akm-cli 0.9.0-beta.44 → 0.9.0-beta.46

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 (80) hide show
  1. package/dist/cli/shared.js +28 -0
  2. package/dist/cli.js +1 -2
  3. package/dist/commands/env/env-cli.js +16 -24
  4. package/dist/commands/env/secret-cli.js +12 -20
  5. package/dist/commands/graph/graph-cli.js +5 -13
  6. package/dist/commands/graph/graph.js +3 -3
  7. package/dist/commands/health.js +5 -0
  8. package/dist/commands/improve/consolidate/chunking.js +141 -0
  9. package/dist/commands/improve/consolidate/eligibility.js +64 -0
  10. package/dist/commands/improve/consolidate/merge.js +145 -0
  11. package/dist/commands/improve/consolidate/sanitize.js +231 -0
  12. package/dist/commands/improve/consolidate/types.js +4 -0
  13. package/dist/commands/improve/consolidate.js +20 -571
  14. package/dist/commands/improve/distill.js +5 -9
  15. package/dist/commands/improve/eligibility.js +434 -0
  16. package/dist/commands/improve/extract-cli.js +9 -1
  17. package/dist/commands/improve/extract.js +5 -19
  18. package/dist/commands/improve/improve-auto-accept.js +4 -8
  19. package/dist/commands/improve/improve-cli.js +35 -60
  20. package/dist/commands/improve/improve-result-file.js +5 -23
  21. package/dist/commands/improve/improve-session.js +58 -0
  22. package/dist/commands/improve/improve.js +107 -3606
  23. package/dist/commands/improve/locks.js +154 -0
  24. package/dist/commands/improve/loop-stages.js +1079 -0
  25. package/dist/commands/improve/preparation.js +1963 -0
  26. package/dist/commands/improve/recombine.js +6 -12
  27. package/dist/commands/improve/reflect.js +29 -34
  28. package/dist/commands/proposal/drain.js +25 -48
  29. package/dist/commands/proposal/proposal-cli.js +21 -31
  30. package/dist/commands/proposal/validators/proposals.js +3 -7
  31. package/dist/commands/read/curate.js +70 -14
  32. package/dist/commands/read/knowledge.js +2 -2
  33. package/dist/commands/sources/self-update.js +2 -2
  34. package/dist/commands/sources/stash-cli.js +9 -37
  35. package/dist/commands/tasks/tasks-cli.js +19 -27
  36. package/dist/commands/wiki-cli.js +21 -35
  37. package/dist/core/config/config.js +18 -2
  38. package/dist/core/events.js +3 -7
  39. package/dist/core/logs-db.js +6 -63
  40. package/dist/core/parse.js +36 -16
  41. package/dist/core/state/migrations.js +714 -0
  42. package/dist/core/state-db.js +28 -779
  43. package/dist/indexer/db/db.js +82 -216
  44. package/dist/indexer/graph/graph-extraction.js +2 -0
  45. package/dist/indexer/indexer.js +11 -112
  46. package/dist/indexer/passes/dir-staleness.js +114 -0
  47. package/dist/indexer/search/search-source.js +10 -24
  48. package/dist/integrations/agent/runner-dispatch.js +59 -0
  49. package/dist/llm/client.js +22 -11
  50. package/dist/llm/graph-extract.js +58 -42
  51. package/dist/llm/memory-infer.js +34 -22
  52. package/dist/llm/metadata-enhance.js +35 -30
  53. package/dist/llm/structured-call.js +49 -0
  54. package/dist/output/shapes/passthrough.js +0 -1
  55. package/dist/registry/providers/skills-sh.js +21 -147
  56. package/dist/registry/providers/static-index.js +15 -157
  57. package/dist/registry/resolve.js +22 -9
  58. package/dist/scripts/migrate-storage.js +892 -1186
  59. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +214 -179
  60. package/dist/setup/setup.js +26 -5
  61. package/dist/sources/providers/filesystem.js +0 -1
  62. package/dist/sources/providers/git-install.js +206 -0
  63. package/dist/sources/providers/git-provider.js +234 -0
  64. package/dist/sources/providers/git-stash.js +248 -0
  65. package/dist/sources/providers/git.js +10 -671
  66. package/dist/sources/providers/npm.js +2 -6
  67. package/dist/sources/providers/sync-from-ref.js +9 -1
  68. package/dist/sources/providers/website.js +2 -3
  69. package/dist/sources/website-ingest.js +51 -9
  70. package/dist/sources/wiki-fetchers/registry.js +53 -0
  71. package/dist/sources/wiki-fetchers/youtube.js +181 -0
  72. package/dist/storage/database.js +45 -10
  73. package/dist/storage/managed-db.js +82 -0
  74. package/dist/storage/repositories/registry-cache.js +92 -0
  75. package/dist/tasks/runner.js +5 -13
  76. package/dist/workflows/runtime/runs.js +1 -117
  77. package/dist/workflows/runtime/workflow-asset-loader.js +125 -0
  78. package/package.json +5 -5
  79. package/dist/commands/db-cli.js +0 -23
  80. package/dist/indexer/db/db-backup.js +0 -376
@@ -62,8 +62,8 @@ var init_warn = () => {};
62
62
 
63
63
  // node_modules/dotenv/lib/main.js
