@oh-my-pi/pi-coding-agent 14.9.3 → 14.9.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 (108) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/package.json +7 -7
  3. package/src/async/job-manager.ts +66 -9
  4. package/src/capability/rule.ts +20 -0
  5. package/src/cli/setup-cli.ts +14 -161
  6. package/src/cli/stats-cli.ts +56 -2
  7. package/src/cli.ts +0 -1
  8. package/src/config/model-registry.ts +13 -0
  9. package/src/config/model-resolver.ts +8 -2
  10. package/src/config/settings-schema.ts +1 -11
  11. package/src/edit/index.ts +8 -0
  12. package/src/edit/renderer.ts +6 -1
  13. package/src/edit/streaming.ts +53 -2
  14. package/src/eval/eval.lark +30 -10
  15. package/src/eval/js/context-manager.ts +334 -601
  16. package/src/eval/js/shared/helpers.ts +237 -0
  17. package/src/eval/js/shared/indirect-eval.ts +30 -0
  18. package/src/eval/js/{prelude.txt → shared/prelude.txt} +0 -2
  19. package/src/eval/js/shared/rewrite-imports.ts +211 -0
  20. package/src/eval/js/shared/runtime.ts +168 -0
  21. package/src/eval/js/shared/types.ts +18 -0
  22. package/src/eval/js/tool-bridge.ts +2 -4
  23. package/src/eval/js/worker-core.ts +146 -0
  24. package/src/eval/js/worker-entry.ts +24 -0
  25. package/src/eval/js/worker-protocol.ts +41 -0
  26. package/src/eval/parse.ts +218 -49
  27. package/src/eval/py/display.ts +71 -0
  28. package/src/eval/py/executor.ts +97 -96
  29. package/src/eval/py/index.ts +2 -2
  30. package/src/eval/py/kernel.ts +472 -900
  31. package/src/eval/py/prelude.py +106 -87
  32. package/src/eval/py/runner.py +879 -0
  33. package/src/eval/py/runtime.ts +3 -16
  34. package/src/eval/py/tool-bridge.ts +137 -0
  35. package/src/export/html/template.css +12 -0
  36. package/src/export/html/template.generated.ts +1 -1
  37. package/src/export/html/template.js +113 -7
  38. package/src/extensibility/plugins/loader.ts +31 -6
  39. package/src/extensibility/skills.ts +20 -0
  40. package/src/internal-urls/agent-protocol.ts +63 -52
  41. package/src/internal-urls/artifact-protocol.ts +51 -51
  42. package/src/internal-urls/docs-index.generated.ts +35 -3
  43. package/src/internal-urls/index.ts +6 -19
  44. package/src/internal-urls/local-protocol.ts +49 -7
  45. package/src/internal-urls/mcp-protocol.ts +2 -8
  46. package/src/internal-urls/memory-protocol.ts +89 -59
  47. package/src/internal-urls/router.ts +38 -22
  48. package/src/internal-urls/rule-protocol.ts +2 -20
  49. package/src/internal-urls/skill-protocol.ts +4 -27
  50. package/src/main.ts +1 -1
  51. package/src/mcp/manager.ts +17 -0
  52. package/src/modes/components/session-observer-overlay.ts +2 -2
  53. package/src/modes/components/tool-execution.ts +6 -0
  54. package/src/modes/components/tree-selector.ts +4 -0
  55. package/src/modes/controllers/command-controller.ts +0 -23
  56. package/src/modes/controllers/event-controller.ts +23 -2
  57. package/src/modes/controllers/mcp-command-controller.ts +7 -10
  58. package/src/modes/interactive-mode.ts +2 -2
  59. package/src/modes/theme/theme.ts +27 -27
  60. package/src/modes/types.ts +1 -1
  61. package/src/modes/utils/ui-helpers.ts +14 -9
  62. package/src/prompts/commands/orchestrate.md +1 -0
  63. package/src/prompts/system/project-prompt.md +10 -2
  64. package/src/prompts/system/subagent-system-prompt.md +8 -8
  65. package/src/prompts/system/system-prompt.md +13 -7
  66. package/src/prompts/tools/ask.md +0 -1
  67. package/src/prompts/tools/bash.md +0 -10
  68. package/src/prompts/tools/eval.md +15 -30
  69. package/src/prompts/tools/github.md +6 -5
  70. package/src/prompts/tools/hashline.md +1 -0
  71. package/src/prompts/tools/job.md +14 -6
  72. package/src/prompts/tools/task.md +20 -3
  73. package/src/registry/agent-registry.ts +2 -1
  74. package/src/sdk.ts +87 -89
  75. package/src/session/agent-session.ts +58 -21
  76. package/src/session/artifacts.ts +7 -4
  77. package/src/session/history-storage.ts +77 -19
  78. package/src/session/session-manager.ts +30 -1
  79. package/src/ssh/connection-manager.ts +32 -16
  80. package/src/ssh/sshfs-mount.ts +10 -7
  81. package/src/system-prompt.ts +0 -5
  82. package/src/task/executor.ts +14 -2
  83. package/src/task/index.ts +19 -5
  84. package/src/tool-discovery/tool-index.ts +21 -8
  85. package/src/tools/ast-edit.ts +3 -2
  86. package/src/tools/ast-grep.ts +3 -2
  87. package/src/tools/bash.ts +15 -9
  88. package/src/tools/browser/tab-protocol.ts +4 -0
  89. package/src/tools/browser/tab-supervisor.ts +98 -7
  90. package/src/tools/browser/tab-worker.ts +104 -58
  91. package/src/tools/eval.ts +49 -11
  92. package/src/tools/fetch.ts +1 -1
  93. package/src/tools/gh.ts +140 -4
  94. package/src/tools/index.ts +12 -11
  95. package/src/tools/job.ts +48 -12
  96. package/src/tools/read.ts +5 -4
  97. package/src/tools/search.ts +3 -2
  98. package/src/tools/todo-write.ts +1 -1
  99. package/src/web/scrapers/mastodon.ts +1 -1
  100. package/src/web/scrapers/repology.ts +7 -7
  101. package/src/web/search/index.ts +6 -4
  102. package/src/cli/jupyter-cli.ts +0 -106
  103. package/src/commands/jupyter.ts +0 -32
  104. package/src/eval/py/cancellation.ts +0 -28
  105. package/src/eval/py/gateway-coordinator.ts +0 -424
  106. package/src/internal-urls/jobs-protocol.ts +0 -120
  107. package/src/prompts/system/now-prompt.md +0 -7
  108. /package/src/eval/js/{prelude.ts → shared/prelude.ts} +0 -0
