akm-cli 0.9.0-beta.50 → 0.9.0-beta.52

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 (51) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +12 -4
  3. package/dist/akm +38 -0
  4. package/dist/akm-migrate-storage +38 -0
  5. package/dist/assets/wiki/ingest-workflow-template.md +34 -12
  6. package/dist/assets/wiki/schema-template.md +4 -4
  7. package/dist/cli/parse-args.js +46 -1
  8. package/dist/cli.js +12 -6
  9. package/dist/commands/config-cli.js +18 -2
  10. package/dist/commands/env/child-env.js +47 -0
  11. package/dist/commands/env/env-cli.js +17 -2
  12. package/dist/commands/env/secret-cli.js +24 -2
  13. package/dist/commands/health/checks.js +1 -1
  14. package/dist/commands/improve/improve-auto-accept.js +30 -2
  15. package/dist/commands/improve/improve-cli.js +1 -1
  16. package/dist/commands/improve/improve-result-file.js +9 -2
  17. package/dist/commands/improve/preparation.js +10 -2
  18. package/dist/commands/improve/recombine.js +52 -15
  19. package/dist/commands/lint/env-key-rules.js +4 -0
  20. package/dist/commands/read/knowledge.js +5 -2
  21. package/dist/commands/read/search-cli.js +2 -4
  22. package/dist/commands/read/search.js +9 -6
  23. package/dist/commands/read/show.js +19 -5
  24. package/dist/commands/sources/init.js +13 -8
  25. package/dist/commands/sources/installed-stashes.js +6 -2
  26. package/dist/commands/sources/schema-repair.js +33 -47
  27. package/dist/commands/sources/source-add.js +7 -3
  28. package/dist/commands/tasks/tasks.js +38 -10
  29. package/dist/core/asset/asset-registry.js +1 -1
  30. package/dist/core/asset/asset-spec.js +4 -2
  31. package/dist/core/config/config-migration.js +12 -11
  32. package/dist/indexer/passes/memory-inference.js +3 -2
  33. package/dist/indexer/search/db-search.js +6 -4
  34. package/dist/indexer/search/search-source.js +15 -2
  35. package/dist/integrations/agent/prompts.js +1 -1
  36. package/dist/llm/memory-infer-impl.js +138 -0
  37. package/dist/llm/memory-infer.js +1 -135
  38. package/dist/migrate-storage-node.mjs +8 -0
  39. package/dist/output/renderers.js +1 -1
  40. package/dist/scripts/migrate-storage.js +463 -347
  41. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +99 -99
  42. package/dist/sources/include.js +6 -2
  43. package/dist/sources/providers/git-install.js +10 -6
  44. package/dist/sources/providers/provider-utils.js +13 -7
  45. package/dist/sources/providers/website.js +8 -3
  46. package/dist/sources/website-ingest.js +136 -20
  47. package/dist/text-import-hook.mjs +0 -0
  48. package/dist/wiki/wiki.js +15 -11
  49. package/docs/data-and-telemetry.md +2 -2
  50. package/docs/migration/release-notes/0.9.0.md +39 -0
  51. package/package.json +8 -8
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
+ import { createRequire } from "node:module";
3
4
  var __create = Object.create;
4
5
  var __getProtoOf = Object.getPrototypeOf;
5
6
  var __defProp = Object.defineProperty;
@@ -63,7 +64,7 @@ var __export = (target, all) => {
63
64
  });
64
65
  };
65
66
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
66
- var __require = import.meta.require;
67
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
67
68
 
68
69
  // node_modules/dotenv/lib/main.js
