@danypops/pi-lector 0.17.0 → 0.17.2
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.
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
CallHierarchyEntry,
|
|
3
3
|
Diagnostic,
|
|
4
|
+
DiagnosticContext,
|
|
4
5
|
DocumentSymbolEntry,
|
|
5
6
|
Hover,
|
|
6
7
|
IncomingCall,
|
|
@@ -153,8 +154,21 @@ export function formatDiagnosticsCall(args: { path?: unknown }, theme: LectorThe
|
|
|
153
154
|
return `${theme.fg("toolTitle", theme.bold(presentationTitle("diagnostics")))} ${theme.fg("accent", path)}`;
|
|
154
155
|
}
|
|
155
156
|
|
|
156
|
-
|
|
157
|
-
|
|
157
|
+
/** Describes project confidence separately from native diagnostics, optionally including setup actions. */
|
|
158
|
+
export function describeDiagnosticContext(context: DiagnosticContext | undefined, expanded = true): string {
|
|
159
|
+
const lines = [`Project context: ${context?.confidence ?? "unknown"}`];
|
|
160
|
+
if (expanded) for (const finding of context?.setupFindings ?? []) lines.push(`setup ${finding.kind}: ${finding.action}`);
|
|
161
|
+
return lines.join("\n");
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function formatDiagnosticsResult(
|
|
165
|
+
diagnostics: readonly Diagnostic[] | undefined,
|
|
166
|
+
expanded: boolean,
|
|
167
|
+
theme: LectorTheme,
|
|
168
|
+
context?: DiagnosticContext,
|
|
169
|
+
): string {
|
|
170
|
+
const contextText = context ? `${describeDiagnosticContext(context, expanded)}\n` : "";
|
|
171
|
+
if (!diagnostics || diagnostics.length === 0) return contextText + theme.fg("success", "No diagnostics.");
|
|
158
172
|
|
|
159
173
|
const lines = [
|
|
160
174
|
theme.fg("muted", `${diagnostics.length} diagnostic${diagnostics.length === 1 ? "" : "s"}:`),
|
|
@@ -171,7 +185,7 @@ export function formatDiagnosticsResult(diagnostics: readonly Diagnostic[] | und
|
|
|
171
185
|
moreLine: moreLine(theme),
|
|
172
186
|
}),
|
|
173
187
|
];
|
|
174
|
-
return lines.join("\n");
|
|
188
|
+
return contextText + lines.join("\n");
|
|
175
189
|
}
|
|
176
190
|
|
|
177
191
|
function formatPathCall(toolName: string, args: { path?: unknown }, theme: LectorTheme, qualifier = ""): string {
|
package/extension/src/index.ts
CHANGED
|
@@ -4,7 +4,6 @@ import { resolve } from "node:path";
|
|
|
4
4
|
import type {
|
|
5
5
|
CachedRepositoryPage,
|
|
6
6
|
ContentHash,
|
|
7
|
-
Diagnostic,
|
|
8
7
|
DocumentSymbolEntry,
|
|
9
8
|
EditOutcome,
|
|
10
9
|
FindFilesResult,
|
|
@@ -53,6 +52,7 @@ import { formatApplyPatchCall, formatApplyPatchResult } from "./apply-patch/rend
|
|
|
53
52
|
import { createLectorCodeIntelligenceOperations } from "./code-intelligence/operations.ts";
|
|
54
53
|
import {
|
|
55
54
|
type CallHierarchyToolDetails,
|
|
55
|
+
describeDiagnosticContext,
|
|
56
56
|
formatCallHierarchyCall,
|
|
57
57
|
formatCallHierarchyResult,
|
|
58
58
|
formatCodeActionApplyCall,
|
|
@@ -324,8 +324,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
324
324
|
});
|
|
325
325
|
|
|
326
326
|
let cachingOverlay: CachingOverlay | undefined;
|
|
327
|
+
let disposeWorkspaceObserver: (() => void) | undefined;
|
|
327
328
|
pi.on("session_shutdown", (_event, ctx) => {
|
|
328
329
|
sessionGeneration++;
|
|
330
|
+
disposeWorkspaceObserver?.();
|
|
331
|
+
disposeWorkspaceObserver = undefined;
|
|
329
332
|
cacheStatesByRoot.clear();
|
|
330
333
|
monitoringRoots.clear();
|
|
331
334
|
lastInjectedSummary = undefined;
|
|
@@ -343,7 +346,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
343
346
|
monitoringRoots.clear();
|
|
344
347
|
lastInjectedSummary = undefined;
|
|
345
348
|
uiContext = ctx;
|
|
346
|
-
|
|
349
|
+
disposeWorkspaceObserver?.();
|
|
350
|
+
const observerGeneration = sessionGeneration;
|
|
351
|
+
disposeWorkspaceObserver = setNewWorkspaceObserver((root) => {
|
|
352
|
+
if (sessionGeneration === observerGeneration) startMonitoringRoot(root, ctx);
|
|
353
|
+
});
|
|
347
354
|
if (ctx.hasUI) {
|
|
348
355
|
// The persistent widget counterpart to the single-line "lector-cache" status above.
|
|
349
356
|
// Ownership is the Pi session, not cwd: one session may legitimately touch several roots.
|
|
@@ -437,7 +444,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
437
444
|
name: "localize_context",
|
|
438
445
|
label: "Localize Context",
|
|
439
446
|
description:
|
|
440
|
-
"Localize a natural-language coding task to a bounded, ranked set of workspace symbols. Combines lexical source matches with the persisted call/reference/containment graph, returns compact signatures and explicit score reasons, and reports incomplete or unavailable graph coverage. The daemon does not invoke an LLM. `directory` selects the project explicitly.",
|
|
447
|
+
"Localize a natural-language coding task to a bounded, ranked set of workspace symbols. Combines lexical source matches with the persisted call/reference/containment graph, returns compact signatures and explicit score reasons, and reports incomplete or unavailable graph coverage. Returns workspace-relative paths, excluding dependency and escaped symlink targets; inspect a package through its separately registered workspace. Checks generation hashes against bounded current source snapshots; stale or unverified declarations are excluded and completeness is reduced. The daemon does not invoke an LLM. `directory` selects the project explicitly.",
|
|
441
448
|
promptSnippet: "Localize a coding task to ranked symbols and compact graph-backed context",
|
|
442
449
|
promptGuidelines: [
|
|
443
450
|
"Use localize_context near the start of an unfamiliar implementation or debugging task to get a bounded candidate set before reading files one by one.",
|
|
@@ -771,7 +778,8 @@ export default function (pi: ExtensionAPI) {
|
|
|
771
778
|
registerLectorTool({
|
|
772
779
|
name: "diagnostics",
|
|
773
780
|
label: "Diagnostics",
|
|
774
|
-
description:
|
|
781
|
+
description:
|
|
782
|
+
"List native errors and warnings with bounded project-context confidence, separate setup findings, synchronized source hash and reported document versions. Server readiness is not compiler verification; unreported configuration stays unknown.",
|
|
775
783
|
promptSnippet: "List current errors/warnings for one file",
|
|
776
784
|
promptGuidelines: ["Use diagnostics after an edit to check for new type errors in one specific file, instead of running a full project build."],
|
|
777
785
|
parameters: Type.Object({ path: Type.String({ description: "Absolute or cwd-relative path to the file" }) }),
|
|
@@ -782,7 +790,10 @@ export default function (pi: ExtensionAPI) {
|
|
|
782
790
|
details.diagnostics.length === 0
|
|
783
791
|
? "No diagnostics."
|
|
784
792
|
: details.diagnostics.map((d) => `${d.severity} ${d.range.path}:${d.range.start.line}:${d.range.start.character} -- ${d.message}`).join("\n");
|
|
785
|
-
return {
|
|
793
|
+
return {
|
|
794
|
+
content: [{ type: "text", text: `${describeIntelligenceSource(details.provenance)}\n${describeDiagnosticContext(details.context)}\n${text}` }],
|
|
795
|
+
details,
|
|
796
|
+
};
|
|
786
797
|
},
|
|
787
798
|
renderCall(args, theme, context) {
|
|
788
799
|
const text = context.lastComponent instanceof Text ? context.lastComponent : new Text("", 0, 0);
|
|
@@ -798,9 +809,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
798
809
|
.join("\n");
|
|
799
810
|
return new Text(theme.fg("error", errorText || "diagnostics failed"), 0, 0);
|
|
800
811
|
}
|
|
801
|
-
const details = result.details as
|
|
812
|
+
const details = result.details as OperationOutputs["workspace.diagnostics"] | undefined;
|
|
802
813
|
const text = context.lastComponent instanceof Text ? context.lastComponent : new Text("", 0, 0);
|
|
803
|
-
text.setText(renderIntelligenceSource(formatDiagnosticsResult(details?.diagnostics, expanded, theme), details?.provenance, theme));
|
|
814
|
+
text.setText(renderIntelligenceSource(formatDiagnosticsResult(details?.diagnostics, expanded, theme, details?.context), details?.provenance, theme));
|
|
804
815
|
return text;
|
|
805
816
|
},
|
|
806
817
|
});
|
|
@@ -61,8 +61,13 @@ const retryingClient: RetryingClient<LectorClient> = createRetryingClient(() =>
|
|
|
61
61
|
*/
|
|
62
62
|
let onNewWorkspace: ((root: string) => void) | undefined;
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
/** Registers a workspace observer and returns an idempotent disposer that preserves later registrations. */
|
|
65
|
+
export function setNewWorkspaceObserver(observer: ((root: string) => void) | undefined): () => void {
|
|
66
|
+
const registration = observer ? (root: string) => observer(root) : undefined;
|
|
67
|
+
onNewWorkspace = registration;
|
|
68
|
+
return () => {
|
|
69
|
+
if (onNewWorkspace === registration) onNewWorkspace = undefined;
|
|
70
|
+
};
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
export interface RetryingLectorClient {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danypops/pi-lector",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.2",
|
|
4
4
|
"description": "Pi host adapter for Lector: overrides read/write/edit with a daemon-backed, hash-guarded filesystem",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@danypops/vehicle-client-pi": "^0.45.0"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@danypops/lector": "^0.23.
|
|
25
|
+
"@danypops/lector": "^0.23.1",
|
|
26
26
|
"@danypops/vehicle-client": "^0.10.8",
|
|
27
27
|
"@danypops/vehicle-core": "^0.19.1",
|
|
28
28
|
"malevich-tui-components": "^0.32.1",
|