@mrclrchtr/supi-code-intelligence 2.1.0 → 2.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 (98) hide show
  1. package/README.md +17 -3
  2. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/README.md +9 -8
  3. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  4. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -3
  5. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -5
  6. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/scoped-settings-list.ts +372 -0
  7. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-action-menu.ts +101 -0
  8. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +13 -7
  9. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +464 -0
  10. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-submenus.ts +124 -0
  11. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +50 -309
  12. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +2 -5
  13. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings.ts +17 -1
  14. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
  15. package/node_modules/@mrclrchtr/supi-core/README.md +9 -8
  16. package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  17. package/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -3
  18. package/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -5
  19. package/node_modules/@mrclrchtr/supi-core/src/settings/scoped-settings-list.ts +372 -0
  20. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-action-menu.ts +101 -0
  21. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +13 -7
  22. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +464 -0
  23. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-submenus.ts +124 -0
  24. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +50 -309
  25. package/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +2 -5
  26. package/node_modules/@mrclrchtr/supi-core/src/settings.ts +17 -1
  27. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/README.md +9 -8
  28. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  29. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -3
  30. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -5
  31. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/scoped-settings-list.ts +372 -0
  32. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-action-menu.ts +101 -0
  33. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +13 -7
  34. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +464 -0
  35. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-submenus.ts +124 -0
  36. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +50 -309
  37. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +2 -5
  38. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings.ts +17 -1
  39. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
  40. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/README.md +9 -8
  41. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  42. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -3
  43. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -5
  44. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/scoped-settings-list.ts +372 -0
  45. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-action-menu.ts +101 -0
  46. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +13 -7
  47. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +464 -0
  48. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-submenus.ts +124 -0
  49. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +50 -309
  50. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +2 -5
  51. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings.ts +17 -1
  52. package/node_modules/@mrclrchtr/supi-lsp/package.json +3 -3
  53. package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +49 -12
  54. package/node_modules/@mrclrchtr/supi-lsp/src/config/lsp-settings.ts +1 -1
  55. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/README.md +9 -8
  56. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  57. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -3
  58. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -5
  59. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/scoped-settings-list.ts +372 -0
  60. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-action-menu.ts +101 -0
  61. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +13 -7
  62. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +464 -0
  63. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-submenus.ts +124 -0
  64. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +50 -309
  65. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +2 -5
  66. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings.ts +17 -1
  67. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
  68. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/README.md +9 -8
  69. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  70. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -3
  71. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -5
  72. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/scoped-settings-list.ts +372 -0
  73. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-action-menu.ts +101 -0
  74. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +13 -7
  75. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +464 -0
  76. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-submenus.ts +124 -0
  77. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +50 -309
  78. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +2 -5
  79. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings.ts +17 -1
  80. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +3 -3
  81. package/package.json +5 -5
  82. package/src/analysis/instruction-files.ts +194 -0
  83. package/src/app/app.ts +6 -1
  84. package/src/config.ts +42 -0
  85. package/src/extension.ts +27 -0
  86. package/src/session/session.ts +67 -0
  87. package/src/substrate/lsp/diagnostic-injection.ts +0 -15
  88. package/src/substrate/lsp/settings.ts +101 -179
  89. package/src/tool/guidance.ts +27 -38
  90. package/src/tool/orientation/mode.ts +53 -2
  91. package/src/tool/result/types.ts +3 -0
  92. package/src/tool/schemas.ts +22 -32
  93. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +0 -207
  94. package/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +0 -207
  95. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +0 -207
  96. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +0 -207
  97. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +0 -207
  98. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +0 -207
@@ -2,6 +2,11 @@
2
2
  //
3
3
  // Each code_* tool owns its complete promptGuidelines here.
4
4
  // Runtime registration data (name, parameters, run) lives in specs.ts.
5
+ //
6
+ // Cross-tool steering is centralized (authored once on its natural-home tool) and
7
+ // some tools have empty promptGuidelines by design: all code_* tools are always
8
+ // active together, so a steering bullet on one tool is always co-visible. See
9
+ // docs/adr/0013-centralized-code-intelligence-prompt-steering-assumes-all-tools-active.md.
5
10
 
6
11
  import type { CodeIntelligenceToolName } from "../types/index.ts";
7
12
 
