feat: community wave — 7 fixes, relink, sidebar Write, discoverability (v0.13.5.0) (#641) * test: add 16 failing tests for 6 community fixes Tests-first for all fixes in this PR wave: - #594 discoverability: gstack tag in descriptions, 120-char first line - #573 feature signals: ship/SKILL.md Step 4 detection - #510 context warnings: no preemptive warnings in generated files - #474 Safety Net: no find -delete in generated files - #467 telemetry: JSONL writes gated by _TEL conditional - #584 sidebar: Write in allowedTools, stderr capture - #578 relink: prefixed/flat symlinks, cleanup, error, config hook Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: replace find -delete with find -exec rm for Safety Net (#474) -delete is a non-POSIX extension that fails on Safety Net environments. -exec rm {} + is POSIX-compliant and works everywhere. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: gate local JSONL writes by telemetry setting (#467) When telemetry is off, nothing is written anywhere — not just remote, but local JSONL too. Clean trust contract: off means off everywhere. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: remove preemptive context warnings from plan-eng-review (#510) The system handles context compaction automatically. Preemptive warnings waste tokens and create false urgency. Skills should not warn about context limits — just describe the compression priority order. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add (gstack) tag to skill descriptions for discoverability (#594) Every SKILL.md.tmpl description now contains "gstack" on the last line, making skills findable in Claude Code's command palette. First-line hooks stay under 120 chars. Split ship description to fix wrapping. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: auto-relink skill symlinks on prefix config change (#578) New bin/gstack-relink creates prefixed (gstack-*) or flat symlinks based on skill_prefix config. gstack-config auto-triggers relink when skill_prefix changes. Setup guards against recursive calls with GSTACK_SETUP_RUNNING env var. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add feature signal detection to version bump heuristic (#573) /ship Step 4 now checks for feature signals (new routes, migrations, test+source pairs, feat/ branches) when deciding version bumps. PATCH requires no feature signals. MINOR asks the user if any signal is detected or 500+ lines changed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: sidebar Write tool, stderr capture, cross-platform URL opener (#584) Add Write to sidebar allowedTools (both sidebar-agent.ts and server.ts). Write doesn't expand attack surface beyond what Bash already provides. Replace empty stderr handler with buffer capture for better error diagnostics. New bin/gstack-open-url for cross-platform URL opening. Does NOT include Search Before Building intro flow (deferred). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: update sidebar-security test for Write tool addition The fallback allowedTools string now includes Write, matching the sidebar-agent.ts change from commit 68dc957. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: bump version and changelog (v0.13.5.0) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: prevent gstack-relink from double-prefixing gstack-upgrade gstack-relink now checks if a skill directory is already named gstack-* before prepending the prefix. Previously, setting skill_prefix=true would create gstack-gstack-upgrade, breaking the /gstack-upgrade command. Matches setup script behavior (setup:260) which already has this guard. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: add double-prefix fix to changelog Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: remove .factory/ from git tracking and add to .gitignore Generated Factory Droid skills are build output, same as .agents/. They should not be committed to the repo. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix: security audit remediation — 12 fixes, 20 tests (v0.13.1.0) (#595) * fix: remove auth token from /health, secure extension bootstrap (CRITICAL-02 + HIGH-03) - Remove token from /health response (was leaked to any localhost process) - Write .auth.json to extension dir for Manifest V3 bootstrap - sidebar-agent reads token from state file via BROWSE_STATE_FILE env var - Remove getToken handler from extension (token via health broadcast) - Extension loads token before first health poll to prevent race condition * fix: require auth on cookie-picker data routes (CRITICAL-01) - Add Bearer token auth gate on all /cookie-picker/* data/action routes - GET /cookie-picker HTML page stays unauthenticated (UI shell) - Token embedded in served HTML for picker's fetch calls - CORS preflight now allows Authorization header * fix: add state file TTL and plaintext cookie warning (HIGH-02) - Add savedAt timestamp to state save output - Warn on load if state file older than 7 days - Auto-delete stale state files (>7 days) on server startup - Warning about plaintext cookie storage in save message * fix: innerHTML XSS in extension content script and sidepanel (MEDIUM-01) - content.js: replace innerHTML with createElement/textContent for ref panel - sidepanel.js: escape entry.command with escapeHtml() in activity feed - Both found by security audit + Codex adversarial red team * fix: symlink bypass in validateReadPath (MEDIUM-02) - Always resolve to absolute path first (fixes relative path bypass) - Use realpathSync to follow symlinks before boundary check - Throw on non-ENOENT realpathSync failures (explicit over silent) - Resolve SAFE_DIRECTORIES through realpathSync (macOS /tmp → /private/tmp) - Resolve directory part for non-existent files (ENOENT with symlinked parent) * fix: freeze hook symlink bypass and prefix collision (MEDIUM-03) - Add POSIX-portable path resolution (cd + pwd -P, works on macOS) - Fix prefix collision: /project-evil no longer matches /project freeze dir - Use trailing slash in boundary check to require directory boundary * fix: shell script injection in gstack-config and telemetry (MEDIUM-04) - gstack-config: validate keys (alphanumeric+underscore only) - gstack-config: use grep -F (fixed string) instead of -E (regex) - gstack-config: escape sed special chars in values, drop newlines - gstack-telemetry-log: sanitize REPO_SLUG and BRANCH via json_safe() * test: 20 security tests for audit remediation - server-auth: verify token removed from /health, auth on /refs, /activity/* - cookie-picker: auth required on data routes, HTML page unauthenticated - path-validation: symlink bypass blocked, realpathSync failure throws - gstack-config: regex key rejected, sed special chars preserved - state-ttl: savedAt timestamp, 7-day TTL warning - telemetry: branch/repo with quotes don't corrupt JSON - adversarial: sidepanel escapes entry.command, freeze prefix collision * chore: bump version and changelog (v0.13.1.0) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: tone down changelog — defense in depth, not catastrophic bugs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
feat: skill prefix is now a persistent user choice (v0.12.11.0) (#571) * feat: make skill prefix a persistent, interactive user setting - Add --prefix flag alongside --no-prefix - Read/write skill_prefix from ~/.gstack/config.yaml (true/false) - Interactive prompt on first setup when no preference saved - Non-TTY environments default to flat names (no prefix) - Add cleanup_prefixed_claude_symlinks() for reverse direction - Fix gstack-config sed portability (mktemp+mv instead of BSD sed -i '') - Add SKILL_PREFIX to preamble output with namespace-aware instruction * test: add prefix config tests + README switching instructions 8 structural tests for persistent prefix setting: config reading, --prefix flag, config persistence, interactive prompt, TTY fallback, reverse cleanup, cleanup ordering, welcome. * chore: regenerate SKILL.md files with SKILL_PREFIX preamble * chore: bump version and changelog (v0.12.11.0) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: reframe changelog as feature, not mea culpa * docs: update CONTRIBUTING + CLAUDE.md for prefix-aware vendoring - CONTRIBUTING: vendoring now includes ./setup step for per-skill symlinks - CONTRIBUTING: prefix choice documented in contributor workflow + dev diagram - CONTRIBUTING: switching prefix mode section added - CLAUDE.md: vendored symlink awareness section covers prefix setting Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
feat: smart update check with auto-upgrade, snooze backoff, config CLI (v0.3.9) (#62) * feat: add bin/gstack-config CLI for reading/writing ~/.gstack/config.yaml Simple get/set/list interface for persistent gstack configuration. Used by update-check and upgrade skill for auto_upgrade and update_check settings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: smart update check with 12h cache, snooze backoff, config disable - Reduce cache TTL from 24h to 12h for faster update detection - Add exponential snooze backoff: 24h → 48h → 1 week (resets on new version) - Add update_check: false config option to disable checks entirely - Clear snooze file on just-upgraded - 14 new tests covering snooze levels, expiry, corruption, and config paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: upgrade skill with auto-upgrade, 4-option prompt, vendored sync - Auto-upgrade mode via config or GSTACK_AUTO_UPGRADE=1 env var - 4-option AskUserQuestion: upgrade once, always, not now, never - Step 4.5: sync local vendored copy after upgrading primary install - Snooze write with escalating backoff on "Not now" - Update preamble text in gen-skill-docs for new upgrade flow - Regenerate all SKILL.md files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: simplify upgrade instructions, move auto-upgrade to completed README now points to /gstack-upgrade instead of long paste commands. Auto-upgrade TODO moved to Completed section (v0.3.8). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: bump version and changelog (v0.3.9) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>