@oh-my-pi/pi-coding-agent 15.0.2 → 15.1.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 (138) hide show
  1. package/CHANGELOG.md +56 -1
  2. package/examples/custom-tools/README.md +11 -7
  3. package/examples/custom-tools/hello/index.ts +2 -2
  4. package/examples/extensions/README.md +19 -8
  5. package/examples/extensions/api-demo.ts +15 -19
  6. package/examples/extensions/hello.ts +5 -6
  7. package/examples/extensions/plan-mode.ts +1 -1
  8. package/examples/extensions/reload-runtime.ts +4 -3
  9. package/examples/extensions/with-deps/index.ts +4 -3
  10. package/examples/sdk/06-extensions.ts +4 -2
  11. package/package.json +7 -17
  12. package/src/autoresearch/tools/init-experiment.ts +38 -41
  13. package/src/autoresearch/tools/log-experiment.ts +32 -41
  14. package/src/autoresearch/tools/run-experiment.ts +3 -3
  15. package/src/autoresearch/tools/update-notes.ts +11 -11
  16. package/src/commit/agentic/tools/analyze-file.ts +4 -4
  17. package/src/commit/agentic/tools/git-file-diff.ts +4 -4
  18. package/src/commit/agentic/tools/git-hunk.ts +5 -5
  19. package/src/commit/agentic/tools/git-overview.ts +4 -4
  20. package/src/commit/agentic/tools/propose-changelog.ts +13 -13
  21. package/src/commit/agentic/tools/propose-commit.ts +6 -6
  22. package/src/commit/agentic/tools/recent-commits.ts +3 -3
  23. package/src/commit/agentic/tools/schemas.ts +28 -28
  24. package/src/commit/agentic/tools/split-commit.ts +22 -21
  25. package/src/commit/analysis/summary.ts +4 -4
  26. package/src/commit/changelog/generate.ts +7 -11
  27. package/src/commit/shared-llm.ts +22 -34
  28. package/src/config/config-file.ts +35 -13
  29. package/src/config/model-registry.ts +9 -190
  30. package/src/config/models-config-schema.ts +166 -0
  31. package/src/config/settings-schema.ts +18 -0
  32. package/src/edit/index.ts +2 -2
  33. package/src/edit/modes/apply-patch.ts +7 -6
  34. package/src/edit/modes/patch.ts +18 -25
  35. package/src/edit/modes/replace.ts +18 -20
  36. package/src/eval/js/shared/rewrite-imports.ts +131 -10
  37. package/src/eval/py/executor.ts +233 -623
  38. package/src/eval/py/kernel.ts +27 -2
  39. package/src/exa/factory.ts +5 -4
  40. package/src/exa/mcp-client.ts +1 -1
  41. package/src/exa/researcher.ts +9 -20
  42. package/src/exa/search.ts +26 -52
  43. package/src/exa/types.ts +1 -1
  44. package/src/exa/websets.ts +54 -53
  45. package/src/exec/bash-executor.ts +2 -1
  46. package/src/extensibility/custom-commands/loader.ts +5 -3
  47. package/src/extensibility/custom-commands/types.ts +4 -2
  48. package/src/extensibility/custom-tools/loader.ts +5 -3
  49. package/src/extensibility/custom-tools/types.ts +7 -6
  50. package/src/extensibility/custom-tools/wrapper.ts +1 -1
  51. package/src/extensibility/extensions/loader.ts +7 -3
  52. package/src/extensibility/extensions/types.ts +9 -5
  53. package/src/extensibility/extensions/wrapper.ts +1 -2
  54. package/src/extensibility/hooks/loader.ts +3 -1
  55. package/src/extensibility/hooks/tool-wrapper.ts +1 -1
  56. package/src/extensibility/hooks/types.ts +4 -2
  57. package/src/extensibility/plugins/legacy-pi-compat.ts +30 -0
  58. package/src/extensibility/shared-events.ts +1 -1
  59. package/src/extensibility/typebox.ts +391 -0
  60. package/src/goals/tools/goal-tool.ts +6 -12
  61. package/src/hashline/types.ts +4 -4
  62. package/src/hindsight/state.ts +2 -2
  63. package/src/index.ts +0 -2
  64. package/src/internal-urls/docs-index.generated.ts +7 -7
  65. package/src/lsp/types.ts +30 -38
  66. package/src/mcp/manager.ts +1 -1
  67. package/src/mcp/tool-bridge.ts +1 -1
  68. package/src/modes/components/session-observer-overlay.ts +12 -1
  69. package/src/modes/components/status-line/segments.ts +2 -1
  70. package/src/modes/controllers/command-controller.ts +27 -2
  71. package/src/modes/controllers/event-controller.ts +3 -4
  72. package/src/modes/interactive-mode.ts +1 -1
  73. package/src/modes/rpc/host-tools.ts +1 -1
  74. package/src/modes/rpc/rpc-client.ts +1 -1
  75. package/src/modes/rpc/rpc-types.ts +1 -1
  76. package/src/modes/theme/theme.ts +111 -117
  77. package/src/modes/types.ts +1 -1
  78. package/src/modes/utils/context-usage.ts +2 -2
  79. package/src/sdk.ts +31 -8
  80. package/src/session/agent-session.ts +74 -104
  81. package/src/session/messages.ts +16 -51
  82. package/src/session/session-manager.ts +22 -2
  83. package/src/session/streaming-output.ts +16 -6
  84. package/src/task/executor.ts +208 -86
  85. package/src/task/index.ts +15 -11
  86. package/src/task/render.ts +32 -5
  87. package/src/task/types.ts +54 -39
  88. package/src/tools/ask.ts +12 -12
  89. package/src/tools/ast-edit.ts +11 -15
  90. package/src/tools/ast-grep.ts +9 -10
  91. package/src/tools/bash.ts +9 -23
  92. package/src/tools/browser.ts +39 -53
  93. package/src/tools/calculator.ts +12 -11
  94. package/src/tools/checkpoint.ts +7 -7
  95. package/src/tools/debug.ts +40 -43
  96. package/src/tools/eval.ts +6 -8
  97. package/src/tools/find.ts +10 -13
  98. package/src/tools/gh.ts +71 -128
  99. package/src/tools/hindsight-recall.ts +4 -6
  100. package/src/tools/hindsight-reflect.ts +5 -5
  101. package/src/tools/hindsight-retain.ts +15 -17
  102. package/src/tools/image-gen.ts +32 -82
  103. package/src/tools/index.ts +4 -1
  104. package/src/tools/inspect-image.ts +8 -9
  105. package/src/tools/irc.ts +15 -27
  106. package/src/tools/job.ts +14 -21
  107. package/src/tools/read.ts +7 -8
  108. package/src/tools/recipe/index.ts +7 -9
  109. package/src/tools/render-mermaid.ts +12 -12
  110. package/src/tools/report-tool-issue.ts +4 -4
  111. package/src/tools/resolve.ts +11 -11
  112. package/src/tools/review.ts +14 -26
  113. package/src/tools/search-tool-bm25.ts +7 -9
  114. package/src/tools/search.ts +19 -22
  115. package/src/tools/ssh.ts +7 -7
  116. package/src/tools/todo-write.ts +26 -34
  117. package/src/tools/vim.ts +10 -26
  118. package/src/tools/write.ts +5 -5
  119. package/src/tools/yield.ts +100 -54
  120. package/src/web/search/index.ts +9 -24
  121. package/src/prompts/compaction/branch-summary-context.md +0 -5
  122. package/src/prompts/compaction/branch-summary-preamble.md +0 -2
  123. package/src/prompts/compaction/branch-summary.md +0 -30
  124. package/src/prompts/compaction/compaction-short-summary.md +0 -9
  125. package/src/prompts/compaction/compaction-summary-context.md +0 -5
  126. package/src/prompts/compaction/compaction-summary.md +0 -38
  127. package/src/prompts/compaction/compaction-turn-prefix.md +0 -17
  128. package/src/prompts/compaction/compaction-update-summary.md +0 -45
  129. package/src/prompts/system/auto-handoff-threshold-focus.md +0 -1
  130. package/src/prompts/system/file-operations.md +0 -10
  131. package/src/prompts/system/handoff-document.md +0 -49
  132. package/src/prompts/system/summarization-system.md +0 -3
  133. package/src/session/compaction/branch-summarization.ts +0 -324
  134. package/src/session/compaction/compaction.ts +0 -1420
  135. package/src/session/compaction/errors.ts +0 -31
  136. package/src/session/compaction/index.ts +0 -8
  137. package/src/session/compaction/pruning.ts +0 -91
  138. package/src/session/compaction/utils.ts +0 -184
