@canonmsg/agent-sdk 12.5.1 → 13.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +57 -24
  2. package/dist/chunks/{chunk-C2WJT3VX.js → chunk-5WPAB5MB.js} +1047 -856
  3. package/dist/chunks/{chunk-3KFVBOVI.js → chunk-DNHJGAEL.js} +1115 -1020
  4. package/dist/chunks/chunk-DTAWEQCM.js +406 -0
  5. package/dist/chunks/{chunk-TFSURFF6.js → chunk-TYZT346O.js} +1720 -4006
  6. package/dist/chunks/chunk-YHDDOADK.js +118 -0
  7. package/dist/chunks/chunk-YJUPKU47.js +1490 -0
  8. package/dist/chunks/{mls-crypto-Y44BOSEM.js → mls-crypto-NZVMSUFU.js} +2 -1
  9. package/dist/cli.js +86 -48
  10. package/dist/drivers/acp.d.ts +56 -0
  11. package/dist/drivers/codex.d.ts +1 -2
  12. package/dist/drivers/subprocess.d.ts +38 -0
  13. package/dist/index.d.ts +4 -2
  14. package/dist/index.js +12 -3
  15. package/dist/internal/backend-contracts/endpointContentPolicy.d.ts +2 -2
  16. package/dist/internal/backend-contracts/index.d.ts +1 -0
  17. package/dist/internal/backend-contracts/loggedOutSessions.d.ts +7 -0
  18. package/dist/internal/backend-contracts/mlsDevCredential.d.ts +3 -0
  19. package/dist/internal/backend-contracts/mlsDevGroup.d.ts +17 -0
  20. package/dist/internal/core/completed-output-journal.d.ts +0 -5
  21. package/dist/internal/core/index.d.ts +3 -9
  22. package/dist/internal/core/retry.d.ts +2 -89
  23. package/dist/internal/core/silent-turn.d.ts +4 -33
  24. package/dist/internal/endpoint/engine.d.ts +6 -0
  25. package/dist/internal/endpoint/mls-dev-client.d.ts +2 -0
  26. package/dist/internal/endpoint/mls-dev-groups.d.ts +12 -0
  27. package/dist/internal/endpoint/mls-dev-text.d.ts +32 -0
  28. package/dist/internal/endpoint/node-mls-custody-protocol.d.ts +5 -0
  29. package/dist/internal/endpoint/node.d.ts +1 -0
  30. package/dist/internal/endpoint/transport.d.ts +1 -1
  31. package/dist/media.js +4 -2
  32. package/dist/mls/darwin-arm64/canon-mls-custody +0 -0
  33. package/dist/mls/linux-arm64/canon-mls-custody +0 -0
  34. package/dist/mls/linux-x64/canon-mls-custody +0 -0
  35. package/dist/mls/wasm/canon_mls_wasm.js +363 -0
  36. package/dist/mls/wasm/canon_mls_wasm_bg.wasm +0 -0
  37. package/dist/mls-wasm-host.js +258 -0
  38. package/dist/runner/mls-bundled.d.ts +15 -2
  39. package/dist/runner/mls-managed.d.ts +6 -3
  40. package/dist/runner/mls.d.ts +4 -7
  41. package/dist/runner/runner.d.ts +9 -12
  42. package/dist/runner/types.d.ts +37 -1
  43. package/package.json +1 -1
  44. package/dist/internal/core/approval-manager.d.ts +0 -43
  45. package/dist/internal/core/runtime-request-manager.d.ts +0 -283
  46. package/dist/internal/core/turn-verbosity.d.ts +0 -79
@@ -2,7 +2,8 @@ import {
2
2
  createMlsDevCredentialVerifier,
3
3
  mlsDevDeviceHttpConfiguration,
4
4
  parseMlsDevClientConfiguration
5
- } from "./chunk-C2WJT3VX.js";
5
+ } from "./chunk-YHDDOADK.js";
6
+ import "./chunk-5WPAB5MB.js";
6
7
  export {
7
8
  createMlsDevCredentialVerifier,
8
9
  mlsDevDeviceHttpConfiguration,
package/dist/cli.js CHANGED
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  MLS_SETUP_ACTIONS,
4
- assertPrivateHome,
4
+ acpDriver,
5
5
  awaitErrand,
6
+ checkAcp,
6
7
  checkCodex,
7
8
  claudeDriver,
8
9
  codeDriver,
@@ -20,10 +21,13 @@ import {
20
21
  readRelayCredential,
21
22
  relayRunnerHome,
22
23
  runMlsDevSetup,
23
- runnerLockName,
24
24
  startRelayChannel,
25
25
  writeRelayCredential
26
- } from "./chunks/chunk-3KFVBOVI.js";
26
+ } from "./chunks/chunk-DNHJGAEL.js";
27
+ import {
28
+ assertPrivateHome,
29
+ runnerLockName
30
+ } from "./chunks/chunk-DTAWEQCM.js";
27
31
  import {
28
32
  CanonApiError,
29
33
  CanonClient,
@@ -34,11 +38,13 @@ import {
34
38
  resolveCanonRuntimeConnection,
35
39
  runCli,
36
40
  verifyCanonRuntimeConnection
37
- } from "./chunks/chunk-TFSURFF6.js";
41
+ } from "./chunks/chunk-TYZT346O.js";
42
+ import "./chunks/chunk-YJUPKU47.js";
43
+ import "./chunks/chunk-YHDDOADK.js";
38
44
  import {
39
45
  __name,
40
46
  isCanonClientVersion
41
- } from "./chunks/chunk-C2WJT3VX.js";
47
+ } from "./chunks/chunk-5WPAB5MB.js";
42
48
 
43
49
  // src/cli.ts
44
50
  import { realpathSync } from "node:fs";
@@ -67,6 +73,8 @@ Usage:
67
73
  canon-agent run --driver codex [--cwd <dir>] [--model <id>] [--sandbox <mode>]
68
74
  [--approval-policy <policy>] [--codex-path <path>] [--profile <name>]
69
75
  [--environment <id>]
76
+ canon-agent run --driver acp [--cwd <dir>] [--guest-mode <id> | --unguarded-guests]
77
+ [--profile <name>] [--environment <id>] -- <agent command> [args]
70
78
  canon-agent run --driver connector --relay-config <path> [--mls-dev-config <path>]
