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.