/gsd-surface
Toggle which skills are surfaced — apply a profile, list, or disable a cluster without reinstall
$ npx -y skills add open-gsd/gsd-core --skill gsd-surface --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/gsd-surface
Context preview
The summary Claude sees to decide when to auto-load this skill.
Toggle which skills are surfaced — apply a profile, list, or disable a cluster without reinstall
SKILL.md
gsd-surface.SKILL.mdname: gsd-surface
description: "Toggle which skills are surfaced — apply a profile, list, or disable a cluster without reinstall"
argument-hint: "[list|status|profile <name>|disable <cluster>|enable <cluster>|reset]"
allowed-tools:
- Read
- Write
- Bash
<objective> Manage the runtime skill surface without reinstall. Reads/writes `~/.claude/.gsd-surface.json` (sibling to `~/.claude/.gsd-profile`) and re-stages the active skills directory in place. Skill dirs live at `~/.claude/skills/gsd-*/`.
Sub-commands: list · status · profile · disable · enable · reset </objective>
Sub-command routing
Parse the first token of $ARGUMENTS:
| Token | Action | |---|---| | `list` | Show enabled + disabled clusters and skills | | `status` | Alias for `list` plus token cost summary | | `profile <name>` | Write `baseProfile` and re-stage | | `profile <n1>,<n2>` | Composed profiles (comma-separated, no spaces) | | `disable <cluster>` | Add cluster to `disabledClusters`, re-stage | | `enable <cluster>` | Remove cluster from `disabledClusters`, re-stage | | `reset` | Delete `.gsd-surface.json`, return to install-time profile | | *(none)* | Treat as `list` |
---
list / status
Load the capability registry and call `listSurface(runtimeConfigDir, manifest, CLUSTERS, registry)` from the engine module at `${runtimeConfigDir}/gsd-core/bin/lib/surface.cjs`. The registry is loaded via:
const registry = require(runtimeConfigDir + '/gsd-core/bin/lib/capability-registry.cjs');
Display:
Enabled (N skills, ~T tokens):
core_loop: new-project discuss-phase plan-phase execute-phase help update
audit_review: …
…
Disabled:
utility: health stats settings …
Token cost: ~T (budget cap ~500 tokens for 200k context @ 1%)
For `status` also append:
Base profile: standard (from .gsd-surface.json)
Install profile: standard (from .gsd-profile)
---
profile \<name\>
1. Read current surface: `readSurface(runtimeConfigDir)` → if null, seed from `readActiveProfile(runtimeConfigDir)`. 2. Set `surfaceState.baseProfile = name`. 3. `writeSurface(runtimeConfigDir, surfaceState)`. 4. Resolve and re-apply:
const registry = require(runtimeConfigDir + '/gsd-core/bin/lib/capability-registry.cjs');
const layout = resolveRuntimeArtifactLayout(runtime, runtimeConfigDir, scope);
applySurface(runtimeConfigDir, layout, manifest, CLUSTERS, registry);
5. Confirm: "Surface updated to profile `<name>`. N skills enabled."
---
disable \<cluster\>
Valid cluster names: `core_loop`, `audit_review`, `milestone`, `research_ideate`, `workspace_state`, `docs`, `ui`, `ai_eval`, `ns_meta`, `utility`.
1. Validate cluster name against `Object.keys(CLUSTERS)`. 2. Read or initialize surface state. 3. Add cluster to `surfaceState.disabledClusters` (deduplicate). 4. `writeSurface` → resolve layout → `applySurface`:
const registry = require(runtimeConfigDir + '/gsd-core/bin/lib/capability-registry.cjs');
const layout = resolveRuntimeArtifactLayout(runtime, runtimeConfigDir, scope);
applySurface(runtimeConfigDir, layout, manifest, CLUSTERS, registry);
5. Confirm: "Disabled cluster `<cluster>`. N skills removed from surface."
---
enable \<cluster\>
1. Read surface state; if null, nothing to enable — print "No surface delta active." 2. Remove cluster from `surfaceState.disabledClusters`. 3. `writeSurface` → resolve layout → `applySurface`:
const registry = require(runtimeConfigDir + '/gsd-core/bin/lib/capability-registry.cjs');
const layout = resolveRuntimeArtifactLayout(runtime, runtimeConfigDir, scope);
applySurface(runtimeConfigDir, layout, manifest, CLUSTERS, registry);
4. Confirm: "Enabled cluster `<cluster>`. N skills added back to surface."
---
reset
1. Check if `.gsd-surface.json` exists. 2. Delete it. 3. Re-apply using only `readActiveProfile(runtimeConfigDir)` (install-time profile). 4. Confirm: "Surface reset to install-time profile `<name>`."
---
runtimeConfigDir resolution
The `runtimeConfigDir` for `applySurface` is the **base Claude config directory** (`~/.claude`), NOT the skills sub-directory (`~/.claude/skills`).
This matches `installRuntimeArtifacts` and `uninstallRuntimeArtifacts`, which also receive `~/.claude` as `configDir`. The skill dirs themselves live at `~/.claude/skills/gsd-*/` because the `claude global` layout has `destSubpath = 'skills'` — they are derived from `configDir`, not the root for it.
# Claude Code — global install
RUNTIME_CONFIG_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
SCOPE="global"
# Artifact destinations are derived from runtime layout
# via resolveRuntimeArtifactLayout(runtime, RUNTIME_CONFIG_DIR, SCOPE)
# then applySurface(RUNTIME_CONFIG_DIR, layout, manifest, CLUSTERS)Surface state is stored at `${RUNTIME_CONFIG_DIR}/.gsd-surface.json` (i.e. `~/.claude/.gsd-surface.json`).
All paths can be overridden by reading the `CLAUDE_CONFIG_DIR` env var if set.
---
Error handling
- Unknown cluster name → list valid cluster names, exit without writing.
- Unknown profile name → list known profiles (`core`, `standard`, `full`), exit.
- Missing `surface.cjs` → prompt: "Run `npm i -g @opengsd/gsd-core` to reinstall GSD."
<execution_context> Surface state file: `~/.claude/.gsd-surface.json` Install profile marker: `~/.claude/.gsd-profile` Skill dirs: `~/.claude/skills/gsd-*/` Engine module: `~/.claude/gsd-core/bin/lib/surface.cjs` Cluster definitions: `~/.claude/gsd-core/bin/lib/clusters.cjs` </execution_context>
Read more
name: gsd-surface description: "Toggle which skills are surfaced — apply a profile, list, or disable a cluster without reinstall" argument-hint: "[list|status|profile <name>|disable <cluster>|enable <cluster>|reset]" allowed-tools: - Read - Write - Bash
<objective> Manage the runtime skill surface without reinstall. Reads/writes `~/.claude/.gsd-surface.json` (sibling to `~/.claude/.gsd-profile`) and re-stages the active skills directory in place. Skill dirs live at `~/.claude/skills/gsd-*/`.
Sub-commands: list · status · profile · disable · enable · reset </objective>
Sub-command routing
Parse the first token of $ARGUMENTS:
| Token | Action | |---|---| | `list` | Show enabled + disabled clusters and skills | | `status` | Alias for `list` plus token cost summary | | `profile <name>` | Write `baseProfile` and re-stage | | `profile <n1>,<n2>` | Composed profiles (comma-separated, no spaces) | | `disable <cluster>` | Add cluster to `disabledClusters`, re-stage | | `enable <cluster>` | Remove cluster from `disabledClusters`, re-stage | | `reset` | Delete `.gsd-surface.json`, return to install-time profile | | *(none)* | Treat as `list` |
---
list / status
Load the capability registry and call `listSurface(runtimeConfigDir, manifest, CLUSTERS, registry)` from the engine module at `${runtimeConfigDir}/gsd-core/bin/lib/surface.cjs`. The registry is loaded via:
const registry = require(runtimeConfigDir + '/gsd-core/bin/lib/capability-registry.cjs');
Display:
Enabled (N skills, ~T tokens): core_loop: new-project discuss-phase plan-phase execute-phase help update audit_review: … … Disabled: utility: health stats settings … Token cost: ~T (budget cap ~500 tokens for 200k context @ 1%)
For `status` also append:
Base profile: standard (from .gsd-surface.json) Install profile: standard (from .gsd-profile)
---
profile \<name\>
1. Read current surface: `readSurface(runtimeConfigDir)` → if null, seed from `readActiveProfile(runtimeConfigDir)`. 2. Set `surfaceState.baseProfile = name`. 3. `writeSurface(runtimeConfigDir, surfaceState)`. 4. Resolve and re-apply:
const registry = require(runtimeConfigDir + '/gsd-core/bin/lib/capability-registry.cjs'); const layout = resolveRuntimeArtifactLayout(runtime, runtimeConfigDir, scope); applySurface(runtimeConfigDir, layout, manifest, CLUSTERS, registry);
5. Confirm: "Surface updated to profile `<name>`. N skills enabled."
---
disable \<cluster\>
Valid cluster names: `core_loop`, `audit_review`, `milestone`, `research_ideate`, `workspace_state`, `docs`, `ui`, `ai_eval`, `ns_meta`, `utility`.
1. Validate cluster name against `Object.keys(CLUSTERS)`. 2. Read or initialize surface state. 3. Add cluster to `surfaceState.disabledClusters` (deduplicate). 4. `writeSurface` → resolve layout → `applySurface`:
const registry = require(runtimeConfigDir + '/gsd-core/bin/lib/capability-registry.cjs'); const layout = resolveRuntimeArtifactLayout(runtime, runtimeConfigDir, scope); applySurface(runtimeConfigDir, layout, manifest, CLUSTERS, registry);
5. Confirm: "Disabled cluster `<cluster>`. N skills removed from surface."
---
enable \<cluster\>
1. Read surface state; if null, nothing to enable — print "No surface delta active." 2. Remove cluster from `surfaceState.disabledClusters`. 3. `writeSurface` → resolve layout → `applySurface`:
const registry = require(runtimeConfigDir + '/gsd-core/bin/lib/capability-registry.cjs'); const layout = resolveRuntimeArtifactLayout(runtime, runtimeConfigDir, scope); applySurface(runtimeConfigDir, layout, manifest, CLUSTERS, registry);
4. Confirm: "Enabled cluster `<cluster>`. N skills added back to surface."
---
reset
1. Check if `.gsd-surface.json` exists. 2. Delete it. 3. Re-apply using only `readActiveProfile(runtimeConfigDir)` (install-time profile). 4. Confirm: "Surface reset to install-time profile `<name>`."
---
runtimeConfigDir resolution
The `runtimeConfigDir` for `applySurface` is the **base Claude config directory** (`~/.claude`), NOT the skills sub-directory (`~/.claude/skills`).
This matches `installRuntimeArtifacts` and `uninstallRuntimeArtifacts`, which also receive `~/.claude` as `configDir`. The skill dirs themselves live at `~/.claude/skills/gsd-*/` because the `claude global` layout has `destSubpath = 'skills'` — they are derived from `configDir`, not the root for it.
# Claude Code — global install
RUNTIME_CONFIG_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
SCOPE="global"
# Artifact destinations are derived from runtime layout
# via resolveRuntimeArtifactLayout(runtime, RUNTIME_CONFIG_DIR, SCOPE)
# then applySurface(RUNTIME_CONFIG_DIR, layout, manifest, CLUSTERS)Surface state is stored at `${RUNTIME_CONFIG_DIR}/.gsd-surface.json` (i.e. `~/.claude/.gsd-surface.json`).
All paths can be overridden by reading the `CLAUDE_CONFIG_DIR` env var if set.
---
Error handling
- Unknown cluster name → list valid cluster names, exit without writing.
- Unknown profile name → list known profiles (`core`, `standard`, `full`), exit.
- Missing `surface.cjs` → prompt: "Run `npm i -g @opengsd/gsd-core` to reinstall GSD."
<execution_context> Surface state file: `~/.claude/.gsd-surface.json` Install profile marker: `~/.claude/.gsd-profile` Skill dirs: `~/.claude/skills/gsd-*/` Engine module: `~/.claude/gsd-core/bin/lib/surface.cjs` Cluster definitions: `~/.claude/gsd-core/bin/lib/clusters.cjs` </execution_context>
Git. Ship. Done. A light-weight meta-prompting, context engineering, and spec-driven development system for Claude Code, OpenCode, Antigravity CLI, Kimi CLI, Kilo, Codex, Copilot, Cursor, Windsurf, and more.
Repo: open-gsd/gsd-core
Other skills on gsd-core.
- /gsd-add-tests
Generate tests for a completed phase based on UAT criteria and implementation
Open skill - /gsd-ai-integration-phase
Generate an AI-SPEC.md design contract for phases that involve building AI systems.
Open skill - /gsd-audit-fix
Autonomous audit-to-fix pipeline — find issues, classify, fix, test, commit
Open skill - /gsd-audit-milestone
Audit milestone completion against original intent before archiving
Open skill - /gsd-audit-uat
Cross-phase audit of all outstanding UAT and verification items
Open skill - /gsd-autonomous
Run all remaining phases autonomously — discuss→plan→execute per phase
Open skill

