@loompad/cli 0.1.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 (177) hide show
  1. package/ARCHITECTURE.md +211 -0
  2. package/CHANGELOG.md +470 -0
  3. package/LICENSE +21 -0
  4. package/README.md +630 -0
  5. package/dist/adapters/base.d.ts +71 -0
  6. package/dist/adapters/base.js +187 -0
  7. package/dist/adapters/base.js.map +1 -0
  8. package/dist/adapters/bridges/antigravity.d.ts +53 -0
  9. package/dist/adapters/bridges/antigravity.js +106 -0
  10. package/dist/adapters/bridges/antigravity.js.map +1 -0
  11. package/dist/adapters/bridges/cdp.d.ts +82 -0
  12. package/dist/adapters/bridges/cdp.js +222 -0
  13. package/dist/adapters/bridges/cdp.js.map +1 -0
  14. package/dist/adapters/bridges/gui-chat.d.ts +113 -0
  15. package/dist/adapters/bridges/gui-chat.js +498 -0
  16. package/dist/adapters/bridges/gui-chat.js.map +1 -0
  17. package/dist/adapters/bridges/kiro.d.ts +19 -0
  18. package/dist/adapters/bridges/kiro.js +22 -0
  19. package/dist/adapters/bridges/kiro.js.map +1 -0
  20. package/dist/adapters/bridges/profiles.d.ts +82 -0
  21. package/dist/adapters/bridges/profiles.js +125 -0
  22. package/dist/adapters/bridges/profiles.js.map +1 -0
  23. package/dist/adapters/claude-code.d.ts +26 -0
  24. package/dist/adapters/claude-code.js +209 -0
  25. package/dist/adapters/claude-code.js.map +1 -0
  26. package/dist/adapters/codex.d.ts +51 -0
  27. package/dist/adapters/codex.js +291 -0
  28. package/dist/adapters/codex.js.map +1 -0
  29. package/dist/adapters/echo.d.ts +20 -0
  30. package/dist/adapters/echo.js +79 -0
  31. package/dist/adapters/echo.js.map +1 -0
  32. package/dist/adapters/grok.d.ts +61 -0
  33. package/dist/adapters/grok.js +217 -0
  34. package/dist/adapters/grok.js.map +1 -0
  35. package/dist/adapters/index.d.ts +9 -0
  36. package/dist/adapters/index.js +33 -0
  37. package/dist/adapters/index.js.map +1 -0
  38. package/dist/adapters/opencode.d.ts +64 -0
  39. package/dist/adapters/opencode.js +426 -0
  40. package/dist/adapters/opencode.js.map +1 -0
  41. package/dist/cli/common.d.ts +11 -0
  42. package/dist/cli/common.js +40 -0
  43. package/dist/cli/common.js.map +1 -0
  44. package/dist/cli/doctor.d.ts +12 -0
  45. package/dist/cli/doctor.js +181 -0
  46. package/dist/cli/doctor.js.map +1 -0
  47. package/dist/cli/index.d.ts +8 -0
  48. package/dist/cli/index.js +641 -0
  49. package/dist/cli/index.js.map +1 -0
  50. package/dist/cli/tui-model.d.ts +73 -0
  51. package/dist/cli/tui-model.js +312 -0
  52. package/dist/cli/tui-model.js.map +1 -0
  53. package/dist/cli/tui.d.ts +15 -0
  54. package/dist/cli/tui.js +451 -0
  55. package/dist/cli/tui.js.map +1 -0
  56. package/dist/cli/ui.d.ts +10 -0
  57. package/dist/cli/ui.js +135 -0
  58. package/dist/cli/ui.js.map +1 -0
  59. package/dist/core/ades.d.ts +79 -0
  60. package/dist/core/ades.js +130 -0
  61. package/dist/core/ades.js.map +1 -0
  62. package/dist/core/baton.d.ts +37 -0
  63. package/dist/core/baton.js +92 -0
  64. package/dist/core/baton.js.map +1 -0
  65. package/dist/core/brain-extract.d.ts +111 -0
  66. package/dist/core/brain-extract.js +248 -0
  67. package/dist/core/brain-extract.js.map +1 -0
  68. package/dist/core/brain-index.d.ts +128 -0
  69. package/dist/core/brain-index.js +338 -0
  70. package/dist/core/brain-index.js.map +1 -0
  71. package/dist/core/brain.d.ts +214 -0
  72. package/dist/core/brain.js +425 -0
  73. package/dist/core/brain.js.map +1 -0
  74. package/dist/core/claude-cli.d.ts +12 -0
  75. package/dist/core/claude-cli.js +47 -0
  76. package/dist/core/claude-cli.js.map +1 -0
  77. package/dist/core/distill.d.ts +19 -0
  78. package/dist/core/distill.js +88 -0
  79. package/dist/core/distill.js.map +1 -0
  80. package/dist/core/eventlog.d.ts +43 -0
  81. package/dist/core/eventlog.js +211 -0
  82. package/dist/core/eventlog.js.map +1 -0
  83. package/dist/core/git.d.ts +203 -0
  84. package/dist/core/git.js +460 -0
  85. package/dist/core/git.js.map +1 -0
  86. package/dist/core/logbook.d.ts +59 -0
  87. package/dist/core/logbook.js +118 -0
  88. package/dist/core/logbook.js.map +1 -0
  89. package/dist/core/memory.d.ts +34 -0
  90. package/dist/core/memory.js +124 -0
  91. package/dist/core/memory.js.map +1 -0
  92. package/dist/core/notify.d.ts +11 -0
  93. package/dist/core/notify.js +30 -0
  94. package/dist/core/notify.js.map +1 -0
  95. package/dist/core/projection.d.ts +20 -0
  96. package/dist/core/projection.js +96 -0
  97. package/dist/core/projection.js.map +1 -0
  98. package/dist/core/registry.d.ts +76 -0
  99. package/dist/core/registry.js +147 -0
  100. package/dist/core/registry.js.map +1 -0
  101. package/dist/core/router.d.ts +42 -0
  102. package/dist/core/router.js +99 -0
  103. package/dist/core/router.js.map +1 -0
  104. package/dist/core/routes.d.ts +93 -0
  105. package/dist/core/routes.js +399 -0
  106. package/dist/core/routes.js.map +1 -0
  107. package/dist/core/search.d.ts +63 -0
  108. package/dist/core/search.js +0 -0
  109. package/dist/core/search.js.map +1 -0
  110. package/dist/core/setup.d.ts +70 -0
  111. package/dist/core/setup.js +250 -0
  112. package/dist/core/setup.js.map +1 -0
  113. package/dist/core/suggestions.d.ts +15 -0
  114. package/dist/core/suggestions.js +38 -0
  115. package/dist/core/suggestions.js.map +1 -0
  116. package/dist/core/worktree.d.ts +32 -0
  117. package/dist/core/worktree.js +83 -0
  118. package/dist/core/worktree.js.map +1 -0
  119. package/dist/daemon/app-page.d.ts +32 -0
  120. package/dist/daemon/app-page.js +6363 -0
  121. package/dist/daemon/app-page.js.map +1 -0
  122. package/dist/daemon/auth.d.ts +51 -0
  123. package/dist/daemon/auth.js +135 -0
  124. package/dist/daemon/auth.js.map +1 -0
  125. package/dist/daemon/board.d.ts +117 -0
  126. package/dist/daemon/board.js +202 -0
  127. package/dist/daemon/board.js.map +1 -0
  128. package/dist/daemon/brand-icons.d.ts +29 -0
  129. package/dist/daemon/brand-icons.js +44 -0
  130. package/dist/daemon/brand-icons.js.map +1 -0
  131. package/dist/daemon/client.d.ts +127 -0
  132. package/dist/daemon/client.js +237 -0
  133. package/dist/daemon/client.js.map +1 -0
  134. package/dist/daemon/geist-font.d.ts +10 -0
  135. package/dist/daemon/geist-font.js +783 -0
  136. package/dist/daemon/geist-font.js.map +1 -0
  137. package/dist/daemon/guards.d.ts +18 -0
  138. package/dist/daemon/guards.js +40 -0
  139. package/dist/daemon/guards.js.map +1 -0
  140. package/dist/daemon/linear.d.ts +59 -0
  141. package/dist/daemon/linear.js +117 -0
  142. package/dist/daemon/linear.js.map +1 -0
  143. package/dist/daemon/push.d.ts +22 -0
  144. package/dist/daemon/push.js +58 -0
  145. package/dist/daemon/push.js.map +1 -0
  146. package/dist/daemon/runtime.d.ts +299 -0
  147. package/dist/daemon/runtime.js +1016 -0
  148. package/dist/daemon/runtime.js.map +1 -0
  149. package/dist/daemon/server.d.ts +125 -0
  150. package/dist/daemon/server.js +1728 -0
  151. package/dist/daemon/server.js.map +1 -0
  152. package/dist/daemon/tasks.d.ts +153 -0
  153. package/dist/daemon/tasks.js +264 -0
  154. package/dist/daemon/tasks.js.map +1 -0
  155. package/dist/daemon/terminals.d.ts +82 -0
  156. package/dist/daemon/terminals.js +372 -0
  157. package/dist/daemon/terminals.js.map +1 -0
  158. package/dist/index.d.ts +20 -0
  159. package/dist/index.js +20 -0
  160. package/dist/index.js.map +1 -0
  161. package/dist/sdk.d.ts +17 -0
  162. package/dist/sdk.js +17 -0
  163. package/dist/sdk.js.map +1 -0
  164. package/dist/types.d.ts +236 -0
  165. package/dist/types.js +18 -0
  166. package/dist/types.js.map +1 -0
  167. package/docs/SETUP.md +265 -0
  168. package/docs/adapters.md +132 -0
  169. package/docs/design-system.md +245 -0
  170. package/docs/img/board-linear.png +0 -0
  171. package/docs/img/board-projects.png +0 -0
  172. package/docs/img/brain.png +0 -0
  173. package/docs/img/settings.png +0 -0
  174. package/docs/img/workspace.png +0 -0
  175. package/docs/integration-notes.md +76 -0
  176. package/docs/proposals/brain.md +262 -0
  177. package/package.json +84 -0
