cognitive-modules-cli 2.2.0 → 2.2.5

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 (94) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +35 -29
  4. package/dist/cli.js +572 -28
  5. package/dist/commands/add.d.ts +33 -14
  6. package/dist/commands/add.js +222 -13
  7. package/dist/commands/compose.d.ts +31 -0
  8. package/dist/commands/compose.js +185 -0
  9. package/dist/commands/index.d.ts +5 -0
  10. package/dist/commands/index.js +5 -0
  11. package/dist/commands/init.js +23 -1
  12. package/dist/commands/migrate.d.ts +30 -0
  13. package/dist/commands/migrate.js +650 -0
  14. package/dist/commands/pipe.d.ts +1 -0
  15. package/dist/commands/pipe.js +31 -11
  16. package/dist/commands/remove.js +33 -2
  17. package/dist/commands/run.d.ts +1 -0
  18. package/dist/commands/run.js +37 -27
  19. package/dist/commands/search.d.ts +28 -0
  20. package/dist/commands/search.js +143 -0
  21. package/dist/commands/test.d.ts +65 -0
  22. package/dist/commands/test.js +454 -0
  23. package/dist/commands/update.d.ts +1 -0
  24. package/dist/commands/update.js +106 -14
  25. package/dist/commands/validate.d.ts +36 -0
  26. package/dist/commands/validate.js +97 -0
  27. package/dist/errors/index.d.ts +218 -0
  28. package/dist/errors/index.js +412 -0
  29. package/dist/index.d.ts +2 -2
  30. package/dist/index.js +5 -1
  31. package/dist/mcp/server.js +84 -79
  32. package/dist/modules/composition.d.ts +251 -0
  33. package/dist/modules/composition.js +1330 -0
  34. package/dist/modules/index.d.ts +2 -0
  35. package/dist/modules/index.js +2 -0
  36. package/dist/modules/loader.d.ts +22 -2
  37. package/dist/modules/loader.js +171 -6
  38. package/dist/modules/runner.d.ts +422 -1
  39. package/dist/modules/runner.js +1472 -71
  40. package/dist/modules/subagent.d.ts +6 -1
  41. package/dist/modules/subagent.js +20 -13
  42. package/dist/modules/validator.d.ts +28 -0
  43. package/dist/modules/validator.js +637 -0
  44. package/dist/providers/anthropic.d.ts +15 -0
  45. package/dist/providers/anthropic.js +147 -5
  46. package/dist/providers/base.d.ts +11 -0
  47. package/dist/providers/base.js +18 -0
  48. package/dist/providers/gemini.d.ts +15 -0
  49. package/dist/providers/gemini.js +122 -5
  50. package/dist/providers/ollama.d.ts +15 -0
  51. package/dist/providers/ollama.js +111 -3
  52. package/dist/providers/openai.d.ts +11 -0
  53. package/dist/providers/openai.js +133 -0
  54. package/dist/registry/client.d.ts +204 -0
  55. package/dist/registry/client.js +356 -0
  56. package/dist/registry/index.d.ts +4 -0
  57. package/dist/registry/index.js +4 -0
  58. package/dist/server/http.js +173 -42
  59. package/dist/types.d.ts +123 -8
  60. package/dist/types.js +4 -1
  61. package/dist/version.d.ts +1 -0
  62. package/dist/version.js +4 -0
  63. package/package.json +32 -7
  64. package/src/cli.ts +0 -410
  65. package/src/commands/add.ts +0 -315
  66. package/src/commands/index.ts +0 -12
  67. package/src/commands/init.ts +0 -94
  68. package/src/commands/list.ts +0 -33
  69. package/src/commands/pipe.ts +0 -76
  70. package/src/commands/remove.ts +0 -57
  71. package/src/commands/run.ts +0 -80
  72. package/src/commands/update.ts +0 -130
  73. package/src/commands/versions.ts +0 -79
  74. package/src/index.ts +0 -55
  75. package/src/mcp/index.ts +0 -5
  76. package/src/mcp/server.ts +0 -403
  77. package/src/modules/index.ts +0 -7
  78. package/src/modules/loader.ts +0 -318
  79. package/src/modules/runner.ts +0 -495
  80. package/src/modules/subagent.ts +0 -275
  81. package/src/providers/anthropic.ts +0 -89
  82. package/src/providers/base.ts +0 -29
  83. package/src/providers/deepseek.ts +0 -83
  84. package/src/providers/gemini.ts +0 -117
  85. package/src/providers/index.ts +0 -78
  86. package/src/providers/minimax.ts +0 -81
  87. package/src/providers/moonshot.ts +0 -82
  88. package/src/providers/ollama.ts +0 -83
  89. package/src/providers/openai.ts +0 -84
  90. package/src/providers/qwen.ts +0 -82
  91. package/src/server/http.ts +0 -316
  92. package/src/server/index.ts +0 -6
  93. package/src/types.ts +0 -495
  94. package/tsconfig.json +0 -17
@@ -12,12 +12,14 @@ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSche
12
12
  import { findModule, listModules, getDefaultSearchPaths } from '../modules/loader.js';
13
13
  import { runModule } from '../modules/runner.js';
14
14
  import { getProvider } from '../providers/index.js';
15
+ import { VERSION } from '../version.js';
16
+ import { ErrorCodes, attachContext, makeErrorEnvelope, makeMcpError, makeMcpSuccess } from '../errors/index.js';
15
17
  // =============================================================================
16
18
  // Server Setup
17
19
  // =============================================================================
18
20
  const server = new Server({
19
21
  name: 'cognitive-modules',
20
- version: '1.3.0',
22
+ version: VERSION,
21
23
  }, {
22
24
  capabilities: {
23
25
  tools: {},
@@ -35,7 +37,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
35
37
  tools: [
36
38
  {
37
39
  name: 'cognitive_run',
38
- description: 'Run a Cognitive Module to get structured AI analysis results',
40
+ description: 'Run a Cognitive Module to get structured AI analysis results (Cognitive Protocol v2.2)',
39
41
  inputSchema: {
40
42
  type: 'object',
41
43
  properties: {
@@ -61,7 +63,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
61
63
  },
62
64
  {
63
65
  name: 'cognitive_list',
64
- description: 'List all installed Cognitive Modules',
66
+ description: 'List all installed Cognitive Modules (Cognitive Protocol v2.2)',
65
67
  inputSchema: {
66
68
  type: 'object',
67
69
  properties: {},
@@ -69,7 +71,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
69
71
  },
70
72
  {
71
73
  name: 'cognitive_info',
72
- description: 'Get detailed information about a Cognitive Module',
74
+ description: 'Get detailed information about a Cognitive Module (Cognitive Protocol v2.2)',
73
75
  inputSchema: {
74
76
  type: 'object',
75
77
  properties: {
@@ -84,113 +86,105 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
84
86
  ],
85
87
  };
86
88
  });
89
+ // Error handling now uses unified errors module (../errors/index.js)
87
90
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
88
91
  const { name, arguments: args } = request.params;
92
+ const runContext = name === 'cognitive_run'
93
+ ? { module: args.module, provider: args.provider ?? 'unknown' }
94
+ : undefined;
89
95
  try {
90
96
  switch (name) {
91
97
  case 'cognitive_run': {
92
98
  const { module: moduleName, args: inputArgs, provider: providerName, model } = args;
99
+ const providerLabel = providerName ?? 'unknown';
93
100
  // Find module
94
101
  const moduleData = await findModule(moduleName, searchPaths);
95
102
  if (!moduleData) {
96
- return {
97
- content: [
98
- {
99
- type: 'text',
100
- text: JSON.stringify({ ok: false, error: `Module '${moduleName}' not found` }),
101
- },
102
- ],
103
- };
103
+ return makeMcpError({
104
+ code: ErrorCodes.MODULE_NOT_FOUND,
105
+ message: `Module '${moduleName}' not found`,
106
+ suggestion: 'Use cognitive_list to see available modules',
107
+ module: moduleName,
108
+ provider: providerLabel,
109
+ });
104
110
  }
105
111
  // Create provider
106
112
  const provider = getProvider(providerName, model);
107
- // Run module
113
+ const resolvedProvider = provider?.name ?? providerLabel;
114
+ // Run module - result is already v2.2 envelope
108
115
  const result = await runModule(moduleData, provider, {
109
- input: { query: inputArgs, code: inputArgs },
116
+ args: inputArgs,
110
117
  useV22: true,
111
118
  });
119
+ const contextual = attachContext(result, {
120
+ module: moduleName,
121
+ provider: resolvedProvider,
122
+ });
112
123
  return {
113
124
  content: [
114
125
  {
115
126
  type: 'text',
116
- text: JSON.stringify(result, null, 2),
127
+ text: JSON.stringify(contextual, null, 2),
117
128
  },
118
129
  ],
119
130
  };
120
131
  }
121
132
  case 'cognitive_list': {
122
133
  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
- };
134
+ return makeMcpSuccess({
135
+ data: {
136
+ modules: modules.map((m) => ({
137
+ name: m.name,
138
+ location: m.location,
139
+ format: m.format,
140
+ tier: m.tier,
141
+ responsibility: m.responsibility,
142
+ })),
143
+ count: modules.length,
144
+ },
145
+ explain: `Found ${modules.length} installed modules`,
146
+ });
139
147
  }
140
148
  case 'cognitive_info': {
141
149
  const { module: moduleName } = args;
142
150
  const moduleData = await findModule(moduleName, searchPaths);
143
151
  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
+ return makeMcpError({
153
+ code: ErrorCodes.MODULE_NOT_FOUND,
154
+ message: `Module '${moduleName}' not found`,
155
+ suggestion: 'Use cognitive_list to see available modules',
156
+ module: moduleName,
157
+ });
152
158
  }
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
- };
159
+ return makeMcpSuccess({
160
+ data: {
161
+ name: moduleData.name,
162
+ version: moduleData.version,
163
+ responsibility: moduleData.responsibility,
164
+ tier: moduleData.tier,
165
+ format: moduleData.format,
166
+ inputSchema: moduleData.inputSchema,
167
+ outputSchema: moduleData.outputSchema,
168
+ },
169
+ explain: `Module '${moduleName}' info retrieved`,
170
+ });
170
171
  }
171
172
  default:
172
- return {
173
- content: [
174
- {
175
- type: 'text',
176
- text: JSON.stringify({ ok: false, error: `Unknown tool: ${name}` }),
177
- },
178
- ],
179
- };
173
+ return makeMcpError({
174
+ code: ErrorCodes.INVALID_REFERENCE,
175
+ message: `Unknown tool: ${name}`,
176
+ suggestion: 'Use cognitive_run, cognitive_list, or cognitive_info',
177
+ });
180
178
  }
181
179
  }
182
180
  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
- };
181
+ const errorMessage = error instanceof Error ? error.message : String(error);
182
+ return makeMcpError({
183
+ code: ErrorCodes.INTERNAL_ERROR,
184
+ message: errorMessage,
185
+ recoverable: false,
186
+ ...(runContext ?? {}),
187
+ });
194
188
  }
195
189
  });
