@wingman-ai/gateway 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/.wingman/agents/README.md +7 -1
  2. package/.wingman/agents/coding/agent.md +295 -202
  3. package/.wingman/agents/coding-v2/agent.md +127 -0
  4. package/.wingman/agents/coding-v2/implementor.md +89 -0
  5. package/dist/agent/config/agentConfig.cjs +31 -17
  6. package/dist/agent/config/agentConfig.d.ts +23 -1
  7. package/dist/agent/config/agentConfig.js +30 -19
  8. package/dist/agent/config/agentLoader.cjs +26 -8
  9. package/dist/agent/config/agentLoader.d.ts +4 -2
  10. package/dist/agent/config/agentLoader.js +26 -8
  11. package/dist/agent/config/modelFactory.cjs +77 -27
  12. package/dist/agent/config/modelFactory.d.ts +11 -1
  13. package/dist/agent/config/modelFactory.js +77 -27
  14. package/dist/agent/config/toolRegistry.cjs +19 -6
  15. package/dist/agent/config/toolRegistry.d.ts +5 -2
  16. package/dist/agent/config/toolRegistry.js +19 -6
  17. package/dist/agent/middleware/hooks/types.cjs +13 -13
  18. package/dist/agent/middleware/hooks/types.d.ts +1 -1
  19. package/dist/agent/middleware/hooks/types.js +14 -14
  20. package/dist/agent/tests/agentConfig.test.cjs +22 -2
  21. package/dist/agent/tests/agentConfig.test.js +22 -2
  22. package/dist/agent/tests/agentLoader.test.cjs +38 -1
  23. package/dist/agent/tests/agentLoader.test.js +38 -1
  24. package/dist/agent/tests/backgroundTerminal.test.cjs +70 -0
  25. package/dist/agent/tests/backgroundTerminal.test.d.ts +1 -0
  26. package/dist/agent/tests/backgroundTerminal.test.js +64 -0
  27. package/dist/agent/tests/commandExecuteTool.test.cjs +29 -0
  28. package/dist/agent/tests/commandExecuteTool.test.d.ts +1 -0
  29. package/dist/agent/tests/commandExecuteTool.test.js +23 -0
  30. package/dist/agent/tests/modelFactory.test.cjs +35 -0
  31. package/dist/agent/tests/modelFactory.test.js +35 -0
  32. package/dist/agent/tests/terminalSessionManager.test.cjs +121 -0
  33. package/dist/agent/tests/terminalSessionManager.test.d.ts +1 -0
  34. package/dist/agent/tests/terminalSessionManager.test.js +115 -0
  35. package/dist/agent/tests/toolRegistry.test.cjs +14 -2
  36. package/dist/agent/tests/toolRegistry.test.js +14 -2
  37. package/dist/agent/tools/background_terminal.cjs +128 -0
  38. package/dist/agent/tools/background_terminal.d.ts +41 -0
  39. package/dist/agent/tools/background_terminal.js +94 -0
  40. package/dist/agent/tools/code_search.cjs +6 -6
  41. package/dist/agent/tools/code_search.d.ts +1 -1
  42. package/dist/agent/tools/code_search.js +7 -7
  43. package/dist/agent/tools/command_execute.cjs +22 -7
  44. package/dist/agent/tools/command_execute.d.ts +3 -2
  45. package/dist/agent/tools/command_execute.js +23 -8
  46. package/dist/agent/tools/git_status.cjs +3 -3
  47. package/dist/agent/tools/git_status.d.ts +1 -1
  48. package/dist/agent/tools/git_status.js +4 -4
  49. package/dist/agent/tools/internet_search.cjs +6 -6
  50. package/dist/agent/tools/internet_search.d.ts +1 -1
  51. package/dist/agent/tools/internet_search.js +7 -7
  52. package/dist/agent/tools/terminal_session_manager.cjs +321 -0
  53. package/dist/agent/tools/terminal_session_manager.d.ts +77 -0
  54. package/dist/agent/tools/terminal_session_manager.js +284 -0
  55. package/dist/agent/tools/think.cjs +4 -4
  56. package/dist/agent/tools/think.d.ts +1 -1
  57. package/dist/agent/tools/think.js +5 -5
  58. package/dist/agent/tools/ui_registry.cjs +13 -13
  59. package/dist/agent/tools/ui_registry.d.ts +4 -4
  60. package/dist/agent/tools/ui_registry.js +14 -14
  61. package/dist/agent/tools/web_crawler.cjs +4 -4
  62. package/dist/agent/tools/web_crawler.d.ts +1 -1
  63. package/dist/agent/tools/web_crawler.js +5 -5
  64. package/dist/agent/utils.cjs +2 -1
  65. package/dist/agent/utils.js +2 -1
  66. package/dist/cli/config/schema.cjs +89 -89
  67. package/dist/cli/config/schema.d.ts +1 -1
  68. package/dist/cli/config/schema.js +90 -90
  69. package/dist/cli/core/agentInvoker.cjs +170 -21
  70. package/dist/cli/core/agentInvoker.d.ts +25 -4
  71. package/dist/cli/core/agentInvoker.js +157 -20
  72. package/dist/cli/core/streamParser.cjs +15 -0
  73. package/dist/cli/core/streamParser.js +15 -0
  74. package/dist/cli/ui/toolDisplayHelpers.cjs +2 -0
  75. package/dist/cli/ui/toolDisplayHelpers.js +2 -0
  76. package/dist/gateway/hooks/registry.cjs +2 -1
  77. package/dist/gateway/hooks/registry.d.ts +1 -1
  78. package/dist/gateway/hooks/registry.js +2 -1
  79. package/dist/gateway/hooks/types.cjs +11 -11
  80. package/dist/gateway/hooks/types.d.ts +1 -1
  81. package/dist/gateway/hooks/types.js +12 -12
  82. package/dist/gateway/http/agents.cjs +67 -4
  83. package/dist/gateway/http/agents.js +67 -4
  84. package/dist/gateway/http/types.d.ts +5 -3
  85. package/dist/gateway/http/webhooks.cjs +6 -5
  86. package/dist/gateway/http/webhooks.js +6 -5
  87. package/dist/gateway/server.cjs +7 -0
  88. package/dist/gateway/server.d.ts +1 -0
  89. package/dist/gateway/server.js +7 -0
  90. package/dist/gateway/validation.cjs +39 -39
  91. package/dist/gateway/validation.d.ts +1 -1
  92. package/dist/gateway/validation.js +40 -40
  93. package/dist/tests/additionalMessageMiddleware.test.cjs +3 -0
  94. package/dist/tests/additionalMessageMiddleware.test.js +3 -0
  95. package/dist/tests/agentInvokerSummarization.test.cjs +171 -12
  96. package/dist/tests/agentInvokerSummarization.test.js +172 -13
  97. package/dist/tests/agents-api.test.cjs +45 -5
  98. package/dist/tests/agents-api.test.js +45 -5
  99. package/dist/tests/cli-init.test.cjs +27 -3
  100. package/dist/tests/cli-init.test.js +27 -3
  101. package/dist/tests/codex-provider.test.cjs +24 -0
  102. package/dist/tests/codex-provider.test.js +24 -0
  103. package/dist/tests/gateway.test.cjs +7 -7
  104. package/dist/tests/gateway.test.js +7 -7
  105. package/dist/tests/toolDisplayHelpers.test.cjs +3 -0
  106. package/dist/tests/toolDisplayHelpers.test.js +3 -0
  107. package/dist/tools/mcp-finance.cjs +48 -48
  108. package/dist/tools/mcp-finance.js +48 -48
  109. package/dist/types/mcp.cjs +15 -15
  110. package/dist/types/mcp.d.ts +1 -1
  111. package/dist/types/mcp.js +16 -16
  112. package/dist/types/voice.cjs +21 -21
  113. package/dist/types/voice.d.ts +1 -1
  114. package/dist/types/voice.js +22 -22
  115. package/dist/webui/assets/index-DVWQluit.css +11 -0
  116. package/dist/webui/assets/index-Dlyzwalc.js +270 -0
  117. package/dist/webui/favicon-32x32.png +0 -0
  118. package/dist/webui/favicon-64x64.png +0 -0
  119. package/dist/webui/favicon.webp +0 -0
  120. package/dist/webui/index.html +4 -2
  121. package/package.json +13 -12
  122. package/.wingman/agents/coding/implementor.md +0 -103
  123. package/dist/webui/assets/index-BVMavpud.css +0 -11
  124. package/dist/webui/assets/index-DCB2aVVf.js +0 -182
