@pella-labs/pinakes 0.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 +208 -0
- package/dist/cli/audit.d.ts +30 -0
- package/dist/cli/audit.d.ts.map +1 -0
- package/dist/cli/audit.js +49 -0
- package/dist/cli/audit.js.map +1 -0
- package/dist/cli/export.d.ts +32 -0
- package/dist/cli/export.d.ts.map +1 -0
- package/dist/cli/export.js +73 -0
- package/dist/cli/export.js.map +1 -0
- package/dist/cli/import.d.ts +24 -0
- package/dist/cli/import.d.ts.map +1 -0
- package/dist/cli/import.js +96 -0
- package/dist/cli/import.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +172 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/purge.d.ts +23 -0
- package/dist/cli/purge.d.ts.map +1 -0
- package/dist/cli/purge.js +57 -0
- package/dist/cli/purge.js.map +1 -0
- package/dist/cli/rebuild.d.ts +54 -0
- package/dist/cli/rebuild.d.ts.map +1 -0
- package/dist/cli/rebuild.js +113 -0
- package/dist/cli/rebuild.js.map +1 -0
- package/dist/cli/serve.d.ts +49 -0
- package/dist/cli/serve.d.ts.map +1 -0
- package/dist/cli/serve.js +296 -0
- package/dist/cli/serve.js.map +1 -0
- package/dist/cli/status.d.ts +39 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +108 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/db/client.d.ts +109 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +175 -0
- package/dist/db/client.js.map +1 -0
- package/dist/db/repository.d.ts +82 -0
- package/dist/db/repository.d.ts.map +1 -0
- package/dist/db/repository.js +173 -0
- package/dist/db/repository.js.map +1 -0
- package/dist/db/schema.d.ts +990 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +259 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/db/types.d.ts +28 -0
- package/dist/db/types.d.ts.map +1 -0
- package/dist/db/types.js +11 -0
- package/dist/db/types.js.map +1 -0
- package/dist/gaps/detector.d.ts +67 -0
- package/dist/gaps/detector.d.ts.map +1 -0
- package/dist/gaps/detector.js +160 -0
- package/dist/gaps/detector.js.map +1 -0
- package/dist/gate/budget.d.ts +90 -0
- package/dist/gate/budget.d.ts.map +1 -0
- package/dist/gate/budget.js +145 -0
- package/dist/gate/budget.js.map +1 -0
- package/dist/ingest/chokidar.d.ts +33 -0
- package/dist/ingest/chokidar.d.ts.map +1 -0
- package/dist/ingest/chokidar.js +152 -0
- package/dist/ingest/chokidar.js.map +1 -0
- package/dist/ingest/ingester.d.ts +117 -0
- package/dist/ingest/ingester.d.ts.map +1 -0
- package/dist/ingest/ingester.js +312 -0
- package/dist/ingest/ingester.js.map +1 -0
- package/dist/ingest/manifest.d.ts +87 -0
- package/dist/ingest/manifest.d.ts.map +1 -0
- package/dist/ingest/manifest.js +223 -0
- package/dist/ingest/manifest.js.map +1 -0
- package/dist/ingest/memory-store.d.ts +55 -0
- package/dist/ingest/memory-store.d.ts.map +1 -0
- package/dist/ingest/memory-store.js +94 -0
- package/dist/ingest/memory-store.js.map +1 -0
- package/dist/ingest/parse/chunk.d.ts +15 -0
- package/dist/ingest/parse/chunk.d.ts.map +1 -0
- package/dist/ingest/parse/chunk.js +88 -0
- package/dist/ingest/parse/chunk.js.map +1 -0
- package/dist/ingest/parse/markdown.d.ts +64 -0
- package/dist/ingest/parse/markdown.d.ts.map +1 -0
- package/dist/ingest/parse/markdown.js +152 -0
- package/dist/ingest/parse/markdown.js.map +1 -0
- package/dist/ingest/queue.d.ts +21 -0
- package/dist/ingest/queue.d.ts.map +1 -0
- package/dist/ingest/queue.js +24 -0
- package/dist/ingest/queue.js.map +1 -0
- package/dist/ingest/source.d.ts +42 -0
- package/dist/ingest/source.d.ts.map +1 -0
- package/dist/ingest/source.js +19 -0
- package/dist/ingest/source.js.map +1 -0
- package/dist/mcp/envelope.d.ts +73 -0
- package/dist/mcp/envelope.d.ts.map +1 -0
- package/dist/mcp/envelope.js +46 -0
- package/dist/mcp/envelope.js.map +1 -0
- package/dist/mcp/tools/execute.d.ts +55 -0
- package/dist/mcp/tools/execute.d.ts.map +1 -0
- package/dist/mcp/tools/execute.js +232 -0
- package/dist/mcp/tools/execute.js.map +1 -0
- package/dist/mcp/tools/search.d.ts +53 -0
- package/dist/mcp/tools/search.d.ts.map +1 -0
- package/dist/mcp/tools/search.js +114 -0
- package/dist/mcp/tools/search.js.map +1 -0
- package/dist/observability/audit.d.ts +25 -0
- package/dist/observability/audit.d.ts.map +1 -0
- package/dist/observability/audit.js +38 -0
- package/dist/observability/audit.js.map +1 -0
- package/dist/observability/logger.d.ts +4 -0
- package/dist/observability/logger.d.ts.map +1 -0
- package/dist/observability/logger.js +56 -0
- package/dist/observability/logger.js.map +1 -0
- package/dist/observability/metrics.d.ts +38 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/metrics.js +64 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/retrieval/embedder.d.ts +130 -0
- package/dist/retrieval/embedder.d.ts.map +1 -0
- package/dist/retrieval/embedder.js +278 -0
- package/dist/retrieval/embedder.js.map +1 -0
- package/dist/retrieval/fts.d.ts +42 -0
- package/dist/retrieval/fts.d.ts.map +1 -0
- package/dist/retrieval/fts.js +46 -0
- package/dist/retrieval/fts.js.map +1 -0
- package/dist/retrieval/hybrid.d.ts +43 -0
- package/dist/retrieval/hybrid.d.ts.map +1 -0
- package/dist/retrieval/hybrid.js +120 -0
- package/dist/retrieval/hybrid.js.map +1 -0
- package/dist/retrieval/vec.d.ts +39 -0
- package/dist/retrieval/vec.d.ts.map +1 -0
- package/dist/retrieval/vec.js +50 -0
- package/dist/retrieval/vec.js.map +1 -0
- package/dist/sandbox/bindings/budget.d.ts +10 -0
- package/dist/sandbox/bindings/budget.d.ts.map +1 -0
- package/dist/sandbox/bindings/budget.js +44 -0
- package/dist/sandbox/bindings/budget.js.map +1 -0
- package/dist/sandbox/bindings/install.d.ts +23 -0
- package/dist/sandbox/bindings/install.d.ts.map +1 -0
- package/dist/sandbox/bindings/install.js +15 -0
- package/dist/sandbox/bindings/install.js.map +1 -0
- package/dist/sandbox/bindings/kg.d.ts +29 -0
- package/dist/sandbox/bindings/kg.d.ts.map +1 -0
- package/dist/sandbox/bindings/kg.js +323 -0
- package/dist/sandbox/bindings/kg.js.map +1 -0
- package/dist/sandbox/bindings/logger.d.ts +11 -0
- package/dist/sandbox/bindings/logger.d.ts.map +1 -0
- package/dist/sandbox/bindings/logger.js +33 -0
- package/dist/sandbox/bindings/logger.js.map +1 -0
- package/dist/sandbox/bindings/write.d.ts +34 -0
- package/dist/sandbox/bindings/write.d.ts.map +1 -0
- package/dist/sandbox/bindings/write.js +195 -0
- package/dist/sandbox/bindings/write.js.map +1 -0
- package/dist/sandbox/executor.d.ts +68 -0
- package/dist/sandbox/executor.d.ts.map +1 -0
- package/dist/sandbox/executor.js +280 -0
- package/dist/sandbox/executor.js.map +1 -0
- package/dist/sandbox/helpers.d.ts +26 -0
- package/dist/sandbox/helpers.d.ts.map +1 -0
- package/dist/sandbox/helpers.js +131 -0
- package/dist/sandbox/helpers.js.map +1 -0
- package/dist/sandbox/pool.d.ts +63 -0
- package/dist/sandbox/pool.d.ts.map +1 -0
- package/dist/sandbox/pool.js +98 -0
- package/dist/sandbox/pool.js.map +1 -0
- package/dist/sandbox/vendored-codemode.d.ts +99 -0
- package/dist/sandbox/vendored-codemode.d.ts.map +1 -0
- package/dist/sandbox/vendored-codemode.js +471 -0
- package/dist/sandbox/vendored-codemode.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +74 -0
- package/dist/server.js.map +1 -0
- package/dist/spike.d.ts +15 -0
- package/dist/spike.d.ts.map +1 -0
- package/dist/spike.js +90 -0
- package/dist/spike.js.map +1 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# kg-mcp
|
|
2
|
+
|
|
3
|
+
Local stdio MCP server that indexes a [Karpathy-style](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f) two-level knowledge wiki (project + personal) into SQLite and exposes it to any coding LLM via [Cloudflare-style code-mode](https://blog.cloudflare.com/code-mode-mcp/).
|
|
4
|
+
|
|
5
|
+
**Two tools. One process. Works with any MCP client.**
|
|
6
|
+
|
|
7
|
+
- `kg_search` — hybrid FTS5 + vector search ranked by Reciprocal Rank Fusion
|
|
8
|
+
- `kg_execute` — run JS in a QuickJS sandbox with `kg.project.*` bindings for search, graph traversal, wiki writes, and more
|
|
9
|
+
|
|
10
|
+
Markdown is canonical. SQLite is the index. If the index is corrupted or lost, rebuild it from markdown.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# Clone and build
|
|
16
|
+
git clone <repo-url> && cd knowledge-graph
|
|
17
|
+
pnpm install
|
|
18
|
+
pnpm run build
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Requires **Node.js 24 LTS** (`^24.10.0`) and **pnpm** (`>=10.30.0`).
|
|
22
|
+
|
|
23
|
+
## Quick start
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Initialize a wiki directory
|
|
27
|
+
mkdir -p .kg/wiki
|
|
28
|
+
echo "# My Project\nSome knowledge about the project." > .kg/wiki/overview.md
|
|
29
|
+
|
|
30
|
+
# Start the stdio server
|
|
31
|
+
pnpm run kg -- serve --wiki-path .kg/wiki
|
|
32
|
+
|
|
33
|
+
# Or rebuild the index from existing markdown
|
|
34
|
+
pnpm run kg -- rebuild --wiki-path .kg/wiki
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## MCP client configuration
|
|
38
|
+
|
|
39
|
+
### Claude Code
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
claude mcp add kg-mcp -- npx tsx /path/to/knowledge-graph/src/cli/index.ts serve --wiki-path /path/to/project/.kg/wiki
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Or add to `.claude/settings.json`:
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"mcpServers": {
|
|
50
|
+
"kg-mcp": {
|
|
51
|
+
"command": "npx",
|
|
52
|
+
"args": ["tsx", "/path/to/knowledge-graph/src/cli/index.ts", "serve", "--wiki-path", "/path/to/project/.kg/wiki"]
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Goose
|
|
59
|
+
|
|
60
|
+
Add to `~/.config/goose/profiles.yaml`:
|
|
61
|
+
|
|
62
|
+
```yaml
|
|
63
|
+
extensions:
|
|
64
|
+
kg-mcp:
|
|
65
|
+
name: kg-mcp
|
|
66
|
+
type: stdio
|
|
67
|
+
cmd: npx
|
|
68
|
+
args:
|
|
69
|
+
- tsx
|
|
70
|
+
- /path/to/knowledge-graph/src/cli/index.ts
|
|
71
|
+
- serve
|
|
72
|
+
- --wiki-path
|
|
73
|
+
- /path/to/project/.kg/wiki
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Codex
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
export CODEX_MCP_SERVERS='{"kg-mcp":{"command":"npx","args":["tsx","/path/to/knowledge-graph/src/cli/index.ts","serve","--wiki-path","/path/to/project/.kg/wiki"]}}'
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### OpenCode
|
|
83
|
+
|
|
84
|
+
Add to `opencode.json`:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"mcp": {
|
|
89
|
+
"kg-mcp": {
|
|
90
|
+
"command": "npx",
|
|
91
|
+
"args": ["tsx", "/path/to/knowledge-graph/src/cli/index.ts", "serve", "--wiki-path", "/path/to/project/.kg/wiki"]
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Cursor
|
|
98
|
+
|
|
99
|
+
Add to Cursor settings (Settings > MCP Servers):
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"mcpServers": {
|
|
104
|
+
"kg-mcp": {
|
|
105
|
+
"command": "npx",
|
|
106
|
+
"args": ["tsx", "/path/to/knowledge-graph/src/cli/index.ts", "serve", "--wiki-path", "/path/to/project/.kg/wiki"]
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Example queries
|
|
113
|
+
|
|
114
|
+
### Search
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
kg_search({ query: "authentication flow", scope: "project" })
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Execute (code-mode)
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
// Full-text search
|
|
124
|
+
kg_execute({ code: `return kg.project.fts("bcrypt")` })
|
|
125
|
+
|
|
126
|
+
// Node lookup + neighbors
|
|
127
|
+
kg_execute({ code: `
|
|
128
|
+
const node = kg.project.get("sha1-id-here");
|
|
129
|
+
const neighbors = kg.project.neighbors(node.id, { depth: 2 });
|
|
130
|
+
return { node, neighbors };
|
|
131
|
+
` })
|
|
132
|
+
|
|
133
|
+
// Write a wiki page
|
|
134
|
+
kg_execute({ code: `
|
|
135
|
+
return kg.project.write("decisions/use-postgres.md", "# Use PostgreSQL\\nWe chose Postgres because...");
|
|
136
|
+
` })
|
|
137
|
+
|
|
138
|
+
// Query across both scopes
|
|
139
|
+
kg_execute({
|
|
140
|
+
code: `return kg.project.hybrid("deploy process")`,
|
|
141
|
+
scope: "both"
|
|
142
|
+
})
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## CLI commands
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
kg serve --wiki-path <dir> # Start the stdio MCP server
|
|
149
|
+
kg rebuild --wiki-path <dir> # Full rebuild from markdown
|
|
150
|
+
kg status # Health check + row counts
|
|
151
|
+
kg audit [--tail] [--n 20] # Tail the audit log
|
|
152
|
+
kg purge --scope <s> --confirm # Delete a scope's DB
|
|
153
|
+
kg export --scope <s> [--out f] # Dump nodes + edges as JSON
|
|
154
|
+
kg import --scope <s> --in f # Restore from dump
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Embedder configuration
|
|
158
|
+
|
|
159
|
+
The default embedder is bundled (`Xenova/all-MiniLM-L6-v2`, 384 dimensions, runs locally). You can upgrade to a more capable embedder via environment variables:
|
|
160
|
+
|
|
161
|
+
### Ollama (local, free)
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
export KG_EMBED_PROVIDER=ollama
|
|
165
|
+
export KG_OLLAMA_URL=http://localhost:11434
|
|
166
|
+
export KG_OLLAMA_MODEL=nomic-embed-text
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Voyage AI (cloud, paid)
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
export KG_EMBED_PROVIDER=voyage
|
|
173
|
+
export KG_VOYAGE_API_KEY=your-key-here
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### OpenAI (cloud, paid)
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
export KG_EMBED_PROVIDER=openai
|
|
180
|
+
export KG_OPENAI_API_KEY=your-key-here
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Changing the embedder requires a full rebuild (`kg rebuild`) since the vector dimensions change.
|
|
184
|
+
|
|
185
|
+
## Architecture
|
|
186
|
+
|
|
187
|
+
- **Single process**: MCP server, file watcher, SQLite writer, read pool, embedder, and QuickJS sandbox all in one Node process
|
|
188
|
+
- **Single writer, multi reader**: one writer connection + 2 reader connections per DB, WAL mode
|
|
189
|
+
- **Two-level KG**: project wiki (`.kg/wiki/`) + personal wiki (`~/.kg/wiki/`), fully isolated by default
|
|
190
|
+
- **Privacy invariant**: personal KG bindings are only injected when `scope` includes `'personal'`
|
|
191
|
+
- **Budget gate**: every response stays under `max_tokens` (default 5000, hard cap 25000)
|
|
192
|
+
- **Deterministic IDs**: `sha1(scope + ':' + source_uri + ':' + section_path)` means re-indexing is idempotent
|
|
193
|
+
|
|
194
|
+
## Development
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
pnpm install
|
|
198
|
+
pnpm run dev # Watch mode
|
|
199
|
+
pnpm run test # Run tests (vitest)
|
|
200
|
+
pnpm run test:privacy # Privacy adversarial suite (merge blocker)
|
|
201
|
+
pnpm run test:budget # Budget gate adversarial suite
|
|
202
|
+
pnpm run typecheck # tsc --noEmit
|
|
203
|
+
pnpm run lint # eslint
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## License
|
|
207
|
+
|
|
208
|
+
See LICENSE file.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kg audit --tail` — tail the kg_audit table for a scope's DB.
|
|
3
|
+
*
|
|
4
|
+
* Reads the most recent N audit rows (default 20) and prints them as
|
|
5
|
+
* newline-delimited JSON. Strictly read-only.
|
|
6
|
+
*/
|
|
7
|
+
export interface AuditOptions {
|
|
8
|
+
/** Number of rows to show (default 20) */
|
|
9
|
+
n?: number;
|
|
10
|
+
/** Project DB path */
|
|
11
|
+
dbPath?: string;
|
|
12
|
+
/** Wiki path (used to derive default dbPath) */
|
|
13
|
+
wikiPath?: string;
|
|
14
|
+
/** Personal DB path */
|
|
15
|
+
profileDbPath?: string;
|
|
16
|
+
/** Which scope to tail: 'project' | 'personal' (default 'project') */
|
|
17
|
+
scope?: 'project' | 'personal';
|
|
18
|
+
}
|
|
19
|
+
export interface AuditRow {
|
|
20
|
+
id: number;
|
|
21
|
+
ts: number;
|
|
22
|
+
tool_name: string;
|
|
23
|
+
scope_requested: string;
|
|
24
|
+
caller_ctx: string | null;
|
|
25
|
+
response_tokens: number | null;
|
|
26
|
+
error: string | null;
|
|
27
|
+
}
|
|
28
|
+
export declare function auditCommand(options: AuditOptions): AuditRow[];
|
|
29
|
+
export declare function renderAudit(rows: AuditRow[]): string;
|
|
30
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/cli/audit.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AAEH,MAAM,WAAW,YAAY;IAC3B,0CAA0C;IAC1C,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sEAAsE;IACtE,KAAK,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,QAAQ,EAAE,CAqB9D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,CAGpD"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { dirname, isAbsolute, resolve } from 'node:path';
|
|
4
|
+
import { closeDb, openDb } from '../db/client.js';
|
|
5
|
+
export function auditCommand(options) {
|
|
6
|
+
const scope = options.scope ?? 'project';
|
|
7
|
+
const n = options.n ?? 20;
|
|
8
|
+
const dbPath = resolveDbPath(options, scope);
|
|
9
|
+
if (!existsSync(dbPath)) {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
const bundle = openDb(dbPath, { runMigrations: false });
|
|
13
|
+
try {
|
|
14
|
+
const rows = bundle.writer
|
|
15
|
+
.prepare(`SELECT id, ts, tool_name, scope_requested, caller_ctx, response_tokens, error
|
|
16
|
+
FROM kg_audit ORDER BY id DESC LIMIT ?`)
|
|
17
|
+
.all(n);
|
|
18
|
+
return rows.reverse(); // chronological order
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
closeDb(bundle);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function renderAudit(rows) {
|
|
25
|
+
if (rows.length === 0)
|
|
26
|
+
return '(no audit rows)';
|
|
27
|
+
return rows.map((r) => JSON.stringify(r)).join('\n');
|
|
28
|
+
}
|
|
29
|
+
// ----------------------------------------------------------------------------
|
|
30
|
+
// Path helpers (shared pattern with status.ts)
|
|
31
|
+
// ----------------------------------------------------------------------------
|
|
32
|
+
function resolveDbPath(options, scope) {
|
|
33
|
+
if (scope === 'personal') {
|
|
34
|
+
if (options.profileDbPath)
|
|
35
|
+
return resolveAbs(options.profileDbPath);
|
|
36
|
+
const env = process.env.KG_PROFILE_PATH;
|
|
37
|
+
const profileDir = env ? resolveAbs(env) : resolve(homedir(), '.pharos/profile');
|
|
38
|
+
return resolve(profileDir, 'kg.db');
|
|
39
|
+
}
|
|
40
|
+
if (options.dbPath)
|
|
41
|
+
return resolveAbs(options.dbPath);
|
|
42
|
+
if (options.wikiPath)
|
|
43
|
+
return resolve(dirname(resolveAbs(options.wikiPath)), 'kg.db');
|
|
44
|
+
return resolve(process.cwd(), '.pharos/kg.db');
|
|
45
|
+
}
|
|
46
|
+
function resolveAbs(p) {
|
|
47
|
+
return isAbsolute(p) ? p : resolve(process.cwd(), p);
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/cli/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAgClD,MAAM,UAAU,YAAY,CAAC,OAAqB;IAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,SAAS,CAAC;IACzC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAE7C,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM;aACvB,OAAO,CACN;gDACwC,CACzC;aACA,GAAG,CAAC,CAAC,CAAe,CAAC;QACxB,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,sBAAsB;IAC/C,CAAC;YAAS,CAAC;QACT,OAAO,CAAC,MAAM,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAgB;IAC1C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,iBAAiB,CAAC;IAChD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACvD,CAAC;AAED,+EAA+E;AAC/E,+CAA+C;AAC/C,+EAA+E;AAE/E,SAAS,aAAa,CAAC,OAAqB,EAAE,KAA6B;IACzE,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;QACzB,IAAI,OAAO,CAAC,aAAa;YAAE,OAAO,UAAU,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QACpE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;QACxC,MAAM,UAAU,GAAG,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,iBAAiB,CAAC,CAAC;QACjF,OAAO,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IACD,IAAI,OAAO,CAAC,MAAM;QAAE,OAAO,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,IAAI,OAAO,CAAC,QAAQ;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACrF,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kg export --scope <s> [--out file.json]` — dump a scope's nodes + edges
|
|
3
|
+
* as JSON for backup / migration / debugging.
|
|
4
|
+
*
|
|
5
|
+
* Output format:
|
|
6
|
+
* ```json
|
|
7
|
+
* {
|
|
8
|
+
* "scope": "project",
|
|
9
|
+
* "exported_at": "2026-04-09T...",
|
|
10
|
+
* "nodes": [ ... ],
|
|
11
|
+
* "edges": [ ... ],
|
|
12
|
+
* "chunks": [ ... ]
|
|
13
|
+
* }
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export interface ExportOptions {
|
|
17
|
+
scope: 'project' | 'personal';
|
|
18
|
+
out?: string;
|
|
19
|
+
dbPath?: string;
|
|
20
|
+
wikiPath?: string;
|
|
21
|
+
profileDbPath?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface ExportData {
|
|
24
|
+
scope: string;
|
|
25
|
+
exported_at: string;
|
|
26
|
+
nodes: unknown[];
|
|
27
|
+
edges: unknown[];
|
|
28
|
+
chunks: unknown[];
|
|
29
|
+
}
|
|
30
|
+
export declare function exportCommand(options: ExportOptions): ExportData;
|
|
31
|
+
export declare function renderExport(data: ExportData, outPath?: string): string;
|
|
32
|
+
//# sourceMappingURL=export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/cli/export.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,GAAG,UAAU,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,MAAM,EAAE,OAAO,EAAE,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,UAAU,CAiDhE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAIvE"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { existsSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { dirname, isAbsolute, resolve } from 'node:path';
|
|
4
|
+
import { closeDb, openDb } from '../db/client.js';
|
|
5
|
+
export function exportCommand(options) {
|
|
6
|
+
const dbPath = resolveDbPath(options, options.scope);
|
|
7
|
+
if (!existsSync(dbPath)) {
|
|
8
|
+
return {
|
|
9
|
+
scope: options.scope,
|
|
10
|
+
exported_at: new Date().toISOString(),
|
|
11
|
+
nodes: [],
|
|
12
|
+
edges: [],
|
|
13
|
+
chunks: [],
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const bundle = openDb(dbPath, { runMigrations: false });
|
|
17
|
+
try {
|
|
18
|
+
const nodes = bundle.writer
|
|
19
|
+
.prepare(`SELECT * FROM kg_nodes WHERE scope = ?`)
|
|
20
|
+
.all(options.scope);
|
|
21
|
+
const edges = bundle.writer
|
|
22
|
+
.prepare(`SELECT e.* FROM kg_edges e
|
|
23
|
+
JOIN kg_nodes n ON e.src_id = n.id
|
|
24
|
+
WHERE n.scope = ?`)
|
|
25
|
+
.all(options.scope);
|
|
26
|
+
const chunks = bundle.writer
|
|
27
|
+
.prepare(`SELECT c.* FROM kg_chunks c
|
|
28
|
+
JOIN kg_nodes n ON c.node_id = n.id
|
|
29
|
+
WHERE n.scope = ?`)
|
|
30
|
+
.all(options.scope);
|
|
31
|
+
const data = {
|
|
32
|
+
scope: options.scope,
|
|
33
|
+
exported_at: new Date().toISOString(),
|
|
34
|
+
nodes,
|
|
35
|
+
edges,
|
|
36
|
+
chunks,
|
|
37
|
+
};
|
|
38
|
+
if (options.out) {
|
|
39
|
+
writeFileSync(options.out, JSON.stringify(data, null, 2), 'utf-8');
|
|
40
|
+
}
|
|
41
|
+
return data;
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
closeDb(bundle);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function renderExport(data, outPath) {
|
|
48
|
+
const line = `${data.scope}: ${data.nodes.length} nodes, ${data.edges.length} edges, ${data.chunks.length} chunks`;
|
|
49
|
+
if (outPath)
|
|
50
|
+
return `${line} → ${outPath}`;
|
|
51
|
+
return line;
|
|
52
|
+
}
|
|
53
|
+
// ----------------------------------------------------------------------------
|
|
54
|
+
// Path helpers
|
|
55
|
+
// ----------------------------------------------------------------------------
|
|
56
|
+
function resolveDbPath(options, scope) {
|
|
57
|
+
if (scope === 'personal') {
|
|
58
|
+
if (options.profileDbPath)
|
|
59
|
+
return resolveAbs(options.profileDbPath);
|
|
60
|
+
const env = process.env.KG_PROFILE_PATH;
|
|
61
|
+
const profileDir = env ? resolveAbs(env) : resolve(homedir(), '.pharos/profile');
|
|
62
|
+
return resolve(profileDir, 'kg.db');
|
|
63
|
+
}
|
|
64
|
+
if (options.dbPath)
|
|
65
|
+
return resolveAbs(options.dbPath);
|
|
66
|
+
if (options.wikiPath)
|
|
67
|
+
return resolve(dirname(resolveAbs(options.wikiPath)), 'kg.db');
|
|
68
|
+
return resolve(process.cwd(), '.pharos/kg.db');
|
|
69
|
+
}
|
|
70
|
+
function resolveAbs(p) {
|
|
71
|
+
return isAbsolute(p) ? p : resolve(process.cwd(), p);
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/cli/export.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kg import --scope <s> --in file.json` — restore nodes, edges, and chunks
|
|
3
|
+
* from a JSON dump produced by `kg export`.
|
|
4
|
+
*
|
|
5
|
+
* Imports are additive: existing rows with the same PK are replaced via
|
|
6
|
+
* INSERT OR REPLACE. This makes import idempotent — running it twice
|
|
7
|
+
* with the same file produces the same DB state.
|
|
8
|
+
*/
|
|
9
|
+
export interface ImportOptions {
|
|
10
|
+
scope: 'project' | 'personal';
|
|
11
|
+
inFile: string;
|
|
12
|
+
dbPath?: string;
|
|
13
|
+
wikiPath?: string;
|
|
14
|
+
profileDbPath?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ImportResult {
|
|
17
|
+
scope: string;
|
|
18
|
+
nodes: number;
|
|
19
|
+
edges: number;
|
|
20
|
+
chunks: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function importCommand(options: ImportOptions): ImportResult;
|
|
23
|
+
export declare function renderImport(result: ImportResult): string;
|
|
24
|
+
//# sourceMappingURL=import.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../../src/cli/import.ts"],"names":[],"mappings":"AAOA;;;;;;;GAOG;AAEH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,GAAG,UAAU,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAaD,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,YAAY,CAuFlE;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAEzD"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { dirname, isAbsolute, resolve } from 'node:path';
|
|
4
|
+
import { closeDb, openDb } from '../db/client.js';
|
|
5
|
+
import { logger } from '../observability/logger.js';
|
|
6
|
+
export function importCommand(options) {
|
|
7
|
+
if (!existsSync(options.inFile)) {
|
|
8
|
+
throw new Error(`input file does not exist: ${options.inFile}`);
|
|
9
|
+
}
|
|
10
|
+
const raw = readFileSync(options.inFile, 'utf-8');
|
|
11
|
+
const data = JSON.parse(raw);
|
|
12
|
+
if (data.scope && data.scope !== options.scope) {
|
|
13
|
+
logger.warn({ fileScope: data.scope, requestedScope: options.scope }, 'import file scope does not match requested scope');
|
|
14
|
+
}
|
|
15
|
+
const dbPath = resolveDbPath(options, options.scope);
|
|
16
|
+
const bundle = openDb(dbPath);
|
|
17
|
+
try {
|
|
18
|
+
const result = { scope: options.scope, nodes: 0, edges: 0, chunks: 0 };
|
|
19
|
+
bundle.writer.exec('BEGIN');
|
|
20
|
+
try {
|
|
21
|
+
// Import nodes
|
|
22
|
+
if (data.nodes?.length) {
|
|
23
|
+
const insertNode = bundle.writer.prepare(`INSERT OR REPLACE INTO kg_nodes
|
|
24
|
+
(id, scope, source_uri, section_path, kind, title, content, source_sha, token_count, confidence, created_at, updated_at, last_accessed_at)
|
|
25
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
26
|
+
for (const n of data.nodes) {
|
|
27
|
+
insertNode.run(n.id, options.scope, n.source_uri, n.section_path, n.kind ?? 'section', n.title ?? null, n.content, n.source_sha, n.token_count ?? 0, n.confidence ?? 'extracted', n.created_at ?? Date.now(), n.updated_at ?? Date.now(), n.last_accessed_at ?? Date.now());
|
|
28
|
+
result.nodes++;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Import edges
|
|
32
|
+
if (data.edges?.length) {
|
|
33
|
+
const insertEdge = bundle.writer.prepare(`INSERT OR REPLACE INTO kg_edges (src_id, dst_id, edge_kind)
|
|
34
|
+
VALUES (?, ?, ?)`);
|
|
35
|
+
for (const e of data.edges) {
|
|
36
|
+
try {
|
|
37
|
+
insertEdge.run(e.src_id, e.dst_id, e.edge_kind);
|
|
38
|
+
result.edges++;
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
// FK violations expected if referenced nodes aren't in the dump
|
|
42
|
+
logger.debug({ err, edge: e }, 'import: skipped edge (FK violation)');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Import chunks
|
|
47
|
+
if (data.chunks?.length) {
|
|
48
|
+
const insertChunk = bundle.writer.prepare(`INSERT OR REPLACE INTO kg_chunks
|
|
49
|
+
(id, node_id, chunk_index, text, chunk_sha, token_count, created_at)
|
|
50
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`);
|
|
51
|
+
for (const c of data.chunks) {
|
|
52
|
+
try {
|
|
53
|
+
insertChunk.run(c.id, c.node_id, c.chunk_index, c.text, c.chunk_sha, c.token_count ?? 0, c.created_at ?? Date.now());
|
|
54
|
+
result.chunks++;
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
logger.debug({ err, chunk: c }, 'import: skipped chunk (FK violation)');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
bundle.writer.exec('COMMIT');
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
bundle.writer.exec('ROLLBACK');
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
closeDb(bundle);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export function renderImport(result) {
|
|
74
|
+
return `${result.scope}: imported ${result.nodes} nodes, ${result.edges} edges, ${result.chunks} chunks`;
|
|
75
|
+
}
|
|
76
|
+
// ----------------------------------------------------------------------------
|
|
77
|
+
// Path helpers
|
|
78
|
+
// ----------------------------------------------------------------------------
|
|
79
|
+
function resolveDbPath(options, scope) {
|
|
80
|
+
if (scope === 'personal') {
|
|
81
|
+
if (options.profileDbPath)
|
|
82
|
+
return resolveAbs(options.profileDbPath);
|
|
83
|
+
const env = process.env.KG_PROFILE_PATH;
|
|
84
|
+
const profileDir = env ? resolveAbs(env) : resolve(homedir(), '.pharos/profile');
|
|
85
|
+
return resolve(profileDir, 'kg.db');
|
|
86
|
+
}
|
|
87
|
+
if (options.dbPath)
|
|
88
|
+
return resolveAbs(options.dbPath);
|
|
89
|
+
if (options.wikiPath)
|
|
90
|
+
return resolve(dirname(resolveAbs(options.wikiPath)), 'kg.db');
|
|
91
|
+
return resolve(process.cwd(), '.pharos/kg.db');
|
|
92
|
+
}
|
|
93
|
+
function resolveAbs(p) {
|
|
94
|
+
return isAbsolute(p) ? p : resolve(process.cwd(), p);
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/cli/import.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|