@wingman-ai/gateway 0.4.1 → 0.4.3

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 (200) hide show
  1. package/README.md +14 -0
  2. package/dist/agent/config/mcpClientManager.cjs +104 -1
  3. package/dist/agent/config/mcpClientManager.d.ts +30 -0
  4. package/dist/agent/config/mcpClientManager.js +104 -1
  5. package/dist/agent/config/modelFactory.cjs +10 -0
  6. package/dist/agent/config/modelFactory.js +10 -0
  7. package/dist/agent/config/xaiImageModel.cjs +242 -0
  8. package/dist/agent/config/xaiImageModel.d.ts +33 -0
  9. package/dist/agent/config/xaiImageModel.js +202 -0
  10. package/dist/agent/tests/mcpClientManager.test.cjs +116 -0
  11. package/dist/agent/tests/mcpClientManager.test.js +117 -1
  12. package/dist/agent/tests/mcpResourceTools.test.cjs +101 -0
  13. package/dist/agent/tests/mcpResourceTools.test.d.ts +1 -0
  14. package/dist/agent/tests/mcpResourceTools.test.js +95 -0
  15. package/dist/agent/tests/modelFactory.test.cjs +16 -2
  16. package/dist/agent/tests/modelFactory.test.js +16 -2
  17. package/dist/agent/tests/xaiImageModel.test.cjs +194 -0
  18. package/dist/agent/tests/xaiImageModel.test.d.ts +1 -0
  19. package/dist/agent/tests/xaiImageModel.test.js +188 -0
  20. package/dist/agent/tools/mcp_resources.cjs +111 -0
  21. package/dist/agent/tools/mcp_resources.d.ts +3 -0
  22. package/dist/agent/tools/mcp_resources.js +77 -0
  23. package/dist/bench/adapters/commandAdapter.cjs +93 -0
  24. package/dist/bench/adapters/commandAdapter.d.ts +6 -0
  25. package/dist/bench/adapters/commandAdapter.js +59 -0
  26. package/dist/bench/adapters/helpers.cjs +170 -0
  27. package/dist/bench/adapters/helpers.d.ts +7 -0
  28. package/dist/bench/adapters/helpers.js +133 -0
  29. package/dist/bench/adapters/index.cjs +41 -0
  30. package/dist/bench/adapters/index.d.ts +2 -0
  31. package/dist/bench/adapters/index.js +7 -0
  32. package/dist/bench/adapters/wingmanCliAdapter.cjs +100 -0
  33. package/dist/bench/adapters/wingmanCliAdapter.d.ts +6 -0
  34. package/dist/bench/adapters/wingmanCliAdapter.js +66 -0
  35. package/dist/bench/cleanup.cjs +122 -0
  36. package/dist/bench/cleanup.d.ts +9 -0
  37. package/dist/bench/cleanup.js +85 -0
  38. package/dist/bench/config.cjs +190 -0
  39. package/dist/bench/config.d.ts +2 -0
  40. package/dist/bench/config.js +156 -0
  41. package/dist/bench/index.cjs +43 -0
  42. package/dist/bench/index.d.ts +3 -0
  43. package/dist/bench/index.js +3 -0
  44. package/dist/bench/official.cjs +616 -0
  45. package/dist/bench/official.d.ts +80 -0
  46. package/dist/bench/official.js +546 -0
  47. package/dist/bench/officialCli.cjs +204 -0
  48. package/dist/bench/officialCli.d.ts +5 -0
  49. package/dist/bench/officialCli.js +170 -0
  50. package/dist/bench/process.cjs +78 -0
  51. package/dist/bench/process.d.ts +14 -0
  52. package/dist/bench/process.js +44 -0
  53. package/dist/bench/runner.cjs +237 -0
  54. package/dist/bench/runner.d.ts +7 -0
  55. package/dist/bench/runner.js +197 -0
  56. package/dist/bench/scoring.cjs +171 -0
  57. package/dist/bench/scoring.d.ts +9 -0
  58. package/dist/bench/scoring.js +137 -0
  59. package/dist/bench/types.cjs +18 -0
  60. package/dist/bench/types.d.ts +200 -0
  61. package/dist/bench/types.js +0 -0
  62. package/dist/bench/validator.cjs +92 -0
  63. package/dist/bench/validator.d.ts +2 -0
  64. package/dist/bench/validator.js +58 -0
  65. package/dist/cli/commands/init.cjs +135 -1
  66. package/dist/cli/commands/init.js +136 -2
  67. package/dist/cli/commands/skill.cjs +7 -3
  68. package/dist/cli/commands/skill.js +7 -3
  69. package/dist/cli/config/loader.cjs +7 -3
  70. package/dist/cli/config/loader.js +7 -3
  71. package/dist/cli/config/schema.cjs +63 -10
  72. package/dist/cli/config/schema.d.ts +64 -4
  73. package/dist/cli/config/schema.js +59 -9
  74. package/dist/cli/config/warnings.cjs +119 -51
  75. package/dist/cli/config/warnings.js +119 -51
  76. package/dist/cli/core/agentInvoker.cjs +58 -13
  77. package/dist/cli/core/agentInvoker.d.ts +1 -0
  78. package/dist/cli/core/agentInvoker.js +58 -13
  79. package/dist/cli/core/imagePersistence.cjs +17 -1
  80. package/dist/cli/core/imagePersistence.d.ts +2 -0
  81. package/dist/cli/core/imagePersistence.js +13 -3
  82. package/dist/cli/core/sessionManager.cjs +2 -0
  83. package/dist/cli/core/sessionManager.js +3 -1
  84. package/dist/cli/services/skillRepository.cjs +155 -69
  85. package/dist/cli/services/skillRepository.d.ts +7 -2
  86. package/dist/cli/services/skillRepository.js +155 -69
  87. package/dist/cli/services/skillService.cjs +93 -26
  88. package/dist/cli/services/skillService.d.ts +7 -0
  89. package/dist/cli/services/skillService.js +96 -29
  90. package/dist/cli/types/skill.d.ts +8 -3
  91. package/dist/cli/types.d.ts +18 -0
  92. package/dist/gateway/adapters/teams.cjs +419 -0
  93. package/dist/gateway/adapters/teams.d.ts +47 -0
  94. package/dist/gateway/adapters/teams.js +361 -0
  95. package/dist/gateway/http/sms.cjs +286 -0
  96. package/dist/gateway/http/sms.d.ts +4 -0
  97. package/dist/gateway/http/sms.js +249 -0
  98. package/dist/gateway/server.cjs +54 -3
  99. package/dist/gateway/server.d.ts +2 -0
  100. package/dist/gateway/server.js +54 -3
  101. package/dist/gateway/sms/commands.cjs +116 -0
  102. package/dist/gateway/sms/commands.d.ts +15 -0
  103. package/dist/gateway/sms/commands.js +79 -0
  104. package/dist/gateway/sms/control.cjs +118 -0
  105. package/dist/gateway/sms/control.d.ts +18 -0
  106. package/dist/gateway/sms/control.js +84 -0
  107. package/dist/gateway/sms/policyStore.cjs +198 -0
  108. package/dist/gateway/sms/policyStore.d.ts +37 -0
  109. package/dist/gateway/sms/policyStore.js +161 -0
  110. package/dist/providers/registry.cjs +1 -0
  111. package/dist/providers/registry.js +1 -0
  112. package/dist/skills/activation.cjs +92 -0
  113. package/dist/skills/activation.d.ts +12 -0
  114. package/dist/skills/activation.js +58 -0
  115. package/dist/skills/bin-requirements.cjs +63 -0
  116. package/dist/skills/bin-requirements.d.ts +3 -0
  117. package/dist/skills/bin-requirements.js +26 -0
  118. package/dist/skills/metadata.cjs +141 -0
  119. package/dist/skills/metadata.d.ts +29 -0
  120. package/dist/skills/metadata.js +104 -0
  121. package/dist/skills/overlay.cjs +75 -0
  122. package/dist/skills/overlay.d.ts +2 -0
  123. package/dist/skills/overlay.js +38 -0
  124. package/dist/tests/cli-config-loader.test.cjs +7 -3
  125. package/dist/tests/cli-config-loader.test.js +7 -3
  126. package/dist/tests/cli-config-warnings.test.cjs +41 -0
  127. package/dist/tests/cli-config-warnings.test.js +41 -0
  128. package/dist/tests/cli-init.test.cjs +86 -26
  129. package/dist/tests/cli-init.test.js +86 -26
  130. package/dist/tests/config-json-schema.test.cjs +12 -0
  131. package/dist/tests/config-json-schema.test.js +12 -0
  132. package/dist/tests/gateway-http-security.test.cjs +21 -0
  133. package/dist/tests/gateway-http-security.test.js +21 -0
  134. package/dist/tests/gateway-origin-policy.test.cjs +22 -0
  135. package/dist/tests/gateway-origin-policy.test.js +22 -0
  136. package/dist/tests/gateway.test.cjs +57 -0
  137. package/dist/tests/gateway.test.js +57 -0
  138. package/dist/tests/imagePersistence.test.cjs +26 -0
  139. package/dist/tests/imagePersistence.test.js +27 -1
  140. package/dist/tests/run-terminal-bench-official-script.test.cjs +61 -0
  141. package/dist/tests/run-terminal-bench-official-script.test.d.ts +1 -0
  142. package/dist/tests/run-terminal-bench-official-script.test.js +55 -0
  143. package/dist/tests/sessions-api.test.cjs +69 -1
  144. package/dist/tests/sessions-api.test.js +70 -2
  145. package/dist/tests/skill-activation.test.cjs +86 -0
  146. package/dist/tests/skill-activation.test.d.ts +1 -0
  147. package/dist/tests/skill-activation.test.js +80 -0
  148. package/dist/tests/skill-metadata.test.cjs +119 -0
  149. package/dist/tests/skill-metadata.test.d.ts +1 -0
  150. package/dist/tests/skill-metadata.test.js +113 -0
  151. package/dist/tests/skill-repository.test.cjs +363 -0
  152. package/dist/tests/skill-repository.test.js +363 -0
  153. package/dist/tests/sms-api.test.cjs +183 -0
  154. package/dist/tests/sms-api.test.d.ts +1 -0
  155. package/dist/tests/sms-api.test.js +177 -0
  156. package/dist/tests/sms-commands.test.cjs +90 -0
  157. package/dist/tests/sms-commands.test.d.ts +1 -0
  158. package/dist/tests/sms-commands.test.js +84 -0
  159. package/dist/tests/sms-policy-store.test.cjs +69 -0
  160. package/dist/tests/sms-policy-store.test.d.ts +1 -0
  161. package/dist/tests/sms-policy-store.test.js +63 -0
  162. package/dist/tests/teams-adapter.test.cjs +58 -0
  163. package/dist/tests/teams-adapter.test.d.ts +1 -0
  164. package/dist/tests/teams-adapter.test.js +52 -0
  165. package/dist/tests/terminal-bench-adapters-helpers.test.cjs +64 -0
  166. package/dist/tests/terminal-bench-adapters-helpers.test.d.ts +1 -0
  167. package/dist/tests/terminal-bench-adapters-helpers.test.js +58 -0
  168. package/dist/tests/terminal-bench-cleanup.test.cjs +93 -0
  169. package/dist/tests/terminal-bench-cleanup.test.d.ts +1 -0
  170. package/dist/tests/terminal-bench-cleanup.test.js +87 -0
  171. package/dist/tests/terminal-bench-config.test.cjs +62 -0
  172. package/dist/tests/terminal-bench-config.test.d.ts +1 -0
  173. package/dist/tests/terminal-bench-config.test.js +56 -0
  174. package/dist/tests/terminal-bench-official.test.cjs +194 -0
  175. package/dist/tests/terminal-bench-official.test.d.ts +1 -0
  176. package/dist/tests/terminal-bench-official.test.js +188 -0
  177. package/dist/tests/terminal-bench-runner.test.cjs +82 -0
  178. package/dist/tests/terminal-bench-runner.test.d.ts +1 -0
  179. package/dist/tests/terminal-bench-runner.test.js +76 -0
  180. package/dist/tests/terminal-bench-scoring.test.cjs +128 -0
  181. package/dist/tests/terminal-bench-scoring.test.d.ts +1 -0
  182. package/dist/tests/terminal-bench-scoring.test.js +122 -0
  183. package/dist/tools/mcp-fal-ai.cjs +1 -1
  184. package/dist/tools/mcp-fal-ai.js +1 -1
  185. package/dist/webui/assets/index-Cyg_Hs57.css +11 -0
  186. package/dist/webui/assets/{index-BMekSELC.js → index-DZXLLjaA.js} +109 -109
  187. package/dist/webui/index.html +2 -2
  188. package/package.json +14 -5
  189. package/skills/gog/SKILL.md +1 -1
  190. package/skills/weather/SKILL.md +1 -1
  191. package/templates/agents/game-dev/agent.md +122 -63
  192. package/templates/agents/game-dev/art-director.md +106 -0
  193. package/templates/agents/game-dev/game-designer.md +87 -0
  194. package/templates/agents/game-dev/scene-engineer.md +474 -0
  195. package/dist/webui/assets/index-Cwkg4DKj.css +0 -11
  196. package/skills/ui-registry/SKILL.md +0 -35
  197. package/templates/agents/game-dev/art-generation.md +0 -38
  198. package/templates/agents/game-dev/asset-refinement.md +0 -17
  199. package/templates/agents/game-dev/planning-idea.md +0 -17
  200. package/templates/agents/game-dev/ui-specialist.md +0 -17
