akm-cli 0.9.5 → 0.9.6

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 (105) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/dist/commands/env/env-cli.js +1 -2
  3. package/dist/commands/env/secret-cli.js +1 -5
  4. package/dist/commands/feedback-cli.js +0 -4
  5. package/dist/commands/health/checks.js +0 -32
  6. package/dist/commands/health/surfaces.js +2 -2
  7. package/dist/commands/health.js +6 -15
  8. package/dist/commands/improve/autonomy-gate.js +1 -1
  9. package/dist/commands/improve/consolidate.js +25 -26
  10. package/dist/commands/improve/distill.js +2 -2
  11. package/dist/commands/improve/extract.js +8 -1
  12. package/dist/commands/improve/improve.js +3 -5
  13. package/dist/commands/improve/locks.js +13 -5
  14. package/dist/commands/improve/loop-stages.js +8 -9
  15. package/dist/commands/improve/memory/memory-contradiction-detect.js +1 -19
  16. package/dist/commands/improve/outcome-loop.js +0 -6
  17. package/dist/commands/improve/reflect.js +20 -9
  18. package/dist/commands/lint/index.js +4 -6
  19. package/dist/commands/proposal/validators/proposal-quality-validators.js +0 -7
  20. package/dist/commands/sources/bundle-config-ops.js +9 -4
  21. package/dist/commands/sources/info.js +14 -10
  22. package/dist/commands/tasks/tasks.js +12 -16
  23. package/dist/commands/workflow-cli.js +2 -2
  24. package/dist/core/common.js +61 -24
  25. package/dist/core/config/config-io.js +2 -2
  26. package/dist/core/config/config-sources.js +32 -2
  27. package/dist/core/config/config.js +1 -1
  28. package/dist/core/config/schema/engines.js +9 -7
  29. package/dist/core/config/schema/primitives.js +0 -5
  30. package/dist/core/config/schema/search.js +2 -1
  31. package/dist/core/file-lock.js +2 -1
  32. package/dist/core/maintenance-barrier.js +2 -14
  33. package/dist/core/paths.js +0 -3
  34. package/dist/core/redaction.js +2 -2
  35. package/dist/core/spawn-env.js +8 -12
  36. package/dist/core/state/migrations.js +1 -12
  37. package/dist/core/state-db.js +9 -27
  38. package/dist/core/write-source.js +12 -19
  39. package/dist/execution/directory-identity.js +36 -10
  40. package/dist/indexer/graph/graph-boost.js +0 -4
  41. package/dist/indexer/index-writer-lock.js +43 -24
  42. package/dist/indexer/index-written-assets.js +5 -6
  43. package/dist/indexer/indexer.js +2 -39
  44. package/dist/indexer/materialize-embeddings.js +85 -41
  45. package/dist/indexer/search/db-search.js +15 -48
  46. package/dist/indexer/search/ranking-contributors.js +0 -25
  47. package/dist/indexer/search/ranking.js +3 -13
  48. package/dist/integrations/agent/builder-shared.js +0 -25
  49. package/dist/integrations/agent/model-map.js +2 -60
  50. package/dist/integrations/harnesses/aider/agent-builder.js +1 -3
  51. package/dist/integrations/harnesses/amazonq/agent-builder.js +2 -7
  52. package/dist/integrations/harnesses/claude/agent-builder.js +1 -4
  53. package/dist/integrations/harnesses/codex/agent-builder.js +1 -4
  54. package/dist/integrations/harnesses/copilot/agent-builder.js +2 -6
  55. package/dist/integrations/harnesses/gemini/agent-builder.js +2 -7
  56. package/dist/integrations/harnesses/opencode/agent-builder.js +1 -4
  57. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +2 -16
  58. package/dist/integrations/harnesses/openhands/agent-builder.js +1 -3
  59. package/dist/integrations/harnesses/pi/agent-builder.js +2 -4
  60. package/dist/integrations/session-logs/index.js +0 -9
  61. package/dist/llm/client.js +75 -42
  62. package/dist/llm/embedder.js +7 -3
  63. package/dist/llm/embedders/remote.js +141 -42
  64. package/dist/registry/network.js +5 -37
  65. package/dist/runtime.js +2 -10
  66. package/dist/scripts/akm-migrate-node.js +60 -126
  67. package/dist/scripts/akm-migrate.js +60 -126
  68. package/dist/setup/engine-config.js +2 -5
  69. package/dist/setup/registry-stash-loader.js +0 -8
  70. package/dist/setup/setup.js +9 -46
  71. package/dist/setup/steps/connection-shared.js +10 -13
  72. package/dist/sources/providers/git-install.js +1 -1
  73. package/dist/storage/engines/sqlite-migrations.js +20 -1
  74. package/dist/storage/repositories/index-entries-repository.js +0 -15
  75. package/dist/tasks/backends/launchd.js +15 -20
  76. package/dist/tasks/backends/schtasks.js +18 -8
  77. package/dist/tasks/run/run-native-task.js +8 -6
  78. package/dist/tasks/source/bounded-document.js +2 -4
  79. package/dist/tasks/source/task-source-v3-frozen.js +5 -7
  80. package/dist/tasks/source/task-source-v4.js +5 -10
  81. package/dist/tasks/source/task-to-v3.js +5 -10
  82. package/dist/tasks/source/task-to-v4.js +1 -4
  83. package/dist/tasks/source-v3.js +6 -6
  84. package/dist/workflows/exec/native-executor.js +21 -31
  85. package/dist/workflows/exec/run-workflow.js +5 -6
  86. package/dist/workflows/exec/scheduler.js +3 -19
  87. package/dist/workflows/exec/step-work.js +1 -4
  88. package/dist/workflows/exec/unit-dispatch.js +2 -2
  89. package/dist/workflows/exec/worktree.js +1 -13
  90. package/dist/workflows/freeze/targets/child-workflow.js +2 -10
  91. package/dist/workflows/ir/plan-hash.js +4 -6
  92. package/dist/workflows/ir/schema-v4.js +0 -12
  93. package/dist/workflows/ir/schema.js +20 -31
  94. package/dist/workflows/parser.js +11 -52
  95. package/dist/workflows/renderer.js +2 -3
  96. package/dist/workflows/resource-limits.js +11 -41
  97. package/dist/workflows/runtime/runs.js +3 -4
  98. package/dist/workflows/source-ir/schema.js +14 -30
  99. package/dist/workflows/validator.js +1 -7
  100. package/docs/reference/configuration.md +1 -1
  101. package/package.json +1 -1
  102. package/schemas/akm-config.json +4 -23
  103. package/schemas/akm-task.json +1 -2
  104. package/schemas/akm-workflow.json +1 -13
  105. package/dist/indexer/search/semantic-status.js +0 -142
