@agentconnect.md/daemon 1.0.0-rc.323 → 1.0.0-rc.324

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.
@@ -1,4 +1,4 @@
1
- import { o as loadConfig, t as discoverAgents } from "./load-agents-C2pFahVp.js";
1
+ import { o as loadConfig, t as discoverAgents } from "./load-agents-CuXy_Ei1.js";
2
2
  //#region src/cli/agent-list.ts
3
3
  async function runAgentList(opts) {
4
4
  const out = opts.out ?? process.stdout;
@@ -18,4 +18,4 @@ async function runAgentList(opts) {
18
18
  //#endregion
19
19
  export { runAgentList };
20
20
 
21
- //# sourceMappingURL=agent-list-Ckqv2x26.js.map
21
+ //# sourceMappingURL=agent-list-CE6JNwIB.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-list-Ckqv2x26.js","names":[],"sources":["../src/cli/agent-list.ts"],"sourcesContent":["import { loadConfig } from '../config/load-config.js'\nimport { discoverAgents } from '../agents/load-agents.js'\n\nexport interface RunAgentListOpts {\n agentsDir?: string\n configPath?: string\n root?: string\n out?: NodeJS.WritableStream\n}\n\n// Read-only view of the local agent directory. Mutating agents (add/remove/\n// enable/disable) is intentionally not a CLI command — agent business config is\n// owned by the Control Plane (agent/upsert + register/ok roster, see\n// cp/cp-agent-registry.ts) or by hand-editing agent.json; the daemon only\n// reconciles what it finds on disk. This lists what that discovery sees.\nexport async function runAgentList(opts: RunAgentListOpts): Promise<void> {\n const out = opts.out ?? process.stdout\n const cfg = loadConfig({\n root: opts.root,\n configPath: opts.configPath,\n optional: true,\n overrides: { agentsDir: opts.agentsDir }\n })\n const agentsDir = cfg.agentsDir!\n const discovered = discoverAgents(agentsDir)\n if (discovered.length === 0) {\n out.write(`no agents found under ${agentsDir}\\n`)\n return\n }\n for (const { agent, dir } of discovered) {\n out.write(`${agent.id}\\t${agent.status}\\t${agent.runtime}\\t${agent.name}\\t${dir}\\n`)\n }\n}\n"],"mappings":";;AAeA,eAAsB,aAAa,MAAuC;CACxE,MAAM,MAAM,KAAK,OAAO,QAAQ;CAOhC,MAAM,YANM,WAAW;EACrB,MAAM,KAAK;EACX,YAAY,KAAK;EACjB,UAAU;EACV,WAAW,EAAE,WAAW,KAAK,UAAU;CACzC,CACoB,CAAC,CAAC;CACtB,MAAM,aAAa,eAAe,SAAS;CAC3C,IAAI,WAAW,WAAW,GAAG;EAC3B,IAAI,MAAM,yBAAyB,UAAU,GAAG;EAChD;CACF;CACA,KAAK,MAAM,EAAE,OAAO,SAAS,YAC3B,IAAI,MAAM,GAAG,MAAM,GAAG,IAAI,MAAM,OAAO,IAAI,MAAM,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,GAAG;AAEvF"}
1
+ {"version":3,"file":"agent-list-CE6JNwIB.js","names":[],"sources":["../src/cli/agent-list.ts"],"sourcesContent":["import { loadConfig } from '../config/load-config.js'\nimport { discoverAgents } from '../agents/load-agents.js'\n\nexport interface RunAgentListOpts {\n agentsDir?: string\n configPath?: string\n root?: string\n out?: NodeJS.WritableStream\n}\n\n// Read-only view of the local agent directory. Mutating agents (add/remove/\n// enable/disable) is intentionally not a CLI command — agent business config is\n// owned by the Control Plane (agent/upsert + register/ok roster, see\n// cp/cp-agent-registry.ts) or by hand-editing agent.json; the daemon only\n// reconciles what it finds on disk. This lists what that discovery sees.\nexport async function runAgentList(opts: RunAgentListOpts): Promise<void> {\n const out = opts.out ?? process.stdout\n const cfg = loadConfig({\n root: opts.root,\n configPath: opts.configPath,\n optional: true,\n overrides: { agentsDir: opts.agentsDir }\n })\n const agentsDir = cfg.agentsDir!\n const discovered = discoverAgents(agentsDir)\n if (discovered.length === 0) {\n out.write(`no agents found under ${agentsDir}\\n`)\n return\n }\n for (const { agent, dir } of discovered) {\n out.write(`${agent.id}\\t${agent.status}\\t${agent.runtime}\\t${agent.name}\\t${dir}\\n`)\n }\n}\n"],"mappings":";;AAeA,eAAsB,aAAa,MAAuC;CACxE,MAAM,MAAM,KAAK,OAAO,QAAQ;CAOhC,MAAM,YANM,WAAW;EACrB,MAAM,KAAK;EACX,YAAY,KAAK;EACjB,UAAU;EACV,WAAW,EAAE,WAAW,KAAK,UAAU;CACzC,CACoB,CAAC,CAAC;CACtB,MAAM,aAAa,eAAe,SAAS;CAC3C,IAAI,WAAW,WAAW,GAAG;EAC3B,IAAI,MAAM,yBAAyB,UAAU,GAAG;EAChD;CACF;CACA,KAAK,MAAM,EAAE,OAAO,SAAS,YAC3B,IAAI,MAAM,GAAG,MAAM,GAAG,IAAI,MAAM,OAAO,IAAI,MAAM,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,GAAG;AAEvF"}
@@ -1,6 +1,6 @@
1
- import { a as agentChildEnv, i as selectAgent, o as loadConfig } from "./load-agents-C2pFahVp.js";
1
+ import { a as agentChildEnv, i as selectAgent, o as loadConfig } from "./load-agents-CuXy_Ei1.js";
2
2
  import { l as resolveRoot } from "./paths-DEcUO8lC.js";
3
- import { a as prepareWorkspace, f as memoryProviderFor, t as AcpHost, w as resolveRuntimes } from "./acp-host-BEjpql6l.js";
3
+ import { T as resolveRuntimes, a as prepareWorkspace, f as memoryProviderFor, t as AcpHost } from "./acp-host-DKkoWiWe.js";
4
4
  import { createInterface } from "node:readline";
5
5
  //#region src/cli/chat.ts
6
6
  function renderUpdate(out) {
@@ -84,4 +84,4 @@ async function runChat(opts) {
84
84
  //#endregion
85
85
  export { renderUpdate, runChat };
86
86
 
87
- //# sourceMappingURL=chat-MTttQBSF.js.map
87
+ //# sourceMappingURL=chat-lv_zfcAK.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-MTttQBSF.js","names":[],"sources":["../src/cli/chat.ts"],"sourcesContent":["import { createInterface } from 'node:readline'\nimport type { ContentBlock, SessionUpdate } from '@agentclientprotocol/sdk'\nimport { loadConfig } from '../config/load-config.js'\nimport { resolveRuntimes } from '../runtimes/registry.js'\nimport { selectAgent } from '../agents/load-agents.js'\nimport { agentChildEnv } from '../agents/agent-env.js'\nimport { memoryProviderFor } from '../agents/memory-provider.js'\nimport { prepareWorkspace } from '../workspace/workspace-manager.js'\nimport { AcpHost } from '../acp/acp-host.js'\nimport { resolveRoot } from '../paths.js'\n\nexport function renderUpdate(out: NodeJS.WritableStream) {\n return (_sessionId: string, update: SessionUpdate): void => {\n if (update.sessionUpdate === 'agent_message_chunk' && update.content.type === 'text') {\n out.write(update.content.text)\n } else if (update.sessionUpdate === 'tool_call') {\n const title = ('title' in update && update.title) || update.toolCallId || 'tool'\n out.write(`\\n[tool] ${title}\\n`)\n }\n }\n}\n\nexport interface RunChatOpts {\n agentsDir?: string\n agentName?: string\n message?: string\n configPath?: string\n root?: string\n out?: NodeJS.WritableStream\n input?: NodeJS.ReadableStream\n}\n\nexport async function runChat(opts: RunChatOpts): Promise<void> {\n const out = opts.out ?? process.stdout\n const root = resolveRoot(opts.root)\n const cfg = loadConfig({\n root: opts.root,\n configPath: opts.configPath,\n optional: true,\n overrides: { agentsDir: opts.agentsDir }\n })\n const agent = selectAgent(cfg.agentsDir!, opts.agentName)\n\n const runtimes = await resolveRuntimes(cfg, root, { neededRuntimes: [agent.runtime], mode: 'cache-first' })\n const runtime = runtimes[agent.runtime]\n if (!runtime) {\n const available = Object.keys(runtimes).sort().join(', ') || '(none)'\n throw new Error(`runtime \"${agent.runtime}\" not found. Available: ${available}`)\n }\n\n const host = new AcpHost(runtime, {\n onUpdate: renderUpdate(out),\n // Memory-backend env for parity with the daemon (managed disables the runtime's\n // own memory; native redirects it under the agent root).\n env: { ...agentChildEnv(agent), ...memoryProviderFor(agent, runtime).runtimeEnv() },\n configPrefs: {\n model: agent.runtimeOverrides?.model,\n permissionMode: agent.permissionMode,\n reasoningEffort: agent.reasoningEffort,\n fastMode: agent.fastMode\n }\n })\n // The adapter child runs in its own process group (see AcpHost.start), so a\n // terminal Ctrl-C no longer kills it as a side effect — Node's default SIGINT\n // exit would skip the finally below and leak it. Stop the host, then re-exit.\n // Registered BEFORE start(): a first-run `npx -y` runtime download takes long\n // enough that Ctrl-C mid-start is common, and the spawn happens early in start().\n const onSigint = () => {\n void host.stop().finally(() => process.exit(130))\n }\n process.once('SIGINT', onSigint)\n try {\n await host.start()\n const cwd = await prepareWorkspace(agent)\n const sessionId = await host.newSession(cwd)\n\n const send = async (text: string) => {\n const blocks: ContentBlock[] = [{ type: 'text', text }]\n await host.prompt(sessionId, blocks)\n out.write('\\n')\n }\n\n if (typeof opts.message === 'string' && opts.message.length > 0) {\n await send(opts.message)\n return\n }\n\n const rl = createInterface({ input: opts.input ?? process.stdin })\n out.write(`Chatting with ${agent.name} (${agent.id}). Type .exit to quit.\\n> `)\n try {\n for await (const line of rl) {\n const text = line.trim()\n if (text === '.exit' || text === '.quit') break\n if (text.length > 0) await send(text)\n out.write('> ')\n }\n } finally {\n rl.close()\n }\n } finally {\n process.removeListener('SIGINT', onSigint)\n await host.stop()\n }\n}\n"],"mappings":";;;;;AAWA,SAAgB,aAAa,KAA4B;CACvD,QAAQ,YAAoB,WAAgC;EAC1D,IAAI,OAAO,kBAAkB,yBAAyB,OAAO,QAAQ,SAAS,QAC5E,IAAI,MAAM,OAAO,QAAQ,IAAI;OACxB,IAAI,OAAO,kBAAkB,aAAa;GAC/C,MAAM,QAAS,WAAW,UAAU,OAAO,SAAU,OAAO,cAAc;GAC1E,IAAI,MAAM,YAAY,MAAM,GAAG;EACjC;CACF;AACF;AAYA,eAAsB,QAAQ,MAAkC;CAC9D,MAAM,MAAM,KAAK,OAAO,QAAQ;CAChC,MAAM,OAAO,YAAY,KAAK,IAAI;CAClC,MAAM,MAAM,WAAW;EACrB,MAAM,KAAK;EACX,YAAY,KAAK;EACjB,UAAU;EACV,WAAW,EAAE,WAAW,KAAK,UAAU;CACzC,CAAC;CACD,MAAM,QAAQ,YAAY,IAAI,WAAY,KAAK,SAAS;CAExD,MAAM,WAAW,MAAM,gBAAgB,KAAK,MAAM;EAAE,gBAAgB,CAAC,MAAM,OAAO;EAAG,MAAM;CAAc,CAAC;CAC1G,MAAM,UAAU,SAAS,MAAM;CAC/B,IAAI,CAAC,SAAS;EACZ,MAAM,YAAY,OAAO,KAAK,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,KAAK;EAC7D,MAAM,IAAI,MAAM,YAAY,MAAM,QAAQ,0BAA0B,WAAW;CACjF;CAEA,MAAM,OAAO,IAAI,QAAQ,SAAS;EAChC,UAAU,aAAa,GAAG;EAG1B,KAAK;GAAE,GAAG,cAAc,KAAK;GAAG,GAAG,kBAAkB,OAAO,OAAO,CAAC,CAAC,WAAW;EAAE;EAClF,aAAa;GACX,OAAO,MAAM,kBAAkB;GAC/B,gBAAgB,MAAM;GACtB,iBAAiB,MAAM;GACvB,UAAU,MAAM;EAClB;CACF,CAAC;CAMD,MAAM,iBAAiB;EACrB,KAAU,KAAK,CAAC,CAAC,cAAc,QAAQ,KAAK,GAAG,CAAC;CAClD;CACA,QAAQ,KAAK,UAAU,QAAQ;CAC/B,IAAI;EACF,MAAM,KAAK,MAAM;EACjB,MAAM,MAAM,MAAM,iBAAiB,KAAK;EACxC,MAAM,YAAY,MAAM,KAAK,WAAW,GAAG;EAE3C,MAAM,OAAO,OAAO,SAAiB;GACnC,MAAM,SAAyB,CAAC;IAAE,MAAM;IAAQ;GAAK,CAAC;GACtD,MAAM,KAAK,OAAO,WAAW,MAAM;GACnC,IAAI,MAAM,IAAI;EAChB;EAEA,IAAI,OAAO,KAAK,YAAY,YAAY,KAAK,QAAQ,SAAS,GAAG;GAC/D,MAAM,KAAK,KAAK,OAAO;GACvB;EACF;EAEA,MAAM,KAAK,gBAAgB,EAAE,OAAO,KAAK,SAAS,QAAQ,MAAM,CAAC;EACjE,IAAI,MAAM,iBAAiB,MAAM,KAAK,IAAI,MAAM,GAAG,2BAA2B;EAC9E,IAAI;GACF,WAAW,MAAM,QAAQ,IAAI;IAC3B,MAAM,OAAO,KAAK,KAAK;IACvB,IAAI,SAAS,WAAW,SAAS,SAAS;IAC1C,IAAI,KAAK,SAAS,GAAG,MAAM,KAAK,IAAI;IACpC,IAAI,MAAM,IAAI;GAChB;EACF,UAAU;GACR,GAAG,MAAM;EACX;CACF,UAAU;EACR,QAAQ,eAAe,UAAU,QAAQ;EACzC,MAAM,KAAK,KAAK;CAClB;AACF"}
1
+ {"version":3,"file":"chat-lv_zfcAK.js","names":[],"sources":["../src/cli/chat.ts"],"sourcesContent":["import { createInterface } from 'node:readline'\nimport type { ContentBlock, SessionUpdate } from '@agentclientprotocol/sdk'\nimport { loadConfig } from '../config/load-config.js'\nimport { resolveRuntimes } from '../runtimes/registry.js'\nimport { selectAgent } from '../agents/load-agents.js'\nimport { agentChildEnv } from '../agents/agent-env.js'\nimport { memoryProviderFor } from '../agents/memory-provider.js'\nimport { prepareWorkspace } from '../workspace/workspace-manager.js'\nimport { AcpHost } from '../acp/acp-host.js'\nimport { resolveRoot } from '../paths.js'\n\nexport function renderUpdate(out: NodeJS.WritableStream) {\n return (_sessionId: string, update: SessionUpdate): void => {\n if (update.sessionUpdate === 'agent_message_chunk' && update.content.type === 'text') {\n out.write(update.content.text)\n } else if (update.sessionUpdate === 'tool_call') {\n const title = ('title' in update && update.title) || update.toolCallId || 'tool'\n out.write(`\\n[tool] ${title}\\n`)\n }\n }\n}\n\nexport interface RunChatOpts {\n agentsDir?: string\n agentName?: string\n message?: string\n configPath?: string\n root?: string\n out?: NodeJS.WritableStream\n input?: NodeJS.ReadableStream\n}\n\nexport async function runChat(opts: RunChatOpts): Promise<void> {\n const out = opts.out ?? process.stdout\n const root = resolveRoot(opts.root)\n const cfg = loadConfig({\n root: opts.root,\n configPath: opts.configPath,\n optional: true,\n overrides: { agentsDir: opts.agentsDir }\n })\n const agent = selectAgent(cfg.agentsDir!, opts.agentName)\n\n const runtimes = await resolveRuntimes(cfg, root, { neededRuntimes: [agent.runtime], mode: 'cache-first' })\n const runtime = runtimes[agent.runtime]\n if (!runtime) {\n const available = Object.keys(runtimes).sort().join(', ') || '(none)'\n throw new Error(`runtime \"${agent.runtime}\" not found. Available: ${available}`)\n }\n\n const host = new AcpHost(runtime, {\n onUpdate: renderUpdate(out),\n // Memory-backend env for parity with the daemon (managed disables the runtime's\n // own memory; native redirects it under the agent root).\n env: { ...agentChildEnv(agent), ...memoryProviderFor(agent, runtime).runtimeEnv() },\n configPrefs: {\n model: agent.runtimeOverrides?.model,\n permissionMode: agent.permissionMode,\n reasoningEffort: agent.reasoningEffort,\n fastMode: agent.fastMode\n }\n })\n // The adapter child runs in its own process group (see AcpHost.start), so a\n // terminal Ctrl-C no longer kills it as a side effect — Node's default SIGINT\n // exit would skip the finally below and leak it. Stop the host, then re-exit.\n // Registered BEFORE start(): a first-run `npx -y` runtime download takes long\n // enough that Ctrl-C mid-start is common, and the spawn happens early in start().\n const onSigint = () => {\n void host.stop().finally(() => process.exit(130))\n }\n process.once('SIGINT', onSigint)\n try {\n await host.start()\n const cwd = await prepareWorkspace(agent)\n const sessionId = await host.newSession(cwd)\n\n const send = async (text: string) => {\n const blocks: ContentBlock[] = [{ type: 'text', text }]\n await host.prompt(sessionId, blocks)\n out.write('\\n')\n }\n\n if (typeof opts.message === 'string' && opts.message.length > 0) {\n await send(opts.message)\n return\n }\n\n const rl = createInterface({ input: opts.input ?? process.stdin })\n out.write(`Chatting with ${agent.name} (${agent.id}). Type .exit to quit.\\n> `)\n try {\n for await (const line of rl) {\n const text = line.trim()\n if (text === '.exit' || text === '.quit') break\n if (text.length > 0) await send(text)\n out.write('> ')\n }\n } finally {\n rl.close()\n }\n } finally {\n process.removeListener('SIGINT', onSigint)\n await host.stop()\n }\n}\n"],"mappings":";;;;;AAWA,SAAgB,aAAa,KAA4B;CACvD,QAAQ,YAAoB,WAAgC;EAC1D,IAAI,OAAO,kBAAkB,yBAAyB,OAAO,QAAQ,SAAS,QAC5E,IAAI,MAAM,OAAO,QAAQ,IAAI;OACxB,IAAI,OAAO,kBAAkB,aAAa;GAC/C,MAAM,QAAS,WAAW,UAAU,OAAO,SAAU,OAAO,cAAc;GAC1E,IAAI,MAAM,YAAY,MAAM,GAAG;EACjC;CACF;AACF;AAYA,eAAsB,QAAQ,MAAkC;CAC9D,MAAM,MAAM,KAAK,OAAO,QAAQ;CAChC,MAAM,OAAO,YAAY,KAAK,IAAI;CAClC,MAAM,MAAM,WAAW;EACrB,MAAM,KAAK;EACX,YAAY,KAAK;EACjB,UAAU;EACV,WAAW,EAAE,WAAW,KAAK,UAAU;CACzC,CAAC;CACD,MAAM,QAAQ,YAAY,IAAI,WAAY,KAAK,SAAS;CAExD,MAAM,WAAW,MAAM,gBAAgB,KAAK,MAAM;EAAE,gBAAgB,CAAC,MAAM,OAAO;EAAG,MAAM;CAAc,CAAC;CAC1G,MAAM,UAAU,SAAS,MAAM;CAC/B,IAAI,CAAC,SAAS;EACZ,MAAM,YAAY,OAAO,KAAK,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,KAAK;EAC7D,MAAM,IAAI,MAAM,YAAY,MAAM,QAAQ,0BAA0B,WAAW;CACjF;CAEA,MAAM,OAAO,IAAI,QAAQ,SAAS;EAChC,UAAU,aAAa,GAAG;EAG1B,KAAK;GAAE,GAAG,cAAc,KAAK;GAAG,GAAG,kBAAkB,OAAO,OAAO,CAAC,CAAC,WAAW;EAAE;EAClF,aAAa;GACX,OAAO,MAAM,kBAAkB;GAC/B,gBAAgB,MAAM;GACtB,iBAAiB,MAAM;GACvB,UAAU,MAAM;EAClB;CACF,CAAC;CAMD,MAAM,iBAAiB;EACrB,KAAU,KAAK,CAAC,CAAC,cAAc,QAAQ,KAAK,GAAG,CAAC;CAClD;CACA,QAAQ,KAAK,UAAU,QAAQ;CAC/B,IAAI;EACF,MAAM,KAAK,MAAM;EACjB,MAAM,MAAM,MAAM,iBAAiB,KAAK;EACxC,MAAM,YAAY,MAAM,KAAK,WAAW,GAAG;EAE3C,MAAM,OAAO,OAAO,SAAiB;GACnC,MAAM,SAAyB,CAAC;IAAE,MAAM;IAAQ;GAAK,CAAC;GACtD,MAAM,KAAK,OAAO,WAAW,MAAM;GACnC,IAAI,MAAM,IAAI;EAChB;EAEA,IAAI,OAAO,KAAK,YAAY,YAAY,KAAK,QAAQ,SAAS,GAAG;GAC/D,MAAM,KAAK,KAAK,OAAO;GACvB;EACF;EAEA,MAAM,KAAK,gBAAgB,EAAE,OAAO,KAAK,SAAS,QAAQ,MAAM,CAAC;EACjE,IAAI,MAAM,iBAAiB,MAAM,KAAK,IAAI,MAAM,GAAG,2BAA2B;EAC9E,IAAI;GACF,WAAW,MAAM,QAAQ,IAAI;IAC3B,MAAM,OAAO,KAAK,KAAK;IACvB,IAAI,SAAS,WAAW,SAAS,SAAS;IAC1C,IAAI,KAAK,SAAS,GAAG,MAAM,KAAK,IAAI;IACpC,IAAI,MAAM,IAAI;GAChB;EACF,UAAU;GACR,GAAG,MAAM;EACX;CACF,UAAU;EACR,QAAQ,eAAe,UAAU,QAAQ;EACzC,MAAM,KAAK,KAAK;CAClB;AACF"}
@@ -633,6 +633,7 @@ const RelayRosterEntry = object({
633
633
  const RelayRosterUpdate = object({ relays: array(RelayRosterEntry) });
634
634
  const RegisterOk = object({
635
635
  routingEpoch: number().int(),
636
+ serverFeatures: array(string()).default([]),
636
637
  assignments: array(RouteAssign),
637
638
  agents: array(AgentSpec.extend({ agentId: string().uuid() })).default([]),
638
639
  crons: array(CronUpsert),
@@ -650,6 +651,119 @@ const RegisterOk = object({
650
651
  });
651
652
  //#endregion
652
653
  //#region ../protocol/dist/frames/hook.js
654
+ /** Decimal wire form for Prisma/GitHub bigint values. */
655
+ const HookBigIntString = string().regex(/^(?:0|[1-9]\d*)$/);
656
+ /** The highest formal-review event one hook permits. */
657
+ const HookReviewPolicy = _enum([
658
+ "off",
659
+ "comment",
660
+ "request_changes",
661
+ "full"
662
+ ]);
663
+ /** External run-reporting transport. `status` is reserved for the later R3. */
664
+ const HookReportingMode = _enum([
665
+ "off",
666
+ "check",
667
+ "status"
668
+ ]);
669
+ /** R2a only admits informational; `required` remains a fail-closed future mode. */
670
+ const HookGateMode = _enum(["informational", "required"]);
671
+ /**
672
+ * Exact config + dispatch identity captured when the CP compiles a hook fire.
673
+ *
674
+ * The relay-facing frames expose these fields individually at top level so an
675
+ * older CP/relay can omit them without making the whole fire undecodable. A
676
+ * consumer MUST have every field before enabling review/reporting; absence is
677
+ * not filled with a revision and therefore fails closed. Action-time RPCs use
678
+ * this complete object so a partially rolled-out tuple cannot authorize an
679
+ * effect.
680
+ */
681
+ const HookConfigSnapshot = object({
682
+ configRevision: HookBigIntString,
683
+ dispatchRevision: HookBigIntString,
684
+ dispatchDaemonId: string().uuid(),
685
+ reviewPolicy: HookReviewPolicy,
686
+ reportingMode: HookReportingMode,
687
+ gateMode: HookGateMode
688
+ });
689
+ /** Optional top-level form used only on rolling-compatible delivery frames. */
690
+ const OptionalHookConfigSnapshot = HookConfigSnapshot.partial();
691
+ /**
692
+ * Trusted, body-free GitHub subject/revision metadata. It is deliberately
693
+ * separate from HookContext: HookContext contains attacker-authored prompt
694
+ * excerpts, whereas this object is cut from a signature-verified payload and
695
+ * fenced to the CP-compiled numeric repo/installation rule.
696
+ *
697
+ * `headSha` is absent for PR issue_comment deliveries because GitHub omits the
698
+ * revision there; the daemon resolves it before `hook/start`. R2a informational
699
+ * checks use `reportSha=headSha` once known.
700
+ */
701
+ const GithubHookMetadata = object({
702
+ repoId: HookBigIntString,
703
+ repoFullName: string().min(1),
704
+ sourceInstallationId: HookBigIntString,
705
+ subjectKind: _enum(["issue", "pull_request"]),
706
+ pullNumber: number().int().positive().optional(),
707
+ headSha: string().min(1).optional(),
708
+ baseSha: string().min(1).optional(),
709
+ reportSha: string().min(1).optional(),
710
+ headRepoFullName: string().min(1).optional(),
711
+ mergeCommitSha: string().min(1).optional(),
712
+ isDraft: boolean().optional(),
713
+ baseChanged: boolean().optional()
714
+ }).superRefine((value, ctx) => {
715
+ if (value.subjectKind === "pull_request" && value.pullNumber === void 0) ctx.addIssue({
716
+ code: "custom",
717
+ path: ["pullNumber"],
718
+ message: "pullNumber is required for a pull_request subject"
719
+ });
720
+ if (value.reportSha !== void 0 && value.headSha === void 0) ctx.addIssue({
721
+ code: "custom",
722
+ path: ["reportSha"],
723
+ message: "reportSha requires an authoritative headSha"
724
+ });
725
+ if (value.reportSha !== void 0 && value.headSha !== void 0 && value.reportSha !== value.headSha) ctx.addIssue({
726
+ code: "custom",
727
+ path: ["reportSha"],
728
+ message: "R2a reports only the authoritative pull head SHA"
729
+ });
730
+ });
731
+ const HookReviewEvent = _enum([
732
+ "COMMENT",
733
+ "REQUEST_CHANGES",
734
+ "APPROVE"
735
+ ]);
736
+ const HookReviewVerdict = _enum([
737
+ "pass",
738
+ "fail",
739
+ "neutral"
740
+ ]);
741
+ /** Short machine code only; raw GitHub/runtime exception text never crosses to reporting. */
742
+ const HookReviewResultCode = string().min(1).max(100).regex(/^[a-z0-9_:-]+$/);
743
+ /**
744
+ * Body-free outcome of one reserved formal-review attempt.
745
+ *
746
+ * `not_submitted` is only legal after a deterministic no-effect failure and
747
+ * lets the CP release the reservation. An uncertain POST remains `ambiguous`
748
+ * until marker reconciliation proves whether GitHub created it.
749
+ */
750
+ const HookReviewResult = discriminatedUnion("state", [
751
+ object({
752
+ state: literal("submitted"),
753
+ reviewId: string().min(1),
754
+ event: HookReviewEvent,
755
+ verdict: HookReviewVerdict,
756
+ commitId: string().min(1)
757
+ }),
758
+ object({
759
+ state: literal("not_submitted"),
760
+ code: HookReviewResultCode
761
+ }),
762
+ object({
763
+ state: literal("ambiguous"),
764
+ code: HookReviewResultCode
765
+ })
766
+ ]);
653
767
  /**
654
768
  * Hook (inbound-webhook trigger) frames — webhook-triggers-and-github-events.md.
655
769
  *
@@ -658,8 +772,8 @@ const RegisterOk = object({
658
772
  * (`rc/hook-assign`, frames/relay-cp.ts); the relay pool is the public ingress
659
773
  * that verifies + matches + dispatches the trigger to the target daemon as an
660
774
  * `rd/msg` `hook` member (frames/relay-daemon.ts). Event payloads never touch
661
- * the CP — the only hook frame on the daemon↔CP control WS is the completion
662
- * report below (pure metadata, mirroring `cron/report`).
775
+ * the CP. R1/R2a add only metadata barriers and action-result control frames;
776
+ * the model-visible body remains relay↔daemon.
663
777
  */
664
778
  /**
665
779
  * The trimmed event envelope a fire carries — bounded excerpts only; the full
@@ -686,21 +800,81 @@ const HookContext = object({
686
800
  truncated: boolean().optional()
687
801
  });
688
802
  /**
689
- * `hook/report` (D→C EVT, fire-and-forget) — the dispatched turn ended; closes
803
+ * `hook/report` (D→C REQ → generic `ack`) — the dispatched turn ended; closes
690
804
  * the `HookRun` row the relay's `rc/run-report` opened. Same discipline as
691
805
  * `cron/report`: scoped (the agent must be placed on the reporting daemon),
692
806
  * latest-wins, lost reports harvested by the HookRunReaper (late arrivals may
693
- * still overwrite `orphaned`). Keyed by `(hookId, deliveryKey)`.
807
+ * still overwrite `orphaned`). The daemon retains a metadata-only outbox entry
808
+ * until ACK. Keyed by `(hookId, deliveryKey)`.
694
809
  */
695
810
  const HookReport = object({
696
811
  hookId: string().uuid(),
697
812
  agentId: string().uuid(),
698
813
  deliveryKey: string().min(1),
814
+ ...OptionalHookConfigSnapshot.shape,
815
+ event: string().min(1).optional(),
816
+ github: GithubHookMetadata.optional(),
699
817
  status: _enum(["success", "failed"]),
700
818
  durationMs: number().int().nonnegative().optional(),
701
819
  sessionId: string().optional(),
702
- reason: string().optional()
820
+ reason: string().optional(),
821
+ reviewAttemptId: string().uuid().optional(),
822
+ reviewResult: HookReviewResult.optional()
823
+ }).superRefine((report, ctx) => {
824
+ if (report.reviewAttemptId === void 0 !== (report.reviewResult === void 0)) ctx.addIssue({
825
+ code: "custom",
826
+ path: report.reviewAttemptId === void 0 ? ["reviewAttemptId"] : ["reviewResult"],
827
+ message: "reviewAttemptId and reviewResult must be reported together"
828
+ });
829
+ });
830
+ /**
831
+ * `hook/start` (D→C REQ) — metadata barrier immediately before an accepted
832
+ * GitHub hook enters the model prompt. A successful reply means the CP durably
833
+ * attached the authoritative revision to the accepted HookRun and, for R2a,
834
+ * advanced its informational projection to in_progress.
835
+ */
836
+ const HookStart = object({
837
+ hookId: string().uuid(),
838
+ agentId: string().uuid(),
839
+ deliveryKey: string().min(1),
840
+ event: string().min(1).optional(),
841
+ github: GithubHookMetadata,
842
+ ...HookConfigSnapshot.shape
843
+ });
844
+ const HookStartOk = object({ accepted: literal(true) });
845
+ /** D→C action-time authorization for one formal GitHub review attempt. */
846
+ const GithubReviewAuthorize = object({
847
+ hookId: string().uuid(),
848
+ deliveryKey: string().min(1),
849
+ attemptId: string().uuid(),
850
+ requestedEvent: HookReviewEvent,
851
+ requestedVerdict: HookReviewVerdict,
852
+ snapshot: HookConfigSnapshot
853
+ });
854
+ /** Trusted target echoed with a broker-only purpose token. Secret: never log. */
855
+ const GithubReviewAuthorized = object({
856
+ attemptId: string().uuid(),
857
+ token: string().min(1),
858
+ ttlSec: number().int().positive(),
859
+ expiresAt: string().datetime(),
860
+ repoId: HookBigIntString,
861
+ repoFullName: string().min(1),
862
+ pullNumber: number().int().positive(),
863
+ expectedHeadSha: string().min(1),
864
+ expectedBaseSha: string().min(1)
703
865
  });
866
+ /**
867
+ * Immediate metadata-only convergence after the daemon's GitHub review POST.
868
+ * Submitted metadata is also repeated on HookReport for lost-REP recovery.
869
+ */
870
+ const GithubReviewResultReport = object({
871
+ hookId: string().uuid(),
872
+ deliveryKey: string().min(1),
873
+ attemptId: string().uuid(),
874
+ snapshot: HookConfigSnapshot,
875
+ result: HookReviewResult
876
+ });
877
+ const GithubReviewResultOk = object({ accepted: literal(true) });
704
878
  //#endregion
705
879
  //#region ../protocol/dist/frames/gitcred.js
706
880
  /**
@@ -1395,6 +1569,12 @@ const FRAME_SCHEMAS = {
1395
1569
  "cron/report": CronReport,
1396
1570
  "cron/run": CronRunNow,
1397
1571
  "hook/report": HookReport,
1572
+ "hook/start": HookStart,
1573
+ "hook/start/ok": HookStartOk,
1574
+ "github/review-authorize": GithubReviewAuthorize,
1575
+ "github/review-authorized": GithubReviewAuthorized,
1576
+ "github/review-result": GithubReviewResultReport,
1577
+ "github/review-result/ok": GithubReviewResultOk,
1398
1578
  "integration/upsert": IntegrationUpsert,
1399
1579
  "integration/remove": IntegrationRemove,
1400
1580
  "integration/channels": IntegrationChannels,
@@ -1490,6 +1670,12 @@ discriminatedUnion("type", [
1490
1670
  frame("cron/report", FRAME_SCHEMAS["cron/report"]),
1491
1671
  frame("cron/run", FRAME_SCHEMAS["cron/run"]),
1492
1672
  frame("hook/report", FRAME_SCHEMAS["hook/report"]),
1673
+ frame("hook/start", FRAME_SCHEMAS["hook/start"]),
1674
+ frame("hook/start/ok", FRAME_SCHEMAS["hook/start/ok"]),
1675
+ frame("github/review-authorize", FRAME_SCHEMAS["github/review-authorize"]),
1676
+ frame("github/review-authorized", FRAME_SCHEMAS["github/review-authorized"]),
1677
+ frame("github/review-result", FRAME_SCHEMAS["github/review-result"]),
1678
+ frame("github/review-result/ok", FRAME_SCHEMAS["github/review-result/ok"]),
1493
1679
  frame("integration/upsert", FRAME_SCHEMAS["integration/upsert"]),
1494
1680
  frame("integration/remove", FRAME_SCHEMAS["integration/remove"]),
1495
1681
  frame("integration/channels", FRAME_SCHEMAS["integration/channels"]),
@@ -1671,6 +1857,7 @@ const RcHookAssign = object({
1671
1857
  kind: _enum(["webhook", "github"]),
1672
1858
  agentId: string().uuid(),
1673
1859
  daemonId: string().uuid(),
1860
+ ...OptionalHookConfigSnapshot.shape,
1674
1861
  sessionMode: _enum([
1675
1862
  "perDelivery",
1676
1863
  "perThread",
@@ -1691,6 +1878,12 @@ const RcHookAssign = object({
1691
1878
  appSlug: string().optional(),
1692
1879
  installationIds: array(string())
1693
1880
  }).optional()
1881
+ }).superRefine((rule, ctx) => {
1882
+ if (rule.dispatchDaemonId !== void 0 && rule.dispatchDaemonId !== rule.daemonId) ctx.addIssue({
1883
+ code: "custom",
1884
+ path: ["dispatchDaemonId"],
1885
+ message: "dispatchDaemonId must equal daemonId on a compiled rule"
1886
+ });
1694
1887
  });
1695
1888
  const RcHookRemove = object({ hookId: string().uuid() });
1696
1889
  const RcRunReport = object({
@@ -1699,9 +1892,17 @@ const RcRunReport = object({
1699
1892
  firedAt: string().datetime(),
1700
1893
  agentId: string().uuid(),
1701
1894
  daemonId: string().uuid().optional(),
1702
- event: string().optional(),
1895
+ ...OptionalHookConfigSnapshot.shape,
1896
+ event: string().min(1).optional(),
1897
+ github: GithubHookMetadata.optional(),
1703
1898
  status: _enum(["accepted", "failed"]),
1704
1899
  reason: string().optional()
1900
+ }).superRefine((report, ctx) => {
1901
+ if (report.daemonId !== void 0 && report.dispatchDaemonId !== void 0 && report.daemonId !== report.dispatchDaemonId) ctx.addIssue({
1902
+ code: "custom",
1903
+ path: ["dispatchDaemonId"],
1904
+ message: "dispatchDaemonId must equal daemonId on a delivery report"
1905
+ });
1705
1906
  });
1706
1907
  const RcGithubInstallation = object({
1707
1908
  installationId: string().min(1),
@@ -1938,6 +2139,9 @@ const RdMsg = discriminatedUnion("source", [
1938
2139
  hookId: string().uuid(),
1939
2140
  deliveryKey: string().min(1),
1940
2141
  firedAt: string().datetime(),
2142
+ ...OptionalHookConfigSnapshot.shape,
2143
+ event: string().min(1).optional(),
2144
+ github: GithubHookMetadata.optional(),
1941
2145
  context: HookContext.optional(),
1942
2146
  target: CronTarget.optional()
1943
2147
  })
@@ -2126,6 +2330,6 @@ function isFrame(type) {
2126
2330
  return (frame) => frame.type === type;
2127
2331
  }
2128
2332
  //#endregion
2129
- export { RELAY_DAEMON_WS_PATH as a, SHARED_CONFIG_ACTION_ID as c, encode as d, MAX_FRAME_BYTES as f, ZodIssueCode as g, RESERVED_MCP_SERVER_NAME as h, RELAY_DAEMON_SUBPROTOCOL as i, buildEnvelope as l, RelayRosterEntry as m, gitRepoLabel as n, buildRelayDaemonFrame as o, MEMORY_INDEX as p, normalizeGitUrl as r, decodeRelayDaemonFrame as s, isFrame as t, decodeEnvelope as u };
2333
+ export { ZodIssueCode as _, RELAY_DAEMON_WS_PATH as a, SHARED_CONFIG_ACTION_ID as c, encode as d, MAX_FRAME_BYTES as f, RESERVED_MCP_SERVER_NAME as g, RelayRosterEntry as h, RELAY_DAEMON_SUBPROTOCOL as i, buildEnvelope as l, HookReport as m, gitRepoLabel as n, buildRelayDaemonFrame as o, MEMORY_INDEX as p, normalizeGitUrl as r, decodeRelayDaemonFrame as s, isFrame as t, decodeEnvelope as u };
2130
2334
 
2131
- //# sourceMappingURL=dist-D8I6ZfGL.js.map
2335
+ //# sourceMappingURL=dist-D97dgR66.js.map