graphite-code 0.3.0__py3-none-any.whl

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 (112) hide show
  1. graphite/__init__.py +41 -0
  2. graphite/__main__.py +7 -0
  3. graphite/_cleanup_worker.py +525 -0
  4. graphite/activation.py +164 -0
  5. graphite/agent_hooks.py +577 -0
  6. graphite/agent_settings.py +226 -0
  7. graphite/analyze.py +146 -0
  8. graphite/answer_contract.py +420 -0
  9. graphite/bootstrap.py +210 -0
  10. graphite/buildlock.py +99 -0
  11. graphite/cache.py +131 -0
  12. graphite/channel.py +1325 -0
  13. graphite/cli.py +3053 -0
  14. graphite/cluster.py +111 -0
  15. graphite/config.py +209 -0
  16. graphite/context.py +355 -0
  17. graphite/daemon.py +745 -0
  18. graphite/daemon_health.py +733 -0
  19. graphite/debt.py +118 -0
  20. graphite/dependency_install.py +1597 -0
  21. graphite/detach.py +33 -0
  22. graphite/doctor.py +678 -0
  23. graphite/doctor_probes.py +2100 -0
  24. graphite/engine_identity.py +238 -0
  25. graphite/export/__init__.py +6 -0
  26. graphite/export/html.py +244 -0
  27. graphite/export/json.py +39 -0
  28. graphite/export/md.py +68 -0
  29. graphite/extract/__init__.py +4 -0
  30. graphite/extract/ast.py +1964 -0
  31. graphite/freshness.py +127 -0
  32. graphite/git.py +406 -0
  33. graphite/graph.py +117 -0
  34. graphite/graph_io.py +188 -0
  35. graphite/health.py +147 -0
  36. graphite/hook_entry.py +68 -0
  37. graphite/hookinstall.py +224 -0
  38. graphite/hookshim.py +86 -0
  39. graphite/incident_ledger.py +247 -0
  40. graphite/ingest.py +279 -0
  41. graphite/init.py +791 -0
  42. graphite/io.py +32 -0
  43. graphite/listing.py +51 -0
  44. graphite/llm.py +518 -0
  45. graphite/llm_probe.py +157 -0
  46. graphite/mcp.py +7 -0
  47. graphite/mcp_server.py +450 -0
  48. graphite/natural_query.py +252 -0
  49. graphite/overlays.py +713 -0
  50. graphite/probe_process.py +879 -0
  51. graphite/probe_workspace.py +728 -0
  52. graphite/process_contracts.py +22 -0
  53. graphite/provider_observer.py +397 -0
  54. graphite/query.py +646 -0
  55. graphite/query_plan.py +97 -0
  56. graphite/replacement_audit.py +291 -0
  57. graphite/resolve.py +660 -0
  58. graphite/review.py +782 -0
  59. graphite/routing/__init__.py +5 -0
  60. graphite/routing/approval.py +362 -0
  61. graphite/routing/classifier.py +169 -0
  62. graphite/routing/claude_executor.py +419 -0
  63. graphite/routing/claude_probe.py +102 -0
  64. graphite/routing/cli_identity.py +84 -0
  65. graphite/routing/codex_executor.py +383 -0
  66. graphite/routing/codex_probe.py +93 -0
  67. graphite/routing/context_builder.py +327 -0
  68. graphite/routing/contracts.py +802 -0
  69. graphite/routing/diff_policy.py +468 -0
  70. graphite/routing/edit_apply.py +166 -0
  71. graphite/routing/effort.py +43 -0
  72. graphite/routing/lifecycle.py +771 -0
  73. graphite/routing/lifecycle_operator.py +227 -0
  74. graphite/routing/lifecycle_service.py +555 -0
  75. graphite/routing/lifecycle_storage.py +977 -0
  76. graphite/routing/ollama_executor.py +341 -0
  77. graphite/routing/ollama_probe.py +72 -0
  78. graphite/routing/openrouter_executor.py +338 -0
  79. graphite/routing/openrouter_probe.py +188 -0
  80. graphite/routing/policy.py +815 -0
  81. graphite/routing/probe_runner.py +543 -0
  82. graphite/routing/process_runner.py +523 -0
  83. graphite/routing/profiles.py +554 -0
  84. graphite/routing/prompt.py +58 -0
  85. graphite/routing/registry.py +444 -0
  86. graphite/routing/route_pool.py +629 -0
  87. graphite/routing/route_pool_execution.py +275 -0
  88. graphite/routing/schema_validation.py +169 -0
  89. graphite/routing/service.py +1263 -0
  90. graphite/routing/settings.py +99 -0
  91. graphite/routing/shadow.py +201 -0
  92. graphite/routing/storage.py +4001 -0
  93. graphite/routing/telemetry.py +346 -0
  94. graphite/routing/worktree.py +259 -0
  95. graphite/routing/zai_edit.py +113 -0
  96. graphite/routing/zai_executor.py +191 -0
  97. graphite/routing/zai_probe.py +126 -0
  98. graphite/savings.py +84 -0
  99. graphite/ts_bridge.py +142 -0
  100. graphite/ts_resolver.mjs +314 -0
  101. graphite/typescript_activation.py +1586 -0
  102. graphite/usage_ledger.py +156 -0
  103. graphite/validation.py +148 -0
  104. graphite/watch.py +167 -0
  105. graphite/windows_job.py +368 -0
  106. graphite/windows_startup.py +144 -0
  107. graphite/windows_task.py +212 -0
  108. graphite_code-0.3.0.dist-info/METADATA +743 -0
  109. graphite_code-0.3.0.dist-info/RECORD +112 -0
  110. graphite_code-0.3.0.dist-info/WHEEL +4 -0
  111. graphite_code-0.3.0.dist-info/entry_points.txt +3 -0
  112. graphite_code-0.3.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,743 @@
