@kody-ade/kody-engine 0.4.209 → 0.4.210
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
|
@@ -1542,7 +1542,7 @@ var init_loadCoverageRules = __esm({
|
|
|
1542
1542
|
// package.json
|
|
1543
1543
|
var package_default = {
|
|
1544
1544
|
name: "@kody-ade/kody-engine",
|
|
1545
|
-
version: "0.4.
|
|
1545
|
+
version: "0.4.210",
|
|
1546
1546
|
description: "kody \u2014 autonomous development engine. Single-session Claude Code agent behind a generic executor + declarative executable profiles.",
|
|
1547
1547
|
license: "MIT",
|
|
1548
1548
|
type: "module",
|
|
@@ -4037,9 +4037,11 @@ function loadProfile(profilePath) {
|
|
|
4037
4037
|
return {
|
|
4038
4038
|
...base,
|
|
4039
4039
|
name: requireString(profilePath, r, "name"),
|
|
4040
|
+
executable: execRef,
|
|
4040
4041
|
describe: typeof r.describe === "string" ? r.describe : base.describe,
|
|
4041
4042
|
staff: typeof r.staff === "string" && r.staff.trim() ? r.staff.trim() : base.staff,
|
|
4042
4043
|
every: typeof r.every === "string" && r.every.trim() ? r.every.trim() : void 0,
|
|
4044
|
+
dutyTools: Array.isArray(r.dutyTools) ? r.dutyTools.map((t) => String(t).trim()).filter(Boolean) : base.dutyTools,
|
|
4043
4045
|
mentions: Array.isArray(r.mentions) ? r.mentions.map((m) => String(m).trim()).filter(Boolean) : base.mentions
|
|
4044
4046
|
};
|
|
4045
4047
|
}
|
|
@@ -4078,6 +4080,7 @@ function loadProfile(profilePath) {
|
|
|
4078
4080
|
}
|
|
4079
4081
|
const profile = {
|
|
4080
4082
|
name: requireString(profilePath, r, "name"),
|
|
4083
|
+
executable: void 0,
|
|
4081
4084
|
describe: typeof r.describe === "string" ? r.describe : "",
|
|
4082
4085
|
// Optional persona to run as. Empty/blank string → undefined (no persona).
|
|
4083
4086
|
staff: typeof r.staff === "string" && r.staff.trim() ? r.staff.trim() : void 0,
|
|
@@ -7703,6 +7706,8 @@ async function runJob(job, base) {
|
|
|
7703
7706
|
const preloadedData = {};
|
|
7704
7707
|
preloadedData.jobId = newJobId(valid.flavor);
|
|
7705
7708
|
preloadedData.jobFlavor = valid.flavor;
|
|
7709
|
+
if (valid.duty !== void 0 && valid.duty.length > 0) preloadedData.jobDuty = valid.duty;
|
|
7710
|
+
if (valid.executable !== void 0 && valid.executable.length > 0) preloadedData.jobExecutable = valid.executable;
|
|
7706
7711
|
if (valid.schedule !== void 0 && valid.schedule.length > 0) preloadedData.jobSchedule = valid.schedule;
|
|
7707
7712
|
if (valid.why !== void 0 && valid.why.length > 0) preloadedData.jobWhy = valid.why;
|
|
7708
7713
|
if (valid.persona !== void 0) preloadedData.jobPersona = valid.persona;
|
|
@@ -13438,6 +13443,31 @@ function operatorRequestBlock(why) {
|
|
|
13438
13443
|
"----- END UNTRUSTED INPUT -----"
|
|
13439
13444
|
].join("\n");
|
|
13440
13445
|
}
|
|
13446
|
+
function jobReferenceBlock(profileName, profile, data) {
|
|
13447
|
+
const jobId = typeof data.jobId === "string" && data.jobId.length > 0 ? data.jobId : null;
|
|
13448
|
+
const flavor = typeof data.jobFlavor === "string" && data.jobFlavor.length > 0 ? data.jobFlavor : null;
|
|
13449
|
+
const schedule = typeof data.jobSchedule === "string" && data.jobSchedule.length > 0 ? data.jobSchedule : null;
|
|
13450
|
+
const isJob = Boolean(jobId || flavor || schedule || data.jobDuty || data.jobExecutable || data.jobWhy);
|
|
13451
|
+
if (!isJob) return null;
|
|
13452
|
+
const duty = typeof data.jobDuty === "string" && data.jobDuty.length > 0 ? data.jobDuty : profile.executable ? profile.name : null;
|
|
13453
|
+
const executable = typeof profile.executable === "string" && profile.executable.length > 0 ? profile.executable : typeof data.jobExecutable === "string" && data.jobExecutable.length > 0 ? data.jobExecutable : profileName;
|
|
13454
|
+
const staff = typeof profile.staff === "string" && profile.staff.length > 0 ? profile.staff : typeof data.jobPersona === "string" && data.jobPersona.length > 0 ? data.jobPersona : null;
|
|
13455
|
+
const description = profile.describe.trim();
|
|
13456
|
+
const lines = [
|
|
13457
|
+
"## Job reference",
|
|
13458
|
+
"",
|
|
13459
|
+
"This execution point is a job.",
|
|
13460
|
+
"",
|
|
13461
|
+
`- Job id: ${jobId ?? "(unavailable)"}`,
|
|
13462
|
+
`- Flavor: ${flavor ?? "(unavailable)"}`,
|
|
13463
|
+
...schedule ? [`- Schedule: ${schedule}`] : [],
|
|
13464
|
+
`- Duty: ${duty ?? "(none)"}`,
|
|
13465
|
+
`- Executable: ${executable}`,
|
|
13466
|
+
`- Staff: ${staff ?? "(none)"}`,
|
|
13467
|
+
`- Description: ${description || "(none)"}`
|
|
13468
|
+
];
|
|
13469
|
+
return lines.join("\n");
|
|
13470
|
+
}
|
|
13441
13471
|
async function runExecutable(profileName, input) {
|
|
13442
13472
|
const stageStartedAt = Date.now();
|
|
13443
13473
|
emitEvent(input.cwd, { executable: profileName, kind: "stage_start" });
|
|
@@ -13547,6 +13577,7 @@ async function runExecutable(profileName, input) {
|
|
|
13547
13577
|
const personaSlug = typeof profile.staff === "string" && profile.staff.length > 0 ? profile.staff : typeof ctx.data.jobPersona === "string" && ctx.data.jobPersona.length > 0 ? ctx.data.jobPersona : null;
|
|
13548
13578
|
const staffPersona = personaSlug ? framePersona(personaSlug, loadStaffPersona(input.cwd, personaSlug)) : null;
|
|
13549
13579
|
const jobWhyBlock = typeof ctx.data.jobWhy === "string" ? operatorRequestBlock(ctx.data.jobWhy) : null;
|
|
13580
|
+
const jobRefBlock = jobReferenceBlock(profileName, profile, ctx.data);
|
|
13550
13581
|
const invokeAgent = async (prompt) => {
|
|
13551
13582
|
const externalPlugins = (profile.claudeCode.plugins ?? []).map((p) => path36.isAbsolute(p) ? p : path36.resolve(profile.dir, p)).filter((p) => p.length > 0);
|
|
13552
13583
|
const syntheticPath = ctx.data.syntheticPluginPath;
|
|
@@ -13577,7 +13608,14 @@ async function runExecutable(profileName, input) {
|
|
|
13577
13608
|
maxTurnTimeoutMs: typeof profile.claudeCode.maxTurnTimeoutSec === "number" ? Math.floor(profile.claudeCode.maxTurnTimeoutSec * 1e3) : void 0,
|
|
13578
13609
|
// DISCIPLINE leads so the stable, role-agnostic block sits at the front
|
|
13579
13610
|
// of the cacheable system-prompt prefix; profile/task appends follow.
|
|
13580
|
-
systemPromptAppend: [
|
|
13611
|
+
systemPromptAppend: [
|
|
13612
|
+
DISCIPLINE,
|
|
13613
|
+
staffPersona,
|
|
13614
|
+
jobRefBlock,
|
|
13615
|
+
jobWhyBlock,
|
|
13616
|
+
profile.claudeCode.systemPromptAppend,
|
|
13617
|
+
taskArtifacts?.promptAddendum
|
|
13618
|
+
].filter((s) => typeof s === "string" && s.length > 0).join("\n\n") || void 0,
|
|
13581
13619
|
cacheable: profile.claudeCode.cacheable,
|
|
13582
13620
|
enableVerifyTool: profile.claudeCode.enableVerifyTool,
|
|
13583
13621
|
enableSubmitTool: profile.claudeCode.enableSubmitTool,
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fix",
|
|
3
|
+
"role": "primitive",
|
|
4
|
+
"describe": "Apply review feedback to an existing PR branch.",
|
|
5
|
+
"inputs": [
|
|
6
|
+
{
|
|
7
|
+
"name": "pr",
|
|
8
|
+
"flag": "--pr",
|
|
9
|
+
"type": "int",
|
|
10
|
+
"required": true,
|
|
11
|
+
"describe": "GitHub PR number to apply feedback to."
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "feedback",
|
|
15
|
+
"flag": "--feedback",
|
|
16
|
+
"type": "string",
|
|
17
|
+
"required": false,
|
|
18
|
+
"bindsCommentRest": true,
|
|
19
|
+
"describe": "Inline override. If absent, the flow reads the latest PR review comment."
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"claudeCode": {
|
|
23
|
+
"model": "inherit",
|
|
24
|
+
"permissionMode": "acceptEdits",
|
|
25
|
+
"maxTurns": null,
|
|
26
|
+
"maxTurnTimeoutSec": 1200,
|
|
27
|
+
"systemPromptAppend": null,
|
|
28
|
+
"cacheable": true,
|
|
29
|
+
"enableVerifyTool": true,
|
|
30
|
+
"verifyAttempts": 4,
|
|
31
|
+
"tools": [
|
|
32
|
+
"Read",
|
|
33
|
+
"Write",
|
|
34
|
+
"Edit",
|
|
35
|
+
"Bash",
|
|
36
|
+
"Grep",
|
|
37
|
+
"Glob",
|
|
38
|
+
"mcp__playwright",
|
|
39
|
+
"mcp__kody-verify"
|
|
40
|
+
],
|
|
41
|
+
"hooks": ["block-git"],
|
|
42
|
+
"skills": ["systematic-debugging"],
|
|
43
|
+
"commands": [],
|
|
44
|
+
"subagents": [],
|
|
45
|
+
"plugins": [],
|
|
46
|
+
"mcpServers": [
|
|
47
|
+
{
|
|
48
|
+
"name": "playwright",
|
|
49
|
+
"command": "npx",
|
|
50
|
+
"args": ["-y", "--package=@playwright/mcp@latest", "--", "playwright-mcp"]
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"cliTools": [
|
|
55
|
+
{
|
|
56
|
+
"name": "playwright",
|
|
57
|
+
"install": {
|
|
58
|
+
"required": false,
|
|
59
|
+
"checkCommand": "ls \"$HOME/.cache/ms-playwright\" 2>/dev/null | grep -q '^chromium'",
|
|
60
|
+
"installCommand": "npx --yes playwright install --with-deps chromium"
|
|
61
|
+
},
|
|
62
|
+
"verify": "ls \"$HOME/.cache/ms-playwright\" 2>/dev/null | grep -q '^chromium'",
|
|
63
|
+
"usage": ""
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"lifecycle": "pr-branch",
|
|
67
|
+
"lifecycleConfig": {
|
|
68
|
+
"label": {
|
|
69
|
+
"name": "kody:fixing",
|
|
70
|
+
"color": "e99695",
|
|
71
|
+
"description": "kody: applying review feedback"
|
|
72
|
+
},
|
|
73
|
+
"context": "task",
|
|
74
|
+
"finalize": true
|
|
75
|
+
},
|
|
76
|
+
"scripts": {
|
|
77
|
+
"preflight": [
|
|
78
|
+
{ "script": "fixFlow" }
|
|
79
|
+
],
|
|
80
|
+
"postflight": [
|
|
81
|
+
{ "script": "requireFeedbackActions" }
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
"output": {
|
|
85
|
+
"actionTypes": [
|
|
86
|
+
"FIX_COMPLETED",
|
|
87
|
+
"FIX_FAILED",
|
|
88
|
+
"AGENT_NOT_RUN"
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
You are Kody, an autonomous engineer. Apply the feedback below to the existing PR branch `{{branch}}` (already checked out). The wrapper handles git/gh — you do not.
|
|
2
|
+
|
|
3
|
+
# Repo
|
|
4
|
+
- {{repoOwner}}/{{repoName}}, default branch: {{defaultBranch}}
|
|
5
|
+
|
|
6
|
+
# PR #{{pr.number}}: {{pr.title}}
|
|
7
|
+
{{pr.body}}
|
|
8
|
+
|
|
9
|
+
# Feedback to address (AUTHORITATIVE — supersedes the original issue spec)
|
|
10
|
+
|
|
11
|
+
{{feedback}}
|
|
12
|
+
|
|
13
|
+
{{conventionsBlock}}{{coverageBlock}}{{toolsUsage}}# Existing PR diff (current state, truncated)
|
|
14
|
+
|
|
15
|
+
```diff
|
|
16
|
+
{{prDiff}}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
# Prior art (closed/merged PRs that previously attempted this work, if any)
|
|
20
|
+
{{priorArt}}
|
|
21
|
+
|
|
22
|
+
If a prior-art block is present above, scan it before editing — those are earlier attempts (possibly by you, possibly by a human) at the same fix. Note what was rejected and why; do not repeat a discarded approach.
|
|
23
|
+
|
|
24
|
+
{{memoryContext}}
|
|
25
|
+
|
|
26
|
+
# Required steps
|
|
27
|
+
1. **Extract** every actionable item from the feedback. A structured review uses headings like `### Concerns`, `### Suggestions`, and `### Bugs`; each bullet under those headings is a distinct item. `### Strengths`, `### Summary`, and `### Bottom line` are NOT items — skip them. If the feedback has no headings (plain inline feedback), treat the whole feedback as one item.
|
|
28
|
+
2. **Number each item** internally (Item 1, Item 2, …). You will account for every one of them in your final message below.
|
|
29
|
+
3. **Research** — read only what's needed to act on the items. Make the minimum edits required to implement each one. If the feedback or PR body links to external **non-GitHub** URLs (reproduction sites, bug recordings, spec pages), use the **Playwright MCP** tools (`mcp__playwright__browser_navigate`, `mcp__playwright__browser_snapshot`) to load them — do not rely on your interpretation of the URL alone. Do NOT open GitHub URLs (issues, PRs, repo files, gists) in Playwright — the browser session is anonymous and will 404 on private repos. Issue/PR context is already in this prompt; for anything else on GitHub, use the `gh` CLI via Bash.
|
|
30
|
+
|
|
31
|
+
**Research floor (MUST be met before any Edit/Write):**
|
|
32
|
+
- Read the **full** contents of every file you intend to change.
|
|
33
|
+
- Read the test file for each of those files, if one exists.
|
|
34
|
+
- Skipping the floor on the assumption "feedback says exactly what to change" is a hard failure when the change touches code with non-obvious invariants.
|
|
35
|
+
4. **Verify** — before declaring DONE, call the `verify` tool (mcp__kody-verify__verify). It runs the project's typecheck/lint/test gates and returns `{ ok, failures, attemptsRemaining }`. If `ok: true`, proceed to DONE. If `ok: false`, read the truncated `failures` list, fix what you introduced this round (not pre-existing breakages unrelated to the feedback), and call `verify` again. Bounded by 4 attempts; after that the tool returns `locked: true` and you must wrap up. The postflight verifier still runs after this session as the final ratifier.
|
|
36
|
+
5. Your FINAL message MUST use this exact format (or a single `FAILED: <reason>` line on failure). The `FEEDBACK_ACTIONS:` block is REQUIRED — omitting it or leaving it empty makes your DONE invalid.
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
DONE
|
|
40
|
+
FEEDBACK_ACTIONS:
|
|
41
|
+
- Item 1: "<short restatement of the item>" — <fixed: <what you edited> | declined: <specific reason>>
|
|
42
|
+
- Item 2: "<short restatement>" — <fixed: ... | declined: ...>
|
|
43
|
+
- (one line per extracted item; do NOT omit any)
|
|
44
|
+
COMMIT_MSG: <conventional-commit message for this round of fixes>
|
|
45
|
+
PR_SUMMARY:
|
|
46
|
+
<2-4 bullets describing what changed in THIS fix round — not the whole PR>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Worked example.** Suppose the feedback was:
|
|
50
|
+
|
|
51
|
+
> ### Concerns
|
|
52
|
+
> - The retry loop in `src/queue.ts:42` has no upper bound — could spin forever if the API is down.
|
|
53
|
+
> - `validateInput` accepts negative numbers but the schema says positive.
|
|
54
|
+
>
|
|
55
|
+
> ### Suggestions
|
|
56
|
+
> - Consider extracting the date-parsing logic into a helper.
|
|
57
|
+
|
|
58
|
+
A valid `FEEDBACK_ACTIONS` block:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
FEEDBACK_ACTIONS:
|
|
62
|
+
- Item 1: "retry loop has no upper bound" — fixed: src/queue.ts:42 added maxRetries=5 with exponential backoff and a final throw.
|
|
63
|
+
- Item 2: "validateInput accepts negative numbers but schema says positive" — fixed: src/validate.ts:18 changed z.number() to z.number().positive(); added test cases for -1 and 0.
|
|
64
|
+
- Item 3: "extract date-parsing helper" — declined: the parsing only appears in one call site (src/handlers/webhook.ts:71); extracting now would create a one-caller helper. Will revisit if a second call site appears.
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Notes on the example:
|
|
68
|
+
- Every extracted item appears as exactly one line. None are dropped, none merged.
|
|
69
|
+
- "Strengths" / "Summary" / "Bottom line" sections from the feedback do NOT become items.
|
|
70
|
+
- `declined:` is paired with concrete evidence (one call site + path), not a vague preference.
|
|
71
|
+
|
|
72
|
+
# Rules
|
|
73
|
+
- **The feedback is the scope.** You are here to address the extracted items — nothing else. Do NOT make unrelated refactors, rename variables the reviewer did not flag, or "tighten" types that were not called out. Every edit in your diff must trace back to a specific Item in `FEEDBACK_ACTIONS`.
|
|
74
|
+
- **Default to `fixed`.** `declined` is only acceptable when (a) the item is factually wrong about the code, or (b) it is explicitly out of scope per the issue body. In both cases the `declined: <reason>` line must point to concrete evidence (a file:line that contradicts the item, or a specific issue-body clause).
|
|
75
|
+
- **Treat each item as a concrete change request, not a code review to argue with.** "Add an X branch" means add an X branch — not document that Y already covers the case. "Already handles it in a different way" is NOT an acceptable reason to decline.
|
|
76
|
+
- **Your DONE is only valid if your diff materially implements each `fixed` item.** A diff that only adds tests asserting the current behavior, or only tweaks comments/docs, does NOT count as addressing a change request. If an item asks for a new code path, the diff MUST contain that new code path.
|
|
77
|
+
- **"Already satisfied" (i.e. skipping the edit because the code already does what's asked) is only allowed when you can cite the exact file:line that already implements it.** If in doubt, make the edit — under `fixed`.
|
|
78
|
+
- **Stale feedback.** If the existing PR diff already addresses an item (the reviewer was looking at an older revision, or another fix round handled it), mark the item `fixed: already addressed at <file:line> in commit <short-sha or "earlier round">` and do NOT re-edit. Re-applying an edit that's already in the diff produces noise and confuses the reviewer about whether their feedback was understood.
|
|
79
|
+
- **Not all feedback is an item.** These are NOT items, even if they appear in the feedback body:
|
|
80
|
+
- Questions ("why did you choose X?") — answer in the PR comment thread, not via an edit.
|
|
81
|
+
- Hedges and asides ("interesting", "let me know", "thoughts?") — no action required.
|
|
82
|
+
- Documentation links and references that aren't tied to a concrete change ask.
|
|
83
|
+
- Praise / strengths bullets, even if they suggest improvements implicitly.
|
|
84
|
+
|
|
85
|
+
When in doubt: an item is something with an imperative or a concrete change that would alter the diff. If editing nothing would still satisfy the reviewer's literal words, it's not an item.
|
|
86
|
+
- Do NOT run git/gh commands. The wrapper handles it.
|
|
87
|
+
- Stay on `{{branch}}`.
|
|
88
|
+
- Do not modify files under `.kody/`, `.kody-engine/`, `.kody/`, `node_modules/`, `dist/`, `build/`, `.env`, `*.log`.
|
|
89
|
+
- If the feedback is ambiguous or conflicts with the issue, err toward what the feedback says.
|
|
90
|
+
{{systemPromptAppend}}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "job-live-verify",
|
|
3
|
+
"role": "primitive",
|
|
4
|
+
"describe": "Live-test executable that verifies job reference injection, staff persona injection, synthetic skill loading, locked duty tools, and state postflight.",
|
|
5
|
+
"kind": "oneshot",
|
|
6
|
+
"dutyTools": ["ensure_issue", "ensure_comment"],
|
|
7
|
+
"inputs": [],
|
|
8
|
+
"claudeCode": {
|
|
9
|
+
"model": "inherit",
|
|
10
|
+
"permissionMode": "default",
|
|
11
|
+
"maxTurns": 20,
|
|
12
|
+
"maxThinkingTokens": null,
|
|
13
|
+
"maxTurnTimeoutSec": 180,
|
|
14
|
+
"systemPromptAppend": "You are running Kody's job-wiring live verification. Use the requested tools, then submit state exactly once.",
|
|
15
|
+
"enableSubmitTool": true,
|
|
16
|
+
"tools": ["Read"],
|
|
17
|
+
"hooks": [],
|
|
18
|
+
"skills": ["kody-live-marker"],
|
|
19
|
+
"commands": [],
|
|
20
|
+
"subagents": [],
|
|
21
|
+
"plugins": [],
|
|
22
|
+
"mcpServers": []
|
|
23
|
+
},
|
|
24
|
+
"cliTools": [],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"preflight": [
|
|
27
|
+
{ "script": "loadDutyState" },
|
|
28
|
+
{ "script": "buildSyntheticPlugin" },
|
|
29
|
+
{ "script": "composePrompt" }
|
|
30
|
+
],
|
|
31
|
+
"postflight": [
|
|
32
|
+
{ "script": "parseJobStateFromAgentResult", "with": { "fenceLabel": "kody-job-next-state" } },
|
|
33
|
+
{ "script": "writeJobStateFile" }
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
You are Kody's live job-wiring verification agent.
|
|
2
|
+
|
|
3
|
+
Your only job is to prove that this model session received the job reference, the staff persona, the duty, the executable, the loaded skill, and the locked duty tools.
|
|
4
|
+
|
|
5
|
+
## Evidence to collect
|
|
6
|
+
|
|
7
|
+
1. Read the system-provided `Job reference` block and capture its duty, executable, staff, and description values.
|
|
8
|
+
2. Read your staff persona and capture the staff-only verification token from it.
|
|
9
|
+
3. Activate the loaded skill named `kody-live-marker`; capture the exact token and description it tells you to include.
|
|
10
|
+
4. Use `ensure_issue` with:
|
|
11
|
+
- `key`: `live-job-wiring-proof-2026-06-06`
|
|
12
|
+
- `title`: `Kody live job wiring proof`
|
|
13
|
+
- `body`: a short markdown note that includes the duty, executable, staff, description, staff-only token, and skill token you observed.
|
|
14
|
+
5. Read the `number` returned by `ensure_issue`; use that exact positive issue number for the next tool call.
|
|
15
|
+
6. Use `ensure_comment` on that issue with:
|
|
16
|
+
- `key`: `live-job-wiring-proof-comment-2026-06-06`
|
|
17
|
+
- `body`: one markdown line beginning `live job wiring proof:` and including the same observed values.
|
|
18
|
+
7. Call `submit_state` exactly once, as your final action.
|
|
19
|
+
|
|
20
|
+
## State to submit
|
|
21
|
+
|
|
22
|
+
Submit:
|
|
23
|
+
|
|
24
|
+
- `cursor`: `verified`
|
|
25
|
+
- `done`: `true`
|
|
26
|
+
- `data`: an object containing:
|
|
27
|
+
- `duty`
|
|
28
|
+
- `executable`
|
|
29
|
+
- `staff`
|
|
30
|
+
- `description`
|
|
31
|
+
- `staffToken`
|
|
32
|
+
- `skillToken`
|
|
33
|
+
- `skillDescription`
|
|
34
|
+
- `issueNumber`
|
|
35
|
+
- `commentStatus`: `posted` when `ensure_comment` returns `posted: true`, or `already-existed` when it returns `posted: false`
|
|
36
|
+
- `toolsUsed`, exactly `["ensure_issue", "ensure_comment", "submit_state"]`
|
|
37
|
+
|
|
38
|
+
## Rules
|
|
39
|
+
|
|
40
|
+
- Do not use shell, git, or file editing.
|
|
41
|
+
- If a value is missing, write `MISSING` for that value and still submit state.
|
|
42
|
+
- The proof is the tool calls plus submitted state; no prose summary is needed after `submit_state`.
|
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.210",
|
|
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",
|