Skip to content

Upgrading from 1.x

GAIA 2.0.0 moves the React app, and the Claude setup that applies only to it, into frontend/. The project root becomes a pnpm (opens in a new tab) workspace that holds the shared setup. The 1.6.1 /update-gaia cannot make that move: it merges each file by its path, so it would see every app file at its old path as deleted in the new release. Instead, the v2.0.0 release includes a migration note, a step-by-step guide that Claude follows in your session.

Only 1.6.1 can migrate. On an older 1.x version, update to 1.6.1 first.

A fitness category you added to wiki/decisions/Claude Integration Fitness.md no longer runs in 2.0.0, and the migration replaces that page. If you added any, save them first, while the project is still on 1.6.1. Ask Claude:

Before the GAIA 2.0.0 migration, copy my custom fitness categories out of wiki/decisions/Claude Integration Fitness.md and turn each one into a rule or a skill.

On the machine that does the migration:

  1. Run claude update in your terminal so Claude Code is 2.1.287 or later. It updates Claude Code itself, so it runs outside Claude. The 2.0.0 audit that merges the migration needs it. On 2.1.304 or later, the audit agents start with a smaller context and cost less.
  2. From the main copy of your 1.6.1 project (not a worktree), with no uncommitted changes, run /update-gaia.
  3. The release notes open with a notice for 1.6.1 projects. The update question offers Proceed or Abort. Claude answers Abort for you, because the normal update cannot move a 1.x project, and offers the migration instead.
  4. Say yes. Only then does Claude download gaia-bundle-v2.0.0.tar.gz, check it against its published .sha256 checksum, unpack it, and follow the .gaia/migrations/2.0.0.md note inside it, in the same session.

Nothing in the repository changes before the note’s first step: no stash, commit, or branch.

If you read the release notes on GitHub instead, open Claude Code in your 1.6.1 project and ask it to migrate the project to GAIA 2.0.0.

Before changing anything, the note checks your project and stops with a clear message when:

  • .gaia/VERSION is not exactly 1.6.1
  • frontend/ already exists
  • You are in a worktree, not your main copy of the repo
  • There are uncommitted changes (commit or discard them first, including unfinished TDD work)
  • A plan has started running (finish and merge it, or abandon it)
  • Claude Code is older than 2.1.287
  • gh is not logged in, or jq, tar, or shasum is missing

Spec work that is not finished carries over: a finalized SPEC, a plan written but not started, or a /gaia-spec draft in progress.

  • All work happens on a branch named chore/migrate-gaia-2.0.0. Nothing is committed on main.
  • Claude records its progress in a local file that is not committed, so a new session picks up where the last one left off.
  • Step 7 ends in a restart: quit Claude Code and start a new session from the repository root so the 2.0.0 hooks load. The progress file picks up where it left off.
  • Every commit goes through your git hooks as they are at that point in the migration. The note never uses --no-verify.
  • For every file that comes from GAIA, Claude compares three versions: the 1.6.1 original, yours, and the 2.0.0 one. Your changes stay, GAIA’s changes come in, and you are asked about any real conflict.
  • It never deletes an uncommitted or untracked file of yours without asking where to keep it, never opens a .env file (env files are moved, not read), and never copies GAIA’s lockfile (pnpm install regenerates it).
  • It ends by opening one pull request, which merges through the 2.0.0 Code Audit Team. Restart Claude Code from the project before that audit runs, so the two new audit agents, audit-rule-specialist and audit-refuter, load. In a session started earlier, code-audit-frontend does their reviews itself and says so in its report.

The note makes every 2.0.0 change to GAIA’s own files, and makes or lists the changes your own code needs. In summary:

  • The app, its tests and configs, and the frontend-only rules, skills, and agents move under frontend/. Your .env files move to frontend/.
  • Route files are renamed to the flat file names @react-router/fs-routes expects, and component, page, and hook folders are renamed to kebab-case, your own included. Your app’s URLs do not change.
  • Husky is replaced by plain git hooks in .githooks/.
  • spec-kit’s files are removed. GAIA’s own spec workflow files move to their new paths, with any edits you made.
  • SPEC numbers are no longer tracked in the committed .gaia/specs.json file; they come from spec/NNN git tags instead, and specs, plans, and research move into the gitignored .notebook/.
  • The GAIA CI workflows, actions, and leftover files are removed.
  • The Code Audit Team, a set of reviewers each responsible for certain files, replaces the single code-review-audit agent, and the new Code Audit Team audits the migration’s own pull request.
  • shadcn/ui (opens in a new tab) replaces GAIA’s components, stories replace component tests, and the data layer changes (see Your own code).

