hosts wave: 25 community PRs consolidated + live-verified — 5 new hosts, codex/installer/hook fixes (/grok skill held pending live receipt)#1
Merged
Conversation
When `hosts/claude.ts` has `generation.skipSkills: ['claude']` (the existing config — the /claude outside-voice skill is intentionally for non-Claude hosts), `bun run gen:skill-docs` correctly skips generating `claude/SKILL.md`. But `scripts/skill-check.ts` Templates section still flags it as `❌ generated file missing!` and the script exits 1. Fix: mirror the same `skipSkills` filter that `gen-skill-docs.ts` already uses (see `scripts/gen-skill-docs.ts:510-516`). Read the primary host's skipSkills once, then in the Templates loop, if the output file is missing AND the skill dir is in skipSkills, log it as `- skipped per <host> host config` and skip the error flag instead of marking it missing. Impact: `bun run skill:check` now exits 0 for any host config that uses `skipSkills`. No behavior change when skipSkills is empty (default for most hosts) or when the skipped skill's output is in fact missing for some other reason. Test plan: configure `skipSkills: ['claude']` (default `hosts/claude.ts`), run `bun run gen:skill-docs`, confirm `claude/SKILL.md` is not generated, then `bun run skill:check` — before the patch, exit=1 with `❌ claude/SKILL.md — generated file missing!`; after the patch, exit=0 with `- claude/SKILL.md — skipped per claude host config`.
…rence-hook 'defer' is a real permissionDecision value in Claude Code, but it means 'pause this tool call and hand control back' and is honored in print/non-interactive mode (interactive mode warns and ignores it). The hook emitted it as its 'no opinion' outcome, which made every AskUserQuestion call get deferred in non-interactive sessions (e.g. the Claude Code desktop app): the question UI never rendered and AUQ appeared completely broken after gstack setup registered the hook. The neutral outcome for a PreToolUse hook is a silent exit 0 — so defer() now emits nothing, or only additionalContext (without any permissionDecision) when there is plan-tune memory context to inject. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Cherry-picked from community PR garrytan#2146. [wave adaptation: the new non-AUQ desktop test asserted the 'defer' permissionDecision that PR garrytan#2165 (applied just before this) removed; updated to toBeUndefined() to match the pass-through contract.] Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…Q regression test Salvaged from community PR garrytan#1816 (its hook fix was superseded by garrytan#2165, but its spike-doc correction and empty-stdout regression test are unique): the spike still documented "defer" as a valid permissionDecision value; the real contract is allow/deny/ask only, with pass-through expressed as no permissionDecision at all. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Generate one Node CommonJS enforcement hook, fail closed when project context or the global install cannot be verified, and cover cmd and PowerShell execution paths. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Catch project hook resolution and load failures in the cross-shell Node launcher, returning a sanitized structured denial instead of a module-loader error. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
GeminiAdapter was reading message.text and result.usage, so current CLI content/stats events produced empty $0 success rows. Accept content with an assistant role guard, stats token fallbacks, init model, and treat empty exit-0 output as an error (garrytan#2159). Co-authored-by: Cursor <cursoragent@cursor.com>
Exercise resultFromGeminiStream against current stream-json fixtures (including empty-success hardening). Recognize GEMINI_API_KEY and map IneligibleTierError to auth — personal OAuth free-tier is no longer supported by gemini CLI. Co-authored-by: Cursor <cursoragent@cursor.com>
Pass --skip-trust so temp/untrusted workdirs work in headless benchmarks (mirrors Codex --skip-git-repo-check). Revert VERSION, CHANGELOG, and package.json bumps — leave release bookkeeping to maintainers / /ship, matching community PR practice. Co-authored-by: Cursor <cursoragent@cursor.com>
The setup script's non-Claude host paths (Kiro, Codex, Factory, OpenCode) use selective file linking rather than symlinking the entire repo root. This missed supabase/config.sh, causing gstack-telemetry-sync to silently exit (SUPABASE_URL empty) for all users on these hosts who opted into telemetry. Fixes garrytan#2215
Cherry-picked from community PR garrytan#2198. bin/*.ts helpers import ../lib/*, which hard-fails on copy-mode installs where the runtime root has bin/ but no lib/. [wave adaptation: dropped the mkdir -p "$opencode_gstack/lib" hunk — pre-creating lib/ as a real directory makes ln -snf nest a lib/lib symlink inside it instead of replacing it; the link block alone is correct, matching the existing bin/ pattern.] Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…the .agents sidecar Same root cause as the opencode fix (community PR garrytan#2198): every runtime root links bin/ whose *.ts helpers import ../lib/*, so copy-mode (Windows) installs crash with module-not-found. Apply the identical lib/ link block to all four remaining bin-linking sites. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Hermes Agent (GitHub Copilot GPT-5.4) <agent@nousresearch.com>
Cherry-picked from community PR garrytan#1160: resolvers emitted broken $HOME$GSTACK_* doubled-home fallback paths for env-var hosts, and the codex runtime root/sidecar never linked design/dist. [wave adaptations: converted the PR's new design/dist link from raw ln -snf to _link_or_copy (setup-windows-fallback invariant); merged the sidecar asset list with the wave's lib/ addition.] Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codex uses AGENTS.md as its project instruction file, but the codex host config's pathRewrites omit the CLAUDE.md -> AGENTS.md rewrite that hosts/hermes.ts already has. Generated Codex-host skills therefore still reference CLAUDE.md: the routing preamble checks `[ -f CLAUDE.md ]`, and the routing-injection step can create and `git commit` a CLAUDE.md in a Codex repo (auto-applied in spawned/headless runs). Mirrors the hermes.ts pattern. Refs garrytan#1163. Complements garrytan#1162 (Codex model/tool rewrites, which did not include this filename rewrite). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Issue garrytan#1066 — Codex skills that call AskUserQuestion silently fail in Default mode because Codex strips AskUserQuestion from the tool schema and its equivalent (request_user_input) only works in Plan mode. The HostConfig interface already supports toolRewrites (gbrain, openclaw, factory, hermes all use it). codex.ts was missing it. Adding { 'AskUserQuestion': 'request_user_input' } to codex.ts so that when gen-skill-docs.ts applies rewrites at generation time, any prompt text referencing AskUserQuestion gets replaced with Codex's equivalent. Note: this only handles the text rewrite. A full fix would also need the Plan-mode gate in the preamble (Option 4 in garrytan#1066), but that requires codex-side feature flag changes outside gstack's control. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…regression test Follow-ups to the Codex path move (community PR garrytan#2123) and the AskUserQuestion tool rewrite (community PR garrytan#1101): - gstack-upgrade/migrations/v1.61.0.0.sh removes stale gstack-owned entries from the legacy ~/.codex/skills location (idempotent, non-fatal, touches only gstack/gstack-* entries) - pair-agent tmpl still pointed --local codex credentials at the legacy path - static test pins that generated Codex ship uses request_user_input and never leaks AskUserQuestion Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Cherry-picked from community PR garrytan#1888 (source hunks only; generated docs and the ship golden are regenerated at the end of the wave). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Closes garrytan#1358. Adds the missing bash side of Cursor host support that hosts/cursor.ts and the README already advertised. Mirrors the opencode wiring pattern end-to-end so 'setup --host cursor' actually installs skills to ~/.cursor/skills/gstack-*/ as the README documents. Touches 4 sites in setup: - Lines 87, 100, 135: cursor added to --host expected/accept/error list - Lines 198-218: INSTALL_CURSOR variable + auto-detect ('command -v cursor') + dispatch branch - Phase 1e: gen .cursor/ skill docs via 'bun run gen:skill-docs --host cursor' - New create_cursor_runtime_root + link_cursor_skill_dirs helpers (opencode-shaped) - Phase 6d: install for Cursor (mkdir + create runtime root + link skill dirs) Plus CURSOR_SKILLS / CURSOR_GSTACK path vars at the top of setup. test/gen-skill-docs.test.ts: 389 pass / 0 fail. Two new cases pin the cursor path vars and the install section structure; existing --host arg-list assertions updated to include cursor. Reported by @hhlqsmy.
Slate had the same documented-but-rejected gap as Cursor (README lists it, hosts/slate.ts is registered, setup errored on --host slate). Mechanical clone of the Cursor wiring from community PR garrytan#1526 — hosts/slate.ts runtimeRoot is identical to hosts/cursor.ts, only the paths differ. All link sites route through _link_or_copy. Static tests mirror the cursor assertions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pi implements the Agent Skills spec, so gstack skills work with one config file (no generator, setup, or tooling changes). Skills install to ~/.pi/agent/skills/gstack-*/ for global and .pi/skills/ for project-local, both discovered by pi at startup. - hosts/pi.ts: minimal config mirroring opencode pattern - hosts/index.ts: register pi in ALL_HOST_CONFIGS + re-exports - .gitignore: skip .pi/ (generated skill docs) - README.md: add Pi row to host table + dedicated install section
…ll path Adaptations for the Pi host pick (community PR garrytan#1918): - test/host-config.test.ts host count 10 -> 11 - descriptionLimitBehavior 'warn' (ported from community PR garrytan#1497's config): pi has no committed output, so a future >1024-char skill description would hard-fail generation with no early signal - ./setup --host pi now prints hermes-style integration instructions instead of erroring 'Unknown --host value'; README's Pi section shows the real two-command install instead of a setup path that didn't exist Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adaptations for the Antigravity pick (community PR garrytan#2134): - test/host-config.test.ts host count 11 -> 12 - ./setup --host agy (alias: antigravity) prints hermes-style integration instructions instead of erroring; PR garrytan#2134 shipped no setup wiring, so its README row promised a setup path that didn't exist - README row states the real install method Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds hosts/vibe.ts following the slate.ts minimal template. Vibe uses the SKILL.md standard natively with skills at ~/.vibe/skills/. - globalRoot / localSkillRoot: .vibe/skills/gstack - frontmatter: allowlist mode, keeps name + description - pathRewrites: ~/.claude/skills/gstack → ~/.vibe/skills/gstack - suppressedResolvers: same as other CLI agents (can't self-invoke) - boundaryInstruction: prevents Vibe from reading Claude skill files - cliAliases: ['mistral-vibe'] - skipSkills: ['codex'] (Claude-specific wrapper) Registers in hosts/index.ts, adds row to README Other AI Agents table, adds .vibe/ to .gitignore, bumps host count in host-config test to 11. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adaptations for the Mistral Vibe pick (community PR garrytan#1640): the PR's README row promised --host vibe but shipped no setup wiring. ./setup --host vibe now prints integration instructions; README row states the real install method. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add Qoder (通义灵码) as a new gstack host with official .lingma/skills/ paths. Changes: - hosts/qoder.ts: new host config with .lingma/ paths - hosts/index.ts: register qoder in ALL_HOST_CONFIGS - setup: add qoder install variables, auto-detect, create_qoder_runtime_root(), link_qoder_skill_dirs(), and install block - .gitignore: add .lingma/ - README.md: add qoder to host table, update agent count to 11, add qoder cleanup command - docs/ADDING_A_HOST.md: add qoder to host list - test/host-config.test.ts: update count to 11, add qoder assertion - test/gen-skill-docs.test.ts: update setup host validation string
The Codex install-path move (community PR garrytan#2123) makes pair-agent's --local codex docs point at ~/.agents/skills; the Claude-isolation test already excluded pair-agent for ~/.codex/ but not for .agents/skills. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ime hosts
The Agent->host-tool rewrite only keyed on the exact literal 'use the Agent
tool', which never appears in generated content. Real phrasings ('using the
Agent tool', 'via the Agent tool', 'Use the Agent tool', and bare 'Agent tool')
slipped through, so the host's subagent tool never rendered and the Claude-ism
'Agent tool' leaked into generated docs (16x in hermes alone, delegate_task 0x).
Add article-first + bare-sweep rules to hermes (delegate_task), gbrain and
openclaw (sessions_spawn), and factory. Factory uses the plain noun 'delegation'
since its rewrites are prose, not tool names, which avoids echoing the
surrounding 'subagent' wording; a possessive-first rule handles "Claude Code's
Agent tool". Regenerated all four trees: 0 'Agent tool' leaks. Update the
factory ship golden baseline to match.
From community PR garrytan#1935 (commit b436148), test hunk only: its 8.8K lines of golden fixture content were generated from April 2026 templates and are regenerated fresh at the end of this wave instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
document-generate/SKILL.md, document-release/sections/release-body.md, pair-agent/SKILL.md, and ship/SKILL.md re-rendered from sources changed earlier in this wave (Opus 4.8 trailer, ~/.agents/skills codex path). The autoplan resolver adaptations (codex_reviews master-switch port, keychain-safe Claude probe) are folded into the preceding cherry-pick commit as conflict resolution. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Squashed cherry-pick of community PR garrytan#2248 (8 commits), resolved against this wave's tree: - hosts/index.ts, setup host lists, INSTALL_* detection, and the host-count test unioned with the wave's pi/agy/vibe/qoder additions (registry now 15 hosts) - kept garrytan#2248's exported resolveDistBinary and dropped garrytan#1160's private duplicate resolveBinaryPath in scripts/resolvers/{browse,design}.ts — both fixed the same $HOME$GSTACK_* doubled-home bug identically - generated files and golden fixtures refresh in the wave's final regen commit Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The D7 static invariant (test/setup-windows-fallback.test.ts) flags any non-comment 'ln -' line in setup, including copy-paste hints inside echo strings. Reworded the pi/agy/vibe integration hints to prose; the exact command lives in README's Pi section, which the tripwire does not scan. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Cherry-picked from community PR garrytan#2241 with the VERSION, CHANGELOG.md, and package.json version hunks dropped (the wave PR versions itself at ship time). Generated docs and goldens refresh in the wave's final regen commit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…agents Cross-pick integration: community PR garrytan#2241 added 'grok' to skipSkills on every host that existed on its base, but this wave's five new hosts (pi, agy, vibe, qoder, grok-build) still skipped only 'codex'. The /grok skill is a Claude-host outside-voice wrapper, same class as /codex — external hosts must not generate it (grok-build especially: self-invocation). README agent count updated to the final registry size. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Final wave regen: goldens re-rendered from the consolidated sources (claude trailer 4.8, codex ~/.agents paths + AGENTS.md/request_user_input rewrites, /grok skill rows, Agent-tool rewrite coverage). Creates the hermes/gbrain/openclaw goldens that community PR garrytan#1935's new regression tests read. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codex CLI review of the full wave diff surfaced 7 findings; all real, all fixed: - [P1] setup-host test asserted the pre-grok-build case string — the one deterministic test failure in the wave (bun's aggregate exit code masked it; caught by fail-line audit + codex) - [P1] cursor/slate/qoder installs now self-generate host output before building the runtime root (fresh installs with NEEDS_BUILD=1 skipped the gen step, leaving a runtime root without its root SKILL.md) - [P1] cursor/slate/qoder/grok runtime roots link lib/ next to bin/ (bin/*.ts import ../lib/*; Windows copy-mode installs crashed) - [P1] /grok review <focus> writes user text through a quoted heredoc — previously interpolated into double-quoted shell source, letting $(...) and backticks execute - [P2] BSD mktemp templates ended in a suffix after the X run, which on macOS returns the SAME literal path every call (verified empirically) — grok skill (8 sites) and autoplan resolver (3 sites) fixed - [P2] grok runtime promotion now moves the old tree aside and rolls back on a failed mv instead of stranding users with no runtime Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Regression found by the pristine-main fail-line audit: community PR garrytan#2221 rewords the Gemini NOT READY hint to start with 'Export ...' (sentence case), which the benchmark-cli remediation-hint regex only matched in lowercase. The hint is present and concrete; the regex is now case-insensitive. 15/15 on main and on this branch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…skills Live verification against Qoder's official docs and the published @qoder-ai/qodercli package (v1.0.44) shows community PR garrytan#2116's two core assumptions were wrong: the CLI binary is qodercli (not qoder), and skills are discovered from ~/.qoder/skills + .qoder/skills (docs never mention .lingma — that is the legacy Tongyi Lingma plugin dir). Config, setup wiring, gitignore, README, and docs updated; verified against the installed qodercli 1.0.44. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tatus:error
Found by a LIVE gemini-cli 0.50.0 run (real GEMINI_API_KEY, real
stream-json output): when the API call fails, the CLI emits
result { status: 'error', error: { message } }, which the parser
degraded to the generic 'empty output from gemini CLI (exit 0)'.
The real message (here a billing 429) is what a user needs to see.
Unit test uses the verbatim captured stream as its fixture.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Reverts community PR garrytan#2241 (the /grok second-opinion skill) from this push: every other wave item has a live receipt, but the skill's core value — a successful xAI review round-trip — could not be exercised (account returned 402 Grok Build balance exhausted; auth, flag surface, and graceful degradation ARE verified). The grok-build HOST stays: its install and skill discovery are proven with the real grok CLI (grok inspect lists all 54 skills). The skill returns in a follow-up once one live review is receipted. Generated docs and golden fixtures regenerated without the skill. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What it does
Consolidates the 25 best community "hosts" PRs (from 50 reviewed) into one verified wave: gstack now supports 15 AI coding agents (adds Pi, Antigravity, Mistral Vibe, Qoder, Grok Build), the installer accepts the hosts the README always promised (Cursor, Slate), the Codex integration matches Codex's current skill spec, the AskUserQuestion hook no longer silently swallows questions, and team-mode "required" actually blocks.
How it works
One commit per problem group, cherry-picked with each community author preserved; wave adaptations (conflict ports, a migration script, integration fixes) in separate labeled commits; generated docs and golden fixtures regenerated once from merged sources. VERSION/CHANGELOG untouched — ship picks the number.
What was broken
Installer rejected documented hosts; Codex skills pointed at paths/tools that don't exist there; an invalid hook value silently killed AskUserQuestion in Conductor/Desktop/non-interactive sessions; team-mode enforcement was a no-op; telemetry died on non-Claude installs; the benchmark misread current Gemini output; generated docs leaked Claude-only phrasing. Full problem-group table with every dropped duplicate and reason:
~/.gstack-dev/pr-triage/wave-reports/hosts.md(local report).How it was fixed and how it was verified
Every claim here was tested against the real products, installed on a real machine — not inferred from docs:
gstack-autoplan, gstack-browse, gstack-canary(live LLM call)browse, investigate, shipgstack-upgrade, gstack-autoplan, gstack-benchmarkgstack-autoplan, gstack-benchmark, gstack-browsefrom the new~/.agents/skillspathopencode run→ namedgstack-ship, gstack-investigate, gstack-qagrok inspectlists all 54 gstack skills (no API call); xAI auth round-trip verified liveqodercli,~/.qoder/skills); sandbox install verified~/.codex/skillsgstack entries, spares user files, idempotentAlso survived: an OpenAI Codex adversarial review of the full diff (7 findings, all verified and fixed — including a masked deterministic test failure, a shell-injection hole, and a BSD-mktemp collision confirmed empirically) and a fail-line audit against pristine main that caught one more regression (fixed).
Deliberately EXCLUDED from this push
The /grok second-opinion skill (community PR garrytan#2241 by @ljodea). It's the one wave item whose core value — a successful live xAI review round-trip — could not be exercised: the CLI authenticated fine but the account returned
402 Grok Build usage balance exhausted. Its flag surface, auth path, and graceful degradation ARE verified, and it returns in a follow-up PR the moment one live review is receipted. The grok-build host (install + discovery) is fully verified and stays in.Known-untested remainders, none code-blocking: Windows paths (covered by the repo's windows-tests CI leg), autoplan dual-voice runtime (paid periodic eval tier), Factory/Kiro/Slate/Qoder in-product listings (behind their respective logins; CLIs installed and ready).
Credits
garrytan#1430 @EricXu-0805 · garrytan#2165 @dpnascimento · garrytan#2146 @kalpajit279 · garrytan#1816 @ztownsend (salvage) · garrytan#2229 + garrytan#2221 @time-attack · garrytan#2216 @jizusun · garrytan#2198 @netkurt · garrytan#1494 + garrytan#1888 @jbetala7 · garrytan#1054 @dkoh12 · garrytan#1767 + garrytan#1772 @spacegeologist · garrytan#1160 @mamedov · garrytan#2123 @dpattonux · garrytan#1996 @ashcharus-hue · garrytan#1101 @JiayuuWang · garrytan#1935 @katlun-lgtm · garrytan#1526 @mvanhorn · garrytan#1918 @withabdul (+ idea credit garrytan#1497) · garrytan#2134 @0xshae · garrytan#1640 @nmrtn · garrytan#2116 @andriyhuang · garrytan#1282 @Spenquatch · garrytan#2248 @AgileInnov8tor
Fork PRs don't receive base-repo secrets; when this goes upstream, the branch should be pushed to garrytan/gstack per the repo's fork-PR policy.
🤖 Generated with Claude Code