feat: add /gsd:analyze-dependencies command to detect phase dependencies (#1607)
Analyzes ROADMAP.md phases for file overlap and semantic dependencies, then suggests Depends on entries before running /gsd:manager. Complements the files_modified overlap detection added in the executor (PR #1600). Closes #1530
This commit is contained in:
34
commands/gsd/analyze-dependencies.md
Normal file
34
commands/gsd/analyze-dependencies.md
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
name: gsd:analyze-dependencies
|
||||
description: Analyze phase dependencies and suggest Depends on entries for ROADMAP.md
|
||||
allowed-tools:
|
||||
- Read
|
||||
- Write
|
||||
- Bash
|
||||
- Glob
|
||||
- Grep
|
||||
- AskUserQuestion
|
||||
---
|
||||
<objective>
|
||||
Analyze the phase dependency graph for the current milestone. For each phase pair, determine if there is a dependency relationship based on:
|
||||
- File overlap (phases that modify the same files must be ordered)
|
||||
- Semantic dependencies (a phase that uses an API built by another phase)
|
||||
- Data flow (a phase that consumes output from another phase)
|
||||
|
||||
Then suggest `Depends on` updates to ROADMAP.md.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@~/.claude/get-shit-done/workflows/analyze-dependencies.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
No arguments required. Requires an active milestone with ROADMAP.md.
|
||||
|
||||
Run this command BEFORE `/gsd:manager` to fill in missing `Depends on` fields and prevent merge conflicts from unordered parallel execution.
|
||||
</context>
|
||||
|
||||
<process>
|
||||
Execute the analyze-dependencies workflow from @~/.claude/get-shit-done/workflows/analyze-dependencies.md end-to-end.
|
||||
Present dependency suggestions clearly and apply confirmed updates to ROADMAP.md.
|
||||
</process>
|
||||
@@ -410,6 +410,26 @@ Preview Claude's intended approach before planning.
|
||||
/gsd:list-phase-assumptions 2 # See assumptions for phase 2
|
||||
```
|
||||
|
||||
### `/gsd:analyze-dependencies`
|
||||
|
||||
Analyze phase dependencies and suggest `Depends on` entries for ROADMAP.md before running `/gsd:manager`.
|
||||
|
||||
**Prerequisites:** `.planning/ROADMAP.md` exists
|
||||
**Produces:** Dependency suggestion table; optionally updates `Depends on` fields in ROADMAP.md with confirmation
|
||||
|
||||
**Run this before `/gsd:manager`** when phases have empty `Depends on` fields and you want to avoid merge conflicts from unordered parallel execution.
|
||||
|
||||
```bash
|
||||
/gsd:analyze-dependencies # Analyze all phases and suggest dependencies
|
||||
```
|
||||
|
||||
**Detection methods:**
|
||||
- File overlap — phases touching the same files/domains must be ordered
|
||||
- Semantic dependencies — a phase that consumes an API or schema built by another phase
|
||||
- Data flow — a phase that reads output produced by another phase
|
||||
|
||||
---
|
||||
|
||||
### `/gsd:plan-milestone-gaps`
|
||||
|
||||
Create phases to close gaps from milestone audit.
|
||||
|
||||
96
get-shit-done/workflows/analyze-dependencies.md
Normal file
96
get-shit-done/workflows/analyze-dependencies.md
Normal file
@@ -0,0 +1,96 @@
|
||||
<purpose>
|
||||
Analyze ROADMAP.md phases for dependency relationships before execution. Detect file overlap between phases, semantic API/data-flow dependencies, and suggest `Depends on` entries to prevent merge conflicts during parallel execution by `/gsd:manager`.
|
||||
</purpose>
|
||||
|
||||
<process>
|
||||
|
||||
## 1. Load ROADMAP.md
|
||||
|
||||
Read `.planning/ROADMAP.md`. If it does not exist, error: "No ROADMAP.md found — run `/gsd:new-project` first."
|
||||
|
||||
Extract all phases. For each phase capture:
|
||||
- Phase number and name
|
||||
- Scope/Goal description
|
||||
- Files listed in `Files` or `files_modified` fields (if present)
|
||||
- Existing `Depends on` field value
|
||||
|
||||
## 2. Infer Likely File Modifications
|
||||
|
||||
For each phase without explicit `files_modified`, analyze the scope/goal description to infer which files will likely be modified. Use these heuristics:
|
||||
|
||||
- **Database/schema phases** → migration files, schema definitions, model files
|
||||
- **API/backend phases** → route files, controller files, service files, handler files
|
||||
- **Frontend/UI phases** → component files, page files, style files
|
||||
- **Auth phases** → middleware files, auth route files, session/token files
|
||||
- **Config/infra phases** → config files, environment files, CI/CD files
|
||||
- **Test phases** → test files, spec files, fixture files
|
||||
- **Shared utility phases** → lib/utils files, shared type definitions
|
||||
|
||||
Group phases by their inferred file domain (database, API, frontend, auth, config, shared).
|
||||
|
||||
## 3. Detect Dependency Relationships
|
||||
|
||||
For each pair of phases (A, B), check for dependency signals:
|
||||
|
||||
### File Overlap Detection
|
||||
If phases A and B will both modify files in the same domain or the same specific files, one must run before the other. The phase that *provides* the foundation runs first.
|
||||
|
||||
### Semantic Dependency Detection
|
||||
Read each phase's scope/goal for these patterns:
|
||||
- Phase B mentions consuming, using, or calling something that Phase A creates/implements
|
||||
- Phase B references an "API", "schema", "model", "endpoint", or "interface" that Phase A builds
|
||||
- Phase B says "after X is complete", "once X is built", "using the X from Phase N"
|
||||
- Phase B extends or modifies code that Phase A establishes
|
||||
|
||||
### Data Flow Detection
|
||||
- Phase A creates data structures, schemas, or types → Phase B consumes or transforms them
|
||||
- Phase A seeds/migrates the database → Phase B reads from that database
|
||||
- Phase A exposes an API contract → Phase B implements the client for that contract
|
||||
|
||||
## 4. Build Dependency Table
|
||||
|
||||
Output a dependency suggestion table:
|
||||
|
||||
```
|
||||
Phase Dependency Analysis
|
||||
=========================
|
||||
|
||||
Phase N: <name>
|
||||
Scope: <brief scope>
|
||||
Likely touches: <inferred file domains>
|
||||
|
||||
Suggested dependencies:
|
||||
→ Depends on: <Phase M> — reason: <overlap/semantic/data-flow explanation>
|
||||
|
||||
Current "Depends on": <existing value or "(none)">
|
||||
```
|
||||
|
||||
For phase pairs with no detected dependency, state: "No dependency detected between Phase X and Phase Y."
|
||||
|
||||
## 5. Summarize Suggested Changes
|
||||
|
||||
Show a consolidated diff of proposed ROADMAP.md `Depends on` changes:
|
||||
|
||||
```
|
||||
Suggested ROADMAP.md updates:
|
||||
Phase 3: add "Depends on: 1, 2" (file overlap: database schema)
|
||||
Phase 5: add "Depends on: 3" (semantic: uses auth API from Phase 3)
|
||||
Phase 4: no change needed (independent scope)
|
||||
```
|
||||
|
||||
## 6. Confirm and Apply
|
||||
|
||||
Ask the user: "Apply these `Depends on` suggestions to ROADMAP.md? (yes / no / edit)"
|
||||
|
||||
- **yes** — Write all suggested `Depends on` entries to ROADMAP.md. Confirm each write.
|
||||
- **no** — Print the suggestions as text only. User updates manually.
|
||||
- **edit** — Present each suggestion individually with yes/no/skip per suggestion.
|
||||
|
||||
When writing to ROADMAP.md:
|
||||
- Locate the phase entry and add or update the `Depends on:` field
|
||||
- Preserve all other phase content unchanged
|
||||
- Do not reorder phases
|
||||
|
||||
After applying: "ROADMAP.md updated. Run `/gsd:manager` to execute phases in the correct order."
|
||||
|
||||
</process>
|
||||
51
tests/analyze-dependencies.test.cjs
Normal file
51
tests/analyze-dependencies.test.cjs
Normal file
@@ -0,0 +1,51 @@
|
||||
const { test, describe, beforeEach, afterEach } = require('node:test');
|
||||
const assert = require('node:assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
describe('analyze-dependencies command', () => {
|
||||
test('command file exists', () => {
|
||||
const p = path.join(__dirname, '..', 'commands', 'gsd', 'analyze-dependencies.md');
|
||||
assert.ok(fs.existsSync(p), 'commands/gsd/analyze-dependencies.md should exist');
|
||||
});
|
||||
|
||||
test('command file has description frontmatter', () => {
|
||||
const p = path.join(__dirname, '..', 'commands', 'gsd', 'analyze-dependencies.md');
|
||||
const content = fs.readFileSync(p, 'utf-8');
|
||||
assert.ok(content.includes('description:'), 'Command file must have description frontmatter');
|
||||
});
|
||||
|
||||
test('workflow file exists', () => {
|
||||
const p = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'analyze-dependencies.md');
|
||||
assert.ok(fs.existsSync(p), 'workflows/analyze-dependencies.md should exist');
|
||||
});
|
||||
|
||||
test('workflow describes dependency analysis approach', () => {
|
||||
const p = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'analyze-dependencies.md');
|
||||
const content = fs.readFileSync(p, 'utf-8');
|
||||
assert.ok(content.includes('ROADMAP') || content.includes('phase'),
|
||||
'workflow should reference ROADMAP.md/phases');
|
||||
assert.ok(
|
||||
content.includes('depends') || content.includes('Depends') || content.includes('dependency'),
|
||||
'workflow should reference dependency detection'
|
||||
);
|
||||
});
|
||||
|
||||
test('workflow mentions file overlap detection', () => {
|
||||
const p = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'analyze-dependencies.md');
|
||||
const content = fs.readFileSync(p, 'utf-8');
|
||||
assert.ok(
|
||||
content.includes('file') && (content.includes('overlap') || content.includes('conflict')),
|
||||
'workflow should mention file overlap/conflict detection'
|
||||
);
|
||||
});
|
||||
|
||||
test('docs/COMMANDS.md references analyze-dependencies', () => {
|
||||
const p = path.join(__dirname, '..', 'docs', 'COMMANDS.md');
|
||||
if (fs.existsSync(p)) {
|
||||
const content = fs.readFileSync(p, 'utf-8');
|
||||
assert.ok(content.includes('analyze-dependencies'),
|
||||
'COMMANDS.md should document the new command');
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user