viepilot 2.50.1 → 3.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +214 -0
  2. package/README.md +17 -17
  3. package/bin/viepilot.cjs +1 -0
  4. package/bin/vp-tools.cjs +123 -1
  5. package/docs/brainstorm/session-2026-05-22.md +472 -0
  6. package/docs/dev/agents.md +51 -41
  7. package/docs/dev/architecture.md +26 -0
  8. package/docs/skills-reference.md +96 -0
  9. package/lib/adapter-context.cjs +294 -0
  10. package/lib/adapters/antigravity.cjs +8 -2
  11. package/lib/adapters/claude-code.cjs +4 -0
  12. package/lib/audit/browser-runner.cjs +102 -0
  13. package/lib/intake/adapters/browser.cjs +58 -0
  14. package/lib/intake/adapters/excel-m365.cjs +54 -6
  15. package/lib/intake/auto-intake.cjs +194 -0
  16. package/lib/intake/classifier.cjs +22 -4
  17. package/lib/intake/manifest.cjs +81 -0
  18. package/lib/intake/triage-ux.cjs +10 -2
  19. package/lib/intake/validator.cjs +97 -0
  20. package/lib/intake/writeback.cjs +169 -3
  21. package/lib/request/url-enricher.cjs +69 -0
  22. package/lib/viepilot-install.cjs +15 -0
  23. package/package.json +1 -1
  24. package/skills/vp-audit/SKILL.md +99 -3
  25. package/skills/vp-auto/SKILL.md +54 -4
  26. package/skills/vp-brainstorm/SKILL.md +69 -3
  27. package/skills/vp-crystallize/SKILL.md +52 -3
  28. package/skills/vp-debug/SKILL.md +52 -3
  29. package/skills/vp-design/SKILL.md +52 -3
  30. package/skills/vp-docs/SKILL.md +52 -3
  31. package/skills/vp-evolve/SKILL.md +52 -3
  32. package/skills/vp-info/SKILL.md +52 -3
  33. package/skills/vp-intake/SKILL.md +306 -7
  34. package/skills/vp-pause/SKILL.md +52 -3
  35. package/skills/vp-persona/SKILL.md +52 -3
  36. package/skills/vp-proposal/SKILL.md +52 -3
  37. package/skills/vp-request/SKILL.md +72 -3
  38. package/skills/vp-resume/SKILL.md +52 -3
  39. package/skills/vp-rollback/SKILL.md +52 -3
  40. package/skills/vp-skills/SKILL.md +52 -3
  41. package/skills/vp-status/SKILL.md +52 -3
  42. package/skills/vp-task/SKILL.md +52 -3
  43. package/skills/vp-ui-components/SKILL.md +52 -3
  44. package/skills/vp-update/SKILL.md +52 -3
  45. package/workflows/autonomous.md +268 -18
  46. package/workflows/brainstorm.md +222 -7
  47. package/workflows/crystallize.md +124 -6
  48. package/workflows/design.md +62 -1
  49. package/workflows/request.md +54 -8