@@ -905,7 +905,7 @@ export const SETTINGS_SCHEMA = {
905
905
 
906
906
  "ask.timeout": {
907
907
  type: "number",
908
- default: 30,
908
+ default: 0,
909
909
  ui: {
910
910
  tab: "interaction",
911
911
  label: "Ask Timeout",
@@ -1662,16 +1662,6 @@ export const SETTINGS_SCHEMA = {
1662
1662
  },
1663
1663
  },
1664
1664
 
1665
- "python.sharedGateway": {
1666
- type: "boolean",
1667
- default: true,
1668
- ui: {
1669
- tab: "editing",
1670
- label: "Shared Python Gateway",
1671
- description: "Share IPython kernel gateway across pi instances",
1672
- },
1673
- },
1674
-
1675
1665
  // ────────────────────────────────────────────────────────────────────────
1676
1666
  // Tools
1677
1667
  // ────────────────────────────────────────────────────────────────────────
package/src/edit/index.ts CHANGED
@@ -204,6 +204,7 @@ async function executeSinglePathEntries(
204
204
  const contentTexts: string[] = [];
205
205
  const diffTexts: string[] = [];
206
206
  let firstChangedLine: number | undefined;
207
+ let errorCount = 0;
207
208
 
208
209
  for (let i = 0; i < runs.length; i++) {
209
210
  const isLast = i === runs.length - 1;
@@ -221,6 +222,7 @@ async function executeSinglePathEntries(
221
222
  } catch (err) {
222
223
  const errorText = err instanceof Error ? err.message : String(err);
223
224
  contentTexts.push(`Error editing ${path}: ${errorText}`);
225
+ errorCount++;
224
226
  }
225
227
 
226
228
  if (!isLast && onUpdate) {
@@ -230,6 +232,7 @@ async function executeSinglePathEntries(
230
232
  diff: diffTexts.join("\n"),
231
233
  firstChangedLine,
232
234
  },
235
+ ...(errorCount > 0 ? { isError: true } : {}),
233
236
  });
234
237
  }
235
238
  }
@@ -240,6 +243,11 @@ async function executeSinglePathEntries(
240
243
  diff: diffTexts.join("\n"),
241
244
  firstChangedLine,
242
245
  },
246
+ // Any per-entry failure marks the aggregate result as an error so the
247
+ // renderer takes the error branch instead of falling through to the
248
+ // streaming-edit preview (which displays the *proposed* diff and looks
249
+ // indistinguishable from success).
250
+ ...(errorCount > 0 ? { isError: true } : {}),
243
251
  };
