@pennixrv/trellis-core 0.6.45 → 0.7.0-beta.5

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 (43) hide show
  1. package/dist/mem/adapters/devin.d.ts +50 -0
  2. package/dist/mem/adapters/devin.d.ts.map +1 -0
  3. package/dist/mem/adapters/devin.js +383 -0
  4. package/dist/mem/adapters/devin.js.map +1 -0
  5. package/dist/mem/adapters/opencode.d.ts.map +1 -1
  6. package/dist/mem/adapters/opencode.js +35 -139
  7. package/dist/mem/adapters/opencode.js.map +1 -1
  8. package/dist/mem/adapters/zcode.d.ts.map +1 -1
  9. package/dist/mem/adapters/zcode.js +54 -140
  10. package/dist/mem/adapters/zcode.js.map +1 -1
  11. package/dist/mem/index.d.ts +1 -0
  12. package/dist/mem/index.d.ts.map +1 -1
  13. package/dist/mem/index.js +1 -0
  14. package/dist/mem/index.js.map +1 -1
  15. package/dist/mem/internal/paths.d.ts +22 -0
  16. package/dist/mem/internal/paths.d.ts.map +1 -1
  17. package/dist/mem/internal/paths.js +45 -0
  18. package/dist/mem/internal/paths.js.map +1 -1
  19. package/dist/mem/internal/sqlite-adapter.d.ts +46 -0
  20. package/dist/mem/internal/sqlite-adapter.d.ts.map +1 -0
  21. package/dist/mem/internal/sqlite-adapter.js +116 -0
  22. package/dist/mem/internal/sqlite-adapter.js.map +1 -0
  23. package/dist/mem/internal/sqlite-readonly.d.ts +3 -0
  24. package/dist/mem/internal/sqlite-readonly.d.ts.map +1 -1
  25. package/dist/mem/internal/sqlite-readonly.js +159 -60
  26. package/dist/mem/internal/sqlite-readonly.js.map +1 -1
  27. package/dist/mem/platforms.d.ts +20 -0
  28. package/dist/mem/platforms.d.ts.map +1 -0
  29. package/dist/mem/platforms.js +72 -0
  30. package/dist/mem/platforms.js.map +1 -0
  31. package/dist/mem/projects.d.ts +1 -1
  32. package/dist/mem/projects.d.ts.map +1 -1
  33. package/dist/mem/projects.js +5 -8
  34. package/dist/mem/projects.js.map +1 -1
  35. package/dist/mem/sessions.d.ts +3 -3
  36. package/dist/mem/sessions.d.ts.map +1 -1
  37. package/dist/mem/sessions.js +39 -77
  38. package/dist/mem/sessions.js.map +1 -1
  39. package/dist/mem/types.d.ts +2 -1
  40. package/dist/mem/types.d.ts.map +1 -1
  41. package/dist/mem/types.js +9 -1
  42. package/dist/mem/types.js.map +1 -1
  43. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/mem/internal/paths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,eAAO,MAAM,IAAI,QAAe,CAAC;AACjC,eAAO,MAAM,eAAe,QAAyC,CAAC;AACtE,eAAO,MAAM,cAAc,QAAwC,CAAC;AACpE;2CAC2C;AAC3C,eAAO,MAAM,QAAQ,QAAsD,CAAC;AAC5E;;4DAE4D;AAC5D,eAAO,MAAM,aAAa,QAAuC,CAAC;AAElE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAIxC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CA8BnD;AASD,eAAO,MAAM,YAAY,QAExB,CAAC;AACF,eAAO,MAAM,WAAW,QAGvB,CAAC;AAiBF;;;+EAG+E;AAC/E,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;8CAC8C;AAC9C,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;wEACwE;AACxE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMzE;AAED,0EAA0E;AAC1E,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAsBrD;AAED;4EAC4E;AAC5E,wBAAiB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAkBxD"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/mem/internal/paths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,eAAO,MAAM,IAAI,QAAe,CAAC;AACjC,eAAO,MAAM,eAAe,QAAyC,CAAC;AACtE,eAAO,MAAM,cAAc,QAAwC,CAAC;AACpE;2CAC2C;AAC3C,eAAO,MAAM,QAAQ,QAAsD,CAAC;AAC5E;;4DAE4D;AAC5D,eAAO,MAAM,aAAa,QAAuC,CAAC;AAElE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAIxC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAYxC;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CAUnD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CA8BnD;AASD,eAAO,MAAM,YAAY,QAExB,CAAC;AACF,eAAO,MAAM,WAAW,QAGvB,CAAC;AAiBF;;;+EAG+E;AAC/E,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;8CAC8C;AAC9C,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;wEACwE;AACxE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMzE;AAED,0EAA0E;AAC1E,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAsBrD;AAED;4EAC4E;AAC5E,wBAAiB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAkBxD"}
