@oh-my-pi/pi-coding-agent 16.0.10 → 16.0.11

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 (86) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/cli.js +3208 -3199
  3. package/dist/types/advisor/index.d.ts +1 -0
  4. package/dist/types/advisor/transcript-recorder.d.ts +52 -0
  5. package/dist/types/commit/agentic/agent.d.ts +1 -1
  6. package/dist/types/config/settings-schema.d.ts +0 -4
  7. package/dist/types/edit/file-snapshot-store.d.ts +1 -1
  8. package/dist/types/extensibility/extensions/types.d.ts +7 -0
  9. package/dist/types/modes/components/agent-hub.d.ts +6 -1
  10. package/dist/types/modes/components/agent-transcript-viewer.d.ts +39 -0
  11. package/dist/types/modes/components/chat-transcript-builder.d.ts +42 -0
  12. package/dist/types/modes/controllers/command-controller.d.ts +3 -2
  13. package/dist/types/modes/interactive-mode.d.ts +2 -1
  14. package/dist/types/modes/types.d.ts +2 -1
  15. package/dist/types/registry/agent-registry.d.ts +10 -3
  16. package/dist/types/session/compact-modes.d.ts +60 -0
  17. package/dist/types/session/streaming-output.d.ts +0 -2
  18. package/dist/types/tools/__tests__/json-tree.test.d.ts +1 -0
  19. package/package.json +12 -12
  20. package/src/advisor/index.ts +1 -0
  21. package/src/advisor/transcript-recorder.ts +136 -0
  22. package/src/cli/stats-cli.ts +2 -11
  23. package/src/collab/host.ts +25 -13
  24. package/src/commit/agentic/agent.ts +2 -1
  25. package/src/commit/agentic/tools/git-file-diff.ts +2 -2
  26. package/src/commit/changelog/index.ts +1 -1
  27. package/src/commit/map-reduce/map-phase.ts +1 -1
  28. package/src/commit/map-reduce/utils.ts +1 -1
  29. package/src/config/settings-schema.ts +0 -5
  30. package/src/config/settings.ts +0 -6
  31. package/src/edit/file-snapshot-store.ts +1 -1
  32. package/src/edit/renderer.ts +7 -7
  33. package/src/eval/js/tool-bridge.ts +3 -2
  34. package/src/eval/py/prelude.py +3 -2
  35. package/src/export/html/tool-views.generated.js +28 -28
  36. package/src/extensibility/extensions/types.ts +7 -0
  37. package/src/hindsight/mental-models.ts +1 -1
  38. package/src/internal-urls/docs-index.generated.txt +1 -1
  39. package/src/internal-urls/history-protocol.ts +8 -3
  40. package/src/irc/bus.ts +8 -0
  41. package/src/lsp/index.ts +2 -2
  42. package/src/main.ts +4 -1
  43. package/src/modes/acp/acp-agent.ts +63 -0
  44. package/src/modes/components/agent-hub.ts +97 -920
  45. package/src/modes/components/agent-transcript-viewer.ts +461 -0
  46. package/src/modes/components/chat-transcript-builder.ts +462 -0
  47. package/src/modes/components/diff.ts +12 -35
  48. package/src/modes/controllers/command-controller.ts +12 -2
  49. package/src/modes/controllers/event-controller.ts +1 -1
  50. package/src/modes/controllers/input-controller.ts +8 -1
  51. package/src/modes/controllers/selector-controller.ts +4 -1
  52. package/src/modes/interactive-mode.ts +4 -2
  53. package/src/modes/types.ts +2 -1
  54. package/src/prompts/tools/read.md +1 -1
  55. package/src/registry/agent-registry.ts +13 -4
  56. package/src/sdk.ts +1 -1
  57. package/src/session/agent-session.ts +92 -3
  58. package/src/session/compact-modes.ts +105 -0
  59. package/src/session/session-dump-format.ts +1 -1
  60. package/src/session/session-history-format.ts +1 -1
  61. package/src/session/streaming-output.ts +5 -5
  62. package/src/slash-commands/builtin-registry.ts +16 -4
  63. package/src/task/executor.ts +1 -1
  64. package/src/task/output-manager.ts +5 -0
  65. package/src/tools/__tests__/json-tree.test.ts +35 -0
  66. package/src/tools/approval.ts +1 -1
  67. package/src/tools/bash.ts +0 -1
  68. package/src/tools/browser.ts +0 -1
  69. package/src/tools/eval.ts +1 -1
  70. package/src/tools/gh.ts +1 -1
  71. package/src/tools/irc.ts +1 -1
  72. package/src/tools/json-tree.ts +22 -5
  73. package/src/tools/read.ts +5 -6
  74. package/src/web/scrapers/firefox-addons.ts +1 -1
  75. package/src/web/scrapers/github.ts +1 -1
  76. package/src/web/scrapers/go-pkg.ts +2 -2
  77. package/src/web/scrapers/metacpan.ts +2 -2
  78. package/src/web/scrapers/nvd.ts +2 -2
  79. package/src/web/scrapers/ollama.ts +1 -1
  80. package/src/web/scrapers/opencorporates.ts +1 -1
  81. package/src/web/scrapers/pub-dev.ts +1 -1
  82. package/src/web/scrapers/repology.ts +1 -1
  83. package/src/web/scrapers/sourcegraph.ts +1 -1
  84. package/src/web/scrapers/terraform.ts +6 -6
  85. package/src/web/scrapers/wikidata.ts +2 -2
  86. package/src/workspace-tree.ts +1 -1
@@ -1,7 +1,8 @@
1
- import { INTENT_FIELD, type ThinkingLevel } from "@oh-my-pi/pi-agent-core";
1
+ import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
2
2
  import type { Api, Model } from "@oh-my-pi/pi-ai";
3
3
  import { Markdown } from "@oh-my-pi/pi-tui";
4
4
  import { prompt } from "@oh-my-pi/pi-utils";
5
+ import { INTENT_FIELD } from "@oh-my-pi/pi-wire";
5
6
  import chalk from "chalk";
6
7
  import typesDescriptionPrompt from "../../commit/prompts/types-description.md" with { type: "text" };
7
8
  import type { ModelRegistry } from "../../config/model-registry";
@@ -87,7 +87,7 @@ function truncateDiffContent(diff: string): { content: string; truncated: boolea
87
87
  const truncatedCount = lines.length - KEEP_HEAD_LINES - KEEP_TAIL_LINES;
88
88
 
89
89
  return {
90
- content: [...head, `\n... (truncated ${truncatedCount} lines) ...\n`, ...tail].join("\n"),
90
+ content: [...head, `\n[…${truncatedCount}ln elided…]\n`, ...tail].join("\n"),
91
91
  truncated: true,
92
92
  };
93
93
  }
@@ -117,7 +117,7 @@ function processDiffs(files: string[], diffs: Map<string, string>): { result: st
117
117
  }
118
118
  content = truncated;