71
79
  [--profile <name>] [--environment <id>]
72
80
  canon-agent mls --action <action> [--mls-dev-config <path>] [--room <id>]
@@ -81,34 +89,36 @@ Usage:
81
89
  canon-agent errands [--follow] [--cancel <errand id>] (--agent <id> | --profile <name>)
82
90
  [--environment <id>]
83
91
 
84
- Encrypted rooms need the agent's MLS device. On macOS (Apple silicon) and Linux
85
- (x64, arm64) the runner keeps it in $CANON_HOME with the custody helper this package
86
- ships, and sets it up on the agent's first start: nothing to configure. Every run
87
- command also takes --mls-dev-config <path>, an operator's own custody instead. With
88
- neither, the agent refuses encrypted rooms, and where Canon encrypts every new
89
- conversation it does not start.
92
+ Every room is encrypted, so the agent needs its MLS device. The runner keeps it in
93
+ $CANON_HOME and sets it up on the agent's first start: nothing to configure. On macOS
94
+ (Apple silicon) and glibc Linux (x64, arm64) it uses the custody helper this package
95
+ ships; on Windows, Intel Macs and musl Linux, this package's WASM core. Every run
96
+ command also takes --mls-dev-config <path>, an operator's own custody instead. With none
97
+ of these, the agent refuses every room, and where Canon encrypts every new conversation
98
+ it does not start.
90
99
 
91
- Team rooms (an owner's agents working together): claude and codex also take
100
+ Team rooms (an owner's agents working together): claude, codex and acp also take
92
101
  [--instructions <file>] [--trust-agent <agentId>]...; every run command takes
93
- [--agent-turn-cap <n>] [--mention-alias <name>]..., which apply in encrypted rooms.
94
- code, claude and codex take [--allow-session-for-destructive] for encrypted cards.
102
+ [--agent-turn-cap <n>] [--mention-alias <name>]....
103
+ code, claude, codex and acp take [--allow-session-for-destructive] for encrypted cards.
95
104
 
96
105
  Errands: tell, post and errand direct a running agent from the machine it runs on:
97
106
  whoever can write $CANON_HOME commands it, and the CLI itself uses no network. tell
98
107
  leaves a private note for the agent's next turn in a room: never posted, it starts no
99
- turn. post sends the text as the agent's own message, with no turn (encrypted in an
100
- encrypted room). errand runs one owner-authorised turn that carries the instruction to
101
- the recipient (a room the agent is in, or a new conversation with a person or agent),
102
- reports to --origin, and tells later turns there why the agent came. What concerns an
103
- encrypted room is reported only to an encrypted origin; otherwise the report stays
104
- local (canon-agent errands). Canon's policies, blocks and rate limits apply as to any
105
- message from the agent.
108
+ turn. post sends the text, encrypted, as the agent's own message, with no turn. errand
109
+ runs one owner-authorised turn that carries the instruction to the recipient (a room
110
+ the agent is in, or a new conversation with a person or agent), reports to --origin,
111
+ and tells later turns there why the agent came. Without --origin the report stays local
112
+ (canon-agent errands). Canon's policies, blocks and rate limits apply as to any message
113
+ from the agent.
106
114
 
107
115
  Flags:
108
- --driver <name> The runtime driver: "code", "claude", "codex" or "connector".
116
+ --driver <name> The runtime driver: "code", "claude", "codex", "acp" or
117
+ "connector". acp runs any agent that speaks the Agent Client
118
+ Protocol over stdio, named after --: -- goose acp.
109
119
  --module <path> code: an ES module whose default export answers a turn.
110
120
  Its directory is one the agent may send files from.
111
- --cwd <dir> claude, codex: the directory the runtime works in (default:
121
+ --cwd <dir> claude, codex, acp: the directory the runtime works in (default:
112
122
  the current one). The agent may send files from it.
113
123
  --model <id> claude, codex: the model (default: the runtime's).
114
124
  --permission-mode <m> claude: "default" puts each tool call Claude Code would ask
@@ -124,28 +134,34 @@ Flags:
124
134
  Turns holding anyone else's message are always read-only,
125
135
  approve nothing and get only Canon's tools.
126
136
  --codex-path <path> codex: the Codex CLI (default: codex on the PATH).
127
- --instructions <file> claude, codex: standing instructions from the owner (a role,
128
- say), appended to the runtime's system or developer
129
- instructions. A UTF-8 file of at most 32 KiB, owned by you
137
+ --guest-mode <id> acp: the agent's own read-only session mode, for turns holding
138
+ anyone else's message, such as chat on Goose. Without this
139
+ the agent is not started for such a turn, and the person
140
+ is told it takes only its owner's messages.
141
+ --unguarded-guests acp: run such turns under the agent's own policy instead. The
142
+ driver only refuses permission requests and stops a turn
143
+ if the agent reports a machine tool, so an agent that runs
144
+ tools unasked runs them on this machine for anyone.
145
+ --instructions <file> claude, codex, acp: standing instructions from the owner (a role,
146
+ say), added to the runtime's system or developer
147
+ instructions, or to a session's first prompt. A UTF-8 file of at most 32 KiB, owned by you
130
148
  and not writable by others, read once at start; never sent
131
149
  to Canon.
132
- --trust-agent <id> claude, codex: an agent of the same owner whose messages count
150
+ --trust-agent <id> claude, codex, acp: an agent of the same owner whose messages count
133
151
  as the owner's for tool use (repeat for several), only in a
134
152
  room whose other members are all listed agents that Canon
135
153
  confirms at each turn as active agents of this agent's
136
- owner (and, in plaintext, only for a final that agent's own
137
- runner marked as answering its owner). Otherwise they are
138
- guarded like any other agent's. Approvals still go to the
139
- owner.
140
- --agent-turn-cap <n> Encrypted rooms: another agent's message wakes this agent only
141
- when it @mentions it (by display name, id or an alias), at
142
- most n times in a row per room until a person writes there
143
- (default 6; 0: agents never wake it). Plaintext rooms
144
- follow Canon's group rules.
145
- --mention-alias <name> Encrypted rooms: another name that @mentions this agent, such
146
- as its role (repeat for several).
154
+ owner. Otherwise they are guarded like any other agent's.
155
+ Approvals still go to the owner.
156
+ --agent-turn-cap <n> Another agent's message wakes this agent only when it
157
+ @mentions it (by display name, id or an alias), at most n
158
+ times in a row per room until a person writes there
159
+ (default 6; 0: agents never wake it). The room's own
160
+ rules can stop them sooner.
161
+ --mention-alias <name> Another name that @mentions this agent, such as its role
162
+ (repeat for several).
147
163
  --allow-session-for-destructive
148
- Encrypted rooms: let the owner allow an action the runtime
164
+ Let the owner allow an action the runtime
149
165
  marks destructive (Claude Code's default-to-no prompts,
150
166
  Codex's risky commands and deletions) for the rest of the
151
167
  session. Off by default: each such action asks.
@@ -173,10 +189,9 @@ Flags:
173
189
  --text <text> tell: the note. post: the message. errand: the instruction.
174
190
  At most 32 KiB.
175
191
  --to <id> errand: a conversation the agent is in, or else a person or
176
- agent to start a new (plaintext) conversation with.
192
+ agent to start a new conversation with.
177
193
  --why <why> errand: why the owner sends the agent (at most 4 KiB).
178
- --origin <id> errand: the conversation the report goes to. A report about an
179
- encrypted recipient goes only to an encrypted origin.
194
+ --origin <id> errand: the conversation the report goes to.
180
195
  --follow errands: go on printing each change.
181
196
  --cancel <id> errands: cancel that errand (Stop in its origin also stops it).
182
197
  --agent <id> tell, post, errand, errands: the agent (or --profile).
@@ -192,15 +207,17 @@ Flags:
192
207
  Environment:
193
208
  CANON_API_KEY The agent's key (or use --profile).
194
209
  CANON_ENVIRONMENT_ID Required; a profile from another environment is refused.
195
- CANON_HOME Agent state, default ~/.canon. It must be private (0700).
210
+ CANON_HOME Agent state, default ~/.canon. It must be private (0700; on
211
+ Windows, only you, SYSTEM and Administrators in its access list).
196
212
  ANTHROPIC_API_KEY claude: use this API key instead of a Claude subscription
197
213
  login. The claude driver needs @anthropic-ai/claude-agent-sdk.
198
214
  OPENAI_API_KEY codex: use this API key instead of Codex's own login, unless
199
215
  Codex is configured for another model provider.
200
216
 
201
217
  SIGTERM or Ctrl-C stops taking messages, lets running turns finish for 10 seconds,
202
- then stops them.`;
203
- var AVAILABLE = ["code", "claude", "codex", "connector"];
218
+ then stops them. Windows has no SIGTERM: use Ctrl-C or Ctrl-Break, which is what a
219
+ service wrapper such as NSSM sends. Closing the console gives far less time.`;
220
+ var AVAILABLE = ["code", "claude", "codex", "acp", "connector"];
204
221
  var PERMISSION_MODES = ["default", "acceptEdits", "bypassPermissions"];
205
222
  var SANDBOXES = ["workspace-write", "read-only", "danger-full-access"];
206
223
  var APPROVAL_POLICIES = ["on-request", "untrusted", "never"];
@@ -225,7 +242,7 @@ async function main() {
225
242
  throw new UsageError(error instanceof Error ? error.message : String(error));
226
243
  }
227
244
  const { values, positionals } = parsed;
228
- if (!["run", "mls", "tell", "post", "errand", "errands"].includes(positionals[0] ?? "") || positionals.length > 1) {
245
+ if (!["run", "mls", "tell", "post", "errand", "errands"].includes(positionals[0] ?? "") || positionals.length > 1 && positionals[0] !== "run") {
229
246
  throw new UsageError('Expected the "run", "mls", "tell", "post", "errand" or "errands" command.');
230
247
  }
231
248
  if (positionals[0] === "mls") return mlsSetup(values);
@@ -237,9 +254,13 @@ async function main() {
237
254
  }
238
255
  if (values.driver === "code" && !values.module) throw new UsageError("--driver code needs --module <path>.");
239
256
  if (values.driver === "connector" !== !!values["relay-config"]) throw new UsageError("--relay-config goes with --driver connector, which needs it.");
240
- if (!["claude", "codex"].includes(values.driver) && (values.instructions !== void 0 || values["trust-agent"]?.length)) {
241
- throw new UsageError("--instructions and --trust-agent go with --driver claude or codex.");
257
+ if (!["claude", "codex", "acp"].includes(values.driver) && (values.instructions !== void 0 || values["trust-agent"]?.length)) {
258
+ throw new UsageError("--instructions and --trust-agent go with --driver claude, codex or acp.");
242
259
  }
260
+ const [agentCommand, ...agentArgs] = positionals.slice(1);
261
+ if (values.driver === "acp" !== !!agentCommand) throw new UsageError("--driver acp needs its agent's command after --, and only it takes one: canon-agent run --driver acp -- goose acp.");
262
+ if (values.driver !== "acp" && (values["guest-mode"] !== void 0 || values["unguarded-guests"])) throw new UsageError("--guest-mode and --unguarded-guests go with --driver acp.");
263
+ if (values["guest-mode"] !== void 0 && values["unguarded-guests"]) throw new UsageError("--guest-mode and --unguarded-guests are alternatives.");
243
264
  const team = teamOptions(values);
244
265
  if (values.driver === "connector" && values["allow-session-for-destructive"]) throw new UsageError("--allow-session-for-destructive goes with a driver that asks.");
245
266
  if (values.driver === "connector") return runRelay(values, team);
@@ -282,6 +303,20 @@ async function main() {
282
303
  ...approvalPolicy ? { approvalPolicy } : {},
283
304
  ...instructions ? { instructions } : {}
284
305
  });
306
+ } else if (values.driver === "acp") {
307
+ const cwd = resolve(values.cwd ?? ".");
308
+ const agent = await checkAcp({ command: agentCommand, args: agentArgs, cwd });
309
+ console.error(`canon-agent: ${agent.name}${agent.version ? ` ${agent.version}` : ""} speaks the Agent Client Protocol; ${agent.sessionMemory === "native" ? "it keeps each room's session" : "it keeps no session, so prompts carry recent history"}.`);
310
+ driver = acpDriver({
311
+ command: agentCommand,
312
+ args: agentArgs,
313
+ cwd,
314
+ sessionMemory: agent.sessionMemory,
315
+ ...values["guest-mode"] ? { guestMode: values["guest-mode"] } : {},
316
+ ...values["unguarded-guests"] ? { unguardedGuests: true } : {},
317
+ ...instructions ? { instructions } : {}
318
+ });
319
+ if (!values["guest-mode"] && !values["unguarded-guests"]) console.error("canon-agent: it takes only its owner's messages. To let others reach it, give --guest-mode with a read-only mode of the agent's own.");
285
320
  } else {
286
321
  const modulePath = realpathSync(resolve(values.module));
287
322
  const handler = (await import(pathToFileURL(modulePath).href)).default;
@@ -425,6 +460,8 @@ function parse() {
425
460
  sandbox: { type: "string" },
426
461
  "approval-policy": { type: "string" },
427
462
  "codex-path": { type: "string" },
463
+ "guest-mode": { type: "string" },
464
+ "unguarded-guests": { type: "boolean" },
428
465
  "mls-dev-config": { type: "string" },
429
466
  action: { type: "string" },
430
467
  room: { type: "string" },
@@ -573,6 +610,7 @@ function stopOnSignals(stop) {
573
610
  }, "onSignal");
574
611
  process.on("SIGTERM", onSignal);
575
612
  process.on("SIGINT", onSignal);
613
+ if (process.platform === "win32") for (const signal of ["SIGBREAK", "SIGHUP"]) process.on(signal, onSignal);
576
614
  }
577
615
  __name(stopOnSignals, "stopOnSignals");
578
616
  runCli(import.meta.url, main, (error) => {
@@ -0,0 +1,56 @@
1
+ import { type DriverCapabilities, type RuntimeDriver } from '../runner/types.js';
2
+ export interface AcpDriverOptions {
3
+ /** The agent's executable, e.g. `goose`, found on the PATH. */
4
+ command: string;
5
+ /** Its arguments, e.g. `['acp']`. */
6
+ args?: string[];
7
+ /** The directory the agent works in. The agent may also send files from it. */
8
+ cwd: string;
9
+ /**
10
+ * `native` when the agent keeps a session across its processes; `none` (the default) makes every prompt carry the recent
11
+ * history. `checkAcp` reports which one an agent is.
12
+ */
13
+ sessionMemory?: DriverCapabilities['sessionMemory'];
14
+ /**
15
+ * What a turn holding a message from anyone but the owner or a confirmed trusted agent of the owner does. By default the
16
+ * agent is not started and the person is told it takes only its owner's messages, because nothing here can limit what
17
+ * an arbitrary agent runs. `guestMode` runs it in that session mode instead: a read-only mode of the agent's own, such
18
+ * as `chat` on Goose. Such a turn fails if the agent refuses the mode.
19
+ */
20
+ guestMode?: string;
21
+ /**
22
+ * Run such a turn under the agent's own policy, with no mode. The driver then only refuses permission requests and stops
23
+ * the turn when the agent reports a machine tool running: an agent that does neither runs what the message asks, on
24
+ * this machine. Only for an agent whose developer has limited it some other way.
25
+ */
26
+ unguardedGuests?: boolean;
27
+ /**
28
+ * The owner's standing instructions for this agent (its role, say), added to the first prompt of a session after Canon's
29
+ * own framing, since the protocol has no system prompt. At most 32 KiB; the CLI reads them from `--instructions <file>`.
30
+ */
31
+ instructions?: string;
32
+ /** How long a cancelled agent may take to stop, and an agent with its input closed to exit (default 5 s). */
33
+ interruptGraceMs?: number;
34
+ }
35
+ /** What `initialize` told the driver about an agent. */
36
+ export interface AcpAgent {
37
+ name: string;
38
+ version: string;
39
+ sessionMemory: DriverCapabilities['sessionMemory'];
40
+ }
41
+ /** Checks the agent starts and speaks the protocol; the CLI calls it at startup so a wrong command fails at once. */
42
+ export declare function checkAcp({ command, args, cwd, timeoutMs }: Pick<AcpDriverOptions, 'command' | 'args' | 'cwd'> & {
43
+ timeoutMs?: number;
44
+ }): Promise<AcpAgent>;
45
+ /**
46
+ * Runs an agent that speaks the Agent Client Protocol (v1, JSON-RPC over stdio), which most coding agents do. Each turn is
47
+ * one process that restores the room's session, whose id the runner keeps in the driver state, and exits after the turn:
48
+ * Canon's tool URL and token change per turn, and a session takes its MCP servers only when opened. Stop cancels the
49
+ * native turn and closes a process that does not stop. A room's next turn starts only after the previous process has exited.
50
+ *
51
+ * Unlike the claude and codex drivers, this one cannot configure a sandbox: what runs on the machine is the agent's own
52
+ * policy, which its developer sets. So a turn holding anyone else's message runs only if the owner chose how (`guestMode`
53
+ * or `unguardedGuests`), approves nothing, and stops when the agent reports a machine tool running or leaves that mode.
54
+ * Only the mode is a real limit, since the agent enforces it; the rest depends on what the agent reports.
55
+ */
56
+ export declare function acpDriver(options: AcpDriverOptions): RuntimeDriver;
@@ -1,4 +1,5 @@
1
1
  import { type DriverTurn, type RuntimeDriver } from '../runner/types.js';
2
+ import { type Json } from './subprocess.js';
2
3
  export interface CodexDriverOptions {
3
4
  /** The directory Codex works in. The agent may also send files from it. */
4
5
  cwd: string;
@@ -22,7 +23,6 @@ export interface CodexDriverOptions {
22
23
  /** How long an interrupted Codex may take to stop before its process is closed (default 5 s). */
23
24
  interruptGraceMs?: number;
24
25
  }
25
- type Json = Record<string, unknown>;
26
26
  /** Checks the Codex CLI runs at all; the CLI calls it at startup so a missing install fails at once. */
27
27
  export declare function checkCodex(codexPath?: string): string;
28
28
  /**
@@ -43,4 +43,3 @@ export declare function answerCodexRequest(turn: DriverTurn, method: string, par
43
43
  * does not stop. A room's next turn starts only after the previous process has exited.
44
44
  */
45
45
  export declare function codexDriver(options: CodexDriverOptions): RuntimeDriver;
46
- export {};
@@ -0,0 +1,38 @@
1
+ import type { spawn } from 'node:child_process';
2
+ import type { AskRequest, DriverTurn } from '../runner/types.js';
3
+ /** What the drivers of runtimes that run as a child process share. */
4
+ export type Json = Record<string, unknown>;
5
+ export declare const isRecord: (value: unknown) => value is Json;
6
+ export declare const text: (value: unknown) => string;
7
+ export declare const oneLine: (value: string, max: number) => string;
8
+ export declare const RISKY: RegExp;
9
+ /**
10
+ * A turn holding a message from anyone but the owner, or an agent the runner confirmed as the owner's trusted teammate,
11
+ * is someone else's: coalesced follow-ups count too.
12
+ */
13
+ export declare const guestTurn: (turn: DriverTurn) => boolean;
14
+ /**
15
+ * RUN-25: one native approval request becomes one `approve` ask. The runner answers a repeated ask id once, so the id also
16
+ * carries what is asked: two requests on one item never share an answer.
17
+ */
18
+ export declare function approve(turn: DriverTurn, request: Omit<Extract<AskRequest, {
19
+ kind: 'approve';
20
+ }>, 'kind'>): Promise<"stopped" | "once" | "session" | "denied">;
21
+ export interface StdioRpcOptions {
22
+ /** The runtime's name, for a refusal that carries no message. */
23
+ name: string;
24
+ /** Sent on every message: `{ jsonrpc: '2.0' }` where the runtime's protocol requires it. */
25
+ envelope?: Json;
26
+ }
27
+ /**
28
+ * JSON-RPC over a child's stdio: one line per message. A refusal rejects with the runtime's numeric `code`. A child that
29
+ * exits always reaches `close`, which otherwise waits for its pipes, so a driver can settle its process there.
30
+ */
31
+ export declare function stdioRpc(child: ReturnType<typeof spawn>, handlers: {
32
+ notify(method: string, params: Json): void;
33
+ request(method: string, params: Json, id: unknown): Promise<unknown>;
34
+ }, { name, envelope }: StdioRpcOptions): {
35
+ call: (method: string, params: Json) => Promise<Json>;
36
+ notify: (method: string, params?: Json) => void;
37
+ fail(error: Error): void;
38
+ };
package/dist/index.d.ts CHANGED
@@ -3,9 +3,9 @@ export type { Runner, RunnerOptions } from './runner/runner.js';
3
3
  export { ConnectorRelayError, DriverSessionError } from './runner/types.js';
4
4
  export { loadMlsDevConfiguration, MLS_SETUP_ACTIONS, mlsDevRoomPackageId, runMlsDevSetup } from './runner/mls.js';
5
5
  export type { MlsSetupAction, RunnerMlsOptions } from './runner/mls.js';
6
- export { bundledMlsCustodyHelper, MLS_ENVIRONMENT_PINS } from './runner/mls-bundled.js';
6
+ export { bundledMlsCustodyHelper, bundledMlsWasmCore, MLS_ENVIRONMENT_PINS, type BundledMlsWasmCore } from './runner/mls-bundled.js';
7
7
  export { managedMlsDevice, type ManagedMlsDevice, type ManagedMlsDeviceOptions } from './runner/mls-managed.js';
8
- export type { ActivityEvent, AskAnswer, AskRequest, DriverCapabilities, DriverResult, DriverState, DriverTurn, ErrandFacts, RuntimeDriver, ToolDefinition, ToolResult, TurnInput, TurnInputMessage, TurnTools, } from './runner/types.js';
8
+ export type { ActivityEvent, AskAnswer, AskRequest, DriverCapabilities, DriverResult, DriverState, DriverTurn, ErrandFacts, RoomFacts, RoomRules, RuntimeDriver, ToolDefinition, ToolResult, TurnInput, TurnInputMessage, TurnTools, } from './runner/types.js';
9
9
  export { errandJournal, errandsDirectory, queueErrand } from './runner/errands.js';
10
10
  export type { ErrandCommand, ErrandInput, ErrandKind, ErrandRecord, ErrandStatus } from './runner/errands.js';
11
11
  export { codeDriver } from './drivers/code.js';
@@ -14,6 +14,8 @@ export { claudeDriver, loadClaudeQuery } from './drivers/claude.js';
14
14
  export type { ClaudeDriverOptions, ClaudeQuery } from './drivers/claude.js';
15
15
  export { checkCodex, codexDriver } from './drivers/codex.js';
16
16
  export type { CodexDriverOptions } from './drivers/codex.js';
17
+ export { acpDriver, checkAcp } from './drivers/acp.js';
18
+ export type { AcpAgent, AcpDriverOptions } from './drivers/acp.js';
17
19
  export { connectorDriver } from './drivers/connector.js';
18
20
  export type { ConnectorDriver, ConnectorInbox } from './drivers/connector.js';
19
21
  export { loadRelayConfiguration, startRelayChannel } from './runner/relay.js';
package/dist/index.js CHANGED
@@ -3,7 +3,10 @@ import {
3
3
  DriverSessionError,
4
4
  MLS_ENVIRONMENT_PINS,
5
5
  MLS_SETUP_ACTIONS,
6
+ acpDriver,
6
7
  bundledMlsCustodyHelper,
8
+ bundledMlsWasmCore,
9
+ checkAcp,
7
10
  checkCodex,
8
11
  claudeDriver,
9
12
  codeDriver,
@@ -21,7 +24,8 @@ import {
21
24
  runMlsDevSetup,
22
25
  runtimeDescriptor,
23
26
  startRelayChannel
24
- } from "./chunks/chunk-3KFVBOVI.js";
27
+ } from "./chunks/chunk-DNHJGAEL.js";
28
+ import "./chunks/chunk-DTAWEQCM.js";
25
29
  import {
26
30
  CanonApiError,
27
31
  DEFAULT_ANTHROPIC_REQUEST_HEADROOM_BYTES,
@@ -46,8 +50,10 @@ import {
46
50
  toAnthropicImageBlock,
47
51
  toAnthropicImageBlocksWithinBudget,
48
52
  uploadMediaFile
49
- } from "./chunks/chunk-TFSURFF6.js";
50
- import "./chunks/chunk-C2WJT3VX.js";
53
+ } from "./chunks/chunk-TYZT346O.js";
54
+ import "./chunks/chunk-YJUPKU47.js";
55
+ import "./chunks/chunk-YHDDOADK.js";
56
+ import "./chunks/chunk-5WPAB5MB.js";
51
57
  export {
52
58
  CanonApiError,
53
59
  ConnectorRelayError,
@@ -60,7 +66,10 @@ export {
60
66
  MAX_CANON_MEDIA_BYTES,
61
67
  MLS_ENVIRONMENT_PINS,
62
68
  MLS_SETUP_ACTIONS,
69
+ acpDriver,
63
70
  bundledMlsCustodyHelper,
71
+ bundledMlsWasmCore,
72
+ checkAcp,
64
73
  checkCodex,
65
74
  claudeDriver,
66
75
  clearPendingRegistration,
@@ -14,8 +14,8 @@ export declare const MLS_DEV_UNSUPPORTED_CONTENT_ACTIONS: readonly ["forward_mes
14
14
  * them through, and any other field still keeps the operation out. */
15
15
  export declare const MLS_DEV_DISCLOSED_PROCESSING_FIELDS: Readonly<Record<string, readonly string[]>>;
16
16
  export declare const ENDPOINT_CONTENT_ACTIONS: readonly ["mls_application", "mls_group_control", "initialize_endpoint", "append_artifact_command", "retain_artifact_asset", "sync_phone_contacts", "update_agent_behavior_policy", "update_conversation_agent_behavior_policy", "send_message", "delete_message", "forward_message", "react", "verb_execute", "send_contextual_message", "create_interaction", "consume_interaction", "start_conversation", "create_conversation", "add_member", "remove_member", "leave_conversation", "update_member_role", "update_conversation", "rename_conversation", "update_topic", "update_group_avatar", "mark_read", "cancel_queued_message", "set_conversation_preferences", "set_block", "save_contact", "remove_contact", "respond_interaction", "session_control", "approve_contact_request", "reject_contact_request", "cancel_direct_request", "update_message_disposition", "create_upload", "finalize_upload", "delete_upload", "retry_video_processing", "stage_media_message", "cancel_media_message", "renew_media_message_upload", "finalize_memo_stream", "abort_memo_stream", "create_voice_session", "join_voice_session", "decline_voice_session", "end_voice_session", "consume_runtime_signal", "consume_runtime_primitive", "generate_image"];
17
- export declare const ENDPOINT_CONTENT_FUNCTION_QUERIES: readonly ["mls_group_feed", "mls_group_controls", "mls_group_admissions", "mls_interactions", "list_artifacts", "get_artifact_log", "get_artifact_asset", "discover_agents", "get_unread_summary", "peek_runtime_signal", "list_runtime_primitives", "get_agent_behavior_policy", "get_conversation_agent_behavior_policy", "get_ephemeral", "list_voice_sessions", "list_contact_requests", "list_conversations", "list_messages", "get_messages", "admission_fences", "list_contacts", "get_contact", "get_members", "resolve_admission", "resolve_group_admission", "get_runtime_card_state", "conversation", "conversation_changes", "get_upload", "get_media_message", "get_voice_session", "get_image_generation", "get_image_generation_status", "same_owner_agents"];
18
- export declare const ENDPOINT_CONTENT_QUERIES: readonly ["mls_group_feed", "mls_group_controls", "mls_group_admissions", "mls_interactions", "list_artifacts", "get_artifact_log", "get_artifact_asset", "discover_agents", "get_unread_summary", "peek_runtime_signal", "list_runtime_primitives", "get_agent_behavior_policy", "get_conversation_agent_behavior_policy", "get_ephemeral", "list_voice_sessions", "list_contact_requests", "list_conversations", "list_messages", "get_messages", "admission_fences", "list_contacts", "get_contact", "get_members", "resolve_admission", "resolve_group_admission", "get_runtime_card_state", "conversation", "conversation_changes", "get_upload", "get_media_message", "get_voice_session", "get_image_generation", "get_image_generation_status", "same_owner_agents", "admit_messages"];
17
+ export declare const ENDPOINT_CONTENT_FUNCTION_QUERIES: readonly ["mls_group_feed", "mls_group_controls", "mls_group_admissions", "mls_interactions", "mls_devices", "list_artifacts", "get_artifact_log", "get_artifact_asset", "discover_agents", "get_unread_summary", "peek_runtime_signal", "list_runtime_primitives", "get_agent_behavior_policy", "get_conversation_agent_behavior_policy", "get_ephemeral", "list_voice_sessions", "list_contact_requests", "list_conversations", "list_messages", "get_messages", "admission_fences", "list_contacts", "get_contact", "get_members", "resolve_admission", "resolve_group_admission", "get_runtime_card_state", "conversation", "conversation_changes", "get_upload", "get_media_message", "get_voice_session", "get_image_generation", "get_image_generation_status", "same_owner_agents"];
18
+ export declare const ENDPOINT_CONTENT_QUERIES: readonly ["mls_group_feed", "mls_group_controls", "mls_group_admissions", "mls_interactions", "mls_devices", "list_artifacts", "get_artifact_log", "get_artifact_asset", "discover_agents", "get_unread_summary", "peek_runtime_signal", "list_runtime_primitives", "get_agent_behavior_policy", "get_conversation_agent_behavior_policy", "get_ephemeral", "list_voice_sessions", "list_contact_requests", "list_conversations", "list_messages", "get_messages", "admission_fences", "list_contacts", "get_contact", "get_members", "resolve_admission", "resolve_group_admission", "get_runtime_card_state", "conversation", "conversation_changes", "get_upload", "get_media_message", "get_voice_session", "get_image_generation", "get_image_generation_status", "same_owner_agents", "admit_messages"];
19
19
  export declare const ENDPOINT_CONTENT_EPHEMERALS: readonly ["prewarm_agents", "create_memo_stream", "publish_presence", "publish_typing", "publish_streaming", "publish_turn", "publish_runtime_status", "publish_session_state", "publish_runtime_info", "publish_runtime_activity", "append_memo_chunk"];
20
20
  export declare const ENDPOINT_CONTENT_EPHEMERAL_FAMILIES: readonly ["typing", "streaming", "turn-state", "agent-session", "runtime-card-state", "memo-streams", "runtime-info", "runtime-activity", "runtime-suppression", "runtime-silence", "runtime-attention", "call-attention", "agent-runtime", "presence"];
21
21
  export declare const ENDPOINT_CONTENT_EVENTS: readonly ["connected", "heartbeat", "agent.context", "replay.expired", "error", "participation.suppressed", "artifact.changed", "message.created", "message.snapshot", "message.updated", "message.deleted", "message.media_terminal", "conversation.updated", "conversation.changed", "conversation.removed", "conversations.changed", "contacts.changed", "contact.added", "contact.updated", "contact.removed", "presence", "typing", "runtime.updated", "runtime.control", "turn.updated", "voice.session.started", "voice.session.ended", ...string[]];
@@ -41,6 +41,7 @@ export * from './artifacts.js';
41
41
  export * from './artifactActions.js';
42
42
  export * from './mlsEnvironment.js';
43
43
  export * from './mlsDevEnrollment.js';
44
+ export * from './loggedOutSessions.js';
44
45
  export * from './mlsDevCredential.js';
45
46
  export * from './mlsDevCredentialReconciliation.js';
46
47
  export * from './mlsDevDeviceCustody.js';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Firebase sessions a device log-out ended (web-mls-device.md, decision 10). Firebase can only revoke every session of an
3
+ * account, so Canon names each ended one by its sign-in time, which a token refresh keeps, and refuses it.
4
+ */
5
+ export declare const LOGGED_OUT_SESSIONS_DOCUMENT = "sessions";
6
+ export declare const SESSION_LOGGED_OUT = "SESSION_LOGGED_OUT";
7
+ export declare function isLoggedOutSession(record: unknown, authTime: number): boolean;
@@ -1,6 +1,9 @@
1
1
  import { type MlsDevEnrollmentDevice } from './mlsDevEnrollment.js';
2
2
  import { type MlsEnvironmentId, type MlsIssuerId } from './mlsEnvironment.js';
3
+ /** The lifetime the issuer gives every device. */
3
4
  export declare const MLS_DEV_CREDENTIAL_TTL_MS = 86400000;
5
+ /** The other lifetime verifiers accept, for a person's device only. Nothing issues it yet (mls-production-cutover.md §6). */
6
+ export declare const MLS_DEV_CREDENTIAL_LONG_TTL_MS: number;
4
7
  export declare const MLS_DEV_CREDENTIAL_CHALLENGE_TTL_MS = 300000;
5
8
  export declare const MLS_DEV_CREDENTIAL_MAX_BYTES = 8192;
6
9
  export interface MlsDevCredentialClaims {
@@ -288,6 +288,23 @@ export declare function parseMlsDevGroupCreateConversation(value: unknown): MlsD
288
288
  export declare function parseMlsDevGroupHead(value: unknown): MlsDevGroupHead;
289
289
  export declare function parseMlsDevGroupMarker(value: unknown): MlsDevGroupMarker;
290
290
  export declare function parseMlsDevGroupRoster(value: unknown): readonly MlsDevGroupRosterEntry[];
291
+ /** How long a room waits for a member who just joined it, or was there at its birth (D2, mls-rooms-by-default.md §2.7). */
292
+ export declare const MLS_MEMBER_JOIN_WAIT_MS = 60000;
293
+ /**
294
+ * Whom a send waits for in a room Canon made; empty means it may go (D2, narrowed 2026-10-31, mls-rooms-by-default.md
295
+ * §2.7). `unacceptedIds` are a direct request's target and founders still invited. `joinedAtMs` is the room's
296
+ * `mlsMemberJoinedAtMs`, NaN when it has none.
297
+ */
298
+ export declare function mlsAdmissionWait(input: {
299
+ senderId: string;
300
+ memberIds: readonly string[];
301
+ unacceptedIds: readonly string[];
302
+ admitted: {
303
+ has(id: string): boolean;
304
+ };
305
+ joinedAtMs: number;
306
+ nowMs: number;
307
+ }): string[];
291
308
  /** Hold, then close (owner ruling 2026-10-16; mls-dev-groups.md): how long an erased member's devices wait for a commit. */
292
309
  export declare const MLS_DEV_ROOM_REMOVAL_DEADLINE_MS: number;
293
310
  export interface MlsDevRoomRemovalEntry {
@@ -32,8 +32,3 @@ export declare function createCompletedOutputJournal<T extends CompletedOutputRe
32
32
  /** Runtime-specific shape check beyond the base fields; false is an invalid record. */
33
33
  validate?: (record: T) => boolean;
34
34
  }): CompletedOutputJournal<T>;
35
- /** A new delivery after restart must not silently adopt a changed audience. */
36
- export declare function assertCompletedOutputAudience(record: Pick<CompletedOutputRecordBase, 'audience'>, current: {
37
- memberIds: string[];
38
- membershipRevision?: number;
39
- } | null, label: string): void;
@@ -26,9 +26,6 @@ export type { RegistrationSession, RegistrationCredentials, RegistrationStore, R
26
26
  export { ensureAgentProfile } from './registration-profile.js';
27
27
  export type { EnsureAgentProfileOptions } from './registration-profile.js';
28
28
  export { submitRegistrationRequest, } from './registration.js';
29
- export { RuntimeRequestManager, RuntimeRequestCancelledError, runtimeInputDescriptor, runtimeCardDescriptor, runtimePlanDescriptor, } from './runtime-request-manager.js';
30
- export type { RuntimeRequestKind, RuntimeRequestContext, RuntimeRequestOptions, RuntimeConsumeOutcome, RuntimeOutcomeMessage, RuntimeRequestCallInput, RuntimeRequestPreflightInput, RuntimeRequestPushInput, RuntimeRequestPushMatch, KindDescriptor, RuntimeInputRequestPayload, RuntimeInputRequestResult, RuntimeCardRequestPayload, RuntimeCardRequestResult, RuntimePlanRequestPayload, RuntimePlanRequestResult, } from './runtime-request-manager.js';
31
- export { ApprovalManager } from './approval-manager.js';
32
29
  export { generateApprovalId, buildApprovalRequest, buildApprovalOutcome, redactSecrets, } from './approval-format.js';
33
30
  export { DEFAULT_APPROVAL_CONFIG, parseApprovalReplyMetadata, parseSessionRule, } from './approval-types.js';
34
31
  export type { ApprovalRequestCategory, ApprovalRequestDetail, ApprovalRequestMetadata, ApprovalNativeRequestMetadata, ApprovalRisk, ApprovalReplyMetadata, ApprovalOutcomeMetadata, SessionRule, ApprovalResult, ApprovalConfig, } from './approval-types.js';
@@ -37,10 +34,7 @@ export type { TruncateUnifiedDiffOptions } from './unified-diff.js';
37
34
  export { decodeStoredRuntimeCard } from '../backend-contracts/index.js';
38
35
  export { RUNTIME_CARD_SCHEMA_V1, RUNTIME_CARD_LIMITS, RUNTIME_CARD_FIELD_TYPES, RUNTIME_CARD_LINE_ITEM_COLUMN_TYPES, buildRuntimeCardOutcome, buildRuntimeCardPreview, buildRuntimeInputOutcome, parseRuntimeCardV1, validateRuntimeCardFieldValues, } from './runtime-cards.js';
39
36
  export type { PlanApprovalDecision, PlanApprovalMetadata, PlanApprovalReplyMetadata, RuntimeCardAction, RuntimeCardActionsBlock, RuntimeCardBlock, RuntimeCardBlockKind, RuntimeCardCalloutBlock, RuntimeCardChartBlock, RuntimeCardChartPoint, RuntimeCardChartSeries, RuntimeCardDetailsBlock, RuntimeCardDetailsRow, RuntimeCardField, RuntimeCardFieldChoice, RuntimeCardFieldType, RuntimeCardKnownBlockKind, RuntimeCardLineItemColumn, RuntimeCardLineItemColumnType, RuntimeCardListBlock, RuntimeCardListItem, RuntimeCardMediaKind, RuntimeCardMediaPreviewBlock, RuntimeCardMediaPreviewMedia, RuntimeCardMetric, RuntimeCardMetricGridBlock, RuntimeCardNativeMetadata, RuntimeCardOutcomeMetadata, RuntimeCardPreview, RuntimeCardReplyMetadata, RuntimeCardReplyStatus, RuntimeCardRequestMetadata, RuntimeCardResolutionStatus, RuntimeCardSchemaV1, RuntimeCardSummaryBlock, RuntimeCardTableBlock, RuntimeCardTone, RuntimeCardUnknownBlock, RuntimeCardV1, RuntimeInputAnswers, RuntimeInputChoice, RuntimeInputKind, RuntimeInputNativeMetadata, RuntimeInputOutcomeMetadata, RuntimeInputQuestion, RuntimeInputReplyMetadata, RuntimeInputReplyStatus, RuntimeInputRequestMetadata, RuntimeInputResolutionStatus, } from './runtime-cards.js';
40
- export { NO_REPLY_ACK_NOTE, NO_REPLY_REASON_SENTINEL, reportNoReplyOutcome, } from './silent-turn.js';
41
- export type { NoReplyReportClient } from './silent-turn.js';
42
- export { DEFAULT_TURN_VERBOSITY_BY_CONVERSATION_TYPE, normalizeTurnVerbosityConversationType, parseTurnVerbosityConfig, resolveTurnVerbosity, } from './turn-verbosity.js';
43
- export type { TurnVerbosity, TurnVerbosityConfig, TurnVerbosityConversationType, } from './turn-verbosity.js';
37
+ export { NO_REPLY_ACK_NOTE, NO_REPLY_REASON_SENTINEL, } from './silent-turn.js';
44
38
  export { clearPendingRegistration, loadPendingRegistrations, loadProfiles, savePendingRegistrations, saveProfiles, upsertAgentProfile, isProfileLocked, acquireLock, releaseLock, isProcessAlive, CANON_DIR, AGENTS_PATH, LOCKS_DIR, } from './agent-profiles.js';
45
39
  export type { AgentProfile, AgentProfileInput, PendingRegistration, ProfileLockHandle, } from './agent-profiles.js';
46
40
  export { initRTDBAuth, } from './rtdb-rest.js';
@@ -49,8 +43,8 @@ export { renderCanonHostInboundContent, } from './host-runtime.js';
49
43
  export type { CanonReplyContext, } from './host-runtime.js';
50
44
  export { createRuntimeStatePublisher, } from './runtime-state-publisher.js';
51
45
  export type { RuntimeStatePublisher, RuntimeStatePublisherOptions, RuntimeStreamingPayload, ClearRuntimeActivityOptions, } from './runtime-state-publisher.js';
52
- export { buildChunkedMessagePartMetadata, CANON_MESSAGE_TEXT_MAX_BYTES, ChunkedSendMessageError, DEFAULT_CHUNKED_MESSAGE_TEXT_MAX_BYTES, sendMessageWithRetryChunked, isPendingCanonOperation, isChunkedSendMessageError, isRetryableCanonDeliveryError, sendMessageWithRetry, splitTextByUtf8Bytes, utf8ByteLength, } from './retry.js';
53
- export type { ChunkedMessagePartMetadataInput, ChunkedSendMessageResult, SendMessageChunkingOptions, SendMessageRetryOptions, } from './retry.js';
46
+ export { buildChunkedMessagePartMetadata, CANON_MESSAGE_TEXT_MAX_BYTES, DEFAULT_CHUNKED_MESSAGE_TEXT_MAX_BYTES, isPendingCanonOperation, isRetryableCanonDeliveryError, splitTextByUtf8Bytes, splitTextWithinBytes, utf8ByteLength, } from './retry.js';
47
+ export type { ChunkedMessagePartMetadataInput, } from './retry.js';
54
48
  export { DEFAULT_BASE_URL } from './constants.js';
55
49
  export { CANON_RUNTIME_ENDPOINT_DEFAULTS, DEFAULT_CANON_ENVIRONMENT_ID, DEFAULT_CANON_RUNTIME_ENDPOINTS, getCanonRuntimeEndpointDefaults, requireCanonRuntimeEndpointDefaults, resolveCanonRuntimeConnection, verifyCanonRuntimeConnection, } from './runtime-endpoints.js';
56
50
  export type { CanonRuntimeConnection, CanonRuntimeConnectionOptions, CanonRuntimeEndpointDefaults, } from './runtime-endpoints.js';