@@ -22,9 +22,32 @@ type BabelImportDeclaration = {
22
22
  }>;
23
23
  };
24
24
 
25
- type BabelLexicalDecl =
26
- | { type: "VariableDeclaration"; kind: "const" | "let" | "var"; start: number; end: number }
27
- | { type: "ClassDeclaration"; start: number; end: number; id: { start: number; end: number; name: string } | null };
25
+ type BabelBindingPattern = {
26
+ type: string;
27
+ name?: string;
28
+ properties?: ReadonlyArray<unknown>;
29
+ elements?: ReadonlyArray<unknown | null>;
30
+ argument?: unknown;
31
+ left?: unknown;
32
+ value?: unknown;
33
+ };
34
+
35
+ type BabelVariableDeclaration = {
36
+ type: "VariableDeclaration";
37
+ kind: "const" | "let" | "var";
38
+ start: number;
39
+ end: number;
40
+ declarations?: ReadonlyArray<{ id: BabelBindingPattern }>;
41
+ };
42
+
43
+ type BabelClassDeclaration = {
44
+ type: "ClassDeclaration";
45
+ start: number;
46
+ end: number;
47
+ id: { start: number; end: number; name: string } | null;
48
+ };
49
+
50
+ type BabelLexicalDecl = BabelVariableDeclaration | BabelClassDeclaration;
28
51
 
