@earendil-works/pi-coding-agent 0.78.0 → 0.79.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 (203) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/README.md +26 -6
  3. package/dist/cli/args.d.ts +1 -0
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +15 -2
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +9 -1
  9. package/dist/config.js.map +1 -1
  10. package/dist/core/agent-session-runtime.d.ts +3 -1
  11. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  12. package/dist/core/agent-session-runtime.js +1 -0
  13. package/dist/core/agent-session-runtime.js.map +1 -1
  14. package/dist/core/agent-session-services.d.ts +2 -1
  15. package/dist/core/agent-session-services.d.ts.map +1 -1
  16. package/dist/core/agent-session-services.js +2 -2
  17. package/dist/core/agent-session-services.js.map +1 -1
  18. package/dist/core/agent-session.d.ts +3 -1
  19. package/dist/core/agent-session.d.ts.map +1 -1
  20. package/dist/core/agent-session.js +7 -1
  21. package/dist/core/agent-session.js.map +1 -1
  22. package/dist/core/auth-storage.d.ts.map +1 -1
  23. package/dist/core/auth-storage.js +4 -3
  24. package/dist/core/auth-storage.js.map +1 -1
  25. package/dist/core/compaction/branch-summarization.d.ts +3 -1
  26. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  27. package/dist/core/compaction/branch-summarization.js +9 -3
  28. package/dist/core/compaction/branch-summarization.js.map +1 -1
  29. package/dist/core/compaction/utils.d.ts +1 -1
  30. package/dist/core/compaction/utils.d.ts.map +1 -1
  31. package/dist/core/compaction/utils.js +1 -1
  32. package/dist/core/compaction/utils.js.map +1 -1
  33. package/dist/core/export-html/template.js +19 -6
  34. package/dist/core/extensions/index.d.ts +1 -1
  35. package/dist/core/extensions/index.d.ts.map +1 -1
  36. package/dist/core/extensions/index.js.map +1 -1
  37. package/dist/core/extensions/loader.d.ts +1 -1
  38. package/dist/core/extensions/loader.d.ts.map +1 -1
  39. package/dist/core/extensions/loader.js +4 -4
  40. package/dist/core/extensions/loader.js.map +1 -1
  41. package/dist/core/extensions/runner.d.ts +9 -3
  42. package/dist/core/extensions/runner.d.ts.map +1 -1
  43. package/dist/core/extensions/runner.js +41 -1
  44. package/dist/core/extensions/runner.js.map +1 -1
  45. package/dist/core/extensions/types.d.ts +25 -2
  46. package/dist/core/extensions/types.d.ts.map +1 -1
  47. package/dist/core/extensions/types.js.map +1 -1
  48. package/dist/core/footer-data-provider.d.ts +2 -0
  49. package/dist/core/footer-data-provider.d.ts.map +1 -1
  50. package/dist/core/footer-data-provider.js +29 -1
  51. package/dist/core/footer-data-provider.js.map +1 -1
  52. package/dist/core/model-registry.d.ts.map +1 -1
  53. package/dist/core/model-registry.js +1 -0
  54. package/dist/core/model-registry.js.map +1 -1
  55. package/dist/core/model-resolver.d.ts.map +1 -1
  56. package/dist/core/model-resolver.js +3 -0
  57. package/dist/core/model-resolver.js.map +1 -1
  58. package/dist/core/package-manager.d.ts +3 -0
  59. package/dist/core/package-manager.d.ts.map +1 -1
  60. package/dist/core/package-manager.js +47 -13
  61. package/dist/core/package-manager.js.map +1 -1
  62. package/dist/core/provider-attribution.d.ts +4 -0
  63. package/dist/core/provider-attribution.d.ts.map +1 -0
  64. package/dist/core/provider-attribution.js +72 -0
  65. package/dist/core/provider-attribution.js.map +1 -0
  66. package/dist/core/provider-display-names.d.ts.map +1 -1
  67. package/dist/core/provider-display-names.js +3 -0
  68. package/dist/core/provider-display-names.js.map +1 -1
  69. package/dist/core/resource-loader.d.ts +13 -2
  70. package/dist/core/resource-loader.d.ts.map +1 -1
  71. package/dist/core/resource-loader.js +129 -54
  72. package/dist/core/resource-loader.js.map +1 -1
  73. package/dist/core/sdk.d.ts.map +1 -1
  74. package/dist/core/sdk.js +7 -33
  75. package/dist/core/sdk.js.map +1 -1
  76. package/dist/core/session-manager.d.ts.map +1 -1
  77. package/dist/core/session-manager.js +92 -68
  78. package/dist/core/session-manager.js.map +1 -1
  79. package/dist/core/settings-manager.d.ts +10 -2
  80. package/dist/core/settings-manager.d.ts.map +1 -1
  81. package/dist/core/settings-manager.js +71 -30
  82. package/dist/core/settings-manager.js.map +1 -1
  83. package/dist/core/slash-commands.d.ts.map +1 -1
  84. package/dist/core/slash-commands.js +1 -0
  85. package/dist/core/slash-commands.js.map +1 -1
  86. package/dist/core/tools/bash.d.ts.map +1 -1
  87. package/dist/core/tools/bash.js +1 -1
  88. package/dist/core/tools/bash.js.map +1 -1
  89. package/dist/core/tools/find.d.ts.map +1 -1
  90. package/dist/core/tools/find.js +1 -1
  91. package/dist/core/tools/find.js.map +1 -1
  92. package/dist/core/tools/grep.d.ts.map +1 -1
  93. package/dist/core/tools/grep.js +1 -1
  94. package/dist/core/tools/grep.js.map +1 -1
  95. package/dist/core/tools/ls.d.ts.map +1 -1
  96. package/dist/core/tools/ls.js +1 -1
  97. package/dist/core/tools/ls.js.map +1 -1
  98. package/dist/core/tools/read.d.ts.map +1 -1
  99. package/dist/core/tools/read.js +1 -1
  100. package/dist/core/tools/read.js.map +1 -1
  101. package/dist/core/tools/write.d.ts.map +1 -1
  102. package/dist/core/tools/write.js +1 -1
  103. package/dist/core/tools/write.js.map +1 -1
  104. package/dist/core/trust-manager.d.ts +10 -0
  105. package/dist/core/trust-manager.d.ts.map +1 -0
  106. package/dist/core/trust-manager.js +133 -0
  107. package/dist/core/trust-manager.js.map +1 -0
  108. package/dist/index.d.ts +5 -4
  109. package/dist/index.d.ts.map +1 -1
  110. package/dist/index.js +2 -1
  111. package/dist/index.js.map +1 -1
  112. package/dist/main.d.ts.map +1 -1
  113. package/dist/main.js +195 -6
  114. package/dist/main.js.map +1 -1
  115. package/dist/modes/index.d.ts +1 -1
  116. package/dist/modes/index.d.ts.map +1 -1
  117. package/dist/modes/index.js.map +1 -1
  118. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  119. package/dist/modes/interactive/components/bash-execution.js +2 -2
  120. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  121. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  122. package/dist/modes/interactive/components/footer.js +7 -0
  123. package/dist/modes/interactive/components/footer.js.map +1 -1
  124. package/dist/modes/interactive/components/index.d.ts +1 -0
  125. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  126. package/dist/modes/interactive/components/index.js +1 -0
  127. package/dist/modes/interactive/components/index.js.map +1 -1
  128. package/dist/modes/interactive/components/login-dialog.d.ts +0 -1
  129. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  130. package/dist/modes/interactive/components/login-dialog.js +3 -12
  131. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  132. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  133. package/dist/modes/interactive/components/tool-execution.js +22 -0
  134. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  135. package/dist/modes/interactive/components/trust-selector.d.ts +20 -0
  136. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -0
  137. package/dist/modes/interactive/components/trust-selector.js +86 -0
  138. package/dist/modes/interactive/components/trust-selector.js.map +1 -0
  139. package/dist/modes/interactive/interactive-mode.d.ts +7 -0
  140. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  141. package/dist/modes/interactive/interactive-mode.js +87 -1
  142. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  143. package/dist/modes/print-mode.d.ts.map +1 -1
  144. package/dist/modes/print-mode.js +1 -0
  145. package/dist/modes/print-mode.js.map +1 -1
  146. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  147. package/dist/modes/rpc/rpc-mode.js +1 -0
  148. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  149. package/dist/package-manager-cli.d.ts.map +1 -1
  150. package/dist/package-manager-cli.js +55 -8
  151. package/dist/package-manager-cli.js.map +1 -1
  152. package/dist/utils/git.d.ts.map +1 -1
  153. package/dist/utils/git.js +54 -22
  154. package/dist/utils/git.js.map +1 -1
  155. package/dist/utils/open-browser.d.ts +9 -0
  156. package/dist/utils/open-browser.d.ts.map +1 -0
  157. package/dist/utils/open-browser.js +22 -0
  158. package/dist/utils/open-browser.js.map +1 -0
  159. package/docs/containerization.md +111 -0
  160. package/docs/docs.json +8 -0
  161. package/docs/extensions.md +58 -12
  162. package/docs/index.md +2 -0
  163. package/docs/packages.md +3 -1
  164. package/docs/prompt-templates.md +1 -1
  165. package/docs/providers.md +5 -0
  166. package/docs/rpc.md +1 -1
  167. package/docs/sdk.md +5 -0
  168. package/docs/security.md +57 -0
  169. package/docs/settings.md +10 -0
  170. package/docs/skills.md +1 -1
  171. package/docs/terminal-setup.md +36 -2
  172. package/docs/themes.md +1 -1
  173. package/docs/tmux.md +4 -2
  174. package/docs/tui.md +10 -1
  175. package/docs/usage.md +16 -4
  176. package/examples/extensions/README.md +2 -0
  177. package/examples/extensions/custom-header.ts +1 -1
  178. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  179. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  180. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  181. package/examples/extensions/doom-overlay/index.ts +1 -1
  182. package/examples/extensions/gondolin/index.ts +531 -0
  183. package/examples/extensions/gondolin/package-lock.json +185 -0
  184. package/examples/extensions/gondolin/package.json +19 -0
  185. package/examples/extensions/handoff.ts +1 -1
  186. package/examples/extensions/interactive-shell.ts +1 -1
  187. package/examples/extensions/overlay-qa-tests.ts +152 -81
  188. package/examples/extensions/project-trust.ts +64 -0
  189. package/examples/extensions/qna.ts +1 -1
  190. package/examples/extensions/question.ts +1 -1
  191. package/examples/extensions/questionnaire.ts +1 -1
  192. package/examples/extensions/sandbox/package-lock.json +2 -2
  193. package/examples/extensions/sandbox/package.json +1 -1
  194. package/examples/extensions/snake.ts +1 -1
  195. package/examples/extensions/space-invaders.ts +1 -1
  196. package/examples/extensions/summarize.ts +1 -1
  197. package/examples/extensions/tic-tac-toe.ts +1 -1
  198. package/examples/extensions/todo.ts +1 -1
  199. package/examples/extensions/tools.ts +5 -0
  200. package/examples/extensions/with-deps/package-lock.json +2 -2
  201. package/examples/extensions/with-deps/package.json +1 -1
  202. package/npm-shrinkwrap.json +12 -12
  203. package/package.json +5 -8
