Merge branch 'main' into garrytan/team-supabase-store

Resolved conflicts across 23 files. Key merge decisions:
- Adopted main's TemplateContext type in gen-skill-docs.ts
- Adopted main's new features (trigger phrases, codex integration,
  analytics, proactive config, review chaining)
- Replaced gstack-review-log/gstack-review-read helpers with inline
  approach using $PROJECTS_DIR/$SLUG/reviews/$BRANCH.jsonl paths
- Added "commit":"COMMIT" field to all review log entries (from main)
- Kept our $PROJECTS_DIR/$SLUG path reorganization throughout
- Added Codex E2E test from main + our E2E isolation cleanup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-03-19 17:16:08 -07:00
84 changed files with 8122 additions and 1234 deletions
+54 -18
View File
@@ -5,6 +5,8 @@ description: |
Weekly engineering retrospective. Analyzes commit history, work patterns,
and code quality metrics with persistent history and trend tracking.
Team-aware: breaks down per-person contributions with praise and growth areas.
Use when asked to "weekly retro", "what did we ship", or "engineering retrospective".
Proactively suggest at the end of a work week or sprint.
allowed-tools:
- Bash
- Read
@@ -25,12 +27,19 @@ touch ~/.gstack/sessions/"$PPID"
_SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ')
find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true
_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true)
_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true")
_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
echo "BRANCH: $_BRANCH"
echo "PROACTIVE: $_PROACTIVE"
_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
echo "LAKE_INTRO: $_LAKE_SEEN"
mkdir -p ~/.gstack/analytics
echo '{"skill":"retro","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true
```
If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke
them when the user explicitly asks. The user opted out of proactive suggestions.
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.
If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle.
@@ -119,6 +128,31 @@ Hey gstack team — ran into this while using /{skill-name}:
Slug: lowercase, hyphens, max 60 chars (e.g. `browse-js-no-await`). Skip if file already exists. Max 3 reports per session. File inline and continue — don't stop the workflow. Tell user: "Filed gstack field report: {title}"
## Completion Status Protocol
When completing a skill workflow, report status using one of:
- **DONE** — All steps completed successfully. Evidence provided for each claim.
- **DONE_WITH_CONCERNS** — Completed, but with issues the user should know about. List each concern.
- **BLOCKED** — Cannot proceed. State what is blocking and what was tried.
- **NEEDS_CONTEXT** — Missing information required to continue. State exactly what you need.
### Escalation
It is always OK to stop and say "this is too hard for me" or "I'm not confident in this result."
Bad work is worse than no work. You will not be penalized for escalating.
- If you have attempted a task 3 times without success, STOP and escalate.
- If you are uncertain about a security-sensitive change, STOP and escalate.
- If the scope of work exceeds what you can verify, STOP and escalate.
Escalation format:
```
STATUS: BLOCKED | NEEDS_CONTEXT
REASON: [1-2 sentences]
ATTEMPTED: [what you tried]
RECOMMENDATION: [what the user should do next]
```
## Detect default branch
Before gathering data, detect the repo's default branch name:
@@ -146,7 +180,9 @@ When the user types `/retro`, run this skill.
## Instructions
Parse the argument to determine the time window. Default to 7 days if no argument given. Use `--since="N days ago"`, `--since="N hours ago"`, or `--since="N weeks ago"` (for `w` units) for git log queries. All times should be reported in **Pacific time** (use `TZ=America/Los_Angeles` when converting timestamps).
Parse the argument to determine the time window. Default to 7 days if no argument given. All times should be reported in the user's **local timezone** (use the system default — do NOT set `TZ`).
**Midnight-aligned windows:** For day (`d`) and week (`w`) units, compute an absolute start date at local midnight, not a relative string. For example, if today is 2026-03-18 and the window is 7 days: the start date is 2026-03-11. Use `--since="2026-03-11T00:00:00"` for git log queries — the explicit `T00:00:00` suffix ensures git starts from midnight. Without it, git uses the current wall-clock time (e.g., `--since="2026-03-11"` at 11pm means 11pm, not midnight). For week units, multiply by 7 to get days (e.g., `2w` = 14 days back). For hour (`h`) units, use `--since="N hours ago"` since midnight alignment does not apply to sub-day windows.
**Argument validation:** If the argument doesn't match a number followed by `d`, `h`, or `w`, the word `compare`, or `compare` followed by a number and `d`/`h`/`w`, show this usage and stop:
```
@@ -183,8 +219,7 @@ git log origin/<default> --since="<window>" --format="%H|%aN|%ae|%ai|%s" --short
git log origin/<default> --since="<window>" --format="COMMIT:%H|%aN" --numstat
# 3. Commit timestamps for session detection and hourly distribution (with author)
# Use TZ=America/Los_Angeles for Pacific time conversion
TZ=America/Los_Angeles git log origin/<default> --since="<window>" --format="%at|%aN|%ai|%s" | sort -n
git log origin/<default> --since="<window>" --format="%at|%aN|%ai|%s" | sort -n
# 4. Files most frequently changed (hotspot analysis)
git log origin/<default> --since="<window>" --format="" --name-only | grep -v '^$' | sort | uniq -c | sort -rn
@@ -262,9 +297,17 @@ Include in the metrics table:
If TODOS.md doesn't exist, skip the Backlog Health row.
**Skill Usage (if analytics exist):** Read `~/.gstack/analytics/skill-usage.jsonl` if it exists. Filter entries within the retro time window by `ts` field. Separate skill activations (no `event` field) from hook fires (`event: "hook_fire"`). Aggregate by skill name. Present as:
```
| Skill Usage | /ship(12) /qa(8) /review(5) · 3 safety hook fires |
```
If the JSONL file doesn't exist or has no entries in the window, skip the Skill Usage row.
### Step 3: Commit Time Distribution
Show hourly histogram in Pacific time using bar chart:
Show hourly histogram in local time using bar chart:
```
Hour Commits ████████████████
@@ -368,11 +411,11 @@ If the time window is 14 days or more, split into weekly buckets and show trends
Count consecutive days with at least 1 commit to origin/<default>, going back from today. Track both team streak and personal streak:
```bash
# Team streak: all unique commit dates (Pacific time) — no hard cutoff
TZ=America/Los_Angeles git log origin/<default> --format="%ad" --date=format:"%Y-%m-%d" | sort -u
# Team streak: all unique commit dates (local time) — no hard cutoff
git log origin/<default> --format="%ad" --date=format:"%Y-%m-%d" | sort -u
# Personal streak: only the current user's commits
TZ=America/Los_Angeles git log origin/<default> --author="<user_name>" --format="%ad" --date=format:"%Y-%m-%d" | sort -u
git log origin/<default> --author="<user_name>" --format="%ad" --date=format:"%Y-%m-%d" | sort -u
```
Count backward from today — how many consecutive days have at least one commit? This queries the full history so streaks of any length are reported accurately. Display both:
@@ -413,7 +456,7 @@ mkdir -p $PROJECTS_DIR/$SLUG/retros
Determine the next sequence number for today (substitute the actual date for `$(date +%Y-%m-%d)`):
```bash
# Count existing retros for today to get next sequence number
today=$(TZ=America/Los_Angeles date +%Y-%m-%d)
today=$(date +%Y-%m-%d)
existing=$(ls $PROJECTS_DIR/$SLUG/retros/${today}-*.json 2>/dev/null | wc -l | tr -d ' ')
next=$((existing + 1))
# Save as $PROJECTS_DIR/$SLUG/retros/${today}-${next}.json
@@ -482,13 +525,6 @@ Include backlog data in the JSON when TODOS.md exists:
}
```
After writing the JSON snapshot, register in manifest and sync:
```bash
~/.claude/skills/gstack/bin/gstack-manifest-append retro "retros/${today}-${next}.json" retro "$BRANCH"
~/.claude/skills/gstack/bin/gstack-sync push-retro "$PROJECTS_DIR/$SLUG/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
Structure the output as:
@@ -594,8 +630,8 @@ Small, practical, realistic. Each must be something that takes <5 minutes to ado
When the user runs `/retro compare` (or `/retro compare 14d`):
1. Compute metrics for the current window (default 7d) using `--since="7 days ago"`
2. Compute metrics for the immediately prior same-length window using both `--since` and `--until` to avoid overlap (e.g., `--since="14 days ago" --until="7 days ago"` for a 7d window)
1. Compute metrics for the current window (default 7d) using the midnight-aligned start date (same logic as the main retro — e.g., if today is 2026-03-18 and window is 7d, use `--since="2026-03-11T00:00:00"`)
2. Compute metrics for the immediately prior same-length window using both `--since` and `--until` with midnight-aligned dates to avoid overlap (e.g., for a 7d window starting 2026-03-11: prior window is `--since="2026-03-04T00:00:00" --until="2026-03-11T00:00:00"`)
3. Show a side-by-side comparison table with deltas and arrows
4. Write a brief narrative highlighting the biggest improvements and regressions
5. Save only the current-window snapshot to `$PROJECTS_DIR/$SLUG/retros/` (same as a normal retro run); do **not** persist the prior-window metrics.
@@ -617,7 +653,7 @@ When the user runs `/retro compare` (or `/retro compare 14d`):
- ALL narrative output goes directly to the user in the conversation. The ONLY file written is the `$PROJECTS_DIR/$SLUG/retros/` JSON snapshot.
- Use `origin/<default>` for all git queries (not local main which may be stale)
- Convert all timestamps to Pacific time for display (use `TZ=America/Los_Angeles`)
- Display all timestamps in the user's local timezone (do not override `TZ`)
- If the window has zero commits, say so and suggest a different window
- Round LOC/hour to nearest 50
- Treat merge commits as PR boundaries
+22 -18
View File
@@ -5,6 +5,8 @@ description: |
Weekly engineering retrospective. Analyzes commit history, work patterns,
and code quality metrics with persistent history and trend tracking.
Team-aware: breaks down per-person contributions with praise and growth areas.
Use when asked to "weekly retro", "what did we ship", or "engineering retrospective".
Proactively suggest at the end of a work week or sprint.
allowed-tools:
- Bash
- Read
@@ -42,7 +44,9 @@ When the user types `/retro`, run this skill.
## Instructions
Parse the argument to determine the time window. Default to 7 days if no argument given. Use `--since="N days ago"`, `--since="N hours ago"`, or `--since="N weeks ago"` (for `w` units) for git log queries. All times should be reported in **Pacific time** (use `TZ=America/Los_Angeles` when converting timestamps).
Parse the argument to determine the time window. Default to 7 days if no argument given. All times should be reported in the user's **local timezone** (use the system default — do NOT set `TZ`).
**Midnight-aligned windows:** For day (`d`) and week (`w`) units, compute an absolute start date at local midnight, not a relative string. For example, if today is 2026-03-18 and the window is 7 days: the start date is 2026-03-11. Use `--since="2026-03-11T00:00:00"` for git log queries — the explicit `T00:00:00` suffix ensures git starts from midnight. Without it, git uses the current wall-clock time (e.g., `--since="2026-03-11"` at 11pm means 11pm, not midnight). For week units, multiply by 7 to get days (e.g., `2w` = 14 days back). For hour (`h`) units, use `--since="N hours ago"` since midnight alignment does not apply to sub-day windows.
**Argument validation:** If the argument doesn't match a number followed by `d`, `h`, or `w`, the word `compare`, or `compare` followed by a number and `d`/`h`/`w`, show this usage and stop:
```
@@ -79,8 +83,7 @@ git log origin/<default> --since="<window>" --format="%H|%aN|%ae|%ai|%s" --short
git log origin/<default> --since="<window>" --format="COMMIT:%H|%aN" --numstat
# 3. Commit timestamps for session detection and hourly distribution (with author)
# Use TZ=America/Los_Angeles for Pacific time conversion
TZ=America/Los_Angeles git log origin/<default> --since="<window>" --format="%at|%aN|%ai|%s" | sort -n
git log origin/<default> --since="<window>" --format="%at|%aN|%ai|%s" | sort -n
# 4. Files most frequently changed (hotspot analysis)
git log origin/<default> --since="<window>" --format="" --name-only | grep -v '^$' | sort | uniq -c | sort -rn
@@ -158,9 +161,17 @@ Include in the metrics table:
If TODOS.md doesn't exist, skip the Backlog Health row.
**Skill Usage (if analytics exist):** Read `~/.gstack/analytics/skill-usage.jsonl` if it exists. Filter entries within the retro time window by `ts` field. Separate skill activations (no `event` field) from hook fires (`event: "hook_fire"`). Aggregate by skill name. Present as:
```
| Skill Usage | /ship(12) /qa(8) /review(5) · 3 safety hook fires |
```
If the JSONL file doesn't exist or has no entries in the window, skip the Skill Usage row.
### Step 3: Commit Time Distribution
Show hourly histogram in Pacific time using bar chart:
Show hourly histogram in local time using bar chart:
```
Hour Commits ████████████████
@@ -264,11 +275,11 @@ If the time window is 14 days or more, split into weekly buckets and show trends
Count consecutive days with at least 1 commit to origin/<default>, going back from today. Track both team streak and personal streak:
```bash
# Team streak: all unique commit dates (Pacific time) — no hard cutoff
TZ=America/Los_Angeles git log origin/<default> --format="%ad" --date=format:"%Y-%m-%d" | sort -u
# Team streak: all unique commit dates (local time) — no hard cutoff
git log origin/<default> --format="%ad" --date=format:"%Y-%m-%d" | sort -u
# Personal streak: only the current user's commits
TZ=America/Los_Angeles git log origin/<default> --author="<user_name>" --format="%ad" --date=format:"%Y-%m-%d" | sort -u
git log origin/<default> --author="<user_name>" --format="%ad" --date=format:"%Y-%m-%d" | sort -u
```
Count backward from today — how many consecutive days have at least one commit? This queries the full history so streaks of any length are reported accurately. Display both:
@@ -309,7 +320,7 @@ mkdir -p $PROJECTS_DIR/$SLUG/retros
Determine the next sequence number for today (substitute the actual date for `$(date +%Y-%m-%d)`):
```bash
# Count existing retros for today to get next sequence number
today=$(TZ=America/Los_Angeles date +%Y-%m-%d)
today=$(date +%Y-%m-%d)
existing=$(ls $PROJECTS_DIR/$SLUG/retros/${today}-*.json 2>/dev/null | wc -l | tr -d ' ')
next=$((existing + 1))
# Save as $PROJECTS_DIR/$SLUG/retros/${today}-${next}.json
@@ -378,13 +389,6 @@ Include backlog data in the JSON when TODOS.md exists:
}
```
After writing the JSON snapshot, register in manifest and sync:
```bash
~/.claude/skills/gstack/bin/gstack-manifest-append retro "retros/${today}-${next}.json" retro "$BRANCH"
~/.claude/skills/gstack/bin/gstack-sync push-retro "$PROJECTS_DIR/$SLUG/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
Structure the output as:
@@ -490,8 +494,8 @@ Small, practical, realistic. Each must be something that takes <5 minutes to ado
When the user runs `/retro compare` (or `/retro compare 14d`):
1. Compute metrics for the current window (default 7d) using `--since="7 days ago"`
2. Compute metrics for the immediately prior same-length window using both `--since` and `--until` to avoid overlap (e.g., `--since="14 days ago" --until="7 days ago"` for a 7d window)
1. Compute metrics for the current window (default 7d) using the midnight-aligned start date (same logic as the main retro — e.g., if today is 2026-03-18 and window is 7d, use `--since="2026-03-11T00:00:00"`)
2. Compute metrics for the immediately prior same-length window using both `--since` and `--until` with midnight-aligned dates to avoid overlap (e.g., for a 7d window starting 2026-03-11: prior window is `--since="2026-03-04T00:00:00" --until="2026-03-11T00:00:00"`)
3. Show a side-by-side comparison table with deltas and arrows
4. Write a brief narrative highlighting the biggest improvements and regressions
5. Save only the current-window snapshot to `$PROJECTS_DIR/$SLUG/retros/` (same as a normal retro run); do **not** persist the prior-window metrics.
@@ -513,7 +517,7 @@ When the user runs `/retro compare` (or `/retro compare 14d`):
- ALL narrative output goes directly to the user in the conversation. The ONLY file written is the `$PROJECTS_DIR/$SLUG/retros/` JSON snapshot.
- Use `origin/<default>` for all git queries (not local main which may be stale)
- Convert all timestamps to Pacific time for display (use `TZ=America/Los_Angeles`)
- Display all timestamps in the user's local timezone (do not override `TZ`)
- If the window has zero commits, say so and suggest a different window
- Round LOC/hour to nearest 50
- Treat merge commits as PR boundaries