@earendil-works/pi-coding-agent 0.86.1 → 0.87.1

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 (160) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +25 -675
  3. package/dist/bundle/chunks/{anthropic-messages-MYU5ZMRF.js → anthropic-messages-J5WXPPPC.js} +1 -1
  4. package/dist/bundle/chunks/chunk-65HAU2C5.js +2 -0
  5. package/dist/bundle/chunks/{chunk-CMRUVXTE.js → chunk-OJP47DM6.js} +48 -42
  6. package/dist/bundle/chunks/github-copilot.js +1 -1
  7. package/dist/bundle/chunks/{openai-completions-CYGM3XXP.js → openai-completions-OBX42CLD.js} +2 -2
  8. package/dist/bundle/chunks/{virtual-modules-MGTKWDID.js → virtual-modules-VHMJYYWQ.js} +1 -1
  9. package/dist/bundle/cli-runtime.js +1 -1
  10. package/dist/bundle/index.js +1 -1
  11. package/dist/bundle/rpc-entry.js +1 -1
  12. package/dist/cli/args.d.ts.map +1 -1
  13. package/dist/cli/args.js +14 -4
  14. package/dist/cli/args.js.map +1 -1
  15. package/dist/cli/file-processor.d.ts +1 -1
  16. package/dist/cli/file-processor.d.ts.map +1 -1
  17. package/dist/cli/file-processor.js.map +1 -1
  18. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  19. package/dist/core/agent-session-runtime.js +1 -1
  20. package/dist/core/agent-session-runtime.js.map +1 -1
  21. package/dist/core/agent-session.d.ts +27 -3
  22. package/dist/core/agent-session.d.ts.map +1 -1
  23. package/dist/core/agent-session.js +389 -119
  24. package/dist/core/agent-session.js.map +1 -1
  25. package/dist/core/cache-warmer.d.ts +1 -0
  26. package/dist/core/cache-warmer.d.ts.map +1 -1
  27. package/dist/core/cache-warmer.js +15 -1
  28. package/dist/core/cache-warmer.js.map +1 -1
  29. package/dist/core/compaction/compaction.d.ts +3 -1
  30. package/dist/core/compaction/compaction.d.ts.map +1 -1
  31. package/dist/core/compaction/compaction.js +155 -57
  32. package/dist/core/compaction/compaction.js.map +1 -1
  33. package/dist/core/crash-log.d.ts +5 -0
  34. package/dist/core/crash-log.d.ts.map +1 -1
  35. package/dist/core/crash-log.js +68 -0
  36. package/dist/core/crash-log.js.map +1 -1
  37. package/dist/core/export-html/template.js +6 -1
  38. package/dist/core/extensions/index.d.ts +1 -1
  39. package/dist/core/extensions/index.d.ts.map +1 -1
  40. package/dist/core/extensions/index.js.map +1 -1
  41. package/dist/core/extensions/runner.d.ts +16 -3
  42. package/dist/core/extensions/runner.d.ts.map +1 -1
  43. package/dist/core/extensions/runner.js +110 -5
  44. package/dist/core/extensions/runner.js.map +1 -1
  45. package/dist/core/extensions/types.d.ts +77 -6
  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/index.d.ts +1 -1
  49. package/dist/core/index.d.ts.map +1 -1
  50. package/dist/core/index.js.map +1 -1
  51. package/dist/core/model-config.d.ts +52 -0
  52. package/dist/core/model-config.d.ts.map +1 -1
  53. package/dist/core/model-config.js +16 -0
  54. package/dist/core/model-config.js.map +1 -1
  55. package/dist/core/model-resolver.d.ts.map +1 -1
  56. package/dist/core/model-resolver.js +1 -1
  57. package/dist/core/model-resolver.js.map +1 -1
  58. package/dist/core/prompt-templates.d.ts +6 -1
  59. package/dist/core/prompt-templates.d.ts.map +1 -1
  60. package/dist/core/prompt-templates.js +61 -35
  61. package/dist/core/prompt-templates.js.map +1 -1
  62. package/dist/core/provider-composer.d.ts +1 -0
  63. package/dist/core/provider-composer.d.ts.map +1 -1
  64. package/dist/core/provider-composer.js +19 -0
  65. package/dist/core/provider-composer.js.map +1 -1
  66. package/dist/core/resource-loader.d.ts.map +1 -1
  67. package/dist/core/resource-loader.js +6 -2
  68. package/dist/core/resource-loader.js.map +1 -1
  69. package/dist/core/sdk.d.ts.map +1 -1
  70. package/dist/core/sdk.js +3 -4
  71. package/dist/core/sdk.js.map +1 -1
  72. package/dist/core/session-manager.d.ts +36 -9
  73. package/dist/core/session-manager.d.ts.map +1 -1
  74. package/dist/core/session-manager.js +97 -7
  75. package/dist/core/session-manager.js.map +1 -1
  76. package/dist/core/tools/read.d.ts +4 -1
  77. package/dist/core/tools/read.d.ts.map +1 -1
  78. package/dist/core/tools/read.js +5 -1
  79. package/dist/core/tools/read.js.map +1 -1
  80. package/dist/index.d.ts +2 -2
  81. package/dist/index.d.ts.map +1 -1
  82. package/dist/index.js +1 -1
  83. package/dist/index.js.map +1 -1
  84. package/dist/main.d.ts.map +1 -1
  85. package/dist/main.js +4 -3
  86. package/dist/main.js.map +1 -1
  87. package/dist/modes/interactive/bug-report.d.ts.map +1 -1
  88. package/dist/modes/interactive/bug-report.js +4 -0
  89. package/dist/modes/interactive/bug-report.js.map +1 -1
  90. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  91. package/dist/modes/interactive/components/tree-selector.js +7 -0
  92. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  93. package/dist/modes/interactive/interactive-mode.d.ts +3 -0
  94. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  95. package/dist/modes/interactive/interactive-mode.js +64 -2
  96. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  97. package/dist/utils/mime.d.ts.map +1 -1
  98. package/dist/utils/mime.js +1 -1
  99. package/dist/utils/mime.js.map +1 -1
  100. package/dist/utils/tool-result-images.d.ts +3 -1
  101. package/dist/utils/tool-result-images.d.ts.map +1 -1
  102. package/dist/utils/tool-result-images.js +4 -1
  103. package/dist/utils/tool-result-images.js.map +1 -1
  104. package/docs/cli-integration.md +106 -0
  105. package/docs/cli.md +268 -0
  106. package/docs/compaction.md +45 -26
  107. package/docs/configuration.md +45 -0
  108. package/docs/containerization.md +109 -82
  109. package/docs/custom-provider.md +132 -784
  110. package/docs/docs.json +139 -99
  111. package/docs/environment-variables.md +3 -5
  112. package/docs/extensions.md +134 -2956
  113. package/docs/how-pi-works.md +49 -0
  114. package/docs/images/interactive-mode.png +0 -0
  115. package/docs/index.md +24 -69
  116. package/docs/json.md +193 -65
  117. package/docs/keybindings.md +57 -102
  118. package/docs/llama-cpp.md +3 -3
  119. package/docs/message-types.md +261 -0
  120. package/docs/models.md +64 -546
  121. package/docs/packages.md +66 -167
  122. package/docs/prompt-templates.md +31 -68
  123. package/docs/providers.md +102 -240
  124. package/docs/quickstart.md +61 -106
  125. package/docs/rpc-commands.md +854 -0
  126. package/docs/rpc-extension-ui.md +200 -0
  127. package/docs/rpc.md +129 -1556
  128. package/docs/sdk.md +76 -1160
  129. package/docs/security.md +70 -32
  130. package/docs/session-format.md +25 -216
  131. package/docs/sessions.md +35 -141
  132. package/docs/settings.md +109 -387
  133. package/docs/shell-aliases.md +85 -5
  134. package/docs/skills.md +51 -190
  135. package/docs/slash-commands.md +60 -0
  136. package/docs/terminal-setup.md +105 -78
  137. package/docs/termux.md +74 -83
  138. package/docs/themes.md +68 -280
  139. package/docs/tmux.md +31 -39
  140. package/docs/tui.md +69 -923
  141. package/docs/usage.md +54 -272
  142. package/docs/windows.md +43 -17
  143. package/examples/README.md +13 -2
  144. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  145. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  146. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  147. package/examples/extensions/gondolin/package-lock.json +2 -2
  148. package/examples/extensions/gondolin/package.json +1 -1
  149. package/examples/extensions/sandbox/package-lock.json +2 -2
  150. package/examples/extensions/sandbox/package.json +1 -1
  151. package/examples/extensions/with-deps/package-lock.json +2 -2
  152. package/examples/extensions/with-deps/package.json +1 -1
  153. package/examples/plugins/pi-example-plugin/src/session.ts +3 -2
  154. package/examples/rpc-client.ts +35 -0
  155. package/examples/rpc-extension-ui.ts +25 -5
  156. package/examples/sdk/README.md +1 -1
  157. package/npm-shrinkwrap.json +20 -20
  158. package/package.json +8 -8
  159. package/dist/bundle/chunks/chunk-HTEQD2HM.js +0 -2
  160. package/docs/development.md +0 -90