@@ -24,6 +24,7 @@ import { formatMissingSessionCwdPrompt, MissingSessionCwdError } from "../../cor
24
24
  import { SessionManager } from "../../core/session-manager.js";
25
25
  import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
26
26
  import { isInstallTelemetryEnabled } from "../../core/telemetry.js";
27
+ import { hasProjectConfigDir, hasProjectTrustInputs, ProjectTrustStore } from "../../core/trust-manager.js";
27
28
  import { getChangelogPath, getNewEntries, parseChangelog } from "../../utils/changelog.js";
28
29
  import { copyToClipboard } from "../../utils/clipboard.js";
29
30
  import { extensionForImageMimeType, readClipboardImage } from "../../utils/clipboard-image.js";
@@ -59,6 +60,7 @@ import { SettingsSelectorComponent } from "./components/settings-selector.js";
59
60
  import { SkillInvocationMessageComponent } from "./components/skill-invocation-message.js";
60
61
  import { ToolExecutionComponent } from "./components/tool-execution.js";
61
62
  import { TreeSelectorComponent } from "./components/tree-selector.js";
63
+ import { TrustSelectorComponent } from "./components/trust-selector.js";
62
64
  import { UserMessageComponent } from "./components/user-message.js";
63
65
  import { UserMessageSelectorComponent } from "./components/user-message-selector.js";
