sensemaking 0.12.2 → 0.13.0

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 (245) hide show
  1. package/dist/cjs/cli/download.js +4 -4
  2. package/dist/cjs/cli/download.js.map +1 -1
  3. package/dist/cjs/cli/init.js +4 -4
  4. package/dist/cjs/cli/init.js.map +1 -1
  5. package/dist/cjs/cli/map.js +4 -4
  6. package/dist/cjs/cli/map.js.map +1 -1
  7. package/dist/cjs/cli/named.js +2 -2
  8. package/dist/cjs/cli/named.js.map +1 -1
  9. package/dist/cjs/cli/path.js +6 -6
  10. package/dist/cjs/cli/path.js.map +1 -1
  11. package/dist/cjs/cli/peek.js +4 -4
  12. package/dist/cjs/cli/peek.js.map +1 -1
  13. package/dist/cjs/cli/related.js +4 -4
  14. package/dist/cjs/cli/related.js.map +1 -1
  15. package/dist/cjs/cli/search.js +4 -4
  16. package/dist/cjs/cli/search.js.map +1 -1
  17. package/dist/cjs/cli/shared.d.cts +2 -2
  18. package/dist/cjs/cli/shared.d.ts +2 -2
  19. package/dist/cjs/cli/shared.js +5 -5
  20. package/dist/cjs/cli/shared.js.map +1 -1
  21. package/dist/cjs/cli/status.js +16 -16
  22. package/dist/cjs/cli/status.js.map +1 -1
  23. package/dist/cjs/cli/types.d.cts +1 -1
  24. package/dist/cjs/cli/types.d.ts +1 -1
  25. package/dist/cjs/cli.js +3 -3
  26. package/dist/cjs/cli.js.map +1 -1
  27. package/dist/cjs/commands/index.d.cts +10 -0
  28. package/dist/cjs/commands/index.d.ts +10 -0
  29. package/dist/cjs/commands/index.js +42 -0
  30. package/dist/cjs/commands/index.js.map +1 -0
  31. package/dist/cjs/commands/map.d.cts +21 -0
  32. package/dist/cjs/commands/map.d.ts +21 -0
  33. package/dist/cjs/commands/map.js +90 -0
  34. package/dist/cjs/commands/map.js.map +1 -0
  35. package/dist/cjs/commands/peek.d.cts +20 -0
  36. package/dist/cjs/commands/peek.d.ts +20 -0
  37. package/dist/cjs/commands/peek.js +175 -0
  38. package/dist/cjs/commands/peek.js.map +1 -0
  39. package/dist/cjs/commands/related.d.cts +6 -0
  40. package/dist/cjs/commands/related.d.ts +6 -0
  41. package/dist/cjs/commands/related.js +232 -0
  42. package/dist/cjs/commands/related.js.map +1 -0
  43. package/dist/cjs/commands/scope.d.cts +10 -0
  44. package/dist/cjs/commands/scope.d.ts +10 -0
  45. package/dist/cjs/commands/scope.js +124 -0
  46. package/dist/cjs/commands/scope.js.map +1 -0
  47. package/dist/cjs/commands/search.d.cts +12 -0
  48. package/dist/cjs/commands/search.d.ts +12 -0
  49. package/dist/cjs/{commands.js → commands/search.js} +20 -358
  50. package/dist/cjs/commands/search.js.map +1 -0
  51. package/dist/cjs/commands/status.d.cts +9 -0
  52. package/dist/cjs/commands/status.d.ts +9 -0
  53. package/dist/cjs/commands/status.js +25 -0
  54. package/dist/cjs/commands/status.js.map +1 -0
  55. package/dist/cjs/config/access.d.cts +19 -0
  56. package/dist/cjs/config/access.d.ts +19 -0
  57. package/dist/cjs/config/access.js +149 -0
  58. package/dist/cjs/config/access.js.map +1 -0
  59. package/dist/cjs/config/index.d.cts +5 -0
  60. package/dist/cjs/config/index.d.ts +5 -0
  61. package/dist/cjs/config/index.js +77 -0
  62. package/dist/cjs/config/index.js.map +1 -0
  63. package/dist/cjs/config/load.d.cts +8 -0
  64. package/dist/cjs/config/load.d.ts +8 -0
  65. package/dist/cjs/config/load.js +448 -0
  66. package/dist/cjs/config/load.js.map +1 -0
  67. package/dist/cjs/config/resolve.d.cts +6 -0
  68. package/dist/cjs/config/resolve.d.ts +6 -0
  69. package/dist/cjs/config/resolve.js +50 -0
  70. package/dist/cjs/config/resolve.js.map +1 -0
  71. package/dist/{esm/config.d.ts → cjs/config/types.d.cts} +2 -32
  72. package/dist/cjs/{config.d.cts → config/types.d.ts} +2 -32
  73. package/dist/cjs/config/types.js +39 -0
  74. package/dist/cjs/config/types.js.map +1 -0
  75. package/dist/cjs/config/validate.d.cts +4 -0
  76. package/dist/cjs/config/validate.d.ts +4 -0
  77. package/dist/cjs/config/validate.js +363 -0
  78. package/dist/cjs/config/validate.js.map +1 -0
  79. package/dist/cjs/db/index.d.cts +4 -0
  80. package/dist/cjs/db/index.d.ts +4 -0
  81. package/dist/cjs/db/index.js +42 -0
  82. package/dist/cjs/db/index.js.map +1 -0
  83. package/dist/cjs/{db.d.cts → db/open.d.cts} +2 -8
  84. package/dist/cjs/{db.d.ts → db/open.d.ts} +2 -8
  85. package/dist/cjs/db/open.js +223 -0
  86. package/dist/cjs/db/open.js.map +1 -0
  87. package/dist/cjs/db/reconcile.d.cts +9 -0
  88. package/dist/cjs/db/reconcile.d.ts +9 -0
  89. package/dist/cjs/{db.js → db/reconcile.js} +24 -261
  90. package/dist/cjs/db/reconcile.js.map +1 -0
  91. package/dist/cjs/db/shared.d.cts +5 -0
  92. package/dist/cjs/db/shared.d.ts +5 -0
  93. package/dist/cjs/db/shared.js +45 -0
  94. package/dist/cjs/db/shared.js.map +1 -0
  95. package/dist/cjs/features/embed.d.cts +1 -1
  96. package/dist/cjs/features/embed.d.ts +1 -1
  97. package/dist/cjs/features/embed.js +4 -3
  98. package/dist/cjs/features/embed.js.map +1 -1
  99. package/dist/cjs/features/index.d.cts +1 -1
  100. package/dist/cjs/features/index.d.ts +1 -1
  101. package/dist/cjs/features/index.js +4 -2
  102. package/dist/cjs/features/index.js.map +1 -1
  103. package/dist/cjs/features/links.js +38 -20
  104. package/dist/cjs/features/links.js.map +1 -1
  105. package/dist/cjs/features/tags.d.cts +2 -0
  106. package/dist/cjs/features/tags.d.ts +2 -0
  107. package/dist/cjs/features/tags.js +188 -0
  108. package/dist/cjs/features/tags.js.map +1 -0
  109. package/dist/cjs/features/types.d.cts +2 -2
  110. package/dist/cjs/features/types.d.ts +2 -2
  111. package/dist/cjs/index.d.cts +6 -6
  112. package/dist/cjs/index.d.ts +6 -6
  113. package/dist/cjs/index.js +15 -15
  114. package/dist/cjs/index.js.map +1 -1
  115. package/dist/cjs/scan.d.cts +3 -1
  116. package/dist/cjs/scan.d.ts +3 -1
  117. package/dist/cjs/scan.js +9 -6
  118. package/dist/cjs/scan.js.map +1 -1
  119. package/dist/cjs/sql-functions.d.cts +2 -0
  120. package/dist/cjs/sql-functions.d.ts +2 -0
  121. package/dist/cjs/sql-functions.js +64 -0
  122. package/dist/cjs/sql-functions.js.map +1 -0
  123. package/dist/cjs/watch.d.cts +1 -1
  124. package/dist/cjs/watch.d.ts +1 -1
  125. package/dist/cjs/watch.js +12 -12
  126. package/dist/cjs/watch.js.map +1 -1
  127. package/dist/esm/cli/download.js +1 -1
  128. package/dist/esm/cli/download.js.map +1 -1
  129. package/dist/esm/cli/init.js +1 -1
  130. package/dist/esm/cli/init.js.map +1 -1
  131. package/dist/esm/cli/map.js +1 -1
  132. package/dist/esm/cli/map.js.map +1 -1
  133. package/dist/esm/cli/named.js +1 -1
  134. package/dist/esm/cli/named.js.map +1 -1
  135. package/dist/esm/cli/path.js +1 -1
  136. package/dist/esm/cli/path.js.map +1 -1
  137. package/dist/esm/cli/peek.js +1 -1
  138. package/dist/esm/cli/peek.js.map +1 -1
  139. package/dist/esm/cli/related.js +1 -1
  140. package/dist/esm/cli/related.js.map +1 -1
  141. package/dist/esm/cli/search.js +1 -1
  142. package/dist/esm/cli/search.js.map +1 -1
  143. package/dist/esm/cli/shared.d.ts +2 -2
  144. package/dist/esm/cli/shared.js +2 -2
  145. package/dist/esm/cli/shared.js.map +1 -1
  146. package/dist/esm/cli/status.js +3 -3
  147. package/dist/esm/cli/status.js.map +1 -1
  148. package/dist/esm/cli/types.d.ts +1 -1
  149. package/dist/esm/cli/types.js.map +1 -1
  150. package/dist/esm/cli.js +1 -1
  151. package/dist/esm/cli.js.map +1 -1
  152. package/dist/esm/commands/index.d.ts +10 -0
  153. package/dist/esm/commands/index.js +8 -0
  154. package/dist/esm/commands/index.js.map +1 -0
  155. package/dist/esm/commands/map.d.ts +21 -0
  156. package/dist/esm/commands/map.js +56 -0
  157. package/dist/esm/commands/map.js.map +1 -0
  158. package/dist/esm/commands/peek.d.ts +20 -0
  159. package/dist/esm/commands/peek.js +63 -0
  160. package/dist/esm/commands/peek.js.map +1 -0
  161. package/dist/esm/commands/related.d.ts +6 -0
  162. package/dist/esm/commands/related.js +47 -0
  163. package/dist/esm/commands/related.js.map +1 -0
  164. package/dist/esm/commands/scope.d.ts +10 -0
  165. package/dist/esm/commands/scope.js +60 -0
  166. package/dist/esm/commands/scope.js.map +1 -0
  167. package/dist/esm/commands/search.d.ts +12 -0
  168. package/dist/esm/commands/search.js +258 -0
  169. package/dist/esm/commands/search.js.map +1 -0
  170. package/dist/esm/commands/status.d.ts +9 -0
  171. package/dist/esm/commands/status.js +16 -0
  172. package/dist/esm/commands/status.js.map +1 -0
  173. package/dist/esm/config/access.d.ts +19 -0
  174. package/dist/esm/config/access.js +89 -0
  175. package/dist/esm/config/access.js.map +1 -0
  176. package/dist/esm/config/index.d.ts +5 -0
  177. package/dist/esm/config/index.js +4 -0
  178. package/dist/esm/config/index.js.map +1 -0
  179. package/dist/esm/config/load.d.ts +8 -0
  180. package/dist/esm/config/load.js +242 -0
  181. package/dist/esm/config/load.js.map +1 -0
  182. package/dist/esm/config/resolve.d.ts +6 -0
  183. package/dist/esm/config/resolve.js +35 -0
  184. package/dist/esm/config/resolve.js.map +1 -0
  185. package/dist/{cjs/config.d.ts → esm/config/types.d.ts} +2 -32
  186. package/dist/esm/config/types.js +15 -0
  187. package/dist/esm/config/types.js.map +1 -0
  188. package/dist/esm/config/validate.d.ts +4 -0
  189. package/dist/esm/config/validate.js +226 -0
  190. package/dist/esm/config/validate.js.map +1 -0
  191. package/dist/esm/db/index.d.ts +4 -0
  192. package/dist/esm/db/index.js +5 -0
  193. package/dist/esm/db/index.js.map +1 -0
  194. package/dist/esm/{db.d.ts → db/open.d.ts} +2 -8
  195. package/dist/esm/db/open.js +160 -0
  196. package/dist/esm/db/open.js.map +1 -0
  197. package/dist/esm/db/reconcile.d.ts +9 -0
  198. package/dist/esm/{db.js → db/reconcile.js} +12 -216
  199. package/dist/esm/db/reconcile.js.map +1 -0
  200. package/dist/esm/db/shared.d.ts +5 -0
  201. package/dist/esm/db/shared.js +20 -0
  202. package/dist/esm/db/shared.js.map +1 -0
  203. package/dist/esm/features/embed.d.ts +1 -1
  204. package/dist/esm/features/embed.js +2 -1
  205. package/dist/esm/features/embed.js.map +1 -1
  206. package/dist/esm/features/index.d.ts +1 -1
  207. package/dist/esm/features/index.js +3 -1
  208. package/dist/esm/features/index.js.map +1 -1
  209. package/dist/esm/features/links.js +36 -21
  210. package/dist/esm/features/links.js.map +1 -1
  211. package/dist/esm/features/tags.d.ts +2 -0
  212. package/dist/esm/features/tags.js +80 -0
  213. package/dist/esm/features/tags.js.map +1 -0
  214. package/dist/esm/features/types.d.ts +2 -2
  215. package/dist/esm/features/types.js.map +1 -1
  216. package/dist/esm/index.d.ts +6 -6
  217. package/dist/esm/index.js +3 -3
  218. package/dist/esm/index.js.map +1 -1
  219. package/dist/esm/scan.d.ts +3 -1
  220. package/dist/esm/scan.js +5 -2
  221. package/dist/esm/scan.js.map +1 -1
  222. package/dist/esm/sql-functions.d.ts +2 -0
  223. package/dist/esm/sql-functions.js +47 -0
  224. package/dist/esm/sql-functions.js.map +1 -0
  225. package/dist/esm/watch.d.ts +1 -1
  226. package/dist/esm/watch.js +2 -2
  227. package/dist/esm/watch.js.map +1 -1
  228. package/package.json +2 -1
  229. package/schema.json +4 -0
  230. package/skills/sense/SKILL.md +3 -3
  231. package/skills/sense-bases/EXAMPLES.md +103 -0
  232. package/skills/sense-bases/SKILL.md +137 -0
  233. package/skills/sense-setup/SKILL.md +1 -1
  234. package/dist/cjs/commands.d.cts +0 -58
  235. package/dist/cjs/commands.d.ts +0 -58
  236. package/dist/cjs/commands.js.map +0 -1
  237. package/dist/cjs/config.js +0 -919
  238. package/dist/cjs/config.js.map +0 -1
  239. package/dist/cjs/db.js.map +0 -1
  240. package/dist/esm/commands.d.ts +0 -58
  241. package/dist/esm/commands.js +0 -486
  242. package/dist/esm/commands.js.map +0 -1
  243. package/dist/esm/config.js +0 -599
  244. package/dist/esm/config.js.map +0 -1
  245. package/dist/esm/db.js.map +0 -1
