@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
package/README.md CHANGED
@@ -74,6 +74,14 @@ npm install -g @wingman-ai/gateway
74
74
  wingman init
75
75
  ```
76
76
 
77
+ ### Re-sync Bundled Agent Templates
78
+
79
+ ```bash
80
+ wingman init --mode sync --only agents
81
+ wingman init --mode sync --only agents --agents main,coding
82
+ wingman init --mode sync --only agents --force
83
+ ```
84
+
77
85
  ### Start the Gateway
78
86
 
79
87
  ```bash
@@ -253,6 +261,7 @@ wingman gateway start --discovery tailscale --name "Work Gateway"
253
261
  - **Hooks** for pre/post tool automation.
254
262
  - **Skills** for reusable, domain-specific instruction sets.
255
263
  - **MCP tools** to connect external systems and custom integrations.
264
+ - **Bundled MCP servers** for finance (`bun run mcp:finance`) and FAL AI multimodal generation (`bun run mcp:fal-ai`).
256
265
 
257
266
  ## Development
258
267
 
@@ -24,6 +24,7 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
+ AgentBrowserTransportSchema: ()=>AgentBrowserTransportSchema,
27
28
  WingmanDirectory: ()=>WingmanDirectory,
28
29
  AgentConfigSchema: ()=>AgentConfigSchema,
29
30
  AvailableToolNames: ()=>AvailableToolNames,
