Skip to content

setup --host cursor errors out despite README + hosts/cursor.ts declaring full Cursor support #1358

@hhlqsmy

Description

@hhlqsmy

setup --host cursor errors out despite README + hosts/cursor.ts declaring full Cursor support

Summary

The README and hosts/cursor.ts both advertise Cursor as a supported host (skills install to ~/.cursor/skills/gstack-*/), but the bash entrypoint setup never got the corresponding wiring. As a result ./setup --host cursor fails immediately with Unknown --host value: cursor, and there is no way for a Cursor user to install gstack through the documented quick-start command.

This looks like a documentation/code drift: the TypeScript-side host registry has cursor wired up (hosts/cursor.ts, hosts/index.ts), but the bash glue that dispatches to per-host install logic was never updated.

Tested on v1.27.1.0 (7b4738b).

Reproduction

git clone --single-branch --depth 1 https://github.com/garrytan/gstack.git ~/gstack
cd ~/gstack && ./setup --host cursor

Expected

Per README §"Other AI Agents":

| Cursor | --host cursor | Skills install to ~/.cursor/skills/gstack-*/ |

./setup --host cursor should generate Cursor-flavored skills under ~/.cursor/skills/gstack-*/.

Actual

Unknown --host value: cursor (expected claude, codex, kiro, factory, opencode, openclaw, hermes, gbrain, or auto)

Note that even the error message itself doesn't list cursor as valid — confirming this is missing wiring rather than a regression.

Root cause

cursor is correctly registered on the TypeScript side:

  • hosts/cursor.ts — full HostConfig (globalRoot .cursor/skills/gstack, pathRewrites, runtimeRoot, etc.)
  • hosts/index.ts:21 — included in ALL_HOST_CONFIGS

But the bash setup script is missing it in four places:

  1. setup:46 — error message in --host arg validation
  2. setup:58-59 — host allowlist case statement
  3. setup:94 — fallback "Unknown --host" error message
  4. setup:153-178 — the INSTALL_* flag dispatcher (if/elif) has no cursor branch, so INSTALL_CURSOR is never set
  5. (Downstream) The skill-docs generation block (setup:~315) and the install block (setup:~929) have no cursor mirror of the existing INSTALL_OPENCODE pattern.

Suggested fix

A minimal patch that just makes the entrypoint accept cursor is one line, but the complete fix needs to mirror the opencode integration pattern. Below is a concrete sketch (line numbers from 7b4738b):

Patch 1 — setup:46 (arg validation error message)

-    --host) [ -z "$2" ] && echo "Missing value for --host (expected claude, codex, kiro, factory, opencode, openclaw, hermes, gbrain, or auto)" >&2 && exit 1; HOST="$2"; shift 2 ;;
+    --host) [ -z "$2" ] && echo "Missing value for --host (expected claude, codex, kiro, factory, opencode, cursor, openclaw, hermes, gbrain, or auto)" >&2 && exit 1; HOST="$2"; shift 2 ;;

Patch 2 — setup:58-59 (host allowlist)

 case "$HOST" in
-  claude|codex|kiro|factory|opencode|auto) ;;
+  claude|codex|kiro|factory|opencode|cursor|auto) ;;

Patch 3 — setup:94 (fallback error)

-  *) echo "Unknown --host value: $HOST (expected claude, codex, kiro, factory, opencode, openclaw, hermes, gbrain, or auto)" >&2; exit 1 ;;
+  *) echo "Unknown --host value: $HOST (expected claude, codex, kiro, factory, opencode, cursor, openclaw, hermes, gbrain, or auto)" >&2; exit 1 ;;

Patch 4 — setup:153-178 (INSTALL_* flag dispatcher)

 INSTALL_CLAUDE=0
 INSTALL_CODEX=0
 INSTALL_KIRO=0
 INSTALL_FACTORY=0
 INSTALL_OPENCODE=0
+INSTALL_CURSOR=0
 if [ "$HOST" = "auto" ]; then
   command -v claude >/dev/null 2>&1 && INSTALL_CLAUDE=1
   command -v codex >/dev/null 2>&1 && INSTALL_CODEX=1
   command -v kiro-cli >/dev/null 2>&1 && INSTALL_KIRO=1
   command -v droid >/dev/null 2>&1 && INSTALL_FACTORY=1
   command -v opencode >/dev/null 2>&1 && INSTALL_OPENCODE=1
+  command -v cursor >/dev/null 2>&1 && INSTALL_CURSOR=1
   # If none found, default to claude