244
252
  }
245
253
 
@@ -148,6 +148,8 @@ export interface EditRenderContext {
148
148
  editDiffPreview?: DiffResult | DiffError;
149
149
  /** Multi-file streaming diff preview (edits spanning several files) */
150
150
  perFileDiffPreview?: PerFileDiffPreview[];
151
+ /** Raw in-flight edit text shown while a computed diff preview is unavailable */
152
+ editStreamingFallback?: string;
151
153
  /** Function to render diff text with syntax highlighting */
152
154
  renderDiff?: (diffText: string, options?: { filePath?: string }) => string;
153
155
  }
@@ -272,7 +274,7 @@ function formatMultiFileStreamingDiff(previews: PerFileDiffPreview[], uiTheme: T
272
274
  const parts: string[] = [];
273
275
  for (const preview of previews) {
274
276
  if (!preview.diff && !preview.error) continue;
275
- const header = uiTheme.fg("dim", `\n\n\u2500\u2500 ${shortenPath(preview.path)} \u2500\u2500`);
277
+ const header = uiTheme.fg("dim", `\n\n── ${shortenPath(preview.path)} ──`);
276
278
  if (preview.error) {
277
279
  parts.push(`${header}\n${uiTheme.fg("error", replaceTabs(preview.error, preview.path))}`);
278
280
  continue;
@@ -306,6 +308,9 @@ function getCallPreview(
306
308
  if (args.newText || args.patch) {
307
309
  return renderPlainTextPreview(args.newText ?? args.patch ?? "", uiTheme, rawPath);
308
310
  }
311
+ if (renderContext?.editStreamingFallback) {
312
+ return renderContext.editStreamingFallback;
313
+ }
309
314
  return "";
310
315
  }
311
316
 
@@ -13,14 +13,19 @@
13
13
  * the injected `editMode` rather than probing argument shape.
14
14
  */
15
15
 
16
+ import { sanitizeText } from "@oh-my-pi/pi-natives";
16
17
  import {
18
+ ABORT_MARKER,
19
+ BEGIN_PATCH_MARKER,
17
20
  computeHashlineDiff,
18
21
  computeHashlineSectionDiff,
19
22
  containsRecognizableHashlineOperations,
23
+ END_PATCH_MARKER,
20
24
  type HashlineInputSection,
21
25
  splitHashlineInputs,
22
26
  } from "../hashline";
23
27
  import type { Theme } from "../modes/theme/theme";
28
+ import { replaceTabs, truncateToWidth } from "../tools/render-utils";
24
29
  import { type EditMode, resolveEditMode } from "../utils/edit-mode";
25
30
  import { computeEditDiff, type DiffError, type DiffResult } from "./diff";
26
31
  import { type ApplyPatchEntry, expandApplyPatchToEntries, expandApplyPatchToPreviewEntries } from "./modes/apply-patch";
@@ -61,6 +66,52 @@ export interface EditStreamingStrategy<Args = unknown> {
61
66
  renderStreamingFallback(args: Args, uiTheme: Theme): string;
62
67
  }
63
68
 
69
+ const STREAMING_FALLBACK_LINES = 12;
70
+ const STREAMING_FALLBACK_WIDTH = 80;
71
+
72
+ function isHashlineHeaderLine(line: string): boolean {
73
+ const trimmed = line.trimEnd();
74
+ return trimmed.startsWith("@") && trimmed.length > 1;
75
+ }
76
+
77
+ function isHashlineEnvelopeMarkerLine(line: string): boolean {
78
+ const trimmed = line.trimEnd();
79
+ return trimmed === BEGIN_PATCH_MARKER || trimmed === END_PATCH_MARKER || trimmed === ABORT_MARKER;
80
+ }
81
+
82
+ function trimHashlineStreamingSyntax(lines: string[]): string[] {
83
+ let index = lines.findIndex(line => line.trim().length > 0);
84
+ if (index === -1) return [];
85
+
86
+ if (lines[index].trimEnd() === BEGIN_PATCH_MARKER) {
87
+ index++;
88
+ while (index < lines.length && lines[index].trim().length === 0) index++;
89
+ }
90
+ if (index < lines.length && isHashlineHeaderLine(lines[index])) {
91
+ index++;
92
+ }
93
+
94
+ return lines.slice(index).filter(line => !isHashlineEnvelopeMarkerLine(line));
95
+ }
96
+
97
+ function renderHashlineInputFallback(input: string, uiTheme: Theme): string {
98
+ const lines = trimHashlineStreamingSyntax(sanitizeText(input).split("\n"));
99
+ if (!lines.some(line => line.trim().length > 0)) return "";
100
+
101
+ const displayLines = lines.slice(-STREAMING_FALLBACK_LINES);
102
+ const hidden = lines.length - displayLines.length;
103
+ let text = "\n\n";
104
+ text += displayLines
105
+ .map(line => uiTheme.fg("toolOutput", truncateToWidth(replaceTabs(line), STREAMING_FALLBACK_WIDTH)))
106
+ .join("\n");
107
+ if (hidden > 0) {
108
+ text += uiTheme.fg("dim", `\n… (streaming +${hidden} lines)`);
109
+ } else {
110
+ text += uiTheme.fg("dim", "\n(streaming)");
111
+ }
112
+ return text;
113
+ }
114
+
64
115
  // -----------------------------------------------------------------------------
65
116
  // Partial-JSON handling
66
117
  // -----------------------------------------------------------------------------
@@ -273,8 +324,8 @@ const hashlineStrategy: EditStreamingStrategy<HashlineArgs> = {
273
324
  }
274
325
  return previews.length > 0 ? previews : null;
275
326
  },
276
- renderStreamingFallback() {
277
- return "";
327
+ renderStreamingFallback(args, uiTheme) {
328
+ return typeof args.input === "string" ? renderHashlineInputFallback(args.input, uiTheme) : "";
278
329
  },
279
330
  };
280
331
 
@@ -1,16 +1,36 @@
1
- start: cell+
1
+ // Canonical Eval input. Each cell is introduced by a single header line:
2
+ //
3
+ // *** Cell <LANG>:"<title>" [t:<duration>] [rst]
4
+ //
5
+ // Attribute order is fixed: language+title, then optional timeout, then
6
+ // optional reset flag. Title may be empty (`py:""`).
7
+ //
8
+ // Tokens:
9
+ //
10
+ // py:"..." | js:"..." language plus title (required)
11
+ // t:<digits>(ms|s|m)? per-cell timeout (default 30s)
12
+ // rst reset this language's kernel before running
13
+ //
14
+ // Everything between one header line and the next (or the optional trailing
15
+ // `*** End`, or end of input) is the cell's code, verbatim. The runtime
16
+ // parser additionally accepts content before the first header as an implicit
17
+ // default-language cell, but that is lenient fallback and MUST NOT be relied
18
+ // on.
2
19
 
3
- cell: begin_cell attr* code_line* end_cell
4
- begin_cell: "*** Begin " LANG LF
5
- end_cell: "*** End Cell" LF?
20
+ start: cell+ end_marker
6
21
 
7
- attr: title | timeout | reset
8
- title: "*** Title: " /(.+)/ LF
9
- timeout: "*** Timeout: " /\d+(ms|s|m)?/ LF
10
- reset: "*** Reset" LF
22
+ cell: cell_header code_line*
11
23
 
12
- code_line: /[^\r\n]*/ LF
24
+ cell_header: "*** Cell" WS_INLINE LANG_TITLE (WS_INLINE T_ATTR)? (WS_INLINE RST_FLAG)? LF
13
25
 
14
- LANG: "JS" | "TS" | "PY"
26
+ end_marker: "*** End" LF?
27
+
28
+ code_line: CODE_TEXT LF | LF
29
+ CODE_TEXT: /([^*\r\n]|\*\*?[^*\r\n])+\*{0,2}|\*{1,2}/
30
+
31
+ LANG_TITLE: ("py" | "js") ":\"" /[^"\r\n]*/ "\""
32
+ T_ATTR: "t:" /\d+(ms|s|m)?/
33
+ RST_FLAG: "rst"
15
34
 
16
35
  %import common.LF
36
+ %import common.WS_INLINE