@midhunxavier/code-flow 0.0.0-stage → 0.1.0-preview.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 (284) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +122 -2
  3. package/bin/codeflow.mjs +8 -0
  4. package/bin/launcher.mjs +127 -0
  5. package/dist/remote-host.json +1 -0
  6. package/licenses/inter.txt +92 -0
  7. package/licenses/preact.txt +21 -0
  8. package/licenses/signals-core.txt +21 -0
  9. package/licenses/signals.txt +21 -0
  10. package/licenses/typescript-notices.txt +193 -0
  11. package/licenses/typescript.txt +55 -0
  12. package/licenses/uqr.txt +22 -0
  13. package/licenses/xterm-fit.txt +19 -0
  14. package/licenses/xterm.txt +21 -0
  15. package/package.json +34 -4
  16. package/public/assets/browser-7XI52A6V.js +8 -0
  17. package/public/assets/changes-EYFPASEI.js +1 -0
  18. package/public/assets/chunk-7H3ZLTKA.js +2 -0
  19. package/public/assets/chunk-L7TUCIYF.js +1 -0
  20. package/public/assets/chunk-LLMQG23J.js +163 -0
  21. package/public/assets/main-KIRM2OEK.js +1 -0
  22. package/public/assets/settings-QJZVW22Y.js +9 -0
  23. package/public/assets/styles-615EBB20.css +32 -0
  24. package/public/assets/terminal-A2FI2NAX.js +62 -0
  25. package/public/assets.json +1 -0
  26. package/public/bundle-meta.json +1 -0
  27. package/public/docs/.nojekyll +0 -0
  28. package/public/docs/accessibility.html +19 -0
  29. package/public/docs/acp-agents.html +117 -0
  30. package/public/docs/agent-containers.html +79 -0
  31. package/public/docs/api.html +1130 -0
  32. package/public/docs/app.js +342 -0
  33. package/public/docs/application-improvements.html +275 -0
  34. package/public/docs/architecture-explorer.html +19 -0
  35. package/public/docs/architecture.html +149 -0
  36. package/public/docs/auto-team.html +142 -0
  37. package/public/docs/automations.html +109 -0
  38. package/public/docs/checkpoint-review.html +37 -0
  39. package/public/docs/code-hosts.html +35 -0
  40. package/public/docs/code-intelligence.html +35 -0
  41. package/public/docs/configuration.html +346 -0
  42. package/public/docs/context-inspection.html +23 -0
  43. package/public/docs/coordinated-changes.html +28 -0
  44. package/public/docs/deferred-runs.html +25 -0
  45. package/public/docs/dependency-discovery.html +19 -0
  46. package/public/docs/documentation.html +84 -0
  47. package/public/docs/dynamic-teams-evaluation.html +174 -0
  48. package/public/docs/dynamic-teams-implementation-plan.html +882 -0
  49. package/public/docs/dynamic-teams-implementation-review-1.html +141 -0
  50. package/public/docs/dynamic-teams-plan-review-0.html +204 -0
  51. package/public/docs/extensions.html +42 -0
  52. package/public/docs/external-sources.html +96 -0
  53. package/public/docs/filesystem-policy.html +26 -0
  54. package/public/docs/filtered-tasks.html +44 -0
  55. package/public/docs/font-license.txt +92 -0
  56. package/public/docs/getting-started.html +118 -0
  57. package/public/docs/github-review-threads.html +26 -0
  58. package/public/docs/github.html +157 -0
  59. package/public/docs/help.html +69 -0
  60. package/public/docs/index.html +77 -0
  61. package/public/docs/installation.html +74 -0
  62. package/public/docs/launch-profiles.html +48 -0
  63. package/public/docs/maintenance.html +60 -0
  64. package/public/docs/memory-claims.html +31 -0
  65. package/public/docs/memory-storage.html +58 -0
  66. package/public/docs/notifications.html +39 -0
  67. package/public/docs/patterns.html +195 -0
  68. package/public/docs/performance-results.html +210 -0
  69. package/public/docs/performance.html +166 -0
  70. package/public/docs/project-conventions.html +22 -0
  71. package/public/docs/project-first-navigation-plan.html +587 -0
  72. package/public/docs/project-teams-implementation-plan.html +772 -0
  73. package/public/docs/project-teams.html +99 -0
  74. package/public/docs/provider-compatibility.html +20 -0
  75. package/public/docs/releasing.html +61 -0
  76. package/public/docs/remote-workers.html +64 -0
  77. package/public/docs/review-inbox.html +26 -0
  78. package/public/docs/run-storage.html +23 -0
  79. package/public/docs/runs.html +141 -0
  80. package/public/docs/search.json +1 -0
  81. package/public/docs/security.html +133 -0
  82. package/public/docs/shared-projects.html +31 -0
  83. package/public/docs/ssh-projects.html +60 -0
  84. package/public/docs/style.css +768 -0
  85. package/public/docs/task-reruns.html +30 -0
  86. package/public/docs/team-collaboration.html +379 -0
  87. package/public/docs/verification.html +22 -0
  88. package/public/docs/vscode.html +53 -0
  89. package/public/docs/worker-permission-verification.html +122 -0
  90. package/public/index.html +17 -0
  91. package/scripts/check-node.mjs +7 -0
  92. package/scripts/codeflow.mjs +55 -0
  93. package/scripts/pty.py +273 -0
  94. package/src/acp-connections.js +110 -0
  95. package/src/adapters/acp-presets.js +37 -0
  96. package/src/adapters/acp-types.js +0 -0
  97. package/src/adapters/acp.js +328 -0
  98. package/src/adapters/agy-auth.js +67 -0
  99. package/src/adapters/agy-isolation.js +223 -0
  100. package/src/adapters/agy.js +297 -0
  101. package/src/adapters/claude.js +220 -0
  102. package/src/adapters/codex-app-server.js +518 -0
  103. package/src/adapters/codex.js +299 -0
  104. package/src/adapters/errors.js +57 -0
  105. package/src/adapters/index.js +91 -0
  106. package/src/adapters/managed-permissions.js +37 -0
  107. package/src/adapters/model-discovery.js +100 -0
  108. package/src/adapters/process.js +418 -0
  109. package/src/adapters/team-tools.js +102 -0
  110. package/src/adapters/types.js +0 -0
  111. package/src/agent-container.js +155 -0
  112. package/src/approvals.js +121 -0
  113. package/src/architecture.js +456 -0
  114. package/src/assets.js +44 -0
  115. package/src/automation.js +901 -0
  116. package/src/certificate-renewal.js +75 -0
  117. package/src/chat-handoff.js +55 -0
  118. package/src/checkpoint-review.js +72 -0
  119. package/src/checks.js +303 -0
  120. package/src/code-host-git.js +102 -0
  121. package/src/code-hosts-api.js +99 -0
  122. package/src/code-hosts.js +482 -0
  123. package/src/code-intelligence-worker.mjs +452 -0
  124. package/src/code-intelligence.js +141 -0
  125. package/src/collab/api.js +365 -0
  126. package/src/collab/checkpoints.js +198 -0
  127. package/src/collab/connections.js +139 -0
  128. package/src/collab/host-execution.js +347 -0
  129. package/src/collab/hub-client.js +210 -0
  130. package/src/collab/link-api.js +229 -0
  131. package/src/collab/link.js +595 -0
  132. package/src/collab/model.js +496 -0
  133. package/src/collab/runner.js +1014 -0
  134. package/src/collab/store.js +1452 -0
  135. package/src/collab/terminals.js +361 -0
  136. package/src/collaboration-reviews.js +116 -0
  137. package/src/config.js +48 -0
  138. package/src/context-budget.js +14 -0
  139. package/src/context-inspection.js +204 -0
  140. package/src/context.js +154 -0
  141. package/src/conventions.js +283 -0
  142. package/src/coordinated-api.js +247 -0
  143. package/src/deferred-launch.js +82 -0
  144. package/src/deferred-runs.js +515 -0
  145. package/src/dependency-health.js +35 -0
  146. package/src/diff.js +43 -0
  147. package/src/docs-help.js +316 -0
  148. package/src/doctor.js +232 -0
  149. package/src/engine.js +4366 -0
  150. package/src/env.js +44 -0
  151. package/src/experience.js +50 -0
  152. package/src/extensions.js +144 -0
  153. package/src/filesystem-access.js +107 -0
  154. package/src/filesystem-policy.js +238 -0
  155. package/src/filtered-task-limits.js +93 -0
  156. package/src/filtered-tasks-api.js +53 -0
  157. package/src/filtered-tasks.js +576 -0
  158. package/src/fs.js +57 -0
  159. package/src/git.js +626 -0
  160. package/src/github-review-threads.js +181 -0
  161. package/src/github.js +538 -0
  162. package/src/http.js +69 -0
  163. package/src/improve-settings.js +38 -0
  164. package/src/improve.js +187 -0
  165. package/src/integrations.js +373 -0
  166. package/src/integrity.js +259 -0
  167. package/src/journey-api.js +77 -0
  168. package/src/journey-replay.js +65 -0
  169. package/src/journey-store.js +97 -0
  170. package/src/journeys.js +60 -0
  171. package/src/json.js +81 -0
  172. package/src/launch-profiles.js +292 -0
  173. package/src/learnings.js +80 -0
  174. package/src/log.js +39 -0
  175. package/src/maintenance.js +335 -0
  176. package/src/memory-analysis.js +182 -0
  177. package/src/memory-claims.js +153 -0
  178. package/src/memory-sqlite.js +236 -0
  179. package/src/memory.js +552 -0
  180. package/src/merge-validation.js +58 -0
  181. package/src/model-catalog.js +238 -0
  182. package/src/model-research.js +91 -0
  183. package/src/notes.js +176 -0
  184. package/src/notifications.js +413 -0
  185. package/src/patterns/auto-team-model.js +212 -0
  186. package/src/patterns/auto-team.js +659 -0
  187. package/src/patterns/council.js +199 -0
  188. package/src/patterns/debate.js +188 -0
  189. package/src/patterns/findings.js +141 -0
  190. package/src/patterns/index.js +19 -0
  191. package/src/patterns/loop.js +158 -0
  192. package/src/patterns/pipeline.js +125 -0
  193. package/src/patterns/prompts.js +181 -0
  194. package/src/patterns/race.js +147 -0
  195. package/src/patterns/schemas.js +40 -0
  196. package/src/patterns/solo.js +49 -0
  197. package/src/patterns/supervisor.js +235 -0
  198. package/src/patterns/task-draft.js +29 -0
  199. package/src/patterns/tdd.js +231 -0
  200. package/src/patterns/team-strategies.js +67 -0
  201. package/src/performance.js +43 -0
  202. package/src/persistence-status.js +35 -0
  203. package/src/phone-sessions.js +96 -0
  204. package/src/preview-overlay.js +383 -0
  205. package/src/preview.js +219 -0
  206. package/src/privacy.js +23 -0
  207. package/src/project-report.js +22 -0
  208. package/src/project-team-model.js +178 -0
  209. package/src/project-team-policy.js +42 -0
  210. package/src/project-team-store.js +213 -0
  211. package/src/project-teams-api.js +36 -0
  212. package/src/project-teams.js +551 -0
  213. package/src/projects.js +286 -0
  214. package/src/provider-eligibility.js +9 -0
  215. package/src/readiness.js +98 -0
  216. package/src/remote-tls.js +66 -0
  217. package/src/remote-workers/bundles.js +198 -0
  218. package/src/remote-workers/client.js +332 -0
  219. package/src/remote-workers/durability.js +37 -0
  220. package/src/remote-workers/protocol.js +68 -0
  221. package/src/remote-workers/stdio.js +138 -0
  222. package/src/remote-workers/worker.js +304 -0
  223. package/src/remote.js +204 -0
  224. package/src/repo-config.js +201 -0
  225. package/src/repo-coordination.js +732 -0
  226. package/src/repo-tree.js +106 -0
  227. package/src/retention-policy.js +466 -0
  228. package/src/review-inbox.js +38 -0
  229. package/src/routing.js +49 -0
  230. package/src/run-analysis.js +111 -0
  231. package/src/run-cold-store.js +231 -0
  232. package/src/run-environment.js +15 -0
  233. package/src/run-history.js +91 -0
  234. package/src/run-log.js +160 -0
  235. package/src/run-permissions.js +110 -0
  236. package/src/run-projection.js +75 -0
  237. package/src/run-recovery.js +53 -0
  238. package/src/run-status.js +54 -0
  239. package/src/serve.js +138 -0
  240. package/src/server.js +2738 -0
  241. package/src/shared-access.js +103 -0
  242. package/src/shared-accounts.js +301 -0
  243. package/src/shared-api.js +239 -0
  244. package/src/shell.js +346 -0
  245. package/src/ship.js +344 -0
  246. package/src/slots.js +74 -0
  247. package/src/snapshot.js +388 -0
  248. package/src/source-context.js +17 -0
  249. package/src/sse-writer.js +70 -0
  250. package/src/ssh-projects/bootstrap.mjs +95 -0
  251. package/src/ssh-projects/config.js +45 -0
  252. package/src/ssh-projects/gateway.js +143 -0
  253. package/src/ssh-projects/manager.js +320 -0
  254. package/src/ssh-projects/team-autostart.mjs +93 -0
  255. package/src/ssh-projects/team-remove.mjs +69 -0
  256. package/src/ssh-projects/team-status.mjs +39 -0
  257. package/src/ssh-projects/transport.js +116 -0
  258. package/src/stats.js +139 -0
  259. package/src/store.js +544 -0
  260. package/src/stream.js +91 -0
  261. package/src/sweeps.js +241 -0
  262. package/src/tailscale.js +101 -0
  263. package/src/task-draft.js +23 -0
  264. package/src/team-evaluation.js +242 -0
  265. package/src/team-mailbox.js +160 -0
  266. package/src/team-memory.js +84 -0
  267. package/src/team-rerun-graph.js +15 -0
  268. package/src/team-reruns.js +130 -0
  269. package/src/team-scheduler.js +121 -0
  270. package/src/team-template-store.js +98 -0
  271. package/src/team-templates.js +117 -0
  272. package/src/team-tool-client.mjs +79 -0
  273. package/src/team-tools.js +176 -0
  274. package/src/teams.js +0 -0
  275. package/src/templates.js +62 -0
  276. package/src/transcript.js +134 -0
  277. package/src/verification-integrity.js +27 -0
  278. package/src/verification.js +183 -0
  279. package/src/watch.js +195 -0
  280. package/src/work-queue.js +47 -0
  281. package/src/workflow-control.js +83 -0
  282. package/src/workspace-api.js +207 -0
  283. package/src/workspace-changes.js +61 -0
  284. package/src/workspace.js +146 -0
