@event4u/agent-config 17.1.0 → 17.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +70 -0
  5. package/README.md +2 -2
  6. package/dist/agent-src/commands/project/analyze.md +9 -6
  7. package/dist/agent-src/commands/project/map.md +58 -0
  8. package/dist/agent-src/commands/project.md +5 -3
  9. package/dist/agent-src/skills/code-intelligence/SKILL.md +6 -0
  10. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  11. package/dist/cli/registry.js +1 -1
  12. package/dist/cli-delegate/cmd_conformance.js +23 -39
  13. package/dist/discovery/deprecation-report.md +1 -1
  14. package/dist/discovery/discovery-manifest.json +39 -13
  15. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  16. package/dist/discovery/discovery-manifest.summary.md +3 -3
  17. package/dist/discovery/dormancy-report.md +1 -1
  18. package/dist/discovery/orphan-report.md +1 -1
  19. package/dist/discovery/packs.json +6 -5
  20. package/dist/discovery/trust-report.md +2 -2
  21. package/dist/discovery/workspaces.json +5 -4
  22. package/dist/hooks/dispatch.js +65 -74
  23. package/dist/hooks/dispatch.sha256 +1 -1
  24. package/dist/hooks/instructions_observer.chunk.cjs +301 -0
  25. package/dist/hooks/instructions_observer.chunk.cjs.sha256 +1 -0
  26. package/dist/mcp/registry-manifest.json +2 -2
  27. package/dist/mcp/server.json +2 -2
  28. package/dist/mcp/server.mjs +33058 -22930
  29. package/package.json +4 -1
  30. package/src/config/continuity-surface.json +7 -0
  31. package/src/config/evaluator-budgets.json +4 -4
  32. package/src/config/gate-violation-baselines.json +3 -3
  33. package/src/config/gitignore-block.txt +6 -0
  34. package/src/config/hook-bundle-budget.json +17 -2
  35. package/src/config/hook-token-budget.json +1 -1
  36. package/src/config/packed-binary-manifest.json +27 -0
  37. package/src/config/skill-body-budget.json +7 -1
  38. package/src/scripts/_lib/bench_ab_complexity.ts +14 -2
  39. package/src/scripts/_lib/collector_record.ts +1 -0
  40. package/src/scripts/_lib/runtime_journal.ts +7 -7
  41. package/src/scripts/code_graph/build.ts +210 -10
  42. package/src/scripts/code_graph/cli.ts +168 -46
  43. package/src/scripts/code_graph/detect.ts +5 -4
  44. package/src/scripts/code_graph/docs_layer.ts +57 -0
  45. package/src/scripts/code_graph/extract.ts +58 -13
  46. package/src/scripts/code_graph/extract_more.ts +314 -0
  47. package/src/scripts/code_graph/laravel_overlay.ts +454 -0
  48. package/src/scripts/code_graph/map.ts +846 -0
  49. package/src/scripts/code_graph/map_model.ts +977 -0
  50. package/src/scripts/code_graph/map_verify.ts +140 -0
  51. package/src/scripts/code_graph/map_viewer/viewer.css +278 -0
  52. package/src/scripts/code_graph/map_viewer/viewer.js +756 -0
  53. package/src/scripts/code_graph/scip_reader.ts +201 -0
  54. package/src/scripts/code_graph/sqlite_store.ts +8 -1
  55. package/src/scripts/code_graph/types.ts +81 -15
  56. package/src/scripts/code_graph/validate.ts +16 -26
  57. package/src/scripts/code_graph/verbs.ts +7 -0
  58. package/src/scripts/hook_chunks.mjs +7 -0
  59. package/src/scripts/hook_manifest.json +1 -1
  60. package/src/scripts/hook_manifest.yaml +20 -0
  61. package/src/scripts/hooks/dispatch_hook.ts +2 -2
  62. package/src/scripts/hooks/instructions_observer_hook.ts +25 -6
  63. package/src/scripts/hooks/lazy_concern.ts +4 -0
  64. package/src/scripts/install-hooks.sh +5 -0
  65. package/src/scripts/lint_agents_layout.ts +2 -0
  66. package/src/scripts/lint_hook_manifest.ts +1 -0
  67. package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -6
  68. package/src/scripts/mcp_server/graph_tools.ts +73 -1
  69. package/src/scripts/mcp_server/tools.ts +19 -36
  70. package/src/vendor/grammars/README.md +10 -5
  71. package/src/vendor/grammars/tree-sitter-go.wasm +0 -0
  72. package/src/vendor/grammars/tree-sitter-java.wasm +0 -0
  73. package/src/vendor/grammars/tree-sitter-python.wasm +0 -0
