agentspeak-cli 0.8.0 → 0.9.0

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 (77) hide show
  1. package/dist/adapters/claude.d.ts +13 -0
  2. package/dist/adapters/claude.d.ts.map +1 -0
  3. package/dist/adapters/claude.js +32 -0
  4. package/dist/adapters/claude.js.map +1 -0
  5. package/dist/adapters/cursor-agent.d.ts +10 -0
  6. package/dist/adapters/cursor-agent.d.ts.map +1 -0
  7. package/dist/adapters/cursor-agent.js +29 -0
  8. package/dist/adapters/cursor-agent.js.map +1 -0
  9. package/dist/adapters/echo.d.ts +17 -0
  10. package/dist/adapters/echo.d.ts.map +1 -0
  11. package/dist/adapters/echo.js +39 -0
  12. package/dist/adapters/echo.js.map +1 -0
  13. package/dist/adapters/hermes.d.ts +10 -0
  14. package/dist/adapters/hermes.d.ts.map +1 -0
  15. package/dist/adapters/hermes.js +33 -0
  16. package/dist/adapters/hermes.js.map +1 -0
  17. package/dist/adapters/index.d.ts +69 -0
  18. package/dist/adapters/index.d.ts.map +1 -0
  19. package/dist/adapters/index.js +106 -0
  20. package/dist/adapters/index.js.map +1 -0
  21. package/dist/adapters/openclaw.d.ts +10 -0
  22. package/dist/adapters/openclaw.d.ts.map +1 -0
  23. package/dist/adapters/openclaw.js +32 -0
  24. package/dist/adapters/openclaw.js.map +1 -0
  25. package/dist/adapters/shell-helper.d.ts +32 -0
  26. package/dist/adapters/shell-helper.d.ts.map +1 -0
  27. package/dist/adapters/shell-helper.js +99 -0
  28. package/dist/adapters/shell-helper.js.map +1 -0
  29. package/dist/adapters/stdin.d.ts +13 -0
  30. package/dist/adapters/stdin.d.ts.map +1 -0
  31. package/dist/adapters/stdin.js +72 -0
  32. package/dist/adapters/stdin.js.map +1 -0
  33. package/dist/api.d.ts +1 -0
  34. package/dist/api.d.ts.map +1 -1
  35. package/dist/api.js.map +1 -1
  36. package/dist/auto-shim.d.ts +38 -0
  37. package/dist/auto-shim.d.ts.map +1 -0
  38. package/dist/auto-shim.js +136 -0
  39. package/dist/auto-shim.js.map +1 -0
  40. package/dist/commands/handle-turn.d.ts +23 -8
  41. package/dist/commands/handle-turn.d.ts.map +1 -1
  42. package/dist/commands/handle-turn.js +119 -24
  43. package/dist/commands/handle-turn.js.map +1 -1
  44. package/dist/commands/identity.d.ts +28 -0
  45. package/dist/commands/identity.d.ts.map +1 -0
  46. package/dist/commands/identity.js +104 -0
  47. package/dist/commands/identity.js.map +1 -0
  48. package/dist/commands/inbox.d.ts +20 -0
  49. package/dist/commands/inbox.d.ts.map +1 -0
  50. package/dist/commands/inbox.js +41 -0
  51. package/dist/commands/inbox.js.map +1 -0
  52. package/dist/commands/init.d.ts +7 -0
  53. package/dist/commands/init.d.ts.map +1 -1
  54. package/dist/commands/init.js +35 -1
  55. package/dist/commands/init.js.map +1 -1
  56. package/dist/commands/mcp.d.ts +30 -0
  57. package/dist/commands/mcp.d.ts.map +1 -0
  58. package/dist/commands/mcp.js +195 -0
  59. package/dist/commands/mcp.js.map +1 -0
  60. package/dist/commands/register.d.ts.map +1 -1
  61. package/dist/commands/register.js +14 -1
  62. package/dist/commands/register.js.map +1 -1
  63. package/dist/commands/run.d.ts +29 -0
  64. package/dist/commands/run.d.ts.map +1 -1
  65. package/dist/commands/run.js +193 -12
  66. package/dist/commands/run.js.map +1 -1
  67. package/dist/exec.d.ts +44 -4
  68. package/dist/exec.d.ts.map +1 -1
  69. package/dist/exec.js +69 -5
  70. package/dist/exec.js.map +1 -1
  71. package/dist/index.js +103 -61
  72. package/dist/index.js.map +1 -1
  73. package/dist/state.d.ts +36 -0
  74. package/dist/state.d.ts.map +1 -1
  75. package/dist/state.js +64 -0
  76. package/dist/state.js.map +1 -1
  77. package/package.json +5 -2
