neuronlayer 0.1.0 → 1.1.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 (78) hide show
  1. package/README.md +203 -123
  2. package/dist/index.js +635 -710
  3. package/dist/index.js.map +7 -0
  4. package/package.json +67 -63
  5. package/CONTRIBUTING.md +0 -127
  6. package/esbuild.config.js +0 -26
  7. package/src/cli/commands.ts +0 -382
  8. package/src/core/adr-exporter.ts +0 -253
  9. package/src/core/architecture/architecture-enforcement.ts +0 -228
  10. package/src/core/architecture/duplicate-detector.ts +0 -288
  11. package/src/core/architecture/index.ts +0 -6
  12. package/src/core/architecture/pattern-learner.ts +0 -306
  13. package/src/core/architecture/pattern-library.ts +0 -403
  14. package/src/core/architecture/pattern-validator.ts +0 -324
  15. package/src/core/change-intelligence/bug-correlator.ts +0 -444
  16. package/src/core/change-intelligence/change-intelligence.ts +0 -221
  17. package/src/core/change-intelligence/change-tracker.ts +0 -334
  18. package/src/core/change-intelligence/fix-suggester.ts +0 -340
  19. package/src/core/change-intelligence/index.ts +0 -5
  20. package/src/core/code-verifier.ts +0 -843
  21. package/src/core/confidence/confidence-scorer.ts +0 -251
  22. package/src/core/confidence/conflict-checker.ts +0 -289
  23. package/src/core/confidence/index.ts +0 -5
  24. package/src/core/confidence/source-tracker.ts +0 -263
  25. package/src/core/confidence/warning-detector.ts +0 -241
  26. package/src/core/context-rot/compaction.ts +0 -284
  27. package/src/core/context-rot/context-health.ts +0 -243
  28. package/src/core/context-rot/context-rot-prevention.ts +0 -213
  29. package/src/core/context-rot/critical-context.ts +0 -221
  30. package/src/core/context-rot/drift-detector.ts +0 -255
  31. package/src/core/context-rot/index.ts +0 -7
  32. package/src/core/context.ts +0 -263
  33. package/src/core/decision-extractor.ts +0 -339
  34. package/src/core/decisions.ts +0 -69
  35. package/src/core/deja-vu.ts +0 -421
  36. package/src/core/engine.ts +0 -1455
  37. package/src/core/feature-context.ts +0 -726
  38. package/src/core/ghost-mode.ts +0 -412
  39. package/src/core/learning.ts +0 -485
  40. package/src/core/living-docs/activity-tracker.ts +0 -296
  41. package/src/core/living-docs/architecture-generator.ts +0 -428
  42. package/src/core/living-docs/changelog-generator.ts +0 -348
  43. package/src/core/living-docs/component-generator.ts +0 -230
  44. package/src/core/living-docs/doc-engine.ts +0 -110
  45. package/src/core/living-docs/doc-validator.ts +0 -282
  46. package/src/core/living-docs/index.ts +0 -8
  47. package/src/core/project-manager.ts +0 -297
  48. package/src/core/summarizer.ts +0 -267
  49. package/src/core/test-awareness/change-validator.ts +0 -499
  50. package/src/core/test-awareness/index.ts +0 -5
  51. package/src/index.ts +0 -49
  52. package/src/indexing/ast.ts +0 -563
  53. package/src/indexing/embeddings.ts +0 -85
  54. package/src/indexing/indexer.ts +0 -245
  55. package/src/indexing/watcher.ts +0 -78
  56. package/src/server/gateways/aggregator.ts +0 -374
  57. package/src/server/gateways/index.ts +0 -473
  58. package/src/server/gateways/memory-ghost.ts +0 -343
  59. package/src/server/gateways/memory-query.ts +0 -452
  60. package/src/server/gateways/memory-record.ts +0 -346
  61. package/src/server/gateways/memory-review.ts +0 -410
  62. package/src/server/gateways/memory-status.ts +0 -517
  63. package/src/server/gateways/memory-verify.ts +0 -392
  64. package/src/server/gateways/router.ts +0 -434
  65. package/src/server/gateways/types.ts +0 -610
  66. package/src/server/mcp.ts +0 -154
  67. package/src/server/resources.ts +0 -85
  68. package/src/server/tools.ts +0 -2261
  69. package/src/storage/database.ts +0 -262
  70. package/src/storage/tier1.ts +0 -135
  71. package/src/storage/tier2.ts +0 -764
  72. package/src/storage/tier3.ts +0 -123
  73. package/src/types/documentation.ts +0 -619
  74. package/src/types/index.ts +0 -222
  75. package/src/utils/config.ts +0 -193
  76. package/src/utils/files.ts +0 -117
  77. package/src/utils/time.ts +0 -37
  78. package/src/utils/tokens.ts +0 -52
