@c3-oss/prosa 0.3.1 → 0.3.2
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/dist/bin/prosa.js +59 -30
- package/dist/bin/prosa.js.map +1 -1
- package/dist/cli/main.js +59 -30
- package/dist/cli/main.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/main.js
CHANGED
|
@@ -1642,6 +1642,18 @@ async function openBundle(rootPath) {
|
|
|
1642
1642
|
}
|
|
1643
1643
|
return { path: resolved, db, manifest, paths };
|
|
1644
1644
|
}
|
|
1645
|
+
async function openOrInitBundle(rootPath) {
|
|
1646
|
+
const resolved = path.resolve(rootPath);
|
|
1647
|
+
const paths = bundlePaths(resolved);
|
|
1648
|
+
const dirStat = await stat(resolved).catch(() => null);
|
|
1649
|
+
if (dirStat && !dirStat.isDirectory()) {
|
|
1650
|
+
throw new Error(`bundle path not found or not a directory: ${resolved}`);
|
|
1651
|
+
}
|
|
1652
|
+
if (!dirStat || !await exists(paths.manifest)) {
|
|
1653
|
+
return await initBundle(resolved);
|
|
1654
|
+
}
|
|
1655
|
+
return await openBundle(resolved);
|
|
1656
|
+
}
|
|
1645
1657
|
function closeBundle(bundle) {
|
|
1646
1658
|
closeDb(bundle.db);
|
|
1647
1659
|
}
|
|
@@ -6280,6 +6292,7 @@ init_sessions();
|
|
|
6280
6292
|
function registerProsaTools(server, bundle, options = {}) {
|
|
6281
6293
|
const searchEngine = options.searchEngine ?? "fts5";
|
|
6282
6294
|
const storePath = options.storePath ?? bundle.path;
|
|
6295
|
+
const ensureStore = options.ensureStore ?? false;
|
|
6283
6296
|
registerProsaPrompts(server);
|
|
6284
6297
|
server.registerTool(
|
|
6285
6298
|
"compile",
|
|
@@ -6292,7 +6305,7 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6292
6305
|
},
|
|
6293
6306
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true }
|
|
6294
6307
|
},
|
|
6295
|
-
async ({ source, sessions_path }) => {
|
|
6308
|
+
async ({ source, sessions_path }) => withToolBundle(bundle, storePath, ensureStore, async (activeBundle) => {
|
|
6296
6309
|
if (sessions_path && !source) {
|
|
6297
6310
|
return {
|
|
6298
6311
|
content: [
|
|
@@ -6306,7 +6319,7 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6306
6319
|
}
|
|
6307
6320
|
try {
|
|
6308
6321
|
const result = await runCompileImports({
|
|
6309
|
-
bundle,
|
|
6322
|
+
bundle: activeBundle,
|
|
6310
6323
|
providers: source ? [getCompileProvider(source)] : COMPILE_PROVIDERS,
|
|
6311
6324
|
deferIndex: false,
|
|
6312
6325
|
sessionsPath: sessions_path
|
|
@@ -6347,7 +6360,7 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6347
6360
|
isError: true
|
|
6348
6361
|
};
|
|
6349
6362
|
}
|
|
6350
|
-
}
|
|
6363
|
+
})
|
|
6351
6364
|
);
|
|
6352
6365
|
server.registerTool(
|
|
6353
6366
|
"list_sessions",
|
|
@@ -6362,8 +6375,8 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6362
6375
|
},
|
|
6363
6376
|
annotations: { readOnlyHint: true, idempotentHint: true }
|
|
6364
6377
|
},
|
|
6365
|
-
async (input) => {
|
|
6366
|
-
const rows = listSessions(
|
|
6378
|
+
async (input) => withToolBundle(bundle, storePath, ensureStore, (activeBundle) => {
|
|
6379
|
+
const rows = listSessions(activeBundle, {
|
|
6367
6380
|
sourceTool: input.source,
|
|
6368
6381
|
sinceIso: input.since,
|
|
6369
6382
|
untilIso: input.until,
|
|
@@ -6372,7 +6385,7 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6372
6385
|
return {
|
|
6373
6386
|
content: [{ type: "text", text: JSON.stringify(rows, null, 2) }]
|
|
6374
6387
|
};
|
|
6375
|
-
}
|
|
6388
|
+
})
|
|
6376
6389
|
);
|
|
6377
6390
|
server.registerTool(
|
|
6378
6391
|
"get_session",
|
|
@@ -6384,8 +6397,8 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6384
6397
|
},
|
|
6385
6398
|
annotations: { readOnlyHint: true, idempotentHint: true }
|
|
6386
6399
|
},
|
|
6387
|
-
async ({ session_id }) => {
|
|
6388
|
-
const detail = getSession(
|
|
6400
|
+
async ({ session_id }) => withToolBundle(bundle, storePath, ensureStore, (activeBundle) => {
|
|
6401
|
+
const detail = getSession(activeBundle, session_id);
|
|
6389
6402
|
if (!detail) {
|
|
6390
6403
|
return {
|
|
6391
6404
|
content: [{ type: "text", text: `session not found: ${session_id}` }],
|
|
@@ -6395,7 +6408,7 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6395
6408
|
return {
|
|
6396
6409
|
content: [{ type: "text", text: JSON.stringify(detail, null, 2) }]
|
|
6397
6410
|
};
|
|
6398
|
-
}
|
|
6411
|
+
})
|
|
6399
6412
|
);
|
|
6400
6413
|
server.registerTool(
|
|
6401
6414
|
"search_sessions",
|
|
@@ -6409,8 +6422,13 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6409
6422
|
},
|
|
6410
6423
|
annotations: { readOnlyHint: true, idempotentHint: true }
|
|
6411
6424
|
},
|
|
6412
|
-
async ({ query, limit, raw }) => {
|
|
6413
|
-
const hits = searchFullText(
|
|
6425
|
+
async ({ query, limit, raw }) => withToolBundle(bundle, storePath, ensureStore, (activeBundle) => {
|
|
6426
|
+
const hits = searchFullText(activeBundle, {
|
|
6427
|
+
query,
|
|
6428
|
+
limit: limit ?? 50,
|
|
6429
|
+
raw,
|
|
6430
|
+
engine: searchEngine
|
|
6431
|
+
});
|
|
6414
6432
|
return {
|
|
6415
6433
|
content: [
|
|
6416
6434
|
{
|
|
@@ -6423,7 +6441,7 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6423
6441
|
}
|
|
6424
6442
|
]
|
|
6425
6443
|
};
|
|
6426
|
-
}
|
|
6444
|
+
})
|
|
6427
6445
|
);
|
|
6428
6446
|
server.registerTool(
|
|
6429
6447
|
"export_session_markdown",
|
|
@@ -6435,9 +6453,9 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6435
6453
|
},
|
|
6436
6454
|
annotations: { readOnlyHint: true, idempotentHint: true }
|
|
6437
6455
|
},
|
|
6438
|
-
async ({ session_id }) => {
|
|
6456
|
+
async ({ session_id }) => withToolBundle(bundle, storePath, ensureStore, async (activeBundle) => {
|
|
6439
6457
|
try {
|
|
6440
|
-
const md = await exportSessionMarkdown(
|
|
6458
|
+
const md = await exportSessionMarkdown(activeBundle, session_id);
|
|
6441
6459
|
return { content: [{ type: "text", text: md }] };
|
|
6442
6460
|
} catch (error) {
|
|
6443
6461
|
return {
|
|
@@ -6445,7 +6463,7 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6445
6463
|
isError: true
|
|
6446
6464
|
};
|
|
6447
6465
|
}
|
|
6448
|
-
}
|
|
6466
|
+
})
|
|
6449
6467
|
);
|
|
6450
6468
|
server.registerTool(
|
|
6451
6469
|
"list_tool_calls",
|
|
@@ -6472,7 +6490,7 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6472
6490
|
},
|
|
6473
6491
|
annotations: { readOnlyHint: true, idempotentHint: true }
|
|
6474
6492
|
},
|
|
6475
|
-
async ({ tool_name, canonical_type, session_id, errors_only, limit }) => {
|
|
6493
|
+
async ({ tool_name, canonical_type, session_id, errors_only, limit }) => withToolBundle(bundle, storePath, ensureStore, (activeBundle) => {
|
|
6476
6494
|
const conds = [];
|
|
6477
6495
|
const params = [];
|
|
6478
6496
|
if (tool_name) {
|
|
@@ -6502,11 +6520,11 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6502
6520
|
ORDER BY tc.timestamp_start DESC
|
|
6503
6521
|
LIMIT ${clampLimit(limit, { max: 500, fallback: 100 })}
|
|
6504
6522
|
`;
|
|
6505
|
-
const rows =
|
|
6523
|
+
const rows = activeBundle.db.prepare(sql).all(...params);
|
|
6506
6524
|
return {
|
|
6507
6525
|
content: [{ type: "text", text: JSON.stringify(rows, null, 2) }]
|
|
6508
6526
|
};
|
|
6509
|
-
}
|
|
6527
|
+
})
|
|
6510
6528
|
);
|
|
6511
6529
|
server.registerTool(
|
|
6512
6530
|
"find_touched_files",
|
|
@@ -6519,7 +6537,7 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6519
6537
|
},
|
|
6520
6538
|
annotations: { readOnlyHint: true, idempotentHint: true }
|
|
6521
6539
|
},
|
|
6522
|
-
async ({ path_substring, limit }) => {
|
|
6540
|
+
async ({ path_substring, limit }) => withToolBundle(bundle, storePath, ensureStore, (activeBundle) => {
|
|
6523
6541
|
const sql = `
|
|
6524
6542
|
SELECT tc.session_id, tc.tool_name, tc.canonical_tool_type, tc.path,
|
|
6525
6543
|
tc.timestamp_start, tc.command
|
|
@@ -6534,11 +6552,11 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6534
6552
|
LIMIT ${clampLimit(limit, { max: 500, fallback: 100 })}
|
|
6535
6553
|
`;
|
|
6536
6554
|
const like = `%${path_substring}%`;
|
|
6537
|
-
const rows =
|
|
6555
|
+
const rows = activeBundle.db.prepare(sql).all(like, like);
|
|
6538
6556
|
return {
|
|
6539
6557
|
content: [{ type: "text", text: JSON.stringify(rows, null, 2) }]
|
|
6540
6558
|
};
|
|
6541
|
-
}
|
|
6559
|
+
})
|
|
6542
6560
|
);
|
|
6543
6561
|
server.registerTool(
|
|
6544
6562
|
"get_artifact",
|
|
@@ -6550,8 +6568,8 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6550
6568
|
},
|
|
6551
6569
|
annotations: { readOnlyHint: true, idempotentHint: true }
|
|
6552
6570
|
},
|
|
6553
|
-
async ({ artifact_id }) => {
|
|
6554
|
-
const row =
|
|
6571
|
+
async ({ artifact_id }) => withToolBundle(bundle, storePath, ensureStore, async (activeBundle) => {
|
|
6572
|
+
const row = activeBundle.db.prepare(`SELECT text_object_id, object_id, mime_type FROM artifacts WHERE artifact_id = ?`).get(artifact_id);
|
|
6555
6573
|
if (!row) {
|
|
6556
6574
|
return {
|
|
6557
6575
|
content: [{ type: "text", text: `artifact not found: ${artifact_id}` }],
|
|
@@ -6564,12 +6582,12 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6564
6582
|
}
|
|
6565
6583
|
try {
|
|
6566
6584
|
const { getText: getText2 } = await Promise.resolve().then(() => (init_cas(), cas_exports));
|
|
6567
|
-
const text = await getText2(
|
|
6585
|
+
const text = await getText2(activeBundle, objectId);
|
|
6568
6586
|
return { content: [{ type: "text", text }] };
|
|
6569
6587
|
} catch {
|
|
6570
6588
|
return { content: [{ type: "text", text: `[binary artifact: ${objectId}]` }] };
|
|
6571
6589
|
}
|
|
6572
|
-
}
|
|
6590
|
+
})
|
|
6573
6591
|
);
|
|
6574
6592
|
server.registerTool(
|
|
6575
6593
|
"index_status",
|
|
@@ -6579,14 +6597,25 @@ function registerProsaTools(server, bundle, options = {}) {
|
|
|
6579
6597
|
inputSchema: {},
|
|
6580
6598
|
annotations: { readOnlyHint: true, idempotentHint: true }
|
|
6581
6599
|
},
|
|
6582
|
-
async () => {
|
|
6583
|
-
const rows = getSearchIndexStatuses(
|
|
6600
|
+
async () => withToolBundle(bundle, storePath, ensureStore, (activeBundle) => {
|
|
6601
|
+
const rows = getSearchIndexStatuses(activeBundle);
|
|
6584
6602
|
return {
|
|
6585
6603
|
content: [{ type: "text", text: JSON.stringify(rows, null, 2) }]
|
|
6586
6604
|
};
|
|
6587
|
-
}
|
|
6605
|
+
})
|
|
6588
6606
|
);
|
|
6589
6607
|
}
|
|
6608
|
+
async function withToolBundle(fallbackBundle, storePath, ensureStore, fn) {
|
|
6609
|
+
if (!ensureStore) {
|
|
6610
|
+
return await fn(fallbackBundle);
|
|
6611
|
+
}
|
|
6612
|
+
const bundle = await openOrInitBundle(storePath);
|
|
6613
|
+
try {
|
|
6614
|
+
return await fn(bundle);
|
|
6615
|
+
} finally {
|
|
6616
|
+
closeBundle(bundle);
|
|
6617
|
+
}
|
|
6618
|
+
}
|
|
6590
6619
|
function registerProsaPrompts(server) {
|
|
6591
6620
|
server.registerPrompt(
|
|
6592
6621
|
"investigate_prior_work",
|
|
@@ -6759,7 +6788,7 @@ function createMcpServer(bundle, searchEngine, storePath) {
|
|
|
6759
6788
|
},
|
|
6760
6789
|
{ instructions: PROSA_MCP_INSTRUCTIONS }
|
|
6761
6790
|
);
|
|
6762
|
-
registerProsaTools(server, bundle, { searchEngine, storePath });
|
|
6791
|
+
registerProsaTools(server, bundle, { ensureStore: true, searchEngine, storePath });
|
|
6763
6792
|
return server;
|
|
6764
6793
|
}
|
|
6765
6794
|
async function readBody(req) {
|
|
@@ -6816,7 +6845,7 @@ function mcpCommand() {
|
|
|
6816
6845
|
const serve = new Command5("serve").description("Start a local MCP server over the prosa bundle.").option("--store <path>", "bundle directory", defaultBundlePath()).option("--transport <transport>", "MCP transport: stdio|http", "stdio").option("--host <host>", "bind host", "127.0.0.1").option("--port <port>", "bind port", "7331").option("--path <path>", "HTTP path", "/mcp").option("--search-engine <engine>", "search engine: fts5|tantivy", "fts5").action(
|
|
6817
6846
|
async (options) => {
|
|
6818
6847
|
const storePath = path18.resolve(options.store);
|
|
6819
|
-
const bundle = await
|
|
6848
|
+
const bundle = await openOrInitBundle(storePath);
|
|
6820
6849
|
try {
|
|
6821
6850
|
const transport = parseMcpTransport(options.transport);
|
|
6822
6851
|
const searchEngine = parseSearchEngine(options.searchEngine);
|