@fleetagent/pi-coding-agent 0.0.5 → 0.0.7

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 (201) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +28 -5
  3. package/dist/cli/args.d.ts +2 -0
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +9 -0
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/file-processor.d.ts.map +1 -1
  8. package/dist/cli/file-processor.js +2 -3
  9. package/dist/cli/file-processor.js.map +1 -1
  10. package/dist/config.d.ts.map +1 -1
  11. package/dist/config.js +15 -2
  12. package/dist/config.js.map +1 -1
  13. package/dist/core/agent-session.d.ts +13 -3
  14. package/dist/core/agent-session.d.ts.map +1 -1
  15. package/dist/core/agent-session.js +130 -23
  16. package/dist/core/agent-session.js.map +1 -1
  17. package/dist/core/diagnostics.d.ts +1 -1
  18. package/dist/core/diagnostics.d.ts.map +1 -1
  19. package/dist/core/diagnostics.js.map +1 -1
  20. package/dist/core/export-html/template.js +6 -3
  21. package/dist/core/extensions/runner.d.ts +5 -1
  22. package/dist/core/extensions/runner.d.ts.map +1 -1
  23. package/dist/core/extensions/runner.js +13 -3
  24. package/dist/core/extensions/runner.js.map +1 -1
  25. package/dist/core/extensions/types.d.ts +6 -3
  26. package/dist/core/extensions/types.d.ts.map +1 -1
  27. package/dist/core/extensions/types.js.map +1 -1
  28. package/dist/core/model-registry.d.ts.map +1 -1
  29. package/dist/core/model-registry.js +65 -13
  30. package/dist/core/model-registry.js.map +1 -1
  31. package/dist/core/output-guard.d.ts +1 -0
  32. package/dist/core/output-guard.d.ts.map +1 -1
  33. package/dist/core/output-guard.js +52 -22
  34. package/dist/core/output-guard.js.map +1 -1
  35. package/dist/core/package-manager.d.ts +1 -0
  36. package/dist/core/package-manager.d.ts.map +1 -1
  37. package/dist/core/package-manager.js +161 -24
  38. package/dist/core/package-manager.js.map +1 -1
  39. package/dist/core/pi-agent.d.ts.map +1 -1
  40. package/dist/core/pi-agent.js +12 -3
  41. package/dist/core/pi-agent.js.map +1 -1
  42. package/dist/core/resolve-config-value.d.ts +9 -1
  43. package/dist/core/resolve-config-value.d.ts.map +1 -1
  44. package/dist/core/resolve-config-value.js +134 -11
  45. package/dist/core/resolve-config-value.js.map +1 -1
  46. package/dist/core/resource-loader.d.ts +30 -0
  47. package/dist/core/resource-loader.d.ts.map +1 -1
  48. package/dist/core/resource-loader.js +94 -0
  49. package/dist/core/resource-loader.js.map +1 -1
  50. package/dist/core/rules.d.ts +57 -0
  51. package/dist/core/rules.d.ts.map +1 -0
  52. package/dist/core/rules.js +384 -0
  53. package/dist/core/rules.js.map +1 -0
  54. package/dist/core/session/jsonl-helpers.d.ts +2 -1
  55. package/dist/core/session/jsonl-helpers.d.ts.map +1 -1
  56. package/dist/core/session/jsonl-helpers.js +6 -3
  57. package/dist/core/session/jsonl-helpers.js.map +1 -1
  58. package/dist/core/session/local-session-manager.d.ts +1 -0
  59. package/dist/core/session/local-session-manager.d.ts.map +1 -1
  60. package/dist/core/session/local-session-manager.js +12 -4
  61. package/dist/core/session/local-session-manager.js.map +1 -1
  62. package/dist/core/session/session-manager.d.ts +1 -0
  63. package/dist/core/session/session-manager.d.ts.map +1 -1
  64. package/dist/core/session/session-manager.js.map +1 -1
  65. package/dist/core/session/stores/jsonl-session-store.d.ts +2 -1
  66. package/dist/core/session/stores/jsonl-session-store.d.ts.map +1 -1
  67. package/dist/core/session/stores/jsonl-session-store.js +105 -78
  68. package/dist/core/session/stores/jsonl-session-store.js.map +1 -1
  69. package/dist/core/settings-manager.d.ts +7 -0
  70. package/dist/core/settings-manager.d.ts.map +1 -1
  71. package/dist/core/settings-manager.js +28 -9
  72. package/dist/core/settings-manager.js.map +1 -1
  73. package/dist/core/slash-commands.d.ts +1 -1
  74. package/dist/core/slash-commands.d.ts.map +1 -1
  75. package/dist/core/slash-commands.js +1 -1
  76. package/dist/core/slash-commands.js.map +1 -1
  77. package/dist/core/system-prompt.d.ts +3 -0
  78. package/dist/core/system-prompt.d.ts.map +1 -1
  79. package/dist/core/system-prompt.js +11 -3
  80. package/dist/core/system-prompt.js.map +1 -1
  81. package/dist/core/tools/bash.d.ts.map +1 -1
  82. package/dist/core/tools/bash.js +73 -63
  83. package/dist/core/tools/bash.js.map +1 -1
  84. package/dist/core/tools/edit.d.ts.map +1 -1
  85. package/dist/core/tools/edit.js +45 -76
  86. package/dist/core/tools/edit.js.map +1 -1
  87. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  88. package/dist/core/tools/file-mutation-queue.js +27 -12
  89. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  90. package/dist/core/tools/find.d.ts.map +1 -1
  91. package/dist/core/tools/find.js +11 -2
  92. package/dist/core/tools/find.js.map +1 -1
  93. package/dist/core/tools/grep.d.ts.map +1 -1
  94. package/dist/core/tools/grep.js +3 -3
  95. package/dist/core/tools/grep.js.map +1 -1
  96. package/dist/core/tools/ls.d.ts.map +1 -1
  97. package/dist/core/tools/ls.js +13 -4
  98. package/dist/core/tools/ls.js.map +1 -1
  99. package/dist/core/tools/path-utils.d.ts +1 -0
  100. package/dist/core/tools/path-utils.d.ts.map +1 -1
  101. package/dist/core/tools/path-utils.js +37 -0
  102. package/dist/core/tools/path-utils.js.map +1 -1
  103. package/dist/core/tools/read.d.ts.map +1 -1
  104. package/dist/core/tools/read.js +13 -8
  105. package/dist/core/tools/read.js.map +1 -1
  106. package/dist/core/tools/write.d.ts.map +1 -1
  107. package/dist/core/tools/write.js +24 -32
  108. package/dist/core/tools/write.js.map +1 -1
  109. package/dist/index.d.ts +1 -0
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.js +2 -0
  112. package/dist/index.js.map +1 -1
  113. package/dist/main.d.ts.map +1 -1
  114. package/dist/main.js +6 -2
  115. package/dist/main.js.map +1 -1
  116. package/dist/migrations.d.ts.map +1 -1
  117. package/dist/migrations.js +118 -1
  118. package/dist/migrations.js.map +1 -1
  119. package/dist/modes/interactive/components/config-selector.d.ts +1 -1
  120. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  121. package/dist/modes/interactive/components/config-selector.js +12 -3
  122. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  123. package/dist/modes/interactive/components/footer.d.ts +1 -0
  124. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  125. package/dist/modes/interactive/components/footer.js +14 -5
  126. package/dist/modes/interactive/components/footer.js.map +1 -1
  127. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  128. package/dist/modes/interactive/components/settings-selector.js +1 -1
  129. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  130. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  131. package/dist/modes/interactive/components/user-message.js +1 -1
  132. package/dist/modes/interactive/components/user-message.js.map +1 -1
  133. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  134. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  135. package/dist/modes/interactive/interactive-mode.js +64 -9
  136. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  137. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  138. package/dist/modes/interactive/theme/theme.js +10 -0
  139. package/dist/modes/interactive/theme/theme.js.map +1 -1
  140. package/dist/modes/rpc/rpc-client.d.ts +5 -0
  141. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  142. package/dist/modes/rpc/rpc-client.js +91 -18
  143. package/dist/modes/rpc/rpc-client.js.map +1 -1
  144. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  145. package/dist/modes/rpc/rpc-mode.js +23 -3
  146. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  147. package/dist/modes/rpc/rpc-types.d.ts +1 -1
  148. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  149. package/dist/modes/rpc/rpc-types.js.map +1 -1
  150. package/dist/utils/clipboard-native.d.ts +3 -1
  151. package/dist/utils/clipboard-native.d.ts.map +1 -1
  152. package/dist/utils/clipboard-native.js +14 -8
  153. package/dist/utils/clipboard-native.js.map +1 -1
  154. package/dist/utils/deprecation.d.ts +4 -0
  155. package/dist/utils/deprecation.d.ts.map +1 -0
  156. package/dist/utils/deprecation.js +13 -0
  157. package/dist/utils/deprecation.js.map +1 -0
  158. package/dist/utils/image-resize-core.d.ts +30 -0
  159. package/dist/utils/image-resize-core.d.ts.map +1 -0
  160. package/dist/utils/image-resize-core.js +124 -0
  161. package/dist/utils/image-resize-core.js.map +1 -0
  162. package/dist/utils/image-resize-worker.d.ts +2 -0
  163. package/dist/utils/image-resize-worker.d.ts.map +1 -0
  164. package/dist/utils/image-resize-worker.js +31 -0
  165. package/dist/utils/image-resize-worker.js.map +1 -0
  166. package/dist/utils/image-resize.d.ts +6 -27
  167. package/dist/utils/image-resize.d.ts.map +1 -1
  168. package/dist/utils/image-resize.js +60 -116
  169. package/dist/utils/image-resize.js.map +1 -1
  170. package/dist/utils/json.d.ts +3 -0
  171. package/dist/utils/json.d.ts.map +1 -0
  172. package/dist/utils/json.js +7 -0
  173. package/dist/utils/json.js.map +1 -0
  174. package/docs/custom-provider.md +22 -9
  175. package/docs/extensions.md +13 -11
  176. package/docs/index.md +3 -2
  177. package/docs/models.md +34 -12
  178. package/docs/packages.md +11 -8
  179. package/docs/providers.md +13 -5
  180. package/docs/quickstart.md +1 -1
  181. package/docs/rpc.md +4 -2
  182. package/docs/rules.md +102 -0
  183. package/docs/sdk.md +57 -1
  184. package/docs/settings.md +6 -3
  185. package/docs/terminal-setup.md +6 -0
  186. package/docs/usage.md +6 -4
  187. package/examples/extensions/README.md +2 -1
  188. package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
  189. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  190. package/examples/extensions/custom-provider-gitlab-duo/index.ts +54 -3
  191. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  192. package/examples/extensions/dynamic-resources/RULES.md +8 -0
  193. package/examples/extensions/dynamic-resources/index.ts +1 -0
  194. package/examples/extensions/git-merge-and-resolve.ts +115 -0
  195. package/examples/extensions/reload-runtime.ts +2 -2
  196. package/examples/extensions/sandbox/package.json +1 -1
  197. package/examples/extensions/with-deps/package.json +1 -1
  198. package/examples/sdk/12-full-control.ts +1 -0
  199. package/examples/sdk/README.md +1 -1
  200. package/npm-shrinkwrap.json +13 -12
  201. package/package.json +5 -5
