acpx 0.20.0 → 0.21.1

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 (42) hide show
  1. package/dist/{agent-registry-Gtwn7nMp.js → agent-registry-Cz9fD9H1.js} +5 -8
  2. package/dist/{agent-registry-Gtwn7nMp.js.map → agent-registry-Cz9fD9H1.js.map} +1 -1
  3. package/dist/agent-registry.d.ts +0 -2
  4. package/dist/agent-registry.d.ts.map +1 -1
  5. package/dist/agent-registry.js +1 -1
  6. package/dist/{cli-CnufHoAJ.js → cli-BLEPj7lL.js} +6 -8
  7. package/dist/{cli-CnufHoAJ.js.map → cli-BLEPj7lL.js.map} +1 -1
  8. package/dist/cli.d.ts +1 -5
  9. package/dist/cli.d.ts.map +1 -1
  10. package/dist/cli.js +27 -45
  11. package/dist/cli.js.map +1 -1
  12. package/dist/{client-R5OmZ--S.d.ts → client-D12zqSyN.d.ts} +3 -8
  13. package/dist/client-D12zqSyN.d.ts.map +1 -0
  14. package/dist/{flows-CTRAV28u.js → flows-BVpRv0Df.js} +19 -33
  15. package/dist/{flows-CTRAV28u.js.map → flows-BVpRv0Df.js.map} +1 -1
  16. package/dist/flows.d.ts +2 -14
  17. package/dist/flows.d.ts.map +1 -1
  18. package/dist/flows.js +1 -1
  19. package/dist/{invocation-options-DE3Z_fqa.js → invocation-options-VJlayf-0.js} +16 -12
  20. package/dist/{invocation-options-DE3Z_fqa.js.map → invocation-options-VJlayf-0.js.map} +1 -1
  21. package/dist/{ipc-D2BC99hf.js → ipc-BbYFsKOj.js} +38 -69
  22. package/dist/ipc-BbYFsKOj.js.map +1 -0
  23. package/dist/{output-B1Srnvko.js → output-mqRHzGzM.js} +10 -17
  24. package/dist/{output-B1Srnvko.js.map → output-mqRHzGzM.js.map} +1 -1
  25. package/dist/{queue-owner-runtime-Be8sr9L5.js → queue-owner-runtime-B0mPqOu4.js} +168 -117
  26. package/dist/queue-owner-runtime-B0mPqOu4.js.map +1 -0
  27. package/dist/runtime.d.ts +18 -26
  28. package/dist/runtime.d.ts.map +1 -1
  29. package/dist/runtime.js +29 -32
  30. package/dist/runtime.js.map +1 -1
  31. package/dist/{session-options-DQlqgFv2.d.ts → session-options-BlnP3WAc.d.ts} +8 -7
  32. package/dist/session-options-BlnP3WAc.d.ts.map +1 -0
  33. package/dist/{session-watch-CpYYtV62.js → session-watch-BnIxHQrU.js} +5 -6
  34. package/dist/{session-watch-CpYYtV62.js.map → session-watch-BnIxHQrU.js.map} +1 -1
  35. package/dist/{watch-Db2D1eYN.js → watch-bQXyUy3z.js} +3 -4
  36. package/dist/{watch-Db2D1eYN.js.map → watch-bQXyUy3z.js.map} +1 -1
  37. package/package.json +20 -20
  38. package/skills/acpx/SKILL.md +27 -1
  39. package/dist/client-R5OmZ--S.d.ts.map +0 -1
  40. package/dist/ipc-D2BC99hf.js.map +0 -1
  41. package/dist/queue-owner-runtime-Be8sr9L5.js.map +0 -1
  42. package/dist/session-options-DQlqgFv2.d.ts.map +0 -1
@@ -1,8 +1,5 @@
1
1
  import { AgentCapabilities, AnyMessage, ContentBlock, CreateElicitationRequest, ElicitationContentValue, JsonRpcId, McpServer, McpServer as McpServer$1, RequestPermissionRequest, SessionConfigOption, SessionNotification, SetSessionConfigOptionResponse, ToolKind } from "@agentclientprotocol/sdk";
2
- //#region src/prompt-content.d.ts
3
2
  type PromptInput = ContentBlock[];
