Skip to content

Commit 33fda87

Browse files
jwaldripclaude
andcommitted
feat(plugin): add greenfield project detection and UI mockup generation
Detect project maturity (greenfield/early/established) via commit count and source file heuristics to skip unnecessary scanning in new projects. Add mandatory UI mockup step during elaboration for any intent with a frontend component, with ascii/html format controlled by settings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 3cff0d3 commit 33fda87

File tree

4 files changed

+241
-16
lines changed

4 files changed

+241
-16
lines changed

plugin/hooks/inject-context.sh

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,19 @@ if [ -f "$DAG_LIB" ]; then
3535
source "$DAG_LIB"
3636
fi
3737

38+
# Source config library once (used for providers, maturity detection, etc.)
39+
CONFIG_LIB="${CLAUDE_PLUGIN_ROOT}/lib/config.sh"
40+
if [ -f "$CONFIG_LIB" ]; then
41+
# shellcheck source=/dev/null
42+
source "$CONFIG_LIB"
43+
fi
44+
45+
# Detect project maturity (greenfield / early / established)
46+
PROJECT_MATURITY=""
47+
if type detect_project_maturity &>/dev/null; then
48+
PROJECT_MATURITY=$(detect_project_maturity)
49+
fi
50+
3851
# Load workflows from plugin (defaults) and project (overrides)
3952
# Project workflows merge with plugin workflows (project takes precedence)
4053
PLUGIN_WORKFLOWS="${CLAUDE_PLUGIN_ROOT}/workflows.yml"
@@ -123,6 +136,34 @@ if [ -z "$ITERATION_JSON" ] && [[ "$CURRENT_BRANCH" == ai-dlc/*/* ]] && [[ "$CUR
123136
fi
124137

125138
if [ -z "$ITERATION_JSON" ]; then
139+
# Greenfield fast-path: skip all scanning for brand new projects
140+
if [ "$PROJECT_MATURITY" = "greenfield" ]; then
141+
echo "## AI-DLC Available (Greenfield Project)"
142+
echo ""
143+
echo "**Project maturity:** greenfield"
144+
echo ""
145+
echo "No active AI-DLC task. This looks like a new project — run \`/elaborate\` to start defining your first intent."
146+
echo ""
147+
if [ ! -f ".ai-dlc/settings.yml" ]; then
148+
echo "> **First time?** Run \`/setup\` to configure AI-DLC for this project (auto-detects providers, VCS settings, etc.)"
149+
echo ""
150+
fi
151+
# Inject provider context
152+
if type format_providers_markdown &>/dev/null; then
153+
PROVIDERS_MD=$(format_providers_markdown)
154+
if [ -n "$PROVIDERS_MD" ]; then
155+
echo "$PROVIDERS_MD"
156+
echo ""
157+
fi
158+
fi
159+
if [ -n "$AVAILABLE_WORKFLOWS" ]; then
160+
echo "**Available workflows:**"
161+
echo "$AVAILABLE_WORKFLOWS"
162+
echo ""
163+
fi
164+
exit 0
165+
fi
166+
126167
# Discover resumable intents from filesystem and git branches
127168
declare -A FILESYSTEM_INTENTS
128169
declare -A BRANCH_INTENTS
@@ -218,10 +259,7 @@ if [ -z "$ITERATION_JSON" ]; then
218259
echo ""
219260
fi
220261
# Inject provider context for pre-elaboration awareness
221-
CONFIG_LIB="${CLAUDE_PLUGIN_ROOT}/lib/config.sh"
222-
if [ -f "$CONFIG_LIB" ]; then
223-
# shellcheck source=/dev/null
224-
source "$CONFIG_LIB"
262+
if type format_providers_markdown &>/dev/null; then
225263
PROVIDERS_MD=$(format_providers_markdown)
226264
if [ -n "$PROVIDERS_MD" ]; then
227265
echo "$PROVIDERS_MD"
@@ -233,17 +271,18 @@ if [ -z "$ITERATION_JSON" ]; then
233271
if [ -n "$AVAILABLE_WORKFLOWS" ]; then
234272
echo "## AI-DLC Available"
235273
echo ""
274+
if [ -n "$PROJECT_MATURITY" ]; then
275+
echo "**Project maturity:** $PROJECT_MATURITY"
276+
echo ""
277+
fi
236278
echo "No active AI-DLC task. Run \`/elaborate\` to start a new task."
237279
echo ""
238280
if [ ! -f ".ai-dlc/settings.yml" ]; then
239281
echo "> **First time?** Run \`/setup\` to configure AI-DLC for this project (auto-detects providers, VCS settings, etc.)"
240282
echo ""
241283
fi
242284
# Inject provider context
243-
CONFIG_LIB="${CLAUDE_PLUGIN_ROOT}/lib/config.sh"
244-
if [ -f "$CONFIG_LIB" ]; then
245-
# shellcheck source=/dev/null
246-
source "$CONFIG_LIB"
285+
if type format_providers_markdown &>/dev/null; then
247286
PROVIDERS_MD=$(format_providers_markdown)
248287
if [ -n "$PROVIDERS_MD" ]; then
249288
echo "$PROVIDERS_MD"
@@ -323,17 +362,18 @@ echo ""
323362
echo "**Iteration:** $ITERATION | **Hat:** $HAT | **Workflow:** $WORKFLOW_NAME ($WORKFLOW_HATS_STR)"
324363
echo ""
325364

326-
# Inject provider context
327-
CONFIG_LIB="${CLAUDE_PLUGIN_ROOT}/lib/config.sh"
328-
if [ -f "$CONFIG_LIB" ]; then
329-
# shellcheck source=/dev/null
330-
source "$CONFIG_LIB"
365+
# Inject provider context and maturity signal
366+
if type format_providers_markdown &>/dev/null; then
331367
PROVIDERS_MD=$(format_providers_markdown)
332368
if [ -n "$PROVIDERS_MD" ]; then
333369
echo "$PROVIDERS_MD"
334370
echo ""
335371
fi
336372
fi
373+
if [ -n "$PROJECT_MATURITY" ]; then
374+
echo "**Project maturity:** $PROJECT_MATURITY"
375+
echo ""
376+
fi
337377

338378
# Batch load all han keep values at once (single subprocess call)
339379
# This is much faster than 5+ separate han keep load calls

plugin/lib/config.sh

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,56 @@ detect_ci_cd() {
348348
fi
349349
}
350350

351+
# Detect project maturity based on commit count and source file count
352+
# Usage: detect_project_maturity [directory]
353+
# Returns: greenfield | early | established
354+
detect_project_maturity() {
355+
local dir="${1:-.}"
356+
357+
# Guard: shallow clone — commit count is unreliable
358+
local is_shallow
359+
is_shallow=$(git -C "$dir" rev-parse --is-shallow-repository 2>/dev/null || echo "false")
360+
361+
local commit_count=0
362+
if [ "$is_shallow" != "true" ]; then
363+
commit_count=$(git -C "$dir" rev-list --count HEAD 2>/dev/null || echo "0")
364+
fi
365+
366+
# Count source files excluding scaffolding
367+
# Excludes: *.md, *.json, *.yml, *.yaml, *.lock, *.toml, LICENSE*, Dockerfile*,
368+
# .github/*, .gitlab-ci*, .circleci/*, .ai-dlc/*
369+
local source_file_count
370+
source_file_count=$(git -C "$dir" ls-files 2>/dev/null \
371+
| grep -cvE '\.(md|json|ya?ml|lock|toml)$|^LICENSE|^Dockerfile|^\.github/|^\.gitlab-ci|^\.circleci/|^\.ai-dlc/' \
372+
2>/dev/null || true)
373+
: "${source_file_count:=0}"
374+
375+
# Shallow clone: use source file count only
376+
if [ "$is_shallow" = "true" ]; then
377+
if [ "$source_file_count" -le 5 ]; then
378+
echo "greenfield"
379+
elif [ "$source_file_count" -le 20 ]; then
380+
echo "early"
381+
else
382+
echo "established"
383+
fi
384+
return
385+
fi
386+
387+
# Full repo heuristics
388+
if [ "$commit_count" -le 3 ]; then
389+
echo "greenfield"
390+
elif [ "$commit_count" -le 20 ]; then
391+
if [ "$source_file_count" -le 5 ]; then
392+
echo "greenfield"
393+
else
394+
echo "early"
395+
fi
396+
else
397+
echo "established"
398+
fi
399+
}
400+
351401
# Load provider configuration with fallback chain
352402
# Usage: load_providers [repo_root]
353403
# Returns: JSON object with all provider categories

plugin/schemas/settings.schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
"providers": {
1717
"$ref": "#/definitions/providersConfig",
1818
"description": "External system providers for spec, ticketing, design, and comms"
19+
},
20+
"mockup_format": {
21+
"type": "string",
22+
"enum": ["ascii", "html"],
23+
"default": "ascii",
24+
"description": "Format for UI mockups generated during elaboration. 'ascii' produces text-based wireframes in markdown code blocks. 'html' produces self-contained HTML files written to .ai-dlc/{intent-slug}/mockups/."
1925
}
2026
},
2127
"additionalProperties": false,

plugin/skills/elaborate/SKILL.md

Lines changed: 132 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ Before any elaboration, verify the working environment:
6161
IS_COWORK="${CLAUDE_CODE_IS_COWORK:-}"
6262
IN_REPO=$(git rev-parse --git-dir 2>/dev/null && echo "true" || echo "false")
6363
```
64+
1b. **Detect project maturity**: Read `**Project maturity:**` from the session context injected by the SessionStart hook. If not present, detect directly:
65+
```bash
66+
source "${CLAUDE_PLUGIN_ROOT}/lib/config.sh"
67+
PROJECT_MATURITY=$(detect_project_maturity)
68+
```
69+
Values: `greenfield` (brand new, 0-3 commits or minimal source files), `early` (some code but still small), `established` (mature codebase). This value gates Phase 2.5 exploration behavior.
6470
2. If **not cowork** (`IS_COWORK` is empty) **and in a repo** (`IN_REPO` is `true`): proceed to Phase 0 (Existing Intent Check) below.
6571
3. If **cowork** (`IS_COWORK=1`) **or not in a repo**:
6672
a. **Ask how to access the project**:
@@ -271,19 +277,33 @@ This ensures:
271277

272278
**This phase is mandatory.** Before defining success criteria or decomposing into units, you MUST deeply understand the technical landscape. Shallow understanding here causes builders to build the wrong thing.
273279

280+
### Greenfield Adaptation
281+
282+
**Gate exploration based on project maturity** (detected in Phase 0):
283+
284+
- **Greenfield** (`PROJECT_MATURITY=greenfield`):
285+
- **Skip** items 2 (Existing Codebases) and 5 (Existing Implementations) below — there is no codebase to explore. Do NOT spawn Explore subagents for codebase research.
286+
- **Keep** items 1 (APIs/Schemas), 3 (Data Sources), 4 (Domain Model — from user input + external research), 6 (External Docs/Libraries), 7 (Providers).
287+
- Focus domain discovery on external research, API introspection, and user input rather than codebase analysis.
288+
- **Early** (`PROJECT_MATURITY=early`):
289+
- Use `Glob` and `Read` directly instead of Explore subagents — the codebase is small enough to read directly without subagent overhead.
290+
- All items apply, but codebase exploration should be lightweight.
291+
- **Established** (`PROJECT_MATURITY=established`):
292+
- Full exploration as described below. Use Explore subagents for deep codebase research.
293+
274294
### What to Explore
275295

276296
Based on what the user described in Phase 2, identify every relevant technical surface and explore it thoroughly. Use ALL available research tools — codebase exploration, API introspection, web searches, and documentation fetching:
277297

278298
1. **APIs and Schemas**: If the intent involves an API, query it. Run introspection queries. Read the actual schema. Map every type, field, query, mutation, and subscription. Don't guess what data is available — verify it.
279299

280-
2. **Existing Codebases**: If the intent builds on or integrates with existing code, explore it via Explore subagents. Have them find relevant files, read source code, and report back on existing patterns, conventions, and architecture.
300+
2. **Existing Codebases** *(skip for greenfield)*: If the intent builds on or integrates with existing code, explore it via Explore subagents (or `Glob`/`Read` for early-maturity projects). Have them find relevant files, read source code, and report back on existing patterns, conventions, and architecture.
281301

282302
3. **Data Sources**: If the intent involves data, understand where it lives. Query for real sample data. Understand what fields are populated, what's empty, what's missing. Identify gaps between what's available and what's needed.
283303

284304
4. **Domain Model**: From your exploration, build a domain model — the key entities, their relationships, and their lifecycle. This is not a database schema; it's a conceptual map of the problem space.
285305

286-
5. **Existing Implementations**: If there are related features, similar tools, or reference implementations, read them. Understand what already exists so you don't build duplicates or miss integration points.
306+
5. **Existing Implementations** *(skip for greenfield)*: If there are related features, similar tools, or reference implementations, read them. Understand what already exists so you don't build duplicates or miss integration points.
287307

288308
6. **External Documentation and Libraries**: Use `WebSearch` and `WebFetch` to research relevant libraries, frameworks, APIs, standards, or prior art. If the intent involves a third-party system, find its documentation and understand its capabilities. If the intent involves a design pattern or technique, research best practices and common pitfalls.
289309

@@ -298,7 +318,7 @@ Based on what the user described in Phase 2, identify every relevant technical s
298318

299319
Use every research tool available. Spawn multiple explorations in parallel for independent concerns:
300320

301-
1. **Subagents for deep codebase/API exploration**: Use `Task` with `subagent_type: "Explore"` for multi-step research that requires reading many files, querying APIs, and synthesizing findings:
321+
1. **Subagents for deep codebase/API exploration** *(established projects only)*: Use `Task` with `subagent_type: "Explore"` for multi-step research that requires reading many files, querying APIs, and synthesizing findings. **If greenfield: do NOT spawn Explore subagents for codebase research — there is no codebase to explore.** If early: use `Glob`/`Read` directly instead of Explore subagents.
302322

303323
```
304324
Task({
@@ -357,6 +377,111 @@ Spawn one subagent per design file, in parallel with codebase Explore agents. Wh
357377
- Append to `discovery.md` under `## Design Analysis: {file name}`
358378
- If no design MCP tools are discoverable, the subagent reports unavailability — log a warning and continue without design analysis
359379

380+
5. **UI Mockups**: If the intent involves user-facing interfaces (frontend, CLI, TUI, etc.), generate mockups for every distinct screen or view. This step is **mandatory** for any intent with a UI component — it serves different purposes depending on whether designs exist:
381+
382+
- **Designs exist** (item 4 returned design analysis): Translate the design analysis into mockups that demonstrate your understanding of the designs. This is *verification* — the user confirms that you correctly interpreted the designer's intent before builders act on it. Misunderstanding a design is expensive; catching it here is cheap.
383+
- **No designs exist**: Generate mockups collaboratively with the user as *pre-build visual design*. This is where layout, information hierarchy, and interaction flow get decided. Without this step, builders guess — and they guess wrong. This applies regardless of whether a design provider is configured — having a Figma account doesn't mean designs exist yet. In AI-DLC workflows, design may come later as its own unit with `discipline: design`.
384+
385+
#### Mockup Format
386+
387+
Read the mockup format from settings (default: `ascii`):
388+
```bash
389+
source "${CLAUDE_PLUGIN_ROOT}/lib/config.sh"
390+
REPO_SETTINGS=$(load_repo_settings)
391+
MOCKUP_FORMAT=$(echo "$REPO_SETTINGS" | jq -r '.mockup_format // "ascii"')
392+
```
393+
394+
- **`ascii`** (default): Text-based wireframes rendered in markdown code blocks. Inline in `discovery.md`. Works everywhere, no tooling needed, visible in any terminal or editor.
395+
- **`html`**: Self-contained HTML files written to `.ai-dlc/{intent-slug}/mockups/{view-slug}.html`. Use semantic HTML with inline CSS — no external dependencies. Each file should be viewable by opening it directly in a browser. Reference the file path in `discovery.md` instead of inlining the mockup.
396+
397+
#### Per-View Mockup Process
398+
399+
For each distinct screen or view identified in the domain model:
400+
- Create a mockup showing layout structure, key UI elements, and data placement
401+
- Annotate with interaction notes (what happens on click, hover, submit, error states)
402+
- Show which domain entities map to which UI regions
403+
- If working from designs: note where your interpretation might diverge from the source
404+
405+
Present mockups to the user with `AskUserQuestion`:
406+
```json
407+
{
408+
"questions": [{
409+
"question": "Does this mockup capture the right layout and information hierarchy for {view name}?",
410+
"header": "Mockup",
411+
"options": [
412+
{"label": "Looks right", "description": "Layout and information hierarchy are correct"},
413+
{"label": "Wrong layout", "description": "The arrangement of elements needs changes"},
414+
{"label": "Missing elements", "description": "Important UI elements are not shown"},
415+
{"label": "Wrong data", "description": "The data shown doesn't match what I expect"}
416+
],
417+
"multiSelect": true
418+
}]
419+
}
420+
```
421+
422+
Iterate on mockups until the user confirms. Then persist:
423+
424+
**For `ascii` format** — append to `discovery.md`:
425+
```bash
426+
cat >> "$DISCOVERY_FILE" << 'EOF'
427+
428+
## UI Mockup: {View Name}
429+
430+
**Confirmed:** {ISO timestamp}
431+
**Source:** {design provider analysis | collaborative}
432+
433+
### Layout
434+
```
435+
{ASCII mockup}
436+
```
437+
438+
### Interactions
439+
- {element}: {behavior on click/hover/submit}
440+
- {element}: {error states, loading states}
441+
442+
### Data Mapping
443+
- {UI region} ← {domain entity}.{field}
444+
445+
EOF
446+
```
447+
448+
**For `html` format** — write HTML file and reference in `discovery.md`:
449+
```bash
450+
MOCKUP_DIR=".ai-dlc/${INTENT_SLUG}/mockups"
451+
mkdir -p "$MOCKUP_DIR"
452+
cat > "${MOCKUP_DIR}/{view-slug}.html" << 'HTMLEOF'
453+
<!DOCTYPE html>
454+
<html lang="en">
455+
<head><meta charset="UTF-8"><title>{View Name} — Mockup</title>
456+
<style>/* inline CSS — no external deps */</style>
457+
</head>
458+
<body>
459+
{semantic HTML mockup with inline styles}
460+
</body>
461+
</html>
462+
HTMLEOF
463+
464+
# Reference in discovery.md
465+
cat >> "$DISCOVERY_FILE" << EOF
466+
467+
## UI Mockup: {View Name}
468+
469+
**Confirmed:** {ISO timestamp}
470+
**Source:** {design provider analysis | collaborative}
471+
**File:** \`.ai-dlc/${INTENT_SLUG}/mockups/{view-slug}.html\`
472+
473+
### Interactions
474+
- {element}: {behavior on click/hover/submit}
475+
- {element}: {error states, loading states}
476+
477+
### Data Mapping
478+
- {UI region} ← {domain entity}.{field}
479+
480+
EOF
481+
```
482+
483+
**Skip this step only if:** the intent has no user-facing interface (pure backend, API, data pipeline, infrastructure, etc.).
484+
360485
**Spawn multiple research paths in parallel.** Don't serialize explorations that are independent — launch all of them at once and synthesize when results return.
361486
362487
If a VCS MCP is available (e.g., GitHub MCP), use it for code browsing alongside or instead of local file tools.
@@ -405,6 +530,10 @@ EOF
405530
- `## External Research: {topic}` — For web research, library docs, prior art
406531
- `## Data Source: {name}` — For data source exploration (what's available, what's missing)
407532
- `## Provider Context: {type}` — For ticketing, spec, or comms provider findings
533+
- `## UI Mockup: {view}` — ASCII mockups of user-facing views with interaction notes and data mapping
534+
- `## Architecture Decision: {topic}` — For greenfield/early projects: key architecture choices (frameworks, patterns, structure)
535+
- `## Technology Choice: {name}` — For greenfield/early projects: technology selection rationale
536+
- `## Reference Implementation: {name}` — For greenfield/early projects: external reference implementations or prior art informing the design
408537

409538
**After appending to `discovery.md`, keep only a brief summary in your context** — the full details are safely on disk and will be available to builders. This is the key benefit: your context stays lean for continued exploration while nothing is lost.
410539

0 commit comments

Comments
 (0)