@mariozechner/pi-coding-agent 0.52.6 → 0.52.8

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 (52) hide show
  1. package/CHANGELOG.md +55 -0
  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.map +1 -1
  6. package/dist/core/agent-session.js +7 -0
  7. package/dist/core/agent-session.js.map +1 -1
  8. package/dist/core/auth-storage.d.ts.map +1 -1
  9. package/dist/core/auth-storage.js +16 -0
  10. package/dist/core/auth-storage.js.map +1 -1
  11. package/dist/core/extensions/runner.d.ts +17 -2
  12. package/dist/core/extensions/runner.d.ts.map +1 -1
  13. package/dist/core/extensions/runner.js +54 -9
  14. package/dist/core/extensions/runner.js.map +1 -1
  15. package/dist/core/extensions/types.d.ts +2 -0
  16. package/dist/core/extensions/types.d.ts.map +1 -1
  17. package/dist/core/extensions/types.js.map +1 -1
  18. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  19. package/dist/core/extensions/wrapper.js +3 -3
  20. package/dist/core/extensions/wrapper.js.map +1 -1
  21. package/dist/core/model-registry.d.ts +3 -1
  22. package/dist/core/model-registry.d.ts.map +1 -1
  23. package/dist/core/model-registry.js +133 -37
  24. package/dist/core/model-registry.js.map +1 -1
  25. package/dist/core/package-manager.d.ts +1 -0
  26. package/dist/core/package-manager.d.ts.map +1 -1
  27. package/dist/core/package-manager.js +21 -2
  28. package/dist/core/package-manager.js.map +1 -1
  29. package/dist/main.d.ts.map +1 -1
  30. package/dist/main.js +165 -72
  31. package/dist/main.js.map +1 -1
  32. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  33. package/dist/modes/interactive/components/assistant-message.js +9 -4
  34. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  35. package/dist/modes/interactive/interactive-mode.d.ts +0 -1
  36. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  37. package/dist/modes/interactive/interactive-mode.js +121 -104
  38. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  39. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  40. package/dist/modes/rpc/rpc-mode.js +4 -0
  41. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  42. package/docs/extensions.md +8 -0
  43. package/docs/models.md +40 -1
  44. package/docs/providers.md +13 -0
  45. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  46. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  47. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  48. package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
  49. package/examples/extensions/hello.ts +1 -1
  50. package/examples/extensions/with-deps/package-lock.json +2 -2
  51. package/examples/extensions/with-deps/package.json +1 -1
  52. package/package.json +4 -4
@@ -222,9 +222,9 @@ export class InteractiveMode {
222
222
  // Setup autocomplete
223
223
  this.autocompleteProvider = new CombinedAutocompleteProvider([...slashCommands, ...templateCommands, ...extensionCommands, ...skillCommandList], process.cwd(), fdPath);
224
224
  this.defaultEditor.setAutocompleteProvider(this.autocompleteProvider);
225
- }
226
- rebuildAutocomplete() {
227
- this.setupAutocomplete(this.fdPath);
225
+ if (this.editor !== this.defaultEditor) {
226
+ this.editor.setAutocompleteProvider?.(this.autocompleteProvider);
227
+ }
228
228
  }