196
190
  // =============================================================================
@@ -234,12 +228,17 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
234
228
  const moduleName = match[1];
235
229
  const moduleData = await findModule(moduleName, searchPaths);
236
230
  if (!moduleData) {
231
+ const envelope = attachContext(makeErrorEnvelope({
232
+ code: ErrorCodes.MODULE_NOT_FOUND,
233
+ message: `Module '${moduleName}' not found`,
234
+ recoverable: true,
235
+ }), { module: moduleName });
237
236
  return {
238
237
  contents: [
239
238
  {
240
239
  uri,
241
- mimeType: 'text/plain',
242
- text: `Module '${moduleName}' not found`,
240
+ mimeType: 'application/json',
241
+ text: JSON.stringify(envelope, null, 2),
243
242
  },
244
243
  ],
245
244
  };
@@ -254,12 +253,18 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
254
253
  ],
255
254
  };
256
255
  }
256
+ // Return structured error for unknown resource
257
+ const envelope = makeErrorEnvelope({
258
+ code: ErrorCodes.RESOURCE_NOT_FOUND,
259
+ message: `Unknown resource: ${uri}`,
260
+ recoverable: true,
261
+ });
257
262
  return {
258
263
  contents: [
259
264
  {
260
265
  uri,
261
- mimeType: 'text/plain',
262
- text: `Unknown resource: ${uri}`,
266
+ mimeType: 'application/json',
267
+ text: JSON.stringify(envelope, null, 2),
263
268
  },
264
269
  ],
265
270
  };
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Composition Engine - Module Composition and Orchestration
3
+ *
4
+ * Implements COMPOSITION.md specification:
5
+ * - Sequential Composition: A → B → C
6
+ * - Parallel Composition: A → [B, C, D] → Aggregator
7
+ * - Conditional Composition: A → (condition) → B or C
8
+ * - Iterative Composition: A → (check) → A → ... → Done
9
+ * - Dataflow Mapping: JSONPath-like expressions
10
+ * - Aggregation Strategies: merge, array, first, custom
11
+ * - Dependency Resolution with fallbacks
12
+ * - Timeout handling
13
+ * - Circular dependency detection
14
+ */
15
+ import type { CognitiveModule, ModuleResult, ModuleInput, Provider } from '../types.js';
16
+ /** Composition pattern types */
17
+ export type CompositionPattern = 'sequential' | 'parallel' | 'conditional' | 'iterative';
18
+ /** Aggregation strategy for combining multiple outputs */
19
+ export type AggregationStrategy = 'merge' | 'array' | 'first' | 'custom';
20
+ /** Semver-like version matching pattern */
21
+ export type VersionPattern = string;
22
+ /** Dependency declaration for composition.requires */
23
+ export interface DependencyDeclaration {
24
+ /** Module name */
25
+ name: string;
26
+ /** Semver version pattern */
27
+ version?: VersionPattern;
28
+ /** Whether dependency is optional */
29
+ optional?: boolean;
30
+ /** Fallback module if unavailable */
31
+ fallback?: string | null;
32
+ /** Per-module timeout (ms) */
33
+ timeout_ms?: number;
34
+ }
35
+ /** Dataflow mapping expression */
36
+ export interface DataflowMapping {
37
+ [key: string]: string;
38
+ }
39
+ /** Condition expression for routing */
40
+ export interface ConditionExpression {
41
+ expression: string;
42
+ }
43
+ /** Dataflow step configuration */
44
+ export interface DataflowStep {
45
+ /** Source of data: 'input' or 'module-name.output' */
46
+ from: string | string[];
47
+ /** Destination: module name or 'output' */
48
+ to: string | string[];
49
+ /** Field mapping expressions */
50
+ mapping?: DataflowMapping;
51
+ /** Condition for execution */
52
+ condition?: string;
53
+ /** Aggregation strategy when from is an array */
54
+ aggregate?: AggregationStrategy;
55
+ /** Custom aggregation function name */
56
+ aggregator?: string;
57
+ }
58
+ /** Conditional routing rule */
59
+ export interface RoutingRule {
60
+ /** Condition expression */
61
+ condition: string;
62
+ /** Next module to execute (null means use current result) */
63
+ next: string | null;
64
+ }
65
+ /** Full composition configuration (from module.yaml) */
66
+ export interface CompositionConfig {
67
+ /** Composition pattern */
68
+ pattern: CompositionPattern;
69
+ /** Required dependencies */
70
+ requires?: DependencyDeclaration[];
71
+ /** Dataflow configuration */
72
+ dataflow?: DataflowStep[];
73
+ /** Conditional routing rules */
74
+ routing?: RoutingRule[];
75
+ /** Maximum composition depth */
76
+ max_depth?: number;
77
+ /** Total timeout for composition (ms) */
78
+ timeout_ms?: number;
79
+ /** Iteration configuration */
80
+ iteration?: {
81
+ /** Maximum iterations */
82
+ max_iterations?: number;
83
+ /** Condition to continue iterating */
84
+ continue_condition?: string;
85
+ /** Condition to stop iterating */
86
+ stop_condition?: string;
87
+ };
88
+ }
89
+ /** Execution context for composition */
90
+ export interface CompositionContext {
91
+ /** Current execution depth */
92
+ depth: number;
93
+ /** Maximum allowed depth */
94
+ maxDepth: number;
95
+ /** Results from completed modules */
96
+ results: Record<string, ModuleResult>;
97
+ /** Original input data */
98
+ input: ModuleInput;
99
+ /** Currently running modules (for circular detection) */
100
+ running: Set<string>;
101
+ /** Start time for timeout tracking */
102
+ startTime: number;
103
+ /** Total timeout (ms) */
104
+ timeoutMs?: number;
105
+ /** Iteration count (for iterative composition) */
106
+ iterationCount: number;
107
+ }
108
+ /** Result of composition execution */
109
+ export interface CompositionResult {
110
+ /** Whether composition succeeded */
111
+ ok: boolean;
112
+ /** Final aggregated result */
113
+ result?: ModuleResult;
114
+ /** Results from all executed modules */
115
+ moduleResults: Record<string, ModuleResult>;
116
+ /** Execution trace for debugging */
117
+ trace: ExecutionTrace[];
118
+ /** Total execution time (ms) */
119
+ totalTimeMs: number;
120
+ /** Error if composition failed */
121
+ error?: {
122
+ code: string;
123
+ message: string;
124
+ module?: string;
125
+ };
126
+ }
127
+ /** Execution trace entry */
128
+ export interface ExecutionTrace {
129
+ module: string;
130
+ startTime: number;
131
+ endTime: number;
132
+ durationMs: number;
133
+ success: boolean;
134
+ skipped?: boolean;
135
+ reason?: string;
136
+ }
137
+ export declare const COMPOSITION_ERRORS: {
138
+ readonly E4004: "CIRCULAR_DEPENDENCY";
139
+ readonly E4005: "MAX_DEPTH_EXCEEDED";
140
+ readonly E4008: "COMPOSITION_TIMEOUT";
141
+ readonly E4009: "DEPENDENCY_NOT_FOUND";
142
+ readonly E4010: "DATAFLOW_ERROR";
143
+ readonly E4011: "CONDITION_EVAL_ERROR";
144
+ readonly E4012: "AGGREGATION_ERROR";
145
+ readonly E4013: "ITERATION_LIMIT_EXCEEDED";
146
+ };
147
+ /**
148
+ * Parse and evaluate JSONPath-like expressions.
149
+ *
150
+ * Supported syntax:
151
+ * - $.field - Root field access
152
+ * - $.nested.field - Nested access
153
+ * - $.array[0] - Array index
154
+ * - $.array[*].field - Array map
155
+ * - $ - Entire object
156
+ */
157
+ export declare function evaluateJsonPath(expression: string, data: unknown): unknown;
158
+ /**
159
+ * Apply dataflow mapping to transform data
160
+ */
161
+ export declare function applyMapping(mapping: DataflowMapping, sourceData: unknown): Record<string, unknown>;
162
+ /**
163
+ * Evaluate condition expressions.
164
+ *
165
+ * Supported operators:
166
+ * - Comparison: ==, !=, >, <, >=, <=
167
+ * - Logical: &&, ||, !
168
+ * - Existence: exists($.field)
169
+ * - String: contains($.field, "value")
170
+ */
171
+ export declare function evaluateCondition(expression: string, data: unknown): boolean;
172
+ /**
173
+ * Aggregate multiple results using specified strategy
174
+ */
175
+ export declare function aggregateResults(results: ModuleResult[], strategy: AggregationStrategy): ModuleResult;
176
+ /**
177
+ * Check if version matches pattern (simplified semver)
178
+ */
179
+ export declare function versionMatches(version: string, pattern: string): boolean;
180
+ /**
181
+ * Resolve a dependency, checking version and trying fallbacks
182
+ */
183
+ export declare function resolveDependency(dep: DependencyDeclaration, searchPaths: string[]): Promise<CognitiveModule | null>;
184
+ export declare class CompositionOrchestrator {
185
+ private provider;
186
+ private cwd;
187
+ private searchPaths;
188
+ constructor(provider: Provider, cwd?: string);
189
+ /**
190
+ * Execute a composed module workflow
191
+ */
192
+ execute(moduleName: string, input: ModuleInput, options?: {
193
+ maxDepth?: number;
194
+ timeoutMs?: number;
195
+ }): Promise<CompositionResult>;
196
+ /**
197
+ * Get composition config from module (if exists)
198
+ */
199
+ private getCompositionConfig;
200
+ /**
201
+ * Execute composition based on pattern
202
+ */
203
+ private executeComposition;
204
+ /**
205
+ * Execute sequential composition: A → B → C
206
+ */
207
+ private executeSequential;
208
+ /**
209
+ * Execute parallel composition: A → [B, C, D] → Aggregator
210
+ */
211
+ private executeParallel;
212
+ /**
213
+ * Execute conditional composition: A → (condition) → B or C
214
+ */
215
+ private executeConditional;
216
+ /**
217
+ * Execute iterative composition: A → (check) → A → ... → Done
218
+ */
219
+ private executeIterative;
220
+ /**
221
+ * Execute a single module
222
+ */
223
+ private executeModule;
224
+ /**
225
+ * Execute module with timeout
226
+ */
227
+ private executeModuleWithTimeout;
228
+ /**
229
+ * Check if composition has timed out
230
+ */
231
+ private isTimedOut;
232
+ /**
233
+ * Create timeout error response
234
+ */
235
+ private timeoutError;
236
+ }
237
+ /**
238
+ * Execute a composed module workflow
239
+ */
240
+ export declare function executeComposition(moduleName: string, input: ModuleInput, provider: Provider, options?: {
241
+ cwd?: string;
242
+ maxDepth?: number;
243
+ timeoutMs?: number;
244
+ }): Promise<CompositionResult>;
245
+ /**
246
+ * Validate composition configuration
247
+ */
248
+ export declare function validateCompositionConfig(config: CompositionConfig): {
249
+ valid: boolean;
250
+ errors: string[];
251
+ };