Changelog
What shipped, when, and what changed.
Pulled live from the GitHub releases page. Every version here has a git tag and a npm publish. No ghosted features, no marketing-only version numbers.
What changed
- v0.9.2-alpha.0 (#38) (12576c2)
- Commit the recorded demo GIF + embed in README (#37) (e6d764e)
- Readiness round 3: demo cast, perf guidance, release workflow guard (#36) (bf1884a)
- Readiness round 2: R1.2-R3.4 (CLI polish through release automation) (#35) (f33425d)
- Readiness round 1: dogfood, error paths, front-door, roadmap (#34) (31fc1d0)
- tokens:
spine tokens pull— Figma Variables → DTCG bridge (#33) (f6542fe) - Docs: contract /docs to a pointer list, drop the 7-card link pile (#32) (40fb49c)
- Templates: add api-service and monorepo to the bundled preset set (#31) (21cba35)
- Bump the runtime-deps group across 1 directory with 3 updates (#27) (b9509cd)
- chore: repo hygiene — gitignore maintainer-local state, silence lockfile warning (#30) (a0f06f1)
- CLI: single source of truth for the version string (#29) (2d727b1)
- CLI: black-box e2e tests for every routed subcommand (#28) (68b0322)
- Error pages: upstream reporting, copy-digest, GitHub-issue handoff (#26) (88c61c2)
- Changelog: parse release bodies as sanitized markdown, drop 30-line trim (#24) (ff27932)
- drift: add
spine drift diff— unified diffs for hand-edited exports (#25) (8968591) - CSP: drop nonce from style-src so 'unsafe-inline' actually takes effect (#23) (5532957)
- CLI: unroute hosted-tier subcommands while the hosted tier is dormant (#22) (9924013)
- Add ROADMAP.md (#21) (4a63dbd)
- Mobile nav: portal to body, primary nav links, matched toggle alignment (#19) (14ae5fe)
- Docs: sync README + CONTRIBUTING with v0.9.x alpha reality (#18) (93b4b3e)
- Mobile nav: slide-in side tray with hamburger trigger, product + pages + GitHub (#17) (9a0b695)
- Header logo: orbit reverses on mouseleave instead of snapping back (#16) (1b65105)
- 404: slashed zero (Ø) replaces rotating ring — null-context concept, no motion (#15) (b3fe118)
- Hide Next dev-indicator badge — dev-only noise, never reached prod anyway (#14) (3e6c609)
- Footer: sticky-footer flex layout — footer hugs viewport bottom on short pages (#13) (0fc619f)
- Pricing: drop tier cards + 'What we won't do' — just say it's free (#12) (51eb006)
- Strip hosted sales surface; position as pure OSS CLI (#11) (103fb63)
- Workspace dashboard: real row actions, smart post-auth landing (#9) (9c50408)
- Section tail: link sits above the divider, not below (#8) (46f453b)
- Hero CTAs: 32px top margin so they breathe below the install caption (#7) (8f2f01f)
Install
npm install -g project-spine@0.9.2-alpha.0Or grab the latest alpha via
npm install -g project-spine@next.The operating layer now speaks the design-system's actual tokens, not just the design-rules Markdown.
What's new
New
--tokensinput forspine compile:spine compile --brief ./brief.md --repo . --tokens ./tokens.jsonAccepts design tokens exported from Figma, Tokens Studio, or any W3C DTCG-compliant source. Tokens are merged into the existing
DesignRulespipeline, so every exporter (AGENTS.md, component-plan.md, qa-guardrails.md, etc.) surfaces the brand palette, spacing scale, and typography with source pointers back to the original JSON.Parser features
- Auto-detects format: DTCG (
$value/$type) vs Tokens Studio (value/typewithout$prefix) - Resolves aliases:
{color.primary}style references resolve recursively across the document - Infers types: when
$typeis missing,color/dimension/fontFamily/fontWeight/shadoware detected from path name or value pattern - Source pointers: every token becomes a
kind: "design"rule inspine.jsonwith asource.pointerlikedesign:tokens.json#color/primaryso rules are traceable
Drift detection
Tokens are tracked separately in the export manifest:
drift detected — 2 item(s): [input:tokens] tokens.json — design tokens file changed since last compile. [spine:hash] — spine hash changed (…). Run `spine compile` to refresh exports.Re-run
spine compilewith the same flags to regenerate. A tokens edit no longer double-firesinput:design— the manifest hashes file-based design separately from the tokens-derived section.Example
{ "color": { "primary": { "$value": "#6366f1", "$type": "color", "$description": "brand primary" }, "button": { "bg": { "$value": "{color.primary}", "$type": "color" } } }, "space": { "md": { "$value": "16px", "$type": "dimension" } } }→ AGENTS.md gets a
## Design tokensblock:- color.primary (color): #6366f1 — brand primary - color.button.bg (color): #6366f1 - space.md (dimension): 16pxAlso
docs/tokens.mddocuments the format + drift semanticsproject-spine-kickoffandproject-spine-driftagent skills reference the new flag andinput:tokensdrift kind- 7 new parser tests; full suite 72/72 green
- Auto-detects format: DTCG (
Project Spine is going AI-first on the operating surface, not just on the output surface.
What's new
Six agent skills in
skills/that teach coding agents (Claude Code, Codex CLI, Cursor) how to drive the CLI correctly without the user memorizing commands:Skill Triggers on project-spine"new client project", "AGENTS.md is stale", general orientation project-spine-kickoff"set up Project Spine", "create AGENTS.md from scratch" project-spine-drift"drift", "AGENTS.md is out of date", "check if my spine is current" project-spine-template"use our agency starter", "save this as a team template" project-spine-rationale"share the rationale with the client", "publish project overview" project-spine-workspace"set up a workspace", "invite a teammate", "join my team's workspace" Each skill is a single
SKILL.mdwith YAML frontmatter — the agent auto-loads it when a trigger phrase shows up in the conversation. Skills chain (e.g. kickoff → workspace → rationale) so long-running flows compose.Installing
# Claude Code ./skills/install.sh # also install into Codex CLI ./skills/install.sh --codex # dry-run ./skills/install.sh --dry-runSymlinks into
~/.claude/skills(and~/.codex/skillswith--codex). Re-run after pulling to pick up new skills — existing symlinks are left alone.Also
skills/ships in the npm tarball so globally-installed users can still run the installer out of$(npm root -g)/project-spine/skills- README has a new "Agent skills" section
- 65 tests still green
LLM enrichment lands — opt-in, non-load-bearing, with a real secrets scrubber in front of the wire.
Install / upgrade
npm install -g project-spineWhat's new
--enrichflag onspine compileexport ANTHROPIC_API_KEY=sk-ant-... spine compile --brief ./brief.md --repo . --enrichOne LLM call per compile, produces a sharper intro paragraph for the client-facing rationale.md. Wrapped in
<!-- spine:ai-generated model=... -->markers so reviewers can see exactly what's synthesized vs deterministic.Without
--enrich, the compile is byte-for-byte identical to 0.7.x — no network, no prose changes. With--enrichbut no API key, silently skipped (reportsenrichment: no ANTHROPIC_API_KEY — skipped).Secrets scrubber
Every string headed to the LLM is pre-flighted through
src/llm/scrubber.ts— env-style assignments (*_KEY/*_SECRET/*_TOKEN/ ...), GitHub PATs / OAuth tokens, Anthropic / OpenAI / Stripe / Slack / AWS keys, PEM private-key blocks, and Spine's ownsps_bearer tokens. Conservative by design; 8 unit tests.Fail-closed invariants
- No LLM calls without
--enrichAND an explicit API key. - Enriched output must pass sanity checks (length, no AI refusal patterns) or the deterministic baseline ships.
spine.json,warnings.json,AGENTS.md,CLAUDE.md,copilot-instructions.mdare never touched by the LLM layer. Drift detection and agent rules stay reproducible.
See
docs/llm.mdfor the full contract.What's next
- Figma tokens import — parse a tokens.json and compile into design rules automatically
- Workspace settings page — rename, brand color, logo (currently CLI-only via workspace create)
- CSP nonces — drop
'unsafe-inline'from script-src when Next.js 16 ships stable nonces
- No LLM calls without
The hosted service is no longer CLI-only. Workspaces have a real web UI, a proper web session for browser sign-in, and an invite flow so agency owners can bring teammates in.
Install / upgrade
npm install -g project-spineWhat's new in 0.7.0-alpha.0
Web sessions (separate from CLI bearer)
web_sessionstable, 30-day TTL, HttpOnly/Secure/SameSite=Lax cookie/loginentry page — auto-bounces already-signed-in users to?next=.../logoutrevokes server-side + clears the cookie- Unified
/api/auth/github/callback— distinguishes device flow (CLI) from web flow (browser) by which state cookie is set
Workspace UI at
/w/[slug]Real, not the placeholder anymore. Shows:
- Header with workspace name, description, and brand accent
- Members — list with role badges (owner badge in brand color)
- Templates — name + title + project type
- Published rationales — links to
/r/:slug, updated dates - Projects (drift) — clean/drifted status, last drift timestamp
- Invite teammate pane with the exact CLI command (owner/admin only)
Non-signed-in visits redirect to
/login?next=/w/:slugso the path survives the OAuth hop.Invites
workspace_invitestable (7-day TTL, single-use, role enum)spine workspace invite --role member|adminprints a shareable URL/invite/[code]— branded accept page with inviter name, workspace name, role, expiry- Unauthenticated visitors get "Sign in with GitHub to accept" (kicks off web OAuth with
next=/invite/CODE) - Signed-in visitors get a one-click accept → membership created → redirect to
/w/:slug?welcome=1
CLI additions
Command Purpose spine workspace invite [--role member|admin]prints invite URL + expiry spine workspace memberslists members with roles What's next
- Loop back on GH Actions Dependabot bumps (#1 #2)
- Web invite creation UI (currently CLI-only)
- LLM enrichment layer for rationale prose + backlog copy
- Stripe billing when demand appears
Drift goes from solo-file to team-fleet-view, and the hosted service now has proper Privacy / Terms / SECURITY docs.
Install / upgrade
npm install -g project-spineWhat's new in 0.6.0-alpha.0
Phase 3 — drift push (fleet view primitive)
Drift reports can now be pushed to a workspace, giving agencies one spot to see every client project's current state:
spine drift check --push # after normal drift check output: # pushed to workspace "petri-agency" → project "acme-demo" (project_created) # https://projectspine.dev/w/petri-agency/drift/acme-demo- Project rows auto-create on first push;
last_spine_hash+last_cleanare kept current drift_snapshotsstores a compact time-series (counts + items JSONB) — last 50 fetched by default- API:
POST/GET /api/workspaces/:slug/drift,GET /api/workspaces/:slug/drift/:projectSlug - CI-friendly:
--pushfailure is non-fatal for the drift check's own exit-code semantics
(The web fleet-view UI lands in 0.7.x alongside the workspace UI redesign.)
Governance
/privacy— what we collect, where it lives, how to get it deleted/terms— acceptable use, public-rationale warning, liability-as-is- Expanded SECURITY.md with a full hosted-service posture section (auth model, OAuth state, authorization 404s, secrets handling, DB isolation, log hygiene, coordinated-disclosure timelines)
- Landing page footer links to all three
What's next
- 0.7.x — workspace web UI + invites (members list, template browser, rationale list, fleet view, invite flow)
- LLM enrichment layer (opt-in, content scrubbed before send)
- Stripe billing once there's real demand
- Project rows auto-create on first push;
The sales-tool piece lands here: agencies can now publish a branded, public rationale URL straight from their CLI.
Install / upgrade
npm install -g project-spine # or pinned npm install -g project-spine@0.5.0-alpha.0What's new in 0.5.0-alpha.0
Rationale URLs
A workspace owner/member can publish the compiled
rationale.md(already produced byspine compile) to a public, unguessable URL that inherits the workspace's branding:spine compile --brief ./brief.md --repo . --template saas-marketing spine publish rationale # prints: https://projectspine.dev/r/4gHsVAQ7dtQcoQFeatures:
- Unguessable slug (10 bytes base64url) + revocable anytime with
spine rationale revoke <slug> - Workspace branding — brand color (pink/cyan accent on the page), optional logo
- noindex robots + no OG image leak of rationale content — links work only for who you share them with
- Upsert by project name — re-publishing keeps the URL stable across compile iterations
- Content-hash traceability — every rationale carries sha256 of its canonical payload
New CLI commands
Command Purpose spine publish rationale [--workspace <slug>] [--title "..."]upsert & print URL spine rationale list [--show-revoked]browse active (and optionally revoked) spine rationale revoke <slug>soft-delete; URL starts 404-ing Backend additions
- New
rationalestable (workspace_id, public_slug, project_name, title, spine_hash, content_md, content_hash, published_by, revoked_at) - Public
/r/[publicSlug]page — server-rendered markdown viamarked, inline CSS with workspace accent, proper OG metadata - API routes:
POST/GET /api/workspaces/:slug/rationales,DELETE /api/workspaces/:slug/rationales/:publicSlug - Dev-deps bumped: TypeScript 6, @types/node 25, vitest 4 (Dependabot #3)
End-to-end verified before release
spine compile→spine publish rationale→ public URL returns HTTP 200 with "Petri's agency" branding, markdown-rendered content, x-matched-path: /r/[publicSlug]- Content hash matches between CLI push and server-stored row
What's next
- Phase 3 — drift push to workspace + fleet view API + CLI wiring
- Governance — Privacy, Terms, updated SECURITY.md
- 0.6+ — workspace UI (members list, template browser, invites via web)
- Unguessable slug (10 bytes base64url) + revocable anytime with
The first hosted-workspace release. CLI can now push and pull templates across client projects via a shared Project Spine workspace — the agency wedge.
Install
npm install -g project-spine # or from the alpha channel (same version until next breaking change) npm install -g project-spine@nextMajor additions in 0.4.0-alpha.0
Hosted backend at projectspine.dev
- Next.js 15 app router + Drizzle + Neon Postgres
- GitHub OAuth device flow for CLI auth (RFC 8628-shaped)
- Six tables: users, workspaces, memberships, templates, device_codes, auth_tokens
- Security posture: bearer tokens stored sha256-only, HttpOnly/Secure cookies with OAuth state, content-addressable template hash
CLI commands
spine login/logout/whoami— device flow, ~/.project-spine/config.json with 0600 permsspine workspace create|list|switch|current— multi-workspace supportspine template save --location workspace— push local brief + manifest + design-rules to a workspacespine template list --workspace— browse server-sidespine template pull <name>— download into your local user library; thenspine init --template <name>works as usual
Public domain
- Live at https://projectspine.dev with the landing page, favicon set, and the placeholder /w/:slug page
End-to-end verified
Full round-trip executed before publish:
- login via device flow → token persisted → whoami round-trip
- workspace create → push template → list shows it server-side → pull from a different directory → content hash matches
What's not in this release
- Full workspace web UI (/w/:slug shows a placeholder pointing at the CLI; rich UI lands in 0.4.1)
- Shareable client rationale URLs (Phase 2)
- Drift dashboard / fleet view (Phase 3)
- Billing / Stripe integration (when there's demand)
Breaking changes
None since 0.3.x. The CLI added commands; existing
compile,drift,template save --location user|projectall work identically.Status
Pre-alpha. Interface may still shift; data model is versioned and additive. Feedback welcome at https://github.com/PetriLahdelma/project-spine/issues.
The moat piece: Project Spine can now tell you when what's on disk no longer matches what
spine.jsonsays it should be.Install
npm install -g project-spine@nextWhat's new in 0.3.0-alpha.0
Drift detection
spine drift checkcompares the current repo to the last compile and producesdrift-report.md+drift-report.json.- Detects four kinds of drift:
- Input drift —
brief.md,design-rules.md, template, or repo-profile changed since last compile - Spine hash drift — current inputs would compile to a different
spine.json - Export hand-edit —
AGENTS.md,CLAUDE.md, or any generated export has been edited since compile - Missing exports — files listed in the manifest are no longer on disk
- Input drift —
- CI-friendly exit codes with
--fail-on none|any|inputs|exports. docs/drift.mddocuments the contract and includes a ready-to-copy GitHub Action.
Idempotency fix
The drift tests surfaced a real bug: compile used to hash the agent-file presence that compile itself writes. This made compile self-feeding — the second run had a different hash than the first even with no user change. Fixed by canonicalizing the hash payload via
canonicalizeForHash/canonicalizeRepoForHash, which strip timestamps and the agent-file state Spine produces. Compile is now idempotent;spine drift checkright afterspine compileis always clean.Also
export-manifest.jsonschema (first hashed contract for file-level drift)- This repo now runs
spine drift checkagainst itself in CI (see.github/workflows/drift.yml) - 57 passing tests (+7 drift scenarios)
What's next
- More detector depth (Figma token JSON, more framework variants)
- LLM enrichment layer (opt-in, never load-bearing) for richer rationale prose
- Hosted workspace + team templates (v0.4)
First public release of `project-spine` on npm.
Install
```bash npm install -g project-spine@next spine --help ```
What's in 0.1.0-alpha.0
- Brief parser (Markdown + YAML frontmatter, fuzzy section headings, project-type classifier)
- Repo analyzer (framework, routing, styling, testing, linting, TypeScript strictness, CI, agent files, monorepo detection)
- Rules compiler that merges brief + repo + optional design + optional template into a canonical `spine.json` with source-pointer traceability on every rule
- 9 exporters: `AGENTS.md`, `CLAUDE.md`, `copilot-instructions.md`, architecture summary, scaffold plan, route inventory, component plan, QA guardrails, sprint-1 backlog, client rationale
- 4 starter templates (saas-marketing, app-dashboard, design-system, docs-portal) that contribute routes / components / QA / agent rules
- User-authored templates via `spine template save`
- `spine explain ` with per-warning suggestions
- `spine compile --fail-on warn|error` for CI integration
- Sprint-1 split into setup (clear-the-runway) + deliver (from brief goals)
Status
Pre-alpha. Interface may shift. See PRD.md for the product thinking and docs/field-notes.md for honest dogfood notes.
What's next (from the roadmap)
- v0.3 drift detection — `spine drift check` with CI-friendly exit codes and a GitHub Action wrapper. The moat piece.
- More detector depth (Figma token JSON, more framework variants)
- First paid tier around drift + governance
Cached for 10 minutes. Source of truth: github.com/PetriLahdelma/project-spine/releases.