@oh-my-pi/pi-coding-agent 17.1.5 → 17.1.6

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 (207) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/{CHANGELOG-qs3vd6xf.md → CHANGELOG-x9zt79k8.md} +31 -0
  3. package/dist/cli.js +2989 -2978
  4. package/dist/types/capability/index.d.ts +1 -1
  5. package/dist/types/capability/types.d.ts +23 -1
  6. package/dist/types/config/settings-schema.d.ts +23 -1
  7. package/dist/types/internal-urls/mcp-protocol.d.ts +3 -2
  8. package/dist/types/internal-urls/parse.d.ts +12 -0
  9. package/dist/types/internal-urls/router.d.ts +6 -0
  10. package/dist/types/internal-urls/types.d.ts +6 -0
  11. package/dist/types/lsp/config.d.ts +1 -0
  12. package/dist/types/lsp/types.d.ts +2 -0
  13. package/dist/types/mcp/manager.d.ts +5 -0
  14. package/dist/types/mcp/tool-bridge.d.ts +13 -0
  15. package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -1
  16. package/dist/types/modes/rpc/rpc-mode.d.ts +2 -0
  17. package/dist/types/sdk.d.ts +3 -1
  18. package/dist/types/session/agent-session-types.d.ts +3 -1
  19. package/dist/types/session/agent-session.d.ts +2 -0
  20. package/dist/types/session/model-controls.d.ts +3 -0
  21. package/dist/types/session/session-advisors.d.ts +7 -1
  22. package/dist/types/session/tool-choice-queue.d.ts +6 -4
  23. package/dist/types/session/turn-recovery.d.ts +4 -2
  24. package/dist/types/task/index.d.ts +1 -1
  25. package/dist/types/task/types.d.ts +3 -11
  26. package/dist/types/thinking.d.ts +21 -2
  27. package/dist/types/utils/title-generator.d.ts +17 -16
  28. package/package.json +12 -12
  29. package/src/capability/index.ts +43 -12
  30. package/src/capability/mcp.ts +21 -0
  31. package/src/capability/types.ts +20 -1
  32. package/src/cli/read-cli.ts +44 -2
  33. package/src/config/settings-schema.ts +27 -1
  34. package/src/eval/py/runner.py +16 -2
  35. package/src/extensibility/extensions/runner.ts +91 -5
  36. package/src/extensibility/extensions/types.ts +0 -1
  37. package/src/extensibility/hooks/types.ts +0 -1
  38. package/src/internal-urls/mcp-protocol.ts +17 -3
  39. package/src/internal-urls/parse.ts +31 -0
  40. package/src/internal-urls/router.ts +24 -4
  41. package/src/internal-urls/types.ts +6 -0
  42. package/src/live/transport.ts +2 -2
  43. package/src/lsp/client.ts +2 -2
  44. package/src/lsp/config.ts +4 -0
  45. package/src/lsp/types.ts +2 -0
  46. package/src/mcp/config.ts +26 -14
  47. package/src/mcp/manager.ts +26 -9
  48. package/src/mcp/tool-bridge.ts +52 -1
  49. package/src/memories/index.ts +25 -6
  50. package/src/modes/components/status-line/segments.ts +3 -1
  51. package/src/modes/controllers/command-controller.ts +10 -10
  52. package/src/modes/controllers/extension-ui-controller.ts +3 -3
  53. package/src/modes/rpc/rpc-mode.ts +60 -47
  54. package/src/prompts/steering/user-interjection.md +2 -5
  55. package/src/prompts/tools/task.md +4 -2
  56. package/src/sdk.ts +17 -8
  57. package/src/session/agent-session-types.ts +3 -0
  58. package/src/session/agent-session.ts +21 -4
  59. package/src/session/model-controls.ts +43 -7
  60. package/src/session/session-advisors.ts +30 -14
  61. package/src/session/session-tools.ts +4 -2
  62. package/src/session/tool-choice-queue.ts +19 -4
  63. package/src/session/turn-recovery.ts +21 -2
  64. package/src/task/executor.ts +11 -3
  65. package/src/task/index.ts +43 -32
  66. package/src/task/types.ts +12 -17
  67. package/src/thinking.ts +68 -5
  68. package/src/tools/read.ts +2 -2
  69. package/src/utils/title-generator.ts +88 -34
  70. package/dist/types/advisor/__tests__/advisor.test.d.ts +0 -1
  71. package/dist/types/advisor/__tests__/config.test.d.ts +0 -1
  72. package/dist/types/advisor/__tests__/emission-guard.test.d.ts +0 -1
  73. package/dist/types/cli/__tests__/auth-gateway-catalog.test.d.ts +0 -1
  74. package/dist/types/cli/update-cli.test.d.ts +0 -1
  75. package/dist/types/config/__tests__/model-registry.test.d.ts +0 -1
  76. package/dist/types/eval/__tests__/agent-bridge.test.d.ts +0 -1
  77. package/dist/types/eval/__tests__/bridge-timeout.test.d.ts +0 -1
  78. package/dist/types/eval/__tests__/budget-bridge.test.d.ts +0 -1
  79. package/dist/types/eval/__tests__/completion-bridge.test.d.ts +0 -1
  80. package/dist/types/eval/__tests__/helpers-local-roots.test.d.ts +0 -1
  81. package/dist/types/eval/__tests__/idle-timeout.test.d.ts +0 -1
  82. package/dist/types/eval/__tests__/js-context-manager.test.d.ts +0 -1
  83. package/dist/types/eval/__tests__/julia-prelude.test.d.ts +0 -1
  84. package/dist/types/eval/__tests__/kernel-spawn.test.d.ts +0 -1
  85. package/dist/types/eval/__tests__/prelude-agent.test.d.ts +0 -1
  86. package/dist/types/eval/__tests__/process-entry-import.test.d.ts +0 -1
  87. package/dist/types/eval/py/__tests__/prelude.test.d.ts +0 -1
  88. package/dist/types/eval/py/__tests__/runner-shell-output.test.d.ts +0 -1
  89. package/dist/types/hindsight/client.test.d.ts +0 -1
  90. package/dist/types/internal-urls/__tests__/agent-protocol-nested.test.d.ts +0 -1
  91. package/dist/types/internal-urls/__tests__/ssh-protocol.test.d.ts +0 -1
  92. package/dist/types/launch/broker-list-order.test.d.ts +0 -1
  93. package/dist/types/launch/broker-output-snapshot.test.d.ts +0 -1
  94. package/dist/types/launch/protocol.test.d.ts +0 -1
  95. package/dist/types/launch/spawn-options.test.d.ts +0 -1
  96. package/dist/types/launch/terminal-output.test.d.ts +0 -1
  97. package/dist/types/live/protocol.test.d.ts +0 -1
  98. package/dist/types/mcp/config-writer.test.d.ts +0 -1
  99. package/dist/types/mcp/smithery-auth.test.d.ts +0 -1
  100. package/dist/types/mcp/smithery-registry.test.d.ts +0 -1
  101. package/dist/types/mcp/transports/stdio.test.d.ts +0 -1
  102. package/dist/types/modes/components/__tests__/dynamic-border.test.d.ts +0 -1
  103. package/dist/types/modes/components/__tests__/move-overlay.test.d.ts +0 -1
  104. package/dist/types/modes/components/__tests__/pause-screen.test.d.ts +0 -1
  105. package/dist/types/modes/components/__tests__/skill-message.test.d.ts +0 -1
  106. package/dist/types/modes/components/custom-editor-plugin-ctor.test.d.ts +0 -1
  107. package/dist/types/modes/components/custom-editor.test.d.ts +0 -1
  108. package/dist/types/modes/components/login-dialog.test.d.ts +0 -1
  109. package/dist/types/modes/components/status-line/component.jj-cache.test.d.ts +0 -1
  110. package/dist/types/modes/components/status-line/component.test.d.ts +0 -1
  111. package/dist/types/modes/components/tool-execution.test.d.ts +0 -1
  112. package/dist/types/modes/controllers/extension-ui-controller.test.d.ts +0 -1
  113. package/dist/types/modes/noninteractive-dispose.test.d.ts +0 -1
  114. package/dist/types/modes/print-mode.test.d.ts +0 -1
  115. package/dist/types/modes/session-teardown.test.d.ts +0 -1
  116. package/dist/types/modes/theme/mermaid-rendering.test.d.ts +0 -1
  117. package/dist/types/modes/utils/transcript-render-helpers.test.d.ts +0 -1
  118. package/dist/types/modes/warp-events.test.d.ts +0 -1
  119. package/dist/types/plan-mode/approved-plan-prompt.test.d.ts +0 -1
  120. package/dist/types/plan-mode/model-transition.test.d.ts +0 -1
  121. package/dist/types/plan-mode/reentry-prompt.test.d.ts +0 -1
  122. package/dist/types/session/agent-session-error-log.test.d.ts +0 -1
  123. package/dist/types/session/blob-store.test.d.ts +0 -1
  124. package/dist/types/session/messages.test.d.ts +0 -1
  125. package/dist/types/session/session-context.test.d.ts +0 -1
  126. package/dist/types/ssh/__tests__/connection-manager-args.test.d.ts +0 -1
  127. package/dist/types/ssh/__tests__/connection-manager-timeout.test.d.ts +0 -1
  128. package/dist/types/ssh/__tests__/file-transfer-posix-guard.test.d.ts +0 -1
  129. package/dist/types/ssh/__tests__/sshfs-mount.test.d.ts +0 -1
  130. package/dist/types/system-prompt.test.d.ts +0 -1
  131. package/dist/types/task/render.test.d.ts +0 -1
  132. package/dist/types/task/spawn-policy.test.d.ts +0 -1
  133. package/dist/types/tools/__tests__/eval-description.test.d.ts +0 -1
  134. package/dist/types/tools/__tests__/glob.test.d.ts +0 -1
  135. package/dist/types/tools/__tests__/json-tree.test.d.ts +0 -1
  136. package/dist/types/tools/__tests__/vibe-render.test.d.ts +0 -1
  137. package/dist/types/tools/hub/launch-compat.test.d.ts +0 -1
  138. package/dist/types/vibe/__tests__/token-rate.test.d.ts +0 -1
  139. package/src/advisor/__tests__/advisor.test.ts +0 -4889
  140. package/src/advisor/__tests__/config.test.ts +0 -349
  141. package/src/advisor/__tests__/emission-guard.test.ts +0 -147
  142. package/src/cli/__tests__/auth-gateway-catalog.test.ts +0 -111
  143. package/src/cli/update-cli.test.ts +0 -28
  144. package/src/config/__tests__/model-registry.test.ts +0 -182
  145. package/src/eval/__tests__/agent-bridge.test.ts +0 -1509
  146. package/src/eval/__tests__/bridge-timeout.test.ts +0 -170
  147. package/src/eval/__tests__/budget-bridge.test.ts +0 -80
  148. package/src/eval/__tests__/completion-bridge.test.ts +0 -412
  149. package/src/eval/__tests__/helpers-local-roots.test.ts +0 -55
  150. package/src/eval/__tests__/idle-timeout.test.ts +0 -80
  151. package/src/eval/__tests__/js-context-manager.test.ts +0 -456
  152. package/src/eval/__tests__/julia-prelude.test.ts +0 -66
  153. package/src/eval/__tests__/kernel-spawn.test.ts +0 -115
  154. package/src/eval/__tests__/prelude-agent.test.ts +0 -156
  155. package/src/eval/__tests__/process-entry-import.test.ts +0 -137
  156. package/src/eval/py/__tests__/prelude.test.ts +0 -104
  157. package/src/eval/py/__tests__/runner-shell-output.test.ts +0 -157
  158. package/src/hindsight/client.test.ts +0 -75
  159. package/src/internal-urls/__tests__/agent-protocol-nested.test.ts +0 -141
  160. package/src/internal-urls/__tests__/ssh-protocol.test.ts +0 -331
  161. package/src/launch/broker-list-order.test.ts +0 -89
  162. package/src/launch/broker-output-snapshot.test.ts +0 -126
  163. package/src/launch/protocol.test.ts +0 -59
  164. package/src/launch/spawn-options.test.ts +0 -31
  165. package/src/launch/terminal-output.test.ts +0 -107
  166. package/src/live/protocol.test.ts +0 -140
  167. package/src/mcp/config-writer.test.ts +0 -43
  168. package/src/mcp/smithery-auth.test.ts +0 -29
  169. package/src/mcp/smithery-registry.test.ts +0 -51
  170. package/src/mcp/transports/stdio.test.ts +0 -427
  171. package/src/modes/components/__tests__/dynamic-border.test.ts +0 -55
  172. package/src/modes/components/__tests__/move-overlay.test.ts +0 -252
  173. package/src/modes/components/__tests__/pause-screen.test.ts +0 -143
  174. package/src/modes/components/__tests__/skill-message.test.ts +0 -94
  175. package/src/modes/components/custom-editor-plugin-ctor.test.ts +0 -36
  176. package/src/modes/components/custom-editor.test.ts +0 -510
  177. package/src/modes/components/login-dialog.test.ts +0 -56
  178. package/src/modes/components/status-line/component.jj-cache.test.ts +0 -229
  179. package/src/modes/components/status-line/component.test.ts +0 -84
  180. package/src/modes/components/tool-execution.test.ts +0 -162
  181. package/src/modes/controllers/extension-ui-controller.test.ts +0 -250
  182. package/src/modes/noninteractive-dispose.test.ts +0 -73
  183. package/src/modes/print-mode.test.ts +0 -71
  184. package/src/modes/session-teardown.test.ts +0 -219
  185. package/src/modes/theme/mermaid-rendering.test.ts +0 -53
  186. package/src/modes/utils/transcript-render-helpers.test.ts +0 -38
  187. package/src/modes/warp-events.test.ts +0 -794
  188. package/src/plan-mode/approved-plan-prompt.test.ts +0 -36
  189. package/src/plan-mode/model-transition.test.ts +0 -60
  190. package/src/plan-mode/reentry-prompt.test.ts +0 -41
  191. package/src/session/agent-session-error-log.test.ts +0 -59
  192. package/src/session/blob-store.test.ts +0 -56
  193. package/src/session/messages.test.ts +0 -282
  194. package/src/session/session-context.test.ts +0 -384
  195. package/src/ssh/__tests__/connection-manager-args.test.ts +0 -191
  196. package/src/ssh/__tests__/connection-manager-timeout.test.ts +0 -61
  197. package/src/ssh/__tests__/file-transfer-posix-guard.test.ts +0 -105
  198. package/src/ssh/__tests__/sshfs-mount.test.ts +0 -13
  199. package/src/system-prompt.test.ts +0 -236
  200. package/src/task/render.test.ts +0 -290
  201. package/src/task/spawn-policy.test.ts +0 -62
  202. package/src/tools/__tests__/eval-description.test.ts +0 -18
  203. package/src/tools/__tests__/glob.test.ts +0 -37
  204. package/src/tools/__tests__/json-tree.test.ts +0 -35
  205. package/src/tools/__tests__/vibe-render.test.ts +0 -210
  206. package/src/tools/hub/launch-compat.test.ts +0 -40
  207. package/src/vibe/__tests__/token-rate.test.ts +0 -96