@@ -1,15 +1,31 @@
1
- import { AgentLoader } from "../../agent/config/agentLoader.js";
2
- import { getAvailableTools } from "../../agent/config/toolRegistry.js";
3
- import { GatewayRouter } from "../router.js";
4
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
2
  import { join } from "node:path";
6
3
  import { dump, load } from "js-yaml";
4
+ import { ReasoningEffortSchema } from "../../agent/config/agentConfig.js";
5
+ import { AgentLoader } from "../../agent/config/agentLoader.js";
6
+ import { getAvailableTools } from "../../agent/config/toolRegistry.js";
7
7
  import { AgentVoiceConfigSchema } from "../../types/voice.js";
8
+ import { GatewayRouter } from "../router.js";
8
9
  const hasOwn = (value, key)=>Boolean(value && Object.prototype.hasOwnProperty.call(value, key));
9
10
  const getPromptTrainingFromPayload = (payload)=>{
10
11
  if (hasOwn(payload, "promptTraining")) return payload.promptTraining;
11
12
  if (hasOwn(payload, "promptRefinement")) return payload.promptRefinement;
12
13
  };
14
+ const getReasoningEffortFromPayload = (payload)=>{
15
+ if (hasOwn(payload, "reasoningEffort")) return payload.reasoningEffort;
16
+ if (hasOwn(payload, "thinkingEffort")) return payload.thinkingEffort;
17
+ };
18
+ const parseReasoningEffort = (value, fieldPath)=>{
19
+ const parsed = ReasoningEffortSchema.safeParse(value);
20
+ if (!parsed.success) return {
21
+ ok: false,
22
+ error: `Invalid ${fieldPath}: expected one of minimal|low|medium|high`
23
+ };
24
+ return {
25
+ ok: true,
26
+ value: parsed.data
27
+ };
28
+ };
13
29
  const mapPromptTrainingFields = (value)=>({
14
30
  promptTraining: value,
15
31
  promptRefinement: value
@@ -20,6 +36,7 @@ const mapSubAgentForResponse = (sub)=>({
20
36
  description: sub.description,
21
37
  tools: sub.tools || [],
22
38
  model: sub.model,
39
+ reasoningEffort: sub.reasoningEffort,
23
40
  prompt: sub.systemPrompt,
24
41
  ...mapPromptTrainingFields(sub.promptRefinement)
25
42
  });
@@ -60,12 +77,23 @@ const normalizeSubAgents = (rawSubAgents)=>{
60
77
  ok: false,
61
78
  error: `Invalid subAgents[${index}].promptTraining`
62
79
  };
80
+ const rawReasoningEffort = getReasoningEffortFromPayload(item);
81
+ let reasoningEffort;
82
+ if (null != rawReasoningEffort) {
83
+ const parsedEffort = parseReasoningEffort(rawReasoningEffort, `subAgents[${index}].reasoningEffort`);
84
+ if (!parsedEffort.ok) return {
85
+ ok: false,
86
+ error: parsedEffort.error
87
+ };
88
+ reasoningEffort = parsedEffort.value;
89
+ }
63
90
  const tools = Array.isArray(item.tools) ? item.tools.filter((tool)=>availableTools.includes(tool)) : [];
64
91
  const sub = {
65
92
  name,
66
93
  description,
67
94
  tools,
68
95
  model: item.model?.trim() || void 0,
96
+ reasoningEffort,
69
97
  systemPrompt: prompt
70
98
  };
71
99
  if (null != promptTraining) sub.promptRefinement = promptTraining;
@@ -77,13 +105,14 @@ const normalizeSubAgents = (rawSubAgents)=>{
77
105
  };
78
106
  };
79
107
  const buildAgentMarkdown = (params)=>{
80
- const { id, description, tools, model, prompt, voice, promptRefinement, subAgents } = params;
108
+ const { id, description, tools, model, reasoningEffort, prompt, voice, promptRefinement, subAgents } = params;
81
109
  const metadata = {
82
110
  name: id,
83
111
  description: description || "New Wingman agent",
84
112
  tools: tools || []
85
113
  };
86
114
  if (model) metadata.model = model;
115
+ if (reasoningEffort) metadata.reasoningEffort = reasoningEffort;
87
116
  if (voice) metadata.voice = voice;
88
117
  if (void 0 !== promptRefinement) metadata.promptRefinement = promptRefinement;
89
118
  if (subAgents && subAgents.length > 0) metadata.subAgents = subAgents;
@@ -123,6 +152,7 @@ const handleAgentsApi = async (ctx, req, url)=>{
123
152
  description: agent.description,
124
153
  tools: agent.tools || [],
125
154
  model: agent.model,
155
+ reasoningEffort: agent.reasoningEffort,
126
156
  voice: agent.voice,
127
157
  ...mapPromptTrainingFields(agent.promptRefinement),
128
158
  subAgents: agent.subAgents?.map((sub)=>mapSubAgentForResponse(sub)) || []
@@ -156,6 +186,15 @@ const handleAgentsApi = async (ctx, req, url)=>{
156
186
  if (null != promptTraining && "boolean" != typeof promptTraining && ("object" != typeof promptTraining || Array.isArray(promptTraining))) return new Response("Invalid promptTraining configuration", {
157
187
  status: 400
158
188
  });
189
+ const rawReasoningEffort = getReasoningEffortFromPayload(body);
190
+ let reasoningEffort;
191
+ if (null != rawReasoningEffort) {
192
+ const parsedEffort = parseReasoningEffort(rawReasoningEffort, "reasoningEffort");
193
+ if (!parsedEffort.ok) return new Response(parsedEffort.error, {
194
+ status: 400
195
+ });
196
+ reasoningEffort = parsedEffort.value;
197
+ }
159
198
  const rawSubAgents = hasOwn(body, "subAgents") ? body.subAgents : body.subagents;
160
199
  const subAgentsResult = normalizeSubAgents(rawSubAgents);
161
200
  if (!subAgentsResult.ok) return new Response(subAgentsResult.error, {
@@ -173,6 +212,7 @@ const handleAgentsApi = async (ctx, req, url)=>{
173
212
  description: body.description,
174
213
  tools,
175
214
  model: body.model,
215
+ reasoningEffort,
176
216
  prompt: body.prompt,
177
217
  voice: parsedVoice,
178
218
  promptRefinement: null === promptTraining ? void 0 : promptTraining,
@@ -200,6 +240,7 @@ const handleAgentsApi = async (ctx, req, url)=>{
200
240
  description: body.description,
201
241
  tools,
202
242
  model: body.model,
243
+ reasoningEffort,
203
244
  voice: parsedVoice,
204
245
  ...mapPromptTrainingFields(null === promptTraining ? void 0 : promptTraining),
205
246
  subAgents: subAgentsResult.value.map((sub)=>mapSubAgentForResponse(sub))
@@ -230,6 +271,7 @@ const handleAgentsApi = async (ctx, req, url)=>{
230
271
  description: agentConfig.description,
231
272
  tools: agentConfig.tools || [],
232
273
  model: agentConfig.model,
274
+ reasoningEffort: agentConfig.reasoningEffort,
233
275
  voice: agentConfig.voice,
234
276
  ...mapPromptTrainingFields(agentConfig.promptRefinement),
235
277
  subAgents: agentConfig.subAgents?.map((sub)=>mapSubAgentForResponse(sub)) || [],
@@ -257,6 +299,16 @@ const handleAgentsApi = async (ctx, req, url)=>{
257
299
  const tools = Array.isArray(body.tools) ? body.tools.filter((tool)=>getAvailableTools().includes(tool)) : agentConfig.tools || [];
258
300
  const nextDescription = body.description ?? agentConfig.description;
259
301
  const nextModel = body.model ?? agentConfig.model;
302
+ const bodyReasoningEffort = getReasoningEffortFromPayload(body);
303
+ let nextReasoningEffort = agentConfig.reasoningEffort;
304
+ if (null === bodyReasoningEffort) nextReasoningEffort = void 0;
305
+ else if (void 0 !== bodyReasoningEffort) {
306
+ const parsedEffort = parseReasoningEffort(bodyReasoningEffort, "reasoningEffort");
307
+ if (!parsedEffort.ok) return new Response(parsedEffort.error, {
308
+ status: 400
309
+ });
310
+ nextReasoningEffort = parsedEffort.value;
311
+ }
260
312
  const nextPrompt = body.prompt ?? agentConfig.systemPrompt;
261
313
  const nextVoice = void 0 === parsedVoice ? agentConfig.voice : parsedVoice;
262
314
  const bodyPromptTraining = getPromptTrainingFromPayload(body);
@@ -287,6 +339,11 @@ const handleAgentsApi = async (ctx, req, url)=>{
287
339
  parsed.tools = tools;
288
340
  if (nextModel) parsed.model = nextModel;
289
341
  else delete parsed.model;
342
+ if (nextReasoningEffort) parsed.reasoningEffort = nextReasoningEffort;
343
+ else {
344
+ delete parsed.reasoningEffort;
345
+ delete parsed.thinkingEffort;
346
+ }
290
347
  parsed.systemPrompt = nextPrompt;
291
348
  if (nextVoice) parsed.voice = nextVoice;
292
349
  else delete parsed.voice;
@@ -306,6 +363,11 @@ const handleAgentsApi = async (ctx, req, url)=>{
306
363
  metadata.tools = tools;
307
364
  if (nextModel) metadata.model = nextModel;
308
365
  else delete metadata.model;
366
+ if (nextReasoningEffort) metadata.reasoningEffort = nextReasoningEffort;
367
+ else {
368
+ delete metadata.reasoningEffort;
369
+ delete metadata.thinkingEffort;
370
+ }
309
371
  if (nextVoice) metadata.voice = nextVoice;
310
372
  else delete metadata.voice;
311
373
  if (void 0 !== nextPromptRefinement) metadata.promptRefinement = nextPromptRefinement;
@@ -340,6 +402,7 @@ const handleAgentsApi = async (ctx, req, url)=>{
340
402
  description: nextDescription,
341
403
  tools,
342
404
  model: nextModel,
405
+ reasoningEffort: nextReasoningEffort,
343
406
  voice: nextVoice,
344
407
  ...mapPromptTrainingFields(nextPromptRefinement),
345
408
  subAgents: nextSubAgents.map((sub)=>mapSubAgentForResponse(sub)),
@@ -1,8 +1,9 @@
1
- import type { GatewayRouter } from "../router.js";
2
- import type { GatewayAuth } from "../auth.js";
3
- import type { Logger } from "@/logger.js";
1
+ import type { TerminalSessionManager } from "@/agent/tools/terminal_session_manager.js";
4
2
  import type { WingmanConfigType } from "@/cli/config/schema.js";
5
3
  import type { SessionManager } from "@/cli/core/sessionManager.js";
4
+ import type { Logger } from "@/logger.js";
5
+ import type { GatewayAuth } from "../auth.js";
6
+ import type { GatewayRouter } from "../router.js";
6
7
  export type GatewayHttpContext = {
7
8
  workspace: string;
8
9
  configDir: string;
@@ -21,5 +22,6 @@ export type GatewayHttpContext = {
21
22
  resolveFsRoots: () => string[];
22
23
  resolveFsPath: (path: string) => string;
23
24
  isPathWithinRoots: (path: string, roots: string[]) => boolean;
25
+ getTerminalSessionManager: () => TerminalSessionManager;
24
26
  getBuiltInTools: () => string[];
25
27
  };
@@ -28,12 +28,12 @@ __webpack_require__.d(__webpack_exports__, {
28
28
  createWebhookStore: ()=>createWebhookStore,
29
29
  handleWebhookInvoke: ()=>handleWebhookInvoke
30
30
  });
31
- const agentInvoker_cjs_namespaceObject = require("../../cli/core/agentInvoker.cjs");
32
- const outputManager_cjs_namespaceObject = require("../../cli/core/outputManager.cjs");
33
- const agentLoader_cjs_namespaceObject = require("../../agent/config/agentLoader.cjs");
34
31
  const external_node_crypto_namespaceObject = require("node:crypto");
35
32
  const external_node_fs_namespaceObject = require("node:fs");
36
33
  const external_node_path_namespaceObject = require("node:path");
34
+ const agentLoader_cjs_namespaceObject = require("../../agent/config/agentLoader.cjs");
35
+ const agentInvoker_cjs_namespaceObject = require("../../cli/core/agentInvoker.cjs");
36
+ const outputManager_cjs_namespaceObject = require("../../cli/core/outputManager.cjs");
37
37
  const WEBHOOK_PRESETS = new Set([
38
38
  "gog-gmail"
39
39
  ]);
@@ -192,12 +192,12 @@ const handleWebhooksApi = async (ctx, store, req, url)=>{
192
192
  if (!agentExists(ctx, nextAgentId)) return new Response("Invalid agentId", {
193
193
  status: 400
194
194
  });
195
- const hasPreset = Object.prototype.hasOwnProperty.call(body ?? {}, "preset");
195
+ const hasPreset = Object.hasOwn(body ?? {}, "preset");
196
196
  const presetValue = hasPreset ? normalizePreset(body?.preset) : webhook.preset;
197
197
  if (hasPreset && body?.preset && !presetValue && "custom" !== body.preset.trim()) return new Response("Invalid preset", {
198
198
  status: 400
199
199
  });
200
- const hasSessionId = Object.prototype.hasOwnProperty.call(body ?? {}, "sessionId");
200
+ const hasSessionId = Object.hasOwn(body ?? {}, "sessionId");
201
201
  let nextSessionId = webhook.sessionId;
202
202
  if (hasSessionId) {
203
203
  const trimmed = body?.sessionId?.trim();
@@ -316,6 +316,7 @@ const handleWebhookInvoke = async (ctx, store, req, url)=>{
316
316
  outputManager,
317
317
  logger: ctx.logger,
318
318
  sessionManager,
319
+ terminalSessionManager: ctx.getTerminalSessionManager(),
319
320
  workdir,
320
321
  defaultOutputDir
321
322
  });
@@ -1,9 +1,9 @@
1
- import { AgentInvoker } from "../../cli/core/agentInvoker.js";
2
- import { OutputManager } from "../../cli/core/outputManager.js";
3
- import { AgentLoader } from "../../agent/config/agentLoader.js";
4
1
  import { randomUUID } from "node:crypto";
5
2
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
6
3
  import { join } from "node:path";
4
+ import { AgentLoader } from "../../agent/config/agentLoader.js";
5
+ import { AgentInvoker } from "../../cli/core/agentInvoker.js";
6
+ import { OutputManager } from "../../cli/core/outputManager.js";
7
7
  const WEBHOOK_PRESETS = new Set([
8
8
  "gog-gmail"
9
9
  ]);
@@ -162,12 +162,12 @@ const handleWebhooksApi = async (ctx, store, req, url)=>{
162
162
  if (!agentExists(ctx, nextAgentId)) return new Response("Invalid agentId", {
163
163
  status: 400
164
164
  });
165
- const hasPreset = Object.prototype.hasOwnProperty.call(body ?? {}, "preset");
165
+ const hasPreset = Object.hasOwn(body ?? {}, "preset");
166
166
  const presetValue = hasPreset ? normalizePreset(body?.preset) : webhook.preset;
167
167
  if (hasPreset && body?.preset && !presetValue && "custom" !== body.preset.trim()) return new Response("Invalid preset", {
168
168
  status: 400
169
169
  });
170
- const hasSessionId = Object.prototype.hasOwnProperty.call(body ?? {}, "sessionId");
170
+ const hasSessionId = Object.hasOwn(body ?? {}, "sessionId");
171
171
  let nextSessionId = webhook.sessionId;
172
172
  if (hasSessionId) {
173
173
  const trimmed = body?.sessionId?.trim();
@@ -286,6 +286,7 @@ const handleWebhookInvoke = async (ctx, store, req, url)=>{
286
286
  outputManager,
287
287
  logger: ctx.logger,
288
288
  sessionManager,
289
+ terminalSessionManager: ctx.getTerminalSessionManager(),
289
290
  workdir,
290
291
  defaultOutputDir
291
292
  });
@@ -33,6 +33,7 @@ const external_node_fs_namespaceObject = require("node:fs");
33
33
  const external_node_os_namespaceObject = require("node:os");
34
34
  const external_node_path_namespaceObject = require("node:path");
35
35
  const external_node_url_namespaceObject = require("node:url");
36
+ const terminal_session_manager_cjs_namespaceObject = require("../agent/tools/terminal_session_manager.cjs");
36
37
  const loader_cjs_namespaceObject = require("../cli/config/loader.cjs");
37
38
  const agentInvoker_cjs_namespaceObject = require("../cli/core/agentInvoker.cjs");
38
39
  const outputManager_cjs_namespaceObject = require("../cli/core/outputManager.cjs");
@@ -107,6 +108,7 @@ class GatewayServer {
107
108
  });
108
109
  return;
109
110
  }
111
+ if (url.pathname.startsWith("/api/")) return this.handleUiRequest(req);
110
112
  const webhookResponse = await (0, webhooks_cjs_namespaceObject.handleWebhookInvoke)(this.getHttpContext(), this.webhookStore, req, url);
111
113
  if (webhookResponse) return webhookResponse;
112
114
  if (this.controlUiSamePort) return this.handleUiRequest(req);
@@ -163,6 +165,7 @@ class GatewayServer {
163
165
  this.uiServer.stop();
164
166
  this.uiServer = null;
165
167
  }
168
+ this.terminalSessionManager.dispose();
166
169
  this.log("info", "Gateway stopped");
167
170
  }
168
171
  getPort() {
@@ -495,6 +498,7 @@ class GatewayServer {
495
498
  outputManager,
496
499
  logger: this.logger,
497
500
  sessionManager,
501
+ terminalSessionManager: this.terminalSessionManager,
498
502
  workdir,
499
503
  defaultOutputDir
500
504
  });
@@ -932,6 +936,7 @@ class GatewayServer {
932
936
  resolveFsRoots: ()=>this.resolveFsRoots(),
933
937
  resolveFsPath: (path)=>this.resolveFsPath(path),
934
938
  isPathWithinRoots: (path, roots)=>this.isPathWithinRoots(path, roots),
939
+ getTerminalSessionManager: ()=>this.terminalSessionManager,
935
940
  getBuiltInTools: ()=>this.getBuiltInTools()
936
941
  };
937
942
  }
@@ -1331,6 +1336,7 @@ class GatewayServer {
1331
1336
  _define_property(this, "activeSessionRequests", new Map());
1332
1337
  _define_property(this, "queuedSessionRequests", new Map());
1333
1338
  _define_property(this, "requestSessionKeys", new Map());
1339
+ _define_property(this, "terminalSessionManager", void 0);
1334
1340
  _define_property(this, "bridgeQueues", new Map());
1335
1341
  _define_property(this, "bridgePollWaiters", new Map());
1336
1342
  this.workspace = config.workspace || process.cwd();
@@ -1381,6 +1387,7 @@ class GatewayServer {
1381
1387
  this.controlUiPort = controlUi?.port || 18790;
1382
1388
  this.controlUiSamePort = this.controlUiEnabled && this.controlUiPort === this.config.port;
1383
1389
  this.uiDistDir = this.controlUiEnabled ? this.resolveControlUiDir() : null;
1390
+ this.terminalSessionManager = new terminal_session_manager_cjs_namespaceObject.TerminalSessionManager();
1384
1391
  }
1385
1392
  }
1386
1393
  function buildAttachmentPreview(attachments) {
@@ -37,6 +37,7 @@ export declare class GatewayServer {
37
37
  private activeSessionRequests;
38
38
  private queuedSessionRequests;
39
39
  private requestSessionKeys;
40
+ private terminalSessionManager;
40
41
  private bridgeQueues;
41
42
  private bridgePollWaiters;
42
43
  constructor(config?: Partial<GatewayConfig>);
@@ -2,6 +2,7 @@ import { existsSync, mkdirSync, statSync, writeFileSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { dirname, isAbsolute, join, normalize, sep } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
+ import { TerminalSessionManager } from "../agent/tools/terminal_session_manager.js";
5
6
  import { WingmanConfigLoader } from "../cli/config/loader.js";
6
7
  import { AgentInvoker } from "../cli/core/agentInvoker.js";
7
8
  import { OutputManager } from "../cli/core/outputManager.js";
@@ -76,6 +77,7 @@ class GatewayServer {
76
77
  });
77
78
  return;
78
79
  }
80
+ if (url.pathname.startsWith("/api/")) return this.handleUiRequest(req);
79
81
  const webhookResponse = await handleWebhookInvoke(this.getHttpContext(), this.webhookStore, req, url);
80
82
  if (webhookResponse) return webhookResponse;
81
83
  if (this.controlUiSamePort) return this.handleUiRequest(req);
@@ -132,6 +134,7 @@ class GatewayServer {
132
134
  this.uiServer.stop();
133
135
  this.uiServer = null;
134
136
  }
137
+ this.terminalSessionManager.dispose();
135
138
  this.log("info", "Gateway stopped");
136
139
  }
137
140
  getPort() {
@@ -464,6 +467,7 @@ class GatewayServer {
464
467
  outputManager,
465
468
  logger: this.logger,
466
469
  sessionManager,
470
+ terminalSessionManager: this.terminalSessionManager,
467
471
  workdir,
468
472
  defaultOutputDir
469
473
  });
@@ -901,6 +905,7 @@ class GatewayServer {
901
905
  resolveFsRoots: ()=>this.resolveFsRoots(),
902
906
  resolveFsPath: (path)=>this.resolveFsPath(path),
903
907
  isPathWithinRoots: (path, roots)=>this.isPathWithinRoots(path, roots),
908
+ getTerminalSessionManager: ()=>this.terminalSessionManager,
904
909
  getBuiltInTools: ()=>this.getBuiltInTools()
905
910
  };
906
911
  }
@@ -1300,6 +1305,7 @@ class GatewayServer {
1300
1305
  _define_property(this, "activeSessionRequests", new Map());
1301
1306
  _define_property(this, "queuedSessionRequests", new Map());
1302
1307
  _define_property(this, "requestSessionKeys", new Map());
1308
+ _define_property(this, "terminalSessionManager", void 0);
1303
1309
  _define_property(this, "bridgeQueues", new Map());
1304
1310
  _define_property(this, "bridgePollWaiters", new Map());
1305
1311
  this.workspace = config.workspace || process.cwd();
@@ -1350,6 +1356,7 @@ class GatewayServer {
1350
1356
  this.controlUiPort = controlUi?.port || 18790;
1351
1357
  this.controlUiSamePort = this.controlUiEnabled && this.controlUiPort === this.config.port;
1352
1358
  this.uiDistDir = this.controlUiEnabled ? this.resolveControlUiDir() : null;
1359
+ this.terminalSessionManager = new TerminalSessionManager();
1353
1360
  }
1354
1361
  }
1355
1362
  function buildAttachmentPreview(attachments) {
@@ -38,7 +38,7 @@ __webpack_require__.d(__webpack_exports__, {
38
38
  BroadcastPayloadSchema: ()=>BroadcastPayloadSchema
39
39
  });
40
40
  const external_zod_namespaceObject = require("zod");
41
- const MessageTypeSchema = external_zod_namespaceObject.z["enum"]([
41
+ const MessageTypeSchema = external_zod_namespaceObject["enum"]([
42
42
  "connect",
43
43
  "res",
44
44
  "req:agent",
@@ -58,52 +58,52 @@ const MessageTypeSchema = external_zod_namespaceObject.z["enum"]([
58
58
  "error",
59
59
  "ack"
60
60
  ]);
61
- const GatewayMessageSchema = external_zod_namespaceObject.z.object({
61
+ const GatewayMessageSchema = external_zod_namespaceObject.object({
62
62
  type: MessageTypeSchema,
63
- id: external_zod_namespaceObject.z.string().optional(),
64
- client: external_zod_namespaceObject.z.object({
65
- instanceId: external_zod_namespaceObject.z.string().min(1),
66
- clientType: external_zod_namespaceObject.z.string().min(1),
67
- version: external_zod_namespaceObject.z.string().optional()
63
+ id: external_zod_namespaceObject.string().optional(),
64
+ client: external_zod_namespaceObject.object({
65
+ instanceId: external_zod_namespaceObject.string().min(1),
66
+ clientType: external_zod_namespaceObject.string().min(1),
67
+ version: external_zod_namespaceObject.string().optional()
68
68
  }).optional(),
69
- auth: external_zod_namespaceObject.z.object({
70
- token: external_zod_namespaceObject.z.string().optional(),
71
- password: external_zod_namespaceObject.z.string().optional(),
72
- deviceId: external_zod_namespaceObject.z.string().optional()
69
+ auth: external_zod_namespaceObject.object({
70
+ token: external_zod_namespaceObject.string().optional(),
71
+ password: external_zod_namespaceObject.string().optional(),
72
+ deviceId: external_zod_namespaceObject.string().optional()
73
73
  }).optional(),
74
- ok: external_zod_namespaceObject.z.boolean().optional(),
75
- clientId: external_zod_namespaceObject.z.string().optional(),
76
- nodeId: external_zod_namespaceObject.z.string().optional(),
77
- groupId: external_zod_namespaceObject.z.string().optional(),
78
- roomId: external_zod_namespaceObject.z.string().optional(),
79
- targetNodeId: external_zod_namespaceObject.z.string().optional(),
80
- payload: external_zod_namespaceObject.z.unknown().optional(),
81
- timestamp: external_zod_namespaceObject.z.number(),
82
- messageId: external_zod_namespaceObject.z.string().optional()
74
+ ok: external_zod_namespaceObject.boolean().optional(),
75
+ clientId: external_zod_namespaceObject.string().optional(),
76
+ nodeId: external_zod_namespaceObject.string().optional(),
77
+ groupId: external_zod_namespaceObject.string().optional(),
78
+ roomId: external_zod_namespaceObject.string().optional(),
79
+ targetNodeId: external_zod_namespaceObject.string().optional(),
80
+ payload: external_zod_namespaceObject.unknown().optional(),
81
+ timestamp: external_zod_namespaceObject.number(),
82
+ messageId: external_zod_namespaceObject.string().optional()
83
83
  });
84
- const RegisterPayloadSchema = external_zod_namespaceObject.z.object({
85
- name: external_zod_namespaceObject.z.string().min(1).max(100),
86
- capabilities: external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string()).optional(),
87
- token: external_zod_namespaceObject.z.string().optional()
84
+ const RegisterPayloadSchema = external_zod_namespaceObject.object({
85
+ name: external_zod_namespaceObject.string().min(1).max(100),
86
+ capabilities: external_zod_namespaceObject.array(external_zod_namespaceObject.string()).optional(),
87
+ token: external_zod_namespaceObject.string().optional()
88
88
  });
89
- const JoinGroupPayloadSchema = external_zod_namespaceObject.z.object({
90
- groupId: external_zod_namespaceObject.z.string().optional(),
91
- groupName: external_zod_namespaceObject.z.string().min(1).max(100).optional(),
92
- createIfNotExists: external_zod_namespaceObject.z.boolean().optional(),
93
- description: external_zod_namespaceObject.z.string().max(500).optional()
89
+ const JoinGroupPayloadSchema = external_zod_namespaceObject.object({
90
+ groupId: external_zod_namespaceObject.string().optional(),
91
+ groupName: external_zod_namespaceObject.string().min(1).max(100).optional(),
92
+ createIfNotExists: external_zod_namespaceObject.boolean().optional(),
93
+ description: external_zod_namespaceObject.string().max(500).optional()
94
94
  });
95
- const BroadcastPayloadSchema = external_zod_namespaceObject.z.object({
96
- groupId: external_zod_namespaceObject.z.string().min(1),
97
- message: external_zod_namespaceObject.z.unknown()
95
+ const BroadcastPayloadSchema = external_zod_namespaceObject.object({
96
+ groupId: external_zod_namespaceObject.string().min(1),
97
+ message: external_zod_namespaceObject.unknown()
98
98
  });
99
- const DirectPayloadSchema = external_zod_namespaceObject.z.object({
100
- targetNodeId: external_zod_namespaceObject.z.string().min(1),
101
- message: external_zod_namespaceObject.z.unknown()
99
+ const DirectPayloadSchema = external_zod_namespaceObject.object({
100
+ targetNodeId: external_zod_namespaceObject.string().min(1),
101
+ message: external_zod_namespaceObject.unknown()
102
102
  });
103
- const ErrorPayloadSchema = external_zod_namespaceObject.z.object({
104
- code: external_zod_namespaceObject.z.string().min(1),
105
- message: external_zod_namespaceObject.z.string().min(1),
106
- details: external_zod_namespaceObject.z.unknown().optional()
103
+ const ErrorPayloadSchema = external_zod_namespaceObject.object({
104
+ code: external_zod_namespaceObject.string().min(1),
105
+ message: external_zod_namespaceObject.string().min(1),
106
+ details: external_zod_namespaceObject.unknown().optional()
107
107
  });
108
108
  function validateGatewayMessage(data) {
109
109
  try {
@@ -1,4 +1,4 @@
1
- import { z } from "zod";
1
+ import * as z from "zod";
2
2
  import type { GatewayMessage, RegisterPayload, JoinGroupPayload, BroadcastPayload, DirectPayload } from "./types.js";
3
3
  /**
4
4
  * Message type enum for validation
@@ -1,5 +1,5 @@
1
- import { z } from "zod";
2
- const MessageTypeSchema = z["enum"]([
1
+ import { array, boolean as external_zod_boolean, enum as external_zod_enum, number, object, string, unknown } from "zod";
2
+ const MessageTypeSchema = external_zod_enum([
3
3
  "connect",
4
4
  "res",
5
5
  "req:agent",
@@ -19,52 +19,52 @@ const MessageTypeSchema = z["enum"]([
19
19
  "error",
20
20
  "ack"
21
21
  ]);
22
- const GatewayMessageSchema = z.object({
22
+ const GatewayMessageSchema = object({
23
23
  type: MessageTypeSchema,
24
- id: z.string().optional(),
25
- client: z.object({
26
- instanceId: z.string().min(1),
27
- clientType: z.string().min(1),
28
- version: z.string().optional()
24
+ id: string().optional(),
25
+ client: object({
26
+ instanceId: string().min(1),
27
+ clientType: string().min(1),
28
+ version: string().optional()
29
29
  }).optional(),
30
- auth: z.object({
31
- token: z.string().optional(),
32
- password: z.string().optional(),
33
- deviceId: z.string().optional()
30
+ auth: object({
31
+ token: string().optional(),
32
+ password: string().optional(),
33
+ deviceId: string().optional()
34
34
  }).optional(),
35
- ok: z.boolean().optional(),
36
- clientId: z.string().optional(),
37
- nodeId: z.string().optional(),
38
- groupId: z.string().optional(),
39
- roomId: z.string().optional(),
40
- targetNodeId: z.string().optional(),
41
- payload: z.unknown().optional(),
42
- timestamp: z.number(),
43
- messageId: z.string().optional()
35
+ ok: external_zod_boolean().optional(),
36
+ clientId: string().optional(),
37
+ nodeId: string().optional(),
38
+ groupId: string().optional(),
39
+ roomId: string().optional(),
40
+ targetNodeId: string().optional(),
41
+ payload: unknown().optional(),
42
+ timestamp: number(),
43
+ messageId: string().optional()
44
44
  });
45
- const RegisterPayloadSchema = z.object({
46
- name: z.string().min(1).max(100),
47
- capabilities: z.array(z.string()).optional(),
48
- token: z.string().optional()
45
+ const RegisterPayloadSchema = object({
46
+ name: string().min(1).max(100),
47
+ capabilities: array(string()).optional(),
48
+ token: string().optional()
49
49
  });
50
- const JoinGroupPayloadSchema = z.object({
51
- groupId: z.string().optional(),
52
- groupName: z.string().min(1).max(100).optional(),
53
- createIfNotExists: z.boolean().optional(),
54
- description: z.string().max(500).optional()
50
+ const JoinGroupPayloadSchema = object({
51
+ groupId: string().optional(),
52
+ groupName: string().min(1).max(100).optional(),
53
+ createIfNotExists: external_zod_boolean().optional(),
54
+ description: string().max(500).optional()
55
55
  });
56
- const BroadcastPayloadSchema = z.object({
57
- groupId: z.string().min(1),
58
- message: z.unknown()
56
+ const BroadcastPayloadSchema = object({
57
+ groupId: string().min(1),
58
+ message: unknown()
59
59
  });
60
- const DirectPayloadSchema = z.object({
61
- targetNodeId: z.string().min(1),
62
- message: z.unknown()
60
+ const DirectPayloadSchema = object({
61
+ targetNodeId: string().min(1),
62
+ message: unknown()
63
63
  });
64
- const ErrorPayloadSchema = z.object({
65
- code: z.string().min(1),
66
- message: z.string().min(1),
67
- details: z.unknown().optional()
64
+ const ErrorPayloadSchema = object({
65
+ code: string().min(1),
66
+ message: string().min(1),
67
+ details: unknown().optional()
68
68
  });
69
69
  function validateGatewayMessage(data) {
70
70
  try {
@@ -40,6 +40,7 @@ const additional_messages_cjs_namespaceObject = require("../agent/middleware/add
40
40
  (0, external_vitest_namespaceObject.expect)(result.messages).toHaveLength(2);
41
41
  const injected = result.messages[0];
42
42
  (0, external_vitest_namespaceObject.expect)(injected.additional_kwargs?.source).toBe("additional-message-middleware");
43
+ (0, external_vitest_namespaceObject.expect)(injected).toBeInstanceOf(external_langchain_namespaceObject.HumanMessage);
43
44
  });
44
45
  (0, external_vitest_namespaceObject.it)("adds confidentiality guidance without exposing machine details", async ()=>{
45
46
  const workspaceRoot = external_node_path_default().resolve("repo");
@@ -59,7 +60,9 @@ const additional_messages_cjs_namespaceObject = require("../agent/middleware/add
59
60
  const injected = result.messages[0];
60
61
  const content = injected.content ?? "";
61
62
  (0, external_vitest_namespaceObject.expect)(content).toContain("Confidentiality");
63
+ (0, external_vitest_namespaceObject.expect)(content).toContain("inspect system/tool output internally");
62
64
  (0, external_vitest_namespaceObject.expect)(content).toContain("Do not disclose");
65
+ (0, external_vitest_namespaceObject.expect)(content).toContain("Do not quote internal tool call IDs");
63
66
  (0, external_vitest_namespaceObject.expect)(content).toContain("Working Directory");
64
67
  (0, external_vitest_namespaceObject.expect)(content).toContain("current working directory");
65
68
  (0, external_vitest_namespaceObject.expect)(content).toContain("Use relative paths");
@@ -16,6 +16,7 @@ describe("additionalMessageMiddleware", ()=>{
16
16
  expect(result.messages).toHaveLength(2);
17
17
  const injected = result.messages[0];
18
18
  expect(injected.additional_kwargs?.source).toBe("additional-message-middleware");
19
+ expect(injected).toBeInstanceOf(HumanMessage);
19
20
  });
20
21
  it("adds confidentiality guidance without exposing machine details", async ()=>{
21
22
  const workspaceRoot = node_path.resolve("repo");
@@ -35,7 +36,9 @@ describe("additionalMessageMiddleware", ()=>{
35
36
  const injected = result.messages[0];
36
37
  const content = injected.content ?? "";
37
38
  expect(content).toContain("Confidentiality");
39
+ expect(content).toContain("inspect system/tool output internally");
38
40
  expect(content).toContain("Do not disclose");
41
+ expect(content).toContain("Do not quote internal tool call IDs");
39
42
  expect(content).toContain("Working Directory");
40
43
  expect(content).toContain("current working directory");
41
44
  expect(content).toContain("Use relative paths");