From 6dab38172f79dc76c5a4cada84809bc599b5c7fa Mon Sep 17 00:00:00 2001 From: catlog22 Date: Sun, 21 Dec 2025 09:36:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=BC=BA=20CSS=20=E5=B8=83?= =?UTF-8?q?=E5=B1=80=EF=BC=8C=E4=BC=98=E5=8C=96=E7=BB=84=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=E7=81=B5=E6=B4=BB=E6=80=A7=E5=92=8C=E5=93=8D=E5=BA=94=E5=BC=8F?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=EF=BC=9B=E6=9B=B4=E6=96=B0=E8=B0=83=E8=AF=95?= =?UTF-8?q?=E5=92=8C=E8=BD=BB=E9=87=8F=E7=BA=A7=E8=AE=A1=E5=88=92=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=B5=81=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .codex/prompts/debug.md | 318 ++++++++++++ .codex/prompts/lite-plan.md | 469 ++++++++++++++++++ .../dashboard-css/24-prompt-history.css | 26 +- .../dashboard-js/components/hook-manager.js | 69 ++- 4 files changed, 866 insertions(+), 16 deletions(-) create mode 100644 .codex/prompts/debug.md create mode 100644 .codex/prompts/lite-plan.md diff --git a/.codex/prompts/debug.md b/.codex/prompts/debug.md new file mode 100644 index 00000000..5470cfbc --- /dev/null +++ b/.codex/prompts/debug.md @@ -0,0 +1,318 @@ +--- +description: Interactive hypothesis-driven debugging with NDJSON logging, iterative until resolved +argument-hint: BUG="" +--- + +# Workflow Debug Command + +## Overview + +Evidence-based interactive debugging command. Systematically identifies root causes through hypothesis-driven logging and iterative verification. + +**Core workflow**: Explore → Add Logging → Reproduce → Analyze Log → Fix → Verify + +## Bug Description + +**Target bug**: $BUG + +## Execution Process + +``` +Session Detection: + ├─ Check if debug session exists for this bug + ├─ EXISTS + debug.log has content → Analyze mode + └─ NOT_FOUND or empty log → Explore mode + +Explore Mode: + ├─ Locate error source in codebase + ├─ Generate testable hypotheses (dynamic count) + ├─ Add NDJSON logging instrumentation + └─ Output: Hypothesis list + await user reproduction + +Analyze Mode: + ├─ Parse debug.log, validate each hypothesis + └─ Decision: + ├─ Confirmed → Fix root cause + ├─ Inconclusive → Add more logging, iterate + └─ All rejected → Generate new hypotheses + +Fix & Cleanup: + ├─ Apply fix based on confirmed hypothesis + ├─ User verifies + ├─ Remove debug instrumentation + └─ If not fixed → Return to Analyze mode +``` + +## Implementation + +### Session Setup & Mode Detection + +```javascript +const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString() + +const bugSlug = "$BUG".toLowerCase().replace(/[^a-z0-9]+/g, '-').substring(0, 30) +const dateStr = getUtc8ISOString().substring(0, 10) + +const sessionId = `DBG-${bugSlug}-${dateStr}` +const sessionFolder = `.workflow/.debug/${sessionId}` +const debugLogPath = `${sessionFolder}/debug.log` + +// Auto-detect mode +const sessionExists = fs.existsSync(sessionFolder) +const logHasContent = sessionExists && fs.existsSync(debugLogPath) && fs.statSync(debugLogPath).size > 0 + +const mode = logHasContent ? 'analyze' : 'explore' + +if (!sessionExists) { + bash(`mkdir -p ${sessionFolder}`) +} +``` + +--- + +### Explore Mode + +**Step 1.1: Locate Error Source** + +```javascript +// Extract keywords from bug description +const keywords = extractErrorKeywords("$BUG") +// e.g., ['Stack Length', '未找到', 'registered 0'] + +// Search codebase for error locations +for (const keyword of keywords) { + Grep({ pattern: keyword, path: ".", output_mode: "content", "-C": 3 }) +} + +// Identify affected files and functions +const affectedLocations = [...] // from search results +``` + +**Step 1.2: Generate Hypotheses (Dynamic)** + +```javascript +// Hypothesis categories based on error pattern +const HYPOTHESIS_PATTERNS = { + "not found|missing|undefined|未找到": "data_mismatch", + "0|empty|zero|registered 0": "logic_error", + "timeout|connection|sync": "integration_issue", + "type|format|parse": "type_mismatch" +} + +// Generate hypotheses based on actual issue (NOT fixed count) +function generateHypotheses(bugDescription, affectedLocations) { + const hypotheses = [] + + // Analyze bug and create targeted hypotheses + // Each hypothesis has: + // - id: H1, H2, ... (dynamic count) + // - description: What might be wrong + // - testable_condition: What to log + // - logging_point: Where to add instrumentation + + return hypotheses // Could be 1, 3, 5, or more +} + +const hypotheses = generateHypotheses("$BUG", affectedLocations) +``` + +**Step 1.3: Add NDJSON Instrumentation** + +For each hypothesis, add logging at the relevant location: + +**Python template**: +```python +# region debug [H{n}] +try: + import json, time + _dbg = { + "sid": "{sessionId}", + "hid": "H{n}", + "loc": "{file}:{line}", + "msg": "{testable_condition}", + "data": { + # Capture relevant values here + }, + "ts": int(time.time() * 1000) + } + with open(r"{debugLogPath}", "a", encoding="utf-8") as _f: + _f.write(json.dumps(_dbg, ensure_ascii=False) + "\n") +except: pass +# endregion +``` + +**JavaScript/TypeScript template**: +```javascript +// region debug [H{n}] +try { + require('fs').appendFileSync("{debugLogPath}", JSON.stringify({ + sid: "{sessionId}", + hid: "H{n}", + loc: "{file}:{line}", + msg: "{testable_condition}", + data: { /* Capture relevant values */ }, + ts: Date.now() + }) + "\n"); +} catch(_) {} +// endregion +``` + +**Output to user**: +``` +## Hypotheses Generated + +Based on error "$BUG", generated {n} hypotheses: + +{hypotheses.map(h => ` +### ${h.id}: ${h.description} +- Logging at: ${h.logging_point} +- Testing: ${h.testable_condition} +`).join('')} + +**Debug log**: ${debugLogPath} + +**Next**: Run reproduction steps, then come back for analysis. +``` + +--- + +### Analyze Mode + +```javascript +// Parse NDJSON log +const entries = Read(debugLogPath).split('\n') + .filter(l => l.trim()) + .map(l => JSON.parse(l)) + +// Group by hypothesis +const byHypothesis = groupBy(entries, 'hid') + +// Validate each hypothesis +for (const [hid, logs] of Object.entries(byHypothesis)) { + const hypothesis = hypotheses.find(h => h.id === hid) + const latestLog = logs[logs.length - 1] + + // Check if evidence confirms or rejects hypothesis + const verdict = evaluateEvidence(hypothesis, latestLog.data) + // Returns: 'confirmed' | 'rejected' | 'inconclusive' +} +``` + +**Output**: +``` +## Evidence Analysis + +Analyzed ${entries.length} log entries. + +${results.map(r => ` +### ${r.id}: ${r.description} +- **Status**: ${r.verdict} +- **Evidence**: ${JSON.stringify(r.evidence)} +- **Reason**: ${r.reason} +`).join('')} + +${confirmedHypothesis ? ` +## Root Cause Identified + +**${confirmedHypothesis.id}**: ${confirmedHypothesis.description} + +Ready to fix. +` : ` +## Need More Evidence + +Add more logging or refine hypotheses. +`} +``` + +--- + +### Fix & Cleanup + +```javascript +// Apply fix based on confirmed hypothesis +// ... Edit affected files + +// After user verifies fix works: + +// Remove debug instrumentation (search for region markers) +const instrumentedFiles = Grep({ + pattern: "# region debug|// region debug", + output_mode: "files_with_matches" +}) + +for (const file of instrumentedFiles) { + // Remove content between region markers + removeDebugRegions(file) +} + +console.log(` +## Debug Complete + +- Root cause: ${confirmedHypothesis.description} +- Fix applied to: ${modifiedFiles.join(', ')} +- Debug instrumentation removed +`) +``` + +--- + +## Debug Log Format (NDJSON) + +Each line is a JSON object: + +```json +{"sid":"DBG-xxx-2025-12-18","hid":"H1","loc":"file.py:func:42","msg":"Check dict keys","data":{"keys":["a","b"],"target":"c","found":false},"ts":1734567890123} +``` + +| Field | Description | +|-------|-------------| +| `sid` | Session ID | +| `hid` | Hypothesis ID (H1, H2, ...) | +| `loc` | Code location | +| `msg` | What's being tested | +| `data` | Captured values | +| `ts` | Timestamp (ms) | + +## Session Folder + +``` +.workflow/.debug/DBG-{slug}-{date}/ +├── debug.log # NDJSON log (main artifact) +└── resolution.md # Summary after fix (optional) +``` + +## Iteration Flow + +``` +First Call (/prompts:debug BUG="error"): + ├─ No session exists → Explore mode + ├─ Extract error keywords, search codebase + ├─ Generate hypotheses, add logging + └─ Await user reproduction + +After Reproduction (/prompts:debug BUG="error"): + ├─ Session exists + debug.log has content → Analyze mode + ├─ Parse log, evaluate hypotheses + └─ Decision: + ├─ Confirmed → Fix → User verify + │ ├─ Fixed → Cleanup → Done + │ └─ Not fixed → Add logging → Iterate + ├─ Inconclusive → Add logging → Iterate + └─ All rejected → New hypotheses → Iterate + +Output: + └─ .workflow/.debug/DBG-{slug}-{date}/debug.log +``` + +## Error Handling + +| Situation | Action | +|-----------|--------| +| Empty debug.log | Verify reproduction triggered the code path | +| All hypotheses rejected | Generate new hypotheses with broader scope | +| Fix doesn't work | Iterate with more granular logging | +| >5 iterations | Escalate with collected evidence | + +--- + +**Now execute the debug workflow for bug**: $BUG diff --git a/.codex/prompts/lite-plan.md b/.codex/prompts/lite-plan.md new file mode 100644 index 00000000..c6894a61 --- /dev/null +++ b/.codex/prompts/lite-plan.md @@ -0,0 +1,469 @@ +--- +description: Lightweight interactive planning workflow with direct exploration, outputs plan.json after user confirmation +argument-hint: TASK="" [EXPLORE="true"] +--- + +# Workflow Lite-Plan Command + +## Overview + +Intelligent lightweight planning command with dynamic workflow adaptation based on task complexity. Focuses on planning phases (exploration, clarification, planning, confirmation) and outputs plan.json for subsequent execution. + +**Core capabilities:** +- Intelligent task analysis with automatic exploration detection +- Direct code exploration (grep, find, file reading) when codebase understanding needed +- Interactive clarification after exploration to gather missing information +- Adaptive planning strategy based on complexity +- Two-step confirmation: plan display → user approval +- Outputs plan.json file after user confirmation + +## Task Description + +**Target task**: $TASK +**Force exploration**: $EXPLORE + +## Execution Process + +``` +Phase 1: Task Analysis & Exploration + ├─ Parse input (description or .md file) + ├─ Intelligent complexity assessment (Low/Medium/High) + ├─ Exploration decision (auto-detect or EXPLORE="true") + └─ Decision: + ├─ needsExploration=true → Direct exploration using grep/find/read + └─ needsExploration=false → Skip to Phase 2/3 + +Phase 2: Clarification (optional) + ├─ Aggregate clarification needs from exploration + ├─ Output questions to user + └─ STOP and wait for user reply + +Phase 3: Planning (NO CODE EXECUTION - planning only) + └─ Generate plan.json following schema + └─ MUST proceed to Phase 4 + +Phase 4: Confirmation + ├─ Display plan summary (tasks, complexity, estimated time) + ├─ Output confirmation request + └─ STOP and wait for user approval + +Phase 5: Output + └─ Write plan.json to session folder +``` + +## Implementation + +### Phase 1: Intelligent Direct Exploration + +**Session Setup** (MANDATORY - follow exactly): +```javascript +// Helper: Get UTC+8 (China Standard Time) ISO string +const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString() + +const taskSlug = "$TASK".toLowerCase().replace(/[^a-z0-9]+/g, '-').substring(0, 40) +const dateStr = getUtc8ISOString().substring(0, 10) // Format: 2025-11-29 + +const sessionId = `${taskSlug}-${dateStr}` // e.g., "implement-jwt-refresh-2025-11-29" +const sessionFolder = `.workflow/.lite-plan/${sessionId}` + +// Create session folder +mkdir -p ${sessionFolder} +``` + +**Exploration Decision Logic**: +```javascript +needsExploration = ( + "$EXPLORE" === "true" || + task.mentions_specific_files || + task.requires_codebase_context || + task.needs_architecture_understanding || + task.modifies_existing_code +) + +if (!needsExploration) { + // Skip to Phase 2 (Clarification) or Phase 3 (Planning) + proceed_to_next_phase() +} +``` + +**Complexity Assessment** (Intelligent Analysis): +```javascript +// Analyzes task complexity based on: +// - Scope: How many systems/modules are affected? +// - Depth: Surface change vs architectural impact? +// - Risk: Potential for breaking existing functionality? +// - Dependencies: How interconnected is the change? + +const complexity = analyzeTaskComplexity("$TASK") +// Returns: 'Low' | 'Medium' | 'High' +// Low: Single file, isolated change, minimal risk +// Medium: Multiple files, some dependencies, moderate risk +// High: Cross-module, architectural, high risk + +// Angle assignment based on task type +const ANGLE_PRESETS = { + architecture: ['architecture', 'dependencies', 'modularity', 'integration-points'], + security: ['security', 'auth-patterns', 'dataflow', 'validation'], + performance: ['performance', 'bottlenecks', 'caching', 'data-access'], + bugfix: ['error-handling', 'dataflow', 'state-management', 'edge-cases'], + feature: ['patterns', 'integration-points', 'testing', 'dependencies'] +} + +function selectAngles(taskDescription, count) { + const text = taskDescription.toLowerCase() + let preset = 'feature' // default + + if (/refactor|architect|restructure|modular/.test(text)) preset = 'architecture' + else if (/security|auth|permission|access/.test(text)) preset = 'security' + else if (/performance|slow|optimi|cache/.test(text)) preset = 'performance' + else if (/fix|bug|error|issue|broken/.test(text)) preset = 'bugfix' + + return ANGLE_PRESETS[preset].slice(0, count) +} + +const selectedAngles = selectAngles("$TASK", complexity === 'High' ? 4 : (complexity === 'Medium' ? 3 : 1)) + +console.log(` +## Exploration Plan + +Task Complexity: ${complexity} +Selected Angles: ${selectedAngles.join(', ')} + +Starting direct exploration... +`) +``` + +**Direct Exploration** (No Agent - Use grep/find/read directly): + +```javascript +// For each selected angle, perform direct exploration + +selectedAngles.forEach((angle, index) => { + console.log(`\n### Exploring: ${angle} (${index + 1}/${selectedAngles.length})`) + + // Step 1: Structural Scan + // - Find relevant files using grep/rg + // - Analyze directory structure + // - Identify modules related to the angle + + // Example commands: + // rg -l "keyword_from_task" --type ts + // find . -name "*.ts" -path "*auth*" + // tree -L 3 src/ + + // Step 2: Content Analysis + // - Read key files identified + // - Analyze patterns and conventions + // - Identify integration points + + // Step 3: Document Findings + const explorationResult = { + angle: angle, + project_structure: [], // Modules/architecture relevant to angle + relevant_files: [], // Files affected from angle perspective + patterns: [], // Angle-related patterns to follow + dependencies: [], // Dependencies relevant to angle + integration_points: [], // Where to integrate from angle viewpoint + constraints: [], // Angle-specific limitations/conventions + clarification_needs: [], // Angle-related ambiguities + _metadata: { + exploration_angle: angle, + exploration_index: index + 1, + timestamp: getUtc8ISOString() + } + } + + // Write exploration result + Write(`${sessionFolder}/exploration-${angle}.json`, JSON.stringify(explorationResult, null, 2)) +}) +``` + +**Build Exploration Manifest**: +```javascript +// After all explorations complete, build manifest +const explorationFiles = find(`${sessionFolder}`, "-name", "exploration-*.json") + +const explorationManifest = { + session_id: sessionId, + task_description: "$TASK", + timestamp: getUtc8ISOString(), + complexity: complexity, + exploration_count: selectedAngles.length, + explorations: explorationFiles.map(file => { + const data = JSON.parse(Read(file)) + return { + angle: data._metadata.exploration_angle, + file: path.basename(file), + path: file, + index: data._metadata.exploration_index + } + }) +} + +Write(`${sessionFolder}/explorations-manifest.json`, JSON.stringify(explorationManifest, null, 2)) + +console.log(` +## Exploration Complete + +Generated exploration files in ${sessionFolder}: +${explorationManifest.explorations.map(e => `- exploration-${e.angle}.json (angle: ${e.angle})`).join('\n')} + +Manifest: explorations-manifest.json +Angles explored: ${explorationManifest.explorations.map(e => e.angle).join(', ')} +`) +``` + +**Output**: +- `${sessionFolder}/exploration-{angle1}.json` +- `${sessionFolder}/exploration-{angle2}.json` +- ... (1-4 files based on complexity) +- `${sessionFolder}/explorations-manifest.json` + +--- + +### Phase 2: Clarification (Optional) + +**Skip if**: No exploration or `clarification_needs` is empty across all explorations + +**Aggregate clarification needs from all exploration angles**: +```javascript +// Load manifest and all exploration files +const manifest = JSON.parse(Read(`${sessionFolder}/explorations-manifest.json`)) +const explorations = manifest.explorations.map(exp => ({ + angle: exp.angle, + data: JSON.parse(Read(exp.path)) +})) + +// Aggregate clarification needs from all explorations +const allClarifications = [] +explorations.forEach(exp => { + if (exp.data.clarification_needs?.length > 0) { + exp.data.clarification_needs.forEach(need => { + allClarifications.push({ + ...need, + source_angle: exp.angle + }) + }) + } +}) + +// Intelligent deduplication: analyze allClarifications by intent +// - Identify questions with similar intent across different angles +// - Merge similar questions: combine options, consolidate context +// - Produce dedupedClarifications with unique intents only +const dedupedClarifications = intelligentMerge(allClarifications) +``` + +**Output Questions and Wait for User Reply**: +```javascript +if (dedupedClarifications.length > 0) { + console.log(` +## Clarification Needed + +Based on exploration, the following questions need your input: + +${dedupedClarifications.map((need, index) => ` +### Question ${index + 1}: [${need.source_angle}] + +**${need.question}** + +Context: ${need.context} + +Options: +${need.options.map((opt, i) => ` ${i + 1}. ${opt}${need.recommended === i ? ' ★ (Recommended)' : ''}`).join('\n')} +`).join('\n')} + +--- + +**Please reply with your choices** (e.g., "Q1: 2, Q2: 1, Q3: 3") to continue planning. + +**WAITING FOR USER INPUT...** +`) + + // STOP HERE - Wait for user reply before continuing to Phase 3 + return +} +``` + +**After User Reply**: Store responses in `clarificationContext` and proceed to Phase 3. + +--- + +### Phase 3: Planning + +**IMPORTANT**: Phase 3 is **planning only** - NO code execution. + +**Read Schema**: +```javascript +// Read plan schema for reference +const schema = Read("~/.claude/workflows/cli-templates/schemas/plan-json-schema.json") +``` + +**Read All Exploration Files**: +```javascript +// MANDATORY - Read and review ALL exploration files +const manifest = JSON.parse(Read(`${sessionFolder}/explorations-manifest.json`)) +manifest.explorations.forEach(exp => { + const explorationData = Read(exp.path) + console.log(`\n### Exploration: ${exp.angle}\n${explorationData}`) +}) +``` + +**Generate Plan**: +```javascript +// Generate plan following schema +// Plan MUST incorporate insights from exploration files +const plan = { + summary: "Brief description of what will be implemented", + approach: "High-level approach and strategy", + tasks: [ + // Each task: { id, title, description, scope, files, depends_on, execution_group, complexity } + // Group by feature/module, NOT by file + // 2-7 tasks recommended + ], + estimated_time: "Total estimated time", + complexity: complexity, // Low | Medium | High + _metadata: { + timestamp: getUtc8ISOString(), + source: "lite-plan", + planning_mode: "direct", + exploration_angles: manifest.explorations.map(e => e.angle) + } +} +``` + +**Task Grouping Rules**: +1. **Group by feature**: All changes for one feature = one task (even if 3-5 files) +2. **Group by context**: Tasks with similar context or related functional changes can be grouped together +3. **Minimize task count**: Simple, unrelated tasks can also be grouped to reduce overhead +4. **Avoid file-per-task**: Do NOT create separate tasks for each file +5. **Substantial tasks**: Each task should represent 15-60 minutes of work +6. **True dependencies only**: Only use depends_on when Task B cannot start without Task A's output +7. **Prefer parallel**: Most tasks should be independent (no depends_on) + +**Proceed to Phase 4** - DO NOT execute code here. + +--- + +### Phase 4: Task Confirmation + +**Display Plan Summary**: +```javascript +const plan = JSON.parse(Read(`${sessionFolder}/plan.json`)) + +console.log(` +## Implementation Plan + +**Summary**: ${plan.summary} +**Approach**: ${plan.approach} + +**Tasks** (${plan.tasks.length}): +${plan.tasks.map((t, i) => ` +### Task ${i+1}: ${t.title} +- **Description**: ${t.description} +- **Scope**: ${t.scope} +- **Files**: ${t.files.join(', ')} +- **Complexity**: ${t.complexity} +- **Dependencies**: ${t.depends_on?.join(', ') || 'None'} +`).join('\n')} + +**Overall Complexity**: ${plan.complexity} +**Estimated Time**: ${plan.estimated_time} + +--- + +## Confirmation Required + +Please review the plan above and reply with one of the following: + +- **"Allow"** - Proceed with this plan, output plan.json +- **"Modify"** - Describe what changes you want to make +- **"Cancel"** - Abort the planning workflow + +**WAITING FOR USER CONFIRMATION...** +`) + +// STOP HERE - Wait for user confirmation before writing plan.json +return +``` + +--- + +### Phase 5: Output Plan File + +**After User Confirms "Allow"**: +```javascript +// Write final plan.json to session folder +Write(`${sessionFolder}/plan.json`, JSON.stringify(plan, null, 2)) + +console.log(` +## Plan Output Complete + +**Plan file written**: ${sessionFolder}/plan.json + +**Session folder**: ${sessionFolder} + +**Contents**: +- explorations-manifest.json +${manifest.explorations.map(e => `- exploration-${e.angle}.json`).join('\n')} +- plan.json + +--- + +You can now use this plan with your preferred execution method: +- Manual implementation following the tasks +- Pass to another tool/agent for execution +- Import into project management system +`) +``` + +--- + +## Session Folder Structure + +``` +.workflow/.lite-plan/{task-slug}-{YYYY-MM-DD}/ +├── exploration-{angle1}.json # Exploration angle 1 +├── exploration-{angle2}.json # Exploration angle 2 +├── exploration-{angle3}.json # Exploration angle 3 (if applicable) +├── exploration-{angle4}.json # Exploration angle 4 (if applicable) +├── explorations-manifest.json # Exploration index +└── plan.json # Implementation plan (after confirmation) +``` + +**Example**: +``` +.workflow/.lite-plan/implement-jwt-refresh-2025-11-25/ +├── exploration-architecture.json +├── exploration-auth-patterns.json +├── exploration-security.json +├── explorations-manifest.json +└── plan.json +``` + +## Workflow States + +| State | Action | Next | +|-------|--------|------| +| Phase 1 Complete | Exploration done | → Phase 2 or 3 | +| Phase 2 Output | Questions displayed | → Wait for user reply | +| User Replied | Clarifications received | → Phase 3 | +| Phase 3 Complete | Plan generated | → Phase 4 | +| Phase 4 Output | Plan displayed | → Wait for user confirmation | +| User: "Allow" | Confirmed | → Phase 5 (Write plan.json) | +| User: "Modify" | Changes requested | → Revise plan, back to Phase 4 | +| User: "Cancel" | Aborted | → End workflow | + +## Error Handling + +| Error | Resolution | +|-------|------------| +| Exploration failure | Skip exploration, continue with task description only | +| No relevant files found | Broaden search scope or proceed with minimal context | +| Clarification timeout | Use exploration findings as-is | +| Confirmation timeout | Save context, display resume instructions | +| Modify loop > 3 times | Suggest breaking task into smaller pieces | + +--- + +**Now execute the lite-plan workflow for task**: $TASK diff --git a/ccw/src/templates/dashboard-css/24-prompt-history.css b/ccw/src/templates/dashboard-css/24-prompt-history.css index 7bd178cd..13fe21ab 100644 --- a/ccw/src/templates/dashboard-css/24-prompt-history.css +++ b/ccw/src/templates/dashboard-css/24-prompt-history.css @@ -4,10 +4,15 @@ .prompt-history-view { font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; padding: 1.5rem; + display: flex; + flex-direction: column; + height: calc(100vh - 120px); + min-height: 0; } .prompt-history-header { margin-bottom: 1.5rem; + flex-shrink: 0; } /* Stats Grid */ @@ -107,6 +112,9 @@ border: 1px solid hsl(var(--border)); border-radius: 0.75rem; overflow: hidden; + display: flex; + flex-direction: column; + min-height: 0; } .prompt-timeline-header { @@ -118,6 +126,7 @@ background: hsl(var(--muted) / 0.3); gap: 1rem; flex-wrap: nowrap; + flex-shrink: 0; } .prompt-timeline-header h3 { @@ -190,9 +199,10 @@ /* Timeline List */ .prompt-timeline-list { - max-height: 600px; + flex: 1; overflow-y: auto; padding: 0.5rem; + min-height: 0; } /* Session Groups */ @@ -428,6 +438,9 @@ border: 1px solid hsl(var(--border)); border-radius: 0.75rem; overflow: hidden; + display: flex; + flex-direction: column; + min-height: 0; } .insights-panel-header { @@ -437,6 +450,7 @@ padding: 1rem; border-bottom: 1px solid hsl(var(--border)); background: hsl(var(--muted) / 0.3); + flex-shrink: 0; } .insights-panel-header h3 { @@ -496,6 +510,8 @@ justify-content: center; padding: 3rem 1.5rem; text-align: center; + flex: 1; + min-height: 200px; } .insights-empty-state i { @@ -514,9 +530,10 @@ } .insights-list { - max-height: 600px; + flex: 1; overflow-y: auto; padding: 0.5rem; + min-height: 0; } .insights-section { @@ -729,6 +746,8 @@ justify-content: center; padding: 3rem 1.5rem; text-align: center; + flex: 1; + min-height: 200px; } .prompt-empty-state i { @@ -752,8 +771,9 @@ /* ========== Insights History Cards ========== */ .insights-history-container { padding: 0.75rem; - max-height: calc(100vh - 300px); + flex: 1; overflow-y: auto; + min-height: 0; } .insights-history-cards { diff --git a/ccw/src/templates/dashboard-js/components/hook-manager.js b/ccw/src/templates/dashboard-js/components/hook-manager.js index 3df8a412..8c2b32b9 100644 --- a/ccw/src/templates/dashboard-js/components/hook-manager.js +++ b/ccw/src/templates/dashboard-js/components/hook-manager.js @@ -590,8 +590,8 @@ async function openHookWizardModal(wizardId) { wizardConfig.selectedOptions = []; } - // Ensure available skills are loaded for SKILL context wizard - if (wizardId === 'skill-context' && typeof window.availableSkills === 'undefined') { + // Always refresh available skills when opening SKILL context wizard + if (wizardId === 'skill-context') { await loadAvailableSkills(); } @@ -862,7 +862,8 @@ function renderSkillContextConfig() { if (selectedOption === 'auto') { let skillBadges = ''; - if (typeof window.availableSkills === 'undefined') { + let isLoading = typeof window.availableSkills === 'undefined' || window.skillsLoading; + if (isLoading) { // Still loading skillBadges = '' + t('common.loading') + '...'; } else if (availableSkills.length === 0) { @@ -875,12 +876,22 @@ function renderSkillContextConfig() { }).join(' '); } return '
' + - '
' + - '' + - '' + t('hook.wizard.autoDetectionMode') + '' + + '
' + + '
' + + '' + + '' + t('hook.wizard.autoDetectionMode') + '' + + '
' + + '' + '
' + '

