Page SDK
Status: Shipped Generated from app @ 1b3d5a69d73473db077dfb44f4390b42cded6bd4 Regenerate: pnpm gen:reference
Every HTML page in your spaces gets a window.codesense object. It can read your plans live and act: change a status, open a workspace, send an agent a message. There are 55 bridge methods: 28 reads and 27 action verbs. Every one runs when the page calls it; there is nothing to declare and no prompt.
Outside CodeSense the object isn’t there, so check for it first: if (!window.codesense) { … }.
Versions
window.codesense.version is "2". Every queryContext() result carries schemaVersion: 1. If your page sees a version or schemaVersion it doesn’t know, show its static content instead of reading fields that may have changed.
The SDK object
| Member | What it does |
|---|---|
version | The SDK version string. |
firstPaint | Data embedded in the page for first paint, or null. |
invoke | Call a bridge method by name: invoke(method, args). Resolves with its result. |
act | Call an action verb: act(verb, args). Same as invoke. |
routineResult | Read private cached routine data and provenance; never launches. |
routineRefresh | Explicitly refresh through routine admission with optional variables. |
routineStatus | Read cached routine status and last-good data. |
routineCancel | Cancel this principal's live result runs for a routine key. |
onRoutineResult | Subscribe to routine invalidations; reread through the cached API. Returns an unsubscribe function. |
readWorkspace | Shorthand for act('readWorkspace', args). |
queryContext | Find context files by metadata across every synced org (or a scoped set): queryContext(query). Resolves with {total, rows, groups?, nextCursor?}. |
subscribeContext | Live queryContext: subscribeContext(query, (result, error) => …) runs now and on every context change. Returns an unsubscribe function. |
snapshot | Freeze the page into a static HTML record, optionally embedding state. |
theme | In a right pane, the app's theme where the pane sits: resolves {scheme, tokens}; the tokens are also set on the page root as CSS custom properties (--cs-bg, --cs-fg, ...). |
onTheme | Subscribe to the theme: onTheme((theme) => …) runs once it is known and on every change. Returns an unsubscribe function. |
onVisibility | Subscribe to whether the page is on screen: onVisibility((visible) => …). Pause polling while hidden. Returns an unsubscribe function. |
prefs | This dashboard's own settings object ({} at first), kept in your app state across restarts; a team copy and a private copy each have their own. |
setPrefs | Merge keys into this dashboard's settings: setPrefs({key: value}); null removes a key. Resolves the result. Plain JSON only; 16 KB per dashboard; its own budget (denied: prefs budget). Feature-detect on older hosts. |
getNavSelection | What the left nav has selected in the page's own team: resolves {org, team, file, drill} or null. file is the active tab {path, relPath, kind, id, title, epic}; drill is the drilled folder {path, relPath, epic} (null at the root). Paths outside the team's content read as null. Resolves null rather than wait past 5 s. To select a file in the nav, call openFile. |
onNavSelectionChange | Follow the left nav: onNavSelectionChange((selection) => …) runs once the selection is known and once per settled change. Nothing is sent until a page asks; the last unsubscribe stops it. Feature-detect it on older hosts. Returns an unsubscribe function. |
sessions | Every running agent session, as the list_sessions MCP tool lists it: [{handle, displayName, state, launchedBy, unread, oldestUnreadAt, story?, workspace?, machine?, role?, avatar?, agent?, progress?}]. progress is its latest signal_progress: {phase, step?, total?, note?, atMs}. |
onSessions | Live sessions(): onSessions((list, error) => …) runs now and whenever the roster changes. Returns an unsubscribe function. |
agents | The agents you can launch: [{key, name, description, runtime, scope, team, runningNow}]. |
agent | One saved agent as agent_get returns it, with the sessions running it: agent({key}) → {id, definition, resolved, instances, …}. |
inbox | Inbox messages, newest first, marking nothing read: inbox({scope?, agentId?, sessionId?, role?, limit?}) → {messages, humanUnread}. |
roles | Each role queue and who holds it: roles({role?, limit?}) → {roles: [{role, roleName, registrations, counts, deliveries}]}. |
updates | Agents' progress notes, newest first: updates({limit?}) → {updates}. |
humanStatus | Your status as agents see it: {status, note?, updatedAtMs}. |
onAgentsChanged | Run a callback whenever sessions, role queues or your status change; re-read then. Returns an unsubscribe function. |
onInboxChanged | Run a callback whenever an inbox message is stored, read or claimed; re-read then. Returns an unsubscribe function. |
context | Where this page lives: {org, team, layer, contentRoot}, or null outside every content root (team is null in the private space). Scope a query to the page's team with where: {orgs: [org], teams: [team]}. |
openFile | Open a file in the viewer: openFile(path) or openFile({path, team?, newTab?}). path is absolute (a queryContext row's path) inside a synced team's content root, or relative to the page's own root; another team's file switches to that team. |
setField | Write one frontmatter key of a content file: setField({path, field, value}); value null removes the key, numbers stay numbers. {path, fields} writes several keys at once. |
setBadge | Show a count on the pane's panel title: setBadge({count, severity?: 'info'|'warning'|'error'}); setBadge(null) clears it. |
sprints | The team's sprints. |
taxonomy | The team's statuses. |
routines | Every routine you can see, as routine_list returns it: [{id, name, scope, schedule_in_words, enabled, next_run_at, last_run, needs_you, ...}]. |
routine | One routine in full, as routine_get returns it: routine({key}) → {id, routine, runs, ...}. |
routineRuns | A routine's run history, newest first, as routine_runs returns it: routineRuns({key, limit?, before?}) → {runs, next_before}. |
routineRun | One routine run with its routine, as routine_run returns it: routineRun({runId}). |
runs | The latest outcome of every agent run, newest first, as list_runs returns it: runs({limit?}) → [{outcome, validated, has_structured_transcript}]. |
run | One agent run in full, as read_run returns it: run({runId, maxArtifactBytes?}) → {outcome, transcript, artifact, artifactTruncated}. |
runEvidence | One agent run's evidence, as read_run_evidence returns it: runEvidence({runId, storyId?}) → {header, run: {steps: [{nodeId, attempts}]}, perNodeResults, authority} or null. storyId defaults to the run's own story. |
runWorkProduct | The git branch an agent run produced, as read_run_work_product returns it: runWorkProduct({runId}) → {branch} or null. |
worktrees | This Mac's managed worktrees, as list_worktrees returns them: {rows, reaped}. |
machines | The machines the page's team sees, as list_machines returns them: [{machineId, kind, label, scope, status, attention, ...}]. |
onRoutinesChanged | Run a callback whenever a routine or one of its runs changes; re-read then. Returns an unsubscribe function. |
onMachinesChanged | Run a callback whenever a machine is saved, removed, shared or changes connection state; re-read then. Returns an unsubscribe function. |
onWorktreesChanged | Run a callback whenever a managed worktree is added or removed; re-read then. Returns an unsubscribe function. |
Read methods
Call these with invoke(name, args).
| Method | Tier | What it does |
|---|---|---|
getDependencyStatus | exempt | Dependency and health status. |
analyze | exempt | Run the user's own agent CLI once over {prompt, data} and return the text. No tools, one turn. |
getEpicHandle | exempt | The containing epic's document path when the page is inside an open epic workspace, else null. |
getDocDir | exempt | The page's own absolute directory, or null. |
queryContext | exempt | Find context files by metadata (the same engine as the query_context MCP tool and csquery blocks). |
context | exempt | Where the page lives: {org, team, layer, contentRoot}, or null. |
sessions | exempt | Every running agent session, as list_sessions lists it. |
agents | exempt | The agents you can launch, including the built-in starters. |
agent | exempt | One saved agent with the sessions running it: {key} → the agent_get data plus instances. |
inbox | exempt | The page team's inbox messages, newest first: {scope?: to-human | to-agents | all, agentId?, sessionId?, role?, limit?} → {messages, humanUnread}. Marks nothing read. |
roles | exempt | The page team's role queues: {role?, limit?} → {roles: [{role, roleName, registrations, counts, deliveries}]}. Claims nothing. |
updates | exempt | The page team's latest agent updates (the Inbox pane's Updates lane): {limit?} → {updates}. |
humanStatus | exempt | Your status in the page's team: {status: online | away | busy | offline, note?, updatedAtMs}. |
watchInbox | exempt | Confirms the host pushes codesense:inbox-changed into the page; listen for it and re-read. |
watchAgentInbox | exempt | As watchInbox, optionally naming one agent: {agentId?}. |
watchAgentActivity | exempt | Confirms the host pushes codesense:agent-activity-changed into the page; listen for it and re-read. |
routines | exempt | Every routine you can see (the routine_list data). |
routine | exempt | One routine in full: {key} → the routine_get data. |
routineRuns | exempt | A routine's run history, newest first: {key, limit?, before?} → the routine_runs data. |
routineRun | exempt | One routine run with its routine: {runId} → the routine_run data. |
runs | exempt | The latest outcome of every agent run, newest first: {limit?} → the list_runs rows. |
run | exempt | One agent run's outcome, transcript and captured output: {runId, maxArtifactBytes?} → the read_run result. |
runEvidence | exempt | One agent run's audit header, step and attempt spine, and per-step reported results: {runId, storyId?} → the read_run_evidence result. |
runWorkProduct | exempt | The git branch an agent run produced: {runId} → the read_run_work_product result. |
worktrees | exempt | This Mac's managed worktrees: the list_worktrees result. |
machines | exempt | The machines the page's team sees: the list_machines result for its org and team. |
validateYaml | exempt | Validate a YAML document against a known kind (agent, routine, team, org, story-frontmatter, epic-frontmatter, worktree, bundle): {kind, text} → {ok, errors}. Pure parse; no writes. |
prefs | exempt | This dashboard's own settings object, kept in your app state per dashboard instance ({} at first). |
Action verbs
Call these with act(verb, args).
| Verb | Tier | Arguments | What it does | Example rejection |
|---|---|---|---|---|
routineResult | read | {key: string} | Read a private cached structured routine result; never launches. Returns snapshot, latest_attempt, revision and schema_compatible. | unavailable: |
routineStatus | read | {key: string} | Read cached routine result and latest attempt status, without launches. | unavailable: |
routineRefresh | spawn | {key: string, variables?: Record<string,string>} | Explicitly refresh through existing routine admission, profile, overlap and runtime policy. Call it only from an explicit user action. | busy |
routineCancel | manage | {key: string} | Cancel this principal's live structured result runs for a routine, retaining last-good data. | unavailable: |
setStatus | metadata | {path: string | string[], status: string} | Set a scanned doc's status frontmatter. The batch form (path[]) applies best-effort and resolves to a per-item result array. | denied: write budget |
setField | metadata | {path: string, field: string, value: string | number | boolean | Array<string|number|boolean> | null} | {path: string, fields: Record<string, …>} | Write top-level frontmatter keys of a content file (.md, or a mapped cs:* meta in .html) inside a team or private content root: value: null removes the key, numbers/booleans are written as YAML numbers/booleans, lists as block lists. | denied: write budget |
setPrefs | metadata | Record<string, JSON> (a key set to null is removed) | Merge keys into this dashboard's own settings (read them back with codesense.prefs()), kept in the user's app state across restarts — a frame's localStorage is not (its origin changes every launch). | denied: prefs budget |
routeToContext | metadata | {codeRepoPath, codeRepoSlug, logicalName, layer?} | Route a source-repo file into a CodeSense context layer. | denied: route not applied (…) |
draft | metadata | {level: string, from: string} | Create + seed a new managed content doc derived from from at tier level. | unmanaged (verbatim CodeSense reject) |
openWorkspace | spawn | {storyId: string} | {target: {kind: 'story'|'epic'|'branch'|'dir', storyId?, session?, title?, agent?, team?, epic?, repo?, branch?, path?}, headed?: boolean, initialPrompt?: string, sessionMode?: 'new'|'focus'} | Open a workspace — the generic open primitive. | busy |
openFile | spawn | {path: string, team?: string, newTab?: boolean} | Open a file in the CodeSense viewer. path is an absolute path (e.g. a queryContext() row's path) inside any synced team's content root, or a path relative to the page's own content root; with team it is relative to that team's content root in the page's org. | refused: |
runPrompt | spawn | {target: string, prompt: string} | Drive a prompt into an already-live story session (supersedes the retired fireSkill). | unavailable: |
sendToSession | send | {target: string, text: string} | Inject a chat turn into a story's already-running agent session. | denied: send budget |
readWorkspace | read | {path: string} | Read a file (or list a dir with a trailing /) strictly within the doc's own directory subtree on a managed surface. The doc supplies only path; the extension whitelist, ../symlink confinement, and size/binary guards are all enforced CodeSense-side. | traversal: |
runSkill | spawn | {skill: string, args: string[]} | Deprecated → prefer runPrompt (a prompt into a real, observable session) or openWorkspace({headed:false, initialPrompt}). Runs a registered skill on the user's agent CLI (detached, headless) with tool use enabled + multi-turn — the write-capable sibling of analyze. | not-allowed: |
openTab | spawn | {workspaceId: string, agent?: boolean} | Add a new terminal tab to an already-open generic (dir) workspace and return its addressable {sessionId}. The tab spawns at the workspace cwd; agent:true also launches the agent CLI into it so it can host prompts. | not-allowed: openTab targets generic (dir) workspaces only |
sendToWorkspaceTab | send | {sessionId: string, mode: 'command'|'prompt', text: string} | Deliver text to a specific generic-workspace tab addressed by the sessionId returned from openTab. command submits to the shell; prompt injects into a verified-live agent (refuses no-agent-in-tab when the tab hosts no live agent — a prompt never lands in a bare shell). | no-agent-in-tab |
getWorkspaceStatus | read | {storyId: string} | Return {exists, live, sessionId} for a story's workspace, so a board renders the honest affordance — exists:false → Launch, exists:true → Focus, live:true → running — for a story it did not itself open. | unavailable: |
closeWorkspace | manage | {target: string, removeWorktree?: boolean, discardUnsaved?: boolean} | The close half of a board-owned session lifecycle, with an optional destructive escalation. Base behavior: close a session the board opened, addressed by the same opaque handle it opened/sends with (a storyId, a {repo}#{branch}, or an epicDocPath). | unavailable: |
closeTerminalTab | manage | {handle: string} | Close one terminal tab opened via openWorkspace/openTab (or minted by open_terminal_tab/open_remote_tab MCP), the symmetric counterpart of the open verbs. handle is the opaque tab handle a sessions() row carries (a raw sessionId is refused with unknownHandle). | unavailable: |
stopSession | manage | {handle: string} | Stop any live session by the handle a sessions() row carries, as the Agents panel's Stop does (a dispatched Weft worker is marked needs-attention first; frees its concurrency slot, writes one audit line). Idempotent: a handle with no live session is a no-op, so a page can stop defensively. | unavailable: |
postMessage | send | {to: string, text: string, onClick?: {type: 'goto-agent', agentId} | {type: 'open-file', path} | {type: 'show-message'}} | Send a message from a dashboard pane into the active team's inbox. to is a role name (an agent id) or the literal "human"; the message writes an inbox row and (for a role) a pending wv_role_delivery row in one commit. | denied: send budget |
sendAsHuman | send | {to: string, text: string, contentType?: 'plain'|'markdown'|'html', onClick?: {type: 'goto-agent', agentId} | {type: 'open-file', path} | {type: 'show-message'}, attachFile?: string, replyTo?: string, summary?: string} | Send a message as the human. to is a running session (a sessions() handle; the mail lands in that session's own inbox and its hooks tell it at turn end) or, failing that, a role (any role name, usually a saved Agent's id) queued in the page's team for whichever instance claims it. | denied: send budget |
replyAsHuman | send | {messageId: number, text: string, contentType?: 'plain'|'markdown'|'html', summary?: string} | Reply as the human to an inbox() message, exactly as the Inbox pane's reply does: the reply goes only to the message's replyTo when it has one (for role:<id>, queued as a pending delivery for that role), else to its sender, threaded under it, and the original is marked read. | denied: send budget |
markRead | metadata | {messageIds: number[]} | Mark messages to the human read, as opening them in the Inbox does (inbox() row unread turns false; a message to anyone else is left alone). Resolves {marked: n}. | denied: write budget |
setHumanStatus | metadata | {status: 'online'|'away'|'busy'|'offline', note?: string} | Set the human's status in the page's team (what agents read with get_human_status to decide whether to ping): online, away (short break), busy (heads-down; only critical pings), offline (out). note is a short free-text hint (<=200 chars). | denied: write budget |
gotoAgent | spawn | {agentId: string} | Focus the agent's running terminal — the same gesture as clicking the agent's status chip in the Agents panel (onLocate). agentId is the bare agent definition id (AgentRow.key's last segment, or the prefix of agentRevision). | unavailable: |
Tiers
| Tier | Verbs | Guards |
|---|---|---|
metadata | setStatus, setField, setPrefs, routeToContext, draft, markRead, setHumanStatus | Silent frontmatter or file writes. A runaway guard rejects a burst of write calls with denied: write budget. |
spawn | routineRefresh, openWorkspace, openFile, runPrompt, runSkill, openTab, gotoAgent | Opens a workspace or drives an agent. Capped by concurrency; a burst of cap-free opens is rejected with denied: spawn budget. |
send | sendToSession, sendToWorkspaceTab, postMessage, sendAsHuman, replyAsHuman | A chat turn into a running agent. Rate-limited. |
read | routineResult, routineStatus, readWorkspace, getWorkspaceStatus | An audited read. No budget. |
manage | routineCancel, closeWorkspace, closeTerminalTab, stopSession | Closes or stops a session. Audited. |
A failed call rejects the promise with an error whose message starts with a stable prefix, such as denied: write budget, busy or unavailable:. Branch on err.message.startsWith(…).
A minimal page
Add <meta name="cs:type" content="dashboard"> so the page is listed as a dashboard, then call any verb.
<meta name="cs:type" content="dashboard">
<script type="module">
if (window.codesense) {
const res = await window.codesense.queryContext({
where: { kinds: ["story"] },
match: { status: "blocked" },
});
// render res.rows with textContent, then:
await window.codesense.act("openWorkspace", { storyId: "W-5" });
}
</script> This page and the sdk section of get_live_data_contract are built from the same verb tables, so they list the same verbs, tiers and versions. Agents writing a page should call the get_live_data_contract MCP tool first and validate_live_data_doc before saving. See Live-data contract.
Generated from app @ 1b3d5a69d73473db077dfb44f4390b42cded6bd4 Regenerate: pnpm gen:reference
How we know this is accurate 3 sources
Checked against the app at 1b3d5a69d73473db077dfb44f4390b42cded6bd4.
Code
-
src/features/dashboard/components/html-bridge.ts -
src-tauri/src/mcp/live_data_authoring.rs -
src-tauri/src/http/routes/viewer.rs