con un clic
publish
Bump version, build, test, publish to npm, and install locally
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Menú
Bump version, build, test, publish to npm, and install locally
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Basado en la clasificación ocupacional SOC
Alias for /flo-simplify — see that skill's description.
Alias for /quicken — see that skill's description.
Alias for /ward — see that skill's description.
MoFlo ticket spell - analyze and execute GitHub issues
Verify-before-done — exercise the current change end-to-end against its acceptance criteria (the SDD plan's, or the ticket's) and report a per-criterion PASS/FAIL verdict, then record the outcome to memory. This is the concrete action that satisfies moflo's verify-before-done gate (`gates.verify_before_done` / `/flo -v` / `/flo -sd`). Use before `gh pr create` when the change must be proven to work, not just tested in passing. Verifies only — it does not fix; on FAIL it reports the gaps and stops.
Turn a vague idea into a concrete, actionable spec through a short Socratic dialogue, then hand the result off to an existing moflo surface — a /flo ticket, a spell, or memory. Use BEFORE you have a defined unit of work, when the goal is still fuzzy.
| name | publish |
| description | Bump version, build, test, publish to npm, and install locally |
| arguments | <patch|minor|major> <-rc> <--check|-ch> |
Automated release pipeline for moflo. Bumps version, commits, builds, tests, runs doctor, publishes to npm, and installs the new version locally.
Arguments: $ARGUMENTS
/publish # patch bump, default mode (skips CI-covered gates)
/publish minor # minor bump (4.8.56 → 4.9.0)
/publish major # major bump (4.8.56 → 5.0.0)
/publish -rc # patch RC bump (4.8.56 → 4.8.57-rc.1)
/publish minor -rc # minor RC bump (4.8.56 → 4.9.0-rc.1)
/publish --check # full pre-flight (lint + test + smoke + everything)
/publish -ch # short form of --check
/publish minor -ch # combine: full pre-flight on a minor bump
Default (flag absent): runs build + doctor + trigger-based manual checks only. Skips local lint/test/smoke because lint+test are covered by ci.yml on every PR + push to main, and cross-platform smoke is dispatched as part of this skill (Step 8.5 below) — the release-smoke.yml workflow runs the full 3-OS matrix on the exact commit about to be published.
With --check or -ch (any presence): runs the full pre-flight from pre-publish-rules.md — lint, build, test, doctor (strict), local clean smoke, local populated smoke, and a forced full walk of every manual gate. Use this for publishes that didn't go through a green PR, risky releases, or when you want belt-and-suspenders on the local box in addition to the CI matrix.
The flag is presence-only. --check and -ch both set it to true. There is no --check=true / --check=false syntax — absence means false.
patch if not specified-rc flag: produce a release candidate--check or -ch (presence): set CHECK_MODE=true. Otherwise CHECK_MODE=false.-rc: Use npm version <patch|minor|major> --no-git-tag-version-rc: Calculate manually:
4.8.57-rc.3), increment the RC number (→ 4.8.57-rc.4)-rc.1 (e.g., 4.8.56 → 4.8.57-rc.1)npm version <new-version> --no-git-tag-versionbash .claude/skills/publish/fingerprint.sh
The script diffs HEAD against the most recent chore: install moflo@* commit and pattern-matches the file list against the manual-gate triggers from pre-publish-rules.md. Output is one block:
Triggered manual checks: bin-scriptfiles-sync info-loss-audit
Diff range: <last-publish-sha>..HEAD
Changed files: 7
Triggered manual checks: none means gates 1/2/6 don't apply to this diff — skip them entirely.
This step costs ~50 tokens and is the cornerstone of token-efficient default mode.
npm run build
Always runs regardless of CHECK_MODE. Syncs the version to src/cli/version.ts via the version lifecycle script, then compiles all TypeScript. Confirms the deliverables on disk are correct.
Must exit 0. If it fails, stop and fix the build error.
CHECK_MODE=true)npm run lint
Skipped by default — ci.yml runs lint on every PR with max-warnings 0. Run when --check is set.
CHECK_MODE=true)npm test
Skipped by default — ci.yml runs the full test suite on every PR. Run when --check is set.
Must have 0 test file failures. If any test files fail, retest them individually to distinguish real failures from flaky ones (per broken window theory). Fix all real failures before proceeding.
npx moflo doctor --strict
Doctor is the only check with no CI equivalent — it inspects local state (daemon lock, embeddings hygiene, sandbox tier, vector-stats freshness) that CI cannot validate for you. Always runs in --strict mode regardless of CHECK_MODE.
Never --fix on the publish path. A release pipeline must fail fast on broken local state, not silently repair it; a doctor that auto-repairs masks the very signal we want — "something is off, stop and investigate before shipping." If doctor --strict fails, stop and run flo healer --fix (or npx moflo doctor --fix) interactively, verify the repair, then retry the publish.
CHECK_MODE=true)npm run test:smoke
npm run test:smoke:populated
Skipped by default. Local smoke covers the same harness as CI's Ubuntu leg, so it adds little signal over release-smoke.yml's Ubuntu matrix entry (Step 8.5). Run only when --check is set — useful if you want belt-and-suspenders on the local box before dispatching the full CI matrix.
Read the fingerprint output from Step 1.
| Trigger | Manual check (gate) | What to walk |
|---|---|---|
split-newlines | Gate 7 | Diff the changed file-reading code; verify any newline split uses /\r?\n/ not '\n' |
homedir-tmpdir | Gate 7 | Verify env-var literals use os.homedir() / os.tmpdir(), not raw process.env.HOME / /tmp |
bwrap-permissions | Gate 7 | Spell bash steps that need network declare permissionLevel: elevated |
posix-only-spell-bash | Gate 7 | Spell bash steps avoid mkdir/rm/cp; use node -e with fs/os for cross-platform file ops |
bin-scriptfiles-sync | Gate 8 | New bin/ script appears in all three scriptFiles arrays (session-start-launcher.mjs, init/moflo-init.ts, third sync site) |
helper-static-files | Gate 8 | New helpers ship as static bin/ files, not generated at runtime |
shipped-guidance-prefix | Gate 8 | New shipped guidance has moflo- prefix and lives in .claude/guidance/shipped/ |
files-glob-coverage | Gate 9 | Run npm pack --dry-run and confirm new shipped files appear in the tarball listing |
info-loss-audit | Gate 10 | For each deleted/renamed file, audit destinations bullet-by-bullet — every piece of removed content has a home |
If CHECK_MODE=true, walk all manual gates regardless of triggers (full audit). If CHECK_MODE=false, walk only triggered ones.
If the trigger set is none AND CHECK_MODE=false: skip Step 7 entirely.
Commit the version bump files:
git add package.json package-lock.json src/cli/version.ts
git commit -m "chore: bump version to <new-version>"
git push origin main
Only commit version-related files. Do not stage unrelated changes.
# Capture the SHA we just pushed — release-smoke runs against this exact commit.
PUBLISH_SHA=$(git rev-parse HEAD)
# Trigger the full 3-OS × 2-harness matrix. `sha` is a required workflow input
# so the dispatched run is unambiguously bound to this commit.
gh workflow run release-smoke.yml --ref main -f sha="$PUBLISH_SHA"
# Give GitHub a moment to register the dispatched run.
sleep 10
# Find the run we just dispatched by matching head_sha. This is robust against
# concurrent dispatches (e.g. a manual UI retry from another tab) — never use
# `--limit 1` alone, which would race against any unrelated in-flight run.
RUN_ID=$(gh run list --workflow=release-smoke.yml --branch main \
--json databaseId,headSha \
--jq ".[] | select(.headSha == \"$PUBLISH_SHA\") | .databaseId" \
| head -1)
if [ -z "$RUN_ID" ]; then
echo "ERROR: no release-smoke run found for SHA $PUBLISH_SHA. Wait a few seconds and retry, or check https://github.com/eric-cielo/moflo/actions/workflows/release-smoke.yml" >&2
exit 1
fi
# Block until the run completes. Exits non-zero on failure.
gh run watch "$RUN_ID" --exit-status
release-smoke.yml runs full consumer + populated smoke on Ubuntu/macOS/Windows, plus file-sync smoke on all three filesystems. Per-PR CI is intentionally Ubuntu-only to keep recurring cost manageable — the full cross-platform matrix is paid once here, at publish time, against the exact commit we're about to publish.
Wall time expectations: typical run is ~15-20 min once caches are warm. The first dispatch after release-smoke.yml lands will have cold caches on every leg (no prior runs of this workflow exist to populate the consumer-warm and fastembed caches per-OS). Expect ~25-35 min on that first dispatch — the macOS leg is the long pole. Subsequent dispatches reuse the cache and settle to the typical ~15 min.
If gh run watch exits non-zero: stop immediately. Inspect the failed leg with gh run view "$RUN_ID" --log-failed, fix the underlying issue, push the fix, then re-run this step (no need to rerun Steps 0–8 — the bump commit is already on main, and the SHA-filtered lookup will pick up the new dispatched run against the same SHA only after cancel-in-progress: false lets the previous run drain). Do not proceed to npm publish until release-smoke is green for the SHA you intend to publish.
npm whoami
If 401 or "not logged in": auth token in ~/.npmrc is missing or expired. Ask the user for a valid npm publish token.
How to create a token (provide these instructions to the user if needed):
moflo packagenpm_...)Once the user provides the token, write it to ~/.npmrc:
echo "//registry.npmjs.org/:_authToken=<token>" > ~/.npmrc
Verify with npm whoami before proceeding.
npm publish --tag <tag>
npm publish (publishes to latest tag by default)npm publish --tag rc (publishes to rc tag so it doesn't become latest)OTP handling:
npm publish --otp=<code> --tag <tag>npm view moflo version
npm view moflo dist-tags
Confirm the published version matches what we just built.
npm install moflo@<new-version> --save-dev
npm install --package-lock-only --force
npm ci --dry-run --legacy-peer-deps
The first command updates package.json and package-lock.json to use the newly published version as a devDependency.
The second command (--package-lock-only --force) backfills cross-platform optional-dependency entries that npm omits from the lockfile when npm install runs on a single host platform. Without it, transitive optional deps like the nested @rolldown/binding-wasm32-wasi/node_modules/@emnapi/* entries get dropped when publishing from Windows, and the resulting lockfile fails npm ci on Ubuntu/macOS CI legs. This produced the green-release-smoke → red-ci.yml divergence in run 26487580745 (moflo@4.10.27 install commit).
The final npm ci --dry-run --legacy-peer-deps proves the resulting lockfile is in sync with package.json before we commit it. If this exits non-zero, stop and investigate — do not commit a broken lockfile.
If package.json or package-lock.json changed from the install:
git add package.json package-lock.json
git commit -m "chore: install moflo@<new-version>"
git push origin main
The chore: install moflo@<version> commit message is the anchor the fingerprint uses to bound future diffs — keep the prefix exact.
Print a summary at the end:
Publish Summary
───────────────
Mode: default | --check
Version: <old> → <new>
Tag: latest | rc
Build: passed
Tests: skipped (CI-covered) | <N> files passed, <N> tests passed
Lint: skipped (CI-covered) | passed
Doctor: <N> passed, <N> warnings
Smoke (local): skipped (CI-covered) | passed
Release-smoke: green (run <id>, 3-OS × 2-harness)
Triggered gates: <list> | none
Published: moflo@<new-version>
Installed: moflo@<new-version> (devDependency)
--force on npm publishprepublishOnly script in package.json runs npm run build automatically, so npm publish will fail-fast on any TypeScript or asset-bundling error even if Step 2 had been skipped (it isn't — Step 2 always runs).claude/guidance/internal/pre-publish-rules.md — never duplicate or paraphrase them in this skill; reference and follow--checkUse --check / -ch when:
For the common case — publishing right after a merged green PR — the default mode is correct and meaningfully cheaper in tokens and time.
.claude/skills/publish/fingerprint.sh — Trigger-fingerprint script invoked by Step 1.claude/guidance/internal/pre-publish-rules.md — Authoritative gate ruleset (gates 1–10) and trigger mapdocs/BUILD.md — Step-by-step build/publish process this skill mirrors.claude/guidance/internal/dogfooding.md — Why we catch consumer-facing regressions first as our own dependencyharness/consumer-smoke/README.md — Smoke harness profiles (clean + populated) that prove a consumer install works.github/workflows/ci.yml — Lint/build/test gates this skill skips by default (ubuntu-only).github/workflows/consumer-install-smoke.yml — Per-PR ubuntu-only smoke.github/workflows/file-sync-smoke.yml — Per-PR ubuntu-only file-sync smoke.github/workflows/release-smoke.yml — Full 3-OS × 2-harness matrix this skill dispatches at Step 8.5