# CoworkSdk

`window.cowork` (also the global `cowork`): everything an app's widget can call — its
 routines, dialogs, connections, notifications, capture, its own state and panes. A widget never
 sees a secret or the filesystem: that work belongs in a routine.

## Properties

### agent

```ts
agent: object;
```

Expose content to the IDE's AI agent. Text the user selects in
 the app is captured automatically; these calls add programmatic control.
 Everything mirrors into `.cowork/local/agent-context.md`, which the agent
 receives as live selection context. NOTE: `agent` is also the one part
 of this SDK available inside `.html` apps.

#### clearContext

```ts
clearContext: () => void;
```

##### Returns

`void`

#### clearSelection

```ts
clearSelection: () => void;
```

Clears only the select() slot; highlighted-text capture is unaffected.

##### Returns

`void`

#### select

```ts
select: (text) => void;
```

Publish a synthetic "selection" (list/canvas UIs — one item per line).
 COMPOSES with any highlighted text — the agent sees both.

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `text` | `string` |

##### Returns

`void`

#### setAutoSelection

```ts
setAutoSelection: (enabled) => void;
```

Default-ON automatic capture of highlighted text. `false`
 stops the automatic publishes and clears the captured text; `true`
 re-publishes the current selection. select()/setContext() unaffected.

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `enabled` | `boolean` |

##### Returns

`void`

#### setContext

```ts
setContext: (value) => void;
```

Extra app context for the agent (objects are JSON-stringified).

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `value` | `unknown` |

##### Returns

`void`

***

### app

```ts
app: object;
```

This app's own panes — its sidebar, its tabs, its dialog — talking to each other:
 `post` reaches every OTHER open pane of the same app in this workspace (plain data);
 `onMessage` returns the unsubscribe. E.g. the sidebar posts `{ type: "open", id }`
 and the tab shows that record.

#### onMessage

```ts
onMessage: (cb) => () => void;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `cb` | (`message`) => `void` |

##### Returns

() => `void`

#### post

```ts
post: (message) => void;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `message` | `unknown` |

##### Returns

`void`

***

### badge

```ts
badge: (count) => Promise<void>;
```

This app's count on the OS badge, summed over the apps: on the desktop app's
 dock / taskbar icon for the ACTIVE workspace only; in a browser tab, a
 `(N) ` prefix on its title. Another workspace's count waits until that
 workspace is active. State, not an event: the latest call wins, 0 clears,
 nothing expires — report it on every poll (a restart clears it). `count` is
 a non-negative integer. A muted app's count leaves the sum.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `count` | `number` |

#### Returns

`Promise`\<`void`\>

***

### browser

```ts
browser: object;
```

The desktop app's in-IDE browser — the page beside the IDE, for a setup guide's "Open …" buttons.
 `open(url)` shows an http(s) page there (a tab already on that site is reused, else a new tab)
 and resolves `{ embedded: true }`; without an in-IDE browser (web, code-server) it falls back to
 `openExternal` and resolves `{ embedded: false }` — so call it unconditionally. `status()` lists
 its tabs (`{ open, tabs: [{ url, title, active }] }`), or `null` when there is none — poll it
 (only while `visible`) to follow where the user is, e.g. to pick an id out of the URL they reached.

#### open

```ts
open: (url) => Promise<{
  embedded: boolean;
}>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `url` | `string` |

##### Returns

`Promise`\<\{
  `embedded`: `boolean`;
\}\>

#### status

```ts
status: () => Promise<
  | {
  open: boolean;
  tabs: object[];
}
| null>;
```

##### Returns

`Promise`\<
  \| \{
  `open`: `boolean`;
  `tabs`: `object`[];
\}
  \| `null`\>

***

### capture

```ts
capture: object;
```

Screen and audio capture. Declare what the panes may capture in cowork.json
 (`"capture": ["screen", "system-audio", "mic", "screenshot"]`, any subset); every
 capture still asks the person in Cowork's dialog, which names this app, what it asks
 for and what it gets — nothing starts without that Allow, and a recording shows a pill
 with Stop. `record` resolves once recording (the file lands at `session.file` after
 Stop; `live: true` also streams 16 kHz mono frames to `onAudio` — the app hears what
 the person hears); `shot` resolves with one PNG (`path` when saved, `image` when
 asked). Files default to `Recordings/<date-time>-<app>.webm` / `.png`. Rejects by
 name: Denied, NotDeclared, Busy (one per workspace),
 DiskFull, Unsupported (a page that cannot capture). Panes only — no routine captures.

#### current

```ts
current: () => 
  | CoworkCaptureSession
  | null;