@@ -0,0 +1,125 @@
1
+ /**
2
+ * What each GUI agent's chat is made of.
3
+ *
4
+ * Read off the running apps, with two projects' work behind them:
5
+ * krishnakanthb13/antigravity_phone_chat for the shape of Antigravity's chat,
6
+ * and yazanbaker94/AntiGravity-AutoAccept for how to attach to it at all. Both
7
+ * MIT, both doing this daily against real installs.
8
+ *
9
+ * Everything here was then checked against Antigravity IDE 1.107.0 on this
10
+ * machine, and the checking mattered — two of the borrowed selectors are gone
11
+ * in this build, and the app that matters isn't the one with the obvious name.
12
+ *
13
+ * The scoping is the important idea, and it's from the phone-chat project. The
14
+ * composer is looked for *inside* `#conversation` — never in the document at
15
+ * large. These are VS Code-family apps and Monaco, the editor holding your
16
+ * source file, is a `contenteditable`. Hunt the document and you will
17
+ * eventually find it and type a prompt into someone's code. Search inside the
18
+ * chat panel and you cannot.
19
+ *
20
+ * Selectors rot; two already did. When they stop matching, the bridge says so
21
+ * rather than improvising, and `options.selectors` overrides any of it without
22
+ * waiting for a release.
23
+ */
24
+ /** Anything under one of these is never a composer, whatever else it looks like. */
25
+ export const FORBIDDEN_ANCESTORS = [".monaco-editor", ".editor-instance", '[role="code"]'];
26
+ export const PROFILES = {
27
+ /**
28
+ * Antigravity IDE — a Lexical composer inside a `#conversation` panel.
29
+ *
30
+ * Read off the real thing: Antigravity IDE 1.107.0, signed in, workbench
31
+ * open. The composer is `<div data-lexical-editor="true" aria-label="Message
32
+ * input">` and the submit is:
33
+ *
34
+ * <button aria-label="Send message" data-testid="send-button"
35
+ * data-tooltip-id="input-send-button-send-tooltip">
36
+ *
37
+ * `data-testid` leads because a testid is a promise to a test suite, and
38
+ * things people test against get renamed less often than classes do. The
39
+ * tooltip id is the same control by another name, and it's what
40
+ * antigravity_phone_chat matches on. `svg.lucide-arrow-right` is that
41
+ * project's selector and finds nothing in this build — kept last so older
42
+ * installs still work.
43
+ *
44
+ * Note WHICH app this is. `Antigravity.app` and `Antigravity IDE.app` are two
45
+ * different programs: the first is the Manager (a plain https:// page behind
46
+ * a Google sign-in, no chat DOM at all), the second is the VS Code fork with
47
+ * the agent in it. Probing the Manager for a composer finds nothing and
48
+ * tells you Antigravity has no chat, which is wrong and wasted an afternoon.
49
+ */
50
+ antigravity: {
51
+ name: "Antigravity IDE",
52
+ defaultPort: 9333,
53
+ launch: {
54
+ darwin: 'open -a "Antigravity IDE" --args --remote-debugging-port=9333',
55
+ win32: "right-click the Antigravity IDE shortcut → Properties → append --remote-debugging-port=9333 to Target",
56
+ linux: "antigravity --remote-debugging-port=9333 (or add it to the Exec line of its .desktop file)",
57
+ },
58
+ chatRoots: ["#conversation", "#chat", ".cascade"],
59
+ composer: '[data-lexical-editor="true"], [contenteditable="true"]',
60
+ send: [
61
+ '[data-testid="send-button"]',
62
+ '[data-tooltip-id="input-send-button-send-tooltip"]',
63
+ "svg.lucide-arrow-right",
64
+ ],
65
+ busy: '[data-tooltip-id="input-send-button-cancel-tooltip"]',
66
+ transcript: ["#conversation", "#chat", ".cascade", "[data-scroll-area]"],
67
+ // Observed verbatim in 1.107.0: "There was an error with your
68
+ // authentication. To log in, click here".
69
+ signedOut: /error with your authentication|to log in, click here|^log in$/i,
70
+ },
71
+ /**
72
+ * Kiro — a VS Code fork whose chat lives in a workbench panel.
73
+ *
74
+ * Nobody has published working selectors for it and this machine can't
75
+ * produce them either: Kiro opens on a Getting Started tab with no chat panel,
76
+ * so there was nothing to read. These are the VS Code conventions its panel
77
+ * most likely follows, and if they miss, the bridge reports that rather than
78
+ * falling back to the document — which is where Monaco lives.
79
+ *
80
+ * Unverified. Set options.selectors.composer and it stops mattering.
81
+ */
82
+ kiro: {
83
+ name: "Kiro",
84
+ defaultPort: 9334,
85
+ launch: {
86
+ darwin: 'open -a "Kiro" --args --remote-debugging-port=9334',
87
+ win32: "right-click the Kiro shortcut → Properties → append --remote-debugging-port=9334 to Target",
88
+ linux: "kiro --remote-debugging-port=9334",
89
+ },
90
+ chatRoots: [
91
+ "#workbench\\.parts\\.sidebar",
92
+ "#workbench\\.parts\\.auxiliarybar",
93
+ "#workbench\\.parts\\.panel",
94
+ ".chat-container",
95
+ "[id*='chat']",
96
+ ],
97
+ composer: '.chat-input-container [contenteditable="true"], textarea, [contenteditable="true"]',
98
+ send: [".codicon-send", "[aria-label*='Send' i]"],
99
+ transcript: [".chat-container", ".interactive-list", "[id*='chat']"],
100
+ },
101
+ };
102
+ /**
103
+ * When we don't know the app: no chat root to scope to, so the composer has to
104
+ * earn it by being labelled like one, and Monaco is excluded explicitly rather
105
+ * than structurally. Strictly worse than a profile — that's why profiles exist.
106
+ */
107
+ export const GENERIC = {
108
+ name: "the app",
109
+ defaultPort: 9222,
110
+ launch: {
111
+ darwin: "launch it with --remote-debugging-port=9222",
112
+ win32: "launch it with --remote-debugging-port=9222",
113
+ linux: "launch it with --remote-debugging-port=9222",
114
+ },
115
+ chatRoots: ["body"],
116
+ composer: 'textarea, [contenteditable="true"]',
117
+ send: ["[aria-label='Send' i]", "button"],
118
+ transcript: ["body"],
119
+ };
120
+ /** What a chat box calls itself, for the generic path only. */
121
+ export const CHATTY = /ask|message|chat|prompt|plan|type .*here|what.*build|reply/i;
122
+ export function profileFor(kind) {
123
+ return PROFILES[kind] ?? GENERIC;
124
+ }
125
+ //# sourceMappingURL=profiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../../src/adapters/bridges/profiles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AA8CH,oFAAoF;AACpF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,gBAAgB,EAAE,kBAAkB,EAAE,eAAe,CAAC,CAAC;AAE3F,MAAM,CAAC,MAAM,QAAQ,GAA+B;IAClD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,WAAW,EAAE;QACX,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,IAAI;QACjB,MAAM,EAAE;YACN,MAAM,EAAE,+DAA+D;YACvE,KAAK,EAAE,uGAAuG;YAC9G,KAAK,EAAE,6FAA6F;SACrG;QACD,SAAS,EAAE,CAAC,eAAe,EAAE,OAAO,EAAE,UAAU,CAAC;QACjD,QAAQ,EAAE,wDAAwD;QAClE,IAAI,EAAE;YACJ,6BAA6B;YAC7B,oDAAoD;YACpD,wBAAwB;SACzB;QACD,IAAI,EAAE,sDAAsD;QAC5D,UAAU,EAAE,CAAC,eAAe,EAAE,OAAO,EAAE,UAAU,EAAE,oBAAoB,CAAC;QACxE,8DAA8D;QAC9D,0CAA0C;QAC1C,SAAS,EAAE,gEAAgE;KAC5E;IAED;;;;;;;;;;OAUG;IACH,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,IAAI;QACjB,MAAM,EAAE;YACN,MAAM,EAAE,oDAAoD;YAC5D,KAAK,EAAE,4FAA4F;YACnG,KAAK,EAAE,mCAAmC;SAC3C;QACD,SAAS,EAAE;YACT,8BAA8B;YAC9B,mCAAmC;YACnC,4BAA4B;YAC5B,iBAAiB;YACjB,cAAc;SACf;QACD,QAAQ,EAAE,oFAAoF;QAC9F,IAAI,EAAE,CAAC,eAAe,EAAE,wBAAwB,CAAC;QACjD,UAAU,EAAE,CAAC,iBAAiB,EAAE,mBAAmB,EAAE,cAAc,CAAC;KACrE;CACF,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAe;IACjC,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,IAAI;IACjB,MAAM,EAAE;QACN,MAAM,EAAE,6CAA6C;QACrD,KAAK,EAAE,6CAA6C;QACpD,KAAK,EAAE,6CAA6C;KACrD;IACD,SAAS,EAAE,CAAC,MAAM,CAAC;IACnB,QAAQ,EAAE,oCAAoC;IAC9C,IAAI,EAAE,CAAC,uBAAuB,EAAE,QAAQ,CAAC;IACzC,UAAU,EAAE,CAAC,MAAM,CAAC;CACrB,CAAC;AAEF,+DAA+D;AAC/D,MAAM,CAAC,MAAM,MAAM,GAAG,6DAA6D,CAAC;AAEpF,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC;AACnC,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Claude Code adapter — drives the `claude` CLI headless, one process per
3
+ * turn, resuming the same session id across turns.
4
+ *
5
+ * claude -p "<text>" --output-format stream-json --verbose
6
+ * [--resume <sessionId>] [--append-system-prompt <briefing>]
7
+ * --permission-mode <mode>
8
+ *
9
+ * Surface verified against claude 2.1.83 — see docs/integration-notes.md.
10
+ */
11
+ import type { SendInput } from "../types.js";
12
+ import { AdapterBase } from "./base.js";
13
+ export declare class ClaudeCodeAdapter extends AdapterBase {
14
+ private child;
15
+ private options;
16
+ constructor(id: string, projectDir: string, options?: Record<string, unknown>);
17
+ private get sessionId();
18
+ private set sessionId(value);
19
+ private get bin();
20
+ available(): Promise<boolean>;
21
+ start(): Promise<void>;
22
+ stop(): Promise<void>;
23
+ send(input: SendInput): Promise<void>;
24
+ private handleStreamEvent;
25
+ interrupt(): Promise<void>;
26
+ }
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Claude Code adapter — drives the `claude` CLI headless, one process per
3
+ * turn, resuming the same session id across turns.
4
+ *
5
+ * claude -p "<text>" --output-format stream-json --verbose
6
+ * [--resume <sessionId>] [--append-system-prompt <briefing>]
7
+ * --permission-mode <mode>
8
+ *
9
+ * Surface verified against claude 2.1.83 — see docs/integration-notes.md.
10
+ */
11
+ import { spawn } from "node:child_process";
12
+ import readline from "node:readline";
13
+ import { readProjectState, writeProjectState } from "../core/registry.js";
14
+ import { AdapterBase, agentEnv, cliAvailable } from "./base.js";
15
+ export class ClaudeCodeAdapter extends AdapterBase {
16
+ child = null;
17
+ options;
18
+ constructor(id, projectDir, options = {}) {
19
+ super(id, "claude-code", projectDir);
20
+ this.options = options;
21
+ }
22
+ get sessionId() {
23
+ const state = readProjectState(this.projectDir);
24
+ return state.agents[this.id]?.sessionId;
25
+ }
26
+ set sessionId(value) {
27
+ const state = readProjectState(this.projectDir);
28
+ state.agents[this.id] = { ...state.agents[this.id], sessionId: value };
29
+ writeProjectState(this.projectDir, state);
30
+ }
31
+ get bin() {
32
+ return this.options.bin ?? "claude";
33
+ }
34
+ async available() {
35
+ return cliAvailable(this.bin);
36
+ }
37
+ async start() {
38
+ this.emit({ kind: "status", payload: { state: "ready", session: this.sessionId ?? null } });
39
+ }
40
+ async stop() {
41
+ await this.interrupt();
42
+ }
43
+ async send(input) {
44
+ if (this._busy)
45
+ throw new Error(`claude-code agent "${this.id}" is busy`);
46
+ this._busy = true;
47
+ const started = Date.now();
48
+ const args = [
49
+ "-p",
50
+ input.text,
51
+ "--output-format",
52
+ "stream-json",
53
+ "--verbose",
54
+ "--permission-mode",
55
+ this.options.permissionMode ?? "acceptEdits",
56
+ ];
57
+ if (this.sessionId)
58
+ args.push("--resume", this.sessionId);
59
+ if (input.briefing)
60
+ args.push("--append-system-prompt", input.briefing);
61
+ if (this.options.model)
62
+ args.push("--model", this.options.model);
63
+ if (this.options.extraArgs)
64
+ args.push(...this.options.extraArgs);
65
+ try {
66
+ await new Promise((resolve, reject) => {
67
+ const child = spawn(this.bin, args, {
68
+ cwd: this.projectDir,
69
+ stdio: ["ignore", "pipe", "pipe"],
70
+ env: agentEnv(),
71
+ });
72
+ this.child = child;
73
+ let lastAssistantText = "";
74
+ let sawResult = false;
75
+ let stderrTail = "";
76
+ const rl = readline.createInterface({ input: child.stdout });
77
+ rl.on("line", (line) => {
78
+ const trimmed = line.trim();
79
+ if (!trimmed.startsWith("{"))
80
+ return;
81
+ let evt;
82
+ try {
83
+ evt = JSON.parse(trimmed);
84
+ }
85
+ catch {
86
+ return;
87
+ }
88
+ this.handleStreamEvent(evt, (t) => (lastAssistantText = t));
89
+ if (evt.type === "result")
90
+ sawResult = true;
91
+ });
92
+ child.stderr.on("data", (d) => {
93
+ stderrTail = (stderrTail + d.toString()).slice(-2000);
94
+ });
95
+ child.on("error", (err) => reject(err));
96
+ child.on("close", (code, signal) => {
97
+ this.child = null;
98
+ if (signal) {
99
+ this.emit({ kind: "status", payload: { state: "interrupted", signal } });
100
+ resolve();
101
+ return;
102
+ }
103
+ if (code !== 0 && !sawResult) {
104
+ this.emit({
105
+ kind: "error",
106
+ payload: { message: `${this.bin} exited ${code}`, stderr: stderrTail },
107
+ });
108
+ reject(new Error(`${this.bin} exited ${code}: ${stderrTail.slice(0, 200)}`));
109
+ return;
110
+ }
111
+ // Blocked-on-human heuristic: the turn ended on a question.
112
+ if (/\?\s*$/.test(lastAssistantText.trim())) {
113
+ this.emit({
114
+ kind: "needs_input",
115
+ payload: { question: lastAssistantText.slice(-500) },
116
+ });
117
+ }
118
+ this.emit({
119
+ kind: "run_complete",
120
+ payload: { durationMs: Date.now() - started },
121
+ });
122
+ resolve();
123
+ });
124
+ });
125
+ }
126
+ finally {
127
+ this._busy = false;
128
+ this.child = null;
129
+ }
130
+ }
131
+ handleStreamEvent(evt, setLastText) {
132
+ const type = evt.type;
133
+ if (type === "system" && evt.subtype === "init") {
134
+ const sid = evt.session_id;
135
+ if (sid)
136
+ this.sessionId = sid;
137
+ this.emit({ kind: "status", payload: { state: "turn_started", session: sid ?? null } });
138
+ return;
139
+ }
140
+ if (type === "assistant") {
141
+ const message = evt.message;
142
+ for (const block of message?.content ?? []) {
143
+ if (block.type === "text" && typeof block.text === "string" && block.text.trim()) {
144
+ setLastText(block.text);
145
+ this.emit({ kind: "message", payload: { text: block.text } });
146
+ }
147
+ else if (block.type === "thinking" && typeof block.thinking === "string" && block.thinking.trim()) {
148
+ // Extended thinking. Emitted as a reasoning-tagged message so the UI
149
+ // can fold it into its "thinking" block, the same shape codex and
150
+ // grok use. It never becomes lastAssistantText (that's the reply).
151
+ this.emit({ kind: "message", payload: { text: block.thinking, reasoning: true } });
152
+ }
153
+ else if (block.type === "tool_use") {
154
+ const name = String(block.name ?? "tool");
155
+ const input = (block.input ?? {});
156
+ this.emit({
157
+ kind: "tool_call",
158
+ payload: { tool: name, summary: summarizeToolInput(name, input) },
159
+ });
160
+ const path = input.file_path ?? input.notebook_path;
161
+ if (["Edit", "Write", "NotebookEdit", "MultiEdit"].includes(name) && path) {
162
+ this.emit({ kind: "file_edit", payload: { path: String(path), tool: name } });
163
+ }
164
+ }
165
+ }
166
+ return;
167
+ }
168
+ if (type === "result") {
169
+ const cost = evt.total_cost_usd;
170
+ const isError = Boolean(evt.is_error);
171
+ if (isError) {
172
+ this.emit({
173
+ kind: "error",
174
+ payload: { message: String(evt.result ?? evt.subtype ?? "unknown error") },
175
+ });
176
+ }
177
+ if (cost !== undefined) {
178
+ this.emit({ kind: "status", payload: { state: "turn_cost", costUsd: cost } });
179
+ }
180
+ }
181
+ }
182
+ async interrupt() {
183
+ const child = this.child;
184
+ if (!child)
185
+ return;
186
+ child.kill("SIGINT");
187
+ await new Promise((resolve) => {
188
+ const t = setTimeout(() => {
189
+ try {
190
+ child.kill("SIGKILL");
191
+ }
192
+ catch {
193
+ // already gone
194
+ }
195
+ resolve();
196
+ }, 3000);
197
+ child.on("close", () => {
198
+ clearTimeout(t);
199
+ resolve();
200
+ });
201
+ });
202
+ }
203
+ }
204
+ function summarizeToolInput(name, input) {
205
+ const interesting = input.file_path ?? input.command ?? input.pattern ?? input.url ?? input.prompt ?? "";
206
+ const text = String(interesting).replace(/\s+/g, " ");
207
+ return `${name}: ${text.slice(0, 160)}`;
208
+ }
209
+ //# sourceMappingURL=claude-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/adapters/claude-code.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Codex adapter — drives the `codex` CLI headless, one process per turn,
3
+ * resuming the same thread across turns.
4
+ *
5
+ * codex exec --json --skip-git-repo-check -C <dir> -s <sandbox> "<text>"
6
+ * codex exec resume <threadId> --json … "<text>"
7
+ *
8
+ * The CLI ships inside the desktop app as well as on PATH, so `available()`
9
+ * looks in both places — a Mac with Codex.app installed and nothing on PATH is
10
+ * the common case, and refusing to find it there would be wrong.
11
+ *
12
+ * Event surface verified against codex-cli 0.142.4 by running it and reading
13
+ * what came out, not by guessing:
14
+ *
15
+ * {"type":"thread.started","thread_id":"019f…"}
16
+ * {"type":"turn.started"}
17
+ * {"type":"item.started","item":{"id":"item_1","type":"command_execution",…}}
18
+ * {"type":"item.completed","item":{"id":"item_1","type":"command_execution",
19
+ * "command":"/bin/zsh -lc 'echo hi'","aggregated_output":"hi\n","exit_code":0}}
20
+ * {"type":"item.completed","item":{"id":"item_2","type":"agent_message","text":"…"}}
21
+ * {"type":"item.completed","item":{"id":"item_3","type":"file_change",
22
+ * "changes":[{"path":"/abs/note.txt","kind":"add"}]}}
23
+ * {"type":"turn.completed","usage":{"input_tokens":52831,"output_tokens":120,…}}
24
+ *
25
+ * Note what is NOT in there: money. Codex reports tokens, never a dollar
26
+ * figure, so this adapter reports tokens and no cost. Inventing a USD number
27
+ * from a price table we'd have to keep current is how you end up with a fake
28
+ * $0.001 in the UI presented as fact.
29
+ */
30
+ import type { SendInput } from "../types.js";
31
+ import { AdapterBase } from "./base.js";
32
+ /**
33
+ * Where the codex CLI is on this machine: an explicit override, then PATH,
34
+ * then inside the app bundle.
35
+ */
36
+ export declare function codexBin(override?: string): string | null;
37
+ export declare class CodexAdapter extends AdapterBase {
38
+ private child;
39
+ private options;
40
+ constructor(id: string, projectDir: string, options?: Record<string, unknown>);
41
+ /** Codex calls it a thread; loom stores it in the same slot as any session. */
42
+ private get threadId();
43
+ private set threadId(value);
44
+ available(): Promise<boolean>;
45
+ start(): Promise<void>;
46
+ stop(): Promise<void>;
47
+ send(input: SendInput): Promise<void>;
48
+ private handleEvent;
49
+ private handleItem;
50
+ interrupt(): Promise<void>;
51
+ }