akm-cli 0.9.1-beta.1 → 0.9.1-beta.2

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 (57) hide show
  1. package/CHANGELOG.md +18 -1
  2. package/dist/cli/parse-args.js +7 -1
  3. package/dist/commands/env/child-env.js +14 -0
  4. package/dist/commands/improve/eval-cases.js +2 -0
  5. package/dist/commands/improve/memory/memory-improve.js +1 -0
  6. package/dist/commands/lint/index.js +5 -1
  7. package/dist/commands/sources/add-cli.js +8 -2
  8. package/dist/commands/sources/migration-help.js +12 -3
  9. package/dist/commands/sources/self-update.js +9 -1
  10. package/dist/core/adapter/adapters/agent-skills-adapter.js +32 -16
  11. package/dist/core/adapter/adapters/akm-lint.js +6 -2
  12. package/dist/core/adapter/adapters/akm-task-adapter.js +4 -2
  13. package/dist/core/adapter/adapters/dotenv-adapter.js +21 -0
  14. package/dist/core/asset/frontmatter.js +6 -1
  15. package/dist/core/common.js +81 -3
  16. package/dist/core/config/config-io.js +5 -45
  17. package/dist/core/config/schema/engines.js +14 -3
  18. package/dist/core/extra-params.js +11 -0
  19. package/dist/core/fs-txn.js +15 -2
  20. package/dist/core/json-schema.js +19 -2
  21. package/dist/core/paths.js +16 -2
  22. package/dist/core/redaction.js +22 -1
  23. package/dist/core/state-db.js +1 -0
  24. package/dist/core/write-source.js +26 -2
  25. package/dist/indexer/indexer.js +31 -6
  26. package/dist/indexer/search/db-search.js +17 -2
  27. package/dist/indexer/walk/walker.js +6 -1
  28. package/dist/integrations/agent/detect.js +13 -1
  29. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +21 -0
  30. package/dist/integrations/lockfile.js +10 -0
  31. package/dist/llm/client.js +14 -19
  32. package/dist/llm/embedder.js +23 -3
  33. package/dist/llm/embedders/remote.js +27 -2
  34. package/dist/output/html-render.js +40 -1
  35. package/dist/runtime.js +23 -1
  36. package/dist/scripts/akm-migrate-node.js +303 -107
  37. package/dist/scripts/akm-migrate.js +303 -107
  38. package/dist/setup/setup.js +22 -7
  39. package/dist/sources/providers/git-install.js +25 -2
  40. package/dist/sources/snapshot-fetchers/content-extract.js +63 -1
  41. package/dist/storage/database.js +71 -12
  42. package/dist/storage/engines/sqlite-migrations.js +61 -2
  43. package/dist/storage/repositories/index-connection.js +11 -1
  44. package/dist/storage/repositories/index-meta-repository.js +11 -0
  45. package/dist/storage/repositories/index-schema.js +17 -2
  46. package/dist/storage/repositories/index-vec-repository.js +43 -5
  47. package/dist/storage/sqlite-pragmas.js +12 -1
  48. package/dist/tasks/runner.js +84 -7
  49. package/dist/tasks/scheduler-invocation.js +19 -0
  50. package/dist/tasks/schema.js +21 -1
  51. package/dist/text-import-hook.mjs +1 -1
  52. package/dist/workflows/exec/native-executor.js +8 -0
  53. package/dist/workflows/exec/step-work.js +10 -2
  54. package/dist/workflows/parser.js +26 -1
  55. package/package.json +1 -1
  56. package/schemas/akm-config.json +10 -5
  57. package/schemas/akm-workflow.json +7 -3
@@ -7076,6 +7076,7 @@ var init_platform = __esm(() => {
7076
7076
  });
7077
7077
 
7078
7078
  // src/core/paths.ts
7079
+ import os from "node:os";
7079
7080
  import path from "node:path";
7080
7081
  function isUnderBunTest(env) {
7081
7082
  return env.BUN_TEST === "1" || env.NODE_ENV === "test";
@@ -7154,9 +7155,13 @@ function getCacheDir(env = process.env) {
7154
7155
  }
7155
7156
  const home = env.HOME?.trim();
7156
7157
  if (!home)
7157
- return path.join("/tmp", "akm-cache");
7158
+ return homelessFallbackDir("akm-cache");
7158
7159
  return path.join(home, ".cache", "akm");
7159
7160
  }
