@kody-ade/kody-engine 0.3.16 → 0.3.18
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
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// package.json
|
|
4
4
|
var package_default = {
|
|
5
5
|
name: "@kody-ade/kody-engine",
|
|
6
|
-
version: "0.3.
|
|
6
|
+
version: "0.3.18",
|
|
7
7
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
8
8
|
license: "MIT",
|
|
9
9
|
type: "module",
|
|
@@ -675,10 +675,10 @@ function autoDispatch(opts) {
|
|
|
675
675
|
if (!Number.isNaN(n) && n > 0) {
|
|
676
676
|
return { executable: "run", cliArgs: { issue: n }, target: n };
|
|
677
677
|
}
|
|
678
|
-
return { executable: "
|
|
678
|
+
return { executable: "mission-scheduler", cliArgs: {}, target: 0 };
|
|
679
679
|
}
|
|
680
680
|
if (eventName === "schedule") {
|
|
681
|
-
return { executable: "
|
|
681
|
+
return { executable: "mission-scheduler", cliArgs: {}, target: 0 };
|
|
682
682
|
}
|
|
683
683
|
if (eventName !== "issue_comment") return null;
|
|
684
684
|
const body = String(event.comment?.body ?? "").toLowerCase();
|
|
@@ -2735,26 +2735,26 @@ function postPrReviewComment(prNumber, body, cwd) {
|
|
|
2735
2735
|
}
|
|
2736
2736
|
}
|
|
2737
2737
|
|
|
2738
|
-
// src/scripts/
|
|
2739
|
-
var
|
|
2738
|
+
// src/scripts/dispatchMissionTicks.ts
|
|
2739
|
+
var dispatchMissionTicks = async (ctx, _profile, args) => {
|
|
2740
2740
|
ctx.skipAgent = true;
|
|
2741
2741
|
const label = String(args?.label ?? "");
|
|
2742
2742
|
const targetExecutable = String(args?.targetExecutable ?? "");
|
|
2743
|
-
if (!label) throw new Error("
|
|
2744
|
-
if (!targetExecutable) throw new Error("
|
|
2743
|
+
if (!label) throw new Error("dispatchMissionTicks: `with.label` is required");
|
|
2744
|
+
if (!targetExecutable) throw new Error("dispatchMissionTicks: `with.targetExecutable` is required");
|
|
2745
2745
|
const issueArg = String(args?.issueArg ?? "issue");
|
|
2746
2746
|
const issues = listIssuesByLabel(label, ctx.cwd);
|
|
2747
|
-
ctx.data.
|
|
2747
|
+
ctx.data.missionIssueCount = issues.length;
|
|
2748
2748
|
if (issues.length === 0) {
|
|
2749
|
-
process.stdout.write(`[
|
|
2749
|
+
process.stdout.write(`[missions] no open issues with label "${label}"
|
|
2750
2750
|
`);
|
|
2751
2751
|
return;
|
|
2752
2752
|
}
|
|
2753
|
-
process.stdout.write(`[
|
|
2753
|
+
process.stdout.write(`[missions] ticking ${issues.length} issue(s) via ${targetExecutable}
|
|
2754
2754
|
`);
|
|
2755
2755
|
const results = [];
|
|
2756
2756
|
for (const issue of issues) {
|
|
2757
|
-
process.stdout.write(`[
|
|
2757
|
+
process.stdout.write(`[missions] \u2192 tick #${issue.number}: ${issue.title}
|
|
2758
2758
|
`);
|
|
2759
2759
|
try {
|
|
2760
2760
|
const out = await runExecutable(targetExecutable, {
|
|
@@ -2766,17 +2766,17 @@ var dispatchManagerTicks = async (ctx, _profile, args) => {
|
|
|
2766
2766
|
});
|
|
2767
2767
|
results.push({ issue: issue.number, exitCode: out.exitCode, reason: out.reason });
|
|
2768
2768
|
if (out.exitCode !== 0) {
|
|
2769
|
-
process.stderr.write(`[
|
|
2769
|
+
process.stderr.write(`[missions] tick #${issue.number} failed (exit ${out.exitCode}): ${out.reason ?? ""}
|
|
2770
2770
|
`);
|
|
2771
2771
|
}
|
|
2772
2772
|
} catch (err) {
|
|
2773
2773
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2774
|
-
process.stderr.write(`[
|
|
2774
|
+
process.stderr.write(`[missions] tick #${issue.number} crashed: ${msg}
|
|
2775
2775
|
`);
|
|
2776
2776
|
results.push({ issue: issue.number, exitCode: 99, reason: msg });
|
|
2777
2777
|
}
|
|
2778
2778
|
}
|
|
2779
|
-
ctx.data.
|
|
2779
|
+
ctx.data.missionTickResults = results;
|
|
2780
2780
|
ctx.output.exitCode = 0;
|
|
2781
2781
|
};
|
|
2782
2782
|
function listIssuesByLabel(label, cwd) {
|
|
@@ -5544,7 +5544,7 @@ var preflightScripts = {
|
|
|
5544
5544
|
skipAgent,
|
|
5545
5545
|
classifyByLabel,
|
|
5546
5546
|
diagMcp,
|
|
5547
|
-
|
|
5547
|
+
dispatchMissionTicks
|
|
5548
5548
|
};
|
|
5549
5549
|
var postflightScripts = {
|
|
5550
5550
|
parseAgentResult: parseAgentResult2,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "
|
|
2
|
+
"name": "mission-scheduler",
|
|
3
3
|
"role": "watch",
|
|
4
|
-
"describe": "Scheduled: for every open issue labeled kody:
|
|
4
|
+
"describe": "Scheduled: for every open issue labeled kody:mission, invoke mission-tick once. No agent on the scheduler itself.",
|
|
5
5
|
"kind": "scheduled",
|
|
6
6
|
"schedule": "*/5 * * * *",
|
|
7
7
|
"inputs": [],
|
|
@@ -36,12 +36,12 @@
|
|
|
36
36
|
"scripts": {
|
|
37
37
|
"preflight": [
|
|
38
38
|
{
|
|
39
|
-
"script": "
|
|
39
|
+
"script": "dispatchMissionTicks",
|
|
40
40
|
"with": {
|
|
41
|
-
"label": "kody:
|
|
41
|
+
"label": "kody:mission",
|
|
42
42
|
"color": "1d76db",
|
|
43
|
-
"description": "kody: issue is a
|
|
44
|
-
"targetExecutable": "
|
|
43
|
+
"description": "kody: issue is a mission — scheduler ticks it every cron wake",
|
|
44
|
+
"targetExecutable": "mission-tick",
|
|
45
45
|
"issueArg": "issue"
|
|
46
46
|
}
|
|
47
47
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "
|
|
2
|
+
"name": "mission-tick",
|
|
3
3
|
"role": "primitive",
|
|
4
|
-
"describe": "One classifier tick for one
|
|
4
|
+
"describe": "One classifier tick for one mission issue: read intent + state, decide and execute via gh, emit next state.",
|
|
5
5
|
"kind": "oneshot",
|
|
6
6
|
"inputs": [
|
|
7
7
|
{
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"flag": "--issue",
|
|
10
10
|
"type": "int",
|
|
11
11
|
"required": true,
|
|
12
|
-
"describe": "GitHub issue number that owns this
|
|
12
|
+
"describe": "GitHub issue number that owns this mission."
|
|
13
13
|
}
|
|
14
14
|
],
|
|
15
15
|
"claudeCode": {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
{
|
|
46
46
|
"script": "loadIssueStateComment",
|
|
47
47
|
"with": {
|
|
48
|
-
"marker": "kody-
|
|
48
|
+
"marker": "kody-mission-state",
|
|
49
49
|
"issueArg": "issue"
|
|
50
50
|
}
|
|
51
51
|
},
|
|
@@ -57,13 +57,13 @@
|
|
|
57
57
|
{
|
|
58
58
|
"script": "parseIssueStateFromAgentResult",
|
|
59
59
|
"with": {
|
|
60
|
-
"fenceLabel": "kody-
|
|
60
|
+
"fenceLabel": "kody-mission-next-state"
|
|
61
61
|
}
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
"script": "writeIssueStateComment",
|
|
65
65
|
"with": {
|
|
66
|
-
"marker": "kody-
|
|
66
|
+
"marker": "kody-mission-state",
|
|
67
67
|
"issueArg": "issue"
|
|
68
68
|
}
|
|
69
69
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
You are **kody
|
|
1
|
+
You are **kody mission-tick**, the coordinator for one GitHub-issue-scoped mission. You do **not** touch code, do **not** commit, and do **not** edit files. You coordinate other kody executables by dispatching their workflows, observing their runs, and writing back state.
|
|
2
2
|
|
|
3
3
|
## The mission
|
|
4
4
|
|
|
@@ -16,25 +16,26 @@ This is the state you wrote at the end of the previous tick (or `null` if this i
|
|
|
16
16
|
{{issueStateJson}}
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
`cursor` is *your* enum — pick whatever labels map cleanly to your mission's phases (e.g. `seed`, `spawn-release`, `waiting-release`, `merge-to-dev`, `finalize`, `done`). `data` is where you stash anything you need on the next tick (run IDs, SHAs, child issue numbers, budget counters). `done: true`
|
|
19
|
+
`cursor` is *your* enum — pick whatever labels map cleanly to your mission's phases (e.g. `seed`, `spawn-release`, `waiting-release`, `merge-to-dev`, `finalize`, `done`). `data` is where you stash anything you need on the next tick (run IDs, SHAs, child issue numbers, budget counters). `done: true` is how you signal to future-you that the mission is over — check for it first on every tick and exit early without acting if it's set. Closing the issue also stops ticks (the scheduler only lists open issues).
|
|
20
20
|
|
|
21
21
|
## What to do on this tick
|
|
22
22
|
|
|
23
|
-
1. **
|
|
24
|
-
2. **
|
|
23
|
+
1. **Check `done`.** If the prior state has `done: true`, emit the same state back unchanged and exit without any other action. The mission is over; don't resurrect it.
|
|
24
|
+
2. **Re-read the mission.** If the human has edited the description in a way that changes what "on track" means, adapt.
|
|
25
|
+
3. **Decide the single next step** based on (cursor, data, mission).
|
|
25
26
|
- If `cursor` is `null`/first-run, initialize: plan the pipeline, pick an initial cursor, record any baseline info in `data`.
|
|
26
27
|
- If you're waiting on a child run, check its status via `gh run view <id> --json status,conclusion`. If still running, just update cursor/data minimally and exit — the next cron wake will check again. If succeeded, advance. If failed, record the failure and either spawn a remediation child or mark `done: true` with an error.
|
|
27
28
|
- If it's time to spawn a child executable, use `gh workflow run kody.yml -f issue_number=<N>` (or the appropriate workflow + inputs for the consumer repo). Capture the dispatched run's ID via `gh run list --workflow=kody.yml --limit 1 --json databaseId --jq '.[0].databaseId'` and stash it in `data`.
|
|
28
29
|
- If the mission is complete, set `done: true` and a terminal cursor like `done`.
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
4. **Optionally post a human-readable narration comment** on the issue summarizing what you just did (spawned run #12345, waiting on CI, etc.). Keep it short. Use `gh issue comment {{issueNumber}} --body "..."`.
|
|
31
|
+
5. **Emit the new state** at the very end of your response using the fenced block below. Do not include `version` or `rev` — the postflight script manages those.
|
|
31
32
|
|
|
32
33
|
## Output contract (MANDATORY, exactly once, at the end)
|
|
33
34
|
|
|
34
|
-
End your response with a single fenced block using the `kody-
|
|
35
|
+
End your response with a single fenced block using the `kody-mission-next-state` language tag:
|
|
35
36
|
|
|
36
37
|
````
|
|
37
|
-
```kody-
|
|
38
|
+
```kody-mission-next-state
|
|
38
39
|
{
|
|
39
40
|
"cursor": "<your-next-cursor>",
|
|
40
41
|
"data": { ... },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kody-ade/kody-engine",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.18",
|
|
4
4
|
"description": "kody — autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|