@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/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(bundle, {
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(bundle, session_id);
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(bundle, { query, limit: limit ?? 50, raw, engine: searchEngine });
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(bundle, session_id);
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 = bundle.db.prepare(sql).all(...params);
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 = bundle.db.prepare(sql).all(like, like);
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 = bundle.db.prepare(`SELECT text_object_id, object_id, mime_type FROM artifacts WHERE artifact_id = ?`).get(artifact_id);
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(bundle, objectId);
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(bundle);
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 openBundle(storePath);
6848
+ const bundle = await openOrInitBundle(storePath);
6820
6849
  try {
6821
6850
  const transport = parseMcpTransport(options.transport);
6822
6851
  const searchEngine = parseSearchEngine(options.searchEngine);