@@ -1364,6 +1364,19 @@ concerns:
1364
1364
  #
1365
1365
  # Never blocks, never warns: exit 0 on every path including a malformed
1366
1366
  # payload or an unwritable disk. fail_closed: false.
1367
+ # road-to-a-setup-that-decides-itself step 1.1 — the instructions-loaded
1368
+ # observer. CAPTURE ONLY: one classified line per loaded file into
1369
+ # `<machine root>/runtime/arrivals/<session>.jsonl`, the input of the arrival
1370
+ # record the computed layer form reads. Emits nothing to the model; exit 0 on
1371
+ # every path. Loaded from its own conditional chunk, never inlined.
1372
+ # Kill switch: `AGENT_CONFIG_INSTRUCTIONS_OBSERVER=off`, or remove the
1373
+ # `instructions_loaded` row under `platforms.claude` and reinstall.
1374
+ instructions-observer:
1375
+ script: src/scripts/hooks/instructions_observer_hook.ts
1376
+ args: []
1377
+ fail_closed: false
1378
+ severity: advisory
1379
+ effect: telemetry
1367
1380
  subagent-ledger:
1368
1381
  script: src/scripts/hooks/subagent_ledger_hook.ts
1369
1382
  args: []
@@ -1640,6 +1653,10 @@ platforms:
1640
1653
  subagent_start: [subagent-ledger, journal-record]
1641
1654
  subagent_stop: [subagent-ledger, journal-record]
1642
1655
  agent_error: [host-rate-marker]
1656
+ # Observe-only; the host runs this event asynchronously, once per loaded file.
1657
+ # `journal-record` is deliberately not bound here: the event is recordable
1658
+ # (RECORDED_EVENTS), but its capture lives under runtime/arrivals/.
1659
+ instructions_loaded: [instructions-observer]
1643
1660
 
1644
1661
  # Cowork — the Claude desktop app's local-agent-mode runtime, built
1645
1662
  # on top of the Claude Code CLI. Same lifecycle vocabulary, same
@@ -1796,6 +1813,9 @@ native_event_aliases:
1796
1813
  # agents/evidence/investigations/subagent-lifecycle-phase0-host-pin.md.
1797
1814
  SubagentStart: subagent_start
1798
1815
  SubagentStop: subagent_stop
1816
+ # Present on the installed binary (exact-token count 9):
1817
+ # agents/evidence/investigations/standing-context-40k-host-and-machine-probes.md § 1.
1818
+ InstructionsLoaded: instructions_loaded
1799
1819
  # StopFailure fires on an API failure and carries its class in `error`
1800
1820
  # (observed on 2.1.308 with `server_error`; `rate_limit` is the host's
1801
1821
  # documented value for the plan limit and has not been observed live, so a
@@ -118,8 +118,8 @@ export const EVENT_VOCABULARY: ReadonlySet<string> = new Set([
118
118
  "stop",
119
119
  "pre_compact",
120
120
  "agent_error",
121
- "subagent_start",
122
- "subagent_stop",
121
+ "subagent_start", "subagent_stop",
122
+ "instructions_loaded",
123
123
  ]);
124
124
 
