Commit Graph

27 Commits

Author SHA1 Message Date
Tom Boucher
06cf7826e3 test: deepen fixture module v2 for reliability (#329)
* test: deepen fixture seam for init/state/workstream suites

* test: deepen fixture module v2 with declarative builders
2026-05-26 11:23:42 -04:00
Tom Boucher
936cf26706 fix(#2769): tolerate Requirements header with colon inside bold delimiters (#2782)
* fix(#2769): tolerate Requirements header with colon inside bold delimiters

extractReqIds in sdk/src/query/init.ts and the legacy init.cjs port only
matched `**Requirements**:` (colon outside bold), so phases declared with
the equally-valid markdown form `**Requirements:**` (colon inside bold,
which is what the project's own templates emit) returned phase_req_ids:
null for both `init plan-phase` and `init execute-phase`.

The mirror-image bug in `phase complete`'s REQUIREMENTS.md traceability
sweep at get-shit-done/bin/lib/phase.cjs:871 only matched the inside-bold
form, silently skipping the REQ-ID checkbox flips for any roadmap that
used the outside-bold form. Both parsers now share the same canonical
regex that accepts all three rendered-identical variants:

  **Requirements:**     (colon inside bold)
  **Requirements**:     (colon outside bold)
  **Requirements** :    (space before outside colon)

Tests:
- tests/init.test.cjs — parameterized over the three header variants for
  both init plan-phase and init execute-phase (6 new behavioral cases).
- sdk/src/query/init.test.ts — describe.each over the same variants
  exercising initPlanPhase through the SDK.
- tests/bug-2769-requirements-header-variants.test.cjs — phase complete
  flips REQ-001 in REQUIREMENTS.md across all three header variants.

Closes #2769

* refactor(#2769): centralize REQUIREMENTS_HEADER_RE constant per CodeRabbit
2026-04-27 12:31:49 -04:00
Tom Boucher
5afcd5577e fix: zero-padded phase numbers bypass archived-phase guard; stale current_milestone (#2458)
* fix(sdk): extractCurrentMilestone Backlog leak + state.begin-phase flag parsing

Closes #2422
Closes #2420

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

* fix(sdk): skip stateVersion early-return for shipped milestones

When STATE.md has a stale `milestone: v1.0` entry but v1.0 is already
shipped (heading contains ✅ in ROADMAP.md), the stateVersion early-return
path in getMilestoneInfo was returning v1.0 instead of detecting the new
active milestone.

Two-part fix:
1. In the stateVersion block: skip the early-return when the matched
   heading line includes ✅ (shipped marker). Fall through to normal
   detection instead.
2. In the heading-format fallback regex: add a negative lookahead
   `(?!.*✅)` so the regex never matches a ✅ heading regardless of
   whether stateVersion was present. This handles the no-STATE.md case
   and ensures fallthrough from part 1 actually finds the next milestone.

Adds two regression tests covering both ✅-suffix (`## v1.0 ✅ Name`)
and ✅-prefix (`## ✅ v1.0 Name`) heading formats.

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

* fix(core): allow padded-and-unpadded phase headings in getRoadmapPhaseInternal

The zero-strip normalization (01→1) fixed the archived-phase guard but
broke lookup against ROADMAP headings that still use zero-padded numbers
like "Phase 01:". Change the regex to use 0*<normalized> so both formats
match, making the fix robust regardless of ROADMAP heading style.

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 10:08:40 -04:00
Tom Boucher
55877d372f feat(handoffs): include project identity in all Next Up blocks (#1948) (#2287)
* feat(handoffs): include project identity in all Next Up blocks

Adds project_code and project_title to withProjectRoot() and updates
all 30 Next Up headings across 18 workflow files to include
[PROJECT_CODE] PROJECT_TITLE suffix for multi-project clarity.

Closes #1948

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(review): add withProjectRoot tests and fix placeholder syntax (#1951)

Address code review feedback:
- Add 4 tests for project_code/project_title injection in withProjectRoot()
- Fix inconsistent placeholder syntax in continuation-format.md canonical
  template (bare-brace → shell-dollar to match variant examples)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(phase): preserve zero-padded prefix in renameDecimalPhases

Captures the zero-padded prefix (e.g. "06" from "06.3-slug") with
(0*${baseInt}) so renamed directories keep their original format
(06.2-slug) instead of stripping padding (6.2-slug).

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

---------

Co-authored-by: Brandon Higgins <brandonscotthiggins@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 16:43:02 -04:00
Tom Boucher
875b257c18 fix(init): embed auto_advance/auto_chain_active/mode in init plan-phase output (#2228)
Prevents infinite config-get loops on Kimi K2.5 and other models that
re-execute bash tool calls when they encounter config-get subshell patterns.
Values are now bundled into the init plan-phase JSON so step 15 of
plan-phase.md can read them directly without separate shell calls.

Closes #2192

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 14:59:15 -04:00
Gabriel Rodrigues Garcia
e6e33602c3 fix(init): ignore archived phases from prior milestones sharing a phase number (#2186)
When a new milestone reuses a phase number that exists in an archived
milestone (e.g., v2.0 Phase 2 while v1.0-phases/02-old-feature exists),
findPhaseInternal falls through to the archive and returns the old
phase. init plan-phase and init execute-phase then emitted archived
values for phase_dir, phase_slug, has_context, has_research, and
*_path fields, while phase_req_ids came from the current ROADMAP —
producing a silent inconsistency that pointed downstream agents at a
shipped phase from a previous milestone.

cmdInitPhaseOp already guarded against this (see lines 617-642);
apply the same guard in cmdInitPlanPhase, cmdInitExecutePhase, and
cmdInitVerifyWork: if findPhaseInternal returns an archived match
and the current ROADMAP.md has the phase, discard the archived
phaseInfo so the ROADMAP fallback path produces clean values.

Adds three regression tests covering plan-phase, execute-phase, and
verify-work under the shared-number scenario.
2026-04-13 10:59:11 -04:00
Tom Boucher
2703422be8 refactor(tests): standardize to node:assert/strict and t.after() per CONTRIBUTING.md (#1675)
* refactor(tests): standardize to node:assert/strict and t.after() per CONTRIBUTING.md

- Replace require('node:assert') with require('node:assert/strict') across
  all 73 test files to enforce strict equality (no type coercion)
- Replace try/finally cleanup blocks with t.after() hooks in core.test.cjs
  and hooks-opt-in.test.cjs per the test lifecycle standards
- Utility functions in codex-config and security-scan retain try/finally
  as that is appropriate for per-function resource guards, not lifecycle hooks

Closes #1674

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

* perf(tests): add --test-concurrency=4 to test runner for parallel file execution

Node.js --test-concurrency controls how many test files run as parallel child
processes. Set to 4 by default, configurable via TEST_CONCURRENCY env var.
Fixes tests at a known level rather than inheriting os.availableParallelism()
which varies across CI environments.

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

* fix(security): allowlist verify.test.cjs in prompt-injection scanner

tests/verify.test.cjs uses <human>...</human> as GSD phase task-type
XML (meaning "a human should verify this step"), which matches the
scanner's fake-message-boundary pattern for LLM APIs. This is a
false positive — add it to the allowlist alongside the other test files
that legitimately contain injection-adjacent patterns.

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 14:29:03 -04:00
Tom Boucher
00e0446b99 fix: four bug fixes — bold plan checkboxes, BACKLOG recommendations, executor_model regression tests, session_id path traversal
- fix(#1572): phase complete now marks bold-wrapped plan checkboxes in ROADMAP.md
  (`- [ ] **01-01**` format) by allowing optional `**` around plan IDs in the
  planCheckboxPattern regex in both phase.cjs and roadmap.cjs

- fix(#1569): manager init no longer recommends 999.x (BACKLOG) phases as next
  actions; add guard in cmdManagerInit that skips phases matching /^999(?:\.|$)/

- fix(#1568): add regression tests confirming init execute-phase respects
  model_overrides for executor_model, including when resolve_model_ids is 'omit'

- fix(#1533): reject session_id values containing path traversal sequences
  (../,  /, \) in gsd-context-monitor and gsd-statusline before constructing
  /tmp file paths; add security tests covering both hooks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 11:30:08 -04:00
Tom Boucher
03a711bef7 fix: update map-codebase test for refactored workflow
The map-codebase workflow was refactored to remove the explicit
"Runtimes with Task tool" line in favor of inline detection instructions.
Updated test to match the new workflow structure by checking the
"NOT available" condition line instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:10:07 -04:00
Tom Boucher
dbc5b2ab87 fix: expand brownfield project detection to cover Android, Kotlin, Gradle, and 15+ additional ecosystems
The code/package detection in cmdInitNewProject only recognized 7 file
extensions and 5 package files, missing Android (Kotlin + Gradle), Flutter
(Dart + pubspec.yaml), C/C++, C#, Ruby, PHP, Scala, and others. This caused
new-project to treat brownfield projects in those ecosystems as greenfield,
skipping the codebase mapping step.

Added 18 code extensions and 11 package/build files to the detection lists.

Fixes #1325

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 14:19:30 -04:00
Tom Boucher
d86c3a9e35 fix: list OpenCode as runtime with Task tool support in map-codebase
OpenCode has a `task` tool that supports spawning subagents, but
map-codebase workflow incorrectly listed it under "Runtimes WITHOUT
Task tool". This caused the agent to skip parallel mapping and fall
back to sequential mode, wasting tokens when it self-corrected.

Move OpenCode to the "with Task tool" list and clarify that either
`Task` or `task` (case-insensitive) qualifies. Add regression test.

Fixes #1316

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 11:27:59 -04:00
Tom Boucher
65aed734e9 fix: handle missing config.json in text_mode test
The test tried to fs.readFileSync on config.json which doesn't exist
in createTempProject() fixtures. Now gracefully creates the config
from scratch when the file is missing.

Co-Authored-By: GhadiSaab <GhadiSaab@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 11:21:43 -04:00
Ghadi Saab
a74e6b1e94 fix: add text_mode support to plan-phase workflow
`workflow.text_mode: true` (or `--text` flag) now applies to
plan-phase, not just discuss-phase. Fixes #1313.

Changes:
- `init plan-phase` now exposes `text_mode` from config in its JSON output
- plan-phase workflow parses `--text` flag and resolves TEXT_MODE from
  init JSON or flag, whichever is set
- All four AskUserQuestion call sites (no-context gate, research prompt,
  UI design contract gate, requirements coverage gap) now conditionally
  present as plain-text numbered lists when TEXT_MODE is active
- `--text` added to plan-phase command argument-hint and flags docs
- Tests added for init output and workflow references

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 11:21:43 -04:00
Chris Esposito
71aedb28d5 test: add init tests for has_reviews and reviews_path
- Test that has_reviews=true and reviews_path is set when REVIEWS.md exists
- Test that reviews_path is undefined and has_reviews=false when missing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 20:44:24 -04:00
Tom Boucher
1063fdf1ad fix(init): add ROADMAP fallback to plan-phase, execute-phase, and verify-work (#1238)
cmdInitPlanPhase, cmdInitExecutePhase, and cmdInitVerifyWork returned
phase_found: false when the phase existed in ROADMAP.md but no phase
directory had been created yet. This caused workflows to fail silently
after /gsd:new-project, producing directories named null-null.

cmdInitPhaseOp (used by discuss-phase) already had a ROADMAP fallback.
Applied the same pattern to the three missing commands: when
findPhaseInternal returns null, fall back to getRoadmapPhaseInternal
and construct phaseInfo from the ROADMAP entry.

Added 5 regression tests covering:
- plan-phase ROADMAP fallback
- execute-phase ROADMAP fallback
- verify-work ROADMAP fallback
- phase_found false when neither directory nor ROADMAP entry exists
- disk directory preferred over ROADMAP fallback
2026-03-20 10:38:57 -04:00
Srinivas Koduri
21081dc821 feat: multi-repo workspace support with auto-detection and project root resolution
Add support for workspaces with multiple independent git repositories.
When configured, GSD routes commits to the correct sub-repo and ensures
.planning/ stays at the project root.

Core features:
- detectSubRepos(): scans child directories for .git to discover repos
- findProjectRoot(): walks up from CWD to find the project root that
  owns .planning/, preventing orphaned .planning/ in sub-repos
- loadConfig auto-syncs sub_repos when repos are added or removed
- Migrates legacy "multiRepo: true" to sub_repos array automatically
- All init commands include project_root in output
- cmdCommitToSubrepo: groups files by sub-repo prefix, commits independently

Zero impact on single-repo workflows — sub_repos defaults to empty array.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 12:18:20 -07:00
Tom Boucher
841da5a80d Merge pull request #1155 from gsd-build/Solvely/quick-task-branching
feat(quick): add quick-task branch support
2026-03-19 12:03:58 -04:00
Colin
3a0c81133b feat(quick): add quick-task branch support 2026-03-17 12:04:02 -04:00
Colin
52b2d390cc feat(milestones): support safe phase-number resets 2026-03-17 11:00:24 -04:00
Colin Johnson
6de816f68c fix(init): prefer current milestone phase-op targets (#1068) 2026-03-15 19:30:28 -06:00
闫冰
75d21866c8 feat(quick): replace auto-increment number with YYMMDD-xxx timestamp ID (#1012)
Quick task IDs were sequential integers (001, 002...) computed by reading
the local .planning/quick/ directory max value. Two users running /gsd:quick
simultaneously would get the same number, causing directory collisions on git.

Replace with a collision-resistant format: YYMMDD-xxx where xxx is the
number of 2-second blocks elapsed since midnight, encoded as 3 lowercase
Base36 characters (000–xbz). Practical collision window is ~2 seconds per
user — effectively zero for any realistic team workflow.

- init.cjs: remove nextNum scan logic, generate quickId from wall clock
- quick.md: rename all next_num refs to quick_id, update directory patterns
- init.test.cjs: rewrite cmdInitQuick tests for new ID format

Co-authored-by: yanbing <yanbing@corp.netease.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 11:35:59 -06:00
Lex Christopherson
011df21dd0 fix(test): expect forward-slash paths in cmdInitTodos assertion
The source now outputs posix paths; update the test to match instead
of using path.join (which produces backslashes on Windows).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 11:38:24 -06:00
Ethan Hurst
ec943fec72 test(08-02): add cmdInitProgress, cmdInitQuick, cmdInitMapCodebase, cmdInitNewProject, cmdInitNewMilestone tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 05:47:33 +10:00
Ethan Hurst
add7799cee test(08-01): add cmdInitTodos, cmdInitMilestoneOp, cmdInitPhaseOp fallback tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 05:47:33 +10:00
Lex Christopherson
acb76fee16 test: add TBD guard coverage for phase_req_ids extraction
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 09:35:43 -06:00
dush999
ea3c22d345 fix: propagate phase_req_ids from ROADMAP to workflow agents (#684) (#702)
Added TBD guard test before merge.
2026-02-23 09:35:28 -06:00
Tyler Satre
fa2e156887 refactor: split gsd-tools.test.cjs into domain test files
Move 81 tests (18 describe blocks) from single monolithic test file
into 7 domain-specific test files under tests/ with shared helpers.
Test parity verified: 81/81 pass before and after split.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 10:30:54 -05:00