@oh-my-pi/pi-coding-agent 16.0.2 → 16.0.3

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 (88) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +0 -1
  3. package/dist/cli.js +217 -276
  4. package/dist/types/advisor/advise-tool.d.ts +30 -1
  5. package/dist/types/commands/install.d.ts +1 -1
  6. package/dist/types/config/model-resolver.d.ts +8 -0
  7. package/dist/types/config/settings-schema.d.ts +0 -10
  8. package/dist/types/eval/js/shared/runtime.d.ts +1 -0
  9. package/dist/types/eval/js/worker-core.d.ts +1 -0
  10. package/dist/types/extensibility/extensions/loader.d.ts +2 -2
  11. package/dist/types/goals/runtime.d.ts +0 -1
  12. package/dist/types/mcp/tool-bridge.d.ts +3 -0
  13. package/dist/types/modes/components/custom-editor.d.ts +14 -4
  14. package/dist/types/modes/controllers/command-controller.d.ts +1 -1
  15. package/dist/types/modes/interactive-mode.d.ts +1 -1
  16. package/dist/types/modes/setup-wizard/wizard-overlay.d.ts +3 -2
  17. package/dist/types/modes/theme/mermaid-cache.d.ts +18 -1
  18. package/dist/types/modes/types.d.ts +1 -1
  19. package/dist/types/registry/agent-lifecycle.d.ts +16 -1
  20. package/dist/types/sdk.d.ts +8 -0
  21. package/dist/types/session/agent-session.d.ts +20 -8
  22. package/dist/types/session/session-dump-format.d.ts +8 -2
  23. package/dist/types/session/session-entries.d.ts +4 -0
  24. package/dist/types/session/session-history-format.d.ts +2 -0
  25. package/dist/types/session/session-manager.d.ts +22 -0
  26. package/dist/types/stt/downloader.d.ts +5 -5
  27. package/dist/types/task/executor.d.ts +6 -0
  28. package/dist/types/task/persisted-revive.d.ts +36 -0
  29. package/dist/types/tiny/models.d.ts +8 -0
  30. package/dist/types/tools/builtin-names.d.ts +1 -1
  31. package/dist/types/tools/index.d.ts +0 -1
  32. package/package.json +12 -12
  33. package/src/advisor/__tests__/advisor.test.ts +150 -50
  34. package/src/advisor/advise-tool.ts +48 -6
  35. package/src/advisor/runtime.ts +10 -3
  36. package/src/auto-thinking/classifier.ts +12 -3
  37. package/src/cli.ts +2 -2
  38. package/src/commands/install.ts +3 -3
  39. package/src/config/model-resolver.ts +28 -11
  40. package/src/config/settings-schema.ts +0 -11
  41. package/src/eval/agent-bridge.ts +2 -0
  42. package/src/eval/js/context-manager.ts +2 -1
  43. package/src/eval/js/shared/runtime.ts +189 -15
  44. package/src/eval/js/worker-core.ts +19 -0
  45. package/src/export/html/index.ts +1 -1
  46. package/src/export/html/tool-views.generated.js +34 -35
  47. package/src/extensibility/extensions/loader.ts +21 -9
  48. package/src/goals/runtime.ts +1 -23
  49. package/src/internal-urls/docs-index.generated.ts +4 -6
  50. package/src/main.ts +20 -0
  51. package/src/mcp/render.ts +11 -1
  52. package/src/mcp/tool-bridge.ts +3 -0
  53. package/src/modes/components/custom-editor.test.ts +63 -18
  54. package/src/modes/components/custom-editor.ts +63 -15
  55. package/src/modes/controllers/command-controller.ts +2 -2
  56. package/src/modes/controllers/input-controller.ts +15 -9
  57. package/src/modes/controllers/selector-controller.ts +13 -8
  58. package/src/modes/controllers/tan-command-controller.ts +1 -0
  59. package/src/modes/interactive-mode.ts +4 -2
  60. package/src/modes/setup-wizard/wizard-overlay.ts +26 -4
  61. package/src/modes/theme/mermaid-cache.ts +74 -11
  62. package/src/modes/theme/theme.ts +14 -1
  63. package/src/modes/types.ts +1 -1
  64. package/src/prompts/system/system-prompt.md +2 -1
  65. package/src/registry/agent-lifecycle.ts +60 -8
  66. package/src/sdk.ts +20 -26
  67. package/src/session/agent-session.ts +246 -78
  68. package/src/session/artifacts.ts +19 -1
  69. package/src/session/session-dump-format.ts +167 -23
  70. package/src/session/session-entries.ts +4 -0
  71. package/src/session/session-history-format.ts +37 -3
  72. package/src/session/session-manager.ts +94 -4
  73. package/src/slash-commands/builtin-registry.ts +4 -7
  74. package/src/stt/asr-client.ts +6 -0
  75. package/src/stt/downloader.ts +13 -6
  76. package/src/stt/stt-controller.ts +52 -11
  77. package/src/task/executor.ts +18 -2
  78. package/src/task/index.ts +2 -2
  79. package/src/task/persisted-revive.ts +128 -0
  80. package/src/tiny/models.ts +10 -0
  81. package/src/tiny/worker.ts +4 -3
  82. package/src/tools/builtin-names.ts +0 -1
  83. package/src/tools/index.ts +0 -4
  84. package/src/tools/output-meta.ts +17 -3
  85. package/src/utils/title-generator.ts +4 -4
  86. package/dist/types/tools/render-mermaid.d.ts +0 -38
  87. package/src/prompts/tools/render-mermaid.md +0 -9
  88. package/src/tools/render-mermaid.ts +0 -69