7161
+ function homelessFallbackDir(kind) {
7162
+ const uid = typeof process.getuid === "function" ? process.getuid() : undefined;
7163
+ return path.join(os.tmpdir(), uid === undefined ? kind : `${kind}-${uid}`);
7164
+ }
7160
7165
  function getDataDir(env = process.env, platform = process.platform) {
7161
7166
  const override = env.AKM_DATA_DIR?.trim();
7162
7167
  if (override)
@@ -7182,7 +7187,7 @@ function getDataDir(env = process.env, platform = process.platform) {
7182
7187
  return path.join(xdgDataHome, "akm");
7183
7188
  const home = env.HOME?.trim();
7184
7189
  if (!home)
7185
- return path.join("/tmp", "akm-data");
7190
+ return homelessFallbackDir("akm-data");
7186
7191
  return path.join(home, ".local", "share", "akm");
7187
7192
  }
7188
7193
  function getDbPath(env = process.env) {
@@ -7262,6 +7267,59 @@ function readTextFileWithLimit(filePath, maxBytes, label = "File") {
7262
7267
  fs.closeSync(fd);
7263
7268
  }
7264
7269
  }
7270
+ function stripJsonComments(text) {
7271
+ let result = "";
7272
+ let i = 0;
7273
+ let inString = false;
7274
+ while (i < text.length) {
7275
+ if (inString) {
7276
+ if (text[i] === "\\") {
7277
+ result += text[i] + (text[i + 1] ?? "");
7278
+ i += 2;
7279
+ continue;
7280
+ }
7281
+ if (text[i] === '"') {
7282
+ inString = false;
7283
+ }
7284
+ result += text[i];
7285
+ i++;
7286
+ continue;
7287
+ }
7288
+ if (text[i] === '"') {
7289
+ inString = true;
7290
+ result += text[i];
7291
+ i++;
7292
+ continue;
7293
+ }
7294
+ if (text[i] === "/" && text[i + 1] === "/") {
7295
+ while (i < text.length && text[i] !== `
7296
+ `)
7297
+ i++;
7298
+ continue;
7299
+ }
7300
+ if (text[i] === "/" && text[i + 1] === "*") {
7301
+ i += 2;
7302
+ while (i < text.length && !(text[i] === "*" && text[i + 1] === "/"))
7303
+ i++;
7304
+ i += 2;
7305
+ continue;
7306
+ }
7307
+ result += text[i];
7308
+ i++;
7309
+ }
7310
+ return result;
7311
+ }
7312
+ function existingFileMode(filePath) {
7313
+ try {
7314
+ return fs.statSync(filePath).mode & 511;
7315
+ } catch {
7316
+ try {
7317
+ return 438 & ~process.umask();
7318
+ } catch {
7319
+ return 420;
7320
+ }
7321
+ }
7322
+ }
7265
7323
  function writeFileAtomic(target, content, mode) {
7266
7324
  const tmp = `${target}.tmp.${process.pid}.${crypto.randomBytes(8).toString("hex")}`;
7267
7325
  const data = typeof content === "string" ? Buffer.from(content) : content;
@@ -7374,7 +7432,7 @@ function readStashDirFromConfig() {
7374
7432
  try {
7375
7433
  const configPath = getConfigPath();
7376
7434
  const text = readTextFileWithLimit(configPath, MAX_CONFIG_FILE_BYTES, "Config file");
7377
- const raw = JSON.parse(text);
7435
+ const raw = JSON.parse(stripJsonComments(text));
7378
7436
  if (typeof raw !== "object" || raw === null)
7379
7437
  return;
7380
7438
  const bundles = raw.bundles;
@@ -7663,8 +7721,8 @@ function isProcessAlive(pid) {
7663
7721
  try {
7664
7722
  process.kill(pid, 0);
7665
7723
  return true;
7666
- } catch {
7667
- return false;
7724
+ } catch (err) {
7725
+ return err?.code === "EPERM";
7668
7726
  }
7669
7727
  }
7670
7728
  var MAX_CONFIG_FILE_BYTES, MAX_LOCAL_METADATA_BYTES, MAX_LOCK_METADATA_BYTES, DEFAULT_RESPONSE_BYTE_CAP, ResponseTooLargeError, BodyReadTimeoutError;
@@ -7829,7 +7887,7 @@ var init_runtime = __esm(() => {
7829
7887
  var require_main = __commonJS((exports, module) => {
7830
7888
  var fs3 = __require("fs");
7831
7889
  var path7 = __require("path");
7832
- var os = __require("os");
7890
+ var os2 = __require("os");
7833
7891
  var crypto2 = __require("crypto");
7834
7892
  var TIPS = [
7835
7893
  "◈ encrypted .env [www.dotenvx.com]",
@@ -7977,7 +8035,7 @@ var require_main = __commonJS((exports, module) => {
7977
8035
  return null;
7978
8036
  }
7979
8037
  function _resolveHome(envPath) {
7980
- return envPath[0] === "~" ? path7.join(os.homedir(), envPath.slice(1)) : envPath;
8038
+ return envPath[0] === "~" ? path7.join(os2.homedir(), envPath.slice(1)) : envPath;
7981
8039
  }
7982
8040
  function _configVault(options) {
7983
8041
  const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
@@ -8289,21 +8347,32 @@ function loadBunSqlite() {
8289
8347
  }
8290
8348
  return bunSqliteModule;
8291
8349
  }
8350
+ function abiMismatchRemedy(message) {
8351
+ const ABI_MISMATCH_SHAPES = [
8352
+ "did not self-register",
8353
+ "NODE_MODULE_VERSION",
8354
+ "was compiled against a different",
8355
+ "invalid ELF header"
8356
+ ];
8357
+ if (!ABI_MISMATCH_SHAPES.some((shape) => message.includes(shape)))
8358
+ return;
8359
+ return `akm could not load 'better-sqlite3': its native binding was built for a different
8360
+ ` + `Node.js version than the one now running (this Node is ABI ${process.versions.modules}).
8361
+ ` + `This is what happens when Node is upgraded after akm is installed. It is NOT a
8362
+ ` + `broken install, and reinstalling akm is not required.
8363
+ ` + ` Fix: npm rebuild better-sqlite3 # in akm's install directory
8364
+ ` + ` Or: npm install -g akm-cli # reinstall, rebuilding against this Node
8365
+ ` + " Or: run akm under Bun, whose built-in SQLite driver needs no native binding.";
8366
+ }
8292
8367
  function loadBetterSqlite3() {
8293
8368
  if (!betterSqlite3Ctor) {
8294
8369
  let mod;
8295
8370
  try {
8296
8371
  mod = nodeRequire2("better-sqlite3");
8297
8372
  } catch (err) {
8298
- throw new Error(`akm could not load 'better-sqlite3', the SQLite driver it needs on Node.js.
8299
- ` + ` • If the error below says the module was compiled against a DIFFERENT Node.js
8300
- ` + ` version, you upgraded Node after installing akm. Reinstall akm (or run
8301
- ` + " `npm rebuild better-sqlite3` in its install directory) so the binding is\n" + ` rebuilt for the Node you are now running. This is the common case after a
8302
- ` + ` Node major upgrade, and it is NOT a broken install.
8303
- ` + ` • Otherwise, reinstall akm with a working C/C++ build toolchain so its optional
8304
- ` + " '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).
8305
- ` + ` • Or run akm under Bun, which has a built-in SQLite driver and needs no native build.
8306
- ` + ` Underlying load error: ${err instanceof Error ? err.message : String(err)}`);
8373
+ const raw = err instanceof Error ? err.message : String(err);
8374
+ throw new Error(`${abiMismatchRemedy(raw) ?? MISSING_BINDING_REMEDY}
8375
+ Underlying load error: ${raw}`);
8307
8376
  }
8308
8377
  betterSqlite3Ctor = mod.default ?? mod;
8309
8378
  }
@@ -8316,11 +8385,22 @@ function openNodeDatabase(path10, opts) {
8316
8385
  options.readonly = opts.readonly;
8317
8386
  if (opts?.create === false)
8318
8387
  options.fileMustExist = true;
8319
- const db = opts ? new BetterSqlite3(path10, options) : new BetterSqlite3(path10);
8388
+ let db;
8389
+ try {
8390
+ db = opts ? new BetterSqlite3(path10, options) : new BetterSqlite3(path10);
8391
+ } catch (err) {
8392
+ const raw = err instanceof Error ? err.message : String(err);
8393
+ const remedy = abiMismatchRemedy(raw);
8394
+ if (!remedy)
8395
+ throw err;
8396
+ throw new Error(`${remedy}
8397
+ Underlying error: ${raw}`);
8398
+ }
8320
8399
  return {
8321
8400
  prepare: db.prepare.bind(db),
8322
8401
  exec: db.exec.bind(db),
8323
8402
  run: (sql, ...params) => db.prepare(sql).run(...params),
8403
+ loadExtension: db.loadExtension.bind(db),
8324
8404
  transaction: db.transaction.bind(db),
8325
8405
  get inTransaction() {
8326
8406
  return db.inTransaction;
@@ -8328,7 +8408,7 @@ function openNodeDatabase(path10, opts) {
8328
8408
  close: db.close.bind(db)
8329
8409
  };
8330
8410
  }
8331
- var isBun2, nodeRequire2, bunSqliteProvider, nodeSqliteProvider, PROVIDERS, bunSqliteModule, betterSqlite3Ctor;
8411
+ var isBun2, nodeRequire2, bunSqliteProvider, nodeSqliteProvider, PROVIDERS, bunSqliteModule, betterSqlite3Ctor, MISSING_BINDING_REMEDY;
8332
8412
  var init_database = __esm(() => {
8333
8413
  isBun2 = !!process.versions?.bun;
8334
8414
  nodeRequire2 = createRequire3(import.meta.url);
@@ -8343,6 +8423,10 @@ var init_database = __esm(() => {
8343
8423
  open: openNodeDatabase
8344
8424
  };
8345
8425
  PROVIDERS = [bunSqliteProvider, nodeSqliteProvider];
8426
+ MISSING_BINDING_REMEDY = `akm could not load 'better-sqlite3', the SQLite driver it needs on Node.js.
8427
+ ` + ` • Reinstall akm with a working C/C++ build toolchain so its optional
8428
+ ` + " 'better-sqlite3' native binding builds (a global `npm i -g better-sqlite3`\n" + ` will NOT be resolved — Node loads it from akm's own node_modules).
8429
+ ` + " • Or run akm under Bun, which has a built-in SQLite driver and needs no native build.";
8346
8430
  });
8347
8431
 
8348
8432
  // src/core/file-lock.ts
@@ -8761,12 +8845,43 @@ function runMigrations(db, migrations, opts) {
8761
8845
  if (applied.has(migration.id))
8762
8846
  continue;
8763
8847
  opts?.beforeMigration?.(migration);
8764
- db.transaction(() => {
8848
+ withImmediateWriteLock(db, () => {
8849
+ const already = db.prepare("SELECT 1 FROM schema_migrations WHERE id = ?").get(migration.id);
8850
+ if (already)
8851
+ return;
8765
8852
  db.exec(migration.up);
8766
8853
  db.prepare("INSERT INTO schema_migrations (id) VALUES (?)").run(migration.id);
8767
- })();
8854
+ });
8855
+ applied.add(migration.id);
8856
+ }
8857
+ }
8858
+ function withImmediateWriteLock(db, fn) {
8859
+ if (db.inTransaction) {
8860
+ fn();
8861
+ return;
8862
+ }
8863
+ let lastBeginErr;
8864
+ for (let attempt = 1;attempt <= IMMEDIATE_LOCK_MAX_ATTEMPTS; attempt++) {
8865
+ try {
8866
+ db.exec("BEGIN IMMEDIATE");
8867
+ } catch (err) {
8868
+ lastBeginErr = err;
8869
+ continue;
8870
+ }
8871
+ try {
8872
+ fn();
8873
+ db.exec("COMMIT");
8874
+ return;
8875
+ } catch (err) {
8876
+ try {
8877
+ db.exec("ROLLBACK");
8878
+ } catch {}
8879
+ throw err;
8880
+ }
8768
8881
  }
8882
+ throw lastBeginErr instanceof Error ? lastBeginErr : new Error(`could not acquire the migration write lock after ${IMMEDIATE_LOCK_MAX_ATTEMPTS} attempts`);
8769
8883
  }
8884
+ var IMMEDIATE_LOCK_MAX_ATTEMPTS = 5;
8770
8885
 
8771
8886
  // src/core/state/migrations.ts
8772
8887
  function runMigrations2(db, options) {
@@ -27691,7 +27806,7 @@ function applyStandardPragmas(db, opts = {}) {
27691
27806
  warnNetworkFallbackOnce(opts.dataDir);
27692
27807
  }
27693
27808
  }
27694
- db.exec("PRAGMA busy_timeout = 30000");
27809
+ db.exec(`PRAGMA busy_timeout = ${SQLITE_BUSY_TIMEOUT_MS}`);
27695
27810
  db.exec(`PRAGMA journal_mode = ${mode}`);
27696
27811
  if (opts.foreignKeys !== false) {
27697
27812
  db.exec("PRAGMA foreign_keys = ON");
@@ -27707,7 +27822,7 @@ function warnNetworkFallbackOnce(dataDir) {
27707
27822
  warnedNetworkFallback = true;
27708
27823
  warn(`[akm] network filesystem detected at ${dataDir} — WAL unsupported, using DELETE journal mode`);
27709
27824
  }
27710
- 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;
27825
+ 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, SQLITE_BUSY_TIMEOUT_MS = 30000;
27711
27826
  var init_sqlite_pragmas = __esm(() => {
27712
27827
  init_warn();
27713
27828
  init_runtime();
@@ -27800,6 +27915,7 @@ function openStateDatabase(dbPath) {
27800
27915
  exec: db.exec.bind(db),
27801
27916
  run: db.run.bind(db),
27802
27917
  transaction: db.transaction.bind(db),
27918
+ loadExtension: db.loadExtension.bind(db),
27803
27919
  get inTransaction() {
27804
27920
  return db.inTransaction;
27805
27921
  },
@@ -28272,13 +28388,14 @@ function purgeEmbeddings(db, opts) {
28272
28388
  }
28273
28389
  setMeta(db, "hasEmbeddings", "0");
28274
28390
  }
28275
- var vecStatus, VEC_DOCS_URL = "https://github.com/itlackey/akm/blob/main/docs/reference/configuration.md#sqlite-vec-extension", VEC_FALLBACK_THRESHOLD = 1e4, vecInitWarnedDbs;
28391
+ var vecStatus, vecTablePresent, VEC_DOCS_URL = "https://github.com/itlackey/akm/blob/main/docs/reference/configuration.md#sqlite-vec-extension", VEC_FALLBACK_THRESHOLD = 1e4, vecInitWarnedDbs;
28276
28392
  var init_index_vec_repository = __esm(() => {
28277
28393
  init_best_effort();
28278
28394
  init_warn();
28279
28395
  init_types();
28280
28396
  init_index_meta_repository();
28281
28397
  vecStatus = new WeakMap;
28398
+ vecTablePresent = new WeakMap;
28282
28399
  vecInitWarnedDbs = new WeakSet;
28283
28400
  });
28284
28401
 
@@ -28569,8 +28686,13 @@ function ensureBundleRefColumns(db) {
28569
28686
  }, "entries table may not exist on a brand-new DB before CREATE — caller is responsible");
28570
28687
  }
28571
28688
  function ensureUniqueItemRefIndex(db) {
28572
- db.exec("DROP INDEX IF EXISTS idx_entries_item_ref");
28573
- db.exec("CREATE UNIQUE INDEX idx_entries_item_ref ON entries(item_ref)");
28689
+ const existing = db.prepare("SELECT sql FROM sqlite_master WHERE type = 'index' AND name = 'idx_entries_item_ref'").get();
28690
+ if (existing?.sql && /\bUNIQUE\b/i.test(existing.sql))
28691
+ return;
28692
+ db.transaction(() => {
28693
+ db.exec("DROP INDEX IF EXISTS idx_entries_item_ref");
28694
+ db.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_entries_item_ref ON entries(item_ref)");
28695
+ })();
28574
28696
  }
28575
28697
  function tableExists2(db, name) {
28576
28698
  const row = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name=? LIMIT 1").get(name);
@@ -28705,7 +28827,9 @@ function openReadonlyExistingDatabase(dbPath) {
28705
28827
  assertIndexPathReadable(resolvedPath);
28706
28828
  if (classifyPathAccess(resolvedPath).access === "absent")
28707
28829
  return;
28708
- return openDatabase(resolvedPath, { readonly: true, create: false });
28830
+ const db = openDatabase(resolvedPath, { readonly: true, create: false });
28831
+ db.exec(`PRAGMA busy_timeout = ${SQLITE_BUSY_TIMEOUT_MS}`);
28832
+ return db;
28709
28833
  }
28710
28834
  function closeDatabase(db) {
28711
28835
  db.close();
@@ -28716,6 +28840,7 @@ var init_index_connection = __esm(() => {
28716
28840
  init_paths();
28717
28841
  init_database();
28718
28842
  init_managed_db();
28843
+ init_sqlite_pragmas();
28719
28844
  init_index_schema();
28720
28845
  init_index_vec_repository();
28721
28846
  });
@@ -29077,7 +29202,7 @@ __export(exports_migrate_storage, {
29077
29202
  MIGRATIONS: () => MIGRATIONS
29078
29203
  });
29079
29204
  import fs47 from "node:fs";
29080
- import os7 from "node:os";
29205
+ import os8 from "node:os";
29081
29206
  import path53 from "node:path";
29082
29207
  import readline from "node:readline";
29083
29208
  function parseFromArg(args) {
@@ -29902,8 +30027,8 @@ async function main(args = process.argv.slice(2)) {
29902
30027
  var MIGRATED_MARKER = ".migrated", dataDir, stateDir, cacheDir, configDir, stateDbPath, indexDbPath, PATHS, versionReports, v07To08Migration, v08To09Migration, MIGRATIONS;
29903
30028
  var init_migrate_storage = __esm(() => {
29904
30029
  init_paths();
29905
- dataDir = process.env.AKM_DATA_DIR?.trim() ?? (process.env.XDG_DATA_HOME?.trim() ? path53.join(process.env.XDG_DATA_HOME.trim(), "akm") : path53.join(os7.homedir(), ".local", "share", "akm"));
29906
- stateDir = process.env.AKM_STATE_DIR?.trim() ?? (process.env.XDG_STATE_HOME?.trim() ? path53.join(process.env.XDG_STATE_HOME.trim(), "akm") : path53.join(os7.homedir(), ".local", "state", "akm"));
30030
+ dataDir = process.env.AKM_DATA_DIR?.trim() ?? (process.env.XDG_DATA_HOME?.trim() ? path53.join(process.env.XDG_DATA_HOME.trim(), "akm") : path53.join(os8.homedir(), ".local", "share", "akm"));
30031
+ stateDir = process.env.AKM_STATE_DIR?.trim() ?? (process.env.XDG_STATE_HOME?.trim() ? path53.join(process.env.XDG_STATE_HOME.trim(), "akm") : path53.join(os8.homedir(), ".local", "state", "akm"));
29907
30032
  cacheDir = getCacheDir();
29908
30033
  configDir = getConfigDir();
29909
30034
  stateDbPath = path53.join(dataDir, "state.db");
@@ -30049,8 +30174,8 @@ function flattenForText(value, path, lines) {
30049
30174
  }
30050
30175
 
30051
30176
  // src/output/html-render.ts
30052
- init_runtime();
30053
30177
  import path4 from "node:path";
30178
+ init_runtime();
30054
30179
  var TEMPLATES_DIR = path4.join(getDirname(import.meta.url), "../assets/templates/html");
30055
30180
 
30056
30181
  // src/output/command-registry.ts
@@ -32555,7 +32680,7 @@ class UsageError2 extends AkmError2 {
32555
32680
  // scripts/akm-migrate/config-migrate.ts
32556
32681
  import { randomUUID as randomUUID5 } from "node:crypto";
32557
32682
  import fs43 from "node:fs";
32558
- import os6 from "node:os";
32683
+ import os7 from "node:os";
32559
32684
  import path49 from "node:path";
32560
32685
 
32561
32686
  // src/cli/shared.ts
@@ -32731,6 +32856,15 @@ var TASK_EXTENSION = ".yml";
32731
32856
  var TASK_NEAR_MISS_EXTENSION = ".yaml";
32732
32857
  var TASK_MAX_TIMEOUT_MS = WORKFLOW_MAX_TIMEOUT_MS;
32733
32858
  var TASK_MAX_REDACT_NAMES = WORKFLOW_MAX_EXEC_PASS_ENV;
32859
+ function isPresentTarget(value) {
32860
+ if (value === undefined || value === null)
32861
+ return false;
32862
+ if (typeof value === "string")
32863
+ return value.trim() !== "";
32864
+ if (Array.isArray(value))
32865
+ return value.length > 0;
32866
+ return true;
32867
+ }
32734
32868
  function taskFieldProblems(data) {
32735
32869
  const problems = [];
32736
32870
  if (data.version !== TASK_SCHEMA_VERSION)
@@ -33079,6 +33213,7 @@ function collectWorkflowWarnings(document) {
33079
33213
 
33080
33214
  // src/core/asset/frontmatter.ts
33081
33215
  import fs4 from "node:fs";
33216
+ init_common();
33082
33217
 
33083
33218
  // src/core/write-provenance.ts
33084
33219
  import path7 from "node:path";
@@ -33197,7 +33332,7 @@ function mutateFrontmatter(filePath, mutator) {
33197
33332
  ${serializeFrontmatter(nextFrontmatter)}
33198
33333
  ---
33199
33334
  ${parsed.content}` : assembleAsset(nextFrontmatter, parsed.content);
33200
- fs4.writeFileSync(filePath, next, "utf8");
33335
+ writeFileAtomic(filePath, next, existingFileMode(filePath));
33201
33336
  recordWrittenPath(filePath);
33202
33337
  return true;
33203
33338
  }
@@ -33285,8 +33420,12 @@ function validateExtraParams(value) {
33285
33420
  return [{ path: [], message: "must be an object" }];
33286
33421
  }
33287
33422
  const issues = [];
33423
+ const seen = new WeakSet;
33288
33424
  const visit2 = (entry, path8) => {
33289
33425
  if (Array.isArray(entry)) {
33426
+ if (seen.has(entry))
33427
+ return;
33428
+ seen.add(entry);
33290
33429
  entry.forEach((child, index) => {
33291
33430
  visit2(child, [...path8, index]);
33292
33431
  });
@@ -33294,6 +33433,9 @@ function validateExtraParams(value) {
33294
33433
  }
33295
33434
  if (!entry || typeof entry !== "object")
33296
33435
  return;
33436
+ if (seen.has(entry))
33437
+ return;
33438
+ seen.add(entry);
33297
33439
  for (const [key, child] of Object.entries(entry)) {
33298
33440
  const normalized = normalizeExtraParamKey(key);
33299
33441
  if (path8.length === 0 && PROTECTED_TOP_LEVEL_KEYS.has(normalized)) {
@@ -33388,6 +33530,9 @@ function pushIssue(issues, path8, keyword, kind, message) {
33388
33530
  function isPlainObject(value) {
33389
33531
  return typeof value === "object" && value !== null && !Array.isArray(value);
33390
33532
  }
33533
+ function isSupportedEnumValue(value) {
33534
+ return value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value);
33535
+ }
33391
33536
  function checkDefinitionNode(schema, path8, issues, depth) {
33392
33537
  if (depth > MAX_DEFINITION_DEPTH) {
33393
33538
  pushIssue(issues, path8, "(depth)", "malformed", `schema nesting exceeds the depth limit of ${MAX_DEFINITION_DEPTH}`);
@@ -33414,8 +33559,16 @@ function checkDefinitionNode(schema, path8, issues, depth) {
33414
33559
  }
33415
33560
  }
33416
33561
  }
33417
- if (schema.enum !== undefined && (!Array.isArray(schema.enum) || schema.enum.length === 0)) {
33418
- pushIssue(issues, [...path8, "enum"], "enum", "malformed", `"enum" must be a non-empty array of allowed values`);
33562
+ if (schema.enum !== undefined) {
33563
+ if (!Array.isArray(schema.enum) || schema.enum.length === 0) {
33564
+ pushIssue(issues, [...path8, "enum"], "enum", "malformed", `"enum" must be a non-empty array of allowed values`);
33565
+ } else {
33566
+ schema.enum.forEach((value, index) => {
33567
+ if (isSupportedEnumValue(value))
33568
+ return;
33569
+ pushIssue(issues, [...path8, "enum", index], "enum", "unsupported", `"enum" values must be JSON primitives (string, finite number, boolean, or null) in the workflow ` + `schema subset — object and array enum members cannot be matched by the runtime subset`);
33570
+ });
33571
+ }
33419
33572
  }
33420
33573
  for (const keyword of ["allOf", "anyOf", "oneOf"]) {
33421
33574
  const branches = schema[keyword];
@@ -34096,7 +34249,13 @@ function parseUnit(ctx, raw, path8, stepLabel) {
34096
34249
  unit.output = output;
34097
34250
  if (raw.env !== undefined) {
34098
34251
  if (Array.isArray(raw.env) && raw.env.every((entry) => typeof entry === "string" && entry.trim() !== "")) {
34099
- unit.env = raw.env.map((entry) => entry.trim());
34252
+ const envRefs = raw.env.map((entry) => entry.trim());
34253
+ const duplicate = envRefs.find((ref, i) => envRefs.indexOf(ref) !== i);
34254
+ if (duplicate !== undefined) {
34255
+ ctx.err([...path8, "env"], `${stepLabel} "env" contains a duplicate entry: "${duplicate}".`);
34256
+ } else {
34257
+ unit.env = envRefs;
34258
+ }
34100
34259
  } else {
34101
34260
  ctx.err([...path8, "env"], `${stepLabel} "env" must be a list of non-empty env asset refs.`);
34102
34261
  }
@@ -34264,6 +34423,10 @@ function parseRoute(ctx, raw, path8, stepLabel, stepIndex, routeChecks) {
34264
34423
  return;
34265
34424
  }
34266
34425
  const match = String(branch.match);
34426
+ if (match === "") {
34427
+ ctx.errAtLine(matchLine, `${stepLabel} "when[${i}].match" must not be empty.`);
34428
+ return;
34429
+ }
34267
34430
  if (typeof branch.step !== "string" || branch.step.trim() === "") {
34268
34431
  ctx.err([...branchPath, "step"], `${stepLabel} "when[${i}].step" must be a step id string.`);
34269
34432
  return;
@@ -34305,12 +34468,18 @@ function parseInputs(ctx, raw, path8, stepLabel) {
34305
34468
  ctx.err(path8, `${stepLabel} "inputs" must contain at most ${WORKFLOW_MAX_INPUTS} entries.`);
34306
34469
  }
34307
34470
  const out = [];
34471
+ const seen = new Set;
34308
34472
  raw.forEach((entry, i) => {
34309
34473
  if (typeof entry !== "string" || entry.trim() === "") {
34310
34474
  ctx.err([...path8, i], `${stepLabel} "inputs[${i}]" must be a non-empty reference string.`);
34311
34475
  return;
34312
34476
  }
34313
34477
  const value = entry.trim();
34478
+ if (seen.has(value)) {
34479
+ ctx.err([...path8, i], `${stepLabel} "inputs[${i}]" duplicates an earlier entry: "${value}".`);
34480
+ return;
34481
+ }
34482
+ seen.add(value);
34314
34483
  checkReferenceSyntax(ctx, value, [...path8, i], `${stepLabel} "inputs[${i}]"`);
34315
34484
  out.push(value);
34316
34485
  });
@@ -34698,7 +34867,7 @@ function taskDiagnostics(relPath, data) {
34698
34867
  if (data === null || Object.keys(data).length === 0)
34699
34868
  return [];
34700
34869
  const missing = taskFieldProblems(data);
34701
- const hasTarget = "prompt" in data || "workflow" in data || "command" in data;
34870
+ const hasTarget = ["prompt", "workflow", "command"].some((key) => isPresentTarget(data[key]));
34702
34871
  if (!hasTarget)
34703
34872
  missing.push("prompt, workflow, or command");
34704
34873
  if (missing.length > 0) {
@@ -34816,6 +34985,7 @@ init_common();
34816
34985
  init_errors();
34817
34986
  init_file_lock();
34818
34987
  init_paths();
34988
+ init_common();
34819
34989
  import fs7 from "node:fs";
34820
34990
  import path11 from "node:path";
34821
34991
  function readConfigText(configPath) {
@@ -34895,48 +35065,6 @@ function withConfigLock(fn) {
34895
35065
  release();
34896
35066
  }
34897
35067
  }
34898
- function stripJsonComments(text) {
34899
- let result = "";
34900
- let i = 0;
34901
- let inString = false;
34902
- while (i < text.length) {
34903
- if (inString) {
34904
- if (text[i] === "\\") {
34905
- result += text[i] + (text[i + 1] ?? "");
34906
- i += 2;
34907
- continue;
34908
- }
34909
- if (text[i] === '"') {
34910
- inString = false;
34911
- }
34912
- result += text[i];
34913
- i++;
34914
- continue;
34915
- }
34916
- if (text[i] === '"') {
34917
- inString = true;
34918
- result += text[i];
34919
- i++;
34920
- continue;
34921
- }
34922
- if (text[i] === "/" && text[i + 1] === "/") {
34923
- while (i < text.length && text[i] !== `
34924
- `)
34925
- i++;
34926
- continue;
34927
- }
34928
- if (text[i] === "/" && text[i + 1] === "*") {
34929
- i += 2;
34930
- while (i < text.length && !(text[i] === "*" && text[i + 1] === "/"))
34931
- i++;
34932
- i += 2;
34933
- continue;
34934
- }
34935
- result += text[i];
34936
- i++;
34937
- }
34938
- return result;
34939
- }
34940
35068
 
34941
35069
  // node_modules/zod/v3/external.js
34942
35070
  var exports_external = {};
@@ -39039,6 +39167,7 @@ var VALID_HARNESS_IDS = Object.freeze(HARNESS_ID_TABLE.map((h) => h.id));
39039
39167
  var HARNESS_AGENT_DISPATCH_IDS = new Set(HARNESS_ID_TABLE.filter((h) => h.agentDispatch).map((h) => h.id));
39040
39168
 
39041
39169
  // src/core/config/schema/engines.ts
39170
+ var timeoutMsField = exports_external.union([positiveInt.max(WORKFLOW_MAX_TIMEOUT_MS), exports_external.null()]).optional();
39042
39171
  var LlmConnectionConfigSchema = exports_external.object({
39043
39172
  provider: exports_external.string().optional(),
39044
39173
  endpoint: exports_external.string(),
@@ -39046,7 +39175,7 @@ var LlmConnectionConfigSchema = exports_external.object({
39046
39175
  apiKey: exports_external.string().optional(),
39047
39176
  temperature: exports_external.number().finite().optional(),
39048
39177
  maxTokens: positiveInt.optional(),
39049
- timeoutMs: exports_external.union([positiveInt, exports_external.null()]).optional(),
39178
+ timeoutMs: timeoutMsField,
39050
39179
  concurrency: positiveInt.optional(),
39051
39180
  capabilities: LlmCapabilitiesSchema.optional(),
39052
39181
  extraParams: ExtraParamsSchema.optional(),
@@ -39065,7 +39194,7 @@ var LlmEngineSchema = exports_external.object({
39065
39194
  apiKey: exports_external.string().regex(ENV_REFERENCE_PATTERN, `apiKey must be $VAR or \${VAR}`).optional(),
39066
39195
  temperature: exports_external.number().finite().optional(),
39067
39196
  maxTokens: positiveInt.optional(),
39068
- timeoutMs: exports_external.union([positiveInt, exports_external.null()]).optional(),
39197
+ timeoutMs: timeoutMsField,
39069
39198
  concurrency: positiveInt.optional(),
39070
39199
  supportsJsonSchema: exports_external.boolean().optional(),
39071
39200
  extraParams: ExtraParamsSchema.optional(),
@@ -39086,7 +39215,7 @@ var AgentEngineSchema = exports_external.object({
39086
39215
  args: exports_external.array(exports_external.string()).optional(),
39087
39216
  workspace: nonEmptyString.optional(),
39088
39217
  model: nonEmptyString.optional(),
39089
- timeoutMs: exports_external.union([positiveInt, exports_external.null()]).optional(),
39218
+ timeoutMs: timeoutMsField,
39090
39219
  modelAliases: ModelAliasMapSchema.optional(),
39091
39220
  llmEngine: engineName.optional()
39092
39221
  }).passthrough().superRefine((value, ctx) => {
@@ -40189,7 +40318,7 @@ function inferLegacyBundleIds(sources) {
40189
40318
 
40190
40319
  // scripts/akm-migrate/migrate/legacy/config-source-migration.ts
40191
40320
  import fs24 from "node:fs";
40192
- import os from "node:os";
40321
+ import os2 from "node:os";
40193
40322
  import path28 from "node:path";
40194
40323
 
40195
40324
  // src/core/adapter/adapters/agent-skills-adapter.ts
@@ -40438,20 +40567,32 @@ function skillFieldDiagnostics(relPath, dirName, data) {
40438
40567
  return diagnostics;
40439
40568
  }
40440
40569
  var MAX_PACKAGE_PROBE_DEPTH = 3;
40441
- async function subtreeHasManifest(dir, entries, ctx, depth) {
40570
+ function missingManifestDiagnostic(dir) {
40571
+ return { file: dir, issue: "missing-skill-md", detail: `no SKILL.md in ${dir}/`, fixed: false };
40572
+ }
40573
+ async function scanPackageCandidate(dir, entries, ctx, depth) {
40442
40574
  if (entries.includes(SKILL_MANIFEST))
40443
- return true;
40444
- if (depth >= MAX_PACKAGE_PROBE_DEPTH)
40445
- return false;
40575
+ return { containsManifest: true, diagnostics: [] };
40576
+ if (depth >= MAX_PACKAGE_PROBE_DEPTH) {
40577
+ return { containsManifest: false, diagnostics: [missingManifestDiagnostic(dir)] };
40578
+ }
40579
+ const children = [];
40446
40580
  for (const entry of entries) {
40581
+ if (entry.startsWith("."))
40582
+ continue;
40447
40583
  const child = `${dir}/${entry}`;
40448
40584
  const childEntries = await ctx.list(child);
40449
40585
  if (childEntries.length === 0)
40450
40586
  continue;
40451
- if (await subtreeHasManifest(child, childEntries, ctx, depth + 1))
40452
- return true;
40587
+ children.push(await scanPackageCandidate(child, childEntries, ctx, depth + 1));
40453
40588
  }
40454
- return false;
40589
+ if (children.some((child) => child.containsManifest)) {
40590
+ return {
40591
+ containsManifest: true,
40592
+ diagnostics: children.flatMap((child) => child.diagnostics)
40593
+ };
40594
+ }
40595
+ return { containsManifest: false, diagnostics: [missingManifestDiagnostic(dir)] };
40455
40596
  }
40456
40597
  async function missingManifestDiagnostics(ctx) {
40457
40598
  const diagnostics = [];
@@ -40461,9 +40602,7 @@ async function missingManifestDiagnostics(ctx) {
40461
40602
  const entries = await ctx.list(name);
40462
40603
  if (entries.length === 0)
40463
40604
  continue;
40464
- if (await subtreeHasManifest(name, entries, ctx, 1))
40465
- continue;
40466
- diagnostics.push({ file: name, issue: "missing-skill-md", detail: `no SKILL.md in ${name}/`, fixed: false });
40605
+ diagnostics.push(...(await scanPackageCandidate(name, entries, ctx, 1)).diagnostics);
40467
40606
  }
40468
40607
  return diagnostics;
40469
40608
  }
@@ -42204,7 +42343,7 @@ function taskDiagnostics2(relPath, data) {
42204
42343
  if (Object.keys(data).length === 0)
42205
42344
  return [];
42206
42345
  const problems = taskFieldProblems(data);
42207
- const targets = TARGET_KEYS.filter((k) => (k in data) && data[k] !== undefined && data[k] !== null);
42346
+ const targets = TARGET_KEYS.filter((k) => isPresentTarget(data[k]));
42208
42347
  if (targets.length === 0)
42209
42348
  problems.push("exactly one target (prompt, workflow, or command)");
42210
42349
  else if (targets.length > 1)
@@ -42608,6 +42747,10 @@ function classify2(relPath) {
42608
42747
  }
42609
42748
  return null;
42610
42749
  }
42750
+ function hasSensitiveMarker(absPath, type) {
42751
+ const marker = type === "env" ? absPath.replace(/\.env$/i, ".sensitive") : `${absPath}.sensitive`;
42752
+ return marker !== absPath && fs19.existsSync(marker);
42753
+ }
42611
42754
  function scanKeyNames(raw) {
42612
42755
  const keys = [];
42613
42756
  const seen = new Set;
@@ -42627,6 +42770,8 @@ function recognize5(c, file) {
42627
42770
  const type = classify2(file.relPath);
42628
42771
  if (type === null)
42629
42772
  return null;
42773
+ if (hasSensitiveMarker(file.absPath, type))
42774
+ return null;
42630
42775
  const posix = toPosix6(file.relPath);
42631
42776
  const raw = file.content();
42632
42777
  if (type === "env") {
@@ -43541,9 +43686,9 @@ function hasOldSourceShape(raw) {
43541
43686
  }
43542
43687
  function expandTilde(p) {
43543
43688
  if (p === "~")
43544
- return os.homedir();
43689
+ return os2.homedir();
43545
43690
  if (p.startsWith("~/") || p.startsWith("~\\"))
43546
- return path28.join(os.homedir(), p.slice(2));
43691
+ return path28.join(os2.homedir(), p.slice(2));
43547
43692
  return p;
43548
43693
  }
43549
43694
  function readString(value) {
@@ -43774,14 +43919,14 @@ function generateTargetConfig(raw, currentConfigVersion) {
43774
43919
  // scripts/akm-migrate/migrate/legacy/content-migration.ts
43775
43920
  import { randomBytes } from "node:crypto";
43776
43921
  import fs27 from "node:fs";
43777
- import os3 from "node:os";
43922
+ import os4 from "node:os";
43778
43923
  import path31 from "node:path";
43779
43924
  init_common();
43780
43925
  init_warn();
43781
43926
 
43782
43927
  // scripts/akm-migrate/migrate/legacy/legacy-layout.ts
43783
43928
  import fs25 from "node:fs";
43784
- import os2 from "node:os";
43929
+ import os3 from "node:os";
43785
43930
  import path29 from "node:path";
43786
43931
  import { fileURLToPath as fileURLToPath2 } from "node:url";
43787
43932
 
@@ -44217,7 +44362,7 @@ function fileUriToPath(ref) {
44217
44362
  return after;
44218
44363
  }
44219
44364
  function toReadableLocalId(absolutePath) {
44220
- const home = os2.homedir();
44365
+ const home = os3.homedir();
44221
44366
  if (absolutePath === home)
44222
44367
  return "~";
44223
44368
  if (absolutePath.startsWith(home + path29.sep)) {
@@ -44372,7 +44517,7 @@ function runContentMigration(stashRoots, options = {}) {
44372
44517
  rewriteSourceBackrefsInDir(dir, report);
44373
44518
  }
44374
44519
  const operationId = options.operationId ?? `direct-${process.pid}-${randomBytes(8).toString("hex")}`;
44375
- const batchPath = options.renameBatchPath ?? path31.join(os3.tmpdir(), `akm-reserved-renames-${operationId}-${randomBytes(8).toString("hex")}.json`);
44520
+ const batchPath = options.renameBatchPath ?? path31.join(os4.tmpdir(), `akm-reserved-renames-${operationId}-${randomBytes(8).toString("hex")}.json`);
44376
44521
  let batch;
44377
44522
  try {
44378
44523
  batch = loadReservedRenameBatch(batchPath, operationId);
@@ -44654,7 +44799,7 @@ init_common();
44654
44799
  init_errors();
44655
44800
  import { spawnSync as spawnSync3 } from "node:child_process";
44656
44801
  import fs28 from "node:fs";
44657
- import os4 from "node:os";
44802
+ import os5 from "node:os";
44658
44803
  import path33 from "node:path";
44659
44804
  import { fileURLToPath as fileURLToPath3, pathToFileURL } from "node:url";
44660
44805
 
@@ -45174,7 +45319,7 @@ function fileUriToPath2(ref) {
45174
45319
  return after;
45175
45320
  }
45176
45321
  function toReadableLocalId2(absolutePath) {
45177
- const home = os4.homedir();
45322
+ const home = os5.homedir();
45178
45323
  if (absolutePath === home)
45179
45324
  return "~";
45180
45325
  if (absolutePath.startsWith(home + path33.sep)) {
@@ -45579,7 +45724,7 @@ function errMsg2(error2) {
45579
45724
  // scripts/akm-migrate/migrate/legacy/task-target-ref-migration.ts
45580
45725
  import crypto4 from "node:crypto";
45581
45726
  import fs40 from "node:fs";
45582
- import os5 from "node:os";
45727
+ import os6 from "node:os";
45583
45728
  import path46 from "node:path";
45584
45729
  init_errors();
45585
45730
 
@@ -46183,6 +46328,14 @@ function resolveWritable(entry) {
46183
46328
  return entry.writable;
46184
46329
  return entry.type === "filesystem";
46185
46330
  }
46331
+ var WINDOWS_RESERVED_DEVICE_NAMES = new Set([
46332
+ "con",
46333
+ "prn",
46334
+ "aux",
46335
+ "nul",
46336
+ ...Array.from({ length: 9 }, (_, i) => `com${i + 1}`),
46337
+ ...Array.from({ length: 9 }, (_, i) => `lpt${i + 1}`)
46338
+ ]);
46186
46339
  function resolveGitContentRoot(repoPath) {
46187
46340
  const contentPath = path40.join(repoPath, "content");
46188
46341
  return fs35.existsSync(contentPath) && fs35.statSync(contentPath).isDirectory() ? contentPath : repoPath;
@@ -50763,6 +50916,22 @@ function markdownDestination(url) {
50763
50916
  return url.replaceAll("(", "%28").replaceAll(")", "%29");
50764
50917
  }
50765
50918
  var MAX_NESTING_DEPTH = 2000;
50919
+ var VOID_ELEMENTS = new Set([
50920
+ "area",
50921
+ "base",
50922
+ "br",
50923
+ "col",
50924
+ "embed",
50925
+ "hr",
50926
+ "img",
50927
+ "input",
50928
+ "link",
50929
+ "meta",
50930
+ "param",
50931
+ "source",
50932
+ "track",
50933
+ "wbr"
50934
+ ]);
50766
50935
  function exceedsNestingBudget(html) {
50767
50936
  let depth = 0;
50768
50937
  let max = 0;
@@ -50772,6 +50941,8 @@ function exceedsNestingBudget(html) {
50772
50941
  const selfClosing = match[3] === "/";
50773
50942
  if (selfClosing)
50774
50943
  continue;
50944
+ if (VOID_ELEMENTS.has(match[2].toLowerCase()))
50945
+ continue;
50775
50946
  if (closing)
50776
50947
  depth = Math.max(0, depth - 1);
50777
50948
  else {
@@ -50973,8 +51144,33 @@ ${content.trim().replace(/\n\s*\n/g, `
50973
51144
  function escapeResidualMarkup(markdown) {
50974
51145
  return markdown.replace(/<(?=[a-zA-Z/!?])/g, "&lt;");
50975
51146
  }
51147
+ function escapeOutsideCodeFences(markdown) {
51148
+ const lines = markdown.split(`
51149
+ `);
51150
+ let inFence = false;
51151
+ let fenceMarker = "";
51152
+ for (let i = 0;i < lines.length; i++) {
51153
+ const line = lines[i];
51154
+ const fence = /^\s*(`{3,}|~{3,})/.exec(line);
51155
+ if (fence) {
51156
+ const marker = fence[1];
51157
+ if (!inFence) {
51158
+ inFence = true;
51159
+ fenceMarker = marker[0];
51160
+ } else if (marker[0] === fenceMarker) {
51161
+ inFence = false;
51162
+ fenceMarker = "";
51163
+ }
51164
+ continue;
51165
+ }
51166
+ if (!inFence)
51167
+ lines[i] = escapeResidualMarkup(line);
51168
+ }
51169
+ return lines.join(`
51170
+ `);
51171
+ }
50976
51172
  function finalizeMarkdown(markdown) {
50977
- return escapeResidualMarkup(markdown).replace(/\r/g, "").replace(/[ \t]+\n/g, `
51173
+ return escapeOutsideCodeFences(markdown).replace(/\r/g, "").replace(/[ \t]+\n/g, `
50978
51174
  `).replace(/\n{3,}/g, `
50979
51175
 
50980
51176
  `).trim();
@@ -57852,9 +58048,9 @@ function migrationError(filePath, detail) {
57852
58048
  }
57853
58049
  function expandTilde2(value) {
57854
58050
  if (value === "~")
57855
- return os5.homedir();
58051
+ return os6.homedir();
57856
58052
  if (value.startsWith("~/") || value.startsWith("~\\"))
57857
- return path46.join(os5.homedir(), value.slice(2));
58053
+ return path46.join(os6.homedir(), value.slice(2));
57858
58054
  return value;
57859
58055
  }
57860
58056
  function bundlesFromConfig(config, pathResolutionBase, migrationLockEntries) {
@@ -59778,9 +59974,9 @@ async function runMigrationStatus(options = {}) {
59778
59974
  }
59779
59975
  function expandTilde4(value) {
59780
59976
  if (value === "~")
59781
- return os6.homedir();
59977
+ return os7.homedir();
59782
59978
  if (value.startsWith("~/") || value.startsWith("~\\"))
59783
- return path49.join(os6.homedir(), value.slice(2));
59979
+ return path49.join(os7.homedir(), value.slice(2));
59784
59980
  return value;
59785
59981
  }
59786
59982
  function migrationLockMatchesBundle(lock, bundle) {