Only after the merge does Claude change anything on GitHub, and it asks you before each change:

  • Push a spec/NNN starting tag so the next SPEC number continues from your highest one.
  • Remove the old code-review-audit required check, keeping GAIA-Audit and every other check.
  • Delete the GAIA CI secrets (CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_API_KEY). Revoke the token where you created it and uninstall the Claude GitHub App yourself. Deleting the secret alone leaves the credential working.
  • Sync labels (renaming severity:important and severity:suggestion in place), close open gaia-ci pull requests, and delete gaia-ci/ branches.

It then asks before deleting leftover local files, sets up any existing worktrees that already have the 2.0.0 layout, and passes you to /setup-gaia, which records the 2.0.0 setup decisions.

Until the pull request merges, everything is on your machine and can be undone, and nothing on GitHub has changed. Ask Claude to undo it:

Roll back the GAIA 2.0.0 migration. Follow the Rollback section of the 2.0.0 migration note.

Claude moves your env files back, switches to main, deletes the migration branch, restores the SPEC ledger, undoes the notebook move, reinstalls packages, and checks that the 1.6.1 git hooks are active again. Then restart Claude Code yourself so the 1.6.1 hooks load.

The note sets up only the machine that runs it. Every teammate, and every other machine you use, catches up once after pulling the merged migration, from the root of the main copy of the repo. Node 22.22.0 or newer is required.

  1. Make sure the project is on GAIA 2.1.0 or later. /setup-gaia does the catch-up from 2.1.0 on. If the project is still on 2.0.x, run /update-gaia and merge the update first. That happens once for the project, not once per machine.

  2. Update Claude Code to 2.1.287 or later. Run this in your terminal, since it updates Claude Code itself:

    Terminal window
    claude update
  3. Start Claude in the project and type /setup-gaia. On a machine that was on GAIA 1.x, setup finds what 1.x left behind and fixes each item. It asks before deleting the retired files, removing Serena or the plugin, renaming and pushing branches, and running the leftover-file cleanup. The install and the two moves run without a question.

    • runs pnpm install for the new frontend/ layout
    • deletes the retired local GAIA files (.gaia/cache, .gaia/local/handoff, and an old decline ledger)
    • moves your specs, plans, and research into the Notebook
    • moves a root React Doctor skill under frontend/.claude/skills/
    • removes Serena, which 2.0.0 dropped
    • renames each unmerged spec-<nnn>-<slug> branch to its 2.0.0 name and pushes it
    • finds the old abbreviated GAIA_* variable names in your shell profile and CI workflows, and offers to fix the workflows
    • offers to uninstall the claude-obsidian plugin if you do not use it outside GAIA
    • runs the leftover-file cleanup

    Until it runs, the statusline shows a /setup-gaia nudge. /update-gaia can also do it: on a machine that is behind, its pull runs the catch-up, and on the machine that runs the update, Claude runs it in the main checkout after merging the update’s pull request.

    Setup also asks to turn the git hooks on if they are off, enables pnpm at the pinned version, installs Chromium (the browser the tests run in), and records this machine’s 2.0.0 choices. Claude Code may ask you to approve running the notebook move script; approve it. A step that fails is reported and retried on the next /setup-gaia run.

    Claude cannot open .env files, so check frontend/.env yourself for the old variable names. GAIA_LEDGER_LOCK_TIMEOUT_SECS, GAIA_LEDGER_LOCK_STALE_SECS, and GAIA_LEDGER_LOCK_POLL_SECS now end in _SECONDS. GAIA_SPEC_REMOTE_TIMEOUT_SECONDS, GAIA_SPEC_ALLOCATION_MAXIMUM_RETRIES, GAIA_TITLE_MAXIMUM_LENGTH, and GAIA_WIKI_FETCH_MINIMUM_INTERVAL_MINUTES replace their abbreviated forms. An old name is ignored without any warning. Setup leaves your shell profile files to you too: it names each match and its new name.

    Until the notebook move runs, the spec and plan commands stop and say the move is needed.

The note changes GAIA’s files and lists what your own code needs. The release notes mark every such item Action required with the exact command. Claude can make these changes. After the migration merges, ask:

Read the GAIA 2.0.0 release notes on GitHub. Go through their "Action required" items for my own code and make the changes, one item at a time, asking before anything I might want to keep.