@@ -19,94 +24,78 @@ export type CodeIntelligenceToolPromptSurfaceMap = Record<
19
24
  export const CODE_INTELLIGENCE_TOOL_PROMPT_SURFACES: CodeIntelligenceToolPromptSurfaceMap = {
20
25
  code_resolve: {
21
26
  description:
22
- "Resolve human or code references into precise file/range/symbol targets and stable target handles. Use when a symbol, file, or code reference is ambiguous and needs precise resolution. Returns targetId and spanId handles that can be passed to code_graph, code_impact, and code_refactor_plan. Supports anchored (file + line + character), file-only, and query/symbol inputs. Anchored coordinates resolve a real symbol target from provider-backed evidence: an exact identifier coordinate resolves to a named target; a declaration-header coordinate (e.g. an `export` keyword) snaps to the symbol name anchor only when unambiguous. Whitespace/comment/non-symbol coordinates fail honestly and recommend code_inspect. Does not fall back to text search for symbol resolution; ambiguous results return ranked candidates with target IDs for every shown item. Output is truncated to 2000 lines / 50KB.",
27
+ "Resolve references to evidence-backed code targets and stable targetId/spanId handles for follow-up code_* tools. Accepts query/symbol/file or anchored file+line+character; anchored resolution snaps only to real provider-backed symbols, and whitespace/comment/non-symbol points fail with code_inspect guidance. No text-search fallback; ambiguous results return ranked candidates. Truncates at 2000 lines/50KB.",
23
28
  promptSnippet: "code_resolve — resolve references into precise targets and target handles",
24
29
  promptGuidelines: [
25
- "Use code_resolve when a symbol, file, or code reference is ambiguous and needs precise resolution.",
26
- "Prefer code_resolve as the entry point before code_orientation, code_graph, code_impact, or code_refactor_plan — its targetId replaces fragile file/line/character coordinates.",
27
- "When code_resolve returns ambiguous results with ranked candidates, pick one and use file + line + character for follow-up resolution.",
30
+ "Use code_resolve first for ambiguous or symbol-only targets, before graph/impact/refactor/orientation; if resolve returns ranked candidates, narrow with a candidate file + line + character.",
28
31
  ],
29
32
  },
30
33
  code_inspect: {
31
34
  description:
32
- "Inspect one precise point in a file and return factual syntax, symbol, hover, definition, diagnostics, and code-action information. Use when you need to understand exactly what is at a position without choosing between provider-specific substrate tools. When some providers are unavailable, returns best-effort sections with explicit unavailable notes instead of heuristic guesses. Code action titles are advisory only — there is no tool to execute them yet. Output is truncated to 2000 lines / 50KB.",
35
+ "Inspect one exact file position for syntax, symbol, hover/definition, nearby diagnostics, and code-action titles. Requires file, line, and character; use for point facts, not broad orientation. Unavailable providers are disclosed; code actions are advisory only. Truncates at 2000 lines/50KB.",
33
36
  promptSnippet: "code_inspect — factual point inspection",
34
- promptGuidelines: [
35
- "Use code_inspect for factual point inspection at one precise file position.",
36
- "Provide `file`, `line`, and `character` — code_inspect is intentionally point-based.",
37
- "Prefer code_inspect over code_orientation for point-level facts when no symbol target can be resolved.",
38
- ],
37
+ // No guidelines: selection is steered by code_orientation's bullet plus this
38
+ // self-sufficient description. See ADR 0013 (all code_* tools always active).
39
+ promptGuidelines: [],
39
40
  },
40
41
  code_orientation: {
41
42
  description:
42
- "Primary code-orientation tool for understanding a project, discovered module, directory, file, or symbol before choosing surgical follow-up tools. Use `focus` for a workspace-relative path or discovered module name; omit `focus` for project orientation. Use `focus` + `line` + `character` for symbol orientation, or pass `targetId` from `code_resolve`; `targetId` takes precedence over focus/coordinates and stale target IDs do not fall back. Symbol orientation returns definitions, JSDoc/TSDoc docs, local diagnostics near the target, and Read Next guidance; relation evidence belongs in code_graph, impact evidence in code_impact, and health/status in code_health. Not a point-inspection tool — use code_inspect for exact position facts. `maxResults` caps each rendered list and defaults to 10. Output is truncated to 2000 lines / 50KB.",
43
+ "Orient around the workspace, module, directory, file, or resolved symbol before surgical work. Omit focus for workspace orientation; use focus for a path/module, or targetId/focus+line+character for symbol orientation. Directory focus may surface local instruction files (CLAUDE.md, AGENTS.md). targetId wins and stale IDs error. Returns landmarks, docs, local diagnostics, and read-next guidance; relations/impact/health belong in code_graph/code_impact/code_health. maxResults caps lists; output is truncated to 2000 lines / 50KB.",
43
44
  promptSnippet: "code_orientation — project/module/file/symbol orientation",
44
45
  promptGuidelines: [
45
46
  "Use `code_orientation({ focus })` for first-pass project/package/directory/file orientation before `bash`/`read`.",
47
+ "Use directory focus (for example `packages/foo`) to surface local instruction files before package work.",
46
48
  "Use code_resolve first for bare symbol names, then pass the resulting targetId to code_orientation.",
47
49
  "Use code_graph/code_impact/code_health for relations, impact, or full health instead of asking code_orientation for those sections.",
48
50
  ],
49
51
  },
50
52
  code_graph: {
51
53
  description:
52
- 'Unified relation-graph tool replaces code_references, code_calls, and code_implementations. Resolves a target once and dispatches to the appropriate analysis service per requested relation. Defaults to ["references"] when `relations` is omitted. Each relation is best-effort: unavailable substrates skip with a note rather than failing the whole call. Each relation annotates its evidence source. The tests relation displays discovery provenance (semantic+conventions or conventions-only) separately from any extracted test labels. `callees` is structural/direct-scope evidence: it reports call expressions by source shape, not symbol identity, and excludes calls inside nested function/method/callback scopes — use `references` on a resolved target for identity-aware incoming callers. Pass `calleeDepth: "deep"` to include callees from nested scopes. `imports` and `exports` use file-level tree-sitter analysis; `tests` discovers companion test files and labels. Targeted graph results include Read Next guidance for source ranges worth inspecting via `read`. `scope` (not `path`) narrows by workspace-relative directory/package. Use code_resolve first to get a targetId, then pass it to code_graph. Output is truncated to 2000 lines / 50KB.',
54
+ 'Analyze relation evidence for a resolved target or coordinates: references, structural callees, imports/exports, implementations, and tests. Defaults to references; relations:["all"] expands all families. Per-relation substrate failures are disclosed. Callees are syntax/direct-scope source-shape calls, not symbol identity; calleeDepth:"deep" includes nested scopes. Scope narrows by workspace path; targetId from code_resolve is preferred. Truncates at 2000 lines/50KB.',
53
55
  promptSnippet: "code_graph — semantic and structural relation graph",
54
- promptGuidelines: [
55
- "Use code_graph to find references, direct structural calls, and implementations for a target.",
56
- 'Default `relations` is ["references"]; use `relations: ["callees"]` or `["implements"]` for those, or `relations: ["all"]` to expand to every relation family in one call.',
57
- "After code_graph, follow up with code_orientation on individual results for type or definition context.",
58
- 'Pass `calleeDepth: "deep"` to include callees from nested function/method/callback scopes (default `"direct"` excludes them).',
59
- 'Suggested relations by target kind: For functions/methods: `["references", "callees", "tests"]` — For interfaces/types/classes/enums: `["references", "implements"]` — For files/modules: `["imports", "exports"]` — For tests: `["tests"]`.',
60
- ],
56
+ // No guidelines: selection is steered by this self-sufficient description plus
57
+ // code_impact's "use code_graph instead of code_impact" bullet. See ADR 0013.
58
+ promptGuidelines: [],
61
59
  },
62
60
  code_impact: {
63
61
  description:
64
- "Estimate blast radius and downstream impact for a target or user-supplied change set before making edits. `changeSetFiles` are explicit workspace-relative files to analyze as in scope for a proposed/current change; they are not inferred from git and carry no line-level diff evidence. Uses semantic evidence for target-based impact and merges semantic references for symbols defined in change-set files when available. Includes Read Next guidance for source ranges worth inspecting via `read` before editing. Does not fall back to heuristic text search. Use a resolved target for precise semantic reference-based impact. Output is truncated to 2000 lines / 50KB.",
62
+ "Estimate blast radius for a resolved target or user-supplied changeSetFiles before editing. changeSetFiles are explicit files, not inferred from git and no line-level diff; change-only requests report insufficient evidence. Uses semantic references plus deterministic test discovery when available; no heuristic search fallback. Output includes read-next guidance; truncates at 2000 lines/50KB.",
65
63
  promptSnippet: "code_impact — blast radius and impact",
66
64
  promptGuidelines: [
67
- "Use code_impact before edits to estimate blast radius and follow-up checks.",
68
- "Use code_graph instead of code_impact when you only need a plain reference list without impact analysis.",
65
+ "Use code_graph instead of code_impact when you only need a plain reference list.",
69
66
  ],
70
67
  },
71
68
  code_find: {
72
69
  description:
73
- 'Unified ranked code search with strict mode dispatch: default/`mode: "text"` is literal ripgrep, `mode: "regex"` is ripgrep regex, `mode: "semantic"` is LSP workspace-symbol search, and `mode: "ast"` is tree-sitter structured search. `mode: "ast"` requires `kind` and currently supports `definition`, `import`, `export`, `call`, `type`, `interface`, `class`, `method`, `enum`, and `test`. `mode: "text"`, `mode: "regex"`, and `mode: "semantic"` do not accept `kind`. `scope` accepts one workspace-relative path or an array of paths; delimiter-separated strings are split only when no exact path exists. `code_find` with `mode: "semantic"` does not silently fall back to text search, and unsupported mode/kind combinations fail. AST `call` mode matches call-site identifiers by name, not by symbol identity; use `code_graph` references for identity-aware callers of a resolved target. Output is truncated to 2000 lines / 50KB.',
70
+ 'Search code with explicit modes: text literal (default), regex, semantic workspace-symbol, or ast structured. mode:"ast" requires `kind` (definition/import/export/call/type/interface/class/method/enum/test); text/regex/semantic reject kind. Semantic mode uses LSP only and does not silently fall back. AST call matches written call-site names, not by symbol identity; use code_graph references on a resolved target for symbol-identity-aware callers. Truncates at 2000 lines/50KB.',
74
71
  promptSnippet: "code_find — unified ranked code search",
75
72
  promptGuidelines: [
76
- "Use code_find as the sole code search tool for literal text, regex, semantic workspace-symbol, or AST structured search.",
77
- 'code_find with `mode: "ast"` requires `kind` and supports `definition`, `import`, `export`, `call`, `type`, `interface`, `class`, `method`, `enum`, and `test`.',
78
- 'code_find with `mode: "text"`, `mode: "regex"`, or `mode: "semantic"` does not accept `kind`.',
79
- 'code_find with `mode: "semantic"` does not fall back to text search and fails when semantic capability is unavailable.',
80
- 'AST `call` mode matches call-site identifiers by name only; use `code_graph` with `relations: ["references"]` on a resolved target for symbol-identity-aware callers.',
73
+ "Use code_find for explicit text, regex, semantic symbol, or AST search; use code_graph references for symbol-identity callers.",
81
74
  ],
82
75
  },
83
76
  code_refactor_plan: {
84
77
  description:
85
- 'Pure planner: previews a precise semantic refactor plan without mutating files and returns a planId for later use with code_refactor_apply. Supports rename_symbol plus extract_function/extract_variable when the active LSP can return precise edits. Legacy `operation: "rename"` is accepted as a compatibility alias. This tool never mutates files. Output is truncated to 2000 lines / 50KB.',
78
+ "Preview a semantic refactor plan and return planId; never mutates files. Supports rename_symbol (rename alias) and extract_function/extract_variable when LSP returns precise edits. Requires targetId or anchored file+line+character, plus operation-specific newName/range. Apply separately with code_refactor_apply. Truncates at 2000 lines/50KB.",
86
79
  promptSnippet: "code_refactor_plan — preview a precise workflow refactor plan",
87
80
  promptGuidelines: [
88
- 'Use `operation: "rename_symbol"` with code_refactor_plan for symbol renames. Legacy `operation: "rename"` is accepted as a compatibility alias.',
89
- 'Use `operation: "extract_function"` or `"extract_variable"` with a 1-based `range` and `newName` when the LSP advertises precise extract code actions.',
90
- "code_refactor_plan is a pure planner — it returns a planId. Use code_refactor_apply with that planId to execute.",
81
+ "Use code_refactor_plan to preview rename/extract edits only; mutate later with code_refactor_apply and the returned planId.",
91
82
  ],
92
83
  },
93
84
  code_refactor_apply: {
94
85
  description:
95
- "Sole mutator in the refactor workflow: applies a previously stored plan by planId. Revalidates the plan and checks file fingerprints, mutating files only when the plan is still fresh. Output is truncated to 2000 lines / 50KB.",
86
+ "Apply a stored refactor plan by planId. Revalidates plan freshness and file fingerprints before mutating; does not compose new plans. Truncates at 2000 lines/50KB.",
96
87
  promptSnippet: "code_refactor_apply — apply a stored refactor plan",
97
88
  promptGuidelines: [
98
- "Use code_refactor_apply to execute a plan generated by code_refactor_plan.",
99
- "Use code_refactor_plan first to obtain a planId, then code_refactor_apply to execute it.",
89
+ "Use code_refactor_apply only with a planId returned by code_refactor_plan.",
100
90
  ],
101
91
  },
102
92
  code_health: {
103
93
  description:
104
- "Summarize diagnostics, language server status, dirty workspace signals, coverage, and unused-code findings. Pass refresh: true to recover stale diagnostics before checking. Use scope to narrow to a specific file or package. Use include to request specific sections: diagnostics, servers, dirty, coverage, unused. Defaults to summary level (counts); use level: detailed for per-file listings. Output is truncated to 2000 lines / 50KB.",
94
+ "Report workspace health: diagnostics, language-server status, dirty files, coverage, and unused code. Use scope/include/level to narrow; refresh:true recovers stale diagnostics. Missing coverage/unused reports are disclosed. Truncates at 2000 lines/50KB.",
105
95
  promptSnippet:
106
96
  "code_health — diagnostics, server status, coverage, unused-code, and workspace health",
107
97
  promptGuidelines: [
108
- "Use code_health to check for diagnostics, language server status, dirty workspace state, coverage, or unused-code signals.",
109
- "Pass `refresh: true` to code_health to recover stale diagnostics before checking.",
98
+ "Use code_health for diagnostics/server/dirty/coverage/unused health; pass refresh:true to code_health before relying on stale diagnostics.",
110
99
  ],
111
100
  },
112
101
  };
