@mariozechner/pi-coding-agent 0.49.1 → 0.49.2

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 (51) hide show
  1. package/CHANGELOG.md +23 -1
  2. package/README.md +2 -9
  3. package/dist/core/agent-session.d.ts.map +1 -1
  4. package/dist/core/agent-session.js +6 -0
  5. package/dist/core/agent-session.js.map +1 -1
  6. package/dist/core/export-html/template.css +19 -0
  7. package/dist/core/export-html/template.js +70 -5
  8. package/dist/core/extensions/index.d.ts +1 -1
  9. package/dist/core/extensions/index.d.ts.map +1 -1
  10. package/dist/core/extensions/index.js.map +1 -1
  11. package/dist/core/extensions/types.d.ts +10 -3
  12. package/dist/core/extensions/types.d.ts.map +1 -1
  13. package/dist/core/extensions/types.js.map +1 -1
  14. package/dist/core/model-registry.d.ts.map +1 -1
  15. package/dist/core/model-registry.js +1 -3
  16. package/dist/core/model-registry.js.map +1 -1
  17. package/dist/core/sdk.d.ts.map +1 -1
  18. package/dist/core/sdk.js +9 -1
  19. package/dist/core/sdk.js.map +1 -1
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/main.d.ts.map +1 -1
  24. package/dist/main.js +2 -1
  25. package/dist/main.js.map +1 -1
  26. package/dist/modes/interactive/components/model-selector.d.ts +9 -0
  27. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  28. package/dist/modes/interactive/components/model-selector.js +84 -38
  29. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  30. package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  31. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  32. package/dist/modes/interactive/components/settings-selector.js +10 -0
  33. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  34. package/dist/modes/interactive/interactive-mode.d.ts +5 -2
  35. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  36. package/dist/modes/interactive/interactive-mode.js +48 -25
  37. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  38. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  39. package/dist/modes/rpc/rpc-mode.js +2 -1
  40. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  41. package/dist/modes/rpc/rpc-types.d.ts +1 -0
  42. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  43. package/dist/modes/rpc/rpc-types.js.map +1 -1
  44. package/docs/extensions.md +5 -3
  45. package/docs/tui.md +6 -3
  46. package/examples/extensions/README.md +1 -0
  47. package/examples/extensions/question.ts +9 -22
  48. package/examples/extensions/widget-placement.ts +17 -0
  49. package/examples/extensions/with-deps/package-lock.json +2 -2
  50. package/examples/extensions/with-deps/package.json +1 -1
  51. package/package.json +4 -4
