@danypops/pi-lector 0.7.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -12,11 +12,17 @@ pi install npm:@danypops/pi-lector
|
|
|
12
12
|
|
|
13
13
|
Symbol and semantic tool results identify their backend and fidelity. `typescript-language-server` results are semantic; compiler or parser fallback results are structural and list their limitations.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
Every workspace's symbol graph auto-populates in the background the moment any tool
|
|
16
|
+
first touches it -- reachable_from, workspace_map, reference_based_rename, and
|
|
17
|
+
symbol_annotations all return an empty or refusing result rather than an error if
|
|
18
|
+
it's still building, instead of requiring an explicit "start indexing" call.
|
|
18
19
|
|
|
19
20
|
When a session starts inside a Git repository, pi-lector checks a durable, bounded
|
|
20
21
|
source-content manifest without blocking startup. The footer reports not cached,
|
|
21
|
-
caching, or cached
|
|
22
|
-
|
|
22
|
+
caching, or cached across every workspace touched so far this session; completion
|
|
23
|
+
also emits a one-shot notification. Session shutdown stops polling, and the agent
|
|
24
|
+
receives each state transition once in its context.
|
|
25
|
+
|
|
26
|
+
For an explicit, custom-bound population outside of Pi (a larger scan than the
|
|
27
|
+
default 500 files / 100 symbols per file), use `lector workspace populate-symbol-graph`
|
|
28
|
+
and `lector job status` directly.
|
|
@@ -37,7 +37,14 @@ export interface CodeIntelligenceOperations {
|
|
|
37
37
|
prepareCallHierarchy(path: string, line: number, character: number): Promise<OperationOutputs["workspace.prepareCallHierarchy"]>;
|
|
38
38
|
incomingCalls(path: string, line: number, character: number): Promise<OperationOutputs["workspace.incomingCalls"]>;
|
|
39
39
|
outgoingCalls(path: string, line: number, character: number): Promise<OperationOutputs["workspace.outgoingCalls"]>;
|
|
40
|
+
/**
|
|
41
|
+
* Not exposed as a standalone Pi tool -- every workspace auto-populates on first touch via
|
|
42
|
+
* monitorWorkspaceCache (workspace-cache-operations.ts). Kept here as an internal capability
|
|
43
|
+
* for tests that need a populated graph. For an explicit/custom-bound population outside
|
|
44
|
+
* Pi entirely, `lector workspace populate-symbol-graph` calls the daemon directly.
|
|
45
|
+
*/
|
|
40
46
|
populateSymbolGraph(path: string, maxFiles: number, maxSymbolsPerFile: number, waitMs?: number): Promise<JobSnapshot<PopulateSymbolGraphResult>>;
|
|
47
|
+
/** Not exposed as a standalone Pi tool -- see populateSymbolGraph. */
|
|
41
48
|
jobStatus(jobId: string): Promise<JobSnapshot<PopulateSymbolGraphResult>>;
|
|
42
49
|
reachableFrom(path: string, line: number, character: number, maxDepth: number, kind?: SymbolEdgeKind): Promise<readonly SymbolNode[]>;
|
|
43
50
|
/** Never spawns a symbol index -- safe to call opportunistically (e.g. before deciding whether to enrich a result). */
|
|
@@ -5,9 +5,7 @@ import type {
|
|
|
5
5
|
Hover,
|
|
6
6
|
IncomingCall,
|
|
7
7
|
IntelligenceProvenance,
|
|
8
|
-
JobSnapshot,
|
|
9
8
|
OutgoingCall,
|
|
10
|
-
PopulateSymbolGraphResult,
|
|
11
9
|
SymbolNode,
|
|
12
10
|
WorkspaceLocation,
|
|
13
11
|
WorkspaceMapResult,
|
|
@@ -213,29 +211,6 @@ export function formatCallHierarchyResult(details: CallHierarchyToolDetails | un
|
|
|
213
211
|
return formatOutgoingCallsResult(details.calls, expanded, theme);
|
|
214
212
|
}
|
|
215
213
|
|
|
216
|
-
export function formatPopulateSymbolGraphCall(args: { path?: unknown; maxFiles?: unknown; maxSymbolsPerFile?: unknown }, theme: LectorTheme): string {
|
|
217
|
-
const path = typeof args.path === "string" ? args.path : "";
|
|
218
|
-
return `${theme.fg("toolTitle", theme.bold("populate_symbol_graph"))} ${theme.fg("accent", path)}`;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
export function describePopulateSymbolGraphJob(job: JobSnapshot<PopulateSymbolGraphResult>): string {
|
|
222
|
-
if (job.status === "queued") return `Source workspace is registered; symbol graph is queued and still loading (job ${job.id}). Poll job_status.`;
|
|
223
|
-
if (job.status === "running") return `Source workspace is registered; symbol graph is still loading (job ${job.id}). Poll job_status.`;
|
|
224
|
-
if (job.status === "failed") return `Job ${job.id} failed [${job.error.code}] -- ${job.error.message}`;
|
|
225
|
-
const result = job.result;
|
|
226
|
-
const counts = `${result.filesProcessed}/${result.filesAttempted} files, ${result.symbolsProcessed} symbol${result.symbolsProcessed === 1 ? "" : "s"}, ${result.nodesAdded} node${result.nodesAdded === 1 ? "" : "s"}, ${result.edgesAdded} edge${result.edgesAdded === 1 ? "" : "s"}`;
|
|
227
|
-
if (result.completeness === "complete") return `Job ${job.id} cached ${counts}`;
|
|
228
|
-
const first = result.failures[0];
|
|
229
|
-
const failure = first ? ` First failure: ${first.path} [${first.code} via ${first.provenance.backend}] ${first.message}` : "";
|
|
230
|
-
return `Job ${job.id} partially cached ${counts}; ${result.filesFailed} failed file${result.filesFailed === 1 ? "" : "s"} (${result.failureCount} failed operations).${failure}`;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
export function formatPopulateSymbolGraphResult(job: JobSnapshot<PopulateSymbolGraphResult> | undefined, theme: LectorTheme): string {
|
|
234
|
-
if (!job) return theme.fg("dim", "No job result.");
|
|
235
|
-
const color = job.status === "failed" ? "error" : job.status === "succeeded" ? "muted" : "warning";
|
|
236
|
-
return theme.fg(color, describePopulateSymbolGraphJob(job));
|
|
237
|
-
}
|
|
238
|
-
|
|
239
214
|
export function formatReachableFromCall(args: { path?: unknown; line?: unknown; character?: unknown; maxDepth?: unknown }, theme: LectorTheme): string {
|
|
240
215
|
const base = formatPositionalCall("reachable_from", args, theme);
|
|
241
216
|
const maxDepth = typeof args.maxDepth === "number" ? args.maxDepth : "?";
|
|
@@ -243,7 +218,8 @@ export function formatReachableFromCall(args: { path?: unknown; line?: unknown;
|
|
|
243
218
|
}
|
|
244
219
|
|
|
245
220
|
export function formatReachableFromResult(symbols: readonly SymbolNode[] | undefined, expanded: boolean, theme: LectorTheme): string {
|
|
246
|
-
if (!symbols || symbols.length === 0)
|
|
221
|
+
if (!symbols || symbols.length === 0)
|
|
222
|
+
return theme.fg("dim", "Nothing reachable at this position (the workspace's symbol graph may still be populating in the background -- retry shortly).");
|
|
247
223
|
|
|
248
224
|
const displayCount = expanded ? symbols.length : Math.min(symbols.length, DEFAULT_VISIBLE_CALLS);
|
|
249
225
|
const lines = [theme.fg("muted", `${symbols.length} reachable symbol${symbols.length === 1 ? "" : "s"}:`)];
|
|
@@ -261,7 +237,8 @@ export function formatWorkspaceMapCall(args: { path?: unknown; maxEntries?: unkn
|
|
|
261
237
|
}
|
|
262
238
|
|
|
263
239
|
export function formatWorkspaceMapResult(result: WorkspaceMapResult | undefined, expanded: boolean, theme: LectorTheme): string {
|
|
264
|
-
if (!result || result.entries.length === 0)
|
|
240
|
+
if (!result || result.entries.length === 0)
|
|
241
|
+
return theme.fg("dim", "No ranked symbols (the workspace's symbol graph may still be populating in the background -- retry shortly).");
|
|
265
242
|
|
|
266
243
|
const displayCount = expanded ? result.entries.length : Math.min(result.entries.length, DEFAULT_VISIBLE_SYMBOLS);
|
|
267
244
|
const lines = [
|
package/extension/src/index.ts
CHANGED
|
@@ -9,14 +9,12 @@ import type {
|
|
|
9
9
|
GithubRepoSearchResult,
|
|
10
10
|
Hover,
|
|
11
11
|
IntelligenceProvenance,
|
|
12
|
-
JobSnapshot,
|
|
13
12
|
LineEdit,
|
|
14
13
|
LineEditOutcome,
|
|
15
14
|
MutationHistoryEntry,
|
|
16
15
|
NpmPackageCandidate,
|
|
17
16
|
OperationOutputs,
|
|
18
17
|
PackageSourceOperationResult,
|
|
19
|
-
PopulateSymbolGraphResult,
|
|
20
18
|
RepoFetchResult,
|
|
21
19
|
SourcegraphCodeCandidate,
|
|
22
20
|
SymbolAnnotation,
|
|
@@ -42,7 +40,6 @@ import { formatApplyPatchCall, formatApplyPatchResult } from "./apply-patch-rend
|
|
|
42
40
|
import { createLectorCodeIntelligenceOperations } from "./code-intelligence-operations.ts";
|
|
43
41
|
import {
|
|
44
42
|
type CallHierarchyToolDetails,
|
|
45
|
-
describePopulateSymbolGraphJob,
|
|
46
43
|
formatCallHierarchyCall,
|
|
47
44
|
formatCallHierarchyResult,
|
|
48
45
|
formatDiagnosticsCall,
|
|
@@ -57,8 +54,6 @@ import {
|
|
|
57
54
|
formatGoToImplementationResult,
|
|
58
55
|
formatHoverCall,
|
|
59
56
|
formatHoverResult,
|
|
60
|
-
formatPopulateSymbolGraphCall,
|
|
61
|
-
formatPopulateSymbolGraphResult,
|
|
62
57
|
formatReachableFromCall,
|
|
63
58
|
formatReachableFromResult,
|
|
64
59
|
formatWorkspaceMapCall,
|
|
@@ -623,87 +618,6 @@ export default function (pi: ExtensionAPI) {
|
|
|
623
618
|
},
|
|
624
619
|
});
|
|
625
620
|
|
|
626
|
-
pi.registerTool({
|
|
627
|
-
name: "populate_symbol_graph",
|
|
628
|
-
label: "Populate Symbol Graph",
|
|
629
|
-
description:
|
|
630
|
-
"Walk a workspace's real call relationships into a persisted graph, so reachable_from can answer multi-hop questions (transitive callers, reachability) without chaining many find_references/call_hierarchy calls by hand. Run this once before reachable_from.",
|
|
631
|
-
promptSnippet: "Populate a workspace's symbol graph for multi-hop queries",
|
|
632
|
-
promptGuidelines: [
|
|
633
|
-
"Run populate_symbol_graph once for a workspace before using reachable_from against it; an unpopulated workspace's graph is empty, not an error.",
|
|
634
|
-
"populate_symbol_graph waits briefly, then returns a job id with an explicit still-loading state instead of blocking the turn. Use job_status later; do not spin in a blind polling loop.",
|
|
635
|
-
"maxFiles and maxSymbolsPerFile are both required and bound the scan explicitly -- a symbol-dense file (many interfaces/properties) can easily exceed a small maxSymbolsPerFile before reaching the functions/methods that actually matter.",
|
|
636
|
-
],
|
|
637
|
-
parameters: Type.Object({
|
|
638
|
-
path: Type.String({ description: "Any absolute or cwd-relative path inside the workspace to populate" }),
|
|
639
|
-
maxFiles: Type.Number({ description: "Maximum number of source files to scan" }),
|
|
640
|
-
maxSymbolsPerFile: Type.Number({ description: "Maximum number of declarations to process per file" }),
|
|
641
|
-
initialWaitMs: Type.Optional(Type.Number({ description: "Bounded initial wait before returning a still-loading job; defaults to 500, maximum 30000" })),
|
|
642
|
-
}),
|
|
643
|
-
async execute(_toolCallId, params) {
|
|
644
|
-
const path = resolve(cwd, params.path);
|
|
645
|
-
const job = await codeIntelligenceOperations.populateSymbolGraph(path, params.maxFiles, params.maxSymbolsPerFile, params.initialWaitMs);
|
|
646
|
-
return {
|
|
647
|
-
content: [{ type: "text", text: describePopulateSymbolGraphJob(job) }],
|
|
648
|
-
details: { job },
|
|
649
|
-
};
|
|
650
|
-
},
|
|
651
|
-
renderCall(args, theme, context) {
|
|
652
|
-
const text = context.lastComponent instanceof Text ? context.lastComponent : new Text("", 0, 0);
|
|
653
|
-
text.setText(formatPopulateSymbolGraphCall(args, theme));
|
|
654
|
-
return text;
|
|
655
|
-
},
|
|
656
|
-
renderResult(result, { isPartial }, theme, context) {
|
|
657
|
-
if (isPartial) return new Text(theme.fg("warning", "Populating symbol graph..."), 0, 0);
|
|
658
|
-
if (context.isError) {
|
|
659
|
-
const errorText = result.content
|
|
660
|
-
.filter((block) => block.type === "text")
|
|
661
|
-
.map((block) => block.text)
|
|
662
|
-
.join("\n");
|
|
663
|
-
return new Text(theme.fg("error", errorText || "populate_symbol_graph failed"), 0, 0);
|
|
664
|
-
}
|
|
665
|
-
const details = result.details as { job?: JobSnapshot<PopulateSymbolGraphResult> } | undefined;
|
|
666
|
-
const text = context.lastComponent instanceof Text ? context.lastComponent : new Text("", 0, 0);
|
|
667
|
-
text.setText(formatPopulateSymbolGraphResult(details?.job, theme));
|
|
668
|
-
return text;
|
|
669
|
-
},
|
|
670
|
-
});
|
|
671
|
-
|
|
672
|
-
pi.registerTool({
|
|
673
|
-
name: "job_status",
|
|
674
|
-
label: "Job Status",
|
|
675
|
-
description:
|
|
676
|
-
"Poll one process-lifetime Lector background job. Returns queued/running with an actionable still-loading state, succeeded with the bounded result, or failed with a stable error code and message. Jobs are bounded and do not survive daemon restart; an unknown id explains expiry/restart rather than returning empty data.",
|
|
677
|
-
promptSnippet: "Poll a Lector background job by id",
|
|
678
|
-
parameters: Type.Object({
|
|
679
|
-
jobId: Type.String({ description: "Job id returned by populate_symbol_graph" }),
|
|
680
|
-
}),
|
|
681
|
-
async execute(_toolCallId, params) {
|
|
682
|
-
const job = await codeIntelligenceOperations.jobStatus(params.jobId);
|
|
683
|
-
return { content: [{ type: "text", text: describePopulateSymbolGraphJob(job) }], details: { job } };
|
|
684
|
-
},
|
|
685
|
-
renderCall(args, theme, context) {
|
|
686
|
-
const jobId = typeof args.jobId === "string" ? args.jobId : "";
|
|
687
|
-
const text = context.lastComponent instanceof Text ? context.lastComponent : new Text("", 0, 0);
|
|
688
|
-
text.setText(`${theme.fg("toolTitle", theme.bold("job_status"))} ${theme.fg("accent", jobId)}`);
|
|
689
|
-
return text;
|
|
690
|
-
},
|
|
691
|
-
renderResult(result, { isPartial }, theme, context) {
|
|
692
|
-
if (isPartial) return new Text(theme.fg("warning", "Checking background job..."), 0, 0);
|
|
693
|
-
if (context.isError) {
|
|
694
|
-
const errorText = result.content
|
|
695
|
-
.filter((block) => block.type === "text")
|
|
696
|
-
.map((block) => block.text)
|
|
697
|
-
.join("\n");
|
|
698
|
-
return new Text(theme.fg("error", errorText || "job_status failed"), 0, 0);
|
|
699
|
-
}
|
|
700
|
-
const details = result.details as { job?: JobSnapshot<PopulateSymbolGraphResult> } | undefined;
|
|
701
|
-
const text = context.lastComponent instanceof Text ? context.lastComponent : new Text("", 0, 0);
|
|
702
|
-
text.setText(formatPopulateSymbolGraphResult(details?.job, theme));
|
|
703
|
-
return text;
|
|
704
|
-
},
|
|
705
|
-
});
|
|
706
|
-
|
|
707
621
|
pi.registerTool({
|
|
708
622
|
name: "reference_based_rename",
|
|
709
623
|
label: "Reference-Based Rename",
|
|
@@ -711,7 +625,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
711
625
|
"Move/rename a file and rewrite every static import/export specifier the workspace's own populated symbol graph knows references it -- atomically, rolled back entirely on any failure. Non-LSP: uses find_references + a real parse of import/export declarations, not a language server's own rename. Refuses outright (touches nothing) unless the workspace's symbol graph is fully populated and current for the given bounds -- a partial rename that silently misses a reference is worse than refusing (Sourcegraph's CodeScaleBench finding). Does not follow dynamic import(expr)/require(expr) or any plain string reference to the file -- always check the returned caveats.",
|
|
712
626
|
promptSnippet: "Move a file and update every import that references it",
|
|
713
627
|
promptGuidelines: [
|
|
714
|
-
"
|
|
628
|
+
"The workspace's symbol graph auto-populates in the background (default bounds: 500 files, 100 symbols/file) the first time this workspace is touched. If this refuses because the graph isn't populated at the requested maxFiles/maxSymbolsPerFile, run `lector workspace populate-symbol-graph <path> --max-files <n> --max-symbols-per-file <n>` via bash for a larger scan, then retry.",
|
|
715
629
|
"Always read the returned caveats: this never rewrites a dynamic import(expr)/require(expr) or a plain string reference to the old path, even if one exists.",
|
|
716
630
|
],
|
|
717
631
|
parameters: Type.Object({
|
|
@@ -840,10 +754,10 @@ export default function (pi: ExtensionAPI) {
|
|
|
840
754
|
name: "symbol_annotations",
|
|
841
755
|
label: "Symbol Annotations",
|
|
842
756
|
description:
|
|
843
|
-
'Agent-authored narrative content anchored to one or more symbols in the workspace\'s persisted graph -- e.g. a "user story dataflow" note spanning every symbol touched end-to-end. Every anchor must resolve to a real, currently-known symbol (
|
|
757
|
+
'Agent-authored narrative content anchored to one or more symbols in the workspace\'s persisted graph -- e.g. a "user story dataflow" note spanning every symbol touched end-to-end. Every anchor must resolve to a real, currently-known symbol (the workspace\'s symbol graph auto-populates in the background on first touch). get/list/tree live-check staleness against the current graph/workspace on every call and persist a correction before returning, so a returned status never disagrees with reality -- a stale annotation must be refreshed (re-authored and re-anchored) or scrubbed (soft-deleted, restorable) by an explicit decision; Lector never rewrites the narrative itself. contain/uncontain build a reusable, nestable structure on top of plain annotations: a container (e.g. a "data flow") can contain other annotations -- including per-symbol notes shared by more than one container (DRY reuse) or another container one level deeper (nested data flows) -- without duplicating their content. tree reads a whole bounded subtree in one call. Actions: create, get, list, refresh, scrub, restore, contain, uncontain, tree.',
|
|
844
758
|
promptSnippet: "Attach, read, or invalidate narrative annotations on the symbol graph",
|
|
845
759
|
promptGuidelines: [
|
|
846
|
-
"Resolve real anchor positions first (find_symbols/document_symbols/go_to_definition) -- an anchor position must match
|
|
760
|
+
"Resolve real anchor positions first (find_symbols/document_symbols/go_to_definition) -- an anchor position must match the workspace's own symbol graph's recorded position for that symbol, not just any occurrence of its name.",
|
|
847
761
|
"A stale annotation's body may no longer describe the code accurately -- read it, decide whether to refresh (re-author) or scrub (remove), never trust it as-is.",
|
|
848
762
|
"Prefer reusing an existing per-symbol annotation as a shared child of several containers over re-authoring the same explanation in each -- that reuse is the reason contain/uncontain exist.",
|
|
849
763
|
"contain/uncontain are idempotent (containing an already-contained child, or uncontaining an already-absent relationship, is a no-op, not an error) and reject a cycle up front rather than accepting one.",
|
|
@@ -1005,7 +919,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1005
919
|
name: "reachable_from",
|
|
1006
920
|
label: "Reachable From",
|
|
1007
921
|
description:
|
|
1008
|
-
"Every symbol reachable from an exact file position by following the workspace's persisted call graph up to maxDepth hops -- transitive callers/reachability that would otherwise require chaining many find_references/call_hierarchy calls by hand.
|
|
922
|
+
"Every symbol reachable from an exact file position by following the workspace's persisted call graph up to maxDepth hops -- transitive callers/reachability that would otherwise require chaining many find_references/call_hierarchy calls by hand. The workspace's symbol graph auto-populates in the background the first time this workspace is touched; if it's still building, this returns an empty result rather than an error -- wait a moment and retry.",
|
|
1009
923
|
promptSnippet: "Find symbols reachable from a position, up to N hops, via the persisted graph",
|
|
1010
924
|
promptGuidelines: [
|
|
1011
925
|
"Use reachable_from for multi-hop questions (does A eventually call C through B); use call_hierarchy (direction=incoming/outgoing) for a single direct hop live against the language server.",
|
|
@@ -1053,7 +967,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1053
967
|
name: "workspace_map",
|
|
1054
968
|
label: "Workspace Map",
|
|
1055
969
|
description:
|
|
1056
|
-
"A ranked, budget-bounded summary of the workspace's most structurally central symbols (aider-repomap-shaped) -- signature-only, highest-ranked first by PageRank over the populated call/reference graph, not full file dumps. Use when orienting in an unfamiliar or large codebase instead of reading many files one by one.
|
|
970
|
+
"A ranked, budget-bounded summary of the workspace's most structurally central symbols (aider-repomap-shaped) -- signature-only, highest-ranked first by PageRank over the populated call/reference graph, not full file dumps. Use when orienting in an unfamiliar or large codebase instead of reading many files one by one. The workspace's symbol graph auto-populates in the background the first time this workspace is touched; if it's still building, this returns empty rather than an error -- wait a moment and retry.",
|
|
1057
971
|
promptSnippet: "Get a ranked, signature-only overview of the workspace's most central symbols",
|
|
1058
972
|
promptGuidelines: [
|
|
1059
973
|
"Prefer this over reading many files to get oriented in a large or unfamiliar codebase -- it surfaces the most-referenced symbols first, not an arbitrary file order.",
|
|
@@ -1071,7 +985,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1071
985
|
const result = await codeIntelligenceOperations.workspaceMap(path, params.maxNodes, params.maxEdges, params.maxEntries, params.maxBytes);
|
|
1072
986
|
const text =
|
|
1073
987
|
result.entries.length === 0
|
|
1074
|
-
? "No ranked symbols (
|
|
988
|
+
? "No ranked symbols (the workspace's symbol graph may still be populating in the background -- retry shortly)."
|
|
1075
989
|
: result.entries
|
|
1076
990
|
.map(
|
|
1077
991
|
(entry) => `${entry.kind} ${entry.name} -- ${entry.path}:${entry.line}:${entry.character}${entry.signature ? ` -- ${entry.signature}` : ""}`,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { existsSync, statSync } from "node:fs";
|
|
2
2
|
import { dirname, extname, parse } from "node:path";
|
|
3
|
-
import { createRetryingClient, type RetryingClient } from "@danypops/daemon-kit/pi-client";
|
|
4
3
|
import {
|
|
5
4
|
connectLectorClient,
|
|
6
5
|
descriptorForExtension,
|
|
@@ -11,6 +10,7 @@ import {
|
|
|
11
10
|
remoteErrorIs,
|
|
12
11
|
type WorkspaceId,
|
|
13
12
|
} from "@danypops/lector";
|
|
13
|
+
import { createRetryingClient, type RetryingClient } from "@danypops/vehicle-client/daemon-client";
|
|
14
14
|
import { nearestGitRoot, nearestProjectRoot } from "./nearest-workspace-root.ts";
|
|
15
15
|
|
|
16
16
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danypops/pi-lector",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
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",
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"typebox": "*"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@danypops/
|
|
22
|
-
"@danypops/lector": "^0.
|
|
21
|
+
"@danypops/vehicle-client": "^0.1.1",
|
|
22
|
+
"@danypops/lector": "^0.10.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@earendil-works/pi-ai": "^0.81.1",
|