@mariozechner/pi-coding-agent 0.65.2 → 0.66.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/CHANGELOG.md +14 -0
- package/README.md +16 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -0
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +2 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/assets/clankolas.png +0 -0
- package/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
- package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -0
- package/dist/modes/interactive/components/earendil-announcement.js +40 -0
- package/dist/modes/interactive/components/earendil-announcement.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +5 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +74 -25
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +6 -6
|
@@ -33,6 +33,7 @@ import { CustomEditor } from "./components/custom-editor.js";
|
|
|
33
33
|
import { CustomMessageComponent } from "./components/custom-message.js";
|
|
34
34
|
import { DaxnutsComponent } from "./components/daxnuts.js";
|
|
35
35
|
import { DynamicBorder } from "./components/dynamic-border.js";
|
|
36
|
+
import { EarendilAnnouncementComponent } from "./components/earendil-announcement.js";
|
|
36
37
|
import { ExtensionEditorComponent } from "./components/extension-editor.js";
|
|
37
38
|
import { ExtensionInputComponent } from "./components/extension-input.js";
|
|
38
39
|
import { ExtensionSelectorComponent } from "./components/extension-selector.js";
|
|
@@ -53,6 +54,10 @@ import { getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMar
|
|
|
53
54
|
function isExpandable(obj) {
|
|
54
55
|
return typeof obj === "object" && obj !== null && "setExpanded" in obj && typeof obj.setExpanded === "function";
|
|
55
56
|
}
|
|
57
|
+
const ANTHROPIC_SUBSCRIPTION_AUTH_WARNING = "Anthropic subscription auth is active. Third-party usage now draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage.";
|
|
58
|
+
function isAnthropicSubscriptionAuthKey(apiKey) {
|
|
59
|
+
return typeof apiKey === "string" && apiKey.startsWith("sk-ant-oat");
|
|
60
|
+
}
|
|
56
61
|
export class InteractiveMode {
|
|
57
62
|
options;
|
|
58
63
|
runtimeHost;
|
|
@@ -80,6 +85,8 @@ export class InteractiveMode {
|
|
|
80
85
|
lastSigintTime = 0;
|
|
81
86
|
lastEscapeTime = 0;
|
|
82
87
|
changelogMarkdown = undefined;
|
|
88
|
+
startupNoticesShown = false;
|
|
89
|
+
anthropicSubscriptionWarningShown = false;
|
|
83
90
|
// Status line tracking (for mutating immediately-sequential status updates)
|
|
84
91
|
lastStatusSpacer = undefined;
|
|
85
92
|
lastStatusText = undefined;
|
|
@@ -281,6 +288,42 @@ export class InteractiveMode {
|
|
|
281
288
|
this.editor.setAutocompleteProvider?.(this.autocompleteProvider);
|
|
282
289
|
}
|
|
283
290
|
}
|
|
291
|
+
shouldShowEarendilAnnouncement() {
|
|
292
|
+
const now = new Date();
|
|
293
|
+
return now.getFullYear() === 2026 && now.getMonth() === 3 && (now.getDate() === 8 || now.getDate() === 9);
|
|
294
|
+
}
|
|
295
|
+
showStartupNoticesIfNeeded() {
|
|
296
|
+
if (this.startupNoticesShown) {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
this.startupNoticesShown = true;
|
|
300
|
+
if (this.shouldShowEarendilAnnouncement()) {
|
|
301
|
+
if (this.chatContainer.children.length > 0) {
|
|
302
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
303
|
+
}
|
|
304
|
+
this.chatContainer.addChild(new EarendilAnnouncementComponent());
|
|
305
|
+
}
|
|
306
|
+
if (!this.changelogMarkdown) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
if (this.chatContainer.children.length > 0) {
|
|
310
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
311
|
+
}
|
|
312
|
+
this.chatContainer.addChild(new DynamicBorder());
|
|
313
|
+
if (this.settingsManager.getCollapseChangelog()) {
|
|
314
|
+
const versionMatch = this.changelogMarkdown.match(/##\s+\[?(\d+\.\d+\.\d+)\]?/);
|
|
315
|
+
const latestVersion = versionMatch ? versionMatch[1] : this.version;
|
|
316
|
+
const condensedText = `Updated to v${latestVersion}. Use ${theme.bold("/changelog")} to view full changelog.`;
|
|
317
|
+
this.chatContainer.addChild(new Text(condensedText, 1, 0));
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", "What's New")), 1, 0));
|
|
321
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
322
|
+
this.chatContainer.addChild(new Markdown(this.changelogMarkdown.trim(), 1, 0, this.getMarkdownThemeWithSettings()));
|
|
323
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
324
|
+
}
|
|
325
|
+
this.chatContainer.addChild(new DynamicBorder());
|
|
326
|
+
}
|
|
284
327
|
async init() {
|
|
285
328
|
if (this.isInitialized)
|
|
286
329
|
return;
|
|
@@ -324,36 +367,11 @@ export class InteractiveMode {
|
|
|
324
367
|
this.headerContainer.addChild(new Spacer(1));
|
|
325
368
|
this.headerContainer.addChild(this.builtInHeader);
|
|
326
369
|
this.headerContainer.addChild(new Spacer(1));
|
|
327
|
-
// Add changelog if provided
|
|
328
|
-
if (this.changelogMarkdown) {
|
|
329
|
-
this.headerContainer.addChild(new DynamicBorder());
|
|
330
|
-
if (this.settingsManager.getCollapseChangelog()) {
|
|
331
|
-
const versionMatch = this.changelogMarkdown.match(/##\s+\[?(\d+\.\d+\.\d+)\]?/);
|
|
332
|
-
const latestVersion = versionMatch ? versionMatch[1] : this.version;
|
|
333
|
-
const condensedText = `Updated to v${latestVersion}. Use ${theme.bold("/changelog")} to view full changelog.`;
|
|
334
|
-
this.headerContainer.addChild(new Text(condensedText, 1, 0));
|
|
335
|
-
}
|
|
336
|
-
else {
|
|
337
|
-
this.headerContainer.addChild(new Text(theme.bold(theme.fg("accent", "What's New")), 1, 0));
|
|
338
|
-
this.headerContainer.addChild(new Spacer(1));
|
|
339
|
-
this.headerContainer.addChild(new Markdown(this.changelogMarkdown.trim(), 1, 0, this.getMarkdownThemeWithSettings()));
|
|
340
|
-
this.headerContainer.addChild(new Spacer(1));
|
|
341
|
-
}
|
|
342
|
-
this.headerContainer.addChild(new DynamicBorder());
|
|
343
|
-
}
|
|
344
370
|
}
|
|
345
371
|
else {
|
|
346
372
|
// Minimal header when silenced
|
|
347
373
|
this.builtInHeader = new Text("", 0, 0);
|
|
348
374
|
this.headerContainer.addChild(this.builtInHeader);
|
|
349
|
-
if (this.changelogMarkdown) {
|
|
350
|
-
// Still show changelog notification even in silent mode
|
|
351
|
-
this.headerContainer.addChild(new Spacer(1));
|
|
352
|
-
const versionMatch = this.changelogMarkdown.match(/##\s+\[?(\d+\.\d+\.\d+)\]?/);
|
|
353
|
-
const latestVersion = versionMatch ? versionMatch[1] : this.version;
|
|
354
|
-
const condensedText = `Updated to v${latestVersion}. Use ${theme.bold("/changelog")} to view full changelog.`;
|
|
355
|
-
this.headerContainer.addChild(new Text(condensedText, 1, 0));
|
|
356
|
-
}
|
|
357
375
|
}
|
|
358
376
|
this.ui.addChild(this.chatContainer);
|
|
359
377
|
this.ui.addChild(this.pendingMessagesContainer);
|
|
@@ -439,6 +457,7 @@ export class InteractiveMode {
|
|
|
439
457
|
if (modelFallbackMessage) {
|
|
440
458
|
this.showWarning(modelFallbackMessage);
|
|
441
459
|
}
|
|
460
|
+
void this.maybeWarnAboutAnthropicSubscriptionAuth();
|
|
442
461
|
// Process initial messages
|
|
443
462
|
if (initialMessage) {
|
|
444
463
|
try {
|
|
@@ -970,10 +989,12 @@ export class InteractiveMode {
|
|
|
970
989
|
const extensionRunner = this.session.extensionRunner;
|
|
971
990
|
if (!extensionRunner) {
|
|
972
991
|
this.showLoadedResources({ extensions: [], force: false });
|
|
992
|
+
this.showStartupNoticesIfNeeded();
|
|
973
993
|
return;
|
|
974
994
|
}
|
|
975
995
|
this.setupExtensionShortcuts(extensionRunner);
|
|
976
996
|
this.showLoadedResources({ force: false });
|
|
997
|
+
this.showStartupNoticesIfNeeded();
|
|
977
998
|
}
|
|
978
999
|
applyRuntimeSettings() {
|
|
979
1000
|
this.footer.setSession(this.session);
|
|
@@ -2460,6 +2481,7 @@ export class InteractiveMode {
|
|
|
2460
2481
|
this.updateEditorBorderColor();
|
|
2461
2482
|
const thinkingStr = result.model.reasoning && result.thinkingLevel !== "off" ? ` (thinking: ${result.thinkingLevel})` : "";
|
|
2462
2483
|
this.showStatus(`Switched to ${result.model.name || result.model.id}${thinkingStr}`);
|
|
2484
|
+
void this.maybeWarnAboutAnthropicSubscriptionAuth(result.model);
|
|
2463
2485
|
}
|
|
2464
2486
|
}
|
|
2465
2487
|
catch (error) {
|
|
@@ -2899,6 +2921,7 @@ export class InteractiveMode {
|
|
|
2899
2921
|
this.footer.invalidate();
|
|
2900
2922
|
this.updateEditorBorderColor();
|
|
2901
2923
|
this.showStatus(`Model: ${model.id}`);
|
|
2924
|
+
void this.maybeWarnAboutAnthropicSubscriptionAuth(model);
|
|
2902
2925
|
this.checkDaxnutsEasterEgg(model);
|
|
2903
2926
|
}
|
|
2904
2927
|
catch (error) {
|
|
@@ -2930,6 +2953,31 @@ export class InteractiveMode {
|
|
|
2930
2953
|
const uniqueProviders = new Set(models.map((m) => m.provider));
|
|
2931
2954
|
this.footerDataProvider.setAvailableProviderCount(uniqueProviders.size);
|
|
2932
2955
|
}
|
|
2956
|
+
async maybeWarnAboutAnthropicSubscriptionAuth(model = this.session.model) {
|
|
2957
|
+
if (this.anthropicSubscriptionWarningShown) {
|
|
2958
|
+
return;
|
|
2959
|
+
}
|
|
2960
|
+
if (!model || model.provider !== "anthropic") {
|
|
2961
|
+
return;
|
|
2962
|
+
}
|
|
2963
|
+
const storedCredential = this.session.modelRegistry.authStorage.get("anthropic");
|
|
2964
|
+
if (storedCredential?.type === "oauth") {
|
|
2965
|
+
this.anthropicSubscriptionWarningShown = true;
|
|
2966
|
+
this.showWarning(ANTHROPIC_SUBSCRIPTION_AUTH_WARNING);
|
|
2967
|
+
return;
|
|
2968
|
+
}
|
|
2969
|
+
try {
|
|
2970
|
+
const apiKey = await this.session.modelRegistry.getApiKeyForProvider(model.provider);
|
|
2971
|
+
if (!isAnthropicSubscriptionAuthKey(apiKey)) {
|
|
2972
|
+
return;
|
|
2973
|
+
}
|
|
2974
|
+
this.anthropicSubscriptionWarningShown = true;
|
|
2975
|
+
this.showWarning(ANTHROPIC_SUBSCRIPTION_AUTH_WARNING);
|
|
2976
|
+
}
|
|
2977
|
+
catch {
|
|
2978
|
+
// Ignore auth lookup failures for warning-only checks.
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2933
2981
|
showModelSelector(initialSearchInput) {
|
|
2934
2982
|
this.showSelector((done) => {
|
|
2935
2983
|
const selector = new ModelSelectorComponent(this.ui, this.session.model, this.settingsManager, this.session.modelRegistry, this.session.scopedModels, async (model) => {
|
|
@@ -2939,6 +2987,7 @@ export class InteractiveMode {
|
|
|
2939
2987
|
this.updateEditorBorderColor();
|
|
2940
2988
|
done();
|
|
2941
2989
|
this.showStatus(`Model: ${model.id}`);
|
|
2990
|
+
void this.maybeWarnAboutAnthropicSubscriptionAuth(model);
|
|
2942
2991
|
this.checkDaxnutsEasterEgg(model);
|
|
2943
2992
|
}
|
|
2944
2993
|
catch (error) {
|