@@ -125,6 +125,7 @@ export class InteractiveMode {
125
125
  version;
126
126
  isInitialized = false;
127
127
  onInputCallback;
128
+ pendingUserInputs = [];
128
129
  loadingAnimation = undefined;
129
130
  workingMessage = undefined;
130
131
  workingVisible = true;
@@ -327,9 +328,10 @@ export class InteractiveMode {
327
328
  description: this.prefixAutocompleteDescription(cmd.description, cmd.sourceInfo),
328
329
  getArgumentCompletions: cmd.getArgumentCompletions,
329
330
  }));
330
- // Build skill commands from session.skills (if enabled)
331
+ // Build skill/rule commands from loaded resources (if enabled)
331
332
  this.skillCommands.clear();
332
333
  const skillCommandList = [];
334
+ const ruleCommandList = [];
333
335
  if (this.settingsManager.getEnableSkillCommands()) {
334
336
  for (const skill of this.session.resourceLoader.getSkills().skills) {
335
337
  const commandName = `skill:${skill.name}`;
@@ -339,8 +341,15 @@ export class InteractiveMode {
339
341
  description: this.prefixAutocompleteDescription(skill.description, skill.sourceInfo),
340
342
  });
341
343
  }
344
+ for (const rule of this.session.resourceLoader.getRules().rules) {
345
+ const commandName = `rule:${rule.name}`;
346
+ ruleCommandList.push({
347
+ name: commandName,
348
+ description: this.prefixAutocompleteDescription(rule.description, rule.sourceInfo),
349
+ });
350
+ }
342
351
  }
