Distribution: CLI releases, install scripts, npm packages#22
Merged
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Phase 1 — version plumbing: scripts/set-version.ts stamps the lockstep
version across root + all workspaces; scripts/check-versions.ts enforces it
in the gate; CHANGELOG.md seeds the release-notes flow.
Phase 2 — CLI releases: cli/build.js --all-targets cross-compiles the four
release targets; scripts/package-release.ts produces tar.gz archives +
checksums.txt; .github/workflows/release.yml (tag v*) runs the same one gate,
asserts tag == lockstep version, and publishes the GitHub Release with the
CHANGELOG section as notes.
Phase 3 — install entry points: docs/install.sh (POSIX, checksum-verified,
~/.local/bin, no sudo; discovers the latest version from checksums.txt so no
GitHub API call) and docs/install.md (agent-readable manual steps).
scripts/check-install-sh.ts drives the full install loop against a local HTTP
fixture in ci; a shared serving test pins .sh-as-text/plain and raw .md
round-tripping.
Phase 4 — npm packages: the five publishable packages (shared, server-core,
server-deploy-{aws,cloudflare,local}) build to dist/ (tsc ESM +
declarations) and stage publish-shaped tarballs; scripts/check-npm-pack.ts
verifies tarball shape, imports every package under plain Node (Bun for
deploy-local), and typechecks a NodeNext consumer — all hermetically in ci.
scripts/publish-packages.ts publishes from a clean tagged checkout.
Discovered prerequisites shipped along the way: cross-package imports moved
from relative ../../../shared paths to @scratchwork/* specifiers with real
workspace deps; relative imports in publishable packages carry .ts extensions
for rewriteRelativeImportExtensions (d.ts specifiers post-processed); the
Bun-only svg text import became a generated module (freshness-checked); the
server tooling workspace dissolved into server/core/src/deploy/ with proc.ts
ported to node:child_process so deploys run under plain Node; MIT LICENSE
added (packages can't publish without one — flag if you want a different
license).
Phase 5 — RELEASING.md documents the loop end to end. The first real release
(v0.2.0) is the remaining unchecked plan item.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bun.spawnSync blocks the event loop that the Bun.serve fixture needs to answer the install script's curl (which has no timeout), so the check hung forever — locally and in the GitHub CI run for this branch, which died at the workflow's 20-minute timeout. Spawning async with awaited stdout/stderr/exit keeps the fixture responsive; the check now runs in about a second. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Encodes the release procedure as an agent skill: preflight (version choice, changelog content, gh/npm auth), bump PR, merge + tag, npm publish from a clean tag checkout, homepage republish, and a container smoke test of the real install path. Irreversible steps (tag push, npm publish, homepage republish) sit behind explicit confirmation gates. RELEASING.md stays the normative doc and now points at the skill. The release/ gitignore rule is now anchored to the repo root — unanchored it also swallowed .claude/skills/release/. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The directory was already the published scratchwork.dev site: the landing page (index.md with the logo and project description), its components, and the install.sh / install.md entry points. Naming it after the domain makes that role explicit. References updated across README, renderer README, RELEASING.md, the release skill (publish command now scratchwork.dev --project www --public), AGENTS.md's outside-the-gate list, and the install-sh check's script path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
scratchwork.dev/www is the published homepage project (landing page, components, install.sh / install.md). scratchwork.dev/server is the Cloudflare deployment workspace for the scratchwork.dev server, modeled on deploy/cloudflare-vanilla: worker scratchwork-dev, R2 scratchwork-dev, D1 scratchwork-dev-projects, routes for scratchwork.dev, www.scratchwork.dev, app.scratchwork.dev, and pages.scratchwork.dev, public OAuth with public projects allowed. It joins the root workspaces (and therefore the gate), with deploy:scratchwork-dev / local:scratchwork-dev root scripts. default-renderer.generated.js is regenerated because bun.lock is a renderer source-hash input and the new workspace changed the lockfile; the embedded renderer HTML is byte-identical. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements
notes/distribution-plan.mdend to end (every item except the first real release, which happens after merge per RELEASING.md).What's here
bun scripts/set-version.ts X.Y.Zstamps root + all workspaces; lockstep is enforced inbun run ci;CHANGELOG.mdfeeds release notes.cli/build.js --all-targetscross-compiles darwin/linux × arm64/x64 (verified locally: all four binaries build and package);release.ymltriggers onv*tags, runs the same one gate, asserts tag == version, and creates the GitHub Release with archives +checksums.txt.~/.local/bin, never sudo; latest-version discovery reads asset names fromchecksums.txtso no GitHub API call. Hermetically tested in ci (local HTTP fixture, fakeunamefor platform mapping) plus a serving test pinning.sh→text/plainand raw.mdround-tripping..d.ts, per the decision-2 flip) — the five packages tsc-emit todist/and stage publish-shaped tarballs; ci packs them, imports every package under plain Node from the real tarballs, and typechecks a NodeNext consumer.scripts/publish-packages.tspublishes from a clean tagged checkout in dependency order.Discovered work (details in the plan note)
Publishing forced structural fixes the plan hadn't named: cross-package imports moved from relative
../../../sharedpaths to@scratchwork/*specifiers; publishable packages use explicit.tsimport extensions (rewriteRelativeImportExtensions, with a d.ts post-process); the Bun-only svg text import became a generated module; and theservertooling workspace dissolved intoserver/core/src/deploy/(proc.tsported fromBun.spawntonode:child_processso deploys run under plain Node).server/core/src/deploy/{env,proc}.ts(pre-existing plain-Promise deploy tooling that moved into lint scope; rationale inline). An Effect-native rewrite of the deploy tooling chain would let the baseline shrink again.Invariants: verified per AGENTS.md (report in the session) — auth/adapters/routes untouched beyond mechanical import-specifier rewrites; full
bun run cigreen.🤖 Generated with Claude Code