@nanonets/graft 0.10.0 → 0.12.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.
- package/README.md +34 -13
- package/dist/ai/crux.d.ts.map +1 -1
- package/dist/ai/crux.js +7 -6
- package/dist/ai/crux.js.map +1 -1
- package/dist/ai/failure.d.ts +49 -0
- package/dist/ai/failure.d.ts.map +1 -0
- package/dist/ai/failure.js +74 -0
- package/dist/ai/failure.js.map +1 -0
- package/dist/ai/llm/anthropic.d.ts.map +1 -1
- package/dist/ai/llm/anthropic.js +4 -1
- package/dist/ai/llm/anthropic.js.map +1 -1
- package/dist/ai/llm/claude-cli.d.ts +60 -0
- package/dist/ai/llm/claude-cli.d.ts.map +1 -0
- package/dist/ai/llm/claude-cli.js +417 -0
- package/dist/ai/llm/claude-cli.js.map +1 -0
- package/dist/ai/llm/openai.d.ts.map +1 -1
- package/dist/ai/llm/openai.js +2 -0
- package/dist/ai/llm/openai.js.map +1 -1
- package/dist/ai/llm/types.d.ts +9 -0
- package/dist/ai/llm/types.d.ts.map +1 -1
- package/dist/ai/llm/types.js +12 -1
- package/dist/ai/llm/types.js.map +1 -1
- package/dist/ask/ask.d.ts.map +1 -1
- package/dist/ask/ask.js +39 -45
- package/dist/ask/ask.js.map +1 -1
- package/dist/ask/fuse.d.ts +83 -46
- package/dist/ask/fuse.d.ts.map +1 -1
- package/dist/ask/fuse.js +165 -67
- package/dist/ask/fuse.js.map +1 -1
- package/dist/blast/blast-cli.d.ts +30 -0
- package/dist/blast/blast-cli.d.ts.map +1 -0
- package/dist/blast/blast-cli.js +163 -0
- package/dist/blast/blast-cli.js.map +1 -0
- package/dist/blast/blast.d.ts +119 -0
- package/dist/blast/blast.d.ts.map +1 -0
- package/dist/blast/blast.js +383 -0
- package/dist/blast/blast.js.map +1 -0
- package/dist/blast/diff.d.ts +53 -0
- package/dist/blast/diff.d.ts.map +1 -0
- package/dist/blast/diff.js +193 -0
- package/dist/blast/diff.js.map +1 -0
- package/dist/blast/modules.d.ts +33 -0
- package/dist/blast/modules.d.ts.map +1 -0
- package/dist/blast/modules.js +83 -0
- package/dist/blast/modules.js.map +1 -0
- package/dist/blast/name.d.ts +61 -0
- package/dist/blast/name.d.ts.map +1 -0
- package/dist/blast/name.js +233 -0
- package/dist/blast/name.js.map +1 -0
- package/dist/blast/render.d.ts +37 -0
- package/dist/blast/render.d.ts.map +1 -0
- package/dist/blast/render.js +300 -0
- package/dist/blast/render.js.map +1 -0
- package/dist/blast/viz.d.ts +17 -0
- package/dist/blast/viz.d.ts.map +1 -0
- package/dist/blast/viz.js +324 -0
- package/dist/blast/viz.js.map +1 -0
- package/dist/claude/hooks.d.ts +13 -0
- package/dist/claude/hooks.d.ts.map +1 -1
- package/dist/claude/hooks.js +44 -4
- package/dist/claude/hooks.js.map +1 -1
- package/dist/claude/shim-template.d.ts.map +1 -1
- package/dist/claude/shim-template.js +45 -15
- package/dist/claude/shim-template.js.map +1 -1
- package/dist/claude/state.d.ts +5 -0
- package/dist/claude/state.d.ts.map +1 -1
- package/dist/claude/state.js.map +1 -1
- package/dist/cli-picker.d.ts +44 -5
- package/dist/cli-picker.d.ts.map +1 -1
- package/dist/cli-picker.js +73 -26
- package/dist/cli-picker.js.map +1 -1
- package/dist/cli.js +270 -14
- package/dist/cli.js.map +1 -1
- package/dist/context/build.d.ts +8 -0
- package/dist/context/build.d.ts.map +1 -1
- package/dist/context/build.js +57 -9
- package/dist/context/build.js.map +1 -1
- package/dist/context/check.d.ts.map +1 -1
- package/dist/context/check.js +7 -6
- package/dist/context/check.js.map +1 -1
- package/dist/context/node-file.d.ts.map +1 -1
- package/dist/context/node-file.js +9 -2
- package/dist/context/node-file.js.map +1 -1
- package/dist/graph/bindings.d.ts.map +1 -1
- package/dist/graph/bindings.js +245 -2
- package/dist/graph/bindings.js.map +1 -1
- package/dist/graph/build.d.ts.map +1 -1
- package/dist/graph/build.js +36 -16
- package/dist/graph/build.js.map +1 -1
- package/dist/graph/check.d.ts +4 -0
- package/dist/graph/check.d.ts.map +1 -1
- package/dist/graph/check.js +8 -1
- package/dist/graph/check.js.map +1 -1
- package/dist/graph/container.d.ts +63 -0
- package/dist/graph/container.d.ts.map +1 -0
- package/dist/graph/container.js +185 -0
- package/dist/graph/container.js.map +1 -0
- package/dist/graph/enrich.d.ts +18 -0
- package/dist/graph/enrich.d.ts.map +1 -1
- package/dist/graph/enrich.js +55 -2
- package/dist/graph/enrich.js.map +1 -1
- package/dist/graph/extract.d.ts +8 -1
- package/dist/graph/extract.d.ts.map +1 -1
- package/dist/graph/extract.js +401 -12
- package/dist/graph/extract.js.map +1 -1
- package/dist/graph/generic.d.ts +34 -1
- package/dist/graph/generic.d.ts.map +1 -1
- package/dist/graph/generic.js +176 -6
- package/dist/graph/generic.js.map +1 -1
- package/dist/graph/invariants.d.ts +32 -0
- package/dist/graph/invariants.d.ts.map +1 -0
- package/dist/graph/invariants.js +49 -0
- package/dist/graph/invariants.js.map +1 -0
- package/dist/graph/queries/clojure.scm +58 -0
- package/dist/graph/resolve.d.ts.map +1 -1
- package/dist/graph/resolve.js +249 -23
- package/dist/graph/resolve.js.map +1 -1
- package/dist/graph/scopes.d.ts +2 -2
- package/dist/graph/scopes.d.ts.map +1 -1
- package/dist/graph/scopes.js +8 -6
- package/dist/graph/scopes.js.map +1 -1
- package/dist/graph/source-files.d.ts +13 -4
- package/dist/graph/source-files.d.ts.map +1 -1
- package/dist/graph/source-files.js +35 -12
- package/dist/graph/source-files.js.map +1 -1
- package/dist/graph/types.d.ts +3 -1
- package/dist/graph/types.d.ts.map +1 -1
- package/dist/graph/workspace-cli.d.ts +2 -0
- package/dist/graph/workspace-cli.d.ts.map +1 -1
- package/dist/graph/workspace-cli.js +10 -4
- package/dist/graph/workspace-cli.js.map +1 -1
- package/dist/graph/workspace.d.ts +11 -6
- package/dist/graph/workspace.d.ts.map +1 -1
- package/dist/graph/workspace.js +24 -13
- package/dist/graph/workspace.js.map +1 -1
- package/dist/graph/write.d.ts.map +1 -1
- package/dist/graph/write.js +25 -2
- package/dist/graph/write.js.map +1 -1
- package/dist/hosts/antigravity.d.ts +7 -0
- package/dist/hosts/antigravity.d.ts.map +1 -0
- package/dist/hosts/antigravity.js +42 -0
- package/dist/hosts/antigravity.js.map +1 -0
- package/dist/hosts/codex-hooks.d.ts +3 -3
- package/dist/hosts/codex-hooks.d.ts.map +1 -1
- package/dist/hosts/codex-hooks.js +27 -21
- package/dist/hosts/codex-hooks.js.map +1 -1
- package/dist/hosts/init.d.ts.map +1 -1
- package/dist/hosts/init.js +6 -1
- package/dist/hosts/init.js.map +1 -1
- package/dist/hosts/mcp-config.d.ts.map +1 -1
- package/dist/hosts/mcp-config.js +7 -0
- package/dist/hosts/mcp-config.js.map +1 -1
- package/dist/hosts/plan.d.ts +1 -1
- package/dist/hosts/plan.d.ts.map +1 -1
- package/dist/hosts/plan.js +2 -0
- package/dist/hosts/plan.js.map +1 -1
- package/dist/hosts/registry.d.ts.map +1 -1
- package/dist/hosts/registry.js +13 -0
- package/dist/hosts/registry.js.map +1 -1
- package/dist/ingest/fs.d.ts +9 -2
- package/dist/ingest/fs.d.ts.map +1 -1
- package/dist/ingest/fs.js +100 -16
- package/dist/ingest/fs.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +45 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/telemetry/contract.d.ts +90 -0
- package/dist/telemetry/contract.d.ts.map +1 -0
- package/dist/telemetry/contract.js +203 -0
- package/dist/telemetry/contract.js.map +1 -0
- package/dist/telemetry/flush.d.ts +21 -0
- package/dist/telemetry/flush.d.ts.map +1 -0
- package/dist/telemetry/flush.js +84 -0
- package/dist/telemetry/flush.js.map +1 -0
- package/dist/telemetry/gate.d.ts +16 -0
- package/dist/telemetry/gate.d.ts.map +1 -0
- package/dist/telemetry/gate.js +64 -0
- package/dist/telemetry/gate.js.map +1 -0
- package/dist/telemetry/identity.d.ts +33 -0
- package/dist/telemetry/identity.d.ts.map +1 -0
- package/dist/telemetry/identity.js +80 -0
- package/dist/telemetry/identity.js.map +1 -0
- package/dist/telemetry/index.d.ts +18 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +16 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/key.d.ts +21 -0
- package/dist/telemetry/key.d.ts.map +1 -0
- package/dist/telemetry/key.js +49 -0
- package/dist/telemetry/key.js.map +1 -0
- package/dist/telemetry/notice.d.ts +19 -0
- package/dist/telemetry/notice.d.ts.map +1 -0
- package/dist/telemetry/notice.js +90 -0
- package/dist/telemetry/notice.js.map +1 -0
- package/dist/telemetry/queue.d.ts +35 -0
- package/dist/telemetry/queue.d.ts.map +1 -0
- package/dist/telemetry/queue.js +162 -0
- package/dist/telemetry/queue.js.map +1 -0
- package/dist/telemetry/send.d.ts +19 -0
- package/dist/telemetry/send.d.ts.map +1 -0
- package/dist/telemetry/send.js +84 -0
- package/dist/telemetry/send.js.map +1 -0
- package/dist/telemetry/sessions.d.ts +8 -0
- package/dist/telemetry/sessions.d.ts.map +1 -0
- package/dist/telemetry/sessions.js +81 -0
- package/dist/telemetry/sessions.js.map +1 -0
- package/dist/telemetry/track.d.ts +43 -0
- package/dist/telemetry/track.d.ts.map +1 -0
- package/dist/telemetry/track.js +108 -0
- package/dist/telemetry/track.js.map +1 -0
- package/dist/upkeep-run.d.ts +15 -0
- package/dist/upkeep-run.d.ts.map +1 -0
- package/dist/upkeep-run.js +60 -0
- package/dist/upkeep-run.js.map +1 -0
- package/dist/upkeep.d.ts +114 -0
- package/dist/upkeep.d.ts.map +1 -0
- package/dist/upkeep.js +232 -0
- package/dist/upkeep.js.map +1 -0
- package/dist/util/num.d.ts +3 -0
- package/dist/util/num.d.ts.map +1 -0
- package/dist/util/num.js +20 -0
- package/dist/util/num.js.map +1 -0
- package/dist/util/state.d.ts +11 -4
- package/dist/util/state.d.ts.map +1 -1
- package/dist/util/state.js +9 -0
- package/dist/util/state.js.map +1 -1
- package/dist/viewer/app.js +1 -1
- package/dist/viewer/index.html +1 -0
- package/dist/viewer/style.css +23 -2
- package/dist/viz/assemble.d.ts +33 -0
- package/dist/viz/assemble.d.ts.map +1 -1
- package/dist/viz/assemble.js.map +1 -1
- package/dist/viz/export.d.ts +39 -0
- package/dist/viz/export.d.ts.map +1 -0
- package/dist/viz/export.js +98 -0
- package/dist/viz/export.js.map +1 -0
- package/package.json +15 -5
- package/scripts/stamp-telemetry-key.mjs +53 -0
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<a href="https://nodejs.org"><img src="https://img.shields.io/node/v/%40nanonets%2Fgraft?style=for-the-badge&logo=nodedotjs&logoColor=white" /></a>
|
|
14
14
|
<img src="https://img.shields.io/badge/TypeScript-strict-3178C6?style=for-the-badge&logo=typescript&logoColor=white" />
|
|
15
15
|
<img src="https://img.shields.io/badge/License-MIT-20C997?style=for-the-badge" />
|
|
16
|
-
<img src="https://img.shields.io/badge/telemetry-
|
|
16
|
+
<a href="TELEMETRY.md"><img src="https://img.shields.io/badge/telemetry-anonymous%2C%20opt--out-546FFF?style=for-the-badge" /></a>
|
|
17
17
|
<a href="https://scorecard.dev/viewer/?uri=github.com/NanoNets/Graft"><img src="https://img.shields.io/ossf-scorecard/github.com/NanoNets/Graft?style=for-the-badge&label=openssf%20scorecard" /></a>
|
|
18
18
|
</p>
|
|
19
19
|
|
|
@@ -105,8 +105,8 @@ Graft builds that understanding **once** and writes it into your repo as a folde
|
|
|
105
105
|
|
|
106
106
|
- **Real explanations, not a list of symbols.** Each node says, in plain English, what a part of the system does and how it connects to the rest, the way a senior engineer would explain it. That is the part an agent actually needs so it can skip the exploration. It is not a dump of function names.
|
|
107
107
|
- **A real graph you can read.** No embeddings, no similarity search, no index to keep warm. The graph is a set of linked files your agent opens, greps, and follows, exactly the way it reads any other file in the repo.
|
|
108
|
-
- **
|
|
109
|
-
- **
|
|
108
|
+
- **A local cache, not a committed artifact.** `graft build` writes `graft/` and adds it to `.gitignore` — it's a regenerable local cache, like `node_modules`. What you commit is the small wiring `graft init` drops in (`.claude/`, `AGENTS.md`, the MCP config); each teammate runs `graft build` to generate their own graph. No database, no server, no setup.
|
|
109
|
+
- **Always fresh, automatically.** Every query rebuilds the graph against the working tree first — structural, `$0`, ~3ms when nothing moved — so `ask`/`grep`/`callers`/`skeleton`/`map` describe the code as it is right now, including uncommitted edits. `graft check` is a local freshness signal; there's no stale index to babysit.
|
|
110
110
|
- **Your provider, your key, your model.** Summaries are written by any provider you choose — OpenAI, Anthropic (native), OpenRouter, Fireworks, Groq, a LiteLLM proxy, or a local model — under your own key. The structural code graph (`graft build`, `graft check`) is deterministic tree-sitter and never calls a model at all.
|
|
111
111
|
|
|
112
112
|
<p align="center">
|
|
@@ -179,7 +179,7 @@ flowchart LR
|
|
|
179
179
|
|
|
180
180
|
Every pass is cached by content hash — the LLM ones and the tree-sitter parse alike. Re-running only touches the files that changed, so the second build is fast and cheap (on this repo, 124 files: 0.74s cold, 0.18s after one edited file, 0.18s with nothing changed). `graft build --no-reuse` forces a cold re-parse.
|
|
181
181
|
|
|
182
|
-
That cheapness is what lets **every query refresh the graph before it answers**. A retrieval call stats the tree against the last build's fingerprint (~3ms), and rebuilds only if something moved — so `ask`/`grep`/`callers`/`skeleton`/`map` describe the code as it is right now, including edits that are unsaved to git: uncommitted, unstaged, or staged all look the same to graft
|
|
182
|
+
That cheapness is what lets **every query refresh the graph before it answers**. A retrieval call stats the tree against the last build's fingerprint (~3ms), and rebuilds only if something moved — so `ask`/`grep`/`callers`/`skeleton`/`map` describe the code as it is right now, including edits that are unsaved to git: uncommitted, unstaged, or staged all look the same to graft. Git determines the visible file set; freshness compares the working-tree bytes rather than commit or index state. The refresh is structural and `$0`; it never calls the LLM. Turn it off per-command with `--no-refresh`, or everywhere with `GRAFT_NO_REFRESH=1`.
|
|
183
183
|
|
|
184
184
|
Alongside the markdown graph, `graft build` builds `graft/.graph/wiring.json` — a per-symbol code graph — plus a per-file wiring card mirroring your source tree. Tier 1 is pure tree-sitter (every function, class, and call edge; deterministic, no model, no network), which is why plain `graft build` needs no key. The `--deep` pass adds a one-line summary and a crux excerpt per symbol, cached by body hash.
|
|
185
185
|
|
|
@@ -192,12 +192,12 @@ compiler-grade layer — all `$0` and deterministic (no model, no key):
|
|
|
192
192
|
|
|
193
193
|
- **Full-fidelity** — hand-written extractors with scope-aware, cross-file call
|
|
194
194
|
and import resolution:
|
|
195
|
-
**TypeScript / JavaScript** (incl. JSX & TSX), **Python**, **Go**.
|
|
195
|
+
**TypeScript / JavaScript** (incl. JSX & TSX), **Python**, **Go**, **Java**.
|
|
196
196
|
|
|
197
197
|
- **Broad** — symbols (functions, classes, methods, types, …) plus name-resolved
|
|
198
198
|
call edges via a generic tree-sitter extractor, one grammar per language:
|
|
199
|
-
**Rust,
|
|
200
|
-
OCaml, Zig, Dart**.
|
|
199
|
+
**Rust, C, C++, C#, Ruby, PHP, Kotlin, Scala, Swift, Elixir, Solidity,
|
|
200
|
+
OCaml, Zig, Dart, Clojure**.
|
|
201
201
|
|
|
202
202
|
- **Compiler-grade edges (opt-in)** — `graft build --lsp` adds precise
|
|
203
203
|
`lsp_resolved` call edges (member calls the static pass can't type) when a
|
|
@@ -205,7 +205,7 @@ compiler-grade layer — all `$0` and deterministic (no model, no key):
|
|
|
205
205
|
**gopls** (Go), **pyright** (Python), **typescript-language-server** (TS/JS).
|
|
206
206
|
It's best-effort — with no server installed the graph is unchanged.
|
|
207
207
|
|
|
208
|
-
Twenty languages in total. A file whose language isn't listed is skipped, not
|
|
208
|
+
Twenty-one languages in total. A file whose language isn't listed is skipped, not
|
|
209
209
|
indexed. Adding a broad-tier language is a small contribution — see
|
|
210
210
|
[CREDITS.md](CREDITS.md) for the folks who added the current set.
|
|
211
211
|
|
|
@@ -237,7 +237,7 @@ _Summary, sources, links, and notes ship today in markdown nodes. The crux ships
|
|
|
237
237
|
|
|
238
238
|
- **On your machine, no key, no network:** the structural code graph. `graft build` (wiring graph + per-file cards), `graft check`, and `graft ask` are deterministic tree-sitter — they never call a model.
|
|
239
239
|
- **Through your provider key:** the LLM-written parts — `graft build --deep` adds the concept nodes (file summaries + node synthesis) and the per-symbol summaries and cruxes. graft is vendor-neutral: set `GRAFT_PROVIDER` (`openai` for any OpenAI-compatible endpoint, or `anthropic` for the native API), your `GRAFT_API_KEY`, `GRAFT_MODEL`, and — for the `openai` wire format — `GRAFT_BASE_URL` to point at OpenRouter, Fireworks, Groq, a LiteLLM proxy, a local server, or OpenAI itself. Or pass `--provider/--model/--api-key/--base-url` on the command line. (`OPENROUTER_API_KEY` still works as a deprecated fallback.)
|
|
240
|
-
- **
|
|
240
|
+
- **Anonymous usage stats** — the only network calls are the LLM requests you configured, a daily npm version check, and one batched usage ping. The ping carries buckets and fixed labels only: never your code, file paths, repo name, symbols, queries, or error messages. [`TELEMETRY.md`](TELEMETRY.md) is the complete list and `graft telemetry debug` prints exactly what your machine would send. Turn it off with `graft telemetry disable`, `DO_NOT_TRACK=1`, or by unchecking the box in `graft init`; it is off in CI and in any build from source.
|
|
241
241
|
|
|
242
242
|
See [`.env.example`](.env.example) for the full list of settings (model, base URL, graph directory).
|
|
243
243
|
|
|
@@ -331,6 +331,8 @@ graft build [dir] # build graft/ from the code at [dir]: wiri
|
|
|
331
331
|
graft build --deep # add the LLM layer: concept nodes + per-symbol summary/crux (cached)
|
|
332
332
|
graft build --extensions .ts .py # only include these code extensions
|
|
333
333
|
graft build --no-reuse # re-parse every file instead of replaying unchanged ones from cache
|
|
334
|
+
graft build --follow-submodules # include initialized submodules; persist the choice for builds + MCP refresh
|
|
335
|
+
graft build --no-follow-submodules # exclude submodules again and persist that choice (the default)
|
|
334
336
|
|
|
335
337
|
graft ask "<task>" [dir] # query the graph — ranked nodes + exact file:line (no LLM, no key)
|
|
336
338
|
graft ask "<task>" --json # machine-readable result
|
|
@@ -349,16 +351,24 @@ graft grep "<regex>" -i --fixed # case-insensitive; treat the pattern as a
|
|
|
349
351
|
graft map [dir] # token-budgeted repo orientation — dir clusters, hubs, hotspots (no LLM, no key)
|
|
350
352
|
graft map --max-dirs N # raise/lower the number of directories shown
|
|
351
353
|
|
|
354
|
+
graft blast [dir] # blast radius of a diff: what depends on the lines this change touched (no LLM, no key)
|
|
355
|
+
graft blast --base origin/main # diff against the merge base with HEAD — what a PR job runs
|
|
356
|
+
graft blast --format markdown # a PR comment: the areas a change can reach, per-symbol detail collapsed under it
|
|
357
|
+
graft blast --base origin/main --name # name those areas with one cached LLM call, instead of a full --deep build
|
|
358
|
+
graft blast --export-viz site/ # also write the interactive page for this radius (what a PR comment links to)
|
|
359
|
+
graft blast --depth all --format json # the full transitive closure, machine-readable
|
|
360
|
+
|
|
352
361
|
graft check [dir] # fail (exit 1) if graft/ has drifted from the code (never auto-refreshes — it's the drift report)
|
|
353
362
|
graft check --json # print the drift report as JSON
|
|
354
363
|
|
|
355
|
-
# ask / skeleton / callers / grep / map all refresh the graph first if the working tree moved:
|
|
364
|
+
# ask / skeleton / callers / grep / map / blast all refresh the graph first if the working tree moved:
|
|
356
365
|
# --no-refresh # answer from the graph exactly as it is on disk
|
|
357
366
|
# GRAFT_NO_REFRESH=1 # same, for every command
|
|
358
367
|
# GRAFT_REFRESH=hash # hash every file instead of trusting size+mtime
|
|
359
368
|
|
|
360
369
|
graft viz [dir] # see the graph: serves an interactive viewer on localhost
|
|
361
370
|
graft viz --port 5000 --no-open # pick a port; don't auto-open the browser
|
|
371
|
+
graft viz --export site/ --title "PR #12" # one self-contained index.html — for CI, GitHub Pages, or a build artifact
|
|
362
372
|
|
|
363
373
|
graft init [dir] # pick which agents to wire (prompts on a terminal; writes nothing until you choose)
|
|
364
374
|
graft init --dry-run # list every file it would touch, then exit
|
|
@@ -371,6 +381,8 @@ graft init --list-agents # list known agent ids and exit
|
|
|
371
381
|
|
|
372
382
|
graft version # print the installed + latest published npm version
|
|
373
383
|
graft upgrade # npm install -g the latest published version
|
|
384
|
+
# a new version is announced automatically (checked once a day);
|
|
385
|
+
# after upgrading, the next session refreshes this repo's wiring itself
|
|
374
386
|
|
|
375
387
|
# global
|
|
376
388
|
graft --dir <path> # use a context dir other than <repo>/graft
|
|
@@ -414,9 +426,9 @@ scripts/ 2 files · 0 symbols
|
|
|
414
426
|
hotspots: contextDirFor · function · src/context/node-file.ts:L100-L103 · 21← wiringPath · function · src/graph/write.ts:L20-L22 · 14← buildGraph · function · src/graph/build.ts:L104-L218 · 11← ...
|
|
415
427
|
```
|
|
416
428
|
|
|
417
|
-
## Monorepos & multi-repo folders
|
|
429
|
+
## Monorepos, submodules & multi-repo folders
|
|
418
430
|
|
|
419
|
-
Graft
|
|
431
|
+
Graft supports these layouts:
|
|
420
432
|
|
|
421
433
|
- **A monorepo with one `.git`** (a `pnpm-workspace.yaml`/`package.json`
|
|
422
434
|
`workspaces`, or per-package `go.mod`/`pyproject.toml`/`Cargo.toml`) —
|
|
@@ -424,13 +436,22 @@ Graft handles two shapes without any config:
|
|
|
424
436
|
rank every scope on its own terms and fuse the results, so the biggest
|
|
425
437
|
sub-project can't drown a small one; hits carry `[scope/]` labels, and
|
|
426
438
|
`graft map` groups its directory clusters by scope first.
|
|
439
|
+
- **A Git superproject with initialized submodules** — submodules stay excluded
|
|
440
|
+
by default. Run `graft build --follow-submodules` to fold initialized gitlinks
|
|
441
|
+
into one graph, prefixing child paths (for example,
|
|
442
|
+
`deps/parser/src/index.ts`) while honoring each submodule's own Git ignore
|
|
443
|
+
rules. Visible untracked files are included too; uninitialized submodules
|
|
444
|
+
remain absent until `git submodule update --init` checks them out. The choice
|
|
445
|
+
is saved in `.graft/config.json`, so later no-flag builds and MCP automatic
|
|
446
|
+
refreshes behave the same way. Run `graft build --no-follow-submodules` to
|
|
447
|
+
restore and persist the default boundary.
|
|
427
448
|
- **A folder of separate git repos** (no `.git` at the top) — `graft build`
|
|
428
449
|
auto-splits: each child gets its own (git-ignored) `graft/`, and the parent
|
|
429
450
|
gets a `graft/workspace.json` index. Queries from the parent federate across
|
|
430
451
|
every child, always labeled `<child>/`. Run `graft build` inside a child to
|
|
431
452
|
work on just that repo.
|
|
432
453
|
|
|
433
|
-
|
|
454
|
+
In every layout, narrow to one sub-project with `graft ask "<task>" --in <scope>/`
|
|
434
455
|
once you know where you're working.
|
|
435
456
|
|
|
436
457
|
`graft init` at the parent of a multi-repo folder wires **every child repo too**,
|
package/dist/ai/crux.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crux.d.ts","sourceRoot":"","sources":["../../src/ai/crux.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE9C,kFAAkF;AAClF,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;CACzD;
|
|
1
|
+
{"version":3,"file":"crux.d.ts","sourceRoot":"","sources":["../../src/ai/crux.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE9C,kFAAkF;AAClF,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;CACzD;AAyED,+EAA+E;AAC/E,qBAAa,kBAAmB,YAAW,cAAc;IAC3C,OAAO,CAAC,KAAK;gBAAL,KAAK,EAAE,SAAS;IAE9B,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;CAoB9D"}
|
package/dist/ai/crux.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
const SYSTEM_PROMPT = `You explain code definitions for a code graph that helps engineers navigate a codebase.
|
|
2
2
|
|
|
3
|
-
You are given ONE source file with 1-based line numbers, and a list of TARGET definitions in it.
|
|
3
|
+
You are given ONE source file with 1-based line numbers, and a list of TARGET definitions in it. Describe EVERY target via the record_symbols tool.
|
|
4
4
|
|
|
5
5
|
Rules:
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
6
|
+
- Return EXACTLY ONE entry for EVERY target id, using that id verbatim. The number of entries you return MUST equal the number of targets. Never omit a target: a reply missing any id is invalid and will be re-requested.
|
|
7
|
+
- A trivial symbol is NOT an exception. You still return it — with a one-sentence summary and crux 0/0 (see below). "Skip" means "give it no crux span", NEVER "leave it out".
|
|
8
|
+
- summary: ONE sentence — what the symbol is FOR at the business-logic level (the problem it solves or the rule it enforces), not a restatement of its signature.
|
|
9
|
+
- crux_start / crux_end: FILE line numbers (as shown), inside that symbol's own line range. Pick the SINGLE most important contiguous span — the core branch, formula, guard, or state change — at most ~8 lines, and NEVER the whole function. When there is no single focal span (a trivial getter, a plain data holder, a one-line delegation, or logic spread evenly), use crux_start: 0 and crux_end: 0. That 0/0 IS the answer — do not drop the entry.`;
|
|
10
10
|
const RECORD_TOOL = "record_symbols";
|
|
11
11
|
const SYMBOLS_SCHEMA = {
|
|
12
12
|
type: "object",
|
|
@@ -41,7 +41,8 @@ function userContent(input) {
|
|
|
41
41
|
.map((n) => `- id=${n.id} | ${n.kind} | lines L${n.startLine}-L${n.endLine}` +
|
|
42
42
|
(n.signature ? ` | ${n.signature}` : ""))
|
|
43
43
|
.join("\n");
|
|
44
|
-
|
|
44
|
+
const n = input.nodes.length;
|
|
45
|
+
return `FILE: ${input.path}\n\n${numberLines(input.source)}\n\nTARGETS (${n} — return all ${n}, one entry per id):\n${targets}`;
|
|
45
46
|
}
|
|
46
47
|
/** Normalize the tool's parsed argument object into a {@link NodeCrux} list. */
|
|
47
48
|
function parseResults(obj) {
|
package/dist/ai/crux.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crux.js","sourceRoot":"","sources":["../../src/ai/crux.ts"],"names":[],"mappings":"AA6CA,MAAM,aAAa,GAAG;;;;;;;;
|
|
1
|
+
{"version":3,"file":"crux.js","sourceRoot":"","sources":["../../src/ai/crux.ts"],"names":[],"mappings":"AA6CA,MAAM,aAAa,GAAG;;;;;;;;8bAQwa,CAAC;AAE/b,MAAM,WAAW,GAAG,gBAAgB,CAAC;AAErC,MAAM,cAAc,GAAG;IACrB,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,OAAO,EAAE;YACP,IAAI,EAAE,OAAO;YACb,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACtB,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBAC3B,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBAC9B,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;iBAC7B;gBACD,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,CAAC;aACtD;SACF;KACF;IACD,QAAQ,EAAE,CAAC,SAAS,CAAC;CACb,CAAC;AAEX,kFAAkF;AAClF,MAAM,cAAc,GAAG,MAAM,CAAC;AAE9B,SAAS,WAAW,CAAC,MAAc;IACjC,MAAM,OAAO,GACX,MAAM,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC;IAChG,OAAO,OAAO;SACX,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;SACrC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,SAAS,WAAW,CAAC,KAAoB;IACvC,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK;SACxB,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,OAAO,EAAE;QAChE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAC3C;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;IAC7B,OAAO,SAAS,KAAK,CAAC,IAAI,OAAO,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,yBAAyB,OAAO,EAAE,CAAC;AAClI,CAAC;AAED,gFAAgF;AAChF,SAAS,YAAY,CAAC,GAAsC;IAC1D,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IACnD,MAAM,GAAG,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9F,OAAO,GAAG,CAAC,OAAO;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAA4B,CAAC;SACxC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC;SACvC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACX,EAAE,EAAE,CAAC,CAAC,EAAY;QAClB,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;QAC9D,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC;QAC7B,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;KAC1B,CAAC,CAAC,CAAC;AACR,CAAC;AAED,+EAA+E;AAC/E,MAAM,OAAO,kBAAkB;IACT;IAApB,YAAoB,KAAgB;QAAhB,UAAK,GAAL,KAAK,CAAW;IAAG,CAAC;IAExC,KAAK,CAAC,YAAY,CAAC,KAAoB;QACrC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;YAClC,WAAW,EAAE,CAAC;YACd,SAAS,EAAE,IAAI;YACf,KAAK,EAAE;gBACL;oBACE,IAAI,EAAE,WAAW;oBACjB,WAAW,EAAE,8DAA8D;oBAC3E,UAAU,EAAE,cAAoD;iBACjE;aACF;YACD,cAAc,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE;YACnD,QAAQ,EAAE;gBACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE;gBAC1C,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE;aAC9C;SACF,CAAC,CAAC;QACH,OAAO,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAyC,CAAC,CAAC;IACnF,CAAC;CACF"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* When to stop calling a provider that is failing (#127).
|
|
3
|
+
*
|
|
4
|
+
* Both LLM passes of `build --deep` — the per-file concept summaries
|
|
5
|
+
* (`context/build.ts`) and the per-file crux pass (`graph/enrich.ts`) — used to
|
|
6
|
+
* catch every error per file, keep going, and finish with a clean exit. On an
|
|
7
|
+
* 884-file repo behind a gateway whose token quota was spent that produced 1,617
|
|
8
|
+
* failed calls, a normal success footer, and a graph whose meaning tier was
|
|
9
|
+
* missing; the degradation surfaced days later as bad `ask` results.
|
|
10
|
+
*
|
|
11
|
+
* One gate, shared by both passes, so they agree on what "the provider stopped
|
|
12
|
+
* working" means and a caller can report it once.
|
|
13
|
+
*/
|
|
14
|
+
/** Consecutive failures that end a pass. One flaky file is normal; five in a row is
|
|
15
|
+
* a provider that is not going to start working, and each further call is spend
|
|
16
|
+
* with no chance of a result. */
|
|
17
|
+
export declare const MAX_CONSECUTIVE_FAILURES = 5;
|
|
18
|
+
/**
|
|
19
|
+
* Errors no amount of retrying fixes: the key is wrong, or the account/quota is
|
|
20
|
+
* spent. Matched on the message because that is all a provider-neutral transport
|
|
21
|
+
* carries — over-matching costs a build that was going to fail anyway, while
|
|
22
|
+
* under-matching just falls back to the consecutive-failure cutoff.
|
|
23
|
+
*/
|
|
24
|
+
export declare function terminalReason(message: string): string | null;
|
|
25
|
+
/**
|
|
26
|
+
* Failure bookkeeping for one LLM pass: how many units failed, how many were
|
|
27
|
+
* skipped once it gave up, and the human-readable reason it did.
|
|
28
|
+
*
|
|
29
|
+
* Single-threaded by construction — every mutation happens between awaits in the
|
|
30
|
+
* pass's own worker — so no locking is needed despite the concurrency above it.
|
|
31
|
+
*/
|
|
32
|
+
export declare class LlmFailureGate {
|
|
33
|
+
/** Units (files) whose call failed. */
|
|
34
|
+
failed: number;
|
|
35
|
+
/** Units never attempted because the pass had already given up. */
|
|
36
|
+
skipped: number;
|
|
37
|
+
/** Why the pass stopped, when it did. */
|
|
38
|
+
fatal?: string;
|
|
39
|
+
private consecutive;
|
|
40
|
+
/** True once the pass should stop issuing calls. */
|
|
41
|
+
get stopped(): boolean;
|
|
42
|
+
/** Record a failed unit; sets {@link fatal} when this failure is the last straw. */
|
|
43
|
+
record(message: string): void;
|
|
44
|
+
/** Record a success — a failure run only counts while it is unbroken. */
|
|
45
|
+
succeeded(): void;
|
|
46
|
+
/** Record a unit that was not attempted because the pass had stopped. */
|
|
47
|
+
skip(): void;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=failure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failure.d.ts","sourceRoot":"","sources":["../../src/ai/failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;iCAEiC;AACjC,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS7D;AAED;;;;;;GAMG;AACH,qBAAa,cAAc;IACzB,uCAAuC;IACvC,MAAM,SAAK;IACX,mEAAmE;IACnE,OAAO,SAAK;IACZ,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,WAAW,CAAK;IAExB,oDAAoD;IACpD,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,oFAAoF;IACpF,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAW7B,yEAAyE;IACzE,SAAS,IAAI,IAAI;IAIjB,yEAAyE;IACzE,IAAI,IAAI,IAAI;CAGb"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* When to stop calling a provider that is failing (#127).
|
|
3
|
+
*
|
|
4
|
+
* Both LLM passes of `build --deep` — the per-file concept summaries
|
|
5
|
+
* (`context/build.ts`) and the per-file crux pass (`graph/enrich.ts`) — used to
|
|
6
|
+
* catch every error per file, keep going, and finish with a clean exit. On an
|
|
7
|
+
* 884-file repo behind a gateway whose token quota was spent that produced 1,617
|
|
8
|
+
* failed calls, a normal success footer, and a graph whose meaning tier was
|
|
9
|
+
* missing; the degradation surfaced days later as bad `ask` results.
|
|
10
|
+
*
|
|
11
|
+
* One gate, shared by both passes, so they agree on what "the provider stopped
|
|
12
|
+
* working" means and a caller can report it once.
|
|
13
|
+
*/
|
|
14
|
+
/** Consecutive failures that end a pass. One flaky file is normal; five in a row is
|
|
15
|
+
* a provider that is not going to start working, and each further call is spend
|
|
16
|
+
* with no chance of a result. */
|
|
17
|
+
export const MAX_CONSECUTIVE_FAILURES = 5;
|
|
18
|
+
/**
|
|
19
|
+
* Errors no amount of retrying fixes: the key is wrong, or the account/quota is
|
|
20
|
+
* spent. Matched on the message because that is all a provider-neutral transport
|
|
21
|
+
* carries — over-matching costs a build that was going to fail anyway, while
|
|
22
|
+
* under-matching just falls back to the consecutive-failure cutoff.
|
|
23
|
+
*/
|
|
24
|
+
export function terminalReason(message) {
|
|
25
|
+
const m = message.toLowerCase();
|
|
26
|
+
if (/quota|insufficient[_ ]funds|insufficient[_ ]quota|billing|payment required|402/.test(m)) {
|
|
27
|
+
return "the provider reports the quota/credit for this key is exhausted";
|
|
28
|
+
}
|
|
29
|
+
if (/\b401\b|\b403\b|unauthorized|invalid api key|invalid_api_key|authentication/.test(m)) {
|
|
30
|
+
return "the provider rejected the API key";
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Failure bookkeeping for one LLM pass: how many units failed, how many were
|
|
36
|
+
* skipped once it gave up, and the human-readable reason it did.
|
|
37
|
+
*
|
|
38
|
+
* Single-threaded by construction — every mutation happens between awaits in the
|
|
39
|
+
* pass's own worker — so no locking is needed despite the concurrency above it.
|
|
40
|
+
*/
|
|
41
|
+
export class LlmFailureGate {
|
|
42
|
+
/** Units (files) whose call failed. */
|
|
43
|
+
failed = 0;
|
|
44
|
+
/** Units never attempted because the pass had already given up. */
|
|
45
|
+
skipped = 0;
|
|
46
|
+
/** Why the pass stopped, when it did. */
|
|
47
|
+
fatal;
|
|
48
|
+
consecutive = 0;
|
|
49
|
+
/** True once the pass should stop issuing calls. */
|
|
50
|
+
get stopped() {
|
|
51
|
+
return this.fatal !== undefined;
|
|
52
|
+
}
|
|
53
|
+
/** Record a failed unit; sets {@link fatal} when this failure is the last straw. */
|
|
54
|
+
record(message) {
|
|
55
|
+
this.failed++;
|
|
56
|
+
this.consecutive++;
|
|
57
|
+
const terminal = terminalReason(message);
|
|
58
|
+
if (terminal) {
|
|
59
|
+
this.fatal = `${terminal} — stopped after ${this.failed} failed file(s). First error: ${message}`;
|
|
60
|
+
}
|
|
61
|
+
else if (this.consecutive >= MAX_CONSECUTIVE_FAILURES) {
|
|
62
|
+
this.fatal = `${this.consecutive} files in a row failed, so the pass stopped rather than keep calling. Last error: ${message}`;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** Record a success — a failure run only counts while it is unbroken. */
|
|
66
|
+
succeeded() {
|
|
67
|
+
this.consecutive = 0;
|
|
68
|
+
}
|
|
69
|
+
/** Record a unit that was not attempted because the pass had stopped. */
|
|
70
|
+
skip() {
|
|
71
|
+
this.skipped++;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=failure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failure.js","sourceRoot":"","sources":["../../src/ai/failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;iCAEiC;AACjC,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,MAAM,CAAC,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAChC,IAAI,gFAAgF,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7F,OAAO,iEAAiE,CAAC;IAC3E,CAAC;IACD,IAAI,6EAA6E,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1F,OAAO,mCAAmC,CAAC;IAC7C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,cAAc;IACzB,uCAAuC;IACvC,MAAM,GAAG,CAAC,CAAC;IACX,mEAAmE;IACnE,OAAO,GAAG,CAAC,CAAC;IACZ,yCAAyC;IACzC,KAAK,CAAU;IACP,WAAW,GAAG,CAAC,CAAC;IAExB,oDAAoD;IACpD,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC;IAClC,CAAC;IAED,oFAAoF;IACpF,MAAM,CAAC,OAAe;QACpB,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,KAAK,GAAG,GAAG,QAAQ,oBAAoB,IAAI,CAAC,MAAM,iCAAiC,OAAO,EAAE,CAAC;QACpG,CAAC;aAAM,IAAI,IAAI,CAAC,WAAW,IAAI,wBAAwB,EAAE,CAAC;YACxD,IAAI,CAAC,KAAK,GAAG,GAAG,IAAI,CAAC,WAAW,qFAAqF,OAAO,EAAE,CAAC;QACjI,CAAC;IACH,CAAC;IAED,yEAAyE;IACzE,SAAS;QACP,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;IACvB,CAAC;IAED,yEAAyE;IACzE,IAAI;QACF,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/ai/llm/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,SAAS,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/ai/llm/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAE1C,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAsC,MAAM,YAAY,CAAC;AAM3G,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAKD,qBAAa,kBAAmB,YAAW,SAAS;IAClD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;gBAEV,IAAI,EAAE,yBAAyB;IAQrC,MAAM,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAuDrD,sFAAsF;IACtF,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,YAAY;CA4BrB"}
|
package/dist/ai/llm/anthropic.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* signatures survive a multi-turn loop.
|
|
16
16
|
*/
|
|
17
17
|
import Anthropic from "@anthropic-ai/sdk";
|
|
18
|
+
import { transportRetries } from "./types.js";
|
|
18
19
|
const PROVIDER = "anthropic";
|
|
19
20
|
const JSON_TOOL = "emit_json";
|
|
20
21
|
const DEFAULT_MAX_TOKENS = 4096;
|
|
@@ -26,7 +27,9 @@ export class AnthropicChatModel {
|
|
|
26
27
|
constructor(opts) {
|
|
27
28
|
this.model = opts.model;
|
|
28
29
|
this.label = opts.label ?? `${PROVIDER}:${opts.model}`;
|
|
29
|
-
this.client =
|
|
30
|
+
this.client =
|
|
31
|
+
opts.client ??
|
|
32
|
+
new Anthropic({ apiKey: opts.apiKey, baseURL: opts.baseUrl, maxRetries: transportRetries() });
|
|
30
33
|
}
|
|
31
34
|
async create(req) {
|
|
32
35
|
const system = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../src/ai/llm/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,SAAS,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../src/ai/llm/anthropic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { ChatModel, ChatRequest, ChatResponse } from "./types.js";
|
|
2
|
+
export interface ClaudeCliResult {
|
|
3
|
+
code: number | null;
|
|
4
|
+
stdout: string;
|
|
5
|
+
stderr: string;
|
|
6
|
+
}
|
|
7
|
+
/** Injectable process runner — tests pass a stub so nothing is ever spawned. */
|
|
8
|
+
export type ClaudeCliRunner = (args: string[], stdin: string, timeoutMs: number) => Promise<ClaudeCliResult>;
|
|
9
|
+
export interface ClaudeCliChatModelOptions {
|
|
10
|
+
/** Model alias or full id (`sonnet`, `opus`, `claude-sonnet-5`, …). */
|
|
11
|
+
model: string;
|
|
12
|
+
/** Path to the CLI. Default: resolved from PATH (env GRAFT_CLAUDE_BIN wins). */
|
|
13
|
+
bin?: string;
|
|
14
|
+
label?: string;
|
|
15
|
+
/** Per-call wall clock. Default 300s — a crux pass over a big file is slow. */
|
|
16
|
+
timeoutMs?: number;
|
|
17
|
+
/** Optional spend ceiling passed through as `--max-budget-usd`. */
|
|
18
|
+
maxBudgetUsd?: number;
|
|
19
|
+
/** Inject a runner (tests stub it; production omits it). */
|
|
20
|
+
run?: ClaudeCliRunner;
|
|
21
|
+
}
|
|
22
|
+
export declare class ClaudeCliChatModel implements ChatModel {
|
|
23
|
+
readonly label: string;
|
|
24
|
+
private model;
|
|
25
|
+
private runner;
|
|
26
|
+
private timeoutMs;
|
|
27
|
+
private maxBudgetUsd?;
|
|
28
|
+
constructor(opts: ClaudeCliChatModelOptions);
|
|
29
|
+
create(req: ChatRequest): Promise<ChatResponse>;
|
|
30
|
+
/**
|
|
31
|
+
* Transport-level retry. A `--deep` build is thousands of sequential calls over
|
|
32
|
+
* hours, so a single blip — an overloaded upstream, a dropped connection, one
|
|
33
|
+
* slow file hitting the wall clock — would otherwise silently cost that file its
|
|
34
|
+
* summary. Only failures classified transient are retried; a bad login or an
|
|
35
|
+
* exhausted quota fails immediately, because sleeping on those just turns a
|
|
36
|
+
* clear error into a slow one.
|
|
37
|
+
*/
|
|
38
|
+
private invoke;
|
|
39
|
+
private invokeOnce;
|
|
40
|
+
}
|
|
41
|
+
export declare function isTransient(message: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Pull one JSON value out of a model reply. Handles the two ways a prompt-enforced
|
|
44
|
+
* schema leaks: a markdown fence around the object, and prose either side of it.
|
|
45
|
+
* Brace scanning is string- and escape-aware so a `}` inside a summary can't end
|
|
46
|
+
* the object early. Returns undefined when nothing parses.
|
|
47
|
+
*/
|
|
48
|
+
export declare function extractJson(text: string): unknown;
|
|
49
|
+
/**
|
|
50
|
+
* Resolve the CLI without a shell. Node's spawn only appends `.exe` on Windows,
|
|
51
|
+
* so PATHEXT is walked by hand — the native installer ships `claude.exe` but an
|
|
52
|
+
* `npm i -g` install leaves only the `claude.cmd` shim, and missing it would make
|
|
53
|
+
* this provider look uninstalled on a machine where it works fine.
|
|
54
|
+
*/
|
|
55
|
+
export declare function resolveClaudeBin(explicit?: string): string | undefined;
|
|
56
|
+
/** True when the `claude` CLI is installed. Cached — this runs per build, not per file. */
|
|
57
|
+
export declare function claudeCliAvailable(explicit?: string): boolean;
|
|
58
|
+
/** Test seam: drop the memoized lookup so a test can flip PATH. */
|
|
59
|
+
export declare function resetClaudeCliCache(): void;
|
|
60
|
+
//# sourceMappingURL=claude-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-cli.d.ts","sourceRoot":"","sources":["../../../src/ai/llm/claude-cli.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAA4B,MAAM,YAAY,CAAC;AAgBjG,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,gFAAgF;AAChF,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;AAE7G,MAAM,WAAW,yBAAyB;IACxC,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,GAAG,CAAC,EAAE,eAAe,CAAC;CACvB;AAiBD,qBAAa,kBAAmB,YAAW,SAAS;IAClD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAC,CAAS;gBAElB,IAAI,EAAE,yBAAyB;IAQrC,MAAM,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAgDrD;;;;;;;OAOG;YACW,MAAM;YAeN,UAAU;CAmCzB;AAeD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGpD;AAkFD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CA0CjD;AAcD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAgBtE;AAID,2FAA2F;AAC3F,wBAAgB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAI7D;AAED,mEAAmE;AACnE,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
|