Cristian Uibar c5657fcbfd fix(surface): default missing optional fields in readSurface, normalize writeSurface input (#3666)
* surface: default missing optional fields in readSurface, normalize writeSurface input

readSurface used to reject any .gsd-surface.json missing one of its four fields
and return null with no diagnostic, so the active surface silently degraded to
the 'full' profile. Optional array fields (disabledClusters, explicitAdds,
explicitRemoves) now default to [] when missing or wrong-typed; hard failures
(malformed JSON, non-object root, missing/non-string baseProfile) still return
null but emit a console.warn naming the file + reason.

writeSurface now normalizes its input to the full SurfaceState shape and
throws on missing baseProfile, so partial writes can no longer land on disk
and trip readSurface later. Tests extended to cover the new lenient and
warn-on-hard-fail behavior plus the writer guard.

Fixes #3662

* surface: reject whitespace-only baseProfile + migrate new tests to helpers.cjs

Applies CodeRabbit findings on PR #3666:

1. readSurface and writeSurface now reject baseProfile values that are blank
   after trim() (e.g. "   "), not only the empty string. Whitespace-only
   strings would split-by-comma to [''] downstream and silently produce an
   unresolvable profile mode. Both guards updated symmetrically; warn/error
   messages reworded to "missing, non-string, or blank".

2. tests/surface-state.test.cjs now uses createTempDir + cleanup from
   tests/helpers.cjs instead of local mkdtempSync + fs.rmSync, aligning with
   the repo coding guideline for root-level tests. The local tmpDir() helper
   delegates to createTempDir for backward-compat with the existing test
   bodies. Per-test cleanup calls swapped to cleanup(dir).

3. Added regression tests:
   - readSurface rejects whitespace-only baseProfile and warns
   - writeSurface rejects whitespace-only baseProfile, non-string baseProfile,
     and null surfaceState

Refs #3662

* surface: warn on unknown baseProfile mode names in read and write

Applies a Codex review finding on PR #3666:

readSurface and writeSurface used to accept any non-blank string as
baseProfile. A typo like {"baseProfile":"standrad"} would pass validation,
then resolveProfile() in install-profiles.cjs would silently fall back to
'full' with no diagnostic — the same silent-degradation symptom that #3662
was filed to fix, just through a different code path.

Both functions now split baseProfile by comma, validate each mode against
the registered PROFILES set ('core', 'standard', 'full'), and emit a single
[gsd] console.warn line that names the unknown modes and lists the valid
ones. The state is still parsed/written — resolveProfile() decides the
actual resolution fallback. Composed profiles where some modes are valid
and some are not warn only about the unknown subset.

Side note: the pre-existing 'round-trips composed base profile' test used
'core,audit' as a stand-in composed string. 'audit' is not a registered
profile (the three known profiles are 'core', 'standard', 'full'), so the
test was relying on the old lack of validation. Switched to 'core,standard'
to preserve the round-trip intent without producing diagnostic noise.

Refs #3662

* changeset: include blank/typo baseProfile in documented read failure cases

CodeRabbit minor finding on PR #3666 — the changeset wording only mentioned
"missing/non-string baseProfile" but the implementation also rejects blank
(including whitespace-only) baseProfile values, and warns on typo'd /
unknown profile mode names. Updated to match actual behavior.

* changeset: pr field should be PR number, not issue number

Codex review finding on PR #3666. The changeset's `pr: 3662` was the linked
issue (#3662), but the convention across other .changeset/*.md files is that
`pr:` carries the PR number. Verified by spot-checking other changesets
(2937 → pr: 3515, 3298 → pr: 3306, 3541 → pr: 3547 — all PR numbers).
Updated to `pr: 3666`. The body text still references the issue.

* surface: reject comma-only baseProfile + warn on wrong-typed optional fields

Three Gemini review findings on PR #3666 — all spirit-of-#3662 edge cases:

1. Comma-only baseProfile bypasses validation. readSurface used to accept
   baseProfile: ", ," because trim() returned "," (non-empty). Downstream
   resolveProfile() would split-and-filter to [] and silently fall back to
   'full'. Added effectiveProfileModes() helper that splits, trims, filters
   empty — both readSurface and writeSurface now reject when the result is
   empty. Same silent-degradation symptom as the original bug.

2. Wrong-typed optional fields silently coerced. readSurface used to coerce
   {disabledClusters: 42} to {disabledClusters: []} with no diagnostic.
   Now warns via mistypedOptionalFields() before normalizeSurfaceState()
   does the coercion, in both reader and writer.

3. Missing test coverage for the EACCES branch in readSurface. Added a
   chmod-000 unreadable-file test, skipped on Windows and root accounts
   (mode bits are ignored on those platforms).

48/48 surface tests pass. Final codex pass returned LGTM on the prior
state; these three additions strengthen the same lenient/loud contract.

Refs #3662
2026-05-18 00:14:07 -04:00
2026-05-15 18:16:33 -04:00

GET SHIT DONE

English · Português · 简体中文 · 日本語 · 한국어

A light-weight meta-prompting, context engineering, and spec-driven development system for Claude Code, OpenCode, Gemini CLI, Kilo, Codex, Copilot, Cursor, Windsurf, and more.

Solves context rot — the quality degradation that happens as your AI fills its context window.

npm version npm downloads Tests Discord X (Twitter) $GSD Token GitHub stars License


npx get-shit-done-cc@latest

Works on Mac, Windows, and Linux.


GSD Install


"If you know clearly what you want, this WILL build it for you. No bs."

"I've done SpecKit, OpenSpec and Taskmaster — this has produced the best results for me."

"By far the most powerful addition to my Claude Code. Nothing over-engineered. Literally just gets shit done."


Trusted by engineers at Amazon, Google, Shopify, and Webflow.


Important

Returning to GSD?

Run /gsd-map-codebase to re-index your codebase, then /gsd-new-project to rebuild GSD's planning context. Your code is fine — GSD just needs its context rebuilt. See the CHANGELOG for what's new.


Why I Built This

I'm a solo developer. I don't write code — Claude Code does.

Other spec-driven tools exist, but they're all built for 50-person engineering orgs — sprint ceremonies, story points, stakeholder syncs, Jira workflows. I'm not that. I'm a creative person trying to build great things consistently.

So I built GSD. The complexity is in the system, not in your workflow. Behind the scenes: context engineering, XML prompt formatting, subagent orchestration, state management. What you see: a few commands that just work.

The system gives Claude everything it needs to do the work and verify it. I trust the workflow. It just does a good job.

— TÂCHES


How It Works

The loop is six commands. Each one does exactly one thing.

1. Initialize

/gsd-new-project

Questions → research → requirements → roadmap. You approve it, then you're ready to build.

Already have code? Run /gsd-map-codebase first. It analyzes your stack, architecture, and conventions so /gsd-new-project asks the right questions.

2. Discuss

/gsd-discuss-phase 1

Your roadmap has a sentence per phase. That's not enough to build it the way you imagine it. Discuss captures your decisions before anything gets planned: layouts, API shapes, error handling, data structures — whatever gray areas exist for this specific phase.

The output feeds directly into research and planning. Skip it, get reasonable defaults. Use it, get your vision.

3. Plan

/gsd-plan-phase 1

Research → plan → verify, in a loop until the plans pass. Each plan is small enough to execute in a fresh context window.

4. Execute

/gsd-execute-phase 1

Plans run in parallel waves. Each executor gets a fresh 200k-token context. Each task gets its own atomic commit. Walk away, come back to completed work with a clean git history.

Your main context window stays at 30–40%. The work happens in the subagents.

5. Verify

/gsd-verify-work 1

Walk through what was built. Anything broken gets a diagnosed fix plan — ready for immediate re-execution. You don't debug manually; you just run execute again.

6. Repeat → Ship

/gsd-ship 1
/gsd-complete-milestone
/gsd-new-milestone

Loop discuss → plan → execute → verify → ship until the milestone is done. Then archive, tag, and start the next one fresh.


Getting Started

npx get-shit-done-cc@latest

The installer prompts for your runtime (Claude Code, OpenCode, Gemini CLI, Kilo, Codex, Copilot, Cursor, Windsurf, and more) and whether to install globally or locally.

claude --dangerously-skip-permissions

GSD is built for frictionless automation. Skip-permissions is how it's intended to run.

Install only the skills you need with --profile=core (six core-loop skills), --profile=standard (core + phase management), or the default full install. Profiles compose: --profile=core,audit. --minimal is an alias for --profile=core. See docs/USER-GUIDE.md for the full walkthrough, non-interactive install flags for all 15 runtimes, and permissions configuration. See ADR-0011 for the profile model and runtime surface control.

Current release highlights are in docs/RELEASE-v1.42.1.md: package legitimacy checks, safer installer migrations, runtime surface control, custom ship PR sections, reviewer defaults, fallow structural review, and quota-aware execution recovery.


Commands

The main loop:

Command What it does
/gsd-new-project Questions → research → requirements → roadmap
/gsd-discuss-phase [N] Capture implementation decisions before planning
/gsd-plan-phase [N] Research + plan + verify
/gsd-execute-phase <N> Execute plans in parallel waves
/gsd-verify-work [N] Manual acceptance testing
/gsd-ship [N] Create PR from verified phase work
/gsd-progress --next Auto-detect and run the next step
/gsd-complete-milestone Archive milestone and tag release
/gsd-new-milestone Start next version
/gsd:surface Enable/disable skill clusters at runtime without reinstall

For ad-hoc tasks, autonomous mode, codebase analysis, forensics, and the full command surface — see docs/COMMANDS.md.


Why It Works

Three things most AI-coding setups get wrong:

1. Context bloat. As a session grows, quality degrades. GSD keeps your main context clean by doing the heavy work in fresh subagent contexts. Researchers, planners, and executors each start fresh with exactly what they need.

2. No shared memory. GSD maintains structured artifacts that survive session boundaries: PROJECT.md (vision), REQUIREMENTS.md (scope), ROADMAP.md (where you're going), STATE.md (current position and decisions), CONTEXT.md (per-phase implementation decisions). Every new session loads these and knows exactly where things stand.

3. No verification. Code that "runs" isn't code that "works." GSD's verify step walks you through what was built, diagnoses failures with dedicated debug agents, and generates fix plans before you declare a phase done.

See docs/ARCHITECTURE.md for how the multi-agent orchestration and context engineering work in detail.


Configuration

Settings live in .planning/config.json. Configure during /gsd-new-project or update with /gsd-settings.

Key dials:

Setting What it controls
mode interactive (confirm each step) or yolo (auto-approve)
Model profiles quality / balanced / budget — controls which model each agent uses
workflow.research / plan_check / verifier Toggle the quality agents that add tokens and time
parallelization.enabled Run independent plans simultaneously

Optional structural review: set code_quality.fallow.enabled to true to add a fallow pre-pass to /gsd-code-review. GSD writes .planning/phases/<phase>/FALLOW.json and surfaces a Structural Findings (fallow) section in REVIEW.md. Install with npm install -D fallow@^2.70.0 (or system-wide via cargo install fallow; note that the Rust binary's JSON schema must match the documented v2.70+ contract — older versions may produce silent zero-finding output).

Package legitimacy checks are built into the research, planning, and execution path: recommended dependencies get audited, unverified packages require a human checkpoint, and failed installs stop instead of trying similarly named alternatives.

For the full configuration reference — all settings, git branching strategies, per-runtime model overrides, workstream config inheritance, agent skills injection — see docs/CONFIGURATION.md.


Documentation

Doc What's in it
User Guide End-to-end walkthrough, install options, all runtime flags, configuration reference
Commands Every command with flags and examples
Configuration Full config schema, model profiles, git branching
Architecture How the multi-agent orchestration works
CLI Tools gsd-sdk query and programmatic SDK dispatch seams
Features Complete feature index
Changelog What changed in each release

Troubleshooting

Commands not showing up? Restart your runtime after install. GSD installs to ~/.claude/skills/gsd-*/ (Claude Code), ~/.codex/skills/gsd-*/ (Codex), or the equivalent for your runtime.

Codex users — minimum supported CLI version is 0.130.0. Codex CLI 0.130.0 (release notes) removed extra-skill-roots discovery via openai/codex#21485; from that version onward Codex discovers skills from standard roots (including ~/.codex/skills/<name>/SKILL.md). GSD installs there directly. Earlier Codex CLI versions may still discover additional roots, which can surface duplicate gsd-* entries (one from extra-roots discovery, one from ~/.codex/skills/); restart Codex after install and either upgrade or accept the duplicate listing.

Something broken? Re-run the installer — it's idempotent:

npx get-shit-done-cc@latest

Containers or Docker? Set CLAUDE_CONFIG_DIR before installing to avoid tilde-expansion issues:

CLAUDE_CONFIG_DIR=/home/youruser/.claude npx get-shit-done-cc --global

Full troubleshooting and uninstall instructions in docs/USER-GUIDE.md.


Community

Project Platform
gsd-opencode Original OpenCode port
Discord Community support

Star History

Star History Chart

License

MIT License. See LICENSE for details.


Claude Code is powerful. GSD makes it reliable.

Description
No description provided
Readme MIT 77 MiB
Languages
JavaScript 82.3%
TypeScript 17.4%
Shell 0.3%