@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.
- package/README.md +17 -3
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/README.md +9 -8
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -3
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -5
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/scoped-settings-list.ts +372 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-action-menu.ts +101 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +13 -7
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +464 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-submenus.ts +124 -0
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +50 -309
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +2 -5
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings.ts +17 -1
- package/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-core/README.md +9 -8
- package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -3
- package/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -5
- package/node_modules/@mrclrchtr/supi-core/src/settings/scoped-settings-list.ts +372 -0
- package/node_modules/@mrclrchtr/supi-core/src/settings/settings-action-menu.ts +101 -0
- package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +13 -7
- package/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +464 -0
- package/node_modules/@mrclrchtr/supi-core/src/settings/settings-submenus.ts +124 -0
- package/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +50 -309
- package/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +2 -5
- package/node_modules/@mrclrchtr/supi-core/src/settings.ts +17 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/README.md +9 -8
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -3
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -5
- 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
- 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
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +13 -7
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +464 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-submenus.ts +124 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +50 -309
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +2 -5
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings.ts +17 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/README.md +9 -8
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -3
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -5
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/scoped-settings-list.ts +372 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-action-menu.ts +101 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +13 -7
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +464 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-submenus.ts +124 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +50 -309
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +2 -5
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings.ts +17 -1
- package/node_modules/@mrclrchtr/supi-lsp/package.json +3 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +49 -12
- package/node_modules/@mrclrchtr/supi-lsp/src/config/lsp-settings.ts +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/README.md +9 -8
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -5
- 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
- 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
- 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
- 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
- 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
- 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
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +2 -5
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings.ts +17 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/README.md +9 -8
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -5
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/scoped-settings-list.ts +372 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-action-menu.ts +101 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +13 -7
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +464 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-submenus.ts +124 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +50 -309
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings-ui.ts +2 -5
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings.ts +17 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +3 -3
- package/package.json +5 -5
- package/src/analysis/instruction-files.ts +194 -0
- package/src/app/app.ts +6 -1
- package/src/config.ts +42 -0
- package/src/extension.ts +27 -0
- package/src/session/session.ts +67 -0
- package/src/substrate/lsp/diagnostic-injection.ts +0 -15
- package/src/substrate/lsp/settings.ts +101 -179
- package/src/tool/guidance.ts +27 -38
- package/src/tool/orientation/mode.ts +53 -2
- package/src/tool/result/types.ts +3 -0
- package/src/tool/schemas.ts +22 -32
- package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +0 -207
- package/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +0 -207
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +0 -207
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +0 -207
- 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
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +0 -207
package/src/tool/guidance.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
"
|
|
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
|
-
'
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
|
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
|
|
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
|
-
'
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
"
|
|
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
|
|
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
|
-
"
|
|
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
|
|
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 {
|
|
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
|
/**
|
package/src/tool/result/types.ts
CHANGED
|
@@ -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
|
package/src/tool/schemas.ts
CHANGED
|
@@ -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
|
|
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
|
|
11
|
+
description: "Workspace-relative search scope.",
|
|
12
12
|
}),
|
|
13
13
|
Type.Array(
|
|
14
14
|
Type.String({
|
|
15
|
-
description: "Workspace-relative
|
|
15
|
+
description: "Workspace-relative search scope.",
|
|
16
16
|
}),
|
|
17
17
|
{
|
|
18
|
-
description: "One or more workspace-relative
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
"
|
|
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: "
|
|
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
|
-
}
|