```

This app's recording in progress, if any — to re-attach after the pane remounts.

##### Returns

  \| [`CoworkCaptureSession`](/docs/reference/sdk/interfaces/coworkcapturesession.md)
  \| `null`

#### record

```ts
record: (opts?) => Promise<CoworkCaptureSession>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `opts?` | \{ `audio?`: \{ `mic?`: `boolean`; `system?`: `boolean`; \}; `file?`: `string`; `live?`: `boolean`; `video?`: `false` \| `"window"` \| `"screen"`; \} |
| `opts.audio?` | \{ `mic?`: `boolean`; `system?`: `boolean`; \} |
| `opts.audio.mic?` | `boolean` |
| `opts.audio.system?` | `boolean` |
| `opts.file?` | `string` |
| `opts.live?` | `boolean` |
| `opts.video?` | `false` \| `"window"` \| `"screen"` |

##### Returns

`Promise`\<[`CoworkCaptureSession`](/docs/reference/sdk/interfaces/coworkcapturesession.md)\>

#### shot

```ts
shot: (opts?) => Promise<{
  image?: Blob;
  path?: string;
}>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `opts?` | \{ `file?`: `string`; `image?`: `boolean`; `source?`: `"window"` \| `"screen"`; \} |
| `opts.file?` | `string` |
| `opts.image?` | `boolean` |
| `opts.source?` | `"window"` \| `"screen"` |

##### Returns

`Promise`\<\{
  `image?`: `Blob`;
  `path?`: `string`;
\}\>

***

### chat

```ts
chat: object;
```

Send a message to the workbench chat panel: opens the chat
 and SUBMITS the text as a query. Fire-and-forget.

#### ask

```ts
ask: (text) => void;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `text` | `string` |

##### Returns

`void`

***

### closeTab

```ts
closeTab: () => void;
```

Close this app's editor tab (as if the user hit × on it). No-op in a
 sidebar viewpane.

#### Returns

`void`

***

### consent

```ts
consent: object;
```

