mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-03 15:43:11 +08:00
Refactor workflow-lite-planex documentation to standardize phase naming and improve clarity
- Updated phase references in SKILL.md and 01-lite-plan.md to use "LP-Phase" prefix for consistency. - Added critical context isolation note in 01-lite-plan.md to clarify phase invocation rules. - Enhanced execution process descriptions to reflect updated phase naming conventions. Improve error handling in frontend routing - Introduced ChunkErrorBoundary component to handle lazy-loaded chunk load failures. - Wrapped lazy-loaded routes with error boundary and suspense for better user experience. - Created PageSkeleton component for loading states in lazy-loaded routes. Sanitize header values in notification routes - Added regex validation for header values to prevent XSS attacks by allowing only printable ASCII characters. Enhance mobile responsiveness in documentation styles - Updated CSS breakpoints to use custom properties for better maintainability. - Improved layout styles across various components to ensure consistent behavior on mobile devices.
This commit is contained in:
@@ -589,7 +589,17 @@ CONSTRAINTS: ${perspective.constraints}
|
|||||||
if (findings.length) contextLines.push(`**Key Findings**:\n${findings.map(f => `- ${f}`).join('\n')}`)
|
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')}"`)
|
Skill(skill="workflow-lite-planex", args=`"${taskDescription}\n\n${contextLines.join('\n')}"`)
|
||||||
return // ⛔ analyze-with-file terminates here
|
return // ⛔ analyze-with-file terminates here
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,24 +67,42 @@ Always route to coordinator. Coordinator reads `roles/coordinator/role.md` and e
|
|||||||
|
|
||||||
User just provides task description.
|
User just provides task description.
|
||||||
|
|
||||||
**Invocation**: `Skill(skill="team-perf-opt", args="<task-description>")`
|
**Invocation**:
|
||||||
|
```bash
|
||||||
|
Skill(skill="team-perf-opt", args="<task-description>") # auto mode
|
||||||
|
Skill(skill="team-perf-opt", args="--parallel-mode=fan-out <task-description>") # force fan-out
|
||||||
|
Skill(skill="team-perf-opt", args='--parallel-mode=independent "target1" "target2"') # independent
|
||||||
|
Skill(skill="team-perf-opt", args="--max-branches=3 <task-description>") # 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**:
|
**Lifecycle**:
|
||||||
```
|
```
|
||||||
User provides task description
|
User provides task description + optional --parallel-mode / --max-branches
|
||||||
-> coordinator Phase 1-3: Requirement clarification -> TeamCreate -> Create task chain
|
-> coordinator Phase 1-3: Parse flags -> TeamCreate -> Create task chain (mode-aware)
|
||||||
-> coordinator Phase 4: spawn first batch workers (background) -> STOP
|
-> coordinator Phase 4: spawn first batch workers (background) -> STOP
|
||||||
-> Worker (team-worker agent) executes -> SendMessage callback -> coordinator advances
|
-> 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):
|
**User Commands** (wake paused coordinator):
|
||||||
|
|
||||||
| Command | Action |
|
| 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 |
|
| `resume` / `continue` | Check worker states, advance next step |
|
||||||
| `revise <TASK-ID> [feedback]` | Create revision task + cascade downstream |
|
| `revise <TASK-ID> [feedback]` | Create revision task + cascade downstream (scoped to branch) |
|
||||||
| `feedback <text>` | Analyze feedback impact, create targeted revision chain |
|
| `feedback <text>` | Analyze feedback impact, create targeted revision chain |
|
||||||
| `recheck` | Re-run quality check |
|
| `recheck` | Re-run quality check |
|
||||||
| `improve [dimension]` | Auto-improve weakest dimension |
|
| `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 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
|
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] [benchmarker]
|
||||||
PROFILE-001 --> STRATEGY-001 --> IMPL-001 --> | BENCH-001 |
|
^ |
|
||||||
[profiler] [strategist] [optimizer] | [bench] |
|
+<--FIX-001---->+
|
||||||
^ +-----------+
|
| REVIEW-001
|
||||||
| |
|
+<--------> [reviewer]
|
||||||
| +-----------+
|
(max 3 iterations) |
|
||||||
+<--FIX--->| REVIEW-001|
|
|
||||||
| | [reviewer]|
|
|
||||||
| +-----------+
|
|
||||||
| |
|
|
||||||
(max 3 iterations) v
|
|
||||||
COMPLETE
|
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
|
### Cadence Control
|
||||||
|
|
||||||
**Beat model**: Event-driven, each beat = coordinator wake -> process -> spawn -> STOP.
|
**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-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-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-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-4 | All tasks complete | Phase 5 | Interactive completion action |
|
| 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
|
### Task Metadata Registry
|
||||||
|
|
||||||
|
**Single mode** (backward compatible):
|
||||||
|
|
||||||
| Task ID | Role | Phase | Dependencies | Description |
|
| Task ID | Role | Phase | Dependencies | Description |
|
||||||
|---------|------|-------|-------------|-------------|
|
|---------|------|-------|-------------|-------------|
|
||||||
| PROFILE-001 | profiler | Stage 1 | (none) | Profile application, identify bottlenecks |
|
| 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 |
|
| 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 |
|
| 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
|
## Completion Action
|
||||||
@@ -292,9 +369,10 @@ AskUserQuestion({
|
|||||||
|
|
||||||
## Session Directory
|
## Session Directory
|
||||||
|
|
||||||
|
**Single mode**:
|
||||||
```
|
```
|
||||||
.workflow/<session-id>/
|
.workflow/<session-id>/
|
||||||
+-- session.json # Session metadata + status
|
+-- session.json # Session metadata + status + parallel_mode
|
||||||
+-- artifacts/
|
+-- artifacts/
|
||||||
| +-- baseline-metrics.json # Profiler: before-optimization metrics
|
| +-- baseline-metrics.json # Profiler: before-optimization metrics
|
||||||
| +-- bottleneck-report.md # Profiler: ranked bottleneck findings
|
| +-- bottleneck-report.md # Profiler: ranked bottleneck findings
|
||||||
@@ -312,6 +390,47 @@ AskUserQuestion({
|
|||||||
| +-- DISCUSS-REVIEW.md # Review discussion record
|
| +-- DISCUSS-REVIEW.md # Review discussion record
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Fan-out mode** (adds branches/ directory):
|
||||||
|
```
|
||||||
|
.workflow/<session-id>/
|
||||||
|
+-- 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-id>/
|
||||||
|
+-- 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
|
## Session Resume
|
||||||
|
|
||||||
Coordinator supports `--resume` / `--continue` for interrupted sessions:
|
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 |
|
| team-worker agent unavailable | Error: requires .claude/agents/team-worker.md |
|
||||||
| Completion action timeout | Default to Keep Active |
|
| Completion action timeout | Default to Keep Active |
|
||||||
| Profiling tool not available | Fallback to static analysis methods |
|
| Profiling tool not available | Fallback to static analysis methods |
|
||||||
| Benchmark regression detected | Auto-create FIX task with regression details |
|
| 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 |
|
| 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 |
|
||||||
|
|||||||
@@ -15,15 +15,30 @@ Run benchmarks comparing before/after optimization metrics. Validate that improv
|
|||||||
|
|
||||||
| Input | Source | Required |
|
| Input | Source | Required |
|
||||||
|-------|--------|----------|
|
|-------|--------|----------|
|
||||||
| Baseline metrics | <session>/artifacts/baseline-metrics.json | Yes |
|
| Baseline metrics | <session>/artifacts/baseline-metrics.json (shared) | Yes |
|
||||||
| Optimization plan | <session>/artifacts/optimization-plan.md | Yes |
|
| Optimization plan / detail | Varies by mode (see below) | Yes |
|
||||||
| shared-memory.json | <session>/wisdom/shared-memory.json | Yes |
|
| shared-memory.json | <session>/wisdom/shared-memory.json | Yes |
|
||||||
|
|
||||||
1. Extract session path from task description
|
1. Extract session path from task description
|
||||||
2. Read baseline metrics -- extract pre-optimization performance numbers
|
2. **Detect branch/pipeline context** from task description:
|
||||||
3. Read optimization plan -- extract success criteria and target thresholds
|
|
||||||
4. Load shared-memory.json for project type and optimization scope
|
| Task Description Field | Value | Context |
|
||||||
5. Detect available benchmark tools from project:
|
|----------------------|-------|---------|
|
||||||
|
| `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 `<session>/artifacts/baseline-metrics.json` (shared baseline)
|
||||||
|
- Independent: Read `<session>/artifacts/pipelines/{P}/baseline-metrics.json`
|
||||||
|
|
||||||
|
4. **Load optimization context**:
|
||||||
|
- Single: Read `<session>/artifacts/optimization-plan.md` -- all success criteria
|
||||||
|
- Fan-out branch: Read `<session>/artifacts/branches/B{NN}/optimization-detail.md` -- only this branch's criteria
|
||||||
|
- Independent: Read `<session>/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 |
|
| 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 |
|
| Makefile with bench target | Custom benchmarks | make bench |
|
||||||
| No tooling detected | Manual measurement | Timed execution via Bash |
|
| 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
|
## Phase 3: Benchmark Execution
|
||||||
|
|
||||||
@@ -60,6 +78,10 @@ Run benchmarks matching detected project type:
|
|||||||
- Collect post-optimization metrics matching baseline format
|
- Collect post-optimization metrics matching baseline format
|
||||||
- Calculate improvement percentages per metric
|
- 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
|
## Phase 4: Result Analysis
|
||||||
|
|
||||||
Compare against baseline and plan criteria:
|
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 |
|
| Regression detected | Any unrelated metric degrades > 5% | FAIL -> fix_required |
|
||||||
| Plan criteria not met | Any criterion not satisfied | FAIL -> fix_required |
|
| Plan criteria not met | Any criterion not satisfied | FAIL -> fix_required |
|
||||||
|
|
||||||
1. Write benchmark results to `<session>/artifacts/benchmark-results.json`:
|
1. Write benchmark results to output path:
|
||||||
- Per-metric: name, baseline value, current value, improvement %, verdict
|
- Single: `<session>/artifacts/benchmark-results.json`
|
||||||
- Overall verdict: PASS / WARN / FAIL
|
- Fan-out: `<session>/artifacts/branches/B{NN}/benchmark-results.json`
|
||||||
- Regression details (if any)
|
- Independent: `<session>/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 `<session>/wisdom/shared-memory.json` under `benchmarker` namespace:
|
2. Update `<session>/wisdom/shared-memory.json` under scoped namespace:
|
||||||
- Read existing -> merge `{ "benchmarker": { verdict, improvements, regressions } }` -> write back
|
- 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:
|
3. If verdict is FAIL, include detailed feedback in message for FIX task creation:
|
||||||
- Which metrics failed, by how much, suggested investigation areas
|
- Which metrics failed, by how much, suggested investigation areas
|
||||||
|
|||||||
@@ -24,17 +24,36 @@ Implement optimization changes following the strategy plan. For FIX tasks, apply
|
|||||||
|
|
||||||
| Input | Source | Required |
|
| Input | Source | Required |
|
||||||
|-------|--------|----------|
|
|-------|--------|----------|
|
||||||
| Optimization plan | <session>/artifacts/optimization-plan.md | Yes (IMPL) |
|
| Optimization plan | <session>/artifacts/optimization-plan.md | Yes (IMPL, no branch) |
|
||||||
|
| Branch optimization detail | <session>/artifacts/branches/B{NN}/optimization-detail.md | Yes (IMPL with branch) |
|
||||||
|
| Pipeline optimization plan | <session>/artifacts/pipelines/{P}/optimization-plan.md | Yes (IMPL with pipeline) |
|
||||||
| Review/bench feedback | From task description | Yes (FIX) |
|
| Review/bench feedback | From task description | Yes (FIX) |
|
||||||
| shared-memory.json | <session>/wisdom/shared-memory.json | Yes |
|
| shared-memory.json | <session>/wisdom/shared-memory.json | Yes |
|
||||||
| Wisdom files | <session>/wisdom/patterns.md | No |
|
| Wisdom files | <session>/wisdom/patterns.md | No |
|
||||||
| Context accumulator | From prior IMPL/FIX tasks | Yes (inner loop) |
|
| Context accumulator | From prior IMPL/FIX tasks | Yes (inner loop) |
|
||||||
|
|
||||||
1. Extract session path and task mode (IMPL or FIX) from task description
|
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
|
2. **Detect branch/pipeline context** from task description:
|
||||||
3. For FIX: parse review/benchmark feedback for specific issues to address
|
|
||||||
4. Use `explore` subagent to load implementation context for target files
|
| Task Description Field | Value | Context |
|
||||||
5. For inner loop: load context_accumulator from prior IMPL/FIX tasks to avoid re-reading
|
|----------------------|-------|---------|
|
||||||
|
| `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 `<session>/artifacts/optimization-plan.md` -- extract ALL priority-ordered changes
|
||||||
|
- **Fan-out branch**: Read `<session>/artifacts/branches/B{NN}/optimization-detail.md` -- extract ONLY this branch's optimization (single OPT-ID)
|
||||||
|
- **Independent pipeline**: Read `<session>/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
|
## Phase 3: Code Implementation
|
||||||
|
|
||||||
@@ -46,7 +65,9 @@ Implementation backend selection:
|
|||||||
| Direct | Single-file changes or targeted fixes | Inline Edit/Write tools |
|
| Direct | Single-file changes or targeted fixes | Inline Edit/Write tools |
|
||||||
|
|
||||||
For IMPL tasks:
|
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)
|
- Follow implementation guidance from plan (target files, patterns)
|
||||||
- Preserve existing behavior -- optimization must not break functionality
|
- 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.
|
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
|
- Files modified, optimizations applied, validation results
|
||||||
- Any discovered patterns or caveats for subsequent iterations
|
- Any discovered patterns or caveats for subsequent iterations
|
||||||
|
|
||||||
|
**Branch output paths**:
|
||||||
|
- Single: write artifacts to `<session>/artifacts/`
|
||||||
|
- Fan-out: write artifacts to `<session>/artifacts/branches/B{NN}/`
|
||||||
|
- Independent: write artifacts to `<session>/artifacts/pipelines/{P}/`
|
||||||
|
|||||||
@@ -19,15 +19,34 @@ Review optimization code changes for correctness, side effects, regression risks
|
|||||||
| Input | Source | Required |
|
| Input | Source | Required |
|
||||||
|-------|--------|----------|
|
|-------|--------|----------|
|
||||||
| Optimization code changes | From IMPL task artifacts / git diff | Yes |
|
| Optimization code changes | From IMPL task artifacts / git diff | Yes |
|
||||||
| Optimization plan | <session>/artifacts/optimization-plan.md | Yes |
|
| Optimization plan / detail | Varies by mode (see below) | Yes |
|
||||||
| Benchmark results | <session>/artifacts/benchmark-results.json | No |
|
| Benchmark results | Varies by mode (see below) | No |
|
||||||
| shared-memory.json | <session>/wisdom/shared-memory.json | Yes |
|
| shared-memory.json | <session>/wisdom/shared-memory.json | Yes |
|
||||||
|
|
||||||
1. Extract session path from task description
|
1. Extract session path from task description
|
||||||
2. Read optimization plan -- understand intended changes and success criteria
|
2. **Detect branch/pipeline context** from task description:
|
||||||
3. Load shared-memory.json for optimizer namespace (files modified, patterns applied)
|
|
||||||
4. Identify changed files from optimizer context -- read each modified file
|
| Task Description Field | Value | Context |
|
||||||
5. If benchmark results available, read for cross-reference with code quality
|
|----------------------|-------|---------|
|
||||||
|
| `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 `<session>/artifacts/optimization-plan.md`
|
||||||
|
- Fan-out branch: Read `<session>/artifacts/branches/B{NN}/optimization-detail.md`
|
||||||
|
- Independent: Read `<session>/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: `<session>/artifacts/benchmark-results.json`
|
||||||
|
- Fan-out: `<session>/artifacts/branches/B{NN}/benchmark-results.json`
|
||||||
|
- Independent: `<session>/artifacts/pipelines/{P}/benchmark-results.json`
|
||||||
|
|
||||||
## Phase 3: Multi-Dimension Review
|
## 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 |
|
| 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 |
|
| REJECT | Has Critical findings or fundamental approach flaw | Send fix_required + flag for strategist escalation |
|
||||||
|
|
||||||
1. Write review report to `<session>/artifacts/review-report.md`:
|
1. Write review report to scoped output path:
|
||||||
- Per-dimension findings with severity, file:line, description
|
- Single: `<session>/artifacts/review-report.md`
|
||||||
- Overall verdict with rationale
|
- Fan-out: `<session>/artifacts/branches/B{NN}/review-report.md`
|
||||||
- Specific fix instructions for REVISE/REJECT verdicts
|
- Independent: `<session>/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 `<session>/wisdom/shared-memory.json` under `reviewer` namespace:
|
2. Update `<session>/wisdom/shared-memory.json` under scoped namespace:
|
||||||
- Read existing -> merge `{ "reviewer": { verdict, finding_count, critical_count, dimensions_reviewed } }` -> write back
|
- 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 `<session>/discussions/DISCUSS-REVIEW.md`
|
3. If DISCUSS-REVIEW was triggered, record discussion summary in `<session>/discussions/DISCUSS-REVIEW.md` (or `DISCUSS-REVIEW-B{NN}.md` for branch-scoped discussions)
|
||||||
|
|||||||
@@ -62,12 +62,53 @@ Define measurable success criteria per optimization (target metric value or impr
|
|||||||
## Phase 4: Plan Output
|
## Phase 4: Plan Output
|
||||||
|
|
||||||
1. Write optimization plan to `<session>/artifacts/optimization-plan.md`:
|
1. Write optimization plan to `<session>/artifacts/optimization-plan.md`:
|
||||||
- Priority-ordered list of optimizations
|
|
||||||
- Per optimization: target bottleneck, strategy, expected improvement %, risk level
|
Each optimization MUST have a unique OPT-ID and self-contained detail block:
|
||||||
- Success criteria: specific metric thresholds to verify
|
|
||||||
- Implementation guidance: files to modify, patterns to apply
|
```markdown
|
||||||
|
### OPT-001: <title>
|
||||||
|
- 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:
|
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`
|
3. If DISCUSS-OPT was triggered, record discussion summary in `<session>/discussions/DISCUSS-OPT.md`
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Command: Dispatch
|
# 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
|
## 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 |
|
| User requirement | From coordinator Phase 1 | Yes |
|
||||||
| Session folder | From coordinator Phase 2 | Yes |
|
| Session folder | From coordinator Phase 2 | Yes |
|
||||||
| Pipeline definition | From SKILL.md Pipeline Definitions | 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
|
1. Load user requirement and optimization scope from session.json
|
||||||
2. Load pipeline stage definitions from SKILL.md Task Metadata Registry
|
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
|
### Task Description Template
|
||||||
|
|
||||||
@@ -32,20 +36,33 @@ TASK:
|
|||||||
CONTEXT:
|
CONTEXT:
|
||||||
- Session: <session-folder>
|
- Session: <session-folder>
|
||||||
- Scope: <optimization-scope>
|
- Scope: <optimization-scope>
|
||||||
|
- Branch: <branch-id or 'none'>
|
||||||
- Upstream artifacts: <artifact-1>, <artifact-2>
|
- Upstream artifacts: <artifact-1>, <artifact-2>
|
||||||
- Shared memory: <session>/wisdom/shared-memory.json
|
- Shared memory: <session>/wisdom/shared-memory.json
|
||||||
EXPECTED: <deliverable path> + <quality criteria>
|
EXPECTED: <deliverable path> + <quality criteria>
|
||||||
CONSTRAINTS: <scope limits, focus areas>
|
CONSTRAINTS: <scope limits, focus areas>
|
||||||
---
|
---
|
||||||
InnerLoop: <true|false>",
|
InnerLoop: <true|false>
|
||||||
|
BranchId: <B01|A|none>",
|
||||||
blockedBy: [<dependency-list>],
|
blockedBy: [<dependency-list>],
|
||||||
status: "pending"
|
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):
|
**PROFILE-001** (profiler, Stage 1):
|
||||||
```
|
```
|
||||||
@@ -59,6 +76,7 @@ TASK:
|
|||||||
CONTEXT:
|
CONTEXT:
|
||||||
- Session: <session-folder>
|
- Session: <session-folder>
|
||||||
- Scope: <optimization-scope>
|
- Scope: <optimization-scope>
|
||||||
|
- Branch: none
|
||||||
- Shared memory: <session>/wisdom/shared-memory.json
|
- Shared memory: <session>/wisdom/shared-memory.json
|
||||||
EXPECTED: <session>/artifacts/baseline-metrics.json + <session>/artifacts/bottleneck-report.md | Quantified metrics with evidence
|
EXPECTED: <session>/artifacts/baseline-metrics.json + <session>/artifacts/bottleneck-report.md | Quantified metrics with evidence
|
||||||
CONSTRAINTS: Focus on <optimization-scope> | Profile before any changes
|
CONSTRAINTS: Focus on <optimization-scope> | Profile before any changes
|
||||||
@@ -77,13 +95,15 @@ TASK:
|
|||||||
- Analyze bottleneck report and baseline metrics
|
- Analyze bottleneck report and baseline metrics
|
||||||
- Select optimization strategies per bottleneck type
|
- Select optimization strategies per bottleneck type
|
||||||
- Prioritize by impact/effort ratio, define success criteria
|
- 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:
|
CONTEXT:
|
||||||
- Session: <session-folder>
|
- Session: <session-folder>
|
||||||
- Scope: <optimization-scope>
|
- Scope: <optimization-scope>
|
||||||
|
- Branch: none
|
||||||
- Upstream artifacts: baseline-metrics.json, bottleneck-report.md
|
- Upstream artifacts: baseline-metrics.json, bottleneck-report.md
|
||||||
- Shared memory: <session>/wisdom/shared-memory.json
|
- Shared memory: <session>/wisdom/shared-memory.json
|
||||||
EXPECTED: <session>/artifacts/optimization-plan.md | Priority-ordered with improvement targets
|
EXPECTED: <session>/artifacts/optimization-plan.md | Priority-ordered with improvement targets, discrete OPT-IDs
|
||||||
CONSTRAINTS: Focus on highest-impact optimizations | Risk assessment required
|
CONSTRAINTS: Focus on highest-impact optimizations | Risk assessment required | Non-overlapping file targets per OPT-ID
|
||||||
---
|
---
|
||||||
InnerLoop: false",
|
InnerLoop: false",
|
||||||
blockedBy: ["PROFILE-001"],
|
blockedBy: ["PROFILE-001"],
|
||||||
@@ -103,6 +123,7 @@ TASK:
|
|||||||
CONTEXT:
|
CONTEXT:
|
||||||
- Session: <session-folder>
|
- Session: <session-folder>
|
||||||
- Scope: <optimization-scope>
|
- Scope: <optimization-scope>
|
||||||
|
- Branch: none
|
||||||
- Upstream artifacts: optimization-plan.md
|
- Upstream artifacts: optimization-plan.md
|
||||||
- Shared memory: <session>/wisdom/shared-memory.json
|
- Shared memory: <session>/wisdom/shared-memory.json
|
||||||
EXPECTED: Modified source files + validation passing | Optimizations applied without regressions
|
EXPECTED: Modified source files + validation passing | Optimizations applied without regressions
|
||||||
@@ -126,6 +147,7 @@ TASK:
|
|||||||
CONTEXT:
|
CONTEXT:
|
||||||
- Session: <session-folder>
|
- Session: <session-folder>
|
||||||
- Scope: <optimization-scope>
|
- Scope: <optimization-scope>
|
||||||
|
- Branch: none
|
||||||
- Upstream artifacts: baseline-metrics.json, optimization-plan.md
|
- Upstream artifacts: baseline-metrics.json, optimization-plan.md
|
||||||
- Shared memory: <session>/wisdom/shared-memory.json
|
- Shared memory: <session>/wisdom/shared-memory.json
|
||||||
EXPECTED: <session>/artifacts/benchmark-results.json | Per-metric comparison with verdicts
|
EXPECTED: <session>/artifacts/benchmark-results.json | Per-metric comparison with verdicts
|
||||||
@@ -149,6 +171,7 @@ TASK:
|
|||||||
CONTEXT:
|
CONTEXT:
|
||||||
- Session: <session-folder>
|
- Session: <session-folder>
|
||||||
- Scope: <optimization-scope>
|
- Scope: <optimization-scope>
|
||||||
|
- Branch: none
|
||||||
- Upstream artifacts: optimization-plan.md, benchmark-results.json (if available)
|
- Upstream artifacts: optimization-plan.md, benchmark-results.json (if available)
|
||||||
- Shared memory: <session>/wisdom/shared-memory.json
|
- Shared memory: <session>/wisdom/shared-memory.json
|
||||||
EXPECTED: <session>/artifacts/review-report.md | Per-dimension findings with severity
|
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
|
## Phase 4: Validation
|
||||||
|
|
||||||
Verify task chain integrity:
|
Verify task chain integrity:
|
||||||
|
|
||||||
| Check | Method | Expected |
|
| Check | Method | Expected |
|
||||||
|-------|--------|----------|
|
|-------|--------|----------|
|
||||||
| All 5 tasks created | TaskList count | 5 tasks |
|
| Task count correct | TaskList count | single: 5, auto/fan-out: 2 (pre-CP-2.5), independent: 5*M |
|
||||||
| Dependencies correct | STRATEGY blocks on PROFILE, IMPL blocks on STRATEGY, BENCH+REVIEW block on IMPL | All valid |
|
| Dependencies correct | Trace dependency graph | Acyclic, correct blockedBy |
|
||||||
| No circular dependencies | Trace dependency graph | Acyclic |
|
| 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 |
|
| 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.
|
If validation fails, fix the specific task and re-validate.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Command: Monitor
|
# 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
|
## 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 |
|
| Trigger event | From Entry Router detection | Yes |
|
||||||
| Pipeline definition | From SKILL.md | 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
|
2. Run TaskList() to get current task statuses
|
||||||
3. Identify trigger event type from Entry Router
|
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.
|
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:
|
2. Mark task as completed:
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -29,15 +36,23 @@ TaskUpdate({ taskId: "<task-id>", status: "completed" })
|
|||||||
```
|
```
|
||||||
|
|
||||||
3. Record completion in session state
|
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 |
|
| Completed Task | Checkpoint | Action |
|
||||||
|---------------|------------|--------|
|
|---------------|------------|--------|
|
||||||
| PROFILE-001 | CP-1 | Notify user: bottleneck report ready for review |
|
| PROFILE-001 / PROFILE-{P}01 | CP-1 | Notify user: bottleneck report ready for review |
|
||||||
| STRATEGY-001 | CP-2 | Notify user: optimization plan ready for review |
|
| STRATEGY-001 / STRATEGY-{P}01 | CP-2 | Notify user: optimization plan ready for review |
|
||||||
| BENCH-001 or REVIEW-001 | CP-3 | Check verdicts (see Review-Fix Cycle below) |
|
| 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
|
### 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
|
4. STOP after spawning -- wait for next callback
|
||||||
|
|
||||||
### Review-Fix Cycle (CP-3)
|
### 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:
|
When both BENCH-001 and REVIEW-001 are completed:
|
||||||
|
|
||||||
1. Read benchmark verdict from shared-memory (benchmarker namespace)
|
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 |
|
| FAIL | REVISE/REJECT | Create FIX task with combined feedback |
|
||||||
| Any | REJECT | Create FIX task + flag for strategist re-evaluation |
|
| 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 |
|
| Cycle Count | Action |
|
||||||
|-------------|--------|
|
|-------------|--------|
|
||||||
| < 3 | Create FIX task, increment cycle count |
|
| < 3 | Create FIX task, increment cycle count for this branch/pipeline |
|
||||||
| >= 3 | Escalate to user with summary of remaining issues |
|
| >= 3 | Escalate THIS branch/pipeline to user. Other branches continue |
|
||||||
|
|
||||||
4. Create FIX task if needed:
|
#### FIX Task Creation (branched)
|
||||||
|
|
||||||
|
**Fan-out mode**:
|
||||||
```
|
```
|
||||||
TaskCreate({
|
TaskCreate({
|
||||||
subject: "FIX-<N>",
|
subject: "FIX-B{NN}-{cycle}",
|
||||||
description: "PURPOSE: Fix issues identified by review/benchmark | Success: All flagged issues resolved
|
description: "PURPOSE: Fix issues in branch B{NN} from review/benchmark | Success: All flagged issues resolved
|
||||||
TASK:
|
TASK:
|
||||||
- Address review findings: <specific-findings>
|
- Address review findings: <specific-findings>
|
||||||
- Fix benchmark regressions: <specific-regressions>
|
- Fix benchmark regressions: <specific-regressions>
|
||||||
- Re-validate after fixes
|
- Re-validate after fixes
|
||||||
CONTEXT:
|
CONTEXT:
|
||||||
- Session: <session-folder>
|
- Session: <session-folder>
|
||||||
- Upstream artifacts: review-report.md, benchmark-results.json
|
- Branch: B{NN}
|
||||||
- Shared memory: <session>/wisdom/shared-memory.json
|
- Upstream artifacts: branches/B{NN}/review-report.md, branches/B{NN}/benchmark-results.json
|
||||||
EXPECTED: Fixed source files | All flagged issues addressed
|
- Shared memory: <session>/wisdom/shared-memory.json (namespace: optimizer.B{NN})
|
||||||
CONSTRAINTS: Targeted fixes only | Do not introduce new changes
|
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: [],
|
blockedBy: [],
|
||||||
status: "pending"
|
status: "pending"
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
5. Create new BENCH and REVIEW tasks blocked on FIX task
|
Create new BENCH and REVIEW with retry suffix:
|
||||||
6. Proceed to handleSpawnNext (spawns optimizer for FIX task)
|
- `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
|
### handleCheck
|
||||||
|
|
||||||
Output current pipeline status without advancing.
|
Output current pipeline status grouped by branch/pipeline.
|
||||||
|
|
||||||
1. Build status graph from task list:
|
|
||||||
|
|
||||||
|
**Single mode** (unchanged):
|
||||||
```
|
```
|
||||||
Pipeline Status:
|
Pipeline Status:
|
||||||
[DONE] PROFILE-001 (profiler) -> bottleneck-report.md
|
[DONE] PROFILE-001 (profiler) -> bottleneck-report.md
|
||||||
@@ -139,7 +210,47 @@ Fix Cycles: 0/3
|
|||||||
Session: <session-id>
|
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
|
### handleResume
|
||||||
|
|
||||||
@@ -148,7 +259,8 @@ Resume pipeline after user pause or interruption.
|
|||||||
1. Audit task list for inconsistencies:
|
1. Audit task list for inconsistencies:
|
||||||
- Tasks stuck in "in_progress" -> reset to "pending"
|
- Tasks stuck in "in_progress" -> reset to "pending"
|
||||||
- Tasks with completed blockers but still "pending" -> include in spawn list
|
- 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
|
### handleConsensus
|
||||||
|
|
||||||
@@ -156,46 +268,65 @@ Handle consensus_blocked signals from discuss rounds.
|
|||||||
|
|
||||||
| Severity | Action |
|
| Severity | Action |
|
||||||
|----------|--------|
|
|----------|--------|
|
||||||
| HIGH | Pause pipeline, notify user with findings summary |
|
| HIGH | Pause pipeline (or branch), notify user with findings summary |
|
||||||
| MEDIUM | Create revision task for the blocked role |
|
| MEDIUM | Create revision task for the blocked role (scoped to branch if applicable) |
|
||||||
| LOW | Log finding, continue pipeline |
|
| LOW | Log finding, continue pipeline |
|
||||||
|
|
||||||
### handleComplete
|
### handleComplete
|
||||||
|
|
||||||
Triggered when all pipeline tasks are completed and no fix cycles remain.
|
Triggered when all pipeline tasks are completed and no fix cycles remain.
|
||||||
|
|
||||||
1. Verify all tasks have status "completed":
|
**Completion check varies by mode**:
|
||||||
|
|
||||||
```
|
| Mode | Completion Condition |
|
||||||
TaskList()
|
|------|---------------------|
|
||||||
```
|
| 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
|
**Aggregate results** before transitioning to Phase 5:
|
||||||
3. If all completed, transition to coordinator Phase 5 (Report + Completion Action)
|
|
||||||
|
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
|
### handleRevise
|
||||||
|
|
||||||
Triggered by user "revise <TASK-ID> [feedback]" command.
|
Triggered by user "revise <TASK-ID> [feedback]" command.
|
||||||
|
|
||||||
1. Parse target task ID and optional feedback
|
1. Parse target task ID and optional feedback
|
||||||
2. Create revision task with same role but updated requirements
|
2. Detect branch/pipeline from task ID pattern
|
||||||
3. Set blockedBy to empty (immediate execution)
|
3. Create revision task with same role but updated requirements, scoped to branch
|
||||||
4. Cascade: create new downstream tasks that depend on the revised task
|
4. Set blockedBy to empty (immediate execution)
|
||||||
5. Proceed to handleSpawnNext
|
5. Cascade: create new downstream tasks within same branch only
|
||||||
|
6. Proceed to handleSpawnNext
|
||||||
|
|
||||||
### handleFeedback
|
### handleFeedback
|
||||||
|
|
||||||
Triggered by user "feedback <text>" command.
|
Triggered by user "feedback <text>" command.
|
||||||
|
|
||||||
1. Analyze feedback text to determine impact scope
|
1. Analyze feedback text to determine impact scope
|
||||||
2. Identify which pipeline stage and role should handle the feedback
|
2. Identify which pipeline stage, role, and branch/pipeline should handle the feedback
|
||||||
3. Create targeted revision task
|
3. Create targeted revision task (scoped to branch if applicable)
|
||||||
4. Proceed to handleSpawnNext
|
4. Proceed to handleSpawnNext
|
||||||
|
|
||||||
## Phase 4: State Persistence
|
## Phase 4: State Persistence
|
||||||
|
|
||||||
After every handler execution:
|
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
|
2. Verify task list consistency
|
||||||
3. STOP and wait for next event
|
3. STOP and wait for next event
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ When coordinator is invoked, detect invocation type:
|
|||||||
| Detection | Condition | Handler |
|
| Detection | Condition | Handler |
|
||||||
|-----------|-----------|---------|
|
|-----------|-----------|---------|
|
||||||
| Worker callback | Message contains role tag [profiler], [strategist], [optimizer], [benchmarker], [reviewer] | -> handleCallback |
|
| 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 |
|
| Consensus blocked | Message contains "consensus_blocked" | -> handleConsensus |
|
||||||
| Status check | Arguments contain "check" or "status" | -> handleCheck |
|
| Status check | Arguments contain "check" or "status" | -> handleCheck |
|
||||||
| Manual resume | Arguments contain "resume" or "continue" | -> handleResume |
|
| 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):
|
1. **Load session context** (if exists):
|
||||||
- Scan `.workflow/.team/PERF-OPT-*/team-session.json` for active/paused sessions
|
- 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:
|
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 "check", "status", "resume", "continue" keywords
|
||||||
- Check for "consensus_blocked" signal
|
- Check for "consensus_blocked" signal
|
||||||
|
|
||||||
@@ -114,15 +116,26 @@ TeamCreate({ team_name: "perf-opt" })
|
|||||||
## Phase 1: Requirement Clarification
|
## Phase 1: Requirement Clarification
|
||||||
|
|
||||||
1. Parse user task description from $ARGUMENTS
|
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 |
|
| Signal | Target |
|
||||||
|--------|--------|
|
|--------|--------|
|
||||||
| Specific file/module mentioned | Scoped optimization |
|
| Specific file/module mentioned | Scoped optimization |
|
||||||
| "slow", "performance", generic | Full application profiling |
|
| "slow", "performance", generic | Full application profiling |
|
||||||
| Specific metric mentioned (FCP, memory, startup) | Targeted metric optimization |
|
| 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({
|
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")
|
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:
|
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:
|
4. Create team:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"skill_name": "team-perf-opt",
|
"skill_name": "team-perf-opt",
|
||||||
"skill_path": ".claude/skills/team-perf-opt/",
|
"skill_path": ".claude/skills/team-perf-opt/",
|
||||||
"worker_agent": "team-worker",
|
"worker_agent": "team-worker",
|
||||||
"pipeline_type": "Linear with Review-Fix Cycle",
|
"pipeline_type": "Linear with Review-Fix Cycle (Parallel-Capable)",
|
||||||
"completion_action": "interactive",
|
"completion_action": "interactive",
|
||||||
"has_inline_discuss": true,
|
"has_inline_discuss": true,
|
||||||
"has_shared_explore": 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": {
|
"pipeline": {
|
||||||
"stages": [
|
"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"
|
"diagram": "See pipeline-diagram section"
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -187,22 +215,50 @@
|
|||||||
{
|
{
|
||||||
"name": "Performance Baseline",
|
"name": "Performance Baseline",
|
||||||
"path": "<session>/artifacts/baseline-metrics.json",
|
"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",
|
"name": "Bottleneck Report",
|
||||||
"path": "<session>/artifacts/bottleneck-report.md",
|
"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",
|
"name": "Optimization Plan",
|
||||||
"path": "<session>/artifacts/optimization-plan.md",
|
"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",
|
"name": "Benchmark Results",
|
||||||
"path": "<session>/artifacts/benchmark-results.json",
|
"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}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ Trigger `workflow-lite-planex` → dispatches to Phase 1 (lite-plan). Phase 1 in
|
|||||||
| Phase | Document | Description |
|
| 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 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
|
## 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)
|
1. Collect preferences via AskUserQuestion (autoYes, forceExplore)
|
||||||
2. Enhance prompt with project context availability
|
2. Enhance prompt with project context availability
|
||||||
3. Read phases/01-lite-plan.md
|
3. Read phases/01-lite-plan.md
|
||||||
4. Execute lite-plan pipeline (Phase 1-5 within the phase doc)
|
4. Execute lite-plan pipeline (LP-Phase 1-5 within the phase doc)
|
||||||
5. lite-plan Phase 5 directly reads and executes Phase 2 (lite-execute) with executionContext
|
5. lite-plan LP-Phase 5 directly reads and executes Phase 2 (lite-execute) with executionContext
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -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.
|
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
|
- Two-step confirmation: plan display → multi-dimensional input collection
|
||||||
- Execution handoff with complete context to lite-execute
|
- 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
|
## Input
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -53,42 +61,42 @@ When `workflowPreferences.autoYes === true`:
|
|||||||
## Execution Process
|
## Execution Process
|
||||||
|
|
||||||
```
|
```
|
||||||
Phase 1: Task Analysis & Exploration
|
LP-Phase 1: Task Analysis & Exploration
|
||||||
├─ Parse input (description or .md file)
|
├─ Parse input (description or .md file)
|
||||||
├─ intelligent complexity assessment (Low/Medium/High)
|
├─ intelligent complexity assessment (Low/Medium/High)
|
||||||
├─ Exploration decision (auto-detect or workflowPreferences.forceExplore)
|
├─ Exploration decision (auto-detect or workflowPreferences.forceExplore)
|
||||||
├─ Context protection: If file reading ≥50k chars → force cli-explore-agent
|
├─ Context protection: If file reading ≥50k chars → force cli-explore-agent
|
||||||
└─ Decision:
|
└─ Decision:
|
||||||
├─ needsExploration=true → Launch parallel cli-explore-agents (1-4 based on complexity)
|
├─ 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
|
├─ Aggregate clarification_needs from all exploration angles
|
||||||
├─ Deduplicate similar questions
|
├─ Deduplicate similar questions
|
||||||
└─ Decision:
|
└─ Decision:
|
||||||
├─ Has clarifications → AskUserQuestion (max 4 questions per round, multiple rounds allowed)
|
├─ 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)
|
LP-Phase 3: Planning (NO CODE EXECUTION - planning only)
|
||||||
└─ Decision (based on Phase 1 complexity):
|
└─ 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
|
├─ 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)
|
└─ 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)
|
├─ Display plan summary (tasks, complexity, estimated time)
|
||||||
└─ AskUserQuestion:
|
└─ AskUserQuestion:
|
||||||
├─ Confirm: Allow / Modify / Cancel
|
├─ Confirm: Allow / Modify / Cancel
|
||||||
├─ Execution: Agent / Codex / Auto
|
├─ Execution: Agent / Codex / Auto
|
||||||
└─ Review: Gemini / Agent / Skip
|
└─ Review: Gemini / Agent / Skip
|
||||||
|
|
||||||
Phase 5: Execute
|
LP-Phase 5: Execute
|
||||||
├─ Build executionContext (plan + explorations + clarifications + selections)
|
├─ Build executionContext (plan + explorations + clarifications + selections)
|
||||||
└─ Direct handoff: Read phases/02-lite-execute.md → Execute with executionContext (Mode 1)
|
└─ Direct handoff: Read phases/02-lite-execute.md → Execute with executionContext (Mode 1)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
|
||||||
### Phase 1: Intelligent Multi-Angle Exploration
|
### LP-Phase 1: Intelligent Multi-Angle Exploration
|
||||||
|
|
||||||
**Session Setup** (MANDATORY - follow exactly):
|
**Session Setup** (MANDATORY - follow exactly):
|
||||||
```javascript
|
```javascript
|
||||||
@@ -104,14 +112,14 @@ const sessionFolder = `.workflow/.lite-plan/${sessionId}`
|
|||||||
bash(`mkdir -p ${sessionFolder} && test -d ${sessionFolder} && echo "SUCCESS: ${sessionFolder}" || echo "FAILED: ${sessionFolder}"`)
|
bash(`mkdir -p ${sessionFolder} && test -d ${sessionFolder} && echo "SUCCESS: ${sessionFolder}" || echo "FAILED: ${sessionFolder}"`)
|
||||||
```
|
```
|
||||||
|
|
||||||
**TodoWrite (Phase 1 start)**:
|
**TodoWrite (LP-Phase 1 start)**:
|
||||||
```javascript
|
```javascript
|
||||||
TodoWrite({ todos: [
|
TodoWrite({ todos: [
|
||||||
{ content: "Phase 1: Exploration", status: "in_progress", activeForm: "Exploring codebase" },
|
{ content: "LP-Phase 1: Exploration", status: "in_progress", activeForm: "Exploring codebase" },
|
||||||
{ content: "Phase 2: Clarification", status: "pending", activeForm: "Collecting clarifications" },
|
{ content: "LP-Phase 2: Clarification", status: "pending", activeForm: "Collecting clarifications" },
|
||||||
{ content: "Phase 3: Planning", status: "pending", activeForm: "Generating plan" },
|
{ content: "LP-Phase 3: Planning", status: "pending", activeForm: "Generating plan" },
|
||||||
{ content: "Phase 4: Confirmation", status: "pending", activeForm: "Awaiting confirmation" },
|
{ content: "LP-Phase 4: Confirmation", status: "pending", activeForm: "Awaiting confirmation" },
|
||||||
{ content: "Phase 5: Execution", status: "pending", activeForm: "Executing tasks" }
|
{ content: "LP-Phase 5: Execution", status: "pending", activeForm: "Executing tasks" }
|
||||||
]})
|
]})
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -129,7 +137,7 @@ needsExploration = workflowPreferences.forceExplore ? true
|
|||||||
|
|
||||||
if (!needsExploration) {
|
if (!needsExploration) {
|
||||||
// Skip exploration — analysis context already in task description (or not needed)
|
// 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()
|
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
|
```javascript
|
||||||
TodoWrite({ todos: [
|
TodoWrite({ todos: [
|
||||||
{ content: "Phase 1: Exploration", status: "completed", activeForm: "Exploring codebase" },
|
{ content: "LP-Phase 1: Exploration", status: "completed", activeForm: "Exploring codebase" },
|
||||||
{ content: "Phase 2: Clarification", status: "in_progress", activeForm: "Collecting clarifications" },
|
{ content: "LP-Phase 2: Clarification", status: "in_progress", activeForm: "Collecting clarifications" },
|
||||||
{ content: "Phase 3: Planning", status: "pending", activeForm: "Generating plan" },
|
{ content: "LP-Phase 3: Planning", status: "pending", activeForm: "Generating plan" },
|
||||||
{ content: "Phase 4: Confirmation", status: "pending", activeForm: "Awaiting confirmation" },
|
{ content: "LP-Phase 4: Confirmation", status: "pending", activeForm: "Awaiting confirmation" },
|
||||||
{ content: "Phase 5: Execution", status: "pending", activeForm: "Executing tasks" }
|
{ 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
|
**Skip if**: No exploration or `clarification_needs` is empty across all explorations
|
||||||
|
|
||||||
@@ -379,7 +387,7 @@ if (autoYes) {
|
|||||||
// Auto mode: Skip clarification phase
|
// Auto mode: Skip clarification phase
|
||||||
console.log(`[Auto] Skipping ${dedupedClarifications.length} clarification questions`)
|
console.log(`[Auto] Skipping ${dedupedClarifications.length} clarification questions`)
|
||||||
console.log(`Proceeding to planning with exploration results...`)
|
console.log(`Proceeding to planning with exploration results...`)
|
||||||
// Continue to Phase 3
|
// Continue to LP-Phase 3
|
||||||
} else if (dedupedClarifications.length > 0) {
|
} else if (dedupedClarifications.length > 0) {
|
||||||
// Interactive mode: Multi-round clarification
|
// Interactive mode: Multi-round clarification
|
||||||
const BATCH_SIZE = 4
|
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 生成后执行):
|
**Executor Assignment** (Claude 智能分配,plan 生成后执行):
|
||||||
|
|
||||||
@@ -494,7 +502,7 @@ const plan = {
|
|||||||
// Step 6: Write plan overview to session folder
|
// Step 6: Write plan overview to session folder
|
||||||
Write(`${sessionFolder}/plan.json`, JSON.stringify(plan, null, 2))
|
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:
|
**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`
|
**Output**: `${sessionFolder}/plan.json`
|
||||||
|
|
||||||
**TodoWrite (Phase 3 complete)**:
|
**TodoWrite (LP-Phase 3 complete)**:
|
||||||
```javascript
|
```javascript
|
||||||
TodoWrite({ todos: [
|
TodoWrite({ todos: [
|
||||||
{ content: "Phase 1: Exploration", status: "completed", activeForm: "Exploring codebase" },
|
{ content: "LP-Phase 1: Exploration", status: "completed", activeForm: "Exploring codebase" },
|
||||||
{ content: "Phase 2: Clarification", status: "completed", activeForm: "Collecting clarifications" },
|
{ content: "LP-Phase 2: Clarification", status: "completed", activeForm: "Collecting clarifications" },
|
||||||
{ content: "Phase 3: Planning", status: "completed", activeForm: "Generating plan" },
|
{ content: "LP-Phase 3: Planning", status: "completed", activeForm: "Generating plan" },
|
||||||
{ content: "Phase 4: Confirmation", status: "in_progress", activeForm: "Awaiting confirmation" },
|
{ content: "LP-Phase 4: Confirmation", status: "in_progress", activeForm: "Awaiting confirmation" },
|
||||||
{ content: "Phase 5: Execution", status: "pending", activeForm: "Executing tasks" }
|
{ 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**
|
**Step 4.1: Display Plan**
|
||||||
```javascript
|
```javascript
|
||||||
@@ -684,22 +692,22 @@ if (autoYes) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**TodoWrite (Phase 4 confirmed)**:
|
**TodoWrite (LP-Phase 4 confirmed)**:
|
||||||
```javascript
|
```javascript
|
||||||
const executionLabel = userSelection.execution_method
|
const executionLabel = userSelection.execution_method
|
||||||
|
|
||||||
TodoWrite({ todos: [
|
TodoWrite({ todos: [
|
||||||
{ content: "Phase 1: Exploration", status: "completed", activeForm: "Exploring codebase" },
|
{ content: "LP-Phase 1: Exploration", status: "completed", activeForm: "Exploring codebase" },
|
||||||
{ content: "Phase 2: Clarification", status: "completed", activeForm: "Collecting clarifications" },
|
{ content: "LP-Phase 2: Clarification", status: "completed", activeForm: "Collecting clarifications" },
|
||||||
{ content: "Phase 3: Planning", status: "completed", activeForm: "Generating plan" },
|
{ content: "LP-Phase 3: Planning", status: "completed", activeForm: "Generating plan" },
|
||||||
{ content: `Phase 4: Confirmed [${executionLabel}]`, status: "completed", activeForm: "Confirmed" },
|
{ content: `LP-Phase 4: Confirmed [${executionLabel}]`, status: "completed", activeForm: "Confirmed" },
|
||||||
{ content: `Phase 5: Execution [${executionLabel}]`, status: "in_progress", activeForm: `Executing [${executionLabel}]` }
|
{ 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.
|
**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
|
## 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).
|
||||||
|
|||||||
157
ccw/frontend/src/components/ChunkErrorBoundary.tsx
Normal file
157
ccw/frontend/src/components/ChunkErrorBoundary.tsx
Normal file
@@ -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>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
12
ccw/frontend/src/components/PageSkeleton.tsx
Normal file
12
ccw/frontend/src/components/PageSkeleton.tsx
Normal file
@@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
import { createBrowserRouter, RouteObject, Navigate } from 'react-router-dom';
|
import { createBrowserRouter, RouteObject, Navigate } from 'react-router-dom';
|
||||||
import { lazy, Suspense } from 'react';
|
import { lazy, Suspense } from 'react';
|
||||||
import { AppShell } from '@/components/layout';
|
import { AppShell } from '@/components/layout';
|
||||||
|
import { ChunkErrorBoundary } from '@/components/ChunkErrorBoundary';
|
||||||
|
import { PageSkeleton } from '@/components/PageSkeleton';
|
||||||
|
|
||||||
// Import HomePage directly (no lazy - needed immediately)
|
// Import HomePage directly (no lazy - needed immediately)
|
||||||
import { HomePage } from '@/pages/HomePage';
|
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 AnalysisPage = lazy(() => import('@/pages/AnalysisPage').then(m => ({ default: m.AnalysisPage })));
|
||||||
const SpecsSettingsPage = lazy(() => import('@/pages/SpecsSettingsPage').then(m => ({ default: m.SpecsSettingsPage })));
|
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 (
|
return (
|
||||||
<div className="flex items-center justify-center h-full">
|
<ChunkErrorBoundary>
|
||||||
<div className="animate-pulse text-muted-foreground">Loading...</div>
|
<Suspense fallback={<PageSkeleton />}>
|
||||||
</div>
|
{element}
|
||||||
|
</Suspense>
|
||||||
|
</ChunkErrorBoundary>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,11 +65,7 @@ function PageSkeleton() {
|
|||||||
const routes: RouteObject[] = [
|
const routes: RouteObject[] = [
|
||||||
{
|
{
|
||||||
path: 'cli-sessions/share',
|
path: 'cli-sessions/share',
|
||||||
element: (
|
element: withErrorHandling(<CliSessionSharePage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<CliSessionSharePage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
@@ -74,68 +77,36 @@ const routes: RouteObject[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'sessions',
|
path: 'sessions',
|
||||||
element: (
|
element: withErrorHandling(<SessionsPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<SessionsPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'sessions/:sessionId',
|
path: 'sessions/:sessionId',
|
||||||
element: (
|
element: withErrorHandling(<SessionDetailPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<SessionDetailPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'sessions/:sessionId/fix',
|
path: 'sessions/:sessionId/fix',
|
||||||
element: (
|
element: withErrorHandling(<FixSessionPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<FixSessionPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'sessions/:sessionId/review',
|
path: 'sessions/:sessionId/review',
|
||||||
element: (
|
element: withErrorHandling(<ReviewSessionPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<ReviewSessionPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'lite-tasks',
|
path: 'lite-tasks',
|
||||||
element: (
|
element: withErrorHandling(<LiteTasksPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<LiteTasksPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
// /lite-tasks/:sessionId route removed - now using TaskDrawer
|
// /lite-tasks/:sessionId route removed - now using TaskDrawer
|
||||||
{
|
{
|
||||||
path: 'project',
|
path: 'project',
|
||||||
element: (
|
element: withErrorHandling(<ProjectOverviewPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<ProjectOverviewPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'history',
|
path: 'history',
|
||||||
element: (
|
element: withErrorHandling(<HistoryPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<HistoryPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'orchestrator',
|
path: 'orchestrator',
|
||||||
element: (
|
element: withErrorHandling(<OrchestratorPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<OrchestratorPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'loops',
|
path: 'loops',
|
||||||
@@ -143,19 +114,11 @@ const routes: RouteObject[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'cli-viewer',
|
path: 'cli-viewer',
|
||||||
element: (
|
element: withErrorHandling(<CliViewerPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<CliViewerPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'issues',
|
path: 'issues',
|
||||||
element: (
|
element: withErrorHandling(<IssueHubPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<IssueHubPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
// Legacy routes - redirect to hub with tab parameter
|
// Legacy routes - redirect to hub with tab parameter
|
||||||
{
|
{
|
||||||
@@ -168,147 +131,75 @@ const routes: RouteObject[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'skills',
|
path: 'skills',
|
||||||
element: (
|
element: withErrorHandling(<SkillsManagerPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<SkillsManagerPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'commands',
|
path: 'commands',
|
||||||
element: (
|
element: withErrorHandling(<CommandsManagerPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<CommandsManagerPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'memory',
|
path: 'memory',
|
||||||
element: (
|
element: withErrorHandling(<MemoryPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<MemoryPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'prompts',
|
path: 'prompts',
|
||||||
element: (
|
element: withErrorHandling(<PromptHistoryPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<PromptHistoryPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'settings',
|
path: 'settings',
|
||||||
element: (
|
element: withErrorHandling(<SettingsPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<SettingsPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'settings/mcp',
|
path: 'settings/mcp',
|
||||||
element: (
|
element: withErrorHandling(<McpManagerPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<McpManagerPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'settings/endpoints',
|
path: 'settings/endpoints',
|
||||||
element: (
|
element: withErrorHandling(<EndpointsPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<EndpointsPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'settings/installations',
|
path: 'settings/installations',
|
||||||
element: (
|
element: withErrorHandling(<InstallationsPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<InstallationsPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'settings/rules',
|
path: 'settings/rules',
|
||||||
element: (
|
element: withErrorHandling(<RulesManagerPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<RulesManagerPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'settings/specs',
|
path: 'settings/specs',
|
||||||
element: (
|
element: withErrorHandling(<SpecsSettingsPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<SpecsSettingsPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'settings/codexlens',
|
path: 'settings/codexlens',
|
||||||
element: (
|
element: withErrorHandling(<CodexLensManagerPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<CodexLensManagerPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'api-settings',
|
path: 'api-settings',
|
||||||
element: (
|
element: withErrorHandling(<ApiSettingsPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<ApiSettingsPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'hooks',
|
path: 'hooks',
|
||||||
element: (
|
element: withErrorHandling(<HookManagerPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<HookManagerPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'explorer',
|
path: 'explorer',
|
||||||
element: (
|
element: withErrorHandling(<ExplorerPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<ExplorerPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'graph',
|
path: 'graph',
|
||||||
element: (
|
element: withErrorHandling(<GraphExplorerPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<GraphExplorerPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'teams',
|
path: 'teams',
|
||||||
element: (
|
element: withErrorHandling(<TeamPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<TeamPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'analysis',
|
path: 'analysis',
|
||||||
element: (
|
element: withErrorHandling(<AnalysisPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<AnalysisPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'terminal-dashboard',
|
path: 'terminal-dashboard',
|
||||||
element: (
|
element: withErrorHandling(<TerminalDashboardPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<TerminalDashboardPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'skill-hub',
|
path: 'skill-hub',
|
||||||
@@ -317,11 +208,7 @@ const routes: RouteObject[] = [
|
|||||||
// Catch-all route for 404
|
// Catch-all route for 404
|
||||||
{
|
{
|
||||||
path: '*',
|
path: '*',
|
||||||
element: (
|
element: withErrorHandling(<NotFoundPage />),
|
||||||
<Suspense fallback={<PageSkeleton />}>
|
|
||||||
<NotFoundPage />
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -39,6 +39,11 @@ const FEISHU_HOSTNAMES = ['feishu.cn', 'larksuite.com', 'lark.com'];
|
|||||||
const DINGTALK_HOSTNAMES = ['dingtalk.com', 'oapi.dingtalk.com'];
|
const DINGTALK_HOSTNAMES = ['dingtalk.com', 'oapi.dingtalk.com'];
|
||||||
const WECOM_HOSTNAMES = ['qyapi.weixin.qq.com', 'work.weixin.qq.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)
|
* Validate URL format (must be http or https)
|
||||||
*/
|
*/
|
||||||
@@ -113,6 +118,11 @@ function isValidHeaders(headers: unknown): { valid: boolean; error?: string } {
|
|||||||
if (typeof value !== 'string') {
|
if (typeof value !== 'string') {
|
||||||
return { valid: false, error: `Header '${key}' value must be a 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
|
// Block potentially dangerous headers
|
||||||
const lowerKey = key.toLowerCase();
|
const lowerKey = key.toLowerCase();
|
||||||
if (['host', 'content-length', 'connection'].includes(lowerKey)) {
|
if (['host', 'content-length', 'connection'].includes(lowerKey)) {
|
||||||
|
|||||||
@@ -549,6 +549,7 @@ onUnmounted(() => {
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 2rem;
|
padding: 0 2rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -573,6 +574,7 @@ onUnmounted(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 2rem;
|
padding: 0 2rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-visual {
|
.hero-visual {
|
||||||
@@ -743,6 +745,8 @@ onUnmounted(() => {
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(4, 1fr);
|
grid-template-columns: repeat(4, 1fr);
|
||||||
gap: 1.25rem;
|
gap: 1.25rem;
|
||||||
|
max-width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.feature-card {
|
.feature-card {
|
||||||
padding: 1.75rem;
|
padding: 1.75rem;
|
||||||
@@ -751,6 +755,8 @@ onUnmounted(() => {
|
|||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
|
box-sizing: border-box;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
.feature-card:hover {
|
.feature-card:hover {
|
||||||
transform: translateY(-4px);
|
transform: translateY(-4px);
|
||||||
@@ -800,6 +806,8 @@ onUnmounted(() => {
|
|||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
padding: 2.5rem;
|
padding: 2.5rem;
|
||||||
box-shadow: var(--vp-shadow-2);
|
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-header { display: flex; justify-content: space-between; align-items: center; }
|
||||||
.cadence-label {
|
.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.active { border-color: var(--vp-c-brand-1); background: var(--vp-c-brand-1); }
|
||||||
.tick-node.blocked { background: #ef4444; border-color: #ef4444; }
|
.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 { 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-node.active, .stage-node.done { opacity: 1; }
|
||||||
.stage-badge { min-height: 24px; margin-bottom: 0.5rem; }
|
.stage-badge { min-height: 24px; margin-bottom: 0.5rem; }
|
||||||
@@ -1281,15 +1296,27 @@ onUnmounted(() => {
|
|||||||
* ============================================ */
|
* ============================================ */
|
||||||
|
|
||||||
/* Tablet (768px - 1024px) */
|
/* Tablet (768px - 1024px) */
|
||||||
@media (max-width: 1024px) {
|
@media (max-width: var(--bp-md)) {
|
||||||
.features-grid { grid-template-columns: repeat(2, 1fr); }
|
.features-grid {
|
||||||
.hero-container { gap: 1.5rem; }
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
.hero-container {
|
||||||
|
gap: 1.5rem;
|
||||||
|
padding: 0 1.5rem;
|
||||||
|
}
|
||||||
.hero-title { font-size: 2.25rem; }
|
.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) */
|
/* 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 - add extra padding-top to clear fixed nav (56px) */
|
||||||
.hero-section {
|
.hero-section {
|
||||||
padding: 4.5rem 0 2rem;
|
padding: 4.5rem 0 2rem;
|
||||||
@@ -1373,7 +1400,6 @@ onUnmounted(() => {
|
|||||||
padding: 1.25rem;
|
padding: 1.25rem;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
}
|
||||||
.pipeline-flow {
|
.pipeline-flow {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -1389,7 +1415,7 @@ onUnmounted(() => {
|
|||||||
.law-content, .log-content { padding: 1rem; font-size: 0.8rem; min-height: 60px; }
|
.law-content, .log-content { padding: 1rem; font-size: 0.8rem; min-height: 60px; }
|
||||||
|
|
||||||
/* JSON Section */
|
/* JSON Section */
|
||||||
.json-section { padding: 0; overflow-x: hidden; }
|
.json-section { padding: 0; }
|
||||||
.json-grid {
|
.json-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -1455,7 +1481,7 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Small Mobile (< 480px) */
|
/* Small Mobile (< 480px) */
|
||||||
@media (max-width: 480px) {
|
@media (max-width: var(--bp-xs)) {
|
||||||
.hero-title { font-size: 1.5rem; }
|
.hero-title { font-size: 1.5rem; }
|
||||||
.hero-actions { flex-direction: column; width: 100%; }
|
.hero-actions { flex-direction: column; width: 100%; }
|
||||||
.hero-actions .btn-primary,
|
.hero-actions .btn-primary,
|
||||||
|
|||||||
@@ -196,13 +196,12 @@ onBeforeUnmount(() => {
|
|||||||
/* Container queries in mobile.css provide additional responsiveness */
|
/* Container queries in mobile.css provide additional responsiveness */
|
||||||
|
|
||||||
/* Mobile-specific styles */
|
/* Mobile-specific styles */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: var(--bp-sm)) {
|
||||||
.hero-extensions {
|
.hero-extensions {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
max-width: 100vw;
|
max-width: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-stats {
|
.hero-stats {
|
||||||
|
|||||||
@@ -86,12 +86,10 @@
|
|||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
max-width: 100vw !important;
|
max-width: 100vw !important;
|
||||||
overflow-x: hidden !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.Layout:has(.pro-home) {
|
.Layout:has(.pro-home) {
|
||||||
max-width: 100vw !important;
|
max-width: 100vw !important;
|
||||||
overflow-x: hidden !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure VPNav doesn't cause overflow */
|
/* Ensure VPNav doesn't cause overflow */
|
||||||
@@ -113,7 +111,6 @@
|
|||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
overflow-x: hidden !important;
|
|
||||||
box-sizing: border-box !important;
|
box-sizing: border-box !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Responsive design */
|
/* Responsive design */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: var(--bp-sm)) {
|
||||||
.demo-header {
|
.demo-header {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Mobile-Responsive Styles
|
* Mobile-Responsive Styles
|
||||||
* Breakpoints: 320px-768px (mobile), 768px-1024px (tablet), 1024px+ (desktop)
|
* Breakpoints: < 480px (xs), < 768px (sm/mobile), 768px-1024px (md/tablet), > 1024px (lg/desktop)
|
||||||
* Uses CSS custom properties from variables.css: --bp-mobile, --bp-tablet, --bp-desktop
|
* Uses CSS custom properties from variables.css: --bp-xs, --bp-sm, --bp-md, --bp-lg
|
||||||
* WCAG 2.1 AA compliant
|
* WCAG 2.1 AA compliant
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
max-width: 320px;
|
max-width: 320px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: var(--bp-sm)) {
|
||||||
.VPSidebar {
|
.VPSidebar {
|
||||||
width: var(--vp-sidebar-width, 272px);
|
width: var(--vp-sidebar-width, 272px);
|
||||||
max-width: none;
|
max-width: none;
|
||||||
@@ -31,13 +31,13 @@
|
|||||||
padding: 16px;
|
padding: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: var(--bp-sm)) {
|
||||||
.VPContent {
|
.VPContent {
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1024px) {
|
@media (min-width: var(--bp-md)) {
|
||||||
.VPContent {
|
.VPContent {
|
||||||
padding: 32px 48px;
|
padding: 32px 48px;
|
||||||
}
|
}
|
||||||
@@ -48,14 +48,14 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: var(--bp-sm)) {
|
||||||
.VPDocOutline {
|
.VPDocOutline {
|
||||||
display: block;
|
display: block;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1024px) {
|
@media (min-width: var(--bp-md)) {
|
||||||
.VPDocOutline {
|
.VPDocOutline {
|
||||||
width: 256px;
|
width: 256px;
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
/* Container Query Rules (modern browsers) */
|
/* Container Query Rules (modern browsers) */
|
||||||
@supports (container-type: inline-size) {
|
@supports (container-type: inline-size) {
|
||||||
/* Sidebar Container Queries */
|
/* Sidebar Container Queries */
|
||||||
@container sidebar (max-width: 480px) {
|
@container sidebar (max-width: var(--bp-xs)) {
|
||||||
.VPSidebar .group {
|
.VPSidebar .group {
|
||||||
padding: 12px 16px;
|
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 {
|
.VPSidebar .group {
|
||||||
padding: 16px 20px;
|
padding: 16px 20px;
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@container sidebar (min-width: 768px) {
|
@container sidebar (min-width: var(--bp-sm)) {
|
||||||
.VPSidebar .group {
|
.VPSidebar .group {
|
||||||
padding: 16px 24px;
|
padding: 16px 24px;
|
||||||
}
|
}
|
||||||
@@ -221,25 +221,25 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Generic Container-Responsive Utility Class */
|
/* Generic Container-Responsive Utility Class */
|
||||||
@container (max-width: 480px) {
|
@container (max-width: var(--bp-xs)) {
|
||||||
.container-responsive {
|
.container-responsive {
|
||||||
padding: 0 var(--spacing-fluid-xs);
|
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 {
|
.container-responsive {
|
||||||
padding: 0 var(--spacing-fluid-sm);
|
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 {
|
.container-responsive {
|
||||||
padding: 0 var(--spacing-fluid-md);
|
padding: 0 var(--spacing-fluid-md);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@container (min-width: 1024px) {
|
@container (min-width: var(--bp-md)) {
|
||||||
.container-responsive {
|
.container-responsive {
|
||||||
padding: 0 var(--spacing-fluid-lg);
|
padding: 0 var(--spacing-fluid-lg);
|
||||||
}
|
}
|
||||||
@@ -250,7 +250,7 @@
|
|||||||
* ============================================ */
|
* ============================================ */
|
||||||
|
|
||||||
/* Base Mobile Styles (320px+) */
|
/* Base Mobile Styles (320px+) */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: var(--bp-sm)) {
|
||||||
/* Typography */
|
/* Typography */
|
||||||
:root {
|
:root {
|
||||||
--vp-font-size-base: 14px;
|
--vp-font-size-base: 14px;
|
||||||
@@ -598,7 +598,7 @@
|
|||||||
/* ============================================
|
/* ============================================
|
||||||
* Tablet Styles (768px - 1024px)
|
* 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 {
|
:root {
|
||||||
--vp-content-width: 760px;
|
--vp-content-width: 760px;
|
||||||
--vp-sidebar-width: 240px;
|
--vp-sidebar-width: 240px;
|
||||||
@@ -639,7 +639,7 @@
|
|||||||
/* ============================================
|
/* ============================================
|
||||||
* Desktop Styles (1024px+)
|
* Desktop Styles (1024px+)
|
||||||
* ============================================ */
|
* ============================================ */
|
||||||
@media (min-width: 1024px) {
|
@media (min-width: var(--bp-md)) {
|
||||||
:root {
|
:root {
|
||||||
--vp-layout-max-width: 1600px;
|
--vp-layout-max-width: 1600px;
|
||||||
--vp-content-width: 960px;
|
--vp-content-width: 960px;
|
||||||
@@ -692,7 +692,7 @@
|
|||||||
/* ============================================
|
/* ============================================
|
||||||
* Large Desktop (1440px+)
|
* Large Desktop (1440px+)
|
||||||
* ============================================ */
|
* ============================================ */
|
||||||
@media (min-width: 1440px) {
|
@media (min-width: var(--bp-lg)) {
|
||||||
:root {
|
:root {
|
||||||
--vp-content-width: 1040px;
|
--vp-content-width: 1040px;
|
||||||
--vp-sidebar-width: 280px;
|
--vp-sidebar-width: 280px;
|
||||||
@@ -749,23 +749,20 @@
|
|||||||
/* ============================================
|
/* ============================================
|
||||||
* ProfessionalHome Component - Mobile Optimizations
|
* ProfessionalHome Component - Mobile Optimizations
|
||||||
* ============================================ */
|
* ============================================ */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: var(--bp-sm)) {
|
||||||
/* Root level overflow prevention */
|
/* Root level overflow prevention */
|
||||||
html, body {
|
html, body {
|
||||||
overflow-x: hidden;
|
|
||||||
max-width: 100vw;
|
max-width: 100vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* VitePress Layout container fix */
|
/* VitePress Layout container fix */
|
||||||
.Layout {
|
.Layout {
|
||||||
max-width: 100vw;
|
max-width: 100vw;
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* VPContent container fix */
|
/* VPContent container fix */
|
||||||
.VPContent {
|
.VPContent {
|
||||||
max-width: 100vw;
|
max-width: 100vw;
|
||||||
overflow-x: hidden;
|
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -774,7 +771,6 @@
|
|||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
max-width: 100vw;
|
max-width: 100vw;
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-stats {
|
.hero-stats {
|
||||||
@@ -790,7 +786,6 @@
|
|||||||
|
|
||||||
/* Prevent horizontal scroll */
|
/* Prevent horizontal scroll */
|
||||||
.pro-home {
|
.pro-home {
|
||||||
overflow-x: hidden;
|
|
||||||
max-width: 100vw;
|
max-width: 100vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -888,8 +883,7 @@
|
|||||||
/* Quick Start Section - prevent overflow */
|
/* Quick Start Section - prevent overflow */
|
||||||
.pro-home .quickstart-section {
|
.pro-home .quickstart-section {
|
||||||
padding: 3rem 0;
|
padding: 3rem 0;
|
||||||
max-width: 100vw;
|
max-width: 100%;
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pro-home .quickstart-layout {
|
.pro-home .quickstart-layout {
|
||||||
@@ -917,19 +911,17 @@
|
|||||||
/* Features section overflow fix */
|
/* Features section overflow fix */
|
||||||
.pro-home .features-section {
|
.pro-home .features-section {
|
||||||
max-width: 100vw;
|
max-width: 100vw;
|
||||||
overflow-x: hidden;
|
|
||||||
padding: 3rem 0;
|
padding: 3rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pipeline section overflow fix */
|
/* Pipeline section overflow fix */
|
||||||
.pro-home .pipeline-section {
|
.pro-home .pipeline-section {
|
||||||
max-width: 100vw;
|
max-width: 100vw;
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ProfessionalHome - Tablet Optimizations */
|
/* 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 {
|
.pro-home .hero-section {
|
||||||
padding: 3rem 0 2.5rem;
|
padding: 3rem 0 2.5rem;
|
||||||
}
|
}
|
||||||
@@ -949,7 +941,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ProfessionalHome - Small Mobile (< 480px) */
|
/* ProfessionalHome - Small Mobile (< 480px) */
|
||||||
@media (max-width: 480px) {
|
@media (max-width: var(--bp-xs)) {
|
||||||
.pro-home .hero-badge {
|
.pro-home .hero-badge {
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
padding: 0.2rem 0.5rem;
|
padding: 0.2rem 0.5rem;
|
||||||
@@ -973,7 +965,7 @@
|
|||||||
/* ============================================
|
/* ============================================
|
||||||
* Dark Mode Specific
|
* Dark Mode Specific
|
||||||
* ============================================ */
|
* ============================================ */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: var(--bp-sm)) {
|
||||||
.dark {
|
.dark {
|
||||||
--vp-c-bg: #0f172a;
|
--vp-c-bg: #0f172a;
|
||||||
--vp-c-text-1: #f1f5f9;
|
--vp-c-text-1: #f1f5f9;
|
||||||
@@ -983,7 +975,7 @@
|
|||||||
/* ============================================
|
/* ============================================
|
||||||
* Print Styles for Mobile
|
* Print Styles for Mobile
|
||||||
* ============================================ */
|
* ============================================ */
|
||||||
@media print and (max-width: 768px) {
|
@media print and (max-width: var(--bp-sm)) {
|
||||||
.VPContent {
|
.VPContent {
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,9 +143,15 @@
|
|||||||
--vp-z-index-toast: 200;
|
--vp-z-index-toast: 200;
|
||||||
|
|
||||||
/* Responsive Breakpoints (VitePress standard) */
|
/* Responsive Breakpoints (VitePress standard) */
|
||||||
--bp-mobile: 768px; /* Mobile: < 768px */
|
--bp-xs: 480px; /* Extra Small: < 480px */
|
||||||
--bp-tablet: 1024px; /* Tablet: 768px - 1024px */
|
--bp-sm: 768px; /* Small (Mobile): < 768px */
|
||||||
--bp-desktop: 1440px; /* Desktop: > 1024px, large: > 1440px */
|
--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
|
/* Container Query Breakpoints
|
||||||
* Aligned with media query breakpoints for consistency
|
* Aligned with media query breakpoints for consistency
|
||||||
|
|||||||
Reference in New Issue
Block a user