@kody-ade/kody-engine 0.4.15 → 0.4.17
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 +1 -1
- package/dist/executables/goal-tick/tick.sh +38 -13
- package/package.json +1 -1
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.17",
|
|
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",
|
|
@@ -142,15 +142,19 @@ ensure_goal_issue() {
|
|
|
142
142
|
body=$(printf "Umbrella issue for goal **%s**.\n\nClosed automatically when the goal PR (\`%s\` → \`%s\`) merges.\n" \
|
|
143
143
|
"$goal_id" "$goal_branch" "$default_branch")
|
|
144
144
|
|
|
145
|
-
|
|
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 \
|
|
146
150
|
--title "$title" \
|
|
147
151
|
--body "$body" \
|
|
148
152
|
--label "$label" \
|
|
149
|
-
--label "kody:building"
|
|
150
|
-
--json number --jq '.number' 2>/dev/null || echo "")
|
|
153
|
+
--label "kody:building" 2>/dev/null || echo "")
|
|
151
154
|
|
|
152
|
-
|
|
153
|
-
|
|
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"
|
|
154
158
|
return 0
|
|
155
159
|
fi
|
|
156
160
|
|
|
@@ -171,10 +175,29 @@ PY
|
|
|
171
175
|
}
|
|
172
176
|
|
|
173
177
|
list_goal_issues() {
|
|
174
|
-
# Up to 100 goal-labelled issues. PRs filtered out.
|
|
178
|
+
# Up to 100 goal-labelled issues. PRs filtered out. Also filters out the
|
|
179
|
+
# umbrella goal issue (if any) — it shares the `goal:<id>` label so the
|
|
180
|
+
# dashboard groups it under the goal, but it must NOT count as a child
|
|
181
|
+
# task: while the umbrella is open the "all child tasks closed" finalize
|
|
182
|
+
# check would never fire (the umbrella only closes on goal-PR merge,
|
|
183
|
+
# which only happens during finalize — deadlock).
|
|
184
|
+
local exclude
|
|
185
|
+
exclude=$(read_state_field "goalIssueNumber")
|
|
175
186
|
gh api \
|
|
176
187
|
"repos/{owner}/{repo}/issues?labels=${label}&state=all&per_page=100" \
|
|
177
|
-
--jq '[.[] | select(.pull_request == null) | {number, state: (.state | ascii_upcase), labels: [.labels[].name]}]'
|
|
188
|
+
--jq '[.[] | select(.pull_request == null) | {number, state: (.state | ascii_upcase), labels: [.labels[].name]}]' \
|
|
189
|
+
| EXCLUDE="$exclude" python3 -c "
|
|
190
|
+
import json, os, sys
|
|
191
|
+
data = json.load(sys.stdin)
|
|
192
|
+
ex = os.environ.get('EXCLUDE', '')
|
|
193
|
+
if ex:
|
|
194
|
+
try:
|
|
195
|
+
ex_num = int(ex)
|
|
196
|
+
data = [i for i in data if i['number'] != ex_num]
|
|
197
|
+
except ValueError:
|
|
198
|
+
pass
|
|
199
|
+
print(json.dumps(data))
|
|
200
|
+
"
|
|
178
201
|
}
|
|
179
202
|
|
|
180
203
|
# ── Cleanup path: state == abandoned ──────────────────────────────────────────
|
|
@@ -220,6 +243,14 @@ fi
|
|
|
220
243
|
ensure_label "$dispatched_label" "ededed" "kody goal-runner: already dispatched this tick"
|
|
221
244
|
ensure_label "$failed_label" "b60205" "kody goal-runner: task failed; needs human attention"
|
|
222
245
|
|
|
246
|
+
# Open the umbrella goal issue on the first active tick (idempotent — no-op if
|
|
247
|
+
# state.json already has goalIssueNumber). The dashboard renders this issue as
|
|
248
|
+
# the goal's "row" with kody:building status; it auto-closes when the final
|
|
249
|
+
# goal PR merges via the `Closes #N` we add to that PR's body. Doing this here
|
|
250
|
+
# (before list_goal_issues) ensures the umbrella exists before we start
|
|
251
|
+
# counting child tasks, so list_goal_issues can filter it out cleanly.
|
|
252
|
+
ensure_goal_issue
|
|
253
|
+
|
|
223
254
|
issues_json=$(list_goal_issues)
|
|
224
255
|
total=$(echo "$issues_json" | python3 -c "import json,sys; print(len(json.load(sys.stdin)))")
|
|
225
256
|
if [ "$total" = "0" ]; then
|
|
@@ -357,12 +388,6 @@ else
|
|
|
357
388
|
fi
|
|
358
389
|
fi
|
|
359
390
|
|
|
360
|
-
# The goal branch now exists (or the fallback path will be used). Open the
|
|
361
|
-
# umbrella goal issue if we haven't yet, so the dashboard can render the goal
|
|
362
|
-
# as an issue row with a "kody:building" status and the goal branch as its
|
|
363
|
-
# preview. Idempotent — only the first call actually creates anything.
|
|
364
|
-
ensure_goal_issue
|
|
365
|
-
|
|
366
391
|
echo "[goal-tick] dispatching @kody on task #$next_issue (--base $goal_branch)"
|
|
367
392
|
gh issue comment "$next_issue" --body "@kody --base ${goal_branch}"
|
|
368
393
|
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.17",
|
|
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",
|