@mrclrchtr/supi-code-intelligence 2.0.5 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/README.md +71 -1
  2. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/README.md +29 -21
  3. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +2 -1
  4. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +88 -69
  5. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config.ts +22 -8
  6. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/prompt-surface.ts +357 -0
  7. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/prompt-surface.ts +4 -0
  8. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-command.ts +1 -1
  9. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +51 -29
  10. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +64 -18
  11. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings.ts +11 -5
  12. package/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/tool-framework.ts +10 -0
  13. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
  14. package/node_modules/@mrclrchtr/supi-core/README.md +29 -21
  15. package/node_modules/@mrclrchtr/supi-core/package.json +2 -1
  16. package/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +88 -69
  17. package/node_modules/@mrclrchtr/supi-core/src/config/config.ts +22 -8
  18. package/node_modules/@mrclrchtr/supi-core/src/config/prompt-surface.ts +357 -0
  19. package/node_modules/@mrclrchtr/supi-core/src/prompt-surface.ts +4 -0
  20. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-command.ts +1 -1
  21. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +51 -29
  22. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +64 -18
  23. package/node_modules/@mrclrchtr/supi-core/src/settings.ts +11 -5
  24. package/node_modules/@mrclrchtr/supi-core/src/tool-framework.ts +10 -0
  25. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/README.md +29 -21
  26. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +2 -1
  27. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +88 -69
  28. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config.ts +22 -8
  29. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/prompt-surface.ts +357 -0
  30. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/prompt-surface.ts +4 -0
  31. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-command.ts +1 -1
  32. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +51 -29
  33. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +64 -18
  34. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings.ts +11 -5
  35. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/tool-framework.ts +10 -0
  36. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
  37. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/README.md +29 -21
  38. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +2 -1
  39. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +88 -69
  40. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config.ts +22 -8
  41. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/prompt-surface.ts +357 -0
  42. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/prompt-surface.ts +4 -0
  43. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-command.ts +1 -1
  44. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +51 -29
  45. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +64 -18
  46. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings.ts +11 -5
  47. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/tool-framework.ts +10 -0
  48. package/node_modules/@mrclrchtr/supi-lsp/package.json +3 -3
  49. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/README.md +29 -21
  50. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/package.json +2 -1
  51. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +88 -69
  52. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/config.ts +22 -8
  53. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/config/prompt-surface.ts +357 -0
  54. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/prompt-surface.ts +4 -0
  55. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-command.ts +1 -1
  56. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +51 -29
  57. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +64 -18
  58. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/settings.ts +11 -5
  59. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/node_modules/@mrclrchtr/supi-core/src/tool-framework.ts +10 -0
  60. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +2 -2
  61. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/README.md +29 -21
  62. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +2 -1
  63. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config-settings.ts +88 -69
  64. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config.ts +22 -8
  65. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/prompt-surface.ts +357 -0
  66. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/prompt-surface.ts +4 -0
  67. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-command.ts +1 -1
  68. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +51 -29
  69. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-ui.ts +64 -18
  70. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings.ts +11 -5
  71. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/tool-framework.ts +10 -0
  72. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +3 -3
  73. package/package.json +5 -5
  74. package/src/analysis/evidence.ts +13 -0
  75. package/src/analysis/search/pattern.ts +24 -13
  76. package/src/analysis/search/ripgrep.ts +92 -7
  77. package/src/extension.ts +1 -1
  78. package/src/session/capability-adapter.ts +218 -0
  79. package/src/session/session.ts +39 -1
  80. package/src/session/target-workflow.ts +430 -0
  81. package/src/substrate/lsp/settings.ts +7 -3
  82. package/src/tool/find/execute.ts +23 -10
  83. package/src/tool/find/orchestrate.ts +67 -54
  84. package/src/tool/find/semantic-search.ts +30 -16
  85. package/src/tool/graph/collect-relation.ts +2 -1
  86. package/src/tool/graph/execute.ts +40 -12
  87. package/src/tool/graph/markdown-base.ts +5 -37
  88. package/src/tool/graph/orchestrate.ts +9 -35
  89. package/src/tool/graph/tui.ts +2 -0
  90. package/src/tool/guidance.ts +1 -1
  91. package/src/tool/health/markdown.ts +12 -70
  92. package/src/tool/health/orchestrate.ts +5 -13
  93. package/src/tool/impact/analysis.ts +0 -27
  94. package/src/tool/impact/change-set-impact.ts +3 -2
  95. package/src/tool/impact/execute.ts +27 -0
  96. package/src/tool/impact/file-level-impact.ts +3 -2
  97. package/src/tool/impact/result.ts +2 -21
  98. package/src/tool/impact/single-impact.ts +3 -2
  99. package/src/tool/infra/error-results.ts +18 -196
  100. package/src/tool/infra/pipeline.ts +24 -1
  101. package/src/tool/inspect/markdown.ts +4 -41
  102. package/src/tool/inspect/orchestrate.ts +27 -28
  103. package/src/tool/orientation/orchestrate.ts +5 -8
  104. package/src/tool/orientation/precise-target.ts +65 -69
  105. package/src/tool/refactor-apply/orchestrate.ts +2 -7
  106. package/src/tool/refactor-plan/orchestrate.ts +31 -39
  107. package/src/tool/resolve/markdown.ts +5 -6
  108. package/src/tool/resolve/orchestrate.ts +7 -103
  109. package/src/tool/result/errors.ts +199 -0
  110. package/src/tool/result/find.ts +29 -0
  111. package/src/tool/result/graph.ts +93 -0
  112. package/src/tool/result/health.ts +94 -0
  113. package/src/tool/result/impact.ts +50 -0
  114. package/src/tool/result/inspect.ts +60 -0
  115. package/src/tool/result/orientation.ts +30 -0
  116. package/src/tool/result/refactor.ts +35 -0
  117. package/src/tool/result/resolve.ts +114 -0
  118. package/src/tool/result/types.ts +188 -0
  119. package/src/tool/schemas.ts +22 -1
  120. package/src/types/details.ts +17 -185
  121. package/src/ui/tui/common.ts +45 -1