125
125
  const _SEVERITY_BY_EXIT: Record<number, string> = {
@@ -46,19 +46,20 @@
46
46
  * the observer has written since. A failure that also prevents writing the mark
47
47
  * — the machine root itself unwritable — leaves none.
48
48
  *
49
- * NOT YET BOUND. No manifest row runs this concern, and it is not in the
50
- * dispatcher's concern registry, so it adds nothing to the hook bundle until
51
- * its binding lands; the binding needs bundle headroom it does not have today.
49
+ * BOUND ON `claude` ALONE, FROM ITS OWN CHUNK. The manifest runs it on
50
+ * `instructions_loaded`; the dispatcher loads it through `LAZY_CONCERNS`, so its
51
+ * body is not inlined into the dispatch bundle. The binding itself is: one
52
+ * registry row and the event name, 237 bytes (`hook-bundle-budget.json`).
52
53
  *
53
54
  * KILL SWITCH. `AGENT_CONFIG_INSTRUCTIONS_OBSERVER=off` makes it a no-op without
54
- * a reinstall; once the binding above lands, removing that one
55
- * `instructions_loaded` row from `hook_manifest.yaml` and reinstalling removes
56
- * it entirely. Either is the
55
+ * a reinstall; removing the one `instructions_loaded` row from
56
+ * `hook_manifest.yaml` and reinstalling removes it entirely. Either is the
57
57
  * response to hook failures, duplicate events, a session-start regression or an
58
58
  * unexplained test break.
59
59
  */
60
60
  import * as fs from 'node:fs';
61
61
  import * as path from 'node:path';
62
+ import { fileURLToPath, pathToFileURL } from 'node:url';
62
63
 
63
64
  import { event4u_root } from '../_lib/user_global_paths.js';
64
65
  import { captureInstructionsLoaded, isSessionFile } from '../_lib/instructions_loaded_event.js';
@@ -168,3 +169,21 @@ export function main(): number {
168
169
  return EXIT_ALLOW;
169
170
  }
170
171
  }
172
+
173
+ // The spawn fallback runs this file as a script, so it needs an entry; inside a
174
+ // bundle or chunk every module shares one `import.meta.url`, so it must never fire there.
175
+ declare const __AGENT_CONFIG_BUNDLE__: boolean | undefined;
176
+ function _isCliEntry(): boolean {
177
+ if (typeof __AGENT_CONFIG_BUNDLE__ !== 'undefined' && __AGENT_CONFIG_BUNDLE__) {
178
+ return false;
179
+ }
180
+ if (process.argv[1] === undefined) return false;
181
+ const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
182
+ if (import.meta.url === argvUrl) return true;
183
+ try {
184
+ return fs.realpathSync(fileURLToPath(import.meta.url)) === fs.realpathSync(path.resolve(process.argv[1]));
185
+ } catch {
186
+ return false;
187
+ }
188
+ }
189
+ if (_isCliEntry()) process.exit(main());
@@ -68,6 +68,10 @@ export const LAZY_CONCERNS: Readonly<Record<string, { readonly chunk: string; re
68
68
  chunk: 'chat_history.chunk.cjs',
69
69
  source: path.join('..', 'chat_history'),
70
70
  }),
71
+ 'src/scripts/hooks/instructions_observer_hook.ts': Object.freeze({
72
+ chunk: 'instructions_observer.chunk.cjs',
73
+ source: 'instructions_observer_hook',
74
+ }),
71
75
  });
72
76
 
73
77
  declare const __AGENT_CONFIG_BUNDLE__: boolean | undefined;
@@ -674,6 +674,11 @@ if [ -f "$cg_cache" ] && [ -x ./agent-config ]; then
674
674
  (
675
675
  trap 'rmdir "$cg_lock" 2>/dev/null || true' EXIT
676
676
  ./agent-config code-graph refresh --budget-seconds 60 >/dev/null 2>&1 || true
677
+ # The map follows the index it is drawn from, but only for a
678
+ # project that asked for one: no agents/map/, no map (ADR-297).
679
+ if [ -d agents/map ]; then
680
+ ./agent-config code-graph map --no-verify --no-build >/dev/null 2>&1 || true
681
+ fi
677
682
  ) >/dev/null 2>&1 &
678
683
  fi
679
684
  fi
