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.
@@ -7042,7 +7042,8 @@ var init_errors = __esm(() => {
7042
7042
  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.",
7043
7043
  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.",
7044
7044
  UNKNOWN_IMPROVE_STRATEGY: "Pass one of the listed strategy names to `--strategy`, or define it under `improve.strategies`. Names are case-sensitive.",
7045
- EXECUTION_NOT_AUTHORIZED: "Change the selected tools or update the machine/user execution policy, then retry."
7045
+ EXECUTION_NOT_AUTHORIZED: "Change the selected tools or update the machine/user execution policy, then retry.",
7046
+ 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."
7046
7047
  };
7047
7048
  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.";
7048
7049
  USAGE_HINTS = {
@@ -7064,7 +7065,8 @@ var init_errors = __esm(() => {
7064
7065
  INPUT_BINDING_INVALID: "Check the step's with: keys against the target's declared inputs.",
7065
7066
  TASK_TARGET_UNSUPPORTED: "Task definitions support command, script, workflow, and shell (run:) targets; akm/command is layered by callers.",
7066
7067
  WORKFLOW_IR_VERSION_UNSUPPORTED: "Abandon the run with `akm workflow abandon <id>`, then start it again from the workflow source \u2014 a frozen plan this akm cannot execute is not re-executable in place.",
7067
- 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."
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
+ 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."
7068
7070
  };
7069
7071
  NOT_FOUND_HINTS = {
7070
7072
  ASSET_NOT_FOUND: "Run `akm search <query>` or `akm index` to refresh the index.",
@@ -8388,6 +8390,17 @@ function parseRefInput(raw) {
8388
8390
  }
8389
8391
  return { type: parts.type, name: parts.name, origin: ref.bundle };
8390
8392
  }
8393
+ function isFullRefInput(raw) {
8394
+ const trimmed = raw.trim();
8395
+ if (!trimmed)
8396
+ return false;
8397
+ try {
8398
+ const parsed = parseBundleRef(trimmed);
8399
+ return parsed.bundle !== undefined || typeNameFromConceptId(parsed.conceptId) !== undefined;
8400
+ } catch {
8401
+ return false;
8402
+ }
8403
+ }
8391
8404
  var init_resolve_ref = __esm(() => {
8392
8405
  init_errors();
8393
8406
  init_asset_placement();
@@ -12414,7 +12427,7 @@ function bindStepSections(headings, lines, bodyStartLine, totalLines, path24, de
12414
12427
  if (!declaredIds.has(h.text)) {
12415
12428
  errors3.push({
12416
12429
  line: h.line,
12417
- message: `Unexpected level-2 heading "## ${h.text}" on line ${h.line} \u2014 no step "${h.text}" is declared in frontmatter "steps:". Level-2 headings must exactly match a declared step id.`
12430
+ message: `Unexpected level-2 heading "## ${h.text}" on line ${h.line} \u2014 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.`
12418
12431
  });
12419
12432
  continue;
12420
12433
  }
@@ -68087,15 +68100,15 @@ ${this.boa_token}${this.audio_token.repeat(this._compute_audio_num_tokens(audio_
68087
68100
  });
68088
68101
 
68089
68102
  // src/indexer/walk/file-context.ts
68090
- import fs45 from "fs";
68091
- import path55 from "path";
68103
+ import fs47 from "fs";
68104
+ import path56 from "path";
68092
68105
  function buildFileContext(stashRoot, absPath) {
68093
- const relPath = toPosix(path55.relative(stashRoot, absPath));
68094
- const ext = path55.extname(absPath).toLowerCase();
68095
- const fileName = path55.basename(absPath);
68096
- const parentDirAbs = path55.dirname(absPath);
68097
- const parentDir = path55.basename(parentDirAbs);
68098
- const relDir = toPosix(path55.dirname(relPath));
68106
+ const relPath = toPosix(path56.relative(stashRoot, absPath));
68107
+ const ext = path56.extname(absPath).toLowerCase();
68108
+ const fileName = path56.basename(absPath);
68109
+ const parentDirAbs = path56.dirname(absPath);
68110
+ const parentDir = path56.basename(parentDirAbs);
68111
+ const relDir = toPosix(path56.dirname(relPath));
68099
68112
  const ancestorDirs = relDir === "." ? [] : relDir.split("/").filter((seg) => seg.length > 0);
68100
68113
  let cachedContent;
68101
68114
  let cachedFrontmatter;
@@ -68112,7 +68125,7 @@ function buildFileContext(stashRoot, absPath) {
68112
68125
  stashRoot,
68113
68126
  content() {
68114
68127
  if (cachedContent === undefined) {
68115
- cachedContent = fs45.readFileSync(absPath, "utf8");
68128
+ cachedContent = fs47.readFileSync(absPath, "utf8");
68116
68129
  }
68117
68130
  return cachedContent;
68118
68131
  },
@@ -68127,7 +68140,7 @@ function buildFileContext(stashRoot, absPath) {
68127
68140
  },
68128
68141
  stat() {
68129
68142
  if (cachedStat === undefined) {
68130
- cachedStat = fs45.statSync(absPath);
68143
+ cachedStat = fs47.statSync(absPath);
68131
68144
  }
68132
68145
  return cachedStat;
68133
68146
  }
@@ -70250,6 +70263,7 @@ function formatProposalDrainPlain(r) {
70250
70263
  const deferred = Array.isArray(r.deferred) ? r.deferred : [];
70251
70264
  const skippedByCap = Array.isArray(r.skippedByCap) ? r.skippedByCap : [];
70252
70265
  const staged = Array.isArray(r.staged) ? r.staged : [];
70266
+ const failed = Array.isArray(r.failed) ? r.failed : [];
70253
70267
  const prefix = r.dryRun === true ? "[dry-run] " : "";
70254
70268
  const lines = [
70255
70269
  `${prefix}Drained proposal queue (strategy=${String(r.strategy ?? "?")}, policy=${policy}, applyMode=${applyMode})`,
@@ -70257,11 +70271,15 @@ function formatProposalDrainPlain(r) {
70257
70271
  ` rejected: ${rejected.length}`,
70258
70272
  ` deferred: ${deferred.length}`,
70259
70273
  ` skippedByCap: ${skippedByCap.length}`,
70260
- ` staged: ${staged.length}`
70274
+ ` staged: ${staged.length}`,
70275
+ ` failed: ${failed.length}`
70261
70276
  ];
70262
70277
  for (const d of deferred) {
70263
70278
  lines.push(` - ${String(d.id ?? "?")} (${String(d.reason ?? "?")})`);
70264
70279
  }
70280
+ for (const f of failed) {
70281
+ lines.push(` ! ${String(f.id ?? "?")} (${String(f.reason ?? "?")}): ${String(f.detail ?? "?")}`);
70282
+ }
70265
70283
  appendLoweringNotices(lines, r);
70266
70284
  return lines.join(`
70267
70285
  `).trimEnd();
@@ -75483,12 +75501,16 @@ var httpUrl = exports_external.string().refine((v) => v.startsWith("http://") ||
75483
75501
  });
75484
75502
  var ENGINE_NAME_PATTERN = new RegExp(ENGINE_NAME_PATTERN_SOURCE);
75485
75503
  var ENV_REFERENCE_PATTERN = /^\$[A-Za-z_][A-Za-z0-9_]*$|^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/;
75504
+ var SECRET_STORE_REFERENCE_PATTERN = /^secret:\/\/(.+)$/;
75486
75505
  var engineName = exports_external.string().max(63).regex(ENGINE_NAME_PATTERN, "names must be lowercase kebab-case and must not begin with reserved akm-");
75506
+ function isApiKeyReference(value) {
75507
+ return ENV_REFERENCE_PATTERN.test(value) || SECRET_STORE_REFERENCE_PATTERN.test(value);
75508
+ }
75487
75509
  function symbolicOrWarnApiKey(label) {
75488
75510
  return exports_external.string().superRefine((value) => {
75489
- if (ENV_REFERENCE_PATTERN.test(value))
75511
+ if (isApiKeyReference(value))
75490
75512
  return;
75491
- 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) \u2014 see docs/reference/data-and-telemetry.md.`);
75513
+ 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> ...\`) \u2014 see docs/reference/data-and-telemetry.md.`);
75492
75514
  });
75493
75515
  }
75494
75516
  var chatCompletionsEndpoint = exports_external.string().superRefine((value, ctx) => {
@@ -76656,11 +76678,19 @@ function getSources(config) {
76656
76678
  function loadConfig() {
76657
76679
  return loadUserConfig();
76658
76680
  }
76659
- function resolveSecret(value) {
76681
+ function resolveSecret(value, resolveFromStore) {
76660
76682
  if (value === undefined)
76661
76683
  return;
76662
76684
  if (typeof value !== "string")
76663
76685
  return value;
76686
+ const storeRef = SECRET_STORE_REFERENCE_PATTERN.exec(value)?.[1];
76687
+ if (storeRef !== undefined) {
76688
+ const resolved = resolveFromStore?.(storeRef) ?? null;
76689
+ if (resolved === null) {
76690
+ throw new ConfigError(`Secret store reference "${value}" did not resolve to a stored value.`, "SECRET_REFERENCE_UNRESOLVED");
76691
+ }
76692
+ return resolved;
76693
+ }
76664
76694
  if (!value.includes("$"))
76665
76695
  return value;
76666
76696
  return value.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}|\$([A-Za-z_][A-Za-z0-9_]*)/g, (_match, braced, bare) => {
@@ -78545,9 +78575,9 @@ function listTxnJournalsTolerant(predicate) {
78545
78575
 
78546
78576
  // src/commands/proposal/repository.ts
78547
78577
  import { createHash as createHash9, randomUUID as randomUUID6 } from "crypto";
78548
- import fs47 from "fs";
78578
+ import fs49 from "fs";
78549
78579
  init_dist();
78550
- import path60 from "path";
78580
+ import path61 from "path";
78551
78581
 
78552
78582
  // src/core/adapter/adapters/agent-skills-adapter.ts
78553
78583
  init_frontmatter();
@@ -92631,8 +92661,8 @@ init_warn();
92631
92661
  init_write_provenance();
92632
92662
 
92633
92663
  // src/indexer/index-written-assets.ts
92634
- import fs46 from "fs";
92635
- import path58 from "path";
92664
+ import fs48 from "fs";
92665
+ import path59 from "path";
92636
92666
  init_errors();
92637
92667
  init_paths();
92638
92668
  init_warn();
@@ -93669,6 +93699,127 @@ function redactSensitiveText(text, sensitiveValues) {
93669
93699
 
93670
93700
  // src/llm/embedders/remote.ts
93671
93701
  init_warn();
93702
+
93703
+ // src/sources/snapshot-fetchers/secret-seam.ts
93704
+ import fs45 from "fs";
93705
+
93706
+ // src/core/env-secret-ref.ts
93707
+ import fs43 from "fs";
93708
+ import path54 from "path";
93709
+
93710
+ // src/registry/origin-resolve.ts
93711
+ init_asset_ref();
93712
+ function resolveSourcesForOrigin(origin, allSources) {
93713
+ if (!origin)
93714
+ return allSources;
93715
+ const installations = deriveInstallations(allSources);
93716
+ return allSources.filter((_, index) => installations[index]?.id === origin);
93717
+ }
93718
+
93719
+ // src/core/asset/asset-create.ts
93720
+ init_errors();
93721
+ function normalizeCreateSubPath(subPath) {
93722
+ if (subPath === undefined)
93723
+ return "";
93724
+ const trimmed = subPath.trim().replace(/\\/g, "/").replace(/^\/+|\/+$/g, "");
93725
+ if (!trimmed)
93726
+ return "";
93727
+ if (trimmed.split("/").some((segment) => !segment || segment === "." || segment === "..")) {
93728
+ throw new UsageError("--path must be a relative directory without '.' or '..' segments.");
93729
+ }
93730
+ return trimmed;
93731
+ }
93732
+ function assertFlatAssetName(name) {
93733
+ if (name?.replace(/\\/g, "/").replace(/\.md$/i, "").includes("/")) {
93734
+ throw new UsageError("Asset --name must be a flat name without '/'. Use --path to choose a subdirectory " + "(e.g. --path personal --name grocery-list).");
93735
+ }
93736
+ }
93737
+ function combineCreatePath(subPath, baseName) {
93738
+ return subPath ? `${subPath}/${baseName}` : baseName;
93739
+ }
93740
+
93741
+ // src/core/env-secret-ref.ts
93742
+ init_asset_placement();
93743
+ init_resolve_ref();
93744
+ init_common();
93745
+ init_errors();
93746
+ function assertNotRemovedVaultRef(ref) {
93747
+ const boundary = ref.indexOf("//");
93748
+ const bare = boundary >= 0 ? ref.slice(boundary + 2) : ref;
93749
+ if (/^vault[:/]/.test(bare.trim())) {
93750
+ throw new UsageError("The `vault` asset type was removed in 0.9.0 \u2014 use `env/` (whole .env config) or `secrets/` (a single value).", "INVALID_FLAG_VALUE");
93751
+ }
93752
+ }
93753
+ function assertNotColonRef(ref, aliases, replacement) {
93754
+ const boundary = ref.indexOf("//");
93755
+ const bare = (boundary >= 0 ? ref.slice(boundary + 2) : ref).trim();
93756
+ const colon = bare.indexOf(":");
93757
+ if (colon <= 0)
93758
+ return;
93759
+ const head = bare.slice(0, colon).toLowerCase();
93760
+ if (!aliases.includes(head))
93761
+ return;
93762
+ const name = bare.slice(colon + 1);
93763
+ throw new UsageError(`The \`${head}:\` ref spelling was removed in 0.9.0 \u2014 use the slash form instead: \`${replacement}${name}\`.`, "INVALID_FLAG_VALUE");
93764
+ }
93765
+ function findEnvSource(origin, type, name) {
93766
+ const sources = resolveSourceEntries(undefined, loadConfig());
93767
+ if (sources.length === 0) {
93768
+ throw new UsageError("No bundles configured. Run `akm bundle create` to create your working bundle.");
93769
+ }
93770
+ const candidates = origin ? resolveSourcesForOrigin(origin, sources) : sources;
93771
+ const typeDir = type === "env" ? "env" : "secrets";
93772
+ const member = candidates.find((source) => fs43.existsSync(assetPathForName(type, path54.join(source.path, typeDir), name)));
93773
+ if (member)
93774
+ return member;
93775
+ if (!origin) {
93776
+ const fallback = candidates[0];
93777
+ if (fallback)
93778
+ return fallback;
93779
+ throw new UsageError("No bundles configured. Run `akm bundle create` to create your working bundle.");
93780
+ }
93781
+ const named = candidates[0];
93782
+ if (!named) {
93783
+ throw new NotFoundError(`Source not found for origin: ${origin}`);
93784
+ }
93785
+ return named;
93786
+ }
93787
+ function parseSecretRef(ref) {
93788
+ assertNotRemovedVaultRef(ref);
93789
+ assertNotColonRef(ref, ["secret", "secrets"], "secrets/");
93790
+ return parseRefInput(isFullRefInput(ref) ? ref : `secrets/${ref}`);
93791
+ }
93792
+ function resolveSecretPath(ref, create) {
93793
+ const parsed = parseSecretRef(ref);
93794
+ if (parsed.type !== "secret") {
93795
+ throw new UsageError(`Expected a secret ref (secrets/<name>); got "${ref}".`);
93796
+ }
93797
+ if (create) {
93798
+ assertFlatAssetName(parsed.name);
93799
+ parsed.name = combineCreatePath(normalizeCreateSubPath(create.subPath), parsed.name);
93800
+ }
93801
+ const source = findEnvSource(parsed.origin, "secret", parsed.name);
93802
+ const typeRoot = path54.join(source.path, "secrets");
93803
+ const absPath = assetPathForName("secret", typeRoot, parsed.name);
93804
+ if (!isWithin(absPath, typeRoot)) {
93805
+ throw new UsageError(`Secret name "${parsed.name}" escapes the secrets directory.`);
93806
+ }
93807
+ return { name: parsed.name, absPath, source };
93808
+ }
93809
+
93810
+ // src/sources/snapshot-fetchers/secret-seam.ts
93811
+ function resolveSecretFromStore(ref) {
93812
+ try {
93813
+ const { absPath } = resolveSecretPath(ref);
93814
+ if (!fs45.existsSync(absPath))
93815
+ return null;
93816
+ return fs45.readFileSync(absPath, "utf8").trim() || null;
93817
+ } catch {
93818
+ return null;
93819
+ }
93820
+ }
93821
+
93822
+ // src/llm/embedders/remote.ts
93672
93823
  var DEFAULT_REMOTE_BATCH_SIZE = 100;
93673
93824
  var DEFAULT_TOKEN_BUDGET = 8000;
93674
93825
  function estimateTokenCount(text) {
@@ -93824,14 +93975,14 @@ class RemoteEmbedder {
93824
93975
  }
93825
93976
  buildHeaders() {
93826
93977
  const headers = { "Content-Type": "application/json" };
93827
- const resolvedKey = resolveSecret(this.config.apiKey);
93978
+ const resolvedKey = resolveSecret(this.config.apiKey, resolveSecretFromStore);
93828
93979
  if (resolvedKey) {
93829
93980
  headers.Authorization = `Bearer ${resolvedKey}`;
93830
93981
  }
93831
93982
  return headers;
93832
93983
  }
93833
93984
  safeErrorBody(body) {
93834
- const resolvedKey = resolveSecret(this.config.apiKey);
93985
+ const resolvedKey = resolveSecret(this.config.apiKey, resolveSecretFromStore);
93835
93986
  return redactSensitiveText(redactErrorBody(body), resolvedKey ? [resolvedKey] : []);
93836
93987
  }
93837
93988
  }
@@ -94067,7 +94218,7 @@ function publishTargetedEmbeddingMeta(db, config) {
94067
94218
  }
94068
94219
 
94069
94220
  // src/indexer/scan/drain-dir.ts
94070
- import path57 from "path";
94221
+ import path58 from "path";
94071
94222
  init_common();
94072
94223
  init_recognition_util();
94073
94224
 
@@ -94076,8 +94227,8 @@ init_common();
94076
94227
  init_errors();
94077
94228
  init_recognition_util();
94078
94229
  init_warn();
94079
- import fs43 from "fs";
94080
- import path54 from "path";
94230
+ import fs46 from "fs";
94231
+ import path55 from "path";
94081
94232
 
94082
94233
  class WorkflowSourceRejectionError extends UsageError {
94083
94234
  sourcePaths;
@@ -94117,13 +94268,13 @@ class WorkflowSourcePathIdentityError extends WorkflowSourceRejectionError {
94117
94268
  function workflowNameForSourcePath(sourceRoot, adapterId, sourcePath) {
94118
94269
  if (adapterId !== "akm" && adapterId !== "akm-workflow")
94119
94270
  return;
94120
- const relativePath = toPosix(path54.relative(path54.resolve(sourceRoot), path54.resolve(sourcePath)));
94271
+ const relativePath = toPosix(path55.relative(path55.resolve(sourceRoot), path55.resolve(sourcePath)));
94121
94272
  if (!isSafeRelativeName(relativePath))
94122
94273
  return;
94123
94274
  const ownedPath = adapterId === "akm" ? relativePath.replace(/^workflows\//, "") : relativePath;
94124
94275
  if (adapterId === "akm" && ownedPath === relativePath)
94125
94276
  return;
94126
- const extension = path54.posix.extname(ownedPath);
94277
+ const extension = path55.posix.extname(ownedPath);
94127
94278
  if (!WORKFLOW_EXTENSIONS.includes(extension.toLowerCase()))
94128
94279
  return;
94129
94280
  return ownedPath;
@@ -94136,38 +94287,38 @@ function listWorkflowSourceFiles(sourceRoot, adapterId, name) {
94136
94287
  throw new UsageError("Workflow ref resolves outside the bundle root.", "PATH_ESCAPE_VIOLATION");
94137
94288
  }
94138
94289
  let realRoot;
94139
- const authoredRoot = path54.resolve(sourceRoot);
94290
+ const authoredRoot = path55.resolve(sourceRoot);
94140
94291
  try {
94141
- realRoot = fs43.realpathSync(authoredRoot);
94292
+ realRoot = fs46.realpathSync(authoredRoot);
94142
94293
  } catch {
94143
94294
  return [];
94144
94295
  }
94145
- const ownershipRoot = adapterId === "akm" ? path54.join(authoredRoot, "workflows") : authoredRoot;
94146
- const parent = path54.join(ownershipRoot, path54.dirname(canonicalName));
94296
+ const ownershipRoot = adapterId === "akm" ? path55.join(authoredRoot, "workflows") : authoredRoot;
94297
+ const parent = path55.join(ownershipRoot, path55.dirname(canonicalName));
94147
94298
  if (!isWithinResolved(parent, authoredRoot)) {
94148
94299
  throw new UsageError("Workflow ref resolves outside the bundle root.", "PATH_ESCAPE_VIOLATION");
94149
94300
  }
94150
94301
  let entries;
94151
94302
  try {
94152
- entries = fs43.readdirSync(parent, { withFileTypes: true });
94303
+ entries = fs46.readdirSync(parent, { withFileTypes: true });
94153
94304
  } catch {
94154
94305
  return [];
94155
94306
  }
94156
- const basename = path54.basename(canonicalName);
94307
+ const basename = path55.basename(canonicalName);
94157
94308
  const candidates = [];
94158
94309
  for (const entry of entries) {
94159
94310
  if (!entry.isFile() && !entry.isSymbolicLink())
94160
94311
  continue;
94161
- const extension = path54.extname(entry.name);
94312
+ const extension = path55.extname(entry.name);
94162
94313
  const lowerExtension = extension.toLowerCase();
94163
94314
  if (!WORKFLOW_EXTENSIONS.includes(lowerExtension))
94164
94315
  continue;
94165
94316
  if (entry.name.slice(0, -extension.length) !== basename)
94166
94317
  continue;
94167
- const candidatePath = path54.join(parent, entry.name);
94318
+ const candidatePath = path55.join(parent, entry.name);
94168
94319
  candidates.push({
94169
94320
  path: candidatePath,
94170
- relativePath: toPosix(path54.relative(authoredRoot, candidatePath)),
94321
+ relativePath: toPosix(path55.relative(authoredRoot, candidatePath)),
94171
94322
  lowerExtension,
94172
94323
  extensionlessStem: entry.name.slice(0, -extension.length)
94173
94324
  });
@@ -94202,7 +94353,7 @@ function inspectWorkflowSourceCandidate(candidate, canonicalName, realRoot) {
94202
94353
  const issues = [];
94203
94354
  let authoredStat;
94204
94355
  try {
94205
- authoredStat = fs43.lstatSync(candidate.path);
94356
+ authoredStat = fs46.lstatSync(candidate.path);
94206
94357
  } catch {
94207
94358
  issues.push(new WorkflowSourceLinkResolutionError(candidate.relativePath));
94208
94359
  return { issues };
@@ -94214,21 +94365,21 @@ function inspectWorkflowSourceCandidate(candidate, canonicalName, realRoot) {
94214
94365
  }
94215
94366
  let realPath;
94216
94367
  try {
94217
- realPath = fs43.realpathSync(candidate.path);
94368
+ realPath = fs46.realpathSync(candidate.path);
94218
94369
  } catch {
94219
94370
  issues.push(new WorkflowSourceLinkResolutionError(candidate.relativePath));
94220
94371
  return { issues };
94221
94372
  }
94222
- const targetPath = toPosix(path54.relative(realRoot, realPath));
94373
+ const targetPath = toPosix(path55.relative(realRoot, realPath));
94223
94374
  const contained2 = isWithinResolved(realPath, realRoot);
94224
94375
  if (!contained2)
94225
94376
  issues.push(new WorkflowSourcePathIdentityError(candidate.relativePath, targetPath));
94226
- if (isLink && path54.extname(realPath).toLowerCase() !== candidate.lowerExtension) {
94377
+ if (isLink && path55.extname(realPath).toLowerCase() !== candidate.lowerExtension) {
94227
94378
  issues.push(new WorkflowSourceLinkIdentityError(candidate.relativePath, targetPath));
94228
94379
  }
94229
94380
  if (contained2) {
94230
94381
  try {
94231
- if (!fs43.statSync(realPath).isFile())
94382
+ if (!fs46.statSync(realPath).isFile())
94232
94383
  issues.push(new WorkflowSourceLinkResolutionError(candidate.relativePath));
94233
94384
  } catch {
94234
94385
  issues.push(new WorkflowSourceLinkResolutionError(candidate.relativePath));
@@ -94256,11 +94407,11 @@ function normalizeName2(name) {
94256
94407
  return name.replaceAll("\\", "/");
94257
94408
  }
94258
94409
  function isSafeRelativeName(name) {
94259
- return name.length > 0 && !path54.posix.isAbsolute(name) && name !== ".." && !name.startsWith("../") && path54.posix.normalize(name) === name;
94410
+ return name.length > 0 && !path55.posix.isAbsolute(name) && name !== ".." && !name.startsWith("../") && path55.posix.normalize(name) === name;
94260
94411
  }
94261
94412
  function isWithinResolved(candidate, root2) {
94262
- const relative = path54.relative(root2, path54.resolve(candidate));
94263
- return relative === "" || !relative.startsWith("..") && !path54.isAbsolute(relative);
94413
+ const relative = path55.relative(root2, path55.resolve(candidate));
94414
+ return relative === "" || !relative.startsWith("..") && !path55.isAbsolute(relative);
94264
94415
  }
94265
94416
 
94266
94417
  // src/indexer/scan/drain-dir.ts
@@ -94269,13 +94420,13 @@ init_metadata();
94269
94420
  init_file_context();
94270
94421
 
94271
94422
  // src/indexer/scan/doc-to-entry.ts
94272
- import path56 from "path";
94423
+ import path57 from "path";
94273
94424
  function indexDocumentToStashEntry(doc) {
94274
94425
  const dj = doc.documentJson ?? {};
94275
94426
  const entry = {
94276
94427
  name: doc.name,
94277
94428
  type: doc.type,
94278
- filename: path56.basename(doc.path ?? "")
94429
+ filename: path57.basename(doc.path ?? "")
94279
94430
  };
94280
94431
  if (doc.description !== undefined)
94281
94432
  entry.description = doc.description;
@@ -94395,7 +94546,7 @@ function drainDirDocuments(adapter, component, fileContexts) {
94395
94546
  throw error2;
94396
94547
  rejectedConceptIds.add(adapter.id === "akm" ? `workflows/${canonicalName}` : canonicalName);
94397
94548
  for (const relativePath of error2.sourcePaths) {
94398
- rejectedPaths.add(path57.join(component.root, relativePath));
94549
+ rejectedPaths.add(path58.join(component.root, relativePath));
94399
94550
  }
94400
94551
  warnings.push(error2.message);
94401
94552
  }
@@ -94457,7 +94608,7 @@ async function indexWrittenAssets(stashDir, filePaths, options = {}) {
94457
94608
  if (isPathAbsent(dbPath))
94458
94609
  return true;
94459
94610
  const files = filePaths.filter((f) => {
94460
- const rel = path58.relative(stashDir, f);
94611
+ const rel = path59.relative(stashDir, f);
94461
94612
  return !rel.split(/[\\/]+/).some((segment) => segment.startsWith("."));
94462
94613
  });
94463
94614
  if (files.length === 0)
@@ -94471,10 +94622,10 @@ async function indexWrittenAssets(stashDir, filePaths, options = {}) {
94471
94622
  const unindexable = new Set;
94472
94623
  const rejectedConceptIds = new Set;
94473
94624
  for (const file of files) {
94474
- if (!fs46.existsSync(file)) {
94625
+ if (!fs48.existsSync(file)) {
94475
94626
  let authoredDanglingSymlink = false;
94476
94627
  try {
94477
- authoredDanglingSymlink = fs46.lstatSync(file).isSymbolicLink();
94628
+ authoredDanglingSymlink = fs48.lstatSync(file).isSymbolicLink();
94478
94629
  } catch {}
94479
94630
  if (!authoredDanglingSymlink) {
94480
94631
  unindexable.add(file);
@@ -94525,7 +94676,7 @@ async function indexWrittenAssets(stashDir, filePaths, options = {}) {
94525
94676
  for (const { file, entry, conceptId, contentHash } of pairs) {
94526
94677
  let entryWithSize = entry;
94527
94678
  try {
94528
- entryWithSize = { ...entry, fileSize: fs46.statSync(file).size };
94679
+ entryWithSize = { ...entry, fileSize: fs48.statSync(file).size };
94529
94680
  } catch {}
94530
94681
  const provenance = deriveEntryProvenance({ bundleId: component.id, componentId: component.id, adapterId: component.adapter }, entry.type, entry.name, conceptId);
94531
94682
  const supersededIds = db.prepare("SELECT id FROM entries WHERE file_path = ? AND item_ref <> ?").all(file, provenance.itemRef);
@@ -94558,7 +94709,7 @@ async function indexWrittenAssets(stashDir, filePaths, options = {}) {
94558
94709
  init_asset_placement();
94559
94710
  init_asset_ref();
94560
94711
  init_warn();
94561
- import path59 from "path";
94712
+ import path60 from "path";
94562
94713
  function changesToStored(changes) {
94563
94714
  return changes.map((c, i) => ({
94564
94715
  path: c.path,
@@ -94611,10 +94762,10 @@ function currentProposalTarget(value) {
94611
94762
  if (typeof value !== "object" || value === null)
94612
94763
  throw new Error("Proposal metadata has an invalid proposedTarget.");
94613
94764
  const target = value;
94614
- if (typeof target.source !== "string" || !isBundleSlug(target.source) || typeof target.root !== "string" || !path59.isAbsolute(target.root)) {
94765
+ if (typeof target.source !== "string" || !isBundleSlug(target.source) || typeof target.root !== "string" || !path60.isAbsolute(target.root)) {
94615
94766
  throw new Error("Proposal metadata has an invalid proposedTarget.");
94616
94767
  }
94617
- return { source: target.source, root: path59.resolve(target.root) };
94768
+ return { source: target.source, root: path60.resolve(target.root) };
94618
94769
  }
94619
94770
  function invalidPresentField(name) {
94620
94771
  throw new Error(`Proposal metadata has an invalid ${name}.`);
@@ -94654,7 +94805,7 @@ function validatePresentMetadata(meta) {
94654
94805
  }
94655
94806
  if (Object.hasOwn(meta, "acceptedTarget")) {
94656
94807
  const target = meta.acceptedTarget;
94657
- 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") {
94808
+ 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") {
94658
94809
  invalidPresentField("acceptedTarget");
94659
94810
  }
94660
94811
  }
@@ -95388,12 +95539,12 @@ function proposalHash(content) {
95388
95539
  return createHash9("sha256").update(content).digest("hex");
95389
95540
  }
95390
95541
  function proposalFileHash(filePath) {
95391
- return proposalHash(fs47.readFileSync(filePath));
95542
+ return proposalHash(fs49.readFileSync(filePath));
95392
95543
  }
95393
95544
  function sameProposalFile(left, right) {
95394
95545
  try {
95395
- const leftStat = fs47.statSync(left);
95396
- const rightStat = fs47.statSync(right);
95546
+ const leftStat = fs49.statSync(left);
95547
+ const rightStat = fs49.statSync(right);
95397
95548
  return leftStat.dev === rightStat.dev && leftStat.ino === rightStat.ino;
95398
95549
  } catch {
95399
95550
  return false;
@@ -95402,20 +95553,20 @@ function sameProposalFile(left, right) {
95402
95553
  function cleanupProposalPublication(p) {
95403
95554
  for (const filePath of [p.publishPath, p.displacedPath]) {
95404
95555
  try {
95405
- fs47.rmSync(filePath, { force: true });
95556
+ fs49.rmSync(filePath, { force: true });
95406
95557
  } catch (error2) {
95407
95558
  warn(`[proposals] transaction publication cleanup failed at ${filePath}: ${error2 instanceof Error ? error2.message : String(error2)}`);
95408
95559
  }
95409
95560
  }
95410
- fsyncTxnDir(path60.dirname(p.assetPath));
95561
+ fsyncTxnDir(path61.dirname(p.assetPath));
95411
95562
  }
95412
95563
  function rollbackPreparedProposalTransaction(txn) {
95413
95564
  const p = txn.journal.payload;
95414
- const currentHash = fs47.existsSync(p.assetPath) ? proposalFileHash(p.assetPath) : null;
95415
- if (!fs47.existsSync(p.displacedPath)) {
95565
+ const currentHash = fs49.existsSync(p.assetPath) ? proposalFileHash(p.assetPath) : null;
95566
+ if (!fs49.existsSync(p.displacedPath)) {
95416
95567
  if (p.originalHash === null) {
95417
95568
  if (currentHash === p.publishedHash && sameProposalFile(p.assetPath, p.publishPath)) {
95418
- fs47.unlinkSync(p.assetPath);
95569
+ fs49.unlinkSync(p.assetPath);
95419
95570
  recordWrittenPath(p.assetPath);
95420
95571
  } else if (currentHash !== null) {
95421
95572
  throw new Error(`Cannot roll back proposal transaction: target was created externally.`);
@@ -95427,30 +95578,30 @@ function rollbackPreparedProposalTransaction(txn) {
95427
95578
  return;
95428
95579
  }
95429
95580
  if (currentHash === p.publishedHash) {
95430
- fs47.unlinkSync(p.assetPath);
95581
+ fs49.unlinkSync(p.assetPath);
95431
95582
  recordWrittenPath(p.assetPath);
95432
95583
  } else if (currentHash !== null && currentHash !== p.originalHash) {
95433
95584
  throw new Error(`Cannot roll back proposal transaction: ${p.assetPath} diverged.`);
95434
95585
  }
95435
- if (fs47.existsSync(p.displacedPath)) {
95436
- if (fs47.existsSync(p.assetPath)) {
95586
+ if (fs49.existsSync(p.displacedPath)) {
95587
+ if (fs49.existsSync(p.assetPath)) {
95437
95588
  throw new Error(`Cannot restore proposal backup: ${p.assetPath} is occupied.`);
95438
95589
  }
95439
- fs47.linkSync(p.displacedPath, p.assetPath);
95590
+ fs49.linkSync(p.displacedPath, p.assetPath);
95440
95591
  recordWrittenPath(p.assetPath);
95441
95592
  }
95442
95593
  cleanupProposalPublication(p);
95443
95594
  }
95444
95595
  function validatePublishedProposal(p) {
95445
- if (!fs47.existsSync(p.assetPath) || proposalFileHash(p.assetPath) !== p.publishedHash) {
95596
+ if (!fs49.existsSync(p.assetPath) || proposalFileHash(p.assetPath) !== p.publishedHash) {
95446
95597
  throw new Error(`Cannot recover proposal ${p.proposalId}: published asset diverged.`);
95447
95598
  }
95448
95599
  }
95449
95600
  function persistProposalTransactionState(txn, proposal, ctx) {
95450
95601
  const p = txn.journal.payload;
95451
95602
  const decidedAt = txn.journal.decidedAt;
95452
- const backupContent = p.backupPath ? fs47.readFileSync(p.backupPath, "utf8") : undefined;
95453
- const publishedContent = fs47.readFileSync(p.contentPath, "utf8");
95603
+ const backupContent = p.backupPath ? fs49.readFileSync(p.backupPath, "utf8") : undefined;
95604
+ const publishedContent = fs49.readFileSync(p.contentPath, "utf8");
95454
95605
  return withProposalsDb(p.stashDir, ctx, (db) => withImmediateTransaction(db, () => {
95455
95606
  const current = requireProposal(db, p.stashDir, p.proposalId);
95456
95607
  if (p.operation === "accept") {
@@ -95468,7 +95619,7 @@ function persistProposalTransactionState(txn, proposal, ctx) {
95468
95619
  payload: { ...proposal.payload, content: publishedContent },
95469
95620
  changes: [
95470
95621
  {
95471
- path: path60.relative(txn.journal.root, p.assetPath),
95622
+ path: path61.relative(txn.journal.root, p.assetPath),
95472
95623
  op: p.originalHash === null ? "create" : "update",
95473
95624
  after: publishedContent
95474
95625
  }
@@ -95539,7 +95690,7 @@ async function finalizeProposalTransaction(txn, target, proposal, ctx) {
95539
95690
  cleanupProposalPublication(p);
95540
95691
  if (txn.journal.phase === "asset-published") {
95541
95692
  const commitRoot = target.source.repoPath ?? target.source.path;
95542
- const commitPath = path60.relative(commitRoot, p.assetPath).replaceAll(path60.sep, "/");
95693
+ const commitPath = path61.relative(commitRoot, p.assetPath).replaceAll(path61.sep, "/");
95543
95694
  publishWriteTargetTransaction(target, p.gitPublication, {
95544
95695
  transactionId: txn.journal.transactionId,
95545
95696
  message: `${p.operation === "accept" ? "Update" : "Revert"} ${p.ref}`,
@@ -95576,8 +95727,8 @@ async function finalizeProposalTransaction(txn, target, proposal, ctx) {
95576
95727
  function fenceProposalTxnJournal(journal, txnDir, root2) {
95577
95728
  const p = journal.payload;
95578
95729
  const refIdentity = proposalRefIdentity(p.ref);
95579
- if (!["accept", "revert"].includes(p.operation) || !p.targetSource || !p.targetKind || refIdentity?.bundle === undefined || !isWithin(p.assetPath, root2) || ![p.contentPath, p.backupPath].filter((candidate) => candidate !== null).every((candidate) => isWithin(candidate, txnDir)) || ![p.publishPath, p.displacedPath].every((candidate) => isWithin(candidate, root2) && path60.dirname(candidate) === path60.dirname(p.assetPath))) {
95580
- throw new Error(`Refusing unsafe proposal transaction journal at ${path60.join(txnDir, "journal.json")}.`);
95730
+ if (!["accept", "revert"].includes(p.operation) || !p.targetSource || !p.targetKind || refIdentity?.bundle === undefined || !isWithin(p.assetPath, root2) || ![p.contentPath, p.backupPath].filter((candidate) => candidate !== null).every((candidate) => isWithin(candidate, txnDir)) || ![p.publishPath, p.displacedPath].every((candidate) => isWithin(candidate, root2) && path61.dirname(candidate) === path61.dirname(p.assetPath))) {
95731
+ throw new Error(`Refusing unsafe proposal transaction journal at ${path61.join(txnDir, "journal.json")}.`);
95581
95732
  }
95582
95733
  }
95583
95734
  function resolveProposalRecoveryTarget(config, journal) {
@@ -95677,8 +95828,8 @@ async function recoverStaleTxns(stashDir) {
95677
95828
  }
95678
95829
 
95679
95830
  // scripts/akm-migrate/migrate/writer-relocation.ts
95680
- import fs48 from "fs";
95681
- import path61 from "path";
95831
+ import fs50 from "fs";
95832
+ import path62 from "path";
95682
95833
  init_paths();
95683
95834
  function relocationSpecs(stashDir) {
95684
95835
  return [
@@ -95698,7 +95849,7 @@ function mutexSiblingName(lockName) {
95698
95849
  function fileCountIfExists(dir) {
95699
95850
  let entries;
95700
95851
  try {
95701
- entries = fs48.readdirSync(dir, { withFileTypes: true });
95852
+ entries = fs50.readdirSync(dir, { withFileTypes: true });
95702
95853
  } catch {
95703
95854
  return;
95704
95855
  }
@@ -95706,7 +95857,7 @@ function fileCountIfExists(dir) {
95706
95857
  }
95707
95858
  function statFileIfExists(filePath) {
95708
95859
  try {
95709
- const stat = fs48.statSync(filePath);
95860
+ const stat = fs50.statSync(filePath);
95710
95861
  return stat.isFile() ? stat : undefined;
95711
95862
  } catch {
95712
95863
  return;
@@ -95716,8 +95867,8 @@ function classifyLockArtifacts(akmDir) {
95716
95867
  const removable = [];
95717
95868
  const skipped = [];
95718
95869
  for (const lockName of LOCK_NAMES) {
95719
- const lockPath = path61.join(akmDir, lockName);
95720
- const mutexPath = path61.join(akmDir, mutexSiblingName(lockName));
95870
+ const lockPath = path62.join(akmDir, lockName);
95871
+ const mutexPath = path62.join(akmDir, mutexSiblingName(lockName));
95721
95872
  const lockStat = statFileIfExists(lockPath);
95722
95873
  const mutexStat = statFileIfExists(mutexPath);
95723
95874
  if (!lockStat) {
@@ -95743,11 +95894,11 @@ function classifyLockArtifacts(akmDir) {
95743
95894
  return { removable, skipped };
95744
95895
  }
95745
95896
  function findWriterRelocationEntries(stashDir) {
95746
- const akmDir = path61.join(stashDir, ".akm");
95897
+ const akmDir = path62.join(stashDir, ".akm");
95747
95898
  const directories = [];
95748
95899
  for (const spec of relocationSpecs(stashDir)) {
95749
95900
  const relativeParts = Array.isArray(spec.oldRelative) ? spec.oldRelative : [spec.oldRelative];
95750
- const oldPath = path61.join(akmDir, ...relativeParts);
95901
+ const oldPath = path62.join(akmDir, ...relativeParts);
95751
95902
  const fileCount = fileCountIfExists(oldPath);
95752
95903
  if (fileCount === undefined || fileCount === 0)
95753
95904
  continue;
@@ -95758,36 +95909,36 @@ function findWriterRelocationEntries(stashDir) {
95758
95909
  }
95759
95910
  function moveFile(oldFilePath, newFilePath) {
95760
95911
  try {
95761
- fs48.renameSync(oldFilePath, newFilePath);
95912
+ fs50.renameSync(oldFilePath, newFilePath);
95762
95913
  } catch (error2) {
95763
95914
  if (error2.code !== "EXDEV")
95764
95915
  throw error2;
95765
- fs48.copyFileSync(oldFilePath, newFilePath);
95766
- fs48.rmSync(oldFilePath, { force: true });
95916
+ fs50.copyFileSync(oldFilePath, newFilePath);
95917
+ fs50.rmSync(oldFilePath, { force: true });
95767
95918
  }
95768
95919
  }
95769
95920
  function moveDirectoryContents(entry) {
95770
95921
  const errors3 = [];
95771
95922
  let moved = 0;
95772
- fs48.mkdirSync(entry.newPath, { recursive: true });
95923
+ fs50.mkdirSync(entry.newPath, { recursive: true });
95773
95924
  let names;
95774
95925
  try {
95775
- names = fs48.readdirSync(entry.oldPath).sort();
95926
+ names = fs50.readdirSync(entry.oldPath).sort();
95776
95927
  } catch {
95777
95928
  return { key: entry.key, oldPath: entry.oldPath, newPath: entry.newPath, moved: 0, errors: [] };
95778
95929
  }
95779
95930
  for (const name of names) {
95780
- const oldFilePath = path61.join(entry.oldPath, name);
95781
- const newFilePath = path61.join(entry.newPath, name);
95931
+ const oldFilePath = path62.join(entry.oldPath, name);
95932
+ const newFilePath = path62.join(entry.newPath, name);
95782
95933
  let oldStat;
95783
95934
  try {
95784
- oldStat = fs48.lstatSync(oldFilePath);
95935
+ oldStat = fs50.lstatSync(oldFilePath);
95785
95936
  } catch {
95786
95937
  continue;
95787
95938
  }
95788
95939
  if (!oldStat.isFile())
95789
95940
  continue;
95790
- if (fs48.existsSync(newFilePath))
95941
+ if (fs50.existsSync(newFilePath))
95791
95942
  continue;
95792
95943
  try {
95793
95944
  moveFile(oldFilePath, newFilePath);
@@ -95800,13 +95951,13 @@ function moveDirectoryContents(entry) {
95800
95951
  }
95801
95952
  function removeIfEmptyDir(dir) {
95802
95953
  try {
95803
- if (fs48.readdirSync(dir).length === 0)
95804
- fs48.rmdirSync(dir);
95954
+ if (fs50.readdirSync(dir).length === 0)
95955
+ fs50.rmdirSync(dir);
95805
95956
  } catch {}
95806
95957
  }
95807
95958
  function removeLockArtifact(entry) {
95808
95959
  try {
95809
- fs48.rmSync(entry.path, { force: true });
95960
+ fs50.rmSync(entry.path, { force: true });
95810
95961
  return { path: entry.path, removed: true };
95811
95962
  } catch (error2) {
95812
95963
  return { path: entry.path, removed: false, error: error2 instanceof Error ? error2.message : String(error2) };
@@ -95818,36 +95969,36 @@ function applyWriterRelocation(stashDir) {
95818
95969
  const lockResults = lockArtifacts.map(removeLockArtifact);
95819
95970
  for (const spec of relocationSpecs(stashDir)) {
95820
95971
  const relativeParts = Array.isArray(spec.oldRelative) ? spec.oldRelative : [spec.oldRelative];
95821
- removeIfEmptyDir(path61.join(stashDir, ".akm", ...relativeParts));
95972
+ removeIfEmptyDir(path62.join(stashDir, ".akm", ...relativeParts));
95822
95973
  }
95823
95974
  return { directories: directoryResults, lockArtifacts: lockResults, skippedLocks };
95824
95975
  }
95825
95976
 
95826
95977
  // scripts/akm-migrate/task-migrate.ts
95827
95978
  import { randomUUID as randomUUID7 } from "crypto";
95828
- import fs53 from "fs";
95979
+ import fs56 from "fs";
95829
95980
  import os5 from "os";
95830
- import path64 from "path";
95981
+ import path65 from "path";
95831
95982
  init_errors();
95832
95983
  init_paths();
95833
95984
 
95834
95985
  // scripts/akm-migrate/migrate/task-files-to-v3.ts
95835
95986
  init_errors();
95836
95987
  import crypto6 from "crypto";
95837
- import fs50 from "fs";
95838
- import path62 from "path";
95988
+ import fs53 from "fs";
95989
+ import path63 from "path";
95839
95990
 
95840
95991
  // scripts/akm-migrate/migrate/durable-fs.ts
95841
- import fs49 from "fs";
95992
+ import fs51 from "fs";
95842
95993
  function fsyncDirectoryPortable(directory) {
95843
95994
  if (process.platform === "win32")
95844
95995
  return;
95845
95996
  try {
95846
- const fd = fs49.openSync(directory, "r");
95997
+ const fd = fs51.openSync(directory, "r");
95847
95998
  try {
95848
- fs49.fsyncSync(fd);
95999
+ fs51.fsyncSync(fd);
95849
96000
  } finally {
95850
- fs49.closeSync(fd);
96001
+ fs51.closeSync(fd);
95851
96002
  }
95852
96003
  } catch (cause) {
95853
96004
  const code = cause.code;
@@ -95861,25 +96012,25 @@ function migrationError(detail) {
95861
96012
  return new ConfigError(`Task migration to v3 failed: ${detail}`, "INVALID_CONFIG_FILE");
95862
96013
  }
95863
96014
  function contained2(root2, candidate) {
95864
- const relative = path62.relative(root2, candidate);
95865
- return relative === "" || !relative.startsWith("..") && !path62.isAbsolute(relative);
96015
+ const relative = path63.relative(root2, candidate);
96016
+ return relative === "" || !relative.startsWith("..") && !path63.isAbsolute(relative);
95866
96017
  }
95867
96018
  function realDirectory(filePath) {
95868
- const stat = fs50.lstatSync(filePath);
96019
+ const stat = fs53.lstatSync(filePath);
95869
96020
  if (stat.isSymbolicLink() || !stat.isDirectory())
95870
96021
  throw migrationError(`${filePath} must be a real directory.`);
95871
- return fs50.realpathSync(filePath);
96022
+ return fs53.realpathSync(filePath);
95872
96023
  }
95873
96024
  function snapshot(filePath) {
95874
- const stat = fs50.lstatSync(filePath);
96025
+ const stat = fs53.lstatSync(filePath);
95875
96026
  if (stat.isSymbolicLink() || !stat.isFile())
95876
96027
  throw migrationError(`${filePath} must be a real file.`);
95877
- const bytes = fs50.readFileSync(filePath);
96028
+ const bytes = fs53.readFileSync(filePath);
95878
96029
  return Object.freeze({ bytes, mode: stat.mode & 511 });
95879
96030
  }
95880
96031
  function writable(filePath) {
95881
96032
  try {
95882
- fs50.accessSync(filePath, fs50.constants.W_OK);
96033
+ fs53.accessSync(filePath, fs53.constants.W_OK);
95883
96034
  return true;
95884
96035
  } catch {
95885
96036
  return false;
@@ -95892,12 +96043,12 @@ function walkTasks(root2, tasksDir, out) {
95892
96043
  throw migrationError(`${root2.root} resolves outside bundle ${root2.bundleId}.`);
95893
96044
  }
95894
96045
  const visit2 = (directory) => {
95895
- const physicalDirectory = fs50.realpathSync(directory);
96046
+ const physicalDirectory = fs53.realpathSync(directory);
95896
96047
  if (!contained2(physicalRoot, physicalDirectory)) {
95897
96048
  throw migrationError(`${directory} resolves outside bundle ${root2.bundleId}.`);
95898
96049
  }
95899
- for (const entry of fs50.readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
95900
- const candidate = path62.join(directory, entry.name);
96050
+ for (const entry of fs53.readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
96051
+ const candidate = path63.join(directory, entry.name);
95901
96052
  if (entry.isSymbolicLink())
95902
96053
  throw migrationError(`task migration does not follow symbolic link ${candidate}.`);
95903
96054
  if (entry.isDirectory()) {
@@ -95907,7 +96058,7 @@ function walkTasks(root2, tasksDir, out) {
95907
96058
  if (!entry.isFile() || !entry.name.endsWith(".yml"))
95908
96059
  continue;
95909
96060
  const current = snapshot(candidate);
95910
- const parent = path62.dirname(candidate);
96061
+ const parent = path63.dirname(candidate);
95911
96062
  out.push({
95912
96063
  filePath: candidate,
95913
96064
  bytes: current.bytes,
@@ -95923,9 +96074,9 @@ function walkTasks(root2, tasksDir, out) {
95923
96074
  function inspectTaskToV3Files(roots) {
95924
96075
  const files = [];
95925
96076
  for (const root2 of [...roots].sort((a, b) => a.bundleId.localeCompare(b.bundleId))) {
95926
- const tasksDir = root2.layout === "akm-task" ? root2.root : path62.join(root2.root, "tasks");
96077
+ const tasksDir = root2.layout === "akm-task" ? root2.root : path63.join(root2.root, "tasks");
95927
96078
  try {
95928
- const stat = fs50.lstatSync(tasksDir);
96079
+ const stat = fs53.lstatSync(tasksDir);
95929
96080
  if (stat.isSymbolicLink())
95930
96081
  throw migrationError(`task migration does not follow symbolic link ${tasksDir}.`);
95931
96082
  if (!stat.isDirectory())
@@ -95940,33 +96091,33 @@ function inspectTaskToV3Files(roots) {
95940
96091
  return files.sort((a, b) => a.filePath.localeCompare(b.filePath));
95941
96092
  }
95942
96093
  function hashPath(filePath) {
95943
- return crypto6.createHash("sha256").update(path62.resolve(filePath)).digest("hex").slice(0, 16);
96094
+ return crypto6.createHash("sha256").update(path63.resolve(filePath)).digest("hex").slice(0, 16);
95944
96095
  }
95945
96096
  function taskMigrationBackupPath(backupRoot, filePath) {
95946
- return path62.join(backupRoot, "files", `${hashPath(filePath)}-${path62.basename(filePath)}`);
96097
+ return path63.join(backupRoot, "files", `${hashPath(filePath)}-${path63.basename(filePath)}`);
95947
96098
  }
95948
96099
  function writeDurable(filePath, bytes, mode, exclusive = false) {
95949
- fs50.mkdirSync(path62.dirname(filePath), { recursive: true });
96100
+ fs53.mkdirSync(path63.dirname(filePath), { recursive: true });
95950
96101
  const flags = exclusive ? "wx" : "w";
95951
- const fd = fs50.openSync(filePath, flags, mode);
96102
+ const fd = fs53.openSync(filePath, flags, mode);
95952
96103
  try {
95953
- fs50.writeFileSync(fd, bytes);
95954
- fs50.fsyncSync(fd);
96104
+ fs53.writeFileSync(fd, bytes);
96105
+ fs53.fsyncSync(fd);
95955
96106
  } finally {
95956
- fs50.closeSync(fd);
96107
+ fs53.closeSync(fd);
95957
96108
  }
95958
- fs50.chmodSync(filePath, mode);
95959
- fsyncDirectoryPortable(path62.dirname(filePath));
96109
+ fs53.chmodSync(filePath, mode);
96110
+ fsyncDirectoryPortable(path63.dirname(filePath));
95960
96111
  }
95961
96112
  function replaceAtomically(filePath, bytes, mode) {
95962
- const temporary = path62.join(path62.dirname(filePath), `.${path62.basename(filePath)}.migrate-${crypto6.randomUUID()}`);
96113
+ const temporary = path63.join(path63.dirname(filePath), `.${path63.basename(filePath)}.migrate-${crypto6.randomUUID()}`);
95963
96114
  try {
95964
96115
  writeDurable(temporary, bytes, mode, true);
95965
- fs50.renameSync(temporary, filePath);
95966
- fsyncDirectoryPortable(path62.dirname(filePath));
96116
+ fs53.renameSync(temporary, filePath);
96117
+ fsyncDirectoryPortable(path63.dirname(filePath));
95967
96118
  } finally {
95968
96119
  try {
95969
- fs50.unlinkSync(temporary);
96120
+ fs53.unlinkSync(temporary);
95970
96121
  } catch (cause) {
95971
96122
  if (cause.code !== "ENOENT")
95972
96123
  throw cause;
@@ -96005,7 +96156,7 @@ function applyTaskToV3MigrationPlan(plan, options) {
96005
96156
  const current = snapshot(change.filePath);
96006
96157
  if (!current.bytes.equals(change.after))
96007
96158
  continue;
96008
- replaceAtomically(change.filePath, fs50.readFileSync(taskMigrationBackupPath(options.backupRoot, change.filePath)), change.mode);
96159
+ replaceAtomically(change.filePath, fs53.readFileSync(taskMigrationBackupPath(options.backupRoot, change.filePath)), change.mode);
96009
96160
  }
96010
96161
  throw cause;
96011
96162
  }
@@ -96015,31 +96166,31 @@ function applyTaskToV3MigrationPlan(plan, options) {
96015
96166
  // scripts/akm-migrate/migrate/task-files-to-v4.ts
96016
96167
  init_errors();
96017
96168
  import crypto7 from "crypto";
96018
- import fs51 from "fs";
96019
- import path63 from "path";
96169
+ import fs55 from "fs";
96170
+ import path64 from "path";
96020
96171
  function migrationError2(detail) {
96021
96172
  return new ConfigError(`Task migration to v4 failed: ${detail}`, "INVALID_CONFIG_FILE");
96022
96173
  }
96023
96174
  function contained3(root2, candidate) {
96024
- const relative = path63.relative(root2, candidate);
96025
- return relative === "" || !relative.startsWith("..") && !path63.isAbsolute(relative);
96175
+ const relative = path64.relative(root2, candidate);
96176
+ return relative === "" || !relative.startsWith("..") && !path64.isAbsolute(relative);
96026
96177
  }
96027
96178
  function realDirectory2(filePath) {
96028
- const stat = fs51.lstatSync(filePath);
96179
+ const stat = fs55.lstatSync(filePath);
96029
96180
  if (stat.isSymbolicLink() || !stat.isDirectory())
96030
96181
  throw migrationError2(`${filePath} must be a real directory.`);
96031
- return fs51.realpathSync(filePath);
96182
+ return fs55.realpathSync(filePath);
96032
96183
  }
96033
96184
  function snapshot2(filePath) {
96034
- const stat = fs51.lstatSync(filePath);
96185
+ const stat = fs55.lstatSync(filePath);
96035
96186
  if (stat.isSymbolicLink() || !stat.isFile())
96036
96187
  throw migrationError2(`${filePath} must be a real file.`);
96037
- const bytes = fs51.readFileSync(filePath);
96188
+ const bytes = fs55.readFileSync(filePath);
96038
96189
  return Object.freeze({ bytes, mode: stat.mode & 511 });
96039
96190
  }
96040
96191
  function writable2(filePath) {
96041
96192
  try {
96042
- fs51.accessSync(filePath, fs51.constants.W_OK);
96193
+ fs55.accessSync(filePath, fs55.constants.W_OK);
96043
96194
  return true;
96044
96195
  } catch {
96045
96196
  return false;
@@ -96052,12 +96203,12 @@ function walkTasks2(root2, tasksDir, out) {
96052
96203
  throw migrationError2(`${root2.root} resolves outside bundle ${root2.bundleId}.`);
96053
96204
  }
96054
96205
  const visit2 = (directory) => {
96055
- const physicalDirectory = fs51.realpathSync(directory);
96206
+ const physicalDirectory = fs55.realpathSync(directory);
96056
96207
  if (!contained3(physicalRoot, physicalDirectory)) {
96057
96208
  throw migrationError2(`${directory} resolves outside bundle ${root2.bundleId}.`);
96058
96209
  }
96059
- for (const entry of fs51.readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
96060
- const candidate = path63.join(directory, entry.name);
96210
+ for (const entry of fs55.readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
96211
+ const candidate = path64.join(directory, entry.name);
96061
96212
  if (entry.isSymbolicLink())
96062
96213
  throw migrationError2(`task migration does not follow symbolic link ${candidate}.`);
96063
96214
  if (entry.isDirectory()) {
@@ -96067,7 +96218,7 @@ function walkTasks2(root2, tasksDir, out) {
96067
96218
  if (!entry.isFile() || !entry.name.endsWith(".yml"))
96068
96219
  continue;
96069
96220
  const current = snapshot2(candidate);
96070
- const parent = path63.dirname(candidate);
96221
+ const parent = path64.dirname(candidate);
96071
96222
  out.push({
96072
96223
  filePath: candidate,
96073
96224
  bytes: current.bytes,
@@ -96083,9 +96234,9 @@ function walkTasks2(root2, tasksDir, out) {
96083
96234
  function inspectTaskToV4Files(roots) {
96084
96235
  const files = [];
96085
96236
  for (const root2 of [...roots].sort((a, b) => a.bundleId.localeCompare(b.bundleId))) {
96086
- const tasksDir = root2.layout === "akm-task" ? root2.root : path63.join(root2.root, "tasks");
96237
+ const tasksDir = root2.layout === "akm-task" ? root2.root : path64.join(root2.root, "tasks");
96087
96238
  try {
96088
- const stat = fs51.lstatSync(tasksDir);
96239
+ const stat = fs55.lstatSync(tasksDir);
96089
96240
  if (stat.isSymbolicLink())
96090
96241
  throw migrationError2(`task migration does not follow symbolic link ${tasksDir}.`);
96091
96242
  if (!stat.isDirectory())
@@ -96100,33 +96251,33 @@ function inspectTaskToV4Files(roots) {
96100
96251
  return files.sort((a, b) => a.filePath.localeCompare(b.filePath));
96101
96252
  }
96102
96253
  function hashPath2(filePath) {
96103
- return crypto7.createHash("sha256").update(path63.resolve(filePath)).digest("hex").slice(0, 16);
96254
+ return crypto7.createHash("sha256").update(path64.resolve(filePath)).digest("hex").slice(0, 16);
96104
96255
  }
96105
96256
  function taskMigrationBackupPathV4(backupRoot, filePath) {
96106
- return path63.join(backupRoot, "files", `${hashPath2(filePath)}-${path63.basename(filePath)}`);
96257
+ return path64.join(backupRoot, "files", `${hashPath2(filePath)}-${path64.basename(filePath)}`);
96107
96258
  }
96108
96259
  function writeDurable2(filePath, bytes, mode, exclusive = false) {
96109
- fs51.mkdirSync(path63.dirname(filePath), { recursive: true });
96260
+ fs55.mkdirSync(path64.dirname(filePath), { recursive: true });
96110
96261
  const flags = exclusive ? "wx" : "w";
96111
- const fd = fs51.openSync(filePath, flags, mode);
96262
+ const fd = fs55.openSync(filePath, flags, mode);
96112
96263
  try {
96113
- fs51.writeFileSync(fd, bytes);
96114
- fs51.fsyncSync(fd);
96264
+ fs55.writeFileSync(fd, bytes);
96265
+ fs55.fsyncSync(fd);
96115
96266
  } finally {
96116
- fs51.closeSync(fd);
96267
+ fs55.closeSync(fd);
96117
96268
  }
96118
- fs51.chmodSync(filePath, mode);
96119
- fsyncDirectoryPortable(path63.dirname(filePath));
96269
+ fs55.chmodSync(filePath, mode);
96270
+ fsyncDirectoryPortable(path64.dirname(filePath));
96120
96271
  }
96121
96272
  function replaceAtomically2(filePath, bytes, mode) {
96122
- const temporary = path63.join(path63.dirname(filePath), `.${path63.basename(filePath)}.migrate-${crypto7.randomUUID()}`);
96273
+ const temporary = path64.join(path64.dirname(filePath), `.${path64.basename(filePath)}.migrate-${crypto7.randomUUID()}`);
96123
96274
  try {
96124
96275
  writeDurable2(temporary, bytes, mode, true);
96125
- fs51.renameSync(temporary, filePath);
96126
- fsyncDirectoryPortable(path63.dirname(filePath));
96276
+ fs55.renameSync(temporary, filePath);
96277
+ fsyncDirectoryPortable(path64.dirname(filePath));
96127
96278
  } finally {
96128
96279
  try {
96129
- fs51.unlinkSync(temporary);
96280
+ fs55.unlinkSync(temporary);
96130
96281
  } catch (cause) {
96131
96282
  if (cause.code !== "ENOENT")
96132
96283
  throw cause;
@@ -96165,7 +96316,7 @@ function applyTaskToV4MigrationPlan(plan, options) {
96165
96316
  const current = snapshot2(change.filePath);
96166
96317
  if (!current.bytes.equals(change.after))
96167
96318
  continue;
96168
- replaceAtomically2(change.filePath, fs51.readFileSync(taskMigrationBackupPathV4(options.backupRoot, change.filePath)), change.mode);
96319
+ replaceAtomically2(change.filePath, fs55.readFileSync(taskMigrationBackupPathV4(options.backupRoot, change.filePath)), change.mode);
96169
96320
  }
96170
96321
  throw cause;
96171
96322
  }
@@ -96177,12 +96328,12 @@ function expandTilde(value) {
96177
96328
  if (value === "~")
96178
96329
  return os5.homedir();
96179
96330
  if (value.startsWith("~/") || value.startsWith("~\\"))
96180
- return path64.join(os5.homedir(), value.slice(2));
96331
+ return path65.join(os5.homedir(), value.slice(2));
96181
96332
  return value;
96182
96333
  }
96183
96334
  function existingDirectory(target) {
96184
96335
  try {
96185
- return fs53.statSync(target).isDirectory();
96336
+ return fs56.statSync(target).isDirectory();
96186
96337
  } catch (cause) {
96187
96338
  if (cause.code === "ENOENT")
96188
96339
  return false;
@@ -96203,21 +96354,21 @@ function taskRoots(config, resolutionBase = process.cwd()) {
96203
96354
  const source = sources.get(bundleId);
96204
96355
  if (!source)
96205
96356
  continue;
96206
- const configuredRoot = source.type === "filesystem" && source.path ? path64.resolve(resolutionBase, expandTilde(source.path)) : lockContentRootFor(bundleId, source.type);
96357
+ const configuredRoot = source.type === "filesystem" && source.path ? path65.resolve(resolutionBase, expandTilde(source.path)) : lockContentRootFor(bundleId, source.type);
96207
96358
  if (!configuredRoot || !existingDirectory(configuredRoot))
96208
96359
  continue;
96209
- const bundleRoot = path64.resolve(configuredRoot);
96360
+ const bundleRoot = path65.resolve(configuredRoot);
96210
96361
  const component = bundleComponentConfig(bundle);
96211
- const componentRoot = path64.resolve(bundleRoot, component?.root ?? ".");
96212
- const relative = path64.relative(bundleRoot, componentRoot);
96213
- if (relative === ".." || relative.startsWith(`..${path64.sep}`) || path64.isAbsolute(relative)) {
96362
+ const componentRoot = path65.resolve(bundleRoot, component?.root ?? ".");
96363
+ const relative = path65.relative(bundleRoot, componentRoot);
96364
+ if (relative === ".." || relative.startsWith(`..${path65.sep}`) || path65.isAbsolute(relative)) {
96214
96365
  throw new ConfigError(`Task migration component root ${componentRoot} escapes bundle ${bundleId} at ${bundleRoot}.`, "INVALID_CONFIG_FILE");
96215
96366
  }
96216
96367
  if (!existingDirectory(componentRoot))
96217
96368
  continue;
96218
96369
  const adapter = component?.adapter ?? detectAdapterId(componentRoot, "");
96219
96370
  if (!component?.adapter && adapter === "") {
96220
- const flatTasks = fs53.readdirSync(componentRoot, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".yml")).map((entry) => entry.name).sort();
96371
+ const flatTasks = fs56.readdirSync(componentRoot, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".yml")).map((entry) => entry.name).sort();
96221
96372
  if (flatTasks.length > 0) {
96222
96373
  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");
96223
96374
  }
@@ -96289,8 +96440,8 @@ function applyTaskV3Migration() {
96289
96440
  const before = inspectCurrentTaskPlan();
96290
96441
  if (before.result.taskV3Migration.changed === 0)
96291
96442
  return before.result;
96292
- const backupRoot = path64.join(getDataDir(), "backups", "task-v3");
96293
- const backupPath = path64.join(backupRoot, `${Date.now()}-${randomUUID7()}`);
96443
+ const backupRoot = path65.join(getDataDir(), "backups", "task-v3");
96444
+ const backupPath = path65.join(backupRoot, `${Date.now()}-${randomUUID7()}`);
96294
96445
  const applied = applyTaskToV3MigrationPlan(before.plan, { backupRoot: backupPath });
96295
96446
  const after = inspectCurrentTaskPlan().result;
96296
96447
  if (after.taskV3Migration.changed > 0) {
@@ -96346,8 +96497,8 @@ function applyTaskV4Migration() {
96346
96497
  const before = inspectCurrentTaskV4Plan();
96347
96498
  if (before.result.taskV4Migration.changed === 0)
96348
96499
  return before.result;
96349
- const backupRoot = path64.join(getDataDir(), "backups", "task-v4");
96350
- const backupPath = path64.join(backupRoot, `${Date.now()}-${randomUUID7()}`);
96500
+ const backupRoot = path65.join(getDataDir(), "backups", "task-v4");
96501
+ const backupPath = path65.join(backupRoot, `${Date.now()}-${randomUUID7()}`);
96351
96502
  const applied = applyTaskToV4MigrationPlan(before.plan, { backupRoot: backupPath });
96352
96503
  const after = inspectCurrentTaskV4Plan().result;
96353
96504
  if (after.taskV4Migration.changed > 0) {