@vaclav-synacek/pi-coding-agent-termux 0.50.1-0 → 0.50.7-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.
Files changed (96) hide show
  1. package/CHANGELOG.md +108 -1
  2. package/dist/cli/args.d.ts.map +1 -1
  3. package/dist/cli/args.js +1 -0
  4. package/dist/cli/args.js.map +1 -1
  5. package/dist/core/agent-session.d.ts +8 -0
  6. package/dist/core/agent-session.d.ts.map +1 -1
  7. package/dist/core/agent-session.js +29 -13
  8. package/dist/core/agent-session.js.map +1 -1
  9. package/dist/core/defaults.d.ts +3 -0
  10. package/dist/core/defaults.d.ts.map +1 -0
  11. package/dist/core/defaults.js +2 -0
  12. package/dist/core/defaults.js.map +1 -0
  13. package/dist/core/extensions/runner.d.ts +5 -0
  14. package/dist/core/extensions/runner.d.ts.map +1 -1
  15. package/dist/core/extensions/runner.js +12 -0
  16. package/dist/core/extensions/runner.js.map +1 -1
  17. package/dist/core/extensions/types.d.ts +3 -0
  18. package/dist/core/extensions/types.d.ts.map +1 -1
  19. package/dist/core/extensions/types.js.map +1 -1
  20. package/dist/core/model-registry.d.ts.map +1 -1
  21. package/dist/core/model-registry.js +6 -0
  22. package/dist/core/model-registry.js.map +1 -1
  23. package/dist/core/model-resolver.d.ts.map +1 -1
  24. package/dist/core/model-resolver.js +9 -6
  25. package/dist/core/model-resolver.js.map +1 -1
  26. package/dist/core/package-manager.d.ts.map +1 -1
  27. package/dist/core/package-manager.js +102 -20
  28. package/dist/core/package-manager.js.map +1 -1
  29. package/dist/core/prompt-templates.d.ts.map +1 -1
  30. package/dist/core/prompt-templates.js.map +1 -1
  31. package/dist/core/sdk.d.ts +1 -1
  32. package/dist/core/sdk.d.ts.map +1 -1
  33. package/dist/core/sdk.js +3 -2
  34. package/dist/core/sdk.js.map +1 -1
  35. package/dist/core/settings-manager.d.ts +11 -3
  36. package/dist/core/settings-manager.d.ts.map +1 -1
  37. package/dist/core/settings-manager.js +96 -16
  38. package/dist/core/settings-manager.js.map +1 -1
  39. package/dist/core/tools/path-utils.d.ts.map +1 -1
  40. package/dist/core/tools/path-utils.js +28 -3
  41. package/dist/core/tools/path-utils.js.map +1 -1
  42. package/dist/main.d.ts.map +1 -1
  43. package/dist/main.js +2 -1
  44. package/dist/main.js.map +1 -1
  45. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  46. package/dist/modes/interactive/components/config-selector.js +12 -1
  47. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  48. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  49. package/dist/modes/interactive/components/custom-editor.js +2 -1
  50. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  51. package/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  52. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
  53. package/dist/modes/interactive/components/daxnuts.js +140 -0
  54. package/dist/modes/interactive/components/daxnuts.js.map +1 -0
  55. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  56. package/dist/modes/interactive/components/footer.js +17 -13
  57. package/dist/modes/interactive/components/footer.js.map +1 -1
  58. package/dist/modes/interactive/components/index.d.ts +1 -0
  59. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  60. package/dist/modes/interactive/components/index.js +1 -0
  61. package/dist/modes/interactive/components/index.js.map +1 -1
  62. package/dist/modes/interactive/components/settings-selector.d.ts +4 -2
  63. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  64. package/dist/modes/interactive/components/settings-selector.js +13 -1
  65. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  66. package/dist/modes/interactive/interactive-mode.d.ts +3 -0
  67. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  68. package/dist/modes/interactive/interactive-mode.js +81 -37
  69. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  70. package/dist/modes/rpc/rpc-client.d.ts +9 -1
  71. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  72. package/dist/modes/rpc/rpc-client.js +13 -0
  73. package/dist/modes/rpc/rpc-client.js.map +1 -1
  74. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  75. package/dist/modes/rpc/rpc-mode.js +45 -0
  76. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  77. package/dist/modes/rpc/rpc-types.d.ts +34 -0
  78. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  79. package/dist/modes/rpc/rpc-types.js.map +1 -1
  80. package/dist/utils/clipboard.d.ts.map +1 -1
  81. package/dist/utils/clipboard.js +4 -0
  82. package/dist/utils/clipboard.js.map +1 -1
  83. package/docs/extensions.md +12 -0
  84. package/docs/keybindings.md +7 -5
  85. package/docs/models.md +32 -0
  86. package/docs/providers.md +4 -1
  87. package/docs/rpc.md +62 -1
  88. package/docs/settings.md +1 -0
  89. package/examples/extensions/antigravity-image-gen.ts +1 -1
  90. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  91. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  92. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  93. package/examples/extensions/system-prompt-header.ts +17 -0
  94. package/examples/extensions/with-deps/package-lock.json +2 -2
  95. package/examples/extensions/with-deps/package.json +1 -1
  96. package/package.json +5 -4