@@ -62,6 +62,7 @@ const ALLOWED_SOURCE_DIRS: ReadonlySet<string> = new Set([
62
62
  'evidence',
63
63
  'features',
64
64
  'knowledge', // * consumer
65
+ 'map', // * consumer — code-graph map, local-only, gitignored (ADR-297)
65
66
  'memory', // * consumer
66
67
  'notes', // legacy; new files go to evidence/notes/
67
68
  'reports', // legacy; new files go to evidence/reports/ (see agents-layout.md)
@@ -91,6 +92,7 @@ const CONSUMER_EXPECTED_ENTRIES: ReadonlySet<string> = new Set([
91
92
  '.gitkeep',
92
93
  // Optional but legitimate consumer entries (will not trigger warnings)
93
94
  'knowledge',
95
+ 'map',
94
96
  'memory',
95
97
  'proposals',
96
98
  'roadmaps',
@@ -93,6 +93,7 @@ const EVENT_VOCABULARY: ReadonlySet<string> = new Set([
93
93
  "agent_error",
94
94
  "subagent_start",
95
95
  "subagent_stop",
96
+ "instructions_loaded",
96
97
  ]);
97
98
 
98
99
  // Known platform identifiers.
@@ -93,7 +93,7 @@
93
93
  },
94
94
  {
95
95
  "name": "chat_history_read",
96
- "description": "Read recent entries back from the consumer project's chat-history JSONL (`agents/runtime/.agent-chat-history`; `agents/.agent-chat-history` accepted for back-compat). Use to recover context from an earlier session — decisions, notes, phase markers — at the start of a new task. Read-only. Returns the resolved file path plus a list of matching entries (newest last). Combine `session`, `last`, and `entry_type` to narrow the result.",
96
+ "description": "Read recent entries from the chat-history JSONL (`agents/runtime/.agent-chat-history`; legacy `agents/.agent-chat-history` accepted) to recover decisions, notes and phase markers from an earlier session. Returns the resolved path and matching entries, newest last.",
97
97
  "side_effect": "ro",
98
98
  "implemented_on": [
99
99
  "stdio"
@@ -116,7 +116,7 @@
116
116
  },
117
117
  "path": {
118
118
  "type": "string",
119
- "description": "Optional history-file path override; defaults to the standard chat-history location under the project root."
119
+ "description": "History-file override; default is the standard location."
120
120
  },
121
121
  "around": {
122
122
  "type": "integer",
@@ -142,7 +142,7 @@
142
142
  "full"
143
143
  ],
144
144
  "default": "full",
145
- "description": "'index' returns compact rows (ref, t tag, ~100-char preview, tokens_estimate) instead of full entries — scan first, then re-read the refs you need via `around` or a narrowed filter. History entries are large, so index mode pays off here. 'full' (default) returns complete entries."
145
+ "description": "'index' returns compact rows (ref, t tag, preview, tokens_estimate) — scan, then re-read refs via `around` or a filter. 'full' (default) returns whole entries."
146
146
  }
147
147
  },
148
148
  "additionalProperties": false
@@ -222,6 +222,29 @@
222
222
  "readOnlyHint": true
223
223
  }
224
224
  },
225
+ {
226
+ "name": "graph_area",
227
+ "description": "One code-map area by id, exact name or member file: files, hubs, dependencies. Else refused.",
228
+ "side_effect": "ro",
229
+ "implemented_on": [
230
+ "stdio"
231
+ ],
232
+ "input_schema": {
233
+ "type": "object",
234
+ "required": [
235
+ "area"
236
+ ],
237
+ "properties": {
238
+ "area": {
239
+ "type": "string"
240
+ }
241
+ },
242
+ "additionalProperties": false
243
+ },
244
+ "annotations": {
245
+ "readOnlyHint": true
246
+ }
247
+ },
225
248
  {
226
249
  "name": "graph_dead",
227
250
  "description": "Symbols with no accepted reference that no declared entry point names. REFUSES (status `refused`) while a source is unreadable: with no exportedness recorded, an exported-but-unimported symbol is indistinguishable from a dead one. Never a deletion recommendation.",
@@ -283,6 +306,22 @@
283
306
  "readOnlyHint": false
284
307
  }
