@wingman-ai/gateway 0.2.5 → 0.3.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 (184) hide show
  1. package/README.md +9 -0
  2. package/dist/agent/config/agentConfig.cjs +12 -0
  3. package/dist/agent/config/agentConfig.d.ts +26 -0
  4. package/dist/agent/config/agentConfig.js +10 -1
  5. package/dist/agent/config/agentLoader.cjs +9 -0
  6. package/dist/agent/config/agentLoader.js +9 -0
  7. package/dist/agent/config/mcpClientManager.cjs +44 -10
  8. package/dist/agent/config/mcpClientManager.d.ts +6 -2
  9. package/dist/agent/config/mcpClientManager.js +44 -10
  10. package/dist/agent/config/toolRegistry.cjs +20 -1
  11. package/dist/agent/config/toolRegistry.d.ts +15 -0
  12. package/dist/agent/config/toolRegistry.js +20 -1
  13. package/dist/agent/tests/agentConfig.test.cjs +6 -1
  14. package/dist/agent/tests/agentConfig.test.js +6 -1
  15. package/dist/agent/tests/browserControlHelpers.test.cjs +35 -0
  16. package/dist/agent/tests/browserControlHelpers.test.d.ts +1 -0
  17. package/dist/agent/tests/browserControlHelpers.test.js +29 -0
  18. package/dist/agent/tests/browserControlTool.test.cjs +2117 -0
  19. package/dist/agent/tests/browserControlTool.test.d.ts +1 -0
  20. package/dist/agent/tests/browserControlTool.test.js +2111 -0
  21. package/dist/agent/tests/mcpClientManager.test.cjs +124 -0
  22. package/dist/agent/tests/mcpClientManager.test.d.ts +1 -0
  23. package/dist/agent/tests/mcpClientManager.test.js +118 -0
  24. package/dist/agent/tests/toolRegistry.test.cjs +6 -0
  25. package/dist/agent/tests/toolRegistry.test.js +6 -0
  26. package/dist/agent/tools/browser_control.cjs +1282 -0
  27. package/dist/agent/tools/browser_control.d.ts +478 -0
  28. package/dist/agent/tools/browser_control.js +1242 -0
  29. package/dist/agent/tools/command_execute.cjs +1 -1
  30. package/dist/agent/tools/command_execute.js +1 -1
  31. package/dist/cli/commands/agent.cjs +16 -2
  32. package/dist/cli/commands/agent.js +16 -2
  33. package/dist/cli/commands/browser.cjs +603 -0
  34. package/dist/cli/commands/browser.d.ts +13 -0
  35. package/dist/cli/commands/browser.js +566 -0
  36. package/dist/cli/commands/gateway.cjs +18 -7
  37. package/dist/cli/commands/gateway.d.ts +5 -1
  38. package/dist/cli/commands/gateway.js +18 -7
  39. package/dist/cli/commands/init.cjs +134 -45
  40. package/dist/cli/commands/init.js +134 -45
  41. package/dist/cli/commands/skill.cjs +3 -2
  42. package/dist/cli/commands/skill.js +3 -2
  43. package/dist/cli/config/loader.cjs +15 -0
  44. package/dist/cli/config/loader.js +15 -0
  45. package/dist/cli/config/schema.cjs +51 -2
  46. package/dist/cli/config/schema.d.ts +51 -0
  47. package/dist/cli/config/schema.js +44 -1
  48. package/dist/cli/core/agentInvoker.cjs +55 -66
  49. package/dist/cli/core/agentInvoker.d.ts +10 -13
  50. package/dist/cli/core/agentInvoker.js +42 -62
  51. package/dist/cli/core/imagePersistence.cjs +125 -0
  52. package/dist/cli/core/imagePersistence.d.ts +24 -0
  53. package/dist/cli/core/imagePersistence.js +85 -0
  54. package/dist/cli/core/sessionManager.cjs +297 -40
  55. package/dist/cli/core/sessionManager.d.ts +9 -0
  56. package/dist/cli/core/sessionManager.js +297 -40
  57. package/dist/cli/core/workspace.cjs +89 -0
  58. package/dist/cli/core/workspace.d.ts +1 -0
  59. package/dist/cli/core/workspace.js +55 -0
  60. package/dist/cli/index.cjs +53 -5
  61. package/dist/cli/index.js +53 -5
  62. package/dist/cli/types/browser.cjs +18 -0
  63. package/dist/cli/types/browser.d.ts +9 -0
  64. package/dist/cli/types/browser.js +0 -0
  65. package/dist/debug/terminalProbe.cjs +57 -0
  66. package/dist/debug/terminalProbe.d.ts +10 -0
  67. package/dist/debug/terminalProbe.js +20 -0
  68. package/dist/debug/terminalProbeAuth.cjs +140 -0
  69. package/dist/debug/terminalProbeAuth.d.ts +20 -0
  70. package/dist/debug/terminalProbeAuth.js +97 -0
  71. package/dist/gateway/browserRelayServer.cjs +338 -0
  72. package/dist/gateway/browserRelayServer.d.ts +38 -0
  73. package/dist/gateway/browserRelayServer.js +301 -0
  74. package/dist/gateway/http/agents.cjs +22 -0
  75. package/dist/gateway/http/agents.js +22 -0
  76. package/dist/gateway/http/fs.cjs +76 -0
  77. package/dist/gateway/http/fs.js +77 -1
  78. package/dist/gateway/http/sessions.cjs +25 -5
  79. package/dist/gateway/http/sessions.js +25 -5
  80. package/dist/gateway/server.cjs +155 -17
  81. package/dist/gateway/server.d.ts +6 -1
  82. package/dist/gateway/server.js +148 -16
  83. package/dist/gateway/transport/websocket.cjs +45 -10
  84. package/dist/gateway/transport/websocket.d.ts +1 -0
  85. package/dist/gateway/transport/websocket.js +41 -9
  86. package/dist/gateway/types.d.ts +4 -0
  87. package/dist/tests/agentInvokerSummarization.test.cjs +56 -37
  88. package/dist/tests/agentInvokerSummarization.test.js +58 -39
  89. package/dist/tests/agentInvokerWorkdir.test.cjs +50 -0
  90. package/dist/tests/agentInvokerWorkdir.test.js +52 -2
  91. package/dist/tests/agents-api.test.cjs +52 -0
  92. package/dist/tests/agents-api.test.js +53 -1
  93. package/dist/tests/browser-command.test.cjs +264 -0
  94. package/dist/tests/browser-command.test.d.ts +1 -0
  95. package/dist/tests/browser-command.test.js +258 -0
  96. package/dist/tests/browser-relay-server.test.cjs +20 -0
  97. package/dist/tests/browser-relay-server.test.d.ts +1 -0
  98. package/dist/tests/browser-relay-server.test.js +14 -0
  99. package/dist/tests/cli-config-loader.test.cjs +43 -0
  100. package/dist/tests/cli-config-loader.test.js +43 -0
  101. package/dist/tests/cli-init.test.cjs +61 -2
  102. package/dist/tests/cli-init.test.js +61 -2
  103. package/dist/tests/cli-workspace-root.test.cjs +114 -0
  104. package/dist/tests/cli-workspace-root.test.d.ts +1 -0
  105. package/dist/tests/cli-workspace-root.test.js +108 -0
  106. package/dist/tests/falRuntime.test.cjs +78 -0
  107. package/dist/tests/falRuntime.test.d.ts +1 -0
  108. package/dist/tests/falRuntime.test.js +72 -0
  109. package/dist/tests/falSummary.test.cjs +51 -0
  110. package/dist/tests/falSummary.test.d.ts +1 -0
  111. package/dist/tests/falSummary.test.js +45 -0
  112. package/dist/tests/fs-api.test.cjs +138 -0
  113. package/dist/tests/fs-api.test.d.ts +1 -0
  114. package/dist/tests/fs-api.test.js +132 -0
  115. package/dist/tests/gateway-command-workspace.test.cjs +150 -0
  116. package/dist/tests/gateway-command-workspace.test.d.ts +1 -0
  117. package/dist/tests/gateway-command-workspace.test.js +144 -0
  118. package/dist/tests/gateway-request-execution-overrides.test.cjs +42 -0
  119. package/dist/tests/gateway-request-execution-overrides.test.d.ts +1 -0
  120. package/dist/tests/gateway-request-execution-overrides.test.js +36 -0
  121. package/dist/tests/gateway.test.cjs +140 -1
  122. package/dist/tests/gateway.test.js +140 -1
  123. package/dist/tests/imagePersistence.test.cjs +143 -0
  124. package/dist/tests/imagePersistence.test.d.ts +1 -0
  125. package/dist/tests/imagePersistence.test.js +137 -0
  126. package/dist/tests/sessionMessageAttachments.test.cjs +30 -0
  127. package/dist/tests/sessionMessageAttachments.test.js +30 -0
  128. package/dist/tests/sessionStateMessages.test.cjs +126 -0
  129. package/dist/tests/sessionStateMessages.test.js +126 -0
  130. package/dist/tests/sessions-api.test.cjs +117 -3
  131. package/dist/tests/sessions-api.test.js +118 -4
  132. package/dist/tests/terminalProbe.test.cjs +45 -0
  133. package/dist/tests/terminalProbe.test.d.ts +1 -0
  134. package/dist/tests/terminalProbe.test.js +39 -0
  135. package/dist/tests/terminalProbeAuth.test.cjs +85 -0
  136. package/dist/tests/terminalProbeAuth.test.d.ts +1 -0
  137. package/dist/tests/terminalProbeAuth.test.js +79 -0
  138. package/dist/tests/websocket-transport.test.cjs +31 -0
  139. package/dist/tests/websocket-transport.test.d.ts +1 -0
  140. package/dist/tests/websocket-transport.test.js +25 -0
  141. package/dist/tools/fal/runtime.cjs +103 -0
  142. package/dist/tools/fal/runtime.d.ts +10 -0
  143. package/dist/tools/fal/runtime.js +60 -0
  144. package/dist/tools/fal/summary.cjs +78 -0
  145. package/dist/tools/fal/summary.d.ts +22 -0
  146. package/dist/tools/fal/summary.js +41 -0
  147. package/dist/tools/mcp-fal-ai.cjs +1041 -0
  148. package/dist/tools/mcp-fal-ai.d.ts +1 -0
  149. package/dist/tools/mcp-fal-ai.js +1025 -0
  150. package/dist/types/mcp.cjs +2 -0
  151. package/dist/types/mcp.d.ts +8 -0
  152. package/dist/types/mcp.js +3 -1
  153. package/dist/webui/assets/index-BW9nM0J2.css +11 -0
  154. package/dist/webui/assets/index-C8-oboEC.js +278 -0
  155. package/dist/webui/index.html +2 -2
  156. package/extensions/wingman-browser-extension/README.md +27 -0
  157. package/extensions/wingman-browser-extension/background.js +416 -0
  158. package/extensions/wingman-browser-extension/manifest.json +19 -0
  159. package/extensions/wingman-browser-extension/options.html +156 -0
  160. package/extensions/wingman-browser-extension/options.js +106 -0
  161. package/package.json +18 -13
  162. package/{.wingman → templates}/agents/README.md +2 -1
  163. package/{.wingman → templates}/agents/coding/agent.md +5 -1
  164. package/{.wingman → templates}/agents/coding-v2/agent.md +58 -1
  165. package/templates/agents/game-dev/agent.md +101 -0
  166. package/templates/agents/game-dev/art-generation.md +38 -0
  167. package/templates/agents/game-dev/asset-refinement.md +17 -0
  168. package/templates/agents/game-dev/planning-idea.md +17 -0
  169. package/templates/agents/game-dev/ui-specialist.md +17 -0
  170. package/templates/agents/main/agent.md +29 -0
  171. package/{.wingman → templates}/agents/researcher/agent.md +9 -0
  172. package/{.wingman → templates}/agents/stock-trader/agent.md +1 -0
  173. package/.wingman/agents/main/agent.md +0 -22
  174. package/dist/webui/assets/index-C7EuTbnE.js +0 -270
  175. package/dist/webui/assets/index-DVWQluit.css +0 -11
  176. /package/{.wingman → templates}/agents/coding-v2/implementor.md +0 -0
  177. /package/{.wingman → templates}/agents/stock-trader/chain-curator.md +0 -0
  178. /package/{.wingman → templates}/agents/stock-trader/goal-translator.md +0 -0
  179. /package/{.wingman → templates}/agents/stock-trader/guardrails-veto.md +0 -0
  180. /package/{.wingman → templates}/agents/stock-trader/path-planner.md +0 -0
  181. /package/{.wingman → templates}/agents/stock-trader/regime-analyst.md +0 -0
  182. /package/{.wingman → templates}/agents/stock-trader/risk.md +0 -0
  183. /package/{.wingman → templates}/agents/stock-trader/selection.md +0 -0
  184. /package/{.wingman → templates}/agents/stock-trader/strategy-composer.md +0 -0
