@wingman-ai/gateway 0.2.2 → 0.2.4

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 (160) hide show
  1. package/.wingman/agents/README.md +7 -1
  2. package/.wingman/agents/coding/agent.md +299 -201
  3. package/.wingman/agents/coding-v2/agent.md +127 -0
  4. package/.wingman/agents/coding-v2/implementor.md +89 -0
  5. package/.wingman/agents/main/agent.md +4 -0
  6. package/README.md +1 -0
  7. package/dist/agent/config/agentConfig.cjs +31 -17
  8. package/dist/agent/config/agentConfig.d.ts +23 -1
  9. package/dist/agent/config/agentConfig.js +30 -19
  10. package/dist/agent/config/agentLoader.cjs +26 -8
  11. package/dist/agent/config/agentLoader.d.ts +4 -2
  12. package/dist/agent/config/agentLoader.js +26 -8
  13. package/dist/agent/config/modelFactory.cjs +95 -25
  14. package/dist/agent/config/modelFactory.d.ts +13 -1
  15. package/dist/agent/config/modelFactory.js +95 -25
  16. package/dist/agent/config/toolRegistry.cjs +19 -6
  17. package/dist/agent/config/toolRegistry.d.ts +5 -2
  18. package/dist/agent/config/toolRegistry.js +19 -6
  19. package/dist/agent/middleware/hooks/types.cjs +13 -13
  20. package/dist/agent/middleware/hooks/types.d.ts +1 -1
  21. package/dist/agent/middleware/hooks/types.js +14 -14
  22. package/dist/agent/tests/agentConfig.test.cjs +22 -2
  23. package/dist/agent/tests/agentConfig.test.js +22 -2
  24. package/dist/agent/tests/agentLoader.test.cjs +38 -1
  25. package/dist/agent/tests/agentLoader.test.js +38 -1
  26. package/dist/agent/tests/backgroundTerminal.test.cjs +70 -0
  27. package/dist/agent/tests/backgroundTerminal.test.d.ts +1 -0
  28. package/dist/agent/tests/backgroundTerminal.test.js +64 -0
  29. package/dist/agent/tests/commandExecuteTool.test.cjs +29 -0
  30. package/dist/agent/tests/commandExecuteTool.test.d.ts +1 -0
  31. package/dist/agent/tests/commandExecuteTool.test.js +23 -0
  32. package/dist/agent/tests/modelFactory.test.cjs +47 -5
  33. package/dist/agent/tests/modelFactory.test.js +47 -5
  34. package/dist/agent/tests/terminalSessionManager.test.cjs +121 -0
  35. package/dist/agent/tests/terminalSessionManager.test.d.ts +1 -0
  36. package/dist/agent/tests/terminalSessionManager.test.js +115 -0
  37. package/dist/agent/tests/toolRegistry.test.cjs +14 -2
  38. package/dist/agent/tests/toolRegistry.test.js +14 -2
  39. package/dist/agent/tools/background_terminal.cjs +128 -0
  40. package/dist/agent/tools/background_terminal.d.ts +41 -0
  41. package/dist/agent/tools/background_terminal.js +94 -0
  42. package/dist/agent/tools/code_search.cjs +6 -6
  43. package/dist/agent/tools/code_search.d.ts +1 -1
  44. package/dist/agent/tools/code_search.js +7 -7
  45. package/dist/agent/tools/command_execute.cjs +22 -7
  46. package/dist/agent/tools/command_execute.d.ts +3 -2
  47. package/dist/agent/tools/command_execute.js +23 -8
  48. package/dist/agent/tools/git_status.cjs +3 -3
  49. package/dist/agent/tools/git_status.d.ts +1 -1
  50. package/dist/agent/tools/git_status.js +4 -4
  51. package/dist/agent/tools/internet_search.cjs +6 -6
  52. package/dist/agent/tools/internet_search.d.ts +1 -1
  53. package/dist/agent/tools/internet_search.js +7 -7
  54. package/dist/agent/tools/terminal_session_manager.cjs +321 -0
  55. package/dist/agent/tools/terminal_session_manager.d.ts +77 -0
  56. package/dist/agent/tools/terminal_session_manager.js +284 -0
  57. package/dist/agent/tools/think.cjs +4 -4
  58. package/dist/agent/tools/think.d.ts +1 -1
  59. package/dist/agent/tools/think.js +5 -5
  60. package/dist/agent/tools/ui_registry.cjs +13 -13
  61. package/dist/agent/tools/ui_registry.d.ts +4 -4
  62. package/dist/agent/tools/ui_registry.js +14 -14
  63. package/dist/agent/tools/web_crawler.cjs +4 -4
  64. package/dist/agent/tools/web_crawler.d.ts +1 -1
  65. package/dist/agent/tools/web_crawler.js +5 -5
  66. package/dist/agent/utils.cjs +2 -1
  67. package/dist/agent/utils.js +2 -1
  68. package/dist/cli/commands/init.cjs +7 -6
  69. package/dist/cli/commands/init.js +7 -6
  70. package/dist/cli/commands/provider.cjs +17 -3
  71. package/dist/cli/commands/provider.js +17 -3
  72. package/dist/cli/config/loader.cjs +27 -0
  73. package/dist/cli/config/loader.js +27 -0
  74. package/dist/cli/config/schema.cjs +146 -68
  75. package/dist/cli/config/schema.d.ts +89 -1
  76. package/dist/cli/config/schema.js +134 -68
  77. package/dist/cli/core/agentInvoker.cjs +344 -17
  78. package/dist/cli/core/agentInvoker.d.ts +63 -3
  79. package/dist/cli/core/agentInvoker.js +303 -12
  80. package/dist/cli/core/sessionManager.cjs +32 -5
  81. package/dist/cli/core/sessionManager.js +32 -5
  82. package/dist/cli/core/streamParser.cjs +15 -0
  83. package/dist/cli/core/streamParser.js +15 -0
  84. package/dist/cli/index.cjs +6 -5
  85. package/dist/cli/index.js +6 -5
  86. package/dist/cli/types.d.ts +32 -0
  87. package/dist/cli/ui/toolDisplayHelpers.cjs +2 -0
  88. package/dist/cli/ui/toolDisplayHelpers.js +2 -0
  89. package/dist/gateway/hooks/registry.cjs +2 -1
  90. package/dist/gateway/hooks/registry.d.ts +1 -1
  91. package/dist/gateway/hooks/registry.js +2 -1
  92. package/dist/gateway/hooks/types.cjs +11 -11
  93. package/dist/gateway/hooks/types.d.ts +1 -1
  94. package/dist/gateway/hooks/types.js +12 -12
  95. package/dist/gateway/http/agents.cjs +67 -4
  96. package/dist/gateway/http/agents.js +67 -4
  97. package/dist/gateway/http/sessions.cjs +7 -7
  98. package/dist/gateway/http/sessions.js +7 -7
  99. package/dist/gateway/http/types.d.ts +5 -3
  100. package/dist/gateway/http/webhooks.cjs +6 -5
  101. package/dist/gateway/http/webhooks.js +6 -5
  102. package/dist/gateway/server.cjs +198 -41
  103. package/dist/gateway/server.d.ts +9 -1
  104. package/dist/gateway/server.js +198 -41
  105. package/dist/gateway/types.d.ts +1 -0
  106. package/dist/gateway/validation.cjs +39 -39
  107. package/dist/gateway/validation.d.ts +1 -1
  108. package/dist/gateway/validation.js +40 -40
  109. package/dist/providers/codex.cjs +167 -0
  110. package/dist/providers/codex.d.ts +15 -0
  111. package/dist/providers/codex.js +127 -0
  112. package/dist/providers/credentials.cjs +8 -0
  113. package/dist/providers/credentials.js +8 -0
  114. package/dist/providers/registry.cjs +11 -0
  115. package/dist/providers/registry.d.ts +1 -1
  116. package/dist/providers/registry.js +11 -0
  117. package/dist/tests/additionalMessageMiddleware.test.cjs +3 -0
  118. package/dist/tests/additionalMessageMiddleware.test.js +3 -0
  119. package/dist/tests/agentInvokerSummarization.test.cjs +455 -0
  120. package/dist/tests/agentInvokerSummarization.test.d.ts +1 -0
  121. package/dist/tests/agentInvokerSummarization.test.js +449 -0
  122. package/dist/tests/agents-api.test.cjs +45 -5
  123. package/dist/tests/agents-api.test.js +45 -5
  124. package/dist/tests/cli-config-loader.test.cjs +88 -0
  125. package/dist/tests/cli-config-loader.test.js +88 -0
  126. package/dist/tests/cli-init.test.cjs +27 -3
  127. package/dist/tests/cli-init.test.js +27 -3
  128. package/dist/tests/codex-credentials-precedence.test.cjs +94 -0
  129. package/dist/tests/codex-credentials-precedence.test.d.ts +1 -0
  130. package/dist/tests/codex-credentials-precedence.test.js +88 -0
  131. package/dist/tests/codex-provider.test.cjs +210 -0
  132. package/dist/tests/codex-provider.test.d.ts +1 -0
  133. package/dist/tests/codex-provider.test.js +204 -0
  134. package/dist/tests/gateway.test.cjs +115 -8
  135. package/dist/tests/gateway.test.js +115 -8
  136. package/dist/tests/provider-command-codex.test.cjs +57 -0
  137. package/dist/tests/provider-command-codex.test.d.ts +1 -0
  138. package/dist/tests/provider-command-codex.test.js +51 -0
  139. package/dist/tests/sessionStateMessages.test.cjs +38 -0
  140. package/dist/tests/sessionStateMessages.test.js +38 -0
  141. package/dist/tests/toolDisplayHelpers.test.cjs +3 -0
  142. package/dist/tests/toolDisplayHelpers.test.js +3 -0
  143. package/dist/tools/mcp-finance.cjs +48 -48
  144. package/dist/tools/mcp-finance.js +48 -48
  145. package/dist/types/mcp.cjs +15 -15
  146. package/dist/types/mcp.d.ts +1 -1
  147. package/dist/types/mcp.js +16 -16
  148. package/dist/types/voice.cjs +21 -21
  149. package/dist/types/voice.d.ts +1 -1
  150. package/dist/types/voice.js +22 -22
  151. package/dist/webui/assets/index-DVWQluit.css +11 -0
  152. package/dist/webui/assets/index-Dlyzwalc.js +270 -0
  153. package/dist/webui/favicon-32x32.png +0 -0
  154. package/dist/webui/favicon-64x64.png +0 -0
  155. package/dist/webui/favicon.webp +0 -0
  156. package/dist/webui/index.html +4 -2
  157. package/package.json +13 -12
  158. package/.wingman/agents/coding/implementor.md +0 -79
  159. package/dist/webui/assets/index-CPhfGPHc.js +0 -182
  160. package/dist/webui/assets/index-DDsMIOTX.css +0 -11
@@ -14,7 +14,8 @@ const isBun = void 0 !== globalThis.Bun;
14
14
  const describeIfBun = isBun ? describe : describe.skip;
15
15
  vi.mock("@/cli/core/agentInvoker.js", ()=>({
16
16
  AgentInvoker: class {
17
- async invokeAgent(_agentId, _content, _sessionId, _attachments, options) {
17
+ async invokeAgent(_agentId, content, _sessionId, _attachments, options) {
18
+ if ("throw-no-event" === content) throw new Error("Synthetic invocation failure");
18
19
  const signal = options?.signal;
19
20
  await new Promise((resolve)=>{
20
21
  const timer = setTimeout(resolve, 75);
@@ -173,14 +174,15 @@ describeIfBun("Gateway", ()=>{
173
174
  }));
174
175
  it("should broadcast messages to group members", async ()=>new Promise((resolve, reject)=>{
175
176
  let client1NodeId = null;
176
- let messagesReceived = 0;
177
+ let broadcastGroupId = null;
177
178
  const client1 = new GatewayClient(`ws://localhost:${port}/ws`, "broadcaster", {
178
179
  events: {
179
180
  registered: async (nodeId)=>{
180
181
  client1NodeId = nodeId;
181
182
  await client1.joinGroup("broadcast-test");
182
183
  },
183
- joinedGroup: ()=>{
184
+ joinedGroup: (groupId)=>{
185
+ broadcastGroupId = groupId;
184
186
  client2.connect().catch(reject);
185
187
  }
186
188
  }
@@ -191,14 +193,13 @@ describeIfBun("Gateway", ()=>{
191
193
  await client2.joinGroup("broadcast-test");
192
194
  },
193
195
  joinedGroup: ()=>{
194
- client1.broadcast("broadcast-test", {
196
+ client1.broadcast(broadcastGroupId || "broadcast-test", {
195
197
  message: "Hello from client 1"
196
198
  });
197
199
  },
198
200
  broadcast: (message, fromNodeId)=>{
199
201
  expect(fromNodeId).toBe(client1NodeId);
200
202
  expect(message.message).toBe("Hello from client 1");
201
- messagesReceived++;
202
203
  client1.disconnect();
203
204
  client2.disconnect();
204
205
  resolve();
@@ -331,6 +332,26 @@ describeIfBun("Gateway", ()=>{
331
332
  desktopClient.close();
332
333
  requester.close();
333
334
  });
335
+ it("should emit agent-error to requester when invocation throws without emitting", async ()=>{
336
+ const requester = await connectClient("session-error-requester");
337
+ const requestId = "req-invocation-error";
338
+ const sessionId = "session-error-test";
339
+ requester.send(JSON.stringify({
340
+ type: "req:agent",
341
+ id: requestId,
342
+ payload: {
343
+ agentId: "main",
344
+ sessionKey: sessionId,
345
+ content: "throw-no-event"
346
+ },
347
+ timestamp: Date.now()
348
+ }));
349
+ const errorMsg = await waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === requestId && msg.payload?.type === "agent-error");
350
+ expect(errorMsg.payload?.error).toContain("Synthetic invocation failure");
351
+ expect(errorMsg.payload?.sessionId).toBe(sessionId);
352
+ expect(errorMsg.payload?.agentId).toBe("main");
353
+ requester.close();
354
+ });
334
355
  it("should cancel an in-flight agent request", async ()=>{
335
356
  const requester = await connectClient("session-cancel-requester");
336
357
  const requestId = "req-cancel-test";
@@ -359,6 +380,92 @@ describeIfBun("Gateway", ()=>{
359
380
  ]).toContain(ack.payload?.status);
360
381
  requester.close();
361
382
  });
383
+ it("should queue and dequeue requests for the same session", async ()=>{
384
+ const requester = await connectClient("session-queue-requester");
385
+ const sessionId = `session-queue-${Date.now()}`;
386
+ const firstRequestId = `req-queue-first-${Date.now()}`;
387
+ const secondRequestId = `req-queue-second-${Date.now()}`;
388
+ const firstCompletePromise = waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === firstRequestId && msg.payload?.type === "agent-complete", 10000);
389
+ const queuedAckPromise = waitForMessage(requester, (msg)=>"ack" === msg.type && msg.id === secondRequestId && msg.payload?.action === "req:agent" && msg.payload?.status === "queued", 10000);
390
+ const queuedEventPromise = waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === secondRequestId && msg.payload?.type === "request-queued", 10000);
391
+ const dequeuedAckPromise = waitForMessage(requester, (msg)=>"ack" === msg.type && msg.id === secondRequestId && msg.payload?.action === "req:agent" && msg.payload?.status === "dequeued", 10000);
392
+ const secondCompletePromise = waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === secondRequestId && msg.payload?.type === "agent-complete", 10000);
393
+ requester.send(JSON.stringify({
394
+ type: "req:agent",
395
+ id: firstRequestId,
396
+ payload: {
397
+ agentId: "main",
398
+ sessionKey: sessionId,
399
+ content: "First queued request"
400
+ },
401
+ timestamp: Date.now()
402
+ }));
403
+ requester.send(JSON.stringify({
404
+ type: "req:agent",
405
+ id: secondRequestId,
406
+ payload: {
407
+ agentId: "main",
408
+ sessionKey: sessionId,
409
+ content: "Second queued request"
410
+ },
411
+ timestamp: Date.now()
412
+ }));
413
+ const queuedAck = await queuedAckPromise;
414
+ expect(queuedAck.payload?.position).toBe(1);
415
+ const queuedEvent = await queuedEventPromise;
416
+ expect(queuedEvent.payload?.position).toBe(1);
417
+ expect(queuedEvent.payload?.sessionId).toBe(sessionId);
418
+ await firstCompletePromise;
419
+ const dequeuedAck = await dequeuedAckPromise;
420
+ expect(dequeuedAck.payload?.remaining).toBe(0);
421
+ await secondCompletePromise;
422
+ requester.close();
423
+ });
424
+ it("should cancel a queued request", async ()=>{
425
+ const requester = await connectClient("session-cancel-queued-requester");
426
+ const sessionId = `session-cancel-queued-${Date.now()}`;
427
+ const firstRequestId = `req-cancel-queued-first-${Date.now()}`;
428
+ const secondRequestId = `req-cancel-queued-second-${Date.now()}`;
429
+ const queuedAckPromise = waitForMessage(requester, (msg)=>"ack" === msg.type && msg.id === secondRequestId && msg.payload?.action === "req:agent" && msg.payload?.status === "queued", 10000);
430
+ requester.send(JSON.stringify({
431
+ type: "req:agent",
432
+ id: firstRequestId,
433
+ payload: {
434
+ agentId: "main",
435
+ sessionKey: sessionId,
436
+ content: "First request"
437
+ },
438
+ timestamp: Date.now()
439
+ }));
440
+ requester.send(JSON.stringify({
441
+ type: "req:agent",
442
+ id: secondRequestId,
443
+ payload: {
444
+ agentId: "main",
445
+ sessionKey: sessionId,
446
+ content: "Second request"
447
+ },
448
+ timestamp: Date.now()
449
+ }));
450
+ await queuedAckPromise;
451
+ requester.send(JSON.stringify({
452
+ type: "req:agent:cancel",
453
+ id: `cancel-${secondRequestId}`,
454
+ payload: {
455
+ requestId: secondRequestId
456
+ },
457
+ timestamp: Date.now()
458
+ }));
459
+ const cancelAck = await waitForMessage(requester, (msg)=>"ack" === msg.type && msg.payload?.action === "req:agent:cancel" && msg.payload?.requestId === secondRequestId && msg.payload?.status === "cancelled_queued", 10000);
460
+ expect(cancelAck.payload?.status).toBe("cancelled_queued");
461
+ await waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === firstRequestId && msg.payload?.type === "agent-complete", 10000);
462
+ const queuedRequests = server.queuedSessionRequests;
463
+ const isStillQueued = [
464
+ ...queuedRequests.values()
465
+ ].some((queue)=>queue.some((item)=>item.msg?.id === secondRequestId));
466
+ expect(isStillQueued).toBe(false);
467
+ requester.close();
468
+ });
362
469
  it("should clear session messages via API", async ()=>{
363
470
  const createRes = await fetch(`http://localhost:${port}/api/sessions`, {
364
471
  method: "POST",
@@ -366,18 +473,18 @@ describeIfBun("Gateway", ()=>{
366
473
  "Content-Type": "application/json"
367
474
  },
368
475
  body: JSON.stringify({
369
- agentId: "main",
370
476
  name: "Clear Test"
371
477
  })
372
478
  });
373
479
  expect(createRes.ok).toBe(true);
374
480
  const session = await createRes.json();
375
- const manager = await server.getSessionManager("main");
481
+ const sessionAgentId = session.agentId || "main";
482
+ const manager = await server.getSessionManager(sessionAgentId);
376
483
  manager.updateSession(session.id, {
377
484
  messageCount: 3,
378
485
  lastMessagePreview: "Hello"
379
486
  });
380
- const clearRes = await fetch(`http://localhost:${port}/api/sessions/${encodeURIComponent(session.id)}/messages?agentId=main`, {
487
+ const clearRes = await fetch(`http://localhost:${port}/api/sessions/${encodeURIComponent(session.id)}/messages?agentId=${encodeURIComponent(sessionAgentId)}`, {
381
488
  method: "DELETE"
382
489
  });
383
490
  expect(clearRes.ok).toBe(true);
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __webpack_exports__ = {};
3
+ const external_node_fs_namespaceObject = require("node:fs");
4
+ const external_node_os_namespaceObject = require("node:os");
5
+ const external_node_path_namespaceObject = require("node:path");
6
+ const external_vitest_namespaceObject = require("vitest");
7
+ const provider_cjs_namespaceObject = require("../cli/commands/provider.cjs");
8
+ const codex_cjs_namespaceObject = require("../providers/codex.cjs");
9
+ (0, external_vitest_namespaceObject.describe)("provider command codex login", ()=>{
10
+ let codexHome;
11
+ const originalCodexHome = process.env.CODEX_HOME;
12
+ (0, external_vitest_namespaceObject.beforeEach)(()=>{
13
+ codexHome = (0, external_node_fs_namespaceObject.mkdtempSync)((0, external_node_path_namespaceObject.join)((0, external_node_os_namespaceObject.tmpdir)(), "wingman-provider-codex-"));
14
+ process.env.CODEX_HOME = codexHome;
15
+ });
16
+ (0, external_vitest_namespaceObject.afterEach)(()=>{
17
+ if (void 0 === originalCodexHome) delete process.env.CODEX_HOME;
18
+ else process.env.CODEX_HOME = originalCodexHome;
19
+ if ((0, external_node_fs_namespaceObject.existsSync)(codexHome)) (0, external_node_fs_namespaceObject.rmSync)(codexHome, {
20
+ recursive: true,
21
+ force: true
22
+ });
23
+ });
24
+ (0, external_vitest_namespaceObject.it)("uses existing codex login without requiring a token", async ()=>{
25
+ const authPath = (0, codex_cjs_namespaceObject.getCodexAuthPath)();
26
+ (0, external_node_fs_namespaceObject.mkdirSync)((0, external_node_path_namespaceObject.dirname)(authPath), {
27
+ recursive: true
28
+ });
29
+ (0, external_node_fs_namespaceObject.writeFileSync)(authPath, JSON.stringify({
30
+ tokens: {
31
+ access_token: "codex-access-token",
32
+ account_id: "acct_123"
33
+ }
34
+ }, null, 2));
35
+ const exitSpy = external_vitest_namespaceObject.vi.spyOn(process, "exit").mockImplementation((code)=>{
36
+ throw new Error(`process.exit(${code ?? "undefined"})`);
37
+ });
38
+ try {
39
+ await (0, external_vitest_namespaceObject.expect)((0, provider_cjs_namespaceObject.executeProviderCommand)({
40
+ subcommand: "login",
41
+ args: [
42
+ "codex"
43
+ ],
44
+ verbosity: "silent",
45
+ outputMode: "json",
46
+ options: {}
47
+ })).resolves.toBeUndefined();
48
+ (0, external_vitest_namespaceObject.expect)(exitSpy).not.toHaveBeenCalled();
49
+ } finally{
50
+ exitSpy.mockRestore();
51
+ }
52
+ });
53
+ });
54
+ for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
55
+ Object.defineProperty(exports, '__esModule', {
56
+ value: true
57
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,51 @@
1
+ import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { dirname, join } from "node:path";
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
+ import { executeProviderCommand } from "../cli/commands/provider.js";
6
+ import { getCodexAuthPath } from "../providers/codex.js";
7
+ describe("provider command codex login", ()=>{
8
+ let codexHome;
9
+ const originalCodexHome = process.env.CODEX_HOME;
10
+ beforeEach(()=>{
11
+ codexHome = mkdtempSync(join(tmpdir(), "wingman-provider-codex-"));
12
+ process.env.CODEX_HOME = codexHome;
13
+ });
14
+ afterEach(()=>{
15
+ if (void 0 === originalCodexHome) delete process.env.CODEX_HOME;
16
+ else process.env.CODEX_HOME = originalCodexHome;
17
+ if (existsSync(codexHome)) rmSync(codexHome, {
18
+ recursive: true,
19
+ force: true
20
+ });
21
+ });
22
+ it("uses existing codex login without requiring a token", async ()=>{
23
+ const authPath = getCodexAuthPath();
24
+ mkdirSync(dirname(authPath), {
25
+ recursive: true
26
+ });
27
+ writeFileSync(authPath, JSON.stringify({
28
+ tokens: {
29
+ access_token: "codex-access-token",
30
+ account_id: "acct_123"
31
+ }
32
+ }, null, 2));
33
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation((code)=>{
34
+ throw new Error(`process.exit(${code ?? "undefined"})`);
35
+ });
36
+ try {
37
+ await expect(executeProviderCommand({
38
+ subcommand: "login",
39
+ args: [
40
+ "codex"
41
+ ],
42
+ verbosity: "silent",
43
+ outputMode: "json",
44
+ options: {}
45
+ })).resolves.toBeUndefined();
46
+ expect(exitSpy).not.toHaveBeenCalled();
47
+ } finally{
48
+ exitSpy.mockRestore();
49
+ }
50
+ });
51
+ });
@@ -65,6 +65,44 @@ const sessionManager_cjs_namespaceObject = require("../cli/core/sessionManager.c
65
65
  content: "keep"
66
66
  });
67
67
  });
68
+ (0, external_vitest_namespaceObject.it)("extracts content from responses-style text blocks", ()=>{
69
+ const state = {
70
+ createdAt: 2000,
71
+ values: {
72
+ messages: [
73
+ {
74
+ role: "user",
75
+ content: [
76
+ {
77
+ type: "input_text",
78
+ text: "Build a plan"
79
+ }
80
+ ]
81
+ },
82
+ {
83
+ role: "assistant",
84
+ content: [
85
+ {
86
+ type: "output_text",
87
+ text: "Here is the plan."
88
+ }
89
+ ]
90
+ }
91
+ ]
92
+ }
93
+ };
94
+ const result = (0, sessionManager_cjs_namespaceObject.extractMessagesFromState)(state);
95
+ (0, external_vitest_namespaceObject.expect)(result).not.toBeNull();
96
+ (0, external_vitest_namespaceObject.expect)(result).toHaveLength(2);
97
+ (0, external_vitest_namespaceObject.expect)(result?.[0]).toMatchObject({
98
+ role: "user",
99
+ content: "Build a plan"
100
+ });
101
+ (0, external_vitest_namespaceObject.expect)(result?.[1]).toMatchObject({
102
+ role: "assistant",
103
+ content: "Here is the plan."
104
+ });
105
+ });
68
106
  });
69
107
  for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
70
108
  Object.defineProperty(exports, '__esModule', {
@@ -63,4 +63,42 @@ describe("extractMessagesFromState", ()=>{
63
63
  content: "keep"
64
64
  });
65
65
  });
66
+ it("extracts content from responses-style text blocks", ()=>{
67
+ const state = {
68
+ createdAt: 2000,
69
+ values: {
70
+ messages: [
71
+ {
72
+ role: "user",
73
+ content: [
74
+ {
75
+ type: "input_text",
76
+ text: "Build a plan"
77
+ }
78
+ ]
79
+ },
80
+ {
81
+ role: "assistant",
82
+ content: [
83
+ {
84
+ type: "output_text",
85
+ text: "Here is the plan."
86
+ }
87
+ ]
88
+ }
89
+ ]
90
+ }
91
+ };
92
+ const result = extractMessagesFromState(state);
93
+ expect(result).not.toBeNull();
94
+ expect(result).toHaveLength(2);
95
+ expect(result?.[0]).toMatchObject({
96
+ role: "user",
97
+ content: "Build a plan"
98
+ });
99
+ expect(result?.[1]).toMatchObject({
100
+ role: "assistant",
101
+ content: "Here is the plan."
102
+ });
103
+ });
66
104
  });
@@ -19,6 +19,9 @@ const toolDisplayHelpers_cjs_namespaceObject = require("../cli/ui/toolDisplayHel
19
19
  (0, external_vitest_namespaceObject.expect)((0, toolDisplayHelpers_cjs_namespaceObject.extractSubagentName)({
20
20
  subagent: "Runner"
21
21
  })).toBe("Runner");
22
+ (0, external_vitest_namespaceObject.expect)((0, toolDisplayHelpers_cjs_namespaceObject.extractSubagentName)({
23
+ subagent_type: "reviewer"
24
+ })).toBe("reviewer");
22
25
  (0, external_vitest_namespaceObject.expect)((0, toolDisplayHelpers_cjs_namespaceObject.extractSubagentName)({
23
26
  agent: {
24
27
  name: "Writer"
@@ -17,6 +17,9 @@ describe("toolDisplayHelpers", ()=>{
17
17
  expect(extractSubagentName({
18
18
  subagent: "Runner"
19
19
  })).toBe("Runner");
20
+ expect(extractSubagentName({
21
+ subagent_type: "reviewer"
22
+ })).toBe("reviewer");
20
23
  expect(extractSubagentName({
21
24
  agent: {
22
25
  name: "Writer"
@@ -246,8 +246,8 @@ var __webpack_modules__ = {
246
246
  server.registerTool("finnhub.symbolSearch", {
247
247
  title: "Finnhub Symbol Search",
248
248
  description: "Search for symbols or companies by query.",
249
- inputSchema: zod__rspack_import_2.z.object({
250
- query: zod__rspack_import_2.z.string().min(1)
249
+ inputSchema: zod__rspack_import_2.object({
250
+ query: zod__rspack_import_2.string().min(1)
251
251
  })
252
252
  }, async ({ query })=>{
253
253
  const data = await fetchFinnhub("/search", {
@@ -258,8 +258,8 @@ var __webpack_modules__ = {
258
258
  server.registerTool("finnhub.quote", {
259
259
  title: "Finnhub Quote",
260
260
  description: "Get the latest quote for a symbol.",
261
- inputSchema: zod__rspack_import_2.z.object({
262
- symbol: zod__rspack_import_2.z.string().min(1)
261
+ inputSchema: zod__rspack_import_2.object({
262
+ symbol: zod__rspack_import_2.string().min(1)
263
263
  })
264
264
  }, async ({ symbol })=>{
265
265
  const data = await fetchFinnhub("/quote", {
@@ -270,8 +270,8 @@ var __webpack_modules__ = {
270
270
  server.registerTool("finnhub.companyProfile", {
271
271
  title: "Finnhub Company Profile",
272
272
  description: "Get company profile data for a symbol.",
273
- inputSchema: zod__rspack_import_2.z.object({
274
- symbol: zod__rspack_import_2.z.string().min(1)
273
+ inputSchema: zod__rspack_import_2.object({
274
+ symbol: zod__rspack_import_2.string().min(1)
275
275
  })
276
276
  }, async ({ symbol })=>{
277
277
  const data = await fetchFinnhub("/stock/profile2", {
@@ -282,9 +282,9 @@ var __webpack_modules__ = {
282
282
  server.registerTool("finnhub.financials", {
283
283
  title: "Finnhub Financial Metrics",
284
284
  description: "Get financial metrics (including P/E) for a symbol.",
285
- inputSchema: zod__rspack_import_2.z.object({
286
- symbol: zod__rspack_import_2.z.string().min(1),
287
- metric: zod__rspack_import_2.z.string().optional().default("all")
285
+ inputSchema: zod__rspack_import_2.object({
286
+ symbol: zod__rspack_import_2.string().min(1),
287
+ metric: zod__rspack_import_2.string().optional().default("all")
288
288
  })
289
289
  }, async ({ symbol, metric })=>{
290
290
  const data = await fetchFinnhub("/stock/metric", {
@@ -296,9 +296,9 @@ var __webpack_modules__ = {
296
296
  server.registerTool("finnhub.earnings", {
297
297
  title: "Finnhub Earnings",
298
298
  description: "Get earnings history for a symbol.",
299
- inputSchema: zod__rspack_import_2.z.object({
300
- symbol: zod__rspack_import_2.z.string().min(1),
301
- limit: zod__rspack_import_2.z.number().int().min(1).max(20).optional()
299
+ inputSchema: zod__rspack_import_2.object({
300
+ symbol: zod__rspack_import_2.string().min(1),
301
+ limit: zod__rspack_import_2.number().int().min(1).max(20).optional()
302
302
  })
303
303
  }, async ({ symbol, limit })=>{
304
304
  const data = await fetchFinnhub("/stock/earnings", {
@@ -312,10 +312,10 @@ var __webpack_modules__ = {
312
312
  server.registerTool("finnhub.news", {
313
313
  title: "Finnhub Company News",
314
314
  description: "Get recent company news for a symbol.",
315
- inputSchema: zod__rspack_import_2.z.object({
316
- symbol: zod__rspack_import_2.z.string().min(1),
317
- from: zod__rspack_import_2.z.string().optional(),
318
- to: zod__rspack_import_2.z.string().optional()
315
+ inputSchema: zod__rspack_import_2.object({
316
+ symbol: zod__rspack_import_2.string().min(1),
317
+ from: zod__rspack_import_2.string().optional(),
318
+ to: zod__rspack_import_2.string().optional()
319
319
  })
320
320
  }, async ({ symbol, from, to })=>{
321
321
  const toDate = to || new Date().toISOString().slice(0, 10);
@@ -335,8 +335,8 @@ var __webpack_modules__ = {
335
335
  server.registerTool("finnhub.marketNews", {
336
336
  title: "Finnhub Market News",
337
337
  description: "Get broad market news (general category) for theme detection.",
338
- inputSchema: zod__rspack_import_2.z.object({
339
- category: zod__rspack_import_2.z.string().min(1).optional().default("general")
338
+ inputSchema: zod__rspack_import_2.object({
339
+ category: zod__rspack_import_2.string().min(1).optional().default("general")
340
340
  })
341
341
  }, async ({ category })=>{
342
342
  const data = await fetchFinnhub("/news", {
@@ -347,8 +347,8 @@ var __webpack_modules__ = {
347
347
  server.registerTool("finnhub.peers", {
348
348
  title: "Finnhub Stock Peers",
349
349
  description: "Get peer symbols for a company.",
350
- inputSchema: zod__rspack_import_2.z.object({
351
- symbol: zod__rspack_import_2.z.string().min(1)
350
+ inputSchema: zod__rspack_import_2.object({
351
+ symbol: zod__rspack_import_2.string().min(1)
352
352
  })
353
353
  }, async ({ symbol })=>{
354
354
  const data = await fetchFinnhub("/stock/peers", {
@@ -359,12 +359,12 @@ var __webpack_modules__ = {
359
359
  server.registerTool("finnhub.candles", {
360
360
  title: "Finnhub Candles",
361
361
  description: `Get OHLCV candles for a symbol. ${candleCapSummary} ${candleSourceSummary} ${candleSessionSummary}`,
362
- inputSchema: zod__rspack_import_2.z.object({
363
- symbol: zod__rspack_import_2.z.string().min(1),
364
- resolution: zod__rspack_import_2.z.string().optional().default("D"),
365
- from: zod__rspack_import_2.z.number().int().optional(),
366
- to: zod__rspack_import_2.z.number().int().optional(),
367
- lookbackDays: zod__rspack_import_2.z.number().int().positive().optional()
362
+ inputSchema: zod__rspack_import_2.object({
363
+ symbol: zod__rspack_import_2.string().min(1),
364
+ resolution: zod__rspack_import_2.string().optional().default("D"),
365
+ from: zod__rspack_import_2.number().int().optional(),
366
+ to: zod__rspack_import_2.number().int().optional(),
367
+ lookbackDays: zod__rspack_import_2.number().int().positive().optional()
368
368
  })
369
369
  }, async ({ symbol, resolution, from, to, lookbackDays })=>{
370
370
  const range = (0, _finance_candleRange_js__rspack_import_5.resolveCandleRange)({
@@ -390,12 +390,12 @@ var __webpack_modules__ = {
390
390
  server.registerTool("finnhub.technicalSnapshot", {
391
391
  title: "Finnhub Technical Snapshot",
392
392
  description: `Fetch candles and compute RSI/EMA/ATR locally. ${candleCapSummary} ${candleSourceSummary} ${candleSessionSummary}`,
393
- inputSchema: zod__rspack_import_2.z.object({
394
- symbol: zod__rspack_import_2.z.string().min(1),
395
- resolution: zod__rspack_import_2.z.string().optional().default("D"),
396
- from: zod__rspack_import_2.z.number().int().optional(),
397
- to: zod__rspack_import_2.z.number().int().optional(),
398
- lookbackDays: zod__rspack_import_2.z.number().int().positive().optional()
393
+ inputSchema: zod__rspack_import_2.object({
394
+ symbol: zod__rspack_import_2.string().min(1),
395
+ resolution: zod__rspack_import_2.string().optional().default("D"),
396
+ from: zod__rspack_import_2.number().int().optional(),
397
+ to: zod__rspack_import_2.number().int().optional(),
398
+ lookbackDays: zod__rspack_import_2.number().int().positive().optional()
399
399
  })
400
400
  }, async ({ symbol, resolution, from, to, lookbackDays })=>{
401
401
  const range = (0, _finance_candleRange_js__rspack_import_5.resolveCandleRange)({
@@ -440,9 +440,9 @@ var __webpack_modules__ = {
440
440
  server.registerTool("finnhub.optionChain", {
441
441
  title: "Finnhub Option Chain",
442
442
  description: "Get option chain data for a symbol (date optional).",
443
- inputSchema: zod__rspack_import_2.z.object({
444
- symbol: zod__rspack_import_2.z.string().min(1),
445
- date: zod__rspack_import_2.z.string().optional()
443
+ inputSchema: zod__rspack_import_2.object({
444
+ symbol: zod__rspack_import_2.string().min(1),
445
+ date: zod__rspack_import_2.string().optional()
446
446
  })
447
447
  }, async ({ symbol, date })=>{
448
448
  const data = await fetchFinnhub("/stock/option-chain", {
@@ -456,25 +456,25 @@ var __webpack_modules__ = {
456
456
  server.registerTool("options.analyze", {
457
457
  title: "Options Structure Analyzer",
458
458
  description: "Compute payoff metrics and optional Greeks for an options structure using supplied leg prices.",
459
- inputSchema: zod__rspack_import_2.z.object({
460
- underlyingPrice: zod__rspack_import_2.z.number().positive(),
461
- daysToExpiry: zod__rspack_import_2.z.number().positive().optional(),
462
- riskFreeRate: zod__rspack_import_2.z.number().optional().default(0),
463
- dividendYield: zod__rspack_import_2.z.number().optional().default(0),
464
- legs: zod__rspack_import_2.z.array(zod__rspack_import_2.z.object({
465
- type: zod__rspack_import_2.z["enum"]([
459
+ inputSchema: zod__rspack_import_2.object({
460
+ underlyingPrice: zod__rspack_import_2.number().positive(),
461
+ daysToExpiry: zod__rspack_import_2.number().positive().optional(),
462
+ riskFreeRate: zod__rspack_import_2.number().optional().default(0),
463
+ dividendYield: zod__rspack_import_2.number().optional().default(0),
464
+ legs: zod__rspack_import_2.array(zod__rspack_import_2.object({
465
+ type: zod__rspack_import_2["enum"]([
466
466
  "call",
467
467
  "put"
468
468
  ]),
469
- side: zod__rspack_import_2.z["enum"]([
469
+ side: zod__rspack_import_2["enum"]([
470
470
  "buy",
471
471
  "sell"
472
472
  ]),
473
- strike: zod__rspack_import_2.z.number().positive(),
474
- premium: zod__rspack_import_2.z.number().nonnegative(),
475
- qty: zod__rspack_import_2.z.number().int().positive().optional(),
476
- contractMultiplier: zod__rspack_import_2.z.number().positive().optional(),
477
- impliedVol: zod__rspack_import_2.z.number().positive().optional()
473
+ strike: zod__rspack_import_2.number().positive(),
474
+ premium: zod__rspack_import_2.number().nonnegative(),
475
+ qty: zod__rspack_import_2.number().int().positive().optional(),
476
+ contractMultiplier: zod__rspack_import_2.number().positive().optional(),
477
+ impliedVol: zod__rspack_import_2.number().positive().optional()
478
478
  })).min(1)
479
479
  })
480
480
  }, async (input)=>{