mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-26 22:51:47 +02:00
feat: first-run activation — project-aware scaffold, router front door, onboarding nudges
Adds the activation system that drives a new install toward a concrete first move: - bin/gstack-first-task-detect: local-git+filesystem repo classifier emitting one validated enum bucket (greenfield/code_<lang>/branch_ahead/dirty_default/clean_default), portable timeouts, fail-safe empty output. - generate-first-run-guidance.ts: unified preamble section — first-run project-aware scaffold + returning-session plan->review->ship tip, gated on a persistent .activated marker and never run in headless. Detection wired lazily in generate-preamble-bash.ts. - SKILL.md.tmpl: top-level gstack skill is now a pure router (browse body removed; it lives in /browse), routing any request and sending browser/QA work to /browse. - setup: first-move nudge on first install. office-hours: closing handoff that launches the next review via the Skill tool. - telemetry-ingest: accept onboarding/first_task_scaffold_shown/handoff/route event types.
This commit is contained in:
+23
-242
@@ -1,26 +1,40 @@
|
||||
---
|
||||
name: gstack
|
||||
preamble-tier: 1
|
||||
version: 1.1.0
|
||||
version: 1.2.0
|
||||
description: |
|
||||
Fast headless browser for QA testing and site dogfooding. Navigate pages, interact with
|
||||
elements, verify state, diff before/after, take annotated screenshots, test responsive
|
||||
layouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or
|
||||
test a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)
|
||||
Router for the gstack skill suite. Sends any gstack request to the right skill
|
||||
(planning, review, QA, shipping, debugging, docs, security, design). For browser/QA
|
||||
and dogfooding it points you at /browse. Use when you invoke gstack without a specific
|
||||
skill, or ask "which gstack skill fits this?". (gstack)
|
||||
allowed-tools:
|
||||
- Bash
|
||||
- Read
|
||||
- AskUserQuestion
|
||||
triggers:
|
||||
- browse this page
|
||||
- take a screenshot
|
||||
- navigate to url
|
||||
- inspect the page
|
||||
- gstack
|
||||
- which gstack skill
|
||||
- route this with gstack
|
||||
|
||||
---
|
||||
|
||||
{{PREAMBLE}}
|
||||
|
||||
## Route first
|
||||
|
||||
This is the gstack router. Its one job is to send the request to the right skill.
|
||||
|
||||
1. If the request is about a browser, QA, dogfooding, screenshots, or inspecting a page
|
||||
(open a site, test a deploy, take a screenshot, check a flow visually) → invoke `/browse`.
|
||||
2. Otherwise, route by the rules below. If nothing matches, answer directly.
|
||||
|
||||
Best-effort, record which way you routed (never block on it). Set `ROUTE_OUTCOME` to
|
||||
`browse` (sent to /browse), `routed` (sent to another skill), or `direct` (answered
|
||||
directly, no skill matched):
|
||||
```bash
|
||||
~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type route --skill gstack --outcome ROUTE_OUTCOME --session-id "$_SESSION_ID" 2>/dev/null || true
|
||||
```
|
||||
|
||||
If `PROACTIVE` is `false`: do NOT proactively invoke or suggest other gstack skills during
|
||||
this session. Only run skills the user explicitly invokes. This preference persists across
|
||||
sessions via `gstack-config`.
|
||||
@@ -75,236 +89,3 @@ directly as usual.
|
||||
|
||||
If the user opts out of suggestions, run `gstack-config set proactive false`.
|
||||
If they opt back in, run `gstack-config set proactive true`.
|
||||
|
||||
# gstack browse: QA Testing & Dogfooding
|
||||
|
||||
Persistent headless Chromium. First call auto-starts (~3s), then ~100-200ms per command.
|
||||
Auto-shuts down after 30 min idle. State persists between calls (cookies, tabs, sessions).
|
||||
|
||||
{{BROWSE_SETUP}}
|
||||
|
||||
## IMPORTANT
|
||||
|
||||
- Use the compiled binary via Bash: `$B <command>`
|
||||
- NEVER use `mcp__claude-in-chrome__*` tools. They are slow and unreliable.
|
||||
- Browser persists between calls — cookies, login sessions, and tabs carry over.
|
||||
- Dialogs (alert/confirm/prompt) are auto-accepted by default — no browser lockup.
|
||||
- **Show screenshots:** After `$B screenshot`, `$B snapshot -a -o`, or `$B responsive`, always use the Read tool on the output PNG(s) so the user can see them. Without this, screenshots are invisible.
|
||||
|
||||
## QA Workflows
|
||||
|
||||
> **Credential safety:** Use environment variables for test credentials.
|
||||
> Set them before running: `export TEST_EMAIL="..." TEST_PASSWORD="..."`
|
||||
|
||||
### Test a user flow (login, signup, checkout, etc.)
|
||||
|
||||
```bash
|
||||
# 1. Go to the page
|
||||
$B goto https://app.example.com/login
|
||||
|
||||
# 2. See what's interactive
|
||||
$B snapshot -i
|
||||
|
||||
# 3. Fill the form using refs
|
||||
$B fill @e3 "$TEST_EMAIL"
|
||||
$B fill @e4 "$TEST_PASSWORD"
|
||||
$B click @e5
|
||||
|
||||
# 4. Verify it worked
|
||||
$B snapshot -D # diff shows what changed after clicking
|
||||
$B is visible ".dashboard" # assert the dashboard appeared
|
||||
$B screenshot /tmp/after-login.png
|
||||
```
|
||||
|
||||
### Verify a deployment / check prod
|
||||
|
||||
```bash
|
||||
$B goto https://yourapp.com
|
||||
$B text # read the page — does it load?
|
||||
$B console # any JS errors?
|
||||
$B network # any failed requests?
|
||||
$B js "document.title" # correct title?
|
||||
$B is visible ".hero-section" # key elements present?
|
||||
$B screenshot /tmp/prod-check.png
|
||||
```
|
||||
|
||||
### Dogfood a feature end-to-end
|
||||
|
||||
```bash
|
||||
# Navigate to the feature
|
||||
$B goto https://app.example.com/new-feature
|
||||
|
||||
# Take annotated screenshot — shows every interactive element with labels
|
||||
$B snapshot -i -a -o /tmp/feature-annotated.png
|
||||
|
||||
# Find ALL clickable things (including divs with cursor:pointer)
|
||||
$B snapshot -C
|
||||
|
||||
# Walk through the flow
|
||||
$B snapshot -i # baseline
|
||||
$B click @e3 # interact
|
||||
$B snapshot -D # what changed? (unified diff)
|
||||
|
||||
# Check element states
|
||||
$B is visible ".success-toast"
|
||||
$B is enabled "#next-step-btn"
|
||||
$B is checked "#agree-checkbox"
|
||||
|
||||
# Check console for errors after interactions
|
||||
$B console
|
||||
```
|
||||
|
||||
### Test responsive layouts
|
||||
|
||||
```bash
|
||||
# Quick: 3 screenshots at mobile/tablet/desktop
|
||||
$B goto https://yourapp.com
|
||||
$B responsive /tmp/layout
|
||||
|
||||
# Manual: specific viewport
|
||||
$B viewport 375x812 # iPhone
|
||||
$B screenshot /tmp/mobile.png
|
||||
$B viewport 1440x900 # Desktop
|
||||
$B screenshot /tmp/desktop.png
|
||||
|
||||
# Element screenshot (crop to specific element)
|
||||
$B screenshot "#hero-banner" /tmp/hero.png
|
||||
$B snapshot -i
|
||||
$B screenshot @e3 /tmp/button.png
|
||||
|
||||
# Region crop
|
||||
$B screenshot --clip 0,0,800,600 /tmp/above-fold.png
|
||||
|
||||
# Viewport only (no scroll)
|
||||
$B screenshot --viewport /tmp/viewport.png
|
||||
```
|
||||
|
||||
### Test file upload
|
||||
|
||||
```bash
|
||||
$B goto https://app.example.com/upload
|
||||
$B snapshot -i
|
||||
$B upload @e3 /path/to/test-file.pdf
|
||||
$B is visible ".upload-success"
|
||||
$B screenshot /tmp/upload-result.png
|
||||
```
|
||||
|
||||
### Test forms with validation
|
||||
|
||||
```bash
|
||||
$B goto https://app.example.com/form
|
||||
$B snapshot -i
|
||||
|
||||
# Submit empty — check validation errors appear
|
||||
$B click @e10 # submit button
|
||||
$B snapshot -D # diff shows error messages appeared
|
||||
$B is visible ".error-message"
|
||||
|
||||
# Fill and resubmit
|
||||
$B fill @e3 "valid input"
|
||||
$B click @e10
|
||||
$B snapshot -D # diff shows errors gone, success state
|
||||
```
|
||||
|
||||
### Test dialogs (delete confirmations, prompts)
|
||||
|
||||
```bash
|
||||
# Set up dialog handling BEFORE triggering
|
||||
$B dialog-accept # will auto-accept next alert/confirm
|
||||
$B click "#delete-button" # triggers confirmation dialog
|
||||
$B dialog # see what dialog appeared
|
||||
$B snapshot -D # verify the item was deleted
|
||||
|
||||
# For prompts that need input
|
||||
$B dialog-accept "my answer" # accept with text
|
||||
$B click "#rename-button" # triggers prompt
|
||||
```
|
||||
|
||||
### Test authenticated pages (import real browser cookies)
|
||||
|
||||
```bash
|
||||
# Import cookies from your real browser (opens interactive picker)
|
||||
$B cookie-import-browser
|
||||
|
||||
# Or import a specific domain directly
|
||||
$B cookie-import-browser comet --domain .github.com
|
||||
|
||||
# Now test authenticated pages
|
||||
$B goto https://github.com/settings/profile
|
||||
$B snapshot -i
|
||||
$B screenshot /tmp/github-profile.png
|
||||
```
|
||||
|
||||
> **Cookie safety:** `cookie-import-browser` transfers real session data.
|
||||
> Only import cookies from browsers you control.
|
||||
|
||||
### Compare two pages / environments
|
||||
|
||||
```bash
|
||||
$B diff https://staging.app.com https://prod.app.com
|
||||
```
|
||||
|
||||
### Multi-step chain (efficient for long flows)
|
||||
|
||||
```bash
|
||||
echo '[
|
||||
["goto","https://app.example.com"],
|
||||
["snapshot","-i"],
|
||||
["fill","@e3","$TEST_EMAIL"],
|
||||
["fill","@e4","$TEST_PASSWORD"],
|
||||
["click","@e5"],
|
||||
["snapshot","-D"],
|
||||
["screenshot","/tmp/result.png"]
|
||||
]' | $B chain
|
||||
```
|
||||
|
||||
## Quick Assertion Patterns
|
||||
|
||||
```bash
|
||||
# Element exists and is visible
|
||||
$B is visible ".modal"
|
||||
|
||||
# Button is enabled/disabled
|
||||
$B is enabled "#submit-btn"
|
||||
$B is disabled "#submit-btn"
|
||||
|
||||
# Checkbox state
|
||||
$B is checked "#agree"
|
||||
|
||||
# Input is editable
|
||||
$B is editable "#name-field"
|
||||
|
||||
# Element has focus
|
||||
$B is focused "#search-input"
|
||||
|
||||
# Page contains text
|
||||
$B js "document.body.textContent.includes('Success')"
|
||||
|
||||
# Element count
|
||||
$B js "document.querySelectorAll('.list-item').length"
|
||||
|
||||
# Specific attribute value
|
||||
$B attrs "#logo" # returns all attributes as JSON
|
||||
|
||||
# CSS property
|
||||
$B css ".button" "background-color"
|
||||
```
|
||||
|
||||
## Snapshot System
|
||||
|
||||
{{SNAPSHOT_FLAGS}}
|
||||
|
||||
## Command Reference
|
||||
|
||||
{{COMMAND_REFERENCE}}
|
||||
|
||||
## Tips
|
||||
|
||||
1. **Navigate once, query many times.** `goto` loads the page; then `text`, `js`, `screenshot` all hit the loaded page instantly.
|
||||
2. **Use `snapshot -i` first.** See all interactive elements, then click/fill by ref. No CSS selector guessing.
|
||||
3. **Use `snapshot -D` to verify.** Baseline → action → diff. See exactly what changed.
|
||||
4. **Use `is` for assertions.** `is visible .modal` is faster and more reliable than parsing page text.
|
||||
5. **Use `snapshot -a` for evidence.** Annotated screenshots are great for bug reports.
|
||||
6. **Use `snapshot -C` for tricky UIs.** Finds clickable divs that the accessibility tree misses.
|
||||
7. **Check `console` after actions.** Catch JS errors that don't surface visually.
|
||||
8. **Use `chain` for long flows.** Single command, no per-step CLI overhead.
|
||||
|
||||
Reference in New Issue
Block a user