@kody-ade/kody-engine 0.4.14 → 0.4.16
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.4.
|
|
6
|
+
version: "0.4.16",
|
|
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",
|
|
@@ -108,6 +108,72 @@ ensure_label() {
|
|
|
108
108
|
gh label create "$1" --color "$2" --description "$3" --force >/dev/null 2>&1 || true
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
read_state_field() {
|
|
112
|
+
# read_state_field <key> — prints the value or empty string. Never fails.
|
|
113
|
+
python3 - "$state_file" "$1" <<'PY' 2>/dev/null || echo ""
|
|
114
|
+
import json, sys
|
|
115
|
+
path, key = sys.argv[1], sys.argv[2]
|
|
116
|
+
try:
|
|
117
|
+
with open(path) as f:
|
|
118
|
+
s = json.load(f)
|
|
119
|
+
v = s.get(key, "")
|
|
120
|
+
print("" if v is None else v)
|
|
121
|
+
except Exception:
|
|
122
|
+
print("")
|
|
123
|
+
PY
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
ensure_goal_issue() {
|
|
127
|
+
# Create the umbrella goal issue (once), label it goal:<id> + kody:building,
|
|
128
|
+
# and persist its number on state.json. Idempotent: if state already has
|
|
129
|
+
# goalIssueNumber, this is a no-op. The issue auto-closes when the final
|
|
130
|
+
# goal PR merges, via the `Closes #N` line we add to that PR body.
|
|
131
|
+
local existing
|
|
132
|
+
existing=$(read_state_field "goalIssueNumber")
|
|
133
|
+
if [ -n "$existing" ] && [ "$existing" != "0" ]; then
|
|
134
|
+
return 0
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
ensure_label "$label" "0e8a16" "kody goal task: belongs to goal ${goal_id}"
|
|
138
|
+
ensure_label "kody:building" "1d76db" "kody: in-flight (work being assembled on a branch)"
|
|
139
|
+
|
|
140
|
+
local title body num
|
|
141
|
+
title="goal: ${goal_id}"
|
|
142
|
+
body=$(printf "Umbrella issue for goal **%s**.\n\nClosed automatically when the goal PR (\`%s\` → \`%s\`) merges.\n" \
|
|
143
|
+
"$goal_id" "$goal_branch" "$default_branch")
|
|
144
|
+
|
|
145
|
+
# `gh issue create` prints the new issue's URL on stdout
|
|
146
|
+
# (https://github.com/<owner>/<repo>/issues/<n>). It does NOT support
|
|
147
|
+
# --json/--jq, so parse the trailing number off the URL.
|
|
148
|
+
local url
|
|
149
|
+
url=$(gh issue create \
|
|
150
|
+
--title "$title" \
|
|
151
|
+
--body "$body" \
|
|
152
|
+
--label "$label" \
|
|
153
|
+
--label "kody:building" 2>/dev/null || echo "")
|
|
154
|
+
|
|
155
|
+
num="${url##*/}"
|
|
156
|
+
if [ -z "$num" ] || ! [[ "$num" =~ ^[0-9]+$ ]]; then
|
|
157
|
+
echo "[goal-tick] ensure_goal_issue: gh issue create failed (got '${url}') — continuing without umbrella issue"
|
|
158
|
+
return 0
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
python3 - "$state_file" "$num" <<'PY'
|
|
162
|
+
import json, sys
|
|
163
|
+
from datetime import datetime, timezone
|
|
164
|
+
path = sys.argv[1]
|
|
165
|
+
n = int(sys.argv[2])
|
|
166
|
+
with open(path) as f:
|
|
167
|
+
s = json.load(f)
|
|
168
|
+
s["goalIssueNumber"] = n
|
|
169
|
+
s["updatedAt"] = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
|
|
170
|
+
with open(path, "w") as f:
|
|
171
|
+
json.dump(s, f, indent=2)
|
|
172
|
+
f.write("\n")
|
|
173
|
+
PY
|
|
174
|
+
echo "[goal-tick] opened umbrella issue #${num} for ${goal_id}"
|
|
175
|
+
}
|
|
176
|
+
|
|
111
177
|
list_goal_issues() {
|
|
112
178
|
# Up to 100 goal-labelled issues. PRs filtered out.
|
|
113
179
|
gh api \
|
|
@@ -181,7 +247,16 @@ if [ "$open_count" = "0" ]; then
|
|
|
181
247
|
existing_pr=$(gh pr list --head "$goal_branch" --state open --json number,url --jq '.[0]' 2>/dev/null || echo "")
|
|
182
248
|
if [ -z "$existing_pr" ] || [ "$existing_pr" = "null" ]; then
|
|
183
249
|
title="goal: ${goal_id}"
|
|
184
|
-
|
|
250
|
+
goal_issue_number=$(read_state_field "goalIssueNumber")
|
|
251
|
+
# `Closes #N` auto-closes the umbrella goal issue on PR merge — that's
|
|
252
|
+
# how the dashboard learns the goal is done. Skip the line gracefully
|
|
253
|
+
# if no umbrella issue was ever opened (older goals from before this
|
|
254
|
+
# change, or `gh issue create` failed silently during a tick).
|
|
255
|
+
if [ -n "$goal_issue_number" ] && [ "$goal_issue_number" != "0" ]; then
|
|
256
|
+
body=$(printf "Final integration PR for goal **%s**.\n\nAll task issues are closed and merged into \`%s\`. Ready for review.\n\nCloses #%s\n" "$goal_id" "$goal_branch" "$goal_issue_number")
|
|
257
|
+
else
|
|
258
|
+
body=$(printf "Final integration PR for goal **%s**.\n\nAll task issues are closed and merged into \`%s\`. Ready for review.\n" "$goal_id" "$goal_branch")
|
|
259
|
+
fi
|
|
185
260
|
goal_pr_url=$(gh pr create \
|
|
186
261
|
--head "$goal_branch" \
|
|
187
262
|
--base "$default_branch" \
|
|
@@ -286,6 +361,12 @@ else
|
|
|
286
361
|
fi
|
|
287
362
|
fi
|
|
288
363
|
|
|
364
|
+
# The goal branch now exists (or the fallback path will be used). Open the
|
|
365
|
+
# umbrella goal issue if we haven't yet, so the dashboard can render the goal
|
|
366
|
+
# as an issue row with a "kody:building" status and the goal branch as its
|
|
367
|
+
# preview. Idempotent — only the first call actually creates anything.
|
|
368
|
+
ensure_goal_issue
|
|
369
|
+
|
|
289
370
|
echo "[goal-tick] dispatching @kody on task #$next_issue (--base $goal_branch)"
|
|
290
371
|
gh issue comment "$next_issue" --body "@kody --base ${goal_branch}"
|
|
291
372
|
gh issue edit "$next_issue" --add-label "$dispatched_label"
|
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.16",
|
|
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",
|