graphlin 0.1.3 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/README.md +12 -3
  4. package/docs/decision-service.md +393 -0
  5. package/docs/extension-authoring.md +553 -0
  6. package/docs/model-api.md +293 -0
  7. package/docs/usage.md +472 -0
  8. package/docs/visualizer-views.md +240 -0
  9. package/node_modules/@vscode/tree-sitter-wasm/LICENSE +21 -0
  10. package/node_modules/@vscode/tree-sitter-wasm/README.md +36 -0
  11. package/node_modules/@vscode/tree-sitter-wasm/SECURITY.md +41 -0
  12. package/node_modules/@vscode/tree-sitter-wasm/cgmanifest.json +16 -0
  13. package/node_modules/@vscode/tree-sitter-wasm/package.json +42 -0
  14. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-bash.wasm +0 -0
  15. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-c-sharp.wasm +0 -0
  16. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-cpp.wasm +0 -0
  17. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-css.wasm +0 -0
  18. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-go.wasm +0 -0
  19. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-ini.wasm +0 -0
  20. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-java.wasm +0 -0
  21. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-javascript.wasm +0 -0
  22. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-php.wasm +0 -0
  23. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-powershell.wasm +0 -0
  24. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-python.wasm +0 -0
  25. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-regex.wasm +0 -0
  26. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-ruby.wasm +0 -0
  27. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-rust.wasm +0 -0
  28. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-tsx.wasm +0 -0
  29. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-typescript.wasm +0 -0
  30. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter.js +4075 -0
  31. package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter.wasm +0 -0
  32. package/node_modules/@vscode/tree-sitter-wasm/wasm/web-tree-sitter.d.ts +1027 -0
  33. package/package.json +78 -9
  34. package/plugin.json +4 -2
  35. package/runtime/architecture/analysis.mjs +344 -0
  36. package/runtime/architecture/controller.mjs +209 -0
  37. package/runtime/architecture/evidence.mjs +108 -0
  38. package/runtime/architecture/profile.mjs +56 -0
  39. package/runtime/core/evidence.mjs +43 -9
  40. package/runtime/core/graph.mjs +11 -6
  41. package/runtime/core/privacy.mjs +1 -0
  42. package/runtime/daemon/auth.mjs +7 -3
  43. package/runtime/daemon/diagnostics.mjs +1 -1
  44. package/runtime/daemon/extension-api.mjs +203 -0
  45. package/runtime/daemon/lineage.mjs +70 -0
  46. package/runtime/daemon/manager.mjs +9 -6
  47. package/runtime/daemon/model-api.mjs +728 -0
  48. package/runtime/daemon/model-persistence.mjs +220 -0
  49. package/runtime/daemon/server.mjs +81 -14
  50. package/runtime/daemon/settings.mjs +11 -3
  51. package/runtime/decisions/broker.mjs +349 -0
  52. package/runtime/decisions/contracts.mjs +179 -0
  53. package/runtime/decisions/evaluation.mjs +305 -0
  54. package/runtime/decisions/faults.mjs +32 -0
  55. package/runtime/decisions/index.mjs +818 -0
  56. package/runtime/decisions/profiles.mjs +93 -0
  57. package/runtime/decisions/questions.mjs +268 -0
  58. package/runtime/discovery/index.mjs +2 -0
  59. package/runtime/discovery/inventory.mjs +160 -0
  60. package/runtime/discovery/parser.mjs +40 -0
  61. package/runtime/discovery/structure.mjs +232 -0
  62. package/runtime/extensions/contracts.mjs +59 -0
  63. package/runtime/extensions/frame.mjs +64 -0
  64. package/runtime/extensions/index.mjs +9 -0
  65. package/runtime/extensions/manifest.mjs +95 -0
  66. package/runtime/extensions/packages.mjs +222 -0
  67. package/runtime/extensions/profiles.mjs +36 -0
  68. package/runtime/extensions/projection.mjs +130 -0
  69. package/runtime/extensions/registry.mjs +285 -0
  70. package/runtime/extensions/scene.mjs +105 -0
  71. package/runtime/extensions/sdk.d.ts +205 -0
  72. package/runtime/extensions/sdk.mjs +88 -0
  73. package/runtime/jev/index.mjs +13 -777
  74. package/runtime/jev/provider.mjs +101 -0
  75. package/runtime/jev/questions.mjs +16 -258
  76. package/runtime/jev/wire.mjs +17 -25
  77. package/runtime/model/changes.mjs +42 -0
  78. package/runtime/model/history.mjs +124 -0
  79. package/runtime/model/index.mjs +2 -0
  80. package/runtime/model/project-model.mjs +1020 -0
  81. package/runtime/model/records.mjs +240 -0
  82. package/runtime/pipeline.mjs +267 -55
  83. package/runtime/platform.mjs +254 -0
  84. package/runtime/visualizers/blocks.mjs +5 -0
  85. package/runtime/visualizers/c4.mjs +154 -0
  86. package/runtime/visualizers/changes.mjs +24 -0
  87. package/runtime/visualizers/code.mjs +5 -0
  88. package/runtime/visualizers/index.mjs +23 -0
  89. package/runtime/visualizers/structure.mjs +120 -0
  90. package/runtime/visualizers/timeline.mjs +66 -0
  91. package/runtime/web/app.js +225 -63
  92. package/runtime/web/extension-frame.js +128 -0
  93. package/runtime/web/index.html +38 -1
  94. package/runtime/web/model-client.js +162 -0
  95. package/runtime/web/platform.js +445 -0
  96. package/runtime/web/scene.js +111 -0
  97. package/runtime/web/style.css +51 -0
  98. package/schemas/graph.schema.json +4 -1
  99. package/scripts/arguments.mjs +5 -1
  100. package/scripts/build-packages.mjs +6 -2
  101. package/scripts/control.mjs +1 -1
  102. package/scripts/daemon.mjs +2 -1
  103. package/scripts/extensions.mjs +44 -0
  104. package/scripts/graphlin.mjs +23 -3
  105. package/scripts/onboarding.mjs +10 -3
  106. package/scripts/validate-packages.mjs +54 -8