@@ -38,6 +39,7 @@ const WingmanDirectory = ".wingman";
38
39
  const AvailableToolNames = external_zod_namespaceObject["enum"]([
39
40
  "internet_search",
40
41
  "web_crawler",
42
+ "browser_control",
41
43
  "command_execute",
42
44
  "background_terminal",
43
45
  "think",
@@ -56,6 +58,11 @@ const ReasoningEffortSchema = external_zod_namespaceObject.preprocess((value)=>{
56
58
  "medium",
57
59
  "high"
58
60
  ]));
61
+ const AgentBrowserTransportSchema = external_zod_namespaceObject["enum"]([
62
+ "auto",
63
+ "playwright",
64
+ "relay"
65
+ ]);
59
66
  const PromptRefinementSchema = external_zod_namespaceObject.preprocess((value)=>{
60
67
  if (void 0 === value) return;
61
68
  if ("boolean" == typeof value) return {
@@ -76,6 +83,9 @@ const BaseAgentConfigSchema = external_zod_namespaceObject.object({
76
83
  blockedCommands: external_zod_namespaceObject.array(external_zod_namespaceObject.string()).optional().describe("List of blocked commands for command_execute tool (e.g., ['rm', 'mv'])"),
77
84
  allowScriptExecution: external_zod_namespaceObject.boolean().optional().default(true).describe("Whether to allow script execution in command_execute tool"),
78
85
  commandTimeout: external_zod_namespaceObject.number().optional().default(300000).describe("Command execution timeout in milliseconds (default: 300000)"),
86
+ browserProfile: external_zod_namespaceObject.string().min(1).optional().describe("Optional named browser profile ID for persistent browser_control sessions"),
87
+ browserTransport: AgentBrowserTransportSchema.optional().describe('Optional browser_control transport preference ("auto", "playwright", or "relay")'),
88
+ browserExtensions: external_zod_namespaceObject.array(external_zod_namespaceObject.string().min(1)).optional().describe("Optional extension IDs to load for browser_control sessions (maps from wingman.config browser.extensions)"),
79
89
  toolHooks: types_cjs_namespaceObject.HooksConfigSchema.optional().describe("Agent-specific tool hooks configuration"),
80
90
  mcp: mcp_cjs_namespaceObject.MCPServersConfigSchema.optional().describe("Agent-specific MCP server configurations"),
81
91
  mcpUseGlobal: external_zod_namespaceObject.boolean().optional().default(false).describe("Whether this agent should also load global MCP servers from wingman.config.json"),
@@ -135,12 +145,14 @@ function validateAgentConfig(config) {
135
145
  };
136
146
  }
137
147
  }
148
+ exports.AgentBrowserTransportSchema = __webpack_exports__.AgentBrowserTransportSchema;
138
149
  exports.AgentConfigSchema = __webpack_exports__.AgentConfigSchema;
139
150
  exports.AvailableToolNames = __webpack_exports__.AvailableToolNames;
140
151
  exports.ReasoningEffortSchema = __webpack_exports__.ReasoningEffortSchema;
141
152
  exports.WingmanDirectory = __webpack_exports__.WingmanDirectory;
142
153
  exports.validateAgentConfig = __webpack_exports__.validateAgentConfig;
143
154
  for(var __rspack_i in __webpack_exports__)if (-1 === [
155
+ "AgentBrowserTransportSchema",
144
156
  "AgentConfigSchema",
145
157
  "AvailableToolNames",
146
158
  "ReasoningEffortSchema",
@@ -6,6 +6,7 @@ export declare const WingmanDirectory = ".wingman";
6
6
  export declare const AvailableToolNames: z.ZodEnum<{
7
7
  internet_search: "internet_search";
8
8
  web_crawler: "web_crawler";
9
+ browser_control: "browser_control";
9
10
  command_execute: "command_execute";
10
11
  background_terminal: "background_terminal";
11
12
  think: "think";
@@ -23,6 +24,11 @@ export declare const ReasoningEffortSchema: z.ZodPipe<z.ZodTransform<unknown, un
23
24
  high: "high";
24
25
  }>>;
25
26
  export type ReasoningEffort = z.infer<typeof ReasoningEffortSchema>;
27
+ export declare const AgentBrowserTransportSchema: z.ZodEnum<{
28
+ auto: "auto";
29
+ playwright: "playwright";
30
+ relay: "relay";
31
+ }>;
26
32
  declare const PromptRefinementSchema: z.ZodPipe<z.ZodTransform<{} | null | undefined, unknown>, z.ZodObject<{
27
33
  enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
28
34
  instructionsPath: z.ZodOptional<z.ZodString>;
@@ -35,6 +41,7 @@ export declare const AgentConfigSchema: z.ZodObject<{
35
41
  tools: z.ZodOptional<z.ZodArray<z.ZodEnum<{
36
42
  internet_search: "internet_search";
37
43
  web_crawler: "web_crawler";
44
+ browser_control: "browser_control";
38
45
  command_execute: "command_execute";
39
46
  background_terminal: "background_terminal";
40
47
  think: "think";
@@ -54,6 +61,13 @@ export declare const AgentConfigSchema: z.ZodObject<{
54
61
  blockedCommands: z.ZodOptional<z.ZodArray<z.ZodString>>;
55
62
  allowScriptExecution: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
56
63
  commandTimeout: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
64
+ browserProfile: z.ZodOptional<z.ZodString>;
65
+ browserTransport: z.ZodOptional<z.ZodEnum<{
66
+ auto: "auto";
67
+ playwright: "playwright";
68
+ relay: "relay";
69
+ }>>;
70
+ browserExtensions: z.ZodOptional<z.ZodArray<z.ZodString>>;
57
71
  toolHooks: z.ZodOptional<z.ZodObject<{
58
72
  PreToolUse: z.ZodOptional<z.ZodArray<z.ZodObject<{
59
73
  matcher: z.ZodOptional<z.ZodString>;
@@ -83,12 +97,14 @@ export declare const AgentConfigSchema: z.ZodObject<{
83
97
  servers: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
84
98
  name: z.ZodString;
85
99
  transport: z.ZodLiteral<"stdio">;
100
+ defaultToolTimeout: z.ZodOptional<z.ZodNumber>;
86
101
  command: z.ZodString;
87
102
  args: z.ZodOptional<z.ZodArray<z.ZodString>>;
88
103
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
89
104
  }, z.core.$strip>, z.ZodObject<{
90
105
  name: z.ZodString;
91
106
  transport: z.ZodLiteral<"sse">;
107
+ defaultToolTimeout: z.ZodOptional<z.ZodNumber>;
92
108
  url: z.ZodString;
93
109
  headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
94
110
  }, z.core.$strip>]>>>;
@@ -129,6 +145,7 @@ export declare const AgentConfigSchema: z.ZodObject<{
129
145
  tools: z.ZodOptional<z.ZodArray<z.ZodEnum<{
130
146
  internet_search: "internet_search";
131
147
  web_crawler: "web_crawler";
148
+ browser_control: "browser_control";
132
149
  command_execute: "command_execute";
133
150
  background_terminal: "background_terminal";
134
151
  think: "think";
@@ -148,6 +165,13 @@ export declare const AgentConfigSchema: z.ZodObject<{
148
165
  blockedCommands: z.ZodOptional<z.ZodArray<z.ZodString>>;
149
166
  allowScriptExecution: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
150
167
  commandTimeout: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
168
+ browserProfile: z.ZodOptional<z.ZodString>;
169
+ browserTransport: z.ZodOptional<z.ZodEnum<{
170
+ auto: "auto";
171
+ playwright: "playwright";
172
+ relay: "relay";
173
+ }>>;
174
+ browserExtensions: z.ZodOptional<z.ZodArray<z.ZodString>>;
151
175
  toolHooks: z.ZodOptional<z.ZodObject<{
152
176
  PreToolUse: z.ZodOptional<z.ZodArray<z.ZodObject<{
153
177
  matcher: z.ZodOptional<z.ZodString>;
@@ -177,12 +201,14 @@ export declare const AgentConfigSchema: z.ZodObject<{
177
201
  servers: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
178
202
  name: z.ZodString;
179
203
  transport: z.ZodLiteral<"stdio">;
204
+ defaultToolTimeout: z.ZodOptional<z.ZodNumber>;
180
205
  command: z.ZodString;
181
206
  args: z.ZodOptional<z.ZodArray<z.ZodString>>;
182
207
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
183
208
  }, z.core.$strip>, z.ZodObject<{
184
209
  name: z.ZodString;
185
210
  transport: z.ZodLiteral<"sse">;
211
+ defaultToolTimeout: z.ZodOptional<z.ZodNumber>;
186
212
  url: z.ZodString;
187
213
  headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
188
214
  }, z.core.$strip>]>>>;
@@ -6,6 +6,7 @@ const WingmanDirectory = ".wingman";
6
6
  const AvailableToolNames = external_zod_enum([
7
7
  "internet_search",
8
8
  "web_crawler",
9
+ "browser_control",
9
10
  "command_execute",
10
11
  "background_terminal",
11
12
  "think",
@@ -24,6 +25,11 @@ const ReasoningEffortSchema = preprocess((value)=>{
24
25
  "medium",
25
26
  "high"
26
27
  ]));
28
+ const AgentBrowserTransportSchema = external_zod_enum([
29
+ "auto",
30
+ "playwright",
31
+ "relay"
32
+ ]);
27
33
  const PromptRefinementSchema = preprocess((value)=>{
28
34
  if (void 0 === value) return;
29
35
  if ("boolean" == typeof value) return {
@@ -44,6 +50,9 @@ const BaseAgentConfigSchema = object({
44
50
  blockedCommands: array(string()).optional().describe("List of blocked commands for command_execute tool (e.g., ['rm', 'mv'])"),
45
51
  allowScriptExecution: external_zod_boolean().optional().default(true).describe("Whether to allow script execution in command_execute tool"),
46
52
  commandTimeout: number().optional().default(300000).describe("Command execution timeout in milliseconds (default: 300000)"),
53
+ browserProfile: string().min(1).optional().describe("Optional named browser profile ID for persistent browser_control sessions"),
54
+ browserTransport: AgentBrowserTransportSchema.optional().describe('Optional browser_control transport preference ("auto", "playwright", or "relay")'),
55
+ browserExtensions: array(string().min(1)).optional().describe("Optional extension IDs to load for browser_control sessions (maps from wingman.config browser.extensions)"),
47
56
  toolHooks: HooksConfigSchema.optional().describe("Agent-specific tool hooks configuration"),
48
57
  mcp: MCPServersConfigSchema.optional().describe("Agent-specific MCP server configurations"),
49
58
  mcpUseGlobal: external_zod_boolean().optional().default(false).describe("Whether this agent should also load global MCP servers from wingman.config.json"),
@@ -103,4 +112,4 @@ function validateAgentConfig(config) {
103
112
  };
104
113
  }
105
114
  }
106
- export { AgentConfigSchema, AvailableToolNames, ReasoningEffortSchema, WingmanDirectory, validateAgentConfig };
115
+ export { AgentBrowserTransportSchema, AgentConfigSchema, AvailableToolNames, ReasoningEffortSchema, WingmanDirectory, validateAgentConfig };
@@ -228,6 +228,15 @@ class AgentLoader {
228
228
  blockedCommands: source.blockedCommands,
229
229
  allowScriptExecution: source.allowScriptExecution,
230
230
  timeout: source.commandTimeout,
231
+ browserProfile: source.browserProfile || this.wingmanConfig?.browser?.defaultProfile,
232
+ browserTransport: source.browserTransport || this.wingmanConfig?.browser?.transport,
233
+ browserProfilesDirectory: this.wingmanConfig?.browser?.profilesDir,
234
+ browserProfiles: this.wingmanConfig?.browser?.profiles,
235
+ browserExtensions: source.browserExtensions,
236
+ browserExtensionsDirectory: this.wingmanConfig?.browser?.extensionsDir,
237
+ browserExtensionsById: this.wingmanConfig?.browser?.extensions,
238
+ browserDefaultExtensions: this.wingmanConfig?.browser?.defaultExtensions,
239
+ browserRelay: this.wingmanConfig?.browser?.relay,
231
240
  searchConfig: this.wingmanConfig?.search,
232
241
  mcpConfigs,
233
242
  skillsDirectory,
@@ -200,6 +200,15 @@ class AgentLoader {
200
200
  blockedCommands: source.blockedCommands,
201
201
  allowScriptExecution: source.allowScriptExecution,
202
202
  timeout: source.commandTimeout,
203
+ browserProfile: source.browserProfile || this.wingmanConfig?.browser?.defaultProfile,
204
+ browserTransport: source.browserTransport || this.wingmanConfig?.browser?.transport,
205
+ browserProfilesDirectory: this.wingmanConfig?.browser?.profilesDir,
206
+ browserProfiles: this.wingmanConfig?.browser?.profiles,
207
+ browserExtensions: source.browserExtensions,
208
+ browserExtensionsDirectory: this.wingmanConfig?.browser?.extensionsDir,
209
+ browserExtensionsById: this.wingmanConfig?.browser?.extensions,
210
+ browserDefaultExtensions: this.wingmanConfig?.browser?.defaultExtensions,
211
+ browserRelay: this.wingmanConfig?.browser?.relay,
203
212
  searchConfig: this.wingmanConfig?.search,
204
213
  mcpConfigs,
205
214
  skillsDirectory,
@@ -26,8 +26,8 @@ __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
27
  MCPClientManager: ()=>MCPClientManager
28
28
  });
29
- const mcp_adapters_namespaceObject = require("@langchain/mcp-adapters");
30
29
  const tools_namespaceObject = require("@langchain/core/tools");
30
+ const mcp_adapters_namespaceObject = require("@langchain/mcp-adapters");
31
31
  function _define_property(obj, key, value) {
32
32
  if (key in obj) Object.defineProperty(obj, key, {
33
33
  value: value,
@@ -45,26 +45,51 @@ class MCPClientManager {
45
45
  return Array.from(serverMap.values());
46
46
  }
47
47
  buildClientConfig() {
48
- const clientConfig = {};
48
+ const mcpServers = {};
49
49
  for (const server of this.serverConfigs)if ("stdio" === server.transport) {
50
50
  const stdioServer = server;
51
51
  const resolvedEnv = {};
52
52
  for (const [key, value] of Object.entries(stdioServer.env || {}))resolvedEnv[key] = resolveEnvValue(value);
53
- clientConfig[server.name] = {
53
+ const runtimeEnv = this.applyRuntimeEnv(resolvedEnv);
54
+ const defaultToolTimeout = getDefaultToolTimeout(stdioServer);
55
+ mcpServers[server.name] = {
54
56
  transport: "stdio",
55
57
  command: stdioServer.command,
56
58
  args: stdioServer.args || [],
57
- env: resolvedEnv
59
+ env: runtimeEnv,
60
+ ...void 0 !== defaultToolTimeout ? {
61
+ defaultToolTimeout
62
+ } : {}
58
63
  };
59
64
  } else if ("sse" === server.transport) {
60
65
  const sseServer = server;
61
- clientConfig[server.name] = {
66
+ const defaultToolTimeout = getDefaultToolTimeout(sseServer);
67
+ mcpServers[server.name] = {
62
68
  transport: "sse",
63
69
  url: sseServer.url,
64
- headers: sseServer.headers || {}
70
+ headers: sseServer.headers || {},
71
+ ...void 0 !== defaultToolTimeout ? {
72
+ defaultToolTimeout
73
+ } : {}
65
74
  };
66
75
  }
67
- return clientConfig;
76
+ return {
77
+ mcpServers,
78
+ useStandardContentBlocks: false,
79
+ outputHandling: {
80
+ image: "artifact",
81
+ audio: "artifact",
82
+ resource: "artifact"
83
+ }
84
+ };
85
+ }
86
+ applyRuntimeEnv(env) {
87
+ if (!this.executionWorkspace) return env;
88
+ const next = {
89
+ ...env
90
+ };
91
+ next.WINGMAN_WORKDIR = this.executionWorkspace;
92
+ return next;
68
93
  }
69
94
  async initialize() {
70
95
  if (0 === this.serverConfigs.length) return void this.logger.debug("No MCP servers configured");
@@ -117,7 +142,8 @@ class MCPClientManager {
117
142
  if (sanitized === original) return tool;
118
143
  const originalLabel = `Original tool name: ${original}`;
119
144
  const description = tool.description ? `${tool.description}\n\n${originalLabel}` : originalLabel;
120
- const schema = tool.schema ?? tool.inputSchema;
145
+ const toolWithSchema = tool;
146
+ const schema = toolWithSchema.schema ?? toolWithSchema.inputSchema;
121
147
  if (!schema) try {
122
148
  tool.name = sanitized;
123
149
  tool.description = description;
@@ -128,7 +154,7 @@ class MCPClientManager {
128
154
  return (0, tools_namespaceObject.tool)(async (input)=>tool.invoke(input), {
129
155
  name: sanitized,
130
156
  description,
131
- schema
157
+ schema: schema
132
158
  });
133
159
  });
134
160
  }
@@ -145,12 +171,14 @@ class MCPClientManager {
145
171
  hasServers() {
146
172
  return this.serverConfigs.length > 0;
147
173
  }
148
- constructor(configs, logger){
174
+ constructor(configs, logger, options){
149
175
  _define_property(this, "client", null);
150
176
  _define_property(this, "logger", void 0);
151
177
  _define_property(this, "serverConfigs", void 0);
178
+ _define_property(this, "executionWorkspace", void 0);
152
179
  this.logger = logger;
153
180
  this.serverConfigs = this.mergeConfigs(configs);
181
+ this.executionWorkspace = options?.executionWorkspace?.trim() || null;
154
182
  }
155
183
  }
156
184
  function resolveEnvValue(value) {
@@ -159,6 +187,12 @@ function resolveEnvValue(value) {
159
187
  const envValue = process.env[match[1]];
160
188
  return envValue ?? "";
161
189
  }
190
+ function getDefaultToolTimeout(server) {
191
+ const candidate = server.defaultToolTimeout;
192
+ if ("number" != typeof candidate) return;
193
+ if (!Number.isFinite(candidate) || candidate <= 0) return;
194
+ return Math.floor(candidate);
195
+ }
162
196
  exports.MCPClientManager = __webpack_exports__.MCPClientManager;
163
197
  for(var __rspack_i in __webpack_exports__)if (-1 === [
164
198
  "MCPClientManager"
@@ -1,6 +1,6 @@
1
1
  import type { StructuredTool } from "@langchain/core/tools";
2
- import type { MCPServersConfig } from "@/types/mcp.js";
3
2
  import type { Logger } from "@/logger.js";
3
+ import type { MCPServersConfig } from "@/types/mcp.js";
4
4
  /**
5
5
  * Manages MCP server connections and tool retrieval
6
6
  * Handles server lifecycle: initialization, tool loading, and cleanup
@@ -9,7 +9,10 @@ export declare class MCPClientManager {
9
9
  private client;
10
10
  private logger;
11
11
  private serverConfigs;
12
- constructor(configs: MCPServersConfig[], logger: Logger);
12
+ private executionWorkspace;
13
+ constructor(configs: MCPServersConfig[], logger: Logger, options?: {
14
+ executionWorkspace?: string | null;
15
+ });
13
16
  /**
14
17
  * Merge multiple MCP configurations (global + agent-specific)
15
18
  * Agent-specific servers override global ones with same name
@@ -19,6 +22,7 @@ export declare class MCPClientManager {
19
22
  * Convert Wingman MCP config to MultiServerMCPClient format
20
23
  */
21
24
  private buildClientConfig;
25
+ private applyRuntimeEnv;
22
26
  /**
23
27
  * Initialize MCP client and connect to servers
24
28
  */
@@ -1,5 +1,5 @@
1
- import { MultiServerMCPClient } from "@langchain/mcp-adapters";
2
1
  import { tool as tools_tool } from "@langchain/core/tools";
2
+ import { MultiServerMCPClient } from "@langchain/mcp-adapters";
3
3
  function _define_property(obj, key, value) {
4
4
  if (key in obj) Object.defineProperty(obj, key, {
5
5
  value: value,
@@ -17,26 +17,51 @@ class MCPClientManager {
17
17
  return Array.from(serverMap.values());
18
18
  }
19
19
  buildClientConfig() {
20
- const clientConfig = {};
20
+ const mcpServers = {};
21
21
  for (const server of this.serverConfigs)if ("stdio" === server.transport) {
22
22
  const stdioServer = server;
23
23
  const resolvedEnv = {};
24
24
  for (const [key, value] of Object.entries(stdioServer.env || {}))resolvedEnv[key] = resolveEnvValue(value);
25
- clientConfig[server.name] = {
25
+ const runtimeEnv = this.applyRuntimeEnv(resolvedEnv);
26
+ const defaultToolTimeout = getDefaultToolTimeout(stdioServer);
27
+ mcpServers[server.name] = {
26
28
  transport: "stdio",
27
29
  command: stdioServer.command,
28
30
  args: stdioServer.args || [],
29
- env: resolvedEnv
31
+ env: runtimeEnv,
32
+ ...void 0 !== defaultToolTimeout ? {
33
+ defaultToolTimeout
34
+ } : {}
30
35
  };
31
36
  } else if ("sse" === server.transport) {
32
37
  const sseServer = server;
33
- clientConfig[server.name] = {
38
+ const defaultToolTimeout = getDefaultToolTimeout(sseServer);
39
+ mcpServers[server.name] = {
34
40
  transport: "sse",
35
41
  url: sseServer.url,
36
- headers: sseServer.headers || {}
42
+ headers: sseServer.headers || {},
43
+ ...void 0 !== defaultToolTimeout ? {
44
+ defaultToolTimeout
45
+ } : {}
37
46
  };
38
47
  }
39
- return clientConfig;
48
+ return {
49
+ mcpServers,
50
+ useStandardContentBlocks: false,
51
+ outputHandling: {
52
+ image: "artifact",
53
+ audio: "artifact",
54
+ resource: "artifact"
55
+ }
56
+ };
57
+ }
58
+ applyRuntimeEnv(env) {
59
+ if (!this.executionWorkspace) return env;
60
+ const next = {
61
+ ...env
62
+ };
63
+ next.WINGMAN_WORKDIR = this.executionWorkspace;
64
+ return next;
40
65
  }
41
66
  async initialize() {
42
67
  if (0 === this.serverConfigs.length) return void this.logger.debug("No MCP servers configured");
@@ -89,7 +114,8 @@ class MCPClientManager {
89
114
  if (sanitized === original) return tool;
90
115
  const originalLabel = `Original tool name: ${original}`;
91
116
  const description = tool.description ? `${tool.description}\n\n${originalLabel}` : originalLabel;
92
- const schema = tool.schema ?? tool.inputSchema;
117
+ const toolWithSchema = tool;
118
+ const schema = toolWithSchema.schema ?? toolWithSchema.inputSchema;
93
119
  if (!schema) try {
94
120
  tool.name = sanitized;
95
121
  tool.description = description;
@@ -100,7 +126,7 @@ class MCPClientManager {
100
126
  return tools_tool(async (input)=>tool.invoke(input), {
101
127
  name: sanitized,
102
128
  description,
103
- schema
129
+ schema: schema
104
130
  });
105
131
  });
106
132
  }
@@ -117,12 +143,14 @@ class MCPClientManager {
117
143
  hasServers() {
118
144
  return this.serverConfigs.length > 0;
119
145
  }
120
- constructor(configs, logger){
146
+ constructor(configs, logger, options){
121
147
  _define_property(this, "client", null);
122
148
  _define_property(this, "logger", void 0);
123
149
  _define_property(this, "serverConfigs", void 0);
150
+ _define_property(this, "executionWorkspace", void 0);
124
151
  this.logger = logger;
125
152
  this.serverConfigs = this.mergeConfigs(configs);
153
+ this.executionWorkspace = options?.executionWorkspace?.trim() || null;
126
154
  }
127
155
  }
128
156
  function resolveEnvValue(value) {
@@ -131,4 +159,10 @@ function resolveEnvValue(value) {
131
159
  const envValue = process.env[match[1]];
132
160
  return envValue ?? "";
133
161
  }
162
+ function getDefaultToolTimeout(server) {
163
+ const candidate = server.defaultToolTimeout;
164
+ if ("number" != typeof candidate) return;
165
+ if (!Number.isFinite(candidate) || candidate <= 0) return;
166
+ return Math.floor(candidate);
167
+ }
134
168
  export { MCPClientManager };
@@ -31,6 +31,7 @@ __webpack_require__.d(__webpack_exports__, {
31
31
  });
32
32
  const external_logger_cjs_namespaceObject = require("../../logger.cjs");
33
33
  const background_terminal_cjs_namespaceObject = require("../tools/background_terminal.cjs");
34
+ const browser_control_cjs_namespaceObject = require("../tools/browser_control.cjs");
34
35
  const code_search_cjs_namespaceObject = require("../tools/code_search.cjs");
35
36
  const command_execute_cjs_namespaceObject = require("../tools/command_execute.cjs");
36
37
  const git_status_cjs_namespaceObject = require("../tools/git_status.cjs");
@@ -65,6 +66,21 @@ function createTool(name, options = {}) {
65
66
  return (0, internet_search_cjs_namespaceObject.createInternetSearchTool)(searchConfig);
66
67
  case "web_crawler":
67
68
  return web_crawler_cjs_namespaceObject.webCrawler;
69
+ case "browser_control":
70
+ return (0, browser_control_cjs_namespaceObject.createBrowserControlTool)({
71
+ workspace: runtimeWorkspace,
72
+ configWorkspace: workspace,
73
+ launchTimeoutMs: timeout,
74
+ browserProfile: options.browserProfile,
75
+ browserTransport: options.browserTransport,
76
+ profilesRootDir: options.browserProfilesDirectory,
77
+ profilePaths: options.browserProfiles,
78
+ browserExtensions: options.browserExtensions,
79
+ extensionsRootDir: options.browserExtensionsDirectory,
80
+ extensionPaths: options.browserExtensionsById,
81
+ defaultExtensions: options.browserDefaultExtensions,
82
+ relayConfig: options.browserRelay
83
+ });
68
84
  case "command_execute":
69
85
  return (0, command_execute_cjs_namespaceObject.createCommandExecuteTool)(runtimeWorkspace, process.env, blockedCommands, allowScriptExecution, timeout);
70
86
  case "background_terminal":
@@ -102,7 +118,9 @@ async function createTools(toolNames, options = {}) {
102
118
  else logger.warn(`Skipping unknown tool: ${name}`);
103
119
  }
104
120
  if (options.mcpConfigs && options.mcpConfigs.length > 0) try {
105
- const mcpManager = new external_mcpClientManager_cjs_namespaceObject.MCPClientManager(options.mcpConfigs, logger);
121
+ const mcpManager = new external_mcpClientManager_cjs_namespaceObject.MCPClientManager(options.mcpConfigs, logger, {
122
+ executionWorkspace: options.executionWorkspace || options.workspace || null
123
+ });
106
124
  await mcpManager.initialize();
107
125
  const mcpTools = await mcpManager.getTools();
108
126
  if (mcpTools.length > 0) {
@@ -119,6 +137,7 @@ function getAvailableTools() {
119
137
  return [
120
138
  "internet_search",
121
139
  "web_crawler",
140
+ "browser_control",
122
141
  "command_execute",
123
142
  "background_terminal",
124
143
  "think",
@@ -9,6 +9,21 @@ export interface ToolOptions {
9
9
  blockedCommands?: string[];
10
10
  allowScriptExecution?: boolean;
11
11
  timeout?: number;
12
+ browserProfile?: string;
13
+ browserTransport?: "auto" | "playwright" | "relay";
14
+ browserProfilesDirectory?: string;
15
+ browserProfiles?: Record<string, string>;
16
+ browserExtensions?: string[];
17
+ browserExtensionsDirectory?: string;
18
+ browserExtensionsById?: Record<string, string>;
19
+ browserDefaultExtensions?: string[];
20
+ browserRelay?: {
21
+ enabled?: boolean;
22
+ host?: string;
23
+ port?: number;
24
+ requireAuth?: boolean;
25
+ authToken?: string;
26
+ };
12
27
  terminalOwnerId?: string;
13
28
  terminalSessionManager?: TerminalSessionManager;
14
29
  searchConfig?: SearchConfig;
@@ -1,5 +1,6 @@
1
1
  import { createLogger } from "../../logger.js";
2
2
  import { createBackgroundTerminalTool } from "../tools/background_terminal.js";
3
+ import { createBrowserControlTool } from "../tools/browser_control.js";
3
4
  import { createCodeSearchTool } from "../tools/code_search.js";
4
5
  import { createCommandExecuteTool } from "../tools/command_execute.js";
5
6
  import { createGitStatusTool } from "../tools/git_status.js";
@@ -34,6 +35,21 @@ function createTool(name, options = {}) {
34
35
  return createInternetSearchTool(searchConfig);
35
36
  case "web_crawler":
36
37
  return webCrawler;
38
+ case "browser_control":
39
+ return createBrowserControlTool({
40
+ workspace: runtimeWorkspace,
41
+ configWorkspace: workspace,
42
+ launchTimeoutMs: timeout,
43
+ browserProfile: options.browserProfile,
44
+ browserTransport: options.browserTransport,
45
+ profilesRootDir: options.browserProfilesDirectory,
46
+ profilePaths: options.browserProfiles,
47
+ browserExtensions: options.browserExtensions,
48
+ extensionsRootDir: options.browserExtensionsDirectory,
49
+ extensionPaths: options.browserExtensionsById,
50
+ defaultExtensions: options.browserDefaultExtensions,
51
+ relayConfig: options.browserRelay
52
+ });
37
53
  case "command_execute":
38
54
  return createCommandExecuteTool(runtimeWorkspace, process.env, blockedCommands, allowScriptExecution, timeout);
39
55
  case "background_terminal":
@@ -71,7 +87,9 @@ async function createTools(toolNames, options = {}) {
71
87
  else logger.warn(`Skipping unknown tool: ${name}`);
72
88
  }
73
89
  if (options.mcpConfigs && options.mcpConfigs.length > 0) try {
74
- const mcpManager = new MCPClientManager(options.mcpConfigs, logger);
90
+ const mcpManager = new MCPClientManager(options.mcpConfigs, logger, {
91
+ executionWorkspace: options.executionWorkspace || options.workspace || null
92
+ });
75
93
  await mcpManager.initialize();
76
94
  const mcpTools = await mcpManager.getTools();
77
95
  if (mcpTools.length > 0) {
@@ -88,6 +106,7 @@ function getAvailableTools() {
88
106
  return [
89
107
  "internet_search",
90
108
  "web_crawler",
109
+ "browser_control",
91
110
  "command_execute",
92
111
  "background_terminal",
93
112
  "think",
@@ -34,7 +34,9 @@ const agentConfig_cjs_namespaceObject = require("../config/agentConfig.cjs");
34
34
  "mv"
35
35
  ],
36
36
  allowScriptExecution: true,
37
- commandTimeout: 300000
37
+ commandTimeout: 300000,
38
+ browserProfile: "trading",
39
+ browserTransport: "relay"
38
40
  };
39
41
  const result = (0, agentConfig_cjs_namespaceObject.validateAgentConfig)(config);
40
42
  (0, external_vitest_namespaceObject.expect)(result.success).toBe(true);
@@ -51,6 +53,8 @@ const agentConfig_cjs_namespaceObject = require("../config/agentConfig.cjs");
51
53
  ]);
52
54
  (0, external_vitest_namespaceObject.expect)(result.data.allowScriptExecution).toBe(true);
53
55
  (0, external_vitest_namespaceObject.expect)(result.data.commandTimeout).toBe(300000);
56
+ (0, external_vitest_namespaceObject.expect)(result.data.browserProfile).toBe("trading");
57
+ (0, external_vitest_namespaceObject.expect)(result.data.browserTransport).toBe("relay");
54
58
  }
55
59
  });
56
60
  (0, external_vitest_namespaceObject.it)("should allow subagents to override models", ()=>{
@@ -189,6 +193,7 @@ const agentConfig_cjs_namespaceObject = require("../config/agentConfig.cjs");
189
193
  const validTools = [
190
194
  "internet_search",
191
195
  "web_crawler",
196
+ "browser_control",
192
197
  "command_execute",
193
198
  "background_terminal",
194
199
  "think",
@@ -32,7 +32,9 @@ describe("Agent Configuration Schema", ()=>{
32
32
  "mv"
33
33
  ],
34
34
  allowScriptExecution: true,
35
- commandTimeout: 300000
35
+ commandTimeout: 300000,
36
+ browserProfile: "trading",
37
+ browserTransport: "relay"
36
38
  };
37
39
  const result = validateAgentConfig(config);
38
40
  expect(result.success).toBe(true);
@@ -49,6 +51,8 @@ describe("Agent Configuration Schema", ()=>{
49
51
  ]);
50
52
  expect(result.data.allowScriptExecution).toBe(true);
51
53
  expect(result.data.commandTimeout).toBe(300000);
54
+ expect(result.data.browserProfile).toBe("trading");
55
+ expect(result.data.browserTransport).toBe("relay");
52
56
  }
53
57
  });
54
58
  it("should allow subagents to override models", ()=>{
@@ -187,6 +191,7 @@ describe("Agent Configuration Schema", ()=>{
187
191
  const validTools = [
188
192
  "internet_search",
189
193
  "web_crawler",
194
+ "browser_control",
190
195
  "command_execute",
191
196
  "background_terminal",
192
197
  "think",