@mrclrchtr/supi-code-intelligence 5.0.0 → 6.0.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.
- package/README.md +2 -2
- package/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-core/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-core/src/api.ts +1 -1
- package/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -3
- package/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
- package/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/README.md +34 -3
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/api.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -3
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
- package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/package.json +3 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +12 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-cache.ts +67 -28
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-collection.ts +63 -6
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-evidence.ts +46 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-host.ts +1 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-publication.ts +214 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-refresh.ts +278 -79
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-timing.ts +29 -8
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostics.ts +101 -19
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-state.ts +19 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-sync.ts +49 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +73 -15
- package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +1 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +2 -2
- package/node_modules/@mrclrchtr/supi-lsp/src/config/config.ts +5 -5
- package/node_modules/@mrclrchtr/supi-lsp/src/config/server-config.ts +3 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-extends.ts +68 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-path.ts +8 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/config/tsconfig-scope.ts +176 -24
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/evidence.ts +4 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/workspace-sentinels.ts +46 -10
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-diagnostics.ts +4 -3
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +65 -17
- package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +143 -21
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostic-surface.ts +2 -0
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostics.ts +43 -1
- package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registry.ts +31 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +2 -2
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/api.ts +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +0 -3
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug.ts +9 -0
- package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/index.ts +1 -1
- package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +3 -3
- package/package.json +5 -5
- package/src/analysis/health/diagnostics.ts +58 -126
- package/src/analysis/health/file-scope.ts +184 -0
- package/src/analysis/health/recovery.ts +8 -1
- package/src/analysis/readiness.ts +4 -0
- package/src/analysis/search/ast-scan.ts +4 -1
- package/src/analysis/search/pattern-analysis.ts +10 -3
- package/src/analysis/search/pattern.ts +6 -1
- package/src/config.ts +35 -1
- package/src/extension.ts +57 -14
- package/src/overview/overview-data.ts +9 -2
- package/src/overview/overview.ts +49 -30
- package/src/overview/types.ts +2 -0
- package/src/session/find-types.ts +2 -2
- package/src/session/find-workflow.ts +3 -2
- package/src/session/health-refresh.ts +76 -49
- package/src/session/health-types.ts +7 -1
- package/src/session/health-workflow.ts +35 -18
- package/src/session/input/workflows.ts +2 -2
- package/src/session/inspect-workflow.ts +2 -1
- package/src/session/orientation/collect.ts +2 -2
- package/src/session/orientation-types.ts +2 -0
- package/src/session/orientation-workflow.ts +8 -2
- package/src/session/refactor-workflow.ts +2 -1
- package/src/session/session.ts +25 -1
- package/src/substrate/lsp/maintenance.ts +105 -23
- package/src/substrate/lsp/recovery.ts +11 -5
- package/src/tool/code_find/execute.ts +23 -0
- package/src/tool/code_find/guidance.ts +8 -0
- package/src/tool/{find → code_find}/render.ts +1 -1
- package/src/tool/{result/find.ts → code_find/result.ts} +36 -11
- package/src/tool/code_find/spec.ts +37 -0
- package/src/tool/code_graph/execute.ts +24 -0
- package/src/tool/code_graph/guidance.ts +6 -0
- package/src/tool/{graph → code_graph}/markdown.ts +1 -1
- package/src/tool/{result/graph.ts → code_graph/result.ts} +69 -4
- package/src/tool/code_graph/spec.ts +39 -0
- package/src/tool/{health → code_health}/execute.ts +2 -18
- package/src/tool/code_health/guidance.ts +8 -0
- package/src/tool/{health → code_health}/markdown.ts +68 -18
- package/src/tool/{result/health.ts → code_health/result.ts} +29 -4
- package/src/tool/code_health/spec.ts +41 -0
- package/src/tool/code_inspect/execute.ts +20 -0
- package/src/tool/code_inspect/guidance.ts +6 -0
- package/src/tool/{inspect → code_inspect}/markdown.ts +1 -1
- package/src/tool/{result/inspect.ts → code_inspect/result.ts} +32 -3
- package/src/tool/code_inspect/spec.ts +25 -0
- package/src/tool/code_orientation/execute.ts +25 -0
- package/src/tool/code_orientation/guidance.ts +9 -0
- package/src/tool/{orientation → code_orientation}/markdown.ts +1 -1
- package/src/tool/{result/orientation.ts → code_orientation/result.ts} +67 -3
- package/src/tool/code_orientation/spec.ts +25 -0
- package/src/tool/code_refactor_apply/execute.ts +17 -0
- package/src/tool/code_refactor_apply/guidance.ts +5 -0
- package/src/tool/{refactor-apply/execute.ts → code_refactor_apply/result.ts} +5 -11
- package/src/tool/code_refactor_apply/spec.ts +26 -0
- package/src/tool/code_refactor_plan/execute.ts +27 -0
- package/src/tool/code_refactor_plan/guidance.ts +8 -0
- package/src/tool/{refactor-plan/execute.ts → code_refactor_plan/result.ts} +9 -22
- package/src/tool/code_refactor_plan/spec.ts +25 -0
- package/src/tool/code_resolve/execute.ts +19 -0
- package/src/tool/code_resolve/guidance.ts +8 -0
- package/src/tool/{resolve → code_resolve}/markdown.ts +1 -1
- package/src/tool/{result/resolve.ts → code_resolve/result.ts} +37 -24
- package/src/tool/code_resolve/spec.ts +25 -0
- package/src/tool/guidance.ts +71 -52
- package/src/tool/infra/truncate.ts +40 -0
- package/src/tool/{refactor-plan/markdown.ts → refactor-markdown.ts} +4 -7
- package/src/tool/register.ts +9 -97
- package/src/tool/result/refactor.ts +1 -4
- package/src/tool/schemas.ts +26 -157
- package/src/tool/specs.ts +40 -126
- package/src/tool/find/execute.ts +0 -43
- package/src/tool/graph/execute.ts +0 -82
- package/src/tool/inspect/execute.ts +0 -40
- package/src/tool/orientation/execute.ts +0 -80
- package/src/tool/resolve/execute.ts +0 -53
- /package/src/tool/{find → code_find}/ast-kinds.ts +0 -0
- /package/src/tool/{find → code_find}/markdown.ts +0 -0
- /package/src/tool/{find → code_find}/modes.ts +0 -0
- /package/src/tool/{find → code_find}/tui.ts +0 -0
- /package/src/tool/{graph → code_graph}/tui.ts +0 -0
- /package/src/tool/{health → code_health}/refresh-status.ts +0 -0
- /package/src/tool/{health → code_health}/semantic-state.ts +0 -0
- /package/src/tool/{health → code_health}/tui.ts +0 -0
- /package/src/tool/{inspect → code_inspect}/tui.ts +0 -0
- /package/src/tool/{orientation → code_orientation}/tui.ts +0 -0
- /package/src/tool/{refactor-apply → code_refactor_apply}/tui.ts +0 -0
- /package/src/tool/{refactor-plan → code_refactor_plan}/tui.ts +0 -0
- /package/src/tool/{resolve → code_resolve}/tui.ts +0 -0
|
@@ -4,6 +4,7 @@ import type { CapabilityState } from "@mrclrchtr/supi-code-runtime/api";
|
|
|
4
4
|
import { isCodeRequestInterruption } from "@mrclrchtr/supi-code-runtime/api";
|
|
5
5
|
import type {
|
|
6
6
|
LspRuntimeController,
|
|
7
|
+
WorkspaceDiagnosticReport,
|
|
7
8
|
WorkspaceLspRuntime,
|
|
8
9
|
WorkspaceLspRuntimeState,
|
|
9
10
|
} from "@mrclrchtr/supi-lsp/api";
|
|
@@ -18,6 +19,7 @@ import {
|
|
|
18
19
|
} from "../analysis/health/diagnostics.ts";
|
|
19
20
|
import { describeStructuralState } from "../analysis/health/recovery.ts";
|
|
20
21
|
import { collectServers } from "../analysis/health/signals.ts";
|
|
22
|
+
import { SEMANTIC_READINESS_TIMEOUT_REASON } from "../analysis/readiness.ts";
|
|
21
23
|
import { resolveScope } from "../analysis/search/paths.ts";
|
|
22
24
|
import type { CapabilityAdapter } from "./capability-adapter.ts";
|
|
23
25
|
import { collectHealthRefreshAttempt } from "./health-refresh.ts";
|
|
@@ -72,7 +74,7 @@ export async function runHealthWorkflow(
|
|
|
72
74
|
const serverInventoryAvailable = lspState.kind === "ready" || lspState.kind === "disabled";
|
|
73
75
|
|
|
74
76
|
const diagnosticsScope = diagnosticScope(scopeFilter);
|
|
75
|
-
const
|
|
77
|
+
const refreshCollection = await collectRefreshState({
|
|
76
78
|
refreshRequested: request.refresh === true,
|
|
77
79
|
diagnosticsRequested: included.includes("diagnostics"),
|
|
78
80
|
runtime,
|
|
@@ -102,10 +104,12 @@ export async function runHealthWorkflow(
|
|
|
102
104
|
detailed: level === "detailed",
|
|
103
105
|
requestControl: control,
|
|
104
106
|
refreshEvidence:
|
|
105
|
-
(
|
|
106
|
-
|
|
107
|
-
|
|
107
|
+
(refreshCollection.attempt.kind === "completed" ||
|
|
108
|
+
refreshCollection.attempt.kind === "failed") &&
|
|
109
|
+
refreshCollection.attempt.operationScope === "workspace-runtime"
|
|
110
|
+
? refreshCollection.attempt.diagnosticEvidence
|
|
108
111
|
: undefined,
|
|
112
|
+
refreshReport: refreshCollection.diagnosticReport,
|
|
109
113
|
});
|
|
110
114
|
// A cancellation that landed during diagnostic resolution must not produce
|
|
111
115
|
// a completed health result the caller no longer awaits.
|
|
@@ -121,7 +125,7 @@ export async function runHealthWorkflow(
|
|
|
121
125
|
structuralStatus: describeStructuralState(capabilityStates.structural),
|
|
122
126
|
diagnostics,
|
|
123
127
|
servers,
|
|
124
|
-
refresh,
|
|
128
|
+
refresh: refreshCollection.attempt,
|
|
125
129
|
level,
|
|
126
130
|
capabilityWarnings: capabilityWarnings?.hasWarnings ? capabilityWarnings : undefined,
|
|
127
131
|
};
|
|
@@ -154,7 +158,7 @@ async function establishSemanticHealthState(
|
|
|
154
158
|
);
|
|
155
159
|
if (readiness.kind === "ready") return { kind: "ready" };
|
|
156
160
|
if (readiness.kind === "timeout") {
|
|
157
|
-
return { kind: "pending", reason:
|
|
161
|
+
return { kind: "pending", reason: SEMANTIC_READINESS_TIMEOUT_REASON };
|
|
158
162
|
}
|
|
159
163
|
return { kind: "unavailable", reason: readiness.reason };
|
|
160
164
|
}
|
|
@@ -213,6 +217,11 @@ function collectCapabilityWarnings(
|
|
|
213
217
|
return report.hasWarnings ? report : undefined;
|
|
214
218
|
}
|
|
215
219
|
|
|
220
|
+
interface HealthRefreshStateCollection {
|
|
221
|
+
readonly attempt: HealthRefreshState;
|
|
222
|
+
readonly diagnosticReport?: WorkspaceDiagnosticReport;
|
|
223
|
+
}
|
|
224
|
+
|
|
216
225
|
interface RefreshStateOptions {
|
|
217
226
|
readonly refreshRequested: boolean;
|
|
218
227
|
readonly diagnosticsRequested: boolean;
|
|
@@ -224,27 +233,35 @@ interface RefreshStateOptions {
|
|
|
224
233
|
}
|
|
225
234
|
|
|
226
235
|
/** Run the requested workspace-runtime refresh and retain only facts the runtime establishes. */
|
|
227
|
-
async function collectRefreshState(
|
|
236
|
+
async function collectRefreshState(
|
|
237
|
+
options: RefreshStateOptions,
|
|
238
|
+
): Promise<HealthRefreshStateCollection> {
|
|
228
239
|
const { deps, diagnosticsRequested, diagnosticsScope, lspState, runtime } = options;
|
|
229
240
|
if (!diagnosticsRequested) {
|
|
230
241
|
return {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
242
|
+
attempt: {
|
|
243
|
+
kind: "not-requested",
|
|
244
|
+
reason: "Diagnostics were not requested.",
|
|
245
|
+
lastAttempt: deps.lastRefreshAttempt,
|
|
246
|
+
},
|
|
234
247
|
};
|
|
235
248
|
}
|
|
236
249
|
if (!options.refreshRequested) {
|
|
237
250
|
return {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
251
|
+
attempt: {
|
|
252
|
+
kind: "not-requested",
|
|
253
|
+
reason: "Refresh was not requested.",
|
|
254
|
+
lastAttempt: deps.lastRefreshAttempt,
|
|
255
|
+
},
|
|
241
256
|
};
|
|
242
257
|
}
|
|
243
258
|
if (!runtime) {
|
|
244
259
|
return {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
260
|
+
attempt: {
|
|
261
|
+
kind: "not-attempted",
|
|
262
|
+
reason: refreshUnavailableReason(lspState),
|
|
263
|
+
lastAttempt: deps.lastRefreshAttempt,
|
|
264
|
+
},
|
|
248
265
|
};
|
|
249
266
|
}
|
|
250
267
|
|
|
@@ -270,7 +287,7 @@ async function collectRefreshState(options: RefreshStateOptions): Promise<Health
|
|
|
270
287
|
message: "Refreshing diagnostics and recovery state",
|
|
271
288
|
}),
|
|
272
289
|
});
|
|
273
|
-
deps.trackRefreshAttempt(attempt);
|
|
290
|
+
deps.trackRefreshAttempt(attempt.attempt);
|
|
274
291
|
return attempt;
|
|
275
292
|
} catch (error) {
|
|
276
293
|
// Cancellation must propagate; a cancelled caller no longer awaits a
|
|
@@ -285,7 +302,7 @@ async function collectRefreshState(options: RefreshStateOptions): Promise<Health
|
|
|
285
302
|
reason: errorMessage(error),
|
|
286
303
|
};
|
|
287
304
|
deps.trackRefreshAttempt(attempt);
|
|
288
|
-
return attempt;
|
|
305
|
+
return { attempt };
|
|
289
306
|
}
|
|
290
307
|
}
|
|
291
308
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Runtime parsers for inspection, Orientation, graph, and find workflows. */
|
|
2
2
|
|
|
3
|
-
import { type CodeFindAstKind, isCodeFindAstKind } from "../../tool/
|
|
4
|
-
import { CODE_FIND_MODES } from "../../tool/
|
|
3
|
+
import { type CodeFindAstKind, isCodeFindAstKind } from "../../tool/code_find/ast-kinds.ts";
|
|
4
|
+
import { CODE_FIND_MODES } from "../../tool/code_find/modes.ts";
|
|
5
5
|
import type { FindMode, FindWorkflowInput } from "../find-types.ts";
|
|
6
6
|
import type { GraphWorkflowInput, RequestedGraphRelation } from "../graph-types.ts";
|
|
7
7
|
import type { InspectWorkflowInput } from "../inspect-types.ts";
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import type { WorkspaceLspRuntimeState } from "@mrclrchtr/supi-lsp/api";
|
|
4
4
|
import { withSemanticRequestControl } from "../analysis/provider.ts";
|
|
5
|
+
import { SEMANTIC_READINESS_TIMEOUT_REASON } from "../analysis/readiness.ts";
|
|
5
6
|
import type { CapabilityAdapter, ReadinessOutcome } from "./capability-adapter.ts";
|
|
6
7
|
import { parseInspectWorkflowInput } from "./input/workflows.ts";
|
|
7
8
|
import { collectInspectSections } from "./inspect/collect.ts";
|
|
@@ -155,7 +156,7 @@ function semanticReadinessReason(readiness: ReadinessOutcome): string {
|
|
|
155
156
|
case "ready":
|
|
156
157
|
return "No semantic provider is active for this file.";
|
|
157
158
|
case "timeout":
|
|
158
|
-
return
|
|
159
|
+
return SEMANTIC_READINESS_TIMEOUT_REASON;
|
|
159
160
|
case "unavailable":
|
|
160
161
|
return readiness.reason;
|
|
161
162
|
}
|
|
@@ -183,7 +183,7 @@ async function buildEnrichedDefsSection(
|
|
|
183
183
|
hasStructuralEvidence,
|
|
184
184
|
hasSemanticEvidence: contextHasSemanticEvidence,
|
|
185
185
|
status: contextHasSemanticEvidence ? "partial" : "unavailable",
|
|
186
|
-
reason: "Definition targets require a live language server.",
|
|
186
|
+
reason: deps.semanticReadinessReason ?? "Definition targets require a live language server.",
|
|
187
187
|
evidenceLists: [],
|
|
188
188
|
};
|
|
189
189
|
}
|
|
@@ -292,7 +292,7 @@ async function buildDiagnosticsSection(
|
|
|
292
292
|
},
|
|
293
293
|
],
|
|
294
294
|
false,
|
|
295
|
-
"Diagnostics require a live language server.",
|
|
295
|
+
deps.semanticReadinessReason ?? "Diagnostics require a live language server.",
|
|
296
296
|
);
|
|
297
297
|
}
|
|
298
298
|
|
|
@@ -37,6 +37,8 @@ export interface OrientationDeps {
|
|
|
37
37
|
readonly provider: CodeProvider | null;
|
|
38
38
|
readonly cwd: string;
|
|
39
39
|
readonly lspRuntime: WorkspaceLspRuntimeState;
|
|
40
|
+
/** Typed reason to surface when target semantic readiness timed out. */
|
|
41
|
+
readonly semanticReadinessReason?: string;
|
|
40
42
|
readonly requestControl?: CodeRequestControl;
|
|
41
43
|
}
|
|
42
44
|
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
findInstructionFilesForDirectory,
|
|
10
10
|
} from "../analysis/instruction-files.ts";
|
|
11
11
|
import { createStructuralCodeProvider, withSemanticRequestControl } from "../analysis/provider.ts";
|
|
12
|
+
import { SEMANTIC_READINESS_TIMEOUT_REASON } from "../analysis/readiness.ts";
|
|
12
13
|
import { normalizePath } from "../analysis/search/paths.ts";
|
|
13
14
|
import { loadCodeIntelligenceConfig } from "../config.ts";
|
|
14
15
|
import type { CapabilityAdapter } from "./capability-adapter.ts";
|
|
@@ -33,6 +34,8 @@ export interface OrientationWorkflowDeps extends TargetWorkflowDeps {
|
|
|
33
34
|
readonly markInstructionDirsSurfaced: (directories: string[]) => void;
|
|
34
35
|
/** Whether the project is trusted — controls instruction-file discovery. */
|
|
35
36
|
readonly projectTrusted: boolean;
|
|
37
|
+
/** Global config home for hermetic config reads; undefined uses os.homedir(). */
|
|
38
|
+
readonly homeDir?: string;
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
/** Resolve the Orientation focus and collect immutable facts for presentation adapters. */
|
|
@@ -146,11 +149,13 @@ async function orientTarget(options: {
|
|
|
146
149
|
const provider = semanticReady
|
|
147
150
|
? withSemanticRequestControl(deps.capability.getProvider(deps.cwd), control)
|
|
148
151
|
: createStructuralCodeProvider(deps.capability.getStructuralProvider(deps.cwd));
|
|
152
|
+
const semanticReadinessReason =
|
|
153
|
+
readiness.kind === "timeout" ? SEMANTIC_READINESS_TIMEOUT_REASON : undefined;
|
|
149
154
|
const lspRuntime = semanticReady
|
|
150
155
|
? deps.capability.getLspRuntimeState(deps.cwd)
|
|
151
156
|
: {
|
|
152
157
|
kind: "unavailable" as const,
|
|
153
|
-
reason: readiness.kind === "timeout" ?
|
|
158
|
+
reason: readiness.kind === "timeout" ? SEMANTIC_READINESS_TIMEOUT_REASON : readiness.reason,
|
|
154
159
|
};
|
|
155
160
|
const result = await executeOrientation(
|
|
156
161
|
{ target: entry, maxResults },
|
|
@@ -158,6 +163,7 @@ async function orientTarget(options: {
|
|
|
158
163
|
model,
|
|
159
164
|
provider,
|
|
160
165
|
lspRuntime,
|
|
166
|
+
semanticReadinessReason,
|
|
161
167
|
cwd: deps.cwd,
|
|
162
168
|
requestControl: control,
|
|
163
169
|
},
|
|
@@ -201,7 +207,7 @@ function addInstructionFiles(
|
|
|
201
207
|
deps: OrientationWorkflowDeps,
|
|
202
208
|
): Awaited<ReturnType<typeof executeOrientation>> {
|
|
203
209
|
if (!deps.projectTrusted || !isDirectory(focusPath)) return result;
|
|
204
|
-
const config = loadCodeIntelligenceConfig(deps.cwd);
|
|
210
|
+
const config = loadCodeIntelligenceConfig(deps.cwd, deps.homeDir);
|
|
205
211
|
const matches = findInstructionFilesForDirectory({
|
|
206
212
|
directory: focusPath,
|
|
207
213
|
cwd: deps.cwd,
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
SourceRange,
|
|
8
8
|
} from "@mrclrchtr/supi-code-runtime/api";
|
|
9
9
|
import { toLspPosition } from "@mrclrchtr/supi-lsp/api";
|
|
10
|
+
import { SEMANTIC_READINESS_TIMEOUT_REASON } from "../analysis/readiness.ts";
|
|
10
11
|
import { applyWorkspaceEdit } from "../analysis/refactor/apply.ts";
|
|
11
12
|
import {
|
|
12
13
|
establishMutationAuthority,
|
|
@@ -93,7 +94,7 @@ export async function runRefactorPlanWorkflow(
|
|
|
93
94
|
control,
|
|
94
95
|
);
|
|
95
96
|
if (readiness.kind === "timeout") {
|
|
96
|
-
return { kind: "unavailable", reason:
|
|
97
|
+
return { kind: "unavailable", reason: SEMANTIC_READINESS_TIMEOUT_REASON };
|
|
97
98
|
}
|
|
98
99
|
if (readiness.kind === "unavailable") return readiness;
|
|
99
100
|
throwIfAborted(control);
|
package/src/session/session.ts
CHANGED
|
@@ -138,6 +138,8 @@ export class WorkspaceCodeIntelligenceSession {
|
|
|
138
138
|
|
|
139
139
|
/** Whether the hidden architecture overview has been injected. */
|
|
140
140
|
#hasInjectedOverview = false;
|
|
141
|
+
/** Pinned overview setting; null until resolved once per session. */
|
|
142
|
+
#overviewEnabled: boolean | null = null;
|
|
141
143
|
|
|
142
144
|
/** Most recent explicit diagnostic refresh attempt, including its established outcome. */
|
|
143
145
|
#lastHealthRefreshAttempt: HealthRefreshAttempt | null = null;
|
|
@@ -166,6 +168,9 @@ export class WorkspaceCodeIntelligenceSession {
|
|
|
166
168
|
/** Whether the project owning this session is trusted for config loading. */
|
|
167
169
|
#projectTrusted = false;
|
|
168
170
|
|
|
171
|
+
/** Global config home for hermetic config reads; undefined uses os.homedir(). */
|
|
172
|
+
#homeDir: string | undefined;
|
|
173
|
+
|
|
169
174
|
constructor(cwd: string, capability?: CapabilityAdapter) {
|
|
170
175
|
this.cwd = cwd;
|
|
171
176
|
this.#capability = capability ?? new WorkspaceCapabilityAdapter();
|
|
@@ -176,6 +181,11 @@ export class WorkspaceCodeIntelligenceSession {
|
|
|
176
181
|
this.#projectTrusted = trusted;
|
|
177
182
|
}
|
|
178
183
|
|
|
184
|
+
/** Record the global-config home used for session config reads. */
|
|
185
|
+
setHomeDir(homeDir?: string): void {
|
|
186
|
+
this.#homeDir = homeDir;
|
|
187
|
+
}
|
|
188
|
+
|
|
179
189
|
/** Attach lifecycle-owned LSP state without exposing it to Tool adapters. */
|
|
180
190
|
attachLspController(controller: LspRuntimeController | null): void {
|
|
181
191
|
this.#lspController = controller;
|
|
@@ -194,9 +204,22 @@ export class WorkspaceCodeIntelligenceSession {
|
|
|
194
204
|
this.#hasInjectedOverview = true;
|
|
195
205
|
}
|
|
196
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Pin the overview setting resolved once per session. The first resolution
|
|
209
|
+
* wins; later config changes never toggle the setting mid-session.
|
|
210
|
+
*/
|
|
211
|
+
setOverviewEnabledOnce(enabled: boolean): void {
|
|
212
|
+
this.#overviewEnabled ??= enabled;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Whether the overview setting has been pinned for this session. */
|
|
216
|
+
hasPinnedOverview(): boolean {
|
|
217
|
+
return this.#overviewEnabled !== null;
|
|
218
|
+
}
|
|
219
|
+
|
|
197
220
|
/** Atomically claim first-turn overview injection for this workspace session. */
|
|
198
221
|
claimOverviewInjection(): boolean {
|
|
199
|
-
if (this.#hasInjectedOverview) return false;
|
|
222
|
+
if (this.#overviewEnabled === false || this.#hasInjectedOverview) return false;
|
|
200
223
|
this.#hasInjectedOverview = true;
|
|
201
224
|
return true;
|
|
202
225
|
}
|
|
@@ -284,6 +307,7 @@ export class WorkspaceCodeIntelligenceSession {
|
|
|
284
307
|
surfacedInstructionDirs: this.#surfacedInstructionDirs,
|
|
285
308
|
markInstructionDirsSurfaced: (directories) => this.markInstructionDirsSurfaced(directories),
|
|
286
309
|
projectTrusted: this.#projectTrusted,
|
|
310
|
+
homeDir: this.#homeDir,
|
|
287
311
|
},
|
|
288
312
|
control,
|
|
289
313
|
);
|
|
@@ -13,16 +13,38 @@ import {
|
|
|
13
13
|
isCodeRequestInterruption,
|
|
14
14
|
throwIfCodeRequestInterrupted,
|
|
15
15
|
} from "@mrclrchtr/supi-code-runtime/api";
|
|
16
|
+
import { isWithinOrEqual } from "@mrclrchtr/supi-core/api";
|
|
17
|
+
import { uriToFile } from "@mrclrchtr/supi-core/path";
|
|
16
18
|
import type { DiagnosticEvidenceSummary } from "@mrclrchtr/supi-lsp/api";
|
|
17
19
|
import {
|
|
18
|
-
|
|
20
|
+
FileChangeType,
|
|
21
|
+
type FileEvent,
|
|
22
|
+
invalidateTsconfigCacheForConfig,
|
|
23
|
+
invalidateTsconfigCacheForConfigDir,
|
|
19
24
|
isLikelyStaleDiagnostic,
|
|
25
|
+
isProjectConfigFileName,
|
|
20
26
|
raceRequestControl,
|
|
21
27
|
syncWorkspaceSentinelSnapshot,
|
|
22
28
|
type WorkspaceLspRuntime,
|
|
23
29
|
} from "@mrclrchtr/supi-lsp/api";
|
|
24
30
|
import { mergeDiagnosticEvidence } from "../../diagnostics/evidence.ts";
|
|
25
31
|
|
|
32
|
+
/** Options shared by the workspace and file-scoped maintenance passes. */
|
|
33
|
+
export interface LspMaintenanceOptions {
|
|
34
|
+
control?: CodeRequestControl;
|
|
35
|
+
/**
|
|
36
|
+
* Workspace-relative scope prefix for source-file discovery. Discovery only
|
|
37
|
+
* tracks created files inside this prefix; null disables the scope bound.
|
|
38
|
+
*/
|
|
39
|
+
scope?: string | null;
|
|
40
|
+
/**
|
|
41
|
+
* Track files created since the last refresh so the following refresh pull
|
|
42
|
+
* includes them. Only the workspace-runtime path sets this; the snapshot is
|
|
43
|
+
* still widened on file-scoped passes so later diffs stay correct.
|
|
44
|
+
*/
|
|
45
|
+
trackSources?: boolean;
|
|
46
|
+
}
|
|
47
|
+
|
|
26
48
|
/**
|
|
27
49
|
* Run sentinel-sync, diagnostic refresh, and stale-module resync as a single
|
|
28
50
|
* maintenance pass. Call before explicit diagnostic queries (code_health with
|
|
@@ -32,28 +54,28 @@ export async function refreshLspMaintenance(
|
|
|
32
54
|
runtime: WorkspaceLspRuntime,
|
|
33
55
|
cwd: string,
|
|
34
56
|
sentinelSnapshot: Map<string, number>,
|
|
35
|
-
|
|
57
|
+
options: LspMaintenanceOptions = {},
|
|
36
58
|
): Promise<WorkspaceLspMaintenanceResult> {
|
|
37
|
-
const { snapshot } = synchronizeSentinels(runtime, cwd, sentinelSnapshot);
|
|
59
|
+
const { snapshot } = await synchronizeSentinels(runtime, cwd, sentinelSnapshot, options);
|
|
38
60
|
let diagnosticEvidence = emptyEvidence();
|
|
39
61
|
let failureReason: string | undefined;
|
|
40
62
|
|
|
41
63
|
// Refresh before stale-module inspection. The refresh owns deleted-file
|
|
42
64
|
// classification; later snapshots must not erase its removed evidence.
|
|
43
65
|
try {
|
|
44
|
-
diagnosticEvidence = await runtime.refreshOpenDiagnostics(undefined, control);
|
|
66
|
+
diagnosticEvidence = await runtime.refreshOpenDiagnostics(undefined, options.control);
|
|
45
67
|
} catch (error) {
|
|
46
|
-
if (isCodeRequestInterruption(error, control)) throw error;
|
|
68
|
+
if (isCodeRequestInterruption(error, options.control)) throw error;
|
|
47
69
|
failureReason = errorMessage(error);
|
|
48
70
|
diagnosticEvidence = readRuntimeEvidence(runtime);
|
|
49
71
|
}
|
|
50
72
|
|
|
51
73
|
try {
|
|
52
|
-
const staleResult = await resyncStaleModuleFiles(runtime, cwd, control);
|
|
74
|
+
const staleResult = await resyncStaleModuleFiles(runtime, cwd, options.control);
|
|
53
75
|
diagnosticEvidence = mergeDiagnosticEvidence(diagnosticEvidence, staleResult.evidence, cwd);
|
|
54
76
|
if (staleResult.completed) failureReason = undefined;
|
|
55
77
|
} catch (error) {
|
|
56
|
-
if (isCodeRequestInterruption(error, control)) throw error;
|
|
78
|
+
if (isCodeRequestInterruption(error, options.control)) throw error;
|
|
57
79
|
// Keep evidence from the first refresh when stale inspection fails.
|
|
58
80
|
}
|
|
59
81
|
|
|
@@ -93,15 +115,13 @@ export async function refreshFileLspMaintenance(options: {
|
|
|
93
115
|
const { runtime, cwd, sentinelSnapshot, filePath, control } = options;
|
|
94
116
|
// A cancelled caller stops before any maintenance work starts.
|
|
95
117
|
throwIfCodeRequestInterrupted(control);
|
|
96
|
-
const { snapshot } = synchronizeSentinels(runtime, cwd, sentinelSnapshot);
|
|
118
|
+
const { snapshot } = await synchronizeSentinels(runtime, cwd, sentinelSnapshot);
|
|
97
119
|
const target = nodePath.resolve(filePath);
|
|
98
|
-
const stale = runtime
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
(
|
|
102
|
-
|
|
103
|
-
entry.diagnostics.some((diagnostic) => isLikelyStaleDiagnostic(diagnostic)),
|
|
104
|
-
);
|
|
120
|
+
const stale = confirmedOutstandingDiagnostics(runtime, cwd).some(
|
|
121
|
+
(entry) =>
|
|
122
|
+
nodePath.resolve(cwd, entry.file) === target &&
|
|
123
|
+
entry.diagnostics.some((diagnostic) => isLikelyStaleDiagnostic(diagnostic)),
|
|
124
|
+
);
|
|
105
125
|
|
|
106
126
|
runtime.pruneMissingFiles();
|
|
107
127
|
if (stale) {
|
|
@@ -116,29 +136,91 @@ export async function refreshFileLspMaintenance(options: {
|
|
|
116
136
|
return { snapshot, matchedStaleFileCount: stale ? 1 : 0 };
|
|
117
137
|
}
|
|
118
138
|
|
|
119
|
-
|
|
139
|
+
/**
|
|
140
|
+
* Sync the widened workspace snapshot, forward sentinel changes, and track
|
|
141
|
+
* source files newly created since the last pass.
|
|
142
|
+
*
|
|
143
|
+
* The snapshot is widened to every regular file on every pass so later diffs
|
|
144
|
+
* see genuine creations. Only sentinel-file events are forwarded as workspace
|
|
145
|
+
* changes (config semantics unchanged); created source files are tracked only
|
|
146
|
+
* on the workspace-runtime path and only once the snapshot was primed by an
|
|
147
|
+
* earlier pass — the first pass establishes the baseline and cannot tell a
|
|
148
|
+
* just-created file from a long-existing one.
|
|
149
|
+
*/
|
|
150
|
+
async function synchronizeSentinels(
|
|
120
151
|
runtime: WorkspaceLspRuntime,
|
|
121
152
|
cwd: string,
|
|
122
153
|
sentinelSnapshot: Map<string, number>,
|
|
154
|
+
options: LspMaintenanceOptions = {},
|
|
123
155
|
) {
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
156
|
+
const primed = sentinelSnapshot.size > 0;
|
|
157
|
+
const state = syncWorkspaceSentinelSnapshot(cwd, sentinelSnapshot, {
|
|
158
|
+
includeSourceFiles: true,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
invalidateChangedProjectConfigs(state.changes);
|
|
162
|
+
if (state.changes.length > 0) runtime.noteWorkspaceChanges(state.changes);
|
|
163
|
+
|
|
164
|
+
if (options.trackSources && primed) {
|
|
165
|
+
await trackCreatedSourceFiles(runtime, state.sourceChanges, options.scope);
|
|
128
166
|
}
|
|
167
|
+
|
|
129
168
|
return state;
|
|
130
169
|
}
|
|
131
170
|
|
|
132
|
-
/**
|
|
171
|
+
/** Invalidate cached tsconfig scope parses only for config files that changed. */
|
|
172
|
+
function invalidateChangedProjectConfigs(changes: readonly FileEvent[]): void {
|
|
173
|
+
for (const change of changes) {
|
|
174
|
+
const filePath = uriToFile(change.uri);
|
|
175
|
+
if (!isProjectConfigFileName(nodePath.basename(filePath))) continue;
|
|
176
|
+
// Change-targeted invalidation: only config files affect tsconfig scope
|
|
177
|
+
// decisions. A created config can also turn previously empty lookups into
|
|
178
|
+
// resolved ones below the new config's directory.
|
|
179
|
+
invalidateTsconfigCacheForConfig(filePath);
|
|
180
|
+
if (change.type === FileChangeType.Created) {
|
|
181
|
+
invalidateTsconfigCacheForConfigDir(nodePath.dirname(filePath));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** Track source files newly created since the last pass, within the scope bound. */
|
|
187
|
+
async function trackCreatedSourceFiles(
|
|
188
|
+
runtime: WorkspaceLspRuntime,
|
|
189
|
+
sourceChanges: readonly FileEvent[],
|
|
190
|
+
scope: string | null | undefined,
|
|
191
|
+
): Promise<void> {
|
|
192
|
+
for (const change of sourceChanges) {
|
|
193
|
+
if (change.type !== FileChangeType.Created) continue;
|
|
194
|
+
const filePath = uriToFile(change.uri);
|
|
195
|
+
if (scope && !isWithinOrEqual(scope, filePath)) continue;
|
|
196
|
+
// Best-effort: a file no client can serve stays untracked and is
|
|
197
|
+
// simply absent from evidence until a later explicit request.
|
|
198
|
+
await runtime.trackFile(filePath);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** Return only diagnostics whose document evidence is confirmed. */
|
|
203
|
+
function confirmedOutstandingDiagnostics(runtime: WorkspaceLspRuntime, cwd: string) {
|
|
204
|
+
const outstanding = runtime.getOutstandingDiagnostics(1);
|
|
205
|
+
const confirmedFiles = new Set(
|
|
206
|
+
outstanding.evidence.documents
|
|
207
|
+
.filter((document) => document.status === "confirmed")
|
|
208
|
+
.map((document) => nodePath.resolve(cwd, document.file)),
|
|
209
|
+
);
|
|
210
|
+
return outstanding.entries.filter((entry) =>
|
|
211
|
+
confirmedFiles.has(nodePath.resolve(cwd, entry.file)),
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Re-open files with confirmed stale module-resolution errors. */
|
|
133
216
|
async function resyncStaleModuleFiles(
|
|
134
217
|
runtime: WorkspaceLspRuntime,
|
|
135
218
|
cwd: string,
|
|
136
219
|
control?: CodeRequestControl,
|
|
137
220
|
): Promise<{ evidence: DiagnosticEvidenceSummary; completed: boolean }> {
|
|
138
|
-
const outstanding = runtime.getOutstandingDiagnostics(1);
|
|
139
221
|
const staleFiles: string[] = [];
|
|
140
222
|
|
|
141
|
-
for (const entry of
|
|
223
|
+
for (const entry of confirmedOutstandingDiagnostics(runtime, cwd)) {
|
|
142
224
|
if (entry.diagnostics.some((d) => isLikelyStaleDiagnostic(d))) {
|
|
143
225
|
staleFiles.push(entry.file);
|
|
144
226
|
}
|
|
@@ -11,7 +11,11 @@ import type {
|
|
|
11
11
|
ToolResultEvent,
|
|
12
12
|
} from "@earendil-works/pi-coding-agent";
|
|
13
13
|
import { fileToUri } from "@mrclrchtr/supi-core/path";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
invalidateTsconfigCacheForConfig,
|
|
16
|
+
invalidateTsconfigCacheForConfigDir,
|
|
17
|
+
isProjectConfigFileName,
|
|
18
|
+
} from "@mrclrchtr/supi-lsp/api";
|
|
15
19
|
import type { LspAdapterState } from "./state.ts";
|
|
16
20
|
|
|
17
21
|
/** Tool names whose successful results should trigger workspace change notifications. */
|
|
@@ -37,10 +41,12 @@ export function registerWorkspaceRecoveryHandler(pi: ExtensionAPI, state: LspAda
|
|
|
37
41
|
const normalized = filePath.startsWith("@") ? filePath.slice(1) : filePath;
|
|
38
42
|
const resolved = nodePath.resolve(cwd, normalized);
|
|
39
43
|
|
|
40
|
-
// Invalidate tsconfig cache when config
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
// Invalidate the tsconfig scope cache only when a project config itself
|
|
45
|
+
// changed; other .json/.jsonc writes (package.json and friends) do not
|
|
46
|
+
// affect scope decisions and keep their cached parses.
|
|
47
|
+
if (isProjectConfigFileName(nodePath.basename(resolved))) {
|
|
48
|
+
invalidateTsconfigCacheForConfig(resolved);
|
|
49
|
+
invalidateTsconfigCacheForConfigDir(nodePath.dirname(resolved));
|
|
44
50
|
}
|
|
45
51
|
|
|
46
52
|
runtime.noteWorkspaceChanges([{ uri: fileToUri(resolved), type: 2 }]);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Thin Pi adapter for the session-owned code_find workflow. */
|
|
2
|
+
|
|
3
|
+
import type { FindMode, FindWorkflowInput } from "../../session/find-types.ts";
|
|
4
|
+
import type { CodeIntelResult, CodeIntelToolExecCtx } from "../../types/index.ts";
|
|
5
|
+
import { toWorkflowControl } from "../infra/workflow-control.ts";
|
|
6
|
+
import type { CodeFindAstKind } from "./ast-kinds.ts";
|
|
7
|
+
import { finishFindResult } from "./result.ts";
|
|
8
|
+
|
|
9
|
+
export interface CodeFindToolParams {
|
|
10
|
+
query: string;
|
|
11
|
+
scope?: string[];
|
|
12
|
+
mode: FindMode;
|
|
13
|
+
kind?: CodeFindAstKind;
|
|
14
|
+
maxResults?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function executeFindTool(
|
|
18
|
+
params: CodeFindToolParams,
|
|
19
|
+
ctx: CodeIntelToolExecCtx,
|
|
20
|
+
): Promise<CodeIntelResult> {
|
|
21
|
+
const outcome = await ctx.session.find(params as FindWorkflowInput, toWorkflowControl(ctx));
|
|
22
|
+
return finishFindResult(outcome, params.scope);
|
|
23
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const toolDescription =
|
|
2
|
+
'Search source shape with mode:"ast" or LSP workspace symbols with mode:"semantic". Modes never silently fall back. Unscoped AST scans cover visible supported files, skipping hidden and generated/dependency directories.';
|
|
3
|
+
|
|
4
|
+
export const promptSnippet = "explicit structural or semantic code search";
|
|
5
|
+
|
|
6
|
+
export const promptGuidelines = [
|
|
7
|
+
"Use code_find for structural or semantic search evidence; use PI grep for literal/regex source search and code_graph references for symbol-identity relationships.",
|
|
8
|
+
];
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
type EvidenceListMetadata,
|
|
5
5
|
renderEvidenceListMetadataDisclosure,
|
|
6
6
|
} from "../../analysis/evidence.ts";
|
|
7
|
-
import type { FindResultAssembly } from "../result/find.ts";
|
|
8
7
|
import { renderStructuredEmptyState, renderStructuredMatches } from "./markdown.ts";
|
|
8
|
+
import type { FindResultAssembly } from "./result.ts";
|
|
9
9
|
|
|
10
10
|
export function renderFindResult(assembly: FindResultAssembly): string {
|
|
11
11
|
const { outcome } = assembly;
|
|
@@ -10,9 +10,9 @@ import {
|
|
|
10
10
|
assembleToolResult,
|
|
11
11
|
type ResultProvenance,
|
|
12
12
|
type ToolResultAssembly,
|
|
13
|
-
} from "
|
|
14
|
-
import { createToolDisplaySection } from "
|
|
15
|
-
import type { SearchDetails, ToolDisplaySection } from "
|
|
13
|
+
} from "../result/assembly.ts";
|
|
14
|
+
import { createToolDisplaySection } from "../result/display.ts";
|
|
15
|
+
import type { SearchDetails, ToolDisplaySection } from "../result/types.ts";
|
|
16
16
|
|
|
17
17
|
/** Presentation-neutral assembled find result. */
|
|
18
18
|
export interface FindResultAssembly {
|
|
@@ -81,16 +81,9 @@ function findNextQueries(outcome: Extract<FindWorkflowOutcome, { kind: "complete
|
|
|
81
81
|
if (outcome.data.kind === "semantic" && outcome.data.symbols.length === 0) {
|
|
82
82
|
return [
|
|
83
83
|
"If you know the file, use code_resolve with a file selector to enumerate document declarations",
|
|
84
|
-
"Change mode only when you need a different code-aware evidence substrate",
|
|
85
84
|
];
|
|
86
85
|
}
|
|
87
|
-
|
|
88
|
-
return [
|
|
89
|
-
"Use code_graph references on a resolved target for symbol-identity relationships",
|
|
90
|
-
"Use PI grep for literal or regex source matches when it is active",
|
|
91
|
-
];
|
|
92
|
-
}
|
|
93
|
-
return ["Change mode only when you need a different code-aware evidence substrate"];
|
|
86
|
+
return [];
|
|
94
87
|
}
|
|
95
88
|
|
|
96
89
|
function createFindEvidence(outcome: Extract<FindWorkflowOutcome, { kind: "completed" }>): {
|
|
@@ -157,3 +150,35 @@ function findProvenance(
|
|
|
157
150
|
? [{ source: "semantic", capability: "workspace-symbol" }]
|
|
158
151
|
: [{ source: "structural", capability: "tree-sitter" }];
|
|
159
152
|
}
|
|
153
|
+
|
|
154
|
+
import type { CodeIntelResult, CodeIntelToolExecCtx } from "../../types/index.ts";
|
|
155
|
+
import { searchErrorResult } from "../result/errors.ts";
|
|
156
|
+
import { renderFindResult } from "./render.ts";
|
|
157
|
+
|
|
158
|
+
type FindOutcome = Awaited<ReturnType<CodeIntelToolExecCtx["session"]["find"]>>;
|
|
159
|
+
|
|
160
|
+
/** Assemble the final model-visible code_find result for one workflow outcome. */
|
|
161
|
+
export function finishFindResult(
|
|
162
|
+
outcome: FindOutcome,
|
|
163
|
+
scope: readonly string[] | undefined,
|
|
164
|
+
): CodeIntelResult {
|
|
165
|
+
if (outcome.kind === "unavailable") throw new Error(outcome.reason);
|
|
166
|
+
if (outcome.kind === "invalid-input") {
|
|
167
|
+
return searchErrorResult(`**Error:** ${outcome.message}`, {
|
|
168
|
+
scope: Array.isArray(scope) ? scope.join(", ") : null,
|
|
169
|
+
nextQueries: ["Fix the search input and retry"],
|
|
170
|
+
message: outcome.message,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const assembly = assembleFindWorkflowResult(outcome);
|
|
175
|
+
return {
|
|
176
|
+
content: renderFindResult(assembly),
|
|
177
|
+
details: {
|
|
178
|
+
type: "search",
|
|
179
|
+
data: assembly.details,
|
|
180
|
+
status: "completed",
|
|
181
|
+
displaySections: assembly.displaySections,
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
}
|