@nanonets/graft 0.13.0 → 0.16.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 (308) hide show
  1. package/README.md +26 -10
  2. package/dist/ai/crux.d.ts +14 -1
  3. package/dist/ai/crux.d.ts.map +1 -1
  4. package/dist/ai/crux.js +39 -51
  5. package/dist/ai/crux.js.map +1 -1
  6. package/dist/ai/failure.d.ts +13 -2
  7. package/dist/ai/failure.d.ts.map +1 -1
  8. package/dist/ai/failure.js +16 -4
  9. package/dist/ai/failure.js.map +1 -1
  10. package/dist/ai/llm/factory.d.ts +10 -1
  11. package/dist/ai/llm/factory.d.ts.map +1 -1
  12. package/dist/ai/llm/factory.js +16 -0
  13. package/dist/ai/llm/factory.js.map +1 -1
  14. package/dist/ai/llm/litellm.d.ts +34 -0
  15. package/dist/ai/llm/litellm.d.ts.map +1 -0
  16. package/dist/ai/llm/litellm.js +45 -0
  17. package/dist/ai/llm/litellm.js.map +1 -0
  18. package/dist/ai/llm/openai.d.ts.map +1 -1
  19. package/dist/ai/llm/openai.js +66 -7
  20. package/dist/ai/llm/openai.js.map +1 -1
  21. package/dist/ai/llm/orcarouter.d.ts +34 -0
  22. package/dist/ai/llm/orcarouter.d.ts.map +1 -0
  23. package/dist/ai/llm/orcarouter.js +45 -0
  24. package/dist/ai/llm/orcarouter.js.map +1 -0
  25. package/dist/ai/llm/recover-tool.d.ts +19 -0
  26. package/dist/ai/llm/recover-tool.d.ts.map +1 -0
  27. package/dist/ai/llm/recover-tool.js +109 -0
  28. package/dist/ai/llm/recover-tool.js.map +1 -0
  29. package/dist/ai/providers.d.ts.map +1 -1
  30. package/dist/ai/providers.js +15 -3
  31. package/dist/ai/providers.js.map +1 -1
  32. package/dist/ai/synthesize.d.ts.map +1 -1
  33. package/dist/ai/synthesize.js +19 -5
  34. package/dist/ai/synthesize.js.map +1 -1
  35. package/dist/app/checkout.d.ts +28 -0
  36. package/dist/app/checkout.d.ts.map +1 -0
  37. package/dist/app/checkout.js +100 -0
  38. package/dist/app/checkout.js.map +1 -0
  39. package/dist/app/events.d.ts +37 -0
  40. package/dist/app/events.d.ts.map +1 -0
  41. package/dist/app/events.js +59 -0
  42. package/dist/app/events.js.map +1 -0
  43. package/dist/app/identity.d.ts +54 -0
  44. package/dist/app/identity.d.ts.map +1 -0
  45. package/dist/app/identity.js +96 -0
  46. package/dist/app/identity.js.map +1 -0
  47. package/dist/app/main.d.ts +2 -0
  48. package/dist/app/main.d.ts.map +1 -0
  49. package/dist/app/main.js +56 -0
  50. package/dist/app/main.js.map +1 -0
  51. package/dist/app/pages.d.ts +39 -0
  52. package/dist/app/pages.d.ts.map +1 -0
  53. package/dist/app/pages.js +86 -0
  54. package/dist/app/pages.js.map +1 -0
  55. package/dist/app/queue.d.ts +40 -0
  56. package/dist/app/queue.d.ts.map +1 -0
  57. package/dist/app/queue.js +68 -0
  58. package/dist/app/queue.js.map +1 -0
  59. package/dist/app/review.d.ts +23 -0
  60. package/dist/app/review.d.ts.map +1 -0
  61. package/dist/app/review.js +139 -0
  62. package/dist/app/review.js.map +1 -0
  63. package/dist/app/server.d.ts +40 -0
  64. package/dist/app/server.d.ts.map +1 -0
  65. package/dist/app/server.js +117 -0
  66. package/dist/app/server.js.map +1 -0
  67. package/dist/ask/ask.d.ts +35 -0
  68. package/dist/ask/ask.d.ts.map +1 -1
  69. package/dist/ask/ask.js +427 -63
  70. package/dist/ask/ask.js.map +1 -1
  71. package/dist/ask/file-rank.d.ts +72 -0
  72. package/dist/ask/file-rank.d.ts.map +1 -0
  73. package/dist/ask/file-rank.js +160 -0
  74. package/dist/ask/file-rank.js.map +1 -0
  75. package/dist/ask/file-selection.d.ts +4 -0
  76. package/dist/ask/file-selection.d.ts.map +1 -1
  77. package/dist/ask/file-selection.js +25 -0
  78. package/dist/ask/file-selection.js.map +1 -1
  79. package/dist/ask/fuse.d.ts +16 -0
  80. package/dist/ask/fuse.d.ts.map +1 -1
  81. package/dist/ask/fuse.js +21 -4
  82. package/dist/ask/fuse.js.map +1 -1
  83. package/dist/ask/graphrank.d.ts +18 -0
  84. package/dist/ask/graphrank.d.ts.map +1 -1
  85. package/dist/ask/graphrank.js +65 -19
  86. package/dist/ask/graphrank.js.map +1 -1
  87. package/dist/blast/blast-cli.d.ts +5 -0
  88. package/dist/blast/blast-cli.d.ts.map +1 -1
  89. package/dist/blast/blast-cli.js +21 -30
  90. package/dist/blast/blast-cli.js.map +1 -1
  91. package/dist/blast/blast.d.ts +9 -0
  92. package/dist/blast/blast.d.ts.map +1 -1
  93. package/dist/blast/blast.js.map +1 -1
  94. package/dist/blast/name.d.ts +13 -0
  95. package/dist/blast/name.d.ts.map +1 -1
  96. package/dist/blast/name.js +36 -0
  97. package/dist/blast/name.js.map +1 -1
  98. package/dist/blast/owners.d.ts +85 -0
  99. package/dist/blast/owners.d.ts.map +1 -0
  100. package/dist/blast/owners.js +272 -0
  101. package/dist/blast/owners.js.map +1 -0
  102. package/dist/blast/render.d.ts.map +1 -1
  103. package/dist/blast/render.js +105 -0
  104. package/dist/blast/render.js.map +1 -1
  105. package/dist/blast/viz.d.ts.map +1 -1
  106. package/dist/blast/viz.js +10 -0
  107. package/dist/blast/viz.js.map +1 -1
  108. package/dist/claude/format.js +1 -1
  109. package/dist/claude/format.js.map +1 -1
  110. package/dist/claude/hooks.d.ts.map +1 -1
  111. package/dist/claude/hooks.js +132 -22
  112. package/dist/claude/hooks.js.map +1 -1
  113. package/dist/claude/init.d.ts +1 -0
  114. package/dist/claude/init.d.ts.map +1 -1
  115. package/dist/claude/init.js +1 -1
  116. package/dist/claude/init.js.map +1 -1
  117. package/dist/claude/session-metrics.d.ts +63 -0
  118. package/dist/claude/session-metrics.d.ts.map +1 -0
  119. package/dist/claude/session-metrics.js +181 -0
  120. package/dist/claude/session-metrics.js.map +1 -0
  121. package/dist/claude/settings-merge.d.ts +18 -1
  122. package/dist/claude/settings-merge.d.ts.map +1 -1
  123. package/dist/claude/settings-merge.js +70 -27
  124. package/dist/claude/settings-merge.js.map +1 -1
  125. package/dist/claude/state.d.ts +25 -0
  126. package/dist/claude/state.d.ts.map +1 -1
  127. package/dist/claude/state.js +14 -1
  128. package/dist/claude/state.js.map +1 -1
  129. package/dist/claude/statusline.d.ts +5 -3
  130. package/dist/claude/statusline.d.ts.map +1 -1
  131. package/dist/claude/statusline.js +6 -4
  132. package/dist/claude/statusline.js.map +1 -1
  133. package/dist/claude/tally.d.ts +23 -0
  134. package/dist/claude/tally.d.ts.map +1 -0
  135. package/dist/claude/tally.js +138 -0
  136. package/dist/claude/tally.js.map +1 -0
  137. package/dist/cli.js +145 -4
  138. package/dist/cli.js.map +1 -1
  139. package/dist/context/build.d.ts +11 -0
  140. package/dist/context/build.d.ts.map +1 -1
  141. package/dist/context/build.js +49 -9
  142. package/dist/context/build.js.map +1 -1
  143. package/dist/context/check.d.ts.map +1 -1
  144. package/dist/context/check.js +5 -12
  145. package/dist/context/check.js.map +1 -1
  146. package/dist/context/node-file.d.ts +2 -1
  147. package/dist/context/node-file.d.ts.map +1 -1
  148. package/dist/context/node-file.js +70 -3
  149. package/dist/context/node-file.js.map +1 -1
  150. package/dist/context/savings.d.ts +8 -0
  151. package/dist/context/savings.d.ts.map +1 -1
  152. package/dist/context/savings.js +14 -0
  153. package/dist/context/savings.js.map +1 -1
  154. package/dist/engine.d.ts +4 -0
  155. package/dist/engine.d.ts.map +1 -1
  156. package/dist/engine.js +2 -0
  157. package/dist/engine.js.map +1 -1
  158. package/dist/graph/bindings.d.ts +6 -5
  159. package/dist/graph/bindings.d.ts.map +1 -1
  160. package/dist/graph/bindings.js +117 -5
  161. package/dist/graph/bindings.js.map +1 -1
  162. package/dist/graph/build.d.ts +4 -0
  163. package/dist/graph/build.d.ts.map +1 -1
  164. package/dist/graph/build.js +7 -4
  165. package/dist/graph/build.js.map +1 -1
  166. package/dist/graph/cards.d.ts +4 -3
  167. package/dist/graph/cards.d.ts.map +1 -1
  168. package/dist/graph/cards.js +34 -6
  169. package/dist/graph/cards.js.map +1 -1
  170. package/dist/graph/check.d.ts.map +1 -1
  171. package/dist/graph/check.js +36 -6
  172. package/dist/graph/check.js.map +1 -1
  173. package/dist/graph/enrich.d.ts +4 -4
  174. package/dist/graph/enrich.d.ts.map +1 -1
  175. package/dist/graph/enrich.js +32 -6
  176. package/dist/graph/enrich.js.map +1 -1
  177. package/dist/graph/extract.d.ts +9 -2
  178. package/dist/graph/extract.d.ts.map +1 -1
  179. package/dist/graph/extract.js +356 -12
  180. package/dist/graph/extract.js.map +1 -1
  181. package/dist/graph/fingerprint.d.ts +6 -1
  182. package/dist/graph/fingerprint.d.ts.map +1 -1
  183. package/dist/graph/fingerprint.js +7 -3
  184. package/dist/graph/fingerprint.js.map +1 -1
  185. package/dist/graph/generic.d.ts +10 -0
  186. package/dist/graph/generic.d.ts.map +1 -1
  187. package/dist/graph/generic.js +20 -3
  188. package/dist/graph/generic.js.map +1 -1
  189. package/dist/graph/invariants.d.ts +3 -2
  190. package/dist/graph/invariants.d.ts.map +1 -1
  191. package/dist/graph/invariants.js +6 -3
  192. package/dist/graph/invariants.js.map +1 -1
  193. package/dist/graph/refresh.d.ts.map +1 -1
  194. package/dist/graph/refresh.js +6 -2
  195. package/dist/graph/refresh.js.map +1 -1
  196. package/dist/graph/resolve.d.ts +1 -1
  197. package/dist/graph/resolve.d.ts.map +1 -1
  198. package/dist/graph/resolve.js +106 -5
  199. package/dist/graph/resolve.js.map +1 -1
  200. package/dist/graph/scopes.d.ts.map +1 -1
  201. package/dist/graph/scopes.js +2 -1
  202. package/dist/graph/scopes.js.map +1 -1
  203. package/dist/graph/source-files.d.ts +7 -2
  204. package/dist/graph/source-files.d.ts.map +1 -1
  205. package/dist/graph/source-files.js +19 -6
  206. package/dist/graph/source-files.js.map +1 -1
  207. package/dist/graph/workspace-cli.d.ts +2 -0
  208. package/dist/graph/workspace-cli.d.ts.map +1 -1
  209. package/dist/graph/workspace-cli.js +3 -0
  210. package/dist/graph/workspace-cli.js.map +1 -1
  211. package/dist/graph/workspace.d.ts +2 -0
  212. package/dist/graph/workspace.d.ts.map +1 -1
  213. package/dist/graph/workspace.js +173 -6
  214. package/dist/graph/workspace.js.map +1 -1
  215. package/dist/hosts/antigravity.d.ts +2 -2
  216. package/dist/hosts/antigravity.d.ts.map +1 -1
  217. package/dist/hosts/codex-hooks.d.ts +2 -6
  218. package/dist/hosts/codex-hooks.d.ts.map +1 -1
  219. package/dist/hosts/codex-hooks.js +7 -30
  220. package/dist/hosts/codex-hooks.js.map +1 -1
  221. package/dist/hosts/config-write.d.ts +36 -0
  222. package/dist/hosts/config-write.d.ts.map +1 -0
  223. package/dist/hosts/config-write.js +63 -0
  224. package/dist/hosts/config-write.js.map +1 -0
  225. package/dist/hosts/cursor-hooks.d.ts +18 -0
  226. package/dist/hosts/cursor-hooks.d.ts.map +1 -0
  227. package/dist/hosts/cursor-hooks.js +100 -0
  228. package/dist/hosts/cursor-hooks.js.map +1 -0
  229. package/dist/hosts/init.d.ts +2 -2
  230. package/dist/hosts/init.d.ts.map +1 -1
  231. package/dist/hosts/init.js +8 -2
  232. package/dist/hosts/init.js.map +1 -1
  233. package/dist/hosts/mcp-config.d.ts +15 -5
  234. package/dist/hosts/mcp-config.d.ts.map +1 -1
  235. package/dist/hosts/mcp-config.js +51 -15
  236. package/dist/hosts/mcp-config.js.map +1 -1
  237. package/dist/hosts/plan.d.ts.map +1 -1
  238. package/dist/hosts/plan.js +2 -0
  239. package/dist/hosts/plan.js.map +1 -1
  240. package/dist/hosts/retract.d.ts +47 -0
  241. package/dist/hosts/retract.d.ts.map +1 -0
  242. package/dist/hosts/retract.js +473 -0
  243. package/dist/hosts/retract.js.map +1 -0
  244. package/dist/index.d.ts +2 -0
  245. package/dist/index.d.ts.map +1 -1
  246. package/dist/index.js +2 -0
  247. package/dist/index.js.map +1 -1
  248. package/dist/ingest/fs.d.ts +39 -5
  249. package/dist/ingest/fs.d.ts.map +1 -1
  250. package/dist/ingest/fs.js +104 -11
  251. package/dist/ingest/fs.js.map +1 -1
  252. package/dist/mcp/tool-names.d.ts +20 -0
  253. package/dist/mcp/tool-names.d.ts.map +1 -0
  254. package/dist/mcp/tool-names.js +36 -0
  255. package/dist/mcp/tool-names.js.map +1 -0
  256. package/dist/mcp/tools.d.ts +11 -2
  257. package/dist/mcp/tools.d.ts.map +1 -1
  258. package/dist/mcp/tools.js +9 -21
  259. package/dist/mcp/tools.js.map +1 -1
  260. package/dist/telemetry/contract.d.ts.map +1 -1
  261. package/dist/telemetry/contract.js +17 -3
  262. package/dist/telemetry/contract.js.map +1 -1
  263. package/dist/telemetry/flush.d.ts.map +1 -1
  264. package/dist/telemetry/flush.js +1 -0
  265. package/dist/telemetry/flush.js.map +1 -1
  266. package/dist/telemetry/identity.d.ts +7 -0
  267. package/dist/telemetry/identity.d.ts.map +1 -1
  268. package/dist/telemetry/identity.js.map +1 -1
  269. package/dist/telemetry/index.d.ts +2 -2
  270. package/dist/telemetry/index.d.ts.map +1 -1
  271. package/dist/telemetry/index.js +2 -2
  272. package/dist/telemetry/index.js.map +1 -1
  273. package/dist/telemetry/sessions.d.ts +19 -2
  274. package/dist/telemetry/sessions.d.ts.map +1 -1
  275. package/dist/telemetry/sessions.js +57 -34
  276. package/dist/telemetry/sessions.js.map +1 -1
  277. package/dist/telemetry/track.d.ts +22 -3
  278. package/dist/telemetry/track.d.ts.map +1 -1
  279. package/dist/telemetry/track.js +34 -5
  280. package/dist/telemetry/track.js.map +1 -1
  281. package/dist/upkeep-run.js +1 -1
  282. package/dist/upkeep-run.js.map +1 -1
  283. package/dist/upkeep.d.ts +7 -4
  284. package/dist/upkeep.d.ts.map +1 -1
  285. package/dist/upkeep.js +2 -1
  286. package/dist/upkeep.js.map +1 -1
  287. package/dist/util/state.d.ts +12 -2
  288. package/dist/util/state.d.ts.map +1 -1
  289. package/dist/util/state.js +4 -0
  290. package/dist/util/state.js.map +1 -1
  291. package/dist/viewer/app.js +2 -1
  292. package/dist/viewer/style.css +14 -0
  293. package/dist/viz/assemble.d.ts +17 -0
  294. package/dist/viz/assemble.d.ts.map +1 -1
  295. package/dist/viz/assemble.js.map +1 -1
  296. package/package.json +12 -4
  297. package/scripts/graph-quality.mjs +3 -3
  298. package/scripts/postinstall.mjs +42 -3
  299. package/scripts/run-tests.mjs +14 -0
  300. package/scripts/tally-audit.mjs +140 -0
  301. package/dist/ai/llm/claude-cli.d.ts +0 -60
  302. package/dist/ai/llm/claude-cli.d.ts.map +0 -1
  303. package/dist/ai/llm/claude-cli.js +0 -417
  304. package/dist/ai/llm/claude-cli.js.map +0 -1
  305. package/dist/util/num.d.ts +0 -3
  306. package/dist/util/num.d.ts.map +0 -1
  307. package/dist/util/num.js +0 -20
  308. package/dist/util/num.js.map +0 -1
