@oh-my-pi/pi-coding-agent 16.4.6 → 16.5.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 (141) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/dist/cli.js +3312 -3254
  3. package/dist/types/cli/args.d.ts +5 -0
  4. package/dist/types/cli/gallery-fixtures/shell.d.ts +1 -1
  5. package/dist/types/commands/launch.d.ts +15 -0
  6. package/dist/types/config/model-resolver.d.ts +4 -3
  7. package/dist/types/config/model-roles.d.ts +8 -0
  8. package/dist/types/config/settings-schema.d.ts +46 -14
  9. package/dist/types/extensibility/extensions/types.d.ts +1 -1
  10. package/dist/types/launch/broker.d.ts +2 -0
  11. package/dist/types/launch/client.d.ts +22 -0
  12. package/dist/types/launch/paths.d.ts +4 -0
  13. package/dist/types/launch/presence.d.ts +8 -0
  14. package/dist/types/launch/protocol.d.ts +170 -0
  15. package/dist/types/launch/terminal-output.d.ts +7 -0
  16. package/dist/types/modes/components/agent-hub.d.ts +1 -1
  17. package/dist/types/modes/components/index.d.ts +1 -0
  18. package/dist/types/modes/components/model-browser.d.ts +28 -3
  19. package/dist/types/modes/components/model-hub.d.ts +0 -10
  20. package/dist/types/modes/components/model-picker.d.ts +44 -0
  21. package/dist/types/modes/components/plan-review-overlay.d.ts +2 -0
  22. package/dist/types/modes/components/status-line/types.d.ts +3 -0
  23. package/dist/types/modes/components/welcome.d.ts +4 -0
  24. package/dist/types/modes/print-mode.d.ts +14 -8
  25. package/dist/types/modes/print-mode.test.d.ts +1 -0
  26. package/dist/types/modes/theme/theme.d.ts +2 -1
  27. package/dist/types/sdk.d.ts +5 -1
  28. package/dist/types/session/agent-session.d.ts +42 -0
  29. package/dist/types/session/session-context.d.ts +9 -0
  30. package/dist/types/session/session-entries.d.ts +6 -0
  31. package/dist/types/thinking.d.ts +2 -2
  32. package/dist/types/tiny/models.d.ts +1 -1
  33. package/dist/types/tools/browser/launch.d.ts +1 -0
  34. package/dist/types/tools/browser/run-cancellation.d.ts +28 -2
  35. package/dist/types/tools/browser/tab-protocol.d.ts +6 -0
  36. package/dist/types/tools/browser/tab-worker.d.ts +6 -0
  37. package/dist/types/tools/builtin-names.d.ts +1 -1
  38. package/dist/types/tools/index.d.ts +1 -0
  39. package/dist/types/tools/launch.d.ts +121 -0
  40. package/dist/types/tools/render-utils.d.ts +2 -0
  41. package/dist/types/tools/terminal-output.d.ts +5 -0
  42. package/dist/types/vibe/runtime.d.ts +2 -2
  43. package/dist/types/web/search/types.d.ts +0 -8
  44. package/package.json +20 -20
  45. package/src/cli/args.ts +11 -0
  46. package/src/cli/flag-tables.ts +9 -0
  47. package/src/cli/gallery-fixtures/shell.ts +82 -1
  48. package/src/cli.ts +10 -0
  49. package/src/commands/launch.ts +17 -0
  50. package/src/config/model-resolver.ts +110 -31
  51. package/src/config/model-roles.ts +14 -0
  52. package/src/config/settings-schema.ts +71 -7
  53. package/src/edit/renderer.ts +13 -10
  54. package/src/eval/__tests__/agent-bridge.test.ts +2 -2
  55. package/src/eval/__tests__/completion-bridge.test.ts +1 -1
  56. package/src/eval/completion-bridge.ts +4 -4
  57. package/src/eval/js/shared/rewrite-imports.ts +31 -13
  58. package/src/export/ttsr.ts +0 -3
  59. package/src/extensibility/extensions/model-api.ts +1 -1
  60. package/src/extensibility/extensions/types.ts +1 -1
  61. package/src/internal-urls/docs-index.ts +4 -4
  62. package/src/launch/broker.ts +1017 -0
  63. package/src/launch/client.ts +344 -0
  64. package/src/launch/paths.ts +17 -0
  65. package/src/launch/presence.ts +82 -0
  66. package/src/launch/protocol.ts +386 -0
  67. package/src/launch/terminal-output.ts +46 -0
  68. package/src/main.ts +50 -1
  69. package/src/modes/acp/acp-agent.ts +8 -1
  70. package/src/modes/components/agent-hub.ts +101 -31
  71. package/src/modes/components/compaction-summary-message.ts +8 -2
  72. package/src/modes/components/index.ts +1 -0
  73. package/src/modes/components/model-browser.ts +152 -49
  74. package/src/modes/components/model-hub.ts +55 -142
  75. package/src/modes/components/model-picker.ts +233 -0
  76. package/src/modes/components/plan-review-overlay.ts +7 -0
  77. package/src/modes/components/snapcompact-shape-preview-doc.md +7 -11
  78. package/src/modes/components/status-line/component.test.ts +41 -2
  79. package/src/modes/components/status-line/component.ts +4 -0
  80. package/src/modes/components/status-line/segments.ts +6 -0
  81. package/src/modes/components/status-line/types.ts +3 -0
  82. package/src/modes/components/tips.txt +2 -1
  83. package/src/modes/components/welcome.ts +13 -14
  84. package/src/modes/controllers/command-controller.ts +9 -1
  85. package/src/modes/controllers/event-controller.ts +31 -32
  86. package/src/modes/controllers/selector-controller.ts +96 -22
  87. package/src/modes/controllers/tan-command-controller.ts +40 -1
  88. package/src/modes/interactive-mode.ts +20 -3
  89. package/src/modes/print-mode.test.ts +71 -0
  90. package/src/modes/print-mode.ts +51 -2
  91. package/src/modes/theme/theme.ts +9 -0
  92. package/src/modes/utils/ui-helpers.ts +25 -4
  93. package/src/prompts/agents/designer.md +1 -1
  94. package/src/prompts/agents/librarian.md +1 -1
  95. package/src/prompts/agents/reviewer.md +1 -1
  96. package/src/prompts/agents/scout.md +1 -1
  97. package/src/prompts/system/plan-yolo-handoff.md +5 -0
  98. package/src/prompts/system/prewalk-checklist.md +7 -0
  99. package/src/prompts/system/prewalk-continue.md +1 -0
  100. package/src/prompts/system/prewalk-plan.md +13 -0
  101. package/src/prompts/system/system-prompt.md +9 -7
  102. package/src/prompts/system/tan-context-switch.md +17 -0
  103. package/src/prompts/tools/bash.md +6 -4
  104. package/src/prompts/tools/browser.md +4 -4
  105. package/src/prompts/tools/launch.md +25 -0
  106. package/src/sdk.ts +8 -2
  107. package/src/session/agent-session.ts +550 -87
  108. package/src/session/session-context.test.ts +10 -5
  109. package/src/session/session-context.ts +25 -8
  110. package/src/session/session-entries.ts +6 -0
  111. package/src/slash-commands/builtin-registry.ts +25 -0
  112. package/src/task/agents.ts +2 -2
  113. package/src/thinking.ts +10 -3
  114. package/src/tiny/models.ts +7 -7
  115. package/src/tools/bash-interactive.ts +5 -8
  116. package/src/tools/bash.ts +38 -24
  117. package/src/tools/browser/cmux/cmux-tab.ts +17 -2
  118. package/src/tools/browser/launch.ts +8 -4
  119. package/src/tools/browser/run-cancellation.ts +66 -6
  120. package/src/tools/browser/tab-protocol.ts +6 -0
  121. package/src/tools/browser/tab-supervisor.ts +17 -1
  122. package/src/tools/browser/tab-worker.ts +140 -21
  123. package/src/tools/builtin-names.ts +1 -0
  124. package/src/tools/eval-render.ts +16 -14
  125. package/src/tools/index.ts +5 -0
  126. package/src/tools/inspect-image.ts +2 -2
  127. package/src/tools/launch.ts +643 -0
  128. package/src/tools/render-utils.ts +3 -0
  129. package/src/tools/renderers.ts +2 -0
  130. package/src/tools/terminal-output.ts +141 -0
  131. package/src/tts/speech-enhancer.ts +2 -2
  132. package/src/utils/image-vision-fallback.ts +3 -3
  133. package/src/vibe/runtime.ts +2 -2
  134. package/src/web/search/provider.ts +0 -10
  135. package/src/web/search/providers/perplexity.ts +18 -2
  136. package/src/web/search/providers/public.ts +2 -4
  137. package/src/web/search/types.ts +0 -10
  138. package/dist/types/web/search/providers/bing.d.ts +0 -14
  139. package/dist/types/web/search/providers/yahoo.d.ts +0 -14
  140. package/src/web/search/providers/bing.ts +0 -197
  141. package/src/web/search/providers/yahoo.ts +0 -179