Command consent — ask the user (via the shared Allow/Deny + "Always allow
 in this workspace" modal) before running something. `value` is a stable
 human label; `detail` is shown verbatim (the exact command) for
 transparency. A persisted grant lives in Cowork's per-workspace consent file,
 on this computer, NEVER in the workspace — nothing is shipped, so every machine
 approves the first time. Returns `granted` + a one-shot `ticket` when allowed just
 once; pass it to `stream.open({ consent: { value, ticket } })`.

#### request

```ts
request: (opts) => Promise<{
  granted: boolean;
  ticket?: string;
}>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `opts` | \{ `body?`: `string`; `detail?`: `string`; `kind?`: `string`; `title?`: `string`; `value`: `string`; \} |
| `opts.body?` | `string` |
| `opts.detail?` | `string` |
| `opts.kind?` | `string` |
| `opts.title?` | `string` |
| `opts.value` | `string` |

##### Returns

`Promise`\<\{
  `granted`: `boolean`;
  `ticket?`: `string`;
\}\>

***

### credentials

```ts
credentials: object;
```

The connections of the capabilities this app uses. A capability declares how it connects
 (`"credential"` in its cowork.json); the person connects once — here or in Manage
 Workspace › Components › Credentials — and every capability sharing the connection is
 connected. Never a token or a key: the capability's routines call the service.

#### connect

```ts
connect: (name, fields?) => Promise<void>;
```

Connect it. A sign-in opens the service's consent for what every capability using it
 needs and resolves once the page is open — the sign-in finishes in the browser, then
 refresh; a key saves `fields` (e.g. `{ token }`). One that takes either signs in
 unless `fields` are given.

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `name` | `string` |
| `fields?` | `Record`\<`string`, `string`\> |

##### Returns

`Promise`\<`void`\>

#### get

```ts
get: (name) => Promise<CoworkConnection>;
```

The connection — ready when `state` is "connected".

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `name` | `string` |

##### Returns

`Promise`\<[`CoworkConnection`](/docs/reference/sdk/interfaces/coworkconnection.md)\>

***

### identity

```ts
identity: object;
```

Who is signed in: currentUser() → {uid, email}, or null when signed out.

#### currentUser

```ts
currentUser: () => Promise<
  | {
  email: string | null;
  uid: string;
}
| null>;
```

##### Returns

`Promise`\<
  \| \{
  `email`: `string` \| `null`;
  `uid`: `string`;
\}
  \| `null`\>

***

### journal

```ts
journal: object;
```

The skill journal — learnings and error notes per skill, "open" until
 an agent folds them into the skill and resolves them. `entries` lists one skill's,
 oldest first: its open ones unless `status` says otherwise, at most `limit` (1–200,
 default 200). `resolve` marks the given ids applied, or every open one of the skill.

#### add

```ts
add: (entry) => Promise<CoworkJournalEntry>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `entry` | \{ `kind?`: `"learning"` \| `"error"` \| `"note"`; `skill`: `string`; `source?`: `string`; `text`: `string`; \} |
| `entry.kind?` | `"learning"` \| `"error"` \| `"note"` |
| `entry.skill` | `string` |
| `entry.source?` | `string` |
| `entry.text` | `string` |

##### Returns

`Promise`\<[`CoworkJournalEntry`](/docs/reference/sdk/interfaces/coworkjournalentry.md)\>

#### entries

```ts
entries: (skill, opts?) => Promise<CoworkJournalEntry[]>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `skill` | `string` |
| `opts?` | \{ `limit?`: `number`; `status?`: `"all"` \| `"open"` \| `"applied"`; \} |
| `opts.limit?` | `number` |
| `opts.status?` | `"all"` \| `"open"` \| `"applied"` |

##### Returns

`Promise`\<[`CoworkJournalEntry`](/docs/reference/sdk/interfaces/coworkjournalentry.md)[]\>

#### resolve

```ts
resolve: (skill, ids?) => Promise<{
  resolved: number;
}>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `skill` | `string` |
| `ids?` | `number`[] |

##### Returns

`Promise`\<\{
  `resolved`: `number`;
\}\>

#### skills

```ts
skills: () => Promise<object[]>;
```

##### Returns

`Promise`\<`object`[]\>

***

### log

```ts
log: (...parts) => void;
```

Emit a log line to the "Cowork" Output panel.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| ...`parts` | `unknown`[] |

#### Returns

`void`

***

### notify

```ts
notify: (n) => Promise<void>;
```

An OS notification from this app — a banner from the desktop app (even with
 its window closed), or from a browser tab on this workspace (best effort: a
 backgrounded tab is throttled); only the ACTIVE workspace's notifications
 show. Rejects in a machine's (remote) window. `title` is required and shows exactly as sent
 (≤ 100 characters; `body` ≤ 300, `tag` ≤ 64 — longer is cut). A `tag`
 replaces this app's not-yet-shown notification with the same tag; `urgent`
 keeps the banner up and asks for attention (dock bounce, flashing taskbar).
 A click opens this app. Resolves too when the user muted the app (Manage
 Workspace › Notifications) or it sent more than 6 in a minute — those are
 dropped; one nobody shows within a minute is dropped as well. Rejects
 BadRequest without a title. To notify with no pane open, call
 `ctx.notify` from a routine.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `n` | \{ `body?`: `string`; `tag?`: `string`; `title`: `string`; `urgent?`: `boolean`; \} |
| `n.body?` | `string` |
| `n.tag?` | `string` |
| `n.title` | `string` |
| `n.urgent?` | `boolean` |

#### Returns

`Promise`\<`void`\>

***

### onNotification

```ts
onNotification: (cb) => () => void;
```

Called with each of THIS app's notifications as Cowork accepts it — its panes' `cowork.notify`,
 its routines' `ctx.notify`, and a capability's that shows as this app — in every open pane of
 the app: `useEffect(() => cowork.onNotification((n) => setLast(n)), [])`. Returns the
 unsubscribe. Live only: a pane that opens later never gets earlier ones. A muted app's
 notifications and the ones Cowork drops (more than 6 a minute, the app switched off) never
 arrive. Another app's notifications reach a routine instead, through its `notifications`
 trigger.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `cb` | (`n`) => `void` |

#### Returns

() => `void`

***

### onTitleAction

```ts
onTitleAction: (handler) => () => void;
```

Subscribe to pane title-action button clicks (the standalone runner's panes).

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `handler` | (`id`) => `void` |

#### Returns

() => `void`

***

### onVisibility

```ts
onVisibility: (cb) => () => void;
```

Subscribe to visibility flips. Returns the unsubscribe function.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `cb` | (`visible`) => `void` |

#### Returns

() => `void`

***

### openedFile?

```ts
openedFile?: CoworkOpenedFile;
```

Present only when opened via fileRouting (editor tab).

***

### openExternal

```ts
openExternal: (url) => void;
```

Open an external URL (http/https/mailto) via VS Code — shows the workbench
 trust prompt (Open / Copy / configure trusted domains).

 You usually DON'T need to call this: the app host intercepts clicks on any
 `<a href="https://…">` and routes them here automatically, so ordinary
 markup is already safe (relative and `#anchor` links are untouched). Call
 it directly for PROGRAMMATIC opens — no click involved.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `url` | `string` |

#### Returns

`void`

***

### openFile

```ts
openFile: (path) => void;
```

Open a workspace file (routes through fileRouting when it matches).

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `path` | `string` |

#### Returns

`void`

***

### queue

```ts
queue: object;
```

Task queues (the workspace's .cowork/local/queues.db; the Tasks view) — work for agents and
 scripts. A task has a `subject`, a `status` (todo → in_progress → needs_review or done;
 failed past its attempts), who it is `from` and `to` (an agent's name, "owner" or
 "anyone"), `review` (its finish waits for the owner), the request (`body`, `files`) and a
 thread of `entries`. `send` creates the queue (≤ 1 MiB body, files as
 `{name, text}` or `{name, base64}` — data, never a path; a repeated `ref` answers the first
 task); `receive` takes the oldest task for `as` or for anyone (`mine`: its own only) with a
 `receipt` (null = none); `ack` finishes it — the result and files are the holder's entry,
 `review` asks the owner, `to` hands it on — `nack` gives it back. `approve`, `reject`
 (Send back), `reply`, `retry` act as the owner; `tasks` is the Tasks view's one read.
 Reads on a workspace with no queue yet answer empty. Times are epoch ms.

#### ack

```ts
ack: (queue, id, receipt, opts?) => Promise<CoworkQueueTask>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `queue` | `string` |
| `id` | `number` |
| `receipt` | `string` |
| `opts?` | \{ `files?`: ( \| \{ `name`: `string`; `text`: `string`; \} \| \{ `base64`: `string`; `name`: `string`; \})[]; `result?`: `string`; `review?`: `boolean`; `to?`: `string`; \} |
| `opts.files?` | ( \| \{ `name`: `string`; `text`: `string`; \} \| \{ `base64`: `string`; `name`: `string`; \})[] |
| `opts.result?` | `string` |
| `opts.review?` | `boolean` |
| `opts.to?` | `string` |

##### Returns

`Promise`\<[`CoworkQueueTask`](/docs/reference/sdk/interfaces/coworkqueuetask.md)\>

#### approve

```ts
approve: (queue, id) => Promise<CoworkQueueTask>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `queue` | `string` |
| `id` | `number` |

##### Returns

`Promise`\<[`CoworkQueueTask`](/docs/reference/sdk/interfaces/coworkqueuetask.md)\>

#### create

```ts
create: (queue, opts?) => Promise<CoworkQueueInfo>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `queue` | `string` |
| `opts?` | \{ `leaseS?`: `number`; `maxAttempts?`: `number`; `review?`: `boolean`; \} |
| `opts.leaseS?` | `number` |
| `opts.maxAttempts?` | `number` |
| `opts.review?` | `boolean` |

##### Returns

`Promise`\<[`CoworkQueueInfo`](/docs/reference/sdk/interfaces/coworkqueueinfo.md)\>

#### items

```ts
items: (queue, opts?) => Promise<CoworkQueueTask[]>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `queue` | `string` |
| `opts?` | \{ `agent?`: `string`; `before?`: `number`; `limit?`: `number`; `view?`: [`CoworkTaskView`](/docs/reference/sdk/type-aliases/coworktaskview.md); \} |
| `opts.agent?` | `string` |
| `opts.before?` | `number` |
| `opts.limit?` | `number` |
| `opts.view?` | [`CoworkTaskView`](/docs/reference/sdk/type-aliases/coworktaskview.md) |

##### Returns

`Promise`\<[`CoworkQueueTask`](/docs/reference/sdk/interfaces/coworkqueuetask.md)[]\>

#### list

```ts
list: () => Promise<CoworkQueueInfo[]>;
```

##### Returns

`Promise`\<[`CoworkQueueInfo`](/docs/reference/sdk/interfaces/coworkqueueinfo.md)[]\>

#### nack

```ts
nack: (queue, id, receipt, opts?) => Promise<CoworkQueueTask>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `queue` | `string` |
| `id` | `number` |
| `receipt` | `string` |
| `opts?` | \{ `delayS?`: `number`; `error?`: `string`; \} |
| `opts.delayS?` | `number` |
| `opts.error?` | `string` |

##### Returns

`Promise`\<[`CoworkQueueTask`](/docs/reference/sdk/interfaces/coworkqueuetask.md)\>

#### peek

```ts
peek: (queue, id) => Promise<
  | CoworkQueueTask
| null>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `queue` | `string` |
| `id` | `number` |

##### Returns

`Promise`\<
  \| [`CoworkQueueTask`](/docs/reference/sdk/interfaces/coworkqueuetask.md)
  \| `null`\>

#### purge

```ts
purge: (queue, status?) => Promise<{
  purged: number;
}>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `queue` | `string` |
| `status?` | `"done"` \| `"failed"` \| `"all"` |

##### Returns

`Promise`\<\{
  `purged`: `number`;
\}\>

#### receive

```ts
receive: (queue, opts?) => Promise<
  | CoworkQueueTask & object
| null>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `queue` | `string` |
| `opts?` | \{ `as?`: `string`; `leaseS?`: `number`; `mine?`: `boolean`; \} |
| `opts.as?` | `string` |
| `opts.leaseS?` | `number` |
| `opts.mine?` | `boolean` |

##### Returns

`Promise`\<
  \| [`CoworkQueueTask`](/docs/reference/sdk/interfaces/coworkqueuetask.md) & `object`
  \| `null`\>

#### receivers

```ts
receivers: (queue?) => Promise<CoworkQueueReceiver[]>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `queue?` | `string` |

##### Returns

`Promise`\<[`CoworkQueueReceiver`](/docs/reference/sdk/interfaces/coworkqueuereceiver.md)[]\>

#### reject

```ts
reject: (queue, id, comment, opts?) => Promise<CoworkQueueTask>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `queue` | `string` |
| `id` | `number` |
| `comment` | `string` |
| `opts?` | \{ `files?`: ( \| \{ `name`: `string`; `text`: `string`; \} \| \{ `base64`: `string`; `name`: `string`; \})[]; \} |
| `opts.files?` | ( \| \{ `name`: `string`; `text`: `string`; \} \| \{ `base64`: `string`; `name`: `string`; \})[] |

##### Returns

`Promise`\<[`CoworkQueueTask`](/docs/reference/sdk/interfaces/coworkqueuetask.md)\>

#### remove

```ts
remove: (queue, id?) => Promise<{
  removed: boolean;
}>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `queue` | `string` |
| `id?` | `number` |

##### Returns

`Promise`\<\{
  `removed`: `boolean`;
\}\>

#### reply

```ts
reply: (queue, id, body, opts?) => Promise<CoworkQueueTask>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `queue` | `string` |
| `id` | `number` |
| `body` | `string` |
| `opts?` | \{ `as?`: `string`; `files?`: ( \| \{ `name`: `string`; `text`: `string`; \} \| \{ `base64`: `string`; `name`: `string`; \})[]; `to?`: `string` \| `null`; \} |
| `opts.as?` | `string` |
| `opts.files?` | ( \| \{ `name`: `string`; `text`: `string`; \} \| \{ `base64`: `string`; `name`: `string`; \})[] |
| `opts.to?` | `string` \| `null` |

##### Returns

`Promise`\<[`CoworkQueueTask`](/docs/reference/sdk/interfaces/coworkqueuetask.md)\>

#### retry

```ts
retry: (queue, id) => Promise<CoworkQueueTask>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `queue` | `string` |
| `id` | `number` |

##### Returns

`Promise`\<[`CoworkQueueTask`](/docs/reference/sdk/interfaces/coworkqueuetask.md)\>

#### send

```ts
send: (queue, task) => Promise<CoworkQueueTask>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `queue` | `string` |
| `task` | \{ `as?`: `string`; `body?`: `string`; `delayS?`: `number`; `files?`: ( \| \{ `name`: `string`; `text`: `string`; \} \| \{ `base64`: `string`; `name`: `string`; \})[]; `meta?`: `Record`\<`string`, `unknown`\>; `ref?`: `string`; `review?`: `boolean`; `subject?`: `string`; `to?`: `string`; \} |
| `task.as?` | `string` |
| `task.body?` | `string` |
| `task.delayS?` | `number` |
| `task.files?` | ( \| \{ `name`: `string`; `text`: `string`; \} \| \{ `base64`: `string`; `name`: `string`; \})[] |
| `task.meta?` | `Record`\<`string`, `unknown`\> |
| `task.ref?` | `string` |
| `task.review?` | `boolean` |
| `task.subject?` | `string` |
| `task.to?` | `string` |

##### Returns

`Promise`\<[`CoworkQueueTask`](/docs/reference/sdk/interfaces/coworkqueuetask.md)\>

#### summary

```ts
summary: () => Promise<{
  journal: number;
  needsYou: number;
}>;
```

##### Returns

`Promise`\<\{
  `journal`: `number`;
  `needsYou`: `number`;
\}\>

#### tasks

```ts
tasks: (opts?) => Promise<{
  agents: CoworkQueueReceiver[];
  counts: Record<CoworkTaskView, number>;
  queues: CoworkQueueInfo[];
  tasks: CoworkQueueTask[];
}>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `opts?` | \{ `agent?`: `string`; `limit?`: `number`; `q?`: `string`; `queue?`: `string`; `view?`: [`CoworkTaskView`](/docs/reference/sdk/type-aliases/coworktaskview.md); \} |
| `opts.agent?` | `string` |
| `opts.limit?` | `number` |
| `opts.q?` | `string` |
| `opts.queue?` | `string` |
| `opts.view?` | [`CoworkTaskView`](/docs/reference/sdk/type-aliases/coworktaskview.md) |

##### Returns

`Promise`\<\{
  `agents`: [`CoworkQueueReceiver`](/docs/reference/sdk/interfaces/coworkqueuereceiver.md)[];
  `counts`: `Record`\<[`CoworkTaskView`](/docs/reference/sdk/type-aliases/coworktaskview.md), `number`\>;
  `queues`: [`CoworkQueueInfo`](/docs/reference/sdk/interfaces/coworkqueueinfo.md)[];
  `tasks`: [`CoworkQueueTask`](/docs/reference/sdk/interfaces/coworkqueuetask.md)[];
\}\>

***

### routines

```ts
routines: object;
```

Run a registered routine — declared in an app's .cowork/apps/<name>/cowork.json
 `routines` — and resolve its return
 value. Rejects with the routine's error: `e.name` is the kind it threw
 (`NotConnected` from ctx.error / ctx.credential), `e.runId` the run
 (`cowork routine runs show <id>`). Cowork's own `NotFound` (no such routine, or its
 capability is not installed) comes before any run and has no `e.runId` — a `NotFound`
 the routine threw always has one. Identical calls in flight share one run,
 and a busy daemon (TooManyRoutines) is waited out within the call's timeout.

#### run

```ts
run: (id, args?, opts?) => Promise<unknown>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `id` | `string` |
| `args?` | `unknown` |
| `opts?` | \{ `timeoutMs?`: `number`; \} |
| `opts.timeoutMs?` | `number` |

##### Returns

`Promise`\<`unknown`\>

#### runs

```ts
runs: (id?, opts?) => Promise<CoworkRoutineRun[]>;
```

Bounded run history (newest first) — metadata only (ts, ok, durationMs,
 error / resultPreview). Omit id for all routines in this workspace;
 `opts.app` narrows to one package's runs (its manifest name). Each run
 names its package (`app`, its `kind` when the record says) and, when
 another routine called it, `chain` — the callers, outermost first.

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `id?` | `string` |
| `opts?` | \{ `app?`: `string`; \} |
| `opts.app?` | `string` |

##### Returns

`Promise`\<[`CoworkRoutineRun`](/docs/reference/sdk/interfaces/coworkroutinerun.md)[]\>

#### subscribe

```ts
subscribe: (id, args, opts) => object;
```

Keep a routine's answer fresh: runs now, then every `interval` seconds (min 5,
 default 60) while a pane of this app is on screen — ONE loop shared by every pane of
 the app asking the same routine with the same args (the sidebar and its tab poll
 once, not twice). `onData` gets each NEW answer (identical answers are not re-sent;
 a pane opening later gets the last one at once); `onError` gets the failure by name —
 `NotConnected` pauses the loop until `refresh()` (call it after the user connects);
 `refresh()` always answers this pane — from a run that starts after the call, even when nothing
 changed — await it for a spinner, or to see the result of a change you just made.
 Use this instead of setInterval: `useEffect(() => { const s = cowork.routines.subscribe(…);
 return () => s.close() }, [])`.

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `id` | `string` |
| `args` | `unknown` |
| `opts` | \{ `interval?`: `number`; `onData?`: (`data`) => `void`; `onError?`: (`error`) => `void`; `timeoutMs?`: `number`; \} |
| `opts.interval?` | `number` |
| `opts.onData?` | (`data`) => `void` |
| `opts.onError?` | (`error`) => `void` |
| `opts.timeoutMs?` | `number` |

##### Returns

`object`

###### close

```ts
close: () => void;
```

###### Returns

`void`

###### refresh

```ts
refresh: () => Promise<void>;
```

###### Returns

`Promise`\<`void`\>

***

### setTitleActions

```ts
setTitleActions: (actions) => void;
```

Replace the pane title-action buttons (the standalone runner's panes).

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `actions` | `object`[] |

#### Returns

`void`

***

### state

```ts
state: object;
```

Persisted per-view state (survives hide/show + reloads).

#### get

```ts
get: <T>() => T | undefined;
```

##### Type Parameters

| Type Parameter | Default type |
| ------ | ------ |
| `T` | `unknown` |

##### Returns

`T` \| `undefined`

#### set

```ts
set: (value) => void;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `value` | `unknown` |

##### Returns

`void`

***

### statusBar

```ts
statusBar: object;
```

The apps' footer items (see CoworkStatusBarItem), keyed by app name.

#### click

```ts
click: (app) => void;
```

Act as if the user clicked the app's item.

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `app` | `string` |

##### Returns

`void`

#### get

```ts
get: (app) => 
  | CoworkStatusBarItem
  | null;
```

An app's item as last drawn (`data` included), or null.

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `app` | `string` |

##### Returns

  \| [`CoworkStatusBarItem`](/docs/reference/sdk/interfaces/coworkstatusbaritem.md)
  \| `null`

#### onChange

```ts
onChange: (cb) => () => void;
```

Called with each app's current item right away, then on every change
 of any app's item — subscribe rather than reading get() at mount.

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `cb` | (`app`, `item`) => `void` |

##### Returns

() => `void`

#### refresh

```ts
refresh: (app?) => void;
```

Re-run an app's statusBar routine now (all apps without one) — after
 your widget changed what it reports.

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `app?` | `string` |

##### Returns

`void`

***

### stream

```ts
stream: object;
```

Persistent process streams — spawn ONE long-lived process on the
 daemon and move raw stdio bytes (PTY mirrors, tail -f, long CLIs),
 instead of paying a subprocess per routine call. Token-gated like
 routines.run. `onData` gets stdout bytes as they arrive; `onEnd`
 fires exactly once ("end" = the process exited, "error" = the stream
 broke, "closed" = you closed it). The daemon caps concurrent streams
 (8) and reaps orphans; ONE reader per stream — reconnect by opening a
 fresh stream. Per view at most 2 streams may be open at once (each
 pins one of the origin's ~6 browser connections) — open() throws past
 that cap, so close a stream before opening the next.

#### open

```ts
open: (opts) => Promise<{
  close: () => Promise<void>;
  id: string;
  write: (data) => Promise<void>;
}>;
```

##### Parameters

| Parameter | Type | Description |
| ------ | ------ | ------ |
| `opts` | \{ `argv`: `string`[]; `consent`: \{ `ticket?`: `string`; `value`: `string`; \}; `onData`: (`bytes`) => `void`; `onEnd?`: (`reason`) => `void`; \} | - |
| `opts.argv` | `string`[] | - |
| `opts.consent` | \{ `ticket?`: `string`; `value`: `string`; \} | Proof the user approved this command (from cowork.consent.request): the stable label they consented to + a one-shot `ticket` for an "allow once" (omit for a persisted "always allow"). Without a covering grant/ticket the daemon refuses (ConsentRequired). |
| `opts.consent.ticket?` | `string` | - |
| `opts.consent.value` | `string` | - |
| `opts.onData` | (`bytes`) => `void` | - |
| `opts.onEnd?` | (`reason`) => `void` | - |

##### Returns

`Promise`\<\{
  `close`: () => `Promise`\<`void`\>;
  `id`: `string`;
  `write`: (`data`) => `Promise`\<`void`\>;
\}\>

***

### tables

```ts
tables: object;
```

Local SQLite tables. `db` is a WORKSPACE-RELATIVE path to a
 .db file; calls go through the daemon (WAL mode, so reads stay safe while
 routines write). query() is read-only (non-SELECT SQL is rejected) and
 every page is capped at 500 rows; exec() is for writes/DDL.

#### exec

```ts
exec: (opts) => Promise<{
  changes: number;
  lastInsertRowid: number;
}>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `opts` | \{ `db`: `string`; `params?`: `unknown`[]; `sql`: `string`; \} |
| `opts.db` | `string` |
| `opts.params?` | `unknown`[] |
| `opts.sql` | `string` |

##### Returns

`Promise`\<\{
  `changes`: `number`;
  `lastInsertRowid`: `number`;
\}\>

#### query

```ts
query: (opts) => Promise<{
  columns: string[];
  rowCount: number;
  rows: unknown[][];
  truncated: boolean;
}>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `opts` | \{ `db`: `string`; `limit?`: `number`; `offset?`: `number`; `params?`: `unknown`[]; `sql`: `string`; \} |
| `opts.db` | `string` |
| `opts.limit?` | `number` |
| `opts.offset?` | `number` |
| `opts.params?` | `unknown`[] |
| `opts.sql` | `string` |

##### Returns

`Promise`\<\{
  `columns`: `string`[];
  `rowCount`: `number`;
  `rows`: `unknown`[][];
  `truncated`: `boolean`;
\}\>

#### schema

```ts
schema: (opts) => Promise<{
  tables: object[];
}>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `opts` | \{ `db`: `string`; \} |
| `opts.db` | `string` |

##### Returns

`Promise`\<\{
  `tables`: `object`[];
\}\>

***

### ui

```ts
ui: object;
```

Modal dialogs, drawn by Cowork. `dialog` resolves the button's `label` and the fields' `values`
 plus the button's own. On Cancel or Esc `label` is null and `values` still holds the fields as
 they were left — test `label`, never `values`. `confirm` is the yes/no shorthand:
 `true` only on the confirm action, `false` on Cancel or Esc; called bare it asks
 "Are you sure?" with Continue.

#### confirm

```ts
confirm: (opts?) => Promise<boolean>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `opts?` | \{ `body?`: `string`; `cancelLabel?`: `string`; `confirmLabel?`: `string`; `destructive?`: `boolean`; `title?`: `string`; \} |
| `opts.body?` | `string` |
| `opts.cancelLabel?` | `string` |
| `opts.confirmLabel?` | `string` |
| `opts.destructive?` | `boolean` |
| `opts.title?` | `string` |

##### Returns

`Promise`\<`boolean`\>

#### dialog

```ts
dialog: (opts) => Promise<{
  label: string | null;
  values: Record<string, unknown>;
}>;
```

##### Parameters

| Parameter | Type |
| ------ | ------ |
| `opts` | [`CoworkDialog`](/docs/reference/sdk/interfaces/coworkdialog.md) |

##### Returns

`Promise`\<\{
  `label`: `string` \| `null`;
  `values`: `Record`\<`string`, `unknown`\>;
\}\>

***

### viewSource

```ts
viewSource: () => void;
```

Open this app's SOURCE file (editor tabs: the routed document) in the
 plain text editor — the "view code" affordance.

#### Returns

`void`

***

### visible

```ts
readonly visible: boolean;
```

Whether this pane/tab is currently on screen. Retained panes
 stay ALIVE while hidden, and the Page Visibility API / layout width both
 lie inside webview iframes — this host-pumped flag is the honest signal.
 Gate polls on it; refetch on the rising edge via `onVisibility`.

***

### workspaceRoot

```ts
workspaceRoot: string;
```

The workspace this pane belongs to: its folder's absolute path — in a machine's (remote)
 window `cowork-remote://<machine>/<path>`, on a published site `/published/<folder name>`.
 Its last segment is the workspace's name.
