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.
- package/CHANGELOG.md +105 -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.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/outcome-loop.js +0 -6
- package/dist/commands/improve/reflect.js +20 -9
- package/dist/commands/lint/index.js +4 -6
- package/dist/commands/proposal/validators/proposal-quality-validators.js +0 -7
- 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/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/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 +60 -126
- package/dist/scripts/akm-migrate.js +60 -126
- 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/storage/engines/sqlite-migrations.js +20 -1
- package/dist/storage/repositories/index-entries-repository.js +0 -15
- package/dist/tasks/backends/launchd.js +15 -20
- package/dist/tasks/backends/schtasks.js +18 -8
- package/dist/tasks/run/run-native-task.js +8 -6
- package/dist/tasks/source/bounded-document.js +2 -4
- 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/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/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;
|
|
@@ -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:
|
|
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
|
|
15990
|
-
sourceError(ctx, ["maxRetries"],
|
|
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:
|
|
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
|
|
16500
|
-
sourceError(ctx, ["akm", "maxRetries"],
|
|
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 >
|
|
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
|
|
16994
|
-
throw new Error(
|
|
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`,
|
|
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`,
|
|
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`,
|
|
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
|
|
18553
|
-
fail2(`${location}.max must be
|
|
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
|
|
18584
|
-
fail2(`${location}.branches must
|
|
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
|
|
18605
|
-
fail2(`${location}.maxLoops must be an integer
|
|
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
|
|
18639
|
-
fail2(`params must contain
|
|
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
|
|
18652
|
-
fail2(`outputs must contain
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
20178
|
-
ctx.err([...path13, "max"], `${stepLabel} "retry.max" is required and must be
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
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(["
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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,
|
|
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",
|