@@ -0,0 +1,132 @@
1
+ import { existsSync, mkdirSync, mkdtempSync, rmSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join, normalize } from "node:path";
4
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
5
+ import { handleFsApi } from "../gateway/http/fs.js";
6
+ describe("fs API", ()=>{
7
+ let rootDir;
8
+ let extraDir;
9
+ beforeEach(()=>{
10
+ rootDir = mkdtempSync(join(tmpdir(), "wingman-fs-api-"));
11
+ extraDir = null;
12
+ });
13
+ afterEach(()=>{
14
+ rmSync(rootDir, {
15
+ recursive: true,
16
+ force: true
17
+ });
18
+ if (extraDir) rmSync(extraDir, {
19
+ recursive: true,
20
+ force: true
21
+ });
22
+ });
23
+ const createCtx = ()=>({
24
+ resolveFsRoots: ()=>[
25
+ rootDir
26
+ ],
27
+ resolveFsPath: (path)=>normalize(path),
28
+ isPathWithinRoots: (targetPath, roots)=>{
29
+ const resolved = normalize(targetPath);
30
+ return roots.some((root)=>{
31
+ const normalizedRoot = normalize(root);
32
+ return resolved === normalizedRoot || resolved.startsWith(`${normalizedRoot}/`) || resolved.startsWith(`${normalizedRoot}\\`);
33
+ });
34
+ }
35
+ });
36
+ it("creates a folder inside allowed roots", async ()=>{
37
+ const parent = join(rootDir, "parent");
38
+ mkdirSync(parent, {
39
+ recursive: true
40
+ });
41
+ const req = new Request("http://localhost/api/fs/mkdir", {
42
+ method: "POST",
43
+ headers: {
44
+ "Content-Type": "application/json"
45
+ },
46
+ body: JSON.stringify({
47
+ path: parent,
48
+ name: "new-folder"
49
+ })
50
+ });
51
+ const res = await handleFsApi(createCtx(), req, new URL(req.url));
52
+ expect(res).not.toBeNull();
53
+ expect(res?.ok).toBe(true);
54
+ const payload = await res?.json();
55
+ expect(payload.path).toBe(normalize(join(parent, "new-folder")));
56
+ expect(existsSync(payload.path)).toBe(true);
57
+ });
58
+ it("rejects invalid folder names", async ()=>{
59
+ const parent = join(rootDir, "parent");
60
+ mkdirSync(parent, {
61
+ recursive: true
62
+ });
63
+ const req = new Request("http://localhost/api/fs/mkdir", {
64
+ method: "POST",
65
+ headers: {
66
+ "Content-Type": "application/json"
67
+ },
68
+ body: JSON.stringify({
69
+ path: parent,
70
+ name: "bad/name"
71
+ })
72
+ });
73
+ const res = await handleFsApi(createCtx(), req, new URL(req.url));
74
+ expect(res).not.toBeNull();
75
+ expect(res?.status).toBe(400);
76
+ expect(await res?.text()).toBe("invalid folder name");
77
+ });
78
+ it("rejects paths outside allowed roots", async ()=>{
79
+ extraDir = mkdtempSync(join(tmpdir(), "wingman-fs-outside-"));
80
+ const req = new Request("http://localhost/api/fs/mkdir", {
81
+ method: "POST",
82
+ headers: {
83
+ "Content-Type": "application/json"
84
+ },
85
+ body: JSON.stringify({
86
+ path: extraDir,
87
+ name: "new-folder"
88
+ })
89
+ });
90
+ const res = await handleFsApi(createCtx(), req, new URL(req.url));
91
+ expect(res).not.toBeNull();
92
+ expect(res?.status).toBe(403);
93
+ expect(await res?.text()).toBe("path not allowed");
94
+ });
95
+ it("returns 409 when the target folder already exists", async ()=>{
96
+ const parent = join(rootDir, "parent");
97
+ const existing = join(parent, "existing");
98
+ mkdirSync(existing, {
99
+ recursive: true
100
+ });
101
+ const req = new Request("http://localhost/api/fs/mkdir", {
102
+ method: "POST",
103
+ headers: {
104
+ "Content-Type": "application/json"
105
+ },
106
+ body: JSON.stringify({
107
+ path: parent,
108
+ name: "existing"
109
+ })
110
+ });
111
+ const res = await handleFsApi(createCtx(), req, new URL(req.url));
112
+ expect(res).not.toBeNull();
113
+ expect(res?.status).toBe(409);
114
+ expect(await res?.text()).toBe("path already exists");
115
+ });
116
+ it("rejects non-string path and folder name values", async ()=>{
117
+ const req = new Request("http://localhost/api/fs/mkdir", {
118
+ method: "POST",
119
+ headers: {
120
+ "Content-Type": "application/json"
121
+ },
122
+ body: JSON.stringify({
123
+ path: 123,
124
+ name: 456
125
+ })
126
+ });
127
+ const res = await handleFsApi(createCtx(), req, new URL(req.url));
128
+ expect(res).not.toBeNull();
129
+ expect(res?.status).toBe(400);
130
+ expect(await res?.text()).toBe("path required");
131
+ });
132
+ });
@@ -0,0 +1,150 @@
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 gateway_cjs_namespaceObject = require("../cli/commands/gateway.cjs");
8
+ function _define_property(obj, key, value) {
9
+ if (key in obj) Object.defineProperty(obj, key, {
10
+ value: value,
11
+ enumerable: true,
12
+ configurable: true,
13
+ writable: true
14
+ });
15
+ else obj[key] = value;
16
+ return obj;
17
+ }
18
+ const daemonStartMock = external_vitest_namespaceObject.vi.fn(async (_config)=>{});
19
+ const daemonStopMock = external_vitest_namespaceObject.vi.fn(async ()=>{});
20
+ const daemonRestartMock = external_vitest_namespaceObject.vi.fn(async ()=>{});
21
+ const daemonGetStatusMock = external_vitest_namespaceObject.vi.fn(()=>({
22
+ running: false
23
+ }));
24
+ const daemonGetLogFileMock = external_vitest_namespaceObject.vi.fn(()=>"/tmp/wingman-gateway.log");
25
+ const daemonGetPidFileMock = external_vitest_namespaceObject.vi.fn(()=>"/tmp/wingman-gateway.pid");
26
+ const daemonGetConfigFileMock = external_vitest_namespaceObject.vi.fn(()=>"/tmp/wingman-gateway.json");
27
+ let serverStartShouldReject = false;
28
+ const createdServerConfigs = [];
29
+ const serverStartMock = external_vitest_namespaceObject.vi.fn(async ()=>{
30
+ if (serverStartShouldReject) throw new Error("synthetic gateway run stop");
31
+ });
32
+ const serverStopMock = external_vitest_namespaceObject.vi.fn(async ()=>{});
33
+ const loadConfigMock = external_vitest_namespaceObject.vi.fn(()=>({
34
+ gateway: {
35
+ host: "127.0.0.1",
36
+ port: 18789,
37
+ auth: {
38
+ mode: "none"
39
+ }
40
+ }
41
+ }));
42
+ external_vitest_namespaceObject.vi.mock("../gateway/index.js", ()=>({
43
+ GatewayDaemon: class {
44
+ constructor(){
45
+ _define_property(this, "start", daemonStartMock);
46
+ _define_property(this, "stop", daemonStopMock);
47
+ _define_property(this, "restart", daemonRestartMock);
48
+ _define_property(this, "getStatus", daemonGetStatusMock);
49
+ _define_property(this, "getLogFile", daemonGetLogFileMock);
50
+ _define_property(this, "getPidFile", daemonGetPidFileMock);
51
+ _define_property(this, "getConfigFile", daemonGetConfigFileMock);
52
+ }
53
+ },
54
+ GatewayServer: class {
55
+ constructor(config){
56
+ _define_property(this, "start", serverStartMock);
57
+ _define_property(this, "stop", serverStopMock);
58
+ createdServerConfigs.push(config);
59
+ }
60
+ },
61
+ GatewayClient: class {
62
+ }
63
+ }));
64
+ external_vitest_namespaceObject.vi.mock("../cli/config/loader.js", ()=>({
65
+ WingmanConfigLoader: class {
66
+ constructor(){
67
+ _define_property(this, "loadConfig", loadConfigMock);
68
+ }
69
+ }
70
+ }));
71
+ (0, external_vitest_namespaceObject.describe)("gateway command workspace handling", ()=>{
72
+ let tempRoot;
73
+ let consoleLogSpy;
74
+ let consoleErrorSpy;
75
+ let processExitSpy;
76
+ const originalGatewayConfigEnv = process.env.WINGMAN_GATEWAY_CONFIG;
77
+ (0, external_vitest_namespaceObject.beforeEach)(()=>{
78
+ tempRoot = (0, external_node_fs_namespaceObject.mkdtempSync)((0, external_node_path_namespaceObject.join)((0, external_node_os_namespaceObject.tmpdir)(), "wingman-gateway-command-"));
79
+ serverStartShouldReject = false;
80
+ createdServerConfigs.length = 0;
81
+ daemonStartMock.mockClear();
82
+ serverStartMock.mockClear();
83
+ loadConfigMock.mockClear();
84
+ consoleLogSpy = external_vitest_namespaceObject.vi.spyOn(console, "log").mockImplementation(()=>{});
85
+ consoleErrorSpy = external_vitest_namespaceObject.vi.spyOn(console, "error").mockImplementation(()=>{});
86
+ processExitSpy = external_vitest_namespaceObject.vi.spyOn(process, "exit").mockImplementation((code)=>{
87
+ throw new Error(`process.exit(${code ?? "undefined"})`);
88
+ });
89
+ delete process.env.WINGMAN_GATEWAY_CONFIG;
90
+ });
91
+ (0, external_vitest_namespaceObject.afterEach)(()=>{
92
+ consoleLogSpy.mockRestore();
93
+ consoleErrorSpy.mockRestore();
94
+ processExitSpy.mockRestore();
95
+ if (originalGatewayConfigEnv) process.env.WINGMAN_GATEWAY_CONFIG = originalGatewayConfigEnv;
96
+ else delete process.env.WINGMAN_GATEWAY_CONFIG;
97
+ if ((0, external_node_fs_namespaceObject.existsSync)(tempRoot)) (0, external_node_fs_namespaceObject.rmSync)(tempRoot, {
98
+ recursive: true,
99
+ force: true
100
+ });
101
+ });
102
+ (0, external_vitest_namespaceObject.it)("passes workspace/configDir into daemon config on gateway start", async ()=>{
103
+ const workspace = (0, external_node_path_namespaceObject.join)(tempRoot, "workspace");
104
+ const configDir = ".wingman-dev";
105
+ await (0, gateway_cjs_namespaceObject.executeGatewayCommand)({
106
+ subcommand: "start",
107
+ args: [],
108
+ options: {}
109
+ }, {
110
+ workspace,
111
+ configDir
112
+ });
113
+ (0, external_vitest_namespaceObject.expect)(daemonStartMock).toHaveBeenCalledTimes(1);
114
+ (0, external_vitest_namespaceObject.expect)(daemonStartMock).toHaveBeenCalledWith(external_vitest_namespaceObject.expect.objectContaining({
115
+ workspace,
116
+ configDir
117
+ }));
118
+ });
119
+ (0, external_vitest_namespaceObject.it)("fills missing workspace/configDir when running from daemon config", async ()=>{
120
+ const workspace = (0, external_node_path_namespaceObject.join)(tempRoot, "workspace");
121
+ const configDir = ".wingman-dev";
122
+ const daemonConfigPath = (0, external_node_path_namespaceObject.join)(tempRoot, "gateway-daemon.json");
123
+ (0, external_node_fs_namespaceObject.writeFileSync)(daemonConfigPath, JSON.stringify({
124
+ host: "127.0.0.1",
125
+ port: 18789,
126
+ auth: {
127
+ mode: "none"
128
+ }
129
+ }));
130
+ process.env.WINGMAN_GATEWAY_CONFIG = daemonConfigPath;
131
+ serverStartShouldReject = true;
132
+ await (0, external_vitest_namespaceObject.expect)((0, gateway_cjs_namespaceObject.executeGatewayCommand)({
133
+ subcommand: "run",
134
+ args: [],
135
+ options: {
136
+ daemon: true
137
+ }
138
+ }, {
139
+ workspace,
140
+ configDir
141
+ })).rejects.toThrow("process.exit(1)");
142
+ (0, external_vitest_namespaceObject.expect)(createdServerConfigs).toHaveLength(1);
143
+ (0, external_vitest_namespaceObject.expect)(createdServerConfigs[0]?.workspace).toBe(workspace);
144
+ (0, external_vitest_namespaceObject.expect)(createdServerConfigs[0]?.configDir).toBe(configDir);
145
+ });
146
+ });
147
+ for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
148
+ Object.defineProperty(exports, '__esModule', {
149
+ value: true
150
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,144 @@
1
+ import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
+ import { executeGatewayCommand } from "../cli/commands/gateway.js";
6
+ function _define_property(obj, key, value) {
7
+ if (key in obj) Object.defineProperty(obj, key, {
8
+ value: value,
9
+ enumerable: true,
10
+ configurable: true,
11
+ writable: true
12
+ });
13
+ else obj[key] = value;
14
+ return obj;
15
+ }
16
+ const daemonStartMock = vi.fn(async (_config)=>{});
17
+ const daemonStopMock = vi.fn(async ()=>{});
18
+ const daemonRestartMock = vi.fn(async ()=>{});
19
+ const daemonGetStatusMock = vi.fn(()=>({
20
+ running: false
21
+ }));
22
+ const daemonGetLogFileMock = vi.fn(()=>"/tmp/wingman-gateway.log");
23
+ const daemonGetPidFileMock = vi.fn(()=>"/tmp/wingman-gateway.pid");
24
+ const daemonGetConfigFileMock = vi.fn(()=>"/tmp/wingman-gateway.json");
25
+ let serverStartShouldReject = false;
26
+ const createdServerConfigs = [];
27
+ const serverStartMock = vi.fn(async ()=>{
28
+ if (serverStartShouldReject) throw new Error("synthetic gateway run stop");
29
+ });
30
+ const serverStopMock = vi.fn(async ()=>{});
31
+ const loadConfigMock = vi.fn(()=>({
32
+ gateway: {
33
+ host: "127.0.0.1",
34
+ port: 18789,
35
+ auth: {
36
+ mode: "none"
37
+ }
38
+ }
39
+ }));
40
+ vi.mock("../gateway/index.js", ()=>({
41
+ GatewayDaemon: class {
42
+ constructor(){
43
+ _define_property(this, "start", daemonStartMock);
44
+ _define_property(this, "stop", daemonStopMock);
45
+ _define_property(this, "restart", daemonRestartMock);
46
+ _define_property(this, "getStatus", daemonGetStatusMock);
47
+ _define_property(this, "getLogFile", daemonGetLogFileMock);
48
+ _define_property(this, "getPidFile", daemonGetPidFileMock);
49
+ _define_property(this, "getConfigFile", daemonGetConfigFileMock);
50
+ }
51
+ },
52
+ GatewayServer: class {
53
+ constructor(config){
54
+ _define_property(this, "start", serverStartMock);
55
+ _define_property(this, "stop", serverStopMock);
56
+ createdServerConfigs.push(config);
57
+ }
58
+ },
59
+ GatewayClient: class {
60
+ }
61
+ }));
62
+ vi.mock("../cli/config/loader.js", ()=>({
63
+ WingmanConfigLoader: class {
64
+ constructor(){
65
+ _define_property(this, "loadConfig", loadConfigMock);
66
+ }
67
+ }
68
+ }));
69
+ describe("gateway command workspace handling", ()=>{
70
+ let tempRoot;
71
+ let consoleLogSpy;
72
+ let consoleErrorSpy;
73
+ let processExitSpy;
74
+ const originalGatewayConfigEnv = process.env.WINGMAN_GATEWAY_CONFIG;
75
+ beforeEach(()=>{
76
+ tempRoot = mkdtempSync(join(tmpdir(), "wingman-gateway-command-"));
77
+ serverStartShouldReject = false;
78
+ createdServerConfigs.length = 0;
79
+ daemonStartMock.mockClear();
80
+ serverStartMock.mockClear();
81
+ loadConfigMock.mockClear();
82
+ consoleLogSpy = vi.spyOn(console, "log").mockImplementation(()=>{});
83
+ consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(()=>{});
84
+ processExitSpy = vi.spyOn(process, "exit").mockImplementation((code)=>{
85
+ throw new Error(`process.exit(${code ?? "undefined"})`);
86
+ });
87
+ delete process.env.WINGMAN_GATEWAY_CONFIG;
88
+ });
89
+ afterEach(()=>{
90
+ consoleLogSpy.mockRestore();
91
+ consoleErrorSpy.mockRestore();
92
+ processExitSpy.mockRestore();
93
+ if (originalGatewayConfigEnv) process.env.WINGMAN_GATEWAY_CONFIG = originalGatewayConfigEnv;
94
+ else delete process.env.WINGMAN_GATEWAY_CONFIG;
95
+ if (existsSync(tempRoot)) rmSync(tempRoot, {
96
+ recursive: true,
97
+ force: true
98
+ });
99
+ });
100
+ it("passes workspace/configDir into daemon config on gateway start", async ()=>{
101
+ const workspace = join(tempRoot, "workspace");
102
+ const configDir = ".wingman-dev";
103
+ await executeGatewayCommand({
104
+ subcommand: "start",
105
+ args: [],
106
+ options: {}
107
+ }, {
108
+ workspace,
109
+ configDir
110
+ });
111
+ expect(daemonStartMock).toHaveBeenCalledTimes(1);
112
+ expect(daemonStartMock).toHaveBeenCalledWith(expect.objectContaining({
113
+ workspace,
114
+ configDir
115
+ }));
116
+ });
117
+ it("fills missing workspace/configDir when running from daemon config", async ()=>{
118
+ const workspace = join(tempRoot, "workspace");
119
+ const configDir = ".wingman-dev";
120
+ const daemonConfigPath = join(tempRoot, "gateway-daemon.json");
121
+ writeFileSync(daemonConfigPath, JSON.stringify({
122
+ host: "127.0.0.1",
123
+ port: 18789,
124
+ auth: {
125
+ mode: "none"
126
+ }
127
+ }));
128
+ process.env.WINGMAN_GATEWAY_CONFIG = daemonConfigPath;
129
+ serverStartShouldReject = true;
130
+ await expect(executeGatewayCommand({
131
+ subcommand: "run",
132
+ args: [],
133
+ options: {
134
+ daemon: true
135
+ }
136
+ }, {
137
+ workspace,
138
+ configDir
139
+ })).rejects.toThrow("process.exit(1)");
140
+ expect(createdServerConfigs).toHaveLength(1);
141
+ expect(createdServerConfigs[0]?.workspace).toBe(workspace);
142
+ expect(createdServerConfigs[0]?.configDir).toBe(configDir);
143
+ });
144
+ });
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __webpack_exports__ = {};
3
+ const external_vitest_namespaceObject = require("vitest");
4
+ const server_cjs_namespaceObject = require("../gateway/server.cjs");
5
+ (0, external_vitest_namespaceObject.describe)("gateway request execution overrides", ()=>{
6
+ (0, external_vitest_namespaceObject.it)("accepts absolute execution workspace overrides", ()=>{
7
+ const value = (0, server_cjs_namespaceObject.resolveExecutionWorkspaceOverride)({
8
+ execution: {
9
+ workspace: " /tmp/wingman/workspace "
10
+ }
11
+ });
12
+ (0, external_vitest_namespaceObject.expect)(value).toBe("/tmp/wingman/workspace");
13
+ });
14
+ (0, external_vitest_namespaceObject.it)("rejects relative execution workspace overrides", ()=>{
15
+ const value = (0, server_cjs_namespaceObject.resolveExecutionWorkspaceOverride)({
16
+ execution: {
17
+ workspace: "./apps/wingman"
18
+ }
19
+ });
20
+ (0, external_vitest_namespaceObject.expect)(value).toBeNull();
21
+ });
22
+ (0, external_vitest_namespaceObject.it)("parses config-dir execution override when present", ()=>{
23
+ const value = (0, server_cjs_namespaceObject.resolveExecutionConfigDirOverride)({
24
+ execution: {
25
+ configDir: " .wingman-dev "
26
+ }
27
+ });
28
+ (0, external_vitest_namespaceObject.expect)(value).toBe(".wingman-dev");
29
+ });
30
+ (0, external_vitest_namespaceObject.it)("ignores empty config-dir execution override", ()=>{
31
+ const value = (0, server_cjs_namespaceObject.resolveExecutionConfigDirOverride)({
32
+ execution: {
33
+ configDir: " "
34
+ }
35
+ });
36
+ (0, external_vitest_namespaceObject.expect)(value).toBeNull();
37
+ });
38
+ });
39
+ for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
40
+ Object.defineProperty(exports, '__esModule', {
41
+ value: true
42
+ });
@@ -0,0 +1,36 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { resolveExecutionConfigDirOverride, resolveExecutionWorkspaceOverride } from "../gateway/server.js";
3
+ describe("gateway request execution overrides", ()=>{
4
+ it("accepts absolute execution workspace overrides", ()=>{
5
+ const value = resolveExecutionWorkspaceOverride({
6
+ execution: {
7
+ workspace: " /tmp/wingman/workspace "
8
+ }
9
+ });
10
+ expect(value).toBe("/tmp/wingman/workspace");
11
+ });
12
+ it("rejects relative execution workspace overrides", ()=>{
13
+ const value = resolveExecutionWorkspaceOverride({
14
+ execution: {
15
+ workspace: "./apps/wingman"
16
+ }
17
+ });
18
+ expect(value).toBeNull();
19
+ });
20
+ it("parses config-dir execution override when present", ()=>{
21
+ const value = resolveExecutionConfigDirOverride({
22
+ execution: {
23
+ configDir: " .wingman-dev "
24
+ }
25
+ });
26
+ expect(value).toBe(".wingman-dev");
27
+ });
28
+ it("ignores empty config-dir execution override", ()=>{
29
+ const value = resolveExecutionConfigDirOverride({
30
+ execution: {
31
+ configDir: " "
32
+ }
33
+ });
34
+ expect(value).toBeNull();
35
+ });
36
+ });