@@ -0,0 +1,297 @@
1
+ import { mkdtemp, rm } from "node:fs/promises";
2
+ import { tmpdir } from "node:os";
3
+ import { AGY_NATIVE_LIMITATION } from "../run-permissions.js";
4
+ import { join } from "node:path";
5
+ import { agyCredentialFailure, inspectAgyAuthLog } from "./agy-auth.js";
6
+ import { classifyError, cliErrorLine, resetFromText } from "./errors.js";
7
+ import { captureOutput, commandExists, describeFailure, processErrorKind, startJsonlProcess, stringify, truncate, unknownEvents } from "./process.js";
8
+ import { STEP_TIMEOUT_MS } from "../config.js";
9
+ import { childEnv } from "../env.js";
10
+ import { agyIsolationProblem, agyManagedOptionsProblem, inspectAgyIsolationRuntime, prepareAgyIsolation, discoverIsolatedAgyModels, AGY_FILE_ONLY_LIMITATION, AGY_ISOLATION_VERSION } from "./agy-isolation.js";
11
+ function sandboxGitEnv() {
12
+ return {
13
+ ...childEnv(),
14
+ GIT_CONFIG_GLOBAL: "/dev/null",
15
+ GIT_CONFIG_COUNT: "1",
16
+ GIT_CONFIG_KEY_0: "core.excludesFile",
17
+ GIT_CONFIG_VALUE_0: "/dev/null"
18
+ };
19
+ }
20
+ function skipPermissions() {
21
+ return process.env.CODEFLOW_AGY_SKIP_PERMISSIONS !== "0";
22
+ }
23
+ function createAgyAdapter(prepare = async (opts) => prepareAgyIsolation(opts.cwd, opts.mode, await inspectAgyIsolationRuntime())) {
24
+ return {
25
+ id: "agy",
26
+ displayName: "Antigravity CLI",
27
+ binary: "agy",
28
+ available: () => commandExists("agy"),
29
+ managedAvailability: agyIsolationProblem,
30
+ managedLimitations: [AGY_FILE_ONLY_LIMITATION],
31
+ async discoverModels(context) {
32
+ if (context?.agentContainer) throw new Error("Antigravity container discovery is unverified");
33
+ if (context?.isolatedAgy) return discoverIsolatedAgyModels();
34
+ const catalog = await discoverNativeAgyModels();
35
+ return { ...catalog, efforts: [], models: catalog.models.map((model) => ({ ...model, efforts: void 0 })), discovery: { source: "agy models", confidence: "reported", verifiedAt: Date.now() } };
36
+ },
37
+ async catalog() {
38
+ const out = await captureOutput("agy", ["models"], 45e3);
39
+ const models = out.split("\n").map((line) => line.split(" ")).filter((cols) => cols.length >= 2 && cols[0].trim()).map(([id, label]) => ({ id: id.trim(), label: label.trim() }));
40
+ return { models, efforts: ["low", "medium", "high", "xhigh", "max"], allowCustom: true };
41
+ },
42
+ async run(opts, onEvent) {
43
+ const native = opts.permissions?.implementation === "agy-native-v1";
44
+ const managed = !!opts.permissions;
45
+ let nativeScratch;
46
+ let isolation;
47
+ if (opts.permissions) {
48
+ const problem = native ? agyNativeOptionsProblem(opts) : agyManagedOptionsProblem(opts);
49
+ if (problem) return { ok: false, finalText: "", errorKind: "cli_incompatible", error: problem };
50
+ if (opts.resumeSessionId) return { ok: false, finalText: "", errorKind: "session_not_found", error: "Managed Antigravity requires a fresh turn with portable context" };
51
+ try {
52
+ if (!native) isolation = await prepare(opts);
53
+ } catch {
54
+ return { ok: false, finalText: "", errorKind: "cli_incompatible", error: "Could not establish the verified Antigravity isolation boundary. macOS, CLI 1.4.4 and an existing Keychain login/security cache are required. No permissive fallback was used." };
55
+ }
56
+ }
57
+ try {
58
+ if (native) {
59
+ nativeScratch = await mkdtemp(join(tmpdir(), "codeflow-agy-native-"));
60
+ onEvent({ kind: "status", text: AGY_NATIVE_LIMITATION });
61
+ }
62
+ if (isolation) onEvent({ kind: "status", text: `${AGY_FILE_ONLY_LIMITATION} Executor: ${AGY_ISOLATION_VERSION}; CLI 1.4.4.` });
63
+ if (opts.agentContainer) onEvent({ kind: "status", text: `Antigravity runs in Docker image ${opts.agentContainer.image}. Team messages and memory are provided at turn boundaries.` });
64
+ if (opts.teamTools) onEvent({ kind: "status", text: "Live MCP collaboration is unavailable in this Antigravity adapter; team messages and memory are provided at turn boundaries." });
65
+ const timeoutMs = typeof opts.timeoutMs === "number" && Number.isFinite(opts.timeoutMs) && opts.timeoutMs > 0 ? opts.timeoutMs : STEP_TIMEOUT_MS;
66
+ const args = [
67
+ "--input-format",
68
+ "stream-json",
69
+ "--output-format",
70
+ "stream-json",
71
+ "--print-timeout",
72
+ `${Math.max(1, Math.ceil(timeoutMs / 6e4))}m`
73
+ ];
74
+ const sandboxed = !native && (!!isolation || !(opts.mode === "write" && opts.trust === "full"));
75
+ if (sandboxed) args.push("--sandbox");
76
+ if (opts.resumeSessionId) args.push("--conversation", opts.resumeSessionId);
77
+ if (opts.model) args.push("--model", opts.model);
78
+ if (opts.effort) args.push("--effort", opts.effort);
79
+ if (opts.jsonSchema) args.push("--json-schema", JSON.stringify(opts.jsonSchema));
80
+ const nativeLog = isolation || nativeScratch ? join(isolation?.paths.scratch ?? nativeScratch, "native-auth.log") : void 0;
81
+ if (isolation) args.push("--agent", "codeflow-isolated", "--disable-slash-commands", "--log-file", nativeLog);
82
+ else {
83
+ if (nativeLog) args.push("--log-file", nativeLog);
84
+ if (native || skipPermissions()) args.push("--dangerously-skip-permissions");
85
+ }
86
+ let sessionId;
87
+ let finalText = "";
88
+ let streamedText = "";
89
+ let resultError;
90
+ let statusKind;
91
+ let sawResult = false;
92
+ let policyDrift = false;
93
+ let managedDiagnostic = "";
94
+ let structured;
95
+ const openTools = /* @__PURE__ */ new Set();
96
+ const unknown = unknownEvents("agy");
97
+ const unknownSteps = /* @__PURE__ */ new Set();
98
+ const proc = startJsonlProcess({
99
+ agentContainer: opts.agentContainer ? { config: opts.agentContainer, mode: opts.mode } : void 0,
100
+ command: isolation?.command ?? "agy",
101
+ args: [...isolation?.args ?? [], ...args],
102
+ input: `${JSON.stringify({ event: "user", message: { content: opts.prompt } })}
103
+ `,
104
+ cwd: isolation?.paths.workspace ?? opts.cwd,
105
+ // Without the sandbox the agent's commands use your git config, but never code-flow's own secrets.
106
+ env: isolation?.env ?? (sandboxed ? sandboxGitEnv() : childEnv()),
107
+ signal: opts.signal,
108
+ timeoutMs: timeoutMs + 3e4,
109
+ idleTimeoutMs: opts.idleTimeoutMs,
110
+ onText: (line) => {
111
+ if (managed) managedDiagnostic = (managedDiagnostic + "\n" + line).slice(-64e3);
112
+ else onEvent({ kind: "status", text: line });
113
+ },
114
+ onJson: (msg) => {
115
+ if (policyDrift) return;
116
+ switch (msg.event) {
117
+ case "init":
118
+ if (msg.conversation_id && !managed) {
119
+ sessionId = msg.conversation_id;
120
+ onEvent({ kind: "session", sessionId: msg.conversation_id });
121
+ }
122
+ break;
123
+ case "step_update": {
124
+ const step = msg.step_update ?? {};
125
+ if (isolation && step.step_type === "tool" && step.tool_name && !managedAgyToolAllowed(step.tool_name, opts.mode)) {
126
+ policyDrift = true;
127
+ proc.kill();
128
+ return;
129
+ }
130
+ if (step.text_delta) {
131
+ streamedText += step.text_delta;
132
+ if (!managed) onEvent({ kind: "text", text: step.text_delta });
133
+ }
134
+ if (!step.text_delta && step.step_type !== "tool" && step.step_type !== "agent_response") {
135
+ const id = `${step.conversation_id ?? ""}:${step.step_index ?? step.step_type}`;
136
+ if (!unknownSteps.has(id)) {
137
+ unknownSteps.add(id);
138
+ unknown.add(`${step.step_type ?? "(no type)"} step`);
139
+ }
140
+ }
141
+ if (step.step_type === "tool" && step.tool_name) {
142
+ const callId = `${step.conversation_id ?? ""}:${step.step_index ?? step.tool_name}`;
143
+ if (step.state === "ACTIVE" && !openTools.has(callId)) {
144
+ openTools.add(callId);
145
+ onEvent({
146
+ kind: "tool_call",
147
+ callId,
148
+ name: step.tool_name,
149
+ input: truncate(stringify(step.tool_info?.parameters ?? ""), 2e3)
150
+ });
151
+ } else if (step.state === "DONE" || step.state === "ERROR") {
152
+ if (!openTools.has(callId)) {
153
+ onEvent({
154
+ kind: "tool_call",
155
+ callId,
156
+ name: step.tool_name,
157
+ input: truncate(stringify(step.tool_info?.parameters ?? ""), 2e3)
158
+ });
159
+ }
160
+ openTools.delete(callId);
161
+ const error2 = step.tool_info?.error?.message;
162
+ onEvent({
163
+ kind: "tool_result",
164
+ callId,
165
+ output: truncate(error2 ?? stringify(step.tool_info?.output ?? step.tool_info?.result ?? "done")),
166
+ isError: step.state === "ERROR"
167
+ });
168
+ }
169
+ }
170
+ break;
171
+ }
172
+ case "result": {
173
+ sawResult = true;
174
+ proc.resultSeen();
175
+ const result = msg.result ?? {};
176
+ finalText = result.response ?? streamedText;
177
+ if (result.conversation_id && !managed) sessionId = result.conversation_id;
178
+ if (result.structured_output !== void 0) structured = result.structured_output;
179
+ if (result.status && result.status !== "SUCCESS") {
180
+ const detail = typeof result.error === "string" ? result.error : result.error?.message;
181
+ resultError = detail ? `${detail} (agy status ${result.status})` : `agy finished with status ${result.status}`;
182
+ statusKind = agyStatusKind(String(result.status), detail, !!opts.resumeSessionId);
183
+ } else if (!finalText.trim() && result.denied_actions?.length) {
184
+ const denied = result.denied_actions.map((d) => d.display_name ?? d.action).join(", ");
185
+ resultError = isolation ? "Isolated Antigravity denied a tool. Assign this task to a worker with the required tools." : `agy stopped after headless mode denied: ${denied}. Allow it in permissions.allow or enable CODEFLOW_AGY_SKIP_PERMISSIONS.`;
186
+ }
187
+ onEvent({
188
+ kind: "usage",
189
+ inputTokens: result.usage?.input_tokens,
190
+ outputTokens: result.usage?.output_tokens,
191
+ cacheReadTokens: result.usage?.cached_input_tokens ?? result.usage?.cache_read_input_tokens
192
+ });
193
+ break;
194
+ }
195
+ case "user":
196
+ break;
197
+ default:
198
+ unknown.add(msg.event ?? msg.type);
199
+ }
200
+ }
201
+ });
202
+ const outcome = await proc.outcome;
203
+ const authObservation = nativeLog ? await inspectAgyAuthLog(nativeLog) : void 0;
204
+ if (managed && (authObservation?.credentialFailure || authObservation?.interactiveAuthObserved || agyCredentialFailure(outcome.stderr + "\n" + managedDiagnostic))) {
205
+ resultError = "Native authentication could not be maintained in the recorded execution mode";
206
+ statusKind = "auth";
207
+ }
208
+ const drift = unknown.report();
209
+ if (drift && !managed) onEvent({ kind: "status", text: drift });
210
+ if (policyDrift) {
211
+ const error2 = "Antigravity reported a tool outside its verified file-only policy. The worker was stopped; runtime compatibility must be reverified.";
212
+ onEvent({ kind: "error", message: error2 });
213
+ return { ok: false, finalText: "", errorKind: "cli_incompatible", error: error2 };
214
+ }
215
+ if (sawResult && !resultError && !outcome.aborted) {
216
+ if (managed && finalText) onEvent({ kind: "text", text: finalText });
217
+ return { ok: true, finalText, sessionId, structured };
218
+ }
219
+ const stopped = processErrorKind(outcome);
220
+ if (!sawResult && outcome.exitCode === 0 && !stopped) {
221
+ resultError = "agy exited without a result event. Some agy versions print nothing when stdout is a pipe; update agy, and make sure you have logged in once with an interactive `agy` session.";
222
+ }
223
+ let error = resultError ?? describeFailure("agy", outcome);
224
+ const own = resultError ?? cliErrorLine(outcome.stderr + (managed ? "\n" + managedDiagnostic : ""));
225
+ const authKind = managed ? managedAgyAuthKind(sawResult ? resultError ?? "" : outcome.stderr + "\n" + managedDiagnostic) ?? (statusKind === "auth" ? "auth" : void 0) : void 0;
226
+ const errorKind = stopped === "cancelled" ? stopped : authKind ?? stopped ?? statusKind ?? classifyError(own);
227
+ if (managed) error = native ? `Unrestricted Antigravity failed (${errorKind}). Check the existing login in its normal session, then resume. Code Flow never starts sign-in or changes credentials; native diagnostics are withheld.` : managedAgyFailure(errorKind);
228
+ const resetsAt = errorKind === "usage_limit" ? resetFromText(own) : void 0;
229
+ onEvent({ kind: "error", message: error });
230
+ return {
231
+ ok: false,
232
+ finalText: managed ? "" : finalText || streamedText,
233
+ sessionId: errorKind === "session_not_found" ? void 0 : sessionId,
234
+ error,
235
+ errorKind,
236
+ ...resetsAt && { resetsAt }
237
+ };
238
+ } finally {
239
+ await isolation?.cleanup();
240
+ if (nativeScratch) await rm(nativeScratch, { recursive: true, force: true });
241
+ }
242
+ }
243
+ };
244
+ }
245
+ const agyAdapter = createAgyAdapter();
246
+ function managedAgyToolAllowed(name, mode) {
247
+ return ["view_file", "list_dir", "manage_task", ...mode === "write" ? ["write_to_file", "replace_file_content"] : []].includes(name);
248
+ }
249
+ function managedAgyAuthKind(detail) {
250
+ return /authentication (?:failed|timed out)|please (?:sign|log) in|invalid_grant|(?:refresh|access)[ _-]?token.{0,80}(?:expired|revoked|invalid|failed)|(?:failed|unable) to (?:retrieve|refresh).{0,40}token|(?:keyring|keychain).{0,80}(?:locked|denied|unavailable)|interaction (?:is )?not allowed/i.test(detail) || agyCredentialFailure(detail) || classifyError(detail) === "auth" ? "auth" : void 0;
251
+ }
252
+ function managedAgyFailure(kind) {
253
+ if (kind === "auth") return "Antigravity could not use or refresh the existing native login. Check or unlock it in Antigravity's normal interactive session, then resume. Code Flow will start a fresh isolated turn; permissions were not widened.";
254
+ if (kind === "usage_limit" || kind === "rate_limit") return `Isolated Antigravity reached a ${kind === "usage_limit" ? "usage" : "rate"} limit.`;
255
+ return `Isolated Antigravity failed (${kind}). Native diagnostics were withheld because they can contain authentication data. Check the CLI in its normal interactive session before resuming; no permissive fallback was used.`;
256
+ }
257
+ function agyStatusKind(status, detail, resuming) {
258
+ if (/RESOURCE_EXHAUSTED|QUOTA/i.test(status)) {
259
+ const text = detail ?? "";
260
+ if (/\bper (?:minute|second|min\b)|\brate\b/i.test(text)) return "rate_limit";
261
+ return /daily|per day|\bplan\b|usage limit|quota (?:exceeded|reached|exhausted)|exceeded (?:your|the) [\w -]{0,30}quota/i.test(text) ? "usage_limit" : "rate_limit";
262
+ }
263
+ if (/RATE/i.test(status)) return "rate_limit";
264
+ if (/UNAUTHENTICATED|AUTH|LOGIN|SIGN_?IN/i.test(status)) return "auth";
265
+ if (resuming && /NOT_FOUND/i.test(status)) return "session_not_found";
266
+ if (/UNAVAILABLE|INTERNAL|OVERLOAD/i.test(status)) return "transient";
267
+ if (/DEADLINE|TIMEOUT/i.test(status)) return "timeout";
268
+ if (/CANCEL/i.test(status)) return "cancelled";
269
+ return void 0;
270
+ }
271
+ function agyNativeOptionsProblem(opts) {
272
+ const p = opts.permissions;
273
+ if (!p || p.provider !== "agy" || p.implementation !== "agy-native-v1" || p.isolation !== "none" || p.nativeDelegation !== true || p.commandNetwork !== "allowed" || p.externalTools !== "provider-configured" || p.trust !== "full" || opts.trust !== "full" || p.mode !== opts.mode || !["read", "write"].includes(p.mode) || !["managed", "none"].includes(p.delegation) || p.toolApprovals !== false || opts.interactiveApprovals || !Array.isArray(p.required) || p.required.length || !Number.isSafeInteger(p.policyRevision) || p.policyRevision < 1 || opts.agentContainer) return "Antigravity options do not match an explicit unrestricted permission receipt";
274
+ }
275
+ async function discoverNativeAgyModels() {
276
+ const scratch = await mkdtemp(join(tmpdir(), "codeflow-agy-models-"));
277
+ try {
278
+ const log = join(scratch, "native-auth.log");
279
+ const output = await captureOutput("agy", ["--log-file", log, "models"], 45e3);
280
+ const auth = await inspectAgyAuthLog(log);
281
+ if (auth.credentialFailure || auth.interactiveAuthObserved || agyCredentialFailure(output) || managedAgyAuthKind(output)) throw new Error("Native login unavailable");
282
+ const models = output.split("\n").map((line) => line.split(" ")).filter((cols) => cols.length >= 2 && cols[0].trim()).map(([id, label]) => ({ id: id.trim(), label: label.trim() }));
283
+ if (!models.length) throw new Error("No models");
284
+ return { models, efforts: [], allowCustom: false };
285
+ } catch {
286
+ throw new Error("Antigravity model discovery could not verify the existing native login");
287
+ } finally {
288
+ await rm(scratch, { recursive: true, force: true });
289
+ }
290
+ }
291
+ export {
292
+ agyAdapter,
293
+ agyNativeOptionsProblem,
294
+ createAgyAdapter,
295
+ managedAgyAuthKind,
296
+ managedAgyToolAllowed
297
+ };
@@ -0,0 +1,220 @@
1
+ import { discoverModels } from "./model-discovery.js";
2
+ import { managedPermissionProblem } from "./managed-permissions.js";
3
+ import { classifyError, cliErrorLine, resetFromText } from "./errors.js";
4
+ import { commandExists, describeFailure, processErrorKind, startJsonlProcess, stderrTail, stringify, truncate, unknownEvents } from "./process.js";
5
+ import { adapterTeamCapabilities, prepareTeamTools, TEAM_NESTED_DENYLIST, TEAM_TOOL_ALLOWLIST } from "./team-tools.js";
6
+ const READ_TOOLS = [
7
+ "Read",
8
+ "Grep",
9
+ "Glob",
10
+ "Bash(git diff *)",
11
+ "Bash(git log *)",
12
+ "Bash(git show *)",
13
+ "Bash(git status *)",
14
+ "Bash(ls *)"
15
+ ];
16
+ const GIT_READ_DENY = ["Bash(git *--out*)", "Bash(git *--no-index*)"];
17
+ const IGNORED_TYPES = /* @__PURE__ */ new Set(["stream_event", "tool_progress", "tool_use_summary", "auth_status", "keep_alive", "control_request", "control_response", "control_cancel_request"]);
18
+ const IGNORED_BLOCKS = /* @__PURE__ */ new Set(["redacted_thinking"]);
19
+ const DEFAULT_WRITE_TOOLS = [
20
+ ...READ_TOOLS,
21
+ "Bash(git add *)",
22
+ "Bash(npm *)",
23
+ "Bash(npx *)",
24
+ "Bash(node *)",
25
+ "Bash(pnpm *)",
26
+ "Bash(yarn *)",
27
+ "Bash(python3 *)",
28
+ "Bash(pytest *)",
29
+ "Bash(uv *)",
30
+ "Bash(poetry *)",
31
+ "Bash(cargo *)",
32
+ "Bash(go *)",
33
+ "Bash(make *)",
34
+ "Bash(mkdir *)"
35
+ ];
36
+ function writeTools(trust = "standard") {
37
+ if (trust === "safe") return READ_TOOLS;
38
+ if (trust === "trusted") return [...READ_TOOLS, "Bash"];
39
+ const env = process.env.CODEFLOW_CLAUDE_WRITE_TOOLS;
40
+ return env ? env.split(",").map((t) => t.trim()).filter(Boolean) : DEFAULT_WRITE_TOOLS;
41
+ }
42
+ const claudeAdapter = {
43
+ id: "claude",
44
+ discoverModels: (context) => discoverModels("claude", context),
45
+ displayName: "Claude Code",
46
+ binary: "claude",
47
+ available: () => commandExists("claude"),
48
+ // The CLI has no model-listing command; it accepts these aliases (always the latest
49
+ // model of each family) or any full model name.
50
+ async catalog() {
51
+ return {
52
+ models: [
53
+ { id: "fable", label: "Fable (latest)" },
54
+ { id: "opus", label: "Opus (latest)" },
55
+ { id: "sonnet", label: "Sonnet (latest)" },
56
+ { id: "haiku", label: "Haiku (latest)" }
57
+ ],
58
+ efforts: ["low", "medium", "high", "xhigh", "max"],
59
+ allowCustom: true
60
+ };
61
+ },
62
+ async run(opts, onEvent) {
63
+ const permissionProblem = await managedPermissionProblem("claude", opts);
64
+ if (permissionProblem) return permissionProblem;
65
+ const supportsTools = !opts.agentContainer && opts.teamTools && (await adapterTeamCapabilities("claude")).scopedTools === "tested";
66
+ const teamTools = supportsTools ? await prepareTeamTools(opts.teamTools) : void 0;
67
+ if (opts.agentContainer) onEvent({ kind: "status", text: `Claude runs in Docker image ${opts.agentContainer.image}. Live team tools are unavailable in containers; use structured outcomes and next-turn replies.` });
68
+ else if (opts.teamTools && !teamTools) onEvent({ kind: "status", text: "This Claude CLI has no verified per-turn team tools; use structured outcomes and next-turn replies." });
69
+ try {
70
+ const args = ["-p", "--output-format", "stream-json", "--verbose"];
71
+ if (opts.permissions) args.push("--settings", '{"ultracode":false,"disableWorkflows":true,"disableAllHooks":true}');
72
+ if (opts.resumeSessionId) args.push("--resume", opts.resumeSessionId);
73
+ if (opts.model) args.push("--model", opts.model);
74
+ if (opts.effort) args.push("--effort", opts.effort);
75
+ if (opts.jsonSchema) args.push("--json-schema", JSON.stringify(opts.jsonSchema));
76
+ if (teamTools) args.push("--mcp-config", teamTools.claudeConfig, "--strict-mcp-config");
77
+ else if (opts.permissions?.externalTools === "disabled") args.push("--mcp-config", '{"mcpServers":{}}', "--strict-mcp-config");
78
+ if (opts.permissions?.externalTools === "disabled") args.push("--no-chrome");
79
+ const collaborationTools = teamTools ? TEAM_TOOL_ALLOWLIST : [];
80
+ const full = opts.mode === "write" && opts.trust === "full";
81
+ const allowedTools = full ? [] : [...opts.mode === "write" ? writeTools(opts.trust) : READ_TOOLS, ...collaborationTools];
82
+ const limitedShell = !full && !allowedTools.includes("Bash");
83
+ const deniedTools = [...opts.mode === "read" ? ["Edit", "Write", "NotebookEdit"] : [], ...opts.questionProtocol === "structured" || opts.permissions?.nativeDelegation === false ? TEAM_NESTED_DENYLIST : [], ...opts.permissions?.externalTools === "disabled" ? ["WebSearch", "WebFetch"] : []];
84
+ const denied = [deniedTools.join(","), limitedShell ? GIT_READ_DENY.join(",") : ""].filter(Boolean);
85
+ if (denied.length) args.push("--disallowedTools", ...denied);
86
+ if (full) args.push("--permission-mode", "bypassPermissions");
87
+ else args.push("--permission-mode", opts.mode === "write" ? "acceptEdits" : "default", "--allowedTools", allowedTools.join(","));
88
+ let sessionId;
89
+ let finalText = "";
90
+ let lastAssistantText = "";
91
+ let resultError;
92
+ let sawResult = false;
93
+ let structured;
94
+ let rejected;
95
+ const unknown = unknownEvents("claude");
96
+ const proc = startJsonlProcess({
97
+ agentContainer: opts.agentContainer ? { config: opts.agentContainer, mode: opts.mode } : void 0,
98
+ command: "claude",
99
+ args,
100
+ input: opts.prompt,
101
+ cwd: opts.cwd,
102
+ signal: opts.signal,
103
+ timeoutMs: opts.timeoutMs,
104
+ idleTimeoutMs: opts.idleTimeoutMs,
105
+ onText: (line) => onEvent({ kind: "status", text: line }),
106
+ onJson: (msg) => {
107
+ switch (msg.type) {
108
+ case "system":
109
+ if (msg.subtype === "init" && msg.session_id) {
110
+ sessionId = msg.session_id;
111
+ onEvent({ kind: "session", sessionId: msg.session_id });
112
+ }
113
+ break;
114
+ case "assistant":
115
+ for (const block of msg.message?.content ?? []) {
116
+ if (block.type === "text" && block.text) {
117
+ lastAssistantText = block.text;
118
+ onEvent({ kind: "text", text: block.text });
119
+ } else if (block.type === "thinking" && block.thinking) {
120
+ onEvent({ kind: "thinking", text: block.thinking });
121
+ } else if (block.type === "tool_use") {
122
+ onEvent({
123
+ kind: "tool_call",
124
+ callId: block.id,
125
+ name: block.name,
126
+ input: truncate(stringify(block.input), 2e3)
127
+ });
128
+ } else if (!["text", "thinking"].includes(block.type) && !IGNORED_BLOCKS.has(block.type)) {
129
+ unknown.add(`${block.type} block`);
130
+ }
131
+ }
132
+ break;
133
+ case "user":
134
+ for (const block of msg.message?.content ?? []) {
135
+ if (block.type !== "tool_result") continue;
136
+ const output = Array.isArray(block.content) ? block.content.map((c) => c.type === "text" ? c.text : `[${c.type}]`).join("\n") : stringify(block.content ?? "");
137
+ onEvent({
138
+ kind: "tool_result",
139
+ callId: block.tool_use_id,
140
+ output: truncate(output),
141
+ isError: Boolean(block.is_error)
142
+ });
143
+ }
144
+ break;
145
+ case "rate_limit_event": {
146
+ const info = msg.rate_limit_info ?? {};
147
+ const windows = {};
148
+ for (const [name, w] of Object.entries(info.unifiedWindows ?? {})) {
149
+ windows[name] = { utilization: w?.utilization, resetsAt: w?.resetsAt ? w.resetsAt * 1e3 : void 0 };
150
+ }
151
+ if (!Object.keys(windows).length && (info.utilization !== void 0 || info.resetsAt)) {
152
+ windows[info.rateLimitType ?? "limit"] = { utilization: info.utilization, resetsAt: info.resetsAt ? info.resetsAt * 1e3 : void 0 };
153
+ }
154
+ onEvent({ kind: "quota", status: info.status ?? "unknown", windows });
155
+ if (info.status && info.status !== "allowed") onEvent({ kind: "status", text: `Claude rate limit: ${info.status}` });
156
+ if (info.status === "rejected") {
157
+ const full2 = Object.values(windows).filter((w) => (w.utilization ?? 0) >= 1 && w.resetsAt).map((w) => w.resetsAt);
158
+ rejected = { resetsAt: info.resetsAt ? info.resetsAt * 1e3 : full2.length ? Math.max(...full2) : void 0 };
159
+ }
160
+ break;
161
+ }
162
+ case "result":
163
+ sawResult = true;
164
+ proc.resultSeen();
165
+ finalText = typeof msg.result === "string" ? msg.result : lastAssistantText;
166
+ if (msg.session_id) sessionId = msg.session_id;
167
+ if (msg.structured_output !== void 0) structured = msg.structured_output;
168
+ if (msg.is_error || /^error/.test(msg.subtype ?? "")) resultError = resultErrorText(msg);
169
+ onEvent({
170
+ kind: "usage",
171
+ // Writing to the prompt cache is billed as input; reading from it is counted apart.
172
+ inputTokens: (msg.usage?.input_tokens ?? 0) + (msg.usage?.cache_creation_input_tokens ?? 0),
173
+ outputTokens: msg.usage?.output_tokens,
174
+ cacheReadTokens: msg.usage?.cache_read_input_tokens,
175
+ costUsd: msg.total_cost_usd
176
+ });
177
+ if (Array.isArray(msg.permission_denials) && msg.permission_denials.length) {
178
+ const names = msg.permission_denials.map((d) => d.tool_name).join(", ");
179
+ onEvent({ kind: "status", text: `Denied in headless mode: ${names}` });
180
+ }
181
+ break;
182
+ default:
183
+ if (!IGNORED_TYPES.has(msg.type)) unknown.add(msg.type);
184
+ }
185
+ }
186
+ });
187
+ const outcome = await proc.outcome;
188
+ const drift = unknown.report();
189
+ if (drift) onEvent({ kind: "status", text: drift });
190
+ if (sawResult && !resultError && !outcome.aborted) return { ok: true, finalText, sessionId, structured };
191
+ const tail = stderrTail(outcome);
192
+ const error = resultError ? `${resultError}${tail && !resultError.includes(tail) ? `
193
+ ${tail}` : ""}` : !sawResult && outcome.exitCode === 0 ? `claude exited without a result${tail ? `: ${tail}` : ""}` : describeFailure("claude", outcome);
194
+ const own = resultError ?? cliErrorLine(outcome.stderr);
195
+ let errorKind = processErrorKind(outcome) ?? classifyError(own);
196
+ if (rejected && (errorKind === "other" || errorKind === "rate_limit")) errorKind = "usage_limit";
197
+ const resetsAt = errorKind === "usage_limit" ? rejected?.resetsAt ?? resetFromText(own) : void 0;
198
+ onEvent({ kind: "error", message: error });
199
+ return {
200
+ ok: false,
201
+ finalText: finalText || lastAssistantText,
202
+ sessionId: errorKind === "session_not_found" ? void 0 : sessionId,
203
+ error,
204
+ errorKind,
205
+ ...resetsAt && { resetsAt }
206
+ };
207
+ } finally {
208
+ await teamTools?.cleanup();
209
+ }
210
+ }
211
+ };
212
+ function resultErrorText(msg) {
213
+ if (msg.is_error && typeof msg.result === "string" && msg.result.trim()) return msg.result.trim();
214
+ const errors = Array.isArray(msg.errors) ? msg.errors.filter((e) => typeof e === "string" && e).join("; ") : "";
215
+ const what = msg.subtype === "error_max_turns" ? "Claude stopped at its turn limit" : msg.subtype === "error_max_budget_usd" ? "Claude stopped at its budget limit" : msg.subtype === "error_during_execution" ? "Claude stopped with an error during execution" : `Claude reported an error${msg.subtype && msg.subtype !== "success" ? ` (${msg.subtype})` : ""}`;
216
+ return errors ? `${what}: ${errors}` : what;
217
+ }
218
+ export {
219
+ claudeAdapter
220
+ };