229
229
  async init() {
230
230
  if (this.isInitialized)
@@ -233,7 +233,6 @@ export class InteractiveMode {
233
233
  this.changelogMarkdown = this.getChangelogForDisplay();
234
234
  // Setup autocomplete with fd tool for file path completion
235
235
  this.fdPath = await ensureTool("fd");
236
- this.setupAutocomplete(this.fdPath);
237
236
  // Add header container as first child
238
237
  this.ui.addChild(this.headerContainer);
239
238
  // Add header with keybindings from config (unless silenced)
@@ -639,104 +638,114 @@ export class InteractiveMode {
639
638
  return lines.join("\n");
640
639
  }
641
640
  showLoadedResources(options) {
642
- const shouldShow = options?.force || this.options.verbose || !this.settingsManager.getQuietStartup();
643
- if (!shouldShow) {
641
+ const showListing = options?.force || this.options.verbose || !this.settingsManager.getQuietStartup();
642
+ const showDiagnostics = showListing || options?.showDiagnosticsWhenQuiet === true;
643
+ if (!showListing && !showDiagnostics) {
644
644
  return;
645
645
  }
646
646
  const metadata = this.session.resourceLoader.getPathMetadata();
647
647
  const sectionHeader = (name, color = "mdHeading") => theme.fg(color, `[${name}]`);
648
- const contextFiles = this.session.resourceLoader.getAgentsFiles().agentsFiles;
649
- if (contextFiles.length > 0) {
650
- this.chatContainer.addChild(new Spacer(1));
651
- const contextList = contextFiles.map((f) => theme.fg("dim", ` ${this.formatDisplayPath(f.path)}`)).join("\n");
652
- this.chatContainer.addChild(new Text(`${sectionHeader("Context")}\n${contextList}`, 0, 0));
653
- this.chatContainer.addChild(new Spacer(1));
654
- }
655
- const skills = this.session.resourceLoader.getSkills().skills;
656
- if (skills.length > 0) {
657
- const skillPaths = skills.map((s) => s.filePath);
658
- const groups = this.buildScopeGroups(skillPaths, metadata);
659
- const skillList = this.formatScopeGroups(groups, {
660
- formatPath: (p) => this.formatDisplayPath(p),
661
- formatPackagePath: (p, source) => this.getShortPath(p, source),
662
- });
663
- this.chatContainer.addChild(new Text(`${sectionHeader("Skills")}\n${skillList}`, 0, 0));
664
- this.chatContainer.addChild(new Spacer(1));
665
- }
666
- const skillDiagnostics = this.session.resourceLoader.getSkills().diagnostics;
667
- if (skillDiagnostics.length > 0) {
668
- const warningLines = this.formatDiagnostics(skillDiagnostics, metadata);
669
- this.chatContainer.addChild(new Text(`${theme.fg("warning", "[Skill conflicts]")}\n${warningLines}`, 0, 0));
670
- this.chatContainer.addChild(new Spacer(1));
671
- }
672
- const templates = this.session.promptTemplates;
673
- if (templates.length > 0) {
674
- const templatePaths = templates.map((t) => t.filePath);
675
- const groups = this.buildScopeGroups(templatePaths, metadata);
676
- const templateByPath = new Map(templates.map((t) => [t.filePath, t]));
677
- const templateList = this.formatScopeGroups(groups, {
678
- formatPath: (p) => {
679
- const template = templateByPath.get(p);
680
- return template ? `/${template.name}` : this.formatDisplayPath(p);
681
- },
682
- formatPackagePath: (p) => {
683
- const template = templateByPath.get(p);
684
- return template ? `/${template.name}` : this.formatDisplayPath(p);
685
- },
686
- });
687
- this.chatContainer.addChild(new Text(`${sectionHeader("Prompts")}\n${templateList}`, 0, 0));
688
- this.chatContainer.addChild(new Spacer(1));
689
- }
690
- const promptDiagnostics = this.session.resourceLoader.getPrompts().diagnostics;
691
- if (promptDiagnostics.length > 0) {
692
- const warningLines = this.formatDiagnostics(promptDiagnostics, metadata);
693
- this.chatContainer.addChild(new Text(`${theme.fg("warning", "[Prompt conflicts]")}\n${warningLines}`, 0, 0));
694
- this.chatContainer.addChild(new Spacer(1));
695
- }
696
- const extensionPaths = options?.extensionPaths ?? [];
697
- if (extensionPaths.length > 0) {
698
- const groups = this.buildScopeGroups(extensionPaths, metadata);
699
- const extList = this.formatScopeGroups(groups, {
700
- formatPath: (p) => this.formatDisplayPath(p),
701
- formatPackagePath: (p, source) => this.getShortPath(p, source),
702
- });
703
- this.chatContainer.addChild(new Text(`${sectionHeader("Extensions", "mdHeading")}\n${extList}`, 0, 0));
704
- this.chatContainer.addChild(new Spacer(1));
705
- }
706
- const extensionDiagnostics = [];
707
- const extensionErrors = this.session.resourceLoader.getExtensions().errors;
708
- if (extensionErrors.length > 0) {
709
- for (const error of extensionErrors) {
710
- extensionDiagnostics.push({ type: "error", message: error.error, path: error.path });
711
- }
712
- }
713
- const commandDiagnostics = this.session.extensionRunner?.getCommandDiagnostics() ?? [];
714
- extensionDiagnostics.push(...commandDiagnostics);
715
- const shortcutDiagnostics = this.session.extensionRunner?.getShortcutDiagnostics() ?? [];
716
- extensionDiagnostics.push(...shortcutDiagnostics);
717
- if (extensionDiagnostics.length > 0) {
718
- const warningLines = this.formatDiagnostics(extensionDiagnostics, metadata);
719
- this.chatContainer.addChild(new Text(`${theme.fg("warning", "[Extension issues]")}\n${warningLines}`, 0, 0));
720
- this.chatContainer.addChild(new Spacer(1));
721
- }
722
- // Show loaded themes (excluding built-in)
723
- const loadedThemes = this.session.resourceLoader.getThemes().themes;
724
- const customThemes = loadedThemes.filter((t) => t.sourcePath);
725
- if (customThemes.length > 0) {
726
- const themePaths = customThemes.map((t) => t.sourcePath);
727
- const groups = this.buildScopeGroups(themePaths, metadata);
728
- const themeList = this.formatScopeGroups(groups, {
729
- formatPath: (p) => this.formatDisplayPath(p),
730
- formatPackagePath: (p, source) => this.getShortPath(p, source),
731
- });
732
- this.chatContainer.addChild(new Text(`${sectionHeader("Themes")}\n${themeList}`, 0, 0));
733
- this.chatContainer.addChild(new Spacer(1));
648
+ const skillsResult = this.session.resourceLoader.getSkills();
649
+ const promptsResult = this.session.resourceLoader.getPrompts();
650
+ const themesResult = this.session.resourceLoader.getThemes();
651
+ if (showListing) {
652
+ const contextFiles = this.session.resourceLoader.getAgentsFiles().agentsFiles;
653
+ if (contextFiles.length > 0) {
654
+ this.chatContainer.addChild(new Spacer(1));
655
+ const contextList = contextFiles
656
+ .map((f) => theme.fg("dim", ` ${this.formatDisplayPath(f.path)}`))
657
+ .join("\n");
658
+ this.chatContainer.addChild(new Text(`${sectionHeader("Context")}\n${contextList}`, 0, 0));
659
+ this.chatContainer.addChild(new Spacer(1));
660
+ }
661
+ const skills = skillsResult.skills;
662
+ if (skills.length > 0) {
663
+ const skillPaths = skills.map((s) => s.filePath);
664
+ const groups = this.buildScopeGroups(skillPaths, metadata);
665
+ const skillList = this.formatScopeGroups(groups, {
666
+ formatPath: (p) => this.formatDisplayPath(p),
667
+ formatPackagePath: (p, source) => this.getShortPath(p, source),
668
+ });
669
+ this.chatContainer.addChild(new Text(`${sectionHeader("Skills")}\n${skillList}`, 0, 0));
670
+ this.chatContainer.addChild(new Spacer(1));
671
+ }
672
+ const templates = this.session.promptTemplates;
673
+ if (templates.length > 0) {
674
+ const templatePaths = templates.map((t) => t.filePath);
675
+ const groups = this.buildScopeGroups(templatePaths, metadata);
676
+ const templateByPath = new Map(templates.map((t) => [t.filePath, t]));
677
+ const templateList = this.formatScopeGroups(groups, {
678
+ formatPath: (p) => {
679
+ const template = templateByPath.get(p);
680
+ return template ? `/${template.name}` : this.formatDisplayPath(p);
681
+ },
682
+ formatPackagePath: (p) => {
683
+ const template = templateByPath.get(p);
684
+ return template ? `/${template.name}` : this.formatDisplayPath(p);
685
+ },
686
+ });
687
+ this.chatContainer.addChild(new Text(`${sectionHeader("Prompts")}\n${templateList}`, 0, 0));
688
+ this.chatContainer.addChild(new Spacer(1));
689
+ }
690
+ const extensionPaths = options?.extensionPaths ?? [];
691
+ if (extensionPaths.length > 0) {
692
+ const groups = this.buildScopeGroups(extensionPaths, metadata);
693
+ const extList = this.formatScopeGroups(groups, {
694
+ formatPath: (p) => this.formatDisplayPath(p),
695
+ formatPackagePath: (p, source) => this.getShortPath(p, source),
696
+ });
697
+ this.chatContainer.addChild(new Text(`${sectionHeader("Extensions", "mdHeading")}\n${extList}`, 0, 0));
698
+ this.chatContainer.addChild(new Spacer(1));
699
+ }
700
+ // Show loaded themes (excluding built-in)
701
+ const loadedThemes = themesResult.themes;
702
+ const customThemes = loadedThemes.filter((t) => t.sourcePath);
703
+ if (customThemes.length > 0) {
704
+ const themePaths = customThemes.map((t) => t.sourcePath);
705
+ const groups = this.buildScopeGroups(themePaths, metadata);
706
+ const themeList = this.formatScopeGroups(groups, {
707
+ formatPath: (p) => this.formatDisplayPath(p),
708
+ formatPackagePath: (p, source) => this.getShortPath(p, source),
709
+ });
710
+ this.chatContainer.addChild(new Text(`${sectionHeader("Themes")}\n${themeList}`, 0, 0));
711
+ this.chatContainer.addChild(new Spacer(1));
712
+ }
734
713
  }
735
- const themeDiagnostics = this.session.resourceLoader.getThemes().diagnostics;
736
- if (themeDiagnostics.length > 0) {
737
- const warningLines = this.formatDiagnostics(themeDiagnostics, metadata);
738
- this.chatContainer.addChild(new Text(`${theme.fg("warning", "[Theme conflicts]")}\n${warningLines}`, 0, 0));
739
- this.chatContainer.addChild(new Spacer(1));
714
+ if (showDiagnostics) {
715
+ const skillDiagnostics = skillsResult.diagnostics;
716
+ if (skillDiagnostics.length > 0) {
717
+ const warningLines = this.formatDiagnostics(skillDiagnostics, metadata);
718
+ this.chatContainer.addChild(new Text(`${theme.fg("warning", "[Skill conflicts]")}\n${warningLines}`, 0, 0));
719
+ this.chatContainer.addChild(new Spacer(1));
720
+ }
721
+ const promptDiagnostics = promptsResult.diagnostics;
722
+ if (promptDiagnostics.length > 0) {
723
+ const warningLines = this.formatDiagnostics(promptDiagnostics, metadata);
724
+ this.chatContainer.addChild(new Text(`${theme.fg("warning", "[Prompt conflicts]")}\n${warningLines}`, 0, 0));
725
+ this.chatContainer.addChild(new Spacer(1));
726
+ }
727
+ const extensionDiagnostics = [];
728
+ const extensionErrors = this.session.resourceLoader.getExtensions().errors;
729
+ if (extensionErrors.length > 0) {
730
+ for (const error of extensionErrors) {
731
+ extensionDiagnostics.push({ type: "error", message: error.error, path: error.path });
732
+ }
733
+ }
734
+ const commandDiagnostics = this.session.extensionRunner?.getCommandDiagnostics() ?? [];
735
+ extensionDiagnostics.push(...commandDiagnostics);
736
+ const shortcutDiagnostics = this.session.extensionRunner?.getShortcutDiagnostics() ?? [];
737
+ extensionDiagnostics.push(...shortcutDiagnostics);
738
+ if (extensionDiagnostics.length > 0) {
739
+ const warningLines = this.formatDiagnostics(extensionDiagnostics, metadata);
740
+ this.chatContainer.addChild(new Text(`${theme.fg("warning", "[Extension issues]")}\n${warningLines}`, 0, 0));
741
+ this.chatContainer.addChild(new Spacer(1));
742
+ }
743
+ const themeDiagnostics = themesResult.diagnostics;
744
+ if (themeDiagnostics.length > 0) {
745
+ const warningLines = this.formatDiagnostics(themeDiagnostics, metadata);
746
+ this.chatContainer.addChild(new Text(`${theme.fg("warning", "[Theme conflicts]")}\n${warningLines}`, 0, 0));
747
+ this.chatContainer.addChild(new Spacer(1));
748
+ }
740
749
  }
741
750
  }
742
751
  /**
@@ -807,13 +816,16 @@ export class InteractiveMode {
807
816
  },
808
817
  shutdownHandler: () => {
809
818
  this.shutdownRequested = true;
819
+ if (!this.session.isStreaming) {
820
+ void this.shutdown();
821
+ }
810
822
  },
811
823
  onError: (error) => {
812
824
  this.showExtensionError(error.extensionPath, error.error, error.stack);
813
825
  },
814
826
  });
815
827
  setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
816
- this.rebuildAutocomplete();
828
+ this.setupAutocomplete(this.fdPath);
817
829
  const extensionRunner = this.session.extensionRunner;
818
830
  if (!extensionRunner) {
819
831
  this.showLoadedResources({ extensionPaths: [], force: false });
@@ -1079,6 +1091,7 @@ export class InteractiveMode {
1079
1091
  setHeader: (factory) => this.setExtensionHeader(factory),
1080
1092
  setTitle: (title) => this.ui.terminal.setTitle(title),
1081
1093
  custom: (factory, options) => this.showExtensionCustom(factory, options),
1094
+ pasteToEditor: (text) => this.editor.handleInput(`\x1b[200~${text}\x1b[201~`),
1082
1095
  setEditorText: (text) => this.editor.setText(text),
1083
1096
  getEditorText: () => this.editor.getText(),
1084
1097
  editor: (title, prefill) => this.showExtensionEditor(title, prefill),
@@ -1250,9 +1263,9 @@ export class InteractiveMode {
1250
1263
  // Use duck typing since instanceof fails across jiti module boundaries
1251
1264
  const customEditor = newEditor;
1252
1265
  if ("actionHandlers" in customEditor && customEditor.actionHandlers instanceof Map) {
1253
- customEditor.onEscape = this.defaultEditor.onEscape;
1254
- customEditor.onCtrlD = this.defaultEditor.onCtrlD;
1255
- customEditor.onPasteImage = this.defaultEditor.onPasteImage;
1266
+ customEditor.onEscape = () => this.defaultEditor.onEscape?.();
1267
+ customEditor.onCtrlD = () => this.defaultEditor.onCtrlD?.();
1268
+ customEditor.onPasteImage = () => this.defaultEditor.onPasteImage?.();
1256
1269
  customEditor.onExtensionShortcut = (data) => this.defaultEditor.onExtensionShortcut?.(data);
1257
1270
  // Copy action handlers (clear, suspend, model switching, etc.)
1258
1271
  for (const [action, handler] of this.defaultEditor.actionHandlers) {
@@ -2529,7 +2542,7 @@ export class InteractiveMode {
2529
2542
  },
2530
2543
  onEnableSkillCommandsChange: (enabled) => {
2531
2544
  this.settingsManager.setEnableSkillCommands(enabled);
2532
- this.rebuildAutocomplete();
2545
+ this.setupAutocomplete(this.fdPath);
2533
2546
  },
2534
2547
  onSteeringModeChange: (mode) => {
2535
2548
  this.session.setSteeringMode(mode);
@@ -3131,14 +3144,18 @@ export class InteractiveMode {
3131
3144
  }
3132
3145
  this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor());
3133
3146
  this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());
3134
- this.rebuildAutocomplete();
3147
+ this.setupAutocomplete(this.fdPath);
3135
3148
  const runner = this.session.extensionRunner;
3136
3149
  if (runner) {
3137
3150
  this.setupExtensionShortcuts(runner);
3138
3151
  }
3139
3152
  this.rebuildChatFromMessages();
3140
3153
  dismissLoader(this.editor);
3141
- this.showLoadedResources({ extensionPaths: runner?.getExtensionPaths() ?? [], force: true });
3154
+ this.showLoadedResources({
3155
+ extensionPaths: runner?.getExtensionPaths() ?? [],
3156
+ force: false,
3157
+ showDiagnosticsWhenQuiet: true,
3158
+ });
3142
3159
  const modelsJsonError = this.session.modelRegistry.getError();
3143
3160
  if (modelsJsonError) {
3144
3161
  this.showError(`models.json error: ${modelsJsonError}`);