@@ -9379,8 +9379,6 @@ function getRegistryIndexCacheDir() {
9379
9379
  }
9380
9380
 
9381
9381
  // src/core/common.ts
9382
- var MAX_CONFIG_FILE_BYTES = 1024 * 1024;
9383
- var MAX_LOCAL_METADATA_BYTES = 1024 * 1024;
9384
9382
  var MAX_LOCK_METADATA_BYTES = 64 * 1024;
9385
9383
  function readTextFileDescriptorWithLimit(fd, maxBytes, label = "File", displayPath = "(open file)") {
9386
9384
  const stat = fs.fstatSync(fd);
@@ -9402,10 +9400,13 @@ function readTextFileDescriptorWithLimit(fd, maxBytes, label = "File", displayPa
9402
9400
  }
9403
9401
  return buffer.subarray(0, total).toString("utf8");
9404
9402
  }
9405
- function readTextFileWithLimit(filePath, maxBytes, label = "File") {
9403
+ function readTextFile(filePath, label = "File") {
9406
9404
  const fd = fs.openSync(filePath, "r");
9407
9405
  try {
9408
- return readTextFileDescriptorWithLimit(fd, maxBytes, label, filePath);
9406
+ const stat = fs.fstatSync(fd);
9407
+ if (!stat.isFile())
9408
+ throw new ConfigError(`${label} is not a regular file: ${filePath}.`, "INVALID_CONFIG_FILE");
9409
+ return fs.readFileSync(fd, "utf8");
9409
9410
  } finally {
9410
9411
  fs.closeSync(fd);
9411
9412
  }
@@ -9505,6 +9506,8 @@ function asNonEmptyString(value) {
9505
9506
  return trimmed.length > 0 ? trimmed : undefined;
9506
9507
  }
9507
9508
  function isProcessAlive(pid) {
9509
+ if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0)
9510
+ return false;
9508
9511
  try {
9509
9512
  process.kill(pid, 0);
9510
9513
  return true;
@@ -14879,25 +14882,13 @@ var EXECUTION_MAX_TIMEOUT_MS = 2 ** 31 - 1;
14879
14882
  // src/workflows/resource-limits.ts
14880
14883
  var WORKFLOW_MAX_PLAN_BYTES = 2 * 1024 * 1024;
14881
14884
  var WORKFLOW_MAX_SOURCE_BYTES = 1024 * 1024;
14882
- var WORKFLOW_MAX_STEPS = 256;
14883
- var WORKFLOW_MAX_PARAMS = 128;
14884
- var WORKFLOW_MAX_ROUTE_BRANCHES = 256;
14885
14885
  var WORKFLOW_MAX_INSTRUCTION_BYTES = 256 * 1024;
14886
14886
  var WORKFLOW_MAX_SCHEMA_BYTES = 256 * 1024;
14887
14887
  var WORKFLOW_MAX_EXTRA_PARAMS_BYTES = 64 * 1024;
14888
- var WORKFLOW_MAX_MAP_EXPANSION = 1e4;
14889
- var WORKFLOW_MAX_INPUTS = 64;
14890
- var WORKFLOW_MAX_OUTPUTS = 64;
14891
14888
  var WORKFLOW_MAX_CONCURRENCY = 64;
14892
- var WORKFLOW_MAX_GATE_LOOPS = 100;
14893
- var WORKFLOW_MAX_RETRIES = 100;
14894
14889
  var WORKFLOW_MAX_TIMEOUT_MS = EXECUTION_MAX_TIMEOUT_MS;
14895
14890
  var WORKFLOW_ENGINE_NAME_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
14896
14891
  var WORKFLOW_MAX_ENGINE_NAME_LENGTH = 63;
14897
- var WORKFLOW_MAX_EXEC_ARGV = 64;
14898
- var WORKFLOW_MAX_EXEC_ARG_BYTES = 4096;
14899
- var WORKFLOW_MAX_EXEC_CWD_LENGTH = 1024;
14900
- var WORKFLOW_MAX_EXEC_PASS_ENV = 32;
14901
14892
  var WORKFLOW_ENV_VAR_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
14902
14893
  var WORKFLOW_MAX_EXEC_OUTPUT_BYTES = 8 * 1024 * 1024;
14903
14894
  var EXEC_CONTEXT_LIMITS_POSIX = {
@@ -14915,13 +14906,13 @@ function jsonBytes(value) {
14915
14906
  var WORKFLOW_MAX_EMBEDDED_CHILD_PLAN_BYTES = 1024 * 1024;
14916
14907
 
14917
14908
  // src/tasks/source/bounded-document.ts
14918
- var TASK_V3_MAX_SOURCE_BYTES = 1024 * 1024;
14919
14909
  var TASK_V3_MAX_JSON_DEPTH = 64;
14920
14910
  var TASK_V3_MAX_JSON_NODES = 1e4;
14921
14911
  var TASK_V3_MAX_COLLECTION_ITEMS = 1024;
14922
14912
  var TASK_V3_MAX_OBJECT_KEYS = 256;
14923
14913
  var TASK_V3_MAX_STRING_BYTES = 256 * 1024;
14924
14914
  var TASK_V3_MAX_SCHEDULES = 64;
14915
+ var TASK_V3_MAX_REDACT_NAMES = 32;
14925
14916
  function own2(value, key) {
14926
14917
  return Object.hasOwn(value, key);
14927
14918
  }
@@ -15210,9 +15201,6 @@ function readBoundedTaskSourceYaml(input, options) {
15210
15201
  if (typeof input.yaml !== "string") {
15211
15202
  throw new UsageError(`Invalid ${sourceLabel} at ${input.filePath}: source must be a string.`, "TASK_SOURCE_INVALID");
15212
15203
  }
15213
- if (utf8Bytes2(input.yaml) > TASK_V3_MAX_SOURCE_BYTES) {
15214
- throw new UsageError(`Invalid ${sourceLabel} at ${input.filePath}: source exceeds the 1 MiB (${TASK_V3_MAX_SOURCE_BYTES}-byte) resource limit.`, "TASK_SOURCE_INVALID");
15215
- }
15216
15204
  const lineCounter2 = new $LineCounter;
15217
15205
  let document;
15218
15206
  try {
@@ -15972,7 +15960,7 @@ function parseExecutionControls(input, ctx) {
15972
15960
  out.timeout = parseTimeoutTopLevel(input.timeout, ctx);
15973
15961
  if (own2(input, "redact")) {
15974
15962
  const names = parseStringArray(input.redact, ctx, ["redact"], {
15975
- max: WORKFLOW_MAX_EXEC_PASS_ENV,
15963
+ max: TASK_V3_MAX_REDACT_NAMES,
15976
15964
  pattern: WORKFLOW_ENV_VAR_NAME_PATTERN
15977
15965
  });
15978
15966
  if (new Set(names).size !== names.length)
@@ -15986,8 +15974,8 @@ function parseExecutionControls(input, ctx) {
15986
15974
  out.maxSteps = input.maxSteps;
15987
15975
  }
15988
15976
  if (own2(input, "maxRetries")) {
15989
- if (!Number.isSafeInteger(input.maxRetries) || input.maxRetries < 0 || input.maxRetries > WORKFLOW_MAX_RETRIES) {
15990
- sourceError(ctx, ["maxRetries"], `must be an integer from 0 through ${WORKFLOW_MAX_RETRIES}.`);
15977
+ if (!Number.isSafeInteger(input.maxRetries) || input.maxRetries < 0) {
15978
+ sourceError(ctx, ["maxRetries"], "must be a non-negative safe integer.");
15991
15979
  }
15992
15980
  out.maxRetries = input.maxRetries;
15993
15981
  }
@@ -16047,9 +16035,6 @@ function parseInputDeclaration(name, raw, ctx) {
16047
16035
  function parseInputDeclarations(value, ctx) {
16048
16036
  const input = asRecord(value, ctx, ["inputs"]);
16049
16037
  const names = Object.keys(input);
16050
- if (names.length > WORKFLOW_MAX_PARAMS) {
16051
- sourceError(ctx, ["inputs"], `accepts at most ${WORKFLOW_MAX_PARAMS} declared inputs.`);
16052
- }
16053
16038
  const result = {};
16054
16039
  for (const name of names) {
16055
16040
  if (!INPUT_NAME_PATTERN.test(name)) {
@@ -16482,7 +16467,7 @@ function parseAkm(value, ctx) {
16482
16467
  out.timeout = parseTimeout(input.timeout, ctx);
16483
16468
  if (own2(input, "redact")) {
16484
16469
  const names = parseStringArray(input.redact, ctx, ["akm", "redact"], {
16485
- max: WORKFLOW_MAX_EXEC_PASS_ENV,
16470
+ max: TASK_V3_MAX_REDACT_NAMES,
16486
16471
  pattern: WORKFLOW_ENV_VAR_NAME_PATTERN
16487
16472
  });
16488
16473
  if (new Set(names).size !== names.length)
@@ -16496,8 +16481,8 @@ function parseAkm(value, ctx) {
16496
16481
  out.maxSteps = input.maxSteps;
16497
16482
  }
16498
16483
  if (own2(input, "maxRetries")) {
16499
- if (!Number.isSafeInteger(input.maxRetries) || input.maxRetries < 0 || input.maxRetries > WORKFLOW_MAX_RETRIES) {
16500
- sourceError(ctx, ["akm", "maxRetries"], `must be an integer from 0 through ${WORKFLOW_MAX_RETRIES}.`);
16484
+ if (!Number.isSafeInteger(input.maxRetries) || input.maxRetries < 0) {
16485
+ sourceError(ctx, ["akm", "maxRetries"], "must be a non-negative safe integer.");
16501
16486
  }
16502
16487
  out.maxRetries = input.maxRetries;
16503
16488
  }
@@ -16814,9 +16799,6 @@ function optionalString(value, label) {
16814
16799
  return exactString(value, label);
16815
16800
  }
16816
16801
  function parseLegacyTaskYaml(input) {
16817
- if (input.bytes.byteLength > TASK_V3_MAX_SOURCE_BYTES) {
16818
- throw new Error(`task YAML exceeds the 1 MiB (${TASK_V3_MAX_SOURCE_BYTES}-byte) source resource limit`);
16819
- }
16820
16802
  let source;
16821
16803
  try {
16822
16804
  source = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(input.bytes);
@@ -16864,7 +16846,7 @@ function validateCommonV2(data) {
16864
16846
  }
16865
16847
  }
16866
16848
  if (data.redact !== undefined && data.redact !== null) {
16867
- if (!Array.isArray(data.redact) || data.redact.length > WORKFLOW_MAX_EXEC_PASS_ENV || data.redact.some((entry) => typeof entry !== "string" || !WORKFLOW_ENV_VAR_NAME_PATTERN.test(entry))) {
16849
+ if (!Array.isArray(data.redact) || data.redact.length > TASK_V3_MAX_REDACT_NAMES || data.redact.some((entry) => typeof entry !== "string" || !WORKFLOW_ENV_VAR_NAME_PATTERN.test(entry))) {
16868
16850
  throw new Error("redact must contain only bounded environment variable names");
16869
16851
  }
16870
16852
  }
@@ -16990,8 +16972,8 @@ function migratedObject(data) {
16990
16972
  akm.maxSteps = data.maxSteps;
16991
16973
  }
16992
16974
  if (data.maxRetries !== undefined && data.maxRetries !== null) {
16993
- if (!Number.isSafeInteger(data.maxRetries) || data.maxRetries < 0 || data.maxRetries > WORKFLOW_MAX_RETRIES) {
16994
- throw new Error(`maxRetries must be from 0 through ${WORKFLOW_MAX_RETRIES}`);
16975
+ if (!Number.isSafeInteger(data.maxRetries) || data.maxRetries < 0) {
16976
+ throw new Error("maxRetries must be a non-negative integer");
16995
16977
  }
16996
16978
  akm.maxRetries = data.maxRetries;
16997
16979
  }
@@ -17250,9 +17232,6 @@ function exactString2(value, label, nonempty = false) {
17250
17232
  return value;
17251
17233
  }
17252
17234
  function parseV3RawYaml(input) {
17253
- if (input.bytes.byteLength > TASK_V3_MAX_SOURCE_BYTES) {
17254
- throw new Error(`task YAML exceeds the 1 MiB (${TASK_V3_MAX_SOURCE_BYTES}-byte) source resource limit`);
17255
- }
17256
17235
  let source;
17257
17236
  try {
17258
17237
  source = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(input.bytes);
@@ -18453,7 +18432,7 @@ function validateStep(value, jobId, index, stepIds, options) {
18453
18432
  }
18454
18433
  validateMap(step.map, `step ${id} map`);
18455
18434
  validateRoute(step.route, `step ${id} route`);
18456
- optionalStringList(step.inputs, `step ${id} inputs`, WORKFLOW_MAX_INPUTS);
18435
+ optionalStringList(step.inputs, `step ${id} inputs`, Infinity);
18457
18436
  if (Array.isArray(step.inputs)) {
18458
18437
  for (const [inputIndex, input] of step.inputs.entries())
18459
18438
  validateReference(input, `step ${id} inputs[${inputIndex}]`);
@@ -18475,12 +18454,7 @@ function validateExec(value, location, options) {
18475
18454
  return;
18476
18455
  const exec = record(value, location);
18477
18456
  keys(exec, ["command", "cwd", "passEnv"], location);
18478
- stringList(exec.command, `${location}.command`, WORKFLOW_MAX_EXEC_ARGV, false);
18479
- for (const [index, argument] of exec.command.entries()) {
18480
- if (utf8Bytes(argument) > WORKFLOW_MAX_EXEC_ARG_BYTES) {
18481
- fail2(`${location}.command[${index}] exceeds ${WORKFLOW_MAX_EXEC_ARG_BYTES} bytes`);
18482
- }
18483
- }
18457
+ stringList(exec.command, `${location}.command`, Infinity, false);
18484
18458
  try {
18485
18459
  rejectNulInArgv(exec.command);
18486
18460
  } catch (cause) {
@@ -18488,9 +18462,6 @@ function validateExec(value, location, options) {
18488
18462
  }
18489
18463
  optionalString2(exec.cwd, `${location}.cwd`);
18490
18464
  if (exec.cwd !== undefined) {
18491
- if (exec.cwd.length > WORKFLOW_MAX_EXEC_CWD_LENGTH) {
18492
- fail2(`${location}.cwd exceeds ${WORKFLOW_MAX_EXEC_CWD_LENGTH} characters`);
18493
- }
18494
18465
  try {
18495
18466
  exec.cwd = canonicalizeWorkflowWorkingDirectory(exec.cwd, options.workspaceRoot);
18496
18467
  } catch (cause) {
@@ -18498,7 +18469,7 @@ function validateExec(value, location, options) {
18498
18469
  }
18499
18470
  }
18500
18471
  if (exec.passEnv !== undefined) {
18501
- stringList(exec.passEnv, `${location}.passEnv`, WORKFLOW_MAX_EXEC_PASS_ENV, false);
18472
+ stringList(exec.passEnv, `${location}.passEnv`, Infinity, false);
18502
18473
  }
18503
18474
  if (Array.isArray(exec.passEnv)) {
18504
18475
  for (const name of exec.passEnv) {
@@ -18549,8 +18520,8 @@ function validateRetry(value, location) {
18549
18520
  return;
18550
18521
  const retry = record(value, location);
18551
18522
  keys(retry, ["max", "on"], location);
18552
- if (!Number.isSafeInteger(retry.max) || retry.max < 0 || retry.max > WORKFLOW_MAX_RETRIES) {
18553
- fail2(`${location}.max must be an integer from 0 through ${WORKFLOW_MAX_RETRIES}`);
18523
+ if (!Number.isSafeInteger(retry.max) || retry.max < 0) {
18524
+ fail2(`${location}.max must be a non-negative integer`);
18554
18525
  }
18555
18526
  stringList(retry.on, `${location}.on`, PROGRAM_RETRY_REASONS.length, false);
18556
18527
  for (const reason of retry.on) {
@@ -18580,8 +18551,8 @@ function validateRoute(value, location) {
18580
18551
  keys(route, ["input", "branches", "defaultStepId"], location);
18581
18552
  nonEmptyString2(route.input, `${location}.input`);
18582
18553
  validateReference(route.input, `${location}.input`);
18583
- if (!Array.isArray(route.branches) || route.branches.length === 0 || route.branches.length > WORKFLOW_MAX_ROUTE_BRANCHES) {
18584
- fail2(`${location}.branches must contain 1 through ${WORKFLOW_MAX_ROUTE_BRANCHES} entries`);
18554
+ if (!Array.isArray(route.branches) || route.branches.length === 0) {
18555
+ fail2(`${location}.branches must be a non-empty array`);
18585
18556
  }
18586
18557
  const matches = new Set;
18587
18558
  for (const [index, value2] of route.branches.entries()) {
@@ -18601,8 +18572,8 @@ function validateGate(value, location) {
18601
18572
  return;
18602
18573
  const gate = record(value, location);
18603
18574
  keys(gate, ["maxLoops", "rubric"], location);
18604
- if (gate.maxLoops !== undefined && (!Number.isSafeInteger(gate.maxLoops) || gate.maxLoops < 1 || gate.maxLoops > WORKFLOW_MAX_GATE_LOOPS)) {
18605
- fail2(`${location}.maxLoops must be an integer from 1 through ${WORKFLOW_MAX_GATE_LOOPS}`);
18575
+ if (gate.maxLoops !== undefined && (!Number.isSafeInteger(gate.maxLoops) || gate.maxLoops < 1)) {
18576
+ fail2(`${location}.maxLoops must be an integer of at least 1`);
18606
18577
  }
18607
18578
  optionalString2(gate.rubric, `${location}.rubric`);
18608
18579
  }
@@ -18635,8 +18606,8 @@ function validateParams(value) {
18635
18606
  if (value === undefined)
18636
18607
  return;
18637
18608
  const params = record(value, "params");
18638
- if (Object.keys(params).length === 0 || Object.keys(params).length > WORKFLOW_MAX_PARAMS) {
18639
- fail2(`params must contain 1 through ${WORKFLOW_MAX_PARAMS} entries`);
18609
+ if (Object.keys(params).length === 0) {
18610
+ fail2(`params must contain at least one entry`);
18640
18611
  }
18641
18612
  for (const [name, schema] of Object.entries(params)) {
18642
18613
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))
@@ -18648,8 +18619,8 @@ function validateOutputs(value) {
18648
18619
  if (value === undefined)
18649
18620
  return;
18650
18621
  const outputs = record(value, "outputs");
18651
- if (Object.keys(outputs).length === 0 || Object.keys(outputs).length > WORKFLOW_MAX_OUTPUTS) {
18652
- fail2(`outputs must contain 1 through ${WORKFLOW_MAX_OUTPUTS} entries`);
18622
+ if (Object.keys(outputs).length === 0) {
18623
+ fail2(`outputs must contain at least one entry`);
18653
18624
  }
18654
18625
  for (const [name, declaration] of Object.entries(outputs)) {
18655
18626
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))
@@ -18672,9 +18643,6 @@ function validateBudget(value) {
18672
18643
  fail2(`budget.${key} must be a positive integer`);
18673
18644
  }
18674
18645
  }
18675
- if (typeof budget.maxUnits === "number" && budget.maxUnits > WORKFLOW_MAX_MAP_EXPANSION) {
18676
- fail2(`budget.maxUnits must be at most ${WORKFLOW_MAX_MAP_EXPANSION}`);
18677
- }
18678
18646
  }
18679
18647
  function validateLlm(value, location) {
18680
18648
  if (value === undefined)
@@ -19258,12 +19226,6 @@ function checkXrefs(value, line, errors2) {
19258
19226
  }
19259
19227
  }
19260
19228
  function checkResourceLimits(draft, errors2) {
19261
- if (draft.steps.length > WORKFLOW_MAX_STEPS) {
19262
- errors2.push({ line: 1, message: `Workflow must contain at most ${WORKFLOW_MAX_STEPS} steps.` });
19263
- }
19264
- if (Object.keys(draft.params ?? {}).length > WORKFLOW_MAX_PARAMS) {
19265
- errors2.push({ line: 1, message: `Workflow must contain at most ${WORKFLOW_MAX_PARAMS} parameters.` });
19266
- }
19267
19229
  for (const step of draft.steps) {
19268
19230
  if (step.instructions && utf8Bytes(step.instructions.text) > WORKFLOW_MAX_INSTRUCTION_BYTES) {
19269
19231
  errors2.push({
@@ -19625,9 +19587,6 @@ function parseParams(ctx, raw) {
19625
19587
  ctx.err(["params"], `"params" must be a mapping of param name to a JSON Schema object (e.g. changed_files: { type: array }).`);
19626
19588
  return;
19627
19589
  }
19628
- if (Object.keys(raw).length > WORKFLOW_MAX_PARAMS) {
19629
- ctx.err(["params"], `"params" must contain at most ${WORKFLOW_MAX_PARAMS} entries.`);
19630
- }
19631
19590
  const params = {};
19632
19591
  for (const [paramName, value] of Object.entries(raw)) {
19633
19592
  if (!INPUT_NAME_PATTERN.test(paramName)) {
@@ -19653,9 +19612,6 @@ function parseOutputs(ctx, raw) {
19653
19612
  ctx.err(["outputs"], `"outputs" must be a mapping of output name to { from, schema? } (e.g. report: { from: steps.summarize.output }).`);
19654
19613
  return;
19655
19614
  }
19656
- if (Object.keys(raw).length > WORKFLOW_MAX_OUTPUTS) {
19657
- ctx.err(["outputs"], `"outputs" must contain at most ${WORKFLOW_MAX_OUTPUTS} entries.`);
19658
- }
19659
19615
  const outputs = {};
19660
19616
  for (const [outputName, value] of Object.entries(raw)) {
19661
19617
  const path13 = ["outputs", outputName];
@@ -19747,10 +19703,10 @@ function parseBudget(ctx, raw) {
19747
19703
  }
19748
19704
  }
19749
19705
  if (raw.max_units !== undefined) {
19750
- if (typeof raw.max_units === "number" && Number.isInteger(raw.max_units) && raw.max_units >= 1 && raw.max_units <= WORKFLOW_MAX_MAP_EXPANSION) {
19706
+ if (typeof raw.max_units === "number" && Number.isInteger(raw.max_units) && raw.max_units >= 1) {
19751
19707
  budget.maxUnits = raw.max_units;
19752
19708
  } else {
19753
- ctx.err([...path13, "max_units"], `"budget.max_units" must be an integer from 1 through ${WORKFLOW_MAX_MAP_EXPANSION}.`);
19709
+ ctx.err([...path13, "max_units"], `"budget.max_units" must be an integer >= 1.`);
19754
19710
  }
19755
19711
  }
19756
19712
  return Object.keys(budget).length > 0 ? budget : undefined;
@@ -19760,9 +19716,6 @@ function parseSteps(ctx, raw) {
19760
19716
  ctx.err(["steps"], `"steps" is required and must be a list with at least one step.`);
19761
19717
  return [];
19762
19718
  }
19763
- if (raw.length > WORKFLOW_MAX_STEPS) {
19764
- ctx.err(["steps"], `"steps" must contain at most ${WORKFLOW_MAX_STEPS} entries.`);
19765
- }
19766
19719
  const idIndex = new Map;
19767
19720
  raw.forEach((rawStep, index) => {
19768
19721
  if (isPlainRecord(rawStep) && typeof rawStep.id === "string" && !idIndex.has(rawStep.id)) {
@@ -19933,10 +19886,6 @@ function parseExecPassEnv(ctx, raw, path13, stepLabel) {
19933
19886
  ctx.err(path13, `${stepLabel} "exec.pass_env" must be a non-empty list of environment variable NAMES to copy through from ` + `akm's own environment, e.g. pass_env: [CARGO_HOME]. Values never appear here \u2014 use "env:" bindings for those.`);
19934
19887
  return;
19935
19888
  }
19936
- if (raw.length > WORKFLOW_MAX_EXEC_PASS_ENV) {
19937
- ctx.err(path13, `${stepLabel} "exec.pass_env" must have at most ${WORKFLOW_MAX_EXEC_PASS_ENV} entries. A command needing ` + `more than that should use explicit named "env:" bindings instead.`);
19938
- return;
19939
- }
19940
19889
  const names = [];
19941
19890
  for (const [index, entry] of raw.entries()) {
19942
19891
  if (typeof entry !== "string" || !WORKFLOW_ENV_VAR_NAME_PATTERN.test(entry)) {
@@ -19956,10 +19905,6 @@ function parseExecCommand(ctx, raw, path13, stepLabel) {
19956
19905
  ctx.err(path13, `${stepLabel} "exec" requires "command": a non-empty argv list, e.g. command: ["bun", "run", "test:unit"]. ` + `A single shell string is not accepted \u2014 the command is spawned directly, never through a shell.`);
19957
19906
  return;
19958
19907
  }
19959
- if (raw.length > WORKFLOW_MAX_EXEC_ARGV) {
19960
- ctx.err(path13, `${stepLabel} "exec.command" must have at most ${WORKFLOW_MAX_EXEC_ARGV} entries.`);
19961
- return;
19962
- }
19963
19908
  const argv = [];
19964
19909
  for (const [index, entry] of raw.entries()) {
19965
19910
  if (typeof entry !== "string" || entry === "") {
@@ -19970,10 +19915,6 @@ function parseExecCommand(ctx, raw, path13, stepLabel) {
19970
19915
  ctx.err([...path13, index], `${stepLabel} "exec.command[${index}]" may not contain NUL bytes.`);
19971
19916
  return;
19972
19917
  }
19973
- if (utf8Bytes(entry) > WORKFLOW_MAX_EXEC_ARG_BYTES) {
19974
- ctx.err(path13, `${stepLabel} "exec.command[${index}]" exceeds ${WORKFLOW_MAX_EXEC_ARG_BYTES} bytes.`);
19975
- return;
19976
- }
19977
19918
  argv.push(entry);
19978
19919
  }
19979
19920
  return argv;
@@ -19986,10 +19927,6 @@ function parseExecCwd(ctx, raw, path13, stepLabel) {
19986
19927
  return;
19987
19928
  }
19988
19929
  const value = raw.trim();
19989
- if (value.length > WORKFLOW_MAX_EXEC_CWD_LENGTH) {
19990
- ctx.err(path13, `${stepLabel} "exec.cwd" exceeds ${WORKFLOW_MAX_EXEC_CWD_LENGTH} characters.`);
19991
- return;
19992
- }
19993
19930
  if (!isContainedRelativePath(value)) {
19994
19931
  ctx.err(path13, `${stepLabel} "exec.cwd" (${JSON.stringify(value)}) must be a RELATIVE path inside the unit's working ` + `directory \u2014 absolute paths, Windows drive letters, "~", and ".." segments are rejected.`);
19995
19932
  return;
@@ -20023,10 +19960,10 @@ function parseMap(ctx, raw, path13, stepLabel) {
20023
19960
  }
20024
19961
  let concurrency;
20025
19962
  if (raw.concurrency !== undefined) {
20026
- if (typeof raw.concurrency === "number" && Number.isInteger(raw.concurrency) && raw.concurrency > 0 && raw.concurrency <= WORKFLOW_MAX_CONCURRENCY) {
20027
- concurrency = raw.concurrency;
19963
+ if (typeof raw.concurrency === "number" && Number.isInteger(raw.concurrency) && raw.concurrency > 0) {
19964
+ concurrency = Math.min(raw.concurrency, WORKFLOW_MAX_CONCURRENCY);
20028
19965
  } else {
20029
- ctx.err([...path13, "concurrency"], `${stepLabel} "concurrency" must be an integer from 1 through ${WORKFLOW_MAX_CONCURRENCY}.`);
19966
+ ctx.err([...path13, "concurrency"], `${stepLabel} "concurrency" must be a positive integer.`);
20030
19967
  }
20031
19968
  }
20032
19969
  const reducer = parseEnumField(ctx, raw.reducer, [...path13, "reducer"], `${stepLabel} "reducer"`, PROGRAM_REDUCERS);
@@ -20058,9 +19995,6 @@ function parseRoute(ctx, raw, path13, stepLabel, stepIndex, routeChecks) {
20058
19995
  if (!Array.isArray(raw.when) || raw.when.length === 0) {
20059
19996
  ctx.err(whenPath, `${stepLabel} "route" requires "when": a non-empty list of { match, step } branches (e.g. when: [{ match: pass, step: ship }]).`);
20060
19997
  } else {
20061
- if (raw.when.length > WORKFLOW_MAX_ROUTE_BRANCHES) {
20062
- ctx.err(whenPath, `${stepLabel} "when" must contain at most ${WORKFLOW_MAX_ROUTE_BRANCHES} branches.`);
20063
- }
20064
19998
  const seenMatches = new Map;
20065
19999
  raw.when.forEach((branch, i) => {
20066
20000
  const branchPath = [...whenPath, i];
@@ -20116,9 +20050,6 @@ function parseInputs(ctx, raw, path13, stepLabel) {
20116
20050
  ctx.err(path13, `${stepLabel} "inputs" must be a non-empty list of reference strings.`);
20117
20051
  return;
20118
20052
  }
20119
- if (raw.length > WORKFLOW_MAX_INPUTS) {
20120
- ctx.err(path13, `${stepLabel} "inputs" must contain at most ${WORKFLOW_MAX_INPUTS} entries.`);
20121
- }
20122
20053
  const out = [];
20123
20054
  const seen = new Set;
20124
20055
  raw.forEach((entry, i) => {
@@ -20145,10 +20076,10 @@ function parseGate(ctx, raw, path13, stepLabel) {
20145
20076
  checkUnknownKeys(ctx, raw, path13, GATE_KEYS, `${stepLabel} "gate"`);
20146
20077
  const gate = {};
20147
20078
  if (raw.max_loops !== undefined) {
20148
- if (typeof raw.max_loops === "number" && Number.isInteger(raw.max_loops) && raw.max_loops >= 1 && raw.max_loops <= WORKFLOW_MAX_GATE_LOOPS) {
20079
+ if (typeof raw.max_loops === "number" && Number.isInteger(raw.max_loops) && raw.max_loops >= 1) {
20149
20080
  gate.maxLoops = raw.max_loops;
20150
20081
  } else {
20151
- ctx.err([...path13, "max_loops"], `${stepLabel} "gate.max_loops" must be an integer from 1 through ${WORKFLOW_MAX_GATE_LOOPS}.`);
20082
+ ctx.err([...path13, "max_loops"], `${stepLabel} "gate.max_loops" must be an integer of at least 1.`);
20152
20083
  }
20153
20084
  }
20154
20085
  return gate;
@@ -20174,8 +20105,8 @@ function parseRetry(ctx, raw, path13, stepLabel) {
20174
20105
  }
20175
20106
  checkUnknownKeys(ctx, raw, path13, RETRY_KEYS, `${stepLabel} "retry"`);
20176
20107
  let ok = true;
20177
- if (!(typeof raw.max === "number" && Number.isInteger(raw.max) && raw.max >= 0 && raw.max <= WORKFLOW_MAX_RETRIES)) {
20178
- ctx.err([...path13, "max"], `${stepLabel} "retry.max" is required and must be an integer from 0 through ${WORKFLOW_MAX_RETRIES}.`);
20108
+ if (!(typeof raw.max === "number" && Number.isInteger(raw.max) && raw.max >= 0)) {
20109
+ ctx.err([...path13, "max"], `${stepLabel} "retry.max" is required and must be a non-negative integer.`);
20179
20110
  ok = false;
20180
20111
  }
20181
20112
  const on = [];
@@ -23763,7 +23694,7 @@ function withLockOperationMutex(lockPath, run) {
23763
23694
  db.exec("BEGIN IMMEDIATE");
23764
23695
  began = db.inTransaction;
23765
23696
  if (!began)
23766
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 2 ** attempt);
23697
+ sleepSync(2 ** attempt);
23767
23698
  }
23768
23699
  if (!began)
23769
23700
  throw new Error(`Could not acquire lock operation mutex for ${lockPath}.`);
@@ -23926,7 +23857,7 @@ function extractHolderPid(content) {
23926
23857
  // src/core/config/config-io.ts
23927
23858
  function readConfigText(configPath) {
23928
23859
  try {
23929
- return readTextFileWithLimit(configPath, MAX_CONFIG_FILE_BYTES, "Config file");
23860
+ return readTextFile(configPath, "Config file");
23930
23861
  } catch (err) {
23931
23862
  if (err.code === "ENOENT")
23932
23863
  return;
@@ -28033,9 +27964,6 @@ var ExtraParamsSchema = exports_external.record(exports_external.unknown()).supe
28033
27964
  ctx.addIssue({ code: exports_external.ZodIssueCode.custom, path: issue.path, message: issue.message });
28034
27965
  }
28035
27966
  });
28036
- var LlmCapabilitiesSchema = exports_external.object({
28037
- structuredOutput: exports_external.boolean().optional()
28038
- }).passthrough();
28039
27967
  var LlmInvocationOverridesSchema = exports_external.object({
28040
27968
  temperature: exports_external.number().finite().optional(),
28041
27969
  maxTokens: positiveInt.optional(),
@@ -28091,15 +28019,13 @@ var LlmConnectionConfigSchema = exports_external.object({
28091
28019
  maxTokens: positiveInt.optional(),
28092
28020
  timeoutMs: timeoutMsField,
28093
28021
  concurrency: positiveInt.optional(),
28094
- capabilities: LlmCapabilitiesSchema.optional(),
28022
+ supportsJsonSchema: exports_external.boolean().optional(),
28095
28023
  extraParams: ExtraParamsSchema.optional(),
28096
28024
  contextLength: positiveInt.optional(),
28097
28025
  enableThinking: exports_external.boolean().optional(),
28098
28026
  reasoningEffort: nonEmptyString3.optional()
28099
28027
  }).passthrough();
28100
- var LlmProfileConfigSchema = LlmConnectionConfigSchema.extend({
28101
- supportsJsonSchema: exports_external.boolean().optional()
28102
- }).passthrough();
28028
+ var LlmProfileConfigSchema = LlmConnectionConfigSchema.passthrough();
28103
28029
  var AgentPlatformSchema = exports_external.enum(VALID_HARNESS_IDS);
28104
28030
  var LlmEngineSchema = exports_external.object({
28105
28031
  kind: exports_external.literal("llm"),
@@ -28111,7 +28037,6 @@ var LlmEngineSchema = exports_external.object({
28111
28037
  maxTokens: positiveInt.optional(),
28112
28038
  timeoutMs: timeoutMsField,
28113
28039
  concurrency: positiveInt.optional(),
28114
- supportsJsonSchema: exports_external.boolean().optional(),
28115
28040
  extraParams: ExtraParamsSchema.optional(),
28116
28041
  contextLength: positiveInt.optional(),
28117
28042
  enableThinking: exports_external.boolean().optional(),
@@ -28141,7 +28066,6 @@ var AgentEngineSchema = exports_external.object({
28141
28066
  "temperature",
28142
28067
  "maxTokens",
28143
28068
  "concurrency",
28144
- "supportsJsonSchema",
28145
28069
  "extraParams",
28146
28070
  "contextLength",
28147
28071
  "enableThinking",
@@ -28507,7 +28431,7 @@ var SearchGraphBoostSchema = exports_external.object({
28507
28431
  hopBoostPerEntity: nonNegativeNumber.optional(),
28508
28432
  hopBoostCap: nonNegativeNumber.optional(),
28509
28433
  maxHops: positiveInt.max(3).optional(),
28510
- confidenceMode: exports_external.enum(["off", "blend", "multiply"]).default("blend").optional(),
28434
+ confidenceMode: exports_external.enum(["blend"]).default("blend").optional(),
28511
28435
  confidenceWeight: exports_external.number().finite().min(0).max(1).default(0.2).optional()
28512
28436
  }).passthrough();
28513
28437
  var SearchConfigSchema = exports_external.object({
@@ -29049,8 +28973,7 @@ function withMaintenanceStartBarrier(run) {
29049
28973
 
29050
28974
  // src/indexer/index-writer-lock.ts
29051
28975
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
29052
- var INDEX_WRITER_LOCK_STALE_AFTER_MS = 12 * 60 * 60 * 1000;
29053
- var DEFAULT_INDEX_WRITER_MAX_WAIT_MS = 10 * 60 * 1000;
28976
+ var DEFAULT_ASSET_MUTATION_MAX_WAIT_MS = 10 * 60 * 1000;
29054
28977
  var leaseContext = new AsyncLocalStorage2;
29055
28978
 
29056
28979
  // src/integrations/lockfile.ts
@@ -29848,9 +29771,14 @@ function existingDirectory(target) {
29848
29771
  throw cause;
29849
29772
  }
29850
29773
  }
29774
+ function reconcileDuplicateRoot(existing, candidate, sharedPath) {
29775
+ if (existing.writable === candidate.writable && existing.layout === candidate.layout)
29776
+ return;
29777
+ throw new ConfigError(`Bundles "${existing.bundleId}" and "${candidate.bundleId}" both resolve to the same directory ` + `(${sharedPath}) but disagree on writable/adapter settings. Two bundle ids configured for one ` + "directory must have matching settings, or one of them removed \u2014 run `akm bundle list` to see both.", "INVALID_CONFIG_FILE");
29778
+ }
29851
29779
  function taskRoots(config, resolutionBase = process.cwd()) {
29852
29780
  const sources = new Map((bundlesToSourceEntries(config) ?? []).map((source) => [source.name, source]));
29853
- const roots = [];
29781
+ const rootsByPath = new Map;
29854
29782
  for (const [bundleId, bundle] of Object.entries(config.bundles ?? {})) {
29855
29783
  if (bundle.enabled === false)
29856
29784
  continue;
@@ -29878,15 +29806,21 @@ function taskRoots(config, resolutionBase = process.cwd()) {
29878
29806
  }
29879
29807
  if (adapter !== "akm" && adapter !== "akm-task")
29880
29808
  continue;
29881
- roots.push({
29809
+ const candidate = {
29882
29810
  bundleId,
29883
29811
  root: componentRoot,
29884
29812
  bundleRoot,
29885
29813
  writable: component?.writable ?? resolveWritable(source),
29886
29814
  layout: adapter === "akm-task" ? "akm-task" : "akm-stash"
29887
- });
29815
+ };
29816
+ const existing = rootsByPath.get(componentRoot);
29817
+ if (existing) {
29818
+ reconcileDuplicateRoot(existing, candidate, componentRoot);
29819
+ continue;
29820
+ }
29821
+ rootsByPath.set(componentRoot, candidate);
29888
29822
  }
29889
- return roots;
29823
+ return [...rootsByPath.values()];
29890
29824
  }
29891
29825
  function summarize(plan) {
29892
29826
  const files = plan.files.map((file) => ({
@@ -7,11 +7,10 @@ export function readCurrentLlmEngine(config) {
7
7
  const engine = name ? config.engines?.[name] : undefined;
8
8
  if (!engine || engine.kind !== "llm")
9
9
  return undefined;
10
- const { kind: _kind, supportsJsonSchema, timeoutMs, ...connection } = engine;
10
+ const { kind: _kind, timeoutMs, ...connection } = engine;
11
11
  return {
12
12
  ...connection,
13
13
  ...(timeoutMs !== undefined ? { timeoutMs } : {}),
14
- ...(supportsJsonSchema !== undefined ? { capabilities: { structuredOutput: supportsJsonSchema } } : {}),
15
14
  };
16
15
  }
17
16
  export function readAgentEngineSelection(config) {
@@ -45,15 +44,13 @@ export function writeLlmEngine(config, llm) {
45
44
  const endpoint = llm.endpoint.endsWith("/chat/completions")
46
45
  ? llm.endpoint
47
46
  : `${llm.endpoint.replace(/\/$/, "")}/chat/completions`;
48
- const { capabilities, ...connection } = llm;
49
47
  return {
50
48
  engines: {
51
49
  ...(config.engines ?? {}),
52
50
  [name]: {
53
- ...connection,
51
+ ...llm,
54
52
  kind: "llm",
55
53
  endpoint,
56
- ...(capabilities?.structuredOutput !== undefined ? { supportsJsonSchema: capabilities.structuredOutput } : {}),
57
54
  },
58
55
  },
59
56
  defaults: { ...(config.defaults ?? {}), engine: config.defaults?.engine ?? name, llmEngine: name },
@@ -17,14 +17,6 @@ import { hasRegistryUrlCredentials } from "../core/registry-url.js";
17
17
  import { allowPrivateRegistryFixtureForTests, cancelRegistryResponse, fetchRegistryResponse, } from "../registry/network.js";
18
18
  import { parseRegistryRef } from "../registry/resolve.js";
19
19
  // ── Default selections ──────────────────────────────────────────────────────
20
- /**
21
- * Registry stash IDs that are pre-selected by default during setup.
22
- * IDs must match the `id` field in the official registry index and have a
23
- * matching target in AUTHENTICATED_DEFAULT_TARGETS.
24
- *
25
- * The target binding is intentionally separate from display metadata.
26
- */
27
- export const DEFAULT_SELECTED_STASH_IDS = ["itlackey/akm-stash"];
28
20
  const AUTHENTICATED_DEFAULT_TARGETS = {
29
21
  "itlackey/akm-stash": {
30
22
  installType: "git",