@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
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { auditCommand, renderAudit } from './audit.js';
|
|
3
|
+
import { exportCommand, renderExport } from './export.js';
|
|
4
|
+
import { importCommand, renderImport } from './import.js';
|
|
5
|
+
import { purgeCommand, renderPurge } from './purge.js';
|
|
6
|
+
import { rebuildCommand } from './rebuild.js';
|
|
7
|
+
import { renderStatus, statusCommand } from './status.js';
|
|
8
|
+
import { serveCommand } from './serve.js';
|
|
9
|
+
import { logger } from '../observability/logger.js';
|
|
10
|
+
function parseFlags(argv) {
|
|
11
|
+
const flags = {};
|
|
12
|
+
const positional = [];
|
|
13
|
+
for (let i = 0; i < argv.length; i++) {
|
|
14
|
+
const arg = argv[i];
|
|
15
|
+
if (arg.startsWith('--')) {
|
|
16
|
+
const eqIdx = arg.indexOf('=');
|
|
17
|
+
if (eqIdx > 0) {
|
|
18
|
+
flags[arg.slice(2, eqIdx)] = arg.slice(eqIdx + 1);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
const next = argv[i + 1];
|
|
22
|
+
if (next && !next.startsWith('--')) {
|
|
23
|
+
flags[arg.slice(2)] = next;
|
|
24
|
+
i++;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
flags[arg.slice(2)] = true;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
positional.push(arg);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return { flags, positional };
|
|
36
|
+
}
|
|
37
|
+
function getString(flags, key) {
|
|
38
|
+
const v = flags[key];
|
|
39
|
+
return typeof v === 'string' ? v : undefined;
|
|
40
|
+
}
|
|
41
|
+
function getRequiredString(flags, key) {
|
|
42
|
+
const v = getString(flags, key);
|
|
43
|
+
if (!v)
|
|
44
|
+
throw new Error(`missing required flag: --${key}`);
|
|
45
|
+
return v;
|
|
46
|
+
}
|
|
47
|
+
async function main() {
|
|
48
|
+
const argv = process.argv.slice(2);
|
|
49
|
+
const subcommand = argv[0];
|
|
50
|
+
const { flags } = parseFlags(argv.slice(1));
|
|
51
|
+
switch (subcommand) {
|
|
52
|
+
case 'serve': {
|
|
53
|
+
await serveCommand({
|
|
54
|
+
wikiPath: getRequiredString(flags, 'wiki-path'),
|
|
55
|
+
dbPath: getString(flags, 'db-path'),
|
|
56
|
+
profilePath: getString(flags, 'profile-path'),
|
|
57
|
+
profileDbPath: getString(flags, 'profile-db-path'),
|
|
58
|
+
});
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
case 'rebuild': {
|
|
62
|
+
const scope = getString(flags, 'scope');
|
|
63
|
+
const summaries = await rebuildCommand({
|
|
64
|
+
wikiPath: getRequiredString(flags, 'wiki-path'),
|
|
65
|
+
dbPath: getString(flags, 'db-path'),
|
|
66
|
+
profilePath: getString(flags, 'profile-path'),
|
|
67
|
+
profileDbPath: getString(flags, 'profile-db-path'),
|
|
68
|
+
scope,
|
|
69
|
+
});
|
|
70
|
+
for (const s of summaries) {
|
|
71
|
+
// eslint-disable-next-line no-console
|
|
72
|
+
console.log(`${s.scope.padEnd(8)} files=${s.files} nodes=${s.nodes} ` +
|
|
73
|
+
`chunks_added=${s.chunks_added} chunks_skipped=${s.chunks_skipped} ` +
|
|
74
|
+
`embedder_calls=${s.embedder_calls} duration=${s.durationMs}ms`);
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
case 'status': {
|
|
79
|
+
const statuses = statusCommand({
|
|
80
|
+
dbPath: getString(flags, 'db-path'),
|
|
81
|
+
wikiPath: getString(flags, 'wiki-path'),
|
|
82
|
+
profileDbPath: getString(flags, 'profile-db-path'),
|
|
83
|
+
});
|
|
84
|
+
// eslint-disable-next-line no-console
|
|
85
|
+
console.log(renderStatus(statuses));
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case 'audit': {
|
|
89
|
+
const rows = auditCommand({
|
|
90
|
+
n: getString(flags, 'n') ? parseInt(getString(flags, 'n'), 10) : undefined,
|
|
91
|
+
dbPath: getString(flags, 'db-path'),
|
|
92
|
+
wikiPath: getString(flags, 'wiki-path'),
|
|
93
|
+
profileDbPath: getString(flags, 'profile-db-path'),
|
|
94
|
+
scope: getString(flags, 'scope') ?? undefined,
|
|
95
|
+
});
|
|
96
|
+
// eslint-disable-next-line no-console
|
|
97
|
+
console.log(renderAudit(rows));
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
case 'purge': {
|
|
101
|
+
const scope = getRequiredString(flags, 'scope');
|
|
102
|
+
const result = purgeCommand({
|
|
103
|
+
scope,
|
|
104
|
+
confirm: flags['confirm'] === true,
|
|
105
|
+
dbPath: getString(flags, 'db-path'),
|
|
106
|
+
wikiPath: getString(flags, 'wiki-path'),
|
|
107
|
+
profileDbPath: getString(flags, 'profile-db-path'),
|
|
108
|
+
});
|
|
109
|
+
// eslint-disable-next-line no-console
|
|
110
|
+
console.log(renderPurge(result));
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
case 'export': {
|
|
114
|
+
const scope = getRequiredString(flags, 'scope');
|
|
115
|
+
const out = getString(flags, 'out');
|
|
116
|
+
const data = exportCommand({
|
|
117
|
+
scope,
|
|
118
|
+
out,
|
|
119
|
+
dbPath: getString(flags, 'db-path'),
|
|
120
|
+
wikiPath: getString(flags, 'wiki-path'),
|
|
121
|
+
profileDbPath: getString(flags, 'profile-db-path'),
|
|
122
|
+
});
|
|
123
|
+
if (!out) {
|
|
124
|
+
// eslint-disable-next-line no-console
|
|
125
|
+
console.log(JSON.stringify(data, null, 2));
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
// eslint-disable-next-line no-console
|
|
129
|
+
console.log(renderExport(data, out));
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
case 'import': {
|
|
134
|
+
const scope = getRequiredString(flags, 'scope');
|
|
135
|
+
const result = importCommand({
|
|
136
|
+
scope,
|
|
137
|
+
inFile: getRequiredString(flags, 'in'),
|
|
138
|
+
dbPath: getString(flags, 'db-path'),
|
|
139
|
+
wikiPath: getString(flags, 'wiki-path'),
|
|
140
|
+
profileDbPath: getString(flags, 'profile-db-path'),
|
|
141
|
+
});
|
|
142
|
+
// eslint-disable-next-line no-console
|
|
143
|
+
console.log(renderImport(result));
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
case undefined:
|
|
147
|
+
case 'help':
|
|
148
|
+
case '-h':
|
|
149
|
+
case '--help': {
|
|
150
|
+
// eslint-disable-next-line no-console
|
|
151
|
+
console.log(`kg — KG-MCP CLI
|
|
152
|
+
|
|
153
|
+
Usage:
|
|
154
|
+
kg serve --wiki-path <dir> [--db-path <path>] [--profile-path <dir>] [--profile-db-path <path>]
|
|
155
|
+
kg rebuild --wiki-path <dir> [--db-path <path>] [--scope project|personal|both]
|
|
156
|
+
kg status [--db-path <path>] [--wiki-path <dir>] [--profile-db-path <path>]
|
|
157
|
+
kg audit [--tail] [--n <count>] [--scope project|personal] [--db-path <path>]
|
|
158
|
+
kg purge --scope <project|personal> --confirm [--db-path <path>]
|
|
159
|
+
kg export --scope <project|personal> [--out file.json] [--db-path <path>]
|
|
160
|
+
kg import --scope <project|personal> --in file.json [--db-path <path>]`);
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
default:
|
|
164
|
+
throw new Error(`unknown subcommand: ${subcommand}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
main().catch((err) => {
|
|
168
|
+
logger.error({ err }, 'kg cli failed');
|
|
169
|
+
console.error(err instanceof Error ? err.message : err);
|
|
170
|
+
process.exit(1);
|
|
171
|
+
});
|
|
172
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kg purge --scope <s> [--confirm]` — delete a scope's SQLite DB file.
|
|
3
|
+
*
|
|
4
|
+
* This is the nuclear option: wipes the DB entirely. The user can rebuild
|
|
5
|
+
* from markdown afterwards (`kg rebuild`). Requires `--confirm` flag to
|
|
6
|
+
* prevent accidental deletion.
|
|
7
|
+
*/
|
|
8
|
+
export interface PurgeOptions {
|
|
9
|
+
scope: 'project' | 'personal';
|
|
10
|
+
confirm?: boolean;
|
|
11
|
+
dbPath?: string;
|
|
12
|
+
wikiPath?: string;
|
|
13
|
+
profileDbPath?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PurgeResult {
|
|
16
|
+
scope: string;
|
|
17
|
+
dbPath: string;
|
|
18
|
+
deleted: boolean;
|
|
19
|
+
reason?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function purgeCommand(options: PurgeOptions): PurgeResult;
|
|
22
|
+
export declare function renderPurge(result: PurgeResult): string;
|
|
23
|
+
//# sourceMappingURL=purge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purge.d.ts","sourceRoot":"","sources":["../../src/cli/purge.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AAEH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,SAAS,GAAG,UAAU,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,WAAW,CA6B/D;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAKvD"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { existsSync, unlinkSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { dirname, isAbsolute, resolve } from 'node:path';
|
|
4
|
+
export function purgeCommand(options) {
|
|
5
|
+
const dbPath = resolveDbPath(options, options.scope);
|
|
6
|
+
if (!options.confirm) {
|
|
7
|
+
return {
|
|
8
|
+
scope: options.scope,
|
|
9
|
+
dbPath,
|
|
10
|
+
deleted: false,
|
|
11
|
+
reason: 'pass --confirm to actually delete the database',
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
if (!existsSync(dbPath)) {
|
|
15
|
+
return {
|
|
16
|
+
scope: options.scope,
|
|
17
|
+
dbPath,
|
|
18
|
+
deleted: false,
|
|
19
|
+
reason: 'database file does not exist',
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
// Remove the main DB file and WAL/SHM sidecars if present
|
|
23
|
+
unlinkSync(dbPath);
|
|
24
|
+
for (const suffix of ['-wal', '-shm']) {
|
|
25
|
+
const sidecar = dbPath + suffix;
|
|
26
|
+
if (existsSync(sidecar))
|
|
27
|
+
unlinkSync(sidecar);
|
|
28
|
+
}
|
|
29
|
+
return { scope: options.scope, dbPath, deleted: true };
|
|
30
|
+
}
|
|
31
|
+
export function renderPurge(result) {
|
|
32
|
+
if (result.deleted) {
|
|
33
|
+
return `purged ${result.scope} DB: ${result.dbPath}`;
|
|
34
|
+
}
|
|
35
|
+
return `${result.scope} DB NOT deleted: ${result.reason} (${result.dbPath})`;
|
|
36
|
+
}
|
|
37
|
+
// ----------------------------------------------------------------------------
|
|
38
|
+
// Path helpers
|
|
39
|
+
// ----------------------------------------------------------------------------
|
|
40
|
+
function resolveDbPath(options, scope) {
|
|
41
|
+
if (scope === 'personal') {
|
|
42
|
+
if (options.profileDbPath)
|
|
43
|
+
return resolveAbs(options.profileDbPath);
|
|
44
|
+
const env = process.env.KG_PROFILE_PATH;
|
|
45
|
+
const profileDir = env ? resolveAbs(env) : resolve(homedir(), '.pharos/profile');
|
|
46
|
+
return resolve(profileDir, 'kg.db');
|
|
47
|
+
}
|
|
48
|
+
if (options.dbPath)
|
|
49
|
+
return resolveAbs(options.dbPath);
|
|
50
|
+
if (options.wikiPath)
|
|
51
|
+
return resolve(dirname(resolveAbs(options.wikiPath)), 'kg.db');
|
|
52
|
+
return resolve(process.cwd(), '.pharos/kg.db');
|
|
53
|
+
}
|
|
54
|
+
function resolveAbs(p) {
|
|
55
|
+
return isAbsolute(p) ? p : resolve(process.cwd(), p);
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=purge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purge.js","sourceRoot":"","sources":["../../src/cli/purge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyBzD,MAAM,UAAU,YAAY,CAAC,OAAqB;IAChD,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAErD,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,OAAO;YACL,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM;YACN,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,gDAAgD;SACzD,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM;YACN,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,8BAA8B;SACvC,CAAC;IACJ,CAAC;IAED,0DAA0D;IAC1D,UAAU,CAAC,MAAM,CAAC,CAAC;IACnB,KAAK,MAAM,MAAM,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;QAChC,IAAI,UAAU,CAAC,OAAO,CAAC;YAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAmB;IAC7C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,UAAU,MAAM,CAAC,KAAK,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;IACvD,CAAC;IACD,OAAO,GAAG,MAAM,CAAC,KAAK,oBAAoB,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,GAAG,CAAC;AAC/E,CAAC;AAED,+EAA+E;AAC/E,eAAe;AACf,+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,54 @@
|
|
|
1
|
+
import { type Embedder } from '../retrieval/embedder.js';
|
|
2
|
+
/**
|
|
3
|
+
* `kg rebuild` — full-rebuild-from-markdown CLI subcommand for KG-MCP Phase 2.
|
|
4
|
+
*
|
|
5
|
+
* Walks the wiki directory, calls `IngesterService.ingestFile` for every
|
|
6
|
+
* markdown file, prints a summary. Default behavior: ingest both project and
|
|
7
|
+
* personal scope (if `--profile-path` resolves to a directory that exists).
|
|
8
|
+
* Pass `--scope project` or `--scope personal` to narrow.
|
|
9
|
+
*
|
|
10
|
+
* **Why "rebuild" and not "ingest"**: this is the markdown-canonical recovery
|
|
11
|
+
* path (CLAUDE.md §What this is — "If the index is corrupted or lost, rebuild
|
|
12
|
+
* it from the markdown source"). It's the answer to "my SQLite file got
|
|
13
|
+
* deleted / sqlite-vec broke / I changed the embedder model". The chokidar
|
|
14
|
+
* watcher in Pass 3 is the steady-state ingest path.
|
|
15
|
+
*
|
|
16
|
+
* **Performance budget**: <10s for the fixture (PRD acceptance criterion #5).
|
|
17
|
+
* On 100-file repos this should still complete in <2 minutes; the embedder
|
|
18
|
+
* is the bottleneck (~50ms per chunk × ~3 chunks per file = 150ms per file
|
|
19
|
+
* cold; warm chunks via per-chunk SHA skip drop this to ~5ms).
|
|
20
|
+
*/
|
|
21
|
+
export interface RebuildOptions {
|
|
22
|
+
/** Project wiki directory (required) */
|
|
23
|
+
wikiPath: string;
|
|
24
|
+
/** Project DB path (default: `<wikiPath>/../kg.db`) */
|
|
25
|
+
dbPath?: string;
|
|
26
|
+
/** Personal wiki directory (default: `~/.pharos/profile/wiki`) */
|
|
27
|
+
profilePath?: string;
|
|
28
|
+
/** Personal DB path (default: `<profilePath>/../kg.db`) */
|
|
29
|
+
profileDbPath?: string;
|
|
30
|
+
/** Which scopes to rebuild: 'project' | 'personal' | 'both' (default: 'both', falls back to 'project' if profile dir missing) */
|
|
31
|
+
scope?: 'project' | 'personal' | 'both';
|
|
32
|
+
/**
|
|
33
|
+
* Optional embedder injection — used by tests so they can pass a `CountingEmbedder`
|
|
34
|
+
* instead of loading the real model. Default: `TransformersEmbedder` singleton.
|
|
35
|
+
*/
|
|
36
|
+
embedder?: Embedder;
|
|
37
|
+
}
|
|
38
|
+
export interface RebuildSummary {
|
|
39
|
+
scope: 'project' | 'personal';
|
|
40
|
+
files: number;
|
|
41
|
+
nodes: number;
|
|
42
|
+
chunks_added: number;
|
|
43
|
+
chunks_skipped: number;
|
|
44
|
+
embedder_calls: number;
|
|
45
|
+
durationMs: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Run a full-rebuild against one or both scopes. Returns a list of summaries
|
|
49
|
+
* (one per scope actually ingested). Throws on a fatal error per scope but
|
|
50
|
+
* continues to the next scope so a corrupted personal DB doesn't block the
|
|
51
|
+
* project rebuild (or vice versa).
|
|
52
|
+
*/
|
|
53
|
+
export declare function rebuildCommand(options: RebuildOptions): Promise<RebuildSummary[]>;
|
|
54
|
+
//# sourceMappingURL=rebuild.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rebuild.d.ts","sourceRoot":"","sources":["../../src/cli/rebuild.ts"],"names":[],"mappings":"AAQA,OAAO,EAAwB,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAE/E;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iIAAiI;IACjI,KAAK,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;IACxC;;;OAGG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,GAAG,UAAU,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CA4CvF"}
|
|
@@ -0,0 +1,113 @@
|
|
|
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
|
+
import { IngesterService } from '../ingest/ingester.js';
|
|
6
|
+
import { listMarkdownFiles } from '../ingest/manifest.js';
|
|
7
|
+
import { logger } from '../observability/logger.js';
|
|
8
|
+
import { TransformersEmbedder } from '../retrieval/embedder.js';
|
|
9
|
+
/**
|
|
10
|
+
* Run a full-rebuild against one or both scopes. Returns a list of summaries
|
|
11
|
+
* (one per scope actually ingested). Throws on a fatal error per scope but
|
|
12
|
+
* continues to the next scope so a corrupted personal DB doesn't block the
|
|
13
|
+
* project rebuild (or vice versa).
|
|
14
|
+
*/
|
|
15
|
+
export async function rebuildCommand(options) {
|
|
16
|
+
const summaries = [];
|
|
17
|
+
const projectWiki = resolveAbs(options.wikiPath);
|
|
18
|
+
if (!existsSync(projectWiki)) {
|
|
19
|
+
throw new Error(`wiki path does not exist: ${projectWiki}`);
|
|
20
|
+
}
|
|
21
|
+
const projectDbPath = resolveAbs(options.dbPath ?? defaultDbPathFor(projectWiki));
|
|
22
|
+
const profileWiki = resolveAbs(options.profilePath ?? defaultProfileWikiPath());
|
|
23
|
+
const profileDbPath = resolveAbs(options.profileDbPath ?? defaultDbPathFor(profileWiki));
|
|
24
|
+
const scope = options.scope ?? 'both';
|
|
25
|
+
const includeProject = scope === 'project' || scope === 'both';
|
|
26
|
+
const includePersonal = (scope === 'personal' || scope === 'both') && existsSync(profileWiki);
|
|
27
|
+
// Lazily construct the shared embedder once for both scopes.
|
|
28
|
+
const embedder = options.embedder ?? new TransformersEmbedder();
|
|
29
|
+
await embedder.warmup();
|
|
30
|
+
if (includeProject) {
|
|
31
|
+
const summary = await rebuildOneScope({
|
|
32
|
+
scope: 'project',
|
|
33
|
+
wikiDir: projectWiki,
|
|
34
|
+
dbPath: projectDbPath,
|
|
35
|
+
embedder,
|
|
36
|
+
});
|
|
37
|
+
summaries.push(summary);
|
|
38
|
+
}
|
|
39
|
+
if (includePersonal) {
|
|
40
|
+
const summary = await rebuildOneScope({
|
|
41
|
+
scope: 'personal',
|
|
42
|
+
wikiDir: profileWiki,
|
|
43
|
+
dbPath: profileDbPath,
|
|
44
|
+
embedder,
|
|
45
|
+
});
|
|
46
|
+
summaries.push(summary);
|
|
47
|
+
}
|
|
48
|
+
return summaries;
|
|
49
|
+
}
|
|
50
|
+
async function rebuildOneScope(args) {
|
|
51
|
+
const { scope, wikiDir, dbPath, embedder } = args;
|
|
52
|
+
const t0 = Date.now();
|
|
53
|
+
const bundle = openDb(dbPath);
|
|
54
|
+
try {
|
|
55
|
+
const ingester = new IngesterService(bundle, embedder, scope, wikiDir);
|
|
56
|
+
const files = listMarkdownFiles(wikiDir);
|
|
57
|
+
let nodes = 0;
|
|
58
|
+
let chunksAdded = 0;
|
|
59
|
+
let chunksSkipped = 0;
|
|
60
|
+
let embedderCalls = 0;
|
|
61
|
+
for (const file of files) {
|
|
62
|
+
try {
|
|
63
|
+
const result = await ingester.ingestFile(file);
|
|
64
|
+
nodes += result.nodes_written;
|
|
65
|
+
chunksAdded += result.chunks_added;
|
|
66
|
+
chunksSkipped += result.chunks_skipped;
|
|
67
|
+
embedderCalls += result.embedder_calls;
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
logger.error({ err, file, scope }, 'rebuild: failed to ingest file');
|
|
71
|
+
// Continue with the next file rather than aborting the entire rebuild —
|
|
72
|
+
// partial progress is better than total failure here.
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
scope,
|
|
77
|
+
files: files.length,
|
|
78
|
+
nodes,
|
|
79
|
+
chunks_added: chunksAdded,
|
|
80
|
+
chunks_skipped: chunksSkipped,
|
|
81
|
+
embedder_calls: embedderCalls,
|
|
82
|
+
durationMs: Date.now() - t0,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
closeDb(bundle);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// ----------------------------------------------------------------------------
|
|
90
|
+
// Path defaults
|
|
91
|
+
// ----------------------------------------------------------------------------
|
|
92
|
+
function resolveAbs(p) {
|
|
93
|
+
return isAbsolute(p) ? p : resolve(process.cwd(), p);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Default DB path for a given wiki directory: `<wikiDir>/../kg.db`. Lives
|
|
97
|
+
* next to the wiki dir, inside the same `.pharos/` folder. Locked decision
|
|
98
|
+
* for Phase 2 (per AskUserQuestion 2026-04-08).
|
|
99
|
+
*/
|
|
100
|
+
function defaultDbPathFor(wikiDir) {
|
|
101
|
+
return resolve(dirname(wikiDir), 'kg.db');
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Default personal wiki path. Honors `KG_PROFILE_PATH` env var, else
|
|
105
|
+
* `~/.pharos/profile/wiki`.
|
|
106
|
+
*/
|
|
107
|
+
function defaultProfileWikiPath() {
|
|
108
|
+
const env = process.env.KG_PROFILE_PATH;
|
|
109
|
+
if (env)
|
|
110
|
+
return resolve(env, 'wiki');
|
|
111
|
+
return resolve(homedir(), '.pharos/profile/wiki');
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=rebuild.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rebuild.js","sourceRoot":"","sources":["../../src/cli/rebuild.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
/**
|
|
4
|
+
* `kg serve` — stdio MCP server for KG-MCP Phase 2.
|
|
5
|
+
*
|
|
6
|
+
* Replaces Phase 1's `src/spike.ts` with the production wiring:
|
|
7
|
+
* 1. Open project + (optional) personal SQLite DBs (one writer + 2 readers each)
|
|
8
|
+
* 2. Warm the embedder singleton
|
|
9
|
+
* 3. Run startup consistency check against the manifest → re-ingest stale files
|
|
10
|
+
* 4. Start chokidar watchers for both scopes (with 2s debounce, drop-oldest)
|
|
11
|
+
* 5. Build the McpServer + register `kg_search` and `kg_execute`
|
|
12
|
+
* 6. Connect to StdioServerTransport and listen
|
|
13
|
+
*
|
|
14
|
+
* Graceful shutdown on SIGTERM/SIGINT closes the watchers, drains in-flight
|
|
15
|
+
* ingests, closes the DBs, and exits within 2 seconds.
|
|
16
|
+
*
|
|
17
|
+
* Per CLAUDE.md §Security #1: only the project repository binding is exposed
|
|
18
|
+
* to the tool handlers in Phase 2. Personal-scope tool reads stay gated
|
|
19
|
+
* behind the existing Phase 5 check in the tool handlers — even though the
|
|
20
|
+
* personal-scope DB is fully populated by the watcher, the LLM can't read
|
|
21
|
+
* from it until the 15-test privacy adversarial suite lands in Phase 5.
|
|
22
|
+
*/
|
|
23
|
+
export interface ServeOptions {
|
|
24
|
+
/** Project wiki directory (required) */
|
|
25
|
+
wikiPath: string;
|
|
26
|
+
/** Project DB path (default: `<wikiPath>/../kg.db`) */
|
|
27
|
+
dbPath?: string;
|
|
28
|
+
/** Personal wiki directory (default: `~/.pharos/profile/wiki` if it exists, else skip personal) */
|
|
29
|
+
profilePath?: string;
|
|
30
|
+
/** Personal DB path (default: `<profilePath>/../kg.db`) */
|
|
31
|
+
profileDbPath?: string;
|
|
32
|
+
}
|
|
33
|
+
interface ServerHandle {
|
|
34
|
+
server: McpServer;
|
|
35
|
+
shutdown: (signal: string) => Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Build (but don't start) the stdio server. Exposed as a function so future
|
|
39
|
+
* tests / in-process integrations can construct a server without going
|
|
40
|
+
* through the CLI argv path.
|
|
41
|
+
*/
|
|
42
|
+
export declare function buildServer(options: ServeOptions): Promise<ServerHandle>;
|
|
43
|
+
/**
|
|
44
|
+
* The CLI entry point: build the server, connect stdio, install signal
|
|
45
|
+
* handlers, listen forever.
|
|
46
|
+
*/
|
|
47
|
+
export declare function serveCommand(options: ServeOptions): Promise<void>;
|
|
48
|
+
export {};
|
|
49
|
+
//# sourceMappingURL=serve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/cli/serve.ts"],"names":[],"mappings":";AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiBpE;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mGAAmG;IACnG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,YAAY;IACpB,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CA6J9E;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBvE"}
|