69
70
  var require_main = __commonJS((exports, module) => {
@@ -72,14 +73,14 @@ var require_main = __commonJS((exports, module) => {
72
73
  var os = __require("os");
73
74
  var crypto = __require("crypto");
74
75
  var TIPS = [
75
- "\u25C8 encrypted .env [www.dotenvx.com]",
76
- "\u25C8 secrets for agents [www.dotenvx.com]",
77
- "\u2301 auth for agents [www.vestauth.com]",
78
- "\u2318 custom filepath { path: '/custom/path/.env' }",
79
- "\u2318 enable debugging { debug: true }",
80
- "\u2318 override existing { override: true }",
81
- "\u2318 suppress logs { quiet: true }",
82
- "\u2318 multiple files { path: ['.env.local', '.env'] }"
76
+ " encrypted .env [www.dotenvx.com]",
77
+ " secrets for agents [www.dotenvx.com]",
78
+ " auth for agents [www.vestauth.com]",
79
+ " custom filepath { path: '/custom/path/.env' }",
80
+ " enable debugging { debug: true }",
81
+ " override existing { override: true }",
82
+ " suppress logs { quiet: true }",
83
+ " multiple files { path: ['.env.local', '.env'] }"
83
84
  ];
84
85
  function _getRandomTip() {
85
86
  return TIPS[Math.floor(Math.random() * TIPS.length)];
@@ -146,13 +147,13 @@ var require_main = __commonJS((exports, module) => {
146
147
  return DotenvModule.parse(decrypted);
147
148
  }
148
149
  function _warn(message) {
149
- console.error(`\u26A0 ${message}`);
150
+ console.error(`⚠ ${message}`);
150
151
  }
151
152
  function _debug(message) {
152
- console.log(`\u2506 ${message}`);
153
+ console.log(`┆ ${message}`);
153
154
  }
154
155
  function _log(message) {
155
- console.log(`\u25C7 ${message}`);
156
+ console.log(`◇ ${message}`);
156
157
  }
157
158
  function _dotenvKey(options) {
158
159
  if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {
@@ -402,7 +403,7 @@ var init_errors = __esm(() => {
402
403
  EMBEDDING_NOT_CONFIGURED: 'Run `akm config set embedding \'{"endpoint":"...","model":"..."}\'` to enable embeddings.',
403
404
  LLM_NOT_CONFIGURED: 'Run `akm setup` or `akm config set profiles.llm.default \'{"endpoint":"...","model":"..."}\' to configure an LLM profile.',
404
405
  TEST_ISOLATION_MISSING: "Under bun test, when AKM_STASH_DIR is set you MUST also set XDG_DATA_HOME (or AKM_DATA_DIR) and XDG_STATE_HOME (or AKM_STATE_DIR) to temp directories so the test does not touch the developer's real ~/.local/share/akm or ~/.local/state/akm.",
405
- SETUP_TMP_STASH_REFUSED: "Use a persistent directory, or set AKM_FORCE_SETUP_TMP_STASH=1 to opt in to a sandboxed setup (setup also pre-sets AKM_STASH_DIR so config and cache writes auto-isolate into $stashDir/.akm/ \u2014 host config is preserved).",
406
+ SETUP_TMP_STASH_REFUSED: "Use a persistent directory, or set AKM_FORCE_SETUP_TMP_STASH=1 to opt in to a sandboxed setup (setup also pre-sets AKM_STASH_DIR so config and cache writes auto-isolate into $stashDir/.akm/ host config is preserved).",
406
407
  UNSAFE_STASH_DIR: "Choose a path inside your home directory (e.g. ~/akm) or another empty workspace. The stash directory cannot be the filesystem root, your home directory itself, or a sensitive system path like /etc, /var, ~/.config, or ~/.ssh."
407
408
  };
408
409
  USAGE_HINTS = {
@@ -451,7 +452,7 @@ var init_errors = __esm(() => {
451
452
  });
452
453
 
453
454
  // src/commands/env/env.ts
454
- import fs from "fs";
455
+ import fs from "node:fs";
455
456
  function scanKeys(text) {
456
457
  const keys = [];
457
458
  const seen = new Set;
@@ -3922,15 +3923,15 @@ var require_errors = __commonJS((exports) => {
3922
3923
  let lineStr = src.substring(lc.lineStarts[line - 1], lc.lineStarts[line]).replace(/[\n\r]+$/, "");
3923
3924
  if (ci >= 60 && lineStr.length > 80) {
3924
3925
  const trimStart = Math.min(ci - 39, lineStr.length - 79);
3925
- lineStr = "\u2026" + lineStr.substring(trimStart);
3926
+ lineStr = "" + lineStr.substring(trimStart);
3926
3927
  ci -= trimStart - 1;
3927
3928
  }
3928
3929
  if (lineStr.length > 80)
3929
- lineStr = lineStr.substring(0, 79) + "\u2026";
3930
+ lineStr = lineStr.substring(0, 79) + "";
3930
3931
  if (line > 1 && /^ *$/.test(lineStr.substring(0, ci))) {
3931
3932
  let prev = src.substring(lc.lineStarts[line - 2], lc.lineStarts[line - 1]);
3932
3933
  if (prev.length > 80)
3933
- prev = prev.substring(0, 79) + `\u2026
3934
+ prev = prev.substring(0, 79) + `…
3934
3935
  `;
3935
3936
  lineStr = prev + lineStr;
3936
3937
  }
@@ -4985,8 +4986,8 @@ var require_resolve_flow_scalar = __commonJS((exports) => {
4985
4986
  r: "\r",
4986
4987
  t: "\t",
4987
4988
  v: "\v",
4988
- N: "\x85",
4989
- _: "\xA0",
4989
+ N: "…",
4990
+ _: " ",
4990
4991
  L: "\u2028",
4991
4992
  P: "\u2029",
4992
4993
  " ": " ",
@@ -7579,7 +7580,7 @@ var init_markdown = __esm(() => {
7579
7580
  });
7580
7581
 
7581
7582
  // src/core/warn.ts
7582
- import fs2 from "fs";
7583
+ import fs2 from "node:fs";
7583
7584
  function isVerbose() {
7584
7585
  const env = process.env.AKM_VERBOSE?.trim().toLowerCase();
7585
7586
  if (env === "1" || env === "true" || env === "yes" || env === "on")
@@ -7641,7 +7642,7 @@ var init_metadata_contributors = __esm(() => {
7641
7642
  });
7642
7643
 
7643
7644
  // src/indexer/passes/metadata.ts
7644
- import fs3 from "fs";
7645
+ import fs3 from "node:fs";
7645
7646
  function extractDescriptionFromComments(filePath) {
7646
7647
  let content;
7647
7648
  try {
@@ -7694,7 +7695,7 @@ var init_metadata = __esm(() => {
7694
7695
  });
7695
7696
 
7696
7697
  // src/core/asset/asset-ref.ts
7697
- import path from "path";
7698
+ import path from "node:path";
7698
7699
  function parseAssetRef(ref) {
7699
7700
  const trimmed = ref.trim();
7700
7701
  if (!trimmed)
@@ -7715,7 +7716,7 @@ function parseAssetRef(ref) {
7715
7716
  const rawType = body.slice(0, colon);
7716
7717
  const rawName = body.slice(colon + 1);
7717
7718
  if (rawType === "vault") {
7718
- throw new UsageError("The `vault` asset type was removed in 0.9.0 \u2014 use `env:` (whole .env config) or `secret:` (a single value).", "MISSING_REQUIRED_ARGUMENT");
7719
+ throw new UsageError("The `vault` asset type was removed in 0.9.0 use `env:` (whole .env config) or `secret:` (a single value).", "MISSING_REQUIRED_ARGUMENT");
7719
7720
  }
7720
7721
  const resolvedType = TYPE_ALIASES[rawType] ?? rawType;
7721
7722
  if (!isAssetType(resolvedType)) {
@@ -8176,7 +8177,7 @@ function loadDocument(ctx) {
8176
8177
  const result = parseWorkflow(ctx.content(), { path: ctx.relPath });
8177
8178
  if (result.ok)
8178
8179
  return result.document;
8179
- const summary = result.errors.map((e) => `${ctx.relPath}:${e.line} \u2014 ${e.message}`).join(`
8180
+ const summary = result.errors.map((e) => `${ctx.relPath}:${e.line} ${e.message}`).join(`
8180
8181
  `);
8181
8182
  throw new UsageError(`Workflow has errors:
8182
8183
  ${summary}`);
@@ -8418,19 +8419,21 @@ var init_asset_registry = __esm(() => {
8418
8419
  });
8419
8420
 
8420
8421
  // src/core/asset/asset-spec.ts
8421
- import path2 from "path";
8422
+ import path2 from "node:path";
8423
+ function toPosix2(input) {
8424
+ return input.replace(/\\/g, "/");
8425
+ }
8422
8426
  function getAssetTypes() {
8423
8427
  return Object.keys(ASSET_SPECS_INTERNAL);
8424
8428
  }
8425
8429
  var buildTaskAction = (ref) => `akm tasks show ${ref.replace(/^task:/, "")} -> inspect; akm tasks run <id> -> run now; akm tasks remove <id> -> unschedule`, markdownSpec, SCRIPT_EXTENSIONS, scriptSpec, ASSET_SPECS_INTERNAL, TYPE_DIRS;
8426
8430
  var init_asset_spec = __esm(() => {
8427
8431
  init_renderers();
8428
- init_common();
8429
8432
  init_asset_registry();
8430
8433
  markdownSpec = {
8431
8434
  isRelevantFile: (fileName) => path2.extname(fileName).toLowerCase() === ".md",
8432
8435
  toCanonicalName: (typeRoot, filePath) => {
8433
- const rel = toPosix(path2.relative(typeRoot, filePath));
8436
+ const rel = toPosix2(path2.relative(typeRoot, filePath));
8434
8437
  return rel.endsWith(".md") ? rel.slice(0, -3) : rel;
8435
8438
  },
8436
8439
  toAssetPath: (typeRoot, name) => {
@@ -8458,7 +8461,7 @@ var init_asset_spec = __esm(() => {
8458
8461
  ]);
8459
8462
  scriptSpec = {
8460
8463
  isRelevantFile: (fileName) => SCRIPT_EXTENSIONS.has(path2.extname(fileName).toLowerCase()),
8461
- toCanonicalName: (typeRoot, filePath) => toPosix(path2.relative(typeRoot, filePath)),
8464
+ toCanonicalName: (typeRoot, filePath) => toPosix2(path2.relative(typeRoot, filePath)),
8462
8465
  toAssetPath: (typeRoot, name) => path2.join(typeRoot, name)
8463
8466
  };
8464
8467
  ASSET_SPECS_INTERNAL = {
@@ -8466,7 +8469,7 @@ var init_asset_spec = __esm(() => {
8466
8469
  stashDir: "skills",
8467
8470
  isRelevantFile: (fileName) => fileName === "SKILL.md",
8468
8471
  toCanonicalName: (typeRoot, filePath) => {
8469
- const relDir = toPosix(path2.dirname(path2.relative(typeRoot, filePath)));
8472
+ const relDir = toPosix2(path2.dirname(path2.relative(typeRoot, filePath)));
8470
8473
  if (!relDir || relDir === ".")
8471
8474
  return;
8472
8475
  return relDir;
@@ -8488,7 +8491,7 @@ var init_asset_spec = __esm(() => {
8488
8491
  stashDir: "env",
8489
8492
  isRelevantFile: (fileName) => fileName === ".env" || fileName.endsWith(".env"),
8490
8493
  toCanonicalName: (typeRoot, filePath) => {
8491
- const rel = toPosix(path2.relative(typeRoot, filePath));
8494
+ const rel = toPosix2(path2.relative(typeRoot, filePath));
8492
8495
  const fileName = path2.basename(rel);
8493
8496
  if (fileName === ".env") {
8494
8497
  const dir = path2.dirname(rel);
@@ -8503,12 +8506,12 @@ var init_asset_spec = __esm(() => {
8503
8506
  return path2.join(typeRoot, name.endsWith(".env") ? name : `${name}.env`);
8504
8507
  },
8505
8508
  rendererName: "env-file",
8506
- 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`
8509
+ actionBuilder: (ref) => `akm show ${ref} -> inspect key names; akm env run ${ref} -- <command> -> run with the whole .env injected (prefer --clean to minimize inherited parent env; child stdout is not redacted); akm env export ${ref} --out <file> -> write a sourceable script to a file`
8507
8510
  },
8508
8511
  secret: {
8509
8512
  stashDir: "secrets",
8510
8513
  isRelevantFile: (fileName) => !fileName.endsWith(".lock") && !fileName.endsWith(".sensitive"),
8511
- toCanonicalName: (typeRoot, filePath) => toPosix(path2.relative(typeRoot, filePath)),
8514
+ toCanonicalName: (typeRoot, filePath) => toPosix2(path2.relative(typeRoot, filePath)),
8512
8515
  toAssetPath: (typeRoot, name) => path2.join(typeRoot, name),
8513
8516
  rendererName: "secret-file",
8514
8517
  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`
@@ -8529,7 +8532,7 @@ var init_asset_spec = __esm(() => {
8529
8532
  stashDir: "tasks",
8530
8533
  isRelevantFile: (fileName) => path2.extname(fileName).toLowerCase() === ".yml",
8531
8534
  toCanonicalName: (typeRoot, filePath) => {
8532
- const rel = toPosix(path2.relative(typeRoot, filePath));
8535
+ const rel = toPosix2(path2.relative(typeRoot, filePath));
8533
8536
  return rel.endsWith(".yml") ? rel.slice(0, -4) : rel;
8534
8537
  },
8535
8538
  toAssetPath: (typeRoot, name) => {
@@ -8555,68 +8558,8 @@ var init_asset_spec = __esm(() => {
8555
8558
  TYPE_DIRS = Object.fromEntries(Object.entries(ASSET_SPECS_INTERNAL).map(([type, spec]) => [type, spec.stashDir]));
8556
8559
  });
8557
8560
 
8558
- // src/core/common.ts
8559
- import crypto from "crypto";
8560
- import fs4 from "fs";
8561
- import path3 from "path";
8562
- function isAssetType(type) {
8563
- return Object.hasOwn(TYPE_DIRS, type);
8564
- }
8565
- function writeFileAtomic(target, content, mode) {
8566
- const tmp = `${target}.tmp.${process.pid}.${crypto.randomBytes(8).toString("hex")}`;
8567
- const fd = fs4.openSync(tmp, "w", mode ?? 384);
8568
- try {
8569
- if (typeof content === "string") {
8570
- fs4.writeSync(fd, content);
8571
- } else {
8572
- fs4.writeSync(fd, content);
8573
- }
8574
- try {
8575
- fs4.fdatasyncSync(fd);
8576
- } catch {}
8577
- } finally {
8578
- fs4.closeSync(fd);
8579
- }
8580
- fs4.renameSync(tmp, target);
8581
- try {
8582
- const dirFd = fs4.openSync(path3.dirname(target), "r");
8583
- try {
8584
- fs4.fsyncSync(dirFd);
8585
- } finally {
8586
- fs4.closeSync(dirFd);
8587
- }
8588
- } catch {}
8589
- }
8590
- function toPosix(input) {
8591
- return input.replace(/\\/g, "/");
8592
- }
8593
- function asNonEmptyString(value) {
8594
- if (typeof value !== "string")
8595
- return;
8596
- const trimmed = value.trim();
8597
- return trimmed.length > 0 ? trimmed : undefined;
8598
- }
8599
- function isProcessAlive(pid) {
8600
- try {
8601
- process.kill(pid, 0);
8602
- return true;
8603
- } catch {
8604
- return false;
8605
- }
8606
- }
8607
- var ASSET_TYPES, ASSET_TYPE_SET, IS_WINDOWS, DEFAULT_RESPONSE_BYTE_CAP;
8608
- var init_common = __esm(() => {
8609
- init_asset_spec();
8610
- init_errors();
8611
- init_paths();
8612
- ASSET_TYPES = Object.freeze([...getAssetTypes()]);
8613
- ASSET_TYPE_SET = new Set(ASSET_TYPES);
8614
- IS_WINDOWS = process.platform === "win32";
8615
- DEFAULT_RESPONSE_BYTE_CAP = 10 * 1024 * 1024;
8616
- });
8617
-
8618
8561
  // src/core/paths.ts
8619
- import path4 from "path";
8562
+ import path3 from "node:path";
8620
8563
  function isUnderBunTest(env) {
8621
8564
  return env.BUN_TEST === "1" || env.NODE_ENV === "test";
8622
8565
  }
@@ -8633,37 +8576,37 @@ function getConfigDir(env = process.env, platform = process.platform) {
8633
8576
  if (platform === "win32") {
8634
8577
  const appData = env.APPDATA?.trim();
8635
8578
  if (appData)
8636
- return path4.join(appData, "akm");
8579
+ return path3.join(appData, "akm");
8637
8580
  } else {
8638
8581
  const xdgConfigHome2 = env.XDG_CONFIG_HOME?.trim();
8639
8582
  if (xdgConfigHome2)
8640
- return path4.join(xdgConfigHome2, "akm");
8583
+ return path3.join(xdgConfigHome2, "akm");
8641
8584
  }
8642
8585
  const stashOverride = env.AKM_STASH_DIR?.trim();
8643
8586
  if (stashOverride && isTransientStashPath(stashOverride)) {
8644
- return path4.join(stashOverride, ".akm");
8587
+ return path3.join(stashOverride, ".akm");
8645
8588
  }
8646
8589
  if (platform === "win32") {
8647
8590
  const appData = env.APPDATA?.trim();
8648
8591
  if (appData)
8649
- return path4.join(appData, "akm");
8592
+ return path3.join(appData, "akm");
8650
8593
  const userProfile = env.USERPROFILE?.trim();
8651
8594
  if (!userProfile) {
8652
8595
  throw new ConfigError("Unable to determine config directory. Set APPDATA or USERPROFILE.", "CONFIG_DIR_UNRESOLVABLE");
8653
8596
  }
8654
- return path4.join(userProfile, "AppData", "Roaming", "akm");
8597
+ return path3.join(userProfile, "AppData", "Roaming", "akm");
8655
8598
  }
8656
8599
  const xdgConfigHome = env.XDG_CONFIG_HOME?.trim();
8657
8600
  if (xdgConfigHome)
8658
- return path4.join(xdgConfigHome, "akm");
8601
+ return path3.join(xdgConfigHome, "akm");
8659
8602
  const home = env.HOME?.trim();
8660
8603
  if (!home) {
8661
8604
  throw new ConfigError("Unable to determine config directory. Set XDG_CONFIG_HOME or HOME.", "CONFIG_DIR_UNRESOLVABLE");
8662
8605
  }
8663
- return path4.join(home, ".config", "akm");
8606
+ return path3.join(home, ".config", "akm");
8664
8607
  }
8665
8608
  function getConfigPath() {
8666
- return path4.join(getConfigDir(), "config.json");
8609
+ return path3.join(getConfigDir(), "config.json");
8667
8610
  }
8668
8611
  function getCacheDir() {
8669
8612
  const override = process.env.AKM_CACHE_DIR?.trim();
@@ -8672,30 +8615,30 @@ function getCacheDir() {
8672
8615
  if (IS_WINDOWS) {
8673
8616
  const localAppData = process.env.LOCALAPPDATA?.trim();
8674
8617
  if (localAppData)
8675
- return path4.join(localAppData, "akm");
8618
+ return path3.join(localAppData, "akm");
8676
8619
  const userProfile = process.env.USERPROFILE?.trim();
8677
8620
  if (userProfile)
8678
- return path4.join(userProfile, "AppData", "Local", "akm");
8621
+ return path3.join(userProfile, "AppData", "Local", "akm");
8679
8622
  const appData = process.env.APPDATA?.trim();
8680
8623
  if (appData) {
8681
- return path4.join(appData, "..", "Local", "akm");
8624
+ return path3.join(appData, "..", "Local", "akm");
8682
8625
  }
8683
8626
  } else {
8684
8627
  const xdgCacheHome = process.env.XDG_CACHE_HOME?.trim();
8685
8628
  if (xdgCacheHome)
8686
- return path4.join(xdgCacheHome, "akm");
8629
+ return path3.join(xdgCacheHome, "akm");
8687
8630
  }
8688
8631
  const stashOverride = process.env.AKM_STASH_DIR?.trim();
8689
8632
  if (stashOverride && isTransientStashPath(stashOverride)) {
8690
- return path4.join(stashOverride, ".akm", "cache");
8633
+ return path3.join(stashOverride, ".akm", "cache");
8691
8634
  }
8692
8635
  if (IS_WINDOWS) {
8693
8636
  throw new ConfigError("Unable to determine cache directory. Set LOCALAPPDATA, USERPROFILE, or APPDATA.", "CONFIG_DIR_UNRESOLVABLE");
8694
8637
  }
8695
8638
  const home = process.env.HOME?.trim();
8696
8639
  if (!home)
8697
- return path4.join("/tmp", "akm-cache");
8698
- return path4.join(home, ".cache", "akm");
8640
+ return path3.join("/tmp", "akm-cache");
8641
+ return path3.join(home, ".cache", "akm");
8699
8642
  }
8700
8643
  function getDataDir(env = process.env, platform = process.platform) {
8701
8644
  const override = env.AKM_DATA_DIR?.trim();
@@ -8707,50 +8650,91 @@ function getDataDir(env = process.env, platform = process.platform) {
8707
8650
  if (platform === "win32") {
8708
8651
  const localAppData = env.LOCALAPPDATA?.trim();
8709
8652
  if (localAppData)
8710
- return path4.join(localAppData, "akm", "data");
8653
+ return path3.join(localAppData, "akm", "data");
8711
8654
  const userProfile = env.USERPROFILE?.trim();
8712
8655
  if (userProfile)
8713
- return path4.join(userProfile, "AppData", "Local", "akm", "data");
8656
+ return path3.join(userProfile, "AppData", "Local", "akm", "data");
8714
8657
  const appData = env.APPDATA?.trim();
8715
8658
  if (!appData) {
8716
8659
  throw new ConfigError("Unable to determine data directory. Set LOCALAPPDATA, USERPROFILE, or APPDATA.", "CONFIG_DIR_UNRESOLVABLE");
8717
8660
  }
8718
- return path4.join(appData, "..", "Local", "akm", "data");
8661
+ return path3.join(appData, "..", "Local", "akm", "data");
8719
8662
  }
8720
8663
  const xdgDataHome = env.XDG_DATA_HOME?.trim();
8721
8664
  if (xdgDataHome)
8722
- return path4.join(xdgDataHome, "akm");
8665
+ return path3.join(xdgDataHome, "akm");
8723
8666
  const home = env.HOME?.trim();
8724
8667
  if (!home)
8725
- return path4.join("/tmp", "akm-data");
8726
- return path4.join(home, ".local", "share", "akm");
8668
+ return path3.join("/tmp", "akm-data");
8669
+ return path3.join(home, ".local", "share", "akm");
8727
8670
  }
8728
8671
  function getDbPath() {
8729
- return path4.join(getDataDir(), "index.db");
8672
+ return path3.join(getDataDir(), "index.db");
8730
8673
  }
8731
- function getDefaultStashDir() {
8732
- const override = process.env.AKM_STASH_DIR?.trim();
8733
- if (override)
8734
- return override;
8735
- if (IS_WINDOWS) {
8736
- const userProfile = process.env.USERPROFILE?.trim();
8737
- if (userProfile)
8738
- return path4.join(userProfile, "Documents", "akm");
8739
- return path4.join("C:\\", "akm");
8674
+ var init_paths = __esm(() => {
8675
+ init_common();
8676
+ init_errors();
8677
+ });
8678
+
8679
+ // src/core/common.ts
8680
+ import crypto from "node:crypto";
8681
+ import fs4 from "node:fs";
8682
+ import path4 from "node:path";
8683
+ function isAssetType(type) {
8684
+ return Object.hasOwn(TYPE_DIRS, type);
8685
+ }
8686
+ function writeFileAtomic(target, content, mode) {
8687
+ const tmp = `${target}.tmp.${process.pid}.${crypto.randomBytes(8).toString("hex")}`;
8688
+ const fd = fs4.openSync(tmp, "w", mode ?? 384);
8689
+ try {
8690
+ if (typeof content === "string") {
8691
+ fs4.writeSync(fd, content);
8692
+ } else {
8693
+ fs4.writeSync(fd, content);
8694
+ }
8695
+ try {
8696
+ fs4.fdatasyncSync(fd);
8697
+ } catch {}
8698
+ } finally {
8699
+ fs4.closeSync(fd);
8740
8700
  }
8741
- const home = process.env.HOME?.trim();
8742
- if (!home) {
8743
- throw new ConfigError("Unable to determine default stash directory. Set HOME.", "STASH_DIR_NOT_FOUND");
8701
+ fs4.renameSync(tmp, target);
8702
+ try {
8703
+ const dirFd = fs4.openSync(path4.dirname(target), "r");
8704
+ try {
8705
+ fs4.fsyncSync(dirFd);
8706
+ } finally {
8707
+ fs4.closeSync(dirFd);
8708
+ }
8709
+ } catch {}
8710
+ }
8711
+ function asNonEmptyString(value) {
8712
+ if (typeof value !== "string")
8713
+ return;
8714
+ const trimmed = value.trim();
8715
+ return trimmed.length > 0 ? trimmed : undefined;
8716
+ }
8717
+ function isProcessAlive(pid) {
8718
+ try {
8719
+ process.kill(pid, 0);
8720
+ return true;
8721
+ } catch {
8722
+ return false;
8744
8723
  }
8745
- return path4.join(home, "akm");
8746
8724
  }
8747
- var init_paths = __esm(() => {
8748
- init_common();
8725
+ var ASSET_TYPES, ASSET_TYPE_SET, IS_WINDOWS, DEFAULT_RESPONSE_BYTE_CAP;
8726
+ var init_common = __esm(() => {
8727
+ init_asset_spec();
8749
8728
  init_errors();
8729
+ init_paths();
8730
+ ASSET_TYPES = Object.freeze([...getAssetTypes()]);
8731
+ ASSET_TYPE_SET = new Set(ASSET_TYPES);
8732
+ IS_WINDOWS = process.platform === "win32";
8733
+ DEFAULT_RESPONSE_BYTE_CAP = 10 * 1024 * 1024;
8750
8734
  });
8751
8735
 
8752
8736
  // src/storage/database.ts
8753
- import { createRequire } from "module";
8737
+ import { createRequire as createRequire2 } from "node:module";
8754
8738
  function selectProvider() {
8755
8739
  const provider = PROVIDERS.find((p) => p.supported());
8756
8740
  if (!provider) {
@@ -8758,12 +8742,12 @@ function selectProvider() {
8758
8742
  }
8759
8743
  return provider;
8760
8744
  }
8761
- function openDatabase(path5, opts) {
8762
- return selectProvider().open(path5, opts);
8745
+ function openDatabase(path6, opts) {
8746
+ return selectProvider().open(path6, opts);
8763
8747
  }
8764
- function openBunDatabase(path5, opts) {
8748
+ function openBunDatabase(path6, opts) {
8765
8749
  const { Database: BunDatabase } = loadBunSqlite();
8766
- const db = opts ? new BunDatabase(path5, bunOptions(opts)) : new BunDatabase(path5);
8750
+ const db = opts ? new BunDatabase(path6, bunOptions(opts)) : new BunDatabase(path6);
8767
8751
  return db;
8768
8752
  }
8769
8753
  function bunOptions(opts) {
@@ -8787,29 +8771,29 @@ function loadBetterSqlite3() {
8787
8771
  mod = nodeRequire("better-sqlite3");
8788
8772
  } catch (err) {
8789
8773
  throw new Error(`akm could not load 'better-sqlite3', the SQLite driver it needs on Node.js.
8790
- ` + ` \u2022 Reinstall akm with a working C/C++ build toolchain so its optional
8791
- ` + " '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).
8792
- ` + ` \u2022 Or run akm under Bun, which has a built-in SQLite driver and needs no native build.
8774
+ ` + ` Reinstall akm with a working C/C++ build toolchain so its optional
8775
+ ` + " 'better-sqlite3' native binding rebuilds (a global `npm i -g better-sqlite3`\n" + ` will NOT be resolved Node loads it from akm's own node_modules).
8776
+ ` + ` Or run akm under Bun, which has a built-in SQLite driver and needs no native build.
8793
8777
  ` + ` Underlying load error: ${err instanceof Error ? err.message : String(err)}`);
8794
8778
  }
8795
8779
  betterSqlite3Ctor = mod.default ?? mod;
8796
8780
  }
8797
8781
  return betterSqlite3Ctor;
8798
8782
  }
8799
- function openNodeDatabase(path5, opts) {
8783
+ function openNodeDatabase(path6, opts) {
8800
8784
  const BetterSqlite3 = loadBetterSqlite3();
8801
8785
  const options = {};
8802
8786
  if (opts?.readonly !== undefined)
8803
8787
  options.readonly = opts.readonly;
8804
8788
  if (opts?.create === false)
8805
8789
  options.fileMustExist = true;
8806
- const db = opts ? new BetterSqlite3(path5, options) : new BetterSqlite3(path5);
8790
+ const db = opts ? new BetterSqlite3(path6, options) : new BetterSqlite3(path6);
8807
8791
  return db;
8808
8792
  }
8809
8793
  var isBun, nodeRequire, bunSqliteProvider, nodeSqliteProvider, PROVIDERS, bunSqliteModule, betterSqlite3Ctor;
8810
8794
  var init_database = __esm(() => {
8811
8795
  isBun = !!process.versions?.bun;
8812
- nodeRequire = createRequire(import.meta.url);
8796
+ nodeRequire = createRequire2(import.meta.url);
8813
8797
  bunSqliteProvider = {
8814
8798
  name: "bun:sqlite",
8815
8799
  supported: () => isBun,
@@ -8824,15 +8808,15 @@ var init_database = __esm(() => {
8824
8808
  });
8825
8809
 
8826
8810
  // src/runtime.ts
8827
- import { createHash } from "crypto";
8828
- import { createWriteStream, statfsSync } from "fs";
8829
- import { createRequire as createRequire2 } from "module";
8811
+ import { createHash } from "node:crypto";
8812
+ import { createWriteStream, statfsSync } from "node:fs";
8813
+ import { createRequire as createRequire3 } from "node:module";
8830
8814
  function sha256Hex(data) {
8831
8815
  return createHash("sha256").update(data).digest("hex");
8832
8816
  }
8833
- function statfsType(path5) {
8817
+ function statfsType(path6) {
8834
8818
  try {
8835
- return statfsSync(path5).type;
8819
+ return statfsSync(path6).type;
8836
8820
  } catch {
8837
8821
  return;
8838
8822
  }
@@ -8850,7 +8834,7 @@ function bunGlobal() {
8850
8834
  var isBun2, nodeRequire2, mainPath;
8851
8835
  var init_runtime = __esm(() => {
8852
8836
  isBun2 = !!process.versions?.bun;
8853
- nodeRequire2 = createRequire2(import.meta.url);
8837
+ nodeRequire2 = createRequire3(import.meta.url);
8854
8838
  mainPath = isBun2 ? bunGlobal().main : process.argv[1];
8855
8839
  });
8856
8840
 
@@ -8874,7 +8858,7 @@ function warnInvalidJournalModeOnce(raw) {
8874
8858
  if (warnedInvalid)
8875
8859
  return;
8876
8860
  warnedInvalid = true;
8877
- warn(`[akm] invalid AKM_SQLITE_JOURNAL_MODE=${JSON.stringify(raw)} \u2014 using WAL (valid: WAL, DELETE, TRUNCATE)`);
8861
+ warn(`[akm] invalid AKM_SQLITE_JOURNAL_MODE=${JSON.stringify(raw)} using WAL (valid: WAL, DELETE, TRUNCATE)`);
8878
8862
  }
8879
8863
  function isNetworkFilesystem(fsType) {
8880
8864
  if (fsType === undefined)
@@ -8904,7 +8888,7 @@ function warnNetworkFallbackOnce(dataDir) {
8904
8888
  if (warnedNetworkFallback)
8905
8889
  return;
8906
8890
  warnedNetworkFallback = true;
8907
- warn(`[akm] network filesystem detected at ${dataDir} \u2014 WAL unsupported, using DELETE journal mode`);
8891
+ warn(`[akm] network filesystem detected at ${dataDir} WAL unsupported, using DELETE journal mode`);
8908
8892
  }
8909
8893
  var VALID_MODES, warnedInvalid = false, warnedNetworkFallback = false, FS_MAGIC_NFS = 26985, FS_MAGIC_SMB = 20859, FS_MAGIC_CIFS = 4283649346, FS_MAGIC_SMB2 = 4266872130, FS_MAGIC_FUSE = 1702057286, NETWORK_FS_MAGICS;
8910
8894
  var init_sqlite_pragmas = __esm(() => {
@@ -8921,10 +8905,10 @@ var init_sqlite_pragmas = __esm(() => {
8921
8905
  });
8922
8906
 
8923
8907
  // src/storage/managed-db.ts
8924
- import fs5 from "fs";
8925
- import path5 from "path";
8908
+ import fs5 from "node:fs";
8909
+ import path6 from "node:path";
8926
8910
  function openManagedDatabase(spec) {
8927
- const dir = path5.dirname(spec.path);
8911
+ const dir = path6.dirname(spec.path);
8928
8912
  if (!fs5.existsSync(dir)) {
8929
8913
  fs5.mkdirSync(dir, { recursive: true });
8930
8914
  }
@@ -9034,26 +9018,26 @@ var init_migrations = __esm(() => {
9034
9018
  {
9035
9019
  id: "001-initial-schema",
9036
9020
  up: `
9037
- -- \u2500\u2500 events \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
9021
+ -- ── events ──────────────────────────────────────────────────────────────
9038
9022
  --
9039
9023
  -- Replaces events.jsonl. Indexed (query) columns:
9040
- -- id INTEGER PK \u2014 monotonic rowid; replaces byte-offset cursor.
9024
+ -- id INTEGER PK monotonic rowid; replaces byte-offset cursor.
9041
9025
  -- Callers store this as "sinceId" for resume.
9042
- -- event_type TEXT \u2014 indexed; replaces the type filter in readEvents().
9043
- -- ts TEXT \u2014 ISO-8601 UTC ms; indexed for range queries.
9044
- -- ref TEXT \u2014 nullable asset ref; indexed for ref-scoped queries.
9026
+ -- event_type TEXT indexed; replaces the type filter in readEvents().
9027
+ -- ts TEXT ISO-8601 UTC ms; indexed for range queries.
9028
+ -- ref TEXT nullable asset ref; indexed for ref-scoped queries.
9045
9029
  --
9046
9030
  -- Extensible (metadata_json) columns:
9047
- -- metadata_json TEXT \u2014 JSON object storing all non-indexed payload
9031
+ -- metadata_json TEXT JSON object storing all non-indexed payload
9048
9032
  -- fields (tags, any future structured fields).
9049
9033
  -- Maps directly to EventEnvelope.metadata.
9050
9034
  --
9051
- -- schema_version mirrors EventEnvelope.schemaVersion \u2014 always 1 for v1
9035
+ -- schema_version mirrors EventEnvelope.schemaVersion always 1 for v1
9052
9036
  -- rows. Stored as a column (not in the JSON blob) so future schema
9053
9037
  -- changes can be detected and migrated row-by-row if ever needed.
9054
9038
  --
9055
9039
  -- TTL: rows where ts < NOW() - 90 days can be deleted by a maintenance job.
9056
- -- No automatic deletion occurs here \u2014 callers call purgeOldEvents().
9040
+ -- No automatic deletion occurs here callers call purgeOldEvents().
9057
9041
  --
9058
9042
  -- ADD COLUMN extension points (future migrations):
9059
9043
  -- ALTER TABLE events ADD COLUMN stash_dir TEXT DEFAULT NULL;
@@ -9069,38 +9053,38 @@ var init_migrations = __esm(() => {
9069
9053
  );
9070
9054
 
9071
9055
  -- Query patterns supported by these indexes:
9072
- -- SELECT \u2026 WHERE event_type = ? \u2192 idx_events_type
9073
- -- SELECT \u2026 WHERE ref = ? \u2192 idx_events_ref
9074
- -- SELECT \u2026 WHERE ts >= ? AND ts <= ? \u2192 idx_events_ts
9075
- -- SELECT \u2026 WHERE event_type = ? AND ref = ? \u2192 idx_events_type (prefix scan) + filter
9076
- -- SELECT \u2026 WHERE id > ? \u2192 PK (rowid) \u2014 no extra index needed
9056
+ -- SELECT WHERE event_type = ? idx_events_type
9057
+ -- SELECT WHERE ref = ? idx_events_ref
9058
+ -- SELECT WHERE ts >= ? AND ts <= ? idx_events_ts
9059
+ -- SELECT WHERE event_type = ? AND ref = ? idx_events_type (prefix scan) + filter
9060
+ -- SELECT WHERE id > ? PK (rowid) no extra index needed
9077
9061
  CREATE INDEX IF NOT EXISTS idx_events_type ON events(event_type);
9078
9062
  CREATE INDEX IF NOT EXISTS idx_events_ref ON events(ref);
9079
9063
  CREATE INDEX IF NOT EXISTS idx_events_ts ON events(ts);
9080
9064
 
9081
- -- \u2500\u2500 proposals \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
9065
+ -- ── proposals ────────────────────────────────────────────────────────────
9082
9066
  --
9083
9067
  -- Replaces per-uuid JSON directories under <stashDir>/.akm/proposals/.
9084
9068
  --
9085
9069
  -- Indexed (query) columns:
9086
- -- id TEXT PK \u2014 UUID (crypto.randomUUID()); stable directory name.
9087
- -- stash_dir TEXT \u2014 absolute stash root; multi-stash installs need
9070
+ -- id TEXT PK UUID (crypto.randomUUID()); stable directory name.
9071
+ -- stash_dir TEXT absolute stash root; multi-stash installs need
9088
9072
  -- this to partition proposal lists per stash.
9089
- -- ref TEXT \u2014 target asset ref (e.g. "lesson:alpha");
9073
+ -- ref TEXT target asset ref (e.g. "lesson:alpha");
9090
9074
  -- indexed for ref-scoped queue views.
9091
- -- status TEXT \u2014 "pending" | "accepted" | "rejected"; indexed
9075
+ -- status TEXT "pending" | "accepted" | "rejected"; indexed
9092
9076
  -- so pending-queue queries are fast.
9093
- -- source TEXT \u2014 human-readable origin tag (e.g. "reflect").
9094
- -- created_at TEXT \u2014 ISO-8601; used for ORDER BY created_at ASC.
9095
- -- updated_at TEXT \u2014 ISO-8601; updated on accept/reject.
9077
+ -- source TEXT human-readable origin tag (e.g. "reflect").
9078
+ -- created_at TEXT ISO-8601; used for ORDER BY created_at ASC.
9079
+ -- updated_at TEXT ISO-8601; updated on accept/reject.
9096
9080
  --
9097
9081
  -- Large payload columns (NOT indexed):
9098
- -- content TEXT \u2014 full markdown text; the proposal payload body.
9099
- -- frontmatter_json TEXT \u2014 JSON of parsed frontmatter (may be NULL when
9082
+ -- content TEXT full markdown text; the proposal payload body.
9083
+ -- frontmatter_json TEXT JSON of parsed frontmatter (may be NULL when
9100
9084
  -- the content has no frontmatter block).
9101
9085
  --
9102
9086
  -- Extensible (metadata_json) columns:
9103
- -- metadata_json TEXT \u2014 JSON object for future proposal fields.
9087
+ -- metadata_json TEXT JSON object for future proposal fields.
9104
9088
  -- Current fields stored here: sourceRun,
9105
9089
  -- review, confidence, gateDecision (#577),
9106
9090
  -- backupContent, eligibilitySource.
@@ -9126,38 +9110,38 @@ var init_migrations = __esm(() => {
9126
9110
  );
9127
9111
 
9128
9112
  -- Query patterns:
9129
- -- SELECT \u2026 WHERE stash_dir = ? AND status = ? \u2192 idx_proposals_stash_status
9130
- -- SELECT \u2026 WHERE ref = ? AND status = ? \u2192 idx_proposals_ref_status
9131
- -- SELECT \u2026 WHERE id = ? \u2192 PK
9113
+ -- SELECT WHERE stash_dir = ? AND status = ? idx_proposals_stash_status
9114
+ -- SELECT WHERE ref = ? AND status = ? idx_proposals_ref_status
9115
+ -- SELECT WHERE id = ? PK
9132
9116
  CREATE INDEX IF NOT EXISTS idx_proposals_stash_status
9133
9117
  ON proposals(stash_dir, status);
9134
9118
  CREATE INDEX IF NOT EXISTS idx_proposals_ref_status
9135
9119
  ON proposals(ref, status);
9136
9120
 
9137
- -- \u2500\u2500 task_history \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
9121
+ -- ── task_history ─────────────────────────────────────────────────────────
9138
9122
  --
9139
9123
  -- Replaces per-task JSONL files under <cacheDir>/tasks/history/.
9140
9124
  --
9141
9125
  -- Indexed (query) columns:
9142
- -- task_id TEXT PK \u2014 stable task identifier string.
9143
- -- status TEXT \u2014 terminal status (e.g. "completed", "failed",
9126
+ -- task_id TEXT PK stable task identifier string.
9127
+ -- status TEXT terminal status (e.g. "completed", "failed",
9144
9128
  -- "cancelled"); indexed for status-scoped queries.
9145
- -- started_at TEXT \u2014 ISO-8601; indexed for time-range queries.
9146
- -- target_kind TEXT \u2014 kind of the target entity (e.g. "issue",
9129
+ -- started_at TEXT ISO-8601; indexed for time-range queries.
9130
+ -- target_kind TEXT kind of the target entity (e.g. "issue",
9147
9131
  -- "workflow", "agent"); indexed for kind-scoped queries.
9148
- -- target_ref TEXT \u2014 stable ref of the target entity; indexed for
9132
+ -- target_ref TEXT stable ref of the target entity; indexed for
9149
9133
  -- per-target history lookups.
9150
9134
  --
9151
9135
  -- Non-indexed time columns:
9152
- -- completed_at TEXT \u2014 ISO-8601 or NULL if still running.
9153
- -- failed_at TEXT \u2014 ISO-8601 or NULL.
9136
+ -- completed_at TEXT ISO-8601 or NULL if still running.
9137
+ -- failed_at TEXT ISO-8601 or NULL.
9154
9138
  --
9155
9139
  -- Non-indexed diagnostic columns:
9156
- -- log_path TEXT \u2014 absolute path to the task log file, if any.
9140
+ -- log_path TEXT absolute path to the task log file, if any.
9157
9141
  --
9158
9142
  -- Extensible (metadata_json) columns:
9159
- -- metadata_json TEXT \u2014 JSON object for future task fields (exit_code,
9160
- -- runner, priority, parent_task_id, \u2026).
9143
+ -- metadata_json TEXT JSON object for future task fields (exit_code,
9144
+ -- runner, priority, parent_task_id, ).
9161
9145
  --
9162
9146
  -- ADD COLUMN extension points (future migrations):
9163
9147
  -- ALTER TABLE task_history ADD COLUMN exit_code INTEGER DEFAULT NULL;
@@ -9178,10 +9162,10 @@ var init_migrations = __esm(() => {
9178
9162
  );
9179
9163
 
9180
9164
  -- Query patterns:
9181
- -- SELECT \u2026 WHERE task_id = ? \u2192 PK
9182
- -- SELECT \u2026 WHERE started_at >= ? AND started_at <= ? \u2192 idx_task_history_started
9183
- -- SELECT \u2026 WHERE target_kind = ? AND target_ref = ? \u2192 idx_task_history_target
9184
- -- SELECT \u2026 WHERE status = ? \u2192 idx_task_history_status
9165
+ -- SELECT WHERE task_id = ? PK
9166
+ -- SELECT WHERE started_at >= ? AND started_at <= ? idx_task_history_started
9167
+ -- SELECT WHERE target_kind = ? AND target_ref = ? idx_task_history_target
9168
+ -- SELECT WHERE status = ? idx_task_history_status
9185
9169
  CREATE INDEX IF NOT EXISTS idx_task_history_started
9186
9170
  ON task_history(started_at);
9187
9171
  CREATE INDEX IF NOT EXISTS idx_task_history_target
@@ -9250,12 +9234,12 @@ var init_migrations = __esm(() => {
9250
9234
  );
9251
9235
 
9252
9236
  -- Query patterns supported:
9253
- -- SELECT \u2026 WHERE started_at >= ? AND started_at <= ?
9254
- -- \u2192 idx_improve_runs_started
9255
- -- SELECT \u2026 WHERE dry_run = 0
9256
- -- \u2192 idx_improve_runs_dry_run (productivity audits filter trap)
9257
- -- SELECT \u2026 WHERE stash_dir = ? AND scope_mode = ?
9258
- -- \u2192 idx_improve_runs_stash_scope
9237
+ -- SELECT WHERE started_at >= ? AND started_at <= ?
9238
+ -- idx_improve_runs_started
9239
+ -- SELECT WHERE dry_run = 0
9240
+ -- idx_improve_runs_dry_run (productivity audits filter trap)
9241
+ -- SELECT WHERE stash_dir = ? AND scope_mode = ?
9242
+ -- idx_improve_runs_stash_scope
9259
9243
  CREATE INDEX IF NOT EXISTS idx_improve_runs_started
9260
9244
  ON improve_runs(started_at);
9261
9245
  CREATE INDEX IF NOT EXISTS idx_improve_runs_dry_run
@@ -9282,9 +9266,9 @@ var init_migrations = __esm(() => {
9282
9266
  );
9283
9267
 
9284
9268
  -- Query patterns:
9285
- -- SELECT \u2026 WHERE harness = ? \u2192 idx_extract_sessions_harness
9286
- -- SELECT \u2026 WHERE processed_at >= ? \u2192 idx_extract_sessions_processed
9287
- -- SELECT \u2026 WHERE harness = ? AND session_id = ? \u2192 PK
9269
+ -- SELECT WHERE harness = ? idx_extract_sessions_harness
9270
+ -- SELECT WHERE processed_at >= ? idx_extract_sessions_processed
9271
+ -- SELECT WHERE harness = ? AND session_id = ? PK
9288
9272
  CREATE INDEX IF NOT EXISTS idx_extract_sessions_harness
9289
9273
  ON extract_sessions_seen(harness);
9290
9274
  CREATE INDEX IF NOT EXISTS idx_extract_sessions_processed
@@ -9474,9 +9458,9 @@ __export(exports_state_db, {
9474
9458
  computeImproveRunMetrics: () => computeImproveRunMetrics,
9475
9459
  blobToEmbedding: () => blobToEmbedding
9476
9460
  });
9477
- import path6 from "path";
9461
+ import path7 from "node:path";
9478
9462
  function getStateDbPath() {
9479
- return path6.join(getDataDir(), "state.db");
9463
+ return path7.join(getDataDir(), "state.db");
9480
9464
  }
9481
9465
  function openStateDatabase(dbPath) {
9482
9466
  return openManagedDatabase({ path: dbPath ?? getStateDbPath(), init: runMigrations2 });
@@ -9798,7 +9782,7 @@ function listExistingTableNames(db, names) {
9798
9782
  return db.prepare(`SELECT name FROM sqlite_master WHERE type = 'table' AND name IN (${placeholders}) ORDER BY name`).all(...names);
9799
9783
  }
9800
9784
  async function importEventsJsonl(db, jsonlPath) {
9801
- const { readFileSync, existsSync } = await import("fs");
9785
+ const { readFileSync, existsSync } = await import("node:fs");
9802
9786
  if (!existsSync(jsonlPath)) {
9803
9787
  return { imported: 0, maxId: 0, skipped: 0 };
9804
9788
  }
@@ -10135,7 +10119,7 @@ var init_best_effort = __esm(() => {
10135
10119
  // src/llm/embedders/types.ts
10136
10120
  function cosineSimilarity(a, b) {
10137
10121
  if (a.length !== b.length) {
10138
- warn("cosineSimilarity: vector dimension mismatch (%d vs %d) \u2014 re-index recommended", a.length, b.length);
10122
+ warn("cosineSimilarity: vector dimension mismatch (%d vs %d) re-index recommended", a.length, b.length);
10139
10123
  return 0;
10140
10124
  }
10141
10125
  const len = a.length;
@@ -10225,7 +10209,7 @@ function ensureUsageEventsSchema(db) {
10225
10209
  }
10226
10210
 
10227
10211
  // src/core/file-lock.ts
10228
- import fs6 from "fs";
10212
+ import fs6 from "node:fs";
10229
10213
  function tryAcquireLockSync(lockPath, payload) {
10230
10214
  try {
10231
10215
  fs6.writeFileSync(lockPath, payload, { flag: "wx" });
@@ -10290,8 +10274,8 @@ var init_file_lock = __esm(() => {
10290
10274
  });
10291
10275
 
10292
10276
  // src/core/config/config-io.ts
10293
- import fs7 from "fs";
10294
- import path7 from "path";
10277
+ import fs7 from "node:fs";
10278
+ import path8 from "node:path";
10295
10279
  function parseConfigText(text, sourcePath) {
10296
10280
  const stripped = stripJsonComments(text);
10297
10281
  const where = sourcePath ? ` at ${sourcePath}` : "";
@@ -10327,11 +10311,11 @@ function writeConfigAtomic(configPath, config) {
10327
10311
  function backupExistingConfig(configPath) {
10328
10312
  if (!fs7.existsSync(configPath))
10329
10313
  return;
10330
- const backupDir = path7.join(getCacheDir(), "config-backups");
10314
+ const backupDir = path8.join(getCacheDir(), "config-backups");
10331
10315
  fs7.mkdirSync(backupDir, { recursive: true });
10332
10316
  const timestamp = new Date().toISOString().replace(/[.:]/g, "-");
10333
- const timestamped = path7.join(backupDir, `config-${timestamp}.json`);
10334
- const latest = path7.join(backupDir, "config.latest.json");
10317
+ const timestamped = path8.join(backupDir, `config-${timestamp}.json`);
10318
+ const latest = path8.join(backupDir, "config.latest.json");
10335
10319
  fs7.copyFileSync(configPath, timestamped);
10336
10320
  fs7.copyFileSync(configPath, latest);
10337
10321
  pruneOldBackups(backupDir);
@@ -10345,7 +10329,7 @@ function pruneOldBackups(backupDir) {
10345
10329
  return;
10346
10330
  }
10347
10331
  const timestamped = entries.filter((n) => n.startsWith("config-") && n.endsWith(".json") && n !== "config.latest.json").map((name) => {
10348
- const full = path7.join(backupDir, name);
10332
+ const full = path8.join(backupDir, name);
10349
10333
  let mtime = 0;
10350
10334
  try {
10351
10335
  mtime = fs7.statSync(full).mtimeMs;
@@ -10359,7 +10343,7 @@ function pruneOldBackups(backupDir) {
10359
10343
  }
10360
10344
  }
10361
10345
  function getConfigLockPath() {
10362
- return path7.join(getConfigDir(), "config.json.lck");
10346
+ return path8.join(getConfigDir(), "config.json.lck");
10363
10347
  }
10364
10348
  function sleepSyncMs2(ms) {
10365
10349
  sleepSync(ms);
@@ -10367,7 +10351,7 @@ function sleepSyncMs2(ms) {
10367
10351
  function acquireConfigLock() {
10368
10352
  const lockPath = getConfigLockPath();
10369
10353
  try {
10370
- fs7.mkdirSync(path7.dirname(lockPath), { recursive: true });
10354
+ fs7.mkdirSync(path8.dirname(lockPath), { recursive: true });
10371
10355
  } catch {}
10372
10356
  for (let attempt = 0;attempt < CONFIG_LOCK_MAX_RETRIES; attempt++) {
10373
10357
  try {
@@ -10526,11 +10510,11 @@ var init_inline_refs = __esm(() => {
10526
10510
  });
10527
10511
 
10528
10512
  // src/integrations/harnesses/claude/session-log.ts
10529
- import fs8 from "fs";
10530
- import os from "os";
10531
- import path8 from "path";
10513
+ import fs8 from "node:fs";
10514
+ import os from "node:os";
10515
+ import path9 from "node:path";
10532
10516
  function claudeProjectsDir() {
10533
- return process.env.AKM_CLAUDE_PROJECTS_DIR ?? path8.join(os.homedir(), ".claude", "projects");
10517
+ return process.env.AKM_CLAUDE_PROJECTS_DIR ?? path9.join(os.homedir(), ".claude", "projects");
10534
10518
  }
10535
10519
  function parseClaudeEvent(entry, sessionId, filePath, fallbackTsMs) {
10536
10520
  if (!entry || typeof entry !== "object")
@@ -10637,8 +10621,8 @@ class ClaudeCodeProvider {
10637
10621
  }
10638
10622
  if (stat.mtimeMs < sinceMs)
10639
10623
  continue;
10640
- const sessionId = path8.basename(jsonlPath, ".jsonl");
10641
- const projectHint = path8.basename(path8.dirname(jsonlPath));
10624
+ const sessionId = path9.basename(jsonlPath, ".jsonl");
10625
+ const projectHint = path9.basename(path9.dirname(jsonlPath));
10642
10626
  const peek = this.#peekJsonl(jsonlPath);
10643
10627
  summaries.push({
10644
10628
  harness: this.name,
@@ -10662,7 +10646,7 @@ class ClaudeCodeProvider {
10662
10646
  let title;
10663
10647
  let firstTsMs;
10664
10648
  let lastTsMs;
10665
- const projectHint = path8.basename(path8.dirname(ref.filePath));
10649
+ const projectHint = path9.basename(path9.dirname(ref.filePath));
10666
10650
  for (const line of lines) {
10667
10651
  let entry;
10668
10652
  try {
@@ -10755,7 +10739,7 @@ class ClaudeCodeProvider {
10755
10739
  *#walkJsonl(dir) {
10756
10740
  try {
10757
10741
  for (const entry of fs8.readdirSync(dir, { withFileTypes: true })) {
10758
- const full = path8.join(dir, entry.name);
10742
+ const full = path9.join(dir, entry.name);
10759
10743
  if (entry.isDirectory())
10760
10744
  yield* this.#walkJsonl(full);
10761
10745
  else if (entry.name.endsWith(".jsonl") && entry.name !== "journal.jsonl")
@@ -10812,14 +10796,14 @@ var init_agent_builder2 = __esm(() => {
10812
10796
  var init_config_import2 = () => {};
10813
10797
 
10814
10798
  // src/integrations/harnesses/opencode/session-log.ts
10815
- import fs9 from "fs";
10816
- import os2 from "os";
10817
- import path9 from "path";
10799
+ import fs9 from "node:fs";
10800
+ import os2 from "node:os";
10801
+ import path10 from "node:path";
10818
10802
  function getOpenCodeBaseDir() {
10819
10803
  if (process.platform === "darwin") {
10820
- return path9.join(os2.homedir(), "Library", "Application Support", "opencode");
10804
+ return path10.join(os2.homedir(), "Library", "Application Support", "opencode");
10821
10805
  }
10822
- return path9.join(os2.homedir(), ".local", "share", "opencode");
10806
+ return path10.join(os2.homedir(), ".local", "share", "opencode");
10823
10807
  }
10824
10808
 
10825
10809
  class OpenCodeProvider {
@@ -10829,25 +10813,25 @@ class OpenCodeProvider {
10829
10813
  return fs9.existsSync(this.#baseDir);
10830
10814
  }
10831
10815
  #dbPath(base) {
10832
- return path9.join(base, OPENCODE_DB_FILENAME);
10816
+ return path10.join(base, OPENCODE_DB_FILENAME);
10833
10817
  }
10834
10818
  watchRoots() {
10835
10819
  const roots = [];
10836
10820
  if (fs9.existsSync(this.#dbPath(this.#baseDir)))
10837
10821
  roots.push(this.#baseDir);
10838
- const sessionRoot = path9.join(this.#baseDir, "storage", "session");
10822
+ const sessionRoot = path10.join(this.#baseDir, "storage", "session");
10839
10823
  if (fs9.existsSync(sessionRoot))
10840
10824
  roots.push(sessionRoot);
10841
10825
  return roots;
10842
10826
  }
10843
10827
  *readEvents(input) {
10844
- const candidates = [this.#baseDir, path9.join(this.#baseDir, "log")];
10828
+ const candidates = [this.#baseDir, path10.join(this.#baseDir, "log")];
10845
10829
  for (const dir of candidates) {
10846
10830
  if (!fs9.existsSync(dir))
10847
10831
  continue;
10848
10832
  try {
10849
10833
  for (const file of fs9.readdirSync(dir)) {
10850
- const full = path9.join(dir, file);
10834
+ const full = path10.join(dir, file);
10851
10835
  let stat;
10852
10836
  try {
10853
10837
  stat = fs9.statSync(full);
@@ -10890,13 +10874,13 @@ class OpenCodeProvider {
10890
10874
  const dbPath = this.#dbPath(base);
10891
10875
  if (fs9.existsSync(dbPath))
10892
10876
  return this.#listSessionsFromDb(dbPath, sinceMs);
10893
- const sessionRoot = path9.join(base, "storage", "session");
10877
+ const sessionRoot = path10.join(base, "storage", "session");
10894
10878
  if (!fs9.existsSync(sessionRoot))
10895
10879
  return [];
10896
10880
  const summaries = [];
10897
10881
  try {
10898
10882
  for (const projectId of fs9.readdirSync(sessionRoot)) {
10899
- const projectDir = path9.join(sessionRoot, projectId);
10883
+ const projectDir = path10.join(sessionRoot, projectId);
10900
10884
  let pstat;
10901
10885
  try {
10902
10886
  pstat = fs9.statSync(projectDir);
@@ -10908,7 +10892,7 @@ class OpenCodeProvider {
10908
10892
  for (const file of fs9.readdirSync(projectDir)) {
10909
10893
  if (!file.endsWith(".json"))
10910
10894
  continue;
10911
- const filePath = path9.join(projectDir, file);
10895
+ const filePath = path10.join(projectDir, file);
10912
10896
  let stat;
10913
10897
  try {
10914
10898
  stat = fs9.statSync(filePath);
@@ -10923,7 +10907,7 @@ class OpenCodeProvider {
10923
10907
  } catch {
10924
10908
  continue;
10925
10909
  }
10926
- const sessionId = typeof meta?.id === "string" ? meta.id : path9.basename(file, ".json");
10910
+ const sessionId = typeof meta?.id === "string" ? meta.id : path10.basename(file, ".json");
10927
10911
  const time = meta?.time ?? undefined;
10928
10912
  const startedAt = typeof time?.created === "number" ? time.created : stat.ctimeMs;
10929
10913
  const endedAt = typeof time?.updated === "number" ? time.updated : stat.mtimeMs;
@@ -10944,7 +10928,7 @@ class OpenCodeProvider {
10944
10928
  return summaries.sort((a, b) => (b.endedAt ?? 0) - (a.endedAt ?? 0));
10945
10929
  }
10946
10930
  readSession(ref) {
10947
- if (path9.basename(ref.filePath) === OPENCODE_DB_FILENAME)
10931
+ if (path10.basename(ref.filePath) === OPENCODE_DB_FILENAME)
10948
10932
  return this.#readSessionFromDb(ref);
10949
10933
  let meta = {};
10950
10934
  try {
@@ -10958,12 +10942,12 @@ class OpenCodeProvider {
10958
10942
  const events = [];
10959
10943
  const inlineRefs = [];
10960
10944
  const inferredBase = this.#inferBaseFromSessionPath(ref.filePath) ?? this.#baseDir;
10961
- const msgDir = path9.join(inferredBase, "storage", "message", ref.sessionId);
10945
+ const msgDir = path10.join(inferredBase, "storage", "message", ref.sessionId);
10962
10946
  if (fs9.existsSync(msgDir)) {
10963
10947
  try {
10964
10948
  const files = fs9.readdirSync(msgDir).filter((f) => f.endsWith(".json"));
10965
10949
  for (const file of files) {
10966
- const full = path9.join(msgDir, file);
10950
+ const full = path10.join(msgDir, file);
10967
10951
  let msg;
10968
10952
  try {
10969
10953
  msg = JSON.parse(fs9.readFileSync(full, "utf8"));
@@ -11096,8 +11080,8 @@ class OpenCodeProvider {
11096
11080
  }
11097
11081
  }
11098
11082
  #inferBaseFromSessionPath(filePath) {
11099
- const dir = path9.dirname(filePath);
11100
- const parts = dir.split(path9.sep);
11083
+ const dir = path10.dirname(filePath);
11084
+ const parts = dir.split(path10.sep);
11101
11085
  if (parts.length < 3)
11102
11086
  return;
11103
11087
  const last = parts[parts.length - 1];
@@ -11105,7 +11089,7 @@ class OpenCodeProvider {
11105
11089
  const thirdLast = parts[parts.length - 3];
11106
11090
  if (sndLast !== "session" || thirdLast !== "storage" || !last)
11107
11091
  return;
11108
- return parts.slice(0, parts.length - 3).join(path9.sep);
11092
+ return parts.slice(0, parts.length - 3).join(path10.sep);
11109
11093
  }
11110
11094
  #messageToEvent(msg, sessionId, filePath) {
11111
11095
  const time = msg.time ?? undefined;
@@ -11459,7 +11443,8 @@ function migrateProcessEntryToImprove(result, processName, legacy) {
11459
11443
  }
11460
11444
  }
11461
11445
  }
11462
- function migrateConfigShape(raw) {
11446
+ function migrateConfigShape(raw, opts) {
11447
+ const emitWarn = opts?.warn ?? warn;
11463
11448
  const hasLegacyKeys = Object.hasOwn(raw, "features") || isObj(raw.llm) && (Object.hasOwn(raw.llm, "endpoint") || Object.hasOwn(raw.llm, "features")) || isObj(raw.agent) || Object.hasOwn(raw, "stashes") || typeof raw.semanticSearchMode === "boolean" || hasOpenvikingSource(raw);
11464
11449
  if (raw.configVersion === CURRENT_CONFIG_VERSION && !hasLegacyKeys) {
11465
11450
  return { changed: false, result: raw };
@@ -11476,9 +11461,9 @@ function migrateConfigShape(raw) {
11476
11461
  if (Array.isArray(result.stashes)) {
11477
11462
  if (!Array.isArray(result.sources)) {
11478
11463
  result.sources = result.stashes;
11479
- console.warn("[akm config-migrate] Legacy `stashes[]` config key renamed to `sources[]`. " + "Re-save your config to remove the deprecation notice.");
11464
+ emitWarn("[akm config-migrate] Legacy `stashes[]` config key renamed to `sources[]`. " + "Re-save your config to remove the deprecation notice.");
11480
11465
  } else {
11481
- console.warn("[akm config-migrate] Both `stashes[]` and `sources[]` present; `stashes[]` dropped (sources takes precedence).");
11466
+ emitWarn("[akm config-migrate] Both `stashes[]` and `sources[]` present; `stashes[]` dropped (sources takes precedence).");
11482
11467
  }
11483
11468
  delete result.stashes;
11484
11469
  changed = true;
@@ -11490,7 +11475,7 @@ function migrateConfigShape(raw) {
11490
11475
  for (const entry of sources) {
11491
11476
  if (isObj(entry) && entry.type === "openviking") {
11492
11477
  const name = typeof entry.name === "string" && entry.name ? entry.name : "unnamed";
11493
- console.warn(`[akm config-migrate] Source "${name}" (type: openviking) is no longer supported. ` + "Remove it from your config, or replace with a `website`/`git` source. " + "Entry dropped from sources[].");
11478
+ emitWarn(`[akm config-migrate] Source "${name}" (type: openviking) is no longer supported. ` + "Remove it from your config, or replace with a `website`/`git` source. " + "Entry dropped from sources[].");
11494
11479
  renamed = true;
11495
11480
  continue;
11496
11481
  }
@@ -11603,9 +11588,9 @@ function migrateConfigShape(raw) {
11603
11588
  const camelKey = toCamelCase(legacyKey);
11604
11589
  if (typeof legacyVal === "boolean" || isObj(legacyVal)) {
11605
11590
  migrateProcessEntryToImprove(result, camelKey, legacyVal);
11606
- warn(`[akm config-migrate] Unknown features.improve.${legacyKey} migrated to ` + `profiles.improve.default.processes.${camelKey}. Please verify the new location.`);
11591
+ emitWarn(`[akm config-migrate] Unknown features.improve.${legacyKey} migrated to ` + `profiles.improve.default.processes.${camelKey}. Please verify the new location.`);
11607
11592
  } else {
11608
- warn(`[akm config-migrate] features.improve.${legacyKey} has an unrecognized value type ` + `(${typeof legacyVal}); dropping. Please re-add it under profiles.improve.* manually.`);
11593
+ emitWarn(`[akm config-migrate] features.improve.${legacyKey} has an unrecognized value type ` + `(${typeof legacyVal}); dropping. Please re-add it under profiles.improve.* manually.`);
11609
11594
  }
11610
11595
  }
11611
11596
  changed = true;
@@ -11653,9 +11638,9 @@ function migrateConfigShape(raw) {
11653
11638
  const camelKey = toCamelCase(legacyKey);
11654
11639
  const ok = migrateGenericGateToSection(result, "index", camelKey, legacyVal);
11655
11640
  if (ok) {
11656
- warn(`[akm config-migrate] Unknown features.index.${legacyKey} migrated to ` + `index.${camelKey}. Please verify the new location is correct.`);
11641
+ emitWarn(`[akm config-migrate] Unknown features.index.${legacyKey} migrated to ` + `index.${camelKey}. Please verify the new location is correct.`);
11657
11642
  } else {
11658
- warn(`[akm config-migrate] features.index.${legacyKey} has an unrecognized value shape; ` + `dropping. Please re-add it under index.${camelKey} manually if needed.`);
11643
+ emitWarn(`[akm config-migrate] features.index.${legacyKey} has an unrecognized value shape; ` + `dropping. Please re-add it under index.${camelKey} manually if needed.`);
11659
11644
  }
11660
11645
  }
11661
11646
  changed = true;
@@ -11678,9 +11663,9 @@ function migrateConfigShape(raw) {
11678
11663
  const camelKey = toCamelCase(legacyKey);
11679
11664
  const ok = migrateGenericGateToSection(result, "search", camelKey, legacyVal);
11680
11665
  if (ok) {
11681
- warn(`[akm config-migrate] Unknown features.search.${legacyKey} migrated to ` + `search.${camelKey}. Please verify the new location is correct.`);
11666
+ emitWarn(`[akm config-migrate] Unknown features.search.${legacyKey} migrated to ` + `search.${camelKey}. Please verify the new location is correct.`);
11682
11667
  } else {
11683
- warn(`[akm config-migrate] features.search.${legacyKey} has an unrecognized value shape; ` + `dropping. Please re-add it under search.${camelKey} manually if needed.`);
11668
+ emitWarn(`[akm config-migrate] features.search.${legacyKey} has an unrecognized value shape; ` + `dropping. Please re-add it under search.${camelKey} manually if needed.`);
11684
11669
  }
11685
11670
  }
11686
11671
  changed = true;
@@ -11783,7 +11768,7 @@ function migrateConfigShape(raw) {
11783
11768
  changed = true;
11784
11769
  }
11785
11770
  if (improveObj.preset !== undefined) {
11786
- console.warn("[akm config-migrate] defaults.improve.preset is no longer supported. " + "Use `--profile <name>` (built-ins: default, quick, thorough, memory-focus) instead.");
11771
+ emitWarn("[akm config-migrate] defaults.improve.preset is no longer supported. " + "Use `--profile <name>` (built-ins: default, quick, thorough, memory-focus) instead.");
11787
11772
  }
11788
11773
  delete defaultsRaw.improve;
11789
11774
  if (Object.keys(defaultsRaw).length > 0) {
@@ -12277,8 +12262,8 @@ class ParseStatus {
12277
12262
  }
12278
12263
  }
12279
12264
  var makeIssue = (params) => {
12280
- const { data, path: path10, errorMaps, issueData } = params;
12281
- const fullPath = [...path10, ...issueData.path || []];
12265
+ const { data, path: path11, errorMaps, issueData } = params;
12266
+ const fullPath = [...path11, ...issueData.path || []];
12282
12267
  const fullIssue = {
12283
12268
  ...issueData,
12284
12269
  path: fullPath
@@ -12324,11 +12309,11 @@ var init_errorUtil = __esm(() => {
12324
12309
 
12325
12310
  // node_modules/zod/v3/types.js
12326
12311
  class ParseInputLazyPath {
12327
- constructor(parent, value, path10, key) {
12312
+ constructor(parent, value, path11, key) {
12328
12313
  this._cachedPath = [];
12329
12314
  this.parent = parent;
12330
12315
  this.data = value;
12331
- this._path = path10;
12316
+ this._path = path11;
12332
12317
  this._key = key;
12333
12318
  }
12334
12319
  get path() {
@@ -15963,7 +15948,7 @@ var init_config_schema = __esm(() => {
15963
15948
  if ("feedbackDistillation" in val) {
15964
15949
  ctx.addIssue({
15965
15950
  code: exports_external.ZodIssueCode.custom,
15966
- message: "feedbackDistillation was removed in 0.8.0 \u2014 use processes.distill.enabled instead. " + "It now controls both the orchestration gate and the LLM-call gate."
15951
+ message: "feedbackDistillation was removed in 0.8.0 use processes.distill.enabled instead. " + "It now controls both the orchestration gate and the LLM-call gate."
15967
15952
  });
15968
15953
  }
15969
15954
  });
@@ -16251,7 +16236,7 @@ var init_config_schema = __esm(() => {
16251
16236
  });
16252
16237
 
16253
16238
  // src/core/config/config-sources.ts
16254
- import { createHash as createHash2 } from "crypto";
16239
+ import { createHash as createHash2 } from "node:crypto";
16255
16240
  function deriveStashEntryName(entry) {
16256
16241
  if (entry.name)
16257
16242
  return entry.name;
@@ -16352,8 +16337,8 @@ __export(exports_config, {
16352
16337
  DEFAULT_GRAPH_EXTRACTION_BATCH_SIZE: () => DEFAULT_GRAPH_EXTRACTION_BATCH_SIZE,
16353
16338
  DEFAULT_CONFIG: () => DEFAULT_CONFIG
16354
16339
  });
16355
- import fs10 from "fs";
16356
- import path10 from "path";
16340
+ import fs10 from "node:fs";
16341
+ import path11 from "node:path";
16357
16342
  function resolveBatchSize(configured, contextLength) {
16358
16343
  const base = configured && configured > 0 ? configured : DEFAULT_GRAPH_EXTRACTION_BATCH_SIZE;
16359
16344
  if (!contextLength || contextLength <= 0)
@@ -16467,13 +16452,13 @@ function maybeAutoMigrateConfigFile(configPath, text) {
16467
16452
  const newVersion = typeof result.configVersion === "string" ? result.configVersion : "0.8.0";
16468
16453
  const backupDir = `${getCacheDir()}/config-backups`;
16469
16454
  const banner = [
16470
- "\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501",
16471
- ` akm: auto-migrated config \u2192 ${newVersion} format`,
16455
+ "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━",
16456
+ ` akm: auto-migrated config ${newVersion} format`,
16472
16457
  ` file: ${configPath}`,
16473
16458
  ` backup: ${backupDir}/config-<timestamp>.json`,
16474
16459
  " to opt out of future auto-migration: AKM_NO_AUTO_MIGRATE=1",
16475
16460
  " to preview a dry-run diff: akm config migrate --dry-run --print-diff",
16476
- "\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"
16461
+ "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
16477
16462
  ].join(`
16478
16463
  `);
16479
16464
  process.stderr?.write?.(`${banner}
@@ -16492,7 +16477,7 @@ function loadConfig() {
16492
16477
  function saveConfig(config) {
16493
16478
  cachedConfig = undefined;
16494
16479
  const configPath = getConfigPath();
16495
- const dir = path10.dirname(configPath);
16480
+ const dir = path11.dirname(configPath);
16496
16481
  fs10.mkdirSync(dir, { recursive: true });
16497
16482
  const sanitized = sanitizeConfigForWrite(config);
16498
16483
  const parseResult = AkmConfigSchema.safeParse(sanitized);
@@ -16638,14 +16623,14 @@ function applyRuntimeEnvApiKeys(config) {
16638
16623
  return next;
16639
16624
  }
16640
16625
  function warnIfProjectConfigPresent(startDir) {
16641
- let currentDir = path10.resolve(startDir);
16626
+ let currentDir = path11.resolve(startDir);
16642
16627
  while (true) {
16643
- const configPath = path10.join(currentDir, PROJECT_CONFIG_RELATIVE_PATH);
16628
+ const configPath = path11.join(currentDir, PROJECT_CONFIG_RELATIVE_PATH);
16644
16629
  if (isFile(configPath) && !PROJECT_CONFIG_DEPRECATION_WARNED.has(configPath)) {
16645
16630
  PROJECT_CONFIG_DEPRECATION_WARNED.add(configPath);
16646
16631
  warn(`[akm] DEPRECATED: project-level config file found at ${configPath}. ` + "Project-level config files are no longer merged (removed after 0.8.x deprecation). " + "Move any needed settings to ~/.config/akm/config.json; this file is ignored.");
16647
16632
  }
16648
- const parentDir = path10.dirname(currentDir);
16633
+ const parentDir = path11.dirname(currentDir);
16649
16634
  if (parentDir === currentDir)
16650
16635
  break;
16651
16636
  currentDir = parentDir;
@@ -16687,7 +16672,7 @@ var init_config2 = __esm(() => {
16687
16672
  detail: "brief"
16688
16673
  }
16689
16674
  };
16690
- PROJECT_CONFIG_RELATIVE_PATH = path10.join(".akm", "config.json");
16675
+ PROJECT_CONFIG_RELATIVE_PATH = path11.join(".akm", "config.json");
16691
16676
  INDEX_RESERVED_KEYS = new Set(["metadataEnhance", "stalenessDetection"]);
16692
16677
  PROJECT_CONFIG_DEPRECATION_WARNED = new Set;
16693
16678
  });
@@ -16757,12 +16742,12 @@ __export(exports_db, {
16757
16742
  EMBEDDING_DIM: () => EMBEDDING_DIM,
16758
16743
  DB_VERSION: () => DB_VERSION
16759
16744
  });
16760
- import fs11 from "fs";
16761
- import { createRequire as createRequire3 } from "module";
16762
- import path11 from "path";
16745
+ import fs11 from "node:fs";
16746
+ import { createRequire as createRequire4 } from "node:module";
16747
+ import path12 from "node:path";
16763
16748
  function openIndexDatabase(dbPath, options) {
16764
16749
  const resolvedPath = dbPath ?? getDbPath();
16765
- const dir = path11.dirname(resolvedPath);
16750
+ const dir = path12.dirname(resolvedPath);
16766
16751
  if (!fs11.existsSync(dir)) {
16767
16752
  fs11.mkdirSync(dir, { recursive: true });
16768
16753
  }
@@ -16788,7 +16773,7 @@ function resolveConfiguredEmbeddingDim() {
16788
16773
  }
16789
16774
  function openExistingDatabase(dbPath) {
16790
16775
  const resolvedPath = dbPath ?? getDbPath();
16791
- const dir = path11.dirname(resolvedPath);
16776
+ const dir = path12.dirname(resolvedPath);
16792
16777
  const db = openDatabase(resolvedPath);
16793
16778
  applyStandardPragmas(db, { dataDir: dir });
16794
16779
  loadVecExtension(db);
@@ -16799,7 +16784,7 @@ function closeDatabase(db) {
16799
16784
  }
16800
16785
  function loadVecExtension(db) {
16801
16786
  try {
16802
- const esmRequire = createRequire3(import.meta.url);
16787
+ const esmRequire = createRequire4(import.meta.url);
16803
16788
  const sqliteVec = esmRequire("sqlite-vec");
16804
16789
  sqliteVec.load(db);
16805
16790
  vecStatus.set(db, true);
@@ -17008,7 +16993,7 @@ function ensureSchema(db, embeddingDim) {
17008
16993
  );
17009
16994
 
17010
16995
  -- #624-P3: lazy graph-extraction queue. Standalone table (NO FK to
17011
- -- graph_files \u2014 a queued file by definition has no graph row yet).
16996
+ -- graph_files a queued file by definition has no graph row yet).
17012
16997
  -- Idempotent on (stash_root, file_path); drained highest-priority-first.
17013
16998
  -- CREATE TABLE IF NOT EXISTS is the forward migration (no DB_VERSION bump).
17014
16999
  CREATE TABLE IF NOT EXISTS graph_extraction_queue (
@@ -17104,7 +17089,7 @@ function deleteIndexDirState(db, dirPath) {
17104
17089
  db.prepare("DELETE FROM index_dir_state WHERE dir_path = ?").run(dirPath);
17105
17090
  }
17106
17091
  function deleteIndexDirStatesByStashDir(db, stashDir) {
17107
- db.prepare("DELETE FROM index_dir_state WHERE dir_path = ? OR dir_path LIKE ?").run(stashDir, `${stashDir}${path11.sep}%`);
17092
+ db.prepare("DELETE FROM index_dir_state WHERE dir_path = ? OR dir_path LIKE ?").run(stashDir, `${stashDir}${path12.sep}%`);
17108
17093
  }
17109
17094
  function upsertEntry(db, entryKey, dirPath, filePath, stashDir, entry, searchText) {
17110
17095
  const stmts = getUpsertStmts(db);
@@ -17146,7 +17131,7 @@ function ensureDerivedFromColumn(db) {
17146
17131
  db.exec("ALTER TABLE entries ADD COLUMN derived_from TEXT");
17147
17132
  }
17148
17133
  db.exec("CREATE INDEX IF NOT EXISTS idx_entries_derived_from ON entries(derived_from)");
17149
- }, "entries table may not exist on a brand-new DB before CREATE \u2014 caller is responsible");
17134
+ }, "entries table may not exist on a brand-new DB before CREATE caller is responsible");
17150
17135
  }
17151
17136
  function tableExists(db, name) {
17152
17137
  const row = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name=? LIMIT 1").get(name);
@@ -17168,7 +17153,7 @@ function migrateGraphFilesSchema(db) {
17168
17153
  if (tableExists(db, "graph_file_relations")) {
17169
17154
  db.exec("ALTER TABLE graph_file_relations RENAME TO graph_file_relations_legacy");
17170
17155
  }
17171
- }, "graph_files may not exist on a brand-new DB before CREATE \u2014 caller is responsible");
17156
+ }, "graph_files may not exist on a brand-new DB before CREATE caller is responsible");
17172
17157
  }
17173
17158
  function migrateGraphDataFromLegacy(db) {
17174
17159
  if (!tableExists(db, "graph_files_legacy"))
@@ -17206,7 +17191,7 @@ function migrateGraphDataFromLegacy(db) {
17206
17191
  db.exec("DROP TABLE IF EXISTS graph_files_legacy");
17207
17192
  }, "drop legacy graph tables after migration");
17208
17193
  if (migratedFiles > 0) {
17209
- warn(`[akm] graph index re-keyed (#624): migrated ${migratedFiles} extracted file(s) to the new schema \u2014 no re-extraction needed. Index + embeddings untouched.`);
17194
+ warn(`[akm] graph index re-keyed (#624): migrated ${migratedFiles} extracted file(s) to the new schema no re-extraction needed. Index + embeddings untouched.`);
17210
17195
  }
17211
17196
  }
17212
17197
  function getDerivedForParent(db, parentRef) {
@@ -17224,7 +17209,7 @@ function getDerivedForParent(db, parentRef) {
17224
17209
  try {
17225
17210
  entry = JSON.parse(row.entry_json);
17226
17211
  } catch {
17227
- warn(`[db] getDerivedForParent: skipping entry id=${row.id} \u2014 corrupt entry_json`);
17212
+ warn(`[db] getDerivedForParent: skipping entry id=${row.id} corrupt entry_json`);
17228
17213
  return null;
17229
17214
  }
17230
17215
  return {
@@ -17259,7 +17244,7 @@ function getPositiveFeedbackCountsByIds(db, ids) {
17259
17244
  result.set(row.entry_id, row.cnt);
17260
17245
  }
17261
17246
  }
17262
- }, "usage_events table may be missing on legacy DBs \u2014 treat as zero counts");
17247
+ }, "usage_events table may be missing on legacy DBs treat as zero counts");
17263
17248
  }
17264
17249
  return result;
17265
17250
  }
@@ -17414,7 +17399,7 @@ function float32Buffer(vec) {
17414
17399
  }
17415
17400
  function bufferToFloat32(buf, expectedDim) {
17416
17401
  if (buf.byteLength !== expectedDim * 4) {
17417
- warn("[db] bufferToFloat32: skipping embedding row \u2014 expected %d bytes (%d dim x 4), got %d", expectedDim * 4, expectedDim, buf.byteLength);
17402
+ warn("[db] bufferToFloat32: skipping embedding row expected %d bytes (%d dim x 4), got %d", expectedDim * 4, expectedDim, buf.byteLength);
17418
17403
  return null;
17419
17404
  }
17420
17405
  const aligned = new ArrayBuffer(buf.byteLength);
@@ -17510,7 +17495,7 @@ function runFtsQuery(db, ftsQuery, limit, entryType, excludeTypes) {
17510
17495
  try {
17511
17496
  entry = JSON.parse(row.entry_json);
17512
17497
  } catch {
17513
- warn(`[db] searchFts: skipping entry id=${row.id} \u2014 corrupt entry_json`);
17498
+ warn(`[db] searchFts: skipping entry id=${row.id} corrupt entry_json`);
17514
17499
  continue;
17515
17500
  }
17516
17501
  results.push({
@@ -17541,7 +17526,7 @@ function parseEntryRows(rows, context) {
17541
17526
  try {
17542
17527
  entry = JSON.parse(row.entry_json);
17543
17528
  } catch {
17544
- warn(`[db] ${context}: skipping entry id=${row.id} \u2014 corrupt entry_json`);
17529
+ warn(`[db] ${context}: skipping entry id=${row.id} corrupt entry_json`);
17545
17530
  continue;
17546
17531
  }
17547
17532
  entries.push({
@@ -17637,7 +17622,7 @@ function getEntryById(db, id) {
17637
17622
  try {
17638
17623
  entry = JSON.parse(row.entry_json);
17639
17624
  } catch {
17640
- warn(`[db] getEntryById: skipping entry id=${id} \u2014 corrupt entry_json`);
17625
+ warn(`[db] getEntryById: skipping entry id=${id} corrupt entry_json`);
17641
17626
  return;
17642
17627
  }
17643
17628
  return { filePath: row.file_path, entry };
@@ -18020,6 +18005,45 @@ var init_db = __esm(() => {
18020
18005
  upsertStmtsByDb = new WeakMap;
18021
18006
  });
18022
18007
 
18008
+ // src/indexer/db/db.ts
18009
+ import { createRequire as createRequire5 } from "node:module";
18010
+ import path13 from "node:path";
18011
+ function openExistingDatabase2(dbPath) {
18012
+ const resolvedPath = dbPath ?? getDbPath();
18013
+ const dir = path13.dirname(resolvedPath);
18014
+ const db = openDatabase(resolvedPath);
18015
+ applyStandardPragmas(db, { dataDir: dir });
18016
+ loadVecExtension2(db);
18017
+ return db;
18018
+ }
18019
+ function closeDatabase2(db) {
18020
+ db.close();
18021
+ }
18022
+ function loadVecExtension2(db) {
18023
+ try {
18024
+ const esmRequire = createRequire5(import.meta.url);
18025
+ const sqliteVec = esmRequire("sqlite-vec");
18026
+ sqliteVec.load(db);
18027
+ vecStatus2.set(db, true);
18028
+ } catch {
18029
+ vecStatus2.set(db, false);
18030
+ }
18031
+ }
18032
+ var vecStatus2, vecInitWarnedDbs2, upsertStmtsByDb2;
18033
+ var init_db2 = __esm(() => {
18034
+ init_asset_ref();
18035
+ init_best_effort();
18036
+ init_paths();
18037
+ init_warn();
18038
+ init_types();
18039
+ init_runtime();
18040
+ init_database();
18041
+ init_sqlite_pragmas();
18042
+ vecStatus2 = new WeakMap;
18043
+ vecInitWarnedDbs2 = new WeakSet;
18044
+ upsertStmtsByDb2 = new WeakMap;
18045
+ });
18046
+
18023
18047
  // src/indexer/db/graph-db.ts
18024
18048
  var exports_graph_db = {};
18025
18049
  __export(exports_graph_db, {
@@ -18034,18 +18058,18 @@ __export(exports_graph_db, {
18034
18058
  drainExtractionQueue: () => drainExtractionQueue,
18035
18059
  deleteStoredGraph: () => deleteStoredGraph
18036
18060
  });
18037
- import fs12 from "fs";
18061
+ import fs12 from "node:fs";
18038
18062
  function withReadableGraphDb(db, fn) {
18039
18063
  if (db)
18040
18064
  return fn(db);
18041
18065
  const dbPath = getDbPath();
18042
18066
  if (!fs12.existsSync(dbPath))
18043
18067
  throw new Error("GRAPH_DB_MISSING");
18044
- const opened = openExistingDatabase(dbPath);
18068
+ const opened = openExistingDatabase2(dbPath);
18045
18069
  try {
18046
18070
  return fn(opened);
18047
18071
  } finally {
18048
- closeDatabase(opened);
18072
+ closeDatabase2(opened);
18049
18073
  }
18050
18074
  }
18051
18075
  function uniqueSorted(values) {
@@ -18378,16 +18402,107 @@ function loadStoredGraphSnapshot(stashPath, db) {
18378
18402
  var init_graph_db = __esm(() => {
18379
18403
  init_errors();
18380
18404
  init_paths();
18381
- init_db();
18405
+ init_db2();
18382
18406
  });
18383
18407
 
18384
18408
  // scripts/migrate-storage.ts
18385
- init_paths();
18386
18409
  import fs13 from "fs";
18387
18410
  import os3 from "os";
18388
- import path12 from "path";
18411
+ import path14 from "path";
18389
18412
  import readline from "readline";
18390
18413
 
18414
+ // src/core/paths.ts
18415
+ init_common();
18416
+ init_errors();
18417
+ import path5 from "node:path";
18418
+ function isTransientStashPath2(p) {
18419
+ return p.startsWith("/tmp/") || p === "/tmp" || p.startsWith("/var/tmp/") || p === "/var/tmp" || p.startsWith("/private/tmp/") || p.startsWith("/private/var/folders/") || p.startsWith("/var/folders/");
18420
+ }
18421
+ function getConfigDir2(env = process.env, platform = process.platform) {
18422
+ const override = env.AKM_CONFIG_DIR?.trim();
18423
+ if (override)
18424
+ return override;
18425
+ if (platform === "win32") {
18426
+ const appData = env.APPDATA?.trim();
18427
+ if (appData)
18428
+ return path5.join(appData, "akm");
18429
+ } else {
18430
+ const xdgConfigHome2 = env.XDG_CONFIG_HOME?.trim();
18431
+ if (xdgConfigHome2)
18432
+ return path5.join(xdgConfigHome2, "akm");
18433
+ }
18434
+ const stashOverride = env.AKM_STASH_DIR?.trim();
18435
+ if (stashOverride && isTransientStashPath2(stashOverride)) {
18436
+ return path5.join(stashOverride, ".akm");
18437
+ }
18438
+ if (platform === "win32") {
18439
+ const appData = env.APPDATA?.trim();
18440
+ if (appData)
18441
+ return path5.join(appData, "akm");
18442
+ const userProfile = env.USERPROFILE?.trim();
18443
+ if (!userProfile) {
18444
+ throw new ConfigError("Unable to determine config directory. Set APPDATA or USERPROFILE.", "CONFIG_DIR_UNRESOLVABLE");
18445
+ }
18446
+ return path5.join(userProfile, "AppData", "Roaming", "akm");
18447
+ }
18448
+ const xdgConfigHome = env.XDG_CONFIG_HOME?.trim();
18449
+ if (xdgConfigHome)
18450
+ return path5.join(xdgConfigHome, "akm");
18451
+ const home = env.HOME?.trim();
18452
+ if (!home) {
18453
+ throw new ConfigError("Unable to determine config directory. Set XDG_CONFIG_HOME or HOME.", "CONFIG_DIR_UNRESOLVABLE");
18454
+ }
18455
+ return path5.join(home, ".config", "akm");
18456
+ }
18457
+ function getCacheDir2() {
18458
+ const override = process.env.AKM_CACHE_DIR?.trim();
18459
+ if (override)
18460
+ return override;
18461
+ if (IS_WINDOWS) {
18462
+ const localAppData = process.env.LOCALAPPDATA?.trim();
18463
+ if (localAppData)
18464
+ return path5.join(localAppData, "akm");
18465
+ const userProfile = process.env.USERPROFILE?.trim();
18466
+ if (userProfile)
18467
+ return path5.join(userProfile, "AppData", "Local", "akm");
18468
+ const appData = process.env.APPDATA?.trim();
18469
+ if (appData) {
18470
+ return path5.join(appData, "..", "Local", "akm");
18471
+ }
18472
+ } else {
18473
+ const xdgCacheHome = process.env.XDG_CACHE_HOME?.trim();
18474
+ if (xdgCacheHome)
18475
+ return path5.join(xdgCacheHome, "akm");
18476
+ }
18477
+ const stashOverride = process.env.AKM_STASH_DIR?.trim();
18478
+ if (stashOverride && isTransientStashPath2(stashOverride)) {
18479
+ return path5.join(stashOverride, ".akm", "cache");
18480
+ }
18481
+ if (IS_WINDOWS) {
18482
+ throw new ConfigError("Unable to determine cache directory. Set LOCALAPPDATA, USERPROFILE, or APPDATA.", "CONFIG_DIR_UNRESOLVABLE");
18483
+ }
18484
+ const home = process.env.HOME?.trim();
18485
+ if (!home)
18486
+ return path5.join("/tmp", "akm-cache");
18487
+ return path5.join(home, ".cache", "akm");
18488
+ }
18489
+ function getDefaultStashDir2() {
18490
+ const override = process.env.AKM_STASH_DIR?.trim();
18491
+ if (override)
18492
+ return override;
18493
+ if (IS_WINDOWS) {
18494
+ const userProfile = process.env.USERPROFILE?.trim();
18495
+ if (userProfile)
18496
+ return path5.join(userProfile, "Documents", "akm");
18497
+ return path5.join("C:\\", "akm");
18498
+ }
18499
+ const home = process.env.HOME?.trim();
18500
+ if (!home) {
18501
+ throw new ConfigError("Unable to determine default stash directory. Set HOME.", "STASH_DIR_NOT_FOUND");
18502
+ }
18503
+ return path5.join(home, "akm");
18504
+ }
18505
+
18391
18506
  // src/indexer/usage/unmigrated-vaults-guard.ts
18392
18507
  init_warn();
18393
18508
  var MIGRATED_MARKER = ".migrated";
@@ -18410,12 +18525,12 @@ function parseFromArg() {
18410
18525
  return val;
18411
18526
  }
18412
18527
  var FROM_VERSION = parseFromArg();
18413
- var dataDir = process.env.AKM_DATA_DIR?.trim() ?? (process.env.XDG_DATA_HOME?.trim() ? path12.join(process.env.XDG_DATA_HOME.trim(), "akm") : path12.join(os3.homedir(), ".local", "share", "akm"));
18414
- var stateDir = process.env.AKM_STATE_DIR?.trim() ?? (process.env.XDG_STATE_HOME?.trim() ? path12.join(process.env.XDG_STATE_HOME.trim(), "akm") : path12.join(os3.homedir(), ".local", "state", "akm"));
18415
- var cacheDir = getCacheDir();
18416
- var configDir = getConfigDir();
18417
- var stateDbPath = path12.join(dataDir, "state.db");
18418
- var indexDbPath = path12.join(dataDir, "index.db");
18528
+ var dataDir = process.env.AKM_DATA_DIR?.trim() ?? (process.env.XDG_DATA_HOME?.trim() ? path14.join(process.env.XDG_DATA_HOME.trim(), "akm") : path14.join(os3.homedir(), ".local", "share", "akm"));
18529
+ var stateDir = process.env.AKM_STATE_DIR?.trim() ?? (process.env.XDG_STATE_HOME?.trim() ? path14.join(process.env.XDG_STATE_HOME.trim(), "akm") : path14.join(os3.homedir(), ".local", "state", "akm"));
18530
+ var cacheDir = getCacheDir2();
18531
+ var configDir = getConfigDir2();
18532
+ var stateDbPath = path14.join(dataDir, "state.db");
18533
+ var indexDbPath = path14.join(dataDir, "index.db");
18419
18534
  var PATHS = {
18420
18535
  cacheDir,
18421
18536
  configDir,
@@ -18442,8 +18557,8 @@ function copyTree(src, dest, opts) {
18442
18557
  let failed = 0;
18443
18558
  ensureDir(dest);
18444
18559
  for (const entry of fs13.readdirSync(src, { withFileTypes: true })) {
18445
- const srcEntry = path12.join(src, entry.name);
18446
- const destEntry = path12.join(dest, entry.name);
18560
+ const srcEntry = path14.join(src, entry.name);
18561
+ const destEntry = path14.join(dest, entry.name);
18447
18562
  if (entry.isDirectory()) {
18448
18563
  const sub = copyTree(srcEntry, destEntry, opts);
18449
18564
  copied += sub.copied;
@@ -18471,7 +18586,7 @@ function countFilesRecursive(dir) {
18471
18586
  let count = 0;
18472
18587
  for (const entry of fs13.readdirSync(dir, { withFileTypes: true })) {
18473
18588
  if (entry.isDirectory()) {
18474
- count += countFilesRecursive(path12.join(dir, entry.name));
18589
+ count += countFilesRecursive(path14.join(dir, entry.name));
18475
18590
  } else {
18476
18591
  count++;
18477
18592
  }
@@ -18484,8 +18599,8 @@ async function runSteps(steps, ctx) {
18484
18599
  }
18485
18600
  }
18486
18601
  function migrateDb(ctx, filename) {
18487
- const src = path12.join(ctx.paths.cacheDir, filename);
18488
- const dest = path12.join(ctx.paths.dataDir, filename);
18602
+ const src = path14.join(ctx.paths.cacheDir, filename);
18603
+ const dest = path14.join(ctx.paths.dataDir, filename);
18489
18604
  if (!fs13.existsSync(src)) {
18490
18605
  return { name: filename, status: "skipped", detail: "source not found" };
18491
18606
  }
@@ -18507,7 +18622,7 @@ function migrateDb(ctx, filename) {
18507
18622
  return { name: filename, status: "failed", detail: `size mismatch after copy: ${src} \u2192 ${dest}` };
18508
18623
  }
18509
18624
  async function migrateEventsJsonl(ctx) {
18510
- const src = path12.join(ctx.paths.cacheDir, "events.jsonl");
18625
+ const src = path14.join(ctx.paths.cacheDir, "events.jsonl");
18511
18626
  if (!fs13.existsSync(src)) {
18512
18627
  return { name: "events.jsonl \u2192 state.db", status: "skipped", detail: "source not found" };
18513
18628
  }
@@ -18552,8 +18667,8 @@ async function migrateEventsJsonl(ctx) {
18552
18667
  }
18553
18668
  }
18554
18669
  function migrateTaskHistory(ctx) {
18555
- const src = path12.join(ctx.paths.cacheDir, "tasks", "history");
18556
- const dest = path12.join(ctx.paths.stateDir, "tasks", "history");
18670
+ const src = path14.join(ctx.paths.cacheDir, "tasks", "history");
18671
+ const dest = path14.join(ctx.paths.stateDir, "tasks", "history");
18557
18672
  if (!fs13.existsSync(src)) {
18558
18673
  return { name: "tasks/history/", status: "skipped", detail: "source directory not found" };
18559
18674
  }
@@ -18573,8 +18688,8 @@ function migrateTaskHistory(ctx) {
18573
18688
  let copied = 0;
18574
18689
  let failed = 0;
18575
18690
  for (const file of files) {
18576
- const srcFile = path12.join(src, file);
18577
- const destFile = path12.join(dest, file);
18691
+ const srcFile = path14.join(src, file);
18692
+ const destFile = path14.join(dest, file);
18578
18693
  try {
18579
18694
  if (copyAndVerify(srcFile, destFile)) {
18580
18695
  copied++;
@@ -18603,8 +18718,8 @@ function migrateTaskHistory(ctx) {
18603
18718
  }
18604
18719
  }
18605
18720
  function migrateLockfile(ctx) {
18606
- const src = path12.join(ctx.paths.configDir, "akm.lock");
18607
- const dest = path12.join(ctx.paths.dataDir, "akm.lock");
18721
+ const src = path14.join(ctx.paths.configDir, "akm.lock");
18722
+ const dest = path14.join(ctx.paths.dataDir, "akm.lock");
18608
18723
  if (!fs13.existsSync(src)) {
18609
18724
  return { name: "akm.lock", status: "skipped", detail: "source not found" };
18610
18725
  }
@@ -18628,8 +18743,8 @@ function migrateLockfile(ctx) {
18628
18743
  return { name: "akm.lock", status: "failed", detail: `size mismatch after copy: ${src} \u2192 ${dest}` };
18629
18744
  }
18630
18745
  function migrateConfigBackups(ctx) {
18631
- const src = path12.join(ctx.paths.cacheDir, "config-backups");
18632
- const dest = path12.join(ctx.paths.dataDir, "config-backups");
18746
+ const src = path14.join(ctx.paths.cacheDir, "config-backups");
18747
+ const dest = path14.join(ctx.paths.dataDir, "config-backups");
18633
18748
  if (!fs13.existsSync(src)) {
18634
18749
  return { name: "config-backups/", status: "skipped", detail: "source directory not found" };
18635
18750
  }
@@ -18669,7 +18784,7 @@ function migrateConfigBackups(ctx) {
18669
18784
  }
18670
18785
  }
18671
18786
  async function migrateTaskHistoryToDb(ctx) {
18672
- const src = path12.join(ctx.paths.cacheDir, "tasks", "history");
18787
+ const src = path14.join(ctx.paths.cacheDir, "tasks", "history");
18673
18788
  if (!fs13.existsSync(src)) {
18674
18789
  return { name: "tasks/history/ \u2192 state.db", status: "skipped", detail: "source directory not found" };
18675
18790
  }
@@ -18696,7 +18811,7 @@ async function migrateTaskHistoryToDb(ctx) {
18696
18811
  let failed = 0;
18697
18812
  try {
18698
18813
  for (const file of files) {
18699
- const filePath = path12.join(src, file);
18814
+ const filePath = path14.join(src, file);
18700
18815
  const text = fs13.readFileSync(filePath, "utf8");
18701
18816
  const lines = text.split(`
18702
18817
  `).filter((l) => l.trim().length > 0);
@@ -18756,7 +18871,7 @@ async function migrateTaskHistoryToDb(ctx) {
18756
18871
  }
18757
18872
  }
18758
18873
  function noteRegistryIndexCache(ctx) {
18759
- const src = path12.join(ctx.paths.cacheDir, "registry-index");
18874
+ const src = path14.join(ctx.paths.cacheDir, "registry-index");
18760
18875
  if (!fs13.existsSync(src)) {
18761
18876
  return { name: "registry-index/ (note)", status: "skipped", detail: "no old $CACHE/registry-index/ directory found" };
18762
18877
  }
@@ -18770,7 +18885,7 @@ function noteRegistryIndexCache(ctx) {
18770
18885
  These are ignored in v0.9 \u2014 data is now stored in the registry_index_cache` + `
18771
18886
  table in $DATA/index.db and will be rebuilt on next 'akm registry search'.
18772
18887
  You may safely delete these files after migration:
18773
- ` + legacyFiles.map((f) => ` ${path12.join(src, f)}`).join(`
18888
+ ` + legacyFiles.map((f) => ` ${path14.join(src, f)}`).join(`
18774
18889
  `));
18775
18890
  }
18776
18891
  return {
@@ -18784,13 +18899,13 @@ var v07To08Migration = {
18784
18899
  sourceVersion: "0.7",
18785
18900
  isNeeded: (paths) => {
18786
18901
  const candidates = [
18787
- path12.join(paths.cacheDir, "index.db"),
18788
- path12.join(paths.cacheDir, "workflow.db"),
18789
- path12.join(paths.cacheDir, "events.jsonl"),
18790
- path12.join(paths.cacheDir, "tasks", "history"),
18791
- path12.join(paths.configDir, "akm.lock"),
18792
- path12.join(paths.cacheDir, "config-backups"),
18793
- path12.join(paths.cacheDir, "registry-index")
18902
+ path14.join(paths.cacheDir, "index.db"),
18903
+ path14.join(paths.cacheDir, "workflow.db"),
18904
+ path14.join(paths.cacheDir, "events.jsonl"),
18905
+ path14.join(paths.cacheDir, "tasks", "history"),
18906
+ path14.join(paths.configDir, "akm.lock"),
18907
+ path14.join(paths.cacheDir, "config-backups"),
18908
+ path14.join(paths.cacheDir, "registry-index")
18794
18909
  ];
18795
18910
  return candidates.some((p) => fs13.existsSync(p));
18796
18911
  },
@@ -18807,9 +18922,9 @@ var v07To08Migration = {
18807
18922
  };
18808
18923
  function legacyGraphCandidatePaths(ctx) {
18809
18924
  return [
18810
- path12.join(ctx.paths.cacheDir, "graph-snapshot.json"),
18811
- path12.join(ctx.paths.dataDir, "graph-snapshot.json"),
18812
- path12.join(ctx.paths.dataDir, "graph-export.json")
18925
+ path14.join(ctx.paths.cacheDir, "graph-snapshot.json"),
18926
+ path14.join(ctx.paths.dataDir, "graph-snapshot.json"),
18927
+ path14.join(ctx.paths.dataDir, "graph-export.json")
18813
18928
  ];
18814
18929
  }
18815
18930
  function findLegacyGraphFile(ctx) {
@@ -18817,10 +18932,10 @@ function findLegacyGraphFile(ctx) {
18817
18932
  if (fs13.existsSync(candidate) && fs13.statSync(candidate).isFile())
18818
18933
  return candidate;
18819
18934
  }
18820
- const graphDir = path12.join(ctx.paths.cacheDir, "graph");
18935
+ const graphDir = path14.join(ctx.paths.cacheDir, "graph");
18821
18936
  if (fs13.existsSync(graphDir) && fs13.statSync(graphDir).isDirectory()) {
18822
18937
  try {
18823
- const json = fs13.readdirSync(graphDir).filter((f) => f.endsWith(".json")).map((f) => path12.join(graphDir, f));
18938
+ const json = fs13.readdirSync(graphDir).filter((f) => f.endsWith(".json")).map((f) => path14.join(graphDir, f));
18824
18939
  if (json.length > 0)
18825
18940
  return json[0];
18826
18941
  } catch {}
@@ -18888,9 +19003,9 @@ async function migrateGraphFileToDb(ctx) {
18888
19003
  };
18889
19004
  }
18890
19005
  const snapshot = validation.data;
18891
- const { openExistingDatabase: openExistingDatabase2, closeDatabase: closeDatabase2 } = await Promise.resolve().then(() => (init_db(), exports_db));
19006
+ const { openExistingDatabase: openExistingDatabase3, closeDatabase: closeDatabase3 } = await Promise.resolve().then(() => (init_db(), exports_db));
18892
19007
  const { replaceStoredGraph: replaceStoredGraph2, loadStoredGraphMeta: loadStoredGraphMeta2 } = await Promise.resolve().then(() => (init_graph_db(), exports_graph_db));
18893
- const db = openExistingDatabase2(ctx.paths.indexDbPath);
19008
+ const db = openExistingDatabase3(ctx.paths.indexDbPath);
18894
19009
  try {
18895
19010
  const graph = {
18896
19011
  schemaVersion: snapshot.schemaVersion ?? 2,
@@ -18963,7 +19078,7 @@ async function migrateGraphFileToDb(ctx) {
18963
19078
  detail: `imported graph snapshot from ${legacyFile} into ${ctx.paths.indexDbPath} (stash ${snapshot.stashRoot}; ${importedCount} file(s) imported of ${graph.files.length} in source). Source renamed to ${renamed} \u2014 delete manually when ready.`
18964
19079
  };
18965
19080
  } finally {
18966
- closeDatabase2(db);
19081
+ closeDatabase3(db);
18967
19082
  }
18968
19083
  } catch (err) {
18969
19084
  const msg = err instanceof Error ? err.message : String(err);
@@ -18972,19 +19087,19 @@ async function migrateGraphFileToDb(ctx) {
18972
19087
  }
18973
19088
  function resolvePrimaryStashDir(configDirPath) {
18974
19089
  try {
18975
- const cfgPath = path12.join(configDirPath, "config.json");
19090
+ const cfgPath = path14.join(configDirPath, "config.json");
18976
19091
  if (fs13.existsSync(cfgPath)) {
18977
19092
  const cfg = JSON.parse(fs13.readFileSync(cfgPath, "utf8"));
18978
19093
  if (typeof cfg.stashDir === "string" && cfg.stashDir.length > 0)
18979
19094
  return cfg.stashDir;
18980
19095
  }
18981
19096
  } catch {}
18982
- return getDefaultStashDir();
19097
+ return getDefaultStashDir2();
18983
19098
  }
18984
19099
  function countEnvFilesRecursive(dir) {
18985
19100
  let count = 0;
18986
19101
  for (const entry of fs13.readdirSync(dir, { withFileTypes: true })) {
18987
- const full = path12.join(dir, entry.name);
19102
+ const full = path14.join(dir, entry.name);
18988
19103
  if (entry.isDirectory()) {
18989
19104
  count += countEnvFilesRecursive(full);
18990
19105
  } else if (entry.name === ".env" || entry.name.endsWith(".env")) {
@@ -19002,7 +19117,7 @@ function chmodTreeSecure(dir) {
19002
19117
  return { ok: false, detail: `chmod 0700 ${dir} failed: ${err instanceof Error ? err.message : err}` };
19003
19118
  }
19004
19119
  for (const entry of fs13.readdirSync(dir, { withFileTypes: true })) {
19005
- const full = path12.join(dir, entry.name);
19120
+ const full = path14.join(dir, entry.name);
19006
19121
  if (entry.isDirectory()) {
19007
19122
  const sub = chmodTreeSecure(full);
19008
19123
  if (!sub.ok)
@@ -19024,9 +19139,9 @@ function chmodTreeSecure(dir) {
19024
19139
  async function migrateVaultsToEnv(ctx) {
19025
19140
  const name = "vaults/ \u2192 env/";
19026
19141
  const stashDir = resolvePrimaryStashDir(ctx.paths.configDir);
19027
- const vaultsDir = path12.join(stashDir, "vaults");
19028
- const envDir = path12.join(stashDir, "env");
19029
- const marker = path12.join(vaultsDir, MIGRATED_MARKER);
19142
+ const vaultsDir = path14.join(stashDir, "vaults");
19143
+ const envDir = path14.join(stashDir, "env");
19144
+ const marker = path14.join(vaultsDir, MIGRATED_MARKER);
19030
19145
  if (!fs13.existsSync(vaultsDir)) {
19031
19146
  return { name, status: "skipped", detail: `no vaults/ directory under ${stashDir}` };
19032
19147
  }
@@ -19167,12 +19282,12 @@ task_history: task_id PK).
19167
19282
  Migration complete. No errors.`);
19168
19283
  console.log(`
19169
19284
  Old files at the original locations are safe to delete manually after verifying akm works:
19170
- ${path12.join(cacheDir, "index.db")}
19171
- ${path12.join(cacheDir, "workflow.db")}
19172
- ${path12.join(cacheDir, "events.jsonl")}
19173
- ${path12.join(cacheDir, "tasks", "history")}
19174
- ${path12.join(cacheDir, "config-backups")}
19175
- ${path12.join(configDir, "akm.lock")}
19285
+ ${path14.join(cacheDir, "index.db")}
19286
+ ${path14.join(cacheDir, "workflow.db")}
19287
+ ${path14.join(cacheDir, "events.jsonl")}
19288
+ ${path14.join(cacheDir, "tasks", "history")}
19289
+ ${path14.join(cacheDir, "config-backups")}
19290
+ ${path14.join(configDir, "akm.lock")}
19176
19291
 
19177
19292
  Next step \u2014 repopulate graph data (if migrating from 0.7):
19178
19293
  The 0.8.0 graph schema redesign (DB_VERSION 12 \u2192 13) rebuilds the graph
@@ -19265,7 +19380,7 @@ var invokedDirectly = (() => {
19265
19380
  if (!entry)
19266
19381
  return false;
19267
19382
  const here = new URL(import.meta.url).pathname;
19268
- return path12.resolve(entry) === here;
19383
+ return path14.resolve(entry) === here;
19269
19384
  } catch {
19270
19385
  return false;
19271
19386
  }
@@ -19275,5 +19390,6 @@ if (invokedDirectly) {
19275
19390
  }
19276
19391
  export {
19277
19392
  runMigrations3 as runMigrations,
19393
+ main,
19278
19394
  MIGRATIONS2 as MIGRATIONS
19279
19395
  };