privateer-agent 0.14.6 → 0.15.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.
- package/README.md +5 -5
- package/bin/headless-flags.mjs +1 -1
- package/bin/privateer-launch.mjs +33 -0
- package/bin/privateer-subagent.mjs +13 -0
- package/extensions/privateer-codemode.ts +15 -0
- package/extensions/privateer-connect.ts +21 -18
- package/extensions/privateer-web.ts +1 -1
- package/package.json +8 -9
- package/patches/{@earendil-works+pi-ai+0.86.0.patch → @earendil-works+pi-ai+1.3.0.patch} +6 -7
- package/patches/{@earendil-works+pi-coding-agent+0.86.0.patch → @earendil-works+pi-coding-agent+1.3.0.patch} +275 -184
- package/patches/{pi-background-tasks+2.5.0.patch → pi-background-tasks+2.6.10.patch} +36 -21
- package/src/bridge/engineAdapter.ts +6 -0
- package/src/config/moat.ts +51 -12
- package/src/config/moatManifest.json +3 -3
- package/src/config/whatsNew.json +4 -4
- package/src/ext/permissionGate.ts +39 -2
- package/src/harbor/closeSession.ts +1 -1
- package/src/harbor/index.ts +55 -133
- package/src/mcp/catalog.ts +10 -9
- package/src/mcp/piMcp.ts +139 -0
- package/src/mcp/toolNames.ts +39 -140
- package/src/permissions/classify.ts +42 -4
- package/src/permissions/protected.ts +7 -0
- package/src/providers/account.ts +7 -2
- package/src/remote/mcpControl.ts +189 -66
- package/src/remote/relayClient.ts +1 -1
- package/src/routines/toolSelect.ts +4 -4
- package/src/harbor/buildLock.ts +0 -19
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/config.js b/node_modules/@earendil-works/pi-coding-agent/dist/config.js
|
|
2
|
-
index
|
|
2
|
+
index 62eb303..b5e56ff 100644
|
|
3
3
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/config.js
|
|
4
4
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/config.js
|
|
5
|
-
@@ -
|
|
5
|
+
@@ -469,9 +469,72 @@ catch (e) {
|
|
6
6
|
const piConfigName = pkg.piConfig?.name;
|
|
7
7
|
export const PACKAGE_NAME = pkg.name || "@earendil-works/pi-coding-agent";
|
|
8
8
|
export const APP_NAME = piConfigName || "pi";
|
|
@@ -77,13 +77,13 @@ index 872dd55..edd61db 100644
|
|
|
77
77
|
export const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;
|
|
78
78
|
export const ENV_SESSION_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_SESSION_DIR`;
|
|
79
79
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js b/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js
|
|
80
|
-
index
|
|
80
|
+
index 11ab140..46acdfd 100644
|
|
81
81
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js
|
|
82
82
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js
|
|
83
|
-
@@ -
|
|
84
|
-
import { createAllToolDefinitions } from "./tools/index.js";
|
|
83
|
+
@@ -46,6 +46,129 @@ import { createAllToolDefinitions } from "./tools/index.js";
|
|
85
84
|
import { createToolDefinitionFromAgentTool } from "./tools/tool-definition-wrapper.js";
|
|
86
|
-
import { addUsageToTotals, createUsageTotals } from "./usage-totals.js";
|
|
85
|
+
import { addUsageToTotals, combineUsage, createUsageTotals } from "./usage-totals.js";
|
|
86
|
+
import { findLatestResponse, getBranchSelection, getVirtualModelState, isVirtualModel, VIRTUAL_MODEL_STATE_ENTRY, } from "./virtual-models.js";
|
|
87
87
|
+// ============================================================================
|
|
88
88
|
+// Privateer patch: provider errors that aren't API responses
|
|
89
89
|
+//
|
|
@@ -210,16 +210,16 @@ index 638646d..ba1da98 100644
|
|
|
210
210
|
/**
|
|
211
211
|
* Parse a skill block from message text.
|
|
212
212
|
* Returns null if the text doesn't contain a skill block.
|
|
213
|
-
@@ -
|
|
213
|
+
@@ -108,6 +231,8 @@ export class AgentSession {
|
|
214
214
|
// Retry state
|
|
215
215
|
_retryAbortController = undefined;
|
|
216
216
|
_retryAttempt = 0;
|
|
217
217
|
+ // Privateer patch: when the provider last exhausted the retry budget on a 429.
|
|
218
218
|
+ _pvThrottledAt = 0;
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
@@ -
|
|
219
|
+
/**
|
|
220
|
+
* Failed response that the next request repeats, set by auto-retry and overflow recovery. The
|
|
221
|
+
* retry is routed with it as `failed`, since the context no longer contains it.
|
|
222
|
+
@@ -240,6 +365,14 @@ export class AgentSession {
|
|
223
223
|
}
|
|
224
224
|
const isOAuth = this._modelRuntime.isUsingOAuth(model.provider);
|
|
225
225
|
if (isOAuth) {
|
|
@@ -234,7 +234,7 @@ index 638646d..ba1da98 100644
|
|
|
234
234
|
throw new Error(`Authentication failed for "${model.provider}". ` +
|
|
235
235
|
`Credentials may have expired or network is unavailable. ` +
|
|
236
236
|
`Run '/login ${model.provider}' to re-authenticate.`);
|
|
237
|
-
@@ -
|
|
237
|
+
@@ -749,6 +882,16 @@ export class AgentSession {
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
240
|
}
|
|
@@ -248,11 +248,26 @@ index 638646d..ba1da98 100644
|
|
|
248
248
|
+ typeof event.message.errorMessage === "string") {
|
|
249
249
|
+ event.message.errorMessage = compactProviderError(event.message.errorMessage);
|
|
250
250
|
+ }
|
|
251
|
-
// Emit to extensions first
|
|
251
|
+
// Emit to extensions first, then notify public listeners.
|
|
252
252
|
await this._emitExtensionEvent(event);
|
|
253
|
-
|
|
254
|
-
@@ -
|
|
255
|
-
|
|
253
|
+
this._emit(event.type === "agent_end" ? { ...event, willRetry: this._willRetryAfterAgentEnd(event) } : event);
|
|
254
|
+
@@ -1450,7 +1593,13 @@ export class AgentSession {
|
|
255
|
+
// Check if we need to compact before sending (catches aborted responses).
|
|
256
|
+
// The starting message is sent below, so do not call agent.continue() here.
|
|
257
|
+
const lastAssistant = this._findLastAssistantMessage();
|
|
258
|
+
- if (lastAssistant) {
|
|
259
|
+
+ // Privateer patch: skip this while the provider is still throttling us.
|
|
260
|
+
+ // Compaction here is another LLM call to the endpoint that just spent our
|
|
261
|
+
+ // whole retry budget on 429s; it cannot succeed, and its failure is reported
|
|
262
|
+
+ // as "Auto-compaction cancelled" — burying the user's actual prompt. One
|
|
263
|
+
+ // rate-limit window of patience, then we try again as normal. The context is
|
|
264
|
+
+ // not lost: the next turn re-checks compaction once the window has passed.
|
|
265
|
+
+ if (lastAssistant && Date.now() - this._pvThrottledAt >= PV_MAX_RETRY_DELAY_MS) {
|
|
266
|
+
await this._checkCompaction(lastAssistant, false);
|
|
267
|
+
}
|
|
268
|
+
const selectedToolsBefore = this._baseSystemPromptOptions.selectedTools;
|
|
269
|
+
@@ -1526,6 +1675,33 @@ export class AgentSession {
|
|
270
|
+
finalError: message.errorMessage,
|
|
256
271
|
});
|
|
257
272
|
this._retryAttempt = 0;
|
|
258
273
|
+ // Privateer patch: remember that the endpoint is throttling us. The
|
|
@@ -260,7 +275,7 @@ index 638646d..ba1da98 100644
|
|
|
260
275
|
+ // and firing it now just spends the summarizer budget on another 429 —
|
|
261
276
|
+ // which is what answered the user's next message with "Auto-compaction
|
|
262
277
|
+ // cancelled" instead of a reply. See the guard in prompt().
|
|
263
|
-
+ if (isThrottleFailure(
|
|
278
|
+
+ if (isThrottleFailure(message.errorMessage)) {
|
|
264
279
|
+ this._pvThrottledAt = Date.now();
|
|
265
280
|
+ }
|
|
266
281
|
+ // Privateer patch: a transient error that survived the full retry budget
|
|
@@ -280,15 +295,15 @@ index 638646d..ba1da98 100644
|
|
|
280
295
|
+ // classifies the raw HTML body as transient (it contains "500"/"502"), so the
|
|
281
296
|
+ // agent looks hung — retrying a compaction that can never succeed — until the
|
|
282
297
|
+ // summarizer budget burns. Context overflow never matches isHardHttpFailure.
|
|
283
|
-
+ if (
|
|
298
|
+
+ if (message.stopReason === "error" && isHardHttpFailure(message.errorMessage)) {
|
|
284
299
|
+ return false;
|
|
285
300
|
}
|
|
286
|
-
if (await this._checkCompaction(
|
|
301
|
+
if (await this._checkCompaction(message, true, toolResults)) {
|
|
287
302
|
return !this._agentRunAbortRequested;
|
|
288
|
-
@@ -
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
303
|
+
@@ -1655,6 +1831,14 @@ export class AgentSession {
|
|
304
|
+
if (!hasConfiguredAuth) {
|
|
305
|
+
const isOAuth = this._modelRuntime.isUsingOAuth(this.model.provider);
|
|
306
|
+
if (isOAuth) {
|
|
292
307
|
+ // Privateer patch: the account channel has no API key that could expire —
|
|
293
308
|
+ // the terminal is simply not signed in yet (a fresh install now boots on
|
|
294
309
|
+ // `privateer/*`, which is the model it will run once logged in). Stock Pi's
|
|
@@ -297,27 +312,12 @@ index 638646d..ba1da98 100644
|
|
|
297
312
|
+ if (this.model.provider === "privateer") {
|
|
298
313
|
+ throw new Error(formatNoApiKeyFoundMessage(this.model.provider));
|
|
299
314
|
+ }
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
@@ -
|
|
304
|
-
// Check if we need to compact before sending (catches aborted responses).
|
|
305
|
-
// The user's new prompt is sent below, so do not call agent.continue() here.
|
|
306
|
-
const lastAssistant = this._findLastAssistantMessage();
|
|
307
|
-
- if (lastAssistant) {
|
|
308
|
-
+ // Privateer patch: skip this while the provider is still throttling us.
|
|
309
|
-
+ // Compaction here is another LLM call to the endpoint that just spent our
|
|
310
|
-
+ // whole retry budget on 429s; it cannot succeed, and its failure is reported
|
|
311
|
-
+ // as "Auto-compaction cancelled" — burying the user's actual prompt. One
|
|
312
|
-
+ // rate-limit window of patience, then we try again as normal. The context is
|
|
313
|
-
+ // not lost: the next turn re-checks compaction once the window has passed.
|
|
314
|
-
+ if (lastAssistant && Date.now() - this._pvThrottledAt >= PV_MAX_RETRY_DELAY_MS) {
|
|
315
|
-
await this._checkCompaction(lastAssistant, false);
|
|
316
|
-
}
|
|
317
|
-
// Build messages array (custom message if any, then user message)
|
|
318
|
-
@@ -2351,6 +2535,34 @@ export class AgentSession {
|
|
315
|
+
throw new Error(`Authentication failed for "${this.model.provider}". ` +
|
|
316
|
+
`Credentials may have expired or network is unavailable. ` +
|
|
317
|
+
`Run '/login ${this.model.provider}' to re-authenticate.`);
|
|
318
|
+
@@ -3012,6 +3196,34 @@ export class AgentSession {
|
|
319
319
|
// Context overflow is handled by compaction, not retry.
|
|
320
|
-
if (isContextOverflow(message, this.model?.contextWindow ?? 0))
|
|
320
|
+
if (isContextOverflow(message, (this._modelForMessage(message) ?? this.model)?.contextWindow ?? 0))
|
|
321
321
|
return false;
|
|
322
322
|
+ // Privateer patch: an HTTP status is a fact; a substring of the body is a guess.
|
|
323
323
|
+ // pi classifies by regex over the whole error text, so a 403 whose body merely
|
|
@@ -350,7 +350,7 @@ index 638646d..ba1da98 100644
|
|
|
350
350
|
return isRetryableAssistantError(message);
|
|
351
351
|
}
|
|
352
352
|
/**
|
|
353
|
-
@@ -
|
|
353
|
+
@@ -3069,7 +3281,10 @@ export class AgentSession {
|
|
354
354
|
this._retryAttempt--;
|
|
355
355
|
return false;
|
|
356
356
|
}
|
|
@@ -408,7 +408,7 @@ index 197bccc..bc9ac3f 100644
|
|
|
408
408
|
//# sourceMappingURL=auth-guidance.js.map
|
|
409
409
|
|
|
410
410
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.js b/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.js
|
|
411
|
-
index
|
|
411
|
+
index f9292e8..07c79da 100644
|
|
412
412
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.js
|
|
413
413
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.js
|
|
414
414
|
@@ -6,7 +6,7 @@ import * as fs from "node:fs";
|
|
@@ -420,7 +420,7 @@ index be748bf..378f4c7 100644
|
|
|
420
420
|
import { resolvePath } from "../../utils/paths.js";
|
|
421
421
|
import { createEventBus } from "../event-bus.js";
|
|
422
422
|
import { execCommand } from "../exec.js";
|
|
423
|
-
@@ -
|
|
423
|
+
@@ -468,12 +468,15 @@ async function loadExtensionModule(extensionPath, cacheToken) {
|
|
424
424
|
const createJitiImpl = await getCreateJiti();
|
|
425
425
|
// Compiled binaries and the bundled Node distribution use embedded modules.
|
|
426
426
|
// Source TypeScript reuses host modules and root tsconfig paths. Unbundled
|
|
@@ -438,7 +438,7 @@ index be748bf..378f4c7 100644
|
|
|
438
438
|
const jiti = createJitiImpl(import.meta.url, {
|
|
439
439
|
moduleCache: false,
|
|
440
440
|
...resolutionOptions,
|
|
441
|
-
@@ -
|
|
441
|
+
@@ -674,9 +677,23 @@ export async function discoverAndLoadExtensions(configuredPaths, cwd, agentDir =
|
|
442
442
|
}
|
|
443
443
|
}
|
|
444
444
|
};
|
|
@@ -466,7 +466,7 @@ index be748bf..378f4c7 100644
|
|
|
466
466
|
const globalExtDir = path.join(resolvedAgentDir, "extensions");
|
|
467
467
|
addPaths(discoverExtensionsInDir(globalExtDir));
|
|
468
468
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js b/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js
|
|
469
|
-
index
|
|
469
|
+
index 4d54e22..3c59e90 100644
|
|
470
470
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js
|
|
471
471
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js
|
|
472
472
|
@@ -24,7 +24,7 @@ import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
@@ -477,8 +477,8 @@ index 696e98c..7585930 100644
|
|
|
477
477
|
+import { projectConfigDirs, projectConfigWriteDir, resolveProjectConfigPath } from "../config.js";
|
|
478
478
|
import { spawnProcess, spawnProcessSync } from "../utils/child-process.js";
|
|
479
479
|
import { parseGitUrl } from "../utils/git.js";
|
|
480
|
-
import { canonicalizePath, isLocalPath, markPathIgnoredByCloudSync, resolvePath } from "../utils/paths.js";
|
|
481
|
-
@@ -
|
|
480
|
+
import { canonicalizePath, isLocalPath, markPathIgnoredByCloudSync, normalizePath, resolvePath, } from "../utils/paths.js";
|
|
481
|
+
@@ -717,28 +717,36 @@ export class DefaultPackageManager {
|
|
482
482
|
const packageSources = this.dedupePackages(allPackages);
|
|
483
483
|
await this.resolvePackageSources(packageSources, accumulator, onMissing);
|
|
484
484
|
const globalBaseDir = this.agentDir;
|
|
@@ -512,10 +512,18 @@ index 696e98c..7585930 100644
|
|
|
512
512
|
}
|
|
513
513
|
- this.addAutoDiscoveredResources(accumulator, globalSettings, projectSettings, globalBaseDir, projectBaseDir);
|
|
514
514
|
+ this.addAutoDiscoveredResources(accumulator, globalSettings, projectSettings, globalBaseDir, projectBaseDirs);
|
|
515
|
+
// Built-in extensions are enabled unless the user `extensions` setting excludes them, for example
|
|
516
|
+
// with `-builtin:mcp`. A matching `+`, `-`, or `!` entry in the project setting overrides that.
|
|
517
|
+
+ // Privateer patch: built-in paths are not relative, so the first (preferred)
|
|
518
|
+
+ // project config dir is the base for their override patterns.
|
|
519
|
+
for (const name of this.builtinExtensions) {
|
|
520
|
+
const path = `${BUILTIN_PATH_PREFIX}${name}`;
|
|
521
|
+
- const projectEnabled = applyAutoloadDisabledPatterns([path], getOverridePatterns(projectSettings.extensions ?? []), projectBaseDir).get(path);
|
|
522
|
+
+ const projectEnabled = applyAutoloadDisabledPatterns([path], getOverridePatterns(projectSettings.extensions ?? []), projectBaseDirs[0]).get(path);
|
|
523
|
+
this.addResource(accumulator.extensions, path, { source: "builtin", scope: projectEnabled === undefined ? "user" : "project", origin: "top-level" }, projectEnabled ?? isEnabledByOverrides(path, globalSettings.extensions ?? [], globalBaseDir));
|
|
524
|
+
}
|
|
515
525
|
return this.toResolvedPaths(accumulator);
|
|
516
|
-
|
|
517
|
-
async resolveExtensionSources(sources, options) {
|
|
518
|
-
@@ -1681,13 +1687,30 @@ export class DefaultPackageManager {
|
|
526
|
+
@@ -1727,13 +1735,30 @@ export class DefaultPackageManager {
|
|
519
527
|
writeFileSync(ignorePath, "*\n!.gitignore\n", "utf-8");
|
|
520
528
|
}
|
|
521
529
|
}
|
|
@@ -547,7 +555,7 @@ index 696e98c..7585930 100644
|
|
|
547
555
|
}
|
|
548
556
|
return join(this.agentDir, "npm");
|
|
549
557
|
}
|
|
550
|
-
@@ -
|
|
558
|
+
@@ -1772,7 +1797,9 @@ export class DefaultPackageManager {
|
|
551
559
|
}
|
|
552
560
|
if (scope === "project") {
|
|
553
561
|
this.assertProjectTrustedForScope(scope);
|
|
@@ -558,7 +566,7 @@ index 696e98c..7585930 100644
|
|
|
558
566
|
}
|
|
559
567
|
return join(this.agentDir, "npm", "node_modules", source.name);
|
|
560
568
|
}
|
|
561
|
-
@@ -
|
|
569
|
+
@@ -1809,7 +1836,7 @@ export class DefaultPackageManager {
|
|
562
570
|
}
|
|
563
571
|
if (scope === "project") {
|
|
564
572
|
this.assertProjectTrustedForScope(scope);
|
|
@@ -567,7 +575,7 @@ index 696e98c..7585930 100644
|
|
|
567
575
|
}
|
|
568
576
|
return join(this.agentDir, "git");
|
|
569
577
|
}
|
|
570
|
-
@@ -
|
|
578
|
+
@@ -1832,7 +1859,7 @@ export class DefaultPackageManager {
|
|
571
579
|
getBaseDirForScope(scope) {
|
|
572
580
|
if (scope === "project") {
|
|
573
581
|
this.assertProjectTrustedForScope(scope);
|
|
@@ -576,7 +584,7 @@ index 696e98c..7585930 100644
|
|
|
576
584
|
}
|
|
577
585
|
if (scope === "user") {
|
|
578
586
|
return this.agentDir;
|
|
579
|
-
@@ -
|
|
587
|
+
@@ -1843,7 +1870,30 @@ export class DefaultPackageManager {
|
|
580
588
|
return resolvePath(input, this.cwd, { homeDir: getHomeDir(), trim: true });
|
|
581
589
|
}
|
|
582
590
|
resolvePathFromBase(input, baseDir) {
|
|
@@ -608,7 +616,7 @@ index 696e98c..7585930 100644
|
|
|
608
616
|
}
|
|
609
617
|
collectPackageResources(packageRoot, accumulator, filter, metadata) {
|
|
610
618
|
if (filter) {
|
|
611
|
-
@@ -
|
|
619
|
+
@@ -1983,19 +2033,24 @@ export class DefaultPackageManager {
|
|
612
620
|
this.addResource(target, f, metadata, enabledPaths.has(f));
|
|
613
621
|
}
|
|
614
622
|
}
|
|
@@ -637,7 +645,7 @@ index 696e98c..7585930 100644
|
|
|
637
645
|
const userOverrides = {
|
|
638
646
|
extensions: (globalSettings.extensions ?? []),
|
|
639
647
|
skills: (globalSettings.skills ?? []),
|
|
640
|
-
@@ -
|
|
648
|
+
@@ -2014,12 +2069,12 @@ export class DefaultPackageManager {
|
|
641
649
|
prompts: join(globalBaseDir, "prompts"),
|
|
642
650
|
themes: join(globalBaseDir, "themes"),
|
|
643
651
|
};
|
|
@@ -656,7 +664,7 @@ index 696e98c..7585930 100644
|
|
|
656
664
|
const userAgentsSkillsDir = join(getHomeDir(), ".agents", "skills");
|
|
657
665
|
const projectTrusted = this.settingsManager.isProjectTrusted();
|
|
658
666
|
const projectAgentsSkillDirs = projectTrusted
|
|
659
|
-
@@ -
|
|
667
|
+
@@ -2033,10 +2088,13 @@ export class DefaultPackageManager {
|
|
660
668
|
}
|
|
661
669
|
};
|
|
662
670
|
if (projectTrusted) {
|
|
@@ -674,7 +682,7 @@ index 696e98c..7585930 100644
|
|
|
674
682
|
}
|
|
675
683
|
// Project skills from .agents/ (each with its own baseDir)
|
|
676
684
|
for (const agentsSkillsDir of projectAgentsSkillDirs) {
|
|
677
|
-
@@ -
|
|
685
|
+
@@ -2048,8 +2106,11 @@ export class DefaultPackageManager {
|
|
678
686
|
addResources("skills", collectAutoSkillEntries(agentsSkillsDir, "agents"), agentsMetadata, projectOverrides.skills, agentsBaseDir);
|
|
679
687
|
}
|
|
680
688
|
if (projectTrusted) {
|
|
@@ -689,13 +697,14 @@ index 696e98c..7585930 100644
|
|
|
689
697
|
// User extensions from ~/.pi/agent/
|
|
690
698
|
addResources("extensions", collectAutoExtensionEntries(userDirs.extensions), userMetadata, userOverrides.extensions, globalBaseDir);
|
|
691
699
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/core/project-trust.js b/node_modules/@earendil-works/pi-coding-agent/dist/core/project-trust.js
|
|
692
|
-
index
|
|
700
|
+
index 0ff35ba..2bf0d59 100644
|
|
693
701
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/core/project-trust.js
|
|
694
702
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/core/project-trust.js
|
|
695
|
-
@@ -1,
|
|
703
|
+
@@ -1,9 +1,9 @@
|
|
696
704
|
-import { APP_NAME, CONFIG_DIR_NAME } from "../config.js";
|
|
697
705
|
+import { APP_NAME, formatProjectConfigDirNames } from "../config.js";
|
|
698
706
|
import { emitProjectTrustEvent } from "./extensions/runner.js";
|
|
707
|
+
import { SETTINGS_DEFAULTS } from "./settings-defaults.js";
|
|
699
708
|
import { getProjectTrustOptions, hasTrustRequiringProjectResources, } from "./trust-manager.js";
|
|
700
709
|
function formatProjectTrustPrompt(cwd) {
|
|
701
710
|
- return `Trust project folder?\n${cwd}\n\nThis allows ${APP_NAME} to load ${CONFIG_DIR_NAME} settings and resources, install missing project packages, and execute project extensions.`;
|
|
@@ -704,7 +713,7 @@ index 2f85768..328b27b 100644
|
|
|
704
713
|
async function selectProjectTrustOption(cwd, ctx) {
|
|
705
714
|
const options = getProjectTrustOptions(cwd, { includeSessionOnly: true });
|
|
706
715
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/core/prompt-templates.js b/node_modules/@earendil-works/pi-coding-agent/dist/core/prompt-templates.js
|
|
707
|
-
index
|
|
716
|
+
index c37ea83..3043d61 100644
|
|
708
717
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/core/prompt-templates.js
|
|
709
718
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/core/prompt-templates.js
|
|
710
719
|
@@ -1,6 +1,6 @@
|
|
@@ -715,9 +724,9 @@ index 3700c08..79cb85e 100644
|
|
|
715
724
|
import { parseFrontmatter } from "../utils/frontmatter.js";
|
|
716
725
|
import { resolvePath } from "../utils/paths.js";
|
|
717
726
|
import { createSyntheticSourceInfo } from "./source-info.js";
|
|
718
|
-
@@ -
|
|
719
|
-
|
|
720
|
-
|
|
727
|
+
@@ -186,7 +186,8 @@ export function loadPromptTemplates(options) {
|
|
728
|
+
diagnostics.push(...result.diagnostics);
|
|
729
|
+
};
|
|
721
730
|
const globalPromptsDir = join(resolvedAgentDir, "prompts");
|
|
722
731
|
- const projectPromptsDir = resolve(resolvedCwd, CONFIG_DIR_NAME, "prompts");
|
|
723
732
|
+ // Privateer patch: `.privateer/prompts` then `.pi/prompts`.
|
|
@@ -725,7 +734,7 @@ index 3700c08..79cb85e 100644
|
|
|
725
734
|
const isUnderPath = (target, root) => {
|
|
726
735
|
const normalizedRoot = resolve(root);
|
|
727
736
|
if (target === normalizedRoot) {
|
|
728
|
-
@@ -
|
|
737
|
+
@@ -203,7 +204,8 @@ export function loadPromptTemplates(options) {
|
|
729
738
|
baseDir: globalPromptsDir,
|
|
730
739
|
});
|
|
731
740
|
}
|
|
@@ -735,31 +744,31 @@ index 3700c08..79cb85e 100644
|
|
|
735
744
|
return createSyntheticSourceInfo(resolvedPath, {
|
|
736
745
|
source: "local",
|
|
737
746
|
scope: "project",
|
|
738
|
-
@@ -
|
|
747
|
+
@@ -217,7 +219,9 @@ export function loadPromptTemplates(options) {
|
|
739
748
|
};
|
|
740
749
|
if (includeDefaults) {
|
|
741
|
-
|
|
742
|
-
-
|
|
750
|
+
addResult(loadTemplatesFromDir(globalPromptsDir, getSourceInfo));
|
|
751
|
+
- addResult(loadTemplatesFromDir(projectPromptsDir, getSourceInfo));
|
|
743
752
|
+ for (const projectPromptsDir of projectPromptsDirs) {
|
|
744
|
-
+
|
|
753
|
+
+ addResult(loadTemplatesFromDir(projectPromptsDir, getSourceInfo));
|
|
745
754
|
+ }
|
|
746
755
|
}
|
|
747
756
|
// 3. Load explicit prompt paths
|
|
748
757
|
for (const rawPath of promptPaths) {
|
|
749
758
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.js b/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.js
|
|
750
|
-
index
|
|
759
|
+
index 563d7d5..4f669b6 100644
|
|
751
760
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.js
|
|
752
761
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.js
|
|
753
|
-
@@ -
|
|
754
|
-
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
762
|
+
@@ -2,7 +2,7 @@ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
755
763
|
import { basename, dirname, join, resolve, sep } from "node:path";
|
|
764
|
+
import { detectCapabilities, getTerminalColorMode } from "@earendil-works/pi-tui";
|
|
756
765
|
import chalk from "chalk";
|
|
757
766
|
-import { CONFIG_DIR_NAME } from "../config.js";
|
|
758
767
|
+import { findProjectConfigPath, projectConfigDirCandidates, projectConfigDirs } from "../config.js";
|
|
759
768
|
import { loadThemeFromPath } from "../modes/interactive/theme/theme.js";
|
|
760
769
|
import { canonicalizePath, isLocalPath, resolvePath } from "../utils/paths.js";
|
|
761
770
|
import { stripBom } from "../utils/text.js";
|
|
762
|
-
@@ -
|
|
771
|
+
@@ -759,12 +759,14 @@ export class DefaultResourceLoader {
|
|
763
772
|
join(this.agentDir, "themes"),
|
|
764
773
|
join(this.agentDir, "extensions"),
|
|
765
774
|
];
|
|
@@ -780,7 +789,7 @@ index c5ed4d7..d9f50ae 100644
|
|
|
780
789
|
for (const root of agentRoots) {
|
|
781
790
|
if (this.isUnderPath(normalizedPath, root)) {
|
|
782
791
|
return { path: filePath, source: "local", scope: "user", origin: "top-level", baseDir: root };
|
|
783
|
-
@@ -
|
|
792
|
+
@@ -803,7 +805,11 @@ export class DefaultResourceLoader {
|
|
784
793
|
const themes = [];
|
|
785
794
|
const diagnostics = [];
|
|
786
795
|
if (includeDefaults) {
|
|
@@ -791,9 +800,9 @@ index c5ed4d7..d9f50ae 100644
|
|
|
791
800
|
+ ...projectConfigDirs(this.cwd).map((dir) => join(dir, "themes")),
|
|
792
801
|
+ ];
|
|
793
802
|
for (const dir of defaultDirs) {
|
|
794
|
-
this.loadThemesFromDir(dir, themes, diagnostics);
|
|
803
|
+
this.loadThemesFromDir(dir, themes, diagnostics, colorMode);
|
|
795
804
|
}
|
|
796
|
-
@@ -
|
|
805
|
+
@@ -942,8 +948,9 @@ export class DefaultResourceLoader {
|
|
797
806
|
return { themes: Array.from(seen.values()), diagnostics };
|
|
798
807
|
}
|
|
799
808
|
discoverSystemPromptFile() {
|
|
@@ -805,7 +814,7 @@ index c5ed4d7..d9f50ae 100644
|
|
|
805
814
|
return projectPath;
|
|
806
815
|
}
|
|
807
816
|
const globalPath = join(this.agentDir, "SYSTEM.md");
|
|
808
|
-
@@ -
|
|
817
|
+
@@ -953,8 +960,9 @@ export class DefaultResourceLoader {
|
|
809
818
|
return undefined;
|
|
810
819
|
}
|
|
811
820
|
discoverAppendSystemPromptFile() {
|
|
@@ -818,10 +827,10 @@ index c5ed4d7..d9f50ae 100644
|
|
|
818
827
|
}
|
|
819
828
|
const globalPath = join(this.agentDir, "APPEND_SYSTEM.md");
|
|
820
829
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js b/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js
|
|
821
|
-
index
|
|
830
|
+
index d5ce9cd..a456908 100644
|
|
822
831
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js
|
|
823
832
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js
|
|
824
|
-
@@ -
|
|
833
|
+
@@ -2,7 +2,7 @@ import { randomUUID } from "crypto";
|
|
825
834
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
826
835
|
import { dirname, join } from "path";
|
|
827
836
|
import lockfile from "proper-lockfile";
|
|
@@ -830,7 +839,7 @@ index ed9d8d2..34d344c 100644
|
|
|
830
839
|
import { normalizePath, resolvePath } from "../utils/paths.js";
|
|
831
840
|
import { stripBom } from "../utils/text.js";
|
|
832
841
|
import { DEFAULT_HTTP_IDLE_TIMEOUT_MS, parseHttpIdleTimeoutMs } from "./http-dispatcher.js";
|
|
833
|
-
@@ -
|
|
842
|
+
@@ -114,14 +114,112 @@ function toSettingsError(scope, error, path) {
|
|
834
843
|
error: error instanceof Error ? error : new Error(String(error)),
|
|
835
844
|
};
|
|
836
845
|
}
|
|
@@ -944,7 +953,7 @@ index ed9d8d2..34d344c 100644
|
|
|
944
953
|
}
|
|
945
954
|
acquireLockSyncWithRetry(path) {
|
|
946
955
|
const maxAttempts = 10;
|
|
947
|
-
@@ -
|
|
956
|
+
@@ -148,7 +246,13 @@ export class FileSettingsStorage {
|
|
948
957
|
throw lastError ?? new Error("Failed to acquire settings lock");
|
|
949
958
|
}
|
|
950
959
|
withLock(scope, fn) {
|
|
@@ -959,7 +968,7 @@ index ed9d8d2..34d344c 100644
|
|
|
959
968
|
const dir = dirname(path);
|
|
960
969
|
let release;
|
|
961
970
|
try {
|
|
962
|
-
@@ -
|
|
971
|
+
@@ -226,7 +330,7 @@ export class SettingsManager {
|
|
963
972
|
const storage = new FileSettingsStorage(resolvedCwd, resolvedAgentDir);
|
|
964
973
|
return SettingsManager.fromStorageWithPaths(storage, options, {
|
|
965
974
|
global: join(resolvedAgentDir, "settings.json"),
|
|
@@ -968,7 +977,7 @@ index ed9d8d2..34d344c 100644
|
|
|
968
977
|
});
|
|
969
978
|
}
|
|
970
979
|
/** Create a SettingsManager from an arbitrary storage backend */
|
|
971
|
-
@@ -
|
|
980
|
+
@@ -723,7 +827,15 @@ export class SettingsManager {
|
|
972
981
|
getProviderRetrySettings() {
|
|
973
982
|
return {
|
|
974
983
|
timeoutMs: this.settings.retry?.provider?.timeoutMs,
|
|
@@ -982,11 +991,11 @@ index ed9d8d2..34d344c 100644
|
|
|
982
991
|
+ // 2 here is deliberately small: it is a *per-attempt* budget that nests inside
|
|
983
992
|
+ // the session retry, and each of its waits already honours the server's number.
|
|
984
993
|
+ maxRetries: this.settings.retry?.provider?.maxRetries ?? 2,
|
|
985
|
-
maxRetryDelayMs: this.settings.retry?.provider?.maxRetryDelayMs ??
|
|
994
|
+
maxRetryDelayMs: this.settings.retry?.provider?.maxRetryDelayMs ?? SETTINGS_DEFAULTS.retry.provider.maxRetryDelayMs,
|
|
986
995
|
};
|
|
987
996
|
}
|
|
988
997
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/core/skills.js b/node_modules/@earendil-works/pi-coding-agent/dist/core/skills.js
|
|
989
|
-
index
|
|
998
|
+
index 65aa0b1..51537ef 100644
|
|
990
999
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/core/skills.js
|
|
991
1000
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/core/skills.js
|
|
992
1001
|
@@ -1,7 +1,7 @@
|
|
@@ -998,7 +1007,7 @@ index d101003..540b972 100644
|
|
|
998
1007
|
import { parseFrontmatter } from "../utils/frontmatter.js";
|
|
999
1008
|
import { canonicalizePath, resolvePath } from "../utils/paths.js";
|
|
1000
1009
|
import { createSyntheticSourceInfo } from "./source-info.js";
|
|
1001
|
-
@@ -
|
|
1010
|
+
@@ -353,10 +353,15 @@ export function loadSkills(options) {
|
|
1002
1011
|
}
|
|
1003
1012
|
if (includeDefaults) {
|
|
1004
1013
|
addSkills(loadSkillsFromDirInternal(join(resolvedAgentDir, "skills"), "user", true));
|
|
@@ -1016,7 +1025,7 @@ index d101003..540b972 100644
|
|
|
1016
1025
|
const isUnderPath = (target, root) => {
|
|
1017
1026
|
const normalizedRoot = resolve(root);
|
|
1018
1027
|
if (target === normalizedRoot) {
|
|
1019
|
-
@@ -
|
|
1028
|
+
@@ -369,7 +374,7 @@ export function loadSkills(options) {
|
|
1020
1029
|
if (!includeDefaults) {
|
|
1021
1030
|
if (isUnderPath(resolvedPath, userSkillsDir))
|
|
1022
1031
|
return "user";
|
|
@@ -1026,23 +1035,23 @@ index d101003..540b972 100644
|
|
|
1026
1035
|
}
|
|
1027
1036
|
return "path";
|
|
1028
1037
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.js b/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.js
|
|
1029
|
-
index
|
|
1038
|
+
index 25cc1c5..8a90edd 100644
|
|
1030
1039
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.js
|
|
1031
1040
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.js
|
|
1032
1041
|
@@ -8,7 +8,7 @@ export const BUILTIN_SLASH_COMMANDS = [
|
|
1033
1042
|
{ name: "export", description: "Export session (HTML default, or specify path: .html/.jsonl)" },
|
|
1034
1043
|
{ name: "import", description: "Import and resume a session from a JSONL file" },
|
|
1035
|
-
{ name: "share", description: "Share session
|
|
1044
|
+
{ name: "share", description: "Share session via a Radius artifact or a GitHub gist" },
|
|
1036
1045
|
- { name: "bug", description: "Report a bug to the Pi developers", argumentHint: "<description>" },
|
|
1037
1046
|
+ { name: "bug", description: "Export a bug report to email to Privateer support", argumentHint: "<description>" },
|
|
1038
1047
|
{ name: "copy", description: "Copy last agent message to clipboard" },
|
|
1039
1048
|
{ name: "name", description: "Set session display name" },
|
|
1040
1049
|
{ name: "session", description: "Show session info and stats" },
|
|
1041
1050
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/output-accumulator.js b/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/output-accumulator.js
|
|
1042
|
-
index
|
|
1051
|
+
index 640d225..a376a21 100644
|
|
1043
1052
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/output-accumulator.js
|
|
1044
1053
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/output-accumulator.js
|
|
1045
|
-
@@ -
|
|
1054
|
+
@@ -4,6 +4,30 @@ import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, truncateTail } from "./truncate.j
|
|
1046
1055
|
function byteLength(text) {
|
|
1047
1056
|
return Buffer.byteLength(text, "utf-8");
|
|
1048
1057
|
}
|
|
@@ -1073,7 +1082,7 @@ index 7241668..7b79305 100644
|
|
|
1073
1082
|
/**
|
|
1074
1083
|
* Incrementally tracks streaming output with bounded memory.
|
|
1075
1084
|
*
|
|
1076
|
-
@@ -
|
|
1085
|
+
@@ -26,6 +50,11 @@ export class OutputAccumulator {
|
|
1077
1086
|
completedLines = 0;
|
|
1078
1087
|
totalLines = 0;
|
|
1079
1088
|
currentLineBytes = 0;
|
|
@@ -1085,7 +1094,7 @@ index 7241668..7b79305 100644
|
|
|
1085
1094
|
hasOpenLine = false;
|
|
1086
1095
|
finished = false;
|
|
1087
1096
|
tempFilePath;
|
|
1088
|
-
@@ -
|
|
1097
|
+
@@ -34,6 +63,8 @@ export class OutputAccumulator {
|
|
1089
1098
|
this.maxLines = options.maxLines ?? DEFAULT_MAX_LINES;
|
|
1090
1099
|
this.maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
1091
1100
|
this.maxRollingBytes = Math.max(this.maxBytes * 2, 1);
|
|
@@ -1094,7 +1103,7 @@ index 7241668..7b79305 100644
|
|
|
1094
1103
|
this.tempFilePrefix = options.tempFilePrefix ?? "pi-output";
|
|
1095
1104
|
}
|
|
1096
1105
|
append(data) {
|
|
1097
|
-
@@ -
|
|
1106
|
+
@@ -151,8 +182,11 @@ export class OutputAccumulator {
|
|
1098
1107
|
}
|
|
1099
1108
|
const bytes = byteLength(text);
|
|
1100
1109
|
this.totalDecodedBytes += bytes;
|
|
@@ -1108,7 +1117,7 @@ index 7241668..7b79305 100644
|
|
|
1108
1117
|
if (this.tailBytes > this.maxRollingBytes * 2) {
|
|
1109
1118
|
this.trimTail();
|
|
1110
1119
|
}
|
|
1111
|
-
@@ -
|
|
1120
|
+
@@ -174,6 +208,42 @@ export class OutputAccumulator {
|
|
1112
1121
|
}
|
|
1113
1122
|
this.totalLines = this.completedLines + (this.hasOpenLine ? 1 : 0);
|
|
1114
1123
|
}
|
|
@@ -1152,7 +1161,7 @@ index 7241668..7b79305 100644
|
|
|
1152
1161
|
const buffer = Buffer.from(this.tailText, "utf-8");
|
|
1153
1162
|
if (buffer.length <= this.maxRollingBytes) {
|
|
1154
1163
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/core/trust-manager.js b/node_modules/@earendil-works/pi-coding-agent/dist/core/trust-manager.js
|
|
1155
|
-
index
|
|
1164
|
+
index 5562460..12516b9 100644
|
|
1156
1165
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/core/trust-manager.js
|
|
1157
1166
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/core/trust-manager.js
|
|
1158
1167
|
@@ -2,7 +2,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
@@ -1164,7 +1173,7 @@ index 0877ee7..faa2559 100644
|
|
|
1164
1173
|
import { canonicalizePath, resolvePath } from "../utils/paths.js";
|
|
1165
1174
|
import { stripBom } from "../utils/text.js";
|
|
1166
1175
|
const TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES = [
|
|
1167
|
-
@@ -
|
|
1176
|
+
@@ -152,9 +152,13 @@ export function hasTrustRequiringProjectResources(cwd) {
|
|
1168
1177
|
const homeDir = canonicalizePath(resolvePath(process.env.HOME || homedir()));
|
|
1169
1178
|
const userAgentsSkillsDir = join(homeDir, ".agents", "skills");
|
|
1170
1179
|
let currentDir = canonicalizePath(resolvePath(cwd));
|
|
@@ -1181,8 +1190,24 @@ index 0877ee7..faa2559 100644
|
|
|
1181
1190
|
}
|
|
1182
1191
|
while (true) {
|
|
1183
1192
|
const agentsSkillsDir = join(currentDir, ".agents", "skills");
|
|
1193
|
+
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/extensions/mcp/cli.js b/node_modules/@earendil-works/pi-coding-agent/dist/extensions/mcp/cli.js
|
|
1194
|
+
index 8f0d990..8c7931f 100644
|
|
1195
|
+
--- a/node_modules/@earendil-works/pi-coding-agent/dist/extensions/mcp/cli.js
|
|
1196
|
+
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/extensions/mcp/cli.js
|
|
1197
|
+
@@ -8,7 +8,10 @@ import { existsSync } from "node:fs";
|
|
1198
|
+
import { join } from "node:path";
|
|
1199
|
+
import { createInterface } from "node:readline/promises";
|
|
1200
|
+
import chalk from "chalk";
|
|
1201
|
+
-import { APP_NAME, CONFIG_DIR_NAME } from "../../config.js";
|
|
1202
|
+
+import { APP_NAME as PI_APP_NAME, CONFIG_DIR_NAME } from "../../config.js";
|
|
1203
|
+
+// Privateer patch: the commands this prints are ones the user types, so they name the
|
|
1204
|
+
+// command the user actually ran (`privateer`, set by the launcher), not Pi's.
|
|
1205
|
+
+const APP_NAME = process.env.PRIVATEER_CMD || PI_APP_NAME;
|
|
1206
|
+
import { validateMcpServerConfig } from "../../core/mcp-servers.js";
|
|
1207
|
+
import { ProjectTrustStore } from "../../core/trust-manager.js";
|
|
1208
|
+
import { openBrowser } from "../../utils/open-browser.js";
|
|
1184
1209
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/index.d.ts b/node_modules/@earendil-works/pi-coding-agent/dist/index.d.ts
|
|
1185
|
-
index
|
|
1210
|
+
index 3821d9f..b58133c 100644
|
|
1186
1211
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/index.d.ts
|
|
1187
1212
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/index.d.ts
|
|
1188
1213
|
@@ -1,7 +1,7 @@
|
|
@@ -1195,7 +1220,7 @@ index 205144d..14080a2 100644
|
|
|
1195
1220
|
export { type BranchPreparation, type BranchSummaryResult, type CollectEntriesResult, type CompactionResult, type CutPointResult, calculateContextTokens, collectEntriesForBranchSummary, compact, DEFAULT_COMPACTION_SETTINGS, estimateTokens, type FileOperations, findCutPoint, findTurnStartIndex, type GenerateBranchSummaryOptions, generateBranchSummary, generateSummary, generateSummaryWithUsage, getLastAssistantUsage, prepareBranchEntries, serializeConversation, shouldCompact, } from "./core/compaction/index.ts";
|
|
1196
1221
|
export { createEventBus, type EventBus, type EventBusController } from "./core/event-bus.ts";
|
|
1197
1222
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/index.js b/node_modules/@earendil-works/pi-coding-agent/dist/index.js
|
|
1198
|
-
index
|
|
1223
|
+
index ab5cfcc..09fb05b 100644
|
|
1199
1224
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/index.js
|
|
1200
1225
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/index.js
|
|
1201
1226
|
@@ -3,7 +3,7 @@ export { parseArgs } from "./cli/args.js";
|
|
@@ -1208,10 +1233,10 @@ index 01017cd..c2b8722 100644
|
|
|
1208
1233
|
export { calculateContextTokens, collectEntriesForBranchSummary, compact, DEFAULT_COMPACTION_SETTINGS, estimateTokens, findCutPoint, findTurnStartIndex, generateBranchSummary, generateSummary, generateSummaryWithUsage, getLastAssistantUsage, prepareBranchEntries, serializeConversation, shouldCompact, } from "./core/compaction/index.js";
|
|
1209
1234
|
export { createEventBus } from "./core/event-bus.js";
|
|
1210
1235
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/main.js b/node_modules/@earendil-works/pi-coding-agent/dist/main.js
|
|
1211
|
-
index
|
|
1236
|
+
index e4fb658..8af5e0d 100644
|
|
1212
1237
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/main.js
|
|
1213
1238
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/main.js
|
|
1214
|
-
@@ -
|
|
1239
|
+
@@ -821,7 +821,58 @@ export async function main(args, options) {
|
|
1215
1240
|
if (exitCode !== 0) {
|
|
1216
1241
|
process.exitCode = exitCode;
|
|
1217
1242
|
}
|
|
@@ -1306,10 +1331,10 @@ index c30d6b8..ad1654a 100644
|
|
|
1306
1331
|
return warnings;
|
|
1307
1332
|
}
|
|
1308
1333
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/bug-report.d.ts b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/bug-report.d.ts
|
|
1309
|
-
index
|
|
1334
|
+
index d7b6c7b..10af81f 100644
|
|
1310
1335
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/bug-report.d.ts
|
|
1311
1336
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/bug-report.d.ts
|
|
1312
|
-
@@ -
|
|
1337
|
+
@@ -10,7 +10,7 @@ interface BugReportContext {
|
|
1313
1338
|
showStatus: (message: string) => void;
|
|
1314
1339
|
showError: (message: string) => void;
|
|
1315
1340
|
}
|
|
@@ -1320,10 +1345,10 @@ index 7eae594..b21fae3 100644
|
|
|
1320
1345
|
//# sourceMappingURL=bug-report.d.ts.map
|
|
1321
1346
|
|
|
1322
1347
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/bug-report.js b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/bug-report.js
|
|
1323
|
-
index
|
|
1348
|
+
index 3918684..42db58d 100644
|
|
1324
1349
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/bug-report.js
|
|
1325
1350
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/bug-report.js
|
|
1326
|
-
@@ -1,
|
|
1351
|
+
@@ -1,28 +1,27 @@
|
|
1327
1352
|
import * as path from "node:path";
|
|
1328
1353
|
-import { getAuthCredential } from "../../cli/auth-command.js";
|
|
1329
1354
|
import { BUG_REPORT_CUSTOM_ENTRY_TYPE, bugReportArchiveFileName, collectBugReportDiagnostics, collectBugReportMetadata, writeBugReportArchive, } from "../../core/bug-report.js";
|
|
@@ -1332,7 +1357,7 @@ index 59ae447..68cf842 100644
|
|
|
1332
1357
|
-import { getRadiusGatewayUrl, RADIUS_PROVIDER_ID } from "../../core/radius.js";
|
|
1333
1358
|
import { serializeSessionBranch } from "../../core/session-export.js";
|
|
1334
1359
|
import { BorderedLoader } from "./components/bordered-loader.js";
|
|
1335
|
-
import {
|
|
1360
|
+
import { ExtensionEditorComponent } from "./components/extension-editor.js";
|
|
1336
1361
|
import { ExtensionSelectorComponent } from "./components/extension-selector.js";
|
|
1337
1362
|
import { createShareTrailingEntries } from "./session-share.js";
|
|
1338
1363
|
import { theme } from "./theme/theme.js";
|
|
@@ -1350,7 +1375,17 @@ index 59ae447..68cf842 100644
|
|
|
1350
1375
|
export async function reportBug(context, initialHint) {
|
|
1351
1376
|
const options = await promptForOptions(context, initialHint);
|
|
1352
1377
|
if (!options) {
|
|
1353
|
-
|
|
1378
|
+
context.showStatus("Bug report cancelled");
|
|
1379
|
+
return;
|
|
1380
|
+
}
|
|
1381
|
+
- if (options.delivery === "upload" && process.env.PI_OFFLINE) {
|
|
1382
|
+
- context.showError("Uploading bug reports requires online mode. Use Export as Zip instead.");
|
|
1383
|
+
- return;
|
|
1384
|
+
- }
|
|
1385
|
+
let summary;
|
|
1386
|
+
if (options.includeSummary) {
|
|
1387
|
+
const loader = showLoader(context, `Writing summary with ${context.session.model?.name ?? "the current model"}...`);
|
|
1388
|
+
@@ -51,16 +50,6 @@ export async function reportBug(context, initialHint) {
|
|
1354
1389
|
context.showError(`Failed to build bug report: ${errorMessage(error)}`);
|
|
1355
1390
|
return;
|
|
1356
1391
|
}
|
|
@@ -1367,7 +1402,7 @@ index 59ae447..68cf842 100644
|
|
|
1367
1402
|
await exportZip(context, bundle);
|
|
1368
1403
|
}
|
|
1369
1404
|
async function promptForOptions(context, initialHint) {
|
|
1370
|
-
@@ -
|
|
1405
|
+
@@ -80,14 +69,13 @@ async function promptForOptions(context, initialHint) {
|
|
1371
1406
|
includeSummary = summary !== "No";
|
|
1372
1407
|
}
|
|
1373
1408
|
const description = hint.trim();
|
|
@@ -1384,7 +1419,7 @@ index 59ae447..68cf842 100644
|
|
|
1384
1419
|
};
|
|
1385
1420
|
}
|
|
1386
1421
|
function buildBundle(session, options, summary) {
|
|
1387
|
-
@@ -
|
|
1422
|
+
@@ -115,28 +103,6 @@ function buildBundle(session, options, summary) {
|
|
1388
1423
|
: undefined,
|
|
1389
1424
|
};
|
|
1390
1425
|
}
|
|
@@ -1413,7 +1448,7 @@ index 59ae447..68cf842 100644
|
|
|
1413
1448
|
async function exportZip(context, bundle) {
|
|
1414
1449
|
const archivePath = path.join(process.cwd(), bugReportArchiveFileName(bundle.metadata.id));
|
|
1415
1450
|
try {
|
|
1416
|
-
@@ -
|
|
1451
|
+
@@ -147,7 +113,7 @@ async function exportZip(context, bundle) {
|
|
1417
1452
|
return;
|
|
1418
1453
|
}
|
|
1419
1454
|
recordInSession(context.session, bundle, { delivery: "zip", path: archivePath });
|
|
@@ -1423,7 +1458,7 @@ index 59ae447..68cf842 100644
|
|
|
1423
1458
|
function recordInSession(session, bundle, delivery) {
|
|
1424
1459
|
session.sessionManager.appendCustomEntry(BUG_REPORT_CUSTOM_ENTRY_TYPE, {
|
|
1425
1460
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.js b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.js
|
|
1426
|
-
index
|
|
1461
|
+
index 3825648..9bd656b 100644
|
|
1427
1462
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.js
|
|
1428
1463
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.js
|
|
1429
1464
|
@@ -4,7 +4,7 @@
|
|
@@ -1432,10 +1467,10 @@ index 6f7ed6a..b0ed0ae 100644
|
|
|
1432
1467
|
import { Container, getKeybindings, Input, matchesKey, Spacer, truncateToWidth, visibleWidth, } from "@earendil-works/pi-tui";
|
|
1433
1468
|
-import { CONFIG_DIR_NAME } from "../../../config.js";
|
|
1434
1469
|
+import { CONFIG_DIR_NAME, PROJECT_CONFIG_DIR_NAMES, formatProjectConfigDirNames, projectConfigDirs, projectConfigWriteDir } from "../../../config.js";
|
|
1470
|
+
import { BUILTIN_PATH_PREFIX } from "../../../core/source-info.js";
|
|
1435
1471
|
import { canonicalizePath, isLocalPath, resolvePath } from "../../../utils/paths.js";
|
|
1436
1472
|
import { theme } from "../theme/theme.js";
|
|
1437
|
-
|
|
1438
|
-
@@ -43,7 +43,7 @@ function getGroupLabel(metadata, agentDir) {
|
|
1473
|
+
@@ -47,7 +47,7 @@ function getGroupLabel(metadata, agentDir) {
|
|
1439
1474
|
? `User (${formatBaseDir(metadata.baseDir)})`
|
|
1440
1475
|
: `Project (${formatBaseDir(metadata.baseDir)})`;
|
|
1441
1476
|
}
|
|
@@ -1444,7 +1479,7 @@ index 6f7ed6a..b0ed0ae 100644
|
|
|
1444
1479
|
}
|
|
1445
1480
|
return metadata.scope === "user" ? "User settings" : "Project settings";
|
|
1446
1481
|
}
|
|
1447
|
-
@@ -
|
|
1482
|
+
@@ -148,7 +148,7 @@ class ConfigSelectorHeader {
|
|
1448
1483
|
const hint = switchHint + actionHint + sep + rawKeyHint("esc", "close");
|
|
1449
1484
|
const spacing = Math.max(1, width - visibleWidth(title) - visibleWidth(hint));
|
|
1450
1485
|
const scopeHint = this.writeScope === "project"
|
|
@@ -1453,7 +1488,7 @@ index 6f7ed6a..b0ed0ae 100644
|
|
|
1453
1488
|
: theme.fg("muted", `~/${CONFIG_DIR_NAME}/agent/settings.json`);
|
|
1454
1489
|
return [
|
|
1455
1490
|
truncateToWidth(`${title}${" ".repeat(spacing)}${hint}`, width, ""),
|
|
1456
|
-
@@ -
|
|
1491
|
+
@@ -703,7 +703,12 @@ class ResourceList {
|
|
1457
1492
|
return item.metadata.scope === "project" ? "project" : "user";
|
|
1458
1493
|
}
|
|
1459
1494
|
getTopLevelBaseDir(scope) {
|
|
@@ -1466,9 +1501,9 @@ index 6f7ed6a..b0ed0ae 100644
|
|
|
1466
1501
|
+ return projectConfigDirs(this.cwd)[0] ?? projectConfigWriteDir(this.cwd);
|
|
1467
1502
|
}
|
|
1468
1503
|
getResourcePattern(item) {
|
|
1469
|
-
|
|
1504
|
+
if (item.metadata.source === "builtin")
|
|
1470
1505
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/footer.js b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/footer.js
|
|
1471
|
-
index
|
|
1506
|
+
index cf40733..c31e867 100644
|
|
1472
1507
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/footer.js
|
|
1473
1508
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/footer.js
|
|
1474
1509
|
@@ -1,7 +1,6 @@
|
|
@@ -1524,7 +1559,7 @@ index 0e2811e..c0326e3 100644
|
|
|
1524
1559
|
/**
|
|
1525
1560
|
* Format token counts for compact footer display.
|
|
1526
1561
|
*/
|
|
1527
|
-
@@ -41,
|
|
1562
|
+
@@ -41,14 +77,16 @@ export function formatCwdForFooter(cwd, home) {
|
|
1528
1563
|
return relativeToHome === "" ? "~" : `~${sep}${relativeToHome}`;
|
|
1529
1564
|
}
|
|
1530
1565
|
/**
|
|
@@ -1538,14 +1573,40 @@ index 0e2811e..c0326e3 100644
|
|
|
1538
1573
|
*/
|
|
1539
1574
|
export class FooterComponent {
|
|
1540
1575
|
autoCompactEnabled = true;
|
|
1541
|
-
|
|
1576
|
+
session;
|
|
1577
|
+
footerData;
|
|
1578
|
+
- sessionStats;
|
|
1579
|
+
constructor(session, footerData) {
|
|
1580
|
+
this.session = session;
|
|
1581
|
+
this.footerData = footerData;
|
|
1582
|
+
@@ -73,67 +111,10 @@ export class FooterComponent {
|
|
1583
|
+
dispose() {
|
|
1584
|
+
// Git watcher cleanup handled by provider
|
|
1542
1585
|
}
|
|
1543
|
-
|
|
1544
|
-
|
|
1586
|
+
- /**
|
|
1587
|
+
- * Usage totals and context usage scan the whole session, and the footer renders on every frame.
|
|
1588
|
+
- * Entries are append-only and every append moves the leaf, so the results only change with the
|
|
1589
|
+
- * session, leaf, entry count, or the model whose context window applies.
|
|
1590
|
+
- */
|
|
1591
|
+
- getSessionStats() {
|
|
1592
|
+
- const sessionManager = this.session.sessionManager;
|
|
1593
|
+
- const entryCount = sessionManager.getEntryCount();
|
|
1594
|
+
- const sessionId = sessionManager.getSessionId();
|
|
1595
|
+
- const leafId = sessionManager.getLeafId();
|
|
1596
|
+
- const limitsModel = this.session.routedModel?.model ?? this.session.model;
|
|
1597
|
+
- const cached = this.sessionStats;
|
|
1598
|
+
- if (cached &&
|
|
1599
|
+
- cached.session === this.session &&
|
|
1600
|
+
- cached.sessionId === sessionId &&
|
|
1601
|
+
- cached.leafId === leafId &&
|
|
1602
|
+
- cached.entryCount === entryCount &&
|
|
1603
|
+
- cached.limitsModel === limitsModel) {
|
|
1604
|
+
- return cached;
|
|
1605
|
+
- }
|
|
1545
1606
|
- // Calculate cumulative usage from ALL session entries (not just post-compaction messages)
|
|
1546
1607
|
- const usageTotals = createUsageTotals();
|
|
1547
1608
|
- let latestCacheHitRate;
|
|
1548
|
-
- for (const entry of
|
|
1609
|
+
- for (const entry of sessionManager.getEntries()) {
|
|
1549
1610
|
- if (entry.type === "usage") {
|
|
1550
1611
|
- addUsageToTotals(usageTotals, entry.usage);
|
|
1551
1612
|
- }
|
|
@@ -1565,16 +1626,30 @@ index 0e2811e..c0326e3 100644
|
|
|
1565
1626
|
- // Calculate context usage from session (handles compaction correctly).
|
|
1566
1627
|
- // After compaction, tokens are unknown until the next LLM response.
|
|
1567
1628
|
- const contextUsage = this.session.getContextUsage();
|
|
1629
|
+
- this.sessionStats = {
|
|
1630
|
+
- session: this.session,
|
|
1631
|
+
- sessionId,
|
|
1632
|
+
- leafId,
|
|
1633
|
+
- entryCount,
|
|
1634
|
+
- limitsModel,
|
|
1635
|
+
- usageTotals,
|
|
1636
|
+
- latestCacheHitRate,
|
|
1637
|
+
- contextUsage,
|
|
1638
|
+
- };
|
|
1639
|
+
- return this.sessionStats;
|
|
1640
|
+
- }
|
|
1641
|
+
render(width) {
|
|
1642
|
+
const state = this.session.state;
|
|
1643
|
+
- const { usageTotals, latestCacheHitRate, contextUsage } = this.getSessionStats();
|
|
1568
1644
|
- const contextWindow = contextUsage?.contextWindow ?? state.model?.contextWindow ?? 0;
|
|
1569
1645
|
- const contextPercentValue = contextUsage?.percent ?? 0;
|
|
1570
1646
|
- const contextPercent = contextUsage?.percent !== null ? contextPercentValue.toFixed(1) : "?";
|
|
1571
1647
|
+ // Privateer: no token counters, cache-hit rate, cost or context gauge in the
|
|
1572
|
-
+ // footer — so
|
|
1573
|
-
+ // session entry on EVERY render to build numbers we no longer draw.
|
|
1648
|
+
+ // footer — so upstream's getSessionStats() scan that fed them is gone too.
|
|
1574
1649
|
// Replace home directory with ~
|
|
1575
1650
|
let pwd = formatCwdForFooter(this.session.sessionManager.getCwd(), process.env.HOME || process.env.USERPROFILE);
|
|
1576
1651
|
// Add git branch if available
|
|
1577
|
-
@@ -
|
|
1652
|
+
@@ -146,56 +127,24 @@ export class FooterComponent {
|
|
1578
1653
|
if (sessionName) {
|
|
1579
1654
|
pwd = `${pwd} • ${sessionName}`;
|
|
1580
1655
|
}
|
|
@@ -1646,7 +1721,7 @@ index 0e2811e..c0326e3 100644
|
|
|
1646
1721
|
const minPadding = 2;
|
|
1647
1722
|
// Add thinking level indicator if model supports reasoning
|
|
1648
1723
|
let rightSideWithoutProvider = modelName;
|
|
1649
|
-
@@ -
|
|
1724
|
+
@@ -214,50 +163,48 @@ export class FooterComponent {
|
|
1650
1725
|
let rightSide = rightSideWithoutProvider;
|
|
1651
1726
|
if (this.footerData.getAvailableProviderCount() > 1 && state.model) {
|
|
1652
1727
|
rightSide = `(${state.model.provider}) ${rightSideWithoutProvider}`;
|
|
@@ -1716,14 +1791,14 @@ index 0e2811e..c0326e3 100644
|
|
|
1716
1791
|
return lines;
|
|
1717
1792
|
}
|
|
1718
1793
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tool-execution.js b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tool-execution.js
|
|
1719
|
-
index
|
|
1794
|
+
index d447db5..8f7de42 100644
|
|
1720
1795
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tool-execution.js
|
|
1721
1796
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tool-execution.js
|
|
1722
1797
|
@@ -1,9 +1,36 @@
|
|
1723
1798
|
-import { Box, Container, getCapabilities, Image, MouseRegion, Spacer, Text, } from "@earendil-works/pi-tui";
|
|
1724
1799
|
+import { Box, Container, getCapabilities, Image, MouseRegion, Spacer, visibleWidth, Text, } from "@earendil-works/pi-tui";
|
|
1725
|
-
import { getTextOutput as getRenderedTextOutput } from "../../../core/tools/render-utils.js";
|
|
1726
|
-
import {
|
|
1800
|
+
import { formatToolCallWithArgs, getTextOutput as getRenderedTextOutput } from "../../../core/tools/render-utils.js";
|
|
1801
|
+
import { ensurePngTranscoder } from "../../../utils/image-convert.js";
|
|
1727
1802
|
import { theme } from "../theme/theme.js";
|
|
1728
1803
|
import { keyHint } from "./keybinding-hints.js";
|
|
1729
1804
|
const FALLBACK_PREVIEW_LINES = 10;
|
|
@@ -1757,7 +1832,7 @@ index 6d0356c..ca0aa98 100644
|
|
|
1757
1832
|
export class ToolExecutionComponent extends Container {
|
|
1758
1833
|
contentBox;
|
|
1759
1834
|
contentText;
|
|
1760
|
-
@@ -
|
|
1835
|
+
@@ -47,8 +74,13 @@ export class ToolExecutionComponent extends Container {
|
|
1761
1836
|
// Always create all shell variants. contentBox is used for default renderer-based composition.
|
|
1762
1837
|
// selfRenderContainer is used when the tool renders its own framing.
|
|
1763
1838
|
// contentText is reserved for generic fallback rendering when no tool definition exists.
|
|
@@ -1773,9 +1848,9 @@ index 6d0356c..ca0aa98 100644
|
|
|
1773
1848
|
this.contentTextRegion = this.createResultRegion(this.contentText);
|
|
1774
1849
|
this.selfRenderContainer = new Container();
|
|
1775
1850
|
if (this.hasRendererDefinition()) {
|
|
1776
|
-
@@ -
|
|
1851
|
+
@@ -95,6 +127,13 @@ export class ToolExecutionComponent extends Container {
|
|
1777
1852
|
createCallFallback() {
|
|
1778
|
-
return new Text(
|
|
1853
|
+
return new Text(formatToolCallWithArgs(this.toolName, this.args, theme, this.expanded), 0, 0);
|
|
1779
1854
|
}
|
|
1780
1855
|
+ /** Privateer: red-flag a failed call, pass a pending/succeeded one straight through. */
|
|
1781
1856
|
+ decorateCall(component) {
|
|
@@ -1787,7 +1862,7 @@ index 6d0356c..ca0aa98 100644
|
|
|
1787
1862
|
createResultFallback() {
|
|
1788
1863
|
const output = this.getTextOutput();
|
|
1789
1864
|
if (!output) {
|
|
1790
|
-
@@ -
|
|
1865
|
+
@@ -213,19 +252,22 @@ export class ToolExecutionComponent extends Container {
|
|
1791
1866
|
renderContainer.clear();
|
|
1792
1867
|
const callRenderer = this.getCallRenderer();
|
|
1793
1868
|
if (!callRenderer) {
|
|
@@ -1813,7 +1888,7 @@ index 6d0356c..ca0aa98 100644
|
|
|
1813
1888
|
hasContent = true;
|
|
1814
1889
|
}
|
|
1815
1890
|
}
|
|
1816
|
-
@@ -
|
|
1891
|
+
@@ -309,7 +351,8 @@ export class ToolExecutionComponent extends Container {
|
|
1817
1892
|
return getRenderedTextOutput(this.result, this.showImages);
|
|
1818
1893
|
}
|
|
1819
1894
|
formatToolExecution() {
|
|
@@ -1824,19 +1899,19 @@ index 6d0356c..ca0aa98 100644
|
|
|
1824
1899
|
if (content) {
|
|
1825
1900
|
text += `\n\n${content}`;
|
|
1826
1901
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js
|
|
1827
|
-
index
|
|
1902
|
+
index d2343a5..8487713 100644
|
|
1828
1903
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js
|
|
1829
1904
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js
|
|
1830
|
-
@@ -
|
|
1905
|
+
@@ -11,7 +11,7 @@ import * as TuiLayouts from "@earendil-works/pi-tui";
|
|
1831
1906
|
import { CombinedAutocompleteProvider, Container, fuzzyFilter, getCapabilities, hyperlink, Markdown, matchesKey, Spacer, setCapabilityOverrides, setKeybindings, Text, TruncatedText, TuiAltScreen, TuiMainScreen, visibleWidth, } from "@earendil-works/pi-tui";
|
|
1832
1907
|
import chalk from "chalk";
|
|
1833
1908
|
import { spawn } from "child_process";
|
|
1834
|
-
-import { APP_NAME, APP_TITLE, CONFIG_DIR_NAME, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, VERSION, } from "../../config.js";
|
|
1835
|
-
+import { APP_NAME, APP_TITLE, formatProjectConfigDirNames, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, VERSION, } from "../../config.js";
|
|
1909
|
+
-import { APP_NAME, APP_TITLE, CONFIG_DIR_NAME, detectInstallChange, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, VERSION, } from "../../config.js";
|
|
1910
|
+
+import { APP_NAME, APP_TITLE, detectInstallChange, formatProjectConfigDirNames, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, VERSION, } from "../../config.js";
|
|
1836
1911
|
import { parseSkillBlock } from "../../core/agent-session.js";
|
|
1837
1912
|
import { SessionImportFileNotFoundError } from "../../core/agent-session-runtime.js";
|
|
1838
1913
|
import { CACHE_TTL_MS, collectCacheMisses, computeCacheWaste, detectCacheMiss, } from "../../core/cache-stats.js";
|
|
1839
|
-
@@ -
|
|
1914
|
+
@@ -177,7 +177,12 @@ export function formatResumeCommand(sessionManager) {
|
|
1840
1915
|
const sessionFile = sessionManager.getSessionFile();
|
|
1841
1916
|
if (!sessionFile || !fs.existsSync(sessionFile))
|
|
1842
1917
|
return undefined;
|
|
@@ -1850,8 +1925,8 @@ index d82182c..08bec2d 100644
|
|
|
1850
1925
|
if (!sessionManager.usesDefaultSessionDir()) {
|
|
1851
1926
|
args.push("--session-dir", quoteIfNeeded(sessionManager.getSessionDir()));
|
|
1852
1927
|
}
|
|
1853
|
-
@@ -
|
|
1854
|
-
|
|
1928
|
+
@@ -232,6 +237,77 @@ function formatLoginProviderCompletionDescription(provider) {
|
|
1929
|
+
.join("/");
|
|
1855
1930
|
return provider.name === provider.id ? authTypes : `${provider.name} · ${authTypes}`;
|
|
1856
1931
|
}
|
|
1857
1932
|
+// Privateer patch: describe an error we only have the TEXT of. Mirrors
|
|
@@ -1928,7 +2003,7 @@ index d82182c..08bec2d 100644
|
|
|
1928
2003
|
export class InteractiveMode {
|
|
1929
2004
|
runtimeHost;
|
|
1930
2005
|
renderer;
|
|
1931
|
-
@@ -
|
|
2006
|
+
@@ -451,9 +527,15 @@ export class InteractiveMode {
|
|
1932
2007
|
}
|
|
1933
2008
|
getBuiltInCommandConflictDiagnostics(extensionRunner) {
|
|
1934
2009
|
const builtinNames = new Set(BUILTIN_SLASH_COMMANDS.map((command) => command.name));
|
|
@@ -1945,7 +2020,7 @@ index d82182c..08bec2d 100644
|
|
|
1945
2020
|
.map((command) => ({
|
|
1946
2021
|
type: "warning",
|
|
1947
2022
|
message: command.invocationName === command.name
|
|
1948
|
-
@@ -
|
|
2023
|
+
@@ -841,20 +923,18 @@ export class InteractiveMode {
|
|
1949
2024
|
this.showNewVersionNotification(newRelease);
|
|
1950
2025
|
}
|
|
1951
2026
|
});
|
|
@@ -1978,16 +2053,16 @@ index d82182c..08bec2d 100644
|
|
|
1978
2053
|
// Check tmux keyboard setup asynchronously
|
|
1979
2054
|
this.checkTmuxKeyboardSetup().then((warning) => {
|
|
1980
2055
|
if (warning) {
|
|
1981
|
-
@@ -
|
|
2056
|
+
@@ -1651,7 +1731,7 @@ export class InteractiveMode {
|
|
1982
2057
|
if (this.bugReportHintShown)
|
|
1983
2058
|
return;
|
|
1984
2059
|
this.bugReportHintShown = true;
|
|
1985
|
-
- this.chatContainer.addChild(new
|
|
1986
|
-
+ this.chatContainer.addChild(new
|
|
2060
|
+
- this.chatContainer.addChild(new ThemedText(() => theme.fg("muted", `If this looks like a ${APP_NAME} bug, /bug sends a report to the developers.`), this.outputPad, 0));
|
|
2061
|
+
+ this.chatContainer.addChild(new ThemedText(() => theme.fg("muted", `If this looks like a ${APP_NAME} bug, /bug exports a report you can email to support@privateer.pro.`), this.outputPad, 0));
|
|
1987
2062
|
this.ui.requestRender();
|
|
1988
2063
|
}
|
|
1989
|
-
|
|
1990
|
-
@@ -
|
|
2064
|
+
maybeSuggestBugReport(message) {
|
|
2065
|
+
@@ -2558,7 +2638,17 @@ export class InteractiveMode {
|
|
1991
2066
|
if (text === "/model" || text.startsWith("/model ")) {
|
|
1992
2067
|
const searchTerm = text.startsWith("/model ") ? text.slice(7).trim() : undefined;
|
|
1993
2068
|
this.editor.setText("");
|
|
@@ -2006,7 +2081,7 @@ index d82182c..08bec2d 100644
|
|
|
2006
2081
|
return;
|
|
2007
2082
|
}
|
|
2008
2083
|
if (text === "/thinking" || text.startsWith("/thinking ")) {
|
|
2009
|
-
@@ -
|
|
2084
|
+
@@ -2636,12 +2726,42 @@ export class InteractiveMode {
|
|
2010
2085
|
if (text === "/login" || text.startsWith("/login ")) {
|
|
2011
2086
|
const providerRef = text.startsWith("/login ") ? text.slice(7).trim() : undefined;
|
|
2012
2087
|
this.editor.setText("");
|
|
@@ -2051,7 +2126,7 @@ index d82182c..08bec2d 100644
|
|
|
2051
2126
|
return;
|
|
2052
2127
|
}
|
|
2053
2128
|
if (text === "/new") {
|
|
2054
|
-
@@ -
|
|
2129
|
+
@@ -3006,9 +3126,19 @@ export class InteractiveMode {
|
|
2055
2130
|
if (entries[0]?.type !== "compaction") {
|
|
2056
2131
|
throw new Error("Completed compaction is missing from the session context");
|
|
2057
2132
|
}
|
|
@@ -2074,20 +2149,20 @@ index d82182c..08bec2d 100644
|
|
|
2074
2149
|
this.addMessageToChat(createCompactionSummaryMessage(event.result.summary, event.result.tokensBefore, new Date().toISOString()));
|
|
2075
2150
|
if (event.result.usage) {
|
|
2076
2151
|
this.addCompactionCostNotice({
|
|
2077
|
-
@@ -
|
|
2152
|
+
@@ -3441,7 +3571,7 @@ export class InteractiveMode {
|
|
2078
2153
|
if (this.chatContainer.children.length > 0) {
|
|
2079
2154
|
this.chatContainer.addChild(new Spacer(1));
|
|
2080
2155
|
}
|
|
2081
|
-
- this.chatContainer.addChild(new
|
|
2082
|
-
+ this.chatContainer.addChild(new
|
|
2156
|
+
- this.chatContainer.addChild(new ThemedText(() => theme.fg("warning", `This project is not trusted. Project ${CONFIG_DIR_NAME} resources and packages are ignored. Use /trust to save a trust decision, then restart pi.`), 1, 0));
|
|
2157
|
+
+ this.chatContainer.addChild(new ThemedText(() => theme.fg("warning", `This project is not trusted. Project ${formatProjectConfigDirNames()} resources and packages are ignored. Use /trust to save a trust decision, then restart ${process.env.PRIVATEER_CMD || APP_NAME}.`), 1, 0));
|
|
2083
2158
|
}
|
|
2084
2159
|
async getUserInput() {
|
|
2085
2160
|
const queuedInput = this.pendingUserInputs.shift();
|
|
2086
|
-
@@ -
|
|
2161
|
+
@@ -3795,7 +3925,17 @@ export class InteractiveMode {
|
|
2087
2162
|
}
|
|
2088
2163
|
showError(errorMessage) {
|
|
2089
2164
|
this.chatContainer.addChild(new Spacer(1));
|
|
2090
|
-
- this.chatContainer.addChild(new
|
|
2165
|
+
- this.chatContainer.addChild(new ThemedText(() => theme.fg("error", `Error: ${errorMessage}`), this.outputPad, 0));
|
|
2091
2166
|
+ // Privateer patch: by the time an error reaches here it is only a string — the
|
|
2092
2167
|
+ // structured fields describeError() reads are long gone, so the user was shown
|
|
2093
2168
|
+ // the SDK's own words ("429 status code (no body)"), which say nothing about
|
|
@@ -2095,49 +2170,65 @@ index d82182c..08bec2d 100644
|
|
|
2095
2170
|
+ // it and say what describeError would. Mirrors describeErrorText in
|
|
2096
2171
|
+ // src/engine/errors.ts. Anything without a leading status prints unchanged.
|
|
2097
2172
|
+ const described = pvDescribeErrorText(errorMessage);
|
|
2098
|
-
+ this.chatContainer.addChild(new
|
|
2173
|
+
+ this.chatContainer.addChild(new ThemedText(() => theme.fg("error", `Error: ${described?.message ?? errorMessage}`), this.outputPad, 0));
|
|
2099
2174
|
+ if (described?.hint) {
|
|
2100
|
-
+ this.chatContainer.addChild(new
|
|
2175
|
+
+ this.chatContainer.addChild(new ThemedText(() => theme.fg("muted", described.hint), this.outputPad, 0));
|
|
2101
2176
|
+ }
|
|
2102
2177
|
this.ui.requestRender();
|
|
2103
2178
|
}
|
|
2104
2179
|
showWarning(warningMessage) {
|
|
2105
2180
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/dark.json b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/dark.json
|
|
2106
|
-
index
|
|
2181
|
+
index 0a82c28..f9c106b 100644
|
|
2107
2182
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/dark.json
|
|
2108
2183
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/dark.json
|
|
2109
|
-
@@ -
|
|
2110
|
-
"customMessageBg": "
|
|
2111
|
-
"customMessageText": "
|
|
2112
|
-
"customMessageLabel": "
|
|
2113
|
-
- "toolPendingBg": "
|
|
2114
|
-
- "toolSuccessBg": "
|
|
2115
|
-
- "toolErrorBg": "
|
|
2184
|
+
@@ -34,9 +34,9 @@
|
|
2185
|
+
"customMessageBg": "okhsl(295 42% 24%)",
|
|
2186
|
+
"customMessageText": "muted",
|
|
2187
|
+
"customMessageLabel": "violet",
|
|
2188
|
+
- "toolPendingBg": "okhsl(229 5% 24%)",
|
|
2189
|
+
- "toolSuccessBg": "okhsl(158 46% 25%)",
|
|
2190
|
+
- "toolErrorBg": "okhsl(19 54% 25%)",
|
|
2116
2191
|
+ "toolPendingBg": "",
|
|
2117
2192
|
+ "toolSuccessBg": "",
|
|
2118
2193
|
+ "toolErrorBg": "",
|
|
2119
2194
|
"toolTitle": "text",
|
|
2120
|
-
"toolOutput": "
|
|
2121
|
-
|
|
2195
|
+
"toolOutput": "muted",
|
|
2196
|
+
"mdHeading": "yellow",
|
|
2122
2197
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/light.json b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/light.json
|
|
2123
|
-
index
|
|
2198
|
+
index 3d870c0..57a2cb5 100644
|
|
2124
2199
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/light.json
|
|
2125
2200
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/light.json
|
|
2126
|
-
@@ -
|
|
2127
|
-
"customMessageBg": "
|
|
2128
|
-
"customMessageText": "
|
|
2129
|
-
"customMessageLabel": "
|
|
2130
|
-
- "toolPendingBg": "
|
|
2131
|
-
- "toolSuccessBg": "
|
|
2132
|
-
- "toolErrorBg": "
|
|
2201
|
+
@@ -34,9 +34,9 @@
|
|
2202
|
+
"customMessageBg": "okhsl(295 25% 91%)",
|
|
2203
|
+
"customMessageText": "muted",
|
|
2204
|
+
"customMessageLabel": "violet",
|
|
2205
|
+
- "toolPendingBg": "okhsl(248 3% 91%)",
|
|
2206
|
+
- "toolSuccessBg": "okhsl(156 21% 91%)",
|
|
2207
|
+
- "toolErrorBg": "okhsl(24 23% 91%)",
|
|
2133
2208
|
+ "toolPendingBg": "",
|
|
2134
2209
|
+ "toolSuccessBg": "",
|
|
2135
2210
|
+ "toolErrorBg": "",
|
|
2136
2211
|
"toolTitle": "text",
|
|
2137
|
-
"toolOutput": "
|
|
2138
|
-
|
|
2212
|
+
"toolOutput": "muted",
|
|
2213
|
+
"mdHeading": "yellow",
|
|
2214
|
+
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.js b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.js
|
|
2215
|
+
index d50acea..0ff5f27 100644
|
|
2216
|
+
--- a/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.js
|
|
2217
|
+
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.js
|
|
2218
|
+
@@ -409,6 +409,11 @@ function createSystemTheme(mode) {
|
|
2219
|
+
saturation: terminalColorsPending ? 0 : 1,
|
|
2220
|
+
appearanceHint: getTerminalTheme(),
|
|
2221
|
+
});
|
|
2222
|
+
+ // Privateer patch: flat tool calls — no tinted panel behind pending/success/error tool
|
|
2223
|
+
+ // blocks, matching dark.json/light.json. "" means the terminal's own background, so a
|
|
2224
|
+
+ // tool call reads as part of the transcript; the red ✗ marks a failure on its own.
|
|
2225
|
+
+ for (const token of ["toolPendingBg", "toolSuccessBg", "toolErrorBg"])
|
|
2226
|
+
+ generated.colors[token] = "";
|
|
2227
|
+
const { fgColors, bgColors } = splitThemeColors(withThemeTokenFallbacks(generated.colors));
|
|
2228
|
+
return new Theme(fgColors, bgColors, mode ?? getTerminalColorMode(), {
|
|
2229
|
+
name: SYSTEM_THEME_NAME,
|
|
2139
2230
|
diff --git a/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js b/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js
|
|
2140
|
-
index
|
|
2231
|
+
index 6f56150..a68a510 100644
|
|
2141
2232
|
--- a/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js
|
|
2142
2233
|
+++ b/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js
|
|
2143
2234
|
@@ -5,7 +5,7 @@ import chalk from "chalk";
|
|
@@ -2149,7 +2240,7 @@ index 3f101e6..51c7f73 100644
|
|
|
2149
2240
|
import { ModelRuntime } from "./core/model-runtime.js";
|
|
2150
2241
|
import { DefaultPackageManager } from "./core/package-manager.js";
|
|
2151
2242
|
import { resolveProjectTrusted } from "./core/project-trust.js";
|
|
2152
|
-
@@ -
|
|
2243
|
+
@@ -245,7 +245,7 @@ Without -l, starts in global settings (~/${CONFIG_DIR_NAME}/agent/settings.json)
|
|
2153
2244
|
Press Tab in the TUI to switch between global and project-local modes.
|
|
2154
2245
|
|
|
2155
2246
|
Options:
|
|
@@ -2158,7 +2249,7 @@ index 3f101e6..51c7f73 100644
|
|
|
2158
2249
|
-a, --approve Trust project-local files for this command with -l
|
|
2159
2250
|
-na, --no-approve Ignore project-local files for this command with -l
|
|
2160
2251
|
`);
|
|
2161
|
-
@@ -
|
|
2252
|
+
@@ -259,7 +259,7 @@ function printPackageCommandHelp(command) {
|
|
2162
2253
|
Install a package and add it to settings.
|
|
2163
2254
|
|
|
2164
2255
|
Options:
|
|
@@ -2167,7 +2258,7 @@ index 3f101e6..51c7f73 100644
|
|
|
2167
2258
|
-a, --approve Trust project-local files for this command
|
|
2168
2259
|
-na, --no-approve Ignore project-local files for this command
|
|
2169
2260
|
|
|
2170
|
-
@@ -
|
|
2261
|
+
@@ -280,7 +280,7 @@ Remove a package and its source from settings.
|
|
2171
2262
|
Alias: ${APP_NAME} uninstall <source> [-l]
|
|
2172
2263
|
|
|
2173
2264
|
Options:
|