Files
msd-core/sdk
Tom Boucher 2980f0ec48 fix(sdk): stripShippedMilestones handles inline SHIPPED headings; getMilestoneInfo prefers STATE.md (#2508)
* fix(sdk): stripShippedMilestones handles inline SHIPPED headings; getMilestoneInfo prefers STATE.md

Fixes two compounding bugs:

- #2496: stripShippedMilestones only stripped <details> blocks, ignoring
  '## Heading — ✅ SHIPPED ...' inline markers. Shipped milestone sections
  were leaking into downstream parsers.

- #2495: getMilestoneInfo checked STATE.md frontmatter only as a last-resort
  fallback, so it returned the first heading match (often a leaked shipped
  milestone) rather than the current milestone. Moved STATE.md check to
  priority 1, consistent with extractCurrentMilestone.

Closes #2495
Closes #2496

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(roadmap): handle ### SHIPPED headings and STATE.md version-only case

Two follow-up fixes from CodeRabbit review of #2508:

1. stripShippedMilestones only split on ## boundaries; ### headings marked
   ✅ SHIPPED were not stripped, leaking into fallback parsers. Expanded
   the split/filter regex to #{2,3} to align with extractCurrentMilestone.

2. getMilestoneInfo's early-return on parseMilestoneFromState discarded the
   real milestone name from ROADMAP.md when STATE.md had only `milestone:`
   (no `milestone_name:`), returning the placeholder name 'milestone'.
   Now only short-circuits when STATE.md provides a real name; otherwise
   falls through to ROADMAP for the name while using stateVersion to
   override the version in every ROADMAP-derived return path.

Tests: +2 new cases (### SHIPPED heading, version-only STATE.md).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 10:41:35 -04:00
..

@gsd-build/sdk

TypeScript SDK for Get Shit Done: deterministic query/mutation handlers, plan execution, and event-stream telemetry so agents focus on judgment, not shell plumbing.

Install

npm install @gsd-build/sdk

Quickstart — programmatic

import { GSD, createRegistry } from '@gsd-build/sdk';

const gsd = new GSD({ projectDir: process.cwd(), sessionId: 'my-run' });
const tools = gsd.createTools();

const registry = createRegistry(gsd.eventStream, 'my-run');
const { data } = await registry.dispatch('state.json', [], process.cwd());

Quickstart — CLI

From a project that depends on this package, invoke the CLI with Node (recommended in CI and local dev):

node ./node_modules/@gsd-build/sdk/dist/cli.js query state.json
node ./node_modules/@gsd-build/sdk/dist/cli.js query roadmap.analyze

If no native handler is registered for a command, the CLI can transparently shell out to get-shit-done/bin/gsd-tools.cjs (see stderr warning), unless GSD_QUERY_FALLBACK=off.

What ships

Area Entry
Query registry createRegistry() in src/query/index.ts — same handlers as gsd-sdk query
Tools bridge GSDTools — native dispatch with optional CJS subprocess fallback
Orchestrators PhaseRunner, InitRunner, GSD
CLI gsd-sdk — query, run, init, auto

Guides

  • Handler registry & contracts: src/query/QUERY-HANDLERS.md
  • Repository docs (when present): docs/ARCHITECTURE.md, docs/CLI-TOOLS.md at repo root

Environment

Variable Purpose
GSD_QUERY_FALLBACK off / never disables CLI fallback to gsd-tools.cjs for unknown commands
GSD_AGENTS_DIR Override directory scanned for installed GSD agents (~/.claude/agents by default)