Commit Graph

2 Commits

Author SHA1 Message Date
jkrperson f6299c4d67 feat(installer): clearer wizard labels for install vs team mode
"Add to this project (team mode)" implied team mode replaces the global
install when it actually stacks on top of it. Relabels the wizard so the
relationship is explicit:

- "Install gstack on this machine" (was "Install globally (on this machine)")
- "Enable team mode for this repo" (was "Add to this project (team mode)")
  with hint: "global install + commits team-sync config to this repo so
  teammates auto-update"

Pre-select intro note now says upfront that there are two install modes
and that team mode is a superset of the machine install.

Required/optional tier hints now say what each actually does (PreToolUse
hook block vs CLAUDE.md nudge) instead of vague "block sessions" /
"nudge teammates".

No behavior changes — labels and hint text only. 77 tests still pass.
2026-04-25 02:53:59 +08:00
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