@@ -16,12 +16,12 @@ import { parseSkillBlock } from "../../core/agent-session.js";
16
16
  import { SessionImportFileNotFoundError } from "../../core/agent-session-runtime.js";
17
17
  import { CACHE_TTL_MS, collectCacheMisses, computeCacheWaste, detectCacheMiss, } from "../../core/cache-stats.js";
18
18
  import { formatCacheWarmingStatus, formatCacheWarmingUsage } from "../../core/cache-warmer.js";
19
- import { recordCrash, takeUnnotifiedCrash } from "../../core/crash-log.js";
19
+ import { findExtensionStackMatches, recordCrash, takeUnnotifiedCrash } from "../../core/crash-log.js";
20
20
  import { DEFAULT_THINKING_LEVEL, THINKING_LEVEL_OPTIONS } from "../../core/defaults.js";
21
21
  import { FooterDataProvider } from "../../core/footer-data-provider.js";
22
22
  import { configureHttpDispatcher, formatHttpIdleTimeoutMs } from "../../core/http-dispatcher.js";
23
23
  import { KeybindingsManager } from "../../core/keybindings.js";
24
- import { createCompactionSummaryMessage } from "../../core/messages.js";
24
+ import { createCompactionSummaryMessage, createCustomMessage } from "../../core/messages.js";
25
25
  import { defaultModelPerProvider, findExactModelReferenceMatch, resolveModelScopeFromModels, } from "../../core/model-resolver.js";
