@kody-ade/kody-engine 0.2.7 → 0.2.8
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/kody2.js +254 -18
- package/dist/executables/build/profile.json +16 -1
- package/package.json +1 -1
package/dist/bin/kody2.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// package.json
|
|
4
4
|
var package_default = {
|
|
5
5
|
name: "@kody-ade/kody-engine",
|
|
6
|
-
version: "0.2.
|
|
6
|
+
version: "0.2.8",
|
|
7
7
|
description: "kody2 \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
8
8
|
license: "MIT",
|
|
9
9
|
type: "module",
|
|
@@ -1962,10 +1962,201 @@ var loadCoverageRules = async (ctx) => {
|
|
|
1962
1962
|
ctx.data.coverageRules = ctx.config.testRequirements ?? [];
|
|
1963
1963
|
};
|
|
1964
1964
|
|
|
1965
|
+
// src/state.ts
|
|
1966
|
+
import { execFileSync as execFileSync10 } from "child_process";
|
|
1967
|
+
var STATE_BEGIN = "<!-- kody2:state:v1:begin -->";
|
|
1968
|
+
var STATE_END = "<!-- kody2:state:v1:end -->";
|
|
1969
|
+
var HISTORY_MAX_ENTRIES = 20;
|
|
1970
|
+
var API_TIMEOUT_MS2 = 3e4;
|
|
1971
|
+
function emptyState() {
|
|
1972
|
+
return {
|
|
1973
|
+
schemaVersion: 1,
|
|
1974
|
+
core: {
|
|
1975
|
+
phase: "idle",
|
|
1976
|
+
status: "pending",
|
|
1977
|
+
currentExecutable: null,
|
|
1978
|
+
lastOutcome: null,
|
|
1979
|
+
attempts: {}
|
|
1980
|
+
},
|
|
1981
|
+
executables: {},
|
|
1982
|
+
history: []
|
|
1983
|
+
};
|
|
1984
|
+
}
|
|
1985
|
+
function ghToken3() {
|
|
1986
|
+
return process.env.GH_PAT?.trim() || process.env.GH_TOKEN;
|
|
1987
|
+
}
|
|
1988
|
+
function gh3(args, input, cwd) {
|
|
1989
|
+
const token = ghToken3();
|
|
1990
|
+
const env = token ? { ...process.env, GH_TOKEN: token } : { ...process.env };
|
|
1991
|
+
return execFileSync10("gh", args, {
|
|
1992
|
+
encoding: "utf-8",
|
|
1993
|
+
timeout: API_TIMEOUT_MS2,
|
|
1994
|
+
cwd,
|
|
1995
|
+
env,
|
|
1996
|
+
input,
|
|
1997
|
+
stdio: input ? ["pipe", "pipe", "pipe"] : ["ignore", "pipe", "pipe"]
|
|
1998
|
+
}).trim();
|
|
1999
|
+
}
|
|
2000
|
+
function findStateComment(target, number, cwd) {
|
|
2001
|
+
const apiPath = target === "issue" ? `repos/{owner}/{repo}/issues/${number}/comments` : `repos/{owner}/{repo}/issues/${number}/comments`;
|
|
2002
|
+
try {
|
|
2003
|
+
const raw = gh3(["api", "--paginate", apiPath], void 0, cwd);
|
|
2004
|
+
const list = JSON.parse(raw);
|
|
2005
|
+
for (const c of list) {
|
|
2006
|
+
if (c.body?.includes(STATE_BEGIN)) {
|
|
2007
|
+
return { id: String(c.id), body: c.body };
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
} catch {
|
|
2011
|
+
}
|
|
2012
|
+
return null;
|
|
2013
|
+
}
|
|
2014
|
+
function parseStateComment(body) {
|
|
2015
|
+
const beginIdx = body.indexOf(STATE_BEGIN);
|
|
2016
|
+
const endIdx = body.indexOf(STATE_END, beginIdx + 1);
|
|
2017
|
+
if (beginIdx < 0 || endIdx < 0) return emptyState();
|
|
2018
|
+
const between = body.slice(beginIdx + STATE_BEGIN.length, endIdx);
|
|
2019
|
+
const fenceMatch = between.match(/```json\s*([\s\S]*?)\s*```/);
|
|
2020
|
+
if (!fenceMatch) return emptyState();
|
|
2021
|
+
try {
|
|
2022
|
+
const parsed = JSON.parse(fenceMatch[1]);
|
|
2023
|
+
if (parsed?.schemaVersion !== 1) return emptyState();
|
|
2024
|
+
return {
|
|
2025
|
+
schemaVersion: 1,
|
|
2026
|
+
core: { ...emptyState().core, ...parsed.core },
|
|
2027
|
+
executables: parsed.executables ?? {},
|
|
2028
|
+
history: Array.isArray(parsed.history) ? parsed.history : []
|
|
2029
|
+
};
|
|
2030
|
+
} catch {
|
|
2031
|
+
return emptyState();
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
function reduce(state, executable, action) {
|
|
2035
|
+
if (!action) return state;
|
|
2036
|
+
const newAttempts = { ...state.core.attempts, [executable]: (state.core.attempts[executable] ?? 0) + 1 };
|
|
2037
|
+
const newExecutables = {
|
|
2038
|
+
...state.executables,
|
|
2039
|
+
[executable]: { ...state.executables[executable] ?? { lastAction: null }, lastAction: action }
|
|
2040
|
+
};
|
|
2041
|
+
const newHistory = [
|
|
2042
|
+
...state.history,
|
|
2043
|
+
{ timestamp: action.timestamp, executable, action: action.type, note: noteFromAction(action) }
|
|
2044
|
+
].slice(-HISTORY_MAX_ENTRIES);
|
|
2045
|
+
return {
|
|
2046
|
+
schemaVersion: 1,
|
|
2047
|
+
core: {
|
|
2048
|
+
...state.core,
|
|
2049
|
+
attempts: newAttempts,
|
|
2050
|
+
lastOutcome: action,
|
|
2051
|
+
currentExecutable: executable,
|
|
2052
|
+
status: statusFromAction(action),
|
|
2053
|
+
phase: phaseFromAction(executable, action)
|
|
2054
|
+
},
|
|
2055
|
+
executables: newExecutables,
|
|
2056
|
+
history: newHistory
|
|
2057
|
+
};
|
|
2058
|
+
}
|
|
2059
|
+
function statusFromAction(action) {
|
|
2060
|
+
if (/FAILED$|ERROR$|MISSING$|REJECTED$/i.test(action.type)) return "failed";
|
|
2061
|
+
if (/COMPLETED$|SHIPPED$|MERGED$|SUCCESS$/i.test(action.type)) return "succeeded";
|
|
2062
|
+
return "running";
|
|
2063
|
+
}
|
|
2064
|
+
function phaseFromAction(executable, action) {
|
|
2065
|
+
if (/FAILED$|ERROR$|REJECTED$/i.test(action.type)) return "failed";
|
|
2066
|
+
if (executable === "build") return statusFromAction(action) === "succeeded" ? "implementing" : "implementing";
|
|
2067
|
+
if (executable === "review") return "reviewing";
|
|
2068
|
+
if (executable === "release") return "shipped";
|
|
2069
|
+
return "idle";
|
|
2070
|
+
}
|
|
2071
|
+
function noteFromAction(action) {
|
|
2072
|
+
const p = action.payload;
|
|
2073
|
+
if (typeof p?.prUrl === "string") return p.prUrl;
|
|
2074
|
+
if (typeof p?.reason === "string") return p.reason.slice(0, 120);
|
|
2075
|
+
if (typeof p?.commitMessage === "string") return p.commitMessage.slice(0, 120);
|
|
2076
|
+
return void 0;
|
|
2077
|
+
}
|
|
2078
|
+
function renderStateComment(state) {
|
|
2079
|
+
const lines = [];
|
|
2080
|
+
lines.push(STATE_BEGIN);
|
|
2081
|
+
lines.push("");
|
|
2082
|
+
lines.push("```json");
|
|
2083
|
+
lines.push(JSON.stringify(
|
|
2084
|
+
{ schemaVersion: state.schemaVersion, core: state.core, executables: state.executables, history: state.history },
|
|
2085
|
+
null,
|
|
2086
|
+
2
|
|
2087
|
+
));
|
|
2088
|
+
lines.push("```");
|
|
2089
|
+
lines.push("");
|
|
2090
|
+
lines.push(STATE_END);
|
|
2091
|
+
lines.push("");
|
|
2092
|
+
lines.push("## kody2 task state");
|
|
2093
|
+
lines.push("");
|
|
2094
|
+
lines.push(`- **Phase:** \`${state.core.phase}\` **Status:** \`${state.core.status}\``);
|
|
2095
|
+
if (state.core.currentExecutable) {
|
|
2096
|
+
lines.push(`- **Last executable:** \`${state.core.currentExecutable}\``);
|
|
2097
|
+
}
|
|
2098
|
+
if (state.core.lastOutcome) {
|
|
2099
|
+
lines.push(`- **Last action:** \`${state.core.lastOutcome.type}\``);
|
|
2100
|
+
}
|
|
2101
|
+
const attempts = Object.entries(state.core.attempts).map(([k, v]) => `${k}:${v}`).join(", ");
|
|
2102
|
+
if (attempts) lines.push(`- **Attempts:** ${attempts}`);
|
|
2103
|
+
if (state.core.prUrl) lines.push(`- **PR:** ${state.core.prUrl}`);
|
|
2104
|
+
if (state.core.runUrl) lines.push(`- **Run:** ${state.core.runUrl}`);
|
|
2105
|
+
lines.push("");
|
|
2106
|
+
if (state.history.length > 0) {
|
|
2107
|
+
lines.push("### Recent history");
|
|
2108
|
+
lines.push("");
|
|
2109
|
+
const recent = state.history.slice(-10).reverse();
|
|
2110
|
+
for (const h of recent) {
|
|
2111
|
+
const note = h.note ? ` \u2014 ${h.note}` : "";
|
|
2112
|
+
lines.push(`- \`${h.timestamp}\` **${h.executable}** \u2192 \`${h.action}\`${note}`);
|
|
2113
|
+
}
|
|
2114
|
+
lines.push("");
|
|
2115
|
+
}
|
|
2116
|
+
return lines.join("\n");
|
|
2117
|
+
}
|
|
2118
|
+
function readTaskState(target, number, cwd) {
|
|
2119
|
+
const existing = findStateComment(target, number, cwd);
|
|
2120
|
+
return existing ? parseStateComment(existing.body) : emptyState();
|
|
2121
|
+
}
|
|
2122
|
+
function writeTaskState(target, number, state, cwd) {
|
|
2123
|
+
const body = renderStateComment(state);
|
|
2124
|
+
const existing = findStateComment(target, number, cwd);
|
|
2125
|
+
try {
|
|
2126
|
+
if (existing) {
|
|
2127
|
+
gh3(
|
|
2128
|
+
["api", `repos/{owner}/{repo}/issues/comments/${existing.id}`, "-X", "PATCH", "-F", "body=@-"],
|
|
2129
|
+
body,
|
|
2130
|
+
cwd
|
|
2131
|
+
);
|
|
2132
|
+
} else {
|
|
2133
|
+
const sub = target === "issue" ? "issue" : "pr";
|
|
2134
|
+
gh3([sub, "comment", String(number), "--body-file", "-"], body, cwd);
|
|
2135
|
+
}
|
|
2136
|
+
} catch (err) {
|
|
2137
|
+
process.stderr.write(
|
|
2138
|
+
`[kody2 state] failed to write state on ${target} #${number}: ${err instanceof Error ? err.message : String(err)}
|
|
2139
|
+
`
|
|
2140
|
+
);
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
|
|
2144
|
+
// src/scripts/loadTaskState.ts
|
|
2145
|
+
var loadTaskState = async (ctx) => {
|
|
2146
|
+
const target = ctx.data.commentTargetType;
|
|
2147
|
+
const number = ctx.data.commentTargetNumber;
|
|
2148
|
+
if (!target || !number) {
|
|
2149
|
+
ctx.data.taskState = emptyState();
|
|
2150
|
+
return;
|
|
2151
|
+
}
|
|
2152
|
+
ctx.data.taskState = readTaskState(target, number, ctx.cwd);
|
|
2153
|
+
};
|
|
2154
|
+
|
|
1965
2155
|
// src/scripts/parseAgentResult.ts
|
|
1966
|
-
var parseAgentResult2 = async (ctx,
|
|
2156
|
+
var parseAgentResult2 = async (ctx, profile, agentResult) => {
|
|
1967
2157
|
if (!agentResult) {
|
|
1968
2158
|
ctx.data.agentDone = false;
|
|
2159
|
+
ctx.data.action = makeAction("AGENT_NOT_RUN", { reason: "no agent result" });
|
|
1969
2160
|
return;
|
|
1970
2161
|
}
|
|
1971
2162
|
const parsed = parseAgentResult(agentResult.finalText);
|
|
@@ -1975,7 +2166,21 @@ var parseAgentResult2 = async (ctx, _profile, agentResult) => {
|
|
|
1975
2166
|
ctx.data.agentFailureReason = parsed.failureReason;
|
|
1976
2167
|
ctx.data.agentOutcome = agentResult.outcome;
|
|
1977
2168
|
ctx.data.agentError = agentResult.error;
|
|
2169
|
+
const modeSeg = (ctx.args.mode ?? profile.name).replace(/-/g, "_").toUpperCase();
|
|
2170
|
+
if (parsed.done) {
|
|
2171
|
+
ctx.data.action = makeAction(`${modeSeg}_COMPLETED`, {
|
|
2172
|
+
commitMessage: parsed.commitMessage,
|
|
2173
|
+
prSummary: parsed.prSummary
|
|
2174
|
+
});
|
|
2175
|
+
} else {
|
|
2176
|
+
ctx.data.action = makeAction(`${modeSeg}_FAILED`, {
|
|
2177
|
+
reason: parsed.failureReason || agentResult.error || "unknown failure"
|
|
2178
|
+
});
|
|
2179
|
+
}
|
|
1978
2180
|
};
|
|
2181
|
+
function makeAction(type, payload) {
|
|
2182
|
+
return { type, payload, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
|
|
2183
|
+
}
|
|
1979
2184
|
|
|
1980
2185
|
// src/scripts/postIssueComment.ts
|
|
1981
2186
|
var postIssueComment2 = async (ctx) => {
|
|
@@ -2079,7 +2284,7 @@ REVIEW_POSTED=https://github.com/${ctx.config.github.owner}/${ctx.config.github.
|
|
|
2079
2284
|
};
|
|
2080
2285
|
|
|
2081
2286
|
// src/scripts/releaseFlow.ts
|
|
2082
|
-
import { execFileSync as
|
|
2287
|
+
import { execFileSync as execFileSync11, spawnSync } from "child_process";
|
|
2083
2288
|
import * as fs11 from "fs";
|
|
2084
2289
|
import * as path10 from "path";
|
|
2085
2290
|
function bumpVersion(current, bump) {
|
|
@@ -2109,7 +2314,7 @@ function generateChangelog(cwd, newVersion, lastTag) {
|
|
|
2109
2314
|
const range = lastTag ? `${lastTag}..HEAD` : "HEAD";
|
|
2110
2315
|
let log = "";
|
|
2111
2316
|
try {
|
|
2112
|
-
log =
|
|
2317
|
+
log = execFileSync11("git", ["log", range, "--pretty=format:%s||%h", "--no-merges"], {
|
|
2113
2318
|
cwd,
|
|
2114
2319
|
encoding: "utf-8",
|
|
2115
2320
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -2166,7 +2371,7 @@ ${entry}${prior.slice(idx + 1)}`);
|
|
|
2166
2371
|
}
|
|
2167
2372
|
}
|
|
2168
2373
|
function git3(args, cwd, timeout = 6e4) {
|
|
2169
|
-
return
|
|
2374
|
+
return execFileSync11("git", args, {
|
|
2170
2375
|
encoding: "utf-8",
|
|
2171
2376
|
timeout,
|
|
2172
2377
|
cwd,
|
|
@@ -2381,7 +2586,7 @@ ${truncate2(r.stderr, 2e3)}
|
|
|
2381
2586
|
}
|
|
2382
2587
|
|
|
2383
2588
|
// src/scripts/resolveFlow.ts
|
|
2384
|
-
import { execFileSync as
|
|
2589
|
+
import { execFileSync as execFileSync12 } from "child_process";
|
|
2385
2590
|
var CONFLICT_DIFF_MAX_BYTES = 4e4;
|
|
2386
2591
|
var resolveFlow = async (ctx) => {
|
|
2387
2592
|
const prNumber = ctx.args.pr;
|
|
@@ -2433,7 +2638,7 @@ var resolveFlow = async (ctx) => {
|
|
|
2433
2638
|
};
|
|
2434
2639
|
function getConflictedFiles(cwd) {
|
|
2435
2640
|
try {
|
|
2436
|
-
const out =
|
|
2641
|
+
const out = execFileSync12("git", ["diff", "--name-only", "--diff-filter=U"], {
|
|
2437
2642
|
encoding: "utf-8",
|
|
2438
2643
|
cwd,
|
|
2439
2644
|
env: { ...process.env, HUSKY: "0" }
|
|
@@ -2448,7 +2653,7 @@ function getConflictMarkersPreview(files, cwd, maxBytes = CONFLICT_DIFF_MAX_BYTE
|
|
|
2448
2653
|
let total = 0;
|
|
2449
2654
|
for (const f of files) {
|
|
2450
2655
|
try {
|
|
2451
|
-
const content =
|
|
2656
|
+
const content = execFileSync12("cat", [f], { encoding: "utf-8", cwd }).toString();
|
|
2452
2657
|
const snippet = `### ${f}
|
|
2453
2658
|
|
|
2454
2659
|
\`\`\`
|
|
@@ -2528,6 +2733,35 @@ function tryPost(issueNumber, body, cwd) {
|
|
|
2528
2733
|
}
|
|
2529
2734
|
}
|
|
2530
2735
|
|
|
2736
|
+
// src/scripts/saveTaskState.ts
|
|
2737
|
+
var saveTaskState = async (ctx, profile) => {
|
|
2738
|
+
const target = ctx.data.commentTargetType;
|
|
2739
|
+
const number = ctx.data.commentTargetNumber;
|
|
2740
|
+
const state = ctx.data.taskState;
|
|
2741
|
+
if (!target || !number || !state) return;
|
|
2742
|
+
const executable = profile.name;
|
|
2743
|
+
const action = ctx.data.action ?? synthesizeAction(ctx);
|
|
2744
|
+
if (ctx.output.prUrl && !state.core.prUrl) state.core.prUrl = ctx.output.prUrl;
|
|
2745
|
+
if (typeof ctx.data.runUrl === "string") state.core.runUrl = ctx.data.runUrl;
|
|
2746
|
+
const next = reduce(state, executable, action);
|
|
2747
|
+
if (ctx.output.prUrl) next.core.prUrl = ctx.output.prUrl;
|
|
2748
|
+
if (typeof ctx.data.runUrl === "string") next.core.runUrl = ctx.data.runUrl;
|
|
2749
|
+
writeTaskState(target, number, next, ctx.cwd);
|
|
2750
|
+
ctx.data.taskStateRendered = renderStateComment(next);
|
|
2751
|
+
};
|
|
2752
|
+
function synthesizeAction(ctx) {
|
|
2753
|
+
const ok = ctx.output.exitCode === 0;
|
|
2754
|
+
return {
|
|
2755
|
+
type: ok ? "RUN_COMPLETED" : "RUN_FAILED",
|
|
2756
|
+
payload: {
|
|
2757
|
+
exitCode: ctx.output.exitCode,
|
|
2758
|
+
reason: ctx.output.reason,
|
|
2759
|
+
prUrl: ctx.output.prUrl
|
|
2760
|
+
},
|
|
2761
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2762
|
+
};
|
|
2763
|
+
}
|
|
2764
|
+
|
|
2531
2765
|
// src/verify.ts
|
|
2532
2766
|
import { spawn as spawn2 } from "child_process";
|
|
2533
2767
|
var TAIL_CHARS = 4e3;
|
|
@@ -2730,6 +2964,7 @@ var preflightScripts = {
|
|
|
2730
2964
|
initFlow,
|
|
2731
2965
|
releaseFlow,
|
|
2732
2966
|
watchStalePrsFlow,
|
|
2967
|
+
loadTaskState,
|
|
2733
2968
|
loadConventions,
|
|
2734
2969
|
loadCoverageRules,
|
|
2735
2970
|
composePrompt
|
|
@@ -2742,7 +2977,8 @@ var postflightScripts = {
|
|
|
2742
2977
|
ensurePr: ensurePr2,
|
|
2743
2978
|
postIssueComment: postIssueComment2,
|
|
2744
2979
|
postReviewResult,
|
|
2745
|
-
writeRunSummary
|
|
2980
|
+
writeRunSummary,
|
|
2981
|
+
saveTaskState
|
|
2746
2982
|
};
|
|
2747
2983
|
var allScriptNames = /* @__PURE__ */ new Set([
|
|
2748
2984
|
...Object.keys(preflightScripts),
|
|
@@ -2750,7 +2986,7 @@ var allScriptNames = /* @__PURE__ */ new Set([
|
|
|
2750
2986
|
]);
|
|
2751
2987
|
|
|
2752
2988
|
// src/tools.ts
|
|
2753
|
-
import { execFileSync as
|
|
2989
|
+
import { execFileSync as execFileSync13 } from "child_process";
|
|
2754
2990
|
function verifyCliTools(tools, cwd) {
|
|
2755
2991
|
const out = [];
|
|
2756
2992
|
for (const t of tools) out.push(verifyOne(t, cwd));
|
|
@@ -2783,7 +3019,7 @@ function verifyOne(tool, cwd) {
|
|
|
2783
3019
|
}
|
|
2784
3020
|
function runShell2(cmd, cwd, timeoutMs = 3e4) {
|
|
2785
3021
|
try {
|
|
2786
|
-
|
|
3022
|
+
execFileSync13("sh", ["-c", cmd], { cwd, stdio: "pipe", timeout: timeoutMs });
|
|
2787
3023
|
return true;
|
|
2788
3024
|
} catch {
|
|
2789
3025
|
return false;
|
|
@@ -2981,7 +3217,7 @@ function finish(out) {
|
|
|
2981
3217
|
}
|
|
2982
3218
|
|
|
2983
3219
|
// src/kody2-cli.ts
|
|
2984
|
-
import { execFileSync as
|
|
3220
|
+
import { execFileSync as execFileSync14 } from "child_process";
|
|
2985
3221
|
import * as fs15 from "fs";
|
|
2986
3222
|
import * as path12 from "path";
|
|
2987
3223
|
|
|
@@ -3126,7 +3362,7 @@ function detectPackageManager2(cwd) {
|
|
|
3126
3362
|
}
|
|
3127
3363
|
function shellOut(cmd, args, cwd, stream = true) {
|
|
3128
3364
|
try {
|
|
3129
|
-
|
|
3365
|
+
execFileSync14(cmd, args, {
|
|
3130
3366
|
cwd,
|
|
3131
3367
|
stdio: stream ? "inherit" : "pipe",
|
|
3132
3368
|
env: { ...process.env, HUSKY: "0", SKIP_HOOKS: "1", CI: process.env.CI ?? "1" }
|
|
@@ -3139,7 +3375,7 @@ function shellOut(cmd, args, cwd, stream = true) {
|
|
|
3139
3375
|
}
|
|
3140
3376
|
function isOnPath(bin) {
|
|
3141
3377
|
try {
|
|
3142
|
-
|
|
3378
|
+
execFileSync14("which", [bin], { stdio: "pipe" });
|
|
3143
3379
|
return true;
|
|
3144
3380
|
} catch {
|
|
3145
3381
|
return false;
|
|
@@ -3173,7 +3409,7 @@ function installLitellmIfNeeded(cwd) {
|
|
|
3173
3409
|
} catch {
|
|
3174
3410
|
}
|
|
3175
3411
|
try {
|
|
3176
|
-
|
|
3412
|
+
execFileSync14("python3", ["-c", "import litellm"], { stdio: "pipe" });
|
|
3177
3413
|
process.stdout.write("\u2192 kody2: litellm already installed\n");
|
|
3178
3414
|
return 0;
|
|
3179
3415
|
} catch {
|
|
@@ -3183,16 +3419,16 @@ function installLitellmIfNeeded(cwd) {
|
|
|
3183
3419
|
}
|
|
3184
3420
|
function configureGitIdentity(cwd) {
|
|
3185
3421
|
try {
|
|
3186
|
-
const name =
|
|
3422
|
+
const name = execFileSync14("git", ["config", "user.name"], { cwd, stdio: "pipe", encoding: "utf-8" }).trim();
|
|
3187
3423
|
if (name) return;
|
|
3188
3424
|
} catch {
|
|
3189
3425
|
}
|
|
3190
3426
|
try {
|
|
3191
|
-
|
|
3427
|
+
execFileSync14("git", ["config", "user.name", "kody2-bot"], { cwd, stdio: "pipe" });
|
|
3192
3428
|
} catch {
|
|
3193
3429
|
}
|
|
3194
3430
|
try {
|
|
3195
|
-
|
|
3431
|
+
execFileSync14("git", ["config", "user.email", "kody2-bot@users.noreply.github.com"], { cwd, stdio: "pipe" });
|
|
3196
3432
|
} catch {
|
|
3197
3433
|
}
|
|
3198
3434
|
}
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
{ "script": "fixFlow", "runWhen": { "args.mode": "fix" } },
|
|
68
68
|
{ "script": "fixCiFlow", "runWhen": { "args.mode": "fix-ci" } },
|
|
69
69
|
{ "script": "resolveFlow", "runWhen": { "args.mode": "resolve" } },
|
|
70
|
+
{ "script": "loadTaskState" },
|
|
70
71
|
{ "script": "loadConventions" },
|
|
71
72
|
{ "script": "loadCoverageRules" },
|
|
72
73
|
{ "script": "composePrompt" }
|
|
@@ -78,7 +79,21 @@
|
|
|
78
79
|
{ "script": "commitAndPush" },
|
|
79
80
|
{ "script": "ensurePr" },
|
|
80
81
|
{ "script": "postIssueComment" },
|
|
81
|
-
{ "script": "writeRunSummary" }
|
|
82
|
+
{ "script": "writeRunSummary" },
|
|
83
|
+
{ "script": "saveTaskState" }
|
|
84
|
+
]
|
|
85
|
+
},
|
|
86
|
+
"output": {
|
|
87
|
+
"actionTypes": [
|
|
88
|
+
"RUN_COMPLETED",
|
|
89
|
+
"RUN_FAILED",
|
|
90
|
+
"FIX_COMPLETED",
|
|
91
|
+
"FIX_FAILED",
|
|
92
|
+
"FIX_CI_COMPLETED",
|
|
93
|
+
"FIX_CI_FAILED",
|
|
94
|
+
"RESOLVE_COMPLETED",
|
|
95
|
+
"RESOLVE_FAILED",
|
|
96
|
+
"AGENT_NOT_RUN"
|
|
82
97
|
]
|
|
83
98
|
}
|
|
84
99
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kody-ade/kody-engine",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
4
4
|
"description": "kody2 — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|