sensemaking 0.2.0 → 0.3.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 (182) hide show
  1. package/README.md +107 -126
  2. package/dist/cjs/cli.js +172 -182
  3. package/dist/cjs/cli.js.map +1 -1
  4. package/dist/cjs/commands/find.d.cts +3 -0
  5. package/dist/cjs/commands/find.d.ts +3 -0
  6. package/dist/cjs/commands/find.js +73 -0
  7. package/dist/cjs/commands/find.js.map +1 -0
  8. package/dist/cjs/commands/index.d.cts +5 -0
  9. package/dist/cjs/commands/index.d.ts +5 -0
  10. package/dist/cjs/commands/index.js +94 -0
  11. package/dist/cjs/commands/index.js.map +1 -0
  12. package/dist/cjs/commands/init.d.cts +3 -0
  13. package/dist/cjs/commands/init.d.ts +3 -0
  14. package/dist/cjs/commands/init.js +18 -0
  15. package/dist/cjs/commands/init.js.map +1 -0
  16. package/dist/cjs/commands/map.d.cts +3 -0
  17. package/dist/cjs/commands/map.d.ts +3 -0
  18. package/dist/cjs/commands/map.js +21 -0
  19. package/dist/cjs/commands/map.js.map +1 -0
  20. package/dist/cjs/commands/named.d.cts +2 -0
  21. package/dist/cjs/commands/named.d.ts +2 -0
  22. package/dist/cjs/commands/named.js +23 -0
  23. package/dist/cjs/commands/named.js.map +1 -0
  24. package/dist/cjs/commands/peek.d.cts +3 -0
  25. package/dist/cjs/commands/peek.d.ts +3 -0
  26. package/dist/cjs/commands/peek.js +69 -0
  27. package/dist/cjs/commands/peek.js.map +1 -0
  28. package/dist/cjs/commands/query.d.cts +3 -0
  29. package/dist/cjs/commands/query.d.ts +3 -0
  30. package/dist/cjs/commands/query.js +43 -0
  31. package/dist/cjs/commands/query.js.map +1 -0
  32. package/dist/cjs/commands/rebuild.d.cts +3 -0
  33. package/dist/cjs/commands/rebuild.d.ts +3 -0
  34. package/dist/cjs/commands/rebuild.js +20 -0
  35. package/dist/cjs/commands/rebuild.js.map +1 -0
  36. package/dist/cjs/commands/status.d.cts +3 -0
  37. package/dist/cjs/commands/status.d.ts +3 -0
  38. package/dist/cjs/commands/status.js +24 -0
  39. package/dist/cjs/commands/status.js.map +1 -0
  40. package/dist/cjs/commands/types.d.cts +15 -0
  41. package/dist/cjs/commands/types.d.ts +15 -0
  42. package/dist/cjs/commands/types.js +5 -0
  43. package/dist/cjs/commands/types.js.map +1 -0
  44. package/dist/cjs/commands/vault.d.cts +6 -0
  45. package/dist/cjs/commands/vault.d.ts +6 -0
  46. package/dist/cjs/commands/vault.js +94 -0
  47. package/dist/cjs/commands/vault.js.map +1 -0
  48. package/dist/cjs/commands/watch.d.cts +3 -0
  49. package/dist/cjs/commands/watch.d.ts +3 -0
  50. package/dist/cjs/commands/watch.js +173 -0
  51. package/dist/cjs/commands/watch.js.map +1 -0
  52. package/dist/cjs/config.d.cts +11 -1
  53. package/dist/cjs/config.d.ts +11 -1
  54. package/dist/cjs/config.js +82 -9
  55. package/dist/cjs/config.js.map +1 -1
  56. package/dist/cjs/db.d.cts +1 -1
  57. package/dist/cjs/db.d.ts +1 -1
  58. package/dist/cjs/db.js +107 -16
  59. package/dist/cjs/db.js.map +1 -1
  60. package/dist/cjs/errors.d.cts +1 -1
  61. package/dist/cjs/errors.d.ts +1 -1
  62. package/dist/cjs/errors.js.map +1 -1
  63. package/dist/cjs/features/index.d.cts +7 -0
  64. package/dist/cjs/features/index.d.ts +7 -0
  65. package/dist/cjs/features/index.js +36 -0
  66. package/dist/cjs/features/index.js.map +1 -0
  67. package/dist/cjs/features/links.d.cts +4 -0
  68. package/dist/cjs/features/links.d.ts +4 -0
  69. package/dist/cjs/features/links.js +217 -0
  70. package/dist/cjs/features/links.js.map +1 -0
  71. package/dist/cjs/features/rank.d.cts +2 -0
  72. package/dist/cjs/features/rank.d.ts +2 -0
  73. package/dist/cjs/features/rank.js +95 -0
  74. package/dist/cjs/features/rank.js.map +1 -0
  75. package/dist/cjs/features/sections.d.cts +9 -0
  76. package/dist/cjs/features/sections.d.ts +9 -0
  77. package/dist/cjs/features/sections.js +54 -0
  78. package/dist/cjs/features/sections.js.map +1 -0
  79. package/dist/cjs/features/types.d.cts +11 -0
  80. package/dist/cjs/features/types.d.ts +11 -0
  81. package/dist/cjs/features/types.js +5 -0
  82. package/dist/cjs/features/types.js.map +1 -0
  83. package/dist/cjs/graph.d.cts +7 -0
  84. package/dist/cjs/graph.d.ts +7 -0
  85. package/dist/cjs/graph.js +237 -0
  86. package/dist/cjs/graph.js.map +1 -0
  87. package/dist/cjs/index.d.cts +9 -2
  88. package/dist/cjs/index.d.ts +9 -2
  89. package/dist/cjs/index.js +39 -0
  90. package/dist/cjs/index.js.map +1 -1
  91. package/dist/cjs/output.d.cts +21 -0
  92. package/dist/cjs/output.d.ts +21 -0
  93. package/dist/cjs/output.js +112 -3
  94. package/dist/cjs/output.js.map +1 -1
  95. package/dist/cjs/scan.d.cts +3 -1
  96. package/dist/cjs/scan.d.ts +3 -1
  97. package/dist/cjs/scan.js +62 -14
  98. package/dist/cjs/scan.js.map +1 -1
  99. package/dist/cjs/verbs.d.cts +31 -0
  100. package/dist/cjs/verbs.d.ts +31 -0
  101. package/dist/cjs/verbs.js +284 -0
  102. package/dist/cjs/verbs.js.map +1 -0
  103. package/dist/esm/cli.js +63 -107
  104. package/dist/esm/cli.js.map +1 -1
  105. package/dist/esm/commands/find.d.ts +3 -0
  106. package/dist/esm/commands/find.js +14 -0
  107. package/dist/esm/commands/find.js.map +1 -0
  108. package/dist/esm/commands/index.d.ts +5 -0
  109. package/dist/esm/commands/index.js +13 -0
  110. package/dist/esm/commands/index.js.map +1 -0
  111. package/dist/esm/commands/init.d.ts +3 -0
  112. package/dist/esm/commands/init.js +7 -0
  113. package/dist/esm/commands/init.js.map +1 -0
  114. package/dist/esm/commands/map.d.ts +3 -0
  115. package/dist/esm/commands/map.js +10 -0
  116. package/dist/esm/commands/map.js.map +1 -0
  117. package/dist/esm/commands/named.d.ts +2 -0
  118. package/dist/esm/commands/named.js +12 -0
  119. package/dist/esm/commands/named.js.map +1 -0
  120. package/dist/esm/commands/peek.d.ts +3 -0
  121. package/dist/esm/commands/peek.js +12 -0
  122. package/dist/esm/commands/peek.js.map +1 -0
  123. package/dist/esm/commands/query.d.ts +3 -0
  124. package/dist/esm/commands/query.js +7 -0
  125. package/dist/esm/commands/query.js.map +1 -0
  126. package/dist/esm/commands/rebuild.d.ts +3 -0
  127. package/dist/esm/commands/rebuild.js +9 -0
  128. package/dist/esm/commands/rebuild.js.map +1 -0
  129. package/dist/esm/commands/status.d.ts +3 -0
  130. package/dist/esm/commands/status.js +13 -0
  131. package/dist/esm/commands/status.js.map +1 -0
  132. package/dist/esm/commands/types.d.ts +15 -0
  133. package/dist/esm/commands/types.js +1 -0
  134. package/dist/esm/commands/types.js.map +1 -0
  135. package/dist/esm/commands/vault.d.ts +6 -0
  136. package/dist/esm/commands/vault.js +29 -0
  137. package/dist/esm/commands/vault.js.map +1 -0
  138. package/dist/esm/commands/watch.d.ts +3 -0
  139. package/dist/esm/commands/watch.js +19 -0
  140. package/dist/esm/commands/watch.js.map +1 -0
  141. package/dist/esm/config.d.ts +11 -1
  142. package/dist/esm/config.js +68 -12
  143. package/dist/esm/config.js.map +1 -1
  144. package/dist/esm/db.d.ts +1 -1
  145. package/dist/esm/db.js +27 -9
  146. package/dist/esm/db.js.map +1 -1
  147. package/dist/esm/errors.d.ts +1 -1
  148. package/dist/esm/errors.js.map +1 -1
  149. package/dist/esm/features/index.d.ts +7 -0
  150. package/dist/esm/features/index.js +14 -0
  151. package/dist/esm/features/index.js.map +1 -0
  152. package/dist/esm/features/links.d.ts +4 -0
  153. package/dist/esm/features/links.js +81 -0
  154. package/dist/esm/features/links.js.map +1 -0
  155. package/dist/esm/features/rank.d.ts +2 -0
  156. package/dist/esm/features/rank.js +17 -0
  157. package/dist/esm/features/rank.js.map +1 -0
  158. package/dist/esm/features/sections.d.ts +9 -0
  159. package/dist/esm/features/sections.js +41 -0
  160. package/dist/esm/features/sections.js.map +1 -0
  161. package/dist/esm/features/types.d.ts +11 -0
  162. package/dist/esm/features/types.js +3 -0
  163. package/dist/esm/features/types.js.map +1 -0
  164. package/dist/esm/graph.d.ts +7 -0
  165. package/dist/esm/graph.js +79 -0
  166. package/dist/esm/graph.js.map +1 -0
  167. package/dist/esm/index.d.ts +9 -2
  168. package/dist/esm/index.js +4 -1
  169. package/dist/esm/index.js.map +1 -1
  170. package/dist/esm/output.d.ts +21 -0
  171. package/dist/esm/output.js +28 -0
  172. package/dist/esm/output.js.map +1 -1
  173. package/dist/esm/scan.d.ts +3 -1
  174. package/dist/esm/scan.js +56 -7
  175. package/dist/esm/scan.js.map +1 -1
  176. package/dist/esm/verbs.d.ts +31 -0
  177. package/dist/esm/verbs.js +139 -0
  178. package/dist/esm/verbs.js.map +1 -0
  179. package/package.json +4 -4
  180. package/schema.json +23 -4
  181. package/skills/sense/EXAMPLES.md +46 -81
  182. package/skills/sense/SKILL.md +58 -92
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return _default;
9
+ }
10
+ });
11
+ var _watchts = require("../watch.js");
12
+ var _vaultts = require("./vault.js");
13
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
14
+ try {
15
+ var info = gen[key](arg);
16
+ var value = info.value;
17
+ } catch (error) {
18
+ reject(error);
19
+ return;
20
+ }
21
+ if (info.done) {
22
+ resolve(value);
23
+ } else {
24
+ Promise.resolve(value).then(_next, _throw);
25
+ }
26
+ }
27
+ function _async_to_generator(fn) {
28
+ return function() {
29
+ var self = this, args = arguments;
30
+ return new Promise(function(resolve, reject) {
31
+ var gen = fn.apply(self, args);
32
+ function _next(value) {
33
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
34
+ }
35
+ function _throw(err) {
36
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
37
+ }
38
+ _next(undefined);
39
+ });
40
+ };
41
+ }
42
+ function _ts_generator(thisArg, body) {
43
+ var f, y, t, _ = {
44
+ label: 0,
45
+ sent: function() {
46
+ if (t[0] & 1) throw t[1];
47
+ return t[1];
48
+ },
49
+ trys: [],
50
+ ops: []
51
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
52
+ return d(g, "next", {
53
+ value: verb(0)
54
+ }), d(g, "throw", {
55
+ value: verb(1)
56
+ }), d(g, "return", {
57
+ value: verb(2)
58
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
59
+ value: function() {
60
+ return this;
61
+ }
62
+ }), g;
63
+ function verb(n) {
64
+ return function(v) {
65
+ return step([
66
+ n,
67
+ v
68
+ ]);
69
+ };
70
+ }
71
+ function step(op) {
72
+ if (f) throw new TypeError("Generator is already executing.");
73
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
74
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
75
+ if (y = 0, t) op = [
76
+ op[0] & 2,
77
+ t.value
78
+ ];
79
+ switch(op[0]){
80
+ case 0:
81
+ case 1:
82
+ t = op;
83
+ break;
84
+ case 4:
85
+ _.label++;
86
+ return {
87
+ value: op[1],
88
+ done: false
89
+ };
90
+ case 5:
91
+ _.label++;
92
+ y = op[1];
93
+ op = [
94
+ 0
95
+ ];
96
+ continue;
97
+ case 7:
98
+ op = _.ops.pop();
99
+ _.trys.pop();
100
+ continue;
101
+ default:
102
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
103
+ _ = 0;
104
+ continue;
105
+ }
106
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
107
+ _.label = op[1];
108
+ break;
109
+ }
110
+ if (op[0] === 6 && _.label < t[1]) {
111
+ _.label = t[1];
112
+ t = op;
113
+ break;
114
+ }
115
+ if (t && _.label < t[2]) {
116
+ _.label = t[2];
117
+ _.ops.push(op);
118
+ break;
119
+ }
120
+ if (t[2]) _.ops.pop();
121
+ _.trys.pop();
122
+ continue;
123
+ }
124
+ op = body.call(thisArg, _);
125
+ } catch (e) {
126
+ op = [
127
+ 6,
128
+ e
129
+ ];
130
+ y = 0;
131
+ } finally{
132
+ f = t = 0;
133
+ }
134
+ if (op[0] & 5) throw op[1];
135
+ return {
136
+ value: op[0] ? op[1] : void 0,
137
+ done: true
138
+ };
139
+ }
140
+ }
141
+ var watch = function watch(ctx) {
142
+ return _async_to_generator(function() {
143
+ return _ts_generator(this, function(_state) {
144
+ switch(_state.label){
145
+ case 0:
146
+ return [
147
+ 4,
148
+ (0, _watchts.runWatch)(ctx.resolveConfig(), {
149
+ force: ctx.values.force,
150
+ onEvent: function onEvent(event) {
151
+ if (event.type === 'started') {
152
+ console.log("".concat(ctx.name, " watch: watching ").concat(event.baseDir));
153
+ console.log("".concat(ctx.name, " watch: db ").concat(event.dbPath));
154
+ } else if (event.type === 'reconciled') {
155
+ (0, _vaultts.printWarnings)(event.warnings);
156
+ if (event.parsed > 0) console.log("".concat(ctx.name, " watch: reconciled, ").concat(event.parsed, " file(s) reparsed (").concat(event.total, " total)"));
157
+ } else {
158
+ console.error("".concat(ctx.name, " watch: reconcile error: ").concat(event.message));
159
+ }
160
+ }
161
+ })
162
+ ];
163
+ case 1:
164
+ _state.sent();
165
+ return [
166
+ 2
167
+ ];
168
+ }
169
+ });
170
+ })();
171
+ };
172
+ var _default = watch;
173
+ /* 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/commands/watch.ts"],"sourcesContent":["import type { WatchEvent } from '../watch.ts';\nimport { runWatch } from '../watch.ts';\nimport type { Command } from './types.ts';\nimport { printWarnings } from './vault.ts';\n\nconst watch: Command = async (ctx) => {\n await runWatch(ctx.resolveConfig(), {\n force: ctx.values.force,\n onEvent: (event: WatchEvent) => {\n if (event.type === 'started') {\n console.log(`${ctx.name} watch: watching ${event.baseDir}`);\n console.log(`${ctx.name} watch: db ${event.dbPath}`);\n } else if (event.type === 'reconciled') {\n printWarnings(event.warnings);\n if (event.parsed > 0) console.log(`${ctx.name} watch: reconciled, ${event.parsed} file(s) reparsed (${event.total} total)`);\n } else {\n console.error(`${ctx.name} watch: reconcile error: ${event.message}`);\n }\n },\n });\n};\nexport default watch;\n"],"names":["watch","ctx","runWatch","resolveConfig","force","values","onEvent","event","type","console","log","name","baseDir","dbPath","printWarnings","warnings","parsed","total","error","message"],"mappings":";;;;+BAqBA;;;eAAA;;;uBApByB;uBAEK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE9B,IAAMA,QAAiB,eAAOC;;;;;oBAC5B;;wBAAMC,IAAAA,iBAAQ,EAACD,IAAIE,aAAa,IAAI;4BAClCC,OAAOH,IAAII,MAAM,CAACD,KAAK;4BACvBE,SAAS,SAATA,QAAUC;gCACR,IAAIA,MAAMC,IAAI,KAAK,WAAW;oCAC5BC,QAAQC,GAAG,CAAC,AAAC,GAA8BH,OAA5BN,IAAIU,IAAI,EAAC,qBAAiC,OAAdJ,MAAMK,OAAO;oCACxDH,QAAQC,GAAG,CAAC,AAAC,GAAwBH,OAAtBN,IAAIU,IAAI,EAAC,eAA0B,OAAbJ,MAAMM,MAAM;gCACnD,OAAO,IAAIN,MAAMC,IAAI,KAAK,cAAc;oCACtCM,IAAAA,sBAAa,EAACP,MAAMQ,QAAQ;oCAC5B,IAAIR,MAAMS,MAAM,GAAG,GAAGP,QAAQC,GAAG,CAAC,AAAC,GAAiCH,OAA/BN,IAAIU,IAAI,EAAC,wBAAwDJ,OAAlCA,MAAMS,MAAM,EAAC,uBAAiC,OAAZT,MAAMU,KAAK,EAAC;gCACpH,OAAO;oCACLR,QAAQS,KAAK,CAAC,AAAC,GAAsCX,OAApCN,IAAIU,IAAI,EAAC,6BAAyC,OAAdJ,MAAMY,OAAO;gCACpE;4BACF;wBACF;;;oBAbA;;;;;;IAcF;;IACA,WAAenB"}
@@ -1,18 +1,28 @@
1
1
  export declare const CONFIG_FILENAME = "sense.config.json";
2
2
  export declare const STATE_DIR = ".sense";
3
- export declare const SUPPORTED_CONFIG_VERSION = 1;
3
+ export declare const SUPPORTED_CONFIG_VERSION = 2;
4
+ export declare const FEATURE_NAMES: readonly ["links", "sections", "rank"];
5
+ export type FeatureName = (typeof FEATURE_NAMES)[number];
4
6
  export interface Config {
5
7
  $schema?: string;
6
8
  version?: number;
7
9
  scan: {
8
10
  include: string[];
9
11
  };
12
+ features?: Partial<Record<FeatureName, boolean>>;
10
13
  queries: Record<string, string>;
11
14
  }
12
15
  export interface ResolvedConfig extends Config {
13
16
  baseDir: string;
14
17
  configPath: string | null;
18
+ migratedFrom?: number;
15
19
  }
20
+ export declare function featureEnabled(cfg: Config, name: FeatureName): boolean;
21
+ export declare function enabledFeatures(cfg: Config): FeatureName[];
22
+ export declare function migrateConfig(cfg: Config): {
23
+ cfg: Config;
24
+ from: number;
25
+ };
16
26
  export declare function initConfig(dir: string): string;
17
27
  export declare function findConfigPath(startDir: string): string | null;
18
28
  export declare function loadConfig(explicitPath?: string): ResolvedConfig;
@@ -1,18 +1,28 @@
1
1
  export declare const CONFIG_FILENAME = "sense.config.json";
2
2
  export declare const STATE_DIR = ".sense";
3
- export declare const SUPPORTED_CONFIG_VERSION = 1;
3
+ export declare const SUPPORTED_CONFIG_VERSION = 2;
4
+ export declare const FEATURE_NAMES: readonly ["links", "sections", "rank"];
5
+ export type FeatureName = (typeof FEATURE_NAMES)[number];
4
6
  export interface Config {
5
7
  $schema?: string;
6
8
  version?: number;
7
9
  scan: {
8
10
  include: string[];
9
11
  };
12
+ features?: Partial<Record<FeatureName, boolean>>;
10
13
  queries: Record<string, string>;
11
14
  }
12
15
  export interface ResolvedConfig extends Config {
13
16
  baseDir: string;
14
17
  configPath: string | null;
18
+ migratedFrom?: number;
15
19
  }
20
+ export declare function featureEnabled(cfg: Config, name: FeatureName): boolean;
21
+ export declare function enabledFeatures(cfg: Config): FeatureName[];
22
+ export declare function migrateConfig(cfg: Config): {
23
+ cfg: Config;
24
+ from: number;
25
+ };
16
26
  export declare function initConfig(dir: string): string;
17
27
  export declare function findConfigPath(startDir: string): string | null;
18
28
  export declare function loadConfig(explicitPath?: string): ResolvedConfig;
@@ -12,12 +12,21 @@ _export(exports, {
12
12
  get CONFIG_FILENAME () {
13
13
  return CONFIG_FILENAME;
14
14
  },
15
+ get FEATURE_NAMES () {
16
+ return FEATURE_NAMES;
17
+ },
15
18
  get STATE_DIR () {
16
19
  return STATE_DIR;
17
20
  },
18
21
  get SUPPORTED_CONFIG_VERSION () {
19
22
  return SUPPORTED_CONFIG_VERSION;
20
23
  },
24
+ get enabledFeatures () {
25
+ return enabledFeatures;
26
+ },
27
+ get featureEnabled () {
28
+ return featureEnabled;
29
+ },
21
30
  get findConfigPath () {
22
31
  return findConfigPath;
23
32
  },
@@ -26,6 +35,9 @@ _export(exports, {
26
35
  },
27
36
  get loadConfig () {
28
37
  return loadConfig;
38
+ },
39
+ get migrateConfig () {
40
+ return migrateConfig;
29
41
  }
30
42
  });
31
43
  var _nodefs = require("node:fs");
@@ -85,23 +97,76 @@ function _object_spread_props(target, source) {
85
97
  }
86
98
  var CONFIG_FILENAME = 'sense.config.json';
87
99
  var STATE_DIR = '.sense';
88
- var SUPPORTED_CONFIG_VERSION = 1;
89
- function initConfig(dir) {
90
- var configPath = (0, _nodepath.join)(dir, CONFIG_FILENAME);
91
- if ((0, _nodefs.existsSync)(configPath)) {
92
- throw new _errorsts.SenseError('CONFIG_EXISTS', "".concat(CONFIG_FILENAME, " already exists in ").concat(dir));
100
+ var SUPPORTED_CONFIG_VERSION = 2;
101
+ var FEATURE_NAMES = [
102
+ 'links',
103
+ 'sections',
104
+ 'rank'
105
+ ];
106
+ function featureEnabled(cfg, name) {
107
+ var _cfg_features;
108
+ var enabled = ((_cfg_features = cfg.features) === null || _cfg_features === void 0 ? void 0 : _cfg_features[name]) !== false;
109
+ if (name === 'rank') return enabled && featureEnabled(cfg, 'links');
110
+ return enabled;
111
+ }
112
+ function enabledFeatures(cfg) {
113
+ return FEATURE_NAMES.filter(function(name) {
114
+ return featureEnabled(cfg, name);
115
+ });
116
+ }
117
+ // Pure per-version steps; loadConfig chains them from the file's version up to SUPPORTED_CONFIG_VERSION.
118
+ var MIGRATIONS = {
119
+ // v1 -> v2: features block introduced, everything enabled (matches the old implicit behavior of `links` etc. not existing).
120
+ 1: function(cfg) {
121
+ return _object_spread_props(_object_spread({}, cfg), {
122
+ version: 2,
123
+ features: Object.fromEntries(FEATURE_NAMES.map(function(name) {
124
+ return [
125
+ name,
126
+ true
127
+ ];
128
+ }))
129
+ });
93
130
  }
94
- var starter = {
131
+ };
132
+ function migrateConfig(cfg) {
133
+ var _cfg_version;
134
+ var from = (_cfg_version = cfg.version) !== null && _cfg_version !== void 0 ? _cfg_version : 1;
135
+ var current = cfg;
136
+ for(var v = from; v < SUPPORTED_CONFIG_VERSION; v++){
137
+ var step = MIGRATIONS[v];
138
+ if (!step) throw new _errorsts.SenseError('CONFIG_VERSION_UNSUPPORTED', "no migration from config version ".concat(v));
139
+ current = step(current);
140
+ }
141
+ return {
142
+ cfg: current,
143
+ from: from
144
+ };
145
+ }
146
+ function starterConfig() {
147
+ return {
95
148
  $schema: 'https://unpkg.com/sensemaking/schema.json',
96
- version: 1,
149
+ version: SUPPORTED_CONFIG_VERSION,
97
150
  scan: {
98
151
  include: [
99
152
  '**/*.md'
