@kody-ade/kody-engine 0.4.288 → 0.4.290
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/README.md +3 -7
- package/dist/bin/kody.js +108 -115
- package/dist/executables/agent-factory/prompt.md +5 -4
- package/dist/executables/types.ts +13 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -78,10 +78,6 @@ See [SECURITY.md](SECURITY.md) to report a vulnerability.
|
|
|
78
78
|
│ src/executor.ts — runs capability implementations │
|
|
79
79
|
│ .kody/capabilities/<slug>/ │
|
|
80
80
|
│ profile.json · capability.md · optional skills/scripts │
|
|
81
|
-
│ .kody/capabilities/<slug>/ │
|
|
82
|
-
│ legacy fallback: profile.json · capability.md │
|
|
83
|
-
│ .kody/executables/<name>/ │
|
|
84
|
-
│ legacy fallback: profile.json · prompt.md · *.sh │
|
|
85
81
|
│ src/scripts/*.ts — cross-cutting catalog │
|
|
86
82
|
└─────────────────────────────────────────────┘
|
|
87
83
|
```
|
|
@@ -91,10 +87,10 @@ Every top-level command is an auto-discovered capability action. The router has
|
|
|
91
87
|
after `@kody` through `config.aliases`, then falls back to the legacy-named
|
|
92
88
|
`config.defaultExecutable` / `config.defaultPrExecutable` fields as default
|
|
93
89
|
capability actions. Drop a new `.kody/capabilities/<slug>/` directory with
|
|
94
|
-
`profile.json` + `capability.md
|
|
95
|
-
|
|
90
|
+
`profile.json` + `capability.md`. Project/store `.kody/executables/` folders
|
|
91
|
+
are obsolete and are not resolver sources.
|
|
96
92
|
|
|
97
|
-
|
|
93
|
+
Capability implementation profiles are private implementation units and contain
|
|
98
94
|
**only** three kinds of files: `profile.json` (declaration), `prompt.md` (agent
|
|
99
95
|
instructions), and `.sh` scripts (mechanical side-effect work). Cross-cutting
|
|
100
96
|
TypeScript lives in [src/scripts/](src/scripts/); it can't import from
|
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.290",
|
|
19
19
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
20
20
|
license: "MIT",
|
|
21
21
|
type: "module",
|
|
@@ -1266,7 +1266,7 @@ var init_events = __esm({
|
|
|
1266
1266
|
// src/verify.ts
|
|
1267
1267
|
import { spawn } from "child_process";
|
|
1268
1268
|
function runCommand(command, cwd) {
|
|
1269
|
-
return new Promise((
|
|
1269
|
+
return new Promise((resolve10) => {
|
|
1270
1270
|
const start = Date.now();
|
|
1271
1271
|
const child = spawn(command, {
|
|
1272
1272
|
cwd,
|
|
@@ -1295,11 +1295,11 @@ function runCommand(command, cwd) {
|
|
|
1295
1295
|
child.on("exit", (code) => {
|
|
1296
1296
|
clearTimeout(timer);
|
|
1297
1297
|
const tail = Buffer.concat(buffers).toString("utf-8").slice(-TAIL_CHARS);
|
|
1298
|
-
|
|
1298
|
+
resolve10({ exitCode: code ?? -1, durationMs: Date.now() - start, tail });
|
|
1299
1299
|
});
|
|
1300
1300
|
child.on("error", (err) => {
|
|
1301
1301
|
clearTimeout(timer);
|
|
1302
|
-
|
|
1302
|
+
resolve10({ exitCode: -1, durationMs: Date.now() - start, tail: err.message });
|
|
1303
1303
|
});
|
|
1304
1304
|
});
|
|
1305
1305
|
}
|
|
@@ -1907,6 +1907,8 @@ function parseCapabilityConfig(raw) {
|
|
|
1907
1907
|
executable: stringField(raw.executable),
|
|
1908
1908
|
tickScript: stringField(raw.tickScript),
|
|
1909
1909
|
disabled: typeof raw.disabled === "boolean" ? raw.disabled : void 0,
|
|
1910
|
+
internal: typeof raw.internal === "boolean" ? raw.internal : void 0,
|
|
1911
|
+
public: typeof raw.public === "boolean" ? raw.public : void 0,
|
|
1910
1912
|
agent: stringField(raw.agent),
|
|
1911
1913
|
mentions: stringList(raw.mentions).map((m) => m.replace(/^@/, "")),
|
|
1912
1914
|
tools,
|
|
@@ -2022,7 +2024,6 @@ function getCompanyStoreAssetRoot(kind) {
|
|
|
2022
2024
|
if (!root) return null;
|
|
2023
2025
|
const folderByKind = {
|
|
2024
2026
|
capabilities: "capabilities",
|
|
2025
|
-
executables: "executables",
|
|
2026
2027
|
goals: "goals",
|
|
2027
2028
|
agents: "agents",
|
|
2028
2029
|
workflows: "workflows"
|
|
@@ -2128,15 +2129,9 @@ function getExecutablesRoot() {
|
|
|
2128
2129
|
}
|
|
2129
2130
|
return candidates[0];
|
|
2130
2131
|
}
|
|
2131
|
-
function getProjectExecutablesRoot() {
|
|
2132
|
-
return path8.join(process.cwd(), ".kody", "executables");
|
|
2133
|
-
}
|
|
2134
2132
|
function getProjectCapabilitiesRoot() {
|
|
2135
2133
|
return path8.join(process.cwd(), ".kody", "capabilities");
|
|
2136
2134
|
}
|
|
2137
|
-
function getCompanyStoreExecutablesRoot() {
|
|
2138
|
-
return getCompanyStoreAssetRoot("executables");
|
|
2139
|
-
}
|
|
2140
2135
|
function getCompanyStoreCapabilitiesRoot() {
|
|
2141
2136
|
return getCompanyStoreAssetRoot("capabilities");
|
|
2142
2137
|
}
|
|
@@ -2157,14 +2152,10 @@ function getBuiltinCapabilitiesRoot() {
|
|
|
2157
2152
|
}
|
|
2158
2153
|
function getExecutableRoots() {
|
|
2159
2154
|
const projectCapabilitiesRoot = getProjectCapabilitiesRoot();
|
|
2160
|
-
const projectExecutablesRoot = getProjectExecutablesRoot();
|
|
2161
2155
|
const storeCapabilitiesRoot = getCompanyStoreCapabilitiesRoot();
|
|
2162
|
-
const storeExecutablesRoot = getCompanyStoreExecutablesRoot();
|
|
2163
2156
|
return [
|
|
2164
2157
|
projectCapabilitiesRoot,
|
|
2165
|
-
projectExecutablesRoot,
|
|
2166
2158
|
...storeCapabilitiesRoot ? [storeCapabilitiesRoot] : [],
|
|
2167
|
-
...storeExecutablesRoot ? [storeExecutablesRoot] : [],
|
|
2168
2159
|
getExecutablesRoot()
|
|
2169
2160
|
];
|
|
2170
2161
|
}
|
|
@@ -2216,21 +2207,12 @@ function listCapabilityActions(projectCapabilitiesRoot = getProjectCapabilitiesR
|
|
|
2216
2207
|
seen.add(action.action);
|
|
2217
2208
|
out.push(action);
|
|
2218
2209
|
};
|
|
2219
|
-
const storeCapabilitiesRoot = getCompanyStoreCapabilitiesRoot();
|
|
2220
|
-
const projectExecutableRoots = [getProjectExecutablesRoot()];
|
|
2221
|
-
const storeExecutableRoot = getCompanyStoreExecutablesRoot();
|
|
2222
|
-
const storeExecutableRoots = storeExecutableRoot ? [storeExecutableRoot] : [];
|
|
2223
2210
|
for (const action of listFolderCapabilityActions(projectCapabilitiesRoot, "project-folder"))
|
|
2224
2211
|
add(action);
|
|
2225
|
-
|
|
2226
|
-
for (const action of listExecutableCapabilityActions(root, "project-executable")) add(action);
|
|
2227
|
-
}
|
|
2212
|
+
const storeCapabilitiesRoot = getCompanyStoreCapabilitiesRoot();
|
|
2228
2213
|
if (storeCapabilitiesRoot) {
|
|
2229
2214
|
for (const action of listFolderCapabilityActions(storeCapabilitiesRoot, "company-store")) add(action);
|
|
2230
2215
|
}
|
|
2231
|
-
for (const root of storeExecutableRoots) {
|
|
2232
|
-
for (const action of listExecutableCapabilityActions(root, "company-store-executable")) add(action);
|
|
2233
|
-
}
|
|
2234
2216
|
for (const action of listBuiltinCapabilityActions(getBuiltinCapabilitiesRoot())) add(action);
|
|
2235
2217
|
return out.sort((a, b) => a.action.localeCompare(b.action));
|
|
2236
2218
|
}
|
|
@@ -2294,34 +2276,6 @@ function isImplementationProfile(profilePath, requireImplementationProfile) {
|
|
|
2294
2276
|
return false;
|
|
2295
2277
|
}
|
|
2296
2278
|
}
|
|
2297
|
-
function listExecutableCapabilityActions(root, source) {
|
|
2298
|
-
if (!fs6.existsSync(root) || !fs6.statSync(root).isDirectory()) return [];
|
|
2299
|
-
const out = [];
|
|
2300
|
-
for (const ent of fs6.readdirSync(root, { withFileTypes: true })) {
|
|
2301
|
-
if (!ent.isDirectory() || !isSafeName(ent.name)) continue;
|
|
2302
|
-
const profilePath = path8.join(root, ent.name, CAPABILITY_PROFILE_FILE);
|
|
2303
|
-
if (!fs6.existsSync(profilePath) || !fs6.statSync(profilePath).isFile()) continue;
|
|
2304
|
-
try {
|
|
2305
|
-
const raw = JSON.parse(fs6.readFileSync(profilePath, "utf-8"));
|
|
2306
|
-
const action = typeof raw.action === "string" && raw.action.trim() ? raw.action.trim() : "";
|
|
2307
|
-
if (!action) continue;
|
|
2308
|
-
if (!PUBLIC_EXECUTABLE_ROLES.has(String(raw.role))) continue;
|
|
2309
|
-
if (typeof raw.kind !== "string" || !raw.kind.trim()) continue;
|
|
2310
|
-
if (!Array.isArray(raw.inputs)) continue;
|
|
2311
|
-
out.push({
|
|
2312
|
-
action,
|
|
2313
|
-
capability: ent.name,
|
|
2314
|
-
executable: ent.name,
|
|
2315
|
-
cliArgs: {},
|
|
2316
|
-
source,
|
|
2317
|
-
describe: typeof raw.describe === "string" ? raw.describe : void 0,
|
|
2318
|
-
profilePath
|
|
2319
|
-
});
|
|
2320
|
-
} catch {
|
|
2321
|
-
}
|
|
2322
|
-
}
|
|
2323
|
-
return out.sort((a, b) => a.action.localeCompare(b.action));
|
|
2324
|
-
}
|
|
2325
2279
|
function listFolderCapabilityActions(root, source) {
|
|
2326
2280
|
if (!fs6.existsSync(root) || !fs6.statSync(root).isDirectory()) return [];
|
|
2327
2281
|
const out = [];
|
|
@@ -2329,6 +2283,7 @@ function listFolderCapabilityActions(root, source) {
|
|
|
2329
2283
|
if (!isSafeName(slug2)) continue;
|
|
2330
2284
|
const capability = readCapabilityFolder(root, slug2);
|
|
2331
2285
|
if (!capability) continue;
|
|
2286
|
+
if (capability.config.internal === true || capability.config.public === false) continue;
|
|
2332
2287
|
const action = capability.config.action ?? slug2;
|
|
2333
2288
|
const { executable, cliArgs } = resolveCapabilityExecution(capability);
|
|
2334
2289
|
out.push({
|
|
@@ -2978,7 +2933,7 @@ var init_repoWorkspace = __esm({
|
|
|
2978
2933
|
defaultCloneRepo = (repo, token, dir) => {
|
|
2979
2934
|
fs7.mkdirSync(path9.dirname(dir), { recursive: true });
|
|
2980
2935
|
const authUrl = token ? `https://x-access-token:${token}@github.com/${repo}.git` : `https://github.com/${repo}.git`;
|
|
2981
|
-
return new Promise((
|
|
2936
|
+
return new Promise((resolve10, reject) => {
|
|
2982
2937
|
const child = spawn2("git", ["clone", "--depth=1", authUrl, dir], {
|
|
2983
2938
|
stdio: "inherit"
|
|
2984
2939
|
});
|
|
@@ -2994,7 +2949,7 @@ var init_repoWorkspace = __esm({
|
|
|
2994
2949
|
spawnSync("git", ["-C", dir, "config", "user.email", email]);
|
|
2995
2950
|
} catch {
|
|
2996
2951
|
}
|
|
2997
|
-
|
|
2952
|
+
resolve10();
|
|
2998
2953
|
});
|
|
2999
2954
|
child.on("error", reject);
|
|
3000
2955
|
});
|
|
@@ -3302,10 +3257,10 @@ async function runAgent(opts) {
|
|
|
3302
3257
|
let timer;
|
|
3303
3258
|
let next;
|
|
3304
3259
|
if (turnTimeoutMs > 0) {
|
|
3305
|
-
const timeoutPromise = new Promise((
|
|
3260
|
+
const timeoutPromise = new Promise((resolve10) => {
|
|
3306
3261
|
timer = setTimeout(() => {
|
|
3307
3262
|
timedOut = true;
|
|
3308
|
-
|
|
3263
|
+
resolve10({ done: true, value: void 0 });
|
|
3309
3264
|
}, turnTimeoutMs);
|
|
3310
3265
|
});
|
|
3311
3266
|
next = await Promise.race([nextPromise, timeoutPromise]);
|
|
@@ -4255,18 +4210,29 @@ function loadProfile(profilePath) {
|
|
|
4255
4210
|
if (!refPath) {
|
|
4256
4211
|
throw new ProfileError(profilePath, `capability references unknown executable '${execRef}'`);
|
|
4257
4212
|
}
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4213
|
+
if (path19.resolve(refPath) === path19.resolve(profilePath)) {
|
|
4214
|
+
} else {
|
|
4215
|
+
const base = loadProfile(refPath);
|
|
4216
|
+
return {
|
|
4217
|
+
...base,
|
|
4218
|
+
name: requireString(profilePath, r, "name"),
|
|
4219
|
+
action: typeof r.action === "string" && r.action.trim() ? r.action.trim() : void 0,
|
|
4220
|
+
implementation: execRef,
|
|
4221
|
+
executable: execRef,
|
|
4222
|
+
internal: typeof r.internal === "boolean" ? r.internal : base.internal,
|
|
4223
|
+
public: typeof r.public === "boolean" ? r.public : base.public,
|
|
4224
|
+
capabilityKind: parseCapabilityKind(r.capabilityKind) ?? base.capabilityKind,
|
|
4225
|
+
slug: typeof r.slug === "string" && r.slug.trim() ? r.slug.trim() : base.slug,
|
|
4226
|
+
title: typeof r.title === "string" && r.title.trim() ? r.title.trim() : base.title,
|
|
4227
|
+
skills: parseStringArray2(r.skills) ?? base.skills,
|
|
4228
|
+
prompt: typeof r.prompt === "string" && r.prompt.trim() ? r.prompt.trim() : base.prompt,
|
|
4229
|
+
chatTools: parseStringArray2(r.chatTools) ?? base.chatTools,
|
|
4230
|
+
describe: typeof r.describe === "string" ? r.describe : base.describe,
|
|
4231
|
+
agent: typeof r.agent === "string" && r.agent.trim() ? r.agent.trim() : base.agent,
|
|
4232
|
+
capabilityTools: parseStringArray2(r.capabilityTools ?? r.capabilityTools ?? r.tools) ?? base.capabilityTools,
|
|
4233
|
+
mentions: Array.isArray(r.mentions) ? r.mentions.map((m) => String(m).trim()).filter(Boolean) : base.mentions
|
|
4234
|
+
};
|
|
4235
|
+
}
|
|
4270
4236
|
}
|
|
4271
4237
|
const kind = r.kind === "scheduled" ? "scheduled" : "oneshot";
|
|
4272
4238
|
if (kind === "scheduled" && typeof r.schedule !== "string") {
|
|
@@ -4306,6 +4272,14 @@ function loadProfile(profilePath) {
|
|
|
4306
4272
|
action: typeof r.action === "string" && r.action.trim() ? r.action.trim() : void 0,
|
|
4307
4273
|
implementation: void 0,
|
|
4308
4274
|
executable: void 0,
|
|
4275
|
+
internal: typeof r.internal === "boolean" ? r.internal : void 0,
|
|
4276
|
+
public: typeof r.public === "boolean" ? r.public : void 0,
|
|
4277
|
+
capabilityKind: parseCapabilityKind(r.capabilityKind),
|
|
4278
|
+
slug: typeof r.slug === "string" && r.slug.trim() ? r.slug.trim() : void 0,
|
|
4279
|
+
title: typeof r.title === "string" && r.title.trim() ? r.title.trim() : void 0,
|
|
4280
|
+
skills: parseStringArray2(r.skills),
|
|
4281
|
+
prompt: typeof r.prompt === "string" && r.prompt.trim() ? r.prompt.trim() : void 0,
|
|
4282
|
+
chatTools: parseStringArray2(r.chatTools),
|
|
4309
4283
|
describe: typeof r.describe === "string" ? r.describe : "",
|
|
4310
4284
|
// Optional agent to run as. Empty/blank string → undefined (no agent).
|
|
4311
4285
|
agent: typeof r.agent === "string" && r.agent.trim() ? r.agent.trim() : void 0,
|
|
@@ -4406,6 +4380,9 @@ function parseStringArray2(raw) {
|
|
|
4406
4380
|
const values = raw.map((t) => String(t).trim()).filter(Boolean);
|
|
4407
4381
|
return values.length > 0 ? values : void 0;
|
|
4408
4382
|
}
|
|
4383
|
+
function parseCapabilityKind(raw) {
|
|
4384
|
+
return raw === "observe" || raw === "act" || raw === "verify" ? raw : void 0;
|
|
4385
|
+
}
|
|
4409
4386
|
function parseInputs(p, raw) {
|
|
4410
4387
|
if (!Array.isArray(raw)) throw new ProfileError(p, `"inputs" must be an array`);
|
|
4411
4388
|
const out = [];
|
|
@@ -4670,6 +4647,14 @@ var init_profile = __esm({
|
|
|
4670
4647
|
"implementations",
|
|
4671
4648
|
"executable",
|
|
4672
4649
|
"executables",
|
|
4650
|
+
"internal",
|
|
4651
|
+
"public",
|
|
4652
|
+
"capabilityKind",
|
|
4653
|
+
"slug",
|
|
4654
|
+
"title",
|
|
4655
|
+
"skills",
|
|
4656
|
+
"prompt",
|
|
4657
|
+
"chatTools",
|
|
4673
4658
|
"agent",
|
|
4674
4659
|
"every",
|
|
4675
4660
|
"capabilityTools",
|
|
@@ -12961,7 +12946,7 @@ function retryDelaysMs() {
|
|
|
12961
12946
|
}
|
|
12962
12947
|
function sleep(ms) {
|
|
12963
12948
|
if (ms <= 0) return Promise.resolve();
|
|
12964
|
-
return new Promise((
|
|
12949
|
+
return new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
12965
12950
|
}
|
|
12966
12951
|
async function fetchGoalStateWithRetry(config, goalId, cwd) {
|
|
12967
12952
|
let state = fetchGoalState(config, goalId, cwd);
|
|
@@ -13798,6 +13783,11 @@ function normalizeBundleFiles(ctx, bundle) {
|
|
|
13798
13783
|
if (!relativePath) {
|
|
13799
13784
|
throw new Error(`openAgentFactoryStatePr: files[${index}].path must point to a state repo file`);
|
|
13800
13785
|
}
|
|
13786
|
+
if (relativePath === "executables" || relativePath.startsWith("executables/")) {
|
|
13787
|
+
throw new Error(
|
|
13788
|
+
`openAgentFactoryStatePr: files[${index}].path uses obsolete executables storage; use capabilities/<slug>/ instead`
|
|
13789
|
+
);
|
|
13790
|
+
}
|
|
13801
13791
|
if (seen.has(relativePath)) {
|
|
13802
13792
|
throw new Error(`openAgentFactoryStatePr: duplicate generated file path: ${relativePath}`);
|
|
13803
13793
|
}
|
|
@@ -15637,7 +15627,7 @@ var init_previewBuildHelpers = __esm({
|
|
|
15637
15627
|
// src/scripts/previewBuildRun.ts
|
|
15638
15628
|
import { spawn as spawn4 } from "child_process";
|
|
15639
15629
|
async function runCmd(cmd, args, opts = {}) {
|
|
15640
|
-
await new Promise((
|
|
15630
|
+
await new Promise((resolve10, reject) => {
|
|
15641
15631
|
const child = spawn4(cmd, args, {
|
|
15642
15632
|
cwd: opts.cwd,
|
|
15643
15633
|
env: { ...process.env, ...opts.env ?? {} },
|
|
@@ -15649,7 +15639,7 @@ async function runCmd(cmd, args, opts = {}) {
|
|
|
15649
15639
|
}
|
|
15650
15640
|
child.on("error", reject);
|
|
15651
15641
|
child.on("close", (code) => {
|
|
15652
|
-
if (code === 0)
|
|
15642
|
+
if (code === 0) resolve10();
|
|
15653
15643
|
else reject(new Error(`${cmd} ${args.join(" ")} exited ${code}`));
|
|
15654
15644
|
});
|
|
15655
15645
|
});
|
|
@@ -16773,7 +16763,7 @@ function stripAnsi2(s) {
|
|
|
16773
16763
|
return s.replace(ANSI_RE2, "");
|
|
16774
16764
|
}
|
|
16775
16765
|
function runCommand2(command, cwd) {
|
|
16776
|
-
return new Promise((
|
|
16766
|
+
return new Promise((resolve10) => {
|
|
16777
16767
|
const child = spawn5(command, {
|
|
16778
16768
|
cwd,
|
|
16779
16769
|
shell: true,
|
|
@@ -16800,11 +16790,11 @@ function runCommand2(command, cwd) {
|
|
|
16800
16790
|
}, TEST_TIMEOUT_MS);
|
|
16801
16791
|
child.on("exit", (code) => {
|
|
16802
16792
|
clearTimeout(timer);
|
|
16803
|
-
|
|
16793
|
+
resolve10({ exitCode: code ?? -1, output: Buffer.concat(buffers).toString("utf-8") });
|
|
16804
16794
|
});
|
|
16805
16795
|
child.on("error", (err) => {
|
|
16806
16796
|
clearTimeout(timer);
|
|
16807
|
-
|
|
16797
|
+
resolve10({ exitCode: -1, output: err.message });
|
|
16808
16798
|
});
|
|
16809
16799
|
});
|
|
16810
16800
|
}
|
|
@@ -17209,21 +17199,21 @@ function lineStream(stream) {
|
|
|
17209
17199
|
tryDeliver();
|
|
17210
17200
|
});
|
|
17211
17201
|
return {
|
|
17212
|
-
next: (timeoutMs) => new Promise((
|
|
17202
|
+
next: (timeoutMs) => new Promise((resolve10) => {
|
|
17213
17203
|
if (queue.length > 0) {
|
|
17214
|
-
|
|
17204
|
+
resolve10(queue.shift());
|
|
17215
17205
|
return;
|
|
17216
17206
|
}
|
|
17217
17207
|
if (ended) {
|
|
17218
|
-
|
|
17208
|
+
resolve10(null);
|
|
17219
17209
|
return;
|
|
17220
17210
|
}
|
|
17221
|
-
waiter =
|
|
17211
|
+
waiter = resolve10;
|
|
17222
17212
|
const t = setTimeout(
|
|
17223
17213
|
() => {
|
|
17224
|
-
if (waiter ===
|
|
17214
|
+
if (waiter === resolve10) {
|
|
17225
17215
|
waiter = null;
|
|
17226
|
-
|
|
17216
|
+
resolve10(null);
|
|
17227
17217
|
}
|
|
17228
17218
|
},
|
|
17229
17219
|
Math.max(0, timeoutMs)
|
|
@@ -17712,7 +17702,6 @@ var init_stateWorkspace = __esm({
|
|
|
17712
17702
|
"use strict";
|
|
17713
17703
|
init_stateRepo();
|
|
17714
17704
|
DIR_MAPPINGS = [
|
|
17715
|
-
{ stateDir: "executables", localDir: path41.join(".kody", "executables") },
|
|
17716
17705
|
{ stateDir: "capabilities", localDir: path41.join(".kody", "capabilities") },
|
|
17717
17706
|
{ stateDir: "agents", localDir: path41.join(".kody", "agents") },
|
|
17718
17707
|
{ stateDir: "context", localDir: path41.join(".kody", "context") },
|
|
@@ -18513,14 +18502,14 @@ async function runShellEntry(entry, ctx, profile) {
|
|
|
18513
18502
|
let killTimer;
|
|
18514
18503
|
let escalateTimer;
|
|
18515
18504
|
const result = await new Promise(
|
|
18516
|
-
(
|
|
18505
|
+
(resolve10) => {
|
|
18517
18506
|
let settled = false;
|
|
18518
18507
|
const settle = (code, signal, spawnErr) => {
|
|
18519
18508
|
if (settled) return;
|
|
18520
18509
|
settled = true;
|
|
18521
18510
|
if (killTimer) clearTimeout(killTimer);
|
|
18522
18511
|
if (escalateTimer) clearTimeout(escalateTimer);
|
|
18523
|
-
|
|
18512
|
+
resolve10({ code, signal, spawnErr });
|
|
18524
18513
|
};
|
|
18525
18514
|
child.on("error", (err) => settle(null, null, err));
|
|
18526
18515
|
child.on("close", (code, signal) => settle(code, signal));
|
|
@@ -18781,7 +18770,7 @@ async function runJob(job, base) {
|
|
|
18781
18770
|
}
|
|
18782
18771
|
const workflow = capabilityContext?.config.workflow ?? workflowContext?.config.workflow;
|
|
18783
18772
|
const workflowIdentity = valid.workflow ?? capabilityIdentity ?? workflowContext?.slug;
|
|
18784
|
-
const capabilitySelectedExecutable = resolvedCapability?.executable ?? capabilityContext?.config.executable ?? capabilityContext?.config.executables?.[0] ?? (capabilityContext?.config.tickScript ? "capability-tick-scripted" : void 0);
|
|
18773
|
+
const capabilitySelectedExecutable = resolvedCapability?.executable ?? capabilityContext?.config.executable ?? capabilityContext?.config.executables?.[0] ?? (capabilityContext?.config.role ? capabilityContext.slug : void 0) ?? (capabilityContext?.config.tickScript ? "capability-tick-scripted" : void 0);
|
|
18785
18774
|
const profileName = valid.executable ?? capabilitySelectedExecutable;
|
|
18786
18775
|
if (workflow && shouldRunCapabilityWorkflow(valid, workflow, workflowIdentity, capabilitySelectedExecutable, base)) {
|
|
18787
18776
|
const workflowCapability = capabilityContext ?? workflowContext;
|
|
@@ -20860,6 +20849,10 @@ async function runCi(argv) {
|
|
|
20860
20849
|
`);
|
|
20861
20850
|
return 64;
|
|
20862
20851
|
}
|
|
20852
|
+
if (process.env.GITHUB_EVENT_NAME === "issue_comment") {
|
|
20853
|
+
process.stdout.write("\u2192 kody: no action for event issue_comment \u2014 exiting cleanly\n");
|
|
20854
|
+
return 0;
|
|
20855
|
+
}
|
|
20863
20856
|
process.stdout.write(`\u2192 kody: no action for event ${process.env.GITHUB_EVENT_NAME} \u2014 checking scheduled watches
|
|
20864
20857
|
`);
|
|
20865
20858
|
return runScheduledFanOut(cwd, args, { force: false });
|
|
@@ -21246,17 +21239,17 @@ function authOk(req, expected) {
|
|
|
21246
21239
|
return false;
|
|
21247
21240
|
}
|
|
21248
21241
|
function readJsonBody(req) {
|
|
21249
|
-
return new Promise((
|
|
21242
|
+
return new Promise((resolve10, reject) => {
|
|
21250
21243
|
const chunks = [];
|
|
21251
21244
|
req.on("data", (c) => chunks.push(c));
|
|
21252
21245
|
req.on("end", () => {
|
|
21253
21246
|
const raw = Buffer.concat(chunks).toString("utf-8");
|
|
21254
21247
|
if (!raw.trim()) {
|
|
21255
|
-
|
|
21248
|
+
resolve10({});
|
|
21256
21249
|
return;
|
|
21257
21250
|
}
|
|
21258
21251
|
try {
|
|
21259
|
-
|
|
21252
|
+
resolve10(JSON.parse(raw));
|
|
21260
21253
|
} catch (err) {
|
|
21261
21254
|
reject(err instanceof Error ? err : new Error(String(err)));
|
|
21262
21255
|
}
|
|
@@ -21611,11 +21604,11 @@ async function brainServe(opts) {
|
|
|
21611
21604
|
model,
|
|
21612
21605
|
litellmUrl
|
|
21613
21606
|
});
|
|
21614
|
-
await new Promise((
|
|
21607
|
+
await new Promise((resolve10) => {
|
|
21615
21608
|
server.listen(port, "0.0.0.0", () => {
|
|
21616
21609
|
process.stdout.write(`[brain-serve] listening on 0.0.0.0:${port} (cwd=${opts.cwd})
|
|
21617
21610
|
`);
|
|
21618
|
-
|
|
21611
|
+
resolve10();
|
|
21619
21612
|
});
|
|
21620
21613
|
});
|
|
21621
21614
|
const shutdown = (signal) => {
|
|
@@ -21868,14 +21861,14 @@ async function startBrainProxy(opts) {
|
|
|
21868
21861
|
const { httpServer, handler } = buildBrainProxy(opts);
|
|
21869
21862
|
const port = opts.port ?? 0;
|
|
21870
21863
|
const host = opts.host ?? "127.0.0.1";
|
|
21871
|
-
await new Promise((
|
|
21864
|
+
await new Promise((resolve10) => httpServer.listen(port, host, () => resolve10()));
|
|
21872
21865
|
const addr = httpServer.address();
|
|
21873
21866
|
return {
|
|
21874
21867
|
httpServer,
|
|
21875
21868
|
port: addr.port,
|
|
21876
21869
|
url: `http://${host}:${addr.port}`,
|
|
21877
|
-
stop: () => new Promise((
|
|
21878
|
-
httpServer.close(() =>
|
|
21870
|
+
stop: () => new Promise((resolve10) => {
|
|
21871
|
+
httpServer.close(() => resolve10());
|
|
21879
21872
|
}),
|
|
21880
21873
|
handler
|
|
21881
21874
|
};
|
|
@@ -22025,23 +22018,23 @@ function buildMcpHttpServer(opts) {
|
|
|
22025
22018
|
httpServer,
|
|
22026
22019
|
routes,
|
|
22027
22020
|
port,
|
|
22028
|
-
stop: () => new Promise((
|
|
22021
|
+
stop: () => new Promise((resolve10) => {
|
|
22029
22022
|
let pending = transports.size;
|
|
22030
22023
|
if (pending === 0) {
|
|
22031
|
-
httpServer.close(() =>
|
|
22024
|
+
httpServer.close(() => resolve10());
|
|
22032
22025
|
return;
|
|
22033
22026
|
}
|
|
22034
22027
|
for (const transport of transports.values()) {
|
|
22035
22028
|
void transport.close().finally(() => {
|
|
22036
22029
|
pending--;
|
|
22037
|
-
if (pending === 0) httpServer.close(() =>
|
|
22030
|
+
if (pending === 0) httpServer.close(() => resolve10());
|
|
22038
22031
|
});
|
|
22039
22032
|
}
|
|
22040
22033
|
})
|
|
22041
22034
|
};
|
|
22042
22035
|
}
|
|
22043
22036
|
function listenMcpHttpServer(server, host = "127.0.0.1") {
|
|
22044
|
-
return new Promise((
|
|
22037
|
+
return new Promise((resolve10, reject) => {
|
|
22045
22038
|
server.httpServer.once("error", reject);
|
|
22046
22039
|
server.httpServer.listen(server.port, host, () => {
|
|
22047
22040
|
server.httpServer.off("error", reject);
|
|
@@ -22049,7 +22042,7 @@ function listenMcpHttpServer(server, host = "127.0.0.1") {
|
|
|
22049
22042
|
if (addr && typeof addr === "object") {
|
|
22050
22043
|
server.port = addr.port;
|
|
22051
22044
|
}
|
|
22052
|
-
|
|
22045
|
+
resolve10();
|
|
22053
22046
|
});
|
|
22054
22047
|
});
|
|
22055
22048
|
}
|
|
@@ -22190,7 +22183,7 @@ async function waitForNextUserMessage(opts) {
|
|
|
22190
22183
|
}
|
|
22191
22184
|
}
|
|
22192
22185
|
function sleep3(ms) {
|
|
22193
|
-
return new Promise((
|
|
22186
|
+
return new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
22194
22187
|
}
|
|
22195
22188
|
function currentBranch(cwd) {
|
|
22196
22189
|
try {
|
|
@@ -23293,14 +23286,14 @@ function sendJson2(res, status, body) {
|
|
|
23293
23286
|
res.end(JSON.stringify(body));
|
|
23294
23287
|
}
|
|
23295
23288
|
function readJsonBody2(req) {
|
|
23296
|
-
return new Promise((
|
|
23289
|
+
return new Promise((resolve10, reject) => {
|
|
23297
23290
|
const chunks = [];
|
|
23298
23291
|
req.on("data", (c) => chunks.push(c));
|
|
23299
23292
|
req.on("end", () => {
|
|
23300
23293
|
const raw = Buffer.concat(chunks).toString("utf-8");
|
|
23301
|
-
if (!raw.trim()) return
|
|
23294
|
+
if (!raw.trim()) return resolve10({});
|
|
23302
23295
|
try {
|
|
23303
|
-
|
|
23296
|
+
resolve10(JSON.parse(raw));
|
|
23304
23297
|
} catch (err) {
|
|
23305
23298
|
reject(err instanceof Error ? err : new Error(String(err)));
|
|
23306
23299
|
}
|
|
@@ -23482,10 +23475,10 @@ async function poolServe() {
|
|
|
23482
23475
|
}
|
|
23483
23476
|
});
|
|
23484
23477
|
const apiHost = process.env.POOL_API_HOST ?? "::";
|
|
23485
|
-
await new Promise((
|
|
23478
|
+
await new Promise((resolve10) => {
|
|
23486
23479
|
server.listen(apiPort, apiHost, () => {
|
|
23487
23480
|
log(`listening on ${apiHost}:${apiPort} (min=${min}, app=${app}, region=${region})`);
|
|
23488
|
-
|
|
23481
|
+
resolve10();
|
|
23489
23482
|
});
|
|
23490
23483
|
});
|
|
23491
23484
|
const shutdown = (signal) => {
|
|
@@ -23524,17 +23517,17 @@ function authOk2(req, expected) {
|
|
|
23524
23517
|
return false;
|
|
23525
23518
|
}
|
|
23526
23519
|
function readJsonBody3(req) {
|
|
23527
|
-
return new Promise((
|
|
23520
|
+
return new Promise((resolve10, reject) => {
|
|
23528
23521
|
const chunks = [];
|
|
23529
23522
|
req.on("data", (c) => chunks.push(c));
|
|
23530
23523
|
req.on("end", () => {
|
|
23531
23524
|
const raw = Buffer.concat(chunks).toString("utf-8");
|
|
23532
23525
|
if (!raw.trim()) {
|
|
23533
|
-
|
|
23526
|
+
resolve10({});
|
|
23534
23527
|
return;
|
|
23535
23528
|
}
|
|
23536
23529
|
try {
|
|
23537
|
-
|
|
23530
|
+
resolve10(JSON.parse(raw));
|
|
23538
23531
|
} catch (err) {
|
|
23539
23532
|
reject(err instanceof Error ? err : new Error(String(err)));
|
|
23540
23533
|
}
|
|
@@ -23668,13 +23661,13 @@ async function defaultRunJob(job) {
|
|
|
23668
23661
|
...interactive && job.idleExitMs ? { KODY_IDLE_EXIT_MS: String(job.idleExitMs) } : {},
|
|
23669
23662
|
...interactive && job.hardCapMs ? { KODY_HARD_CAP_MS: String(job.hardCapMs) } : {}
|
|
23670
23663
|
};
|
|
23671
|
-
const run = (cmd, args, cwd) => new Promise((
|
|
23664
|
+
const run = (cmd, args, cwd) => new Promise((resolve10) => {
|
|
23672
23665
|
const child = spawn8(cmd, args, { stdio: "inherit", env: childEnv, cwd });
|
|
23673
|
-
child.on("exit", (code) =>
|
|
23666
|
+
child.on("exit", (code) => resolve10(code ?? 0));
|
|
23674
23667
|
child.on("error", (err) => {
|
|
23675
23668
|
process.stderr.write(`[runner-serve] ${cmd} failed: ${err.message}
|
|
23676
23669
|
`);
|
|
23677
|
-
|
|
23670
|
+
resolve10(1);
|
|
23678
23671
|
});
|
|
23679
23672
|
});
|
|
23680
23673
|
process.stdout.write(`[runner-serve] job ${job.jobId}: cloning ${job.repo}@${branch}
|
|
@@ -23750,11 +23743,11 @@ async function runnerServe() {
|
|
|
23750
23743
|
const port = Number(process.env.PORT ?? DEFAULT_PORT2);
|
|
23751
23744
|
const server = buildServer2({ apiKey });
|
|
23752
23745
|
const host = process.env.RUNNER_HOST ?? "::";
|
|
23753
|
-
await new Promise((
|
|
23746
|
+
await new Promise((resolve10) => {
|
|
23754
23747
|
server.listen(port, host, () => {
|
|
23755
23748
|
process.stdout.write(`[runner-serve] listening on ${host}:${port} (idle, awaiting job)
|
|
23756
23749
|
`);
|
|
23757
|
-
|
|
23750
|
+
resolve10();
|
|
23758
23751
|
});
|
|
23759
23752
|
});
|
|
23760
23753
|
const shutdown = (signal) => {
|
|
@@ -23823,14 +23816,14 @@ async function serve(opts) {
|
|
|
23823
23816
|
`);
|
|
23824
23817
|
const args = ["--dangerously-skip-permissions", "--model", model.model];
|
|
23825
23818
|
const child = spawn9("claude", args, { stdio: "inherit", env: editorEnv, cwd: opts.cwd });
|
|
23826
|
-
const exitCode = await new Promise((
|
|
23827
|
-
child.on("exit", (code) =>
|
|
23819
|
+
const exitCode = await new Promise((resolve10) => {
|
|
23820
|
+
child.on("exit", (code) => resolve10(code ?? 0));
|
|
23828
23821
|
child.on("error", (err) => {
|
|
23829
23822
|
process.stderr.write(`[kody serve] failed to launch Claude Code: ${err.message}
|
|
23830
23823
|
`);
|
|
23831
23824
|
process.stderr.write(` Install: https://docs.anthropic.com/claude/docs/claude-code
|
|
23832
23825
|
`);
|
|
23833
|
-
|
|
23826
|
+
resolve10(1);
|
|
23834
23827
|
});
|
|
23835
23828
|
});
|
|
23836
23829
|
killProxy();
|
|
@@ -18,7 +18,7 @@ You are Kody's agent factory. Convert the operator request into review-ready Kod
|
|
|
18
18
|
|
|
19
19
|
# Task
|
|
20
20
|
|
|
21
|
-
Design the smallest Kody model structure that satisfies the request. You may create or assemble simple
|
|
21
|
+
Design the smallest Kody model structure that satisfies the request. You may create or assemble simple capability implementation profiles, capabilities, loops, goals, and agents.
|
|
22
22
|
|
|
23
23
|
Use the current Kody vocabulary:
|
|
24
24
|
|
|
@@ -31,7 +31,7 @@ Use the current Kody vocabulary:
|
|
|
31
31
|
Use current storage names when producing files:
|
|
32
32
|
|
|
33
33
|
- capability: capability contract, public action ownership, kind, agent, cadence, and output contract
|
|
34
|
-
-
|
|
34
|
+
- implementation profile: capability implementation stored under `capabilities/<slug>/`
|
|
35
35
|
|
|
36
36
|
# Boundaries
|
|
37
37
|
|
|
@@ -40,7 +40,8 @@ Use current storage names when producing files:
|
|
|
40
40
|
- Do not activate generated definitions yourself.
|
|
41
41
|
- Do not create a consumer-repo PR.
|
|
42
42
|
- The deterministic postflight will open a review PR in the configured state repo under the configured state path.
|
|
43
|
-
- Put generated file paths relative to the configured state path, for example `
|
|
43
|
+
- Put generated file paths relative to the configured state path, for example `capabilities/...`, `agents/...`, `goals/...`, or `memory/...`.
|
|
44
|
+
- Do not create `executables/...` paths. External executables are obsolete; implementation profiles live in capability folders.
|
|
44
45
|
- Produce complete file contents. Do not describe patches.
|
|
45
46
|
- Prefer a small bundle over a broad framework. Include assumptions in the summary.
|
|
46
47
|
|
|
@@ -59,7 +60,7 @@ PR_SUMMARY:
|
|
|
59
60
|
"summary": "human explanation and assumptions",
|
|
60
61
|
"files": [
|
|
61
62
|
{
|
|
62
|
-
"path": "
|
|
63
|
+
"path": "capabilities/example/profile.json",
|
|
63
64
|
"content": "{\n \"name\": \"example\"\n}\n"
|
|
64
65
|
}
|
|
65
66
|
]
|
|
@@ -56,6 +56,18 @@ export interface Profile {
|
|
|
56
56
|
executable?: string
|
|
57
57
|
implementations?: string[]
|
|
58
58
|
executables?: string[]
|
|
59
|
+
/** Hide a capability implementation profile from public action discovery. */
|
|
60
|
+
internal?: boolean
|
|
61
|
+
/** Explicit public-action flag for capability profiles. */
|
|
62
|
+
public?: boolean
|
|
63
|
+
/** Public capability output class when the profile also serves as a capability contract. */
|
|
64
|
+
capabilityKind?: "observe" | "act" | "verify"
|
|
65
|
+
/** Optional dashboard-facing capability metadata. The executor does not act on these fields. */
|
|
66
|
+
slug?: string
|
|
67
|
+
title?: string
|
|
68
|
+
skills?: string[]
|
|
69
|
+
prompt?: string
|
|
70
|
+
chatTools?: string[]
|
|
59
71
|
/**
|
|
60
72
|
* Execution model — orthogonal to `role`.
|
|
61
73
|
* `oneshot` (default): single invocation on demand.
|
|
@@ -160,7 +172,7 @@ export interface Profile {
|
|
|
160
172
|
* preflight runs. composePrompt prefers these over a fresh disk read so the
|
|
161
173
|
* template survives working-tree churn from runFlow's branch setup — on the CI
|
|
162
174
|
* runner a branch checkout can drop the tracked-but-ignore-negated
|
|
163
|
-
* `.kody/
|
|
175
|
+
* `.kody/capabilities/<name>/` dir, and reading prompt.md afterwards fails with
|
|
164
176
|
* ENOENT even though profile.json (read here, earlier) loaded fine.
|
|
165
177
|
*/
|
|
166
178
|
promptTemplates?: Record<string, string>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kody-ade/kody-engine",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.290",
|
|
4
4
|
"description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|