@@ -28,7 +28,7 @@ const taskAgent = {
28
28
  systemPrompt: "Run the task.",
29
29
  source: "bundled",
30
30
  spawns: "*",
31
- model: ["pi/task"],
31
+ model: ["@task"],
32
32
  } satisfies AgentDefinition;
33
33
 
34
34
  const reviewerAgent = {
@@ -36,7 +36,7 @@ const reviewerAgent = {
36
36
  description: "Reviewer agent",
37
37
  systemPrompt: "Review the task.",
38
38
  source: "bundled",
39
- model: ["pi/smol"],
39
+ model: ["@smol"],
40
40
  } satisfies AgentDefinition;
41
41
 
42
42
  interface SessionOptions {
@@ -193,7 +193,7 @@ describe("runEvalCompletion", () => {
193
193
  expect(resolved).toEqual(["p/smol", "p/default", "p/slow"]);
194
194
  });
195
195
 
196
- it("prefers the session active model for the default tier, falling back to pi/default", async () => {
196
+ it("prefers the session active model for the default tier, falling back to @default", async () => {
197
197
  const spy = vi.spyOn(ai, "completeSimple").mockResolvedValue(assistant({ text: "ok" }));
198
198
  const session = makeSession({ available: [SMOL, DEFAULT, SLOW], activeModel: "p/slow" });
199
199
 
@@ -37,9 +37,9 @@ const STRUCTURED_TOOL_NAME = "respond";
37
37
  type CompletionTier = "smol" | "default" | "slow";
38
38
 
39
39
  const TIER_TO_PATTERN: Record<CompletionTier, string> = {
40
- smol: "pi/smol",
41
- default: "pi/default",
42
- slow: "pi/slow",
40
+ smol: "@smol",
41
+ default: "@default",
42
+ slow: "@slow",
43
43
  };
44
44
 
45
45
  const completionArgsSchema = type({
@@ -62,7 +62,7 @@ export interface EvalCompletionResult {
62
62
 
63
63
  /**
64
64
  * Resolve a tier to a concrete {@link Model}. `default` prefers the session's
65
- * active model and falls back to the `pi/default` role; `smol`/`slow` resolve
65
+ * active model and falls back to the `@default` role; `smol`/`slow` resolve
66
66
  * their respective role patterns. Returns `undefined` when nothing matches.
67
67
  */
68
68
  function resolveTierModel(tier: CompletionTier, session: ToolSession): Model<Api> | undefined {
@@ -48,6 +48,15 @@ type BabelClassDeclaration = {
48
48
  };
49
49
 
50
50
  type BabelLexicalDecl = BabelVariableDeclaration | BabelClassDeclaration;
51
+ type BabelFunctionDeclaration = {
52
+ type: "FunctionDeclaration";
53
+ start: number;
54
+ end: number;
55
+ id: { start: number; end: number; name: string } | null;
56
+ };
57
+
58
+ /** Top-level declarations whose bindings must survive the cell (demoted and/or published). */
59
+ type BabelPublishableDecl = BabelLexicalDecl | BabelFunctionDeclaration;
51
60
 
52
61
  type BabelExpressionStatement = {
53
62
  type: "ExpressionStatement";
@@ -322,7 +331,7 @@ function collectBindingNames(pattern: unknown, names: string[]): void {
322
331
  }
323
332
  }
324
333
 
325
- function getLexicalBindingNames(node: BabelLexicalDecl): string[] {
334
+ function getLexicalBindingNames(node: BabelPublishableDecl): string[] {
326
335
  const names: string[] = [];
327
336
  if (node.type === "VariableDeclaration") {
328
337
  for (const declaration of node.declarations ?? []) collectBindingNames(declaration.id, names);
@@ -348,40 +357,49 @@ function appendGlobalBindingPublish(source: string, names: readonly string[]): s
348
357
  * let { a, b } = obj; -> var { a, b } = obj;
349
358
  * class Foo extends Bar {} -> var Foo = class extends Bar {};
350
359
  *
351
- * When the source must run inside the async wrapper, demoted `var`s would normally become
352
- * function-scoped. In that mode we publish each top-level binding back to the wrapper's
353
- * lexical `this`, which is the worker global object.
360
+ * When the source must run inside the async wrapper (top-level `await`), demoted `var`s
361
+ * and the user's own top-level `var` and `function` declarations would be scoped to the
362
+ * wrapper function and die with the cell. In that mode we publish every top-level binding
363
+ * back to the wrapper's lexical `this`, which is the worker global object.
354
364
  *
355
- * Nested declarations (inside functions, blocks, classes) are left alone \u2014 they're
365
+ * Nested declarations (inside functions, blocks, classes) are left alone they're
356
366
  * scoped to their enclosing function/block regardless of `var` vs `let`/`const`.
357
367
  */
358
368
  async function demoteTopLevelLexicals(code: string, options: { publishGlobals?: boolean } = {}): Promise<string> {
359
- if (!/\b(?:const|let|class)\b/.test(code)) return code;
369
+ const publishGlobals = options.publishGlobals === true;
370
+ const fastPath = publishGlobals ? /\b(?:const|let|class|var|function)\b/ : /\b(?:const|let|class)\b/;
371
+ if (!fastPath.test(code)) return code;
360
372
 
361
373
  const ast = await parseProgram(code);
362
374
  if (!ast) {
363
375
  return code;
364
376
  }
365
377
 
366
- const targets: BabelLexicalDecl[] = [];
378
+ const targets: Array<{ node: BabelPublishableDecl; demote: boolean }> = [];
367
379
  for (const node of ast.program.body) {
368
380
  if (node.type === "VariableDeclaration") {
369
381
  const decl = node as unknown as BabelVariableDeclaration;
370
- if (decl.kind === "const" || decl.kind === "let") targets.push(decl);
382
+ if (decl.kind === "const" || decl.kind === "let") targets.push({ node: decl, demote: true });
383
+ else if (publishGlobals) targets.push({ node: decl, demote: false });
371
384
  } else if (node.type === "ClassDeclaration") {
372
385
  const decl = node as unknown as BabelClassDeclaration;
373
- if (decl.id) targets.push(decl);
386
+ if (decl.id) targets.push({ node: decl, demote: true });
387
+ } else if (publishGlobals && node.type === "FunctionDeclaration") {
388
+ const decl = node as unknown as BabelFunctionDeclaration;
389
+ if (decl.id) targets.push({ node: decl, demote: false });
374
390
  }
375
391
  }
376
392
  if (targets.length === 0) return code;
377
393
 
378
- targets.sort((a, b) => b.start - a.start);
394
+ targets.sort((a, b) => b.node.start - a.node.start);
379
395
  let result = code;
380
- for (const node of targets) {
396
+ for (const { node, demote } of targets) {
381
397
  const segment = result.slice(node.start, node.end);
382
- const bindingNames = options.publishGlobals ? getLexicalBindingNames(node) : [];
398
+ const bindingNames = publishGlobals ? getLexicalBindingNames(node) : [];
383
399
  let replacement: string;
384
- if (node.type === "VariableDeclaration") {
400
+ if (!demote) {
401
+ replacement = segment;
402
+ } else if (node.type === "VariableDeclaration") {
385
403
  replacement = `var${segment.slice(node.kind.length)}`;
386
404
  } else {
387
405
  const id = node.id;
@@ -457,9 +457,6 @@ export class TtsrManager {
457
457
  strictness: AstMatchStrictness.Smart,
458
458
  limit: 1,
459
459
  });
460
- if (result.parseErrors && result.parseErrors.length > 0) {
461
- logger.debug("TTSR ast match reported parse errors", { parseErrors: result.parseErrors });
462
- }
463
460
  return result.totalMatches > 0;
464
461
  } catch (error) {
465
462
  logger.warn("TTSR ast match failed, treating as no match", {
@@ -25,7 +25,7 @@ export function createExtensionModelQuery(
25
25
  return {
26
26
  list: () => modelRegistry.getAvailable(),
27
27
  current: () => getModel(),
28
- // resolveModelRoleValue expands a role alias (`pi/slow`) to its full configured
28
+ // resolveModelRoleValue expands a role alias (`@slow`) to its full configured
29
29
  // priority list and tries each pattern — the same path core selection uses — so a
30
30
  // fallback model lower in the list still resolves. Plain model strings pass through
31
31
  // as a single pattern.
@@ -391,7 +391,7 @@ export interface ExtensionModelQuery {
391
391
  /** The current session model, if one is set. */
392
392
  current(): Model | undefined;
393
393
  /**
394
- * Resolve a model string (`provider/id`, bare id) or role alias (`pi/slow`, a
394
+ * Resolve a model string (`provider/id`, bare id) or role alias (`@slow`, a
395
395
  * configured role) to a Model, using the same settings-backed aliases and match
396
396
  * preferences as core selection. Thinking/routing suffixes are accepted and resolved
397
397
  * to the base model (pass effort separately). Returns undefined when nothing matches.
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Harness documentation index for the `omp://` protocol.
3
3
  *
4
- * Compiled binaries and the prepacked npm bundle inline a compressed index from
5
- * `docs-index.generated.txt` (populated by `gen:docs` at build time). The format is two lines:
4
+ * Compiled binaries and the prepacked npm bundle inline a compressed index of the
5
+ * docs (injected via `process.env.PI_DOCS_EMBED` at build time). The format is two lines:
6
6
  * 1. a plain JSON array of the sorted doc file names, and
7
7
  * 2. a base64 gzip blob of the index-aligned doc bodies (`string[]`).
8
8
  * Listing/completion (`getDocFilenames`) parses only the small first line and
@@ -83,8 +83,8 @@ function getIndex(): DocsIndex {
83
83
  const decoded = decodeDocsIndex(docsEmbed);
84
84
  if (decoded === null) {
85
85
  throw new Error(
86
- "Malformed embedded docs index (docs-index.generated.txt): non-empty payload without a newline separator. " +
87
- "Rebuild with `bun run gen:docs`.",
86
+ "Malformed embedded docs index: non-empty payload without a newline separator. " +
87
+ "Rebuild the binary or bundle.",
88
88
  );
89
89
  }
90
90
  index = decoded;