@@ -6,10 +6,17 @@
6
6
  * orientation.
7
7
  */
8
8
 
9
- import { existsSync } from "node:fs";
9
+ import { existsSync, statSync } from "node:fs";
10
10
  import type { ArchitectureModel } from "../../analysis/architecture/model.ts";
11
+ import {
12
+ findInstructionFilesForDirectory,
13
+ insertInstructionsNearTop,
14
+ renderInstructionFiles,
15
+ } from "../../analysis/instruction-files.ts";
11
16
  import { normalizePath } from "../../analysis/search/ripgrep.ts";
17
+ import { loadCodeIntelligenceConfig } from "../../config.ts";
12
18
  import type { CodeIntelResult, CodeIntelToolExecCtx } from "../../types/index.ts";
19
+ import type { OrientationUseCaseResult } from "../../ui/markdown/types.ts";
13
20
  import { unavailableContextDetails } from "../infra/error-results.ts";
14
21
  import { prepareOrientationDeps } from "./deps.ts";
15
22
  import type { CodeOrientationToolParams } from "./execute.ts";
@@ -50,8 +57,52 @@ export async function runOrientationMode(
50
57
  },
51
58
  { ...deps, cwd: ctx.cwd },
52
59
  );
60
+ const withInstructions = addInstructionFilesForDirectoryFocus(result, focusResolution.path, ctx);
53
61
 
