feat: add /setup-team-sync skill, auto-push transcript hooks in skills

- setup-team-sync/SKILL.md.tmpl: idempotent guided setup (create config,
  OAuth, verify connectivity, configure settings, summary)
- ship/retro/qa SKILL.md.tmpl: add push-transcript hook after existing
  push-ship/push-retro/push-qa hooks (silent, non-fatal)
- scripts/gen-skill-docs.ts: add setup-team-sync to template list
- Regenerated all SKILL.md files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-03-16 00:15:36 -05:00
parent a104471272
commit 3a57a3f59e
9 changed files with 276 additions and 0 deletions
+1
View File
@@ -271,6 +271,7 @@ $B snapshot -i -a -o "$REPORT_DIR/screenshots/issue-002.png"
}
QAEOF
~/.claude/skills/gstack/bin/gstack-sync push-qa .gstack/qa-reports/qa-sync.json 2>/dev/null && echo "Synced to team ✓" || true
~/.claude/skills/gstack/bin/gstack-sync push-transcript 2>/dev/null || true
```
Substitute actual values. Uses snake_case keys matching the Supabase schema.
+1
View File
@@ -245,6 +245,7 @@ $B snapshot -i -a -o "$REPORT_DIR/screenshots/issue-002.png"
}
QAEOF
~/.claude/skills/gstack/bin/gstack-sync push-qa .gstack/qa-reports/qa-sync.json 2>/dev/null && echo "Synced to team ✓" || true
~/.claude/skills/gstack/bin/gstack-sync push-transcript 2>/dev/null || true
```
Substitute actual values. Uses snake_case keys matching the Supabase schema.
+1
View File
@@ -358,6 +358,7 @@ Include backlog data in the JSON when TODOS.md exists:
After writing the JSON snapshot, sync to the team store (non-fatal, silent if not configured):
```bash
~/.claude/skills/gstack/bin/gstack-sync push-retro ".context/retros/${today}-${next}.json" 2>/dev/null && echo "Synced to team ✓" || true
~/.claude/skills/gstack/bin/gstack-sync push-transcript 2>/dev/null || true
```
### Step 14: Write the Narrative
+1
View File
@@ -349,6 +349,7 @@ Include backlog data in the JSON when TODOS.md exists:
After writing the JSON snapshot, sync to the team store (non-fatal, silent if not configured):
```bash
~/.claude/skills/gstack/bin/gstack-sync push-retro ".context/retros/${today}-${next}.json" 2>/dev/null && echo "Synced to team ✓" || true
~/.claude/skills/gstack/bin/gstack-sync push-transcript 2>/dev/null || true
```
### Step 14: Write the Narrative
+1
View File
@@ -183,6 +183,7 @@ function findTemplates(): string[] {
path.join(ROOT, 'plan-eng-review', 'SKILL.md.tmpl'),
path.join(ROOT, 'retro', 'SKILL.md.tmpl'),
path.join(ROOT, 'gstack-upgrade', 'SKILL.md.tmpl'),
path.join(ROOT, 'setup-team-sync', 'SKILL.md.tmpl'),
];
for (const p of candidates) {
if (fs.existsSync(p)) templates.push(p);
+139
View File
@@ -0,0 +1,139 @@
---
name: setup-team-sync
version: 1.0.0
description: |
Set up team sync with Supabase. Creates .gstack-sync.json if missing,
authenticates via OAuth, verifies connectivity, and configures sync settings.
Idempotent — safe to run multiple times. Use before first /ship, /retro, or /qa
to enable team data sharing.
allowed-tools:
- Bash
- Read
- Write
- AskUserQuestion
---
<!-- AUTO-GENERATED from SKILL.md.tmpl — do not edit directly -->
<!-- Regenerate: bun run gen:skill-docs -->
## Update Check (run first)
```bash
_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true)
[ -n "$_UPD" ] && echo "$_UPD" || true
```
If output shows `UPGRADE_AVAILABLE <old> <new>`: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED <from> <to>`: tell user "Running gstack v{to} (just updated!)" and continue.
# Setup Team Sync
Set up gstack team sync with Supabase. This skill is idempotent — safe to run anytime.
## Steps
### Step 1: Check project config
```bash
cat .gstack-sync.json 2>/dev/null || echo "NOT_FOUND"
```
- If the file exists and has `supabase_url`, `supabase_anon_key`, and `team_slug`: print "Team config found: {team_slug} at {supabase_url}" and skip to Step 3.
- If NOT_FOUND: proceed to Step 2.
### Step 2: Create .gstack-sync.json
Ask the user for three values using AskUserQuestion:
1. **Supabase URL** — e.g., `https://xyzcompany.supabase.co`
- Found in Supabase Dashboard → Project Settings → API → Project URL
2. **Anon Key** — the public `anon` key (NOT the `service_role` key)
- Found in Supabase Dashboard → Project Settings → API → Project API keys → `anon` `public`
- This key is safe to commit — it's public by design (like a Firebase API key). RLS enforces real access control.
3. **Team slug** — a short identifier like `my-team` or `yc-internal`
Then write `.gstack-sync.json`:
```bash
cat > .gstack-sync.json << 'ENDCONFIG'
{
"supabase_url": "USER_PROVIDED_URL",
"supabase_anon_key": "USER_PROVIDED_KEY",
"team_slug": "USER_PROVIDED_SLUG"
}
ENDCONFIG
echo "Created .gstack-sync.json"
```
Tell the user: "Commit this file to your repo so team members get it automatically. The anon key is public by Supabase design — RLS enforces real access control."
### Step 3: Check authentication
```bash
~/.claude/skills/gstack/bin/gstack-sync status 2>&1
```
Look at the output:
- If `Authenticated: yes` → skip to Step 5
- If `Authenticated: no` → proceed to Step 4
### Step 4: Authenticate
```bash
~/.claude/skills/gstack/bin/gstack-sync setup 2>&1
```
This opens a browser for OAuth. Tell the user to complete authentication in their browser. Wait for the output to show "Authenticated as ..." or an error.
If it fails with "Port 54321 is in use", ask the user to close the other process and retry.
### Step 5: Test connectivity
```bash
~/.claude/skills/gstack/bin/gstack-sync test 2>&1
```
This runs a full push + pull test. All 4 steps should show `ok`:
1. Config: ok
2. Auth: ok
3. Push: ok (with latency)
4. Pull: ok (with row count)
If Step 3 (Push) fails, tell the user: "The Supabase migrations may not be applied yet. Copy the SQL files from `supabase/migrations/` and run them in your Supabase SQL editor, in order (001 through 006)."
### Step 6: Configure sync settings
```bash
~/.claude/skills/gstack/bin/gstack-config get sync_enabled 2>/dev/null
~/.claude/skills/gstack/bin/gstack-config get sync_transcripts 2>/dev/null
```
Ask the user if they want to enable transcript sync (opt-in, shares Claude session data with the team):
- If they say yes:
```bash
~/.claude/skills/gstack/bin/gstack-config set sync_enabled true
~/.claude/skills/gstack/bin/gstack-config set sync_transcripts true
```
- If they say no (or just want basic sync without transcripts):
```bash
~/.claude/skills/gstack/bin/gstack-config set sync_enabled true
```
### Step 7: Summary
Print a summary:
```
Team sync setup complete!
Project config: .gstack-sync.json ✓ (commit to repo)
Authentication: {email} ✓
Connectivity: {supabase_url} ✓
Sync enabled: yes
Transcripts: {yes/no}
Next steps:
• Run /ship, /retro, or /qa — data syncs automatically
• View team data: gstack-sync show
• Check status anytime: gstack-sync status
```
+130
View File
@@ -0,0 +1,130 @@
---
name: setup-team-sync
version: 1.0.0
description: |
Set up team sync with Supabase. Creates .gstack-sync.json if missing,
authenticates via OAuth, verifies connectivity, and configures sync settings.
Idempotent — safe to run multiple times. Use before first /ship, /retro, or /qa
to enable team data sharing.
allowed-tools:
- Bash
- Read
- Write
- AskUserQuestion
---
{{UPDATE_CHECK}}
# Setup Team Sync
Set up gstack team sync with Supabase. This skill is idempotent — safe to run anytime.
## Steps
### Step 1: Check project config
```bash
cat .gstack-sync.json 2>/dev/null || echo "NOT_FOUND"
```
- If the file exists and has `supabase_url`, `supabase_anon_key`, and `team_slug`: print "Team config found: {team_slug} at {supabase_url}" and skip to Step 3.
- If NOT_FOUND: proceed to Step 2.
### Step 2: Create .gstack-sync.json
Ask the user for three values using AskUserQuestion:
1. **Supabase URL** — e.g., `https://xyzcompany.supabase.co`
- Found in Supabase Dashboard → Project Settings → API → Project URL
2. **Anon Key** — the public `anon` key (NOT the `service_role` key)
- Found in Supabase Dashboard → Project Settings → API → Project API keys → `anon` `public`
- This key is safe to commit — it's public by design (like a Firebase API key). RLS enforces real access control.
3. **Team slug** — a short identifier like `my-team` or `yc-internal`
Then write `.gstack-sync.json`:
```bash
cat > .gstack-sync.json << 'ENDCONFIG'
{
"supabase_url": "USER_PROVIDED_URL",
"supabase_anon_key": "USER_PROVIDED_KEY",
"team_slug": "USER_PROVIDED_SLUG"
}
ENDCONFIG
echo "Created .gstack-sync.json"
```
Tell the user: "Commit this file to your repo so team members get it automatically. The anon key is public by Supabase design — RLS enforces real access control."
### Step 3: Check authentication
```bash
~/.claude/skills/gstack/bin/gstack-sync status 2>&1
```
Look at the output:
- If `Authenticated: yes` → skip to Step 5
- If `Authenticated: no` → proceed to Step 4
### Step 4: Authenticate
```bash
~/.claude/skills/gstack/bin/gstack-sync setup 2>&1
```
This opens a browser for OAuth. Tell the user to complete authentication in their browser. Wait for the output to show "Authenticated as ..." or an error.
If it fails with "Port 54321 is in use", ask the user to close the other process and retry.
### Step 5: Test connectivity
```bash
~/.claude/skills/gstack/bin/gstack-sync test 2>&1
```
This runs a full push + pull test. All 4 steps should show `ok`:
1. Config: ok
2. Auth: ok
3. Push: ok (with latency)
4. Pull: ok (with row count)
If Step 3 (Push) fails, tell the user: "The Supabase migrations may not be applied yet. Copy the SQL files from `supabase/migrations/` and run them in your Supabase SQL editor, in order (001 through 006)."
### Step 6: Configure sync settings
```bash
~/.claude/skills/gstack/bin/gstack-config get sync_enabled 2>/dev/null
~/.claude/skills/gstack/bin/gstack-config get sync_transcripts 2>/dev/null
```
Ask the user if they want to enable transcript sync (opt-in, shares Claude session data with the team):
- If they say yes:
```bash
~/.claude/skills/gstack/bin/gstack-config set sync_enabled true
~/.claude/skills/gstack/bin/gstack-config set sync_transcripts true
```
- If they say no (or just want basic sync without transcripts):
```bash
~/.claude/skills/gstack/bin/gstack-config set sync_enabled true
```
### Step 7: Summary
Print a summary:
```
Team sync setup complete!
Project config: .gstack-sync.json ✓ (commit to repo)
Authentication: {email} ✓
Connectivity: {supabase_url} ✓
Sync enabled: yes
Transcripts: {yes/no}
Next steps:
• Run /ship, /retro, or /qa — data syncs automatically
• View team data: gstack-sync show
• Check status anytime: gstack-sync status
```
+1
View File
@@ -431,6 +431,7 @@ Substitute actual values from the preceding steps. Use `0` for Greptile fields i
2. Push (non-fatal):
```bash
~/.claude/skills/gstack/bin/gstack-sync push-ship /tmp/gstack-ship-log.json 2>/dev/null && echo "Synced to team ✓" || true
~/.claude/skills/gstack/bin/gstack-sync push-transcript 2>/dev/null || true
```
---
+1
View File
@@ -422,6 +422,7 @@ Substitute actual values from the preceding steps. Use `0` for Greptile fields i
2. Push (non-fatal):
```bash
~/.claude/skills/gstack/bin/gstack-sync push-ship /tmp/gstack-ship-log.json 2>/dev/null && echo "Synced to team ✓" || true
~/.claude/skills/gstack/bin/gstack-sync push-transcript 2>/dev/null || true
```
---