pi-lens 3.8.19 → 3.8.21
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/CHANGELOG.md +26 -0
- package/README.md +10 -7
- package/clients/dispatch/dispatcher.ts +53 -1
- package/clients/dispatch/integration.ts +37 -26
- package/clients/dispatch/plan.ts +26 -15
- package/clients/dispatch/runners/lsp.ts +6 -1
- package/clients/dispatch/runners/pyright.ts +4 -6
- package/clients/dispatch/runners/ruff.ts +52 -7
- package/clients/dispatch/runners/sqlfluff.ts +9 -3
- package/clients/dispatch/runners/yamllint.ts +3 -2
- package/clients/file-utils.ts +13 -2
- package/clients/formatters.ts +8 -4
- package/clients/installer/index.ts +371 -49
- package/clients/language-policy.ts +154 -0
- package/clients/language-profile.ts +167 -0
- package/clients/lsp/index.ts +81 -11
- package/clients/lsp/interactive-install.ts +35 -16
- package/clients/lsp/server.ts +357 -267
- package/clients/runtime-context.ts +26 -0
- package/clients/runtime-coordinator.ts +30 -2
- package/clients/runtime-session.ts +293 -103
- package/clients/runtime-tool-result.ts +8 -10
- package/clients/runtime-turn.ts +21 -4
- package/clients/todo-scanner.ts +6 -1
- package/index.ts +15 -3
- package/package.json +1 -1
package/clients/runtime-turn.ts
CHANGED
|
@@ -82,7 +82,9 @@ export async function handleTurnEnd(deps: TurnEndDeps): Promise<void> {
|
|
|
82
82
|
blockerParts.push(runtime.consumeLastCascadeOutput());
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
if (
|
|
85
|
+
if (runtime.isStartupScanInFlight("jscpd")) {
|
|
86
|
+
dbg("turn_end: skipping jscpd (startup scan still in flight)");
|
|
87
|
+
} else if (await jscpdClient.ensureAvailable()) {
|
|
86
88
|
const jscpdFiles = cacheManager.getFilesForJscpd(cwd);
|
|
87
89
|
if (jscpdFiles.length > 0) {
|
|
88
90
|
dbg(`turn_end: jscpd scanning ${jscpdFiles.length} file(s)`);
|
|
@@ -135,7 +137,7 @@ export async function handleTurnEnd(deps: TurnEndDeps): Promise<void> {
|
|
|
135
137
|
report += ` ${displayA}:${clone.startA} ↔ ${displayB}:${clone.startB} (${clone.lines} lines)\n`;
|
|
136
138
|
}
|
|
137
139
|
if (firstPath) {
|
|
138
|
-
report += `
|
|
140
|
+
report += ` First location: ${firstPath}\n`;
|
|
139
141
|
}
|
|
140
142
|
blockerParts.push(report);
|
|
141
143
|
}
|
|
@@ -143,7 +145,9 @@ export async function handleTurnEnd(deps: TurnEndDeps): Promise<void> {
|
|
|
143
145
|
}
|
|
144
146
|
}
|
|
145
147
|
|
|
146
|
-
if (
|
|
148
|
+
if (runtime.isStartupScanInFlight("knip")) {
|
|
149
|
+
dbg("turn_end: skipping knip (startup scan still in flight)");
|
|
150
|
+
} else if (await knipClient.ensureAvailable()) {
|
|
147
151
|
const knipResult = knipClient.analyze(cwd, getKnipIgnorePatterns());
|
|
148
152
|
const prevKnip = cacheManager.readCache<ReturnType<KnipClient["analyze"]>>(
|
|
149
153
|
"knip",
|
|
@@ -178,7 +182,7 @@ export async function handleTurnEnd(deps: TurnEndDeps): Promise<void> {
|
|
|
178
182
|
report += ` ${display}${issue.line ? `:${issue.line}` : ""} — ${issue.type}: ${issue.name}\n`;
|
|
179
183
|
}
|
|
180
184
|
if (firstPath) {
|
|
181
|
-
report += `
|
|
185
|
+
report += ` First location: ${firstPath}\n`;
|
|
182
186
|
}
|
|
183
187
|
blockerParts.push(report);
|
|
184
188
|
}
|
|
@@ -231,7 +235,20 @@ export async function handleTurnEnd(deps: TurnEndDeps): Promise<void> {
|
|
|
231
235
|
`turn_end: ${blockerParts.length} blocker section(s) found, persisting for next context`,
|
|
232
236
|
);
|
|
233
237
|
const content = capTurnEndMessage(blockerParts.join("\n\n"));
|
|
238
|
+
const signature = `${files.slice().sort().join("|")}::${content}`;
|
|
239
|
+
const last = cacheManager.readCache<{ signature: string }>(
|
|
240
|
+
"turn-end-findings-last",
|
|
241
|
+
cwd,
|
|
242
|
+
);
|
|
243
|
+
if (last?.data?.signature === signature) {
|
|
244
|
+
dbg("turn_end: duplicate blocker findings detected, suppressing re-prompt");
|
|
245
|
+
cacheManager.clearTurnState(cwd);
|
|
246
|
+
runtime.fixedThisTurn.clear();
|
|
247
|
+
resetFormatService();
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
234
250
|
cacheManager.writeCache("turn-end-findings", { content }, cwd);
|
|
251
|
+
cacheManager.writeCache("turn-end-findings-last", { signature }, cwd);
|
|
235
252
|
} else {
|
|
236
253
|
cacheManager.clearTurnState(cwd);
|
|
237
254
|
}
|
package/clients/todo-scanner.ts
CHANGED
|
@@ -91,7 +91,12 @@ export class TodoScanner {
|
|
|
91
91
|
const absolutePath = path.resolve(filePath);
|
|
92
92
|
if (!fs.existsSync(absolutePath)) return [];
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
let content: string;
|
|
95
|
+
try {
|
|
96
|
+
content = fs.readFileSync(absolutePath, "utf-8");
|
|
97
|
+
} catch {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
95
100
|
const lines = content.split("\n");
|
|
96
101
|
const items: TodoItem[] = [];
|
|
97
102
|
|
package/index.ts
CHANGED
|
@@ -29,7 +29,10 @@ import { captureSnapshot } from "./clients/metrics-history.js";
|
|
|
29
29
|
import { findSimilarFunctions } from "./clients/project-index.js";
|
|
30
30
|
import { RuffClient } from "./clients/ruff-client.js";
|
|
31
31
|
import { RuntimeCoordinator } from "./clients/runtime-coordinator.js";
|
|
32
|
-
import {
|
|
32
|
+
import {
|
|
33
|
+
consumeSessionStartGuidance,
|
|
34
|
+
consumeTurnEndFindings,
|
|
35
|
+
} from "./clients/runtime-context.js";
|
|
33
36
|
import { handleSessionStart } from "./clients/runtime-session.js";
|
|
34
37
|
import { handleToolResult } from "./clients/runtime-tool-result.js";
|
|
35
38
|
import { handleTurnEnd } from "./clients/runtime-turn.js";
|
|
@@ -51,10 +54,12 @@ const _getExtensionDir = () => {
|
|
|
51
54
|
return ".";
|
|
52
55
|
};
|
|
53
56
|
|
|
54
|
-
const
|
|
57
|
+
const DEBUG_LOG_DIR = path.join(os.homedir(), ".pi-lens");
|
|
58
|
+
const DEBUG_LOG = path.join(DEBUG_LOG_DIR, "sessionstart.log");
|
|
55
59
|
function dbg(msg: string) {
|
|
56
60
|
const line = `[${new Date().toISOString()}] ${msg}\n`;
|
|
57
61
|
try {
|
|
62
|
+
nodeFs.mkdirSync(DEBUG_LOG_DIR, { recursive: true });
|
|
58
63
|
nodeFs.appendFileSync(DEBUG_LOG, line);
|
|
59
64
|
} catch (e) {
|
|
60
65
|
// Pipeline error logged
|
|
@@ -733,7 +738,14 @@ pi.on("turn_end", async (_event, ctx) => {
|
|
|
733
738
|
(pi as any).on("context", async (_event: unknown, ctx: { cwd?: string }) => {
|
|
734
739
|
try {
|
|
735
740
|
const cwd = ctx.cwd ?? process.cwd();
|
|
736
|
-
|
|
741
|
+
const turnEndFindings = consumeTurnEndFindings(cacheManager, cwd);
|
|
742
|
+
const sessionGuidance = consumeSessionStartGuidance(cacheManager, cwd);
|
|
743
|
+
const messages = [
|
|
744
|
+
...(sessionGuidance?.messages ?? []),
|
|
745
|
+
...(turnEndFindings?.messages ?? []),
|
|
746
|
+
];
|
|
747
|
+
if (messages.length === 0) return;
|
|
748
|
+
return { messages };
|
|
737
749
|
} catch (err) {
|
|
738
750
|
dbg(`context event error: ${err}`);
|
|
739
751
|
}
|