26
26
  import { CredentialSynchronizationError } from "../../core/model-runtime.js";
27
27
  import { DefaultPackageManager } from "../../core/package-manager.js";
@@ -121,6 +121,22 @@ function isDeadTerminalError(error) {
121
121
  const code = error.code;
122
122
  return code !== undefined && DEAD_TERMINAL_ERROR_CODES.has(code);
123
123
  }
124
+ export function formatCrashExtensionHint(extensionMatches) {
125
+ const matches = Array.isArray(extensionMatches)
126
+ ? extensionMatches.filter((match) => typeof match === "string" && match.length > 0)
127
+ : [];
128
+ if (matches.length === 0)
129
+ return undefined;
130
+ const quoted = matches.map((match) => `\`${match}\``);
131
+ const labels = quoted.length === 1
132
+ ? quoted[0]
133
+ : quoted.length === 2
134
+ ? quoted.join(" and ")
135
+ : `${quoted.slice(0, -1).join(", ")}, and ${quoted[quoted.length - 1]}`;
136
+ const noun = matches.length === 1 ? "extension" : "extensions";
137
+ const pronoun = matches.length === 1 ? "it" : "them";
138
+ return `A stack frame came from loaded ${noun} ${labels}, which may be involved. Try disabling ${pronoun} with \`${APP_NAME} config\`, or run \`${APP_NAME} -ne\` to confirm.`;
139
+ }
124
140
  const ANTHROPIC_SUBSCRIPTION_AUTH_WARNING = "Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage. Disable this warning in /settings.";