The ones most projects meet:

  • shadcn/ui role tokens. Colors come from named roles (shadcn tokens such as primary or muted) in frontend/app/styles/theme.css. Removed utility classes and the primary-* color scale map to those tokens, and GAIA’s Button, LinkButton, Toast, form wrappers, and react-icons are replaced by ui/* components and lucide-react (opens in a new tab).

  • cn. cn from the cn package replaces twMerge and twJoin, with cond && 'class' as the one conditional form.

  • @gaia-react/lint 3.0.0. New rules, a required -- reason on every eslint-disable, and an optional ...lint.reactRouter group. Claude can add the new ... entries to frontend/eslint.config.mjs. GAIA asks you to approve every edit to that file, because the same kind of edit can also switch rules off.

  • Stories as tests. React Testing Library, happy-dom, and jsdom are gone. Convert component tests to stories with play functions and hook tests to vitest-browser-react.

  • Chromatic (opens in a new tab) modes. Replace chromatic: {viewports: [...]} with viewports set per mode, and excludeDark with modes: {dark: {disable: true}}.

  • msw 3. Ask Claude to migrate your handlers to msw 3; it runs msw’s codemod (npx codemod@latest run @mswjs/v3).

  • Data layer. Services are Ky (opens in a new tab) and Zod (opens in a new tab) modules, and create() defaults to camelCase. A snake_case backend passes {isSnakeCaseEnabled: true}.

  • FormError’s hide prop is now isHidden.

  • Label renames. priority:high, priority:critical, and needs-human-review in your own workflows or templates become severity:major, severity:critical, and needs-human. Ask Claude:

    Find the old GAIA label names (priority:high, priority:critical, needs-human-review) in my workflows and templates, rename them, and remove the old gaia-ci label.
  • Custom fitness categories. A category you added to wiki/decisions/Claude Integration Fitness.md no longer runs. Save it before you migrate; see Before you start.

  • Your own React performance drive spec. Rename {keep: true} to {isRunDirectoryKept: true}; the old name is ignored.

  • Codify declines. Candidates you declined in /gaia-harden come back once in /gaia-codify.

  • Templates. GAIA no longer ships a pull request template, issue templates, or FUNDING.yml. Your copies stay yours; deleting .github/ISSUE_TEMPLATE/ restores GitHub’s defaults.

  • Agent teams. GAIA no longer turns on Claude Code’s experimental agent-teams flag. Set it in your own user or local settings if you want it.

  • React Compiler is on by default. Run pnpm lint and all your tests, or ask Claude to. To turn it off, ask Claude to disable the React Compiler.

  • Vitest (opens in a new tab) 5 turns on clearMocks by default and fails an un-awaited .resolves or .rejects, so a few of your own tests may need small fixes.

  • Client environment allowlist. The browser gets only the environment variables on an allowlist, so server variables stay on the server. If a story of yours reads window.process.env, pass the value in as a story arg instead; if a test depends on a value from your .env, set it in your shell or give it a default in frontend/test/setup.ts.

  • Same-site redirects. resolveLocalRedirect and LocalRedirectSchema replace isLocalRedirect; the migration switches GAIA’s own actions.

  • Dropped packages and pages. react-router-dom is no longer used (pnpm remove react-router-dom). The example privacy and terms pages and @tailwindcss/typography no longer ship; keep the pages when the migration asks if you use them, otherwise run pnpm -C frontend remove @tailwindcss/typography. GAIA’s branded Header, Footer, and logo no longer ship either; the migration keeps your customized copies as your own files.

  • Removed i18n? If your project removed i18n, delete the LANGUAGES import and testIgnore from frontend/playwright.config.ts, or Playwright cannot load its config.

Commands you knew in 1.x have new names or are gone. See What changed in the commands.

1.x2.0.0
/gaia-audit/gaia-cleanse, narrowed to memory and auto-loaded files
/gaia-harden/gaia-codify
/setup-gaia-ci, /setup-cloned-gaia-project/setup-gaia
/gaia-handoff, /gaia-pickupRemoved. Resume from the run folder’s STATE.md or a continuation prompt. See Work lifecycle.
/gaia-debt list, why, fixRemoved. Run /gaia-debt with no argument to work the top of the backlog, or pass one or more issue numbers. A trailing worktree or branch picks where the work happens.
/gaia-wiki sync, consolidate, lint, --force/gaia-wiki takes no arguments and always runs all three.
/speckit.gaia.*Removed with spec-kit.
/gaia-serena-syncRemoved with Serena.
GAIA CIRemoved. Audits run locally.
code-review-audit agentThe Code Audit Team

There are no aliases. User-only commands (/gaia-init, /setup-gaia, /gaia-fitness, /gaia-forensics, /gaia-codify, /gaia-residue) no longer appear in Claude’s skill listing and Claude never starts them on its own. Type them as slash commands.