@@ -19,6 +19,7 @@ import type {
19
19
  OrientationTarget,
20
20
  OrientationUseCaseResult,
21
21
  } from "../../ui/markdown/types.ts";
22
+ import { assembleOrientationDetails } from "../result/orientation.ts";
22
23
  import { type RenderedOrientationSection, renderOrientationResult } from "./markdown.ts";
23
24
 
24
25
  const DEFAULT_TARGET_SECTIONS: OrientationSection[] = ["defs", "docs", "diagnostics"];
@@ -59,15 +60,13 @@ async function executeOrientationContext(
59
60
  lspService: deps.lspService,
60
61
  });
61
62
 
62
- const details: ContextDetails = {
63
+ const details: ContextDetails = assembleOrientationDetails({
63
64
  confidence: result.details.confidence,
64
- task: null,
65
65
  focusTarget: input.focus ?? null,
66
- requestedSections: [],
67
66
  renderedSections: ["orientation"],
68
67
  omittedCount: result.details.omittedCount,
69
68
  nextQueries: result.details.nextQueries,
70
- };
69
+ });
71
70
 
72
71
  return {
73
72
  content: result.content,
@@ -107,15 +106,13 @@ async function executeTargetOrientation(
107
106
  ? "structural"
108
107
  : "unavailable";
109
108
 
110
- const details: ContextDetails = {
109
+ const details: ContextDetails = assembleOrientationDetails({
111
110
  confidence,
112
- task: null,
113
111
  focusTarget,
114
112
  requestedSections,
115
113
  renderedSections: sections.map((section) => section.key),
116
- omittedCount: 0,
117
114
  nextQueries: buildNextQueries(input.target, deps.cwd),
118
- };
115
+ });
119
116
 
120
117
  return {
121
118
  content: renderOrientationResult({
@@ -4,14 +4,18 @@
4
4
  * Handles targetId expansion, coordinate-based symbol resolution, and
5
5
  * running the use-case layer for a resolved symbol target. Shared by
6
6
  * the main code_orientation executor.
7
+ *
8
+ * Uses the session target workflow (deep seam) instead of ad-hoc
9
+ * expandTargetId / executeResolveService calls.
7
10
  */
8
11
 
9
12
  import { relative } from "node:path";
10
- import { executeResolveService } from "../../analysis/target/service.ts";
13
+ import type { TargetWorkflowOutcome } from "../../session/session.ts";
11
14
  import type { TargetStoreEntry } from "../../session/target-store.ts";
12
15
  import type { CodeIntelResult, CodeIntelToolExecCtx, ContextDetails } from "../../types/index.ts";
13
16
  import { orientationCoordinateRules } from "../infra/cross-field.ts";
14
17
  import { unavailableContextDetails } from "../infra/error-results.ts";
18
+ import { assembleOrientationDetails } from "../result/orientation.ts";
15
19
  import { prepareOrientationDeps } from "./deps.ts";
16
20
  import type { CodeOrientationToolParams } from "./execute.ts";
17
21
  import { executeOrientation } from "./orchestrate.ts";
@@ -27,29 +31,57 @@ export interface PreciseTarget {
27
31
 
28
32
  /**
29
33
  * Outcome of precise-target resolution in code_orientation.
30
- *
31
- * {@link resolvePreciseTarget} returns this discriminated union instead
32
- * of {@link CodeIntelResult} | null so callers can't silently fall through
33
- * on a bug that produces null unintentionally.
34
34
  */
35
35
  export type PreciseTargetOutcome =
36
36
  | { kind: "resolved"; result: CodeIntelResult }
37
37
  | { kind: "fallthrough" };
38
38
 
39
+ /** Orientation target-workflow policy: file-level not for precise, name anchor not required. */
40
+ const ORIENTATION_TARGET_POLICY = {
41
+ fileLevelAllowed: false,
42
+ nameAnchorRequired: false,
43
+ waitForSemantic: true,
44
+ } as const;
45
+
39
46
  /**
40
47
  * Resolve a precise target ({@link CodeOrientationToolParams.targetId}
41
48
  * wins over focus/coordinates), then run symbol-centered orientation
42
49
  * sections. Falls through to orientation-mode when both targetId
43
50
  * expansion and coordinate resolution produce no target.
44
51
  */
52
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: layered resolution + disambiguation + section building stays together for clarity
45
53
  export async function resolvePreciseTarget(
46
54
  params: CodeOrientationToolParams,
47
55
  ctx: CodeIntelToolExecCtx,
48
56
  hasCoords: boolean,
49
57
  ): Promise<PreciseTargetOutcome> {
58
+ // ── Deep seam: resolve through session target workflow ──
50
59
  if (params.targetId !== undefined && params.targetId !== null) {
51
- const targetIdOutcome = await resolveTargetIdTarget(params, ctx, hasCoords);
52
- if (targetIdOutcome.kind === "resolved") return targetIdOutcome;
60
+ const outcome = await ctx.session.resolveTarget(
61
+ {
62
+ targetId: params.targetId,
63
+ file: hasCoords ? params.focus : undefined,
64
+ line: hasCoords ? params.line : undefined,
65
+ character: hasCoords ? params.character : undefined,
66
+ },
67
+ ORIENTATION_TARGET_POLICY,
68
+ );
69
+ if (outcome.kind === "resolved") {
70
+ const precise: PreciseTarget = {
71
+ entry: outcome.entry,
72
+ notes: outcome.notes,
73
+ };
74
+ return wrapOutcome(await runWithOrientationTarget(params, ctx, precise));
75
+ }
76
+ if (outcome.kind === "invalid-input" || outcome.kind === "unavailable") {
77
+ return wrapOutcome({
78
+ content: `**Error:** ${outcome.kind === "invalid-input" ? outcome.message : outcome.reason}`,
79
+ details: unavailableContextDetails([
80
+ "Verify the `targetId` is valid and from this session",
81
+ "Re-resolve with `code_resolve` to get a fresh targetId",
82
+ ]),
83
+ });
84
+ }
53
85
  }
54
86
 
55
87
  if (hasCoords) {
@@ -60,36 +92,6 @@ export async function resolvePreciseTarget(
60
92
  return { kind: "fallthrough" };
61
93
  }
62
94
 
63
- /** Resolve a targetId-supplied precise target, or fallthrough. */
64
- async function resolveTargetIdTarget(
65
- params: CodeOrientationToolParams,
66
- ctx: CodeIntelToolExecCtx,
67
- hasCoords: boolean,
68
- ): Promise<PreciseTargetOutcome> {
69
- const expansion = ctx.session.expandTargetId(params);
70
- if (expansion.kind === "error") {
71
- return wrapOutcome({
72
- content: expansion.message,
73
- details: unavailableContextDetails([
74
- "Verify the `targetId` is valid and from this session",
75
- "Re-resolve with `code_resolve` to get a fresh targetId",
76
- ]),
77
- });
78
- }
79
- if (expansion.kind !== "ok") return { kind: "fallthrough" };
80
-
81
- const notes: string[] = [];
82
- if (params.focus || hasCoords) {
83
- notes.push(
84
- "_Note: `targetId` takes precedence over the supplied focus/coordinates; focus and coordinates were ignored._",
85
- );
86
- }
87
-
88
- return wrapOutcome(
89
- await runWithOrientationTarget(params, ctx, { entry: expansion.entry, notes }),
90
- );
91
- }
92
-
93
95
  /** Resolve a focus+coordinate-supplied precise target, or fallthrough. */
94
96
  async function resolveCoordinateTarget(
95
97
  params: CodeOrientationToolParams,
@@ -105,39 +107,42 @@ async function resolveCoordinateTarget(
105
107
  });
106
108
  }
107
109
 
108
- const resolveResult = await executeResolveService(
110
+ const outcome = await ctx.session.resolveTarget(
109
111
  { file: params.focus, line: params.line, character: params.character },
110
- ctx.session,
112
+ ORIENTATION_TARGET_POLICY,
111
113
  );
112
114
 
113
- if (resolveResult.kind === "error") {
115
+ if (outcome.kind === "resolved") {
116
+ return wrapOutcome(
117
+ await runWithOrientationTarget(params, ctx, { entry: outcome.entry, notes: outcome.notes }),
118
+ );
119
+ }
120
+
121
+ if (outcome.kind === "disambiguation") {
122
+ return wrapOutcome(disambiguationResult(outcome));
123
+ }
124
+
125
+ if (outcome.kind === "invalid-input") {
114
126
  return wrapOutcome({
115
- content: resolveResult.message,
127
+ content: outcome.message,
116
128
  details: unavailableContextDetails([
117
129
  "Use `code_inspect` for point-level facts at this coordinate",
118
130
  "Or pass the identifier coordinate of a declaration",
119
131
  ]),
120
132
  });
121
133
  }
122
- if (resolveResult.kind === "disambiguation") {
123
- return wrapOutcome(disambiguationResult(resolveResult));
124
- }
125
134
 
126
- const entry = resolveResult.targets[0];
127
- if (!entry) {
128
- return wrapOutcome({
129
- content: "**Error:** Coordinate resolution returned no target.",
130
- details: unavailableContextDetails(["Use `code_inspect` for point-level facts"]),
131
- });
132
- }
133
-
134
- return wrapOutcome(await runWithOrientationTarget(params, ctx, { entry, notes: [] }));
135
+ return wrapOutcome({
136
+ content: "**Error:** Coordinate resolution returned no target.",
137
+ details: unavailableContextDetails(["Use `code_inspect` for point-level facts"]),
138
+ });
135
139
  }
136
140
 
137
141
  /** Wrap a CodeIntelResult into a resolved PreciseTargetOutcome. */
138
142
  function wrapOutcome(result: CodeIntelResult): PreciseTargetOutcome {
139
143
  return { kind: "resolved", result };
140
144
  }
145
+
141
146
  async function runWithOrientationTarget(
142
147
  params: CodeOrientationToolParams,
143
148
  ctx: CodeIntelToolExecCtx,
@@ -170,12 +175,7 @@ async function runWithOrientationTarget(
170
175
 
171
176
  // ── Helpers ───────────────────────────────────────────────────────────
172
177
 
173
- /**
174
- * Cross-field rule for code_orientation coordinate mode.
175
- *
176
- * TypeBox already enforces line/character types and min >= 1.
177
- * This covers only pairing, existence, and directory checks.
178
- */
178
+ /** Cross-field rule for code_orientation coordinate mode. */
179
179
  const validateCoordinateParams = orientationCoordinateRules<CodeOrientationToolParams>();
180
180
 
181
181
  function buildOrientationTarget(params: CodeOrientationToolParams) {
@@ -215,14 +215,14 @@ function prependNotes(
215
215
 
216
216
  /** Build the ambiguous-coordinate result: candidate targetIds, no sections. */
217
217
  function disambiguationResult(
218
- result: Extract<Awaited<ReturnType<typeof executeResolveService>>, { kind: "disambiguation" }>,
218
+ outcome: Extract<TargetWorkflowOutcome, { kind: "disambiguation" }>,
219
219
  ): CodeIntelResult {
220
220
  const lines: string[] = ["# Multiple matches found", ""];
221
221
  lines.push(
222
222
  "Coordinate resolution was ambiguous. Use `focus` + `line` + `character` for one of the candidates (pass the identifier coordinate):",
223
223
  );
224
224
  lines.push("");
225
- for (const c of result.candidates) {
225
+ for (const c of outcome.candidates) {
226
226
  const kind = c.kind ? ` (\`${c.kind}\`)` : "";
227
227
  const container = c.container ? ` in \`${c.container}\`` : "";
228
228
  lines.push(
@@ -231,14 +231,10 @@ function disambiguationResult(
231
231
  lines.push(` Target ID: \`${c.targetId}\``);
232
232
  }
233
233
 
234
- const details: ContextDetails = {
234
+ const details: ContextDetails = assembleOrientationDetails({
235
235
  confidence: "semantic",
236
- task: null,
237
- focusTarget: null,
238
- requestedSections: [],
239
- renderedSections: [],
240
- omittedCount: 0,
241
- candidates: result.candidates.map((c) => ({
236
+ omittedCount: outcome.omittedCount,
237
+ candidates: outcome.candidates.map((c) => ({
242
238
  targetId: c.targetId,
243
239
  name: c.name,
244
240
  kind: c.kind,
@@ -251,7 +247,7 @@ function disambiguationResult(
251
247
  nextQueries: [
252
248
  "Use `focus` + `line` + `character` for one of the candidates above (pass the identifier coordinate)",
253
249
  ],
254
- };
250
+ });
255
251
 
256
252
  return { content: lines.join("\n"), details: { type: "context", data: details } };
257
253
  }
@@ -15,6 +15,7 @@ import type { WorkspaceCodeIntelligenceSession } from "../../session/session.ts"
15
15
  import type { CodeIntelResult } from "../../types/index.ts";
16
16
  import { unavailableSearchDetails } from "../infra/error-results.ts";
17
17
  import { renderRefactorApplyResult } from "../refactor-plan/markdown.ts";
18
+ import { assembleRefactorApplyDetails } from "../result/refactor.ts";
18
19
  import { applyWorkspaceEdit } from "./apply.ts";
19
20
 
20
21
  export interface RefactorApplyInput {
@@ -77,13 +78,7 @@ export async function executeRefactorApply(
77
78
  content,
78
79
  details: {
79
80
  type: "search" as const,
80
- data: {
81
- confidence: "semantic" as const,
82
- scope: null,
83
- candidateCount: applyResult.kind === "applied" ? applyResult.totalEdits : 0,
84
- omittedCount: 0,
85
- nextQueries: ["`code_health` to check for new issues after the refactor"],
86
- },
81
+ data: assembleRefactorApplyDetails(applyResult),
87
82
  },
88
83
  };
89
84
  }
@@ -17,7 +17,6 @@ import {
17
17
  type SourceRange,
18
18
  } from "@mrclrchtr/supi-code-runtime/api";
19
19
  import { toLspPosition } from "@mrclrchtr/supi-lsp/api";
20
- import { createEvidenceList } from "../../analysis/evidence.ts";
21
20
  import { validateEdit } from "../../analysis/refactor/safety.ts";
22
21
  import { normalizePath } from "../../analysis/search/ripgrep.ts";
23
22
  import {
@@ -28,6 +27,7 @@ import {
28
27
  import type { WorkspaceCodeIntelligenceSession } from "../../session/session.ts";
29
28
  import type { CodeIntelResult } from "../../types/index.ts";
30
29
  import { unavailableSearchDetails } from "../infra/error-results.ts";
30
+ import { assembleRefactorPlanDetails } from "../result/refactor.ts";
31
31
  import { renderRefactorPlanResult } from "./markdown.ts";
32
32
 
33
33
  type CanonicalRefactorOperation = Exclude<RefactorOperation, "rename">;
@@ -73,7 +73,7 @@ export async function executeRefactorPlan(
73
73
  }
74
74
  const operation = normalizedOperation.operation;
75
75
 
76
- const target = resolveRefactorTarget(input, operation, deps.session);
76
+ const target = await resolveRefactorTarget(input, operation, deps.session);
77
77
  if ("content" in target) return target;
78
78
 
79
79
  const resolvedFile = normalizePath(target.file, deps.cwd);
@@ -125,25 +125,13 @@ export async function executeRefactorPlan(
125
125
  };
126
126
  deps.session.storePlan(plan);
127
127
 
128
- const editEvidence = createEvidenceList({
129
- key: "refactor.edits",
130
- items: refactorResult.edits.edits,
131
- maxResults: 5,
132
- }).metadata;
133
128
  const content = renderRefactorPlanResult(plan, deps.cwd);
134
129
 
135
130
  return {
136
131
  content,
137
132
  details: {
138
133
  type: "search" as const,
139
- data: {
140
- confidence: "semantic" as const,
141
- scope: null,
142
- candidateCount: refactorResult.edits.edits.length,
143
- omittedCount: editEvidence.omittedCount ?? 0,
144
- evidenceLists: [editEvidence],
145
- nextQueries: [`Use code_refactor_apply with planId: "${planId}" to apply this refactor`],
146
- },
134
+ data: assembleRefactorPlanDetails(refactorResult.edits, planId),
147
135
  },
148
136
  };
149
137
  }
@@ -174,39 +162,43 @@ function normalizeRequestedOperation(
174
162
  }
175
163
 
176
164
  // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: target expansion and operation-specific validation are kept together for clear user-facing errors.
177
- function resolveRefactorTarget(
165
+ async function resolveRefactorTarget(
178
166
  input: RefactorPlanInput,
179
167
  operation: CanonicalRefactorOperation,
180
168
  session: WorkspaceCodeIntelligenceSession,
181
- ): CodeIntelResult | { file: string; line: number; character: number } {
182
- const expansion = session.expandTargetId(input);
183
- if (expansion.kind === "error") {
184
- return {
185
- content: expansion.message,
186
- details: unavailableSearchDetails(null, [
187
- "Verify the `targetId` is valid and from this session",
188
- ]),
189
- };
190
- }
191
- if (expansion.kind === "ok") {
192
- input.file = expansion.file;
193
- input.line = expansion.line;
194
- input.character = expansion.character;
195
-
196
- // Per ADR 0003: rename_symbol is position-strict LSP rename requires
197
- // the identifier (name anchor), and a declaration anchor silently yields
198
- // empty or wrong edits. Refuse before planning.
199
- if (operation === "rename_symbol" && expansion.entry.anchorKind === "declaration") {
169
+ ): Promise<CodeIntelResult | { file: string; line: number; character: number }> {
170
+ // ── Deep seam: resolve target through the session target workflow ──
171
+ if (input.targetId) {
172
+ const policy = {
173
+ fileLevelAllowed: false,
174
+ nameAnchorRequired: operation === "rename_symbol",
175
+ waitForSemantic: false,
176
+ } as const;
177
+
178
+ const outcome = await session.resolveTarget({ targetId: input.targetId }, policy);
179
+ if (outcome.kind === "resolved") {
180
+ input.file = outcome.entry.file;
181
+ input.line = outcome.entry.displayLine;
182
+ input.character = outcome.entry.displayCharacter;
183
+ } else if (outcome.kind === "invalid-input") {
184
+ // Declaration-anchor refusal for rename_symbol comes back as invalid-input
200
185
  return {
201
- content:
202
- `**Cannot plan rename:** The resolved target fell back to a declaration anchor (the \`export\` keyword or similar), not an identifier (name anchor). LSP \`rename\` requires the identifier. ` +
203
- `Re-resolve via \`code_resolve\` after the language server has indexed the file, ` +
204
- `or pass \`file\` + \`line\` + \`character\` anchored directly on the identifier.`,
186
+ content: `**Cannot plan rename:** ${outcome.message}`,
205
187
  details: unavailableSearchDetails(null, [
206
188
  "Re-resolve via `code_resolve` when the LSP has indexed the file",
207
189
  "Or use `file` + `line` + `character` anchored on the identifier directly",
208
190
  ]),
209
191
  };
192
+ } else {
193
+ return {
194
+ content:
195
+ outcome.kind === "unavailable"
196
+ ? `**Error:** ${outcome.reason}`
197
+ : `**Error:** Target resolution failed. Verify the targetId is valid and from this session.`,
198
+ details: unavailableSearchDetails(null, [
199
+ "Verify the `targetId` is valid and from this session",
200
+ ]),
201
+ };
210
202
  }
211
203
  }
212
204
 
@@ -7,11 +7,9 @@
7
7
 
8
8
  import { relative } from "node:path";
9
9
  import { renderEvidenceListMetadataDisclosure } from "../../analysis/evidence.ts";
10
- import type {
11
- DisambiguationCandidate,
12
- ResolveServiceResult,
13
- } from "../../analysis/target/service.ts";
10
+ import type { DisambiguationCandidate } from "../../analysis/target/service.ts";
14
11
  import type { TargetStoreEntry } from "../../session/target-store.ts";
12
+ import type { ResolveResultAssembly } from "../result/resolve.ts";
15
13
 
16
14
  /**
17
15
  * Render a provenance note for an anchored resolution, but only when the
@@ -57,8 +55,9 @@ function renderSingleTarget(t: TargetStoreEntry, confidence: string, cwd: string
57
55
  return lines;
58
56
  }
59
57
 
60
- /** Render a full resolve service result into markdown. */
61
- export function renderResolveResult(result: ResolveServiceResult, cwd: string): string {
58
+ /** Render an assembled resolve result into markdown. */
59
+ export function renderResolveResult(assembly: ResolveResultAssembly): string {
60
+ const { result, cwd } = assembly;
62
61
  switch (result.kind) {
63
62
  case "resolved":
64
63
  return renderResolved(result.targets, result.omittedCount, result.confidence, cwd);
@@ -1,15 +1,11 @@
1
1
  /**
2
- * code_resolve orchestration — result assembly and details construction.
3
- *
4
- * Receives raw resolution outcomes from the resolution service and
5
- * assembles the markdown content and structured details.
2
+ * code_resolve orchestration — resolve facts, assemble tool evidence, render adapters.
6
3
  */
7
4
 
8
- import { relative } from "node:path";
9
5
  import { executeResolveService, type ResolveServiceParams } from "../../analysis/target/service.ts";
10
6
  import type { WorkspaceCodeIntelligenceSession } from "../../session/session.ts";
11
- import type { CodeIntelResult, ResolveDetails } from "../../types/index.ts";
12
- import { unavailableResolveDetails } from "../infra/error-results.ts";
7
+ import type { CodeIntelResult } from "../../types/index.ts";
8
+ import { assembleResolveResult, suggestedResolveRelations } from "../result/resolve.ts";
13
9
  import { renderResolveResult } from "./markdown.ts";
14
10
 
15
11
  export interface ResolveOrchestrateInput {
@@ -21,114 +17,22 @@ export interface ResolveOrchestrateInput {
21
17
  export async function orchestrateResolve(input: ResolveOrchestrateInput): Promise<CodeIntelResult> {
22
18
  const { params, session, cwd } = input;
23
19
  const result = await executeResolveService(params, session);
20
+ const assembly = assembleResolveResult(result, cwd);
24
21
 
25
- let content = renderResolveResult(result, cwd);
22
+ let content = renderResolveResult(assembly);
26
23
 
27
24
  // For single-target resolutions, append actionable "Chain next" guidance.
28
25
  if (result.kind === "resolved" && result.targets.length === 1) {
29
26
  const target = result.targets[0];
30
- const rels = suggestedRelations(target.kind);
27
+ const rels = suggestedResolveRelations(target.kind);
31
28
  if (rels) {
32
29
  const chainLine = `Chain next: \`code_graph(targetId: "${target.targetId}", relations: ${JSON.stringify(rels)})\``;
33
30
  content = `${content}\n${chainLine}\n`;
34
31
  }
35
32
  }
36
33
 
37
- // Build structured details
38
- if (result.kind === "resolved") {
39
- const details: ResolveDetails = {
40
- confidence: result.confidence,
41
- targetCount: result.targets.length + result.omittedCount,
42
- omittedCount: result.omittedCount,
43
- evidenceLists: [
44
- {
45
- key: "resolve.targets",
46
- totalCount: result.targets.length + result.omittedCount,
47
- shownCount: result.targets.length,
48
- omittedCount: result.omittedCount,
49
- partialReason: null,
50
- },
51
- ],
52
- targets: result.targets.map((t) => ({
53
- targetId: t.targetId,
54
- spanId: t.spanId,
55
- file: relative(cwd, t.file) || t.file,
56
- displayLine: t.displayLine,
57
- displayCharacter: t.displayCharacter,
58
- name: t.name,
59
- kind: t.kind,
60
- anchorKind: t.anchorKind,
61
- confidence: t.confidence,
62
- provenance: t.provenance,
63
- resolution: t.resolution,
64
- })),
65
- nextQueries: result.nextQueries,
66
- };
67
- return { content, details: { type: "resolve", data: details } };
68
- }
69
-
70
- if (result.kind === "disambiguation") {
71
- const details: ResolveDetails = {
72
- confidence: "semantic",
73
- targetCount: result.candidates.length + result.omittedCount,
74
- omittedCount: result.omittedCount,
75
- evidenceLists: [
76
- {
77
- key: "resolve.candidates",
78
- totalCount: result.candidates.length + result.omittedCount,
79
- shownCount: result.candidates.length,
80
- omittedCount: result.omittedCount,
81
- partialReason: null,
82
- },
83
- ],
84
- targets: [],
85
- candidates: result.candidates.map((cand) => ({
86
- targetId: cand.targetId,
87
- name: cand.name,
88
- kind: cand.kind,
89
- container: cand.container,
90
- file: cand.file,
91
- line: cand.line,
92
- character: cand.character,
93
- reason: cand.reason,
94
- rank: cand.rank,
95
- anchorKind: cand.anchorKind,
96
- })),
97
- nextQueries: result.nextQueries,
98
- };
99
- return { content, details: { type: "resolve", data: details } };
100
- }
101
-
102
- // Error — still return structured details
103
34
  return {
104
35
  content,
105
- details: unavailableResolveDetails([
106
- "Refine the `query` or `scope`",
107
- "Use anchored `file` + `line` + `character` for a precise target",
108
- ]),
36
+ details: { type: "resolve", data: assembly.details },
109
37
  };
110
38
  }
111
-
112
- /**
113
- * Suggested `code_graph` relations for a resolved symbol kind.
114
- */
115
- function suggestedRelations(kind: string | undefined | null): string[] | undefined {
116
- switch (kind?.toLowerCase()) {
117
- case "function":
118
- case "method":
119
- case "constructor":
120
- return ["references", "callees", "tests"];
121
- case "class":
122
- case "interface":
123
- case "type":
124
- case "enum":
125
- return ["references", "implements"];
126
- case "file":
127
- case "module":
128
- return ["imports", "exports"];
129
- case "test":
130
- return ["tests"];
131
- default:
132
- return undefined;
133
- }
134
- }