mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-04 01:40:45 +08:00
Refactor execution modes and CLI integration across agents
- Updated code-developer, tdd-developer, and test-fix-agent to streamline execution modes based on task.meta.execution_config.method. - Removed legacy command handling and introduced CLI handoff for 'cli' execution method. - Enhanced buildCliHandoffPrompt to include task JSON path and improved context handling. - Updated task-generate-agent and task-generate-tdd to reflect new execution method mappings and removed command field from implementation_approach. - Improved CLI settings validation in CliSettingsModal with format and length checks. - Added localization for new CLI settings messages in English and Chinese. - Enhanced GPU selector to use localized strings for GPU types. - Introduced TypeScript LSP setup documentation for better user guidance.
This commit is contained in:
@@ -1,216 +0,0 @@
|
||||
# Test Generation Enhancement - Implementation Summary
|
||||
|
||||
## Overview
|
||||
|
||||
Enhanced test-task-generate workflow with two major improvements:
|
||||
1. **Gemini Test Enhancement** (Phase 1.5): Comprehensive test suggestions for API, integration, and error scenarios
|
||||
2. **Planning Notes Mechanism** (test-planning-notes.md): Record Gemini enhancement, context, and plan process for full transparency
|
||||
|
||||
---
|
||||
|
||||
## Changes Made
|
||||
|
||||
### 1. Created Gemini Prompt Template
|
||||
**File**: `~/.claude/workflows/cli-templates/prompts/test/test-suggestions-enhancement.txt`
|
||||
- Structured prompt for Gemini CLI to generate comprehensive test suggestions
|
||||
- Covers L1-L3 test layers with focus on API, integration, and error scenarios
|
||||
- Produces actionable test specifications with expected behavior and success criteria
|
||||
|
||||
### 2. Enhanced test-task-generate.md with Two Major Features
|
||||
|
||||
**Location**: `.claude/commands/workflow/tools/test-task-generate.md`
|
||||
|
||||
#### A. Phase 1.5: Gemini Test Enhancement
|
||||
- **Invocation of cli-execution-agent** for Gemini analysis
|
||||
- **Template**: test-suggestions-enhancement.txt
|
||||
- **Output**: gemini-enriched-suggestions.md
|
||||
- **Merge**: Appends enriched suggestions to TEST_ANALYSIS_RESULTS.md
|
||||
|
||||
#### B. test-planning-notes.md Mechanism (NEW - References plan.md pattern)
|
||||
Similar to plan.md's planning-notes.md, this records the entire planning journey.
|
||||
|
||||
**Lifecycle**:
|
||||
1. **Phase 1 Creation**: Initialize test-planning-notes.md with Test Intent
|
||||
2. **Phase 1.5 Update**: Record Gemini Enhancement findings
|
||||
3. **Phase 2 Update**: Final Task Generation findings (agent-executed)
|
||||
|
||||
---
|
||||
|
||||
## Planning Notes Architecture (Similar to plan.md)
|
||||
|
||||
### test-planning-notes.md Structure
|
||||
|
||||
```markdown
|
||||
# Test Planning Notes
|
||||
|
||||
**Session**: WFS-test-xxx
|
||||
**Source Session**: WFS-xxx
|
||||
**Created**: [timestamp]
|
||||
|
||||
## Test Intent (Phase 1)
|
||||
- **PROJECT_TYPE**: [Detected project type]
|
||||
- **TEST_FRAMEWORK**: [Detected framework]
|
||||
- **COVERAGE_TARGET**: [Coverage goal]
|
||||
- **SOURCE_SESSION**: [Source session ID]
|
||||
|
||||
---
|
||||
|
||||
## Context Findings (Phase 1)
|
||||
### Files with Coverage Gaps
|
||||
[Extracted from TEST_ANALYSIS_RESULTS.md]
|
||||
|
||||
### Test Framework & Conventions
|
||||
- Framework: [Framework]
|
||||
- Coverage Target: [Target]
|
||||
|
||||
---
|
||||
|
||||
## Gemini Enhancement (Phase 1.5)
|
||||
|
||||
**Analysis Timestamp**: [timestamp]
|
||||
**Template**: test-suggestions-enhancement.txt
|
||||
**Output File**: .process/gemini-enriched-suggestions.md
|
||||
|
||||
### Enriched Test Suggestions (Complete Gemini Analysis)
|
||||
|
||||
[COMPLETE CONTENT FROM gemini-enriched-suggestions.md EMBEDDED HERE]
|
||||
[All L1-L3 test suggestions, API contracts, integration patterns, error scenarios]
|
||||
|
||||
### Gemini Analysis Summary
|
||||
- **Status**: Enrichment complete
|
||||
- **Layers Covered**: L1, L2.1, L2.2, L2.4, L2.5
|
||||
- **Focus Areas**: API contracts, integration patterns, error scenarios, edge cases
|
||||
- **Output Stored**: Full analysis in gemini-enriched-suggestions.md
|
||||
|
||||
### Key Features
|
||||
|
||||
1. **Complete Gemini Analysis Embedded**: Full enriched suggestions content is directly embedded into test-planning-notes.md
|
||||
2. **Preserved Output File**: gemini-enriched-suggestions.md still generated as artifact for reference
|
||||
3. **Consolidated Context**: test-planning-notes.md becomes single source of truth for all planning context
|
||||
4. **Agent Friendly**: test-action-planning-agent can read complete planning context from one file
|
||||
|
||||
### Use Cases for Gemini Content in planning-notes.md
|
||||
|
||||
| Use Case | Benefit |
|
||||
|----------|---------|
|
||||
| Reviewer reads planning-notes | See full Gemini suggestions without opening separate file |
|
||||
| Agent reads planning-notes | Get enriched context alongside other planning metadata |
|
||||
| Archive session | Complete record of analysis in one file |
|
||||
| N+1 phase reference | Full history of suggestions for iterative refinement |
|
||||
|
||||
---
|
||||
|
||||
## Consolidated Test Requirements (Phase 2 Input)
|
||||
1. [Context] Test framework conventions
|
||||
2. [Context] Coverage target
|
||||
3. [Gemini] API contract test strategies
|
||||
4. [Gemini] Error scenario coverage
|
||||
[... more consolidated requirements]
|
||||
|
||||
---
|
||||
|
||||
## Task Generation (Phase 2)
|
||||
[Updated by test-action-planning-agent]
|
||||
|
||||
## N+1 Context
|
||||
### Decisions
|
||||
| Decision | Rationale | Revisit? |
|
||||
|----------|-----------|----------|
|
||||
[Decisions made during planning]
|
||||
|
||||
### Deferred
|
||||
- [ ] Items for N+1 phase
|
||||
```
|
||||
|
||||
### Key Benefits of Planning Notes
|
||||
|
||||
1. **Full Transparency**: Record Gemini enhancement findings and context
|
||||
2. **Consolidated Context**: All phase inputs/outputs in one place
|
||||
3. **N+1 Support**: Track decisions and deferred items for future iterations
|
||||
4. **Agent Context**: test-action-planning-agent reads consolidated requirements
|
||||
5. **Traceability**: How each test requirement came from which phase/source
|
||||
6. **Integration Consistency**: Follows same pattern as plan.md for familiarity
|
||||
|
||||
---
|
||||
|
||||
## Complete Integration Flow
|
||||
|
||||
```
|
||||
test-task-generate execution:
|
||||
├─ Phase 1: Context Preparation
|
||||
│ ├─ Load session metadata
|
||||
│ ├─ Load TEST_ANALYSIS_RESULTS.md (original)
|
||||
│ └─ CREATE test-planning-notes.md (Test Intent section)
|
||||
│
|
||||
├─ Phase 1.5: Gemini Test Enhancement
|
||||
│ ├─ Invoke cli-execution-agent for Gemini analysis
|
||||
│ ├─ Generate gemini-enriched-suggestions.md (full analysis output)
|
||||
│ └─ RECORD complete enrichment to test-planning-notes.md (embed full Gemini analysis)
|
||||
│
|
||||
└─ Phase 2: Test Document Generation (Agent)
|
||||
├─ Load TEST_ANALYSIS_RESULTS.md (original, unchanged)
|
||||
├─ Load test-planning-notes.md (includes full Gemini enrichment)
|
||||
├─ Generate task JSONs (IMPL-*.json)
|
||||
└─ Create IMPL_PLAN.md + TODO_LIST.md
|
||||
```
|
||||
|
||||
## Key Design Decisions
|
||||
|
||||
### Gemini Enhancement Recording Strategy
|
||||
|
||||
**Decision**: Record Gemini enhancement to test-planning-notes.md instead of appending to TEST_ANALYSIS_RESULTS.md
|
||||
|
||||
**Rationale**:
|
||||
1. **Separation of Concerns**: TEST_ANALYSIS_RESULTS.md remains as original analysis output
|
||||
2. **Single Source of Truth**: test-planning-notes.md consolidates ALL planning context
|
||||
3. **Better Traceability**: Clear separation between base analysis and AI enrichment
|
||||
4. **Follows plan.md Pattern**: Consistent with planning-notes.md mechanism
|
||||
|
||||
**Implementation**:
|
||||
- Phase 1.5 generates gemini-enriched-suggestions.md (preserved as output file)
|
||||
- Complete Gemini analysis content is embedded into test-planning-notes.md
|
||||
- test-action-planning-agent reads both TEST_ANALYSIS_RESULTS.md and test-planning-notes.md
|
||||
|
||||
## No Breaking Changes
|
||||
|
||||
**Backward Compatible**:
|
||||
- Phase 1.5 is optional enhancement - if Gemini analysis fails, workflow continues with original TEST_ANALYSIS_RESULTS.md
|
||||
- test-action-planning-agent requires NO modifications to source code
|
||||
- test-planning-notes.md consolidates context but doesn't replace existing inputs
|
||||
- Existing workflows unaffected; only adds richer suggestions and traceability
|
||||
|
||||
**Enriched Layers**:
|
||||
- **L1 (Unit)**: Edge cases, boundary conditions, error path validation
|
||||
- **L2.1 (Integration)**: Module interactions, dependency injection patterns
|
||||
- **L2.2 (API Contracts)**: Request/response, validation, status codes, error responses
|
||||
- **L2.4 (External APIs)**: Mock strategies, failure scenarios, timeout handling
|
||||
- **L2.5 (Failure Modes)**: Exception hierarchies, error propagation, recovery strategies
|
||||
|
||||
**Benefits**:
|
||||
- ✅ Comprehensive API test specifications
|
||||
- ✅ Detailed integration test strategies
|
||||
- ✅ Systematic error scenario coverage
|
||||
- ✅ More actionable task generation
|
||||
- ✅ Reduced manual test planning effort
|
||||
|
||||
## How Test-Action-Planning-Agent Uses Enrichment
|
||||
|
||||
**Phase 1 (Context Loading)**:
|
||||
- test-action-planning-agent reads complete TEST_ANALYSIS_RESULTS.md
|
||||
- Includes both original analysis AND Gemini-enhanced suggestions
|
||||
- Automatically leverages enriched content for task generation
|
||||
|
||||
**IMPL-001.json (Test Generation)**:
|
||||
- Generated with reference to enriched test specifications
|
||||
- Enhanced L1-L3 layer requirements from Gemini analysis
|
||||
- More detailed test case descriptions
|
||||
- Better integration and error scenario coverage
|
||||
|
||||
## Verification
|
||||
|
||||
To verify the enhancement is working:
|
||||
1. Run `/workflow:test-fix-gen` to trigger test workflow
|
||||
2. Check `.workflow/active/[session]/.process/gemini-enriched-suggestions.md` exists
|
||||
3. Check TEST_ANALYSIS_RESULTS.md contains "## Gemini-Enhanced Test Suggestions" section
|
||||
4. Review IMPL-001.json - should reference enriched test specifications
|
||||
5. Execute `/workflow:test-cycle-execute` - generated tests should cover API, integration, and error scenarios comprehensively
|
||||
@@ -288,8 +288,8 @@ function computeCliStrategy(task, allTasks) {
|
||||
"execution_group": "parallel-abc123|null",
|
||||
"module": "frontend|backend|shared|null",
|
||||
"execution_config": {
|
||||
"method": "agent|hybrid|cli",
|
||||
"cli_tool": "codex|gemini|qwen|auto",
|
||||
"method": "agent|cli",
|
||||
"cli_tool": "codex|gemini|qwen|auto|null",
|
||||
"enable_resume": true,
|
||||
"previous_cli_id": "string|null"
|
||||
}
|
||||
@@ -303,7 +303,7 @@ function computeCliStrategy(task, allTasks) {
|
||||
- `execution_group`: Parallelization group ID (tasks with same ID can run concurrently) or `null` for sequential tasks
|
||||
- `module`: Module identifier for multi-module projects (e.g., `frontend`, `backend`, `shared`) or `null` for single-module
|
||||
- `execution_config`: CLI execution settings (MUST align with userConfig from task-generate-agent)
|
||||
- `method`: Execution method - `agent` (direct), `hybrid` (agent + CLI), `cli` (CLI only)
|
||||
- `method`: Execution method - `agent` (direct) or `cli` (CLI only). Only two values in final task JSON.
|
||||
- `cli_tool`: Preferred CLI tool - `codex`, `gemini`, `qwen`, `auto`, or `null` (for agent-only)
|
||||
- `enable_resume`: Whether to use `--resume` for CLI continuity (default: true)
|
||||
- `previous_cli_id`: Previous task's CLI execution ID for resume (populated at runtime)
|
||||
@@ -318,14 +318,16 @@ userConfig.executionMethod → meta.execution_config
|
||||
|
||||
"cli" →
|
||||
meta.execution_config = { method: "cli", cli_tool: userConfig.preferredCliTool, enable_resume: true }
|
||||
Execution: Agent executes pre_analysis, then hands off context + implementation_approach to CLI
|
||||
Execution: Agent executes pre_analysis, then hands off full context to CLI via buildCliHandoffPrompt()
|
||||
|
||||
"hybrid" →
|
||||
meta.execution_config = { method: "hybrid", cli_tool: userConfig.preferredCliTool, enable_resume: true }
|
||||
Execution: Agent decides which tasks to handoff to CLI based on complexity
|
||||
Per-task decision: set method to "agent" OR "cli" per task based on complexity
|
||||
- Simple tasks (≤3 files, straightforward logic) → { method: "agent", cli_tool: null, enable_resume: false }
|
||||
- Complex tasks (>3 files, complex logic, refactoring) → { method: "cli", cli_tool: userConfig.preferredCliTool, enable_resume: true }
|
||||
Final task JSON always has method = "agent" or "cli", never "hybrid"
|
||||
```
|
||||
|
||||
**Note**: implementation_approach steps NO LONGER contain `command` fields. CLI execution is controlled by task-level `meta.execution_config` only.
|
||||
**IMPORTANT**: implementation_approach steps do NOT contain `command` fields. Execution routing is controlled by task-level `meta.execution_config.method` only.
|
||||
|
||||
**Test Task Extensions** (for type="test-gen" or type="test-fix"):
|
||||
|
||||
@@ -344,7 +346,7 @@ userConfig.executionMethod → meta.execution_config
|
||||
- `test_framework`: Existing test framework from project (required for test tasks)
|
||||
- `coverage_target`: Target code coverage percentage (optional)
|
||||
|
||||
**Note**: CLI tool usage for test-fix tasks is now controlled via `flow_control.implementation_approach` steps with `command` fields, not via `meta.use_codex`.
|
||||
**Note**: CLI tool usage for test-fix tasks is now controlled via task-level `meta.execution_config.method`, not via `meta.use_codex`.
|
||||
|
||||
#### Context Object
|
||||
|
||||
@@ -555,59 +557,45 @@ The examples above demonstrate **patterns**, not fixed requirements. Agent MUST:
|
||||
|
||||
##### Implementation Approach
|
||||
|
||||
**Execution Modes**:
|
||||
**Execution Control**:
|
||||
|
||||
The `implementation_approach` supports **two execution modes** based on the presence of the `command` field:
|
||||
The `implementation_approach` defines sequential implementation steps. Execution routing is controlled by **task-level `meta.execution_config.method`**, NOT by step-level `command` fields.
|
||||
|
||||
1. **Default Mode (Agent Execution)** - `command` field **omitted**:
|
||||
**Two Execution Modes**:
|
||||
|
||||
1. **Agent Mode** (`meta.execution_config.method = "agent"`):
|
||||
- Agent interprets `modification_points` and `logic_flow` autonomously
|
||||
- Direct agent execution with full context awareness
|
||||
- No external tool overhead
|
||||
- **Use for**: Standard implementation tasks where agent capability is sufficient
|
||||
- **Required fields**: `step`, `title`, `description`, `modification_points`, `logic_flow`, `depends_on`, `output`
|
||||
|
||||
2. **CLI Mode (Command Execution)** - `command` field **included**:
|
||||
- Specified command executes the step directly
|
||||
- Leverages specialized CLI tools (codex/gemini/qwen) for complex reasoning
|
||||
- **Use for**: Large-scale features, complex refactoring, or when user explicitly requests CLI tool usage
|
||||
- **Required fields**: Same as default mode **PLUS** `command`, `resume_from` (optional)
|
||||
- **Command patterns** (with resume support):
|
||||
- `ccw cli -p '[prompt]' --tool codex --mode write --cd [path]`
|
||||
- `ccw cli -p '[prompt]' --resume ${previousCliId} --tool codex --mode write` (resume from previous)
|
||||
- `ccw cli -p '[prompt]' --tool gemini --mode write --cd [path]` (write mode)
|
||||
- **Resume mechanism**: When step depends on previous CLI execution, include `--resume` with previous execution ID
|
||||
2. **CLI Mode** (`meta.execution_config.method = "cli"`):
|
||||
- Agent executes `pre_analysis`, then hands off full context to CLI via `buildCliHandoffPrompt()`
|
||||
- CLI tool specified in `meta.execution_config.cli_tool` (codex/gemini/qwen)
|
||||
- Leverages specialized CLI tools for complex reasoning
|
||||
- **Use for**: Large-scale features, complex refactoring, or when userConfig.executionMethod = "cli"
|
||||
|
||||
**Semantic CLI Tool Selection**:
|
||||
**Step Schema** (same for both modes):
|
||||
```json
|
||||
{
|
||||
"step": 1,
|
||||
"title": "Step title",
|
||||
"description": "What to implement (may use [variable] placeholders from pre_analysis)",
|
||||
"modification_points": ["Quantified changes: [list with counts]"],
|
||||
"logic_flow": ["Implementation sequence"],
|
||||
"depends_on": [0],
|
||||
"output": "variable_name"
|
||||
}
|
||||
```
|
||||
|
||||
Agent determines CLI tool usage per-step based on user semantics and task nature.
|
||||
**Required fields**: `step`, `title`, `description`, `modification_points`, `logic_flow`, `depends_on`, `output`
|
||||
|
||||
**Source**: Scan `metadata.task_description` from context-package.json for CLI tool preferences.
|
||||
**IMPORTANT**: Do NOT add `command` field to implementation_approach steps. Execution routing is determined by task-level `meta.execution_config.method` only.
|
||||
|
||||
**User Semantic Triggers** (patterns to detect in task_description):
|
||||
- "use Codex/codex" → Add `command` field with Codex CLI
|
||||
- "use Gemini/gemini" → Add `command` field with Gemini CLI
|
||||
- "use Qwen/qwen" → Add `command` field with Qwen CLI
|
||||
- "CLI execution" / "automated" → Infer appropriate CLI tool
|
||||
|
||||
**Task-Based Selection** (when no explicit user preference):
|
||||
- **Implementation/coding**: Codex preferred for autonomous development
|
||||
- **Analysis/exploration**: Gemini preferred for large context analysis
|
||||
- **Documentation**: Gemini/Qwen with write mode (`--mode write`)
|
||||
- **Testing**: Depends on complexity - simple=agent, complex=Codex
|
||||
|
||||
**Default Behavior**: Agent always executes the workflow. CLI commands are embedded in `implementation_approach` steps:
|
||||
- Agent orchestrates task execution
|
||||
- When step has `command` field, agent executes it via CCW CLI
|
||||
- When step has no `command` field, agent implements directly
|
||||
- This maintains agent control while leveraging CLI tool power
|
||||
|
||||
**Key Principle**: The `command` field is **optional**. Agent decides based on user semantics and task complexity.
|
||||
|
||||
**Examples**:
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
[
|
||||
// === DEFAULT MODE: Agent Execution (no command field) ===
|
||||
{
|
||||
"step": 1,
|
||||
"title": "Load and analyze role analyses",
|
||||
@@ -644,8 +632,7 @@ Agent determines CLI tool usage per-step based on user semantics and task nature
|
||||
],
|
||||
"depends_on": [1],
|
||||
"output": "implementation"
|
||||
},
|
||||
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
@@ -202,33 +202,17 @@ for (const step of task.flow_control.pre_analysis || []) {
|
||||
preAnalysisResults[step.output_to] = result;
|
||||
}
|
||||
|
||||
// Phase 2: Determine execution mode
|
||||
const hasLegacyCommands = task.flow_control.implementation_approach
|
||||
.some(step => step.command);
|
||||
// Phase 2: Determine execution mode (based on task.meta.execution_config.method)
|
||||
// Two modes: 'cli' (call CLI tool) or 'agent' (execute directly)
|
||||
|
||||
IF hasLegacyCommands:
|
||||
// Backward compatibility: Old mode with step.command fields
|
||||
FOR each step in implementation_approach[]:
|
||||
IF step.command exists:
|
||||
→ Execute via Bash: Bash({ command: step.command, timeout: 3600000 })
|
||||
ELSE:
|
||||
→ Agent direct implementation
|
||||
|
||||
ELSE IF executionMethod === 'cli':
|
||||
// New mode: CLI Handoff
|
||||
→ const cliPrompt = buildCliHandoffPrompt(preAnalysisResults, task)
|
||||
IF executionMethod === 'cli':
|
||||
// CLI Handoff: Full context passed to CLI via buildCliHandoffPrompt
|
||||
→ const cliPrompt = buildCliHandoffPrompt(preAnalysisResults, task, taskJsonPath)
|
||||
→ const cliCommand = buildCliCommand(task, cliTool, cliPrompt)
|
||||
→ Bash({ command: cliCommand, run_in_background: false, timeout: 3600000 })
|
||||
|
||||
ELSE IF executionMethod === 'hybrid':
|
||||
// Hybrid mode: Agent decides based on task complexity
|
||||
→ IF task is complex (multiple files, complex logic):
|
||||
Use CLI Handoff (same as cli mode)
|
||||
ELSE:
|
||||
Use Agent direct implementation
|
||||
|
||||
ELSE (executionMethod === 'agent'):
|
||||
// Default: Agent direct implementation
|
||||
// Execute implementation steps directly
|
||||
FOR each step in implementation_approach[]:
|
||||
1. Variable Substitution: Replace [variable_name] with preAnalysisResults
|
||||
2. Read modification_points[] as files to create/modify
|
||||
@@ -253,26 +237,23 @@ function getDefaultCliTool() {
|
||||
}
|
||||
|
||||
// Build CLI prompt from pre-analysis results and task
|
||||
function buildCliHandoffPrompt(preAnalysisResults, task) {
|
||||
function buildCliHandoffPrompt(preAnalysisResults, task, taskJsonPath) {
|
||||
const contextSection = Object.entries(preAnalysisResults)
|
||||
.map(([key, value]) => `### ${key}\n${value}`)
|
||||
.join('\n\n');
|
||||
|
||||
const approachSection = task.flow_control.implementation_approach
|
||||
.map((step, i) => `
|
||||
### Step ${step.step}: ${step.title}
|
||||
${step.description}
|
||||
|
||||
**Modification Points**:
|
||||
${step.modification_points?.map(m => `- ${m}`).join('\n') || 'N/A'}
|
||||
|
||||
**Logic Flow**:
|
||||
${step.logic_flow?.map((l, j) => `${j + 1}. ${l}`).join('\n') || 'Follow modification points'}
|
||||
`).join('\n');
|
||||
const conventions = task.context.shared_context?.conventions?.join(' | ') || '';
|
||||
const constraints = `Follow existing patterns | No breaking changes${conventions ? ' | ' + conventions : ''}`;
|
||||
|
||||
return `
|
||||
PURPOSE: ${task.title}
|
||||
Complete implementation based on pre-analyzed context.
|
||||
Complete implementation based on pre-analyzed context and task JSON.
|
||||
|
||||
## TASK JSON
|
||||
Read full task definition: ${taskJsonPath}
|
||||
|
||||
## TECH STACK
|
||||
${task.context.shared_context?.tech_stack?.map(t => `- ${t}`).join('\n') || 'Auto-detect from project files'}
|
||||
|
||||
## PRE-ANALYSIS CONTEXT
|
||||
${contextSection}
|
||||
@@ -280,17 +261,17 @@ ${contextSection}
|
||||
## REQUIREMENTS
|
||||
${task.context.requirements?.map(r => `- ${r}`).join('\n') || task.context.requirements}
|
||||
|
||||
## IMPLEMENTATION APPROACH
|
||||
${approachSection}
|
||||
|
||||
## ACCEPTANCE CRITERIA
|
||||
${task.context.acceptance?.map(a => `- ${a}`).join('\n') || task.context.acceptance}
|
||||
|
||||
## TARGET FILES
|
||||
${task.flow_control.target_files?.map(f => `- ${f}`).join('\n') || 'See modification points above'}
|
||||
${task.flow_control.target_files?.map(f => `- ${f}`).join('\n') || 'See task JSON modification_points'}
|
||||
|
||||
## FOCUS PATHS
|
||||
${task.context.focus_paths?.map(p => `- ${p}`).join('\n') || 'See task JSON'}
|
||||
|
||||
MODE: write
|
||||
CONSTRAINTS: Follow existing patterns | No breaking changes
|
||||
CONSTRAINTS: ${constraints}
|
||||
`.trim();
|
||||
}
|
||||
|
||||
@@ -319,7 +300,7 @@ function buildCliCommand(task, cliTool, cliPrompt) {
|
||||
**Execution Config Reference** (from task.meta.execution_config):
|
||||
| Field | Values | Description |
|
||||
|-------|--------|-------------|
|
||||
| `method` | `agent` / `cli` / `hybrid` | Execution mode (default: agent) |
|
||||
| `method` | `agent` / `cli` | Execution mode (default: agent) |
|
||||
| `cli_tool` | See `~/.claude/cli-tools.json` | CLI tool preference (first enabled tool as default) |
|
||||
| `enable_resume` | `true` / `false` | Enable CLI session resume |
|
||||
|
||||
|
||||
@@ -154,11 +154,15 @@ STEP 1: Parse Red Phase Requirements
|
||||
→ Load existing test patterns from focus_paths
|
||||
|
||||
STEP 2: Execute Red Phase Implementation
|
||||
IF step.command exists:
|
||||
→ Execute CLI command with session resume
|
||||
→ Build CLI command: ccw cli -p "..." --resume {resume_from} --tool {tool} --mode write
|
||||
const executionMethod = task.meta?.execution_config?.method || 'agent';
|
||||
|
||||
IF executionMethod === 'cli':
|
||||
// CLI Handoff: Full context passed via buildCliHandoffPrompt
|
||||
→ const cliPrompt = buildCliHandoffPrompt(preAnalysisResults, task, taskJsonPath)
|
||||
→ const cliCommand = buildCliCommand(task, cliTool, cliPrompt)
|
||||
→ Bash({ command: cliCommand, run_in_background: false, timeout: 3600000 })
|
||||
ELSE:
|
||||
→ Direct agent implementation
|
||||
// Execute directly
|
||||
→ Create test files in modification_points
|
||||
→ Write test cases following test_cases enumeration
|
||||
→ Use context.shared_context.conventions for test style
|
||||
@@ -195,11 +199,16 @@ STEP 1: Parse Green Phase Requirements
|
||||
→ Set max_iterations from meta.max_iterations (default: 3)
|
||||
|
||||
STEP 2: Initial Implementation
|
||||
IF step.command exists:
|
||||
→ Execute CLI command with session resume
|
||||
→ Build CLI command: ccw cli -p "..." --resume {resume_from} --tool {tool} --mode write
|
||||
const executionMethod = task.meta?.execution_config?.method || 'agent';
|
||||
|
||||
IF executionMethod === 'cli':
|
||||
// CLI Handoff: Full context passed via buildCliHandoffPrompt
|
||||
→ const cliPrompt = buildCliHandoffPrompt(preAnalysisResults, task, taskJsonPath)
|
||||
→ const cliCommand = buildCliCommand(task, cliTool, cliPrompt)
|
||||
→ Bash({ command: cliCommand, run_in_background: false, timeout: 3600000 })
|
||||
|
||||
ELSE:
|
||||
→ Direct agent implementation
|
||||
// Execute implementation steps directly
|
||||
→ Implement functions in modification_points
|
||||
→ Follow logic_flow sequence
|
||||
→ Use minimal code to pass tests (no over-engineering)
|
||||
@@ -293,10 +302,15 @@ STEP 1: Parse Refactor Phase Requirements
|
||||
→ Load refactoring scope from modification_points
|
||||
|
||||
STEP 2: Execute Refactor Implementation
|
||||
IF step.command exists:
|
||||
→ Execute CLI command with session resume
|
||||
const executionMethod = task.meta?.execution_config?.method || 'agent';
|
||||
|
||||
IF executionMethod === 'cli':
|
||||
// CLI Handoff: Full context passed via buildCliHandoffPrompt
|
||||
→ const cliPrompt = buildCliHandoffPrompt(preAnalysisResults, task, taskJsonPath)
|
||||
→ const cliCommand = buildCliCommand(task, cliTool, cliPrompt)
|
||||
→ Bash({ command: cliCommand, run_in_background: false, timeout: 3600000 })
|
||||
ELSE:
|
||||
→ Direct agent refactoring
|
||||
// Execute directly
|
||||
→ Apply refactorings from logic_flow
|
||||
→ Follow refactoring best practices:
|
||||
• Extract functions for clarity
|
||||
@@ -326,47 +340,15 @@ STEP 3: Regression Testing (REQUIRED)
|
||||
|
||||
### 3. CLI Execution Integration
|
||||
|
||||
**CLI Session Resumption** (when step.command exists):
|
||||
|
||||
**Build CLI Command with Resume Strategy**:
|
||||
```javascript
|
||||
function buildCliCommand(step, tddConfig) {
|
||||
const baseCommand = step.command // From task JSON
|
||||
|
||||
// Parse cli_execution strategy
|
||||
switch (tddConfig.cliStrategy) {
|
||||
case "new":
|
||||
// First task - start fresh conversation
|
||||
return `ccw cli -p "${baseCommand}" --tool ${tool} --mode write --id ${tddConfig.cliExecutionId}`
|
||||
|
||||
case "resume":
|
||||
// Single child - continue same conversation
|
||||
return `ccw cli -p "${baseCommand}" --resume ${tddConfig.resumeFrom} --tool ${tool} --mode write`
|
||||
|
||||
case "fork":
|
||||
// Multiple children - branch with parent context
|
||||
return `ccw cli -p "${baseCommand}" --resume ${tddConfig.resumeFrom} --id ${tddConfig.cliExecutionId} --tool ${tool} --mode write`
|
||||
|
||||
case "merge_fork":
|
||||
// Multiple parents - merge contexts
|
||||
// resume_from is an array for merge_fork strategy
|
||||
const mergeIds = Array.isArray(tddConfig.resumeFrom)
|
||||
? tddConfig.resumeFrom.join(',')
|
||||
: tddConfig.resumeFrom
|
||||
return `ccw cli -p "${baseCommand}" --resume ${mergeIds} --id ${tddConfig.cliExecutionId} --tool ${tool} --mode write`
|
||||
|
||||
default:
|
||||
// Fallback - no resume
|
||||
return `ccw cli -p "${baseCommand}" --tool ${tool} --mode write`
|
||||
}
|
||||
}
|
||||
```
|
||||
**CLI Functions** (inherited from code-developer):
|
||||
- `buildCliHandoffPrompt(preAnalysisResults, task, taskJsonPath)` - Assembles CLI prompt with full context
|
||||
- `buildCliCommand(task, cliTool, cliPrompt)` - Builds CLI command with resume strategy
|
||||
|
||||
**Execute CLI Command**:
|
||||
```javascript
|
||||
// TDD agent runs in foreground - can receive hook callbacks
|
||||
Bash(
|
||||
command=buildCliCommand(step, tddConfig),
|
||||
command=buildCliCommand(task, cliTool, cliPrompt),
|
||||
timeout=3600000, // 60 min for CLI execution
|
||||
run_in_background=false // Agent can receive task completion hooks
|
||||
)
|
||||
@@ -504,7 +486,7 @@ Before completing any TDD task, verify:
|
||||
- Use test-fix cycle in Green phase
|
||||
- Auto-revert on max iterations failure
|
||||
- Generate TDD-enhanced summaries
|
||||
- Use CLI resume strategies when step.command exists
|
||||
- Use CLI resume strategies when meta.execution_config.method is "cli"
|
||||
- Log all test-fix iterations to .process/
|
||||
|
||||
**Bash Tool (CLI Execution in TDD Agent)**:
|
||||
|
||||
@@ -83,15 +83,15 @@ When task JSON contains implementation_approach array:
|
||||
- `description`: Detailed description with variable references
|
||||
- `modification_points`: Test and code modification targets
|
||||
- `logic_flow`: Test-fix iteration sequence
|
||||
- `command`: Optional CLI command (only when explicitly specified)
|
||||
- `depends_on`: Array of step numbers that must complete first
|
||||
- `output`: Variable name for this step's output
|
||||
5. **Execution Mode Selection**:
|
||||
- IF `command` field exists → Execute CLI command via Bash tool
|
||||
- ELSE (no command) → Agent direct execution:
|
||||
- Parse `modification_points` as files to modify
|
||||
- Follow `logic_flow` for test-fix iteration
|
||||
- Use test_commands from flow_control for test execution
|
||||
- Based on `meta.execution_config.method`:
|
||||
- `"cli"` → Build CLI command via buildCliHandoffPrompt() and execute via Bash tool
|
||||
- `"agent"` (default) → Agent direct execution:
|
||||
- Parse `modification_points` as files to modify
|
||||
- Follow `logic_flow` for test-fix iteration
|
||||
- Use test_commands from flow_control for test execution
|
||||
|
||||
|
||||
### 1. Context Assessment & Test Discovery
|
||||
|
||||
@@ -284,16 +284,24 @@ Execution Method: ${userConfig.executionMethod} // agent|hybrid|cli
|
||||
Preferred CLI Tool: ${userConfig.preferredCliTool} // codex|gemini|qwen|auto
|
||||
Supplementary Materials: ${userConfig.supplementaryMaterials}
|
||||
|
||||
## CLI TOOL SELECTION
|
||||
Based on userConfig.executionMethod:
|
||||
- "agent": No command field in implementation_approach steps
|
||||
- "hybrid": Add command field to complex steps only (agent handles simple steps)
|
||||
- "cli": Add command field to ALL implementation_approach steps
|
||||
## EXECUTION METHOD MAPPING
|
||||
Based on userConfig.executionMethod, set task-level meta.execution_config:
|
||||
|
||||
CLI Resume Support (MANDATORY for all CLI commands):
|
||||
- Use --resume parameter to continue from previous task execution
|
||||
- Read previous task's cliExecutionId from session state
|
||||
- Format: ccw cli -p "[prompt]" --resume ${previousCliId} --tool ${tool} --mode write
|
||||
"agent" →
|
||||
meta.execution_config = { method: "agent", cli_tool: null, enable_resume: false }
|
||||
Agent executes implementation_approach steps directly
|
||||
|
||||
"cli" →
|
||||
meta.execution_config = { method: "cli", cli_tool: userConfig.preferredCliTool, enable_resume: true }
|
||||
Agent executes pre_analysis, then hands off full context to CLI via buildCliHandoffPrompt()
|
||||
|
||||
"hybrid" →
|
||||
Per-task decision: Analyze task complexity, set method to "agent" OR "cli" per task
|
||||
- Simple tasks (≤3 files, straightforward logic) → method: "agent"
|
||||
- Complex tasks (>3 files, complex logic, refactoring) → method: "cli"
|
||||
CLI tool: userConfig.preferredCliTool, enable_resume: true
|
||||
|
||||
IMPORTANT: Do NOT add command field to implementation_approach steps. Execution routing is controlled by task-level meta.execution_config.method only.
|
||||
|
||||
## PRIORITIZED CONTEXT (from context-package.prioritized_context) - ALREADY SORTED
|
||||
Context sorting is ALREADY COMPLETED in context-gather Phase 2/3. DO NOT re-sort.
|
||||
@@ -458,16 +466,24 @@ Execution Method: ${userConfig.executionMethod} // agent|hybrid|cli
|
||||
Preferred CLI Tool: ${userConfig.preferredCliTool} // codex|gemini|qwen|auto
|
||||
Supplementary Materials: ${userConfig.supplementaryMaterials}
|
||||
|
||||
## CLI TOOL SELECTION
|
||||
Based on userConfig.executionMethod:
|
||||
- "agent": No command field in implementation_approach steps
|
||||
- "hybrid": Add command field to complex steps only (agent handles simple steps)
|
||||
- "cli": Add command field to ALL implementation_approach steps
|
||||
## EXECUTION METHOD MAPPING
|
||||
Based on userConfig.executionMethod, set task-level meta.execution_config:
|
||||
|
||||
CLI Resume Support (MANDATORY for all CLI commands):
|
||||
- Use --resume parameter to continue from previous task execution
|
||||
- Read previous task's cliExecutionId from session state
|
||||
- Format: ccw cli -p "[prompt]" --resume ${previousCliId} --tool ${tool} --mode write
|
||||
"agent" →
|
||||
meta.execution_config = { method: "agent", cli_tool: null, enable_resume: false }
|
||||
Agent executes implementation_approach steps directly
|
||||
|
||||
"cli" →
|
||||
meta.execution_config = { method: "cli", cli_tool: userConfig.preferredCliTool, enable_resume: true }
|
||||
Agent executes pre_analysis, then hands off full context to CLI via buildCliHandoffPrompt()
|
||||
|
||||
"hybrid" →
|
||||
Per-task decision: Analyze task complexity, set method to "agent" OR "cli" per task
|
||||
- Simple tasks (≤3 files, straightforward logic) → method: "agent"
|
||||
- Complex tasks (>3 files, complex logic, refactoring) → method: "cli"
|
||||
CLI tool: userConfig.preferredCliTool, enable_resume: true
|
||||
|
||||
IMPORTANT: Do NOT add command field to implementation_approach steps. Execution routing is controlled by task-level meta.execution_config.method only.
|
||||
|
||||
## PRIORITIZED CONTEXT (from context-package.prioritized_context) - ALREADY SORTED
|
||||
Context sorting is ALREADY COMPLETED in context-gather Phase 2/3. DO NOT re-sort.
|
||||
|
||||
@@ -359,16 +359,24 @@ Execution Method: ${userConfig.executionMethod} // agent|hybrid|cli
|
||||
Preferred CLI Tool: ${userConfig.preferredCliTool} // codex|gemini|qwen|auto
|
||||
Supplementary Materials: ${userConfig.supplementaryMaterials}
|
||||
|
||||
## CLI TOOL SELECTION
|
||||
Based on userConfig.executionMethod:
|
||||
- "agent": No command field in implementation_approach steps
|
||||
- "hybrid": Add command field to complex steps only (Red/Green phases recommended for CLI)
|
||||
- "cli": Add command field to ALL Red-Green-Refactor steps
|
||||
## EXECUTION METHOD MAPPING
|
||||
Based on userConfig.executionMethod, set task-level meta.execution_config:
|
||||
|
||||
CLI Resume Support (MANDATORY for all CLI commands):
|
||||
- Use --resume parameter to continue from previous task execution
|
||||
- Read previous task's cliExecutionId from session state
|
||||
- Format: ccw cli -p "[prompt]" --resume [previousCliId] --tool [tool] --mode write
|
||||
"agent" →
|
||||
meta.execution_config = { method: "agent", cli_tool: null, enable_resume: false }
|
||||
Agent executes Red-Green-Refactor phases directly
|
||||
|
||||
"cli" →
|
||||
meta.execution_config = { method: "cli", cli_tool: userConfig.preferredCliTool, enable_resume: true }
|
||||
Agent executes pre_analysis, then hands off full context to CLI via buildCliHandoffPrompt()
|
||||
|
||||
"hybrid" →
|
||||
Per-task decision: Analyze TDD cycle complexity, set method to "agent" OR "cli" per task
|
||||
- Simple cycles (≤5 test cases, ≤3 files) → method: "agent"
|
||||
- Complex cycles (>5 test cases, >3 files, integration tests) → method: "cli"
|
||||
CLI tool: userConfig.preferredCliTool, enable_resume: true
|
||||
|
||||
IMPORTANT: Do NOT add command field to implementation_approach steps. Execution routing is controlled by task-level meta.execution_config.method only.
|
||||
|
||||
## EXPLORATION CONTEXT (from context-package.exploration_results)
|
||||
- Load exploration_results from context-package.json
|
||||
@@ -426,7 +434,7 @@ CLI Resume Support (MANDATORY for all CLI commands):
|
||||
2. Green Phase (`tdd_phase: "green"`): Implement to pass tests
|
||||
3. Refactor Phase (`tdd_phase: "refactor"`): Improve code quality
|
||||
- `flow_control.pre_analysis`: Include exploration integration_points analysis
|
||||
- CLI tool usage based on userConfig (add `command` field per executionMethod)
|
||||
- **meta.execution_config**: Set per userConfig.executionMethod (agent/cli/hybrid)
|
||||
- **Details**: See action-planning-agent.md § TDD Task JSON Generation
|
||||
|
||||
##### 2. IMPL_PLAN.md (TDD Variant)
|
||||
@@ -623,7 +631,7 @@ This section provides quick reference for TDD task JSON structure. For complete
|
||||
- Context: `focus_paths` use absolute or clear relative paths
|
||||
- Flow control: Exactly 3 steps with `tdd_phase` field ("red", "green", "refactor")
|
||||
- Flow control: `pre_analysis` includes exploration integration_points analysis
|
||||
- Command field: Added per `userConfig.executionMethod` (agent/hybrid/cli)
|
||||
- **meta.execution_config**: Set per `userConfig.executionMethod` (agent/cli/hybrid)
|
||||
- See Phase 2 agent prompt for full schema and requirements
|
||||
|
||||
## Output Files Structure
|
||||
@@ -736,7 +744,7 @@ IMPL (Green phase) tasks include automatic test-fix cycle:
|
||||
3. **Success Path**: Tests pass → Complete task
|
||||
4. **Failure Path**: Tests fail → Enter iterative fix cycle:
|
||||
- **Gemini Diagnosis**: Analyze failures with bug-fix template
|
||||
- **Fix Application**: Agent (default) or CLI (if `command` field present)
|
||||
- **Fix Application**: Agent executes fixes directly
|
||||
- **Retest**: Verify fix resolves failures
|
||||
- **Repeat**: Up to max_iterations (default: 3)
|
||||
5. **Safety Net**: Auto-revert all changes if max iterations reached
|
||||
@@ -745,5 +753,5 @@ IMPL (Green phase) tasks include automatic test-fix cycle:
|
||||
|
||||
## Configuration Options
|
||||
- **meta.max_iterations**: Number of fix attempts in Green phase (default: 3)
|
||||
- **CLI tool usage**: Determined semantically from user's task description via `command` field in implementation_approach
|
||||
- **meta.execution_config.method**: Execution routing (agent/cli) determined from userConfig.executionMethod
|
||||
|
||||
|
||||
@@ -116,6 +116,16 @@ export function CliSettingsModal({ open, onClose, cliSettings }: CliSettingsModa
|
||||
|
||||
if (!name.trim()) {
|
||||
newErrors.name = formatMessage({ id: 'apiSettings.validation.nameRequired' });
|
||||
} else {
|
||||
// Validate name format: must start with letter, followed by letters/numbers/hyphens/underscores
|
||||
const namePattern = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
|
||||
if (!namePattern.test(name.trim())) {
|
||||
newErrors.name = formatMessage({ id: 'apiSettings.cliSettings.nameFormatHint' });
|
||||
}
|
||||
// Validate name length
|
||||
if (name.trim().length > 32) {
|
||||
newErrors.name = formatMessage({ id: 'apiSettings.cliSettings.nameTooLong' }, { max: 32 });
|
||||
}
|
||||
}
|
||||
|
||||
if (mode === 'provider-based') {
|
||||
@@ -219,7 +229,11 @@ export function CliSettingsModal({ open, onClose, cliSettings }: CliSettingsModa
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
placeholder={formatMessage({ id: 'apiSettings.cliSettings.namePlaceholder' })}
|
||||
className={errors.name ? 'border-destructive' : ''}
|
||||
maxLength={32}
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{formatMessage({ id: 'apiSettings.cliSettings.nameFormatHint' })}
|
||||
</p>
|
||||
{errors.name && <p className="text-sm text-destructive">{errors.name}</p>}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@ function DeviceCard({ device, isSelected, onSelect, isSelecting }: DeviceCardPro
|
||||
)}
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{formatMessage({ id: 'codexlens.gpu.type' })}: {device.type === 'discrete' ? '独立显卡' : '集成显卡'}
|
||||
{formatMessage({ id: 'codexlens.gpu.type' })}: {formatMessage({ id: device.type === 'discrete' ? 'codexlens.gpu.discrete' : 'codexlens.gpu.integrated' })}
|
||||
</p>
|
||||
{device.memory?.total && (
|
||||
<p className="text-xs text-muted-foreground">
|
||||
|
||||
@@ -289,6 +289,8 @@
|
||||
"descriptionPlaceholder": "Optional description for this configuration",
|
||||
"selectProvider": "Select a provider",
|
||||
"includeCoAuthoredBy": "Include co-authored-by in commits",
|
||||
"nameFormatHint": "Letters, numbers, hyphens, underscores only. Used as: ccw cli --tool [name]",
|
||||
"nameTooLong": "Name must be {max} characters or less",
|
||||
"validation": {
|
||||
"providerRequired": "Please select a provider",
|
||||
"authOrBaseUrlRequired": "Please enter auth token or base URL"
|
||||
|
||||
@@ -142,6 +142,8 @@
|
||||
"notAvailable": "GPU functionality not available",
|
||||
"unknownDevice": "Unknown device",
|
||||
"type": "Type",
|
||||
"discrete": "Discrete GPU",
|
||||
"integrated": "Integrated GPU",
|
||||
"driver": "Driver Version",
|
||||
"memory": "Memory"
|
||||
},
|
||||
|
||||
@@ -289,6 +289,8 @@
|
||||
"descriptionPlaceholder": "此配置的可选描述",
|
||||
"selectProvider": "选择提供商",
|
||||
"includeCoAuthoredBy": "在提交中包含 co-authored-by",
|
||||
"nameFormatHint": "仅限字母、数字、连字符和下划线。用作:ccw cli --tool [名称]",
|
||||
"nameTooLong": "名称必须在 {max} 个字符以内",
|
||||
"validation": {
|
||||
"providerRequired": "请选择提供商",
|
||||
"authOrBaseUrlRequired": "请输入认证令牌或基础 URL"
|
||||
|
||||
@@ -142,6 +142,8 @@
|
||||
"notAvailable": "GPU 功能不可用",
|
||||
"unknownDevice": "未知设备",
|
||||
"type": "类型",
|
||||
"discrete": "独立显卡",
|
||||
"integrated": "集成显卡",
|
||||
"driver": "驱动版本",
|
||||
"memory": "显存"
|
||||
},
|
||||
|
||||
@@ -446,9 +446,9 @@ export function SettingsPage() {
|
||||
{/* System Theme Toggle (Backward Compatibility) */}
|
||||
<div className="flex items-center justify-between pt-4 border-t border-border">
|
||||
<div>
|
||||
<p className="font-medium text-foreground">系统跟随</p>
|
||||
<p className="font-medium text-foreground">{formatMessage({ id: 'settings.appearance.systemFollow' })}</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
使用系统的深色/浅色模式设置
|
||||
{formatMessage({ id: 'settings.appearance.systemFollowDesc' })}
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
|
||||
@@ -421,7 +421,7 @@ async function showToolConfigModal(toolName) {
|
||||
var status = cliToolStatus[toolName] || {};
|
||||
|
||||
if (!toolConfig) {
|
||||
toolConfig = { enabled: true, primaryModel: '', secondaryModel: '' };
|
||||
toolConfig = { enabled: true, primaryModel: '', secondaryModel: '', type: 'builtin' };
|
||||
}
|
||||
|
||||
var content = buildToolConfigModalContent(toolName, toolConfig, models, status);
|
||||
@@ -1163,7 +1163,7 @@ function initToolConfigModalEvents(tool, currentConfig, models) {
|
||||
}
|
||||
|
||||
// Only include settingsFile for builtin claude tool
|
||||
if (tool === 'claude' && config.type === 'builtin') {
|
||||
if (tool === 'claude' && currentConfig.type === 'builtin') {
|
||||
updateData.settingsFile = settingsFile || null;
|
||||
}
|
||||
|
||||
|
||||
@@ -228,10 +228,13 @@ function getGlobalSettingsPath(): string {
|
||||
*/
|
||||
function resolveConfigPath(projectDir: string): { path: string; source: 'project' | 'global' | 'default' } {
|
||||
const globalPath = getGlobalConfigPath();
|
||||
debugLog(`[HYPOTHESIS-1] Checking for global config at: ${globalPath}`);
|
||||
if (fs.existsSync(globalPath)) {
|
||||
debugLog(`[HYPOTHESIS-1] Global config found. Using source: 'global'`);
|
||||
return { path: globalPath, source: 'global' };
|
||||
}
|
||||
|
||||
debugLog(`[HYPOTHESIS-1] Global config NOT found. Using source: 'default'`);
|
||||
// Return global path for default (will be created there)
|
||||
return { path: globalPath, source: 'default' };
|
||||
}
|
||||
@@ -278,15 +281,13 @@ function backupConfigFile(filePath: string): string {
|
||||
|
||||
/**
|
||||
* Ensure tool has required fields (for backward compatibility)
|
||||
* Preserves ALL fields from original tool object
|
||||
*/
|
||||
function ensureToolTags(tool: Partial<ClaudeCliTool>): ClaudeCliTool {
|
||||
return {
|
||||
...tool, // Preserve all original fields (including availableModels, type, id, etc.)
|
||||
enabled: tool.enabled ?? true,
|
||||
primaryModel: tool.primaryModel,
|
||||
secondaryModel: tool.secondaryModel,
|
||||
tags: tool.tags ?? [],
|
||||
envFile: tool.envFile,
|
||||
settingsFile: tool.settingsFile
|
||||
tags: tool.tags ?? []
|
||||
};
|
||||
}
|
||||
|
||||
@@ -509,10 +510,12 @@ export async function ensureClaudeCliToolsAsync(projectDir: string, createInProj
|
||||
* Automatically migrates older config versions to v3.2.0
|
||||
*/
|
||||
export function loadClaudeCliTools(projectDir: string): ClaudeCliToolsConfig & { _source?: string } {
|
||||
debugLog(`[DIAGNOSIS] Starting to load claude cli tools for projectDir: ${projectDir}`);
|
||||
const resolved = resolveConfigPath(projectDir);
|
||||
|
||||
try {
|
||||
if (resolved.source === 'default') {
|
||||
debugLog('[DIAGNOSIS] Resolved source is "default", returning default config.');
|
||||
return { ...DEFAULT_TOOLS_CONFIG, _source: 'default' };
|
||||
}
|
||||
|
||||
@@ -526,9 +529,8 @@ export function loadClaudeCliTools(projectDir: string): ClaudeCliToolsConfig & {
|
||||
const mergedTools: Record<string, ClaudeCliTool> = {};
|
||||
for (const [key, tool] of Object.entries(migrated.tools || {})) {
|
||||
mergedTools[key] = {
|
||||
...ensureToolTags(tool),
|
||||
type: tool.type ?? 'builtin',
|
||||
id: tool.id // Preserve id for api-endpoint type
|
||||
...ensureToolTags(tool), // Now preserves all fields including availableModels, type, id
|
||||
type: tool.type ?? 'builtin' // Ensure type has default value
|
||||
};
|
||||
}
|
||||
|
||||
@@ -554,6 +556,7 @@ export function loadClaudeCliTools(projectDir: string): ClaudeCliToolsConfig & {
|
||||
debugLog(`[claude-cli-tools] Loaded tools config from ${resolved.source}: ${resolved.path}`);
|
||||
return config;
|
||||
} catch (err) {
|
||||
console.error('[HYPOTHESIS-2] Error loading or parsing tools config. Falling back to default. Error:', err);
|
||||
console.error('[claude-cli-tools] Error loading tools config:', err);
|
||||
return { ...DEFAULT_TOOLS_CONFIG, _source: 'default' };
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ export interface CliToolConfig {
|
||||
secondaryModel: string;
|
||||
tags?: string[];
|
||||
envFile?: string | null;
|
||||
type?: 'builtin' | 'cli-wrapper' | 'api-endpoint'; // Tool type for frontend routing
|
||||
settingsFile?: string | null; // Claude CLI settings file path
|
||||
}
|
||||
|
||||
export interface CliConfig {
|
||||
@@ -156,7 +158,9 @@ export function getFullConfigResponse(baseDir: string): {
|
||||
primaryModel: tool.primaryModel ?? '',
|
||||
secondaryModel: tool.secondaryModel ?? '',
|
||||
tags: tool.tags,
|
||||
envFile: tool.envFile
|
||||
envFile: tool.envFile,
|
||||
type: tool.type, // Preserve type field for frontend routing
|
||||
settingsFile: tool.settingsFile // Preserve settingsFile for Claude CLI
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user