@kody-ade/kody-engine 0.4.431 → 0.4.432
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 +142 -91
- package/dist/runtime-services/capability-scheduler/profile.json +61 -0
- package/dist/runtime-services/capability-tick/profile.json +86 -0
- package/dist/runtime-services/capability-tick/prompt.md +77 -0
- package/dist/runtime-services/capability-tick/prompts/locked.md +50 -0
- package/dist/runtime-services/capability-tick-scripted/profile.json +76 -0
- package/dist/runtime-services/dispatch-due-loops/profile.json +54 -0
- package/dist/runtime-services/goal-manager/profile.json +56 -0
- package/dist/runtime-services/goal-scheduler/__pycache__/managed_todo_state.cpython-314.pyc +0 -0
- package/dist/runtime-services/goal-scheduler/managed_todo_state.py +160 -0
- package/dist/runtime-services/goal-scheduler/profile.json +51 -0
- package/dist/runtime-services/goal-scheduler/scheduler.sh +872 -0
- package/dist/runtime-services/task-jobs/profile.json +51 -0
- package/package.json +2 -1
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.432",
|
|
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",
|
|
@@ -40,6 +40,7 @@ var init_package = __esm({
|
|
|
40
40
|
posttest: "tsx scripts/check-coverage-floor.ts",
|
|
41
41
|
"test:smoke": "vitest run tests/smoke --no-coverage",
|
|
42
42
|
"test:e2e": "vitest run tests/e2e --no-coverage",
|
|
43
|
+
"test:runtime-services": 'node --test "tests/runtime-services/*.test.mjs"',
|
|
43
44
|
"test:all": "vitest run tests --no-coverage",
|
|
44
45
|
typecheck: "tsc --noEmit",
|
|
45
46
|
lint: "biome check",
|
|
@@ -47,7 +48,7 @@ var init_package = __esm({
|
|
|
47
48
|
format: "biome format --write",
|
|
48
49
|
"verify:package": "node scripts/verify-package-tarball.cjs",
|
|
49
50
|
"brain:publish": "docker buildx build --platform linux/amd64 -f runner/Dockerfile.brain -t ghcr.io/${KODY_BRAIN_GHCR_OWNER:-aharonyaircohen}/kody-brain:latest --push runner",
|
|
50
|
-
prepublishOnly: "pnpm typecheck && vitest run tests/unit tests/int --no-coverage && pnpm build && pnpm verify:package"
|
|
51
|
+
prepublishOnly: "pnpm typecheck && vitest run tests/unit tests/int --no-coverage && pnpm test:runtime-services && pnpm build && pnpm verify:package"
|
|
51
52
|
},
|
|
52
53
|
dependencies: {
|
|
53
54
|
"@actions/cache": "^6.0.0",
|
|
@@ -761,7 +762,7 @@ function buildVerifyEnv(source = process.env) {
|
|
|
761
762
|
return env;
|
|
762
763
|
}
|
|
763
764
|
function runCommand(command, cwd) {
|
|
764
|
-
return new Promise((
|
|
765
|
+
return new Promise((resolve19) => {
|
|
765
766
|
const start = Date.now();
|
|
766
767
|
const child = spawn(command, {
|
|
767
768
|
cwd,
|
|
@@ -790,11 +791,11 @@ function runCommand(command, cwd) {
|
|
|
790
791
|
child.on("exit", (code) => {
|
|
791
792
|
clearTimeout(timer);
|
|
792
793
|
const tail = Buffer.concat(buffers).toString("utf-8").slice(-TAIL_CHARS);
|
|
793
|
-
|
|
794
|
+
resolve19({ exitCode: code ?? -1, durationMs: Date.now() - start, tail });
|
|
794
795
|
});
|
|
795
796
|
child.on("error", (err) => {
|
|
796
797
|
clearTimeout(timer);
|
|
797
|
-
|
|
798
|
+
resolve19({ exitCode: -1, durationMs: Date.now() - start, tail: err.message });
|
|
798
799
|
});
|
|
799
800
|
});
|
|
800
801
|
}
|
|
@@ -2014,6 +2015,18 @@ function getImplementationsRoot() {
|
|
|
2014
2015
|
}
|
|
2015
2016
|
return candidates[0];
|
|
2016
2017
|
}
|
|
2018
|
+
function getRuntimeServicesRoot() {
|
|
2019
|
+
const here = path7.dirname(new URL(import.meta.url).pathname);
|
|
2020
|
+
const candidates = [
|
|
2021
|
+
path7.join(here, "runtime-services"),
|
|
2022
|
+
path7.join(here, "..", "runtime-services"),
|
|
2023
|
+
path7.join(here, "..", "src", "runtime-services")
|
|
2024
|
+
];
|
|
2025
|
+
for (const candidate of candidates) {
|
|
2026
|
+
if (fs6.existsSync(candidate) && fs6.statSync(candidate).isDirectory()) return candidate;
|
|
2027
|
+
}
|
|
2028
|
+
return candidates[0];
|
|
2029
|
+
}
|
|
2017
2030
|
function getProjectCapabilitiesRoot() {
|
|
2018
2031
|
return capabilitiesRoot();
|
|
2019
2032
|
}
|
|
@@ -2038,6 +2051,9 @@ function getImplementationRoots() {
|
|
|
2038
2051
|
function getImplementationRootsForCwd(cwd) {
|
|
2039
2052
|
return [implementationsRoot(cwd), getImplementationsRoot()];
|
|
2040
2053
|
}
|
|
2054
|
+
function getRuntimeProfileRootsForCwd(cwd) {
|
|
2055
|
+
return [...getImplementationRootsForCwd(cwd), getRuntimeServicesRoot()];
|
|
2056
|
+
}
|
|
2041
2057
|
function getCapabilityRoots(projectCapabilitiesRoot = getProjectCapabilitiesRoot()) {
|
|
2042
2058
|
return [projectCapabilitiesRoot, getBuiltinCapabilitiesRoot()];
|
|
2043
2059
|
}
|
|
@@ -2061,10 +2077,13 @@ function listImplementations(roots = getImplementationRoots()) {
|
|
|
2061
2077
|
}
|
|
2062
2078
|
return out.sort((a, b) => a.name.localeCompare(b.name));
|
|
2063
2079
|
}
|
|
2064
|
-
function
|
|
2080
|
+
function listRuntimeProfilesForCwd(cwd) {
|
|
2081
|
+
return listImplementations(getRuntimeProfileRootsForCwd(cwd));
|
|
2082
|
+
}
|
|
2083
|
+
function resolveImplementation(name, roots = getRuntimeProfileRootsForCwd(process.cwd())) {
|
|
2065
2084
|
return resolveImplementationCandidates(name, roots)[0] ?? null;
|
|
2066
2085
|
}
|
|
2067
|
-
function resolveImplementationCandidates(name, roots =
|
|
2086
|
+
function resolveImplementationCandidates(name, roots = getRuntimeProfileRootsForCwd(process.cwd())) {
|
|
2068
2087
|
if (!isSafeName(name)) return [];
|
|
2069
2088
|
const rootList = typeof roots === "string" ? [roots] : roots;
|
|
2070
2089
|
const out = [];
|
|
@@ -2184,7 +2203,7 @@ function canonical(value) {
|
|
|
2184
2203
|
return JSON.stringify(value);
|
|
2185
2204
|
}
|
|
2186
2205
|
function implementationDeclaresInput(implementation, inputName, cwd = process.cwd()) {
|
|
2187
|
-
const profilePath = resolveImplementation(implementation,
|
|
2206
|
+
const profilePath = resolveImplementation(implementation, getRuntimeProfileRootsForCwd(cwd));
|
|
2188
2207
|
if (!profilePath) return false;
|
|
2189
2208
|
try {
|
|
2190
2209
|
const document = JSON.parse(fs6.readFileSync(profilePath, "utf-8"));
|
|
@@ -3413,7 +3432,7 @@ var init_repoWorkspace = __esm({
|
|
|
3413
3432
|
defaultCloneRepo = (repo, token, dir) => {
|
|
3414
3433
|
fs7.mkdirSync(path8.dirname(dir), { recursive: true });
|
|
3415
3434
|
const clone = buildCloneProcess(repo, token);
|
|
3416
|
-
return new Promise((
|
|
3435
|
+
return new Promise((resolve19, reject) => {
|
|
3417
3436
|
const child = spawn2("git", ["clone", "--depth=1", clone.url, dir], {
|
|
3418
3437
|
env: clone.env,
|
|
3419
3438
|
stdio: "inherit"
|
|
@@ -3433,7 +3452,7 @@ var init_repoWorkspace = __esm({
|
|
|
3433
3452
|
}
|
|
3434
3453
|
} catch {
|
|
3435
3454
|
}
|
|
3436
|
-
|
|
3455
|
+
resolve19();
|
|
3437
3456
|
});
|
|
3438
3457
|
child.on("error", reject);
|
|
3439
3458
|
});
|
|
@@ -3747,10 +3766,10 @@ async function runAgent(opts) {
|
|
|
3747
3766
|
let timer;
|
|
3748
3767
|
let next;
|
|
3749
3768
|
if (turnTimeoutMs > 0) {
|
|
3750
|
-
const timeoutPromise = new Promise((
|
|
3769
|
+
const timeoutPromise = new Promise((resolve19) => {
|
|
3751
3770
|
timer = setTimeout(() => {
|
|
3752
3771
|
timedOut = true;
|
|
3753
|
-
|
|
3772
|
+
resolve19({ done: true, value: void 0 });
|
|
3754
3773
|
}, turnTimeoutMs);
|
|
3755
3774
|
});
|
|
3756
3775
|
next = await Promise.race([nextPromise, timeoutPromise]);
|
|
@@ -3766,7 +3785,7 @@ async function runAgent(opts) {
|
|
|
3766
3785
|
try {
|
|
3767
3786
|
await Promise.race([
|
|
3768
3787
|
iterator.return(void 0).catch(() => void 0),
|
|
3769
|
-
new Promise((
|
|
3788
|
+
new Promise((resolve19) => setTimeout(resolve19, 1e4).unref())
|
|
3770
3789
|
]);
|
|
3771
3790
|
} catch {
|
|
3772
3791
|
}
|
|
@@ -4794,10 +4813,12 @@ var init_buildSyntheticPlugin = __esm({
|
|
|
4794
4813
|
const resolvePart = (bucket, entry) => {
|
|
4795
4814
|
const local = path17.join(profile.dir, bucket, entry);
|
|
4796
4815
|
if (fs18.existsSync(local)) return local;
|
|
4816
|
+
const shared = path17.resolve(profile.dir, "..", "..", "shared", bucket, entry);
|
|
4817
|
+
if (fs18.existsSync(shared)) return shared;
|
|
4797
4818
|
const central = path17.join(catalog, bucket, entry);
|
|
4798
4819
|
if (fs18.existsSync(central)) return central;
|
|
4799
4820
|
throw new Error(
|
|
4800
|
-
`buildSyntheticPlugin: ${bucket} entry '${entry}' not found in implementation dir (${profile.dir}/${bucket}/) or catalog (${catalog}/${bucket}/)`
|
|
4821
|
+
`buildSyntheticPlugin: ${bucket} entry '${entry}' not found in implementation dir (${profile.dir}/${bucket}/), Store shared assets (${path17.dirname(shared)}/), or catalog (${catalog}/${bucket}/)`
|
|
4801
4822
|
);
|
|
4802
4823
|
};
|
|
4803
4824
|
if (cc.skills.length > 0) {
|
|
@@ -4861,9 +4882,13 @@ function splitFrontmatter(raw) {
|
|
|
4861
4882
|
function resolveAgentFile2(profileDir, name) {
|
|
4862
4883
|
const local = path18.join(profileDir, "agents", `${name}.md`);
|
|
4863
4884
|
if (fs19.existsSync(local)) return local;
|
|
4885
|
+
const shared = path18.resolve(profileDir, "..", "..", "shared", "agents", `${name}.md`);
|
|
4886
|
+
if (fs19.existsSync(shared)) return shared;
|
|
4864
4887
|
const central = path18.join(getPluginsCatalogRoot(), "agents", `${name}.md`);
|
|
4865
4888
|
if (fs19.existsSync(central)) return central;
|
|
4866
|
-
throw new Error(
|
|
4889
|
+
throw new Error(
|
|
4890
|
+
`loadSubagents: agent '${name}' not found in ${profileDir}/agents/, hydrated shared assets, or engine catalog`
|
|
4891
|
+
);
|
|
4867
4892
|
}
|
|
4868
4893
|
function captureSubagentTemplates(profile) {
|
|
4869
4894
|
const names = profile.claudeCode.subagents;
|
|
@@ -7034,11 +7059,11 @@ async function nextAvailableLitellmUrl(url) {
|
|
|
7034
7059
|
throw new Error(`no free LiteLLM port found after ${startPort}`);
|
|
7035
7060
|
}
|
|
7036
7061
|
function canListen(port, host) {
|
|
7037
|
-
return new Promise((
|
|
7062
|
+
return new Promise((resolve19) => {
|
|
7038
7063
|
const server = net.createServer();
|
|
7039
|
-
server.once("error", () =>
|
|
7064
|
+
server.once("error", () => resolve19(false));
|
|
7040
7065
|
server.once("listening", () => {
|
|
7041
|
-
server.close(() =>
|
|
7066
|
+
server.close(() => resolve19(true));
|
|
7042
7067
|
});
|
|
7043
7068
|
server.listen(port, host);
|
|
7044
7069
|
});
|
|
@@ -13859,10 +13884,10 @@ async function runAttempt(run, job, timeoutSeconds) {
|
|
|
13859
13884
|
exitCode: 99,
|
|
13860
13885
|
reason: error instanceof Error ? error.message : String(error)
|
|
13861
13886
|
})),
|
|
13862
|
-
new Promise((
|
|
13887
|
+
new Promise((resolve19) => {
|
|
13863
13888
|
timer = setTimeout(() => {
|
|
13864
13889
|
abortController.abort();
|
|
13865
|
-
|
|
13890
|
+
resolve19({ exitCode: 124, reason: `target timed out after ${formatSeconds(timeoutSeconds)}s` });
|
|
13866
13891
|
}, timeoutSeconds * 1e3);
|
|
13867
13892
|
})
|
|
13868
13893
|
]);
|
|
@@ -13902,7 +13927,7 @@ function formatSeconds(seconds) {
|
|
|
13902
13927
|
}
|
|
13903
13928
|
async function wait(milliseconds) {
|
|
13904
13929
|
if (milliseconds <= 0) return;
|
|
13905
|
-
await new Promise((
|
|
13930
|
+
await new Promise((resolve19) => setTimeout(resolve19, milliseconds));
|
|
13906
13931
|
}
|
|
13907
13932
|
function repositoryTenant(config) {
|
|
13908
13933
|
const owner = config.github?.owner?.trim() || process.env.GITHUB_REPOSITORY?.split("/")[0]?.trim();
|
|
@@ -15082,7 +15107,7 @@ function performInit(cwd, force) {
|
|
|
15082
15107
|
fs36.writeFileSync(workflowPath, loadKodyWorkflowTemplate());
|
|
15083
15108
|
wrote.push(".github/workflows/kody.yml");
|
|
15084
15109
|
}
|
|
15085
|
-
for (const exe of
|
|
15110
|
+
for (const exe of listRuntimeProfilesForCwd(cwd)) {
|
|
15086
15111
|
let profile;
|
|
15087
15112
|
try {
|
|
15088
15113
|
profile = loadProfile(exe.profilePath);
|
|
@@ -15490,7 +15515,7 @@ function retryDelaysMs() {
|
|
|
15490
15515
|
}
|
|
15491
15516
|
function sleep(ms) {
|
|
15492
15517
|
if (ms <= 0) return Promise.resolve();
|
|
15493
|
-
return new Promise((
|
|
15518
|
+
return new Promise((resolve19) => setTimeout(resolve19, ms));
|
|
15494
15519
|
}
|
|
15495
15520
|
async function fetchGoalStateWithRetry(config, goalId, cwd) {
|
|
15496
15521
|
let state = await fetchGoalStateAsync(config, goalId, cwd);
|
|
@@ -18609,7 +18634,7 @@ var init_previewBuildHelpers = __esm({
|
|
|
18609
18634
|
// src/scripts/previewBuildRun.ts
|
|
18610
18635
|
import { spawn as spawn5 } from "child_process";
|
|
18611
18636
|
async function runCmd(cmd, args, opts = {}) {
|
|
18612
|
-
await new Promise((
|
|
18637
|
+
await new Promise((resolve19, reject) => {
|
|
18613
18638
|
const child = spawn5(cmd, args, {
|
|
18614
18639
|
cwd: opts.cwd,
|
|
18615
18640
|
env: { ...process.env, ...opts.env ?? {} },
|
|
@@ -18621,7 +18646,7 @@ async function runCmd(cmd, args, opts = {}) {
|
|
|
18621
18646
|
}
|
|
18622
18647
|
child.on("error", reject);
|
|
18623
18648
|
child.on("close", (code) => {
|
|
18624
|
-
if (code === 0)
|
|
18649
|
+
if (code === 0) resolve19();
|
|
18625
18650
|
else reject(new Error(`${cmd} ${args.join(" ")} exited ${code}`));
|
|
18626
18651
|
});
|
|
18627
18652
|
});
|
|
@@ -19885,7 +19910,7 @@ function stripAnsi2(s) {
|
|
|
19885
19910
|
return s.replace(ANSI_RE2, "");
|
|
19886
19911
|
}
|
|
19887
19912
|
function runCommand2(command, cwd) {
|
|
19888
|
-
return new Promise((
|
|
19913
|
+
return new Promise((resolve19) => {
|
|
19889
19914
|
const child = spawn6(command, {
|
|
19890
19915
|
cwd,
|
|
19891
19916
|
shell: true,
|
|
@@ -19912,11 +19937,11 @@ function runCommand2(command, cwd) {
|
|
|
19912
19937
|
}, TEST_TIMEOUT_MS);
|
|
19913
19938
|
child.on("exit", (code) => {
|
|
19914
19939
|
clearTimeout(timer);
|
|
19915
|
-
|
|
19940
|
+
resolve19({ exitCode: code ?? -1, output: Buffer.concat(buffers).toString("utf-8") });
|
|
19916
19941
|
});
|
|
19917
19942
|
child.on("error", (err) => {
|
|
19918
19943
|
clearTimeout(timer);
|
|
19919
|
-
|
|
19944
|
+
resolve19({ exitCode: -1, output: err.message });
|
|
19920
19945
|
});
|
|
19921
19946
|
});
|
|
19922
19947
|
}
|
|
@@ -20322,21 +20347,21 @@ function lineStream(stream) {
|
|
|
20322
20347
|
tryDeliver();
|
|
20323
20348
|
});
|
|
20324
20349
|
return {
|
|
20325
|
-
next: (timeoutMs) => new Promise((
|
|
20350
|
+
next: (timeoutMs) => new Promise((resolve19) => {
|
|
20326
20351
|
if (queue.length > 0) {
|
|
20327
|
-
|
|
20352
|
+
resolve19(queue.shift());
|
|
20328
20353
|
return;
|
|
20329
20354
|
}
|
|
20330
20355
|
if (ended) {
|
|
20331
|
-
|
|
20356
|
+
resolve19(null);
|
|
20332
20357
|
return;
|
|
20333
20358
|
}
|
|
20334
|
-
waiter =
|
|
20359
|
+
waiter = resolve19;
|
|
20335
20360
|
const t = setTimeout(
|
|
20336
20361
|
() => {
|
|
20337
|
-
if (waiter ===
|
|
20362
|
+
if (waiter === resolve19) {
|
|
20338
20363
|
waiter = null;
|
|
20339
|
-
|
|
20364
|
+
resolve19(null);
|
|
20340
20365
|
}
|
|
20341
20366
|
},
|
|
20342
20367
|
Math.max(0, timeoutMs)
|
|
@@ -21596,7 +21621,7 @@ function clearStampedLifecycleLabels(profile, ctx) {
|
|
|
21596
21621
|
}
|
|
21597
21622
|
}
|
|
21598
21623
|
function resolveProfilePath(profileName, cwd = process.cwd()) {
|
|
21599
|
-
const found = resolveImplementation(profileName,
|
|
21624
|
+
const found = resolveImplementation(profileName, getRuntimeProfileRootsForCwd(cwd));
|
|
21600
21625
|
if (found) return found;
|
|
21601
21626
|
const here = path45.dirname(new URL(import.meta.url).pathname);
|
|
21602
21627
|
const candidates = [
|
|
@@ -21613,7 +21638,7 @@ function resolveProfilePath(profileName, cwd = process.cwd()) {
|
|
|
21613
21638
|
return candidates[0];
|
|
21614
21639
|
}
|
|
21615
21640
|
function loadRunnableProfile(profileName, cwd) {
|
|
21616
|
-
const candidates = resolveImplementationCandidates(profileName,
|
|
21641
|
+
const candidates = resolveImplementationCandidates(profileName, getRuntimeProfileRootsForCwd(cwd));
|
|
21617
21642
|
const skipped = [];
|
|
21618
21643
|
for (const profilePath2 of candidates) {
|
|
21619
21644
|
const profile2 = loadProfile(profilePath2);
|
|
@@ -21766,14 +21791,14 @@ async function runShellEntry(entry, ctx, profile) {
|
|
|
21766
21791
|
let killTimer;
|
|
21767
21792
|
let escalateTimer;
|
|
21768
21793
|
const result = await new Promise(
|
|
21769
|
-
(
|
|
21794
|
+
(resolve19) => {
|
|
21770
21795
|
let settled = false;
|
|
21771
21796
|
const settle = (code, signal, spawnErr) => {
|
|
21772
21797
|
if (settled) return;
|
|
21773
21798
|
settled = true;
|
|
21774
21799
|
if (killTimer) clearTimeout(killTimer);
|
|
21775
21800
|
if (escalateTimer) clearTimeout(escalateTimer);
|
|
21776
|
-
|
|
21801
|
+
resolve19({ code, signal, spawnErr });
|
|
21777
21802
|
};
|
|
21778
21803
|
child.on("error", (err) => settle(null, null, err));
|
|
21779
21804
|
child.on("close", (code, signal) => settle(code, signal));
|
|
@@ -22973,9 +22998,9 @@ var CodexAppServerClient = class {
|
|
|
22973
22998
|
await this.request("thread/resume", { threadId });
|
|
22974
22999
|
}
|
|
22975
23000
|
async runTurn(args) {
|
|
22976
|
-
await new Promise((
|
|
23001
|
+
await new Promise((resolve19, reject) => {
|
|
22977
23002
|
this.process.turnWaiters.set(args.threadId, {
|
|
22978
|
-
resolve:
|
|
23003
|
+
resolve: resolve19,
|
|
22979
23004
|
reject,
|
|
22980
23005
|
onNotification: args.onNotification,
|
|
22981
23006
|
queue: Promise.resolve()
|
|
@@ -22992,8 +23017,8 @@ var CodexAppServerClient = class {
|
|
|
22992
23017
|
}
|
|
22993
23018
|
request(method, params) {
|
|
22994
23019
|
const id = this.process.nextId++;
|
|
22995
|
-
return new Promise((
|
|
22996
|
-
this.process.pending.set(id, { resolve:
|
|
23020
|
+
return new Promise((resolve19, reject) => {
|
|
23021
|
+
this.process.pending.set(id, { resolve: resolve19, reject });
|
|
22997
23022
|
this.process.child.stdin.write(`${JSON.stringify({ method, id, params })}
|
|
22998
23023
|
`);
|
|
22999
23024
|
});
|
|
@@ -24277,7 +24302,7 @@ function dispatchScheduledWatches(opts) {
|
|
|
24277
24302
|
const envWindow = Number(process.env.KODY_SCHEDULE_WINDOW_SEC);
|
|
24278
24303
|
const windowSec = opts?.windowSec ?? (Number.isFinite(envWindow) && envWindow > 0 ? envWindow : 300);
|
|
24279
24304
|
const out = [];
|
|
24280
|
-
for (const exe of
|
|
24305
|
+
for (const exe of listRuntimeProfilesForCwd(opts?.cwd ?? process.cwd())) {
|
|
24281
24306
|
let raw;
|
|
24282
24307
|
try {
|
|
24283
24308
|
raw = fs16.readFileSync(exe.profilePath, "utf-8");
|
|
@@ -24871,8 +24896,14 @@ async function runCi(argv) {
|
|
|
24871
24896
|
if (noTarget && capabilityInput) {
|
|
24872
24897
|
forceRunAction = capabilityInput;
|
|
24873
24898
|
if (messageInput) {
|
|
24874
|
-
const route = resolveCapabilityAction(
|
|
24875
|
-
|
|
24899
|
+
const route = resolveCapabilityAction(
|
|
24900
|
+
capabilityInput,
|
|
24901
|
+
capabilitiesRoot(cwd)
|
|
24902
|
+
);
|
|
24903
|
+
const textInputs = route?.implementation ? (getProfileInputs(
|
|
24904
|
+
route.implementation,
|
|
24905
|
+
getRuntimeProfileRootsForCwd(cwd)
|
|
24906
|
+
) ?? []).filter(
|
|
24876
24907
|
(input) => input.type === "string"
|
|
24877
24908
|
) : [];
|
|
24878
24909
|
if (textInputs.length === 1) {
|
|
@@ -24905,7 +24936,7 @@ async function runCi(argv) {
|
|
|
24905
24936
|
workflow: forceRunAction,
|
|
24906
24937
|
cliArgs: {}
|
|
24907
24938
|
};
|
|
24908
|
-
const scheduledWatchRoute = manualGoalManager || capabilityRoute || workflowRoute ? void 0 : dispatchScheduledWatches({ force: true }).find(
|
|
24939
|
+
const scheduledWatchRoute = manualGoalManager || capabilityRoute || workflowRoute ? void 0 : dispatchScheduledWatches({ force: true, cwd }).find(
|
|
24909
24940
|
(match) => match.action === forceRunAction || match.capability === forceRunAction || match.implementation === forceRunAction
|
|
24910
24941
|
);
|
|
24911
24942
|
const route = manualGoalManager ? {
|
|
@@ -25158,7 +25189,10 @@ ${CI_HELP}`);
|
|
|
25158
25189
|
}
|
|
25159
25190
|
}
|
|
25160
25191
|
async function runScheduledFanOut(cwd, args, opts) {
|
|
25161
|
-
const matches = dispatchScheduledWatches({
|
|
25192
|
+
const matches = dispatchScheduledWatches({
|
|
25193
|
+
force: opts.force,
|
|
25194
|
+
cwd
|
|
25195
|
+
});
|
|
25162
25196
|
if (matches.length === 0) {
|
|
25163
25197
|
process.stdout.write(
|
|
25164
25198
|
`\u2192 kody: scheduled wake \u2014 no watches matched ${opts.force ? "(force mode, no watches discovered)" : "(window)"}, exiting cleanly
|
|
@@ -25445,17 +25479,17 @@ function authOk(req, expected) {
|
|
|
25445
25479
|
return false;
|
|
25446
25480
|
}
|
|
25447
25481
|
function readJsonBody(req) {
|
|
25448
|
-
return new Promise((
|
|
25482
|
+
return new Promise((resolve19, reject) => {
|
|
25449
25483
|
const chunks = [];
|
|
25450
25484
|
req.on("data", (c) => chunks.push(c));
|
|
25451
25485
|
req.on("end", () => {
|
|
25452
25486
|
const raw = Buffer.concat(chunks).toString("utf-8");
|
|
25453
25487
|
if (!raw.trim()) {
|
|
25454
|
-
|
|
25488
|
+
resolve19({});
|
|
25455
25489
|
return;
|
|
25456
25490
|
}
|
|
25457
25491
|
try {
|
|
25458
|
-
|
|
25492
|
+
resolve19(JSON.parse(raw));
|
|
25459
25493
|
} catch (err) {
|
|
25460
25494
|
reject(err instanceof Error ? err : new Error(String(err)));
|
|
25461
25495
|
}
|
|
@@ -25795,11 +25829,11 @@ async function brainServe(opts) {
|
|
|
25795
25829
|
litellmUrl,
|
|
25796
25830
|
driver
|
|
25797
25831
|
});
|
|
25798
|
-
await new Promise((
|
|
25832
|
+
await new Promise((resolve19) => {
|
|
25799
25833
|
server.listen(port, "0.0.0.0", () => {
|
|
25800
25834
|
process.stdout.write(`[brain-serve] listening on 0.0.0.0:${port} (cwd=${opts.cwd})
|
|
25801
25835
|
`);
|
|
25802
|
-
|
|
25836
|
+
resolve19();
|
|
25803
25837
|
});
|
|
25804
25838
|
});
|
|
25805
25839
|
const shutdown = (signal) => {
|
|
@@ -26054,14 +26088,14 @@ async function startBrainProxy(opts) {
|
|
|
26054
26088
|
const { httpServer, handler } = buildBrainProxy(opts);
|
|
26055
26089
|
const port = opts.port ?? 0;
|
|
26056
26090
|
const host = opts.host ?? "127.0.0.1";
|
|
26057
|
-
await new Promise((
|
|
26091
|
+
await new Promise((resolve19) => httpServer.listen(port, host, () => resolve19()));
|
|
26058
26092
|
const addr = httpServer.address();
|
|
26059
26093
|
return {
|
|
26060
26094
|
httpServer,
|
|
26061
26095
|
port: addr.port,
|
|
26062
26096
|
url: `http://${host}:${addr.port}`,
|
|
26063
|
-
stop: () => new Promise((
|
|
26064
|
-
httpServer.close(() =>
|
|
26097
|
+
stop: () => new Promise((resolve19) => {
|
|
26098
|
+
httpServer.close(() => resolve19());
|
|
26065
26099
|
}),
|
|
26066
26100
|
handler
|
|
26067
26101
|
};
|
|
@@ -26211,23 +26245,23 @@ function buildMcpHttpServer(opts) {
|
|
|
26211
26245
|
httpServer,
|
|
26212
26246
|
routes,
|
|
26213
26247
|
port,
|
|
26214
|
-
stop: () => new Promise((
|
|
26248
|
+
stop: () => new Promise((resolve19) => {
|
|
26215
26249
|
let pending = transports.size;
|
|
26216
26250
|
if (pending === 0) {
|
|
26217
|
-
httpServer.close(() =>
|
|
26251
|
+
httpServer.close(() => resolve19());
|
|
26218
26252
|
return;
|
|
26219
26253
|
}
|
|
26220
26254
|
for (const transport of transports.values()) {
|
|
26221
26255
|
void transport.close().finally(() => {
|
|
26222
26256
|
pending--;
|
|
26223
|
-
if (pending === 0) httpServer.close(() =>
|
|
26257
|
+
if (pending === 0) httpServer.close(() => resolve19());
|
|
26224
26258
|
});
|
|
26225
26259
|
}
|
|
26226
26260
|
})
|
|
26227
26261
|
};
|
|
26228
26262
|
}
|
|
26229
26263
|
function listenMcpHttpServer(server, host = "127.0.0.1") {
|
|
26230
|
-
return new Promise((
|
|
26264
|
+
return new Promise((resolve19, reject) => {
|
|
26231
26265
|
server.httpServer.once("error", reject);
|
|
26232
26266
|
server.httpServer.listen(server.port, host, () => {
|
|
26233
26267
|
server.httpServer.off("error", reject);
|
|
@@ -26235,7 +26269,7 @@ function listenMcpHttpServer(server, host = "127.0.0.1") {
|
|
|
26235
26269
|
if (addr && typeof addr === "object") {
|
|
26236
26270
|
server.port = addr.port;
|
|
26237
26271
|
}
|
|
26238
|
-
|
|
26272
|
+
resolve19();
|
|
26239
26273
|
});
|
|
26240
26274
|
});
|
|
26241
26275
|
}
|
|
@@ -26385,7 +26419,7 @@ async function waitForNextUserMessage(opts) {
|
|
|
26385
26419
|
}
|
|
26386
26420
|
}
|
|
26387
26421
|
function sleep3(ms) {
|
|
26388
|
-
return new Promise((
|
|
26422
|
+
return new Promise((resolve19) => setTimeout(resolve19, ms));
|
|
26389
26423
|
}
|
|
26390
26424
|
function currentBranch(cwd) {
|
|
26391
26425
|
try {
|
|
@@ -26723,7 +26757,7 @@ init_state_backend();
|
|
|
26723
26757
|
import { createHash as createHash8 } from "crypto";
|
|
26724
26758
|
import * as fs50 from "fs";
|
|
26725
26759
|
import * as path51 from "path";
|
|
26726
|
-
var SLUG_RE2 = /^[a-z0-9][a-z0-9_-]{0,
|
|
26760
|
+
var SLUG_RE2 = /^[a-z0-9][a-z0-9_-]{0,127}$/;
|
|
26727
26761
|
function assertSafeDefinitionPath(filePath) {
|
|
26728
26762
|
const segments = filePath.split("/");
|
|
26729
26763
|
if (!filePath || filePath.startsWith("/") || filePath.includes("\\") || filePath.includes("\0") || segments.some((segment) => !segment || segment === "." || segment === "..")) {
|
|
@@ -26751,6 +26785,13 @@ function verifyDefinition(definition) {
|
|
|
26751
26785
|
}
|
|
26752
26786
|
return bundle;
|
|
26753
26787
|
}
|
|
26788
|
+
function writeBundle(root, bundle) {
|
|
26789
|
+
for (const [filePath, contents] of Object.entries(bundle.files)) {
|
|
26790
|
+
const target = path51.join(root, filePath);
|
|
26791
|
+
fs50.mkdirSync(path51.dirname(target), { recursive: true });
|
|
26792
|
+
fs50.writeFileSync(target, contents, "utf8");
|
|
26793
|
+
}
|
|
26794
|
+
}
|
|
26754
26795
|
function writeDefinition(root, kind, definition) {
|
|
26755
26796
|
const bundle = verifyDefinition(definition);
|
|
26756
26797
|
if (kind === "agent") {
|
|
@@ -26760,20 +26801,18 @@ function writeDefinition(root, kind, definition) {
|
|
|
26760
26801
|
return;
|
|
26761
26802
|
}
|
|
26762
26803
|
if (kind === "goal") {
|
|
26763
|
-
|
|
26764
|
-
for (const [filePath, contents] of Object.entries(bundle.files)) {
|
|
26765
|
-
const target = path51.join(goalRoot, filePath);
|
|
26766
|
-
fs50.mkdirSync(path51.dirname(target), { recursive: true });
|
|
26767
|
-
fs50.writeFileSync(target, contents, "utf8");
|
|
26768
|
-
}
|
|
26804
|
+
writeBundle(path51.join(root, "goals", definition.slug), bundle);
|
|
26769
26805
|
return;
|
|
26770
26806
|
}
|
|
26771
|
-
|
|
26772
|
-
|
|
26773
|
-
|
|
26774
|
-
fs50.mkdirSync(path51.dirname(target), { recursive: true });
|
|
26775
|
-
fs50.writeFileSync(target, contents, "utf8");
|
|
26807
|
+
if (kind === "implementation") {
|
|
26808
|
+
writeBundle(path51.join(root, "implementations", definition.slug), bundle);
|
|
26809
|
+
return;
|
|
26776
26810
|
}
|
|
26811
|
+
if (kind === "asset") {
|
|
26812
|
+
writeBundle(path51.join(root, "shared"), bundle);
|
|
26813
|
+
return;
|
|
26814
|
+
}
|
|
26815
|
+
writeBundle(path51.join(root, "capabilities", definition.slug), bundle);
|
|
26777
26816
|
}
|
|
26778
26817
|
async function hydrateDefinitions(options) {
|
|
26779
26818
|
const root = path51.join(options.cwd, ".kody-engine", "definitions");
|
|
@@ -26782,11 +26821,15 @@ async function hydrateDefinitions(options) {
|
|
|
26782
26821
|
fs50.mkdirSync(path51.join(staging, "agents"), { recursive: true });
|
|
26783
26822
|
fs50.mkdirSync(path51.join(staging, "capabilities"), { recursive: true });
|
|
26784
26823
|
fs50.mkdirSync(path51.join(staging, "goals"), { recursive: true });
|
|
26824
|
+
fs50.mkdirSync(path51.join(staging, "implementations"), { recursive: true });
|
|
26825
|
+
fs50.mkdirSync(path51.join(staging, "shared"), { recursive: true });
|
|
26785
26826
|
try {
|
|
26786
|
-
const [capabilities, agents, goals] = await Promise.all([
|
|
26827
|
+
const [capabilities, agents, goals, implementations, assets] = await Promise.all([
|
|
26787
26828
|
options.backend.listDefinitions(options.tenantId, "capability"),
|
|
26788
26829
|
options.backend.listDefinitions(options.tenantId, "agent"),
|
|
26789
|
-
options.backend.listDefinitions(options.tenantId, "goal")
|
|
26830
|
+
options.backend.listDefinitions(options.tenantId, "goal"),
|
|
26831
|
+
options.backend.listDefinitions(options.tenantId, "implementation"),
|
|
26832
|
+
options.backend.listDefinitions(options.tenantId, "asset")
|
|
26790
26833
|
]);
|
|
26791
26834
|
const versions = {};
|
|
26792
26835
|
for (const definition of capabilities) {
|
|
@@ -26801,6 +26844,14 @@ async function hydrateDefinitions(options) {
|
|
|
26801
26844
|
writeDefinition(staging, "goal", definition);
|
|
26802
26845
|
versions[`goal:${definition.slug}`] = definition.version;
|
|
26803
26846
|
}
|
|
26847
|
+
for (const definition of implementations) {
|
|
26848
|
+
writeDefinition(staging, "implementation", definition);
|
|
26849
|
+
versions[`implementation:${definition.slug}`] = definition.version;
|
|
26850
|
+
}
|
|
26851
|
+
for (const definition of assets) {
|
|
26852
|
+
writeDefinition(staging, "asset", definition);
|
|
26853
|
+
versions[`asset:${definition.slug}`] = definition.version;
|
|
26854
|
+
}
|
|
26804
26855
|
const manifest = {
|
|
26805
26856
|
schemaVersion: 1,
|
|
26806
26857
|
tenantId: options.tenantId,
|
|
@@ -27431,14 +27482,14 @@ function sendJson2(res, status, body) {
|
|
|
27431
27482
|
res.end(JSON.stringify(body));
|
|
27432
27483
|
}
|
|
27433
27484
|
function readJsonBody2(req) {
|
|
27434
|
-
return new Promise((
|
|
27485
|
+
return new Promise((resolve19, reject) => {
|
|
27435
27486
|
const chunks = [];
|
|
27436
27487
|
req.on("data", (c) => chunks.push(c));
|
|
27437
27488
|
req.on("end", () => {
|
|
27438
27489
|
const raw = Buffer.concat(chunks).toString("utf-8");
|
|
27439
|
-
if (!raw.trim()) return
|
|
27490
|
+
if (!raw.trim()) return resolve19({});
|
|
27440
27491
|
try {
|
|
27441
|
-
|
|
27492
|
+
resolve19(JSON.parse(raw));
|
|
27442
27493
|
} catch (err) {
|
|
27443
27494
|
reject(err instanceof Error ? err : new Error(String(err)));
|
|
27444
27495
|
}
|
|
@@ -27649,10 +27700,10 @@ async function poolServe() {
|
|
|
27649
27700
|
}
|
|
27650
27701
|
});
|
|
27651
27702
|
const apiHost = process.env.POOL_API_HOST ?? "::";
|
|
27652
|
-
await new Promise((
|
|
27703
|
+
await new Promise((resolve19) => {
|
|
27653
27704
|
server.listen(apiPort, apiHost, () => {
|
|
27654
27705
|
log(`listening on ${apiHost}:${apiPort} (min=${min}, app=${app}, region=${region})`);
|
|
27655
|
-
|
|
27706
|
+
resolve19();
|
|
27656
27707
|
});
|
|
27657
27708
|
});
|
|
27658
27709
|
if (loopTickEnabled) void runLoopTick();
|
|
@@ -27692,17 +27743,17 @@ function authOk2(req, expected) {
|
|
|
27692
27743
|
return false;
|
|
27693
27744
|
}
|
|
27694
27745
|
function readJsonBody3(req) {
|
|
27695
|
-
return new Promise((
|
|
27746
|
+
return new Promise((resolve19, reject) => {
|
|
27696
27747
|
const chunks = [];
|
|
27697
27748
|
req.on("data", (c) => chunks.push(c));
|
|
27698
27749
|
req.on("end", () => {
|
|
27699
27750
|
const raw = Buffer.concat(chunks).toString("utf-8");
|
|
27700
27751
|
if (!raw.trim()) {
|
|
27701
|
-
|
|
27752
|
+
resolve19({});
|
|
27702
27753
|
return;
|
|
27703
27754
|
}
|
|
27704
27755
|
try {
|
|
27705
|
-
|
|
27756
|
+
resolve19(JSON.parse(raw));
|
|
27706
27757
|
} catch (err) {
|
|
27707
27758
|
reject(err instanceof Error ? err : new Error(String(err)));
|
|
27708
27759
|
}
|
|
@@ -27836,13 +27887,13 @@ async function defaultRunJob(job) {
|
|
|
27836
27887
|
...interactive && job.idleExitMs ? { KODY_IDLE_EXIT_MS: String(job.idleExitMs) } : {},
|
|
27837
27888
|
...interactive && job.hardCapMs ? { KODY_HARD_CAP_MS: String(job.hardCapMs) } : {}
|
|
27838
27889
|
};
|
|
27839
|
-
const run = (cmd, args, cwd) => new Promise((
|
|
27890
|
+
const run = (cmd, args, cwd) => new Promise((resolve19) => {
|
|
27840
27891
|
const child = spawn9(cmd, args, { stdio: "inherit", env: childEnv, cwd });
|
|
27841
|
-
child.on("exit", (code) =>
|
|
27892
|
+
child.on("exit", (code) => resolve19(code ?? 0));
|
|
27842
27893
|
child.on("error", (err) => {
|
|
27843
27894
|
process.stderr.write(`[runner-serve] ${cmd} failed: ${err.message}
|
|
27844
27895
|
`);
|
|
27845
|
-
|
|
27896
|
+
resolve19(1);
|
|
27846
27897
|
});
|
|
27847
27898
|
});
|
|
27848
27899
|
process.stdout.write(`[runner-serve] job ${job.jobId}: cloning ${job.repo}@${branch}
|
|
@@ -27918,11 +27969,11 @@ async function runnerServe() {
|
|
|
27918
27969
|
const port = Number(process.env.PORT ?? DEFAULT_PORT2);
|
|
27919
27970
|
const server = buildServer2({ apiKey });
|
|
27920
27971
|
const host = process.env.RUNNER_HOST ?? "::";
|
|
27921
|
-
await new Promise((
|
|
27972
|
+
await new Promise((resolve19) => {
|
|
27922
27973
|
server.listen(port, host, () => {
|
|
27923
27974
|
process.stdout.write(`[runner-serve] listening on ${host}:${port} (idle, awaiting job)
|
|
27924
27975
|
`);
|
|
27925
|
-
|
|
27976
|
+
resolve19();
|
|
27926
27977
|
});
|
|
27927
27978
|
});
|
|
27928
27979
|
const shutdown = (signal) => {
|
|
@@ -27991,14 +28042,14 @@ async function serve(opts) {
|
|
|
27991
28042
|
`);
|
|
27992
28043
|
const args = ["--dangerously-skip-permissions", "--model", model.model];
|
|
27993
28044
|
const child = spawn10("claude", args, { stdio: "inherit", env: editorEnv, cwd: opts.cwd });
|
|
27994
|
-
const exitCode = await new Promise((
|
|
27995
|
-
child.on("exit", (code) =>
|
|
28045
|
+
const exitCode = await new Promise((resolve19) => {
|
|
28046
|
+
child.on("exit", (code) => resolve19(code ?? 0));
|
|
27996
28047
|
child.on("error", (err) => {
|
|
27997
28048
|
process.stderr.write(`[kody serve] failed to launch Claude Code: ${err.message}
|
|
27998
28049
|
`);
|
|
27999
28050
|
process.stderr.write(` Install: https://docs.anthropic.com/claude/docs/claude-code
|
|
28000
28051
|
`);
|
|
28001
|
-
|
|
28052
|
+
resolve19(1);
|
|
28002
28053
|
});
|
|
28003
28054
|
});
|
|
28004
28055
|
killProxy();
|