@earendil-works/pi-coding-agent 0.84.3 → 0.84.4

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.
Files changed (102) hide show
  1. package/CHANGELOG.md +47 -3
  2. package/README.md +5 -4
  3. package/dist/bundle/chunks/{chunk-GPPBJGBU.js → chunk-2KVJKXS2.js} +1 -1
  4. package/dist/bundle/chunks/{chunk-E5KXRMZK.js → chunk-OMWWHBTG.js} +69 -68
  5. package/dist/bundle/chunks/github-copilot.js +1 -1
  6. package/dist/bundle/chunks/{google-generative-ai-XDKMGBCJ.js → google-generative-ai-YMUPJBKR.js} +1 -1
  7. package/dist/bundle/chunks/{google-vertex-D5FGEO3Y.js → google-vertex-MPWMV4OF.js} +1 -1
  8. package/dist/bundle/chunks/https-proxy-agent-2VXB7436.js +13 -0
  9. package/dist/bundle/chunks/{mistral-conversations-YK73UAOZ.js → mistral-conversations-Q3AWZJAZ.js} +1 -1
  10. package/dist/bundle/chunks/{openai-completions-JD4WAC3R.js → openai-completions-ERMU2SS7.js} +1 -1
  11. package/dist/bundle/cli.js +1 -1
  12. package/dist/bundle/index.js +1 -1
  13. package/dist/bundle/rpc-entry.js +1 -1
  14. package/dist/cli/startup-ui.d.ts.map +1 -1
  15. package/dist/cli/startup-ui.js +2 -1
  16. package/dist/cli/startup-ui.js.map +1 -1
  17. package/dist/core/agent-session.d.ts +12 -1
  18. package/dist/core/agent-session.d.ts.map +1 -1
  19. package/dist/core/agent-session.js +77 -9
  20. package/dist/core/agent-session.js.map +1 -1
  21. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  22. package/dist/core/compaction/branch-summarization.js +4 -3
  23. package/dist/core/compaction/branch-summarization.js.map +1 -1
  24. package/dist/core/compaction/compaction.d.ts +5 -0
  25. package/dist/core/compaction/compaction.d.ts.map +1 -1
  26. package/dist/core/compaction/compaction.js +19 -5
  27. package/dist/core/compaction/compaction.js.map +1 -1
  28. package/dist/core/extensions/index.d.ts +1 -1
  29. package/dist/core/extensions/index.d.ts.map +1 -1
  30. package/dist/core/extensions/index.js.map +1 -1
  31. package/dist/core/extensions/runner.d.ts +5 -0
  32. package/dist/core/extensions/runner.d.ts.map +1 -1
  33. package/dist/core/extensions/runner.js +45 -1
  34. package/dist/core/extensions/runner.js.map +1 -1
  35. package/dist/core/extensions/types.d.ts +18 -1
  36. package/dist/core/extensions/types.d.ts.map +1 -1
  37. package/dist/core/extensions/types.js.map +1 -1
  38. package/dist/core/session-manager.d.ts.map +1 -1
  39. package/dist/core/session-manager.js +4 -2
  40. package/dist/core/session-manager.js.map +1 -1
  41. package/dist/core/settings-manager.d.ts +8 -1
  42. package/dist/core/settings-manager.d.ts.map +1 -1
  43. package/dist/core/settings-manager.js +17 -0
  44. package/dist/core/settings-manager.js.map +1 -1
  45. package/dist/extensions/llama/client.d.ts +6 -0
  46. package/dist/extensions/llama/client.d.ts.map +1 -1
  47. package/dist/extensions/llama/client.js +7 -0
  48. package/dist/extensions/llama/client.js.map +1 -1
  49. package/dist/extensions/llama/provider.d.ts +3 -1
  50. package/dist/extensions/llama/provider.d.ts.map +1 -1
  51. package/dist/extensions/llama/provider.js +27 -6
  52. package/dist/extensions/llama/provider.js.map +1 -1
  53. package/dist/index.d.ts +2 -1
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +1 -0
  56. package/dist/index.js.map +1 -1
  57. package/dist/main.d.ts.map +1 -1
  58. package/dist/main.js +2 -0
  59. package/dist/main.js.map +1 -1
  60. package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  61. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  62. package/dist/modes/interactive/components/settings-selector.js +10 -0
  63. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  64. package/dist/modes/interactive/interactive-mode.d.ts +4 -0
  65. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  66. package/dist/modes/interactive/interactive-mode.js +48 -24
  67. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  68. package/dist/modes/rpc/rpc-client.d.ts +7 -0
  69. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  70. package/dist/modes/rpc/rpc-client.js +7 -0
  71. package/dist/modes/rpc/rpc-client.js.map +1 -1
  72. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  73. package/dist/modes/rpc/rpc-mode.js +3 -0
  74. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  75. package/dist/modes/rpc/rpc-types.d.ts +12 -0
  76. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  77. package/dist/modes/rpc/rpc-types.js.map +1 -1
  78. package/dist/utils/shell.d.ts.map +1 -1
  79. package/dist/utils/shell.js +6 -4
  80. package/dist/utils/shell.js.map +1 -1
  81. package/docs/compaction.md +2 -0
  82. package/docs/custom-provider.md +7 -7
  83. package/docs/environment-variables.md +3 -0
  84. package/docs/extensions.md +18 -0
  85. package/docs/keybindings.md +1 -1
  86. package/docs/quickstart.md +1 -1
  87. package/docs/rpc.md +23 -0
  88. package/docs/settings.md +12 -4
  89. package/docs/terminal-setup.md +12 -0
  90. package/docs/usage.md +4 -3
  91. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  92. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  93. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  94. package/examples/extensions/gondolin/package-lock.json +2 -2
  95. package/examples/extensions/gondolin/package.json +1 -1
  96. package/examples/extensions/sandbox/package-lock.json +2 -2
  97. package/examples/extensions/sandbox/package.json +1 -1
  98. package/examples/extensions/with-deps/package-lock.json +2 -2
  99. package/examples/extensions/with-deps/package.json +1 -1
  100. package/npm-shrinkwrap.json +23 -23
  101. package/package.json +6 -6
  102. package/dist/bundle/chunks/dist-RDWOYWHR.js +0 -13
