@kody-ade/kody-engine 0.2.8 → 0.2.10
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 +89 -33
- package/dist/executables/orchestrator/profile.json +55 -0
- package/dist/executables/orchestrator/prompt.md +56 -0
- package/dist/executables/orchestrator/prompts/orchestrator.md +56 -0
- package/dist/executables/plan/profile.json +49 -0
- package/dist/executables/plan/prompt.md +42 -0
- package/dist/executables/plan/prompts/plan.md +42 -0
- 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.10",
|
|
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",
|
|
@@ -108,6 +108,7 @@ function loadConfig(projectDir = process.cwd()) {
|
|
|
108
108
|
},
|
|
109
109
|
issueContext: parseIssueContext(raw.issueContext),
|
|
110
110
|
testRequirements: parseTestRequirements(raw.testRequirements),
|
|
111
|
+
defaultExecutable: typeof raw.defaultExecutable === "string" && raw.defaultExecutable.length > 0 ? raw.defaultExecutable : void 0,
|
|
111
112
|
release: parseReleaseConfig(raw.release)
|
|
112
113
|
};
|
|
113
114
|
}
|
|
@@ -1962,6 +1963,27 @@ var loadCoverageRules = async (ctx) => {
|
|
|
1962
1963
|
ctx.data.coverageRules = ctx.config.testRequirements ?? [];
|
|
1963
1964
|
};
|
|
1964
1965
|
|
|
1966
|
+
// src/scripts/loadIssueContext.ts
|
|
1967
|
+
var DEFAULT_COMMENT_LIMIT = 12;
|
|
1968
|
+
var DEFAULT_COMMENT_MAX_BYTES = 4e3;
|
|
1969
|
+
var loadIssueContext = async (ctx) => {
|
|
1970
|
+
const issueNumber = ctx.args.issue;
|
|
1971
|
+
if (typeof issueNumber !== "number" || issueNumber <= 0) {
|
|
1972
|
+
throw new Error("loadIssueContext: ctx.args.issue (positive integer) is required");
|
|
1973
|
+
}
|
|
1974
|
+
const issue = getIssue(issueNumber, ctx.cwd);
|
|
1975
|
+
const cfgCtx = ctx.config.issueContext ?? {};
|
|
1976
|
+
const limit = cfgCtx.commentLimit ?? DEFAULT_COMMENT_LIMIT;
|
|
1977
|
+
const maxBytes = cfgCtx.commentMaxBytes ?? DEFAULT_COMMENT_MAX_BYTES;
|
|
1978
|
+
const sorted = [...issue.comments].sort((a, b) => a.createdAt < b.createdAt ? 1 : -1);
|
|
1979
|
+
const kept = sorted.slice(0, limit);
|
|
1980
|
+
const commentsFormatted = kept.length === 0 ? "(no comments yet)" : kept.map((c) => `- **${c.author}** (${c.createdAt}):
|
|
1981
|
+
${truncate2(c.body, maxBytes).replace(/\n/g, "\n ")}`).join("\n\n");
|
|
1982
|
+
ctx.data.issue = { ...issue, commentsFormatted };
|
|
1983
|
+
ctx.data.commentTargetType = "issue";
|
|
1984
|
+
ctx.data.commentTargetNumber = issueNumber;
|
|
1985
|
+
};
|
|
1986
|
+
|
|
1965
1987
|
// src/state.ts
|
|
1966
1988
|
import { execFileSync as execFileSync10 } from "child_process";
|
|
1967
1989
|
var STATE_BEGIN = "<!-- kody2:state:v1:begin -->";
|
|
@@ -2965,6 +2987,7 @@ var preflightScripts = {
|
|
|
2965
2987
|
releaseFlow,
|
|
2966
2988
|
watchStalePrsFlow,
|
|
2967
2989
|
loadTaskState,
|
|
2990
|
+
loadIssueContext,
|
|
2968
2991
|
loadConventions,
|
|
2969
2992
|
loadCoverageRules,
|
|
2970
2993
|
composePrompt
|
|
@@ -3223,11 +3246,13 @@ import * as path12 from "path";
|
|
|
3223
3246
|
|
|
3224
3247
|
// src/dispatch.ts
|
|
3225
3248
|
import * as fs14 from "fs";
|
|
3226
|
-
function autoDispatch(
|
|
3227
|
-
|
|
3249
|
+
function autoDispatch(opts) {
|
|
3250
|
+
const explicit = opts?.explicit;
|
|
3251
|
+
if (explicit?.issueNumber && explicit.issueNumber > 0) {
|
|
3228
3252
|
return {
|
|
3229
|
-
|
|
3230
|
-
|
|
3253
|
+
executable: "build",
|
|
3254
|
+
cliArgs: { mode: "run", issue: explicit.issueNumber },
|
|
3255
|
+
target: explicit.issueNumber
|
|
3231
3256
|
};
|
|
3232
3257
|
}
|
|
3233
3258
|
const eventName = process.env.GITHUB_EVENT_NAME;
|
|
@@ -3241,30 +3266,60 @@ function autoDispatch(explicit) {
|
|
|
3241
3266
|
}
|
|
3242
3267
|
if (eventName === "workflow_dispatch") {
|
|
3243
3268
|
const n = parseInt(String(event.inputs?.issue_number ?? ""), 10);
|
|
3244
|
-
if (!Number.isNaN(n) && n > 0)
|
|
3269
|
+
if (!Number.isNaN(n) && n > 0) {
|
|
3270
|
+
return { executable: "build", cliArgs: { mode: "run", issue: n }, target: n };
|
|
3271
|
+
}
|
|
3245
3272
|
return null;
|
|
3246
3273
|
}
|
|
3247
|
-
if (eventName
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3274
|
+
if (eventName !== "issue_comment") return null;
|
|
3275
|
+
const body = String(event.comment?.body ?? "").toLowerCase();
|
|
3276
|
+
const targetNum = Number(event.issue?.number ?? 0);
|
|
3277
|
+
const isPr = !!event.issue?.pull_request;
|
|
3278
|
+
if (!targetNum) return null;
|
|
3279
|
+
const afterTag = extractAfterTag(body);
|
|
3280
|
+
if (isPr) {
|
|
3281
|
+
if (/\bfix-ci\b/.test(afterTag)) {
|
|
3282
|
+
return { executable: "build", cliArgs: { mode: "fix-ci", pr: targetNum }, target: targetNum };
|
|
3283
|
+
}
|
|
3284
|
+
if (/\bresolve\b/.test(afterTag)) {
|
|
3285
|
+
return { executable: "build", cliArgs: { mode: "resolve", pr: targetNum }, target: targetNum };
|
|
3258
3286
|
}
|
|
3259
|
-
|
|
3287
|
+
const feedback = extractFeedback(afterTag);
|
|
3288
|
+
return {
|
|
3289
|
+
executable: "build",
|
|
3290
|
+
cliArgs: { mode: "fix", pr: targetNum, ...feedback ? { feedback } : {} },
|
|
3291
|
+
target: targetNum
|
|
3292
|
+
};
|
|
3260
3293
|
}
|
|
3261
|
-
|
|
3294
|
+
const sub = extractSubcommand(afterTag);
|
|
3295
|
+
const defaultExec = opts?.config?.defaultExecutable ?? "build";
|
|
3296
|
+
if (!sub) {
|
|
3297
|
+
return asDispatch(defaultExec, targetNum);
|
|
3298
|
+
}
|
|
3299
|
+
if (sub === "build") {
|
|
3300
|
+
return { executable: "build", cliArgs: { mode: "run", issue: targetNum }, target: targetNum };
|
|
3301
|
+
}
|
|
3302
|
+
if (sub === "orchestrate" || sub === "orchestrator") {
|
|
3303
|
+
return { executable: "orchestrator", cliArgs: { issue: targetNum }, target: targetNum };
|
|
3304
|
+
}
|
|
3305
|
+
return asDispatch(sub, targetNum);
|
|
3306
|
+
}
|
|
3307
|
+
function asDispatch(executable, target) {
|
|
3308
|
+
if (executable === "build") {
|
|
3309
|
+
return { executable, cliArgs: { mode: "run", issue: target }, target };
|
|
3310
|
+
}
|
|
3311
|
+
return { executable, cliArgs: { issue: target }, target };
|
|
3262
3312
|
}
|
|
3263
3313
|
function extractAfterTag(body) {
|
|
3264
3314
|
const idx = body.indexOf("@kody2");
|
|
3265
3315
|
if (idx === -1) return body;
|
|
3266
3316
|
return body.slice(idx + "@kody2".length).trim();
|
|
3267
3317
|
}
|
|
3318
|
+
function extractSubcommand(afterTag) {
|
|
3319
|
+
const match = afterTag.match(/^([a-z][a-z0-9-]{1,40})\b/);
|
|
3320
|
+
if (!match) return null;
|
|
3321
|
+
return match[1];
|
|
3322
|
+
}
|
|
3268
3323
|
function extractFeedback(afterTag) {
|
|
3269
3324
|
const cleaned = afterTag.replace(/^(fix|please|kindly)[\s:,.-]+/i, "").trim();
|
|
3270
3325
|
return cleaned.length > 0 ? cleaned : void 0;
|
|
@@ -3463,7 +3518,13 @@ async function runCi(argv) {
|
|
|
3463
3518
|
return 0;
|
|
3464
3519
|
}
|
|
3465
3520
|
const args = parseCiArgs(argv);
|
|
3466
|
-
const
|
|
3521
|
+
const cwd = args.cwd ? path12.resolve(args.cwd) : process.cwd();
|
|
3522
|
+
let earlyConfig;
|
|
3523
|
+
try {
|
|
3524
|
+
earlyConfig = loadConfig(cwd);
|
|
3525
|
+
} catch {
|
|
3526
|
+
}
|
|
3527
|
+
const autoFallback = !args.issueNumber ? autoDispatch({ config: earlyConfig }) : null;
|
|
3467
3528
|
if (!args.issueNumber && !autoFallback) {
|
|
3468
3529
|
} else {
|
|
3469
3530
|
args.errors = args.errors.filter((e) => !e.includes("--issue"));
|
|
@@ -3475,14 +3536,13 @@ async function runCi(argv) {
|
|
|
3475
3536
|
${CI_HELP}`);
|
|
3476
3537
|
return 64;
|
|
3477
3538
|
}
|
|
3478
|
-
const cwd = args.cwd ? path12.resolve(args.cwd) : process.cwd();
|
|
3479
3539
|
const dispatch = autoFallback ?? {
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3540
|
+
executable: "build",
|
|
3541
|
+
cliArgs: { mode: "run", issue: args.issueNumber },
|
|
3542
|
+
target: args.issueNumber
|
|
3483
3543
|
};
|
|
3484
3544
|
const issueNumber = dispatch.target;
|
|
3485
|
-
process.stdout.write(`\u2192 kody2 preflight (cwd=${cwd},
|
|
3545
|
+
process.stdout.write(`\u2192 kody2 preflight (cwd=${cwd}, executable=${dispatch.executable}, target=${issueNumber})
|
|
3486
3546
|
`);
|
|
3487
3547
|
try {
|
|
3488
3548
|
const n = unpackAllSecrets();
|
|
@@ -3519,17 +3579,13 @@ ${CI_HELP}`);
|
|
|
3519
3579
|
postFailureTail(issueNumber, cwd, `preflight crashed: ${msg}`);
|
|
3520
3580
|
return 99;
|
|
3521
3581
|
}
|
|
3522
|
-
process.stdout.write(`\u2192 kody2: preflight done, handing off to kody2 ${dispatch.
|
|
3582
|
+
process.stdout.write(`\u2192 kody2: preflight done, handing off to kody2 ${dispatch.executable}
|
|
3523
3583
|
|
|
3524
3584
|
`);
|
|
3525
3585
|
try {
|
|
3526
|
-
const config = loadConfig(cwd);
|
|
3527
|
-
const
|
|
3528
|
-
|
|
3529
|
-
else cliArgs.pr = issueNumber;
|
|
3530
|
-
if (dispatch.feedback) cliArgs.feedback = dispatch.feedback;
|
|
3531
|
-
const result = await runExecutable("build", {
|
|
3532
|
-
cliArgs,
|
|
3586
|
+
const config = earlyConfig ?? loadConfig(cwd);
|
|
3587
|
+
const result = await runExecutable(dispatch.executable, {
|
|
3588
|
+
cliArgs: dispatch.cliArgs,
|
|
3533
3589
|
cwd,
|
|
3534
3590
|
config,
|
|
3535
3591
|
verbose: args.verbose,
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "orchestrator",
|
|
3
|
+
"describe": "Drive a chain of kody2 executables by posting @kody2 subcommand comments and polling the task-state comment. Atomic — one orchestrator run fires one flow.",
|
|
4
|
+
|
|
5
|
+
"inputs": [
|
|
6
|
+
{
|
|
7
|
+
"name": "issue",
|
|
8
|
+
"flag": "--issue",
|
|
9
|
+
"type": "int",
|
|
10
|
+
"required": true,
|
|
11
|
+
"describe": "GitHub issue number to drive."
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "flow",
|
|
15
|
+
"flag": "--flow",
|
|
16
|
+
"type": "string",
|
|
17
|
+
"required": false,
|
|
18
|
+
"describe": "Named flow to run (e.g. 'plan-then-build'). Defaults to plan-then-build."
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
|
|
22
|
+
"claudeCode": {
|
|
23
|
+
"model": "inherit",
|
|
24
|
+
"permissionMode": "default",
|
|
25
|
+
"maxTurns": null,
|
|
26
|
+
"systemPromptAppend": null,
|
|
27
|
+
"tools": ["Bash", "Read"],
|
|
28
|
+
"hooks": { "PreToolUse": [], "PostToolUse": [], "Stop": [] },
|
|
29
|
+
"skills": [],
|
|
30
|
+
"commands": [],
|
|
31
|
+
"subagents": [],
|
|
32
|
+
"plugins": [],
|
|
33
|
+
"mcpServers": []
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
"cliTools": [],
|
|
37
|
+
|
|
38
|
+
"scripts": {
|
|
39
|
+
"preflight": [
|
|
40
|
+
{ "script": "loadIssueContext" },
|
|
41
|
+
{ "script": "loadTaskState" },
|
|
42
|
+
{ "script": "composePrompt" }
|
|
43
|
+
],
|
|
44
|
+
"postflight": [
|
|
45
|
+
{ "script": "parseAgentResult" },
|
|
46
|
+
{ "script": "postIssueComment" },
|
|
47
|
+
{ "script": "writeRunSummary" },
|
|
48
|
+
{ "script": "saveTaskState" }
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
"output": {
|
|
53
|
+
"actionTypes": ["ORCHESTRATION_COMPLETED", "ORCHESTRATION_FAILED"]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
You are the **kody2 orchestrator** for issue #{{issue.number}} on {{repoOwner}}/{{repoName}}.
|
|
2
|
+
|
|
3
|
+
Your job: drive a 2-step flow **plan → build** by posting `@kody2 <subcommand>` comments on the issue and watching the state-comment for completion signals. You do NOT edit files. You do NOT run git. You use `gh` (via Bash) only to post comments and read the state-comment.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Issue #{{issue.number}}: {{issue.title}}
|
|
8
|
+
|
|
9
|
+
{{issue.body}}
|
|
10
|
+
|
|
11
|
+
# Required flow (plan-then-build)
|
|
12
|
+
|
|
13
|
+
1. **Kick off plan.** Post an issue comment with EXACTLY this body:
|
|
14
|
+
```
|
|
15
|
+
@kody2 plan
|
|
16
|
+
```
|
|
17
|
+
Use: `gh issue comment {{issue.number}} --body "@kody2 plan"` (in the cwd).
|
|
18
|
+
2. **Wait for plan to complete.** Poll the issue's state-comment every ~30s. The state-comment is the one whose body starts with `<!-- kody2:state:v1:begin -->`. Fetch it with:
|
|
19
|
+
```
|
|
20
|
+
gh api repos/{{repoOwner}}/{{repoName}}/issues/{{issue.number}}/comments --paginate --jq '.[] | select(.body | contains("kody2:state:v1:begin")) | .body'
|
|
21
|
+
```
|
|
22
|
+
Parse the JSON block inside the sentinels. Look for `core.lastOutcome.type == "PLAN_COMPLETED"`.
|
|
23
|
+
If `core.lastOutcome.type == "PLAN_FAILED"` OR if 10 minutes pass without completion → abort with:
|
|
24
|
+
```
|
|
25
|
+
FAILED: plan did not complete (<reason from state or "timeout">)
|
|
26
|
+
```
|
|
27
|
+
3. **Kick off build.** Post:
|
|
28
|
+
```
|
|
29
|
+
@kody2 build
|
|
30
|
+
```
|
|
31
|
+
Same `gh issue comment` command.
|
|
32
|
+
4. **Wait for build to complete.** Same poll technique. Look for `core.lastOutcome.type == "RUN_COMPLETED"` (build's success marker) or `RUN_FAILED`. If `RUN_FAILED` or 30 minutes pass → abort with `FAILED: build did not complete (...)`.
|
|
33
|
+
5. **Emit final summary.**
|
|
34
|
+
|
|
35
|
+
# Required final output
|
|
36
|
+
|
|
37
|
+
On success:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
DONE
|
|
41
|
+
COMMIT_MSG: chore(orchestrator): plan-then-build for #{{issue.number}}
|
|
42
|
+
PR_SUMMARY:
|
|
43
|
+
- Posted `@kody2 plan` and observed PLAN_COMPLETED.
|
|
44
|
+
- Posted `@kody2 build` and observed RUN_COMPLETED.
|
|
45
|
+
- Final PR: <prUrl from state>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
On failure, a single line: `FAILED: <concrete reason>`.
|
|
49
|
+
|
|
50
|
+
# Rules
|
|
51
|
+
|
|
52
|
+
- NEVER edit files. Read-only flow.
|
|
53
|
+
- NEVER run git. Only `gh` via Bash for comment posting and state polling.
|
|
54
|
+
- Between polls, sleep ~30 seconds. Do NOT poll faster than once every 30 seconds.
|
|
55
|
+
- Hard cap: 40 turns total across the whole flow. If you're approaching the cap, fail early with `FAILED: turn budget exhausted`.
|
|
56
|
+
- If you post an `@kody2` comment and the state-comment does NOT update within the poll window, the child executable likely didn't run — check the GitHub Actions runs tab URL via `gh run list --limit 5 --json conclusion,status,url` to diagnose, then fail with a concrete reason.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
You are the **kody2 orchestrator** for issue #{{issue.number}} on {{repoOwner}}/{{repoName}}.
|
|
2
|
+
|
|
3
|
+
Your job: drive a 2-step flow **plan → build** by posting `@kody2 <subcommand>` comments on the issue and watching the state-comment for completion signals. You do NOT edit files. You do NOT run git. You use `gh` (via Bash) only to post comments and read the state-comment.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Issue #{{issue.number}}: {{issue.title}}
|
|
8
|
+
|
|
9
|
+
{{issue.body}}
|
|
10
|
+
|
|
11
|
+
# Required flow (plan-then-build)
|
|
12
|
+
|
|
13
|
+
1. **Kick off plan.** Post an issue comment with EXACTLY this body:
|
|
14
|
+
```
|
|
15
|
+
@kody2 plan
|
|
16
|
+
```
|
|
17
|
+
Use: `gh issue comment {{issue.number}} --body "@kody2 plan"` (in the cwd).
|
|
18
|
+
2. **Wait for plan to complete.** Poll the issue's state-comment every ~30s. The state-comment is the one whose body starts with `<!-- kody2:state:v1:begin -->`. Fetch it with:
|
|
19
|
+
```
|
|
20
|
+
gh api repos/{{repoOwner}}/{{repoName}}/issues/{{issue.number}}/comments --paginate --jq '.[] | select(.body | contains("kody2:state:v1:begin")) | .body'
|
|
21
|
+
```
|
|
22
|
+
Parse the JSON block inside the sentinels. Look for `core.lastOutcome.type == "PLAN_COMPLETED"`.
|
|
23
|
+
If `core.lastOutcome.type == "PLAN_FAILED"` OR if 10 minutes pass without completion → abort with:
|
|
24
|
+
```
|
|
25
|
+
FAILED: plan did not complete (<reason from state or "timeout">)
|
|
26
|
+
```
|
|
27
|
+
3. **Kick off build.** Post:
|
|
28
|
+
```
|
|
29
|
+
@kody2 build
|
|
30
|
+
```
|
|
31
|
+
Same `gh issue comment` command.
|
|
32
|
+
4. **Wait for build to complete.** Same poll technique. Look for `core.lastOutcome.type == "RUN_COMPLETED"` (build's success marker) or `RUN_FAILED`. If `RUN_FAILED` or 30 minutes pass → abort with `FAILED: build did not complete (...)`.
|
|
33
|
+
5. **Emit final summary.**
|
|
34
|
+
|
|
35
|
+
# Required final output
|
|
36
|
+
|
|
37
|
+
On success:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
DONE
|
|
41
|
+
COMMIT_MSG: chore(orchestrator): plan-then-build for #{{issue.number}}
|
|
42
|
+
PR_SUMMARY:
|
|
43
|
+
- Posted `@kody2 plan` and observed PLAN_COMPLETED.
|
|
44
|
+
- Posted `@kody2 build` and observed RUN_COMPLETED.
|
|
45
|
+
- Final PR: <prUrl from state>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
On failure, a single line: `FAILED: <concrete reason>`.
|
|
49
|
+
|
|
50
|
+
# Rules
|
|
51
|
+
|
|
52
|
+
- NEVER edit files. Read-only flow.
|
|
53
|
+
- NEVER run git. Only `gh` via Bash for comment posting and state polling.
|
|
54
|
+
- Between polls, sleep ~30 seconds. Do NOT poll faster than once every 30 seconds.
|
|
55
|
+
- Hard cap: 40 turns total across the whole flow. If you're approaching the cap, fail early with `FAILED: turn budget exhausted`.
|
|
56
|
+
- If you post an `@kody2` comment and the state-comment does NOT update within the poll window, the child executable likely didn't run — check the GitHub Actions runs tab URL via `gh run list --limit 5 --json conclusion,status,url` to diagnose, then fail with a concrete reason.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "plan",
|
|
3
|
+
"describe": "Research an issue and produce a concrete implementation plan as a comment. Read-only — no branches, no commits.",
|
|
4
|
+
|
|
5
|
+
"inputs": [
|
|
6
|
+
{
|
|
7
|
+
"name": "issue",
|
|
8
|
+
"flag": "--issue",
|
|
9
|
+
"type": "int",
|
|
10
|
+
"required": true,
|
|
11
|
+
"describe": "GitHub issue number to plan."
|
|
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": "loadIssueContext" },
|
|
34
|
+
{ "script": "loadTaskState" },
|
|
35
|
+
{ "script": "loadConventions" },
|
|
36
|
+
{ "script": "composePrompt" }
|
|
37
|
+
],
|
|
38
|
+
"postflight": [
|
|
39
|
+
{ "script": "parseAgentResult" },
|
|
40
|
+
{ "script": "postIssueComment" },
|
|
41
|
+
{ "script": "writeRunSummary" },
|
|
42
|
+
{ "script": "saveTaskState" }
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
"output": {
|
|
47
|
+
"actionTypes": ["PLAN_COMPLETED", "PLAN_FAILED"]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
You are a senior engineer producing an **implementation plan** for the GitHub issue below. You will NOT write code. You will NOT run git or gh commands. You will NOT modify files. Your only outputs are:
|
|
2
|
+
|
|
3
|
+
1. Use Read / Grep / Glob / Bash (read-only) to study the codebase as much as needed.
|
|
4
|
+
2. Emit a final message with the plan wrapped in the required markers (see "Required output").
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Repo
|
|
9
|
+
- {{repoOwner}}/{{repoName}}, default branch: {{defaultBranch}}
|
|
10
|
+
|
|
11
|
+
# Issue #{{issue.number}}: {{issue.title}}
|
|
12
|
+
|
|
13
|
+
{{issue.body}}
|
|
14
|
+
|
|
15
|
+
Recent comments (most recent first, truncated):
|
|
16
|
+
{{issue.commentsFormatted}}
|
|
17
|
+
|
|
18
|
+
{{conventionsBlock}}
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Required output
|
|
23
|
+
|
|
24
|
+
Your FINAL message must be exactly this shape (no extra text before or after):
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
DONE
|
|
28
|
+
COMMIT_MSG: plan: <very short title>
|
|
29
|
+
PR_SUMMARY:
|
|
30
|
+
<A concrete implementation plan in markdown. Include:
|
|
31
|
+
- Files to change (with paths), and the change in each.
|
|
32
|
+
- New files to create, with their purpose and rough shape.
|
|
33
|
+
- Any ambiguities that need the human to resolve first.
|
|
34
|
+
- Verification checklist (typecheck / tests / lint expectations).
|
|
35
|
+
Keep to ~60 lines or less. No filler. No marketing language.>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
# Rules
|
|
39
|
+
- Read-only. Do NOT modify any file.
|
|
40
|
+
- Do NOT run git or gh commands.
|
|
41
|
+
- No speculative scope — plan only what the issue asks for.
|
|
42
|
+
- If the issue is ambiguous and you cannot make progress without input, output `FAILED: <what's unclear>` instead of a plan.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
You are a senior engineer producing an **implementation plan** for the GitHub issue below. You will NOT write code. You will NOT run git or gh commands. You will NOT modify files. Your only outputs are:
|
|
2
|
+
|
|
3
|
+
1. Use Read / Grep / Glob / Bash (read-only) to study the codebase as much as needed.
|
|
4
|
+
2. Emit a final message with the plan wrapped in the required markers (see "Required output").
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Repo
|
|
9
|
+
- {{repoOwner}}/{{repoName}}, default branch: {{defaultBranch}}
|
|
10
|
+
|
|
11
|
+
# Issue #{{issue.number}}: {{issue.title}}
|
|
12
|
+
|
|
13
|
+
{{issue.body}}
|
|
14
|
+
|
|
15
|
+
Recent comments (most recent first, truncated):
|
|
16
|
+
{{issue.commentsFormatted}}
|
|
17
|
+
|
|
18
|
+
{{conventionsBlock}}
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Required output
|
|
23
|
+
|
|
24
|
+
Your FINAL message must be exactly this shape (no extra text before or after):
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
DONE
|
|
28
|
+
COMMIT_MSG: plan: <very short title>
|
|
29
|
+
PR_SUMMARY:
|
|
30
|
+
<A concrete implementation plan in markdown. Include:
|
|
31
|
+
- Files to change (with paths), and the change in each.
|
|
32
|
+
- New files to create, with their purpose and rough shape.
|
|
33
|
+
- Any ambiguities that need the human to resolve first.
|
|
34
|
+
- Verification checklist (typecheck / tests / lint expectations).
|
|
35
|
+
Keep to ~60 lines or less. No filler. No marketing language.>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
# Rules
|
|
39
|
+
- Read-only. Do NOT modify any file.
|
|
40
|
+
- Do NOT run git or gh commands.
|
|
41
|
+
- No speculative scope — plan only what the issue asks for.
|
|
42
|
+
- If the issue is ambiguous and you cannot make progress without input, output `FAILED: <what's unclear>` instead of a plan.
|
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.10",
|
|
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",
|