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
@@ -1,318 +0,0 @@
1
- /**
2
- * Module Loader - Load and parse Cognitive Modules
3
- * Supports both v1 (MODULE.md) and v2 (module.yaml + prompt.md) formats
4
- */
5
-
6
- import * as fs from 'node:fs/promises';
7
- import * as path from 'node:path';
8
- import yaml from 'js-yaml';
9
- import type {
10
- CognitiveModule,
11
- ModuleConstraints,
12
- ModulePolicies,
13
- ToolsPolicy,
14
- OutputContract,
15
- FailureContract,
16
- RuntimeRequirements,
17
- OverflowConfig,
18
- EnumConfig,
19
- CompatConfig,
20
- MetaConfig,
21
- ModuleTier,
22
- SchemaStrictness
23
- } from '../types.js';
24
-
25
- const FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n([\s\S]*))?/;
26
-
27
- /**
28
- * Detect module format version
29
- */
30
- async function detectFormat(modulePath: string): Promise<'v1' | 'v2'> {
31
- const v2Manifest = path.join(modulePath, 'module.yaml');
32
- try {
33
- await fs.access(v2Manifest);
34
- return 'v2';
35
- } catch {
36
- return 'v1';
37
- }
38
- }
39
-
40
- /**
41
- * Detect v2.x sub-version from manifest
42
- */
43
- function detectV2Version(manifest: Record<string, unknown>): string {
44
- if (manifest.tier || manifest.overflow || manifest.enums) {
45
- return 'v2.2';
46
- }
47
- if (manifest.policies || manifest.failure) {
48
- return 'v2.1';
49
- }
50
- return 'v2.0';
51
- }
52
-
53
- /**
54
- * Load v2 format module (module.yaml + prompt.md)
55
- */
56
- async function loadModuleV2(modulePath: string): Promise<CognitiveModule> {
57
- const manifestFile = path.join(modulePath, 'module.yaml');
58
- const promptFile = path.join(modulePath, 'prompt.md');
59
- const schemaFile = path.join(modulePath, 'schema.json');
60
-
61
- // Read module.yaml
62
- const manifestContent = await fs.readFile(manifestFile, 'utf-8');
63
- const manifest = yaml.load(manifestContent) as Record<string, unknown>;
64
-
65
- // Detect v2.x version
66
- const formatVersion = detectV2Version(manifest);
67
-
68
- // Read prompt.md
69
- let prompt = '';
70
- try {
71
- prompt = await fs.readFile(promptFile, 'utf-8');
72
- } catch {
73
- // prompt.md is optional, manifest may include inline prompt
74
- }
75
-
76
- // Read schema.json
77
- let inputSchema: object | undefined;
78
- let outputSchema: object | undefined;
79
- let dataSchema: object | undefined;
80
- let metaSchema: object | undefined;
81
- let errorSchema: object | undefined;
82
-
83
- try {
84
- const schemaContent = await fs.readFile(schemaFile, 'utf-8');
85
- const schema = JSON.parse(schemaContent);
86
- inputSchema = schema.input;
87
- // Support both "data" (v2.2) and "output" (v2.1) aliases
88
- dataSchema = schema.data || schema.output;
89
- outputSchema = dataSchema; // Backward compat
90
- metaSchema = schema.meta;
91
- errorSchema = schema.error;
92
- } catch {
93
- // Schema file is optional but recommended
94
- }
95
-
96
- // Extract v2.2 fields
97
- const tier = manifest.tier as ModuleTier | undefined;
98
- const schemaStrictness = (manifest.schema_strictness as SchemaStrictness) || 'medium';
99
-
100
- // Determine default max_items based on strictness (SPEC-v2.2)
101
- const strictnessMaxItems: Record<SchemaStrictness, number> = {
102
- high: 0,
103
- medium: 5,
104
- low: 20
105
- };
106
- const defaultMaxItems = strictnessMaxItems[schemaStrictness] ?? 5;
107
- const defaultEnabled = schemaStrictness !== 'high';
108
-
109
- // Parse overflow config with strictness-based defaults
110
- const overflowRaw = (manifest.overflow as Record<string, unknown>) || {};
111
- const overflow: OverflowConfig = {
112
- enabled: (overflowRaw.enabled as boolean) ?? defaultEnabled,
113
- recoverable: (overflowRaw.recoverable as boolean) ?? true,
114
- max_items: (overflowRaw.max_items as number) ?? defaultMaxItems,
115
- require_suggested_mapping: (overflowRaw.require_suggested_mapping as boolean) ?? true
116
- };
117
-
118
- // Parse enums config
119
- const enumsRaw = (manifest.enums as Record<string, unknown>) || {};
120
- const enums: EnumConfig = {
121
- strategy: (enumsRaw.strategy as 'strict' | 'extensible') ??
122
- (tier === 'exec' ? 'strict' : 'extensible'),
123
- unknown_tag: (enumsRaw.unknown_tag as string) ?? 'custom'
124
- };
125
-
126
- // Parse compat config
127
- const compatRaw = (manifest.compat as Record<string, unknown>) || {};
128
- const compat: CompatConfig = {
129
- accepts_v21_payload: (compatRaw.accepts_v21_payload as boolean) ?? true,
130
- runtime_auto_wrap: (compatRaw.runtime_auto_wrap as boolean) ?? true,
131
- schema_output_alias: (compatRaw.schema_output_alias as 'data' | 'output') ?? 'data'
132
- };
133
-
134
- // Parse meta config (including risk_rule) with validation
135
- const metaRaw = (manifest.meta as Record<string, unknown>) || {};
136
- const rawRiskRule = metaRaw.risk_rule as string | undefined;
137
- const validRiskRules = ['max_changes_risk', 'max_issues_risk', 'explicit'];
138
- const validatedRiskRule = rawRiskRule && validRiskRules.includes(rawRiskRule)
139
- ? rawRiskRule as 'max_changes_risk' | 'max_issues_risk' | 'explicit'
140
- : undefined;
141
-
142
- const metaConfig: MetaConfig = {
143
- required: metaRaw.required as string[] | undefined,
144
- risk_rule: validatedRiskRule,
145
- };
146
-
147
- return {
148
- name: manifest.name as string || path.basename(modulePath),
149
- version: manifest.version as string || '1.0.0',
150
- responsibility: manifest.responsibility as string || '',
151
- excludes: (manifest.excludes as string[]) || [],
152
- constraints: manifest.constraints as ModuleConstraints | undefined,
153
- policies: manifest.policies as ModulePolicies | undefined,
154
- tools: manifest.tools as ToolsPolicy | undefined,
155
- output: manifest.output as OutputContract | undefined,
156
- failure: manifest.failure as FailureContract | undefined,
157
- runtimeRequirements: manifest.runtime_requirements as RuntimeRequirements | undefined,
158
- // v2.2 fields
159
- tier,
160
- schemaStrictness,
161
- overflow,
162
- enums,
163
- compat,
164
- metaConfig,
165
- // Context and prompt
166
- context: manifest.context as 'fork' | 'main' | undefined,
167
- prompt,
168
- // Schemas
169
- inputSchema,
170
- outputSchema,
171
- dataSchema,
172
- metaSchema,
173
- errorSchema,
174
- // Metadata
175
- location: modulePath,
176
- format: 'v2',
177
- formatVersion,
178
- };
179
- }
180
-
181
- /**
182
- * Load v1 format module (MODULE.md with frontmatter)
183
- */
184
- async function loadModuleV1(modulePath: string): Promise<CognitiveModule> {
185
- const moduleFile = path.join(modulePath, 'MODULE.md');
186
- const schemaFile = path.join(modulePath, 'schema.json');
187
-
188
- // Read MODULE.md
189
- const moduleContent = await fs.readFile(moduleFile, 'utf-8');
190
-
191
- // Parse frontmatter
192
- const match = moduleContent.match(FRONTMATTER_REGEX);
193
- if (!match) {
194
- throw new Error(`Invalid MODULE.md: missing YAML frontmatter in ${moduleFile}`);
195
- }
196
-
197
- const frontmatter = yaml.load(match[1]) as Record<string, unknown>;
198
- const prompt = (match[2] || '').trim();
199
-
200
- // Read schema.json
201
- let inputSchema: object | undefined;
202
- let outputSchema: object | undefined;
203
-
204
- try {
205
- const schemaContent = await fs.readFile(schemaFile, 'utf-8');
206
- const schema = JSON.parse(schemaContent);
207
- inputSchema = schema.input;
208
- outputSchema = schema.output;
209
- } catch {
210
- // Schema file is optional
211
- }
212
-
213
- // Extract constraints from v1 format
214
- const constraints: ModuleConstraints = {};
215
- const v1Constraints = frontmatter.constraints as Record<string, boolean> | undefined;
216
- if (v1Constraints) {
217
- constraints.no_network = v1Constraints.no_network;
218
- constraints.no_side_effects = v1Constraints.no_side_effects;
219
- constraints.no_inventing_data = v1Constraints.no_inventing_data;
220
- }
221
-
222
- return {
223
- name: frontmatter.name as string || path.basename(modulePath),
224
- version: frontmatter.version as string || '1.0.0',
225
- responsibility: frontmatter.responsibility as string || '',
226
- excludes: (frontmatter.excludes as string[]) || [],
227
- constraints: Object.keys(constraints).length > 0 ? constraints : undefined,
228
- context: frontmatter.context as 'fork' | 'main' | undefined,
229
- prompt,
230
- inputSchema,
231
- outputSchema,
232
- location: modulePath,
233
- format: 'v1',
234
- };
235
- }
236
-
237
- /**
238
- * Load a Cognitive Module (auto-detects format)
239
- */
240
- export async function loadModule(modulePath: string): Promise<CognitiveModule> {
241
- const format = await detectFormat(modulePath);
242
-
243
- if (format === 'v2') {
244
- return loadModuleV2(modulePath);
245
- } else {
246
- return loadModuleV1(modulePath);
247
- }
248
- }
249
-
250
- /**
251
- * Check if a directory contains a valid module
252
- */
253
- async function isValidModule(modulePath: string): Promise<boolean> {
254
- const v2Manifest = path.join(modulePath, 'module.yaml');
255
- const v1Module = path.join(modulePath, 'MODULE.md');
256
-
257
- try {
258
- await fs.access(v2Manifest);
259
- return true;
260
- } catch {
261
- try {
262
- await fs.access(v1Module);
263
- return true;
264
- } catch {
265
- return false;
266
- }
267
- }
268
- }
269
-
270
- export async function findModule(name: string, searchPaths: string[]): Promise<CognitiveModule | null> {
271
- for (const basePath of searchPaths) {
272
- const modulePath = path.join(basePath, name);
273
-
274
- if (await isValidModule(modulePath)) {
275
- return await loadModule(modulePath);
276
- }
277
- }
278
-
279
- return null;
280
- }
281
-
282
- export async function listModules(searchPaths: string[]): Promise<CognitiveModule[]> {
283
- const modules: CognitiveModule[] = [];
284
-
285
- for (const basePath of searchPaths) {
286
- try {
287
- const entries = await fs.readdir(basePath, { withFileTypes: true });
288
-
289
- for (const entry of entries) {
290
- if (entry.isDirectory()) {
291
- const modulePath = path.join(basePath, entry.name);
292
-
293
- if (await isValidModule(modulePath)) {
294
- try {
295
- const module = await loadModule(modulePath);
296
- modules.push(module);
297
- } catch {
298
- // Skip invalid modules
299
- }
300
- }
301
- }
302
- }
303
- } catch {
304
- // Path doesn't exist, skip
305
- }
306
- }
307
-
308
- return modules;
309
- }
310
-
311
- export function getDefaultSearchPaths(cwd: string): string[] {
312
- const home = process.env.HOME || '';
313
- return [
314
- path.join(cwd, 'cognitive', 'modules'),
315
- path.join(cwd, '.cognitive', 'modules'),
316
- path.join(home, '.cognitive', 'modules'),
317
- ];
318
- }