@@ -7,7 +7,7 @@ import * as fs from "node:fs";
7
7
  import * as os from "node:os";
8
8
  import * as path from "node:path";
9
9
  import * as TuiLayouts from "@earendil-works/pi-tui";
10
- import { CombinedAutocompleteProvider, Container, fuzzyFilter, getCapabilities, hyperlink, Markdown, matchesKey, ProcessTerminal, Spacer, setKeybindings, Text, TruncatedText, TuiAltScreen, TuiMainScreen, visibleWidth, } from "@earendil-works/pi-tui";
10
+ import { CombinedAutocompleteProvider, Container, fuzzyFilter, getCapabilities, hyperlink, Markdown, matchesKey, ProcessTerminal, Spacer, setCapabilityOverrides, setKeybindings, Text, TruncatedText, TuiAltScreen, TuiMainScreen, visibleWidth, } from "@earendil-works/pi-tui";
11
11
  import chalk from "chalk";
12
12
  import { spawn } from "child_process";
13
13
  import { APP_NAME, APP_TITLE, CONFIG_DIR_NAME, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, VERSION, } from "../../config.js";
@@ -187,6 +187,7 @@ export function createInteractiveTui(options) {
187
187
  searchCurrentMatchStyle: (text) => theme.bold(theme.inverse(styleSearchMatch(text))),
188
188
  openUrl: openBrowser,
189
189
  onRightClickPaste: options.onRightClickPaste,
190
+ copyOnSelect: options.fullscreenCopyOnSelect,
190
191
  copySelection: async (text) => {
191
192
  try {
192
193
  await copyToClipboard(text);
@@ -350,6 +351,7 @@ export class InteractiveMode {
350
351
  }
351
352
  constructor(runtimeHost, options = {}) {
352
353
  this.runtimeHost = runtimeHost;
354
+ setCapabilityOverrides(this.settingsManager.getTerminalCapabilityOverrides());
353
355
  const tuiMode = options.tuiMode ?? this.settingsManager.getTuiMode();
354
356
  this.options = { ...options, tuiMode };
355
357
  this.autoTrustOnReloadCwd = options.autoTrustOnReloadCwd;
@@ -366,6 +368,7 @@ export class InteractiveMode {
366
368
  showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
367
369
  logDirectory: getAgentDir(),
368
370
  onRightClickPaste: this.onRightClickPaste,
371
+ fullscreenCopyOnSelect: this.settingsManager.getFullscreenCopyOnSelect(),
369
372
  });
370
373
  this.ui = createInteractiveTuiReference(() => this.renderer);
371
374
  this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());
@@ -613,6 +616,7 @@ export class InteractiveMode {
613
616
  logDirectory: getAgentDir(),
614
617
  terminal,
615
618
  onRightClickPaste: this.onRightClickPaste,
619
+ fullscreenCopyOnSelect: this.settingsManager.getFullscreenCopyOnSelect(),
616
620
  });
617
621
  nextUi.setClearOnShrink(clearOnShrink);
618
622
  nextUi.onDebug = onDebug;
@@ -1521,8 +1525,12 @@ export class InteractiveMode {
1521
1525
  this.transcriptScrollView?.setScrollbar(this.settingsManager.getFullscreenScrollbar());
1522
1526
  }
1523
1527
  applyRuntimeSettings() {
1528
+ setCapabilityOverrides(this.settingsManager.getTerminalCapabilityOverrides());
1524
1529
  configureHttpDispatcher(this.settingsManager.getHttpIdleTimeoutMs());
1525
1530
  this.applyFullscreenScrollbarSetting();
1531
+ if (this.renderer instanceof TuiAltScreen) {
1532
+ this.renderer.setCopyOnSelect(this.settingsManager.getFullscreenCopyOnSelect());
1533
+ }
1526
1534
  this.footer.setSession(this.session);
1527
1535
  this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled);
1528
1536
  this.footerDataProvider.setCwd(this.sessionManager.getCwd());
@@ -1672,6 +1680,9 @@ export class InteractiveMode {
1672
1680
  this.statusContainer.addChild(this.idleStatus);
1673
1681
  }
1674
1682
  }