125
141
  function isAnthropicSubscriptionAuthKey(apiKey) {
126
142
  return typeof apiKey === "string" && apiKey.startsWith("sk-ant-oat");
@@ -243,6 +259,7 @@ export class InteractiveMode {
243
259
  managedToolStatusStarted = false;
244
260
  // Streaming message tracking
245
261
  streamingComponent = undefined;
262
+ entriesRenderedByBoundaryCompaction = new Set();
246
263
  streamingMessage = undefined;
247
264
  // Tool execution tracking: toolCallId -> component
248
265
  pendingTools = new Map();
@@ -1540,6 +1557,10 @@ export class InteractiveMode {
1540
1557
  async handleFatalRuntimeError(prefix, error) {
1541
1558
  const message = error instanceof Error ? error.message : String(error);
1542
1559
  this.showError(`${prefix}: ${message}`);
1560
+ const extensionHint = this.getCrashExtensionHint(error);
1561
+ if (extensionHint) {
1562
+ this.chatContainer.addChild(new Text(theme.fg("warning", extensionHint), this.outputPad, 0));
1563
+ }
1543
1564
  if (this.recordCrash("fatal_error", error)) {
1544
1565
  this.chatContainer.addChild(new Text(theme.fg("muted", this.crashReportInstructions()), this.outputPad, 0));
1545
1566
  }
@@ -1547,6 +1568,14 @@ export class InteractiveMode {
1547
1568
  this.stop("transcript");
1548
1569
  process.exit(1);
1549
1570
  }
1571
+ getCrashExtensionHint(error) {
1572
+ try {
1573
+ return formatCrashExtensionHint(findExtensionStackMatches(error instanceof Error ? error.stack : undefined, this.session.resourceLoader.getExtensions().extensions));
1574
+ }
1575
+ catch {
1576
+ return undefined;
1577
+ }
1578
+ }
1550
1579
  /** Persist a crash so the next start can point the user at `/bug`. Returns false when nothing was written. */
1551
1580
  recordCrash(kind, error) {
1552
1581
  try {
@@ -2644,6 +2673,8 @@ export class InteractiveMode {
2644
2673
  this.ui.requestRender();
2645
2674
  break;
2646
2675
  case "entry_appended":
2676
+ if (this.entriesRenderedByBoundaryCompaction.delete(event.entry.id))
2677
+ break;
2647
2678
  if (event.entry.type === "custom") {
2648
2679
  this.addCustomEntryToChat(event.entry);
2649
2680
  this.ui.requestRender();
@@ -2652,6 +2683,34 @@ export class InteractiveMode {
2652
2683
  this.addCacheWarmingUsage(event.entry);
2653
2684
  this.ui.requestRender();
2654
2685
  }
2686
+ else if (event.entry.type === "custom_message" && event.entry.display) {
2687
+ this.addMessageToChat(createCustomMessage(event.entry.customType, event.entry.content, event.entry.display, event.entry.details, event.entry.timestamp));
2688
+ this.ui.requestRender();
2689
+ }
2690
+ else if (event.entry.type === "compaction") {
2691
+ const entries = this.sessionManager.buildContextEntries();
2692
+ if (entries[0]?.id !== event.entry.id)
2693
+ break;
2694
+ this.chatContainer.clear();
2695
+ const branch = this.sessionManager.getBranch();
2696
+ const compactionIndex = branch.findIndex((entry) => entry.id === event.entry.id);
2697
+ const entriesAfterCompaction = new Set(branch.slice(compactionIndex + 1).map((entry) => entry.id));
2698
+ const retainedEntries = entries.slice(1);
2699
+ this.renderSessionEntries(retainedEntries.filter((entry) => !entriesAfterCompaction.has(entry.id)));
2700
+ this.addMessageToChat(createCompactionSummaryMessage(event.entry.summary, event.entry.tokensBefore, event.entry.timestamp));
2701
+ if (event.entry.usage) {
2702
+ this.addCompactionCostNotice({
2703
+ type: "compaction_cost",
2704
+ kind: "compaction",
2705
+ usage: event.entry.usage,
2706
+ });
2707
+ }
2708
+ this.renderSessionEntries(retainedEntries.filter((entry) => entriesAfterCompaction.has(entry.id)));
2709
+ for (const entryId of entriesAfterCompaction)
2710
+ this.entriesRenderedByBoundaryCompaction.add(entryId);
2711
+ this.footer.invalidate();
2712
+ this.ui.requestRender();
2713
+ }
2655
2714
  break;
2656
2715
  case "session_info_changed":
2657
2716
  this.updateTerminalTitle();
@@ -3374,6 +3433,9 @@ export class InteractiveMode {
3374
3433
  catch { }
3375
3434
  console.error(`${APP_NAME} exiting due to uncaughtException:`);
3376
3435
  console.error(error);
3436
+ const extensionHint = this.getCrashExtensionHint(error);
3437
+ if (extensionHint)
3438
+ console.error(`\n${extensionHint}`);
3377
3439
  if (this.recordCrash("uncaught_exception", error)) {
3378
3440
  console.error(`\n${this.crashReportInstructions()}`);
3379
3441
  }