gstack/installer
jkrperson 714e968d69 feat(installer): npx @garrytan/gstack — interactive installer CLI
Adds installer/ — a TypeScript CLI that wraps the existing ./setup bash
script behind a zero-friction `npx` entry point. Replaces the paste-prompt
install flow with an interactive wizard while preserving ./setup as the
source of truth for host registration and symlinks.

Commands:
  install | init | uninstall (--project) | upgrade | doctor
  status | list | enable <skill> | disable <skill>

No-args launches a @clack/prompts wizard that auto-detects git repos +
installed hosts (claude, codex, factory, opencode, kiro), collects
multi-select host + prefix + CLAUDE.md choices, and routes to install or
team-mode init.

The CLI:
- clones garrytan/gstack into ~/.claude/skills/gstack
- shells out to ./setup once per selected host (or --host auto)
- for init, runs ./setup --team + bin/gstack-team-init <required|optional>,
  stages .claude/ + CLAUDE.md
- inserts/updates a fenced <!-- gstack:begin --> block in CLAUDE.md listing
  every discovered skill
- uninstall walks ~/.claude, ~/.codex, ~/.factory, ~/.config/opencode,
  ~/.kiro skills dirs and removes symlinks/dirs pointing into the gstack
  install (canonicalized with fs.realpathSync to handle macOS /var vs
  /private/var), then removes the CLAUDE.md block and scrubs gstack
  PreToolUse hooks from project .claude/settings.json
- preserves ~/.gstack/ session state across uninstalls

Testing:
- 77 tests, bun:test runner, 3s runtime
- Unit: claude-md (11), skills (12), project-config (11), cleanup (12 + a
  /var realpath regression test), paths (9)
- Integration: spawns dist/cli.js against fake HOME fixtures — verifies
  exit codes, enable/disable round-trip + name normalization, uninstall
  scrubs settings.json preserving non-gstack hooks and top-level keys,
  EPIPE handling under `gstack list | head`, wizard intro without TTY

End-to-end dry-run completed via `npm link` and `npm pack` against a real
clone + real build (clone -> browse binary -> Playwright Chromium -> 40
skills linked -> CLAUDE.md written -> doctor green -> uninstall leaves 0
zombies).

Live demo published under @jkresabal/gstack for testing:
  npx @jkresabal/gstack

Upstream publish (after this PR): cd installer && npm publish --access public

Philosophy: thin wrapper. ~2.3K LOC, 16KB packed, two runtime deps
(@clack/prompts + picocolors), Node 18+. No logic duplicated from ./setup.
If ./setup learns a new flag, the CLI surfaces it with one line.
2026-04-25 02:37:27 +08:00
..
src feat(installer): npx @garrytan/gstack — interactive installer CLI 2026-04-25 02:37:27 +08:00
test feat(installer): npx @garrytan/gstack — interactive installer CLI 2026-04-25 02:37:27 +08:00
.gitignore feat(installer): npx @garrytan/gstack — interactive installer CLI 2026-04-25 02:37:27 +08:00
.npmignore feat(installer): npx @garrytan/gstack — interactive installer CLI 2026-04-25 02:37:27 +08:00
PUBLISHING.md feat(installer): npx @garrytan/gstack — interactive installer CLI 2026-04-25 02:37:27 +08:00
README.md feat(installer): npx @garrytan/gstack — interactive installer CLI 2026-04-25 02:37:27 +08:00
package-lock.json feat(installer): npx @garrytan/gstack — interactive installer CLI 2026-04-25 02:37:27 +08:00
package.json feat(installer): npx @garrytan/gstack — interactive installer CLI 2026-04-25 02:37:27 +08:00
tsconfig.json feat(installer): npx @garrytan/gstack — interactive installer CLI 2026-04-25 02:37:27 +08:00
tsconfig.test.json feat(installer): npx @garrytan/gstack — interactive installer CLI 2026-04-25 02:37:27 +08:00

README.md

@garrytan/gstack — installer CLI

Interactive installer for gstack, Garry Tan's Claude Code skill pack and workflow tooling.

Usage

# Zero-friction: interactive wizard
npx @garrytan/gstack

# Scripted: verb-based subcommands
npx @garrytan/gstack install --host claude,codex
npx @garrytan/gstack init --tier required
npx @garrytan/gstack upgrade
npx @garrytan/gstack uninstall --project --yes
npx @garrytan/gstack doctor
npx @garrytan/gstack status
npx @garrytan/gstack list
npx @garrytan/gstack disable /qa
npx @garrytan/gstack enable /qa

Works with npx, bunx, and pnpm dlx.

What it does

install — clones gstack into ~/.claude/skills/gstack, builds the browse/design binaries via bun, registers with your chosen AI hosts (Claude Code, Codex, Factory Droid, OpenCode, Kiro), and inserts a <!-- gstack:begin --> / <!-- gstack:end --> block into ~/.claude/CLAUDE.md documenting the available skills.

init — runs inside a git repo. Installs globally if needed, enables team mode (the SessionStart auto-update hook), runs gstack-team-init <tier> to bootstrap the repo, and stages/commits the changes. Teammates get gstack automatically on their next session.

uninstall — removes the install and walks every host's skills directory (~/.claude/skills, ~/.codex/skills, ~/.factory/skills, ~/.config/opencode/skills, ~/.kiro/skills) removing any symlink or directory whose SKILL.md points into the gstack install. Cleans the CLAUDE.md block and scrubs the PreToolUse hook from project settings.json. ~/.gstack/ (session state) is preserved.

upgradegit fetch + hard reset to origin/main in ~/.claude/skills/gstack, then re-runs ./setup --host auto to rebuild and re-link.

doctor — checks git, bun, install state, binary freshness, skill count, and per-host registration. Exit code 1 if any check fails.

status — one-screen summary: version, install path, team mode, auto-upgrade, skill prefix mode, per-host registration, per-project disabled-skills list.

list — enumerates installed skills with descriptions parsed from each SKILL.md frontmatter.

enable <skill> / disable <skill> — toggle skills per-project via .claude/settings.local.json's disabledSkills array. Names can be qa, /qa, or gstack-qa — all normalize to the same entry.

Requirements

  • Node.js 18+ (for the installer itself)
  • bun 1.0+ (for building gstack binaries)
  • git
  • bash (Windows: Git Bash or WSL)

Philosophy

The installer is a thin wrapper around gstack's existing ./setup bash script — no logic is duplicated. This keeps the installer small, auditable, and guaranteed to stay in sync with upstream. If setup learns a new flag, the installer picks it up by exposing a new option.

Development

cd installer
npm install
npm run build        # compile TS to dist/
npm start -- --help  # run the built CLI

# Watch mode
npm run dev

# Smoke test locally
npm link
gstack --help

To test without publishing:

# From anywhere, use the local checkout:
npx /absolute/path/to/gstack/installer install

License

MIT — same as gstack.