64
64
  var require_main = __commonJS((exports, module) => {
65
- var fs2 = __require("fs");
66
- var path = __require("path");
65
+ var fs3 = __require("fs");
66
+ var path2 = __require("path");
67
67
  var os = __require("os");
68
68
  var crypto = __require("crypto");
69
69
  var TIPS = [
@@ -196,7 +196,7 @@ var require_main = __commonJS((exports, module) => {
196
196
  if (options && options.path && options.path.length > 0) {
197
197
  if (Array.isArray(options.path)) {
198
198
  for (const filepath of options.path) {
199
- if (fs2.existsSync(filepath)) {
199
+ if (fs3.existsSync(filepath)) {
200
200
  possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
201
201
  }
202
202
  }
@@ -204,15 +204,15 @@ var require_main = __commonJS((exports, module) => {
204
204
  possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
205
205
  }
206
206
  } else {
207
- possibleVaultPath = path.resolve(process.cwd(), ".env.vault");
207
+ possibleVaultPath = path2.resolve(process.cwd(), ".env.vault");
208
208
  }
209
- if (fs2.existsSync(possibleVaultPath)) {
209
+ if (fs3.existsSync(possibleVaultPath)) {
210
210
  return possibleVaultPath;
211
211
  }
212
212
  return null;
213
213
  }
214
214
  function _resolveHome(envPath) {
215
- return envPath[0] === "~" ? path.join(os.homedir(), envPath.slice(1)) : envPath;
215
+ return envPath[0] === "~" ? path2.join(os.homedir(), envPath.slice(1)) : envPath;
216
216
  }
217
217
  function _configVault(options) {
218
218
  const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
@@ -229,7 +229,7 @@ var require_main = __commonJS((exports, module) => {
229
229
  return { parsed };
230
230
  }
231
231
  function configDotenv(options) {
232
- const dotenvPath = path.resolve(process.cwd(), ".env");
232
+ const dotenvPath = path2.resolve(process.cwd(), ".env");
233
233
  let encoding = "utf8";
234
234
  let processEnv = process.env;
235
235
  if (options && options.processEnv != null) {
@@ -257,13 +257,13 @@ var require_main = __commonJS((exports, module) => {
257
257
  }
258
258
  let lastError;
259
259
  const parsedAll = {};
260
- for (const path2 of optionPaths) {
260
+ for (const path3 of optionPaths) {
261
261
  try {
262
- const parsed = DotenvModule.parse(fs2.readFileSync(path2, { encoding }));
262
+ const parsed = DotenvModule.parse(fs3.readFileSync(path3, { encoding }));
263
263
  DotenvModule.populate(parsedAll, parsed, options);
264
264
  } catch (e) {
265
265
  if (debug) {
266
- _debug(`failed to load ${path2} ${e.message}`);
266
+ _debug(`failed to load ${path3} ${e.message}`);
267
267
  }
268
268
  lastError = e;
269
269
  }
@@ -276,7 +276,7 @@ var require_main = __commonJS((exports, module) => {
276
276
  const shortPaths = [];
277
277
  for (const filePath of optionPaths) {
278
278
  try {
279
- const relative = path.relative(process.cwd(), filePath);
279
+ const relative = path2.relative(process.cwd(), filePath);
280
280
  shortPaths.push(relative);
281
281
  } catch (e) {
282
282
  if (debug) {
@@ -438,7 +438,7 @@ var init_errors = __esm(() => {
438
438
  });
439
439
 
440
440
  // src/commands/env/env.ts
441
- import fs2 from "fs";
441
+ import fs3 from "fs";
442
442
  function scanKeys(text) {
443
443
  const keys = [];
444
444
  const seen = new Set;
@@ -465,9 +465,9 @@ function scanComments(text) {
465
465
  return comments;
466
466
  }
467
467
  function listKeys(envPath) {
468
- if (!fs2.existsSync(envPath))
468
+ if (!fs3.existsSync(envPath))
469
469
  return { keys: [], comments: [] };
470
- const text = fs2.readFileSync(envPath, "utf8");
470
+ const text = fs3.readFileSync(envPath, "utf8");
471
471
  return { keys: scanKeys(text), comments: scanComments(text) };
472
472
  }
473
473
  var import_dotenv, ASSIGN_RE;
@@ -550,17 +550,17 @@ var require_visit = __commonJS((exports) => {
550
550
  visit.BREAK = BREAK;
551
551
  visit.SKIP = SKIP;
552
552
  visit.REMOVE = REMOVE;
553
- function visit_(key, node, visitor, path) {
554
- const ctrl = callVisitor(key, node, visitor, path);
553
+ function visit_(key, node, visitor, path2) {
554
+ const ctrl = callVisitor(key, node, visitor, path2);
555
555
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
556
- replaceNode(key, path, ctrl);
557
- return visit_(key, ctrl, visitor, path);
556
+ replaceNode(key, path2, ctrl);
557
+ return visit_(key, ctrl, visitor, path2);
558
558
  }
559
559
  if (typeof ctrl !== "symbol") {
560
560
  if (identity.isCollection(node)) {
561
- path = Object.freeze(path.concat(node));
561
+ path2 = Object.freeze(path2.concat(node));
562
562
  for (let i = 0;i < node.items.length; ++i) {
563
- const ci = visit_(i, node.items[i], visitor, path);
563
+ const ci = visit_(i, node.items[i], visitor, path2);
564
564
  if (typeof ci === "number")
565
565
  i = ci - 1;
566
566
  else if (ci === BREAK)
@@ -571,13 +571,13 @@ var require_visit = __commonJS((exports) => {
571
571
  }
572
572
  }
573
573
  } else if (identity.isPair(node)) {
574
- path = Object.freeze(path.concat(node));
575
- const ck = visit_("key", node.key, visitor, path);
574
+ path2 = Object.freeze(path2.concat(node));
575
+ const ck = visit_("key", node.key, visitor, path2);
576
576
  if (ck === BREAK)
577
577
  return BREAK;
578
578
  else if (ck === REMOVE)
579
579
  node.key = null;
580
- const cv = visit_("value", node.value, visitor, path);
580
+ const cv = visit_("value", node.value, visitor, path2);
581
581
  if (cv === BREAK)
582
582
  return BREAK;
583
583
  else if (cv === REMOVE)
@@ -598,17 +598,17 @@ var require_visit = __commonJS((exports) => {
598
598
  visitAsync.BREAK = BREAK;
599
599
  visitAsync.SKIP = SKIP;
600
600
  visitAsync.REMOVE = REMOVE;
601
- async function visitAsync_(key, node, visitor, path) {
602
- const ctrl = await callVisitor(key, node, visitor, path);
601
+ async function visitAsync_(key, node, visitor, path2) {
602
+ const ctrl = await callVisitor(key, node, visitor, path2);
603
603
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
604
- replaceNode(key, path, ctrl);
605
- return visitAsync_(key, ctrl, visitor, path);
604
+ replaceNode(key, path2, ctrl);
605
+ return visitAsync_(key, ctrl, visitor, path2);
606
606
  }
607
607
  if (typeof ctrl !== "symbol") {
608
608
  if (identity.isCollection(node)) {
609
- path = Object.freeze(path.concat(node));
609
+ path2 = Object.freeze(path2.concat(node));
610
610
  for (let i = 0;i < node.items.length; ++i) {
611
- const ci = await visitAsync_(i, node.items[i], visitor, path);
611
+ const ci = await visitAsync_(i, node.items[i], visitor, path2);
612
612
  if (typeof ci === "number")
613
613
  i = ci - 1;
614
614
  else if (ci === BREAK)
@@ -619,13 +619,13 @@ var require_visit = __commonJS((exports) => {
619
619
  }
620
620
  }
621
621
  } else if (identity.isPair(node)) {
622
- path = Object.freeze(path.concat(node));
623
- const ck = await visitAsync_("key", node.key, visitor, path);
622
+ path2 = Object.freeze(path2.concat(node));
623
+ const ck = await visitAsync_("key", node.key, visitor, path2);
624
624
  if (ck === BREAK)
625
625
  return BREAK;
626
626
  else if (ck === REMOVE)
627
627
  node.key = null;
628
- const cv = await visitAsync_("value", node.value, visitor, path);
628
+ const cv = await visitAsync_("value", node.value, visitor, path2);
629
629
  if (cv === BREAK)
630
630
  return BREAK;
631
631
  else if (cv === REMOVE)
@@ -652,23 +652,23 @@ var require_visit = __commonJS((exports) => {
652
652
  }
653
653
  return visitor;
654
654
  }
655
- function callVisitor(key, node, visitor, path) {
655
+ function callVisitor(key, node, visitor, path2) {
656
656
  if (typeof visitor === "function")
657
- return visitor(key, node, path);
657
+ return visitor(key, node, path2);
658
658
  if (identity.isMap(node))
659
- return visitor.Map?.(key, node, path);
659
+ return visitor.Map?.(key, node, path2);
660
660
  if (identity.isSeq(node))
661
- return visitor.Seq?.(key, node, path);
661
+ return visitor.Seq?.(key, node, path2);
662
662
  if (identity.isPair(node))
663
- return visitor.Pair?.(key, node, path);
663
+ return visitor.Pair?.(key, node, path2);
664
664
  if (identity.isScalar(node))
665
- return visitor.Scalar?.(key, node, path);
665
+ return visitor.Scalar?.(key, node, path2);
666
666
  if (identity.isAlias(node))
667
- return visitor.Alias?.(key, node, path);
667
+ return visitor.Alias?.(key, node, path2);
668
668
  return;
669
669
  }
670
- function replaceNode(key, path, node) {
671
- const parent = path[path.length - 1];
670
+ function replaceNode(key, path2, node) {
671
+ const parent = path2[path2.length - 1];
672
672
  if (identity.isCollection(parent)) {
673
673
  parent.items[key] = node;
674
674
  } else if (identity.isPair(parent)) {
@@ -1227,10 +1227,10 @@ var require_Collection = __commonJS((exports) => {
1227
1227
  var createNode = require_createNode();
1228
1228
  var identity = require_identity();
1229
1229
  var Node = require_Node();
1230
- function collectionFromPath(schema, path, value) {
1230
+ function collectionFromPath(schema, path2, value) {
1231
1231
  let v = value;
1232
- for (let i = path.length - 1;i >= 0; --i) {
1233
- const k = path[i];
1232
+ for (let i = path2.length - 1;i >= 0; --i) {
1233
+ const k = path2[i];
1234
1234
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
1235
1235
  const a = [];
1236
1236
  a[k] = v;
@@ -1249,7 +1249,7 @@ var require_Collection = __commonJS((exports) => {
1249
1249
  sourceObjects: new Map
1250
1250
  });
1251
1251
  }
1252
- var isEmptyPath = (path) => path == null || typeof path === "object" && !!path[Symbol.iterator]().next().done;
1252
+ var isEmptyPath = (path2) => path2 == null || typeof path2 === "object" && !!path2[Symbol.iterator]().next().done;
1253
1253
 
1254
1254
  class Collection extends Node.NodeBase {
1255
1255
  constructor(type, schema) {
@@ -1270,11 +1270,11 @@ var require_Collection = __commonJS((exports) => {
1270
1270
  copy.range = this.range.slice();
1271
1271
  return copy;
1272
1272
  }
1273
- addIn(path, value) {
1274
- if (isEmptyPath(path))
1273
+ addIn(path2, value) {
1274
+ if (isEmptyPath(path2))
1275
1275
  this.add(value);
1276
1276
  else {
1277
- const [key, ...rest] = path;
1277
+ const [key, ...rest] = path2;
1278
1278
  const node = this.get(key, true);
1279
1279
  if (identity.isCollection(node))
1280
1280
  node.addIn(rest, value);
@@ -1284,8 +1284,8 @@ var require_Collection = __commonJS((exports) => {
1284
1284
  throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
1285
1285
  }
1286
1286
  }
1287
- deleteIn(path) {
1288
- const [key, ...rest] = path;
1287
+ deleteIn(path2) {
1288
+ const [key, ...rest] = path2;
1289
1289
  if (rest.length === 0)
1290
1290
  return this.delete(key);
1291
1291
  const node = this.get(key, true);
@@ -1294,8 +1294,8 @@ var require_Collection = __commonJS((exports) => {
1294
1294
  else
1295
1295
  throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
1296
1296
  }
1297
- getIn(path, keepScalar) {
1298
- const [key, ...rest] = path;
1297
+ getIn(path2, keepScalar) {
1298
+ const [key, ...rest] = path2;
1299
1299
  const node = this.get(key, true);
1300
1300
  if (rest.length === 0)
1301
1301
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -1310,15 +1310,15 @@ var require_Collection = __commonJS((exports) => {
1310
1310
  return n == null || allowScalar && identity.isScalar(n) && n.value == null && !n.commentBefore && !n.comment && !n.tag;
1311
1311
  });
1312
1312
  }
1313
- hasIn(path) {
1314
- const [key, ...rest] = path;
1313
+ hasIn(path2) {
1314
+ const [key, ...rest] = path2;
1315
1315
  if (rest.length === 0)
1316
1316
  return this.has(key);
1317
1317
  const node = this.get(key, true);
1318
1318
  return identity.isCollection(node) ? node.hasIn(rest) : false;
1319
1319
  }
1320
- setIn(path, value) {
1321
- const [key, ...rest] = path;
1320
+ setIn(path2, value) {
1321
+ const [key, ...rest] = path2;
1322
1322
  if (rest.length === 0) {
1323
1323
  this.set(key, value);
1324
1324
  } else {
@@ -3711,9 +3711,9 @@ var require_Document = __commonJS((exports) => {
3711
3711
  if (assertCollection(this.contents))
3712
3712
  this.contents.add(value);
3713
3713
  }
3714
- addIn(path, value) {
3714
+ addIn(path2, value) {
3715
3715
  if (assertCollection(this.contents))
3716
- this.contents.addIn(path, value);
3716
+ this.contents.addIn(path2, value);
3717
3717
  }
3718
3718
  createAlias(node, name) {
3719
3719
  if (!node.anchor) {
@@ -3762,30 +3762,30 @@ var require_Document = __commonJS((exports) => {
3762
3762
  delete(key) {
3763
3763
  return assertCollection(this.contents) ? this.contents.delete(key) : false;
3764
3764
  }
3765
- deleteIn(path) {
3766
- if (Collection.isEmptyPath(path)) {
3765
+ deleteIn(path2) {
3766
+ if (Collection.isEmptyPath(path2)) {
3767
3767
  if (this.contents == null)
3768
3768
  return false;
3769
3769
  this.contents = null;
3770
3770
  return true;
3771
3771
  }
3772
- return assertCollection(this.contents) ? this.contents.deleteIn(path) : false;
3772
+ return assertCollection(this.contents) ? this.contents.deleteIn(path2) : false;
3773
3773
  }
3774
3774
  get(key, keepScalar) {
3775
3775
  return identity.isCollection(this.contents) ? this.contents.get(key, keepScalar) : undefined;
3776
3776
  }
3777
- getIn(path, keepScalar) {
3778
- if (Collection.isEmptyPath(path))
3777
+ getIn(path2, keepScalar) {
3778
+ if (Collection.isEmptyPath(path2))
3779
3779
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
3780
- return identity.isCollection(this.contents) ? this.contents.getIn(path, keepScalar) : undefined;
3780
+ return identity.isCollection(this.contents) ? this.contents.getIn(path2, keepScalar) : undefined;
3781
3781
  }
3782
3782
  has(key) {
3783
3783
  return identity.isCollection(this.contents) ? this.contents.has(key) : false;
3784
3784
  }
3785
- hasIn(path) {
3786
- if (Collection.isEmptyPath(path))
3785
+ hasIn(path2) {
3786
+ if (Collection.isEmptyPath(path2))
3787
3787
  return this.contents !== undefined;
3788
- return identity.isCollection(this.contents) ? this.contents.hasIn(path) : false;
3788
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path2) : false;
3789
3789
  }
3790
3790
  set(key, value) {
3791
3791
  if (this.contents == null) {
@@ -3794,13 +3794,13 @@ var require_Document = __commonJS((exports) => {
3794
3794
  this.contents.set(key, value);
3795
3795
  }
3796
3796
  }
3797
- setIn(path, value) {
3798
- if (Collection.isEmptyPath(path)) {
3797
+ setIn(path2, value) {
3798
+ if (Collection.isEmptyPath(path2)) {
3799
3799
  this.contents = value;
3800
3800
  } else if (this.contents == null) {
3801
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path), value);
3801
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path2), value);
3802
3802
  } else if (assertCollection(this.contents)) {
3803
- this.contents.setIn(path, value);
3803
+ this.contents.setIn(path2, value);
3804
3804
  }
3805
3805
  }
3806
3806
  setSchema(version, options = {}) {
@@ -5695,9 +5695,9 @@ var require_cst_visit = __commonJS((exports) => {
5695
5695
  visit.BREAK = BREAK;
5696
5696
  visit.SKIP = SKIP;
5697
5697
  visit.REMOVE = REMOVE;
5698
- visit.itemAtPath = (cst, path) => {
5698
+ visit.itemAtPath = (cst, path2) => {
5699
5699
  let item = cst;
5700
- for (const [field, index] of path) {
5700
+ for (const [field, index] of path2) {
5701
5701
  const tok = item?.[field];
5702
5702
  if (tok && "items" in tok) {
5703
5703
  item = tok.items[index];
@@ -5706,23 +5706,23 @@ var require_cst_visit = __commonJS((exports) => {
5706
5706
  }
5707
5707
  return item;
5708
5708
  };
5709
- visit.parentCollection = (cst, path) => {
5710
- const parent = visit.itemAtPath(cst, path.slice(0, -1));
5711
- const field = path[path.length - 1][0];
5709
+ visit.parentCollection = (cst, path2) => {
5710
+ const parent = visit.itemAtPath(cst, path2.slice(0, -1));
5711
+ const field = path2[path2.length - 1][0];
5712
5712
  const coll = parent?.[field];
5713
5713
  if (coll && "items" in coll)
5714
5714
  return coll;
5715
5715
  throw new Error("Parent collection not found");
5716
5716
  };
5717
- function _visit(path, item, visitor) {
5718
- let ctrl = visitor(item, path);
5717
+ function _visit(path2, item, visitor) {
5718
+ let ctrl = visitor(item, path2);
5719
5719
  if (typeof ctrl === "symbol")
5720
5720
  return ctrl;
5721
5721
  for (const field of ["key", "value"]) {
5722
5722
  const token = item[field];
5723
5723
  if (token && "items" in token) {
5724
5724
  for (let i = 0;i < token.items.length; ++i) {
5725
- const ci = _visit(Object.freeze(path.concat([[field, i]])), token.items[i], visitor);
5725
+ const ci = _visit(Object.freeze(path2.concat([[field, i]])), token.items[i], visitor);
5726
5726
  if (typeof ci === "number")
5727
5727
  i = ci - 1;
5728
5728
  else if (ci === BREAK)
@@ -5733,10 +5733,10 @@ var require_cst_visit = __commonJS((exports) => {
5733
5733
  }
5734
5734
  }
5735
5735
  if (typeof ctrl === "function" && field === "key")
5736
- ctrl = ctrl(item, path);
5736
+ ctrl = ctrl(item, path2);
5737
5737
  }
5738
5738
  }
5739
- return typeof ctrl === "function" ? ctrl(item, path) : ctrl;
5739
+ return typeof ctrl === "function" ? ctrl(item, path2) : ctrl;
5740
5740
  }
5741
5741
  exports.visit = visit;
5742
5742
  });
@@ -7005,14 +7005,14 @@ var require_parser = __commonJS((exports) => {
7005
7005
  case "scalar":
7006
7006
  case "single-quoted-scalar":
7007
7007
  case "double-quoted-scalar": {
7008
- const fs3 = this.flowScalar(this.type);
7008
+ const fs4 = this.flowScalar(this.type);
7009
7009
  if (atNextItem || it.value) {
7010
- map.items.push({ start, key: fs3, sep: [] });
7010
+ map.items.push({ start, key: fs4, sep: [] });
7011
7011
  this.onKeyLine = true;
7012
7012
  } else if (it.sep) {
7013
- this.stack.push(fs3);
7013
+ this.stack.push(fs4);
7014
7014
  } else {
7015
- Object.assign(it, { key: fs3, sep: [] });
7015
+ Object.assign(it, { key: fs4, sep: [] });
7016
7016
  this.onKeyLine = true;
7017
7017
  }
7018
7018
  return;
@@ -7140,13 +7140,13 @@ var require_parser = __commonJS((exports) => {
7140
7140
  case "scalar":
7141
7141
  case "single-quoted-scalar":
7142
7142
  case "double-quoted-scalar": {
7143
- const fs3 = this.flowScalar(this.type);
7143
+ const fs4 = this.flowScalar(this.type);
7144
7144
  if (!it || it.value)
7145
- fc.items.push({ start: [], key: fs3, sep: [] });
7145
+ fc.items.push({ start: [], key: fs4, sep: [] });
7146
7146
  else if (it.sep)
7147
- this.stack.push(fs3);
7147
+ this.stack.push(fs4);
7148
7148
  else
7149
- Object.assign(it, { key: fs3, sep: [] });
7149
+ Object.assign(it, { key: fs4, sep: [] });
7150
7150
  return;
7151
7151
  }
7152
7152
  case "flow-map-end":
@@ -7583,11 +7583,11 @@ var init_metadata_contributors = __esm(() => {
7583
7583
  });
7584
7584
 
7585
7585
  // src/indexer/passes/metadata.ts
7586
- import fs3 from "fs";
7586
+ import fs4 from "fs";
7587
7587
  function extractDescriptionFromComments(filePath) {
7588
7588
  let content;
7589
7589
  try {
7590
- content = fs3.readFileSync(filePath, "utf8");
7590
+ content = fs4.readFileSync(filePath, "utf8");
7591
7591
  } catch {
7592
7592
  return null;
7593
7593
  }
@@ -7693,7 +7693,7 @@ var init_validator = __esm(() => {
7693
7693
  // src/workflows/parser.ts
7694
7694
  function parseWorkflow(markdown, source) {
7695
7695
  const errors2 = [];
7696
- const path = source.path;
7696
+ const path2 = source.path;
7697
7697
  const lines = markdown.split(/\r?\n/);
7698
7698
  const totalLines = lines.length;
7699
7699
  const fmBlock = parseFrontmatterBlock(markdown);
@@ -7701,7 +7701,7 @@ function parseWorkflow(markdown, source) {
7701
7701
  const fmData = readFrontmatter(fmBlock?.frontmatter, errors2);
7702
7702
  const description = readDescription(fmData);
7703
7703
  const tags = readTags(fmData, errors2, frontmatterEndLine);
7704
- const parameters = readParameters(fmData, errors2, frontmatterEndLine, path);
7704
+ const parameters = readParameters(fmData, errors2, frontmatterEndLine, path2);
7705
7705
  const toc = parseMarkdownToc(markdown);
7706
7706
  const { title, titleLine } = extractTitle(toc.headings, errors2);
7707
7707
  for (const h of toc.headings) {
@@ -7718,7 +7718,7 @@ function parseWorkflow(markdown, source) {
7718
7718
  });
7719
7719
  }
7720
7720
  }
7721
- const steps = extractSteps(toc.headings, lines, totalLines, path, errors2);
7721
+ const steps = extractSteps(toc.headings, lines, totalLines, path2, errors2);
7722
7722
  if (steps.length === 0 && titleLine > 0) {
7723
7723
  errors2.push({
7724
7724
  line: titleLine,
@@ -7732,7 +7732,7 @@ function parseWorkflow(markdown, source) {
7732
7732
  ...tags ? { tags } : {},
7733
7733
  ...parameters ? { parameters } : {},
7734
7734
  steps,
7735
- source: { path, lineCount: totalLines }
7735
+ source: { path: path2, lineCount: totalLines }
7736
7736
  };
7737
7737
  runSemanticChecks(draft, fmData, frontmatterEndLine, errors2);
7738
7738
  if (errors2.length > 0) {
@@ -7767,7 +7767,7 @@ function extractTitle(headings, errors2) {
7767
7767
  }
7768
7768
  return { title, titleLine: first.line };
7769
7769
  }
7770
- function extractSteps(headings, lines, totalLines, path, errors2) {
7770
+ function extractSteps(headings, lines, totalLines, path2, errors2) {
7771
7771
  const steps = [];
7772
7772
  let sequenceIndex = 0;
7773
7773
  for (let i = 0;i < headings.length; i++) {
@@ -7783,11 +7783,11 @@ function extractSteps(headings, lines, totalLines, path, errors2) {
7783
7783
  continue;
7784
7784
  }
7785
7785
  const stepEnd = Math.min(findNextSiblingOrParentLine(headings, i, 2) - 1, totalLines);
7786
- const stepSource = { path, start: h.line, end: stepEnd };
7786
+ const stepSource = { path: path2, start: h.line, end: stepEnd };
7787
7787
  const subsections = collectSubsections(headings, i, stepEnd);
7788
7788
  const stepIdSearchEnd = subsections.length > 0 ? subsections[0].headingLine - 1 : stepEnd;
7789
7789
  const stepId = scanStepId(lines, h.line + 1, stepIdSearchEnd, stepTitle, errors2);
7790
- const { instructions, completionCriteria } = collectStepBody(subsections, lines, path, stepTitle, errors2);
7790
+ const { instructions, completionCriteria } = collectStepBody(subsections, lines, path2, stepTitle, errors2);
7791
7791
  if (!stepId)
7792
7792
  continue;
7793
7793
  if (!instructions) {
@@ -7827,7 +7827,7 @@ function collectSubsections(headings, stepIndex, stepEnd) {
7827
7827
  }
7828
7828
  return subs;
7829
7829
  }
7830
- function collectStepBody(subsections, lines, path, stepTitle, errors2) {
7830
+ function collectStepBody(subsections, lines, path2, stepTitle, errors2) {
7831
7831
  let instructions;
7832
7832
  let completionCriteria;
7833
7833
  for (const sub of subsections) {
@@ -7849,7 +7849,7 @@ function collectStepBody(subsections, lines, path, stepTitle, errors2) {
7849
7849
  }
7850
7850
  instructions = {
7851
7851
  text,
7852
- source: { path, start: sub.bodyStart, end: sub.bodyEnd }
7852
+ source: { path: path2, start: sub.bodyStart, end: sub.bodyEnd }
7853
7853
  };
7854
7854
  continue;
7855
7855
  }
@@ -7861,7 +7861,7 @@ function collectStepBody(subsections, lines, path, stepTitle, errors2) {
7861
7861
  });
7862
7862
  continue;
7863
7863
  }
7864
- const items = collectBullets(lines, sub.bodyStart, sub.bodyEnd, path);
7864
+ const items = collectBullets(lines, sub.bodyStart, sub.bodyEnd, path2);
7865
7865
  if (items.length === 0) {
7866
7866
  errors2.push({
7867
7867
  line: sub.headingLine,
@@ -7910,7 +7910,7 @@ function scanStepId(lines, startLineInclusive, endLineInclusive, stepTitle, erro
7910
7910
  }
7911
7911
  return foundId;
7912
7912
  }
7913
- function collectBullets(lines, startLineInclusive, endLineInclusive, path) {
7913
+ function collectBullets(lines, startLineInclusive, endLineInclusive, path2) {
7914
7914
  const items = [];
7915
7915
  for (let lineNum = startLineInclusive;lineNum <= endLineInclusive; lineNum++) {
7916
7916
  const trimmed = (lines[lineNum - 1] ?? "").trim();
@@ -7921,7 +7921,7 @@ function collectBullets(lines, startLineInclusive, endLineInclusive, path) {
7921
7921
  continue;
7922
7922
  items.push({
7923
7923
  text: match[1].trim(),
7924
- source: { path, start: lineNum, end: lineNum }
7924
+ source: { path: path2, start: lineNum, end: lineNum }
7925
7925
  });
7926
7926
  }
7927
7927
  return items;
@@ -7990,7 +7990,7 @@ function readTags(data, errors2, fmEndLine) {
7990
7990
  }
7991
7991
  return v.map((tag) => tag.trim());
7992
7992
  }
7993
- function readParameters(data, errors2, fmEndLine, path) {
7993
+ function readParameters(data, errors2, fmEndLine, path2) {
7994
7994
  const v = data.params;
7995
7995
  if (v === undefined || v === null)
7996
7996
  return;
@@ -8024,7 +8024,7 @@ function readParameters(data, errors2, fmEndLine, path) {
8024
8024
  out.push({
8025
8025
  name: trimmedName,
8026
8026
  description: desc.trim(),
8027
- source: { path, start: 1, end: fmEndLine }
8027
+ source: { path: path2, start: 1, end: fmEndLine }
8028
8028
  });
8029
8029
  }
8030
8030
  return out.length > 0 ? out : undefined;
@@ -8304,7 +8304,7 @@ var init_asset_registry = __esm(() => {
8304
8304
  });
8305
8305
 
8306
8306
  // src/core/asset/asset-spec.ts
8307
- import path from "path";
8307
+ import path2 from "path";
8308
8308
  function getAssetTypes() {
8309
8309
  return Object.keys(ASSET_SPECS_INTERNAL);
8310
8310
  }
@@ -8314,14 +8314,14 @@ var init_asset_spec = __esm(() => {
8314
8314
  init_common();
8315
8315
  init_asset_registry();
8316
8316
  markdownSpec = {
8317
- isRelevantFile: (fileName) => path.extname(fileName).toLowerCase() === ".md",
8317
+ isRelevantFile: (fileName) => path2.extname(fileName).toLowerCase() === ".md",
8318
8318
  toCanonicalName: (typeRoot, filePath) => {
8319
- const rel = toPosix(path.relative(typeRoot, filePath));
8319
+ const rel = toPosix(path2.relative(typeRoot, filePath));
8320
8320
  return rel.endsWith(".md") ? rel.slice(0, -3) : rel;
8321
8321
  },
8322
8322
  toAssetPath: (typeRoot, name) => {
8323
8323
  const withExt = name.endsWith(".md") ? name : `${name}.md`;
8324
- return path.join(typeRoot, withExt);
8324
+ return path2.join(typeRoot, withExt);
8325
8325
  }
8326
8326
  };
8327
8327
  SCRIPT_EXTENSIONS = new Set([
@@ -8343,21 +8343,21 @@ var init_asset_spec = __esm(() => {
8343
8343
  ".kts"
8344
8344
  ]);
8345
8345
  scriptSpec = {
8346
- isRelevantFile: (fileName) => SCRIPT_EXTENSIONS.has(path.extname(fileName).toLowerCase()),
8347
- toCanonicalName: (typeRoot, filePath) => toPosix(path.relative(typeRoot, filePath)),
8348
- toAssetPath: (typeRoot, name) => path.join(typeRoot, name)
8346
+ isRelevantFile: (fileName) => SCRIPT_EXTENSIONS.has(path2.extname(fileName).toLowerCase()),
8347
+ toCanonicalName: (typeRoot, filePath) => toPosix(path2.relative(typeRoot, filePath)),
8348
+ toAssetPath: (typeRoot, name) => path2.join(typeRoot, name)
8349
8349
  };
8350
8350
  ASSET_SPECS_INTERNAL = {
8351
8351
  skill: {
8352
8352
  stashDir: "skills",
8353
8353
  isRelevantFile: (fileName) => fileName === "SKILL.md",
8354
8354
  toCanonicalName: (typeRoot, filePath) => {
8355
- const relDir = toPosix(path.dirname(path.relative(typeRoot, filePath)));
8355
+ const relDir = toPosix(path2.dirname(path2.relative(typeRoot, filePath)));
8356
8356
  if (!relDir || relDir === ".")
8357
8357
  return;
8358
8358
  return relDir;
8359
8359
  },
8360
- toAssetPath: (typeRoot, name) => path.join(typeRoot, name, "SKILL.md")
8360
+ toAssetPath: (typeRoot, name) => path2.join(typeRoot, name, "SKILL.md")
8361
8361
  },
8362
8362
  command: { stashDir: "commands", ...markdownSpec },
8363
8363
  agent: { stashDir: "agents", ...markdownSpec },
@@ -8374,10 +8374,10 @@ var init_asset_spec = __esm(() => {
8374
8374
  stashDir: "env",
8375
8375
  isRelevantFile: (fileName) => fileName === ".env" || fileName.endsWith(".env"),
8376
8376
  toCanonicalName: (typeRoot, filePath) => {
8377
- const rel = toPosix(path.relative(typeRoot, filePath));
8378
- const fileName = path.basename(rel);
8377
+ const rel = toPosix(path2.relative(typeRoot, filePath));
8378
+ const fileName = path2.basename(rel);
8379
8379
  if (fileName === ".env") {
8380
- const dir = path.dirname(rel);
8380
+ const dir = path2.dirname(rel);
8381
8381
  return dir === "." || dir === "" ? "default" : `${dir}/default`;
8382
8382
  }
8383
8383
  const stripped = rel.endsWith(".env") ? rel.slice(0, -4) : rel;
@@ -8385,8 +8385,8 @@ var init_asset_spec = __esm(() => {
8385
8385
  },
8386
8386
  toAssetPath: (typeRoot, name) => {
8387
8387
  if (name === "default")
8388
- return path.join(typeRoot, ".env");
8389
- return path.join(typeRoot, name.endsWith(".env") ? name : `${name}.env`);
8388
+ return path2.join(typeRoot, ".env");
8389
+ return path2.join(typeRoot, name.endsWith(".env") ? name : `${name}.env`);
8390
8390
  },
8391
8391
  rendererName: "env-file",
8392
8392
  actionBuilder: (ref) => `akm show ${ref} -> inspect key names; akm env run ${ref} -- <command> -> run with the whole .env injected (values never reach stdout); akm env export ${ref} --out <file> -> write a sourceable script to a file`
@@ -8394,8 +8394,8 @@ var init_asset_spec = __esm(() => {
8394
8394
  secret: {
8395
8395
  stashDir: "secrets",
8396
8396
  isRelevantFile: (fileName) => !fileName.endsWith(".lock") && !fileName.endsWith(".sensitive"),
8397
- toCanonicalName: (typeRoot, filePath) => toPosix(path.relative(typeRoot, filePath)),
8398
- toAssetPath: (typeRoot, name) => path.join(typeRoot, name),
8397
+ toCanonicalName: (typeRoot, filePath) => toPosix(path2.relative(typeRoot, filePath)),
8398
+ toAssetPath: (typeRoot, name) => path2.join(typeRoot, name),
8399
8399
  rendererName: "secret-file",
8400
8400
  actionBuilder: (ref) => `akm show ${ref} -> name only (value never shown); akm secret path ${ref} -> file path; akm secret run ${ref} <VAR> -- <command> -> run with value injected into $VAR`
8401
8401
  },
@@ -8413,14 +8413,14 @@ var init_asset_spec = __esm(() => {
8413
8413
  },
8414
8414
  task: {
8415
8415
  stashDir: "tasks",
8416
- isRelevantFile: (fileName) => path.extname(fileName).toLowerCase() === ".yml",
8416
+ isRelevantFile: (fileName) => path2.extname(fileName).toLowerCase() === ".yml",
8417
8417
  toCanonicalName: (typeRoot, filePath) => {
8418
- const rel = toPosix(path.relative(typeRoot, filePath));
8418
+ const rel = toPosix(path2.relative(typeRoot, filePath));
8419
8419
  return rel.endsWith(".yml") ? rel.slice(0, -4) : rel;
8420
8420
  },
8421
8421
  toAssetPath: (typeRoot, name) => {
8422
8422
  const withExt = name.endsWith(".yml") ? name : `${name}.yml`;
8423
- return path.join(typeRoot, withExt);
8423
+ return path2.join(typeRoot, withExt);
8424
8424
  },
8425
8425
  rendererName: "task-yaml",
8426
8426
  actionBuilder: buildTaskAction
@@ -8463,7 +8463,7 @@ var init_common = __esm(() => {
8463
8463
  });
8464
8464
 
8465
8465
  // src/core/paths.ts
8466
- import path2 from "path";
8466
+ import path3 from "path";
8467
8467
  function isUnderBunTest(env) {
8468
8468
  return env.BUN_TEST === "1" || env.NODE_ENV === "test";
8469
8469
  }
@@ -8480,23 +8480,23 @@ function getDataDir(env = process.env, platform = process.platform) {
8480
8480
  if (platform === "win32") {
8481
8481
  const localAppData = env.LOCALAPPDATA?.trim();
8482
8482
  if (localAppData)
8483
- return path2.join(localAppData, "akm", "data");
8483
+ return path3.join(localAppData, "akm", "data");
8484
8484
  const userProfile = env.USERPROFILE?.trim();
8485
8485
  if (userProfile)
8486
- return path2.join(userProfile, "AppData", "Local", "akm", "data");
8486
+ return path3.join(userProfile, "AppData", "Local", "akm", "data");
8487
8487
  const appData = env.APPDATA?.trim();
8488
8488
  if (!appData) {
8489
8489
  throw new ConfigError("Unable to determine data directory. Set LOCALAPPDATA, USERPROFILE, or APPDATA.", "CONFIG_DIR_UNRESOLVABLE");
8490
8490
  }
8491
- return path2.join(appData, "..", "Local", "akm", "data");
8491
+ return path3.join(appData, "..", "Local", "akm", "data");
8492
8492
  }
8493
8493
  const xdgDataHome = env.XDG_DATA_HOME?.trim();
8494
8494
  if (xdgDataHome)
8495
- return path2.join(xdgDataHome, "akm");
8495
+ return path3.join(xdgDataHome, "akm");
8496
8496
  const home = env.HOME?.trim();
8497
8497
  if (!home)
8498
- return path2.join("/tmp", "akm-data");
8499
- return path2.join(home, ".local", "share", "akm");
8498
+ return path3.join("/tmp", "akm-data");
8499
+ return path3.join(home, ".local", "share", "akm");
8500
8500
  }
8501
8501
  var init_paths = __esm(() => {
8502
8502
  init_common();
@@ -8505,21 +8505,39 @@ var init_paths = __esm(() => {
8505
8505
 
8506
8506
  // scripts/migrations/import-fs-improve-runs-to-db.ts
8507
8507
  import fs5 from "fs";
8508
- import path4 from "path";
8508
+ import path5 from "path";
8509
8509
 
8510
8510
  // src/core/state-db.ts
8511
- import fs4 from "fs";
8512
- import path3 from "path";
8511
+ import path4 from "path";
8512
+
8513
+ // src/storage/managed-db.ts
8514
+ import fs2 from "fs";
8515
+ import path from "path";
8513
8516
 
8514
8517
  // src/storage/database.ts
8515
8518
  import { createRequire } from "module";
8516
8519
  var isBun = !!process.versions?.bun;
8517
8520
  var nodeRequire = createRequire(import.meta.url);
8518
- function openDatabase(path, opts) {
8519
- if (isBun) {
8520
- return openBunDatabase(path, opts);
8521
+ var bunSqliteProvider = {
8522
+ name: "bun:sqlite",
8523
+ supported: () => isBun,
8524
+ open: openBunDatabase
8525
+ };
8526
+ var nodeSqliteProvider = {
8527
+ name: "better-sqlite3",
8528
+ supported: () => !isBun,
8529
+ open: openNodeDatabase
8530
+ };
8531
+ var PROVIDERS = [bunSqliteProvider, nodeSqliteProvider];
8532
+ function selectProvider() {
8533
+ const provider = PROVIDERS.find((p) => p.supported());
8534
+ if (!provider) {
8535
+ throw new Error(`No storage provider supports the current runtime (${isBun ? "Bun" : "Node"}).`);
8521
8536
  }
8522
- return openNodeDatabase(path, opts);
8537
+ return provider;
8538
+ }
8539
+ function openDatabase(path, opts) {
8540
+ return selectProvider().open(path, opts);
8523
8541
  }
8524
8542
  function openBunDatabase(path, opts) {
8525
8543
  const { Database: BunDatabase } = loadBunSqlite();
@@ -8544,7 +8562,16 @@ function loadBunSqlite() {
8544
8562
  var betterSqlite3Ctor;
8545
8563
  function loadBetterSqlite3() {
8546
8564
  if (!betterSqlite3Ctor) {
8547
- const mod = nodeRequire("better-sqlite3");
8565
+ let mod;
8566
+ try {
8567
+ mod = nodeRequire("better-sqlite3");
8568
+ } catch (err) {
8569
+ throw new Error(`akm could not load 'better-sqlite3', the SQLite driver it needs on Node.js.
8570
+ ` + ` \u2022 Reinstall akm with a working C/C++ build toolchain so its optional
8571
+ ` + " 'better-sqlite3' native binding rebuilds (a global `npm i -g better-sqlite3`\n" + ` will NOT be resolved \u2014 Node loads it from akm's own node_modules).
8572
+ ` + ` \u2022 Or run akm under Bun, which has a built-in SQLite driver and needs no native build.
8573
+ ` + ` Underlying load error: ${err instanceof Error ? err.message : String(err)}`);
8574
+ }
8548
8575
  betterSqlite3Ctor = mod.default ?? mod;
8549
8576
  }
8550
8577
  return betterSqlite3Ctor;
@@ -8560,30 +8587,6 @@ function openNodeDatabase(path, opts) {
8560
8587
  return db;
8561
8588
  }
8562
8589
 
8563
- // src/storage/engines/sqlite-migrations.ts
8564
- function ensureMigrationsTable(db) {
8565
- db.exec(`
8566
- CREATE TABLE IF NOT EXISTS schema_migrations (
8567
- id TEXT PRIMARY KEY,
8568
- applied_at TEXT NOT NULL DEFAULT (datetime('now'))
8569
- );
8570
- `);
8571
- }
8572
- function runMigrations(db, migrations, opts) {
8573
- ensureMigrationsTable(db);
8574
- opts?.bootstrap?.(db);
8575
- const appliedRows = db.prepare("SELECT id FROM schema_migrations").all();
8576
- const applied = new Set(appliedRows.map((r) => r.id));
8577
- for (const migration of migrations) {
8578
- if (applied.has(migration.id))
8579
- continue;
8580
- db.transaction(() => {
8581
- db.exec(migration.up);
8582
- db.prepare("INSERT INTO schema_migrations (id) VALUES (?)").run(migration.id);
8583
- })();
8584
- }
8585
- }
8586
-
8587
8590
  // src/storage/sqlite-pragmas.ts
8588
8591
  init_warn();
8589
8592
 
@@ -8672,6 +8675,18 @@ function warnNetworkFallbackOnce(dataDir) {
8672
8675
  warn(`[akm] network filesystem detected at ${dataDir} \u2014 WAL unsupported, using DELETE journal mode`);
8673
8676
  }
8674
8677
 
8678
+ // src/storage/managed-db.ts
8679
+ function openManagedDatabase(spec) {
8680
+ const dir = path.dirname(spec.path);
8681
+ if (!fs2.existsSync(dir)) {
8682
+ fs2.mkdirSync(dir, { recursive: true });
8683
+ }
8684
+ const db = openDatabase(spec.path);
8685
+ applyStandardPragmas(db, spec.pragmas ?? { dataDir: dir });
8686
+ spec.init?.(db);
8687
+ return db;
8688
+ }
8689
+
8675
8690
  // src/core/assert.ts
8676
8691
  function assertNever(x, context) {
8677
8692
  let serialized;
@@ -8713,20 +8728,32 @@ function classifyImproveAction(mode) {
8713
8728
  // src/core/state-db.ts
8714
8729
  init_paths();
8715
8730
  init_warn();
8716
- function getStateDbPath() {
8717
- return path3.join(getDataDir(), "state.db");
8731
+
8732
+ // src/storage/engines/sqlite-migrations.ts
8733
+ function ensureMigrationsTable(db) {
8734
+ db.exec(`
8735
+ CREATE TABLE IF NOT EXISTS schema_migrations (
8736
+ id TEXT PRIMARY KEY,
8737
+ applied_at TEXT NOT NULL DEFAULT (datetime('now'))
8738
+ );
8739
+ `);
8718
8740
  }
8719
- function openStateDatabase(dbPath) {
8720
- const resolvedPath = dbPath ?? getStateDbPath();
8721
- const dir = path3.dirname(resolvedPath);
8722
- if (!fs4.existsSync(dir)) {
8723
- fs4.mkdirSync(dir, { recursive: true });
8724
- }
8725
- const db = openDatabase(resolvedPath);
8726
- applyStandardPragmas(db, { dataDir: dir });
8727
- runMigrations2(db);
8728
- return db;
8741
+ function runMigrations(db, migrations, opts) {
8742
+ ensureMigrationsTable(db);
8743
+ opts?.bootstrap?.(db);
8744
+ const appliedRows = db.prepare("SELECT id FROM schema_migrations").all();
8745
+ const applied = new Set(appliedRows.map((r) => r.id));
8746
+ for (const migration of migrations) {
8747
+ if (applied.has(migration.id))
8748
+ continue;
8749
+ db.transaction(() => {
8750
+ db.exec(migration.up);
8751
+ db.prepare("INSERT INTO schema_migrations (id) VALUES (?)").run(migration.id);
8752
+ })();
8753
+ }
8729
8754
  }
8755
+
8756
+ // src/core/state/migrations.ts
8730
8757
  var MIGRATIONS = [
8731
8758
  {
8732
8759
  id: "001-initial-schema",
@@ -9119,6 +9146,14 @@ var MIGRATIONS = [
9119
9146
  function runMigrations2(db) {
9120
9147
  runMigrations(db, MIGRATIONS);
9121
9148
  }
9149
+
9150
+ // src/core/state-db.ts
9151
+ function getStateDbPath() {
9152
+ return path4.join(getDataDir(), "state.db");
9153
+ }
9154
+ function openStateDatabase(dbPath) {
9155
+ return openManagedDatabase({ path: dbPath ?? getStateDbPath(), init: runMigrations2 });
9156
+ }
9122
9157
  function computeImproveRunMetrics(result) {
9123
9158
  const plannedCount = Array.isArray(result.plannedRefs) ? result.plannedRefs.length : 0;
9124
9159
  const actions = Array.isArray(result.actions) ? result.actions : [];
@@ -9162,7 +9197,7 @@ function recordImproveRun(db, input) {
9162
9197
  function parseArgs(argv) {
9163
9198
  const stashFromEnv = process.env.AKM_STASH_DIR;
9164
9199
  const out = {
9165
- stashDir: stashFromEnv ?? path4.join(process.env.HOME ?? "", "akm"),
9200
+ stashDir: stashFromEnv ?? path5.join(process.env.HOME ?? "", "akm"),
9166
9201
  dryRun: false,
9167
9202
  archive: true
9168
9203
  };
@@ -9221,7 +9256,7 @@ function inferScope(envelope) {
9221
9256
  }
9222
9257
  async function main() {
9223
9258
  const args = parseArgs(process.argv.slice(2));
9224
- const runsRoot = path4.join(args.stashDir, ".akm", "runs");
9259
+ const runsRoot = path5.join(args.stashDir, ".akm", "runs");
9225
9260
  if (!fs5.existsSync(runsRoot)) {
9226
9261
  console.log(`[import] no legacy runs directory at ${runsRoot}; nothing to do`);
9227
9262
  return;
@@ -9240,7 +9275,7 @@ async function main() {
9240
9275
  let skippedParseFailed = 0;
9241
9276
  let skippedNoTimestamp = 0;
9242
9277
  for (const id of entries) {
9243
- const resultPath = path4.join(runsRoot, id, "improve-result.json");
9278
+ const resultPath = path5.join(runsRoot, id, "improve-result.json");
9244
9279
  if (!fs5.existsSync(resultPath)) {
9245
9280
  skippedNoResult++;
9246
9281
  continue;
@@ -9316,7 +9351,7 @@ async function main() {
9316
9351
  return;
9317
9352
  }
9318
9353
  const ts = new Date().toISOString().replace(/[:.]/g, "-");
9319
- const archiveTarget = path4.join(args.stashDir, ".akm", `runs.archived-${ts}`);
9354
+ const archiveTarget = path5.join(args.stashDir, ".akm", `runs.archived-${ts}`);
9320
9355
  fs5.renameSync(runsRoot, archiveTarget);
9321
9356
  console.log(`[import] archived ${runsRoot} \u2192 ${archiveTarget}`);
9322
9357
  }