1683
+ showWorkingStatusIndicator() {
1684
+ this.showStatusIndicator(new WorkingStatusIndicator(this.ui, this.workingMessage ?? this.defaultWorkingMessage, this.workingIndicatorOptions));
1685
+ }
1675
1686
  setWorkingVisible(visible) {
1676
1687
  this.workingVisible = visible;
1677
1688
  if (!visible) {
@@ -1680,7 +1691,7 @@ export class InteractiveMode {
1680
1691
  return;
1681
1692
  }
1682
1693
  if (this.session.isStreaming && this.activeStatusIndicator?.kind !== "working") {
1683
- this.showStatusIndicator(new WorkingStatusIndicator(this.ui, this.workingMessage ?? this.defaultWorkingMessage, this.workingIndicatorOptions));
1694
+ this.showWorkingStatusIndicator();
1684
1695
  }
1685
1696
  this.ui.requestRender();
1686
1697
  }
@@ -2300,7 +2311,7 @@ export class InteractiveMode {
2300
2311
  this.defaultEditor.onAction("app.tools.expand", () => this.toggleToolOutputExpansion());
2301
2312
  this.defaultEditor.onAction("app.thinking.toggle", () => this.toggleThinkingBlockVisibility());
2302
2313
  this.defaultEditor.onAction("app.editor.external", () => void this.handleOpenExternalEditor());
2303
- this.defaultEditor.onAction("app.message.copy", () => void this.handleCopyCommand({ flashConfirmation: true }));
2314
+ this.defaultEditor.onAction("app.message.copy", () => void this.handleCopyCommand({ flashConfirmation: true, preferSelection: true }));
2304
2315
  this.defaultEditor.onAction("app.message.followUp", () => this.handleFollowUp());
2305
2316
  this.defaultEditor.onAction("app.message.dequeue", () => this.handleDequeue());
2306
2317
  this.defaultEditor.onAction("app.session.new", () => this.handleClearCommand());
@@ -2567,17 +2578,21 @@ export class InteractiveMode {
2567
2578
  switch (event.type) {
2568
2579
  case "agent_start":
2569
2580
  this.pendingTools.clear();
2570
- if (this.settingsManager.getShowTerminalProgress()) {
2571
- this.ui.terminal.setProgress(true);
2572
- }
2573
2581
  // Restore main escape handler if retry handler is still active
2574
2582
  // (retry success event fires later, but we need main handler now)
2575
2583
  if (this.retryEscapeHandler) {
2576
2584
  this.defaultEditor.onEscape = this.retryEscapeHandler;
2577
2585
  this.retryEscapeHandler = undefined;
2578
2586
  }
2587
+ break;
2588
+ case "turn_start":
2589
+ if (this.settingsManager.getShowTerminalProgress()) {
2590
+ this.ui.terminal.setProgress(true);
2591
+ }
2579
2592
  if (this.workingVisible) {
2580
- this.showStatusIndicator(new WorkingStatusIndicator(this.ui, this.workingMessage ?? this.defaultWorkingMessage, this.workingIndicatorOptions));
2593
+ if (this.activeStatusIndicator?.kind !== "working") {
2594
+ this.showWorkingStatusIndicator();
2595
+ }
2581
2596
  }
2582
2597
  else {
2583
2598
  this.clearStatusIndicator();
@@ -3447,18 +3462,19 @@ export class InteractiveMode {
3447
3462
  }
3448
3463
  this.showStatus(`Tool output: ${expanded ? "expanded" : "collapsed"}`);
3449
3464
  }
3465
+ /** Update rendered assistant messages without rebuilding live tool components. */
3466
+ updateThinkingBlockVisibility() {
3467
+ for (const child of this.chatContainer.children) {
3468
+ if (child instanceof AssistantMessageComponent) {
3469
+ child.setHideThinkingBlock(this.hideThinkingBlock);
3470
+ }
3471
+ }
3472
+ this.ui.requestRender();
3473
+ }
3450
3474
  toggleThinkingBlockVisibility() {
3451
3475
  this.hideThinkingBlock = !this.hideThinkingBlock;
3452
3476
  this.settingsManager.setHideThinkingBlock(this.hideThinkingBlock);
3453
- // Rebuild chat from session messages
3454
- this.chatContainer.clear();
3455
- this.rebuildChatFromMessages();
3456
- // If streaming, re-add the streaming component with updated visibility and re-render
3457
- if (this.streamingComponent && this.streamingMessage) {
3458
- this.streamingComponent.setHideThinkingBlock(this.hideThinkingBlock);
3459
- this.streamingComponent.updateContent(this.streamingMessage);
3460
- this.chatContainer.addChild(this.streamingComponent);
3461
- }
3477
+ this.updateThinkingBlockVisibility();
3462
3478
  this.showStatus(`Thinking blocks: ${this.hideThinkingBlock ? "hidden" : "visible"}`);
3463
3479
  }
3464
3480
  async handleOpenExternalEditor() {
@@ -3775,6 +3791,7 @@ export class InteractiveMode {
3775
3791
  tuiMode: this.ui.mode,
3776
3792
  fullscreenExitOutput: this.settingsManager.getFullscreenExitOutput(),
3777
3793
  fullscreenScrollbar: this.settingsManager.getFullscreenScrollbar(),
3794
+ fullscreenCopyOnSelect: this.settingsManager.getFullscreenCopyOnSelect(),
3778
3795
  warnings: this.settingsManager.getWarnings(),
3779
3796
  }, {
3780
3797
  onAutoCompactChange: (enabled) => {
@@ -3851,13 +3868,7 @@ export class InteractiveMode {
3851
3868
  onHideThinkingBlockChange: (hidden) => {
3852
3869
  this.hideThinkingBlock = hidden;
3853
3870
  this.settingsManager.setHideThinkingBlock(hidden);
3854
- for (const child of this.chatContainer.children) {
3855
- if (child instanceof AssistantMessageComponent) {
3856
- child.setHideThinkingBlock(hidden);
3857
- }
3858
- }
3859
- this.chatContainer.clear();
3860
- this.rebuildChatFromMessages();
3871
+ this.updateThinkingBlockVisibility();
3861
3872
  },
3862
3873
  onMermaidRenderingModeChange: (mode) => {
3863
3874
  this.settingsManager.setMermaidRenderingMode(mode);
@@ -3951,6 +3962,11 @@ export class InteractiveMode {
3951
3962
  this.settingsManager.setFullscreenScrollbar(mode);
3952
3963
  this.applyFullscreenScrollbarSetting();
3953
3964
  },
3965
+ onFullscreenCopyOnSelectChange: (enabled) => {
3966
+ this.settingsManager.setFullscreenCopyOnSelect(enabled);
3967
+ if (this.renderer instanceof TuiAltScreen)
3968
+ this.renderer.setCopyOnSelect(enabled);
3969
+ },
3954
3970
  onWarningsChange: (warnings) => {
3955
3971
  this.settingsManager.setWarnings(warnings);
3956
3972
  },
@@ -4140,6 +4156,7 @@ export class InteractiveMode {
4140
4156
  const selectModel = async (model, persist) => {
4141
4157
  try {
4142
4158
  await this.session.setModel(model, { persist });
4159
+ this.updateAvailableProviderCount();
4143
4160
  this.footer.invalidate();
4144
4161
  this.updateEditorBorderColor();
4145
4162
  done();
@@ -4988,8 +5005,8 @@ export class InteractiveMode {
4988
5005
  activeHeader.setExpanded(this.toolOutputExpanded);
4989
5006
  }
4990
5007
  setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
4991
- await this.themeController.applyFromSettings();
4992
5008
  this.applyRuntimeSettings();
5009
+ await this.themeController.applyFromSettings();
4993
5010
  this.setupAutocompleteProvider();
4994
5011
  const runner = this.session.extensionRunner;
4995
5012
  this.setupExtensionShortcuts(runner);
@@ -5111,6 +5128,13 @@ export class InteractiveMode {
5111
5128
  });
5112
5129
  }
5113
5130
  async handleCopyCommand(options = {}) {
5131
+ if (options.preferSelection &&
5132
+ this.ui instanceof TuiAltScreen &&
5133
+ !this.ui.getCopyOnSelect() &&
5134
+ this.ui.hasActiveSelection()) {
5135
+ await this.ui.copyActiveSelectionToClipboard();
5136
+ return;
5137
+ }
5114
5138
  const text = this.session.getLastAssistantText();
5115
5139
  if (!text) {
5116
5140
  this.showError("No agent messages to copy yet.");