@@ -28,6 +28,7 @@ import { BranchSummaryMessageComponent } from "./components/branch-summary-messa
28
28
  import { CompactionSummaryMessageComponent } from "./components/compaction-summary-message.js";
29
29
  import { CustomEditor } from "./components/custom-editor.js";
30
30
  import { CustomMessageComponent } from "./components/custom-message.js";
31
+ import { DaxnutsComponent } from "./components/daxnuts.js";
31
32
  import { DynamicBorder } from "./components/dynamic-border.js";
32
33
  import { ExtensionEditorComponent } from "./components/extension-editor.js";
33
34
  import { ExtensionInputComponent } from "./components/extension-input.js";
@@ -116,6 +117,8 @@ export class InteractiveMode {
116
117
  widgetContainerBelow;
117
118
  // Custom footer from extension (undefined = use built-in footer)
118
119
  customFooter = undefined;
120
+ // Header container that holds the built-in or custom header
121
+ headerContainer;
119
122
  // Built-in header (logo + keybinding hints + changelog)
120
123
  builtInHeader = undefined;
121
124
  // Custom header from extension (undefined = use built-in header)
@@ -135,6 +138,7 @@ export class InteractiveMode {
135
138
  this.session = session;
136
139
  this.version = VERSION;
137
140
  this.ui = new TUI(new ProcessTerminal(), this.settingsManager.getShowHardwareCursor());
141
+ this.headerContainer = new Container();
138
142
  this.chatContainer = new Container();
139
143
  this.pendingMessagesContainer = new Container();
140
144
  this.statusContainer = new Container();
@@ -142,7 +146,11 @@ export class InteractiveMode {
142
146
  this.widgetContainerBelow = new Container();
143
147
  this.keybindings = KeybindingsManager.create();
144
148
  const editorPaddingX = this.settingsManager.getEditorPaddingX();
145
- this.defaultEditor = new CustomEditor(this.ui, getEditorTheme(), this.keybindings, { paddingX: editorPaddingX });
149
+ const autocompleteMaxVisible = this.settingsManager.getAutocompleteMaxVisible();
150
+ this.defaultEditor = new CustomEditor(this.ui, getEditorTheme(), this.keybindings, {
151
+ paddingX: editorPaddingX,
152
+ autocompleteMaxVisible,
153
+ });
146
154
  this.editor = this.defaultEditor;
147
155
  this.editorContainer = new Container();
148
156
  this.editorContainer.addChild(this.editor);
@@ -239,6 +247,8 @@ export class InteractiveMode {
239
247
  // Setup autocomplete with fd tool for file path completion
240
248
  this.fdPath = await ensureTool("fd");
241
249
  this.setupAutocomplete(this.fdPath);
250
+ // Add header container as first child
251
+ this.ui.addChild(this.headerContainer);
242
252
  // Add header with keybindings from config (unless silenced)
243
253
  if (this.options.verbose || !this.settingsManager.getQuietStartup()) {
244
254
  const logo = theme.bold(theme.fg("accent", APP_NAME)) + theme.fg("dim", ` v${this.version}`);
@@ -268,37 +278,38 @@ export class InteractiveMode {
268
278
  ].join("\n");
269
279
  this.builtInHeader = new Text(`${logo}\n${instructions}`, 1, 0);
270
280
  // Setup UI layout
271
- this.ui.addChild(new Spacer(1));
272
- this.ui.addChild(this.builtInHeader);
273
- this.ui.addChild(new Spacer(1));
281
+ this.headerContainer.addChild(new Spacer(1));
282
+ this.headerContainer.addChild(this.builtInHeader);
283
+ this.headerContainer.addChild(new Spacer(1));
274
284
  // Add changelog if provided
275
285
  if (this.changelogMarkdown) {
276
- this.ui.addChild(new DynamicBorder());
286
+ this.headerContainer.addChild(new DynamicBorder());
277
287
  if (this.settingsManager.getCollapseChangelog()) {
278
288
  const versionMatch = this.changelogMarkdown.match(/##\s+\[?(\d+\.\d+\.\d+)\]?/);
279
289
  const latestVersion = versionMatch ? versionMatch[1] : this.version;
280
290
  const condensedText = `Updated to v${latestVersion}. Use ${theme.bold("/changelog")} to view full changelog.`;
281
- this.ui.addChild(new Text(condensedText, 1, 0));
291
+ this.headerContainer.addChild(new Text(condensedText, 1, 0));
282
292
  }
283
293
  else {
284
- this.ui.addChild(new Text(theme.bold(theme.fg("accent", "What's New")), 1, 0));
285
- this.ui.addChild(new Spacer(1));
286
- this.ui.addChild(new Markdown(this.changelogMarkdown.trim(), 1, 0, this.getMarkdownThemeWithSettings()));
287
- this.ui.addChild(new Spacer(1));
294
+ this.headerContainer.addChild(new Text(theme.bold(theme.fg("accent", "What's New")), 1, 0));
295
+ this.headerContainer.addChild(new Spacer(1));
296
+ this.headerContainer.addChild(new Markdown(this.changelogMarkdown.trim(), 1, 0, this.getMarkdownThemeWithSettings()));
297
+ this.headerContainer.addChild(new Spacer(1));
288
298
  }
289
- this.ui.addChild(new DynamicBorder());
299
+ this.headerContainer.addChild(new DynamicBorder());
290
300
  }
291
301
  }
292
302
  else {
293
303
  // Minimal header when silenced
294
304
  this.builtInHeader = new Text("", 0, 0);
305
+ this.headerContainer.addChild(this.builtInHeader);
295
306
  if (this.changelogMarkdown) {
296
307
  // Still show changelog notification even in silent mode
297
- this.ui.addChild(new Spacer(1));
308
+ this.headerContainer.addChild(new Spacer(1));
298
309
  const versionMatch = this.changelogMarkdown.match(/##\s+\[?(\d+\.\d+\.\d+)\]?/);
299
310
  const latestVersion = versionMatch ? versionMatch[1] : this.version;
300
311
  const condensedText = `Updated to v${latestVersion}. Use ${theme.bold("/changelog")} to view full changelog.`;
301
- this.ui.addChild(new Text(condensedText, 1, 0));
312
+ this.headerContainer.addChild(new Text(condensedText, 1, 0));
302
313
  }
303
314
  }
304
315
  this.ui.addChild(this.chatContainer);
@@ -312,13 +323,15 @@ export class InteractiveMode {
312
323
  this.ui.setFocus(this.editor);
313
324
  this.setupKeyHandlers();
314
325
  this.setupEditorSubmitHandler();
326
+ // Initialize extensions first so resources are shown before messages
327
+ await this.initExtensions();
328
+ // Render initial messages AFTER showing loaded resources
329
+ this.renderInitialMessages();
315
330
  // Start the UI
316
331
  this.ui.start();
317
332
  this.isInitialized = true;
318
333
  // Set terminal title
319
334
  this.updateTerminalTitle();
320
- // Initialize extensions with TUI-based UI context
321
- await this.initExtensions();
322
335
  // Subscribe to agent events
323
336
  this.subscribeToAgent();
324
337
  // Set up theme file watcher
@@ -359,7 +372,6 @@ export class InteractiveMode {
359
372
  this.showNewVersionNotification(newVersion);
360
373
  }
361
374
  });
362
- this.renderInitialMessages();
363
375
  // Show startup warnings
364
376
  const { migratedProviders, modelFallbackMessage, initialMessage, initialImages, initialMessages } = this.options;
365
377
  if (migratedProviders && migratedProviders.length > 0) {
@@ -858,6 +870,7 @@ export class InteractiveMode {
858
870
  }
859
871
  })();
860
872
  },
873
+ getSystemPrompt: () => this.session.systemPrompt,
861
874
  });
862
875
  // Set up the extension shortcut handler on the default editor
863
876
  this.defaultEditor.onExtensionShortcut = (data) => {
@@ -1018,22 +1031,26 @@ export class InteractiveMode {
1018
1031
  if (this.customHeader?.dispose) {
1019
1032
  this.customHeader.dispose();
1020
1033
  }
1021
- // Remove current header from UI
1022
- if (this.customHeader) {
1023
- this.ui.removeChild(this.customHeader);
1024
- }
1025
- else {
1026
- this.ui.removeChild(this.builtInHeader);
1027
- }
1034
+ // Find the index of the current header in the header container
1035
+ const currentHeader = this.customHeader || this.builtInHeader;
1036
+ const index = this.headerContainer.children.indexOf(currentHeader);
1028
1037
  if (factory) {
1029
- // Create and add custom header at position 1 (after initial spacer)
1038
+ // Create and add custom header
1030
1039
  this.customHeader = factory(this.ui, theme);
1031
- this.ui.children.splice(1, 0, this.customHeader);
1040
+ if (index !== -1) {
1041
+ this.headerContainer.children[index] = this.customHeader;
1042
+ }
1043
+ else {
1044
+ // If not found (e.g. builtInHeader was never added), add at the top
1045
+ this.headerContainer.children.unshift(this.customHeader);
1046
+ }
1032
1047
  }
1033
1048
  else {
1034
- // Restore built-in header at position 1
1049
+ // Restore built-in header
1035
1050
  this.customHeader = undefined;
1036
- this.ui.children.splice(1, 0, this.builtInHeader);
1051
+ if (index !== -1) {
1052
+ this.headerContainer.children[index] = this.builtInHeader;
1053
+ }
1037
1054
  }
1038
1055
  this.ui.requestRender();
1039
1056
  }
@@ -1377,19 +1394,22 @@ export class InteractiveMode {
1377
1394
  this.updateEditorBorderColor();
1378
1395
  }
1379
1396
  else if (!this.editor.getText().trim()) {
1380
- // Double-escape with empty editor triggers /tree or /fork based on setting
1381
- const now = Date.now();
1382
- if (now - this.lastEscapeTime < 500) {
1383
- if (this.settingsManager.getDoubleEscapeAction() === "tree") {
1384
- this.showTreeSelector();
1397
+ // Double-escape with empty editor triggers /tree, /fork, or nothing based on setting
1398
+ const action = this.settingsManager.getDoubleEscapeAction();
1399
+ if (action !== "none") {
1400
+ const now = Date.now();
1401
+ if (now - this.lastEscapeTime < 500) {
1402
+ if (action === "tree") {
1403
+ this.showTreeSelector();
1404
+ }
1405
+ else {
1406
+ this.showUserMessageSelector();
1407
+ }
1408
+ this.lastEscapeTime = 0;
1385
1409
  }
1386
1410
  else {
1387
- this.showUserMessageSelector();
1411
+ this.lastEscapeTime = now;
1388
1412
  }
1389
- this.lastEscapeTime = 0;
1390
- }
1391
- else {
1392
- this.lastEscapeTime = now;
1393
1413
  }
1394
1414
  }
1395
1415
  };
@@ -2477,6 +2497,7 @@ export class InteractiveMode {
2477
2497
  doubleEscapeAction: this.settingsManager.getDoubleEscapeAction(),
2478
2498
  showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
2479
2499
  editorPaddingX: this.settingsManager.getEditorPaddingX(),
2500
+ autocompleteMaxVisible: this.settingsManager.getAutocompleteMaxVisible(),
2480
2501
  quietStartup: this.settingsManager.getQuietStartup(),
2481
2502
  }, {
2482
2503
  onAutoCompactChange: (enabled) => {
@@ -2558,6 +2579,13 @@ export class InteractiveMode {
2558
2579
  this.editor.setPaddingX(padding);
2559
2580
  }
2560
2581
  },
2582
+ onAutocompleteMaxVisibleChange: (maxVisible) => {
2583
+ this.settingsManager.setAutocompleteMaxVisible(maxVisible);
2584
+ this.defaultEditor.setAutocompleteMaxVisible(maxVisible);
2585
+ if (this.editor !== this.defaultEditor && this.editor.setAutocompleteMaxVisible !== undefined) {
2586
+ this.editor.setAutocompleteMaxVisible(maxVisible);
2587
+ }
2588
+ },
2561
2589
  onCancel: () => {
2562
2590
  done();
2563
2591
  this.ui.requestRender();
@@ -2578,6 +2606,7 @@ export class InteractiveMode {
2578
2606
  this.footer.invalidate();
2579
2607
  this.updateEditorBorderColor();
2580
2608
  this.showStatus(`Model: ${model.id}`);
2609
+ this.checkDaxnutsEasterEgg(model);
2581
2610
  }
2582
2611
  catch (error) {
2583
2612
  this.showError(error instanceof Error ? error.message : String(error));
@@ -2637,6 +2666,7 @@ export class InteractiveMode {
2637
2666
  this.updateEditorBorderColor();
2638
2667
  done();
2639
2668
  this.showStatus(`Model: ${model.id}`);
2669
+ this.checkDaxnutsEasterEgg(model);
2640
2670
  }
2641
2671
  catch (error) {
2642
2672
  done();
@@ -3310,6 +3340,8 @@ export class InteractiveMode {
3310
3340
  const cursorWordRight = this.getEditorKeyDisplay("cursorWordRight");
3311
3341
  const cursorLineStart = this.getEditorKeyDisplay("cursorLineStart");
3312
3342
  const cursorLineEnd = this.getEditorKeyDisplay("cursorLineEnd");
3343
+ const jumpForward = this.getEditorKeyDisplay("jumpForward");
3344
+ const jumpBackward = this.getEditorKeyDisplay("jumpBackward");
3313
3345
  const pageUp = this.getEditorKeyDisplay("pageUp");
3314
3346
  const pageDown = this.getEditorKeyDisplay("pageDown");
3315
3347
  // Editing keybindings
@@ -3344,6 +3376,8 @@ export class InteractiveMode {
3344
3376
  | \`${cursorWordLeft}\` / \`${cursorWordRight}\` | Move by word |
3345
3377
  | \`${cursorLineStart}\` | Start of line |
3346
3378
  | \`${cursorLineEnd}\` | End of line |
3379
+ | \`${jumpForward}\` | Jump forward to character |
3380
+ | \`${jumpBackward}\` | Jump backward to character |
3347
3381
  | \`${pageUp}\` / \`${pageDown}\` | Scroll by page |
3348
3382
 
3349
3383
  **Editing**
@@ -3457,6 +3491,16 @@ export class InteractiveMode {
3457
3491
  this.chatContainer.addChild(new ArminComponent(this.ui));
3458
3492
  this.ui.requestRender();
3459
3493
  }
3494
+ handleDaxnuts() {
3495
+ this.chatContainer.addChild(new Spacer(1));
3496
+ this.chatContainer.addChild(new DaxnutsComponent(this.ui));
3497
+ this.ui.requestRender();
3498
+ }
3499
+ checkDaxnutsEasterEgg(model) {
3500
+ if (model.provider === "opencode" && model.id.toLowerCase().includes("kimi-k2.5")) {
3501
+ this.handleDaxnuts();
3502
+ }
3503
+ }
3460
3504
  async handleBashCommand(command, excludeFromContext = false) {
3461
3505
  const extensionRunner = this.session.extensionRunner;
3462
3506
  // Emit user_bash event to let extensions intercept