garrytan / garrytan/gstack

Opencode host skills contain hardcoded Claude-specific tools and config paths

Open
#2,626 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
133k
Forks
19.9k
Avg merge
18h 46m
Merged PRs (30d)
26

Description

## Summary

The generated SKILL.md files for the Opencode host contain hardcoded Claude Code-specific tool references, env vars, and config file paths that do not exist in Opencode. The preamble and several resolvers assume Claude as the runtime across all hosts, making the Opencode (and likely Codex/Kiro/Slate) outputs non-functional or misleading.

## Affected artifacts

Every generated skill under `.opencode/skills/gstack-*/SKILL.md` exhibits some combination of the following.

### 1. `AskUserQuestion` tool references

The preamble and skill prose instruct the agent to use `AskUserQuestion` — a Claude Code native tool. Opencode uses the `question` tool instead. References appear in:

- Preamble prose: "ask telemetry once via AskUserQuestion", "warn once via AskUserQuestion"
- `## AskUserQuestion Format` section references `mcp__*__AskUserQuestion` MCP variant
- `generate-ask-user-format.ts` (line 4+)
- `generate-completion-status.ts` (line 29+) — plan-mode instructions reference AskUserQuestion and ExitPlanMode
- `generate-telemetry-prompt.ts`, `generate-vendoring-deprecation.ts`, `generate-routing-injection.ts`
- `testing.ts` (lines 55, 63, 94, 361, 482, 489, 493)

### 2. `ExitPlanMode` tool reference

`generate-completion-status.ts` (line 29) references `ExitPlanMode` — Claude Code specific, not available in Opencode.

### 3. `CLAUDE_PLAN_FILE` env var

The preamble (`generate-preamble-bash.ts`, line 120-124) detects Claude Code plan mode via:
```bash
if [ -n "${CLAUDE_PLAN_FILE:-}${GSTACK_PLAN_MODE_FORCE:-}" ]; then
```
This is dead code for Opencode — the env var is never set.

### 4. `.claude.json` gbrain MCP detection

`generate-preamble-bash.ts` (line 377) reads gbrain MCP config from `~/.claude.json`:
```bash
if command -v jq >/dev/null 2>&1 && [ -f "$HOME/.claude.json" ]; then
```
For Opencode, this should read `~/.config/opencode/opencode.jsonc`.

### 5. `.claude/skills/gstack` vendored detection

The preamble (line 108-112) checks:
```bash
if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then
```
Should also check `.opencode/skills/gstack` for the Opencode host.

### 6. `MODEL_OVERLAY: claude`

`gen-skill-docs.ts` defaults to `--model claude` (line 100), so every Opencode skill gets the Claude behavioral overlay. There is no `opencode.md` model overlay file. The `## Model-Specific Behavioral Patch` heading also hardcodes "(claude)" regardless of host.

## Root cause

The preamble generation (`generate-preamble-bash.ts`) and several resolvers (`generate-completion-status.ts`, `generate-ask-user-format.ts`, `model-overlay.ts`) have Claude-specific content that is not parameterized by host. The Opencode host config (`hosts/opencode.ts`) only sets paths — it does not override tool names, config file locations, plan mode detection, or model overlay selection.

## Existing related issues

- **#314** — Community member forked gstack entirely into [gstack-opencode](https://github.com/VanGoghBuilder/gstack-opencode) because the Claude-centricity was too deep to fix incrementally. This issue is the upstream equivalent of that fork's reason for existing.
- **#1925** — `/gstack-upgrade` only re-registers Claude Code, so other hosts drift. Related but about the upgrade path, not preamble content.
- **#1694** — Host-generated skill files pollute Claude's scanner. Structural, not content.

## Suggested fixes

1. **Tool name rewrites**: Add `AskUserQuestion → question` and `ExitPlanMode → (skip)` to the Opencode host config's `toolRewrites`. Update resolvers to check host context before emitting Claude-only tool prose.

2. **Plan mode detection**: Parameterize the `CLAUDE_PLAN_FILE` check — Opencode likely uses a different env var or mechanism. The resolver should emit host-appropriate detection logic.

3. **gbrain config path**: The gbrain MCP detection should read from the host's config file (`opencode.jsonc` for Opencode) rather than hardcoding `.claude.json`.

4. **Vendored detection**: The preamble should check the host's own skill directory (`.opencode/skills/gstack`) in addition to `.claude/skills/gstack`.

5. **Model overlay**: Either create an `opencode.md` overlay or default to no overlay for non-Claude hosts.

6. **Host parameterization**: The `defineHost` interface should support `questionToolName`, `planModeEnvVar`, `configFilePath`, `vendoredCheckPath` fields so resolvers can emit host-correct content.

## Environment

- gstack version: v1.67.1.0
- Host: opencode (with `./setup --host opencode`)
- Install: global git at `~/gstack/`
- Skills generated to: `~/.config/opencode/skills/gstack/` + `~/gstack/.opencode/skills/`

Contributor guide

Open the contributing guide

Research direction

Start with hosts/opencode.ts and the defineHost interface, then trace the affected generators and resolvers named in the issue, including generate-preamble-bash.ts, generate-completion-status.ts, generate-ask-user-format.ts, model-overlay.ts, and gen-skill-docs.ts. Inspect generated .opencode/skills/gstack-*/SKILL.md files and relevant cases in testing.ts; done means Opencode output no longer contains Claude-only tools, paths, environment checks, or overlays.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
tooling
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.