@@ -1,5 +1,3 @@
1
- // The Node floor (>=22.20) is explained here and nowhere else: 22.20 is the first release with
2
- // both FTS5 and row-returning INSERT ... RETURNING. Raise it only for a load-bearing capability.
3
1
  "use strict";
4
2
  Object.defineProperty(exports, "__esModule", {
5
3
  value: true
@@ -11,40 +9,26 @@ function _export(target, all) {
11
9
  });
12
10
  }
13
11
  _export(exports, {
14
- get DB_FILENAME () {
15
- return DB_FILENAME;
12
+ get changedSignatureKeys () {
13
+ return changedSignatureKeys;
16
14
  },
17
- get SCHEMA_VERSION () {
18
- return SCHEMA_VERSION;
19
- },
20
- get clearCache () {
21
- return clearCache;
22
- },
23
- get docCount () {
24
- return docCount;
25
- },
26
- get getMeta () {
27
- return getMeta;
28
- },
29
- get open () {
30
- return open;
15
+ get rebuildContentTable () {
16
+ return rebuildContentTable;
31
17
  },
32
18
  get reconcile () {
33
19
  return reconcile;
34
20
  },
35
- get setMeta () {
36
- return setMeta;
21
+ get signatureDiff () {
22
+ return signatureDiff;
37
23
  }
38
24
  });
39
- var _nodefs = require("node:fs");
40
- var _nodepath = require("node:path");
41
- var _nodesqlite = require("node:sqlite");
42
- var _configts = require("./config.js");
43
- var _errorsts = require("./errors.js");
44
- var _indexts = require("./features/index.js");
45
- var _progressts = require("./progress.js");
46
- var _scants = require("./scan.js");
47
- var _segmentts = require("./segment.js");
25
+ var _indexts = require("../config/index.js");
26
+ var _errorsts = require("../errors.js");
27
+ var _indexts1 = require("../features/index.js");
28
+ var _progressts = require("../progress.js");
29
+ var _scants = require("../scan.js");
30
+ var _segmentts = require("../segment.js");
31
+ var _sharedts = require("./shared.js");
48
32
  function _array_like_to_array(arr, len) {
49
33
  if (len == null || len > arr.length) len = arr.length;
50
34
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
@@ -108,137 +92,12 @@ function _unsupported_iterable_to_array(o, minLen) {
108
92
  var CORE_FRONTMATTER_COLUMNS = new Set([
109
93
  'path',
110
94
  '_mtime',
95
+ '_ctime',
111
96
  '_size',
112
97
  '_parse_error'
113
98
  ]);
114
- var DB_FILENAME = 'cache.db';
115
- var SCHEMA_VERSION = '12';
116
99
  // SQLite's compile-time SQLITE_MAX_COLUMN, default 2000 (https://www.sqlite.org/limits.html).
117
100
  var MAX_FRONTMATTER_COLUMNS = 2000;
118
- function quoteIdent(name) {
119
- return '"'.concat(name.split('"').join('""'), '"');
120
- }
121
- // has(field, value): JSON-array field -> membership, string field -> substring, NULL -> false.
122
- function registerFunctions(db, segmenting) {
123
- db.function('has', {
124
- deterministic: true,
125
- varargs: false
126
- }, function(field, value) {
127
- if (field === null || field === undefined) return 0;
128
- var needle = String(value);
129
- if (typeof field === 'string') {
130
- if (field.startsWith('[')) {
131
- try {
132
- var parsed = JSON.parse(field);
133
- if (Array.isArray(parsed)) {
134
- return parsed.some(function(item) {
135
- return String(item) === needle;
136
- }) ? 1 : 0;
137
- }
138
- } catch (unused) {}
139
- }
140
- return field.includes(needle) ? 1 : 0;
141
- }
142
- return String(field).includes(needle) ? 1 : 0;
143
- });
144
- // Raw `content MATCH '<unspaced text>'` cannot be rewritten behind the author's back, and
145
- // matches nothing, so the same transform is available to hand-written SQL by name. `segmenting`
146
- // is the same config predicate commands.ts's search() gates on (contentTokenize(cfg) ===
147
- // undefined), passed in by open() rather than read back from persisted state.
148
- db.function('segment', {
149
- deterministic: true,
150
- varargs: false
151
- }, function(terms) {
152
- var text = terms === null || terms === undefined ? '' : String(terms);
153
- return segmenting ? (0, _segmentts.segmentMatch)(text) : text;
154
- });
155
- }
156
- function getColumns(db) {
157
- var rows = db.prepare('PRAGMA table_info(frontmatter)').all();
158
- return new Set(rows.map(function(r) {
159
- return r.name;
160
- }));
161
- }
162
- // Stemming is English-only, but the segmentation underneath it is what decides coverage:
163
- // unicode61 splits on spaces, so a language written without them (Chinese, Japanese, Thai)
164
- // indexes a whole run as one token and word search finds nothing. `content.tokenize` is how
165
- // such a tree picks trigram instead.
166
- var DEFAULT_TOKENIZE = 'porter unicode61';
167
- // FTS5 takes its tokenizer as a string literal inside DDL, where nothing can bind, so a
168
- // configured value has to be concatenated. Probing a throwaway table is what makes that safe
169
- // and is also the whole validation: anything the linked SQLite accepts passes, anything else
170
- // fails here with SQLite's own message rather than against the real table. It means no table
171
- // of which version added which tokenizer has to be maintained.
172
- function resolveTokenize(db, cfg) {
173
- var configured = (0, _configts.contentTokenize)(cfg);
174
- if (configured === undefined) return DEFAULT_TOKENIZE;
175
- var literal = configured.replace(/'/g, "''");
176
- try {
177
- db.exec('DROP TABLE IF EXISTS temp.sense_tokenize_probe');
178
- db.exec("CREATE VIRTUAL TABLE temp.sense_tokenize_probe USING fts5(x, tokenize = '".concat(literal, "')"));
179
- db.exec('DROP TABLE IF EXISTS temp.sense_tokenize_probe');
180
- } catch (err) {
181
- throw new _errorsts.SenseError('CONFIG_INVALID', 'content.tokenize "'.concat(configured, '" is not a tokenizer this SQLite accepts (').concat(err.message, "); the built-in choices are unicode61, ascii, porter, and trigram, each with their own options"));
182
- }
183
- return literal;
184
- }
185
- // The tokenizer the content table was actually built with, from its own DDL -- the one
186
- // record that cannot desynchronize from the table. NULL when the table does not exist yet.
187
- function storedTokenize(db) {
188
- var row = db.prepare("SELECT sql FROM sqlite_master WHERE name = 'content'").get();
189
- if (!row) return null;
190
- var m = row.sql.match(/tokenize = '((?:[^']|'')*)'/);
191
- return m ? m[1] : null;
192
- }
193
- // Content is a separate table (not a column on frontmatter) so `SELECT * FROM frontmatter`
194
- // can't dump file text into context. Features add their own tables after the core ones.
195
- function ensureSchema(db, cfg, tokenize) {
196
- db.exec('CREATE TABLE IF NOT EXISTS frontmatter ("path" TEXT PRIMARY KEY, "_mtime" REAL, "_size" INTEGER, "_parse_error" TEXT)');
197
- // IF NOT EXISTS is safe against a tokenizer change: open() compares the table's own DDL
198
- // against the resolved tokenizer before this runs, so a stale table is already gone by now.
199
- // The three `_seg` sidecars are appended after path, never inserted: bm25(content, ...) and
200
- // snippet(content, 2, ...) are documented against the first three columns and keep working
201
- // (FTS5 defaults the weights it was not given). Each carries its field's exploded unspaced
202
- // runs for text that needs it, and an empty string for text that does not.
203
- db.exec("CREATE VIRTUAL TABLE IF NOT EXISTS content USING fts5(title, summary, text, path UNINDEXED, title_seg, summary_seg, text_seg, tokenize = '".concat(tokenize, "')"));
204
- // Coverage, not ownership: a path can appear under several presets. path leads the PK so the
205
- // per-doc delete is an index hit -- keyed the other way, cold builds went quadratic.
206
- db.exec('CREATE TABLE IF NOT EXISTS preset_files ("path" TEXT, preset TEXT, PRIMARY KEY ("path", preset))');
207
- db.exec('CREATE INDEX IF NOT EXISTS preset_files_preset ON preset_files(preset)');
208
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
209
- try {
210
- for(var _iterator = (0, _indexts.activeFeatures)(cfg)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
211
- var feature = _step.value;
212
- feature.schema(db);
213
- }
214
- } catch (err) {
215
- _didIteratorError = true;
216
- _iteratorError = err;
217
- } finally{
218
- try {
219
- if (!_iteratorNormalCompletion && _iterator.return != null) {
220
- _iterator.return();
221
- }
222
- } finally{
223
- if (_didIteratorError) {
224
- throw _iteratorError;
225
- }
226
- }
227
- }
228
- if (getMeta(db, 'schema_version') === null) setMeta(db, 'schema_version', SCHEMA_VERSION);
229
- if (getMeta(db, 'features') === null) setMeta(db, 'features', (0, _configts.featureSignature)(cfg));
230
- }
231
- function getMeta(db, key) {
232
- var row = db.prepare('SELECT value FROM meta WHERE key = ?').get(key);
233
- return row ? row.value : null;
234
- }
235
- function setMeta(db, key, value) {
236
- if (value === null) {
237
- db.prepare('DELETE FROM meta WHERE key = ?').run(key);
238
- return;
239
- }
240
- db.prepare('INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value').run(key, value);
241
- }
242
101
  // Shared by reconcile() and the tokenize-only rebuild in open(), so both prepare the same
243
102
  // literal instead of two copies drifting apart.
244
103
  var INSERT_CONTENT_SQL = 'INSERT INTO content (rowid, title, summary, text, "path", title_seg, summary_seg, text_seg) VALUES ((SELECT rowid FROM frontmatter WHERE "path" = ?), ?, ?, ?, ?, ?, ?, ?)';
@@ -247,10 +106,6 @@ var INSERT_CONTENT_SQL = 'INSERT INTO content (rowid, title, summary, text, "pat
247
106
  function insertContentRow(insertBody, doc, segmenting) {
248
107
  insertBody.run(doc.relPath, doc.search.title, doc.search.summary, doc.search.text, doc.relPath, segmenting ? (0, _segmentts.segmentField)(doc.search.title) : '', segmenting ? (0, _segmentts.segmentField)(doc.search.summary) : '', segmenting ? (0, _segmentts.segmentField)(doc.search.text) : '');
249
108
  }
250
- function docCount(db) {
251
- var row = db.prepare('SELECT COUNT(*) AS n FROM frontmatter').get();
252
- return row.n;
253
- }
254
109
  function reconcile(db, cfg, baseDir) {
255
110
  var files = (0, _scants.listFiles)(cfg, baseDir);
256
111
  var currentSet = new Set(files.map(function(f) {
@@ -276,8 +131,8 @@ function reconcile(db, cfg, baseDir) {
276
131
  parsed: 0,
277
132
  warnings: []
278
133
  };
279
- var features = (0, _indexts.activeFeatures)(cfg);
280
- var seenColumns = getColumns(db);
134
+ var features = (0, _indexts1.activeFeatures)(cfg);
135
+ var seenColumns = (0, _sharedts.getColumns)(db);
281
136
  var newColumns = [];
282
137
  var parsedDocs = [];
283
138
  var warnings = [];
@@ -352,12 +207,12 @@ function reconcile(db, cfg, baseDir) {
352
207
  });
353
208
  // ON CONFLICT UPDATE (not OR REPLACE) keeps the row's rowid stable across reparses --
354
209
  // content rows are coupled to that rowid below.
355
- var insertSql = "INSERT INTO frontmatter (".concat(writableColumns.map(quoteIdent).join(', '), ") VALUES (").concat(writableColumns.map(function() {
210
+ var insertSql = "INSERT INTO frontmatter (".concat(writableColumns.map(_sharedts.quoteIdent).join(', '), ") VALUES (").concat(writableColumns.map(function() {
356
211
  return '?';
357
212
  }).join(', '), ') ON CONFLICT("path") DO UPDATE SET ').concat(writableColumns.filter(function(c) {
358
213
  return c !== 'path';
359
214
  }).map(function(c) {
360
- return "".concat(quoteIdent(c), " = excluded.").concat(quoteIdent(c));
215
+ return "".concat((0, _sharedts.quoteIdent)(c), " = excluded.").concat((0, _sharedts.quoteIdent)(c));
361
216
  }).join(', '));
362
217
  var added = toReparse.filter(function(f) {
363
218
  return !existing.has(f.relPath);
@@ -380,7 +235,7 @@ function reconcile(db, cfg, baseDir) {
380
235
  try {
381
236
  for(var _iterator1 = newColumns[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
382
237
  var col = _step1.value;
383
- db.exec("ALTER TABLE frontmatter ADD COLUMN ".concat(quoteIdent(col)));
238
+ db.exec("ALTER TABLE frontmatter ADD COLUMN ".concat((0, _sharedts.quoteIdent)(col)));
384
239
  }
385
240
  } catch (err) {
386
241
  _didIteratorError1 = true;
@@ -455,7 +310,7 @@ function reconcile(db, cfg, baseDir) {
455
310
  var insertBody = db.prepare(INSERT_CONTENT_SQL);
456
311
  // A non-default tokenizer means the tree has chosen its own scheme; a phrase query over
457
312
  // grapheme runs would be nonsense against trigram, so the sidecars stay empty.
458
- var segmenting = (0, _configts.contentTokenize)(cfg) === undefined;
313
+ var segmenting = (0, _indexts.contentTokenize)(cfg) === undefined;
459
314
  var _iteratorNormalCompletion4 = true, _didIteratorError4 = false, _iteratorError4 = undefined;
460
315
  try {
461
316
  var _loop1 = function() {
@@ -467,6 +322,7 @@ function reconcile(db, cfg, baseDir) {
467
322
  var _doc_data_col;
468
323
  if (col === 'path') return doc.relPath;
469
324
  if (col === '_mtime') return doc.mtimeMs;
325
+ if (col === '_ctime') return doc.ctimeMs;
470
326
  if (col === '_size') return doc.size;
471
327
  // Written per parse, unlike _rank, which a feature pass owns and the upsert skips.
472
328
  if (col === '_parse_error') return doc.parseError;
@@ -587,18 +443,16 @@ function reconcile(db, cfg, baseDir) {
587
443
  // Reconcile's own write-transaction duration, for open()'s derived busy_timeout (F):
588
444
  // keep the observed max so a big watcher reconcile's lock hold is what the next open bounds its wait against.
589
445
  var durationMs = Date.now() - txStart;
590
- var prevRaw = getMeta(db, 'reconcile_max_ms');
446
+ var prevRaw = (0, _sharedts.getMeta)(db, 'reconcile_max_ms');
591
447
  // -1, not 0, so a genuinely 0ms first reconcile (sub-millisecond, common on a tiny tree)
592
448
  // still gets recorded instead of losing to the "nothing recorded yet" default.
593
449
  var prevMax = prevRaw === null ? -1 : Number(prevRaw);
594
- if (durationMs > prevMax) setMeta(db, 'reconcile_max_ms', String(durationMs));
450
+ if (durationMs > prevMax) (0, _sharedts.setMeta)(db, 'reconcile_max_ms', String(durationMs));
595
451
  return {
596
452
  parsed: parsedDocs.length,
597
453
  warnings: warnings
598
454
  };
599
455
  }
600
- // Segment keys that moved between two feature signatures (see config.featureSignature's
601
- // format: global features, embed provider, tokenize, then one segment per preset).
602
456
  function changedSignatureKeys(before, after) {
603
457
  var keyOf = function keyOf(part) {
604
458
  return part.startsWith('preset:') ? part.split(':').slice(0, 2).join(':') : part.split(':')[0];
@@ -656,7 +510,6 @@ function changedSignatureKeys(before, after) {
656
510
  }
657
511
  return changed;
658
512
  }
659
- // Names what moved, for the rebuild notice.
660
513
  function signatureDiff(before, after) {
661
514
  var changed = changedSignatureKeys(before, after);
662
515
  var label = function label(key) {
@@ -664,12 +517,6 @@ function signatureDiff(before, after) {
664
517
  };
665
518
  return changed.size === 0 ? 'features' : _to_consumable_array(changed).map(label).join(', ');
666
519
  }
667
- // The tokenize-only rebuild in open(): content is dropped and repopulated from files already
668
- // listed in frontmatter, which itself is untouched. Frontmatter, links, sections, and
669
- // embeddings are file-derived and tokenizer-independent, so they survive. No feature extractors
670
- // run here -- doc.search (title/summary/text) is all content population needs. Returns
671
- // parseFile's per-file warnings (e.g. a bad date) so open() can surface them -- mtimes are
672
- // untouched, so reconcile() never reparses these files and would otherwise never emit them again.
673
520
  function rebuildContentTable(db, cfg, baseDir) {
674
521
  var known = new Set(db.prepare('SELECT "path" FROM frontmatter').all().map(function(r) {
675
522
  return r.path;
@@ -677,7 +524,7 @@ function rebuildContentTable(db, cfg, baseDir) {
677
524
  var files = (0, _scants.listFiles)(cfg, baseDir).filter(function(f) {
678
525
  return known.has(f.relPath);
679
526
  });
680
- var segmenting = (0, _configts.contentTokenize)(cfg) === undefined;
527
+ var segmenting = (0, _indexts.contentTokenize)(cfg) === undefined;
681
528
  var insertBody = db.prepare(INSERT_CONTENT_SQL);
682
529
  var warnings = [];
683
530
  db.exec('BEGIN');
@@ -712,88 +559,4 @@ function rebuildContentTable(db, cfg, baseDir) {
712
559
  }
713
560
  return warnings;
714
561
  }
715
- function open(cfg) {
716
- var _getMeta;
717
- var stateDir = (0, _nodepath.join)(cfg.baseDir, _configts.STATE_DIR);
718
- (0, _nodefs.mkdirSync)(stateDir, {
719
- recursive: true
720
- });
721
- var dbPath = (0, _nodepath.join)(stateDir, DB_FILENAME);
722
- var db = new _nodesqlite.DatabaseSync(dbPath);
723
- db.exec('PRAGMA journal_mode = WAL');
724
- // Covers a concurrent watcher's bulk reconcile (~5s for 500 files at 26k notes). A query
725
- // that outwaits it still fails loudly.
726
- db.exec('PRAGMA busy_timeout = 30000');
727
- registerFunctions(db, (0, _configts.contentTokenize)(cfg) === undefined);
728
- db.exec('CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT)');
729
- // Before the rebuild branch below, never after: that branch deletes the cache, so a typo'd
730
- // tokenizer validated later would cost a full re-index (and re-embed) to reach its own error.
731
- var tokenize = resolveTokenize(db, cfg);
732
- // Schema-version or feature-set mismatch: reconcile only reparses changed files, so an
733
- // old cache can't be patched incrementally -- rebuild instead (cheap: nothing expensive lives here).
734
- var version = getMeta(db, 'schema_version');
735
- var features = getMeta(db, 'features');
736
- var wantFeatures = (0, _configts.featureSignature)(cfg);
737
- var tokenizeOnlyRebuild = false;
738
- if (version !== null && version !== SCHEMA_VERSION || features !== null && features !== wantFeatures) {
739
- // Indexing derives from presets, so a config edit rebuilding the cache must say so and
740
- // name what changed -- silent rebuilds make derived indexing look like a hang or a bug.
741
- if (version !== null && version !== SCHEMA_VERSION) {
742
- console.error('sense: cache format changed (new sensemaking version); rebuilding the index');
743
- db.close();
744
- clearCache(cfg);
745
- return open(cfg);
746
- }
747
- var changedKeys = changedSignatureKeys(features !== null && features !== void 0 ? features : '', wantFeatures);
748
- // Only the tokenizer moved: frontmatter, links, sections, and embeddings are file-derived
749
- // and tokenizer-independent, so they don't need re-deriving. Everything else -- a preset
750
- // edit, an embed model change -- still takes the full clear/reopen below.
751
- if (changedKeys.size === 1 && changedKeys.has('tokenize')) {
752
- console.error('sense: config change (content tokenizer) rebuilds the text index; vectors, links, and sections are kept');
753
- db.exec('DROP TABLE content');
754
- tokenizeOnlyRebuild = true;
755
- } else {
756
- var changed = signatureDiff(features !== null && features !== void 0 ? features : '', wantFeatures);
757
- console.error("sense: config change (".concat(changed, ") rebuilds the index"));
758
- db.close();
759
- clearCache(cfg);
760
- return open(cfg);
761
- }
762
- }
763
- // Meta can lie after a crash between table creation and the signature write; the table's
764
- // own DDL cannot. A mismatch here rebuilds no matter what meta says. A tokenize-only rebuild
765
- // just dropped content above, so storedTokenize sees no table and this guard is skipped
766
- // naturally rather than needing its own case.
767
- var stored = storedTokenize(db);
768
- if (stored !== null && stored !== tokenize) {
769
- console.error('sense: cache was built with a different content tokenizer; rebuilding the index');
770
- db.close();
771
- clearCache(cfg);
772
- return open(cfg);
773
- }
774
- ensureSchema(db, cfg, tokenize);
775
- var rebuildWarnings = [];
776
- if (tokenizeOnlyRebuild) {
777
- rebuildWarnings = rebuildContentTable(db, cfg, cfg.baseDir);
778
- setMeta(db, 'features', wantFeatures);
779
- }
780
- // 3x the largest reconcile this cache has recorded, floored at 30s and capped at 10min.
781
- // Installed before reconcile() -- that call is the one that races a watcher's transaction.
782
- var recordedMaxMs = Number((_getMeta = getMeta(db, 'reconcile_max_ms')) !== null && _getMeta !== void 0 ? _getMeta : '0');
783
- db.exec("PRAGMA busy_timeout = ".concat(Math.min(Math.max(30000, 3 * recordedMaxMs), 600000)));
784
- var _reconcile = reconcile(db, cfg, cfg.baseDir), parsed = _reconcile.parsed, warnings = _reconcile.warnings;
785
- return {
786
- db: db,
787
- cfg: cfg,
788
- dbPath: dbPath,
789
- parsed: parsed,
790
- warnings: _to_consumable_array(rebuildWarnings).concat(_to_consumable_array(warnings))
791
- };
792
- }
793
- function clearCache(cfg) {
794
- (0, _nodefs.rmSync)((0, _nodepath.join)(cfg.baseDir, _configts.STATE_DIR), {
795
- recursive: true,
796
- force: true
797
- });
798
- }
799
562
  /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/db/reconcile.ts"],"sourcesContent":["import type { DatabaseSync, StatementSync } from 'node:sqlite';\nimport type { Config } from '../config/index.ts';\nimport { contentTokenize } from '../config/index.ts';\nimport { SenseError } from '../errors.ts';\nimport { activeFeatures } from '../features/index.ts';\nimport type { ReconcileDelta } from '../features/types.ts';\nimport { progress } from '../progress.ts';\nimport type { ParsedDoc } from '../scan.ts';\nimport { listFiles, parseFile, RESERVED_COLUMNS } from '../scan.ts';\nimport { segmentField } from '../segment.ts';\nimport { getColumns, getMeta, quoteIdent, setMeta } from './shared.ts';\n\n// Feature-owned columns (`_rank`) must stay out of the upsert: a reparse would null the last\n// computed value on every touch, not just the reconciles that recompute it.\nconst CORE_FRONTMATTER_COLUMNS = new Set(['path', '_mtime', '_ctime', '_size', '_parse_error']);\n\n// SQLite's compile-time SQLITE_MAX_COLUMN, default 2000 (https://www.sqlite.org/limits.html).\nconst MAX_FRONTMATTER_COLUMNS = 2000;\n\n// Shared by reconcile() and the tokenize-only rebuild in open(), so both prepare the same\n// literal instead of two copies drifting apart.\nconst INSERT_CONTENT_SQL = `INSERT INTO content (rowid, title, summary, text, \"path\", title_seg, summary_seg, text_seg) VALUES ((SELECT rowid FROM frontmatter WHERE \"path\" = ?), ?, ?, ?, ?, ?, ?, ?)`;\n\n// Shared by reconcile() and the tokenize-only rebuild in open(), so content population is\n// defined once. Assumes the frontmatter row for doc.relPath already exists (rowid lookup).\nfunction insertContentRow(insertBody: StatementSync, doc: ParsedDoc, segmenting: boolean): void {\n insertBody.run(doc.relPath, doc.search.title, doc.search.summary, doc.search.text, doc.relPath, segmenting ? segmentField(doc.search.title) : '', segmenting ? segmentField(doc.search.summary) : '', segmenting ? segmentField(doc.search.text) : '');\n}\n\nexport function reconcile(db: DatabaseSync, cfg: Config, baseDir: string): { parsed: number; warnings: string[] } {\n const files = listFiles(cfg, baseDir);\n const currentSet = new Set(files.map((f) => f.relPath));\n\n const existingRows = db.prepare(`SELECT \"path\", \"_mtime\", \"_size\" FROM frontmatter`).all() as Array<{\n path: string;\n _mtime: number;\n _size: number;\n }>;\n const existing = new Map(existingRows.map((r) => [r.path, r]));\n const vanished = existingRows.filter((r) => !currentSet.has(r.path)).map((r) => r.path);\n\n const toReparse = files.filter((f) => {\n const row = existing.get(f.relPath);\n return !row || row._mtime !== f.mtimeMs || row._size !== f.size;\n });\n\n if (vanished.length === 0 && toReparse.length === 0) return { parsed: 0, warnings: [] };\n\n const features = activeFeatures(cfg);\n const seenColumns = getColumns(db);\n const newColumns: string[] = [];\n const parsedDocs: ParsedDoc[] = [];\n const warnings: string[] = [];\n\n // Bulk reparses (a sync, a cold build) are the long silences a query can hit; short\n // reconciles stay silent (progress() has a threshold).\n const report = progress('reparsing files', toReparse.length);\n let parsedCount = 0;\n for (const file of toReparse) {\n // A doc only gets extract/store from features that apply to it (currently: embed, via\n // FileStat.embed -- true iff the config names an embedding model).\n const fileFeatures = features.filter((feature) => !feature.enabledForFile || feature.enabledForFile(cfg, file));\n const { doc, warnings: fileWarnings } = parseFile(file, fileFeatures);\n report.tick(++parsedCount);\n warnings.push(...fileWarnings);\n for (const key of Object.keys(doc.data)) {\n if (!seenColumns.has(key)) {\n seenColumns.add(key);\n newColumns.push(key);\n }\n }\n parsedDocs.push(doc);\n }\n report.finish();\n\n const allColumns = [...seenColumns];\n // Fence before ALTERing: SQLite's own failure past this point is a raw\n // \"too many columns on sqlite_altertab_frontmatter\" with no indication of the boundary or the levers.\n if (allColumns.length > MAX_FRONTMATTER_COLUMNS) {\n throw new SenseError(\n 'COLUMN_LIMIT',\n `frontmatter would need ${allColumns.length} columns, crossing SQLite's compile-time SQLITE_MAX_COLUMN limit (default ${MAX_FRONTMATTER_COLUMNS}; see https://www.sqlite.org/limits.html). Narrow the presets' include globs so fewer/other files are indexed, or fix whatever is generating unbounded frontmatter keys.`\n );\n }\n // Columns the frontmatter upsert actually writes: core + parsed frontmatter keys, never a\n // feature-owned reserved column (see CORE_FRONTMATTER_COLUMNS above).\n const writableColumns = allColumns.filter((c) => CORE_FRONTMATTER_COLUMNS.has(c) || !RESERVED_COLUMNS.has(c));\n // ON CONFLICT UPDATE (not OR REPLACE) keeps the row's rowid stable across reparses --\n // content rows are coupled to that rowid below.\n const insertSql = `INSERT INTO frontmatter (${writableColumns.map(quoteIdent).join(', ')}) VALUES (${writableColumns.map(() => '?').join(', ')}) ON CONFLICT(\"path\") DO UPDATE SET ${writableColumns\n .filter((c) => c !== 'path')\n .map((c) => `${quoteIdent(c)} = excluded.${quoteIdent(c)}`)\n .join(', ')}`;\n\n const added = toReparse.filter((f) => !existing.has(f.relPath)).map((f) => f.relPath);\n const delta: ReconcileDelta = { files, reparsed: parsedDocs.map((d) => d.relPath), added, vanished };\n\n const txStart = Date.now();\n db.exec('BEGIN');\n try {\n for (const col of newColumns) db.exec(`ALTER TABLE frontmatter ADD COLUMN ${quoteIdent(col)}`);\n // FTS5 has no upsert, so delete-before-insert into `content`; coupled to the\n // frontmatter rowid (indexed via its PRIMARY KEY) instead of the UNINDEXED `path`\n // column, which a per-row DELETE would otherwise scan the whole table to find.\n const delBody = db.prepare(`DELETE FROM content WHERE rowid = (SELECT rowid FROM frontmatter WHERE \"path\" = ?)`);\n const delPresetFiles = db.prepare(`DELETE FROM preset_files WHERE \"path\" = ?`);\n const insertPresetFile = db.prepare(`INSERT INTO preset_files (\"path\", preset) VALUES (?, ?)`);\n if (vanished.length > 0) {\n const del = db.prepare(`DELETE FROM frontmatter WHERE \"path\" = ?`);\n for (const path of vanished) {\n // content delete must run first: it looks up the frontmatter rowid by path, which\n // the frontmatter delete below would otherwise have already removed.\n delBody.run(path);\n del.run(path);\n delPresetFiles.run(path);\n for (const feature of features) feature.remove?.(db, path, delta);\n }\n }\n if (parsedDocs.length > 0) {\n const insert = db.prepare(insertSql);\n const insertBody = db.prepare(INSERT_CONTENT_SQL);\n // A non-default tokenizer means the tree has chosen its own scheme; a phrase query over\n // grapheme runs would be nonsense against trigram, so the sidecars stay empty.\n const segmenting = contentTokenize(cfg) === undefined;\n for (const doc of parsedDocs) {\n const values = writableColumns.map((col) => {\n if (col === 'path') return doc.relPath;\n if (col === '_mtime') return doc.mtimeMs;\n if (col === '_ctime') return doc.ctimeMs;\n if (col === '_size') return doc.size;\n // Written per parse, unlike _rank, which a feature pass owns and the upsert skips.\n if (col === '_parse_error') return doc.parseError;\n return doc.data[col] ?? null;\n });\n // Frontmatter upsert first: content's rowid lookup below depends on this row existing.\n insert.run(...values);\n // Only for docs that have rows: an unconditional delete made cold crawls quadratic.\n if (existing.has(doc.relPath)) {\n delBody.run(doc.relPath);\n for (const feature of features) feature.remove?.(db, doc.relPath, delta);\n }\n insertContentRow(insertBody, doc, segmenting);\n // A preset edit forces a full rebuild, so an unchanged doc's coverage is already\n // correct; new docs have nothing to clear, which keeps cold builds linear.\n if (existing.has(doc.relPath)) delPresetFiles.run(doc.relPath);\n for (const presetName of doc.presets) insertPresetFile.run(doc.relPath, presetName);\n for (const feature of features) feature.store?.(db, doc.relPath, doc.extracted[feature.name], delta);\n }\n }\n for (const feature of features) feature.afterReconcile?.(db, delta);\n db.exec('COMMIT');\n } catch (err) {\n db.exec('ROLLBACK');\n throw err;\n }\n\n // Reconcile's own write-transaction duration, for open()'s derived busy_timeout (F):\n // keep the observed max so a big watcher reconcile's lock hold is what the next open bounds its wait against.\n const durationMs = Date.now() - txStart;\n const prevRaw = getMeta(db, 'reconcile_max_ms');\n // -1, not 0, so a genuinely 0ms first reconcile (sub-millisecond, common on a tiny tree)\n // still gets recorded instead of losing to the \"nothing recorded yet\" default.\n const prevMax = prevRaw === null ? -1 : Number(prevRaw);\n if (durationMs > prevMax) setMeta(db, 'reconcile_max_ms', String(durationMs));\n\n return { parsed: parsedDocs.length, warnings };\n}\n\n// Segment keys that moved between two feature signatures (see config.featureSignature's\n// format: global features, embed provider, tokenize, then one segment per preset).\nexport function changedSignatureKeys(before: string, after: string): Set<string> {\n const keyOf = (part: string) => (part.startsWith('preset:') ? part.split(':').slice(0, 2).join(':') : part.split(':')[0]);\n const parse = (sig: string) => new Map(sig.split('|').map((part) => [keyOf(part), part]));\n const a = parse(before);\n const b = parse(after);\n const changed = new Set<string>();\n for (const [key, val] of b) if (a.get(key) !== val) changed.add(key);\n for (const key of a.keys()) if (!b.has(key)) changed.add(key);\n return changed;\n}\n\n// Names what moved, for the rebuild notice.\nexport function signatureDiff(before: string, after: string): string {\n const changed = changedSignatureKeys(before, after);\n const label = (key: string) => (key === 'embed' ? 'embed settings' : key === 'tokenize' ? 'content tokenizer' : key.startsWith('preset:') ? `preset \"${key.slice(7)}\"` : 'features');\n return changed.size === 0 ? 'features' : [...changed].map(label).join(', ');\n}\n\n// The tokenize-only rebuild in open(): content is dropped and repopulated from files already\n// listed in frontmatter, which itself is untouched. Frontmatter, links, sections, and\n// embeddings are file-derived and tokenizer-independent, so they survive. No feature extractors\n// run here -- doc.search (title/summary/text) is all content population needs. Returns\n// parseFile's per-file warnings (e.g. a bad date) so open() can surface them -- mtimes are\n// untouched, so reconcile() never reparses these files and would otherwise never emit them again.\nexport function rebuildContentTable(db: DatabaseSync, cfg: Config, baseDir: string): string[] {\n const known = new Set((db.prepare('SELECT \"path\" FROM frontmatter').all() as Array<{ path: string }>).map((r) => r.path));\n const files = listFiles(cfg, baseDir).filter((f) => known.has(f.relPath));\n const segmenting = contentTokenize(cfg) === undefined;\n const insertBody = db.prepare(INSERT_CONTENT_SQL);\n const warnings: string[] = [];\n db.exec('BEGIN');\n try {\n for (const file of files) {\n const { doc, warnings: fileWarnings } = parseFile(file);\n warnings.push(...fileWarnings);\n insertContentRow(insertBody, doc, segmenting);\n }\n db.exec('COMMIT');\n } catch (err) {\n db.exec('ROLLBACK');\n throw err;\n }\n return warnings;\n}\n"],"names":["changedSignatureKeys","rebuildContentTable","reconcile","signatureDiff","CORE_FRONTMATTER_COLUMNS","Set","MAX_FRONTMATTER_COLUMNS","INSERT_CONTENT_SQL","insertContentRow","insertBody","doc","segmenting","run","relPath","search","title","summary","text","segmentField","db","cfg","baseDir","files","listFiles","currentSet","map","f","existingRows","prepare","all","existing","Map","r","path","vanished","filter","has","toReparse","row","get","_mtime","mtimeMs","_size","size","length","parsed","warnings","features","activeFeatures","seenColumns","getColumns","newColumns","parsedDocs","report","progress","parsedCount","file","fileFeatures","feature","enabledForFile","parseFile","fileWarnings","tick","push","Object","keys","data","key","add","finish","allColumns","SenseError","writableColumns","c","RESERVED_COLUMNS","insertSql","quoteIdent","join","added","delta","reparsed","d","txStart","Date","now","exec","col","delBody","delPresetFiles","insertPresetFile","del","remove","insert","contentTokenize","undefined","values","ctimeMs","parseError","presets","presetName","store","extracted","name","afterReconcile","err","durationMs","prevRaw","getMeta","prevMax","Number","setMeta","String","before","after","keyOf","part","startsWith","split","slice","parse","sig","a","b","changed","val","label","known"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { DatabaseSync } from 'node:sqlite';
2
+ export declare function quoteIdent(name: string): string;
3
+ export declare function getColumns(db: DatabaseSync): Set<string>;
4
+ export declare function getMeta(db: DatabaseSync, key: string): string | null;
5
+ export declare function setMeta(db: DatabaseSync, key: string, value: string | null): void;
@@ -0,0 +1,5 @@
1
+ import type { DatabaseSync } from 'node:sqlite';
2
+ export declare function quoteIdent(name: string): string;
3
+ export declare function getColumns(db: DatabaseSync): Set<string>;
4
+ export declare function getMeta(db: DatabaseSync, key: string): string | null;
5
+ export declare function setMeta(db: DatabaseSync, key: string, value: string | null): void;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get getColumns () {
13
+ return getColumns;
14
+ },
15
+ get getMeta () {
16
+ return getMeta;
17
+ },
18
+ get quoteIdent () {
19
+ return quoteIdent;
20
+ },
21
+ get setMeta () {
22
+ return setMeta;
23
+ }
24
+ });
25
+ function quoteIdent(name) {
26
+ return '"'.concat(name.split('"').join('""'), '"');
27
+ }
28
+ function getColumns(db) {
29
+ var rows = db.prepare('PRAGMA table_info(frontmatter)').all();
30
+ return new Set(rows.map(function(r) {
31
+ return r.name;
32
+ }));
33
+ }
34
+ function getMeta(db, key) {
35
+ var row = db.prepare('SELECT value FROM meta WHERE key = ?').get(key);
36
+ return row ? row.value : null;
37
+ }
38
+ function setMeta(db, key, value) {
39
+ if (value === null) {
40
+ db.prepare('DELETE FROM meta WHERE key = ?').run(key);
41
+ return;
42
+ }
43
+ db.prepare('INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value').run(key, value);
44
+ }
45
+ /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/db/shared.ts"],"sourcesContent":["import type { DatabaseSync } from 'node:sqlite';\n\n// SQL and meta-table primitives both open() and reconcile() need, kept below both so\n// neither imports the other's module.\n\nexport function quoteIdent(name: string): string {\n return `\"${name.split('\"').join('\"\"')}\"`;\n}\n\nexport function getColumns(db: DatabaseSync): Set<string> {\n const rows = db.prepare('PRAGMA table_info(frontmatter)').all() as Array<{ name: string }>;\n return new Set(rows.map((r) => r.name));\n}\n\nexport function getMeta(db: DatabaseSync, key: string): string | null {\n const row = db.prepare('SELECT value FROM meta WHERE key = ?').get(key) as { value: string } | undefined;\n return row ? row.value : null;\n}\n\nexport function setMeta(db: DatabaseSync, key: string, value: string | null): void {\n if (value === null) {\n db.prepare('DELETE FROM meta WHERE key = ?').run(key);\n return;\n }\n db.prepare('INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value').run(key, value);\n}\n"],"names":["getColumns","getMeta","quoteIdent","setMeta","name","split","join","db","rows","prepare","all","Set","map","r","key","row","get","value","run"],"mappings":";;;;;;;;;;;QASgBA;eAAAA;;QAKAC;eAAAA;;QATAC;eAAAA;;QAcAC;eAAAA;;;AAdT,SAASD,WAAWE,IAAY;IACrC,OAAO,AAAC,IAA8B,OAA3BA,KAAKC,KAAK,CAAC,KAAKC,IAAI,CAAC,OAAM;AACxC;AAEO,SAASN,WAAWO,EAAgB;IACzC,IAAMC,OAAOD,GAAGE,OAAO,CAAC,kCAAkCC,GAAG;IAC7D,OAAO,IAAIC,IAAIH,KAAKI,GAAG,CAAC,SAACC;eAAMA,EAAET,IAAI;;AACvC;AAEO,SAASH,QAAQM,EAAgB,EAAEO,GAAW;IACnD,IAAMC,MAAMR,GAAGE,OAAO,CAAC,wCAAwCO,GAAG,CAACF;IACnE,OAAOC,MAAMA,IAAIE,KAAK,GAAG;AAC3B;AAEO,SAASd,QAAQI,EAAgB,EAAEO,GAAW,EAAEG,KAAoB;IACzE,IAAIA,UAAU,MAAM;QAClBV,GAAGE,OAAO,CAAC,kCAAkCS,GAAG,CAACJ;QACjD;IACF;IACAP,GAAGE,OAAO,CAAC,qGAAqGS,GAAG,CAACJ,KAAKG;AAC3H"}
@@ -1,5 +1,5 @@
1
1
  import type { DatabaseSync } from 'node:sqlite';
2
- import type { Config } from '../config.js';
2
+ import type { Config } from '../config/index.js';
3
3
  import type { Feature } from './types.js';
4
4
  export interface EmbedProvider {
5
5
  id: string;
@@ -1,5 +1,5 @@
1
1
  import type { DatabaseSync } from 'node:sqlite';
2
- import type { Config } from '../config.js';
2
+ import type { Config } from '../config/index.js';
3
3
  import type { Feature } from './types.js';
4
4
  export interface EmbedProvider {
5
5
  id: string;
@@ -46,7 +46,7 @@ _export(exports, {
46
46
  var _nodefs = require("node:fs");
47
47
  var _nodeos = require("node:os");
48
48
  var _nodepath = require("node:path");
49
- var _configts = require("../config.js");
49
+ var _indexts = require("../config/index.js");
50
50
  var _errorsts = require("../errors.js");
51
51
  var _progressts = require("../progress.js");
52
52
  var _scants = require("../scan.js");
@@ -399,7 +399,7 @@ function hasModelFiles(model) {
399
399
  });
400
400
  }
401
401
  function modelPresent(cfg) {
402
- var e = (0, _configts.embedConfig)(cfg);
402
+ var e = (0, _indexts.embedConfig)(cfg);
403
403
  if (!e) return false;
404
404
  return e.type === 'api' || hasModelFiles(e.model);
405
405
  }
@@ -707,7 +707,7 @@ function apiProvider(model, url, keyEnv) {
707
707
  var providers = new Map();
708
708
  function getProvider(cfg) {
709
709
  var _e_url;
710
- var e = (0, _configts.embedConfig)(cfg);
710
+ var e = (0, _indexts.embedConfig)(cfg);
711
711
  if (!e) throw new _errorsts.SenseError('EMBED_DISABLED', 'this tree has no embedding model: add an "embed" block naming one to sense.config.json, then run `sense download`');
712
712
  var sig = "".concat(e.type, ":").concat(e.model, ":").concat((_e_url = e.url) !== null && _e_url !== void 0 ? _e_url : '');
713
713
  var p = providers.get(sig);
@@ -823,6 +823,7 @@ function embedPending(db, cfg, baseDir) {
823
823
  relPath: path,
824
824
  absPath: (0, _nodepath.join)(baseDir, path),
825
825
  mtimeMs: 0,
826
+ ctimeMs: 0,
826
827
  size: 0,
827
828
  presets: [],
828
829
  embed: true