akm-cli 0.9.5 → 0.9.7
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.
- package/CHANGELOG.md +295 -0
- package/dist/assets/hints/cli-hints-full.md +3 -3
- package/dist/assets/improve-strategies/catchup.json +40 -11
- package/dist/assets/improve-strategies/thorough.json +45 -7
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +2 -2
- package/dist/commands/agent/contribute-cli.js +11 -0
- package/dist/commands/env/env-cli.js +1 -2
- package/dist/commands/env/secret-cli.js +1 -5
- package/dist/commands/feedback-cli.js +0 -4
- package/dist/commands/health/checks.js +0 -32
- package/dist/commands/health/surfaces.js +2 -2
- package/dist/commands/health.js +6 -15
- package/dist/commands/improve/autonomy-gate.js +1 -1
- package/dist/commands/improve/consolidate.js +25 -26
- package/dist/commands/improve/distill.js +2 -2
- package/dist/commands/improve/extract.js +8 -1
- package/dist/commands/improve/improve-cli.js +1 -1
- package/dist/commands/improve/improve-strategies.js +0 -4
- package/dist/commands/improve/improve.js +3 -5
- package/dist/commands/improve/locks.js +13 -5
- package/dist/commands/improve/loop-stages.js +8 -9
- package/dist/commands/improve/memory/memory-contradiction-detect.js +1 -19
- package/dist/commands/improve/memory/memory-improve.js +2 -1
- package/dist/commands/improve/outcome-loop.js +0 -6
- package/dist/commands/improve/preparation.js +1 -1
- package/dist/commands/improve/reflect.js +21 -10
- package/dist/commands/lint/base-linter.js +141 -18
- package/dist/commands/lint/index.js +21 -10
- package/dist/commands/proposal/validators/proposal-quality-validators.js +0 -7
- package/dist/commands/read/curate.js +47 -0
- package/dist/commands/read/search-cli.js +24 -1
- package/dist/commands/sources/bundle-config-ops.js +9 -4
- package/dist/commands/sources/info.js +14 -10
- package/dist/commands/tasks/tasks.js +12 -16
- package/dist/commands/workflow-cli.js +2 -2
- package/dist/core/asset/asset-placement.js +13 -2
- package/dist/core/asset/frontmatter.js +116 -0
- package/dist/core/asset/memory-archive.js +97 -0
- package/dist/core/common.js +61 -24
- package/dist/core/config/config-io.js +2 -2
- package/dist/core/config/config-sources.js +32 -2
- package/dist/core/config/config.js +1 -1
- package/dist/core/config/engine-semantics.js +0 -2
- package/dist/core/config/schema/engines.js +9 -7
- package/dist/core/config/schema/primitives.js +0 -5
- package/dist/core/config/schema/search.js +2 -1
- package/dist/core/file-lock.js +2 -1
- package/dist/core/maintenance-barrier.js +2 -14
- package/dist/core/paths.js +0 -3
- package/dist/core/redaction.js +2 -2
- package/dist/core/spawn-env.js +8 -12
- package/dist/core/state/migrations.js +1 -12
- package/dist/core/state-db.js +9 -27
- package/dist/core/write-source.js +12 -19
- package/dist/execution/directory-identity.js +36 -10
- package/dist/indexer/graph/graph-boost.js +0 -4
- package/dist/indexer/index-writer-lock.js +43 -24
- package/dist/indexer/index-written-assets.js +5 -6
- package/dist/indexer/indexer.js +2 -39
- package/dist/indexer/materialize-embeddings.js +85 -41
- package/dist/indexer/search/db-search.js +15 -48
- package/dist/indexer/search/ranking-contributors.js +0 -25
- package/dist/indexer/search/ranking.js +3 -13
- package/dist/integrations/agent/builder-shared.js +0 -25
- package/dist/integrations/agent/model-map.js +2 -60
- package/dist/integrations/harnesses/aider/agent-builder.js +1 -3
- package/dist/integrations/harnesses/amazonq/agent-builder.js +2 -7
- package/dist/integrations/harnesses/claude/agent-builder.js +1 -4
- package/dist/integrations/harnesses/codex/agent-builder.js +1 -4
- package/dist/integrations/harnesses/copilot/agent-builder.js +2 -6
- package/dist/integrations/harnesses/gemini/agent-builder.js +2 -7
- package/dist/integrations/harnesses/opencode/agent-builder.js +1 -4
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +2 -16
- package/dist/integrations/harnesses/openhands/agent-builder.js +1 -3
- package/dist/integrations/harnesses/pi/agent-builder.js +2 -4
- package/dist/integrations/session-logs/index.js +0 -9
- package/dist/llm/client.js +75 -42
- package/dist/llm/embedder.js +7 -3
- package/dist/llm/embedders/remote.js +141 -42
- package/dist/registry/network.js +5 -37
- package/dist/runtime.js +2 -10
- package/dist/scripts/akm-migrate-node.js +73 -133
- package/dist/scripts/akm-migrate.js +73 -133
- package/dist/setup/engine-config.js +2 -5
- package/dist/setup/registry-stash-loader.js +0 -8
- package/dist/setup/setup.js +9 -46
- package/dist/setup/steps/connection-shared.js +10 -13
- package/dist/sources/providers/git-install.js +1 -1
- package/dist/sources/snapshot-fetchers/website-ingest.js +126 -0
- package/dist/storage/engines/sqlite-migrations.js +20 -1
- package/dist/storage/repositories/index-connection.js +45 -3
- package/dist/storage/repositories/index-entries-repository.js +0 -15
- package/dist/tasks/backends/cron.js +49 -9
- package/dist/tasks/backends/launchd.js +15 -20
- package/dist/tasks/backends/schtasks.js +18 -8
- package/dist/tasks/resolve-akm-bin.js +17 -2
- package/dist/tasks/run/run-native-task.js +8 -6
- package/dist/tasks/scheduler-invocation.js +8 -1
- package/dist/tasks/source/bounded-document.js +2 -4
- package/dist/tasks/source/parse-task-source.js +23 -9
- package/dist/tasks/source/task-source-v3-frozen.js +5 -7
- package/dist/tasks/source/task-source-v4.js +5 -10
- package/dist/tasks/source/task-to-v3.js +5 -10
- package/dist/tasks/source/task-to-v4.js +1 -4
- package/dist/tasks/source-v3.js +6 -6
- package/dist/workflows/exec/native-executor.js +21 -31
- package/dist/workflows/exec/run-workflow.js +5 -6
- package/dist/workflows/exec/scheduler.js +3 -19
- package/dist/workflows/exec/step-work.js +1 -4
- package/dist/workflows/exec/unit-dispatch.js +2 -2
- package/dist/workflows/exec/worktree.js +1 -13
- package/dist/workflows/freeze/targets/child-workflow.js +2 -10
- package/dist/workflows/ir/plan-hash.js +4 -6
- package/dist/workflows/ir/schema-v4.js +0 -12
- package/dist/workflows/ir/schema.js +20 -31
- package/dist/workflows/parser.js +11 -52
- package/dist/workflows/renderer.js +2 -3
- package/dist/workflows/resource-limits.js +11 -41
- package/dist/workflows/runtime/runs.js +3 -4
- package/dist/workflows/source-ir/schema.js +14 -30
- package/dist/workflows/validator.js +1 -7
- package/docs/reference/cli.md +5 -1
- package/docs/reference/configuration.md +1 -1
- package/package.json +1 -1
- package/schemas/akm-config.json +4 -23
- package/schemas/akm-task.json +1 -2
- package/schemas/akm-workflow.json +1 -13
- package/dist/assets/improve-strategies/frequent.json +0 -15
- package/dist/assets/improve-strategies/memory-focus.json +0 -15
- 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
|
|
9403
|
+
function readTextFile(filePath, label = "File") {
|
|
9406
9404
|
const fd = fs.openSync(filePath, "r");
|
|
9407
9405
|
try {
|
|
9408
|
-
|
|
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;
|
|
@@ -11521,6 +11524,7 @@ var SCRIPT_EXTENSIONS = new Set([
|
|
|
11521
11524
|
".kts"
|
|
11522
11525
|
]);
|
|
11523
11526
|
var WORKFLOW_EXTENSIONS = [".md", ".yml"];
|
|
11527
|
+
var DERIVED_SUFFIX = ".derived";
|
|
11524
11528
|
var KNOWN_TYPES = [
|
|
11525
11529
|
"skill",
|
|
11526
11530
|
"command",
|
|
@@ -11681,6 +11685,9 @@ function assetPathForName(assetType, typeRoot, name) {
|
|
|
11681
11685
|
}
|
|
11682
11686
|
function assetPathCandidatesForName(assetType, typeRoot, name) {
|
|
11683
11687
|
const primary = assetPathForName(assetType, typeRoot, name);
|
|
11688
|
+
if (assetType === "memory" && !name.endsWith(DERIVED_SUFFIX)) {
|
|
11689
|
+
return [primary, assetPathForName(assetType, typeRoot, `${name}${DERIVED_SUFFIX}`)];
|
|
11690
|
+
}
|
|
11684
11691
|
if (assetType !== "env")
|
|
11685
11692
|
return [primary];
|
|
11686
11693
|
const base = name === "default" ? "" : name.endsWith("/default") ? name.slice(0, -"default".length) : undefined;
|
|
@@ -14879,25 +14886,13 @@ var EXECUTION_MAX_TIMEOUT_MS = 2 ** 31 - 1;
|
|
|
14879
14886
|
// src/workflows/resource-limits.ts
|
|
14880
14887
|
var WORKFLOW_MAX_PLAN_BYTES = 2 * 1024 * 1024;
|
|
14881
14888
|
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
14889
|
var WORKFLOW_MAX_INSTRUCTION_BYTES = 256 * 1024;
|
|
14886
14890
|
var WORKFLOW_MAX_SCHEMA_BYTES = 256 * 1024;
|
|
14887
14891
|
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
14892
|
var WORKFLOW_MAX_CONCURRENCY = 64;
|
|
14892
|
-
var WORKFLOW_MAX_GATE_LOOPS = 100;
|
|
14893
|
-
var WORKFLOW_MAX_RETRIES = 100;
|
|
14894
14893
|
var WORKFLOW_MAX_TIMEOUT_MS = EXECUTION_MAX_TIMEOUT_MS;
|
|
14895
14894
|
var WORKFLOW_ENGINE_NAME_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
|
|
14896
14895
|
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
14896
|
var WORKFLOW_ENV_VAR_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
14902
14897
|
var WORKFLOW_MAX_EXEC_OUTPUT_BYTES = 8 * 1024 * 1024;
|
|
14903
14898
|
var EXEC_CONTEXT_LIMITS_POSIX = {
|
|
@@ -14915,13 +14910,13 @@ function jsonBytes(value) {
|
|
|
14915
14910
|
var WORKFLOW_MAX_EMBEDDED_CHILD_PLAN_BYTES = 1024 * 1024;
|
|
14916
14911
|
|
|
14917
14912
|
// src/tasks/source/bounded-document.ts
|
|
14918
|
-
var TASK_V3_MAX_SOURCE_BYTES = 1024 * 1024;
|
|
14919
14913
|
var TASK_V3_MAX_JSON_DEPTH = 64;
|
|
14920
14914
|
var TASK_V3_MAX_JSON_NODES = 1e4;
|
|
14921
14915
|
var TASK_V3_MAX_COLLECTION_ITEMS = 1024;
|
|
14922
14916
|
var TASK_V3_MAX_OBJECT_KEYS = 256;
|
|
14923
14917
|
var TASK_V3_MAX_STRING_BYTES = 256 * 1024;
|
|
14924
14918
|
var TASK_V3_MAX_SCHEDULES = 64;
|
|
14919
|
+
var TASK_V3_MAX_REDACT_NAMES = 32;
|
|
14925
14920
|
function own2(value, key) {
|
|
14926
14921
|
return Object.hasOwn(value, key);
|
|
14927
14922
|
}
|
|
@@ -15210,9 +15205,6 @@ function readBoundedTaskSourceYaml(input, options) {
|
|
|
15210
15205
|
if (typeof input.yaml !== "string") {
|
|
15211
15206
|
throw new UsageError(`Invalid ${sourceLabel} at ${input.filePath}: source must be a string.`, "TASK_SOURCE_INVALID");
|
|
15212
15207
|
}
|
|
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
15208
|
const lineCounter2 = new $LineCounter;
|
|
15217
15209
|
let document;
|
|
15218
15210
|
try {
|
|
@@ -15972,7 +15964,7 @@ function parseExecutionControls(input, ctx) {
|
|
|
15972
15964
|
out.timeout = parseTimeoutTopLevel(input.timeout, ctx);
|
|
15973
15965
|
if (own2(input, "redact")) {
|
|
15974
15966
|
const names = parseStringArray(input.redact, ctx, ["redact"], {
|
|
15975
|
-
max:
|
|
15967
|
+
max: TASK_V3_MAX_REDACT_NAMES,
|
|
15976
15968
|
pattern: WORKFLOW_ENV_VAR_NAME_PATTERN
|
|
15977
15969
|
});
|
|
15978
15970
|
if (new Set(names).size !== names.length)
|
|
@@ -15986,8 +15978,8 @@ function parseExecutionControls(input, ctx) {
|
|
|
15986
15978
|
out.maxSteps = input.maxSteps;
|
|
15987
15979
|
}
|
|
15988
15980
|
if (own2(input, "maxRetries")) {
|
|
15989
|
-
if (!Number.isSafeInteger(input.maxRetries) || input.maxRetries < 0
|
|
15990
|
-
sourceError(ctx, ["maxRetries"],
|
|
15981
|
+
if (!Number.isSafeInteger(input.maxRetries) || input.maxRetries < 0) {
|
|
15982
|
+
sourceError(ctx, ["maxRetries"], "must be a non-negative safe integer.");
|
|
15991
15983
|
}
|
|
15992
15984
|
out.maxRetries = input.maxRetries;
|
|
15993
15985
|
}
|
|
@@ -16047,9 +16039,6 @@ function parseInputDeclaration(name, raw, ctx) {
|
|
|
16047
16039
|
function parseInputDeclarations(value, ctx) {
|
|
16048
16040
|
const input = asRecord(value, ctx, ["inputs"]);
|
|
16049
16041
|
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
16042
|
const result = {};
|
|
16054
16043
|
for (const name of names) {
|
|
16055
16044
|
if (!INPUT_NAME_PATTERN.test(name)) {
|
|
@@ -16482,7 +16471,7 @@ function parseAkm(value, ctx) {
|
|
|
16482
16471
|
out.timeout = parseTimeout(input.timeout, ctx);
|
|
16483
16472
|
if (own2(input, "redact")) {
|
|
16484
16473
|
const names = parseStringArray(input.redact, ctx, ["akm", "redact"], {
|
|
16485
|
-
max:
|
|
16474
|
+
max: TASK_V3_MAX_REDACT_NAMES,
|
|
16486
16475
|
pattern: WORKFLOW_ENV_VAR_NAME_PATTERN
|
|
16487
16476
|
});
|
|
16488
16477
|
if (new Set(names).size !== names.length)
|
|
@@ -16496,8 +16485,8 @@ function parseAkm(value, ctx) {
|
|
|
16496
16485
|
out.maxSteps = input.maxSteps;
|
|
16497
16486
|
}
|
|
16498
16487
|
if (own2(input, "maxRetries")) {
|
|
16499
|
-
if (!Number.isSafeInteger(input.maxRetries) || input.maxRetries < 0
|
|
16500
|
-
sourceError(ctx, ["akm", "maxRetries"],
|
|
16488
|
+
if (!Number.isSafeInteger(input.maxRetries) || input.maxRetries < 0) {
|
|
16489
|
+
sourceError(ctx, ["akm", "maxRetries"], "must be a non-negative safe integer.");
|
|
16501
16490
|
}
|
|
16502
16491
|
out.maxRetries = input.maxRetries;
|
|
16503
16492
|
}
|
|
@@ -16814,9 +16803,6 @@ function optionalString(value, label) {
|
|
|
16814
16803
|
return exactString(value, label);
|
|
16815
16804
|
}
|
|
16816
16805
|
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
16806
|
let source;
|
|
16821
16807
|
try {
|
|
16822
16808
|
source = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(input.bytes);
|
|
@@ -16864,7 +16850,7 @@ function validateCommonV2(data) {
|
|
|
16864
16850
|
}
|
|
16865
16851
|
}
|
|
16866
16852
|
if (data.redact !== undefined && data.redact !== null) {
|
|
16867
|
-
if (!Array.isArray(data.redact) || data.redact.length >
|
|
16853
|
+
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
16854
|
throw new Error("redact must contain only bounded environment variable names");
|
|
16869
16855
|
}
|
|
16870
16856
|
}
|
|
@@ -16990,8 +16976,8 @@ function migratedObject(data) {
|
|
|
16990
16976
|
akm.maxSteps = data.maxSteps;
|
|
16991
16977
|
}
|
|
16992
16978
|
if (data.maxRetries !== undefined && data.maxRetries !== null) {
|
|
16993
|
-
if (!Number.isSafeInteger(data.maxRetries) || data.maxRetries < 0
|
|
16994
|
-
throw new Error(
|
|
16979
|
+
if (!Number.isSafeInteger(data.maxRetries) || data.maxRetries < 0) {
|
|
16980
|
+
throw new Error("maxRetries must be a non-negative integer");
|
|
16995
16981
|
}
|
|
16996
16982
|
akm.maxRetries = data.maxRetries;
|
|
16997
16983
|
}
|
|
@@ -17250,9 +17236,6 @@ function exactString2(value, label, nonempty = false) {
|
|
|
17250
17236
|
return value;
|
|
17251
17237
|
}
|
|
17252
17238
|
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
17239
|
let source;
|
|
17257
17240
|
try {
|
|
17258
17241
|
source = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(input.bytes);
|
|
@@ -17549,6 +17532,9 @@ function peekTaskSourceVersion(root) {
|
|
|
17549
17532
|
return typeof value === "number" ? value : undefined;
|
|
17550
17533
|
}
|
|
17551
17534
|
var TASK_MIGRATE_HINT = "Run `akm migrate apply --dry-run` to preview the task-v3 to task-source-v4 conversion, then run `akm migrate apply`.";
|
|
17535
|
+
function unmigratableVersionError(filePath, version, reason, detail) {
|
|
17536
|
+
return new UsageError(`TASK_SCHEMA_VERSION_UNSUPPORTED: Task at ${filePath} uses task schema version ${version} and needs a human decision before it can run \u2014 the deterministic migrator cannot convert it automatically (${reason}${detail ? `: ${detail}` : ""}).`, "TASK_SCHEMA_VERSION_UNSUPPORTED", "Review the file and resolve the ambiguity by hand, then it will convert normally; `akm migrate status` reports the same reason.");
|
|
17537
|
+
}
|
|
17552
17538
|
function unsupportedVersionError(filePath, version) {
|
|
17553
17539
|
return new UsageError(`TASK_SCHEMA_VERSION_UNSUPPORTED: Task at ${filePath} uses task schema version ${version}, which this release does not accept.`, "TASK_SCHEMA_VERSION_UNSUPPORTED", TASK_MIGRATE_HINT);
|
|
17554
17540
|
}
|
|
@@ -17568,12 +17554,12 @@ function planInMemoryV4Bytes(version, yaml, filePath, workspaceRoot) {
|
|
|
17568
17554
|
} else {
|
|
17569
17555
|
const v3Outcome = planTaskToV3File(baseInput);
|
|
17570
17556
|
if (v3Outcome.status !== "changed")
|
|
17571
|
-
return;
|
|
17557
|
+
return { reason: v3Outcome.reason, detail: v3Outcome.detail };
|
|
17572
17558
|
v3Bytes = v3Outcome.after;
|
|
17573
17559
|
}
|
|
17574
17560
|
const v4Outcome = planTaskToV4File({ ...baseInput, bytes: v3Bytes });
|
|
17575
17561
|
if (v4Outcome.status !== "changed")
|
|
17576
|
-
return;
|
|
17562
|
+
return { reason: v4Outcome.reason, detail: v4Outcome.detail };
|
|
17577
17563
|
return v4Outcome.after.toString("utf8");
|
|
17578
17564
|
}
|
|
17579
17565
|
function parseTaskSource(input) {
|
|
@@ -17581,16 +17567,17 @@ function parseTaskSource(input) {
|
|
|
17581
17567
|
const version = peekTaskSourceVersion(root);
|
|
17582
17568
|
if (version !== undefined && version !== TASK_SOURCE_V4_VERSION) {
|
|
17583
17569
|
if (version === 2 || version === 3) {
|
|
17584
|
-
const
|
|
17585
|
-
if (
|
|
17570
|
+
const shimmed = planInMemoryV4Bytes(version, input.yaml, input.filePath, input.workspaceRoot);
|
|
17571
|
+
if (typeof shimmed === "string") {
|
|
17586
17572
|
const v4 = parseTaskSourceV4({
|
|
17587
|
-
yaml:
|
|
17573
|
+
yaml: shimmed,
|
|
17588
17574
|
filePath: input.filePath,
|
|
17589
17575
|
...input.workspaceRoot ? { workspaceRoot: input.workspaceRoot } : {}
|
|
17590
17576
|
});
|
|
17591
17577
|
warn(`akm: task ${input.filePath} uses schema v${version} \u2014 auto-read as v4; run \`akm migrate apply\` to rewrite it and silence this`);
|
|
17592
17578
|
return Object.freeze({ version: 4, v4 });
|
|
17593
17579
|
}
|
|
17580
|
+
throw unmigratableVersionError(input.filePath, version, shimmed.reason, shimmed.detail);
|
|
17594
17581
|
}
|
|
17595
17582
|
throw unsupportedVersionError(input.filePath, version);
|
|
17596
17583
|
}
|
|
@@ -18453,7 +18440,7 @@ function validateStep(value, jobId, index, stepIds, options) {
|
|
|
18453
18440
|
}
|
|
18454
18441
|
validateMap(step.map, `step ${id} map`);
|
|
18455
18442
|
validateRoute(step.route, `step ${id} route`);
|
|
18456
|
-
optionalStringList(step.inputs, `step ${id} inputs`,
|
|
18443
|
+
optionalStringList(step.inputs, `step ${id} inputs`, Infinity);
|
|
18457
18444
|
if (Array.isArray(step.inputs)) {
|
|
18458
18445
|
for (const [inputIndex, input] of step.inputs.entries())
|
|
18459
18446
|
validateReference(input, `step ${id} inputs[${inputIndex}]`);
|
|
@@ -18475,12 +18462,7 @@ function validateExec(value, location, options) {
|
|
|
18475
18462
|
return;
|
|
18476
18463
|
const exec = record(value, location);
|
|
18477
18464
|
keys(exec, ["command", "cwd", "passEnv"], location);
|
|
18478
|
-
stringList(exec.command, `${location}.command`,
|
|
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
|
-
}
|
|
18465
|
+
stringList(exec.command, `${location}.command`, Infinity, false);
|
|
18484
18466
|
try {
|
|
18485
18467
|
rejectNulInArgv(exec.command);
|
|
18486
18468
|
} catch (cause) {
|
|
@@ -18488,9 +18470,6 @@ function validateExec(value, location, options) {
|
|
|
18488
18470
|
}
|
|
18489
18471
|
optionalString2(exec.cwd, `${location}.cwd`);
|
|
18490
18472
|
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
18473
|
try {
|
|
18495
18474
|
exec.cwd = canonicalizeWorkflowWorkingDirectory(exec.cwd, options.workspaceRoot);
|
|
18496
18475
|
} catch (cause) {
|
|
@@ -18498,7 +18477,7 @@ function validateExec(value, location, options) {
|
|
|
18498
18477
|
}
|
|
18499
18478
|
}
|
|
18500
18479
|
if (exec.passEnv !== undefined) {
|
|
18501
|
-
stringList(exec.passEnv, `${location}.passEnv`,
|
|
18480
|
+
stringList(exec.passEnv, `${location}.passEnv`, Infinity, false);
|
|
18502
18481
|
}
|
|
18503
18482
|
if (Array.isArray(exec.passEnv)) {
|
|
18504
18483
|
for (const name of exec.passEnv) {
|
|
@@ -18549,8 +18528,8 @@ function validateRetry(value, location) {
|
|
|
18549
18528
|
return;
|
|
18550
18529
|
const retry = record(value, location);
|
|
18551
18530
|
keys(retry, ["max", "on"], location);
|
|
18552
|
-
if (!Number.isSafeInteger(retry.max) || retry.max < 0
|
|
18553
|
-
fail2(`${location}.max must be
|
|
18531
|
+
if (!Number.isSafeInteger(retry.max) || retry.max < 0) {
|
|
18532
|
+
fail2(`${location}.max must be a non-negative integer`);
|
|
18554
18533
|
}
|
|
18555
18534
|
stringList(retry.on, `${location}.on`, PROGRAM_RETRY_REASONS.length, false);
|
|
18556
18535
|
for (const reason of retry.on) {
|
|
@@ -18580,8 +18559,8 @@ function validateRoute(value, location) {
|
|
|
18580
18559
|
keys(route, ["input", "branches", "defaultStepId"], location);
|
|
18581
18560
|
nonEmptyString2(route.input, `${location}.input`);
|
|
18582
18561
|
validateReference(route.input, `${location}.input`);
|
|
18583
|
-
if (!Array.isArray(route.branches) || route.branches.length === 0
|
|
18584
|
-
fail2(`${location}.branches must
|
|
18562
|
+
if (!Array.isArray(route.branches) || route.branches.length === 0) {
|
|
18563
|
+
fail2(`${location}.branches must be a non-empty array`);
|
|
18585
18564
|
}
|
|
18586
18565
|
const matches = new Set;
|
|
18587
18566
|
for (const [index, value2] of route.branches.entries()) {
|
|
@@ -18601,8 +18580,8 @@ function validateGate(value, location) {
|
|
|
18601
18580
|
return;
|
|
18602
18581
|
const gate = record(value, location);
|
|
18603
18582
|
keys(gate, ["maxLoops", "rubric"], location);
|
|
18604
|
-
if (gate.maxLoops !== undefined && (!Number.isSafeInteger(gate.maxLoops) || gate.maxLoops < 1
|
|
18605
|
-
fail2(`${location}.maxLoops must be an integer
|
|
18583
|
+
if (gate.maxLoops !== undefined && (!Number.isSafeInteger(gate.maxLoops) || gate.maxLoops < 1)) {
|
|
18584
|
+
fail2(`${location}.maxLoops must be an integer of at least 1`);
|
|
18606
18585
|
}
|
|
18607
18586
|
optionalString2(gate.rubric, `${location}.rubric`);
|
|
18608
18587
|
}
|
|
@@ -18635,8 +18614,8 @@ function validateParams(value) {
|
|
|
18635
18614
|
if (value === undefined)
|
|
18636
18615
|
return;
|
|
18637
18616
|
const params = record(value, "params");
|
|
18638
|
-
if (Object.keys(params).length === 0
|
|
18639
|
-
fail2(`params must contain
|
|
18617
|
+
if (Object.keys(params).length === 0) {
|
|
18618
|
+
fail2(`params must contain at least one entry`);
|
|
18640
18619
|
}
|
|
18641
18620
|
for (const [name, schema] of Object.entries(params)) {
|
|
18642
18621
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))
|
|
@@ -18648,8 +18627,8 @@ function validateOutputs(value) {
|
|
|
18648
18627
|
if (value === undefined)
|
|
18649
18628
|
return;
|
|
18650
18629
|
const outputs = record(value, "outputs");
|
|
18651
|
-
if (Object.keys(outputs).length === 0
|
|
18652
|
-
fail2(`outputs must contain
|
|
18630
|
+
if (Object.keys(outputs).length === 0) {
|
|
18631
|
+
fail2(`outputs must contain at least one entry`);
|
|
18653
18632
|
}
|
|
18654
18633
|
for (const [name, declaration] of Object.entries(outputs)) {
|
|
18655
18634
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))
|
|
@@ -18672,9 +18651,6 @@ function validateBudget(value) {
|
|
|
18672
18651
|
fail2(`budget.${key} must be a positive integer`);
|
|
18673
18652
|
}
|
|
18674
18653
|
}
|
|
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
18654
|
}
|
|
18679
18655
|
function validateLlm(value, location) {
|
|
18680
18656
|
if (value === undefined)
|
|
@@ -19258,12 +19234,6 @@ function checkXrefs(value, line, errors2) {
|
|
|
19258
19234
|
}
|
|
19259
19235
|
}
|
|
19260
19236
|
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
19237
|
for (const step of draft.steps) {
|
|
19268
19238
|
if (step.instructions && utf8Bytes(step.instructions.text) > WORKFLOW_MAX_INSTRUCTION_BYTES) {
|
|
19269
19239
|
errors2.push({
|
|
@@ -19625,9 +19595,6 @@ function parseParams(ctx, raw) {
|
|
|
19625
19595
|
ctx.err(["params"], `"params" must be a mapping of param name to a JSON Schema object (e.g. changed_files: { type: array }).`);
|
|
19626
19596
|
return;
|
|
19627
19597
|
}
|
|
19628
|
-
if (Object.keys(raw).length > WORKFLOW_MAX_PARAMS) {
|
|
19629
|
-
ctx.err(["params"], `"params" must contain at most ${WORKFLOW_MAX_PARAMS} entries.`);
|
|
19630
|
-
}
|
|
19631
19598
|
const params = {};
|
|
19632
19599
|
for (const [paramName, value] of Object.entries(raw)) {
|
|
19633
19600
|
if (!INPUT_NAME_PATTERN.test(paramName)) {
|
|
@@ -19653,9 +19620,6 @@ function parseOutputs(ctx, raw) {
|
|
|
19653
19620
|
ctx.err(["outputs"], `"outputs" must be a mapping of output name to { from, schema? } (e.g. report: { from: steps.summarize.output }).`);
|
|
19654
19621
|
return;
|
|
19655
19622
|
}
|
|
19656
|
-
if (Object.keys(raw).length > WORKFLOW_MAX_OUTPUTS) {
|
|
19657
|
-
ctx.err(["outputs"], `"outputs" must contain at most ${WORKFLOW_MAX_OUTPUTS} entries.`);
|
|
19658
|
-
}
|
|
19659
19623
|
const outputs = {};
|
|
19660
19624
|
for (const [outputName, value] of Object.entries(raw)) {
|
|
19661
19625
|
const path13 = ["outputs", outputName];
|
|
@@ -19747,10 +19711,10 @@ function parseBudget(ctx, raw) {
|
|
|
19747
19711
|
}
|
|
19748
19712
|
}
|
|
19749
19713
|
if (raw.max_units !== undefined) {
|
|
19750
|
-
if (typeof raw.max_units === "number" && Number.isInteger(raw.max_units) && raw.max_units >= 1
|
|
19714
|
+
if (typeof raw.max_units === "number" && Number.isInteger(raw.max_units) && raw.max_units >= 1) {
|
|
19751
19715
|
budget.maxUnits = raw.max_units;
|
|
19752
19716
|
} else {
|
|
19753
|
-
ctx.err([...path13, "max_units"], `"budget.max_units" must be an integer
|
|
19717
|
+
ctx.err([...path13, "max_units"], `"budget.max_units" must be an integer >= 1.`);
|
|
19754
19718
|
}
|
|
19755
19719
|
}
|
|
19756
19720
|
return Object.keys(budget).length > 0 ? budget : undefined;
|
|
@@ -19760,9 +19724,6 @@ function parseSteps(ctx, raw) {
|
|
|
19760
19724
|
ctx.err(["steps"], `"steps" is required and must be a list with at least one step.`);
|
|
19761
19725
|
return [];
|
|
19762
19726
|
}
|
|
19763
|
-
if (raw.length > WORKFLOW_MAX_STEPS) {
|
|
19764
|
-
ctx.err(["steps"], `"steps" must contain at most ${WORKFLOW_MAX_STEPS} entries.`);
|
|
19765
|
-
}
|
|
19766
19727
|
const idIndex = new Map;
|
|
19767
19728
|
raw.forEach((rawStep, index) => {
|
|
19768
19729
|
if (isPlainRecord(rawStep) && typeof rawStep.id === "string" && !idIndex.has(rawStep.id)) {
|
|
@@ -19933,10 +19894,6 @@ function parseExecPassEnv(ctx, raw, path13, stepLabel) {
|
|
|
19933
19894
|
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
19895
|
return;
|
|
19935
19896
|
}
|
|
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
19897
|
const names = [];
|
|
19941
19898
|
for (const [index, entry] of raw.entries()) {
|
|
19942
19899
|
if (typeof entry !== "string" || !WORKFLOW_ENV_VAR_NAME_PATTERN.test(entry)) {
|
|
@@ -19956,10 +19913,6 @@ function parseExecCommand(ctx, raw, path13, stepLabel) {
|
|
|
19956
19913
|
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
19914
|
return;
|
|
19958
19915
|
}
|
|
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
19916
|
const argv = [];
|
|
19964
19917
|
for (const [index, entry] of raw.entries()) {
|
|
19965
19918
|
if (typeof entry !== "string" || entry === "") {
|
|
@@ -19970,10 +19923,6 @@ function parseExecCommand(ctx, raw, path13, stepLabel) {
|
|
|
19970
19923
|
ctx.err([...path13, index], `${stepLabel} "exec.command[${index}]" may not contain NUL bytes.`);
|
|
19971
19924
|
return;
|
|
19972
19925
|
}
|
|
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
19926
|
argv.push(entry);
|
|
19978
19927
|
}
|
|
19979
19928
|
return argv;
|
|
@@ -19986,10 +19935,6 @@ function parseExecCwd(ctx, raw, path13, stepLabel) {
|
|
|
19986
19935
|
return;
|
|
19987
19936
|
}
|
|
19988
19937
|
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
19938
|
if (!isContainedRelativePath(value)) {
|
|
19994
19939
|
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
19940
|
return;
|
|
@@ -20023,10 +19968,10 @@ function parseMap(ctx, raw, path13, stepLabel) {
|
|
|
20023
19968
|
}
|
|
20024
19969
|
let concurrency;
|
|
20025
19970
|
if (raw.concurrency !== undefined) {
|
|
20026
|
-
if (typeof raw.concurrency === "number" && Number.isInteger(raw.concurrency) && raw.concurrency > 0
|
|
20027
|
-
concurrency = raw.concurrency;
|
|
19971
|
+
if (typeof raw.concurrency === "number" && Number.isInteger(raw.concurrency) && raw.concurrency > 0) {
|
|
19972
|
+
concurrency = Math.min(raw.concurrency, WORKFLOW_MAX_CONCURRENCY);
|
|
20028
19973
|
} else {
|
|
20029
|
-
ctx.err([...path13, "concurrency"], `${stepLabel} "concurrency" must be
|
|
19974
|
+
ctx.err([...path13, "concurrency"], `${stepLabel} "concurrency" must be a positive integer.`);
|
|
20030
19975
|
}
|
|
20031
19976
|
}
|
|
20032
19977
|
const reducer = parseEnumField(ctx, raw.reducer, [...path13, "reducer"], `${stepLabel} "reducer"`, PROGRAM_REDUCERS);
|
|
@@ -20058,9 +20003,6 @@ function parseRoute(ctx, raw, path13, stepLabel, stepIndex, routeChecks) {
|
|
|
20058
20003
|
if (!Array.isArray(raw.when) || raw.when.length === 0) {
|
|
20059
20004
|
ctx.err(whenPath, `${stepLabel} "route" requires "when": a non-empty list of { match, step } branches (e.g. when: [{ match: pass, step: ship }]).`);
|
|
20060
20005
|
} 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
20006
|
const seenMatches = new Map;
|
|
20065
20007
|
raw.when.forEach((branch, i) => {
|
|
20066
20008
|
const branchPath = [...whenPath, i];
|
|
@@ -20116,9 +20058,6 @@ function parseInputs(ctx, raw, path13, stepLabel) {
|
|
|
20116
20058
|
ctx.err(path13, `${stepLabel} "inputs" must be a non-empty list of reference strings.`);
|
|
20117
20059
|
return;
|
|
20118
20060
|
}
|
|
20119
|
-
if (raw.length > WORKFLOW_MAX_INPUTS) {
|
|
20120
|
-
ctx.err(path13, `${stepLabel} "inputs" must contain at most ${WORKFLOW_MAX_INPUTS} entries.`);
|
|
20121
|
-
}
|
|
20122
20061
|
const out = [];
|
|
20123
20062
|
const seen = new Set;
|
|
20124
20063
|
raw.forEach((entry, i) => {
|
|
@@ -20145,10 +20084,10 @@ function parseGate(ctx, raw, path13, stepLabel) {
|
|
|
20145
20084
|
checkUnknownKeys(ctx, raw, path13, GATE_KEYS, `${stepLabel} "gate"`);
|
|
20146
20085
|
const gate = {};
|
|
20147
20086
|
if (raw.max_loops !== undefined) {
|
|
20148
|
-
if (typeof raw.max_loops === "number" && Number.isInteger(raw.max_loops) && raw.max_loops >= 1
|
|
20087
|
+
if (typeof raw.max_loops === "number" && Number.isInteger(raw.max_loops) && raw.max_loops >= 1) {
|
|
20149
20088
|
gate.maxLoops = raw.max_loops;
|
|
20150
20089
|
} else {
|
|
20151
|
-
ctx.err([...path13, "max_loops"], `${stepLabel} "gate.max_loops" must be an integer
|
|
20090
|
+
ctx.err([...path13, "max_loops"], `${stepLabel} "gate.max_loops" must be an integer of at least 1.`);
|
|
20152
20091
|
}
|
|
20153
20092
|
}
|
|
20154
20093
|
return gate;
|
|
@@ -20174,8 +20113,8 @@ function parseRetry(ctx, raw, path13, stepLabel) {
|
|
|
20174
20113
|
}
|
|
20175
20114
|
checkUnknownKeys(ctx, raw, path13, RETRY_KEYS, `${stepLabel} "retry"`);
|
|
20176
20115
|
let ok = true;
|
|
20177
|
-
if (!(typeof raw.max === "number" && Number.isInteger(raw.max) && raw.max >= 0
|
|
20178
|
-
ctx.err([...path13, "max"], `${stepLabel} "retry.max" is required and must be
|
|
20116
|
+
if (!(typeof raw.max === "number" && Number.isInteger(raw.max) && raw.max >= 0)) {
|
|
20117
|
+
ctx.err([...path13, "max"], `${stepLabel} "retry.max" is required and must be a non-negative integer.`);
|
|
20179
20118
|
ok = false;
|
|
20180
20119
|
}
|
|
20181
20120
|
const on = [];
|
|
@@ -23763,7 +23702,7 @@ function withLockOperationMutex(lockPath, run) {
|
|
|
23763
23702
|
db.exec("BEGIN IMMEDIATE");
|
|
23764
23703
|
began = db.inTransaction;
|
|
23765
23704
|
if (!began)
|
|
23766
|
-
|
|
23705
|
+
sleepSync(2 ** attempt);
|
|
23767
23706
|
}
|
|
23768
23707
|
if (!began)
|
|
23769
23708
|
throw new Error(`Could not acquire lock operation mutex for ${lockPath}.`);
|
|
@@ -23926,7 +23865,7 @@ function extractHolderPid(content) {
|
|
|
23926
23865
|
// src/core/config/config-io.ts
|
|
23927
23866
|
function readConfigText(configPath) {
|
|
23928
23867
|
try {
|
|
23929
|
-
return
|
|
23868
|
+
return readTextFile(configPath, "Config file");
|
|
23930
23869
|
} catch (err) {
|
|
23931
23870
|
if (err.code === "ENOENT")
|
|
23932
23871
|
return;
|
|
@@ -27981,9 +27920,7 @@ var BUILTIN_IMPROVE_STRATEGY_NAMES = [
|
|
|
27981
27920
|
"default",
|
|
27982
27921
|
"quick",
|
|
27983
27922
|
"thorough",
|
|
27984
|
-
"memory-focus",
|
|
27985
27923
|
"graph-refresh",
|
|
27986
|
-
"frequent",
|
|
27987
27924
|
"consolidate",
|
|
27988
27925
|
"catchup",
|
|
27989
27926
|
"reflect-distill",
|
|
@@ -28033,9 +27970,6 @@ var ExtraParamsSchema = exports_external.record(exports_external.unknown()).supe
|
|
|
28033
27970
|
ctx.addIssue({ code: exports_external.ZodIssueCode.custom, path: issue.path, message: issue.message });
|
|
28034
27971
|
}
|
|
28035
27972
|
});
|
|
28036
|
-
var LlmCapabilitiesSchema = exports_external.object({
|
|
28037
|
-
structuredOutput: exports_external.boolean().optional()
|
|
28038
|
-
}).passthrough();
|
|
28039
27973
|
var LlmInvocationOverridesSchema = exports_external.object({
|
|
28040
27974
|
temperature: exports_external.number().finite().optional(),
|
|
28041
27975
|
maxTokens: positiveInt.optional(),
|
|
@@ -28091,15 +28025,13 @@ var LlmConnectionConfigSchema = exports_external.object({
|
|
|
28091
28025
|
maxTokens: positiveInt.optional(),
|
|
28092
28026
|
timeoutMs: timeoutMsField,
|
|
28093
28027
|
concurrency: positiveInt.optional(),
|
|
28094
|
-
|
|
28028
|
+
supportsJsonSchema: exports_external.boolean().optional(),
|
|
28095
28029
|
extraParams: ExtraParamsSchema.optional(),
|
|
28096
28030
|
contextLength: positiveInt.optional(),
|
|
28097
28031
|
enableThinking: exports_external.boolean().optional(),
|
|
28098
28032
|
reasoningEffort: nonEmptyString3.optional()
|
|
28099
28033
|
}).passthrough();
|
|
28100
|
-
var LlmProfileConfigSchema = LlmConnectionConfigSchema.
|
|
28101
|
-
supportsJsonSchema: exports_external.boolean().optional()
|
|
28102
|
-
}).passthrough();
|
|
28034
|
+
var LlmProfileConfigSchema = LlmConnectionConfigSchema.passthrough();
|
|
28103
28035
|
var AgentPlatformSchema = exports_external.enum(VALID_HARNESS_IDS);
|
|
28104
28036
|
var LlmEngineSchema = exports_external.object({
|
|
28105
28037
|
kind: exports_external.literal("llm"),
|
|
@@ -28111,7 +28043,6 @@ var LlmEngineSchema = exports_external.object({
|
|
|
28111
28043
|
maxTokens: positiveInt.optional(),
|
|
28112
28044
|
timeoutMs: timeoutMsField,
|
|
28113
28045
|
concurrency: positiveInt.optional(),
|
|
28114
|
-
supportsJsonSchema: exports_external.boolean().optional(),
|
|
28115
28046
|
extraParams: ExtraParamsSchema.optional(),
|
|
28116
28047
|
contextLength: positiveInt.optional(),
|
|
28117
28048
|
enableThinking: exports_external.boolean().optional(),
|
|
@@ -28141,7 +28072,6 @@ var AgentEngineSchema = exports_external.object({
|
|
|
28141
28072
|
"temperature",
|
|
28142
28073
|
"maxTokens",
|
|
28143
28074
|
"concurrency",
|
|
28144
|
-
"supportsJsonSchema",
|
|
28145
28075
|
"extraParams",
|
|
28146
28076
|
"contextLength",
|
|
28147
28077
|
"enableThinking",
|
|
@@ -28507,7 +28437,7 @@ var SearchGraphBoostSchema = exports_external.object({
|
|
|
28507
28437
|
hopBoostPerEntity: nonNegativeNumber.optional(),
|
|
28508
28438
|
hopBoostCap: nonNegativeNumber.optional(),
|
|
28509
28439
|
maxHops: positiveInt.max(3).optional(),
|
|
28510
|
-
confidenceMode: exports_external.enum(["
|
|
28440
|
+
confidenceMode: exports_external.enum(["blend"]).default("blend").optional(),
|
|
28511
28441
|
confidenceWeight: exports_external.number().finite().min(0).max(1).default(0.2).optional()
|
|
28512
28442
|
}).passthrough();
|
|
28513
28443
|
var SearchConfigSchema = exports_external.object({
|
|
@@ -29049,8 +28979,7 @@ function withMaintenanceStartBarrier(run) {
|
|
|
29049
28979
|
|
|
29050
28980
|
// src/indexer/index-writer-lock.ts
|
|
29051
28981
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
29052
|
-
var
|
|
29053
|
-
var DEFAULT_INDEX_WRITER_MAX_WAIT_MS = 10 * 60 * 1000;
|
|
28982
|
+
var DEFAULT_ASSET_MUTATION_MAX_WAIT_MS = 10 * 60 * 1000;
|
|
29054
28983
|
var leaseContext = new AsyncLocalStorage2;
|
|
29055
28984
|
|
|
29056
28985
|
// src/integrations/lockfile.ts
|
|
@@ -29848,9 +29777,14 @@ function existingDirectory(target) {
|
|
|
29848
29777
|
throw cause;
|
|
29849
29778
|
}
|
|
29850
29779
|
}
|
|
29780
|
+
function reconcileDuplicateRoot(existing, candidate, sharedPath) {
|
|
29781
|
+
if (existing.writable === candidate.writable && existing.layout === candidate.layout)
|
|
29782
|
+
return;
|
|
29783
|
+
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");
|
|
29784
|
+
}
|
|
29851
29785
|
function taskRoots(config, resolutionBase = process.cwd()) {
|
|
29852
29786
|
const sources = new Map((bundlesToSourceEntries(config) ?? []).map((source) => [source.name, source]));
|
|
29853
|
-
const
|
|
29787
|
+
const rootsByPath = new Map;
|
|
29854
29788
|
for (const [bundleId, bundle] of Object.entries(config.bundles ?? {})) {
|
|
29855
29789
|
if (bundle.enabled === false)
|
|
29856
29790
|
continue;
|
|
@@ -29878,15 +29812,21 @@ function taskRoots(config, resolutionBase = process.cwd()) {
|
|
|
29878
29812
|
}
|
|
29879
29813
|
if (adapter !== "akm" && adapter !== "akm-task")
|
|
29880
29814
|
continue;
|
|
29881
|
-
|
|
29815
|
+
const candidate = {
|
|
29882
29816
|
bundleId,
|
|
29883
29817
|
root: componentRoot,
|
|
29884
29818
|
bundleRoot,
|
|
29885
29819
|
writable: component?.writable ?? resolveWritable(source),
|
|
29886
29820
|
layout: adapter === "akm-task" ? "akm-task" : "akm-stash"
|
|
29887
|
-
}
|
|
29821
|
+
};
|
|
29822
|
+
const existing = rootsByPath.get(componentRoot);
|
|
29823
|
+
if (existing) {
|
|
29824
|
+
reconcileDuplicateRoot(existing, candidate, componentRoot);
|
|
29825
|
+
continue;
|
|
29826
|
+
}
|
|
29827
|
+
rootsByPath.set(componentRoot, candidate);
|
|
29888
29828
|
}
|
|
29889
|
-
return
|
|
29829
|
+
return [...rootsByPath.values()];
|
|
29890
29830
|
}
|
|
29891
29831
|
function summarize(plan) {
|
|
29892
29832
|
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,
|
|
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
|
-
...
|
|
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",
|