@@ -0,0 +1,249 @@
1
+ import { applySmsControlCommand } from "../sms/control.js";
2
+ import { createSmsPolicyStore, normalizeSmsPolicyTarget } from "../sms/policyStore.js";
3
+ const MAX_PAUSE_FOR_MS = 2592000000;
4
+ const createSmsPolicyStateStore = (resolveConfigDirPath)=>createSmsPolicyStore(resolveConfigDirPath);
5
+ function decodeTarget(raw) {
6
+ let decoded = "";
7
+ try {
8
+ decoded = decodeURIComponent(raw);
9
+ } catch {
10
+ return null;
11
+ }
12
+ return normalizeSmsPolicyTarget(decoded);
13
+ }
14
+ function parsePauseForMs(raw) {
15
+ if ("number" != typeof raw || !Number.isFinite(raw)) return null;
16
+ const value = Math.trunc(raw);
17
+ if (value <= 0 || value > MAX_PAUSE_FOR_MS) return null;
18
+ return value;
19
+ }
20
+ function toResponsePayload(resolution, nowMs) {
21
+ return {
22
+ ...resolution,
23
+ policy: {
24
+ ...resolution.policy,
25
+ pauseExpiresInMs: resolution.policy.paused && resolution.policy.pausedUntil ? Math.max(resolution.policy.pausedUntil - nowMs, 0) : null
26
+ }
27
+ };
28
+ }
29
+ function parseRoutingTarget(rawTarget) {
30
+ const trimmed = rawTarget.trim();
31
+ if (!trimmed) return null;
32
+ const normalized = normalizeSmsPolicyTarget(trimmed);
33
+ if (!normalized) return null;
34
+ const separatorIndex = normalized.indexOf(":");
35
+ let channel = "sms-macos";
36
+ let peerId = normalized;
37
+ if (separatorIndex > 0 && separatorIndex < normalized.length - 1) {
38
+ const candidateChannel = normalized.slice(0, separatorIndex).trim();
39
+ const candidatePeer = normalized.slice(separatorIndex + 1).trim();
40
+ if (candidateChannel && candidatePeer) {
41
+ channel = candidateChannel;
42
+ peerId = candidatePeer;
43
+ }
44
+ }
45
+ return {
46
+ normalizedTarget: normalized,
47
+ routing: {
48
+ channel,
49
+ peer: {
50
+ kind: "dm",
51
+ id: peerId
52
+ }
53
+ }
54
+ };
55
+ }
56
+ const handleSmsApi = async (ctx, store, req, url)=>{
57
+ if ("/api/sms/messages" === url.pathname) {
58
+ if ("POST" !== req.method) return new Response("Method Not Allowed", {
59
+ status: 405
60
+ });
61
+ let body;
62
+ try {
63
+ body = await req.json();
64
+ } catch {
65
+ return new Response("Invalid JSON body", {
66
+ status: 400
67
+ });
68
+ }
69
+ const parsed = parseRoutingTarget("string" == typeof body.target ? body.target : "");
70
+ if (!parsed) return new Response("valid target required", {
71
+ status: 400
72
+ });
73
+ const nowMs = Date.now();
74
+ const text = "string" == typeof body.text ? body.text : "";
75
+ const control = applySmsControlCommand({
76
+ store,
77
+ target: parsed.normalizedTarget,
78
+ text,
79
+ nowMs
80
+ });
81
+ if (control.handled) return new Response(JSON.stringify({
82
+ kind: "command",
83
+ ...toResponsePayload(control, nowMs)
84
+ }, null, 2), {
85
+ headers: {
86
+ "Content-Type": "application/json"
87
+ }
88
+ });
89
+ if (!control.passThroughText.trim()) return new Response("text required", {
90
+ status: 400
91
+ });
92
+ if (control.policy.stopEnabled) return new Response(JSON.stringify({
93
+ kind: "stopped",
94
+ responseText: "SMS chat is stopped for this sender. Re-enable in Wingman settings/API.",
95
+ policy: control.policy
96
+ }, null, 2), {
97
+ headers: {
98
+ "Content-Type": "application/json"
99
+ }
100
+ });
101
+ const routing = {
102
+ ...parsed.routing
103
+ };
104
+ if ("string" == typeof body.accountId && body.accountId.trim()) routing.accountId = body.accountId.trim();
105
+ if ("string" == typeof body.threadId && body.threadId.trim()) routing.threadId = body.threadId.trim();
106
+ const selectedAgentId = ctx.router.selectAgent("string" == typeof body.agentId ? body.agentId.trim() : void 0, routing);
107
+ if (!selectedAgentId) return new Response("Unable to resolve agent", {
108
+ status: 400
109
+ });
110
+ const explicitSessionKey = "string" == typeof body.sessionKey ? body.sessionKey.trim() : "";
111
+ const sessionKey = explicitSessionKey || ctx.router.buildSessionKey(selectedAgentId, routing);
112
+ const request = {
113
+ agentId: selectedAgentId,
114
+ content: control.passThroughText,
115
+ routing,
116
+ sessionKey
117
+ };
118
+ if ("boolean" == typeof body.queueIfBusy) request.queueIfBusy = body.queueIfBusy;
119
+ return new Response(JSON.stringify({
120
+ kind: "agent",
121
+ target: parsed.normalizedTarget,
122
+ policy: control.policy,
123
+ request
124
+ }, null, 2), {
125
+ headers: {
126
+ "Content-Type": "application/json"
127
+ }
128
+ });
129
+ }
130
+ if ("/api/sms/policies" === url.pathname && "GET" === req.method) {
131
+ const targetRaw = url.searchParams.get("target");
132
+ if (targetRaw) {
133
+ const target = normalizeSmsPolicyTarget(targetRaw);
134
+ if (!target) return new Response("valid target query required", {
135
+ status: 400
136
+ });
137
+ const record = store.resolve(target);
138
+ return new Response(JSON.stringify(record, null, 2), {
139
+ headers: {
140
+ "Content-Type": "application/json"
141
+ }
142
+ });
143
+ }
144
+ const policies = store.list();
145
+ return new Response(JSON.stringify({
146
+ policies
147
+ }, null, 2), {
148
+ headers: {
149
+ "Content-Type": "application/json"
150
+ }
151
+ });
152
+ }
153
+ const commandMatch = url.pathname.match(/^\/api\/sms\/policies\/([^/]+)\/command$/);
154
+ if (commandMatch) {
155
+ if ("POST" !== req.method) return new Response("Method Not Allowed", {
156
+ status: 405
157
+ });
158
+ const target = decodeTarget(commandMatch[1]);
159
+ if (!target) return new Response("valid target required", {
160
+ status: 400
161
+ });
162
+ let body;
163
+ try {
164
+ body = await req.json();
165
+ } catch {
166
+ return new Response("Invalid JSON body", {
167
+ status: 400
168
+ });
169
+ }
170
+ const text = "string" == typeof body.text ? body.text : "";
171
+ const nowMs = "number" == typeof body.nowMs && Number.isFinite(body.nowMs) ? Math.trunc(body.nowMs) : Date.now();
172
+ const result = applySmsControlCommand({
173
+ store,
174
+ target,
175
+ text,
176
+ nowMs
177
+ });
178
+ return new Response(JSON.stringify(toResponsePayload(result, nowMs), null, 2), {
179
+ headers: {
180
+ "Content-Type": "application/json"
181
+ }
182
+ });
183
+ }
184
+ const targetMatch = url.pathname.match(/^\/api\/sms\/policies\/([^/]+)$/);
185
+ if (!targetMatch) return null;
186
+ const target = decodeTarget(targetMatch[1]);
187
+ if (!target) return new Response("valid target required", {
188
+ status: 400
189
+ });
190
+ if ("GET" === req.method) return new Response(JSON.stringify(store.resolve(target), null, 2), {
191
+ headers: {
192
+ "Content-Type": "application/json"
193
+ }
194
+ });
195
+ if ("DELETE" === req.method) {
196
+ store.reset(target);
197
+ return new Response(JSON.stringify(store.resolve(target), null, 2), {
198
+ headers: {
199
+ "Content-Type": "application/json"
200
+ }
201
+ });
202
+ }
203
+ if ("PUT" !== req.method) return new Response("Method Not Allowed", {
204
+ status: 405
205
+ });
206
+ let body;
207
+ try {
208
+ body = await req.json();
209
+ } catch {
210
+ return new Response("Invalid JSON body", {
211
+ status: 400
212
+ });
213
+ }
214
+ const patch = {};
215
+ const hasPauseForMs = Object.hasOwn(body ?? {}, "pauseForMs");
216
+ if (hasPauseForMs) {
217
+ const duration = parsePauseForMs(body.pauseForMs);
218
+ if (null === duration) return new Response("pauseForMs must be a positive duration", {
219
+ status: 400
220
+ });
221
+ const nowMs = Date.now();
222
+ patch.paused = true;
223
+ patch.pausedUntil = nowMs + duration;
224
+ }
225
+ if ("boolean" == typeof body.paused) patch.paused = body.paused;
226
+ if (Object.hasOwn(body ?? {}, "pausedUntil")) {
227
+ const value = body.pausedUntil;
228
+ if (null === value) {
229
+ patch.paused = false;
230
+ patch.pausedUntil = null;
231
+ } else {
232
+ if (!("number" == typeof value && Number.isFinite(value))) return new Response("pausedUntil must be a number or null", {
233
+ status: 400
234
+ });
235
+ patch.paused = true;
236
+ patch.pausedUntil = Math.trunc(value);
237
+ }
238
+ }
239
+ if ("boolean" == typeof body.stopEnabled) patch.stopEnabled = body.stopEnabled;
240
+ if ("off" === body.alertMode || "important-only" === body.alertMode || "all" === body.alertMode) patch.alertMode = body.alertMode;
241
+ if (Object.hasOwn(body ?? {}, "quietHours")) patch.quietHours = body.quietHours ?? null;
242
+ const updated = store.upsert(target, patch);
243
+ return new Response(JSON.stringify(updated, null, 2), {
244
+ headers: {
245
+ "Content-Type": "application/json"
246
+ }
247
+ });
248
+ };
249
+ export { createSmsPolicyStateStore, handleSmsApi };
@@ -45,6 +45,7 @@ const sessionManager_cjs_namespaceObject = require("../cli/core/sessionManager.c
45
45
  const external_logger_cjs_namespaceObject = require("../logger.cjs");
46
46
  const uv_cjs_namespaceObject = require("../utils/uv.cjs");
47
47
  const discord_cjs_namespaceObject = require("./adapters/discord.cjs");
48
+ const teams_cjs_namespaceObject = require("./adapters/teams.cjs");
48
49
  const external_auth_cjs_namespaceObject = require("./auth.cjs");
49
50
  const external_broadcast_cjs_namespaceObject = require("./broadcast.cjs");
50
51
  const external_browserRelayServer_cjs_namespaceObject = require("./browserRelayServer.cjs");
@@ -57,6 +58,7 @@ const nodes_cjs_namespaceObject = require("./http/nodes.cjs");
57
58
  const providers_cjs_namespaceObject = require("./http/providers.cjs");
58
59
  const routines_cjs_namespaceObject = require("./http/routines.cjs");
59
60
  const sessions_cjs_namespaceObject = require("./http/sessions.cjs");
61
+ const sms_cjs_namespaceObject = require("./http/sms.cjs");
60
62
  const voice_cjs_namespaceObject = require("./http/voice.cjs");
61
63
  const webhooks_cjs_namespaceObject = require("./http/webhooks.cjs");
62
64
  const external_node_cjs_namespaceObject = require("./node.cjs");
@@ -125,11 +127,14 @@ function isGatewayOriginAllowed(params) {
125
127
  } catch {
126
128
  return false;
127
129
  }
128
- if ("http:" !== originUrl.protocol && "https:" !== originUrl.protocol) return false;
130
+ const isHttpOriginProtocol = "http:" === originUrl.protocol || "https:" === originUrl.protocol;
131
+ const isTauriOriginProtocol = "tauri:" === originUrl.protocol;
132
+ if (!isHttpOriginProtocol && !isTauriOriginProtocol) return false;
129
133
  const originHost = normalizeHostname(originUrl.hostname);
130
134
  const requestHost = normalizeHostname(requestUrl.hostname);
131
135
  const configHost = normalizeHostname(params.gatewayHost);
132
136
  if (isLoopbackHostname(originHost) && isLoopbackHostname(requestHost)) return true;
137
+ if (!isHttpOriginProtocol) return false;
133
138
  if (!originHost || originHost !== requestHost) return false;
134
139
  const originPort = originUrl.port || defaultPortForProtocol(originUrl.protocol);
135
140
  const allowedPorts = new Set([
@@ -195,6 +200,10 @@ class GatewayServer {
195
200
  });
196
201
  return;
197
202
  }
203
+ if (this.teamsAdapter) {
204
+ const teamsResponse = await this.teamsAdapter.handleHttpRequest(req, url);
205
+ if (teamsResponse) return teamsResponse;
206
+ }
198
207
  if (url.pathname.startsWith("/api/")) return this.handleUiRequest(req);
199
208
  const webhookResponse = await (0, webhooks_cjs_namespaceObject.handleWebhookInvoke)(this.getHttpContext(), this.webhookStore, req, url);
200
209
  if (webhookResponse) return webhookResponse;
@@ -261,9 +270,9 @@ class GatewayServer {
261
270
  return this.boundPort ?? this.config.port;
262
271
  }
263
272
  async startAdapters() {
273
+ const resolvedHost = "0.0.0.0" === this.config.host || "::" === this.config.host ? "127.0.0.1" : this.config.host;
264
274
  const discordConfig = this.wingmanConfig.gateway?.adapters?.discord;
265
275
  if (discordConfig?.enabled) {
266
- const resolvedHost = "0.0.0.0" === this.config.host || "::" === this.config.host ? "127.0.0.1" : this.config.host;
267
276
  const url = discordConfig.gatewayUrl || `ws://${resolvedHost}:${this.config.port}/ws`;
268
277
  const token = discordConfig.gatewayToken || (this.config.auth?.mode === "token" ? this.config.authToken : void 0);
269
278
  const password = discordConfig.gatewayPassword || (this.config.auth?.mode === "password" ? this.config.auth?.password : void 0);
@@ -293,12 +302,51 @@ class GatewayServer {
293
302
  this.discordAdapter = null;
294
303
  }
295
304
  }
305
+ const teamsConfig = this.wingmanConfig.gateway?.adapters?.teams;
306
+ if (teamsConfig?.enabled) {
307
+ const url = teamsConfig.gatewayUrl || `ws://${resolvedHost}:${this.config.port}/ws`;
308
+ const token = teamsConfig.gatewayToken || (this.config.auth?.mode === "token" ? this.config.authToken : void 0);
309
+ const password = teamsConfig.gatewayPassword || (this.config.auth?.mode === "password" ? this.config.auth?.password : void 0);
310
+ this.teamsAdapter = new teams_cjs_namespaceObject.TeamsGatewayAdapter({
311
+ enabled: teamsConfig.enabled,
312
+ appId: teamsConfig.appId,
313
+ appPassword: teamsConfig.appPassword,
314
+ appType: teamsConfig.appType || "MultiTenant",
315
+ tenantId: teamsConfig.tenantId,
316
+ endpointPath: teamsConfig.endpointPath || "/api/adapters/teams/messages",
317
+ mentionOnly: teamsConfig.mentionOnly ?? true,
318
+ allowBots: teamsConfig.allowBots ?? false,
319
+ allowedTeamIds: teamsConfig.allowedTeamIds ?? [],
320
+ allowedChannelIds: teamsConfig.allowedChannelIds ?? [],
321
+ channelSessions: teamsConfig.channelSessions ?? {},
322
+ sessionCommand: teamsConfig.sessionCommand || "!session",
323
+ gatewayUrl: teamsConfig.gatewayUrl,
324
+ gatewayToken: teamsConfig.gatewayToken,
325
+ gatewayPassword: teamsConfig.gatewayPassword,
326
+ responseChunkSize: teamsConfig.responseChunkSize || 3500
327
+ }, {
328
+ url,
329
+ token,
330
+ password
331
+ }, this.logger);
332
+ try {
333
+ await this.teamsAdapter.start();
334
+ this.log("info", `Teams adapter started on ${this.config.host}:${this.config.port}${this.teamsAdapter.endpointPath}`);
335
+ } catch (error) {
336
+ this.log("error", "Failed to start Teams adapter", error);
337
+ this.teamsAdapter = null;
338
+ }
339
+ }
296
340
  }
297
341
  async stopAdapters() {
298
342
  if (this.discordAdapter) {
299
343
  await this.discordAdapter.stop();
300
344
  this.discordAdapter = null;
301
345
  }
346
+ if (this.teamsAdapter) {
347
+ await this.teamsAdapter.stop();
348
+ this.teamsAdapter = null;
349
+ }
302
350
  }
303
351
  async startDiscovery() {
304
352
  const discovery = this.config.discovery;
@@ -1612,7 +1660,7 @@ class GatewayServer {
1612
1660
  }
1613
1661
  }));