@@ -1,417 +0,0 @@
1
- /**
2
- * Subscription transport: drives the locally installed `claude` CLI in headless
3
- * mode instead of calling an HTTP API with a key.
4
- *
5
- * `--deep` was gated on GRAFT_API_KEY, so a developer already paying for a Claude
6
- * subscription still had to buy separate API credits to get concept nodes and
7
- * per-symbol summaries. Claude Code's headless mode (`claude -p`) authenticates
8
- * through the same OAuth session as the interactive CLI, so shelling out to it
9
- * turns that existing subscription into a usable transport — no key anywhere.
10
- *
11
- * The CLI is a coding AGENT, not a completions endpoint, so this adapter narrows
12
- * it back down to one. Every flag below is load-bearing:
13
- * - `--tools ""` removes every built-in tool, so a turn is prompt → text and the
14
- * model physically cannot touch the filesystem while summarizing.
15
- * - `--setting-sources ""`, `--strict-mcp-config` and `--disable-slash-commands`
16
- * keep the user's own hooks, MCP servers and skills out of the run.
17
- * - `--system-prompt` REPLACES Claude Code's agent system prompt. That is also
18
- * what keeps CLAUDE.md out: a personal "always answer in Portuguese" memory
19
- * would otherwise silently rewrite every summary written into the graph.
20
- * - `--no-session-persistence` stops thousands of one-shot summaries from being
21
- * recorded as resumable sessions on disk.
22
- *
23
- * Two things the HTTP adapters get for free are unavailable here:
24
- * - Structured output. There is no `tool_choice`, so {@link ChatRequest.responseFormat}
25
- * is emulated: the schema is stated in the prompt and the reply is parsed back
26
- * into a synthetic {@link ToolCall}, with one corrective retry. Callers
27
- * (synthesize, crux) see the same shape they get from Anthropic or OpenAI.
28
- * - `temperature` and `maxTokens`. No flag exposes either; both are dropped.
29
- * graft only ever asks for temperature 0, and the drift that costs is small
30
- * next to not needing a key at all.
31
- *
32
- * The prompt travels over STDIN, never argv — a 24k-char file summary would blow
33
- * the 32767-char Windows command-line limit — which also keeps every argument
34
- * short and quote-free, so the cmd.exe shim path below stays safe.
35
- */
36
- import { spawn } from "node:child_process";
37
- import { existsSync } from "node:fs";
38
- import { tmpdir } from "node:os";
39
- import { delimiter, join } from "node:path";
40
- const PROVIDER = "claude-cli";
41
- const JSON_TOOL = "emit_json";
42
- const DEFAULT_TIMEOUT_MS = 300_000;
43
- /**
44
- * Replaces Claude Code's agent system prompt. Deliberately short and quote-free:
45
- * the caller's real system prompt is far too big (and too quote-heavy) to be safe
46
- * as an argv entry, so it rides in the stdin envelope instead.
47
- */
48
- const HARNESS_SYSTEM_PROMPT = "You are a precise documentation and analysis engine, not a conversational assistant. " +
49
- "Follow the INSTRUCTIONS block exactly and answer only about the INPUT block. " +
50
- "Emit the requested artifact and nothing else: no preamble, no sign-off, no markdown fences.";
51
- export class ClaudeCliChatModel {
52
- label;
53
- model;
54
- runner;
55
- timeoutMs;
56
- maxBudgetUsd;
57
- constructor(opts) {
58
- this.model = opts.model;
59
- this.label = opts.label ?? `${PROVIDER}:${opts.model}`;
60
- this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
61
- this.maxBudgetUsd = opts.maxBudgetUsd;
62
- this.runner = opts.run ?? defaultRunner(opts.bin);
63
- }
64
- async create(req) {
65
- const fmt = req.responseFormat ?? { kind: "text" };
66
- const schema = schemaFor(req, fmt);
67
- const prompt = buildPrompt(req.messages, schema);
68
- let env = await this.invoke(prompt);
69
- let text = (env.result ?? "").trim();
70
- // Structured output is prompt-enforced, not wire-enforced, so a reply can come
71
- // back with prose around the JSON. Retry ONCE, quoting the bad reply back — far
72
- // cheaper than failing a 5000-file build on one malformed response.
73
- let parsed;
74
- if (fmt.kind !== "text") {
75
- parsed = extractJson(text);
76
- if (parsed === undefined) {
77
- env = await this.invoke(retryPrompt(prompt, text));
78
- text = (env.result ?? "").trim();
79
- parsed = extractJson(text);
80
- }
81
- if (parsed === undefined) {
82
- throw new Error(`claude CLI did not return parseable JSON for ${fmt.kind === "tool" ? fmt.name : "json"} output. ` +
83
- `Got: ${text.slice(0, 200)}${text.length > 200 ? "…" : ""}`);
84
- }
85
- }
86
- const toolCalls = [];
87
- if (fmt.kind === "tool") {
88
- toolCalls.push({ id: `${PROVIDER}_1`, name: fmt.name, args: parsed });
89
- text = "";
90
- }
91
- else if (fmt.kind === "json") {
92
- text = JSON.stringify(parsed);
93
- }
94
- return {
95
- text,
96
- toolCalls,
97
- usage: normalizeUsage(env.usage),
98
- stopReason: env.stop_reason ?? null,
99
- assistant: {
100
- role: "assistant",
101
- content: text,
102
- toolCalls: toolCalls.length ? toolCalls : undefined,
103
- },
104
- };
105
- }
106
- /**
107
- * Transport-level retry. A `--deep` build is thousands of sequential calls over
108
- * hours, so a single blip — an overloaded upstream, a dropped connection, one
109
- * slow file hitting the wall clock — would otherwise silently cost that file its
110
- * summary. Only failures classified transient are retried; a bad login or an
111
- * exhausted quota fails immediately, because sleeping on those just turns a
112
- * clear error into a slow one.
113
- */
114
- async invoke(prompt) {
115
- let lastErr;
116
- for (let attempt = 0; attempt < TRANSIENT_ATTEMPTS; attempt++) {
117
- try {
118
- return await this.invokeOnce(prompt);
119
- }
120
- catch (err) {
121
- lastErr = err;
122
- const msg = err instanceof Error ? err.message : String(err);
123
- if (attempt === TRANSIENT_ATTEMPTS - 1 || !isTransient(msg))
124
- throw err;
125
- await sleep(BACKOFF_MS[attempt]);
126
- }
127
- }
128
- throw lastErr;
129
- }
130
- async invokeOnce(prompt) {
131
- const args = [
132
- "-p",
133
- "--output-format",
134
- "json",
135
- "--model",
136
- this.model,
137
- "--tools",
138
- "", // no filesystem, no network, no shell — this is a completions call
139
- "--system-prompt",
140
- HARNESS_SYSTEM_PROMPT,
141
- "--setting-sources",
142
- "", // no user/project settings ⇒ no hooks, no stray permissions
143
- "--strict-mcp-config",
144
- "--disable-slash-commands",
145
- "--no-session-persistence",
146
- ];
147
- if (this.maxBudgetUsd !== undefined)
148
- args.push("--max-budget-usd", String(this.maxBudgetUsd));
149
- const res = await this.runner(args, prompt, this.timeoutMs);
150
- if (res.code !== 0) {
151
- throw new Error(`claude CLI exited with code ${res.code ?? "null"}: ${(res.stderr || res.stdout).trim().slice(0, 400)}`);
152
- }
153
- const env = parseEnvelope(res.stdout);
154
- if (!env) {
155
- throw new Error(`claude CLI returned no JSON envelope: ${res.stdout.trim().slice(0, 200)}`);
156
- }
157
- if (env.is_error) {
158
- throw new Error(`claude CLI reported an error: ${(env.result ?? env.subtype ?? "unknown").slice(0, 400)}`);
159
- }
160
- return env;
161
- }
162
- }
163
- // --- transient-failure policy ------------------------------------------------
164
- const TRANSIENT_ATTEMPTS = 3;
165
- const BACKOFF_MS = [1_000, 5_000];
166
- /**
167
- * Retry only what a retry can fix. Quota exhaustion and a missing/expired login
168
- * are deliberately absent: both persist for far longer than any backoff here, and
169
- * the user needs to see them now rather than after three sleeps per file.
170
- */
171
- const TRANSIENT = /\b(overloaded|rate.?limit|429|50[0234]|timed out|timeout|ETIMEDOUT|ECONNRESET|ECONNREFUSED|EAI_AGAIN|socket hang up|network|temporarily)\b/i;
172
- const PERMANENT = /\b(usage limit|not found on PATH|invalid api key|\/login|unauthorized|401|403|credit balance)\b/i;
173
- export function isTransient(message) {
174
- if (PERMANENT.test(message))
175
- return false;
176
- return TRANSIENT.test(message);
177
- }
178
- // Deliberately NOT unref'd: an unref'd backoff lets Node exit while the retry is
179
- // still pending, which would end a build mid-flight instead of resuming it.
180
- const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
181
- // --- prompt assembly ---------------------------------------------------------
182
- /**
183
- * The schema the reply must satisfy. `tool` format borrows the named tool's own
184
- * parameter schema, so synthesize/crux keep one schema definition rather than
185
- * maintaining a second copy for this provider.
186
- */
187
- function schemaFor(req, fmt) {
188
- if (fmt.kind === "tool")
189
- return req.tools?.find((t) => t.name === fmt.name)?.parameters ?? { type: "object" };
190
- if (fmt.kind === "json")
191
- return { type: "object" };
192
- return undefined;
193
- }
194
- /** Flatten the neutral message list into one stdin document. */
195
- function buildPrompt(messages, schema) {
196
- const system = messages.filter((m) => m.role === "system").map((m) => m.content.trim()).filter(Boolean);
197
- const rest = messages.filter((m) => m.role !== "system");
198
- const body = rest.length === 1 && rest[0].role === "user"
199
- ? rest[0].content
200
- : rest
201
- .map((m) => {
202
- const head = m.role === "tool" ? `TOOL RESULT (${m.toolCallId ?? ""})` : m.role.toUpperCase();
203
- const calls = m.toolCalls?.length ? `\n${JSON.stringify(m.toolCalls)}` : "";
204
- return `### ${head}\n${m.content}${calls}`;
205
- })
206
- .join("\n\n");
207
- const parts = [];
208
- if (system.length)
209
- parts.push(`<INSTRUCTIONS>\n${system.join("\n\n")}\n</INSTRUCTIONS>`);
210
- parts.push(`<INPUT>\n${body}\n</INPUT>`);
211
- if (schema !== undefined) {
212
- parts.push("<OUTPUT_FORMAT>\n" +
213
- "Reply with a SINGLE JSON object and nothing else. No prose before or after it, " +
214
- "no markdown code fences, no explanation. It must validate against this JSON Schema:\n" +
215
- JSON.stringify(schema) +
216
- "\n</OUTPUT_FORMAT>");
217
- }
218
- return parts.join("\n\n");
219
- }
220
- function retryPrompt(original, bad) {
221
- return (`${original}\n\n<RETRY>\nYour previous reply could not be parsed as JSON. It began:\n` +
222
- `${bad.slice(0, 300)}\n\nReply again with ONLY the JSON object — first character "{", last character "}".\n</RETRY>`);
223
- }
224
- // --- response parsing --------------------------------------------------------
225
- /**
226
- * `--output-format json` prints one object, but a stray warning line on stdout
227
- * would break a naive JSON.parse — so fall back to the last JSON-looking line.
228
- */
229
- function parseEnvelope(stdout) {
230
- const trimmed = stdout.trim();
231
- if (!trimmed)
232
- return undefined;
233
- try {
234
- return JSON.parse(trimmed);
235
- }
236
- catch {
237
- // fall through
238
- }
239
- const lines = trimmed.split(/\r?\n/).filter((l) => l.trim().startsWith("{"));
240
- for (let i = lines.length - 1; i >= 0; i--) {
241
- try {
242
- return JSON.parse(lines[i]);
243
- }
244
- catch {
245
- continue;
246
- }
247
- }
248
- return undefined;
249
- }
250
- /**
251
- * Pull one JSON value out of a model reply. Handles the two ways a prompt-enforced
252
- * schema leaks: a markdown fence around the object, and prose either side of it.
253
- * Brace scanning is string- and escape-aware so a `}` inside a summary can't end
254
- * the object early. Returns undefined when nothing parses.
255
- */
256
- export function extractJson(text) {
257
- const stripped = text.replace(/^\s*```(?:json)?\s*/i, "").replace(/\s*```\s*$/, "").trim();
258
- for (const candidate of [stripped, text]) {
259
- try {
260
- return JSON.parse(candidate);
261
- }
262
- catch {
263
- // fall through to brace scanning
264
- }
265
- const start = candidate.indexOf("{");
266
- if (start === -1)
267
- continue;
268
- let depth = 0;
269
- let inString = false;
270
- let escaped = false;
271
- for (let i = start; i < candidate.length; i++) {
272
- const ch = candidate[i];
273
- if (escaped) {
274
- escaped = false;
275
- continue;
276
- }
277
- if (ch === "\\") {
278
- if (inString)
279
- escaped = true;
280
- continue;
281
- }
282
- if (ch === '"') {
283
- inString = !inString;
284
- continue;
285
- }
286
- if (inString)
287
- continue;
288
- if (ch === "{")
289
- depth++;
290
- else if (ch === "}") {
291
- depth--;
292
- if (depth === 0) {
293
- try {
294
- return JSON.parse(candidate.slice(start, i + 1));
295
- }
296
- catch {
297
- break;
298
- }
299
- }
300
- }
301
- }
302
- }
303
- return undefined;
304
- }
305
- /** The CLI already reports uncached input separately, matching graft's convention. */
306
- function normalizeUsage(u) {
307
- return {
308
- input: u?.input_tokens ?? 0,
309
- output: u?.output_tokens ?? 0,
310
- cacheRead: u?.cache_read_input_tokens ?? 0,
311
- cacheCreate: u?.cache_creation_input_tokens ?? 0,
312
- };
313
- }
314
- // --- process plumbing --------------------------------------------------------
315
- /**
316
- * Resolve the CLI without a shell. Node's spawn only appends `.exe` on Windows,
317
- * so PATHEXT is walked by hand — the native installer ships `claude.exe` but an
318
- * `npm i -g` install leaves only the `claude.cmd` shim, and missing it would make
319
- * this provider look uninstalled on a machine where it works fine.
320
- */
321
- export function resolveClaudeBin(explicit) {
322
- const name = explicit ?? process.env.GRAFT_CLAUDE_BIN ?? "claude";
323
- if (name.includes("/") || name.includes("\\"))
324
- return existsSync(name) ? name : undefined;
325
- const exts = process.platform === "win32"
326
- ? [".EXE", ".CMD", ".BAT", ".COM", ""] // .exe first: it spawns without a shim
327
- : [""];
328
- for (const dir of (process.env.PATH ?? "").split(delimiter)) {
329
- if (!dir)
330
- continue;
331
- for (const ext of exts) {
332
- const p = join(dir.replace(/^"|"$/g, ""), name + ext);
333
- if (existsSync(p))
334
- return p;
335
- }
336
- }
337
- return undefined;
338
- }
339
- let cachedAvailable;
340
- /** True when the `claude` CLI is installed. Cached — this runs per build, not per file. */
341
- export function claudeCliAvailable(explicit) {
342
- if (explicit ?? process.env.GRAFT_CLAUDE_BIN)
343
- return !!resolveClaudeBin(explicit);
344
- if (cachedAvailable === undefined)
345
- cachedAvailable = !!resolveClaudeBin();
346
- return cachedAvailable;
347
- }
348
- /** Test seam: drop the memoized lookup so a test can flip PATH. */
349
- export function resetClaudeCliCache() {
350
- cachedAvailable = undefined;
351
- }
352
- /**
353
- * `cmd.exe` cannot be handed a `.cmd` file through CreateProcess, so an npm shim
354
- * has to be run as a command line. Every argument we pass is short and quote-free
355
- * (the prompt goes over stdin), so quoting each one is enough.
356
- */
357
- function windowsWrap(bin, args) {
358
- const isShim = process.platform === "win32" && /\.(cmd|bat)$/i.test(bin);
359
- if (!isShim)
360
- return { file: bin, argv: args, verbatim: false };
361
- const quote = (s) => `"${s.replace(/"/g, '""')}"`;
362
- const line = [quote(bin), ...args.map(quote)].join(" ");
363
- return { file: process.env.ComSpec ?? "cmd.exe", argv: ["/d", "/s", "/c", `"${line}"`], verbatim: true };
364
- }
365
- function defaultRunner(bin) {
366
- return (args, stdin, timeoutMs) => new Promise((resolve, reject) => {
367
- const resolved = resolveClaudeBin(bin);
368
- if (!resolved) {
369
- reject(new Error("claude CLI not found on PATH. Install Claude Code (https://claude.com/claude-code) and sign in " +
370
- "with your subscription, set GRAFT_CLAUDE_BIN to its path, or use an API-key provider " +
371
- "(GRAFT_PROVIDER=anthropic|openai + GRAFT_API_KEY)."));
372
- return;
373
- }
374
- const { file, argv, verbatim } = windowsWrap(resolved, args);
375
- const child = spawn(file, argv, {
376
- // Never the user's repo: cwd is what CLAUDE.md discovery keys off, and a
377
- // summarization run must not inherit the project's own agent instructions.
378
- cwd: tmpdir(),
379
- windowsHide: true,
380
- windowsVerbatimArguments: verbatim,
381
- env: {
382
- ...process.env,
383
- // Skip the auxiliary Haiku calls (titles, topic detection): pure overhead
384
- // when a "session" is one summary that is never resumed.
385
- DISABLE_NON_ESSENTIAL_MODEL_CALLS: "1",
386
- CLAUDE_CODE_ENTRYPOINT: "graft",
387
- },
388
- stdio: ["pipe", "pipe", "pipe"],
389
- });
390
- let stdout = "";
391
- let stderr = "";
392
- let settled = false;
393
- const finish = (fn) => {
394
- if (settled)
395
- return;
396
- settled = true;
397
- clearTimeout(timer);
398
- fn();
399
- };
400
- const timer = setTimeout(() => {
401
- child.kill("SIGKILL");
402
- finish(() => reject(new Error(`claude CLI timed out after ${timeoutMs}ms`)));
403
- }, timeoutMs);
404
- timer.unref?.();
405
- child.stdout.setEncoding("utf8");
406
- child.stderr.setEncoding("utf8");
407
- child.stdout.on("data", (d) => (stdout += d));
408
- child.stderr.on("data", (d) => (stderr += d));
409
- child.on("error", (err) => finish(() => reject(err)));
410
- child.on("close", (code) => finish(() => resolve({ code, stdout, stderr })));
411
- // A CLI that dies before draining stdin gives us EPIPE; the close handler
412
- // already carries the real diagnosis, so swallow it here.
413
- child.stdin.on("error", () => { });
414
- child.stdin.end(stdin, "utf8");
415
- });
416
- }
417
- //# sourceMappingURL=claude-cli.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"claude-cli.js","sourceRoot":"","sources":["../../../src/ai/llm/claude-cli.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- /** Thousands-separated integer, identical on every machine. */
2
- export declare function formatCount(n: number): string;
3
- //# sourceMappingURL=num.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"num.d.ts","sourceRoot":"","sources":["../../src/util/num.ts"],"names":[],"mappings":"AAgBA,+DAA+D;AAC/D,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7C"}
package/dist/util/num.js DELETED
@@ -1,20 +0,0 @@
1
- /**
2
- * Number formatting for text graft emits.
3
- *
4
- * `toLocaleString()` with no locale follows the MACHINE's locale, which is the
5
- * wrong authority for two of graft's outputs. The savings lines are read by an
6
- * LLM and explicitly ask it to sum them across calls; on a pt-BR/de-DE box the
7
- * bare call renders 1990 as "1.990", which an agent reads as 1.99 — so the
8
- * headline "tokens saved this turn" total comes out ~1000× low. The graph's own
9
- * stats are compared across machines and CI, where a separator that moves with
10
- * the host makes two identical runs look different.
11
- *
12
- * One pinned locale for both: the output is a data interchange format that
13
- * happens to be human-readable, not localized UI.
14
- */
15
- const FORMATTER = new Intl.NumberFormat("en-US");
16
- /** Thousands-separated integer, identical on every machine. */
17
- export function formatCount(n) {
18
- return FORMATTER.format(Math.round(n));
19
- }
20
- //# sourceMappingURL=num.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"num.js","sourceRoot":"","sources":["../../src/util/num.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;AAEjD,+DAA+D;AAC/D,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,OAAO,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC"}