1
+ Metadata-Version: 2.5
2
+ Name: graphite-code
3
+ Version: 0.3.0
4
+ Summary: Local-first, zero-LLM knowledge graph extraction for codebases.
5
+ Project-URL: Homepage, https://github.com/jared0565/graphite
6
+ Project-URL: Repository, https://github.com/jared0565/graphite
7
+ Project-URL: Changelog, https://github.com/jared0565/graphite/blob/main/CHANGELOG.md
8
+ Project-URL: Issues, https://github.com/jared0565/graphite/issues
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: MacOS :: MacOS X
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Operating System :: POSIX :: Linux
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Software Development :: Quality Assurance
22
+ Requires-Python: >=3.11
23
+ Requires-Dist: networkx>=3.3
24
+ Requires-Dist: pydantic>=2.0
25
+ Requires-Dist: python-louvain>=0.16
26
+ Requires-Dist: rich>=13.0
27
+ Requires-Dist: tree-sitter-go>=0.23
28
+ Requires-Dist: tree-sitter-javascript>=0.23
29
+ Requires-Dist: tree-sitter-python>=0.23
30
+ Requires-Dist: tree-sitter-rust>=0.23
31
+ Requires-Dist: tree-sitter-typescript>=0.23
32
+ Requires-Dist: tree-sitter>=0.23
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
35
+ Requires-Dist: pytest-timeout>=2.3; extra == 'dev'
36
+ Requires-Dist: pytest>=8.0; extra == 'dev'
37
+ Requires-Dist: ruff>=0.5; extra == 'dev'
38
+ Provides-Extra: local-llm
39
+ Provides-Extra: mcp
40
+ Requires-Dist: mcp<3,>=1.0; extra == 'mcp'
41
+ Description-Content-Type: text/markdown
42
+
43
+ # Graphite
44
+
45
+ Local-first, deterministic knowledge graph extraction for codebases. A safer, faster, cheaper replacement for `graphify`.
46
+
47
+ ## Principles
48
+
49
+ - **Inference-free canonical graph** — structural extraction never reads provider credentials or invokes a model.
50
+ - **Local-first** — canonical scan, build, report, check, query, context, impact, watch, and daemon operations stay local.
51
+ - **Isolated enrichment** — model output belongs only in explicit, non-authoritative overlays and never changes canonical artifacts.
52
+ - **Deterministic graph** — same commit produces the same structural graph.
53
+ - **Safe output** — no absolute paths or system metadata leak into artifacts.
54
+ - **Incremental** — content-addressed cache means only changed files are re-parsed.
55
+ - **Multi-language** — structural extraction for TypeScript/JavaScript, Python, Go, and Rust.
56
+ - **TypeScript-aware** — uses the local TypeScript compiler API when available, with heuristic fallback.
57
+
58
+ ## Contributing and project internals
59
+
60
+ - [Contributor guide](CONTRIBUTING.md) — development setup, testing, security expectations, and pull-request conventions.
61
+ - [Architecture guide](ARCHITECTURE.md) — pipeline, module boundaries, artifacts, extension points, and failure behavior.
62
+ - [Release guide](RELEASING.md) — maintainer verification, packaging, tagging, publication, and recovery steps.
63
+
64
+ ## Installation
65
+
66
+ ```bash
67
+ git clone https://github.com/jared0565/graphite
68
+ cd graphite
69
+ pip install -e .
70
+ ```
71
+
72
+ Requires Python 3.11 or newer. No model SDK or provider credential is required
73
+ for canonical graph operation.
74
+
75
+ An editable install is what makes `python -m graphite` work from any repository
76
+ on the machine, which is how every onboarded project reaches it.
77
+
78
+ ## System readiness and optional integrations
79
+
80
+ Use the doctor before enabling optional integrations or when diagnosing a host. The fast command performs read-only checks; deep mode exercises the deterministic pipeline and configured integration boundaries:
81
+
82
+ ```bash
83
+ python -m graphite doctor .
84
+ python -m graphite doctor . --deep
85
+ python -m graphite doctor . --deep --include-llm
86
+ ```
87
+
88
+ Each check is `ready` when usable, `optional` when an absent integration does not affect core operation, `degraded` when a non-core capability needs attention, or `blocked` when a core safety or execution requirement failed. The overall result is the most severe check. The exit code boundary is deliberately narrow: `blocked` exits 1, while `ready`, `optional`, and `degraded` exit 0. Use `--json` for the stable machine-readable report.
89
+
90
+ Fast checks do not write to the selected repository. Deep pipeline work writes only to an external private temporary workspace; the selected repository remains read-only. On Windows, the private parent and workspace directories are created with a protected, inheritable current-user DACL. That is a creation-time guarantee, not a claim that the DACL is re-read during every probe phase.
91
+
92
+ Separately, the no-follow lease validates canonical containment, pinned directory handles, reparse state, and directory identity/bindings before and after each phase. Child processes receive native Job Object containment on Windows or POSIX process group containment, bounded I/O, and one end-to-end deadline. Cleanup is reserved within that deadline. A cleanup timeout is reported as a blocked result, and the cleanup worker retains sole ownership of the live lease while overlapping core probes in the same interpreter/process remain blocked. The local OS user and same-user process namespace remain a best-effort trust boundary: these controls reduce pathname races and contain descendants but cannot fully isolate a malicious process running as the same user.
93
+
94
+ MCP is optional. Before optional activation installs, the mandatory repository package-validation policy requires a trusted local validator. Set `GRAPHITE_PACKAGE_VALIDATOR` to the absolute path of the trusted `validate-packages.cjs` maintained by your environment. If the variable is unset, relative, missing, or does not name an existing file, stop. Never execute a relative repository-local validator. Do not download a validator, search for an unknown replacement, or fall back to an unverified script.
95
+
96
+ Run the applicable fail-closed check and validation command. PowerShell:
97
+
98
+ ```powershell
99
+ if (
100
+ [string]::IsNullOrWhiteSpace($env:GRAPHITE_PACKAGE_VALIDATOR) -or
101
+ -not ([System.IO.Path]::IsPathFullyQualified($env:GRAPHITE_PACKAGE_VALIDATOR)) -or
102
+ -not (Test-Path -LiteralPath $env:GRAPHITE_PACKAGE_VALIDATOR -PathType Leaf)
103
+ ) { throw "GRAPHITE_PACKAGE_VALIDATOR is unset, relative, or missing; stop." }
104
+ node $env:GRAPHITE_PACKAGE_VALIDATOR mcp
105
+ if ($LASTEXITCODE -ne 0) { throw "Package validation failed; stop." }
106
+ ```
107
+
108
+ POSIX shell:
109
+
110
+ ```sh
111
+ if [ -z "${GRAPHITE_PACKAGE_VALIDATOR:-}" ]; then
112
+ printf '%s\n' 'GRAPHITE_PACKAGE_VALIDATOR is unset; stop.' >&2
113
+ exit 1
114
+ fi
115
+ case "$GRAPHITE_PACKAGE_VALIDATOR" in
116
+ /*) ;;
117
+ *) printf '%s\n' 'GRAPHITE_PACKAGE_VALIDATOR must be an absolute POSIX path; stop.' >&2; exit 1 ;;
118
+ esac
119
+ if [ ! -f "$GRAPHITE_PACKAGE_VALIDATOR" ]; then
120
+ printf '%s\n' 'GRAPHITE_PACKAGE_VALIDATOR is missing; stop.' >&2
121
+ exit 1
122
+ fi
123
+ node "$GRAPHITE_PACKAGE_VALIDATOR" mcp || exit 1
124
+ ```
125
+
126
+ Only after the applicable validator command succeeds, enable the declared extra:
127
+
128
+ ```bash
129
+ python -m pip install -e ".[mcp]"
130
+ ```
131
+
132
+ The deep MCP probe launches an isolated interpreter from a guarded distribution-record import manifest. It rejects current working directory, user-site, and attacker-controlled selected-root shadows. The exact origin-verified trusted Graphite source may be inside the selected repository, but it is accepted only when its expected lexical, canonical, filesystem-identity, and module-origin checks all match; overlapping MCP dependency or distribution-metadata roots and alternate Graphite origins remain rejected.
133
+
134
+ TypeScript compiler resolution is also optional. Use the same configured validator and fail-closed fully-qualified-path and existence checks, changing only the validated package argument to `typescript`:
135
+
136
+ ```powershell
137
+ node $env:GRAPHITE_PACKAGE_VALIDATOR typescript
138
+ if ($LASTEXITCODE -ne 0) { throw "Package validation failed; stop." }
139
+ ```
140
+
141
+ ```sh
142
+ node "$GRAPHITE_PACKAGE_VALIDATOR" typescript || exit 1
143
+ ```
144
+
145
+ Use the environment variable commands above, or substitute the clearly marked placeholder below with the trusted absolute validator path for your environment:
146
+
147
+ ```text
148
+ node "<absolute-path-to-validator>" typescript
149
+ ```
150
+
151
+ The angle-bracket value is a placeholder, not a literal path or a repository-local validator. Then use the target project's existing package manager to add the verified `typescript` package locally; do not install it globally. Doctor statically detects project-local TypeScript from package metadata but intentionally never executes or transpiles untrusted project JavaScript. A detected compiler therefore remains optional/unverified rather than being treated as executed proof.
152
+
153
+ The validator target in that command is `validate-packages.cjs typescript`; preserve that package spelling exactly.
154
+
155
+ Canonical commands ignore ambient `GRAPHITE_LLM*` settings and never read `GRAPHITE_LLM_API_KEY`. Optional doctor probing remains a separate, explicit network action. For the explicit doctor probe, local Ollama needs no API key; a cloud probe requires a newly rotated, session-scoped value. Never place a credential in a repository file, persistent parent-process configuration, shell history, or log. If a credential may have been exposed, revoke it in the provider dashboard, remove it from parent secret configuration, rotate it, and restart the parent and all affected processes so they cannot retain the old environment.
156
+
157
+ `--include-llm` is an explicit network action and uses synthetic content only. It sends one bounded constant probe with no repository data, follows no redirects or retries, and reports neither response text, raw error text, nor secrets. The normal enrichment setting `GRAPHITE_LLM_MAX_OUTPUT_TOKENS` defaults to 512 and is clamped to 1–4096. The doctor probe overrides it with a fixed 16-token cap. Keep the LLM probe disabled unless network access to the configured endpoint is approved.
158
+
159
+ ## Machine-wide usage
160
+
161
+ Installed editable, `python -m graphite` works from any project in any shell. The `graphite` / `graphite-mcp` console-script shims are equivalent wherever they are on PATH, but a shim directory that PowerShell and cmd see is not always on Git Bash's PATH — prefer `python -m graphite` in scripts and agent instructions.
162
+
163
+ To onboard a new or existing project, run one command from anywhere:
164
+
165
+ ```bash
166
+ python -m graphite init /path/to/MyApp # agent instructions + gitignore + first build + validation
167
+ python -m graphite bootstrap /path/to/MyApp # minimal variant: gitignore + AGENTS.md + build
168
+ ```
169
+
170
+ The machine-wide daemon (`graphite daemon /path/to/projects`) auto-discovers any project with standard markers (`.git`, `package.json`, `pyproject.toml`, `wrangler.toml`, `go.mod`, `Cargo.toml`) and keeps its graph fresh, so `init` is about wiring agent instructions, not registration. To exclude a directory (and its whole subtree) from supervision — e.g. a third-party SDK checkout — drop a `.graphite-ignore` file in it; the daemon skips it at the next discovery cycle.
171
+
172
+ Set `GRAPHITE_PROJECTS_ROOT` to change the default base folder used by `daemon`, `daemon-status`, `daemon-health`, the Windows startup installers, and init/bootstrap daemon-visibility checks (defaults to the current directory when unset).
173
+
174
+ After upgrading graphite itself, restart the daemon: a long-running daemon keeps executing the code it loaded at start, and daemon state is in-memory only, so a restart both loads the new code and rebuilds every supervised graph — clearing `engine_changed` staleness across all managed projects in one pass.
175
+
176
+ ## Usage
177
+
178
+ ```bash
179
+ # Scan a repo (zero tokens)
180
+ graphite scan .
181
+
182
+ # Build the graph (zero tokens)
183
+ graphite build .
184
+
185
+ # Generate report and interactive viewer
186
+ graphite report .
187
+
188
+ # Query the graph
189
+ # Verbs: depends-on, imported-by, callers, calls, path <a> -> <b>,
190
+ # reaches <a> -> <b> (call/reference edges only), community-of, stats
191
+ # Responses carry schema_version plus a uniform `resolution` list (how each
192
+ # input resolved: exact-id | name | path-suffix | fuzzy, with alternates when
193
+ # ambiguous); the per-verb `match` metadata remains. Not-found errors include
194
+ # a `candidates` list of close matches.
195
+ # Traversal is bounded with generous defaults (path/reaches max_depth 32;
196
+ # neighbor listings max_results 200) — results report truncated + limits, and
197
+ # a no_path with truncated:true means the bound was hit, not proven absence.
198
+ graphite query "depends-on src/lib/db.ts"
199
+ graphite query "callers calculateCommissionPence"
200
+
201
+ # Every query is executed through a canonical, inference-free plan (schema v1).
202
+ # --show-plan includes the plan in the result; --plan-only validates and prints
203
+ # the plan without loading the graph (offline syntax check for agents).
204
+ graphite query "reaches handler -> db.write" --show-plan
205
+ graphite query "callers acceptPairing" --plan-only
206
+
207
+ # Natural-language questions via a FIXED deterministic grammar (no LLM, no
208
+ # network): recognized questions translate to a plan and execute (the matched
209
+ # pattern and plan are included); impact/context/tests questions return the
210
+ # canonical command to run; anything else falls back to ranked search as
211
+ # clarification candidates. The full grammar is listed by capabilities.
212
+ graphite query --natural "who calls acceptPairing?"
213
+ graphite query --natural "what breaks if I change db.ts"
214
+ graphite query --natural "who calls acceptPairing" --plan-only
215
+
216
+ # Deterministic ranked node search (symbol, path, or concept) and
217
+ # machine-readable capability discovery for agents (verbs, target roles,
218
+ # limits, plan version, natural-language grammar)
219
+ graphite search "acceptPairing"
220
+ graphite capabilities --json
221
+
222
+ # Integration contract for agents: docs/agent-integration.md walks the
223
+ # discover -> search -> query -> validate workflow; docs/schemas/*.json
224
+ # publishes the plan/result/search/capabilities JSON schemas (kept in
225
+ # lockstep with live outputs by compatibility tests).
226
+
227
+ # Check whether graph-out is current (names the reason when stale:
228
+ # engine_changed vs source changes; --ignore-engine reports source drift only)
229
+ graphite check .
230
+ graphite check . --ignore-engine
231
+
232
+ # Suggest files and tests affected by a change
233
+ graphite impact src/lib/db.ts
234
+
235
+ # Compact agent-ready context for a file or node
236
+ graphite context src/lib/db.ts
237
+
238
+ # Initialize shared Graphite instructions for AI coding platforms
239
+ graphite init C:/Projects/MyApp
240
+ graphite init . --platform codex --platform claude
241
+ graphite init . --all
242
+
243
+ # Make a project Graphite-ready
244
+ graphite bootstrap C:/Projects/MyApp
245
+
246
+ # Check daemon health
247
+ graphite daemon-health C:/Projects
248
+
249
+ # Audit whether Graphite can replace Graphify for a project
250
+ graphite audit-replacement C:/Projects/MyApp
251
+ ```
252
+
253
+ ## Graphify replacement audit
254
+
255
+ Use the replacement audit before removing legacy Graphify files or ignore entries:
256
+
257
+ ```bash
258
+ graphite audit-replacement C:/Projects/MyApp
259
+ graphite audit-replacement . --json
260
+ graphite audit-replacement . --fail-on-blocker
261
+ ```
262
+
263
+ The audit checks Graphite bootstrap state, graph freshness and validity, daemon visibility, daemon health, physical Graphify remnants, and Graphify text/config references. It reports recommendations but never deletes files automatically.
264
+
265
+ ## Daemon health
266
+
267
+ Use daemon health for operational checks and automation:
268
+
269
+ ```bash
270
+ graphite daemon-health C:/Projects
271
+ graphite daemon-health C:/Projects --json
272
+ graphite daemon-health C:/Projects --fail-on-error
273
+ ```
274
+
275
+ Health checks include status age, daemon process presence, startup launcher installation, failing projects, pending initial builds, and projects that have not built successfully within the configured age window.
276
+
277
+ On Windows, process enumeration may require elevated CIM access. If the operating system denies that read-only observation, daemon health reports `daemon_process_check_unavailable` as a warning rather than claiming the daemon is stopped. Fresh status updates and selected-project health remain usable; run the same health command from an elevated shell when a definitive process-presence check is required.
278
+
279
+
280
+ ## AI platform initialization
281
+
282
+ Use `graphite init` when you enter a new project and want AI coding tools to share one Graphite workflow:
283
+
284
+ ```bash
285
+ graphite init .
286
+ graphite init . --platform codex --platform claude
287
+ graphite init . --platform antigravity --platform visual-studio
288
+ graphite init . --all
289
+ graphite init --list-platforms
290
+ ```
291
+
292
+ When no platform is supplied in an interactive terminal, Graphite presents the common platform list and lets you choose. In non-interactive mode, it defaults to Codex, Claude Code, Antigravity, and Visual Studio/GitHub Copilot. The command creates or updates `GRAPHITE.md` with the required workflow plus optional LLM-enrichment instructions, and updates the selected platform instruction files, including `AGENTS.md`, `CLAUDE.md`, `ANTIGRAVITY.md`, `.github/copilot-instructions.md`, `.cursor/rules/graphite.mdc`, and `.windsurfrules` as applicable. It also keeps default-deny `.gitignore` repositories from hiding those instruction files.
293
+
294
+ ## Project bootstrap
295
+
296
+ Use bootstrap for new or existing projects that should join the Graphite workflow:
297
+
298
+ ```bash
299
+ graphite bootstrap C:/Projects/MyApp
300
+ graphite bootstrap . --no-build
301
+ graphite bootstrap . --json
302
+ ```
303
+
304
+ Bootstrap updates `.gitignore`, creates or extends `AGENTS.md` with the auto-consult workflow, checks daemon visibility, builds the initial graph by default, and validates `graph-out/graph.json`.
305
+
306
+ ## Consent-gated project-local TypeScript activation
307
+
308
+ After `graphite init` or `graphite bootstrap` writes its normal onboarding files, Graphite checks whether the selected root has `.ts`/`.tsx` source or `tsconfig.json` evidence but insufficient project-local TypeScript support. Core graphing does not require the compiler: when activation is unavailable, declined, or ineligible, Tree-sitter extraction and heuristic resolution remain available. Graphite adds only the exact project-local `typescript` development dependency; it does not infer `@types/*` or install frameworks or adjacent tooling. Graphite does not install global TypeScript.
309
+
310
+ Automatic activation requires a contained regular `package.json`, exactly one supported root lockfile, matching `package.json#packageManager` metadata when present, safe control-file dependency sources, no manager-specific configuration that could redirect the operation, a supported external manager executable/version, and project-local TypeScript not already being resolvable. The automatic matrix is npm 8–11 with `package-lock.json`, pnpm 11 with `pnpm-lock.yaml`, and Bun 1 with exactly one of `bun.lock` or `bun.lockb`. Yarn is `guidance_only` because Graphite cannot currently prove a version-independent unattended registry, credential, and lifecycle-script boundary. Missing, nested-only, malformed, conflicting, ambiguous, or unsafe evidence also returns `guidance_only`; Graphite never guesses npm or a workspace package.
311
+
312
+ Eligibility reads and snapshots of `package.json` and the selected lockfile happen before the prompt. In an interactive terminal Graphite prompts exactly once after those checks and before validator, network, or any manifest, lockfile, or dependency-store mutation:
313
+
314
+ ```text
315
+ Project-local TypeScript is missing. Install it with <manager> as a development dependency? [y/N]
316
+ ```
317
+
318
+ The prompt defaults to No. Only an explicit `y` or `yes`, case-insensitively, grants consent. Empty input, EOF, malformed input, and every other response mean `declined`. There is no remembered consent between repositories or invocations. JSON, CI, redirected stdin, redirected stdout, and `--yes` are non-interactive activation modes: they never prompt, validate, or install and instead return a non-mutating result such as `guidance_only`, `already_available`, or `not_applicable`.
319
+
320
+ Consent does not bypass validation. `GRAPHITE_PACKAGE_VALIDATOR` must identify an absolute, existing regular file outside the selected root. Graphite invokes that validator through a trusted external Node executable with the exact argument `typescript`; unset, relative, missing, repository-contained, changed, rejected, or non-file validators fail closed before installation. The automatic path permits only `https://registry.npmjs.org/`, removes ambient registry tokens and repository-controlled overrides, uses fixed argv with lifecycle scripts disabled, closes child stdin, and bounds output, descendants, and the shared deadline. Private registries and enterprise mirrors use the manual workflow under the operator's existing package-management policy.
321
+
322
+ Onboarding files are written before activation and remain preserved. Activation then runs before the normal optional build and validation stages. `installed`, `already_available`, `not_applicable`, `declined`, and `guidance_only` do not make otherwise-successful onboarding fail. Explicitly approved `validation_failed`, `installation_failed`, and `verification_failed` outcomes preserve the completed onboarding files but make `init` or `bootstrap` return exit code 1. Package-manager changes remain visible for review; Graphite performs no automatic rollback that could overwrite concurrent edits.
323
+
324
+ When automatic activation is unavailable, follow this fixed manual workflow in order:
325
+
326
+ 1. Set `GRAPHITE_PACKAGE_VALIDATOR` to your environment's trusted absolute validator path outside the project.
327
+ 2. Fail closed if it is unset, relative, missing, or not a regular file.
328
+ 3. Run the validator for the exact package name `typescript`, for example `node "$GRAPHITE_PACKAGE_VALIDATOR" typescript`, and stop on failure.
329
+ 4. Only after successful validation, use the project's existing package manager to add `typescript` as a local development dependency with lifecycle scripts disabled according to local registry and credential policy.
330
+ 5. Rerun `graphite doctor` or onboarding to confirm project-local detection.
331
+
332
+ Normal `build`, `report`, `check`, `doctor`, `daemon`, `watch`, MCP, agent, and other non-onboarding paths have no TypeScript installation authority. These controls reduce and contain risk; they are not a claim that Graphite or the local host is unhackable.
333
+
334
+ ## Agent auto-consult workflow
335
+
336
+ For non-trivial code changes, agents should consult Graphite before broad file reads or edits:
337
+
338
+ ```bash
339
+ graphite check .
340
+ graphite context src/lib/db.ts
341
+ graphite impact src/lib/db.ts
342
+ graphite query "stats"
343
+ ```
344
+
345
+ Use `graphite context` first when you know the likely file. It returns matched nodes, direct dependencies, direct dependents, impacted files, likely tests, community peers, and coupling risk signals without dumping the full graph.
346
+
347
+ ## Deterministic change review
348
+
349
+ Use `review-changes` to turn a change set into a deterministic review packet before accepting or merging it:
350
+
351
+ ```bash
352
+ # Discover all current Git changes and render a Markdown packet
353
+ graphite review-changes .
354
+
355
+ # Emit stable, machine-readable evidence
356
+ graphite review-changes . --json
357
+
358
+ # Opt in to a non-zero exit only when the packet contains a blocker
359
+ graphite review-changes . --json --fail-on-blocker
360
+
361
+ # Review an explicitly selected scope instead of Git discovery
362
+ graphite review-changes . src/lib/db.py tests/test_db.py --json
363
+
364
+ # Use a graph contained within the project root
365
+ graphite review-changes . src/lib/db.py --graph-json artifacts/graph.json --json
366
+ ```
367
+
368
+ With no selected files, Git discovery covers staged, unstaged, untracked, deleted, and renamed paths. With selected files, the packet uses exactly that explicit scope. The command checks graph freshness and validates the packet graph, derives reverse-dependency impact and likely tests, reports risk signals transparently, and emits concrete acceptance criteria. A custom graph uses the `.graphite_manifest.json` beside that graph for freshness checks.
369
+
370
+ Review freshness and repository ingestion share one hardened Git boundary: Graphite selects an absolute external Git executable, removes inherited `GIT_*` redirection, disables optional locks and repository-configured fsmonitor, and fails closed on Git or protocol errors. Git repositories must be processed from their top-level root; unsupported nested roots are rejected rather than scanned with a filesystem fallback.
371
+
372
+ `review-changes` is zero-LLM, local, deterministic, and model-, vendor-, and agent-agnostic. The command itself makes no network requests and transmits nothing. Its local output intentionally contains repository, project, path, graph, and dependency metadata, so callers must protect logs, pipes, and uploaded output. For a successfully constructed packet, risk does not affect exit status; `--fail-on-blocker` makes evidence blockers return `1`. Invalid inputs and operational errors return `1` independently.
373
+
374
+ For containment and resource safety, a custom `--graph-json` must resolve inside the reviewed project root and may be at most 128 MiB. Git stdout is capped at 16 MiB and Git status/file record counts are capped at 100,000. Evidence strings and paths are validated before they enter the packet, and low-level parser, filesystem, and Git errors are not copied into review output. Resolved output and cache directories are excluded from ingestion, including custom locations, so a build does not ingest its own artifacts or immediately make its graph stale. Packet, impact, and rendered-output cardinality remain residual limits; see the audit.
375
+
376
+ The workflow is informed by the pinned [Karpathy-inspired Think Before Coding, Simplicity, Surgical Changes, and Goal-Driven Execution principles](https://github.com/multica-ai/andrej-karpathy-skills/blob/2c606141936f1eeef17fa3043a72095b4765b9c2/README.md) and the [Superpowers spec-to-plan, TDD, and review philosophy](https://github.com/obra/superpowers/blob/d884ae04edebef577e82ff7c4e143debd0bbec99/README.md). Graphite implements those ideas as local evidence and acceptance packets; it does not impose or require any agent vendor.
377
+
378
+ ## Artifact validation
379
+
380
+ Every successful build validates the public `graph-out/graph.json` bundle before publishing reports and writes `graph-out/.graphite_validation.json`.
381
+
382
+ Use this in CI, pre-commit checks, or before relying on an existing graph:
383
+
384
+ ```bash
385
+ graphite validate
386
+ graphite validate --json
387
+ ```
388
+
389
+ Validation checks include:
390
+
391
+ - node IDs are present and unique
392
+ - edge sources and targets exist
393
+ - metadata counts match actual graph contents
394
+ - generated artifacts do not leak absolute filesystem paths
395
+ - cluster members refer to known nodes
396
+
397
+ Graphite writes artifacts atomically so interrupted builds do not leave partially written JSON, Markdown, or HTML files.
398
+
399
+ ## TypeScript compiler-backed resolution
400
+
401
+ Graphite defaults to `GRAPHITE_TYPESCRIPT_RESOLVER=auto`. For TypeScript/JavaScript projects, it tries to use the project's installed `typescript` package to resolve imports and exports more accurately.
402
+
403
+ This improves:
404
+
405
+ - `tsconfig` path aliases
406
+ - `index.ts` barrels
407
+ - `export ... from` and `export * from` re-exports
408
+ - dynamic imports like `await import("./feature")`
409
+ - type-only import confidence labels
410
+ - file-level runtime symbol references
411
+ - file-level type references
412
+
413
+ If Node or TypeScript is unavailable, Graphite falls back to its deterministic heuristic resolver and keeps building the graph.
414
+
415
+ Controls:
416
+
417
+ ```bash
418
+ graphite --typescript-resolver auto build .
419
+ graphite --typescript-resolver disabled build .
420
+ graphite --typescript-resolver-timeout 5 build .
421
+ graphite --no-typescript-symbol-references build .
422
+ ```
423
+
424
+ Environment variables:
425
+
426
+ - `GRAPHITE_TYPESCRIPT_RESOLVER`: `auto`, `compiler`, `heuristic`, or `disabled`.
427
+ - `GRAPHITE_TYPESCRIPT_RESOLVER_TIMEOUT`: compiler resolver timeout in seconds.
428
+ - `GRAPHITE_TYPESCRIPT_SYMBOL_REFERENCES`: `true` or `false` for compiler-backed symbol/type reference edges.
429
+
430
+ ## Background watcher
431
+
432
+ Use the watcher during active development when you want `graph-out` to stay current automatically:
433
+
434
+ ```bash
435
+ graphite watch . --impact
436
+ ```
437
+
438
+ Behavior:
439
+
440
+ - Builds once on startup unless `--no-initial-build` is set.
441
+ - Polls locally and rebuilds canonical graphs without model inference.
442
+ - Debounces file changes before rebuilding, so save bursts do not cause repeated builds.
443
+ - Uses content hashes, not timestamps, to avoid unnecessary rebuilds.
444
+ - With `--impact`, prints impacted files and likely tests from the previous graph before rebuilding.
445
+ - Ignores ambient provider configuration. Legacy non-`none` `--llm` and provider flags are rejected.
446
+
447
+ Useful controls:
448
+
449
+ ```bash
450
+ graphite watch . --impact --interval 2 --debounce 1
451
+ graphite watch . --once --interval 0.1 --debounce 0
452
+ graphite watch . --no-initial-build
453
+ ```
454
+
455
+ ## Multi-project daemon
456
+
457
+ Use the daemon when you want Graphite to keep every discovered project under `C:\Projects` fresh without manually starting a watcher in each repo:
458
+
459
+ ```bash
460
+ # One-shot health/build pass
461
+ graphite daemon C:\Projects --once
462
+
463
+ # Persistent local supervisor
464
+ graphite daemon C:\Projects
465
+
466
+ # Read latest health/status
467
+ graphite daemon-status C:\Projects
468
+ ```
469
+
470
+ Daemon behavior:
471
+
472
+ - Discovers project roots by markers such as `.git`, `package.json`, `pyproject.toml`, `wrangler.toml`, `go.mod`, and `Cargo.toml`.
473
+ - Skips heavy/tool folders such as `node_modules`, `.git`, `graph-out`, `.cache`, `dist`, `build`, and `_tools`.
474
+ - Writes local operational state to `<base>/.graphite-daemon/status.json` and JSONL logs to `<base>/.graphite-daemon/graphite-daemon.log`.
475
+ - Limits work with `--max-projects`, `--max-depth`, `--max-files-per-project`, `--max-builds-per-cycle`, and `--build-timeout`.
476
+ - Runs child builds with isolated stdin and zero-LLM mode unless LLM flags/environment variables are explicitly enabled.
477
+
478
+ Useful controls:
479
+
480
+ ```bash
481
+ graphite daemon C:\Projects --scan-interval 10 --discover-interval 60
482
+ graphite daemon C:\Projects --max-builds-per-cycle 1 --build-timeout 180
483
+ graphite daemon C:\Projects --no-initial-build
484
+ ```
485
+
486
+ Windows startup integration:
487
+
488
+ ```bash
489
+ # Install as a current-user logon task and start immediately
490
+ graphite daemon-install-windows C:\Projects --start-now
491
+
492
+ # Inspect the scheduled task
493
+ graphite daemon-task-status
494
+
495
+ # Remove the scheduled task
496
+ graphite daemon-uninstall-windows
497
+ ```
498
+
499
+ The installed task is named `GraphiteDaemon-FProjects` by default and uses the same bounded zero-LLM daemon defaults.
500
+
501
+ If Task Scheduler creation is blocked by Windows policy, install the non-admin Startup-folder fallback:
502
+
503
+ ```bash
504
+ graphite daemon-install-startup-windows C:\Projects
505
+ graphite daemon-startup-status C:\Projects
506
+ graphite daemon-uninstall-startup-windows C:\Projects
507
+ ```
508
+
509
+ The fallback writes a hidden VBS launcher in the current user's Startup folder and an idempotent PowerShell launcher in `C:\Projects\.graphite-daemon`.
510
+
511
+ ## Canonical graph and enrichment isolation
512
+
513
+ `scan`, `build`, `report`, `check`, `validate`, `query`, `context`, `impact`, `watch`, and `daemon` are canonical operations. They force an internal no-inference configuration, ignore ambient `GRAPHITE_LLM*` values, exclude provider data from graph artifacts, and reject legacy non-`none` `--llm` or provider flags. `--llm none` remains a temporary compatibility no-op.
514
+
515
+ Model enrichment uses the explicit `graphite overlay build` boundary. The command requires an existing fresh canonical graph plus exact current provider-lifecycle and model identity SHA-256 digests. OpenRouter additionally requires its routing-policy digest. Only lifecycle-governed Ollama and OpenRouter overlays are accepted; Ollama is restricted to loopback HTTP and OpenRouter to its canonical HTTPS API root.
516
+
517
+ Global provider options precede the subcommand. These examples deliberately omit credentials; provide an OpenRouter credential only through an approved session-scoped secret environment, never argv or a repository file:
518
+
519
+ ```powershell
520
+ graphite --llm local --llm-provider ollama --llm-model qwen2.5-coder:7b overlay build . `
521
+ --provider-identity-digest <64-lowercase-hex-lifecycle-digest> `
522
+ --model-identity-digest <64-lowercase-hex-model-digest>
523
+
524
+ graphite --llm cloud --llm-provider openrouter --llm-model <exact-provider-model-id> overlay build . `
525
+ --provider-identity-digest <64-lowercase-hex-lifecycle-digest> `
526
+ --model-identity-digest <64-lowercase-hex-model-digest> `
527
+ --routing-policy-digest <64-lowercase-hex-routing-policy-digest>
528
+ ```
529
+
530
+ The overlay manifest binds the canonical bundle fingerprint, lifecycle/model/routing identities, input/output/time limits, creation time, outcome, and schema version. Successful payloads are content-addressed and the manifest is replaced last, so interruption cannot replace the last valid overlay with a partial result. A failed call writes only a separate allowlisted failure category; raw diagnostics, prompts, credentials, endpoints, and paths are excluded.
531
+
532
+ Overlay files are non-authoritative, independently stale, and stored only beneath `graph-out/overlays/<provider>/<identity-digest>/`. Identity-derived paths reject traversal, symlinks, reparse points, collisions, and output-root escape. Restrictive file permissions are applied. Changing the canonical graph or provider/model/routing identity makes the overlay stale without changing canonical freshness or exit status. `query`, `context`, `impact`, validation, routing, watch, and daemon do not read overlays. Deleting the overlay tree removes annotations without changing canonical artifacts.
533
+
534
+ ## Adaptive development routing
535
+
536
+ Graphite's governed development router invokes only locally installed Claude Code
537
+ and Codex CLIs that are already authenticated through a Claude subscription or a
538
+ ChatGPT subscription. It does not accept or use Anthropic/OpenAI API keys. Ollama is
539
+ not a development-routing provider. Future Ollama/OpenAI-compatible enrichment is
540
+ restricted to the separate overlay boundary, and OpenRouter remains separate from
541
+ governed development routing.
542
+
543
+ Authenticated Claude Code and Codex subscription CLIs are the only governed
544
+ development execution providers.
545
+
546
+ Before routing, install the vendor CLIs through their official distribution paths,
547
+ authenticate them interactively, and verify the exact subscription identity:
548
+
549
+ ```powershell
550
+ claude --version
551
+ claude auth status --json
552
+ codex --version
553
+ codex login status
554
+ ```
555
+
556
+ Claude must report `claude.ai` first-party authentication; Codex must report
557
+ `Logged in using ChatGPT`. Graphite hashes the resolved executable and binds its
558
+ version, adapter protocol, requested model, effective model, effort, permission
559
+ mode, risk ceiling, verification time, and expiry into a capability snapshot.
560
+ The no-edit verifier must report input and output usage. Graphite validates both
561
+ against the exact approved reservation before saving the snapshot; missing,
562
+ invalid, or over-budget usage fails closed and creates no active authority.
563
+ Claude profile verification additionally requires one schema-constrained turn and
564
+ an exact terminal `structured_output` object; free-text output is never verification
565
+ authority. Ordinary task execution remains outside this verification-only schema.
566
+ Profile evidence is explicit and short-lived. A CLI update, executable replacement,
567
+ authentication change, effective-model mismatch, or expired snapshot fails closed.
568
+ Capability evidence helps establish eligibility; it is not authorization authority.
569
+
570
+ Provider lifecycle state is stored separately from canonical graph artifacts. The
571
+ states are `discovered`, `compatible`, `verification_required`, `active`,
572
+ `incompatible`, and `unavailable`. A changed executable hash or patch version gets
573
+ a bounded standard probe; a minor version or capability change gets an expanded
574
+ probe; a major version leaves the provider `incompatible` until a new compatibility
575
+ policy is separately approved. Passing a probe moves an identity only to
576
+ `verification_required`, never directly to `active`.
577
+
578
+ The daemon may observe and persist sanitized lifecycle transitions, but it cannot
579
+ activate a provider or add provider facts to the canonical graph. Immediately
580
+ before approval consumption, the lazy execution check re-observes the exact runtime
581
+ identity and is authoritative even when daemon state is stopped or stale. Failure
582
+ or corruption in one provider lifecycle boundary fails that provider closed without
583
+ blocking canonical scan, build, check, query, watch, daemon builds, or another
584
+ independent provider boundary.
585
+
586
+ Lifecycle operator commands open the existing lifecycle database read-only, enforce
587
+ pages of 1–100 records, and emit the same bounded public fields in compact JSON or
588
+ indented human-readable form. They never create missing state or expose executable
589
+ paths, endpoint query strings, credentials, prompts, or raw diagnostics:
590
+
591
+ ```powershell
592
+ graphite lifecycle list . --limit 50 --json
593
+ graphite lifecycle status . --boundary-digest <64-lowercase-hex> --json
594
+ graphite lifecycle history . --boundary-digest <64-lowercase-hex> --limit 50
595
+ graphite lifecycle policy inspect . --boundary-digest <64-lowercase-hex> --json
596
+ ```
597
+
598
+ `lifecycle policy prepare` creates a content-hashed policy candidate only for the
599
+ exact current incompatible identity. It does not persist, promote, or activate the
600
+ candidate; promotion requires a separate human-authorized operation. `graphite lifecycle verification prepare`
601
+ similarly creates the complete manifest for one exact
602
+ `verification_required` identity and stops before inference. The manifest fixes the
603
+ model, effort, token/time/cost bounds, fixture commit, graph and response-contract
604
+ hashes, one attempt, no fallback, no resume, and no substitution. Display and review
605
+ of either candidate grant no execution authority.
606
+
607
+ ```powershell
608
+ graphite route recommend . --objective "Review listing search" --target src/search.py
609
+ graphite route run . --objective "Review listing search" --target src/search.py
610
+ graphite route review . --task-id task-identifier
611
+ graphite route accept . --task-id task-identifier
612
+ graphite route reject . --task-id task-identifier
613
+ graphite route cleanup . --task-id task-identifier
614
+ graphite route status . --json
615
+ graphite route policy . --json
616
+ ```
617
+
618
+ `route recommend` is offline and read-only. It requires a fresh validated graph and
619
+ a current verified capability snapshot. `route run` creates a detached worktree at
620
+ the approved commit, prints the exact provider/model/effort/permission manifest, and
621
+ then asks for consent. Approval defaults to No. Non-TTY input/output, JSON mode, CI,
622
+ and `--yes` cannot grant consent. Approval is signed, short-lived, single-use,
623
+ snapshot-bound, prompt-hash-bound, commit-bound, and token-bound. It is consumed
624
+ immediately before exactly one provider process.
625
+
626
+ The provider may edit only the isolated worktree under the selected permission
627
+ mode. Graphite rejects symlinks/reparse points, nested repositories, submodule
628
+ changes, case collisions, out-of-scope files, excessive file/byte counts, identity
629
+ drift, and diff drift. It runs bounded, credential-free validation and records a
630
+ content hash—not diff contents. Provider output remains untrusted and is never
631
+ validation or merge authority.
632
+
633
+ High-risk work requires a second, separately approved, read-only review by the
634
+ other provider. The reviewer receives an ephemeral synthetic diff and cannot edit.
635
+ `route accept` rechecks the diff and validation evidence, then creates a detached,
636
+ cherry-pickable commit; it never merges the source branch. `route reject` records the
637
+ human verdict. `route cleanup` is a separate destructive authority step.
638
+
639
+ There is no automatic retry, arbitrary provider/model switch, session reuse,
640
+ acceptance, cleanup, cherry-pick, or merge. The sole automatic fallback is a bounded
641
+ one-step advance to the other provider when both exact candidates were selected and
642
+ approved in the same immutable route pool and the first returns the allowlisted
643
+ `capacity_unavailable` category before producing output or side effects. Every other
644
+ failure remains failed and requires a new approval flow. Legacy Ollama executions
645
+ are retained as read-only history and cannot be replayed as Claude or Codex attempts.
646
+
647
+ Telemetry is append-only and restricted to provider/profile identity, category and
648
+ risk, latency, reported token usage, diff size, validation outcome, defect classes,
649
+ rework count, human verdict, and provenance. Source, prompts, responses, diff
650
+ contents, paths, secrets, and raw diagnostics have no telemetry field. Subscription
651
+ cost is `unknown`, never zero. Learning can create a signed candidate and comparison
652
+ evidence, but cannot change the provider allowlist, permission ceiling, risk
653
+ ceilings, or autonomy. Promotion and rollback both require interactive human
654
+ approval and never delete evidence.
655
+
656
+ ### Schema-v4 to schema-v5 migration and rollback
657
+
658
+ Stop all Graphite routing writers before upgrade or rollback. On the first v5 open,
659
+ Graphite creates `backups/events-schema-v4.sqlite3` and
660
+ `backups/events-schema-v4.sha256.json`, verifies the backup is schema v4 and passes
661
+ SQLite integrity and foreign-key checks, then performs the v5 lifecycle-binding
662
+ migration. Historical v4 rows remain readable but do not acquire invented lifecycle
663
+ authority. After migration, run `graphite route status . --json`, SQLite
664
+ `PRAGMA integrity_check`, and `PRAGMA foreign_key_check`, then preserve both backup
665
+ files.
666
+
667
+ Rollback is a database restore, not an in-place downgrade:
668
+
669
+ 1. Stop every process that can write `.graphite/routing/events.sqlite3`.
670
+ 2. Verify the backup SHA-256 against `backups/events-schema-v4.sha256.json` and run
671
+ SQLite `PRAGMA integrity_check` and `PRAGMA foreign_key_check` against the backup.
672
+ 3. Preserve the current v5 database for incident analysis, then atomically restore
673
+ the verified v4 backup as `events.sqlite3`.
674
+ 4. Restore the matching v4 application build and confirm the schema version and
675
+ historical row counts with its read-only status path before allowing writers.
676
+
677
+ If the v5 database is partially migrated, the backup marker is absent/mismatched,
678
+ or integrity fails, keep routing stopped. Restore the verified backup or deploy a
679
+ tested forward fix; do not hand-edit schema metadata or delete evidence.
680
+
681
+ Incident response follows the same containment rule: stop routing, preserve the
682
+ database and worktree evidence, revoke an affected subscription session when
683
+ credential exposure is suspected, and resume only after explicit review.
684
+
685
+ Provider environment variables are reserved for explicit doctor probes and the
686
+ overlay boundary. Canonical commands do not read them:
687
+
688
+ - `GRAPHITE_LLM`: `none`, `auto`, `local`, or `cloud`.
689
+ - `GRAPHITE_LLM_PROVIDER`: `ollama`, `openai-compatible`, `openai`, `openrouter`, `groq`, `lmstudio`, or `vllm`.
690
+ - `GRAPHITE_LLM_MODEL`: model name.
691
+ - `GRAPHITE_LLM_BASE_URL`: provider base URL.
692
+ - `GRAPHITE_LLM_API_KEY`: provider API key; do not commit this.
693
+ - `GRAPHITE_LLM_TIMEOUT`: request timeout seconds.
694
+ - `GRAPHITE_LLM_MAX_INPUT_CHARS`: prompt input budget.
695
+ - `GRAPHITE_LLM_MAX_OUTPUT_TOKENS`: overlay output-token budget, clamped to 1–4096.
696
+
697
+ These settings never appear in canonical manifests or reports.
698
+
699
+ ## Output
700
+
701
+ Artifacts are written to `graph-out/`:
702
+
703
+ - `graph.json` — bundled graph for external tools
704
+ - `GRAPH_REPORT.md` — human-readable audit
705
+ - `graph.html` — interactive viewer
706
+ - `.graphite_*.json` — intermediate pipeline artifacts
707
+
708
+ ## Claude Code skill
709
+
710
+ A skill template lives at `skill/SKILL.md`. To install, from a clone of this
711
+ repository:
712
+
713
+ ```bash
714
+ mkdir -p ~/.claude/skills/graphite
715
+ cp skill/SKILL.md ~/.claude/skills/graphite/SKILL.md
716
+ ```
717
+
718
+ Then use `/graphite [path]` inside Claude Code. The skill defaults to zero-LLM mode.
719
+
720
+ ### MCP server for Claude Code
721
+
722
+ Complete the mandatory package-validation policy and MCP activation steps in [System readiness and optional integrations](#system-readiness-and-optional-integrations). Do not bypass or reorder the validator and install steps.
723
+
724
+ Then configure Claude Code (Desktop) to use the local server. Add this to your `claude_desktop_config.json`:
725
+
726
+ ```json
727
+ {
728
+ "mcpServers": {
729
+ "graphite": {
730
+ "command": "python",
731
+ "args": ["-m", "graphite.mcp"],
732
+ "cwd": "C:/Projects/YourProject"
733
+ }
734
+ }
735
+ }
736
+ ```
737
+
738
+ Once configured, Claude can call these tools automatically:
739
+
740
+ - `graphite_query` — e.g. `depends-on db.ts`, `imported-by db.ts`, `path article-gen/route.ts -> db.ts`, `stats`
741
+ - `graphite_community` — list the community around a node
742
+ - `graphite_summary` — stats, god nodes, entry points, surprising connections
743
+ - `graphite_refresh` — rebuild and reload the graph