fix(cli-history): 转义 sourceDir 以支持 onclick 处理程序

This commit is contained in:
catlog22
2026-01-19 12:22:33 +08:00
parent 6716772e0a
commit e58c33fb6e
2 changed files with 29 additions and 33 deletions

View File

@@ -16,7 +16,7 @@ color: green
- 5-phase task lifecycle (analyze → implement → test → optimize → commit) - 5-phase task lifecycle (analyze → implement → test → optimize → commit)
- Conflict-aware planning (isolate file modifications across issues) - Conflict-aware planning (isolate file modifications across issues)
- Dependency DAG validation - Dependency DAG validation
- Auto-bind for single solution, return for selection on multiple - Execute bind command for single solution, return for selection on multiple
**Key Principle**: Generate tasks conforming to schema with quantified acceptance criteria. **Key Principle**: Generate tasks conforming to schema with quantified acceptance criteria.
@@ -111,30 +111,30 @@ Generate multiple candidate solutions when:
- Multiple valid implementation approaches exist - Multiple valid implementation approaches exist
- Trade-offs between approaches (performance vs simplicity, etc.) - Trade-offs between approaches (performance vs simplicity, etc.)
| Condition | Solutions | | Condition | Solutions | Binding Action |
|-----------|-----------| |-----------|-----------|----------------|
| Low complexity, single approach | 1 solution, auto-bind | | Low complexity, single approach | 1 solution | Execute bind |
| Medium complexity, clear path | 1-2 solutions | | Medium complexity, clear path | 1-2 solutions | Execute bind if 1, return if 2+ |
| High complexity, multiple approaches | 2-3 solutions, user selection | | High complexity, multiple approaches | 2-3 solutions | Return for selection |
**Binding Decision** (based SOLELY on final `solutions.length`):
```javascript
// After generating all solutions
if (solutions.length === 1) {
exec(`ccw issue bind ${issueId} ${solutions[0].id}`); // MUST execute
} else {
return { pending_selection: solutions }; // Return for user choice
}
```
**Solution Evaluation** (for each candidate): **Solution Evaluation** (for each candidate):
```javascript ```javascript
{ {
analysis: { analysis: { risk: "low|medium|high", impact: "low|medium|high", complexity: "low|medium|high" },
risk: "low|medium|high", // Implementation risk score: 0.0-1.0 // Higher = recommended
impact: "low|medium|high", // Scope of changes
complexity: "low|medium|high" // Technical complexity
},
score: 0.0-1.0 // Overall quality score (higher = recommended)
} }
``` ```
**Selection Flow**:
1. Generate all candidate solutions
2. Evaluate and score each
3. Single solution → auto-bind
4. Multiple solutions → return `pending_selection` for user choice
**Task Decomposition** following schema: **Task Decomposition** following schema:
```javascript ```javascript
function decomposeTasks(issue, exploration) { function decomposeTasks(issue, exploration) {
@@ -248,8 +248,8 @@ Write({ file_path: filePath, content: newContent })
``` ```
**Step 2: Bind decision** **Step 2: Bind decision**
- **Single solution**Auto-bind: `ccw issue bind <issue-id> <solution-id>` - 1 solution → Execute `ccw issue bind <issue-id> <solution-id>`
- **Multiple solutions** → Return for user selection (no bind) - 2+ solutions → Return `pending_selection` (no bind)
--- ---
@@ -264,14 +264,7 @@ Write({ file_path: filePath, content: newContent })
Each line is a solution JSON containing tasks. Schema: `cat .claude/workflows/cli-templates/schemas/solution-schema.json` Each line is a solution JSON containing tasks. Schema: `cat .claude/workflows/cli-templates/schemas/solution-schema.json`
### 2.2 Binding ### 2.2 Return Summary
| Scenario | Action |
|----------|--------|
| Single solution | `ccw issue bind <issue-id> <solution-id>` (auto) |
| Multiple solutions | Register only, return for selection |
### 2.3 Return Summary
```json ```json
{ {
@@ -332,9 +325,9 @@ Each line is a solution JSON containing tasks. Schema: `cat .claude/workflows/cl
2. Use vague criteria ("works correctly", "good performance") 2. Use vague criteria ("works correctly", "good performance")
3. Create circular dependencies 3. Create circular dependencies
4. Generate more than 10 tasks per issue 4. Generate more than 10 tasks per issue
5. **Bind when multiple solutions exist** - MUST check `solutions.length === 1` before calling `ccw issue bind` 5. Skip bind when `solutions.length === 1` (MUST execute bind command)
**OUTPUT**: **OUTPUT**:
1. Write solutions to `.workflow/issues/solutions/{issue-id}.jsonl` (JSONL format) 1. Write solutions to `.workflow/issues/solutions/{issue-id}.jsonl`
2. Single solution → `ccw issue bind <issue-id> <solution-id>`; Multiple → return only 2. Execute bind or return `pending_selection` based on solution count
3. Return JSON with `bound`, `pending_selection` 3. Return JSON: `{ bound: [...], pending_selection: [...] }`

View File

@@ -239,6 +239,9 @@ async function showExecutionDetail(executionId, sourceDir) {
return; return;
} }
// Escape sourceDir for use in onclick handlers
const sourceDirEscaped = sourceDir ? sourceDir.replace(/\\/g, '/').replace(/'/g, "\\'") : '';
// Handle both old (single execution) and new (conversation) formats // Handle both old (single execution) and new (conversation) formats
const isConversation = conversation.turns && Array.isArray(conversation.turns); const isConversation = conversation.turns && Array.isArray(conversation.turns);
const turnCount = isConversation ? conversation.turn_count : 1; const turnCount = isConversation ? conversation.turn_count : 1;
@@ -368,7 +371,7 @@ async function showExecutionDetail(executionId, sourceDir) {
</div> </div>
${hasNativeSession ? ` ${hasNativeSession ? `
<div class="cli-detail-native-action"> <div class="cli-detail-native-action">
<button class="btn btn-sm btn-primary" onclick="showNativeSessionDetail('${executionId}')"> <button class="btn btn-sm btn-primary" onclick="showNativeSessionDetail('${executionId}', '${sourceDirEscaped}')">
<i data-lucide="eye" class="w-3.5 h-3.5"></i> View Full Process Conversation <i data-lucide="eye" class="w-3.5 h-3.5"></i> View Full Process Conversation
</button> </button>
</div> </div>