akm-cli 0.9.7 → 0.9.8-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/CHANGELOG.md +218 -0
  2. package/dist/commands/env/env.js +2 -21
  3. package/dist/commands/health/checks.js +0 -25
  4. package/dist/commands/health/improve-metrics.js +8 -34
  5. package/dist/commands/health/windows.js +0 -4
  6. package/dist/commands/health.js +1 -35
  7. package/dist/commands/improve/consolidate/eligibility.js +11 -5
  8. package/dist/commands/improve/extract.js +36 -32
  9. package/dist/commands/improve/memory/memory-belief.js +15 -5
  10. package/dist/commands/improve/memory/memory-contradiction-detect.js +16 -25
  11. package/dist/commands/improve/memory/memory-improve.js +7 -19
  12. package/dist/commands/improve/preparation.js +52 -36
  13. package/dist/commands/improve/reflect.js +13 -17
  14. package/dist/commands/lint/base-linter.js +42 -2
  15. package/dist/commands/lint/index.js +4 -5
  16. package/dist/commands/migrate/config-extra-params.js +61 -0
  17. package/dist/commands/migrate/dead-residue.js +113 -0
  18. package/dist/commands/migrate/stale-txn.js +49 -0
  19. package/dist/commands/migrate-cli.js +42 -1
  20. package/dist/commands/proposal/proposal.js +1 -21
  21. package/dist/commands/proposal/repository.js +0 -4
  22. package/dist/commands/proposal/validators/proposal-quality-validators.js +0 -6
  23. package/dist/commands/read/curate.js +4 -18
  24. package/dist/commands/read/show.js +2 -1
  25. package/dist/commands/sources/installed-stashes.js +5 -1
  26. package/dist/commands/sources/self-update.js +38 -1
  27. package/dist/commands/sources/sources-cli.js +17 -1
  28. package/dist/commands/tasks/tasks.js +0 -8
  29. package/dist/commands/url-checker.js +20 -28
  30. package/dist/core/adapter/adapters/agent-skills-adapter.js +2 -6
  31. package/dist/core/adapter/adapters/akm-adapter.js +2 -3
  32. package/dist/core/adapter/adapters/akm-lint.js +2 -20
  33. package/dist/core/adapter/adapters/akm-task-adapter.js +2 -6
  34. package/dist/core/adapter/adapters/akm-workflow-adapter.js +2 -6
  35. package/dist/core/adapter/adapters/dotenv-adapter.js +2 -22
  36. package/dist/core/adapter/adapters/generic-files-adapter.js +3 -9
  37. package/dist/core/adapter/adapters/llm-wiki-adapter.js +2 -6
  38. package/dist/core/adapter/adapters/okf-adapter.js +7 -18
  39. package/dist/core/adapter/adapters/shared.js +2 -0
  40. package/dist/core/adapter/adapters/tool-dir-shared.js +3 -9
  41. package/dist/core/adapter/adapters/website-snapshot-adapter.js +2 -6
  42. package/dist/core/adapter/validate-context.js +1 -3
  43. package/dist/core/asset/asset-placement.js +1 -3
  44. package/dist/core/asset/frontmatter.js +96 -0
  45. package/dist/core/common.js +66 -2
  46. package/dist/core/config/config-walker.js +6 -10
  47. package/dist/core/config/config.js +11 -8
  48. package/dist/core/extra-params.js +17 -13
  49. package/dist/core/improve-result.js +1 -3
  50. package/dist/core/json-schema.js +9 -11
  51. package/dist/core/state/migrations.js +52 -2
  52. package/dist/core/state-db.js +2 -1
  53. package/dist/execution/executable-identity.js +1 -3
  54. package/dist/execution/guarded-source.js +1 -6
  55. package/dist/indexer/bundle-identity-guard.js +6 -1
  56. package/dist/indexer/db/graph-db.js +139 -154
  57. package/dist/indexer/ensure-index.js +11 -19
  58. package/dist/indexer/graph/graph-boost.js +23 -34
  59. package/dist/indexer/graph/graph-extraction.js +12 -2
  60. package/dist/indexer/indexer.js +1 -1
  61. package/dist/indexer/lookup/adapter-concept-owner.js +12 -9
  62. package/dist/indexer/passes/memory-inference.js +7 -2
  63. package/dist/indexer/scan/drain-dir.js +2 -4
  64. package/dist/indexer/search/db-search.js +3 -3
  65. package/dist/indexer/search/fts-query.js +10 -15
  66. package/dist/indexer/search/search-source.js +0 -13
  67. package/dist/indexer/usage/usage-events.js +9 -1
  68. package/dist/indexer/walk/walker.js +11 -6
  69. package/dist/integrations/harnesses/claude/result-extractor.js +30 -15
  70. package/dist/integrations/harnesses/codex/result-extractor.js +43 -6
  71. package/dist/integrations/harnesses/copilot/result-extractor.js +39 -12
  72. package/dist/integrations/harnesses/gemini/result-extractor.js +40 -12
  73. package/dist/integrations/harnesses/index.js +0 -4
  74. package/dist/integrations/harnesses/openhands/result-extractor.js +51 -19
  75. package/dist/integrations/harnesses/pi/result-extractor.js +45 -12
  76. package/dist/integrations/lockfile.js +0 -14
  77. package/dist/integrations/session-logs/index.js +0 -81
  78. package/dist/llm/client.js +0 -12
  79. package/dist/llm/memory-infer.js +1 -3
  80. package/dist/llm/usage-telemetry.js +1 -3
  81. package/dist/registry/create-provider-registry.js +4 -0
  82. package/dist/registry/factory.js +4 -0
  83. package/dist/registry/resolve.js +23 -8
  84. package/dist/runtime.js +0 -12
  85. package/dist/scripts/akm-migrate-node.js +142 -244
  86. package/dist/scripts/akm-migrate.js +142 -244
  87. package/dist/setup/setup.js +6 -12
  88. package/dist/sources/providers/git-install.js +7 -2
  89. package/dist/sources/providers/tar-utils.js +1 -7
  90. package/dist/sources/snapshot-fetchers/content-extract.js +0 -17
  91. package/dist/storage/managed-db.js +20 -7
  92. package/dist/storage/repositories/events-repository.js +0 -81
  93. package/dist/storage/repositories/index-entries-repository.js +0 -17
  94. package/dist/storage/repositories/index-fts-repository.js +24 -30
  95. package/dist/storage/repositories/index-utility-repository.js +0 -57
  96. package/dist/storage/repositories/index-vec-repository.js +25 -27
  97. package/dist/storage/repositories/task-history-repository.js +9 -3
  98. package/dist/tasks/backends/launchd.js +8 -18
  99. package/dist/tasks/run/task-history.js +21 -31
  100. package/dist/tasks/scheduler-sync.js +1 -6
  101. package/dist/tasks/source/bounded-document.js +1 -14
  102. package/dist/workflows/exec/child-workflow.js +1 -1
  103. package/dist/workflows/exec/native-executor.js +2 -2
  104. package/dist/workflows/exec/step-work.js +5 -17
  105. package/dist/workflows/exec/worktree.js +40 -6
  106. package/dist/workflows/freeze/task-bindings.js +2 -4
  107. package/dist/workflows/ir/compile.js +3 -14
  108. package/dist/workflows/ir/schema-v4.js +4 -6
  109. package/dist/workflows/ir/schema.js +2 -5
  110. package/dist/workflows/parser.js +23 -26
  111. package/dist/workflows/source-files.js +8 -13
  112. package/dist/workflows/source-ir/schema.js +1 -19
  113. package/docs/migration/v0.9.0-troubleshooting.md +12 -2
  114. package/docs/reference/cli.md +2 -0
  115. package/docs/reference/workflow-schema.md +24 -0
  116. package/package.json +2 -5
  117. package/dist/workflows/source-ir/compare.js +0 -17
@@ -9454,6 +9454,12 @@ function stripJsonComments(text) {
9454
9454
  }
9455
9455
  return result;
9456
9456
  }