@@ -0,0 +1,13 @@
1
+ import type { Adapter } from './index.js';
2
+ /**
3
+ * `--via claude` — Anthropic Claude Code CLI.
4
+ *
5
+ * Invocation: `claude -p` reads the prompt from stdin (when no string
6
+ * arg is given) and prints the model output on stdout. Works in both
7
+ * interactive and headless environments and respects ANTHROPIC_API_KEY.
8
+ *
9
+ * Smoke-test envelope short-circuits — we never spend an LLM call to
10
+ * pass the pre-attach gate.
11
+ */
12
+ export declare const claudeAdapter: Adapter;
13
+ //# sourceMappingURL=claude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,YAAY,CAAC;AAGzD;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,EAAE,OAmB3B,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { renderPromptFromEnvelope } from './index.js';
2
+ import { binaryMissing, shellOut, which } from './shell-helper.js';
3
+ /**
4
+ * `--via claude` — Anthropic Claude Code CLI.
5
+ *
6
+ * Invocation: `claude -p` reads the prompt from stdin (when no string
7
+ * arg is given) and prints the model output on stdout. Works in both
8
+ * interactive and headless environments and respects ANTHROPIC_API_KEY.
9
+ *
10
+ * Smoke-test envelope short-circuits — we never spend an LLM call to
11
+ * pass the pre-attach gate.
12
+ */
13
+ export const claudeAdapter = async (ctx) => {
14
+ const start = Date.now();
15
+ if (ctx.smokeTest) {
16
+ return ok('[smoke ok]', start);
17
+ }
18
+ const bin = which('claude');
19
+ if (!bin) {
20
+ return binaryMissing('claude', ctx, 'Install with `npm i -g @anthropic-ai/claude-code` and re-run, or pass --via echo / --via stdin.');
21
+ }
22
+ return shellOut({
23
+ bin,
24
+ args: ['-p'],
25
+ promptStdin: renderPromptFromEnvelope(ctx.envelope),
26
+ timeoutMs: ctx.timeoutMs,
27
+ });
28
+ };
29
+ function ok(body, start) {
30
+ return { stdout: body, stderr: '', exitCode: 0, durationMs: Date.now() - start, timedOut: false };
31
+ }
32
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAEnE;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAY,KAAK,EAAE,GAAG,EAAE,EAAE;IAClD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,OAAO,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC5B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,aAAa,CAClB,QAAQ,EACR,GAAG,EACH,iGAAiG,CAClG,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;QACd,GAAG;QACH,IAAI,EAAE,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnD,SAAS,EAAE,GAAG,CAAC,SAAS;KACzB,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,SAAS,EAAE,CAAC,IAAY,EAAE,KAAa;IACrC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AACpG,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Adapter } from './index.js';
2
+ /**
3
+ * `--via cursor-agent` — Cursor Agent CLI.
4
+ *
5
+ * Invocation: `cursor-agent --print` reads the prompt from stdin and
6
+ * prints the agent's response. The Cursor agent inherits the user's
7
+ * Cursor account and selected model — no API key plumbing required.
8
+ */
9
+ export declare const cursorAgentAdapter: Adapter;
10
+ //# sourceMappingURL=cursor-agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-agent.d.ts","sourceRoot":"","sources":["../../src/adapters/cursor-agent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,YAAY,CAAC;AAGzD;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,OAmBhC,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { renderPromptFromEnvelope } from './index.js';
2
+ import { binaryMissing, shellOut, which } from './shell-helper.js';
3
+ /**
4
+ * `--via cursor-agent` — Cursor Agent CLI.
5
+ *
6
+ * Invocation: `cursor-agent --print` reads the prompt from stdin and
7
+ * prints the agent's response. The Cursor agent inherits the user's
8
+ * Cursor account and selected model — no API key plumbing required.
9
+ */
10
+ export const cursorAgentAdapter = async (ctx) => {
11
+ const start = Date.now();
12
+ if (ctx.smokeTest) {
13
+ return ok('[smoke ok]', start);
14
+ }
15
+ const bin = which('cursor-agent');
16
+ if (!bin) {
17
+ return binaryMissing('cursor-agent', ctx, 'Install Cursor and enable the cursor-agent CLI (Cursor > Settings > Agent CLI).');
18
+ }
19
+ return shellOut({
20
+ bin,
21
+ args: ['--print'],
22
+ promptStdin: renderPromptFromEnvelope(ctx.envelope),
23
+ timeoutMs: ctx.timeoutMs,
24
+ });
25
+ };
26
+ function ok(body, start) {
27
+ return { stdout: body, stderr: '', exitCode: 0, durationMs: Date.now() - start, timedOut: false };
28
+ }
29
+ //# sourceMappingURL=cursor-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-agent.js","sourceRoot":"","sources":["../../src/adapters/cursor-agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAY,KAAK,EAAE,GAAG,EAAE,EAAE;IACvD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,OAAO,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC;IAClC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,aAAa,CAClB,cAAc,EACd,GAAG,EACH,iFAAiF,CAClF,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;QACd,GAAG;QACH,IAAI,EAAE,CAAC,SAAS,CAAC;QACjB,WAAW,EAAE,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnD,SAAS,EAAE,GAAG,CAAC,SAAS;KACzB,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,SAAS,EAAE,CAAC,IAAY,EAAE,KAAa;IACrC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AACpG,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { Adapter } from './index.js';
2
+ /**
3
+ * `--via echo` — built-in templated reply. Always succeeds.
4
+ *
5
+ * Useful in three places:
6
+ * 1. CI / smoke tests — proves the bridge layer works end-to-end
7
+ * without spinning up an LLM.
8
+ * 2. As the safe-default fallback when a meeting needs a participant
9
+ * to *exist* but you don't care what they say (passing turns).
10
+ * 3. As the body of the auto-written reply.sh until the operator
11
+ * edits it to call a real LLM.
12
+ *
13
+ * Honours the smoke-test envelope (returns "[smoke ok]") so it round-
14
+ * trips correctly through the pre-attach smoke test.
15
+ */
16
+ export declare const echoAdapter: Adapter;
17
+ //# sourceMappingURL=echo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"echo.d.ts","sourceRoot":"","sources":["../../src/adapters/echo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,YAAY,CAAC;AAEzD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,WAAW,EAAE,OAezB,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * `--via echo` — built-in templated reply. Always succeeds.
3
+ *
4
+ * Useful in three places:
5
+ * 1. CI / smoke tests — proves the bridge layer works end-to-end
6
+ * without spinning up an LLM.
7
+ * 2. As the safe-default fallback when a meeting needs a participant
8
+ * to *exist* but you don't care what they say (passing turns).
9
+ * 3. As the body of the auto-written reply.sh until the operator
10
+ * edits it to call a real LLM.
11
+ *
12
+ * Honours the smoke-test envelope (returns "[smoke ok]") so it round-
13
+ * trips correctly through the pre-attach smoke test.
14
+ */
15
+ export const echoAdapter = async (ctx) => {
16
+ const start = Date.now();
17
+ if (ctx.smokeTest) {
18
+ return result('[smoke ok]', start);
19
+ }
20
+ const env = ctx.envelope;
21
+ const turn = typeof env.turnNumber === 'number' ? env.turnNumber : '?';
22
+ const role = env.role ?? 'participant';
23
+ const body = `[ack] turn ${turn} acknowledged by --via echo (${role}).\n\n` +
24
+ 'This is the AgentSpeak built-in echo adapter. It does not call an LLM. ' +
25
+ 'Use a different `--via <preset>` (claude / cursor-agent / hermes / openclaw / stdin), ' +
26
+ 'pass `--exec ./reply.sh`, or rely on the auto-written `~/.agentspeak/reply.sh` ' +
27
+ 'to author real replies.';
28
+ return result(body, start);
29
+ };
30
+ function result(body, start) {
31
+ return {
32
+ stdout: body,
33
+ stderr: '',
34
+ exitCode: 0,
35
+ durationMs: Date.now() - start,
36
+ timedOut: false,
37
+ };
38
+ }
39
+ //# sourceMappingURL=echo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"echo.js","sourceRoot":"","sources":["../../src/adapters/echo.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,WAAW,GAAY,KAAK,EAAE,GAAG,EAAE,EAAE;IAChD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,OAAO,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;IACD,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC;IACzB,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;IACvE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,aAAa,CAAC;IACvC,MAAM,IAAI,GACR,cAAc,IAAI,gCAAgC,IAAI,QAAQ;QAC9D,yEAAyE;QACzE,wFAAwF;QACxF,iFAAiF;QACjF,yBAAyB,CAAC;IAC5B,OAAO,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC7B,CAAC,CAAC;AAEF,SAAS,MAAM,CAAC,IAAY,EAAE,KAAa;IACzC,OAAO;QACL,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE,CAAC;QACX,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;QAC9B,QAAQ,EAAE,KAAK;KAChB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Adapter } from './index.js';
2
+ /**
3
+ * `--via hermes` — Hermes runtime CLI bridge.
4
+ *
5
+ * Invocation: `hermes prompt` reads the prompt on stdin and prints the
6
+ * agent's reply. Detection prefers `which hermes` and falls back to
7
+ * `$HERMES_HOME/bin/hermes` so a pinned-install runtime still works.
8
+ */
9
+ export declare const hermesAdapter: Adapter;
10
+ //# sourceMappingURL=hermes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hermes.d.ts","sourceRoot":"","sources":["../../src/adapters/hermes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,YAAY,CAAC;AAGzD;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,EAAE,OAuB3B,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { renderPromptFromEnvelope } from './index.js';
2
+ import { binaryMissing, shellOut, which } from './shell-helper.js';
3
+ /**
4
+ * `--via hermes` — Hermes runtime CLI bridge.
5
+ *
6
+ * Invocation: `hermes prompt` reads the prompt on stdin and prints the
7
+ * agent's reply. Detection prefers `which hermes` and falls back to
8
+ * `$HERMES_HOME/bin/hermes` so a pinned-install runtime still works.
9
+ */
10
+ export const hermesAdapter = async (ctx) => {
11
+ const start = Date.now();
12
+ if (ctx.smokeTest) {
13
+ return ok('[smoke ok]', start);
14
+ }
15
+ let bin = which('hermes');
16
+ if (!bin && process.env.HERMES_HOME) {
17
+ const candidate = `${process.env.HERMES_HOME.replace(/\/$/, '')}/bin/hermes`;
18
+ bin = candidate;
19
+ }
20
+ if (!bin) {
21
+ return binaryMissing('hermes', ctx, 'Set HERMES_HOME or put the `hermes` binary on PATH; or pass --via stdin / --via echo.');
22
+ }
23
+ return shellOut({
24
+ bin,
25
+ args: ['prompt'],
26
+ promptStdin: renderPromptFromEnvelope(ctx.envelope),
27
+ timeoutMs: ctx.timeoutMs,
28
+ });
29
+ };
30
+ function ok(body, start) {
31
+ return { stdout: body, stderr: '', exitCode: 0, durationMs: Date.now() - start, timedOut: false };
32
+ }
33
+ //# sourceMappingURL=hermes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hermes.js","sourceRoot":"","sources":["../../src/adapters/hermes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAY,KAAK,EAAE,GAAG,EAAE,EAAE;IAClD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,OAAO,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC1B,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,SAAS,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC;QAC7E,GAAG,GAAG,SAAS,CAAC;IAClB,CAAC;IACD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,aAAa,CAClB,QAAQ,EACR,GAAG,EACH,uFAAuF,CACxF,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;QACd,GAAG;QACH,IAAI,EAAE,CAAC,QAAQ,CAAC;QAChB,WAAW,EAAE,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnD,SAAS,EAAE,GAAG,CAAC,SAAS;KACzB,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,SAAS,EAAE,CAAC,IAAY,EAAE,KAAa;IACrC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AACpG,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Built-in `--via <preset>` reply adapters.
3
+ *
4
+ * The shim model (--exec ./reply.sh) was the single biggest source of
5
+ * onboarding pain in the wild: agents on Windows hit shebang/PATH/jq
6
+ * issues, agents in sandboxed Python execute_code lost ~/reply.sh between
7
+ * tool calls, and every LLM that joined a meeting first had to author and
8
+ * smoke-test a brand-new bash script. Adapters short-circuit that whole
9
+ * loop: the CLI itself owns the bridge to the LLM, the agent just picks
10
+ * a preset, and (with the exception of `stdin`) there is zero per-machine
11
+ * authoring required.
12
+ *
13
+ * Each adapter is a stdin envelope -> stdout markdown function that
14
+ * returns the same `AdapterResult` shape as `runShim`. The pre-attach
15
+ * smoke test runs against the resolved adapter exactly the same way it
16
+ * runs against a user's `--exec` shim.
17
+ */
18
+ export interface TurnEnvelopeLike {
19
+ taskId?: string;
20
+ turnNumber?: number;
21
+ meetingId?: string;
22
+ agentId?: string;
23
+ role?: string;
24
+ instructions?: string;
25
+ previousTurns?: unknown[];
26
+ agentspeak?: {
27
+ smokeTest?: boolean;
28
+ version?: string;
29
+ } & Record<string, unknown>;
30
+ [k: string]: unknown;
31
+ }
32
+ export interface AdapterCtx {
33
+ envelope: TurnEnvelopeLike;
34
+ /** Smoke test envelope; adapter SHOULD short-circuit and not call its LLM. */
35
+ smokeTest: boolean;
36
+ /** Wall-clock budget for the call, in ms (forwarded to subprocesses). */
37
+ timeoutMs?: number;
38
+ }
39
+ export interface AdapterResult {
40
+ stdout: string;
41
+ stderr: string;
42
+ exitCode: number;
43
+ durationMs: number;
44
+ timedOut: boolean;
45
+ }
46
+ export type Adapter = (ctx: AdapterCtx) => Promise<AdapterResult>;
47
+ export interface AdapterDescriptor {
48
+ name: string;
49
+ summary: string;
50
+ /**
51
+ * If non-null, the adapter requires this binary to be on PATH. Surfaced
52
+ * in `--help` and the smoke-test failure hint so a missing binary
53
+ * produces an actionable error instead of `command not found`.
54
+ */
55
+ requiresBinary?: string;
56
+ adapter: Adapter;
57
+ }
58
+ export declare const ADAPTERS: Record<string, AdapterDescriptor>;
59
+ export declare function resolveAdapter(name: string): AdapterDescriptor;
60
+ export declare function listAdapterNames(): string[];
61
+ export declare function describeAdapters(): string;
62
+ /**
63
+ * Render the envelope as a single markdown prompt that we can hand to a
64
+ * generic LLM CLI. Includes role, instructions, and the transcript so
65
+ * far. Used by the shell-out adapters; pure adapters (echo/stdin) do
66
+ * their own formatting.
67
+ */
68
+ export declare function renderPromptFromEnvelope(env: TurnEnvelopeLike): string;
69
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjF,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,8EAA8E;IAC9E,SAAS,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;AAElE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAuCtD,CAAC;AAEF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAQ9D;AAED,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAOzC;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM,CAoCtE"}
@@ -0,0 +1,106 @@
1
+ import { echoAdapter } from './echo.js';
2
+ import { stdinAdapter } from './stdin.js';
3
+ import { claudeAdapter } from './claude.js';
4
+ import { cursorAgentAdapter } from './cursor-agent.js';
5
+ import { hermesAdapter } from './hermes.js';
6
+ import { openclawAdapter } from './openclaw.js';
7
+ export const ADAPTERS = {
8
+ echo: {
9
+ name: 'echo',
10
+ summary: 'Built-in templated [ack] reply. Zero deps. Useful for CI/smoke and passing turns.',
11
+ adapter: echoAdapter,
12
+ },
13
+ stdin: {
14
+ name: 'stdin',
15
+ summary: 'Interactive: print the turn envelope as markdown, read the reply from stdin until EOF. ' +
16
+ 'For human-in-the-loop or parent-runtimes that pipe replies in.',
17
+ adapter: stdinAdapter,
18
+ },
19
+ claude: {
20
+ name: 'claude',
21
+ summary: 'Exec `claude -p` (Anthropic Claude Code CLI). Requires the `claude` binary on PATH.',
22
+ requiresBinary: 'claude',
23
+ adapter: claudeAdapter,
24
+ },
25
+ 'cursor-agent': {
26
+ name: 'cursor-agent',
27
+ summary: 'Exec `cursor-agent --print`. Requires the `cursor-agent` binary on PATH.',
28
+ requiresBinary: 'cursor-agent',
29
+ adapter: cursorAgentAdapter,
30
+ },
31
+ hermes: {
32
+ name: 'hermes',
33
+ summary: 'Exec `hermes prompt` (Hermes runtime CLI). Requires `hermes` on PATH or HERMES_HOME set.',
34
+ requiresBinary: 'hermes',
35
+ adapter: hermesAdapter,
36
+ },
37
+ openclaw: {
38
+ name: 'openclaw',
39
+ summary: 'Exec `openclaw prompt` (OpenClaw runtime CLI). Requires `openclaw` on PATH or OPENCLAW_HOME set.',
40
+ requiresBinary: 'openclaw',
41
+ adapter: openclawAdapter,
42
+ },
43
+ };
44
+ export function resolveAdapter(name) {
45
+ const d = ADAPTERS[name];
46
+ if (!d) {
47
+ throw new Error(`unknown --via preset "${name}". Known presets: ${listAdapterNames().join(', ')}`);
48
+ }
49
+ return d;
50
+ }
51
+ export function listAdapterNames() {
52
+ return Object.keys(ADAPTERS);
53
+ }
54
+ export function describeAdapters() {
55
+ return listAdapterNames()
56
+ .map((n) => {
57
+ const d = ADAPTERS[n];
58
+ return ` ${n.padEnd(14)} ${d.summary}`;
59
+ })
60
+ .join('\n');
61
+ }
62
+ /**
63
+ * Render the envelope as a single markdown prompt that we can hand to a
64
+ * generic LLM CLI. Includes role, instructions, and the transcript so
65
+ * far. Used by the shell-out adapters; pure adapters (echo/stdin) do
66
+ * their own formatting.
67
+ */
68
+ export function renderPromptFromEnvelope(env) {
69
+ const parts = [];
70
+ parts.push('# AgentSpeak — your turn');
71
+ if (env.meetingId)
72
+ parts.push(`Meeting: ${env.meetingId}`);
73
+ if (env.role)
74
+ parts.push(`Your role: ${env.role}`);
75
+ if (typeof env.turnNumber === 'number')
76
+ parts.push(`Turn: ${env.turnNumber}`);
77
+ parts.push('');
78
+ if (env.instructions) {
79
+ parts.push('## Instructions');
80
+ parts.push(env.instructions);
81
+ parts.push('');
82
+ }
83
+ const prev = Array.isArray(env.previousTurns) ? env.previousTurns : [];
84
+ if (prev.length > 0) {
85
+ parts.push('## Transcript so far');
86
+ for (const t of prev) {
87
+ const turn = t;
88
+ const speaker = (turn.agentId ?? turn.role ?? 'unknown');
89
+ const n = typeof turn.turnNumber === 'number' ? turn.turnNumber : '?';
90
+ const arts = Array.isArray(turn.artifacts) ? turn.artifacts : [];
91
+ const text = arts
92
+ .map((a) => (typeof a.content === 'string' ? a.content : ''))
93
+ .filter((s) => s.length > 0)
94
+ .join('\n')
95
+ .trim();
96
+ parts.push(`### Turn ${n} — ${speaker}`);
97
+ parts.push(text || '(no body)');
98
+ parts.push('');
99
+ }
100
+ }
101
+ parts.push('---');
102
+ parts.push('Write your reply now in markdown. Output ONLY the reply body — no preamble, no role tags, no JSON wrapper. ' +
103
+ 'To close the meeting, include the literal HTML comment <!-- agentspeak:signal=done --> anywhere in your reply.');
104
+ return parts.join('\n');
105
+ }
106
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AA8DhD,MAAM,CAAC,MAAM,QAAQ,GAAsC;IACzD,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,mFAAmF;QAC5F,OAAO,EAAE,WAAW;KACrB;IACD,KAAK,EAAE;QACL,IAAI,EAAE,OAAO;QACb,OAAO,EACL,yFAAyF;YACzF,gEAAgE;QAClE,OAAO,EAAE,YAAY;KACtB;IACD,MAAM,EAAE;QACN,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,qFAAqF;QAC9F,cAAc,EAAE,QAAQ;QACxB,OAAO,EAAE,aAAa;KACvB;IACD,cAAc,EAAE;QACd,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,0EAA0E;QACnF,cAAc,EAAE,cAAc;QAC9B,OAAO,EAAE,kBAAkB;KAC5B;IACD,MAAM,EAAE;QACN,IAAI,EAAE,QAAQ;QACd,OAAO,EACL,0FAA0F;QAC5F,cAAc,EAAE,QAAQ;QACxB,OAAO,EAAE,aAAa;KACvB;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,UAAU;QAChB,OAAO,EACL,kGAAkG;QACpG,cAAc,EAAE,UAAU;QAC1B,OAAO,EAAE,eAAe;KACzB;CACF,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACzB,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CACb,yBAAyB,IAAI,qBAAqB,gBAAgB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAClF,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,gBAAgB,EAAE;SACtB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC;QACvB,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;IAC1C,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAqB;IAC5D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACvC,IAAI,GAAG,CAAC,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;IAC3D,IAAI,GAAG,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACnD,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACnC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,MAAM,IAAI,GAAG,CAA4B,CAAC;YAC1C,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,IAAI,SAAS,CAAW,CAAC;YACnE,MAAM,CAAC,GAAG,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;YACtE,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,SAAuC,CAAC,CAAC,CAAC,EAAE,CAAC;YAChG,MAAM,IAAI,GAAG,IAAI;iBACd,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;iBAC5D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;iBAC3B,IAAI,CAAC,IAAI,CAAC;iBACV,IAAI,EAAE,CAAC;YACV,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC;YACzC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,WAAW,CAAC,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CACR,6GAA6G;QAC3G,gHAAgH,CACnH,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Adapter } from './index.js';
2
+ /**
3
+ * `--via openclaw` — OpenClaw runtime CLI bridge.
4
+ *
5
+ * Invocation: `openclaw prompt` reads the prompt on stdin and prints the
6
+ * agent's reply. Falls back to `$OPENCLAW_HOME/bin/openclaw` when the
7
+ * binary is not on PATH (mirrors the hermes adapter).
8
+ */
9
+ export declare const openclawAdapter: Adapter;
10
+ //# sourceMappingURL=openclaw.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openclaw.d.ts","sourceRoot":"","sources":["../../src/adapters/openclaw.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,YAAY,CAAC;AAGzD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,OAsB7B,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { renderPromptFromEnvelope } from './index.js';
2
+ import { binaryMissing, shellOut, which } from './shell-helper.js';
3
+ /**
4
+ * `--via openclaw` — OpenClaw runtime CLI bridge.
5
+ *
6
+ * Invocation: `openclaw prompt` reads the prompt on stdin and prints the
7
+ * agent's reply. Falls back to `$OPENCLAW_HOME/bin/openclaw` when the
8
+ * binary is not on PATH (mirrors the hermes adapter).
9
+ */
10
+ export const openclawAdapter = async (ctx) => {
11
+ const start = Date.now();
12
+ if (ctx.smokeTest) {
13
+ return ok('[smoke ok]', start);
14
+ }
15
+ let bin = which('openclaw');
16
+ if (!bin && process.env.OPENCLAW_HOME) {
17
+ bin = `${process.env.OPENCLAW_HOME.replace(/\/$/, '')}/bin/openclaw`;
18
+ }
19
+ if (!bin) {
20
+ return binaryMissing('openclaw', ctx, 'Set OPENCLAW_HOME or put the `openclaw` binary on PATH; or pass --via stdin / --via echo.');
21
+ }
22
+ return shellOut({
23
+ bin,
24
+ args: ['prompt'],
25
+ promptStdin: renderPromptFromEnvelope(ctx.envelope),
26
+ timeoutMs: ctx.timeoutMs,
27
+ });
28
+ };
29
+ function ok(body, start) {
30
+ return { stdout: body, stderr: '', exitCode: 0, durationMs: Date.now() - start, timedOut: false };
31
+ }
32
+ //# sourceMappingURL=openclaw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openclaw.js","sourceRoot":"","sources":["../../src/adapters/openclaw.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAY,KAAK,EAAE,GAAG,EAAE,EAAE;IACpD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,OAAO,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,GAAG,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;IAC5B,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QACtC,GAAG,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC;IACvE,CAAC;IACD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,aAAa,CAClB,UAAU,EACV,GAAG,EACH,2FAA2F,CAC5F,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;QACd,GAAG;QACH,IAAI,EAAE,CAAC,QAAQ,CAAC;QAChB,WAAW,EAAE,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnD,SAAS,EAAE,GAAG,CAAC,SAAS;KACzB,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,SAAS,EAAE,CAAC,IAAY,EAAE,KAAa;IACrC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AACpG,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { AdapterCtx, AdapterResult } from './index.js';
2
+ /**
3
+ * Locate a binary on PATH, mimicking `which`. Returns the absolute
4
+ * path if found, or null otherwise. Used by every shell-out adapter
5
+ * so a missing binary surfaces as a clear "claude not on PATH"
6
+ * adapter error instead of a generic exit-127 from spawn.
7
+ */
8
+ export declare function which(bin: string): string | null;
9
+ export interface ShellOutOpts {
10
+ bin: string;
11
+ args: string[];
12
+ /** Prompt fed to the child on stdin. */
13
+ promptStdin: string;
14
+ /** Wall-clock budget. */
15
+ timeoutMs?: number;
16
+ /** Extra env vars merged onto process.env. */
17
+ env?: Record<string, string>;
18
+ }
19
+ /**
20
+ * Run a CLI binary with the prompt fed via stdin and capture stdout +
21
+ * stderr. Standard adapter primitive — every shell-out adapter (claude,
22
+ * cursor-agent, hermes, openclaw) shares this, so platform handling and
23
+ * error capture stay identical.
24
+ */
25
+ export declare function shellOut(opts: ShellOutOpts): Promise<AdapterResult>;
26
+ /**
27
+ * Standardised "binary not found" failure surfaced by every shell-out
28
+ * adapter so the smoke test's [SHIM-FAIL] hint can recommend the right
29
+ * fix verbatim.
30
+ */
31
+ export declare function binaryMissing(name: string, ctx: AdapterCtx, hint?: string): AdapterResult;
32
+ //# sourceMappingURL=shell-helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-helper.d.ts","sourceRoot":"","sources":["../../src/adapters/shell-helper.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE5D;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAehD;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CA6CzE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CAYzF"}
@@ -0,0 +1,99 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { existsSync } from 'node:fs';
3
+ import { delimiter, join } from 'node:path';
4
+ /**
5
+ * Locate a binary on PATH, mimicking `which`. Returns the absolute
6
+ * path if found, or null otherwise. Used by every shell-out adapter
7
+ * so a missing binary surfaces as a clear "claude not on PATH"
8
+ * adapter error instead of a generic exit-127 from spawn.
9
+ */
10
+ export function which(bin) {
11
+ const path = process.env.PATH ?? '';
12
+ const exts = process.platform === 'win32' ? (process.env.PATHEXT ?? '.EXE;.CMD;.BAT;.COM').split(';') : [''];
13
+ for (const dir of path.split(delimiter)) {
14
+ if (!dir)
15
+ continue;
16
+ for (const ext of exts) {
17
+ const candidate = join(dir, bin + ext.toLowerCase());
18
+ if (existsSync(candidate))
19
+ return candidate;
20
+ if (ext) {
21
+ const upper = join(dir, bin + ext);
22
+ if (existsSync(upper))
23
+ return upper;
24
+ }
25
+ }
26
+ }
27
+ return null;
28
+ }
29
+ /**
30
+ * Run a CLI binary with the prompt fed via stdin and capture stdout +
31
+ * stderr. Standard adapter primitive — every shell-out adapter (claude,
32
+ * cursor-agent, hermes, openclaw) shares this, so platform handling and
33
+ * error capture stay identical.
34
+ */
35
+ export async function shellOut(opts) {
36
+ const start = Date.now();
37
+ const proc = spawn(opts.bin, opts.args, {
38
+ stdio: ['pipe', 'pipe', 'pipe'],
39
+ env: { ...process.env, ...opts.env },
40
+ // No shell: true; we already resolved an absolute path with which().
41
+ // This avoids quoting/escaping pitfalls on Windows.
42
+ });
43
+ let stdout = '';
44
+ let stderr = '';
45
+ proc.stdout.on('data', (c) => {
46
+ stdout += c.toString('utf8');
47
+ });
48
+ proc.stderr.on('data', (c) => {
49
+ stderr += c.toString('utf8');
50
+ try {
51
+ process.stderr.write(c);
52
+ }
53
+ catch {
54
+ // tee best-effort
55
+ }
56
+ });
57
+ proc.stdin.write(opts.promptStdin);
58
+ proc.stdin.end();
59
+ let timedOut = false;
60
+ const timer = opts.timeoutMs
61
+ ? setTimeout(() => {
62
+ timedOut = true;
63
+ try {
64
+ proc.kill('SIGTERM');
65
+ }
66
+ catch {
67
+ // ignore
68
+ }
69
+ }, opts.timeoutMs)
70
+ : null;
71
+ const exitCode = await new Promise((resolve) => {
72
+ proc.on('exit', (c) => resolve(c ?? 1));
73
+ proc.on('error', (err) => {
74
+ stderr += `\n[spawn error] ${err instanceof Error ? err.message : String(err)}`;
75
+ resolve(127);
76
+ });
77
+ });
78
+ if (timer)
79
+ clearTimeout(timer);
80
+ return { stdout, stderr, exitCode, durationMs: Date.now() - start, timedOut };
81
+ }
82
+ /**
83
+ * Standardised "binary not found" failure surfaced by every shell-out
84
+ * adapter so the smoke test's [SHIM-FAIL] hint can recommend the right
85
+ * fix verbatim.
86
+ */
87
+ export function binaryMissing(name, ctx, hint) {
88
+ void ctx;
89
+ const msg = `${name} adapter: binary "${name}" not found on PATH. ` +
90
+ (hint ?? `Install ${name} and ensure it's executable from this shell, or pass a different --via preset.`);
91
+ return {
92
+ stdout: '',
93
+ stderr: msg,
94
+ exitCode: 127,
95
+ durationMs: 0,
96
+ timedOut: false,
97
+ };
98
+ }
99
+ //# sourceMappingURL=shell-helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-helper.js","sourceRoot":"","sources":["../../src/adapters/shell-helper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Adapter } from './index.js';
2
+ /**
3
+ * `--via stdin` — interactive bridge.
4
+ *
5
+ * Prints the rendered turn prompt to stdout, then reads the reply from
6
+ * stdin until EOF (Ctrl-D / pipe close). For a human-in-the-loop driver
7
+ * or for a parent runtime that pipes the reply in.
8
+ *
9
+ * Honours the smoke-test envelope to keep `cmdRun`'s pre-attach gate
10
+ * passable without forcing the operator to type anything during install.
11
+ */
12
+ export declare const stdinAdapter: Adapter;
13
+ //# sourceMappingURL=stdin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdin.d.ts","sourceRoot":"","sources":["../../src/adapters/stdin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,YAAY,CAAC;AAEzD;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,EAAE,OAsB1B,CAAC"}