@cleocode/core 2026.9.3 → 2026.9.4
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/dispatch/suggested-next.d.ts.map +1 -1
- package/dist/dispatch/suggested-next.js +7 -1
- package/dist/dispatch/suggested-next.js.map +1 -1
- package/dist/docs/export-document.js +84 -0
- package/dist/docs/export-document.js.map +2 -2
- package/dist/hygiene/validate-spawn-readiness.d.ts +88 -4
- package/dist/hygiene/validate-spawn-readiness.d.ts.map +1 -1
- package/dist/hygiene/validate-spawn-readiness.js +138 -16
- package/dist/hygiene/validate-spawn-readiness.js.map +1 -1
- package/dist/injection.d.ts.map +1 -1
- package/dist/injection.js +10 -2
- package/dist/injection.js.map +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -1
- package/dist/internal.js.map +1 -1
- package/dist/llm/plugin-facade.js +84 -0
- package/dist/llm/plugin-facade.js.map +2 -2
- package/dist/release/open.d.ts +11 -18
- package/dist/release/open.d.ts.map +1 -1
- package/dist/release/open.js +135 -7
- package/dist/release/open.js.map +1 -1
- package/dist/selfimprove/fix-gen.js +84 -0
- package/dist/selfimprove/fix-gen.js.map +2 -2
- package/dist/setup/sections/brain.d.ts +1 -1
- package/dist/setup/sections/brain.js +1 -1
- package/dist/system/bridge-mode.d.ts +1 -1
- package/dist/system/bridge-mode.js +1 -1
- package/dist/tasks/index.d.ts +1 -1
- package/dist/tasks/index.d.ts.map +1 -1
- package/dist/tasks/index.js +1 -1
- package/dist/tasks/index.js.map +1 -1
- package/dist/tasks/tool-cache.d.ts +134 -9
- package/dist/tasks/tool-cache.d.ts.map +1 -1
- package/dist/tasks/tool-cache.js +188 -68
- package/dist/tasks/tool-cache.js.map +1 -1
- package/package.json +13 -13
- package/templates/CLEO-INJECTION.md +6 -6
- package/templates/workflows/release-prepare.yml.tmpl +67 -2
- package/templates/workflows/release-publish.yml.tmpl +1 -1
- package/templates/workflows/release-rollback.yml.tmpl +18 -2
|
@@ -318,7 +318,55 @@ jobs:
|
|
|
318
318
|
id: plan
|
|
319
319
|
run: |
|
|
320
320
|
mkdir -p .cleo/release
|
|
321
|
-
|
|
321
|
+
|
|
322
|
+
# gh#1370 (T12187): the plan file is NAMED BY THE COMMAND, not by us.
|
|
323
|
+
# `cleo release plan` resolves the version through `normalizeVersion`,
|
|
324
|
+
# which ADDS a leading `v` — every plan on disk is
|
|
325
|
+
# `v<version>.plan.json`. Building this path from the raw input meant
|
|
326
|
+
# a dispatch of `2026.9.1` had the command write `v2026.9.1.plan.json`
|
|
327
|
+
# while this step read `2026.9.1.plan.json`. Normalise identically.
|
|
328
|
+
RAW_VERSION="${{ inputs.version }}"
|
|
329
|
+
case "$RAW_VERSION" in
|
|
330
|
+
v*) PLAN_VERSION="$RAW_VERSION" ;;
|
|
331
|
+
*) PLAN_VERSION="v$RAW_VERSION" ;;
|
|
332
|
+
esac
|
|
333
|
+
PLAN_FILE=".cleo/release/${PLAN_VERSION}.plan.json"
|
|
334
|
+
PLAN_LOG="${RUNNER_TEMP:-/tmp}/${PLAN_VERSION}.plan.stdout.log"
|
|
335
|
+
|
|
336
|
+
# gh#1370: a release plan is a PLAN, not a summary envelope.
|
|
337
|
+
#
|
|
338
|
+
# `release plan` WRITES the plan file itself (R-030) and prints only a
|
|
339
|
+
# SUMMARY on stdout — version, taskCount, evidenceComplete,
|
|
340
|
+
# changelogWritten, planPath — with no `tasks` array. So anything that
|
|
341
|
+
# lands a stdout capture at the plan's path still parses as JSON and
|
|
342
|
+
# still hashes cleanly, and `plan-blob-sha256` downstream would then
|
|
343
|
+
# certify the integrity of the wrong artifact. Assert the SHAPE before
|
|
344
|
+
# any hash is taken over it, on BOTH branches.
|
|
345
|
+
ASSERT_PLAN="${RUNNER_TEMP:-/tmp}/assert-release-plan.cjs"
|
|
346
|
+
cat > "$ASSERT_PLAN" <<'ASSERT_PLAN_EOF'
|
|
347
|
+
const { readFileSync } = require('node:fs');
|
|
348
|
+
const target = process.argv[2];
|
|
349
|
+
let plan;
|
|
350
|
+
try {
|
|
351
|
+
plan = JSON.parse(readFileSync(target, 'utf8'));
|
|
352
|
+
} catch (err) {
|
|
353
|
+
console.error('::error::' + target + ' is not valid JSON: ' + err.message);
|
|
354
|
+
console.error('A prose-prefixed summary envelope is not a release plan (gh#1370).');
|
|
355
|
+
process.exit(1);
|
|
356
|
+
}
|
|
357
|
+
if (!Array.isArray(plan.tasks)) {
|
|
358
|
+
const keys = Object.keys(plan).join(', ');
|
|
359
|
+
console.error('::error::' + target + ' has no "tasks" array. Top-level keys: ' + keys);
|
|
360
|
+
console.error('A summary envelope is not a release plan (gh#1370).');
|
|
361
|
+
process.exit(1);
|
|
362
|
+
}
|
|
363
|
+
if (plan.tasks.length === 0) {
|
|
364
|
+
console.error('::error::' + target + ' has an EMPTY "tasks" array — refusing to release nothing.');
|
|
365
|
+
process.exit(1);
|
|
366
|
+
}
|
|
367
|
+
console.log('plan OK: ' + plan.tasks.length + ' tasks, resolvedVersion=' + (plan.resolvedVersion || '<absent>'));
|
|
368
|
+
ASSERT_PLAN_EOF
|
|
369
|
+
|
|
322
370
|
if [ -z "${{ inputs.plan-blob-sha256 }}" ]; then
|
|
323
371
|
echo "No plan-blob-sha256 input — generating fresh plan."
|
|
324
372
|
# T12089: `cleo release plan` REQUIRES a scope (--saga | --epic |
|
|
@@ -338,7 +386,21 @@ jobs:
|
|
|
338
386
|
echo "::error::No release scope supplied. Dispatch with 'epic' or 'tasks' (cleo release plan requires --saga, --epic or --tasks), or pass plan-blob-sha256 with a committed plan file."
|
|
339
387
|
exit 1
|
|
340
388
|
fi
|
|
341
|
-
|
|
389
|
+
# gh#1370: do NOT redirect stdout onto "$PLAN_FILE". The command
|
|
390
|
+
# writes that file itself; the redirect aimed a second writer at the
|
|
391
|
+
# same path and whichever landed last became the artifact hashed
|
|
392
|
+
# below. Capture stdout to a log and surface it only on failure.
|
|
393
|
+
if ! cleo release plan "$RAW_VERSION" "${SCOPE_ARGS[@]}" --json > "$PLAN_LOG" 2>&1; then
|
|
394
|
+
echo "::error::cleo release plan failed — output follows"
|
|
395
|
+
cat "$PLAN_LOG"
|
|
396
|
+
exit 1
|
|
397
|
+
fi
|
|
398
|
+
if [ ! -f "$PLAN_FILE" ]; then
|
|
399
|
+
echo "::error::cleo release plan reported success but $PLAN_FILE does not exist. Plan command output:"
|
|
400
|
+
cat "$PLAN_LOG"
|
|
401
|
+
exit 1
|
|
402
|
+
fi
|
|
403
|
+
node "$ASSERT_PLAN" "$PLAN_FILE"
|
|
342
404
|
else
|
|
343
405
|
echo "Verifying pre-computed plan against sha256=${{ inputs.plan-blob-sha256 }}"
|
|
344
406
|
if [ ! -f "$PLAN_FILE" ]; then
|
|
@@ -350,6 +412,9 @@ jobs:
|
|
|
350
412
|
echo "::error::Plan sha256 mismatch — expected ${{ inputs.plan-blob-sha256 }}, got $ACTUAL"
|
|
351
413
|
exit 1
|
|
352
414
|
fi
|
|
415
|
+
# gh#1370: a matching sha proves the file is UNCHANGED, never that
|
|
416
|
+
# it is a plan. A committed summary envelope hashes just as well.
|
|
417
|
+
node "$ASSERT_PLAN" "$PLAN_FILE"
|
|
353
418
|
fi
|
|
354
419
|
echo "plan_file=$PLAN_FILE" >> "$GITHUB_OUTPUT"
|
|
355
420
|
timeout-minutes: 5
|
|
@@ -382,7 +382,7 @@ jobs:
|
|
|
382
382
|
gh issue create \
|
|
383
383
|
--label release-incident \
|
|
384
384
|
--title "Provenance backfill needed for ${VERSION}" \
|
|
385
|
-
--body "release-publish.yml reconcile job failed for ${VERSION}. Tag and publish completed successfully; only the provenance graph is incomplete. To recover, run \`cleo release reconcile ${VERSION}
|
|
385
|
+
--body "release-publish.yml reconcile job failed for ${VERSION}. Tag and publish completed successfully; only the provenance graph is incomplete. To recover, run \`cleo release reconcile ${VERSION}\` from a local checkout. Workflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
|
386
386
|
env:
|
|
387
387
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
388
388
|
timeout-minutes: 5
|
|
@@ -298,8 +298,24 @@ been updated by the \`reconcile-rollback\` job."
|
|
|
298
298
|
# R-256: reconcile MUST write rollback marker into `releases` +
|
|
299
299
|
# `release_changes`. The CLI is the canonical writer — workflow
|
|
300
300
|
# YAML never touches the DB directly.
|
|
301
|
+
#
|
|
302
|
+
# gh#1373: `--reason` was removed from this line. It is not declared in
|
|
303
|
+
# `release reconcile`'s args — the command's whole flag surface is
|
|
304
|
+
# `--from-workflow --rollback --dry-run --json`. citty parses with
|
|
305
|
+
# `strict: false`, so `--reason` was absorbed as an undeclared boolean and
|
|
306
|
+
# `"${REASON}"` fell through as a stray positional: the operator's reason
|
|
307
|
+
# has never reached the database, and the step reported success every
|
|
308
|
+
# time. Dropping the flag does not lose information that was being
|
|
309
|
+
# recorded; it stops the step from claiming to record it. The reason is
|
|
310
|
+
# echoed into the run log so it is at least retained where an operator
|
|
311
|
+
# reading this job can see it.
|
|
312
|
+
#
|
|
313
|
+
# Giving `reconcile --rollback` a real `--reason` is a CLI change, not a
|
|
314
|
+
# workflow change, and is tracked separately.
|
|
301
315
|
- name: Record rollback
|
|
302
|
-
run:
|
|
316
|
+
run: |
|
|
317
|
+
echo "Rollback reason (not persisted — see gh#1373): ${REASON}"
|
|
318
|
+
cleo release reconcile "${VERSION}" --rollback
|
|
303
319
|
timeout-minutes: 5
|
|
304
320
|
|
|
305
321
|
# Recovery hint in the job summary so an operator who sees a
|
|
@@ -316,7 +332,7 @@ been updated by the \`reconcile-rollback\` job."
|
|
|
316
332
|
echo "**Recovery commands** (if anything went wrong):"
|
|
317
333
|
echo ""
|
|
318
334
|
echo "\`\`\`"
|
|
319
|
-
echo "cleo release reconcile ${VERSION} --rollback
|
|
335
|
+
echo "cleo release reconcile ${VERSION} --rollback"
|
|
320
336
|
echo "\`\`\`"
|
|
321
337
|
} >> "$GITHUB_STEP_SUMMARY"
|
|
322
338
|
timeout-minutes: 1
|