Skip to content

/gsd mode

/gsd mode is a quick toggle between solo and team workflow modes. Each mode records a single mode key in your preferences file and applies a coordinated set of defaults at runtime — saving you from configuring git, isolation, and ID settings individually.

Solo mode is optimized for individual developers — it auto-pushes, uses simple sequential milestone IDs, and keeps git flow lightweight. Team mode is designed for shared repositories — it uses unique milestone IDs to avoid collisions, pushes branches for review, and enables pre-merge checks.

Mode defaults are the lowest-priority layer. Any value you’ve explicitly set in your preferences file overrides the mode default. This means you can use a mode as a starting point and customize individual settings without losing the rest.

/gsd mode # Set workflow mode (global scope)
/gsd mode global # Set workflow mode at global level (same as above)
/gsd mode project # Set workflow mode at project level only

In all cases, a selection prompt opens to choose between solo, team, (none), or keep current.

The command presents four options:

  1. solo — auto-push, squash, simple IDs (personal projects)
  2. team — unique IDs, push branches, pre-merge checks (shared repos)
  3. (none) — configure everything manually
  4. (keep current) — exit without changes

When you select a mode, the mode key is written to your preferences file (mode: solo or mode: team), and the entire preferences file is serialized and saved. The individual git and ID settings are not written — they are resolved at runtime via applyModeDefaults, which merges mode defaults as the lowest-priority layer. Any explicitly set preference value wins over the mode default.

Selecting (none) removes the mode key entirely — all settings revert to whatever you’ve explicitly configured (or their built-in defaults if nothing is set).

By default, /gsd mode writes to the global preferences at ~/.gsd/preferences.md. Pass project to write to .gsd/preferences.md in the current project instead. Project-scope preferences take priority over global preferences during merge, so you can have a different mode per project.

Before opening the mode selector, /gsd mode calls ensurePreferencesFile. If the target preferences file doesn’t exist, it is created from the built-in templates/preferences.md template before proceeding. You won’t be dropped into the selector against a missing file.

SettingSoloTeam
git.auto_pushtrue — pushes after each commitfalse — commits stay local
git.push_branchesfalse — no feature branches pushedtrue — milestone branches pushed for review
git.pre_merge_checkfalse — merge without CI gatetrue — wait for CI before merging
git.merge_strategysquashsquash
git.isolationworktreeworktree
unique_milestone_idsfalse — simple M001, M002trueM001-eh88as, M002-k4m9xz (prevents ID collisions)

In solo mode, milestone IDs are simple sequential numbers: M001, M002, M003. This is clean and easy to reference.

In team mode, milestone IDs include a random 6-character suffix: M001-eh88as. This prevents collisions when multiple contributors queue milestones on different branches — two developers creating “M003” independently would get M003-abc123 and M003-def456 instead of conflicting.

The unique ID format affects directory names (.gsd/milestones/M001-eh88as/), branch names (milestone/M001-eh88as), and all references in state files.

When GSD loads effective preferences it merges layers in this order (last wins for explicit values, earlier fills gaps):

  1. Mode defaults — lowest priority, filled in last for any undefined fields
  2. Token profile defaults — filled in before mode defaults
  3. Global preferences (~/.gsd/preferences.md) — explicit values override everything below
  4. Project preferences (.gsd/preferences.md) — highest priority, wins over global

Mode defaults are applied via applyModeDefaults, which calls mergePreferences(modeDefaults, userPrefs). Because mergePreferences lets the right-hand side win for any defined value, user preferences always take precedence.

FilePurpose
~/.gsd/preferences.mdCreated from template if it doesn’t exist (global scope)
.gsd/preferences.mdCreated from template if it doesn’t exist (project scope)
FilePurpose
~/.gsd/preferences.mdCurrent global preferences (loaded before editing)
.gsd/preferences.mdCurrent project preferences (when project scope)
FilePurpose
~/.gsd/preferences.mdFull preferences file saved with updated mode key (global scope, default)
.gsd/preferences.mdFull preferences file saved with updated mode key (project scope, when project arg passed)

Switching to team mode globally:

> /gsd mode
Workflow mode:
❯ solo — auto-push, squash, simple IDs (personal projects)
team — unique IDs, push branches, pre-merge checks (shared repos)
(none) — configure everything manually
(keep current)
→ team
Mode: team — defaults: auto_push=false, push_branches=true,
pre_merge_check=true, merge_strategy=squash, isolation=worktree,
unique_milestone_ids=true

Switching to project-level solo mode (overrides global team mode for this repo):

> /gsd mode project
Workflow mode (current: team):
❯ solo — auto-push, squash, simple IDs (personal projects)
team — unique IDs, push branches, pre-merge checks (shared repos)
(none) — configure everything manually
(keep current)
→ solo
Mode: solo — defaults: auto_push=true, push_branches=false,
pre_merge_check=false, merge_strategy=squash, isolation=worktree,
unique_milestone_ids=false

Removing mode defaults entirely (configure each preference manually):

> /gsd mode
→ (none)
Saved global preferences to /Users/you/.gsd/preferences.md
  • /gsd prefs — Full preference wizard (mode is one category alongside models, timeouts, git, and skills)
  • /gsd config — Configure tool API keys
  • /gsd doctor — Validates preference file structure