@mrclrchtr/supi-code-intelligence 4.10.0 → 5.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.
Files changed (203) hide show
  1. package/README.md +2 -1
  2. package/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
  3. package/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  4. package/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
  5. package/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
  6. package/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
  7. package/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
  8. package/node_modules/@mrclrchtr/supi-core/README.md +2 -0
  9. package/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  10. package/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
  11. package/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
  12. package/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -3
  13. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
  14. package/node_modules/@mrclrchtr/supi-lsp/README.md +80 -5
  15. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
  16. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  17. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
  18. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
  19. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
  20. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
  21. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/README.md +2 -0
  22. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  23. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
  24. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
  25. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -3
  26. package/node_modules/@mrclrchtr/supi-lsp/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
  27. package/node_modules/@mrclrchtr/supi-lsp/package.json +7 -6
  28. package/node_modules/@mrclrchtr/supi-lsp/src/api.ts +10 -0
  29. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-cache.ts +206 -0
  30. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-capabilities.ts +78 -0
  31. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-collection.ts +114 -0
  32. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-evidence.ts +372 -0
  33. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-host.ts +14 -0
  34. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-pull.ts +62 -0
  35. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-refresh.ts +491 -0
  36. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-request.ts +9 -0
  37. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-timing.ts +71 -11
  38. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostic-waiters.ts +206 -0
  39. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-diagnostics.ts +365 -297
  40. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-state.ts +52 -0
  41. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-document-sync.ts +185 -0
  42. package/node_modules/@mrclrchtr/supi-lsp/src/client/client-file-state.ts +25 -0
  43. package/node_modules/@mrclrchtr/supi-lsp/src/client/client.ts +467 -115
  44. package/node_modules/@mrclrchtr/supi-lsp/src/client/transport.ts +161 -33
  45. package/node_modules/@mrclrchtr/supi-lsp/src/config/capabilities.ts +10 -1
  46. package/node_modules/@mrclrchtr/supi-lsp/src/config/defaults.json +1 -1
  47. package/node_modules/@mrclrchtr/supi-lsp/src/debug-telemetry.ts +45 -0
  48. package/node_modules/@mrclrchtr/supi-lsp/src/diagnostics/evidence.ts +38 -0
  49. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-client-state.ts +79 -9
  50. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-diagnostics.ts +13 -4
  51. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-recovery.ts +300 -24
  52. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager-workspace-symbol.ts +5 -2
  53. package/node_modules/@mrclrchtr/supi-lsp/src/manager/manager.ts +464 -96
  54. package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-refactor-provider.ts +130 -0
  55. package/node_modules/@mrclrchtr/supi-lsp/src/provider/lsp-semantic-provider.ts +45 -329
  56. package/node_modules/@mrclrchtr/supi-lsp/src/provider/refactor-planning.ts +57 -120
  57. package/node_modules/@mrclrchtr/supi-lsp/src/provider/semantic-edit-normalizer.ts +320 -0
  58. package/node_modules/@mrclrchtr/supi-lsp/src/provider/semantic-symbol-mapper.ts +207 -0
  59. package/node_modules/@mrclrchtr/supi-lsp/src/session/readiness.ts +72 -2
  60. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-controller.ts +151 -26
  61. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostic-surface.ts +40 -0
  62. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-diagnostics.ts +50 -0
  63. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-registry.ts +136 -120
  64. package/node_modules/@mrclrchtr/supi-lsp/src/session/runtime-transition-debug.ts +49 -0
  65. package/node_modules/@mrclrchtr/supi-lsp/src/session/workspace-lsp-runtime.ts +102 -0
  66. package/node_modules/@mrclrchtr/supi-tree-sitter/README.md +17 -7
  67. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/README.md +2 -0
  68. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/package.json +1 -1
  69. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/api.ts +9 -0
  70. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/capability/types.ts +53 -13
  71. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/request-control.ts +47 -0
  72. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-code-runtime/src/types.ts +13 -1
  73. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/README.md +2 -0
  74. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/package.json +1 -1
  75. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config/config.ts +31 -0
  76. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/config.ts +2 -0
  77. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +19 -3
  78. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +3 -0
  79. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/LICENSE +21 -0
  80. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/README.md +258 -0
  81. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/dist/babel.cjs +257 -0
  82. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/dist/jiti.cjs +1 -0
  83. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-cli.mjs +34 -0
  84. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-hooks.mjs +124 -0
  85. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-native.mjs +121 -0
  86. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-register.d.mts +1 -0
  87. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-register.mjs +4 -0
  88. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti-static.mjs +23 -0
  89. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.cjs +30 -0
  90. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.d.cts +8 -0
  91. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.d.mts +8 -0
  92. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/jiti.mjs +29 -0
  93. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/lib/types.d.ts +420 -0
  94. package/node_modules/@mrclrchtr/supi-tree-sitter/node_modules/jiti/package.json +146 -0
  95. package/node_modules/@mrclrchtr/supi-tree-sitter/package.json +6 -3
  96. package/node_modules/@mrclrchtr/supi-tree-sitter/src/api.ts +0 -9
  97. package/node_modules/@mrclrchtr/supi-tree-sitter/src/index.ts +0 -8
  98. package/node_modules/@mrclrchtr/supi-tree-sitter/src/provider/tree-sitter-provider.ts +16 -12
  99. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime-controller.ts +65 -87
  100. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/session.ts +47 -95
  101. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-timing.ts +147 -0
  102. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client-lifecycle.ts +39 -0
  103. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-client.ts +561 -0
  104. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-message-size.ts +24 -0
  105. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/structural-worker-protocol.ts +452 -0
  106. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/call-sites.ts +4 -2
  107. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/callees.ts +12 -4
  108. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/exports.ts +4 -2
  109. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/imports.ts +4 -2
  110. package/node_modules/@mrclrchtr/supi-tree-sitter/src/tool/node-at.ts +5 -3
  111. package/node_modules/@mrclrchtr/supi-tree-sitter/src/types.ts +33 -12
  112. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/blocking-test-bootstrap.mjs +34 -0
  113. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/bootstrap.mjs +8 -0
  114. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/parsed-file-store-helpers.ts +23 -0
  115. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/parsed-file-store.ts +400 -0
  116. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/request-control.ts +48 -0
  117. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime-parser-helpers.ts +24 -0
  118. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime-query-helpers.ts +43 -0
  119. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/runtime.ts +421 -0
  120. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/service.ts +116 -0
  121. package/node_modules/@mrclrchtr/supi-tree-sitter/src/worker/worker-main.ts +201 -0
  122. package/package.json +5 -5
  123. package/src/analysis/health/diagnostics.ts +236 -24
  124. package/src/analysis/health/recovery.ts +6 -2
  125. package/src/analysis/provider.ts +58 -0
  126. package/src/analysis/readiness.ts +30 -9
  127. package/src/analysis/refactor/apply.ts +45 -1
  128. package/src/analysis/refactor/mutation-authority.ts +143 -0
  129. package/src/analysis/relations/callees.ts +9 -1
  130. package/src/analysis/relations/types.ts +5 -2
  131. package/src/analysis/search/ast-scan-timing.ts +9 -2
  132. package/src/analysis/search/ast-scan.ts +1 -1
  133. package/src/analysis/search/deadline.ts +2 -2
  134. package/src/analysis/search/pattern-analysis.ts +46 -32
  135. package/src/analysis/search/pattern.ts +12 -2
  136. package/src/analysis/target/anchored.ts +20 -11
  137. package/src/analysis/target/file.ts +18 -11
  138. package/src/analysis/target/identity.ts +19 -3
  139. package/src/analysis/target/symbol.ts +36 -15
  140. package/src/api.ts +4 -0
  141. package/src/diagnostics/evidence.ts +51 -0
  142. package/src/session/capability-adapter.ts +12 -3
  143. package/src/session/find-workflow.ts +17 -7
  144. package/src/session/graph/collect.ts +18 -2
  145. package/src/session/graph-workflow.ts +19 -12
  146. package/src/session/health-refresh.ts +148 -0
  147. package/src/session/health-types.ts +37 -15
  148. package/src/session/health-workflow.ts +37 -39
  149. package/src/session/inspect/collect.ts +20 -3
  150. package/src/session/inspect-workflow.ts +10 -5
  151. package/src/session/orientation/collect.ts +10 -1
  152. package/src/session/orientation/context-facts.ts +3 -1
  153. package/src/session/orientation/context-sections.ts +20 -7
  154. package/src/session/orientation/gather.ts +17 -11
  155. package/src/session/orientation-types.ts +2 -1
  156. package/src/session/orientation-workflow.ts +15 -8
  157. package/src/session/refactor-plans.ts +2 -0
  158. package/src/session/refactor-workflow.ts +59 -14
  159. package/src/session/session.ts +4 -1
  160. package/src/session/target-workflow.ts +54 -23
  161. package/src/session/workflow-control.ts +7 -3
  162. package/src/substrate/lsp/lifecycle.ts +26 -46
  163. package/src/substrate/lsp/maintenance.ts +199 -25
  164. package/src/substrate/lsp/state.ts +2 -2
  165. package/src/substrate/workspace-provider-host.ts +25 -3
  166. package/src/tool/find/execute.ts +7 -1
  167. package/src/tool/find/render.ts +20 -3
  168. package/src/tool/find/tui.ts +23 -21
  169. package/src/tool/graph/execute.ts +23 -3
  170. package/src/tool/graph/tui.ts +59 -46
  171. package/src/tool/health/execute.ts +7 -2
  172. package/src/tool/health/markdown.ts +56 -14
  173. package/src/tool/health/refresh-status.ts +105 -0
  174. package/src/tool/health/tui.ts +95 -98
  175. package/src/tool/infra/workflow-control.ts +8 -0
  176. package/src/tool/inspect/execute.ts +7 -1
  177. package/src/tool/inspect/tui.ts +26 -18
  178. package/src/tool/orientation/execute.ts +21 -3
  179. package/src/tool/orientation/tui.ts +51 -35
  180. package/src/tool/refactor-apply/execute.ts +3 -0
  181. package/src/tool/refactor-apply/tui.ts +43 -25
  182. package/src/tool/refactor-plan/execute.ts +4 -0
  183. package/src/tool/refactor-plan/tui.ts +33 -20
  184. package/src/tool/register.ts +127 -22
  185. package/src/tool/resolve/execute.ts +18 -1
  186. package/src/tool/resolve/tui.ts +42 -24
  187. package/src/tool/result/display.ts +107 -0
  188. package/src/tool/result/errors.ts +20 -17
  189. package/src/tool/result/find.ts +52 -8
  190. package/src/tool/result/graph.ts +44 -1
  191. package/src/tool/result/health.ts +53 -1
  192. package/src/tool/result/inspect.ts +113 -1
  193. package/src/tool/result/orientation.ts +66 -14
  194. package/src/tool/result/refactor.ts +36 -4
  195. package/src/tool/result/resolve.ts +44 -7
  196. package/src/tool/result/types.ts +20 -0
  197. package/src/types/execution.ts +18 -5
  198. package/src/types/index.ts +8 -1
  199. package/src/ui/status-command.ts +5 -3
  200. package/src/ui/status-overlay.ts +4 -0
  201. package/src/ui/tui/common.ts +108 -10
  202. package/src/ui/tui/display.ts +48 -0
  203. package/node_modules/@mrclrchtr/supi-tree-sitter/src/session/runtime.ts +0 -351
