feat: background tasks
Adds Background Tasks — recurring background agents the user can set up to
either keep a digest current (daily email summary, top HN stories, weather
brief) or perform a recurring action (draft a reply, post to Slack, call an
API). Each task is a persistent set of instructions plus optional triggers
(schedule, time-of-day window, or matching incoming Gmail / calendar event).
The agent reads the verbs in the instructions on every run and picks the
right mode automatically.
User-facing surfaces:
- New "Background tasks" entry in the sidebar, with a table listing every
task, its schedule, last run, and an active toggle.
- A detail page per task with a max-width reader showing the task's
current output and a control sidebar for editing instructions, triggers,
and reviewing run history.
- "New task" can open in a free-form box where the user describes what they
want and Copilot sets it up end-to-end, or in a structured form for
manual setup.
- "Edit with Copilot" hand-off from the detail view, pre-seeded with the
task's context.
Under the hood:
- The event pipeline that previously powered live-notes is now a generic
consumer registry. Live-notes and background tasks both subscribe;
incoming events are routed to candidates from both concurrently.
- Schedule helpers and the agent-message trigger block are factored out of
live-notes into shared modules. Both features use the same building
blocks now.
- Copilot's proactive routing is reframed: anything recurring (cadence
words, watch / monitor verbs, action verbs, event-conditional asks) now
flows to background tasks. Live-notes load only on explicit mention.
- A small reliability fix for the run-creation fallback chain: an
empty-string model/provider passed by an LLM tool call now correctly
falls through to the default instead of being persisted as a real value.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 17:43:25 +05:30
import z from 'zod' ;
import { TriggersSchema , type Triggers , type TriggerWindow } from './live-note.js' ;
// ---------------------------------------------------------------------------
// Background tasks
// ---------------------------------------------------------------------------
//
// A bg-task is a persistent agent set up to fire on a schedule and/or in
// response to incoming events. Each task owns a folder under
// `$WorkDir/bg-tasks/<slug>/`:
//
// bg-tasks/<slug>/
// ├── task.yaml # plain YAML: BackgroundTask shape
// ├── index.md # agent-owned body — the user-visible artifact
// └── runs/ # one <runId>.jsonl per run (written by agent runtime)
//
// The agent picks between OUTPUT mode (rewrite index.md with the latest state)
// and ACTION mode (perform a side-effect, append a journal entry) based on
// the verbs in `instructions` each run. No mode field on the task.
// ---------------------------------------------------------------------------
// Re-export triggers so callers don't need a second import.
export { TriggersSchema , type Triggers , type TriggerWindow } ;
export type BackgroundTask = {
name : string ;
instructions : string ;
active : boolean ;
triggers? : Triggers ;
feat(bg-tasks): coding-from-meetings — auto-implement coding action items (#630)
* feat(bg-tasks): coding-from-meetings — auto-implement coding action items
A background-task flavor that watches for meeting notes, scans them for
actionable coding items, and autonomously implements them in isolated git
worktrees, summarizing results in the task's index.md.
- Emit `meeting.notes_ready` when Fireflies/Granola first write a meeting note
- Add optional `projectId` to BackgroundTask (pins a coding task to a repo)
- New `launch-code-task` builtin tool: per group of items, create a
worktree-isolated, yolo, direct code session, wrap the prompt in an
autonomous scaffold, run async, and finalize a per-session row in index.md
- Group code sessions under their meeting heading in index.md
- Summary from the code agent's `## Summary` section; file counts from
`git diff` vs the worktree fork point (counts committed work, not just dirty)
- Guardrails: self-heal projectId across runs, cap launches per run, and bar
the bg-task agent from managing/spawning tasks
- UI: "View available templates" -> Coding-from-meetings preset (repo picker,
prefilled trigger + instructions)
See plan.md for the full design.
* let the copilot able to configure a coding background agent
* Delete plan.md
---------
Co-authored-by: Arjun <6592213+arkml@users.noreply.github.com>
2026-06-18 22:56:43 -07:00
// When set, this is a *coding* task: it implements code in the pinned code
// project (a registered repo) via the `launch-code-task` tool, each launch
// running in its own isolated worktree. Omit for ordinary OUTPUT/ACTION tasks.
projectId? : string ;
feat: background tasks
Adds Background Tasks — recurring background agents the user can set up to
either keep a digest current (daily email summary, top HN stories, weather
brief) or perform a recurring action (draft a reply, post to Slack, call an
API). Each task is a persistent set of instructions plus optional triggers
(schedule, time-of-day window, or matching incoming Gmail / calendar event).
The agent reads the verbs in the instructions on every run and picks the
right mode automatically.
User-facing surfaces:
- New "Background tasks" entry in the sidebar, with a table listing every
task, its schedule, last run, and an active toggle.
- A detail page per task with a max-width reader showing the task's
current output and a control sidebar for editing instructions, triggers,
and reviewing run history.
- "New task" can open in a free-form box where the user describes what they
want and Copilot sets it up end-to-end, or in a structured form for
manual setup.
- "Edit with Copilot" hand-off from the detail view, pre-seeded with the
task's context.
Under the hood:
- The event pipeline that previously powered live-notes is now a generic
consumer registry. Live-notes and background tasks both subscribe;
incoming events are routed to candidates from both concurrently.
- Schedule helpers and the agent-message trigger block are factored out of
live-notes into shared modules. Both features use the same building
blocks now.
- Copilot's proactive routing is reframed: anything recurring (cadence
words, watch / monitor verbs, action verbs, event-conditional asks) now
flows to background tasks. Live-notes load only on explicit mention.
- A small reliability fix for the run-creation fallback chain: an
empty-string model/provider passed by an LLM tool call now correctly
falls through to the default instead of being persisted as a real value.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 17:43:25 +05:30
model? : string ;
provider? : string ;
createdAt : string ;
// Runtime-managed — never hand-write. Mirrors live-note's flat-field
// pattern: `lastAttemptAt` is bumped at every run start (backoff anchor),
// `lastRunAt` / `lastRunSummary` only on successful completion, `lastRunError`
// only on failure (cleared on next success). This keeps the "last good run"
// visible even while a new run is in-flight or failing.
lastAttemptAt? : string ;
lastRunId? : string ;
lastRunAt? : string ;
lastRunSummary? : string ;
lastRunError? : string ;
} ;
export type BackgroundTaskSummary = {
slug : string ;
name : string ;
instructions : string ;
active : boolean ;
triggers? : Triggers ;
feat(bg-tasks): coding-from-meetings — auto-implement coding action items (#630)
* feat(bg-tasks): coding-from-meetings — auto-implement coding action items
A background-task flavor that watches for meeting notes, scans them for
actionable coding items, and autonomously implements them in isolated git
worktrees, summarizing results in the task's index.md.
- Emit `meeting.notes_ready` when Fireflies/Granola first write a meeting note
- Add optional `projectId` to BackgroundTask (pins a coding task to a repo)
- New `launch-code-task` builtin tool: per group of items, create a
worktree-isolated, yolo, direct code session, wrap the prompt in an
autonomous scaffold, run async, and finalize a per-session row in index.md
- Group code sessions under their meeting heading in index.md
- Summary from the code agent's `## Summary` section; file counts from
`git diff` vs the worktree fork point (counts committed work, not just dirty)
- Guardrails: self-heal projectId across runs, cap launches per run, and bar
the bg-task agent from managing/spawning tasks
- UI: "View available templates" -> Coding-from-meetings preset (repo picker,
prefilled trigger + instructions)
See plan.md for the full design.
* let the copilot able to configure a coding background agent
* Delete plan.md
---------
Co-authored-by: Arjun <6592213+arkml@users.noreply.github.com>
2026-06-18 22:56:43 -07:00
projectId? : string ;
feat: background tasks
Adds Background Tasks — recurring background agents the user can set up to
either keep a digest current (daily email summary, top HN stories, weather
brief) or perform a recurring action (draft a reply, post to Slack, call an
API). Each task is a persistent set of instructions plus optional triggers
(schedule, time-of-day window, or matching incoming Gmail / calendar event).
The agent reads the verbs in the instructions on every run and picks the
right mode automatically.
User-facing surfaces:
- New "Background tasks" entry in the sidebar, with a table listing every
task, its schedule, last run, and an active toggle.
- A detail page per task with a max-width reader showing the task's
current output and a control sidebar for editing instructions, triggers,
and reviewing run history.
- "New task" can open in a free-form box where the user describes what they
want and Copilot sets it up end-to-end, or in a structured form for
manual setup.
- "Edit with Copilot" hand-off from the detail view, pre-seeded with the
task's context.
Under the hood:
- The event pipeline that previously powered live-notes is now a generic
consumer registry. Live-notes and background tasks both subscribe;
incoming events are routed to candidates from both concurrently.
- Schedule helpers and the agent-message trigger block are factored out of
live-notes into shared modules. Both features use the same building
blocks now.
- Copilot's proactive routing is reframed: anything recurring (cadence
words, watch / monitor verbs, action verbs, event-conditional asks) now
flows to background tasks. Live-notes load only on explicit mention.
- A small reliability fix for the run-creation fallback chain: an
empty-string model/provider passed by an LLM tool call now correctly
falls through to the default instead of being persisted as a real value.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 17:43:25 +05:30
createdAt : string ;
lastAttemptAt? : string ;
lastRunId? : string ;
lastRunAt? : string ;
lastRunSummary? : string ;
lastRunError? : string ;
} ;
feat(bg-tasks): coding-from-meetings — auto-implement coding action items (#630)
* feat(bg-tasks): coding-from-meetings — auto-implement coding action items
A background-task flavor that watches for meeting notes, scans them for
actionable coding items, and autonomously implements them in isolated git
worktrees, summarizing results in the task's index.md.
- Emit `meeting.notes_ready` when Fireflies/Granola first write a meeting note
- Add optional `projectId` to BackgroundTask (pins a coding task to a repo)
- New `launch-code-task` builtin tool: per group of items, create a
worktree-isolated, yolo, direct code session, wrap the prompt in an
autonomous scaffold, run async, and finalize a per-session row in index.md
- Group code sessions under their meeting heading in index.md
- Summary from the code agent's `## Summary` section; file counts from
`git diff` vs the worktree fork point (counts committed work, not just dirty)
- Guardrails: self-heal projectId across runs, cap launches per run, and bar
the bg-task agent from managing/spawning tasks
- UI: "View available templates" -> Coding-from-meetings preset (repo picker,
prefilled trigger + instructions)
See plan.md for the full design.
* let the copilot able to configure a coding background agent
* Delete plan.md
---------
Co-authored-by: Arjun <6592213+arkml@users.noreply.github.com>
2026-06-18 22:56:43 -07:00
// NOTE: keep `BackgroundTaskSummary` (above) and `BackgroundTask` (top) in sync.
feat: background tasks
Adds Background Tasks — recurring background agents the user can set up to
either keep a digest current (daily email summary, top HN stories, weather
brief) or perform a recurring action (draft a reply, post to Slack, call an
API). Each task is a persistent set of instructions plus optional triggers
(schedule, time-of-day window, or matching incoming Gmail / calendar event).
The agent reads the verbs in the instructions on every run and picks the
right mode automatically.
User-facing surfaces:
- New "Background tasks" entry in the sidebar, with a table listing every
task, its schedule, last run, and an active toggle.
- A detail page per task with a max-width reader showing the task's
current output and a control sidebar for editing instructions, triggers,
and reviewing run history.
- "New task" can open in a free-form box where the user describes what they
want and Copilot sets it up end-to-end, or in a structured form for
manual setup.
- "Edit with Copilot" hand-off from the detail view, pre-seeded with the
task's context.
Under the hood:
- The event pipeline that previously powered live-notes is now a generic
consumer registry. Live-notes and background tasks both subscribe;
incoming events are routed to candidates from both concurrently.
- Schedule helpers and the agent-message trigger block are factored out of
live-notes into shared modules. Both features use the same building
blocks now.
- Copilot's proactive routing is reframed: anything recurring (cadence
words, watch / monitor verbs, action verbs, event-conditional asks) now
flows to background tasks. Live-notes load only on explicit mention.
- A small reliability fix for the run-creation fallback chain: an
empty-string model/provider passed by an LLM tool call now correctly
falls through to the default instead of being persisted as a real value.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 17:43:25 +05:30
export const BackgroundTaskSchema = z . object ( {
name : z.string ( ) . min ( 1 ) . describe ( 'User-facing display name.' ) ,
instructions : z.string ( ) . min ( 1 ) . describe ( 'A persistent instruction in the user\'s words — what should this task keep doing? E.g. "Summarize my unread emails every morning into a brief digest." The agent re-reads instructions on every run and decides whether to rewrite index.md (OUTPUT mode) or perform a side-effect and journal it (ACTION mode) based on the verbs.' ) ,
active : z.boolean ( ) . default ( true ) . describe ( 'Set false to pause without deleting.' ) ,
triggers : TriggersSchema.optional ( ) . describe ( 'When the agent fires. Omit for manual-only.' ) ,
feat(bg-tasks): coding-from-meetings — auto-implement coding action items (#630)
* feat(bg-tasks): coding-from-meetings — auto-implement coding action items
A background-task flavor that watches for meeting notes, scans them for
actionable coding items, and autonomously implements them in isolated git
worktrees, summarizing results in the task's index.md.
- Emit `meeting.notes_ready` when Fireflies/Granola first write a meeting note
- Add optional `projectId` to BackgroundTask (pins a coding task to a repo)
- New `launch-code-task` builtin tool: per group of items, create a
worktree-isolated, yolo, direct code session, wrap the prompt in an
autonomous scaffold, run async, and finalize a per-session row in index.md
- Group code sessions under their meeting heading in index.md
- Summary from the code agent's `## Summary` section; file counts from
`git diff` vs the worktree fork point (counts committed work, not just dirty)
- Guardrails: self-heal projectId across runs, cap launches per run, and bar
the bg-task agent from managing/spawning tasks
- UI: "View available templates" -> Coding-from-meetings preset (repo picker,
prefilled trigger + instructions)
See plan.md for the full design.
* let the copilot able to configure a coding background agent
* Delete plan.md
---------
Co-authored-by: Arjun <6592213+arkml@users.noreply.github.com>
2026-06-18 22:56:43 -07:00
projectId : z.string ( ) . optional ( ) . describe ( 'When set, marks this as a coding task pinned to a registered code project (repo). The agent implements detected work via the launch-code-task tool, each launch in its own isolated worktree.' ) ,
feat: background tasks
Adds Background Tasks — recurring background agents the user can set up to
either keep a digest current (daily email summary, top HN stories, weather
brief) or perform a recurring action (draft a reply, post to Slack, call an
API). Each task is a persistent set of instructions plus optional triggers
(schedule, time-of-day window, or matching incoming Gmail / calendar event).
The agent reads the verbs in the instructions on every run and picks the
right mode automatically.
User-facing surfaces:
- New "Background tasks" entry in the sidebar, with a table listing every
task, its schedule, last run, and an active toggle.
- A detail page per task with a max-width reader showing the task's
current output and a control sidebar for editing instructions, triggers,
and reviewing run history.
- "New task" can open in a free-form box where the user describes what they
want and Copilot sets it up end-to-end, or in a structured form for
manual setup.
- "Edit with Copilot" hand-off from the detail view, pre-seeded with the
task's context.
Under the hood:
- The event pipeline that previously powered live-notes is now a generic
consumer registry. Live-notes and background tasks both subscribe;
incoming events are routed to candidates from both concurrently.
- Schedule helpers and the agent-message trigger block are factored out of
live-notes into shared modules. Both features use the same building
blocks now.
- Copilot's proactive routing is reframed: anything recurring (cadence
words, watch / monitor verbs, action verbs, event-conditional asks) now
flows to background tasks. Live-notes load only on explicit mention.
- A small reliability fix for the run-creation fallback chain: an
empty-string model/provider passed by an LLM tool call now correctly
falls through to the default instead of being persisted as a real value.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 17:43:25 +05:30
model : z.string ( ) . optional ( ) . describe ( 'ADVANCED — leave unset. Per-task model override.' ) ,
provider : z.string ( ) . optional ( ) . describe ( 'ADVANCED — leave unset. Per-task provider name override.' ) ,
createdAt : z.string ( ) . describe ( 'ISO timestamp set once at create-time.' ) ,
lastAttemptAt : z.string ( ) . optional ( ) . describe ( 'Runtime-managed — never write this yourself. Bumped at the start of every agent run; used by the scheduler for backoff so failures do not retry-storm.' ) ,
lastRunId : z.string ( ) . optional ( ) . describe ( 'Runtime-managed — never write this yourself. The id of the most recent run (success or failure); used by the bg-task:stop handler.' ) ,
lastRunAt : z.string ( ) . optional ( ) . describe ( 'Runtime-managed — never write this yourself. Bumped only when an agent run *succeeds*; used as the cycle anchor for cron / window triggers and as the freshness timestamp shown in the UI.' ) ,
lastRunSummary : z.string ( ) . optional ( ) . describe ( 'Runtime-managed — never write this yourself. Set on success; not overwritten on failure so the user keeps seeing the last good summary.' ) ,
lastRunError : z.string ( ) . optional ( ) . describe ( 'Runtime-managed — never write this yourself. Set on a failed run; cleared on the next successful run.' ) ,
} ) ;
export const BackgroundTaskSummarySchema = z . object ( {
slug : z.string ( ) ,
name : z.string ( ) ,
instructions : z.string ( ) ,
active : z.boolean ( ) ,
triggers : TriggersSchema.optional ( ) ,
feat(bg-tasks): coding-from-meetings — auto-implement coding action items (#630)
* feat(bg-tasks): coding-from-meetings — auto-implement coding action items
A background-task flavor that watches for meeting notes, scans them for
actionable coding items, and autonomously implements them in isolated git
worktrees, summarizing results in the task's index.md.
- Emit `meeting.notes_ready` when Fireflies/Granola first write a meeting note
- Add optional `projectId` to BackgroundTask (pins a coding task to a repo)
- New `launch-code-task` builtin tool: per group of items, create a
worktree-isolated, yolo, direct code session, wrap the prompt in an
autonomous scaffold, run async, and finalize a per-session row in index.md
- Group code sessions under their meeting heading in index.md
- Summary from the code agent's `## Summary` section; file counts from
`git diff` vs the worktree fork point (counts committed work, not just dirty)
- Guardrails: self-heal projectId across runs, cap launches per run, and bar
the bg-task agent from managing/spawning tasks
- UI: "View available templates" -> Coding-from-meetings preset (repo picker,
prefilled trigger + instructions)
See plan.md for the full design.
* let the copilot able to configure a coding background agent
* Delete plan.md
---------
Co-authored-by: Arjun <6592213+arkml@users.noreply.github.com>
2026-06-18 22:56:43 -07:00
projectId : z.string ( ) . optional ( ) ,
feat: background tasks
Adds Background Tasks — recurring background agents the user can set up to
either keep a digest current (daily email summary, top HN stories, weather
brief) or perform a recurring action (draft a reply, post to Slack, call an
API). Each task is a persistent set of instructions plus optional triggers
(schedule, time-of-day window, or matching incoming Gmail / calendar event).
The agent reads the verbs in the instructions on every run and picks the
right mode automatically.
User-facing surfaces:
- New "Background tasks" entry in the sidebar, with a table listing every
task, its schedule, last run, and an active toggle.
- A detail page per task with a max-width reader showing the task's
current output and a control sidebar for editing instructions, triggers,
and reviewing run history.
- "New task" can open in a free-form box where the user describes what they
want and Copilot sets it up end-to-end, or in a structured form for
manual setup.
- "Edit with Copilot" hand-off from the detail view, pre-seeded with the
task's context.
Under the hood:
- The event pipeline that previously powered live-notes is now a generic
consumer registry. Live-notes and background tasks both subscribe;
incoming events are routed to candidates from both concurrently.
- Schedule helpers and the agent-message trigger block are factored out of
live-notes into shared modules. Both features use the same building
blocks now.
- Copilot's proactive routing is reframed: anything recurring (cadence
words, watch / monitor verbs, action verbs, event-conditional asks) now
flows to background tasks. Live-notes load only on explicit mention.
- A small reliability fix for the run-creation fallback chain: an
empty-string model/provider passed by an LLM tool call now correctly
falls through to the default instead of being persisted as a real value.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 17:43:25 +05:30
createdAt : z.string ( ) ,
lastAttemptAt : z.string ( ) . optional ( ) ,
lastRunId : z.string ( ) . optional ( ) ,
lastRunAt : z.string ( ) . optional ( ) ,
lastRunSummary : z.string ( ) . optional ( ) ,
lastRunError : z.string ( ) . optional ( ) ,
} ) ;
// ---------------------------------------------------------------------------
// Bus events
// ---------------------------------------------------------------------------
export const BackgroundTaskTrigger = z . enum ( [ 'manual' , 'cron' , 'window' , 'event' ] ) ;
export type BackgroundTaskTriggerType = z . infer < typeof BackgroundTaskTrigger > ;
export const BackgroundTaskAgentStartEvent = z . object ( {
type : z . literal ( 'background_task_agent_start' ) ,
slug : z.string ( ) ,
trigger : BackgroundTaskTrigger ,
runId : z.string ( ) ,
} ) ;
export const BackgroundTaskAgentCompleteEvent = z . object ( {
type : z . literal ( 'background_task_agent_complete' ) ,
slug : z.string ( ) ,
runId : z.string ( ) ,
error : z.string ( ) . optional ( ) ,
summary : z.string ( ) . optional ( ) ,
} ) ;
export const BackgroundTaskAgentEvent = z . union ( [ BackgroundTaskAgentStartEvent , BackgroundTaskAgentCompleteEvent ] ) ;
export type BackgroundTaskAgentEventType = z . infer < typeof BackgroundTaskAgentEvent > ;