botholomew 0.8.0 → 0.8.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "botholomew",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "Local, autonomous AI agent for knowledge work — works your task queue while you sleep.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/db/context.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { resolve as resolvePath } from "node:path";
1
2
  import type { DbConnection } from "./connection.ts";
2
3
  import { buildSetClauses, buildWhereClause, sanitizeInt } from "./query.ts";
3
4
  import { isUuid, uuidv7 } from "./uuid.ts";
@@ -193,15 +194,26 @@ export async function getContextItemBySourcePath(
193
194
  }
194
195
 
195
196
  /**
196
- * Look up a context item by UUID (if the value looks like one) or by context_path.
197
+ * Look up a context item by UUID, `context_path`, or `source_path`.
198
+ *
199
+ * `source_path` fallbacks let users pass the same argument they used for
200
+ * `context add` (e.g. a bare `README.md`) to management commands like
201
+ * `context refresh` / `context chunks`. Relative file paths are resolved
202
+ * against `process.cwd()` to match the absolute `source_path` stored on add.
197
203
  */
198
204
  export async function resolveContextItem(
199
205
  db: DbConnection,
200
206
  pathOrId: string,
201
207
  ): Promise<ContextItem | null> {
202
- return isUuid(pathOrId)
203
- ? getContextItem(db, pathOrId)
204
- : getContextItemByPath(db, pathOrId);
208
+ if (isUuid(pathOrId)) return getContextItem(db, pathOrId);
209
+
210
+ const byContextPath = await getContextItemByPath(db, pathOrId);
211
+ if (byContextPath) return byContextPath;
212
+
213
+ const byUrl = await getContextItemBySourcePath(db, pathOrId, "url");
214
+ if (byUrl) return byUrl;
215
+
216
+ return getContextItemBySourcePath(db, resolvePath(pathOrId), "file");
205
217
  }
206
218
 
207
219
  /**
package/src/db/schema.ts CHANGED
@@ -45,6 +45,7 @@ export async function migrate(db: DbConnection): Promise<void> {
45
45
  const applied = new Set(rows.map((row) => row.id));
46
46
 
47
47
  // Run pending migrations in order
48
+ let appliedAny = false;
48
49
  for (const migration of loadMigrations()) {
49
50
  if (applied.has(migration.id)) continue;
50
51
 
@@ -63,5 +64,15 @@ export async function migrate(db: DbConnection): Promise<void> {
63
64
  migration.id,
64
65
  migration.name,
65
66
  );
67
+ appliedAny = true;
68
+ }
69
+
70
+ // Flush the WAL so the next open has no schema entries to replay. DuckDB's
71
+ // WAL replay of ALTER TABLE re-binds all column defaults on the target
72
+ // table, and our CREATE TABLE defaults use `current_timestamp::VARCHAR` —
73
+ // which cannot be resolved during replay (no default database attached yet),
74
+ // crashing the process on reopen.
75
+ if (appliedAny) {
76
+ await db.exec("CHECKPOINT");
66
77
  }
67
78
  }