@wingman-ai/gateway 0.3.2 → 0.4.0

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 (51) hide show
  1. package/dist/agent/config/mcpClientManager.cjs +48 -9
  2. package/dist/agent/config/mcpClientManager.d.ts +12 -0
  3. package/dist/agent/config/mcpClientManager.js +48 -9
  4. package/dist/agent/tests/mcpClientManager.test.cjs +50 -0
  5. package/dist/agent/tests/mcpClientManager.test.js +50 -0
  6. package/dist/cli/commands/skill.cjs +12 -4
  7. package/dist/cli/commands/skill.js +12 -4
  8. package/dist/cli/config/jsonSchema.cjs +55 -0
  9. package/dist/cli/config/jsonSchema.d.ts +2 -0
  10. package/dist/cli/config/jsonSchema.js +18 -0
  11. package/dist/cli/config/loader.cjs +33 -1
  12. package/dist/cli/config/loader.js +33 -1
  13. package/dist/cli/config/schema.cjs +119 -2
  14. package/dist/cli/config/schema.d.ts +40 -0
  15. package/dist/cli/config/schema.js +119 -2
  16. package/dist/cli/core/agentInvoker.cjs +4 -1
  17. package/dist/cli/core/agentInvoker.d.ts +3 -0
  18. package/dist/cli/core/agentInvoker.js +4 -1
  19. package/dist/cli/services/skillRepository.cjs +138 -20
  20. package/dist/cli/services/skillRepository.d.ts +10 -2
  21. package/dist/cli/services/skillRepository.js +138 -20
  22. package/dist/cli/services/skillSecurityScanner.cjs +158 -0
  23. package/dist/cli/services/skillSecurityScanner.d.ts +28 -0
  24. package/dist/cli/services/skillSecurityScanner.js +121 -0
  25. package/dist/cli/services/skillService.cjs +44 -12
  26. package/dist/cli/services/skillService.d.ts +2 -0
  27. package/dist/cli/services/skillService.js +46 -14
  28. package/dist/cli/types/skill.d.ts +9 -0
  29. package/dist/gateway/server.cjs +5 -1
  30. package/dist/gateway/server.js +5 -1
  31. package/dist/gateway/types.d.ts +9 -0
  32. package/dist/tests/cli-config-loader.test.cjs +33 -1
  33. package/dist/tests/cli-config-loader.test.js +33 -1
  34. package/dist/tests/config-json-schema.test.cjs +25 -0
  35. package/dist/tests/config-json-schema.test.d.ts +1 -0
  36. package/dist/tests/config-json-schema.test.js +19 -0
  37. package/dist/tests/skill-repository.test.cjs +106 -0
  38. package/dist/tests/skill-repository.test.d.ts +1 -0
  39. package/dist/tests/skill-repository.test.js +100 -0
  40. package/dist/tests/skill-security-scanner.test.cjs +126 -0
  41. package/dist/tests/skill-security-scanner.test.d.ts +1 -0
  42. package/dist/tests/skill-security-scanner.test.js +120 -0
  43. package/dist/tests/uv.test.cjs +47 -0
  44. package/dist/tests/uv.test.d.ts +1 -0
  45. package/dist/tests/uv.test.js +41 -0
  46. package/dist/utils/uv.cjs +64 -0
  47. package/dist/utils/uv.d.ts +3 -0
  48. package/dist/utils/uv.js +24 -0
  49. package/package.json +2 -1
  50. package/skills/gog/SKILL.md +36 -0
  51. package/skills/weather/SKILL.md +49 -0
@@ -52,15 +52,7 @@ class MCPClientManager {
52
52
  for (const [key, value] of Object.entries(stdioServer.env || {}))resolvedEnv[key] = resolveEnvValue(value);
53
53
  const runtimeEnv = this.applyRuntimeEnv(resolvedEnv);
54
54
  const defaultToolTimeout = getDefaultToolTimeout(stdioServer);
55
- mcpServers[server.name] = {
56
- transport: "stdio",
57
- command: stdioServer.command,
58
- args: stdioServer.args || [],
59
- env: runtimeEnv,
60
- ...void 0 !== defaultToolTimeout ? {
61
- defaultToolTimeout
62
- } : {}
63
- };
55
+ mcpServers[server.name] = this.buildStdioServerConfig(stdioServer, runtimeEnv, defaultToolTimeout);
64
56
  } else if ("sse" === server.transport) {
65
57
  const sseServer = server;
66
58
  const defaultToolTimeout = getDefaultToolTimeout(sseServer);
@@ -83,6 +75,51 @@ class MCPClientManager {
83
75
  }
84
76
  };
85
77
  }
78
+ buildStdioServerConfig(server, env, defaultToolTimeout) {
79
+ const baseConfig = {
80
+ transport: "stdio",
81
+ command: server.command,
82
+ args: server.args || [],
83
+ env,
84
+ ...void 0 !== defaultToolTimeout ? {
85
+ defaultToolTimeout
86
+ } : {}
87
+ };
88
+ if (!this.proxyConfig?.enabled) return baseConfig;
89
+ const proxyCommand = this.proxyConfig.command?.trim() || "uvx";
90
+ const proxyBaseArgs = this.proxyConfig.baseArgs && this.proxyConfig.baseArgs.length > 0 ? this.proxyConfig.baseArgs : [
91
+ "invariant-gateway@latest",
92
+ "mcp"
93
+ ];
94
+ const proxyEnv = {
95
+ ...env
96
+ };
97
+ if (this.proxyConfig.apiKey) proxyEnv.INVARIANT_API_KEY = this.proxyConfig.apiKey;
98
+ if (this.proxyConfig.apiUrl) {
99
+ proxyEnv.INVARIANT_API_URL = this.proxyConfig.apiUrl;
100
+ proxyEnv.GUARDRAILS_API_URL = this.proxyConfig.apiUrl;
101
+ }
102
+ const proxyArgs = [
103
+ ...proxyBaseArgs,
104
+ "--project-name",
105
+ this.proxyConfig.projectName || "wingman-gateway",
106
+ ...this.proxyConfig.pushExplorer ? [
107
+ "--push-explorer"
108
+ ] : [],
109
+ "--exec",
110
+ baseConfig.command,
111
+ ...baseConfig.args || []
112
+ ];
113
+ return {
114
+ transport: "stdio",
115
+ command: proxyCommand,
116
+ args: proxyArgs,
117
+ env: proxyEnv,
118
+ ...void 0 !== defaultToolTimeout ? {
119
+ defaultToolTimeout
120
+ } : {}
121
+ };
122
+ }
86
123
  applyRuntimeEnv(env) {
87
124
  if (!this.executionWorkspace) return env;
88
125
  const next = {
@@ -176,9 +213,11 @@ class MCPClientManager {
176
213
  _define_property(this, "logger", void 0);
177
214
  _define_property(this, "serverConfigs", void 0);
178
215
  _define_property(this, "executionWorkspace", void 0);
216
+ _define_property(this, "proxyConfig", void 0);
179
217
  this.logger = logger;
180
218
  this.serverConfigs = this.mergeConfigs(configs);
181
219
  this.executionWorkspace = options?.executionWorkspace?.trim() || null;
220
+ this.proxyConfig = options?.proxyConfig;
182
221
  }
183
222
  }
184
223
  function resolveEnvValue(value) {
@@ -1,6 +1,15 @@
1
1
  import type { StructuredTool } from "@langchain/core/tools";
2
2
  import type { Logger } from "@/logger.js";
3
3
  import type { MCPServersConfig } from "@/types/mcp.js";
4
+ export type MCPProxyConfig = {
5
+ enabled?: boolean;
6
+ command?: string;
7
+ baseArgs?: string[];
8
+ projectName?: string;
9
+ pushExplorer?: boolean;
10
+ apiKey?: string;
11
+ apiUrl?: string;
12
+ };
4
13
  /**
5
14
  * Manages MCP server connections and tool retrieval
6
15
  * Handles server lifecycle: initialization, tool loading, and cleanup
@@ -10,8 +19,10 @@ export declare class MCPClientManager {
10
19
  private logger;
11
20
  private serverConfigs;
12
21
  private executionWorkspace;
22
+ private proxyConfig;
13
23
  constructor(configs: MCPServersConfig[], logger: Logger, options?: {
14
24
  executionWorkspace?: string | null;
25
+ proxyConfig?: MCPProxyConfig;
15
26
  });
16
27
  /**
17
28
  * Merge multiple MCP configurations (global + agent-specific)
@@ -22,6 +33,7 @@ export declare class MCPClientManager {
22
33
  * Convert Wingman MCP config to MultiServerMCPClient format
23
34
  */
24
35
  private buildClientConfig;
36
+ private buildStdioServerConfig;
25
37
  private applyRuntimeEnv;
26
38
  /**
27
39
  * Initialize MCP client and connect to servers
@@ -24,15 +24,7 @@ class MCPClientManager {
24
24
  for (const [key, value] of Object.entries(stdioServer.env || {}))resolvedEnv[key] = resolveEnvValue(value);
25
25
  const runtimeEnv = this.applyRuntimeEnv(resolvedEnv);
26
26
  const defaultToolTimeout = getDefaultToolTimeout(stdioServer);
27
- mcpServers[server.name] = {
28
- transport: "stdio",
29
- command: stdioServer.command,
30
- args: stdioServer.args || [],
31
- env: runtimeEnv,
32
- ...void 0 !== defaultToolTimeout ? {
33
- defaultToolTimeout
34
- } : {}
35
- };
27
+ mcpServers[server.name] = this.buildStdioServerConfig(stdioServer, runtimeEnv, defaultToolTimeout);
36
28
  } else if ("sse" === server.transport) {
37
29
  const sseServer = server;
38
30
  const defaultToolTimeout = getDefaultToolTimeout(sseServer);
@@ -55,6 +47,51 @@ class MCPClientManager {
55
47
  }
56
48
  };
57
49
  }
50
+ buildStdioServerConfig(server, env, defaultToolTimeout) {
51
+ const baseConfig = {
52
+ transport: "stdio",
53
+ command: server.command,
54
+ args: server.args || [],
55
+ env,
56
+ ...void 0 !== defaultToolTimeout ? {
57
+ defaultToolTimeout
58
+ } : {}
59
+ };
60
+ if (!this.proxyConfig?.enabled) return baseConfig;
61
+ const proxyCommand = this.proxyConfig.command?.trim() || "uvx";
62
+ const proxyBaseArgs = this.proxyConfig.baseArgs && this.proxyConfig.baseArgs.length > 0 ? this.proxyConfig.baseArgs : [
63
+ "invariant-gateway@latest",
64
+ "mcp"
65
+ ];
66
+ const proxyEnv = {
67
+ ...env
68
+ };
69
+ if (this.proxyConfig.apiKey) proxyEnv.INVARIANT_API_KEY = this.proxyConfig.apiKey;
70
+ if (this.proxyConfig.apiUrl) {
71
+ proxyEnv.INVARIANT_API_URL = this.proxyConfig.apiUrl;
72
+ proxyEnv.GUARDRAILS_API_URL = this.proxyConfig.apiUrl;
73
+ }
74
+ const proxyArgs = [
75
+ ...proxyBaseArgs,
76
+ "--project-name",
77
+ this.proxyConfig.projectName || "wingman-gateway",
78
+ ...this.proxyConfig.pushExplorer ? [
79
+ "--push-explorer"
80
+ ] : [],
81
+ "--exec",
82
+ baseConfig.command,
83
+ ...baseConfig.args || []
84
+ ];
85
+ return {
86
+ transport: "stdio",
87
+ command: proxyCommand,
88
+ args: proxyArgs,
89
+ env: proxyEnv,
90
+ ...void 0 !== defaultToolTimeout ? {
91
+ defaultToolTimeout
92
+ } : {}
93
+ };
94
+ }
58
95
  applyRuntimeEnv(env) {
59
96
  if (!this.executionWorkspace) return env;
60
97
  const next = {
@@ -148,9 +185,11 @@ class MCPClientManager {
148
185
  _define_property(this, "logger", void 0);
149
186
  _define_property(this, "serverConfigs", void 0);
150
187
  _define_property(this, "executionWorkspace", void 0);
188
+ _define_property(this, "proxyConfig", void 0);
151
189
  this.logger = logger;
152
190
  this.serverConfigs = this.mergeConfigs(configs);
153
191
  this.executionWorkspace = options?.executionWorkspace?.trim() || null;
192
+ this.proxyConfig = options?.proxyConfig;
154
193
  }
155
194
  }
156
195
  function resolveEnvValue(value) {
@@ -117,6 +117,56 @@ const getClientConfig = (manager)=>manager.buildClientConfig();
117
117
  const clientConfig = getClientConfig(manager);
118
118
  (0, external_vitest_namespaceObject.expect)(clientConfig.mcpServers["fal-ai"].defaultToolTimeout).toBe(300000);
119
119
  });
120
+ (0, external_vitest_namespaceObject.it)("wraps stdio servers with proxy command when enabled", ()=>{
121
+ const configs = [
122
+ {
123
+ servers: [
124
+ {
125
+ name: "fal-ai",
126
+ transport: "stdio",
127
+ command: "bun",
128
+ args: [
129
+ "run",
130
+ "src/tools/mcp-fal-ai.ts"
131
+ ],
132
+ env: {
133
+ EXISTING: "value"
134
+ }
135
+ }
136
+ ]
137
+ }
138
+ ];
139
+ const manager = new mcpClientManager_cjs_namespaceObject.MCPClientManager(configs, testLogger, {
140
+ proxyConfig: {
141
+ enabled: true,
142
+ command: "uvx",
143
+ baseArgs: [
144
+ "invariant-gateway@latest",
145
+ "mcp"
146
+ ],
147
+ projectName: "wingman-gateway",
148
+ apiKey: "test-api-key",
149
+ apiUrl: "https://explorer.invariantlabs.ai"
150
+ }
151
+ });
152
+ const clientConfig = getClientConfig(manager);
153
+ const server = clientConfig.mcpServers["fal-ai"];
154
+ (0, external_vitest_namespaceObject.expect)(server.command).toBe("uvx");
155
+ (0, external_vitest_namespaceObject.expect)(server.args).toEqual([
156
+ "invariant-gateway@latest",
157
+ "mcp",
158
+ "--project-name",
159
+ "wingman-gateway",
160
+ "--exec",
161
+ "bun",
162
+ "run",
163
+ "src/tools/mcp-fal-ai.ts"
164
+ ]);
165
+ (0, external_vitest_namespaceObject.expect)(server.env.EXISTING).toBe("value");
166
+ (0, external_vitest_namespaceObject.expect)(server.env.INVARIANT_API_KEY).toBe("test-api-key");
167
+ (0, external_vitest_namespaceObject.expect)(server.env.INVARIANT_API_URL).toBe("https://explorer.invariantlabs.ai");
168
+ (0, external_vitest_namespaceObject.expect)(server.env.GUARDRAILS_API_URL).toBe("https://explorer.invariantlabs.ai");
169
+ });
120
170
  });
121
171
  for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
122
172
  Object.defineProperty(exports, '__esModule', {
@@ -115,4 +115,54 @@ describe("MCPClientManager runtime env", ()=>{
115
115
  const clientConfig = getClientConfig(manager);
116
116
  expect(clientConfig.mcpServers["fal-ai"].defaultToolTimeout).toBe(300000);
117
117
  });
118
+ it("wraps stdio servers with proxy command when enabled", ()=>{
119
+ const configs = [
120
+ {
121
+ servers: [
122
+ {
123
+ name: "fal-ai",
124
+ transport: "stdio",
125
+ command: "bun",
126
+ args: [
127
+ "run",
128
+ "src/tools/mcp-fal-ai.ts"
129
+ ],
130
+ env: {
131
+ EXISTING: "value"
132
+ }
133
+ }
134
+ ]
135
+ }
136
+ ];
137
+ const manager = new MCPClientManager(configs, testLogger, {
138
+ proxyConfig: {
139
+ enabled: true,
140
+ command: "uvx",
141
+ baseArgs: [
142
+ "invariant-gateway@latest",
143
+ "mcp"
144
+ ],
145
+ projectName: "wingman-gateway",
146
+ apiKey: "test-api-key",
147
+ apiUrl: "https://explorer.invariantlabs.ai"
148
+ }
149
+ });
150
+ const clientConfig = getClientConfig(manager);
151
+ const server = clientConfig.mcpServers["fal-ai"];
152
+ expect(server.command).toBe("uvx");
153
+ expect(server.args).toEqual([
154
+ "invariant-gateway@latest",
155
+ "mcp",
156
+ "--project-name",
157
+ "wingman-gateway",
158
+ "--exec",
159
+ "bun",
160
+ "run",
161
+ "src/tools/mcp-fal-ai.ts"
162
+ ]);
163
+ expect(server.env.EXISTING).toBe("value");
164
+ expect(server.env.INVARIANT_API_KEY).toBe("test-api-key");
165
+ expect(server.env.INVARIANT_API_URL).toBe("https://explorer.invariantlabs.ai");
166
+ expect(server.env.GUARDRAILS_API_URL).toBe("https://explorer.invariantlabs.ai");
167
+ });
118
168
  });
@@ -41,14 +41,17 @@ async function executeSkillCommand(args, options = {}) {
41
41
  const config = configLoader.loadConfig();
42
42
  try {
43
43
  const repository = new skillRepository_cjs_namespaceObject.SkillRepository({
44
+ provider: config.skills?.provider,
44
45
  repositoryOwner: config.skills?.repositoryOwner,
45
46
  repositoryName: config.skills?.repositoryName,
46
- githubToken: config.skills?.githubToken
47
+ githubToken: config.skills?.githubToken,
48
+ clawhubBaseUrl: config.skills?.clawhubBaseUrl
47
49
  });
48
50
  const service = new skillService_cjs_namespaceObject.SkillService(repository, outputManager, logger, {
49
51
  workspace,
50
52
  skillsDirectory: config.skills?.skillsDirectory,
51
- outputMode: args.outputMode
53
+ outputMode: args.outputMode,
54
+ security: config.skills?.security
52
55
  });
53
56
  const subcommand = args.subcommand;
54
57
  const subcommandArgs = args.args;
@@ -100,7 +103,7 @@ async function executeSkillCommand(args, options = {}) {
100
103
  }
101
104
  function showSkillHelp(outputManager) {
102
105
  if ("interactive" === outputManager.getMode()) console.log(`
103
- Wingman Skill Manager - Install skills from the Anthropic skills repository
106
+ Wingman Skill Manager - Install skills from configured registries
104
107
 
105
108
  Usage:
106
109
  wingman skill browse Browse available skills
@@ -123,10 +126,15 @@ Configuration:
123
126
  Skills can be configured in .wingman/wingman.config.json:
124
127
  {
125
128
  "skills": {
129
+ "provider": "github",
126
130
  "repositoryOwner": "anthropics",
127
131
  "repositoryName": "skills",
128
132
  "githubToken": "optional-token",
129
- "skillsDirectory": "skills"
133
+ "clawhubBaseUrl": "https://clawhub.ai",
134
+ "skillsDirectory": "skills",
135
+ "security": {
136
+ "scanOnInstall": true
137
+ }
130
138
  }
131
139
  }
132
140
  `);
@@ -13,14 +13,17 @@ async function executeSkillCommand(args, options = {}) {
13
13
  const config = configLoader.loadConfig();
14
14
  try {
15
15
  const repository = new SkillRepository({
16
+ provider: config.skills?.provider,
16
17
  repositoryOwner: config.skills?.repositoryOwner,
17
18
  repositoryName: config.skills?.repositoryName,
18
- githubToken: config.skills?.githubToken
19
+ githubToken: config.skills?.githubToken,
20
+ clawhubBaseUrl: config.skills?.clawhubBaseUrl
19
21
  });
20
22
  const service = new SkillService(repository, outputManager, logger, {
21
23
  workspace,
22
24
  skillsDirectory: config.skills?.skillsDirectory,
23
- outputMode: args.outputMode
25
+ outputMode: args.outputMode,
26
+ security: config.skills?.security
24
27
  });
25
28
  const subcommand = args.subcommand;
26
29
  const subcommandArgs = args.args;
@@ -72,7 +75,7 @@ async function executeSkillCommand(args, options = {}) {
72
75
  }
73
76
  function showSkillHelp(outputManager) {
74
77
  if ("interactive" === outputManager.getMode()) console.log(`
75
- Wingman Skill Manager - Install skills from the Anthropic skills repository
78
+ Wingman Skill Manager - Install skills from configured registries
76
79
 
77
80
  Usage:
78
81
  wingman skill browse Browse available skills
@@ -95,10 +98,15 @@ Configuration:
95
98
  Skills can be configured in .wingman/wingman.config.json:
96
99
  {
97
100
  "skills": {
101
+ "provider": "github",
98
102
  "repositoryOwner": "anthropics",
99
103
  "repositoryName": "skills",
100
104
  "githubToken": "optional-token",
101
- "skillsDirectory": "skills"
105
+ "clawhubBaseUrl": "https://clawhub.ai",
106
+ "skillsDirectory": "skills",
107
+ "security": {
108
+ "scanOnInstall": true
109
+ }
102
110
  }
103
111
  }
104
112
  `);
@@ -0,0 +1,55 @@
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
+ buildWingmanConfigJsonSchema: ()=>buildWingmanConfigJsonSchema,
28
+ WINGMAN_CONFIG_JSON_SCHEMA_ID: ()=>WINGMAN_CONFIG_JSON_SCHEMA_ID
29
+ });
30
+ const external_zod_namespaceObject = require("zod");
31
+ const external_schema_cjs_namespaceObject = require("./schema.cjs");
32
+ const WINGMAN_CONFIG_JSON_SCHEMA_ID = "https://getwingmanai.com/schemas/wingman.config.schema.json";
33
+ function buildWingmanConfigJsonSchema() {
34
+ const schema = external_zod_namespaceObject.toJSONSchema(external_schema_cjs_namespaceObject.WingmanConfigSchema, {
35
+ target: "draft-2020-12",
36
+ unrepresentable: "any"
37
+ });
38
+ const { $schema: _ignored, ...schemaWithoutMeta } = schema;
39
+ return {
40
+ $schema: "https://json-schema.org/draft/2020-12/schema",
41
+ $id: WINGMAN_CONFIG_JSON_SCHEMA_ID,
42
+ title: "Wingman Config",
43
+ description: "Schema for .wingman/wingman.config.json",
44
+ ...schemaWithoutMeta
45
+ };
46
+ }
47
+ exports.WINGMAN_CONFIG_JSON_SCHEMA_ID = __webpack_exports__.WINGMAN_CONFIG_JSON_SCHEMA_ID;
48
+ exports.buildWingmanConfigJsonSchema = __webpack_exports__.buildWingmanConfigJsonSchema;
49
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
50
+ "WINGMAN_CONFIG_JSON_SCHEMA_ID",
51
+ "buildWingmanConfigJsonSchema"
52
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
53
+ Object.defineProperty(exports, '__esModule', {
54
+ value: true
55
+ });
@@ -0,0 +1,2 @@
1
+ export declare const WINGMAN_CONFIG_JSON_SCHEMA_ID = "https://getwingmanai.com/schemas/wingman.config.schema.json";
2
+ export declare function buildWingmanConfigJsonSchema(): Record<string, unknown>;
@@ -0,0 +1,18 @@
1
+ import { toJSONSchema } from "zod";
2
+ import { WingmanConfigSchema } from "./schema.js";
3
+ const WINGMAN_CONFIG_JSON_SCHEMA_ID = "https://getwingmanai.com/schemas/wingman.config.schema.json";
4
+ function buildWingmanConfigJsonSchema() {
5
+ const schema = toJSONSchema(WingmanConfigSchema, {
6
+ target: "draft-2020-12",
7
+ unrepresentable: "any"
8
+ });
9
+ const { $schema: _ignored, ...schemaWithoutMeta } = schema;
10
+ return {
11
+ $schema: "https://json-schema.org/draft/2020-12/schema",
12
+ $id: WINGMAN_CONFIG_JSON_SCHEMA_ID,
13
+ title: "Wingman Config",
14
+ description: "Schema for .wingman/wingman.config.json",
15
+ ...schemaWithoutMeta
16
+ };
17
+ }
18
+ export { WINGMAN_CONFIG_JSON_SCHEMA_ID, buildWingmanConfigJsonSchema };
@@ -133,9 +133,31 @@ class WingmanConfigLoader {
133
133
  outputMode: "auto"
134
134
  },
135
135
  skills: {
136
+ provider: "github",
136
137
  repositoryOwner: "anthropics",
137
138
  repositoryName: "skills",
138
- skillsDirectory: "skills"
139
+ clawhubBaseUrl: "https://clawhub.ai",
140
+ skillsDirectory: "skills",
141
+ security: {
142
+ scanOnInstall: true,
143
+ scannerCommand: "uvx",
144
+ scannerArgs: [
145
+ "--from",
146
+ "mcp-scan>=0.4,<0.5",
147
+ "mcp-scan",
148
+ "--json",
149
+ "--skills"
150
+ ],
151
+ blockIssueCodes: [
152
+ "MCP501",
153
+ "MCP506",
154
+ "MCP507",
155
+ "MCP508",
156
+ "MCP509",
157
+ "MCP510",
158
+ "MCP511"
159
+ ]
160
+ }
139
161
  },
140
162
  browser: {
141
163
  profilesDir: ".wingman/browser-profiles",
@@ -167,6 +189,16 @@ class WingmanConfigLoader {
167
189
  allowInsecureAuth: false
168
190
  },
169
191
  dynamicUiEnabled: true,
192
+ mcpProxy: {
193
+ enabled: false,
194
+ command: "uvx",
195
+ baseArgs: [
196
+ "invariant-gateway@latest",
197
+ "mcp"
198
+ ],
199
+ projectName: "wingman-gateway",
200
+ pushExplorer: false
201
+ },
170
202
  adapters: {}
171
203
  },
172
204
  agents: {
@@ -105,9 +105,31 @@ class WingmanConfigLoader {
105
105
  outputMode: "auto"
106
106
  },
107
107
  skills: {
108
+ provider: "github",
108
109
  repositoryOwner: "anthropics",
109
110
  repositoryName: "skills",
110
- skillsDirectory: "skills"
111
+ clawhubBaseUrl: "https://clawhub.ai",
112
+ skillsDirectory: "skills",
113
+ security: {
114
+ scanOnInstall: true,
115
+ scannerCommand: "uvx",
116
+ scannerArgs: [
117
+ "--from",
118
+ "mcp-scan>=0.4,<0.5",
119
+ "mcp-scan",
120
+ "--json",
121
+ "--skills"
122
+ ],
123
+ blockIssueCodes: [
124
+ "MCP501",
125
+ "MCP506",
126
+ "MCP507",
127
+ "MCP508",
128
+ "MCP509",
129
+ "MCP510",
130
+ "MCP511"
131
+ ]
132
+ }
111
133
  },
112
134
  browser: {
113
135
  profilesDir: ".wingman/browser-profiles",
@@ -139,6 +161,16 @@ class WingmanConfigLoader {
139
161
  allowInsecureAuth: false
140
162
  },
141
163
  dynamicUiEnabled: true,
164
+ mcpProxy: {
165
+ enabled: false,
166
+ command: "uvx",
167
+ baseArgs: [
168
+ "invariant-gateway@latest",
169
+ "mcp"
170
+ ],
171
+ projectName: "wingman-gateway",
172
+ pushExplorer: false
173
+ },
142
174
  adapters: {}
143
175
  },
144
176
  agents: {