mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-12 02:37:45 +08:00
fix: 为所有 skill 的 .workflow/ 路径添加 projectRoot 前缀
从子目录执行 skill 时,相对路径 .workflow/ 会导致产物落到错误位置。
通过 git rev-parse --show-toplevel || pwd 检测项目根目录,
所有 .workflow/ 路径引用统一加上 {projectRoot} 前缀确保路径正确。
涉及 72 个文件,覆盖 20+ 个 skill。
This commit is contained in:
@@ -91,7 +91,7 @@ Spawn multiple workers simultaneously, batch wait for results.
|
||||
## Session Structure
|
||||
|
||||
```
|
||||
.workflow/.loop/
|
||||
{projectRoot}/.workflow/.loop/
|
||||
+-- {loopId}.json # Master state
|
||||
+-- {loopId}.workers/ # Worker outputs
|
||||
| +-- init.output.json
|
||||
@@ -184,7 +184,7 @@ Coordinator adapts to mode:
|
||||
|
||||
### 3. State Management
|
||||
|
||||
Unified state at `.workflow/.loop/{loopId}.json`:
|
||||
Unified state at `{projectRoot}/.workflow/.loop/{loopId}.json`:
|
||||
- **API compatible**: Works with CCW API
|
||||
- **Extension fields**: Skill-specific data in `skill_state`
|
||||
- **Worker outputs**: Structured JSON for each action
|
||||
|
||||
@@ -142,7 +142,7 @@ return finalState
|
||||
## Session Structure
|
||||
|
||||
```
|
||||
.workflow/.loop/
|
||||
{projectRoot}/.workflow/.loop/
|
||||
├── {loopId}.json # Master state (API + Skill shared)
|
||||
├── {loopId}.workers/ # Worker structured outputs
|
||||
│ ├── init.output.json
|
||||
@@ -159,7 +159,7 @@ return finalState
|
||||
|
||||
## State Management
|
||||
|
||||
Master state file: `.workflow/.loop/{loopId}.json`
|
||||
Master state file: `{projectRoot}/.workflow/.loop/{loopId}.json`
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -233,8 +233,8 @@ function buildWorkerPrompt(action, loopId, state) {
|
||||
|
||||
### MANDATORY FIRST STEPS (Agent Execute)
|
||||
1. **Read role definition**: ~/.codex/agents/ccw-loop-b-${action}.md (MUST read first)
|
||||
2. Read: .workflow/project-tech.json
|
||||
3. Read: .workflow/project-guidelines.json
|
||||
2. Read: ${projectRoot}/.workflow/project-tech.json
|
||||
3. Read: ${projectRoot}/.workflow/project-guidelines.json
|
||||
|
||||
---
|
||||
|
||||
@@ -247,9 +247,9 @@ Scope:
|
||||
|
||||
Context:
|
||||
- Loop ID: ${loopId}
|
||||
- State: .workflow/.loop/${loopId}.json
|
||||
- Output: .workflow/.loop/${loopId}.workers/${action}.output.json
|
||||
- Progress: .workflow/.loop/${loopId}.progress/${action}.md
|
||||
- State: ${projectRoot}/.workflow/.loop/${loopId}.json
|
||||
- Output: ${projectRoot}/.workflow/.loop/${loopId}.workers/${action}.output.json
|
||||
- Progress: ${projectRoot}/.workflow/.loop/${loopId}.progress/${action}.md
|
||||
|
||||
Deliverables:
|
||||
- 按 WORKER_RESULT 格式输出
|
||||
@@ -374,7 +374,7 @@ function mergeWorkerOutputs(outputs) {
|
||||
2. **Progressive Phase Loading**: Read phase docs ONLY when that phase is about to execute
|
||||
3. **Parse Every Output**: Extract WORKER_RESULT from worker output for next decision
|
||||
4. **Worker 生命周期**: spawn → wait → [send_input if needed] → close,不长期保留 worker
|
||||
5. **结果持久化**: Worker 输出写入 `.workflow/.loop/{loopId}.workers/`
|
||||
5. **结果持久化**: Worker 输出写入 `{projectRoot}/.workflow/.loop/{loopId}.workers/`
|
||||
6. **状态同步**: 每次 worker 完成后更新 master state
|
||||
7. **超时处理**: send_input 请求收敛,再超时则使用已有结果继续
|
||||
8. **DO NOT STOP**: Continuous execution until completed, paused, or max iterations
|
||||
|
||||
@@ -12,6 +12,13 @@ Create or resume a development loop, initialize state file and directory structu
|
||||
|
||||
## Execution
|
||||
|
||||
### Step 0: Determine Project Root
|
||||
|
||||
```javascript
|
||||
// Step 0: Determine Project Root
|
||||
const projectRoot = Bash('git rev-parse --show-toplevel 2>/dev/null || pwd').trim()
|
||||
```
|
||||
|
||||
### Step 1.1: Parse Arguments
|
||||
|
||||
```javascript
|
||||
@@ -37,14 +44,14 @@ if (!validModes.includes(mode)) {
|
||||
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
|
||||
|
||||
function readState(loopId) {
|
||||
const stateFile = `.workflow/.loop/${loopId}.json`
|
||||
const stateFile = `${projectRoot}/.workflow/.loop/${loopId}.json`
|
||||
if (!fs.existsSync(stateFile)) return null
|
||||
return JSON.parse(Read(stateFile))
|
||||
}
|
||||
|
||||
function saveState(loopId, state) {
|
||||
state.updated_at = getUtc8ISOString()
|
||||
Write(`.workflow/.loop/${loopId}.json`, JSON.stringify(state, null, 2))
|
||||
Write(`${projectRoot}/.workflow/.loop/${loopId}.json`, JSON.stringify(state, null, 2))
|
||||
}
|
||||
```
|
||||
|
||||
@@ -63,8 +70,8 @@ console.log(`Creating new loop: ${loopId}`)
|
||||
#### Create Directory Structure
|
||||
|
||||
```bash
|
||||
mkdir -p .workflow/.loop/${loopId}.workers
|
||||
mkdir -p .workflow/.loop/${loopId}.progress
|
||||
mkdir -p ${projectRoot}/.workflow/.loop/${loopId}.workers
|
||||
mkdir -p ${projectRoot}/.workflow/.loop/${loopId}.progress
|
||||
```
|
||||
|
||||
#### Initialize State File
|
||||
@@ -95,7 +102,7 @@ function createState(loopId, taskDescription, mode) {
|
||||
}
|
||||
}
|
||||
|
||||
Write(`.workflow/.loop/${loopId}.json`, JSON.stringify(state, null, 2))
|
||||
Write(`${projectRoot}/.workflow/.loop/${loopId}.json`, JSON.stringify(state, null, 2))
|
||||
return state
|
||||
}
|
||||
```
|
||||
@@ -146,8 +153,8 @@ function checkControlSignals(loopId) {
|
||||
|
||||
- **Variable**: `loopId` - Unique loop identifier
|
||||
- **Variable**: `state` - Initialized or resumed loop state object
|
||||
- **Variable**: `progressDir` - `.workflow/.loop/${loopId}.progress`
|
||||
- **Variable**: `workersDir` - `.workflow/.loop/${loopId}.workers`
|
||||
- **Variable**: `progressDir` - `${projectRoot}/.workflow/.loop/${loopId}.progress`
|
||||
- **Variable**: `workersDir` - `${projectRoot}/.workflow/.loop/${loopId}.workers`
|
||||
- **Variable**: `mode` - `'interactive'` / `'auto'` / `'parallel'`
|
||||
- **TodoWrite**: Mark Phase 1 completed, Phase 2 in_progress
|
||||
|
||||
|
||||
@@ -227,8 +227,8 @@ function buildWorkerPrompt(action, loopId, state) {
|
||||
|
||||
### MANDATORY FIRST STEPS (Agent Execute)
|
||||
1. **Read role definition**: ${roleFiles[action]} (MUST read first)
|
||||
2. Read: .workflow/project-tech.json
|
||||
3. Read: .workflow/project-guidelines.json
|
||||
2. Read: ${projectRoot}/.workflow/project-tech.json
|
||||
3. Read: ${projectRoot}/.workflow/project-guidelines.json
|
||||
|
||||
---
|
||||
|
||||
@@ -242,9 +242,9 @@ Scope:
|
||||
Context:
|
||||
- Loop ID: ${loopId}
|
||||
- Action: ${action}
|
||||
- State File: .workflow/.loop/${loopId}.json
|
||||
- Output File: .workflow/.loop/${loopId}.workers/${action}.output.json
|
||||
- Progress File: .workflow/.loop/${loopId}.progress/${action}.md
|
||||
- State File: ${projectRoot}/.workflow/.loop/${loopId}.json
|
||||
- Output File: ${projectRoot}/.workflow/.loop/${loopId}.workers/${action}.output.json
|
||||
- Progress File: ${projectRoot}/.workflow/.loop/${loopId}.progress/${action}.md
|
||||
|
||||
Deliverables:
|
||||
- WORKER_RESULT 格式输出
|
||||
@@ -432,7 +432,7 @@ async function showMenuAndGetChoice(state) {
|
||||
|
||||
```javascript
|
||||
function persistWorkerOutput(loopId, action, workerResult) {
|
||||
const outputPath = `.workflow/.loop/${loopId}.workers/${action}.output.json`
|
||||
const outputPath = `${projectRoot}/.workflow/.loop/${loopId}.workers/${action}.output.json`
|
||||
Write(outputPath, JSON.stringify({
|
||||
...workerResult,
|
||||
timestamp: getUtc8ISOString()
|
||||
|
||||
@@ -14,7 +14,7 @@ Read state -> Select mode -> Spawn workers -> Wait results -> Merge -> Update st
|
||||
|
||||
```javascript
|
||||
function readState(loopId) {
|
||||
const stateFile = `.workflow/.loop/${loopId}.json`
|
||||
const stateFile = `${projectRoot}/.workflow/.loop/${loopId}.json`
|
||||
return fs.existsSync(stateFile)
|
||||
? JSON.parse(Read(stateFile))
|
||||
: null
|
||||
@@ -178,8 +178,8 @@ function buildWorkerPrompt(action, loopId, state) {
|
||||
|
||||
### MANDATORY FIRST STEPS
|
||||
1. **Read role definition**: ${roleFiles[action]}
|
||||
2. Read: .workflow/project-tech.json
|
||||
3. Read: .workflow/project-guidelines.json
|
||||
2. Read: ${projectRoot}/.workflow/project-tech.json
|
||||
3. Read: ${projectRoot}/.workflow/project-guidelines.json
|
||||
|
||||
---
|
||||
|
||||
@@ -252,6 +252,6 @@ function parseWorkerResult(output) {
|
||||
## Best Practices
|
||||
|
||||
1. **Worker 生命周期**: spawn → wait → close,不保留 worker
|
||||
2. **结果持久化**: Worker 输出写入 `.workflow/.loop/{loopId}.workers/`
|
||||
2. **结果持久化**: Worker 输出写入 `{projectRoot}/.workflow/.loop/{loopId}.workers/`
|
||||
3. **状态同步**: 每次 worker 完成后更新 state
|
||||
4. **超时处理**: send_input 请求收敛,再超时则跳过
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
## Worker Output Structure
|
||||
|
||||
Each worker writes to `.workflow/.loop/{loopId}.workers/{action}.output.json`:
|
||||
Each worker writes to `{projectRoot}/.workflow/.loop/{loopId}.workers/{action}.output.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -81,7 +81,7 @@ Each worker writes to `.workflow/.loop/{loopId}.workers/{action}.output.json`:
|
||||
|
||||
## Progress File Structure
|
||||
|
||||
Human-readable progress in `.workflow/.loop/{loopId}.progress/{action}.md`:
|
||||
Human-readable progress in `{projectRoot}/.workflow/.loop/{loopId}.progress/{action}.md`:
|
||||
|
||||
```markdown
|
||||
# Develop Progress
|
||||
@@ -165,7 +165,7 @@ When `mode === 'parallel'`:
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
.workflow/.loop/
|
||||
{projectRoot}/.workflow/.loop/
|
||||
+-- loop-b-20260122-abc123.json # Master state
|
||||
+-- loop-b-20260122-abc123.workers/
|
||||
| +-- init.output.json
|
||||
|
||||
@@ -29,8 +29,8 @@ Complete reference of worker actions and their capabilities.
|
||||
```
|
||||
|
||||
**Execution**:
|
||||
1. Read `.workflow/project-tech.json`
|
||||
2. Read `.workflow/project-guidelines.json`
|
||||
1. Read `{projectRoot}/.workflow/project-tech.json`
|
||||
2. Read `{projectRoot}/.workflow/project-guidelines.json`
|
||||
3. Parse task into phases
|
||||
4. Create task breakdown
|
||||
5. Generate execution plan
|
||||
|
||||
@@ -21,8 +21,8 @@ Session initialization worker. Parse requirements, create execution plan.
|
||||
```javascript
|
||||
// MANDATORY FIRST STEPS (already in prompt)
|
||||
// 1. Read role definition
|
||||
// 2. Read .workflow/project-tech.json
|
||||
// 3. Read .workflow/project-guidelines.json
|
||||
// 2. Read ${projectRoot}/.workflow/project-tech.json
|
||||
// 3. Read ${projectRoot}/.workflow/project-guidelines.json
|
||||
```
|
||||
|
||||
### Step 2: Analyze Task
|
||||
|
||||
Reference in New Issue
Block a user