@kody-ade/kody-engine 0.2.4 → 0.2.5
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
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.5",
|
|
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",
|
|
@@ -1898,6 +1898,55 @@ function postWith(type, n, body, cwd) {
|
|
|
1898
1898
|
}
|
|
1899
1899
|
}
|
|
1900
1900
|
|
|
1901
|
+
// src/scripts/postReviewResult.ts
|
|
1902
|
+
function detectVerdict(body) {
|
|
1903
|
+
const m = body.match(/##\s*Verdict\s*:\s*(PASS|CONCERNS|FAIL)\b/i);
|
|
1904
|
+
if (!m) return "UNKNOWN";
|
|
1905
|
+
return m[1].toUpperCase();
|
|
1906
|
+
}
|
|
1907
|
+
var postReviewResult = async (ctx, _profile, agentResult) => {
|
|
1908
|
+
const prNumber = ctx.data.commentTargetNumber;
|
|
1909
|
+
if (!prNumber) {
|
|
1910
|
+
ctx.output.exitCode = 99;
|
|
1911
|
+
ctx.output.reason = "review postflight: no PR number in context";
|
|
1912
|
+
return;
|
|
1913
|
+
}
|
|
1914
|
+
if (!agentResult || agentResult.outcome !== "completed") {
|
|
1915
|
+
const reason = agentResult?.error ?? "agent did not complete";
|
|
1916
|
+
try {
|
|
1917
|
+
postPrReviewComment(prNumber, `\u26A0\uFE0F kody2 review FAILED: ${truncate2(reason, 1e3)}`, ctx.cwd);
|
|
1918
|
+
} catch {
|
|
1919
|
+
}
|
|
1920
|
+
ctx.output.exitCode = 1;
|
|
1921
|
+
ctx.output.reason = reason;
|
|
1922
|
+
return;
|
|
1923
|
+
}
|
|
1924
|
+
const reviewBody = agentResult.finalText.trim();
|
|
1925
|
+
if (!reviewBody) {
|
|
1926
|
+
try {
|
|
1927
|
+
postPrReviewComment(prNumber, `\u26A0\uFE0F kody2 review FAILED: agent produced no review body`, ctx.cwd);
|
|
1928
|
+
} catch {
|
|
1929
|
+
}
|
|
1930
|
+
ctx.output.exitCode = 1;
|
|
1931
|
+
ctx.output.reason = "empty review body";
|
|
1932
|
+
return;
|
|
1933
|
+
}
|
|
1934
|
+
try {
|
|
1935
|
+
postPrReviewComment(prNumber, reviewBody, ctx.cwd);
|
|
1936
|
+
} catch (err) {
|
|
1937
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1938
|
+
ctx.output.exitCode = 4;
|
|
1939
|
+
ctx.output.reason = `failed to post review comment: ${msg}`;
|
|
1940
|
+
return;
|
|
1941
|
+
}
|
|
1942
|
+
const verdict = detectVerdict(reviewBody);
|
|
1943
|
+
ctx.data.reviewVerdict = verdict;
|
|
1944
|
+
ctx.output.exitCode = verdict === "FAIL" ? 1 : 0;
|
|
1945
|
+
process.stdout.write(`
|
|
1946
|
+
REVIEW_POSTED=https://github.com/${ctx.config.github.owner}/${ctx.config.github.repo}/pull/${prNumber} (verdict: ${verdict})
|
|
1947
|
+
`);
|
|
1948
|
+
};
|
|
1949
|
+
|
|
1901
1950
|
// src/scripts/resolveFlow.ts
|
|
1902
1951
|
import { execFileSync as execFileSync10 } from "child_process";
|
|
1903
1952
|
var CONFLICT_DIFF_MAX_BYTES = 4e4;
|
|
@@ -1988,6 +2037,33 @@ function tryPostPr3(prNumber, body, cwd) {
|
|
|
1988
2037
|
}
|
|
1989
2038
|
}
|
|
1990
2039
|
|
|
2040
|
+
// src/scripts/reviewFlow.ts
|
|
2041
|
+
var reviewFlow = async (ctx) => {
|
|
2042
|
+
const prNumber = ctx.args.pr;
|
|
2043
|
+
const pr = getPr(prNumber, ctx.cwd);
|
|
2044
|
+
if (pr.state !== "OPEN") {
|
|
2045
|
+
ctx.output.exitCode = 1;
|
|
2046
|
+
ctx.output.reason = `PR #${prNumber} is not OPEN (state: ${pr.state})`;
|
|
2047
|
+
ctx.skipAgent = true;
|
|
2048
|
+
return;
|
|
2049
|
+
}
|
|
2050
|
+
ctx.data.pr = pr;
|
|
2051
|
+
ctx.data.commentTargetType = "pr";
|
|
2052
|
+
ctx.data.commentTargetNumber = prNumber;
|
|
2053
|
+
checkoutPrBranch(prNumber, ctx.cwd);
|
|
2054
|
+
ctx.data.branch = getCurrentBranch(ctx.cwd);
|
|
2055
|
+
ctx.data.prDiff = getPrDiff(prNumber, ctx.cwd);
|
|
2056
|
+
const runUrl = getRunUrl();
|
|
2057
|
+
const runSuffix = runUrl ? `, run ${runUrl}` : "";
|
|
2058
|
+
tryPostPr4(prNumber, `\u{1F440} kody2 review started on PR #${prNumber}${runSuffix}`, ctx.cwd);
|
|
2059
|
+
};
|
|
2060
|
+
function tryPostPr4(prNumber, body, cwd) {
|
|
2061
|
+
try {
|
|
2062
|
+
postPrReviewComment(prNumber, body, cwd);
|
|
2063
|
+
} catch {
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
|
|
1991
2067
|
// src/scripts/runFlow.ts
|
|
1992
2068
|
var runFlow = async (ctx) => {
|
|
1993
2069
|
const issueNumber = ctx.args.issue;
|
|
@@ -2138,6 +2214,7 @@ var preflightScripts = {
|
|
|
2138
2214
|
fixFlow,
|
|
2139
2215
|
fixCiFlow,
|
|
2140
2216
|
resolveFlow,
|
|
2217
|
+
reviewFlow,
|
|
2141
2218
|
initFlow,
|
|
2142
2219
|
loadConventions,
|
|
2143
2220
|
loadCoverageRules,
|
|
@@ -2150,6 +2227,7 @@ var postflightScripts = {
|
|
|
2150
2227
|
commitAndPush: commitAndPush2,
|
|
2151
2228
|
ensurePr: ensurePr2,
|
|
2152
2229
|
postIssueComment: postIssueComment2,
|
|
2230
|
+
postReviewResult,
|
|
2153
2231
|
writeRunSummary
|
|
2154
2232
|
};
|
|
2155
2233
|
var allScriptNames = /* @__PURE__ */ new Set([
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "review",
|
|
3
|
+
"describe": "Read-only structured review of an open PR. Posts one comment, never commits.",
|
|
4
|
+
|
|
5
|
+
"inputs": [
|
|
6
|
+
{
|
|
7
|
+
"name": "pr",
|
|
8
|
+
"flag": "--pr",
|
|
9
|
+
"type": "int",
|
|
10
|
+
"required": true,
|
|
11
|
+
"describe": "GitHub PR number to review."
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
|
|
15
|
+
"claudeCode": {
|
|
16
|
+
"model": "inherit",
|
|
17
|
+
"permissionMode": "default",
|
|
18
|
+
"maxTurns": null,
|
|
19
|
+
"systemPromptAppend": null,
|
|
20
|
+
"tools": ["Read", "Grep", "Glob", "Bash"],
|
|
21
|
+
"hooks": { "PreToolUse": [], "PostToolUse": [], "Stop": [] },
|
|
22
|
+
"skills": [],
|
|
23
|
+
"commands": [],
|
|
24
|
+
"subagents": [],
|
|
25
|
+
"plugins": [],
|
|
26
|
+
"mcpServers": []
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
"cliTools": [],
|
|
30
|
+
|
|
31
|
+
"scripts": {
|
|
32
|
+
"preflight": [
|
|
33
|
+
{ "script": "reviewFlow" },
|
|
34
|
+
{ "script": "loadConventions" },
|
|
35
|
+
{ "script": "composePrompt" }
|
|
36
|
+
],
|
|
37
|
+
"postflight": [
|
|
38
|
+
{ "script": "postReviewResult" }
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
You are Kody, a senior code reviewer. Review PR #{{pr.number}} carefully and post ONE structured review comment. Do NOT edit any files. Do NOT run any `git` or `gh` commands. Use Read / Grep / Glob / Bash only to inspect the diff and surrounding code.
|
|
2
|
+
|
|
3
|
+
# PR #{{pr.number}}: {{pr.title}}
|
|
4
|
+
|
|
5
|
+
Base: {{pr.baseRefName}} ← Head: {{pr.headRefName}}
|
|
6
|
+
|
|
7
|
+
{{pr.body}}
|
|
8
|
+
|
|
9
|
+
{{conventionsBlock}}
|
|
10
|
+
|
|
11
|
+
# Diff
|
|
12
|
+
|
|
13
|
+
```diff
|
|
14
|
+
{{prDiff}}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
# Required output
|
|
18
|
+
|
|
19
|
+
Your FINAL message must be a markdown-formatted review comment, **structured exactly as below** — no preamble, no DONE / COMMIT_MSG / PR_SUMMARY markers. The entire final message IS the review comment and will be posted verbatim:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
## Verdict: PASS | CONCERNS | FAIL
|
|
23
|
+
|
|
24
|
+
### Summary
|
|
25
|
+
<2-3 sentences: what this PR does, is the approach sound>
|
|
26
|
+
|
|
27
|
+
### Strengths
|
|
28
|
+
- <bullet>
|
|
29
|
+
- <bullet>
|
|
30
|
+
|
|
31
|
+
### Concerns
|
|
32
|
+
- <bullet, or "None" if none>
|
|
33
|
+
|
|
34
|
+
### Suggestions
|
|
35
|
+
- <bullet with file:line reference where possible>
|
|
36
|
+
|
|
37
|
+
### Bottom line
|
|
38
|
+
<one sentence>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
# Rules
|
|
42
|
+
|
|
43
|
+
- No file edits. No `git`/`gh` invocations. Read-only investigation.
|
|
44
|
+
- Be specific: cite file paths and line numbers. No generic advice.
|
|
45
|
+
- Verdict **FAIL** only for clear correctness / security / regression risks.
|
|
46
|
+
- Verdict **CONCERNS** for style / clarity / test-coverage gaps that shouldn't block.
|
|
47
|
+
- Verdict **PASS** when the PR meets spec with no blocking issues.
|
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.5",
|
|
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",
|