package/package.json CHANGED
@@ -1,63 +1,67 @@
1
- {
2
- "name": "neuronlayer",
3
- "version": "0.1.0",
4
- "description": "Persistent memory layer for AI coding assistants - MCP server that makes AI truly understand your codebase",
5
- "type": "module",
6
- "main": "dist/index.js",
7
- "bin": {
8
- "neuronlayer": "dist/index.js"
9
- },
10
- "scripts": {
11
- "build": "node esbuild.config.js",
12
- "build:benchmark": "node esbuild.benchmark.cjs",
13
- "build:all": "npm run build && npm run build:benchmark",
14
- "dev": "node --watch dist/index.js",
15
- "start": "node dist/index.js",
16
- "typecheck": "tsc --noEmit",
17
- "test": "vitest",
18
- "test:run": "vitest run",
19
- "benchmark": "npm run build:all && node dist/benchmark/working-benchmark.js",
20
- "benchmark:quick": "npm run build:all && node dist/benchmark/working-benchmark.js --quick",
21
- "benchmark:full": "npm run build:all && node dist/benchmark/working-benchmark.js --iterations 50"
22
- },
23
- "keywords": [
24
- "mcp",
25
- "ai",
26
- "memory",
27
- "context",
28
- "codebase",
29
- "claude",
30
- "embeddings",
31
- "agent",
32
- "coding-assistant",
33
- "llm"
34
- ],
35
- "author": "Abhishek Arun Savakar <abhishek@savakar.com> (https://savakar.com)",
36
- "license": "MIT",
37
- "repository": {
38
- "type": "git",
39
- "url": "git+https://github.com/abhisavakar/memorylayer.git"
40
- },
41
- "bugs": {
42
- "url": "https://github.com/abhisavakar/memorylayer/issues"
43
- },
44
- "homepage": "https://github.com/abhisavakar/memorylayer#readme",
45
- "dependencies": {
46
- "@modelcontextprotocol/sdk": "^1.0.0",
47
- "@xenova/transformers": "^2.17.0",
48
- "better-sqlite3": "^11.0.0",
49
- "chokidar": "^3.6.0",
50
- "glob": "^10.0.0",
51
- "web-tree-sitter": "^0.22.0"
52
- },
53
- "devDependencies": {
54
- "@types/better-sqlite3": "^7.6.0",
55
- "@types/node": "^20.0.0",
56
- "esbuild": "^0.20.0",
57
- "typescript": "^5.4.0",
58
- "vitest": "^1.3.0"
59
- },
60
- "engines": {
61
- "node": ">=18.0.0"
62
- }
63
- }
1
+ {
2
+ "name": "neuronlayer",
3
+ "version": "1.1.0",
4
+ "description": "Turn any AI coding assistant into an intelligent one - MCP server with code intelligence, semantic search, and persistent memory",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "neuronlayer": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist/",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "scripts": {
16
+ "build": "node esbuild.config.js",
17
+ "build:benchmark": "node esbuild.benchmark.cjs",
18
+ "build:all": "npm run build && npm run build:benchmark",
19
+ "dev": "node --watch dist/index.js",
20
+ "start": "node dist/index.js",
21
+ "typecheck": "tsc --noEmit",
22
+ "test": "vitest",
23
+ "test:run": "vitest run",
24
+ "benchmark": "npm run build:all && node dist/benchmark/working-benchmark.js",
25
+ "benchmark:quick": "npm run build:all && node dist/benchmark/working-benchmark.js --quick",
26
+ "benchmark:full": "npm run build:all && node dist/benchmark/working-benchmark.js --iterations 50"
27
+ },
28
+ "keywords": [
29
+ "mcp",
30
+ "ai",
31
+ "memory",
32
+ "context",
33
+ "codebase",
34
+ "claude",
35
+ "embeddings",
36
+ "agent",
37
+ "coding-assistant",
38
+ "llm"
39
+ ],
40
+ "author": "Abhishek Arun Savakar <abhishek@savakar.com> (https://savakar.com)",
41
+ "license": "MIT",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/abhisavakar/neuronlayer.git"
45
+ },
46
+ "bugs": {
47
+ "url": "https://github.com/abhisavakar/neuronlayer/issues"
48
+ },
49
+ "homepage": "https://github.com/abhisavakar/neuronlayer#readme",
50
+ "dependencies": {
51
+ "@modelcontextprotocol/sdk": "^1.27.0",
52
+ "@xenova/transformers": "^2.17.0",
53
+ "better-sqlite3": "^11.8.0",
54
+ "chokidar": "^4.0.0",
55
+ "glob": "^13.0.0"
56
+ },
57
+ "devDependencies": {
58
+ "@types/better-sqlite3": "^7.6.0",
59
+ "@types/node": "^22.0.0",
60
+ "esbuild": "^0.25.0",
61
+ "typescript": "^5.7.0",
62
+ "vitest": "^3.0.0"
63
+ },
64
+ "engines": {
65
+ "node": ">=18.0.0"
66
+ }
67
+ }
package/CONTRIBUTING.md DELETED
@@ -1,127 +0,0 @@
1
- # Contributing to MemoryLayer
2
-
3
- Thank you for your interest in contributing to MemoryLayer! This document provides guidelines and information for contributors.
4
-
5
- ## Code of Conduct
6
-
7
- Be respectful, inclusive, and constructive. We're all here to build something great together.
8
-
9
- ## How to Contribute
10
-
11
- ### Reporting Bugs
12
-
13
- 1. Check existing issues to avoid duplicates
14
- 2. Use a clear, descriptive title
15
- 3. Include:
16
- - Steps to reproduce
17
- - Expected vs actual behavior
18
- - Environment (OS, Node.js version)
19
- - Relevant logs or error messages
20
-
21
- ### Suggesting Features
22
-
23
- 1. Check if the feature is already planned (see Roadmap in README)
24
- 2. Open an issue with `[Feature]` prefix
25
- 3. Describe the use case and proposed solution
26
- 4. Be open to discussion and alternatives
27
-
28
- ### Pull Requests
29
-
30
- 1. Fork the repository
31
- 2. Create a feature branch from `main`
32
- 3. Make your changes
33
- 4. Write/update tests as needed
34
- 5. Run `npm run typecheck` and `npm test`
35
- 6. Submit a PR with a clear description
36
-
37
- ## Development Setup
38
-
39
- ```bash
40
- # Clone your fork
41
- git clone https://github.com/YOUR_USERNAME/memorylayer.git
42
- cd memorylayer
43
-
44
- # Install dependencies
45
- npm install
46
-
47
- # Build
48
- npm run build
49
-
50
- # Run tests
51
- npm test
52
-
53
- # Type check
54
- npm run typecheck
55
- ```
56
-
57
- ## Project Structure
58
-
59
- ```
60
- src/
61
- ├── core/ # Business logic (engine, features)
62
- ├── server/ # MCP server and tools
63
- ├── storage/ # Data persistence (SQLite, vectors)
64
- ├── indexing/ # File indexing and AST
65
- ├── types/ # TypeScript type definitions
66
- ├── utils/ # Shared utilities
67
- └── agent/ # Standalone agent (optional)
68
- ```
69
-
70
- ## Coding Standards
71
-
72
- ### TypeScript
73
-
74
- - Use TypeScript strict mode
75
- - Prefer explicit types over `any`
76
- - Use interfaces for object shapes
77
- - Export types from `src/types/`
78
-
79
- ### Code Style
80
-
81
- - Use meaningful variable/function names
82
- - Keep functions focused and small
83
- - Add comments for non-obvious logic
84
- - Follow existing patterns in the codebase
85
-
86
- ### Testing
87
-
88
- - Write tests for new features
89
- - Tests go in `__tests__/` directories or `*.test.ts` files
90
- - Use Vitest for testing
91
-
92
- ### Commits
93
-
94
- - Use clear, descriptive commit messages
95
- - Follow conventional commits when possible:
96
- - `feat:` new features
97
- - `fix:` bug fixes
98
- - `docs:` documentation
99
- - `refactor:` code restructuring
100
- - `test:` test additions/changes
101
-
102
- ## Areas Where Help Is Needed
103
-
104
- ### High Priority
105
-
106
- 1. **Language Support** - Add AST parsing for Python, Go, Rust
107
- 2. **Bug Fixes** - Check open issues
108
- 3. **Test Coverage** - Increase test coverage
109
-
110
- ### Medium Priority
111
-
112
- 1. **Documentation** - Improve README, add examples
113
- 2. **Performance** - Optimize indexing and search
114
- 3. **IDE Extensions** - VS Code extension
115
-
116
- ### Good First Issues
117
-
118
- Look for issues labeled `good-first-issue` for beginner-friendly tasks.
119
-
120
- ## Questions?
121
-
122
- - Open a Discussion on GitHub
123
- - Check existing issues and documentation
124
-
125
- ## License
126
-
127
- By contributing, you agree that your contributions will be licensed under the MIT License.
package/esbuild.config.js DELETED
@@ -1,26 +0,0 @@
1
- import { build } from 'esbuild';
2
-
3
- const commonOptions = {
4
- bundle: true,
5
- platform: 'node',
6
- target: 'node18',
7
- format: 'esm',
8
- sourcemap: true,
9
- external: [
10
- 'better-sqlite3', // Native module
11
- '@xenova/transformers', // Large, keep external
12
- 'chokidar', // Uses CommonJS require
13
- 'glob', // Keep external
14
- 'web-tree-sitter' // WASM module
15
- ]
16
- };
17
-
18
- // Build main MCP server
19
- await build({
20
- ...commonOptions,
21
- entryPoints: ['src/index.ts'],
22
- outfile: 'dist/index.js',
23
- banner: { js: '#!/usr/bin/env node' },
24
- });
25
-
26
- console.log('Build complete!');
@@ -1,382 +0,0 @@
1
- import { ProjectManager, type ProjectInfo } from '../core/project-manager.js';
2
- import { ADRExporter } from '../core/adr-exporter.js';
3
- import { initializeDatabase } from '../storage/database.js';
4
- import { Tier2Storage } from '../storage/tier2.js';
5
- import { join } from 'path';
6
- import { existsSync } from 'fs';
7
-
8
- const projectManager = new ProjectManager();
9
-
10
- interface CommandResult {
11
- success: boolean;
12
- message: string;
13
- data?: unknown;
14
- }
15
-
16
- // List all projects
17
- export function listProjects(): CommandResult {
18
- const projects = projectManager.listProjects();
19
- const activeProject = projectManager.getActiveProject();
20
-
21
- if (projects.length === 0) {
22
- return {
23
- success: true,
24
- message: 'No projects registered. Use "memorylayer projects add <path>" to add one.'
25
- };
26
- }
27
-
28
- const lines = ['Registered Projects:', ''];
29
- for (const project of projects) {
30
- const isActive = activeProject?.id === project.id ? ' (active)' : '';
31
- lines.push(` ${project.name}${isActive}`);
32
- lines.push(` ID: ${project.id}`);
33
- lines.push(` Path: ${project.path}`);
34
- lines.push(` Files: ${project.totalFiles}, Decisions: ${project.totalDecisions}`);
35
- lines.push(` Languages: ${project.languages.join(', ') || 'N/A'}`);
36
- lines.push('');
37
- }
38
-
39
- return {
40
- success: true,
41
- message: lines.join('\n'),
42
- data: projects
43
- };
44
- }
45
-
46
- // Add a project
47
- export function addProject(projectPath: string): CommandResult {
48
- try {
49
- const projectInfo = projectManager.registerProject(projectPath);
50
- projectManager.setActiveProject(projectInfo.id);
51
-
52
- return {
53
- success: true,
54
- message: `Project "${projectInfo.name}" registered and set as active.\nID: ${projectInfo.id}\nData directory: ${projectInfo.dataDir}`,
55
- data: projectInfo
56
- };
57
- } catch (error) {
58
- return {
59
- success: false,
60
- message: `Failed to add project: ${error instanceof Error ? error.message : String(error)}`
61
- };
62
- }
63
- }
64
-
65
- // Remove a project
66
- export function removeProject(projectId: string): CommandResult {
67
- const project = projectManager.getProject(projectId);
68
-
69
- if (!project) {
70
- return {
71
- success: false,
72
- message: `Project not found: ${projectId}`
73
- };
74
- }
75
-
76
- const removed = projectManager.removeProject(projectId);
77
-
78
- return {
79
- success: removed,
80
- message: removed
81
- ? `Project "${project.name}" removed from registry.`
82
- : `Failed to remove project.`
83
- };
84
- }
85
-
86
- // Switch to a project
87
- export function switchProject(projectId: string): CommandResult {
88
- const project = projectManager.getProject(projectId);
89
-
90
- if (!project) {
91
- return {
92
- success: false,
93
- message: `Project not found: ${projectId}`
94
- };
95
- }
96
-
97
- const switched = projectManager.setActiveProject(projectId);
98
-
99
- return {
100
- success: switched,
101
- message: switched
102
- ? `Switched to project: ${project.name}`
103
- : `Failed to switch project.`
104
- };
105
- }
106
-
107
- // Discover projects
108
- export function discoverProjects(): CommandResult {
109
- const discovered = projectManager.discoverProjects();
110
-
111
- if (discovered.length === 0) {
112
- return {
113
- success: true,
114
- message: 'No projects discovered in common locations.'
115
- };
116
- }
117
-
118
- const lines = [`Discovered ${discovered.length} potential projects:`, ''];
119
- for (const path of discovered) {
120
- const name = path.split(/[/\\]/).pop();
121
- lines.push(` ${name}`);
122
- lines.push(` ${path}`);
123
- lines.push('');
124
- }
125
- lines.push('Use "memorylayer projects add <path>" to register a project.');
126
-
127
- return {
128
- success: true,
129
- message: lines.join('\n'),
130
- data: discovered
131
- };
132
- }
133
-
134
- // Export decisions to ADR
135
- export function exportDecisions(
136
- projectPath?: string,
137
- options: { outputDir?: string; format?: 'madr' | 'nygard' | 'simple' } = {}
138
- ): CommandResult {
139
- // Determine project path
140
- let targetPath = projectPath;
141
- if (!targetPath) {
142
- const activeProject = projectManager.getActiveProject();
143
- if (!activeProject) {
144
- return {
145
- success: false,
146
- message: 'No project specified and no active project. Use "memorylayer projects switch <id>" first.'
147
- };
148
- }
149
- targetPath = activeProject.path;
150
- }
151
-
152
- // Get project info
153
- const projectInfo = projectManager.getProjectByPath(targetPath);
154
- if (!projectInfo) {
155
- return {
156
- success: false,
157
- message: `Project not registered: ${targetPath}. Use "memorylayer projects add ${targetPath}" first.`
158
- };
159
- }
160
-
161
- // Open database and get decisions
162
- const dbPath = join(projectInfo.dataDir, 'memorylayer.db');
163
- if (!existsSync(dbPath)) {
164
- return {
165
- success: false,
166
- message: `Project database not found. Has the project been indexed?`
167
- };
168
- }
169
-
170
- const db = initializeDatabase(dbPath);
171
- const tier2 = new Tier2Storage(db);
172
- const decisions = tier2.getAllDecisions();
173
- db.close();
174
-
175
- if (decisions.length === 0) {
176
- return {
177
- success: true,
178
- message: 'No decisions to export.'
179
- };
180
- }
181
-
182
- // Export
183
- const exporter = new ADRExporter(targetPath);
184
- const exportedFiles = exporter.exportAllDecisions(decisions, {
185
- outputDir: options.outputDir,
186
- format: options.format,
187
- includeIndex: true
188
- });
189
-
190
- return {
191
- success: true,
192
- message: `Exported ${exportedFiles.length} ADR files to ${options.outputDir || join(targetPath, 'docs', 'decisions')}`,
193
- data: exportedFiles
194
- };
195
- }
196
-
197
- // Show project info
198
- export function showProject(projectId?: string): CommandResult {
199
- let project: ProjectInfo | null;
200
-
201
- if (projectId) {
202
- project = projectManager.getProject(projectId);
203
- } else {
204
- project = projectManager.getActiveProject();
205
- }
206
-
207
- if (!project) {
208
- return {
209
- success: false,
210
- message: projectId
211
- ? `Project not found: ${projectId}`
212
- : 'No active project. Use "memorylayer projects switch <id>" first.'
213
- };
214
- }
215
-
216
- const lines = [
217
- `Project: ${project.name}`,
218
- `ID: ${project.id}`,
219
- `Path: ${project.path}`,
220
- `Data Directory: ${project.dataDir}`,
221
- `Files Indexed: ${project.totalFiles}`,
222
- `Decisions: ${project.totalDecisions}`,
223
- `Languages: ${project.languages.join(', ') || 'N/A'}`,
224
- `Last Accessed: ${new Date(project.lastAccessed).toLocaleString()}`
225
- ];
226
-
227
- return {
228
- success: true,
229
- message: lines.join('\n'),
230
- data: project
231
- };
232
- }
233
-
234
- // Print help
235
- export function printHelp(): void {
236
- console.log(`
237
- MemoryLayer CLI - Persistent Memory for AI Coding Assistants
238
-
239
- USAGE:
240
- memorylayer [command] [options]
241
-
242
- COMMANDS:
243
- (no command) Start MCP server for Claude Desktop
244
- projects list List all registered projects
245
- projects add <path> Add a project to the registry
246
- projects remove <id> Remove a project from the registry
247
- projects switch <id> Set a project as active
248
- projects show [id] Show project details
249
- projects discover Discover projects in common locations
250
- export [options] Export decisions to ADR files
251
- help Show this help message
252
-
253
- OPTIONS:
254
- --project, -p <path> Path to the project directory
255
- --output, -o <dir> Output directory for exports
256
- --format <type> ADR format: madr, nygard, simple
257
-
258
- EXAMPLES:
259
- # Start MCP server
260
- memorylayer --project /path/to/project
261
-
262
- # List all projects
263
- memorylayer projects list
264
-
265
- # Add a new project
266
- memorylayer projects add /path/to/my-project
267
-
268
- # Switch active project
269
- memorylayer projects switch abc123
270
-
271
- # Export decisions to ADR files
272
- memorylayer export --format madr
273
-
274
- # Discover projects
275
- memorylayer projects discover
276
-
277
- For more information, visit: https://github.com/your-org/memorylayer
278
- `);
279
- }
280
-
281
- // Parse and execute CLI commands
282
- export function executeCLI(args: string[]): void {
283
- const command = args[0];
284
- const subcommand = args[1];
285
-
286
- switch (command) {
287
- case 'help':
288
- case '--help':
289
- case '-h':
290
- printHelp();
291
- break;
292
-
293
- case 'projects': {
294
- switch (subcommand) {
295
- case 'list':
296
- console.log(listProjects().message);
297
- break;
298
- case 'add': {
299
- const path = args[2];
300
- if (!path) {
301
- console.error('Error: Project path required.');
302
- console.error('Usage: memorylayer projects add <path>');
303
- process.exit(1);
304
- }
305
- const result = addProject(path);
306
- console.log(result.message);
307
- if (!result.success) process.exit(1);
308
- break;
309
- }
310
- case 'remove': {
311
- const id = args[2];
312
- if (!id) {
313
- console.error('Error: Project ID required.');
314
- console.error('Usage: memorylayer projects remove <id>');
315
- process.exit(1);
316
- }
317
- const result = removeProject(id);
318
- console.log(result.message);
319
- if (!result.success) process.exit(1);
320
- break;
321
- }
322
- case 'switch': {
323
- const id = args[2];
324
- if (!id) {
325
- console.error('Error: Project ID required.');
326
- console.error('Usage: memorylayer projects switch <id>');
327
- process.exit(1);
328
- }
329
- const result = switchProject(id);
330
- console.log(result.message);
331
- if (!result.success) process.exit(1);
332
- break;
333
- }
334
- case 'show': {
335
- const id = args[2];
336
- const result = showProject(id);
337
- console.log(result.message);
338
- if (!result.success) process.exit(1);
339
- break;
340
- }
341
- case 'discover':
342
- console.log(discoverProjects().message);
343
- break;
344
- default:
345
- console.error(`Unknown subcommand: ${subcommand}`);
346
- console.error('Available: list, add, remove, switch, show, discover');
347
- process.exit(1);
348
- }
349
- break;
350
- }
351
-
352
- case 'export': {
353
- // Parse export options
354
- let outputDir: string | undefined;
355
- let format: 'madr' | 'nygard' | 'simple' | undefined;
356
-
357
- for (let i = 1; i < args.length; i++) {
358
- const arg = args[i];
359
- const nextArg = args[i + 1];
360
- if ((arg === '--output' || arg === '-o') && nextArg) {
361
- outputDir = nextArg;
362
- i++;
363
- } else if (arg === '--format' && nextArg) {
364
- format = nextArg as 'madr' | 'nygard' | 'simple';
365
- i++;
366
- }
367
- }
368
-
369
- const result = exportDecisions(undefined, { outputDir, format });
370
- console.log(result.message);
371
- if (!result.success) process.exit(1);
372
- break;
373
- }
374
-
375
- default:
376
- // If no command matches, it might be the default MCP server mode
377
- // Return without handling - let main() handle it
378
- return;
379
- }
380
-
381
- process.exit(0);
382
- }