@@ -10,6 +10,7 @@ import type { KeyId } from "@oh-my-pi/pi-tui";
10
10
  import { hasFsCode, isEacces, isEnoent, logger } from "@oh-my-pi/pi-utils";
11
11
  import { z } from "zod/v4";
12
12
  import { type ExtensionModule, extensionModuleCapability } from "../../capability/extension-module";
13
+ import { type Hook, hookCapability } from "../../capability/hook";
13
14
  import { loadCapability } from "../../discovery";
14
15
  import { getExtensionNameFromPath } from "../../discovery/helpers";
15
16
  import type { ExecOptions } from "../../exec/exec";
@@ -479,8 +480,8 @@ async function discoverExtensionsInDir(dir: string): Promise<string[]> {
479
480
  /**
480
481
  * Discover absolute paths of extensions to load, without importing or
481
482
  * binding factories. Hot path on session startup — the scan walks native
482
- * `.omp`/`.pi` extension capabilities, the installed-plugin tree, and any
483
- * configured paths.
483
+ * `.omp`/`.pi` extension capabilities, JS/TS hook factories, the
484
+ * installed-plugin tree, and any configured paths.
484
485
  *
485
486
  * Subagents reuse the parent's collected paths via the SDK's
486
487
  * `preloadedExtensionPaths` option, then call {@link loadExtensions} themselves
@@ -492,11 +493,12 @@ async function discoverExtensionsInDir(dir: string): Promise<string[]> {
492
493
  export async function discoverExtensionPaths(
493
494
  configuredPaths: string[],
494
495
  cwd: string,
495
- disabledExtensionIds: string[] = [],
496
+ disabledExtensionIds?: string[],
496
497
  ): Promise<string[]> {
497
498
  const allPaths: string[] = [];
498
499
  const seen = new Set<string>();
499
- const disabled = new Set(disabledExtensionIds);
500
+ const disabled = new Set(disabledExtensionIds ?? []);
501
+ const loadOptions = disabledExtensionIds ? { cwd, disabledExtensions: disabledExtensionIds } : { cwd };
500
502
 
501
503
  const isDisabledName = (name: string): boolean => disabled.has(`extension-module:${name}`);
502
504
 
@@ -516,17 +518,27 @@ export async function discoverExtensionPaths(
516
518
  };
517
519
 
518
520
  // 1. Discover extension modules via capability API (native .omp/.pi only)
519
- const discovered = await loadCapability<ExtensionModule>(extensionModuleCapability.id, { cwd });
521
+ const discovered = await loadCapability<ExtensionModule>(extensionModuleCapability.id, loadOptions);
520
522
  for (const ext of discovered.items) {
521
523
  if (ext._source.provider !== "native") continue;
522
- if (isDisabledName(ext.name)) continue;
523
524
  addPath(ext.path);
524
525
  }
525
526
 
526
- // 2. Discover extension entry points from installed plugins
527
+ // 2. Discover JS/TS hook factories from hookCapability and bind them through
528
+ // the extension runner, which owns the current runtime event bus. Hook
529
+ // capability loading already applies hook-specific disabled ids; do not also
530
+ // filter them through extension-module names.
531
+ const hooks = await loadCapability<Hook>(hookCapability.id, loadOptions);
532
+ for (const hookPath of hooks.items
533
+ .map(hook => hook.path)
534
+ .filter(hookPath => isExtensionFile(path.basename(hookPath)))) {
535
+ addPath(hookPath);
536
+ }
537
+
538
+ // 3. Discover extension entry points from installed plugins
527
539
  addPaths(await getAllPluginExtensionPaths(cwd));
528
540
 
529
- // 3. Explicitly configured paths
541
+ // 4. Explicitly configured paths
530
542
  for (const configuredPath of configuredPaths) {
531
543
  const resolved = resolvePath(configuredPath, cwd);
532
544
 
@@ -566,7 +578,7 @@ export async function discoverAndLoadExtensions(
566
578
  configuredPaths: string[],
567
579
  cwd: string,
568
580
  eventBus?: EventBus,
569
- disabledExtensionIds: string[] = [],
581
+ disabledExtensionIds?: string[],
570
582
  ): Promise<LoadExtensionsResult> {
571
583
  const paths = await discoverExtensionPaths(configuredPaths, cwd, disabledExtensionIds);
572
584
  return loadExtensions(paths, cwd, eventBus);
@@ -1,4 +1,4 @@
1
- import { prompt, Snowflake } from "@oh-my-pi/pi-utils";
1
+ import { escapeXmlText, prompt, Snowflake } from "@oh-my-pi/pi-utils";
2
2
  import goalBudgetLimitPrompt from "../prompts/goals/goal-budget-limit.md" with { type: "text" };
3
3
  import goalContinuationPrompt from "../prompts/goals/goal-continuation.md" with { type: "text" };
4
4
  import goalModeActivePrompt from "../prompts/goals/goal-mode-active.md" with { type: "text" };
@@ -58,28 +58,6 @@ export function remainingTokens(goal: Goal | null | undefined): number | null {
58
58
  return Math.max(0, goal.tokenBudget - goal.tokensUsed);
59
59
  }
60
60
 
61
- export function escapeXmlText(input: string): string {
62
- let firstEscapable = -1;
63
- for (let index = 0; index < input.length; index++) {
64
- const char = input.charCodeAt(index);
65
- if (char === 38 || char === 60 || char === 62) {
66
- firstEscapable = index;
67
- break;
68
- }
69
- }
70
- if (firstEscapable === -1) return input;
71
-
72
- let output = input.slice(0, firstEscapable);
73
- for (let index = firstEscapable; index < input.length; index++) {
74
- const char = input[index];
75
- if (char === "&") output += "&amp;";
76
- else if (char === "<") output += "&lt;";
77
- else if (char === ">") output += "&gt;";
78
- else output += char;
79
- }
80
- return output;
81
- }
82
-
83
61
  export function renderTrustedObjective(objective: string): string {
84
62
  return `<objective>\n${escapeXmlText(objective)}\n</objective>`;
85
63
  }