285
308
  },
309
+ {
310
+ "name": "graph_map_status",
311
+ "description": "Is there a code map (agents/map/)? Its freshness, counts and MAP.md path.",
312
+ "side_effect": "ro",
313
+ "implemented_on": [
314
+ "stdio"
315
+ ],
316
+ "input_schema": {
317
+ "type": "object",
318
+ "properties": {},
319
+ "additionalProperties": false
320
+ },
321
+ "annotations": {
322
+ "readOnlyHint": true
323
+ }
324
+ },
286
325
  {
287
326
  "name": "graph_node",
288
327
  "description": "One symbol in full: where it is declared, what reaches it, what it reaches, and how connected it is. Resolves EXACTLY (node id, then label) and refuses anything it cannot — it never scores free text, so an answer is always about the node you named.",
@@ -325,7 +364,15 @@
325
364
  "uses",
326
365
  "inherits",
327
366
  "member",
328
- "tests"
367
+ "tests",
368
+ "routes-to",
369
+ "renders",
370
+ "includes",
371
+ "reads",
372
+ "migrates",
373
+ "persists",
374
+ "relates",
375
+ "documents"
329
376
  ],
330
377
  "description": "Restrict to one relation. Omit for all of them."
331
378
  }
@@ -527,7 +574,7 @@
527
574
  },
528
575
  {
529
576
  "name": "memory_lookup",
530
- "description": "Retrieve engineering-memory entries for one or more memory types, optionally narrowed to specific anchor paths. Use before editing a security-sensitive or historically buggy file to surface prior incidents, ownership, and patterns tied to it. WORKFLOW: call with detail:\"index\" FIRST — each row carries id, title and tokens_estimate (the cost of fetching it) — then fetch full bodies via memory_get ONLY for the ids you will actually use, batching multiple ids into one call. Reads `agents/memory/<type>/*.yml` plus the `agents/memory/intake/*.jsonl` signal log. Read-only. Returns the v1 retrieval envelope: a `status` field plus per-type `slices` carrying the matched entries.",
577
+ "description": "Engineering-memory entries for one or more types, optionally narrowed to anchor paths — use before editing a security-sensitive or historically buggy file. Call with detail:\"index\" FIRST (rows carry id, title, tokens_estimate), then memory_get only the ids you will use, batched. Reads `agents/memory/<type>/*.yml` and `agents/memory/intake/*.jsonl`. Returns a `status` plus per-type `slices`.",
531
578
  "side_effect": "ro",
532
579
  "implemented_on": [
533
580
  "stdio"
@@ -568,7 +615,7 @@
568
615
  "token_budget": {
569
616
  "type": "integer",
570
617
  "minimum": 1,
571
- "description": "Optional token budget. When set, entries are rendered as one-line compact rows (id, type, confidence, `line`) and the row set is hard-cut at token_budget × 4 chars; omitted hits appear as a top-level `truncation` hint naming a concrete next step. Absent → the envelope is unchanged."
618
+ "description": "Optional: render compact rows (id, type, confidence, `line`) hard-cut at token_budget × 4 chars; omitted hits yield a top-level `truncation` hint."
572
619
  }
573
620
  },
574
621
  "required": [
@@ -62,6 +62,7 @@ import {
62
62
  testsFor,
63
63
  untested,
64
64
  } from '../code_graph/verbs.js';
65
+ import { areaReport, readMap } from '../code_graph/map.js';
65
66
  import type { BuiltinTool } from './tools.js';
66
67
 
67
68
  /** The `no graph here` answer, in one place so all five agree on its shape. */
@@ -119,7 +120,22 @@ function str(args: Record<string, unknown>, key: string): string {
119
120
  * drift. An enum that silently lost a value would turn a legal filter into a
120
121
  * rejected argument.
121
122
  */
122
- const RELATIONS = ['calls', 'imports', 'uses', 'inherits', 'member', 'tests'] as const;
123
+ const RELATIONS = [
124
+ 'calls',
125
+ 'imports',
126
+ 'uses',
127
+ 'inherits',
128
+ 'member',
129
+ 'tests',
130
+ 'routes-to',
131
+ 'renders',
132
+ 'includes',
133
+ 'reads',
134
+ 'migrates',
135
+ 'persists',
136
+ 'relates',
137
+ 'documents',
138
+ ] as const;
123
139
 
124
140
  function num(args: Record<string, unknown>, key: string, dflt: number): number {
125
141
  const v = args[key];
@@ -360,4 +376,60 @@ export const GRAPH_TOOLS: Record<string, BuiltinTool> = {
360
376
  }));
361
377
  },
362
378
  },
