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
package/dist/registry/network.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
import { isIP } from "node:net";
|
|
5
|
+
import { backoffDelay, computeRetryDelay, abortableDelay as sharedAbortableDelay, shouldRetry } from "../core/common.js";
|
|
5
6
|
import { bareHostname, classifyNetworkAddress, classifyNetworkHostname, resolveHostnameAddresses, } from "../core/network-policy.js";
|
|
6
7
|
import { assertRegistryPinnedTransportAvailable, requestRegistryAddressPinned, } from "./pinned-transport.js";
|
|
7
8
|
export { requestRegistryAddressPinned } from "./pinned-transport.js";
|
|
@@ -77,7 +78,7 @@ async function requestRegistryHop(url, init, options) {
|
|
|
77
78
|
}
|
|
78
79
|
const response = await transport(url, address, init, remainingMs);
|
|
79
80
|
if (attempt < maxRetries && shouldRetry(response.status)) {
|
|
80
|
-
const delay =
|
|
81
|
+
const delay = computeRetryDelay(response, attempt, { maxDelayMs: MAX_REGISTRY_RETRY_DELAY_MS });
|
|
81
82
|
await cancelRegistryResponse(response);
|
|
82
83
|
await abortableDelay(delay, init?.signal);
|
|
83
84
|
continue;
|
|
@@ -87,7 +88,7 @@ async function requestRegistryHop(url, init, options) {
|
|
|
87
88
|
catch (error) {
|
|
88
89
|
if (attempt >= maxRetries || init?.signal?.aborted)
|
|
89
90
|
throw error;
|
|
90
|
-
await abortableDelay(backoffDelay(attempt), init?.signal);
|
|
91
|
+
await abortableDelay(backoffDelay(attempt, undefined, MAX_REGISTRY_RETRY_DELAY_MS), init?.signal);
|
|
91
92
|
}
|
|
92
93
|
}
|
|
93
94
|
throw new Error("Registry retry loop is unreachable");
|
|
@@ -217,45 +218,12 @@ function isRedirect(status) {
|
|
|
217
218
|
export async function cancelRegistryResponse(response) {
|
|
218
219
|
await response.body?.cancel().catch(() => undefined);
|
|
219
220
|
}
|
|
220
|
-
function shouldRetry(status) {
|
|
221
|
-
return status === 429 || status >= 500;
|
|
222
|
-
}
|
|
223
|
-
function retryDelay(response, attempt) {
|
|
224
|
-
const retryAfter = response.headers.get("retry-after");
|
|
225
|
-
if (retryAfter) {
|
|
226
|
-
const seconds = Number(retryAfter);
|
|
227
|
-
if (Number.isFinite(seconds)) {
|
|
228
|
-
return seconds >= 0 ? Math.min(MAX_REGISTRY_RETRY_DELAY_MS, seconds * 1_000) : backoffDelay(attempt);
|
|
229
|
-
}
|
|
230
|
-
const date = Date.parse(retryAfter);
|
|
231
|
-
if (Number.isFinite(date))
|
|
232
|
-
return Math.min(MAX_REGISTRY_RETRY_DELAY_MS, Math.max(0, date - Date.now()));
|
|
233
|
-
}
|
|
234
|
-
return backoffDelay(attempt);
|
|
235
|
-
}
|
|
236
|
-
function backoffDelay(attempt) {
|
|
237
|
-
return Math.min(MAX_REGISTRY_RETRY_DELAY_MS, 500 * 2 ** attempt * (0.5 + Math.random() * 0.5));
|
|
238
|
-
}
|
|
239
221
|
/** Test-only visibility for the server-controlled Retry-After clamp. */
|
|
240
222
|
export function _registryRetryDelayForTests(response, attempt) {
|
|
241
|
-
return
|
|
223
|
+
return computeRetryDelay(response, attempt, { maxDelayMs: MAX_REGISTRY_RETRY_DELAY_MS });
|
|
242
224
|
}
|
|
243
225
|
function abortableDelay(ms, signal) {
|
|
244
|
-
|
|
245
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
246
|
-
if (signal.aborted)
|
|
247
|
-
return Promise.reject(signal.reason ?? new Error("Registry request aborted"));
|
|
248
|
-
return new Promise((resolve, reject) => {
|
|
249
|
-
const timer = setTimeout(() => {
|
|
250
|
-
signal.removeEventListener("abort", onAbort);
|
|
251
|
-
resolve();
|
|
252
|
-
}, ms);
|
|
253
|
-
const onAbort = () => {
|
|
254
|
-
clearTimeout(timer);
|
|
255
|
-
reject(signal.reason ?? new Error("Registry request aborted"));
|
|
256
|
-
};
|
|
257
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
258
|
-
});
|
|
226
|
+
return sharedAbortableDelay(ms, signal, "Registry request aborted");
|
|
259
227
|
}
|
|
260
228
|
/** Existing local HTTP fixtures remain available only inside the test process. */
|
|
261
229
|
export function allowPrivateRegistryFixtureForTests(rawUrl) {
|
package/dist/runtime.js
CHANGED
|
@@ -135,18 +135,10 @@ function stdioFor(mode) {
|
|
|
135
135
|
return mode ?? "pipe";
|
|
136
136
|
}
|
|
137
137
|
// ── Stdin ───────────────────────────────────────────────────────────────────
|
|
138
|
-
/**
|
|
139
|
-
|
|
140
|
-
* than `limitBytes` is read, `onLimitExceeded()` is invoked and its return (an
|
|
141
|
-
* Error) is thrown — callers supply their own message so behaviour is exact.
|
|
142
|
-
*/
|
|
143
|
-
export async function readStdin(limitBytes, onLimitExceeded) {
|
|
138
|
+
/** Read all of stdin as a single `Buffer`. */
|
|
139
|
+
export async function readStdin() {
|
|
144
140
|
const chunks = [];
|
|
145
|
-
let total = 0;
|
|
146
141
|
for await (const chunk of stdinIterator()) {
|
|
147
|
-
total += chunk.byteLength;
|
|
148
|
-
if (total > limitBytes)
|
|
149
|
-
throw onLimitExceeded();
|
|
150
142
|
chunks.push(chunk);
|
|
151
143
|
}
|
|
152
144
|
return Buffer.concat(chunks);
|
|
@@ -9380,8 +9380,6 @@ function getRegistryIndexCacheDir() {
|
|
|
9380
9380
|
}
|
|
9381
9381
|
|
|
9382
9382
|
// src/core/common.ts
|
|
9383
|
-
var MAX_CONFIG_FILE_BYTES = 1024 * 1024;
|
|
9384
|
-
var MAX_LOCAL_METADATA_BYTES = 1024 * 1024;
|
|
9385
9383
|
var MAX_LOCK_METADATA_BYTES = 64 * 1024;
|
|
9386
9384
|
function readTextFileDescriptorWithLimit(fd, maxBytes, label = "File", displayPath = "(open file)") {
|
|
9387
9385
|
const stat = fs.fstatSync(fd);
|
|
@@ -9403,10 +9401,13 @@ function readTextFileDescriptorWithLimit(fd, maxBytes, label = "File", displayPa
|
|
|
9403
9401
|
}
|
|
9404
9402
|
return buffer.subarray(0, total).toString("utf8");
|
|
9405
9403
|
}
|
|
9406
|
-
function
|
|
9404
|
+
function readTextFile(filePath, label = "File") {
|
|
9407
9405
|
const fd = fs.openSync(filePath, "r");
|
|
9408
9406
|
try {
|
|
9409
|
-
|
|
9407
|
+
const stat = fs.fstatSync(fd);
|
|
9408
|
+
if (!stat.isFile())
|
|
9409
|
+
throw new ConfigError(`${label} is not a regular file: ${filePath}.`, "INVALID_CONFIG_FILE");
|
|
9410
|
+
return fs.readFileSync(fd, "utf8");
|
|
9410
9411
|
} finally {
|
|
9411
9412
|
fs.closeSync(fd);
|
|
9412
9413
|
}
|
|
@@ -9506,6 +9507,8 @@ function asNonEmptyString(value) {
|
|
|
9506
9507
|
return trimmed.length > 0 ? trimmed : undefined;
|
|
9507
9508
|
}
|
|
9508
9509
|
function isProcessAlive(pid) {
|
|
9510
|
+
if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0)
|
|
9511
|
+
return false;
|
|
9509
9512
|
try {
|
|
9510
9513
|
process.kill(pid, 0);
|
|
9511
9514
|
return true;
|
|
@@ -14957,25 +14960,13 @@ var EXECUTION_MAX_TIMEOUT_MS = 2 ** 31 - 1;
|
|
|
14957
14960
|
// src/workflows/resource-limits.ts
|
|
14958
14961
|
var WORKFLOW_MAX_PLAN_BYTES = 2 * 1024 * 1024;
|
|
14959
14962
|
var WORKFLOW_MAX_SOURCE_BYTES = 1024 * 1024;
|
|
14960
|
-
var WORKFLOW_MAX_STEPS = 256;
|
|
14961
|
-
var WORKFLOW_MAX_PARAMS = 128;
|
|
14962
|
-
var WORKFLOW_MAX_ROUTE_BRANCHES = 256;
|
|
14963
14963
|
var WORKFLOW_MAX_INSTRUCTION_BYTES = 256 * 1024;
|
|
14964
14964
|
var WORKFLOW_MAX_SCHEMA_BYTES = 256 * 1024;
|
|
14965
14965
|
var WORKFLOW_MAX_EXTRA_PARAMS_BYTES = 64 * 1024;
|
|
14966
|
-
var WORKFLOW_MAX_MAP_EXPANSION = 1e4;
|
|
14967
|
-
var WORKFLOW_MAX_INPUTS = 64;
|
|
14968
|
-
var WORKFLOW_MAX_OUTPUTS = 64;
|
|
14969
14966
|
var WORKFLOW_MAX_CONCURRENCY = 64;
|
|
14970
|
-
var WORKFLOW_MAX_GATE_LOOPS = 100;
|
|
14971
|
-
var WORKFLOW_MAX_RETRIES = 100;
|
|
14972
14967
|
var WORKFLOW_MAX_TIMEOUT_MS = EXECUTION_MAX_TIMEOUT_MS;
|
|
14973
14968
|
var WORKFLOW_ENGINE_NAME_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
|
|
14974
14969
|
var WORKFLOW_MAX_ENGINE_NAME_LENGTH = 63;
|
|
14975
|
-
var WORKFLOW_MAX_EXEC_ARGV = 64;
|
|
14976
|
-
var WORKFLOW_MAX_EXEC_ARG_BYTES = 4096;
|
|
14977
|
-
var WORKFLOW_MAX_EXEC_CWD_LENGTH = 1024;
|
|
14978
|
-
var WORKFLOW_MAX_EXEC_PASS_ENV = 32;
|
|
14979
14970
|
var WORKFLOW_ENV_VAR_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
14980
14971
|
var WORKFLOW_MAX_EXEC_OUTPUT_BYTES = 8 * 1024 * 1024;
|
|
14981
14972
|
var EXEC_CONTEXT_LIMITS_POSIX = {
|
|
@@ -14993,13 +14984,13 @@ function jsonBytes(value) {
|
|
|
14993
14984
|
var WORKFLOW_MAX_EMBEDDED_CHILD_PLAN_BYTES = 1024 * 1024;
|
|
14994
14985
|
|
|
14995
14986
|
// src/tasks/source/bounded-document.ts
|
|
14996
|
-
var TASK_V3_MAX_SOURCE_BYTES = 1024 * 1024;
|
|
14997
14987
|
var TASK_V3_MAX_JSON_DEPTH = 64;
|
|
14998
14988
|
var TASK_V3_MAX_JSON_NODES = 1e4;
|
|
14999
14989
|
var TASK_V3_MAX_COLLECTION_ITEMS = 1024;
|
|
15000
14990
|
var TASK_V3_MAX_OBJECT_KEYS = 256;
|
|
15001
14991
|
var TASK_V3_MAX_STRING_BYTES = 256 * 1024;
|
|
15002
14992
|
var TASK_V3_MAX_SCHEDULES = 64;
|
|
14993
|
+
var TASK_V3_MAX_REDACT_NAMES = 32;
|
|
15003
14994
|
function own2(value, key) {
|
|
15004
14995
|
return Object.hasOwn(value, key);
|
|
15005
14996
|
}
|
|
@@ -15288,9 +15279,6 @@ function readBoundedTaskSourceYaml(input, options) {
|
|
|
15288
15279
|
if (typeof input.yaml !== "string") {
|
|
15289
15280
|
throw new UsageError(`Invalid ${sourceLabel} at ${input.filePath}: source must be a string.`, "TASK_SOURCE_INVALID");
|
|
15290
15281
|
}
|
|
15291
|
-
if (utf8Bytes2(input.yaml) > TASK_V3_MAX_SOURCE_BYTES) {
|
|
15292
|
-
throw new UsageError(`Invalid ${sourceLabel} at ${input.filePath}: source exceeds the 1 MiB (${TASK_V3_MAX_SOURCE_BYTES}-byte) resource limit.`, "TASK_SOURCE_INVALID");
|
|
15293
|
-
}
|
|
15294
15282
|
const lineCounter2 = new $LineCounter;
|
|
15295
15283
|
let document;
|
|
15296
15284
|
try {
|
|
@@ -16050,7 +16038,7 @@ function parseExecutionControls(input, ctx) {
|
|
|
16050
16038
|
out.timeout = parseTimeoutTopLevel(input.timeout, ctx);
|
|
16051
16039
|
if (own2(input, "redact")) {
|
|
16052
16040
|
const names = parseStringArray(input.redact, ctx, ["redact"], {
|
|
16053
|
-
max:
|
|
16041
|
+
max: TASK_V3_MAX_REDACT_NAMES,
|
|
16054
16042
|
pattern: WORKFLOW_ENV_VAR_NAME_PATTERN
|
|
16055
16043
|
});
|
|
16056
16044
|
if (new Set(names).size !== names.length)
|
|
@@ -16064,8 +16052,8 @@ function parseExecutionControls(input, ctx) {
|
|
|
16064
16052
|
out.maxSteps = input.maxSteps;
|
|
16065
16053
|
}
|
|
16066
16054
|
if (own2(input, "maxRetries")) {
|
|
16067
|
-
if (!Number.isSafeInteger(input.maxRetries) || input.maxRetries < 0
|
|
16068
|
-
sourceError(ctx, ["maxRetries"],
|
|
16055
|
+
if (!Number.isSafeInteger(input.maxRetries) || input.maxRetries < 0) {
|
|
16056
|
+
sourceError(ctx, ["maxRetries"], "must be a non-negative safe integer.");
|
|
16069
16057
|
}
|
|
16070
16058
|
out.maxRetries = input.maxRetries;
|
|
16071
16059
|
}
|
|
@@ -16125,9 +16113,6 @@ function parseInputDeclaration(name, raw, ctx) {
|
|
|
16125
16113
|
function parseInputDeclarations(value, ctx) {
|
|
16126
16114
|
const input = asRecord(value, ctx, ["inputs"]);
|
|
16127
16115
|
const names = Object.keys(input);
|
|
16128
|
-
if (names.length > WORKFLOW_MAX_PARAMS) {
|
|
16129
|
-
sourceError(ctx, ["inputs"], `accepts at most ${WORKFLOW_MAX_PARAMS} declared inputs.`);
|
|
16130
|
-
}
|
|
16131
16116
|
const result = {};
|
|
16132
16117
|
for (const name of names) {
|
|
16133
16118
|
if (!INPUT_NAME_PATTERN.test(name)) {
|
|
@@ -16560,7 +16545,7 @@ function parseAkm(value, ctx) {
|
|
|
16560
16545
|
out.timeout = parseTimeout(input.timeout, ctx);
|
|
16561
16546
|
if (own2(input, "redact")) {
|
|
16562
16547
|
const names = parseStringArray(input.redact, ctx, ["akm", "redact"], {
|
|
16563
|
-
max:
|
|
16548
|
+
max: TASK_V3_MAX_REDACT_NAMES,
|
|
16564
16549
|
pattern: WORKFLOW_ENV_VAR_NAME_PATTERN
|
|
16565
16550
|
});
|
|
16566
16551
|
if (new Set(names).size !== names.length)
|
|
@@ -16574,8 +16559,8 @@ function parseAkm(value, ctx) {
|
|
|
16574
16559
|
out.maxSteps = input.maxSteps;
|
|
16575
16560
|
}
|
|
16576
16561
|
if (own2(input, "maxRetries")) {
|
|
16577
|
-
if (!Number.isSafeInteger(input.maxRetries) || input.maxRetries < 0
|
|
16578
|
-
sourceError(ctx, ["akm", "maxRetries"],
|
|
16562
|
+
if (!Number.isSafeInteger(input.maxRetries) || input.maxRetries < 0) {
|
|
16563
|
+
sourceError(ctx, ["akm", "maxRetries"], "must be a non-negative safe integer.");
|
|
16579
16564
|
}
|
|
16580
16565
|
out.maxRetries = input.maxRetries;
|
|
16581
16566
|
}
|
|
@@ -16892,9 +16877,6 @@ function optionalString(value, label) {
|
|
|
16892
16877
|
return exactString(value, label);
|
|
16893
16878
|
}
|
|
16894
16879
|
function parseLegacyTaskYaml(input) {
|
|
16895
|
-
if (input.bytes.byteLength > TASK_V3_MAX_SOURCE_BYTES) {
|
|
16896
|
-
throw new Error(`task YAML exceeds the 1 MiB (${TASK_V3_MAX_SOURCE_BYTES}-byte) source resource limit`);
|
|
16897
|
-
}
|
|
16898
16880
|
let source;
|
|
16899
16881
|
try {
|
|
16900
16882
|
source = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(input.bytes);
|
|
@@ -16942,7 +16924,7 @@ function validateCommonV2(data) {
|
|
|
16942
16924
|
}
|
|
16943
16925
|
}
|
|
16944
16926
|
if (data.redact !== undefined && data.redact !== null) {
|
|
16945
|
-
if (!Array.isArray(data.redact) || data.redact.length >
|
|
16927
|
+
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))) {
|
|
16946
16928
|
throw new Error("redact must contain only bounded environment variable names");
|
|
16947
16929
|
}
|
|
16948
16930
|
}
|
|
@@ -17068,8 +17050,8 @@ function migratedObject(data) {
|
|
|
17068
17050
|
akm.maxSteps = data.maxSteps;
|
|
17069
17051
|
}
|
|
17070
17052
|
if (data.maxRetries !== undefined && data.maxRetries !== null) {
|
|
17071
|
-
if (!Number.isSafeInteger(data.maxRetries) || data.maxRetries < 0
|
|
17072
|
-
throw new Error(
|
|
17053
|
+
if (!Number.isSafeInteger(data.maxRetries) || data.maxRetries < 0) {
|
|
17054
|
+
throw new Error("maxRetries must be a non-negative integer");
|
|
17073
17055
|
}
|
|
17074
17056
|
akm.maxRetries = data.maxRetries;
|
|
17075
17057
|
}
|
|
@@ -17328,9 +17310,6 @@ function exactString2(value, label, nonempty = false) {
|
|
|
17328
17310
|
return value;
|
|
17329
17311
|
}
|
|
17330
17312
|
function parseV3RawYaml(input) {
|
|
17331
|
-
if (input.bytes.byteLength > TASK_V3_MAX_SOURCE_BYTES) {
|
|
17332
|
-
throw new Error(`task YAML exceeds the 1 MiB (${TASK_V3_MAX_SOURCE_BYTES}-byte) source resource limit`);
|
|
17333
|
-
}
|
|
17334
17313
|
let source;
|
|
17335
17314
|
try {
|
|
17336
17315
|
source = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(input.bytes);
|
|
@@ -18531,7 +18510,7 @@ function validateStep(value, jobId, index, stepIds, options) {
|
|
|
18531
18510
|
}
|
|
18532
18511
|
validateMap(step.map, `step ${id} map`);
|
|
18533
18512
|
validateRoute(step.route, `step ${id} route`);
|
|
18534
|
-
optionalStringList(step.inputs, `step ${id} inputs`,
|
|
18513
|
+
optionalStringList(step.inputs, `step ${id} inputs`, Infinity);
|
|
18535
18514
|
if (Array.isArray(step.inputs)) {
|
|
18536
18515
|
for (const [inputIndex, input] of step.inputs.entries())
|
|
18537
18516
|
validateReference(input, `step ${id} inputs[${inputIndex}]`);
|
|
@@ -18553,12 +18532,7 @@ function validateExec(value, location, options) {
|
|
|
18553
18532
|
return;
|
|
18554
18533
|
const exec = record(value, location);
|
|
18555
18534
|
keys(exec, ["command", "cwd", "passEnv"], location);
|
|
18556
|
-
stringList(exec.command, `${location}.command`,
|
|
18557
|
-
for (const [index, argument] of exec.command.entries()) {
|
|
18558
|
-
if (utf8Bytes(argument) > WORKFLOW_MAX_EXEC_ARG_BYTES) {
|
|
18559
|
-
fail2(`${location}.command[${index}] exceeds ${WORKFLOW_MAX_EXEC_ARG_BYTES} bytes`);
|
|
18560
|
-
}
|
|
18561
|
-
}
|
|
18535
|
+
stringList(exec.command, `${location}.command`, Infinity, false);
|
|
18562
18536
|
try {
|
|
18563
18537
|
rejectNulInArgv(exec.command);
|
|
18564
18538
|
} catch (cause) {
|
|
@@ -18566,9 +18540,6 @@ function validateExec(value, location, options) {
|
|
|
18566
18540
|
}
|
|
18567
18541
|
optionalString2(exec.cwd, `${location}.cwd`);
|
|
18568
18542
|
if (exec.cwd !== undefined) {
|
|
18569
|
-
if (exec.cwd.length > WORKFLOW_MAX_EXEC_CWD_LENGTH) {
|
|
18570
|
-
fail2(`${location}.cwd exceeds ${WORKFLOW_MAX_EXEC_CWD_LENGTH} characters`);
|
|
18571
|
-
}
|
|
18572
18543
|
try {
|
|
18573
18544
|
exec.cwd = canonicalizeWorkflowWorkingDirectory(exec.cwd, options.workspaceRoot);
|
|
18574
18545
|
} catch (cause) {
|
|
@@ -18576,7 +18547,7 @@ function validateExec(value, location, options) {
|
|
|
18576
18547
|
}
|
|
18577
18548
|
}
|
|
18578
18549
|
if (exec.passEnv !== undefined) {
|
|
18579
|
-
stringList(exec.passEnv, `${location}.passEnv`,
|
|
18550
|
+
stringList(exec.passEnv, `${location}.passEnv`, Infinity, false);
|
|
18580
18551
|
}
|
|
18581
18552
|
if (Array.isArray(exec.passEnv)) {
|
|
18582
18553
|
for (const name of exec.passEnv) {
|
|
@@ -18627,8 +18598,8 @@ function validateRetry(value, location) {
|
|
|
18627
18598
|
return;
|
|
18628
18599
|
const retry = record(value, location);
|
|
18629
18600
|
keys(retry, ["max", "on"], location);
|
|
18630
|
-
if (!Number.isSafeInteger(retry.max) || retry.max < 0
|
|
18631
|
-
fail2(`${location}.max must be
|
|
18601
|
+
if (!Number.isSafeInteger(retry.max) || retry.max < 0) {
|
|
18602
|
+
fail2(`${location}.max must be a non-negative integer`);
|
|
18632
18603
|
}
|
|
18633
18604
|
stringList(retry.on, `${location}.on`, PROGRAM_RETRY_REASONS.length, false);
|
|
18634
18605
|
for (const reason of retry.on) {
|
|
@@ -18658,8 +18629,8 @@ function validateRoute(value, location) {
|
|
|
18658
18629
|
keys(route, ["input", "branches", "defaultStepId"], location);
|
|
18659
18630
|
nonEmptyString2(route.input, `${location}.input`);
|
|
18660
18631
|
validateReference(route.input, `${location}.input`);
|
|
18661
|
-
if (!Array.isArray(route.branches) || route.branches.length === 0
|
|
18662
|
-
fail2(`${location}.branches must
|
|
18632
|
+
if (!Array.isArray(route.branches) || route.branches.length === 0) {
|
|
18633
|
+
fail2(`${location}.branches must be a non-empty array`);
|
|
18663
18634
|
}
|
|
18664
18635
|
const matches = new Set;
|
|
18665
18636
|
for (const [index, value2] of route.branches.entries()) {
|
|
@@ -18679,8 +18650,8 @@ function validateGate(value, location) {
|
|
|
18679
18650
|
return;
|
|
18680
18651
|
const gate = record(value, location);
|
|
18681
18652
|
keys(gate, ["maxLoops", "rubric"], location);
|
|
18682
|
-
if (gate.maxLoops !== undefined && (!Number.isSafeInteger(gate.maxLoops) || gate.maxLoops < 1
|
|
18683
|
-
fail2(`${location}.maxLoops must be an integer
|
|
18653
|
+
if (gate.maxLoops !== undefined && (!Number.isSafeInteger(gate.maxLoops) || gate.maxLoops < 1)) {
|
|
18654
|
+
fail2(`${location}.maxLoops must be an integer of at least 1`);
|
|
18684
18655
|
}
|
|
18685
18656
|
optionalString2(gate.rubric, `${location}.rubric`);
|
|
18686
18657
|
}
|
|
@@ -18713,8 +18684,8 @@ function validateParams(value) {
|
|
|
18713
18684
|
if (value === undefined)
|
|
18714
18685
|
return;
|
|
18715
18686
|
const params = record(value, "params");
|
|
18716
|
-
if (Object.keys(params).length === 0
|
|
18717
|
-
fail2(`params must contain
|
|
18687
|
+
if (Object.keys(params).length === 0) {
|
|
18688
|
+
fail2(`params must contain at least one entry`);
|
|
18718
18689
|
}
|
|
18719
18690
|
for (const [name, schema] of Object.entries(params)) {
|
|
18720
18691
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))
|
|
@@ -18726,8 +18697,8 @@ function validateOutputs(value) {
|
|
|
18726
18697
|
if (value === undefined)
|
|
18727
18698
|
return;
|
|
18728
18699
|
const outputs = record(value, "outputs");
|
|
18729
|
-
if (Object.keys(outputs).length === 0
|
|
18730
|
-
fail2(`outputs must contain
|
|
18700
|
+
if (Object.keys(outputs).length === 0) {
|
|
18701
|
+
fail2(`outputs must contain at least one entry`);
|
|
18731
18702
|
}
|
|
18732
18703
|
for (const [name, declaration] of Object.entries(outputs)) {
|
|
18733
18704
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))
|
|
@@ -18750,9 +18721,6 @@ function validateBudget(value) {
|
|
|
18750
18721
|
fail2(`budget.${key} must be a positive integer`);
|
|
18751
18722
|
}
|
|
18752
18723
|
}
|
|
18753
|
-
if (typeof budget.maxUnits === "number" && budget.maxUnits > WORKFLOW_MAX_MAP_EXPANSION) {
|
|
18754
|
-
fail2(`budget.maxUnits must be at most ${WORKFLOW_MAX_MAP_EXPANSION}`);
|
|
18755
|
-
}
|
|
18756
18724
|
}
|
|
18757
18725
|
function validateLlm(value, location) {
|
|
18758
18726
|
if (value === undefined)
|
|
@@ -19336,12 +19304,6 @@ function checkXrefs(value, line, errors2) {
|
|
|
19336
19304
|
}
|
|
19337
19305
|
}
|
|
19338
19306
|
function checkResourceLimits(draft, errors2) {
|
|
19339
|
-
if (draft.steps.length > WORKFLOW_MAX_STEPS) {
|
|
19340
|
-
errors2.push({ line: 1, message: `Workflow must contain at most ${WORKFLOW_MAX_STEPS} steps.` });
|
|
19341
|
-
}
|
|
19342
|
-
if (Object.keys(draft.params ?? {}).length > WORKFLOW_MAX_PARAMS) {
|
|
19343
|
-
errors2.push({ line: 1, message: `Workflow must contain at most ${WORKFLOW_MAX_PARAMS} parameters.` });
|
|
19344
|
-
}
|
|
19345
19307
|
for (const step of draft.steps) {
|
|
19346
19308
|
if (step.instructions && utf8Bytes(step.instructions.text) > WORKFLOW_MAX_INSTRUCTION_BYTES) {
|
|
19347
19309
|
errors2.push({
|
|
@@ -19703,9 +19665,6 @@ function parseParams(ctx, raw) {
|
|
|
19703
19665
|
ctx.err(["params"], `"params" must be a mapping of param name to a JSON Schema object (e.g. changed_files: { type: array }).`);
|
|
19704
19666
|
return;
|
|
19705
19667
|
}
|
|
19706
|
-
if (Object.keys(raw).length > WORKFLOW_MAX_PARAMS) {
|
|
19707
|
-
ctx.err(["params"], `"params" must contain at most ${WORKFLOW_MAX_PARAMS} entries.`);
|
|
19708
|
-
}
|
|
19709
19668
|
const params = {};
|
|
19710
19669
|
for (const [paramName, value] of Object.entries(raw)) {
|
|
19711
19670
|
if (!INPUT_NAME_PATTERN.test(paramName)) {
|
|
@@ -19731,9 +19690,6 @@ function parseOutputs(ctx, raw) {
|
|
|
19731
19690
|
ctx.err(["outputs"], `"outputs" must be a mapping of output name to { from, schema? } (e.g. report: { from: steps.summarize.output }).`);
|
|
19732
19691
|
return;
|
|
19733
19692
|
}
|
|
19734
|
-
if (Object.keys(raw).length > WORKFLOW_MAX_OUTPUTS) {
|
|
19735
|
-
ctx.err(["outputs"], `"outputs" must contain at most ${WORKFLOW_MAX_OUTPUTS} entries.`);
|
|
19736
|
-
}
|
|
19737
19693
|
const outputs = {};
|
|
19738
19694
|
for (const [outputName, value] of Object.entries(raw)) {
|
|
19739
19695
|
const path13 = ["outputs", outputName];
|
|
@@ -19825,10 +19781,10 @@ function parseBudget(ctx, raw) {
|
|
|
19825
19781
|
}
|
|
19826
19782
|
}
|
|
19827
19783
|
if (raw.max_units !== undefined) {
|
|
19828
|
-
if (typeof raw.max_units === "number" && Number.isInteger(raw.max_units) && raw.max_units >= 1
|
|
19784
|
+
if (typeof raw.max_units === "number" && Number.isInteger(raw.max_units) && raw.max_units >= 1) {
|
|
19829
19785
|
budget.maxUnits = raw.max_units;
|
|
19830
19786
|
} else {
|
|
19831
|
-
ctx.err([...path13, "max_units"], `"budget.max_units" must be an integer
|
|
19787
|
+
ctx.err([...path13, "max_units"], `"budget.max_units" must be an integer >= 1.`);
|
|
19832
19788
|
}
|
|
19833
19789
|
}
|
|
19834
19790
|
return Object.keys(budget).length > 0 ? budget : undefined;
|
|
@@ -19838,9 +19794,6 @@ function parseSteps(ctx, raw) {
|
|
|
19838
19794
|
ctx.err(["steps"], `"steps" is required and must be a list with at least one step.`);
|
|
19839
19795
|
return [];
|
|
19840
19796
|
}
|
|
19841
|
-
if (raw.length > WORKFLOW_MAX_STEPS) {
|
|
19842
|
-
ctx.err(["steps"], `"steps" must contain at most ${WORKFLOW_MAX_STEPS} entries.`);
|
|
19843
|
-
}
|
|
19844
19797
|
const idIndex = new Map;
|
|
19845
19798
|
raw.forEach((rawStep, index) => {
|
|
19846
19799
|
if (isPlainRecord(rawStep) && typeof rawStep.id === "string" && !idIndex.has(rawStep.id)) {
|
|
@@ -20011,10 +19964,6 @@ function parseExecPassEnv(ctx, raw, path13, stepLabel) {
|
|
|
20011
19964
|
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 — use "env:" bindings for those.`);
|
|
20012
19965
|
return;
|
|
20013
19966
|
}
|
|
20014
|
-
if (raw.length > WORKFLOW_MAX_EXEC_PASS_ENV) {
|
|
20015
|
-
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.`);
|
|
20016
|
-
return;
|
|
20017
|
-
}
|
|
20018
19967
|
const names = [];
|
|
20019
19968
|
for (const [index, entry] of raw.entries()) {
|
|
20020
19969
|
if (typeof entry !== "string" || !WORKFLOW_ENV_VAR_NAME_PATTERN.test(entry)) {
|
|
@@ -20034,10 +19983,6 @@ function parseExecCommand(ctx, raw, path13, stepLabel) {
|
|
|
20034
19983
|
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 — the command is spawned directly, never through a shell.`);
|
|
20035
19984
|
return;
|
|
20036
19985
|
}
|
|
20037
|
-
if (raw.length > WORKFLOW_MAX_EXEC_ARGV) {
|
|
20038
|
-
ctx.err(path13, `${stepLabel} "exec.command" must have at most ${WORKFLOW_MAX_EXEC_ARGV} entries.`);
|
|
20039
|
-
return;
|
|
20040
|
-
}
|
|
20041
19986
|
const argv = [];
|
|
20042
19987
|
for (const [index, entry] of raw.entries()) {
|
|
20043
19988
|
if (typeof entry !== "string" || entry === "") {
|
|
@@ -20048,10 +19993,6 @@ function parseExecCommand(ctx, raw, path13, stepLabel) {
|
|
|
20048
19993
|
ctx.err([...path13, index], `${stepLabel} "exec.command[${index}]" may not contain NUL bytes.`);
|
|
20049
19994
|
return;
|
|
20050
19995
|
}
|
|
20051
|
-
if (utf8Bytes(entry) > WORKFLOW_MAX_EXEC_ARG_BYTES) {
|
|
20052
|
-
ctx.err(path13, `${stepLabel} "exec.command[${index}]" exceeds ${WORKFLOW_MAX_EXEC_ARG_BYTES} bytes.`);
|
|
20053
|
-
return;
|
|
20054
|
-
}
|
|
20055
19996
|
argv.push(entry);
|
|
20056
19997
|
}
|
|
20057
19998
|
return argv;
|
|
@@ -20064,10 +20005,6 @@ function parseExecCwd(ctx, raw, path13, stepLabel) {
|
|
|
20064
20005
|
return;
|
|
20065
20006
|
}
|
|
20066
20007
|
const value = raw.trim();
|
|
20067
|
-
if (value.length > WORKFLOW_MAX_EXEC_CWD_LENGTH) {
|
|
20068
|
-
ctx.err(path13, `${stepLabel} "exec.cwd" exceeds ${WORKFLOW_MAX_EXEC_CWD_LENGTH} characters.`);
|
|
20069
|
-
return;
|
|
20070
|
-
}
|
|
20071
20008
|
if (!isContainedRelativePath(value)) {
|
|
20072
20009
|
ctx.err(path13, `${stepLabel} "exec.cwd" (${JSON.stringify(value)}) must be a RELATIVE path inside the unit's working ` + `directory — absolute paths, Windows drive letters, "~", and ".." segments are rejected.`);
|
|
20073
20010
|
return;
|
|
@@ -20101,10 +20038,10 @@ function parseMap(ctx, raw, path13, stepLabel) {
|
|
|
20101
20038
|
}
|
|
20102
20039
|
let concurrency;
|
|
20103
20040
|
if (raw.concurrency !== undefined) {
|
|
20104
|
-
if (typeof raw.concurrency === "number" && Number.isInteger(raw.concurrency) && raw.concurrency > 0
|
|
20105
|
-
concurrency = raw.concurrency;
|
|
20041
|
+
if (typeof raw.concurrency === "number" && Number.isInteger(raw.concurrency) && raw.concurrency > 0) {
|
|
20042
|
+
concurrency = Math.min(raw.concurrency, WORKFLOW_MAX_CONCURRENCY);
|
|
20106
20043
|
} else {
|
|
20107
|
-
ctx.err([...path13, "concurrency"], `${stepLabel} "concurrency" must be
|
|
20044
|
+
ctx.err([...path13, "concurrency"], `${stepLabel} "concurrency" must be a positive integer.`);
|
|
20108
20045
|
}
|
|
20109
20046
|
}
|
|
20110
20047
|
const reducer = parseEnumField(ctx, raw.reducer, [...path13, "reducer"], `${stepLabel} "reducer"`, PROGRAM_REDUCERS);
|
|
@@ -20136,9 +20073,6 @@ function parseRoute(ctx, raw, path13, stepLabel, stepIndex, routeChecks) {
|
|
|
20136
20073
|
if (!Array.isArray(raw.when) || raw.when.length === 0) {
|
|
20137
20074
|
ctx.err(whenPath, `${stepLabel} "route" requires "when": a non-empty list of { match, step } branches (e.g. when: [{ match: pass, step: ship }]).`);
|
|
20138
20075
|
} else {
|
|
20139
|
-
if (raw.when.length > WORKFLOW_MAX_ROUTE_BRANCHES) {
|
|
20140
|
-
ctx.err(whenPath, `${stepLabel} "when" must contain at most ${WORKFLOW_MAX_ROUTE_BRANCHES} branches.`);
|
|
20141
|
-
}
|
|
20142
20076
|
const seenMatches = new Map;
|
|
20143
20077
|
raw.when.forEach((branch, i) => {
|
|
20144
20078
|
const branchPath = [...whenPath, i];
|
|
@@ -20194,9 +20128,6 @@ function parseInputs(ctx, raw, path13, stepLabel) {
|
|
|
20194
20128
|
ctx.err(path13, `${stepLabel} "inputs" must be a non-empty list of reference strings.`);
|
|
20195
20129
|
return;
|
|
20196
20130
|
}
|
|
20197
|
-
if (raw.length > WORKFLOW_MAX_INPUTS) {
|
|
20198
|
-
ctx.err(path13, `${stepLabel} "inputs" must contain at most ${WORKFLOW_MAX_INPUTS} entries.`);
|
|
20199
|
-
}
|
|
20200
20131
|
const out = [];
|
|
20201
20132
|
const seen = new Set;
|
|
20202
20133
|
raw.forEach((entry, i) => {
|
|
@@ -20223,10 +20154,10 @@ function parseGate(ctx, raw, path13, stepLabel) {
|
|
|
20223
20154
|
checkUnknownKeys(ctx, raw, path13, GATE_KEYS, `${stepLabel} "gate"`);
|
|
20224
20155
|
const gate = {};
|
|
20225
20156
|
if (raw.max_loops !== undefined) {
|
|
20226
|
-
if (typeof raw.max_loops === "number" && Number.isInteger(raw.max_loops) && raw.max_loops >= 1
|
|
20157
|
+
if (typeof raw.max_loops === "number" && Number.isInteger(raw.max_loops) && raw.max_loops >= 1) {
|
|
20227
20158
|
gate.maxLoops = raw.max_loops;
|
|
20228
20159
|
} else {
|
|
20229
|
-
ctx.err([...path13, "max_loops"], `${stepLabel} "gate.max_loops" must be an integer
|
|
20160
|
+
ctx.err([...path13, "max_loops"], `${stepLabel} "gate.max_loops" must be an integer of at least 1.`);
|
|
20230
20161
|
}
|
|
20231
20162
|
}
|
|
20232
20163
|
return gate;
|
|
@@ -20252,8 +20183,8 @@ function parseRetry(ctx, raw, path13, stepLabel) {
|
|
|
20252
20183
|
}
|
|
20253
20184
|
checkUnknownKeys(ctx, raw, path13, RETRY_KEYS, `${stepLabel} "retry"`);
|
|
20254
20185
|
let ok = true;
|
|
20255
|
-
if (!(typeof raw.max === "number" && Number.isInteger(raw.max) && raw.max >= 0
|
|
20256
|
-
ctx.err([...path13, "max"], `${stepLabel} "retry.max" is required and must be
|
|
20186
|
+
if (!(typeof raw.max === "number" && Number.isInteger(raw.max) && raw.max >= 0)) {
|
|
20187
|
+
ctx.err([...path13, "max"], `${stepLabel} "retry.max" is required and must be a non-negative integer.`);
|
|
20257
20188
|
ok = false;
|
|
20258
20189
|
}
|
|
20259
20190
|
const on = [];
|
|
@@ -23841,7 +23772,7 @@ function withLockOperationMutex(lockPath, run) {
|
|
|
23841
23772
|
db.exec("BEGIN IMMEDIATE");
|
|
23842
23773
|
began = db.inTransaction;
|
|
23843
23774
|
if (!began)
|
|
23844
|
-
|
|
23775
|
+
sleepSync(2 ** attempt);
|
|
23845
23776
|
}
|
|
23846
23777
|
if (!began)
|
|
23847
23778
|
throw new Error(`Could not acquire lock operation mutex for ${lockPath}.`);
|
|
@@ -24004,7 +23935,7 @@ function extractHolderPid(content) {
|
|
|
24004
23935
|
// src/core/config/config-io.ts
|
|
24005
23936
|
function readConfigText(configPath) {
|
|
24006
23937
|
try {
|
|
24007
|
-
return
|
|
23938
|
+
return readTextFile(configPath, "Config file");
|
|
24008
23939
|
} catch (err) {
|
|
24009
23940
|
if (err.code === "ENOENT")
|
|
24010
23941
|
return;
|
|
@@ -28111,9 +28042,6 @@ var ExtraParamsSchema = exports_external.record(exports_external.unknown()).supe
|
|
|
28111
28042
|
ctx.addIssue({ code: exports_external.ZodIssueCode.custom, path: issue.path, message: issue.message });
|
|
28112
28043
|
}
|
|
28113
28044
|
});
|
|
28114
|
-
var LlmCapabilitiesSchema = exports_external.object({
|
|
28115
|
-
structuredOutput: exports_external.boolean().optional()
|
|
28116
|
-
}).passthrough();
|
|
28117
28045
|
var LlmInvocationOverridesSchema = exports_external.object({
|
|
28118
28046
|
temperature: exports_external.number().finite().optional(),
|
|
28119
28047
|
maxTokens: positiveInt.optional(),
|
|
@@ -28169,15 +28097,13 @@ var LlmConnectionConfigSchema = exports_external.object({
|
|
|
28169
28097
|
maxTokens: positiveInt.optional(),
|
|
28170
28098
|
timeoutMs: timeoutMsField,
|
|
28171
28099
|
concurrency: positiveInt.optional(),
|
|
28172
|
-
|
|
28100
|
+
supportsJsonSchema: exports_external.boolean().optional(),
|
|
28173
28101
|
extraParams: ExtraParamsSchema.optional(),
|
|
28174
28102
|
contextLength: positiveInt.optional(),
|
|
28175
28103
|
enableThinking: exports_external.boolean().optional(),
|
|
28176
28104
|
reasoningEffort: nonEmptyString3.optional()
|
|
28177
28105
|
}).passthrough();
|
|
28178
|
-
var LlmProfileConfigSchema = LlmConnectionConfigSchema.
|
|
28179
|
-
supportsJsonSchema: exports_external.boolean().optional()
|
|
28180
|
-
}).passthrough();
|
|
28106
|
+
var LlmProfileConfigSchema = LlmConnectionConfigSchema.passthrough();
|
|
28181
28107
|
var AgentPlatformSchema = exports_external.enum(VALID_HARNESS_IDS);
|
|
28182
28108
|
var LlmEngineSchema = exports_external.object({
|
|
28183
28109
|
kind: exports_external.literal("llm"),
|
|
@@ -28189,7 +28115,6 @@ var LlmEngineSchema = exports_external.object({
|
|
|
28189
28115
|
maxTokens: positiveInt.optional(),
|
|
28190
28116
|
timeoutMs: timeoutMsField,
|
|
28191
28117
|
concurrency: positiveInt.optional(),
|
|
28192
|
-
supportsJsonSchema: exports_external.boolean().optional(),
|
|
28193
28118
|
extraParams: ExtraParamsSchema.optional(),
|
|
28194
28119
|
contextLength: positiveInt.optional(),
|
|
28195
28120
|
enableThinking: exports_external.boolean().optional(),
|
|
@@ -28219,7 +28144,6 @@ var AgentEngineSchema = exports_external.object({
|
|
|
28219
28144
|
"temperature",
|
|
28220
28145
|
"maxTokens",
|
|
28221
28146
|
"concurrency",
|
|
28222
|
-
"supportsJsonSchema",
|
|
28223
28147
|
"extraParams",
|
|
28224
28148
|
"contextLength",
|
|
28225
28149
|
"enableThinking",
|
|
@@ -28585,7 +28509,7 @@ var SearchGraphBoostSchema = exports_external.object({
|
|
|
28585
28509
|
hopBoostPerEntity: nonNegativeNumber.optional(),
|
|
28586
28510
|
hopBoostCap: nonNegativeNumber.optional(),
|
|
28587
28511
|
maxHops: positiveInt.max(3).optional(),
|
|
28588
|
-
confidenceMode: exports_external.enum(["
|
|
28512
|
+
confidenceMode: exports_external.enum(["blend"]).default("blend").optional(),
|
|
28589
28513
|
confidenceWeight: exports_external.number().finite().min(0).max(1).default(0.2).optional()
|
|
28590
28514
|
}).passthrough();
|
|
28591
28515
|
var SearchConfigSchema = exports_external.object({
|
|
@@ -29127,8 +29051,7 @@ function withMaintenanceStartBarrier(run) {
|
|
|
29127
29051
|
|
|
29128
29052
|
// src/indexer/index-writer-lock.ts
|
|
29129
29053
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
29130
|
-
var
|
|
29131
|
-
var DEFAULT_INDEX_WRITER_MAX_WAIT_MS = 10 * 60 * 1000;
|
|
29054
|
+
var DEFAULT_ASSET_MUTATION_MAX_WAIT_MS = 10 * 60 * 1000;
|
|
29132
29055
|
var leaseContext = new AsyncLocalStorage2;
|
|
29133
29056
|
|
|
29134
29057
|
// src/integrations/lockfile.ts
|
|
@@ -29926,9 +29849,14 @@ function existingDirectory(target) {
|
|
|
29926
29849
|
throw cause;
|
|
29927
29850
|
}
|
|
29928
29851
|
}
|
|
29852
|
+
function reconcileDuplicateRoot(existing, candidate, sharedPath) {
|
|
29853
|
+
if (existing.writable === candidate.writable && existing.layout === candidate.layout)
|
|
29854
|
+
return;
|
|
29855
|
+
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 — run `akm bundle list` to see both.", "INVALID_CONFIG_FILE");
|
|
29856
|
+
}
|
|
29929
29857
|
function taskRoots(config, resolutionBase = process.cwd()) {
|
|
29930
29858
|
const sources = new Map((bundlesToSourceEntries(config) ?? []).map((source) => [source.name, source]));
|
|
29931
|
-
const
|
|
29859
|
+
const rootsByPath = new Map;
|
|
29932
29860
|
for (const [bundleId, bundle] of Object.entries(config.bundles ?? {})) {
|
|
29933
29861
|
if (bundle.enabled === false)
|
|
29934
29862
|
continue;
|
|
@@ -29956,15 +29884,21 @@ function taskRoots(config, resolutionBase = process.cwd()) {
|
|
|
29956
29884
|
}
|
|
29957
29885
|
if (adapter !== "akm" && adapter !== "akm-task")
|
|
29958
29886
|
continue;
|
|
29959
|
-
|
|
29887
|
+
const candidate = {
|
|
29960
29888
|
bundleId,
|
|
29961
29889
|
root: componentRoot,
|
|
29962
29890
|
bundleRoot,
|
|
29963
29891
|
writable: component?.writable ?? resolveWritable(source),
|
|
29964
29892
|
layout: adapter === "akm-task" ? "akm-task" : "akm-stash"
|
|
29965
|
-
}
|
|
29893
|
+
};
|
|
29894
|
+
const existing = rootsByPath.get(componentRoot);
|
|
29895
|
+
if (existing) {
|
|
29896
|
+
reconcileDuplicateRoot(existing, candidate, componentRoot);
|
|
29897
|
+
continue;
|
|
29898
|
+
}
|
|
29899
|
+
rootsByPath.set(componentRoot, candidate);
|
|
29966
29900
|
}
|
|
29967
|
-
return
|
|
29901
|
+
return [...rootsByPath.values()];
|
|
29968
29902
|
}
|
|
29969
29903
|
function summarize(plan) {
|
|
29970
29904
|
const files = plan.files.map((file) => ({
|