@kody-ade/kody-engine 0.4.386 → 0.4.388
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 +98 -16
- package/package.json +1 -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.388",
|
|
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",
|
|
@@ -3892,6 +3892,34 @@ function createStateBackendFromEnv(env = process.env, client) {
|
|
|
3892
3892
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3893
3893
|
...expectedUpdatedAt ? { expectedUpdatedAt } : {}
|
|
3894
3894
|
});
|
|
3895
|
+
},
|
|
3896
|
+
async getGoal(tenantId, goalId) {
|
|
3897
|
+
const result = await transport.query(anyApi.goals.get, {
|
|
3898
|
+
tenantId: requireTenant(tenantId),
|
|
3899
|
+
goalId: requireNonEmpty(goalId, "goalId")
|
|
3900
|
+
});
|
|
3901
|
+
return result ?? null;
|
|
3902
|
+
},
|
|
3903
|
+
async listGoals(tenantId) {
|
|
3904
|
+
const result = await transport.query(anyApi.goals.list, { tenantId: requireTenant(tenantId) });
|
|
3905
|
+
return Array.isArray(result) ? result : [];
|
|
3906
|
+
},
|
|
3907
|
+
async saveGoal(tenantId, goalId, state, updatedAt, expectedUpdatedAt) {
|
|
3908
|
+
await transport.mutation(anyApi.goals.save, {
|
|
3909
|
+
tenantId: requireTenant(tenantId),
|
|
3910
|
+
goalId: requireNonEmpty(goalId, "goalId"),
|
|
3911
|
+
state,
|
|
3912
|
+
updatedAt,
|
|
3913
|
+
...expectedUpdatedAt ? { expectedUpdatedAt } : {}
|
|
3914
|
+
});
|
|
3915
|
+
},
|
|
3916
|
+
async appendDailyLog(tenantId, stream, date, entry) {
|
|
3917
|
+
await transport.mutation(anyApi.dailyLogs.append, {
|
|
3918
|
+
tenantId: requireTenant(tenantId),
|
|
3919
|
+
stream,
|
|
3920
|
+
date: requireNonEmpty(date, "date"),
|
|
3921
|
+
entry
|
|
3922
|
+
});
|
|
3895
3923
|
}
|
|
3896
3924
|
};
|
|
3897
3925
|
}
|
|
@@ -8114,6 +8142,24 @@ function flushGoalRunLogEvents(config, cwd, data) {
|
|
|
8114
8142
|
log2.events = [];
|
|
8115
8143
|
}
|
|
8116
8144
|
}
|
|
8145
|
+
async function flushGoalRunLogEventsAsync(config, cwd, data) {
|
|
8146
|
+
const tenantId = config.github?.owner && config.github.repo ? `${config.github.owner}/${config.github.repo}` : process.env.GITHUB_REPOSITORY;
|
|
8147
|
+
const backendConfigured = Boolean(process.env.CONVEX_URL?.trim() && process.env.KODY_SERVICE_KEY?.trim() && tenantId);
|
|
8148
|
+
if (!backendConfigured) {
|
|
8149
|
+
if (process.env.GITHUB_ACTIONS === "true") throw new Error("Convex backend is required for goal run logs in GitHub Actions");
|
|
8150
|
+
flushGoalRunLogEvents(config, cwd, data);
|
|
8151
|
+
return;
|
|
8152
|
+
}
|
|
8153
|
+
const backend = createStateBackendFromEnv();
|
|
8154
|
+
for (const [goalId, log2] of Object.entries(goalRunLogs(data))) {
|
|
8155
|
+
if (log2.events.length === 0) continue;
|
|
8156
|
+
const enrichedEvents = log2.events.map((event) => enrichGoalRunLogEvent(config, data, log2.path, event));
|
|
8157
|
+
for (const event of enrichedEvents) {
|
|
8158
|
+
await backend.appendDailyLog(tenantId, "events", event.time.slice(0, 10), event);
|
|
8159
|
+
}
|
|
8160
|
+
log2.events = [];
|
|
8161
|
+
}
|
|
8162
|
+
}
|
|
8117
8163
|
function goalRunLogPath(goalId, data) {
|
|
8118
8164
|
const startedAt = goalRunStartedAt(data);
|
|
8119
8165
|
const runId = goalRunId(data);
|
|
@@ -8536,6 +8582,7 @@ var init_runLog = __esm({
|
|
|
8536
8582
|
"use strict";
|
|
8537
8583
|
init_runIndex();
|
|
8538
8584
|
init_stateRepo();
|
|
8585
|
+
init_state_backend();
|
|
8539
8586
|
init_state2();
|
|
8540
8587
|
LOGS_KEY = "__goalRunLogs";
|
|
8541
8588
|
LOG_RUN_KEY = "__goalRunLogRunId";
|
|
@@ -8714,7 +8761,7 @@ import * as path24 from "path";
|
|
|
8714
8761
|
function goalStatePath(goalId) {
|
|
8715
8762
|
return `todos/${goalId}.json`;
|
|
8716
8763
|
}
|
|
8717
|
-
function
|
|
8764
|
+
function fetchGoalStateLegacy(config, goalId, cwd) {
|
|
8718
8765
|
const filePath = goalStatePath(goalId);
|
|
8719
8766
|
const loaded = readStateText(config, cwd, filePath);
|
|
8720
8767
|
if (!loaded) return null;
|
|
@@ -8769,14 +8816,14 @@ function readStoreGoalTemplate(templateId) {
|
|
|
8769
8816
|
function recordField2(value) {
|
|
8770
8817
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
8771
8818
|
}
|
|
8772
|
-
function
|
|
8819
|
+
function putGoalStateLegacy(config, goalId, state, message = `chore(goals): update ${goalId}`, cwd) {
|
|
8773
8820
|
const previous = readStateText(config, cwd, goalStatePath(goalId));
|
|
8774
8821
|
if (previous && !isManagedTodoRaw(previous.content)) {
|
|
8775
8822
|
throw new Error(`Cannot overwrite regular todo list ${goalId} as managed goal`);
|
|
8776
8823
|
}
|
|
8777
8824
|
upsertStateText(config, cwd, goalStatePath(goalId), serializeTodoGoalState(goalId, state, previous?.content), message);
|
|
8778
8825
|
}
|
|
8779
|
-
function
|
|
8826
|
+
function listGoalStateIdsLegacy(config, cwd) {
|
|
8780
8827
|
const ids = /* @__PURE__ */ new Set();
|
|
8781
8828
|
const todoEntries = listStateDirectory(config, cwd, "todos");
|
|
8782
8829
|
for (const entry of todoEntries) {
|
|
@@ -8787,11 +8834,46 @@ function listGoalStateIds(config, cwd) {
|
|
|
8787
8834
|
}
|
|
8788
8835
|
return [...ids].sort();
|
|
8789
8836
|
}
|
|
8837
|
+
function backendTenant(config) {
|
|
8838
|
+
const owner = config.github?.owner?.trim() || process.env.GITHUB_REPOSITORY?.split("/")[0]?.trim();
|
|
8839
|
+
const repo = config.github?.repo?.trim() || process.env.GITHUB_REPOSITORY?.split("/")[1]?.trim();
|
|
8840
|
+
return owner && repo ? `${owner}/${repo}` : null;
|
|
8841
|
+
}
|
|
8842
|
+
function backendEnabled(config) {
|
|
8843
|
+
return Boolean(process.env.CONVEX_URL?.trim() && process.env.KODY_SERVICE_KEY?.trim() && backendTenant(config));
|
|
8844
|
+
}
|
|
8845
|
+
function backendRequired() {
|
|
8846
|
+
return process.env.GITHUB_ACTIONS === "true";
|
|
8847
|
+
}
|
|
8848
|
+
function decodeGoal(doc) {
|
|
8849
|
+
if (!doc || !doc.state || typeof doc.state !== "object" || Array.isArray(doc.state)) return null;
|
|
8850
|
+
const state = doc.state;
|
|
8851
|
+
if (typeof state.state !== "string" || !state.extra || typeof state.extra !== "object") return null;
|
|
8852
|
+
return resolveStoreBackedGoalState(state);
|
|
8853
|
+
}
|
|
8854
|
+
async function fetchGoalStateAsync(config, goalId, cwd) {
|
|
8855
|
+
const tenantId = backendTenant(config);
|
|
8856
|
+
if (backendEnabled(config) && tenantId) {
|
|
8857
|
+
return decodeGoal(await createStateBackendFromEnv().getGoal(tenantId, goalId));
|
|
8858
|
+
}
|
|
8859
|
+
if (backendRequired()) throw new Error("Convex backend is required for goal state in GitHub Actions");
|
|
8860
|
+
return fetchGoalStateLegacy(config, goalId, cwd);
|
|
8861
|
+
}
|
|
8862
|
+
function fetchGoalState(config, goalId, cwd) {
|
|
8863
|
+
return fetchGoalStateLegacy(config, goalId, cwd);
|
|
8864
|
+
}
|
|
8865
|
+
function putGoalState(config, goalId, state, message = `chore(goals): update ${goalId}`, cwd) {
|
|
8866
|
+
putGoalStateLegacy(config, goalId, state, message, cwd);
|
|
8867
|
+
}
|
|
8868
|
+
function listGoalStateIds(config, cwd) {
|
|
8869
|
+
return listGoalStateIdsLegacy(config, cwd);
|
|
8870
|
+
}
|
|
8790
8871
|
var init_stateStore = __esm({
|
|
8791
8872
|
"src/goal/stateStore.ts"() {
|
|
8792
8873
|
"use strict";
|
|
8793
8874
|
init_companyStore();
|
|
8794
8875
|
init_stateRepo();
|
|
8876
|
+
init_state_backend();
|
|
8795
8877
|
init_managedTodoState();
|
|
8796
8878
|
}
|
|
8797
8879
|
});
|
|
@@ -11290,9 +11372,9 @@ function createNeedsFixIssue(goalId, evidence, result, cwd) {
|
|
|
11290
11372
|
if (!match) throw new Error(`gh issue create returned unexpected output: ${out}`);
|
|
11291
11373
|
return Number(match[1]);
|
|
11292
11374
|
}
|
|
11293
|
-
function flushLogs(ctx) {
|
|
11375
|
+
async function flushLogs(ctx) {
|
|
11294
11376
|
try {
|
|
11295
|
-
|
|
11377
|
+
await flushGoalRunLogEventsAsync(ctx.config, ctx.cwd, ctx.data);
|
|
11296
11378
|
} catch (err) {
|
|
11297
11379
|
process.stderr.write(
|
|
11298
11380
|
`[kody capability-report] goal log persist failed (${err instanceof Error ? err.message : String(err)})
|
|
@@ -11487,7 +11569,7 @@ var init_applyCapabilityReports = __esm({
|
|
|
11487
11569
|
},
|
|
11488
11570
|
decision: { kind: "reject-evidence", nextStep: "block", reason: "goal missing in state repo" }
|
|
11489
11571
|
});
|
|
11490
|
-
flushLogs(ctx);
|
|
11572
|
+
await flushLogs(ctx);
|
|
11491
11573
|
process.stderr.write(`[kody capability-report] goal ${goalId} missing in state repo; report skipped
|
|
11492
11574
|
`);
|
|
11493
11575
|
continue;
|
|
@@ -11555,7 +11637,7 @@ var init_applyCapabilityReports = __esm({
|
|
|
11555
11637
|
};
|
|
11556
11638
|
}
|
|
11557
11639
|
} finally {
|
|
11558
|
-
flushLogs(ctx);
|
|
11640
|
+
await flushLogs(ctx);
|
|
11559
11641
|
}
|
|
11560
11642
|
}
|
|
11561
11643
|
};
|
|
@@ -11854,9 +11936,9 @@ function refreshReportOrFail2(ctx, goalId, state) {
|
|
|
11854
11936
|
if (ctx.output.exitCode === 0) ctx.output.exitCode = 99;
|
|
11855
11937
|
}
|
|
11856
11938
|
}
|
|
11857
|
-
function flushLogs2(ctx) {
|
|
11939
|
+
async function flushLogs2(ctx) {
|
|
11858
11940
|
try {
|
|
11859
|
-
|
|
11941
|
+
await flushGoalRunLogEventsAsync(ctx.config, ctx.cwd, ctx.data);
|
|
11860
11942
|
} catch (err) {
|
|
11861
11943
|
process.stderr.write(
|
|
11862
11944
|
`[goal-manager] goal log persist failed (${err instanceof Error ? err.message : String(err)})
|
|
@@ -11878,17 +11960,17 @@ var init_commitGoalState = __esm({
|
|
|
11878
11960
|
commitGoalState = async (ctx) => {
|
|
11879
11961
|
const goal = ctx.data.goal;
|
|
11880
11962
|
if (!goal) {
|
|
11881
|
-
flushLogs2(ctx);
|
|
11963
|
+
await flushLogs2(ctx);
|
|
11882
11964
|
return;
|
|
11883
11965
|
}
|
|
11884
11966
|
if (ctx.data.goalPersistChanged !== true) {
|
|
11885
11967
|
refreshReportOrFail2(ctx, goal.id, goal.raw);
|
|
11886
|
-
flushLogs2(ctx);
|
|
11968
|
+
await flushLogs2(ctx);
|
|
11887
11969
|
return;
|
|
11888
11970
|
}
|
|
11889
11971
|
const updated = ctx.data.goalPersistState;
|
|
11890
11972
|
if (!updated) {
|
|
11891
|
-
flushLogs2(ctx);
|
|
11973
|
+
await flushLogs2(ctx);
|
|
11892
11974
|
return;
|
|
11893
11975
|
}
|
|
11894
11976
|
try {
|
|
@@ -11900,7 +11982,7 @@ var init_commitGoalState = __esm({
|
|
|
11900
11982
|
`
|
|
11901
11983
|
);
|
|
11902
11984
|
} finally {
|
|
11903
|
-
flushLogs2(ctx);
|
|
11985
|
+
await flushLogs2(ctx);
|
|
11904
11986
|
}
|
|
11905
11987
|
};
|
|
11906
11988
|
}
|
|
@@ -14994,11 +15076,11 @@ function sleep(ms) {
|
|
|
14994
15076
|
return new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
14995
15077
|
}
|
|
14996
15078
|
async function fetchGoalStateWithRetry(config, goalId, cwd) {
|
|
14997
|
-
let state =
|
|
15079
|
+
let state = await fetchGoalStateAsync(config, goalId, cwd);
|
|
14998
15080
|
if (state) return state;
|
|
14999
15081
|
for (const delay of retryDelaysMs()) {
|
|
15000
15082
|
await sleep(delay);
|
|
15001
|
-
state =
|
|
15083
|
+
state = await fetchGoalStateAsync(config, goalId, cwd);
|
|
15002
15084
|
if (state) {
|
|
15003
15085
|
process.stdout.write(`[goal-manager] loaded goal state for ${goalId} after retry
|
|
15004
15086
|
`);
|
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.388",
|
|
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",
|