Brings in 55 commits from main (v0.12.x–v0.13.5.0): Factory Droid compat,
prompt injection defense, user sovereignty, security audit, design binary,
skill namespacing, modular resolvers, Chrome sidebar, and more.
Conflict resolution:
- .agents/ SKILL.md files: deleted (main moved to .factory/)
- 8 .tmpl templates: accepted main (new features: CDP mode, design tools,
global retro, parallelization, distribution checks, plan audits)
- scripts/gen-skill-docs.ts: accepted main's modular resolver refactor
- test/helpers/session-runner.ts: accepted main + layered back CostEntry
tracking from team branch
- Generated SKILL.md files: regenerated via bun run gen:skill-docs
- Updated tests to match main's gstack-slug output (2 lines, no PROJECTS_DIR)
and review log mechanism (gstack-review-log, not $BRANCH.jsonl)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: drop all anon RLS policies + revoke view access + add cache table
Migration 002 locks down the Supabase telemetry backend:
- Drops all SELECT, INSERT, UPDATE policies for the anon role
- Explicitly revokes SELECT on crash_clusters and skill_sequences views
- Drops stale error_message/failed_step columns (exist live but not in migration)
- Creates community_pulse_cache table for server-side aggregation caching
* feat: extend community-pulse with full dashboard data + server-side cache
community-pulse now returns top skills, crash clusters, version distribution,
and weekly active count in a single aggregated response. Results are cached
in the community_pulse_cache table (1-hour TTL) to prevent DoS via repeated
expensive queries.
* fix: route all telemetry through edge functions, not PostgREST
- gstack-telemetry-sync: POST to /functions/v1/telemetry-ingest instead of
/rest/v1/telemetry_events. Removes sed field-renaming (edge function expects
raw JSONL names). Parses inserted count — holds cursor if zero inserted.
- gstack-update-check: POST to /functions/v1/update-check.
- gstack-community-dashboard: calls community-pulse edge function instead of
direct PostgREST queries.
- config.sh: removes GSTACK_TELEMETRY_ENDPOINT, fixes misleading comment.
* test: RLS smoke test + telemetry field name verification
- verify-rls.sh: 9-check smoke test (5 reads + 3 inserts + 1 update)
verifying anon key is fully locked out after migration.
- telemetry.test.ts: verifies JSONL uses raw field names (v, ts, sessions)
that the edge function expects, not Postgres column names.
- README.md: fixes privacy claim to match actual RLS policy.
* chore: bump version and changelog (v0.11.16.0)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: pre-landing review fixes — JSONB field order, version filter, RLS verification
- Dashboard JSON parsing: use per-object grep instead of field-order-dependent
regex (JSONB doesn't preserve key order)
- Version distribution: filter to skill_run events only (was counting all types)
- verify-rls.sh: only 401/403 count as PASS (not empty 200 or 5xx); add
Authorization header to test as anon role properly
- Remove dead empty loop in community-pulse
* chore: untrack browse/dist binaries — 116MB of arm64-only Mach-O
These compiled Bun binaries only work on arm64 macOS, and ./setup
already rebuilds from source for every platform. They were tracked
despite .gitignore due to being committed before the ignore rule.
Untracking stops them from appearing as modified in every diff.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: tone down changelog — security hardening, not incident report
* fix: keep INSERT policies for old client compat, preserve extra columns
- Keep anon INSERT policies so pre-v0.11.16 clients can still sync
telemetry via PostgREST while new clients use edge functions
- Add error_message/failed_step columns to migration (reconcile repo
with live schema) instead of dropping them
- Security fix still lands: SELECT and UPDATE policies are dropped
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: sync package.json version with VERSION file (0.11.16.0)
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add gstack-telemetry-log and gstack-analytics scripts
Local telemetry infrastructure for gstack usage tracking.
gstack-telemetry-log appends JSONL events with skill name, duration,
outcome, session ID, and platform info. Supports off/anonymous/community
privacy tiers. gstack-analytics renders a personal usage dashboard
from local data.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add telemetry preamble injection + opt-in prompt + epilogue
Extends generatePreamble() with telemetry start block (config read,
timer, session ID, .pending marker), opt-in prompt (gated by
.telemetry-prompted), and epilogue instructions for Claude to log
events after skill completion. Adds 5 telemetry tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: regenerate all SKILL.md files with telemetry blocks
Automated regeneration from gen-skill-docs.ts changes. All skills
now include telemetry start block, opt-in prompt, and epilogue.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add Supabase schema, edge functions, and SQL views
Telemetry backend infrastructure: telemetry_events table with RLS
(insert-only), installations table for retention tracking,
update_checks for install pings. Edge functions for update-check
(version + ping), telemetry-ingest (batch insert), and
community-pulse (weekly active count). SQL views for crash
clustering and skill co-occurrence sequences.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add telemetry-sync, community-dashboard, and integration tests
gstack-telemetry-sync: fire-and-forget JSONL → Supabase sync with
privacy tier field stripping, batch limits, and cursor tracking.
gstack-community-dashboard: CLI tool querying Supabase for skill
popularity, crash clusters, and version distribution.
19 integration tests covering all telemetry scripts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: session-specific .pending markers + crash_clusters view fix
Addresses Codex review findings:
- .pending race condition: use .pending-$SESSION_ID instead of
shared .pending file to prevent concurrent session interference
- crash_clusters view: add total_occurrences and anonymous_occurrences
columns since anonymous tier has no installation_id
- Added test: own session pending marker is not finalized
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: dual-attempt update check with Supabase install ping
Fires a parallel background curl to Supabase during the slow-path
version fetch. Logs upgrade_prompted event only on fresh fetches
(not cached replays) to avoid overcounting. GitHub remains the
primary version source — Supabase ping is fire-and-forget.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: integrate telemetry usage stats into /retro output
Retro now reads ~/.gstack/analytics/skill-usage.jsonl and includes
gstack usage metrics (skill run counts, top skills, success rate)
in the weekly retrospective output.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: move 'Skill usage telemetry' to Completed in TODOS.md
Implemented in this branch: local JSONL logging, opt-in prompt,
privacy tiers, Supabase backend, community dashboard, /retro
integration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: wire Supabase credentials and expose tables via Data API
Add supabase/config.sh with project URL and publishable key (safe to
commit — RLS restricts to INSERT only). Update telemetry-sync,
community-dashboard, and update-check to source the config and
include proper auth headers for the Supabase REST API.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: add SELECT RLS policies to migration for community dashboard reads
All telemetry data is anonymous (no PII), so public reads via the
publishable key are safe. Needed for the community dashboard to
query skill popularity, crash clusters, and version distribution.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: bump version and changelog (v0.8.6)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: analytics backward-compatible with old JSONL format
Handle old-format events (no event_type field) alongside new format.
Skip hook_fire events. Fix grep -c whitespace issues and unbound
variable errors.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: map JSONL field names to Postgres columns in telemetry-sync
Local JSONL uses short names (v, ts, sessions) but the Supabase
table expects full names (schema_version, event_timestamp,
concurrent_sessions). Add sed mapping during field stripping.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address Codex adversarial findings — cursor, opt-out, queries
- Sync cursor now advances on HTTP 2xx (not grep for "inserted")
- Update-check respects telemetry opt-out before pinging Supabase
- Dashboard queries use correct view column names (total_occurrences)
- Sync strips old-format "repo" field to prevent privacy leak
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs: add Privacy & Telemetry section to README
Transparent disclosure of what telemetry collects, what it never sends,
how to opt out, and a link to the schema so users can verify.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
P2 from Codex review: weekly digest selected nonexistent 'email'
column from ship_logs, causing a silent Supabase error that dropped
all ship activity from the digest. Now selects user_id, version,
branch, pr_url which all exist in the schema.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Creates public 'screenshots' bucket with RLS policies that restrict
uploads to team members (path: {team_id}/{slug}/{branch}/{filename}).
Public read access enables embedding URLs in PR bodies without auth.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add cross-reference comments between dashboard-queries.ts computeLeaderboard()
and dashboard/ui.ts renderLeaderboard() so maintainers know to update both
- Add security note in setup-team-dashboard about service-role-key visibility
in pg_cron job table
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
From CEO plan review:
- Edge functions: early guard on missing env vars instead of non-null assert crash
- cli-team: wire isTokenExpired check (was imported but unused)
- Migration 007: CHECK constraint on team slug (a-z0-9 hyphens, 2-50 chars)
- Dashboard: streak badges on leaderboard, repo slug in who's-online,
contextual empty states that teach, 60s refresh (was 30s)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New `gstack team` CLI with create, members, set subcommands.
Migration adds team_settings (admin-only), alert_cooldowns (edge-fn
dedup), and create_team() SECURITY DEFINER RPC for atomic team +
first member creation. 9 tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add session intelligence pipeline for team transcript sync:
- lib/transcript-sync.ts: parse history.jsonl, enrich with Claude session
file data (tools_used, full turn count), sync marker management,
10-concurrent push with 5-concurrent Haiku summarization
- lib/llm-summarize.ts: raw fetch() to Anthropic Messages API (no SDK dep),
retry-after on 429, exponential backoff on 5xx, SHA-based eval-cache
- lib/sync.ts: pushTranscript() and pullTranscripts() following existing patterns
- 006_transcript_sync.sql: unique index on (team_id, session_id) for
idempotent upsert, RLS changed from admin-only to team-wide read
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 005_sync_heartbeats.sql migration for connectivity testing
- eval:trend --team flag pulls team eval data (graceful fallback)
- docs/TEAM_SYNC_SETUP.md step-by-step setup guide
- Design doc status updated to Phase 2 complete
- 10 new tests for sync show formatting functions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- lib/cli-eval.ts: routes to list/compare/summary/push/cost/cache/watch
subcommands. Ports logic from 4 separate scripts into unified entry.
Adds ANSI color for TTY (respects NO_COLOR), --limit flag for list.
- bin/gstack-eval: bash wrapper matching bin/gstack-sync pattern
- package.json: eval:* scripts now point to lib/cli-eval.ts
- supabase/migrations/004_eval_costs.sql: per-model cost tracking + RLS
- docs/eval-result-format.md: public format spec for any language
- test/lib-eval-cli.test.ts: integration tests (spawn CLI subprocess)
including 3 push failure modes (file-not-found, invalid schema,
sync unavailable)
215 tests passing across 13 files.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 001_teams.sql: teams + team_members + RLS
- 002_eval_runs.sql: eval results with universal format, indexes, upsert key
- 003_data_tables.sql: retro, QA, ship, greptile, transcripts + RLS
All tables use RLS: team members read/insert, admins delete.
Transcript table has tighter policy (admin-only read).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>