@@ -38,6 +38,51 @@ export function opencodeDataDir() {
38
38
  return path.join(xdg, "opencode");
39
39
  return path.join(HOME, ".local", "share", "opencode");
40
40
  }
41
+ /**
42
+ * Cognition Devin CLI data root (terminal agent, not Devin Desktop / Cascade
43
+ * and not Factory Droid):
44
+ * - Unix: `$XDG_DATA_HOME/devin/cli`, else `~/.local/share/devin/cli`
45
+ * - Windows: `%APPDATA%\devin\cli` (official logs path; falls back to
46
+ * `~/AppData/Roaming` when `APPDATA` is unset)
47
+ *
48
+ * Read per call so tests (and a caller that sets `XDG_DATA_HOME` / `APPDATA`)
49
+ * see their own value. `os.platform()` is also read per call, matching
50
+ * `HOME` reflecting a mocked `os.homedir()`.
51
+ */
52
+ export function devinCliDataDir() {
53
+ if (os.platform() === "win32") {
54
+ const appData = process.env.APPDATA?.trim();
55
+ const base = appData && appData.length > 0
56
+ ? appData
57
+ : path.join(HOME, "AppData", "Roaming");
58
+ return path.join(base, "devin", "cli");
59
+ }
60
+ const xdg = process.env.XDG_DATA_HOME?.trim();
61
+ if (xdg)
62
+ return path.join(xdg, "devin", "cli");
63
+ return path.join(HOME, ".local", "share", "devin", "cli");
64
+ }
65
+ /**
66
+ * Resolve the Devin CLI session database (`sessions.db`), or `undefined`
67
+ * when `DEVIN_DB_PATH=:memory:` (no file to read).
68
+ *
69
+ * 1. `DEVIN_DB_PATH` — absolute path used as-is, `~/` expanded, relative
70
+ * name joined to the data dir, `:memory:` meaning there is no file.
71
+ * 2. `<data>/sessions.db` — Cognition's default store. Missing file is a
72
+ * normal empty result; the adapter checks existence.
73
+ */
74
+ export function devinCliDbPath() {
75
+ const override = process.env.DEVIN_DB_PATH?.trim();
76
+ if (override) {
77
+ if (override === ":memory:")
78
+ return undefined;
79
+ const expanded = expandHome(override);
80
+ return path.isAbsolute(expanded)
81
+ ? expanded
82
+ : path.join(devinCliDataDir(), expanded);
83
+ }
84
+ return path.join(devinCliDataDir(), "sessions.db");
85
+ }
41
86
  /**
42
87
  * Resolve the OpenCode session database, or `undefined` when this machine has
43
88
  * none (a normal empty result, not an error).
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/mem/internal/paths.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/mem/internal/paths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Shared SQLite adapter kit for mem readers (OpenCode, ZCode, Devin CLI).
3
+ *
4
+ * Schema contract, structured warnings, one-slot prepare/release, and a
5
+ * scan visitor that never retains raw rows. Platform files own path, table
6
+ * mapping, and dialogue cleaning — not another copy of these helpers.
7
+ *
8
+ * Access is always through `sqlite-readonly.ts`. No native module, WASM
9
+ * blob, system `sqlite3`, or `better-sqlite3`.
10
+ */
11
+ import type { MemWarning } from "../types.js";
12
+ import { SqliteParseError, type SqliteReadOnly, type SqliteRow, type SqliteTableInfo } from "./sqlite-readonly.js";
13
+ /** Schema mismatch (missing table / column). Distinct from a truncated file. */
14
+ export declare class SqliteSchemaError extends SqliteParseError {
15
+ constructor(message: string);
16
+ }
17
+ export interface SqliteWarningCopy {
18
+ unreadableCode: string;
19
+ snapshotUnstableCode: string;
20
+ /** Omit for ZCode: schema errors degrade to `unreadableCode`. */
21
+ schemaUnsupportedCode?: string;
22
+ writingMessage: (dbPath: string) => string;
23
+ unreadableMessage: (dbPath: string, error: SqliteParseError) => string;
24
+ unsupportedMessage?: (dbPath: string, error: SqliteParseError) => string;
25
+ }
26
+ /** Record one degradation per condition per command. */
27
+ export declare function pushSqliteWarning(warnings: MemWarning[], dbPath: string, error: SqliteParseError, copy: SqliteWarningCopy): void;
28
+ export declare function findTable(db: SqliteReadOnly, name: string): SqliteTableInfo;
29
+ /** True when `CREATE TABLE` sql declares a column of this exact name.
30
+ * Line comments (`-- ...`) sit between columns in some live schemas (Devin
31
+ * CLI) and must not hide the next name. */
32
+ export declare function declaresColumn(table: SqliteTableInfo, name: string): boolean;
33
+ export declare function requireColumns(table: SqliteTableInfo, names: readonly string[]): void;
34
+ export declare function requireOneOfColumns(table: SqliteTableInfo, candidates: readonly string[]): string;
35
+ /** Re-check the first decoded row; CREATE TABLE parse and rows can disagree. */
36
+ export declare function requireRowColumns(rows: readonly SqliteRow[] | SqliteRow, tableName: string, names: readonly string[]): void;
37
+ /** Visit every row and always return false so `scanTable` retains nothing. */
38
+ export declare function scanAndDiscard(db: SqliteReadOnly, tableName: string, visit: (row: SqliteRow) => void): void;
39
+ export declare function withSqliteDb<T>(dbPath: string, warnings: MemWarning[], copy: SqliteWarningCopy, fallback: T, run: (db: SqliteReadOnly) => T): T;
40
+ /** One-slot search-scoped store. Extract reuses it when the path matches. */
41
+ export declare function createSqlitePreparedStore<T>(): {
42
+ prepare: (dbPath: string, load: () => T) => void;
43
+ release: () => void;
44
+ get: (dbPath: string) => T | undefined;
45
+ };
46
+ //# sourceMappingURL=sqlite-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-adapter.d.ts","sourceRoot":"","sources":["../../../src/mem/internal/sqlite-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAEL,gBAAgB,EAGhB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAE9B,gFAAgF;AAChF,qBAAa,iBAAkB,SAAQ,gBAAgB;gBACzC,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iEAAiE;IACjE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3C,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,KAAK,MAAM,CAAC;IACvE,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,KAAK,MAAM,CAAC;CAC1E;AAED,wDAAwD;AACxD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,UAAU,EAAE,EACtB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,iBAAiB,GACtB,IAAI,CAiBN;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CAM3E;AAED;;2CAE2C;AAC3C,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAO5E;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,IAAI,CAON;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,eAAe,EACtB,UAAU,EAAE,SAAS,MAAM,EAAE,GAC5B,MAAM,CAQR;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,EACtC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,IAAI,CASN;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAC5B,EAAE,EAAE,cAAc,EAClB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,GAC9B,IAAI,CAKN;AAED,wBAAgB,YAAY,CAAC,CAAC,EAC5B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,UAAU,EAAE,EACtB,IAAI,EAAE,iBAAiB,EACvB,QAAQ,EAAE,CAAC,EACX,GAAG,EAAE,CAAC,EAAE,EAAE,cAAc,KAAK,CAAC,GAC7B,CAAC,CAcH;AAED,6EAA6E;AAC7E,wBAAgB,yBAAyB,CAAC,CAAC,KAAK;IAC9C,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IACjD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,CAAC,GAAG,SAAS,CAAC;CACxC,CAaA"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Shared SQLite adapter kit for mem readers (OpenCode, ZCode, Devin CLI).
3
+ *
4
+ * Schema contract, structured warnings, one-slot prepare/release, and a
5
+ * scan visitor that never retains raw rows. Platform files own path, table
6
+ * mapping, and dialogue cleaning — not another copy of these helpers.
7
+ *
8
+ * Access is always through `sqlite-readonly.ts`. No native module, WASM
9
+ * blob, system `sqlite3`, or `better-sqlite3`.
10
+ */
11
+ import * as fs from "node:fs";
12
+ import { openSqliteReadOnly, SqliteParseError, SqliteSnapshotUnstableError, stripSqlLineComments, } from "./sqlite-readonly.js";
13
+ /** Schema mismatch (missing table / column). Distinct from a truncated file. */
14
+ export class SqliteSchemaError extends SqliteParseError {
15
+ constructor(message) {
16
+ super(message);
17
+ this.name = "SqliteSchemaError";
18
+ }
19
+ }
20
+ /** Record one degradation per condition per command. */
21
+ export function pushSqliteWarning(warnings, dbPath, error, copy) {
22
+ const code = error instanceof SqliteSnapshotUnstableError
23
+ ? copy.snapshotUnstableCode
24
+ : error instanceof SqliteSchemaError && copy.schemaUnsupportedCode
25
+ ? copy.schemaUnsupportedCode
26
+ : copy.unreadableCode;
27
+ if (warnings.some((warning) => warning.code === code))
28
+ return;
29
+ const message = code === copy.snapshotUnstableCode
30
+ ? copy.writingMessage(dbPath)
31
+ : code === copy.schemaUnsupportedCode
32
+ ? (copy.unsupportedMessage?.(dbPath, error) ??
33
+ copy.unreadableMessage(dbPath, error))
34
+ : copy.unreadableMessage(dbPath, error);
35
+ warnings.push({ code, message });
36
+ }
37
+ export function findTable(db, name) {
38
+ const table = db.listTables().find((item) => item.name === name);
39
+ if (!table) {
40
+ throw new SqliteSchemaError(`missing table: ${name}`);
41
+ }
42
+ return table;
43
+ }
44
+ /** True when `CREATE TABLE` sql declares a column of this exact name.
45
+ * Line comments (`-- ...`) sit between columns in some live schemas (Devin
46
+ * CLI) and must not hide the next name. */
47
+ export function declaresColumn(table, name) {
48
+ const sql = stripSqlLineComments(table.sql);
49
+ const pattern = new RegExp(`(?:\\(|,)\\s*["\`\\[]?${name}(?:["\`\\]]|\\b)`, "i");
50
+ return pattern.test(sql);
51
+ }
52
+ export function requireColumns(table, names) {
53
+ const missing = names.filter((name) => !declaresColumn(table, name));
54
+ if (missing.length > 0) {
55
+ throw new SqliteSchemaError(`table ${table.name} is missing column(s): ${missing.join(", ")}`);
56
+ }
57
+ }
58
+ export function requireOneOfColumns(table, candidates) {
59
+ const found = candidates.find((name) => declaresColumn(table, name));
60
+ if (!found) {
61
+ throw new SqliteSchemaError(`table ${table.name} has none of the expected column(s): ${candidates.join(" / ")}`);
62
+ }
63
+ return found;
64
+ }
65
+ /** Re-check the first decoded row; CREATE TABLE parse and rows can disagree. */
66
+ export function requireRowColumns(rows, tableName, names) {
67
+ const first = Array.isArray(rows) ? rows[0] : rows;
68
+ if (!first)
69
+ return;
70
+ const missing = names.filter((name) => !(name in first));
71
+ if (missing.length > 0) {
72
+ throw new SqliteSchemaError(`table ${tableName} is missing column(s): ${missing.join(", ")}`);
73
+ }
74
+ }
75
+ /** Visit every row and always return false so `scanTable` retains nothing. */
76
+ export function scanAndDiscard(db, tableName, visit) {
77
+ db.scanTable(tableName, (row) => {
78
+ visit(row);
79
+ return false;
80
+ });
81
+ }
82
+ export function withSqliteDb(dbPath, warnings, copy, fallback, run) {
83
+ if (!fs.existsSync(dbPath))
84
+ return fallback;
85
+ try {
86
+ const db = openSqliteReadOnly(dbPath);
87
+ try {
88
+ return run(db);
89
+ }
90
+ finally {
91
+ db.close();
92
+ }
93
+ }
94
+ catch (error) {
95
+ if (!(error instanceof SqliteParseError))
96
+ throw error;
97
+ pushSqliteWarning(warnings, dbPath, error, copy);
98
+ return fallback;
99
+ }
100
+ }
101
+ /** One-slot search-scoped store. Extract reuses it when the path matches. */
102
+ export function createSqlitePreparedStore() {
103
+ let slot = null;
104
+ return {
105
+ prepare(dbPath, load) {
106
+ slot = { dbPath, store: load() };
107
+ },
108
+ release() {
109
+ slot = null;
110
+ },
111
+ get(dbPath) {
112
+ return slot?.dbPath === dbPath ? slot.store : undefined;
113
+ },
114
+ };
115
+ }
116
+ //# sourceMappingURL=sqlite-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-adapter.js","sourceRoot":"","sources":["../../../src/mem/internal/sqlite-adapter.ts"],"names":[],"mappings":"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"}
@@ -61,6 +61,9 @@ export declare class SqliteParseError extends Error {
61
61
  export declare class SqliteSnapshotUnstableError extends SqliteParseError {
62
62
  constructor(mainPath: string);
63
63
  }
64
+ /** Strip `-- line comments` so a comma on the previous line still reveals
65
+ * the next column. Live Devin CLI `CREATE TABLE` SQL uses that layout. */
66
+ export declare function stripSqlLineComments(sql: string): string;
64
67
  /**
65
68
  * Open a SQLite database file for read-only access. Automatically loads the
66
69
  * sibling `<db>-wal` file when present so active WAL-mode databases (e.g.
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite-readonly.d.ts","sourceRoot":"","sources":["../../../src/mem/internal/sqlite-readonly.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAMH;;;iFAGiF;AACjF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,UAAU,IAAI,eAAe,EAAE,CAAC;IAChC;sEACkE;IAClE,SAAS,CACP,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,OAAO,GACtC,SAAS,EAAE,CAAC;IACf,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;CACf;AAID;6EAC6E;AAC7E,qBAAa,gBAAiB,SAAQ,KAAK;IAGvC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO;gBADxB,OAAO,EAAE,MAAM,EACN,KAAK,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED;;;;GAIG;AACH,qBAAa,2BAA4B,SAAQ,gBAAgB;gBACnD,QAAQ,EAAE,MAAM;CAM7B;AAyxBD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CA2HnE;AAED;;uBAEuB;AACvB,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,SAAS,EAAE,CAWb"}
1
+ {"version":3,"file":"sqlite-readonly.d.ts","sourceRoot":"","sources":["../../../src/mem/internal/sqlite-readonly.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAMH;;;iFAGiF;AACjF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,UAAU,IAAI,eAAe,EAAE,CAAC;IAChC;sEACkE;IAClE,SAAS,CACP,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,OAAO,GACtC,SAAS,EAAE,CAAC;IACf,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;CACf;AAID;6EAC6E;AAC7E,qBAAa,gBAAiB,SAAQ,KAAK;IAGvC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO;gBADxB,OAAO,EAAE,MAAM,EACN,KAAK,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED;;;;GAIG;AACH,qBAAa,2BAA4B,SAAQ,gBAAgB;gBACnD,QAAQ,EAAE,MAAM;CAM7B;AAq1BD;0EAC0E;AAC1E,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAExD;AAID;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CA8KnE;AAED;;uBAEuB;AACvB,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,SAAS,EAAE,CAWb"}
@@ -177,16 +177,18 @@ function equalBytes(a, b) {
177
177
  }
178
178
  return true;
179
179
  }
180
+ function stampFromStat(stat) {
181
+ return {
182
+ size: stat.size,
183
+ mtimeMs: stat.mtimeMs,
184
+ ctimeMs: stat.ctimeMs,
185
+ dev: stat.dev,
186
+ ino: stat.ino,
187
+ };
188
+ }
180
189
  function fileStamp(path) {
181
190
  try {
182
- const stat = fs.statSync(path);
183
- return {
184
- size: stat.size,
185
- mtimeMs: stat.mtimeMs,
186
- ctimeMs: stat.ctimeMs,
187
- dev: stat.dev,
188
- ino: stat.ino,
189
- };
191
+ return stampFromStat(fs.statSync(path));
190
192
  }
191
193
  catch (error) {
192
194
  const code = error.code;
@@ -195,6 +197,9 @@ function fileStamp(path) {
195
197
  throw error;
196
198
  }
197
199
  }
200
+ function fileDescriptorStamp(fd) {
201
+ return stampFromStat(fs.fstatSync(fd));
202
+ }
198
203
  function sameStamp(a, b) {
199
204
  if (a === null || b === null)
200
205
  return a === b;
@@ -270,6 +275,7 @@ function captureSnapshot(mainPath) {
270
275
  const shmPath = mainPath + "-shm";
271
276
  let lastError;
272
277
  for (let attempt = 0; attempt < SNAPSHOT_ATTEMPTS; attempt++) {
278
+ let mainFd = null;
273
279
  try {
274
280
  const shmBefore = readWalIndexPrefix(shmPath);
275
281
  const mainBefore = fileStamp(mainPath);
@@ -277,7 +283,7 @@ function captureSnapshot(mainPath) {
277
283
  if (mainBefore === null) {
278
284
  throw new SqliteParseError(`cannot read db file: ${mainPath}`);
279
285
  }
280
- const mainBytes = fs.readFileSync(mainPath);
286
+ mainFd = fs.openSync(mainPath, "r");
281
287
  const walBytes = readOptionalFile(walPath);
282
288
  const mainAfter = fileStamp(mainPath);
283
289
  const walAfter = fileStamp(walPath);
@@ -285,13 +291,22 @@ function captureSnapshot(mainPath) {
285
291
  if (!sameStamp(mainBefore, mainAfter) ||
286
292
  !sameStamp(walBefore, walAfter) ||
287
293
  !equalBytes(shmBefore, shmAfter)) {
294
+ fs.closeSync(mainFd);
295
+ mainFd = null;
288
296
  lastError = new SqliteSnapshotUnstableError(mainPath);
289
297
  continue;
290
298
  }
291
299
  const walIndex = walBytes === null ? null : parseWalIndexHeader(shmAfter);
292
- return { mainBytes, walBytes, walIndex };
300
+ return {
301
+ mainFd,
302
+ mainStamp: mainAfter ?? mainBefore,
303
+ walBytes,
304
+ walIndex,
305
+ };
293
306
  }
294
307
  catch (error) {
308
+ if (mainFd !== null)
309
+ fs.closeSync(mainFd);
295
310
  lastError = error;
296
311
  }
297
312
  }
@@ -394,7 +409,7 @@ function loadWal(walBytes, expectedPageSize, walIndex) {
394
409
  }
395
410
  return { pageMap };
396
411
  }
397
- function makePageSource(mainBytes, header, wal) {
412
+ function makePageSource(snapshot, header, wal) {
398
413
  return {
399
414
  pageSize: header.pageSize,
400
415
  getPage(pgno) {
@@ -406,14 +421,46 @@ function makePageSource(mainBytes, header, wal) {
406
421
  }
407
422
  const start = (pgno - 1) * header.pageSize;
408
423
  const end = start + header.pageSize;
409
- if (end > mainBytes.length) {
424
+ if (end > snapshot.mainStamp.size) {
410
425
  // Page lives beyond the main file and has no WAL copy — treat as empty.
411
426
  return new Uint8Array(header.pageSize);
412
427
  }
413
- return mainBytes.subarray(start, end);
428
+ const page = new Uint8Array(header.pageSize);
429
+ const bytesRead = readExactly(snapshot.mainFd, page, start);
430
+ if (bytesRead !== header.pageSize) {
431
+ throw new SqliteParseError(`short read for SQLite page ${pgno}`);
432
+ }
433
+ return page;
414
434
  },
415
435
  };
416
436
  }
437
+ function readExactly(fd, target, position) {
438
+ let offset = 0;
439
+ while (offset < target.length) {
440
+ const bytesRead = fs.readSync(fd, target, offset, target.length - offset, position + offset);
441
+ if (bytesRead === 0)
442
+ break;
443
+ offset += bytesRead;
444
+ }
445
+ return offset;
446
+ }
447
+ function readMainHeader(snapshot) {
448
+ const bytes = new Uint8Array(DB_HEADER_SIZE);
449
+ const bytesRead = readExactly(snapshot.mainFd, bytes, 0);
450
+ if (bytesRead !== DB_HEADER_SIZE) {
451
+ throw new SqliteParseError("SQLite database header is truncated");
452
+ }
453
+ return bytes;
454
+ }
455
+ function isMainSnapshotStable(mainPath, snapshot) {
456
+ try {
457
+ return (sameStamp(snapshot.mainStamp, fileStamp(mainPath)) &&
458
+ sameStamp(snapshot.mainStamp, fileDescriptorStamp(snapshot.mainFd)));
459
+ }
460
+ catch {
461
+ return false;
462
+ }
463
+ }
417
464
  /** Decode a record body (the payload of a table-leaf cell) into an array of
418
465
  * JS values. Serial type reference: https://www.sqlite.org/fileformat2.html
419
466
  * section 2.1. Only TEXT / INTEGER / NULL / float / BLOB are handled. The
@@ -613,11 +660,12 @@ function decodeLeafCell(page, cellOff, src, header, td) {
613
660
  * not columns.
614
661
  */
615
662
  function parseColumnNames(sql) {
616
- const open = sql.indexOf("(");
617
- const close = sql.lastIndexOf(")");
663
+ const cleaned = stripSqlLineComments(sql);
664
+ const open = cleaned.indexOf("(");
665
+ const close = cleaned.lastIndexOf(")");
618
666
  if (open < 0 || close < 0 || close <= open)
619
667
  return null;
620
- const body = sql.slice(open + 1, close);
668
+ const body = cleaned.slice(open + 1, close);
621
669
  const segments = splitTopLevelCommas(body);
622
670
  const cols = [];
623
671
  for (const seg of segments) {
@@ -661,6 +709,11 @@ function firstIdentifier(piece) {
661
709
  function isConstraintKeyword(id) {
662
710
  return /^(primary|unique|check|foreign|constraint)$/i.test(id);
663
711
  }
712
+ /** Strip `-- line comments` so a comma on the previous line still reveals
713
+ * the next column. Live Devin CLI `CREATE TABLE` SQL uses that layout. */
714
+ export function stripSqlLineComments(sql) {
715
+ return sql.replace(/--[^\n]*/g, " ");
716
+ }
664
717
  // ---------- public entry ----------
665
718
  /**
666
719
  * Open a SQLite database file for read-only access. Automatically loads the
@@ -672,13 +725,53 @@ function isConstraintKeyword(id) {
672
725
  */
673
726
  export function openSqliteReadOnly(mainPath) {
674
727
  const snapshot = captureSnapshot(mainPath);
675
- const { mainBytes } = snapshot;
676
- if (mainBytes.length < DB_HEADER_SIZE) {
677
- throw new SqliteParseError(`db file too small: ${mainPath}`);
728
+ let closed = false;
729
+ let header;
730
+ let src;
731
+ try {
732
+ if (snapshot.mainStamp.size < DB_HEADER_SIZE) {
733
+ throw new SqliteParseError(`db file too small: ${mainPath}`);
734
+ }
735
+ header = parseDbHeader(readMainHeader(snapshot));
736
+ const wal = loadWal(snapshot.walBytes, header.pageSize, snapshot.walIndex);
737
+ src = makePageSource(snapshot, header, wal);
738
+ if (!isMainSnapshotStable(mainPath, snapshot)) {
739
+ throw new SqliteSnapshotUnstableError(mainPath);
740
+ }
741
+ }
742
+ catch (error) {
743
+ fs.closeSync(snapshot.mainFd);
744
+ throw error instanceof SqliteParseError
745
+ ? error
746
+ : new SqliteParseError(`cannot read db file: ${mainPath}`, error);
747
+ }
748
+ function assertOpen() {
749
+ if (closed)
750
+ throw new SqliteParseError("SQLite reader is closed");
751
+ }
752
+ function assertMainSnapshotStable() {
753
+ if (!isMainSnapshotStable(mainPath, snapshot)) {
754
+ throw new SqliteSnapshotUnstableError(mainPath);
755
+ }
756
+ }
757
+ function readStable(read) {
758
+ assertOpen();
759
+ try {
760
+ const value = read();
761
+ assertMainSnapshotStable();
762
+ return value;
763
+ }
764
+ catch (error) {
765
+ if (error instanceof SqliteSnapshotUnstableError)
766
+ throw error;
767
+ if (!isMainSnapshotStable(mainPath, snapshot)) {
768
+ throw new SqliteSnapshotUnstableError(mainPath);
769
+ }
770
+ throw error instanceof SqliteParseError
771
+ ? error
772
+ : new SqliteParseError(`failed reading SQLite snapshot: ${mainPath}`, error);
773
+ }
678
774
  }
679
- const header = parseDbHeader(mainBytes);
680
- const wal = loadWal(snapshot.walBytes, header.pageSize, snapshot.walIndex);
681
- const src = makePageSource(mainBytes, header, wal);
682
775
  // Column-name cache: tableName → column list (or null).
683
776
  const columnCache = new Map();
684
777
  function readSqliteMaster() {
@@ -708,11 +801,12 @@ export function openSqliteReadOnly(mainPath) {
708
801
  function rowidAliasIndex(table, columns) {
709
802
  if (!table.sql || !columns)
710
803
  return -1;
711
- const open = table.sql.indexOf("(");
712
- const close = table.sql.lastIndexOf(")");
804
+ const cleaned = stripSqlLineComments(table.sql);
805
+ const open = cleaned.indexOf("(");
806
+ const close = cleaned.lastIndexOf(")");
713
807
  if (open < 0 || close < 0)
714
808
  return -1;
715
- const body = table.sql.slice(open + 1, close);
809
+ const body = cleaned.slice(open + 1, close);
716
810
  const segments = splitTopLevelCommas(body);
717
811
  let idx = 0;
718
812
  for (const seg of segments) {
@@ -734,46 +828,51 @@ export function openSqliteReadOnly(mainPath) {
734
828
  return {
735
829
  dbPath: mainPath,
736
830
  listTables() {
737
- return readSqliteMaster();
831
+ return readStable(readSqliteMaster);
738
832
  },
739
833
  scanTable(tableName, predicate) {
740
- let table;
741
- try {
742
- table = readSqliteMaster().find((t) => t.name === tableName);
743
- if (!table || table.rootPgno <= 0)
744
- return [];
745
- const columns = columnsFor(table);
746
- const aliasIdx = rowidAliasIndex(table, columns);
747
- const rows = [];
748
- visitTableBtree(src, table.rootPgno, header.textEncoding, header, ({ rowid, values }) => {
749
- const row = {};
750
- for (let i = 0; i < values.length; i++) {
751
- const key = columns?.[i] ?? `col${i}`;
752
- // INTEGER PRIMARY KEY columns store NULL in the record; the real
753
- // value is the cell rowid. Splice it in so callers see the integer.
754
- if (i === aliasIdx && values[i] === null) {
755
- row[key] = rowid;
756
- }
757
- else {
758
- row[key] = values[i];
834
+ return readStable(() => {
835
+ let table;
836
+ try {
837
+ table = readSqliteMaster().find((t) => t.name === tableName);
838
+ if (!table || table.rootPgno <= 0)
839
+ return [];
840
+ const columns = columnsFor(table);
841
+ const aliasIdx = rowidAliasIndex(table, columns);
842
+ const rows = [];
843
+ visitTableBtree(src, table.rootPgno, header.textEncoding, header, ({ rowid, values }) => {
844
+ const row = {};
845
+ for (let i = 0; i < values.length; i++) {
846
+ const key = columns?.[i] ?? `col${i}`;
847
+ // INTEGER PRIMARY KEY columns store NULL in the record; the real
848
+ // value is the cell rowid. Splice it in so callers see the integer.
849
+ if (i === aliasIdx && values[i] === null) {
850
+ row[key] = rowid;
851
+ }
852
+ else {
853
+ row[key] = values[i];
854
+ }
759
855
  }
760
- }
761
- if (!predicate || predicate(row))
762
- rows.push(row);
763
- });
764
- return rows;
765
- }
766
- catch (e) {
767
- // Wrap any non-SqliteParseError (e.g. RangeError from a truncated
768
- // float64, TypeError from a bad cell pointer) so the adapter's single
769
- // catch on SqliteParseError degrades cleanly instead of crashing CLI.
770
- throw e instanceof SqliteParseError
771
- ? e
772
- : new SqliteParseError(`failed reading table "${tableName}"`, e);
773
- }
856
+ if (!predicate || predicate(row))
857
+ rows.push(row);
858
+ });
859
+ return rows;
860
+ }
861
+ catch (error) {
862
+ // Wrap any non-SqliteParseError (e.g. RangeError from a truncated
863
+ // float64, TypeError from a bad cell pointer) so the adapter's single
864
+ // catch on SqliteParseError degrades cleanly instead of crashing CLI.
865
+ throw error instanceof SqliteParseError
866
+ ? error
867
+ : new SqliteParseError(`failed reading table "${tableName}"`, error);
868
+ }
869
+ });
774
870
  },
775
871
  close() {
776
- // Nothing to release — we read the whole file into memory at open time.
872
+ if (closed)
873
+ return;
874
+ closed = true;
875
+ fs.closeSync(snapshot.mainFd);
777
876
  },
778
877
  };
779
878
  }