100
153
  ]
101
154
  },
155
+ features: Object.fromEntries(FEATURE_NAMES.map(function(name) {
156
+ return [
157
+ name,
158
+ true
159
+ ];
160
+ })),
102
161
  queries: {}
103
162
  };
104
- (0, _nodefs.writeFileSync)(configPath, "".concat(JSON.stringify(starter, null, 2), "\n"));
163
+ }
164
+ function initConfig(dir) {
165
+ var configPath = (0, _nodepath.join)(dir, CONFIG_FILENAME);
166
+ if ((0, _nodefs.existsSync)(configPath)) {
167
+ throw new _errorsts.SenseError('CONFIG_EXISTS', "".concat(CONFIG_FILENAME, " already exists in ").concat(dir));
168
+ }
169
+ (0, _nodefs.writeFileSync)(configPath, "".concat(JSON.stringify(starterConfig(), null, 2), "\n"));
105
170
  return configPath;
106
171
  }
107
172
  function findConfigPath(startDir) {
@@ -133,9 +198,17 @@ function loadConfig(explicitPath) {
133
198
  if (version > SUPPORTED_CONFIG_VERSION) {
134
199
  throw new _errorsts.SenseError('CONFIG_VERSION_UNSUPPORTED', "config version ".concat(version, " requires a newer sense"));
135
200
  }
201
+ var migratedFrom;
202
+ if (version < SUPPORTED_CONFIG_VERSION) {
203
+ var result = migrateConfig(cfg);
204
+ cfg = result.cfg;
205
+ migratedFrom = result.from;
206
+ (0, _nodefs.writeFileSync)(configPath, "".concat(JSON.stringify(cfg, null, 2), "\n"));
207
+ }
136
208
  return _object_spread_props(_object_spread({}, cfg), {
137
209
  baseDir: (0, _nodepath.dirname)(configPath),
138
- configPath: configPath
210
+ configPath: configPath,
211
+ migratedFrom: migratedFrom
139
212
  });
140
213
  }
141
214
  /* 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; }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/config.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { SenseError } from './errors.ts';\n\nexport const CONFIG_FILENAME = 'sense.config.json';\nexport const STATE_DIR = '.sense';\n\n// Highest sense.config.json `version` this build understands.\nexport const SUPPORTED_CONFIG_VERSION = 1;\n\nexport interface Config {\n // Editor-only pointer to schema.json; never read by sense.\n $schema?: string;\n version?: number;\n scan: { include: string[] };\n queries: Record<string, string>;\n}\n\nexport interface ResolvedConfig extends Config {\n baseDir: string;\n configPath: string | null;\n}\n\n// Refuses to overwrite an existing config.\nexport function initConfig(dir: string): string {\n const configPath = join(dir, CONFIG_FILENAME);\n if (existsSync(configPath)) {\n throw new SenseError('CONFIG_EXISTS', `${CONFIG_FILENAME} already exists in ${dir}`);\n }\n const starter: Config = {\n $schema: 'https://unpkg.com/sensemaking/schema.json',\n version: 1,\n scan: { include: ['**/*.md'] },\n queries: {},\n };\n writeFileSync(configPath, `${JSON.stringify(starter, null, 2)}\\n`);\n return configPath;\n}\n\nexport function findConfigPath(startDir: string): string | null {\n let dir = resolve(startDir);\n for (;;) {\n const candidate = join(dir, CONFIG_FILENAME);\n if (existsSync(candidate)) return candidate;\n const parent = dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\nexport function loadConfig(explicitPath?: string): ResolvedConfig {\n let configPath: string;\n if (explicitPath) {\n configPath = resolve(process.cwd(), explicitPath);\n if (!existsSync(configPath)) throw new SenseError('CONFIG_NOT_FOUND', `config not found: ${configPath}`);\n } else {\n const found = findConfigPath(process.cwd());\n if (!found) {\n throw new SenseError('CONFIG_NOT_FOUND', `could not find ${CONFIG_FILENAME} in ${process.cwd()} or any parent directory`);\n }\n configPath = found;\n }\n\n const raw = readFileSync(configPath, 'utf8');\n const cfg = JSON.parse(raw) as Config;\n\n const version = cfg.version ?? 1;\n if (version > SUPPORTED_CONFIG_VERSION) {\n throw new SenseError('CONFIG_VERSION_UNSUPPORTED', `config version ${version} requires a newer sense`);\n }\n\n return { ...cfg, baseDir: dirname(configPath), configPath };\n}\n"],"names":["CONFIG_FILENAME","STATE_DIR","SUPPORTED_CONFIG_VERSION","findConfigPath","initConfig","loadConfig","dir","configPath","join","existsSync","SenseError","starter","$schema","version","scan","include","queries","writeFileSync","JSON","stringify","startDir","resolve","candidate","parent","dirname","explicitPath","cfg","process","cwd","found","raw","readFileSync","parse","baseDir"],"mappings":";;;;;;;;;;;QAIaA;eAAAA;;QACAC;eAAAA;;QAGAC;eAAAA;;QA+BGC;eAAAA;;QAfAC;eAAAA;;QA0BAC;eAAAA;;;sBAlDwC;wBACjB;wBACZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEpB,IAAML,kBAAkB;AACxB,IAAMC,YAAY;AAGlB,IAAMC,2BAA2B;AAgBjC,SAASE,WAAWE,GAAW;IACpC,IAAMC,aAAaC,IAAAA,cAAI,EAACF,KAAKN;IAC7B,IAAIS,IAAAA,kBAAU,EAACF,aAAa;QAC1B,MAAM,IAAIG,oBAAU,CAAC,iBAAiB,AAAC,GAAuCJ,OAArCN,iBAAgB,uBAAyB,OAAJM;IAChF;IACA,IAAMK,UAAkB;QACtBC,SAAS;QACTC,SAAS;QACTC,MAAM;YAAEC,SAAS;gBAAC;aAAU;QAAC;QAC7BC,SAAS,CAAC;IACZ;IACAC,IAAAA,qBAAa,EAACV,YAAY,AAAC,GAAmC,OAAjCW,KAAKC,SAAS,CAACR,SAAS,MAAM,IAAG;IAC9D,OAAOJ;AACT;AAEO,SAASJ,eAAeiB,QAAgB;IAC7C,IAAId,MAAMe,IAAAA,iBAAO,EAACD;IAClB,OAAS;QACP,IAAME,YAAYd,IAAAA,cAAI,EAACF,KAAKN;QAC5B,IAAIS,IAAAA,kBAAU,EAACa,YAAY,OAAOA;QAClC,IAAMC,SAASC,IAAAA,iBAAO,EAAClB;QACvB,IAAIiB,WAAWjB,KAAK,OAAO;QAC3BA,MAAMiB;IACR;AACF;AAEO,SAASlB,WAAWoB,YAAqB;QAgB9BC;IAfhB,IAAInB;IACJ,IAAIkB,cAAc;QAChBlB,aAAac,IAAAA,iBAAO,EAACM,QAAQC,GAAG,IAAIH;QACpC,IAAI,CAAChB,IAAAA,kBAAU,EAACF,aAAa,MAAM,IAAIG,oBAAU,CAAC,oBAAoB,AAAC,qBAA+B,OAAXH;IAC7F,OAAO;QACL,IAAMsB,QAAQ1B,eAAewB,QAAQC,GAAG;QACxC,IAAI,CAACC,OAAO;YACV,MAAM,IAAInB,oBAAU,CAAC,oBAAoB,AAAC,kBAAuCiB,OAAtB3B,iBAAgB,QAAoB,OAAd2B,QAAQC,GAAG,IAAG;QACjG;QACArB,aAAasB;IACf;IAEA,IAAMC,MAAMC,IAAAA,oBAAY,EAACxB,YAAY;IACrC,IAAMmB,MAAMR,KAAKc,KAAK,CAACF;IAEvB,IAAMjB,WAAUa,eAAAA,IAAIb,OAAO,cAAXa,0BAAAA,eAAe;IAC/B,IAAIb,UAAUX,0BAA0B;QACtC,MAAM,IAAIQ,oBAAU,CAAC,8BAA8B,AAAC,kBAAyB,OAARG,SAAQ;IAC/E;IAEA,OAAO,wCAAKa;QAAKO,SAAST,IAAAA,iBAAO,EAACjB;QAAaA,YAAAA;;AACjD"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/config.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { SenseError } from './errors.ts';\n\nexport const CONFIG_FILENAME = 'sense.config.json';\nexport const STATE_DIR = '.sense';\n\n// Highest sense.config.json `version` this build understands. Older versions auto-migrate on load.\nexport const SUPPORTED_CONFIG_VERSION = 2;\n\n// Each feature owns its tables, parse-time extraction, and reconcile step; verbs degrade when one is off.\nexport const FEATURE_NAMES = ['links', 'sections', 'rank'] as const;\nexport type FeatureName = (typeof FEATURE_NAMES)[number];\n\nexport interface Config {\n // Editor-only pointer to schema.json; never read by sense.\n $schema?: string;\n version?: number;\n scan: { include: string[] };\n features?: Partial<Record<FeatureName, boolean>>;\n queries: Record<string, string>;\n}\n\nexport interface ResolvedConfig extends Config {\n baseDir: string;\n configPath: string | null;\n // Set when loadConfig auto-migrated the file on disk; cli reports it.\n migratedFrom?: number;\n}\n\n// Absent block or key means enabled -- features are opt-out. `rank` additionally requires `links`.\nexport function featureEnabled(cfg: Config, name: FeatureName): boolean {\n const enabled = cfg.features?.[name] !== false;\n if (name === 'rank') return enabled && featureEnabled(cfg, 'links');\n return enabled;\n}\n\nexport function enabledFeatures(cfg: Config): FeatureName[] {\n return FEATURE_NAMES.filter((name) => featureEnabled(cfg, name));\n}\n\n// Pure per-version steps; loadConfig chains them from the file's version up to SUPPORTED_CONFIG_VERSION.\nconst MIGRATIONS: Record<number, (cfg: Config) => Config> = {\n // v1 -> v2: features block introduced, everything enabled (matches the old implicit behavior of `links` etc. not existing).\n 1: (cfg) => ({ ...cfg, version: 2, features: Object.fromEntries(FEATURE_NAMES.map((name) => [name, true])) as Config['features'] }),\n};\n\nexport function migrateConfig(cfg: Config): { cfg: Config; from: number } {\n const from = cfg.version ?? 1;\n let current = cfg;\n for (let v = from; v < SUPPORTED_CONFIG_VERSION; v++) {\n const step = MIGRATIONS[v];\n if (!step) throw new SenseError('CONFIG_VERSION_UNSUPPORTED', `no migration from config version ${v}`);\n current = step(current);\n }\n return { cfg: current, from };\n}\n\nfunction starterConfig(): Config {\n return {\n $schema: 'https://unpkg.com/sensemaking/schema.json',\n version: SUPPORTED_CONFIG_VERSION,\n scan: { include: ['**/*.md'] },\n features: Object.fromEntries(FEATURE_NAMES.map((name) => [name, true])) as Config['features'],\n queries: {},\n };\n}\n\n// Refuses to overwrite an existing config.\nexport function initConfig(dir: string): string {\n const configPath = join(dir, CONFIG_FILENAME);\n if (existsSync(configPath)) {\n throw new SenseError('CONFIG_EXISTS', `${CONFIG_FILENAME} already exists in ${dir}`);\n }\n writeFileSync(configPath, `${JSON.stringify(starterConfig(), null, 2)}\\n`);\n return configPath;\n}\n\nexport function findConfigPath(startDir: string): string | null {\n let dir = resolve(startDir);\n for (;;) {\n const candidate = join(dir, CONFIG_FILENAME);\n if (existsSync(candidate)) return candidate;\n const parent = dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\nexport function loadConfig(explicitPath?: string): ResolvedConfig {\n let configPath: string;\n if (explicitPath) {\n configPath = resolve(process.cwd(), explicitPath);\n if (!existsSync(configPath)) throw new SenseError('CONFIG_NOT_FOUND', `config not found: ${configPath}`);\n } else {\n const found = findConfigPath(process.cwd());\n if (!found) {\n throw new SenseError('CONFIG_NOT_FOUND', `could not find ${CONFIG_FILENAME} in ${process.cwd()} or any parent directory`);\n }\n configPath = found;\n }\n\n const raw = readFileSync(configPath, 'utf8');\n let cfg = JSON.parse(raw) as Config;\n\n const version = cfg.version ?? 1;\n if (version > SUPPORTED_CONFIG_VERSION) {\n throw new SenseError('CONFIG_VERSION_UNSUPPORTED', `config version ${version} requires a newer sense`);\n }\n\n let migratedFrom: number | undefined;\n if (version < SUPPORTED_CONFIG_VERSION) {\n const result = migrateConfig(cfg);\n cfg = result.cfg;\n migratedFrom = result.from;\n writeFileSync(configPath, `${JSON.stringify(cfg, null, 2)}\\n`);\n }\n\n return { ...cfg, baseDir: dirname(configPath), configPath, migratedFrom };\n}\n"],"names":["CONFIG_FILENAME","FEATURE_NAMES","STATE_DIR","SUPPORTED_CONFIG_VERSION","enabledFeatures","featureEnabled","findConfigPath","initConfig","loadConfig","migrateConfig","cfg","name","enabled","features","filter","MIGRATIONS","version","Object","fromEntries","map","from","current","v","step","SenseError","starterConfig","$schema","scan","include","queries","dir","configPath","join","existsSync","writeFileSync","JSON","stringify","startDir","resolve","candidate","parent","dirname","explicitPath","process","cwd","found","raw","readFileSync","parse","migratedFrom","result","baseDir"],"mappings":"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"}
package/dist/cjs/db.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { DatabaseSync } from 'node:sqlite';
2
2
  import type { Config, ResolvedConfig } from './config.js';
3
3
  export declare const DB_FILENAME = "cache.db";
4
- export declare const SCHEMA_VERSION = "2";
4
+ export declare const SCHEMA_VERSION = "3";
5
5
  export interface OpenResult {
6
6
  db: DatabaseSync;
7
7
  cfg: ResolvedConfig;
package/dist/cjs/db.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { DatabaseSync } from 'node:sqlite';
2
2
  import type { Config, ResolvedConfig } from './config.js';
3
3
  export declare const DB_FILENAME = "cache.db";
4
- export declare const SCHEMA_VERSION = "2";
4
+ export declare const SCHEMA_VERSION = "3";
5
5
  export interface OpenResult {
6
6
  db: DatabaseSync;
7
7
  cfg: ResolvedConfig;
package/dist/cjs/db.js CHANGED
@@ -38,6 +38,7 @@ var _nodefs = require("node:fs");
38
38
  var _nodepath = require("node:path");
39
39
  var _nodesqlite = require("node:sqlite");
40
40
  var _configts = require("./config.js");
41
+ var _indexts = require("./features/index.js");
41
42
  var _scants = require("./scan.js");
42
43
  function _array_like_to_array(arr, len) {
43
44
  if (len == null || len > arr.length) len = arr.length;
@@ -65,7 +66,7 @@ function _unsupported_iterable_to_array(o, minLen) {
65
66
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
66
67
  }
67
68
  var DB_FILENAME = 'cache.db';
68
- var SCHEMA_VERSION = '2';
69
+ var SCHEMA_VERSION = '3';
69
70
  function quoteIdent(name) {
70
71
  return '"'.concat(name.split('"').join('""'), '"');
71
72
  }
@@ -99,11 +100,33 @@ function getColumns(db) {
99
100
  return r.name;
100
101
  }));
101
102
  }
102
- // Content is a separate table (not a column on frontmatter) so `SELECT * FROM frontmatter` can't dump file text into context.
103
- function ensureSchema(db) {
103
+ // Content is a separate table (not a column on frontmatter) so `SELECT * FROM frontmatter`
104
+ // can't dump file text into context. Features add their own tables after the core ones.
105
+ function ensureSchema(db, cfg) {
104
106
  db.exec('CREATE TABLE IF NOT EXISTS frontmatter ("path" TEXT PRIMARY KEY, "_mtime" REAL, "_size" INTEGER)');
105
107
  db.exec("CREATE VIRTUAL TABLE IF NOT EXISTS content USING fts5(title, summary, text, path UNINDEXED, tokenize = 'porter unicode61')");
108
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
109
+ try {
110
+ for(var _iterator = (0, _indexts.activeFeatures)(cfg)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
111
+ var feature = _step.value;
112
+ feature.schema(db);
113
+ }
114
+ } catch (err) {
115
+ _didIteratorError = true;
116
+ _iteratorError = err;
117
+ } finally{
118
+ try {
119
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
120
+ _iterator.return();
121
+ }
122
+ } finally{
123
+ if (_didIteratorError) {
124
+ throw _iteratorError;
125
+ }
126
+ }
127
+ }
106
128
  if (getMeta(db, 'schema_version') === null) setMeta(db, 'schema_version', SCHEMA_VERSION);
129
+ if (getMeta(db, 'features') === null) setMeta(db, 'features', (0, _configts.enabledFeatures)(cfg).join(','));
107
130
  }
108
131
  function getMeta(db, key) {
109
132
  var row = db.prepare('SELECT value FROM meta WHERE key = ?').get(key);
@@ -145,6 +168,7 @@ function reconcile(db, cfg, baseDir) {
145
168
  parsed: 0,
146
169
  warnings: []
147
170
  };
171
+ var features = (0, _indexts.activeFeatures)(cfg);
148
172
  var seenColumns = getColumns(db);
149
173
  var newColumns = [];
150
174
  var parsedDocs = [];
@@ -154,7 +178,7 @@ function reconcile(db, cfg, baseDir) {
154
178
  for(var _iterator = toReparse[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
155
179
  var file = _step.value;
156
180
  var _warnings;
157
- var _parseFile = (0, _scants.parseFile)(file), doc = _parseFile.doc, fileWarnings = _parseFile.warnings;
181
+ var _parseFile = (0, _scants.parseFile)(file, features), doc = _parseFile.doc, fileWarnings = _parseFile.warnings;
158
182
  (_warnings = warnings).push.apply(_warnings, _to_consumable_array(fileWarnings));
159
183
  var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
160
184
  try {
@@ -201,6 +225,7 @@ function reconcile(db, cfg, baseDir) {
201
225
  }).join(', '), ")");
202
226
  db.exec('BEGIN');
203
227
  try {
228
+ var _feature_afterReconcile;
204
229
  var _iteratorNormalCompletion2 = true, _didIteratorError2 = false, _iteratorError2 = undefined;
205
230
  try {
206
231
  for(var _iterator2 = newColumns[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true){
@@ -229,8 +254,29 @@ function reconcile(db, cfg, baseDir) {
229
254
  try {
230
255
  for(var _iterator3 = vanished[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true){
231
256
  var path = _step3.value;
257
+ var _feature_remove;
232
258
  del.run(path);
233
259
  delBody.run(path);
260
+ var _iteratorNormalCompletion4 = true, _didIteratorError4 = false, _iteratorError4 = undefined;
261
+ try {
262
+ for(var _iterator4 = features[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true){
263
+ var feature = _step4.value;
264
+ (_feature_remove = feature.remove) === null || _feature_remove === void 0 ? void 0 : _feature_remove.call(feature, db, path);
265
+ }
266
+ } catch (err) {
267
+ _didIteratorError4 = true;
268
+ _iteratorError4 = err;
269
+ } finally{
270
+ try {
271
+ if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
272
+ _iterator4.return();
273
+ }
274
+ } finally{
275
+ if (_didIteratorError4) {
276
+ throw _iteratorError4;
277
+ }
278
+ }
279
+ }
234
280
  }
235
281
  } catch (err) {
236
282
  _didIteratorError3 = true;
@@ -250,10 +296,10 @@ function reconcile(db, cfg, baseDir) {
250
296
  if (parsedDocs.length > 0) {
251
297
  var insert = db.prepare(insertSql);
252
298
  var insertBody = db.prepare('INSERT INTO content (title, summary, text, "path") VALUES (?, ?, ?, ?)');
253
- var _iteratorNormalCompletion4 = true, _didIteratorError4 = false, _iteratorError4 = undefined;
299
+ var _iteratorNormalCompletion5 = true, _didIteratorError5 = false, _iteratorError5 = undefined;
254
300
  try {
255
301
  var _loop = function() {
256
- var doc = _step4.value;
302
+ var doc = _step5.value;
257
303
  var _insert;
258
304
  var values = allColumns.map(function(col) {
259
305
  var _doc_data_col;
@@ -265,23 +311,65 @@ function reconcile(db, cfg, baseDir) {
265
311
  (_insert = insert).run.apply(_insert, _to_consumable_array(values));
266
312
  delBody.run(doc.relPath);
267
313
  insertBody.run(doc.search.title, doc.search.summary, doc.search.text, doc.relPath);
314
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
315
+ try {
316
+ for(var _iterator = features[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
317
+ var feature = _step.value;
318
+ var _feature_remove, _feature_store;
319
+ (_feature_remove = feature.remove) === null || _feature_remove === void 0 ? void 0 : _feature_remove.call(feature, db, doc.relPath);
320
+ (_feature_store = feature.store) === null || _feature_store === void 0 ? void 0 : _feature_store.call(feature, db, doc.relPath, doc.extracted[feature.name]);
321
+ }
322
+ } catch (err) {
323
+ _didIteratorError = true;
324
+ _iteratorError = err;
325
+ } finally{
326
+ try {
327
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
328
+ _iterator.return();
329
+ }
330
+ } finally{
331
+ if (_didIteratorError) {
332
+ throw _iteratorError;
333
+ }
334
+ }
335
+ }
268
336
  };
269
- for(var _iterator4 = parsedDocs[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true)_loop();
337
+ for(var _iterator5 = parsedDocs[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true)_loop();
270
338
  } catch (err) {
271
- _didIteratorError4 = true;
272
- _iteratorError4 = err;
339
+ _didIteratorError5 = true;
340
+ _iteratorError5 = err;
273
341
  } finally{
274
342
  try {
275
- if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
276
- _iterator4.return();
343
+ if (!_iteratorNormalCompletion5 && _iterator5.return != null) {
344
+ _iterator5.return();
277
345
  }
278
346
  } finally{
279
- if (_didIteratorError4) {
280
- throw _iteratorError4;
347
+ if (_didIteratorError5) {
348
+ throw _iteratorError5;
281
349
  }
282
350
  }
283
351
  }
284
352
  }
353
+ var _iteratorNormalCompletion6 = true, _didIteratorError6 = false, _iteratorError6 = undefined;
354
+ try {
355
+ for(var _iterator6 = features[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true){
356
+ var feature1 = _step6.value;
357
+ (_feature_afterReconcile = feature1.afterReconcile) === null || _feature_afterReconcile === void 0 ? void 0 : _feature_afterReconcile.call(feature1, db, files);
358
+ }
359
+ } catch (err) {
360
+ _didIteratorError6 = true;
361
+ _iteratorError6 = err;
362
+ } finally{
363
+ try {
364
+ if (!_iteratorNormalCompletion6 && _iterator6.return != null) {
365
+ _iterator6.return();
366
+ }
367
+ } finally{
368
+ if (_didIteratorError6) {
369
+ throw _iteratorError6;
370
+ }
371
+ }
372
+ }
285
373
  db.exec('COMMIT');
286
374
  } catch (err) {
287
375
  db.exec('ROLLBACK');
@@ -303,9 +391,12 @@ function open(cfg) {
303
391
  db.exec('PRAGMA busy_timeout = 5000');
304
392
  registerFunctions(db);
305
393
  db.exec('CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT)');
306
- // Schema version mismatch: reconcile only reparses changed files, so an old cache can't be patched up incrementally -- rebuild instead.
394
+ // Schema-version or feature-set mismatch: reconcile only reparses changed files, so an
395
+ // old cache can't be patched incrementally -- rebuild instead (cheap: nothing expensive lives here).
307
396
  var version = getMeta(db, 'schema_version');
308
- if (version !== null && version !== SCHEMA_VERSION) {
397
+ var features = getMeta(db, 'features');
398
+ var wantFeatures = (0, _configts.enabledFeatures)(cfg).join(',');
399
+ if (version !== null && version !== SCHEMA_VERSION || features !== null && features !== wantFeatures) {
309
400
  db.close();
310
401
  (0, _nodefs.rmSync)(stateDir, {
311
402
  recursive: true,
@@ -313,7 +404,7 @@ function open(cfg) {
313
404
  });
314
405
  return open(cfg);
315
406
  }
316
- ensureSchema(db);
407
+ ensureSchema(db, cfg);
317
408
  var _reconcile = reconcile(db, cfg, cfg.baseDir), parsed = _reconcile.parsed, warnings = _reconcile.warnings;
318
409
  return {
319
410
  db: db,