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.
- package/README.md +203 -123
- package/dist/index.js +635 -710
- package/dist/index.js.map +7 -0
- package/package.json +67 -63
- package/CONTRIBUTING.md +0 -127
- package/esbuild.config.js +0 -26
- package/src/cli/commands.ts +0 -382
- package/src/core/adr-exporter.ts +0 -253
- package/src/core/architecture/architecture-enforcement.ts +0 -228
- package/src/core/architecture/duplicate-detector.ts +0 -288
- package/src/core/architecture/index.ts +0 -6
- package/src/core/architecture/pattern-learner.ts +0 -306
- package/src/core/architecture/pattern-library.ts +0 -403
- package/src/core/architecture/pattern-validator.ts +0 -324
- package/src/core/change-intelligence/bug-correlator.ts +0 -444
- package/src/core/change-intelligence/change-intelligence.ts +0 -221
- package/src/core/change-intelligence/change-tracker.ts +0 -334
- package/src/core/change-intelligence/fix-suggester.ts +0 -340
- package/src/core/change-intelligence/index.ts +0 -5
- package/src/core/code-verifier.ts +0 -843
- package/src/core/confidence/confidence-scorer.ts +0 -251
- package/src/core/confidence/conflict-checker.ts +0 -289
- package/src/core/confidence/index.ts +0 -5
- package/src/core/confidence/source-tracker.ts +0 -263
- package/src/core/confidence/warning-detector.ts +0 -241
- package/src/core/context-rot/compaction.ts +0 -284
- package/src/core/context-rot/context-health.ts +0 -243
- package/src/core/context-rot/context-rot-prevention.ts +0 -213
- package/src/core/context-rot/critical-context.ts +0 -221
- package/src/core/context-rot/drift-detector.ts +0 -255
- package/src/core/context-rot/index.ts +0 -7
- package/src/core/context.ts +0 -263
- package/src/core/decision-extractor.ts +0 -339
- package/src/core/decisions.ts +0 -69
- package/src/core/deja-vu.ts +0 -421
- package/src/core/engine.ts +0 -1455
- package/src/core/feature-context.ts +0 -726
- package/src/core/ghost-mode.ts +0 -412
- package/src/core/learning.ts +0 -485
- package/src/core/living-docs/activity-tracker.ts +0 -296
- package/src/core/living-docs/architecture-generator.ts +0 -428
- package/src/core/living-docs/changelog-generator.ts +0 -348
- package/src/core/living-docs/component-generator.ts +0 -230
- package/src/core/living-docs/doc-engine.ts +0 -110
- package/src/core/living-docs/doc-validator.ts +0 -282
- package/src/core/living-docs/index.ts +0 -8
- package/src/core/project-manager.ts +0 -297
- package/src/core/summarizer.ts +0 -267
- package/src/core/test-awareness/change-validator.ts +0 -499
- package/src/core/test-awareness/index.ts +0 -5
- package/src/index.ts +0 -49
- package/src/indexing/ast.ts +0 -563
- package/src/indexing/embeddings.ts +0 -85
- package/src/indexing/indexer.ts +0 -245
- package/src/indexing/watcher.ts +0 -78
- package/src/server/gateways/aggregator.ts +0 -374
- package/src/server/gateways/index.ts +0 -473
- package/src/server/gateways/memory-ghost.ts +0 -343
- package/src/server/gateways/memory-query.ts +0 -452
- package/src/server/gateways/memory-record.ts +0 -346
- package/src/server/gateways/memory-review.ts +0 -410
- package/src/server/gateways/memory-status.ts +0 -517
- package/src/server/gateways/memory-verify.ts +0 -392
- package/src/server/gateways/router.ts +0 -434
- package/src/server/gateways/types.ts +0 -610
- package/src/server/mcp.ts +0 -154
- package/src/server/resources.ts +0 -85
- package/src/server/tools.ts +0 -2261
- package/src/storage/database.ts +0 -262
- package/src/storage/tier1.ts +0 -135
- package/src/storage/tier2.ts +0 -764
- package/src/storage/tier3.ts +0 -123
- package/src/types/documentation.ts +0 -619
- package/src/types/index.ts +0 -222
- package/src/utils/config.ts +0 -193
- package/src/utils/files.ts +0 -117
- package/src/utils/time.ts +0 -37
- package/src/utils/tokens.ts +0 -52
package/package.json
CHANGED
|
@@ -1,63 +1,67 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "neuronlayer",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "dist/index.js",
|
|
7
|
-
"bin": {
|
|
8
|
-
"neuronlayer": "dist/index.js"
|
|
9
|
-
},
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
"
|
|
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!');
|
package/src/cli/commands.ts
DELETED
|
@@ -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
|
-
}
|