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

Brings in 48 commits from main (v0.15.7–v0.15.16): deterministic slugs,
TabSession refactor, pair-agent tunnel fix, content security layers,
community security wave, team-friendly install, interactive snapshots.

Conflict resolution:
- .gitignore: merged both sides (kept .factory/ + added .kiro/.opencode/
  .slate/.cursor/.openclaw/ from main)
- open-gstack-browser/SKILL.md: accepted main (renamed from .factory/)
- setup-team-sync/SKILL.md: regenerated via gen:skill-docs
- test/fixtures/golden/*: updated golden baselines for ship SKILL.md
- codex-ship-SKILL.md: accepted main (renamed from .factory/)
- package.json version: synced to VERSION (0.15.16.0)
- bin/gstack-uninstall: check settings file exists before claiming
  SessionStart hook removal (fixes false positive on clean systems)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-04-07 20:47:07 -10:00
258 changed files with 55174 additions and 2692 deletions

View File

@@ -43,9 +43,15 @@ Deno.serve(async (req) => {
return new Response(`Batch too large (max ${MAX_BATCH_SIZE})`, { status: 400 });
}
// Use the anon key, not the service role key.
// The service role key bypasses Row Level Security (RLS) and grants full
// unrestricted database access — wildly over-privileged for a public
// telemetry endpoint that only needs INSERT on two tables.
// The anon key + properly configured RLS INSERT policies is correct.
// See: https://supabase.com/docs/guides/database/postgres/row-level-security
const supabase = createClient(
Deno.env.get("SUPABASE_URL") ?? "",
Deno.env.get("SUPABASE_SERVICE_ROLE_KEY") ?? ""
Deno.env.get("SUPABASE_ANON_KEY") ?? ""
);
// Validate and transform events