379
+ graph_map_status: {
380
+ name: 'graph_map_status',
381
+ side_effect: 'ro',
382
+ description: 'Is there a code map (agents/map/)? Its freshness, counts and MAP.md path.',
383
+ input_schema: { type: 'object', properties: {}, additionalProperties: false },
384
+ handler: async (_args, root) => {
385
+ const staleness = graphState(root);
386
+ const map = readMap(root);
387
+ if (!map) {
388
+ return {
389
+ status: 'unavailable',
390
+ staleness,
391
+ map: 'absent',
392
+ hint: 'run `agent-config code-graph map` to draw it into agents/map/',
393
+ };
394
+ }
395
+ const m = map.model;
396
+ return {
397
+ status: 'ok',
398
+ staleness,
399
+ map: 'present',
400
+ drawn_at_commit: map.meta.commit,
401
+ graph_state_when_drawn: map.meta.state,
402
+ files: m.files.length,
403
+ areas: m.areas.length,
404
+ trusted_links: m.analyses.trustedEdges,
405
+ guess_share: m.analyses.guessShare,
406
+ request_paths: m.analyses.requestPathsTotal,
407
+ largest_areas: m.areas.slice(0, 5).map((a) => `${a.id} ${a.name} (${a.files.length})`),
408
+ map_md: 'agents/map/MAP.md',
409
+ index_html: 'agents/map/index.html',
410
+ };
411
+ },
412
+ },
413
+ graph_area: {
414
+ name: 'graph_area',
415
+ side_effect: 'ro',
416
+ description: 'One code-map area by id, exact name or member file: files, hubs, dependencies. Else refused.',
417
+ input_schema: {
418
+ type: 'object',
419
+ required: ['area'],
420
+ properties: {
421
+ area: { type: 'string' },
422
+ },
423
+ additionalProperties: false,
424
+ },
425
+ handler: async (args, root) => {
426
+ const q = str(args, 'area');
427
+ if (q === '') return { status: 'error', error: 'area must be a non-empty string' };
428
+ const map = readMap(root);
429
+ if (!map) return { status: 'unavailable', error: 'no map — run `agent-config code-graph map`' };
430
+ const r = areaReport(map.model, q);
431
+ if ('refusal' in r) return { status: 'refused', refusal: r.refusal, candidates: r.candidates };
432
+ return { status: 'ok', drawn_at_commit: map.meta.commit, ...r };
433
+ },
434
+ },
363
435
  };
