@vibgrate/cli 2026.813.1 → 2026.814.2

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 (123) hide show
  1. package/DOCS.md +258 -22
  2. package/NOTICE +7 -0
  3. package/README.md +273 -11
  4. package/dist/agent-5ANHRYEI.js +26 -0
  5. package/dist/{agent-N3CP3SPI.js.map → agent-5ANHRYEI.js.map} +1 -1
  6. package/dist/approvals-T2KXPJLV.js +9 -0
  7. package/dist/approvals-T2KXPJLV.js.map +1 -0
  8. package/dist/baseline-WVD6P5IO.js +9 -0
  9. package/dist/{baseline-ZMRZRGFI.js.map → baseline-WVD6P5IO.js.map} +1 -1
  10. package/dist/{checkpoint-4WFZMKEO.js → checkpoint-UYMYMMQO.js} +6 -3
  11. package/dist/checkpoint-UYMYMMQO.js.map +1 -0
  12. package/dist/chunk-2H2U3DC7.js +6 -0
  13. package/dist/{chunk-RT7P5AYU.js.map → chunk-2H2U3DC7.js.map} +1 -1
  14. package/dist/chunk-2U37PFB2.js +64 -0
  15. package/dist/chunk-2U37PFB2.js.map +1 -0
  16. package/dist/{chunk-GOPANQZT.js → chunk-54RGT2T5.js} +3 -3
  17. package/dist/{chunk-GOPANQZT.js.map → chunk-54RGT2T5.js.map} +1 -1
  18. package/dist/{chunk-OYHAF2J2.js → chunk-5GLQNMTI.js} +5 -5
  19. package/dist/{chunk-OYHAF2J2.js.map → chunk-5GLQNMTI.js.map} +1 -1
  20. package/dist/{chunk-EWZKOU66.js → chunk-75LJM5XD.js} +30 -66
  21. package/dist/chunk-75LJM5XD.js.map +1 -0
  22. package/dist/{chunk-KF2QT6RY.js → chunk-7NMXE6KG.js} +4 -4
  23. package/dist/{chunk-KF2QT6RY.js.map → chunk-7NMXE6KG.js.map} +1 -1
  24. package/dist/{chunk-UZP623Y4.js → chunk-7QDHQLUS.js} +4 -4
  25. package/dist/{chunk-UZP623Y4.js.map → chunk-7QDHQLUS.js.map} +1 -1
  26. package/dist/chunk-AJS4EL2C.js +266 -0
  27. package/dist/chunk-AJS4EL2C.js.map +1 -0
  28. package/dist/{chunk-Z3MUWXP3.js → chunk-BH54SLGZ.js} +4 -4
  29. package/dist/{chunk-Z3MUWXP3.js.map → chunk-BH54SLGZ.js.map} +1 -1
  30. package/dist/{chunk-CJNWHXQD.js → chunk-DSUGC7F5.js} +4 -4
  31. package/dist/{chunk-CJNWHXQD.js.map → chunk-DSUGC7F5.js.map} +1 -1
  32. package/dist/{chunk-FBVKQXBH.js → chunk-FOW5IF73.js} +3 -3
  33. package/dist/{chunk-FBVKQXBH.js.map → chunk-FOW5IF73.js.map} +1 -1
  34. package/dist/{chunk-6GQLEDVK.js → chunk-IHLLWBZU.js} +6 -5
  35. package/dist/chunk-IHLLWBZU.js.map +1 -0
  36. package/dist/{chunk-RHKJPTON.js → chunk-IHXNOY3R.js} +208 -56
  37. package/dist/chunk-IHXNOY3R.js.map +1 -0
  38. package/dist/{chunk-5JJBGBP2.js → chunk-JCN6MSXQ.js} +7 -7
  39. package/dist/{chunk-5JJBGBP2.js.map → chunk-JCN6MSXQ.js.map} +1 -1
  40. package/dist/{chunk-YJU7S7N6.js → chunk-KGPX4EUN.js} +4 -4
  41. package/dist/{chunk-YJU7S7N6.js.map → chunk-KGPX4EUN.js.map} +1 -1
  42. package/dist/{chunk-ADP6ITGF.js → chunk-N3XFY3PX.js} +68 -11
  43. package/dist/chunk-N3XFY3PX.js.map +1 -0
  44. package/dist/{chunk-JYM4QT6F.js → chunk-NKFXXP6W.js} +5 -5
  45. package/dist/{chunk-JYM4QT6F.js.map → chunk-NKFXXP6W.js.map} +1 -1
  46. package/dist/{chunk-5ROZODMW.js → chunk-TFAXW7VM.js} +2 -2
  47. package/dist/chunk-TFAXW7VM.js.map +1 -0
  48. package/dist/{chunk-6423BHLN.js → chunk-TNROG5CO.js} +19 -9
  49. package/dist/chunk-TNROG5CO.js.map +1 -0
  50. package/dist/chunk-TVDYEHIM.js +174 -0
  51. package/dist/chunk-TVDYEHIM.js.map +1 -0
  52. package/dist/{chunk-7ZHSSGUF.js → chunk-WQLZSVNF.js} +4 -3
  53. package/dist/chunk-WQLZSVNF.js.map +1 -0
  54. package/dist/{chunk-3WUTQYRY.js → chunk-WWGLVF7D.js} +9 -8
  55. package/dist/chunk-WWGLVF7D.js.map +1 -0
  56. package/dist/{chunk-KBP7GJV6.js → chunk-X76VPOYH.js} +19 -9
  57. package/dist/chunk-X76VPOYH.js.map +1 -0
  58. package/dist/{chunk-IJQOZ6ZD.js → chunk-YNV5M3JW.js} +8 -8
  59. package/dist/chunk-YNV5M3JW.js.map +1 -0
  60. package/dist/{chunk-Z3AYOZ3C.js → chunk-YQNTIBKS.js} +6 -6
  61. package/dist/{chunk-Z3AYOZ3C.js.map → chunk-YQNTIBKS.js.map} +1 -1
  62. package/dist/cli.js +1130 -489
  63. package/dist/cli.js.map +1 -1
  64. package/dist/embed-worker-main.js +4 -3
  65. package/dist/embed-worker-main.js.map +1 -1
  66. package/dist/{ensure-map-PHAJACFF.js → ensure-map-HQ7A5NDL.js} +15 -14
  67. package/dist/{ensure-map-PHAJACFF.js.map → ensure-map-HQ7A5NDL.js.map} +1 -1
  68. package/dist/fastembed-S6YEJYQV.js +292 -0
  69. package/dist/fastembed-S6YEJYQV.js.map +1 -0
  70. package/dist/graph-backend-W2TNTMY7.js +14 -0
  71. package/dist/{graph-backend-4B3MTVIW.js.map → graph-backend-W2TNTMY7.js.map} +1 -1
  72. package/dist/index.d.ts +4 -3
  73. package/dist/index.js +14 -13
  74. package/dist/index.js.map +1 -1
  75. package/dist/{interactive-WUXMXFNM.js → interactive-EW2VJ3BZ.js} +32 -30
  76. package/dist/interactive-EW2VJ3BZ.js.map +1 -0
  77. package/dist/load-64RK5O6C.js +10 -0
  78. package/dist/{load-EUZSV73H.js.map → load-64RK5O6C.js.map} +1 -1
  79. package/dist/{run-outcome-O5PR7ZCK.js → run-outcome-6QNQIHPV.js} +6 -5
  80. package/dist/run-outcome-6QNQIHPV.js.map +1 -0
  81. package/dist/runtime-session-RJHH3KMF.js +21 -0
  82. package/dist/{runtime-session-PPQDTFIK.js.map → runtime-session-RJHH3KMF.js.map} +1 -1
  83. package/dist/session-4BGYASOH.js +16 -0
  84. package/dist/{session-WS7SOVJE.js.map → session-4BGYASOH.js.map} +1 -1
  85. package/dist/session-store-AQUORKWB.js +4 -0
  86. package/dist/{session-store-KGONLWHN.js.map → session-store-AQUORKWB.js.map} +1 -1
  87. package/dist/{stream-json-7MK3QQYG.js → stream-json-GY5N7WZT.js} +76 -24
  88. package/dist/stream-json-GY5N7WZT.js.map +1 -0
  89. package/dist/version-DPAMQW6M.js +4 -0
  90. package/dist/version-DPAMQW6M.js.map +1 -0
  91. package/dist/{vg-mcp-bridge-DQLCHBI6.js → vg-mcp-bridge-IGHJKKSL.js} +11 -10
  92. package/dist/vg-mcp-bridge-IGHJKKSL.js.map +1 -0
  93. package/dist/{vgd-Y25XSQGZ.js → vgd-ORPA5C2K.js} +12 -11
  94. package/dist/vgd-ORPA5C2K.js.map +1 -0
  95. package/dist/worktree-session-D575IQWM.js +82 -0
  96. package/dist/worktree-session-D575IQWM.js.map +1 -0
  97. package/package.json +4 -2
  98. package/dist/agent-N3CP3SPI.js +0 -24
  99. package/dist/baseline-ZMRZRGFI.js +0 -9
  100. package/dist/checkpoint-4WFZMKEO.js.map +0 -1
  101. package/dist/chunk-3WUTQYRY.js.map +0 -1
  102. package/dist/chunk-5ROZODMW.js.map +0 -1
  103. package/dist/chunk-6423BHLN.js.map +0 -1
  104. package/dist/chunk-6GQLEDVK.js.map +0 -1
  105. package/dist/chunk-7ZHSSGUF.js.map +0 -1
  106. package/dist/chunk-ADP6ITGF.js.map +0 -1
  107. package/dist/chunk-EWZKOU66.js.map +0 -1
  108. package/dist/chunk-IJQOZ6ZD.js.map +0 -1
  109. package/dist/chunk-KBP7GJV6.js.map +0 -1
  110. package/dist/chunk-RHKJPTON.js.map +0 -1
  111. package/dist/chunk-RT7P5AYU.js +0 -6
  112. package/dist/chunk-Z7FM3ETS.js +0 -126
  113. package/dist/chunk-Z7FM3ETS.js.map +0 -1
  114. package/dist/graph-backend-4B3MTVIW.js +0 -13
  115. package/dist/interactive-WUXMXFNM.js.map +0 -1
  116. package/dist/load-EUZSV73H.js +0 -9
  117. package/dist/run-outcome-O5PR7ZCK.js.map +0 -1
  118. package/dist/runtime-session-PPQDTFIK.js +0 -20
  119. package/dist/session-WS7SOVJE.js +0 -15
  120. package/dist/session-store-KGONLWHN.js +0 -4
  121. package/dist/stream-json-7MK3QQYG.js.map +0 -1
  122. package/dist/vg-mcp-bridge-DQLCHBI6.js.map +0 -1
  123. package/dist/vgd-Y25XSQGZ.js.map +0 -1