54
- return { content: result.content, details: { type: "context", data: result.details } };
62
+ return {
63
+ content: withInstructions.content,
64
+ details: { type: "context", data: withInstructions.details },
65
+ };
66
+ }
67
+
68
+ function addInstructionFilesForDirectoryFocus(
69
+ result: OrientationUseCaseResult,
70
+ focusPath: string | undefined,
71
+ ctx: CodeIntelToolExecCtx,
72
+ ): OrientationUseCaseResult {
73
+ if (!focusPath || !isDirectory(focusPath)) return result;
74
+
75
+ const config = loadCodeIntelligenceConfig(ctx.cwd);
76
+ const matches = findInstructionFilesForDirectory({
77
+ directory: focusPath,
78
+ cwd: ctx.cwd,
79
+ fileNames: config.instructionFileNames,
80
+ nativeContextPaths: ctx.session.nativeInstructionPaths,
81
+ surfacedDirectories: ctx.session.surfacedInstructionDirs,
82
+ });
83
+ if (matches.length === 0) return result;
84
+
85
+ const rendered = renderInstructionFiles(matches);
86
+ if (!rendered) return result;
87
+
88
+ ctx.session.markInstructionDirsSurfaced(rendered.metadata.files.map((file) => file.directory));
89
+
90
+ return {
91
+ content: insertInstructionsNearTop(result.content, rendered.markdown),
92
+ details: {
93
+ ...result.details,
94
+ renderedSections: ["instructions", ...result.details.renderedSections],
95
+ instructions: rendered.metadata,
96
+ },
97
+ };
98
+ }
99
+
100
+ function isDirectory(filePath: string): boolean {
101
+ try {
102
+ return statSync(filePath).isDirectory();
103
+ } catch {
104
+ return false;
105
+ }
55
106
  }
