@kody-ade/kody-engine 0.4.393 → 0.4.395
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 +111 -10
- package/package.json +25 -24
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.395",
|
|
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",
|
|
@@ -3921,6 +3921,25 @@ function createStateBackendFromEnv(env = process.env, client) {
|
|
|
3921
3921
|
entry
|
|
3922
3922
|
});
|
|
3923
3923
|
},
|
|
3924
|
+
async saveAgencyRun(tenantId, runId, subjectType, subjectId, run, updatedAt) {
|
|
3925
|
+
await transport.mutation(anyApi.agencyRuns.save, {
|
|
3926
|
+
tenantId: requireTenant(tenantId),
|
|
3927
|
+
runId: requireNonEmpty(runId, "runId"),
|
|
3928
|
+
subjectType,
|
|
3929
|
+
subjectId: requireNonEmpty(subjectId, "subjectId"),
|
|
3930
|
+
run,
|
|
3931
|
+
updatedAt
|
|
3932
|
+
});
|
|
3933
|
+
},
|
|
3934
|
+
async appendRunEvent(tenantId, runId, goalId, event, time) {
|
|
3935
|
+
await transport.mutation(anyApi.runEvents.append, {
|
|
3936
|
+
tenantId: requireTenant(tenantId),
|
|
3937
|
+
runId: requireNonEmpty(runId, "runId"),
|
|
3938
|
+
...goalId ? { goalId: requireNonEmpty(goalId, "goalId") } : {},
|
|
3939
|
+
event,
|
|
3940
|
+
time: requireNonEmpty(time, "time")
|
|
3941
|
+
});
|
|
3942
|
+
},
|
|
3924
3943
|
async saveReport(tenantId, slug, runId, title, body, meta, updatedAt) {
|
|
3925
3944
|
await transport.mutation(anyApi.reports.save, {
|
|
3926
3945
|
tenantId: requireTenant(tenantId),
|
|
@@ -3931,6 +3950,32 @@ function createStateBackendFromEnv(env = process.env, client) {
|
|
|
3931
3950
|
meta,
|
|
3932
3951
|
updatedAt
|
|
3933
3952
|
});
|
|
3953
|
+
},
|
|
3954
|
+
async listIntents(tenantId) {
|
|
3955
|
+
const result = await transport.query(anyApi.intents.list, { tenantId: requireTenant(tenantId) });
|
|
3956
|
+
return Array.isArray(result) ? result : [];
|
|
3957
|
+
},
|
|
3958
|
+
async getIntent(tenantId, intentId) {
|
|
3959
|
+
const result = await transport.query(anyApi.intents.get, {
|
|
3960
|
+
tenantId: requireTenant(tenantId),
|
|
3961
|
+
intentId: requireNonEmpty(intentId, "intentId")
|
|
3962
|
+
});
|
|
3963
|
+
return result ?? null;
|
|
3964
|
+
},
|
|
3965
|
+
async saveIntent(tenantId, intentId, intent, updatedAt) {
|
|
3966
|
+
await transport.mutation(anyApi.intents.save, {
|
|
3967
|
+
tenantId: requireTenant(tenantId),
|
|
3968
|
+
intentId: requireNonEmpty(intentId, "intentId"),
|
|
3969
|
+
intent,
|
|
3970
|
+
updatedAt
|
|
3971
|
+
});
|
|
3972
|
+
},
|
|
3973
|
+
async appendIntentDecision(tenantId, intentId, decision) {
|
|
3974
|
+
await transport.mutation(anyApi.intents.appendDecision, {
|
|
3975
|
+
tenantId: requireTenant(tenantId),
|
|
3976
|
+
intentId: requireNonEmpty(intentId, "intentId"),
|
|
3977
|
+
decision
|
|
3978
|
+
});
|
|
3934
3979
|
}
|
|
3935
3980
|
};
|
|
3936
3981
|
}
|
|
@@ -6984,15 +7029,36 @@ function upsertRunIndexRowBestEffort(config, cwd, row) {
|
|
|
6984
7029
|
`);
|
|
6985
7030
|
}
|
|
6986
7031
|
}
|
|
7032
|
+
async function upsertRunIndexRowBestEffortAsync(config, cwd, row) {
|
|
7033
|
+
if (!row) return;
|
|
7034
|
+
const tenantId = tenantIdForRun(config);
|
|
7035
|
+
const backendConfigured = Boolean(process.env.CONVEX_URL?.trim() && process.env.KODY_SERVICE_KEY?.trim() && tenantId);
|
|
7036
|
+
if (backendConfigured) {
|
|
7037
|
+
const backend = createStateBackendFromEnv();
|
|
7038
|
+
await backend.saveAgencyRun(
|
|
7039
|
+
tenantId,
|
|
7040
|
+
row.id,
|
|
7041
|
+
row.subjectType,
|
|
7042
|
+
row.subjectId,
|
|
7043
|
+
row,
|
|
7044
|
+
row.updatedAt
|
|
7045
|
+
);
|
|
7046
|
+
return;
|
|
7047
|
+
}
|
|
7048
|
+
if (process.env.GITHUB_ACTIONS === "true") {
|
|
7049
|
+
throw new Error("Convex backend is required for the run index in GitHub Actions");
|
|
7050
|
+
}
|
|
7051
|
+
upsertRunIndexRowBestEffort(config, cwd, row);
|
|
7052
|
+
}
|
|
6987
7053
|
function stageRunIndexFinalization(data, row) {
|
|
6988
7054
|
if (!row) return;
|
|
6989
7055
|
const rows = stagedRunIndexRows(data);
|
|
6990
7056
|
rows[row.id] = row;
|
|
6991
7057
|
}
|
|
6992
|
-
function
|
|
7058
|
+
async function finalizeStagedRunIndexRowsAsync(config, cwd, data, result) {
|
|
6993
7059
|
const rows = stagedRunIndexRows(data);
|
|
6994
7060
|
for (const row of Object.values(rows)) {
|
|
6995
|
-
|
|
7061
|
+
await upsertRunIndexRowBestEffortAsync(config, cwd, finalizedRunIndexRow(row, result));
|
|
6996
7062
|
}
|
|
6997
7063
|
data[STAGED_RUN_INDEX_ROWS_KEY] = {};
|
|
6998
7064
|
}
|
|
@@ -7190,6 +7256,10 @@ function isConflict(err) {
|
|
|
7190
7256
|
const msg = err instanceof Error ? err.message : String(err);
|
|
7191
7257
|
return /HTTP 409/i.test(msg) || /HTTP 422/i.test(msg) || /does not match|is at|but expected/i.test(msg);
|
|
7192
7258
|
}
|
|
7259
|
+
function tenantIdForRun(config) {
|
|
7260
|
+
if (config.github?.owner && config.github.repo) return `${config.github.owner}/${config.github.repo}`;
|
|
7261
|
+
return process.env.GITHUB_REPOSITORY?.trim() || void 0;
|
|
7262
|
+
}
|
|
7193
7263
|
function recordValue2(value) {
|
|
7194
7264
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
7195
7265
|
}
|
|
@@ -7206,6 +7276,7 @@ var RUN_INDEX_PATH, MAX_RUNS, STAGED_RUN_INDEX_ROWS_KEY;
|
|
|
7206
7276
|
var init_runIndex = __esm({
|
|
7207
7277
|
"src/runIndex.ts"() {
|
|
7208
7278
|
"use strict";
|
|
7279
|
+
init_state_backend();
|
|
7209
7280
|
init_stateRepo();
|
|
7210
7281
|
RUN_INDEX_PATH = "runs/index.json";
|
|
7211
7282
|
MAX_RUNS = 200;
|
|
@@ -8195,9 +8266,14 @@ async function flushGoalRunLogEventsAsync(config, cwd, data) {
|
|
|
8195
8266
|
for (const [goalId, log2] of Object.entries(goalRunLogs(data))) {
|
|
8196
8267
|
if (log2.events.length === 0) continue;
|
|
8197
8268
|
const enrichedEvents = log2.events.map((event) => enrichGoalRunLogEvent(config, data, log2.path, event));
|
|
8269
|
+
const row = runIndexRowFromGoalEvents(goalId, log2.path, enrichedEvents);
|
|
8270
|
+
if (!row) continue;
|
|
8198
8271
|
for (const event of enrichedEvents) {
|
|
8199
8272
|
await backend.appendDailyLog(tenantId, "events", event.time.slice(0, 10), event);
|
|
8273
|
+
await backend.appendRunEvent(tenantId, row.id, goalId, event, event.time);
|
|
8200
8274
|
}
|
|
8275
|
+
await upsertRunIndexRowBestEffortAsync(config, cwd, row);
|
|
8276
|
+
stageRunIndexFinalization(data, row);
|
|
8201
8277
|
log2.events = [];
|
|
8202
8278
|
}
|
|
8203
8279
|
}
|
|
@@ -15010,6 +15086,30 @@ function listCompanyIntents(config, cwd) {
|
|
|
15010
15086
|
}
|
|
15011
15087
|
return records.sort((a, b) => a.intent.priority - b.intent.priority || a.id.localeCompare(b.id));
|
|
15012
15088
|
}
|
|
15089
|
+
function backendTenant2(config) {
|
|
15090
|
+
const owner = config.github?.owner?.trim() || process.env.GITHUB_REPOSITORY?.split("/")[0]?.trim();
|
|
15091
|
+
const repo = config.github?.repo?.trim() || process.env.GITHUB_REPOSITORY?.split("/")[1]?.trim();
|
|
15092
|
+
return owner && repo ? `${owner}/${repo}` : null;
|
|
15093
|
+
}
|
|
15094
|
+
function backendEnabled2(config) {
|
|
15095
|
+
return Boolean(process.env.CONVEX_URL?.trim() && process.env.KODY_SERVICE_KEY?.trim() && backendTenant2(config));
|
|
15096
|
+
}
|
|
15097
|
+
function backendRequired2() {
|
|
15098
|
+
return process.env.GITHUB_ACTIONS === "true";
|
|
15099
|
+
}
|
|
15100
|
+
async function listCompanyIntentsAsync(config, cwd) {
|
|
15101
|
+
const tenantId = backendTenant2(config);
|
|
15102
|
+
if (backendEnabled2(config) && tenantId) {
|
|
15103
|
+
const records = await createStateBackendFromEnv().listIntents(tenantId);
|
|
15104
|
+
return records.filter((record) => isCompanyIntentId(record.intentId)).map((record) => ({
|
|
15105
|
+
id: record.intentId,
|
|
15106
|
+
path: `convex:intents/${record.intentId}`,
|
|
15107
|
+
intent: normalizeCompanyIntent(`convex:intents/${record.intentId}`, record.intent)
|
|
15108
|
+
})).sort((a, b) => a.intent.priority - b.intent.priority || a.id.localeCompare(b.id));
|
|
15109
|
+
}
|
|
15110
|
+
if (backendRequired2()) throw new Error("Convex backend is required for company intents in GitHub Actions");
|
|
15111
|
+
return listCompanyIntents(config, cwd);
|
|
15112
|
+
}
|
|
15013
15113
|
async function listCompanyPortfolio(config, cwd) {
|
|
15014
15114
|
const goals = [];
|
|
15015
15115
|
for (const id of await listGoalStateIdsAsync(config, cwd)) {
|
|
@@ -15075,6 +15175,7 @@ var init_companyIntent = __esm({
|
|
|
15075
15175
|
"use strict";
|
|
15076
15176
|
init_state2();
|
|
15077
15177
|
init_stateStore();
|
|
15178
|
+
init_state_backend();
|
|
15078
15179
|
init_stateRepo();
|
|
15079
15180
|
SLUG_RE = /^[a-z][a-z0-9-]{0,63}$/;
|
|
15080
15181
|
}
|
|
@@ -15087,7 +15188,7 @@ var init_loadCompanyIntents = __esm({
|
|
|
15087
15188
|
"use strict";
|
|
15088
15189
|
init_companyIntent();
|
|
15089
15190
|
loadCompanyIntents = async (ctx) => {
|
|
15090
|
-
const intents =
|
|
15191
|
+
const intents = await listCompanyIntentsAsync(ctx.config, ctx.cwd);
|
|
15091
15192
|
const active = intents.filter((record) => record.intent.status === "active");
|
|
15092
15193
|
ctx.data.companyIntents = intents;
|
|
15093
15194
|
ctx.data.companyActiveIntents = active;
|
|
@@ -21005,8 +21106,8 @@ async function runImplementation(profileName, input) {
|
|
|
21005
21106
|
const stageStartedAt = Date.now();
|
|
21006
21107
|
let finishRunIndex = null;
|
|
21007
21108
|
emitEvent(input.cwd, { implementation: profileName, kind: "stage_start" });
|
|
21008
|
-
const finishAndEnd = (out) => {
|
|
21009
|
-
finishRunIndex?.(out);
|
|
21109
|
+
const finishAndEnd = async (out) => {
|
|
21110
|
+
await finishRunIndex?.(out);
|
|
21010
21111
|
emitEvent(input.cwd, {
|
|
21011
21112
|
implementation: profileName,
|
|
21012
21113
|
kind: "stage_end",
|
|
@@ -21097,7 +21198,7 @@ async function runImplementation(profileName, input) {
|
|
|
21097
21198
|
if (reasoningEffort) ctx.data.jobReasoningEffort = reasoningEffort;
|
|
21098
21199
|
const runIndexStartedAt = new Date(stageStartedAt).toISOString();
|
|
21099
21200
|
if (!input.skipConfig) {
|
|
21100
|
-
|
|
21201
|
+
await upsertRunIndexRowBestEffortAsync(
|
|
21101
21202
|
config,
|
|
21102
21203
|
input.cwd,
|
|
21103
21204
|
runIndexRowFromJobContext({
|
|
@@ -21109,10 +21210,10 @@ async function runImplementation(profileName, input) {
|
|
|
21109
21210
|
updatedAt: runIndexStartedAt
|
|
21110
21211
|
})
|
|
21111
21212
|
);
|
|
21112
|
-
finishRunIndex = (out) => {
|
|
21213
|
+
finishRunIndex = async (out) => {
|
|
21113
21214
|
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
21114
21215
|
const status = statusFromExitCode(out.exitCode);
|
|
21115
|
-
|
|
21216
|
+
await upsertRunIndexRowBestEffortAsync(
|
|
21116
21217
|
config,
|
|
21117
21218
|
input.cwd,
|
|
21118
21219
|
runIndexRowFromJobContext({
|
|
@@ -21125,7 +21226,7 @@ async function runImplementation(profileName, input) {
|
|
|
21125
21226
|
reason: out.reason
|
|
21126
21227
|
})
|
|
21127
21228
|
);
|
|
21128
|
-
|
|
21229
|
+
await finalizeStagedRunIndexRowsAsync(config, input.cwd, ctx.data, {
|
|
21129
21230
|
status,
|
|
21130
21231
|
updatedAt: finishedAt,
|
|
21131
21232
|
reason: out.reason
|
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.395",
|
|
4
4
|
"description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative implementation profiles.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -12,6 +12,28 @@
|
|
|
12
12
|
"templates",
|
|
13
13
|
"kody.config.schema.json"
|
|
14
14
|
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"kody:run": "tsx bin/kody.ts",
|
|
17
|
+
"serve": "tsx bin/kody.ts serve",
|
|
18
|
+
"serve:vscode": "tsx bin/kody.ts serve vscode",
|
|
19
|
+
"serve:claude": "tsx bin/kody.ts serve claude",
|
|
20
|
+
"clean:dist": "node scripts/clean-dist.cjs",
|
|
21
|
+
"build": "pnpm clean:dist && tsup && node scripts/copy-assets.cjs",
|
|
22
|
+
"check:modularity": "tsx scripts/check-script-modularity.ts",
|
|
23
|
+
"pretest": "pnpm check:modularity",
|
|
24
|
+
"test": "vitest run tests/unit tests/int --coverage",
|
|
25
|
+
"posttest": "tsx scripts/check-coverage-floor.ts",
|
|
26
|
+
"test:smoke": "vitest run tests/smoke --no-coverage",
|
|
27
|
+
"test:e2e": "vitest run tests/e2e --no-coverage",
|
|
28
|
+
"test:all": "vitest run tests --no-coverage",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
|
+
"lint": "biome check",
|
|
31
|
+
"lint:fix": "biome check --write",
|
|
32
|
+
"format": "biome format --write",
|
|
33
|
+
"verify:package": "node scripts/verify-package-tarball.cjs",
|
|
34
|
+
"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",
|
|
35
|
+
"prepublishOnly": "pnpm typecheck && vitest run tests/unit tests/int --no-coverage && pnpm build && pnpm verify:package"
|
|
36
|
+
},
|
|
15
37
|
"dependencies": {
|
|
16
38
|
"@actions/cache": "^6.0.0",
|
|
17
39
|
"@anthropic-ai/claude-agent-sdk": "0.2.119",
|
|
@@ -36,26 +58,5 @@
|
|
|
36
58
|
"url": "git+https://github.com/aharonyaircohen/kody-engine.git"
|
|
37
59
|
},
|
|
38
60
|
"homepage": "https://github.com/aharonyaircohen/kody-engine",
|
|
39
|
-
"bugs": "https://github.com/aharonyaircohen/kody-engine/issues"
|
|
40
|
-
|
|
41
|
-
"kody:run": "tsx bin/kody.ts",
|
|
42
|
-
"serve": "tsx bin/kody.ts serve",
|
|
43
|
-
"serve:vscode": "tsx bin/kody.ts serve vscode",
|
|
44
|
-
"serve:claude": "tsx bin/kody.ts serve claude",
|
|
45
|
-
"clean:dist": "node scripts/clean-dist.cjs",
|
|
46
|
-
"build": "pnpm clean:dist && tsup && node scripts/copy-assets.cjs",
|
|
47
|
-
"check:modularity": "tsx scripts/check-script-modularity.ts",
|
|
48
|
-
"pretest": "pnpm check:modularity",
|
|
49
|
-
"test": "vitest run tests/unit tests/int --coverage",
|
|
50
|
-
"posttest": "tsx scripts/check-coverage-floor.ts",
|
|
51
|
-
"test:smoke": "vitest run tests/smoke --no-coverage",
|
|
52
|
-
"test:e2e": "vitest run tests/e2e --no-coverage",
|
|
53
|
-
"test:all": "vitest run tests --no-coverage",
|
|
54
|
-
"typecheck": "tsc --noEmit",
|
|
55
|
-
"lint": "biome check",
|
|
56
|
-
"lint:fix": "biome check --write",
|
|
57
|
-
"format": "biome format --write",
|
|
58
|
-
"verify:package": "node scripts/verify-package-tarball.cjs",
|
|
59
|
-
"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"
|
|
60
|
-
}
|
|
61
|
-
}
|
|
61
|
+
"bugs": "https://github.com/aharonyaircohen/kody-engine/issues"
|
|
62
|
+
}
|