@@ -108,9 +108,11 @@ export class InteractiveMode {
108
108
  extensionSelector = undefined;
109
109
  extensionInput = undefined;
110
110
  extensionEditor = undefined;
111
- // Extension widgets (components rendered above the editor)
112
- extensionWidgets = new Map();
113
- widgetContainer;
111
+ // Extension widgets (components rendered above/below the editor)
112
+ extensionWidgetsAbove = new Map();
113
+ extensionWidgetsBelow = new Map();
114
+ widgetContainerAbove;
115
+ widgetContainerBelow;
114
116
  // Custom footer from extension (undefined = use built-in footer)
115
117
  customFooter = undefined;
116
118
  // Built-in header (logo + keybinding hints + changelog)
@@ -135,7 +137,8 @@ export class InteractiveMode {
135
137
  this.chatContainer = new Container();
136
138
  this.pendingMessagesContainer = new Container();
137
139
  this.statusContainer = new Container();
138
- this.widgetContainer = new Container();
140
+ this.widgetContainerAbove = new Container();
141
+ this.widgetContainerBelow = new Container();
139
142
  this.keybindings = KeybindingsManager.create();
140
143
  const editorPaddingX = this.settingsManager.getEditorPaddingX();
141
144
  this.defaultEditor = new CustomEditor(this.ui, getEditorTheme(), this.keybindings, { paddingX: editorPaddingX });
@@ -298,9 +301,10 @@ export class InteractiveMode {
298
301
  this.ui.addChild(this.chatContainer);
299
302
  this.ui.addChild(this.pendingMessagesContainer);
300
303
  this.ui.addChild(this.statusContainer);
301
- this.ui.addChild(this.widgetContainer);
302
304
  this.renderWidgets(); // Initialize with default spacer
305
+ this.ui.addChild(this.widgetContainerAbove);
303
306
  this.ui.addChild(this.editorContainer);
307
+ this.ui.addChild(this.widgetContainerBelow);
304
308
  this.ui.addChild(this.footer);
305
309
  this.ui.setFocus(this.editor);
306
310
  this.setupKeyHandlers();
@@ -697,15 +701,22 @@ export class InteractiveMode {
697
701
  /**
698
702
  * Set an extension widget (string array or custom component).
699
703
  */
700
- setExtensionWidget(key, content) {
701
- // Dispose and remove existing widget
702
- const existing = this.extensionWidgets.get(key);
703
- if (existing?.dispose)
704
- existing.dispose();
704
+ setExtensionWidget(key, content, options) {
705
+ const placement = options?.placement ?? "aboveEditor";
706
+ const removeExisting = (map) => {
707
+ const existing = map.get(key);
708
+ if (existing?.dispose)
709
+ existing.dispose();
710
+ map.delete(key);
711
+ };
712
+ removeExisting(this.extensionWidgetsAbove);
713
+ removeExisting(this.extensionWidgetsBelow);
705
714
  if (content === undefined) {
706
- this.extensionWidgets.delete(key);
715
+ this.renderWidgets();
716
+ return;
707
717
  }
708
- else if (Array.isArray(content)) {
718
+ let component;
719
+ if (Array.isArray(content)) {
709
720
  // Wrap string array in a Container with Text components
710
721
  const container = new Container();
711
722
  for (const line of content.slice(0, InteractiveMode.MAX_WIDGET_LINES)) {
@@ -714,13 +725,14 @@ export class InteractiveMode {
714
725
  if (content.length > InteractiveMode.MAX_WIDGET_LINES) {
715
726
  container.addChild(new Text(theme.fg("muted", "... (widget truncated)"), 1, 0));
716
727
  }
717
- this.extensionWidgets.set(key, container);
728
+ component = container;
718
729
  }
719
730
  else {
720
731
  // Factory function - create component
721
- const component = content(this.ui, theme);
722
- this.extensionWidgets.set(key, component);
732
+ component = content(this.ui, theme);
723
733
  }
734
+ const targetMap = placement === "belowEditor" ? this.extensionWidgetsBelow : this.extensionWidgetsAbove;
735
+ targetMap.set(key, component);
724
736
  this.renderWidgets();
725
737
  }
726
738
  // Maximum total widget lines to prevent viewport overflow
@@ -729,19 +741,26 @@ export class InteractiveMode {
729
741
  * Render all extension widgets to the widget container.
730
742
  */
731
743
  renderWidgets() {
732
- if (!this.widgetContainer)
744
+ if (!this.widgetContainerAbove || !this.widgetContainerBelow)
733
745
  return;
734
- this.widgetContainer.clear();
735
- if (this.extensionWidgets.size === 0) {
736
- this.widgetContainer.addChild(new Spacer(1));
737
- this.ui.requestRender();
746
+ this.renderWidgetContainer(this.widgetContainerAbove, this.extensionWidgetsAbove, true, true);
747
+ this.renderWidgetContainer(this.widgetContainerBelow, this.extensionWidgetsBelow, false, false);
748
+ this.ui.requestRender();
749
+ }
750
+ renderWidgetContainer(container, widgets, spacerWhenEmpty, leadingSpacer) {
751
+ container.clear();
752
+ if (widgets.size === 0) {
753
+ if (spacerWhenEmpty) {
754
+ container.addChild(new Spacer(1));
755
+ }
738
756
  return;
739
757
  }
740
- this.widgetContainer.addChild(new Spacer(1));
741
- for (const [_key, component] of this.extensionWidgets) {
742
- this.widgetContainer.addChild(component);
758
+ if (leadingSpacer) {
759
+ container.addChild(new Spacer(1));
760
+ }
761
+ for (const component of widgets.values()) {
762
+ container.addChild(component);
743
763
  }
744
- this.ui.requestRender();
745
764
  }
746
765
  /**
747
766
  * Set a custom footer component, or restore the built-in footer.
@@ -821,7 +840,7 @@ export class InteractiveMode {
821
840
  }
822
841
  }
823
842
  },
824
- setWidget: (key, content) => this.setExtensionWidget(key, content),
843
+ setWidget: (key, content, options) => this.setExtensionWidget(key, content, options),
825
844
  setFooter: (factory) => this.setExtensionFooter(factory),
826
845
  setHeader: (factory) => this.setExtensionHeader(factory),
827
846
  setTitle: (title) => this.ui.terminal.setTitle(title),
@@ -2179,6 +2198,7 @@ export class InteractiveMode {
2179
2198
  doubleEscapeAction: this.settingsManager.getDoubleEscapeAction(),
2180
2199
  showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
2181
2200
  editorPaddingX: this.settingsManager.getEditorPaddingX(),
2201
+ quietStartup: this.settingsManager.getQuietStartup(),
2182
2202
  }, {
2183
2203
  onAutoCompactChange: (enabled) => {
2184
2204
  this.session.setAutoCompactionEnabled(enabled);
@@ -2242,6 +2262,9 @@ export class InteractiveMode {
2242
2262
  onCollapseChangelogChange: (collapsed) => {
2243
2263
  this.settingsManager.setCollapseChangelog(collapsed);
2244
2264
  },
2265
+ onQuietStartupChange: (enabled) => {
2266
+ this.settingsManager.setQuietStartup(enabled);
2267
+ },
2245
2268
  onDoubleEscapeActionChange: (action) => {
2246
2269
  this.settingsManager.setDoubleEscapeAction(action);
2247
2270
  },