29
52
  type BabelExpressionStatement = {
30
53
  type: "ExpressionStatement";
@@ -167,6 +190,53 @@ export function rewriteImports(code: string): string {
167
190
  return result;
168
191
  }
169
192
 
193
+ function collectBindingNames(pattern: unknown, names: string[]): void {
194
+ if (!pattern || typeof pattern !== "object") return;
195
+ const node = pattern as BabelBindingPattern & { parameter?: unknown };
196
+ switch (node.type) {
197
+ case "Identifier":
198
+ if (typeof node.name === "string") names.push(node.name);
199
+ return;
200
+ case "ObjectPattern":
201
+ for (const property of node.properties ?? []) collectBindingNames(property, names);
202
+ return;
203
+ case "ObjectProperty":
204
+ case "Property":
205
+ collectBindingNames(node.value, names);
206
+ return;
207
+ case "ArrayPattern":
208
+ for (const element of node.elements ?? []) collectBindingNames(element, names);
209
+ return;
210
+ case "AssignmentPattern":
211
+ collectBindingNames(node.left, names);
212
+ return;
213
+ case "RestElement":
214
+ collectBindingNames(node.argument, names);
215
+ return;
216
+ case "TSParameterProperty":
217
+ collectBindingNames(node.parameter, names);
218
+ return;
219
+ default:
220
+ return;
221
+ }
222
+ }
223
+
224
+ function getLexicalBindingNames(node: BabelLexicalDecl): string[] {
225
+ const names: string[] = [];
226
+ if (node.type === "VariableDeclaration") {
227
+ for (const declaration of node.declarations ?? []) collectBindingNames(declaration.id, names);
228
+ } else if (node.id) {
229
+ names.push(node.id.name);
230
+ }
231
+ return names;
232
+ }
233
+
234
+ function appendGlobalBindingPublish(source: string, names: readonly string[]): string {
235
+ if (names.length === 0) return source;
236
+ const assignments = names.map(name => `this[${JSON.stringify(name)}] = ${name};`).join("\n");
237
+ return `${source};\n${assignments}`;
238
+ }
239
+
170
240
  /**
171
241
  * Demote top-level `const`/`let`/`class` declarations to `var` so they persist on the
172
242
  * worker's globalThis across indirect `eval` calls. Indirect eval gives each call its own
@@ -177,10 +247,14 @@ export function rewriteImports(code: string): string {
177
247
  * let { a, b } = obj; -> var { a, b } = obj;
178
248
  * class Foo extends Bar {} -> var Foo = class extends Bar {};
179
249
  *
250
+ * When the source must run inside the async wrapper, demoted `var`s would normally become
251
+ * function-scoped. In that mode we publish each top-level binding back to the wrapper's
252
+ * lexical `this`, which is the worker global object.
253
+ *
180
254
  * Nested declarations (inside functions, blocks, classes) are left alone \u2014 they're
181
255
  * scoped to their enclosing function/block regardless of `var` vs `let`/`const`.
182
256
  */
183
- function demoteTopLevelLexicals(code: string): string {
257
+ function demoteTopLevelLexicals(code: string, options: { publishGlobals?: boolean } = {}): string {
184
258
  if (!/\b(?:const|let|class)\b/.test(code)) return code;
185
259
 
186
260
  const ast = parseProgram(code);
@@ -191,10 +265,10 @@ function demoteTopLevelLexicals(code: string): string {
191
265
  const targets: BabelLexicalDecl[] = [];
192
266
  for (const node of ast.program.body) {
193
267
  if (node.type === "VariableDeclaration") {
194
- const decl = node as unknown as BabelLexicalDecl & { kind: string };
195
- if (decl.kind === "const" || decl.kind === "let") targets.push(decl as BabelLexicalDecl);
268
+ const decl = node as unknown as BabelVariableDeclaration;
269
+ if (decl.kind === "const" || decl.kind === "let") targets.push(decl);
196
270
  } else if (node.type === "ClassDeclaration") {
197
- const decl = node as unknown as Extract<BabelLexicalDecl, { type: "ClassDeclaration" }>;
271
+ const decl = node as unknown as BabelClassDeclaration;
198
272
  if (decl.id) targets.push(decl);
199
273
  }
200
274
  }
@@ -204,6 +278,7 @@ function demoteTopLevelLexicals(code: string): string {
204
278
  let result = code;
205
279
  for (const node of targets) {
206
280
  const segment = result.slice(node.start, node.end);
281
+ const bindingNames = options.publishGlobals ? getLexicalBindingNames(node) : [];
207
282
  let replacement: string;
208
283
  if (node.type === "VariableDeclaration") {
209
284
  replacement = `var${segment.slice(node.kind.length)}`;
@@ -215,7 +290,8 @@ function demoteTopLevelLexicals(code: string): string {
215
290
  const hasTrailingSemi = segment.endsWith(";");
216
291
  replacement = `var ${id.name} = class${tail}${hasTrailingSemi ? "" : ";"}`;
217
292
  }
218
- result = result.slice(0, node.start) + replacement + result.slice(node.end);
293
+ result =
294
+ result.slice(0, node.start) + appendGlobalBindingPublish(replacement, bindingNames) + result.slice(node.end);
219
295
  }
220
296
  return result;
221
297
  }
@@ -238,6 +314,50 @@ function returnFinalExpression(code: string): { source: string; returned: boolea
238
314
  return { source: `${prefix}__omp_set_final_expr__((${trimmedStatement}));${suffix}`, returned: true };
239
315
  }
240
316
 
317
+ function isExecutionBoundary(type: string): boolean {
318
+ return (
319
+ type === "FunctionDeclaration" ||
320
+ type === "FunctionExpression" ||
321
+ type === "ArrowFunctionExpression" ||
322
+ type === "ObjectMethod" ||
323
+ type === "ClassMethod" ||
324
+ type === "ClassPrivateMethod" ||
325
+ type === "PrivateMethod"
326
+ );
327
+ }
328
+
329
+ function containsAsyncWrapperSyntax(value: unknown): boolean {
330
+ if (!value || typeof value !== "object") return false;
331
+ if (Array.isArray(value)) {
332
+ for (const item of value) {
333
+ if (containsAsyncWrapperSyntax(item)) return true;
334
+ }
335
+ return false;
336
+ }
337
+
338
+ const node = value as Record<string, unknown>;
339
+ const type = node.type;
340
+ if (type === "ReturnStatement" || type === "AwaitExpression") return true;
341
+ if (type === "ForOfStatement" && node.await === true) return true;
342
+ if (typeof type === "string" && isExecutionBoundary(type)) return false;
343
+
344
+ for (const key in node) {
345
+ if (key === "loc" || key === "extra" || key === "range") continue;
346
+ if (key === "leadingComments" || key === "trailingComments" || key === "innerComments") continue;
347
+ if (containsAsyncWrapperSyntax(node[key])) return true;
348
+ }
349
+ return false;
350
+ }
351
+
352
+ function requiresAsyncWrapper(code: string): boolean {
353
+ const ast = parseProgram(code);
354
+ if (!ast) return false;
355
+ for (const node of ast.program.body) {
356
+ if (containsAsyncWrapperSyntax(node)) return true;
357
+ }
358
+ return false;
359
+ }
360
+
241
361
  /**
242
362
  * Strip TypeScript syntax (type annotations, `interface`, `as`, `satisfies`, generics in
243
363
  * call expressions, etc.) before the import/lexical rewriters parse the code. We use Bun's
@@ -267,11 +387,12 @@ const LOOKS_LIKE_TS =
267
387
  export function wrapCode(code: string): { source: string; asyncWrapped: boolean; finalExpressionReturned: boolean } {
268
388
  const stripped = stripTypeScript(code);
269
389
  const finalExpression = returnFinalExpression(stripped);
390
+ const importsRewritten = rewriteImports(finalExpression.source);
391
+ const needsAsyncWrapper = requiresAsyncWrapper(importsRewritten);
270
392
  const rewritten = {
271
- source: demoteTopLevelLexicals(rewriteImports(finalExpression.source)),
393
+ source: demoteTopLevelLexicals(importsRewritten, { publishGlobals: needsAsyncWrapper }),
272
394
  returned: finalExpression.returned,
273
395
  };
274
- const needsAsyncWrapper = /\bawait\b|\breturn\b/.test(rewritten.source);
275
396
  if (!needsAsyncWrapper) {
276
397
  return { source: rewritten.source, asyncWrapped: false, finalExpressionReturned: rewritten.returned };
277
398
  }