akm-cli 0.9.12 → 0.9.13

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.
@@ -7043,7 +7043,8 @@ var init_errors = __esm(() => {
7043
7043
  TEST_ISOLATION_MISSING: "Under bun test, when AKM_BUNDLE_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.",
7044
7044
  UNSAFE_STASH_DIR: "Choose a path inside your home directory (e.g. ~/akm) or another empty workspace. The bundle directory cannot be the filesystem root, your home directory itself, or a sensitive system path like /etc, /var, ~/.config, or ~/.ssh.",
7045
7045
  UNKNOWN_IMPROVE_STRATEGY: "Pass one of the listed strategy names to `--strategy`, or define it under `improve.strategies`. Names are case-sensitive.",
7046
- EXECUTION_NOT_AUTHORIZED: "Change the selected tools or update the machine/user execution policy, then retry."
7046
+ EXECUTION_NOT_AUTHORIZED: "Change the selected tools or update the machine/user execution policy, then retry.",
7047
+ SECRET_REFERENCE_UNRESOLVED: "Check the secret exists (`akm secret list`) and the name after `secret://` matches, or run `akm secret set <name> <value>` to store it."
7047
7048
  };
7048
7049
  COMPOSITION_INVALID_MULTI_JOB_HINT = "AKM workflows support exactly one job per source, with no needs: between jobs. Split the extra job(s) into " + "their own workflow file, and compose them with uses: workflows/<ref> instead.";
7049
7050
  USAGE_HINTS = {
@@ -7065,7 +7066,8 @@ var init_errors = __esm(() => {
7065
7066
  INPUT_BINDING_INVALID: "Check the step's with: keys against the target's declared inputs.",
7066
7067
  TASK_TARGET_UNSUPPORTED: "Task definitions support command, script, workflow, and shell (run:) targets; akm/command is layered by callers.",
7067
7068
  WORKFLOW_IR_VERSION_UNSUPPORTED: "Abandon the run with `akm workflow abandon <id>`, then start it again from the workflow source — a frozen plan this akm cannot execute is not re-executable in place.",
7068
- WORKFLOW_OUTPUT_INVALID: "Check each `outputs:` entry's `from:` against the step artifact it names, and its `schema:` against the value that step actually promotes."
7069
+ WORKFLOW_OUTPUT_INVALID: "Check each `outputs:` entry's `from:` against the step artifact it names, and its `schema:` against the value that step actually promotes.",
7070
+ RUN_LEASE_HELD: "Wait for the named engine invocation to finish or for the lease to expire, then retry. `akm workflow status <id>` shows the current lease."
7069
7071
  };
7070
7072
  NOT_FOUND_HINTS = {
7071
7073
  ASSET_NOT_FOUND: "Run `akm search <query>` or `akm index` to refresh the index.",
@@ -8389,6 +8391,17 @@ function parseRefInput(raw) {
8389
8391
  }
8390
8392
  return { type: parts.type, name: parts.name, origin: ref.bundle };
8391
8393
  }
8394
+ function isFullRefInput(raw) {
8395
+ const trimmed = raw.trim();
8396
+ if (!trimmed)
8397
+ return false;
8398
+ try {
8399
+ const parsed = parseBundleRef(trimmed);
8400
+ return parsed.bundle !== undefined || typeNameFromConceptId(parsed.conceptId) !== undefined;
8401
+ } catch {
8402
+ return false;
8403
+ }
8404
+ }
8392
8405
  var init_resolve_ref = __esm(() => {
8393
8406
  init_errors();
8394
8407
  init_asset_placement();
@@ -12415,7 +12428,7 @@ function bindStepSections(headings, lines, bodyStartLine, totalLines, path24, de
12415
12428
  if (!declaredIds.has(h.text)) {
12416
12429
  errors3.push({
12417
12430
  line: h.line,
12418
- message: `Unexpected level-2 heading "## ${h.text}" on line ${h.line} — no step "${h.text}" is declared in frontmatter "steps:". Level-2 headings must exactly match a declared step id.`
12431
+ message: `Unexpected level-2 heading "## ${h.text}" on line ${h.line} — no step "${h.text}" is declared in frontmatter "steps:". Level-2 headings must exactly match a declared step id. To document something that is not a step, use a level-3 heading.`
12419
12432
  });
12420
12433
  continue;
12421
12434
  }
@@ -68759,15 +68772,15 @@ ${this.boa_token}${this.audio_token.repeat(this._compute_audio_num_tokens(audio_
68759
68772
  });
68760
68773
 
68761
68774
  // src/indexer/walk/file-context.ts
68762
- import fs45 from "node:fs";
68763
- import path55 from "node:path";
68775
+ import fs47 from "node:fs";
68776
+ import path56 from "node:path";
68764
68777
  function buildFileContext(stashRoot, absPath) {
68765
- const relPath = toPosix(path55.relative(stashRoot, absPath));
68766
- const ext = path55.extname(absPath).toLowerCase();
68767
- const fileName = path55.basename(absPath);
68768
- const parentDirAbs = path55.dirname(absPath);
68769
- const parentDir = path55.basename(parentDirAbs);
68770
- const relDir = toPosix(path55.dirname(relPath));
68778
+ const relPath = toPosix(path56.relative(stashRoot, absPath));
68779
+ const ext = path56.extname(absPath).toLowerCase();
68780
+ const fileName = path56.basename(absPath);
68781
+ const parentDirAbs = path56.dirname(absPath);
68782
+ const parentDir = path56.basename(parentDirAbs);
68783
+ const relDir = toPosix(path56.dirname(relPath));
68771
68784
  const ancestorDirs = relDir === "." ? [] : relDir.split("/").filter((seg) => seg.length > 0);
68772
68785
  let cachedContent;
68773
68786
  let cachedFrontmatter;
@@ -68784,7 +68797,7 @@ function buildFileContext(stashRoot, absPath) {
68784
68797
  stashRoot,
68785
68798
  content() {
68786
68799
  if (cachedContent === undefined) {
68787
- cachedContent = fs45.readFileSync(absPath, "utf8");
68800
+ cachedContent = fs47.readFileSync(absPath, "utf8");
68788
68801
  }
68789
68802
  return cachedContent;
68790
68803
  },
@@ -68799,7 +68812,7 @@ function buildFileContext(stashRoot, absPath) {
68799
68812
  },
68800
68813
  stat() {
68801
68814
  if (cachedStat === undefined) {
68802
- cachedStat = fs45.statSync(absPath);
68815
+ cachedStat = fs47.statSync(absPath);
68803
68816
  }
68804
68817
  return cachedStat;
68805
68818
  }
@@ -70922,6 +70935,7 @@ function formatProposalDrainPlain(r) {
70922
70935
  const deferred = Array.isArray(r.deferred) ? r.deferred : [];
70923
70936
  const skippedByCap = Array.isArray(r.skippedByCap) ? r.skippedByCap : [];
70924
70937
  const staged = Array.isArray(r.staged) ? r.staged : [];
70938
+ const failed = Array.isArray(r.failed) ? r.failed : [];
70925
70939
  const prefix = r.dryRun === true ? "[dry-run] " : "";
70926
70940
  const lines = [
70927
70941
  `${prefix}Drained proposal queue (strategy=${String(r.strategy ?? "?")}, policy=${policy}, applyMode=${applyMode})`,
@@ -70929,11 +70943,15 @@ function formatProposalDrainPlain(r) {
70929
70943
  ` rejected: ${rejected.length}`,
70930
70944
  ` deferred: ${deferred.length}`,
70931
70945
  ` skippedByCap: ${skippedByCap.length}`,
70932
- ` staged: ${staged.length}`
70946
+ ` staged: ${staged.length}`,
70947
+ ` failed: ${failed.length}`
70933
70948
  ];
70934
70949
  for (const d of deferred) {
70935
70950
  lines.push(` - ${String(d.id ?? "?")} (${String(d.reason ?? "?")})`);
70936
70951
  }
70952
+ for (const f of failed) {
70953
+ lines.push(` ! ${String(f.id ?? "?")} (${String(f.reason ?? "?")}): ${String(f.detail ?? "?")}`);
70954
+ }
70937
70955
  appendLoweringNotices(lines, r);
70938
70956
  return lines.join(`
70939
70957
  `).trimEnd();
@@ -76193,12 +76211,16 @@ var httpUrl = exports_external.string().refine((v) => v.startsWith("http://") ||
76193
76211
  });
76194
76212
  var ENGINE_NAME_PATTERN = new RegExp(ENGINE_NAME_PATTERN_SOURCE);
76195
76213
  var ENV_REFERENCE_PATTERN = /^\$[A-Za-z_][A-Za-z0-9_]*$|^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/;
76214
+ var SECRET_STORE_REFERENCE_PATTERN = /^secret:\/\/(.+)$/;
76196
76215
  var engineName = exports_external.string().max(63).regex(ENGINE_NAME_PATTERN, "names must be lowercase kebab-case and must not begin with reserved akm-");
76216
+ function isApiKeyReference(value) {
76217
+ return ENV_REFERENCE_PATTERN.test(value) || SECRET_STORE_REFERENCE_PATTERN.test(value);
76218
+ }
76197
76219
  function symbolicOrWarnApiKey(label) {
76198
76220
  return exports_external.string().superRefine((value) => {
76199
- if (ENV_REFERENCE_PATTERN.test(value))
76221
+ if (isApiKeyReference(value))
76200
76222
  return;
76201
- warnOnce(`config:literal-api-key:${label}`, `A ${label} in config.json is a literal API key, not a $VAR/\${VAR} reference; using it as configured. Prefer \`akm config set ...apiKey '$VAR'\` (with the corresponding env var set) — see docs/reference/data-and-telemetry.md.`);
76223
+ warnOnce(`config:literal-api-key:${label}`, `A ${label} in config.json is a literal API key, not a $VAR/\${VAR}/secret:// reference; using it as configured. Prefer \`akm config set ...apiKey '$VAR'\` (with the corresponding env var set) or \`secret://<name>\` (with \`akm secret set <name> ...\`) — see docs/reference/data-and-telemetry.md.`);
76202
76224
  });
76203
76225
  }
76204
76226
  var chatCompletionsEndpoint = exports_external.string().superRefine((value, ctx) => {
@@ -77366,11 +77388,19 @@ function getSources(config) {
77366
77388
  function loadConfig() {
77367
77389
  return loadUserConfig();
77368
77390
  }
77369
- function resolveSecret(value) {
77391
+ function resolveSecret(value, resolveFromStore) {
77370
77392
  if (value === undefined)
77371
77393
  return;
77372
77394
  if (typeof value !== "string")
77373
77395
  return value;
77396
+ const storeRef = SECRET_STORE_REFERENCE_PATTERN.exec(value)?.[1];
77397
+ if (storeRef !== undefined) {
77398
+ const resolved = resolveFromStore?.(storeRef) ?? null;
77399
+ if (resolved === null) {
77400
+ throw new ConfigError(`Secret store reference "${value}" did not resolve to a stored value.`, "SECRET_REFERENCE_UNRESOLVED");
77401
+ }
77402
+ return resolved;
77403
+ }
77374
77404
  if (!value.includes("$"))
77375
77405
  return value;
77376
77406
  return value.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}|\$([A-Za-z_][A-Za-z0-9_]*)/g, (_match, braced, bare) => {
@@ -79255,9 +79285,9 @@ function listTxnJournalsTolerant(predicate) {
79255
79285
 
79256
79286
  // src/commands/proposal/repository.ts
79257
79287
  import { createHash as createHash9, randomUUID as randomUUID6 } from "node:crypto";
79258
- import fs47 from "node:fs";
79288
+ import fs49 from "node:fs";
79259
79289
  init_dist();
79260
- import path60 from "node:path";
79290
+ import path61 from "node:path";
79261
79291
 
79262
79292
  // src/core/adapter/adapters/agent-skills-adapter.ts
79263
79293
  init_frontmatter();
@@ -92674,8 +92704,8 @@ init_warn();
92674
92704
  init_write_provenance();
92675
92705
 
92676
92706
  // src/indexer/index-written-assets.ts
92677
- import fs46 from "node:fs";
92678
- import path58 from "node:path";
92707
+ import fs48 from "node:fs";
92708
+ import path59 from "node:path";
92679
92709
  init_errors();
92680
92710
  init_paths();
92681
92711
  init_warn();
@@ -93712,6 +93742,127 @@ function redactSensitiveText(text, sensitiveValues) {
93712
93742
 
93713
93743
  // src/llm/embedders/remote.ts
93714
93744
  init_warn();
93745
+
93746
+ // src/sources/snapshot-fetchers/secret-seam.ts
93747
+ import fs45 from "node:fs";
93748
+
93749
+ // src/core/env-secret-ref.ts
93750
+ import fs43 from "node:fs";
93751
+ import path54 from "node:path";
93752
+
93753
+ // src/registry/origin-resolve.ts
93754
+ init_asset_ref();
93755
+ function resolveSourcesForOrigin(origin, allSources) {
93756
+ if (!origin)
93757
+ return allSources;
93758
+ const installations = deriveInstallations(allSources);
93759
+ return allSources.filter((_, index) => installations[index]?.id === origin);
93760
+ }
93761
+
93762
+ // src/core/asset/asset-create.ts
93763
+ init_errors();
93764
+ function normalizeCreateSubPath(subPath) {
93765
+ if (subPath === undefined)
93766
+ return "";
93767
+ const trimmed = subPath.trim().replace(/\\/g, "/").replace(/^\/+|\/+$/g, "");
93768
+ if (!trimmed)
93769
+ return "";
93770
+ if (trimmed.split("/").some((segment) => !segment || segment === "." || segment === "..")) {
93771
+ throw new UsageError("--path must be a relative directory without '.' or '..' segments.");
93772
+ }
93773
+ return trimmed;
93774
+ }
93775
+ function assertFlatAssetName(name) {
93776
+ if (name?.replace(/\\/g, "/").replace(/\.md$/i, "").includes("/")) {
93777
+ throw new UsageError("Asset --name must be a flat name without '/'. Use --path to choose a subdirectory " + "(e.g. --path personal --name grocery-list).");
93778
+ }
93779
+ }
93780
+ function combineCreatePath(subPath, baseName) {
93781
+ return subPath ? `${subPath}/${baseName}` : baseName;
93782
+ }
93783
+
93784
+ // src/core/env-secret-ref.ts
93785
+ init_asset_placement();
93786
+ init_resolve_ref();
93787
+ init_common();
93788
+ init_errors();
93789
+ function assertNotRemovedVaultRef(ref) {
93790
+ const boundary = ref.indexOf("//");
93791
+ const bare = boundary >= 0 ? ref.slice(boundary + 2) : ref;
93792
+ if (/^vault[:/]/.test(bare.trim())) {
93793
+ throw new UsageError("The `vault` asset type was removed in 0.9.0 — use `env/` (whole .env config) or `secrets/` (a single value).", "INVALID_FLAG_VALUE");
93794
+ }
93795
+ }
93796
+ function assertNotColonRef(ref, aliases, replacement) {
93797
+ const boundary = ref.indexOf("//");
93798
+ const bare = (boundary >= 0 ? ref.slice(boundary + 2) : ref).trim();
93799
+ const colon = bare.indexOf(":");
93800
+ if (colon <= 0)
93801
+ return;
93802
+ const head = bare.slice(0, colon).toLowerCase();
93803
+ if (!aliases.includes(head))
93804
+ return;
93805
+ const name = bare.slice(colon + 1);
93806
+ throw new UsageError(`The \`${head}:\` ref spelling was removed in 0.9.0 — use the slash form instead: \`${replacement}${name}\`.`, "INVALID_FLAG_VALUE");
93807
+ }
93808
+ function findEnvSource(origin, type, name) {
93809
+ const sources = resolveSourceEntries(undefined, loadConfig());
93810
+ if (sources.length === 0) {
93811
+ throw new UsageError("No bundles configured. Run `akm bundle create` to create your working bundle.");
93812
+ }
93813
+ const candidates = origin ? resolveSourcesForOrigin(origin, sources) : sources;
93814
+ const typeDir = type === "env" ? "env" : "secrets";
93815
+ const member = candidates.find((source) => fs43.existsSync(assetPathForName(type, path54.join(source.path, typeDir), name)));
93816
+ if (member)
93817
+ return member;
93818
+ if (!origin) {
93819
+ const fallback = candidates[0];
93820
+ if (fallback)
93821
+ return fallback;
93822
+ throw new UsageError("No bundles configured. Run `akm bundle create` to create your working bundle.");
93823
+ }
93824
+ const named = candidates[0];
93825
+ if (!named) {
93826
+ throw new NotFoundError(`Source not found for origin: ${origin}`);
93827
+ }
93828
+ return named;
93829
+ }
93830
+ function parseSecretRef(ref) {
93831
+ assertNotRemovedVaultRef(ref);
93832
+ assertNotColonRef(ref, ["secret", "secrets"], "secrets/");
93833
+ return parseRefInput(isFullRefInput(ref) ? ref : `secrets/${ref}`);
93834
+ }
93835
+ function resolveSecretPath(ref, create) {
93836
+ const parsed = parseSecretRef(ref);
93837
+ if (parsed.type !== "secret") {
93838
+ throw new UsageError(`Expected a secret ref (secrets/<name>); got "${ref}".`);
93839
+ }
93840
+ if (create) {
93841
+ assertFlatAssetName(parsed.name);
93842
+ parsed.name = combineCreatePath(normalizeCreateSubPath(create.subPath), parsed.name);
93843
+ }
93844
+ const source = findEnvSource(parsed.origin, "secret", parsed.name);
93845
+ const typeRoot = path54.join(source.path, "secrets");
93846
+ const absPath = assetPathForName("secret", typeRoot, parsed.name);
93847
+ if (!isWithin(absPath, typeRoot)) {
93848
+ throw new UsageError(`Secret name "${parsed.name}" escapes the secrets directory.`);
93849
+ }
93850
+ return { name: parsed.name, absPath, source };
93851
+ }
93852
+
93853
+ // src/sources/snapshot-fetchers/secret-seam.ts
93854
+ function resolveSecretFromStore(ref) {
93855
+ try {
93856
+ const { absPath } = resolveSecretPath(ref);
93857
+ if (!fs45.existsSync(absPath))
93858
+ return null;
93859
+ return fs45.readFileSync(absPath, "utf8").trim() || null;
93860
+ } catch {
93861
+ return null;
93862
+ }
93863
+ }
93864
+
93865
+ // src/llm/embedders/remote.ts
93715
93866
  var DEFAULT_REMOTE_BATCH_SIZE = 100;
93716
93867
  var DEFAULT_TOKEN_BUDGET = 8000;
93717
93868
  function estimateTokenCount(text) {
@@ -93867,14 +94018,14 @@ class RemoteEmbedder {
93867
94018
  }
93868
94019
  buildHeaders() {
93869
94020
  const headers = { "Content-Type": "application/json" };
93870
- const resolvedKey = resolveSecret(this.config.apiKey);
94021
+ const resolvedKey = resolveSecret(this.config.apiKey, resolveSecretFromStore);
93871
94022
  if (resolvedKey) {
93872
94023
  headers.Authorization = `Bearer ${resolvedKey}`;
93873
94024
  }
93874
94025
  return headers;
93875
94026
  }
93876
94027
  safeErrorBody(body) {
93877
- const resolvedKey = resolveSecret(this.config.apiKey);
94028
+ const resolvedKey = resolveSecret(this.config.apiKey, resolveSecretFromStore);
93878
94029
  return redactSensitiveText(redactErrorBody(body), resolvedKey ? [resolvedKey] : []);
93879
94030
  }
93880
94031
  }
@@ -94110,7 +94261,7 @@ function publishTargetedEmbeddingMeta(db, config) {
94110
94261
  }
94111
94262
 
94112
94263
  // src/indexer/scan/drain-dir.ts
94113
- import path57 from "node:path";
94264
+ import path58 from "node:path";
94114
94265
  init_common();
94115
94266
  init_recognition_util();
94116
94267
 
@@ -94119,8 +94270,8 @@ init_common();
94119
94270
  init_errors();
94120
94271
  init_recognition_util();
94121
94272
  init_warn();
94122
- import fs43 from "node:fs";
94123
- import path54 from "node:path";
94273
+ import fs46 from "node:fs";
94274
+ import path55 from "node:path";
94124
94275
 
94125
94276
  class WorkflowSourceRejectionError extends UsageError {
94126
94277
  sourcePaths;
@@ -94160,13 +94311,13 @@ class WorkflowSourcePathIdentityError extends WorkflowSourceRejectionError {
94160
94311
  function workflowNameForSourcePath(sourceRoot, adapterId, sourcePath) {
94161
94312
  if (adapterId !== "akm" && adapterId !== "akm-workflow")
94162
94313
  return;
94163
- const relativePath = toPosix(path54.relative(path54.resolve(sourceRoot), path54.resolve(sourcePath)));
94314
+ const relativePath = toPosix(path55.relative(path55.resolve(sourceRoot), path55.resolve(sourcePath)));
94164
94315
  if (!isSafeRelativeName(relativePath))
94165
94316
  return;
94166
94317
  const ownedPath = adapterId === "akm" ? relativePath.replace(/^workflows\//, "") : relativePath;
94167
94318
  if (adapterId === "akm" && ownedPath === relativePath)
94168
94319
  return;
94169
- const extension = path54.posix.extname(ownedPath);
94320
+ const extension = path55.posix.extname(ownedPath);
94170
94321
  if (!WORKFLOW_EXTENSIONS.includes(extension.toLowerCase()))
94171
94322
  return;
94172
94323
  return ownedPath;
@@ -94179,38 +94330,38 @@ function listWorkflowSourceFiles(sourceRoot, adapterId, name) {
94179
94330
  throw new UsageError("Workflow ref resolves outside the bundle root.", "PATH_ESCAPE_VIOLATION");
94180
94331
  }
94181
94332
  let realRoot;
94182
- const authoredRoot = path54.resolve(sourceRoot);
94333
+ const authoredRoot = path55.resolve(sourceRoot);
94183
94334
  try {
94184
- realRoot = fs43.realpathSync(authoredRoot);
94335
+ realRoot = fs46.realpathSync(authoredRoot);
94185
94336
  } catch {
94186
94337
  return [];
94187
94338
  }
94188
- const ownershipRoot = adapterId === "akm" ? path54.join(authoredRoot, "workflows") : authoredRoot;
94189
- const parent = path54.join(ownershipRoot, path54.dirname(canonicalName));
94339
+ const ownershipRoot = adapterId === "akm" ? path55.join(authoredRoot, "workflows") : authoredRoot;
94340
+ const parent = path55.join(ownershipRoot, path55.dirname(canonicalName));
94190
94341
  if (!isWithinResolved(parent, authoredRoot)) {
94191
94342
  throw new UsageError("Workflow ref resolves outside the bundle root.", "PATH_ESCAPE_VIOLATION");
94192
94343
  }
94193
94344
  let entries;
94194
94345
  try {
94195
- entries = fs43.readdirSync(parent, { withFileTypes: true });
94346
+ entries = fs46.readdirSync(parent, { withFileTypes: true });
94196
94347
  } catch {
94197
94348
  return [];
94198
94349
  }
94199
- const basename = path54.basename(canonicalName);
94350
+ const basename = path55.basename(canonicalName);
94200
94351
  const candidates = [];
94201
94352
  for (const entry of entries) {
94202
94353
  if (!entry.isFile() && !entry.isSymbolicLink())
94203
94354
  continue;
94204
- const extension = path54.extname(entry.name);
94355
+ const extension = path55.extname(entry.name);
94205
94356
  const lowerExtension = extension.toLowerCase();
94206
94357
  if (!WORKFLOW_EXTENSIONS.includes(lowerExtension))
94207
94358
  continue;
94208
94359
  if (entry.name.slice(0, -extension.length) !== basename)
94209
94360
  continue;
94210
- const candidatePath = path54.join(parent, entry.name);
94361
+ const candidatePath = path55.join(parent, entry.name);
94211
94362
  candidates.push({
94212
94363
  path: candidatePath,
94213
- relativePath: toPosix(path54.relative(authoredRoot, candidatePath)),
94364
+ relativePath: toPosix(path55.relative(authoredRoot, candidatePath)),
94214
94365
  lowerExtension,
94215
94366
  extensionlessStem: entry.name.slice(0, -extension.length)
94216
94367
  });
@@ -94245,7 +94396,7 @@ function inspectWorkflowSourceCandidate(candidate, canonicalName, realRoot) {
94245
94396
  const issues = [];
94246
94397
  let authoredStat;
94247
94398
  try {
94248
- authoredStat = fs43.lstatSync(candidate.path);
94399
+ authoredStat = fs46.lstatSync(candidate.path);
94249
94400
  } catch {
94250
94401
  issues.push(new WorkflowSourceLinkResolutionError(candidate.relativePath));
94251
94402
  return { issues };
@@ -94257,21 +94408,21 @@ function inspectWorkflowSourceCandidate(candidate, canonicalName, realRoot) {
94257
94408
  }
94258
94409
  let realPath;
94259
94410
  try {
94260
- realPath = fs43.realpathSync(candidate.path);
94411
+ realPath = fs46.realpathSync(candidate.path);
94261
94412
  } catch {
94262
94413
  issues.push(new WorkflowSourceLinkResolutionError(candidate.relativePath));
94263
94414
  return { issues };
94264
94415
  }
94265
- const targetPath = toPosix(path54.relative(realRoot, realPath));
94416
+ const targetPath = toPosix(path55.relative(realRoot, realPath));
94266
94417
  const contained2 = isWithinResolved(realPath, realRoot);
94267
94418
  if (!contained2)
94268
94419
  issues.push(new WorkflowSourcePathIdentityError(candidate.relativePath, targetPath));
94269
- if (isLink && path54.extname(realPath).toLowerCase() !== candidate.lowerExtension) {
94420
+ if (isLink && path55.extname(realPath).toLowerCase() !== candidate.lowerExtension) {
94270
94421
  issues.push(new WorkflowSourceLinkIdentityError(candidate.relativePath, targetPath));
94271
94422
  }
94272
94423
  if (contained2) {
94273
94424
  try {
94274
- if (!fs43.statSync(realPath).isFile())
94425
+ if (!fs46.statSync(realPath).isFile())
94275
94426
  issues.push(new WorkflowSourceLinkResolutionError(candidate.relativePath));
94276
94427
  } catch {
94277
94428
  issues.push(new WorkflowSourceLinkResolutionError(candidate.relativePath));
@@ -94299,11 +94450,11 @@ function normalizeName2(name) {
94299
94450
  return name.replaceAll("\\", "/");
94300
94451
  }
94301
94452
  function isSafeRelativeName(name) {
94302
- return name.length > 0 && !path54.posix.isAbsolute(name) && name !== ".." && !name.startsWith("../") && path54.posix.normalize(name) === name;
94453
+ return name.length > 0 && !path55.posix.isAbsolute(name) && name !== ".." && !name.startsWith("../") && path55.posix.normalize(name) === name;
94303
94454
  }
94304
94455
  function isWithinResolved(candidate, root) {
94305
- const relative = path54.relative(root, path54.resolve(candidate));
94306
- return relative === "" || !relative.startsWith("..") && !path54.isAbsolute(relative);
94456
+ const relative = path55.relative(root, path55.resolve(candidate));
94457
+ return relative === "" || !relative.startsWith("..") && !path55.isAbsolute(relative);
94307
94458
  }
94308
94459
 
94309
94460
  // src/indexer/scan/drain-dir.ts
@@ -94312,13 +94463,13 @@ init_metadata();
94312
94463
  init_file_context();
94313
94464
 
94314
94465
  // src/indexer/scan/doc-to-entry.ts
94315
- import path56 from "node:path";
94466
+ import path57 from "node:path";
94316
94467
  function indexDocumentToStashEntry(doc) {
94317
94468
  const dj = doc.documentJson ?? {};
94318
94469
  const entry = {
94319
94470
  name: doc.name,
94320
94471
  type: doc.type,
94321
- filename: path56.basename(doc.path ?? "")
94472
+ filename: path57.basename(doc.path ?? "")
94322
94473
  };
94323
94474
  if (doc.description !== undefined)
94324
94475
  entry.description = doc.description;
@@ -94438,7 +94589,7 @@ function drainDirDocuments(adapter, component, fileContexts) {
94438
94589
  throw error2;
94439
94590
  rejectedConceptIds.add(adapter.id === "akm" ? `workflows/${canonicalName}` : canonicalName);
94440
94591
  for (const relativePath of error2.sourcePaths) {
94441
- rejectedPaths.add(path57.join(component.root, relativePath));
94592
+ rejectedPaths.add(path58.join(component.root, relativePath));
94442
94593
  }
94443
94594
  warnings.push(error2.message);
94444
94595
  }
@@ -94500,7 +94651,7 @@ async function indexWrittenAssets(stashDir, filePaths, options = {}) {
94500
94651
  if (isPathAbsent(dbPath))
94501
94652
  return true;
94502
94653
  const files = filePaths.filter((f) => {
94503
- const rel = path58.relative(stashDir, f);
94654
+ const rel = path59.relative(stashDir, f);
94504
94655
  return !rel.split(/[\\/]+/).some((segment) => segment.startsWith("."));
94505
94656
  });
94506
94657
  if (files.length === 0)
@@ -94514,10 +94665,10 @@ async function indexWrittenAssets(stashDir, filePaths, options = {}) {
94514
94665
  const unindexable = new Set;
94515
94666
  const rejectedConceptIds = new Set;
94516
94667
  for (const file of files) {
94517
- if (!fs46.existsSync(file)) {
94668
+ if (!fs48.existsSync(file)) {
94518
94669
  let authoredDanglingSymlink = false;
94519
94670
  try {
94520
- authoredDanglingSymlink = fs46.lstatSync(file).isSymbolicLink();
94671
+ authoredDanglingSymlink = fs48.lstatSync(file).isSymbolicLink();
94521
94672
  } catch {}
94522
94673
  if (!authoredDanglingSymlink) {
94523
94674
  unindexable.add(file);
@@ -94568,7 +94719,7 @@ async function indexWrittenAssets(stashDir, filePaths, options = {}) {
94568
94719
  for (const { file, entry, conceptId, contentHash } of pairs) {
94569
94720
  let entryWithSize = entry;
94570
94721
  try {
94571
- entryWithSize = { ...entry, fileSize: fs46.statSync(file).size };
94722
+ entryWithSize = { ...entry, fileSize: fs48.statSync(file).size };
94572
94723
  } catch {}
94573
94724
  const provenance = deriveEntryProvenance({ bundleId: component.id, componentId: component.id, adapterId: component.adapter }, entry.type, entry.name, conceptId);
94574
94725
  const supersededIds = db.prepare("SELECT id FROM entries WHERE file_path = ? AND item_ref <> ?").all(file, provenance.itemRef);
@@ -94601,7 +94752,7 @@ async function indexWrittenAssets(stashDir, filePaths, options = {}) {
94601
94752
  init_asset_placement();
94602
94753
  init_asset_ref();
94603
94754
  init_warn();
94604
- import path59 from "node:path";
94755
+ import path60 from "node:path";
94605
94756
  function changesToStored(changes) {
94606
94757
  return changes.map((c, i) => ({
94607
94758
  path: c.path,
@@ -94654,10 +94805,10 @@ function currentProposalTarget(value) {
94654
94805
  if (typeof value !== "object" || value === null)
94655
94806
  throw new Error("Proposal metadata has an invalid proposedTarget.");
94656
94807
  const target = value;
94657
- if (typeof target.source !== "string" || !isBundleSlug(target.source) || typeof target.root !== "string" || !path59.isAbsolute(target.root)) {
94808
+ if (typeof target.source !== "string" || !isBundleSlug(target.source) || typeof target.root !== "string" || !path60.isAbsolute(target.root)) {
94658
94809
  throw new Error("Proposal metadata has an invalid proposedTarget.");
94659
94810
  }
94660
- return { source: target.source, root: path59.resolve(target.root) };
94811
+ return { source: target.source, root: path60.resolve(target.root) };
94661
94812
  }
94662
94813
  function invalidPresentField(name) {
94663
94814
  throw new Error(`Proposal metadata has an invalid ${name}.`);
@@ -94697,7 +94848,7 @@ function validatePresentMetadata(meta) {
94697
94848
  }
94698
94849
  if (Object.hasOwn(meta, "acceptedTarget")) {
94699
94850
  const target = meta.acceptedTarget;
94700
- if (typeof target !== "object" || target === null || typeof target.source !== "string" || !isBundleSlug(target.source) || typeof target.root !== "string" || !path59.isAbsolute(target.root) || typeof target.path !== "string" || !path59.isAbsolute(target.path) || typeof target.contentHash !== "string") {
94851
+ if (typeof target !== "object" || target === null || typeof target.source !== "string" || !isBundleSlug(target.source) || typeof target.root !== "string" || !path60.isAbsolute(target.root) || typeof target.path !== "string" || !path60.isAbsolute(target.path) || typeof target.contentHash !== "string") {
94701
94852
  invalidPresentField("acceptedTarget");
94702
94853
  }
94703
94854
  }
@@ -95431,12 +95582,12 @@ function proposalHash(content) {
95431
95582
  return createHash9("sha256").update(content).digest("hex");
95432
95583
  }
95433
95584
  function proposalFileHash(filePath) {
95434
- return proposalHash(fs47.readFileSync(filePath));
95585
+ return proposalHash(fs49.readFileSync(filePath));
95435
95586
  }
95436
95587
  function sameProposalFile(left, right) {
95437
95588
  try {
95438
- const leftStat = fs47.statSync(left);
95439
- const rightStat = fs47.statSync(right);
95589
+ const leftStat = fs49.statSync(left);
95590
+ const rightStat = fs49.statSync(right);
95440
95591
  return leftStat.dev === rightStat.dev && leftStat.ino === rightStat.ino;
95441
95592
  } catch {
95442
95593
  return false;
@@ -95445,20 +95596,20 @@ function sameProposalFile(left, right) {
95445
95596
  function cleanupProposalPublication(p) {
95446
95597
  for (const filePath of [p.publishPath, p.displacedPath]) {
95447
95598
  try {
95448
- fs47.rmSync(filePath, { force: true });
95599
+ fs49.rmSync(filePath, { force: true });
95449
95600
  } catch (error2) {
95450
95601
  warn(`[proposals] transaction publication cleanup failed at ${filePath}: ${error2 instanceof Error ? error2.message : String(error2)}`);
95451
95602
  }
95452
95603
  }
95453
- fsyncTxnDir(path60.dirname(p.assetPath));
95604
+ fsyncTxnDir(path61.dirname(p.assetPath));
95454
95605
  }
95455
95606
  function rollbackPreparedProposalTransaction(txn) {
95456
95607
  const p = txn.journal.payload;
95457
- const currentHash = fs47.existsSync(p.assetPath) ? proposalFileHash(p.assetPath) : null;
95458
- if (!fs47.existsSync(p.displacedPath)) {
95608
+ const currentHash = fs49.existsSync(p.assetPath) ? proposalFileHash(p.assetPath) : null;
95609
+ if (!fs49.existsSync(p.displacedPath)) {
95459
95610
  if (p.originalHash === null) {
95460
95611
  if (currentHash === p.publishedHash && sameProposalFile(p.assetPath, p.publishPath)) {
95461
- fs47.unlinkSync(p.assetPath);
95612
+ fs49.unlinkSync(p.assetPath);
95462
95613
  recordWrittenPath(p.assetPath);
95463
95614
  } else if (currentHash !== null) {
95464
95615
  throw new Error(`Cannot roll back proposal transaction: target was created externally.`);
@@ -95470,30 +95621,30 @@ function rollbackPreparedProposalTransaction(txn) {
95470
95621
  return;
95471
95622
  }
95472
95623
  if (currentHash === p.publishedHash) {
95473
- fs47.unlinkSync(p.assetPath);
95624
+ fs49.unlinkSync(p.assetPath);
95474
95625
  recordWrittenPath(p.assetPath);
95475
95626
  } else if (currentHash !== null && currentHash !== p.originalHash) {
95476
95627
  throw new Error(`Cannot roll back proposal transaction: ${p.assetPath} diverged.`);
95477
95628
  }
95478
- if (fs47.existsSync(p.displacedPath)) {
95479
- if (fs47.existsSync(p.assetPath)) {
95629
+ if (fs49.existsSync(p.displacedPath)) {
95630
+ if (fs49.existsSync(p.assetPath)) {
95480
95631
  throw new Error(`Cannot restore proposal backup: ${p.assetPath} is occupied.`);
95481
95632
  }
95482
- fs47.linkSync(p.displacedPath, p.assetPath);
95633
+ fs49.linkSync(p.displacedPath, p.assetPath);
95483
95634
  recordWrittenPath(p.assetPath);
95484
95635
  }
95485
95636
  cleanupProposalPublication(p);
95486
95637
  }
95487
95638
  function validatePublishedProposal(p) {
95488
- if (!fs47.existsSync(p.assetPath) || proposalFileHash(p.assetPath) !== p.publishedHash) {
95639
+ if (!fs49.existsSync(p.assetPath) || proposalFileHash(p.assetPath) !== p.publishedHash) {
95489
95640
  throw new Error(`Cannot recover proposal ${p.proposalId}: published asset diverged.`);
95490
95641
  }
95491
95642
  }
95492
95643
  function persistProposalTransactionState(txn, proposal, ctx) {
95493
95644
  const p = txn.journal.payload;
95494
95645
  const decidedAt = txn.journal.decidedAt;
95495
- const backupContent = p.backupPath ? fs47.readFileSync(p.backupPath, "utf8") : undefined;
95496
- const publishedContent = fs47.readFileSync(p.contentPath, "utf8");
95646
+ const backupContent = p.backupPath ? fs49.readFileSync(p.backupPath, "utf8") : undefined;
95647
+ const publishedContent = fs49.readFileSync(p.contentPath, "utf8");
95497
95648
  return withProposalsDb(p.stashDir, ctx, (db) => withImmediateTransaction(db, () => {
95498
95649
  const current = requireProposal(db, p.stashDir, p.proposalId);
95499
95650
  if (p.operation === "accept") {
@@ -95511,7 +95662,7 @@ function persistProposalTransactionState(txn, proposal, ctx) {
95511
95662
  payload: { ...proposal.payload, content: publishedContent },
95512
95663
  changes: [
95513
95664
  {
95514
- path: path60.relative(txn.journal.root, p.assetPath),
95665
+ path: path61.relative(txn.journal.root, p.assetPath),
95515
95666
  op: p.originalHash === null ? "create" : "update",
95516
95667
  after: publishedContent
95517
95668
  }
@@ -95582,7 +95733,7 @@ async function finalizeProposalTransaction(txn, target, proposal, ctx) {
95582
95733
  cleanupProposalPublication(p);
95583
95734
  if (txn.journal.phase === "asset-published") {
95584
95735
  const commitRoot = target.source.repoPath ?? target.source.path;
95585
- const commitPath = path60.relative(commitRoot, p.assetPath).replaceAll(path60.sep, "/");
95736
+ const commitPath = path61.relative(commitRoot, p.assetPath).replaceAll(path61.sep, "/");
95586
95737
  publishWriteTargetTransaction(target, p.gitPublication, {
95587
95738
  transactionId: txn.journal.transactionId,
95588
95739
  message: `${p.operation === "accept" ? "Update" : "Revert"} ${p.ref}`,
@@ -95619,8 +95770,8 @@ async function finalizeProposalTransaction(txn, target, proposal, ctx) {
95619
95770
  function fenceProposalTxnJournal(journal, txnDir, root) {
95620
95771
  const p = journal.payload;
95621
95772
  const refIdentity = proposalRefIdentity(p.ref);
95622
- if (!["accept", "revert"].includes(p.operation) || !p.targetSource || !p.targetKind || refIdentity?.bundle === undefined || !isWithin(p.assetPath, root) || ![p.contentPath, p.backupPath].filter((candidate) => candidate !== null).every((candidate) => isWithin(candidate, txnDir)) || ![p.publishPath, p.displacedPath].every((candidate) => isWithin(candidate, root) && path60.dirname(candidate) === path60.dirname(p.assetPath))) {
95623
- throw new Error(`Refusing unsafe proposal transaction journal at ${path60.join(txnDir, "journal.json")}.`);
95773
+ if (!["accept", "revert"].includes(p.operation) || !p.targetSource || !p.targetKind || refIdentity?.bundle === undefined || !isWithin(p.assetPath, root) || ![p.contentPath, p.backupPath].filter((candidate) => candidate !== null).every((candidate) => isWithin(candidate, txnDir)) || ![p.publishPath, p.displacedPath].every((candidate) => isWithin(candidate, root) && path61.dirname(candidate) === path61.dirname(p.assetPath))) {
95774
+ throw new Error(`Refusing unsafe proposal transaction journal at ${path61.join(txnDir, "journal.json")}.`);
95624
95775
  }
95625
95776
  }
95626
95777
  function resolveProposalRecoveryTarget(config, journal) {
@@ -95720,8 +95871,8 @@ async function recoverStaleTxns(stashDir) {
95720
95871
  }
95721
95872
 
95722
95873
  // scripts/akm-migrate/migrate/writer-relocation.ts
95723
- import fs48 from "node:fs";
95724
- import path61 from "node:path";
95874
+ import fs50 from "node:fs";
95875
+ import path62 from "node:path";
95725
95876
  init_paths();
95726
95877
  function relocationSpecs(stashDir) {
95727
95878
  return [
@@ -95741,7 +95892,7 @@ function mutexSiblingName(lockName) {
95741
95892
  function fileCountIfExists(dir) {
95742
95893
  let entries;
95743
95894
  try {
95744
- entries = fs48.readdirSync(dir, { withFileTypes: true });
95895
+ entries = fs50.readdirSync(dir, { withFileTypes: true });
95745
95896
  } catch {
95746
95897
  return;
95747
95898
  }
@@ -95749,7 +95900,7 @@ function fileCountIfExists(dir) {
95749
95900
  }
95750
95901
  function statFileIfExists(filePath) {
95751
95902
  try {
95752
- const stat = fs48.statSync(filePath);
95903
+ const stat = fs50.statSync(filePath);
95753
95904
  return stat.isFile() ? stat : undefined;
95754
95905
  } catch {
95755
95906
  return;
@@ -95759,8 +95910,8 @@ function classifyLockArtifacts(akmDir) {
95759
95910
  const removable = [];
95760
95911
  const skipped = [];
95761
95912
  for (const lockName of LOCK_NAMES) {
95762
- const lockPath = path61.join(akmDir, lockName);
95763
- const mutexPath = path61.join(akmDir, mutexSiblingName(lockName));
95913
+ const lockPath = path62.join(akmDir, lockName);
95914
+ const mutexPath = path62.join(akmDir, mutexSiblingName(lockName));
95764
95915
  const lockStat = statFileIfExists(lockPath);
95765
95916
  const mutexStat = statFileIfExists(mutexPath);
95766
95917
  if (!lockStat) {
@@ -95786,11 +95937,11 @@ function classifyLockArtifacts(akmDir) {
95786
95937
  return { removable, skipped };
95787
95938
  }
95788
95939
  function findWriterRelocationEntries(stashDir) {
95789
- const akmDir = path61.join(stashDir, ".akm");
95940
+ const akmDir = path62.join(stashDir, ".akm");
95790
95941
  const directories = [];
95791
95942
  for (const spec of relocationSpecs(stashDir)) {
95792
95943
  const relativeParts = Array.isArray(spec.oldRelative) ? spec.oldRelative : [spec.oldRelative];
95793
- const oldPath = path61.join(akmDir, ...relativeParts);
95944
+ const oldPath = path62.join(akmDir, ...relativeParts);
95794
95945
  const fileCount = fileCountIfExists(oldPath);
95795
95946
  if (fileCount === undefined || fileCount === 0)
95796
95947
  continue;
@@ -95801,36 +95952,36 @@ function findWriterRelocationEntries(stashDir) {
95801
95952
  }
95802
95953
  function moveFile(oldFilePath, newFilePath) {
95803
95954
  try {
95804
- fs48.renameSync(oldFilePath, newFilePath);
95955
+ fs50.renameSync(oldFilePath, newFilePath);
95805
95956
  } catch (error2) {
95806
95957
  if (error2.code !== "EXDEV")
95807
95958
  throw error2;
95808
- fs48.copyFileSync(oldFilePath, newFilePath);
95809
- fs48.rmSync(oldFilePath, { force: true });
95959
+ fs50.copyFileSync(oldFilePath, newFilePath);
95960
+ fs50.rmSync(oldFilePath, { force: true });
95810
95961
  }
95811
95962
  }
95812
95963
  function moveDirectoryContents(entry) {
95813
95964
  const errors3 = [];
95814
95965
  let moved = 0;
95815
- fs48.mkdirSync(entry.newPath, { recursive: true });
95966
+ fs50.mkdirSync(entry.newPath, { recursive: true });
95816
95967
  let names;
95817
95968
  try {
95818
- names = fs48.readdirSync(entry.oldPath).sort();
95969
+ names = fs50.readdirSync(entry.oldPath).sort();
95819
95970
  } catch {
95820
95971
  return { key: entry.key, oldPath: entry.oldPath, newPath: entry.newPath, moved: 0, errors: [] };
95821
95972
  }
95822
95973
  for (const name of names) {
95823
- const oldFilePath = path61.join(entry.oldPath, name);
95824
- const newFilePath = path61.join(entry.newPath, name);
95974
+ const oldFilePath = path62.join(entry.oldPath, name);
95975
+ const newFilePath = path62.join(entry.newPath, name);
95825
95976
  let oldStat;
95826
95977
  try {
95827
- oldStat = fs48.lstatSync(oldFilePath);
95978
+ oldStat = fs50.lstatSync(oldFilePath);
95828
95979
  } catch {
95829
95980
  continue;
95830
95981
  }
95831
95982
  if (!oldStat.isFile())
95832
95983
  continue;
95833
- if (fs48.existsSync(newFilePath))
95984
+ if (fs50.existsSync(newFilePath))
95834
95985
  continue;
95835
95986
  try {
95836
95987
  moveFile(oldFilePath, newFilePath);
@@ -95843,13 +95994,13 @@ function moveDirectoryContents(entry) {
95843
95994
  }
95844
95995
  function removeIfEmptyDir(dir) {
95845
95996
  try {
95846
- if (fs48.readdirSync(dir).length === 0)
95847
- fs48.rmdirSync(dir);
95997
+ if (fs50.readdirSync(dir).length === 0)
95998
+ fs50.rmdirSync(dir);
95848
95999
  } catch {}
95849
96000
  }
95850
96001
  function removeLockArtifact(entry) {
95851
96002
  try {
95852
- fs48.rmSync(entry.path, { force: true });
96003
+ fs50.rmSync(entry.path, { force: true });
95853
96004
  return { path: entry.path, removed: true };
95854
96005
  } catch (error2) {
95855
96006
  return { path: entry.path, removed: false, error: error2 instanceof Error ? error2.message : String(error2) };
@@ -95861,36 +96012,36 @@ function applyWriterRelocation(stashDir) {
95861
96012
  const lockResults = lockArtifacts.map(removeLockArtifact);
95862
96013
  for (const spec of relocationSpecs(stashDir)) {
95863
96014
  const relativeParts = Array.isArray(spec.oldRelative) ? spec.oldRelative : [spec.oldRelative];
95864
- removeIfEmptyDir(path61.join(stashDir, ".akm", ...relativeParts));
96015
+ removeIfEmptyDir(path62.join(stashDir, ".akm", ...relativeParts));
95865
96016
  }
95866
96017
  return { directories: directoryResults, lockArtifacts: lockResults, skippedLocks };
95867
96018
  }
95868
96019
 
95869
96020
  // scripts/akm-migrate/task-migrate.ts
95870
96021
  import { randomUUID as randomUUID7 } from "node:crypto";
95871
- import fs53 from "node:fs";
96022
+ import fs56 from "node:fs";
95872
96023
  import os5 from "node:os";
95873
- import path64 from "node:path";
96024
+ import path65 from "node:path";
95874
96025
  init_errors();
95875
96026
  init_paths();
95876
96027
 
95877
96028
  // scripts/akm-migrate/migrate/task-files-to-v3.ts
95878
96029
  init_errors();
95879
96030
  import crypto6 from "node:crypto";
95880
- import fs50 from "node:fs";
95881
- import path62 from "node:path";
96031
+ import fs53 from "node:fs";
96032
+ import path63 from "node:path";
95882
96033
 
95883
96034
  // scripts/akm-migrate/migrate/durable-fs.ts
95884
- import fs49 from "node:fs";
96035
+ import fs51 from "node:fs";
95885
96036
  function fsyncDirectoryPortable(directory) {
95886
96037
  if (process.platform === "win32")
95887
96038
  return;
95888
96039
  try {
95889
- const fd = fs49.openSync(directory, "r");
96040
+ const fd = fs51.openSync(directory, "r");
95890
96041
  try {
95891
- fs49.fsyncSync(fd);
96042
+ fs51.fsyncSync(fd);
95892
96043
  } finally {
95893
- fs49.closeSync(fd);
96044
+ fs51.closeSync(fd);
95894
96045
  }
95895
96046
  } catch (cause) {
95896
96047
  const code = cause.code;
@@ -95904,25 +96055,25 @@ function migrationError(detail) {
95904
96055
  return new ConfigError(`Task migration to v3 failed: ${detail}`, "INVALID_CONFIG_FILE");
95905
96056
  }
95906
96057
  function contained2(root, candidate) {
95907
- const relative = path62.relative(root, candidate);
95908
- return relative === "" || !relative.startsWith("..") && !path62.isAbsolute(relative);
96058
+ const relative = path63.relative(root, candidate);
96059
+ return relative === "" || !relative.startsWith("..") && !path63.isAbsolute(relative);
95909
96060
  }
95910
96061
  function realDirectory(filePath) {
95911
- const stat = fs50.lstatSync(filePath);
96062
+ const stat = fs53.lstatSync(filePath);
95912
96063
  if (stat.isSymbolicLink() || !stat.isDirectory())
95913
96064
  throw migrationError(`${filePath} must be a real directory.`);
95914
- return fs50.realpathSync(filePath);
96065
+ return fs53.realpathSync(filePath);
95915
96066
  }
95916
96067
  function snapshot(filePath) {
95917
- const stat = fs50.lstatSync(filePath);
96068
+ const stat = fs53.lstatSync(filePath);
95918
96069
  if (stat.isSymbolicLink() || !stat.isFile())
95919
96070
  throw migrationError(`${filePath} must be a real file.`);
95920
- const bytes = fs50.readFileSync(filePath);
96071
+ const bytes = fs53.readFileSync(filePath);
95921
96072
  return Object.freeze({ bytes, mode: stat.mode & 511 });
95922
96073
  }
95923
96074
  function writable(filePath) {
95924
96075
  try {
95925
- fs50.accessSync(filePath, fs50.constants.W_OK);
96076
+ fs53.accessSync(filePath, fs53.constants.W_OK);
95926
96077
  return true;
95927
96078
  } catch {
95928
96079
  return false;
@@ -95935,12 +96086,12 @@ function walkTasks(root, tasksDir, out) {
95935
96086
  throw migrationError(`${root.root} resolves outside bundle ${root.bundleId}.`);
95936
96087
  }
95937
96088
  const visit2 = (directory) => {
95938
- const physicalDirectory = fs50.realpathSync(directory);
96089
+ const physicalDirectory = fs53.realpathSync(directory);
95939
96090
  if (!contained2(physicalRoot, physicalDirectory)) {
95940
96091
  throw migrationError(`${directory} resolves outside bundle ${root.bundleId}.`);
95941
96092
  }
95942
- for (const entry of fs50.readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
95943
- const candidate = path62.join(directory, entry.name);
96093
+ for (const entry of fs53.readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
96094
+ const candidate = path63.join(directory, entry.name);
95944
96095
  if (entry.isSymbolicLink())
95945
96096
  throw migrationError(`task migration does not follow symbolic link ${candidate}.`);
95946
96097
  if (entry.isDirectory()) {
@@ -95950,7 +96101,7 @@ function walkTasks(root, tasksDir, out) {
95950
96101
  if (!entry.isFile() || !entry.name.endsWith(".yml"))
95951
96102
  continue;
95952
96103
  const current = snapshot(candidate);
95953
- const parent = path62.dirname(candidate);
96104
+ const parent = path63.dirname(candidate);
95954
96105
  out.push({
95955
96106
  filePath: candidate,
95956
96107
  bytes: current.bytes,
@@ -95966,9 +96117,9 @@ function walkTasks(root, tasksDir, out) {
95966
96117
  function inspectTaskToV3Files(roots) {
95967
96118
  const files = [];
95968
96119
  for (const root of [...roots].sort((a, b) => a.bundleId.localeCompare(b.bundleId))) {
95969
- const tasksDir = root.layout === "akm-task" ? root.root : path62.join(root.root, "tasks");
96120
+ const tasksDir = root.layout === "akm-task" ? root.root : path63.join(root.root, "tasks");
95970
96121
  try {
95971
- const stat = fs50.lstatSync(tasksDir);
96122
+ const stat = fs53.lstatSync(tasksDir);
95972
96123
  if (stat.isSymbolicLink())
95973
96124
  throw migrationError(`task migration does not follow symbolic link ${tasksDir}.`);
95974
96125
  if (!stat.isDirectory())
@@ -95983,33 +96134,33 @@ function inspectTaskToV3Files(roots) {
95983
96134
  return files.sort((a, b) => a.filePath.localeCompare(b.filePath));
95984
96135
  }
95985
96136
  function hashPath(filePath) {
95986
- return crypto6.createHash("sha256").update(path62.resolve(filePath)).digest("hex").slice(0, 16);
96137
+ return crypto6.createHash("sha256").update(path63.resolve(filePath)).digest("hex").slice(0, 16);
95987
96138
  }
95988
96139
  function taskMigrationBackupPath(backupRoot, filePath) {
95989
- return path62.join(backupRoot, "files", `${hashPath(filePath)}-${path62.basename(filePath)}`);
96140
+ return path63.join(backupRoot, "files", `${hashPath(filePath)}-${path63.basename(filePath)}`);
95990
96141
  }
95991
96142
  function writeDurable(filePath, bytes, mode, exclusive = false) {
95992
- fs50.mkdirSync(path62.dirname(filePath), { recursive: true });
96143
+ fs53.mkdirSync(path63.dirname(filePath), { recursive: true });
95993
96144
  const flags = exclusive ? "wx" : "w";
95994
- const fd = fs50.openSync(filePath, flags, mode);
96145
+ const fd = fs53.openSync(filePath, flags, mode);
95995
96146
  try {
95996
- fs50.writeFileSync(fd, bytes);
95997
- fs50.fsyncSync(fd);
96147
+ fs53.writeFileSync(fd, bytes);
96148
+ fs53.fsyncSync(fd);
95998
96149
  } finally {
95999
- fs50.closeSync(fd);
96150
+ fs53.closeSync(fd);
96000
96151
  }
96001
- fs50.chmodSync(filePath, mode);
96002
- fsyncDirectoryPortable(path62.dirname(filePath));
96152
+ fs53.chmodSync(filePath, mode);
96153
+ fsyncDirectoryPortable(path63.dirname(filePath));
96003
96154
  }
96004
96155
  function replaceAtomically(filePath, bytes, mode) {
96005
- const temporary = path62.join(path62.dirname(filePath), `.${path62.basename(filePath)}.migrate-${crypto6.randomUUID()}`);
96156
+ const temporary = path63.join(path63.dirname(filePath), `.${path63.basename(filePath)}.migrate-${crypto6.randomUUID()}`);
96006
96157
  try {
96007
96158
  writeDurable(temporary, bytes, mode, true);
96008
- fs50.renameSync(temporary, filePath);
96009
- fsyncDirectoryPortable(path62.dirname(filePath));
96159
+ fs53.renameSync(temporary, filePath);
96160
+ fsyncDirectoryPortable(path63.dirname(filePath));
96010
96161
  } finally {
96011
96162
  try {
96012
- fs50.unlinkSync(temporary);
96163
+ fs53.unlinkSync(temporary);
96013
96164
  } catch (cause) {
96014
96165
  if (cause.code !== "ENOENT")
96015
96166
  throw cause;
@@ -96048,7 +96199,7 @@ function applyTaskToV3MigrationPlan(plan, options) {
96048
96199
  const current = snapshot(change.filePath);
96049
96200
  if (!current.bytes.equals(change.after))
96050
96201
  continue;
96051
- replaceAtomically(change.filePath, fs50.readFileSync(taskMigrationBackupPath(options.backupRoot, change.filePath)), change.mode);
96202
+ replaceAtomically(change.filePath, fs53.readFileSync(taskMigrationBackupPath(options.backupRoot, change.filePath)), change.mode);
96052
96203
  }
96053
96204
  throw cause;
96054
96205
  }
@@ -96058,31 +96209,31 @@ function applyTaskToV3MigrationPlan(plan, options) {
96058
96209
  // scripts/akm-migrate/migrate/task-files-to-v4.ts
96059
96210
  init_errors();
96060
96211
  import crypto7 from "node:crypto";
96061
- import fs51 from "node:fs";
96062
- import path63 from "node:path";
96212
+ import fs55 from "node:fs";
96213
+ import path64 from "node:path";
96063
96214
  function migrationError2(detail) {
96064
96215
  return new ConfigError(`Task migration to v4 failed: ${detail}`, "INVALID_CONFIG_FILE");
96065
96216
  }
96066
96217
  function contained3(root, candidate) {
96067
- const relative = path63.relative(root, candidate);
96068
- return relative === "" || !relative.startsWith("..") && !path63.isAbsolute(relative);
96218
+ const relative = path64.relative(root, candidate);
96219
+ return relative === "" || !relative.startsWith("..") && !path64.isAbsolute(relative);
96069
96220
  }
96070
96221
  function realDirectory2(filePath) {
96071
- const stat = fs51.lstatSync(filePath);
96222
+ const stat = fs55.lstatSync(filePath);
96072
96223
  if (stat.isSymbolicLink() || !stat.isDirectory())
96073
96224
  throw migrationError2(`${filePath} must be a real directory.`);
96074
- return fs51.realpathSync(filePath);
96225
+ return fs55.realpathSync(filePath);
96075
96226
  }
96076
96227
  function snapshot2(filePath) {
96077
- const stat = fs51.lstatSync(filePath);
96228
+ const stat = fs55.lstatSync(filePath);
96078
96229
  if (stat.isSymbolicLink() || !stat.isFile())
96079
96230
  throw migrationError2(`${filePath} must be a real file.`);
96080
- const bytes = fs51.readFileSync(filePath);
96231
+ const bytes = fs55.readFileSync(filePath);
96081
96232
  return Object.freeze({ bytes, mode: stat.mode & 511 });
96082
96233
  }
96083
96234
  function writable2(filePath) {
96084
96235
  try {
96085
- fs51.accessSync(filePath, fs51.constants.W_OK);
96236
+ fs55.accessSync(filePath, fs55.constants.W_OK);
96086
96237
  return true;
96087
96238
  } catch {
96088
96239
  return false;
@@ -96095,12 +96246,12 @@ function walkTasks2(root, tasksDir, out) {
96095
96246
  throw migrationError2(`${root.root} resolves outside bundle ${root.bundleId}.`);
96096
96247
  }
96097
96248
  const visit2 = (directory) => {
96098
- const physicalDirectory = fs51.realpathSync(directory);
96249
+ const physicalDirectory = fs55.realpathSync(directory);
96099
96250
  if (!contained3(physicalRoot, physicalDirectory)) {
96100
96251
  throw migrationError2(`${directory} resolves outside bundle ${root.bundleId}.`);
96101
96252
  }
96102
- for (const entry of fs51.readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
96103
- const candidate = path63.join(directory, entry.name);
96253
+ for (const entry of fs55.readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
96254
+ const candidate = path64.join(directory, entry.name);
96104
96255
  if (entry.isSymbolicLink())
96105
96256
  throw migrationError2(`task migration does not follow symbolic link ${candidate}.`);
96106
96257
  if (entry.isDirectory()) {
@@ -96110,7 +96261,7 @@ function walkTasks2(root, tasksDir, out) {
96110
96261
  if (!entry.isFile() || !entry.name.endsWith(".yml"))
96111
96262
  continue;
96112
96263
  const current = snapshot2(candidate);
96113
- const parent = path63.dirname(candidate);
96264
+ const parent = path64.dirname(candidate);
96114
96265
  out.push({
96115
96266
  filePath: candidate,
96116
96267
  bytes: current.bytes,
@@ -96126,9 +96277,9 @@ function walkTasks2(root, tasksDir, out) {
96126
96277
  function inspectTaskToV4Files(roots) {
96127
96278
  const files = [];
96128
96279
  for (const root of [...roots].sort((a, b) => a.bundleId.localeCompare(b.bundleId))) {
96129
- const tasksDir = root.layout === "akm-task" ? root.root : path63.join(root.root, "tasks");
96280
+ const tasksDir = root.layout === "akm-task" ? root.root : path64.join(root.root, "tasks");
96130
96281
  try {
96131
- const stat = fs51.lstatSync(tasksDir);
96282
+ const stat = fs55.lstatSync(tasksDir);
96132
96283
  if (stat.isSymbolicLink())
96133
96284
  throw migrationError2(`task migration does not follow symbolic link ${tasksDir}.`);
96134
96285
  if (!stat.isDirectory())
@@ -96143,33 +96294,33 @@ function inspectTaskToV4Files(roots) {
96143
96294
  return files.sort((a, b) => a.filePath.localeCompare(b.filePath));
96144
96295
  }
96145
96296
  function hashPath2(filePath) {
96146
- return crypto7.createHash("sha256").update(path63.resolve(filePath)).digest("hex").slice(0, 16);
96297
+ return crypto7.createHash("sha256").update(path64.resolve(filePath)).digest("hex").slice(0, 16);
96147
96298
  }
96148
96299
  function taskMigrationBackupPathV4(backupRoot, filePath) {
96149
- return path63.join(backupRoot, "files", `${hashPath2(filePath)}-${path63.basename(filePath)}`);
96300
+ return path64.join(backupRoot, "files", `${hashPath2(filePath)}-${path64.basename(filePath)}`);
96150
96301
  }
96151
96302
  function writeDurable2(filePath, bytes, mode, exclusive = false) {
96152
- fs51.mkdirSync(path63.dirname(filePath), { recursive: true });
96303
+ fs55.mkdirSync(path64.dirname(filePath), { recursive: true });
96153
96304
  const flags = exclusive ? "wx" : "w";
96154
- const fd = fs51.openSync(filePath, flags, mode);
96305
+ const fd = fs55.openSync(filePath, flags, mode);
96155
96306
  try {
96156
- fs51.writeFileSync(fd, bytes);
96157
- fs51.fsyncSync(fd);
96307
+ fs55.writeFileSync(fd, bytes);
96308
+ fs55.fsyncSync(fd);
96158
96309
  } finally {
96159
- fs51.closeSync(fd);
96310
+ fs55.closeSync(fd);
96160
96311
  }
96161
- fs51.chmodSync(filePath, mode);
96162
- fsyncDirectoryPortable(path63.dirname(filePath));
96312
+ fs55.chmodSync(filePath, mode);
96313
+ fsyncDirectoryPortable(path64.dirname(filePath));
96163
96314
  }
96164
96315
  function replaceAtomically2(filePath, bytes, mode) {
96165
- const temporary = path63.join(path63.dirname(filePath), `.${path63.basename(filePath)}.migrate-${crypto7.randomUUID()}`);
96316
+ const temporary = path64.join(path64.dirname(filePath), `.${path64.basename(filePath)}.migrate-${crypto7.randomUUID()}`);
96166
96317
  try {
96167
96318
  writeDurable2(temporary, bytes, mode, true);
96168
- fs51.renameSync(temporary, filePath);
96169
- fsyncDirectoryPortable(path63.dirname(filePath));
96319
+ fs55.renameSync(temporary, filePath);
96320
+ fsyncDirectoryPortable(path64.dirname(filePath));
96170
96321
  } finally {
96171
96322
  try {
96172
- fs51.unlinkSync(temporary);
96323
+ fs55.unlinkSync(temporary);
96173
96324
  } catch (cause) {
96174
96325
  if (cause.code !== "ENOENT")
96175
96326
  throw cause;
@@ -96208,7 +96359,7 @@ function applyTaskToV4MigrationPlan(plan, options) {
96208
96359
  const current = snapshot2(change.filePath);
96209
96360
  if (!current.bytes.equals(change.after))
96210
96361
  continue;
96211
- replaceAtomically2(change.filePath, fs51.readFileSync(taskMigrationBackupPathV4(options.backupRoot, change.filePath)), change.mode);
96362
+ replaceAtomically2(change.filePath, fs55.readFileSync(taskMigrationBackupPathV4(options.backupRoot, change.filePath)), change.mode);
96212
96363
  }
96213
96364
  throw cause;
96214
96365
  }
@@ -96220,12 +96371,12 @@ function expandTilde(value) {
96220
96371
  if (value === "~")
96221
96372
  return os5.homedir();
96222
96373
  if (value.startsWith("~/") || value.startsWith("~\\"))
96223
- return path64.join(os5.homedir(), value.slice(2));
96374
+ return path65.join(os5.homedir(), value.slice(2));
96224
96375
  return value;
96225
96376
  }
96226
96377
  function existingDirectory(target) {
96227
96378
  try {
96228
- return fs53.statSync(target).isDirectory();
96379
+ return fs56.statSync(target).isDirectory();
96229
96380
  } catch (cause) {
96230
96381
  if (cause.code === "ENOENT")
96231
96382
  return false;
@@ -96246,21 +96397,21 @@ function taskRoots(config, resolutionBase = process.cwd()) {
96246
96397
  const source = sources.get(bundleId);
96247
96398
  if (!source)
96248
96399
  continue;
96249
- const configuredRoot = source.type === "filesystem" && source.path ? path64.resolve(resolutionBase, expandTilde(source.path)) : lockContentRootFor(bundleId, source.type);
96400
+ const configuredRoot = source.type === "filesystem" && source.path ? path65.resolve(resolutionBase, expandTilde(source.path)) : lockContentRootFor(bundleId, source.type);
96250
96401
  if (!configuredRoot || !existingDirectory(configuredRoot))
96251
96402
  continue;
96252
- const bundleRoot = path64.resolve(configuredRoot);
96403
+ const bundleRoot = path65.resolve(configuredRoot);
96253
96404
  const component = bundleComponentConfig(bundle);
96254
- const componentRoot = path64.resolve(bundleRoot, component?.root ?? ".");
96255
- const relative = path64.relative(bundleRoot, componentRoot);
96256
- if (relative === ".." || relative.startsWith(`..${path64.sep}`) || path64.isAbsolute(relative)) {
96405
+ const componentRoot = path65.resolve(bundleRoot, component?.root ?? ".");
96406
+ const relative = path65.relative(bundleRoot, componentRoot);
96407
+ if (relative === ".." || relative.startsWith(`..${path65.sep}`) || path65.isAbsolute(relative)) {
96257
96408
  throw new ConfigError(`Task migration component root ${componentRoot} escapes bundle ${bundleId} at ${bundleRoot}.`, "INVALID_CONFIG_FILE");
96258
96409
  }
96259
96410
  if (!existingDirectory(componentRoot))
96260
96411
  continue;
96261
96412
  const adapter = component?.adapter ?? detectAdapterId(componentRoot, "");
96262
96413
  if (!component?.adapter && adapter === "") {
96263
- const flatTasks = fs53.readdirSync(componentRoot, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".yml")).map((entry) => entry.name).sort();
96414
+ const flatTasks = fs56.readdirSync(componentRoot, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".yml")).map((entry) => entry.name).sort();
96264
96415
  if (flatTasks.length > 0) {
96265
96416
  throw new ConfigError(`Task migration cannot classify top-level task file(s) ${flatTasks.join(", ")} in bundle ${bundleId}; configure adapter "akm-task" or move them under tasks/.`, "INVALID_CONFIG_FILE");
96266
96417
  }
@@ -96332,8 +96483,8 @@ function applyTaskV3Migration() {
96332
96483
  const before = inspectCurrentTaskPlan();
96333
96484
  if (before.result.taskV3Migration.changed === 0)
96334
96485
  return before.result;
96335
- const backupRoot = path64.join(getDataDir(), "backups", "task-v3");
96336
- const backupPath = path64.join(backupRoot, `${Date.now()}-${randomUUID7()}`);
96486
+ const backupRoot = path65.join(getDataDir(), "backups", "task-v3");
96487
+ const backupPath = path65.join(backupRoot, `${Date.now()}-${randomUUID7()}`);
96337
96488
  const applied = applyTaskToV3MigrationPlan(before.plan, { backupRoot: backupPath });
96338
96489
  const after = inspectCurrentTaskPlan().result;
96339
96490
  if (after.taskV3Migration.changed > 0) {
@@ -96389,8 +96540,8 @@ function applyTaskV4Migration() {
96389
96540
  const before = inspectCurrentTaskV4Plan();
96390
96541
  if (before.result.taskV4Migration.changed === 0)
96391
96542
  return before.result;
96392
- const backupRoot = path64.join(getDataDir(), "backups", "task-v4");
96393
- const backupPath = path64.join(backupRoot, `${Date.now()}-${randomUUID7()}`);
96543
+ const backupRoot = path65.join(getDataDir(), "backups", "task-v4");
96544
+ const backupPath = path65.join(backupRoot, `${Date.now()}-${randomUUID7()}`);
96394
96545
  const applied = applyTaskToV4MigrationPlan(before.plan, { backupRoot: backupPath });
96395
96546
  const after = inspectCurrentTaskV4Plan().result;
96396
96547
  if (after.taskV4Migration.changed > 0) {