dsh-plugin-sessiongraph-tool 0.1.9 → 0.1.11

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.
Files changed (2) hide show
  1. package/lib/index.js +34 -3
  2. package/package.json +3 -3
package/lib/index.js CHANGED
@@ -287,13 +287,44 @@ async function runQuery(ctx, refresher, indexRoot, config, args, exec) {
287
287
  const request = buildRequest(args, indexRoot, config.maxLimit);
288
288
  const refresh = await refresher.ensureFresh(exec.signal);
289
289
  try {
290
- const result = await ctx.sessiongraph.query(request, exec.signal);
291
- return projectResult(result, refresh.stale);
290
+ return projectResult(await ctx.sessiongraph.query(request, exec.signal), refresh.stale);
292
291
  }
293
292
  catch (error) {
294
- throw explainQueryFailure(error, indexRoot);
293
+ // A damaged index is recoverable without asking anyone: the source logs still exist, only the
294
+ // derived database is unusable. Rebuilding once and retrying is strictly better than surfacing
295
+ // `database disk image is malformed` to the model, and it is exactly what a person would do by
296
+ // hand. Every other failure keeps its existing explanation.
297
+ if (!isCorruptIndexError(error))
298
+ throw explainQueryFailure(error, indexRoot);
299
+ try {
300
+ console.error(`sessiongraph: index at "${indexRoot}" is unreadable (${describeError(error)}); rebuilding it`);
301
+ await ctx.sessiongraph.index(indexRoot, { force: true });
302
+ return projectResult(await ctx.sessiongraph.query(request, exec.signal), refresh.stale);
303
+ }
304
+ catch (rebuildError) {
305
+ console.error(`sessiongraph: rebuilding the index failed: ${describeError(rebuildError)}`);
306
+ throw explainQueryFailure(error, indexRoot);
307
+ }
295
308
  }
296
309
  }
310
+ /**
311
+ * Whether a failure means the index file itself is unusable.
312
+ * @param error - the error a query raised.
313
+ * @returns true for the seam's corruption code and for SQLite's own corruption messages.
314
+ */
315
+ function isCorruptIndexError(error) {
316
+ if (error instanceof SessiongraphError)
317
+ return error.code === 'SESSIONGRAPH_CORRUPT';
318
+ return /malformed|not a database|file is encrypted/i.test(describeError(error));
319
+ }
320
+ /**
321
+ * One-line description of a thrown value.
322
+ * @param error - whatever was caught.
323
+ * @returns its message, or a stringified form for non-errors.
324
+ */
325
+ function describeError(error) {
326
+ return error instanceof Error ? error.message : String(error);
327
+ }
297
328
  /**
298
329
  * The `status` answer, including the one case the seam may not answer: when no store claims the root
299
330
  * because no index file exists, "there is no index" is still an honest status, so the tool reports it
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-sessiongraph-tool",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "Model-facing sessiongraph tools for DeepSeek Harness — a read-only sessiongraph tool that searches the whole local conversation history, plus a sessiongraph_index tool that builds or refreshes the index on its own, much larger timeout budget",
5
5
  "keywords": [
6
6
  "dsh",
@@ -50,8 +50,8 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@deepseek-ai/schemastery": "^3.18.1",
53
- "dsh-plugin-sessiongraph-service": "^0.1.9",
54
- "dsh-plugin-sessiongraph-sessions": "^0.1.9"
53
+ "dsh-plugin-sessiongraph-service": "^0.1.11",
54
+ "dsh-plugin-sessiongraph-sessions": "^0.1.11"
55
55
  },
56
56
  "peerDependencies": {
57
57
  "@deepseek-ai/cordis": ">=4.0.1",