@@ -37,6 +37,27 @@ Agent({
37
37
 
38
38
  See `agents/` directory for full agent specifications.
39
39
 
40
+ ## v3 Orchestration Agents (Phase 130 — FEAT-021)
41
+
42
+ On Claude Code adapter (when `ADAPTER_CONTEXT.orchestration.parallel == true`), three dedicated
43
+ subagent definitions in `agents/claude-code/` handle orchestrated execution:
44
+
45
+ | Agent | File | Model | Role |
46
+ |-------|------|-------|------|
47
+ | vp-task-executor | `agents/claude-code/vp-task-executor.md` | claude-haiku-4-5 | Implements a single task contract; fresh context window per task |
48
+ | vp-phase-planner | `agents/claude-code/vp-phase-planner.md` | claude-sonnet-4-6 | Reads phase, builds dependency graph, identifies parallel clusters |
49
+ | vp-quality-gate | `agents/claude-code/vp-quality-gate.md` | claude-sonnet-4-6 | Runs verification commands; reports PASS/FAIL/PARTIAL |
50
+
51
+ **Fan-out pattern** (implemented in Phase 133):
52
+ ```
53
+ vp-phase-planner → clusters → Agent(vp-task-executor) × N (parallel) → Agent(vp-quality-gate)
54
+ ```
55
+
56
+ **PreToolUse/PostToolUse hooks** (Claude Code only, registered via `vp-tools hooks install --adapter claude-code`):
57
+ - `PreToolUse` on `Write`/`Edit` in task scope: validates path is repo-relative (BUG-009 gate)
58
+ - `PostToolUse` on `Bash`: captures command output for quality-gate evidence log
59
+ - Hook config lives in `~/.claude/settings.json` → `hooks` array
60
+
40
61
  <process>
41
62
 
42
63
  > **AUQ preload — Claude Code adapter (ENH-059):** At session start, before any interactive prompt, call `ToolSearch` with `query: "select:AskUserQuestion"` to load the deferred schema. Required on Claude Code (terminal). Skip only if `ToolSearch` returns an error → use text fallback for that session.
@@ -95,6 +116,39 @@ Build `SKILL_CONTEXT_MAP` in session memory:
95
116
 
96
117
  **If `## Skills` section absent or empty**: silent no-op — `SKILL_CONTEXT_MAP = { required: [], optional: [] }`.
97
118
 
119
+ ### ADAPTER_CONTEXT Injection (FEAT-021 Phase 127)
120
+
121
+ Detect the active adapter and inject its capability map into session context. Skills use
122
+ ADAPTER_CONTEXT to select correct tool names and fallback chains — no inline compat tables.
123
+
124
+ ```bash
125
+ ADAPTER_CONTEXT_JSON=$(node "$HOME/.claude/viepilot/bin/vp-tools.cjs" detect-adapter --json 2>/dev/null \
126
+ || node "$(pwd)/bin/vp-tools.cjs" detect-adapter --json 2>/dev/null \
127
+ || echo '{"adapter":"claude-code","interactive_mode":"AUQ","orchestration":{"parallel":true,"teams":true},"capabilities":["shell","read","write","edit","search","agent","interactive"]}')
128
+ ```
129
+
130
+ Parse into session variables:
131
+ - `ADAPTER_ID` — e.g. `"claude-code"`
132
+ - `ADAPTER_INTERACTIVE` — `"AUQ"` | `"text"` | `"none"`
133
+ - `ADAPTER_PARALLEL` — `true` | `false` (orchestration.parallel)
134
+ - `ADAPTER_TOOLS` — tools{} map (use `ctx.tools.shell` → correct tool name)
135
+
136
+ **Shell tool resolution** (use `ADAPTER_TOOLS.shell` for all bash/cmd execution in tasks):
137
+ | Adapter | Shell tool |
138
+ |---|---|
139
+ | claude-code | `Bash` |
140
+ | cursor-agent | `run_terminal_cmd` |
141
+ | antigravity | `shell` |
142
+ | codex | `container.exec` |
143
+ | copilot | `runCommands` |
144
+
145
+ **Interactive fallback chain** (based on `ADAPTER_INTERACTIVE`):
146
+ 1. `"AUQ"` → call `AskUserQuestion` (preload via ToolSearch first)
147
+ 2. `"text"` → show numbered list in plain text
148
+ 3. `"none"` → proceed with defaults (log decision)
149
+
150
+ Silent on error — do not fail the phase. Fallback: assume `claude-code` defaults.
151
+
98
152
  ### Tag Prefix Resolution (ENH-050)
99
153
  Resolve the enriched git tag prefix once at session start. All task/phase tags use `${TAG_PREFIX}`.
100
154
 
@@ -170,9 +224,137 @@ cat .viepilot/phases/{phase}/PHASE-STATE.md
170
224
 
171
225
  Check if phase already has completed tasks → resume from next task.
172
226
 
227
+ ### 3b. Orchestration Mode Selection (Phase 133 — FEAT-021)
228
+
229
+ > ⛔ **ORCHESTRATOR STOP — Implementation Delegation Rule (ENH-096)**
230
+ >
231
+ > On Claude Code adapter, the main orchestrator agent MUST NOT:
232
+ > - Call `Edit`, `Write`, or `MultiEdit` on implementation files (`lib/`, `bin/`, `tests/`, `agents/`, `skills/`, `workflows/` shipping content)
233
+ > - Run `Bash` commands that write source code (e.g. `cat >`, `tee`, compiler/bundler invocations for production output)
234
+ > - Implement features, fix bugs, or write tests inline in this context
235
+ >
236
+ > **Inline implementation is a framework violation.** It fills the orchestrator's context with
237
+ > implementation tokens (file diffs, test output, compile logs), degrading orchestration quality
238
+ > across subsequent tasks.
239
+ >
240
+ > The orchestrator is permitted ONLY to:
241
+ > - `Read` — read PHASE-STATE.md, TRACKER.md, HANDOFF.json, task files, ROADMAP.md (read-only)
242
+ > - `Bash` — read-only git checks ONLY: `git status --porcelain` (BUG-013: `??` lines = untracked, not dirty), `git rev-list --count @{u}..HEAD`, `node bin/vp-tools.cjs git-persistence --strict`
243
+ > - `Agent` — spawn vp-task-executor, vp-quality-gate, vp-phase-planner, tracker-agent, vp-git-agent, changelog-agent
244
+ >
245
+ > The orchestrator MUST NOT call Edit, Write, or Bash for ANY writes — including state files.
246
+ > All writes and git operations go through subagents (ENH-097).
247
+ >
248
+ > All implementation (file edits, test runs for implementation, commits) MUST go through
249
+ > `vp-task-executor`. This applies even when there is only one task in the phase.
250
+
251
+ Before entering the task loop, check `ADAPTER_PARALLEL` (set in ADAPTER_CONTEXT Injection step):
252
+
253
+ ```
254
+ IF ADAPTER_PARALLEL == true AND ADAPTER_ID == "claude-code":
255
+ → ORCHESTRATOR MODE: fan-out dispatch via Agent tool (section 3b-orch)
256
+ ELSE:
257
+ → SEQUENTIAL MODE: single-agent serial execution (section 3b-seq)
258
+ ```
259
+
260
+ **Agent Teams mode** (when `ADAPTER_CONTEXT.orchestration.teams == true` AND pending task count ≥ 8):
261
+ - Set `TEAMS_MODE = true`
262
+ - Activate shared TodoWrite task list for teammate coordination
263
+ - Each Agent worker reads from the shared list rather than receiving an explicit task prompt
264
+
265
+ #### 3b-orch: Orchestrator Fan-out (Claude Code only)
266
+
267
+ When `ADAPTER_PARALLEL == true`:
268
+
269
+ **Step 1 — Dependency resolution** (via `vp-phase-planner` agent):
270
+ ```
271
+ Agent(
272
+ subagent_type: "vp-phase-planner",
273
+ prompt: "Analyze phase {N} tasks in .viepilot/phases/{dir}/PHASE-STATE.md.
274
+ Return JSON: { clusters: [ { tasks: [id,...], can_parallel: bool,
275
+ sequential_fallback: [id,...] } ] }
276
+ Only include incomplete tasks."
277
+ )
278
+ ```
279
+
280
+ Parse `clusters` JSON from agent output. Each cluster is a set of independent tasks that can run in parallel.
281
+
282
+ **Step 2 — Fan-out dispatch** (parallel `Agent` calls per cluster):
283
+ ```
284
+ FOR each cluster in clusters:
285
+ IF cluster.can_parallel == true AND cluster.tasks.length > 1:
286
+ → Dispatch tasks in parallel:
287
+ FOR EACH task_id in cluster.tasks (simultaneously):
288
+ Agent(
289
+ subagent_type: "vp-task-executor",
290
+ prompt: "Execute task {task_id} in phase {N}.
291
+ Task file: .viepilot/phases/{dir}/tasks/{task_id}.md
292
+ PHASE-STATE: .viepilot/phases/{dir}/PHASE-STATE.md
293
+ Repo root: {cwd}
294
+ Return: TASK_RESULT: PASS|FAIL|PARTIAL + summary"
295
+ )
296
+ Collect all TASK_RESULT outputs before advancing.
297
+ ELSE:
298
+ → Execute tasks in sequence (cluster.sequential_fallback order)
299
+ Agent(vp-task-executor, single task)
300
+ ```
301
+
302
+ **Spawn Template (copy-paste verbatim — do not paraphrase):**
303
+ ```
304
+ Agent({
305
+ subagent_type: "vp-task-executor",
306
+ description: "Execute task {task_id} — phase {N}",
307
+ prompt: `Execute ViePilot task {task_id} for phase {N}.
308
+
309
+ Task file: {task_path}
310
+ Phase state: {phase_dir}/PHASE-STATE.md
311
+ Repo root: {cwd}
312
+
313
+ Read the task file completely, implement all acceptance criteria, run verification
314
+ commands, commit with message format: {projectPrefix}-vp-p{N}-t{task_id}: <summary>,
315
+ then report:
316
+ TASK_RESULT: PASS|FAIL|PARTIAL
317
+ Committed: <sha> — <message>
318
+ Criteria: ✅/❌ per item`
319
+ })
320
+ ```
321
+
322
+ Replace `{task_id}`, `{N}`, `{task_path}`, `{phase_dir}`, `{cwd}`, `{projectPrefix}` with actual values.
323
+ The orchestrator MUST NOT call Edit/Write/Bash for implementation — the subagent handles all of that.
324
+
325
+ **Model tiering** (`ADAPTER_CONTEXT.orchestration.model_override`):
326
+ - Worker agent (vp-task-executor): `claude-haiku-4-5` — routine file edits, low token cost
327
+ - Planner/gate agent (vp-phase-planner, vp-quality-gate): `claude-sonnet-4-6` — reasoning, dependency analysis
328
+ - Orchestrator (main agent): retains current model — coordination only, no implementation
329
+
330
+ **Step 3 — Quality gate** (after each cluster completes):
331
+ ```
332
+ Agent(
333
+ subagent_type: "vp-quality-gate",
334
+ prompt: "Run verification for phase {N} cluster {C}.
335
+ Tasks completed: {task_ids}
336
+ Check: acceptance criteria, tests, lint.
337
+ Return: QUALITY_GATE: PASS|FAIL|PARTIAL + findings"
338
+ )
339
+ ```
340
+
341
+ On `QUALITY_GATE: FAIL` or `PARTIAL` → route to control point (retry cluster / skip / stop).
342
+ On `QUALITY_GATE: PASS` → update PHASE-STATE.md (all cluster tasks → done), update TRACKER.md, continue.
343
+
344
+ **Teams mode** (when `TEAMS_MODE == true`):
345
+ - Write all pending task IDs to shared `TodoWrite` list at phase start
346
+ - Each `Agent(vp-task-executor)` reads next available task from shared list
347
+ - Prevents duplicate execution when dispatching ≥ 8 tasks concurrently
348
+
349
+ #### 3b-seq: Sequential Mode (non-Claude Code adapters)
350
+
351
+ When `ADAPTER_PARALLEL == false` (Cursor / Antigravity / Codex / Copilot):
352
+
353
+ Execute tasks one at a time in the main agent context. No fan-out, no subagent dispatch.
354
+
173
355
  ### 3b. Execute Tasks Loop
174
356
 
175
- For each task in phase:
357
+ For each task in phase (sequential mode) or per cluster (orchestrator mode):
176
358
 
177
359
  #### Load Task Context
178
360
  ```yaml
@@ -449,9 +631,9 @@ IF (Paths block contains ≥5 files of the same type, e.g., skills/*/SKILL.md)
449
631
  OR (task description matches: "update all N files", "add row to all skills", "sync across N files")
450
632
  → Invoke doc-sync-agent instead of N sequential edits:
451
633
 
452
- Agent({ subagent_type: "general-purpose",
634
+ Agent({ subagent_type: "doc-sync-agent",
453
635
  description: "doc-sync-agent: {change_mode} across {file_pattern}",
454
- prompt: "Load agents/doc-sync-agent.md. Pattern: {glob}. Mode: {change_mode}. Anchor: {anchor}. Content: {content}."
636
+ prompt: "file_pattern: {glob}. change_mode: {change_mode}. anchor: {anchor}. content: {content}."
455
637
  })
456
638
  Non-Claude Code: apply changes sequentially inline.
457
639
 
@@ -507,6 +689,21 @@ quality_gate:
507
689
  - no_lint_errors: true
508
690
  ```
509
691
 
692
+ #### Test Generation — test-generator-agent (ENH-057, BUG-028 fix)
693
+
694
+ **Trigger**: current task is the last task in the phase AND task.md contains `## Acceptance Criteria`
695
+
696
+ **Claude Code — invoke test-generator-agent:**
697
+ ```
698
+ Agent({ subagent_type: "test-generator-agent",
699
+ description: "test-generator-agent: generate + run contract tests for phase {phase}",
700
+ prompt: "task_file: {task_md_path}. test_output_path: tests/unit/phase{phase}-{task}-contract.test.js. phase_number: {phase}. task_number: {task}."
701
+ })
702
+ ```
703
+ Non-Claude Code: generate test file inline from acceptance criteria, then run `npm test`.
704
+
705
+ If test-generator-agent reports FAIL: **do NOT** mark task complete — fix failing criteria first.
706
+
510
707
  #### Git Persistence Gate (BUG-003)
511
708
  Before marking a task PASS, require durable git persistence:
512
709
 
@@ -540,6 +737,30 @@ If any check fails:
540
737
  - Update TRACKER.md immediately
541
738
  - Update HANDOFF.json immediately
542
739
  - Update CHANGELOG.md if feature/fix
740
+
741
+ **Post-PASS: Intake Write-back (ENH-095)**
742
+
743
+ After the above state updates, check the task `.md` for an `## Intake Source` block:
744
+ ```
745
+ ## Intake Source
746
+ - channel_id: trip-tracking-bug
747
+ - sheet_name: BUG
748
+ - source_row: 1
749
+ - manifest_path: .viepilot/intake/trip-tracking-bug-manifest.json
750
+ - channel_type: excel_m365
751
+ - workbook_id: {workbook_id or null}
752
+ - sharing_url: {sharing_url or null}
753
+ ```
754
+
755
+ If the block is present:
756
+ 1. Parse the fields from the block
757
+ 2. Load manifest from `manifest_path` via `lib/intake/manifest.cjs → loadManifest()`
758
+ 3. Call `getWriteBackConfig(manifest, sheet_name)` → get `response_col`
759
+ 4. Build `response = { status: 'Fixed ✓', phaseTask: 'vp-p{N}-t{M}', version: currentVersion, date: YYYY-MM-DD }`
760
+ 5. Call `lib/intake/writeback.cjs → writebackIntakeResponse(channel, source_row, response, projectRoot, sheet_name, response_col)`
761
+ 6. Log: `[vp-auto] Intake write-back: row {source_row} → col {response_col}: "{text}" — {success|failed}`
762
+ 7. **Write-back failure is non-fatal** — log to stderr and continue to next task regardless
763
+
543
764
  - Move to next task
544
765
 
545
766
  **PARTIAL (some checks fail):**
@@ -564,14 +785,28 @@ update:
564
785
  - CHANGELOG.md: if feature/fix completed ← via changelog-agent at end of phase (ENH-057)
565
786
  ```
566
787
 
567
- **Tracker updates — invoke tracker-agent:**
788
+ **State updates — spawn subagents (Claude Code, ENH-097):**
789
+
568
790
  ```
569
- Agent({ subagent_type: "general-purpose",
570
- description: "tracker-agent: update task {phase}.{task} → {status}",
571
- prompt: "Load agents/tracker-agent.md. Operation: update-task-status. Phase: {phase}. Task: {task}. Status: {status}."
791
+ # Task status (PHASE-STATE.md + TRACKER.md current state):
792
+ Agent({ subagent_type: "tracker-agent",
793
+ description: "Update task {N}.{task_id} {status}",
794
+ prompt: "operation: update-task-status. phase: {N}. task: {task_id}. status: {status}."
795
+ })
796
+
797
+ # HANDOFF.json update:
798
+ Agent({ subagent_type: "tracker-agent",
799
+ description: "Update HANDOFF.json — phase {N} task {task_id}",
800
+ prompt: "operation: update-handoff. phase: {N}. phase_name: {phase_name}. task: {task_id}. task_name: {task_name}. status: {status}. version: {version}. tasks_total: {T}. tasks_completed: {C}. notes: [\"{note}\"]."
801
+ })
802
+
803
+ # ROADMAP.md phase status sync (after phase complete):
804
+ Agent({ subagent_type: "tracker-agent",
805
+ description: "Update ROADMAP.md — phase {N} done",
806
+ prompt: "operation: update-roadmap-phase. phase_number: {N}. status: ✅ done. completed_date: {today}."
572
807
  })
573
808
  ```
574
- Non-Claude Code: update TRACKER.md inline as before.
809
+ Non-Claude Code: update TRACKER.md, HANDOFF.json, ROADMAP.md inline as before.
575
810
 
576
811
  Rule:
577
812
  - Never defer state updates to end-of-phase only.
@@ -633,15 +868,21 @@ Before phase-level verification, run a UI stub check:
633
868
  | smarttrack-*/pom.xml (8 files) | 1.1 | ← WRONG: glob pattern
634
869
  | smarttrack-*/src/** (7 files) | 1.1 | ← WRONG: summarized
635
870
  ```
636
- 4. Create git tag: `{TAG_PREFIX}-vp-p{phase}-complete` (e.g. `git tag "${TAG_PREFIX}-vp-p${PHASE}-complete"`)
871
+ 4. Create phase-complete git tag — spawn vp-git-agent:
872
+ ```
873
+ Agent({ subagent_type: "vp-git-agent",
874
+ description: "Tag phase {N} complete",
875
+ prompt: "operation: create-tag. tag_name: {TAG_PREFIX}-vp-p{N}-complete."
876
+ })
877
+ ```
637
878
  5. Check version bump needed — apply `.viepilot/SYSTEM-RULES.md → Version Bump Rules`:
638
879
  - Features added → MINOR; Fixes only → PATCH; Mixed → MINOR; Breaking → MAJOR
639
880
 
640
881
  **Version bump — invoke changelog-agent (ENH-057, ENH-053 fix):**
641
882
  ```
642
- Agent({ subagent_type: "general-purpose",
643
- description: "changelog-agent: bump to {version} + CHANGELOG [{version}]",
644
- prompt: "Load agents/changelog-agent.md. Version: {version}. Date: {today}. Entries: {phase_summary_bullets}. Files: package.json + CHANGELOG.md."
883
+ Agent({ subagent_type: "changelog-agent",
884
+ description: "Bump to {version} + CHANGELOG [{version}]",
885
+ prompt: "version: {version}. date: {today}. entries: {phase_summary_bullets}."
645
886
  })
646
887
  ```
647
888
  Non-Claude Code: update CHANGELOG.md + package.json inline as before.
@@ -649,13 +890,22 @@ Before phase-level verification, run a UI stub check:
649
890
  > changelog-agent is the **single authority** for version bumps. Both autonomous.md and
650
891
  > evolve.md invoke it — never do inline version bumps (resolves ENH-053).
651
892
 
652
- 6. Update TRACKER.md
653
- 7. Push all changes:
654
- ```bash
655
- git push
656
- git push --tags
657
- node bin/vp-tools.cjs git-persistence --strict
893
+ 6. Update TRACKER.md current state — spawn tracker-agent:
894
+ ```
895
+ Agent({ subagent_type: "tracker-agent",
896
+ description: "Update TRACKER.md — phase {N} complete",
897
+ prompt: "operation: update-current-state. data: Last completed phase {N} — {phase_name}. version: {version}."
898
+ })
899
+ ```
900
+ 7. Push branch + tags — spawn vp-git-agent:
901
+ ```
902
+ Agent({ subagent_type: "vp-git-agent",
903
+ description: "Push phase {N} complete",
904
+ prompt: "operation: push-all."
905
+ })
658
906
  ```
907
+ Then verify persistence (orchestrator may call this read-only check directly):
908
+ `node bin/vp-tools.cjs git-persistence --strict`
659
909
 
660
910
  ### 5a. Sync ROADMAP.md (after every phase complete)
661
911
 
@@ -5,12 +5,18 @@ Allows research inline within the same brainstorm session when needed.
5
5
 
6
6
  ## Adapter Compatibility
7
7
 
8
- | Feature | Claude Code (terminal) | Cursor (Agent/Skills) | Codex CLI | Antigravity (native) |
9
- |---------|----------------------|-----------------------|-----------|----------------------|
10
- | Interactive prompts | ✅ `AskUserQuestion` tool — **REQUIRED** | ❌ text fallback | ❌ text fallback | ❌ text fallback |
8
+ Detected at session start via `vp-tools detect-adapter` ADAPTER_CONTEXT. Use ADAPTER_CONTEXT.interactive to select prompt mode.
11
9
 
12
- **Claude Code (terminal):** Always call `AskUserQuestion` first. Only fall back to the plain-text menu below if the tool returns an error or is unavailable.
13
- **Cursor / Codex CLI / Antigravity / other adapters:** `AskUserQuestion` not available — use text menus below.
10
+ | Feature | claude-code | cursor-agent | antigravity | codex | copilot |
11
+ |---------|------------|--------------|-------------|-------|---------|
12
+ | Interactive (ADAPTER_CONTEXT.interactive) | `AUQ` | `text` | `none` | `none` | `text` |
13
+ | Prompt tool | `AskUserQuestion` | text list | defaults | defaults | text list |
14
+ | Shell tool | `Bash` | `run_terminal_cmd` | `shell` | `container.exec` | `runCommands` |
15
+
16
+ **Interactive fallback chain** (read from ADAPTER_CONTEXT.interactive):
17
+ 1. `"AUQ"` → call `AskUserQuestion` (preload via ToolSearch first)
18
+ 2. `"text"` → show plain-text numbered list
19
+ 3. `"none"` → proceed with session defaults (log decision)
14
20
 
15
21
  ## ViePilot Skill Scope Policy (BUG-004)
16
22
 
@@ -22,7 +28,24 @@ Allows research inline within the same brainstorm session when needed.
22
28
  <process>
23
29
 
24
30
  <step name="detect_session_language">
25
- ## 0. Detect Session Language (ENH-032)
31
+ ## 0. ADAPTER_CONTEXT Load (FEAT-021)
32
+
33
+ Detect active adapter and inject capability context. All interactive prompts in this workflow
34
+ use ADAPTER_CONTEXT.interactive to select the correct prompt mode.
35
+
36
+ ```bash
37
+ ADAPTER_CONTEXT_JSON=$(node "$HOME/.claude/viepilot/bin/vp-tools.cjs" detect-adapter --json 2>/dev/null \
38
+ || node "$(pwd)/bin/vp-tools.cjs" detect-adapter --json 2>/dev/null \
39
+ || echo '{"adapter":"claude-code","interactive_mode":"AUQ","orchestration":{"parallel":true}}')
40
+ ```
41
+
42
+ Parse `interactive_mode` from JSON:
43
+ - `"AUQ"` → use `AskUserQuestion` tool (preload via ToolSearch first)
44
+ - `"text"` or `"none"` → use plain-text numbered list fallback
45
+
46
+ Silent on error — fallback assumes claude-code defaults. Continue without blocking.
47
+
48
+ ## 0B. Detect Session Language (ENH-032)
26
49
 
27
50
  Read `~/.viepilot/config.json` → set `BRAINSTORM_LANG`:
28
51
  - `BRAINSTORM_LANG` = `language.document` from config (default: `en`)
@@ -254,6 +277,38 @@ If the user chooses to continue:
254
277
  5. If the session already has a **`## Phases`** section: briefly summarize existing phases; all subsequent updates must **merge** into that section (no silent deletion) unless the user explicitly requests narrowing/expanding scope.
255
278
  </step>
256
279
 
280
+ <step name="reference_url_research">
281
+ ### Step 3A: Reference URL Research (ENH-092)
282
+
283
+ **Trigger**: User provides a URL in their brainstorm input (competitor, reference app, documentation site).
284
+
285
+ URL pattern detection: `https?://` present in user message before or during Step 3.
286
+
287
+ When triggered:
288
+ 1. Extract URL from user message
289
+ 2. Dispatch research-agent with browser research op:
290
+ ```js
291
+ Agent({ subagent_type: "research-agent",
292
+ description: "research-agent: browse reference URL for brainstorm context",
293
+ prompt: `op: browse_url. url: "${url}". extract_focus: "features,ux-patterns,pricing,tech-stack". topic: "${sessionTitle}"` })
294
+ ```
295
+ 3. Present findings as `## Reference Research` section in brainstorm output:
296
+ - Key features / capabilities
297
+ - UX patterns observed
298
+ - Pricing model (if applicable)
299
+ - Tech stack clues
300
+ 4. Use findings as context for subsequent brainstorm questions
301
+ 5. If agent-browser not available: attempt WebFetch fallback (static HTML only — warn if empty)
302
+
303
+ **Multiple URLs**: if user provides 2+ URLs, dispatch `compare_products` op:
304
+ ```js
305
+ Agent({ subagent_type: "research-agent",
306
+ prompt: `op: compare_products. urls: ${JSON.stringify(urls)}. topic: "${sessionTitle}"` })
307
+ ```
308
+
309
+ **Non-CC adapters**: skip agent dispatch, use WebFetch directly on the URL.
310
+ </step>
311
+
257
312
  <step name="upgrade_gap_detection">
258
313
  ### Step 3B: Upgrade Gap Detection (ENH-067)
259
314
 
@@ -671,7 +726,7 @@ Map brainstorm UI signal keywords to capability tags:
671
726
  | UI Signal keywords | Capability match |
672
727
  |-------------------|-----------------|
673
728
  | `component`, `layout`, `screen`, `page`, `UI`, `UX` | `ui-generation`, `component-design` |
674
- | `responsive`, `mobile`, `grid` | `responsive-layout` |
729
+ | `responsive`, `mobile`, `grid`, `breakpoint`, `viewport`, `adaptive`, `touch`, `swipe`, `safe-area`, `hamburger` | `responsive-layout` |
675
730
  | `design`, `theme`, `color`, `typography` | `design-system`, `design-tokens` |
676
731
  | `form`, `button`, `input`, `modal` | `component-design` |
677
732
 
@@ -699,6 +754,96 @@ After the session's first UI artifact is generated (or updated), append to `note
699
754
  If `## skills_used` already exists: merge (add new skills, update applied_at).
700
755
  If no skills matched or registry absent: omit `## skills_used` section.
701
756
 
757
+ ### Mobile Design Direction Sub-Phase (ENH-085)
758
+
759
+ **Trigger:** UI Direction Mode is active AND any of these keywords appear in the session:
760
+ `mobile` · `responsive` · `breakpoint` · `viewport` · `adaptive` · `touch` · `swipe`
761
+ `safe-area` · `hamburger` · `tablet` · `phone` · `narrow` · `narrow screen` · `screen size`
762
+
763
+ **When triggered — fire TWO sequential AUQ prompts before HTML generation begins:**
764
+
765
+ **AUQ 1 — Viewport Strategy:**
766
+ ```
767
+ question: "What is the responsive design strategy for this project?"
768
+ options:
769
+ - label: "Mobile-first (Recommended)"
770
+ description: "Base styles target mobile; breakpoints (md:, lg:) scale up. Default for most web apps."
771
+ - label: "Desktop-first"
772
+ description: "Full desktop layout; shrink down with max-width breakpoints."
773
+ - label: "Mobile only"
774
+ description: "No desktop variant needed (PWA, native-style app, mobile-specific tool)."
775
+ - label: "Desktop only"
776
+ description: "Internal tool or dashboard — no mobile support required."
777
+ ```
778
+
779
+ **AUQ 2 — Target Device Scope (multiSelect: true):**
780
+ ```
781
+ question: "Which device types need UI direction?"
782
+ multiSelect: true
783
+ options:
784
+ - label: "Phone (≤767px)"
785
+ description: "Small screens, touch-first, vertical scroll, hamburger nav."
786
+ - label: "Tablet (768–1023px)"
787
+ description: "Medium screens, touch+pointer, hybrid layouts."
788
+ - label: "Desktop (≥1024px)"
789
+ description: "Large screens, pointer-first, dense information layouts."
790
+ - label: "Wide / TV (≥1280px)"
791
+ description: "Very large screens, 3+ column layouts, dashboard displays."
792
+ ```
793
+
794
+ **Store answers as session context:**
795
+ ```yaml
796
+ responsive_strategy: mobile-first | desktop-first | mobile-only | desktop-only
797
+ target_devices: [phone, tablet, desktop, wide] # subset based on AUQ selections
798
+ ```
799
+
800
+ **Fallback (if AUQ not available):** set `responsive_strategy: mobile-first`, `target_devices: [phone, tablet, desktop]` silently.
801
+
802
+ **Skip conditions:**
803
+ - No mobile/responsive keywords in session → skip entirely (non-mobile project)
804
+ - `responsive_strategy` already set in session context (resume) → skip AUQ, reuse stored values
805
+
806
+ **Component Responsive Map in notes.md (ENH-085)**
807
+
808
+ After the Mobile Design Direction AUQ completes (or on session resume with `responsive_strategy` set),
809
+ append a `## Component Responsive Map` section to `notes.md`:
810
+
811
+ ```markdown
812
+ ## Component Responsive Map
813
+
814
+ > ViePilot ENH-085 — Strategy: {responsive_strategy} | Devices: {target_devices joined with ", "}
815
+ > Generated: {date}
816
+
817
+ | Component | Mobile (≤767px) | Tablet (768–1023px) | Desktop (≥1024px) |
818
+ |----------------|------------------------|------------------------|----------------------|
819
+ | Navigation | {mobile_nav} | {tablet_nav} | {desktop_nav} |
820
+ | Layout grid | 1 column, full-width | 2 columns | 3+ columns / sidebar |
821
+ | Data table | Card list (stacked) | Scrollable table | Full table + filters |
822
+ | Modal / dialog | Bottom sheet | Centered dialog | Centered dialog |
823
+ | Forms | Single column | 2-col grouped | 2-col grouped |
824
+ | Buttons (CTA) | Full-width | Auto / inline | Auto / inline |
825
+ | Images / media | 100% width, cropped | 50–75% width | Fixed aspect ratio |
826
+
827
+ ### Navigation Pattern Detail
828
+ - **Mobile**: {mobile_nav_detail}
829
+ - **Tablet**: {tablet_nav_detail}
830
+ - **Desktop**: {desktop_nav_detail}
831
+
832
+ ### Responsive Utilities Reference (Tailwind)
833
+ ```
834
+ Mobile base → no prefix (e.g., flex flex-col p-4)
835
+ Tablet → `md:` prefix (e.g., md:flex-row md:grid-cols-2)
836
+ Desktop → `lg:` prefix (e.g., lg:grid-cols-3 lg:sidebar-fixed)
837
+ Wide → `xl:` prefix (e.g., xl:max-w-7xl xl:px-12)
838
+ ```
839
+ ```
840
+
841
+ Nav values for the table: use Navigation strategy lookup table defined in the per-breakpoint HTML section above.
842
+
843
+ **Guard:** If `notes.md` already contains `## Component Responsive Map` → skip (do not overwrite).
844
+
845
+ **Skip:** If `responsive_strategy` is null (non-mobile session) → omit section entirely.
846
+
702
847
  **Required hook (multi-page only)**
703
848
 
704
849
  When the `pages/` directory exists or any `pages/*.html` is added / renamed / removed:
@@ -707,6 +852,76 @@ When the `pages/` directory exists or any `pages/*.html` is added / renamed / re
707
852
  - Immediately update the **`## Pages inventory`** section in `notes.md` (table: Slug | File | Title | Purpose | Key sections | Nav to) — must match 100% of the current `pages/*.html` file set.
708
853
  - Do not end a topic / do not consider the UI session “synced” if the inventory diverges from files on disk.
709
854
 
855
+ **Per-breakpoint sections in pages/*.html (ENH-085)**
856
+
857
+ When `responsive_strategy` is set (from Mobile Design Direction sub-phase), append a
858
+ `<div class="responsive-breakdown">` section to the bottom of every generated `pages/{slug}.html`:
859
+
860
+ ```html
861
+ <!-- Responsive Breakdown — ViePilot ENH-085 -->
862
+ <div class="responsive-breakdown">
863
+ <h2>Responsive Breakdown</h2>
864
+ <!-- Render only sections for active target_devices -->
865
+
866
+ <!-- Phone section: render when target_devices includes "phone" -->
867
+ <details open>
868
+ <summary>📱 Mobile (≤767px)</summary>
869
+ <div class="breakpoint-notes">
870
+ <p><strong>Layout:</strong> {mobile_layout}</p>
871
+ <p><strong>Navigation:</strong> {mobile_nav}</p>
872
+ <ul>{mobile_key_changes}</ul>
873
+ </div>
874
+ </details>
875
+
876
+ <!-- Tablet section: render when target_devices includes "tablet" -->
877
+ <details>
878
+ <summary>💻 Tablet (768–1023px)</summary>
879
+ <div class="breakpoint-notes">
880
+ <p><strong>Layout:</strong> {tablet_layout}</p>
881
+ <p><strong>Navigation:</strong> {tablet_nav}</p>
882
+ <ul>{tablet_key_changes}</ul>
883
+ </div>
884
+ </details>
885
+
886
+ <!-- Desktop section: render when target_devices includes "desktop" -->
887
+ <details>
888
+ <summary>🖥 Desktop (≥1024px)</summary>
889
+ <div class="breakpoint-notes">
890
+ <p><strong>Layout:</strong> {desktop_layout}</p>
891
+ <p><strong>Navigation:</strong> {desktop_nav}</p>
892
+ </div>
893
+ </details>
894
+ </div>
895
+ ```
896
+
897
+ **`<details open>`** = primary breakpoint (phone if mobile-first, desktop if desktop-first).
898
+
899
+ **Navigation strategy lookup** (infer from page purpose):
900
+
901
+ | Page purpose | Mobile nav | Tablet nav | Desktop nav |
902
+ |---|---|---|---|
903
+ | App / dashboard | Hamburger drawer | Bottom tab bar | Left sidebar |
904
+ | Marketing / landing | Hamburger menu | Hamburger menu | Full horizontal nav |
905
+ | E-commerce | Bottom tab (Home/Search/Cart/Profile) | Tab bar + filters | Full nav + mega menu |
906
+ | Admin / internal | Bottom nav (compact) | Collapsible sidebar | Full left sidebar |
907
+ | Auth (login/signup) | Single-column form | Centered card | Centered card |
908
+ | Content / reader | Bottom nav | Collapsed sidebar | Persistent sidebar |
909
+
910
+ **Skip conditions:**
911
+ - `responsive_strategy` absent → skip block entirely
912
+ - `responsive_strategy: mobile-only` → render Phone section only (no details wrapper needed)
913
+ - `responsive_strategy: desktop-only` → render Desktop section only
914
+
915
+ **CSS to append to shared `style.css`** (once per workspace, not per page):
916
+
917
+ ```css
918
+ /* ENH-085 — Responsive Breakdown */
919
+ .responsive-breakdown{margin-top:2rem;border-top:2px solid #e5e7eb;padding-top:1.5rem}
920
+ .responsive-breakdown details{margin-bottom:1rem;border:1px solid #e5e7eb;border-radius:8px;padding:1rem}
921
+ .responsive-breakdown summary{font-weight:600;cursor:pointer;padding:.25rem 0;user-select:none}
922
+ .breakpoint-notes{padding-top:.75rem}
923
+ ```
924
+
710
925
  3. If the user sends references/components (including 21st.dev prompts/links), record clearly:
711
926
  - reference source
712
927
  - the UI area it applies to (page slug if multi-page)