continuum-ai-mcp 1.0.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 +274 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +125 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/database/Database.d.ts +4 -0
- package/dist/database/Database.d.ts.map +1 -0
- package/dist/database/Database.js +83 -0
- package/dist/database/Database.js.map +1 -0
- package/dist/database/schema.sql +121 -0
- package/dist/knowledge/KnowledgeEngine.d.ts +63 -0
- package/dist/knowledge/KnowledgeEngine.d.ts.map +1 -0
- package/dist/knowledge/KnowledgeEngine.js +190 -0
- package/dist/knowledge/KnowledgeEngine.js.map +1 -0
- package/dist/languages/LanguageRegistry.d.ts +38 -0
- package/dist/languages/LanguageRegistry.d.ts.map +1 -0
- package/dist/languages/LanguageRegistry.js +233 -0
- package/dist/languages/LanguageRegistry.js.map +1 -0
- package/dist/languages/definitions/cpp.d.ts +2 -0
- package/dist/languages/definitions/cpp.d.ts.map +1 -0
- package/dist/languages/definitions/cpp.js +25 -0
- package/dist/languages/definitions/cpp.js.map +1 -0
- package/dist/languages/definitions/csharp.d.ts +2 -0
- package/dist/languages/definitions/csharp.d.ts.map +1 -0
- package/dist/languages/definitions/csharp.js +40 -0
- package/dist/languages/definitions/csharp.js.map +1 -0
- package/dist/languages/definitions/go.d.ts +2 -0
- package/dist/languages/definitions/go.d.ts.map +1 -0
- package/dist/languages/definitions/go.js +21 -0
- package/dist/languages/definitions/go.js.map +1 -0
- package/dist/languages/definitions/java.d.ts +2 -0
- package/dist/languages/definitions/java.d.ts.map +1 -0
- package/dist/languages/definitions/java.js +32 -0
- package/dist/languages/definitions/java.js.map +1 -0
- package/dist/languages/definitions/javascript.d.ts +2 -0
- package/dist/languages/definitions/javascript.d.ts.map +1 -0
- package/dist/languages/definitions/javascript.js +26 -0
- package/dist/languages/definitions/javascript.js.map +1 -0
- package/dist/languages/definitions/kotlin.d.ts +2 -0
- package/dist/languages/definitions/kotlin.d.ts.map +1 -0
- package/dist/languages/definitions/kotlin.js +36 -0
- package/dist/languages/definitions/kotlin.js.map +1 -0
- package/dist/languages/definitions/markdown.d.ts +2 -0
- package/dist/languages/definitions/markdown.d.ts.map +1 -0
- package/dist/languages/definitions/markdown.js +18 -0
- package/dist/languages/definitions/markdown.js.map +1 -0
- package/dist/languages/definitions/php.d.ts +2 -0
- package/dist/languages/definitions/php.d.ts.map +1 -0
- package/dist/languages/definitions/php.js +27 -0
- package/dist/languages/definitions/php.js.map +1 -0
- package/dist/languages/definitions/python.d.ts +2 -0
- package/dist/languages/definitions/python.d.ts.map +1 -0
- package/dist/languages/definitions/python.js +17 -0
- package/dist/languages/definitions/python.js.map +1 -0
- package/dist/languages/definitions/ruby.d.ts +2 -0
- package/dist/languages/definitions/ruby.d.ts.map +1 -0
- package/dist/languages/definitions/ruby.js +16 -0
- package/dist/languages/definitions/ruby.js.map +1 -0
- package/dist/languages/definitions/rust.d.ts +2 -0
- package/dist/languages/definitions/rust.d.ts.map +1 -0
- package/dist/languages/definitions/rust.js +28 -0
- package/dist/languages/definitions/rust.js.map +1 -0
- package/dist/languages/definitions/sql.d.ts +2 -0
- package/dist/languages/definitions/sql.d.ts.map +1 -0
- package/dist/languages/definitions/sql.js +36 -0
- package/dist/languages/definitions/sql.js.map +1 -0
- package/dist/languages/definitions/swift.d.ts +2 -0
- package/dist/languages/definitions/swift.d.ts.map +1 -0
- package/dist/languages/definitions/swift.js +40 -0
- package/dist/languages/definitions/swift.js.map +1 -0
- package/dist/languages/definitions/typescript.d.ts +2 -0
- package/dist/languages/definitions/typescript.d.ts.map +1 -0
- package/dist/languages/definitions/typescript.js +40 -0
- package/dist/languages/definitions/typescript.js.map +1 -0
- package/dist/mcp/McpServer.d.ts +2 -0
- package/dist/mcp/McpServer.d.ts.map +1 -0
- package/dist/mcp/McpServer.js +262 -0
- package/dist/mcp/McpServer.js.map +1 -0
- package/dist/parser/IncrementalParser.d.ts +25 -0
- package/dist/parser/IncrementalParser.d.ts.map +1 -0
- package/dist/parser/IncrementalParser.js +195 -0
- package/dist/parser/IncrementalParser.js.map +1 -0
- package/dist/schema/ISchemaAdapter.d.ts +20 -0
- package/dist/schema/ISchemaAdapter.d.ts.map +1 -0
- package/dist/schema/ISchemaAdapter.js +3 -0
- package/dist/schema/ISchemaAdapter.js.map +1 -0
- package/dist/schema/MssqlAdapter.d.ts +6 -0
- package/dist/schema/MssqlAdapter.d.ts.map +1 -0
- package/dist/schema/MssqlAdapter.js +139 -0
- package/dist/schema/MssqlAdapter.js.map +1 -0
- package/dist/schema/MySqlAdapter.d.ts +6 -0
- package/dist/schema/MySqlAdapter.d.ts.map +1 -0
- package/dist/schema/MySqlAdapter.js +77 -0
- package/dist/schema/MySqlAdapter.js.map +1 -0
- package/dist/schema/PostgresAdapter.d.ts +6 -0
- package/dist/schema/PostgresAdapter.d.ts.map +1 -0
- package/dist/schema/PostgresAdapter.js +78 -0
- package/dist/schema/PostgresAdapter.js.map +1 -0
- package/dist/schema/SchemaReader.d.ts +17 -0
- package/dist/schema/SchemaReader.d.ts.map +1 -0
- package/dist/schema/SchemaReader.js +82 -0
- package/dist/schema/SchemaReader.js.map +1 -0
- package/dist/session/SessionEngine.d.ts +40 -0
- package/dist/session/SessionEngine.d.ts.map +1 -0
- package/dist/session/SessionEngine.js +131 -0
- package/dist/session/SessionEngine.js.map +1 -0
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +54 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/watcher/FileWatcher.d.ts +19 -0
- package/dist/watcher/FileWatcher.d.ts.map +1 -0
- package/dist/watcher/FileWatcher.js +146 -0
- package/dist/watcher/FileWatcher.js.map +1 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# Continuum
|
|
2
|
+
|
|
3
|
+
**AI Development Memory Layer — Universal Language Support**
|
|
4
|
+
|
|
5
|
+
> Give your AI coding assistant persistent memory across context windows. Continuum is a local MCP server that watches your codebase, indexes symbols from 14+ languages, tracks your session state, and lets AI assistants resume exactly where they left off — even after context compaction.
|
|
6
|
+
|
|
7
|
+
[](https://github.com/yourusername/continuum/actions/workflows/ci.yml)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://nodejs.org)
|
|
10
|
+
[](https://www.typescriptlang.org)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## The Problem
|
|
15
|
+
|
|
16
|
+
AI coding assistants lose all context when their conversation fills up (context compaction). Every time this happens:
|
|
17
|
+
- You re-explain the goal from scratch
|
|
18
|
+
- The AI re-reads files it already processed
|
|
19
|
+
- Architectural decisions get forgotten
|
|
20
|
+
- Momentum is lost
|
|
21
|
+
|
|
22
|
+
**Continuum fixes this.** It persists session state in a local SQLite database and exposes it through MCP tools so any AI assistant can instantly recover full context.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Architecture
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Your Codebase
|
|
30
|
+
│ (chokidar file watcher)
|
|
31
|
+
▼
|
|
32
|
+
FileWatcher ──► IncrementalParser ──► SQLite (knowledge.db)
|
|
33
|
+
(14 languages) │
|
|
34
|
+
┌─────┴──────┐
|
|
35
|
+
│ Symbols │
|
|
36
|
+
│ Sessions │
|
|
37
|
+
│ Tasks │
|
|
38
|
+
│ FTS5 Index │
|
|
39
|
+
└─────┬───────┘
|
|
40
|
+
│
|
|
41
|
+
McpServer (stdio)
|
|
42
|
+
10 MCP Tools
|
|
43
|
+
│
|
|
44
|
+
Claude Code / Cursor / Copilot
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Quick Start
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# 1. Clone
|
|
53
|
+
git clone https://github.com/yourusername/continuum
|
|
54
|
+
cd continuum
|
|
55
|
+
|
|
56
|
+
# 2. Install
|
|
57
|
+
npm install --legacy-peer-deps
|
|
58
|
+
|
|
59
|
+
# 3. Configure
|
|
60
|
+
cp .env.example .env
|
|
61
|
+
# Edit .env: set WATCH_PATHS to your project's src directory
|
|
62
|
+
|
|
63
|
+
# 4. Run (development)
|
|
64
|
+
npm run dev
|
|
65
|
+
|
|
66
|
+
# 5. Build (production)
|
|
67
|
+
npm run build
|
|
68
|
+
npm start
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Wire to Claude Code
|
|
74
|
+
|
|
75
|
+
Create `.vscode/mcp.json` in **your project's root** (not inside continuum/):
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"mcpServers": {
|
|
80
|
+
"continuum": {
|
|
81
|
+
"command": "node",
|
|
82
|
+
"args": ["/absolute/path/to/continuum/dist/mcp/McpServer.js"],
|
|
83
|
+
"cwd": "/absolute/path/to/continuum",
|
|
84
|
+
"env": {
|
|
85
|
+
"WATCH_PATHS": "${workspaceFolder}/src",
|
|
86
|
+
"DB_PATH": "/absolute/path/to/continuum/knowledge.db",
|
|
87
|
+
"LOG_LEVEL": "info"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
For development (no build step):
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"mcpServers": {
|
|
98
|
+
"continuum": {
|
|
99
|
+
"command": "npx",
|
|
100
|
+
"args": ["tsx", "src/mcp/McpServer.ts"],
|
|
101
|
+
"cwd": "/absolute/path/to/continuum"
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Reload VS Code (`Cmd+Shift+P` on Mac / `Ctrl+Shift+P` on Windows → Developer: Reload Window). Verify: ask Claude "what tools do you have?" — you should see all 10 Continuum tools.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## MCP Tools
|
|
112
|
+
|
|
113
|
+
| Tool | Description |
|
|
114
|
+
|------|-------------|
|
|
115
|
+
| `get_session` | 🔄 **Core recovery tool.** Get full session state — call after any context compaction |
|
|
116
|
+
| `save_task` | 💾 Save structured task state (goal, decisions, next steps, open questions) |
|
|
117
|
+
| `get_touched_files` | 📁 Files modified/created/deleted this session |
|
|
118
|
+
| `find_related_files` | 🔍 Cross-layer search for symbols, features, and files |
|
|
119
|
+
| `search_symbols` | 🔎 Full-text search all indexed symbols (FTS5) |
|
|
120
|
+
| `get_schema` | 🗄️ Live DB schema for a table (MSSQL/PostgreSQL/MySQL, cached 1h) |
|
|
121
|
+
| `get_dependencies` | 🕸️ Symbols defined in a file + outgoing relationships |
|
|
122
|
+
| `list_languages` | 🌍 All supported languages with indexed file/symbol counts |
|
|
123
|
+
| `get_session_report` | 📊 Session metrics: tool calls, files touched, estimated tokens saved |
|
|
124
|
+
| `health_check` | 🩺 Server health, uptime, DB status |
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Slash Commands
|
|
129
|
+
|
|
130
|
+
Create these in your project's `.claude/commands/` folder:
|
|
131
|
+
|
|
132
|
+
| Command | Action |
|
|
133
|
+
|---------|--------|
|
|
134
|
+
| `/resume` | Recover full session after compaction — continue without re-explaining |
|
|
135
|
+
| `/checkpoint` | Proactively save task state before context fills |
|
|
136
|
+
| `/task [description]` | Start a task with full codebase context pre-loaded |
|
|
137
|
+
| `/report` | Show session efficiency metrics |
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Supported Languages
|
|
142
|
+
|
|
143
|
+
| Language | Extensions | Symbol Types |
|
|
144
|
+
|----------|-----------|--------------|
|
|
145
|
+
| TypeScript | `.ts`, `.tsx` | class, interface, function, enum, type, method, property |
|
|
146
|
+
| JavaScript | `.js`, `.jsx`, `.mjs`, `.cjs` | class, function, method |
|
|
147
|
+
| Python | `.py`, `.pyw` | class, function, method, async def |
|
|
148
|
+
| Rust | `.rs` | struct, enum, trait, fn, mod, type, impl |
|
|
149
|
+
| Go | `.go` | func, method, struct, interface, type |
|
|
150
|
+
| Java | `.java` | class, interface, enum, method, constructor |
|
|
151
|
+
| C# | `.cs` | class, interface, enum, struct, record, method, property |
|
|
152
|
+
| C/C++ | `.c`, `.cpp`, `.h`, `.hpp` | class, struct, function, method |
|
|
153
|
+
| Ruby | `.rb`, `.rake` | class, module, def, method |
|
|
154
|
+
| PHP | `.php` | class, interface, trait, enum, function, method |
|
|
155
|
+
| Swift | `.swift` | class, struct, protocol, enum, func, extension |
|
|
156
|
+
| Kotlin | `.kt`, `.kts` | class, interface, enum, object, fun |
|
|
157
|
+
| SQL | `.sql` | TABLE, VIEW, PROCEDURE, FUNCTION, TYPE, INDEX |
|
|
158
|
+
| Markdown | `.md`, `.mdx` | H1 (doc), H2 (section), H3 (subsection) |
|
|
159
|
+
|
|
160
|
+
**Adding a new language:** Create a file in `src/languages/definitions/yourlanguage.ts`, call `registerLanguage()` with your rules, and import it in `LanguageRegistry.ts`. No other changes needed.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Database Schema (Optional)
|
|
165
|
+
|
|
166
|
+
Enable the `get_schema` tool by setting `DB_TYPE` in `.env`:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
# PostgreSQL
|
|
170
|
+
DB_TYPE=postgres
|
|
171
|
+
PG_HOST=localhost
|
|
172
|
+
PG_PORT=5432
|
|
173
|
+
PG_DATABASE=myapp
|
|
174
|
+
PG_USER=myuser
|
|
175
|
+
PG_PASSWORD=mypassword
|
|
176
|
+
|
|
177
|
+
# MSSQL
|
|
178
|
+
DB_TYPE=mssql
|
|
179
|
+
MSSQL_HOST=localhost
|
|
180
|
+
MSSQL_DATABASE=myapp
|
|
181
|
+
MSSQL_USER=myuser
|
|
182
|
+
MSSQL_PASSWORD=mypassword
|
|
183
|
+
|
|
184
|
+
# MySQL / MariaDB
|
|
185
|
+
DB_TYPE=mysql
|
|
186
|
+
MYSQL_HOST=localhost
|
|
187
|
+
MYSQL_DATABASE=myapp
|
|
188
|
+
MYSQL_USER=myuser
|
|
189
|
+
MYSQL_PASSWORD=mypassword
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Configuration Reference
|
|
195
|
+
|
|
196
|
+
| Variable | Default | Description |
|
|
197
|
+
|----------|---------|-------------|
|
|
198
|
+
| `WATCH_PATHS` | `./src` | Comma-separated paths to watch |
|
|
199
|
+
| `DB_PATH` | `./knowledge.db` | SQLite database location |
|
|
200
|
+
| `LOG_LEVEL` | `info` | `debug` \| `info` \| `warn` \| `error` |
|
|
201
|
+
| `NODE_ENV` | `development` | Set to `production` for JSON logs |
|
|
202
|
+
| `DB_TYPE` | _(none)_ | `mssql` \| `postgres` \| `mysql` |
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Development
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
npm run dev # Run with tsx (no build step)
|
|
210
|
+
npm run type-check # TypeScript strict check
|
|
211
|
+
npm run lint # ESLint
|
|
212
|
+
npm run format # Prettier
|
|
213
|
+
npm test # Vitest
|
|
214
|
+
npm run test:watch # Vitest watch mode
|
|
215
|
+
npm run test:coverage # Coverage report
|
|
216
|
+
npm run build # Production TypeScript compile
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Docker
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
docker build -t continuum .
|
|
223
|
+
docker compose up -d
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## How It Works
|
|
229
|
+
|
|
230
|
+
1. **Startup**: Continuum creates a new session UUID in SQLite and starts watching your configured paths.
|
|
231
|
+
2. **Indexing**: Every file change triggers incremental parsing. The file's MD5 hash is checked — unchanged files are skipped. New symbols are extracted and stored in SQLite with FTS5 indexing.
|
|
232
|
+
3. **Session tracking**: Every file change after the initial scan is recorded as a `touched_file` event (debounced to 5 seconds per path).
|
|
233
|
+
4. **MCP tools**: Your AI assistant calls tools via stdio. `save_task` checkpoints the current goal and decisions; `get_session` recovers them after compaction.
|
|
234
|
+
5. **Schema cache**: `get_schema` fetches live database schema and caches it in SQLite for 1 hour.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Troubleshooting
|
|
239
|
+
|
|
240
|
+
**Claude Code doesn't see the tools**
|
|
241
|
+
→ Reload VS Code after editing `mcp.json`. Check `npm run dev` starts without errors.
|
|
242
|
+
|
|
243
|
+
**File changes not being indexed**
|
|
244
|
+
→ Ensure `WATCH_PATHS` includes the directory you're editing. Check `LOG_LEVEL=debug` for watcher events.
|
|
245
|
+
|
|
246
|
+
**MSSQL connection fails**
|
|
247
|
+
→ Set `LOG_LEVEL=debug` and check the error. Ensure `trustServerCertificate=true` for local SQL Server.
|
|
248
|
+
|
|
249
|
+
**MCP server crashes on startup**
|
|
250
|
+
→ Ensure no `console.log` in any source file (breaks stdio MCP transport). Use the logger utility.
|
|
251
|
+
|
|
252
|
+
**Symbols not extracted for my language**
|
|
253
|
+
→ Open `src/languages/definitions/` and check the regex rules. Enable `LOG_LEVEL=debug` to see what's parsed.
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Contributing
|
|
258
|
+
|
|
259
|
+
1. Fork the repository
|
|
260
|
+
2. Create a feature branch: `git checkout -b feat/new-language`
|
|
261
|
+
3. Add your language definition in `src/languages/definitions/`
|
|
262
|
+
4. Add tests in `tests/parser.test.ts`
|
|
263
|
+
5. Run `npm test && npm run type-check`
|
|
264
|
+
6. Submit a PR
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## License
|
|
269
|
+
|
|
270
|
+
MIT — see [LICENSE](LICENSE)
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
*Continuum v1.0 — Model-agnostic · Offline · No cloud dependencies · Production-ready*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const command = process.argv[2];
|
|
40
|
+
if (command === 'init') {
|
|
41
|
+
console.log('Initializing Continuum MCP configuration...');
|
|
42
|
+
const cwd = process.cwd();
|
|
43
|
+
// Base MCP Configuration
|
|
44
|
+
const mcpConfig = {
|
|
45
|
+
mcpServers: {
|
|
46
|
+
continuum: {
|
|
47
|
+
command: "npx",
|
|
48
|
+
args: ["continuum", "start"],
|
|
49
|
+
env: {
|
|
50
|
+
WATCH_PATHS: "${workspaceFolder}/src",
|
|
51
|
+
DB_PATH: "${workspaceFolder}/knowledge.db",
|
|
52
|
+
LOG_LEVEL: "info"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
// 1. .vscode/mcp.json (Claude Code / Antigravity)
|
|
58
|
+
const vscodeDir = path.join(cwd, '.vscode');
|
|
59
|
+
if (!fs.existsSync(vscodeDir)) {
|
|
60
|
+
fs.mkdirSync(vscodeDir, { recursive: true });
|
|
61
|
+
}
|
|
62
|
+
const vscodeMcpPath = path.join(vscodeDir, 'mcp.json');
|
|
63
|
+
if (!fs.existsSync(vscodeMcpPath)) {
|
|
64
|
+
fs.writeFileSync(vscodeMcpPath, JSON.stringify(mcpConfig, null, 2));
|
|
65
|
+
console.log(`✅ Created ${vscodeMcpPath}`);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
console.log(`ℹ️ Skipped ${vscodeMcpPath} (already exists)`);
|
|
69
|
+
}
|
|
70
|
+
// 2. .cursor/mcp.json (Cursor)
|
|
71
|
+
const cursorDir = path.join(cwd, '.cursor');
|
|
72
|
+
if (!fs.existsSync(cursorDir)) {
|
|
73
|
+
fs.mkdirSync(cursorDir, { recursive: true });
|
|
74
|
+
}
|
|
75
|
+
const cursorMcpPath = path.join(cursorDir, 'mcp.json');
|
|
76
|
+
if (!fs.existsSync(cursorMcpPath)) {
|
|
77
|
+
fs.writeFileSync(cursorMcpPath, JSON.stringify(mcpConfig, null, 2));
|
|
78
|
+
console.log(`✅ Created ${cursorMcpPath}`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
console.log(`ℹ️ Skipped ${cursorMcpPath} (already exists)`);
|
|
82
|
+
}
|
|
83
|
+
// 3. AI System Prompts
|
|
84
|
+
const rulesContent = `You have access to the Continuum MCP tools.
|
|
85
|
+
Always call \`get_session\` when you first start working or if you lose context.
|
|
86
|
+
Use \`save_task\` to proactively save goals, decisions, and next steps before closing sessions.
|
|
87
|
+
`;
|
|
88
|
+
const cursorRulesPath = path.join(cwd, '.cursorrules');
|
|
89
|
+
if (!fs.existsSync(cursorRulesPath)) {
|
|
90
|
+
fs.writeFileSync(cursorRulesPath, rulesContent);
|
|
91
|
+
console.log(`✅ Created ${cursorRulesPath}`);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
console.log(`ℹ️ Skipped ${cursorRulesPath} (already exists)`);
|
|
95
|
+
}
|
|
96
|
+
const claudePath = path.join(cwd, '.claude.md');
|
|
97
|
+
if (!fs.existsSync(claudePath)) {
|
|
98
|
+
fs.writeFileSync(claudePath, rulesContent);
|
|
99
|
+
console.log(`✅ Created ${claudePath}`);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
console.log(`ℹ️ Skipped ${claudePath} (already exists)`);
|
|
103
|
+
}
|
|
104
|
+
// 4. .env
|
|
105
|
+
const envPath = path.join(cwd, '.env');
|
|
106
|
+
if (!fs.existsSync(envPath)) {
|
|
107
|
+
fs.writeFileSync(envPath, `WATCH_PATHS=./src\nDB_PATH=./knowledge.db\nLOG_LEVEL=info\n`);
|
|
108
|
+
console.log(`✅ Created ${envPath}`);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
console.log(`ℹ️ Skipped ${envPath} (already exists)`);
|
|
112
|
+
}
|
|
113
|
+
console.log('\n🎉 Initialization complete! Restart your IDE or AI assistant to load the tools.');
|
|
114
|
+
}
|
|
115
|
+
else if (command === 'start') {
|
|
116
|
+
// Run the MCP server
|
|
117
|
+
require('../mcp/McpServer.js');
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
console.log('Continuum AI MCP Setup');
|
|
121
|
+
console.log('Usage:');
|
|
122
|
+
console.log(' npx continuum init - Setup MCP config files in current directory');
|
|
123
|
+
console.log(' npx continuum start - Run the MCP server manually');
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,uCAAyB;AACzB,2CAA6B;AAE7B,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEhC,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAE3D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,yBAAyB;IACzB,MAAM,SAAS,GAAG;QAChB,UAAU,EAAE;YACV,SAAS,EAAE;gBACT,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,CAAC,WAAW,EAAE,OAAO,CAAC;gBAC5B,GAAG,EAAE;oBACH,WAAW,EAAE,wBAAwB;oBACrC,OAAO,EAAE,iCAAiC;oBAC1C,SAAS,EAAE,MAAM;iBAClB;aACF;SACF;KACF,CAAC;IAEF,kDAAkD;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACvD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAClC,EAAE,CAAC,aAAa,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,aAAa,aAAa,EAAE,CAAC,CAAC;IAC5C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,eAAe,aAAa,mBAAmB,CAAC,CAAC;IAC/D,CAAC;IAED,+BAA+B;IAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IACD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACvD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAClC,EAAE,CAAC,aAAa,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,aAAa,aAAa,EAAE,CAAC,CAAC;IAC5C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,eAAe,aAAa,mBAAmB,CAAC,CAAC;IAC/D,CAAC;IAED,uBAAuB;IACvB,MAAM,YAAY,GAAG;;;CAGtB,CAAC;IAEA,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IACvD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACpC,EAAE,CAAC,aAAa,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,aAAa,eAAe,EAAE,CAAC,CAAC;IAC9C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,eAAe,eAAe,mBAAmB,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAChD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,aAAa,UAAU,EAAE,CAAC,CAAC;IACzC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,eAAe,UAAU,mBAAmB,CAAC,CAAC;IAC5D,CAAC;IAED,UAAU;IACV,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,6DAA6D,CAAC,CAAC;QACzF,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,EAAE,CAAC,CAAC;IACtC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,eAAe,OAAO,mBAAmB,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,mFAAmF,CAAC,CAAC;AACnG,CAAC;KAAM,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;IAC/B,qBAAqB;IACrB,OAAO,CAAC,qBAAqB,CAAC,CAAC;AACjC,CAAC;KAAM,CAAC;IACN,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,sEAAsE,CAAC,CAAC;IACpF,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;AACtE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Database.d.ts","sourceRoot":"","sources":["../../src/database/Database.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAS3C,wBAAgB,KAAK,IAAI,aAAa,CAAC,QAAQ,CAgC9C;AAED,wBAAgB,OAAO,IAAI,IAAI,CAS9B"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.getDb = getDb;
|
|
40
|
+
exports.closeDb = closeDb;
|
|
41
|
+
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
const DB_PATH = process.env.DB_PATH || './knowledge.db';
|
|
45
|
+
const SCHEMA_PATH = path.join(__dirname, 'schema.sql');
|
|
46
|
+
let db = null;
|
|
47
|
+
function getDb() {
|
|
48
|
+
if (!db) {
|
|
49
|
+
db = new better_sqlite3_1.default(DB_PATH);
|
|
50
|
+
db.pragma('journal_mode = WAL');
|
|
51
|
+
db.pragma('foreign_keys = ON');
|
|
52
|
+
db.pragma('cache_size = -16000'); // 16 MB page cache
|
|
53
|
+
db.pragma('temp_store = MEMORY');
|
|
54
|
+
const schema = fs.readFileSync(SCHEMA_PATH, 'utf-8');
|
|
55
|
+
db.exec(schema);
|
|
56
|
+
// Seed metadata on first boot
|
|
57
|
+
const versionCheck = db
|
|
58
|
+
.prepare("SELECT value FROM metadata WHERE key = 'version'")
|
|
59
|
+
.get();
|
|
60
|
+
if (!versionCheck) {
|
|
61
|
+
const now = Math.floor(Date.now() / 1000);
|
|
62
|
+
db.prepare("INSERT OR IGNORE INTO metadata VALUES ('version', '1.0.0')").run();
|
|
63
|
+
db.prepare(`INSERT OR IGNORE INTO metadata VALUES ('first_started', '${now}')`).run();
|
|
64
|
+
}
|
|
65
|
+
db.prepare(`INSERT OR REPLACE INTO metadata VALUES ('last_started', '${Math.floor(Date.now() / 1000)}')`).run();
|
|
66
|
+
db.prepare(`INSERT OR REPLACE INTO metadata VALUES ('boot_count',
|
|
67
|
+
CAST((COALESCE((SELECT value FROM metadata WHERE key='boot_count'), 0)) AS INTEGER) + 1
|
|
68
|
+
)`).run();
|
|
69
|
+
}
|
|
70
|
+
return db;
|
|
71
|
+
}
|
|
72
|
+
function closeDb() {
|
|
73
|
+
if (db) {
|
|
74
|
+
try {
|
|
75
|
+
db.close();
|
|
76
|
+
db = null;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// already closed
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=Database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Database.js","sourceRoot":"","sources":["../../src/database/Database.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,sBAgCC;AAED,0BASC;AApDD,oEAA2C;AAC3C,uCAAyB;AACzB,2CAA6B;AAE7B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,gBAAgB,CAAC;AACxD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;AAEvD,IAAI,EAAE,GAAkC,IAAI,CAAC;AAE7C,SAAgB,KAAK;IACnB,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,EAAE,GAAG,IAAI,wBAAa,CAAC,OAAO,CAAC,CAAC;QAChC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAChC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;QAC/B,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC,mBAAmB;QACrD,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;QAEjC,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACrD,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEhB,8BAA8B;QAC9B,MAAM,YAAY,GAAG,EAAE;aACpB,OAAO,CAAC,kDAAkD,CAAC;aAC3D,GAAG,EAAmC,CAAC;QAE1C,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;YAC1C,EAAE,CAAC,OAAO,CAAC,4DAA4D,CAAC,CAAC,GAAG,EAAE,CAAC;YAC/E,EAAE,CAAC,OAAO,CAAC,4DAA4D,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;QACxF,CAAC;QAED,EAAE,CAAC,OAAO,CACR,4DAA4D,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAC9F,CAAC,GAAG,EAAE,CAAC;QACR,EAAE,CAAC,OAAO,CACR;;QAEE,CACH,CAAC,GAAG,EAAE,CAAC;IACV,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAgB,OAAO;IACrB,IAAI,EAAE,EAAE,CAAC;QACP,IAAI,CAAC;YACH,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,EAAE,GAAG,IAAI,CAAC;QACZ,CAAC;QAAC,MAAM,CAAC;YACP,iBAAiB;QACnB,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
-- ─────────────────────────────────────────────────────────────────────────────
|
|
2
|
+
-- Continuum v1.0 — SQLite Schema
|
|
3
|
+
-- ─────────────────────────────────────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
-- Server metadata (version, boot tracking)
|
|
6
|
+
CREATE TABLE IF NOT EXISTS metadata (
|
|
7
|
+
key TEXT PRIMARY KEY,
|
|
8
|
+
value TEXT NOT NULL
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
-- Files indexed from watched directories
|
|
12
|
+
CREATE TABLE IF NOT EXISTS files (
|
|
13
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
14
|
+
path TEXT NOT NULL UNIQUE,
|
|
15
|
+
language TEXT, -- 'typescript' | 'python' | 'rust' | ...
|
|
16
|
+
last_parsed INTEGER, -- unix epoch
|
|
17
|
+
hash TEXT, -- MD5 of file content for dedup
|
|
18
|
+
size_bytes INTEGER,
|
|
19
|
+
symbol_count INTEGER DEFAULT 0,
|
|
20
|
+
created_at INTEGER DEFAULT (unixepoch()),
|
|
21
|
+
updated_at INTEGER DEFAULT (unixepoch())
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
-- Symbols extracted from files (classes, functions, methods, etc.)
|
|
25
|
+
CREATE TABLE IF NOT EXISTS symbols (
|
|
26
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
27
|
+
file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
|
28
|
+
name TEXT NOT NULL,
|
|
29
|
+
kind TEXT NOT NULL, -- class | function | method | interface | enum | struct | trait | module | property | constructor
|
|
30
|
+
start_line INTEGER,
|
|
31
|
+
end_line INTEGER,
|
|
32
|
+
signature TEXT, -- first ~120 chars of the definition
|
|
33
|
+
created_at INTEGER DEFAULT (unixepoch())
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
-- Full-text search index over symbol names (SQLite FTS5)
|
|
37
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS symbols_fts USING fts5(
|
|
38
|
+
name,
|
|
39
|
+
kind,
|
|
40
|
+
file_path,
|
|
41
|
+
content='' -- contentless: we store data in symbols table
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
-- Relationships between symbols (imports, calls, extends, implements)
|
|
45
|
+
CREATE TABLE IF NOT EXISTS relationships (
|
|
46
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
47
|
+
from_id INTEGER NOT NULL REFERENCES symbols(id) ON DELETE CASCADE,
|
|
48
|
+
to_name TEXT NOT NULL,
|
|
49
|
+
kind TEXT NOT NULL, -- calls | imports | extends | implements | uses
|
|
50
|
+
created_at INTEGER DEFAULT (unixepoch())
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
-- Active coding sessions
|
|
54
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
55
|
+
id TEXT PRIMARY KEY, -- UUID
|
|
56
|
+
goal TEXT,
|
|
57
|
+
started_at INTEGER DEFAULT (unixepoch()),
|
|
58
|
+
updated_at INTEGER DEFAULT (unixepoch()),
|
|
59
|
+
compaction_count INTEGER DEFAULT 0
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
-- Files touched during a session (opened, modified, created, deleted)
|
|
63
|
+
CREATE TABLE IF NOT EXISTS touched_files (
|
|
64
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
65
|
+
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
66
|
+
path TEXT NOT NULL,
|
|
67
|
+
action TEXT NOT NULL, -- opened | modified | created | deleted
|
|
68
|
+
touched_at INTEGER DEFAULT (unixepoch())
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
-- Structured task state saved by AI during a session
|
|
72
|
+
CREATE TABLE IF NOT EXISTS tasks (
|
|
73
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
74
|
+
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
75
|
+
goal TEXT,
|
|
76
|
+
decisions TEXT, -- JSON array of strings
|
|
77
|
+
next_steps TEXT, -- JSON array of strings
|
|
78
|
+
open_questions TEXT, -- JSON array of strings
|
|
79
|
+
saved_at INTEGER DEFAULT (unixepoch())
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
-- Manual feature-to-file mappings (populated by AI via register_feature tool)
|
|
83
|
+
CREATE TABLE IF NOT EXISTS features (
|
|
84
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
85
|
+
name TEXT NOT NULL,
|
|
86
|
+
layer TEXT NOT NULL, -- controller | service | repository | ui | test | db | model
|
|
87
|
+
file_path TEXT NOT NULL,
|
|
88
|
+
description TEXT,
|
|
89
|
+
created_at INTEGER DEFAULT (unixepoch())
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
-- Cached live database schema (populated by get_schema tool)
|
|
93
|
+
CREATE TABLE IF NOT EXISTS schema_cache (
|
|
94
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
95
|
+
table_name TEXT NOT NULL UNIQUE,
|
|
96
|
+
schema_json TEXT NOT NULL,
|
|
97
|
+
cached_at INTEGER DEFAULT (unixepoch())
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
-- Every MCP tool call logged for observability
|
|
101
|
+
CREATE TABLE IF NOT EXISTS tool_usage (
|
|
102
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
103
|
+
session_id TEXT,
|
|
104
|
+
tool_name TEXT NOT NULL,
|
|
105
|
+
input_json TEXT,
|
|
106
|
+
tokens_returned INTEGER,
|
|
107
|
+
duration_ms INTEGER,
|
|
108
|
+
called_at INTEGER DEFAULT (unixepoch())
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
-- ─── Indexes ────────────────────────────────────────────────────────────────
|
|
112
|
+
CREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file_id);
|
|
113
|
+
CREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);
|
|
114
|
+
CREATE INDEX IF NOT EXISTS idx_symbols_kind ON symbols(kind);
|
|
115
|
+
CREATE INDEX IF NOT EXISTS idx_relationships_from ON relationships(from_id);
|
|
116
|
+
CREATE INDEX IF NOT EXISTS idx_touched_session ON touched_files(session_id);
|
|
117
|
+
CREATE INDEX IF NOT EXISTS idx_touched_path ON touched_files(path);
|
|
118
|
+
CREATE INDEX IF NOT EXISTS idx_features_name ON features(name);
|
|
119
|
+
CREATE INDEX IF NOT EXISTS idx_files_language ON files(language);
|
|
120
|
+
CREATE INDEX IF NOT EXISTS idx_tool_session ON tool_usage(session_id);
|
|
121
|
+
CREATE INDEX IF NOT EXISTS idx_tool_name ON tool_usage(tool_name);
|