1614
1662
  }
1615
- const apiResponse = await (0, webhooks_cjs_namespaceObject.handleWebhooksApi)(ctx, this.webhookStore, req, url) || await (0, routines_cjs_namespaceObject.handleRoutinesApi)(ctx, this.routineStore, req, url) || await (0, nodes_cjs_namespaceObject.handleNodesApi)(ctx, this.nodeManager, this.nodeApprovalStore, req, url) || await (0, agents_cjs_namespaceObject.handleAgentsApi)(ctx, req, url) || await (0, providers_cjs_namespaceObject.handleProvidersApi)(ctx, req, url) || await (0, voice_cjs_namespaceObject.handleVoiceApi)(ctx, req, url) || await (0, fs_cjs_namespaceObject.handleFsApi)(ctx, req, url) || await (0, sessions_cjs_namespaceObject.handleSessionsApi)(ctx, req, url);
1663
+ const apiResponse = await (0, webhooks_cjs_namespaceObject.handleWebhooksApi)(ctx, this.webhookStore, req, url) || await (0, routines_cjs_namespaceObject.handleRoutinesApi)(ctx, this.routineStore, req, url) || await (0, sms_cjs_namespaceObject.handleSmsApi)(ctx, this.smsPolicyStore, req, url) || await (0, nodes_cjs_namespaceObject.handleNodesApi)(ctx, this.nodeManager, this.nodeApprovalStore, req, url) || await (0, agents_cjs_namespaceObject.handleAgentsApi)(ctx, req, url) || await (0, providers_cjs_namespaceObject.handleProvidersApi)(ctx, req, url) || await (0, voice_cjs_namespaceObject.handleVoiceApi)(ctx, req, url) || await (0, fs_cjs_namespaceObject.handleFsApi)(ctx, req, url) || await (0, sessions_cjs_namespaceObject.handleSessionsApi)(ctx, req, url);
1616
1664
  if (apiResponse) return this.withApiCors(req, url, apiResponse);