4
- //#endregion
5
- //#region src/types.d.ts
6
3
  type AcpPermissionRequest = {
7
4
  sessionId: string;
8
5
  raw: RequestPermissionRequest;
@@ -145,6 +142,13 @@ type AcpClientOptions = {
145
142
  agentArgv?: string[];
146
143
  /** Trusted child-only environment overlay; never persisted as session options. */
147
144
  agentProcessEnv?: Record<string, string>;
145
+ /**
146
+ * Opt-in allowlist: agent children, probes and terminals inherit only process essentials,
147
+ * these parent names and `ACPX_AUTH_*` grants.
148
+ */
149
+ agentProcessEnvAllow?: readonly string[];
150
+ /** Parent environment names that agent children, probes and terminals do not inherit. */
151
+ agentProcessEnvBlock?: readonly string[];
148
152
  cwd: string;
149
153
  mcpServers?: McpServer[];
150
154
  permissionMode: PermissionMode;
@@ -325,8 +329,6 @@ type SessionRecord = {
325
329
  acpx?: SessionAcpxState;
326
330
  importedFrom?: SessionImportedFrom;
327
331
  };
328
- //#endregion
329
- //#region src/runtime/engine/session-options.d.ts
330
332
  type SystemPromptOption = string | {
331
333
  append: string;
332
334
  };
@@ -346,6 +348,5 @@ type SessionAgentOptions = {
346
348
  */
347
349
  env?: Record<string, string>;
348
350
  };
349
- //#endregion
350
351
  export { PermissionPolicy as C, PromptInput as E, PermissionMode as S, SessionRecord as T, AcpProcessSpawnFailure as _, AcpElicitationHandler as a, McpServer$1 as b, AcpElicitationResponse as c, AcpPermissionHandler as d, AcpPermissionRequest as f, AcpProcessLifecycle as g, AcpProcessLaunchScope as h, AcpElicitationContext as i, AcpJsonRpcMessage as l, AcpProcessLaunch as m, SystemPromptOption as n, AcpElicitationMode as o, AcpProcessExit as p, AcpClientOptions as r, AcpElicitationRequest as s, SessionAgentOptions as t, AcpPermissionDecision as u, AcpProcessStarted as v, PermissionStats as w, NonInteractivePermissionPolicy as x, AuthPolicy as y };
351
- //# sourceMappingURL=session-options-DQlqgFv2.d.ts.map
352
+ //# sourceMappingURL=session-options-BlnP3WAc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-options-BlnP3WAc.d.ts","names":[],"sources":["../src/prompt-content.ts","../src/types.ts","../src/runtime/engine/session-options.ts"],"mappings":";KAEY,cAAc;KCgBd;EACV;EACA,KAAK;EACL,cAAc;;KAGJ;EACN;EAAqB;;EACrB;;EACA;;EACA;;EACA;;EACA;;KAEM,wBACV,SAAS,sBACT;EAAW,QAAQ;MAChB,QAAQ;cAEA;KACD,6BAA6B;KAC7B,wBAAwB;KAExB;;EAEV,WAAW;;EAEX,QAAQ;;KAGL;EACH,QAAQ;;KAGE;EAEN;EACA,UAAU,eAAe;IACvB;EACD;IAAsB;EACtB;IAAqB;KAEhB,yBACV,SAAS,uBACT,SAAS,0BACN,QAAQ;cAiBA;KACD,yBAAyB;cAExB;KACD,qBAAqB;cAEpB;KACD,yCAAyC;cAExC;KACD,iCAAiC;KAEjC;EACV;EACA;EACA;EACA,gBAAgB;;KAGN;EACV;EACA;EACA;EACA;EACA;EACA;EACA,WAAW;EACX;EACA;EACA;EACA;;KAQU,oBAAoB;KACpB;KAyCA;EACV;EACA;EACA;EACA;;KAGU;KAUA;KAEA;EACV,QAAQ;EACR,QAAQ;EACR;EACA;EACA;;KAGU;EACV;EACA;EACA;EACA;EACA;EACA;;KAgDU,wBACR;EAAW;KACX;EAAW;EAAyB;KACpC;EAAW;EAAuB;;KAE1B,mBAAmB;EAC7B;EACA,OAAO;EACP;EACA;EACA;;KAGU,oBAAoB,mBAC9B;EACE;EACA;;KAGQ,yBAAyB,mBACnC;EACE;EACA;;KAGQ,iBAAiB,oBAC3B;EACE;EACA,QAAQ,OAAO;EACf;;;;;;;;;KAUQ;EACV,iBAAiB,QAAQ,qBAAqB;EAC9C,aAAa,SAAS,sBAAsB;EAC5C,iBAAiB,SAAS,2BAA2B;EACrD,UAAU,MAAM,mBAAmB;;KAGzB;EACV;EACA;;EAEA,kBAAkB;;;;;EAKlB;;EAEA;EACA;EACA,aAAa;EACb,gBAAgB;EAChB,4BAA4B;EAC5B,mBAAmB;EACnB,kBAAkB;EAClB,aAAa;EACb;EACA;EACA,4BAA4B;EAC5B,mBAAmB;EACnB,qBAAqB;EACrB;EACA;EACA;IACE;IACA;IACA;IACA;MAA0B;;IAC1B,MAAM;;EAER,gBAAgB,WAAW,qBAAqB,SAAS;EACzD,sBAAsB,WAAW,qBAAqB,SAAS;EAC/D,mBAAmB,cAAc;EACjC,qBAAqB,WAAW;EAChC,0BAA0B,OAAO;EACjC,sBAAsB;;cAGX;KACD;EACV;EACA;EACA;IACE;IACA;;;KAIQ;EACV;EACA;;KAGU;EAEN;;EAGA;IACE;IACA;;;EAIF,OAAO;;EAGP,OAAO;;KAGD;EACV;EACA;EACA;EACA;EACA;EACA;;KAGU;EAEN;;EAGA,OAAO;;KAGD;EACV;EACA;EACA;EACA,SAAS;EACT;;KAGU;EAEN;;EAGA;IACE;IACA;;;EAIF;;EAGA,SAAS;;KAGH;EACV;EACA,SAAS;;KAGC;EACV,SAAS;EACT,cAAc,eAAe;EAC7B;;KAGU;EAEN,MAAM;;EAGN,OAAO;;KAID;EACV;EACA;EACA;EACA;EACA;EACA;;KAGU;EACV;EACA;;KAGU;EACV;EACA;EACA;;KAYU;EACV;EACA;EACA;EACA;EACA,yBAAyB;EACzB;EACA;EACA,wBAAwB;EACxB;EACA,qBAAqB;EACrB,iBAAiB;EACjB;IACE;IACA;IACA;IACA;MAA2B;;IAC3B,MAAM;;;KAIE;EACV;EACA;EACA;EACA;;KAGU;EACV,eAAe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;EACV;EACA;EACA;EACA;EACA;EACA;EACA,sBAAsB,OAAO;EAC7B;EACA;EACA;EACA,oBAAoB;EACpB;EACA,UAAU;EACV;EACA,wBAAwB;EACxB,kBAAkB;EAClB,qBAAqB,eAAe;EACpC,OAAO;EACP,eAAe;;KC7fL;EAAgC;;KAEhC;EACV;EACA;EACA;EACA,eAAe;;;;;;;;;;EAUf,MAAM"}
@@ -1,8 +1,8 @@
1
- import { i as JsonMessageSanitizer, t as createOutputFormatter } from "./output-B1Srnvko.js";
2
- import { it as isAcpJsonRpcMessage, lt as parsePromptStopReason } from "./ipc-D2BC99hf.js";
3
- import { t as watchSession } from "./watch-Db2D1eYN.js";
1
+ import { i as JsonMessageSanitizer, t as createOutputFormatter } from "./output-mqRHzGzM.js";
2
+ import { it as isAcpJsonRpcMessage, lt as parsePromptStopReason } from "./ipc-BbYFsKOj.js";
3
+ import { t as watchSession } from "./watch-bQXyUy3z.js";
4
4
  import { once } from "node:events";
5
- //#region src/cli/session-watch.ts
5
+ // src/cli/session-watch.ts
6
6
  function watchRenderer(policy) {
7
7
  const chunks = [];
8
8
  const stdout = { write: (chunk) => {
@@ -70,7 +70,6 @@ async function runSessionWatch(record, options) {
70
70
  }
71
71
  if (outputError) throw outputError;
72
72
  }
73
- //#endregion
74
73
  export { runSessionWatch };
75
74
 
76
- //# sourceMappingURL=session-watch-CpYYtV62.js.map
75
+ //# sourceMappingURL=session-watch-BnIxHQrU.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-watch-CpYYtV62.js","names":[],"sources":["../src/cli/session-watch.ts"],"sourcesContent":["import { once } from \"node:events\";\nimport { isAcpJsonRpcMessage, parsePromptStopReason } from \"../acp/jsonrpc.js\";\nimport type { SessionWatchEvent } from \"../session/journal.js\";\nimport { watchSession } from \"../session/watch.js\";\nimport type { OutputFormatter, OutputPolicy, SessionRecord } from \"../types.js\";\nimport { JsonMessageSanitizer } from \"./output/json-formatter.js\";\nimport { createOutputFormatter } from \"./output/output.js\";\n\nfunction watchRenderer(policy: OutputPolicy): (event: SessionWatchEvent) => string[] {\n const chunks: string[] = [];\n const stdout = {\n write: (chunk: string) => {\n chunks.push(chunk);\n },\n };\n let sanitizer = new JsonMessageSanitizer(policy.suppressReads, true);\n let formatter = createOutputFormatter(policy.format, { stdout });\n return (event) => {\n chunks.length = 0;\n if (event.type === \"turn_started\") {\n sanitizer = new JsonMessageSanitizer(policy.suppressReads, true);\n formatter = createOutputFormatter(policy.format, { stdout });\n }\n if (policy.format === \"json\") {\n chunks.push(\n JSON.stringify(\n event.type === \"message\"\n ? { ...event, message: sanitizer.sanitize(event.message) }\n : event,\n ) + \"\\n\",\n );\n } else if (event.type === \"message\") {\n renderWatchMessage(event, sanitizer, formatter, policy.format === \"quiet\");\n } else {\n if (event.type === \"turn_result\") {\n formatter.flush();\n }\n if (policy.format !== \"quiet\") {\n chunks.push(watchLifecycleLine(event));\n }\n }\n return chunks;\n };\n}\n\nfunction renderWatchMessage(\n event: Extract<SessionWatchEvent, { type: \"message\" }>,\n sanitizer: JsonMessageSanitizer,\n formatter: OutputFormatter,\n quiet: boolean,\n): void {\n const message = sanitizer.sanitize(event.message);\n if (!isAcpJsonRpcMessage(message)) {\n throw new Error(\"Invalid sanitized session message\");\n }\n if (quiet || parsePromptStopReason(message) === undefined) {\n formatter.onAcpMessage(message);\n }\n}\n\nfunction watchLifecycleLine(event: Exclude<SessionWatchEvent, { type: \"message\" }>): string {\n if (event.type === \"turn_started\") {\n return `\\n[${event.requestId}] started cursor=${event.cursor}\\n`;\n }\n const detail =\n event.result.status === \"failed\" ? event.result.error.message : event.result.stopReason;\n return `\\n[${event.requestId}] ${event.result.status}${detail ? `: ${detail}` : \"\"} cursor=${event.cursor}\\n`;\n}\n\nexport async function runSessionWatch(\n record: SessionRecord,\n options: { cursor?: string; policy: OutputPolicy },\n): Promise<void> {\n const stopped = new AbortController();\n let outputError: Error | undefined;\n const stop = () => stopped.abort();\n const onOutputError = (error: Error) => {\n if ((error as NodeJS.ErrnoException).code !== \"EPIPE\") {\n outputError = error;\n }\n stop();\n };\n const render = watchRenderer(options.policy);\n process.on(\"SIGINT\", stop);\n process.on(\"SIGTERM\", stop);\n process.on(\"SIGHUP\", stop);\n process.stdout.on(\"error\", onOutputError);\n try {\n for await (const event of watchSession({\n record,\n cursor: options.cursor,\n signal: stopped.signal,\n })) {\n for (const chunk of render(event)) {\n if (stopped.signal.aborted) {\n break;\n }\n if (!process.stdout.write(chunk)) {\n await once(process.stdout, \"drain\", { signal: stopped.signal });\n }\n }\n }\n } catch (error) {\n if (!stopped.signal.aborted) {\n throw error;\n }\n } finally {\n process.off(\"SIGINT\", stop);\n process.off(\"SIGTERM\", stop);\n process.off(\"SIGHUP\", stop);\n process.stdout.off(\"error\", onOutputError);\n }\n if (outputError) {\n throw outputError;\n }\n}\n"],"mappings":";;;;;AAQA,SAAS,cAAc,QAA8D;CACnF,MAAM,SAAmB,CAAC;CAC1B,MAAM,SAAS,EACb,QAAQ,UAAkB;EACxB,OAAO,KAAK,KAAK;CACnB,EACF;CACA,IAAI,YAAY,IAAI,qBAAqB,OAAO,eAAe,IAAI;CACnE,IAAI,YAAY,sBAAsB,OAAO,QAAQ,EAAE,OAAO,CAAC;CAC/D,QAAQ,UAAU;EAChB,OAAO,SAAS;EAChB,IAAI,MAAM,SAAS,gBAAgB;GACjC,YAAY,IAAI,qBAAqB,OAAO,eAAe,IAAI;GAC/D,YAAY,sBAAsB,OAAO,QAAQ,EAAE,OAAO,CAAC;EAC7D;EACA,IAAI,OAAO,WAAW,QACpB,OAAO,KACL,KAAK,UACH,MAAM,SAAS,YACX;GAAE,GAAG;GAAO,SAAS,UAAU,SAAS,MAAM,OAAO;EAAE,IACvD,KACN,IAAI,IACN;OACK,IAAI,MAAM,SAAS,WACxB,mBAAmB,OAAO,WAAW,WAAW,OAAO,WAAW,OAAO;OACpE;GACL,IAAI,MAAM,SAAS,eACjB,UAAU,MAAM;GAElB,IAAI,OAAO,WAAW,SACpB,OAAO,KAAK,mBAAmB,KAAK,CAAC;EAEzC;EACA,OAAO;CACT;AACF;AAEA,SAAS,mBACP,OACA,WACA,WACA,OACM;CACN,MAAM,UAAU,UAAU,SAAS,MAAM,OAAO;CAChD,IAAI,CAAC,oBAAoB,OAAO,GAC9B,MAAM,IAAI,MAAM,mCAAmC;CAErD,IAAI,SAAS,sBAAsB,OAAO,MAAM,KAAA,GAC9C,UAAU,aAAa,OAAO;AAElC;AAEA,SAAS,mBAAmB,OAAgE;CAC1F,IAAI,MAAM,SAAS,gBACjB,OAAO,MAAM,MAAM,UAAU,mBAAmB,MAAM,OAAO;CAE/D,MAAM,SACJ,MAAM,OAAO,WAAW,WAAW,MAAM,OAAO,MAAM,UAAU,MAAM,OAAO;CAC/E,OAAO,MAAM,MAAM,UAAU,IAAI,MAAM,OAAO,SAAS,SAAS,KAAK,WAAW,GAAG,UAAU,MAAM,OAAO;AAC5G;AAEA,eAAsB,gBACpB,QACA,SACe;CACf,MAAM,UAAU,IAAI,gBAAgB;CACpC,IAAI;CACJ,MAAM,aAAa,QAAQ,MAAM;CACjC,MAAM,iBAAiB,UAAiB;EACtC,IAAK,MAAgC,SAAS,SAC5C,cAAc;EAEhB,KAAK;CACP;CACA,MAAM,SAAS,cAAc,QAAQ,MAAM;CAC3C,QAAQ,GAAG,UAAU,IAAI;CACzB,QAAQ,GAAG,WAAW,IAAI;CAC1B,QAAQ,GAAG,UAAU,IAAI;CACzB,QAAQ,OAAO,GAAG,SAAS,aAAa;CACxC,IAAI;EACF,WAAW,MAAM,SAAS,aAAa;GACrC;GACA,QAAQ,QAAQ;GAChB,QAAQ,QAAQ;EAClB,CAAC,GACC,KAAK,MAAM,SAAS,OAAO,KAAK,GAAG;GACjC,IAAI,QAAQ,OAAO,SACjB;GAEF,IAAI,CAAC,QAAQ,OAAO,MAAM,KAAK,GAC7B,MAAM,KAAK,QAAQ,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,CAAC;EAElE;CAEJ,SAAS,OAAO;EACd,IAAI,CAAC,QAAQ,OAAO,SAClB,MAAM;CAEV,UAAU;EACR,QAAQ,IAAI,UAAU,IAAI;EAC1B,QAAQ,IAAI,WAAW,IAAI;EAC3B,QAAQ,IAAI,UAAU,IAAI;EAC1B,QAAQ,OAAO,IAAI,SAAS,aAAa;CAC3C;CACA,IAAI,aACF,MAAM;AAEV"}
1
+ {"version":3,"file":"session-watch-BnIxHQrU.js","names":[],"sources":["../src/cli/session-watch.ts"],"sourcesContent":["import { once } from \"node:events\";\nimport { isAcpJsonRpcMessage, parsePromptStopReason } from \"../acp/jsonrpc.js\";\nimport type { SessionWatchEvent } from \"../session/journal.js\";\nimport { watchSession } from \"../session/watch.js\";\nimport type { OutputFormatter, OutputPolicy, SessionRecord } from \"../types.js\";\nimport { JsonMessageSanitizer } from \"./output/json-formatter.js\";\nimport { createOutputFormatter } from \"./output/output.js\";\n\nfunction watchRenderer(policy: OutputPolicy): (event: SessionWatchEvent) => string[] {\n const chunks: string[] = [];\n const stdout = {\n write: (chunk: string) => {\n chunks.push(chunk);\n },\n };\n let sanitizer = new JsonMessageSanitizer(policy.suppressReads, true);\n let formatter = createOutputFormatter(policy.format, { stdout });\n return (event) => {\n chunks.length = 0;\n if (event.type === \"turn_started\") {\n sanitizer = new JsonMessageSanitizer(policy.suppressReads, true);\n formatter = createOutputFormatter(policy.format, { stdout });\n }\n if (policy.format === \"json\") {\n chunks.push(\n JSON.stringify(\n event.type === \"message\"\n ? { ...event, message: sanitizer.sanitize(event.message) }\n : event,\n ) + \"\\n\",\n );\n } else if (event.type === \"message\") {\n renderWatchMessage(event, sanitizer, formatter, policy.format === \"quiet\");\n } else {\n if (event.type === \"turn_result\") {\n formatter.flush();\n }\n if (policy.format !== \"quiet\") {\n chunks.push(watchLifecycleLine(event));\n }\n }\n return chunks;\n };\n}\n\nfunction renderWatchMessage(\n event: Extract<SessionWatchEvent, { type: \"message\" }>,\n sanitizer: JsonMessageSanitizer,\n formatter: OutputFormatter,\n quiet: boolean,\n): void {\n const message = sanitizer.sanitize(event.message);\n if (!isAcpJsonRpcMessage(message)) {\n throw new Error(\"Invalid sanitized session message\");\n }\n if (quiet || parsePromptStopReason(message) === undefined) {\n formatter.onAcpMessage(message);\n }\n}\n\nfunction watchLifecycleLine(event: Exclude<SessionWatchEvent, { type: \"message\" }>): string {\n if (event.type === \"turn_started\") {\n return `\\n[${event.requestId}] started cursor=${event.cursor}\\n`;\n }\n const detail =\n event.result.status === \"failed\" ? event.result.error.message : event.result.stopReason;\n return `\\n[${event.requestId}] ${event.result.status}${detail ? `: ${detail}` : \"\"} cursor=${event.cursor}\\n`;\n}\n\nexport async function runSessionWatch(\n record: SessionRecord,\n options: { cursor?: string; policy: OutputPolicy },\n): Promise<void> {\n const stopped = new AbortController();\n let outputError: Error | undefined;\n const stop = () => stopped.abort();\n const onOutputError = (error: Error) => {\n if ((error as NodeJS.ErrnoException).code !== \"EPIPE\") {\n outputError = error;\n }\n stop();\n };\n const render = watchRenderer(options.policy);\n process.on(\"SIGINT\", stop);\n process.on(\"SIGTERM\", stop);\n process.on(\"SIGHUP\", stop);\n process.stdout.on(\"error\", onOutputError);\n try {\n for await (const event of watchSession({\n record,\n cursor: options.cursor,\n signal: stopped.signal,\n })) {\n for (const chunk of render(event)) {\n if (stopped.signal.aborted) {\n break;\n }\n if (!process.stdout.write(chunk)) {\n await once(process.stdout, \"drain\", { signal: stopped.signal });\n }\n }\n }\n } catch (error) {\n if (!stopped.signal.aborted) {\n throw error;\n }\n } finally {\n process.off(\"SIGINT\", stop);\n process.off(\"SIGTERM\", stop);\n process.off(\"SIGHUP\", stop);\n process.stdout.off(\"error\", onOutputError);\n }\n if (outputError) {\n throw outputError;\n }\n}\n"],"mappings":";;;;;AAQA,SAAS,cAAc,QAA8D;CACnF,MAAM,SAAmB,CAAC;CAC1B,MAAM,SAAS,EACb,QAAQ,UAAkB;EACxB,OAAO,KAAK,KAAK;CACnB,EACF;CACA,IAAI,YAAY,IAAI,qBAAqB,OAAO,eAAe,IAAI;CACnE,IAAI,YAAY,sBAAsB,OAAO,QAAQ,EAAE,OAAO,CAAC;CAC/D,QAAQ,UAAU;EAChB,OAAO,SAAS;EAChB,IAAI,MAAM,SAAS,gBAAgB;GACjC,YAAY,IAAI,qBAAqB,OAAO,eAAe,IAAI;GAC/D,YAAY,sBAAsB,OAAO,QAAQ,EAAE,OAAO,CAAC;EAC7D;EACA,IAAI,OAAO,WAAW,QACpB,OAAO,KACL,KAAK,UACH,MAAM,SAAS,YACX;GAAE,GAAG;GAAO,SAAS,UAAU,SAAS,MAAM,OAAO;EAAE,IACvD,KACN,IAAI,IACN;OACK,IAAI,MAAM,SAAS,WACxB,mBAAmB,OAAO,WAAW,WAAW,OAAO,WAAW,OAAO;OACpE;GACL,IAAI,MAAM,SAAS,eACjB,UAAU,MAAM;GAElB,IAAI,OAAO,WAAW,SACpB,OAAO,KAAK,mBAAmB,KAAK,CAAC;EAEzC;EACA,OAAO;CACT;AACF;AAEA,SAAS,mBACP,OACA,WACA,WACA,OACM;CACN,MAAM,UAAU,UAAU,SAAS,MAAM,OAAO;CAChD,IAAI,CAAC,oBAAoB,OAAO,GAC9B,MAAM,IAAI,MAAM,mCAAmC;CAErD,IAAI,SAAS,sBAAsB,OAAO,MAAM,KAAA,GAC9C,UAAU,aAAa,OAAO;AAElC;AAEA,SAAS,mBAAmB,OAAgE;CAC1F,IAAI,MAAM,SAAS,gBACjB,OAAO,MAAM,MAAM,UAAU,mBAAmB,MAAM,OAAO;CAE/D,MAAM,SACJ,MAAM,OAAO,WAAW,WAAW,MAAM,OAAO,MAAM,UAAU,MAAM,OAAO;CAC/E,OAAO,MAAM,MAAM,UAAU,IAAI,MAAM,OAAO,SAAS,SAAS,KAAK,WAAW,GAAG,UAAU,MAAM,OAAO;AAC5G;AAEA,eAAsB,gBACpB,QACA,SACe;CACf,MAAM,UAAU,IAAI,gBAAgB;CACpC,IAAI;CACJ,MAAM,aAAa,QAAQ,MAAM;CACjC,MAAM,iBAAiB,UAAiB;EACtC,IAAK,MAAgC,SAAS,SAC5C,cAAc;EAEhB,KAAK;CACP;CACA,MAAM,SAAS,cAAc,QAAQ,MAAM;CAC3C,QAAQ,GAAG,UAAU,IAAI;CACzB,QAAQ,GAAG,WAAW,IAAI;CAC1B,QAAQ,GAAG,UAAU,IAAI;CACzB,QAAQ,OAAO,GAAG,SAAS,aAAa;CACxC,IAAI;EACF,WAAW,MAAM,SAAS,aAAa;GACrC;GACA,QAAQ,QAAQ;GAChB,QAAQ,QAAQ;EAClB,CAAC,GACC,KAAK,MAAM,SAAS,OAAO,KAAK,GAAG;GACjC,IAAI,QAAQ,OAAO,SACjB;GAEF,IAAI,CAAC,QAAQ,OAAO,MAAM,KAAK,GAC7B,MAAM,KAAK,QAAQ,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,CAAC;EAElE;CAEJ,SAAS,OAAO;EACd,IAAI,CAAC,QAAQ,OAAO,SAClB,MAAM;CAEV,UAAU;EACR,QAAQ,IAAI,UAAU,IAAI;EAC1B,QAAQ,IAAI,WAAW,IAAI;EAC3B,QAAQ,IAAI,UAAU,IAAI;EAC1B,QAAQ,OAAO,IAAI,SAAS,aAAa;CAC3C;CACA,IAAI,aACF,MAAM;AAEV"}
@@ -1,5 +1,5 @@
1
- import { E as observeProcessIncarnation, J as SessionWatchError, L as readSessionRecord, Y as watchSession$1, Zt as SessionNotFoundError, l as readQueueOwnerRecord } from "./ipc-D2BC99hf.js";
2
- //#region src/session/watch.ts
1
+ import { E as observeProcessIncarnation, J as SessionWatchError, L as readSessionRecord, Y as watchSession$1, Zt as SessionNotFoundError, l as readQueueOwnerRecord } from "./ipc-BbYFsKOj.js";
2
+ // src/session/watch.ts
3
3
  const OWNER_OBSERVATION_REUSE_MS = 1e3;
4
4
  function reuseObservation(cached) {
5
5
  if (!cached) return false;
@@ -79,7 +79,6 @@ function watchSession(options) {
79
79
  })[Symbol.asyncIterator]();
80
80
  } };
81
81
  }
82
- //#endregion
83
82
  export { watchSession as t };
84
83
 
85
- //# sourceMappingURL=watch-Db2D1eYN.js.map
84
+ //# sourceMappingURL=watch-bQXyUy3z.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"watch-Db2D1eYN.js","names":["watchJournal"],"sources":["../src/session/watch.ts"],"sourcesContent":["import { SessionNotFoundError } from \"../errors.js\";\nimport { observeProcessIncarnation, type ProcessIncarnation } from \"../process-identity.js\";\nimport type { SessionRecord } from \"../types.js\";\nimport {\n SessionWatchError,\n watchSession as watchJournal,\n type SessionWatchEvent,\n} from \"./journal.js\";\nimport { readSessionRecord } from \"./persistence.js\";\nimport { readQueueOwnerRecord, type QueueOwnerRecord } from \"./queue/lease-store.js\";\n\nconst OWNER_OBSERVATION_REUSE_MS = 1_000;\n\ntype WatchObservation = {\n ownerKey: string | null;\n incarnation?: { state: ProcessIncarnation; checkedAt: number; decisionPending: boolean };\n missingRequest: string | null;\n};\n\nfunction reuseObservation(cached: WatchObservation[\"incarnation\"]): boolean {\n if (!cached) {\n return false;\n }\n // A query first forces a journal reread, then gets one decision pass even\n // after a slow consumer. Otherwise repeated probes can defer errors forever.\n if (cached.decisionPending) {\n cached.decisionPending = false;\n return true;\n }\n return (\n cached.state === \"gone\" || performance.now() - cached.checkedAt < OWNER_OBSERVATION_REUSE_MS\n );\n}\n\nfunction selectOwner(owner: QueueOwnerRecord | undefined, observation: WatchObservation): boolean {\n // Heartbeats and retirement receipts do not change the owner's incarnation.\n // Keep only this small key, never the potentially large descendant receipt.\n const key = owner\n ? JSON.stringify([owner.pid, owner.ownerGeneration, owner.processIdentity])\n : null;\n if (key === observation.ownerKey) {\n return false;\n }\n observation.ownerKey = key;\n observation.incarnation = undefined;\n observation.missingRequest = null;\n return true;\n}\n\nasync function runningOwner(\n recordId: string,\n observation: WatchObservation,\n): Promise<{ owner?: QueueOwnerRecord; queried: boolean }> {\n let owner = await readQueueOwnerRecord(recordId);\n selectOwner(owner, observation);\n if (!owner) {\n return { queried: false };\n }\n const cached = observation.incarnation;\n let queried = false;\n // A verified departed incarnation cannot return. Cache that fact even for\n // idle watches; other observations are bounded independently of journal polls.\n if (!reuseObservation(cached)) {\n queried = true;\n // Observation cadence must not truncate the canonical provider's query budget.\n const state = await observeProcessIncarnation(owner.pid, owner.processIdentity);\n owner = await readQueueOwnerRecord(recordId);\n if (selectOwner(owner, observation)) {\n // A replacement may have settled or recovered the journal during the\n // query. Let the reader revisit it before interpreting the old result.\n return { owner, queried };\n }\n observation.incarnation = { state, checkedAt: performance.now(), decisionPending: true };\n }\n return { owner: observation.incarnation?.state === \"gone\" ? undefined : owner, queried };\n}\n\nasync function continueWatching(\n recordId: string,\n pendingRequestId: string | null,\n observation: WatchObservation,\n): Promise<boolean> {\n const { owner, queried } = await runningOwner(recordId, observation);\n if (queried) {\n // A probe can outlast a journal update, including replacement by an older\n // owner. Revisit the journal before any unsupported/unknown/end decision.\n observation.missingRequest = owner ? null : pendingRequestId;\n return true;\n }\n if (owner) {\n if (!owner.sessionWatch) {\n throw new SessionWatchError(\n \"WATCH_OWNER_UNSUPPORTED\",\n \"This running session owner predates passive watching. Let it expire when idle or explicitly close the session before starting new work.\",\n );\n }\n observation.missingRequest = null;\n return true;\n }\n if (pendingRequestId && pendingRequestId === observation.missingRequest) {\n throw new SessionWatchError(\n \"WATCH_OUTCOME_UNKNOWN\",\n `Session owner ended without a settled result for request ${pendingRequestId}; its outcome is unknown. Resume watching from the last cursor after recovery, and do not automatically replay the prompt.`,\n );\n }\n observation.missingRequest = pendingRequestId;\n if (pendingRequestId) {\n return true;\n }\n return await isSessionOpen(recordId);\n}\n\nasync function isSessionOpen(recordId: string): Promise<boolean> {\n const record = await readSessionRecord(recordId);\n if (!record || record.acpxRecordId !== recordId) {\n throw new SessionNotFoundError(recordId);\n }\n return record.closed !== true;\n}\n\nexport function watchSession(options: {\n record: SessionRecord | Promise<SessionRecord>;\n cursor?: string;\n signal?: AbortSignal;\n}): AsyncIterable<SessionWatchEvent> {\n return {\n [Symbol.asyncIterator]() {\n const observation: WatchObservation = { ownerKey: null, missingRequest: null };\n return watchJournal({\n ...options,\n continueWatching: (record, requestId) =>\n continueWatching(record.acpxRecordId, requestId, observation),\n })[Symbol.asyncIterator]();\n },\n };\n}\n"],"mappings":";;AAWA,MAAM,6BAA6B;AAQnC,SAAS,iBAAiB,QAAkD;CAC1E,IAAI,CAAC,QACH,OAAO;CAIT,IAAI,OAAO,iBAAiB;EAC1B,OAAO,kBAAkB;EACzB,OAAO;CACT;CACA,OACE,OAAO,UAAU,UAAU,YAAY,IAAI,IAAI,OAAO,YAAY;AAEtE;AAEA,SAAS,YAAY,OAAqC,aAAwC;CAGhG,MAAM,MAAM,QACR,KAAK,UAAU;EAAC,MAAM;EAAK,MAAM;EAAiB,MAAM;CAAe,CAAC,IACxE;CACJ,IAAI,QAAQ,YAAY,UACtB,OAAO;CAET,YAAY,WAAW;CACvB,YAAY,cAAc,KAAA;CAC1B,YAAY,iBAAiB;CAC7B,OAAO;AACT;AAEA,eAAe,aACb,UACA,aACyD;CACzD,IAAI,QAAQ,MAAM,qBAAqB,QAAQ;CAC/C,YAAY,OAAO,WAAW;CAC9B,IAAI,CAAC,OACH,OAAO,EAAE,SAAS,MAAM;CAE1B,MAAM,SAAS,YAAY;CAC3B,IAAI,UAAU;CAGd,IAAI,CAAC,iBAAiB,MAAM,GAAG;EAC7B,UAAU;EAEV,MAAM,QAAQ,MAAM,0BAA0B,MAAM,KAAK,MAAM,eAAe;EAC9E,QAAQ,MAAM,qBAAqB,QAAQ;EAC3C,IAAI,YAAY,OAAO,WAAW,GAGhC,OAAO;GAAE;GAAO;EAAQ;EAE1B,YAAY,cAAc;GAAE;GAAO,WAAW,YAAY,IAAI;GAAG,iBAAiB;EAAK;CACzF;CACA,OAAO;EAAE,OAAO,YAAY,aAAa,UAAU,SAAS,KAAA,IAAY;EAAO;CAAQ;AACzF;AAEA,eAAe,iBACb,UACA,kBACA,aACkB;CAClB,MAAM,EAAE,OAAO,YAAY,MAAM,aAAa,UAAU,WAAW;CACnE,IAAI,SAAS;EAGX,YAAY,iBAAiB,QAAQ,OAAO;EAC5C,OAAO;CACT;CACA,IAAI,OAAO;EACT,IAAI,CAAC,MAAM,cACT,MAAM,IAAI,kBACR,2BACA,yIACF;EAEF,YAAY,iBAAiB;EAC7B,OAAO;CACT;CACA,IAAI,oBAAoB,qBAAqB,YAAY,gBACvD,MAAM,IAAI,kBACR,yBACA,4DAA4D,iBAAiB,2HAC/E;CAEF,YAAY,iBAAiB;CAC7B,IAAI,kBACF,OAAO;CAET,OAAO,MAAM,cAAc,QAAQ;AACrC;AAEA,eAAe,cAAc,UAAoC;CAC/D,MAAM,SAAS,MAAM,kBAAkB,QAAQ;CAC/C,IAAI,CAAC,UAAU,OAAO,iBAAiB,UACrC,MAAM,IAAI,qBAAqB,QAAQ;CAEzC,OAAO,OAAO,WAAW;AAC3B;AAEA,SAAgB,aAAa,SAIQ;CACnC,OAAO,EACL,CAAC,OAAO,iBAAiB;EACvB,MAAM,cAAgC;GAAE,UAAU;GAAM,gBAAgB;EAAK;EAC7E,OAAOA,eAAa;GAClB,GAAG;GACH,mBAAmB,QAAQ,cACzB,iBAAiB,OAAO,cAAc,WAAW,WAAW;EAChE,CAAC,CAAC,CAAC,OAAO,cAAc,CAAC;CAC3B,EACF;AACF"}
1
+ {"version":3,"file":"watch-bQXyUy3z.js","names":["watchJournal"],"sources":["../src/session/watch.ts"],"sourcesContent":["import { SessionNotFoundError } from \"../errors.js\";\nimport { observeProcessIncarnation, type ProcessIncarnation } from \"../process-identity.js\";\nimport type { SessionRecord } from \"../types.js\";\nimport {\n SessionWatchError,\n watchSession as watchJournal,\n type SessionWatchEvent,\n} from \"./journal.js\";\nimport { readSessionRecord } from \"./persistence.js\";\nimport { readQueueOwnerRecord, type QueueOwnerRecord } from \"./queue/lease-store.js\";\n\nconst OWNER_OBSERVATION_REUSE_MS = 1_000;\n\ntype WatchObservation = {\n ownerKey: string | null;\n incarnation?: { state: ProcessIncarnation; checkedAt: number; decisionPending: boolean };\n missingRequest: string | null;\n};\n\nfunction reuseObservation(cached: WatchObservation[\"incarnation\"]): boolean {\n if (!cached) {\n return false;\n }\n // A query first forces a journal reread, then gets one decision pass even\n // after a slow consumer. Otherwise repeated probes can defer errors forever.\n if (cached.decisionPending) {\n cached.decisionPending = false;\n return true;\n }\n return (\n cached.state === \"gone\" || performance.now() - cached.checkedAt < OWNER_OBSERVATION_REUSE_MS\n );\n}\n\nfunction selectOwner(owner: QueueOwnerRecord | undefined, observation: WatchObservation): boolean {\n // Heartbeats and retirement receipts do not change the owner's incarnation.\n // Keep only this small key, never the potentially large descendant receipt.\n const key = owner\n ? JSON.stringify([owner.pid, owner.ownerGeneration, owner.processIdentity])\n : null;\n if (key === observation.ownerKey) {\n return false;\n }\n observation.ownerKey = key;\n observation.incarnation = undefined;\n observation.missingRequest = null;\n return true;\n}\n\nasync function runningOwner(\n recordId: string,\n observation: WatchObservation,\n): Promise<{ owner?: QueueOwnerRecord; queried: boolean }> {\n let owner = await readQueueOwnerRecord(recordId);\n selectOwner(owner, observation);\n if (!owner) {\n return { queried: false };\n }\n const cached = observation.incarnation;\n let queried = false;\n // A verified departed incarnation cannot return. Cache that fact even for\n // idle watches; other observations are bounded independently of journal polls.\n if (!reuseObservation(cached)) {\n queried = true;\n // Observation cadence must not truncate the canonical provider's query budget.\n const state = await observeProcessIncarnation(owner.pid, owner.processIdentity);\n owner = await readQueueOwnerRecord(recordId);\n if (selectOwner(owner, observation)) {\n // A replacement may have settled or recovered the journal during the\n // query. Let the reader revisit it before interpreting the old result.\n return { owner, queried };\n }\n observation.incarnation = { state, checkedAt: performance.now(), decisionPending: true };\n }\n return { owner: observation.incarnation?.state === \"gone\" ? undefined : owner, queried };\n}\n\nasync function continueWatching(\n recordId: string,\n pendingRequestId: string | null,\n observation: WatchObservation,\n): Promise<boolean> {\n const { owner, queried } = await runningOwner(recordId, observation);\n if (queried) {\n // A probe can outlast a journal update, including replacement by an older\n // owner. Revisit the journal before any unsupported/unknown/end decision.\n observation.missingRequest = owner ? null : pendingRequestId;\n return true;\n }\n if (owner) {\n if (!owner.sessionWatch) {\n throw new SessionWatchError(\n \"WATCH_OWNER_UNSUPPORTED\",\n \"This running session owner predates passive watching. Let it expire when idle or explicitly close the session before starting new work.\",\n );\n }\n observation.missingRequest = null;\n return true;\n }\n if (pendingRequestId && pendingRequestId === observation.missingRequest) {\n throw new SessionWatchError(\n \"WATCH_OUTCOME_UNKNOWN\",\n `Session owner ended without a settled result for request ${pendingRequestId}; its outcome is unknown. Resume watching from the last cursor after recovery, and do not automatically replay the prompt.`,\n );\n }\n observation.missingRequest = pendingRequestId;\n if (pendingRequestId) {\n return true;\n }\n return await isSessionOpen(recordId);\n}\n\nasync function isSessionOpen(recordId: string): Promise<boolean> {\n const record = await readSessionRecord(recordId);\n if (!record || record.acpxRecordId !== recordId) {\n throw new SessionNotFoundError(recordId);\n }\n return record.closed !== true;\n}\n\nexport function watchSession(options: {\n record: SessionRecord | Promise<SessionRecord>;\n cursor?: string;\n signal?: AbortSignal;\n}): AsyncIterable<SessionWatchEvent> {\n return {\n [Symbol.asyncIterator]() {\n const observation: WatchObservation = { ownerKey: null, missingRequest: null };\n return watchJournal({\n ...options,\n continueWatching: (record, requestId) =>\n continueWatching(record.acpxRecordId, requestId, observation),\n })[Symbol.asyncIterator]();\n },\n };\n}\n"],"mappings":";;AAWA,MAAM,6BAA6B;AAQnC,SAAS,iBAAiB,QAAkD;CAC1E,IAAI,CAAC,QACH,OAAO;CAIT,IAAI,OAAO,iBAAiB;EAC1B,OAAO,kBAAkB;EACzB,OAAO;CACT;CACA,OACE,OAAO,UAAU,UAAU,YAAY,IAAI,IAAI,OAAO,YAAY;AAEtE;AAEA,SAAS,YAAY,OAAqC,aAAwC;CAGhG,MAAM,MAAM,QACR,KAAK,UAAU;EAAC,MAAM;EAAK,MAAM;EAAiB,MAAM;CAAe,CAAC,IACxE;CACJ,IAAI,QAAQ,YAAY,UACtB,OAAO;CAET,YAAY,WAAW;CACvB,YAAY,cAAc,KAAA;CAC1B,YAAY,iBAAiB;CAC7B,OAAO;AACT;AAEA,eAAe,aACb,UACA,aACyD;CACzD,IAAI,QAAQ,MAAM,qBAAqB,QAAQ;CAC/C,YAAY,OAAO,WAAW;CAC9B,IAAI,CAAC,OACH,OAAO,EAAE,SAAS,MAAM;CAE1B,MAAM,SAAS,YAAY;CAC3B,IAAI,UAAU;CAGd,IAAI,CAAC,iBAAiB,MAAM,GAAG;EAC7B,UAAU;EAEV,MAAM,QAAQ,MAAM,0BAA0B,MAAM,KAAK,MAAM,eAAe;EAC9E,QAAQ,MAAM,qBAAqB,QAAQ;EAC3C,IAAI,YAAY,OAAO,WAAW,GAGhC,OAAO;GAAE;GAAO;EAAQ;EAE1B,YAAY,cAAc;GAAE;GAAO,WAAW,YAAY,IAAI;GAAG,iBAAiB;EAAK;CACzF;CACA,OAAO;EAAE,OAAO,YAAY,aAAa,UAAU,SAAS,KAAA,IAAY;EAAO;CAAQ;AACzF;AAEA,eAAe,iBACb,UACA,kBACA,aACkB;CAClB,MAAM,EAAE,OAAO,YAAY,MAAM,aAAa,UAAU,WAAW;CACnE,IAAI,SAAS;EAGX,YAAY,iBAAiB,QAAQ,OAAO;EAC5C,OAAO;CACT;CACA,IAAI,OAAO;EACT,IAAI,CAAC,MAAM,cACT,MAAM,IAAI,kBACR,2BACA,yIACF;EAEF,YAAY,iBAAiB;EAC7B,OAAO;CACT;CACA,IAAI,oBAAoB,qBAAqB,YAAY,gBACvD,MAAM,IAAI,kBACR,yBACA,4DAA4D,iBAAiB,2HAC/E;CAEF,YAAY,iBAAiB;CAC7B,IAAI,kBACF,OAAO;CAET,OAAO,MAAM,cAAc,QAAQ;AACrC;AAEA,eAAe,cAAc,UAAoC;CAC/D,MAAM,SAAS,MAAM,kBAAkB,QAAQ;CAC/C,IAAI,CAAC,UAAU,OAAO,iBAAiB,UACrC,MAAM,IAAI,qBAAqB,QAAQ;CAEzC,OAAO,OAAO,WAAW;AAC3B;AAEA,SAAgB,aAAa,SAIQ;CACnC,OAAO,EACL,CAAC,OAAO,iBAAiB;EACvB,MAAM,cAAgC;GAAE,UAAU;GAAM,gBAAgB;EAAK;EAC7E,OAAOA,eAAa;GAClB,GAAG;GACH,mBAAmB,QAAQ,cACzB,iBAAiB,OAAO,cAAc,WAAW,WAAW;EAChE,CAAC,CAAC,CAAC,OAAO,cAAc,CAAC;CAC3B,EACF;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "acpx",
3
- "version": "0.20.0",
3
+ "version": "0.21.1",
4
4
  "description": "Headless CLI client for the Agent Client Protocol (ACP) — talk to coding agents from the command line",
5
5
  "keywords": [
6
6
  "acp",
@@ -81,39 +81,39 @@
81
81
  "viewer:typecheck": "tsc -p examples/flows/replay-viewer/tsconfig.json --noEmit && tsc -p examples/flows/replay-viewer/tsconfig.server.json --noEmit"
82
82
  },
83
83
  "dependencies": {
84
- "@agentclientprotocol/sdk": "^1.5.0",
85
- "@openclaw/fs-safe": "^0.26.7",
84
+ "@agentclientprotocol/sdk": "^1.9.0",
85
+ "@openclaw/fs-safe": "^0.26.13",
86
86
  "commander": "^15.0.0",
87
87
  "skillflag": "^0.2.1",
88
88
  "tsx": "^4.23.15",
89
- "zod": "^4.6.5"
89
+ "zod": "^4.6.7"
90
90
  },
91
91
  "devDependencies": {
92
- "@stryker-mutator/core": "^10.0.0",
93
- "@types/node": "^26.6.2",
92
+ "@stryker-mutator/core": "^10.1.1",
93
+ "@types/node": "^26.6.5",
94
94
  "@types/react": "^19.3.0",
95
95
  "@types/react-dom": "^19.3.0",
96
96
  "@types/react-test-renderer": "^19.3.0",
97
- "@types/ws": "^8.18.1",
97
+ "@types/ws": "^8.18.2",
98
98
  "@typescript/native": "npm:typescript@^7.0.2",
99
- "@vitejs/plugin-react": "^6.1.1",
100
- "@xyflow/react": "^12.11.6",
99
+ "@vitejs/plugin-react": "^6.1.2",
100
+ "@xyflow/react": "^12.12.0",
101
101
  "c8": "^12.0.0",
102
102
  "elkjs": "^0.12.0",
103
103
  "fast-json-patch": "^3.1.1",
104
104
  "husky": "^9.1.7",
105
- "lint-staged": "^17.5.1",
106
- "markdownlint-cli2": "^0.23.3",
107
- "oxfmt": "^0.73.0",
108
- "oxlint": "^1.85.0",
109
- "oxlint-tsgolint": "^7.0.2002",
110
- "react": "^19.3.0",
111
- "react-dom": "^19.3.0",
112
- "react-test-renderer": "^19.3.0",
113
- "tsdown": "^0.23.0",
105
+ "lint-staged": "^17.6.0",
106
+ "markdownlint-cli2": "^0.24.0",
107
+ "oxfmt": "^0.74.0",
108
+ "oxlint": "^1.89.0",
109
+ "oxlint-tsgolint": "^7.0.2005",
110
+ "react": "^19.3.1",
111
+ "react-dom": "^19.3.1",
112
+ "react-test-renderer": "^19.3.1",
113
+ "tsdown": "^0.23.2",
114
114
  "typescript": "npm:@typescript/typescript6@^6.0.2",
115
- "vite": "^8.3.1",
116
- "ws": "^8.21.3"
115
+ "vite": "^8.3.5",
116
+ "ws": "^8.22.0"
117
117
  },
118
118
  "lint-staged": {
119
119
  "*.{js,ts}": [
@@ -117,6 +117,7 @@ Rules:
117
117
  - Default agent is `codex` for top-level `prompt`, `exec`, and `sessions`.
118
118
  - Unknown positional agent tokens are treated as raw agent commands.
119
119
  - `--agent <command>` explicitly sets a raw ACP adapter command.
120
+ - Claude package fallback uses the ACPX-owned adapter range. An adapter installed alongside ACPX takes precedence; update it and any explicitly selected native Claude executable separately. Existing custom launchers stay operator-controlled.
120
121
  - Do not combine a positional agent and `--agent` in the same command.
121
122
  - Gemini version checks, Copilot ACP support checks, and their startup diagnostics use the selected agent's working directory and child environment, including session environment and embedded runtime overrides.
122
123
  - Embedded host lifecycle admission also covers compatibility and diagnostic invocations. Correlate their events by `launchId`; one session can produce several adapter processes. Checks retire their owned processes and output pipes before settling.
@@ -399,7 +400,32 @@ Use `acpx config show` to inspect the resolved config and `acpx config init` to
399
400
  For ACP `authenticate` handshakes, use either config `auth` entries or explicit
400
401
  `ACPX_AUTH_<METHOD_ID>` environment variables such as `ACPX_AUTH_OPENAI_API_KEY`.
401
402
  Ambient provider env vars such as `OPENAI_API_KEY` are still passed through to
402
- child agents, but they do not trigger ACP auth-method selection on their own.
403
+ child agents by default, but they do not trigger ACP auth-method selection on
404
+ their own.
405
+
406
+ ## Embedded environment inheritance
407
+
408
+ Embedding hosts can set `agentProcessEnvAllow` or `agentProcessEnvBlock` on
409
+ `createAcpRuntime()` to keep parent variables, such as the host's own service
410
+ credentials, out of agents, command probes, and ACP terminals. Both are off by
411
+ default and the CLI does not set them, so without them children inherit the
412
+ whole environment as before.
413
+
414
+ - `agentProcessEnvAllow` keeps only process essentials (`PATH`, `HOME`, locale,
415
+ temp and similar names) plus the listed names. An empty list keeps only the
416
+ essentials and explicit grants.
417
+ - `agentProcessEnvBlock` removes the listed names, applied after the allowlist.
418
+ - Explicit grants still apply: `ACPX_AUTH_<METHOD_ID>` variables pass through
419
+ both lists, and `agentProcessEnv`, saved session `env`, and a terminal
420
+ request's own `env` are layered on top.
421
+
422
+ A filtered provider key does not reach the agent. Agent-specific environment
423
+ authentication that ACPX selects itself, such as Grok Build's `XAI_API_KEY` for
424
+ `xai.api_key`, is skipped as well when the key is filtered. Keep such a key by
425
+ listing it in the allowlist and leaving it off the blocklist, or pass it as an
426
+ `ACPX_AUTH_*` grant (for Grok Build, `ACPX_AUTH_XAI_API_KEY`). See
427
+ [`docs/runtime-environment.md`](https://github.com/openclaw/acpx/blob/main/docs/runtime-environment.md)
428
+ and [`agents/GrokBuild.md`](https://github.com/openclaw/acpx/blob/main/agents/GrokBuild.md).
403
429
 
404
430
  ## Devin ACP compatibility
405
431
 
@@ -1 +0,0 @@
1
- {"version":3,"file":"client-R5OmZ--S.d.ts","names":[],"sources":["../src/async-control.ts","../src/acp/model-config-state.ts","../src/acp/client.ts"],"mappings":";;;KAcY;EACV,SAAS;EACT;;;;KChBU;EACV;EACA;EACA,iBAAiB;IACf;IACA;;;;;KCiNC;EACH,YAAY;EACZ;EACA;EACA;;KAGU;EACV;EACA;EACA,gBAAgB;EAChB,SAAS;EACT;EACA;;KAGU;EACV;EACA,gBAAgB;EAChB,SAAS;EACT;EACA;;KAGU,sBAAsB;KA4C7B;KAsFO;EACV;EACA,QAAQ,OAAO;EACf;EACA,QAAQ;EACR;;KAGU;EACV;EACA;EACA;EACA,WAAW;;cAoBA;UACH;UACA;UACA;mBACS;mBACA;mBACA;UACT;UACA;UACA;mBAQS;mBAMA;mBACA;UACT;UACA;UACA;UACA;UACA;UACA;mBACS;mBACA;mBACA;UACT;UACA;UAEA;UACA;UACA;UACA;mBACS;mBACA;EAEL,YAAA,SAAS;MAmCjB,oBAAoB;EAIxB;EAIA,sBAAsB;EAItB,6BAA6B;EAW7B;EAIA;EAIA;EAIA;EAIA,iBACE,UAAU,KACR;EAWJ;EAIA,qBAAqB;IACnB,iBAAiB;IACjB,4BAA4B;IAC5B,mBAAmB;IACnB;IACA;IACA;IACA;;UAuBM;UASA;UAcA;EAUR,mBAAmB;EAInB,gBAAgB;EAUhB;UAIQ;EAWF,MACJ,YAAY,qBACZ,UAAU,KAAK,sCACd;UA0FW;UAWA;UA4DN;UAiBM;UAkBN;UAwBA;UAIM;UAwCN;UAOM;UA6EA;UAaA;UAoBN;UAgEM;UAwBA;UAoBA;UA+BN;UAgBA;EAWF,cACJ,cACA,YAAY,sBACX,QAAQ;EAiDL,YAAY,mBAAmB,eAAyB,QAAQ;EAKhE,uBACJ,mBACA,cACA,UAAS,qBACR,QAAQ;EAoCL,cACJ,mBACA,cACA,YAAY,sBACX,QAAQ;UAqBH;UAWA;EAKF,OACJ,mBACA,QAAQ,sBACR,yBAAyB,sBACzB,gBAAgB,uBAChB,sBAAsB,sBACtB,YAAY,sBACX,QAAQ;UA2CH;UAsBA;UAaA;UAUA;UAcA;UAwBA;UAYA;UAQA;EAOF,eACJ,mBACA,gBACA,YAAY,sBACX;EAaG,uBACJ,mBACA,kBACA,eACA,QAAQ,+BACR,YAAY,sBACX,QAAQ;EAuBL,gBACJ,mBACA,iBACA,QAAQ,+BACR,YAAY,sBACX,QAAQ;UAmBH;UAUM;UAoBA;UAqBN;EAoBF,OAAO,oBAAoB;EA8B3B,aAAa,oBAAoB;EAcjC,aAAa,SAAQ,sBAA2B,QAAQ;EAOxD,6BAA6B;EAS7B,mBAAmB,kBAAiB,QAAQ;EAyClD,SAAS;UAgBK;UAiCA;UAyCA;UAeN;UAIA;UAIM;UAON;UAcM;UA8BN;UAYM;UAyBN;UAkBA;UAOA;UAOA;UAcA;UASA;UAqEM;UA0BN;UA2CA;UAQA;UAUA;UAcM;UA6BA;UAiCN;UAUA;UAQM;UAuCN;UAuBA;UAqBA;UAIA;UAwBA;UASM;UA8BN;UAoBA;UAiBM;UAwBN;UAqBA;UAQA;UAQA;UA6BA;UAmBA;UAmBA;UAmBA;UAyBA;UAKA;UAwBA;UASA;UAUM;UAqDN;UAYM;UAmBA;UASA;UASA;UAoBN;UASA;UAMA;UAaA;UAWM;UAkBA;EAgCR,0BAA0B;IAC9B;IACA;MACE"}