@@ -1298,15 +1298,11 @@ export const ALLOWLIST: Record<string, BuiltinTool> = {
1298
1298
  name: 'chat_history_read',
1299
1299
  side_effect: 'ro',
1300
1300
  description:
1301
- "Read recent entries back from the consumer project's " +
1302
- 'chat-history JSONL ' +
1303
- '(`agents/runtime/.agent-chat-history`; ' +
1304
- '`agents/.agent-chat-history` accepted for back-compat). Use ' +
1305
- 'to recover context from an earlier session — decisions, ' +
1306
- 'notes, phase markers — at the start of a new task. ' +
1307
- 'Read-only. Returns the resolved file path plus a list of ' +
1308
- 'matching entries (newest last). Combine `session`, `last`, ' +
1309
- 'and `entry_type` to narrow the result.',
1301
+ 'Read recent entries from the chat-history JSONL ' +
1302
+ '(`agents/runtime/.agent-chat-history`; legacy ' +
1303
+ '`agents/.agent-chat-history` accepted) to recover decisions, ' +
1304
+ 'notes and phase markers from an earlier session. Returns the ' +
1305
+ 'resolved path and matching entries, newest last.',
1310
1306
  input_schema: {
1311
1307
  type: 'object',
1312
1308
  properties: {
@@ -1328,9 +1324,7 @@ export const ALLOWLIST: Record<string, BuiltinTool> = {
1328
1324
  path: {
1329
1325
  type: 'string',
1330
1326
  description:
1331
- 'Optional history-file path override; defaults to ' +
1332
- 'the standard chat-history location under the ' +
1333
- 'project root.',
1327
+ 'History-file override; default is the standard location.',
1334
1328
  },
1335
1329
  around: {
1336
1330
  type: 'integer',
@@ -1359,12 +1353,9 @@ export const ALLOWLIST: Record<string, BuiltinTool> = {
1359
1353
  enum: ['index', 'full'],
1360
1354
  default: 'full',
1361
1355
  description:
1362
- "'index' returns compact rows (ref, t tag, ~100-char " +
1363
- 'preview, tokens_estimate) instead of full entries — ' +
1364
- 'scan first, then re-read the refs you need via ' +
1365
- '`around` or a narrowed filter. History entries are ' +
1366
- "large, so index mode pays off here. 'full' " +
1367
- '(default) returns complete entries.',
1356
+ "'index' returns compact rows (ref, t tag, preview, " +
1357
+ 'tokens_estimate) — scan, then re-read refs via ' +
1358
+ "`around` or a filter. 'full' (default) returns whole entries.",
1368
1359
  },
1369
1360
  },
1370
1361
  additionalProperties: false,
@@ -1375,18 +1366,13 @@ export const ALLOWLIST: Record<string, BuiltinTool> = {
1375
1366
  name: 'memory_lookup',
1376
1367
  side_effect: 'ro',
1377
1368
  description:
1378
- 'Retrieve engineering-memory entries for one or more memory ' +
1379
- 'types, optionally narrowed to specific anchor paths. Use ' +
1380
- 'before editing a security-sensitive or historically buggy ' +
1381
- 'file to surface prior incidents, ownership, and patterns ' +
1382
- 'tied to it. WORKFLOW: call with detail:"index" FIRST — each ' +
1383
- 'row carries id, title and tokens_estimate (the cost of ' +
1384
- 'fetching it) — then fetch full bodies via memory_get ONLY ' +
1385
- 'for the ids you will actually use, batching multiple ids ' +
1386
- 'into one call. Reads `agents/memory/<type>/*.yml` plus the ' +
1387
- '`agents/memory/intake/*.jsonl` signal log. Read-only. ' +
1388
- 'Returns the v1 retrieval envelope: a `status` field plus ' +
1389
- 'per-type `slices` carrying the matched entries.',
1369
+ 'Engineering-memory entries for one or more types, optionally ' +
1370
+ 'narrowed to anchor paths — use before editing a ' +
1371
+ 'security-sensitive or historically buggy file. Call with ' +
1372
+ 'detail:"index" FIRST (rows carry id, title, tokens_estimate), ' +
1373
+ 'then memory_get only the ids you will use, batched. Reads ' +
1374
+ '`agents/memory/<type>/*.yml` and `agents/memory/intake/*.jsonl`. ' +
1375
+ 'Returns a `status` plus per-type `slices`.',
1390
1376
  input_schema: {
1391
1377
  type: 'object',
1392
1378
  properties: {
@@ -1426,12 +1412,9 @@ export const ALLOWLIST: Record<string, BuiltinTool> = {
1426
1412
  type: 'integer',
1427
1413
  minimum: 1,
1428
1414
  description:
1429
- 'Optional token budget. When set, entries are ' +
1430
- 'rendered as one-line compact rows (id, type, ' +
1431
- 'confidence, `line`) and the row set is hard-cut at ' +
1432
- 'token_budget × 4 chars; omitted hits appear as a ' +
1433
- 'top-level `truncation` hint naming a concrete next ' +
1434
- 'step. Absent → the envelope is unchanged.',
1415
+ 'Optional: render compact rows (id, type, confidence, ' +
1416
+ '`line`) hard-cut at token_budget × 4 chars; omitted ' +
1417
+ 'hits yield a top-level `truncation` hint.',
1435
1418
  },
1436
1419
  },
1437
1420
  required: ['types'],
@@ -10,9 +10,11 @@ with no manual parser install (ADR-259).
10
10
 
11
11
  `tree-sitter-wasms` carries 36 grammars (49 MiB on disk). Depending on it at
12
12
  runtime would hand every consumer all 36, which is the option ADR-259 §
13
- Alternatives rejects on exactly that measurement. Only the three grammars below
13
+ Alternatives rejects on exactly that measurement. Only the six grammars below
14
14
  are loadable by the engine — `GRAMMAR_WASM` in `src/scripts/code_graph/types.ts`
15
- has three entries — so the other 33 would be payload with no reader.
15
+ has six entries — so the other 30 would be payload with no reader. Vue needs no
16
+ grammar of its own: the extractor blanks a component's template and parses its
17
+ `<script>` with the TypeScript grammar.
16
18
 
17
19
  **No grammar is ever fetched at runtime** (Kill register K1). These files are in
18
20
  the tarball; the loader reads them from disk.
@@ -24,8 +26,11 @@ the tarball; the loader reads them from disk.
24
26
  | php | `tree-sitter-php.wasm` | `55bb617b6f01e14bab997861f0b20a2420cf6ba3199ffeb295b9ec398966d8a3` |
25
27
  | typescript (also serves `.tsx`) | `tree-sitter-typescript.wasm` | `8515404dceed38e1ed86aa34b09fcf3379fff1b4ff9dd3967bcd6d1eb5ac3d8f` |
26
28
  | javascript | `tree-sitter-javascript.wasm` | `63812b9e275d26851264734868d27a1656bd44a2ef6eb3e85e6b03728c595ab5` |
29
+ | python | `tree-sitter-python.wasm` | `9056d0fb0c337810d019fae350e8167786119da98f0f282aceae7ab89ee8253b` |
30
+ | go | `tree-sitter-go.wasm` | `9963ca89b616eaf04b08a43bc1fb0f07b85395bec313330851f1f1ead2f755b6` |
31
+ | java | `tree-sitter-java.wasm` | `637aac4415fb39a211a4f4292d63c66b5ce9c32fa2cd35464af4f681d91b9a1f` |
27
32
 
28
- All three are built against **grammar ABI 14** (`EXPECTED_GRAMMAR_ABI` in
33
+ All six are built against **grammar ABI 14** (`EXPECTED_GRAMMAR_ABI` in
29
34
  `src/scripts/code_graph/types.ts`). The loader asserts the ABI on every load, so
30
35
  a drifted grammar fails loudly rather than parsing wrongly.
31
36
 
@@ -68,7 +73,7 @@ The pair is ABI-coupled and must move together:
68
73
 
69
74
  ```bash
70
75
  npm i -D web-tree-sitter@<v> tree-sitter-wasms@<v>
71
- for g in php typescript javascript; do
76
+ for g in php typescript javascript python go java; do
72
77
  cp node_modules/tree-sitter-wasms/out/tree-sitter-$g.wasm src/vendor/grammars/
73
78
  done
74
79
  shasum -a 256 src/vendor/grammars/*.wasm # update the table above
@@ -76,7 +81,7 @@ shasum -a 256 src/vendor/grammars/*.wasm # update the table above
76
81
 
77
82
  Then update, in the same change:
78
83
 
79
- - the three entries in `src/config/packed-binary-manifest.json` (they are
84
+ - the six entries in `src/config/packed-binary-manifest.json` (they are
80
85
  path-, sha256- and size-bound, so any refresh invalidates them by design).
81
86
  This used to name `BINARY_PAYLOAD_EXCEPTIONS` in `src/scripts/check_pack_size.ts`,
82
87
  a constant that no longer exists — `grep -rn BINARY_PAYLOAD_EXCEPTIONS` returned