@@ -1,182 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, test, vi } from "bun:test";
2
- import { mkdtempSync, rmSync } from "node:fs";
3
- import * as os from "node:os";
4
- import * as path from "node:path";
5
- import type { AuthStorage } from "@oh-my-pi/pi-ai";
6
- import { buildModel } from "@oh-my-pi/pi-catalog/build";
7
- import { ModelRegistry } from "../model-registry";
8
-
9
- /** Stub auth storage for registry lifecycle and missing-credential coverage. */
10
- function createStubAuthStorage(): AuthStorage {
11
- const stub = {
12
- setFallbackResolver: () => {},
13
- clearConfigApiKeys: () => {},
14
- hasAuth: () => false,
15
- getApiKey: async () => undefined,
16
- };
17
- return stub as unknown as AuthStorage;
18
- }
19
-
20
- const testModel = buildModel({
21
- id: "test-model",
22
- name: "Test Model",
23
- api: "openai-completions",
24
- provider: "test",
25
- baseUrl: "https://example.test",
26
- reasoning: false,
27
- input: ["text"],
28
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
29
- contextWindow: 1000,
30
- maxTokens: 100,
31
- });
32
-
33
- describe("ModelRegistry", () => {
34
- let tmpDir: string;
35
- let registry: ModelRegistry;
36
-
37
- beforeEach(() => {
38
- tmpDir = mkdtempSync(path.join(os.tmpdir(), "omp-reg-"));
39
- // Construct with an explicit modelsPath inside the temp dir so the
40
- // constructor's #loadModels read returns "not-found" rather than
41
- // touching the host's ~/.omp/agent/models.yaml. isBunTestRuntime()
42
- // auto-stubs #fetch in the constructor.
43
- registry = new ModelRegistry(createStubAuthStorage(), path.join(tmpDir, "models.yaml"));
44
- });
45
-
46
- afterEach(() => {
47
- vi.restoreAllMocks();
48
- rmSync(tmpDir, { recursive: true, force: true });
49
- });
50
-
51
- test("resolves immediately when no background refresh is in flight", async () => {
52
- // No refreshInBackground() called → #backgroundRefresh is undefined.
53
- // The awaiter must settle within a single microtask, never hanging.
54
- let settled = false;
55
- const p = registry.awaitBackgroundRefresh().then(() => {
56
- settled = true;
57
- });
58
- await Promise.resolve();
59
- await p;
60
- expect(settled).toBe(true);
61
- });
62
-
63
- test("blocks until the in-flight background refresh resolves, then resolves", async () => {
64
- // Drive refreshInBackground with a controlled refresh() return value so
65
- // #backgroundRefresh is captured but not yet settled.
66
- const { promise, resolve } = Promise.withResolvers<void>();
67
- const refreshSpy = vi.spyOn(registry, "refresh").mockReturnValue(promise);
68
-
69
- registry.refreshInBackground();
70
- expect(refreshSpy).toHaveBeenCalledTimes(1);
71
-
72
- let settled = false;
73
- const awaitPromise = registry.awaitBackgroundRefresh().then(() => {
74
- settled = true;
75
- });
76
-
77
- // Yield to the microtask queue: the awaiter must still be pending.
78
- for (let i = 0; i < 5; i++) await Promise.resolve();
79
- expect(settled).toBe(false);
80
-
81
- resolve();
82
-
83
- await awaitPromise;
84
- expect(settled).toBe(true);
85
- });
86
-
87
- test("resolves even when the underlying refresh rejects (refreshInBackground swallows)", async () => {
88
- // refreshInBackground wraps refresh() in .catch(...) so discovery errors
89
- // never reach awaitBackgroundRefresh callers. The awaiter must resolve,
90
- // not propagate the rejection.
91
- const { promise, reject } = Promise.withResolvers<void>();
92
- vi.spyOn(registry, "refresh").mockReturnValue(promise);
93
-
94
- registry.refreshInBackground();
95
-
96
- let settled = false;
97
- const awaitPromise = registry.awaitBackgroundRefresh().then(() => {
98
- settled = true;
99
- });
100
-
101
- reject(new Error("synthetic discovery failure"));
102
-
103
- await awaitPromise;
104
- expect(settled).toBe(true);
105
- });
106
-
107
- test("awaiter is a no-op after the in-flight refresh settles and clears #backgroundRefresh", async () => {
108
- // Once refreshInBackground's promise resolves, #backgroundRefresh is
109
- // cleared in the .finally. A subsequent awaitBackgroundRefresh must be
110
- // an immediate no-op (microtask), not hang waiting for a stale promise
111
- // or a second refresh that was never started.
112
- const { promise, resolve } = Promise.withResolvers<void>();
113
- vi.spyOn(registry, "refresh").mockReturnValue(promise);
114
-
115
- registry.refreshInBackground();
116
- resolve();
117
- await registry.awaitBackgroundRefresh();
118
-
119
- // Now #backgroundRefresh is cleared. A fresh await must resolve in a
120
- // single microtask — measure by asserting it settles before a second
121
- // microtask tick.
122
- let settled = false;
123
- const p = registry.awaitBackgroundRefresh().then(() => {
124
- settled = true;
125
- });
126
- await Promise.resolve();
127
- expect(settled).toBe(true);
128
- await p;
129
- });
130
-
131
- test("refreshInBackground deduplicates: a second call while in-flight starts no new refresh", async () => {
132
- // The guard `if (this.#backgroundRefresh) return` at the top of
133
- // refreshInBackground prevents concurrent refreshes. A second call
134
- // while the first is still pending must not invoke refresh() again.
135
- const { promise, resolve } = Promise.withResolvers<void>();
136
- const refreshSpy = vi.spyOn(registry, "refresh").mockReturnValue(promise);
137
-
138
- registry.refreshInBackground();
139
- registry.refreshInBackground();
140
- registry.refreshInBackground();
141
-
142
- expect(refreshSpy).toHaveBeenCalledTimes(1);
143
-
144
- resolve();
145
- await registry.awaitBackgroundRefresh();
146
-
147
- // After settle, #backgroundRefresh is cleared — a new call DOES start
148
- // a fresh refresh.
149
- const { promise: secondPromise, resolve: secondResolve } = Promise.withResolvers<void>();
150
- refreshSpy.mockReturnValue(secondPromise);
151
- registry.refreshInBackground();
152
- expect(refreshSpy).toHaveBeenCalledTimes(2);
153
-
154
- secondResolve();
155
- await registry.awaitBackgroundRefresh();
156
- });
157
- test("resolves API keys and provider headers for legacy extensions", async () => {
158
- const model = testModel;
159
- vi.spyOn(registry, "getApiKey").mockResolvedValue("test-key");
160
- vi.spyOn(registry, "getProviderHeaders").mockReturnValue({ "x-test": "value" });
161
-
162
- expect(await registry.getApiKeyAndHeaders(model)).toEqual({
163
- ok: true,
164
- apiKey: "test-key",
165
- headers: { "x-test": "value" },
166
- });
167
- });
168
-
169
- test("returns an error when authentication resolves without a credential", async () => {
170
- expect(await registry.getApiKeyAndHeaders(testModel)).toEqual({
171
- ok: false,
172
- error: 'No API key found for "test"',
173
- });
174
- });
175
-
176
- test("maps legacy extension auth failures into the result contract", async () => {
177
- const model = testModel;
178
- vi.spyOn(registry, "getApiKey").mockRejectedValue(new Error("auth failed"));
179
-
180
- expect(await registry.getApiKeyAndHeaders(model)).toEqual({ ok: false, error: "auth failed" });
181
- });
182
- });