diff --git a/.changeset/steady-mice-frolic.md b/.changeset/steady-mice-frolic.md new file mode 100644 index 000000000..d5bb4f8d6 --- /dev/null +++ b/.changeset/steady-mice-frolic.md @@ -0,0 +1,5 @@ +--- +type: Added +pr: 1994 +--- +**`/gsd:onboard` guides brownfield setup** — existing repos now have a top-level onboarding command that routes through codebase mapping, docs ingest, project initialization, and an onboarding summary without silently overwriting planning files. diff --git a/.gitignore b/.gitignore index 9562ecd17..c44176af8 100644 --- a/.gitignore +++ b/.gitignore @@ -192,6 +192,7 @@ build/ /gsd-core/bin/lib/eval.cjs /gsd-core/bin/lib/eval-command-router.cjs /gsd-core/bin/lib/init-command-router.cjs +/gsd-core/bin/lib/onboard-projection.cjs /gsd-core/bin/lib/agent-command-router.cjs /gsd-core/bin/lib/agent-install-check.cjs /gsd-core/bin/lib/task-command-router.cjs diff --git a/CONTEXT.md b/CONTEXT.md index 02e92c938..fa1df0b0b 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -68,7 +68,7 @@ Canonical command normalization and resolution Interface (`query-command-resolut Module owning command resolution, policy projection (`mutation`, `output_mode`), unknown-command diagnosis, and handler Adapter binding at one seam for query dispatch. ### Init Command Module -Module owning the `init.*` family of query handlers that compose atomic queries into the flat JSON bundles consumed by init workflows (`/gsd-execute-phase`, `/gsd-plan-phase`, `/gsd-verify-work`, `/gsd-new-project`, `/gsd-manager`, `/gsd-progress`, `/gsd-resume`, etc.). Source of truth: `gsd-core/bin/lib/init.cjs` — the basic handlers (plus `withProjectRoot` project-identity injection) and the 3 heavyweight handlers (`initNewProject`, `initProgress`, `initManager`). All handlers return `{ data: }`. Test seams: `tests/init.test.cjs` and `tests/init-manager.test.cjs` (cover withProjectRoot precedence, progress/manager precedence regression #2674, workstream scoping regression #3196, and cross-milestone dependency regression #2267). (The SDK `handlers/init/*.ts` sources and the `init*.test.ts` seams were retired with the SDK package per ADR-0174.) +Module owning the `init.*` family of query handlers that compose atomic queries into the flat JSON bundles consumed by init workflows (`/gsd-execute-phase`, `/gsd-plan-phase`, `/gsd-verify-work`, `/gsd-new-project`, `/gsd-onboard`, `/gsd-manager`, `/gsd-progress`, `/gsd-resume`, etc.). Source of truth: `src/init.cts` and the compiled `gsd-core/bin/lib/init.cjs`; onboarding routing readiness lives in `src/onboard-projection.cts`. The basic handlers (plus `withProjectRoot` project-identity injection) and the heavyweight handlers (`initNewProject`, `initOnboard`, `initProgress`, `initManager`) return `{ data: }`. Test seams: `tests/init.test.cjs`, `tests/onboard-command.test.cjs`, and `tests/init-manager.test.cjs` (cover withProjectRoot precedence, onboarding projection/rendering, progress/manager precedence regression #2674, workstream scoping regression #3196, and cross-milestone dependency regression #2267). (The SDK `handlers/init/*.ts` sources and the `init*.test.ts` seams were retired with the SDK package per ADR-0174.) ### Command Routing Hub Single dispatch seam (`gsd-core/bin/lib/command-routing-hub.cjs`) that centralizes CJS routing, the no-throw pure-result contract, typed error variants, and dispatch-event emission for all command family adapters. Interface: `createHub({ cjsRegistry, manifest, logger }) → hub`; `hub.dispatch({ family, subcommand, args, cwd, raw, parentTraceId? }) → Result` where `Result = { ok: true, data } | { ok: false, kind, ...typedPayload }` and `kind ∈ { UnknownCommand, InvalidArgs, HandlerRefusal, HandlerFailure }`. The `InvalidArgs` variant carries an optional `exitReason?: string` field (amendment #1642 / #1644 Phase 1) holding the `ERROR_REASON` enum value, separate from `reason` (the explanation text); the `makeInvalidArgs(arg, reason, exitReason?)` factory omits the field when the third arg is absent, undefined, or empty — preserving the strict-keys invariant tested at `tests/command-routing-hub.test.cjs:444`. The Hub is single-runtime (no mode selection, no sdkLoader), never prints, never exits, never throws. Adapters call `createHub`, dispatch, then translate the pure Result to `output()`/`error()` calls; when an `InvalidArgs` Result carries `exitReason`, the adapter passes it as the second arg to `error(message, exitReason)` so the JSON-error envelope (`GSD_JSON_ERRORS=1`) preserves the typed reason. Source: `gsd-core/bin/lib/command-routing-hub.cjs`; ADR: `docs/adr/0174-retire-gsd-sdk-package-boundary.md` (§5 amended #1642). diff --git a/README.ja-JP.md b/README.ja-JP.md index 449483459..e852c33b0 100644 --- a/README.ja-JP.md +++ b/README.ja-JP.md @@ -47,13 +47,14 @@ npx @opengsd/gsd-core@latest 別のランタイムをお使いの場合や Node.js がない場合は [ランタイムへのインストール](docs/ja-JP/how-to/install-on-your-runtime.md) を参照してください。 -インストール後、最初のプロジェクトを開始します。 +インストール後、新規プロジェクトを開始するか、既存リポジトリをオンボーディングします。 ```bash -/gsd-new-project +/gsd-new-project # グリーンフィールドプロジェクト +/gsd-onboard # 既存コードベース ``` -初めての方は [はじめてのプロジェクト](docs/ja-JP/tutorials/your-first-project.md) で、インストールから最初のフェーズ出荷までのガイド付きチュートリアルをご覧ください。 +初めての方は [はじめてのプロジェクト](docs/ja-JP/tutorials/your-first-project.md) で、インストールから最初のフェーズ出荷までのガイド付きチュートリアルをご覧ください。既存リポジトリの場合は [既存コードベースのオンボーディング](docs/ja-JP/tutorials/onboarding-an-existing-codebase.md) を参照してください。 --- diff --git a/README.ko-KR.md b/README.ko-KR.md index 3bef4570b..2d90f1a6e 100644 --- a/README.ko-KR.md +++ b/README.ko-KR.md @@ -47,13 +47,14 @@ npx @opengsd/gsd-core@latest 다른 런타임이나 Node.js가 없는 환경은 [런타임에 설치하기](docs/ko-KR/how-to/install-on-your-runtime.md)를 참조하세요. -설치 후 첫 번째 프로젝트를 시작합니다: +설치 후 새 프로젝트를 시작하거나 기존 저장소를 온보딩합니다: ```bash -/gsd-new-project +/gsd-new-project # 그린필드 프로젝트 +/gsd-onboard # 기존 코드베이스 ``` -처음 사용하시나요? [첫 번째 프로젝트](docs/ko-KR/tutorials/your-first-project.md)를 따라 설치부터 첫 단계 출시까지 안내받으세요. +처음 사용하시나요? [첫 번째 프로젝트](docs/ko-KR/tutorials/your-first-project.md)를 따라 설치부터 첫 단계 출시까지 안내받으세요. 기존 저장소라면 [기존 코드베이스 온보딩](docs/ko-KR/tutorials/onboarding-an-existing-codebase.md)을 참고하세요. --- diff --git a/README.md b/README.md index d18deabc7..9f5f08857 100644 --- a/README.md +++ b/README.md @@ -47,13 +47,14 @@ The installer prompts for your runtime (Claude Code, OpenCode, Antigravity CLI, On another runtime or without Node.js? See [Install on your runtime](docs/how-to/install-on-your-runtime.md). -Once installed, start your first project: +Once installed, start a new project or onboard an existing repo: ```bash -/gsd-new-project +/gsd-new-project # greenfield project +/gsd-onboard # existing codebase ``` -New here? Follow [Your first project](docs/tutorials/your-first-project.md) for a guided walkthrough from install to first shipped phase. +New here? Follow [Your first project](docs/tutorials/your-first-project.md) for a guided walkthrough from install to first shipped phase, or [Onboarding an existing codebase](docs/tutorials/onboarding-an-existing-codebase.md) for brownfield setup. --- diff --git a/README.pt-BR.md b/README.pt-BR.md index 91c6de96e..96c0c9ada 100644 --- a/README.pt-BR.md +++ b/README.pt-BR.md @@ -47,13 +47,14 @@ O instalador solicita seu ambiente de execução (Claude Code, OpenCode, Gemini Em outro runtime ou sem Node.js? Consulte [Instalar no seu runtime](docs/pt-BR/how-to/install-on-your-runtime.md). -Após a instalação, inicie seu primeiro projeto: +Após a instalação, inicie um projeto novo ou integre um repositório existente: ```bash -/gsd-new-project +/gsd-new-project # projeto greenfield +/gsd-onboard # base de código existente ``` -É a primeira vez? Siga [Seu primeiro projeto](docs/pt-BR/tutorials/your-first-project.md) para um passo a passo guiado, desde a instalação até a primeira fase entregue. +É a primeira vez? Siga [Seu primeiro projeto](docs/pt-BR/tutorials/your-first-project.md) para um passo a passo guiado, desde a instalação até a primeira fase entregue. Para um repositório existente, consulte [Integrar uma base de código existente](docs/pt-BR/tutorials/onboarding-an-existing-codebase.md). --- diff --git a/README.zh-CN.md b/README.zh-CN.md index 7e2831c54..993167e57 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -47,13 +47,14 @@ npx @opengsd/gsd-core@latest 使用其他运行时或没有 Node.js?请参阅[在你的运行时上安装](docs/zh-CN/how-to/install-on-your-runtime.md)。 -安装完成后,启动你的第一个项目: +安装完成后,启动一个新项目或接入现有仓库: ```bash -/gsd-new-project +/gsd-new-project # 新建项目 +/gsd-onboard # 现有代码库 ``` -初次使用?请按照[你的第一个项目](docs/zh-CN/tutorials/your-first-project.md)进行引导式操作,从安装到完成第一个交付阶段。 +初次使用?请按照[你的第一个项目](docs/zh-CN/tutorials/your-first-project.md)进行引导式操作,从安装到完成第一个交付阶段。对于现有仓库,请参阅[接入现有代码库](docs/zh-CN/tutorials/onboarding-an-existing-codebase.md)。 --- diff --git a/commands/gsd/map-codebase.md b/commands/gsd/map-codebase.md index b48db59a5..c11d56d69 100644 --- a/commands/gsd/map-codebase.md +++ b/commands/gsd/map-codebase.md @@ -9,7 +9,7 @@ allowed-tools: - Grep - Write - Agent -requires: [config, new-project, plan-phase] +requires: [config, new-project, plan-phase, onboard] --- @@ -42,7 +42,7 @@ Parse the first token of $ARGUMENTS: Check for .planning/STATE.md - loads context if project already initialized **This command can run:** -- Before /gsd:new-project (brownfield codebases) - creates codebase map first +- Via /gsd:onboard for first-time brownfield setup - creates codebase map first - After /gsd:new-project (greenfield codebases) - updates codebase map as code evolves - Anytime to refresh codebase understanding @@ -51,7 +51,7 @@ Check for .planning/STATE.md - loads context if project already initialized **Use map-codebase for:** - Brownfield projects before initialization (understand existing code first) - Refreshing codebase map after significant changes -- Onboarding to an unfamiliar codebase +- Refreshing or deepening an onboarded codebase map - Before major refactoring (understand current state) - When STATE.md references outdated codebase info @@ -71,7 +71,7 @@ Check for .planning/STATE.md - loads context if project already initialized 4. Wait for agents to complete, collect confirmations (NOT document contents) 5. Verify all 7 documents exist with line counts 6. Commit codebase map -7. Offer next steps (typically: /gsd:new-project or /gsd:plan-phase) +7. Offer next steps (typically: /gsd:onboard, /gsd:new-project, or /gsd:plan-phase) diff --git a/commands/gsd/ns-project.md b/commands/gsd/ns-project.md index 3deb4943f..ae6e1748a 100644 --- a/commands/gsd/ns-project.md +++ b/commands/gsd/ns-project.md @@ -5,7 +5,7 @@ argument-hint: "" allowed-tools: - Read - Skill -requires: [new-project, new-milestone, complete-milestone, audit-milestone, milestone-summary, import, ingest-docs, profile-user, review-backlog] +requires: [new-project, onboard, new-milestone, complete-milestone, audit-milestone, milestone-summary, import, ingest-docs, profile-user, review-backlog] --- Route to the appropriate project / milestone skill based on the user's intent. @@ -15,6 +15,7 @@ inline as part of `gsd-audit-milestone`'s output. | User wants | Invoke | |---|---| | Start a new project | gsd-new-project | +| Onboard an existing codebase | gsd-onboard | | Create a new milestone | gsd-new-milestone | | Complete the current milestone | gsd-complete-milestone | | Audit a milestone for issues | gsd-audit-milestone | diff --git a/commands/gsd/onboard.md b/commands/gsd/onboard.md new file mode 100644 index 000000000..e51fd9919 --- /dev/null +++ b/commands/gsd/onboard.md @@ -0,0 +1,46 @@ +--- +name: gsd:onboard +description: Guide existing codebase onboarding through mapping, doc ingest, and planning setup +argument-hint: "[--fast] [--text]" +allowed-tools: + - Read + - Bash + - Write + - Glob + - Grep + - Agent + - AskUserQuestion +requires: [config, new-project, map-codebase, ingest-docs, manager] +--- + +**Copilot (VS Code):** Use `vscode_askquestions` wherever this workflow calls `AskUserQuestion`. They are equivalent — `vscode_askquestions` is the VS Code Copilot implementation of the same interactive question API. + + + +Guide brownfield onboarding for an existing codebase by routing through the existing GSD primitives in the safe order: codebase map → docs ingest → project initialization → onboarding summary. + +**Creates or confirms:** +- `.planning/codebase/` — evidence-backed codebase map from `/gsd:map-codebase` +- `.planning/PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md`, `STATE.md` — project setup from `/gsd:new-project` or `/gsd:ingest-docs` +- `.planning/onboarding/SUMMARY.md` — lightweight index of what was learned and the next command + +**Non-goals:** This command does not execute phases, ship work, or overwrite existing planning artifacts without an explicit gate. + + + +@~/.claude/gsd-core/workflows/onboard.md +@~/.claude/gsd-core/references/ui-brand.md +@~/.claude/gsd-core/references/gate-prompts.md + + + +Arguments: $ARGUMENTS + +Flags: +- `--fast` — prefer `/gsd:map-codebase --fast` for the mapping handoff; the complete map is still required before `/gsd:new-project`. +- `--text` — use plain-text numbered lists instead of TUI menus. + + + +Execute the onboard workflow end-to-end. Preserve all safety gates, text-mode fallbacks, idempotency checks, and top-level handoff rules for nested interactive commands. + diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 07e25df3a..760409bcd 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -620,7 +620,8 @@ Equivalent paths for other runtimes: │ ├── FEATURES.md │ ├── ARCHITECTURE.md │ └── PITFALLS.md -├── codebase/ # Brownfield mapping (from /gsd-map-codebase) +├── codebase/ # Brownfield mapping (from /gsd-map-codebase or /gsd-onboard) +├── onboarding/ # Brownfield onboarding summary (from /gsd-onboard) │ ├── STACK.md # YAML frontmatter carries `last_mapped_commit` │ ├── ARCHITECTURE.md # for the post-execute drift gate (#2003) │ ├── CONVENTIONS.md diff --git a/docs/CLI-TOOLS.md b/docs/CLI-TOOLS.md index 392656603..923a1f757 100644 --- a/docs/CLI-TOOLS.md +++ b/docs/CLI-TOOLS.md @@ -421,13 +421,14 @@ node gsd-tools.cjs scaffold phase-dir --phase N --name "phase name" ## Init Commands (Compound Context Loading) -Load all context needed for a specific workflow in one call. Returns JSON with project info, config, state, and workflow-specific data. +Load all context needed for a specific workflow in one call. Returns JSON with project info, config, state, and workflow-specific data. `init onboard [--fast] [--text]` reports brownfield signals, planning-doc candidates, codebase-map completeness, fast-map readiness, text-mode routing, partial planning state, and onboarding summary status for `/gsd-onboard`. ```bash node gsd-tools.cjs init execute-phase node gsd-tools.cjs init plan-phase node gsd-tools.cjs init new-project node gsd-tools.cjs init new-milestone +node gsd-tools.cjs init onboard [--fast] [--text] node gsd-tools.cjs init quick node gsd-tools.cjs init resume node gsd-tools.cjs init verify-work diff --git a/docs/COMMANDS.md b/docs/COMMANDS.md index e8f968d1b..22216ff54 100644 --- a/docs/COMMANDS.md +++ b/docs/COMMANDS.md @@ -58,6 +58,25 @@ Initialize a new project with deep context gathering. --- +### `/gsd-onboard` + +Guide an existing codebase through first-time GSD onboarding. The command checks repo state, routes you through codebase mapping, optional docs ingest, project initialization, and creates an onboarding summary once planning exists. + +| Flag | Description | +|------|-------------| +| `--fast` | Prefer the lightweight `/gsd-map-codebase --fast` mapping handoff; a complete map is still required before `/gsd-new-project` | +| `--text` | Use numbered plain-text gates instead of TUI menus | + +**Prerequisites:** Existing repo or planning docs. For empty greenfield projects, use `/gsd-new-project`. +**Produces:** `.planning/codebase/` via map-codebase, `.planning/` via new-project or ingest-docs, and `.planning/onboarding/SUMMARY.md` after project setup. + +```bash +/gsd-onboard # Guided brownfield onboarding +/gsd-onboard --fast # Use lightweight codebase mapping first, then complete the map before project setup +``` + +--- + ### `/gsd-workspace` Manage GSD workspaces — create, list, or remove isolated workspace environments with repo copies and independent `.planning/` directories. @@ -1183,7 +1202,7 @@ gsd capability remove my-cap --scope project # Turn the installed overl ### `/gsd-map-codebase` -Analyze existing codebase with parallel mapper agents. Use `--fast` for a quick single-agent scan, or `--query` to search existing intel. +Analyze existing codebase with parallel mapper agents. Use `--fast` for a quick single-agent scan, or `--query` to search existing intel. First-time brownfield setup should usually start with `/gsd-onboard`, which hands off to this command when a map is missing. | Argument | Required | Description | |----------|----------|-------------| diff --git a/docs/FEATURES.md b/docs/FEATURES.md index 0019ee7dd..1a80bd7c3 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -38,6 +38,7 @@ - [Model Profiles](#26-model-profiles) - [Brownfield Features](#brownfield-features) - [Codebase Mapping](#27-codebase-mapping) + - [Existing Codebase Onboarding](#27b-existing-codebase-onboarding) - [Utility Features](#utility-features) - [Debug System](#28-debug-system) - [Todo Management](#29-todo-management) @@ -789,7 +790,7 @@ **Command:** `/gsd-map-codebase [area]` -**Purpose:** Analyze an existing codebase before starting a new project, so GSD understands what exists. +**Purpose:** Analyze an existing codebase before starting a new project or as the mapping handoff from `/gsd-onboard`, so GSD understands what exists. **Requirements:** - REQ-MAP-01: System MUST spawn parallel mapper agents for each analysis area @@ -817,6 +818,27 @@ only the subtrees the phase actually changed. Each produced document carries `last_mapped_commit` in its YAML frontmatter so drift can be measured against the mapping point, not HEAD. +### 27b. Existing Codebase Onboarding + +**Command:** `/gsd-onboard [--fast] [--text]` + +**Purpose:** Guide first-time setup for an existing repository by checking brownfield state, routing through codebase mapping and docs ingest, then handing off to project initialization without silently overwriting planning artifacts. + +**Requirements:** +- REQ-ONBOARD-01: System MUST detect existing code, package manifests, planning documents, partial `.planning/` state, and complete or missing codebase-map files. +- REQ-ONBOARD-02: System MUST hand off to `/gsd-map-codebase` or `/gsd-map-codebase --fast` when brownfield code lacks the required `.planning/codebase/` map files; fast-map readiness is partial and MUST NOT be treated as sufficient for `/gsd-new-project`. +- REQ-ONBOARD-03: System MUST offer `/gsd-ingest-docs` before `/gsd-new-project` when ADR/PRD/SPEC/RFC candidates exist and no project exists. +- REQ-ONBOARD-04: System MUST refuse to report onboarding complete until `PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md`, and `STATE.md` all exist. +- REQ-ONBOARD-05: System MUST create or confirm `.planning/onboarding/SUMMARY.md` only after project setup exists. +- REQ-ONBOARD-06: System MUST support `--text` for numbered plain-text gates on runtimes without interactive menus. + +**Produces:** +| Artifact | Description | +|----------|-------------| +| `.planning/codebase/` | Codebase map produced by the `/gsd-map-codebase` handoff | +| `.planning/PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md`, `STATE.md` | Planning setup produced by `/gsd-new-project` or `/gsd-ingest-docs` | +| `.planning/onboarding/SUMMARY.md` | Onboarding status, artifact index, and next-command summary | + ### 27a. Post-Execute Codebase Drift Detection **Introduced by:** #2003 diff --git a/docs/INVENTORY-MANIFEST.json b/docs/INVENTORY-MANIFEST.json index 0bc7c3b28..91c72c593 100644 --- a/docs/INVENTORY-MANIFEST.json +++ b/docs/INVENTORY-MANIFEST.json @@ -78,6 +78,7 @@ "/gsd-ns-project", "/gsd-ns-review", "/gsd-ns-workflow", + "/gsd-onboard", "/gsd-pause-work", "/gsd-phase", "/gsd-plan-phase", @@ -160,6 +161,7 @@ "next.md", "node-repair.md", "note.md", + "onboard.md", "pause-work.md", "plan-milestone-gaps.md", "plan-phase.md", @@ -225,6 +227,7 @@ "gates.md", "git-integration.md", "git-planning-commit.md", + "gsd-run-resolver.md", "honest-verifier.md", "ios-scaffold.md", "loop-hook-dispatch.md", @@ -369,6 +372,7 @@ "model-catalog.cjs", "model-profiles.cjs", "model-resolver.cjs", + "onboard-projection.cjs", "package-identity.cjs", "package-legitimacy.cjs", "phase-command-router.cjs", diff --git a/docs/INVENTORY.md b/docs/INVENTORY.md index aa41acbdf..a05d6e304 100644 --- a/docs/INVENTORY.md +++ b/docs/INVENTORY.md @@ -79,6 +79,7 @@ These six routers are descriptor-only entries that the model picks first; the bo | Command | Role | Source | |---------|------|--------| | `/gsd-new-project` | Initialize a new project with deep context gathering and PROJECT.md. | [commands/gsd/new-project.md](../commands/gsd/new-project.md) | +| `/gsd-onboard` | Guide existing codebase onboarding through mapping, docs ingest, project setup, and onboarding summary. | [commands/gsd/onboard.md](../commands/gsd/onboard.md) | | `/gsd-workspace` | Manage GSD workspaces — create (`--new`), list (`--list`), or remove (`--remove`) isolated workspace environments. | [commands/gsd/workspace.md](../commands/gsd/workspace.md) | | `/gsd-discuss-phase` | Gather phase context through adaptive questioning before planning. | [commands/gsd/discuss-phase.md](../commands/gsd/discuss-phase.md) | | `/gsd-mvp-phase` | Plan a phase as a vertical MVP slice — user story, SPIDR splitting, then plan-phase. | [commands/gsd/mvp-phase.md](../commands/gsd/mvp-phase.md) | @@ -223,6 +224,7 @@ Full roster at `gsd-core/workflows/*.md`. Workflows are thin orchestrators that | `milestone-summary.md` | Milestone summary synthesis — onboarding and review artifact from milestone artifacts. | `/gsd-milestone-summary` | | `new-milestone.md` | Start a new milestone cycle — load project context, gather goals, update PROJECT.md/STATE.md. | `/gsd-new-milestone` | | `new-project.md` | Unified new-project flow — questioning, research (optional), requirements, roadmap. | `/gsd-new-project` | +| `onboard.md` | Brownfield onboarding orchestration — map codebase, ingest docs, initialize planning, summarize next step. | `/gsd-onboard` | | `new-workspace.md` | Create an isolated workspace with repo worktrees/clones and an independent `.planning/`. | `/gsd-workspace --new` | | `next.md` | Detect current project state and automatically advance to the next logical step. | `/gsd-progress --next` | | `node-repair.md` | Autonomous repair operator for failed task verification; invoked by `execute-plan`. | `execute-plan.md` (recovery) | diff --git a/docs/USER-GUIDE.md b/docs/USER-GUIDE.md index e06c10d4d..aaaee31af 100644 --- a/docs/USER-GUIDE.md +++ b/docs/USER-GUIDE.md @@ -79,7 +79,7 @@ The core GSD loop is: **discuss → plan → execute → verify → ship**, repe See [Your first project](tutorials/your-first-project.md). -For onboarding an existing codebase before starting a new milestone, see [Onboarding an existing codebase](tutorials/onboarding-an-existing-codebase.md). +For onboarding an existing codebase before starting a new milestone, run `/gsd-onboard` or see [Onboarding an existing codebase](tutorials/onboarding-an-existing-codebase.md). **Relevant flags at a glance:** @@ -536,11 +536,13 @@ claude --dangerously-skip-permissions ### Existing Codebase ```bash -/gsd-map-codebase # Analyse what exists (parallel agents) -/gsd-new-project # Questions focus on what you're ADDING +/gsd-onboard # Safely map, ingest docs, and initialize planning +# Follow the printed top-level handoff commands, then rerun /gsd-onboard # (normal phase workflow from here) ``` +`/gsd-onboard` routes through `/gsd-map-codebase`, `/gsd-ingest-docs`, and `/gsd-new-project` without nesting interactive workflows or overwriting existing planning files silently. + **Post-execute drift detection (#2003).** After every `/gsd-execute-phase`, GSD checks whether the phase introduced enough structural change to make `.planning/codebase/STRUCTURE.md` stale. Flip the behavior with: ```bash @@ -986,7 +988,8 @@ To disable parallel execution entirely: `/gsd-settings` → set `parallelization themes/ default.css # Shared CSS variables for all sketches MANIFEST.md # Index of all sketches with winners - codebase/ # Brownfield codebase mapping (from /gsd-map-codebase) + codebase/ # Brownfield codebase mapping (from /gsd-map-codebase or /gsd-onboard) + onboarding/ # Brownfield onboarding summary (from /gsd-onboard) phases/ XX-phase-name/ XX-YY-PLAN.md # Atomic execution plans diff --git a/docs/adr/1990-existing-code-onboarding.md b/docs/adr/1990-existing-code-onboarding.md new file mode 100644 index 000000000..aa9b47c3f --- /dev/null +++ b/docs/adr/1990-existing-code-onboarding.md @@ -0,0 +1,69 @@ +# Existing Code Onboarding Module owns deterministic repo-state detection and onboarding route selection + +- **Status:** Proposed +- **Date:** 2026-07-06 +- **Issue:** #1990 +- **Implementation:** PR #1994 + +## Context + +GSD already ships strong individual primitives for adopting an existing codebase: `/gsd:map-codebase` (parallel codebase analysis), `/gsd:ingest-docs` (classify and consolidate existing ADR/PRD/SPEC/RFC docs), and `/gsd:new-project` (planning initialization). What it lacked was a single guided entry point that inspects a brownfield repository and tells the user *which primitive runs first*. + +Left to prose alone, that ordering is ambiguous and unsafe: a user can initialize planning before a codebase map exists, skip relevant design docs, or overwrite/duplicate `.planning/` context instead of reusing it. The ordering is not a matter of taste — it is a **dependency graph** (a map should exist before planning; existing design docs should be ingested before a fresh `/gsd:new-project`; nothing should clobber an in-progress `.planning/`). A dependency graph that decides the next safe action from filesystem state is a *projection*, not something a workflow's natural-language instructions can evaluate reliably or test. + +GSD already has the seam for this. The **Init Command Module** (`src/init.cts` → `gsd-core/bin/lib/init.cjs`) owns the `init.*` family of query handlers that compose atomic queries into the flat JSON bundles that init workflows consume, alongside the projection-module precedent set by the **Planning Path Projection Module** (ADR-0006) and the **Shell Command Projection Module** (ADR-0009). Adding `/gsd:onboard` as free-form workflow prose that scans the tree inline would put untested, non-deterministic filesystem logic in markdown — precisely the anti-pattern those projection modules exist to prevent. + +## Decision + +Introduce the **Existing Code Onboarding Module** (implemented as the `src/onboard-projection.cts` → `gsd-core/bin/lib/onboard-projection.cjs` projection) as the Seam that owns **deterministic detection of brownfield repository state and the selection of the next onboarding action**. It is a pure, side-effect-free projection consumed by the Init Command Module's `initOnboard` handler and rendered by the `/gsd:onboard` workflow. It never writes; detection and route selection are a function of repository state only. + +**Detected state (inputs):** + +| Signal | Rule / invariant | +|---|---| +| Brownfield code present | Depth-capped recursive scan for source files (`hasCodeFilesInternal`) OR a recognized package manifest (`hasPackageFileInternal`). | +| Generated / vendor exclusion | Scan skips `CODE_SCAN_SKIP_DIRS` (`node_modules`, `dist`, `build`, `.next`, `.nuxt`, `.svelte-kit`, `coverage`, `vendor`, `.venv`, `venv`) so vendored trees never produce a false brownfield positive. | +| Codebase-map completeness | Whether `.planning/codebase/` holds the canonical map artifacts. | +| Existing design docs | Presence of ADR/PRD/SPEC/RFC-style candidates (root, nested, and segment-based). | +| Partial planning state | Whether some but not all of `PROJECT.md` / `REQUIREMENTS.md` / `ROADMAP.md` / `STATE.md` exist. | + +**Route selection (output), ordered by dependency, not by convenience:** + +1. Brownfield code without a complete `.planning/codebase/` map → hand off to `/gsd:map-codebase` (or `/gsd:map-codebase --fast` in fast mode). +2. Design-doc candidates present and no project yet → offer `/gsd:ingest-docs` **before** `/gsd:new-project`. +3. Otherwise → `/gsd:new-project`. + +The gate order is load-bearing: **partial-planning and fast-map-completeness are evaluated before the docs-ingest branch**, so a half-mapped or half-initialized repo is never routed past the step it still owes. Handoff commands are runtime-formatted (`buildHandoffCommands` / `formatGsdSlash`) so the projected next command is correct for the installed runtime's slash syntax. + +**Safety invariants (the reason this is a Module, not a helper):** + +- **Idempotent / no silent overwrite.** Onboarding never mutates existing tracked `.planning/` artifacts; re-running leaves them byte-unchanged. +- **`SUMMARY.md` is a trailing artifact.** `.planning/onboarding/SUMMARY.md` is written only *after* project setup exists, and only if absent. +- **"Complete" is a conjunction.** Onboarding does not report complete until `PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md`, and `STATE.md` all exist — no single-file short-circuit. +- **Text-mode parity.** `--text` renders the same gate decisions as numbered plain-text prompts, so runtimes without an interactive picker get identical routing. + +## What stays OUTSIDE this Module + +- **The primitives themselves.** `/gsd:map-codebase`, `/gsd:ingest-docs`, and `/gsd:new-project` retain their own behavior; the Module only *chooses and orders* them. It projects the route; it does not re-implement the destinations. +- **Writing planning artifacts.** All `.planning/` writes remain owned by the destination commands and the Installer/planning modules. The projection is read-only. +- **The workflow's rendering.** `gsd-core/workflows/onboard.md` owns menu/gate presentation; the command `commands/gsd/onboard.md` (and its skill mirror) owns delegation. The Module owns only the state→route decision they consume. + +## Consequences + +- Brownfield onboarding becomes a single, testable entry point with deterministic routing, rather than order-of-operations folklore in prose. The projection is unit-tested (`tests/onboard-command.test.cjs`) for brownfield/greenfield detection, vendor-dir exclusion, gate ordering (partial-planning before docs-ingest), idempotency/no-mutation, and runtime-formatted handoffs. +- The Init Command Module gains one more heavyweight handler (`initOnboard`) with the same `{ data: }` contract as its siblings — no new dispatch shape. +- **New maintenance coupling, now explicit.** The Module's completeness checks must track the canonical `.planning/codebase/` artifact list and the routing targets' identities; if `/gsd:map-codebase` / `/gsd:ingest-docs` / `/gsd:new-project` change their entry contracts, this projection must follow. This ADR records that coupling as the known cost of centralizing the routing decision (the alternative — duplicating the decision across each primitive — is worse). +- No new runtime dependencies; no change to existing command semantics (additive). + +## Open questions + +- Should codebase-map completeness be sourced from a single shared predicate (owned by the map module) rather than re-encoded here, so the two cannot drift? +- The `/gsd:onboard` workflow sources its `gsd_run` bootstrap from a shared `references/gsd-run-resolver.md` snippet rather than inlining it. If that delegation pattern is adopted by other workflows, it likely deserves its own short ADR — noting it here so the precedent is visible rather than silently established. + +## References + +- ADR-0006 — Planning Path Projection Module (projection-module precedent for `.planning` path resolution). +- ADR-0009 — Shell Command Projection Module (runtime-aware projection precedent). +- Init Command Module (`src/init.cts` → `gsd-core/bin/lib/init.cjs`) — owner of the `init.*` handler family that consumes this projection via `initOnboard`. +- `CONTEXT.md` § Init Command Module — where the onboarding projection is registered. +- Issue #1990 — feature spec and acceptance criteria. diff --git a/docs/adr/README.md b/docs/adr/README.md index 5922a7422..03038a5c9 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -64,6 +64,7 @@ See **[CONTRIBUTING.md — "Proposing an ADR or PRD"](../../CONTRIBUTING.md#prop | [1769-state-md-transition-module.md](1769-state-md-transition-module.md) | STATE.md Transition Module — intent-based transitions over scattered RMW callbacks | Proposed | | [1817-state-md-rebuild-derivability-contract.md](1817-state-md-rebuild-derivability-contract.md) | STATE.md rebuild — derivability contract (capstone 11th transition) | Accepted | | [2008-command-exit-zero-gate.md](2008-command-exit-zero-gate.md) | Generic gate-predicate evaluator with a `command-exit-zero` kind (#2008) | Accepted | +| [1990-existing-code-onboarding.md](1990-existing-code-onboarding.md) | Existing Code Onboarding Module owns deterministic repo-state detection and onboarding route selection | Proposed | ## Seam map diff --git a/docs/how-to/install-minimal-and-add-skills.md b/docs/how-to/install-minimal-and-add-skills.md index e30537af7..53a6f772d 100644 --- a/docs/how-to/install-minimal-and-add-skills.md +++ b/docs/how-to/install-minimal-and-add-skills.md @@ -45,7 +45,7 @@ If `core` is too small, pick a wider profile instead. Pass it with `--profile= node gsd-tools.cjs init plan-phase node gsd-tools.cjs init new-project node gsd-tools.cjs init new-milestone +node gsd-tools.cjs init onboard [--fast] [--text] node gsd-tools.cjs init quick node gsd-tools.cjs init resume node gsd-tools.cjs init verify-work diff --git a/docs/ja-JP/COMMANDS.md b/docs/ja-JP/COMMANDS.md index d63034e51..9a2bb72f4 100644 --- a/docs/ja-JP/COMMANDS.md +++ b/docs/ja-JP/COMMANDS.md @@ -51,6 +51,25 @@ v1.40 では、最初のステージエントリーポイントとして6つの --- +### `/gsd-onboard` + +既存コードベースの初回 GSD オンボーディングを案内します。リポジトリ状態を確認し、コードベースマッピング、任意のドキュメント取り込み、プロジェクト初期化へ安全にハンドオフし、計画が揃った後にオンボーディング summary を作成します。 + +| フラグ | 説明 | +|------|-------------| +| `--fast` | 軽量な `/gsd-map-codebase --fast` マッピングハンドオフを優先。ただし `/gsd-new-project` 前には完全なマップが必要 | +| `--text` | TUI メニューではなく番号付きプレーンテキストのゲートを使用 | + +**前提条件:** 既存リポジトリまたは計画ドキュメント。空のグリーンフィールドプロジェクトには `/gsd-new-project` を使用します。 +**生成物:** map-codebase による `.planning/codebase/`、new-project または ingest-docs による `.planning/`、セットアップ後の `.planning/onboarding/SUMMARY.md`。 + +```bash +/gsd-onboard # ガイド付き brownfield オンボーディング +/gsd-onboard --fast # 先に軽量マップを使い、その後プロジェクト設定前に完全マップを作成 +``` + +--- + ### `/gsd-workspace` GSD ワークスペースを管理 — リポジトリコピーと独立した `.planning/` ディレクトリを持つ隔離されたワークスペース環境を作成、一覧表示、または削除します。 diff --git a/docs/ja-JP/FEATURES.md b/docs/ja-JP/FEATURES.md index 6f91953c6..31c1da45c 100644 --- a/docs/ja-JP/FEATURES.md +++ b/docs/ja-JP/FEATURES.md @@ -38,6 +38,7 @@ - [モデルプロファイル](#26-モデルプロファイル) - [ブラウンフィールド機能](#ブラウンフィールド機能) - [コードベースマッピング](#27-コードベースマッピング) + - [既存コードベースオンボーディング](#27b-既存コードベースオンボーディング) - [ユーティリティ機能](#ユーティリティ機能) - [デバッグシステム](#28-デバッグシステム) - [Todo 管理](#29-todo-管理) @@ -781,7 +782,7 @@ **コマンド:** `/gsd-map-codebase [area]` -**目的:** 新しいプロジェクトを開始する前に既存のコードベースを分析し、GSD が既存の構成を理解できるようにします。 +**目的:** 新しいプロジェクトを開始する前、または `/gsd-onboard` からのマッピングハンドオフとして既存のコードベースを分析し、GSD が既存の構成を理解できるようにします。 **要件:** - REQ-MAP-01: システムは各分析領域に対して並列マッパーエージェントを起動しなければならない @@ -805,6 +806,27 @@ `--paths ` スコープヒントを受け付けます。指定した場合、ツリー全体をスキャンする代わりに、リストされたリポジトリ相対プレフィックスに探索を制限します。 これはフェーズが実際に変更したサブツリーのみを更新するために、実行後コードベースドリフトゲートが使用するパスウェイです。各生成ドキュメントはその YAML フロントマターに `last_mapped_commit` を持ち、ドリフトを HEAD ではなくマッピング時点と照らし合わせて計測できます。 +### 27b. 既存コードベースオンボーディング + +**コマンド:** `/gsd-onboard [--fast] [--text]` + +**目的:** 既存リポジトリの初回セットアップを案内し、brownfield 状態を確認してコードベースマッピング、docs 取り込み、プロジェクト初期化へ安全にハンドオフします。 + +**要件:** +- REQ-ONBOARD-01: 既存コード、package manifest、計画ドキュメント、部分的な `.planning/`、コードベースマップの不足を検出する。 +- REQ-ONBOARD-02: 必要な `.planning/codebase/` マップファイルがない brownfield では `/gsd-map-codebase` または `/gsd-map-codebase --fast` へハンドオフする。fast マップの readiness は部分的であり、`/gsd-new-project` に十分として扱ってはならない。 +- REQ-ONBOARD-03: ADR/PRD/SPEC/RFC 候補があり project がない場合、`/gsd-new-project` の前に `/gsd-ingest-docs` を提示する。 +- REQ-ONBOARD-04: `PROJECT.md`、`REQUIREMENTS.md`、`ROADMAP.md`、`STATE.md` が揃うまで完了扱いにしない。 +- REQ-ONBOARD-05: project setup 後にのみ `.planning/onboarding/SUMMARY.md` を作成または確認する。 +- REQ-ONBOARD-06: 対話型メニューがない runtime 向けに、`--text` で番号付きプレーンテキスト gate をサポートする。 + +**生成物:** +| Artifact | 説明 | +|----------|-------------| +| `.planning/codebase/` | `/gsd-map-codebase` handoff が生成するコードベースマップ | +| `.planning/PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md`, `STATE.md` | `/gsd-new-project` または `/gsd-ingest-docs` が生成する planning setup | +| `.planning/onboarding/SUMMARY.md` | Onboarding status、artifact index、next-command summary | + ### 27a. 実行後コードベースドリフト検出 **導入:** #2003 diff --git a/docs/ja-JP/INVENTORY.md b/docs/ja-JP/INVENTORY.md index a1d5a6a70..506e18442 100644 --- a/docs/ja-JP/INVENTORY.md +++ b/docs/ja-JP/INVENTORY.md @@ -78,6 +78,7 @@ | コマンド | 役割 | ソース | |----------|------|--------| | `/gsd-new-project` | 深いコンテキスト収集と PROJECT.md で新しいプロジェクトを初期化。 | [commands/gsd/new-project.md](../../commands/gsd/new-project.md) | +| `/gsd-onboard` | 既存コードベースをマッピング、ドキュメント取り込み、プロジェクト設定、onboarding summary へ案内。 | [commands/gsd/onboard.md](../../commands/gsd/onboard.md) | | `/gsd-workspace` | GSD ワークスペースを管理 — 独立したワークスペース環境を作成(`--new`)、一覧表示(`--list`)、削除(`--remove`)。 | [commands/gsd/workspace.md](../../commands/gsd/workspace.md) | | `/gsd-discuss-phase` | 計画前にアダプティブな質問でフェーズコンテキストを収集。 | [commands/gsd/discuss-phase.md](../../commands/gsd/discuss-phase.md) | | `/gsd-mvp-phase` | フェーズを垂直 MVP スライスとして計画 — ユーザーストーリー、SPIDR 分割、その後 plan-phase。 | [commands/gsd/mvp-phase.md](../../commands/gsd/mvp-phase.md) | @@ -218,6 +219,7 @@ | `milestone-summary.md` | マイルストーンサマリー合成 — マイルストーンアーティファクトからオンボーディングとレビューアーティファクトを作成。 | `/gsd-milestone-summary` | | `new-milestone.md` | 新しいマイルストーンサイクルを開始 — プロジェクトコンテキストを読み込み、目標を収集して PROJECT.md/STATE.md を更新。 | `/gsd-new-milestone` | | `new-project.md` | 統合新プロジェクトフロー — 質問、調査(任意)、要件、ロードマップ。 | `/gsd-new-project` | +| `onboard.md` | Brownfield onboarding orchestration — コードベースをマップし、docs を取り込み、planning を初期化し、次のステップを要約。 | `/gsd-onboard` | | `new-workspace.md` | リポジトリのワークツリー/クローンと独立した `.planning/` を持つ独立したワークスペースを作成。 | `/gsd-workspace --new` | | `next.md` | 現在のプロジェクト状態を検出して次の論理的なステップに自動的に進む。 | `/gsd-progress --next` | | `node-repair.md` | タスク検証が失敗した場合の自律修復オペレーター。`execute-plan` から呼び出し。 | `execute-plan.md` (recovery) | diff --git a/docs/ja-JP/USER-GUIDE.md b/docs/ja-JP/USER-GUIDE.md index 264953822..15c4ee089 100644 --- a/docs/ja-JP/USER-GUIDE.md +++ b/docs/ja-JP/USER-GUIDE.md @@ -474,8 +474,8 @@ claude --dangerously-skip-permissions ### 既存のコードベース ```bash -/gsd-map-codebase # Analyse what exists (parallel agents) -/gsd-new-project # Questions focus on what you're ADDING +/gsd-onboard # Safely map, ingest docs, and initialize planning +# Follow printed handoff commands, then rerun /gsd-onboard # (normal phase workflow from here) ``` @@ -864,7 +864,8 @@ All subagent/executor commits MUST use `--no-verify`. themes/ default.css # Shared CSS variables for all sketches MANIFEST.md # Index of all sketches with winners - codebase/ # Brownfield codebase mapping (from /gsd-map-codebase) + codebase/ # Brownfield codebase mapping (from /gsd-map-codebase or /gsd-onboard) + onboarding/ # Brownfield onboarding summary (from /gsd-onboard) phases/ XX-phase-name/ XX-YY-PLAN.md # Atomic execution plans diff --git a/docs/ja-JP/how-to/install-on-your-runtime.md b/docs/ja-JP/how-to/install-on-your-runtime.md index 1c1900736..bcd26fc82 100644 --- a/docs/ja-JP/how-to/install-on-your-runtime.md +++ b/docs/ja-JP/how-to/install-on-your-runtime.md @@ -273,10 +273,11 @@ npx @opengsd/gsd-core@latest --opencode --global ## インストール後の作業 -新しいコマンドとエージェントを反映するためにランタイムを再起動してください。その後、最初のプロジェクトを開始します。 +新しいコマンドとエージェントを反映するためにランタイムを再起動してください。その後、新規プロジェクトを開始するか既存リポジトリをオンボーディングします。 ```bash -/gsd-new-project +/gsd-new-project # グリーンフィールドプロジェクト +/gsd-onboard # 既存コードベース ``` 再起動後もコマンドが見つからない場合は、インストールディレクトリがランタイムの期待する設定パスと一致しているか確認してください。最もよくある不一致については上記のプレリリースエディションのセクションを参照してください。 diff --git a/docs/ja-JP/reference/planning-artifacts.md b/docs/ja-JP/reference/planning-artifacts.md index 1f51165ca..f231de028 100644 --- a/docs/ja-JP/reference/planning-artifacts.md +++ b/docs/ja-JP/reference/planning-artifacts.md @@ -23,6 +23,8 @@ │ ├── architecture.md │ ├── stack.md │ └── ... +├── onboarding/ # ブラウンフィールドオンボーディング概要(オプション) +│ └── SUMMARY.md ├── intel/ # クエリ可能なシンボルインデックス(オプション、intel.enabled) │ └── API-SURFACE.md └── phases/ @@ -48,7 +50,7 @@ | | | |---|---| | **用途** | プロジェクトの正規アイデンティティ: 概要、対象ユーザー、コアバリュー、要件、制約、主要な意思決定。プロダクトの進化に伴いプロジェクトライフサイクル全体を通じて更新されます。 | -| **生成元** | `/gsd-new-project`(初回作成); 意思決定が検証されると `/gsd-complete-milestone` によって更新されます。 | +| **生成元** | `/gsd-new-project`(初回作成、`/gsd-onboard` のハンドオフを含む); 意思決定が検証されると `/gsd-complete-milestone` によって更新されます。 | | **参照先** | すべてのプランニングワークフロー; `gsd-phase-researcher`、`gsd-planner`(コンテキスト); `discuss-phase`(過去の意思決定); `gsd-plan-checker`(プロジェクト制約)。 | ### `ROADMAP.md` @@ -56,7 +58,7 @@ | | | |---|---| | **用途** | マイルストーンおよびフェーズ一覧。ゴール、要件 ID、成功基準、フェーズごとの正規リファレンスを含みます。プロジェクトが何をどの順序で構築するかに関する唯一の信頼できる情報源です。 | -| **生成元** | `/gsd-new-project`(初回作成); `/gsd-phase --insert` および `/gsd-complete-milestone` によって更新されます。 | +| **生成元** | `/gsd-new-project`(初回作成、`/gsd-onboard` のハンドオフを含む); `/gsd-phase --insert` および `/gsd-complete-milestone` によって更新されます。 | | **参照先** | `/gsd-discuss-phase`、`/gsd-plan-phase`、`/gsd-execute-phase`; フェーズ情報を必要とするすべてのオーケストレーションコマンド; `gsd-planner`、`gsd-plan-checker`、`gsd-phase-researcher`。 | ### `REQUIREMENTS.md` @@ -64,7 +66,7 @@ | | | |---|---| | **用途** | 番号付きのチェック可能な受け入れ基準。各要件はロードマップフェーズにマッピングされる ID(例: `AUTH-01`)を持ちます。フェーズが実行されると要件を完了済みとしてマークします。 | -| **生成元** | `/gsd-new-project`(初回作成); `execute-phase` によって要件が完了済みとしてマークされます。 | +| **生成元** | `/gsd-new-project`(初回作成、`/gsd-onboard` のハンドオフを含む); `execute-phase` によって要件が完了済みとしてマークされます。 | | **参照先** | `gsd-planner`(プランはすべてのフェーズ要件 ID に対処しなければならない); `gsd-plan-checker` ディメンション1(要件カバレッジ); `discuss-phase`(過去の要件)。 | ### `STATE.md` @@ -72,7 +74,7 @@ | | | |---|---| | **用途** | 現在地を追跡するリビングドキュメント — 現在のフェーズとプラン、進捗指標、蓄積された意思決定、セッション継続性ノート。すべてのワークフロー実行の開始時に読み込まれます。重要なアクションのたびに更新されます。 | -| **生成元** | `/gsd-new-project`(初回作成); すべてのフェーズワークフロー、`/gsd-pause-work`、`/gsd-resume-work` によって継続的に更新されます。 | +| **生成元** | `/gsd-new-project`(初回作成、`/gsd-onboard` のハンドオフを含む); すべてのフェーズワークフロー、`/gsd-pause-work`、`/gsd-resume-work` によって継続的に更新されます。 | | **参照先** | すべてのオーケストレーションワークフロー; `/gsd-progress`; `/gsd-quick` 経由のアドホックタスク実行; `gsd-planner` および `gsd-phase-researcher`(プロジェクトの意思決定)。 | 完全なフィールドリファレンスは [STATE.md スキーマ](state-md.md) を参照してください。 @@ -87,6 +89,14 @@ 完全なスキーマは [CONFIGURATION](../../CONFIGURATION.md) を参照してください。 +### `onboarding/SUMMARY.md`(オプション) + +| | | +|---|---| +| **用途** | ブラウンフィールドオンボーディングの索引。アーティファクト状態、コードベースマッピングの完了状況、初回セットアップ後に推奨される次の GSD コマンドを記録します。 | +| **生成元** | `PROJECT.md`、`REQUIREMENTS.md`、`ROADMAP.md`、`STATE.md` がすべて存在した後の `/gsd-onboard`。 | +| **参照先** | 初回セットアップを確認する人間、および既存オンボーディング状態を確認する今後の `/gsd-onboard` 実行。 | + ### `MILESTONES.md`(オプション) | | | diff --git a/docs/ja-JP/tutorials/onboarding-an-existing-codebase.md b/docs/ja-JP/tutorials/onboarding-an-existing-codebase.md index f2a268486..8a730dc98 100644 --- a/docs/ja-JP/tutorials/onboarding-an-existing-codebase.md +++ b/docs/ja-JP/tutorials/onboarding-an-existing-codebase.md @@ -44,15 +44,15 @@ claude --dangerously-skip-permissions --- -## ステップ 3 — コードベースのマッピング +## ステップ 3 — Brownfield オンボーディングの開始 -プロジェクトを作成する前に、GSD Core に既存のコードを学習させてください。これがブラウンフィールドの計画を正確にするステップです。 +プロジェクトを作成する前に、GSD Core にリポジトリ状態を確認させ、安全な次のトップレベルコマンドを表示させます。これにより、コードベースコンテキストの取りこぼしや既存 planning ファイルの上書きを防げます。 ```text -/gsd-map-codebase +/gsd-onboard ``` -GSD Core が4つの並行マッパーサブエージェントを生成します(「Spawning 4 parallel codebase mapper agents…」という通知が表示されます。1〜5分かかりますので中断しないでください)。各エージェントはそれぞれ異なる観点に注目します: +オンボーディングがコードベースマップ不足を示したら、推奨オプションを選び、表示された `/gsd-map-codebase` ハンドオフを実行してから `/gsd-onboard` を再実行します。`/gsd-onboard --fast` は軽量な初回パスには使えますが、`/gsd-new-project` の前には完全なマップが必要です。`/gsd-map-codebase` が4つの並行マッパーサブエージェントを生成します(「Spawning 4 parallel codebase mapper agents…」という通知が表示されます。1〜5分かかりますので中断しないでください)。各エージェントはそれぞれ異なる観点に注目します: | エージェント | 観点 | |-------|-------| @@ -84,7 +84,7 @@ Created .planning/codebase/: --- -## ステップ 4 — コンテキストをクリアしてプロジェクトを作成 +## ステップ 4 — オンボーディングを再実行してプロジェクトを初期化する セッションウィンドウをクリアします: @@ -92,12 +92,14 @@ Created .planning/codebase/: /clear ``` -プロジェクトを作成します。前のステップで GSD Core が既存のコードを見つけているため、これがブラウンフィールドプロジェクトであることをすでに把握しています。`/gsd-new-project` を実行すると、既存のものを再説明するのではなく、*追加する*内容に焦点を当てた質問がされます: +`/gsd-onboard` をもう一度実行します。GSD Core が ADR、PRD、spec、RFC、またはルートレベルの要件ドキュメントを検出した場合は、先に推奨される `/gsd-ingest-docs` ハンドオフを実行し、その後 `/gsd-onboard` を再実行してください。コンテキストが整うと、オンボーディングはプロジェクト初期化のハンドオフを表示します: ```text /gsd-new-project ``` +前のステップで GSD Core が既存のコードを見つけているため、`/gsd-new-project` はこれがブラウンフィールドプロジェクトだと分かっています。質問は既存のものを再説明するのではなく、*追加する*内容に焦点を当てます: + GSD Core が何を作りたいかを尋ねます。コードベース全体の説明ではなく、追加する機能で答えてください: ```text @@ -124,6 +126,8 @@ Proposed Roadmap ロードマップを承認してください。 +プロジェクト設定が完了したら、もう一度 `/gsd-onboard` を実行します。`PROJECT.md`、`REQUIREMENTS.md`、`ROADMAP.md`、`STATE.md` がすべて存在するため、オンボーディングは `.planning/onboarding/SUMMARY.md` を作成または確認します。 + **`.planning/` に作成されるファイル:** ```text @@ -133,6 +137,7 @@ Proposed Roadmap ROADMAP.md ← フェーズ 1、ステータス: pending STATE.md ← セッションメモリ config.json ← ワークフロー設定 + onboarding/SUMMARY.md ← オンボーディング状態と次のコマンド codebase/ ← ステップ 3 の7つのマップファイル ``` @@ -212,6 +217,7 @@ GSD Core があなたの `CONVENTIONS.md` と `ARCHITECTURE.md` を読み込ん ## 学んだこと +- `/gsd-onboard` が対話型コマンドをネストしたり既存 planning ファイルを上書きしたりせずに、ブラウンフィールド設定を安全に順序付ける仕組み。 - `/gsd-map-codebase` が4つの並行エージェントを実行して `.planning/codebase/` に `STACK.md`、`ARCHITECTURE.md`、`CONVENTIONS.md`、`CONCERNS.md`、`STRUCTURE.md`、`TESTING.md`、`INTEGRATIONS.md` を生成する仕組み。 - ブラウンフィールドリポジトリで `/gsd-new-project` を実行すると、*追加する*内容に焦点を当てた質問がされ、既存コードから Validated 要件が自動入力される仕組み。 - コードベースマップが `/gsd-discuss-phase` のすべての質問を形成する方法 — ファイルパス、パターン、規約が実際のコードから導出される。 diff --git a/docs/ko-KR/ARCHITECTURE.md b/docs/ko-KR/ARCHITECTURE.md index 3c8481647..2e737c75c 100644 --- a/docs/ko-KR/ARCHITECTURE.md +++ b/docs/ko-KR/ARCHITECTURE.md @@ -512,7 +512,8 @@ UI-SPEC.md (단계별) ─────────────────── │ ├── FEATURES.md │ ├── ARCHITECTURE.md │ └── PITFALLS.md -├── codebase/ # 브라운필드 매핑 (/gsd-map-codebase에서) +├── codebase/ # 브라운필드 매핑 (/gsd-map-codebase 또는 /gsd-onboard에서) +├── onboarding/ # 브라운필드 온보딩 요약 (/gsd-onboard에서) │ ├── STACK.md # YAML 전문에 `last_mapped_commit` 포함 │ ├── ARCHITECTURE.md # 실행 후 드리프트 게이트를 위한 (#2003) │ ├── CONVENTIONS.md diff --git a/docs/ko-KR/CLI-TOOLS.md b/docs/ko-KR/CLI-TOOLS.md index 80496bf35..7d9f76984 100644 --- a/docs/ko-KR/CLI-TOOLS.md +++ b/docs/ko-KR/CLI-TOOLS.md @@ -288,13 +288,14 @@ node gsd-tools.cjs scaffold phase-dir --phase N --name "phase name" ## Init 명령 (복합 컨텍스트 로딩) -하나의 호출로 특정 워크플로우에 필요한 모든 컨텍스트를 로드합니다. 프로젝트 정보, 설정, 상태, 워크플로우별 데이터가 포함된 JSON을 반환합니다. +하나의 호출로 특정 워크플로우에 필요한 모든 컨텍스트를 로드합니다. 프로젝트 정보, 설정, 상태, 워크플로우별 데이터가 포함된 JSON을 반환합니다. `init onboard [--fast] [--text]`는 `/gsd-onboard`를 위해 brownfield 신호, 계획 문서 후보, 코드베이스 맵 완성도, fast 맵 준비 상태, 텍스트 모드 라우팅, 부분 planning 상태, 온보딩 요약 상태를 반환합니다. ```bash node gsd-tools.cjs init execute-phase node gsd-tools.cjs init plan-phase node gsd-tools.cjs init new-project node gsd-tools.cjs init new-milestone +node gsd-tools.cjs init onboard [--fast] [--text] node gsd-tools.cjs init quick node gsd-tools.cjs init resume node gsd-tools.cjs init verify-work diff --git a/docs/ko-KR/COMMANDS.md b/docs/ko-KR/COMMANDS.md index 56c8f3625..338bb91d9 100644 --- a/docs/ko-KR/COMMANDS.md +++ b/docs/ko-KR/COMMANDS.md @@ -51,6 +51,25 @@ v1.40에서 여섯 개의 네임스페이스 라우터가 1단계 진입점으 --- +### `/gsd-onboard` + +기존 코드베이스의 최초 GSD 온보딩을 안내합니다. 저장소 상태를 확인하고 코드베이스 매핑, 선택적 문서 수집, 프로젝트 초기화로 안전하게 넘긴 뒤 계획 파일이 준비되면 onboarding summary를 만듭니다. + +| 플래그 | 설명 | +|------|-------------| +| `--fast` | 경량 `/gsd-map-codebase --fast` 매핑 handoff 우선 사용. 단, `/gsd-new-project` 전에는 완전한 맵이 필요 | +| `--text` | TUI 메뉴 대신 번호가 있는 plain-text gate 사용 | + +**전제 조건:** 기존 저장소 또는 계획 문서. 빈 greenfield 프로젝트는 `/gsd-new-project`를 사용하세요. +**생성 결과:** map-codebase의 `.planning/codebase/`, new-project 또는 ingest-docs의 `.planning/`, 설정 후 `.planning/onboarding/SUMMARY.md`. + +```bash +/gsd-onboard # 안내형 brownfield 온보딩 +/gsd-onboard --fast # 먼저 경량 맵을 사용하고, 프로젝트 설정 전 완전한 맵 작성 +``` + +--- + ### `/gsd-workspace` GSD 워크스페이스 관리 — 리포지토리 복사본과 독립적인 `.planning/` 디렉토리를 갖는 격리된 워크스페이스 환경을 생성, 나열, 또는 삭제합니다. diff --git a/docs/ko-KR/FEATURES.md b/docs/ko-KR/FEATURES.md index be2f5d268..a6663acd3 100644 --- a/docs/ko-KR/FEATURES.md +++ b/docs/ko-KR/FEATURES.md @@ -38,6 +38,7 @@ - [모델 프로파일](#26-model-profiles) - [브라운필드 기능](#brownfield-features) - [코드베이스 매핑](#27-codebase-mapping) + - [기존 코드베이스 온보딩](#27b-existing-codebase-onboarding) - [유틸리티 기능](#utility-features) - [디버그 시스템](#28-debug-system) - [할 일 관리](#29-todo-management) @@ -716,7 +717,7 @@ **명령어:** `/gsd-map-codebase [area]` -**목적:** 새 프로젝트를 시작하기 전에 기존 코드베이스를 분석하여 GSD가 무엇이 존재하는지 이해하도록 합니다. +**목적:** 새 프로젝트 시작 전 또는 `/gsd-onboard`의 매핑 handoff로 기존 코드베이스를 분석하여 GSD가 무엇이 존재하는지 이해하도록 합니다. **요구사항.** - REQ-MAP-01: 각 분석 영역에 대한 병렬 매퍼 에이전트를 생성해야 합니다. @@ -736,6 +737,27 @@ | `TESTING.md` | 테스트 인프라, 커버리지, 패턴 | | `INTEGRATIONS.md` | 외부 서비스, API, 서드파티 의존성 | +### 27b. Existing Codebase Onboarding + +**명령어:** `/gsd-onboard [--fast] [--text]` + +**목적:** 기존 저장소의 최초 설정을 안내하고 brownfield 상태를 확인해 코드베이스 매핑, docs 수집, 프로젝트 초기화로 안전하게 handoff합니다. + +**요구사항.** +- REQ-ONBOARD-01: 기존 코드, package manifest, planning 문서, 부분 `.planning/` 상태, 코드베이스 맵 누락을 감지해야 합니다. +- REQ-ONBOARD-02: 필요한 `.planning/codebase/` 맵 파일이 없는 brownfield에서는 `/gsd-map-codebase` 또는 `/gsd-map-codebase --fast`로 handoff해야 합니다. fast 맵 readiness는 부분 상태이며 `/gsd-new-project`에 충분한 것으로 취급해서는 안 됩니다. +- REQ-ONBOARD-03: ADR/PRD/SPEC/RFC 후보가 있고 project가 없으면 `/gsd-new-project` 전에 `/gsd-ingest-docs`를 제안해야 합니다. +- REQ-ONBOARD-04: `PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md`, `STATE.md`가 모두 있을 때까지 완료로 보고하지 않아야 합니다. +- REQ-ONBOARD-05: project setup 후에만 `.planning/onboarding/SUMMARY.md`를 만들거나 확인해야 합니다. +- REQ-ONBOARD-06: 대화형 메뉴가 없는 runtime을 위해 `--text` 번호형 plain-text gate를 지원해야 합니다. + +**생성 산출물.** +| 산출물 | 설명 | +|----------|-------------| +| `.planning/codebase/` | `/gsd-map-codebase` handoff가 생성한 코드베이스 맵 | +| `.planning/PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md`, `STATE.md` | `/gsd-new-project` 또는 `/gsd-ingest-docs`가 생성한 planning setup | +| `.planning/onboarding/SUMMARY.md` | Onboarding status, artifact index, next-command summary | + --- ## 유틸리티 기능 diff --git a/docs/ko-KR/INVENTORY.md b/docs/ko-KR/INVENTORY.md index a73860461..83b0faf53 100644 --- a/docs/ko-KR/INVENTORY.md +++ b/docs/ko-KR/INVENTORY.md @@ -78,6 +78,7 @@ | 명령어 | 역할 | 소스 | |---------|------|--------| | `/gsd-new-project` | 심층 컨텍스트 수집 및 PROJECT.md로 새 프로젝트 초기화. | [commands/gsd/new-project.md](../../commands/gsd/new-project.md) | +| `/gsd-onboard` | 기존 코드베이스를 매핑, 문서 수집, 프로젝트 설정, onboarding summary로 안내합니다. | [commands/gsd/onboard.md](../../commands/gsd/onboard.md) | | `/gsd-workspace` | GSD 워크스페이스 관리 — 격리된 워크스페이스 환경을 생성(`--new`), 목록(`--list`), 또는 제거(`--remove`). | [commands/gsd/workspace.md](../../commands/gsd/workspace.md) | | `/gsd-discuss-phase` | 계획 전 적응형 질문을 통한 단계 컨텍스트 수집. | [commands/gsd/discuss-phase.md](../../commands/gsd/discuss-phase.md) | | `/gsd-mvp-phase` | 수직 MVP 슬라이스로 단계 계획 — 사용자 스토리, SPIDR 분할, 이후 plan-phase. | [commands/gsd/mvp-phase.md](../../commands/gsd/mvp-phase.md) | @@ -218,6 +219,7 @@ | `milestone-summary.md` | 마일스톤 아티팩트에서 온보딩 및 검토용 마일스톤 요약 합성. | `/gsd-milestone-summary` | | `new-milestone.md` | 새 마일스톤 사이클 시작 — 프로젝트 컨텍스트 로드, 목표 수집, PROJECT.md/STATE.md 업데이트. | `/gsd-new-milestone` | | `new-project.md` | 통합 새 프로젝트 플로우 — 질문, 조사(선택), 요구사항, 로드맵. | `/gsd-new-project` | +| `onboard.md` | Brownfield 온보딩 오케스트레이션 — 코드베이스 매핑, 문서 수집, planning 초기화, 다음 단계 요약. | `/gsd-onboard` | | `new-workspace.md` | 저장소 워크트리/클론과 독립적인 `.planning/`이 포함된 격리된 워크스페이스 생성. | `/gsd-workspace --new` | | `next.md` | 현재 프로젝트 상태를 감지하고 다음 논리적 단계로 자동 진행. | `/gsd-progress --next` | | `node-repair.md` | 실패한 태스크 검증을 위한 자율 수리 오퍼레이터; `execute-plan`에 의해 호출. | `execute-plan.md` (복구) | diff --git a/docs/ko-KR/USER-GUIDE.md b/docs/ko-KR/USER-GUIDE.md index a2f8c01aa..95cb95d9b 100644 --- a/docs/ko-KR/USER-GUIDE.md +++ b/docs/ko-KR/USER-GUIDE.md @@ -474,8 +474,8 @@ claude --dangerously-skip-permissions ### 기존 코드베이스 ```bash -/gsd-map-codebase # Analyse what exists (parallel agents) -/gsd-new-project # Questions focus on what you're ADDING +/gsd-onboard # Safely map, ingest docs, and initialize planning +# Follow printed handoff commands, then rerun /gsd-onboard # (normal phase workflow from here) ``` @@ -864,7 +864,8 @@ All subagent/executor commits MUST use `--no-verify`. themes/ default.css # Shared CSS variables for all sketches MANIFEST.md # Index of all sketches with winners - codebase/ # Brownfield codebase mapping (from /gsd-map-codebase) + codebase/ # Brownfield codebase mapping (from /gsd-map-codebase or /gsd-onboard) + onboarding/ # Brownfield onboarding summary (from /gsd-onboard) phases/ XX-phase-name/ XX-YY-PLAN.md # Atomic execution plans diff --git a/docs/ko-KR/how-to/install-on-your-runtime.md b/docs/ko-KR/how-to/install-on-your-runtime.md index 1a296068f..435e48c81 100644 --- a/docs/ko-KR/how-to/install-on-your-runtime.md +++ b/docs/ko-KR/how-to/install-on-your-runtime.md @@ -273,10 +273,11 @@ npx @opengsd/gsd-core@latest --opencode --global ## 설치 후 -새 명령과 에이전트를 적용하려면 런타임을 재시작하세요. 그런 다음 첫 번째 프로젝트를 시작합니다: +새 명령과 에이전트를 적용하려면 런타임을 재시작하세요. 그런 다음 새 프로젝트를 시작하거나 기존 저장소를 온보딩합니다: ```bash -/gsd-new-project +/gsd-new-project # 그린필드 프로젝트 +/gsd-onboard # 기존 코드베이스 ``` 재시작 후 명령을 찾을 수 없다면 설치 디렉터리가 런타임이 기대하는 설정 경로와 일치하는지 확인하세요. 위의 프리릴리스 에디션 섹션에서 가장 흔한 불일치 사례를 다룹니다. diff --git a/docs/ko-KR/reference/planning-artifacts.md b/docs/ko-KR/reference/planning-artifacts.md index 0447a9392..04c163b7a 100644 --- a/docs/ko-KR/reference/planning-artifacts.md +++ b/docs/ko-KR/reference/planning-artifacts.md @@ -23,6 +23,8 @@ │ ├── architecture.md │ ├── stack.md │ └── ... +├── onboarding/ # 브라운필드 온보딩 요약 (선택) +│ └── SUMMARY.md ├── intel/ # 쿼리 가능한 심볼 인덱스 (선택, intel.enabled) │ └── API-SURFACE.md └── phases/ @@ -48,7 +50,7 @@ | | | |---|---| | **목적** | 표준 프로젝트 아이덴티티: 무엇인지, 누구를 위한 것인지, 핵심 가치, 요구사항, 제약 사항, 주요 결정. 제품이 발전함에 따라 프로젝트 생명주기 전반에 걸쳐 업데이트됩니다. | -| **생성자** | `/gsd-new-project` (최초 생성); 결정이 검증됨에 따라 `/gsd-complete-milestone`에 의해 업데이트됩니다. | +| **생성자** | `/gsd-new-project` (최초 생성, `/gsd-onboard` handoff 포함); 결정이 검증됨에 따라 `/gsd-complete-milestone`에 의해 업데이트됩니다. | | **소비자** | 모든 플래닝 워크플로; `gsd-phase-researcher`, `gsd-planner` (컨텍스트); `discuss-phase` (이전 결정); `gsd-plan-checker` (프로젝트 제약 사항). | ### `ROADMAP.md` @@ -56,7 +58,7 @@ | | | |---|---| | **목적** | 목표, 요구사항 ID, 성공 기준, 페이즈별 표준 참조가 있는 마일스톤 및 페이즈 목록. 프로젝트가 무엇을 빌드하고 어떤 순서로 하는지에 대한 단일 진실의 원천. | -| **생성자** | `/gsd-new-project` (최초 생성); `/gsd-phase --insert`와 `/gsd-complete-milestone`에 의해 업데이트됩니다. | +| **생성자** | `/gsd-new-project` (최초 생성, `/gsd-onboard` handoff 포함); `/gsd-phase --insert`와 `/gsd-complete-milestone`에 의해 업데이트됩니다. | | **소비자** | `/gsd-discuss-phase`, `/gsd-plan-phase`, `/gsd-execute-phase`; 페이즈 정보가 필요한 모든 오케스트레이션 명령; `gsd-planner`, `gsd-plan-checker`, `gsd-phase-researcher`. | ### `REQUIREMENTS.md` @@ -64,7 +66,7 @@ | | | |---|---| | **목적** | 프로젝트의 번호가 매겨진 체크 가능한 인수 기준. 각 요구사항은 로드맵 페이즈에 매핑되는 ID(예: `AUTH-01`)를 가집니다. 페이즈가 실행됨에 따라 요구사항을 완료로 표시합니다. | -| **생성자** | `/gsd-new-project` (최초 생성); `execute-phase`에 의해 요구사항이 완료로 표시됩니다. | +| **생성자** | `/gsd-new-project` (최초 생성, `/gsd-onboard` handoff 포함); `execute-phase`에 의해 요구사항이 완료로 표시됩니다. | | **소비자** | `gsd-planner` (플랜은 모든 페이즈 요구사항 ID를 처리해야 함); `gsd-plan-checker` Dimension 1 (요구사항 커버리지); `discuss-phase` (이전 요구사항). | ### `STATE.md` @@ -72,7 +74,7 @@ | | | |---|---| | **목적** | 살아있는 위치 추적기 — 현재 페이즈와 플랜, 진행 지표, 누적된 결정, 세션 연속성 노트. 모든 워크플로 실행 시작 시 읽힙니다. 중요한 작업 이후 업데이트됩니다. | -| **생성자** | `/gsd-new-project` (최초 생성); 모든 페이즈 워크플로, `/gsd-pause-work`, `/gsd-resume-work`에 의해 지속적으로 업데이트됩니다. | +| **생성자** | `/gsd-new-project` (최초 생성, `/gsd-onboard` handoff 포함); 모든 페이즈 워크플로, `/gsd-pause-work`, `/gsd-resume-work`에 의해 지속적으로 업데이트됩니다. | | **소비자** | 모든 오케스트레이션 워크플로; `/gsd-progress`; `/gsd-quick`을 통한 임시 태스크 실행; `gsd-planner` 및 `gsd-phase-researcher` (프로젝트 결정). | 전체 필드 참조는 [STATE.md 스키마](state-md.md)를 참조하세요. @@ -87,6 +89,14 @@ 전체 스키마는 [CONFIGURATION](../../CONFIGURATION.md)을 참조하세요. +### `onboarding/SUMMARY.md` (선택) + +| | | +|---|---| +| **목적** | 브라운필드 온보딩 인덱스. 아티팩트 상태, 코드베이스 매핑 완료 여부, 초기 설정 후 권장되는 다음 GSD 명령을 기록합니다. | +| **생성자** | `PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md`, `STATE.md`가 모두 존재한 뒤 `/gsd-onboard`. | +| **소비자** | 초기 설정을 검토하는 사람; 기존 온보딩 상태를 확인하는 향후 `/gsd-onboard` 실행. | + ### `MILESTONES.md` (선택) | | | diff --git a/docs/ko-KR/tutorials/onboarding-an-existing-codebase.md b/docs/ko-KR/tutorials/onboarding-an-existing-codebase.md index 794d62534..6fe4b7c51 100644 --- a/docs/ko-KR/tutorials/onboarding-an-existing-codebase.md +++ b/docs/ko-KR/tutorials/onboarding-an-existing-codebase.md @@ -44,15 +44,15 @@ claude --dangerously-skip-permissions --- -## Step 3 — 코드베이스 매핑 +## Step 3 — 브라운필드 온보딩 시작 -프로젝트를 생성하기 전에 GSD Core가 이미 존재하는 것을 학습하도록 합니다. 이 단계가 브라운필드 계획의 정확도를 높이는 핵심입니다. +프로젝트를 생성하기 전에 GSD Core가 저장소 상태를 검사하고 안전한 다음 top-level 명령을 알려주게 하세요. 이 단계는 코드베이스 컨텍스트를 건너뛰거나 기존 planning 파일을 덮어쓰는 일을 방지합니다. ```text -/gsd-map-codebase +/gsd-onboard ``` -GSD Core가 4개의 병렬 매퍼 서브 에이전트를 생성합니다("Spawning 4 parallel codebase mapper agents…" 메시지가 표시되며, 1–5분 소요됩니다. 중단하지 마세요). 각 에이전트는 서로 다른 관심사에 집중합니다: +온보딩이 코드베이스 맵 누락을 보고하면 권장 옵션을 선택하고 출력된 `/gsd-map-codebase` handoff를 실행한 뒤 `/gsd-onboard`를 다시 실행합니다. `/gsd-onboard --fast`는 가벼운 첫 패스에는 충분하지만, `/gsd-new-project` 전에는 완전한 맵이 필요합니다. `/gsd-map-codebase`가 4개의 병렬 매퍼 서브 에이전트를 생성합니다("Spawning 4 parallel codebase mapper agents…" 메시지가 표시되며, 1–5분 소요됩니다. 중단하지 마세요). 각 에이전트는 서로 다른 관심사에 집중합니다: | 에이전트 | 집중 영역 | |---------|---------| @@ -84,7 +84,7 @@ Created .planning/codebase/: --- -## Step 4 — 컨텍스트 초기화 후 프로젝트 생성 +## Step 4 — 온보딩 재실행 및 프로젝트 초기화 세션 창을 초기화합니다: @@ -92,7 +92,7 @@ Created .planning/codebase/: /clear ``` -이제 프로젝트를 생성합니다. GSD Core가 이전 단계에서 기존 코드를 발견했으므로, 이미 이것이 브라운필드 프로젝트임을 알고 있습니다. `/gsd-new-project`를 실행하면 기존의 것을 재구성하는 것이 아니라 *추가하는* 것에 집중한 질문을 합니다: +이제 `/gsd-onboard`를 다시 실행합니다. GSD Core가 ADR, PRD, spec, RFC 또는 루트 요구사항 문서를 감지하면 먼저 권장되는 `/gsd-ingest-docs` handoff를 실행하고 이후 `/gsd-onboard`를 다시 실행하세요. 컨텍스트가 준비되면 온보딩이 프로젝트 초기화 handoff를 출력합니다: ```text /gsd-new-project @@ -124,6 +124,8 @@ Proposed Roadmap 로드맵을 승인합니다. +프로젝트 설정이 끝난 뒤 `/gsd-onboard`를 한 번 더 실행합니다. 이제 `PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md`, `STATE.md`가 모두 있으므로 온보딩은 `.planning/onboarding/SUMMARY.md`를 생성하거나 확인합니다. + **`.planning/`에 생성되는 파일:** ```text @@ -133,6 +135,7 @@ Proposed Roadmap ROADMAP.md ← Phase 1, 상태: pending STATE.md ← 세션 메모리 config.json ← 워크플로 설정 + onboarding/SUMMARY.md ← 온보딩 상태와 다음 명령 codebase/ ← Step 3에서 생성된 7개의 맵 파일 ``` @@ -212,6 +215,7 @@ GSD Core가 `CONVENTIONS.md`와 `ARCHITECTURE.md`를 읽었으므로, 질문들 ## 배운 내용 +- `/gsd-onboard`가 인터랙티브 명령을 중첩하거나 기존 planning 파일을 덮어쓰지 않고 브라운필드 설정을 안전하게 순서화하는 방법. - `/gsd-map-codebase`가 4개의 병렬 에이전트를 실행하여 `.planning/codebase/`에 `STACK.md`, `ARCHITECTURE.md`, `CONVENTIONS.md`, `CONCERNS.md`, `STRUCTURE.md`, `TESTING.md`, `INTEGRATIONS.md`를 생성하는 방법. - 브라운필드 저장소에서 `/gsd-new-project`가 *추가하는* 것에 집중한 질문을 하고 기존 코드에서 Validated 요구사항을 채우는 방법. - 코드베이스 맵이 `/gsd-discuss-phase`의 모든 질문을 형성하는 방법 — 파일 경로, 패턴, 컨벤션이 실제 코드에서 옵니다. diff --git a/docs/pt-BR/ARCHITECTURE.md b/docs/pt-BR/ARCHITECTURE.md index 4b2f1cf3f..14ff90570 100644 --- a/docs/pt-BR/ARCHITECTURE.md +++ b/docs/pt-BR/ARCHITECTURE.md @@ -527,7 +527,8 @@ Caminhos equivalentes para outros runtimes: │ ├── FEATURES.md │ ├── ARCHITECTURE.md │ └── PITFALLS.md -├── codebase/ # Mapeamento de brownfield (do /gsd-map-codebase) +├── codebase/ # Mapeamento de brownfield (do /gsd-map-codebase ou /gsd-onboard) +├── onboarding/ # Resumo de onboarding brownfield (do /gsd-onboard) │ ├── STACK.md # Frontmatter YAML carrega `last_mapped_commit` │ ├── ARCHITECTURE.md # para o portão de desvio pós-execução (#2003) │ ├── CONVENTIONS.md diff --git a/docs/pt-BR/CLI-TOOLS.md b/docs/pt-BR/CLI-TOOLS.md index 24441e6bd..107c3259a 100644 --- a/docs/pt-BR/CLI-TOOLS.md +++ b/docs/pt-BR/CLI-TOOLS.md @@ -290,13 +290,14 @@ node gsd-tools.cjs scaffold phase-dir --phase N --name "phase name" ## Comandos Init (Carregamento de Contexto Composto) -Carrega todo o contexto necessário para um fluxo de trabalho específico em uma única chamada. Retorna JSON com informações do projeto, configuração, estado e dados específicos do fluxo de trabalho. +Carrega todo o contexto necessário para um fluxo de trabalho específico em uma única chamada. Retorna JSON com informações do projeto, configuração, estado e dados específicos do fluxo de trabalho. `init onboard [--fast] [--text]` retorna, para `/gsd-onboard`, sinais de brownfield, candidatos a docs de planning, completude do mapa de código, prontidão do mapa fast, roteamento em modo texto, estado parcial de planning e status do resumo de onboarding. ```bash node gsd-tools.cjs init execute-phase node gsd-tools.cjs init plan-phase node gsd-tools.cjs init new-project node gsd-tools.cjs init new-milestone +node gsd-tools.cjs init onboard [--fast] [--text] node gsd-tools.cjs init quick node gsd-tools.cjs init resume node gsd-tools.cjs init verify-work diff --git a/docs/pt-BR/COMMANDS.md b/docs/pt-BR/COMMANDS.md index e8b74bb13..dc7e978e1 100644 --- a/docs/pt-BR/COMMANDS.md +++ b/docs/pt-BR/COMMANDS.md @@ -51,6 +51,25 @@ Inicializa um novo projeto com coleta aprofundada de contexto. --- +### `/gsd-onboard` + +Guia o onboarding inicial de um código existente no GSD. O comando verifica o estado do repositório, encaminha com segurança por mapeamento da base de código, ingestão opcional de documentos, inicialização do projeto e cria um onboarding summary quando o planejamento existe. + +| Flag | Descrição | +|------|-----------| +| `--fast` | Prefere o handoff leve `/gsd-map-codebase --fast`; um mapa completo ainda é necessário antes de `/gsd-new-project` | +| `--text` | Usa gates numerados em texto puro em vez de menus TUI | + +**Pré-requisitos:** Repositório existente ou documentos de planejamento. Para projetos greenfield vazios, use `/gsd-new-project`. +**Produz:** `.planning/codebase/` via map-codebase, `.planning/` via new-project ou ingest-docs, e `.planning/onboarding/SUMMARY.md` após a configuração do projeto. + +```bash +/gsd-onboard # Onboarding brownfield guiado +/gsd-onboard --fast # Usa primeiro o mapa leve e depois completa o mapa antes do setup do projeto +``` + +--- + ### `/gsd-workspace` Gerencia workspaces do GSD — cria, lista ou remove ambientes de workspace isolados com cópias de repositório e diretórios `.planning/` independentes. diff --git a/docs/pt-BR/FEATURES.md b/docs/pt-BR/FEATURES.md index 186d504a8..ade045a95 100644 --- a/docs/pt-BR/FEATURES.md +++ b/docs/pt-BR/FEATURES.md @@ -14,7 +14,7 @@ Para catálogo completo e detalhamento exaustivo, consulte [FEATURES.md em ingl - **Commits atômicos por tarefa** para rastreabilidade e rollback - **Verificação pós-execução** com foco em objetivos da fase - **UAT guiado** via `/gsd-verify-work` -- **Suporte brownfield** com `/gsd-map-codebase` +- **Suporte brownfield** com `/gsd-onboard` e `/gsd-map-codebase` - **Workstreams** para trilhas paralelas sem colisão de estado - **Backlog, seeds e threads** para memória de médio/longo prazo @@ -68,7 +68,7 @@ Para catálogo completo e detalhamento exaustivo, consulte [FEATURES.md em ingl |--------|----------| | Projeto novo | `/gsd-new-project` -> `/gsd-discuss-phase` -> `/gsd-plan-phase` -> `/gsd-execute-phase` | | Correção rápida | `/gsd-quick` | -| Código existente | `/gsd-map-codebase` -> `/gsd-new-project` | +| Código existente | `/gsd-onboard` -> handoffs para `/gsd-map-codebase`, `/gsd-ingest-docs`, `/gsd-new-project` | | Fechamento de release | `/gsd-audit-milestone` -> `/gsd-complete-milestone` | --- diff --git a/docs/pt-BR/INVENTORY.md b/docs/pt-BR/INVENTORY.md index c10cbe76e..7be789824 100644 --- a/docs/pt-BR/INVENTORY.md +++ b/docs/pt-BR/INVENTORY.md @@ -78,6 +78,7 @@ Esses seis roteadores são entradas apenas descritivas que o modelo seleciona pr | Comando | Função | Fonte | |---------|--------|-------| | `/gsd-new-project` | Inicializa um novo projeto com coleta profunda de contexto e PROJECT.md. | [commands/gsd/new-project.md](../../commands/gsd/new-project.md) | +| `/gsd-onboard` | Guia código existente por mapeamento, ingestão de docs, configuração de projeto e onboarding summary. | [commands/gsd/onboard.md](../../commands/gsd/onboard.md) | | `/gsd-workspace` | Gerencia workspaces GSD — criar (`--new`), listar (`--list`) ou remover (`--remove`) ambientes de workspace isolados. | [commands/gsd/workspace.md](../../commands/gsd/workspace.md) | | `/gsd-discuss-phase` | Coleta contexto da fase por meio de perguntas adaptativas antes do planejamento. | [commands/gsd/discuss-phase.md](../../commands/gsd/discuss-phase.md) | | `/gsd-mvp-phase` | Planeja uma fase como uma fatia vertical de MVP — história de usuário, divisão SPIDR, depois plan-phase. | [commands/gsd/mvp-phase.md](../../commands/gsd/mvp-phase.md) | @@ -218,6 +219,7 @@ Registro completo em `get-shit-done/workflows/*.md`. Workflows são orquestrador | `milestone-summary.md` | Síntese do resumo do milestone — artefato de onboarding e revisão a partir dos artefatos do milestone. | `/gsd-milestone-summary` | | `new-milestone.md` | Inicia um novo ciclo de milestone — carregar contexto do projeto, coletar objetivos, atualizar PROJECT.md/STATE.md. | `/gsd-new-milestone` | | `new-project.md` | Fluxo unificado de novo projeto — questionamento, pesquisa (opcional), requisitos, roadmap. | `/gsd-new-project` | +| `onboard.md` | Orquestração de onboarding brownfield — mapear código, ingerir docs, inicializar planning e resumir próximo passo. | `/gsd-onboard` | | `new-workspace.md` | Cria um workspace isolado com worktrees/clones do repositório e um `.planning/` independente. | `/gsd-workspace --new` | | `next.md` | Detecta o estado atual do projeto e avança automaticamente para o próximo passo lógico. | `/gsd-progress --next` | | `node-repair.md` | Operador de reparo autônomo para verificação de tarefa com falha; invocado por `execute-plan`. | `execute-plan.md` (recuperação) | diff --git a/docs/pt-BR/USER-GUIDE.md b/docs/pt-BR/USER-GUIDE.md index e0b269607..c5f0a393b 100644 --- a/docs/pt-BR/USER-GUIDE.md +++ b/docs/pt-BR/USER-GUIDE.md @@ -474,8 +474,8 @@ claude --dangerously-skip-permissions ### Base de código existente ```bash -/gsd-map-codebase # Analyse what exists (parallel agents) -/gsd-new-project # Questions focus on what you're ADDING +/gsd-onboard # Safely map, ingest docs, and initialize planning +# Follow printed handoff commands, then rerun /gsd-onboard # (normal phase workflow from here) ``` @@ -864,7 +864,8 @@ Para desativar a execução paralela completamente: `/gsd-settings` → defina ` themes/ default.css # Shared CSS variables for all sketches MANIFEST.md # Index of all sketches with winners - codebase/ # Brownfield codebase mapping (from /gsd-map-codebase) + codebase/ # Brownfield codebase mapping (from /gsd-map-codebase or /gsd-onboard) + onboarding/ # Brownfield onboarding summary (from /gsd-onboard) phases/ XX-phase-name/ XX-YY-PLAN.md # Atomic execution plans diff --git a/docs/pt-BR/how-to/install-on-your-runtime.md b/docs/pt-BR/how-to/install-on-your-runtime.md index ba0d31ea1..3b70bc4e8 100644 --- a/docs/pt-BR/how-to/install-on-your-runtime.md +++ b/docs/pt-BR/how-to/install-on-your-runtime.md @@ -273,10 +273,11 @@ npx @opengsd/gsd-core@latest --opencode --global ## Após a instalação -Reinicie seu ambiente para carregar os novos comandos e agentes. Em seguida, inicie seu primeiro projeto: +Reinicie seu ambiente para carregar os novos comandos e agentes. Em seguida, inicie um projeto novo ou faça onboarding de um repositório existente: ```bash -/gsd-new-project +/gsd-new-project # projeto greenfield +/gsd-onboard # base de código existente ``` Se o comando não for encontrado após o reinício, verifique se o diretório de instalação corresponde ao caminho de configuração esperado pelo ambiente. A seção de edições de pré-lançamento acima cobre a incompatibilidade mais comum. diff --git a/docs/pt-BR/reference/planning-artifacts.md b/docs/pt-BR/reference/planning-artifacts.md index 7d6859acc..5ddb9ecfa 100644 --- a/docs/pt-BR/reference/planning-artifacts.md +++ b/docs/pt-BR/reference/planning-artifacts.md @@ -23,6 +23,8 @@ O diretório `.planning/` é a memória compartilhada do GSD Core para um projet │ ├── architecture.md │ ├── stack.md │ └── ... +├── onboarding/ # Resumo de onboarding brownfield (opcional) +│ └── SUMMARY.md ├── intel/ # Índice de símbolos consultável (opcional, intel.enabled) │ └── API-SURFACE.md └── phases/ @@ -48,7 +50,7 @@ O diretório `.planning/` é a memória compartilhada do GSD Core para um projet | | | |---|---| | **Finalidade** | Identidade canônica do projeto: o que é, para quem é, valor central, requisitos, restrições e decisões-chave. Atualizado ao longo do ciclo de vida do projeto conforme o produto evolui. | -| **Produzido por** | `/gsd-new-project` (criação inicial); atualizado por `/gsd-complete-milestone` à medida que as decisões são validadas. | +| **Produzido por** | `/gsd-new-project` (criação inicial, incluindo handoff do `/gsd-onboard`); atualizado por `/gsd-complete-milestone` à medida que as decisões são validadas. | | **Consumido por** | Todos os fluxos de trabalho de planejamento; `gsd-phase-researcher`, `gsd-planner` (contexto); `discuss-phase` (decisões anteriores); `gsd-plan-checker` (restrições do projeto). | ### `ROADMAP.md` @@ -56,7 +58,7 @@ O diretório `.planning/` é a memória compartilhada do GSD Core para um projet | | | |---|---| | **Finalidade** | Listagem de marcos e fases com objetivos, IDs de requisitos, critérios de sucesso e referências canônicas por fase. A fonte única de verdade sobre o que o projeto está construindo e em que ordem. | -| **Produzido por** | `/gsd-new-project` (criação inicial); atualizado por `/gsd-phase --insert` e `/gsd-complete-milestone`. | +| **Produzido por** | `/gsd-new-project` (criação inicial, incluindo handoff do `/gsd-onboard`); atualizado por `/gsd-phase --insert` e `/gsd-complete-milestone`. | | **Consumido por** | `/gsd-discuss-phase`, `/gsd-plan-phase`, `/gsd-execute-phase`; todos os comandos de orquestração que precisam de informações de fase; `gsd-planner`, `gsd-plan-checker`, `gsd-phase-researcher`. | ### `REQUIREMENTS.md` @@ -64,7 +66,7 @@ O diretório `.planning/` é a memória compartilhada do GSD Core para um projet | | | |---|---| | **Finalidade** | Critérios de aceitação numerados e verificáveis para o projeto. Cada requisito possui um ID (ex.: `AUTH-01`) que mapeia para as fases do roadmap. Marca os requisitos como concluídos conforme as fases são executadas. | -| **Produzido por** | `/gsd-new-project` (criação inicial); requisitos marcados como concluídos por `execute-phase`. | +| **Produzido por** | `/gsd-new-project` (criação inicial, incluindo handoff do `/gsd-onboard`); requisitos marcados como concluídos por `execute-phase`. | | **Consumido por** | `gsd-planner` (os planos devem contemplar todos os IDs de requisitos da fase); `gsd-plan-checker` Dimensão 1 (cobertura de requisitos); `discuss-phase` (requisitos anteriores). | ### `STATE.md` @@ -72,7 +74,7 @@ O diretório `.planning/` é a memória compartilhada do GSD Core para um projet | | | |---|---| | **Finalidade** | Rastreador de posição em andamento — fase e plano atuais, métricas de progresso, decisões acumuladas, notas de continuidade de sessão. Lido no início de toda execução de fluxo de trabalho. Atualizado após cada ação significativa. | -| **Produzido por** | `/gsd-new-project` (criação inicial); atualizado continuamente por todos os fluxos de fase, `/gsd-pause-work`, `/gsd-resume-work`. | +| **Produzido por** | `/gsd-new-project` (criação inicial, incluindo handoff do `/gsd-onboard`); atualizado continuamente por todos os fluxos de fase, `/gsd-pause-work`, `/gsd-resume-work`. | | **Consumido por** | Todos os fluxos de orquestração; `/gsd-progress`; execução de tarefas avulsas via `/gsd-quick`; `gsd-planner` e `gsd-phase-researcher` (decisões do projeto). | Consulte o [esquema de STATE.md](state-md.md) para a referência completa de campos. @@ -87,6 +89,14 @@ Consulte o [esquema de STATE.md](state-md.md) para a referência completa de cam Consulte [CONFIGURATION](../CONFIGURATION.md) para o esquema completo. +### `onboarding/SUMMARY.md` (opcional) + +| | | +|---|---| +| **Finalidade** | Índice de onboarding brownfield que registra status dos artefatos, se o mapeamento do código-base está completo e o próximo comando GSD recomendado após a configuração inicial. | +| **Produzido por** | `/gsd-onboard` depois que `PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md` e `STATE.md` existem. | +| **Consumido por** | Humanos revisando a configuração inicial; futuras execuções de `/gsd-onboard` ao confirmar o estado de onboarding existente. | + ### `MILESTONES.md` (opcional) | | | diff --git a/docs/pt-BR/tutorials/onboarding-an-existing-codebase.md b/docs/pt-BR/tutorials/onboarding-an-existing-codebase.md index 760cf362f..4e8a99c76 100644 --- a/docs/pt-BR/tutorials/onboarding-an-existing-codebase.md +++ b/docs/pt-BR/tutorials/onboarding-an-existing-codebase.md @@ -44,15 +44,15 @@ claude --dangerously-skip-permissions --- -## Passo 3 — Mapear a base de código +## Passo 3 — Iniciar o onboarding brownfield -Antes de criar um projeto, deixe o GSD Core aprender o que já existe. Este é o passo que torna o planejamento brownfield preciso. +Antes de criar um projeto, deixe o GSD Core inspecionar o estado do repositório e indicar o próximo comando de nível superior seguro. Este passo evita pular contexto de código ou sobrescrever arquivos de planning existentes. ```text -/gsd-map-codebase +/gsd-onboard ``` -O GSD Core cria quatro sub-agentes mapeadores paralelos (você verá "Spawning 4 parallel codebase mapper agents…" — isso leva de 1 a 5 minutos; não interrompa). Cada agente foca em uma preocupação diferente: +Se o onboarding informar que o mapa da base de código está ausente, escolha a opção recomendada e execute o handoff `/gsd-map-codebase` impresso antes de rodar `/gsd-onboard` novamente. `/gsd-onboard --fast` serve para uma primeira passada leve, mas um mapa completo ainda é necessário antes de `/gsd-new-project`. O `/gsd-map-codebase` cria quatro sub-agentes mapeadores paralelos (você verá "Spawning 4 parallel codebase mapper agents…" — isso leva de 1 a 5 minutos; não interrompa). Cada agente foca em uma preocupação diferente: | Agente | Foco | |--------|------| @@ -84,7 +84,7 @@ Abra `.planning/codebase/CONCERNS.md`. Este é o arquivo mais útil para ler ant --- -## Passo 4 — Limpar o contexto e criar o projeto +## Passo 4 — Reexecutar o onboarding e inicializar o projeto Limpe a janela de sessão: @@ -92,12 +92,14 @@ Limpe a janela de sessão: /clear ``` -Agora crie o projeto. Como o GSD Core encontrou código existente no passo anterior, já sabe que se trata de um projeto brownfield. Quando você executa `/gsd-new-project`, as perguntas focam no que você está *adicionando*, e não em reconstruir o que já existe: +Agora execute `/gsd-onboard` novamente. Se o GSD Core detectar ADRs, PRDs, specs, RFCs ou requisitos de nível raiz, aceite o handoff recomendado para `/gsd-ingest-docs` primeiro e depois rode `/gsd-onboard` de novo. Quando o contexto estiver pronto, o onboarding imprimirá o handoff de inicialização: ```text /gsd-new-project ``` +Como o GSD Core encontrou código existente no passo anterior, `/gsd-new-project` sabe que é um projeto brownfield. As perguntas focam no que você está *adicionando*, não em reconstruir o que já existe: + O GSD Core pergunta o que você quer construir. Responda com o recurso que está adicionando, e não com uma descrição de toda a base de código: ```text @@ -124,6 +126,8 @@ Proposed Roadmap Aprove o roteiro. +Execute `/gsd-onboard` mais uma vez depois que a configuração do projeto terminar. Agora que `PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md` e `STATE.md` existem, o onboarding cria ou confirma `.planning/onboarding/SUMMARY.md`. + **O que é criado em `.planning/`:** ```text @@ -133,6 +137,7 @@ Aprove o roteiro. ROADMAP.md ← Fase 1, status: pending STATE.md ← memória de sessão config.json ← configurações do fluxo de trabalho + onboarding/SUMMARY.md ← status do onboarding e próximo comando codebase/ ← os sete arquivos de mapa do Passo 3 ``` @@ -212,6 +217,7 @@ Para cada recurso futuro, execute `/gsd-map-codebase` novamente sempre que a est ## O que você aprendeu +- Como `/gsd-onboard` sequencia com segurança o setup brownfield sem aninhar comandos interativos ou sobrescrever planning existente. - Como `/gsd-map-codebase` executa quatro agentes paralelos para produzir `STACK.md`, `ARCHITECTURE.md`, `CONVENTIONS.md`, `CONCERNS.md`, `STRUCTURE.md`, `TESTING.md` e `INTEGRATIONS.md` em `.planning/codebase/`. - Como `/gsd-new-project` em um repositório brownfield concentra as perguntas no que você está *adicionando* e preenche os requisitos Validated a partir do código existente. - Como o mapa da base de código orienta cada pergunta em `/gsd-discuss-phase` — caminhos de arquivos, padrões e convenções vêm do seu código real. diff --git a/docs/reference/planning-artifacts.md b/docs/reference/planning-artifacts.md index 5d7dd5e6a..d62c32005 100644 --- a/docs/reference/planning-artifacts.md +++ b/docs/reference/planning-artifacts.md @@ -23,6 +23,8 @@ The `.planning/` directory is GSD Core's shared memory for a project. Every work │ ├── architecture.md │ ├── stack.md │ └── ... +├── onboarding/ # Brownfield onboarding summary (optional) +│ └── SUMMARY.md ├── intel/ # Queryable symbol index (optional, intel.enabled) │ └── API-SURFACE.md └── phases/ @@ -48,7 +50,7 @@ The `.planning/` directory is GSD Core's shared memory for a project. Every work | | | |---|---| | **Purpose** | Canonical project identity: what it is, who it is for, core value, requirements, constraints, and key decisions. Updated throughout the project lifecycle as the product evolves. | -| **Produced by** | `/gsd-new-project` (initial creation); updated by `/gsd-complete-milestone` as decisions are validated. | +| **Produced by** | `/gsd-new-project` (initial creation, including `/gsd-onboard` handoff); updated by `/gsd-complete-milestone` as decisions are validated. | | **Consumed by** | All planning workflows; `gsd-phase-researcher`, `gsd-planner` (context); `discuss-phase` (prior decisions); `gsd-plan-checker` (project constraints). | Includes an optional `## Business Context` section (Customer, Revenue model, Success metric, Strategy notes) for monetized or customer-facing projects — four one-line fields that connect business outcomes to requirement prioritization. It is deleted for internal tools, experiments, or meta workspaces, and reviewed at each milestone by `/gsd-complete-milestone` when present. @@ -58,7 +60,7 @@ Includes an optional `## Business Context` section (Customer, Revenue model, Suc | | | |---|---| | **Purpose** | Milestone and phase listing with goals, requirement IDs, success criteria, and canonical references per phase. The single source of truth for what the project is building and in what order. | -| **Produced by** | `/gsd-new-project` (initial creation); updated by `/gsd-phase --insert` and `/gsd-complete-milestone`. | +| **Produced by** | `/gsd-new-project` (initial creation, including `/gsd-onboard` handoff); updated by `/gsd-phase --insert` and `/gsd-complete-milestone`. | | **Consumed by** | `/gsd-discuss-phase`, `/gsd-plan-phase`, `/gsd-execute-phase`; all orchestration commands that need phase information; `gsd-planner`, `gsd-plan-checker`, `gsd-phase-researcher`. | ### `REQUIREMENTS.md` @@ -66,7 +68,7 @@ Includes an optional `## Business Context` section (Customer, Revenue model, Suc | | | |---|---| | **Purpose** | Numbered, checkable acceptance criteria for the project. Each requirement carries an ID (e.g., `AUTH-01`) that maps to roadmap phases. Marks requirements complete as phases are executed. | -| **Produced by** | `/gsd-new-project` (initial creation); requirements marked complete by `execute-phase`. | +| **Produced by** | `/gsd-new-project` (initial creation, including `/gsd-onboard` handoff); requirements marked complete by `execute-phase`. | | **Consumed by** | `gsd-planner` (plans must address all phase requirement IDs); `gsd-plan-checker` Dimension 1 (requirement coverage); `discuss-phase` (prior requirements). | ### `STATE.md` @@ -74,7 +76,7 @@ Includes an optional `## Business Context` section (Customer, Revenue model, Suc | | | |---|---| | **Purpose** | Living position tracker — current phase and plan, progress metrics, accumulated decisions, session continuity notes. Read at the start of every workflow run. Updated after every significant action. | -| **Produced by** | `/gsd-new-project` (initial creation); updated continuously by all phase workflows, `/gsd-pause-work`, `/gsd-resume-work`. | +| **Produced by** | `/gsd-new-project` (initial creation, including `/gsd-onboard` handoff); updated continuously by all phase workflows, `/gsd-pause-work`, `/gsd-resume-work`. | | **Consumed by** | All orchestration workflows; `/gsd-progress`; ad-hoc task execution via `/gsd-quick`; `gsd-planner` and `gsd-phase-researcher` (project decisions). | See [STATE.md schema](state-md.md) for the full field reference. @@ -89,6 +91,14 @@ See [STATE.md schema](state-md.md) for the full field reference. See [CONFIGURATION](../CONFIGURATION.md) for the complete schema. +### `onboarding/SUMMARY.md` (optional) + +| | | +|---|---| +| **Purpose** | Brownfield onboarding index that records artifact status, whether codebase mapping is complete, and the next recommended GSD command after first-time setup. | +| **Produced by** | `/gsd-onboard` after `PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md`, and `STATE.md` all exist. | +| **Consumed by** | Humans reviewing first-time setup; future `/gsd-onboard` runs when confirming existing onboarding state. | + ### `MILESTONES.md` (optional) | | | diff --git a/docs/tutorials/onboarding-an-existing-codebase.md b/docs/tutorials/onboarding-an-existing-codebase.md index 22c536f4a..fd6774ee4 100644 --- a/docs/tutorials/onboarding-an-existing-codebase.md +++ b/docs/tutorials/onboarding-an-existing-codebase.md @@ -44,15 +44,21 @@ claude --dangerously-skip-permissions --- -## Step 3 — Map the codebase +## Step 3 — Start brownfield onboarding -Before creating a project, let GSD Core learn what already exists. This is the step that makes brownfield planning accurate. +Before creating a project, let GSD Core inspect the repo state and tell you the safe next top-level command. This is the step that prevents brownfield setup from skipping codebase context or overwriting existing planning files. + +```text +/gsd-onboard +``` + +If code exists and `.planning/codebase/` is missing, GSD Core asks you to map the codebase first. Choose the recommended mapping option, then run the printed handoff command: ```text /gsd-map-codebase ``` -GSD Core spawns four parallel mapper sub-agents (you'll see "Spawning 4 parallel codebase mapper agents…" — this takes 1–5 minutes; do not interrupt). Each agent focuses on a different concern: +Use `/gsd-onboard --fast` if you want the onboarding gate to prefer `/gsd-map-codebase --fast` for a lighter first pass. Fast mode is only enough for lightweight onboarding; `/gsd-onboard` still sends you back to the full mapper before `/gsd-new-project`. The full mapper spawns four parallel mapper sub-agents (you'll see "Spawning 4 parallel codebase mapper agents…" — this takes 1–5 minutes; do not interrupt). Each agent focuses on a different concern: | Agent | Focus | |-------|-------| @@ -84,7 +90,7 @@ Open `.planning/codebase/CONCERNS.md`. This is the most useful file to read befo --- -## Step 4 — Clear context and create the project +## Step 4 — Rerun onboarding and initialize the project Clear the session window: @@ -92,12 +98,20 @@ Clear the session window: /clear ``` -Now create the project. Because GSD Core found existing code in the last step, it already knows this is a brownfield project. When you run `/gsd-new-project`, the questions focus on what you are *adding*, not rebuilding what already exists: +Now rerun onboarding: + +```text +/gsd-onboard +``` + +If GSD Core detects ADRs, PRDs, specs, RFCs, or top-level requirements docs, choose the recommended docs-ingest handoff first and rerun `/gsd-onboard` afterward. Once codebase context and any existing docs are handled, onboarding prints the project-initialization handoff: ```text /gsd-new-project ``` +Because GSD Core found existing code in the previous step, `/gsd-new-project` knows this is a brownfield project. The questions focus on what you are *adding*, not rebuilding what already exists: + GSD Core asks what you want to build. Answer with the feature you are adding, not a description of the whole codebase: ```text @@ -138,6 +152,20 @@ Approve the roadmap. Notice that `.planning/codebase/` is already there from Step 3. GSD Core read those files when writing `PROJECT.md`, which is why it could populate the Validated requirements without you describing them. +Run onboarding one more time after project setup completes: + +```text +/gsd-onboard +``` + +Now that `PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md`, and `STATE.md` all exist, onboarding creates or confirms: + +```text +.planning/onboarding/SUMMARY.md +``` + +This summary is a lightweight index of the setup artifacts and the next command to run. + --- ## Step 5 — Clear context and discuss Phase 1 @@ -206,12 +234,13 @@ You now have a project with a codebase map, a discuss decision record, and verif /gsd-ship 1 ``` -For every future feature, run `/gsd-map-codebase` again whenever the structure changes significantly, so the codebase map stays fresh. +For every future feature, run `/gsd-map-codebase` again whenever the structure changes significantly, so the codebase map stays fresh. Rerun `/gsd-onboard` only when you want to re-check first-time setup completeness or regenerate the onboarding summary. --- ## What you've learned +- How `/gsd-onboard` safely sequences brownfield setup without nesting interactive commands or overwriting existing planning files. - How `/gsd-map-codebase` runs four parallel agents to produce `STACK.md`, `ARCHITECTURE.md`, `CONVENTIONS.md`, `CONCERNS.md`, `STRUCTURE.md`, `TESTING.md`, and `INTEGRATIONS.md` in `.planning/codebase/`. - How `/gsd-new-project` in a brownfield repo focuses questions on what you are *adding* and populates Validated requirements from existing code. - How the codebase map shapes every question in `/gsd-discuss-phase` — file paths, patterns, and conventions come from your actual code. @@ -222,5 +251,5 @@ For every future feature, run `/gsd-map-codebase` again whenever the structure c ## Related - [Your first project](your-first-project.md) — the full greenfield loop from install to PR -- [Map codebase via Commands](../COMMANDS.md) — all `/gsd-map-codebase` flags and subcommands +- [Commands](../COMMANDS.md) — `/gsd-onboard`, plus all `/gsd-map-codebase` flags and subcommands - [Documentation index](../README.md) diff --git a/docs/zh-CN/ARCHITECTURE.md b/docs/zh-CN/ARCHITECTURE.md index 5a92e72bb..6395b3733 100644 --- a/docs/zh-CN/ARCHITECTURE.md +++ b/docs/zh-CN/ARCHITECTURE.md @@ -512,7 +512,8 @@ UI-SPEC.md (per phase) ─────────────────── │ ├── FEATURES.md │ ├── ARCHITECTURE.md │ └── PITFALLS.md -├── codebase/ # Brownfield mapping (from /gsd-map-codebase) +├── codebase/ # Brownfield mapping (from /gsd-map-codebase or /gsd-onboard) +├── onboarding/ # Brownfield onboarding summary (from /gsd-onboard) │ ├── STACK.md # YAML frontmatter carries `last_mapped_commit` │ ├── ARCHITECTURE.md # for the post-execute drift gate (#2003) │ ├── CONVENTIONS.md diff --git a/docs/zh-CN/CLI-TOOLS.md b/docs/zh-CN/CLI-TOOLS.md index ff86c98e9..b141cb17e 100644 --- a/docs/zh-CN/CLI-TOOLS.md +++ b/docs/zh-CN/CLI-TOOLS.md @@ -288,13 +288,14 @@ node gsd-tools.cjs scaffold phase-dir --phase N --name "phase name" ## Init 命令(复合上下文加载) -通过单次调用加载特定工作流所需的所有上下文。返回包含项目信息、配置、状态和工作流专属数据的 JSON。 +通过单次调用加载特定工作流所需的所有上下文。返回包含项目信息、配置、状态和工作流专属数据的 JSON。`init onboard [--fast] [--text]` 会为 `/gsd-onboard` 返回 brownfield 信号、planning 文档候选、代码库映射完整性、fast 映射就绪状态、文本模式路由、部分 planning 状态和 onboarding summary 状态。 ```bash node gsd-tools.cjs init execute-phase node gsd-tools.cjs init plan-phase node gsd-tools.cjs init new-project node gsd-tools.cjs init new-milestone +node gsd-tools.cjs init onboard [--fast] [--text] node gsd-tools.cjs init quick node gsd-tools.cjs init resume node gsd-tools.cjs init verify-work diff --git a/docs/zh-CN/COMMANDS.md b/docs/zh-CN/COMMANDS.md index 10d808254..3985a0928 100644 --- a/docs/zh-CN/COMMANDS.md +++ b/docs/zh-CN/COMMANDS.md @@ -51,6 +51,25 @@ v1.40 中,六个命名空间路由器作为第一阶段入口点随附发布 --- +### `/gsd-onboard` + +引导现有代码库完成首次 GSD 接入。该命令检查仓库状态,安全地转到代码库映射、可选文档摄取、项目初始化,并在规划文件齐备后创建 onboarding summary。 + +| 标志 | 描述 | +|------|-------------| +| `--fast` | 优先使用轻量 `/gsd-map-codebase --fast` 映射交接;在 `/gsd-new-project` 前仍需要完整映射 | +| `--text` | 使用编号纯文本关卡,而不是 TUI 菜单 | + +**前提条件:** 现有仓库或规划文档。空的绿地项目请使用 `/gsd-new-project`。 +**产出:** 由 map-codebase 生成的 `.planning/codebase/`,由 new-project 或 ingest-docs 生成的 `.planning/`,以及项目设置后的 `.planning/onboarding/SUMMARY.md`。 + +```bash +/gsd-onboard # 引导式 brownfield 接入 +/gsd-onboard --fast # 先使用轻量映射,并在项目设置前补全完整映射 +``` + +--- + ### `/gsd-workspace` 管理 GSD 工作区 — 创建、列出或移除隔离的工作区环境,包含仓库副本和独立的 `.planning/` 目录。 diff --git a/docs/zh-CN/FEATURES.md b/docs/zh-CN/FEATURES.md index abfbea94e..80953d3af 100644 --- a/docs/zh-CN/FEATURES.md +++ b/docs/zh-CN/FEATURES.md @@ -38,6 +38,7 @@ - [模型配置](#26-model-profiles) - [棕地功能](#brownfield-features) - [代码库映射](#27-codebase-mapping) + - [现有代码库接入](#27b-现有代码库接入) - [实用功能](#utility-features) - [调试系统](#28-debug-system) - [待办事项管理](#29-todo-management) @@ -783,7 +784,7 @@ **命令:** `/gsd-map-codebase [area]` -**目的:** 在启动新项目之前分析现有代码库,使 GSD 了解已有内容。 +**目的:** 在启动新项目之前,或作为 `/gsd-onboard` 的映射交接,分析现有代码库,使 GSD 了解已有内容。 **需求:** - REQ-MAP-01:系统必须为每个分析领域派生并行映射智能体 @@ -805,6 +806,27 @@ **增量重映射 — `--paths` (#2003):** 映射器接受可选的 `--paths ` 范围提示。提供时,它将探索限制在列出的仓库相对前缀,而非扫描整个代码树。这是执行后代码库漂移门控用于仅刷新阶段实际修改的子树的路径。每个生成的文档在其 YAML 前置元数据中携带 `last_mapped_commit`,以便相对于映射点(而非 HEAD)来测量漂移。 +### 27b. 现有代码库接入 + +**命令:** `/gsd-onboard [--fast] [--text]` + +**目的:** 引导现有仓库完成首次设置,检查 brownfield 状态,并安全交接到代码库映射、docs 摄取和项目初始化。 + +**需求:** +- REQ-ONBOARD-01:系统必须检测现有代码、package manifest、规划文档、部分 `.planning/` 状态以及缺失的代码库映射文件。 +- REQ-ONBOARD-02:当 brownfield 缺少所需 `.planning/codebase/` 映射文件时,系统必须交接到 `/gsd-map-codebase` 或 `/gsd-map-codebase --fast`。fast 映射 readiness 是部分状态,不得视为足以运行 `/gsd-new-project`。 +- REQ-ONBOARD-03:当存在 ADR/PRD/SPEC/RFC 候选且 project 不存在时,系统必须在 `/gsd-new-project` 前提供 `/gsd-ingest-docs`。 +- REQ-ONBOARD-04:在 `PROJECT.md`、`REQUIREMENTS.md`、`ROADMAP.md`、`STATE.md` 全部存在前,系统不得报告 onboarding 完成。 +- REQ-ONBOARD-05:系统必须仅在 project setup 后创建或确认 `.planning/onboarding/SUMMARY.md`。 +- REQ-ONBOARD-06:系统必须为没有交互式菜单的运行时支持 `--text` 编号纯文本关卡。 + +**产出:** +| Artifact | 说明 | +|----------|-------------| +| `.planning/codebase/` | 由 `/gsd-map-codebase` 交接生成的代码库映射 | +| `.planning/PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md`, `STATE.md` | 由 `/gsd-new-project` 或 `/gsd-ingest-docs` 生成的规划设置 | +| `.planning/onboarding/SUMMARY.md` | Onboarding status、artifact index 和 next-command summary | + ### 27a. 执行后代码库漂移检测 **引入版本:** #2003 diff --git a/docs/zh-CN/INVENTORY.md b/docs/zh-CN/INVENTORY.md index d6344bfba..e1d295914 100644 --- a/docs/zh-CN/INVENTORY.md +++ b/docs/zh-CN/INVENTORY.md @@ -78,6 +78,7 @@ | 命令 | 角色 | 源文件 | |------|------|--------| | `/gsd-new-project` | 通过深度上下文收集和 PROJECT.md 初始化新项目。 | [commands/gsd/new-project.md](../../commands/gsd/new-project.md) | +| `/gsd-onboard` | 引导现有代码库完成映射、文档摄取、项目设置和 onboarding summary。 | [commands/gsd/onboard.md](../../commands/gsd/onboard.md) | | `/gsd-workspace` | 管理 GSD 工作区 — 创建(`--new`)、列出(`--list`)或移除(`--remove`)隔离的工作区环境。 | [commands/gsd/workspace.md](../../commands/gsd/workspace.md) | | `/gsd-discuss-phase` | 在规划前通过自适应提问收集阶段上下文。 | [commands/gsd/discuss-phase.md](../../commands/gsd/discuss-phase.md) | | `/gsd-mvp-phase` | 将阶段规划为垂直 MVP 切片 — 用户故事、SPIDR 拆分,然后进行阶段规划。 | [commands/gsd/mvp-phase.md](../../commands/gsd/mvp-phase.md) | @@ -218,6 +219,7 @@ | `milestone-summary.md` | 里程碑摘要综合 — 从里程碑产物生成的入职和审查产物。 | `/gsd-milestone-summary` | | `new-milestone.md` | 启动新里程碑周期 — 加载项目上下文、收集目标、更新 PROJECT.md/STATE.md。 | `/gsd-new-milestone` | | `new-project.md` | 统一的新项目流程 — 提问、研究(可选)、需求、路线图。 | `/gsd-new-project` | +| `onboard.md` | Brownfield 接入编排 — 映射代码库、摄取文档、初始化规划并总结下一步。 | `/gsd-onboard` | | `new-workspace.md` | 创建带有仓库 worktree/克隆和独立 `.planning/` 的隔离工作区。 | `/gsd-workspace --new` | | `next.md` | 检测当前项目状态并自动推进到下一个逻辑步骤。 | `/gsd-progress --next` | | `node-repair.md` | 用于失败任务验证的自主修复算子;由 `execute-plan` 调用。 | `execute-plan.md`(恢复) | diff --git a/docs/zh-CN/USER-GUIDE.md b/docs/zh-CN/USER-GUIDE.md index 3c7c0acea..6462395f6 100644 --- a/docs/zh-CN/USER-GUIDE.md +++ b/docs/zh-CN/USER-GUIDE.md @@ -473,8 +473,8 @@ claude --dangerously-skip-permissions ### 现有代码库 ```bash -/gsd-map-codebase # Analyse what exists (parallel agents) -/gsd-new-project # Questions focus on what you're ADDING +/gsd-onboard # Safely map, ingest docs, and initialize planning +# Follow printed handoff commands, then rerun /gsd-onboard # (normal phase workflow from here) ``` @@ -863,7 +863,8 @@ All subagent/executor commits MUST use `--no-verify`. themes/ default.css # Shared CSS variables for all sketches MANIFEST.md # Index of all sketches with winners - codebase/ # Brownfield codebase mapping (from /gsd-map-codebase) + codebase/ # Brownfield codebase mapping (from /gsd-map-codebase or /gsd-onboard) + onboarding/ # Brownfield onboarding summary (from /gsd-onboard) phases/ XX-phase-name/ XX-YY-PLAN.md # Atomic execution plans diff --git a/docs/zh-CN/how-to/install-on-your-runtime.md b/docs/zh-CN/how-to/install-on-your-runtime.md index 63a97cce3..7bf6f97fb 100644 --- a/docs/zh-CN/how-to/install-on-your-runtime.md +++ b/docs/zh-CN/how-to/install-on-your-runtime.md @@ -273,10 +273,11 @@ npx @opengsd/gsd-core@latest --opencode --global ## 安装后 -重启您的运行时以加载新命令和代理。然后启动您的第一个项目: +重启您的运行时以加载新命令和代理。然后启动新项目或接入现有仓库: ```bash -/gsd-new-project +/gsd-new-project # 新建项目 +/gsd-onboard # 现有代码库 ``` 如果重启后找不到该命令,请确认安装目录与运行时预期的配置路径匹配。上方的预发布版章节介绍了最常见的路径不匹配情况。 diff --git a/docs/zh-CN/reference/planning-artifacts.md b/docs/zh-CN/reference/planning-artifacts.md index 7039e8cd5..73c513916 100644 --- a/docs/zh-CN/reference/planning-artifacts.md +++ b/docs/zh-CN/reference/planning-artifacts.md @@ -23,6 +23,8 @@ │ ├── architecture.md │ ├── stack.md │ └── ... +├── onboarding/ # Brownfield onboarding 摘要(可选) +│ └── SUMMARY.md ├── intel/ # 可查询的符号索引(可选,intel.enabled) │ └── API-SURFACE.md └── phases/ @@ -48,7 +50,7 @@ | | | |---|---| | **用途** | 规范的项目标识:项目内容、目标用户、核心价值、需求、约束和关键决策。随项目演进持续更新。 | -| **生成者** | `/gsd-new-project`(初始创建);由 `/gsd-complete-milestone` 在决策验证后更新。 | +| **生成者** | `/gsd-new-project`(初始创建,包含 `/gsd-onboard` 交接);由 `/gsd-complete-milestone` 在决策验证后更新。 | | **消费者** | 所有规划工作流;`gsd-phase-researcher`、`gsd-planner`(上下文);`discuss-phase`(历史决策);`gsd-plan-checker`(项目约束)。 | ### `ROADMAP.md` @@ -56,7 +58,7 @@ | | | |---|---| | **用途** | 里程碑与阶段列表,含目标、需求 ID、成功标准以及每个阶段的规范参考。是项目构建内容和顺序的唯一可信来源。 | -| **生成者** | `/gsd-new-project`(初始创建);由 `/gsd-phase --insert` 和 `/gsd-complete-milestone` 更新。 | +| **生成者** | `/gsd-new-project`(初始创建,包含 `/gsd-onboard` 交接);由 `/gsd-phase --insert` 和 `/gsd-complete-milestone` 更新。 | | **消费者** | `/gsd-discuss-phase`、`/gsd-plan-phase`、`/gsd-execute-phase`;所有需要阶段信息的编排命令;`gsd-planner`、`gsd-plan-checker`、`gsd-phase-researcher`。 | ### `REQUIREMENTS.md` @@ -64,7 +66,7 @@ | | | |---|---| | **用途** | 编号化、可勾选的项目验收标准。每条需求带有 ID(如 `AUTH-01`),映射到路线图阶段。随着阶段执行,逐步标记需求为已完成。 | -| **生成者** | `/gsd-new-project`(初始创建);需求由 `execute-phase` 标记为已完成。 | +| **生成者** | `/gsd-new-project`(初始创建,包含 `/gsd-onboard` 交接);需求由 `execute-phase` 标记为已完成。 | | **消费者** | `gsd-planner`(计划必须覆盖所有阶段需求 ID);`gsd-plan-checker` 维度 1(需求覆盖);`discuss-phase`(历史需求)。 | ### `STATE.md` @@ -72,7 +74,7 @@ | | | |---|---| | **用途** | 实时进度跟踪器——当前阶段与计划、进度指标、积累的决策、会话连续性说明。每次工作流运行时首先读取,每次重要操作后更新。 | -| **生成者** | `/gsd-new-project`(初始创建);由所有阶段工作流、`/gsd-pause-work`、`/gsd-resume-work` 持续更新。 | +| **生成者** | `/gsd-new-project`(初始创建,包含 `/gsd-onboard` 交接);由所有阶段工作流、`/gsd-pause-work`、`/gsd-resume-work` 持续更新。 | | **消费者** | 所有编排工作流;`/gsd-progress`;通过 `/gsd-quick` 执行的临时任务;`gsd-planner` 和 `gsd-phase-researcher`(项目决策)。 | 完整字段参考请参见 [STATE.md 模式](state-md.md)。 @@ -87,6 +89,14 @@ 完整模式请参见 [CONFIGURATION](../CONFIGURATION.md)。 +### `onboarding/SUMMARY.md`(可选) + +| | | +|---|---| +| **用途** | Brownfield onboarding 索引,记录产物状态、代码库映射是否完整,以及初次设置后的下一个推荐 GSD 命令。 | +| **生成者** | `/gsd-onboard`,在 `PROJECT.md`、`REQUIREMENTS.md`、`ROADMAP.md` 和 `STATE.md` 全部存在后生成。 | +| **消费者** | 审查初次设置的人;以后确认现有 onboarding 状态的 `/gsd-onboard` 运行。 | + ### `MILESTONES.md`(可选) | | | diff --git a/docs/zh-CN/tutorials/onboarding-an-existing-codebase.md b/docs/zh-CN/tutorials/onboarding-an-existing-codebase.md index 05576183b..b90522443 100644 --- a/docs/zh-CN/tutorials/onboarding-an-existing-codebase.md +++ b/docs/zh-CN/tutorials/onboarding-an-existing-codebase.md @@ -44,15 +44,15 @@ claude --dangerously-skip-permissions --- -## 第 3 步 — 映射代码库 +## 第 3 步 — 开始 brownfield onboarding -在创建项目之前,先让 GSD Core 了解已有的内容。这是使棕地规划准确的关键步骤。 +在创建项目之前,让 GSD Core 检查仓库状态并告诉您安全的下一个顶层命令。这一步可避免跳过代码库上下文或覆盖现有 planning 文件。 ```text -/gsd-map-codebase +/gsd-onboard ``` -GSD Core 会派生四个并行映射子代理(您将看到"Spawning 4 parallel codebase mapper agents…"——这需要 1–5 分钟;请勿中断)。每个代理专注于不同的关注点: +如果 onboarding 报告缺少代码库映射,请选择推荐选项并运行打印出的 `/gsd-map-codebase` 交接命令,然后重新运行 `/gsd-onboard`。`/gsd-onboard --fast` 只适合轻量首次通过;在 `/gsd-new-project` 前仍需要完整映射。`/gsd-map-codebase` 会派生四个并行映射子代理(您将看到"Spawning 4 parallel codebase mapper agents…"——这需要 1–5 分钟;请勿中断)。每个代理专注于不同的关注点: | 代理 | 关注点 | |-------|-------| @@ -84,7 +84,7 @@ Created .planning/codebase/: --- -## 第 4 步 — 清除上下文并创建项目 +## 第 4 步 — 重新运行 onboarding 并初始化项目 清除会话窗口: @@ -92,12 +92,14 @@ Created .planning/codebase/: /clear ``` -现在创建项目。由于 GSD Core 在上一步中发现了现有代码,它已经知道这是一个棕地项目。当您运行 `/gsd-new-project` 时,问题将聚焦于您所*新增*的内容,而非重新描述已有的内容: +现在再次运行 `/gsd-onboard`。如果 GSD Core 检测到 ADR、PRD、spec、RFC 或根级需求文档,请先接受推荐的 `/gsd-ingest-docs` 交接,然后再运行 `/gsd-onboard`。上下文准备好后,onboarding 会打印项目初始化交接命令: ```text /gsd-new-project ``` +由于 GSD Core 在上一步中发现了现有代码,`/gsd-new-project` 知道这是一个棕地项目。问题将聚焦于您所*新增*的内容,而非重新描述已有的内容: + GSD Core 会询问您想构建什么。请用您正在添加的功能来回答,而不是描述整个代码库: ```text @@ -124,6 +126,8 @@ Proposed Roadmap 批准路线图。 +项目设置完成后,再运行一次 `/gsd-onboard`。现在 `PROJECT.md`、`REQUIREMENTS.md`、`ROADMAP.md` 和 `STATE.md` 都已存在,onboarding 会创建或确认 `.planning/onboarding/SUMMARY.md`。 + **在 `.planning/` 中创建的内容:** ```text @@ -133,7 +137,8 @@ Proposed Roadmap ROADMAP.md ← Phase 1, status: pending STATE.md ← session memory config.json ← workflow settings - codebase/ ← the seven map files from Step 3 + onboarding/SUMMARY.md ← onboarding 状态和下一个命令 + codebase/ ← 第 3 步生成的七个映射文件 ``` 注意 `.planning/codebase/` 已经从第 3 步存在。GSD Core 在编写 `PROJECT.md` 时读取了这些文件,这就是为什么它无需您描述即可填充已验证的需求。 @@ -212,6 +217,7 @@ Proposed Roadmap ## 您学到了什么 +- `/gsd-onboard` 如何安全编排 brownfield 设置,不嵌套交互式命令,也不覆盖现有 planning 文件。 - `/gsd-map-codebase` 如何运行四个并行代理,在 `.planning/codebase/` 中生成 `STACK.md`、`ARCHITECTURE.md`、`CONVENTIONS.md`、`CONCERNS.md`、`STRUCTURE.md`、`TESTING.md` 和 `INTEGRATIONS.md`。 - 在棕地仓库中运行 `/gsd-new-project` 如何将问题聚焦于您所*新增*的内容,并从现有代码中填充已验证的需求。 - 代码库映射如何塑造 `/gsd-discuss-phase` 中的每个问题——文件路径、模式和规范均来自您的实际代码。 diff --git a/eslint.config.mjs b/eslint.config.mjs index d382077df..925ecc649 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -164,6 +164,7 @@ export default tseslint.config( 'gsd-core/bin/lib/eval.cjs', 'gsd-core/bin/lib/eval-command-router.cjs', 'gsd-core/bin/lib/init-command-router.cjs', + 'gsd-core/bin/lib/onboard-projection.cjs', 'gsd-core/bin/lib/agent-command-router.cjs', 'gsd-core/bin/lib/agent-install-check.cjs', 'gsd-core/bin/lib/task-command-router.cjs', diff --git a/gsd-core/references/gsd-run-resolver.md b/gsd-core/references/gsd-run-resolver.md new file mode 100644 index 000000000..01f6acb6d --- /dev/null +++ b/gsd-core/references/gsd-run-resolver.md @@ -0,0 +1,8 @@ +# Standard `gsd_run` Resolver + +Use this bootstrap block when a workflow must call `gsd-tools` from the active worktree/runtime. +Keep this resolver centralized; workflows should reference this file instead of copying the shell probe. + +```bash +_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi +``` diff --git a/gsd-core/templates/project.md b/gsd-core/templates/project.md index a78c5c220..d63152fbc 100644 --- a/gsd-core/templates/project.md +++ b/gsd-core/templates/project.md @@ -166,7 +166,7 @@ and implemented by workflows/transition.md and workflows/complete-milestone.md. For existing codebases: -1. **Map codebase first** via `/gsd:map-codebase` +1. **Onboard or map codebase first** via `/gsd:onboard` (recommended first-time path) or `/gsd:map-codebase` 2. **Infer Validated requirements** from existing code: - What does the codebase actually do? diff --git a/gsd-core/workflows/do.md b/gsd-core/workflows/do.md index a7268e950..db0dfa312 100644 --- a/gsd-core/workflows/do.md +++ b/gsd-core/workflows/do.md @@ -40,8 +40,9 @@ Evaluate `$ARGUMENTS` against these routing rules. Apply the **first matching** | If the text describes... | Route to | Why | |--------------------------|----------|-----| -| Starting a new project, "set up", "initialize" | `/gsd:new-project` | Needs full project initialization | -| Mapping or analyzing an existing codebase | `/gsd:map-codebase` | Codebase discovery | +| Starting a new greenfield project, "set up", "initialize" | `/gsd:new-project` | Needs full project initialization | +| First-time setup for an existing codebase, brownfield onboarding | `/gsd:onboard` | Safe map → docs ingest → project setup sequence | +| Mapping or analyzing an existing codebase map | `/gsd:map-codebase` | Codebase discovery or refresh | | A bug, error, crash, failure, or something broken | `/gsd:debug` | Needs systematic investigation | | Spiking, "test if", "will this work", "experiment", "prove this out", validate feasibility | `/gsd:spike` | Throwaway experiment to validate feasibility | | Sketching, "mockup", "what would this look like", "prototype the UI", "design this", explore visual direction | `/gsd:sketch` | Throwaway HTML mockups to explore design | @@ -61,7 +62,7 @@ Evaluate `$ARGUMENTS` against these routing rules. Apply the **first matching** | Completing a milestone, shipping, releasing | `/gsd:complete-milestone` | Milestone lifecycle | | A specific, actionable, small task (add feature, fix typo, update config) | `/gsd:quick` | Self-contained, single executor | -**Requires `.planning/` directory:** All routes except `/gsd:new-project`, `/gsd:map-codebase`, `/gsd:spike`, `/gsd:sketch`, and `/gsd:help`. If the project doesn't exist and the route requires it, suggest `/gsd:new-project` first. +**Requires `.planning/` directory:** All routes except `/gsd:new-project`, `/gsd:onboard`, `/gsd:map-codebase`, `/gsd:spike`, `/gsd:sketch`, and `/gsd:help`. If the project doesn't exist and the route requires it, suggest `/gsd:onboard` for existing codebases or `/gsd:new-project` for greenfield projects. **Ambiguity handling:** If the text could reasonably match multiple routes, ask the user via AskUserQuestion with the top 2-3 options. For example: diff --git a/gsd-core/workflows/help/modes/brief.md b/gsd-core/workflows/help/modes/brief.md index 359c32f1a..46a1cd41f 100644 --- a/gsd-core/workflows/help/modes/brief.md +++ b/gsd-core/workflows/help/modes/brief.md @@ -7,7 +7,8 @@ One-liner refresher for returning users. Output ONLY the `` content b ```text /gsd:new-project Initialize a project (greenfield) -/gsd:map-codebase Map an existing codebase (brownfield) +/gsd:onboard Onboard an existing codebase (brownfield) +/gsd:map-codebase Refresh/map codebase intelligence /gsd:plan-phase Create a phase plan /gsd:execute-phase Execute a phase /gsd:progress Where am I, what's next diff --git a/gsd-core/workflows/help/modes/default.md b/gsd-core/workflows/help/modes/default.md index 866f1d7dd..86274d63b 100644 --- a/gsd-core/workflows/help/modes/default.md +++ b/gsd-core/workflows/help/modes/default.md @@ -11,11 +11,12 @@ Plan-driven development for solo agentic work with Claude Code. GSD Core turns a ```text /gsd:new-project # Greenfield: questioning → research → requirements → roadmap +/gsd:onboard # Existing codebase: map → ingest docs → initialize planning /gsd:plan-phase 1 # Create a detailed plan for phase 1 /gsd:execute-phase 1 # Execute all plans in the phase ``` -Existing codebase? Run `/gsd:map-codebase` first to ground GSD in your code. +Existing codebase? Run `/gsd:onboard` to map the repo, ingest existing docs, and initialize planning safely. ## Common commands diff --git a/gsd-core/workflows/help/modes/full.md b/gsd-core/workflows/help/modes/full.md index a6686bbae..235fae38d 100644 --- a/gsd-core/workflows/help/modes/full.md +++ b/gsd-core/workflows/help/modes/full.md @@ -62,6 +62,16 @@ Creates all `.planning/` artifacts: Usage: `/gsd:new-project` +**`/gsd:onboard [--fast] [--text]`** +Guide first-time onboarding for an existing codebase. + +- Detects brownfield code, existing planning docs, and partial `.planning/` state +- Routes through `/gsd:map-codebase`, `/gsd:ingest-docs`, and `/gsd:new-project` in the safe order +- Creates `.planning/onboarding/SUMMARY.md` after project setup +- Idempotent: confirms existing artifacts and does not overwrite planning silently + +Usage: `/gsd:onboard` + **`/gsd:map-codebase [--fast] [--focus ] [--query ]`** Map an existing codebase for brownfield projects. @@ -72,7 +82,7 @@ Map an existing codebase for brownfield projects. - Analyzes codebase with parallel Explore agents - Creates `.planning/codebase/` with 7 focused documents - Covers stack, architecture, structure, conventions, testing, integrations, concerns -- Use before `/gsd:new-project` on existing codebases +- Usually reached through `/gsd:onboard` for first-time existing-codebase setup; run directly to refresh or focus a map Usage: `/gsd:map-codebase` diff --git a/gsd-core/workflows/help/modes/topic.md b/gsd-core/workflows/help/modes/topic.md index d89229607..89b380263 100644 --- a/gsd-core/workflows/help/modes/topic.md +++ b/gsd-core/workflows/help/modes/topic.md @@ -9,7 +9,7 @@ Emit a section from the full reference for the topic in `$ARGUMENTS`. Read `work |---|---| | `next`, `smart-entry` | `### Smart Entry` | | `workflow`, `core`, `core-workflow` | `## Core Workflow` (entire section through end of `### Quick Mode`) | -| `init`, `new-project` | `### Project Initialization` | +| `init`, `new-project`, `onboard`, `onboarding`, `brownfield` | `### Project Initialization` | | `map`, `map-codebase` | The `/gsd:map-codebase` block under `### Project Initialization` | | `discuss`, `discuss-phase` | The `/gsd:discuss-phase` block under `### Phase Planning` | | `plan`, `planning`, `plan-phase` | `### Phase Planning` | diff --git a/gsd-core/workflows/onboard.md b/gsd-core/workflows/onboard.md new file mode 100644 index 000000000..dbcd7c147 --- /dev/null +++ b/gsd-core/workflows/onboard.md @@ -0,0 +1,277 @@ +# /gsd:onboard Workflow + +One-command onboarding for an existing or unknown repo. This workflow is a thin +renderer around `init onboard`; deterministic routing lives in the CLI projection. + +@~/.claude/gsd-core/references/gsd-run-resolver.md + +## 1. Render the Onboarding Projection + +Parse `$ARGUMENTS`: +- `--fast` passes `--fast` to `init onboard`. Fast mode accepts the fast map for lightweight onboarding only; `next_action` still decides whether complete map work is required before project setup. +- `--text` forces text-mode choices for runtimes without `AskUserQuestion`. + +Run the standard `gsd_run` resolver from the reference above, then run the projection from the runtime root: + +```bash +# If --fast was parsed from $ARGUMENTS: +INIT=$(gsd_run --cwd "$_GSD_RUNTIME_ROOT" init onboard --fast --raw) +# Otherwise: +INIT=$(gsd_run --cwd "$_GSD_RUNTIME_ROOT" init onboard --raw) +if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi +``` + +Parse JSON fields from `INIT`: + +- `next_action.kind`, `next_action.command`, `next_action.reason`, `next_action.missing`, `next_action.summary_path` +- `handoff_commands.ingest_docs`, `handoff_commands.manager`, `handoff_commands.new_project`, `handoff_commands.onboard` +- `map_readiness`, `codebase_map_summary_status`, `codebase_map_final_status` +- `planning_exists`, `project_exists`, `requirements_exists`, `roadmap_exists`, `state_exists` +- `is_brownfield`, `fast_mode`, `has_codebase_map`, `has_fast_codebase_map` +- `missing_codebase_map_files`, `missing_fast_codebase_map_files` +- `has_docs_candidates`, `doc_candidate_count`, `onboarding_summary_exists` +- `commit_docs`, `text_mode`, `has_git`, `git_worktree_root`, `in_nested_subdir` + +Set: +- `TEXT_MODE=true` if `--text` is present or `text_mode` is true. When `TEXT_MODE` is active, replace every `AskUserQuestion` call below with a plain-text numbered list and ask the user to type their choice number — required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available. +- `ONBOARDING_ROOT={git_worktree_root || _GSD_RUNTIME_ROOT}`. + +If `has_git` and `in_nested_subdir` are true, warn that onboarding artifacts belong to the outer worktree at `git_worktree_root`. Do not run `git init`. + +## 2. Execute `next_action` + +### `map-codebase` + +If `next_action.kind == "map-codebase"`: + +- If `TEXT_MODE=true`, print: + +```text +{next_action.reason} +Missing map files: {fast_mode ? missing_fast_codebase_map_files : missing_codebase_map_files} + +1. Map codebase first — run {next_action.command} from worktree root {ONBOARDING_ROOT} (Recommended) +2. Skip mapping — continue with weaker onboarding context + +Enter number: +``` + +- Otherwise use AskUserQuestion: + - header: "Codebase" + - question: "{next_action.reason} Map it first?" + - options: + - "Map codebase first" — Run `{next_action.command}` from worktree root `{ONBOARDING_ROOT}` (Recommended) + - "Skip mapping" — Continue with weaker onboarding context + +If the user chooses mapping, do not nest the interactive workflow. Print: + +```text +Run from worktree root {ONBOARDING_ROOT}: + +{next_action.command} + +Then rerun {handoff_commands.onboard} from the same worktree root. +``` + +Exit. If the user skips mapping: + +- If `(project_exists || requirements_exists || roadmap_exists || state_exists) && (!project_exists || !requirements_exists || !roadmap_exists || !state_exists)`, route the skip to the partial planning guard instead: + +```text +Skipping codebase mapping may give downstream steps weaker context, but project planning exists and is incomplete. + +PROJECT.md: {project_exists ? "present" : "missing"} +REQUIREMENTS.md: {requirements_exists ? "present" : "missing"} +ROADMAP.md: {roadmap_exists ? "present" : "missing"} +STATE.md: {state_exists ? "present" : "missing"} + +Run the appropriate lower-level command to fill the missing planning artifact(s), then rerun {handoff_commands.onboard}. +``` + +Exit. + +- If `has_docs_candidates && !project_exists`, route the skip to docs ingest instead: + +```text +Skipping codebase mapping may give downstream steps weaker context, but existing ADR/PRD/SPEC/RFC documents should still be ingested before {handoff_commands.new_project}. + +Run from worktree root {ONBOARDING_ROOT}: + +{handoff_commands.ingest_docs} + +Then rerun {handoff_commands.onboard} from the same worktree root. +``` + +Exit. + +- Otherwise print: + +```text +Skipping codebase mapping may give {handoff_commands.new_project} weaker context. + +Run from worktree root {ONBOARDING_ROOT}: + +{handoff_commands.new_project} + +Then rerun {handoff_commands.onboard} from the same worktree root. +``` + +Exit. + +### `ingest-docs` + +If `next_action.kind == "ingest-docs"`: + +- If `TEXT_MODE=true`, print: + +```text +{next_action.reason} +Detected {doc_candidate_count} possible ADR/PRD/SPEC/RFC document(s). + +1. Ingest docs first — run {next_action.command} from worktree root {ONBOARDING_ROOT} (Recommended) +2. Skip docs ingest — continue to {handoff_commands.new_project} + +Enter number: +``` + +- Otherwise use AskUserQuestion: + - header: "Docs" + - question: "Detected {doc_candidate_count} possible ADR/PRD/SPEC/RFC document(s). Ingest them first?" + - options: + - "Ingest docs first" — Run `{next_action.command}` from worktree root `{ONBOARDING_ROOT}` (Recommended) + - "Skip docs ingest" — Continue to `{handoff_commands.new_project}` + +If the user chooses ingest, print: + +```text +Run from worktree root {ONBOARDING_ROOT}: + +{next_action.command} + +Then rerun {handoff_commands.onboard} from the same worktree root. +``` + +Exit. If the user skips docs ingest, print: + +```text +Skipping docs ingest may omit existing ADR/PRD/SPEC/RFC context from {handoff_commands.new_project}. + +Run from worktree root {ONBOARDING_ROOT}: + +{handoff_commands.new_project} + +Then rerun {handoff_commands.onboard} from the same worktree root. +``` + +Exit. + +### `complete-map-before-new-project` + +If `next_action.kind == "complete-map-before-new-project"`, print: + +```text +{next_action.reason} + +Run from worktree root {ONBOARDING_ROOT}: + +{next_action.command} + +Then rerun {handoff_commands.onboard} from the same worktree root. +``` + +Exit. + +### `new-project` + +If `next_action.kind == "new-project"`, print: + +```text +{next_action.reason} + +Run from worktree root {ONBOARDING_ROOT}: + +{next_action.command} + +Then rerun {handoff_commands.onboard} from the same worktree root. +``` + +Exit. + +### `partial-planning` + +If `next_action.kind == "partial-planning"`, print: + +```text +Project planning exists but is incomplete. + +Missing files: {next_action.missing} +REQUIREMENTS.md: {requirements_exists ? "present" : "missing"} +ROADMAP.md: {roadmap_exists ? "present" : "missing"} +STATE.md: {state_exists ? "present" : "missing"} + +Run the appropriate lower-level command to fill the missing planning artifact(s), then rerun {handoff_commands.onboard}. +``` + +Exit. + +### `ready` + +If `next_action.kind == "ready"`, print the final status section and exit. + +### `write-summary` + +If `next_action.kind == "write-summary"`, continue to summary creation. + +## 3. Create Onboarding Summary + +Create `{ONBOARDING_ROOT}/{next_action.summary_path}`. Do not overwrite an existing summary; the projection should only route here when the summary is missing. + +Summary template: + +```markdown +# Onboarding Summary + +## Project State +- PROJECT.md: {project_exists ? "present" : "missing"} +- REQUIREMENTS.md: {requirements_exists ? "present" : "missing"} +- ROADMAP.md: {roadmap_exists ? "present" : "missing"} +- STATE.md: {state_exists ? "present" : "missing"} + +## Codebase Context +- Brownfield repo: {is_brownfield ? "yes" : "no"} +- Map readiness: {map_readiness} +- Codebase map: {codebase_map_summary_status} +- Fast map available: {has_fast_codebase_map ? "yes" : "no"} + +## Docs Context +- Existing ADR/PRD/SPEC/RFC candidates: {has_docs_candidates ? doc_candidate_count : 0} + +## Recommended Next Step +- {handoff_commands.manager} +``` + +If `commit_docs` is true, commit only the summary path from the onboarding root: + +```bash +gsd_run --cwd "$ONBOARDING_ROOT" query commit "docs: create onboarding summary" --files .planning/onboarding/SUMMARY.md +``` + +Continue to final status. + +## 4. Final Status + +Print: + +```text +Onboarding status: +- PROJECT.md: {project_exists ? "present" : "missing"} +- REQUIREMENTS.md: {requirements_exists ? "present" : "missing"} +- ROADMAP.md: {roadmap_exists ? "present" : "missing"} +- STATE.md: {state_exists ? "present" : "missing"} +- Codebase map: {codebase_map_final_status} +- Onboarding summary: present + +Next recommended command: {handoff_commands.manager} +``` + +Do not run implementation execution or shipping from onboarding. diff --git a/scripts/sync-runtime-launcher.cjs b/scripts/sync-runtime-launcher.cjs index 6ce5a6303..dbc38a2b4 100644 --- a/scripts/sync-runtime-launcher.cjs +++ b/scripts/sync-runtime-launcher.cjs @@ -343,9 +343,12 @@ function transformFile(content, preamble) { } } - // Insert preamble into the first gsd_run block only + // Insert preamble into the first gsd_run block only — UNLESS this file + // delegates to the shared resolver reference (@-include). Delegating files keep + // the stripped blocks (any inline preamble removed) but never get one inserted. + const delegates = delegatesToResolverReference(content); const finalBlocks = strippedBlocks.map((stripped, bi) => { - if (bi === firstGsdRunBlockIdx) { + if (!delegates && bi === firstGsdRunBlockIdx) { return insertPreamble(stripped, preamble); } return stripped; @@ -374,6 +377,21 @@ function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } +/** + * A file "delegates to the shared resolver" when it pulls the canonical gsd_run + * preamble in from gsd-core/references/gsd-run-resolver.md via an @-include + * instead of inlining the snippet (see onboard.md / issue #1990). + * + * These files must NOT carry an inline preamble: the resolver reference ships the + * one canonical copy, and onboard-command.test.cjs asserts the inline form is + * absent. transformFile still STRIPS any inline preamble from them (so a stray + * copy is removed) but never re-inserts one — mirroring the exemption in + * runtime-launcher-parity.test.cjs (subtest B / B2). + */ +function delegatesToResolverReference(content) { + return content.includes('references/gsd-run-resolver.md'); +} + // Main function main() { const preamble = loadPreamble(); diff --git a/skills/gsd-map-codebase/SKILL.md b/skills/gsd-map-codebase/SKILL.md index 1f8fbb1d5..36c909128 100644 --- a/skills/gsd-map-codebase/SKILL.md +++ b/skills/gsd-map-codebase/SKILL.md @@ -42,7 +42,7 @@ Parse the first token of $ARGUMENTS: Check for .planning/STATE.md - loads context if project already initialized **This command can run:** -- Before /gsd-new-project (brownfield codebases) - creates codebase map first +- Via /gsd-onboard for first-time brownfield setup - creates codebase map first - After /gsd-new-project (greenfield codebases) - updates codebase map as code evolves - Anytime to refresh codebase understanding @@ -51,7 +51,7 @@ Check for .planning/STATE.md - loads context if project already initialized **Use map-codebase for:** - Brownfield projects before initialization (understand existing code first) - Refreshing codebase map after significant changes -- Onboarding to an unfamiliar codebase +- Refreshing or deepening an onboarded codebase map - Before major refactoring (understand current state) - When STATE.md references outdated codebase info @@ -71,7 +71,7 @@ Check for .planning/STATE.md - loads context if project already initialized 4. Wait for agents to complete, collect confirmations (NOT document contents) 5. Verify all 7 documents exist with line counts 6. Commit codebase map -7. Offer next steps (typically: /gsd-new-project or /gsd-plan-phase) +7. Offer next steps (typically: /gsd-onboard, /gsd-new-project, or /gsd-plan-phase) diff --git a/skills/gsd-ns-project/SKILL.md b/skills/gsd-ns-project/SKILL.md index 5aa5a8e8b..96d22ac4d 100644 --- a/skills/gsd-ns-project/SKILL.md +++ b/skills/gsd-ns-project/SKILL.md @@ -14,6 +14,7 @@ inline as part of `gsd-audit-milestone`'s output. | User wants | Invoke | |---|---| | Start a new project | gsd-new-project | +| Onboard an existing codebase | gsd-onboard | | Create a new milestone | gsd-new-milestone | | Complete the current milestone | gsd-complete-milestone | | Audit a milestone for issues | gsd-audit-milestone | diff --git a/skills/gsd-onboard/SKILL.md b/skills/gsd-onboard/SKILL.md new file mode 100644 index 000000000..d3b3946f5 --- /dev/null +++ b/skills/gsd-onboard/SKILL.md @@ -0,0 +1,46 @@ +--- +name: gsd-onboard +description: "Guide existing codebase onboarding through mapping, doc ingest, and planning setup" +argument-hint: "[--fast] [--text]" +allowed-tools: + - Read + - Bash + - Write + - Glob + - Grep + - Agent + - AskUserQuestion +--- + + +**Copilot (VS Code):** Use `vscode_askquestions` wherever this workflow calls `AskUserQuestion`. They are equivalent — `vscode_askquestions` is the VS Code Copilot implementation of the same interactive question API. + + + +Guide brownfield onboarding for an existing codebase by routing through the existing GSD primitives in the safe order: codebase map → docs ingest → project initialization → onboarding summary. + +**Creates or confirms:** +- `.planning/codebase/` — evidence-backed codebase map from `/gsd-map-codebase` +- `.planning/PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md`, `STATE.md` — project setup from `/gsd-new-project` or `/gsd-ingest-docs` +- `.planning/onboarding/SUMMARY.md` — lightweight index of what was learned and the next command + +**Non-goals:** This command does not execute phases, ship work, or overwrite existing planning artifacts without an explicit gate. + + + +@~/.claude/gsd-core/workflows/onboard.md +@~/.claude/gsd-core/references/ui-brand.md +@~/.claude/gsd-core/references/gate-prompts.md + + + +Arguments: $ARGUMENTS + +Flags: +- `--fast` — prefer `/gsd-map-codebase --fast` for the mapping handoff; the complete map is still required before `/gsd-new-project`. +- `--text` — use plain-text numbered lists instead of TUI menus. + + + +Execute the onboard workflow end-to-end. Preserve all safety gates, text-mode fallbacks, idempotency checks, and top-level handoff rules for nested interactive commands. + diff --git a/src/clusters.cts b/src/clusters.cts index 2ea92abfd..7ba2ff05b 100644 --- a/src/clusters.cts +++ b/src/clusters.cts @@ -33,6 +33,7 @@ export const CLUSTERS: ClusterMap = Object.freeze({ core_loop: Object.freeze([ 'next', 'new-project', + 'onboard', 'discuss-phase', 'plan-phase', 'execute-phase', diff --git a/src/command-aliases.cts b/src/command-aliases.cts index 9df935e33..19c2a36be 100644 --- a/src/command-aliases.cts +++ b/src/command-aliases.cts @@ -296,6 +296,14 @@ export const INIT_COMMAND_ALIASES: CommandAlias[] = [ "subcommand": "new-milestone", "mutation": false }, + { + "canonical": "init.onboard", + "aliases": [ + "init onboard" + ], + "subcommand": "onboard", + "mutation": false + }, { "canonical": "init.quick", "aliases": [ diff --git a/src/init-command-router.cts b/src/init-command-router.cts index 317ce0059..6ea4b4dac 100644 --- a/src/init-command-router.cts +++ b/src/init-command-router.cts @@ -28,6 +28,7 @@ interface InitModule { cmdInitPlanPhase(cwd: string, phase: string | undefined, raw: boolean, opts: Record): void; cmdInitNewProject(cwd: string, raw: boolean): void; cmdInitNewMilestone(cwd: string, raw: boolean): void; + cmdInitOnboard(cwd: string, raw: boolean, opts?: Record): void; cmdInitQuick(cwd: string, name: string, raw: boolean): void; cmdInitIngestDocs(cwd: string, raw: boolean): void; cmdInitResume(cwd: string, raw: boolean): void; @@ -71,6 +72,10 @@ function routeInitCommand({ init, args, cwd, raw, error }: RouteInitCommandOptio }, 'new-project': () => init.cmdInitNewProject(cwd, raw), 'new-milestone': () => init.cmdInitNewMilestone(cwd, raw), + onboard: () => { + const namedArgs = parseNamedArgs(args, [], ['fast', 'text']); + init.cmdInitOnboard(cwd, raw, { fast: namedArgs['fast'], text: namedArgs['text'] }); + }, quick: () => init.cmdInitQuick(cwd, args.slice(2).join(' '), raw), 'ingest-docs': () => init.cmdInitIngestDocs(cwd, raw), resume: () => init.cmdInitResume(cwd, raw), diff --git a/src/init.cts b/src/init.cts index 1b9de1cb0..19d8e6f1c 100644 --- a/src/init.cts +++ b/src/init.cts @@ -51,6 +51,15 @@ const { checkAgentsInstalled } = agentInstallCheck; import gitBaseBranch = require('./git-base-branch.cjs'); const { gitWorktreeInfoInternal } = gitBaseBranch; import { makeResolution } from './resolution.cjs'; +// eslint-disable-next-line @typescript-eslint/no-require-imports -- onboard-projection.cjs is an export= CommonJS module +import onboardProjection = require('./onboard-projection.cjs'); +const { + REQUIRED_CODEBASE_MAP_FILES, + buildOnboardProjection, + hasCodeFilesInternal, + hasPackageFileInternal, + listCodebaseMapFiles, +} = onboardProjection; const { output, error } = io; const { loadConfig, loadConfigResolved } = configLoader; @@ -625,68 +634,11 @@ function cmdInitNewProject(cwd: string, raw: boolean): void { const exaKeyFile = path.join(homedir, '.gsd', 'exa_api_key'); const hasExaSearch = !!(process.env['EXA_API_KEY'] || fs.existsSync(exaKeyFile)); - let hasCode = false; - let hasPackageFile = false; - try { - const codeExtensions = new Set([ - '.ts', '.js', '.py', '.go', '.rs', '.swift', '.java', - '.kt', '.kts', - '.c', '.cpp', '.h', - '.cs', - '.rb', - '.php', - '.dart', - '.m', '.mm', - '.scala', - '.groovy', - '.lua', - '.r', '.R', - '.zig', - '.ex', '.exs', - '.clj', - ]); - const skipDirs = new Set([ - 'node_modules', '.git', '.planning', '.claude', '.codex', - '__pycache__', 'target', 'dist', 'build', - ]); - function findCodeFiles(dir: string, depth: number): boolean { - if (depth > 3) return false; - let entries: fs.Dirent[]; - try { - entries = fs.readdirSync(dir, { withFileTypes: true }); - } catch { - return false; - } - for (const entry of entries) { - if (entry.isFile() && codeExtensions.has(path.extname(entry.name))) return true; - if (entry.isDirectory() && !skipDirs.has(entry.name)) { - if (findCodeFiles(path.join(dir, entry.name), depth + 1)) return true; - } - } - return false; - } - hasCode = findCodeFiles(cwd, 0); - } catch { - /* intentionally empty — best-effort detection */ - } - - hasPackageFile = - pathExistsInternal(cwd, 'package.json') || - pathExistsInternal(cwd, 'requirements.txt') || - pathExistsInternal(cwd, 'Cargo.toml') || - pathExistsInternal(cwd, 'go.mod') || - pathExistsInternal(cwd, 'Package.swift') || - pathExistsInternal(cwd, 'build.gradle') || - pathExistsInternal(cwd, 'build.gradle.kts') || - pathExistsInternal(cwd, 'pom.xml') || - pathExistsInternal(cwd, 'Gemfile') || - pathExistsInternal(cwd, 'composer.json') || - pathExistsInternal(cwd, 'pubspec.yaml') || - pathExistsInternal(cwd, 'CMakeLists.txt') || - pathExistsInternal(cwd, 'Makefile') || - pathExistsInternal(cwd, 'build.zig') || - pathExistsInternal(cwd, 'mix.exs') || - pathExistsInternal(cwd, 'project.clj'); + const hasCode = hasCodeFilesInternal(cwd); + const hasPackageFile = hasPackageFileInternal(cwd); + const isBrownfield = hasCode || hasPackageFile; + const codebaseMapFiles = listCodebaseMapFiles(cwd); + const hasCodebaseMap = codebaseMapFiles.length === REQUIRED_CODEBASE_MAP_FILES.length; const result: Record = { researcher_model: resolveModelInternal(cwd, 'gsd-project-researcher'), @@ -696,14 +648,13 @@ function cmdInitNewProject(cwd: string, raw: boolean): void { commit_docs: config.commit_docs, project_exists: pathExistsInternal(cwd, '.planning/PROJECT.md'), - has_codebase_map: pathExistsInternal(cwd, '.planning/codebase'), + has_codebase_map: hasCodebaseMap, planning_exists: pathExistsInternal(cwd, '.planning'), has_existing_code: hasCode, has_package_file: hasPackageFile, - is_brownfield: hasCode || hasPackageFile, - needs_codebase_map: - (hasCode || hasPackageFile) && !pathExistsInternal(cwd, '.planning/codebase'), + is_brownfield: isBrownfield, + needs_codebase_map: isBrownfield && !hasCodebaseMap, ...getInitGitState(cwd), @@ -840,6 +791,25 @@ function cmdInitIngestDocs(cwd: string, raw: boolean): void { output(withProjectRoot(cwd, result), raw); } +function cmdInitOnboard( + cwd: string, + raw: boolean, + options: Record = {}, +): void { + const config = loadConfig(cwd); + const workflowConfig = (config.workflow ?? {}) as Record; + const result = { + ...buildOnboardProjection(cwd, { + commitDocs: !!config.commit_docs, + fast: options['fast'] === true, + textMode: options['text'] === true || !!config.text_mode || !!workflowConfig['text_mode'], + }), + ...getInitGitState(cwd), + }; + + output(withProjectRoot(cwd, result), raw); +} + function cmdInitResume(cwd: string, raw: boolean): void { const config = loadConfig(cwd); @@ -2606,6 +2576,7 @@ export = { cmdInitNewMilestone, cmdInitQuick, cmdInitIngestDocs, + cmdInitOnboard, cmdInitResume, cmdInitVerifyWork, cmdInitPhaseOp, diff --git a/src/install-profiles.cts b/src/install-profiles.cts index 474327ae5..fd6bfba76 100644 --- a/src/install-profiles.cts +++ b/src/install-profiles.cts @@ -51,6 +51,7 @@ const PROFILES = Object.freeze({ standard: Object.freeze([ // Core loop 'new-project', + 'onboard', 'discuss-phase', 'plan-phase', 'execute-phase', diff --git a/src/onboard-projection.cts b/src/onboard-projection.cts new file mode 100644 index 000000000..bcd3b794b --- /dev/null +++ b/src/onboard-projection.cts @@ -0,0 +1,437 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +// eslint-disable-next-line @typescript-eslint/no-require-imports -- core-utils.cjs is an export= CommonJS module +import coreUtils = require('./core-utils.cjs'); +// eslint-disable-next-line @typescript-eslint/no-require-imports -- planning-workspace.cjs is an export= CommonJS module +import planningWorkspace = require('./planning-workspace.cjs'); +import { formatGsdSlash, resolveRuntime } from './runtime-slash.cjs'; + +const { pathExistsInternal, toPosixPath } = coreUtils; +const { planningDir, planningRoot } = planningWorkspace; + +const CODE_EXTENSIONS = new Set([ + '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.py', '.go', '.rs', '.swift', '.java', + '.kt', '.kts', '.c', '.cpp', '.cc', '.h', '.hpp', '.cs', '.rb', '.php', '.dart', + '.m', '.mm', '.scala', '.groovy', '.lua', '.r', '.R', '.zig', '.ex', '.exs', '.clj', +]); + +const CODE_SCAN_SKIP_DIRS = new Set([ + 'node_modules', '.git', '.planning', '.claude', '.codex', '__pycache__', 'target', + 'dist', 'build', '.next', '.nuxt', '.svelte-kit', 'coverage', 'vendor', '.venv', 'venv', +]); + +const PACKAGE_FILES = [ + 'package.json', 'requirements.txt', 'pyproject.toml', 'Cargo.toml', 'go.mod', + 'Package.swift', 'build.gradle', 'build.gradle.kts', 'pom.xml', 'Gemfile', + 'composer.json', 'pubspec.yaml', 'CMakeLists.txt', 'Makefile', 'build.zig', + 'mix.exs', 'project.clj', +]; + +const REQUIRED_CODEBASE_MAP_FILES = [ + 'STACK.md', 'ARCHITECTURE.md', 'STRUCTURE.md', 'CONVENTIONS.md', 'TESTING.md', + 'INTEGRATIONS.md', 'CONCERNS.md', +]; + +const FAST_CODEBASE_MAP_FILES = [ + 'STACK.md', 'INTEGRATIONS.md', 'ARCHITECTURE.md', 'STRUCTURE.md', +]; + +const PLANNING_DOC_SEGMENTS = new Set([ + 'adr', 'adrs', 'prd', 'prds', 'spec', 'specs', 'rfc', 'rfcs', +]); + +type MapReadiness = 'none' | 'fast' | 'complete'; + +interface OnboardHandoffCommands { + ingest_docs: string; + manager: string; + map_codebase: string; + map_codebase_fast: string; + new_project: string; + onboard: string; +} + +type OnboardNextAction = + | { kind: 'map-codebase'; command: string; reason: string } + | { kind: 'ingest-docs'; command: string; reason: string } + | { kind: 'new-project'; command: string; reason: string } + | { kind: 'complete-map-before-new-project'; command: string; reason: string } + | { kind: 'partial-planning'; missing: string[]; reason: string } + | { kind: 'write-summary'; summary_path: string; reason: string } + | { kind: 'ready'; reason: string }; + +interface BuildOnboardProjectionOptions { + commitDocs: boolean; + fast: boolean; + textMode: boolean; +} + +interface OnboardProjection { + commit_docs: boolean; + text_mode: boolean; + + project_exists: boolean; + planning_exists: boolean; + requirements_exists: boolean; + roadmap_exists: boolean; + state_exists: boolean; + config_exists: boolean; + + handoff_commands: OnboardHandoffCommands; + + has_existing_code: boolean; + has_package_file: boolean; + is_brownfield: boolean; + fast_mode: boolean; + map_readiness: MapReadiness; + next_action: OnboardNextAction; + needs_codebase_map: boolean; + needs_fast_codebase_map: boolean; + has_codebase_map: boolean; + has_fast_codebase_map: boolean; + codebase_dir_exists: boolean; + fast_codebase_map_files_required: string[]; + codebase_map_files_present: string[]; + missing_codebase_map_files: string[]; + missing_fast_codebase_map_files: string[]; + codebase_map_summary_status: string; + codebase_map_final_status: string; + + has_docs_candidates: boolean; + doc_candidate_count: number; + doc_candidates: string[]; + + onboarding_summary_exists: boolean; + onboarding_summary_path: string; + + project_path: string; + requirements_path: string; + roadmap_path: string; + state_path: string; + codebase_dir: string; + onboarding_dir: string; +} + +function hasCodeFilesInternal(dir: string, depth = 0): boolean { + if (depth > 3) return false; + let entries: fs.Dirent[]; + try { + entries = fs.readdirSync(dir, { withFileTypes: true }); + } catch { + return false; + } + + for (const entry of entries) { + if (entry.isFile() && CODE_EXTENSIONS.has(path.extname(entry.name))) return true; + if (entry.isDirectory() && !CODE_SCAN_SKIP_DIRS.has(entry.name)) { + if (hasCodeFilesInternal(path.join(dir, entry.name), depth + 1)) return true; + } + } + + return false; +} + +function hasPackageFileInternal(cwd: string): boolean { + return PACKAGE_FILES.some((file) => pathExistsInternal(cwd, file)); +} + +function listPlanningDocCandidates(cwd: string): string[] { + const roots = ['docs', 'adr', 'adrs', 'prd', 'prds', 'spec', 'specs', 'rfc', 'rfcs']; + const candidates = new Set(); + + function isPlanningDocCandidate(rel: string, name: string): boolean { + const upperName = name.toUpperCase(); + const relLower = rel.toLowerCase(); + const pathSegments = relLower.split('/'); + return ( + /(^|[-_ ])(ADR|PRD|SPEC|RFC)([-_ ]|\.)/i.test(name) || + /^\d{4}[-_].+\.md$/i.test(name) || + pathSegments.some((segment) => PLANNING_DOC_SEGMENTS.has(segment)) || + upperName === 'REQUIREMENTS.MD' + ); + } + + function addCandidate(rel: string, name: string): void { + if (name.toLowerCase().endsWith('.md') && isPlanningDocCandidate(rel, name)) { + candidates.add(toPosixPath(rel)); + } + } + + function visit(dir: string, relDir: string, depth: number): void { + if (depth > 3) return; + let entries: fs.Dirent[]; + try { + entries = fs.readdirSync(dir, { withFileTypes: true }); + } catch { + return; + } + + for (const entry of entries) { + const rel = relDir ? `${relDir}/${entry.name}` : entry.name; + if (entry.isDirectory()) { + if (!CODE_SCAN_SKIP_DIRS.has(entry.name)) { + visit(path.join(dir, entry.name), rel, depth + 1); + } + continue; + } + + if (entry.isFile()) addCandidate(rel, entry.name); + } + } + + let rootEntries: fs.Dirent[] = []; + try { + rootEntries = fs.readdirSync(cwd, { withFileTypes: true }); + } catch { + rootEntries = []; + } + + for (const entry of rootEntries) { + if (entry.isFile()) addCandidate(entry.name, entry.name); + } + + for (const root of roots) { + const full = path.join(cwd, root); + if (fs.existsSync(full)) visit(full, root, 0); + } + + return [...candidates].sort(); +} + +function listCodebaseMapFiles(cwd: string): string[] { + const codebaseDir = path.join(planningRoot(cwd), 'codebase'); + if (!fs.existsSync(codebaseDir)) return []; + return REQUIRED_CODEBASE_MAP_FILES.filter((file) => + fs.existsSync(path.join(codebaseDir, file)), + ); +} + +function getMapReadiness(hasCompleteMap: boolean, hasFastMap: boolean): MapReadiness { + if (hasCompleteMap) return 'complete'; + if (hasFastMap) return 'fast'; + return 'none'; +} + +function mapSummaryStatus(mapReadiness: MapReadiness): string { + if (mapReadiness === 'complete') return '.planning/codebase/ (complete codebase map)'; + if (mapReadiness === 'fast') return '.planning/codebase/ (fast/partial codebase map; complete map still required for project setup)'; + return 'missing'; +} + +function mapFinalStatus(mapReadiness: MapReadiness): string { + if (mapReadiness === 'complete') return 'complete'; + if (mapReadiness === 'fast') return 'fast/partial; complete map still required for project setup'; + return 'missing'; +} + +function planningMissing( + projectExists: boolean, + requirementsExists: boolean, + roadmapExists: boolean, + stateExists: boolean, +): string[] { + const missing: string[] = []; + if (!projectExists) missing.push('PROJECT.md'); + if (!requirementsExists) missing.push('REQUIREMENTS.md'); + if (!roadmapExists) missing.push('ROADMAP.md'); + if (!stateExists) missing.push('STATE.md'); + return missing; +} + +function nextAction(params: { + fastMode: boolean; + isBrownfield: boolean; + needsOnboardCodebaseMap: boolean; + hasDocsCandidates: boolean; + projectExists: boolean; + mapReadiness: MapReadiness; + onboardingSummaryExists: boolean; + onboardingSummaryPath: string; + hasPlanningArtifacts: boolean; + missingPlanningFiles: string[]; + handoffCommands: OnboardHandoffCommands; +}): OnboardNextAction { + if (params.isBrownfield && params.needsOnboardCodebaseMap) { + return { + kind: 'map-codebase', + command: params.fastMode ? params.handoffCommands.map_codebase_fast : params.handoffCommands.map_codebase, + reason: 'Existing code was detected, but the required .planning/codebase/ map is missing.', + }; + } + + if (params.hasPlanningArtifacts && params.missingPlanningFiles.length > 0) { + return { + kind: 'partial-planning', + missing: params.missingPlanningFiles, + reason: 'Project planning exists but required planning files are missing.', + }; + } + + if (params.fastMode && params.mapReadiness === 'fast' && !params.projectExists) { + return { + kind: 'complete-map-before-new-project', + command: params.handoffCommands.map_codebase, + reason: 'The fast map is enough for lightweight onboarding, but project setup still requires the complete codebase map.', + }; + } + + if (params.hasDocsCandidates && !params.projectExists) { + return { + kind: 'ingest-docs', + command: params.handoffCommands.ingest_docs, + reason: 'Detected existing ADR/PRD/SPEC/RFC document(s) before project setup.', + }; + } + + if (!params.isBrownfield && !params.projectExists && !params.hasDocsCandidates) { + return { + kind: 'new-project', + command: params.handoffCommands.new_project, + reason: 'No existing code or planning docs were detected.', + }; + } + + if (!params.projectExists) { + return { + kind: 'new-project', + command: params.handoffCommands.new_project, + reason: 'Codebase context is ready for project initialization.', + }; + } + + if (!params.onboardingSummaryExists) { + return { + kind: 'write-summary', + summary_path: params.onboardingSummaryPath, + reason: 'Onboarding summary is missing.', + }; + } + + return { + kind: 'ready', + reason: 'Onboarding summary already exists.', + }; +} + +function buildHandoffCommands(cwd: string): OnboardHandoffCommands { + const runtime = resolveRuntime(cwd); + return { + ingest_docs: formatGsdSlash('ingest-docs', runtime) as string, + manager: formatGsdSlash('manager', runtime) as string, + map_codebase: formatGsdSlash('map-codebase', runtime) as string, + map_codebase_fast: formatGsdSlash('map-codebase --fast', runtime) as string, + new_project: formatGsdSlash('new-project', runtime) as string, + onboard: formatGsdSlash('onboard', runtime) as string, + }; +} + +function buildOnboardProjection(cwd: string, options: BuildOnboardProjectionOptions): OnboardProjection { + const handoffCommands = buildHandoffCommands(cwd); + const codebaseMapFiles = listCodebaseMapFiles(cwd); + const missingCodebaseMapFiles = REQUIRED_CODEBASE_MAP_FILES.filter( + (file) => !codebaseMapFiles.includes(file), + ); + const missingFastCodebaseMapFiles = FAST_CODEBASE_MAP_FILES.filter( + (file) => !codebaseMapFiles.includes(file), + ); + const docCandidates = listPlanningDocCandidates(cwd); + const hasCode = hasCodeFilesInternal(cwd); + const hasPackageFile = hasPackageFileInternal(cwd); + const isBrownfield = hasCode || hasPackageFile; + const hasCodebaseMap = codebaseMapFiles.length === REQUIRED_CODEBASE_MAP_FILES.length; + const hasFastCodebaseMap = missingFastCodebaseMapFiles.length === 0; + const mapReadinessValue = getMapReadiness(hasCodebaseMap, hasFastCodebaseMap); + const needsCodebaseMap = isBrownfield && !hasCodebaseMap; + const needsFastCodebaseMap = isBrownfield && !hasFastCodebaseMap; + const needsOnboardCodebaseMap = options.fast ? needsFastCodebaseMap : needsCodebaseMap; + const projectRootPath = path.join(planningRoot(cwd), 'PROJECT.md'); + const projectScopedPath = path.join(planningDir(cwd), 'PROJECT.md'); + const projectExists = + fs.existsSync(projectRootPath) || fs.existsSync(projectScopedPath); + const requirementsExists = fs.existsSync(path.join(planningDir(cwd), 'REQUIREMENTS.md')); + const roadmapExists = fs.existsSync(path.join(planningDir(cwd), 'ROADMAP.md')); + const stateExists = fs.existsSync(path.join(planningDir(cwd), 'STATE.md')); + const onboardingSummaryPath = path.join(planningRoot(cwd), 'onboarding', 'SUMMARY.md'); + const onboardingSummaryExists = fs.existsSync(onboardingSummaryPath); + const hasPlanningArtifacts = projectExists || requirementsExists || roadmapExists || stateExists; + const missingPlanningFiles = planningMissing( + projectExists, + requirementsExists, + roadmapExists, + stateExists, + ); + + return { + commit_docs: options.commitDocs, + text_mode: options.textMode, + + project_exists: projectExists, + planning_exists: fs.existsSync(planningRoot(cwd)), + requirements_exists: requirementsExists, + roadmap_exists: roadmapExists, + state_exists: stateExists, + config_exists: fs.existsSync(path.join(planningDir(cwd), 'config.json')), + + handoff_commands: handoffCommands, + + has_existing_code: hasCode, + has_package_file: hasPackageFile, + is_brownfield: isBrownfield, + fast_mode: options.fast, + map_readiness: mapReadinessValue, + next_action: nextAction({ + fastMode: options.fast, + isBrownfield, + needsOnboardCodebaseMap, + hasDocsCandidates: docCandidates.length > 0, + projectExists, + mapReadiness: mapReadinessValue, + onboardingSummaryExists, + onboardingSummaryPath: toPosixPath(path.relative(cwd, onboardingSummaryPath)), + hasPlanningArtifacts, + missingPlanningFiles, + handoffCommands, + }), + needs_codebase_map: needsCodebaseMap, + needs_fast_codebase_map: needsFastCodebaseMap, + has_codebase_map: hasCodebaseMap, + has_fast_codebase_map: hasFastCodebaseMap, + codebase_dir_exists: fs.existsSync(path.join(planningRoot(cwd), 'codebase')), + fast_codebase_map_files_required: FAST_CODEBASE_MAP_FILES, + codebase_map_files_present: codebaseMapFiles, + missing_codebase_map_files: missingCodebaseMapFiles, + missing_fast_codebase_map_files: missingFastCodebaseMapFiles, + codebase_map_summary_status: mapSummaryStatus(mapReadinessValue), + codebase_map_final_status: mapFinalStatus(mapReadinessValue), + + has_docs_candidates: docCandidates.length > 0, + doc_candidate_count: docCandidates.length, + doc_candidates: docCandidates, + + onboarding_summary_exists: onboardingSummaryExists, + onboarding_summary_path: toPosixPath(path.relative(cwd, onboardingSummaryPath)), + + project_path: toPosixPath(path.relative( + cwd, + fs.existsSync(projectRootPath) ? projectRootPath : projectScopedPath, + )), + requirements_path: toPosixPath( + path.relative(cwd, path.join(planningDir(cwd), 'REQUIREMENTS.md')), + ), + roadmap_path: toPosixPath(path.relative(cwd, path.join(planningDir(cwd), 'ROADMAP.md'))), + state_path: toPosixPath(path.relative(cwd, path.join(planningDir(cwd), 'STATE.md'))), + codebase_dir: toPosixPath(path.relative(cwd, path.join(planningRoot(cwd), 'codebase'))), + onboarding_dir: toPosixPath(path.relative(cwd, path.join(planningRoot(cwd), 'onboarding'))), + }; +} + +export = { + REQUIRED_CODEBASE_MAP_FILES, + FAST_CODEBASE_MAP_FILES, + buildOnboardProjection, + hasCodeFilesInternal, + hasPackageFileInternal, + listCodebaseMapFiles, + listPlanningDocCandidates, +}; diff --git a/tests/fixtures/golden-install-parity/antigravity.json b/tests/fixtures/golden-install-parity/antigravity.json index 738934d69..1621a1957 100644 --- a/tests/fixtures/golden-install-parity/antigravity.json +++ b/tests/fixtures/golden-install-parity/antigravity.json @@ -87,6 +87,7 @@ "gsd-core/references/gates.md": "7dc9fd3a3d6217c6", "gsd-core/references/git-integration.md": "9e6076a137f9e156", "gsd-core/references/git-planning-commit.md": "f897a15ebfc3f5a7", + "gsd-core/references/gsd-run-resolver.md": "c11c191ffad86a9f", "gsd-core/references/honest-verifier.md": "a31a4bf42d82d5e9", "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", @@ -172,7 +173,7 @@ "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", "gsd-core/templates/phase-prompt.md": "31f627d456ab14b0", "gsd-core/templates/planner-subagent-prompt.md": "6c9f1b23ee3dc05f", - "gsd-core/templates/project.md": "e4a3b331be081e62", + "gsd-core/templates/project.md": "fae14114f2b79b10", "gsd-core/templates/requirements.md": "a44de4c2f146e473", "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", @@ -225,7 +226,7 @@ "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", "gsd-core/workflows/discuss-phase/templates/context.md": "9804674fccada405", "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "2b56ec2868cbddb4", - "gsd-core/workflows/do.md": "22adc4ed8589a015", + "gsd-core/workflows/do.md": "3eddf1cc9e04b685", "gsd-core/workflows/docs-update.md": "8e986e26d0e6e1a0", "gsd-core/workflows/edit-phase.md": "fc932e82ba1f585a", "gsd-core/workflows/eval-review.md": "eb4040eaa5b8497f", @@ -242,10 +243,10 @@ "gsd-core/workflows/graduation.md": "a9d8f15ba81a993f", "gsd-core/workflows/health.md": "1ac4d567ee95acfb", "gsd-core/workflows/help.md": "5d040504b9ab35e3", - "gsd-core/workflows/help/modes/brief.md": "2e923b3ed635d495", - "gsd-core/workflows/help/modes/default.md": "b544113eb9aa54fa", - "gsd-core/workflows/help/modes/full.md": "0e253248c1c2e063", - "gsd-core/workflows/help/modes/topic.md": "19a279fe91922d3b", + "gsd-core/workflows/help/modes/brief.md": "fa2675516b40e2e3", + "gsd-core/workflows/help/modes/default.md": "be05e56b2c5ee2c0", + "gsd-core/workflows/help/modes/full.md": "c8ffd141e28f5111", + "gsd-core/workflows/help/modes/topic.md": "0bf9ab39d7044d69", "gsd-core/workflows/import.md": "41c62ae199209a68", "gsd-core/workflows/inbox.md": "a448220c548f27bc", "gsd-core/workflows/ingest-docs.md": "e2707f28f67d128b", @@ -263,6 +264,7 @@ "gsd-core/workflows/next.md": "8beefb4335dd7c41", "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", "gsd-core/workflows/note.md": "3ce09c0aa0a20599", + "gsd-core/workflows/onboard.md": "69d871aa53a1a859", "gsd-core/workflows/pause-work.md": "564de32981a24337", "gsd-core/workflows/plan-milestone-gaps.md": "dd6a4b3a8b05ab6e", "gsd-core/workflows/plan-phase.md": "cb56e635fef4d3f3", @@ -367,7 +369,7 @@ "skills/gsd-inbox/SKILL.md": "4ec0198966ac4f7d", "skills/gsd-ingest-docs/SKILL.md": "f4e43968af317ed8", "skills/gsd-manager/SKILL.md": "6e51785860784d8c", - "skills/gsd-map-codebase/SKILL.md": "e10431a9386c6aec", + "skills/gsd-map-codebase/SKILL.md": "552f914f43b2181c", "skills/gsd-mempalace-capture/SKILL.md": "588ddf4fbf3ebe65", "skills/gsd-mempalace-recall/SKILL.md": "2d95e385fee26dee", "skills/gsd-milestone-summary/SKILL.md": "2955ab3e3a444ca3", @@ -378,9 +380,10 @@ "skills/gsd-ns-context/SKILL.md": "e791bc60e4cf124e", "skills/gsd-ns-ideate/SKILL.md": "b85f270e8415f595", "skills/gsd-ns-manage/SKILL.md": "d55c53b5b0513033", - "skills/gsd-ns-project/SKILL.md": "64844073a6115c45", + "skills/gsd-ns-project/SKILL.md": "905eff81dbb98b38", "skills/gsd-ns-review/SKILL.md": "2e30158e112d173c", "skills/gsd-ns-workflow/SKILL.md": "529e21833a6a8831", + "skills/gsd-onboard/SKILL.md": "1447665c64c8ade8", "skills/gsd-pause-work/SKILL.md": "9d3cc6bd70b03df1", "skills/gsd-phase/SKILL.md": "00676bbea61410bf", "skills/gsd-plan-phase/SKILL.md": "168046ccf9702532", diff --git a/tests/fixtures/golden-install-parity/augment.json b/tests/fixtures/golden-install-parity/augment.json index eaa7fb7ba..8c1231a56 100644 --- a/tests/fixtures/golden-install-parity/augment.json +++ b/tests/fixtures/golden-install-parity/augment.json @@ -62,7 +62,7 @@ "commands/gsd-inbox.md": "c218298db8b36e31", "commands/gsd-ingest-docs.md": "6718b04c597a5428", "commands/gsd-manager.md": "8f4ae79774902293", - "commands/gsd-map-codebase.md": "f3a06c4c7503f243", + "commands/gsd-map-codebase.md": "e4e170d4ef2d46c6", "commands/gsd-mempalace-capture.md": "2e610f3ebe2eb5b4", "commands/gsd-mempalace-recall.md": "38716c0983a3ef9c", "commands/gsd-milestone-summary.md": "ff5e11e6b33d4b5e", @@ -73,9 +73,10 @@ "commands/gsd-ns-context.md": "011c44e7aa46e64a", "commands/gsd-ns-ideate.md": "edc5e543512dd48a", "commands/gsd-ns-manage.md": "0409d810e499357f", - "commands/gsd-ns-project.md": "8dfd1b9a2ffe86ac", + "commands/gsd-ns-project.md": "ff67e85bc6f7fc5a", "commands/gsd-ns-review.md": "3766ed10827882a0", "commands/gsd-ns-workflow.md": "c3b3c046a74ec0ee", + "commands/gsd-onboard.md": "1e8acf7be31834be", "commands/gsd-pause-work.md": "4fb032f72238fe33", "commands/gsd-phase.md": "4920d15d779329eb", "commands/gsd-plan-phase.md": "e74f3cb7a10cbb83", @@ -157,6 +158,7 @@ "gsd-core/references/gates.md": "bd79c7f90c8cb8d7", "gsd-core/references/git-integration.md": "77bf9dff38b2c9d4", "gsd-core/references/git-planning-commit.md": "f897a15ebfc3f5a7", + "gsd-core/references/gsd-run-resolver.md": "e71eb728b84641b1", "gsd-core/references/honest-verifier.md": "8815c9fc18c35719", "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", @@ -242,7 +244,7 @@ "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", "gsd-core/templates/phase-prompt.md": "b811bf951092df2f", "gsd-core/templates/planner-subagent-prompt.md": "ebf29dbb27042370", - "gsd-core/templates/project.md": "ab4af6becca2bb23", + "gsd-core/templates/project.md": "4f311fb1b05b823b", "gsd-core/templates/requirements.md": "a44de4c2f146e473", "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", @@ -295,7 +297,7 @@ "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", "gsd-core/workflows/discuss-phase/templates/context.md": "6cd929e989fe2b0f", "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "1bbd7703f11128e1", - "gsd-core/workflows/do.md": "8f460af710c8f6a4", + "gsd-core/workflows/do.md": "7512dd1892f118a1", "gsd-core/workflows/docs-update.md": "f35922d15b7061c9", "gsd-core/workflows/edit-phase.md": "966a3eadd1bebc04", "gsd-core/workflows/eval-review.md": "f898936e2cfe4130", @@ -312,10 +314,10 @@ "gsd-core/workflows/graduation.md": "47f1594c88c08501", "gsd-core/workflows/health.md": "107e3c72e76d9535", "gsd-core/workflows/help.md": "5d040504b9ab35e3", - "gsd-core/workflows/help/modes/brief.md": "5fe077fbbdb5d9f7", - "gsd-core/workflows/help/modes/default.md": "cc8ef97de634c995", - "gsd-core/workflows/help/modes/full.md": "3ac1c1bb851da7a5", - "gsd-core/workflows/help/modes/topic.md": "6762e41e3291ae24", + "gsd-core/workflows/help/modes/brief.md": "924860e1f07defb0", + "gsd-core/workflows/help/modes/default.md": "08a02976c0c5cc50", + "gsd-core/workflows/help/modes/full.md": "fc307cb77544df1d", + "gsd-core/workflows/help/modes/topic.md": "5c160093f3cbf35d", "gsd-core/workflows/import.md": "3d3fa603ceb8bc9f", "gsd-core/workflows/inbox.md": "437f981ef9ae7b26", "gsd-core/workflows/ingest-docs.md": "c859921c811ac11b", @@ -333,6 +335,7 @@ "gsd-core/workflows/next.md": "13fb800f2472d970", "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", "gsd-core/workflows/note.md": "5a99eb396c744619", + "gsd-core/workflows/onboard.md": "6f9e6c0b484271a9", "gsd-core/workflows/pause-work.md": "f2b33bba5593d422", "gsd-core/workflows/plan-milestone-gaps.md": "852f6d7c0c4299dc", "gsd-core/workflows/plan-phase.md": "8b1209958c31ca2f", @@ -414,7 +417,7 @@ "skills/gsd-ns-context/skills/docs-update/SKILL.md": "e7ab14a984f7462c", "skills/gsd-ns-context/skills/extract-learnings/SKILL.md": "48846bf26ccaf0e7", "skills/gsd-ns-context/skills/graphify/SKILL.md": "3d6341614add6ccd", - "skills/gsd-ns-context/skills/map-codebase/SKILL.md": "51d6b970dca3c28e", + "skills/gsd-ns-context/skills/map-codebase/SKILL.md": "2017007dcd69d153", "skills/gsd-ns-context/skills/mempalace-capture/SKILL.md": "a7261b5ead71cc58", "skills/gsd-ns-context/skills/mempalace-recall/SKILL.md": "646e59e76acd548f", "skills/gsd-ns-ideate/SKILL.md": "d70360a5f7e8ac90", @@ -442,7 +445,7 @@ "skills/gsd-ns-manage/skills/update/SKILL.md": "c8165b8085ba106a", "skills/gsd-ns-manage/skills/workspace/SKILL.md": "98cc03aa8c735e9d", "skills/gsd-ns-manage/skills/workstreams/SKILL.md": "94d00b5116523f36", - "skills/gsd-ns-project/SKILL.md": "4d7e3c3870536dc9", + "skills/gsd-ns-project/SKILL.md": "ae47130ec878de8c", "skills/gsd-ns-project/skills/audit-milestone/SKILL.md": "6d4c77390c549fc7", "skills/gsd-ns-project/skills/complete-milestone/SKILL.md": "0af489daf6fd3f16", "skills/gsd-ns-project/skills/import/SKILL.md": "a3cfa7abc5ddd26d", @@ -450,6 +453,7 @@ "skills/gsd-ns-project/skills/milestone-summary/SKILL.md": "18dc0c134cb62657", "skills/gsd-ns-project/skills/new-milestone/SKILL.md": "a94ff34b09e17a98", "skills/gsd-ns-project/skills/new-project/SKILL.md": "81f681f54ca61f90", + "skills/gsd-ns-project/skills/onboard/SKILL.md": "1f5b29c75a91be4f", "skills/gsd-ns-project/skills/profile-user/SKILL.md": "68b015a40d386bff", "skills/gsd-ns-project/skills/review-backlog/SKILL.md": "0f25310aa0cd48f6", "skills/gsd-ns-review/SKILL.md": "d7567fd9a75a5c21", diff --git a/tests/fixtures/golden-install-parity/claude.json b/tests/fixtures/golden-install-parity/claude.json index 67d82d1ee..c12529b64 100644 --- a/tests/fixtures/golden-install-parity/claude.json +++ b/tests/fixtures/golden-install-parity/claude.json @@ -86,6 +86,7 @@ "gsd-core/references/gates.md": "7dc9fd3a3d6217c6", "gsd-core/references/git-integration.md": "5c70ef3203b7c9ce", "gsd-core/references/git-planning-commit.md": "f897a15ebfc3f5a7", + "gsd-core/references/gsd-run-resolver.md": "e71eb728b84641b1", "gsd-core/references/honest-verifier.md": "8815c9fc18c35719", "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", @@ -171,7 +172,7 @@ "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", "gsd-core/templates/phase-prompt.md": "213ccd947451ff2b", "gsd-core/templates/planner-subagent-prompt.md": "6c9f1b23ee3dc05f", - "gsd-core/templates/project.md": "1f687c7a88381080", + "gsd-core/templates/project.md": "ae1f68db042c2522", "gsd-core/templates/requirements.md": "a44de4c2f146e473", "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", @@ -224,7 +225,7 @@ "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", "gsd-core/workflows/discuss-phase/templates/context.md": "6cd929e989fe2b0f", "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "1bbd7703f11128e1", - "gsd-core/workflows/do.md": "56215b98e26448bc", + "gsd-core/workflows/do.md": "61b92fb4d0bf3975", "gsd-core/workflows/docs-update.md": "63082608d3ae92be", "gsd-core/workflows/edit-phase.md": "8323bfe10faa0c0a", "gsd-core/workflows/eval-review.md": "f59e8329dae1e528", @@ -241,10 +242,10 @@ "gsd-core/workflows/graduation.md": "47f1594c88c08501", "gsd-core/workflows/health.md": "f934b1f1e9f3ae72", "gsd-core/workflows/help.md": "5d040504b9ab35e3", - "gsd-core/workflows/help/modes/brief.md": "2e923b3ed635d495", - "gsd-core/workflows/help/modes/default.md": "b544113eb9aa54fa", - "gsd-core/workflows/help/modes/full.md": "93cbdf7e542115a1", - "gsd-core/workflows/help/modes/topic.md": "899d7168a485297f", + "gsd-core/workflows/help/modes/brief.md": "fa2675516b40e2e3", + "gsd-core/workflows/help/modes/default.md": "be05e56b2c5ee2c0", + "gsd-core/workflows/help/modes/full.md": "e2084c6766e32d6c", + "gsd-core/workflows/help/modes/topic.md": "6e42db16f1568be9", "gsd-core/workflows/import.md": "6e8acff8c3918795", "gsd-core/workflows/inbox.md": "91aac6360e1a8672", "gsd-core/workflows/ingest-docs.md": "25832c784e8812e6", @@ -262,6 +263,7 @@ "gsd-core/workflows/next.md": "ef30b829a6d5c5f6", "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", "gsd-core/workflows/note.md": "42b66686b2c102cb", + "gsd-core/workflows/onboard.md": "3c50ed1f1fd07619", "gsd-core/workflows/pause-work.md": "5716362557f44ce4", "gsd-core/workflows/plan-milestone-gaps.md": "1b43d12812f7bc1e", "gsd-core/workflows/plan-phase.md": "6978a15b5232b310", @@ -366,7 +368,7 @@ "skills/gsd-inbox/SKILL.md": "d05a099c0be02c60", "skills/gsd-ingest-docs/SKILL.md": "eb85e654917a503a", "skills/gsd-manager/SKILL.md": "1370d93741e47828", - "skills/gsd-map-codebase/SKILL.md": "5009595dbde69739", + "skills/gsd-map-codebase/SKILL.md": "cf65e61890448285", "skills/gsd-mempalace-capture/SKILL.md": "40a31ad049374297", "skills/gsd-mempalace-recall/SKILL.md": "c3f412d5a64f3921", "skills/gsd-milestone-summary/SKILL.md": "33d51a325d314f3a", @@ -377,9 +379,10 @@ "skills/gsd-ns-context/SKILL.md": "3102e7ad9b60f182", "skills/gsd-ns-ideate/SKILL.md": "c2c129408a046d22", "skills/gsd-ns-manage/SKILL.md": "8d786e01fa28a7bb", - "skills/gsd-ns-project/SKILL.md": "cc0c4bd9feeab147", + "skills/gsd-ns-project/SKILL.md": "76c77b121ad68b6c", "skills/gsd-ns-review/SKILL.md": "4111ea56e820479f", "skills/gsd-ns-workflow/SKILL.md": "4282c40a5e6e8bbe", + "skills/gsd-onboard/SKILL.md": "46460b479b7524bf", "skills/gsd-pause-work/SKILL.md": "35e8a148e44f5361", "skills/gsd-phase/SKILL.md": "00be96e7ae36c6f0", "skills/gsd-plan-phase/SKILL.md": "0c9e87da048acfb7", diff --git a/tests/fixtures/golden-install-parity/cline.json b/tests/fixtures/golden-install-parity/cline.json index 249c34e6c..388feaf2b 100644 --- a/tests/fixtures/golden-install-parity/cline.json +++ b/tests/fixtures/golden-install-parity/cline.json @@ -90,6 +90,7 @@ "gsd-core/references/gates.md": "bd79c7f90c8cb8d7", "gsd-core/references/git-integration.md": "f5403e1470e46e69", "gsd-core/references/git-planning-commit.md": "f897a15ebfc3f5a7", + "gsd-core/references/gsd-run-resolver.md": "07544d9a957fc2ca", "gsd-core/references/honest-verifier.md": "8815c9fc18c35719", "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", @@ -175,7 +176,7 @@ "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", "gsd-core/templates/phase-prompt.md": "b811bf951092df2f", "gsd-core/templates/planner-subagent-prompt.md": "ebf29dbb27042370", - "gsd-core/templates/project.md": "ab4af6becca2bb23", + "gsd-core/templates/project.md": "4f311fb1b05b823b", "gsd-core/templates/requirements.md": "a44de4c2f146e473", "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", @@ -228,7 +229,7 @@ "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", "gsd-core/workflows/discuss-phase/templates/context.md": "6cd929e989fe2b0f", "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "1bbd7703f11128e1", - "gsd-core/workflows/do.md": "a35bbd09f381d940", + "gsd-core/workflows/do.md": "045a18f30efb1202", "gsd-core/workflows/docs-update.md": "39f288623a8f6f32", "gsd-core/workflows/edit-phase.md": "9c9fadc047c61d74", "gsd-core/workflows/eval-review.md": "3e1d7829ed2ed494", @@ -245,10 +246,10 @@ "gsd-core/workflows/graduation.md": "16fedecda36769eb", "gsd-core/workflows/health.md": "788fad84fa42eb9f", "gsd-core/workflows/help.md": "5d040504b9ab35e3", - "gsd-core/workflows/help/modes/brief.md": "5fe077fbbdb5d9f7", - "gsd-core/workflows/help/modes/default.md": "77c34f4a77dec02c", - "gsd-core/workflows/help/modes/full.md": "1bf502890828ada8", - "gsd-core/workflows/help/modes/topic.md": "6762e41e3291ae24", + "gsd-core/workflows/help/modes/brief.md": "924860e1f07defb0", + "gsd-core/workflows/help/modes/default.md": "86f7a14ad06e2f6f", + "gsd-core/workflows/help/modes/full.md": "efb266b8dbe60f51", + "gsd-core/workflows/help/modes/topic.md": "5c160093f3cbf35d", "gsd-core/workflows/import.md": "96ec687c5cfe84ac", "gsd-core/workflows/inbox.md": "437f981ef9ae7b26", "gsd-core/workflows/ingest-docs.md": "7d0517356c9f2619", @@ -266,6 +267,7 @@ "gsd-core/workflows/next.md": "3f8b61a35587a021", "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", "gsd-core/workflows/note.md": "5a99eb396c744619", + "gsd-core/workflows/onboard.md": "6f9e6c0b484271a9", "gsd-core/workflows/pause-work.md": "3530607514b0ac00", "gsd-core/workflows/plan-milestone-gaps.md": "bafdc6945cd2bd87", "gsd-core/workflows/plan-phase.md": "46db1a845f25a579", @@ -325,7 +327,7 @@ "skills/gsd-ns-context/skills/docs-update/SKILL.md": "d150afd41a25ec08", "skills/gsd-ns-context/skills/extract-learnings/SKILL.md": "d39269bea995fabc", "skills/gsd-ns-context/skills/graphify/SKILL.md": "030050fcd08d129d", - "skills/gsd-ns-context/skills/map-codebase/SKILL.md": "19aec854da15f77b", + "skills/gsd-ns-context/skills/map-codebase/SKILL.md": "fa6a37402430af7d", "skills/gsd-ns-context/skills/mempalace-capture/SKILL.md": "588ddf4fbf3ebe65", "skills/gsd-ns-context/skills/mempalace-recall/SKILL.md": "2d95e385fee26dee", "skills/gsd-ns-ideate/SKILL.md": "c10342345c01c91f", @@ -353,7 +355,7 @@ "skills/gsd-ns-manage/skills/update/SKILL.md": "2666ab7786b69017", "skills/gsd-ns-manage/skills/workspace/SKILL.md": "c2616b157ec2350b", "skills/gsd-ns-manage/skills/workstreams/SKILL.md": "737841783c7fdd4f", - "skills/gsd-ns-project/SKILL.md": "5668e3a5e1d8896d", + "skills/gsd-ns-project/SKILL.md": "fac77a9e770fd655", "skills/gsd-ns-project/skills/audit-milestone/SKILL.md": "739ed755ad84e58e", "skills/gsd-ns-project/skills/complete-milestone/SKILL.md": "a69d534b385d6aaf", "skills/gsd-ns-project/skills/import/SKILL.md": "bc9b615cb141d26f", @@ -361,6 +363,7 @@ "skills/gsd-ns-project/skills/milestone-summary/SKILL.md": "e3636a5e9bbaab1f", "skills/gsd-ns-project/skills/new-milestone/SKILL.md": "bc8989d97f3161ad", "skills/gsd-ns-project/skills/new-project/SKILL.md": "ff0d57491df30624", + "skills/gsd-ns-project/skills/onboard/SKILL.md": "56c34282575926d4", "skills/gsd-ns-project/skills/profile-user/SKILL.md": "0406eed4dbd9560c", "skills/gsd-ns-project/skills/review-backlog/SKILL.md": "d8a150558cc9326a", "skills/gsd-ns-review/SKILL.md": "c5afe33c212947dd", diff --git a/tests/fixtures/golden-install-parity/codebuddy.json b/tests/fixtures/golden-install-parity/codebuddy.json index d2f667992..3c64eaf27 100644 --- a/tests/fixtures/golden-install-parity/codebuddy.json +++ b/tests/fixtures/golden-install-parity/codebuddy.json @@ -62,7 +62,7 @@ "commands/gsd-inbox.md": "eecfcfff57f89975", "commands/gsd-ingest-docs.md": "ab3e58239c23d61d", "commands/gsd-manager.md": "bfe9e261fa918876", - "commands/gsd-map-codebase.md": "9ed09a9a9ce48ffd", + "commands/gsd-map-codebase.md": "5093093d42240325", "commands/gsd-mempalace-capture.md": "e9e00b0602e1d8b8", "commands/gsd-mempalace-recall.md": "6efef238d8c62569", "commands/gsd-milestone-summary.md": "e3a36fbd695a1833", @@ -73,9 +73,10 @@ "commands/gsd-ns-context.md": "cc8954f405ae7916", "commands/gsd-ns-ideate.md": "fd1dd80d705e6e36", "commands/gsd-ns-manage.md": "5cc012d0be1caabb", - "commands/gsd-ns-project.md": "52e30c8d84bb1ee5", + "commands/gsd-ns-project.md": "76672fae61723e55", "commands/gsd-ns-review.md": "a28dbfd4aba5f74b", "commands/gsd-ns-workflow.md": "a1b874be9cf16caf", + "commands/gsd-onboard.md": "63283b90aa671229", "commands/gsd-pause-work.md": "6caa75a7c2b4dd2d", "commands/gsd-phase.md": "e3ca4958ea20a935", "commands/gsd-plan-phase.md": "6de27d54ac191539", @@ -157,6 +158,7 @@ "gsd-core/references/gates.md": "bd79c7f90c8cb8d7", "gsd-core/references/git-integration.md": "77bf9dff38b2c9d4", "gsd-core/references/git-planning-commit.md": "f897a15ebfc3f5a7", + "gsd-core/references/gsd-run-resolver.md": "e71eb728b84641b1", "gsd-core/references/honest-verifier.md": "8815c9fc18c35719", "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", @@ -242,7 +244,7 @@ "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", "gsd-core/templates/phase-prompt.md": "b811bf951092df2f", "gsd-core/templates/planner-subagent-prompt.md": "ebf29dbb27042370", - "gsd-core/templates/project.md": "ab4af6becca2bb23", + "gsd-core/templates/project.md": "4f311fb1b05b823b", "gsd-core/templates/requirements.md": "a44de4c2f146e473", "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", @@ -295,7 +297,7 @@ "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", "gsd-core/workflows/discuss-phase/templates/context.md": "6cd929e989fe2b0f", "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "1bbd7703f11128e1", - "gsd-core/workflows/do.md": "8f460af710c8f6a4", + "gsd-core/workflows/do.md": "7512dd1892f118a1", "gsd-core/workflows/docs-update.md": "f35922d15b7061c9", "gsd-core/workflows/edit-phase.md": "966a3eadd1bebc04", "gsd-core/workflows/eval-review.md": "f898936e2cfe4130", @@ -312,10 +314,10 @@ "gsd-core/workflows/graduation.md": "47f1594c88c08501", "gsd-core/workflows/health.md": "107e3c72e76d9535", "gsd-core/workflows/help.md": "5d040504b9ab35e3", - "gsd-core/workflows/help/modes/brief.md": "5fe077fbbdb5d9f7", - "gsd-core/workflows/help/modes/default.md": "cc8ef97de634c995", - "gsd-core/workflows/help/modes/full.md": "4c018bcc9ed4e55c", - "gsd-core/workflows/help/modes/topic.md": "6762e41e3291ae24", + "gsd-core/workflows/help/modes/brief.md": "924860e1f07defb0", + "gsd-core/workflows/help/modes/default.md": "08a02976c0c5cc50", + "gsd-core/workflows/help/modes/full.md": "3a19e96b69bcc33e", + "gsd-core/workflows/help/modes/topic.md": "5c160093f3cbf35d", "gsd-core/workflows/import.md": "3d3fa603ceb8bc9f", "gsd-core/workflows/inbox.md": "437f981ef9ae7b26", "gsd-core/workflows/ingest-docs.md": "c859921c811ac11b", @@ -333,6 +335,7 @@ "gsd-core/workflows/next.md": "13fb800f2472d970", "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", "gsd-core/workflows/note.md": "5a99eb396c744619", + "gsd-core/workflows/onboard.md": "6f9e6c0b484271a9", "gsd-core/workflows/pause-work.md": "f2b33bba5593d422", "gsd-core/workflows/plan-milestone-gaps.md": "852f6d7c0c4299dc", "gsd-core/workflows/plan-phase.md": "3e4debac4579684f", @@ -437,7 +440,7 @@ "skills/gsd-inbox/SKILL.md": "0eb81a1b2e1835d3", "skills/gsd-ingest-docs/SKILL.md": "2df55e0ec95d57d9", "skills/gsd-manager/SKILL.md": "816db4d4ed618537", - "skills/gsd-map-codebase/SKILL.md": "00622b489483ba69", + "skills/gsd-map-codebase/SKILL.md": "b304ec25e9a95c93", "skills/gsd-mempalace-capture/SKILL.md": "5f10d368835e062c", "skills/gsd-mempalace-recall/SKILL.md": "70c8491f53f4161b", "skills/gsd-milestone-summary/SKILL.md": "9eb030a1ac307fa1", @@ -448,9 +451,10 @@ "skills/gsd-ns-context/SKILL.md": "305b9b6248e8cc95", "skills/gsd-ns-ideate/SKILL.md": "c63a1aed61888b35", "skills/gsd-ns-manage/SKILL.md": "6a5b711b5103c566", - "skills/gsd-ns-project/SKILL.md": "345ea11ccffd21b0", + "skills/gsd-ns-project/SKILL.md": "3711ce904d20ca66", "skills/gsd-ns-review/SKILL.md": "98f1f3b3caf1a279", "skills/gsd-ns-workflow/SKILL.md": "b77682820700300b", + "skills/gsd-onboard/SKILL.md": "6ad789a03124cd4f", "skills/gsd-pause-work/SKILL.md": "e2de20b7539e78d4", "skills/gsd-phase/SKILL.md": "f87211f779315ced", "skills/gsd-plan-phase/SKILL.md": "6134e837750034ab", diff --git a/tests/fixtures/golden-install-parity/codex.json b/tests/fixtures/golden-install-parity/codex.json index fde33cf6c..169606db3 100644 --- a/tests/fixtures/golden-install-parity/codex.json +++ b/tests/fixtures/golden-install-parity/codex.json @@ -122,6 +122,7 @@ "gsd-core/references/gates.md": "11fd2bdf27df57a5", "gsd-core/references/git-integration.md": "94715b69448bb818", "gsd-core/references/git-planning-commit.md": "5aad099c51135a0f", + "gsd-core/references/gsd-run-resolver.md": "e71eb728b84641b1", "gsd-core/references/honest-verifier.md": "8815c9fc18c35719", "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", @@ -207,7 +208,7 @@ "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", "gsd-core/templates/phase-prompt.md": "56c67fdc5d31b556", "gsd-core/templates/planner-subagent-prompt.md": "a48a5a2ebd5a9f47", - "gsd-core/templates/project.md": "034a6501f348c5a5", + "gsd-core/templates/project.md": "c6005bd88a346a3e", "gsd-core/templates/requirements.md": "a44de4c2f146e473", "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", @@ -260,7 +261,7 @@ "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", "gsd-core/workflows/discuss-phase/templates/context.md": "9804674fccada405", "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "2b56ec2868cbddb4", - "gsd-core/workflows/do.md": "8f3e77a9486bc57b", + "gsd-core/workflows/do.md": "feec00355f896a3d", "gsd-core/workflows/docs-update.md": "e255317df939e302", "gsd-core/workflows/edit-phase.md": "e592a4d85ce5380f", "gsd-core/workflows/eval-review.md": "63d0d0670b54c244", @@ -277,10 +278,10 @@ "gsd-core/workflows/graduation.md": "47f1594c88c08501", "gsd-core/workflows/health.md": "5b835fc606fd3e9b", "gsd-core/workflows/help.md": "08e1349950c5602a", - "gsd-core/workflows/help/modes/brief.md": "becceb85b25dca89", - "gsd-core/workflows/help/modes/default.md": "18c7dc50066f5cd6", - "gsd-core/workflows/help/modes/full.md": "8a7854a34df89bd8", - "gsd-core/workflows/help/modes/topic.md": "303613ba8b123b9f", + "gsd-core/workflows/help/modes/brief.md": "da44b130d1afe556", + "gsd-core/workflows/help/modes/default.md": "4bb3082d28026eea", + "gsd-core/workflows/help/modes/full.md": "01a1ec54df54da6e", + "gsd-core/workflows/help/modes/topic.md": "b7c7e4a8800bc3ea", "gsd-core/workflows/import.md": "cb3c8f9d09edb434", "gsd-core/workflows/inbox.md": "61b8b10e7a74b2e9", "gsd-core/workflows/ingest-docs.md": "3cb763e0687d7ffa", @@ -298,6 +299,7 @@ "gsd-core/workflows/next.md": "7097a9607a981086", "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", "gsd-core/workflows/note.md": "664da466ab989f9d", + "gsd-core/workflows/onboard.md": "83c40ba7055b8b24", "gsd-core/workflows/pause-work.md": "a217770ecafcb2e0", "gsd-core/workflows/plan-milestone-gaps.md": "73d46f77c50a0690", "gsd-core/workflows/plan-phase.md": "89ee3233c1aee273", @@ -382,7 +384,7 @@ "skills/gsd-inbox/SKILL.md": "1315033595643485", "skills/gsd-ingest-docs/SKILL.md": "5bd2838bf0b6dc1b", "skills/gsd-manager/SKILL.md": "cb1cf56f5d3f66d6", - "skills/gsd-map-codebase/SKILL.md": "25d0b3adfc8b75dc", + "skills/gsd-map-codebase/SKILL.md": "cd27dc028718426b", "skills/gsd-mempalace-capture/SKILL.md": "1a7fac4d53f607ab", "skills/gsd-mempalace-recall/SKILL.md": "7205b02250e89f25", "skills/gsd-milestone-summary/SKILL.md": "af84ecb400f23556", @@ -393,9 +395,10 @@ "skills/gsd-ns-context/SKILL.md": "9b496da79789b3f9", "skills/gsd-ns-ideate/SKILL.md": "84ca1cde06110981", "skills/gsd-ns-manage/SKILL.md": "909dafa0cd19ba5a", - "skills/gsd-ns-project/SKILL.md": "fb8ad6c2223be3c3", + "skills/gsd-ns-project/SKILL.md": "936b6998d42520ac", "skills/gsd-ns-review/SKILL.md": "022253010db0e072", "skills/gsd-ns-workflow/SKILL.md": "cba075bc819b539e", + "skills/gsd-onboard/SKILL.md": "f42fc2edebeda671", "skills/gsd-pause-work/SKILL.md": "b379469eed78a196", "skills/gsd-phase/SKILL.md": "25477edc97a90c91", "skills/gsd-plan-phase/SKILL.md": "19ead1acb151a868", diff --git a/tests/fixtures/golden-install-parity/copilot.json b/tests/fixtures/golden-install-parity/copilot.json index df7ac4c89..2253639cb 100644 --- a/tests/fixtures/golden-install-parity/copilot.json +++ b/tests/fixtures/golden-install-parity/copilot.json @@ -88,6 +88,7 @@ "gsd-core/references/gates.md": "7dc9fd3a3d6217c6", "gsd-core/references/git-integration.md": "657a93c539c16cab", "gsd-core/references/git-planning-commit.md": "f897a15ebfc3f5a7", + "gsd-core/references/gsd-run-resolver.md": "fca7e30efb0afe3f", "gsd-core/references/honest-verifier.md": "08b1e82f59c18078", "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", @@ -173,7 +174,7 @@ "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", "gsd-core/templates/phase-prompt.md": "e2b07376944c84e8", "gsd-core/templates/planner-subagent-prompt.md": "6c9f1b23ee3dc05f", - "gsd-core/templates/project.md": "e4a3b331be081e62", + "gsd-core/templates/project.md": "fae14114f2b79b10", "gsd-core/templates/requirements.md": "a44de4c2f146e473", "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", @@ -226,7 +227,7 @@ "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", "gsd-core/workflows/discuss-phase/templates/context.md": "9804674fccada405", "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "2b56ec2868cbddb4", - "gsd-core/workflows/do.md": "988a20dab90c60c5", + "gsd-core/workflows/do.md": "9b46119803df09a6", "gsd-core/workflows/docs-update.md": "9292cfa3c52c434e", "gsd-core/workflows/edit-phase.md": "8667c28b22b1599f", "gsd-core/workflows/eval-review.md": "81c8e72ba3862856", @@ -243,10 +244,10 @@ "gsd-core/workflows/graduation.md": "f013efc29096faf0", "gsd-core/workflows/health.md": "f343fd32a0e398e4", "gsd-core/workflows/help.md": "5d040504b9ab35e3", - "gsd-core/workflows/help/modes/brief.md": "2e923b3ed635d495", - "gsd-core/workflows/help/modes/default.md": "b544113eb9aa54fa", - "gsd-core/workflows/help/modes/full.md": "0e9381367d6257bd", - "gsd-core/workflows/help/modes/topic.md": "19a279fe91922d3b", + "gsd-core/workflows/help/modes/brief.md": "fa2675516b40e2e3", + "gsd-core/workflows/help/modes/default.md": "be05e56b2c5ee2c0", + "gsd-core/workflows/help/modes/full.md": "ce88d4eb6b301e09", + "gsd-core/workflows/help/modes/topic.md": "0bf9ab39d7044d69", "gsd-core/workflows/import.md": "f4fa65e332b00f7e", "gsd-core/workflows/inbox.md": "a448220c548f27bc", "gsd-core/workflows/ingest-docs.md": "52be14d1a0713731", @@ -264,6 +265,7 @@ "gsd-core/workflows/next.md": "81c08abb34b2da88", "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", "gsd-core/workflows/note.md": "4a5ee74cf2fc1f54", + "gsd-core/workflows/onboard.md": "a62602c6f3fd538a", "gsd-core/workflows/pause-work.md": "9ce66367be6c40db", "gsd-core/workflows/plan-milestone-gaps.md": "5cf589802d08bdf3", "gsd-core/workflows/plan-phase.md": "da462f812d1d0e61", @@ -347,7 +349,7 @@ "skills/gsd-inbox/SKILL.md": "cb9ed3865b67c04f", "skills/gsd-ingest-docs/SKILL.md": "10500de29525f6cf", "skills/gsd-manager/SKILL.md": "9946975bec15e737", - "skills/gsd-map-codebase/SKILL.md": "75806f8189d8af49", + "skills/gsd-map-codebase/SKILL.md": "39e7fd6bcc561f9d", "skills/gsd-mempalace-capture/SKILL.md": "f4511f69c14befb7", "skills/gsd-mempalace-recall/SKILL.md": "89523db66f834b2f", "skills/gsd-milestone-summary/SKILL.md": "5ca1dabfe0cd85f0", @@ -358,9 +360,10 @@ "skills/gsd-ns-context/SKILL.md": "d61edde87ae53105", "skills/gsd-ns-ideate/SKILL.md": "ca62cdf78ebe3585", "skills/gsd-ns-manage/SKILL.md": "9b1b7f6d9b877fcd", - "skills/gsd-ns-project/SKILL.md": "f1a666fb76527e6b", + "skills/gsd-ns-project/SKILL.md": "597b8dde8702c22d", "skills/gsd-ns-review/SKILL.md": "6405d0b1cf3f245d", "skills/gsd-ns-workflow/SKILL.md": "243287d21663ba87", + "skills/gsd-onboard/SKILL.md": "4d325f3033df2d37", "skills/gsd-pause-work/SKILL.md": "4f0caa008a8001ff", "skills/gsd-phase/SKILL.md": "d38c7f9b1d0d2360", "skills/gsd-plan-phase/SKILL.md": "d257bb9b1786039d", diff --git a/tests/fixtures/golden-install-parity/cursor.json b/tests/fixtures/golden-install-parity/cursor.json index 38f0ca0a6..ad6435a51 100644 --- a/tests/fixtures/golden-install-parity/cursor.json +++ b/tests/fixtures/golden-install-parity/cursor.json @@ -62,7 +62,7 @@ "commands/gsd-inbox.md": "e6bcee3f863d20db", "commands/gsd-ingest-docs.md": "9e7f8757b9408c01", "commands/gsd-manager.md": "f300b708a5487c76", - "commands/gsd-map-codebase.md": "cf50f4a600119c8a", + "commands/gsd-map-codebase.md": "12f705917eb202fb", "commands/gsd-mempalace-capture.md": "b30bce634ac3136c", "commands/gsd-mempalace-recall.md": "08c910285469a394", "commands/gsd-milestone-summary.md": "adfad2cf43fc5aad", @@ -73,9 +73,10 @@ "commands/gsd-ns-context.md": "b551dcc549c6a23f", "commands/gsd-ns-ideate.md": "32f561de74b1bc7b", "commands/gsd-ns-manage.md": "24445a84bd817c5b", - "commands/gsd-ns-project.md": "b39b509ac4161d28", + "commands/gsd-ns-project.md": "525f84d73f5c51e9", "commands/gsd-ns-review.md": "c8550463fbab5e76", "commands/gsd-ns-workflow.md": "2c1f1fde3c46bb40", + "commands/gsd-onboard.md": "d9e52f558fc2b90f", "commands/gsd-pause-work.md": "59630f05f95fff68", "commands/gsd-phase.md": "9a073dcd0f934f90", "commands/gsd-plan-phase.md": "57de92131fcb16b8", @@ -157,6 +158,7 @@ "gsd-core/references/gates.md": "7dc9fd3a3d6217c6", "gsd-core/references/git-integration.md": "9840f521ad6612b5", "gsd-core/references/git-planning-commit.md": "f897a15ebfc3f5a7", + "gsd-core/references/gsd-run-resolver.md": "e71eb728b84641b1", "gsd-core/references/honest-verifier.md": "8815c9fc18c35719", "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", @@ -242,7 +244,7 @@ "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", "gsd-core/templates/phase-prompt.md": "213ccd947451ff2b", "gsd-core/templates/planner-subagent-prompt.md": "6c9f1b23ee3dc05f", - "gsd-core/templates/project.md": "1f687c7a88381080", + "gsd-core/templates/project.md": "ae1f68db042c2522", "gsd-core/templates/requirements.md": "a44de4c2f146e473", "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", @@ -295,7 +297,7 @@ "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", "gsd-core/workflows/discuss-phase/templates/context.md": "6cd929e989fe2b0f", "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "cd5d01c9ef84ab73", - "gsd-core/workflows/do.md": "dc0ddd1f8231d26b", + "gsd-core/workflows/do.md": "9da6a73980ef2a71", "gsd-core/workflows/docs-update.md": "e86d7d7e2e3dac6d", "gsd-core/workflows/edit-phase.md": "8323bfe10faa0c0a", "gsd-core/workflows/eval-review.md": "a86279dd98dd5c03", @@ -312,10 +314,10 @@ "gsd-core/workflows/graduation.md": "53a4a6fa3b4e6613", "gsd-core/workflows/health.md": "e4d770484b5e7496", "gsd-core/workflows/help.md": "08e1349950c5602a", - "gsd-core/workflows/help/modes/brief.md": "2e923b3ed635d495", - "gsd-core/workflows/help/modes/default.md": "37c5149aae232e61", - "gsd-core/workflows/help/modes/full.md": "ed31d1afcbd3591f", - "gsd-core/workflows/help/modes/topic.md": "177d351f7465787d", + "gsd-core/workflows/help/modes/brief.md": "fa2675516b40e2e3", + "gsd-core/workflows/help/modes/default.md": "b88ff431fffe40ae", + "gsd-core/workflows/help/modes/full.md": "a7a42d4340e8e00b", + "gsd-core/workflows/help/modes/topic.md": "cee80e0adfa3b06c", "gsd-core/workflows/import.md": "5d5fb8e51f6a243a", "gsd-core/workflows/inbox.md": "797c287852eb8957", "gsd-core/workflows/ingest-docs.md": "c6759dbf17e79293", @@ -333,6 +335,7 @@ "gsd-core/workflows/next.md": "174356dcfd7c6c32", "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", "gsd-core/workflows/note.md": "1c1e466c764e3deb", + "gsd-core/workflows/onboard.md": "20c28136423d40ac", "gsd-core/workflows/pause-work.md": "5716362557f44ce4", "gsd-core/workflows/plan-milestone-gaps.md": "1b43d12812f7bc1e", "gsd-core/workflows/plan-phase.md": "c90c001a92fc8a47", @@ -417,7 +420,7 @@ "skills/gsd-inbox/SKILL.md": "f9b4ff17883ee7e4", "skills/gsd-ingest-docs/SKILL.md": "01ed9183a00252ee", "skills/gsd-manager/SKILL.md": "62cd9f671a39e8a4", - "skills/gsd-map-codebase/SKILL.md": "f529da27d3a30b09", + "skills/gsd-map-codebase/SKILL.md": "383559aca64201e8", "skills/gsd-mempalace-capture/SKILL.md": "b308823dee547c65", "skills/gsd-mempalace-recall/SKILL.md": "56f3037091a8bd9a", "skills/gsd-milestone-summary/SKILL.md": "c5dbbc8edb97a7f7", @@ -428,9 +431,10 @@ "skills/gsd-ns-context/SKILL.md": "dcf5711653d57354", "skills/gsd-ns-ideate/SKILL.md": "0114f0bc5501c1e3", "skills/gsd-ns-manage/SKILL.md": "f3232d05d5263f5b", - "skills/gsd-ns-project/SKILL.md": "9f737a544e8d3f31", + "skills/gsd-ns-project/SKILL.md": "81d802dd3ee2e1ff", "skills/gsd-ns-review/SKILL.md": "8c686e92f293bfdd", "skills/gsd-ns-workflow/SKILL.md": "c379192bd17d47d7", + "skills/gsd-onboard/SKILL.md": "cae1f9382469fa00", "skills/gsd-pause-work/SKILL.md": "10e7531a2cb392ad", "skills/gsd-phase/SKILL.md": "1a2c9b64c1af7ffc", "skills/gsd-plan-phase/SKILL.md": "0784da05d41dcfe7", diff --git a/tests/fixtures/golden-install-parity/hermes.json b/tests/fixtures/golden-install-parity/hermes.json index de0a888a6..724e79017 100644 --- a/tests/fixtures/golden-install-parity/hermes.json +++ b/tests/fixtures/golden-install-parity/hermes.json @@ -87,6 +87,7 @@ "gsd-core/references/gates.md": "7dc9fd3a3d6217c6", "gsd-core/references/git-integration.md": "12d23fcbaa7fcf06", "gsd-core/references/git-planning-commit.md": "f897a15ebfc3f5a7", + "gsd-core/references/gsd-run-resolver.md": "769d1472c989cd54", "gsd-core/references/honest-verifier.md": "8815c9fc18c35719", "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", @@ -172,7 +173,7 @@ "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", "gsd-core/templates/phase-prompt.md": "213ccd947451ff2b", "gsd-core/templates/planner-subagent-prompt.md": "6c9f1b23ee3dc05f", - "gsd-core/templates/project.md": "1f687c7a88381080", + "gsd-core/templates/project.md": "ae1f68db042c2522", "gsd-core/templates/requirements.md": "a44de4c2f146e473", "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", @@ -225,7 +226,7 @@ "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", "gsd-core/workflows/discuss-phase/templates/context.md": "6cd929e989fe2b0f", "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "1bbd7703f11128e1", - "gsd-core/workflows/do.md": "045e70c238db6faf", + "gsd-core/workflows/do.md": "e37540cc874fb782", "gsd-core/workflows/docs-update.md": "4d6c06e611d83b6d", "gsd-core/workflows/edit-phase.md": "7f27003f20e88fb8", "gsd-core/workflows/eval-review.md": "f510e5762212dc6f", @@ -242,10 +243,10 @@ "gsd-core/workflows/graduation.md": "d1fd52bbe41dcf34", "gsd-core/workflows/health.md": "c622a5ad0d347d30", "gsd-core/workflows/help.md": "5d040504b9ab35e3", - "gsd-core/workflows/help/modes/brief.md": "2e923b3ed635d495", - "gsd-core/workflows/help/modes/default.md": "bb6876c976996dbd", - "gsd-core/workflows/help/modes/full.md": "fdab4b3690bdd11d", - "gsd-core/workflows/help/modes/topic.md": "899d7168a485297f", + "gsd-core/workflows/help/modes/brief.md": "fa2675516b40e2e3", + "gsd-core/workflows/help/modes/default.md": "8874dac94eb68ae6", + "gsd-core/workflows/help/modes/full.md": "62779da88565d65a", + "gsd-core/workflows/help/modes/topic.md": "6e42db16f1568be9", "gsd-core/workflows/import.md": "a441445515bc2dd5", "gsd-core/workflows/inbox.md": "91aac6360e1a8672", "gsd-core/workflows/ingest-docs.md": "ad496a4c423f1ab7", @@ -263,6 +264,7 @@ "gsd-core/workflows/next.md": "8e1fa29751d96564", "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", "gsd-core/workflows/note.md": "42b66686b2c102cb", + "gsd-core/workflows/onboard.md": "3c50ed1f1fd07619", "gsd-core/workflows/pause-work.md": "ae2d5789a95f70fe", "gsd-core/workflows/plan-milestone-gaps.md": "c86cdc1964256b98", "gsd-core/workflows/plan-phase.md": "e995429805b69fdc", @@ -345,7 +347,7 @@ "skills/gsd/gsd-ns-context/skills/docs-update/SKILL.md": "b059b3045d5daf5c", "skills/gsd/gsd-ns-context/skills/extract-learnings/SKILL.md": "36e59d6e514dcaf0", "skills/gsd/gsd-ns-context/skills/graphify/SKILL.md": "169eefd42c444cde", - "skills/gsd/gsd-ns-context/skills/map-codebase/SKILL.md": "6062ccca1a14b827", + "skills/gsd/gsd-ns-context/skills/map-codebase/SKILL.md": "9d36eee52586bb34", "skills/gsd/gsd-ns-context/skills/mempalace-capture/SKILL.md": "3fa619f73834c436", "skills/gsd/gsd-ns-context/skills/mempalace-recall/SKILL.md": "5d06922e0d7ab7d9", "skills/gsd/gsd-ns-ideate/SKILL.md": "b36bb4700ed6723a", @@ -373,7 +375,7 @@ "skills/gsd/gsd-ns-manage/skills/update/SKILL.md": "433a236998c305b0", "skills/gsd/gsd-ns-manage/skills/workspace/SKILL.md": "d655afc6f16565ed", "skills/gsd/gsd-ns-manage/skills/workstreams/SKILL.md": "6893312eaf14dab0", - "skills/gsd/gsd-ns-project/SKILL.md": "3ff43fdc0e4a6d02", + "skills/gsd/gsd-ns-project/SKILL.md": "6b3af15e7c4441c9", "skills/gsd/gsd-ns-project/skills/audit-milestone/SKILL.md": "de0556f07d899e50", "skills/gsd/gsd-ns-project/skills/complete-milestone/SKILL.md": "180cccc09bf99444", "skills/gsd/gsd-ns-project/skills/import/SKILL.md": "bf781c7a0d83c2cd", @@ -381,6 +383,7 @@ "skills/gsd/gsd-ns-project/skills/milestone-summary/SKILL.md": "c4bda5737f1137f8", "skills/gsd/gsd-ns-project/skills/new-milestone/SKILL.md": "47586c1fc8aa0645", "skills/gsd/gsd-ns-project/skills/new-project/SKILL.md": "8f22ba75717b3c88", + "skills/gsd/gsd-ns-project/skills/onboard/SKILL.md": "1d8d06ac1f27dacd", "skills/gsd/gsd-ns-project/skills/profile-user/SKILL.md": "5a8e01bc7b873a20", "skills/gsd/gsd-ns-project/skills/review-backlog/SKILL.md": "f3ef97da4e9b1d4c", "skills/gsd/gsd-ns-review/SKILL.md": "23fbadeca640e2bd", diff --git a/tests/fixtures/golden-install-parity/kilo.json b/tests/fixtures/golden-install-parity/kilo.json index f058bfa39..7242c9099 100644 --- a/tests/fixtures/golden-install-parity/kilo.json +++ b/tests/fixtures/golden-install-parity/kilo.json @@ -62,7 +62,7 @@ "command/gsd-inbox.md": "1429fc7f556337c3", "command/gsd-ingest-docs.md": "e655ecf1d4433ba9", "command/gsd-manager.md": "1cdc133079833552", - "command/gsd-map-codebase.md": "186c8f79319abc1c", + "command/gsd-map-codebase.md": "704cb63214f51523", "command/gsd-mempalace-capture.md": "a94ca275cbe7134c", "command/gsd-mempalace-recall.md": "d358cdd89c935877", "command/gsd-milestone-summary.md": "4ab29b777f62f0bb", @@ -73,9 +73,10 @@ "command/gsd-ns-context.md": "9a2b55b64f2e1e4b", "command/gsd-ns-ideate.md": "27e7fcdc69eeeb5f", "command/gsd-ns-manage.md": "eded59052ca4b240", - "command/gsd-ns-project.md": "91417cf7b76581dd", + "command/gsd-ns-project.md": "c56395edb9bc7467", "command/gsd-ns-review.md": "61fe33e28eb1b961", "command/gsd-ns-workflow.md": "13c1ab91080c0cc3", + "command/gsd-onboard.md": "3e87a21c9c04f0d7", "command/gsd-pause-work.md": "04e993b1c9f8322b", "command/gsd-phase.md": "8f0e98dc6c223229", "command/gsd-plan-phase.md": "b37e9a61f946c975", @@ -157,6 +158,7 @@ "gsd-core/references/gates.md": "7dc9fd3a3d6217c6", "gsd-core/references/git-integration.md": "fbdf814a3af9c051", "gsd-core/references/git-planning-commit.md": "f897a15ebfc3f5a7", + "gsd-core/references/gsd-run-resolver.md": "e71eb728b84641b1", "gsd-core/references/honest-verifier.md": "8815c9fc18c35719", "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", @@ -242,7 +244,7 @@ "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", "gsd-core/templates/phase-prompt.md": "2e6fd96c2cc26470", "gsd-core/templates/planner-subagent-prompt.md": "6c9f1b23ee3dc05f", - "gsd-core/templates/project.md": "e4a3b331be081e62", + "gsd-core/templates/project.md": "fae14114f2b79b10", "gsd-core/templates/requirements.md": "a44de4c2f146e473", "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", @@ -295,7 +297,7 @@ "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", "gsd-core/workflows/discuss-phase/templates/context.md": "9804674fccada405", "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "04e4feee14772275", - "gsd-core/workflows/do.md": "1e6102574016b150", + "gsd-core/workflows/do.md": "d9a889717e390f8d", "gsd-core/workflows/docs-update.md": "79afaaf19fd527cc", "gsd-core/workflows/edit-phase.md": "8323bfe10faa0c0a", "gsd-core/workflows/eval-review.md": "926eda8bbee28b23", @@ -312,10 +314,10 @@ "gsd-core/workflows/graduation.md": "5cc8638dabcbfd40", "gsd-core/workflows/health.md": "064b3668d5d9569a", "gsd-core/workflows/help.md": "5d040504b9ab35e3", - "gsd-core/workflows/help/modes/brief.md": "2e923b3ed635d495", - "gsd-core/workflows/help/modes/default.md": "b544113eb9aa54fa", - "gsd-core/workflows/help/modes/full.md": "051f9633f45558b4", - "gsd-core/workflows/help/modes/topic.md": "19a279fe91922d3b", + "gsd-core/workflows/help/modes/brief.md": "fa2675516b40e2e3", + "gsd-core/workflows/help/modes/default.md": "be05e56b2c5ee2c0", + "gsd-core/workflows/help/modes/full.md": "775f766dfafb72f9", + "gsd-core/workflows/help/modes/topic.md": "0bf9ab39d7044d69", "gsd-core/workflows/import.md": "f8bbe6f2c0e08a78", "gsd-core/workflows/inbox.md": "a073396097c89c01", "gsd-core/workflows/ingest-docs.md": "29c1fe28bc93b345", @@ -333,6 +335,7 @@ "gsd-core/workflows/next.md": "888297a0b21888ea", "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", "gsd-core/workflows/note.md": "f8c2842a2217f776", + "gsd-core/workflows/onboard.md": "78b288089305dc46", "gsd-core/workflows/pause-work.md": "a6e5336c409fdc8b", "gsd-core/workflows/plan-milestone-gaps.md": "1b43d12812f7bc1e", "gsd-core/workflows/plan-phase.md": "03e59f06885e200f", @@ -438,7 +441,7 @@ "skills/gsd-inbox/SKILL.md": "34370c6138415209", "skills/gsd-ingest-docs/SKILL.md": "f049f06a6ec7da43", "skills/gsd-manager/SKILL.md": "a37ecdbe32952262", - "skills/gsd-map-codebase/SKILL.md": "e8c01704e8ada1d2", + "skills/gsd-map-codebase/SKILL.md": "e06d6ac1b7632cbe", "skills/gsd-mempalace-capture/SKILL.md": "f960b7b1a8fdf89b", "skills/gsd-mempalace-recall/SKILL.md": "2091c48e6e986e28", "skills/gsd-milestone-summary/SKILL.md": "da645171ca2299d8", @@ -449,9 +452,10 @@ "skills/gsd-ns-context/SKILL.md": "110fb2227bcde535", "skills/gsd-ns-ideate/SKILL.md": "d093d59a8519decc", "skills/gsd-ns-manage/SKILL.md": "2756981de613022e", - "skills/gsd-ns-project/SKILL.md": "757976d48e8b7a26", + "skills/gsd-ns-project/SKILL.md": "56d3d8a321d267f8", "skills/gsd-ns-review/SKILL.md": "680bdd33c882b049", "skills/gsd-ns-workflow/SKILL.md": "579b7f0dac74e1fb", + "skills/gsd-onboard/SKILL.md": "0e3cc902f44b41b8", "skills/gsd-pause-work/SKILL.md": "34366b18a392a717", "skills/gsd-phase/SKILL.md": "64a241d4f8665aa2", "skills/gsd-plan-phase/SKILL.md": "c73cba04a26f0bfe", diff --git a/tests/fixtures/golden-install-parity/kimi.json b/tests/fixtures/golden-install-parity/kimi.json index 9f4648e44..8b896e0e8 100644 --- a/tests/fixtures/golden-install-parity/kimi.json +++ b/tests/fixtures/golden-install-parity/kimi.json @@ -123,6 +123,7 @@ "gsd-core/references/gates.md": "bd79c7f90c8cb8d7", "gsd-core/references/git-integration.md": "77bf9dff38b2c9d4", "gsd-core/references/git-planning-commit.md": "f897a15ebfc3f5a7", + "gsd-core/references/gsd-run-resolver.md": "e71eb728b84641b1", "gsd-core/references/honest-verifier.md": "8815c9fc18c35719", "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", @@ -208,7 +209,7 @@ "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", "gsd-core/templates/phase-prompt.md": "b811bf951092df2f", "gsd-core/templates/planner-subagent-prompt.md": "ebf29dbb27042370", - "gsd-core/templates/project.md": "ab4af6becca2bb23", + "gsd-core/templates/project.md": "4f311fb1b05b823b", "gsd-core/templates/requirements.md": "a44de4c2f146e473", "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", @@ -261,7 +262,7 @@ "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", "gsd-core/workflows/discuss-phase/templates/context.md": "6cd929e989fe2b0f", "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "1bbd7703f11128e1", - "gsd-core/workflows/do.md": "8f460af710c8f6a4", + "gsd-core/workflows/do.md": "7512dd1892f118a1", "gsd-core/workflows/docs-update.md": "f35922d15b7061c9", "gsd-core/workflows/edit-phase.md": "966a3eadd1bebc04", "gsd-core/workflows/eval-review.md": "f898936e2cfe4130", @@ -278,10 +279,10 @@ "gsd-core/workflows/graduation.md": "47f1594c88c08501", "gsd-core/workflows/health.md": "107e3c72e76d9535", "gsd-core/workflows/help.md": "5d040504b9ab35e3", - "gsd-core/workflows/help/modes/brief.md": "5fe077fbbdb5d9f7", - "gsd-core/workflows/help/modes/default.md": "cc8ef97de634c995", - "gsd-core/workflows/help/modes/full.md": "94c18706768e5a41", - "gsd-core/workflows/help/modes/topic.md": "6762e41e3291ae24", + "gsd-core/workflows/help/modes/brief.md": "924860e1f07defb0", + "gsd-core/workflows/help/modes/default.md": "08a02976c0c5cc50", + "gsd-core/workflows/help/modes/full.md": "ee47582c5d8d94a7", + "gsd-core/workflows/help/modes/topic.md": "5c160093f3cbf35d", "gsd-core/workflows/import.md": "3d3fa603ceb8bc9f", "gsd-core/workflows/inbox.md": "437f981ef9ae7b26", "gsd-core/workflows/ingest-docs.md": "c859921c811ac11b", @@ -299,6 +300,7 @@ "gsd-core/workflows/next.md": "13fb800f2472d970", "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", "gsd-core/workflows/note.md": "5a99eb396c744619", + "gsd-core/workflows/onboard.md": "6f9e6c0b484271a9", "gsd-core/workflows/pause-work.md": "f2b33bba5593d422", "gsd-core/workflows/plan-milestone-gaps.md": "852f6d7c0c4299dc", "gsd-core/workflows/plan-phase.md": "2f16f3cc05fc59f1", @@ -381,7 +383,7 @@ "skills/gsd-inbox/SKILL.md": "955779a4b1df1c33", "skills/gsd-ingest-docs/SKILL.md": "6366644e623ae9e4", "skills/gsd-manager/SKILL.md": "8a11a1beb8e35a9c", - "skills/gsd-map-codebase/SKILL.md": "55dade835b0f4954", + "skills/gsd-map-codebase/SKILL.md": "73ab0afb2398de2c", "skills/gsd-mempalace-capture/SKILL.md": "64a2ec493092d26e", "skills/gsd-mempalace-recall/SKILL.md": "c6e0195e55cd934c", "skills/gsd-milestone-summary/SKILL.md": "3ea93ccaa0d4d967", @@ -392,9 +394,10 @@ "skills/gsd-ns-context/SKILL.md": "89f5bffe6702c0c5", "skills/gsd-ns-ideate/SKILL.md": "e0c0420f6878906a", "skills/gsd-ns-manage/SKILL.md": "b7fbe29e45e75f54", - "skills/gsd-ns-project/SKILL.md": "1292d4a6a4280ce9", + "skills/gsd-ns-project/SKILL.md": "fcb8a93ade9ecc72", "skills/gsd-ns-review/SKILL.md": "2ff62330379f947f", "skills/gsd-ns-workflow/SKILL.md": "86272fd655c206bc", + "skills/gsd-onboard/SKILL.md": "fd66b3c5b9c6a871", "skills/gsd-pause-work/SKILL.md": "95017c70ae9dca0d", "skills/gsd-phase/SKILL.md": "31578c329cc2583e", "skills/gsd-plan-phase/SKILL.md": "54798eddf30056b5", diff --git a/tests/fixtures/golden-install-parity/opencode.json b/tests/fixtures/golden-install-parity/opencode.json index ea9589877..90f251e7d 100644 --- a/tests/fixtures/golden-install-parity/opencode.json +++ b/tests/fixtures/golden-install-parity/opencode.json @@ -62,7 +62,7 @@ "command/gsd-inbox.md": "cc850bab897aed1f", "command/gsd-ingest-docs.md": "b47c812c247e58a4", "command/gsd-manager.md": "86ece154b34b6d1b", - "command/gsd-map-codebase.md": "1fb678f8a17a380e", + "command/gsd-map-codebase.md": "9aba6b4eed565912", "command/gsd-mempalace-capture.md": "a94ca275cbe7134c", "command/gsd-mempalace-recall.md": "d358cdd89c935877", "command/gsd-milestone-summary.md": "86a827271bc647c5", @@ -73,9 +73,10 @@ "command/gsd-ns-context.md": "9a2b55b64f2e1e4b", "command/gsd-ns-ideate.md": "27e7fcdc69eeeb5f", "command/gsd-ns-manage.md": "eded59052ca4b240", - "command/gsd-ns-project.md": "91417cf7b76581dd", + "command/gsd-ns-project.md": "c56395edb9bc7467", "command/gsd-ns-review.md": "61fe33e28eb1b961", "command/gsd-ns-workflow.md": "13c1ab91080c0cc3", + "command/gsd-onboard.md": "3aafaeb5d3941efe", "command/gsd-pause-work.md": "bb5bf91a2e3e480e", "command/gsd-phase.md": "6bcda1539f949d5a", "command/gsd-plan-phase.md": "7ee44086b59862b9", @@ -157,6 +158,7 @@ "gsd-core/references/gates.md": "7dc9fd3a3d6217c6", "gsd-core/references/git-integration.md": "fbdf814a3af9c051", "gsd-core/references/git-planning-commit.md": "f897a15ebfc3f5a7", + "gsd-core/references/gsd-run-resolver.md": "4e5af9905e4276e4", "gsd-core/references/honest-verifier.md": "b67482409f896a10", "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", @@ -242,7 +244,7 @@ "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", "gsd-core/templates/phase-prompt.md": "ee8880432b4d1566", "gsd-core/templates/planner-subagent-prompt.md": "6c9f1b23ee3dc05f", - "gsd-core/templates/project.md": "e4a3b331be081e62", + "gsd-core/templates/project.md": "fae14114f2b79b10", "gsd-core/templates/requirements.md": "a44de4c2f146e473", "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", @@ -295,7 +297,7 @@ "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", "gsd-core/workflows/discuss-phase/templates/context.md": "9804674fccada405", "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "04e4feee14772275", - "gsd-core/workflows/do.md": "d72e76d9050b53f3", + "gsd-core/workflows/do.md": "85c4c8cb7aa8af87", "gsd-core/workflows/docs-update.md": "850366c2ef8fb780", "gsd-core/workflows/edit-phase.md": "1876c855fb0a0a39", "gsd-core/workflows/eval-review.md": "5394694d29ad7543", @@ -312,10 +314,10 @@ "gsd-core/workflows/graduation.md": "13080b5c24eec27d", "gsd-core/workflows/health.md": "a91e0a8e5d20b2e9", "gsd-core/workflows/help.md": "5d040504b9ab35e3", - "gsd-core/workflows/help/modes/brief.md": "2e923b3ed635d495", - "gsd-core/workflows/help/modes/default.md": "b544113eb9aa54fa", - "gsd-core/workflows/help/modes/full.md": "604993c20f4e4b20", - "gsd-core/workflows/help/modes/topic.md": "19a279fe91922d3b", + "gsd-core/workflows/help/modes/brief.md": "fa2675516b40e2e3", + "gsd-core/workflows/help/modes/default.md": "be05e56b2c5ee2c0", + "gsd-core/workflows/help/modes/full.md": "35598c0ed5f7356f", + "gsd-core/workflows/help/modes/topic.md": "0bf9ab39d7044d69", "gsd-core/workflows/import.md": "67fbf389ab8e57b4", "gsd-core/workflows/inbox.md": "a073396097c89c01", "gsd-core/workflows/ingest-docs.md": "82370f93c45c8015", @@ -333,6 +335,7 @@ "gsd-core/workflows/next.md": "6719a37b8ce2ac4f", "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", "gsd-core/workflows/note.md": "0d1374f2a2257858", + "gsd-core/workflows/onboard.md": "102556e1715c01b9", "gsd-core/workflows/pause-work.md": "70c72beca55c080a", "gsd-core/workflows/plan-milestone-gaps.md": "0a9dacd422cd9533", "gsd-core/workflows/plan-phase.md": "3c49d9f4061b2388", @@ -439,7 +442,7 @@ "skills/gsd-inbox/SKILL.md": "3b2dd319d91dbab4", "skills/gsd-ingest-docs/SKILL.md": "8f294b4894f782a5", "skills/gsd-manager/SKILL.md": "cf40f237b4f20aa7", - "skills/gsd-map-codebase/SKILL.md": "6d74ea41e29ff035", + "skills/gsd-map-codebase/SKILL.md": "73f714297815f74c", "skills/gsd-mempalace-capture/SKILL.md": "f960b7b1a8fdf89b", "skills/gsd-mempalace-recall/SKILL.md": "2091c48e6e986e28", "skills/gsd-milestone-summary/SKILL.md": "175366bb500b5e64", @@ -450,9 +453,10 @@ "skills/gsd-ns-context/SKILL.md": "110fb2227bcde535", "skills/gsd-ns-ideate/SKILL.md": "d093d59a8519decc", "skills/gsd-ns-manage/SKILL.md": "2756981de613022e", - "skills/gsd-ns-project/SKILL.md": "757976d48e8b7a26", + "skills/gsd-ns-project/SKILL.md": "56d3d8a321d267f8", "skills/gsd-ns-review/SKILL.md": "680bdd33c882b049", "skills/gsd-ns-workflow/SKILL.md": "579b7f0dac74e1fb", + "skills/gsd-onboard/SKILL.md": "ea0b1217e5ecae23", "skills/gsd-pause-work/SKILL.md": "c7e9ba4f242c4648", "skills/gsd-phase/SKILL.md": "ee78c0c56c814d84", "skills/gsd-plan-phase/SKILL.md": "6abcc3a1568a6bb9", diff --git a/tests/fixtures/golden-install-parity/qwen.json b/tests/fixtures/golden-install-parity/qwen.json index bf36be0a3..21005fd74 100644 --- a/tests/fixtures/golden-install-parity/qwen.json +++ b/tests/fixtures/golden-install-parity/qwen.json @@ -87,6 +87,7 @@ "gsd-core/references/gates.md": "7dc9fd3a3d6217c6", "gsd-core/references/git-integration.md": "bd249d9024c39c0d", "gsd-core/references/git-planning-commit.md": "f897a15ebfc3f5a7", + "gsd-core/references/gsd-run-resolver.md": "10575c928ff9230d", "gsd-core/references/honest-verifier.md": "8815c9fc18c35719", "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", @@ -172,7 +173,7 @@ "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", "gsd-core/templates/phase-prompt.md": "213ccd947451ff2b", "gsd-core/templates/planner-subagent-prompt.md": "6c9f1b23ee3dc05f", - "gsd-core/templates/project.md": "1f687c7a88381080", + "gsd-core/templates/project.md": "ae1f68db042c2522", "gsd-core/templates/requirements.md": "a44de4c2f146e473", "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", @@ -225,7 +226,7 @@ "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", "gsd-core/workflows/discuss-phase/templates/context.md": "6cd929e989fe2b0f", "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "1bbd7703f11128e1", - "gsd-core/workflows/do.md": "35862ba1f7230247", + "gsd-core/workflows/do.md": "68f2607de614157d", "gsd-core/workflows/docs-update.md": "45d2f0d173c84e07", "gsd-core/workflows/edit-phase.md": "0fb5e0123cfc6f36", "gsd-core/workflows/eval-review.md": "6dee8a1e40ececd4", @@ -242,10 +243,10 @@ "gsd-core/workflows/graduation.md": "40401655435beee3", "gsd-core/workflows/health.md": "043de14edb6a9723", "gsd-core/workflows/help.md": "5d040504b9ab35e3", - "gsd-core/workflows/help/modes/brief.md": "2e923b3ed635d495", - "gsd-core/workflows/help/modes/default.md": "cef457f954a9991e", - "gsd-core/workflows/help/modes/full.md": "1e1e826ba1da0bc5", - "gsd-core/workflows/help/modes/topic.md": "899d7168a485297f", + "gsd-core/workflows/help/modes/brief.md": "fa2675516b40e2e3", + "gsd-core/workflows/help/modes/default.md": "7ca77077085452f5", + "gsd-core/workflows/help/modes/full.md": "00c1433a639f6ed8", + "gsd-core/workflows/help/modes/topic.md": "6e42db16f1568be9", "gsd-core/workflows/import.md": "e56c18a984396066", "gsd-core/workflows/inbox.md": "91aac6360e1a8672", "gsd-core/workflows/ingest-docs.md": "f291310a8a89dbd8", @@ -263,6 +264,7 @@ "gsd-core/workflows/next.md": "c13515a80c20d37d", "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", "gsd-core/workflows/note.md": "42b66686b2c102cb", + "gsd-core/workflows/onboard.md": "3c50ed1f1fd07619", "gsd-core/workflows/pause-work.md": "be33f84dc1d4822f", "gsd-core/workflows/plan-milestone-gaps.md": "d98e98486123eb97", "gsd-core/workflows/plan-phase.md": "1cac08591d361397", @@ -344,7 +346,7 @@ "skills/gsd-ns-context/skills/docs-update/SKILL.md": "3d41e81ec571de60", "skills/gsd-ns-context/skills/extract-learnings/SKILL.md": "8d38e55e5f8b774b", "skills/gsd-ns-context/skills/graphify/SKILL.md": "ac3661e6e576188b", - "skills/gsd-ns-context/skills/map-codebase/SKILL.md": "5009595dbde69739", + "skills/gsd-ns-context/skills/map-codebase/SKILL.md": "cf65e61890448285", "skills/gsd-ns-context/skills/mempalace-capture/SKILL.md": "40a31ad049374297", "skills/gsd-ns-context/skills/mempalace-recall/SKILL.md": "c3f412d5a64f3921", "skills/gsd-ns-ideate/SKILL.md": "4a0d2691054b23e5", @@ -372,7 +374,7 @@ "skills/gsd-ns-manage/skills/update/SKILL.md": "530b4206d729b56d", "skills/gsd-ns-manage/skills/workspace/SKILL.md": "047c3f4247bc869e", "skills/gsd-ns-manage/skills/workstreams/SKILL.md": "f4e54cb9b1ca0442", - "skills/gsd-ns-project/SKILL.md": "a58b3170197968be", + "skills/gsd-ns-project/SKILL.md": "5d7ec93b195555e7", "skills/gsd-ns-project/skills/audit-milestone/SKILL.md": "edb6a0cc6305d724", "skills/gsd-ns-project/skills/complete-milestone/SKILL.md": "f6799a5a713be7bb", "skills/gsd-ns-project/skills/import/SKILL.md": "88f83921a85e536b", @@ -380,6 +382,7 @@ "skills/gsd-ns-project/skills/milestone-summary/SKILL.md": "33d51a325d314f3a", "skills/gsd-ns-project/skills/new-milestone/SKILL.md": "ac99ffb8a966fe9d", "skills/gsd-ns-project/skills/new-project/SKILL.md": "9d5c27ebfa2c4746", + "skills/gsd-ns-project/skills/onboard/SKILL.md": "46460b479b7524bf", "skills/gsd-ns-project/skills/profile-user/SKILL.md": "78ca46045e85223f", "skills/gsd-ns-project/skills/review-backlog/SKILL.md": "1708aab6cb919223", "skills/gsd-ns-review/SKILL.md": "7badceb8627d8154", diff --git a/tests/fixtures/golden-install-parity/trae.json b/tests/fixtures/golden-install-parity/trae.json index c285005e2..05d1d85e7 100644 --- a/tests/fixtures/golden-install-parity/trae.json +++ b/tests/fixtures/golden-install-parity/trae.json @@ -87,6 +87,7 @@ "gsd-core/references/gates.md": "7dc9fd3a3d6217c6", "gsd-core/references/git-integration.md": "1bd40c3f94d712b1", "gsd-core/references/git-planning-commit.md": "f897a15ebfc3f5a7", + "gsd-core/references/gsd-run-resolver.md": "0534754c2758352a", "gsd-core/references/honest-verifier.md": "8815c9fc18c35719", "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", @@ -172,7 +173,7 @@ "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", "gsd-core/templates/phase-prompt.md": "213ccd947451ff2b", "gsd-core/templates/planner-subagent-prompt.md": "6c9f1b23ee3dc05f", - "gsd-core/templates/project.md": "1f687c7a88381080", + "gsd-core/templates/project.md": "ae1f68db042c2522", "gsd-core/templates/requirements.md": "a44de4c2f146e473", "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", @@ -225,7 +226,7 @@ "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", "gsd-core/workflows/discuss-phase/templates/context.md": "6cd929e989fe2b0f", "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "1bbd7703f11128e1", - "gsd-core/workflows/do.md": "f3328dbd4416f11a", + "gsd-core/workflows/do.md": "5131e8796ba9d99b", "gsd-core/workflows/docs-update.md": "f13571f08e083356", "gsd-core/workflows/edit-phase.md": "7facd0faa33c8cad", "gsd-core/workflows/eval-review.md": "37d545d4f0db4927", @@ -242,10 +243,10 @@ "gsd-core/workflows/graduation.md": "1ca877cda258a5de", "gsd-core/workflows/health.md": "1f9fd2deea45896f", "gsd-core/workflows/help.md": "08e1349950c5602a", - "gsd-core/workflows/help/modes/brief.md": "2e923b3ed635d495", - "gsd-core/workflows/help/modes/default.md": "1b3c315342701265", - "gsd-core/workflows/help/modes/full.md": "62c71f57f047999b", - "gsd-core/workflows/help/modes/topic.md": "229e3f3d85bda04b", + "gsd-core/workflows/help/modes/brief.md": "fa2675516b40e2e3", + "gsd-core/workflows/help/modes/default.md": "ed7368e0d1b8644a", + "gsd-core/workflows/help/modes/full.md": "b3287aa383806758", + "gsd-core/workflows/help/modes/topic.md": "8a5344e56fa64ab9", "gsd-core/workflows/import.md": "31af58468db15daf", "gsd-core/workflows/inbox.md": "e9ea37b2d46dc5b4", "gsd-core/workflows/ingest-docs.md": "fba176ad3cc22f5f", @@ -263,6 +264,7 @@ "gsd-core/workflows/next.md": "2163195861877de5", "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", "gsd-core/workflows/note.md": "acc9130fb1e94f0b", + "gsd-core/workflows/onboard.md": "61f111302af0f404", "gsd-core/workflows/pause-work.md": "c20d267e28ce92f0", "gsd-core/workflows/plan-milestone-gaps.md": "26db7b9329b7ddc8", "gsd-core/workflows/plan-phase.md": "fc7d25c0649e2fdf", @@ -322,7 +324,7 @@ "skills/gsd-ns-context/skills/docs-update/SKILL.md": "52755343585b987b", "skills/gsd-ns-context/skills/extract-learnings/SKILL.md": "d39269bea995fabc", "skills/gsd-ns-context/skills/graphify/SKILL.md": "e0253aef14693a7e", - "skills/gsd-ns-context/skills/map-codebase/SKILL.md": "0910348701b1fc65", + "skills/gsd-ns-context/skills/map-codebase/SKILL.md": "2982436d8652f172", "skills/gsd-ns-context/skills/mempalace-capture/SKILL.md": "36c486f14abe869a", "skills/gsd-ns-context/skills/mempalace-recall/SKILL.md": "2d95e385fee26dee", "skills/gsd-ns-ideate/SKILL.md": "c10342345c01c91f", @@ -350,7 +352,7 @@ "skills/gsd-ns-manage/skills/update/SKILL.md": "2fc47bf059aa7b38", "skills/gsd-ns-manage/skills/workspace/SKILL.md": "257d17b9d20274d8", "skills/gsd-ns-manage/skills/workstreams/SKILL.md": "737841783c7fdd4f", - "skills/gsd-ns-project/SKILL.md": "5668e3a5e1d8896d", + "skills/gsd-ns-project/SKILL.md": "fac77a9e770fd655", "skills/gsd-ns-project/skills/audit-milestone/SKILL.md": "0ccabc5556d65d56", "skills/gsd-ns-project/skills/complete-milestone/SKILL.md": "a69d534b385d6aaf", "skills/gsd-ns-project/skills/import/SKILL.md": "a11e630bfd8ae4de", @@ -358,6 +360,7 @@ "skills/gsd-ns-project/skills/milestone-summary/SKILL.md": "9d408f56712ba948", "skills/gsd-ns-project/skills/new-milestone/SKILL.md": "7cbc011130e8590c", "skills/gsd-ns-project/skills/new-project/SKILL.md": "ff0d57491df30624", + "skills/gsd-ns-project/skills/onboard/SKILL.md": "ae4c7b799d9ffb09", "skills/gsd-ns-project/skills/profile-user/SKILL.md": "4f526120cda2f6cc", "skills/gsd-ns-project/skills/review-backlog/SKILL.md": "d8a150558cc9326a", "skills/gsd-ns-review/SKILL.md": "c5afe33c212947dd", diff --git a/tests/fixtures/golden-install-parity/windsurf.json b/tests/fixtures/golden-install-parity/windsurf.json index 60941d862..8fc6899dc 100644 --- a/tests/fixtures/golden-install-parity/windsurf.json +++ b/tests/fixtures/golden-install-parity/windsurf.json @@ -87,6 +87,7 @@ "gsd-core/references/gates.md": "7dc9fd3a3d6217c6", "gsd-core/references/git-integration.md": "6ec36ea6b868655f", "gsd-core/references/git-planning-commit.md": "f897a15ebfc3f5a7", + "gsd-core/references/gsd-run-resolver.md": "1bb6a410d6ebfb33", "gsd-core/references/honest-verifier.md": "8815c9fc18c35719", "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", @@ -172,7 +173,7 @@ "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", "gsd-core/templates/phase-prompt.md": "213ccd947451ff2b", "gsd-core/templates/planner-subagent-prompt.md": "6c9f1b23ee3dc05f", - "gsd-core/templates/project.md": "1f687c7a88381080", + "gsd-core/templates/project.md": "ae1f68db042c2522", "gsd-core/templates/requirements.md": "a44de4c2f146e473", "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", @@ -225,7 +226,7 @@ "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", "gsd-core/workflows/discuss-phase/templates/context.md": "6cd929e989fe2b0f", "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "cd5d01c9ef84ab73", - "gsd-core/workflows/do.md": "a7ff800fdab468c7", + "gsd-core/workflows/do.md": "e2b848547e43c7a5", "gsd-core/workflows/docs-update.md": "70f73cc8c27e0ca0", "gsd-core/workflows/edit-phase.md": "c0ae7d0063f3e789", "gsd-core/workflows/eval-review.md": "b28be79ef29f16fd", @@ -242,10 +243,10 @@ "gsd-core/workflows/graduation.md": "a766039ff6ca653f", "gsd-core/workflows/health.md": "7b19d6e2c0357c3e", "gsd-core/workflows/help.md": "08e1349950c5602a", - "gsd-core/workflows/help/modes/brief.md": "2e923b3ed635d495", - "gsd-core/workflows/help/modes/default.md": "91509fe03bad9795", - "gsd-core/workflows/help/modes/full.md": "4c1a43f7095647e1", - "gsd-core/workflows/help/modes/topic.md": "177d351f7465787d", + "gsd-core/workflows/help/modes/brief.md": "fa2675516b40e2e3", + "gsd-core/workflows/help/modes/default.md": "6a253f1756f74e95", + "gsd-core/workflows/help/modes/full.md": "0cd464dcd077bbfc", + "gsd-core/workflows/help/modes/topic.md": "cee80e0adfa3b06c", "gsd-core/workflows/import.md": "029cacf530aca86b", "gsd-core/workflows/inbox.md": "797c287852eb8957", "gsd-core/workflows/ingest-docs.md": "78ba04ca39f28e8d", @@ -263,6 +264,7 @@ "gsd-core/workflows/next.md": "d48cea140a5153cb", "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", "gsd-core/workflows/note.md": "1c1e466c764e3deb", + "gsd-core/workflows/onboard.md": "20c28136423d40ac", "gsd-core/workflows/pause-work.md": "93fcc1c845da6396", "gsd-core/workflows/plan-milestone-gaps.md": "7880866ee1caf923", "gsd-core/workflows/plan-phase.md": "3e143f39514f8192", diff --git a/tests/fixtures/golden-install-parity/zcode.json b/tests/fixtures/golden-install-parity/zcode.json index 85e467636..290abf249 100644 --- a/tests/fixtures/golden-install-parity/zcode.json +++ b/tests/fixtures/golden-install-parity/zcode.json @@ -62,7 +62,7 @@ "commands/gsd-inbox.md": "da55c1408a6ee6cc", "commands/gsd-ingest-docs.md": "7a3c21ae5d5d133a", "commands/gsd-manager.md": "9f54653a7c589b00", - "commands/gsd-map-codebase.md": "8b605921868c03a3", + "commands/gsd-map-codebase.md": "709e9572953accc6", "commands/gsd-mempalace-capture.md": "5d4556e444acbb90", "commands/gsd-mempalace-recall.md": "5ac67fa4b7f2b03b", "commands/gsd-milestone-summary.md": "f8fa9c357c08b74b", @@ -73,9 +73,10 @@ "commands/gsd-ns-context.md": "011c44e7aa46e64a", "commands/gsd-ns-ideate.md": "edc5e543512dd48a", "commands/gsd-ns-manage.md": "0409d810e499357f", - "commands/gsd-ns-project.md": "8dfd1b9a2ffe86ac", + "commands/gsd-ns-project.md": "ff67e85bc6f7fc5a", "commands/gsd-ns-review.md": "3766ed10827882a0", "commands/gsd-ns-workflow.md": "c3b3c046a74ec0ee", + "commands/gsd-onboard.md": "a35340ce39334fc7", "commands/gsd-pause-work.md": "40a953fcddbedb5d", "commands/gsd-phase.md": "5dd3d40e3461a973", "commands/gsd-plan-phase.md": "2fb6cc9c4caa6a36", @@ -157,6 +158,7 @@ "gsd-core/references/gates.md": "bd79c7f90c8cb8d7", "gsd-core/references/git-integration.md": "77bf9dff38b2c9d4", "gsd-core/references/git-planning-commit.md": "f897a15ebfc3f5a7", + "gsd-core/references/gsd-run-resolver.md": "e71eb728b84641b1", "gsd-core/references/honest-verifier.md": "8815c9fc18c35719", "gsd-core/references/ios-scaffold.md": "5ef0cb7e0fac891f", "gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987", @@ -242,7 +244,7 @@ "gsd-core/templates/milestone.md": "74d2f750ae9f4a9c", "gsd-core/templates/phase-prompt.md": "b811bf951092df2f", "gsd-core/templates/planner-subagent-prompt.md": "ebf29dbb27042370", - "gsd-core/templates/project.md": "ab4af6becca2bb23", + "gsd-core/templates/project.md": "4f311fb1b05b823b", "gsd-core/templates/requirements.md": "a44de4c2f146e473", "gsd-core/templates/research-project/ARCHITECTURE.md": "746b9ef791d758b0", "gsd-core/templates/research-project/FEATURES.md": "f2b800de5df91b0f", @@ -295,7 +297,7 @@ "gsd-core/workflows/discuss-phase/templates/checkpoint.json": "e3bc3dca49db59eb", "gsd-core/workflows/discuss-phase/templates/context.md": "6cd929e989fe2b0f", "gsd-core/workflows/discuss-phase/templates/discussion-log.md": "1bbd7703f11128e1", - "gsd-core/workflows/do.md": "8f460af710c8f6a4", + "gsd-core/workflows/do.md": "7512dd1892f118a1", "gsd-core/workflows/docs-update.md": "f35922d15b7061c9", "gsd-core/workflows/edit-phase.md": "966a3eadd1bebc04", "gsd-core/workflows/eval-review.md": "f898936e2cfe4130", @@ -312,10 +314,10 @@ "gsd-core/workflows/graduation.md": "47f1594c88c08501", "gsd-core/workflows/health.md": "107e3c72e76d9535", "gsd-core/workflows/help.md": "5d040504b9ab35e3", - "gsd-core/workflows/help/modes/brief.md": "5fe077fbbdb5d9f7", - "gsd-core/workflows/help/modes/default.md": "cc8ef97de634c995", - "gsd-core/workflows/help/modes/full.md": "96abbac7f3f10e32", - "gsd-core/workflows/help/modes/topic.md": "6762e41e3291ae24", + "gsd-core/workflows/help/modes/brief.md": "924860e1f07defb0", + "gsd-core/workflows/help/modes/default.md": "08a02976c0c5cc50", + "gsd-core/workflows/help/modes/full.md": "895b35f264530d24", + "gsd-core/workflows/help/modes/topic.md": "5c160093f3cbf35d", "gsd-core/workflows/import.md": "3d3fa603ceb8bc9f", "gsd-core/workflows/inbox.md": "437f981ef9ae7b26", "gsd-core/workflows/ingest-docs.md": "c859921c811ac11b", @@ -333,6 +335,7 @@ "gsd-core/workflows/next.md": "13fb800f2472d970", "gsd-core/workflows/node-repair.md": "07a1628e5a1ff96b", "gsd-core/workflows/note.md": "5a99eb396c744619", + "gsd-core/workflows/onboard.md": "6f9e6c0b484271a9", "gsd-core/workflows/pause-work.md": "f2b33bba5593d422", "gsd-core/workflows/plan-milestone-gaps.md": "852f6d7c0c4299dc", "gsd-core/workflows/plan-phase.md": "a886ba9bdf4d0baf", @@ -414,7 +417,7 @@ "skills/gsd-ns-context/skills/docs-update/SKILL.md": "8fb602920a333d73", "skills/gsd-ns-context/skills/extract-learnings/SKILL.md": "6de7eeaaf4939e5d", "skills/gsd-ns-context/skills/graphify/SKILL.md": "d54c2b44e8059299", - "skills/gsd-ns-context/skills/map-codebase/SKILL.md": "ce7f2382e4086b68", + "skills/gsd-ns-context/skills/map-codebase/SKILL.md": "f48d48b43e2cc4bd", "skills/gsd-ns-context/skills/mempalace-capture/SKILL.md": "40a31ad049374297", "skills/gsd-ns-context/skills/mempalace-recall/SKILL.md": "c3f412d5a64f3921", "skills/gsd-ns-ideate/SKILL.md": "4a0d2691054b23e5", @@ -442,7 +445,7 @@ "skills/gsd-ns-manage/skills/update/SKILL.md": "01ca0efbdb8f6efa", "skills/gsd-ns-manage/skills/workspace/SKILL.md": "c6c07625a373e6a3", "skills/gsd-ns-manage/skills/workstreams/SKILL.md": "f4e54cb9b1ca0442", - "skills/gsd-ns-project/SKILL.md": "a58b3170197968be", + "skills/gsd-ns-project/SKILL.md": "5d7ec93b195555e7", "skills/gsd-ns-project/skills/audit-milestone/SKILL.md": "a6eb7edcfd23c7e4", "skills/gsd-ns-project/skills/complete-milestone/SKILL.md": "d7f6202222d1b26e", "skills/gsd-ns-project/skills/import/SKILL.md": "0a734021e0b86481", @@ -450,6 +453,7 @@ "skills/gsd-ns-project/skills/milestone-summary/SKILL.md": "c77f6c8ce7c57db9", "skills/gsd-ns-project/skills/new-milestone/SKILL.md": "3aad804c48d77474", "skills/gsd-ns-project/skills/new-project/SKILL.md": "e3cfd1fdbc2c3406", + "skills/gsd-ns-project/skills/onboard/SKILL.md": "84519552f7396347", "skills/gsd-ns-project/skills/profile-user/SKILL.md": "f57ad5e5c5899100", "skills/gsd-ns-project/skills/review-backlog/SKILL.md": "1708aab6cb919223", "skills/gsd-ns-review/SKILL.md": "7badceb8627d8154", diff --git a/tests/init.test.cjs b/tests/init.test.cjs index 964ce48f1..2ede0d0e8 100644 --- a/tests/init.test.cjs +++ b/tests/init.test.cjs @@ -1599,6 +1599,9 @@ describe('cmdInitNewProject', () => { test('brownfield with codebase map does not need map', () => { fs.writeFileSync(path.join(tmpDir, 'package.json'), '{"name":"test"}'); fs.mkdirSync(path.join(tmpDir, '.planning', 'codebase'), { recursive: true }); + for (const name of ['STACK', 'ARCHITECTURE', 'STRUCTURE', 'CONVENTIONS', 'TESTING', 'INTEGRATIONS', 'CONCERNS']) { + fs.writeFileSync(path.join(tmpDir, '.planning', 'codebase', `${name}.md`), `# ${name}\n`); + } const result = runGsdTools('init new-project', tmpDir); assert.ok(result.success, `Command failed: ${result.error}`); diff --git a/tests/onboard-command.test.cjs b/tests/onboard-command.test.cjs new file mode 100644 index 000000000..c60987a60 --- /dev/null +++ b/tests/onboard-command.test.cjs @@ -0,0 +1,483 @@ +// allow-test-rule: source-text-is-the-product (see #1990) +// Command/workflow markdown is deployed runtime product; source-text assertions +// below verify the installed command contract. CLI assertions exercise real +// gsd-tools behavior through the public command boundary. + +const { describe, test, beforeEach, afterEach } = require('node:test'); +const assert = require('node:assert/strict'); +const fs = require('fs'); +const path = require('path'); +const { runGsdTools, cleanup } = require('./helpers.cjs'); +const { createFixture } = require('./fixtures/index.cjs'); + +const ROOT = path.join(__dirname, '..'); +const CMD_PATH = path.join(ROOT, 'commands', 'gsd', 'onboard.md'); +const WF_PATH = path.join(ROOT, 'gsd-core', 'workflows', 'onboard.md'); + +describe('init onboard public CLI projection', () => { + let tmpDir; + + beforeEach(() => { + tmpDir = createFixture({ planning: false, projectDoc: false }); + }); + + afterEach(() => { + cleanup(tmpDir); + }); + + test('reports brownfield code, docs, and missing planning state', () => { + fs.mkdirSync(path.join(tmpDir, 'src'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, 'src', 'server.ts'), 'export const server = true;\n'); + fs.mkdirSync(path.join(tmpDir, 'docs', 'adr'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, 'docs', 'adr', '0001-runtime.md'), '# ADR: Runtime\n'); + + const result = runGsdTools('init onboard --raw', tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + + const parsed = JSON.parse(result.output); + assert.strictEqual(parsed.planning_exists, false); + assert.strictEqual(parsed.project_exists, false); + assert.strictEqual(parsed.has_existing_code, true); + assert.strictEqual(parsed.has_codebase_map, false); + assert.strictEqual(parsed.has_docs_candidates, true); + assert.strictEqual(parsed.doc_candidate_count, 1); + assert.deepStrictEqual(parsed.codebase_map_files_present, []); + assert.ok(parsed.doc_candidates.includes('docs/adr/0001-runtime.md')); + for (const file of ['STACK.md', 'ARCHITECTURE.md', 'STRUCTURE.md', 'CONVENTIONS.md', 'TESTING.md', 'INTEGRATIONS.md', 'CONCERNS.md']) { + assert.ok(parsed.missing_codebase_map_files.includes(file), `missing map files should include ${file}`); + } + assert.strictEqual(parsed.onboarding_summary_exists, false); + assert.strictEqual(parsed.text_mode, false); + }); + + test('detects planning docs in top-level ADR, PRD, and RFC folders', () => { + fs.mkdirSync(path.join(tmpDir, 'prd'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, 'prd', 'product.md'), '# Product Requirements\n'); + fs.mkdirSync(path.join(tmpDir, 'adr'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, 'adr', 'decision.md'), '# Architecture Decision\n'); + fs.mkdirSync(path.join(tmpDir, 'rfc'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, 'rfc', 'proposal.md'), '# Request for Comments\n'); + + const result = runGsdTools('init onboard --raw', tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + + const parsed = JSON.parse(result.output); + assert.strictEqual(parsed.has_docs_candidates, true); + assert.strictEqual(parsed.doc_candidate_count, 3); + assert.deepStrictEqual(parsed.doc_candidates, [ + 'adr/decision.md', + 'prd/product.md', + 'rfc/proposal.md', + ]); + }); + + test('detects root-level planning docs without broad repo scan', () => { + fs.writeFileSync(path.join(tmpDir, 'PRD.md'), '# Product Requirements\n'); + fs.writeFileSync(path.join(tmpDir, 'SPEC.md'), '# Specification\n'); + fs.writeFileSync(path.join(tmpDir, 'RFC.md'), '# Request for Comments\n'); + fs.writeFileSync(path.join(tmpDir, 'ADR.md'), '# Architecture Decision\n'); + fs.writeFileSync(path.join(tmpDir, 'REQUIREMENTS.md'), '# Requirements\n'); + fs.writeFileSync(path.join(tmpDir, '0001-decision.md'), '# Decision\n'); + fs.mkdirSync(path.join(tmpDir, 'src'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, 'src', 'PRD.md'), '# Nested Product Requirements\n'); + + const result = runGsdTools('init onboard --raw', tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + + const parsed = JSON.parse(result.output); + assert.strictEqual(parsed.has_docs_candidates, true); + assert.strictEqual(parsed.doc_candidate_count, 6); + assert.deepStrictEqual(parsed.doc_candidates, [ + '0001-decision.md', + 'ADR.md', + 'PRD.md', + 'REQUIREMENTS.md', + 'RFC.md', + 'SPEC.md', + ]); + }); + + test('forwards the --text flag into the public projection', () => { + const result = runGsdTools(['init', 'onboard', '--text', '--raw'], tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + + const parsed = JSON.parse(result.output); + assert.strictEqual(parsed.text_mode, true); + }); + + test('reports complete codebase map and onboarding summary in existing planning', () => { + fs.mkdirSync(path.join(tmpDir, '.planning', 'codebase'), { recursive: true }); + for (const name of ['STACK', 'ARCHITECTURE', 'STRUCTURE', 'CONVENTIONS', 'TESTING', 'INTEGRATIONS', 'CONCERNS']) { + fs.writeFileSync(path.join(tmpDir, '.planning', 'codebase', `${name}.md`), `# ${name}\n`); + } + fs.mkdirSync(path.join(tmpDir, '.planning', 'onboarding'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, '.planning', 'onboarding', 'SUMMARY.md'), '# Onboarding Summary\n'); + fs.writeFileSync(path.join(tmpDir, '.planning', 'PROJECT.md'), '# Project\n'); + fs.writeFileSync(path.join(tmpDir, '.planning', 'REQUIREMENTS.md'), '# Requirements\n'); + fs.writeFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), '# Roadmap\n'); + fs.writeFileSync(path.join(tmpDir, '.planning', 'STATE.md'), '# State\n'); + fs.writeFileSync(path.join(tmpDir, '.planning', 'config.json'), JSON.stringify({ workflow: { text_mode: true } })); + + const trackedFiles = [ + path.join(tmpDir, '.planning', 'PROJECT.md'), + path.join(tmpDir, '.planning', 'ROADMAP.md'), + path.join(tmpDir, '.planning', 'STATE.md'), + path.join(tmpDir, '.planning', 'onboarding', 'SUMMARY.md'), + ]; + const before = new Map(trackedFiles.map(file => [file, fs.readFileSync(file, 'utf8')])); + + const result = runGsdTools('init onboard --raw', tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + + for (const file of trackedFiles) { + assert.strictEqual(fs.readFileSync(file, 'utf8'), before.get(file), `${path.basename(file)} must not be mutated by init onboard`); + } + + const parsed = JSON.parse(result.output); + assert.strictEqual(parsed.planning_exists, true); + assert.strictEqual(parsed.project_exists, true); + assert.strictEqual(parsed.requirements_exists, true); + assert.strictEqual(parsed.roadmap_exists, true); + assert.strictEqual(parsed.state_exists, true); + assert.strictEqual(parsed.has_codebase_map, true); + assert.deepStrictEqual(parsed.missing_codebase_map_files, []); + assert.strictEqual(parsed.onboarding_summary_exists, true); + assert.strictEqual(parsed.onboarding_summary_path, '.planning/onboarding/SUMMARY.md'); + assert.strictEqual(parsed.text_mode, true); + }); + + test('reports fast codebase map readiness and a complete-map handoff before new-project', () => { + fs.mkdirSync(path.join(tmpDir, '.planning', 'codebase'), { recursive: true }); + for (const name of ['STACK', 'INTEGRATIONS', 'ARCHITECTURE', 'STRUCTURE']) { + fs.writeFileSync(path.join(tmpDir, '.planning', 'codebase', `${name}.md`), `# ${name}\n`); + } + fs.writeFileSync(path.join(tmpDir, 'package.json'), '{"name":"fixture"}\n'); + + const result = runGsdTools(['init', 'onboard', '--fast', '--raw'], tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + + const parsed = JSON.parse(result.output); + assert.strictEqual(parsed.map_readiness, 'fast'); + assert.strictEqual(parsed.has_codebase_map, false); + assert.strictEqual(parsed.has_fast_codebase_map, true); + assert.strictEqual(parsed.needs_codebase_map, true); + assert.strictEqual(parsed.needs_fast_codebase_map, false); + assert.strictEqual(parsed.next_action.kind, 'complete-map-before-new-project'); + assert.strictEqual(parsed.next_action.command, '/gsd-map-codebase'); + assert.match(parsed.next_action.reason, /complete codebase map/i); + assert.deepStrictEqual(parsed.fast_codebase_map_files_required, [ + 'STACK.md', + 'INTEGRATIONS.md', + 'ARCHITECTURE.md', + 'STRUCTURE.md', + ]); + assert.deepStrictEqual(parsed.missing_fast_codebase_map_files, []); + }); + + test('routes fast mapped repositories with planning docs to complete map before ingest', () => { + fs.mkdirSync(path.join(tmpDir, '.planning', 'codebase'), { recursive: true }); + for (const name of ['STACK', 'INTEGRATIONS', 'ARCHITECTURE', 'STRUCTURE']) { + fs.writeFileSync(path.join(tmpDir, '.planning', 'codebase', `${name}.md`), `# ${name}\n`); + } + fs.writeFileSync(path.join(tmpDir, 'package.json'), '{"name":"fixture"}\n'); + fs.mkdirSync(path.join(tmpDir, 'docs', 'adr'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, 'docs', 'adr', '0001-runtime.md'), '# ADR: Runtime\n'); + + const result = runGsdTools(['init', 'onboard', '--fast', '--raw'], tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + + const parsed = JSON.parse(result.output); + assert.strictEqual(parsed.next_action.kind, 'complete-map-before-new-project'); + assert.strictEqual(parsed.next_action.command, '/gsd-map-codebase'); + }); + + test('routes planning artifacts without PROJECT.md to partial planning', () => { + fs.mkdirSync(path.join(tmpDir, '.planning'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, '.planning', 'REQUIREMENTS.md'), '# Requirements\n'); + fs.writeFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), '# Roadmap\n'); + fs.writeFileSync(path.join(tmpDir, '.planning', 'STATE.md'), '# State\n'); + + const result = runGsdTools('init onboard --raw', tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + + const parsed = JSON.parse(result.output); + assert.strictEqual(parsed.next_action.kind, 'partial-planning'); + assert.deepStrictEqual(parsed.next_action.missing, ['PROJECT.md']); + }); + + test('fast mode leaves a fully set-up project at write-summary instead of the complete-map gate (regression #1990: fast map gate misroute)', () => { + fs.mkdirSync(path.join(tmpDir, '.planning', 'codebase'), { recursive: true }); + for (const name of ['STACK', 'INTEGRATIONS', 'ARCHITECTURE', 'STRUCTURE']) { + fs.writeFileSync(path.join(tmpDir, '.planning', 'codebase', `${name}.md`), `# ${name}\n`); + } + fs.writeFileSync(path.join(tmpDir, 'package.json'), '{"name":"fixture"}\n'); + for (const name of ['PROJECT', 'REQUIREMENTS', 'ROADMAP', 'STATE']) { + fs.writeFileSync(path.join(tmpDir, '.planning', `${name}.md`), `# ${name}\n`); + } + + const result = runGsdTools(['init', 'onboard', '--fast', '--raw'], tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + + const parsed = JSON.parse(result.output); + assert.strictEqual(parsed.map_readiness, 'fast'); + assert.strictEqual(parsed.project_exists, true); + // Once project setup is complete, a fast map must not misroute back to the + // pre-new-project complete-map handoff; onboarding advances to the summary. + assert.strictEqual(parsed.next_action.kind, 'write-summary'); + assert.strictEqual(parsed.next_action.summary_path, '.planning/onboarding/SUMMARY.md'); + }); + + test('fast mode routes incomplete planning to partial-planning before the complete-map gate (regression #1990: fast map gate misroute)', () => { + fs.mkdirSync(path.join(tmpDir, '.planning', 'codebase'), { recursive: true }); + for (const name of ['STACK', 'INTEGRATIONS', 'ARCHITECTURE', 'STRUCTURE']) { + fs.writeFileSync(path.join(tmpDir, '.planning', 'codebase', `${name}.md`), `# ${name}\n`); + } + fs.writeFileSync(path.join(tmpDir, 'package.json'), '{"name":"fixture"}\n'); + fs.writeFileSync(path.join(tmpDir, '.planning', 'PROJECT.md'), '# Project\n'); + fs.writeFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), '# Roadmap\n'); + fs.writeFileSync(path.join(tmpDir, '.planning', 'STATE.md'), '# State\n'); + + const result = runGsdTools(['init', 'onboard', '--fast', '--raw'], tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + + const parsed = JSON.parse(result.output); + assert.strictEqual(parsed.map_readiness, 'fast'); + // Incomplete planning must surface before the fast-map complete-map handoff. + assert.strictEqual(parsed.next_action.kind, 'partial-planning'); + assert.deepStrictEqual(parsed.next_action.missing, ['REQUIREMENTS.md']); + }); + + test('projects the next action for code, docs, greenfield, partial planning, and summary states', () => { + fs.mkdirSync(path.join(tmpDir, 'src'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, 'src', 'server.ts'), 'export const server = true;\n'); + let result = runGsdTools('init onboard --raw', tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + assert.deepStrictEqual(JSON.parse(result.output).next_action, { + kind: 'map-codebase', + command: '/gsd-map-codebase', + reason: 'Existing code was detected, but the required .planning/codebase/ map is missing.', + }); + + cleanup(tmpDir); + tmpDir = createFixture({ planning: false, projectDoc: false }); + fs.mkdirSync(path.join(tmpDir, 'docs', 'adr'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, 'docs', 'adr', '0001-runtime.md'), '# ADR: Runtime\n'); + result = runGsdTools('init onboard --raw', tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + assert.deepStrictEqual(JSON.parse(result.output).next_action, { + kind: 'ingest-docs', + command: '/gsd-ingest-docs', + reason: 'Detected existing ADR/PRD/SPEC/RFC document(s) before project setup.', + }); + + cleanup(tmpDir); + tmpDir = createFixture({ planning: false, projectDoc: false }); + result = runGsdTools('init onboard --raw', tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + assert.deepStrictEqual(JSON.parse(result.output).next_action, { + kind: 'new-project', + command: '/gsd-new-project', + reason: 'No existing code or planning docs were detected.', + }); + + cleanup(tmpDir); + tmpDir = createFixture({ planning: false, projectDoc: false }); + fs.mkdirSync(path.join(tmpDir, '.planning'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, '.planning', 'PROJECT.md'), '# Project\n'); + fs.writeFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), '# Roadmap\n'); + fs.writeFileSync(path.join(tmpDir, '.planning', 'STATE.md'), '# State\n'); + result = runGsdTools('init onboard --raw', tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + const partial = JSON.parse(result.output); + assert.strictEqual(partial.next_action.kind, 'partial-planning'); + assert.deepStrictEqual(partial.next_action.missing, ['REQUIREMENTS.md']); + + fs.mkdirSync(path.join(tmpDir, '.planning', 'codebase'), { recursive: true }); + for (const name of ['STACK', 'ARCHITECTURE', 'STRUCTURE', 'CONVENTIONS', 'TESTING', 'INTEGRATIONS', 'CONCERNS']) { + fs.writeFileSync(path.join(tmpDir, '.planning', 'codebase', `${name}.md`), `# ${name}\n`); + } + fs.writeFileSync(path.join(tmpDir, '.planning', 'REQUIREMENTS.md'), '# Requirements\n'); + result = runGsdTools('init onboard --raw', tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + assert.deepStrictEqual(JSON.parse(result.output).next_action, { + kind: 'write-summary', + summary_path: '.planning/onboarding/SUMMARY.md', + reason: 'Onboarding summary is missing.', + }); + + fs.mkdirSync(path.join(tmpDir, '.planning', 'onboarding'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, '.planning', 'onboarding', 'SUMMARY.md'), '# Onboarding Summary\n'); + result = runGsdTools('init onboard --raw', tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + assert.deepStrictEqual(JSON.parse(result.output).next_action, { + kind: 'ready', + reason: 'Onboarding summary already exists.', + }); + }); + + test('reports missing requirements in otherwise existing planning', () => { + fs.mkdirSync(path.join(tmpDir, '.planning'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, '.planning', 'PROJECT.md'), '# Project\n'); + fs.writeFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), '# Roadmap\n'); + fs.writeFileSync(path.join(tmpDir, '.planning', 'STATE.md'), '# State\n'); + + const result = runGsdTools('init onboard --raw', tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + + const parsed = JSON.parse(result.output); + assert.strictEqual(parsed.project_exists, true); + assert.strictEqual(parsed.requirements_exists, false); + assert.strictEqual(parsed.roadmap_exists, true); + assert.strictEqual(parsed.state_exists, true); + }); + + test('ignores generated and vendor directories when detecting existing code', () => { + fs.mkdirSync(path.join(tmpDir, 'node_modules', 'pkg'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, 'node_modules', 'pkg', 'index.ts'), 'export const ignored = true;\n'); + fs.mkdirSync(path.join(tmpDir, 'dist'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir, 'dist', 'bundle.js'), 'console.log("ignored");\n'); + + const result = runGsdTools('init onboard --raw', tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + + const parsed = JSON.parse(result.output); + assert.strictEqual(parsed.has_existing_code, false); + assert.strictEqual(parsed.has_package_file, false); + assert.strictEqual(parsed.is_brownfield, false); + assert.strictEqual(parsed.needs_codebase_map, false); + }); + + test('treats package manifests as brownfield even without source files', () => { + fs.writeFileSync(path.join(tmpDir, 'package.json'), '{"name":"fixture"}\n'); + + const result = runGsdTools('init onboard --raw', tmpDir, { HOME: tmpDir }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + + const parsed = JSON.parse(result.output); + assert.strictEqual(parsed.has_existing_code, false); + assert.strictEqual(parsed.has_package_file, true); + assert.strictEqual(parsed.is_brownfield, true); + assert.strictEqual(parsed.needs_codebase_map, true); + }); + + + test('formats onboard handoff commands for the resolved runtime', () => { + fs.writeFileSync(path.join(tmpDir, 'package.json'), '{"name":"fixture"}\n'); + + const result = runGsdTools(['init', 'onboard', '--raw'], tmpDir, { + HOME: tmpDir, + GSD_RUNTIME: 'codex', + }); + assert.ok(result.success, `init onboard should succeed: ${result.error}`); + + const parsed = JSON.parse(result.output); + assert.strictEqual(parsed.next_action.kind, 'map-codebase'); + assert.strictEqual(parsed.next_action.command, '$gsd-map-codebase'); + assert.deepStrictEqual(parsed.handoff_commands, { + map_codebase: '$gsd-map-codebase', + map_codebase_fast: '$gsd-map-codebase --fast', + ingest_docs: '$gsd-ingest-docs', + manager: '$gsd-manager', + new_project: '$gsd-new-project', + onboard: '$gsd-onboard', + }); + }); + + test('dotted query init.onboard matches direct init onboard', () => { + fs.writeFileSync(path.join(tmpDir, 'package.json'), '{"name":"fixture"}\n'); + + const direct = runGsdTools(['init', 'onboard', '--raw'], tmpDir, { HOME: tmpDir }); + const query = runGsdTools(['query', 'init.onboard', '--raw'], tmpDir, { HOME: tmpDir }); + assert.equal(direct.success, true, direct.error || direct.output); + assert.equal(query.success, true, query.error || query.output); + assert.deepStrictEqual(JSON.parse(query.output), JSON.parse(direct.output)); + }); + +}); + +describe('/gsd:onboard command contract', () => { + test('command file declares the onboard command and loads its workflow', () => { + const content = fs.readFileSync(CMD_PATH, 'utf8'); + assert.match(content, /^name:\s*gsd:onboard$/m); + assert.match(content, /^description:\s*.*(?:existing codebase|brownfield|onboard).*$/mi); + assert.match(content, /^\s*- AskUserQuestion$/m); + assert.match(content, /^\s*- Agent$/m); + assert.ok(content.includes('@~/.claude/gsd-core/workflows/onboard.md')); + assert.ok(content.includes('@~/.claude/gsd-core/references/ui-brand.md')); + assert.ok(content.includes('@~/.claude/gsd-core/references/gate-prompts.md')); + }); + + test('workflow renders the init projection without owning the route state machine', () => { + const content = fs.readFileSync(WF_PATH, 'utf8'); + + assert.ok(content.includes('@~/.claude/gsd-core/references/gsd-run-resolver.md')); + assert.ok( + !content.includes('_GSD_SHIM_NAME="gsd-tools.cjs"'), + 'workflow must reference the shared resolver instead of inlining it', + ); + assert.match(content, /init onboard --fast --raw/); + assert.match(content, /init onboard --raw/); + assert.match(content, /next_action\.kind/); + assert.match(content, /map_readiness/); + assert.match(content, /codebase_map_summary_status/); + assert.match(content, /ONBOARDING_ROOT=\{git_worktree_root \|\| _GSD_RUNTIME_ROOT\}/); + + for (const action of [ + 'map-codebase', + 'ingest-docs', + 'complete-map-before-new-project', + 'new-project', + 'partial-planning', + 'write-summary', + 'ready', + ]) { + assert.ok(content.includes(`next_action.kind == "${action}"`), `workflow must render ${action}`); + } + + assert.ok(content.includes('AskUserQuestion'), 'workflow must still support interactive choices'); + assert.ok(content.includes('--text'), 'workflow must document text-mode fallback'); + assert.ok( + content.includes('Exit. If the user skips mapping:'), + 'skip mapping must hand off explicitly instead of falling through to summary creation', + ); + const partialPlanningSkipGuard = + 'If `(project_exists || requirements_exists || roadmap_exists || state_exists) && (!project_exists || !requirements_exists || !roadmap_exists || !state_exists)`, route the skip to the partial planning guard instead:'; + const docsIngestSkipGuard = + 'If `has_docs_candidates && !project_exists`, route the skip to docs ingest instead:'; + assert.ok( + content.includes(partialPlanningSkipGuard), + 'skip mapping must preserve the partial-planning guard when incomplete planning artifacts are present', + ); + assert.ok( + content.includes(docsIngestSkipGuard), + 'skip mapping must preserve the docs-ingest gate when planning docs are present', + ); + assert.ok( + content.indexOf(partialPlanningSkipGuard) < content.indexOf(docsIngestSkipGuard), + 'skip mapping must check partial planning before docs ingest', + ); + assert.ok( + content.includes('{handoff_commands.ingest_docs}'), + 'skip mapping docs-preserving handoff must use the projected docs ingest command', + ); + assert.ok( + content.includes('Skipping codebase mapping may give {handoff_commands.new_project} weaker context.'), + 'skip mapping must warn about weaker context', + ); + assert.ok( + content.includes('Exit. If the user skips docs ingest, print:'), + 'skip docs ingest must hand off explicitly instead of falling through to summary creation', + ); + assert.ok( + content.includes('Skipping docs ingest may omit existing ADR/PRD/SPEC/RFC context from {handoff_commands.new_project}.'), + 'skip docs ingest must warn about omitted docs context', + ); + assert.match(content, /do not overwrite/i, 'workflow must protect existing summary/planning'); + assert.match(content, /query commit "docs: create onboarding summary" --files \.planning\/onboarding\/SUMMARY\.md/); + assert.ok(!content.includes('execute-phase'), 'onboarding must not execute implementation phases'); + assert.ok(!content.includes('gsd:ship'), 'onboarding must not ship work'); + assert.ok(content.includes('Next recommended command: {handoff_commands.manager}')); + assert.ok(!content.includes('/gsd:ingest-docs'), 'skip handoffs must not hard-code legacy ingest command'); + assert.ok(!content.includes('/gsd:new-project'), 'skip handoffs must not hard-code legacy new-project command'); + }); +}); diff --git a/tests/runtime-artifact-layout-install-profiles.test.cjs b/tests/runtime-artifact-layout-install-profiles.test.cjs index ed94af736..6361ec939 100644 --- a/tests/runtime-artifact-layout-install-profiles.test.cjs +++ b/tests/runtime-artifact-layout-install-profiles.test.cjs @@ -380,6 +380,14 @@ describe('resolveProfile', () => { } }); + test('standard profile includes the onboard manager handoff dependency', () => { + const manifest = loadSkillsManifest(REAL_COMMANDS_DIR); + const result = resolveProfile({ modes: ['standard'], manifest }); + assert.ok(result.skills instanceof Set); + assert.ok(result.skills.has('onboard'), 'standard profile should include onboard'); + assert.ok(result.skills.has('manager'), 'onboard handoff must install gsd-manager'); + }); + test('resolves full profile — returns sentinel', () => { const manifest = loadSkillsManifest(REAL_COMMANDS_DIR); const result = resolveProfile({ modes: ['full'], manifest }); diff --git a/tests/runtime-launcher-parity.test.cjs b/tests/runtime-launcher-parity.test.cjs index 8fada64b1..2f2448b7c 100644 --- a/tests/runtime-launcher-parity.test.cjs +++ b/tests/runtime-launcher-parity.test.cjs @@ -136,6 +136,22 @@ function collectAgentFiles() { return results; } +/** + * A workflow/agent file "delegates to the shared resolver" when it pulls the + * canonical gsd_run preamble in from gsd-core/references/gsd-run-resolver.md via + * an @-include instead of inlining the snippet (see onboard.md / issue #1990). + * + * Such files are exempt from the inline-preamble parity checks (B / G / H and the + * runtime-home propagation checks): they intentionally do NOT inline the preamble + * — onboard-command.test.cjs even asserts the absence of the inline form. Their + * resolver correctness is guaranteed transitively by: + * (1) onboard-command.test.cjs asserting the @-include is present, and + * (2) the "resolver reference stays byte-equal to the snippet" guard (B2) below. + */ +function delegatesToResolverReference(content) { + return content.includes('references/gsd-run-resolver.md'); +} + describe('runtime-launcher-parity (#373)', () => { // ─── (A) No retired GSD_SDK token ──────────────────────────────────────── test('(A) no GSD_SDK token in any workflow .md file', () => { @@ -170,6 +186,9 @@ describe('runtime-launcher-parity (#373)', () => { for (const f of files) { const rel = path.relative(WORKFLOWS_DIR, f); const content = fs.readFileSync(f, 'utf8'); + // Files that delegate to the shared resolver reference (@-include) do not + // inline the preamble — exempt them (see delegatesToResolverReference / (B2)). + if (delegatesToResolverReference(content)) continue; const blocks = extractShellBlocks(content); // Collect all block lines in document order for flat analysis @@ -226,6 +245,30 @@ describe('runtime-launcher-parity (#373)', () => { ); }); + // ─── (B2) Shared resolver reference stays byte-equal to the snippet ─────── + // Workflows may delegate to gsd-core/references/gsd-run-resolver.md instead of + // inlining the preamble (see delegatesToResolverReference). That delegation is + // only safe if the reference's bash block is byte-equal to the canonical + // snippet — otherwise a delegating workflow (e.g. onboard.md) would silently + // ship a drifted resolver. This guard replaces the inline-preamble checks for + // those files. + test('(B2) references/gsd-run-resolver.md preamble is byte-equal to the canonical snippet', () => { + const preambleStr = expectedPreamble().join('\n'); + const refPath = path.join(__dirname, '..', 'gsd-core', 'references', 'gsd-run-resolver.md'); + const refContent = fs.readFileSync(refPath, 'utf8'); + const refPreamble = extractShellBlocks(refContent) + .map((b) => b.lines.join('\n')) + .join('\n') + .trim(); + assert.equal( + refPreamble, + preambleStr, + 'gsd-core/references/gsd-run-resolver.md must contain the canonical gsd_run preamble ' + + 'byte-equal to _runtime-launcher.snippet.sh. Re-copy the snippet into the reference so ' + + 'workflows that delegate to it via @-include ship the current resolver.', + ); + }); + // ─── (C) Space-safe behavioral test ────────────────────────────────────── test('(C) gsd_run works with a RUNTIME_DIR path containing spaces', () => { // Create temp dir whose path contains a space @@ -402,6 +445,7 @@ describe('runtime-launcher-parity (#373)', () => { const content = fs.readFileSync(f, 'utf8'); const blocks = extractShellBlocks(content); const allBlockLines = blocks.flatMap((b) => b.lines); + if (delegatesToResolverReference(content)) continue; const fileHasGsdRun = allBlockLines.some((l) => /\bgsd_run\b/.test(l)); if (!fileHasGsdRun) continue; const allContent = allBlockLines.join('\n'); @@ -433,6 +477,7 @@ describe('runtime-launcher-parity (#373)', () => { const content = fs.readFileSync(f, 'utf8'); const blocks = extractShellBlocks(content); const allBlockLines = blocks.flatMap((b) => b.lines); + if (delegatesToResolverReference(content)) continue; const fileHasGsdRun = allBlockLines.some((l) => /\bgsd_run\b/.test(l)); if (!fileHasGsdRun) continue; if (!allBlockLines.join('\n').includes(CODEX_HOME_PROBE)) { @@ -1346,6 +1391,7 @@ describe('bug-891: non-Claude runtime home fallback arms', () => { const content = fs.readFileSync(f, 'utf8'); const blocks = extractShellBlocks(content); const allBlockLines = blocks.flatMap((b) => b.lines); + if (delegatesToResolverReference(content)) continue; const fileHasGsdRun = allBlockLines.some((l) => /\bgsd_run\b/.test(l)); if (!fileHasGsdRun) continue; const allContent = allBlockLines.join('\n'); diff --git a/tests/skill-frontmatter-contract.test.cjs b/tests/skill-frontmatter-contract.test.cjs index 7e8151c87..7aa9a0458 100644 --- a/tests/skill-frontmatter-contract.test.cjs +++ b/tests/skill-frontmatter-contract.test.cjs @@ -476,6 +476,8 @@ const KNOWN_SKILLS = new Set([ 'mvp-phase.md', 'new-milestone.md', 'new-project.md', + // #1990 brownfield onboarding entry command; sibling of new-project, routed under ns-project. + 'onboard.md', // `next.md` was legitimately reclaimed (#1787): the old workflow-advance // command stays absorbed into `progress.md --next`, while the current // `/gsd:next` is a different state-aware smart-entry launcher. diff --git a/tests/workflow-size-baseline.json b/tests/workflow-size-baseline.json index 29fcbfed7..04b3e88bd 100644 --- a/tests/workflow-size-baseline.json +++ b/tests/workflow-size-baseline.json @@ -20,7 +20,7 @@ "discuss-phase-assumptions.md": 27028, "discuss-phase-power.md": 11273, "discuss-phase.md": 31986, - "do.md": 10112, + "do.md": 10353, "docs-update.md": 55706, "edit-phase.md": 12927, "eval-review.md": 9967, @@ -50,6 +50,7 @@ "next.md": 20138, "node-repair.md": 4173, "note.md": 6563, + "onboard.md": 8590, "pause-work.md": 14441, "plan-milestone-gaps.md": 11809, "plan-phase.md": 90455,