64
66
  import { getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, initTheme, onThemeChange, setRegisteredThemes, setTheme, setThemeInstance, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
@@ -213,6 +215,7 @@ export class InteractiveMode {
213
215
  // Custom header from extension (undefined = use built-in header)
214
216
  customHeader = undefined;
215
217
  options;
218
+ autoTrustOnReloadCwd;
216
219
  // Convenience accessors
217
220
  get session() {
218
221
  return this.runtimeHost.session;
@@ -229,6 +232,7 @@ export class InteractiveMode {
229
232
  constructor(runtimeHost, options = {}) {
230
233
  this.runtimeHost = runtimeHost;
231
234
  this.options = options;
235
+ this.autoTrustOnReloadCwd = options.autoTrustOnReloadCwd;
232
236
  this.runtimeHost.setBeforeSessionInvalidate(() => {
233
237
  this.resetExtensionUI();
234
238
  });
@@ -1129,6 +1133,7 @@ export class InteractiveMode {
1129
1133
  const uiContext = this.createExtensionUIContext();
1130
1134
  await this.session.bindExtensions({
1131
1135
  uiContext,
1136
+ mode: "tui",
1132
1137
  abortHandler: () => {
1133
1138
  this.restoreQueuedMessagesToEditor({ abort: true });
1134
1139
  },
@@ -1268,6 +1273,7 @@ export class InteractiveMode {
1268
1273
  // Create a context for shortcut handlers
1269
1274
  const createContext = () => ({
1270
1275
  ui: this.createExtensionUIContext(),
1276
+ mode: "tui",
1271
1277
  hasUI: true,
1272
1278
  cwd: this.sessionManager.getCwd(),
1273
1279
  sessionManager: this.sessionManager,
@@ -1553,6 +1559,20 @@ export class InteractiveMode {
1553
1559
  /**
1554
1560
  * Create the ExtensionUIContext for extensions.
1555
1561
  */
1562
+ createProjectTrustContext(cwd) {
1563
+ const ui = this.createExtensionUIContext();
1564
+ return {
1565
+ cwd,
1566
+ mode: "tui",
1567
+ hasUI: true,
1568
+ ui: {
1569
+ select: ui.select,
1570
+ confirm: ui.confirm,
1571
+ input: ui.input,
1572
+ notify: ui.notify,
1573
+ },
1574
+ };
1575
+ }
1556
1576
  createExtensionUIContext() {
1557
1577
  return {
1558
1578
  select: (title, options, opts) => this.showExtensionSelector(title, options, opts),
@@ -2057,6 +2077,11 @@ export class InteractiveMode {
2057
2077
  this.editor.setText("");
2058
2078
  return;
2059
2079
  }
2080
+ if (text === "/trust") {
2081
+ this.showTrustSelector();
2082
+ this.editor.setText("");
2083
+ return;
2084
+ }
2060
2085
  if (text === "/login") {
2061
2086
  this.showOAuthSelector("login");
2062
2087
  this.editor.setText("");
@@ -2526,6 +2551,7 @@ export class InteractiveMode {
2526
2551
  this.chatContainer.addChild(component);
2527
2552
  // Render user message separately if present
2528
2553
  if (skillBlock.userMessage) {
2554
+ this.chatContainer.addChild(new Spacer(1));
2529
2555
  const userComponent = new UserMessageComponent(skillBlock.userMessage, this.getMarkdownThemeWithSettings());
2530
2556
  this.chatContainer.addChild(userComponent);
2531
2557
  }
@@ -2625,6 +2651,7 @@ export class InteractiveMode {
2625
2651
  updateFooter: true,
2626
2652
  populateHistory: true,
2627
2653
  });
2654
+ this.renderProjectTrustWarningIfNeeded();
2628
2655
  // Show compaction info if session was compacted
2629
2656
  const allEntries = this.sessionManager.getEntries();
2630
2657
  const compactionCount = allEntries.filter((e) => e.type === "compaction").length;
@@ -2633,6 +2660,15 @@ export class InteractiveMode {
2633
2660
  this.showStatus(`Session compacted ${times}`);
2634
2661
  }
2635
2662
  }
2663
+ renderProjectTrustWarningIfNeeded() {
2664
+ if (this.settingsManager.isProjectTrusted() || !hasProjectTrustInputs(this.sessionManager.getCwd())) {
2665
+ return;
2666
+ }
2667
+ if (this.chatContainer.children.length > 0) {
2668
+ this.chatContainer.addChild(new Spacer(1));
2669
+ }
2670
+ this.chatContainer.addChild(new Text(theme.fg("warning", "This project is not trusted. Project instructions (AGENTS.md/CLAUDE.md), .pi resources, and project packages are ignored. Use /trust to save a trust decision, then restart pi."), 1, 0));
2671
+ }
2636
2672
  async getUserInput() {
2637
2673
  const queuedInput = this.pendingUserInputs.shift();
2638
2674
  if (queuedInput !== undefined) {
@@ -3448,6 +3484,51 @@ export class InteractiveMode {
3448
3484
  // Ignore auth lookup failures for warning-only checks.
3449
3485
  }
3450
3486
  }
3487
+ maybeSaveImplicitProjectTrustAfterReload() {
3488
+ const cwd = this.sessionManager.getCwd();
3489
+ if (this.autoTrustOnReloadCwd !== cwd) {
3490
+ return false;
3491
+ }
3492
+ if (!this.settingsManager.isProjectTrusted() || !hasProjectConfigDir(cwd)) {
3493
+ return false;
3494
+ }
3495
+ const trustStore = new ProjectTrustStore(this.runtimeHost.services.agentDir);
3496
+ try {
3497
+ if (trustStore.get(cwd) !== null) {
3498
+ this.autoTrustOnReloadCwd = undefined;
3499
+ return false;
3500
+ }
3501
+ trustStore.set(cwd, true);
3502
+ this.autoTrustOnReloadCwd = undefined;
3503
+ return true;
3504
+ }
3505
+ catch (error) {
3506
+ this.showWarning(`Could not save project trust after reload: ${error instanceof Error ? error.message : String(error)}`);
3507
+ return false;
3508
+ }
3509
+ }
3510
+ showTrustSelector() {
3511
+ const cwd = this.sessionManager.getCwd();
3512
+ const trustStore = new ProjectTrustStore(this.runtimeHost.services.agentDir);
3513
+ const savedDecision = trustStore.get(cwd);
3514
+ this.showSelector((done) => {
3515
+ const selector = new TrustSelectorComponent({
3516
+ cwd,
3517
+ savedDecision,
3518
+ projectTrusted: this.settingsManager.isProjectTrusted(),
3519
+ onSelect: (trusted) => {
3520
+ trustStore.set(cwd, trusted);
3521
+ done();
3522
+ this.showStatus(`Saved trust decision: ${trusted ? "trusted" : "untrusted"}. Restart pi for this to take effect.`);
3523
+ },
3524
+ onCancel: () => {
3525
+ done();
3526
+ this.ui.requestRender();
3527
+ },
3528
+ });
3529
+ return { component: selector, focus: selector };
3530
+ });
3531
+ }
3451
3532
  showModelSelector(initialSearchInput) {
3452
3533
  this.showSelector((done) => {
3453
3534
  const selector = new ModelSelectorComponent(this.ui, this.session.model, this.settingsManager, this.session.modelRegistry, this.session.scopedModels, async (model) => {
@@ -3726,6 +3807,7 @@ export class InteractiveMode {
3726
3807
  try {
3727
3808
  const result = await this.runtimeHost.switchSession(sessionPath, {
3728
3809
  withSession: options?.withSession,
3810
+ projectTrustContextFactory: (cwd) => this.createProjectTrustContext(cwd),
3729
3811
  });
3730
3812
  if (result.cancelled) {
3731
3813
  return result;
@@ -3744,6 +3826,7 @@ export class InteractiveMode {
3744
3826
  const result = await this.runtimeHost.switchSession(sessionPath, {
3745
3827
  cwdOverride: selectedCwd,
3746
3828
  withSession: options?.withSession,
3829
+ projectTrustContextFactory: (cwd) => this.createProjectTrustContext(cwd),
3747
3830
  });
3748
3831
  if (result.cancelled) {
3749
3832
  return result;
@@ -4142,11 +4225,14 @@ export class InteractiveMode {
4142
4225
  force: false,
4143
4226
  showDiagnosticsWhenQuiet: true,
4144
4227
  });
4228
+ const savedImplicitProjectTrust = this.maybeSaveImplicitProjectTrustAfterReload();
4145
4229
  const modelsJsonError = this.session.modelRegistry.getError();
4146
4230
  if (modelsJsonError) {
4147
4231
  this.showError(`models.json error: ${modelsJsonError}`);
4148
4232
  }
4149
- this.showStatus("Reloaded keybindings, extensions, skills, prompts, themes");
4233
+ this.showStatus(savedImplicitProjectTrust
4234
+ ? "Reloaded keybindings, extensions, skills, prompts, themes; saved project trust"
4235
+ : "Reloaded keybindings, extensions, skills, prompts, themes");
4150
4236
  }
4151
4237
  catch (error) {
4152
4238
  dismissReloadBox(previousEditor);