9457
+ function toPosix(input) {
9458
+ return input.replace(/\\/g, "/");
9459
+ }
9460
+ function compareCodePoints(left, right) {
9461
+ return left < right ? -1 : left > right ? 1 : 0;
9462
+ }
9457
9463
  function isContainedRelativePath(value) {
9458
9464
  if (value === "" || value.startsWith("/") || value.startsWith("\\") || value.startsWith("~"))
9459
9465
  return false;
@@ -9506,6 +9512,40 @@ function asNonEmptyString(value) {
9506
9512
  const trimmed = value.trim();
9507
9513
  return trimmed.length > 0 ? trimmed : undefined;
9508
9514
  }
9515
+ var ENV_ASSIGN_LINE_RE = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/;
9516
+ function scanEnvKeyNames(text) {
9517
+ const keys = [];
9518
+ const seen = new Set;
9519
+ for (const line of text.split(/\r?\n/)) {
9520
+ const m = line.match(ENV_ASSIGN_LINE_RE);
9521
+ if (!m)
9522
+ continue;
9523
+ const key = m[1];
9524
+ if (!key)
9525
+ continue;
9526
+ if (seen.has(key))
9527
+ continue;
9528
+ seen.add(key);
9529
+ keys.push(key);
9530
+ }
9531
+ return keys;
9532
+ }
9533
+ function wellFormedUnicode(value) {
9534
+ for (let index = 0;index < value.length; index += 1) {
9535
+ const code = value.charCodeAt(index);
9536
+ if (code >= 55296 && code <= 56319) {
9537
+ const next = value.charCodeAt(index + 1);
9538
+ if (!(next >= 56320 && next <= 57343))
9539
+ return false;
9540
+ index += 1;
9541
+ } else if (code >= 56320 && code <= 57343)
9542
+ return false;
9543
+ }
9544
+ return true;
9545
+ }
9546
+ function isRecord(value) {
9547
+ return typeof value === "object" && value !== null && !Array.isArray(value);
9548
+ }
9509
9549
  function isProcessAlive(pid) {
9510
9550
  if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0)
9511
9551
  return false;
@@ -11548,9 +11588,6 @@ function isKnownType(type) {
11548
11588
  var DEPRECATED_REJECTED_TYPES = new Set(["tool", "vault"]);
11549
11589
 
11550
11590
  // src/core/asset/asset-placement.ts
11551
- function toPosix(input) {
11552
- return input.replace(/\\/g, "/");
11553
- }
11554
11591
  var workflowSpec = {
11555
11592
  isRelevantFile: (fileName) => WORKFLOW_EXTENSIONS.includes(path5.extname(fileName).toLowerCase()),
11556
11593
  toCanonicalName: (typeRoot, filePath) => {
@@ -12728,6 +12765,7 @@ function readTags(value) {
12728
12765
  const tags = value.filter((tag) => typeof tag === "string" && tag.trim().length > 0);
12729
12766
  return tags.length > 0 ? tags : undefined;
12730
12767
  }
12768
+ var RESERVED_FILES = new Set(["index.md", "log.md"]);
12731
12769
  function checkMissingUpdated(data, frontmatterText) {
12732
12770
  return frontmatterText !== null && !("updated" in data);
12733
12771
  }
@@ -12865,12 +12903,8 @@ var NAME_MAX = 64;
12865
12903
  var DESCRIPTION_MAX = 1024;
12866
12904
  var RESERVED_NAME_WORDS = ["anthropic", "claude"];
12867
12905
  var NAME_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/;
12868
- var MAX_CONTENT_CHARS = 1e5;
12869
- function toPosix2(p) {
12870
- return p.replace(/\\/g, "/");
12871
- }
12872
12906
  function skillPackage(relPath) {
12873
- const posix = toPosix2(relPath);
12907
+ const posix = toPosix(relPath);
12874
12908
  const segs = posix.split("/").filter((s) => s.length > 0);
12875
12909
  if (segs.length < 2 || segs[segs.length - 1] !== SKILL_MANIFEST)
12876
12910
  return null;
@@ -12899,7 +12933,7 @@ function recognize(c, file) {
12899
12933
  adapterId: "agent-skills",
12900
12934
  type: "skill",
12901
12935
  name,
12902
- content: body.length > MAX_CONTENT_CHARS ? body.slice(0, MAX_CONTENT_CHARS) : body
12936
+ content: body
12903
12937
  };
12904
12938
  if (description !== undefined)
12905
12939
  doc.description = description;
@@ -12987,7 +13021,7 @@ async function validate(_c, changes, ctx) {
12987
13021
  if (seenDirs.has(pkg.conceptId))
12988
13022
  continue;
12989
13023
  seenDirs.add(pkg.conceptId);
12990
- diagnostics.push(...skillFieldDiagnostics(toPosix2(change.path), pkg.dirName, parseFrontmatter(raw).data));
13024
+ diagnostics.push(...skillFieldDiagnostics(toPosix(change.path), pkg.dirName, parseFrontmatter(raw).data));
12991
13025
  }
12992
13026
  diagnostics.push(...await missingManifestDiagnostics(ctx));
12993
13027
  return diagnostics;
@@ -14846,24 +14880,6 @@ import path14 from "node:path";
14846
14880
 
14847
14881
  // src/commands/env/env.ts
14848
14882
  var import_dotenv = __toESM(require_main(), 1);
14849
- var ASSIGN_RE = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/;
14850
- function scanEnvKeyNames(text) {
14851
- const keys = [];
14852
- const seen = new Set;
14853
- for (const line of text.split(/\r?\n/)) {
14854
- const m = line.match(ASSIGN_RE);
14855
- if (!m)
14856
- continue;
14857
- const key = m[1];
14858
- if (!key)
14859
- continue;
14860
- if (seen.has(key))
14861
- continue;
14862
- seen.add(key);
14863
- keys.push(key);
14864
- }
14865
- return keys;
14866
- }
14867
14883
 
14868
14884
  // src/commands/lint/env-key-rules.ts
14869
14885
  var DANGEROUS_ENV_KEYS = new Set([
@@ -15001,19 +15017,6 @@ function own2(value, key) {
15001
15017
  function utf8Bytes2(value) {
15002
15018
  return new TextEncoder().encode(value).byteLength;
15003
15019
  }
15004
- function wellFormedUnicode(value) {
15005
- for (let index = 0;index < value.length; index += 1) {
15006
- const code = value.charCodeAt(index);
15007
- if (code >= 55296 && code <= 56319) {
15008
- const next = value.charCodeAt(index + 1);
15009
- if (!(next >= 56320 && next <= 57343))
15010
- return false;
15011
- index += 1;
15012
- } else if (code >= 56320 && code <= 57343)
15013
- return false;
15014
- }
15015
- return true;
15016
- }
15017
15020
  function sourceError(ctx, fieldPath, detail) {
15018
15021
  const dotted = fieldPath.length === 0 ? "$" : fieldPath.reduce((display, segment) => typeof segment === "number" ? `${display}[${segment}]` : display.length > 0 ? `${display}.${segment}` : segment, "");
15019
15022
  const line = ctx.lineAt?.(fieldPath);
@@ -15425,9 +15428,6 @@ function pointerFor(path10) {
15425
15428
  function pushIssue(issues, path10, keyword, kind, message) {
15426
15429
  issues.push({ path: [...path10], pointer: pointerFor(path10), keyword, kind, message });
15427
15430
  }
15428
- function isPlainObject(value) {
15429
- return typeof value === "object" && value !== null && !Array.isArray(value);
15430
- }
15431
15431
  function isSupportedEnumValue(value) {
15432
15432
  return value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value);
15433
15433
  }
@@ -15477,7 +15477,7 @@ function checkDefinitionNode(schema, path10, issues, depth) {
15477
15477
  continue;
15478
15478
  }
15479
15479
  branches.forEach((branch, index) => {
15480
- if (isPlainObject(branch)) {
15480
+ if (isRecord(branch)) {
15481
15481
  checkDefinitionNode(branch, [...path10, keyword, index], issues, depth + 1);
15482
15482
  } else {
15483
15483
  pushIssue(issues, [...path10, keyword, index], keyword, "malformed", `"${keyword}[${index}]" must be a schema object`);
@@ -15485,7 +15485,7 @@ function checkDefinitionNode(schema, path10, issues, depth) {
15485
15485
  });
15486
15486
  }
15487
15487
  if (schema.not !== undefined) {
15488
- if (isPlainObject(schema.not)) {
15488
+ if (isRecord(schema.not)) {
15489
15489
  checkDefinitionNode(schema.not, [...path10, "not"], issues, depth + 1);
15490
15490
  } else {
15491
15491
  pushIssue(issues, [...path10, "not"], "not", "malformed", `"not" must be a schema object`);
@@ -15497,11 +15497,11 @@ function checkDefinitionNode(schema, path10, issues, depth) {
15497
15497
  }
15498
15498
  }
15499
15499
  if (schema.properties !== undefined) {
15500
- if (!isPlainObject(schema.properties)) {
15500
+ if (!isRecord(schema.properties)) {
15501
15501
  pushIssue(issues, [...path10, "properties"], "properties", "malformed", `"properties" must be an object mapping property names to schemas`);
15502
15502
  } else {
15503
15503
  for (const [key, propSchema] of Object.entries(schema.properties)) {
15504
- if (isPlainObject(propSchema)) {
15504
+ if (isRecord(propSchema)) {
15505
15505
  checkDefinitionNode(propSchema, [...path10, "properties", key], issues, depth + 1);
15506
15506
  } else {
15507
15507
  pushIssue(issues, [...path10, "properties", key], "properties", "malformed", `property ${JSON.stringify(key)} must be a schema object`);
@@ -15510,7 +15510,7 @@ function checkDefinitionNode(schema, path10, issues, depth) {
15510
15510
  }
15511
15511
  }
15512
15512
  if (schema.items !== undefined) {
15513
- if (isPlainObject(schema.items)) {
15513
+ if (isRecord(schema.items)) {
15514
15514
  checkDefinitionNode(schema.items, [...path10, "items"], issues, depth + 1);
15515
15515
  } else if (Array.isArray(schema.items)) {
15516
15516
  pushIssue(issues, [...path10, "items"], "items", "unsupported", `tuple-form "items" (an array of schemas) is not enforced by the workflow schema subset — use a single schema object`);
@@ -15519,7 +15519,7 @@ function checkDefinitionNode(schema, path10, issues, depth) {
15519
15519
  }
15520
15520
  }
15521
15521
  if (schema.additionalProperties !== undefined && typeof schema.additionalProperties !== "boolean") {
15522
- if (isPlainObject(schema.additionalProperties)) {
15522
+ if (isRecord(schema.additionalProperties)) {
15523
15523
  pushIssue(issues, [...path10, "additionalProperties"], "additionalProperties", "unsupported", `schema-form "additionalProperties" is not enforced by the workflow schema subset — only "additionalProperties: false" is`);
15524
15524
  } else {
15525
15525
  pushIssue(issues, [...path10, "additionalProperties"], "additionalProperties", "malformed", `"additionalProperties" must be a boolean (only "false" is enforced)`);
@@ -15568,7 +15568,7 @@ function combinatorBranches(schema, keyword) {
15568
15568
  const raw = schema[keyword];
15569
15569
  if (!Array.isArray(raw))
15570
15570
  return [];
15571
- return raw.filter(isPlainObject);
15571
+ return raw.filter(isRecord);
15572
15572
  }
15573
15573
  function summarizeBranchFailures(failures) {
15574
15574
  const shown = failures.slice(0, 3).map((f) => `${f.index + 1}: ${f.errors[0] ?? "no match"}`);
@@ -15600,7 +15600,7 @@ function validateCombinators(value, schema, path10, ctx) {
15600
15600
  }
15601
15601
  }
15602
15602
  const not = schema.not;
15603
- if (isPlainObject(not) && branchErrors(value, not, path10, ctx).length === 0) {
15603
+ if (isRecord(not) && branchErrors(value, not, path10, ctx).length === 0) {
15604
15604
  ctx.errors.push(`${path10}: value must not match the "not" schema`);
15605
15605
  }
15606
15606
  }
@@ -16356,20 +16356,17 @@ function formatExtraParamsIssue(label, issue) {
16356
16356
  const suffix = issue.path.map((part) => typeof part === "number" ? `[${part}]` : `.${part}`).join("");
16357
16357
  return `${label}${suffix} ${issue.message}`;
16358
16358
  }
16359
- function isPlainObject2(value) {
16360
- return typeof value === "object" && value !== null && !Array.isArray(value);
16361
- }
16362
16359
  function liftLegacyEngineExtraParams(raw) {
16363
16360
  const lifted = [];
16364
16361
  const conflicts = [];
16365
16362
  const rawEngines = raw.engines;
16366
- if (!isPlainObject2(rawEngines)) {
16363
+ if (!isRecord(rawEngines)) {
16367
16364
  return { config: raw, lifted, conflicts };
16368
16365
  }
16369
16366
  const engines = {};
16370
16367
  let anyEngineChanged = false;
16371
16368
  for (const [name, engineValue] of Object.entries(rawEngines)) {
16372
- if (!isPlainObject2(engineValue) || !isPlainObject2(engineValue.extraParams)) {
16369
+ if (!isRecord(engineValue) || !isRecord(engineValue.extraParams)) {
16373
16370
  engines[name] = engineValue;
16374
16371
  continue;
16375
16372
  }
@@ -17889,11 +17886,6 @@ function sourceStepRef(source) {
17889
17886
  // src/workflows/source-ir/schema.ts
17890
17887
  import { types as utilTypes2 } from "node:util";
17891
17888
 
17892
- // src/workflows/source-ir/compare.ts
17893
- function compareWorkflowSourceCodePoints(left, right) {
17894
- return left < right ? -1 : left > right ? 1 : 0;
17895
- }
17896
-
17897
17889
  // src/workflows/source-ir/semantics.ts
17898
17890
  import fs7 from "node:fs";
17899
17891
  import path12 from "node:path";
@@ -18532,9 +18524,6 @@ function validateStep(value, jobId, index, stepIds, options) {
18532
18524
  extensions(step.extensions, `step ${id} extensions`);
18533
18525
  span(step.source, `step ${id} source`);
18534
18526
  }
18535
- function compareCodePoints(left, right) {
18536
- return compareWorkflowSourceCodePoints(left, right);
18537
- }
18538
18527
  function validateExec(value, location, options) {
18539
18528
  if (value === undefined)
18540
18529
  return;
@@ -18840,7 +18829,7 @@ function snapshotValue(value, depth, location, state) {
18840
18829
  return value;
18841
18830
  }
18842
18831
  if (typeof value === "string") {
18843
- if (!wellFormedUnicode2(value))
18832
+ if (!wellFormedUnicode(value))
18844
18833
  fail2(`${location} must contain well-formed Unicode`);
18845
18834
  countJsonBytes(state, JSON.stringify(value));
18846
18835
  return value;
@@ -18904,7 +18893,7 @@ function snapshotObject(value, depth, location, state) {
18904
18893
  for (const [index, key] of ownKeys.entries()) {
18905
18894
  if (typeof key === "symbol")
18906
18895
  fail2(`${location} contains symbol keys`);
18907
- if (!wellFormedUnicode2(key))
18896
+ if (!wellFormedUnicode(key))
18908
18897
  fail2(`${location} contains an ill-formed key`);
18909
18898
  if (UNSAFE_KEYS.has(key))
18910
18899
  fail2(`${location} contains unsafe key ${key}`);
@@ -18933,20 +18922,6 @@ function countJsonBytes(state, token) {
18933
18922
  if (state.bytes > WORKFLOW_SOURCE_IR_MAX_BYTES)
18934
18923
  fail2("source IR exceeds the byte limit");
18935
18924
  }
18936
- function wellFormedUnicode2(value) {
18937
- for (let index = 0;index < value.length; index++) {
18938
- const code = value.charCodeAt(index);
18939
- if (code >= 55296 && code <= 56319) {
18940
- const next = value.charCodeAt(index + 1);
18941
- if (!(next >= 56320 && next <= 57343))
18942
- return false;
18943
- index++;
18944
- } else if (code >= 56320 && code <= 57343) {
18945
- return false;
18946
- }
18947
- }
18948
- return true;
18949
- }
18950
18925
  function record(value, location) {
18951
18926
  if (value === null || typeof value !== "object" || Array.isArray(value))
18952
18927
  fail2(`${location} must be an object`);
@@ -19091,14 +19066,11 @@ function compileWorkflowPlan(input, title, resolvedUnits = new Map) {
19091
19066
  }
19092
19067
  function sortedOutputs(outputs) {
19093
19068
  const sorted = {};
19094
- for (const name of Object.keys(outputs).sort(compareCodePoints2)) {
19069
+ for (const name of Object.keys(outputs).sort(compareCodePoints)) {
19095
19070
  sorted[name] = outputs[name];
19096
19071
  }
19097
19072
  return sorted;
19098
19073
  }
19099
- function compareCodePoints2(left, right) {
19100
- return left < right ? -1 : left > right ? 1 : 0;
19101
- }
19102
19074
  function compileStep(step, sequenceIndex, defaults, resolved) {
19103
19075
  const gate = {
19104
19076
  kind: "gate",
@@ -19225,12 +19197,6 @@ function collectWorkflowWarnings(input) {
19225
19197
  message: `Step "${step.id}" declares \`gate.max_loops: ${maxLoops}\` on an \`exec\` step — it runs its command ` + `ONCE. A gate loop re-executes the step so it can address the judge's feedback, and a frozen argv cannot ` + `read that feedback; looping would only repeat the command's side effects. The gate still evaluates and ` + `can still fail the step.`
19226
19198
  });
19227
19199
  }
19228
- if ((step.map || step.route === undefined) && step.output === undefined) {
19229
- warnings.push({
19230
- line: step.source.start,
19231
- message: `Step "${step.id}" declares no \`output:\` schema — its unit results are carried as an untyped ` + `artifact (permitted). Add an \`output:\` JSON Schema to type and validate the step artifact.`
19232
- });
19233
- }
19234
19200
  if (declaredParams) {
19235
19201
  const declaredList = [...declaredParams].join(", ");
19236
19202
  const scan = (text, label) => {
@@ -19444,7 +19410,7 @@ function parseWorkflow(markdown, source) {
19444
19410
  };
19445
19411
  if (root === null || root === undefined)
19446
19412
  root = {};
19447
- if (!isPlainRecord(root)) {
19413
+ if (!isRecord(root)) {
19448
19414
  return {
19449
19415
  ok: false,
19450
19416
  errors: [{ line: 2, message: `Workflow frontmatter must be a YAML mapping (key: value pairs).` }]
@@ -19625,7 +19591,7 @@ function checkEnvelopeFields(ctx, root, fmEndLine) {
19625
19591
  checkActorStamp(ctx, root.verified, ["verified"], `"verified"`);
19626
19592
  }
19627
19593
  }
19628
- if (root.provenance !== undefined && !isPlainRecord(root.provenance)) {
19594
+ if (root.provenance !== undefined && !isRecord(root.provenance)) {
19629
19595
  ctx.err(["provenance"], `Workflow frontmatter "provenance" must be a mapping.`);
19630
19596
  }
19631
19597
  if (root.status !== undefined && (typeof root.status !== "string" || !LIFECYCLE_STATUSES.has(root.status))) {
@@ -19638,7 +19604,7 @@ function checkEnvelopeFields(ctx, root, fmEndLine) {
19638
19604
  function checkActorStamp(ctx, value, path13, label) {
19639
19605
  if (value === undefined)
19640
19606
  return;
19641
- if (!isPlainRecord(value)) {
19607
+ if (!isRecord(value)) {
19642
19608
  ctx.err(path13, `Workflow frontmatter ${label} must be a mapping with a non-empty "by".`);
19643
19609
  return;
19644
19610
  }
@@ -19669,7 +19635,7 @@ function checkXrefs2(ctx, value, fmEndLine) {
19669
19635
  function parseParams(ctx, raw) {
19670
19636
  if (raw === undefined)
19671
19637
  return;
19672
- if (!isPlainRecord(raw)) {
19638
+ if (!isRecord(raw)) {
19673
19639
  ctx.err(["params"], `"params" must be a mapping of param name to a JSON Schema object (e.g. changed_files: { type: array }).`);
19674
19640
  return;
19675
19641
  }
@@ -19679,7 +19645,7 @@ function parseParams(ctx, raw) {
19679
19645
  ctx.err(["params", paramName], `Param name "${paramName}" is invalid. Use letters, digits, and underscores, starting with a letter or underscore, so "params.${paramName}" can address it.`);
19680
19646
  continue;
19681
19647
  }
19682
- if (!isPlainRecord(value)) {
19648
+ if (!isRecord(value)) {
19683
19649
  ctx.err(["params", paramName], `Param "${paramName}" must be a JSON Schema object (e.g. { type: string }).`);
19684
19650
  continue;
19685
19651
  }
@@ -19694,7 +19660,7 @@ function parseParams(ctx, raw) {
19694
19660
  function parseOutputs(ctx, raw) {
19695
19661
  if (raw === undefined)
19696
19662
  return;
19697
- if (!isPlainRecord(raw)) {
19663
+ if (!isRecord(raw)) {
19698
19664
  ctx.err(["outputs"], `"outputs" must be a mapping of output name to { from, schema? } (e.g. report: { from: steps.summarize.output }).`);
19699
19665
  return;
19700
19666
  }
@@ -19705,7 +19671,7 @@ function parseOutputs(ctx, raw) {
19705
19671
  ctx.err(path13, `Output name "${outputName}" is invalid. Use letters, digits, and underscores, starting with a letter or ` + `underscore, so "steps.<child>.output.${outputName}" can address it.`);
19706
19672
  continue;
19707
19673
  }
19708
- if (!isPlainRecord(value)) {
19674
+ if (!isRecord(value)) {
19709
19675
  ctx.err(path13, `Output "${outputName}" must be a mapping with "from" (and optional "schema").`);
19710
19676
  continue;
19711
19677
  }
@@ -19725,7 +19691,7 @@ function parseOutputs(ctx, raw) {
19725
19691
  }
19726
19692
  const entry = { from: value.from };
19727
19693
  if (value.schema !== undefined) {
19728
- if (!isPlainRecord(value.schema)) {
19694
+ if (!isRecord(value.schema)) {
19729
19695
  ctx.err([...path13, "schema"], `Output "${outputName}" "schema" must be a JSON Schema object.`);
19730
19696
  } else {
19731
19697
  if (jsonBytes(value.schema) > WORKFLOW_MAX_SCHEMA_BYTES) {
@@ -19743,7 +19709,7 @@ function parseDefaults(ctx, raw) {
19743
19709
  if (raw === undefined)
19744
19710
  return;
19745
19711
  const path13 = ["defaults"];
19746
- if (!isPlainRecord(raw)) {
19712
+ if (!isRecord(raw)) {
19747
19713
  ctx.err(path13, `"defaults" must be a mapping with any of: ${DEFAULTS_KEYS.join(", ")}.`);
19748
19714
  return;
19749
19715
  }
@@ -19775,7 +19741,7 @@ function parseBudget(ctx, raw) {
19775
19741
  if (raw === undefined)
19776
19742
  return;
19777
19743
  const path13 = ["budget"];
19778
- if (!isPlainRecord(raw)) {
19744
+ if (!isRecord(raw)) {
19779
19745
  ctx.err(path13, `"budget" must be a mapping with any of: ${BUDGET_KEYS.join(", ")}.`);
19780
19746
  return;
19781
19747
  }
@@ -19804,7 +19770,7 @@ function parseSteps(ctx, raw) {
19804
19770
  }
19805
19771
  const idIndex = new Map;
19806
19772
  raw.forEach((rawStep, index) => {
19807
- if (isPlainRecord(rawStep) && typeof rawStep.id === "string" && !idIndex.has(rawStep.id)) {
19773
+ if (isRecord(rawStep) && typeof rawStep.id === "string" && !idIndex.has(rawStep.id)) {
19808
19774
  idIndex.set(rawStep.id, index);
19809
19775
  }
19810
19776
  });
@@ -19813,7 +19779,7 @@ function parseSteps(ctx, raw) {
19813
19779
  const routeChecks = [];
19814
19780
  raw.forEach((rawStep, index) => {
19815
19781
  const path13 = ["steps", index];
19816
- if (!isPlainRecord(rawStep)) {
19782
+ if (!isRecord(rawStep)) {
19817
19783
  ctx.err(path13, `Step ${index + 1} must be a mapping with an "id".`);
19818
19784
  return;
19819
19785
  }
@@ -19887,7 +19853,7 @@ function parseSteps(ctx, raw) {
19887
19853
  return steps;
19888
19854
  }
19889
19855
  function parseUnit(ctx, raw, path13, stepLabel) {
19890
- if (!isPlainRecord(raw)) {
19856
+ if (!isRecord(raw)) {
19891
19857
  ctx.err(path13, `${stepLabel} "unit" must be a mapping (a dispatch-override bag).`);
19892
19858
  return;
19893
19859
  }
@@ -19948,7 +19914,7 @@ function parseUnit(ctx, raw, path13, stepLabel) {
19948
19914
  return unit;
19949
19915
  }
19950
19916
  function parseExec(ctx, raw, path13, stepLabel) {
19951
- if (!isPlainRecord(raw)) {
19917
+ if (!isRecord(raw)) {
19952
19918
  ctx.err(path13, `${stepLabel} "exec" must be a mapping with a "command" argv list.`);
19953
19919
  return;
19954
19920
  }
@@ -20032,7 +19998,7 @@ function parseExecCwd(ctx, raw, path13, stepLabel) {
20032
19998
  return value;
20033
19999
  }
20034
20000
  function parseMap(ctx, raw, path13, stepLabel) {
20035
- if (!isPlainRecord(raw)) {
20001
+ if (!isRecord(raw)) {
20036
20002
  ctx.err(path13, `${stepLabel} "map" must be a mapping with an "over" key.`);
20037
20003
  return;
20038
20004
  }
@@ -20064,7 +20030,7 @@ function parseMap(ctx, raw, path13, stepLabel) {
20064
20030
  return map;
20065
20031
  }
20066
20032
  function parseRoute(ctx, raw, path13, stepLabel, stepIndex, routeChecks) {
20067
- if (!isPlainRecord(raw)) {
20033
+ if (!isRecord(raw)) {
20068
20034
  ctx.err(path13, `${stepLabel} "route" must be a mapping with "input" and "when" keys.`);
20069
20035
  return;
20070
20036
  }
@@ -20084,7 +20050,7 @@ function parseRoute(ctx, raw, path13, stepLabel, stepIndex, routeChecks) {
20084
20050
  const seenMatches = new Map;
20085
20051
  raw.when.forEach((branch, i) => {
20086
20052
  const branchPath = [...whenPath, i];
20087
- if (!isPlainRecord(branch)) {
20053
+ if (!isRecord(branch)) {
20088
20054
  ctx.err(branchPath, `${stepLabel} "when[${i}]" must be a mapping: { match, step }.`);
20089
20055
  return;
20090
20056
  }
@@ -20155,7 +20121,7 @@ function parseInputs(ctx, raw, path13, stepLabel) {
20155
20121
  return out.length > 0 ? out : undefined;
20156
20122
  }
20157
20123
  function parseGate(ctx, raw, path13, stepLabel) {
20158
- if (!isPlainRecord(raw)) {
20124
+ if (!isRecord(raw)) {
20159
20125
  ctx.err(path13, `${stepLabel} "gate" must be a mapping with any of: ${GATE_KEYS.join(", ")}.`);
20160
20126
  return;
20161
20127
  }
@@ -20185,7 +20151,7 @@ function parseEngineName(ctx, raw, path13, label) {
20185
20151
  function parseRetry(ctx, raw, path13, stepLabel) {
20186
20152
  if (raw === undefined)
20187
20153
  return;
20188
- if (!isPlainRecord(raw)) {
20154
+ if (!isRecord(raw)) {
20189
20155
  ctx.err(path13, `${stepLabel} "retry" must be a mapping: { max: <n>, on: [<failure_reason>, …] }.`);
20190
20156
  return;
20191
20157
  }
@@ -20258,7 +20224,7 @@ function parseEnumField(ctx, raw, path13, label, allowed) {
20258
20224
  function parseLlmOverrides(ctx, raw, path13, label) {
20259
20225
  if (raw === undefined)
20260
20226
  return;
20261
- if (!isPlainRecord(raw)) {
20227
+ if (!isRecord(raw)) {
20262
20228
  ctx.err(path13, `${label} must be a mapping of LLM invocation overrides.`);
20263
20229
  return;
20264
20230
  }
@@ -20292,7 +20258,7 @@ function parseLlmOverrides(ctx, raw, path13, label) {
20292
20258
  ctx.err([...path13, "supports_json_schema"], `${label}.supports_json_schema must be a boolean.`);
20293
20259
  }
20294
20260
  if (raw.extra_params !== undefined) {
20295
- if (!isPlainRecord(raw.extra_params)) {
20261
+ if (!isRecord(raw.extra_params)) {
20296
20262
  ctx.err([...path13, "extra_params"], `${label}.extra_params must be a JSON object.`);
20297
20263
  } else {
20298
20264
  const issues = validateExtraParams(raw.extra_params);
@@ -20330,7 +20296,7 @@ function parseLlmOverrides(ctx, raw, path13, label) {
20330
20296
  function parseSchemaObject(ctx, raw, path13, label) {
20331
20297
  if (raw === undefined)
20332
20298
  return;
20333
- if (!isPlainRecord(raw)) {
20299
+ if (!isRecord(raw)) {
20334
20300
  ctx.err(path13, `${label} must be a JSON Schema object (e.g. { type: object, properties: { … } }).`);
20335
20301
  return;
20336
20302
  }
@@ -20362,9 +20328,6 @@ function checkUnknownKeys(ctx, obj, path13, allowed, label) {
20362
20328
  }
20363
20329
  }
20364
20330
  }
20365
- function isPlainRecord(value) {
20366
- return typeof value === "object" && value !== null && !Array.isArray(value);
20367
- }
20368
20331
  function describeError(cause) {
20369
20332
  return cause instanceof Error ? cause.message : String(cause);
20370
20333
  }
@@ -21245,22 +21208,6 @@ function nameOrTypeDiagnostics(relPath, data, frontmatter, allowedTypes) {
21245
21208
  }
21246
21209
  return [];
21247
21210
  }
21248
- var ASSIGN_RE2 = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/;
21249
- function scanKeys(text) {
21250
- const keys2 = [];
21251
- const seen = new Set;
21252
- for (const line of text.split(/\r?\n/)) {
21253
- const m = line.match(ASSIGN_RE2);
21254
- if (!m)
21255
- continue;
21256
- const key = m[1];
21257
- if (seen.has(key))
21258
- continue;
21259
- seen.add(key);
21260
- keys2.push(key);
21261
- }
21262
- return keys2;
21263
- }
21264
21211
  function collectSuppressedKeys(raw) {
21265
21212
  const suppressed = new Set;
21266
21213
  const lines = raw.split(/\r?\n/);
@@ -21284,7 +21231,7 @@ function dangerousEnvKeyDiagnostics(type, relPath, raw) {
21284
21231
  if (!baseNameWithExt.endsWith(".env"))
21285
21232
  return [];
21286
21233
  const ref = conceptIdForStashFile(type, ".", relPath);
21287
- const keys2 = scanKeys(raw);
21234
+ const keys2 = scanEnvKeyNames(raw);
21288
21235
  const suppressed = collectSuppressedKeys(raw);
21289
21236
  const diagnostics = [];
21290
21237
  for (const key of keys2) {
@@ -21734,7 +21681,6 @@ function applyFoldedMetadata(entry, folded) {
21734
21681
  }
21735
21682
 
21736
21683
  // src/core/adapter/adapters/akm-adapter.ts
21737
- var RESERVED_FILES = new Set(["index.md", "log.md"]);
21738
21684
  function isReservedFileName(name) {
21739
21685
  return RESERVED_FILES.has(name.toLowerCase());
21740
21686
  }
@@ -22070,14 +22016,10 @@ import fs9 from "node:fs";
22070
22016
  import path16 from "node:path";
22071
22017
  var COMPONENT_ID2 = "main";
22072
22018
  var TASK_EXT = TASK_EXTENSION;
22073
- var MAX_CONTENT_CHARS2 = 1e5;
22074
- function toPosix3(p) {
22075
- return p.replace(/\\/g, "/");
22076
- }
22077
22019
  function recognize3(c, file) {
22078
22020
  if (file.ext !== TASK_EXT)
22079
22021
  return null;
22080
- const conceptId = toPosix3(file.relPath).replace(/\.yml$/i, "");
22022
+ const conceptId = toPosix(file.relPath).replace(/\.yml$/i, "");
22081
22023
  const name = conceptId.split("/").pop() ?? conceptId;
22082
22024
  const raw = file.content();
22083
22025
  return {
@@ -22090,7 +22032,7 @@ function recognize3(c, file) {
22090
22032
  adapterId: "akm-task",
22091
22033
  type: "task",
22092
22034
  name,
22093
- content: raw.length > MAX_CONTENT_CHARS2 ? raw.slice(0, MAX_CONTENT_CHARS2) : raw
22035
+ content: raw
22094
22036
  };
22095
22037
  }
22096
22038
  async function validate3(c, changes, ctx) {
@@ -22104,7 +22046,7 @@ async function validate3(c, changes, ctx) {
22104
22046
  const ext = path16.extname(change.path).toLowerCase();
22105
22047
  if (ext !== TASK_EXT && ext !== TASK_NEAR_MISS_EXTENSION)
22106
22048
  continue;
22107
- const relPath = toPosix3(change.path);
22049
+ const relPath = toPosix(change.path);
22108
22050
  if (ext === TASK_NEAR_MISS_EXTENSION) {
22109
22051
  diagnostics.push({
22110
22052
  file: relPath,
@@ -22134,14 +22076,14 @@ var akmTaskAdapter = {
22134
22076
  recognize: recognize3,
22135
22077
  validate: validate3,
22136
22078
  readCandidates(c, conceptId) {
22137
- const posix = toPosix3(conceptId).replace(/\.ya?ml$/i, "");
22079
+ const posix = toPosix(conceptId).replace(/\.ya?ml$/i, "");
22138
22080
  return [
22139
22081
  { path: path16.join(c.root, `${posix}.yml`), conceptId: posix },
22140
22082
  { path: path16.join(c.root, `${posix}.yaml`), conceptId: posix }
22141
22083
  ];
22142
22084
  },
22143
22085
  placeNew(c, conceptId) {
22144
- const posix = toPosix3(conceptId);
22086
+ const posix = toPosix(conceptId);
22145
22087
  return path16.join(c.root, /\.yml$/i.test(posix) ? posix : `${posix}.yml`);
22146
22088
  },
22147
22089
  directoryList() {
@@ -22177,12 +22119,8 @@ import fs10 from "node:fs";
22177
22119
  import path17 from "node:path";
22178
22120
  var COMPONENT_ID3 = "main";
22179
22121
  var WORKFLOW_EXTS = new Set([".md", ".yml"]);
22180
- var MAX_CONTENT_CHARS3 = 1e5;
22181
- function toPosix4(p) {
22182
- return p.replace(/\\/g, "/");
22183
- }
22184
22122
  function conceptIdOf(relPath) {
22185
- return toPosix4(relPath).replace(/\.(?:md|yml)$/i, "");
22123
+ return toPosix(relPath).replace(/\.(?:md|yml)$/i, "");
22186
22124
  }
22187
22125
  function isReservedDocFile(fileName) {
22188
22126
  return fileName.toLowerCase() === "readme.md";
@@ -22216,7 +22154,7 @@ function recognize4(c, file) {
22216
22154
  adapterId: "akm-workflow",
22217
22155
  type: "workflow",
22218
22156
  name,
22219
- content: body.length > MAX_CONTENT_CHARS3 ? body.slice(0, MAX_CONTENT_CHARS3) : body
22157
+ content: body
22220
22158
  };
22221
22159
  if (description !== undefined)
22222
22160
  doc.description = description;
@@ -22235,7 +22173,7 @@ async function validate4(c, changes, ctx) {
22235
22173
  const ext = path17.extname(change.path).toLowerCase();
22236
22174
  if (!WORKFLOW_EXTS.has(ext) || isReservedDocFile(path17.basename(change.path)))
22237
22175
  continue;
22238
- const relPath = toPosix4(change.path);
22176
+ const relPath = toPosix(change.path);
22239
22177
  if (ext === ".yml") {
22240
22178
  diagnostics.push(...workflowYamlSourceDiagnostics(relPath, raw, relPath, c.root).errors);
22241
22179
  continue;
@@ -22285,7 +22223,7 @@ var akmWorkflowAdapter = {
22285
22223
  recognize: recognize4,
22286
22224
  validate: validate4,
22287
22225
  readCandidates(c, conceptId) {
22288
- const posix = toPosix4(conceptId);
22226
+ const posix = toPosix(conceptId);
22289
22227
  const canonical = posix.replace(/\.(?:md|yml)$/i, "");
22290
22228
  return /\.(?:md|yml)$/i.test(posix) ? [{ path: path17.join(c.root, posix), conceptId: canonical }] : [
22291
22229
  { path: path17.join(c.root, `${posix}.md`), conceptId: canonical },
@@ -22293,7 +22231,7 @@ var akmWorkflowAdapter = {
22293
22231
  ];
22294
22232
  },
22295
22233
  placeNew(c, conceptId) {
22296
- const posix = toPosix4(conceptId);
22234
+ const posix = toPosix(conceptId);
22297
22235
  if (/\.(?:md|yml)$/i.test(posix))
22298
22236
  return path17.join(c.root, posix);
22299
22237
  return path17.join(c.root, `${posix}.md`);
@@ -22318,20 +22256,15 @@ import path19 from "node:path";
22318
22256
 
22319
22257
  // src/core/adapter/adapters/tool-dir-shared.ts
22320
22258
  import path18 from "node:path";
22321
- var RESERVED_FILES2 = new Set(["index.md", "log.md"]);
22322
- var MAX_CONTENT_CHARS4 = 1e5;
22323
22259
  var CANONICAL_COMMAND_DIR = "commands";
22324
22260
  var CANONICAL_AGENT_DIR = "agents";
22325
22261
  var CANONICAL_SKILL_DIR = "skills";
22326
22262
  var SKILL_MANIFEST2 = "SKILL.md";
22327
- function toPosix5(p) {
22328
- return p.replace(/\\/g, "/");
22329
- }
22330
22263
  function isReserved(base3) {
22331
- return RESERVED_FILES2.has(base3.toLowerCase());
22264
+ return RESERVED_FILES.has(base3.toLowerCase());
22332
22265
  }
22333
22266
  function classify(relPath, layout) {
22334
- const posix = toPosix5(relPath);
22267
+ const posix = toPosix(relPath);
22335
22268
  const segs = posix.split("/").filter((s) => s.length > 0);
22336
22269
  if (segs.length === 0)
22337
22270
  return null;
@@ -22378,7 +22311,7 @@ function recognizeToolDir(layout, c, file) {
22378
22311
  adapterId: layout.adapterId,
22379
22312
  type: cls.type,
22380
22313
  name,
22381
- content: body.length > MAX_CONTENT_CHARS4 ? body.slice(0, MAX_CONTENT_CHARS4) : body
22314
+ content: body
22382
22315
  };
22383
22316
  if (cls.type === "instruction")
22384
22317
  doc.ownsPresentation = true;
@@ -22389,7 +22322,7 @@ function recognizeToolDir(layout, c, file) {
22389
22322
  return doc;
22390
22323
  }
22391
22324
  function placeNewToolDir(layout, c, conceptId) {
22392
- const posix = toPosix5(conceptId);
22325
+ const posix = toPosix(conceptId);
22393
22326
  if (posix === layout.instructionConceptId)
22394
22327
  return path18.join(c.root, layout.instructionFile);
22395
22328
  const segs = posix.split("/").filter((s) => s.length > 0);
@@ -22406,7 +22339,7 @@ function placeNewToolDir(layout, c, conceptId) {
22406
22339
  return path18.join(c.root, `${posix}.md`);
22407
22340
  }
22408
22341
  function readCandidatesToolDir(layout, c, conceptId) {
22409
- const posix = toPosix5(conceptId);
22342
+ const posix = toPosix(conceptId);
22410
22343
  if (posix === layout.instructionConceptId) {
22411
22344
  return [{ path: path18.join(c.root, layout.instructionFile), conceptId: posix }];
22412
22345
  }
@@ -22447,7 +22380,7 @@ async function validateToolDir(layout, c, changes, ctx) {
22447
22380
  const raw = change.after ?? await ctx.readFile(change.path);
22448
22381
  if (typeof raw !== "string")
22449
22382
  continue;
22450
- const relPath = toPosix5(change.path);
22383
+ const relPath = toPosix(change.path);
22451
22384
  diagnostics.push(...await skillDirectoryDiagnostics(relPath, seenSkillDirs, ctx, layout.skillDirs));
22452
22385
  const cls = classify(change.path, layout);
22453
22386
  if (cls === null)
@@ -22547,12 +22480,8 @@ var COMPONENT_ID4 = "main";
22547
22480
  var ENV_DIR = "env";
22548
22481
  var SECRETS_DIR = "secrets";
22549
22482
  var SECRET_SKIP_SUFFIXES = [".lock", ".sensitive"];
22550
- var ASSIGN_RE3 = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/;
22551
- function toPosix6(p) {
22552
- return p.replace(/\\/g, "/");
22553
- }
22554
22483
  function classify2(relPath) {
22555
- const posix = toPosix6(relPath);
22484
+ const posix = toPosix(relPath);
22556
22485
  const segs = posix.split("/").filter((s) => s.length > 0);
22557
22486
  if (segs.length < 2)
22558
22487
  return null;
@@ -22570,23 +22499,8 @@ function hasSensitiveMarker(absPath, type) {
22570
22499
  const marker = type === "env" ? absPath.replace(/\.env$/i, ".sensitive") : `${absPath}.sensitive`;
22571
22500
  return marker !== absPath && fs12.existsSync(marker);
22572
22501
  }
22573
- function scanKeyNames(raw) {
22574
- const keys2 = [];
22575
- const seen = new Set;
22576
- for (const line of raw.split(/\r?\n/)) {
22577
- const m = line.match(ASSIGN_RE3);
22578
- if (!m)
22579
- continue;
22580
- const key = m[1];
22581
- if (seen.has(key))
22582
- continue;
22583
- seen.add(key);
22584
- keys2.push(key);
22585
- }
22586
- return keys2;
22587
- }
22588
22502
  function conceptIdForPath(type, relativePath) {
22589
- const posix = toPosix6(relativePath);
22503
+ const posix = toPosix(relativePath);
22590
22504
  if (type === "secret")
22591
22505
  return posix;
22592
22506
  const stripped = posix.replace(/\.env$/i, "");
@@ -22598,12 +22512,12 @@ function recognize5(c, file) {
22598
22512
  return null;
22599
22513
  if (hasSensitiveMarker(file.absPath, type))
22600
22514
  return null;
22601
- const posix = toPosix6(file.relPath);
22515
+ const posix = toPosix(file.relPath);
22602
22516
  const raw = file.content();
22603
22517
  if (type === "env") {
22604
22518
  const conceptId = conceptIdForPath(type, posix);
22605
22519
  const name2 = (conceptId.split("/").pop() ?? conceptId) || "default";
22606
- const keys2 = scanKeyNames(raw);
22520
+ const keys2 = scanEnvKeyNames(raw);
22607
22521
  const doc = {
22608
22522
  ref: `${c.id}//${conceptId}`,
22609
22523
  bundle: c.id,
@@ -22643,7 +22557,7 @@ async function validate5(_c, changes, ctx) {
22643
22557
  const type = classify2(change.path);
22644
22558
  if (type === null)
22645
22559
  continue;
22646
- diagnostics.push(...dangerousEnvKeyDiagnostics(type, toPosix6(change.path), raw));
22560
+ diagnostics.push(...dangerousEnvKeyDiagnostics(type, toPosix(change.path), raw));
22647
22561
  }
22648
22562
  return diagnostics;
22649
22563
  }
@@ -22654,7 +22568,7 @@ var dotenvAdapter = {
22654
22568
  recognize: recognize5,
22655
22569
  validate: validate5,
22656
22570
  readCandidates(c, conceptId) {
22657
- const posix = toPosix6(conceptId);
22571
+ const posix = toPosix(conceptId);
22658
22572
  const slash = posix.indexOf("/");
22659
22573
  if (slash <= 0)
22660
22574
  return [];
@@ -22668,7 +22582,7 @@ var dotenvAdapter = {
22668
22582
  return expanded.map((candidatePath) => ({ path: candidatePath, conceptId: posix }));
22669
22583
  },
22670
22584
  placeNew(c, conceptId) {
22671
- const posix = toPosix6(conceptId);
22585
+ const posix = toPosix(conceptId);
22672
22586
  const slash = posix.indexOf("/");
22673
22587
  if (slash > 0) {
22674
22588
  const head = posix.slice(0, slash);
@@ -22703,13 +22617,8 @@ var dotenvAdapter = {
22703
22617
  import path21 from "node:path";
22704
22618
  var COMPONENT_ID5 = "main";
22705
22619
  var DOCUMENT_EXTENSIONS = new Set([".md", ".markdown", ".txt", ".text"]);
22706
- var RESERVED_FILES3 = new Set(["index.md", "log.md"]);
22707
- var MAX_CONTENT_CHARS5 = 1e5;
22708
- function toPosix7(p) {
22709
- return p.replace(/\\/g, "/");
22710
- }
22711
22620
  function isReserved2(base3) {
22712
- return RESERVED_FILES3.has(base3.toLowerCase());
22621
+ return RESERVED_FILES.has(base3.toLowerCase());
22713
22622
  }
22714
22623
  function classify3(ext) {
22715
22624
  if (SCRIPT_EXTENSIONS.has(ext))
@@ -22719,7 +22628,7 @@ function classify3(ext) {
22719
22628
  return "file";
22720
22629
  }
22721
22630
  function recognize6(c, file) {
22722
- const posix = toPosix7(file.relPath);
22631
+ const posix = toPosix(file.relPath);
22723
22632
  const base3 = posix.split("/").pop() ?? posix;
22724
22633
  if (isReserved2(base3))
22725
22634
  return null;
@@ -22739,7 +22648,7 @@ function recognize6(c, file) {
22739
22648
  adapterId: "generic-files",
22740
22649
  type,
22741
22650
  name,
22742
- content: body.length > MAX_CONTENT_CHARS5 ? body.slice(0, MAX_CONTENT_CHARS5) : body
22651
+ content: body
22743
22652
  };
22744
22653
  if (type !== "script")
22745
22654
  doc.ownsPresentation = true;
@@ -22759,7 +22668,7 @@ async function validate6(c, changes, ctx) {
22759
22668
  const raw = change.after ?? await ctx.readFile(change.path);
22760
22669
  if (typeof raw !== "string")
22761
22670
  continue;
22762
- diagnostics.push(...await runBaseValidateChecks(toPosix7(change.path), parseFrontmatter(raw), c.root, ctx));
22671
+ diagnostics.push(...await runBaseValidateChecks(toPosix(change.path), parseFrontmatter(raw), c.root, ctx));
22763
22672
  }
22764
22673
  return diagnostics;
22765
22674
  }
@@ -22770,7 +22679,7 @@ var genericFilesAdapter = {
22770
22679
  recognize: recognize6,
22771
22680
  validate: validate6,
22772
22681
  readCandidates(c, conceptId) {
22773
- const posix = toPosix7(conceptId);
22682
+ const posix = toPosix(conceptId);
22774
22683
  const extension = path21.extname(posix).toLowerCase();
22775
22684
  const documentCandidates = [...DOCUMENT_EXTENSIONS].map((candidateExtension) => ({
22776
22685
  path: path21.join(c.root, `${posix}${candidateExtension}`),
@@ -22779,7 +22688,7 @@ var genericFilesAdapter = {
22779
22688
  return DOCUMENT_EXTENSIONS.has(extension) ? documentCandidates : [{ path: path21.join(c.root, posix), conceptId: posix }, ...documentCandidates];
22780
22689
  },
22781
22690
  placeNew(c, conceptId) {
22782
- const posix = toPosix7(conceptId);
22691
+ const posix = toPosix(conceptId);
22783
22692
  const hasExt = path21.extname(posix) !== "";
22784
22693
  return path21.join(c.root, hasExt ? posix : `${posix}.md`);
22785
22694
  },
@@ -22797,12 +22706,8 @@ var DEFAULT_PAGE_KIND = "note";
22797
22706
  var RESERVED_ROOT_FILES = new Set(["schema.md", "index.md", "log.md"]);
22798
22707
  var RAW_SUBDIR = "raw";
22799
22708
  var PAGES_SUBDIR = "pages";
22800
- var MAX_CONTENT_CHARS6 = 1e5;
22801
- function toPosix8(p) {
22802
- return p.replace(/\\/g, "/");
22803
- }
22804
22709
  function conceptIdOf2(relPath) {
22805
- return toPosix8(relPath).replace(/\.md$/i, "");
22710
+ return toPosix(relPath).replace(/\.md$/i, "");
22806
22711
  }
22807
22712
  function parseWikiFrontmatter(raw) {
22808
22713
  const out = { xrefs: [], sources: [] };
@@ -22834,13 +22739,13 @@ function parseWikiFrontmatter(raw) {
22834
22739
  return out;
22835
22740
  }
22836
22741
  function isReservedRootFile(relPath) {
22837
- const posix = toPosix8(relPath);
22742
+ const posix = toPosix(relPath);
22838
22743
  if (posix.includes("/"))
22839
22744
  return false;
22840
22745
  return RESERVED_ROOT_FILES.has(posix.toLowerCase());
22841
22746
  }
22842
22747
  function firstSegment(relPath) {
22843
- const posix = toPosix8(relPath);
22748
+ const posix = toPosix(relPath);
22844
22749
  const slash = posix.indexOf("/");
22845
22750
  return slash < 0 ? posix : posix.slice(0, slash);
22846
22751
  }
@@ -22852,7 +22757,7 @@ function resolveXref(xref, bundleId) {
22852
22757
  return target.length > 0 ? target : null;
22853
22758
  }
22854
22759
  function resolveBodyLinks(body, fileRelPath) {
22855
- const dir = path22.posix.dirname(toPosix8(fileRelPath));
22760
+ const dir = path22.posix.dirname(toPosix(fileRelPath));
22856
22761
  const linkRe = /\[[^\]]*\]\(([^)]+)\)/g;
22857
22762
  const out = [];
22858
22763
  const seen = new Set;
@@ -22929,7 +22834,7 @@ function resolveSources(fm) {
22929
22834
  function recognize7(c, file) {
22930
22835
  if (file.ext !== ".md")
22931
22836
  return null;
22932
- const relPath = toPosix8(file.relPath);
22837
+ const relPath = toPosix(file.relPath);
22933
22838
  if (isReservedRootFile(relPath))
22934
22839
  return null;
22935
22840
  const head = firstSegment(relPath);
@@ -22953,7 +22858,7 @@ function recognize7(c, file) {
22953
22858
  ownsPresentation: true,
22954
22859
  type: isRaw ? WIKI_SOURCE_TYPE : fm.pageKind ?? DEFAULT_PAGE_KIND,
22955
22860
  name: lastSegment,
22956
- content: body.length > MAX_CONTENT_CHARS6 ? body.slice(0, MAX_CONTENT_CHARS6) : body
22861
+ content: body
22957
22862
  };
22958
22863
  if (fm.description !== undefined)
22959
22864
  doc.description = fm.description;
@@ -22979,7 +22884,7 @@ async function validate7(c, changes, ctx) {
22979
22884
  const raw = change.after ?? await ctx.readFile(change.path);
22980
22885
  if (typeof raw !== "string")
22981
22886
  continue;
22982
- const relPath = toPosix8(change.path);
22887
+ const relPath = toPosix(change.path);
22983
22888
  if (isReservedRootFile(relPath))
22984
22889
  continue;
22985
22890
  const head = firstSegment(relPath);
@@ -23062,7 +22967,7 @@ var llmWikiAdapter = {
23062
22967
  recognize: recognize7,
23063
22968
  validate: validate7,
23064
22969
  readCandidates(c, conceptId) {
23065
- const canonical = toPosix8(conceptId).replace(/\.md$/i, "");
22970
+ const canonical = toPosix(conceptId).replace(/\.md$/i, "");
23066
22971
  return [{ path: path22.join(c.root, `${canonical}.md`), conceptId: canonical }];
23067
22972
  },
23068
22973
  placeNew(c, conceptId) {
@@ -23098,11 +23003,8 @@ var CONSUMED_FRONTMATTER_KEYS = [
23098
23003
  "stale_after",
23099
23004
  "okf_version"
23100
23005
  ];
23101
- function isPlainObject3(value) {
23102
- return value !== null && typeof value === "object" && !Array.isArray(value);
23103
- }
23104
23006
  function parseActorMapping(value) {
23105
- if (!isPlainObject3(value))
23007
+ if (!isRecord(value))
23106
23008
  return;
23107
23009
  const by = nonEmptyString(value.by);
23108
23010
  if (by === undefined)
@@ -23127,7 +23029,7 @@ function parseOkfSources(value) {
23127
23029
  return;
23128
23030
  const out = [];
23129
23031
  for (const item of value) {
23130
- if (!isPlainObject3(item))
23032
+ if (!isRecord(item))
23131
23033
  continue;
23132
23034
  const resource = nonEmptyString(item.resource);
23133
23035
  if (resource === undefined)
@@ -23155,16 +23057,11 @@ function parseOkfSources(value) {
23155
23057
  function parseLifecycleStatus(value) {
23156
23058
  return value === "draft" || value === "stable" || value === "deprecated" ? value : undefined;
23157
23059
  }
23158
- var RESERVED_FILES4 = new Set(["index.md", "log.md"]);
23159
- var MAX_CONTENT_CHARS7 = 1e5;
23160
- function toPosix9(p) {
23161
- return p.replace(/\\/g, "/");
23162
- }
23163
23060
  function isReservedFileName2(name) {
23164
- return RESERVED_FILES4.has(name.toLowerCase());
23061
+ return RESERVED_FILES.has(name.toLowerCase());
23165
23062
  }
23166
23063
  function resolveOkfLinks(body, fileRelPath) {
23167
- const dir = path23.posix.dirname(toPosix9(fileRelPath));
23064
+ const dir = path23.posix.dirname(toPosix(fileRelPath));
23168
23065
  const definitions = new Map;
23169
23066
  for (const match of body.matchAll(/^\s*\[([^\]]+)\]:\s*(\S+)/gm)) {
23170
23067
  definitions.set(match[1].trim().toLowerCase(), match[2]);
@@ -23222,7 +23119,7 @@ function recognize8(c, file) {
23222
23119
  return null;
23223
23120
  if (isReservedFileName2(file.fileName))
23224
23121
  return null;
23225
- const conceptId = toPosix9(file.relPath).replace(/\.md$/i, "");
23122
+ const conceptId = toPosix(file.relPath).replace(/\.md$/i, "");
23226
23123
  const raw = file.content();
23227
23124
  const parsed = parseFrontmatter(raw);
23228
23125
  const data = parsed.data;
@@ -23233,7 +23130,7 @@ function recognize8(c, file) {
23233
23130
  const description = nonEmptyString(data.description);
23234
23131
  const tags = readTags(data.tags);
23235
23132
  const links = resolveOkfLinks(body, file.relPath);
23236
- const generatedMapping = isPlainObject3(data.generated) ? data.generated : undefined;
23133
+ const generatedMapping = isRecord(data.generated) ? data.generated : undefined;
23237
23134
  const generatedAt = generatedMapping ? nonEmptyString(generatedMapping.at) : undefined;
23238
23135
  const generatedBy = generatedMapping ? nonEmptyString(generatedMapping.by) : undefined;
23239
23136
  const legacyTimestamp = nonEmptyString(data.timestamp);
@@ -23260,7 +23157,7 @@ function recognize8(c, file) {
23260
23157
  ownsPresentation: true,
23261
23158
  type,
23262
23159
  name,
23263
- content: body.length > MAX_CONTENT_CHARS7 ? body.slice(0, MAX_CONTENT_CHARS7) : body
23160
+ content: body
23264
23161
  };
23265
23162
  if (description !== undefined)
23266
23163
  doc.description = description;
@@ -23291,7 +23188,7 @@ async function validate8(c, changes, ctx) {
23291
23188
  const raw = change.after ?? await ctx.readFile(change.path);
23292
23189
  if (typeof raw !== "string")
23293
23190
  continue;
23294
- const relPath = toPosix9(change.path);
23191
+ const relPath = toPosix(change.path);
23295
23192
  const fileName = relPath.split("/").pop() ?? relPath;
23296
23193
  const reserved = isReservedFileName2(fileName);
23297
23194
  const parsed = parseFrontmatter(raw);
@@ -23415,10 +23312,6 @@ var COMPONENT_ID6 = "main";
23415
23312
  var PAGES_PREFIX = "stash/knowledge/";
23416
23313
  var MANIFEST_FILE = "manifest.json";
23417
23314
  var WEBSITE_TAG = "website";
23418
- var MAX_CONTENT_CHARS8 = 1e5;
23419
- function toPosix10(p) {
23420
- return p.replace(/\\/g, "/");
23421
- }
23422
23315
  function parseSnapshotFrontmatter(raw) {
23423
23316
  const out = { tags: [] };
23424
23317
  const block = parseFrontmatterBlock(raw);
@@ -23441,14 +23334,14 @@ function parseSnapshotFrontmatter(raw) {
23441
23334
  return out;
23442
23335
  }
23443
23336
  function isSnapshotPage(relPath) {
23444
- const posix = toPosix10(relPath);
23337
+ const posix = toPosix(relPath);
23445
23338
  return posix.startsWith(PAGES_PREFIX) && posix.toLowerCase().endsWith(".md");
23446
23339
  }
23447
23340
  function isReTypeGated(fm) {
23448
23341
  return fm.sourceUrl !== undefined || fm.tags.includes(WEBSITE_TAG);
23449
23342
  }
23450
23343
  function conceptIdOf3(relPath) {
23451
- return toPosix10(relPath).slice(PAGES_PREFIX.length).replace(/\.md$/i, "");
23344
+ return toPosix(relPath).slice(PAGES_PREFIX.length).replace(/\.md$/i, "");
23452
23345
  }
23453
23346
  function recognize9(c, file) {
23454
23347
  if (file.ext !== ".md" || !isSnapshotPage(file.relPath))
@@ -23471,7 +23364,7 @@ function recognize9(c, file) {
23471
23364
  ownsPresentation: true,
23472
23365
  type: "website",
23473
23366
  name,
23474
- content: body.length > MAX_CONTENT_CHARS8 ? body.slice(0, MAX_CONTENT_CHARS8) : body
23367
+ content: body
23475
23368
  };
23476
23369
  if (fm.description !== undefined)
23477
23370
  doc.description = fm.description;
@@ -23489,7 +23382,7 @@ async function validate9(c, changes, ctx) {
23489
23382
  continue;
23490
23383
  if (!isSnapshotPage(change.path))
23491
23384
  continue;
23492
- const base3 = await runBaseValidateChecks(toPosix10(change.path), parseFrontmatter(raw), c.root, ctx);
23385
+ const base3 = await runBaseValidateChecks(toPosix(change.path), parseFrontmatter(raw), c.root, ctx);
23493
23386
  diagnostics.push(...base3.filter((d) => d.issue !== "missing-updated"));
23494
23387
  }
23495
23388
  return diagnostics;
@@ -23501,7 +23394,7 @@ var websiteSnapshotAdapter = {
23501
23394
  recognize: recognize9,
23502
23395
  validate: validate9,
23503
23396
  readCandidates(c, conceptId) {
23504
- const canonical = toPosix10(conceptId).replace(/\.md$/i, "");
23397
+ const canonical = toPosix(conceptId).replace(/\.md$/i, "");
23505
23398
  return [{ path: path25.join(c.root, PAGES_PREFIX, `${canonical}.md`), conceptId: canonical }];
23506
23399
  },
23507
23400
  looksLikeRoot(root) {
@@ -28891,7 +28784,7 @@ function upgradeConfigVersion(raw, sourcePath) {
28891
28784
 
28892
28785
  // src/core/config/deep-merge.ts
28893
28786
  var UNSAFE_KEYS3 = new Set(["__proto__", "constructor", "prototype"]);
28894
- function isPlainObject4(value) {
28787
+ function isPlainObject(value) {
28895
28788
  if (value === null || typeof value !== "object" || Array.isArray(value))
28896
28789
  return false;
28897
28790
  const prototype = Object.getPrototypeOf(value);
@@ -28900,7 +28793,7 @@ function isPlainObject4(value) {
28900
28793
  function copyConfigValue(value) {
28901
28794
  if (Array.isArray(value))
28902
28795
  return value.map(copyConfigValue);
28903
- if (!isPlainObject4(value))
28796
+ if (!isPlainObject(value))
28904
28797
  return value;
28905
28798
  const copy = {};
28906
28799
  for (const key of Object.keys(value)) {
@@ -28919,7 +28812,7 @@ function deepMergeConfig(base3, override) {
28919
28812
  if (next === undefined)
28920
28813
  continue;
28921
28814
  const current = result[key];
28922
- result[key] = isPlainObject4(current) && isPlainObject4(next) ? deepMergeConfig(current, next) : copyConfigValue(next);
28815
+ result[key] = isPlainObject(current) && isPlainObject(next) ? deepMergeConfig(current, next) : copyConfigValue(next);
28923
28816
  }
28924
28817
  return result;
28925
28818
  }
@@ -28980,8 +28873,8 @@ function loadUserConfig() {
28980
28873
  }
28981
28874
  function parseAndValidateConfigText(text, sourcePath) {
28982
28875
  const parsedRaw = upgradeConfigVersion(parseConfigText(text, sourcePath), sourcePath);
28983
- const { config: raw, lifted, conflicts } = liftLegacyEngineExtraParams(parsedRaw);
28984
28876
  const where = sourcePath ? ` at ${sourcePath}` : "";
28877
+ const { lifted, conflicts } = liftLegacyEngineExtraParams(parsedRaw);
28985
28878
  if (conflicts.length > 0) {
28986
28879
  const lines = conflicts.map((c) => ` - engines.${c.engine}.extraParams.${c.key} (${JSON.stringify(c.extraParamsValue)}) conflicts with engines.${c.engine}.${c.field} (${JSON.stringify(c.fieldValue)})`).join(`
28987
28880
  `);
@@ -28991,11 +28884,13 @@ ${lines}
28991
28884
  Each extraParams key above has a first-class equivalent and akm will not guess which value you meant — remove the extraParams entry once the field carries the value you want.`, "INVALID_CONFIG_FILE");
28992
28885
  }
28993
28886
  if (lifted.length > 0) {
28994
- warn(`Config${where} uses deprecated extraParams keys with first-class equivalents; treating them as the first-class fields for this run (not written back to the file):
28887
+ throw new ConfigError(`Config${where} uses deprecated extraParams keys with first-class equivalents:
28995
28888
  - ${lifted.join(`
28996
- - `)}`);
28889
+ - `)}
28890
+
28891
+ Run \`akm migrate apply\` to rewrite the config file, or move the values onto the first-class fields yourself.`, "INVALID_CONFIG_FILE");
28997
28892
  }
28998
- const parsed = AkmConfigSchema.safeParse(raw);
28893
+ const parsed = AkmConfigSchema.safeParse(parsedRaw);
28999
28894
  if (!parsed.success) {
29000
28895
  const lines = parsed.error.issues.map((i) => ` - ${i.path.join(".") || "(root)"}: ${i.message}`).join(`
29001
28896
  `);
@@ -29290,6 +29185,9 @@ function createProviderRegistry() {
29290
29185
  resolve(type) {
29291
29186
  return map.get(type) ?? null;
29292
29187
  },
29188
+ unregister(type) {
29189
+ map.delete(type);
29190
+ },
29293
29191
  list() {
29294
29192
  return [...map.keys()];
29295
29193
  }