package/docs/usage.md ADDED
@@ -0,0 +1,472 @@
1
+ # Graphlin user guide
2
+
3
+ For your first run, follow the [two-step quick start](../README.md#get-started).
4
+
5
+ A local plugin for live architecture and activity diagrams while a coding agent works.
6
+
7
+ ![Graphlin's Sketchbook diagram showing function calls, a cache write, and a browser-to-service connection](images/graphlin-preview.png)
8
+
9
+ *A close-up from the offline demo. [See the full diagram](images/graphlin-overview.png).*
10
+
11
+ **Development preview.** Install from npm with the command below, or use a
12
+ checkout. Releases pass the full CI matrix; see [releasing](releasing.md) for
13
+ the publishing workflow.
14
+
15
+ ## Guided setup
16
+
17
+ In your project's terminal:
18
+
19
+ ```sh
20
+ npx --yes graphlin@latest
21
+ ```
22
+
23
+ The first run detects host CLIs. If only one is available it selects that host;
24
+ otherwise choose **claude**, **codex**, or **both**. Choose **source** to permit locally filtered source excerpts, user
25
+ prompts, and public agent messages to reach TypeSafe. Choose **local** to parse
26
+ supported source entirely on your machine, or **metadata** to inventory paths
27
+ without opening source files. Local and metadata modes need no API key. Source mode offers a masked key
28
+ prompt when no key is available. Keys never belong in command arguments or chat.
29
+
30
+ Graphlin registers its local marketplaces and installs through the native host
31
+ CLIs for your user account. It preserves unrelated host configuration. Versioned
32
+ packages live under `~/.local/state/graphlin/plugins/graphlin/<version>`, outside
33
+ the npm cache. The viewer opens automatically and stays in the foreground;
34
+ **Ctrl+C** stops it. `--no-open` suppresses browser opening.
35
+
36
+ In a second terminal in the same project, run `claude` or `codex`. Accept the
37
+ project trust prompt. Confirm Graphlin is enabled using Claude's `/plugin`;
38
+ in Codex, use `/hooks` to review and trust Graphlin's hooks. Start a new host
39
+ session after installation. If using a custom data directory, copy the printed
40
+ agent command so the hooks inherit the same `GRAPHLIN_DATA_DIR`.
41
+
42
+ On subsequent runs, the bare command reuses saved setup. To configure without
43
+ starting a viewer, append `init`. A checkout can use
44
+ `node scripts/graphlin.mjs init`. Explicit `start` opens the viewer without
45
+ installing host plugins; omitted policy flags reuse current or saved consent.
46
+ `--no-source` explicitly opts out. A new project without consent is metadata only.
47
+ `--local-source` enables local parsing without remote classification.
48
+
49
+ ## Explore the project
50
+
51
+ The viewer inventories the project before an agent connects. With source
52
+ permission it progressively parses JavaScript, TypeScript, TSX, and Python.
53
+ Other languages retain file-level scopes and show their unsupported coverage.
54
+ The drawing limit does not limit the project model.
55
+
56
+ Choose Code, Blocks, C4, Changes, or Activity timeline. Blocks shows actual
57
+ containment; C4 requires supported architectural interpretations and keeps
58
+ ambiguous responsibilities unknown. Use **Set baseline now** to compare a
59
+ task's changes; discovery of existing code is not automatically creation.
60
+ Search with `/`, clear with Escape, and turn off **Follow agent** to explore
61
+ without camera movement.
62
+
63
+ After the source scan, Graphlin automatically discovers application and component
64
+ boundaries for C4. This requires source-transmission consent and a configured
65
+ decision provider. In the live C4 view, choose **Discover architecture** to run
66
+ discovery again. As source edits are observed, Graphlin updates affected boundaries
67
+ incrementally. Architecture documents are optional; unsupported or ambiguous
68
+ boundaries remain unknown.
69
+
70
+ [View controls and limitations](visualizer-views.md) ·
71
+ [Install or author a visualizer](extension-authoring.md) ·
72
+ [Local read API](model-api.md) · [Replace the decision provider](decision-service.md)
73
+
74
+ ## Consent and keys
75
+
76
+ Consent belongs to the canonical project. The key and installed host list are
77
+ shared within the data directory. The key is kept in a private user settings
78
+ file (0600) in a private directory (0700), separate from evidence and exports.
79
+ Source-enabled `init` also saves an environment-provided key for later launches.
80
+ `TYPESAFE_API_KEY` overrides the saved key; an explicitly empty value disables
81
+ the saved key, so unset it to use the saved credential.
82
+
83
+ To replace an expired or incorrect saved key, run the npm command
84
+ with `init --replace-key`, or `node scripts/graphlin.mjs init --replace-key`
85
+ from a checkout. Replacement uses the masked terminal prompt; no command-line
86
+ key value is accepted. Restart the viewer to load the new key. Use `doctor`
87
+ to inspect setup and classifier state; it does not make a paid key-validation call.
88
+
89
+ Non-interactive commands never wait for Graphlin prompts. Specify a host and
90
+ source choice explicitly, for example:
91
+
92
+ ```sh
93
+ npx --yes graphlin@latest init --host codex --no-source
94
+ ```
95
+
96
+ A pending installation can resume from the bare command using already saved
97
+ project consent, including without a terminal. New projects still require an
98
+ explicit consent choice.
99
+
100
+ With `--allow-source`, a key must already be saved or supplied securely through
101
+ the environment. Use the interactive prompt to save a key. Missing CLIs,
102
+ cancelled setup, and failed host commands produce errors; each completed host
103
+ installation is recorded separately so a partial failure is visible. Installing
104
+ a plugin does not prove its hooks are active or its classifier key is valid.
105
+ Graphlin makes no key-validation request during setup.
106
+
107
+ Setup checks existing marketplace registrations before retrying. A name collision
108
+ with an unrelated `graphlin-local` marketplace is reported without replacing it.
109
+ Version upgrades update every recorded host, even when only one is selected,
110
+ so the shared version stays consistent. A failed upgrade retains the old version
111
+ until all hosts finish. If Codex's marketplace rebind fails after its old
112
+ registration was removed, it is recorded as pending rather than installed.
113
+ The next bare Graphlin run resumes unfinished hosts, including a partially
114
+ completed first installation. Existing keys and Graphlin history remain.
115
+
116
+ To reopen the viewer with a fresh one-use browser URL, use `graphlin open`
117
+ (or append `open` to the npm command). It starts a detached viewer
118
+ if needed. Use `graphlin stop` to stop it.
119
+
120
+ ## Uninstall
121
+
122
+ ```sh
123
+ npx --yes graphlin@latest uninstall
124
+ ```
125
+
126
+ This removes Graphlin from the recorded hosts **for all projects**. Use
127
+ `--host claude`, `--host codex`, or `--host both` to choose explicitly, including
128
+ a manually installed Graphlin plugin. The native host CLIs remove only
129
+ `graphlin@graphlin-local`; unrelated plugins and settings remain intact.
130
+ Claude receives `--keep-data`. Keys, Graphlin history, generated packages, and
131
+ marketplace registrations remain for recovery or reinstall.
132
+
133
+ Uninstall resets source and evidence-persistence consent for the current
134
+ project. It does not change an already running viewer's active policy; stop it
135
+ with `graphlin stop`. Other projects retain their consent. A failed host removal
136
+ is reported and remains in the installation record.
137
+
138
+ The design uses Jev at two principal stages: **intelligent intake** (semantic normalization, contextual redaction, and candidate extraction) and **architecture decisions**. Focused code snippets go directly to Noul questions such as “does this function implement a database write?”, with optional Score evidence-strength diagnostics. Parsers help select context and resolve references; a library-specific semantic analyzer is not required for every relationship. A shared decision service can also support bounded alignment, grouping, enrichment, and contradiction checks. Local code owns privacy enforcement, evidence validity, precise drawing operations, and rendering.
139
+
140
+ ## Try it
141
+
142
+ Requires Node.js 22.14+ on macOS or Linux. There are no package dependencies or
143
+ required build steps.
144
+
145
+ ```sh
146
+ npm run demo
147
+ ```
148
+
149
+ Open the local URL printed by the command. The demo uses synthetic source files
150
+ and recorded classifier answers; it makes no network API requests. It runs the
151
+ actual event normalization, evidence, decision, graph, and viewer components.
152
+ The command stays in your terminal. Press **Ctrl+C** to stop the service.
153
+ `start` behaves the same way; use `--background` only when you want it detached.
154
+
155
+ Starting again for the same canonical project and data directory reuses the
156
+ running service and port. A fresh one-use browser token does not mean a new
157
+ server. A foreground start can join an existing service; Ctrl+C stops that
158
+ joined service too. Separate projects or data directories have separate
159
+ services.
160
+
161
+ For your own project, explicitly start with metadata only:
162
+
163
+ ```sh
164
+ node scripts/graphlin.mjs start --project /path/to/your/app --no-source
165
+ ```
166
+
167
+ Source classification requires a TypeSafe key and explicit permission to
168
+ transmit sanitized excerpts:
169
+
170
+ ```sh
171
+ node scripts/graphlin.mjs init --project /path/to/your/app
172
+ node scripts/graphlin.mjs start --project /path/to/your/app
173
+ ```
174
+
175
+ Choose source mode and enter the key at the masked prompt. The key is read by
176
+ the daemon and never sent to the browser or inherited by installer/browser
177
+ subprocesses. Existing secure `TYPESAFE_API_KEY` environments are also supported.
178
+
179
+ Local filtering excludes credential/environment files, configured exclusions,
180
+ binary/oversized files, and obvious secret values before Jev sees anything.
181
+ Jev adds contextual filtering. Approved evidence is displayed by default;
182
+ use `--no-display-evidence` to hide it. Evidence persistence is a separate
183
+ opt-in, `--persist-evidence`. A policy change requires stopping and restarting
184
+ the daemon.
185
+
186
+ ```sh
187
+ node scripts/graphlin.mjs doctor --project /path/to/your/app
188
+ node scripts/graphlin.mjs status --project /path/to/your/app
189
+ node scripts/graphlin.mjs export --project /path/to/your/app
190
+ node scripts/graphlin.mjs stop --project /path/to/your/app
191
+ ```
192
+
193
+ State lives under `~/.local/state/graphlin` by default. Set
194
+ `GRAPHLIN_DATA_DIR` or use `--data-dir` to choose another location.
195
+ Source excerpts are ephemeral unless persistence is enabled. Retention and
196
+ payload sizes are bounded.
197
+
198
+ ## Investigate a missing shape
199
+
200
+ Select **Classification log** in the viewer and search for a file, such as
201
+ `src/cache.ts`, or an entity name. The log connects file capture and candidate
202
+ selection to Jev's intake scores, role/relation decisions, and the final diagram
203
+ changes. It also explains work that never reaches Jev: duplicate events,
204
+ pre-tool intentions, withheld source, empty candidates, and capacity limits.
205
+
206
+ From another terminal:
207
+
208
+ ```sh
209
+ node scripts/graphlin.mjs logs --project /path/to/your/app
210
+ node scripts/graphlin.mjs logs --project /path/to/your/app --file src/cache.ts
211
+ ```
212
+
213
+ Logging is automatic. After updating Graphlin, stop the existing service with
214
+ **Ctrl+C** and run the same `start` command again. A running process cannot load
215
+ the new logger, and old classifier scores cannot be reconstructed.
216
+
217
+ Each classification records the effective thresholds, both request durations,
218
+ model/rubric versions, validated scores, and fixed rejection reasons. A successful
219
+ classification can still result in no change because source changed while it
220
+ was running, an entity is already current, or a drawing limit was reached.
221
+ The log distinguishes those outcomes from an API failure or timeout.
222
+
223
+ Logs contain no source bodies, prompts, credentials, launch tokens, or raw API
224
+ errors. Live file names and candidate labels follow the evidence-display setting;
225
+ persisted logs omit them unless `--persist-evidence` is enabled. The `--file`
226
+ filter also matches stable artifact IDs, including after a file is deleted.
227
+ The service prints its log location. Retention is bounded to a recent in-memory
228
+ window and two private JSONL files; logs remain separate from diagram exports.
229
+
230
+ ## Plugin packages
231
+
232
+ Guided setup builds and installs these packages automatically. For development
233
+ or manual recovery:
234
+
235
+ ```sh
236
+ npm run build
237
+ claude --plugin-dir ./dist/claude/graphlin
238
+ ```
239
+
240
+ The build creates a `graphlin/` plugin inside `dist/portable`, `dist/claude`,
241
+ and `dist/codex`. Start
242
+ Graphlin for the project before working with the agent; passive hooks quietly
243
+ hand off events to the running service. A bundled MCP server also exposes
244
+ start, stop, status, and doctor controls.
245
+
246
+ The portable package uses Agent Plugins 1.0. Claude has its native manifest;
247
+ Codex has its portable extension and compatibility manifest. Kiro currently
248
+ has an experimental adapter profile. See [adapter coverage](../adapters/README.md).
249
+ Building a package does not install it into your host configuration.
250
+
251
+ The first implementation is Claude-first. Configuration and payload fixtures
252
+ are tested separately from real host activation. It does not claim universal
253
+ hook coverage or access to private reasoning.
254
+
255
+ ## Connect an agent
256
+
257
+ In the live viewer, select **How to connect**. The guide shows copyable commands
258
+ using that service's project, data directory, and available plugin packages.
259
+ Its build step puts versioned plugins under the service's data directory, so
260
+ setup also works when Graphlin's installation folder is read-only.
261
+ Keep Graphlin running in its terminal and run the agent in another terminal.
262
+ The Jev key stays with the service; the agent commands do not include it.
263
+
264
+ After guided installation, simply start `claude` in the project. The manual
265
+ recovery guide can use `claude --plugin-dir` to load the built Claude profile.
266
+ The guide also shows how to resume a session with that profile.
267
+
268
+ The build includes a local Codex marketplace under `dist/codex`. From this
269
+ checkout, the setup commands are:
270
+
271
+ ```sh
272
+ npm run build
273
+ codex plugin marketplace add "$PWD/dist/codex"
274
+ codex plugin add graphlin@graphlin-local
275
+ codex -C /path/to/your/app
276
+ ```
277
+
278
+ Inside Codex, use `/hooks` to review and trust Graphlin's hooks. Start a new
279
+ session after installation. Building the marketplace only creates files;
280
+ the commands above register and install it when you run them.
281
+ If the service uses a custom data directory, use the guide's command so the
282
+ agent inherits the matching `GRAPHLIN_DATA_DIR`.
283
+
284
+ The command forms were checked against the installed CLIs and the official
285
+ [plugin packaging](https://developers.openai.com/plugins/build/plugins) and
286
+ [Codex hooks](https://developers.openai.com/codex/hooks) documentation.
287
+ Installation and hook trust still depend on your host configuration.
288
+
289
+ ## Discover an existing project
290
+
291
+ Start Graphlin with `--allow-source`, connect Claude with the built plugin,
292
+ and ask it to **“orient yourself in this project”** or **“explore the architecture.”**
293
+ Completed reads, searches, and file listings can populate the diagram without
294
+ editing any files. There is no special prompt keyword or extra agent tool.
295
+
296
+ The existing `PostToolUse` hook supplies both the tool arguments and its result.
297
+ Graphlin recognizes returned file paths from Read, Glob, structured Grep results,
298
+ and common `find`, `rg --files`, and simple `ls` listings. It treats those paths as
299
+ hints and captures the current files from disk through the normal project and
300
+ privacy checks. Arbitrary shell output and an agent's summary do not become
301
+ confirmed source evidence. The hook never modifies Claude's tool result.
302
+
303
+ Classification runs asynchronously with two active workflows. Each receives its
304
+ own five-second deadline when it starts, so time waiting behind other file reads
305
+ does not consume that deadline. Queued source is checked again before
306
+ classification and before a result reaches the diagram. Work is deduplicated
307
+ within each session; another session can discover the same unchanged project.
308
+ The classification log records queue wait time and why work was skipped.
309
+
310
+ Discovery is bounded: the fallback directory scan visits at most 100 directories,
311
+ five levels deep, and selects up to 64 source files; explicit tool results can
312
+ identify additional files. The queue holds up to 64 waiting workflows for at most
313
+ two minutes. Excluded, unavailable, oversized, or sensitive files remain subject
314
+ to the existing evidence policy. A shape means code was observed; it does not
315
+ mean a database connection or other runtime operation succeeded.
316
+
317
+ Run `npm run eval:discovery` to replay a burst of orientation reads against real
318
+ Jev using a temporary, synthetic seven-file project. It reports per-file diagram
319
+ coverage, queue timing, and missing files. The probe uses `TYPESAFE_API_KEY` or
320
+ the local `.env.local`; it never reads your application or Claude transcript.
321
+
322
+ ## Follow live work
323
+
324
+ A new Claude session automatically becomes the selected diagram when its
325
+ `SessionStart` hook arrives. Ordinary hooks, delayed classifications, and
326
+ background compaction from another session do not take the selection away.
327
+ You can still choose an older session manually.
328
+
329
+ Expand **Hooks received** in the sidebar to see individual hook receipts from
330
+ all sessions in this project, newest first. Pre-tool, post-tool, and repeated
331
+ deliveries remain separate. The feed holds up to 200 receipts in memory and
332
+ contains event metadata, not tool bodies, prompts, or credentials.
333
+
334
+ **Diagram changes** stacks miniature added, removed, and changed shapes, with
335
+ the latest revision at the top. Select a current shape to inspect its evidence,
336
+ or a removed shape to replay the preceding retained revision. History is bounded;
337
+ gaps and unavailable older revisions are identified. Theme, zoom, and layout
338
+ changes do not create architecture history.
339
+
340
+ Restart an older Graphlin service and reload the viewer to enable the detailed
341
+ hook feed. Receipts from before that restart cannot be reconstructed.
342
+
343
+ ## Arrange the diagram
344
+
345
+ The diagram fills the workspace. Layout, theme, search, and type filters sit
346
+ above it. **Details**, **History**, and **Activity** open panels that are hidden
347
+ by default. Selecting a shape opens its evidence inspector.
348
+
349
+ The dashboard shows the active Git branch, full project path, and running
350
+ Graphlin version. Branch information refreshes every 30 seconds. The update
351
+ check asks npm only for Graphlin's public release metadata and caches the result
352
+ for 30 minutes. If a newer release is available, **How to update** provides a
353
+ copyable command that preserves this project's data directory. Stop the viewer
354
+ with **Ctrl+C**, run that command, and start a new agent session after setup.
355
+
356
+ Choose **Hierarchy**, **Dependency flow**, **Group by type**, **Circular**,
357
+ **Grid**, or **Original**. Auto-arrange responds to changes in the diagram;
358
+ turn it off to keep existing shapes in place, then use **Arrange** when ready.
359
+ Hierarchy follows the arrows and handles cycles; it does not imply ownership.
360
+
361
+ Scroll up over the diagram to zoom in around the pointer; scroll down to zoom
362
+ out. Drag the background to pan. **Fit**, layout switches, and **Arrange** show
363
+ the whole diagram, including below 50% for large hierarchies.
364
+
365
+ When a new shape arrives, the camera centers on it before its balloon animation.
366
+ A view below 50% zoom moves to 50%; a closer view keeps its zoom. If several
367
+ shapes arrive together, the last added shape gets the focus. Initial loads and
368
+ session switches show the whole diagram. Ordinary hook and status updates
369
+ preserve manual zoom and pan.
370
+
371
+ Type in the search box above the diagram, or press **/** to focus it. Search
372
+ matches any part of a node name, ignoring case, and shows only matching nodes
373
+ and connections between them. Each change rearranges the visible nodes and fits
374
+ them into the canvas, including clearing the search with **Esc**.
375
+
376
+ Type buttons show the component kinds present in the current diagram. Toggle
377
+ them individually, choose **All types**, or **Clear all** to start a new
378
+ selection. Search and type filters work together; Esc clears the search while
379
+ keeping the selected types. Filtering changes the view without deleting nodes
380
+ or changing exports.
381
+
382
+ Twelve component kinds map to distinct shapes, including functions, classes,
383
+ interfaces, events, configuration, packages, queues, and datastores.
384
+ Select a component to choose among 15 shapes in the inspector. Long names
385
+ wrap to two lines; the inspector retains the full name.
386
+
387
+ Shapes and arrows use **Tidy sketch** lines: gentle bends, close double strokes,
388
+ and slightly imperfect corners. The **Theme** selector offers
389
+ Sketchbook, Ocean, Forest, Sunset, Berry, Sepia, Blueprint dark, and Midnight
390
+ dark. Component kinds have coordinated fill colors; evidence labels and line
391
+ patterns remain distinct in every theme. Themes apply to the diagram and its
392
+ controls, leaving the evidence inspector readable in the surrounding interface.
393
+
394
+ New components inflate with a small bounce. Removed components pop into
395
+ particles. Replay, initial loading, reconnection, and stale evidence do not
396
+ trigger these effects. Reduced-motion preferences are respected.
397
+
398
+ Layouts and shape overrides affect the view only. They do not change evidence,
399
+ classification, recorded coordinates, or exported graphs. View preferences
400
+ are kept in memory per project/session/replay view and reset on page refresh.
401
+
402
+ ## Test
403
+
404
+ The following development and evaluation commands require a source checkout.
405
+ They are not part of the installed runtime package.
406
+
407
+ ```sh
408
+ npm test
409
+ ```
410
+
411
+ The automated suite uses local fixtures and injected transports. It checks
412
+ privacy, the A-to-B boundary, HTTP response validation, deadlines, event
413
+ correlation, source-version invalidation, graph integrity, replay, local
414
+ authentication, packaging, and viewer behavior.
415
+
416
+ An explicit live evaluation calls Jev with synthetic code cases:
417
+
418
+ ```sh
419
+ npm run eval:jev
420
+ node scripts/evaluate-jev.mjs --repeat 3
421
+ ```
422
+
423
+ This command reads `TYPESAFE_API_KEY`, optionally from `.env.local`, and saves
424
+ a numeric report in the ignored `.graphlin/` directory. It never sends your
425
+ project source. It reports missing candidates/questions and timeouts as
426
+ inconclusive. The default request cap is 128; explicit repeats keep their
427
+ earlier failures in the report. These examples are a smoke evaluation, not a
428
+ calibrated benchmark. See [live findings](jev-integration-findings.md).
429
+
430
+ The implementation uses JavaScript ES modules on Node.js, with HTML, CSS,
431
+ and JavaScript in the viewer. TypeSafe provides an official JavaScript/TypeScript
432
+ SDK, `@typesafe-ai/sdk`. This first slice uses the documented HTTP API through
433
+ Node's built-in `fetch`, keeping installation dependency-free while controlling
434
+ the complete request deadline, response bounds, and retry policy.
435
+
436
+ ## Evidence and limits
437
+
438
+ - Jev interprets focused snippets. A classified write path does not prove a
439
+ live database connection or a successful write.
440
+ - Pre-tool events show pending activity; they cannot confirm future changes.
441
+ - File observations have their own versions and unknown authorship. Changes
442
+ invalidate dependent claims across sessions even when Jev is unavailable.
443
+ - Restored claims start stale until fresh authorized observations support them.
444
+ - Streaming message assembly, semantic alias merging, broad static analysis,
445
+ account-wide budgets, and Windows transport are outside this first slice.
446
+ - Request budgets are per daemon. Classification can pause while metadata and
447
+ evidence invalidation continue.
448
+
449
+ ## Design and review
450
+
451
+ - [Proposed design](graphlin-design.md): architecture, plugin packaging, host coverage, Jev requests, state, drawing language, failure behavior, and delivery plan.
452
+ - [Interactive walkthrough](graphlin-design.html): replay a build, failed check, later verification, component removal, and Jev outage; inspect the two-stage pipeline.
453
+ - [Independent review](graphlin-review.md): prioritized findings and follow-up status.
454
+ - [Research coverage](research-coverage.md): primary documentation and design decisions.
455
+ - [Implementation plan](implementation-plan.md) and [module contracts](module-contracts.md).
456
+ - [Preimplementation review](implementation-review.md).
457
+ - [Implementation validation](implementation-validation.md): code review,
458
+ automated tests, browser checks, and remaining scope.
459
+ - [Jev patterns](jev-patterns.md): intent routing, speculative fan-out,
460
+ confidence gates, and evaluation before enabling domain routing.
461
+
462
+ Open the HTML file directly in a browser, or serve `docs/` with a local static web server. The walkthrough is self-contained and makes no network API calls.
463
+
464
+ The design walkthrough remains illustrative. The live viewer is served by the
465
+ runtime started through the commands above.
466
+
467
+ ## Contributing and license
468
+
469
+ See [CONTRIBUTING.md](../CONTRIBUTING.md) for development and review guidance,
470
+ [SECURITY.md](../SECURITY.md) for vulnerability reporting, and
471
+ [the release guide](releasing.md) for npm publishing.
472
+ Graphlin is available under the [MIT license](../LICENSE).