package/DOCS.md CHANGED
@@ -42,7 +42,9 @@ For a quick overview, see the [README](./README.md). This document covers everyt
42
42
  - [vg install / vg uninstall](#vg-install)
43
43
  - [vg lib](#vg-lib)
44
44
  - [vg map / vg hubs / vg areas / vg oddities](#vg-map--vg-hubs--vg-areas--vg-oddities)
45
+ - [vg llm-host](#vg-llm-host)
45
46
  - [vg models](#vg-models)
47
+ - [vg module](#vg-module)
46
48
  - [vg path](#vg-path)
47
49
  - [vg savings](#vg-savings)
48
50
  - [vg serve](#vg-serve)
@@ -52,6 +54,12 @@ For a quick overview, see the [README](./README.md). This document covers everyt
52
54
  - [vg tests](#vg-tests)
53
55
  - [vg tree](#vg-tree)
54
56
  - [vg unknowns](#vg-unknowns)
57
+ - [Holistic Code Specification (vg hcs)](#holistic-code-specification-vg-hcs)
58
+ - [vg hcs extract](#vg-hcs-extract)
59
+ - [vg hcs digest](#vg-hcs-digest)
60
+ - [vg hcs map](#vg-hcs-map)
61
+ - [vg hcs gate](#vg-hcs-gate)
62
+ - [vg hcs validate](#vg-hcs-validate)
55
63
  - [Diagnostics, IDE & runtime](#diagnostics-ide--runtime)
56
64
  - [vg daemon](#vg-daemon)
57
65
  - [vg doctor](#vg-doctor)
@@ -463,6 +471,11 @@ vg scan [path] [--vulns] [--full] [--format text|json|sarif|md] [--out <file>] [
463
471
  | `--package-manifest <file>` | — | JSON or ZIP package-version manifest used for offline/latest lookups (latest bundle: `https://github.com/vibgrate/manifests/latest-packages.zip`) |
464
472
  | `--no-local-artifacts` | — | Do not write `.vibgrate/*.json` scan artifacts to disk |
465
473
  | `--max-privacy` | — | Hardened privacy mode with minimal scanners and no local artifacts |
474
+ | `--no-graph` | — | Skip building the local code map that scan produces after scoring drift |
475
+ | `--project-scan-timeout <seconds>` | `180` | Per-project scan timeout |
476
+ | `--repository-name <name>` | directory / `package.json` name | Override the repository name recorded for this scan |
477
+ | `--force` | — | Always create a fresh ingest, even when the repository is unchanged since the last scan |
478
+ | `--quiet` | — | Suppress promotional output; scan results are unaffected |
466
479
 
467
480
  By default, the scan writes `.vibgrate/scan_result.json`. Use `--no-local-artifacts` or `--max-privacy` to suppress local JSON artifact files.
468
481
 
@@ -490,6 +503,8 @@ Expected results:
490
503
  - Exit code `2` when configured quality gates are exceeded.
491
504
  - When `--push` is enabled, artifact upload is attempted after scan completion.
492
505
 
506
+ **Plan limits never block the scan.** If your workspace is at a plan limit that gates ingestion — repository cap, scan credits, VM minutes — the CLI warns with the reason (and the upgrade link), disables the upload, and runs the **full local scan** anyway, repeating the warning after the results so it isn't lost in the output. Local scoring never depended on the cloud, and now neither does it depend on your plan. Pass `--strict` to keep the old behaviour and fail the command instead, which is usually what you want in CI.
507
+
493
508
  ---
494
509
 
495
510
  ### Vulnerabilities and exposure attribution
@@ -720,13 +735,27 @@ Add `--json` for machine-readable output.
720
735
 
721
736
  ### vg code
722
737
 
723
- Propose a code edit for a plain-language instruction, grounded in the deterministic code graph. `vg code` is **dry-run by default**: it prints the proposed diff and writes nothing.
738
+ A coding **agent** grounded in the deterministic code graph: its search tool resolves symbols and relations from the map, not text matches from a grep. It runs on a local model or a hosted one, and every change it makes to your working tree is approved before it lands.
724
739
 
725
740
  ```bash
741
+ vg code # guided: pick a model, then describe tasks
726
742
  vg code "add a --timeout flag to the scan command"
727
743
  ```
728
744
 
729
- **Agentic sessions.** With a real model, `vg code` is a coding *agent*, not just a one-shot editor: the model is given tools and works in steps — **search the code graph**, read files, check a symbol's blast radius, edit, create/delete files, and run your tests or build — until the task is done. Every mutating step (an edit or a command) is **governed**: you approve it, or run autonomously with `--auto`. Read-only steps (search/read/list/impact) run without prompting. `--single` forces the old one-shot diff; `--max-steps <n>` caps the loop.
745
+ #### Does it write to my disk?
746
+
747
+ Yes — through approved steps, and only those. This is the one thing to be clear about before you run it:
748
+
749
+ | You run | What happens |
750
+ |---|---|
751
+ | `vg code` or `vg code "<instruction>"` at a terminal | The **agent loop**. Read-only steps (search, read, list, impact) run without prompting. Every edit and every command **asks you first**, and writes when you approve. |
752
+ | `… --auto` | The same loop with no prompts. A denylist blocks catastrophic commands. For CI and scripted runs. |
753
+ | `… --single` | The **one-shot planner**: one proposed edit, no tool loop, no commands. **Dry-run by default** — it prints the diff and writes nothing unless you pass `--apply` *and* `--yes`. |
754
+ | `… --mock <file>` | The one-shot path driven by a scripted reply instead of a model (offline; tests, CI, benchmarks). |
755
+
756
+ The agent loop is the default. `--apply` and `--yes` belong to `--single` / `--mock` only — in the agent loop, consent is the per-step approval instead. Without a TTY and without `--auto`, `vg code` refuses to start rather than writing unattended.
757
+
758
+ **How the loop works.** The model is given tools and works in steps — search the code graph, read files, check a symbol's blast radius, edit, create/delete files, and run your tests or build — until the task is done. `--max-steps <n>` caps the loop (default 24).
730
759
 
731
760
  **Guided mode.** Run `vg code` with no instruction at an interactive terminal and it walks you through everything: it builds the code map, then asks where the model should run — a local model, or one of the current top providers (Claude, GPT, Grok, Gemini, …) surfaced live from the catalog — and which model, with an "enter a slug myself" option at every step. Before pulling any local model it runs a memory pre-flight (estimated footprint vs free RAM/VRAM and already-loaded models) and won't pull a model your machine can't run; then it drops into an agent session where you describe tasks and approve each change. For scripts and CI, pass an instruction with `--auto` (or `--mock`) — the agent only prompts at a TTY, so automation never blocks.
732
761
 
@@ -781,17 +810,50 @@ vg code
781
810
 
782
811
  Run it non-interactively with `vg code "add a --timeout flag to scan" --provider ollama --model qwen2.5-coder:7b --auto`, or against a hosted model with `--provider openrouter --model anthropic/claude-3.5-sonnet` (set `OPENROUTER_API_KEY`).
783
812
 
784
- **In a session** you can type slash-commands: `/undo` reverts the last change, `/diff` shows it, `/model` switches model, `/cost` shows the running token/$ cost, `/help` lists them, `/exit` quits.
813
+ **In a session** you can type slash-commands:
814
+
815
+ | Command | What it does |
816
+ |---|---|
817
+ | `/undo` | Revert the files changed by the last task |
818
+ | `/diff` | Show the last change |
819
+ | `/model` | Switch model without leaving the session |
820
+ | `/cost` | Running token/$ cost for the session (local models are free) |
821
+ | `/compact` | Condense the session so far into one checkpoint recap |
822
+ | `/clear` | Explains that each task already starts fresh — nothing to clear |
823
+ | `/help` | List the commands |
824
+ | `/exit` | Quit (an empty line, `exit`, or `quit` also work) |
785
825
 
786
826
  **More session controls:**
787
827
 
788
828
  - `--stream` streams the model's output live as it's generated.
789
829
  - `--verify [command]` runs your tests after the agent finishes and, if they fail, feeds the failures back so it fixes them (uses the `testCommand` from config if you don't name one).
790
- - `--continue` resumes your most recent sessionit recaps what was already done for the model and restores `/undo`.
830
+ - `--continue [id]` resumes a session — your most recent one, or the id you name recapping what was already done for the model and restoring `/undo`.
831
+ - `--reasoning-effort low|medium|high` tells a reasoning-capable model how hard to think (models without the knob ignore it).
832
+ - `--worktree` runs the session in an **isolated git worktree** under `.vibgrate/worktrees`, so an agent can work without touching your checkout. Bare `--worktree` creates one; `--worktree <id>` reuses it. Inspect and land the result with `--worktree-diff <id>` (print the delta as a patch), `--worktree-apply <id>` (apply it onto the main tree via `git apply --3way`), and `--worktree-remove <id>`.
833
+ - `--security-tier <tier>` sets shell isolation for `run_command`: `L0` runs on the host, `L1` uses Seatbelt or bubblewrap where available (`L2`/`L3` are reserved).
791
834
  - A live **token/$ meter** shows after each task and via `/cost` (cost is shown when the model's price is known; local models are free).
792
835
  - **External MCP tools:** list servers under `mcpServers` in `.vibgrate/code.json` and the agent can call their tools (namespaced `mcp__<server>__<tool>`); read-only tools run freely, anything else is approved like a built-in mutating tool. VG Code also **adopts the standard MCP config files** already in your repo — `.mcp.json` (Claude Code), `.cursor/mcp.json` (Cursor), and `.vscode/mcp.json` (VS Code) — and merges them with your `.vibgrate/code.json` (which wins on any name clash), so servers you've already configured for another tool work here with no extra setup. Both local (`command`) and remote (`url`) servers are supported.
793
836
 
794
- **Tools the agent has:** searching is the code graph (`search_code`) — not a grep — plus `read_file`, `list_files`, `graph_impact` (blast radius), **`library_docs`** (version-correct docs for a dependency you actually have installed, so the model uses the right API for your version), `edit_file`, `create_file`, `delete_file`, and `run_command`.
837
+ **Tools the agent has.** Searching is the code graph (`search_code`) — not a grep. Read-only tools run without prompting; the rest are approved per step (or auto-approved under `--auto`).
838
+
839
+ | Tool | What it does | Approval |
840
+ |---|---|---|
841
+ | `search_code` | Search the code graph: symbols and relations, plus a literal sweep for exact phrases and URLs | free |
842
+ | `read_file` / `list_files` | Read a file (or a line range); list files known to the map | free |
843
+ | `graph_impact` | Blast radius of changing a symbol — callers, importers, subtypes | free |
844
+ | `library_docs` | Version-correct docs for a dependency this project actually installs | free |
845
+ | `set_progress` | Maintain the task checklist shown during the run | free |
846
+ | `inspect_task` / `inspect_change` / `verify_change` | Governance steps: assess the task, review a pending change, verify the result | free |
847
+ | `edit_file` / `create_file` / `delete_file` | Change the working tree | **approved** |
848
+ | `apply_patch` | Apply a validated PatchIR multi-op edit transactionally | **approved** per file |
849
+ | `run_command` | Run tests, builds, or any other shell command | **approved** |
850
+ | `read_notebook` / `edit_notebook_cell` | Read a Jupyter notebook; edit one cell | read free · edit **approved** |
851
+ | `web_fetch` / `web_search` | Fetch a URL or search the web — results are size-capped, secret-redacted, and treated as untrusted | **approved** |
852
+ | `browser_*` | Drive a browser: start, navigate, snapshot, click, type, stop | start/navigate **approved** |
853
+ | `spawn_subagent` | Delegate a sub-task to a nested agent (optionally in a worktree) | **approved** |
854
+ | `ask_user` | Ask you a question mid-task | free |
855
+ | `finish` / `abort` | End the task with a summary, or give up | free |
856
+ | `mcp__<server>__<tool>` | Tools from your configured MCP servers | free if read-only, else **approved** |
795
857
 
796
858
  **Safety.** The agent never sends a secrets file (`.env`, keys, credentials) to the model, and redacts stray credential shapes from any file it reads. Under `--auto`, a denylist blocks catastrophic commands (filesystem wipes, `curl … | sh`, force-push, …); interactively you see and approve each command yourself.
797
859
 
@@ -811,31 +873,68 @@ Run it non-interactively with `vg code "add a --timeout flag to scan" --provider
811
873
  }
812
874
  ```
813
875
 
814
- It assembles a small, high-signal context from the map (the relevant symbols, their relations, the blast radius of changing them, and any hard constraints), asks the model you choose for a minimal edit, and applies that edit through a deterministic merge so the change lands exactly where it was meant to.
876
+ | Key | Default | Notes |
877
+ |---|---|---|
878
+ | `provider` | auto | `vibgrate-relay`, `ollama`, `lmstudio`, `foundry-local`, `openrouter`, `litellm`, `openai`, `together`, `llama-cpp` |
879
+ | `model` | — | Model id/slug (or set `VG_CODE_MODEL`) |
880
+ | `auto` | `false` | Run autonomously (auto-approve) by default |
881
+ | `testCommand` | — | The project's test command, surfaced to the agent and used by `--verify` |
882
+ | `denyCommands` | — | Extra regex/substring rules blocked on top of the built-in denylist |
883
+ | `contextWindow` | model default | Override the usable context window (tokens) for compaction sizing |
884
+ | `maxSteps` | `24` | Default step cap for the agent loop |
885
+ | `capsule` | — | Prefer a source-bearing Task Capsule for first context (`--capsule` / `--no-capsule`) |
886
+ | `securityTier` | `L0` | Shell isolation: `L0` host, `L1` Seatbelt/bubblewrap where available (`L2`/`L3` reserved) |
887
+ | `modelProfile` | derived | Overrides merged onto the model-derived profile: `mode`, `capsuleBudgetTokens`, `maxRepairRounds`, `constrainedDecoding`, `securityTier` |
888
+ | `mcpServers` | — | External MCP servers (name → launch spec), merged with `.mcp.json`, `.cursor/mcp.json`, `.vscode/mcp.json`; this file wins on a name clash |
889
+
890
+ A missing or malformed file is simply "no config", never an error.
891
+
892
+ **How an edit is built.** It assembles a small, high-signal context from the map (the relevant symbols, their relations, the blast radius of changing them, and any hard constraints), asks the model for a minimal edit, and applies that edit through a deterministic merge so the change lands exactly where it was meant to. Before an edit is written, its replacement body is scanned against the graph's identifier trie: an edit that references a symbol the graph does not know — and that is not already local to the target file — is **blocked, not merely flagged**.
815
893
 
816
- Writing is opt-in and confirmed. `--apply` walks the full inspect → assess → dry-run → approve → execute → verify → log lifecycle, and still requires your explicit `--yes` (or an interactive confirmation) — there is no write-without-consent path.
894
+ **The one-shot path.** `--single` skips the tool loop and proposes a single edit. That path is dry-run by default; `--apply` walks the full inspect → assess → dry-run → approve → execute → verify → log lifecycle, and still requires your explicit `--yes` (or an interactive confirmation) — there is no write-without-consent path.
817
895
 
818
896
  ```bash
819
- vg code "rename readCfg to readConfig everywhere it is called" --apply --yes
897
+ vg code "rename readCfg to readConfig everywhere it is called" --single --apply --yes
820
898
  ```
821
899
 
822
900
  Pick a backend with `--provider` and `--model`. No model is bundled, and nothing is installed until you first use a backend that needs it:
823
901
 
824
- - **Local** — `--provider ollama` or `--provider lmstudio` (or `--local` to force on-device only, no network).
825
- - **Hosted** — any OpenAI-compatible endpoint: `--provider openrouter` / `litellm` / `openai` / `together`. API keys are read from the environment only (e.g. `OPENROUTER_API_KEY`), never passed as flags.
902
+ - **Local** — a Code Mode pack, `--provider ollama`, `--provider lmstudio`, `--provider foundry-local`, or `--provider llama-cpp --model-path <gguf>` (or `--local` to force on-device only).
903
+ - **Vibgrate Relay** — the first-party hosted router that supplements your local models: `--provider vibgrate-relay`, authenticated with `VIBGRATE_RELAY_TOKEN` instead of a per-provider API key. Set `VIBGRATE_RELAY_URL` to point at staging or a self-hosted deployment.
904
+ - **Other hosted** — any OpenAI-compatible endpoint: `--provider openrouter` / `litellm` / `openai` / `together`. API keys are read from the environment only (e.g. `OPENROUTER_API_KEY`), never passed as flags.
826
905
 
827
- With no `--provider`, `vg code` chooses from what you have already configured (a hosted key, or a locally-pulled model) and never dials a cloud endpoint you didn't set up.
906
+ With no `--provider`, `vg code` chooses from what you have already configured, best first: **Vibgrate Relay** when `VIBGRATE_RELAY_TOKEN` is set (with local fallback if Relay is unreachable), then another configured hosted key, then a locally-pulled model. It never dials a cloud endpoint you didn't set up.
828
907
 
829
908
  | Flag | Default | Description |
830
909
  |------|---------|-------------|
831
- | `<instruction>` | — | What to change, in plain language |
832
- | `--provider <id>` | auto | `ollama`, `lmstudio`, `openrouter`, `litellm`, `openai`, `together`, `llama-cpp` |
910
+ | `<instruction>` | — | What to change, in plain language. Omit it at a TTY for guided mode. |
911
+ | `--provider <id>` | auto | `vibgrate-relay`, `ollama`, `lmstudio`, `foundry-local`, `openrouter`, `litellm`, `openai`, `together`, `llama-cpp` |
833
912
  | `--model <id>` | — | Model id (or set `VG_CODE_MODEL`) |
834
- | `--file <path>` | | Restrict the edit surface to this file (repeatable) |
835
- | `--budget <n>` | `3000` | Approx context token budget |
836
- | `--apply` | — | Write the change (still requires `--yes` or a confirmation) |
913
+ | `--mode <mode>` | auto-fit | Code Mode: `spark` \| `flow` \| `forge` preferred over raw model names |
914
+ | `--model-path <gguf>` | | GGUF path for `--provider llama-cpp` (weights are never auto-downloaded) |
915
+ | `-f, --file <path>` | — | Restrict the edit surface to this file (repeatable) |
916
+ | `-b, --budget <n>` | `3000` | Approx context token budget |
917
+ | `--auto` | — | Autonomous: auto-approve every edit and command (denylist still applies) |
918
+ | `--max-steps <n>` | `24` | Cap the number of agent steps |
919
+ | `--single` | — | One-shot planner (single edit, no tool loop) instead of the agent |
920
+ | `--apply` | — | `--single`/`--mock` only: write the change (still requires `--yes` or a confirmation) |
837
921
  | `--yes` | — | Consent to write, or to a first-use package install, non-interactively |
838
- | `--local` | — | On-device backends only; never touch the network |
922
+ | `--stream` | — | Stream the model output live |
923
+ | `--verify [command]` | — | After the agent finishes, run tests and feed failures back for repair (uses `testCommand` when no command is given) |
924
+ | `--continue [id]` | — | Resume the most recent session, or the given session id (recap + restore `/undo`) |
925
+ | `--reasoning-effort <level>` | model default | How hard a reasoning-capable model should think: `low` \| `medium` \| `high` |
926
+ | `--worktree [id]` | — | Run the session in an isolated git worktree under `.vibgrate/worktrees` |
927
+ | `--worktree-diff` / `--worktree-apply` / `--worktree-remove <id>` | — | One-shot worktree review flow: print the delta, apply it onto the main tree (`git apply --3way`), or remove the checkout |
928
+ | `--capsule` / `--no-capsule` | config | Use (or disable) a source-bearing Task Capsule for first context |
929
+ | `--security-tier <tier>` | `L0` | Shell isolation: `L0` host, `L1` Seatbelt/bubblewrap where available |
930
+ | `--restore-checkpoint <commit>` | — | One-shot: restore the given `--file` paths from a checkpoint commit, then exit (for host UIs) |
931
+ | `--stream-json` | — | Machine protocol: NDJSON agent events on stdout, approval decisions on stdin (host UIs such as the VS Code panel) |
932
+ | `--session` | — | With `--stream-json`: stay open for further turns instead of exiting after one |
933
+ | `--mock <file>` | — | Use a scripted reply instead of a model (offline; tests/CI/benchmarks) |
934
+ | `-o, --out <file>` | — | Write the JSON result to a file (for CI/benchmarks) |
935
+ | `--local` (global) | — | On-device model backends only — no hosted model call, no catalog fetch |
936
+
937
+ `--stream-json` is the protocol **Vibgrate for VS Code** speaks to the CLI: the panel renders the agent's steps, approves or denies each mutating tool call over stdin, and with `--session` keeps one warm graph across turns. It is a supported surface for any host UI, not just ours.
839
938
 
840
939
  Add `--json` for the full machine-readable result (proposed changes, diffs, and the verification summary), or `--out <file>` to write it for CI. Requires a map — run `vg` first if you have not built one.
841
940
 
@@ -1117,6 +1216,29 @@ vg models pull qwen2.5-coder:7b --dry-run # plan only
1117
1216
 
1118
1217
  ---
1119
1218
 
1219
+ ### vg module
1220
+
1221
+ Manage the **optional local modules** — separately-licensed engines the CLI can load through a narrow seam. Two are supported today: `relevance` (semantic ranking kernel) and `hcs` (the [HCS](#holistic-code-specification-vg-hcs) engine behind `vg hcs`).
1222
+
1223
+ ```bash
1224
+ vg module status # what is installed, and whether it loads
1225
+ vg module install hcs # fetch + unpack (prompts once, unless --yes)
1226
+ vg module install relevance --force
1227
+ vg module remove hcs
1228
+ ```
1229
+
1230
+ Installation fetches the module from the npm registry **as a plain tarball**, verifies its integrity, and unpacks it into the Vibgrate cache. Your project is never touched, and nothing from the tarball executes at install time. State is per-user, not per-repo, and your answer to the prompt is recorded — a decline is remembered, so nothing re-prompts on every run.
1231
+
1232
+ | Subcommand | Description |
1233
+ |------------|-------------|
1234
+ | `status` | Installed modules, their versions, whether the seam can load them, and your recorded consent |
1235
+ | `install <name>` | Install a module (`--yes` to skip the prompt, `--force` to reinstall) |
1236
+ | `remove <name>` | Delete an installed module |
1237
+
1238
+ Set `VIBGRATE_NO_KERNEL=1` to disable optional modules entirely — installs are refused and commands that need an engine exit with `6` ([`ENGINE_UNAVAILABLE`](#exit-codes)) rather than silently degrading. `vg module status` reports the disabled state. Add `--json` to any subcommand for machine-readable output.
1239
+
1240
+ ---
1241
+
1120
1242
  ### vg path
1121
1243
 
1122
1244
  Show how A connects to B — shortest path in the call graph.
@@ -1296,6 +1418,112 @@ Add `--json` for machine-readable output.
1296
1418
 
1297
1419
  ---
1298
1420
 
1421
+ ## Holistic Code Specification (vg hcs)
1422
+
1423
+ `vg hcs` turns source into a stream of **deterministic code facts** — one NDJSON line per fact — and then renders, maps, gates, and validates that stream. Same code in, same facts out, on every machine: the whole pipeline is reproducible, so a fact stream is something you can commit, diff, and gate CI on.
1424
+
1425
+ Extraction currently covers **Rust, Ruby, PHP, Dart, Swift, Scala, C++, COBOL, and VB6** — including the legacy stacks that rarely have any machine-readable specification at all. The engine reports its own supported set, and `--language` accepts anything in it; an unsupported value lists the valid ones.
1426
+
1427
+ **The engine is an optional module.** All HCS computation (fact parsing, decoding, scoring, diffing, rendering) runs inside `@vibgrate/hcs-engine`, a separately-licensed WASM sandbox that makes **no network calls and spawns no processes**. The CLI side is plumbing only — read input, call the engine, write output — so every host gets byte-identical results. The module is auto-provisioned on first use (one-line notice), or install it up front with [`vg module install hcs`](#vg-module).
1428
+
1429
+ When the engine is missing and cannot be fetched, every `vg hcs` subcommand exits **`6` (`ENGINE_UNAVAILABLE`)** — deliberately distinct from `2` (`GATE_FAILED`), so CI can never read "engine missing" as a gate verdict.
1430
+
1431
+ **Typical path:** `vg hcs extract` → `vg hcs digest` (read it) / `vg hcs map` (see the system) / `vg hcs gate` (guard CI).
1432
+
1433
+ ```bash
1434
+ vg hcs extract -o facts.ndjson # facts for the current tree
1435
+ vg hcs digest --in facts.ndjson --format md # a readable specification
1436
+ vg hcs map --facts facts.ndjson --format mermaid
1437
+ vg hcs gate --baseline main.ndjson --facts facts.ndjson
1438
+ ```
1439
+
1440
+ ### vg hcs extract
1441
+
1442
+ Extract facts from source into an NDJSON stream. Test files are excluded by default; the walk skips vendored, build, and dependency directories, and files above 2 MiB.
1443
+
1444
+ ```bash
1445
+ vg hcs extract [dir] -o facts.ndjson
1446
+ vg hcs extract src --language rust --include-tests
1447
+ ```
1448
+
1449
+ **Incremental by default.** When the output stream already exists, extraction is incremental: the engine plans from the previous stream's file-hash index, the CLI re-extracts only added and changed files, and the engine merges — reusing unchanged facts byte-for-byte. So a repeated `-o` run costs only the delta, with output identical to a full extraction. Point `--previous` at a different stream to keep the state file separate from the output, or pass `--full` to re-extract everything from scratch (the merged result still refreshes the index, so the next run stays incremental).
1450
+
1451
+ | Flag | Default | Description |
1452
+ |------|---------|-------------|
1453
+ | `[dir]` | `.` | Directory to extract from |
1454
+ | `--language <lang>` | all supported | Extract only this language |
1455
+ | `--include-tests` | — | Include test files (excluded by default) |
1456
+ | `-o, --out <file>` | stdout | Write the NDJSON stream to a file |
1457
+ | `--previous <file>` | the `--out` file | Previous stream to update incrementally (missing file ⇒ full extraction) |
1458
+ | `--full` | — | Ignore the previous stream and re-extract every file |
1459
+
1460
+ ### vg hcs digest
1461
+
1462
+ Render a fact stream as a human-readable specification.
1463
+
1464
+ ```bash
1465
+ vg hcs extract | vg hcs digest --format md -o SPEC.md
1466
+ vg hcs digest --in facts.ndjson --format html --level full --title "Payments service"
1467
+ ```
1468
+
1469
+ | Flag | Default | Description |
1470
+ |------|---------|-------------|
1471
+ | `--in <file>` | stdin | NDJSON fact stream to read |
1472
+ | `-o, --out <file>` | stdout | Write output to a file |
1473
+ | `--format <format>` | `md` | `md`, `json`, or `html` |
1474
+ | `--level <level>` | `concise` | `concise` or `full` |
1475
+ | `--title <title>` | — | Override the document title |
1476
+
1477
+ ### vg hcs map
1478
+
1479
+ Build the **System Map** from a fact stream — the components, their relations, and the structure they imply.
1480
+
1481
+ ```bash
1482
+ vg hcs map --facts facts.ndjson --format mermaid
1483
+ vg hcs map --facts facts.ndjson --profile migration -o map.json
1484
+ ```
1485
+
1486
+ | Flag | Default | Description |
1487
+ |------|---------|-------------|
1488
+ | `--facts <file>` | stdin | NDJSON fact stream to read |
1489
+ | `-o, --out <file>` | stdout | Write output to a file |
1490
+ | `--format <format>` | `json` | `json`, `md`, or `mermaid` |
1491
+ | `--profile <profile>` | — | Consumer projection: `integration`, `migration`, or `governance` |
1492
+
1493
+ Pass the global `--generated-at <iso>` to pin the artifact timestamp for byte-deterministic output.
1494
+
1495
+ ### vg hcs gate
1496
+
1497
+ The **governance gate**: diff two fact streams and fail on material structural regressions. This is the CI-facing command.
1498
+
1499
+ ```bash
1500
+ vg hcs gate --baseline main.ndjson --facts pr.ndjson --format sarif -o hcs.sarif
1501
+ vg hcs gate --baseline main.ndjson --facts pr.ndjson --policy .vibgrate/hcs-gate.json
1502
+ ```
1503
+
1504
+ | Flag | Default | Description |
1505
+ |------|---------|-------------|
1506
+ | `--baseline <file>` | *required* | Baseline NDJSON facts (the "before" stream) |
1507
+ | `--facts <file>` | stdin | Current NDJSON facts (the "after" stream) |
1508
+ | `--policy <file>` | — | Gate policy JSON — thresholds and disabled rules |
1509
+ | `-o, --out <file>` | stdout | Write the result to a file |
1510
+ | `--format <format>` | `text` | `text`, `json`, or `sarif` |
1511
+
1512
+ Exit codes: `0` when the gate passes, **`2`** on a material structural regression, `6` when the engine is unavailable.
1513
+
1514
+ ### vg hcs validate
1515
+
1516
+ Validate a fact stream against the HCS spec. Exits with the spec's Appendix-I conformance code, so a malformed stream is caught before anything downstream consumes it.
1517
+
1518
+ ```bash
1519
+ vg hcs validate facts.ndjson
1520
+ vg hcs validate facts.ndjson --json
1521
+ ```
1522
+
1523
+ Add `--json` for the full machine-readable report (every error with its code and fact id).
1524
+
1525
+ ---
1526
+
1299
1527
  ## Diagnostics, IDE & runtime
1300
1528
 
1301
1529
  Setup health, IDE language server, local workspace daemon, and context-policy pins.
@@ -1937,11 +2165,19 @@ What it **does** collect:
1937
2165
 
1938
2166
  ## Exit Codes
1939
2167
 
1940
- | Code | Meaning |
1941
- | ---- | ------------------------------ |
1942
- | `0` | Success |
1943
- | `1` | Runtime error |
1944
- | `2` | `--fail-on` threshold exceeded |
2168
+ CI and agents branch on these, so they are a stable contract.
2169
+
2170
+ | Code | Name | Meaning |
2171
+ | ---- | --------------------- | ---------------------------------------------------------------------------------------- |
2172
+ | `0` | `OK` | Success |
2173
+ | `1` | `ERROR` | Runtime error |
2174
+ | `2` | `GATE_FAILED` | A gate failed: `--fail-on` threshold exceeded, a drift budget breached, `vg hcs gate` regression, `vg bisect --assert` unsatisfied |
2175
+ | `3` | `NOT_FOUND` | The thing asked for does not exist (unknown symbol, no version history, …) |
2176
+ | `4` | `NON_DETERMINISTIC` | A verification found output that is not reproducible |
2177
+ | `5` | `USAGE_ERROR` | Bad invocation: unknown command, invalid flag value, missing argument |
2178
+ | `6` | `ENGINE_UNAVAILABLE` | A required optional module is not installed and could not be fetched (see [`vg module`](#vg-module)) |
2179
+
2180
+ `6` is deliberately distinct from `2`: a CI gate must never read "engine missing" as a gate verdict.
1945
2181
 
1946
2182
  ---
1947
2183
 
package/NOTICE CHANGED
@@ -19,6 +19,13 @@ THIRD-PARTY COMPONENTS
19
19
 
20
20
  This product bundles or depends on the following open-source components:
21
21
 
22
+ - fastembed-js (MIT, © Anush008) — the dense-embedding backend in
23
+ src/vendor/fastembed is adapted from fastembed-js v2.1.0
24
+ (https://github.com/Anush008/fastembed-js); see that file's header for the
25
+ changes made
26
+ - @anush008/tokenizers (MIT) — native HuggingFace tokenizers bindings
27
+ - onnxruntime-node (MIT) — ONNX Runtime for local embedding inference
28
+ - tar (ISC) — model archive extraction
22
29
  - web-tree-sitter (MIT) — WASM tree-sitter runtime
23
30
  - tree-sitter-wasms (Unlicense) — pre-compiled tree-sitter grammar .wasm files
24
31
  - graphology and graphology-* (MIT) — in-memory graph model and algorithms