akm-cli 0.9.25-alpha.1 → 0.9.25-alpha.3
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 +243 -280
- package/dist/assets/prompts/reflect-feedback-framing.md +1 -1
- package/dist/assets/prompts/reflect-llm-framed-contract.md +2 -9
- package/dist/assets/prompts/reflect-llm-schema-contract.md +1 -3
- package/dist/assets/prompts/reflect-output-repair.md +1 -1
- package/dist/cli.js +1 -1
- package/dist/commands/improve/consolidate/pair-pass.js +1 -0
- package/dist/commands/improve/consolidate.js +7 -2
- package/dist/commands/improve/execution.js +2 -3
- package/dist/commands/improve/extract-cli.js +3 -2
- package/dist/commands/improve/extract.js +2 -1
- package/dist/commands/improve/improve-cli.js +33 -1
- package/dist/commands/improve/loop-stages.js +3 -0
- package/dist/commands/improve/reflect-noise.js +125 -0
- package/dist/commands/improve/reflect.js +150 -333
- package/dist/commands/improve/retrieval-gate.js +7 -2
- package/dist/commands/improve/session-asset.js +6 -0
- package/dist/commands/improve/stage.js +31 -39
- package/dist/commands/proposal/drain.js +4 -7
- package/dist/commands/proposal/propose.js +2 -11
- package/dist/commands/proposal/validators/proposal-quality-validators.js +11 -5
- package/dist/commands/proposal/validators/proposal-validators.js +4 -5
- package/dist/commands/read/search-cli.js +0 -38
- package/dist/core/asset/asset-serialize.js +1 -1
- package/dist/core/config/schema/engines.js +15 -33
- package/dist/core/config/schema/improve-processes.js +16 -0
- package/dist/core/content-safety.js +0 -24
- package/dist/core/redaction.js +4 -0
- package/dist/core/spawn-env.js +25 -0
- package/dist/core/structured.js +1 -1
- package/dist/execution/source.js +8 -12
- package/dist/integrations/agent/config.js +1 -3
- package/dist/integrations/agent/engine-resolution.js +0 -3
- package/dist/integrations/agent/execution.js +14 -13
- package/dist/integrations/agent/index.js +1 -1
- package/dist/integrations/agent/model-map.js +15 -16
- package/dist/integrations/agent/profiles.js +2 -2
- package/dist/integrations/agent/prompts.js +51 -127
- package/dist/integrations/agent/request-lowering.js +9 -7
- package/dist/integrations/agent/runner-dispatch.js +25 -31
- package/dist/integrations/harnesses/aider/agent-builder.js +1 -2
- package/dist/integrations/harnesses/amazonq/agent-builder.js +1 -2
- package/dist/integrations/harnesses/claude/agent-builder.js +4 -16
- package/dist/integrations/harnesses/codex/agent-builder.js +1 -2
- package/dist/integrations/harnesses/codex/index.js +6 -11
- package/dist/integrations/harnesses/codex/session-log.js +211 -0
- package/dist/integrations/harnesses/ids.js +10 -16
- package/dist/integrations/harnesses/opencode/agent-builder.js +14 -24
- package/dist/integrations/harnesses/opencode/model-config.js +15 -62
- package/dist/integrations/harnesses/opencode/model-work-agent.js +71 -36
- package/dist/integrations/harnesses/opencode-sdk/harness.js +2 -6
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +32 -90
- package/dist/integrations/harnesses/openhands/agent-builder.js +1 -2
- package/dist/integrations/harnesses/pi/agent-builder.js +1 -2
- package/dist/integrations/harnesses/types.js +3 -3
- package/dist/llm/feature-gate.js +2 -5
- package/dist/llm/index-passes.js +2 -2
- package/dist/llm/structured-call.js +5 -5
- package/dist/output/shapes/passthrough.js +1 -0
- package/dist/scripts/akm-migrate-node.js +381 -239
- package/dist/scripts/akm-migrate.js +381 -239
- package/dist/workflows/exec/unit-dispatch.js +4 -13
- package/docs/reference/cli.md +29 -16
- package/docs/reference/configuration.md +79 -85
- package/docs/reference/data-and-telemetry.md +2 -3
- package/docs/reference/workflow-schema.md +6 -9
- package/package.json +1 -1
- package/schemas/akm-config.json +108 -36
|
@@ -29036,6 +29036,7 @@ var PASSTHROUGH_COMMANDS = [
|
|
|
29036
29036
|
"extract",
|
|
29037
29037
|
"health",
|
|
29038
29038
|
"improve",
|
|
29039
|
+
"improve-judge",
|
|
29039
29040
|
"improve-report",
|
|
29040
29041
|
"import",
|
|
29041
29042
|
"index",
|
|
@@ -35454,25 +35455,21 @@ var coerce = {
|
|
|
35454
35455
|
};
|
|
35455
35456
|
var NEVER = INVALID;
|
|
35456
35457
|
// src/integrations/harnesses/ids.ts
|
|
35457
|
-
var OPENCODE_INFERENCE = ["temperature", "maxTokens", "contextLength", "enableThinking", "reasoningEffort"];
|
|
35458
35458
|
var HARNESS_ID_TABLE = [
|
|
35459
|
-
{ id: "opencode", agentDispatch: true, enforcesModelWorkTools: true
|
|
35460
|
-
{ id: "claude", agentDispatch: true, enforcesModelWorkTools: true
|
|
35461
|
-
{ id: "opencode-sdk", agentDispatch: true, enforcesModelWorkTools: true
|
|
35462
|
-
{ id: "codex", agentDispatch: true, enforcesModelWorkTools: false
|
|
35463
|
-
{ id: "copilot", agentDispatch: true, enforcesModelWorkTools: false
|
|
35464
|
-
{ id: "pi", agentDispatch: true, enforcesModelWorkTools: false
|
|
35465
|
-
{ id: "gemini", agentDispatch: true, enforcesModelWorkTools: false
|
|
35466
|
-
{ id: "aider", agentDispatch: true, enforcesModelWorkTools: false
|
|
35467
|
-
{ id: "amazonq", agentDispatch: true, enforcesModelWorkTools: false
|
|
35468
|
-
{ id: "openhands", agentDispatch: true, enforcesModelWorkTools: false
|
|
35459
|
+
{ id: "opencode", agentDispatch: true, enforcesModelWorkTools: true },
|
|
35460
|
+
{ id: "claude", agentDispatch: true, enforcesModelWorkTools: true },
|
|
35461
|
+
{ id: "opencode-sdk", agentDispatch: true, enforcesModelWorkTools: true },
|
|
35462
|
+
{ id: "codex", agentDispatch: true, enforcesModelWorkTools: false },
|
|
35463
|
+
{ id: "copilot", agentDispatch: true, enforcesModelWorkTools: false },
|
|
35464
|
+
{ id: "pi", agentDispatch: true, enforcesModelWorkTools: false },
|
|
35465
|
+
{ id: "gemini", agentDispatch: true, enforcesModelWorkTools: false },
|
|
35466
|
+
{ id: "aider", agentDispatch: true, enforcesModelWorkTools: false },
|
|
35467
|
+
{ id: "amazonq", agentDispatch: true, enforcesModelWorkTools: false },
|
|
35468
|
+
{ id: "openhands", agentDispatch: true, enforcesModelWorkTools: false }
|
|
35469
35469
|
];
|
|
35470
35470
|
var VALID_HARNESS_IDS = Object.freeze(HARNESS_ID_TABLE.map((h) => h.id));
|
|
35471
35471
|
var HARNESS_AGENT_DISPATCH_IDS = new Set(HARNESS_ID_TABLE.filter((h) => h.agentDispatch).map((h) => h.id));
|
|
35472
35472
|
var HARNESS_MODEL_WORK_IDS = new Set(HARNESS_ID_TABLE.filter((h) => h.enforcesModelWorkTools).map((h) => h.id));
|
|
35473
|
-
function harnessInferenceKeys(platform) {
|
|
35474
|
-
return HARNESS_ID_TABLE.find((h) => h.id === platform)?.inference ?? [];
|
|
35475
|
-
}
|
|
35476
35473
|
|
|
35477
35474
|
// src/core/extra-params.ts
|
|
35478
35475
|
var EXTRA_PARAMS_PROTECTED_TOP_LEVEL_KEYS = [
|
|
@@ -35777,13 +35774,6 @@ var LlmEngineSchema = exports_external.object({
|
|
|
35777
35774
|
});
|
|
35778
35775
|
}
|
|
35779
35776
|
});
|
|
35780
|
-
var AGENT_INFERENCE_KEYS = [
|
|
35781
|
-
"temperature",
|
|
35782
|
-
"maxTokens",
|
|
35783
|
-
"contextLength",
|
|
35784
|
-
"enableThinking",
|
|
35785
|
-
"reasoningEffort"
|
|
35786
|
-
];
|
|
35787
35777
|
var AgentEngineSchema = exports_external.object({
|
|
35788
35778
|
kind: exports_external.literal("agent"),
|
|
35789
35779
|
platform: AgentPlatformSchema.refine((platform) => HARNESS_AGENT_DISPATCH_IDS.has(platform), {
|
|
@@ -35794,27 +35784,25 @@ var AgentEngineSchema = exports_external.object({
|
|
|
35794
35784
|
workspace: nonEmptyString.optional(),
|
|
35795
35785
|
model: nonEmptyString.optional(),
|
|
35796
35786
|
timeoutMs: timeoutMsField,
|
|
35797
|
-
llmEngine: engineName.optional()
|
|
35798
|
-
temperature: exports_external.number().finite().optional(),
|
|
35799
|
-
maxTokens: positiveInt.optional(),
|
|
35800
|
-
contextLength: positiveInt.optional(),
|
|
35801
|
-
enableThinking: exports_external.boolean().optional(),
|
|
35802
|
-
reasoningEffort: nonEmptyString.optional()
|
|
35787
|
+
llmEngine: engineName.optional()
|
|
35803
35788
|
}).passthrough().superRefine((value, ctx) => {
|
|
35804
|
-
for (const key of [
|
|
35789
|
+
for (const key of [
|
|
35790
|
+
"provider",
|
|
35791
|
+
"endpoint",
|
|
35792
|
+
"apiKey",
|
|
35793
|
+
"apiKeyFile",
|
|
35794
|
+
"temperature",
|
|
35795
|
+
"maxTokens",
|
|
35796
|
+
"concurrency",
|
|
35797
|
+
"extraParams",
|
|
35798
|
+
"contextLength",
|
|
35799
|
+
"enableThinking",
|
|
35800
|
+
"reasoningEffort",
|
|
35801
|
+
"modelAliases"
|
|
35802
|
+
]) {
|
|
35805
35803
|
if (key in value)
|
|
35806
35804
|
ctx.addIssue({ code: exports_external.ZodIssueCode.custom, path: [key], message: `${key} is not valid on an agent engine` });
|
|
35807
35805
|
}
|
|
35808
|
-
const translated = harnessInferenceKeys(value.platform);
|
|
35809
|
-
for (const key of AGENT_INFERENCE_KEYS) {
|
|
35810
|
-
if (key in value && !translated.includes(key)) {
|
|
35811
|
-
ctx.addIssue({
|
|
35812
|
-
code: exports_external.ZodIssueCode.custom,
|
|
35813
|
-
path: [key],
|
|
35814
|
-
message: `${key} is not valid on a ${value.platform} engine: ${translated.length > 0 ? `the platform translates only ${translated.join(", ")}` : "the platform translates no inference fields"}`
|
|
35815
|
-
});
|
|
35816
|
-
}
|
|
35817
|
-
}
|
|
35818
35806
|
if (value.platform !== "opencode-sdk" && value.llmEngine !== undefined) {
|
|
35819
35807
|
ctx.addIssue({
|
|
35820
35808
|
code: exports_external.ZodIssueCode.custom,
|
|
@@ -35878,6 +35866,11 @@ var clsField = exports_external.object({
|
|
|
35878
35866
|
}).passthrough().optional();
|
|
35879
35867
|
var fidelityCheckField = exports_external.object({ enabled: exports_external.boolean().optional() }).passthrough().optional();
|
|
35880
35868
|
var lowValueFilterField = exports_external.object({ enabled: exports_external.boolean().optional() }).passthrough().optional();
|
|
35869
|
+
var defectFilterField = exports_external.object({
|
|
35870
|
+
placeholders: exports_external.array(nonEmptyString).optional(),
|
|
35871
|
+
metaCommentary: exports_external.array(nonEmptyString).optional(),
|
|
35872
|
+
frontmatterKeys: exports_external.array(nonEmptyString).optional()
|
|
35873
|
+
}).passthrough().optional();
|
|
35881
35874
|
var extractTriageGateField = exports_external.object({
|
|
35882
35875
|
enabled: exports_external.boolean().optional(),
|
|
35883
35876
|
minScore: exports_external.number().min(0).optional()
|
|
@@ -35900,7 +35893,8 @@ var REFLECT_PROCESS_FIELDS = {
|
|
|
35900
35893
|
excludeRefPrefixes: excludeRefPrefixesField,
|
|
35901
35894
|
limit: processLimitField,
|
|
35902
35895
|
qualityGate: qualityGateField,
|
|
35903
|
-
lowValueFilter: lowValueFilterField
|
|
35896
|
+
lowValueFilter: lowValueFilterField,
|
|
35897
|
+
defectFilter: defectFilterField
|
|
35904
35898
|
};
|
|
35905
35899
|
var DISTILL_PROCESS_FIELDS = {
|
|
35906
35900
|
allowedTypes: allowedTypesField,
|
|
@@ -37622,6 +37616,10 @@ var ENV_PASSTHROUGH_REDACTION_POLICY = {
|
|
|
37622
37616
|
OPENCODE_CONFIG: "path",
|
|
37623
37617
|
CLAUDE_CONFIG: "path",
|
|
37624
37618
|
CODEX_CONFIG: "path",
|
|
37619
|
+
XDG_CONFIG_HOME: "path",
|
|
37620
|
+
XDG_DATA_HOME: "path",
|
|
37621
|
+
XDG_CACHE_HOME: "path",
|
|
37622
|
+
XDG_STATE_HOME: "path",
|
|
37625
37623
|
AWS_PROFILE: "identifier",
|
|
37626
37624
|
AWS_REGION: "identifier",
|
|
37627
37625
|
LLM_MODEL: "identifier",
|
|
@@ -39674,10 +39672,7 @@ import { createHash as createHash3 } from "node:crypto";
|
|
|
39674
39672
|
|
|
39675
39673
|
// src/execution/source.ts
|
|
39676
39674
|
var EXECUTION_SOURCE_SCHEMA_VERSION = 1;
|
|
39677
|
-
var
|
|
39678
|
-
function isModelWorkTools(tools) {
|
|
39679
|
-
return Array.isArray(tools) && tools.length === MODEL_WORK_TOOLS.length && tools.every((tool, index) => tool === MODEL_WORK_TOOLS[index]);
|
|
39680
|
-
}
|
|
39675
|
+
var MODEL_WORK_POLICY_ID = "model-work";
|
|
39681
39676
|
function requireRecord(value, path18) {
|
|
39682
39677
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
39683
39678
|
throw new TypeError(`${path18} must be an object`);
|
|
@@ -51045,8 +51040,9 @@ function extensionFields(request) {
|
|
|
51045
51040
|
];
|
|
51046
51041
|
}
|
|
51047
51042
|
function createAgentRequestLowerer(options) {
|
|
51048
|
-
|
|
51049
|
-
|
|
51043
|
+
const supportedInference = new Set(options.inference ?? []);
|
|
51044
|
+
return (_profile, request) => {
|
|
51045
|
+
const modelWork = request.authorization.policy?.id === MODEL_WORK_POLICY_ID;
|
|
51050
51046
|
const notices = [];
|
|
51051
51047
|
const skip = (field) => {
|
|
51052
51048
|
notices.push(untranslated(options.adapter, field));
|
|
@@ -51087,18 +51083,18 @@ function createAgentRequestLowerer(options) {
|
|
|
51087
51083
|
if (Object.hasOwn(request, "inference")) {
|
|
51088
51084
|
dispatch.inference = request.inference ?? null;
|
|
51089
51085
|
for (const key of Object.keys(request.inference ?? {}).sort()) {
|
|
51090
|
-
if (!supportedInference.has(key))
|
|
51086
|
+
if (!(modelWork && supportedInference.has(key)))
|
|
51091
51087
|
skip(`inference.${key}`);
|
|
51092
51088
|
}
|
|
51093
51089
|
}
|
|
51094
|
-
if (
|
|
51095
|
-
if (!options.
|
|
51090
|
+
if (modelWork) {
|
|
51091
|
+
if (!HARNESS_MODEL_WORK_IDS.has(options.adapter)) {
|
|
51096
51092
|
throw new ConfigError(`The ${options.adapter} transport cannot enforce the model-work tool policy.`, "INVALID_CONFIG_FILE");
|
|
51097
51093
|
}
|
|
51098
51094
|
if (dispatch.agent) {
|
|
51099
51095
|
throw new ConfigError(`The ${options.adapter} transport cannot run native agent ${JSON.stringify(dispatch.agent)} under the model-work tool policy.`, "INVALID_CONFIG_FILE");
|
|
51100
51096
|
}
|
|
51101
|
-
dispatch.
|
|
51097
|
+
dispatch.modelWork = true;
|
|
51102
51098
|
} else if (request.tools !== undefined) {
|
|
51103
51099
|
if (hasToolSelection(request.tools) && !translatesTools(options.tools, request.tools)) {
|
|
51104
51100
|
throw new ConfigError(`The ${options.adapter} transport cannot enforce the resolved tool policy.`, "INVALID_CONFIG_FILE");
|
|
@@ -51294,12 +51290,10 @@ var claudeBuilder = {
|
|
|
51294
51290
|
adapter: "claude",
|
|
51295
51291
|
personaChannel: "native",
|
|
51296
51292
|
nativeAgentSelector: true,
|
|
51297
|
-
tools: "all"
|
|
51298
|
-
modelWorkTools: true,
|
|
51299
|
-
inference: ["reasoningEffort"]
|
|
51293
|
+
tools: "all"
|
|
51300
51294
|
}),
|
|
51301
51295
|
build(profile, req) {
|
|
51302
|
-
const modelWork =
|
|
51296
|
+
const modelWork = req.modelWork === true;
|
|
51303
51297
|
const args = modelWork ? [...MODEL_WORK_CLAUDE_FLAGS] : [...profile.args];
|
|
51304
51298
|
if (req.agent) {
|
|
51305
51299
|
args.push("--agent", req.agent);
|
|
@@ -51315,10 +51309,7 @@ var claudeBuilder = {
|
|
|
51315
51309
|
if (model)
|
|
51316
51310
|
args.push("--model", model);
|
|
51317
51311
|
}
|
|
51318
|
-
|
|
51319
|
-
if (typeof effort === "string" && effort.length > 0)
|
|
51320
|
-
args.push("--effort", effort);
|
|
51321
|
-
if (req.tools && !modelWork) {
|
|
51312
|
+
if (req.tools) {
|
|
51322
51313
|
args.push("--allowedTools", normalizeTools(req.tools));
|
|
51323
51314
|
}
|
|
51324
51315
|
if (req.schema) {
|
|
@@ -51776,6 +51767,170 @@ var codexResultExtractor = (result) => {
|
|
|
51776
51767
|
return sessionId === undefined ? { text } : { text, sessionId };
|
|
51777
51768
|
};
|
|
51778
51769
|
|
|
51770
|
+
// src/integrations/harnesses/codex/session-log.ts
|
|
51771
|
+
import fs36 from "node:fs";
|
|
51772
|
+
import os5 from "node:os";
|
|
51773
|
+
import path43 from "node:path";
|
|
51774
|
+
function codexSessionsDir() {
|
|
51775
|
+
return path43.join(process.env.CODEX_HOME || path43.join(os5.homedir(), ".codex"), "sessions");
|
|
51776
|
+
}
|
|
51777
|
+
var META_PEEK_BYTES = 128 * 1024;
|
|
51778
|
+
var INJECTED_CONTEXT_RE = /^\s*(?:# AGENTS\.md instructions[\s\S]*<\/INSTRUCTIONS>|<(environment_context|user_instructions|recommended_plugins|skill|turn_aborted)>[\s\S]*<\/\1>)\s*$/i;
|
|
51779
|
+
function parseSessionMeta(entry) {
|
|
51780
|
+
const e = entry;
|
|
51781
|
+
if (e?.type !== "session_meta" || !e.payload)
|
|
51782
|
+
return;
|
|
51783
|
+
const { timestamp, cwd, source } = e.payload;
|
|
51784
|
+
const startedAt = typeof timestamp === "string" ? Date.parse(timestamp) : Number.NaN;
|
|
51785
|
+
return {
|
|
51786
|
+
...Number.isNaN(startedAt) ? {} : { startedAt },
|
|
51787
|
+
...typeof cwd === "string" ? { cwd } : {},
|
|
51788
|
+
isAgent: typeof source === "object" && source !== null && (("subagent" in source) || ("internal" in source))
|
|
51789
|
+
};
|
|
51790
|
+
}
|
|
51791
|
+
function blockText(blocks, keep = () => true) {
|
|
51792
|
+
if (typeof blocks === "string")
|
|
51793
|
+
return blocks;
|
|
51794
|
+
if (!Array.isArray(blocks))
|
|
51795
|
+
return "";
|
|
51796
|
+
const parts = [];
|
|
51797
|
+
for (const block of blocks) {
|
|
51798
|
+
const text = block?.text;
|
|
51799
|
+
if (typeof text === "string" && keep(text))
|
|
51800
|
+
parts.push(text);
|
|
51801
|
+
}
|
|
51802
|
+
return parts.join(`
|
|
51803
|
+
`);
|
|
51804
|
+
}
|
|
51805
|
+
function toolInputText(input) {
|
|
51806
|
+
let args = input;
|
|
51807
|
+
if (typeof input === "string") {
|
|
51808
|
+
try {
|
|
51809
|
+
args = JSON.parse(input);
|
|
51810
|
+
} catch {
|
|
51811
|
+
return input;
|
|
51812
|
+
}
|
|
51813
|
+
}
|
|
51814
|
+
const fields = args && typeof args === "object" ? args : {};
|
|
51815
|
+
const cmd = fields.cmd ?? fields.command;
|
|
51816
|
+
if (typeof cmd === "string")
|
|
51817
|
+
return cmd;
|
|
51818
|
+
if (Array.isArray(cmd))
|
|
51819
|
+
return cmd.join(" ");
|
|
51820
|
+
return typeof input === "string" ? input : JSON.stringify(input) ?? "";
|
|
51821
|
+
}
|
|
51822
|
+
function parseCodexRecord(entry, sessionId, filePath, fallbackTsMs) {
|
|
51823
|
+
const e = entry;
|
|
51824
|
+
const item = e?.type === "response_item" ? e.payload : undefined;
|
|
51825
|
+
if (!item)
|
|
51826
|
+
return;
|
|
51827
|
+
const toolName2 = typeof item.name === "string" ? item.name : "tool";
|
|
51828
|
+
let role = "assistant";
|
|
51829
|
+
let text;
|
|
51830
|
+
switch (item.type) {
|
|
51831
|
+
case "message":
|
|
51832
|
+
if (item.role !== "user" && item.role !== "assistant")
|
|
51833
|
+
return;
|
|
51834
|
+
role = item.role;
|
|
51835
|
+
text = blockText(item.content, item.role === "user" ? (t) => !INJECTED_CONTEXT_RE.test(t) : undefined);
|
|
51836
|
+
break;
|
|
51837
|
+
case "function_call":
|
|
51838
|
+
text = `[tool:${toolName2}] ${toolInputText(item.arguments)}`;
|
|
51839
|
+
break;
|
|
51840
|
+
case "custom_tool_call":
|
|
51841
|
+
text = `[tool:${toolName2}] ${typeof item.input === "string" ? item.input : ""}`;
|
|
51842
|
+
break;
|
|
51843
|
+
case "local_shell_call":
|
|
51844
|
+
text = `[tool:shell] ${toolInputText(item.action)}`;
|
|
51845
|
+
break;
|
|
51846
|
+
case "function_call_output":
|
|
51847
|
+
case "custom_tool_call_output": {
|
|
51848
|
+
role = "tool";
|
|
51849
|
+
const output = blockText(item.output);
|
|
51850
|
+
text = output ? `[tool_result] ${output}` : "";
|
|
51851
|
+
break;
|
|
51852
|
+
}
|
|
51853
|
+
default:
|
|
51854
|
+
return;
|
|
51855
|
+
}
|
|
51856
|
+
if (!text.trim())
|
|
51857
|
+
return;
|
|
51858
|
+
const ts = typeof e?.timestamp === "string" ? Date.parse(e.timestamp) || fallbackTsMs : fallbackTsMs;
|
|
51859
|
+
return { harness: "codex", text, ts, sessionId, role, filePath };
|
|
51860
|
+
}
|
|
51861
|
+
|
|
51862
|
+
class CodexProvider extends AbstractSessionLogProvider {
|
|
51863
|
+
name = "codex";
|
|
51864
|
+
availabilityRoot() {
|
|
51865
|
+
return codexSessionsDir();
|
|
51866
|
+
}
|
|
51867
|
+
listSessions(input = {}) {
|
|
51868
|
+
return this.listSessionsFromFiles({
|
|
51869
|
+
sinceMs: input.sinceMs ?? 0,
|
|
51870
|
+
enumerate: () => this.walkFiles(input.location ?? codexSessionsDir(), (name) => /^rollout-.+\.jsonl$/.test(name)),
|
|
51871
|
+
summarize: (rolloutPath, stat) => {
|
|
51872
|
+
const meta = this.#peekMeta(rolloutPath);
|
|
51873
|
+
if (meta?.isAgent)
|
|
51874
|
+
return;
|
|
51875
|
+
return this.sessionRef({
|
|
51876
|
+
sessionId: path43.basename(rolloutPath, ".jsonl").slice(-36),
|
|
51877
|
+
filePath: rolloutPath,
|
|
51878
|
+
startedAt: meta?.startedAt ?? stat.ctimeMs,
|
|
51879
|
+
endedAt: stat.mtimeMs,
|
|
51880
|
+
projectHint: meta?.cwd
|
|
51881
|
+
});
|
|
51882
|
+
}
|
|
51883
|
+
});
|
|
51884
|
+
}
|
|
51885
|
+
readSession(ref) {
|
|
51886
|
+
const stat = fs36.statSync(ref.filePath);
|
|
51887
|
+
const events = [];
|
|
51888
|
+
const inlineRefs = [];
|
|
51889
|
+
let meta;
|
|
51890
|
+
for (const line of fs36.readFileSync(ref.filePath, "utf8").split(`
|
|
51891
|
+
`).filter(Boolean)) {
|
|
51892
|
+
let entry;
|
|
51893
|
+
try {
|
|
51894
|
+
entry = JSON.parse(line);
|
|
51895
|
+
} catch {
|
|
51896
|
+
continue;
|
|
51897
|
+
}
|
|
51898
|
+
meta ??= parseSessionMeta(entry);
|
|
51899
|
+
const parsed = parseCodexRecord(entry, ref.sessionId, ref.filePath, stat.mtimeMs);
|
|
51900
|
+
if (!parsed)
|
|
51901
|
+
continue;
|
|
51902
|
+
events.push(parsed);
|
|
51903
|
+
inlineRefs.push(...extractInlineRefMentions(parsed.text, parsed.ts));
|
|
51904
|
+
}
|
|
51905
|
+
return {
|
|
51906
|
+
ref: this.sessionRef({
|
|
51907
|
+
sessionId: ref.sessionId,
|
|
51908
|
+
filePath: ref.filePath,
|
|
51909
|
+
startedAt: meta?.startedAt ?? events[0]?.ts ?? stat.ctimeMs,
|
|
51910
|
+
endedAt: events[events.length - 1]?.ts ?? stat.mtimeMs,
|
|
51911
|
+
projectHint: meta?.cwd
|
|
51912
|
+
}),
|
|
51913
|
+
events,
|
|
51914
|
+
inlineRefs
|
|
51915
|
+
};
|
|
51916
|
+
}
|
|
51917
|
+
#peekMeta(filePath) {
|
|
51918
|
+
try {
|
|
51919
|
+
const fd = fs36.openSync(filePath, "r");
|
|
51920
|
+
try {
|
|
51921
|
+
const head = Buffer.alloc(META_PEEK_BYTES);
|
|
51922
|
+
const firstLine = head.toString("utf8", 0, fs36.readSync(fd, head, 0, head.length, 0)).split(`
|
|
51923
|
+
`, 1)[0] ?? "";
|
|
51924
|
+
return parseSessionMeta(JSON.parse(firstLine));
|
|
51925
|
+
} finally {
|
|
51926
|
+
fs36.closeSync(fd);
|
|
51927
|
+
}
|
|
51928
|
+
} catch {
|
|
51929
|
+
return;
|
|
51930
|
+
}
|
|
51931
|
+
}
|
|
51932
|
+
}
|
|
51933
|
+
|
|
51779
51934
|
// src/integrations/harnesses/codex/index.ts
|
|
51780
51935
|
class CodexHarness extends BaseHarness {
|
|
51781
51936
|
id = "codex";
|
|
@@ -51783,7 +51938,9 @@ class CodexHarness extends BaseHarness {
|
|
|
51783
51938
|
agentBuilder = codexBuilder;
|
|
51784
51939
|
resultExtractor = codexResultExtractor;
|
|
51785
51940
|
presenceEnv = ["CODEX_SANDBOX"];
|
|
51941
|
+
sessionLogProvider = () => new CodexProvider;
|
|
51786
51942
|
capabilities = caps({
|
|
51943
|
+
sessionLogs: true,
|
|
51787
51944
|
agentDispatch: true,
|
|
51788
51945
|
detection: true
|
|
51789
51946
|
});
|
|
@@ -52080,101 +52237,87 @@ class GeminiHarness extends BaseHarness {
|
|
|
52080
52237
|
}
|
|
52081
52238
|
|
|
52082
52239
|
// src/integrations/harnesses/opencode/model-config.ts
|
|
52240
|
+
var MODEL_WORK_AGENT_INFERENCE = ["temperature", "reasoningEffort", "enableThinking"];
|
|
52083
52241
|
var isPositiveInteger = (value) => typeof value === "number" && Number.isInteger(value) && value > 0;
|
|
52084
|
-
function
|
|
52085
|
-
const carried = {};
|
|
52242
|
+
function opencodeInferenceConfig(inference, modelWork) {
|
|
52086
52243
|
const { temperature, reasoningEffort, enableThinking, maxTokens, contextLength } = inference ?? {};
|
|
52244
|
+
const options = {};
|
|
52087
52245
|
if (typeof temperature === "number" && Number.isFinite(temperature))
|
|
52088
|
-
|
|
52246
|
+
options.temperature = temperature;
|
|
52089
52247
|
if (typeof reasoningEffort === "string" && reasoningEffort.length > 0)
|
|
52090
|
-
|
|
52091
|
-
if (typeof enableThinking === "boolean")
|
|
52092
|
-
|
|
52093
|
-
|
|
52094
|
-
if (limit)
|
|
52095
|
-
carried.limit = { context: contextLength, output: maxTokens };
|
|
52096
|
-
const keys = [
|
|
52097
|
-
["temperature", carried.temperature !== undefined, temperature],
|
|
52098
|
-
["reasoningEffort", carried.reasoningEffort !== undefined, reasoningEffort],
|
|
52099
|
-
["enableThinking", carried.enableThinking !== undefined, enableThinking],
|
|
52100
|
-
["maxTokens", limit, maxTokens],
|
|
52101
|
-
["contextLength", limit, contextLength]
|
|
52102
|
-
].filter(([, isCarried, value]) => isCarried || value === null).map(([key]) => key);
|
|
52103
|
-
return { carried, keys };
|
|
52104
|
-
}
|
|
52105
|
-
function splitOpencodeModel(model) {
|
|
52106
|
-
const slash = model.indexOf("/");
|
|
52107
|
-
if (slash <= 0 || slash === model.length - 1)
|
|
52108
|
-
return;
|
|
52109
|
-
return { providerID: model.slice(0, slash), modelID: model.slice(slash + 1) };
|
|
52110
|
-
}
|
|
52111
|
-
function opencodeCarriedKeys(attachable, inference, modelWork) {
|
|
52112
|
-
const { keys } = carriedInference(inference);
|
|
52113
|
-
if (attachable)
|
|
52114
|
-
return keys;
|
|
52115
|
-
return modelWork ? keys.filter((key) => key !== "maxTokens" && key !== "contextLength") : [];
|
|
52116
|
-
}
|
|
52117
|
-
function opencodeInferenceConfig(inference, modelWork) {
|
|
52118
|
-
const { carried } = carriedInference(inference);
|
|
52119
|
-
const options = {};
|
|
52120
|
-
if (carried.temperature !== undefined)
|
|
52121
|
-
options.temperature = carried.temperature;
|
|
52122
|
-
if (carried.reasoningEffort !== undefined)
|
|
52123
|
-
options.reasoningEffort = carried.reasoningEffort;
|
|
52124
|
-
if (carried.enableThinking !== undefined) {
|
|
52125
|
-
options.chat_template_kwargs = { enable_thinking: carried.enableThinking };
|
|
52126
|
-
options.enable_thinking = carried.enableThinking;
|
|
52248
|
+
options.reasoningEffort = reasoningEffort;
|
|
52249
|
+
if (typeof enableThinking === "boolean") {
|
|
52250
|
+
options.chat_template_kwargs = { enable_thinking: enableThinking };
|
|
52251
|
+
options.enable_thinking = enableThinking;
|
|
52127
52252
|
}
|
|
52128
52253
|
const hasOptions = Object.keys(options).length > 0;
|
|
52129
52254
|
return {
|
|
52130
52255
|
entry: {
|
|
52131
52256
|
...hasOptions && !modelWork ? { options } : {},
|
|
52132
|
-
...
|
|
52257
|
+
...isPositiveInteger(maxTokens) && isPositiveInteger(contextLength) ? { limit: { context: contextLength, output: maxTokens } } : {}
|
|
52133
52258
|
},
|
|
52134
52259
|
...hasOptions && modelWork ? { agentOptions: options } : {}
|
|
52135
52260
|
};
|
|
52136
52261
|
}
|
|
52137
|
-
function opencodeModelConfig(model, entry) {
|
|
52138
|
-
const target = model === undefined ? undefined : splitOpencodeModel(model);
|
|
52139
|
-
if (!target || Object.keys(entry).length === 0)
|
|
52140
|
-
return;
|
|
52141
|
-
return { provider: { [target.providerID]: { models: { [target.modelID]: entry } } } };
|
|
52142
|
-
}
|
|
52143
52262
|
|
|
52144
52263
|
// src/integrations/harnesses/opencode/model-work-agent.ts
|
|
52264
|
+
import path44 from "node:path";
|
|
52145
52265
|
var MODEL_WORK_OPENCODE_AGENT = "akm-model-work";
|
|
52146
|
-
var MODEL_WORK_STEPS = 8;
|
|
52147
52266
|
var MODEL_WORK_PROMPT = "You do one bounded task for akm. Use tools only to check what the task needs, never repeat a tool call, and reply with exactly what the task asks for.";
|
|
52148
|
-
|
|
52149
|
-
|
|
52150
|
-
|
|
52151
|
-
|
|
52152
|
-
|
|
52153
|
-
|
|
52154
|
-
|
|
52155
|
-
|
|
52156
|
-
|
|
52157
|
-
|
|
52158
|
-
|
|
52159
|
-
|
|
52160
|
-
|
|
52161
|
-
|
|
52162
|
-
|
|
52163
|
-
|
|
52164
|
-
|
|
52165
|
-
|
|
52267
|
+
function modelWorkPermission(stash) {
|
|
52268
|
+
return {
|
|
52269
|
+
"*": "deny",
|
|
52270
|
+
read: "allow",
|
|
52271
|
+
grep: "allow",
|
|
52272
|
+
glob: "allow",
|
|
52273
|
+
edit: { "*": "allow", ...stash ? { [`${stash.slice(1)}/*`]: "deny" } : {} },
|
|
52274
|
+
external_directory: {
|
|
52275
|
+
...stash ? { [`${stash}/*`]: "allow" } : {},
|
|
52276
|
+
"~/.local/share/opencode/tool-output/*": "deny"
|
|
52277
|
+
},
|
|
52278
|
+
akm_search: "allow",
|
|
52279
|
+
akm_show: "allow",
|
|
52280
|
+
akm_feedback: "deny",
|
|
52281
|
+
akm_remember: "deny",
|
|
52282
|
+
akm_curate: "deny",
|
|
52283
|
+
bash: "deny",
|
|
52284
|
+
doom_loop: "deny",
|
|
52285
|
+
list: "deny",
|
|
52286
|
+
lsp: "deny",
|
|
52287
|
+
question: "deny",
|
|
52288
|
+
skill: "deny",
|
|
52289
|
+
task: "deny",
|
|
52290
|
+
todowrite: "deny",
|
|
52291
|
+
webfetch: "deny",
|
|
52292
|
+
websearch: "deny"
|
|
52293
|
+
};
|
|
52294
|
+
}
|
|
52295
|
+
function modelWorkPluginEnv() {
|
|
52296
|
+
return {
|
|
52297
|
+
AKM_AUTO_CURATE: "0",
|
|
52298
|
+
AKM_AUTO_LEARNING: "0",
|
|
52299
|
+
AKM_AUTO_SKILL_PROPOSALS: "0",
|
|
52300
|
+
AKM_WRITE_GATE: "off",
|
|
52301
|
+
XDG_STATE_HOME: path44.join(getStateDir(), "opencode-model-work"),
|
|
52302
|
+
...process.platform === "win32" ? {} : { AKM_OPENCODE_CLI: "/bin/true" }
|
|
52303
|
+
};
|
|
52304
|
+
}
|
|
52166
52305
|
function modelWorkOpencodeConfig(options) {
|
|
52306
|
+
let stash;
|
|
52307
|
+
try {
|
|
52308
|
+
stash = resolveStashDir();
|
|
52309
|
+
} catch {}
|
|
52310
|
+
const permission = modelWorkPermission(stash);
|
|
52167
52311
|
return {
|
|
52168
|
-
permission: { ...
|
|
52312
|
+
permission: { ...permission },
|
|
52169
52313
|
compaction: { auto: false },
|
|
52170
52314
|
agent: {
|
|
52171
52315
|
[MODEL_WORK_OPENCODE_AGENT]: {
|
|
52172
52316
|
mode: "primary",
|
|
52173
52317
|
description: "akm unattended model work: read and edit inside its working directory only.",
|
|
52174
52318
|
prompt: MODEL_WORK_PROMPT,
|
|
52175
|
-
steps: MODEL_WORK_STEPS,
|
|
52176
52319
|
...options ? { options } : {},
|
|
52177
|
-
permission: { ...
|
|
52320
|
+
permission: { ...permission }
|
|
52178
52321
|
}
|
|
52179
52322
|
}
|
|
52180
52323
|
};
|
|
@@ -52189,18 +52332,12 @@ var opencodeBuilder = {
|
|
|
52189
52332
|
personaChannel: "prompt",
|
|
52190
52333
|
nativeAgentSelector: true,
|
|
52191
52334
|
tools: "none",
|
|
52192
|
-
|
|
52193
|
-
inference: (profile, request) => {
|
|
52194
|
-
const model = request.model?.resolved ?? modelFromArgs(profile.args);
|
|
52195
|
-
return opencodeCarriedKeys(model !== undefined && splitOpencodeModel(model) !== undefined, request.inference, isModelWorkTools(request.tools));
|
|
52196
|
-
}
|
|
52335
|
+
inference: MODEL_WORK_AGENT_INFERENCE
|
|
52197
52336
|
}),
|
|
52198
52337
|
build(profile, req) {
|
|
52199
|
-
|
|
52200
|
-
|
|
52201
|
-
|
|
52202
|
-
const modelConfig = opencodeModelConfig(model, entry);
|
|
52203
|
-
if (modelWork) {
|
|
52338
|
+
if (req.modelWork) {
|
|
52339
|
+
const model = req.model ?? modelFromArgs(profile.args);
|
|
52340
|
+
const { agentOptions } = opencodeInferenceConfig(req.inference, true);
|
|
52204
52341
|
return {
|
|
52205
52342
|
argv: [
|
|
52206
52343
|
profile.bin,
|
|
@@ -52211,7 +52348,10 @@ var opencodeBuilder = {
|
|
|
52211
52348
|
"--",
|
|
52212
52349
|
req.prompt
|
|
52213
52350
|
],
|
|
52214
|
-
env: {
|
|
52351
|
+
env: {
|
|
52352
|
+
...modelWorkPluginEnv(),
|
|
52353
|
+
OPENCODE_CONFIG_CONTENT: JSON.stringify(modelWorkOpencodeConfig(agentOptions))
|
|
52354
|
+
}
|
|
52215
52355
|
};
|
|
52216
52356
|
}
|
|
52217
52357
|
const args = req.model ? [] : [...profile.args];
|
|
@@ -52236,23 +52376,20 @@ var opencodeBuilder = {
|
|
|
52236
52376
|
}
|
|
52237
52377
|
args.push("--");
|
|
52238
52378
|
args.push(req.prompt);
|
|
52239
|
-
return {
|
|
52240
|
-
argv: [profile.bin, ...args],
|
|
52241
|
-
...modelConfig ? { env: { OPENCODE_CONFIG_CONTENT: JSON.stringify(modelConfig) } } : {}
|
|
52242
|
-
};
|
|
52379
|
+
return { argv: [profile.bin, ...args] };
|
|
52243
52380
|
}
|
|
52244
52381
|
};
|
|
52245
52382
|
|
|
52246
52383
|
// src/integrations/harnesses/opencode/session-log.ts
|
|
52247
|
-
import
|
|
52248
|
-
import
|
|
52249
|
-
import
|
|
52384
|
+
import fs38 from "node:fs";
|
|
52385
|
+
import os7 from "node:os";
|
|
52386
|
+
import path46 from "node:path";
|
|
52250
52387
|
|
|
52251
52388
|
// src/storage/sqlite-read-snapshot.ts
|
|
52252
52389
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
52253
|
-
import
|
|
52254
|
-
import
|
|
52255
|
-
import
|
|
52390
|
+
import fs37 from "node:fs";
|
|
52391
|
+
import os6 from "node:os";
|
|
52392
|
+
import path45 from "node:path";
|
|
52256
52393
|
var SNAPSHOT_MAX_ATTEMPTS = 8;
|
|
52257
52394
|
var SNAPSHOT_BACKOFF_MS = 25;
|
|
52258
52395
|
|
|
@@ -52264,7 +52401,7 @@ class SqliteReadSnapshotUnavailableError extends Error {
|
|
|
52264
52401
|
}
|
|
52265
52402
|
function pathExists(filePath) {
|
|
52266
52403
|
try {
|
|
52267
|
-
|
|
52404
|
+
fs37.lstatSync(filePath);
|
|
52268
52405
|
return true;
|
|
52269
52406
|
} catch (error2) {
|
|
52270
52407
|
if (error2.code === "ENOENT")
|
|
@@ -52274,7 +52411,7 @@ function pathExists(filePath) {
|
|
|
52274
52411
|
}
|
|
52275
52412
|
function fileFingerprint(filePath) {
|
|
52276
52413
|
try {
|
|
52277
|
-
const stat =
|
|
52414
|
+
const stat = fs37.statSync(filePath, { bigint: true });
|
|
52278
52415
|
return { size: stat.size, mtimeNs: stat.mtimeNs, ctimeNs: stat.ctimeNs };
|
|
52279
52416
|
} catch (error2) {
|
|
52280
52417
|
if (error2.code === "ENOENT")
|
|
@@ -52296,7 +52433,7 @@ function fingerprintsEqual(left, right) {
|
|
|
52296
52433
|
}
|
|
52297
52434
|
function copyFileOutsideThisProcess(source, destination) {
|
|
52298
52435
|
if (process.platform === "win32") {
|
|
52299
|
-
|
|
52436
|
+
fs37.copyFileSync(source, destination);
|
|
52300
52437
|
return;
|
|
52301
52438
|
}
|
|
52302
52439
|
const result = spawnSync5("cp", ["--", source, destination], {
|
|
@@ -52317,8 +52454,8 @@ function copyFileOutsideThisProcess(source, destination) {
|
|
|
52317
52454
|
function openSqliteReadSnapshot(dbPath) {
|
|
52318
52455
|
if (!pathExists(dbPath))
|
|
52319
52456
|
return;
|
|
52320
|
-
const snapshotDir =
|
|
52321
|
-
const snapshotPath =
|
|
52457
|
+
const snapshotDir = fs37.mkdtempSync(path45.join(os6.tmpdir(), "akm-sqlite-read-"));
|
|
52458
|
+
const snapshotPath = path45.join(snapshotDir, "snapshot.db");
|
|
52322
52459
|
let db;
|
|
52323
52460
|
try {
|
|
52324
52461
|
let copied = false;
|
|
@@ -52333,7 +52470,7 @@ function openSqliteReadSnapshot(dbPath) {
|
|
|
52333
52470
|
if (before.wal)
|
|
52334
52471
|
copyFileOutsideThisProcess(`${dbPath}-wal`, `${snapshotPath}-wal`);
|
|
52335
52472
|
else
|
|
52336
|
-
|
|
52473
|
+
fs37.rmSync(`${snapshotPath}-wal`, { force: true });
|
|
52337
52474
|
const after = databaseFingerprint(dbPath);
|
|
52338
52475
|
if (fingerprintsEqual(before, after) && !pathExists(`${dbPath}-journal`)) {
|
|
52339
52476
|
copied = true;
|
|
@@ -52361,14 +52498,14 @@ function openSqliteReadSnapshot(dbPath) {
|
|
|
52361
52498
|
closeSnapshot();
|
|
52362
52499
|
} catch {}
|
|
52363
52500
|
try {
|
|
52364
|
-
|
|
52501
|
+
fs37.rmSync(snapshotDir, { recursive: true, force: true });
|
|
52365
52502
|
} catch {}
|
|
52366
52503
|
return;
|
|
52367
52504
|
}
|
|
52368
52505
|
try {
|
|
52369
52506
|
closeSnapshot();
|
|
52370
52507
|
} finally {
|
|
52371
|
-
|
|
52508
|
+
fs37.rmSync(snapshotDir, { recursive: true, force: true });
|
|
52372
52509
|
}
|
|
52373
52510
|
};
|
|
52374
52511
|
const cleanupOnExit = () => cleanup(true);
|
|
@@ -52379,7 +52516,7 @@ function openSqliteReadSnapshot(dbPath) {
|
|
|
52379
52516
|
try {
|
|
52380
52517
|
db?.close();
|
|
52381
52518
|
} finally {
|
|
52382
|
-
|
|
52519
|
+
fs37.rmSync(snapshotDir, { recursive: true, force: true });
|
|
52383
52520
|
}
|
|
52384
52521
|
throw error2;
|
|
52385
52522
|
}
|
|
@@ -52388,9 +52525,9 @@ function openSqliteReadSnapshot(dbPath) {
|
|
|
52388
52525
|
// src/integrations/harnesses/opencode/session-log.ts
|
|
52389
52526
|
function getOpenCodeBaseDir() {
|
|
52390
52527
|
if (process.platform === "darwin") {
|
|
52391
|
-
return
|
|
52528
|
+
return path46.join(os7.homedir(), "Library", "Application Support", "opencode");
|
|
52392
52529
|
}
|
|
52393
|
-
return
|
|
52530
|
+
return path46.join(os7.homedir(), ".local", "share", "opencode");
|
|
52394
52531
|
}
|
|
52395
52532
|
var OPENCODE_DB_FILENAME = "opencode.db";
|
|
52396
52533
|
|
|
@@ -52401,13 +52538,13 @@ class OpenCodeProvider extends AbstractSessionLogProvider {
|
|
|
52401
52538
|
return this.#dbPath(this.#baseDir);
|
|
52402
52539
|
}
|
|
52403
52540
|
#dbPath(base) {
|
|
52404
|
-
return
|
|
52541
|
+
return path46.join(base, OPENCODE_DB_FILENAME);
|
|
52405
52542
|
}
|
|
52406
52543
|
listSessions(input = {}) {
|
|
52407
52544
|
const base = input.location ?? this.#baseDir;
|
|
52408
52545
|
const sinceMs = input.sinceMs ?? 0;
|
|
52409
52546
|
const dbPath = this.#dbPath(base);
|
|
52410
|
-
if (!
|
|
52547
|
+
if (!fs38.existsSync(dbPath))
|
|
52411
52548
|
return [];
|
|
52412
52549
|
return this.#listSessionsFromDb(dbPath, sinceMs, input.isolatedSnapshot ?? false);
|
|
52413
52550
|
}
|
|
@@ -52539,8 +52676,7 @@ class OpencodeSdkHarness extends BaseHarness {
|
|
|
52539
52676
|
personaChannel: "native",
|
|
52540
52677
|
nativeAgentSelector: true,
|
|
52541
52678
|
tools: "sdk",
|
|
52542
|
-
|
|
52543
|
-
inference: (_profile, request) => opencodeCarriedKeys(Boolean(request.model?.resolved), request.inference, isModelWorkTools(request.tools))
|
|
52679
|
+
inference: MODEL_WORK_AGENT_INFERENCE
|
|
52544
52680
|
})
|
|
52545
52681
|
};
|
|
52546
52682
|
capabilities = caps({
|
|
@@ -52817,11 +52953,6 @@ var VALID_HARNESS_IDS2 = Object.freeze(HARNESS_REGISTRY.map((h) => h.id));
|
|
|
52817
52953
|
var SESSION_LOG_HARNESSES = HARNESS_REGISTRY.filter(isSessionLogHarness);
|
|
52818
52954
|
var AGENT_DISPATCH_HARNESSES = HARNESS_REGISTRY.filter((h) => h.capabilities.agentDispatch);
|
|
52819
52955
|
|
|
52820
|
-
// src/integrations/agent/model-map.ts
|
|
52821
|
-
var ENGINE_KEY_PATTERN = new RegExp(ENGINE_NAME_PATTERN_SOURCE);
|
|
52822
|
-
var RESERVED_MAP_KEYS = new Set(["__proto__", "constructor", "prototype", "tostring"]);
|
|
52823
|
-
var PROFILE_FIELD_KEYS = new Set(["model", "inference", "engine"]);
|
|
52824
|
-
|
|
52825
52956
|
// src/core/spawn-env.ts
|
|
52826
52957
|
var COMMON_SPAWN_ENV_PASSTHROUGH = [
|
|
52827
52958
|
"HOME",
|
|
@@ -52833,6 +52964,12 @@ var COMMON_SPAWN_ENV_PASSTHROUGH = [
|
|
|
52833
52964
|
"TMPDIR",
|
|
52834
52965
|
"AKM_EVENT_SOURCE"
|
|
52835
52966
|
];
|
|
52967
|
+
var XDG_BASE_DIR_ENV_PASSTHROUGH = [
|
|
52968
|
+
"XDG_CONFIG_HOME",
|
|
52969
|
+
"XDG_DATA_HOME",
|
|
52970
|
+
"XDG_CACHE_HOME",
|
|
52971
|
+
"XDG_STATE_HOME"
|
|
52972
|
+
];
|
|
52836
52973
|
var supplementedPaths = new Map;
|
|
52837
52974
|
|
|
52838
52975
|
// src/integrations/agent/profiles.ts
|
|
@@ -52843,7 +52980,7 @@ var BUILTINS = {
|
|
|
52843
52980
|
bin: "opencode",
|
|
52844
52981
|
args: ["run"],
|
|
52845
52982
|
stdio: "interactive",
|
|
52846
|
-
envPassthrough: [...COMMON_PASSTHROUGH, "OPENCODE_API_KEY", "OPENCODE_CONFIG"],
|
|
52983
|
+
envPassthrough: [...COMMON_PASSTHROUGH, "OPENCODE_API_KEY", "OPENCODE_CONFIG", ...XDG_BASE_DIR_ENV_PASSTHROUGH],
|
|
52847
52984
|
parseOutput: "text"
|
|
52848
52985
|
},
|
|
52849
52986
|
claude: {
|
|
@@ -52923,6 +53060,11 @@ var FALLBACK_ANNOUNCEMENT = `No engine is configured; falling back to \`${FALLBA
|
|
|
52923
53060
|
var NO_ENGINE_MESSAGE_SUFFIX = `has no selected engine, and no usable \`${OPENCODE_SDK_SERVER_BIN}\` binary was found to fall back to.`;
|
|
52924
53061
|
var NO_ENGINE_REMEDY = "Run `akm setup` to detect an installed agent, or set one explicitly: " + '`akm config set engines.claude \'{"kind":"agent","platform":"claude"}\'` ' + "then `akm config set defaults.engine claude`. " + `Installing the \`${OPENCODE_SDK_SERVER_BIN}\` binary also works ` + "(`npm i -g opencode-ai`) — akm falls back to it automatically.";
|
|
52925
53062
|
|
|
53063
|
+
// src/integrations/agent/model-map.ts
|
|
53064
|
+
var ENGINE_KEY_PATTERN = new RegExp(ENGINE_NAME_PATTERN_SOURCE);
|
|
53065
|
+
var RESERVED_MAP_KEYS = new Set(["__proto__", "constructor", "prototype", "tostring"]);
|
|
53066
|
+
var PROFILE_FIELD_KEYS = new Set(["model", "inference", "engine"]);
|
|
53067
|
+
|
|
52926
53068
|
// src/storage/repositories/improve-ledger-repository.ts
|
|
52927
53069
|
var LEDGER_REJECTION_WINDOW_DAYS = Object.freeze({
|
|
52928
53070
|
reflect: 14,
|
|
@@ -53311,8 +53453,8 @@ Commands:
|
|
|
53311
53453
|
`;
|
|
53312
53454
|
|
|
53313
53455
|
// scripts/akm-migrate/migrate/dead-residue.ts
|
|
53314
|
-
import
|
|
53315
|
-
import
|
|
53456
|
+
import fs39 from "node:fs";
|
|
53457
|
+
import path47 from "node:path";
|
|
53316
53458
|
var DEAD_RESIDUE_PATHS = [
|
|
53317
53459
|
{ name: "proposals", reason: "superseded by the `proposals` table in $DATA/state.db (0.9.0)" },
|
|
53318
53460
|
{ prefix: "runs.archived-", reason: "orphaned archive of a directory that no longer exists" },
|
|
@@ -53329,43 +53471,43 @@ function dirSizeBytes(target) {
|
|
|
53329
53471
|
let total = 0;
|
|
53330
53472
|
let entries;
|
|
53331
53473
|
try {
|
|
53332
|
-
entries =
|
|
53474
|
+
entries = fs39.readdirSync(target, { withFileTypes: true });
|
|
53333
53475
|
} catch {
|
|
53334
53476
|
return 0;
|
|
53335
53477
|
}
|
|
53336
53478
|
for (const entry of entries) {
|
|
53337
|
-
const entryPath =
|
|
53479
|
+
const entryPath = path47.join(target, entry.name);
|
|
53338
53480
|
if (entry.isDirectory()) {
|
|
53339
53481
|
total += dirSizeBytes(entryPath);
|
|
53340
53482
|
} else if (entry.isFile()) {
|
|
53341
53483
|
try {
|
|
53342
|
-
total +=
|
|
53484
|
+
total += fs39.statSync(entryPath).size;
|
|
53343
53485
|
} catch {}
|
|
53344
53486
|
}
|
|
53345
53487
|
}
|
|
53346
53488
|
return total;
|
|
53347
53489
|
}
|
|
53348
53490
|
function sizeOf(target) {
|
|
53349
|
-
const st =
|
|
53491
|
+
const st = fs39.statSync(target);
|
|
53350
53492
|
return st.isDirectory() ? dirSizeBytes(target) : st.size;
|
|
53351
53493
|
}
|
|
53352
53494
|
function hostResidue() {
|
|
53353
53495
|
const data = getDataDir();
|
|
53354
53496
|
const state = getStateDir();
|
|
53355
|
-
const configDir =
|
|
53497
|
+
const configDir = path47.dirname(getConfigPath());
|
|
53356
53498
|
const named = [
|
|
53357
|
-
{ absolutePath:
|
|
53358
|
-
{ absolutePath:
|
|
53359
|
-
{ absolutePath:
|
|
53360
|
-
{ absolutePath:
|
|
53361
|
-
{ absolutePath:
|
|
53362
|
-
{ absolutePath:
|
|
53363
|
-
{ absolutePath:
|
|
53499
|
+
{ absolutePath: path47.join(data, "txn"), reason: "filesystem transaction journals (removed in 0.9.17)" },
|
|
53500
|
+
{ absolutePath: path47.join(data, "txn-quarantine"), reason: "quarantined transaction journals (removed in 0.9.17)" },
|
|
53501
|
+
{ absolutePath: path47.join(data, "maintenance.barrier.lock"), reason: "maintenance barrier (removed in 0.9.17)" },
|
|
53502
|
+
{ absolutePath: path47.join(data, "maintenance-activities"), reason: "per-process activity registry (removed in 0.9.17)" },
|
|
53503
|
+
{ absolutePath: path47.join(state, "maintenance-activities"), reason: "per-process activity registry (removed in 0.9.17)" },
|
|
53504
|
+
{ absolutePath: path47.join(state, "version-reconcile.json"), reason: "startup reconcile stamp (removed in 0.9.17)" },
|
|
53505
|
+
{ absolutePath: path47.join(state, "locks", "version-reconcile.lock"), reason: "startup reconcile lock (removed in 0.9.17)" }
|
|
53364
53506
|
];
|
|
53365
53507
|
const found = [];
|
|
53366
53508
|
const claimed = new Set;
|
|
53367
53509
|
for (const entry of named) {
|
|
53368
|
-
if (claimed.has(entry.absolutePath) || !
|
|
53510
|
+
if (claimed.has(entry.absolutePath) || !fs39.existsSync(entry.absolutePath))
|
|
53369
53511
|
continue;
|
|
53370
53512
|
try {
|
|
53371
53513
|
found.push({ ...entry, relativePath: entry.absolutePath, sizeBytes: sizeOf(entry.absolutePath) });
|
|
@@ -53389,13 +53531,13 @@ function hostResidue() {
|
|
|
53389
53531
|
function findSidecars(root, depth, skip) {
|
|
53390
53532
|
let entries;
|
|
53391
53533
|
try {
|
|
53392
|
-
entries =
|
|
53534
|
+
entries = fs39.readdirSync(root, { withFileTypes: true });
|
|
53393
53535
|
} catch {
|
|
53394
53536
|
return [];
|
|
53395
53537
|
}
|
|
53396
53538
|
const found = [];
|
|
53397
53539
|
for (const entry of entries) {
|
|
53398
|
-
const entryPath =
|
|
53540
|
+
const entryPath = path47.join(root, entry.name);
|
|
53399
53541
|
if (entry.isFile() && entry.name.endsWith(".operations.sensitive"))
|
|
53400
53542
|
found.push(entryPath);
|
|
53401
53543
|
else if (entry.isDirectory() && depth > 0 && !skip.has(entryPath)) {
|
|
@@ -53408,10 +53550,10 @@ function findDeadResidueEntries(stashDir) {
|
|
|
53408
53550
|
const host = hostResidue();
|
|
53409
53551
|
if (stashDir === undefined)
|
|
53410
53552
|
return host;
|
|
53411
|
-
const akmDir =
|
|
53553
|
+
const akmDir = path47.join(stashDir, ".akm");
|
|
53412
53554
|
let names;
|
|
53413
53555
|
try {
|
|
53414
|
-
names =
|
|
53556
|
+
names = fs39.readdirSync(akmDir);
|
|
53415
53557
|
} catch {
|
|
53416
53558
|
return [];
|
|
53417
53559
|
}
|
|
@@ -53421,14 +53563,14 @@ function findDeadResidueEntries(stashDir) {
|
|
|
53421
53563
|
for (const name of matches) {
|
|
53422
53564
|
if (!names.includes(name))
|
|
53423
53565
|
continue;
|
|
53424
|
-
const absolutePath =
|
|
53566
|
+
const absolutePath = path47.join(akmDir, name);
|
|
53425
53567
|
let sizeBytes;
|
|
53426
53568
|
try {
|
|
53427
53569
|
sizeBytes = sizeOf(absolutePath);
|
|
53428
53570
|
} catch {
|
|
53429
53571
|
continue;
|
|
53430
53572
|
}
|
|
53431
|
-
found.push({ relativePath:
|
|
53573
|
+
found.push({ relativePath: path47.join(".akm", name), absolutePath, sizeBytes, reason: spec.reason });
|
|
53432
53574
|
}
|
|
53433
53575
|
}
|
|
53434
53576
|
return found;
|
|
@@ -53437,7 +53579,7 @@ function removeDeadResidue(stashDir) {
|
|
|
53437
53579
|
const entries = findDeadResidueEntries(stashDir);
|
|
53438
53580
|
return entries.map((entry) => {
|
|
53439
53581
|
try {
|
|
53440
|
-
|
|
53582
|
+
fs39.rmSync(entry.absolutePath, { recursive: true, force: true });
|
|
53441
53583
|
return { relativePath: entry.relativePath, sizeBytes: entry.sizeBytes, removed: true };
|
|
53442
53584
|
} catch (error2) {
|
|
53443
53585
|
return {
|
|
@@ -53452,18 +53594,18 @@ function removeDeadResidue(stashDir) {
|
|
|
53452
53594
|
|
|
53453
53595
|
// scripts/akm-migrate/task-migrate.ts
|
|
53454
53596
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
53455
|
-
import
|
|
53456
|
-
import
|
|
53457
|
-
import
|
|
53597
|
+
import fs41 from "node:fs";
|
|
53598
|
+
import os8 from "node:os";
|
|
53599
|
+
import path50 from "node:path";
|
|
53458
53600
|
|
|
53459
53601
|
// scripts/akm-migrate/migrate/task-files.ts
|
|
53460
53602
|
import crypto4 from "node:crypto";
|
|
53461
|
-
import
|
|
53462
|
-
import
|
|
53603
|
+
import fs40 from "node:fs";
|
|
53604
|
+
import path49 from "node:path";
|
|
53463
53605
|
|
|
53464
53606
|
// src/tasks/source/task-to-v4.ts
|
|
53465
53607
|
import crypto3 from "node:crypto";
|
|
53466
|
-
import
|
|
53608
|
+
import path48 from "node:path";
|
|
53467
53609
|
|
|
53468
53610
|
// src/tasks/task-id.ts
|
|
53469
53611
|
var VALID_TASK_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
@@ -54272,7 +54414,7 @@ function addSharedNonPromptOverrides(data, akm) {
|
|
|
54272
54414
|
}
|
|
54273
54415
|
function promptSourceKind(raw) {
|
|
54274
54416
|
const trimmed = raw.trim();
|
|
54275
|
-
if (trimmed.startsWith("./") || trimmed.startsWith("../") ||
|
|
54417
|
+
if (trimmed.startsWith("./") || trimmed.startsWith("../") || path48.isAbsolute(trimmed) || /^[A-Za-z]:[\\/]/.test(trimmed)) {
|
|
54276
54418
|
return "file";
|
|
54277
54419
|
}
|
|
54278
54420
|
try {
|
|
@@ -54376,7 +54518,7 @@ function planV2DataToV4(input, data) {
|
|
|
54376
54518
|
return blocked(input, "read-only-source", !input.writable ? "the owning source is not writable" : "the source file or publication directory is read-only");
|
|
54377
54519
|
}
|
|
54378
54520
|
try {
|
|
54379
|
-
validateTaskId(
|
|
54521
|
+
validateTaskId(path48.basename(input.filePath, ".yml"));
|
|
54380
54522
|
} catch (cause) {
|
|
54381
54523
|
return blocked(input, "invalid-v2-task", causeMessage(cause));
|
|
54382
54524
|
}
|
|
@@ -54521,7 +54663,7 @@ function taskToV4PlanFromOutcomes(outcomes) {
|
|
|
54521
54663
|
for (let index = 1;index < files.length; index += 1) {
|
|
54522
54664
|
const previous = files[index - 1];
|
|
54523
54665
|
const current = files[index];
|
|
54524
|
-
if (previous && current &&
|
|
54666
|
+
if (previous && current && path48.resolve(previous.filePath) === path48.resolve(current.filePath)) {
|
|
54525
54667
|
throw new Error(`duplicate task migration file path: ${current.filePath}`);
|
|
54526
54668
|
}
|
|
54527
54669
|
}
|
|
@@ -54533,18 +54675,18 @@ function migrationError(detail) {
|
|
|
54533
54675
|
return new ConfigError(`Task migration failed: ${detail}`, "INVALID_CONFIG_FILE");
|
|
54534
54676
|
}
|
|
54535
54677
|
function contained2(root, candidate) {
|
|
54536
|
-
const relative =
|
|
54537
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
54678
|
+
const relative = path49.relative(root, candidate);
|
|
54679
|
+
return relative === "" || !relative.startsWith("..") && !path49.isAbsolute(relative);
|
|
54538
54680
|
}
|
|
54539
54681
|
function realDirectory(filePath) {
|
|
54540
|
-
const stat =
|
|
54682
|
+
const stat = fs40.lstatSync(filePath);
|
|
54541
54683
|
if (stat.isSymbolicLink() || !stat.isDirectory())
|
|
54542
54684
|
throw migrationError(`${filePath} must be a real directory.`);
|
|
54543
|
-
return
|
|
54685
|
+
return fs40.realpathSync(filePath);
|
|
54544
54686
|
}
|
|
54545
54687
|
function isWritable(filePath) {
|
|
54546
54688
|
try {
|
|
54547
|
-
|
|
54689
|
+
fs40.accessSync(filePath, fs40.constants.W_OK);
|
|
54548
54690
|
return true;
|
|
54549
54691
|
} catch {
|
|
54550
54692
|
return false;
|
|
@@ -54557,12 +54699,12 @@ function walkTasks(root, tasksDir, out) {
|
|
|
54557
54699
|
throw migrationError(`${root.root} resolves outside bundle ${root.bundleId}.`);
|
|
54558
54700
|
}
|
|
54559
54701
|
const visit2 = (directory) => {
|
|
54560
|
-
const physicalDirectory =
|
|
54702
|
+
const physicalDirectory = fs40.realpathSync(directory);
|
|
54561
54703
|
if (!contained2(physicalRoot, physicalDirectory)) {
|
|
54562
54704
|
throw migrationError(`${directory} resolves outside bundle ${root.bundleId}.`);
|
|
54563
54705
|
}
|
|
54564
|
-
for (const entry of
|
|
54565
|
-
const candidate =
|
|
54706
|
+
for (const entry of fs40.readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
54707
|
+
const candidate = path49.join(directory, entry.name);
|
|
54566
54708
|
if (entry.isSymbolicLink())
|
|
54567
54709
|
throw migrationError(`task migration does not follow symbolic link ${candidate}.`);
|
|
54568
54710
|
if (entry.isDirectory()) {
|
|
@@ -54571,11 +54713,11 @@ function walkTasks(root, tasksDir, out) {
|
|
|
54571
54713
|
}
|
|
54572
54714
|
if (!entry.isFile() || !entry.name.endsWith(".yml"))
|
|
54573
54715
|
continue;
|
|
54574
|
-
const stat =
|
|
54716
|
+
const stat = fs40.lstatSync(candidate);
|
|
54575
54717
|
const mode = stat.mode & 511;
|
|
54576
54718
|
out.push({
|
|
54577
54719
|
filePath: candidate,
|
|
54578
|
-
bytes:
|
|
54720
|
+
bytes: fs40.readFileSync(candidate),
|
|
54579
54721
|
mode,
|
|
54580
54722
|
writable: root.writable,
|
|
54581
54723
|
onDiskWritable: isWritable(candidate) && isWritable(directory) && (mode & 146) !== 0,
|
|
@@ -54588,9 +54730,9 @@ function walkTasks(root, tasksDir, out) {
|
|
|
54588
54730
|
function inspectTaskFiles(roots) {
|
|
54589
54731
|
const files = [];
|
|
54590
54732
|
for (const root of [...roots].sort((a, b) => a.bundleId.localeCompare(b.bundleId))) {
|
|
54591
|
-
const tasksDir = root.layout === "akm-task" ? root.root :
|
|
54733
|
+
const tasksDir = root.layout === "akm-task" ? root.root : path49.join(root.root, "tasks");
|
|
54592
54734
|
try {
|
|
54593
|
-
const stat =
|
|
54735
|
+
const stat = fs40.lstatSync(tasksDir);
|
|
54594
54736
|
if (stat.isSymbolicLink())
|
|
54595
54737
|
throw migrationError(`task migration does not follow symbolic link ${tasksDir}.`);
|
|
54596
54738
|
if (!stat.isDirectory())
|
|
@@ -54608,18 +54750,18 @@ function planTaskFilesMigration(inputs) {
|
|
|
54608
54750
|
return taskToV4PlanFromOutcomes(inputs.map(planTaskToV4File));
|
|
54609
54751
|
}
|
|
54610
54752
|
function taskFileBackupPath(backupRoot, filePath) {
|
|
54611
|
-
const digest = crypto4.createHash("sha256").update(
|
|
54612
|
-
return
|
|
54753
|
+
const digest = crypto4.createHash("sha256").update(path49.resolve(filePath)).digest("hex").slice(0, 16);
|
|
54754
|
+
return path49.join(backupRoot, "files", `${digest}-${path49.basename(filePath)}`);
|
|
54613
54755
|
}
|
|
54614
54756
|
function fsyncDirectory(directory) {
|
|
54615
54757
|
if (process.platform === "win32")
|
|
54616
54758
|
return;
|
|
54617
54759
|
try {
|
|
54618
|
-
const fd =
|
|
54760
|
+
const fd = fs40.openSync(directory, "r");
|
|
54619
54761
|
try {
|
|
54620
|
-
|
|
54762
|
+
fs40.fsyncSync(fd);
|
|
54621
54763
|
} finally {
|
|
54622
|
-
|
|
54764
|
+
fs40.closeSync(fd);
|
|
54623
54765
|
}
|
|
54624
54766
|
} catch (cause) {
|
|
54625
54767
|
const code = cause.code;
|
|
@@ -54628,25 +54770,25 @@ function fsyncDirectory(directory) {
|
|
|
54628
54770
|
}
|
|
54629
54771
|
}
|
|
54630
54772
|
function writeDurable(filePath, bytes, mode, exclusive = false) {
|
|
54631
|
-
|
|
54632
|
-
const fd =
|
|
54773
|
+
fs40.mkdirSync(path49.dirname(filePath), { recursive: true });
|
|
54774
|
+
const fd = fs40.openSync(filePath, exclusive ? "wx" : "w", mode);
|
|
54633
54775
|
try {
|
|
54634
|
-
|
|
54635
|
-
|
|
54776
|
+
fs40.writeFileSync(fd, bytes);
|
|
54777
|
+
fs40.fsyncSync(fd);
|
|
54636
54778
|
} finally {
|
|
54637
|
-
|
|
54779
|
+
fs40.closeSync(fd);
|
|
54638
54780
|
}
|
|
54639
|
-
|
|
54640
|
-
fsyncDirectory(
|
|
54781
|
+
fs40.chmodSync(filePath, mode);
|
|
54782
|
+
fsyncDirectory(path49.dirname(filePath));
|
|
54641
54783
|
}
|
|
54642
54784
|
function replaceAtomically(filePath, bytes, mode) {
|
|
54643
|
-
const temporary =
|
|
54785
|
+
const temporary = path49.join(path49.dirname(filePath), `.${path49.basename(filePath)}.migrate-${crypto4.randomUUID()}`);
|
|
54644
54786
|
try {
|
|
54645
54787
|
writeDurable(temporary, bytes, mode, true);
|
|
54646
|
-
|
|
54647
|
-
fsyncDirectory(
|
|
54788
|
+
fs40.renameSync(temporary, filePath);
|
|
54789
|
+
fsyncDirectory(path49.dirname(filePath));
|
|
54648
54790
|
} finally {
|
|
54649
|
-
|
|
54791
|
+
fs40.rmSync(temporary, { force: true });
|
|
54650
54792
|
}
|
|
54651
54793
|
}
|
|
54652
54794
|
function applyTaskFilesPlan(plan, options) {
|
|
@@ -54669,7 +54811,7 @@ function applyTaskFilesPlan(plan, options) {
|
|
|
54669
54811
|
}
|
|
54670
54812
|
} catch (cause) {
|
|
54671
54813
|
for (const change of [...replaced].reverse()) {
|
|
54672
|
-
replaceAtomically(change.filePath,
|
|
54814
|
+
replaceAtomically(change.filePath, fs40.readFileSync(taskFileBackupPath(options.backupRoot, change.filePath)), change.mode);
|
|
54673
54815
|
}
|
|
54674
54816
|
throw cause;
|
|
54675
54817
|
}
|
|
@@ -54679,14 +54821,14 @@ function applyTaskFilesPlan(plan, options) {
|
|
|
54679
54821
|
// scripts/akm-migrate/task-migrate.ts
|
|
54680
54822
|
function expandTilde(value) {
|
|
54681
54823
|
if (value === "~")
|
|
54682
|
-
return
|
|
54824
|
+
return os8.homedir();
|
|
54683
54825
|
if (value.startsWith("~/") || value.startsWith("~\\"))
|
|
54684
|
-
return
|
|
54826
|
+
return path50.join(os8.homedir(), value.slice(2));
|
|
54685
54827
|
return value;
|
|
54686
54828
|
}
|
|
54687
54829
|
function existingDirectory(target) {
|
|
54688
54830
|
try {
|
|
54689
|
-
return
|
|
54831
|
+
return fs41.statSync(target).isDirectory();
|
|
54690
54832
|
} catch (cause) {
|
|
54691
54833
|
if (cause.code === "ENOENT")
|
|
54692
54834
|
return false;
|
|
@@ -54707,14 +54849,14 @@ function taskRoots(config, resolutionBase = process.cwd()) {
|
|
|
54707
54849
|
const source = sources.get(bundleId);
|
|
54708
54850
|
if (!source)
|
|
54709
54851
|
continue;
|
|
54710
|
-
const configuredRoot = source.type === "filesystem" && source.path ?
|
|
54852
|
+
const configuredRoot = source.type === "filesystem" && source.path ? path50.resolve(resolutionBase, expandTilde(source.path)) : lockContentRootFor(bundleId, source.type);
|
|
54711
54853
|
if (!configuredRoot || !existingDirectory(configuredRoot))
|
|
54712
54854
|
continue;
|
|
54713
|
-
const bundleRoot =
|
|
54855
|
+
const bundleRoot = path50.resolve(configuredRoot);
|
|
54714
54856
|
const component = bundleComponentConfig(bundle);
|
|
54715
|
-
const componentRoot =
|
|
54716
|
-
const relative =
|
|
54717
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
54857
|
+
const componentRoot = path50.resolve(bundleRoot, component?.root ?? ".");
|
|
54858
|
+
const relative = path50.relative(bundleRoot, componentRoot);
|
|
54859
|
+
if (relative === ".." || relative.startsWith(`..${path50.sep}`) || path50.isAbsolute(relative)) {
|
|
54718
54860
|
throw new ConfigError(`Task migration component root ${componentRoot} escapes bundle ${bundleId} at ${bundleRoot}.`, "INVALID_CONFIG_FILE");
|
|
54719
54861
|
}
|
|
54720
54862
|
if (!existingDirectory(componentRoot))
|
|
@@ -54731,7 +54873,7 @@ function taskRoots(config, resolutionBase = process.cwd()) {
|
|
|
54731
54873
|
}
|
|
54732
54874
|
const envStash = process.env.AKM_BUNDLE_DIR?.trim();
|
|
54733
54875
|
if (envStash && existingDirectory(envStash)) {
|
|
54734
|
-
const stashRoot =
|
|
54876
|
+
const stashRoot = path50.resolve(envStash);
|
|
54735
54877
|
if (!rootsByPath.has(stashRoot)) {
|
|
54736
54878
|
const bundleId = deriveBundleId(undefined, stashRoot, new Set(Object.keys(config.bundles ?? {})));
|
|
54737
54879
|
const candidate = taskRoot(bundleId, stashRoot, stashRoot, detectAdapterId(stashRoot), () => true);
|
|
@@ -54744,7 +54886,7 @@ function taskRoots(config, resolutionBase = process.cwd()) {
|
|
|
54744
54886
|
function taskRoot(bundleId, bundleRoot, componentRoot, configuredAdapter, writable) {
|
|
54745
54887
|
const adapter = configuredAdapter ?? detectAdapterId(componentRoot, "");
|
|
54746
54888
|
if (!configuredAdapter && adapter === "") {
|
|
54747
|
-
const flatTasks =
|
|
54889
|
+
const flatTasks = fs41.readdirSync(componentRoot, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".yml")).map((entry) => entry.name).sort();
|
|
54748
54890
|
if (flatTasks.length > 0) {
|
|
54749
54891
|
throw new ConfigError(`Task migration cannot classify top-level task file(s) ${flatTasks.join(", ")} in bundle ${bundleId}; configure adapter "akm-task" or move them under tasks/.`, "INVALID_CONFIG_FILE");
|
|
54750
54892
|
}
|
|
@@ -54800,7 +54942,7 @@ function applyTaskFilesMigration() {
|
|
|
54800
54942
|
const before = inspectCurrent();
|
|
54801
54943
|
if (before.result.taskFiles.changed === 0)
|
|
54802
54944
|
return before.result;
|
|
54803
|
-
const backupPath =
|
|
54945
|
+
const backupPath = path50.join(getDataDir(), "backups", "tasks", `${Date.now()}-${randomUUID3()}`);
|
|
54804
54946
|
const applied = applyTaskFilesPlan(before.plan, { backupRoot: backupPath });
|
|
54805
54947
|
return { ...inspectCurrent().result, backupPath, applied: applied.changed.length };
|
|
54806
54948
|
});
|