-  if [ "$INSTALL_CLAUDE" -eq 0 ] && [ "$INSTALL_CODEX" -eq 0 ] && [ "$INSTALL_KIRO" -eq 0 ] && [ "$INSTALL_FACTORY" -eq 0 ] && [ "$INSTALL_OPENCODE" -eq 0 ]; then
+  if [ "$INSTALL_CLAUDE" -eq 0 ] && [ "$INSTALL_CODEX" -eq 0 ] && [ "$INSTALL_KIRO" -eq 0 ] && [ "$INSTALL_FACTORY" -eq 0 ] && [ "$INSTALL_OPENCODE" -eq 0 ] && [ "$INSTALL_CURSOR" -eq 0 ]; then
     INSTALL_CLAUDE=1
   fi
 elif [ "$HOST" = "claude" ]; then
   INSTALL_CLAUDE=1
 elif [ "$HOST" = "codex" ]; then
   INSTALL_CODEX=1
 elif [ "$HOST" = "kiro" ]; then
   INSTALL_KIRO=1
 elif [ "$HOST" = "factory" ]; then
   INSTALL_FACTORY=1
 elif [ "$HOST" = "opencode" ]; then
   INSTALL_OPENCODE=1
+elif [ "$HOST" = "cursor" ]; then
+  INSTALL_CURSOR=1
 fi

Patch 5 — skill-docs generation block (around setup:315)

 # 1d. Generate .opencode/ OpenCode skill docs
 if [ "$INSTALL_OPENCODE" -eq 1 ] && [ "$NEEDS_BUILD" -eq 0 ]; then
   log "Generating .opencode/ skill docs..."
   (
     cd "$SOURCE_GSTACK_DIR"
     bun install --frozen-lockfile 2>/dev/null || bun install
     bun run gen:skill-docs --host opencode
   )
 fi
+
+# 1e. Generate .cursor/ Cursor skill docs
+if [ "$INSTALL_CURSOR" -eq 1 ] && [ "$NEEDS_BUILD" -eq 0 ]; then
+  log "Generating .cursor/ skill docs..."
+  (
+    cd "$SOURCE_GSTACK_DIR"
+    bun install --frozen-lockfile 2>/dev/null || bun install
+    bun run gen:skill-docs --host cursor
+  )
+fi

Patch 6 — install block (around setup:929)

This needs create_cursor_runtime_root / link_cursor_skill_dirs helpers analogous to the opencode ones. The exact signatures depend on how hosts/cursor.ts's runtimeRoot and pathRewrites are meant to map to bash, so I'll defer to whoever wrote hosts/cursor.ts on the canonical implementation:

 # 6c. Install for OpenCode
 if [ "$INSTALL_OPENCODE" -eq 1 ]; then
   mkdir -p "$OPENCODE_SKILLS"
   create_opencode_runtime_root "$SOURCE_GSTACK_DIR" "$OPENCODE_GSTACK"
   link_opencode_skill_dirs "$SOURCE_GSTACK_DIR" "$OPENCODE_SKILLS"
   echo "gstack ready (opencode)."
   echo "  browse: $BROWSE_BIN"
   echo "  opencode skills: $OPENCODE_SKILLS"
 fi
+
+# 6d. Install for Cursor
+if [ "$INSTALL_CURSOR" -eq 1 ]; then
+  mkdir -p "$CURSOR_SKILLS"
+  create_cursor_runtime_root "$SOURCE_GSTACK_DIR" "$CURSOR_GSTACK"
+  link_cursor_skill_dirs "$SOURCE_GSTACK_DIR" "$CURSOR_SKILLS"
+  echo "gstack ready (cursor)."
+  echo "  browse: $BROWSE_BIN"
+  echo "  cursor skills: $CURSOR_SKILLS"
+fi

(Plus the CURSOR_SKILLS=$HOME/.cursor/skills / CURSOR_GSTACK=$CURSOR_SKILLS/gstack variable declarations near the top of the file, matching the OPENCODE_* block at setup:31-32.)

Workaround

For anyone hitting this today, manual symlinks work — Cursor reads ~/.cursor/skills/<name>/SKILL.md and gstack's per-skill folders already have the right structure. The methodology skills (no daemon dependency) work fine; tool-heavy skills (/qa, /browse, /canary, /ship, etc.) need the daemon and won't function in Cursor without further work.

git clone --single-branch --depth 1 https://github.com/garrytan/gstack.git ~/gstack
cd ~/.cursor/skills
for skill in office-hours plan-ceo-review plan-eng-review plan-design-review \
             review investigate retro autoplan learn document-release; do
  ln -s "$HOME/gstack/$skill" "gstack-$skill"
done

After this, Cursor's agent loads the skills via the standard agent_skills discovery mechanism and they trigger correctly on natural-language phrases (e.g. "use gstack-office-hours to review this doc"). I verified this with gstack-office-hours, gstack-plan-ceo-review, gstack-review, and gstack-investigate against a real codebase.

Environment

  • gstack: v1.27.1.0 (7b4738b)
  • OS: macOS (darwin 25.4.0, arm64)
  • bun: 1.3.13
  • Cursor: latest stable

Why this matters

Cursor has a sizeable user base that the README explicitly invites in. Right now those users hit a hard error on the documented install command and have no clear next step — most will assume gstack is broken on their platform rather than a missing piece of bash glue. A roughly 30-line patch unblocks them.

Happy to send a PR if you'd like — just want to confirm the canonical create_cursor_runtime_root / link_cursor_skill_dirs shape (i.e. whether you'd prefer parameterized helpers or per-host duplication) before implementing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions