Conflict resolution notes: - package.json/run-gates: both sides' new doc-sync gates kept (master's scoped-events/readme gates + this branch's website-api/website-yaml); js-yaml devDeps deduped (master added them independently). - pnpm-workspace/knip: website AND python/sdk-runtime entries kept. - doc-typecheck/verify-type-equiv: master's condensed headers kept, website glob retained in both scan scopes. - vendor/cordis/src/fiber.ts: master's lifecycle-hardening code taken; this branch's richer FiberState JSDoc reapplied on top. vendor/README.md logs both local modifications (hardening = 6, JSDoc enrichment = 7). - pnpm-lock: regenerated from master's side (pnpm install). Post-merge sync the gates forced (the system working as designed): - verify-website-yaml caught 4 stale plugin names from master's package reorg (dsh-stdio-agent -> dsh-stdio-demo, dsh-acp-agent -> dsh-acp-demo); 8 references fixed across guide/ and develop/. - gen-website-api picked up master's 6 new services automatically (ctx.approval/permission/sandbox/sessionQuery/skills/tasks -> 6 new pages + sidebar); api/index.md hub updated to list them. - AGENTS.md budget ceiling 1370 -> 1400: the website rows (layout line + two command lines) and master's own growth collided with the old ceiling; all three website rows are load-bearing (new top-level dir, new CI command).
4.7 KiB
ctx.tasks
TaskService — provided by @deepseek-ai/dsh-tasks.
The tasks service: the runtime-global background task registry. See the module doc for the ownership, isolation, and lifecycle contracts.
ctx.tasks.start(spec)
start(spec: TaskStart): TaskId
Preflight access, validation, and owner cleanup before starting and atomically registering work. A throwing starter leaves nothing registered; after it returns, registration cannot fail. Settlement records the outcome, notifies listeners, and releases waiters.
spec— task identity, owner, and synchronous starter.
Returns the registry-issued <kind>-N id.
ctx.tasks.list(caller?)
list(caller?: Agent): TaskSnapshot[]
List caller-owned and unowned tasks in registration order without exposing another session's labels.
caller— reading agent; a non-agent caller sees only unowned tasks.
Returns fresh snapshots.
ctx.tasks.get(id, caller?)
get(id: TaskId, caller?: Agent): TaskSnapshot
Return a non-consuming snapshot without changing its read cursor or notice state. Throws for an unknown or foreign task.
id— task to look up.caller— reading agent checked against the owner.
Returns a fresh snapshot.
ctx.tasks.read(id, caller?)
read(id: TaskId, caller?: Agent): TaskRead
Read the next stream delta, or the idempotent final output after settlement. A terminal read marks the task reported. Throws for an unknown or foreign task.
id— task to read.caller— reading agent checked against the owner.
Returns output text and the post-read snapshot.
ctx.tasks.kill(id, caller?, reason?)
kill(id: TaskId, caller?: Agent, reason?: string): 'requested' | 'already-finished'
Request cancellation, then mark the task stopping and reported. A producer throw propagates without changing task state. Throws for an unknown or foreign task.
id— task to cancel.caller— killing agent checked against the owner.reason— logged reason forwarded to the producer.
Returns requested for live work, otherwise already-finished.
ctx.tasks.wait(id, timeoutMs, caller?, signal?)
async wait(id: TaskId, timeoutMs: number, caller?: Agent, signal?: AbortSignal): Promise<TaskSnapshot>
Wait for settlement or timeout without cancelling the task. Caller abort rejects only while the task is live; after settlement it returns the terminal snapshot so a notice suppressed for this waiter is still delivered. Timed-out and aborted waits detach their resolvers. Throws for invalid, unknown, or foreign input.
id— task to wait for.timeoutMs— positive finite wait bound in milliseconds.caller— waiting agent checked against the owner.signal— optional cancellation of the wait itself.
Returns snapshot at settlement or timeout.
ctx.tasks.onTaskDone(listener)
onTaskDone(listener: TaskDoneListener): () => void
Register an effect-scoped completion listener. Each listener is contained; returned promises are observed but not awaited. No listener runs after service disposal.
listener— receives each terminal snapshot and its exact owner.
Returns disposer that unregisters the listener.
ctx.tasks.attachSurface(name)
attachSurface(name: string): () => void
Attach an effect-scoped surface that can read and stop tasks. start refuses work while none is attached.
name— diagnostic label; duplicate names remain independent.
Returns disposer that detaches this surface.