@kody-ade/kody-engine 0.3.26 → 0.3.28
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.28",
|
|
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",
|
|
@@ -167,6 +167,7 @@ function loadConfig(projectDir = process.cwd()) {
|
|
|
167
167
|
quality: {
|
|
168
168
|
typecheck: typeof quality.typecheck === "string" ? quality.typecheck : "",
|
|
169
169
|
lint: typeof quality.lint === "string" ? quality.lint : "",
|
|
170
|
+
format: typeof quality.format === "string" ? quality.format : "",
|
|
170
171
|
testUnit: typeof quality.testUnit === "string" ? quality.testUnit : ""
|
|
171
172
|
},
|
|
172
173
|
git: {
|
|
@@ -223,11 +224,9 @@ function parseReleaseConfig(raw) {
|
|
|
223
224
|
if (Array.isArray(r.versionFiles)) out.versionFiles = r.versionFiles.filter((f) => typeof f === "string");
|
|
224
225
|
if (typeof r.publishCommand === "string") out.publishCommand = r.publishCommand;
|
|
225
226
|
if (typeof r.notifyCommand === "string") out.notifyCommand = r.notifyCommand;
|
|
226
|
-
if (typeof r.deployCommand === "string") out.deployCommand = r.deployCommand;
|
|
227
227
|
if (typeof r.e2eCommand === "string") out.e2eCommand = r.e2eCommand;
|
|
228
228
|
if (typeof r.draftRelease === "boolean") out.draftRelease = r.draftRelease;
|
|
229
229
|
if (typeof r.releaseBranch === "string") out.releaseBranch = r.releaseBranch;
|
|
230
|
-
if (typeof r.devBranch === "string" && r.devBranch.length > 0) out.devBranch = r.devBranch;
|
|
231
230
|
if (typeof r.timeoutMs === "number" && r.timeoutMs > 0) out.timeoutMs = Math.floor(r.timeoutMs);
|
|
232
231
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
233
232
|
}
|
|
@@ -5079,6 +5078,7 @@ async function verifyAll(config, cwd) {
|
|
|
5079
5078
|
if (config.quality.typecheck) commands.push({ name: "typecheck", cmd: config.quality.typecheck });
|
|
5080
5079
|
if (config.quality.testUnit) commands.push({ name: "test", cmd: config.quality.testUnit });
|
|
5081
5080
|
if (config.quality.lint) commands.push({ name: "lint", cmd: config.quality.lint });
|
|
5081
|
+
if (config.quality.format) commands.push({ name: "format", cmd: config.quality.format });
|
|
5082
5082
|
const failed = [];
|
|
5083
5083
|
const details = {};
|
|
5084
5084
|
for (const { name, cmd } of commands) {
|
|
@@ -5114,6 +5114,17 @@ var verify = async (ctx) => {
|
|
|
5114
5114
|
ctx.data.verifyOk = false;
|
|
5115
5115
|
ctx.data.verifyReason = `verify crashed: ${err instanceof Error ? err.message : String(err)}`;
|
|
5116
5116
|
}
|
|
5117
|
+
if (ctx.data.verifyOk === false) {
|
|
5118
|
+
const action = ctx.data.action;
|
|
5119
|
+
if (action && action.type.endsWith("_COMPLETED")) {
|
|
5120
|
+
const reason = ctx.data.verifyReason || "verify failed";
|
|
5121
|
+
ctx.data.action = {
|
|
5122
|
+
type: action.type.replace(/_COMPLETED$/, "_FAILED"),
|
|
5123
|
+
payload: { reason, downgradedFrom: action.type },
|
|
5124
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
5125
|
+
};
|
|
5126
|
+
}
|
|
5127
|
+
}
|
|
5117
5128
|
};
|
|
5118
5129
|
|
|
5119
5130
|
// src/scripts/watchStalePrsFlow.ts
|
|
@@ -5379,7 +5390,7 @@ async function runExecutable(profileName, input) {
|
|
|
5379
5390
|
config = input.config;
|
|
5380
5391
|
} else if (input.skipConfig) {
|
|
5381
5392
|
config = {
|
|
5382
|
-
quality: { typecheck: "", lint: "", testUnit: "" },
|
|
5393
|
+
quality: { typecheck: "", lint: "", testUnit: "", format: "" },
|
|
5383
5394
|
git: { defaultBranch: "main" },
|
|
5384
5395
|
github: { owner: "", repo: "" },
|
|
5385
5396
|
agent: { model: "claude/claude-haiku-4-5-20251001" }
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
#
|
|
3
|
-
# release-deploy: open a PR from the integration branch (
|
|
4
|
-
#
|
|
5
|
-
# orchestrator's chain ENDS with this PR opened;
|
|
6
|
-
# step. No agent.
|
|
3
|
+
# release-deploy: open a PR from the integration branch (git.defaultBranch)
|
|
4
|
+
# into the production target (release.releaseBranch) — the human gate for
|
|
5
|
+
# production deploy. The orchestrator's chain ENDS with this PR opened;
|
|
6
|
+
# merging it is a manual step. No agent.
|
|
7
7
|
#
|
|
8
8
|
# Behavior:
|
|
9
|
-
# - If release.
|
|
9
|
+
# - If release.releaseBranch is unset OR equals git.defaultBranch:
|
|
10
10
|
# no-op success (single-branch repos have nothing to deploy).
|
|
11
|
-
# - Else: idempotently open PR `
|
|
12
|
-
# open PR
|
|
11
|
+
# - Else: idempotently open PR `defaultBranch` → `releaseBranch`. If an
|
|
12
|
+
# open PR for that pair already exists, reuse its URL.
|
|
13
13
|
#
|
|
14
14
|
# After the PR is opened, runs `release.notifyCommand` (if set) as a
|
|
15
15
|
# best-effort post-deploy hook.
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
# KODY_ARG_ISSUE triggering issue/PR number (optional)
|
|
20
20
|
#
|
|
21
21
|
# Config (env):
|
|
22
|
-
# KODY_CFG_GIT_DEFAULTBRANCH e.g.
|
|
23
|
-
#
|
|
22
|
+
# KODY_CFG_GIT_DEFAULTBRANCH e.g. dev
|
|
23
|
+
# KODY_CFG_RELEASE_RELEASEBRANCH e.g. main (unset → no-op)
|
|
24
24
|
# KODY_CFG_RELEASE_NOTIFYCOMMAND optional; $VERSION substituted
|
|
25
25
|
# KODY_CFG_RELEASE_TIMEOUTMS per-command timeout in ms (default 600000)
|
|
26
26
|
#
|
|
@@ -33,27 +33,36 @@ set -euo pipefail
|
|
|
33
33
|
|
|
34
34
|
dry_run="${KODY_ARG_DRY_RUN:-false}"
|
|
35
35
|
default_branch="${KODY_CFG_GIT_DEFAULTBRANCH:-main}"
|
|
36
|
-
|
|
36
|
+
release_branch="${KODY_CFG_RELEASE_RELEASEBRANCH:-}"
|
|
37
37
|
notify_cmd="${KODY_CFG_RELEASE_NOTIFYCOMMAND:-}"
|
|
38
38
|
timeout_ms="${KODY_CFG_RELEASE_TIMEOUTMS:-600000}"
|
|
39
39
|
timeout_s=$((timeout_ms / 1000))
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
# Read version from the integration branch tip (where the bump commit lives),
|
|
42
|
+
# not from the local working tree (the workflow may have checked out another
|
|
43
|
+
# branch). Falls back to local package.json if the fetch fails.
|
|
44
|
+
read_version() {
|
|
45
|
+
local branch="$1"
|
|
46
|
+
if git fetch origin "$branch" --quiet 2>/dev/null; then
|
|
47
|
+
if pkg=$(git show "origin/${branch}:package.json" 2>/dev/null); then
|
|
48
|
+
echo "$pkg" | python3 -c "import json,sys; print(json.load(sys.stdin)['version'])" 2>/dev/null && return
|
|
49
|
+
fi
|
|
50
|
+
fi
|
|
42
51
|
python3 -c "import json; print(json.load(open('package.json'))['version'])" 2>/dev/null || echo "unknown"
|
|
43
52
|
}
|
|
44
53
|
|
|
45
|
-
version=$(
|
|
54
|
+
version=$(read_version "$default_branch")
|
|
46
55
|
echo "→ release deploy: v${version}"
|
|
47
56
|
|
|
48
57
|
# Single-branch repos: nothing to deploy.
|
|
49
|
-
if [[ -z "$
|
|
50
|
-
echo "KODY_REASON=no
|
|
58
|
+
if [[ -z "$release_branch" || "$release_branch" == "$default_branch" ]]; then
|
|
59
|
+
echo "KODY_REASON=no releaseBranch configured (or equals defaultBranch) — nothing to deploy"
|
|
51
60
|
echo "KODY_SKIP_AGENT=true"
|
|
52
61
|
exit 0
|
|
53
62
|
fi
|
|
54
63
|
|
|
55
64
|
if [[ "$dry_run" == "true" ]]; then
|
|
56
|
-
echo "KODY_REASON=dry-run — would open PR ${
|
|
65
|
+
echo "KODY_REASON=dry-run — would open PR ${default_branch} → ${release_branch}"
|
|
57
66
|
echo "KODY_SKIP_AGENT=true"
|
|
58
67
|
exit 0
|
|
59
68
|
fi
|
|
@@ -61,7 +70,7 @@ fi
|
|
|
61
70
|
export HUSKY=0 SKIP_HOOKS=1 CI="${CI:-1}"
|
|
62
71
|
|
|
63
72
|
# Idempotency: reuse an open PR for this branch pair if one exists.
|
|
64
|
-
existing=$(gh pr list --head "$
|
|
73
|
+
existing=$(gh pr list --head "$default_branch" --base "$release_branch" --state open --json url --limit 1 2>/dev/null \
|
|
65
74
|
| python3 -c 'import json,sys; data=json.load(sys.stdin); print(data[0]["url"] if data else "")' 2>/dev/null \
|
|
66
75
|
|| echo "")
|
|
67
76
|
|
|
@@ -69,10 +78,10 @@ if [[ -n "$existing" ]]; then
|
|
|
69
78
|
echo " reusing existing deploy PR: ${existing}"
|
|
70
79
|
pr_url="$existing"
|
|
71
80
|
else
|
|
72
|
-
body="Automated deploy PR opened by kody — promotes \`${
|
|
81
|
+
body="Automated deploy PR opened by kody — promotes \`${default_branch}\` to \`${release_branch}\` for release **v${version}**.
|
|
73
82
|
|
|
74
|
-
Merge this PR to deploy v${version} to \`${
|
|
75
|
-
if ! pr_url=$(printf '%s' "$body" | gh pr create --head "$
|
|
83
|
+
Merge this PR to deploy v${version} to \`${release_branch}\`."
|
|
84
|
+
if ! pr_url=$(printf '%s' "$body" | gh pr create --head "$default_branch" --base "$release_branch" --title "deploy: ${default_branch} → ${release_branch} (v${version})" --body-file -); then
|
|
76
85
|
echo "KODY_REASON=release deploy: gh pr create failed"
|
|
77
86
|
echo "KODY_SKIP_AGENT=true"
|
|
78
87
|
exit 1
|
|
@@ -101,5 +110,5 @@ if [[ -n "$notify_cmd" ]]; then
|
|
|
101
110
|
fi
|
|
102
111
|
fi
|
|
103
112
|
|
|
104
|
-
echo "KODY_REASON=opened deploy PR ${
|
|
113
|
+
echo "KODY_REASON=opened deploy PR ${default_branch} → ${release_branch} (notify=${notify_status})"
|
|
105
114
|
echo "KODY_SKIP_AGENT=true"
|
|
@@ -26,10 +26,6 @@ bump="${KODY_ARG_BUMP:-patch}"
|
|
|
26
26
|
dry_run="${KODY_ARG_DRY_RUN:-false}"
|
|
27
27
|
prefer="${KODY_ARG_PREFER:-}"
|
|
28
28
|
default_branch="${KODY_CFG_GIT_DEFAULTBRANCH:-main}"
|
|
29
|
-
dev_branch="${KODY_CFG_RELEASE_DEVBRANCH:-}"
|
|
30
|
-
# PR target: dev branch when configured (and different from default), else default.
|
|
31
|
-
pr_base="${dev_branch:-$default_branch}"
|
|
32
|
-
[[ "$pr_base" == "$default_branch" ]] && pr_base="$default_branch"
|
|
33
29
|
version_files_json="${KODY_CFG_RELEASE_VERSIONFILES:-}"
|
|
34
30
|
|
|
35
31
|
fail() {
|
|
@@ -317,8 +313,8 @@ _… truncated; see CHANGELOG.md_"
|
|
|
317
313
|
else
|
|
318
314
|
body_entry="$entry"
|
|
319
315
|
fi
|
|
320
|
-
body=$'Automated release PR opened by kody.\n\n'"$body_entry"$'\n\nThe release orchestrator will merge this into `'"${
|
|
321
|
-
pr_url=$(printf '%s' "$body" | gh pr create --head "$release_branch" --base "$
|
|
316
|
+
body=$'Automated release PR opened by kody.\n\n'"$body_entry"$'\n\nThe release orchestrator will merge this into `'"${default_branch}"$'` and continue to publish + deploy.'
|
|
317
|
+
pr_url=$(printf '%s' "$body" | gh pr create --head "$release_branch" --base "$default_branch" --title "chore: release ${tag}" --body-file -)
|
|
322
318
|
fi
|
|
323
319
|
|
|
324
320
|
if [[ -z "$pr_url" ]]; then
|
|
@@ -24,13 +24,6 @@ set -euo pipefail
|
|
|
24
24
|
|
|
25
25
|
dry_run="${KODY_ARG_DRY_RUN:-false}"
|
|
26
26
|
default_branch="${KODY_CFG_GIT_DEFAULTBRANCH:-main}"
|
|
27
|
-
dev_branch="${KODY_CFG_RELEASE_DEVBRANCH:-}"
|
|
28
|
-
# Tag the branch where the release-prepare PR was merged: devBranch when set
|
|
29
|
-
# (and different from default), else defaultBranch.
|
|
30
|
-
target_branch="$default_branch"
|
|
31
|
-
if [[ -n "$dev_branch" && "$dev_branch" != "$default_branch" ]]; then
|
|
32
|
-
target_branch="$dev_branch"
|
|
33
|
-
fi
|
|
34
27
|
publish_cmd="${KODY_CFG_RELEASE_PUBLISHCOMMAND:-}"
|
|
35
28
|
draft="${KODY_CFG_RELEASE_DRAFTRELEASE:-false}"
|
|
36
29
|
timeout_ms="${KODY_CFG_RELEASE_TIMEOUTMS:-600000}"
|
|
@@ -53,10 +46,10 @@ fi
|
|
|
53
46
|
export HUSKY=0 SKIP_HOOKS=1 CI="${CI:-1}"
|
|
54
47
|
|
|
55
48
|
# Make sure we're on the merged commit. The orchestrator merged the release
|
|
56
|
-
# PR into
|
|
57
|
-
git fetch origin "$
|
|
58
|
-
git checkout "$
|
|
59
|
-
git reset --hard "origin/$
|
|
49
|
+
# PR into default_branch; pull so the local tree has the bump commit.
|
|
50
|
+
git fetch origin "$default_branch" --tags
|
|
51
|
+
git checkout "$default_branch"
|
|
52
|
+
git reset --hard "origin/$default_branch"
|
|
60
53
|
|
|
61
54
|
version=$(read_pkg_version)
|
|
62
55
|
tag="v${version}"
|
package/kody.config.schema.json
CHANGED
|
@@ -23,6 +23,11 @@
|
|
|
23
23
|
"description": "Auto-fix lint command, run when verify fails (e.g., 'pnpm lint:fix')",
|
|
24
24
|
"default": ""
|
|
25
25
|
},
|
|
26
|
+
"format": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"description": "Format check command (e.g., 'pnpm format:check', 'prettier --check .'). Empty to skip.",
|
|
29
|
+
"default": ""
|
|
30
|
+
},
|
|
26
31
|
"formatFix": {
|
|
27
32
|
"type": "string",
|
|
28
33
|
"description": "Auto-fix format command, run when verify fails (e.g., 'pnpm format')",
|
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.28",
|
|
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",
|