@@ -3,7 +3,8 @@ import { createEvidenceList, type EvidenceList } from "../../analysis/evidence.t
3
3
  import type { ApplyResult } from "../../analysis/refactor/apply.ts";
4
4
  import type { RefactorPlan } from "../../session/refactor-plans.ts";
5
5
  import { assembledNextQueries, assembleToolResult, type ToolResultAssembly } from "./assembly.ts";
6
- import type { SearchDetails } from "./types.ts";
6
+ import { createToolDisplaySection } from "./display.ts";
7
+ import type { SearchDetails, ToolDisplaySection } from "./types.ts";
7
8
 
8
9
  export interface RefactorPlanAssemblyData {
9
10
  readonly plan: Readonly<RefactorPlan>;
@@ -14,6 +15,7 @@ export interface RefactorPlanAssemblyData {
14
15
  export interface RefactorPlanResultAssembly {
15
16
  readonly assembled: ToolResultAssembly<RefactorPlanAssemblyData>;
16
17
  readonly details: SearchDetails;
18
+ readonly displaySections: readonly ToolDisplaySection[];
17
19
  }
18
20
 
19
21
  export interface RefactorApplyAssemblyData {
@@ -24,6 +26,13 @@ export interface RefactorApplyAssemblyData {
24
26
  export interface RefactorApplyResultAssembly {
25
27
  readonly assembled: ToolResultAssembly<RefactorApplyAssemblyData>;
26
28
  readonly details: SearchDetails;
29
+ readonly displaySections: readonly ToolDisplaySection[];
30
+ }
31
+
32
+ function formatEdit(edit: FileEdit): string {
33
+ const range = edit.range;
34
+ const replacement = edit.newText.replace(/\n/g, " ↵ ");
35
+ return `${edit.file} L${range.start.line + 1}:${range.start.character + 1} → L${range.end.line + 1}:${range.end.character + 1}: ${replacement}`;
27
36
  }
28
37
 
29
38
  /** Assemble a bounded refactor plan and all facts needed by its renderers. */
@@ -59,6 +68,17 @@ export function assembleRefactorPlanDetails(
59
68
 
60
69
  return {
61
70
  assembled,
71
+ displaySections: [
72
+ createToolDisplaySection({
73
+ key: "refactor.edits",
74
+ title: "Proposed edits",
75
+ items: edits.items,
76
+ totalCount: edits.metadata.totalCount,
77
+ omittedCount: edits.metadata.omittedCount,
78
+ partialReason: edits.metadata.partialReason,
79
+ format: formatEdit,
80
+ }),
81
+ ],
62
82
  details: {
63
83
  confidence: assembled.confidence,
64
84
  scope: null,
@@ -98,8 +118,22 @@ export function assembleRefactorApplyDetails(
98
118
  provenance,
99
119
  });
100
120
 
121
+ const changedFiles = [...new Set(plan.edits.edits.map((edit) => edit.file))];
122
+
101
123
  return {
102
124
  assembled,
125
+ displaySections:
126
+ applyResult.kind === "applied"
127
+ ? [
128
+ createToolDisplaySection({
129
+ key: "refactor.changedFiles",
130
+ title: "Changed files",
131
+ items: changedFiles,
132
+ totalCount: changedFiles.length,
133
+ format: (file) => file,
134
+ }),
135
+ ]
136
+ : [],
103
137
  details: {
104
138
  confidence: assembled.confidence,
105
139
  scope: null,
@@ -107,9 +141,7 @@ export function assembleRefactorApplyDetails(
107
141
  omittedCount: assembled.totals.omittedCount,
108
142
  evidenceLists: [...assembled.evidenceLists],
109
143
  nextQueries: assembledNextQueries(assembled),
110
- ...(applyResult.kind === "applied"
111
- ? { changedFiles: [...new Set(plan.edits.edits.map((edit) => edit.file))] }
112
- : {}),
144
+ ...(applyResult.kind === "applied" ? { changedFiles } : {}),
113
145
  },
114
146
  };
115
147
  }
@@ -10,7 +10,8 @@ import {
10
10
  type ResultProvenance,
11
11
  type ToolResultAssembly,
12
12
  } from "./assembly.ts";
13
- import type { ResolveDetails } from "./types.ts";
13
+ import { createToolDisplaySection } from "./display.ts";
14
+ import type { ResolveDetails, ToolDisplaySection } from "./types.ts";
14
15
 
15
16
  /** Presentation-neutral assembled code_resolve result. */
16
17
  export interface ResolveResultAssembly {
@@ -18,6 +19,7 @@ export interface ResolveResultAssembly {
18
19
  readonly cwd: string;
19
20
  readonly assembled: ToolResultAssembly<TargetWorkflowOutcome>;
20
21
  readonly details: ResolveDetails;
22
+ readonly displaySections: readonly ToolDisplaySection[];
21
23
  }
22
24
 
23
25
  interface ResolveProjection {
@@ -56,16 +58,19 @@ export function assembleResolveResult(
56
58
  provenance,
57
59
  });
58
60
 
61
+ const details = {
62
+ ...projection.details,
63
+ omittedCount: assembled.totals.omittedCount,
64
+ evidenceLists: [...assembled.evidenceLists],
65
+ nextQueries: assembledNextQueries(assembled),
66
+ };
67
+
59
68
  return Object.freeze({
60
69
  outcome,
61
70
  cwd,
62
71
  assembled,
63
- details: {
64
- ...projection.details,
65
- omittedCount: assembled.totals.omittedCount,
66
- evidenceLists: [...assembled.evidenceLists],
67
- nextQueries: assembledNextQueries(assembled),
68
- },
72
+ details,
73
+ displaySections: resolveDisplaySections(details),
69
74
  });
70
75
  }
71
76
 
@@ -233,6 +238,38 @@ function toTargetDetails(target: Readonly<TargetStoreEntry>, cwd: string) {
233
238
  };
234
239
  }
235
240
 
241
+ function resolveDisplaySections(details: ResolveDetails): ToolDisplaySection[] {
242
+ if (details.targets.length > 0) {
243
+ return [
244
+ createToolDisplaySection({
245
+ key: "resolve.targets",
246
+ title: "Targets",
247
+ items: details.targets,
248
+ totalCount: details.targetCount,
249
+ omittedCount: details.omittedCount,
250
+ format: (target) =>
251
+ `${target.name ?? "anonymous"} (${target.kind ?? "unknown"}) — ${target.file}:${target.displayLine}:${target.displayCharacter} [${target.targetId}]`,
252
+ }),
253
+ ];
254
+ }
255
+
256
+ if (details.candidates && details.candidates.length > 0) {
257
+ return [
258
+ createToolDisplaySection({
259
+ key: "resolve.candidates",
260
+ title: "Candidates",
261
+ items: details.candidates,
262
+ totalCount: details.targetCount,
263
+ omittedCount: details.omittedCount,
264
+ format: (candidate) =>
265
+ `${candidate.rank}. ${candidate.name} (${candidate.kind ?? "unknown"}) — ${candidate.file}:${candidate.line}:${candidate.character} [${candidate.targetId}]`,
266
+ }),
267
+ ];
268
+ }
269
+
270
+ return [];
271
+ }
272
+
236
273
  function resolveProvenance(outcome: TargetWorkflowOutcome): ResultProvenance[] {
237
274
  const sources = new Set<"semantic" | "structural">();
238
275
  if (outcome.kind === "resolved") {
@@ -19,6 +19,26 @@ import type {
19
19
  } from "../../session/target-store.ts";
20
20
  import type { ResultProvenance } from "./assembly.ts";
21
21
 
22
+ /** Final state for a public tool result. */
23
+ export type ToolResultStatus = "completed" | "invalid-input" | "disambiguation" | "unavailable";
24
+
25
+ /** Truncation state for model-facing tool content. */
26
+ export interface ToolOutputTruncationDetails {
27
+ truncated: boolean;
28
+ fullOutputPath?: string;
29
+ }
30
+
31
+ /** Bounded, structured rows for the expanded TUI body. */
32
+ export interface ToolDisplaySection {
33
+ key: string;
34
+ title: string;
35
+ lines: readonly string[];
36
+ shownCount: number;
37
+ totalCount: number | null;
38
+ omittedCount: number | null;
39
+ partialReason: string | null;
40
+ }
41
+
22
42
  // ── Anchored coordinate resolution metadata ───────────────────────────
23
43
 
24
44
  /**
@@ -6,6 +6,9 @@ import type {
6
6
  InspectDetails,
7
7
  ResolveDetails,
8
8
  SearchDetails,
9
+ ToolDisplaySection,
10
+ ToolOutputTruncationDetails,
11
+ ToolResultStatus,
9
12
  } from "../tool/result/types.ts";
10
13
 
11
14
  /**
@@ -26,6 +29,8 @@ import type {
26
29
  */
27
30
  export interface CodeIntelToolExecCtx {
28
31
  cwd: string;
32
+ /** Opaque identity for Debug Events directly owned by this public Tool call. */
33
+ operationId?: string;
29
34
  /** Abort signal from the agent runtime; forward to long-running subprocesses. */
30
35
  signal?: AbortSignal;
31
36
  /** Progress callback; long-running executors emit coarse beats, not chatty ones. */
@@ -39,13 +44,21 @@ export interface CodeIntelToolExecCtx {
39
44
  session: WorkspaceCodeIntelligenceSession;
40
45
  }
41
46
 
47
+ /** Shared metadata attached to one persisted Code Intelligence result. */
48
+ export interface CodeIntelResultDetails {
49
+ status?: ToolResultStatus;
50
+ message?: string;
51
+ displaySections?: readonly ToolDisplaySection[];
52
+ truncation?: ToolOutputTruncationDetails;
53
+ }
54
+
42
55
  /** Tool result shape returned by executeAction. */
43
56
  export interface CodeIntelResult {
44
57
  content: string;
45
58
  details?:
46
- | { type: "context"; data: ContextDetails }
47
- | { type: "inspect"; data: InspectDetails }
48
- | { type: "search"; data: SearchDetails }
49
- | { type: "resolve"; data: ResolveDetails }
50
- | { type: "health"; data: HealthDetails };
59
+ | (CodeIntelResultDetails & { type: "context"; data: ContextDetails })
60
+ | (CodeIntelResultDetails & { type: "inspect"; data: InspectDetails })
61
+ | (CodeIntelResultDetails & { type: "search"; data: SearchDetails })
62
+ | (CodeIntelResultDetails & { type: "resolve"; data: ResolveDetails })
63
+ | (CodeIntelResultDetails & { type: "health"; data: HealthDetails });
51
64
  }
@@ -8,7 +8,11 @@ export {
8
8
 
9
9
  // ── Execution context and result ────────────────────────────────────────
10
10
 
11
- export type { CodeIntelResult, CodeIntelToolExecCtx } from "./execution.ts";
11
+ export type {
12
+ CodeIntelResult,
13
+ CodeIntelResultDetails,
14
+ CodeIntelToolExecCtx,
15
+ } from "./execution.ts";
12
16
 
13
17
  // ── Detail types ────────────────────────────────────────────────────────
14
18
 
@@ -23,4 +27,7 @@ export type {
23
27
  OrientationSectionDetails,
24
28
  ResolveDetails,
25
29
  SearchDetails,
30
+ ToolDisplaySection,
31
+ ToolOutputTruncationDetails,
32
+ ToolResultStatus,
26
33
  } from "../tool/result/types.ts";
@@ -52,7 +52,7 @@ export function registerCiStatusCommand(pi: ExtensionAPI): void {
52
52
  fetchDetailedDiagnostics: async (maxSeverity) => {
53
53
  const lspState = getWorkspaceLspRuntime(ctx.cwd);
54
54
  if (lspState.kind !== "ready") return [];
55
- return lspState.runtime.getOutstandingDiagnostics(maxSeverity);
55
+ return lspState.runtime.getOutstandingDiagnostics(maxSeverity).entries;
56
56
  },
57
57
  onRefresh: async () => {
58
58
  const fresh = await gatherCiStatusData(ctx.cwd, pi);
@@ -95,10 +95,11 @@ async function gatherCiStatusData(cwd: string, pi: ExtensionAPI): Promise<CiStat
95
95
  const semanticAvailable = servers.some(
96
96
  (server) => server.status === "running" && server.ready === true,
97
97
  );
98
- const diagnostics =
98
+ const diagnosticSnapshot =
99
99
  lspState.kind === "ready" && semanticAvailable
100
100
  ? lspState.runtime.getOutstandingDiagnosticSummary(1)
101
- : [];
101
+ : { entries: [], current: false };
102
+ const diagnostics = diagnosticSnapshot.entries;
102
103
  const semanticState = deriveSemanticCapabilityState(workspace, lspState, semanticAvailable);
103
104
 
104
105
  // Sort: errors desc, warnings desc, info desc, hints desc
@@ -123,6 +124,7 @@ async function gatherCiStatusData(cwd: string, pi: ExtensionAPI): Promise<CiStat
123
124
  diagnostics,
124
125
  serverInventoryAvailable,
125
126
  semanticAvailable,
127
+ diagnosticSnapshotCurrent: diagnosticSnapshot.current,
126
128
  capabilities: {
127
129
  semantic: semanticState,
128
130
  structural: {
@@ -37,6 +37,8 @@ export interface CiStatusData {
37
37
  serverInventoryAvailable: boolean;
38
38
  /** Whether diagnostics and semantic absence claims are currently supported. */
39
39
  semanticAvailable: boolean;
40
+ /** Whether tracked-file diagnostic counts prove the current document and workspace state. */
41
+ diagnosticSnapshotCurrent: boolean;
40
42
  /** Sorted: errors desc, then warnings desc, then info desc, then hints desc. */
41
43
  diagnostics: OutstandingDiagnosticSummaryEntry[];
42
44
  capabilities: {
@@ -373,6 +375,8 @@ export class CiStatusDialog {
373
375
  const t = this.theme;
374
376
  if (!this.data.semanticAvailable) {
375
377
  container.addChild(new Text(t.fg("dim", " (diagnostics unavailable)"), 1, 0));
378
+ } else if (!this.data.diagnosticSnapshotCurrent) {
379
+ container.addChild(new Text(t.fg("warning", " diagnostic snapshot is stale"), 1, 0));
376
380
  } else {
377
381
  container.addChild(new Text(t.fg("success", " ✓ no issues"), 1, 0));
378
382
  }
@@ -6,19 +6,47 @@
6
6
  * partial/error guards, and the shared simple-result pattern.
7
7
  */
8
8
 
9
- import { getMarkdownTheme, type Theme } from "@earendil-works/pi-coding-agent";
9
+ import {
10
+ getMarkdownTheme,
11
+ type Theme,
12
+ type ToolRenderResultOptions,
13
+ } from "@earendil-works/pi-coding-agent";
10
14
  import { Container, Markdown, Spacer, Text } from "@earendil-works/pi-tui";
11
15
  import { formatEvidenceBadge } from "@mrclrchtr/supi-core/evidence-badge";
16
+ import { truncateDisplayText } from "../../tool/result/display.ts";
17
+ import { renderToolDisplaySections } from "./display.ts";
18
+
19
+ export { formatCallPath, formatCallValue, renderToolDisplaySections } from "./display.ts";
20
+
21
+ import type {
22
+ ToolDisplaySection,
23
+ ToolOutputTruncationDetails,
24
+ ToolResultStatus,
25
+ } from "../../tool/result/types.ts";
12
26
 
13
27
  // ── Result type ──────────────────────────────────────────────────
14
28
 
15
29
  /** Shape of a pi tool result consumed by renderResult functions. */
16
30
  export interface ToolResult {
17
31
  content: Array<{ type: string; text?: string }>;
18
- details?: { type: string; data: Record<string, unknown> };
19
- isError?: boolean;
32
+ details?: {
33
+ type: string;
34
+ data: Record<string, unknown>;
35
+ status?: ToolResultStatus;
36
+ message?: string;
37
+ displaySections?: readonly ToolDisplaySection[];
38
+ truncation?: ToolOutputTruncationDetails;
39
+ };
40
+ }
41
+
42
+ /** PI render context used by Code Intelligence result renderers. */
43
+ export interface ToolRendererContext {
44
+ isError: boolean;
20
45
  }
21
46
 
47
+ /** PI render options used by Code Intelligence result renderers. */
48
+ export type ResultOptios = ToolRenderResultOptions;
49
+
22
50
  // ── Evidence key labels ──────────────────────────────────────────
23
51
 
24
52
  export const EVIDENCE_KEY_LABELS: Record<string, string> = {
@@ -142,7 +170,7 @@ export function renderMarkdownDetail(
142
170
  const markdownText = source.content?.find((c) => c.type === "text")?.text ?? "";
143
171
  if (!markdownText) return;
144
172
  container.addChild(new Spacer(1));
145
- const divider = `${theme.fg("border", "────")} ${theme.fg("dim", "raw markdown")} ${theme.fg("border", "".repeat(100))}`;
173
+ const divider = `${theme.fg("border", "────")} ${theme.fg("dim", "raw markdown")} ${theme.fg("border", "────")}`;
146
174
  container.addChild(new Text(divider, 0, 0));
147
175
  container.addChild(new Markdown(markdownText, 0, 0, getMarkdownTheme()));
148
176
  }
@@ -157,13 +185,62 @@ export function renderError(label: string, theme: Theme): Text {
157
185
  return new Text(theme.fg("error", label), 0, 0);
158
186
  }
159
187
 
160
- // ── Result options ───────────────────────────────────────────────
188
+ /** Render an execution failure from PI's renderer context. */
189
+ export function renderExecutionError(
190
+ context: ToolRendererContext | undefined,
191
+ label: string,
192
+ theme: Theme,
193
+ ): Text | null {
194
+ return context?.isError ? renderError(label, theme) : null;
195
+ }
196
+
197
+ /** Render a domain error encoded in structured result details. */
198
+ export function renderDomainError(result: ToolResult, theme: Theme): Text | null {
199
+ const status = result.details?.status;
200
+ if (status !== "invalid-input" && status !== "disambiguation" && status !== "unavailable") {
201
+ return null;
202
+ }
203
+
204
+ const label =
205
+ status === "invalid-input"
206
+ ? "Invalid input"
207
+ : status === "disambiguation"
208
+ ? "Choose a target"
209
+ : "Unavailable";
210
+ const message = result.details?.message
211
+ ? `: ${truncateDisplayText(result.details.message, 160)}`
212
+ : "";
213
+ return renderError(`${label}${message}`, theme);
214
+ }
215
+
216
+ /** Render an invalid-input or unavailable result with its structured body. */
217
+ export function renderDomainResult(
218
+ result: ToolResult,
219
+ options: ResultOptios,
220
+ theme: Theme,
221
+ error: Text,
222
+ ): Container | Text {
223
+ if (!options.expanded) return error;
224
+ const container = new Container();
225
+ container.addChild(error);
226
+ renderToolDisplaySections(container, result.details?.displaySections, theme);
227
+ renderMarkdownDetail(container, result, theme);
228
+ return container;
229
+ }
161
230
 
162
- export interface ResultOptios {
163
- expanded: boolean;
164
- isPartial: boolean;
231
+ /** Render the structured output-truncation disclosure. */
232
+ export function renderTruncationDisclosure(result: ToolResult, theme: Theme): Text | null {
233
+ const truncation = result.details?.truncation;
234
+ if (!truncation?.truncated) return null;
235
+
236
+ const path = truncation.fullOutputPath
237
+ ? `; full output: ${truncateDisplayText(truncation.fullOutputPath, 160)}`
238
+ : "";
239
+ return new Text(theme.fg("warning", `Output truncated${path}`), 0, 0);
165
240
  }
166
241
 
242
+ // ── Result options ───────────────────────────────────────────────
243
+
167
244
  // ── Shared simple-result renderer ─────────────────────────────────
168
245
 
169
246
  /**
@@ -172,19 +249,34 @@ export interface ResultOptios {
172
249
  *
173
250
  * Handles partial, error, compact, and expanded states uniformly.
174
251
  */
252
+ // biome-ignore lint/complexity/useMaxParams: renderer signature keeps the shared helper convenient for each tool
175
253
  export function renderSimpleResult(
176
254
  result: ToolResult,
177
255
  options: ResultOptios,
178
256
  theme: Theme,
179
257
  partialLabel: string,
258
+ context?: ToolRendererContext,
180
259
  ): Container | Text {
181
260
  if (options.isPartial) return renderPartial(partialLabel, theme);
182
- if (result.isError) return renderError("Tool failed", theme);
261
+
262
+ const executionError = renderExecutionError(context, "Tool failed", theme);
263
+ if (executionError) return executionError;
264
+
265
+ const domainError = renderDomainError(result, theme);
266
+ if (domainError) return renderDomainResult(result, options, theme, domainError);
183
267
 
184
268
  const data = result.details?.data as Record<string, unknown> | undefined;
185
269
  if (options.expanded) return buildExpandedView(result, data, theme);
186
270
 
187
- return buildSimpleCompact(data, theme);
271
+ const compact = buildSimpleCompact(data, theme);
272
+ const truncation = renderTruncationDisclosure(result, theme);
273
+ if (!truncation) return compact;
274
+
275
+ const container = new Container();
276
+ container.addChild(compact);
277
+ container.addChild(new Spacer(1));
278
+ container.addChild(truncation);
279
+ return container;
188
280
  }
189
281
 
190
282
  function buildExpandedView(
@@ -197,7 +289,13 @@ function buildExpandedView(
197
289
  const header = buildSimpleHeader(data, theme);
198
290
  if (header) container.addChild(header);
199
291
 
292
+ renderToolDisplaySections(container, result.details?.displaySections, theme);
200
293
  renderStructuredDetailBody(container, data, theme);
294
+ const truncation = renderTruncationDisclosure(result, theme);
295
+ if (truncation) {
296
+ container.addChild(new Spacer(1));
297
+ container.addChild(truncation);
298
+ }
201
299
  renderMarkdownDetail(container, result, theme);
202
300
 
203
301
  return container;
@@ -0,0 +1,48 @@
1
+ import type { Theme } from "@earendil-works/pi-coding-agent";
2
+ import { type Container, Text } from "@earendil-works/pi-tui";
3
+ import { readToolDisplaySections, truncateDisplayText } from "../../tool/result/display.ts";
4
+ import type { ToolDisplaySection } from "../../tool/result/types.ts";
5
+
6
+ /** Render bounded structured rows for an expanded TUI body. */
7
+ export function renderToolDisplaySections(
8
+ container: Container,
9
+ value: unknown,
10
+ theme: Theme,
11
+ ): void {
12
+ for (const section of readToolDisplaySections(value)) {
13
+ container.addChild(
14
+ new Text(theme.fg("dim", `${section.title}${formatDisplayBounds(section)}`), 0, 0),
15
+ );
16
+ for (const line of section.lines) {
17
+ container.addChild(new Text(theme.fg("muted", line), 0, 0));
18
+ }
19
+ }
20
+ }
21
+
22
+ function formatDisplayBounds(section: ToolDisplaySection): string {
23
+ if (section.totalCount === null) {
24
+ const omitted = section.omittedCount ? `; ${section.omittedCount} collected omitted` : "";
25
+ const reason = section.partialReason
26
+ ? `; more may exist — ${section.partialReason}`
27
+ : "; partial";
28
+ return ` (${section.shownCount}${omitted}${reason})`;
29
+ }
30
+ if (section.omittedCount && section.omittedCount > 0) {
31
+ return ` (${section.shownCount} of ${section.totalCount}; ${section.omittedCount} omitted)`;
32
+ }
33
+ return ` (${section.totalCount})`;
34
+ }
35
+
36
+ /** Format one call argument for a compact human transcript row. */
37
+ export function formatCallValue(value: unknown, maxLength = 60): string | null {
38
+ if (typeof value !== "string" || value.length === 0) return null;
39
+ const normalized = value.replace(/\s+/g, " ").trim();
40
+ return truncateDisplayText(normalized, maxLength);
41
+ }
42
+
43
+ /** Show the final path segment while accepting both POSIX and Windows paths. */
44
+ export function formatCallPath(value: unknown, maxLength = 60): string | null {
45
+ const formatted = formatCallValue(value, Number.MAX_SAFE_INTEGER);
46
+ if (!formatted) return null;
47
+ return formatCallValue(formatted.split(/[\\/]/).pop() ?? formatted, maxLength);
48
+ }