1617
1665
  if ("/api/health" === url.pathname) return this.withApiCors(req, url, this.handleHealthCheck());
1618
1666
  if ("/api/stats" === url.pathname) return this.withApiCors(req, url, this.handleStats());
@@ -1823,8 +1871,10 @@ class GatewayServer {
1823
1871
  _define_property(this, "webhookStore", void 0);
1824
1872
  _define_property(this, "routineStore", void 0);
1825
1873
  _define_property(this, "nodeApprovalStore", void 0);
1874
+ _define_property(this, "smsPolicyStore", void 0);
1826
1875
  _define_property(this, "internalHooks", null);
1827
1876
  _define_property(this, "discordAdapter", null);
1877
+ _define_property(this, "teamsAdapter", null);
1828
1878
  _define_property(this, "sessionSubscriptions", new Map());
1829
1879
  _define_property(this, "socketSubscriptions", new Map());
1830
1880
  _define_property(this, "connectedClients", new Set());
@@ -1845,6 +1895,7 @@ class GatewayServer {
1845
1895
  this.webhookStore = (0, webhooks_cjs_namespaceObject.createWebhookStore)(()=>this.resolveConfigDirPath());
1846
1896
  this.routineStore = (0, routines_cjs_namespaceObject.createRoutineStore)(()=>this.resolveConfigDirPath());
1847
1897
  this.nodeApprovalStore = (0, nodes_cjs_namespaceObject.createNodeApprovalStore)(()=>this.resolveConfigDirPath());
1898
+ this.smsPolicyStore = (0, sms_cjs_namespaceObject.createSmsPolicyStateStore)(()=>this.resolveConfigDirPath());
1848
1899
  const gatewayDefaults = this.wingmanConfig.gateway;
1849
1900
  const envToken = (0, external_env_cjs_namespaceObject.getGatewayTokenFromEnv)();
1850
1901
  const authFromConfig = config.auth?.mode === "token" ? {
@@ -41,8 +41,10 @@ export declare class GatewayServer {
41
41
  private webhookStore;
42
42
  private routineStore;
43
43
  private nodeApprovalStore;
44
+ private smsPolicyStore;
44
45
  private internalHooks;
45
46
  private discordAdapter;
47
+ private teamsAdapter;
46
48
  private sessionSubscriptions;
47
49
  private socketSubscriptions;
48
50
  private connectedClients;
@@ -10,6 +10,7 @@ import { SessionManager } from "../cli/core/sessionManager.js";
10
10
  import { createLogger } from "../logger.js";
11
11
  import { ensureUvAvailableForFeature } from "../utils/uv.js";
12
12
  import { DiscordGatewayAdapter } from "./adapters/discord.js";
13
+ import { TeamsGatewayAdapter } from "./adapters/teams.js";
13
14
  import { GatewayAuth } from "./auth.js";
14
15
  import { BroadcastGroupManager } from "./broadcast.js";
15
16
  import { BrowserRelayServer } from "./browserRelayServer.js";
@@ -22,6 +23,7 @@ import { createNodeApprovalStore, handleNodesApi } from "./http/nodes.js";
22
23
  import { handleProvidersApi } from "./http/providers.js";
23
24
  import { createRoutineStore, handleRoutinesApi } from "./http/routines.js";
24
25
  import { handleSessionsApi } from "./http/sessions.js";
26
+ import { createSmsPolicyStateStore, handleSmsApi } from "./http/sms.js";
25
27
  import { handleVoiceApi } from "./http/voice.js";
26
28
  import { createWebhookStore, handleWebhookInvoke, handleWebhooksApi } from "./http/webhooks.js";
27
29
  import { NodeManager } from "./node.js";
@@ -90,11 +92,14 @@ function isGatewayOriginAllowed(params) {
90
92
  } catch {
91
93
  return false;
92
94
  }
93
- if ("http:" !== originUrl.protocol && "https:" !== originUrl.protocol) return false;
95
+ const isHttpOriginProtocol = "http:" === originUrl.protocol || "https:" === originUrl.protocol;
96
+ const isTauriOriginProtocol = "tauri:" === originUrl.protocol;
97
+ if (!isHttpOriginProtocol && !isTauriOriginProtocol) return false;
94
98
  const originHost = normalizeHostname(originUrl.hostname);
95
99
  const requestHost = normalizeHostname(requestUrl.hostname);
96
100
  const configHost = normalizeHostname(params.gatewayHost);
97
101
  if (isLoopbackHostname(originHost) && isLoopbackHostname(requestHost)) return true;
102
+ if (!isHttpOriginProtocol) return false;
98
103
  if (!originHost || originHost !== requestHost) return false;
99
104
  const originPort = originUrl.port || defaultPortForProtocol(originUrl.protocol);
100
105
  const allowedPorts = new Set([
@@ -160,6 +165,10 @@ class GatewayServer {
160
165
  });
161
166
  return;
162
167
  }
168
+ if (this.teamsAdapter) {
169
+ const teamsResponse = await this.teamsAdapter.handleHttpRequest(req, url);
170
+ if (teamsResponse) return teamsResponse;
171
+ }
163
172
  if (url.pathname.startsWith("/api/")) return this.handleUiRequest(req);
164
173
  const webhookResponse = await handleWebhookInvoke(this.getHttpContext(), this.webhookStore, req, url);
165
174
  if (webhookResponse) return webhookResponse;
@@ -226,9 +235,9 @@ class GatewayServer {
226
235
  return this.boundPort ?? this.config.port;
227
236
  }
228
237
  async startAdapters() {
238
+ const resolvedHost = "0.0.0.0" === this.config.host || "::" === this.config.host ? "127.0.0.1" : this.config.host;
229
239
  const discordConfig = this.wingmanConfig.gateway?.adapters?.discord;
230
240
  if (discordConfig?.enabled) {
231
- const resolvedHost = "0.0.0.0" === this.config.host || "::" === this.config.host ? "127.0.0.1" : this.config.host;
232
241
  const url = discordConfig.gatewayUrl || `ws://${resolvedHost}:${this.config.port}/ws`;
233
242
  const token = discordConfig.gatewayToken || (this.config.auth?.mode === "token" ? this.config.authToken : void 0);
234
243
  const password = discordConfig.gatewayPassword || (this.config.auth?.mode === "password" ? this.config.auth?.password : void 0);
@@ -258,12 +267,51 @@ class GatewayServer {
258
267
  this.discordAdapter = null;
259
268
  }
260
269
  }
270
+ const teamsConfig = this.wingmanConfig.gateway?.adapters?.teams;
271
+ if (teamsConfig?.enabled) {
272
+ const url = teamsConfig.gatewayUrl || `ws://${resolvedHost}:${this.config.port}/ws`;
273
+ const token = teamsConfig.gatewayToken || (this.config.auth?.mode === "token" ? this.config.authToken : void 0);
274
+ const password = teamsConfig.gatewayPassword || (this.config.auth?.mode === "password" ? this.config.auth?.password : void 0);
275
+ this.teamsAdapter = new TeamsGatewayAdapter({
276
+ enabled: teamsConfig.enabled,
277
+ appId: teamsConfig.appId,
278
+ appPassword: teamsConfig.appPassword,
279
+ appType: teamsConfig.appType || "MultiTenant",
280
+ tenantId: teamsConfig.tenantId,
281
+ endpointPath: teamsConfig.endpointPath || "/api/adapters/teams/messages",
282
+ mentionOnly: teamsConfig.mentionOnly ?? true,
283
+ allowBots: teamsConfig.allowBots ?? false,
284
+ allowedTeamIds: teamsConfig.allowedTeamIds ?? [],
285
+ allowedChannelIds: teamsConfig.allowedChannelIds ?? [],
286
+ channelSessions: teamsConfig.channelSessions ?? {},
287
+ sessionCommand: teamsConfig.sessionCommand || "!session",
288
+ gatewayUrl: teamsConfig.gatewayUrl,
289
+ gatewayToken: teamsConfig.gatewayToken,
290
+ gatewayPassword: teamsConfig.gatewayPassword,
291
+ responseChunkSize: teamsConfig.responseChunkSize || 3500
292
+ }, {
293
+ url,
294
+ token,
295
+ password
296
+ }, this.logger);
297
+ try {
298
+ await this.teamsAdapter.start();
299
+ this.log("info", `Teams adapter started on ${this.config.host}:${this.config.port}${this.teamsAdapter.endpointPath}`);
300
+ } catch (error) {
301
+ this.log("error", "Failed to start Teams adapter", error);
302
+ this.teamsAdapter = null;
303
+ }
304
+ }
261
305
  }
262
306
  async stopAdapters() {
263
307
  if (this.discordAdapter) {
264
308
  await this.discordAdapter.stop();
265
309
  this.discordAdapter = null;
266
310
  }
311
+ if (this.teamsAdapter) {
312
+ await this.teamsAdapter.stop();
313
+ this.teamsAdapter = null;
314
+ }
267
315
  }
268
316
  async startDiscovery() {
269
317
  const discovery = this.config.discovery;
@@ -1577,7 +1625,7 @@ class GatewayServer {
1577
1625
  }
1578
1626
  }));
1579
1627
  }
1580
- const apiResponse = await handleWebhooksApi(ctx, this.webhookStore, req, url) || await handleRoutinesApi(ctx, this.routineStore, req, url) || await handleNodesApi(ctx, this.nodeManager, this.nodeApprovalStore, req, url) || await handleAgentsApi(ctx, req, url) || await handleProvidersApi(ctx, req, url) || await handleVoiceApi(ctx, req, url) || await handleFsApi(ctx, req, url) || await handleSessionsApi(ctx, req, url);
1628
+ const apiResponse = await handleWebhooksApi(ctx, this.webhookStore, req, url) || await handleRoutinesApi(ctx, this.routineStore, req, url) || await handleSmsApi(ctx, this.smsPolicyStore, req, url) || await handleNodesApi(ctx, this.nodeManager, this.nodeApprovalStore, req, url) || await handleAgentsApi(ctx, req, url) || await handleProvidersApi(ctx, req, url) || await handleVoiceApi(ctx, req, url) || await handleFsApi(ctx, req, url) || await handleSessionsApi(ctx, req, url);
1581
1629
  if (apiResponse) return this.withApiCors(req, url, apiResponse);
1582
1630
  if ("/api/health" === url.pathname) return this.withApiCors(req, url, this.handleHealthCheck());
1583
1631
  if ("/api/stats" === url.pathname) return this.withApiCors(req, url, this.handleStats());
@@ -1788,8 +1836,10 @@ class GatewayServer {
1788
1836
  _define_property(this, "webhookStore", void 0);
1789
1837
  _define_property(this, "routineStore", void 0);
1790
1838
  _define_property(this, "nodeApprovalStore", void 0);
1839
+ _define_property(this, "smsPolicyStore", void 0);
1791
1840
  _define_property(this, "internalHooks", null);
1792
1841
  _define_property(this, "discordAdapter", null);
1842
+ _define_property(this, "teamsAdapter", null);
1793
1843
  _define_property(this, "sessionSubscriptions", new Map());
1794
1844
  _define_property(this, "socketSubscriptions", new Map());
1795
1845
  _define_property(this, "connectedClients", new Set());
@@ -1810,6 +1860,7 @@ class GatewayServer {
1810
1860
  this.webhookStore = createWebhookStore(()=>this.resolveConfigDirPath());
1811
1861
  this.routineStore = createRoutineStore(()=>this.resolveConfigDirPath());
1812
1862
  this.nodeApprovalStore = createNodeApprovalStore(()=>this.resolveConfigDirPath());
1863
+ this.smsPolicyStore = createSmsPolicyStateStore(()=>this.resolveConfigDirPath());
1813
1864
  const gatewayDefaults = this.wingmanConfig.gateway;
1814
1865
  const envToken = getGatewayTokenFromEnv();
1815
1866
  const authFromConfig = config.auth?.mode === "token" ? {
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ buildSmsHelpMessage: ()=>buildSmsHelpMessage,
28
+ interpretSmsInboundMessage: ()=>interpretSmsInboundMessage
29
+ });
30
+ const MINUTE_MS = 60000;
31
+ const HOUR_MS = 60 * MINUTE_MS;
32
+ const DAY_MS = 24 * HOUR_MS;
33
+ const MAX_PAUSE_DURATION_MS = 30 * DAY_MS;
34
+ function parsePauseDurationMs(raw) {
35
+ const trimmed = raw.trim();
36
+ const match = trimmed.match(/^(\d+)\s*([mhd])$/i);
37
+ if (!match) return null;
38
+ const amount = Number(match[1]);
39
+ if (!Number.isInteger(amount) || amount <= 0) return null;
40
+ const unit = match[2].toLowerCase();
41
+ const multiplier = "m" === unit ? MINUTE_MS : "h" === unit ? HOUR_MS : DAY_MS;
42
+ const durationMs = amount * multiplier;
43
+ if (durationMs <= 0 || durationMs > MAX_PAUSE_DURATION_MS) return null;
44
+ return durationMs;
45
+ }
46
+ function interpretSmsInboundMessage(raw) {
47
+ const trimmed = raw.trim();
48
+ if (!trimmed) return {
49
+ type: "text",
50
+ content: ""
51
+ };
52
+ if (trimmed.startsWith("\\")) return {
53
+ type: "text",
54
+ content: trimmed.slice(1).trimStart()
55
+ };
56
+ const normalized = trimmed.toLowerCase();
57
+ if ("help" === normalized) return {
58
+ type: "command",
59
+ command: {
60
+ name: "help"
61
+ }
62
+ };
63
+ if ("status" === normalized) return {
64
+ type: "command",
65
+ command: {
66
+ name: "status"
67
+ }
68
+ };
69
+ if ("resume" === normalized) return {
70
+ type: "command",
71
+ command: {
72
+ name: "resume"
73
+ }
74
+ };
75
+ if ("stop" === normalized) return {
76
+ type: "command",
77
+ command: {
78
+ name: "stop"
79
+ }
80
+ };
81
+ const pauseMatch = trimmed.match(/^pause(?:\s+(.+))?$/i);
82
+ if (pauseMatch) {
83
+ const durationRaw = pauseMatch[1]?.trim();
84
+ if (!durationRaw) return {
85
+ type: "command",
86
+ command: {
87
+ name: "pause",
88
+ durationMs: null
89
+ }
90
+ };
91
+ const durationMs = parsePauseDurationMs(durationRaw);
92
+ if (null !== durationMs) return {
93
+ type: "command",
94
+ command: {
95
+ name: "pause",
96
+ durationMs
97
+ }
98
+ };
99
+ }
100
+ return {
101
+ type: "text",
102
+ content: trimmed
103
+ };
104
+ }
105
+ function buildSmsHelpMessage() {
106
+ return 'Commands:\n- STATUS\n- PAUSE [15m|2h|1d]\n- RESUME\n- STOP\n- HELP\nUse "\\<command>" to send a command word as normal text.';
107
+ }
108
+ exports.buildSmsHelpMessage = __webpack_exports__.buildSmsHelpMessage;
109
+ exports.interpretSmsInboundMessage = __webpack_exports__.interpretSmsInboundMessage;
110
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
111
+ "buildSmsHelpMessage",
112
+ "interpretSmsInboundMessage"
113
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
114
+ Object.defineProperty(exports, '__esModule', {
115
+ value: true
116
+ });
@@ -0,0 +1,15 @@
1
+ export type SmsControlCommand = {
2
+ name: "pause";
3
+ durationMs: number | null;
4
+ } | {
5
+ name: "resume" | "status" | "help" | "stop";
6
+ };
7
+ export type SmsInboundInterpretation = {
8
+ type: "text";
9
+ content: string;
10
+ } | {
11
+ type: "command";
12
+ command: SmsControlCommand;
13
+ };
14
+ export declare function interpretSmsInboundMessage(raw: string): SmsInboundInterpretation;
15
+ export declare function buildSmsHelpMessage(): string;