diff --git a/.claude/commands/workflow/analyze-with-file.md b/.claude/commands/workflow/analyze-with-file.md index 9c05f486..070e7ae9 100644 --- a/.claude/commands/workflow/analyze-with-file.md +++ b/.claude/commands/workflow/analyze-with-file.md @@ -589,7 +589,17 @@ CONSTRAINTS: ${perspective.constraints} if (findings.length) contextLines.push(`**Key Findings**:\n${findings.map(f => `- ${f}`).join('\n')}`) } - // 3. Hand off to lite-plan — analyze-with-file COMPLETE, do NOT return to any analyze phase + // 3. ⛔ SESSION TERMINATION — output explicit boundary + console.log(` +--- +## ⛔ ANALYZE-WITH-FILE SESSION COMPLETE +All Phase 1-4 of analyze-with-file are FINISHED. +Session: ${sessionId} — concluded at ${new Date().toISOString()} +DO NOT reference any analyze-with-file phase instructions beyond this point. +--- +`) + + // 4. Hand off to lite-plan — analyze-with-file COMPLETE, do NOT return to any analyze phase Skill(skill="workflow-lite-planex", args=`"${taskDescription}\n\n${contextLines.join('\n')}"`) return // ⛔ analyze-with-file terminates here } diff --git a/.claude/skills/team-perf-opt/SKILL.md b/.claude/skills/team-perf-opt/SKILL.md index 5eed4180..30d14bc6 100644 --- a/.claude/skills/team-perf-opt/SKILL.md +++ b/.claude/skills/team-perf-opt/SKILL.md @@ -67,24 +67,42 @@ Always route to coordinator. Coordinator reads `roles/coordinator/role.md` and e User just provides task description. -**Invocation**: `Skill(skill="team-perf-opt", args="")` +**Invocation**: +```bash +Skill(skill="team-perf-opt", args="") # auto mode +Skill(skill="team-perf-opt", args="--parallel-mode=fan-out ") # force fan-out +Skill(skill="team-perf-opt", args='--parallel-mode=independent "target1" "target2"') # independent +Skill(skill="team-perf-opt", args="--max-branches=3 ") # limit branches +``` + +**Parallel Modes**: + +| Mode | Description | When to Use | +|------|-------------|------------| +| `auto` (default) | count <= 2 -> single, count >= 3 -> fan-out | General optimization requests | +| `single` | Linear pipeline, no branching | Simple or tightly coupled optimizations | +| `fan-out` | Shared PROFILE+STRATEGY, then N parallel IMPL->BENCH+REVIEW branches | Multiple independent bottlenecks | +| `independent` | M fully independent pipelines from profiling to review | Separate optimization targets | **Lifecycle**: ``` -User provides task description - -> coordinator Phase 1-3: Requirement clarification -> TeamCreate -> Create task chain +User provides task description + optional --parallel-mode / --max-branches + -> coordinator Phase 1-3: Parse flags -> TeamCreate -> Create task chain (mode-aware) -> coordinator Phase 4: spawn first batch workers (background) -> STOP -> Worker (team-worker agent) executes -> SendMessage callback -> coordinator advances - -> Loop until pipeline complete -> Phase 5 report + completion action + -> [auto/fan-out] CP-2.5: Strategy complete -> create N branch tasks -> spawn all IMPL-B* in parallel + -> [independent] All pipelines run in parallel from the start + -> Per-branch/pipeline fix cycles run independently + -> All branches/pipelines complete -> AGGREGATE -> Phase 5 report + completion action ``` **User Commands** (wake paused coordinator): | Command | Action | |---------|--------| -| `check` / `status` | Output execution status graph, no advancement | +| `check` / `status` | Output execution status graph (branch-grouped), no advancement | | `resume` / `continue` | Check worker states, advance next step | -| `revise [feedback]` | Create revision task + cascade downstream | +| `revise [feedback]` | Create revision task + cascade downstream (scoped to branch) | | `feedback ` | Analyze feedback impact, create targeted revision chain | | `recheck` | Re-run quality check | | `improve [dimension]` | Auto-improve weakest dimension | @@ -147,28 +165,52 @@ Execute built-in Phase 1 (task discovery) -> role-spec Phase 2-4 -> built-in Pha ## Pipeline Definitions -### Pipeline Diagram +### Pipeline Diagrams +**Single Mode** (linear, backward compatible): ``` -Pipeline: Linear with Review-Fix Cycle +Pipeline: Single (Linear with Review-Fix Cycle) ===================================================================== Stage 1 Stage 2 Stage 3 Stage 4 -(W:1) (W:2) (W:3) (W:4) - +-----------+ -PROFILE-001 --> STRATEGY-001 --> IMPL-001 --> | BENCH-001 | -[profiler] [strategist] [optimizer] | [bench] | - ^ +-----------+ - | | - | +-----------+ - +<--FIX--->| REVIEW-001| - | | [reviewer]| - | +-----------+ - | | - (max 3 iterations) v +PROFILE-001 --> STRATEGY-001 --> IMPL-001 --> BENCH-001 +[profiler] [strategist] [optimizer] [benchmarker] + ^ | + +<--FIX-001---->+ + | REVIEW-001 + +<--------> [reviewer] + (max 3 iterations) | COMPLETE ===================================================================== ``` +**Fan-out Mode** (shared stages 1-2, parallel branches 3-4): +``` +Pipeline: Fan-out (N parallel optimization branches) +===================================================================== +Stage 1 Stage 2 CP-2.5 Stage 3+4 (per branch) + (branch creation) +PROFILE-001 --> STRATEGY-001 --+-> IMPL-B01 --> BENCH-B01 + REVIEW-B01 (fix cycle) +[profiler] [strategist] | [optimizer] [bench] [reviewer] + +-> IMPL-B02 --> BENCH-B02 + REVIEW-B02 (fix cycle) + | [optimizer] [bench] [reviewer] + +-> IMPL-B0N --> BENCH-B0N + REVIEW-B0N (fix cycle) + | + AGGREGATE -> Phase 5 +===================================================================== +``` + +**Independent Mode** (M fully independent pipelines): +``` +Pipeline: Independent (M complete pipelines) +===================================================================== +Pipeline A: PROFILE-A01 --> STRATEGY-A01 --> IMPL-A01 --> BENCH-A01 + REVIEW-A01 +Pipeline B: PROFILE-B01 --> STRATEGY-B01 --> IMPL-B01 --> BENCH-B01 + REVIEW-B01 +Pipeline C: PROFILE-C01 --> STRATEGY-C01 --> IMPL-C01 --> BENCH-C01 + REVIEW-C01 + | + AGGREGATE -> Phase 5 +===================================================================== +``` + ### Cadence Control **Beat model**: Event-driven, each beat = coordinator wake -> process -> spawn -> STOP. @@ -247,11 +289,14 @@ Beat View: Performance Optimization Pipeline |------------|---------|----------|----------| | CP-1 | PROFILE-001 complete | After Stage 1 | User reviews bottleneck report, can refine scope | | CP-2 | STRATEGY-001 complete | After Stage 2 | User reviews optimization plan, can adjust priorities | -| CP-3 | REVIEW/BENCH fail | Stage 4 | Auto-create FIX task, re-enter Stage 3 (max 3x) | -| CP-4 | All tasks complete | Phase 5 | Interactive completion action | +| CP-2.5 | STRATEGY-001 complete (auto/fan-out) | After Stage 2 | Auto-create N branch tasks from optimization plan, spawn all IMPL-B* in parallel | +| CP-3 | REVIEW/BENCH fail | Stage 4 (per-branch) | Auto-create FIX task for that branch only (max 3x per branch) | +| CP-4 | All tasks/branches complete | Phase 5 | Aggregate results, interactive completion action | ### Task Metadata Registry +**Single mode** (backward compatible): + | Task ID | Role | Phase | Dependencies | Description | |---------|------|-------|-------------|-------------| | PROFILE-001 | profiler | Stage 1 | (none) | Profile application, identify bottlenecks | @@ -261,6 +306,38 @@ Beat View: Performance Optimization Pipeline | REVIEW-001 | reviewer | Stage 4 | IMPL-001 | Review optimization code for correctness | | FIX-001 | optimizer | Stage 3 (cycle) | REVIEW-001 or BENCH-001 | Fix issues found in review/benchmark | +**Fan-out mode** (branch tasks created at CP-2.5): + +| Task ID | Role | Phase | Dependencies | Description | +|---------|------|-------|-------------|-------------| +| PROFILE-001 | profiler | Stage 1 (shared) | (none) | Profile application | +| STRATEGY-001 | strategist | Stage 2 (shared) | PROFILE-001 | Design plan with discrete OPT-IDs | +| IMPL-B{NN} | optimizer | Stage 3 (branch) | STRATEGY-001 | Implement OPT-{NNN} only | +| BENCH-B{NN} | benchmarker | Stage 4 (branch) | IMPL-B{NN} | Benchmark branch B{NN} | +| REVIEW-B{NN} | reviewer | Stage 4 (branch) | IMPL-B{NN} | Review branch B{NN} | +| FIX-B{NN}-{cycle} | optimizer | Fix (branch) | (none) | Fix issues in branch B{NN} | +| BENCH-B{NN}-R{cycle} | benchmarker | Retry (branch) | FIX-B{NN}-{cycle} | Re-benchmark after fix | +| REVIEW-B{NN}-R{cycle} | reviewer | Retry (branch) | FIX-B{NN}-{cycle} | Re-review after fix | + +**Independent mode**: + +| Task ID | Role | Phase | Dependencies | Description | +|---------|------|-------|-------------|-------------| +| PROFILE-{P}01 | profiler | Stage 1 | (none) | Profile for pipeline {P} target | +| STRATEGY-{P}01 | strategist | Stage 2 | PROFILE-{P}01 | Strategy for pipeline {P} | +| IMPL-{P}01 | optimizer | Stage 3 | STRATEGY-{P}01 | Implement pipeline {P} optimizations | +| BENCH-{P}01 | benchmarker | Stage 4 | IMPL-{P}01 | Benchmark pipeline {P} | +| REVIEW-{P}01 | reviewer | Stage 4 | IMPL-{P}01 | Review pipeline {P} | +| FIX-{P}01-{cycle} | optimizer | Fix | (none) | Fix issues in pipeline {P} | + +### Task Naming Rules + +| Mode | Stage 3 | Stage 4 | Fix | Retry | +|------|---------|---------|-----|-------| +| Single | IMPL-001 | BENCH-001, REVIEW-001 | FIX-001 | BENCH-001-R1, REVIEW-001-R1 | +| Fan-out | IMPL-B01 | BENCH-B01, REVIEW-B01 | FIX-B01-1 | BENCH-B01-R1, REVIEW-B01-R1 | +| Independent | IMPL-A01 | BENCH-A01, REVIEW-A01 | FIX-A01-1 | BENCH-A01-R1, REVIEW-A01-R1 | + --- ## Completion Action @@ -292,9 +369,10 @@ AskUserQuestion({ ## Session Directory +**Single mode**: ``` .workflow// -+-- session.json # Session metadata + status ++-- session.json # Session metadata + status + parallel_mode +-- artifacts/ | +-- baseline-metrics.json # Profiler: before-optimization metrics | +-- bottleneck-report.md # Profiler: ranked bottleneck findings @@ -312,6 +390,47 @@ AskUserQuestion({ | +-- DISCUSS-REVIEW.md # Review discussion record ``` +**Fan-out mode** (adds branches/ directory): +``` +.workflow// ++-- session.json # + parallel_mode, branches, fix_cycles ++-- artifacts/ +| +-- baseline-metrics.json # Shared baseline (all branches use this) +| +-- bottleneck-report.md # Shared bottleneck report +| +-- optimization-plan.md # Shared plan with discrete OPT-IDs +| +-- aggregate-results.json # Aggregated results from all branches +| +-- branches/ +| +-- B01/ +| | +-- optimization-detail.md # Extracted OPT-001 detail +| | +-- benchmark-results.json # Branch B01 benchmark +| | +-- review-report.md # Branch B01 review +| +-- B02/ +| | +-- optimization-detail.md +| | +-- benchmark-results.json +| | +-- review-report.md +| +-- B0N/ ++-- explorations/ wisdom/ discussions/ # Same as single +``` + +**Independent mode** (adds pipelines/ directory): +``` +.workflow// ++-- session.json # + parallel_mode, independent_targets, fix_cycles ++-- artifacts/ +| +-- aggregate-results.json # Aggregated results from all pipelines +| +-- pipelines/ +| +-- A/ +| | +-- baseline-metrics.json +| | +-- bottleneck-report.md +| | +-- optimization-plan.md +| | +-- benchmark-results.json +| | +-- review-report.md +| +-- B/ +| +-- baseline-metrics.json +| +-- ... ++-- explorations/ wisdom/ discussions/ # Same as single +``` + ## Session Resume Coordinator supports `--resume` / `--continue` for interrupted sessions: @@ -345,5 +464,11 @@ Coordinator supports `--resume` / `--continue` for interrupted sessions: | team-worker agent unavailable | Error: requires .claude/agents/team-worker.md | | Completion action timeout | Default to Keep Active | | Profiling tool not available | Fallback to static analysis methods | -| Benchmark regression detected | Auto-create FIX task with regression details | -| Review-fix cycle exceeds 3 iterations | Escalate to user with summary of remaining issues | +| Benchmark regression detected | Auto-create FIX task with regression details (scoped to branch/pipeline) | +| Review-fix cycle exceeds 3 iterations | Escalate to user with summary of remaining issues (per-branch/pipeline scope) | +| One branch IMPL fails | Mark that branch failed, other branches continue to completion | +| Branch scope overlap detected | Strategist constrains non-overlapping target files; IMPL logs warning on detection | +| Shared-memory concurrent writes | Each worker writes only its own namespace key (e.g., `optimizer.B01`) | +| Branch fix cycle >= 3 | Escalate only that branch to user, other branches continue independently | +| max_branches exceeded | Coordinator truncates to top N optimizations by priority at CP-2.5 | +| Independent pipeline partial failure | Failed pipeline marked, others continue; aggregate reports partial results | diff --git a/.claude/skills/team-perf-opt/role-specs/benchmarker.md b/.claude/skills/team-perf-opt/role-specs/benchmarker.md index cf6b0623..59cd2fb4 100644 --- a/.claude/skills/team-perf-opt/role-specs/benchmarker.md +++ b/.claude/skills/team-perf-opt/role-specs/benchmarker.md @@ -15,15 +15,30 @@ Run benchmarks comparing before/after optimization metrics. Validate that improv | Input | Source | Required | |-------|--------|----------| -| Baseline metrics | /artifacts/baseline-metrics.json | Yes | -| Optimization plan | /artifacts/optimization-plan.md | Yes | +| Baseline metrics | /artifacts/baseline-metrics.json (shared) | Yes | +| Optimization plan / detail | Varies by mode (see below) | Yes | | shared-memory.json | /wisdom/shared-memory.json | Yes | 1. Extract session path from task description -2. Read baseline metrics -- extract pre-optimization performance numbers -3. Read optimization plan -- extract success criteria and target thresholds -4. Load shared-memory.json for project type and optimization scope -5. Detect available benchmark tools from project: +2. **Detect branch/pipeline context** from task description: + +| Task Description Field | Value | Context | +|----------------------|-------|---------| +| `BranchId: B{NN}` | Present | Fan-out branch -- benchmark only this branch's metrics | +| `PipelineId: {P}` | Present | Independent pipeline -- use pipeline-scoped baseline | +| Neither present | - | Single mode -- full benchmark | + +3. **Load baseline metrics**: + - Single / Fan-out: Read `/artifacts/baseline-metrics.json` (shared baseline) + - Independent: Read `/artifacts/pipelines/{P}/baseline-metrics.json` + +4. **Load optimization context**: + - Single: Read `/artifacts/optimization-plan.md` -- all success criteria + - Fan-out branch: Read `/artifacts/branches/B{NN}/optimization-detail.md` -- only this branch's criteria + - Independent: Read `/artifacts/pipelines/{P}/optimization-plan.md` + +5. Load shared-memory.json for project type and optimization scope +6. Detect available benchmark tools from project: | Signal | Benchmark Tool | Method | |--------|---------------|--------| @@ -34,7 +49,10 @@ Run benchmarks comparing before/after optimization metrics. Validate that improv | Makefile with bench target | Custom benchmarks | make bench | | No tooling detected | Manual measurement | Timed execution via Bash | -6. Get changed files scope from shared-memory (optimizer namespace) +7. Get changed files scope from shared-memory: + - Single: `optimizer` namespace + - Fan-out: `optimizer.B{NN}` namespace + - Independent: `optimizer.{P}` namespace ## Phase 3: Benchmark Execution @@ -60,6 +78,10 @@ Run benchmarks matching detected project type: - Collect post-optimization metrics matching baseline format - Calculate improvement percentages per metric +**Branch-scoped benchmarking** (fan-out mode): +- Only benchmark metrics relevant to this branch's optimization (from optimization-detail.md) +- Still check for regressions across all metrics (not just branch-specific ones) + ## Phase 4: Result Analysis Compare against baseline and plan criteria: @@ -73,13 +95,16 @@ Compare against baseline and plan criteria: | Regression detected | Any unrelated metric degrades > 5% | FAIL -> fix_required | | Plan criteria not met | Any criterion not satisfied | FAIL -> fix_required | -1. Write benchmark results to `/artifacts/benchmark-results.json`: - - Per-metric: name, baseline value, current value, improvement %, verdict - - Overall verdict: PASS / WARN / FAIL - - Regression details (if any) +1. Write benchmark results to output path: + - Single: `/artifacts/benchmark-results.json` + - Fan-out: `/artifacts/branches/B{NN}/benchmark-results.json` + - Independent: `/artifacts/pipelines/{P}/benchmark-results.json` + - Content: Per-metric: name, baseline value, current value, improvement %, verdict; Overall verdict: PASS / WARN / FAIL; Regression details (if any) -2. Update `/wisdom/shared-memory.json` under `benchmarker` namespace: - - Read existing -> merge `{ "benchmarker": { verdict, improvements, regressions } }` -> write back +2. Update `/wisdom/shared-memory.json` under scoped namespace: + - Single: merge `{ "benchmarker": { verdict, improvements, regressions } }` + - Fan-out: merge `{ "benchmarker.B{NN}": { verdict, improvements, regressions } }` + - Independent: merge `{ "benchmarker.{P}": { verdict, improvements, regressions } }` 3. If verdict is FAIL, include detailed feedback in message for FIX task creation: - Which metrics failed, by how much, suggested investigation areas diff --git a/.claude/skills/team-perf-opt/role-specs/optimizer.md b/.claude/skills/team-perf-opt/role-specs/optimizer.md index deed9e39..1b1db039 100644 --- a/.claude/skills/team-perf-opt/role-specs/optimizer.md +++ b/.claude/skills/team-perf-opt/role-specs/optimizer.md @@ -24,17 +24,36 @@ Implement optimization changes following the strategy plan. For FIX tasks, apply | Input | Source | Required | |-------|--------|----------| -| Optimization plan | /artifacts/optimization-plan.md | Yes (IMPL) | +| Optimization plan | /artifacts/optimization-plan.md | Yes (IMPL, no branch) | +| Branch optimization detail | /artifacts/branches/B{NN}/optimization-detail.md | Yes (IMPL with branch) | +| Pipeline optimization plan | /artifacts/pipelines/{P}/optimization-plan.md | Yes (IMPL with pipeline) | | Review/bench feedback | From task description | Yes (FIX) | | shared-memory.json | /wisdom/shared-memory.json | Yes | | Wisdom files | /wisdom/patterns.md | No | | Context accumulator | From prior IMPL/FIX tasks | Yes (inner loop) | 1. Extract session path and task mode (IMPL or FIX) from task description -2. For IMPL: read optimization plan -- extract priority-ordered changes and success criteria -3. For FIX: parse review/benchmark feedback for specific issues to address -4. Use `explore` subagent to load implementation context for target files -5. For inner loop: load context_accumulator from prior IMPL/FIX tasks to avoid re-reading +2. **Detect branch/pipeline context** from task description: + +| Task Description Field | Value | Context | +|----------------------|-------|---------| +| `BranchId: B{NN}` | Present | Fan-out branch -- load single optimization detail | +| `PipelineId: {P}` | Present | Independent pipeline -- load pipeline-scoped plan | +| Neither present | - | Single mode -- load full optimization plan | + +3. **Load optimization context by mode**: + - **Single mode (no branch)**: Read `/artifacts/optimization-plan.md` -- extract ALL priority-ordered changes + - **Fan-out branch**: Read `/artifacts/branches/B{NN}/optimization-detail.md` -- extract ONLY this branch's optimization (single OPT-ID) + - **Independent pipeline**: Read `/artifacts/pipelines/{P}/optimization-plan.md` -- extract this pipeline's plan + +4. For FIX: parse review/benchmark feedback for specific issues to address +5. Use `explore` subagent to load implementation context for target files +6. For inner loop (single mode only): load context_accumulator from prior IMPL/FIX tasks + +**Shared-memory namespace**: +- Single: write to `optimizer` namespace +- Fan-out: write to `optimizer.B{NN}` namespace +- Independent: write to `optimizer.{P}` namespace ## Phase 3: Code Implementation @@ -46,7 +65,9 @@ Implementation backend selection: | Direct | Single-file changes or targeted fixes | Inline Edit/Write tools | For IMPL tasks: -- Apply optimizations in plan priority order (P0 first, then P1, etc.) +- **Single mode**: Apply optimizations in plan priority order (P0 first, then P1, etc.) +- **Fan-out branch**: Apply ONLY this branch's single optimization (from optimization-detail.md) +- **Independent pipeline**: Apply this pipeline's optimizations in priority order - Follow implementation guidance from plan (target files, patterns) - Preserve existing behavior -- optimization must not break functionality @@ -71,6 +92,11 @@ General rules: If validation fails, attempt auto-fix (max 2 attempts) before reporting error. -Append to context_accumulator for next IMPL/FIX task: +Append to context_accumulator for next IMPL/FIX task (single/inner-loop mode only): - Files modified, optimizations applied, validation results - Any discovered patterns or caveats for subsequent iterations + +**Branch output paths**: +- Single: write artifacts to `/artifacts/` +- Fan-out: write artifacts to `/artifacts/branches/B{NN}/` +- Independent: write artifacts to `/artifacts/pipelines/{P}/` diff --git a/.claude/skills/team-perf-opt/role-specs/reviewer.md b/.claude/skills/team-perf-opt/role-specs/reviewer.md index 075ed943..787aa283 100644 --- a/.claude/skills/team-perf-opt/role-specs/reviewer.md +++ b/.claude/skills/team-perf-opt/role-specs/reviewer.md @@ -19,15 +19,34 @@ Review optimization code changes for correctness, side effects, regression risks | Input | Source | Required | |-------|--------|----------| | Optimization code changes | From IMPL task artifacts / git diff | Yes | -| Optimization plan | /artifacts/optimization-plan.md | Yes | -| Benchmark results | /artifacts/benchmark-results.json | No | +| Optimization plan / detail | Varies by mode (see below) | Yes | +| Benchmark results | Varies by mode (see below) | No | | shared-memory.json | /wisdom/shared-memory.json | Yes | 1. Extract session path from task description -2. Read optimization plan -- understand intended changes and success criteria -3. Load shared-memory.json for optimizer namespace (files modified, patterns applied) -4. Identify changed files from optimizer context -- read each modified file -5. If benchmark results available, read for cross-reference with code quality +2. **Detect branch/pipeline context** from task description: + +| Task Description Field | Value | Context | +|----------------------|-------|---------| +| `BranchId: B{NN}` | Present | Fan-out branch -- review only this branch's changes | +| `PipelineId: {P}` | Present | Independent pipeline -- review pipeline-scoped changes | +| Neither present | - | Single mode -- review all optimization changes | + +3. **Load optimization context by mode**: + - Single: Read `/artifacts/optimization-plan.md` + - Fan-out branch: Read `/artifacts/branches/B{NN}/optimization-detail.md` + - Independent: Read `/artifacts/pipelines/{P}/optimization-plan.md` + +4. Load shared-memory.json for scoped optimizer namespace: + - Single: `optimizer` namespace + - Fan-out: `optimizer.B{NN}` namespace + - Independent: `optimizer.{P}` namespace + +5. Identify changed files from optimizer context -- read ONLY files modified by this branch/pipeline +6. If benchmark results available, read from scoped path: + - Single: `/artifacts/benchmark-results.json` + - Fan-out: `/artifacts/branches/B{NN}/benchmark-results.json` + - Independent: `/artifacts/pipelines/{P}/benchmark-results.json` ## Phase 3: Multi-Dimension Review @@ -58,12 +77,15 @@ Classify overall verdict based on findings: | REVISE | Has High findings, no Critical | Send fix_required with detailed feedback | | REJECT | Has Critical findings or fundamental approach flaw | Send fix_required + flag for strategist escalation | -1. Write review report to `/artifacts/review-report.md`: - - Per-dimension findings with severity, file:line, description - - Overall verdict with rationale - - Specific fix instructions for REVISE/REJECT verdicts +1. Write review report to scoped output path: + - Single: `/artifacts/review-report.md` + - Fan-out: `/artifacts/branches/B{NN}/review-report.md` + - Independent: `/artifacts/pipelines/{P}/review-report.md` + - Content: Per-dimension findings with severity, file:line, description; Overall verdict with rationale; Specific fix instructions for REVISE/REJECT verdicts -2. Update `/wisdom/shared-memory.json` under `reviewer` namespace: - - Read existing -> merge `{ "reviewer": { verdict, finding_count, critical_count, dimensions_reviewed } }` -> write back +2. Update `/wisdom/shared-memory.json` under scoped namespace: + - Single: merge `{ "reviewer": { verdict, finding_count, critical_count, dimensions_reviewed } }` + - Fan-out: merge `{ "reviewer.B{NN}": { verdict, finding_count, critical_count, dimensions_reviewed } }` + - Independent: merge `{ "reviewer.{P}": { verdict, finding_count, critical_count, dimensions_reviewed } }` -3. If DISCUSS-REVIEW was triggered, record discussion summary in `/discussions/DISCUSS-REVIEW.md` +3. If DISCUSS-REVIEW was triggered, record discussion summary in `/discussions/DISCUSS-REVIEW.md` (or `DISCUSS-REVIEW-B{NN}.md` for branch-scoped discussions) diff --git a/.claude/skills/team-perf-opt/role-specs/strategist.md b/.claude/skills/team-perf-opt/role-specs/strategist.md index 946332b0..98ee5172 100644 --- a/.claude/skills/team-perf-opt/role-specs/strategist.md +++ b/.claude/skills/team-perf-opt/role-specs/strategist.md @@ -62,12 +62,53 @@ Define measurable success criteria per optimization (target metric value or impr ## Phase 4: Plan Output 1. Write optimization plan to `/artifacts/optimization-plan.md`: - - Priority-ordered list of optimizations - - Per optimization: target bottleneck, strategy, expected improvement %, risk level - - Success criteria: specific metric thresholds to verify - - Implementation guidance: files to modify, patterns to apply + + Each optimization MUST have a unique OPT-ID and self-contained detail block: + + ```markdown + ### OPT-001: + - Priority: P0 + - Target bottleneck: <bottleneck from report> + - Target files: <file-list> + - Strategy: <selected approach> + - Expected improvement: <metric> by <X%> + - Risk level: <Low/Medium/High> + - Success criteria: <specific threshold to verify> + - Implementation guidance: + 1. <step 1> + 2. <step 2> + 3. <step 3> + + ### OPT-002: <title> + ... + ``` + + Requirements: + - Each OPT-ID is sequentially numbered (OPT-001, OPT-002, ...) + - Each optimization must be **non-overlapping** in target files (no two OPT-IDs modify the same file unless explicitly noted with conflict resolution) + - Implementation guidance must be self-contained -- a branch optimizer should be able to work from a single OPT block without reading others 2. Update `<session>/wisdom/shared-memory.json` under `strategist` namespace: - - Read existing -> merge `{ "strategist": { complexity, optimization_count, priorities, discuss_used } }` -> write back + - Read existing -> merge -> write back: + ```json + { + "strategist": { + "complexity": "<Low|Medium|High>", + "optimization_count": 4, + "priorities": ["P0", "P0", "P1", "P2"], + "discuss_used": false, + "optimizations": [ + { + "id": "OPT-001", + "title": "<title>", + "priority": "P0", + "target_files": ["src/a.ts", "src/b.ts"], + "expected_improvement": "<metric> by <X%>", + "success_criteria": "<threshold>" + } + ] + } + } + ``` 3. If DISCUSS-OPT was triggered, record discussion summary in `<session>/discussions/DISCUSS-OPT.md` diff --git a/.claude/skills/team-perf-opt/roles/coordinator/commands/dispatch.md b/.claude/skills/team-perf-opt/roles/coordinator/commands/dispatch.md index 840082f2..b270b653 100644 --- a/.claude/skills/team-perf-opt/roles/coordinator/commands/dispatch.md +++ b/.claude/skills/team-perf-opt/roles/coordinator/commands/dispatch.md @@ -1,6 +1,6 @@ # Command: Dispatch -Create the performance optimization task chain with correct dependencies and structured task descriptions. +Create the performance optimization task chain with correct dependencies and structured task descriptions. Supports single, fan-out, independent, and auto parallel modes. ## Phase 2: Context Loading @@ -9,12 +9,16 @@ Create the performance optimization task chain with correct dependencies and str | User requirement | From coordinator Phase 1 | Yes | | Session folder | From coordinator Phase 2 | Yes | | Pipeline definition | From SKILL.md Pipeline Definitions | Yes | +| Parallel mode | From session.json `parallel_mode` | Yes | +| Max branches | From session.json `max_branches` | Yes | +| Independent targets | From session.json `independent_targets` (independent mode only) | Conditional | 1. Load user requirement and optimization scope from session.json 2. Load pipeline stage definitions from SKILL.md Task Metadata Registry -3. Determine if single-pass or multi-pass optimization is needed +3. Read `parallel_mode` and `max_branches` from session.json +4. For `independent` mode: read `independent_targets` array from session.json -## Phase 3: Task Chain Creation +## Phase 3: Task Chain Creation (Mode-Branched) ### Task Description Template @@ -32,20 +36,33 @@ TASK: CONTEXT: - Session: <session-folder> - Scope: <optimization-scope> + - Branch: <branch-id or 'none'> - Upstream artifacts: <artifact-1>, <artifact-2> - Shared memory: <session>/wisdom/shared-memory.json EXPECTED: <deliverable path> + <quality criteria> CONSTRAINTS: <scope limits, focus areas> --- -InnerLoop: <true|false>", +InnerLoop: <true|false> +BranchId: <B01|A|none>", blockedBy: [<dependency-list>], status: "pending" }) ``` -### Task Chain +### Mode Router -Create tasks in dependency order: +| Mode | Action | +|------|--------| +| `single` | Create 5 tasks (PROFILE → STRATEGY → IMPL → BENCH + REVIEW) -- unchanged from linear pipeline | +| `auto` | Create PROFILE-001 + STRATEGY-001 only. **Defer branch creation to CP-2.5** after strategy completes | +| `fan-out` | Create PROFILE-001 + STRATEGY-001 only. **Defer branch creation to CP-2.5** after strategy completes | +| `independent` | Create M complete pipelines immediately (one per target) | + +--- + +### Single Mode Task Chain + +Create tasks in dependency order (backward compatible, unchanged): **PROFILE-001** (profiler, Stage 1): ``` @@ -59,6 +76,7 @@ TASK: CONTEXT: - Session: <session-folder> - Scope: <optimization-scope> + - Branch: none - Shared memory: <session>/wisdom/shared-memory.json EXPECTED: <session>/artifacts/baseline-metrics.json + <session>/artifacts/bottleneck-report.md | Quantified metrics with evidence CONSTRAINTS: Focus on <optimization-scope> | Profile before any changes @@ -77,13 +95,15 @@ TASK: - Analyze bottleneck report and baseline metrics - Select optimization strategies per bottleneck type - Prioritize by impact/effort ratio, define success criteria + - Each optimization MUST have a unique OPT-ID (OPT-001, OPT-002, ...) with non-overlapping target files CONTEXT: - Session: <session-folder> - Scope: <optimization-scope> + - Branch: none - Upstream artifacts: baseline-metrics.json, bottleneck-report.md - Shared memory: <session>/wisdom/shared-memory.json -EXPECTED: <session>/artifacts/optimization-plan.md | Priority-ordered with improvement targets -CONSTRAINTS: Focus on highest-impact optimizations | Risk assessment required +EXPECTED: <session>/artifacts/optimization-plan.md | Priority-ordered with improvement targets, discrete OPT-IDs +CONSTRAINTS: Focus on highest-impact optimizations | Risk assessment required | Non-overlapping file targets per OPT-ID --- InnerLoop: false", blockedBy: ["PROFILE-001"], @@ -103,6 +123,7 @@ TASK: CONTEXT: - Session: <session-folder> - Scope: <optimization-scope> + - Branch: none - Upstream artifacts: optimization-plan.md - Shared memory: <session>/wisdom/shared-memory.json EXPECTED: Modified source files + validation passing | Optimizations applied without regressions @@ -126,6 +147,7 @@ TASK: CONTEXT: - Session: <session-folder> - Scope: <optimization-scope> + - Branch: none - Upstream artifacts: baseline-metrics.json, optimization-plan.md - Shared memory: <session>/wisdom/shared-memory.json EXPECTED: <session>/artifacts/benchmark-results.json | Per-metric comparison with verdicts @@ -149,6 +171,7 @@ TASK: CONTEXT: - Session: <session-folder> - Scope: <optimization-scope> + - Branch: none - Upstream artifacts: optimization-plan.md, benchmark-results.json (if available) - Shared memory: <session>/wisdom/shared-memory.json EXPECTED: <session>/artifacts/review-report.md | Per-dimension findings with severity @@ -160,16 +183,190 @@ InnerLoop: false", }) ``` +--- + +### Auto / Fan-out Mode Task Chain (Deferred Branching) + +For `auto` and `fan-out` modes, create only shared stages now. Branch tasks are created at **CP-2.5** after STRATEGY-001 completes. + +Create PROFILE-001 and STRATEGY-001 with same templates as single mode above. + +**Do NOT create IMPL/BENCH/REVIEW tasks yet.** They are created by the CP-2.5 Branch Creation subroutine in monitor.md. + +--- + +### Independent Mode Task Chain + +For `independent` mode, create M complete pipelines -- one per target in `independent_targets` array. + +Pipeline prefix chars: `A, B, C, D, E, F, G, H, I, J` (from config `pipeline_prefix_chars`). + +For each target index `i` (0-based), with prefix char `P = pipeline_prefix_chars[i]`: + +``` +// Create session subdirectory for this pipeline +Bash("mkdir -p <session>/artifacts/pipelines/<P>") + +TaskCreate({ subject: "PROFILE-<P>01", ... }) // blockedBy: [] +TaskCreate({ subject: "STRATEGY-<P>01", ... }) // blockedBy: ["PROFILE-<P>01"] +TaskCreate({ subject: "IMPL-<P>01", ... }) // blockedBy: ["STRATEGY-<P>01"] +TaskCreate({ subject: "BENCH-<P>01", ... }) // blockedBy: ["IMPL-<P>01"] +TaskCreate({ subject: "REVIEW-<P>01", ... }) // blockedBy: ["IMPL-<P>01"] +``` + +Task descriptions follow same template as single mode, with additions: +- `Branch: <P>` in CONTEXT +- Artifact paths use `<session>/artifacts/pipelines/<P>/` instead of `<session>/artifacts/` +- Shared-memory namespace uses `<role>.<P>` (e.g., `profiler.A`, `optimizer.B`) +- Each pipeline's scope is its specific target from `independent_targets[i]` + +Example for pipeline A with target "optimize rendering": +``` +TaskCreate({ + subject: "PROFILE-A01", + description: "PURPOSE: Profile rendering performance | Success: Rendering bottlenecks identified +TASK: + - Detect project type and available profiling tools + - Execute profiling focused on rendering performance + - Collect baseline metrics and rank rendering bottlenecks +CONTEXT: + - Session: <session-folder> + - Scope: optimize rendering + - Pipeline: A + - Shared memory: <session>/wisdom/shared-memory.json (namespace: profiler.A) +EXPECTED: <session>/artifacts/pipelines/A/baseline-metrics.json + bottleneck-report.md +CONSTRAINTS: Focus on rendering scope +--- +InnerLoop: false +PipelineId: A", + status: "pending" +}) +``` + +--- + +### CP-2.5: Branch Creation Subroutine + +**Triggered by**: monitor.md handleCallback when STRATEGY-001 completes in `auto` or `fan-out` mode. + +**Procedure**: + +1. Read `<session>/artifacts/optimization-plan.md` to count OPT-IDs +2. Read `shared-memory.json` -> `strategist.optimization_count` +3. **Auto mode decision**: + +| Optimization Count | Decision | +|-------------------|----------| +| count <= 2 | Switch to `single` mode -- create IMPL-001, BENCH-001, REVIEW-001 (standard single pipeline) | +| count >= 3 | Switch to `fan-out` mode -- create branch tasks below | + +4. Update session.json with resolved `parallel_mode` (auto -> single or fan-out) + +5. **Fan-out branch creation** (when count >= 3 or forced fan-out): + - Truncate to `max_branches` if `optimization_count > max_branches` (keep top N by priority) + - For each optimization `i` (1-indexed), branch ID = `B{NN}` where NN = zero-padded i: + +``` +// Create branch artifact directory +Bash("mkdir -p <session>/artifacts/branches/B{NN}") + +// Extract single OPT detail to branch +Write("<session>/artifacts/branches/B{NN}/optimization-detail.md", + extracted OPT-{NNN} block from optimization-plan.md) +``` + +6. Create branch tasks for each branch B{NN}: + +``` +TaskCreate({ + subject: "IMPL-B{NN}", + description: "PURPOSE: Implement optimization OPT-{NNN} | Success: Single optimization applied, compiles, tests pass +TASK: + - Load optimization detail from branches/B{NN}/optimization-detail.md + - Apply this single optimization to target files + - Validate changes compile and pass existing tests +CONTEXT: + - Session: <session-folder> + - Branch: B{NN} + - Upstream artifacts: branches/B{NN}/optimization-detail.md + - Shared memory: <session>/wisdom/shared-memory.json (namespace: optimizer.B{NN}) +EXPECTED: Modified source files for OPT-{NNN} only +CONSTRAINTS: Only implement this branch's optimization | Do not touch files outside OPT-{NNN} scope +--- +InnerLoop: false +BranchId: B{NN}", + blockedBy: ["STRATEGY-001"], + status: "pending" +}) + +TaskCreate({ + subject: "BENCH-B{NN}", + description: "PURPOSE: Benchmark branch B{NN} optimization | Success: OPT-{NNN} metrics meet success criteria +TASK: + - Load baseline metrics and OPT-{NNN} success criteria + - Benchmark only metrics relevant to this optimization + - Compare against baseline, calculate improvement +CONTEXT: + - Session: <session-folder> + - Branch: B{NN} + - Upstream artifacts: baseline-metrics.json, branches/B{NN}/optimization-detail.md + - Shared memory: <session>/wisdom/shared-memory.json (namespace: benchmarker.B{NN}) +EXPECTED: <session>/artifacts/branches/B{NN}/benchmark-results.json +CONSTRAINTS: Only benchmark this branch's metrics +--- +InnerLoop: false +BranchId: B{NN}", + blockedBy: ["IMPL-B{NN}"], + status: "pending" +}) + +TaskCreate({ + subject: "REVIEW-B{NN}", + description: "PURPOSE: Review branch B{NN} optimization code | Success: Code quality verified for OPT-{NNN} +TASK: + - Load modified files from optimizer.B{NN} shared-memory namespace + - Review across 5 dimensions for this branch's changes only + - Issue verdict: APPROVE, REVISE, or REJECT +CONTEXT: + - Session: <session-folder> + - Branch: B{NN} + - Upstream artifacts: branches/B{NN}/optimization-detail.md + - Shared memory: <session>/wisdom/shared-memory.json (namespace: reviewer.B{NN}) +EXPECTED: <session>/artifacts/branches/B{NN}/review-report.md +CONSTRAINTS: Only review this branch's changes +--- +InnerLoop: false +BranchId: B{NN}", + blockedBy: ["IMPL-B{NN}"], + status: "pending" +}) +``` + +7. Update session.json: + - `branches`: array of branch IDs (["B01", "B02", ...]) + - `fix_cycles`: object keyed by branch ID, all initialized to 0 + +--- + ## Phase 4: Validation Verify task chain integrity: | Check | Method | Expected | |-------|--------|----------| -| All 5 tasks created | TaskList count | 5 tasks | -| Dependencies correct | STRATEGY blocks on PROFILE, IMPL blocks on STRATEGY, BENCH+REVIEW block on IMPL | All valid | +| Task count correct | TaskList count | single: 5, auto/fan-out: 2 (pre-CP-2.5), independent: 5*M | +| Dependencies correct | Trace dependency graph | Acyclic, correct blockedBy | | No circular dependencies | Trace dependency graph | Acyclic | -| All task IDs use correct prefixes | PROFILE-*, STRATEGY-*, IMPL-*, BENCH-*, REVIEW-* | Match role registry | +| Task IDs use correct prefixes | Pattern check | Match naming rules per mode | | Structured descriptions complete | Each has PURPOSE/TASK/CONTEXT/EXPECTED/CONSTRAINTS | All present | +| Branch/Pipeline IDs consistent | Cross-check with session.json | Match | + +### Naming Rules Summary + +| Mode | Stage 3 | Stage 4 | Fix | +|------|---------|---------|-----| +| Single | IMPL-001 | BENCH-001, REVIEW-001 | FIX-001, FIX-002 | +| Fan-out | IMPL-B01 | BENCH-B01, REVIEW-B01 | FIX-B01-1, FIX-B01-2 | +| Independent | IMPL-A01 | BENCH-A01, REVIEW-A01 | FIX-A01-1, FIX-A01-2 | If validation fails, fix the specific task and re-validate. diff --git a/.claude/skills/team-perf-opt/roles/coordinator/commands/monitor.md b/.claude/skills/team-perf-opt/roles/coordinator/commands/monitor.md index 8c2860b0..1b1edac9 100644 --- a/.claude/skills/team-perf-opt/roles/coordinator/commands/monitor.md +++ b/.claude/skills/team-perf-opt/roles/coordinator/commands/monitor.md @@ -1,6 +1,6 @@ # Command: Monitor -Handle all coordinator monitoring events: worker callbacks, status checks, pipeline advancement, and completion. +Handle all coordinator monitoring events: worker callbacks, status checks, pipeline advancement, and completion. Supports single, fan-out, and independent parallel modes with per-branch/pipeline tracking. ## Phase 2: Context Loading @@ -11,7 +11,7 @@ Handle all coordinator monitoring events: worker callbacks, status checks, pipel | Trigger event | From Entry Router detection | Yes | | Pipeline definition | From SKILL.md | Yes | -1. Load session.json for current state and fix cycle count +1. Load session.json for current state, `parallel_mode`, `branches`, `fix_cycles` 2. Run TaskList() to get current task statuses 3. Identify trigger event type from Entry Router @@ -21,7 +21,14 @@ Handle all coordinator monitoring events: worker callbacks, status checks, pipel Triggered when a worker sends completion message. -1. Parse message to identify role and task ID +1. Parse message to identify role, task ID, and **branch/pipeline label**: + +| Message Pattern | Branch Detection | +|----------------|-----------------| +| `[optimizer-B01]` or task ID `IMPL-B01` | Branch `B01` (fan-out) | +| `[profiler-A]` or task ID `PROFILE-A01` | Pipeline `A` (independent) | +| `[profiler]` or task ID `PROFILE-001` | No branch (single) | + 2. Mark task as completed: ``` @@ -29,15 +36,23 @@ TaskUpdate({ taskId: "<task-id>", status: "completed" }) ``` 3. Record completion in session state -4. Check if checkpoint feedback is configured for this stage: + +4. **CP-2.5 check** (auto/fan-out mode only): + - If completed task is STRATEGY-001 AND `parallel_mode` is `auto` or `fan-out`: + - Execute **CP-2.5 Branch Creation** subroutine from dispatch.md + - After branch creation, proceed to handleSpawnNext (spawns all IMPL-B* in parallel) + - STOP after spawning + +5. Check if checkpoint feedback is configured for this stage: | Completed Task | Checkpoint | Action | |---------------|------------|--------| -| PROFILE-001 | CP-1 | Notify user: bottleneck report ready for review | -| STRATEGY-001 | CP-2 | Notify user: optimization plan ready for review | -| BENCH-001 or REVIEW-001 | CP-3 | Check verdicts (see Review-Fix Cycle below) | +| PROFILE-001 / PROFILE-{P}01 | CP-1 | Notify user: bottleneck report ready for review | +| STRATEGY-001 / STRATEGY-{P}01 | CP-2 | Notify user: optimization plan ready for review | +| STRATEGY-001 (auto/fan-out) | CP-2.5 | Execute branch creation, then notify user with branch count | +| BENCH-* or REVIEW-* | CP-3 | Check verdicts per branch (see Review-Fix Cycle below) | -5. Proceed to handleSpawnNext +6. Proceed to handleSpawnNext ### handleSpawnNext @@ -70,11 +85,23 @@ Execute built-in Phase 1 -> role-spec Phase 2-4 -> built-in Phase 5.` }) ``` -3. For Stage 4 (BENCH-001 + REVIEW-001): spawn both in parallel since both block on IMPL-001 +3. **Parallel spawn rules by mode**: + +| Mode | Scenario | Spawn Behavior | +|------|----------|---------------| +| Single | Stage 4 ready | Spawn BENCH-001 + REVIEW-001 in parallel | +| Fan-out (CP-2.5 done) | All IMPL-B* unblocked | Spawn ALL IMPL-B* in parallel | +| Fan-out (IMPL-B{NN} done) | BENCH-B{NN} + REVIEW-B{NN} ready | Spawn both for that branch in parallel | +| Independent | Any unblocked task | Spawn all ready tasks across all pipelines in parallel | + 4. STOP after spawning -- wait for next callback ### Review-Fix Cycle (CP-3) +**Per-branch/pipeline scoping**: Each branch/pipeline has its own independent fix cycle. + +#### Single Mode (unchanged) + When both BENCH-001 and REVIEW-001 are completed: 1. Read benchmark verdict from shared-memory (benchmarker namespace) @@ -88,45 +115,89 @@ When both BENCH-001 and REVIEW-001 are completed: | FAIL | REVISE/REJECT | Create FIX task with combined feedback | | Any | REJECT | Create FIX task + flag for strategist re-evaluation | -3. Check fix cycle count: +#### Fan-out Mode (per-branch) + +When both BENCH-B{NN} and REVIEW-B{NN} are completed for a specific branch: + +1. Read benchmark verdict from `benchmarker.B{NN}` namespace +2. Read review verdict from `reviewer.B{NN}` namespace +3. Apply same verdict matrix as single mode, but scoped to this branch only +4. **Other branches are unaffected** -- they continue independently + +#### Independent Mode (per-pipeline) + +When both BENCH-{P}01 and REVIEW-{P}01 are completed for a specific pipeline: + +1. Read verdicts from `benchmarker.{P}` and `reviewer.{P}` namespaces +2. Apply same verdict matrix, scoped to this pipeline only + +#### Fix Cycle Count Tracking + +Fix cycles are tracked per branch/pipeline in `session.json`: + +```json +// Single mode +{ "fix_cycles": { "main": 0 } } + +// Fan-out mode +{ "fix_cycles": { "B01": 0, "B02": 1, "B03": 0 } } + +// Independent mode +{ "fix_cycles": { "A": 0, "B": 2 } } +``` | Cycle Count | Action | |-------------|--------| -| < 3 | Create FIX task, increment cycle count | -| >= 3 | Escalate to user with summary of remaining issues | +| < 3 | Create FIX task, increment cycle count for this branch/pipeline | +| >= 3 | Escalate THIS branch/pipeline to user. Other branches continue | -4. Create FIX task if needed: +#### FIX Task Creation (branched) +**Fan-out mode**: ``` TaskCreate({ - subject: "FIX-<N>", - description: "PURPOSE: Fix issues identified by review/benchmark | Success: All flagged issues resolved + subject: "FIX-B{NN}-{cycle}", + description: "PURPOSE: Fix issues in branch B{NN} from review/benchmark | Success: All flagged issues resolved TASK: - Address review findings: <specific-findings> - Fix benchmark regressions: <specific-regressions> - Re-validate after fixes CONTEXT: - Session: <session-folder> - - Upstream artifacts: review-report.md, benchmark-results.json - - Shared memory: <session>/wisdom/shared-memory.json -EXPECTED: Fixed source files | All flagged issues addressed -CONSTRAINTS: Targeted fixes only | Do not introduce new changes + - Branch: B{NN} + - Upstream artifacts: branches/B{NN}/review-report.md, branches/B{NN}/benchmark-results.json + - Shared memory: <session>/wisdom/shared-memory.json (namespace: optimizer.B{NN}) +EXPECTED: Fixed source files for B{NN} only +CONSTRAINTS: Targeted fixes only | Do not touch other branches --- -InnerLoop: true", +InnerLoop: false +BranchId: B{NN}", blockedBy: [], status: "pending" }) ``` -5. Create new BENCH and REVIEW tasks blocked on FIX task -6. Proceed to handleSpawnNext (spawns optimizer for FIX task) +Create new BENCH and REVIEW with retry suffix: +- `BENCH-B{NN}-R{cycle}` blocked on `FIX-B{NN}-{cycle}` +- `REVIEW-B{NN}-R{cycle}` blocked on `FIX-B{NN}-{cycle}` + +**Independent mode**: +``` +TaskCreate({ + subject: "FIX-{P}01-{cycle}", + ...same pattern with pipeline prefix... + blockedBy: [], + status: "pending" +}) +``` + +Create `BENCH-{P}01-R{cycle}` and `REVIEW-{P}01-R{cycle}`. ### handleCheck -Output current pipeline status without advancing. - -1. Build status graph from task list: +Output current pipeline status grouped by branch/pipeline. +**Single mode** (unchanged): ``` Pipeline Status: [DONE] PROFILE-001 (profiler) -> bottleneck-report.md @@ -139,7 +210,47 @@ Fix Cycles: 0/3 Session: <session-id> ``` -2. Output status -- do NOT advance pipeline +**Fan-out mode**: +``` +Pipeline Status (fan-out, 3 branches): + Shared Stages: + [DONE] PROFILE-001 (profiler) -> bottleneck-report.md + [DONE] STRATEGY-001 (strategist) -> optimization-plan.md (4 OPT-IDs) + + Branch B01 (OPT-001: <title>): + [RUN] IMPL-B01 (optimizer) -> implementing... + [WAIT] BENCH-B01 (benchmarker) -> blocked by IMPL-B01 + [WAIT] REVIEW-B01 (reviewer) -> blocked by IMPL-B01 + Fix Cycles: 0/3 + + Branch B02 (OPT-002: <title>): + [DONE] IMPL-B02 (optimizer) -> done + [RUN] BENCH-B02 (benchmarker) -> benchmarking... + [RUN] REVIEW-B02 (reviewer) -> reviewing... + Fix Cycles: 0/3 + + Branch B03 (OPT-003: <title>): + [FAIL] IMPL-B03 (optimizer) -> failed + Fix Cycles: 0/3 [BRANCH FAILED] + +Session: <session-id> +``` + +**Independent mode**: +``` +Pipeline Status (independent, 2 pipelines): + Pipeline A (target: optimize rendering): + [DONE] PROFILE-A01 -> [DONE] STRATEGY-A01 -> [RUN] IMPL-A01 -> ... + Fix Cycles: 0/3 + + Pipeline B (target: optimize API): + [DONE] PROFILE-B01 -> [DONE] STRATEGY-B01 -> [DONE] IMPL-B01 -> ... + Fix Cycles: 1/3 + +Session: <session-id> +``` + +Output status -- do NOT advance pipeline. ### handleResume @@ -148,7 +259,8 @@ Resume pipeline after user pause or interruption. 1. Audit task list for inconsistencies: - Tasks stuck in "in_progress" -> reset to "pending" - Tasks with completed blockers but still "pending" -> include in spawn list -2. Proceed to handleSpawnNext +2. For fan-out/independent: check each branch/pipeline independently +3. Proceed to handleSpawnNext ### handleConsensus @@ -156,46 +268,65 @@ Handle consensus_blocked signals from discuss rounds. | Severity | Action | |----------|--------| -| HIGH | Pause pipeline, notify user with findings summary | -| MEDIUM | Create revision task for the blocked role | +| HIGH | Pause pipeline (or branch), notify user with findings summary | +| MEDIUM | Create revision task for the blocked role (scoped to branch if applicable) | | LOW | Log finding, continue pipeline | ### handleComplete Triggered when all pipeline tasks are completed and no fix cycles remain. -1. Verify all tasks have status "completed": +**Completion check varies by mode**: -``` -TaskList() -``` +| Mode | Completion Condition | +|------|---------------------| +| Single | All 5 tasks (+ any FIX/retry tasks) have status "completed" | +| Fan-out | ALL branches have BENCH + REVIEW completed with PASS/APPROVE (or escalated), shared stages done | +| Independent | ALL pipelines have BENCH + REVIEW completed with PASS/APPROVE (or escalated) | -2. If any tasks not completed, return to handleSpawnNext -3. If all completed, transition to coordinator Phase 5 (Report + Completion Action) +**Aggregate results** before transitioning to Phase 5: + +1. For fan-out mode: collect per-branch benchmark results into `<session>/artifacts/aggregate-results.json`: + ```json + { + "branches": { + "B01": { "opt_id": "OPT-001", "bench_verdict": "PASS", "review_verdict": "APPROVE", "improvement": "..." }, + "B02": { "opt_id": "OPT-002", "bench_verdict": "PASS", "review_verdict": "APPROVE", "improvement": "..." }, + "B03": { "status": "failed", "reason": "IMPL failed" } + }, + "overall": { "total_branches": 3, "passed": 2, "failed": 1 } + } + ``` + +2. For independent mode: collect per-pipeline results similarly + +3. If any tasks not completed, return to handleSpawnNext +4. If all completed (allowing for failed branches marked as such), transition to coordinator Phase 5 ### handleRevise Triggered by user "revise <TASK-ID> [feedback]" command. 1. Parse target task ID and optional feedback -2. Create revision task with same role but updated requirements -3. Set blockedBy to empty (immediate execution) -4. Cascade: create new downstream tasks that depend on the revised task -5. Proceed to handleSpawnNext +2. Detect branch/pipeline from task ID pattern +3. Create revision task with same role but updated requirements, scoped to branch +4. Set blockedBy to empty (immediate execution) +5. Cascade: create new downstream tasks within same branch only +6. Proceed to handleSpawnNext ### handleFeedback Triggered by user "feedback <text>" command. 1. Analyze feedback text to determine impact scope -2. Identify which pipeline stage and role should handle the feedback -3. Create targeted revision task +2. Identify which pipeline stage, role, and branch/pipeline should handle the feedback +3. Create targeted revision task (scoped to branch if applicable) 4. Proceed to handleSpawnNext ## Phase 4: State Persistence After every handler execution: -1. Update session.json with current state (active tasks, fix cycle count, last event) +1. Update session.json with current state (active tasks, fix cycle counts per branch, last event, resolved parallel_mode) 2. Verify task list consistency 3. STOP and wait for next event diff --git a/.claude/skills/team-perf-opt/roles/coordinator/role.md b/.claude/skills/team-perf-opt/roles/coordinator/role.md index 4304400f..386db7f7 100644 --- a/.claude/skills/team-perf-opt/roles/coordinator/role.md +++ b/.claude/skills/team-perf-opt/roles/coordinator/role.md @@ -55,6 +55,8 @@ When coordinator is invoked, detect invocation type: | Detection | Condition | Handler | |-----------|-----------|---------| | Worker callback | Message contains role tag [profiler], [strategist], [optimizer], [benchmarker], [reviewer] | -> handleCallback | +| Branch callback | Message contains branch tag [optimizer-B01], [benchmarker-B02], etc. | -> handleCallback (branch-aware) | +| Pipeline callback | Message contains pipeline tag [profiler-A], [optimizer-B], etc. | -> handleCallback (pipeline-aware) | | Consensus blocked | Message contains "consensus_blocked" | -> handleConsensus | | Status check | Arguments contain "check" or "status" | -> handleCheck | | Manual resume | Arguments contain "resume" or "continue" | -> handleResume | @@ -68,10 +70,10 @@ For callback/check/resume/complete: load `commands/monitor.md` and execute match 1. **Load session context** (if exists): - Scan `.workflow/.team/PERF-OPT-*/team-session.json` for active/paused sessions - - If found, extract session folder path and status + - If found, extract session folder path, status, and `parallel_mode` 2. **Parse $ARGUMENTS** for detection keywords: - - Check for role name tags in message content + - Check for role name tags in message content (including branch variants like `[optimizer-B01]`) - Check for "check", "status", "resume", "continue" keywords - Check for "consensus_blocked" signal @@ -114,15 +116,26 @@ TeamCreate({ team_name: "perf-opt" }) ## Phase 1: Requirement Clarification 1. Parse user task description from $ARGUMENTS -2. Identify optimization target: +2. **Parse parallel mode flags**: + +| Flag | Value | Default | +|------|-------|---------| +| `--parallel-mode` | `single`, `fan-out`, `independent`, `auto` | `auto` | +| `--max-branches` | integer 1-10 | 5 (from config) | + + - For `independent` mode: remaining positional arguments after flags are `independent_targets` array + - Example: `--parallel-mode=independent "optimize rendering" "optimize API"` -> targets = ["optimize rendering", "optimize API"] + +3. Identify optimization target: | Signal | Target | |--------|--------| | Specific file/module mentioned | Scoped optimization | | "slow", "performance", generic | Full application profiling | | Specific metric mentioned (FCP, memory, startup) | Targeted metric optimization | +| Multiple quoted targets (independent mode) | Per-target scoped optimization | -3. If target is unclear, ask for clarification: +4. If target is unclear, ask for clarification: ``` AskUserQuestion({ @@ -133,7 +146,7 @@ AskUserQuestion({ }) ``` -4. Record optimization requirement with scope and target metrics +5. Record optimization requirement with scope, target metrics, parallel_mode, and max_branches --- @@ -145,12 +158,38 @@ AskUserQuestion({ Bash("mkdir -p .workflow/<session-id>/artifacts .workflow/<session-id>/explorations .workflow/<session-id>/wisdom .workflow/<session-id>/discussions") ``` -2. Write session.json with status="active", team_name, requirement, timestamp + For independent mode, also create pipeline subdirectories: +``` +// For each target in independent_targets +Bash("mkdir -p .workflow/<session-id>/artifacts/pipelines/A .workflow/<session-id>/artifacts/pipelines/B ...") +``` + +2. Write session.json with extended fields: + +```json +{ + "status": "active", + "team_name": "perf-opt", + "requirement": "<requirement>", + "timestamp": "<ISO-8601>", + "parallel_mode": "<auto|single|fan-out|independent>", + "max_branches": 5, + "branches": [], + "independent_targets": [], + "fix_cycles": {} +} +``` + + - `parallel_mode`: from Phase 1 parsing (default: "auto") + - `max_branches`: from Phase 1 parsing (default: 5) + - `branches`: populated at CP-2.5 for fan-out mode (e.g., ["B01", "B02", "B03"]) + - `independent_targets`: populated for independent mode (e.g., ["optimize rendering", "optimize API"]) + - `fix_cycles`: populated per-branch/pipeline as fix cycles occur 3. Initialize shared-memory.json: ``` -Write("<session>/wisdom/shared-memory.json", { "session_id": "<session-id>", "requirement": "<requirement>" }) +Write("<session>/wisdom/shared-memory.json", { "session_id": "<session-id>", "requirement": "<requirement>", "parallel_mode": "<mode>" }) ``` 4. Create team: diff --git a/.claude/skills/team-perf-opt/specs/team-config.json b/.claude/skills/team-perf-opt/specs/team-config.json index 8e6b2849..478f62e0 100644 --- a/.claude/skills/team-perf-opt/specs/team-config.json +++ b/.claude/skills/team-perf-opt/specs/team-config.json @@ -5,7 +5,7 @@ "skill_name": "team-perf-opt", "skill_path": ".claude/skills/team-perf-opt/", "worker_agent": "team-worker", - "pipeline_type": "Linear with Review-Fix Cycle", + "pipeline_type": "Linear with Review-Fix Cycle (Parallel-Capable)", "completion_action": "interactive", "has_inline_discuss": true, "has_shared_explore": true, @@ -125,6 +125,16 @@ } ], + "parallel_config": { + "modes": ["single", "fan-out", "independent", "auto"], + "default_mode": "auto", + "max_branches": 5, + "auto_mode_rules": { + "single": "optimization_count <= 2", + "fan-out": "optimization_count >= 3" + } + }, + "pipeline": { "stages": [ { @@ -162,6 +172,24 @@ } } ], + "parallel_pipelines": { + "fan-out": { + "shared_stages": [1, 2], + "branch_stages": [3, 4], + "branch_prefix": "B", + "review_fix_cycle": { + "scope": "per_branch", + "max_iterations": 3 + } + }, + "independent": { + "pipeline_prefix_chars": "ABCDEFGHIJ", + "review_fix_cycle": { + "scope": "per_pipeline", + "max_iterations": 3 + } + } + }, "diagram": "See pipeline-diagram section" }, @@ -187,22 +215,50 @@ { "name": "Performance Baseline", "path": "<session>/artifacts/baseline-metrics.json", - "usage": "Before-optimization metrics for comparison" + "usage": "Before-optimization metrics for comparison", + "scope": "shared (fan-out) / per-pipeline (independent)" }, { "name": "Bottleneck Report", "path": "<session>/artifacts/bottleneck-report.md", - "usage": "Profiler output consumed by strategist" + "usage": "Profiler output consumed by strategist", + "scope": "shared (fan-out) / per-pipeline (independent)" }, { "name": "Optimization Plan", "path": "<session>/artifacts/optimization-plan.md", - "usage": "Strategist output consumed by optimizer" + "usage": "Strategist output consumed by optimizer", + "scope": "shared (fan-out) / per-pipeline (independent)" }, { "name": "Benchmark Results", "path": "<session>/artifacts/benchmark-results.json", - "usage": "Benchmarker output consumed by reviewer" + "usage": "Benchmarker output consumed by reviewer", + "scope": "per-branch (fan-out) / per-pipeline (independent)" } - ] + ], + + "shared_memory_namespacing": { + "single": { + "profiler": "profiler", + "strategist": "strategist", + "optimizer": "optimizer", + "benchmarker": "benchmarker", + "reviewer": "reviewer" + }, + "fan-out": { + "profiler": "profiler", + "strategist": "strategist", + "optimizer": "optimizer.B{NN}", + "benchmarker": "benchmarker.B{NN}", + "reviewer": "reviewer.B{NN}" + }, + "independent": { + "profiler": "profiler.{P}", + "strategist": "strategist.{P}", + "optimizer": "optimizer.{P}", + "benchmarker": "benchmarker.{P}", + "reviewer": "reviewer.{P}" + } + } } diff --git a/.claude/skills/workflow-lite-planex/SKILL.md b/.claude/skills/workflow-lite-planex/SKILL.md index 5633d7fe..77fcaf9b 100644 --- a/.claude/skills/workflow-lite-planex/SKILL.md +++ b/.claude/skills/workflow-lite-planex/SKILL.md @@ -39,7 +39,7 @@ Trigger `workflow-lite-planex` → dispatches to Phase 1 (lite-plan). Phase 1 in | Phase | Document | Description | |-------|----------|-------------| | Phase 1 | [phases/01-lite-plan.md](phases/01-lite-plan.md) | Planning pipeline (explore → plan → confirm → handoff to Phase 2) | -| Phase 2 | [phases/02-lite-execute.md](phases/02-lite-execute.md) | Execution engine (internal, called by Phase 1 Phase 5) | +| Phase 2 | [phases/02-lite-execute.md](phases/02-lite-execute.md) | Execution engine (internal, called by Phase 1 LP-Phase 5) | ## Interactive Preference Collection @@ -108,8 +108,8 @@ console.log('Project context loaded via: ccw spec load --category planning') 1. Collect preferences via AskUserQuestion (autoYes, forceExplore) 2. Enhance prompt with project context availability 3. Read phases/01-lite-plan.md -4. Execute lite-plan pipeline (Phase 1-5 within the phase doc) -5. lite-plan Phase 5 directly reads and executes Phase 2 (lite-execute) with executionContext +4. Execute lite-plan pipeline (LP-Phase 1-5 within the phase doc) +5. lite-plan LP-Phase 5 directly reads and executes Phase 2 (lite-execute) with executionContext ``` ## Usage diff --git a/.claude/skills/workflow-lite-planex/phases/01-lite-plan.md b/.claude/skills/workflow-lite-planex/phases/01-lite-plan.md index 68580332..85c3edfb 100644 --- a/.claude/skills/workflow-lite-planex/phases/01-lite-plan.md +++ b/.claude/skills/workflow-lite-planex/phases/01-lite-plan.md @@ -1,4 +1,4 @@ -# Phase 1: Lite-Plan +# LP-Phase 1: Lite-Plan Complete planning pipeline: task analysis, multi-angle exploration, clarification, adaptive planning, confirmation, and execution handoff. @@ -16,6 +16,14 @@ Intelligent lightweight planning command with dynamic workflow adaptation based - Two-step confirmation: plan display → multi-dimensional input collection - Execution handoff with complete context to lite-execute +## Context Isolation + +> **⚠️ CRITICAL**: If this phase was invoked from analyze-with-file (via "生成任务"), +> the analyze-with-file session is **COMPLETE** and all its phase instructions +> are FINISHED and MUST NOT be referenced. +> Only follow the LP-Phase 1-5 defined in THIS document (01-lite-plan.md). +> Phase numbers in this document are INDEPENDENT of any prior workflow. + ## Input ``` @@ -53,42 +61,42 @@ When `workflowPreferences.autoYes === true`: ## Execution Process ``` -Phase 1: Task Analysis & Exploration +LP-Phase 1: Task Analysis & Exploration ├─ Parse input (description or .md file) ├─ intelligent complexity assessment (Low/Medium/High) ├─ Exploration decision (auto-detect or workflowPreferences.forceExplore) ├─ Context protection: If file reading ≥50k chars → force cli-explore-agent └─ Decision: ├─ needsExploration=true → Launch parallel cli-explore-agents (1-4 based on complexity) - └─ needsExploration=false → Skip to Phase 2/3 + └─ needsExploration=false → Skip to LP-Phase 2/3 -Phase 2: Clarification (optional, multi-round) +LP-Phase 2: Clarification (optional, multi-round) ├─ Aggregate clarification_needs from all exploration angles ├─ Deduplicate similar questions └─ Decision: ├─ Has clarifications → AskUserQuestion (max 4 questions per round, multiple rounds allowed) - └─ No clarifications → Skip to Phase 3 + └─ No clarifications → Skip to LP-Phase 3 -Phase 3: Planning (NO CODE EXECUTION - planning only) - └─ Decision (based on Phase 1 complexity): +LP-Phase 3: Planning (NO CODE EXECUTION - planning only) + └─ Decision (based on LP-Phase 1 complexity): ├─ Low → Load schema: cat ~/.ccw/workflows/cli-templates/schemas/plan-overview-base-schema.json → Direct Claude planning (following schema) → plan.json └─ Medium/High → cli-lite-planning-agent → plan.json (agent internally executes quality check) -Phase 4: Confirmation & Selection +LP-Phase 4: Confirmation & Selection ├─ Display plan summary (tasks, complexity, estimated time) └─ AskUserQuestion: ├─ Confirm: Allow / Modify / Cancel ├─ Execution: Agent / Codex / Auto └─ Review: Gemini / Agent / Skip -Phase 5: Execute +LP-Phase 5: Execute ├─ Build executionContext (plan + explorations + clarifications + selections) └─ Direct handoff: Read phases/02-lite-execute.md → Execute with executionContext (Mode 1) ``` ## Implementation -### Phase 1: Intelligent Multi-Angle Exploration +### LP-Phase 1: Intelligent Multi-Angle Exploration **Session Setup** (MANDATORY - follow exactly): ```javascript @@ -104,14 +112,14 @@ const sessionFolder = `.workflow/.lite-plan/${sessionId}` bash(`mkdir -p ${sessionFolder} && test -d ${sessionFolder} && echo "SUCCESS: ${sessionFolder}" || echo "FAILED: ${sessionFolder}"`) ``` -**TodoWrite (Phase 1 start)**: +**TodoWrite (LP-Phase 1 start)**: ```javascript TodoWrite({ todos: [ - { content: "Phase 1: Exploration", status: "in_progress", activeForm: "Exploring codebase" }, - { content: "Phase 2: Clarification", status: "pending", activeForm: "Collecting clarifications" }, - { content: "Phase 3: Planning", status: "pending", activeForm: "Generating plan" }, - { content: "Phase 4: Confirmation", status: "pending", activeForm: "Awaiting confirmation" }, - { content: "Phase 5: Execution", status: "pending", activeForm: "Executing tasks" } + { content: "LP-Phase 1: Exploration", status: "in_progress", activeForm: "Exploring codebase" }, + { content: "LP-Phase 2: Clarification", status: "pending", activeForm: "Collecting clarifications" }, + { content: "LP-Phase 3: Planning", status: "pending", activeForm: "Generating plan" }, + { content: "LP-Phase 4: Confirmation", status: "pending", activeForm: "Awaiting confirmation" }, + { content: "LP-Phase 5: Execution", status: "pending", activeForm: "Executing tasks" } ]}) ``` @@ -129,7 +137,7 @@ needsExploration = workflowPreferences.forceExplore ? true if (!needsExploration) { // Skip exploration — analysis context already in task description (or not needed) - // manifest is absent; Phase 3 loads it with safe fallback + // manifest is absent; LP-Phase 3 loads it with safe fallback proceed_to_next_phase() } ``` @@ -318,14 +326,14 @@ Angles explored: ${explorationManifest.explorations.map(e => e.angle).join(', ') `) ``` -**TodoWrite (Phase 1 complete)**: +**TodoWrite (LP-Phase 1 complete)**: ```javascript TodoWrite({ todos: [ - { content: "Phase 1: Exploration", status: "completed", activeForm: "Exploring codebase" }, - { content: "Phase 2: Clarification", status: "in_progress", activeForm: "Collecting clarifications" }, - { content: "Phase 3: Planning", status: "pending", activeForm: "Generating plan" }, - { content: "Phase 4: Confirmation", status: "pending", activeForm: "Awaiting confirmation" }, - { content: "Phase 5: Execution", status: "pending", activeForm: "Executing tasks" } + { content: "LP-Phase 1: Exploration", status: "completed", activeForm: "Exploring codebase" }, + { content: "LP-Phase 2: Clarification", status: "in_progress", activeForm: "Collecting clarifications" }, + { content: "LP-Phase 3: Planning", status: "pending", activeForm: "Generating plan" }, + { content: "LP-Phase 4: Confirmation", status: "pending", activeForm: "Awaiting confirmation" }, + { content: "LP-Phase 5: Execution", status: "pending", activeForm: "Executing tasks" } ]}) ``` @@ -337,7 +345,7 @@ TodoWrite({ todos: [ --- -### Phase 2: Clarification (Optional, Multi-Round) +### LP-Phase 2: Clarification (Optional, Multi-Round) **Skip if**: No exploration or `clarification_needs` is empty across all explorations @@ -379,7 +387,7 @@ if (autoYes) { // Auto mode: Skip clarification phase console.log(`[Auto] Skipping ${dedupedClarifications.length} clarification questions`) console.log(`Proceeding to planning with exploration results...`) - // Continue to Phase 3 + // Continue to LP-Phase 3 } else if (dedupedClarifications.length > 0) { // Interactive mode: Multi-round clarification const BATCH_SIZE = 4 @@ -412,11 +420,11 @@ if (autoYes) { --- -### Phase 3: Planning +### LP-Phase 3: Planning -**Planning Strategy Selection** (based on Phase 1 complexity): +**Planning Strategy Selection** (based on LP-Phase 1 complexity): -**IMPORTANT**: Phase 3 is **planning only** - NO code execution. All execution happens in Phase 5 via lite-execute. +**IMPORTANT**: LP-Phase 3 is **planning only** - NO code execution. All execution happens in LP-Phase 5 via lite-execute. **Executor Assignment** (Claude 智能分配,plan 生成后执行): @@ -494,7 +502,7 @@ const plan = { // Step 6: Write plan overview to session folder Write(`${sessionFolder}/plan.json`, JSON.stringify(plan, null, 2)) -// Step 7: MUST continue to Phase 4 (Confirmation) - DO NOT execute code here +// Step 7: MUST continue to LP-Phase 4 (Confirmation) - DO NOT execute code here ``` **Medium/High Complexity** - Invoke cli-lite-planning-agent: @@ -584,20 +592,20 @@ Note: Use files[].change (not modification_points), convergence.criteria (not ac **Output**: `${sessionFolder}/plan.json` -**TodoWrite (Phase 3 complete)**: +**TodoWrite (LP-Phase 3 complete)**: ```javascript TodoWrite({ todos: [ - { content: "Phase 1: Exploration", status: "completed", activeForm: "Exploring codebase" }, - { content: "Phase 2: Clarification", status: "completed", activeForm: "Collecting clarifications" }, - { content: "Phase 3: Planning", status: "completed", activeForm: "Generating plan" }, - { content: "Phase 4: Confirmation", status: "in_progress", activeForm: "Awaiting confirmation" }, - { content: "Phase 5: Execution", status: "pending", activeForm: "Executing tasks" } + { content: "LP-Phase 1: Exploration", status: "completed", activeForm: "Exploring codebase" }, + { content: "LP-Phase 2: Clarification", status: "completed", activeForm: "Collecting clarifications" }, + { content: "LP-Phase 3: Planning", status: "completed", activeForm: "Generating plan" }, + { content: "LP-Phase 4: Confirmation", status: "in_progress", activeForm: "Awaiting confirmation" }, + { content: "LP-Phase 5: Execution", status: "pending", activeForm: "Executing tasks" } ]}) ``` --- -### Phase 4: Task Confirmation & Execution Selection +### LP-Phase 4: Task Confirmation & Execution Selection **Step 4.1: Display Plan** ```javascript @@ -684,22 +692,22 @@ if (autoYes) { } ``` -**TodoWrite (Phase 4 confirmed)**: +**TodoWrite (LP-Phase 4 confirmed)**: ```javascript const executionLabel = userSelection.execution_method TodoWrite({ todos: [ - { content: "Phase 1: Exploration", status: "completed", activeForm: "Exploring codebase" }, - { content: "Phase 2: Clarification", status: "completed", activeForm: "Collecting clarifications" }, - { content: "Phase 3: Planning", status: "completed", activeForm: "Generating plan" }, - { content: `Phase 4: Confirmed [${executionLabel}]`, status: "completed", activeForm: "Confirmed" }, - { content: `Phase 5: Execution [${executionLabel}]`, status: "in_progress", activeForm: `Executing [${executionLabel}]` } + { content: "LP-Phase 1: Exploration", status: "completed", activeForm: "Exploring codebase" }, + { content: "LP-Phase 2: Clarification", status: "completed", activeForm: "Collecting clarifications" }, + { content: "LP-Phase 3: Planning", status: "completed", activeForm: "Generating plan" }, + { content: `LP-Phase 4: Confirmed [${executionLabel}]`, status: "completed", activeForm: "Confirmed" }, + { content: `LP-Phase 5: Execution [${executionLabel}]`, status: "in_progress", activeForm: `Executing [${executionLabel}]` } ]}) ``` --- -### Phase 5: Handoff to Execution +### LP-Phase 5: Handoff to Execution **CRITICAL**: lite-plan NEVER executes code directly. ALL execution MUST go through lite-execute. @@ -807,4 +815,4 @@ Read("phases/02-lite-execute.md") ## Next Phase -After Phase 5 handoff, execution continues in [Phase 2: Lite-Execute](02-lite-execute.md). +After LP-Phase 5 handoff, execution continues in [Phase 2: Lite-Execute](02-lite-execute.md). diff --git a/ccw/frontend/src/components/ChunkErrorBoundary.tsx b/ccw/frontend/src/components/ChunkErrorBoundary.tsx new file mode 100644 index 00000000..2c65c8bb --- /dev/null +++ b/ccw/frontend/src/components/ChunkErrorBoundary.tsx @@ -0,0 +1,157 @@ +// ======================================== +// Chunk Error Boundary +// ======================================== +// Error boundary for handling lazy-loaded chunk load failures +// Catches network failures, missing chunks, and other module loading errors + +import React, { Component, ErrorInfo, ReactNode } from 'react'; +import { Button } from '@/components/ui/Button'; + +interface ChunkErrorBoundaryProps { + children: ReactNode; + fallback?: ReactNode; +} + +interface ChunkErrorBoundaryState { + hasError: boolean; + error: Error | null; + errorInfo: ErrorInfo | null; +} + +/** + * Error displayed when a chunk fails to load + */ +function ChunkLoadError({ error, onRetry }: { error: Error | null; onRetry: () => void }) { + return ( + <div className="flex items-center justify-center h-full p-8"> + <div className="text-center max-w-md"> + <div className="mb-4"> + <svg + className="w-16 h-16 mx-auto text-destructive" + fill="none" + stroke="currentColor" + viewBox="0 0 24 24" + > + <path + strokeLinecap="round" + strokeLinejoin="round" + strokeWidth={2} + d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" + /> + </svg> + </div> + <h2 className="text-xl font-semibold mb-2">Failed to Load Page</h2> + <p className="text-muted-foreground mb-6"> + {error?.message.includes('ChunkLoadError') + ? 'A network error occurred while loading this page. Please check your connection and try again.' + : 'An error occurred while loading this page. Please try refreshing.'} + </p> + <div className="flex gap-3 justify-center"> + <Button onClick={onRetry} variant="default"> + Try Again + </Button> + <Button onClick={() => window.location.href = '/'} variant="outline"> + Go Home + </Button> + </div> + {error && ( + <details className="mt-4 text-left"> + <summary className="cursor-pointer text-sm text-muted-foreground hover:text-foreground"> + Technical details + </summary> + <pre className="mt-2 text-xs bg-muted p-2 rounded overflow-auto max-h-32"> + {error.toString()} + </pre> + </details> + )} + </div> + </div> + ); +} + +/** + * Error boundary class component for catching chunk load errors + * + * Wraps lazy-loaded route components to gracefully handle: + * - Network failures during chunk fetch + * - Missing or outdated chunk files + * - Browser caching issues + */ +export class ChunkErrorBoundary extends Component<ChunkErrorBoundaryProps, ChunkErrorBoundaryState> { + constructor(props: ChunkErrorBoundaryProps) { + super(props); + this.state = { + hasError: false, + error: null, + errorInfo: null, + }; + } + + static getDerivedStateFromError(error: Error): Partial<ChunkErrorBoundaryState> { + return { + hasError: true, + error, + }; + } + + componentDidCatch(error: Error, errorInfo: ErrorInfo): void { + // Log error for debugging + console.error('[ChunkErrorBoundary] Chunk load error:', error, errorInfo); + + this.setState({ + errorInfo, + }); + + // Optionally send error to monitoring service + if (typeof window !== 'undefined' && (window as any).reportError) { + (window as any).reportError(error); + } + } + + handleRetry = (): void => { + // Reset error state and retry + this.setState({ + hasError: false, + error: null, + errorInfo: null, + }); + + // Force reload the current route to retry chunk loading + window.location.reload(); + }; + + render(): ReactNode { + if (this.state.hasError) { + // Use custom fallback if provided + if (this.props.fallback) { + return this.props.fallback; + } + + // Default error UI + return <ChunkLoadError error={this.state.error} onRetry={this.handleRetry} />; + } + + return this.props.children; + } +} + +/** + * HOC to wrap a component with ChunkErrorBoundary + * + * Usage: + * ```tsx + * const SafePage = withChunkErrorBoundary(MyPage); + * ``` + */ +export function withChunkErrorBoundary<P extends object>( + Component: React.ComponentType<P>, + fallback?: ReactNode +): React.ComponentType<P> { + return function WrappedComponent(props: P) { + return ( + <ChunkErrorBoundary fallback={fallback}> + <Component {...props} /> + </ChunkErrorBoundary> + ); + }; +} diff --git a/ccw/frontend/src/components/PageSkeleton.tsx b/ccw/frontend/src/components/PageSkeleton.tsx new file mode 100644 index 00000000..8648edc1 --- /dev/null +++ b/ccw/frontend/src/components/PageSkeleton.tsx @@ -0,0 +1,12 @@ +// ======================================== +// Page Skeleton +// ======================================== +// Loading fallback component for lazy-loaded routes + +export function PageSkeleton() { + return ( + <div className="flex items-center justify-center h-full"> + <div className="animate-pulse text-muted-foreground">Loading...</div> + </div> + ); +} diff --git a/ccw/frontend/src/router.tsx b/ccw/frontend/src/router.tsx index 4e35d2cf..4db6907f 100644 --- a/ccw/frontend/src/router.tsx +++ b/ccw/frontend/src/router.tsx @@ -6,6 +6,8 @@ import { createBrowserRouter, RouteObject, Navigate } from 'react-router-dom'; import { lazy, Suspense } from 'react'; import { AppShell } from '@/components/layout'; +import { ChunkErrorBoundary } from '@/components/ChunkErrorBoundary'; +import { PageSkeleton } from '@/components/PageSkeleton'; // Import HomePage directly (no lazy - needed immediately) import { HomePage } from '@/pages/HomePage'; @@ -42,12 +44,17 @@ const TerminalDashboardPage = lazy(() => import('@/pages/TerminalDashboardPage') const AnalysisPage = lazy(() => import('@/pages/AnalysisPage').then(m => ({ default: m.AnalysisPage }))); const SpecsSettingsPage = lazy(() => import('@/pages/SpecsSettingsPage').then(m => ({ default: m.SpecsSettingsPage }))); -// Loading fallback component for lazy-loaded routes -function PageSkeleton() { +/** + * Helper to wrap lazy-loaded components with error boundary and suspense + * Catches chunk load failures and provides retry mechanism + */ +function withErrorHandling(element: React.ReactElement) { return ( - <div className="flex items-center justify-center h-full"> - <div className="animate-pulse text-muted-foreground">Loading...</div> - </div> + <ChunkErrorBoundary> + <Suspense fallback={<PageSkeleton />}> + {element} + </Suspense> + </ChunkErrorBoundary> ); } @@ -58,11 +65,7 @@ function PageSkeleton() { const routes: RouteObject[] = [ { path: 'cli-sessions/share', - element: ( - <Suspense fallback={<PageSkeleton />}> - <CliSessionSharePage /> - </Suspense> - ), + element: withErrorHandling(<CliSessionSharePage />), }, { path: '/', @@ -74,68 +77,36 @@ const routes: RouteObject[] = [ }, { path: 'sessions', - element: ( - <Suspense fallback={<PageSkeleton />}> - <SessionsPage /> - </Suspense> - ), + element: withErrorHandling(<SessionsPage />), }, { path: 'sessions/:sessionId', - element: ( - <Suspense fallback={<PageSkeleton />}> - <SessionDetailPage /> - </Suspense> - ), + element: withErrorHandling(<SessionDetailPage />), }, { path: 'sessions/:sessionId/fix', - element: ( - <Suspense fallback={<PageSkeleton />}> - <FixSessionPage /> - </Suspense> - ), + element: withErrorHandling(<FixSessionPage />), }, { path: 'sessions/:sessionId/review', - element: ( - <Suspense fallback={<PageSkeleton />}> - <ReviewSessionPage /> - </Suspense> - ), + element: withErrorHandling(<ReviewSessionPage />), }, { path: 'lite-tasks', - element: ( - <Suspense fallback={<PageSkeleton />}> - <LiteTasksPage /> - </Suspense> - ), + element: withErrorHandling(<LiteTasksPage />), }, // /lite-tasks/:sessionId route removed - now using TaskDrawer { path: 'project', - element: ( - <Suspense fallback={<PageSkeleton />}> - <ProjectOverviewPage /> - </Suspense> - ), + element: withErrorHandling(<ProjectOverviewPage />), }, { path: 'history', - element: ( - <Suspense fallback={<PageSkeleton />}> - <HistoryPage /> - </Suspense> - ), + element: withErrorHandling(<HistoryPage />), }, { path: 'orchestrator', - element: ( - <Suspense fallback={<PageSkeleton />}> - <OrchestratorPage /> - </Suspense> - ), + element: withErrorHandling(<OrchestratorPage />), }, { path: 'loops', @@ -143,19 +114,11 @@ const routes: RouteObject[] = [ }, { path: 'cli-viewer', - element: ( - <Suspense fallback={<PageSkeleton />}> - <CliViewerPage /> - </Suspense> - ), + element: withErrorHandling(<CliViewerPage />), }, { path: 'issues', - element: ( - <Suspense fallback={<PageSkeleton />}> - <IssueHubPage /> - </Suspense> - ), + element: withErrorHandling(<IssueHubPage />), }, // Legacy routes - redirect to hub with tab parameter { @@ -168,147 +131,75 @@ const routes: RouteObject[] = [ }, { path: 'skills', - element: ( - <Suspense fallback={<PageSkeleton />}> - <SkillsManagerPage /> - </Suspense> - ), + element: withErrorHandling(<SkillsManagerPage />), }, { path: 'commands', - element: ( - <Suspense fallback={<PageSkeleton />}> - <CommandsManagerPage /> - </Suspense> - ), + element: withErrorHandling(<CommandsManagerPage />), }, { path: 'memory', - element: ( - <Suspense fallback={<PageSkeleton />}> - <MemoryPage /> - </Suspense> - ), + element: withErrorHandling(<MemoryPage />), }, { path: 'prompts', - element: ( - <Suspense fallback={<PageSkeleton />}> - <PromptHistoryPage /> - </Suspense> - ), + element: withErrorHandling(<PromptHistoryPage />), }, { path: 'settings', - element: ( - <Suspense fallback={<PageSkeleton />}> - <SettingsPage /> - </Suspense> - ), + element: withErrorHandling(<SettingsPage />), }, { path: 'settings/mcp', - element: ( - <Suspense fallback={<PageSkeleton />}> - <McpManagerPage /> - </Suspense> - ), + element: withErrorHandling(<McpManagerPage />), }, { path: 'settings/endpoints', - element: ( - <Suspense fallback={<PageSkeleton />}> - <EndpointsPage /> - </Suspense> - ), + element: withErrorHandling(<EndpointsPage />), }, { path: 'settings/installations', - element: ( - <Suspense fallback={<PageSkeleton />}> - <InstallationsPage /> - </Suspense> - ), + element: withErrorHandling(<InstallationsPage />), }, { path: 'settings/rules', - element: ( - <Suspense fallback={<PageSkeleton />}> - <RulesManagerPage /> - </Suspense> - ), + element: withErrorHandling(<RulesManagerPage />), }, { path: 'settings/specs', - element: ( - <Suspense fallback={<PageSkeleton />}> - <SpecsSettingsPage /> - </Suspense> - ), + element: withErrorHandling(<SpecsSettingsPage />), }, { path: 'settings/codexlens', - element: ( - <Suspense fallback={<PageSkeleton />}> - <CodexLensManagerPage /> - </Suspense> - ), + element: withErrorHandling(<CodexLensManagerPage />), }, { path: 'api-settings', - element: ( - <Suspense fallback={<PageSkeleton />}> - <ApiSettingsPage /> - </Suspense> - ), + element: withErrorHandling(<ApiSettingsPage />), }, { path: 'hooks', - element: ( - <Suspense fallback={<PageSkeleton />}> - <HookManagerPage /> - </Suspense> - ), + element: withErrorHandling(<HookManagerPage />), }, { path: 'explorer', - element: ( - <Suspense fallback={<PageSkeleton />}> - <ExplorerPage /> - </Suspense> - ), + element: withErrorHandling(<ExplorerPage />), }, { path: 'graph', - element: ( - <Suspense fallback={<PageSkeleton />}> - <GraphExplorerPage /> - </Suspense> - ), + element: withErrorHandling(<GraphExplorerPage />), }, { path: 'teams', - element: ( - <Suspense fallback={<PageSkeleton />}> - <TeamPage /> - </Suspense> - ), + element: withErrorHandling(<TeamPage />), }, { path: 'analysis', - element: ( - <Suspense fallback={<PageSkeleton />}> - <AnalysisPage /> - </Suspense> - ), + element: withErrorHandling(<AnalysisPage />), }, { path: 'terminal-dashboard', - element: ( - <Suspense fallback={<PageSkeleton />}> - <TerminalDashboardPage /> - </Suspense> - ), + element: withErrorHandling(<TerminalDashboardPage />), }, { path: 'skill-hub', @@ -317,11 +208,7 @@ const routes: RouteObject[] = [ // Catch-all route for 404 { path: '*', - element: ( - <Suspense fallback={<PageSkeleton />}> - <NotFoundPage /> - </Suspense> - ), + element: withErrorHandling(<NotFoundPage />), }, ], }, diff --git a/ccw/src/core/routes/notification-routes.ts b/ccw/src/core/routes/notification-routes.ts index 6f1d4d8d..93f326eb 100644 --- a/ccw/src/core/routes/notification-routes.ts +++ b/ccw/src/core/routes/notification-routes.ts @@ -39,6 +39,11 @@ const FEISHU_HOSTNAMES = ['feishu.cn', 'larksuite.com', 'lark.com']; const DINGTALK_HOSTNAMES = ['dingtalk.com', 'oapi.dingtalk.com']; const WECOM_HOSTNAMES = ['qyapi.weixin.qq.com', 'work.weixin.qq.com']; +// Pattern for safe header values - only printable ASCII characters (no control chars) +// This prevents XSS by ensuring header values don't contain HTML/JS metacharacters +// Space (0x20) through tilde (0x7E) are printable ASCII characters +const SAFE_HEADER_VALUE_REGEX = /^[\x20-\x7E]+$/; + /** * Validate URL format (must be http or https) */ @@ -113,6 +118,11 @@ function isValidHeaders(headers: unknown): { valid: boolean; error?: string } { if (typeof value !== 'string') { return { valid: false, error: `Header '${key}' value must be a string` }; } + // Sanitize header value - only allow printable ASCII characters + // This prevents XSS by blocking HTML/JS metacharacters and control characters + if (!SAFE_HEADER_VALUE_REGEX.test(value)) { + return { valid: false, error: `Header '${key}' contains invalid characters. Only printable ASCII characters (space through tilde) are allowed.` }; + } // Block potentially dangerous headers const lowerKey = key.toLowerCase(); if (['host', 'content-length', 'connection'].includes(lowerKey)) { diff --git a/docs/.vitepress/theme/components/ProfessionalHome.vue b/docs/.vitepress/theme/components/ProfessionalHome.vue index a82a2035..4fb8b409 100644 --- a/docs/.vitepress/theme/components/ProfessionalHome.vue +++ b/docs/.vitepress/theme/components/ProfessionalHome.vue @@ -549,6 +549,7 @@ onUnmounted(() => { margin: 0 auto; padding: 0 2rem; width: 100%; + box-sizing: border-box; } /* ============================================ @@ -573,6 +574,7 @@ onUnmounted(() => { align-items: center; padding: 0 2rem; width: 100%; + box-sizing: border-box; } .hero-visual { @@ -743,6 +745,8 @@ onUnmounted(() => { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.25rem; + max-width: 100%; + box-sizing: border-box; } .feature-card { padding: 1.75rem; @@ -751,6 +755,8 @@ onUnmounted(() => { border-radius: 16px; transition: all 0.2s ease; cursor: default; + box-sizing: border-box; + min-width: 0; } .feature-card:hover { transform: translateY(-4px); @@ -800,6 +806,8 @@ onUnmounted(() => { border-radius: 20px; padding: 2.5rem; box-shadow: var(--vp-shadow-2); + box-sizing: border-box; + max-width: 100%; } .cadence-header { display: flex; justify-content: space-between; align-items: center; } .cadence-label { @@ -835,7 +843,14 @@ onUnmounted(() => { } .tick-node.active { border-color: var(--vp-c-brand-1); background: var(--vp-c-brand-1); } .tick-node.blocked { background: #ef4444; border-color: #ef4444; } -.pipeline-flow { display: flex; justify-content: space-between; margin-bottom: 3rem; } +.pipeline-flow { + display: flex; + justify-content: space-between; + margin-bottom: 3rem; + max-width: 100%; + box-sizing: border-box; + flex-wrap: wrap; +} .stage-node { flex: 1; display: flex; flex-direction: column; align-items: center; position: relative; opacity: 0.4; transition: all 0.5s; } .stage-node.active, .stage-node.done { opacity: 1; } .stage-badge { min-height: 24px; margin-bottom: 0.5rem; } @@ -1281,15 +1296,27 @@ onUnmounted(() => { * ============================================ */ /* Tablet (768px - 1024px) */ -@media (max-width: 1024px) { - .features-grid { grid-template-columns: repeat(2, 1fr); } - .hero-container { gap: 1.5rem; } +@media (max-width: var(--bp-md)) { + .features-grid { + grid-template-columns: repeat(2, 1fr); + gap: 1rem; + } + .hero-container { + gap: 1.5rem; + padding: 0 1.5rem; + } .hero-title { font-size: 2.25rem; } - .section-container { padding: 0 1.5rem; } + .section-container { + padding: 0 1.5rem; + max-width: 100%; + } + .pipeline-flow { + gap: 1rem; + } } /* Mobile (< 768px) */ -@media (max-width: 768px) { +@media (max-width: var(--bp-sm)) { /* Hero Section - add extra padding-top to clear fixed nav (56px) */ .hero-section { padding: 4.5rem 0 2rem; @@ -1373,7 +1400,6 @@ onUnmounted(() => { padding: 1.25rem; max-width: 100%; box-sizing: border-box; - overflow-x: hidden; } .pipeline-flow { flex-direction: column; @@ -1389,7 +1415,7 @@ onUnmounted(() => { .law-content, .log-content { padding: 1rem; font-size: 0.8rem; min-height: 60px; } /* JSON Section */ - .json-section { padding: 0; overflow-x: hidden; } + .json-section { padding: 0; } .json-grid { grid-template-columns: 1fr; text-align: center; @@ -1455,7 +1481,7 @@ onUnmounted(() => { } /* Small Mobile (< 480px) */ -@media (max-width: 480px) { +@media (max-width: var(--bp-xs)) { .hero-title { font-size: 1.5rem; } .hero-actions { flex-direction: column; width: 100%; } .hero-actions .btn-primary, diff --git a/docs/.vitepress/theme/layouts/Layout.vue b/docs/.vitepress/theme/layouts/Layout.vue index 810183e3..7259987e 100644 --- a/docs/.vitepress/theme/layouts/Layout.vue +++ b/docs/.vitepress/theme/layouts/Layout.vue @@ -196,13 +196,12 @@ onBeforeUnmount(() => { /* Container queries in mobile.css provide additional responsiveness */ /* Mobile-specific styles */ -@media (max-width: 768px) { +@media (max-width: var(--bp-sm)) { .hero-extensions { margin-top: 1rem; padding: 0 12px; - max-width: 100vw; + max-width: 100%; box-sizing: border-box; - overflow-x: hidden; } .hero-stats { diff --git a/docs/.vitepress/theme/styles/custom.css b/docs/.vitepress/theme/styles/custom.css index c891044f..0ff9fed4 100644 --- a/docs/.vitepress/theme/styles/custom.css +++ b/docs/.vitepress/theme/styles/custom.css @@ -86,12 +86,10 @@ padding: 0 !important; margin: 0 !important; max-width: 100vw !important; - overflow-x: hidden !important; } .Layout:has(.pro-home) { max-width: 100vw !important; - overflow-x: hidden !important; } /* Ensure VPNav doesn't cause overflow */ @@ -113,7 +111,6 @@ padding: 0 !important; margin: 0 !important; width: 100% !important; - overflow-x: hidden !important; box-sizing: border-box !important; } diff --git a/docs/.vitepress/theme/styles/demo.css b/docs/.vitepress/theme/styles/demo.css index a8410301..7938e5de 100644 --- a/docs/.vitepress/theme/styles/demo.css +++ b/docs/.vitepress/theme/styles/demo.css @@ -35,7 +35,7 @@ } /* Responsive design */ -@media (max-width: 768px) { +@media (max-width: var(--bp-sm)) { .demo-header { flex-direction: column; align-items: flex-start; diff --git a/docs/.vitepress/theme/styles/mobile.css b/docs/.vitepress/theme/styles/mobile.css index 834dc5f8..e64bbfd6 100644 --- a/docs/.vitepress/theme/styles/mobile.css +++ b/docs/.vitepress/theme/styles/mobile.css @@ -1,7 +1,7 @@ /** * Mobile-Responsive Styles - * Breakpoints: 320px-768px (mobile), 768px-1024px (tablet), 1024px+ (desktop) - * Uses CSS custom properties from variables.css: --bp-mobile, --bp-tablet, --bp-desktop + * Breakpoints: < 480px (xs), < 768px (sm/mobile), 768px-1024px (md/tablet), > 1024px (lg/desktop) + * Uses CSS custom properties from variables.css: --bp-xs, --bp-sm, --bp-md, --bp-lg * WCAG 2.1 AA compliant */ @@ -19,7 +19,7 @@ max-width: 320px; } - @media (min-width: 768px) { + @media (min-width: var(--bp-sm)) { .VPSidebar { width: var(--vp-sidebar-width, 272px); max-width: none; @@ -31,13 +31,13 @@ padding: 16px; } - @media (min-width: 768px) { + @media (min-width: var(--bp-sm)) { .VPContent { padding: 24px; } } - @media (min-width: 1024px) { + @media (min-width: var(--bp-md)) { .VPContent { padding: 32px 48px; } @@ -48,14 +48,14 @@ display: none; } - @media (min-width: 768px) { + @media (min-width: var(--bp-sm)) { .VPDocOutline { display: block; width: 200px; } } - @media (min-width: 1024px) { + @media (min-width: var(--bp-md)) { .VPDocOutline { width: 256px; } @@ -65,7 +65,7 @@ /* Container Query Rules (modern browsers) */ @supports (container-type: inline-size) { /* Sidebar Container Queries */ - @container sidebar (max-width: 480px) { + @container sidebar (max-width: var(--bp-xs)) { .VPSidebar .group { padding: 12px 16px; } @@ -75,7 +75,7 @@ } } - @container sidebar (min-width: 480px) and (max-width: 768px) { + @container sidebar (min-width: var(--bp-xs)) and (max-width: var(--bp-sm)) { .VPSidebar .group { padding: 16px 20px; } @@ -85,7 +85,7 @@ } } - @container sidebar (min-width: 768px) { + @container sidebar (min-width: var(--bp-sm)) { .VPSidebar .group { padding: 16px 24px; } @@ -221,25 +221,25 @@ } /* Generic Container-Responsive Utility Class */ -@container (max-width: 480px) { +@container (max-width: var(--bp-xs)) { .container-responsive { padding: 0 var(--spacing-fluid-xs); } } -@container (min-width: 480px) and (max-width: 768px) { +@container (min-width: var(--bp-xs)) and (max-width: var(--bp-sm)) { .container-responsive { padding: 0 var(--spacing-fluid-sm); } } -@container (min-width: 768px) and (max-width: 1024px) { +@container (min-width: var(--bp-sm)) and (max-width: var(--bp-md)) { .container-responsive { padding: 0 var(--spacing-fluid-md); } } -@container (min-width: 1024px) { +@container (min-width: var(--bp-md)) { .container-responsive { padding: 0 var(--spacing-fluid-lg); } @@ -250,7 +250,7 @@ * ============================================ */ /* Base Mobile Styles (320px+) */ -@media (max-width: 768px) { +@media (max-width: var(--bp-sm)) { /* Typography */ :root { --vp-font-size-base: 14px; @@ -598,7 +598,7 @@ /* ============================================ * Tablet Styles (768px - 1024px) * ============================================ */ -@media (min-width: 768px) and (max-width: 1024px) { +@media (min-width: var(--bp-sm)) and (max-width: var(--bp-md)) { :root { --vp-content-width: 760px; --vp-sidebar-width: 240px; @@ -639,7 +639,7 @@ /* ============================================ * Desktop Styles (1024px+) * ============================================ */ -@media (min-width: 1024px) { +@media (min-width: var(--bp-md)) { :root { --vp-layout-max-width: 1600px; --vp-content-width: 960px; @@ -692,7 +692,7 @@ /* ============================================ * Large Desktop (1440px+) * ============================================ */ -@media (min-width: 1440px) { +@media (min-width: var(--bp-lg)) { :root { --vp-content-width: 1040px; --vp-sidebar-width: 280px; @@ -749,23 +749,20 @@ /* ============================================ * ProfessionalHome Component - Mobile Optimizations * ============================================ */ -@media (max-width: 768px) { +@media (max-width: var(--bp-sm)) { /* Root level overflow prevention */ html, body { - overflow-x: hidden; max-width: 100vw; } /* VitePress Layout container fix */ .Layout { max-width: 100vw; - overflow-x: hidden; } /* VPContent container fix */ .VPContent { max-width: 100vw; - overflow-x: hidden; padding: 0 !important; } @@ -774,7 +771,6 @@ padding: 0 12px; box-sizing: border-box; max-width: 100vw; - overflow-x: hidden; } .hero-stats { @@ -790,7 +786,6 @@ /* Prevent horizontal scroll */ .pro-home { - overflow-x: hidden; max-width: 100vw; } @@ -888,8 +883,7 @@ /* Quick Start Section - prevent overflow */ .pro-home .quickstart-section { padding: 3rem 0; - max-width: 100vw; - overflow-x: hidden; + max-width: 100%; } .pro-home .quickstart-layout { @@ -917,19 +911,17 @@ /* Features section overflow fix */ .pro-home .features-section { max-width: 100vw; - overflow-x: hidden; padding: 3rem 0; } /* Pipeline section overflow fix */ .pro-home .pipeline-section { max-width: 100vw; - overflow-x: hidden; } } /* ProfessionalHome - Tablet Optimizations */ -@media (min-width: 768px) and (max-width: 1024px) { +@media (min-width: var(--bp-sm)) and (max-width: var(--bp-md)) { .pro-home .hero-section { padding: 3rem 0 2.5rem; } @@ -949,7 +941,7 @@ } /* ProfessionalHome - Small Mobile (< 480px) */ -@media (max-width: 480px) { +@media (max-width: var(--bp-xs)) { .pro-home .hero-badge { font-size: 0.7rem; padding: 0.2rem 0.5rem; @@ -973,7 +965,7 @@ /* ============================================ * Dark Mode Specific * ============================================ */ -@media (max-width: 768px) { +@media (max-width: var(--bp-sm)) { .dark { --vp-c-bg: #0f172a; --vp-c-text-1: #f1f5f9; @@ -983,7 +975,7 @@ /* ============================================ * Print Styles for Mobile * ============================================ */ -@media print and (max-width: 768px) { +@media print and (max-width: var(--bp-sm)) { .VPContent { font-size: 10pt; } diff --git a/docs/.vitepress/theme/styles/variables.css b/docs/.vitepress/theme/styles/variables.css index d3fa886e..1fe4c210 100644 --- a/docs/.vitepress/theme/styles/variables.css +++ b/docs/.vitepress/theme/styles/variables.css @@ -143,9 +143,15 @@ --vp-z-index-toast: 200; /* Responsive Breakpoints (VitePress standard) */ - --bp-mobile: 768px; /* Mobile: < 768px */ - --bp-tablet: 1024px; /* Tablet: 768px - 1024px */ - --bp-desktop: 1440px; /* Desktop: > 1024px, large: > 1440px */ + --bp-xs: 480px; /* Extra Small: < 480px */ + --bp-sm: 768px; /* Small (Mobile): < 768px */ + --bp-md: 1024px; /* Medium (Tablet): 768px - 1024px */ + --bp-lg: 1440px; /* Large (Desktop): > 1024px, extra large: > 1440px */ + + /* Legacy aliases for backward compatibility */ + --bp-mobile: var(--bp-sm); + --bp-tablet: var(--bp-md); + --bp-desktop: var(--bp-lg); /* Container Query Breakpoints * Aligned with media query breakpoints for consistency