343
- return new CombinedAutocompleteProvider([...slashCommands, ...templateCommands, ...extensionCommands, ...skillCommandList], this.activeSession.getCwd(), this.fdPath);
352
+ return new CombinedAutocompleteProvider([...slashCommands, ...templateCommands, ...extensionCommands, ...skillCommandList, ...ruleCommandList], this.activeSession.getCwd(), this.fdPath);
344
353
  }
345
354
  setupAutocompleteProvider() {
346
355
  let provider = this.createBaseAutocompleteProvider();
@@ -970,6 +979,7 @@ export class InteractiveMode {
970
979
  this.chatContainer.addChild(new Spacer(1));
971
980
  };
972
981
  const skillsResult = this.session.resourceLoader.getSkills();
982
+ const rulesResult = this.session.resourceLoader.getRules();
973
983
  const promptsResult = this.session.resourceLoader.getPrompts();
974
984
  const themesResult = this.session.resourceLoader.getThemes();
975
985
  const extensions = options?.extensions ??
@@ -988,6 +998,11 @@ export class InteractiveMode {
988
998
  sourceInfos.set(skill.filePath, skill.sourceInfo);
989
999
  }
990
1000
  }
1001
+ for (const rule of rulesResult.rules) {
1002
+ if (rule.sourceInfo) {
1003
+ sourceInfos.set(rule.filePath, rule.sourceInfo);
1004
+ }
1005
+ }
991
1006
  for (const prompt of promptsResult.prompts) {
992
1007
  if (prompt.sourceInfo) {
993
1008
  sourceInfos.set(prompt.filePath, prompt.sourceInfo);
@@ -1018,6 +1033,16 @@ export class InteractiveMode {
1018
1033
  const skillCompactList = formatCompactList(skills.map((skill) => skill.name));
1019
1034
  addLoadedSection("Skills", skillCompactList, skillList);
1020
1035
  }
1036
+ const rules = rulesResult.rules;
1037
+ if (rules.length > 0) {
1038
+ const groups = this.buildScopeGroups(rules.map((rule) => ({ path: rule.filePath, sourceInfo: rule.sourceInfo })));
1039
+ const ruleList = this.formatScopeGroups(groups, {
1040
+ formatPath: (item) => this.formatDisplayPath(item.path),
1041
+ formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
1042
+ });
1043
+ const ruleCompactList = formatCompactList(rules.map((rule) => rule.name));
1044
+ addLoadedSection("Rules", ruleCompactList, ruleList);
1045
+ }
1021
1046
  const templates = this.session.promptTemplates;
1022
1047
  if (templates.length > 0) {
1023
1048
  const groups = this.buildScopeGroups(templates.map((template) => ({ path: template.filePath, sourceInfo: template.sourceInfo })));
@@ -1067,6 +1092,12 @@ export class InteractiveMode {
1067
1092
  this.chatContainer.addChild(new Text(`${theme.fg("warning", "[Skill conflicts]")}\n${warningLines}`, 0, 0));
1068
1093
  this.chatContainer.addChild(new Spacer(1));
1069
1094
  }
1095
+ const ruleDiagnostics = rulesResult.diagnostics;
1096
+ if (ruleDiagnostics.length > 0) {
1097
+ const warningLines = this.formatDiagnostics(ruleDiagnostics, sourceInfos);
1098
+ this.chatContainer.addChild(new Text(`${theme.fg("warning", "[Rule conflicts]")}\n${warningLines}`, 0, 0));
1099
+ this.chatContainer.addChild(new Spacer(1));
1100
+ }
1070
1101
  const promptDiagnostics = promptsResult.diagnostics;
1071
1102
  if (promptDiagnostics.length > 0) {
1072
1103
  const warningLines = this.formatDiagnostics(promptDiagnostics, sourceInfos);
@@ -2128,6 +2159,9 @@ export class InteractiveMode {
2128
2159
  if (this.onInputCallback) {
2129
2160
  this.onInputCallback(text);
2130
2161
  }
2162
+ else {
2163
+ this.pendingUserInputs.push(text);
2164
+ }
2131
2165
  this.editor.addToHistory?.(text);
2132
2166
  };
2133
2167
  }
@@ -2606,6 +2640,10 @@ export class InteractiveMode {
2606
2640
  }
2607
2641
  }
2608
2642
  async getUserInput() {
2643
+ const queuedInput = this.pendingUserInputs.shift();
2644
+ if (queuedInput !== undefined) {
2645
+ return queuedInput;
2646
+ }
2609
2647
  return new Promise((resolve) => {
2610
2648
  this.onInputCallback = (text) => {
2611
2649
  this.onInputCallback = undefined;
@@ -2641,11 +2679,27 @@ export class InteractiveMode {
2641
2679
  * repaint the final frame while the process is exiting.
2642
2680
  */
2643
2681
  isShuttingDown = false;
2644
- async shutdown() {
2682
+ async shutdown(options) {
2645
2683
  if (this.isShuttingDown)
2646
2684
  return;
2647
2685
  this.isShuttingDown = true;
2648
2686
  this.unregisterSignalHandlers();
2687
+ if (options?.fromSignal) {
2688
+ // Signal-triggered shutdown (SIGTERM/SIGHUP). Emit extension cleanup
2689
+ // (session_shutdown) BEFORE touching the terminal. Extension teardown
2690
+ // such as removing sockets does not write to the tty, so it must not be
2691
+ // skipped if a later terminal-restore write fails on a dead or stalled
2692
+ // terminal. If the terminal is gone, the restore writes below emit EIO,
2693
+ // which the stdout/stderr error handler turns into emergencyTerminalExit;
2694
+ // the render loop is already idle, so this cannot hot-spin (see #4144).
2695
+ await this.runtimeHost.dispose();
2696
+ await this.ui.terminal.drainInput(1000);
2697
+ this.stop();
2698
+ process.exit(0);
2699
+ }
2700
+ // Interactive quit (Ctrl+D, Ctrl+C, /quit, extension shutdown()). Stop the
2701
+ // TUI before emitting shutdown events so extension UI cleanup cannot repaint
2702
+ // the final frame while the process is exiting.
2649
2703
  // Drain any in-flight Kitty key release events before stopping.
2650
2704
  // This prevents escape sequences from leaking to the parent shell over slow SSH.
2651
2705
  await this.ui.terminal.drainInput(1000);
@@ -2709,11 +2763,12 @@ export class InteractiveMode {
2709
2763
  }
2710
2764
  for (const signal of signals) {
2711
2765
  const handler = () => {
2712
- if (signal === "SIGHUP") {
2713
- this.emergencyTerminalExit();
2714
- }
2766
+ // SIGHUP no longer hard-exits: graceful shutdown emits session_shutdown
2767
+ // first, then attempts terminal restore. A genuinely dead terminal
2768
+ // surfaces as an EIO on the restore writes, which the stdout/stderr
2769
+ // error handler converts into emergencyTerminalExit (see #4144, #5080).
2715
2770
  killTrackedDetachedChildren();
2716
- void this.shutdown();
2771
+ void this.shutdown({ fromSignal: true });
2717
2772
  };
2718
2773
  process.prependListener(signal, handler);
2719
2774
  this.signalCleanupHandlers.push(() => process.off(signal, handler));
@@ -4041,7 +4096,7 @@ export class InteractiveMode {
4041
4096
  const borderColor = (s) => theme.fg("border", s);
4042
4097
  reloadBox.addChild(new DynamicBorder(borderColor));
4043
4098
  reloadBox.addChild(new Spacer(1));
4044
- reloadBox.addChild(new Text(theme.fg("muted", "Reloading keybindings, extensions, skills, prompts, themes..."), 1, 0));
4099
+ reloadBox.addChild(new Text(theme.fg("muted", "Reloading keybindings, extensions, skills, rules, prompts, themes..."), 1, 0));
4045
4100
  reloadBox.addChild(new Spacer(1));
4046
4101
  reloadBox.addChild(new DynamicBorder(borderColor));
4047
4102
  const previousEditor = this.editor;
@@ -4093,7 +4148,7 @@ export class InteractiveMode {
4093
4148
  if (modelsJsonError) {
4094
4149
  this.showError(`models.json error: ${modelsJsonError}`);
4095
4150
  }
4096
- this.showStatus("Reloaded keybindings, extensions, skills, prompts, themes");
4151
+ this.showStatus("Reloaded keybindings, extensions, skills, rules, prompts, themes");
4097
4152
  }
4098
4153
  catch (error) {
4099
4154
  dismissReloadBox(previousEditor);