' + t('hook.wizard.autoDetectionInfo') + '

' + - '

' + t('hook.wizard.availableSkills') + ' ' + skillBadges + '

' + + '
' + + '' + t('hook.wizard.availableSkills') + '' + + skillBadges + + '
' + '
'; } @@ -926,27 +937,59 @@ function renderSkillContextConfig() { }).join(''); } - var noSkillsWarning = ''; - if (availableSkills.length === 0) { - noSkillsWarning = '
' + + var isLoading = typeof window.availableSkills === 'undefined' || window.skillsLoading; + var skillsStatusHtml = ''; + if (isLoading) { + skillsStatusHtml = '' + + '' + + t('common.loading') + + ''; + } else if (availableSkills.length === 0) { + skillsStatusHtml = '' + '' + t('hook.wizard.noSkillsFound') + - '
'; + ''; + } else { + skillsStatusHtml = '' + + availableSkills.length + ' ' + t('skills.skillsCount') + + ''; } return '
' + '
' + - '' + t('hook.wizard.configureSkills') + '' + + '
' + + '' + t('hook.wizard.configureSkills') + '' + + skillsStatusHtml + + '' + + '
' + '' + '
' + '
' + configListHtml + '
' + - noSkillsWarning + '
'; } +async function refreshAvailableSkills() { + // Set loading state + window.skillsLoading = true; + renderWizardModalContent(); + + try { + await loadAvailableSkills(); + } finally { + window.skillsLoading = false; + renderWizardModalContent(); + // Refresh Lucide icons + if (typeof lucide !== 'undefined') lucide.createIcons(); + } +} + function addSkillConfig() { if (!wizardConfig.skillConfigs) { wizardConfig.skillConfigs = [];