@kody-ade/kody-engine 0.4.410 → 0.4.411
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/dist/bin/kody.js +281 -312
- package/package.json +1 -1
- package/templates/kody.yml +88 -0
package/dist/bin/kody.js
CHANGED
|
@@ -15,7 +15,7 @@ var init_package = __esm({
|
|
|
15
15
|
"package.json"() {
|
|
16
16
|
package_default = {
|
|
17
17
|
name: "@kody-ade/kody-engine",
|
|
18
|
-
version: "0.4.
|
|
18
|
+
version: "0.4.411",
|
|
19
19
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
|
|
20
20
|
license: "MIT",
|
|
21
21
|
type: "module",
|
|
@@ -746,7 +746,7 @@ function buildVerifyEnv(source = process.env) {
|
|
|
746
746
|
return env;
|
|
747
747
|
}
|
|
748
748
|
function runCommand(command, cwd) {
|
|
749
|
-
return new Promise((
|
|
749
|
+
return new Promise((resolve17) => {
|
|
750
750
|
const start = Date.now();
|
|
751
751
|
const child = spawn(command, {
|
|
752
752
|
cwd,
|
|
@@ -775,11 +775,11 @@ function runCommand(command, cwd) {
|
|
|
775
775
|
child.on("exit", (code) => {
|
|
776
776
|
clearTimeout(timer);
|
|
777
777
|
const tail = Buffer.concat(buffers).toString("utf-8").slice(-TAIL_CHARS);
|
|
778
|
-
|
|
778
|
+
resolve17({ exitCode: code ?? -1, durationMs: Date.now() - start, tail });
|
|
779
779
|
});
|
|
780
780
|
child.on("error", (err) => {
|
|
781
781
|
clearTimeout(timer);
|
|
782
|
-
|
|
782
|
+
resolve17({ exitCode: -1, durationMs: Date.now() - start, tail: err.message });
|
|
783
783
|
});
|
|
784
784
|
});
|
|
785
785
|
}
|
|
@@ -1088,7 +1088,7 @@ function cmsHeaders(opts) {
|
|
|
1088
1088
|
}
|
|
1089
1089
|
};
|
|
1090
1090
|
}
|
|
1091
|
-
async function callDashboardCms(opts,
|
|
1091
|
+
async function callDashboardCms(opts, path52, init = {}) {
|
|
1092
1092
|
const baseUrl = dashboardBaseUrl(opts);
|
|
1093
1093
|
if (!baseUrl) {
|
|
1094
1094
|
return {
|
|
@@ -1100,7 +1100,7 @@ async function callDashboardCms(opts, path51, init = {}) {
|
|
|
1100
1100
|
const headerResult = cmsHeaders(opts);
|
|
1101
1101
|
if (!headerResult.ok) return headerResult;
|
|
1102
1102
|
try {
|
|
1103
|
-
const res = await fetch(`${baseUrl}${
|
|
1103
|
+
const res = await fetch(`${baseUrl}${path52}`, {
|
|
1104
1104
|
...init,
|
|
1105
1105
|
headers: {
|
|
1106
1106
|
...headerResult.headers,
|
|
@@ -1172,8 +1172,8 @@ function documentArg(value) {
|
|
|
1172
1172
|
function normalizeCmsDocumentIdInput(input) {
|
|
1173
1173
|
const trimmed = stripWrappingQuotes(input.trim());
|
|
1174
1174
|
const withoutQuery = trimmed.split(/[?#]/, 1)[0] ?? trimmed;
|
|
1175
|
-
const
|
|
1176
|
-
return
|
|
1175
|
+
const path52 = parseDocumentPath(withoutQuery);
|
|
1176
|
+
return path52 ?? parseDocumentIdSegment(withoutQuery) ?? withoutQuery;
|
|
1177
1177
|
}
|
|
1178
1178
|
function stripWrappingQuotes(value) {
|
|
1179
1179
|
let current = value;
|
|
@@ -1184,9 +1184,9 @@ function stripWrappingQuotes(value) {
|
|
|
1184
1184
|
}
|
|
1185
1185
|
}
|
|
1186
1186
|
function parseDocumentPath(value) {
|
|
1187
|
-
const
|
|
1188
|
-
if (!
|
|
1189
|
-
const parts =
|
|
1187
|
+
const path52 = value.startsWith("http://") || value.startsWith("https://") ? urlPathname(value) : value;
|
|
1188
|
+
if (!path52?.includes("/content/entries/")) return null;
|
|
1189
|
+
const parts = path52.split("/").filter(Boolean).map(decodePathPart);
|
|
1190
1190
|
const entriesIndex = parts.findIndex((part, index) => part === "content" && parts[index + 1] === "entries");
|
|
1191
1191
|
const idPart = parts[entriesIndex + 3];
|
|
1192
1192
|
if (!idPart || idPart === "new") return null;
|
|
@@ -3153,7 +3153,7 @@ var init_repoWorkspace = __esm({
|
|
|
3153
3153
|
defaultCloneRepo = (repo, token, dir) => {
|
|
3154
3154
|
fs7.mkdirSync(path8.dirname(dir), { recursive: true });
|
|
3155
3155
|
const clone = buildCloneProcess(repo, token);
|
|
3156
|
-
return new Promise((
|
|
3156
|
+
return new Promise((resolve17, reject) => {
|
|
3157
3157
|
const child = spawn2("git", ["clone", "--depth=1", clone.url, dir], {
|
|
3158
3158
|
env: clone.env,
|
|
3159
3159
|
stdio: "inherit"
|
|
@@ -3173,7 +3173,7 @@ var init_repoWorkspace = __esm({
|
|
|
3173
3173
|
}
|
|
3174
3174
|
} catch {
|
|
3175
3175
|
}
|
|
3176
|
-
|
|
3176
|
+
resolve17();
|
|
3177
3177
|
});
|
|
3178
3178
|
child.on("error", reject);
|
|
3179
3179
|
});
|
|
@@ -3484,10 +3484,10 @@ async function runAgent(opts) {
|
|
|
3484
3484
|
let timer;
|
|
3485
3485
|
let next;
|
|
3486
3486
|
if (turnTimeoutMs > 0) {
|
|
3487
|
-
const timeoutPromise = new Promise((
|
|
3487
|
+
const timeoutPromise = new Promise((resolve17) => {
|
|
3488
3488
|
timer = setTimeout(() => {
|
|
3489
3489
|
timedOut = true;
|
|
3490
|
-
|
|
3490
|
+
resolve17({ done: true, value: void 0 });
|
|
3491
3491
|
}, turnTimeoutMs);
|
|
3492
3492
|
});
|
|
3493
3493
|
next = await Promise.race([nextPromise, timeoutPromise]);
|
|
@@ -3503,7 +3503,7 @@ async function runAgent(opts) {
|
|
|
3503
3503
|
try {
|
|
3504
3504
|
await Promise.race([
|
|
3505
3505
|
iterator.return(void 0).catch(() => void 0),
|
|
3506
|
-
new Promise((
|
|
3506
|
+
new Promise((resolve17) => setTimeout(resolve17, 1e4).unref())
|
|
3507
3507
|
]);
|
|
3508
3508
|
} catch {
|
|
3509
3509
|
}
|
|
@@ -3769,7 +3769,7 @@ function prepareTaskArtifactsDir(cwd, taskId) {
|
|
|
3769
3769
|
function initializeTaskArtifacts(artifacts, metadata = { taskType: "job" }) {
|
|
3770
3770
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3771
3771
|
const defaults = {
|
|
3772
|
-
"context.json": JSON.stringify(
|
|
3772
|
+
"context.json": `${JSON.stringify(
|
|
3773
3773
|
{
|
|
3774
3774
|
taskId: artifacts.taskId,
|
|
3775
3775
|
taskType: metadata.taskType,
|
|
@@ -3786,7 +3786,8 @@ function initializeTaskArtifacts(artifacts, metadata = { taskType: "job" }) {
|
|
|
3786
3786
|
},
|
|
3787
3787
|
null,
|
|
3788
3788
|
2
|
|
3789
|
-
)
|
|
3789
|
+
)}
|
|
3790
|
+
`,
|
|
3790
3791
|
"memory-recs.json": "[]\n",
|
|
3791
3792
|
"followups.json": "[]\n",
|
|
3792
3793
|
"handoff-notes.md": "Baseline handoff: the agent did not provide additional notes.\n"
|
|
@@ -6669,11 +6670,11 @@ async function nextAvailableLitellmUrl(url) {
|
|
|
6669
6670
|
throw new Error(`no free LiteLLM port found after ${startPort}`);
|
|
6670
6671
|
}
|
|
6671
6672
|
function canListen(port, host) {
|
|
6672
|
-
return new Promise((
|
|
6673
|
+
return new Promise((resolve17) => {
|
|
6673
6674
|
const server = net.createServer();
|
|
6674
|
-
server.once("error", () =>
|
|
6675
|
+
server.once("error", () => resolve17(false));
|
|
6675
6676
|
server.once("listening", () => {
|
|
6676
|
-
server.close(() =>
|
|
6677
|
+
server.close(() => resolve17(true));
|
|
6677
6678
|
});
|
|
6678
6679
|
server.listen(port, host);
|
|
6679
6680
|
});
|
|
@@ -7834,9 +7835,9 @@ import * as fs26 from "fs";
|
|
|
7834
7835
|
function stageGoalRunLogEvent(data, goalId, event, at = nowIso()) {
|
|
7835
7836
|
const logs = goalRunLogs(data);
|
|
7836
7837
|
const existing = logs[goalId];
|
|
7837
|
-
const
|
|
7838
|
+
const path52 = existing?.path ?? goalRunLogPath(goalId, data);
|
|
7838
7839
|
logs[goalId] = {
|
|
7839
|
-
path:
|
|
7840
|
+
path: path52,
|
|
7840
7841
|
events: [...existing?.events ?? [], buildGoalRunLogEvent(data, goalId, event, at)]
|
|
7841
7842
|
};
|
|
7842
7843
|
}
|
|
@@ -7961,7 +7962,7 @@ function buildGoalRunLogEvent(data, goalId, event, at) {
|
|
|
7961
7962
|
if (context !== void 0) base.dispatchContext = context;
|
|
7962
7963
|
return base;
|
|
7963
7964
|
}
|
|
7964
|
-
function enrichGoalRunLogEvent(config, data,
|
|
7965
|
+
function enrichGoalRunLogEvent(config, data, _logPath, event) {
|
|
7965
7966
|
const trigger = event.trigger ?? triggerContext();
|
|
7966
7967
|
const job = event.job ?? jobContext(data);
|
|
7967
7968
|
const run = event.run ?? runContext(data);
|
|
@@ -8252,7 +8253,7 @@ function backendTenant(config) {
|
|
|
8252
8253
|
return owner && repo ? `${owner}/${repo}` : null;
|
|
8253
8254
|
}
|
|
8254
8255
|
function decodeGoal(doc) {
|
|
8255
|
-
if (!doc
|
|
8256
|
+
if (!doc?.state || typeof doc.state !== "object" || Array.isArray(doc.state)) return null;
|
|
8256
8257
|
const state = doc.state;
|
|
8257
8258
|
if (typeof state.state !== "string" || !state.extra || typeof state.extra !== "object") return null;
|
|
8258
8259
|
return state;
|
|
@@ -8809,11 +8810,11 @@ function validateWorkflow(value, options = {}) {
|
|
|
8809
8810
|
function formatWorkflowValidationIssues(issues) {
|
|
8810
8811
|
return issues.map((entry) => `${entry.path}: ${entry.message}`);
|
|
8811
8812
|
}
|
|
8812
|
-
function validateDataMatch(value,
|
|
8813
|
+
function validateDataMatch(value, path52, issues, capabilityOutputs) {
|
|
8813
8814
|
if (value === void 0) return;
|
|
8814
8815
|
const match = asRecord2(value);
|
|
8815
8816
|
if (!match || Object.keys(match).length === 0) {
|
|
8816
|
-
issue(issues, "invalid_condition",
|
|
8817
|
+
issue(issues, "invalid_condition", path52, "workflow condition must contain at least one match");
|
|
8817
8818
|
return;
|
|
8818
8819
|
}
|
|
8819
8820
|
for (const [field, expected] of Object.entries(match)) {
|
|
@@ -8821,7 +8822,7 @@ function validateDataMatch(value, path51, issues, capabilityOutputs) {
|
|
|
8821
8822
|
issue(
|
|
8822
8823
|
issues,
|
|
8823
8824
|
"invalid_data_path",
|
|
8824
|
-
`${
|
|
8825
|
+
`${path52}.${field}`,
|
|
8825
8826
|
`workflow condition must read from facts, evidence, artifacts, result, workflow, or lastOutcome`
|
|
8826
8827
|
);
|
|
8827
8828
|
}
|
|
@@ -8829,12 +8830,12 @@ function validateDataMatch(value, path51, issues, capabilityOutputs) {
|
|
|
8829
8830
|
issue(
|
|
8830
8831
|
issues,
|
|
8831
8832
|
"undeclared_result_path",
|
|
8832
|
-
`${
|
|
8833
|
+
`${path52}.${field}`,
|
|
8833
8834
|
`workflow condition reads ${field}, but the source capability does not declare it`
|
|
8834
8835
|
);
|
|
8835
8836
|
}
|
|
8836
8837
|
if (!isComparable(expected)) {
|
|
8837
|
-
issue(issues, "invalid_condition_value", `${
|
|
8838
|
+
issue(issues, "invalid_condition_value", `${path52}.${field}`, "workflow condition value must be a JSON scalar");
|
|
8838
8839
|
}
|
|
8839
8840
|
}
|
|
8840
8841
|
}
|
|
@@ -8852,8 +8853,8 @@ function isComparable(value) {
|
|
|
8852
8853
|
if (value === null || ["string", "number", "boolean"].includes(typeof value)) return true;
|
|
8853
8854
|
return Array.isArray(value) && value.length > 0 && value.every((item) => isComparable(item) && !Array.isArray(item));
|
|
8854
8855
|
}
|
|
8855
|
-
function issue(issues, code,
|
|
8856
|
-
issues.push({ code, path:
|
|
8856
|
+
function issue(issues, code, path52, message) {
|
|
8857
|
+
issues.push({ code, path: path52, message });
|
|
8857
8858
|
}
|
|
8858
8859
|
var SAFE_NAME, SAFE_STEP_ID, SAFE_DATA_PATH, SUPPORTED_STEP_FIELDS, SUPPORTED_TRANSITION_FIELDS;
|
|
8859
8860
|
var init_workflowValidation = __esm({
|
|
@@ -9111,15 +9112,15 @@ var init_backendStateBackend = __esm({
|
|
|
9111
9112
|
this.jobsDir = opts.jobsDir.replace(/\/+$/, "");
|
|
9112
9113
|
}
|
|
9113
9114
|
async load(slug) {
|
|
9114
|
-
const
|
|
9115
|
+
const path52 = stateFilePath(this.jobsDir, slug);
|
|
9115
9116
|
const loaded = await createStateBackendFromEnv().get(this.tenantId, `capabilities/${slug}`, "job-state");
|
|
9116
9117
|
if (!loaded) {
|
|
9117
|
-
return { path:
|
|
9118
|
+
return { path: path52, handle: null, state: initialStateEnvelope("seed"), created: true };
|
|
9118
9119
|
}
|
|
9119
9120
|
if (!isStateEnvelope(loaded.doc)) {
|
|
9120
9121
|
throw new Error(`BackendStateBackend: capabilities/${slug} is not a StateEnvelope`);
|
|
9121
9122
|
}
|
|
9122
|
-
return { path:
|
|
9123
|
+
return { path: path52, handle: loaded.updatedAt, state: loaded.doc, created: false };
|
|
9123
9124
|
}
|
|
9124
9125
|
async save(loaded, next) {
|
|
9125
9126
|
if (!loaded.created && isStateUnchanged(loaded.state, next)) return false;
|
|
@@ -13915,14 +13916,33 @@ var init_fixFlow = __esm({
|
|
|
13915
13916
|
}
|
|
13916
13917
|
});
|
|
13917
13918
|
|
|
13918
|
-
// src/
|
|
13919
|
-
import { execFileSync as execFileSync14 } from "child_process";
|
|
13919
|
+
// src/workflow-template.ts
|
|
13920
13920
|
import * as fs35 from "fs";
|
|
13921
13921
|
import * as path33 from "path";
|
|
13922
|
+
import { fileURLToPath } from "url";
|
|
13923
|
+
function loadKodyWorkflowTemplate() {
|
|
13924
|
+
const here = path33.dirname(fileURLToPath(import.meta.url));
|
|
13925
|
+
const candidates = [path33.resolve(here, "../templates/kody.yml"), path33.resolve(here, "../../templates/kody.yml")];
|
|
13926
|
+
const source = candidates.find((candidate) => fs35.existsSync(candidate));
|
|
13927
|
+
if (!source) throw new Error(`Kody workflow template is missing: ${KODY_WORKFLOW_TEMPLATE_PATH}`);
|
|
13928
|
+
return fs35.readFileSync(source, "utf8");
|
|
13929
|
+
}
|
|
13930
|
+
var KODY_WORKFLOW_TEMPLATE_PATH;
|
|
13931
|
+
var init_workflow_template = __esm({
|
|
13932
|
+
"src/workflow-template.ts"() {
|
|
13933
|
+
"use strict";
|
|
13934
|
+
KODY_WORKFLOW_TEMPLATE_PATH = "templates/kody.yml";
|
|
13935
|
+
}
|
|
13936
|
+
});
|
|
13937
|
+
|
|
13938
|
+
// src/scripts/initFlow.ts
|
|
13939
|
+
import { execFileSync as execFileSync14 } from "child_process";
|
|
13940
|
+
import * as fs36 from "fs";
|
|
13941
|
+
import * as path34 from "path";
|
|
13922
13942
|
function detectPackageManager(cwd) {
|
|
13923
|
-
if (
|
|
13924
|
-
if (
|
|
13925
|
-
if (
|
|
13943
|
+
if (fs36.existsSync(path34.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
13944
|
+
if (fs36.existsSync(path34.join(cwd, "yarn.lock"))) return "yarn";
|
|
13945
|
+
if (fs36.existsSync(path34.join(cwd, "bun.lockb"))) return "bun";
|
|
13926
13946
|
return "npm";
|
|
13927
13947
|
}
|
|
13928
13948
|
function qualityCommandsFor(pm) {
|
|
@@ -13994,22 +14014,22 @@ function performInit(cwd, force) {
|
|
|
13994
14014
|
const pm = detectPackageManager(cwd);
|
|
13995
14015
|
const ownerRepo = detectOwnerRepo(cwd);
|
|
13996
14016
|
const defaultBranch = defaultBranchFromGit(cwd);
|
|
13997
|
-
const configPath =
|
|
13998
|
-
if (
|
|
14017
|
+
const configPath = path34.join(cwd, "kody.config.json");
|
|
14018
|
+
if (fs36.existsSync(configPath) && !force) {
|
|
13999
14019
|
skipped.push("kody.config.json");
|
|
14000
14020
|
} else {
|
|
14001
14021
|
const cfg = makeConfig(pm, ownerRepo, defaultBranch);
|
|
14002
|
-
|
|
14022
|
+
fs36.writeFileSync(configPath, `${JSON.stringify(cfg, null, 2)}
|
|
14003
14023
|
`);
|
|
14004
14024
|
wrote.push("kody.config.json");
|
|
14005
14025
|
}
|
|
14006
|
-
const workflowDir =
|
|
14007
|
-
const workflowPath =
|
|
14008
|
-
if (
|
|
14026
|
+
const workflowDir = path34.join(cwd, ".github", "workflows");
|
|
14027
|
+
const workflowPath = path34.join(workflowDir, "kody.yml");
|
|
14028
|
+
if (fs36.existsSync(workflowPath) && !force) {
|
|
14009
14029
|
skipped.push(".github/workflows/kody.yml");
|
|
14010
14030
|
} else {
|
|
14011
|
-
|
|
14012
|
-
|
|
14031
|
+
fs36.mkdirSync(workflowDir, { recursive: true });
|
|
14032
|
+
fs36.writeFileSync(workflowPath, loadKodyWorkflowTemplate());
|
|
14013
14033
|
wrote.push(".github/workflows/kody.yml");
|
|
14014
14034
|
}
|
|
14015
14035
|
for (const exe of listImplementations()) {
|
|
@@ -14020,12 +14040,12 @@ function performInit(cwd, force) {
|
|
|
14020
14040
|
continue;
|
|
14021
14041
|
}
|
|
14022
14042
|
if (profile.kind !== "scheduled" || !profile.schedule) continue;
|
|
14023
|
-
const target =
|
|
14024
|
-
if (
|
|
14043
|
+
const target = path34.join(workflowDir, `kody-${exe.name}.yml`);
|
|
14044
|
+
if (fs36.existsSync(target) && !force) {
|
|
14025
14045
|
skipped.push(`.github/workflows/kody-${exe.name}.yml`);
|
|
14026
14046
|
continue;
|
|
14027
14047
|
}
|
|
14028
|
-
|
|
14048
|
+
fs36.writeFileSync(target, renderScheduledWorkflow(exe.name, profile.schedule));
|
|
14029
14049
|
wrote.push(`.github/workflows/kody-${exe.name}.yml`);
|
|
14030
14050
|
}
|
|
14031
14051
|
let labels;
|
|
@@ -14071,7 +14091,7 @@ jobs:
|
|
|
14071
14091
|
run: npx -y -p @kody-ade/kody-engine@latest kody-engine implementation ${name}
|
|
14072
14092
|
`;
|
|
14073
14093
|
}
|
|
14074
|
-
var
|
|
14094
|
+
var initFlow;
|
|
14075
14095
|
var init_initFlow = __esm({
|
|
14076
14096
|
"src/scripts/initFlow.ts"() {
|
|
14077
14097
|
"use strict";
|
|
@@ -14079,67 +14099,7 @@ var init_initFlow = __esm({
|
|
|
14079
14099
|
init_lifecycleLabels();
|
|
14080
14100
|
init_profile();
|
|
14081
14101
|
init_registry();
|
|
14082
|
-
|
|
14083
|
-
#
|
|
14084
|
-
# Triggers: @kody comment on an issue or PR, or manual workflow_dispatch.
|
|
14085
|
-
# Everything else (install deps, set up LiteLLM, run the agent, open the PR)
|
|
14086
|
-
# is handled inside the @kody-ade/kody-engine package.
|
|
14087
|
-
#
|
|
14088
|
-
# Required repo secrets: at least one model provider key (e.g. MINIMAX_API_KEY,
|
|
14089
|
-
# ANTHROPIC_API_KEY). kody reads any *_API_KEY secret automatically via
|
|
14090
|
-
# toJSON(secrets) \u2014 no need to list them here.
|
|
14091
|
-
#
|
|
14092
|
-
# Recommended: KODY_TOKEN secret \u2014 a PAT or GitHub App token with repo
|
|
14093
|
-
# scope so kody's pushes trigger downstream CI and PR-body edits succeed.
|
|
14094
|
-
|
|
14095
|
-
name: kody
|
|
14096
|
-
|
|
14097
|
-
on:
|
|
14098
|
-
workflow_dispatch:
|
|
14099
|
-
inputs:
|
|
14100
|
-
issue_number:
|
|
14101
|
-
description: "GitHub issue number"
|
|
14102
|
-
required: true
|
|
14103
|
-
type: string
|
|
14104
|
-
capability:
|
|
14105
|
-
description: "Capability action to run (default: run)"
|
|
14106
|
-
required: false
|
|
14107
|
-
type: string
|
|
14108
|
-
default: ""
|
|
14109
|
-
issue_comment:
|
|
14110
|
-
types: [created]
|
|
14111
|
-
|
|
14112
|
-
jobs:
|
|
14113
|
-
run:
|
|
14114
|
-
if: >-
|
|
14115
|
-
\${{ github.event_name == 'workflow_dispatch' ||
|
|
14116
|
-
(github.event_name == 'issue_comment' &&
|
|
14117
|
-
contains(github.event.comment.body, '@kody')) }}
|
|
14118
|
-
runs-on: ubuntu-latest
|
|
14119
|
-
timeout-minutes: 60
|
|
14120
|
-
permissions:
|
|
14121
|
-
issues: write
|
|
14122
|
-
pull-requests: write
|
|
14123
|
-
contents: write
|
|
14124
|
-
actions: read
|
|
14125
|
-
steps:
|
|
14126
|
-
- uses: actions/checkout@v4
|
|
14127
|
-
with:
|
|
14128
|
-
fetch-depth: 0
|
|
14129
|
-
token: \${{ secrets.KODY_TOKEN || github.token }}
|
|
14130
|
-
|
|
14131
|
-
- uses: actions/setup-node@v4
|
|
14132
|
-
with:
|
|
14133
|
-
node-version: 22
|
|
14134
|
-
|
|
14135
|
-
- uses: actions/setup-python@v5
|
|
14136
|
-
with:
|
|
14137
|
-
python-version: "3.12"
|
|
14138
|
-
|
|
14139
|
-
- env:
|
|
14140
|
-
ALL_SECRETS: \${{ toJSON(secrets) }}
|
|
14141
|
-
run: npx -y -p @kody-ade/kody-engine@latest kody-engine ci
|
|
14142
|
-
`;
|
|
14102
|
+
init_workflow_template();
|
|
14143
14103
|
initFlow = async (ctx) => {
|
|
14144
14104
|
const force = ctx.args.force === true;
|
|
14145
14105
|
const cwd = ctx.cwd;
|
|
@@ -14173,7 +14133,7 @@ Nothing to do. All files already present. (Use --force to overwrite.)
|
|
|
14173
14133
|
});
|
|
14174
14134
|
|
|
14175
14135
|
// src/scripts/loadAgentAdhoc.ts
|
|
14176
|
-
import * as
|
|
14136
|
+
import * as fs37 from "fs";
|
|
14177
14137
|
function resolveMessage(messageArg) {
|
|
14178
14138
|
const fromComment = readCommentBody();
|
|
14179
14139
|
if (fromComment) return stripDirective(fromComment);
|
|
@@ -14181,9 +14141,9 @@ function resolveMessage(messageArg) {
|
|
|
14181
14141
|
}
|
|
14182
14142
|
function readCommentBody() {
|
|
14183
14143
|
const eventPath = process.env.GITHUB_EVENT_PATH;
|
|
14184
|
-
if (!eventPath || !
|
|
14144
|
+
if (!eventPath || !fs37.existsSync(eventPath)) return "";
|
|
14185
14145
|
try {
|
|
14186
|
-
const event = JSON.parse(
|
|
14146
|
+
const event = JSON.parse(fs37.readFileSync(eventPath, "utf-8"));
|
|
14187
14147
|
return String(event.comment?.body ?? "");
|
|
14188
14148
|
} catch {
|
|
14189
14149
|
return "";
|
|
@@ -14237,10 +14197,10 @@ var init_loadAgentAdhoc = __esm({
|
|
|
14237
14197
|
throw new Error("loadAgentAdhoc: ctx.args.agent must be a non-empty slug");
|
|
14238
14198
|
}
|
|
14239
14199
|
const agentPath = resolveAgentFile(ctx.cwd, agentSlug, agentsDir);
|
|
14240
|
-
if (!
|
|
14200
|
+
if (!fs37.existsSync(agentPath)) {
|
|
14241
14201
|
throw new Error(`loadAgentAdhoc: agent identity not found: ${agentPath}`);
|
|
14242
14202
|
}
|
|
14243
|
-
const { title, body } = parseAgentFile(
|
|
14203
|
+
const { title, body } = parseAgentFile(fs37.readFileSync(agentPath, "utf-8"), agentSlug);
|
|
14244
14204
|
const message = resolveMessage(ctx.args.message);
|
|
14245
14205
|
if (!message) {
|
|
14246
14206
|
throw new Error(
|
|
@@ -14312,13 +14272,13 @@ var init_loadCapabilityState = __esm({
|
|
|
14312
14272
|
function isCompanyIntentId(value) {
|
|
14313
14273
|
return SLUG_RE.test(value);
|
|
14314
14274
|
}
|
|
14315
|
-
function normalizeCompanyIntent(
|
|
14275
|
+
function normalizeCompanyIntent(path52, raw) {
|
|
14316
14276
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
14317
|
-
throw new Error(`${
|
|
14277
|
+
throw new Error(`${path52}: intent must be JSON object`);
|
|
14318
14278
|
}
|
|
14319
14279
|
const input = raw;
|
|
14320
14280
|
const id = stringField4(input.id);
|
|
14321
|
-
if (!id || !isCompanyIntentId(id)) throw new Error(`${
|
|
14281
|
+
if (!id || !isCompanyIntentId(id)) throw new Error(`${path52}: invalid intent id`);
|
|
14322
14282
|
const createdAt = stringField4(input.createdAt) || nowIso();
|
|
14323
14283
|
const updatedAt = stringField4(input.updatedAt) || createdAt;
|
|
14324
14284
|
const description = stringField4(input.description);
|
|
@@ -14480,7 +14440,7 @@ function retryDelaysMs() {
|
|
|
14480
14440
|
}
|
|
14481
14441
|
function sleep(ms) {
|
|
14482
14442
|
if (ms <= 0) return Promise.resolve();
|
|
14483
|
-
return new Promise((
|
|
14443
|
+
return new Promise((resolve17) => setTimeout(resolve17, ms));
|
|
14484
14444
|
}
|
|
14485
14445
|
async function fetchGoalStateWithRetry(config, goalId, cwd) {
|
|
14486
14446
|
let state = await fetchGoalStateAsync(config, goalId, cwd);
|
|
@@ -14609,8 +14569,8 @@ var init_loadIssueStateComment = __esm({
|
|
|
14609
14569
|
});
|
|
14610
14570
|
|
|
14611
14571
|
// src/scripts/loadJobFromFile.ts
|
|
14612
|
-
import * as
|
|
14613
|
-
import * as
|
|
14572
|
+
import * as fs38 from "fs";
|
|
14573
|
+
import * as path35 from "path";
|
|
14614
14574
|
function parseJobFile(raw, slug) {
|
|
14615
14575
|
let stripped = raw;
|
|
14616
14576
|
if (stripped.startsWith("---\n")) {
|
|
@@ -14649,10 +14609,10 @@ var init_loadJobFromFile = __esm({
|
|
|
14649
14609
|
if (!slug) {
|
|
14650
14610
|
throw new Error(`loadJobFromFile: ctx.args.${slugArg} must be a non-empty slug`);
|
|
14651
14611
|
}
|
|
14652
|
-
const capability = resolveCapabilityFolder(slug,
|
|
14612
|
+
const capability = resolveCapabilityFolder(slug, path35.resolve(ctx.cwd, jobsDir));
|
|
14653
14613
|
if (!capability) {
|
|
14654
14614
|
throw new Error(
|
|
14655
|
-
`loadJobFromFile: capability folder not found or incomplete: ${
|
|
14615
|
+
`loadJobFromFile: capability folder not found or incomplete: ${path35.resolve(ctx.cwd, jobsDir, slug)}`
|
|
14656
14616
|
);
|
|
14657
14617
|
}
|
|
14658
14618
|
const { title, body, config } = capability;
|
|
@@ -14662,12 +14622,12 @@ var init_loadJobFromFile = __esm({
|
|
|
14662
14622
|
let agentIdentity = "";
|
|
14663
14623
|
if (agentSlug) {
|
|
14664
14624
|
const agentPath = resolveAgentFile(ctx.cwd, agentSlug, agentsDir);
|
|
14665
|
-
if (!
|
|
14625
|
+
if (!fs38.existsSync(agentPath)) {
|
|
14666
14626
|
throw new Error(
|
|
14667
14627
|
`loadJobFromFile: capability '${slug}' declares agent '${agentSlug}' but ${agentPath} does not exist`
|
|
14668
14628
|
);
|
|
14669
14629
|
}
|
|
14670
|
-
const agentRaw =
|
|
14630
|
+
const agentRaw = fs38.readFileSync(agentPath, "utf-8");
|
|
14671
14631
|
const parsed = parseJobFile(agentRaw, agentSlug);
|
|
14672
14632
|
agentTitle = parsed.title;
|
|
14673
14633
|
agentIdentity = parsed.body;
|
|
@@ -14747,13 +14707,13 @@ ${truncate2(issue2.body, FINDING_BODY_MAX_BYTES)}`;
|
|
|
14747
14707
|
});
|
|
14748
14708
|
|
|
14749
14709
|
// src/scripts/kodyVariables.ts
|
|
14750
|
-
import * as
|
|
14751
|
-
import * as
|
|
14710
|
+
import * as fs39 from "fs";
|
|
14711
|
+
import * as path36 from "path";
|
|
14752
14712
|
function readKodyVariables(cwd) {
|
|
14753
|
-
const full =
|
|
14713
|
+
const full = path36.join(cwd, KODY_VARIABLES_REL_PATH);
|
|
14754
14714
|
let raw;
|
|
14755
14715
|
try {
|
|
14756
|
-
raw =
|
|
14716
|
+
raw = fs39.readFileSync(full, "utf-8");
|
|
14757
14717
|
} catch {
|
|
14758
14718
|
return {};
|
|
14759
14719
|
}
|
|
@@ -14929,8 +14889,8 @@ var init_runtimeSecrets = __esm({
|
|
|
14929
14889
|
});
|
|
14930
14890
|
|
|
14931
14891
|
// src/scripts/loadQaContext.ts
|
|
14932
|
-
import * as
|
|
14933
|
-
import * as
|
|
14892
|
+
import * as fs40 from "fs";
|
|
14893
|
+
import * as path37 from "path";
|
|
14934
14894
|
function parseSlugList(value) {
|
|
14935
14895
|
const inner = value.startsWith("[") && value.endsWith("]") ? value.slice(1, -1) : value;
|
|
14936
14896
|
return inner.split(",").map(
|
|
@@ -14959,18 +14919,18 @@ function readProfileAgents(raw) {
|
|
|
14959
14919
|
return { agent: agent ?? legacy ?? ["kody"], body };
|
|
14960
14920
|
}
|
|
14961
14921
|
function readProfile(cwd) {
|
|
14962
|
-
const dir =
|
|
14963
|
-
if (!
|
|
14922
|
+
const dir = path37.join(cwd, CONTEXT_DIR_REL_PATH);
|
|
14923
|
+
if (!fs40.existsSync(dir)) return "";
|
|
14964
14924
|
let entries;
|
|
14965
14925
|
try {
|
|
14966
|
-
entries =
|
|
14926
|
+
entries = fs40.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
|
|
14967
14927
|
} catch {
|
|
14968
14928
|
return "";
|
|
14969
14929
|
}
|
|
14970
14930
|
const blocks = [];
|
|
14971
14931
|
for (const file of entries) {
|
|
14972
14932
|
try {
|
|
14973
|
-
const raw =
|
|
14933
|
+
const raw = fs40.readFileSync(path37.join(dir, file), "utf-8");
|
|
14974
14934
|
const { agent, body } = readProfileAgents(raw);
|
|
14975
14935
|
if (!agent.includes(QA_AGENT) && !agent.includes(ALL_AGENTS)) continue;
|
|
14976
14936
|
blocks.push(`## ${file}
|
|
@@ -15019,8 +14979,8 @@ var init_loadQaContext = __esm({
|
|
|
15019
14979
|
});
|
|
15020
14980
|
|
|
15021
14981
|
// src/taskContext.ts
|
|
15022
|
-
import * as
|
|
15023
|
-
import * as
|
|
14982
|
+
import * as fs41 from "fs";
|
|
14983
|
+
import * as path38 from "path";
|
|
15024
14984
|
function buildTaskContext(args) {
|
|
15025
14985
|
return {
|
|
15026
14986
|
schemaVersion: TASK_CONTEXT_SCHEMA_VERSION,
|
|
@@ -15036,9 +14996,9 @@ function buildTaskContext(args) {
|
|
|
15036
14996
|
function persistTaskContext(cwd, ctx) {
|
|
15037
14997
|
try {
|
|
15038
14998
|
const dir = runtimeStatePath(cwd, "agent-runs", ctx.runId);
|
|
15039
|
-
|
|
15040
|
-
const file =
|
|
15041
|
-
|
|
14999
|
+
fs41.mkdirSync(dir, { recursive: true });
|
|
15000
|
+
const file = path38.join(dir, "task-context.json");
|
|
15001
|
+
fs41.writeFileSync(file, `${JSON.stringify(ctx, null, 2)}
|
|
15042
15002
|
`);
|
|
15043
15003
|
return file;
|
|
15044
15004
|
} catch (err) {
|
|
@@ -15465,19 +15425,19 @@ function parseAgencyModelProposal(raw) {
|
|
|
15465
15425
|
function normalizeBundleFiles(bundle) {
|
|
15466
15426
|
const seen = /* @__PURE__ */ new Set();
|
|
15467
15427
|
return bundle.files.map((file, index) => {
|
|
15468
|
-
const
|
|
15469
|
-
const parts =
|
|
15470
|
-
if (!
|
|
15428
|
+
const path52 = file.path.replace(/^\/+/, "");
|
|
15429
|
+
const parts = path52.split("/");
|
|
15430
|
+
if (!path52 || file.path.startsWith("/") || file.path.includes("\\") || parts.some((part) => !part || part === "." || part === "..")) {
|
|
15471
15431
|
throw new Error(`openAgencyModelReviewPr: files[${index}].path is unsafe`);
|
|
15472
15432
|
}
|
|
15473
15433
|
if (!/^(agents\/[^/]+\.md|capabilities\/[^/]+\/.+|goals\/(?:templates\/)?[^/]+\/.+|workflows\/[^/]+\.json)$/.test(
|
|
15474
|
-
|
|
15434
|
+
path52
|
|
15475
15435
|
)) {
|
|
15476
15436
|
throw new Error(`openAgencyModelReviewPr: files[${index}].path is not a supported definition path`);
|
|
15477
15437
|
}
|
|
15478
|
-
if (seen.has(
|
|
15479
|
-
seen.add(
|
|
15480
|
-
return { path:
|
|
15438
|
+
if (seen.has(path52)) throw new Error(`openAgencyModelReviewPr: duplicate generated file path: ${path52}`);
|
|
15439
|
+
seen.add(path52);
|
|
15440
|
+
return { path: path52, content: file.content.replace(/\r\n?/g, "\n") };
|
|
15481
15441
|
});
|
|
15482
15442
|
}
|
|
15483
15443
|
function buildProposalId(issueNumber, bundle, sourceLabel) {
|
|
@@ -16421,9 +16381,9 @@ var init_postResearchComment = __esm({
|
|
|
16421
16381
|
});
|
|
16422
16382
|
|
|
16423
16383
|
// src/scripts/prepareBrowserAuth.ts
|
|
16424
|
-
import * as
|
|
16384
|
+
import * as fs42 from "fs";
|
|
16425
16385
|
import * as os6 from "os";
|
|
16426
|
-
import * as
|
|
16386
|
+
import * as path39 from "path";
|
|
16427
16387
|
function appendAuthMessage(ctx, message) {
|
|
16428
16388
|
const current = typeof ctx.data.qaAuthBlock === "string" ? ctx.data.qaAuthBlock.trim() : "";
|
|
16429
16389
|
ctx.data.qaAuthBlock = current ? `${current}
|
|
@@ -16462,9 +16422,9 @@ async function githubJson(url, token) {
|
|
|
16462
16422
|
return await response.json();
|
|
16463
16423
|
}
|
|
16464
16424
|
function writeKodyStorageState(input) {
|
|
16465
|
-
const directory =
|
|
16466
|
-
|
|
16467
|
-
const file =
|
|
16425
|
+
const directory = fs42.mkdtempSync(path39.join(os6.tmpdir(), "kody-browser-auth-"));
|
|
16426
|
+
fs42.chmodSync(directory, 448);
|
|
16427
|
+
const file = path39.join(directory, "storage-state.json");
|
|
16468
16428
|
const now = Date.now();
|
|
16469
16429
|
const repoEntry = {
|
|
16470
16430
|
repoUrl: input.repoUrl,
|
|
@@ -16494,7 +16454,7 @@ function writeKodyStorageState(input) {
|
|
|
16494
16454
|
}
|
|
16495
16455
|
]
|
|
16496
16456
|
};
|
|
16497
|
-
|
|
16457
|
+
fs42.writeFileSync(file, JSON.stringify(storageState), { mode: 384 });
|
|
16498
16458
|
return { directory, file };
|
|
16499
16459
|
}
|
|
16500
16460
|
function configurePlaywright(profile, storageStatePath) {
|
|
@@ -16576,7 +16536,7 @@ async function prepareMethod(ctx, profile, method) {
|
|
|
16576
16536
|
configurePlaywright(profile, state.file);
|
|
16577
16537
|
const authDirectory = state.directory;
|
|
16578
16538
|
registerRuntimeCleanup(ctx, () => {
|
|
16579
|
-
|
|
16539
|
+
fs42.rmSync(authDirectory, { recursive: true, force: true });
|
|
16580
16540
|
});
|
|
16581
16541
|
appendAuthMessage(
|
|
16582
16542
|
ctx,
|
|
@@ -16584,7 +16544,7 @@ async function prepareMethod(ctx, profile, method) {
|
|
|
16584
16544
|
);
|
|
16585
16545
|
return true;
|
|
16586
16546
|
} catch (error) {
|
|
16587
|
-
if (state)
|
|
16547
|
+
if (state) fs42.rmSync(state.directory, { recursive: true, force: true });
|
|
16588
16548
|
const reason = error instanceof Error ? error.message : String(error);
|
|
16589
16549
|
appendAuthMessage(
|
|
16590
16550
|
ctx,
|
|
@@ -16697,9 +16657,9 @@ function latestResult(raw, agentResult) {
|
|
|
16697
16657
|
function recordField4(value) {
|
|
16698
16658
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
16699
16659
|
}
|
|
16700
|
-
function resolveDotted(root,
|
|
16701
|
-
if (!
|
|
16702
|
-
return
|
|
16660
|
+
function resolveDotted(root, path52) {
|
|
16661
|
+
if (!path52) return void 0;
|
|
16662
|
+
return path52.split(".").reduce((value, key) => recordField4(value)?.[key], root);
|
|
16703
16663
|
}
|
|
16704
16664
|
function stringValue4(value) {
|
|
16705
16665
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
@@ -17599,7 +17559,7 @@ var init_previewBuildHelpers = __esm({
|
|
|
17599
17559
|
// src/scripts/previewBuildRun.ts
|
|
17600
17560
|
import { spawn as spawn5 } from "child_process";
|
|
17601
17561
|
async function runCmd(cmd, args, opts = {}) {
|
|
17602
|
-
await new Promise((
|
|
17562
|
+
await new Promise((resolve17, reject) => {
|
|
17603
17563
|
const child = spawn5(cmd, args, {
|
|
17604
17564
|
cwd: opts.cwd,
|
|
17605
17565
|
env: { ...process.env, ...opts.env ?? {} },
|
|
@@ -17611,7 +17571,7 @@ async function runCmd(cmd, args, opts = {}) {
|
|
|
17611
17571
|
}
|
|
17612
17572
|
child.on("error", reject);
|
|
17613
17573
|
child.on("close", (code) => {
|
|
17614
|
-
if (code === 0)
|
|
17574
|
+
if (code === 0) resolve17();
|
|
17615
17575
|
else reject(new Error(`${cmd} ${args.join(" ")} exited ${code}`));
|
|
17616
17576
|
});
|
|
17617
17577
|
});
|
|
@@ -17683,12 +17643,12 @@ fi
|
|
|
17683
17643
|
|
|
17684
17644
|
// src/scripts/runPreviewBuild.ts
|
|
17685
17645
|
import { copyFile, writeFile } from "fs/promises";
|
|
17686
|
-
import * as
|
|
17687
|
-
import { fileURLToPath } from "url";
|
|
17646
|
+
import * as path40 from "path";
|
|
17647
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
17688
17648
|
function bundledDockerfilePath(mode) {
|
|
17689
|
-
const here =
|
|
17649
|
+
const here = path40.dirname(fileURLToPath2(import.meta.url));
|
|
17690
17650
|
const file = mode === "dev" ? "default-Dockerfile.preview.dev" : "default-Dockerfile.preview.prod";
|
|
17691
|
-
return
|
|
17651
|
+
return path40.join(here, "preview-build-templates", file);
|
|
17692
17652
|
}
|
|
17693
17653
|
function required(name) {
|
|
17694
17654
|
const v = (process.env[name] ?? "").trim();
|
|
@@ -17923,10 +17883,10 @@ var init_runPreviewBuild = __esm({
|
|
|
17923
17883
|
console.log(`[preview-build] vault: ${Object.keys(buildEnv).length} secrets, mode=${buildMode}`);
|
|
17924
17884
|
if (Object.keys(buildEnv).length > 0) {
|
|
17925
17885
|
const lines = Object.entries(buildEnv).map(([k, v]) => `${k}=${JSON.stringify(v)}`);
|
|
17926
|
-
await writeFile(
|
|
17886
|
+
await writeFile(path40.join(ctx.cwd, ".env.production.local"), `${lines.join("\n")}
|
|
17927
17887
|
`, "utf8");
|
|
17928
17888
|
}
|
|
17929
|
-
const consumerDockerfile =
|
|
17889
|
+
const consumerDockerfile = path40.join(ctx.cwd, "Dockerfile.preview");
|
|
17930
17890
|
const { stat } = await import("fs/promises");
|
|
17931
17891
|
let hasConsumerDockerfile = false;
|
|
17932
17892
|
try {
|
|
@@ -18110,8 +18070,8 @@ var init_tickShellRunner = __esm({
|
|
|
18110
18070
|
});
|
|
18111
18071
|
|
|
18112
18072
|
// src/scripts/runScheduledImplementationTick.ts
|
|
18113
|
-
import * as
|
|
18114
|
-
import * as
|
|
18073
|
+
import * as fs43 from "fs";
|
|
18074
|
+
import * as path41 from "path";
|
|
18115
18075
|
var runScheduledImplementationTick;
|
|
18116
18076
|
var init_runScheduledImplementationTick = __esm({
|
|
18117
18077
|
"src/scripts/runScheduledImplementationTick.ts"() {
|
|
@@ -18132,14 +18092,14 @@ var init_runScheduledImplementationTick = __esm({
|
|
|
18132
18092
|
ctx.output.reason = `runScheduledImplementationTick: args.slug or ctx.args.${slugArg} must be non-empty capability slug`;
|
|
18133
18093
|
return;
|
|
18134
18094
|
}
|
|
18135
|
-
const capability = resolveCapabilityFolder(slug,
|
|
18095
|
+
const capability = resolveCapabilityFolder(slug, path41.resolve(ctx.cwd, jobsDir));
|
|
18136
18096
|
if (!capability) {
|
|
18137
18097
|
ctx.output.exitCode = 99;
|
|
18138
18098
|
ctx.output.reason = `runScheduledImplementationTick: capability folder not found or incomplete: ${slug} (searched ${jobsDir} and company store)`;
|
|
18139
18099
|
return;
|
|
18140
18100
|
}
|
|
18141
|
-
const shellPath =
|
|
18142
|
-
if (!
|
|
18101
|
+
const shellPath = path41.join(profile.dir, shell);
|
|
18102
|
+
if (!fs43.existsSync(shellPath)) {
|
|
18143
18103
|
ctx.output.exitCode = 99;
|
|
18144
18104
|
ctx.output.reason = `runScheduledImplementationTick: shell not found: ${shell} (looked in ${profile.dir})`;
|
|
18145
18105
|
return;
|
|
@@ -18170,8 +18130,8 @@ var init_runScheduledImplementationTick = __esm({
|
|
|
18170
18130
|
});
|
|
18171
18131
|
|
|
18172
18132
|
// src/scripts/runTickScript.ts
|
|
18173
|
-
import * as
|
|
18174
|
-
import * as
|
|
18133
|
+
import * as fs44 from "fs";
|
|
18134
|
+
import * as path42 from "path";
|
|
18175
18135
|
var runTickScript;
|
|
18176
18136
|
var init_runTickScript = __esm({
|
|
18177
18137
|
"src/scripts/runTickScript.ts"() {
|
|
@@ -18191,10 +18151,10 @@ var init_runTickScript = __esm({
|
|
|
18191
18151
|
ctx.output.reason = `runTickScript: ctx.args.${slugArg} must be a non-empty slug`;
|
|
18192
18152
|
return;
|
|
18193
18153
|
}
|
|
18194
|
-
const capability = readCapabilityFolder(
|
|
18154
|
+
const capability = readCapabilityFolder(path42.resolve(ctx.cwd, jobsDir), slug);
|
|
18195
18155
|
if (!capability) {
|
|
18196
18156
|
ctx.output.exitCode = 99;
|
|
18197
|
-
ctx.output.reason = `runTickScript: capability folder not found or incomplete: ${
|
|
18157
|
+
ctx.output.reason = `runTickScript: capability folder not found or incomplete: ${path42.resolve(ctx.cwd, jobsDir, slug)}`;
|
|
18198
18158
|
return;
|
|
18199
18159
|
}
|
|
18200
18160
|
const tickScript = capability.config.tickScript;
|
|
@@ -18203,8 +18163,8 @@ var init_runTickScript = __esm({
|
|
|
18203
18163
|
ctx.output.reason = `runTickScript: capability ${slug} has no \`tickScript\` in profile.json \u2014 route via capability-tick instead`;
|
|
18204
18164
|
return;
|
|
18205
18165
|
}
|
|
18206
|
-
const scriptPath =
|
|
18207
|
-
if (!
|
|
18166
|
+
const scriptPath = path42.isAbsolute(tickScript) ? tickScript : path42.join(ctx.cwd, tickScript);
|
|
18167
|
+
if (!fs44.existsSync(scriptPath)) {
|
|
18208
18168
|
ctx.output.exitCode = 99;
|
|
18209
18169
|
ctx.output.reason = `runTickScript: tickScript not found: ${scriptPath}`;
|
|
18210
18170
|
return;
|
|
@@ -18486,7 +18446,7 @@ var init_syncFlow = __esm({
|
|
|
18486
18446
|
});
|
|
18487
18447
|
|
|
18488
18448
|
// src/scripts/validateAgencyModelProposal.ts
|
|
18489
|
-
import * as
|
|
18449
|
+
import * as path43 from "path";
|
|
18490
18450
|
function validateModelBundle(bundle, expectedKind, options = {}) {
|
|
18491
18451
|
const failures = [];
|
|
18492
18452
|
validateOneModel(bundle.model, bundle.files, "model", true, failures, expectedKind, options);
|
|
@@ -18812,7 +18772,7 @@ var init_validateAgencyModelProposal = __esm({
|
|
|
18812
18772
|
const bundle = parseAgencyModelProposal(raw);
|
|
18813
18773
|
const expectedKind = readExpectedModelKind(args);
|
|
18814
18774
|
const failures = validateModelBundle(bundle, expectedKind, {
|
|
18815
|
-
capabilityRoot:
|
|
18775
|
+
capabilityRoot: path43.join(ctx.cwd, ".kody", "capabilities")
|
|
18816
18776
|
});
|
|
18817
18777
|
if (failures.length > 0) {
|
|
18818
18778
|
throw new Error(`validateAgencyModelProposal: ${failures.join("; ")}`);
|
|
@@ -18875,7 +18835,7 @@ function stripAnsi2(s) {
|
|
|
18875
18835
|
return s.replace(ANSI_RE2, "");
|
|
18876
18836
|
}
|
|
18877
18837
|
function runCommand2(command, cwd) {
|
|
18878
|
-
return new Promise((
|
|
18838
|
+
return new Promise((resolve17) => {
|
|
18879
18839
|
const child = spawn6(command, {
|
|
18880
18840
|
cwd,
|
|
18881
18841
|
shell: true,
|
|
@@ -18902,11 +18862,11 @@ function runCommand2(command, cwd) {
|
|
|
18902
18862
|
}, TEST_TIMEOUT_MS);
|
|
18903
18863
|
child.on("exit", (code) => {
|
|
18904
18864
|
clearTimeout(timer);
|
|
18905
|
-
|
|
18865
|
+
resolve17({ exitCode: code ?? -1, output: Buffer.concat(buffers).toString("utf-8") });
|
|
18906
18866
|
});
|
|
18907
18867
|
child.on("error", (err) => {
|
|
18908
18868
|
clearTimeout(timer);
|
|
18909
|
-
|
|
18869
|
+
resolve17({ exitCode: -1, output: err.message });
|
|
18910
18870
|
});
|
|
18911
18871
|
});
|
|
18912
18872
|
}
|
|
@@ -19312,21 +19272,21 @@ function lineStream(stream) {
|
|
|
19312
19272
|
tryDeliver();
|
|
19313
19273
|
});
|
|
19314
19274
|
return {
|
|
19315
|
-
next: (timeoutMs) => new Promise((
|
|
19275
|
+
next: (timeoutMs) => new Promise((resolve17) => {
|
|
19316
19276
|
if (queue.length > 0) {
|
|
19317
|
-
|
|
19277
|
+
resolve17(queue.shift());
|
|
19318
19278
|
return;
|
|
19319
19279
|
}
|
|
19320
19280
|
if (ended) {
|
|
19321
|
-
|
|
19281
|
+
resolve17(null);
|
|
19322
19282
|
return;
|
|
19323
19283
|
}
|
|
19324
|
-
waiter =
|
|
19284
|
+
waiter = resolve17;
|
|
19325
19285
|
const t = setTimeout(
|
|
19326
19286
|
() => {
|
|
19327
|
-
if (waiter ===
|
|
19287
|
+
if (waiter === resolve17) {
|
|
19328
19288
|
waiter = null;
|
|
19329
|
-
|
|
19289
|
+
resolve17(null);
|
|
19330
19290
|
}
|
|
19331
19291
|
},
|
|
19332
19292
|
Math.max(0, timeoutMs)
|
|
@@ -19363,7 +19323,7 @@ var init_warmupMcp = __esm({
|
|
|
19363
19323
|
});
|
|
19364
19324
|
|
|
19365
19325
|
// src/scripts/writeAgentRunSummary.ts
|
|
19366
|
-
import * as
|
|
19326
|
+
import * as fs45 from "fs";
|
|
19367
19327
|
var writeAgentRunSummary;
|
|
19368
19328
|
var init_writeAgentRunSummary = __esm({
|
|
19369
19329
|
"src/scripts/writeAgentRunSummary.ts"() {
|
|
@@ -19389,7 +19349,7 @@ var init_writeAgentRunSummary = __esm({
|
|
|
19389
19349
|
if (reason) lines.push(`- **Reason:** ${reason}`);
|
|
19390
19350
|
lines.push("");
|
|
19391
19351
|
try {
|
|
19392
|
-
|
|
19352
|
+
fs45.appendFileSync(summaryPath, `${lines.join("\n")}
|
|
19393
19353
|
`);
|
|
19394
19354
|
} catch {
|
|
19395
19355
|
}
|
|
@@ -19715,17 +19675,17 @@ var init_scripts = __esm({
|
|
|
19715
19675
|
});
|
|
19716
19676
|
|
|
19717
19677
|
// src/stateWorkspace.ts
|
|
19718
|
-
import * as
|
|
19719
|
-
import * as
|
|
19678
|
+
import * as fs46 from "fs";
|
|
19679
|
+
import * as path44 from "path";
|
|
19720
19680
|
function tenantId(config) {
|
|
19721
19681
|
const owner = config.github?.owner?.trim() || process.env.GITHUB_REPOSITORY?.split("/")[0]?.trim();
|
|
19722
19682
|
const repo = config.github?.repo?.trim() || process.env.GITHUB_REPOSITORY?.split("/")[1]?.trim();
|
|
19723
19683
|
return owner && repo ? `${owner}/${repo}` : null;
|
|
19724
19684
|
}
|
|
19725
19685
|
function writeRuntimeFile(cwd, relativePath, content) {
|
|
19726
|
-
const target =
|
|
19727
|
-
|
|
19728
|
-
|
|
19686
|
+
const target = path44.join(cwd, RUNTIME_ROOT, relativePath);
|
|
19687
|
+
fs46.mkdirSync(path44.dirname(target), { recursive: true });
|
|
19688
|
+
fs46.writeFileSync(target, content, "utf8");
|
|
19729
19689
|
}
|
|
19730
19690
|
function record(value) {
|
|
19731
19691
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
@@ -19790,11 +19750,11 @@ async function hydrateStateWorkspace(config, cwd, backendOverride) {
|
|
|
19790
19750
|
throw new Error("Kody backend access is required for runtime workspace documents");
|
|
19791
19751
|
return;
|
|
19792
19752
|
}
|
|
19793
|
-
const key = `${
|
|
19753
|
+
const key = `${path44.resolve(cwd)}|${tenant}`;
|
|
19794
19754
|
if (hydratedWorkspaces.has(key)) return;
|
|
19795
19755
|
const backend = backendOverride ?? createStateBackendFromEnv();
|
|
19796
|
-
const root =
|
|
19797
|
-
|
|
19756
|
+
const root = path44.join(cwd, RUNTIME_ROOT);
|
|
19757
|
+
fs46.rmSync(root, { recursive: true, force: true });
|
|
19798
19758
|
await Promise.all([
|
|
19799
19759
|
hydratePrefix(backend, tenant, cwd, "context:"),
|
|
19800
19760
|
hydratePrefix(backend, tenant, cwd, "memory:"),
|
|
@@ -19810,7 +19770,7 @@ var init_stateWorkspace = __esm({
|
|
|
19810
19770
|
"src/stateWorkspace.ts"() {
|
|
19811
19771
|
"use strict";
|
|
19812
19772
|
init_state_backend();
|
|
19813
|
-
RUNTIME_ROOT =
|
|
19773
|
+
RUNTIME_ROOT = path44.join(".kody-engine", "runtime");
|
|
19814
19774
|
hydratedWorkspaces = /* @__PURE__ */ new Set();
|
|
19815
19775
|
}
|
|
19816
19776
|
});
|
|
@@ -19881,9 +19841,9 @@ var init_tools = __esm({
|
|
|
19881
19841
|
|
|
19882
19842
|
// src/executor.ts
|
|
19883
19843
|
import { spawn as spawn8 } from "child_process";
|
|
19884
|
-
import * as
|
|
19844
|
+
import * as fs47 from "fs";
|
|
19885
19845
|
import * as os7 from "os";
|
|
19886
|
-
import * as
|
|
19846
|
+
import * as path45 from "path";
|
|
19887
19847
|
function isMutatingPostflight(scriptName) {
|
|
19888
19848
|
return MUTATING_POSTFLIGHTS.has(scriptName ?? "");
|
|
19889
19849
|
}
|
|
@@ -20115,7 +20075,7 @@ async function runImplementation(profileName, input) {
|
|
|
20115
20075
|
const jobWhyBlock = typeof ctx.data.jobWhy === "string" ? operatorRequestBlock(ctx.data.jobWhy) : null;
|
|
20116
20076
|
const jobRefBlock = jobReferenceBlock(profileName, profile, ctx.data);
|
|
20117
20077
|
const invokeAgent = async (prompt) => {
|
|
20118
|
-
const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) =>
|
|
20078
|
+
const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) => path45.isAbsolute(p) ? p : path45.resolve(profile.dir, p)).filter((p) => p.length > 0);
|
|
20119
20079
|
const syntheticPath = ctx.data.syntheticPluginPath;
|
|
20120
20080
|
const pluginPaths = [...externalPlugins, ...syntheticPath ? [syntheticPath] : []];
|
|
20121
20081
|
const agents = loadSubagents(profile);
|
|
@@ -20553,17 +20513,17 @@ function clearStampedLifecycleLabels(profile, ctx) {
|
|
|
20553
20513
|
function resolveProfilePath(profileName) {
|
|
20554
20514
|
const found = resolveImplementation(profileName);
|
|
20555
20515
|
if (found) return found;
|
|
20556
|
-
const here =
|
|
20516
|
+
const here = path45.dirname(new URL(import.meta.url).pathname);
|
|
20557
20517
|
const candidates = [
|
|
20558
|
-
|
|
20518
|
+
path45.join(here, "implementations", profileName, "profile.json"),
|
|
20559
20519
|
// same-dir sibling (dev)
|
|
20560
|
-
|
|
20520
|
+
path45.join(here, "..", "implementations", profileName, "profile.json"),
|
|
20561
20521
|
// up one (prod: dist/bin → dist/implementations)
|
|
20562
|
-
|
|
20522
|
+
path45.join(here, "..", "src", "implementations", profileName, "profile.json")
|
|
20563
20523
|
// fallback
|
|
20564
20524
|
];
|
|
20565
20525
|
for (const c of candidates) {
|
|
20566
|
-
if (
|
|
20526
|
+
if (fs47.existsSync(c)) return c;
|
|
20567
20527
|
}
|
|
20568
20528
|
return candidates[0];
|
|
20569
20529
|
}
|
|
@@ -20678,15 +20638,15 @@ function resolveShellTimeoutMs(entry) {
|
|
|
20678
20638
|
}
|
|
20679
20639
|
async function runShellEntry(entry, ctx, profile) {
|
|
20680
20640
|
const shellName = entry.shell;
|
|
20681
|
-
const shellPath =
|
|
20682
|
-
if (!
|
|
20641
|
+
const shellPath = path45.join(profile.dir, shellName);
|
|
20642
|
+
if (!fs47.existsSync(shellPath)) {
|
|
20683
20643
|
ctx.skipAgent = true;
|
|
20684
20644
|
ctx.output.exitCode = 99;
|
|
20685
20645
|
ctx.output.reason = `shell script not found: ${shellName} (looked in ${profile.dir})`;
|
|
20686
20646
|
return;
|
|
20687
20647
|
}
|
|
20688
20648
|
const positional = entry.with ? Object.values(entry.with).map((v) => String(v)) : [];
|
|
20689
|
-
const outputFile =
|
|
20649
|
+
const outputFile = path45.join(
|
|
20690
20650
|
os7.tmpdir(),
|
|
20691
20651
|
`kody-shell-output-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`
|
|
20692
20652
|
);
|
|
@@ -20721,14 +20681,14 @@ async function runShellEntry(entry, ctx, profile) {
|
|
|
20721
20681
|
let killTimer;
|
|
20722
20682
|
let escalateTimer;
|
|
20723
20683
|
const result = await new Promise(
|
|
20724
|
-
(
|
|
20684
|
+
(resolve17) => {
|
|
20725
20685
|
let settled = false;
|
|
20726
20686
|
const settle = (code, signal, spawnErr) => {
|
|
20727
20687
|
if (settled) return;
|
|
20728
20688
|
settled = true;
|
|
20729
20689
|
if (killTimer) clearTimeout(killTimer);
|
|
20730
20690
|
if (escalateTimer) clearTimeout(escalateTimer);
|
|
20731
|
-
|
|
20691
|
+
resolve17({ code, signal, spawnErr });
|
|
20732
20692
|
};
|
|
20733
20693
|
child.on("error", (err) => settle(null, null, err));
|
|
20734
20694
|
child.on("close", (code, signal) => settle(code, signal));
|
|
@@ -20758,9 +20718,9 @@ async function runShellEntry(entry, ctx, profile) {
|
|
|
20758
20718
|
}
|
|
20759
20719
|
let sideChannelText = "";
|
|
20760
20720
|
try {
|
|
20761
|
-
if (
|
|
20762
|
-
sideChannelText =
|
|
20763
|
-
|
|
20721
|
+
if (fs47.existsSync(outputFile)) {
|
|
20722
|
+
sideChannelText = fs47.readFileSync(outputFile, "utf-8");
|
|
20723
|
+
fs47.rmSync(outputFile, { force: true });
|
|
20764
20724
|
}
|
|
20765
20725
|
} catch {
|
|
20766
20726
|
}
|
|
@@ -20931,7 +20891,7 @@ __export(job_exports, {
|
|
|
20931
20891
|
stableJobKey: () => stableJobKey,
|
|
20932
20892
|
validateJob: () => validateJob
|
|
20933
20893
|
});
|
|
20934
|
-
import * as
|
|
20894
|
+
import * as path46 from "path";
|
|
20935
20895
|
function newJobId(flavor) {
|
|
20936
20896
|
localJobSeq += 1;
|
|
20937
20897
|
const runId = process.env.GITHUB_RUN_ID;
|
|
@@ -21394,11 +21354,11 @@ function selectWorkflowTransition(step, data, counts) {
|
|
|
21394
21354
|
}
|
|
21395
21355
|
function workflowResultConditionPaths(transitions) {
|
|
21396
21356
|
return transitions.flatMap(
|
|
21397
|
-
(transition) => Object.keys(transition.when ?? {}).filter((
|
|
21357
|
+
(transition) => Object.keys(transition.when ?? {}).filter((path52) => path52.startsWith("result."))
|
|
21398
21358
|
);
|
|
21399
21359
|
}
|
|
21400
21360
|
function conditionMatches(condition, context) {
|
|
21401
|
-
return Object.entries(condition).every(([
|
|
21361
|
+
return Object.entries(condition).every(([path52, expected]) => valueMatches(resolveDottedPath2(context, path52), expected));
|
|
21402
21362
|
}
|
|
21403
21363
|
function withWorkflowBoundaryEval(capability, result) {
|
|
21404
21364
|
const capabilityKind = capability.config.capabilityKind;
|
|
@@ -21556,7 +21516,7 @@ function loadCapabilityContext(slug, cwd) {
|
|
|
21556
21516
|
return resolveCapabilityFolder(slug, hydratedCapabilitiesRoot(cwd));
|
|
21557
21517
|
}
|
|
21558
21518
|
function hydratedCapabilitiesRoot(cwd) {
|
|
21559
|
-
return
|
|
21519
|
+
return path46.join(cwd, ".kody-engine", "definitions", "capabilities");
|
|
21560
21520
|
}
|
|
21561
21521
|
function loadWorkflowContext(slug, base) {
|
|
21562
21522
|
if (!slug || !base.config || !isWorkflowDefinitionId(slug)) return null;
|
|
@@ -21719,7 +21679,7 @@ function translateOpenAISseToBrain(opts) {
|
|
|
21719
21679
|
|
|
21720
21680
|
// src/servers/brain-serve.ts
|
|
21721
21681
|
import { createServer as createServer2 } from "http";
|
|
21722
|
-
import * as
|
|
21682
|
+
import * as path49 from "path";
|
|
21723
21683
|
|
|
21724
21684
|
// src/chat/loop.ts
|
|
21725
21685
|
init_agent();
|
|
@@ -21873,9 +21833,9 @@ var CodexAppServerClient = class {
|
|
|
21873
21833
|
await this.request("thread/resume", { threadId });
|
|
21874
21834
|
}
|
|
21875
21835
|
async runTurn(args) {
|
|
21876
|
-
await new Promise((
|
|
21836
|
+
await new Promise((resolve17, reject) => {
|
|
21877
21837
|
this.process.turnWaiters.set(args.threadId, {
|
|
21878
|
-
resolve:
|
|
21838
|
+
resolve: resolve17,
|
|
21879
21839
|
reject,
|
|
21880
21840
|
onNotification: args.onNotification,
|
|
21881
21841
|
queue: Promise.resolve()
|
|
@@ -21892,8 +21852,8 @@ var CodexAppServerClient = class {
|
|
|
21892
21852
|
}
|
|
21893
21853
|
request(method, params) {
|
|
21894
21854
|
const id = this.process.nextId++;
|
|
21895
|
-
return new Promise((
|
|
21896
|
-
this.process.pending.set(id, { resolve:
|
|
21855
|
+
return new Promise((resolve17, reject) => {
|
|
21856
|
+
this.process.pending.set(id, { resolve: resolve17, reject });
|
|
21897
21857
|
this.process.child.stdin.write(`${JSON.stringify({ method, id, params })}
|
|
21898
21858
|
`);
|
|
21899
21859
|
});
|
|
@@ -22761,8 +22721,8 @@ init_config();
|
|
|
22761
22721
|
|
|
22762
22722
|
// src/kody-cli.ts
|
|
22763
22723
|
import { execFileSync as execFileSync24 } from "child_process";
|
|
22764
|
-
import * as
|
|
22765
|
-
import * as
|
|
22724
|
+
import * as fs48 from "fs";
|
|
22725
|
+
import * as path47 from "path";
|
|
22766
22726
|
|
|
22767
22727
|
// src/app-auth.ts
|
|
22768
22728
|
import { createSign } from "crypto";
|
|
@@ -23530,6 +23490,20 @@ function recoverCheckoutToken(env = process.env, cwd = process.cwd()) {
|
|
|
23530
23490
|
return token;
|
|
23531
23491
|
}
|
|
23532
23492
|
async function resolveAuthToken(env = process.env) {
|
|
23493
|
+
const readySources = [
|
|
23494
|
+
["GH_PAT", env.GH_PAT],
|
|
23495
|
+
["KODY_TOKEN", env.KODY_TOKEN],
|
|
23496
|
+
["GH_TOKEN", env.GH_TOKEN]
|
|
23497
|
+
];
|
|
23498
|
+
const ready = readySources.find(([, value]) => !!value?.trim());
|
|
23499
|
+
if (ready?.[1]) {
|
|
23500
|
+
const token2 = ready[1].trim();
|
|
23501
|
+
env.GH_TOKEN = token2;
|
|
23502
|
+
recoverCheckoutToken(env);
|
|
23503
|
+
process.stdout.write(`\u2192 kody: GH_TOKEN sourced from env.${ready[0]}
|
|
23504
|
+
`);
|
|
23505
|
+
return token2;
|
|
23506
|
+
}
|
|
23533
23507
|
const creds = readAppCreds(env);
|
|
23534
23508
|
if (creds) {
|
|
23535
23509
|
try {
|
|
@@ -23543,12 +23517,7 @@ async function resolveAuthToken(env = process.env) {
|
|
|
23543
23517
|
`);
|
|
23544
23518
|
}
|
|
23545
23519
|
}
|
|
23546
|
-
const sources = [
|
|
23547
|
-
["KODY_TOKEN", env.KODY_TOKEN],
|
|
23548
|
-
["GH_TOKEN", env.GH_TOKEN],
|
|
23549
|
-
["GITHUB_TOKEN", env.GITHUB_TOKEN],
|
|
23550
|
-
["GH_PAT", env.GH_PAT]
|
|
23551
|
-
];
|
|
23520
|
+
const sources = [["GITHUB_TOKEN", env.GITHUB_TOKEN]];
|
|
23552
23521
|
const picked = sources.find(([, v]) => !!v);
|
|
23553
23522
|
const token = picked?.[1];
|
|
23554
23523
|
if (token && !env.GH_TOKEN) env.GH_TOKEN = token;
|
|
@@ -23564,9 +23533,9 @@ async function resolveAuthToken(env = process.env) {
|
|
|
23564
23533
|
return void 0;
|
|
23565
23534
|
}
|
|
23566
23535
|
function detectPackageManager2(cwd) {
|
|
23567
|
-
if (
|
|
23568
|
-
if (
|
|
23569
|
-
if (
|
|
23536
|
+
if (fs48.existsSync(path47.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
23537
|
+
if (fs48.existsSync(path47.join(cwd, "yarn.lock"))) return "yarn";
|
|
23538
|
+
if (fs48.existsSync(path47.join(cwd, "bun.lockb"))) return "bun";
|
|
23570
23539
|
return "npm";
|
|
23571
23540
|
}
|
|
23572
23541
|
function shouldChainScheduledWatch(match) {
|
|
@@ -23659,8 +23628,8 @@ function postFailureTail(issueNumber, cwd, reason) {
|
|
|
23659
23628
|
const logPath = lastRunLogPath(cwd);
|
|
23660
23629
|
let tail = "";
|
|
23661
23630
|
try {
|
|
23662
|
-
if (
|
|
23663
|
-
const content =
|
|
23631
|
+
if (fs48.existsSync(logPath)) {
|
|
23632
|
+
const content = fs48.readFileSync(logPath, "utf-8");
|
|
23664
23633
|
tail = content.slice(-3e3);
|
|
23665
23634
|
}
|
|
23666
23635
|
} catch {
|
|
@@ -23689,7 +23658,7 @@ async function runCi(argv) {
|
|
|
23689
23658
|
return 0;
|
|
23690
23659
|
}
|
|
23691
23660
|
const args = parseCiArgs(argv);
|
|
23692
|
-
const cwd = args.cwd ?
|
|
23661
|
+
const cwd = args.cwd ? path47.resolve(args.cwd) : process.cwd();
|
|
23693
23662
|
try {
|
|
23694
23663
|
const n = unpackAllSecrets();
|
|
23695
23664
|
if (n > 0) process.stdout.write(`\u2192 kody: unpacked ${n} secret(s) from ALL_SECRETS
|
|
@@ -23748,9 +23717,9 @@ async function runCi(argv) {
|
|
|
23748
23717
|
forceRunCliArgs = { goal: envForceMessage };
|
|
23749
23718
|
}
|
|
23750
23719
|
}
|
|
23751
|
-
if (!args.issueNumber && !autoFallback && !forceRunAction && !runRequestFanOut && eventName === "workflow_dispatch" && dispatchEventPath &&
|
|
23720
|
+
if (!args.issueNumber && !autoFallback && !forceRunAction && !runRequestFanOut && eventName === "workflow_dispatch" && dispatchEventPath && fs48.existsSync(dispatchEventPath)) {
|
|
23752
23721
|
try {
|
|
23753
|
-
const evt = JSON.parse(
|
|
23722
|
+
const evt = JSON.parse(fs48.readFileSync(dispatchEventPath, "utf-8"));
|
|
23754
23723
|
const inputs = objectValue2(evt.inputs);
|
|
23755
23724
|
const issueInput = parseInt(String(inputs?.issue_number ?? ""), 10);
|
|
23756
23725
|
const sessionInput = String(inputs?.sessionId ?? "");
|
|
@@ -24123,8 +24092,8 @@ init_repoWorkspace();
|
|
|
24123
24092
|
|
|
24124
24093
|
// src/scripts/brainTurnLog.ts
|
|
24125
24094
|
init_runtimePaths();
|
|
24126
|
-
import * as
|
|
24127
|
-
import * as
|
|
24095
|
+
import * as fs49 from "fs";
|
|
24096
|
+
import * as path48 from "path";
|
|
24128
24097
|
import posixPath4 from "path/posix";
|
|
24129
24098
|
var live = /* @__PURE__ */ new Map();
|
|
24130
24099
|
function brainEventsFilePath(dir, chatId) {
|
|
@@ -24132,8 +24101,8 @@ function brainEventsFilePath(dir, chatId) {
|
|
|
24132
24101
|
}
|
|
24133
24102
|
function lastPersistedSeq(dir, chatId) {
|
|
24134
24103
|
const p = brainEventsFilePath(dir, chatId);
|
|
24135
|
-
if (!
|
|
24136
|
-
const lines =
|
|
24104
|
+
if (!fs49.existsSync(p)) return 0;
|
|
24105
|
+
const lines = fs49.readFileSync(p, "utf-8").split("\n").filter(Boolean);
|
|
24137
24106
|
if (lines.length === 0) return 0;
|
|
24138
24107
|
try {
|
|
24139
24108
|
return JSON.parse(lines[lines.length - 1]).seq || 0;
|
|
@@ -24143,9 +24112,9 @@ function lastPersistedSeq(dir, chatId) {
|
|
|
24143
24112
|
}
|
|
24144
24113
|
function readSince(dir, chatId, since) {
|
|
24145
24114
|
const p = brainEventsFilePath(dir, chatId);
|
|
24146
|
-
if (!
|
|
24115
|
+
if (!fs49.existsSync(p)) return [];
|
|
24147
24116
|
const out = [];
|
|
24148
|
-
for (const line of
|
|
24117
|
+
for (const line of fs49.readFileSync(p, "utf-8").split("\n")) {
|
|
24149
24118
|
if (!line) continue;
|
|
24150
24119
|
try {
|
|
24151
24120
|
const rec = JSON.parse(line);
|
|
@@ -24171,12 +24140,12 @@ function beginTurn(dir, chatId) {
|
|
|
24171
24140
|
};
|
|
24172
24141
|
live.set(chatId, state);
|
|
24173
24142
|
const p = brainEventsFilePath(dir, chatId);
|
|
24174
|
-
|
|
24143
|
+
fs49.mkdirSync(path48.dirname(p), { recursive: true });
|
|
24175
24144
|
return (event) => {
|
|
24176
24145
|
state.seq += 1;
|
|
24177
24146
|
const rec = { seq: state.seq, turn, ts: Date.now(), event };
|
|
24178
24147
|
try {
|
|
24179
|
-
|
|
24148
|
+
fs49.appendFileSync(p, `${JSON.stringify(rec)}
|
|
24180
24149
|
`);
|
|
24181
24150
|
} catch (err) {
|
|
24182
24151
|
process.stderr.write(
|
|
@@ -24215,7 +24184,7 @@ function endTurnIfUnterminated(dir, chatId, errMessage) {
|
|
|
24215
24184
|
event: { type: "error", error: errMessage || "turn ended unexpectedly", chatId }
|
|
24216
24185
|
};
|
|
24217
24186
|
try {
|
|
24218
|
-
|
|
24187
|
+
fs49.appendFileSync(brainEventsFilePath(dir, chatId), `${JSON.stringify(rec)}
|
|
24219
24188
|
`);
|
|
24220
24189
|
} catch {
|
|
24221
24190
|
}
|
|
@@ -24309,17 +24278,17 @@ function authOk(req, expected) {
|
|
|
24309
24278
|
return false;
|
|
24310
24279
|
}
|
|
24311
24280
|
function readJsonBody(req) {
|
|
24312
|
-
return new Promise((
|
|
24281
|
+
return new Promise((resolve17, reject) => {
|
|
24313
24282
|
const chunks = [];
|
|
24314
24283
|
req.on("data", (c) => chunks.push(c));
|
|
24315
24284
|
req.on("end", () => {
|
|
24316
24285
|
const raw = Buffer.concat(chunks).toString("utf-8");
|
|
24317
24286
|
if (!raw.trim()) {
|
|
24318
|
-
|
|
24287
|
+
resolve17({});
|
|
24319
24288
|
return;
|
|
24320
24289
|
}
|
|
24321
24290
|
try {
|
|
24322
|
-
|
|
24291
|
+
resolve17(JSON.parse(raw));
|
|
24323
24292
|
} catch (err) {
|
|
24324
24293
|
reject(err instanceof Error ? err : new Error(String(err)));
|
|
24325
24294
|
}
|
|
@@ -24578,7 +24547,7 @@ function buildServer(opts) {
|
|
|
24578
24547
|
const runTurn = opts.runTurn ?? runChatTurn;
|
|
24579
24548
|
const createStore = opts.createStore ?? createSessionStore;
|
|
24580
24549
|
const cloneRepo = opts.cloneRepo ?? defaultCloneRepo;
|
|
24581
|
-
const reposRoot = opts.reposRoot ??
|
|
24550
|
+
const reposRoot = opts.reposRoot ?? path49.join(path49.dirname(path49.resolve(opts.cwd)), "repos");
|
|
24582
24551
|
return createServer2(async (req, res) => {
|
|
24583
24552
|
if (!req.method || !req.url) {
|
|
24584
24553
|
sendJson(res, 400, { error: "bad request" });
|
|
@@ -24659,11 +24628,11 @@ async function brainServe(opts) {
|
|
|
24659
24628
|
litellmUrl,
|
|
24660
24629
|
driver
|
|
24661
24630
|
});
|
|
24662
|
-
await new Promise((
|
|
24631
|
+
await new Promise((resolve17) => {
|
|
24663
24632
|
server.listen(port, "0.0.0.0", () => {
|
|
24664
24633
|
process.stdout.write(`[brain-serve] listening on 0.0.0.0:${port} (cwd=${opts.cwd})
|
|
24665
24634
|
`);
|
|
24666
|
-
|
|
24635
|
+
resolve17();
|
|
24667
24636
|
});
|
|
24668
24637
|
});
|
|
24669
24638
|
const shutdown = (signal) => {
|
|
@@ -24918,14 +24887,14 @@ async function startBrainProxy(opts) {
|
|
|
24918
24887
|
const { httpServer, handler } = buildBrainProxy(opts);
|
|
24919
24888
|
const port = opts.port ?? 0;
|
|
24920
24889
|
const host = opts.host ?? "127.0.0.1";
|
|
24921
|
-
await new Promise((
|
|
24890
|
+
await new Promise((resolve17) => httpServer.listen(port, host, () => resolve17()));
|
|
24922
24891
|
const addr = httpServer.address();
|
|
24923
24892
|
return {
|
|
24924
24893
|
httpServer,
|
|
24925
24894
|
port: addr.port,
|
|
24926
24895
|
url: `http://${host}:${addr.port}`,
|
|
24927
|
-
stop: () => new Promise((
|
|
24928
|
-
httpServer.close(() =>
|
|
24896
|
+
stop: () => new Promise((resolve17) => {
|
|
24897
|
+
httpServer.close(() => resolve17());
|
|
24929
24898
|
}),
|
|
24930
24899
|
handler
|
|
24931
24900
|
};
|
|
@@ -25075,23 +25044,23 @@ function buildMcpHttpServer(opts) {
|
|
|
25075
25044
|
httpServer,
|
|
25076
25045
|
routes,
|
|
25077
25046
|
port,
|
|
25078
|
-
stop: () => new Promise((
|
|
25047
|
+
stop: () => new Promise((resolve17) => {
|
|
25079
25048
|
let pending = transports.size;
|
|
25080
25049
|
if (pending === 0) {
|
|
25081
|
-
httpServer.close(() =>
|
|
25050
|
+
httpServer.close(() => resolve17());
|
|
25082
25051
|
return;
|
|
25083
25052
|
}
|
|
25084
25053
|
for (const transport of transports.values()) {
|
|
25085
25054
|
void transport.close().finally(() => {
|
|
25086
25055
|
pending--;
|
|
25087
|
-
if (pending === 0) httpServer.close(() =>
|
|
25056
|
+
if (pending === 0) httpServer.close(() => resolve17());
|
|
25088
25057
|
});
|
|
25089
25058
|
}
|
|
25090
25059
|
})
|
|
25091
25060
|
};
|
|
25092
25061
|
}
|
|
25093
25062
|
function listenMcpHttpServer(server, host = "127.0.0.1") {
|
|
25094
|
-
return new Promise((
|
|
25063
|
+
return new Promise((resolve17, reject) => {
|
|
25095
25064
|
server.httpServer.once("error", reject);
|
|
25096
25065
|
server.httpServer.listen(server.port, host, () => {
|
|
25097
25066
|
server.httpServer.off("error", reject);
|
|
@@ -25099,7 +25068,7 @@ function listenMcpHttpServer(server, host = "127.0.0.1") {
|
|
|
25099
25068
|
if (addr && typeof addr === "object") {
|
|
25100
25069
|
server.port = addr.port;
|
|
25101
25070
|
}
|
|
25102
|
-
|
|
25071
|
+
resolve17();
|
|
25103
25072
|
});
|
|
25104
25073
|
});
|
|
25105
25074
|
}
|
|
@@ -25182,7 +25151,7 @@ async function loadConfigSafe() {
|
|
|
25182
25151
|
}
|
|
25183
25152
|
|
|
25184
25153
|
// src/chat-cli.ts
|
|
25185
|
-
import * as
|
|
25154
|
+
import * as path50 from "path";
|
|
25186
25155
|
|
|
25187
25156
|
// src/chat/inbox.ts
|
|
25188
25157
|
import { execFileSync as execFileSync25 } from "child_process";
|
|
@@ -25249,7 +25218,7 @@ async function waitForNextUserMessage(opts) {
|
|
|
25249
25218
|
}
|
|
25250
25219
|
}
|
|
25251
25220
|
function sleep3(ms) {
|
|
25252
|
-
return new Promise((
|
|
25221
|
+
return new Promise((resolve17) => setTimeout(resolve17, ms));
|
|
25253
25222
|
}
|
|
25254
25223
|
function currentBranch(cwd) {
|
|
25255
25224
|
try {
|
|
@@ -25463,7 +25432,7 @@ async function runChat(argv) {
|
|
|
25463
25432
|
${CHAT_HELP}`);
|
|
25464
25433
|
return 64;
|
|
25465
25434
|
}
|
|
25466
|
-
const cwd = args.cwd ?
|
|
25435
|
+
const cwd = args.cwd ? path50.resolve(args.cwd) : process.cwd();
|
|
25467
25436
|
const sessionId = args.sessionId;
|
|
25468
25437
|
const runRequest = readRunRequestFromEnv();
|
|
25469
25438
|
if (runRequest && "request" in runRequest) {
|
|
@@ -25584,8 +25553,8 @@ init_config();
|
|
|
25584
25553
|
// src/definition-hydration.ts
|
|
25585
25554
|
init_state_backend();
|
|
25586
25555
|
import { createHash as createHash5 } from "crypto";
|
|
25587
|
-
import * as
|
|
25588
|
-
import * as
|
|
25556
|
+
import * as fs50 from "fs";
|
|
25557
|
+
import * as path51 from "path";
|
|
25589
25558
|
var SLUG_RE2 = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
25590
25559
|
function assertSafeDefinitionPath(filePath) {
|
|
25591
25560
|
const segments = filePath.split("/");
|
|
@@ -25619,32 +25588,32 @@ function writeDefinition(root, kind, definition) {
|
|
|
25619
25588
|
if (kind === "agent") {
|
|
25620
25589
|
const raw = bundle.files["agent.md"];
|
|
25621
25590
|
if (typeof raw !== "string") throw new Error(`agent definition ${definition.slug} is missing agent.md`);
|
|
25622
|
-
|
|
25591
|
+
fs50.writeFileSync(path51.join(root, "agents", `${definition.slug}.md`), raw, "utf8");
|
|
25623
25592
|
return;
|
|
25624
25593
|
}
|
|
25625
25594
|
if (kind === "goal") {
|
|
25626
|
-
const goalRoot =
|
|
25595
|
+
const goalRoot = path51.join(root, "goals", definition.slug);
|
|
25627
25596
|
for (const [filePath, contents] of Object.entries(bundle.files)) {
|
|
25628
|
-
const target =
|
|
25629
|
-
|
|
25630
|
-
|
|
25597
|
+
const target = path51.join(goalRoot, filePath);
|
|
25598
|
+
fs50.mkdirSync(path51.dirname(target), { recursive: true });
|
|
25599
|
+
fs50.writeFileSync(target, contents, "utf8");
|
|
25631
25600
|
}
|
|
25632
25601
|
return;
|
|
25633
25602
|
}
|
|
25634
|
-
const capabilityRoot =
|
|
25603
|
+
const capabilityRoot = path51.join(root, "capabilities", definition.slug);
|
|
25635
25604
|
for (const [filePath, contents] of Object.entries(bundle.files)) {
|
|
25636
|
-
const target =
|
|
25637
|
-
|
|
25638
|
-
|
|
25605
|
+
const target = path51.join(capabilityRoot, filePath);
|
|
25606
|
+
fs50.mkdirSync(path51.dirname(target), { recursive: true });
|
|
25607
|
+
fs50.writeFileSync(target, contents, "utf8");
|
|
25639
25608
|
}
|
|
25640
25609
|
}
|
|
25641
25610
|
async function hydrateDefinitions(options) {
|
|
25642
|
-
const root =
|
|
25611
|
+
const root = path51.join(options.cwd, ".kody-engine", "definitions");
|
|
25643
25612
|
const staging = `${root}.tmp-${process.pid}-${Date.now()}`;
|
|
25644
|
-
|
|
25645
|
-
|
|
25646
|
-
|
|
25647
|
-
|
|
25613
|
+
fs50.rmSync(staging, { recursive: true, force: true });
|
|
25614
|
+
fs50.mkdirSync(path51.join(staging, "agents"), { recursive: true });
|
|
25615
|
+
fs50.mkdirSync(path51.join(staging, "capabilities"), { recursive: true });
|
|
25616
|
+
fs50.mkdirSync(path51.join(staging, "goals"), { recursive: true });
|
|
25648
25617
|
try {
|
|
25649
25618
|
const [capabilities, agents, goals] = await Promise.all([
|
|
25650
25619
|
options.backend.listDefinitions(options.tenantId, "capability"),
|
|
@@ -25670,13 +25639,13 @@ async function hydrateDefinitions(options) {
|
|
|
25670
25639
|
hydratedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25671
25640
|
versions: Object.fromEntries(Object.entries(versions).sort(([left], [right]) => left.localeCompare(right)))
|
|
25672
25641
|
};
|
|
25673
|
-
|
|
25642
|
+
fs50.writeFileSync(path51.join(staging, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
|
|
25674
25643
|
`, "utf8");
|
|
25675
|
-
|
|
25676
|
-
|
|
25644
|
+
fs50.rmSync(root, { recursive: true, force: true });
|
|
25645
|
+
fs50.renameSync(staging, root);
|
|
25677
25646
|
return { root, tenantId: options.tenantId, versions: manifest.versions };
|
|
25678
25647
|
} catch (error) {
|
|
25679
|
-
|
|
25648
|
+
fs50.rmSync(staging, { recursive: true, force: true });
|
|
25680
25649
|
throw error;
|
|
25681
25650
|
}
|
|
25682
25651
|
}
|
|
@@ -25769,8 +25738,8 @@ var FlyClient = class {
|
|
|
25769
25738
|
get fetch() {
|
|
25770
25739
|
return this.opts.fetchImpl ?? fetch;
|
|
25771
25740
|
}
|
|
25772
|
-
async call(
|
|
25773
|
-
const res = await this.fetch(`${FLY_API_BASE}${
|
|
25741
|
+
async call(path52, init = {}) {
|
|
25742
|
+
const res = await this.fetch(`${FLY_API_BASE}${path52}`, {
|
|
25774
25743
|
method: init.method ?? "GET",
|
|
25775
25744
|
headers: {
|
|
25776
25745
|
Authorization: `Bearer ${this.opts.token}`,
|
|
@@ -25781,7 +25750,7 @@ var FlyClient = class {
|
|
|
25781
25750
|
if (res.status === 404 && init.allow404) return null;
|
|
25782
25751
|
if (!res.ok) {
|
|
25783
25752
|
const text2 = await res.text().catch(() => "");
|
|
25784
|
-
throw new Error(`Fly API ${res.status} on ${
|
|
25753
|
+
throw new Error(`Fly API ${res.status} on ${path52}: ${text2.slice(0, 200) || res.statusText}`);
|
|
25785
25754
|
}
|
|
25786
25755
|
if (res.status === 204) return null;
|
|
25787
25756
|
const raw = await res.text();
|
|
@@ -26294,14 +26263,14 @@ function sendJson2(res, status, body) {
|
|
|
26294
26263
|
res.end(JSON.stringify(body));
|
|
26295
26264
|
}
|
|
26296
26265
|
function readJsonBody2(req) {
|
|
26297
|
-
return new Promise((
|
|
26266
|
+
return new Promise((resolve17, reject) => {
|
|
26298
26267
|
const chunks = [];
|
|
26299
26268
|
req.on("data", (c) => chunks.push(c));
|
|
26300
26269
|
req.on("end", () => {
|
|
26301
26270
|
const raw = Buffer.concat(chunks).toString("utf-8");
|
|
26302
|
-
if (!raw.trim()) return
|
|
26271
|
+
if (!raw.trim()) return resolve17({});
|
|
26303
26272
|
try {
|
|
26304
|
-
|
|
26273
|
+
resolve17(JSON.parse(raw));
|
|
26305
26274
|
} catch (err) {
|
|
26306
26275
|
reject(err instanceof Error ? err : new Error(String(err)));
|
|
26307
26276
|
}
|
|
@@ -26512,10 +26481,10 @@ async function poolServe() {
|
|
|
26512
26481
|
}
|
|
26513
26482
|
});
|
|
26514
26483
|
const apiHost = process.env.POOL_API_HOST ?? "::";
|
|
26515
|
-
await new Promise((
|
|
26484
|
+
await new Promise((resolve17) => {
|
|
26516
26485
|
server.listen(apiPort, apiHost, () => {
|
|
26517
26486
|
log(`listening on ${apiHost}:${apiPort} (min=${min}, app=${app}, region=${region})`);
|
|
26518
|
-
|
|
26487
|
+
resolve17();
|
|
26519
26488
|
});
|
|
26520
26489
|
});
|
|
26521
26490
|
if (loopTickEnabled) void runLoopTick();
|
|
@@ -26534,7 +26503,7 @@ async function poolServe() {
|
|
|
26534
26503
|
|
|
26535
26504
|
// src/servers/runner-serve.ts
|
|
26536
26505
|
import { spawn as spawn9 } from "child_process";
|
|
26537
|
-
import * as
|
|
26506
|
+
import * as fs51 from "fs";
|
|
26538
26507
|
import { createServer as createServer6 } from "http";
|
|
26539
26508
|
var DEFAULT_PORT2 = 8080;
|
|
26540
26509
|
var DEFAULT_WORKDIR = "/workspace/repo";
|
|
@@ -26555,17 +26524,17 @@ function authOk2(req, expected) {
|
|
|
26555
26524
|
return false;
|
|
26556
26525
|
}
|
|
26557
26526
|
function readJsonBody3(req) {
|
|
26558
|
-
return new Promise((
|
|
26527
|
+
return new Promise((resolve17, reject) => {
|
|
26559
26528
|
const chunks = [];
|
|
26560
26529
|
req.on("data", (c) => chunks.push(c));
|
|
26561
26530
|
req.on("end", () => {
|
|
26562
26531
|
const raw = Buffer.concat(chunks).toString("utf-8");
|
|
26563
26532
|
if (!raw.trim()) {
|
|
26564
|
-
|
|
26533
|
+
resolve17({});
|
|
26565
26534
|
return;
|
|
26566
26535
|
}
|
|
26567
26536
|
try {
|
|
26568
|
-
|
|
26537
|
+
resolve17(JSON.parse(raw));
|
|
26569
26538
|
} catch (err) {
|
|
26570
26539
|
reject(err instanceof Error ? err : new Error(String(err)));
|
|
26571
26540
|
}
|
|
@@ -26669,8 +26638,8 @@ async function defaultRunJob(job) {
|
|
|
26669
26638
|
const workdir = process.env.RUNNER_WORKDIR ?? DEFAULT_WORKDIR;
|
|
26670
26639
|
const branch = job.ref ?? "main";
|
|
26671
26640
|
const authUrl = `https://x-access-token:${job.githubToken}@github.com/${job.repo}.git`;
|
|
26672
|
-
|
|
26673
|
-
|
|
26641
|
+
fs51.rmSync(workdir, { recursive: true, force: true });
|
|
26642
|
+
fs51.mkdirSync(workdir, { recursive: true });
|
|
26674
26643
|
const allSecrets = typeof job.allSecrets === "string" ? job.allSecrets : JSON.stringify(job.allSecrets ?? {});
|
|
26675
26644
|
const target = job.runRequest.target;
|
|
26676
26645
|
const interactive = target.type === "chat";
|
|
@@ -26699,13 +26668,13 @@ async function defaultRunJob(job) {
|
|
|
26699
26668
|
...interactive && job.idleExitMs ? { KODY_IDLE_EXIT_MS: String(job.idleExitMs) } : {},
|
|
26700
26669
|
...interactive && job.hardCapMs ? { KODY_HARD_CAP_MS: String(job.hardCapMs) } : {}
|
|
26701
26670
|
};
|
|
26702
|
-
const run = (cmd, args, cwd) => new Promise((
|
|
26671
|
+
const run = (cmd, args, cwd) => new Promise((resolve17) => {
|
|
26703
26672
|
const child = spawn9(cmd, args, { stdio: "inherit", env: childEnv, cwd });
|
|
26704
|
-
child.on("exit", (code) =>
|
|
26673
|
+
child.on("exit", (code) => resolve17(code ?? 0));
|
|
26705
26674
|
child.on("error", (err) => {
|
|
26706
26675
|
process.stderr.write(`[runner-serve] ${cmd} failed: ${err.message}
|
|
26707
26676
|
`);
|
|
26708
|
-
|
|
26677
|
+
resolve17(1);
|
|
26709
26678
|
});
|
|
26710
26679
|
});
|
|
26711
26680
|
process.stdout.write(`[runner-serve] job ${job.jobId}: cloning ${job.repo}@${branch}
|
|
@@ -26781,11 +26750,11 @@ async function runnerServe() {
|
|
|
26781
26750
|
const port = Number(process.env.PORT ?? DEFAULT_PORT2);
|
|
26782
26751
|
const server = buildServer2({ apiKey });
|
|
26783
26752
|
const host = process.env.RUNNER_HOST ?? "::";
|
|
26784
|
-
await new Promise((
|
|
26753
|
+
await new Promise((resolve17) => {
|
|
26785
26754
|
server.listen(port, host, () => {
|
|
26786
26755
|
process.stdout.write(`[runner-serve] listening on ${host}:${port} (idle, awaiting job)
|
|
26787
26756
|
`);
|
|
26788
|
-
|
|
26757
|
+
resolve17();
|
|
26789
26758
|
});
|
|
26790
26759
|
});
|
|
26791
26760
|
const shutdown = (signal) => {
|
|
@@ -26854,14 +26823,14 @@ async function serve(opts) {
|
|
|
26854
26823
|
`);
|
|
26855
26824
|
const args = ["--dangerously-skip-permissions", "--model", model.model];
|
|
26856
26825
|
const child = spawn10("claude", args, { stdio: "inherit", env: editorEnv, cwd: opts.cwd });
|
|
26857
|
-
const exitCode = await new Promise((
|
|
26858
|
-
child.on("exit", (code) =>
|
|
26826
|
+
const exitCode = await new Promise((resolve17) => {
|
|
26827
|
+
child.on("exit", (code) => resolve17(code ?? 0));
|
|
26859
26828
|
child.on("error", (err) => {
|
|
26860
26829
|
process.stderr.write(`[kody serve] failed to launch Claude Code: ${err.message}
|
|
26861
26830
|
`);
|
|
26862
26831
|
process.stderr.write(` Install: https://docs.anthropic.com/claude/docs/claude-code
|
|
26863
26832
|
`);
|
|
26864
|
-
|
|
26833
|
+
resolve17(1);
|
|
26865
26834
|
});
|
|
26866
26835
|
});
|
|
26867
26836
|
killProxy();
|
|
@@ -27245,7 +27214,7 @@ function parseArgs(argv) {
|
|
|
27245
27214
|
}
|
|
27246
27215
|
async function main(argv = process.argv.slice(2)) {
|
|
27247
27216
|
unpackAllSecrets();
|
|
27248
|
-
const cwdFlag = argv.
|
|
27217
|
+
const cwdFlag = argv.indexOf("--cwd");
|
|
27249
27218
|
const definitionCwd = cwdFlag >= 0 && argv[cwdFlag + 1] ? argv[cwdFlag + 1] : process.cwd();
|
|
27250
27219
|
const shouldHydrate = Boolean(process.env.CONVEX_URL?.trim()) || process.env.GITHUB_ACTIONS === "true" && Boolean(process.env.GITHUB_EVENT_NAME);
|
|
27251
27220
|
if (shouldHydrate) {
|