@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.
- package/README.md +9 -0
- package/dist/agent/config/agentConfig.cjs +12 -0
- package/dist/agent/config/agentConfig.d.ts +26 -0
- package/dist/agent/config/agentConfig.js +10 -1
- package/dist/agent/config/agentLoader.cjs +9 -0
- package/dist/agent/config/agentLoader.js +9 -0
- package/dist/agent/config/mcpClientManager.cjs +44 -10
- package/dist/agent/config/mcpClientManager.d.ts +6 -2
- package/dist/agent/config/mcpClientManager.js +44 -10
- package/dist/agent/config/toolRegistry.cjs +20 -1
- package/dist/agent/config/toolRegistry.d.ts +15 -0
- package/dist/agent/config/toolRegistry.js +20 -1
- package/dist/agent/tests/agentConfig.test.cjs +6 -1
- package/dist/agent/tests/agentConfig.test.js +6 -1
- package/dist/agent/tests/browserControlHelpers.test.cjs +35 -0
- package/dist/agent/tests/browserControlHelpers.test.d.ts +1 -0
- package/dist/agent/tests/browserControlHelpers.test.js +29 -0
- package/dist/agent/tests/browserControlTool.test.cjs +2117 -0
- package/dist/agent/tests/browserControlTool.test.d.ts +1 -0
- package/dist/agent/tests/browserControlTool.test.js +2111 -0
- package/dist/agent/tests/mcpClientManager.test.cjs +124 -0
- package/dist/agent/tests/mcpClientManager.test.d.ts +1 -0
- package/dist/agent/tests/mcpClientManager.test.js +118 -0
- package/dist/agent/tests/toolRegistry.test.cjs +6 -0
- package/dist/agent/tests/toolRegistry.test.js +6 -0
- package/dist/agent/tools/browser_control.cjs +1282 -0
- package/dist/agent/tools/browser_control.d.ts +478 -0
- package/dist/agent/tools/browser_control.js +1242 -0
- package/dist/agent/tools/command_execute.cjs +1 -1
- package/dist/agent/tools/command_execute.js +1 -1
- package/dist/cli/commands/agent.cjs +16 -2
- package/dist/cli/commands/agent.js +16 -2
- package/dist/cli/commands/browser.cjs +603 -0
- package/dist/cli/commands/browser.d.ts +13 -0
- package/dist/cli/commands/browser.js +566 -0
- package/dist/cli/commands/gateway.cjs +18 -7
- package/dist/cli/commands/gateway.d.ts +5 -1
- package/dist/cli/commands/gateway.js +18 -7
- package/dist/cli/commands/init.cjs +134 -45
- package/dist/cli/commands/init.js +134 -45
- package/dist/cli/commands/skill.cjs +3 -2
- package/dist/cli/commands/skill.js +3 -2
- package/dist/cli/config/loader.cjs +15 -0
- package/dist/cli/config/loader.js +15 -0
- package/dist/cli/config/schema.cjs +51 -2
- package/dist/cli/config/schema.d.ts +51 -0
- package/dist/cli/config/schema.js +44 -1
- package/dist/cli/core/agentInvoker.cjs +55 -66
- package/dist/cli/core/agentInvoker.d.ts +10 -13
- package/dist/cli/core/agentInvoker.js +42 -62
- package/dist/cli/core/imagePersistence.cjs +125 -0
- package/dist/cli/core/imagePersistence.d.ts +24 -0
- package/dist/cli/core/imagePersistence.js +85 -0
- package/dist/cli/core/sessionManager.cjs +297 -40
- package/dist/cli/core/sessionManager.d.ts +9 -0
- package/dist/cli/core/sessionManager.js +297 -40
- package/dist/cli/core/workspace.cjs +89 -0
- package/dist/cli/core/workspace.d.ts +1 -0
- package/dist/cli/core/workspace.js +55 -0
- package/dist/cli/index.cjs +53 -5
- package/dist/cli/index.js +53 -5
- package/dist/cli/types/browser.cjs +18 -0
- package/dist/cli/types/browser.d.ts +9 -0
- package/dist/cli/types/browser.js +0 -0
- package/dist/debug/terminalProbe.cjs +57 -0
- package/dist/debug/terminalProbe.d.ts +10 -0
- package/dist/debug/terminalProbe.js +20 -0
- package/dist/debug/terminalProbeAuth.cjs +140 -0
- package/dist/debug/terminalProbeAuth.d.ts +20 -0
- package/dist/debug/terminalProbeAuth.js +97 -0
- package/dist/gateway/browserRelayServer.cjs +338 -0
- package/dist/gateway/browserRelayServer.d.ts +38 -0
- package/dist/gateway/browserRelayServer.js +301 -0
- package/dist/gateway/http/agents.cjs +22 -0
- package/dist/gateway/http/agents.js +22 -0
- package/dist/gateway/http/fs.cjs +76 -0
- package/dist/gateway/http/fs.js +77 -1
- package/dist/gateway/http/sessions.cjs +25 -5
- package/dist/gateway/http/sessions.js +25 -5
- package/dist/gateway/server.cjs +155 -17
- package/dist/gateway/server.d.ts +6 -1
- package/dist/gateway/server.js +148 -16
- package/dist/gateway/transport/websocket.cjs +45 -10
- package/dist/gateway/transport/websocket.d.ts +1 -0
- package/dist/gateway/transport/websocket.js +41 -9
- package/dist/gateway/types.d.ts +4 -0
- package/dist/tests/agentInvokerSummarization.test.cjs +56 -37
- package/dist/tests/agentInvokerSummarization.test.js +58 -39
- package/dist/tests/agentInvokerWorkdir.test.cjs +50 -0
- package/dist/tests/agentInvokerWorkdir.test.js +52 -2
- package/dist/tests/agents-api.test.cjs +52 -0
- package/dist/tests/agents-api.test.js +53 -1
- package/dist/tests/browser-command.test.cjs +264 -0
- package/dist/tests/browser-command.test.d.ts +1 -0
- package/dist/tests/browser-command.test.js +258 -0
- package/dist/tests/browser-relay-server.test.cjs +20 -0
- package/dist/tests/browser-relay-server.test.d.ts +1 -0
- package/dist/tests/browser-relay-server.test.js +14 -0
- package/dist/tests/cli-config-loader.test.cjs +43 -0
- package/dist/tests/cli-config-loader.test.js +43 -0
- package/dist/tests/cli-init.test.cjs +61 -2
- package/dist/tests/cli-init.test.js +61 -2
- package/dist/tests/cli-workspace-root.test.cjs +114 -0
- package/dist/tests/cli-workspace-root.test.d.ts +1 -0
- package/dist/tests/cli-workspace-root.test.js +108 -0
- package/dist/tests/falRuntime.test.cjs +78 -0
- package/dist/tests/falRuntime.test.d.ts +1 -0
- package/dist/tests/falRuntime.test.js +72 -0
- package/dist/tests/falSummary.test.cjs +51 -0
- package/dist/tests/falSummary.test.d.ts +1 -0
- package/dist/tests/falSummary.test.js +45 -0
- package/dist/tests/fs-api.test.cjs +138 -0
- package/dist/tests/fs-api.test.d.ts +1 -0
- package/dist/tests/fs-api.test.js +132 -0
- package/dist/tests/gateway-command-workspace.test.cjs +150 -0
- package/dist/tests/gateway-command-workspace.test.d.ts +1 -0
- package/dist/tests/gateway-command-workspace.test.js +144 -0
- package/dist/tests/gateway-request-execution-overrides.test.cjs +42 -0
- package/dist/tests/gateway-request-execution-overrides.test.d.ts +1 -0
- package/dist/tests/gateway-request-execution-overrides.test.js +36 -0
- package/dist/tests/gateway.test.cjs +140 -1
- package/dist/tests/gateway.test.js +140 -1
- package/dist/tests/imagePersistence.test.cjs +143 -0
- package/dist/tests/imagePersistence.test.d.ts +1 -0
- package/dist/tests/imagePersistence.test.js +137 -0
- package/dist/tests/sessionMessageAttachments.test.cjs +30 -0
- package/dist/tests/sessionMessageAttachments.test.js +30 -0
- package/dist/tests/sessionStateMessages.test.cjs +126 -0
- package/dist/tests/sessionStateMessages.test.js +126 -0
- package/dist/tests/sessions-api.test.cjs +117 -3
- package/dist/tests/sessions-api.test.js +118 -4
- package/dist/tests/terminalProbe.test.cjs +45 -0
- package/dist/tests/terminalProbe.test.d.ts +1 -0
- package/dist/tests/terminalProbe.test.js +39 -0
- package/dist/tests/terminalProbeAuth.test.cjs +85 -0
- package/dist/tests/terminalProbeAuth.test.d.ts +1 -0
- package/dist/tests/terminalProbeAuth.test.js +79 -0
- package/dist/tests/websocket-transport.test.cjs +31 -0
- package/dist/tests/websocket-transport.test.d.ts +1 -0
- package/dist/tests/websocket-transport.test.js +25 -0
- package/dist/tools/fal/runtime.cjs +103 -0
- package/dist/tools/fal/runtime.d.ts +10 -0
- package/dist/tools/fal/runtime.js +60 -0
- package/dist/tools/fal/summary.cjs +78 -0
- package/dist/tools/fal/summary.d.ts +22 -0
- package/dist/tools/fal/summary.js +41 -0
- package/dist/tools/mcp-fal-ai.cjs +1041 -0
- package/dist/tools/mcp-fal-ai.d.ts +1 -0
- package/dist/tools/mcp-fal-ai.js +1025 -0
- package/dist/types/mcp.cjs +2 -0
- package/dist/types/mcp.d.ts +8 -0
- package/dist/types/mcp.js +3 -1
- package/dist/webui/assets/index-BW9nM0J2.css +11 -0
- package/dist/webui/assets/index-C8-oboEC.js +278 -0
- package/dist/webui/index.html +2 -2
- package/extensions/wingman-browser-extension/README.md +27 -0
- package/extensions/wingman-browser-extension/background.js +416 -0
- package/extensions/wingman-browser-extension/manifest.json +19 -0
- package/extensions/wingman-browser-extension/options.html +156 -0
- package/extensions/wingman-browser-extension/options.js +106 -0
- package/package.json +18 -13
- package/{.wingman → templates}/agents/README.md +2 -1
- package/{.wingman → templates}/agents/coding/agent.md +5 -1
- package/{.wingman → templates}/agents/coding-v2/agent.md +58 -1
- package/templates/agents/game-dev/agent.md +101 -0
- package/templates/agents/game-dev/art-generation.md +38 -0
- package/templates/agents/game-dev/asset-refinement.md +17 -0
- package/templates/agents/game-dev/planning-idea.md +17 -0
- package/templates/agents/game-dev/ui-specialist.md +17 -0
- package/templates/agents/main/agent.md +29 -0
- package/{.wingman → templates}/agents/researcher/agent.md +9 -0
- package/{.wingman → templates}/agents/stock-trader/agent.md +1 -0
- package/.wingman/agents/main/agent.md +0 -22
- package/dist/webui/assets/index-C7EuTbnE.js +0 -270
- package/dist/webui/assets/index-DVWQluit.css +0 -11
- /package/{.wingman → templates}/agents/coding-v2/implementor.md +0 -0
- /package/{.wingman → templates}/agents/stock-trader/chain-curator.md +0 -0
- /package/{.wingman → templates}/agents/stock-trader/goal-translator.md +0 -0
- /package/{.wingman → templates}/agents/stock-trader/guardrails-veto.md +0 -0
- /package/{.wingman → templates}/agents/stock-trader/path-planner.md +0 -0
- /package/{.wingman → templates}/agents/stock-trader/regime-analyst.md +0 -0
- /package/{.wingman → templates}/agents/stock-trader/risk.md +0 -0
- /package/{.wingman → templates}/agents/stock-trader/selection.md +0 -0
- /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 @@
|
|
|
1
|
+
export {};
|
|
@@ -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
|
+
});
|