56
107
 
57
108
  /**
@@ -1,5 +1,6 @@
1
1
  import type { ConfidenceMode } from "@mrclrchtr/supi-code-runtime/api";
2
2
  import type { EvidenceListMetadata } from "../../analysis/evidence.ts";
3
+ import type { InstructionFilesMetadata } from "../../analysis/instruction-files.ts";
3
4
  import type { PrioritySignalsSummary } from "../../analysis/signals/project.ts";
4
5
  import type { TestSurfaceDetails } from "../../analysis/tests/test-discovery.ts";
5
6
  import type { AnchorKind, TargetStoreEntry } from "../../session/target-store.ts";
@@ -143,6 +144,8 @@ export interface ContextDetails {
143
144
  evidenceLists?: EvidenceListMetadata[];
144
145
  nextQueries: string[];
145
146
  tests?: TestSurfaceDetails;
147
+ /** Directory-local instruction files surfaced during directory orientation. */
148
+ instructions?: InstructionFilesMetadata;
146
149
  /**
147
150
  * Resolved target store entry — populated for both coordinate and targetId
148
151
  * precise-target inputs. Absent for orientation/scope-only calls and for
@@ -3,27 +3,26 @@ import { type TSchema, Type } from "typebox";
3
3
  import type { CodeIntelligenceToolName } from "../types/index.ts";
4
4
 
5
5
  const ScopeParam = Type.String({
6
- description: "Workspace-relative path, package, or directory scope for the workflow query.",
6
+ description: "Workspace-relative file or directory scope.",
7
7
  });
8
8
  const FindScopeParam = Type.Union(
9
9
  [
10
10
  Type.String({
11
- description: "Workspace-relative path, package, or directory scope for the search query.",
11
+ description: "Workspace-relative search scope.",
12
12
  }),
13
13
  Type.Array(
14
14
  Type.String({
15
- description: "Workspace-relative path, package, or directory search scope.",
15
+ description: "Workspace-relative search scope.",
16
16
  }),
17
17
  {
18
- description: "One or more workspace-relative paths, packages, or directories to search.",
18
+ description: "One or more workspace-relative search scopes.",
19
19
  minItems: 1,
20
20
  uniqueItems: true,
21
21
  },
22
22
  ),
23
23
  ],
24
24
  {
25
- description:
26
- "Workspace-relative path, package, directory, or array of scopes for the search query.",
25
+ description: "Workspace-relative search scope or scope list.",
27
26
  },
28
27
  );
29
28
  const FileParam = Type.String({ description: "Target file path." });
@@ -36,13 +35,13 @@ const CharacterParam = Type.Number({
36
35
  minimum: 1,
37
36
  });
38
37
  const MaxResultsParam = Type.Number({
39
- description: "Maximum number of ranked results.",
38
+ description: "Maximum results.",
40
39
  minimum: 1,
41
40
  });
42
41
  const SymbolParam = Type.String({ description: "Symbol name" });
43
42
  const TargetIdParam = Type.String({
44
43
  description:
45
- "Resolved target handle from `code_resolve`. Takes precedence over file/line/character/symbol.",
44
+ "Resolved target handle from `code_resolve`; takes precedence over other target inputs.",
46
45
  });
47
46
  const RangeParam = Type.Object(
48
47
  {
@@ -114,25 +113,23 @@ export const CodeOrientationParameters = Type.Object(
114
113
  {
115
114
  focus: Type.Optional(
116
115
  Type.String({
117
- description:
118
- "Workspace-relative path or discovered module name to orient around. Omit for project orientation.",
116
+ description: "Workspace-relative path or module name; omit for workspace orientation.",
119
117
  }),
120
118
  ),
121
119
  targetId: Type.Optional(
122
120
  Type.String({
123
- description:
124
- "Resolved target handle from `code_resolve`. Takes precedence over `focus`/`line`/`character`. If invalid or stale, the call errors and does not fall back to coordinates.",
121
+ description: "Resolved target handle; takes precedence, stale IDs error.",
125
122
  }),
126
123
  ),
127
124
  line: Type.Optional(
128
125
  Type.Number({
129
- description: "1-based line for symbol orientation. Requires `focus` and `character`.",
126
+ description: "1-based line for symbol orientation with `focus`.",
130
127
  minimum: 1,
131
128
  }),
132
129
  ),
133
130
  character: Type.Optional(
134
131
  Type.Number({
135
- description: "1-based UTF-16 column for symbol orientation. Requires `focus` and `line`.",
132
+ description: "1-based UTF-16 column for symbol orientation with `focus`.",
136
133
  minimum: 1,
137
134
  }),
138
135
  ),
@@ -153,8 +150,7 @@ export const CodeFindParameters = Type.Object(
153
150
  scope: Type.Optional(FindScopeParam),
154
151
  mode: Type.Optional(
155
152
  StringEnum(["text", "regex", "ast", "semantic"], {
156
- description:
157
- 'Search mode. Omit for literal text search. mode: "ast" requires `kind`; mode: "text", mode: "regex", and mode: "semantic" do not accept `kind`.',
153
+ description: 'Search mode; omit for literal text. mode:"ast" requires `kind`.',
158
154
  }),
159
155
  ),
160
156
  kind: Type.Optional(
@@ -172,13 +168,12 @@ export const CodeFindParameters = Type.Object(
172
168
  "test",
173
169
  ],
174
170
  {
175
- description:
176
- 'Only valid with `mode: "ast"`. Supported AST kinds: `definition`, `import`, `export`, `call`, `type`, `interface`, `class`, `method`, `enum`, `test`. AST `call` matches call-site identifiers by name, not by symbol identity.',
171
+ description: 'AST kind; only valid with mode:"ast".',
177
172
  },
178
173
  ),
179
174
  ),
180
175
  contextLines: Type.Optional(
181
- Type.Number({ description: "Context lines to include around matches.", minimum: 0 }),
176
+ Type.Number({ description: "Context lines around matches.", minimum: 0 }),
182
177
  ),
183
178
  maxResults: Type.Optional(MaxResultsParam),
184
179
  },
@@ -205,11 +200,10 @@ export const CodeGraphParameters = Type.Object(
205
200
  relations: Type.Optional(
206
201
  Type.Array(
207
202
  StringEnum(["all", "references", "callees", "imports", "exports", "implements", "tests"], {
208
- description:
209
- 'Relation families to include in the graph. Use `"all"` to expand to every relation family. `callees` is direct structural outgoing-call evidence: source-shape calls in the enclosing scope, not symbol-identity resolution.',
203
+ description: "Relation family.",
210
204
  }),
211
205
  {
212
- description: 'Requested relation families. Defaults to ["references"] when omitted.',
206
+ description: 'Requested relation families; defaults to ["references"].',
213
207
  uniqueItems: true,
214
208
  },
215
209
  ),
@@ -217,8 +211,7 @@ export const CodeGraphParameters = Type.Object(
217
211
  maxResults: Type.Optional(MaxResultsParam),
218
212
  calleeDepth: Type.Optional(
219
213
  StringEnum(["direct", "deep"], {
220
- description:
221
- 'Depth for callee collection. `"direct"` (default): only direct calls from the enclosing scope, excluding nested function/callback scopes. `"deep"`: include all callees within the enclosing scope, including those inside nested scopes.',
214
+ description: '`"direct"` excludes nested scopes; `"deep"` includes them.',
222
215
  }),
223
216
  ),
224
217
  },
@@ -241,8 +234,7 @@ export const CodeImpactParameters = Type.Object(
241
234
  ),
242
235
  changeSetFiles: Type.Optional(
243
236
  Type.Array(Type.String({ description: "Workspace-relative file in the change set." }), {
244
- description:
245
- "User-supplied files to analyze as the change set. This is not inferred from git and carries no line-level diff evidence.",
237
+ description: "Explicit change-set files; not inferred from git and no line-level diff.",
246
238
  minItems: 1,
247
239
  uniqueItems: true,
248
240
  }),
@@ -250,7 +242,7 @@ export const CodeImpactParameters = Type.Object(
250
242
  includeTests: Type.Optional(
251
243
  Type.Boolean({
252
244
  description:
253
- "Whether likely tests should be included in the impact set. changeSetFiles analysis uses semantic references when available plus deterministic conventions; target-based analysis may combine semantic references with deterministic conventions.",
245
+ "Include likely tests using semantic references and deterministic conventions.",
254
246
  }),
255
247
  ),
256
248
  maxResults: Type.Optional(MaxResultsParam),
@@ -272,8 +264,7 @@ export const CodeImpactParameters = Type.Object(
272
264
  export const CodeRefactorParameters = Type.Object(
273
265
  {
274
266
  operation: StringEnum(["rename", "rename_symbol", "extract_function", "extract_variable"], {
275
- description:
276
- "Precise refactor operation to plan. `rename` is accepted as a compatibility alias for `rename_symbol`.",
267
+ description: "Refactor operation; `rename` is an alias for `rename_symbol`.",
277
268
  }),
278
269
  targetId: Type.Optional(
279
270
  Type.String({ description: "Resolved target handle from `code_resolve`." }),
@@ -329,13 +320,12 @@ export const CodeHealthParameters = Type.Object(
329
320
  ),
330
321
  coveragePath: Type.Optional(
331
322
  Type.String({
332
- description:
333
- "Workspace-relative path to a coverage summary JSON file. Defaults to `coverage/coverage-summary.json`.",
323
+ description: "Coverage summary path; defaults to `coverage/coverage-summary.json`.",
334
324
  }),
335
325
  ),
336
326
  unusedPath: Type.Optional(
337
327
  Type.String({
338
- description: "Workspace-relative path to a knip JSON report. Defaults to `knip.json`.",
328
+ description: "Knip report path; defaults to `knip.json`.",
339
329
  }),
340
330
  ),
341
331
  },
@@ -1,207 +0,0 @@
1
- // Config-aware settings contribution helper for SuPi packages.
2
- //
3
- // Registers config-backed settings sections through PI's shared event bus so
4
- // /supi-settings can collect contributions from all loaded extensions without
5
- // relying on a shared supi-core module instance.
6
-
7
- import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
8
- import type { SettingItem } from "@earendil-works/pi-tui";
9
- import {
10
- isSettingsContributionCollector,
11
- type SettingsScope,
12
- type SettingsSection,
13
- SUPI_SETTINGS_COLLECT_EVENT,
14
- } from "../settings/settings-registry.ts";
15
- import { loadSupiConfigForScope, removeSupiConfigKey, writeSupiConfig } from "./config.ts";
16
-
17
- // ── Types ──────────────────────────────────────────────────────────────────
18
-
19
- /**
20
- * Supported config value types for declarative persistChange.
21
- *
22
- * - `"boolean"`: maps "on" → true, "off" → false
23
- * - `"number"`: parses integer via Number.parseInt, falls back to unset on invalid
24
- * - `"stringList"`: splits on comma, trims whitespace, unsets on empty
25
- */
26
- export type ConfigSettingType = "boolean" | "number" | "stringList";
27
-
28
- /** Extended setting item that can declare its config type for persistence. */
29
- export interface ConfigSettingItem extends SettingItem {
30
- /** Config value type used for auto-generated persistence. */
31
- configType?: ConfigSettingType;
32
- }
33
-
34
- /** Helpers provided to persistChange for scoped SuPi config writes. */
35
- export interface ConfigSettingsHelpers {
36
- /** Write a key to the selected scope's config section. */
37
- set(key: string, value: unknown): void;
38
- /** Remove a key from the selected scope's config section. */
39
- unset(key: string): void;
40
- }
41
-
42
- export interface ConfigSettingsPersistedChange {
43
- scope: SettingsScope;
44
- cwd: string;
45
- settingId: string;
46
- value: string;
47
- }
48
-
49
- export interface ConfigSettingsOptions<T> {
50
- /** Settings contribution identifier — e.g. "lsp", "claude-md". */
51
- id: string;
52
- /** Human-readable label shown in the UI. */
53
- label: string;
54
- /** SuPi config section name — e.g. "lsp", "claude-md". */
55
- section: string;
56
- /** Default config values. */
57
- defaults: T;
58
- /** Build SettingItem[] from scoped config. */
59
- buildItems: (
60
- settings: T,
61
- scope: SettingsScope,
62
- cwd: string,
63
- ctx?: ExtensionContext,
64
- ) => ConfigSettingItem[];
65
- /**
66
- * Convert a UI value into scoped SuPi config writes.
67
- *
68
- * Optional when every item returned by `buildItems` declares `configType`.
69
- * Required when any item lacks `configType`.
70
- */
71
- persistChange?: (
72
- scope: SettingsScope,
73
- cwd: string,
74
- settingId: string,
75
- value: string,
76
- helpers: ConfigSettingsHelpers,
77
- ) => void;
78
- /** Optional live runtime sync after successful persistence. */
79
- afterPersist?: (change: ConfigSettingsPersistedChange) => void;
80
- /** Optional home directory for config resolution (testing). */
81
- homeDir?: string;
82
- }
83
-
84
- // ── Auto-generated persistChange ───────────────────────────────────────────
85
-
86
- function autoPersistChange(
87
- settingId: string,
88
- value: string,
89
- helpers: ConfigSettingsHelpers,
90
- items: ConfigSettingItem[],
91
- ): void {
92
- const item = items.find((i) => i.id === settingId);
93
- if (!item?.configType) return;
94
-
95
- switch (item.configType) {
96
- case "boolean": {
97
- helpers.set(settingId, value === "on");
98
- break;
99
- }
100
- case "number": {
101
- const num = Number.parseInt(value, 10);
102
- if (Number.isFinite(num) && num > 0) {
103
- helpers.set(settingId, num);
104
- } else {
105
- helpers.unset(settingId);
106
- }
107
- break;
108
- }
109
- case "stringList": {
110
- const names = value
111
- .split(",")
112
- .map((s) => s.trim())
113
- .filter((s) => s.length > 0);
114
- if (names.length > 0) {
115
- helpers.set(settingId, names);
116
- } else {
117
- helpers.unset(settingId);
118
- }
119
- break;
120
- }
121
- }
122
- }
123
-
124
- function areAllItemsDeclarative(items: ConfigSettingItem[]): boolean {
125
- return items.length > 0 && items.every((i) => i.configType !== undefined);
126
- }
127
-
128
- function createHelpers<T>(options: ConfigSettingsOptions<T>, scope: SettingsScope, cwd: string) {
129
- return {
130
- set: (key: string, val: unknown) => {
131
- writeSupiConfig(
132
- { section: options.section, scope, cwd },
133
- { [key]: val },
134
- { homeDir: options.homeDir },
135
- );
136
- },
137
- unset: (key: string) => {
138
- removeSupiConfigKey({ section: options.section, scope, cwd }, key, {
139
- homeDir: options.homeDir,
140
- });
141
- },
142
- } satisfies ConfigSettingsHelpers;
143
- }
144
-
145
- function toSettingsSection<T>(options: ConfigSettingsOptions<T>): SettingsSection {
146
- let cachedItems: ConfigSettingItem[] | undefined;
147
-
148
- return {
149
- id: options.id,
150
- label: options.label,
151
- loadValues: (scope, cwd, ctx) => {
152
- const settings = loadSupiConfigForScope(options.section, cwd, options.defaults, {
153
- scope,
154
- homeDir: options.homeDir,
155
- });
156
- const items = options.buildItems(settings, scope, cwd, ctx);
157
- cachedItems = items;
158
- return items;
159
- },
160
- persistChange: (scope, cwd, settingId, value) => {
161
- const helpers = createHelpers(options, scope, cwd);
162
-
163
- if (options.persistChange) {
164
- options.persistChange(scope, cwd, settingId, value, helpers);
165
- } else {
166
- const items = cachedItems ?? options.buildItems(options.defaults, scope, cwd, undefined);
167
- if (!areAllItemsDeclarative(items)) {
168
- throw new Error(
169
- `Settings contribution "${options.id}" needs persistChange or configType on every item.`,
170
- );
171
- }
172
- autoPersistChange(settingId, value, helpers, items);
173
- }
174
-
175
- try {
176
- options.afterPersist?.({ scope, cwd, settingId, value });
177
- } catch (error) {
178
- const message = error instanceof Error ? error.message : String(error);
179
- throw new Error(`Saved setting, but live sync failed: ${message}`, { cause: error });
180
- }
181
- },
182
- };
183
- }
184
-
185
- // ── Registration ───────────────────────────────────────────────────────────
186
-
187
- /**
188
- * Register a config-backed settings contribution for `/supi-settings`.
189
- *
190
- * Contributions are collected through PI's process-local event bus. Call this
191
- * during the extension factory function, not in async session handlers.
192
- */
193
- export function registerConfigSettings<T>(
194
- pi: ExtensionAPI,
195
- options: ConfigSettingsOptions<T>,
196
- ): void {
197
- const section = toSettingsSection(options);
198
- const dispose = pi.events.on(SUPI_SETTINGS_COLLECT_EVENT, (collector) => {
199
- if (isSettingsContributionCollector(collector)) {
200
- collector.add(section);
201
- }
202
- });
203
-
204
- pi.on("session_shutdown", () => {
205
- dispose();
206
- });
207
- }