Files
msd-core/docs/ja-JP/superpowers/specs/2026-03-20-multi-project-workspaces-design.md
Tom Boucher 3aaed8f5d7 test: replace deny-list parity tests with polarity-inverted live-registry (#3049) (#3284)
* test: reproduce Windows SDK not found after fresh npx install (#3211)

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

* test: red — docs-parity live-registry tests fail against stub helper (#3049)

Adds:
- tests/helpers/live-command-registry.cjs (stub: returns empty Set)
- tests/docs-parity-live-registry.test.cjs (new polarity-inverted test)
- tests/fixtures/live-command-registry/ (fixture .md files)

All parity and helper-contract tests fail because the stub returns an
empty registry. This is the intentional RED state before GREEN
implementation.

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

* feat(test-helpers): live-command-registry derives canonical tokens from commands/gsd/*.md (#3049)

Implements GREEN phase:
- tests/helpers/live-command-registry.cjs: walks commands/gsd/*.md, parses
  YAML frontmatter name: field, emits /gsd-slug, /gsd:slug, $gsd-slug per
  command. Memoized per process. Fails loud on malformed frontmatter (k302).
- tests/docs-parity-live-registry.test.cjs: updated with INTERNAL_COMPONENT_SLUGS
  exemption for path-component and placeholder tokens (gsd-build from GitHub
  org URLs, gsd-workspaces from ~/gsd-workspaces/ paths, gsd-tools from
  bin/gsd-tools.cjs paths, etc.)

Docs drift caught and fixed:
- ns-* rename: /gsd-ns-workflow→/gsd-workflow etc. in COMMANDS, FEATURES,
  INVENTORY, USER-GUIDE (6 commands across 4 English files)
- /gsd-scan → /gsd-map-codebase --fast (FEATURES, INVENTORY, USER-GUIDE)
- /gsd-note → /gsd-capture (FEATURES, issue-driven-orchestration, ja-JP, ko-KR)
- /gsd-do → /gsd-fast (FEATURES, ja-JP, ko-KR)
- /gsd-from-gsd2 → /gsd-import --from-gsd2 (CLI-TOOLS, FEATURES, INVENTORY)
- /gsd-verify-phase → /gsd-validate-phase (STATE-MD-LIFECYCLE)
- /gsd-settings-integrations → /gsd-settings or /gsd-config --integrations (CLI-TOOLS)
- /gsd-dev-preferences removed from profile-user artifact lists (AGENTS, COMMANDS,
  FEATURES in English, ja-JP, ko-KR)
- /gsd-select-framework removed from gsd-framework-selector spawner list
  (AGENTS, INVENTORY)

All 28 new tests pass.

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

* refactor(test): replace deny-list parity tests with polarity-inverted live-registry approach (#3049)

- Delete bug-3010-reapply-patches-references.test.cjs (hardcoded deny-list)
- Delete bug-3029-3034-stale-command-routes.test.cjs (hardcoded deny-list)
- Delete bug-3042-3044-research-flag-and-stale-refs.test.cjs (deny-list + frontmatter checks)
- Add tests/skill-frontmatter-contract.test.cjs (frontmatter structural checks extracted from deleted file)
- Update tests/commands-doc-parity.test.cjs to derive slug from name: frontmatter field
  instead of filename, so ns-* commands resolve to their actual deployed tokens

Closes #3049

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

* test: annotate commands-doc-parity with source-text-is-the-product exemption (#3049 lint fix)

The readFileSync on commands/gsd/*.md reads product markdown whose deployed
text IS what the user sees — content.startsWith('---') detects YAML frontmatter
in those files, not source-code structure. Add the allow-test-rule exemption
matching the same rationale used in docs-parity-live-registry.test.cjs.

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

* test: walk docs/** recursively to cover nested locale trees (CR finding 7)

Replaced the non-recursive listMdFiles() with a hand-rolled DFS walker
compatible with Node 20+. Surfaces unreadable-directory errors as stderr
warnings (PRED.k302) rather than silently skipping.

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

* test: annotate live-command-registry helper and commands-doc-parity with source-text exemptions (CR findings 6, 8)

Adds allow-test-rule comments to suppress lint-no-source-grep false
positives on YAML frontmatter structure checks in both files.

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

* test: anchor --research-phase assertions to arg-parsing section and verify combined refresh (CR findings 9, 10)

Finding 9: scopes --research-phase check to within 1200 chars of the flag
description section header, preventing false positives from prose mentions.

Finding 10: tightens the force-refresh assertion to require BOTH --research
and force/refresh semantics within the --research-phase description section,
verifying the combined-mode contract rather than standalone --research presence.

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

* test: fix execSync mock to accept opts parameter, forward to saved implementation (CR finding 5)

The mock at line 212 dropped the options parameter when delegating to
savedExecSync. Updated to (cmd, opts) signature and pass opts through.

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

* docs: correct routing entrypoint, --fast default, /gsd-review collision, verifying-stage mapping (CR findings 1-4)

Finding 1: Change Freeform Routing command from /gsd-fast to /gsd-progress --do.
/gsd-fast is the inline trivial-task executor, not the routing entrypoint.

Finding 2: Clarify that /gsd-map-codebase --fast REQ-SCAN-02 default (tech+arch)
runs as a single combined-focus agent, resolving the contradiction with REQ-SCAN-01.

Finding 3: Rename the namespace router /gsd-review to /gsd-quality across all docs,
command file, and help.md to eliminate the naming collision with the concrete
cross-AI peer-review command (review.md, name: gsd:review).

Finding 4: Replace /gsd-validate-phase with /gsd-verify-work in the STATE-MD-LIFECYCLE.md
verifying-stage table. /gsd-validate-phase is the retroactive Nyquist-validation
flow, not the normal phase-verification step.

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

* docs+test: fix locale doc drift surfaced by recursive walker (CR finding 7 follow-up)

The recursive listMdFiles() walker newly covered docs/**/*.md subdirs.
Stale command references in locale docs are now caught and fixed:

- docs/zh-CN/references/model-profiles.md: remove /gsd-set-profile (deleted command);
  config.json is the current mechanism
- docs/zh-CN/references/ui-brand.md: remove /gsd-alternative-1/2 template placeholders
- docs/{ja-JP,ko-KR,pt-BR}/superpowers/specs/2026-03-20-*: replace
  /gsd-new-workspace, /gsd-list-workspaces, /gsd-remove-workspace with
  /gsd-workspace --new / --list / --remove (consolidated in #2790)

Also adds smoke- and alternative-{1,2} to INTERNAL_COMPONENT_SLUGS (filesystem
path and template placeholder patterns, not slash commands) and introduces
listEnglishMdFiles() to scope the English parity check to docs/ excluding
locale subdirectories (which have their own per-locale describe blocks).

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

* docs: add bash language tag to fenced code blocks in ja-JP and ko-KR workspace specs (CR round 2)

Satisfies MD040 fenced-code-language requirement. These blocks contain
shell commands and were missing the language specifier.

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 02:49:19 -04:00

12 KiB
Raw Blame History

マルチプロジェクトワークスペース (/gsd-workspace --new)

Issue: #1241 Date: 2026-03-20 Status: Approved

課題

GSD は作業ディレクトリごとに1つの .planning/ ディレクトリに紐づいています。複数の独立したプロジェクトを持つユーザー(20以上の子リポジトリを含むモノレポ構成など)や、同一リポジトリ内でフィーチャーブランチの分離が必要なユーザーは、手動でのクローンや状態管理なしに並行して GSD セッションを実行することができません。

解決策

3つの新しいコマンドで物理的なワークスペースディレクトリを作成・一覧表示・削除します。各ワークスペースにはリポジトリのコピー(git worktree またはクローン)と独立した .planning/ ディレクトリが含まれます。

これにより2つのユースケースに対応します:

  • マルチリポジトリオーケストレーション (A): 親ディレクトリから複数のリポジトリにまたがるワークスペース
  • フィーチャーブランチの分離 (B): 現在のリポジトリの worktree を含むワークスペース(--repos . を使用した A の特殊ケース)

コマンド

/gsd-workspace --new

リポジトリのコピーと独自の .planning/ を持つワークスペースディレクトリを作成します。

/gsd-workspace --new --name feature-b --repos hr-ui,ZeymoAPI --path ~/workspaces/feature-b
/gsd-workspace --new --name feature-b --repos . --strategy worktree   # same-repo isolation

引数:

フラグ 必須 デフォルト 説明
--name はい — ワークスペース名
--repos いいえ 対話的な選択 カンマ区切りのリポジトリパスまたは名前
--path いいえ ~/gsd-workspaces/<name> 出力先ディレクトリ
--strategy いいえ worktree worktree(軽量、.git を共有)または clone(完全に独立)
--branch いいえ workspace/<name> チェックアウトするブランチ
--auto いいえ false 対話的な質問をスキップし、デフォルト値を使用

/gsd-workspace --list

~/gsd-workspaces/*/WORKSPACE.md をスキャンしてワークスペースマニフェストを検索します。名前、パス、リポジトリ数、GSD ステータス(PROJECT.md の有無、現在のフェーズ)をテーブル形式で表示します。

/gsd-workspace --remove

確認後にワークスペースディレクトリを削除します。worktree 戦略の場合、まず各メンバーリポジトリに対して git worktree remove を実行します。コミットされていない変更があるリポジトリがある場合は削除を拒否します。

ディレクトリ構造

~/gsd-workspaces/feature-b/          # workspace root
├── WORKSPACE.md                      # manifest
├── .planning/                        # independent GSD planning directory
│   ├── PROJECT.md                    # (if user ran /gsd-new-project)
│   ├── STATE.md
│   └── config.json
├── hr-ui/                            # git worktree of source repo
│   └── (repo contents on workspace/feature-b branch)
└── ZeymoAPI/                         # git worktree of source repo
    └── (repo contents on workspace/feature-b branch)

主要な特性:

  • .planning/ はワークスペースのルートに配置され、個々のリポジトリ内には配置されない
  • 各リポジトリはワークスペースルート直下の対等なディレクトリ
  • WORKSPACE.md はルートにある唯一の GSD 固有ファイル(.planning/ を除く)
  • --strategy clone の場合も同じ構造だが、リポジトリは完全なクローンとなる

WORKSPACE.md のフォーマット

# Workspace: feature-b

Created: 2026-03-20
Strategy: worktree

## Member Repos

| Repo | Source | Branch | Strategy |
|------|--------|--------|----------|
| hr-ui | /root/source/repos/hr-ui | workspace/feature-b | worktree |
| ZeymoAPI | /root/source/repos/ZeymoAPI | workspace/feature-b | worktree |

## Notes

[User can add context about what this workspace is for]

ワークフロー

/gsd-workspace --new のワークフロー手順

  1. セットアップ — init new-workspace を呼び出し、JSON コンテキストを解析する
  2. 入力の収集 — --name/--repos/--path が指定されていない場合、対話的に質問する。リポジトリの選択時は、カレントディレクトリ内の子 .git ディレクトリを選択肢として表示する
  3. バリデーション — 出力先パスが存在しない(または空である)こと。ソースリポジトリが存在し、git リポジトリであることを確認する
  4. ワークスペースディレクトリの作成 — mkdir -p <path>
  5. リポジトリのコピー — 各リポジトリについて:
    • Worktree: git worktree add <workspace>/<repo-name> -b workspace/<name>
    • Clone: git clone <source> <workspace>/<repo-name>
  6. WORKSPACE.md の書き込み — ソースパス、戦略、ブランチを含むマニフェスト
  7. .planning/ の初期化 — mkdir -p <workspace>/.planning
  8. /gsd-new-project の提案 — 新しいワークスペースでプロジェクト初期化を実行するか確認する
  9. コミット — commit_docs が有効な場合、WORKSPACE.md のアトミックコミット
  10. 完了 — ワークスペースのパスと次のステップを表示する

Init 関数 (cmdInitNewWorkspace)

検出項目:

  • カレントディレクトリ内の子 git リポジトリ(対話的なリポジトリ選択用)
  • 出力先パスが既に存在するかどうか
  • ソースリポジトリにコミットされていない変更があるかどうか
  • git worktree が利用可能かどうか
  • デフォルトのワークスペースベースディレクトリ (~/gsd-workspaces/)

ワークフローの分岐制御用フラグを含む JSON を返します。

エラーハンドリング

バリデーションエラー(作成をブロック)

  • 出力先パスが存在し、空でない場合 — 別の名前/パスを選択するよう提案するエラー
  • ソースリポジトリのパスが存在しない、または git リポジトリでない場合 — 失敗したリポジトリを一覧表示するエラー
  • git worktree add が失敗した場合(例:ブランチが既に存在する) — workspace/<name>-<timestamp> ブランチにフォールバックし、それも失敗した場合はエラー

グレースフルハンドリング

  • ソースリポジトリにコミットされていない変更がある場合 — 警告するが許可する(worktree はブランチを新規にチェックアウトし、作業ディレクトリの状態はコピーしない)
  • マルチリポジトリワークスペースでの部分的な失敗 — 成功したリポジトリでワークスペースを作成し、失敗を報告し、部分的な WORKSPACE.md を書き込む
  • --repos .(現在のリポジトリ、ケース B) — ディレクトリ名または git remote からリポジトリ名を検出し、サブディレクトリ名として使用する

Remove-Workspace の安全性

  • ワークスペース内のリポジトリにコミットされていない変更がある場合 — 削除を拒否し、変更のあるリポジトリを表示する
  • Worktree の削除が失敗した場合(例:ソースリポジトリが削除されている) — 警告し、ディレクトリのクリーンアップを続行する
  • 確認 — ワークスペース名を入力する明示的な確認を要求する

List-Workspaces のエッジケース

  • ~/gsd-workspaces/ が存在しない場合 — 「ワークスペースが見つかりません」
  • WORKSPACE.md は存在するが、内部のリポジトリがなくなっている場合 — ワークスペースを表示し、リポジトリを欠落としてマークする

テスト

ユニットテスト (tests/workspace.test.cjs)

  1. cmdInitNewWorkspace が正しい JSON を返す — 子 git リポジトリの検出、出力先パスのバリデーション、git worktree の利用可能性の検出
  2. WORKSPACE.md の生成 — リポジトリテーブル、戦略、日付を含む正しいフォーマット
  3. リポジトリの検出 — カレントディレクトリの子要素内の .git ディレクトリを識別し、git 以外のディレクトリやファイルをスキップする
  4. バリデーション — 既存の空でない出力先パスを拒否し、git リポジトリでないソースパスを拒否する

統合テスト(同一ファイル)

  1. Worktree の作成 — ワークスペースを作成し、リポジトリディレクトリが有効な git worktree であることを検証する
  2. クローンの作成 — ワークスペースを作成し、リポジトリが独立したクローンであることを検証する
  3. ワークスペースの一覧表示 — 2つのワークスペースを作成し、一覧出力に両方が含まれることを検証する
  4. ワークスペースの削除 — worktree でワークスペースを作成し、削除してクリーンアップを検証する
  5. 部分的な失敗 — 有効なリポジトリ1つと無効なパス1つで、有効なリポジトリのみでワークスペースが作成されることを検証する

すべてのテストは一時ディレクトリを使用し、終了時にクリーンアップします。既存の node:test + node:assert パターンに従います。

実装ファイル

コンポーネント パス
コマンド: new-workspace commands/gsd/new-workspace.md
コマンド: list-workspaces commands/gsd/list-workspaces.md
コマンド: remove-workspace commands/gsd/remove-workspace.md
ワークフロー: new-workspace get-shit-done/workflows/new-workspace.md
ワークフロー: list-workspaces get-shit-done/workflows/list-workspaces.md
ワークフロー: remove-workspace get-shit-done/workflows/remove-workspace.md
Init 関数 get-shit-done/bin/lib/init.cjs(cmdInitNewWorkspace、cmdInitListWorkspaces、cmdInitRemoveWorkspace を追加)
ルーティング get-shit-done/bin/gsd-tools.cjs(init switch にケースを追加)
テスト tests/workspace.test.cjs

設計上の決定

決定事項 根拠
論理的なレジストリではなく物理ディレクトリを採用 ファイルシステムを信頼の源とする — GSD の既存の cwd ベースの検出パターンと一致する
Worktree をデフォルト戦略とする 軽量(.git オブジェクトを共有)、作成が高速、クリーンアップが容易
.planning/ をワークスペースルートに配置 個々のリポジトリの planning から完全に分離できる。各ワークスペースは独立した GSD プロジェクトとなる
中央レジストリを使用しない 状態の乖離を回避する。list-workspaces はファイルシステムを直接スキャンする
ケース B を A の特殊ケースとする --repos . で同じ仕組みを再利用し、フィーチャーブランチ専用のコードが不要
デフォルトパスを ~/gsd-workspaces/<name> とする list-workspaces がスキャンしやすい予測可能な場所に配置し、ワークスペースをソースリポジトリの外に保つ