cognitive-modules-cli 1.2.0 → 1.3.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.
- package/README.md +21 -13
- package/dist/cli.js +35 -1
- package/dist/mcp/index.d.ts +4 -0
- package/dist/mcp/index.js +4 -0
- package/dist/mcp/server.d.ts +9 -0
- package/dist/mcp/server.js +344 -0
- package/dist/modules/index.d.ts +1 -0
- package/dist/modules/index.js +1 -0
- package/dist/modules/loader.js +7 -2
- package/dist/modules/runner.js +7 -2
- package/dist/modules/subagent.d.ts +65 -0
- package/dist/modules/subagent.js +185 -0
- package/dist/server/http.d.ts +20 -0
- package/dist/server/http.js +243 -0
- package/dist/server/index.d.ts +5 -0
- package/dist/server/index.js +4 -0
- package/package.json +4 -1
- package/src/cli.ts +36 -1
- package/src/mcp/index.ts +5 -0
- package/src/mcp/server.ts +403 -0
- package/src/modules/index.ts +1 -0
- package/src/modules/loader.ts +8 -2
- package/src/modules/runner.ts +6 -2
- package/src/modules/subagent.ts +275 -0
- package/src/server/http.ts +316 -0
- package/src/server/index.ts +6 -0
package/README.md
CHANGED
|
@@ -33,17 +33,20 @@ cog list
|
|
|
33
33
|
echo "review this code" | cog pipe --module code-reviewer
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
## 与 Python
|
|
36
|
+
## 与 Python 版的功能对比
|
|
37
37
|
|
|
38
38
|
| 功能 | Python (`cogn`) | Node.js (`cog`) |
|
|
39
39
|
|------|----------------|-----------------|
|
|
40
|
-
| 包名 | `cognitive-modules` | `cognitive-modules-cli` |
|
|
40
|
+
| 包名 | `cognitive-modules` | `cogn` / `cognitive-modules-cli` |
|
|
41
41
|
| 安装 | `pip install` | `npm install -g` |
|
|
42
|
-
| 子代理 | ✅ `@call:module` |
|
|
43
|
-
| MCP Server | ✅ |
|
|
44
|
-
| HTTP Server | ✅ |
|
|
42
|
+
| 子代理 | ✅ `@call:module` | ✅ `@call:module` |
|
|
43
|
+
| MCP Server | ✅ | ✅ |
|
|
44
|
+
| HTTP Server | ✅ | ✅ |
|
|
45
|
+
| v2.2 Envelope | ✅ | ✅ |
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
两个版本功能完全一致,共享相同的模块格式和 v2.2 规范。
|
|
48
|
+
|
|
49
|
+
**推荐使用 Node.js 版**:零安装快速体验 `npx cogn run ...`
|
|
47
50
|
|
|
48
51
|
## 支持的 Provider
|
|
49
52
|
|
|
@@ -61,14 +64,19 @@ echo "review this code" | cog pipe --module code-reviewer
|
|
|
61
64
|
## 命令
|
|
62
65
|
|
|
63
66
|
```bash
|
|
64
|
-
|
|
67
|
+
# 模块操作
|
|
68
|
+
cog list # 列出模块
|
|
65
69
|
cog run <module> --args "..." # 运行模块
|
|
66
|
-
cog add <url> -m <module>
|
|
67
|
-
cog update <module>
|
|
68
|
-
cog remove <module>
|
|
69
|
-
cog versions <url>
|
|
70
|
-
cog init <name>
|
|
71
|
-
cog pipe --module <name>
|
|
70
|
+
cog add <url> -m <module> # 从 GitHub 添加模块
|
|
71
|
+
cog update <module> # 更新模块
|
|
72
|
+
cog remove <module> # 删除模块
|
|
73
|
+
cog versions <url> # 查看可用版本
|
|
74
|
+
cog init <name> # 创建新模块
|
|
75
|
+
cog pipe --module <name> # 管道模式
|
|
76
|
+
|
|
77
|
+
# 服务器
|
|
78
|
+
cog serve --port 8000 # 启动 HTTP API 服务
|
|
79
|
+
cog mcp # 启动 MCP 服务(Claude Code / Cursor)
|
|
72
80
|
```
|
|
73
81
|
|
|
74
82
|
## 开发
|
package/dist/cli.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import { parseArgs } from 'node:util';
|
|
17
17
|
import { getProvider, listProviders } from './providers/index.js';
|
|
18
18
|
import { run, list, pipe, init, add, update, remove, versions } from './commands/index.js';
|
|
19
|
-
const VERSION = '1.0
|
|
19
|
+
const VERSION = '1.3.0';
|
|
20
20
|
async function main() {
|
|
21
21
|
const args = process.argv.slice(2);
|
|
22
22
|
const command = args[0];
|
|
@@ -45,6 +45,9 @@ async function main() {
|
|
|
45
45
|
tag: { type: 'string', short: 't' },
|
|
46
46
|
branch: { type: 'string', short: 'b' },
|
|
47
47
|
limit: { type: 'string', short: 'l' },
|
|
48
|
+
// Server options
|
|
49
|
+
host: { type: 'string', short: 'H' },
|
|
50
|
+
port: { type: 'string', short: 'P' },
|
|
48
51
|
},
|
|
49
52
|
allowPositionals: true,
|
|
50
53
|
});
|
|
@@ -249,6 +252,29 @@ async function main() {
|
|
|
249
252
|
}
|
|
250
253
|
break;
|
|
251
254
|
}
|
|
255
|
+
case 'serve': {
|
|
256
|
+
const { serve } = await import('./server/http.js');
|
|
257
|
+
const port = values.port ? parseInt(values.port, 10) : 8000;
|
|
258
|
+
const host = values.host || '0.0.0.0';
|
|
259
|
+
console.log('Starting Cognitive Modules HTTP Server...');
|
|
260
|
+
await serve({ host, port, cwd: ctx.cwd });
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
case 'mcp': {
|
|
264
|
+
try {
|
|
265
|
+
const { serve: serveMcp } = await import('./mcp/server.js');
|
|
266
|
+
await serveMcp();
|
|
267
|
+
}
|
|
268
|
+
catch (e) {
|
|
269
|
+
if (e instanceof Error && e.message.includes('Cannot find module')) {
|
|
270
|
+
console.error('MCP dependencies not installed.');
|
|
271
|
+
console.error('Install with: npm install @modelcontextprotocol/sdk');
|
|
272
|
+
process.exit(1);
|
|
273
|
+
}
|
|
274
|
+
throw e;
|
|
275
|
+
}
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
252
278
|
default:
|
|
253
279
|
console.error(`Unknown command: ${command}`);
|
|
254
280
|
console.error('Run "cog --help" for usage.');
|
|
@@ -280,6 +306,8 @@ COMMANDS:
|
|
|
280
306
|
versions <url> List available versions
|
|
281
307
|
pipe Pipe mode (stdin/stdout)
|
|
282
308
|
init [name] Initialize project or create module
|
|
309
|
+
serve Start HTTP API server
|
|
310
|
+
mcp Start MCP server (for Claude Code, Cursor)
|
|
283
311
|
doctor Check configuration
|
|
284
312
|
|
|
285
313
|
OPTIONS:
|
|
@@ -294,6 +322,8 @@ OPTIONS:
|
|
|
294
322
|
--pretty Pretty-print JSON output
|
|
295
323
|
-V, --verbose Verbose output
|
|
296
324
|
--no-validate Skip schema validation
|
|
325
|
+
-H, --host <host> Server host (default: 0.0.0.0)
|
|
326
|
+
-P, --port <port> Server port (default: 8000)
|
|
297
327
|
-v, --version Show version
|
|
298
328
|
-h, --help Show this help
|
|
299
329
|
|
|
@@ -312,6 +342,10 @@ EXAMPLES:
|
|
|
312
342
|
cog run code-reviewer --provider openai --model gpt-4o --args "..."
|
|
313
343
|
cog list
|
|
314
344
|
|
|
345
|
+
# Servers
|
|
346
|
+
cog serve --port 8080
|
|
347
|
+
cog mcp
|
|
348
|
+
|
|
315
349
|
# Other
|
|
316
350
|
echo "review this code" | cog pipe --module code-reviewer
|
|
317
351
|
cog init my-module
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cognitive Modules MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Provides MCP (Model Context Protocol) interface for Claude Code, Cursor, etc.
|
|
5
|
+
*
|
|
6
|
+
* Start with:
|
|
7
|
+
* cog mcp
|
|
8
|
+
*/
|
|
9
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
10
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
11
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
12
|
+
import { findModule, listModules, getDefaultSearchPaths } from '../modules/loader.js';
|
|
13
|
+
import { runModule } from '../modules/runner.js';
|
|
14
|
+
import { getProvider } from '../providers/index.js';
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// Server Setup
|
|
17
|
+
// =============================================================================
|
|
18
|
+
const server = new Server({
|
|
19
|
+
name: 'cognitive-modules',
|
|
20
|
+
version: '1.2.0',
|
|
21
|
+
}, {
|
|
22
|
+
capabilities: {
|
|
23
|
+
tools: {},
|
|
24
|
+
resources: {},
|
|
25
|
+
prompts: {},
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
const cwd = process.cwd();
|
|
29
|
+
const searchPaths = getDefaultSearchPaths(cwd);
|
|
30
|
+
// =============================================================================
|
|
31
|
+
// Tools
|
|
32
|
+
// =============================================================================
|
|
33
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
34
|
+
return {
|
|
35
|
+
tools: [
|
|
36
|
+
{
|
|
37
|
+
name: 'cognitive_run',
|
|
38
|
+
description: 'Run a Cognitive Module to get structured AI analysis results',
|
|
39
|
+
inputSchema: {
|
|
40
|
+
type: 'object',
|
|
41
|
+
properties: {
|
|
42
|
+
module: {
|
|
43
|
+
type: 'string',
|
|
44
|
+
description: 'Module name, e.g. "code-reviewer", "task-prioritizer"',
|
|
45
|
+
},
|
|
46
|
+
args: {
|
|
47
|
+
type: 'string',
|
|
48
|
+
description: 'Input arguments, e.g. code snippet or task list',
|
|
49
|
+
},
|
|
50
|
+
provider: {
|
|
51
|
+
type: 'string',
|
|
52
|
+
description: 'LLM provider (optional), e.g. "openai", "anthropic"',
|
|
53
|
+
},
|
|
54
|
+
model: {
|
|
55
|
+
type: 'string',
|
|
56
|
+
description: 'Model name (optional), e.g. "gpt-4o", "claude-3-5-sonnet"',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
required: ['module', 'args'],
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'cognitive_list',
|
|
64
|
+
description: 'List all installed Cognitive Modules',
|
|
65
|
+
inputSchema: {
|
|
66
|
+
type: 'object',
|
|
67
|
+
properties: {},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: 'cognitive_info',
|
|
72
|
+
description: 'Get detailed information about a Cognitive Module',
|
|
73
|
+
inputSchema: {
|
|
74
|
+
type: 'object',
|
|
75
|
+
properties: {
|
|
76
|
+
module: {
|
|
77
|
+
type: 'string',
|
|
78
|
+
description: 'Module name',
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
required: ['module'],
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
88
|
+
const { name, arguments: args } = request.params;
|
|
89
|
+
try {
|
|
90
|
+
switch (name) {
|
|
91
|
+
case 'cognitive_run': {
|
|
92
|
+
const { module: moduleName, args: inputArgs, provider: providerName, model } = args;
|
|
93
|
+
// Find module
|
|
94
|
+
const moduleData = await findModule(moduleName, searchPaths);
|
|
95
|
+
if (!moduleData) {
|
|
96
|
+
return {
|
|
97
|
+
content: [
|
|
98
|
+
{
|
|
99
|
+
type: 'text',
|
|
100
|
+
text: JSON.stringify({ ok: false, error: `Module '${moduleName}' not found` }),
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
// Create provider
|
|
106
|
+
const provider = getProvider(providerName, model);
|
|
107
|
+
// Run module
|
|
108
|
+
const result = await runModule(moduleData, provider, {
|
|
109
|
+
input: { query: inputArgs, code: inputArgs },
|
|
110
|
+
useV22: true,
|
|
111
|
+
});
|
|
112
|
+
return {
|
|
113
|
+
content: [
|
|
114
|
+
{
|
|
115
|
+
type: 'text',
|
|
116
|
+
text: JSON.stringify(result, null, 2),
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
case 'cognitive_list': {
|
|
122
|
+
const modules = await listModules(searchPaths);
|
|
123
|
+
return {
|
|
124
|
+
content: [
|
|
125
|
+
{
|
|
126
|
+
type: 'text',
|
|
127
|
+
text: JSON.stringify({
|
|
128
|
+
modules: modules.map((m) => ({
|
|
129
|
+
name: m.name,
|
|
130
|
+
location: m.location,
|
|
131
|
+
format: m.format,
|
|
132
|
+
tier: m.tier,
|
|
133
|
+
})),
|
|
134
|
+
count: modules.length,
|
|
135
|
+
}, null, 2),
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
case 'cognitive_info': {
|
|
141
|
+
const { module: moduleName } = args;
|
|
142
|
+
const moduleData = await findModule(moduleName, searchPaths);
|
|
143
|
+
if (!moduleData) {
|
|
144
|
+
return {
|
|
145
|
+
content: [
|
|
146
|
+
{
|
|
147
|
+
type: 'text',
|
|
148
|
+
text: JSON.stringify({ ok: false, error: `Module '${moduleName}' not found` }),
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
content: [
|
|
155
|
+
{
|
|
156
|
+
type: 'text',
|
|
157
|
+
text: JSON.stringify({
|
|
158
|
+
ok: true,
|
|
159
|
+
name: moduleData.name,
|
|
160
|
+
version: moduleData.version,
|
|
161
|
+
responsibility: moduleData.responsibility,
|
|
162
|
+
tier: moduleData.tier,
|
|
163
|
+
format: moduleData.format,
|
|
164
|
+
inputSchema: moduleData.inputSchema,
|
|
165
|
+
outputSchema: moduleData.outputSchema,
|
|
166
|
+
}, null, 2),
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
default:
|
|
172
|
+
return {
|
|
173
|
+
content: [
|
|
174
|
+
{
|
|
175
|
+
type: 'text',
|
|
176
|
+
text: JSON.stringify({ ok: false, error: `Unknown tool: ${name}` }),
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
return {
|
|
184
|
+
content: [
|
|
185
|
+
{
|
|
186
|
+
type: 'text',
|
|
187
|
+
text: JSON.stringify({
|
|
188
|
+
ok: false,
|
|
189
|
+
error: error instanceof Error ? error.message : String(error),
|
|
190
|
+
}),
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
// =============================================================================
|
|
197
|
+
// Resources
|
|
198
|
+
// =============================================================================
|
|
199
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
200
|
+
const modules = await listModules(searchPaths);
|
|
201
|
+
return {
|
|
202
|
+
resources: [
|
|
203
|
+
{
|
|
204
|
+
uri: 'cognitive://modules',
|
|
205
|
+
name: 'All Modules',
|
|
206
|
+
description: 'List of all installed Cognitive Modules',
|
|
207
|
+
mimeType: 'application/json',
|
|
208
|
+
},
|
|
209
|
+
...modules.map((m) => ({
|
|
210
|
+
uri: `cognitive://module/${m.name}`,
|
|
211
|
+
name: m.name,
|
|
212
|
+
description: m.responsibility || `Cognitive Module: ${m.name}`,
|
|
213
|
+
mimeType: 'text/markdown',
|
|
214
|
+
})),
|
|
215
|
+
],
|
|
216
|
+
};
|
|
217
|
+
});
|
|
218
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
219
|
+
const { uri } = request.params;
|
|
220
|
+
if (uri === 'cognitive://modules') {
|
|
221
|
+
const modules = await listModules(searchPaths);
|
|
222
|
+
return {
|
|
223
|
+
contents: [
|
|
224
|
+
{
|
|
225
|
+
uri,
|
|
226
|
+
mimeType: 'application/json',
|
|
227
|
+
text: JSON.stringify(modules.map((m) => m.name), null, 2),
|
|
228
|
+
},
|
|
229
|
+
],
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
const match = uri.match(/^cognitive:\/\/module\/(.+)$/);
|
|
233
|
+
if (match) {
|
|
234
|
+
const moduleName = match[1];
|
|
235
|
+
const moduleData = await findModule(moduleName, searchPaths);
|
|
236
|
+
if (!moduleData) {
|
|
237
|
+
return {
|
|
238
|
+
contents: [
|
|
239
|
+
{
|
|
240
|
+
uri,
|
|
241
|
+
mimeType: 'text/plain',
|
|
242
|
+
text: `Module '${moduleName}' not found`,
|
|
243
|
+
},
|
|
244
|
+
],
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
contents: [
|
|
249
|
+
{
|
|
250
|
+
uri,
|
|
251
|
+
mimeType: 'text/markdown',
|
|
252
|
+
text: moduleData.prompt,
|
|
253
|
+
},
|
|
254
|
+
],
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
contents: [
|
|
259
|
+
{
|
|
260
|
+
uri,
|
|
261
|
+
mimeType: 'text/plain',
|
|
262
|
+
text: `Unknown resource: ${uri}`,
|
|
263
|
+
},
|
|
264
|
+
],
|
|
265
|
+
};
|
|
266
|
+
});
|
|
267
|
+
// =============================================================================
|
|
268
|
+
// Prompts
|
|
269
|
+
// =============================================================================
|
|
270
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
271
|
+
return {
|
|
272
|
+
prompts: [
|
|
273
|
+
{
|
|
274
|
+
name: 'code_review',
|
|
275
|
+
description: 'Generate a code review prompt',
|
|
276
|
+
arguments: [
|
|
277
|
+
{
|
|
278
|
+
name: 'code',
|
|
279
|
+
description: 'The code to review',
|
|
280
|
+
required: true,
|
|
281
|
+
},
|
|
282
|
+
],
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
name: 'task_prioritize',
|
|
286
|
+
description: 'Generate a task prioritization prompt',
|
|
287
|
+
arguments: [
|
|
288
|
+
{
|
|
289
|
+
name: 'tasks',
|
|
290
|
+
description: 'The tasks to prioritize',
|
|
291
|
+
required: true,
|
|
292
|
+
},
|
|
293
|
+
],
|
|
294
|
+
},
|
|
295
|
+
],
|
|
296
|
+
};
|
|
297
|
+
});
|
|
298
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
299
|
+
const { name, arguments: args } = request.params;
|
|
300
|
+
switch (name) {
|
|
301
|
+
case 'code_review': {
|
|
302
|
+
const code = args?.code ?? '';
|
|
303
|
+
return {
|
|
304
|
+
messages: [
|
|
305
|
+
{
|
|
306
|
+
role: 'user',
|
|
307
|
+
content: {
|
|
308
|
+
type: 'text',
|
|
309
|
+
text: `Please use the cognitive_run tool to review the following code:\n\n\`\`\`\n${code}\n\`\`\`\n\nCall: cognitive_run("code-reviewer", "${code.slice(0, 100)}...")`,
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
],
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
case 'task_prioritize': {
|
|
316
|
+
const tasks = args?.tasks ?? '';
|
|
317
|
+
return {
|
|
318
|
+
messages: [
|
|
319
|
+
{
|
|
320
|
+
role: 'user',
|
|
321
|
+
content: {
|
|
322
|
+
type: 'text',
|
|
323
|
+
text: `Please use the cognitive_run tool to prioritize the following tasks:\n\n${tasks}\n\nCall: cognitive_run("task-prioritizer", "${tasks}")`,
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
],
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
default:
|
|
330
|
+
throw new Error(`Unknown prompt: ${name}`);
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
// =============================================================================
|
|
334
|
+
// Server Start
|
|
335
|
+
// =============================================================================
|
|
336
|
+
export async function serve() {
|
|
337
|
+
const transport = new StdioServerTransport();
|
|
338
|
+
await server.connect(transport);
|
|
339
|
+
console.error('Cognitive Modules MCP Server started');
|
|
340
|
+
}
|
|
341
|
+
// Allow running directly
|
|
342
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
343
|
+
serve().catch(console.error);
|
|
344
|
+
}
|
package/dist/modules/index.d.ts
CHANGED
package/dist/modules/index.js
CHANGED
package/dist/modules/loader.js
CHANGED
|
@@ -103,11 +103,16 @@ async function loadModuleV2(modulePath) {
|
|
|
103
103
|
runtime_auto_wrap: compatRaw.runtime_auto_wrap ?? true,
|
|
104
104
|
schema_output_alias: compatRaw.schema_output_alias ?? 'data'
|
|
105
105
|
};
|
|
106
|
-
// Parse meta config (including risk_rule)
|
|
106
|
+
// Parse meta config (including risk_rule) with validation
|
|
107
107
|
const metaRaw = manifest.meta || {};
|
|
108
|
+
const rawRiskRule = metaRaw.risk_rule;
|
|
109
|
+
const validRiskRules = ['max_changes_risk', 'max_issues_risk', 'explicit'];
|
|
110
|
+
const validatedRiskRule = rawRiskRule && validRiskRules.includes(rawRiskRule)
|
|
111
|
+
? rawRiskRule
|
|
112
|
+
: undefined;
|
|
108
113
|
const metaConfig = {
|
|
109
114
|
required: metaRaw.required,
|
|
110
|
-
risk_rule:
|
|
115
|
+
risk_rule: validatedRiskRule,
|
|
111
116
|
};
|
|
112
117
|
return {
|
|
113
118
|
name: manifest.name || path.basename(modulePath),
|
package/dist/modules/runner.js
CHANGED
|
@@ -34,9 +34,14 @@ function repairEnvelope(response, riskRule = 'max_changes_risk', maxExplainLengt
|
|
|
34
34
|
if (!meta.risk) {
|
|
35
35
|
meta.risk = aggregateRisk(data, riskRule);
|
|
36
36
|
}
|
|
37
|
-
// Trim whitespace only (lossless),
|
|
37
|
+
// Trim whitespace only (lossless), validate is valid RiskLevel
|
|
38
38
|
if (typeof meta.risk === 'string') {
|
|
39
|
-
|
|
39
|
+
const trimmedRisk = meta.risk.trim().toLowerCase();
|
|
40
|
+
const validRisks = ['none', 'low', 'medium', 'high'];
|
|
41
|
+
meta.risk = validRisks.includes(trimmedRisk) ? trimmedRisk : 'medium';
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
meta.risk = 'medium'; // Default for invalid type
|
|
40
45
|
}
|
|
41
46
|
// Repair explain
|
|
42
47
|
if (typeof meta.explain !== 'string') {
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subagent - Orchestrate module calls with isolated execution contexts.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - @call:module-name - Call another module
|
|
6
|
+
* - @call:module-name(args) - Call with arguments
|
|
7
|
+
* - context: fork - Isolated execution (no shared state)
|
|
8
|
+
* - context: main - Shared execution (default)
|
|
9
|
+
*/
|
|
10
|
+
import type { ModuleResult, ModuleInput, Provider } from '../types.js';
|
|
11
|
+
export interface SubagentContext {
|
|
12
|
+
parentId: string | null;
|
|
13
|
+
depth: number;
|
|
14
|
+
maxDepth: number;
|
|
15
|
+
results: Record<string, unknown>;
|
|
16
|
+
isolated: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface CallDirective {
|
|
19
|
+
module: string;
|
|
20
|
+
args: string;
|
|
21
|
+
match: string;
|
|
22
|
+
}
|
|
23
|
+
export interface SubagentRunOptions {
|
|
24
|
+
input?: ModuleInput;
|
|
25
|
+
validateInput?: boolean;
|
|
26
|
+
validateOutput?: boolean;
|
|
27
|
+
maxDepth?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create a new root context
|
|
31
|
+
*/
|
|
32
|
+
export declare function createContext(maxDepth?: number): SubagentContext;
|
|
33
|
+
/**
|
|
34
|
+
* Fork context (isolated - no inherited results)
|
|
35
|
+
*/
|
|
36
|
+
export declare function forkContext(ctx: SubagentContext, moduleName: string): SubagentContext;
|
|
37
|
+
/**
|
|
38
|
+
* Extend context (shared - inherits results)
|
|
39
|
+
*/
|
|
40
|
+
export declare function extendContext(ctx: SubagentContext, moduleName: string): SubagentContext;
|
|
41
|
+
/**
|
|
42
|
+
* Parse @call directives from text
|
|
43
|
+
*/
|
|
44
|
+
export declare function parseCalls(text: string): CallDirective[];
|
|
45
|
+
/**
|
|
46
|
+
* Replace @call directives with their results
|
|
47
|
+
*/
|
|
48
|
+
export declare function substituteCallResults(text: string, callResults: Record<string, unknown>): string;
|
|
49
|
+
export declare class SubagentOrchestrator {
|
|
50
|
+
private provider;
|
|
51
|
+
private running;
|
|
52
|
+
private cwd;
|
|
53
|
+
constructor(provider: Provider, cwd?: string);
|
|
54
|
+
/**
|
|
55
|
+
* Run a module with subagent support.
|
|
56
|
+
* Recursively resolves @call directives before final execution.
|
|
57
|
+
*/
|
|
58
|
+
run(moduleName: string, options?: SubagentRunOptions, context?: SubagentContext): Promise<ModuleResult>;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Convenience function to run a module with subagent support
|
|
62
|
+
*/
|
|
63
|
+
export declare function runWithSubagents(moduleName: string, provider: Provider, options?: SubagentRunOptions & {
|
|
64
|
+
cwd?: string;
|
|
65
|
+
}): Promise<ModuleResult>;
|