@nklisch/pi-enhanced 0.2.0 → 0.2.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/CHANGELOG.md +6 -0
- package/node_modules/@nklisch/pi-background-tasks/CHANGELOG.md +7 -0
- package/node_modules/@nklisch/pi-background-tasks/extensions/background-tasks.test.ts +105 -0
- package/node_modules/@nklisch/pi-background-tasks/extensions/background-tasks.ts +131 -44
- package/node_modules/@nklisch/pi-background-tasks/package.json +1 -1
- package/node_modules/@nklisch/pi-background-tasks/skills/background-tasks/SKILL.md +6 -7
- package/node_modules/@nklisch/pi-clearance/native/clearance-core.win32-x64-msvc.node +0 -0
- package/node_modules/@nklisch/pi-clearance/package.json +1 -1
- package/node_modules/@nklisch/pi-clearance/src/config/config-command-writer.ts +34 -17
- package/node_modules/@nklisch/pi-clearance/src/index.ts +34 -3
- package/node_modules/@nklisch/pi-clearance/src/packs/package-registration.ts +63 -36
- package/node_modules/@nklisch/pi-clearance/src/runtime/allow-request-message.ts +40 -1
- package/node_modules/@nklisch/pi-clearance/src/runtime/command-registry.ts +22 -2
- package/node_modules/@nklisch/pi-clearance/src/runtime/command-transforms.ts +50 -29
- package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/native-ui.ts +233 -49
- package/node_modules/@nklisch/pi-clearance/src/runtime/policy-cache.ts +19 -5
- package/node_modules/@nklisch/pi-conveniences/extensions/context-window-footer.ts +48 -13
- package/node_modules/@nklisch/pi-conveniences/package.json +1 -1
- package/node_modules/@nklisch/pi-fff-compat/extensions/fff-compat-search.ts +49 -42
- package/node_modules/@nklisch/pi-fff-compat/extensions/finder-lifecycle.ts +92 -0
- package/node_modules/@nklisch/pi-fff-compat/package.json +1 -1
- package/node_modules/@nklisch/pi-model-modes/package.json +1 -1
- package/node_modules/@nklisch/pi-model-modes/src/command-message.ts +30 -0
- package/node_modules/@nklisch/pi-model-modes/src/commands.ts +31 -15
- package/node_modules/@nklisch/pi-model-modes/src/style-command.ts +25 -14
- package/node_modules/@nklisch/pi-plugins/README.md +2 -2
- package/node_modules/@nklisch/pi-plugins/dist/application/subagent-hook-runtime.js +4 -1
- package/node_modules/@nklisch/pi-plugins/dist/application/subagent-hook-runtime.js.map +1 -1
- package/node_modules/@nklisch/pi-plugins/dist/composition/background-update-coordinator.js +12 -3
- package/node_modules/@nklisch/pi-plugins/dist/composition/background-update-coordinator.js.map +1 -1
- package/node_modules/@nklisch/pi-plugins/dist/infrastructure/process/command-runner.d.ts +1 -0
- package/node_modules/@nklisch/pi-plugins/dist/infrastructure/process/command-runner.js +19 -11
- package/node_modules/@nklisch/pi-plugins/dist/infrastructure/process/command-runner.js.map +1 -1
- package/node_modules/@nklisch/pi-plugins/dist/pi/hooks/pi-hook-decision-adapter.js +36 -7
- package/node_modules/@nklisch/pi-plugins/dist/pi/hooks/pi-hook-decision-adapter.js.map +1 -1
- package/node_modules/@nklisch/pi-plugins/dist/pi/manager/plugin-manager-component.js +14 -3
- package/node_modules/@nklisch/pi-plugins/dist/pi/manager/plugin-manager-component.js.map +1 -1
- package/node_modules/@nklisch/pi-plugins/dist/pi/manager/plugin-manager-session.js +153 -54
- package/node_modules/@nklisch/pi-plugins/dist/pi/manager/plugin-manager-session.js.map +1 -1
- package/node_modules/@nklisch/pi-plugins/dist/pi/plugin-manager-lifecycle.js +35 -8
- package/node_modules/@nklisch/pi-plugins/dist/pi/plugin-manager-lifecycle.js.map +1 -1
- package/node_modules/@nklisch/pi-plugins/dist/runtime/mcp/pi-mcp-adapter-package.js +1 -1
- package/node_modules/@nklisch/pi-plugins/dist/runtime/mcp/pi-mcp-adapter-runtime.js +1 -1
- package/node_modules/@nklisch/pi-plugins/dist/runtime/subagents/pi-subagents-package.js +1 -1
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/CHANGELOG.md +7 -0
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/package.json +1 -1
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/config/custom-agents.ts +22 -17
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/debug.ts +18 -0
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/child-lifecycle.ts +22 -4
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/concurrency-limiter.ts +32 -8
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/create-subagent-session.ts +8 -7
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/lifecycle-interceptor.ts +25 -6
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/run-listeners.ts +6 -2
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/subagent-manager.ts +31 -16
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/subagent-session.ts +70 -32
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/subagent.ts +55 -50
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/workspace-bracket.ts +6 -2
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/observation/record-observer.ts +37 -34
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/observation/subagent-events-observer.ts +15 -14
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/foreground-runner.ts +31 -26
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/agent-widget.ts +51 -26
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/session-navigator.ts +100 -46
- package/node_modules/@nklisch/pi-plugins/package.json +3 -3
- package/package.json +3 -3
|
@@ -61,8 +61,9 @@ export function createCachingPolicyResolver(
|
|
|
61
61
|
|
|
62
62
|
return {
|
|
63
63
|
resolve: (ctx) => {
|
|
64
|
-
const registeredToolNames =
|
|
65
|
-
|
|
64
|
+
const registeredToolNames = safeRegisteredToolNames(
|
|
65
|
+
options.registeredToolNames,
|
|
66
|
+
ctx,
|
|
66
67
|
);
|
|
67
68
|
const cacheKey = cacheKeyFor(ctx.cwd, registeredToolNames);
|
|
68
69
|
const cached = cache.get(cacheKey);
|
|
@@ -185,7 +186,17 @@ async function attachNativePolicy(
|
|
|
185
186
|
}
|
|
186
187
|
|
|
187
188
|
function freeResolvedNativePolicy(result: PolicyResolverResult): void {
|
|
188
|
-
if (result.ok)
|
|
189
|
+
if (!result.ok) return;
|
|
190
|
+
try {
|
|
191
|
+
result.policy.nativePolicy?.free();
|
|
192
|
+
} catch (error) {
|
|
193
|
+
// Invalidation retires cached policies on a detached promise continuation.
|
|
194
|
+
// A native finalizer failure is operationally important but must not become
|
|
195
|
+
// an unhandled rejection that terminates Pi.
|
|
196
|
+
console.error(
|
|
197
|
+
`Pi Clearance native policy cleanup failed: ${errorMessage(error)}`,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
189
200
|
}
|
|
190
201
|
|
|
191
202
|
function composerResultToPolicyResult(
|
|
@@ -245,15 +256,18 @@ function packageRegistrationIssueWarning(
|
|
|
245
256
|
function safeRegisteredToolNames(
|
|
246
257
|
provider: ((ctx: ExtensionContext) => readonly string[]) | undefined,
|
|
247
258
|
ctx: ExtensionContext,
|
|
248
|
-
): readonly
|
|
259
|
+
): readonly string[] {
|
|
249
260
|
if (provider === undefined) {
|
|
250
261
|
return [];
|
|
251
262
|
}
|
|
252
263
|
|
|
253
264
|
try {
|
|
254
265
|
const toolNames = provider(ctx) as readonly unknown[];
|
|
255
|
-
return Array.isArray(toolNames) ? toolNames : [];
|
|
266
|
+
return Array.isArray(toolNames) ? stableToolNames(toolNames) : [];
|
|
256
267
|
} catch {
|
|
268
|
+
// The host tool catalog is an extension-owned snapshot boundary. A
|
|
269
|
+
// malformed array or throwing getter must degrade to no conditional tools,
|
|
270
|
+
// not escape before the resolver's structured failure path is attached.
|
|
257
271
|
return [];
|
|
258
272
|
}
|
|
259
273
|
}
|
|
@@ -268,9 +268,10 @@ function installFooter(ctx: ExtensionContext, pi: ExtensionAPI): void {
|
|
|
268
268
|
dispose: unsubscribe,
|
|
269
269
|
invalidate() {},
|
|
270
270
|
render(width: number): string[] {
|
|
271
|
-
|
|
271
|
+
try {
|
|
272
|
+
if (width <= 0) return [""];
|
|
272
273
|
|
|
273
|
-
|
|
274
|
+
const model = formatModelName(ctx.model?.id);
|
|
274
275
|
const modelLabel = formatModelLabel(theme, model, pi.getThinkingLevel());
|
|
275
276
|
const branch = footerData.getGitBranch();
|
|
276
277
|
const branchLabel = branch ? `git ${branch}` : "no git";
|
|
@@ -331,13 +332,21 @@ function installFooter(ctx: ExtensionContext, pi: ExtensionAPI): void {
|
|
|
331
332
|
return [formatFooterLine(width, leftCompact, rightCompact)];
|
|
332
333
|
}
|
|
333
334
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
335
|
+
return [
|
|
336
|
+
truncateToWidth(
|
|
337
|
+
[theme.fg("accent", "◆"), modelLabel, rightCompact].join(" "),
|
|
338
|
+
width,
|
|
339
|
+
"",
|
|
340
|
+
),
|
|
341
|
+
];
|
|
342
|
+
} catch (error) {
|
|
343
|
+
// Pi may request one final render while a replaced session tears its
|
|
344
|
+
// footer down. A rendering failure degrades this cosmetic surface.
|
|
345
|
+
logOperationalError(
|
|
346
|
+
`[context-window-footer] render failed: ${describeError(error)}`,
|
|
347
|
+
);
|
|
348
|
+
return [truncateToWidth("context footer unavailable", Math.max(0, width), "")];
|
|
349
|
+
}
|
|
341
350
|
},
|
|
342
351
|
};
|
|
343
352
|
});
|
|
@@ -352,6 +361,22 @@ function clearFooter(ctx: ExtensionContext): void {
|
|
|
352
361
|
footerInstalled = false;
|
|
353
362
|
}
|
|
354
363
|
|
|
364
|
+
function describeError(error: unknown): string {
|
|
365
|
+
try {
|
|
366
|
+
return error instanceof Error ? error.message : String(error);
|
|
367
|
+
} catch {
|
|
368
|
+
return "unprintable error";
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function logOperationalError(message: string): void {
|
|
373
|
+
try {
|
|
374
|
+
console.error(message);
|
|
375
|
+
} catch {
|
|
376
|
+
// stderr can be unavailable during process teardown.
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
355
380
|
function scheduleInstallFooter(ctx: ExtensionContext, pi: ExtensionAPI): void {
|
|
356
381
|
if (!ctx.hasUI || !enabled) return;
|
|
357
382
|
|
|
@@ -366,10 +391,20 @@ function scheduleInstallFooter(ctx: ExtensionContext, pi: ExtensionAPI): void {
|
|
|
366
391
|
try {
|
|
367
392
|
installFooter(ctx, pi);
|
|
368
393
|
} catch (error) {
|
|
369
|
-
//
|
|
370
|
-
//
|
|
371
|
-
|
|
372
|
-
|
|
394
|
+
// Timer callbacks run outside Pi's awaited extension boundary. A stale
|
|
395
|
+
// context is expected during replacement; every other operational
|
|
396
|
+
// failure is diagnostic, but none may escape and terminate Pi.
|
|
397
|
+
const message = describeError(error);
|
|
398
|
+
if (!message.includes("stale after session replacement")) {
|
|
399
|
+
clearPendingTimers();
|
|
400
|
+
logOperationalError(`[context-window-footer] install failed: ${message}`);
|
|
401
|
+
try {
|
|
402
|
+
ctx.ui.notify(`Context footer could not be installed: ${message}`, "error");
|
|
403
|
+
} catch (notifyError) {
|
|
404
|
+
logOperationalError(
|
|
405
|
+
`[context-window-footer] error notification failed: ${describeError(notifyError)}`,
|
|
406
|
+
);
|
|
407
|
+
}
|
|
373
408
|
}
|
|
374
409
|
}
|
|
375
410
|
}, delayMs);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nklisch/pi-conveniences",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Small drop-in quality-of-life conveniences for Pi — /exit, .agents/AGENTS.md context loading, context-window footer, and subagent model listing.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "nklisch"
|
|
@@ -26,6 +26,7 @@ import { statSync } from "node:fs";
|
|
|
26
26
|
import path from "node:path";
|
|
27
27
|
import { Type } from "@earendil-works/pi-ai";
|
|
28
28
|
import { type ExtensionAPI, type ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
29
|
+
import { createGenerationGuardedFinderLifecycle } from "./finder-lifecycle.js";
|
|
29
30
|
|
|
30
31
|
const EXTENSION_NAME = "pi-fff-compat";
|
|
31
32
|
const PACKAGE_HINT = "bundled dependency of @nklisch/pi-fff-compat";
|
|
@@ -154,9 +155,6 @@ type Truncation = {
|
|
|
154
155
|
};
|
|
155
156
|
|
|
156
157
|
let fffModulePromise: Promise<FffModule> | null = null;
|
|
157
|
-
let finder: FffFinder | null = null;
|
|
158
|
-
let finderCwd: string | null = null;
|
|
159
|
-
let finderPromise: { cwd: string; promise: Promise<FffFinder> } | null = null;
|
|
160
158
|
let activeCwd = process.cwd();
|
|
161
159
|
|
|
162
160
|
function envFlagEnabled(value: string | undefined): boolean {
|
|
@@ -195,7 +193,7 @@ function loadFffModule(): Promise<FffModule> {
|
|
|
195
193
|
if (!fffModulePromise) {
|
|
196
194
|
fffModulePromise = (async () => {
|
|
197
195
|
try {
|
|
198
|
-
return (await import("@ff-labs/fff-node")) as FffModule;
|
|
196
|
+
return (await import("@ff-labs/fff-node")) as unknown as FffModule;
|
|
199
197
|
} catch (error) {
|
|
200
198
|
throw new Error(
|
|
201
199
|
`Failed to load @ff-labs/fff-node (${PACKAGE_HINT}): ${error instanceof Error ? error.message : String(error)}`,
|
|
@@ -206,44 +204,38 @@ function loadFffModule(): Promise<FffModule> {
|
|
|
206
204
|
return fffModulePromise;
|
|
207
205
|
}
|
|
208
206
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
historyDbPath: process.env.FFF_HISTORY_DB,
|
|
222
|
-
aiMode: true,
|
|
223
|
-
enableHomeDirScanning: envFlagEnabled(process.env[HOME_SCAN_ENV]),
|
|
224
|
-
enableFsRootScanning: envFlagEnabled(process.env.FFF_ENABLE_ROOT_SCAN),
|
|
225
|
-
disableWatch: envFlagEnabled(process.env[DISABLE_WATCH_ENV]),
|
|
226
|
-
});
|
|
227
|
-
if (!created.ok) throw new Error(`Failed to create FFF finder: ${created.error}`);
|
|
228
|
-
|
|
229
|
-
finder = created.value;
|
|
230
|
-
finderCwd = cwd;
|
|
231
|
-
|
|
232
|
-
const scan = await finder.waitForScan(INITIAL_SCAN_WAIT_MS);
|
|
233
|
-
if (!scan.ok) throw new Error(`FFF scan failed: ${scan.error}`);
|
|
234
|
-
return finder;
|
|
235
|
-
})().finally(() => {
|
|
236
|
-
finderPromise = null;
|
|
237
|
-
}),
|
|
238
|
-
};
|
|
207
|
+
const finderLifecycle = createGenerationGuardedFinderLifecycle<FffFinder>(async (cwd) => {
|
|
208
|
+
const { FileFinder } = await loadFffModule();
|
|
209
|
+
const created = FileFinder.create({
|
|
210
|
+
basePath: cwd,
|
|
211
|
+
frecencyDbPath: process.env.FFF_FRECENCY_DB,
|
|
212
|
+
historyDbPath: process.env.FFF_HISTORY_DB,
|
|
213
|
+
aiMode: true,
|
|
214
|
+
enableHomeDirScanning: envFlagEnabled(process.env[HOME_SCAN_ENV]),
|
|
215
|
+
enableFsRootScanning: envFlagEnabled(process.env.FFF_ENABLE_ROOT_SCAN),
|
|
216
|
+
disableWatch: envFlagEnabled(process.env[DISABLE_WATCH_ENV]),
|
|
217
|
+
});
|
|
218
|
+
if (!created.ok) throw new Error(`Failed to create FFF finder: ${created.error}`);
|
|
239
219
|
|
|
240
|
-
|
|
241
|
-
|
|
220
|
+
const candidate = created.value;
|
|
221
|
+
try {
|
|
222
|
+
const scan = await candidate.waitForScan(INITIAL_SCAN_WAIT_MS);
|
|
223
|
+
if (!scan.ok) throw new Error(`FFF scan failed: ${scan.error}`);
|
|
224
|
+
return candidate;
|
|
225
|
+
} catch (error) {
|
|
226
|
+
if (!candidate.isDestroyed) {
|
|
227
|
+
try {
|
|
228
|
+
candidate.destroy();
|
|
229
|
+
} catch {
|
|
230
|
+
// Preserve the scan/create failure; lifecycle cleanup is best effort.
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
throw error;
|
|
234
|
+
}
|
|
235
|
+
});
|
|
242
236
|
|
|
243
|
-
function
|
|
244
|
-
|
|
245
|
-
finder = null;
|
|
246
|
-
finderCwd = null;
|
|
237
|
+
function ensureFinder(cwd: string): Promise<FffFinder> {
|
|
238
|
+
return finderLifecycle.ensure(cwd);
|
|
247
239
|
}
|
|
248
240
|
|
|
249
241
|
function truncateLine(line: string): { text: string; wasTruncated: boolean } {
|
|
@@ -408,6 +400,21 @@ const findSchema = Type.Object({
|
|
|
408
400
|
limit: Type.Optional(Type.Number({ description: `Maximum number of results (default ${DEFAULT_FIND_LIMIT})` })),
|
|
409
401
|
});
|
|
410
402
|
|
|
403
|
+
function reportInitializationFailure(ctx: ExtensionContext, error: unknown): void {
|
|
404
|
+
let detail = "unknown failure";
|
|
405
|
+
try { detail = error instanceof Error ? error.message : String(error); }
|
|
406
|
+
catch { detail = "unreadable failure"; }
|
|
407
|
+
const message = `${EXTENSION_NAME} init failed: ${detail}`;
|
|
408
|
+
try {
|
|
409
|
+
ctx.ui.notify(message, "error");
|
|
410
|
+
} catch {
|
|
411
|
+
// Initialization can settle after session replacement. The old UI is then
|
|
412
|
+
// intentionally stale, so fall back to a process diagnostic without
|
|
413
|
+
// allowing either reporting sink to escape the awaited host boundary.
|
|
414
|
+
try { console.error(message); } catch { /* no safe reporting sink remains */ }
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
411
418
|
const grepSchema = Type.Object({
|
|
412
419
|
pattern: Type.String({ description: "Search pattern" }),
|
|
413
420
|
path: Type.Optional(Type.String({ description: "Directory or file to search in (default: current directory)" })),
|
|
@@ -449,12 +456,12 @@ export default function fffCompatSearch(pi: ExtensionAPI) {
|
|
|
449
456
|
try {
|
|
450
457
|
await ensureFinder(activeCwd);
|
|
451
458
|
} catch (error) {
|
|
452
|
-
ctx
|
|
459
|
+
reportInitializationFailure(ctx, error);
|
|
453
460
|
}
|
|
454
461
|
});
|
|
455
462
|
|
|
456
463
|
pi.on("session_shutdown", async () => {
|
|
457
|
-
|
|
464
|
+
finderLifecycle.revoke();
|
|
458
465
|
});
|
|
459
466
|
|
|
460
467
|
pi.registerTool({
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export interface FinderLike {
|
|
2
|
+
readonly isDestroyed: boolean;
|
|
3
|
+
destroy(): void;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
interface CurrentFinder<F extends FinderLike> {
|
|
7
|
+
cwd: string;
|
|
8
|
+
generation: number;
|
|
9
|
+
finder: F;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface PendingFinder<F extends FinderLike> {
|
|
13
|
+
cwd: string;
|
|
14
|
+
generation: number;
|
|
15
|
+
promise: Promise<F>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Own the asynchronous finder lifecycle separately from the Pi event seam.
|
|
20
|
+
* A scan can outlive session_shutdown; the generation check prevents that late
|
|
21
|
+
* completion from becoming the finder for a replacement session.
|
|
22
|
+
*/
|
|
23
|
+
export function createGenerationGuardedFinderLifecycle<F extends FinderLike>(
|
|
24
|
+
createFinder: (cwd: string) => Promise<F>,
|
|
25
|
+
): {
|
|
26
|
+
ensure(cwd: string): Promise<F>;
|
|
27
|
+
revoke(): void;
|
|
28
|
+
} {
|
|
29
|
+
let generation = 0;
|
|
30
|
+
let current: CurrentFinder<F> | null = null;
|
|
31
|
+
let pending: PendingFinder<F> | null = null;
|
|
32
|
+
|
|
33
|
+
function destroyQuietly(candidate: F | null): void {
|
|
34
|
+
if (candidate === null || candidate.isDestroyed) return;
|
|
35
|
+
// A stale finder has no live session context in which to report a cleanup
|
|
36
|
+
// failure. Do not let best-effort shutdown cleanup reject the host event.
|
|
37
|
+
try {
|
|
38
|
+
candidate.destroy();
|
|
39
|
+
} catch {
|
|
40
|
+
// The lifecycle is already revoked; there is no safe session state to
|
|
41
|
+
// repopulate, which is the guarantee this cleanup protects.
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function revoke(): void {
|
|
46
|
+
generation++;
|
|
47
|
+
const old = current;
|
|
48
|
+
current = null;
|
|
49
|
+
destroyQuietly(old?.finder ?? null);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function ensure(cwd: string): Promise<F> {
|
|
53
|
+
if (current?.finder.isDestroyed) current = null;
|
|
54
|
+
if (current?.cwd === cwd) return Promise.resolve(current.finder);
|
|
55
|
+
if (pending?.cwd === cwd && pending.generation === generation) return pending.promise;
|
|
56
|
+
|
|
57
|
+
// A different workspace, or a new session after revocation, invalidates
|
|
58
|
+
// every earlier initialization. Its late result will be destroyed below.
|
|
59
|
+
generation++;
|
|
60
|
+
const requestedGeneration = generation;
|
|
61
|
+
const old = current;
|
|
62
|
+
current = null;
|
|
63
|
+
destroyQuietly(old?.finder ?? null);
|
|
64
|
+
|
|
65
|
+
const initialization = (async (): Promise<F> => {
|
|
66
|
+
let candidate: F | null = null;
|
|
67
|
+
try {
|
|
68
|
+
candidate = await createFinder(cwd);
|
|
69
|
+
if (requestedGeneration !== generation) {
|
|
70
|
+
throw new Error("FFF finder initialization was revoked");
|
|
71
|
+
}
|
|
72
|
+
current = { cwd, generation: requestedGeneration, finder: candidate };
|
|
73
|
+
return candidate;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
// If creation itself fails after allocating a finder, the factory owns
|
|
76
|
+
// cleanup. A completed-but-invalidated candidate is closed exactly once
|
|
77
|
+
// here, before its rejected promise reaches the old session callback.
|
|
78
|
+
if (candidate !== null && current?.finder !== candidate) destroyQuietly(candidate);
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
})();
|
|
82
|
+
|
|
83
|
+
let guardedPromise!: Promise<F>;
|
|
84
|
+
guardedPromise = initialization.finally(() => {
|
|
85
|
+
if (pending?.promise === guardedPromise) pending = null;
|
|
86
|
+
});
|
|
87
|
+
pending = { cwd, generation: requestedGeneration, promise: guardedPromise };
|
|
88
|
+
return guardedPromise;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return { ensure, revoke };
|
|
92
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nklisch/pi-fff-compat",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Fast FFF-backed file search through Pi-native find/grep semantics — glob-only file lookup and exact regex/literal grep with no fuzzy fallback.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "nklisch"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Send a display-only command panel without allowing a runtime Promise return
|
|
5
|
+
* from pi.sendMessage to become an unhandled rejection. The published type is
|
|
6
|
+
* void, but newer hosts may return a Promise while session replacement or a
|
|
7
|
+
* stale command context is being detected.
|
|
8
|
+
*/
|
|
9
|
+
export async function sendCommandMessageSafely(
|
|
10
|
+
pi: Pick<ExtensionAPI, "sendMessage">,
|
|
11
|
+
ctx: Pick<ExtensionCommandContext, "ui">,
|
|
12
|
+
message: Parameters<ExtensionAPI["sendMessage"]>[0],
|
|
13
|
+
surface: string,
|
|
14
|
+
): Promise<void> {
|
|
15
|
+
try {
|
|
16
|
+
await Promise.resolve(pi.sendMessage(message));
|
|
17
|
+
} catch (error) {
|
|
18
|
+
// The command context can be stale too, so notification is best effort.
|
|
19
|
+
// The send failure has already been consumed; neither path may escape as
|
|
20
|
+
// an unhandled rejection or replace the command's primary outcome.
|
|
21
|
+
try {
|
|
22
|
+
ctx.ui.notify(
|
|
23
|
+
`${surface}: status panel unavailable (${error instanceof Error ? error.message : String(error)})`,
|
|
24
|
+
"error",
|
|
25
|
+
);
|
|
26
|
+
} catch {
|
|
27
|
+
// A stale UI context has no safe recovery channel at this boundary.
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
} from "./autocomplete.js";
|
|
27
27
|
import { assembleForInspect, getLastBaseSystemPrompt } from "./handler.js";
|
|
28
28
|
import { parseScalarDefaultArgs } from "./command-parse-utils.js";
|
|
29
|
+
import { sendCommandMessageSafely } from "./command-message.js";
|
|
29
30
|
import {
|
|
30
31
|
writeDefaultToConfig,
|
|
31
32
|
readDefaultSources,
|
|
@@ -427,11 +428,16 @@ export function registerModeCommand(pi: ExtensionAPI): void {
|
|
|
427
428
|
modeError = (err as Error).message;
|
|
428
429
|
}
|
|
429
430
|
const presets = listPresetNames();
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
431
|
+
await sendCommandMessageSafely(
|
|
432
|
+
pi,
|
|
433
|
+
ctx,
|
|
434
|
+
{
|
|
435
|
+
customType: MODE_LISTING_MESSAGE_TYPE,
|
|
436
|
+
content: formatModeListing(source, specName, mode, modeError, presets),
|
|
437
|
+
display: true,
|
|
438
|
+
},
|
|
439
|
+
"/mode",
|
|
440
|
+
);
|
|
435
441
|
return;
|
|
436
442
|
}
|
|
437
443
|
|
|
@@ -446,11 +452,16 @@ export function registerModeCommand(pi: ExtensionAPI): void {
|
|
|
446
452
|
if (parsed.kind === "display") {
|
|
447
453
|
const sources = readDefaultSources(ctx.cwd);
|
|
448
454
|
const effective = effectiveDefaultSource(ctx.cwd);
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
455
|
+
await sendCommandMessageSafely(
|
|
456
|
+
pi,
|
|
457
|
+
ctx,
|
|
458
|
+
{
|
|
459
|
+
customType: MODE_DEFAULT_MESSAGE_TYPE,
|
|
460
|
+
content: formatDefaultListing(sources.global, sources.project, effective),
|
|
461
|
+
display: true,
|
|
462
|
+
},
|
|
463
|
+
"/mode default",
|
|
464
|
+
);
|
|
454
465
|
return;
|
|
455
466
|
}
|
|
456
467
|
|
|
@@ -622,11 +633,16 @@ export function registerModeInspectCommand(pi: ExtensionAPI): void {
|
|
|
622
633
|
styleInfo,
|
|
623
634
|
assembledPrompt,
|
|
624
635
|
);
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
636
|
+
await sendCommandMessageSafely(
|
|
637
|
+
pi,
|
|
638
|
+
ctx,
|
|
639
|
+
{
|
|
640
|
+
customType: MODE_INSPECT_MESSAGE_TYPE,
|
|
641
|
+
content,
|
|
642
|
+
display: true,
|
|
643
|
+
},
|
|
644
|
+
"/mode:inspect",
|
|
645
|
+
);
|
|
630
646
|
},
|
|
631
647
|
});
|
|
632
648
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { parseScalarDefaultArgs } from "./command-parse-utils.js";
|
|
3
|
+
import { sendCommandMessageSafely } from "./command-message.js";
|
|
3
4
|
import {
|
|
4
5
|
DEFAULT_OFF,
|
|
5
6
|
effectiveStyleDefaultSource,
|
|
@@ -166,11 +167,16 @@ export function registerStyleCommand(pi: ExtensionAPI): void {
|
|
|
166
167
|
} catch (cause) {
|
|
167
168
|
if (!("error" in effective)) effective = { error: (cause as Error).message };
|
|
168
169
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
170
|
+
await sendCommandMessageSafely(
|
|
171
|
+
pi,
|
|
172
|
+
ctx,
|
|
173
|
+
{
|
|
174
|
+
customType: STYLE_LISTING_MESSAGE_TYPE,
|
|
175
|
+
content: formatStyleListing(effective, styles),
|
|
176
|
+
display: true,
|
|
177
|
+
},
|
|
178
|
+
"/style",
|
|
179
|
+
);
|
|
174
180
|
return;
|
|
175
181
|
}
|
|
176
182
|
|
|
@@ -182,15 +188,20 @@ export function registerStyleCommand(pi: ExtensionAPI): void {
|
|
|
182
188
|
}
|
|
183
189
|
if (parsed.kind === "display") {
|
|
184
190
|
const sources = readStyleDefaultSources(ctx.cwd);
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
await sendCommandMessageSafely(
|
|
192
|
+
pi,
|
|
193
|
+
ctx,
|
|
194
|
+
{
|
|
195
|
+
customType: STYLE_DEFAULT_MESSAGE_TYPE,
|
|
196
|
+
content: formatStyleDefaultListing(
|
|
197
|
+
sources.global,
|
|
198
|
+
sources.project,
|
|
199
|
+
effectiveStyleDefaultSource(ctx.cwd),
|
|
200
|
+
),
|
|
201
|
+
display: true,
|
|
202
|
+
},
|
|
203
|
+
"/style default",
|
|
204
|
+
);
|
|
194
205
|
return;
|
|
195
206
|
}
|
|
196
207
|
|
|
@@ -61,8 +61,8 @@ Marketplace-derived network access is origin-authorized and DNS-pinned. Credenti
|
|
|
61
61
|
|
|
62
62
|
The current production package pins:
|
|
63
63
|
|
|
64
|
-
- `@nklisch/pi-mcp-adapter@2.
|
|
65
|
-
- `@nklisch/pi-subagents@18.1.0-nklisch.
|
|
64
|
+
- `@nklisch/pi-mcp-adapter@2.21.0-nklisch.1`
|
|
65
|
+
- `@nklisch/pi-subagents@18.1.0-nklisch.2`
|
|
66
66
|
|
|
67
67
|
Executable dependencies are checked against their declared package shape before import: exact name and version, license, engine and peer ranges, required exports, and declared Pi resources. The MCP and subagent packages are transitive dependencies: one top-level `pi install npm:@nklisch/pi-plugins` installs and activates both through verified wrappers, so they do not need separate `pi install` entries. The bundled subagent loader reuses Pi's already-loaded coding-agent, AI, and TUI module identities rather than installing a second Pi runtime tree. Package, API, runtime-range, or behavioral drift makes the affected capability unavailable rather than partially activating it. Subagent lifecycle conformance remains a separate qualification contract.
|
|
68
68
|
|
|
@@ -71,7 +71,10 @@ export async function registerSubagentHookRuntime(input) {
|
|
|
71
71
|
return disposePromise;
|
|
72
72
|
};
|
|
73
73
|
const onRuntimeAbort = () => {
|
|
74
|
-
|
|
74
|
+
// Abort dispatch is synchronous and detached from the caller. The explicit
|
|
75
|
+
// dispose() API still reports this failure, while shutdown must consume the
|
|
76
|
+
// rejection here so a provider cleanup error cannot become unhandled.
|
|
77
|
+
void dispose().catch(() => undefined);
|
|
75
78
|
};
|
|
76
79
|
input.runtimeSignal.addEventListener("abort", onRuntimeAbort, { once: true });
|
|
77
80
|
let evidence;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagent-hook-runtime.js","sourceRoot":"","sources":["../../src/application/subagent-hook-runtime.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"subagent-hook-runtime.js","sourceRoot":"","sources":["../../src/application/subagent-hook-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -62,11 +62,20 @@ export function createBackgroundUpdateCoordinator(dependencies) {
|
|
|
62
62
|
const ownedController = controller;
|
|
63
63
|
// Deliberately do not await this task: local startup is complete before
|
|
64
64
|
// any notification publisher, marketplace adapter, or timer participates.
|
|
65
|
-
|
|
65
|
+
// Scheduler adapters are foreign operational boundaries and may throw
|
|
66
|
+
// before returning a promise; normalize both sync throws and rejections
|
|
67
|
+
// into degraded status so detached startup can never reject into Node.
|
|
68
|
+
try {
|
|
69
|
+
task = Promise.resolve(dependencies.scheduler.run(ownedController.signal, maintain)).catch(() => {
|
|
70
|
+
if (!ownedController.signal.aborted)
|
|
71
|
+
dependencies.schedulerStatus?.degrade();
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
66
75
|
if (!ownedController.signal.aborted)
|
|
67
76
|
dependencies.schedulerStatus?.degrade();
|
|
68
|
-
|
|
69
|
-
}
|
|
77
|
+
task = Promise.resolve();
|
|
78
|
+
}
|
|
70
79
|
},
|
|
71
80
|
wake() {
|
|
72
81
|
if (closePromise === undefined)
|
package/node_modules/@nklisch/pi-plugins/dist/composition/background-update-coordinator.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"background-update-coordinator.js","sourceRoot":"","sources":["../../src/composition/background-update-coordinator.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"background-update-coordinator.js","sourceRoot":"","sources":["../../src/composition/background-update-coordinator.ts"],"names":[],"mappings":"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"}
|