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
|
@@ -0,0 +1,185 @@
|
|
|
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 { findModule, getDefaultSearchPaths } from './loader.js';
|
|
11
|
+
import { runModule } from './runner.js';
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// Context Management
|
|
14
|
+
// =============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Create a new root context
|
|
17
|
+
*/
|
|
18
|
+
export function createContext(maxDepth = 5) {
|
|
19
|
+
return {
|
|
20
|
+
parentId: null,
|
|
21
|
+
depth: 0,
|
|
22
|
+
maxDepth,
|
|
23
|
+
results: {},
|
|
24
|
+
isolated: false
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Fork context (isolated - no inherited results)
|
|
29
|
+
*/
|
|
30
|
+
export function forkContext(ctx, moduleName) {
|
|
31
|
+
return {
|
|
32
|
+
parentId: moduleName,
|
|
33
|
+
depth: ctx.depth + 1,
|
|
34
|
+
maxDepth: ctx.maxDepth,
|
|
35
|
+
results: {},
|
|
36
|
+
isolated: true
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Extend context (shared - inherits results)
|
|
41
|
+
*/
|
|
42
|
+
export function extendContext(ctx, moduleName) {
|
|
43
|
+
return {
|
|
44
|
+
parentId: moduleName,
|
|
45
|
+
depth: ctx.depth + 1,
|
|
46
|
+
maxDepth: ctx.maxDepth,
|
|
47
|
+
results: { ...ctx.results },
|
|
48
|
+
isolated: false
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// =============================================================================
|
|
52
|
+
// Call Parsing
|
|
53
|
+
// =============================================================================
|
|
54
|
+
// Pattern to match @call:module-name or @call:module-name(args)
|
|
55
|
+
const CALL_PATTERN = /@call:([a-zA-Z0-9_-]+)(?:\(([^)]*)\))?/g;
|
|
56
|
+
/**
|
|
57
|
+
* Parse @call directives from text
|
|
58
|
+
*/
|
|
59
|
+
export function parseCalls(text) {
|
|
60
|
+
const calls = [];
|
|
61
|
+
let match;
|
|
62
|
+
// Reset regex state
|
|
63
|
+
CALL_PATTERN.lastIndex = 0;
|
|
64
|
+
while ((match = CALL_PATTERN.exec(text)) !== null) {
|
|
65
|
+
calls.push({
|
|
66
|
+
module: match[1],
|
|
67
|
+
args: match[2] || '',
|
|
68
|
+
match: match[0]
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return calls;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Replace @call directives with their results
|
|
75
|
+
*/
|
|
76
|
+
export function substituteCallResults(text, callResults) {
|
|
77
|
+
let result = text;
|
|
78
|
+
for (const [callStr, callResult] of Object.entries(callResults)) {
|
|
79
|
+
const resultStr = typeof callResult === 'object'
|
|
80
|
+
? JSON.stringify(callResult, null, 2)
|
|
81
|
+
: String(callResult);
|
|
82
|
+
result = result.replace(callStr, `[Result from ${callStr}]:\n${resultStr}`);
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
// =============================================================================
|
|
87
|
+
// Orchestrator
|
|
88
|
+
// =============================================================================
|
|
89
|
+
export class SubagentOrchestrator {
|
|
90
|
+
provider;
|
|
91
|
+
running = new Set();
|
|
92
|
+
cwd;
|
|
93
|
+
constructor(provider, cwd = process.cwd()) {
|
|
94
|
+
this.provider = provider;
|
|
95
|
+
this.cwd = cwd;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Run a module with subagent support.
|
|
99
|
+
* Recursively resolves @call directives before final execution.
|
|
100
|
+
*/
|
|
101
|
+
async run(moduleName, options = {}, context) {
|
|
102
|
+
const { input = {}, validateInput = true, validateOutput = true, maxDepth = 5 } = options;
|
|
103
|
+
// Initialize context
|
|
104
|
+
const ctx = context ?? createContext(maxDepth);
|
|
105
|
+
// Check depth limit
|
|
106
|
+
if (ctx.depth > ctx.maxDepth) {
|
|
107
|
+
throw new Error(`Max subagent depth (${ctx.maxDepth}) exceeded. Check for circular calls.`);
|
|
108
|
+
}
|
|
109
|
+
// Prevent circular calls
|
|
110
|
+
if (this.running.has(moduleName)) {
|
|
111
|
+
throw new Error(`Circular call detected: ${moduleName}`);
|
|
112
|
+
}
|
|
113
|
+
this.running.add(moduleName);
|
|
114
|
+
try {
|
|
115
|
+
// Find and load module
|
|
116
|
+
const searchPaths = getDefaultSearchPaths(this.cwd);
|
|
117
|
+
const module = await findModule(moduleName, searchPaths);
|
|
118
|
+
if (!module) {
|
|
119
|
+
throw new Error(`Module not found: ${moduleName}`);
|
|
120
|
+
}
|
|
121
|
+
// Check if this module wants isolated execution
|
|
122
|
+
const moduleContextMode = module.context ?? 'main';
|
|
123
|
+
// Parse @call directives from prompt
|
|
124
|
+
const calls = parseCalls(module.prompt);
|
|
125
|
+
const callResults = {};
|
|
126
|
+
// Resolve each @call directive
|
|
127
|
+
for (const call of calls) {
|
|
128
|
+
const childModule = call.module;
|
|
129
|
+
const childArgs = call.args;
|
|
130
|
+
// Prepare child input
|
|
131
|
+
const childInput = childArgs
|
|
132
|
+
? { query: childArgs, code: childArgs }
|
|
133
|
+
: { ...input };
|
|
134
|
+
// Determine child context
|
|
135
|
+
const childContext = moduleContextMode === 'fork'
|
|
136
|
+
? forkContext(ctx, moduleName)
|
|
137
|
+
: extendContext(ctx, moduleName);
|
|
138
|
+
// Recursively run child module
|
|
139
|
+
const childResult = await this.run(childModule, {
|
|
140
|
+
input: childInput,
|
|
141
|
+
validateInput: false, // Skip validation for @call args
|
|
142
|
+
validateOutput
|
|
143
|
+
}, childContext);
|
|
144
|
+
// Store result
|
|
145
|
+
if (childResult.ok && 'data' in childResult) {
|
|
146
|
+
callResults[call.match] = childResult.data;
|
|
147
|
+
}
|
|
148
|
+
else if ('error' in childResult) {
|
|
149
|
+
callResults[call.match] = { error: childResult.error };
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Substitute call results into prompt
|
|
153
|
+
let modifiedModule = module;
|
|
154
|
+
if (Object.keys(callResults).length > 0) {
|
|
155
|
+
const modifiedPrompt = substituteCallResults(module.prompt, callResults);
|
|
156
|
+
modifiedModule = {
|
|
157
|
+
...module,
|
|
158
|
+
prompt: modifiedPrompt + '\n\n## Subagent Results Available\nThe @call results have been injected above. Use them in your response.\n'
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
// Run the module
|
|
162
|
+
const result = await runModule(modifiedModule, this.provider, {
|
|
163
|
+
input,
|
|
164
|
+
verbose: false,
|
|
165
|
+
useV22: true
|
|
166
|
+
});
|
|
167
|
+
// Store result in context
|
|
168
|
+
if (result.ok && 'data' in result) {
|
|
169
|
+
ctx.results[moduleName] = result.data;
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
finally {
|
|
174
|
+
this.running.delete(moduleName);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Convenience function to run a module with subagent support
|
|
180
|
+
*/
|
|
181
|
+
export async function runWithSubagents(moduleName, provider, options = {}) {
|
|
182
|
+
const { cwd = process.cwd(), ...runOptions } = options;
|
|
183
|
+
const orchestrator = new SubagentOrchestrator(provider, cwd);
|
|
184
|
+
return orchestrator.run(moduleName, runOptions);
|
|
185
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cognitive Modules HTTP API Server
|
|
3
|
+
*
|
|
4
|
+
* Provides RESTful API interface for workflow platform integration.
|
|
5
|
+
*
|
|
6
|
+
* Start with:
|
|
7
|
+
* cog serve --port 8000
|
|
8
|
+
*
|
|
9
|
+
* Environment variables:
|
|
10
|
+
* COGNITIVE_API_KEY - API Key authentication (optional)
|
|
11
|
+
* OPENAI_API_KEY, ANTHROPIC_API_KEY, etc. - LLM provider keys
|
|
12
|
+
*/
|
|
13
|
+
import http from 'node:http';
|
|
14
|
+
export interface ServeOptions {
|
|
15
|
+
host?: string;
|
|
16
|
+
port?: number;
|
|
17
|
+
cwd?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function createServer(options?: ServeOptions): http.Server;
|
|
20
|
+
export declare function serve(options?: ServeOptions): Promise<void>;
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cognitive Modules HTTP API Server
|
|
3
|
+
*
|
|
4
|
+
* Provides RESTful API interface for workflow platform integration.
|
|
5
|
+
*
|
|
6
|
+
* Start with:
|
|
7
|
+
* cog serve --port 8000
|
|
8
|
+
*
|
|
9
|
+
* Environment variables:
|
|
10
|
+
* COGNITIVE_API_KEY - API Key authentication (optional)
|
|
11
|
+
* OPENAI_API_KEY, ANTHROPIC_API_KEY, etc. - LLM provider keys
|
|
12
|
+
*/
|
|
13
|
+
import http from 'node:http';
|
|
14
|
+
import { URL } from 'node:url';
|
|
15
|
+
import { findModule, listModules, getDefaultSearchPaths } from '../modules/loader.js';
|
|
16
|
+
import { runModule } from '../modules/runner.js';
|
|
17
|
+
import { getProvider } from '../providers/index.js';
|
|
18
|
+
// =============================================================================
|
|
19
|
+
// Helpers
|
|
20
|
+
// =============================================================================
|
|
21
|
+
function jsonResponse(res, status, data) {
|
|
22
|
+
res.writeHead(status, {
|
|
23
|
+
'Content-Type': 'application/json',
|
|
24
|
+
'Access-Control-Allow-Origin': '*',
|
|
25
|
+
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
26
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
|
27
|
+
});
|
|
28
|
+
res.end(JSON.stringify(data, null, 2));
|
|
29
|
+
}
|
|
30
|
+
function parseBody(req) {
|
|
31
|
+
return new Promise((resolve, reject) => {
|
|
32
|
+
let body = '';
|
|
33
|
+
req.on('data', (chunk) => (body += chunk));
|
|
34
|
+
req.on('end', () => resolve(body));
|
|
35
|
+
req.on('error', reject);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function verifyApiKey(req) {
|
|
39
|
+
const expectedKey = process.env.COGNITIVE_API_KEY;
|
|
40
|
+
if (!expectedKey)
|
|
41
|
+
return true; // No auth required
|
|
42
|
+
const authHeader = req.headers.authorization;
|
|
43
|
+
if (!authHeader)
|
|
44
|
+
return false;
|
|
45
|
+
const token = authHeader.startsWith('Bearer ') ? authHeader.slice(7) : authHeader;
|
|
46
|
+
return token === expectedKey;
|
|
47
|
+
}
|
|
48
|
+
// =============================================================================
|
|
49
|
+
// Request Handlers
|
|
50
|
+
// =============================================================================
|
|
51
|
+
async function handleRoot(res) {
|
|
52
|
+
jsonResponse(res, 200, {
|
|
53
|
+
name: 'Cognitive Modules API',
|
|
54
|
+
version: '1.2.0',
|
|
55
|
+
docs: '/docs',
|
|
56
|
+
endpoints: {
|
|
57
|
+
run: 'POST /run',
|
|
58
|
+
modules: 'GET /modules',
|
|
59
|
+
module_info: 'GET /modules/{name}',
|
|
60
|
+
health: 'GET /health',
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
async function handleHealth(res) {
|
|
65
|
+
const providers = {
|
|
66
|
+
openai: Boolean(process.env.OPENAI_API_KEY),
|
|
67
|
+
anthropic: Boolean(process.env.ANTHROPIC_API_KEY),
|
|
68
|
+
minimax: Boolean(process.env.MINIMAX_API_KEY),
|
|
69
|
+
deepseek: Boolean(process.env.DEEPSEEK_API_KEY),
|
|
70
|
+
gemini: Boolean(process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY),
|
|
71
|
+
qwen: Boolean(process.env.QWEN_API_KEY || process.env.DASHSCOPE_API_KEY),
|
|
72
|
+
};
|
|
73
|
+
jsonResponse(res, 200, {
|
|
74
|
+
status: 'healthy',
|
|
75
|
+
version: '1.2.0',
|
|
76
|
+
providers,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
async function handleModules(res, searchPaths) {
|
|
80
|
+
const modules = await listModules(searchPaths);
|
|
81
|
+
const moduleInfos = modules.map((m) => ({
|
|
82
|
+
name: m.name,
|
|
83
|
+
version: m.version,
|
|
84
|
+
description: m.responsibility,
|
|
85
|
+
format: m.format,
|
|
86
|
+
path: m.location,
|
|
87
|
+
responsibility: m.responsibility,
|
|
88
|
+
tier: m.tier,
|
|
89
|
+
}));
|
|
90
|
+
jsonResponse(res, 200, {
|
|
91
|
+
modules: moduleInfos,
|
|
92
|
+
count: moduleInfos.length,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
async function handleModuleInfo(res, moduleName, searchPaths) {
|
|
96
|
+
const moduleData = await findModule(moduleName, searchPaths);
|
|
97
|
+
if (!moduleData) {
|
|
98
|
+
jsonResponse(res, 404, { error: `Module '${moduleName}' not found` });
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
jsonResponse(res, 200, {
|
|
102
|
+
name: moduleData.name,
|
|
103
|
+
version: moduleData.version,
|
|
104
|
+
description: moduleData.responsibility,
|
|
105
|
+
format: moduleData.format,
|
|
106
|
+
path: moduleData.location,
|
|
107
|
+
responsibility: moduleData.responsibility,
|
|
108
|
+
tier: moduleData.tier,
|
|
109
|
+
inputSchema: moduleData.inputSchema,
|
|
110
|
+
outputSchema: moduleData.outputSchema,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
async function handleRun(req, res, searchPaths) {
|
|
114
|
+
// Verify API key
|
|
115
|
+
if (!verifyApiKey(req)) {
|
|
116
|
+
jsonResponse(res, 401, {
|
|
117
|
+
error: 'Missing or invalid API Key. Use header: Authorization: Bearer <your-api-key>',
|
|
118
|
+
});
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
// Parse request body
|
|
122
|
+
let request;
|
|
123
|
+
try {
|
|
124
|
+
const body = await parseBody(req);
|
|
125
|
+
request = JSON.parse(body);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
jsonResponse(res, 400, { error: 'Invalid JSON body' });
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
// Validate request
|
|
132
|
+
if (!request.module || !request.args) {
|
|
133
|
+
jsonResponse(res, 400, { error: 'Missing required fields: module, args' });
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
// Find module
|
|
137
|
+
const moduleData = await findModule(request.module, searchPaths);
|
|
138
|
+
if (!moduleData) {
|
|
139
|
+
jsonResponse(res, 404, { error: `Module '${request.module}' not found` });
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
// Create provider
|
|
144
|
+
const provider = getProvider(request.provider, request.model);
|
|
145
|
+
// Run module
|
|
146
|
+
const result = await runModule(moduleData, provider, {
|
|
147
|
+
input: { query: request.args, code: request.args },
|
|
148
|
+
useV22: true,
|
|
149
|
+
});
|
|
150
|
+
const response = {
|
|
151
|
+
ok: result.ok,
|
|
152
|
+
module: request.module,
|
|
153
|
+
provider: request.provider || process.env.LLM_PROVIDER || 'openai',
|
|
154
|
+
};
|
|
155
|
+
if (result.ok) {
|
|
156
|
+
if ('meta' in result)
|
|
157
|
+
response.meta = result.meta;
|
|
158
|
+
if ('data' in result)
|
|
159
|
+
response.data = result.data;
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
if ('error' in result)
|
|
163
|
+
response.error = result.error?.message;
|
|
164
|
+
}
|
|
165
|
+
jsonResponse(res, 200, response);
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
jsonResponse(res, 500, {
|
|
169
|
+
ok: false,
|
|
170
|
+
error: error instanceof Error ? error.message : String(error),
|
|
171
|
+
module: request.module,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
export function createServer(options = {}) {
|
|
176
|
+
const { cwd = process.cwd() } = options;
|
|
177
|
+
const searchPaths = getDefaultSearchPaths(cwd);
|
|
178
|
+
const server = http.createServer(async (req, res) => {
|
|
179
|
+
const url = new URL(req.url || '/', `http://${req.headers.host}`);
|
|
180
|
+
const path = url.pathname;
|
|
181
|
+
const method = req.method?.toUpperCase();
|
|
182
|
+
// Handle CORS preflight
|
|
183
|
+
if (method === 'OPTIONS') {
|
|
184
|
+
res.writeHead(204, {
|
|
185
|
+
'Access-Control-Allow-Origin': '*',
|
|
186
|
+
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
187
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
|
188
|
+
});
|
|
189
|
+
res.end();
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
try {
|
|
193
|
+
// Route requests
|
|
194
|
+
if (path === '/' && method === 'GET') {
|
|
195
|
+
await handleRoot(res);
|
|
196
|
+
}
|
|
197
|
+
else if (path === '/health' && method === 'GET') {
|
|
198
|
+
await handleHealth(res);
|
|
199
|
+
}
|
|
200
|
+
else if (path === '/modules' && method === 'GET') {
|
|
201
|
+
await handleModules(res, searchPaths);
|
|
202
|
+
}
|
|
203
|
+
else if (path.startsWith('/modules/') && method === 'GET') {
|
|
204
|
+
const moduleName = path.slice('/modules/'.length);
|
|
205
|
+
await handleModuleInfo(res, moduleName, searchPaths);
|
|
206
|
+
}
|
|
207
|
+
else if (path === '/run' && method === 'POST') {
|
|
208
|
+
await handleRun(req, res, searchPaths);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
jsonResponse(res, 404, { error: 'Not found' });
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
console.error('Server error:', error);
|
|
216
|
+
jsonResponse(res, 500, {
|
|
217
|
+
error: error instanceof Error ? error.message : 'Internal server error',
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
return server;
|
|
222
|
+
}
|
|
223
|
+
export async function serve(options = {}) {
|
|
224
|
+
const { host = '0.0.0.0', port = 8000 } = options;
|
|
225
|
+
const server = createServer(options);
|
|
226
|
+
return new Promise((resolve, reject) => {
|
|
227
|
+
server.on('error', reject);
|
|
228
|
+
server.listen(port, host, () => {
|
|
229
|
+
console.log(`Cognitive Modules HTTP Server running at http://${host}:${port}`);
|
|
230
|
+
console.log('Endpoints:');
|
|
231
|
+
console.log(' GET / - API info');
|
|
232
|
+
console.log(' GET /health - Health check');
|
|
233
|
+
console.log(' GET /modules - List modules');
|
|
234
|
+
console.log(' GET /modules/:name - Module info');
|
|
235
|
+
console.log(' POST /run - Run module');
|
|
236
|
+
resolve();
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
// Allow running directly
|
|
241
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
242
|
+
serve().catch(console.error);
|
|
243
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognitive-modules-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Cognitive Modules - Structured AI Task Execution with version management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -39,6 +39,9 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"js-yaml": "^4.1.1"
|
|
41
41
|
},
|
|
42
|
+
"optionalDependencies": {
|
|
43
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
44
|
+
},
|
|
42
45
|
"devDependencies": {
|
|
43
46
|
"@types/js-yaml": "^4.0.9",
|
|
44
47
|
"@types/node": "^22.0.0",
|
package/src/cli.ts
CHANGED
|
@@ -19,7 +19,7 @@ import { getProvider, listProviders } from './providers/index.js';
|
|
|
19
19
|
import { run, list, pipe, init, add, update, remove, versions } from './commands/index.js';
|
|
20
20
|
import type { CommandContext } from './types.js';
|
|
21
21
|
|
|
22
|
-
const VERSION = '1.0
|
|
22
|
+
const VERSION = '1.3.0';
|
|
23
23
|
|
|
24
24
|
async function main() {
|
|
25
25
|
const args = process.argv.slice(2);
|
|
@@ -52,6 +52,9 @@ async function main() {
|
|
|
52
52
|
tag: { type: 'string', short: 't' },
|
|
53
53
|
branch: { type: 'string', short: 'b' },
|
|
54
54
|
limit: { type: 'string', short: 'l' },
|
|
55
|
+
// Server options
|
|
56
|
+
host: { type: 'string', short: 'H' },
|
|
57
|
+
port: { type: 'string', short: 'P' },
|
|
55
58
|
},
|
|
56
59
|
allowPositionals: true,
|
|
57
60
|
});
|
|
@@ -288,6 +291,30 @@ async function main() {
|
|
|
288
291
|
break;
|
|
289
292
|
}
|
|
290
293
|
|
|
294
|
+
case 'serve': {
|
|
295
|
+
const { serve } = await import('./server/http.js');
|
|
296
|
+
const port = values.port ? parseInt(values.port as string, 10) : 8000;
|
|
297
|
+
const host = (values.host as string) || '0.0.0.0';
|
|
298
|
+
console.log('Starting Cognitive Modules HTTP Server...');
|
|
299
|
+
await serve({ host, port, cwd: ctx.cwd });
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
case 'mcp': {
|
|
304
|
+
try {
|
|
305
|
+
const { serve: serveMcp } = await import('./mcp/server.js');
|
|
306
|
+
await serveMcp();
|
|
307
|
+
} catch (e) {
|
|
308
|
+
if (e instanceof Error && e.message.includes('Cannot find module')) {
|
|
309
|
+
console.error('MCP dependencies not installed.');
|
|
310
|
+
console.error('Install with: npm install @modelcontextprotocol/sdk');
|
|
311
|
+
process.exit(1);
|
|
312
|
+
}
|
|
313
|
+
throw e;
|
|
314
|
+
}
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
|
|
291
318
|
default:
|
|
292
319
|
console.error(`Unknown command: ${command}`);
|
|
293
320
|
console.error('Run "cog --help" for usage.');
|
|
@@ -319,6 +346,8 @@ COMMANDS:
|
|
|
319
346
|
versions <url> List available versions
|
|
320
347
|
pipe Pipe mode (stdin/stdout)
|
|
321
348
|
init [name] Initialize project or create module
|
|
349
|
+
serve Start HTTP API server
|
|
350
|
+
mcp Start MCP server (for Claude Code, Cursor)
|
|
322
351
|
doctor Check configuration
|
|
323
352
|
|
|
324
353
|
OPTIONS:
|
|
@@ -333,6 +362,8 @@ OPTIONS:
|
|
|
333
362
|
--pretty Pretty-print JSON output
|
|
334
363
|
-V, --verbose Verbose output
|
|
335
364
|
--no-validate Skip schema validation
|
|
365
|
+
-H, --host <host> Server host (default: 0.0.0.0)
|
|
366
|
+
-P, --port <port> Server port (default: 8000)
|
|
336
367
|
-v, --version Show version
|
|
337
368
|
-h, --help Show this help
|
|
338
369
|
|
|
@@ -351,6 +382,10 @@ EXAMPLES:
|
|
|
351
382
|
cog run code-reviewer --provider openai --model gpt-4o --args "..."
|
|
352
383
|
cog list
|
|
353
384
|
|
|
385
|
+
# Servers
|
|
386
|
+
cog serve --port 8080
|
|
387
|
+
cog mcp
|
|
388
|
+
|
|
354
389
|
# Other
|
|
355
390
|
echo "review this code" | cog pipe --module code-reviewer
|
|
356
391
|
cog init my-module
|