119
119
  if (content.length > remaining) {
120
- content = `${content.slice(0, remaining)}\n... (diff truncated due to size) ...`;
120
+ content = `${content.slice(0, remaining)}\n[…${content.length - remaining}ch elided…]`;
121
121
  if (!truncatedFiles.includes(file)) {
122
122
  truncatedFiles.push(file);
123
123
  }
@@ -138,7 +138,7 @@ export async function applyChangelogProposals({
138
138
 
139
139
  function truncateDiff(diff: string, maxChars: number): string {
140
140
  if (diff.length <= maxChars) return diff;
141
- return `${diff.slice(0, maxChars)}\n... (truncated)`;
141
+ return `${diff.slice(0, maxChars)}\n[…${diff.length - maxChars}ch elided…]`;
142
142
  }
143
143
 
144
144
  function formatExistingEntries(entries: Record<string, string[]>): string {
@@ -126,7 +126,7 @@ function generateContextHeader(files: FileDiff[], currentFile: string): string {
126
126
  }
127
127
 
128
128
  if (toShow.length < sorted.length) {
129
- lines.push(`... and ${sorted.length - toShow.length} more files`);
129
+ lines.push(`[…${sorted.length - toShow.length} files elided…]`);
130
130
  }
131
131
 
132
132
  return lines.join("\n");
@@ -5,5 +5,5 @@ export function estimateTokens(text: string): number {
5
5
  export function truncateToTokenLimit(text: string, maxTokens: number): string {
6
6
  const maxChars = maxTokens * 4;
7
7
  if (text.length <= maxChars) return text;
8
- return `${text.slice(0, maxChars)}\n... (truncated)`;
8
+ return `${text.slice(0, maxChars)}\n[…${text.length - maxChars}ch elided…]`;
9
9
  }
@@ -809,11 +809,6 @@ export const SETTINGS_SCHEMA = {
809
809
  description: "Remove the 1-character horizontal padding from the left and right of the terminal output",
810
810
  },
811
811
  },
812
- // Display rendering
813
- "display.tabWidth": {
814
- type: "number",
815
- default: 3,
816
- },
817
812
 
818
813
  "display.shimmer": {
819
814
  type: "enum",
@@ -22,7 +22,6 @@ import {
22
22
  isEnoent,
23
23
  logger,
24
24
  procmgr,
25
- setDefaultTabWidth,
26
25
  } from "@oh-my-pi/pi-utils";
27
26
  import { JSONC, YAML } from "bun";
28
27
  import { type Settings as SettingsCapabilityItem, settingsCapability } from "../capability/settings";
@@ -1103,11 +1102,6 @@ const SETTING_HOOKS: Partial<Record<SettingPath, SettingHook<any>>> = {
1103
1102
  });
1104
1103
  }
1105
1104
  },
1106
- "display.tabWidth": value => {
1107
- if (typeof value === "number") {
1108
- setDefaultTabWidth(value);
1109
- }
1110
- },
1111
1105
  "provider.appendOnlyContext": value => {
1112
1106
  if (typeof value === "string") {
1113
1107
  appendOnlyModeSignal.fire(value);
@@ -102,7 +102,7 @@ const HASHLINE_LINE_PREFIX = /^[ *]?(\d+)(?:-(\d+))?:/;
102
102
  /**
103
103
  * The 1-indexed file lines a hashline-formatted body actually displayed.
104
104
  * Single `NN:` rows contribute that line; a collapsed summary `NN-MM:` row
105
- * (a `{ .. }` brace pair) contributes only its boundary lines `NN` and `MM` —
105
+ * (a `{ }` brace pair) contributes only its boundary lines `NN` and `MM` —
106
106
  * the elided interior was never shown, so editing inside it must be rejected.
107
107
  */
108
108
  export function parseSeenLinesFromHashlineBody(body: string): number[] {
@@ -230,7 +230,7 @@ function truncateEditTitlePath(displayPath: string, maxWidth: number | undefined
230
230
  }
231
231
 
232
232
  function formatEditTitlePath(pathValue: string, maxWidth?: number): string {
233
- return truncateEditTitlePath(replaceTabs(shortenPath(pathValue), pathValue), maxWidth);
233
+ return truncateEditTitlePath(replaceTabs(shortenPath(pathValue)), maxWidth);
234
234
  }
235
235
 
236
236
  function formatEditPathDisplay(
@@ -326,11 +326,11 @@ function renderEditHeader(
326
326
  return buildHeader(fitted.description);
327
327
  }
328
328
 
329
- function renderPlainTextPreview(text: string, uiTheme: Theme, filePath?: string): string {
329
+ function renderPlainTextPreview(text: string, uiTheme: Theme, _filePath?: string): string {
330
330
  const previewLines = sanitizeText(text).split("\n");
331
331
  let preview = "\n\n";
332
332
  for (const line of previewLines.slice(0, CALL_TEXT_PREVIEW_LINES)) {
333
- preview += `${uiTheme.fg("toolOutput", truncateToWidth(replaceTabs(line, filePath), CALL_TEXT_PREVIEW_WIDTH))}\n`;
333
+ preview += `${uiTheme.fg("toolOutput", truncateToWidth(replaceTabs(line), CALL_TEXT_PREVIEW_WIDTH))}\n`;
334
334
  }
335
335
  if (previewLines.length > CALL_TEXT_PREVIEW_LINES) {
336
336
  preview += uiTheme.fg("dim", `… ${previewLines.length - CALL_TEXT_PREVIEW_LINES} more lines`);
@@ -395,7 +395,7 @@ function formatMultiFileStreamingDiff(
395
395
  if (!preview.diff && !preview.error) continue;
396
396
  const header = uiTheme.fg("dim", `\n\n── ${shortenPath(preview.path)} ──`);
397
397
  if (preview.error) {
398
- parts.push(`${header}\n${uiTheme.fg("error", replaceTabs(preview.error, preview.path))}`);
398
+ parts.push(`${header}\n${uiTheme.fg("error", replaceTabs(preview.error))}`);
399
399
  continue;
400
400
  }
401
401
  if (preview.diff) {
@@ -637,7 +637,7 @@ export const editToolRenderer = {
637
637
  callPreviewCaches,
638
638
  );
639
639
  if (applyPatchSummary?.error) {
640
- body += `\n${uiTheme.fg("error", truncateToWidth(replaceTabs(applyPatchSummary.error, rawPath), Math.max(1, width - 2)))}`;
640
+ body += `\n${uiTheme.fg("error", truncateToWidth(replaceTabs(applyPatchSummary.error), Math.max(1, width - 2)))}`;
641
641
  }
642
642
  const bodyLines = body ? body.split("\n") : [];
643
643
  while (bodyLines.length > 0 && bodyLines[0].trim() === "") bodyLines.shift();
@@ -733,11 +733,11 @@ function renderSingleFileResult(
733
733
 
734
734
  let body = "";
735
735
  if (isError) {
736
- if (errorText) body = uiTheme.fg("error", replaceTabs(errorText, rawPath));
736
+ if (errorText) body = uiTheme.fg("error", replaceTabs(errorText));
737
737
  } else if (details?.diff) {
738
738
  body = renderDiffSection(details.diff, rawPath, expanded, uiTheme, renderDiffFn, diffSectionCache);
739
739
  } else if (editDiffPreview) {
740
- if ("error" in editDiffPreview) body = uiTheme.fg("error", replaceTabs(editDiffPreview.error, rawPath));
740
+ if ("error" in editDiffPreview) body = uiTheme.fg("error", replaceTabs(editDiffPreview.error));
741
741
  else if (editDiffPreview.diff)
742
742
  body = renderDiffSection(editDiffPreview.diff, rawPath, expanded, uiTheme, renderDiffFn, diffSectionCache);
743
743
  }
@@ -1,4 +1,5 @@
1
1
  import type { AgentTool, AgentToolResult } from "@oh-my-pi/pi-agent-core";
2
+ import { INTENT_FIELD } from "@oh-my-pi/pi-wire";
2
3
  import type { ToolSession } from "../../tools";
3
4
  import { ToolError } from "../../tools/tool-errors";
4
5
  import { EVAL_AGENT_BRIDGE_NAME, runEvalAgent } from "../agent-bridge";
@@ -48,8 +49,8 @@ function normalizeArgs(args: unknown): unknown {
48
49
  return args;
49
50
  }
50
51
  const record = { ...(args as Record<string, unknown>) };
51
- if (record._i === undefined) {
52
- record._i = "js prelude";
52
+ if (record[INTENT_FIELD] === undefined) {
53
+ record[INTENT_FIELD] = "js prelude";
53
54
  }
54
55
  return record;
55
56
  }
@@ -5,6 +5,7 @@ if "__omp_prelude_loaded__" not in globals():
5
5
  from pathlib import Path
6
6
  import os, json, math, re
7
7
  from urllib.parse import unquote
8
+ INTENT_FIELD = "_i"
8
9
 
9
10
  # __omp_display is injected by runner.py before the prelude executes; it
10
11
  # mirrors IPython's display() semantics with the same MIME bundle output.
@@ -479,8 +480,8 @@ if "__omp_prelude_loaded__" not in globals():
479
480
  f"tool.{self._name}(...) expects a dict of arguments (got {type(args).__name__})"
480
481
  )
481
482
  merged.update(kwargs)
482
- if "_i" not in merged:
483
- merged["_i"] = "py prelude"
483
+ if INTENT_FIELD not in merged:
484
+ merged[INTENT_FIELD] = "py prelude"
484
485
  return _bridge_call(self._name, merged)
485
486
 
486
487
  class _ToolProxy: