@mariozechner/pi-coding-agent 0.65.2 → 0.66.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.
@@ -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,32 @@ export class InteractiveMode {
281
288
  this.editor.setAutocompleteProvider?.(this.autocompleteProvider);
282
289
  }
283
290
  }
291
+ showStartupNoticesIfNeeded() {
292
+ if (this.startupNoticesShown) {
293
+ return;
294
+ }
295
+ this.startupNoticesShown = true;
296
+ if (!this.changelogMarkdown) {
297
+ return;
298
+ }
299
+ if (this.chatContainer.children.length > 0) {
300
+ this.chatContainer.addChild(new Spacer(1));
301
+ }
302
+ this.chatContainer.addChild(new DynamicBorder());
303
+ if (this.settingsManager.getCollapseChangelog()) {
304
+ const versionMatch = this.changelogMarkdown.match(/##\s+\[?(\d+\.\d+\.\d+)\]?/);
305
+ const latestVersion = versionMatch ? versionMatch[1] : this.version;
306
+ const condensedText = `Updated to v${latestVersion}. Use ${theme.bold("/changelog")} to view full changelog.`;
307
+ this.chatContainer.addChild(new Text(condensedText, 1, 0));
308
+ }
309
+ else {
310
+ this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", "What's New")), 1, 0));
311
+ this.chatContainer.addChild(new Spacer(1));
312
+ this.chatContainer.addChild(new Markdown(this.changelogMarkdown.trim(), 1, 0, this.getMarkdownThemeWithSettings()));
313
+ this.chatContainer.addChild(new Spacer(1));
314
+ }
315
+ this.chatContainer.addChild(new DynamicBorder());
316
+ }
284
317
  async init() {
285
318
  if (this.isInitialized)
286
319
  return;
@@ -324,36 +357,11 @@ export class InteractiveMode {
324
357
  this.headerContainer.addChild(new Spacer(1));
325
358
  this.headerContainer.addChild(this.builtInHeader);
326
359
  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
360
  }
345
361
  else {
346
362
  // Minimal header when silenced
347
363
  this.builtInHeader = new Text("", 0, 0);
348
364
  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
365
  }
358
366
  this.ui.addChild(this.chatContainer);
359
367
  this.ui.addChild(this.pendingMessagesContainer);
@@ -439,6 +447,7 @@ export class InteractiveMode {
439
447
  if (modelFallbackMessage) {
440
448
  this.showWarning(modelFallbackMessage);
441
449
  }
450
+ void this.maybeWarnAboutAnthropicSubscriptionAuth();
442
451
  // Process initial messages
443
452
  if (initialMessage) {
444
453
  try {
@@ -970,10 +979,12 @@ export class InteractiveMode {
970
979
  const extensionRunner = this.session.extensionRunner;
971
980
  if (!extensionRunner) {
972
981
  this.showLoadedResources({ extensions: [], force: false });
982
+ this.showStartupNoticesIfNeeded();
973
983
  return;
974
984
  }
975
985
  this.setupExtensionShortcuts(extensionRunner);
976
986
  this.showLoadedResources({ force: false });
987
+ this.showStartupNoticesIfNeeded();
977
988
  }
978
989
  applyRuntimeSettings() {
979
990
  this.footer.setSession(this.session);
@@ -1809,6 +1820,11 @@ export class InteractiveMode {
1809
1820
  this.editor.setText("");
1810
1821
  return;
1811
1822
  }
1823
+ if (text === "/dementedelves") {
1824
+ this.handleDementedDelves();
1825
+ this.editor.setText("");
1826
+ return;
1827
+ }
1812
1828
  if (text === "/resume") {
1813
1829
  this.showSessionSelector();
1814
1830
  this.editor.setText("");
@@ -2460,6 +2476,7 @@ export class InteractiveMode {
2460
2476
  this.updateEditorBorderColor();
2461
2477
  const thinkingStr = result.model.reasoning && result.thinkingLevel !== "off" ? ` (thinking: ${result.thinkingLevel})` : "";
2462
2478
  this.showStatus(`Switched to ${result.model.name || result.model.id}${thinkingStr}`);
2479
+ void this.maybeWarnAboutAnthropicSubscriptionAuth(result.model);
2463
2480
  }
2464
2481
  }
2465
2482
  catch (error) {
@@ -2899,6 +2916,7 @@ export class InteractiveMode {
2899
2916
  this.footer.invalidate();
2900
2917
  this.updateEditorBorderColor();
2901
2918
  this.showStatus(`Model: ${model.id}`);
2919
+ void this.maybeWarnAboutAnthropicSubscriptionAuth(model);
2902
2920
  this.checkDaxnutsEasterEgg(model);
2903
2921
  }
2904
2922
  catch (error) {
@@ -2930,6 +2948,31 @@ export class InteractiveMode {
2930
2948
  const uniqueProviders = new Set(models.map((m) => m.provider));
2931
2949
  this.footerDataProvider.setAvailableProviderCount(uniqueProviders.size);
2932
2950
  }
2951
+ async maybeWarnAboutAnthropicSubscriptionAuth(model = this.session.model) {
2952
+ if (this.anthropicSubscriptionWarningShown) {
2953
+ return;
2954
+ }
2955
+ if (!model || model.provider !== "anthropic") {
2956
+ return;
2957
+ }
2958
+ const storedCredential = this.session.modelRegistry.authStorage.get("anthropic");
2959
+ if (storedCredential?.type === "oauth") {
2960
+ this.anthropicSubscriptionWarningShown = true;
2961
+ this.showWarning(ANTHROPIC_SUBSCRIPTION_AUTH_WARNING);
2962
+ return;
2963
+ }
2964
+ try {
2965
+ const apiKey = await this.session.modelRegistry.getApiKeyForProvider(model.provider);
2966
+ if (!isAnthropicSubscriptionAuthKey(apiKey)) {
2967
+ return;
2968
+ }
2969
+ this.anthropicSubscriptionWarningShown = true;
2970
+ this.showWarning(ANTHROPIC_SUBSCRIPTION_AUTH_WARNING);
2971
+ }
2972
+ catch {
2973
+ // Ignore auth lookup failures for warning-only checks.
2974
+ }
2975
+ }
2933
2976
  showModelSelector(initialSearchInput) {
2934
2977
  this.showSelector((done) => {
2935
2978
  const selector = new ModelSelectorComponent(this.ui, this.session.model, this.settingsManager, this.session.modelRegistry, this.session.scopedModels, async (model) => {
@@ -2939,6 +2982,7 @@ export class InteractiveMode {
2939
2982
  this.updateEditorBorderColor();
2940
2983
  done();
2941
2984
  this.showStatus(`Model: ${model.id}`);
2985
+ void this.maybeWarnAboutAnthropicSubscriptionAuth(model);
2942
2986
  this.checkDaxnutsEasterEgg(model);
2943
2987
  }
2944
2988
  catch (error) {
@@ -3854,6 +3898,11 @@ export class InteractiveMode {
3854
3898
  this.chatContainer.addChild(new ArminComponent(this.ui));
3855
3899
  this.ui.requestRender();
3856
3900
  }
3901
+ handleDementedDelves() {
3902
+ this.chatContainer.addChild(new Spacer(1));
3903
+ this.chatContainer.addChild(new EarendilAnnouncementComponent());
3904
+ this.ui.requestRender();
3905
+ }
3857
3906
  handleDaxnuts() {
3858
3907
  this.chatContainer.addChild(new Spacer(1));
3859
3908
  this.chatContainer.addChild(new DaxnutsComponent(this.ui));