feat: update empty state messages and hints in English and Chinese locales

refactor: rename variables for clarity in ReviewSessionPage and SessionsPage

fix: update version check logic in SettingsPage

chore: remove unused imports in TeamPage and session-detail components

fix: enhance error handling in MCP server

fix: apply default mode in edit-file tool handler

chore: remove tsbuildinfo file

docs: add Quick Plan & Execute phase documentation for issue discovery

chore: clean up ping output file
This commit is contained in:
catlog22
2026-02-12 23:15:48 +08:00
parent fd6262b78b
commit e44a97e812
32 changed files with 912 additions and 1046 deletions

View File

@@ -21,7 +21,7 @@ Stateless iterative development loop using Codex single-agent deep interaction p
| loop-v2-routes.ts (Control Plane) |
| |
| State: {projectRoot}/.workflow/.loop/{loopId}.json (MASTER) |
| Tasks: {projectRoot}/.workflow/.loop/{loopId}.tasks.jsonl |
| Tasks: {projectRoot}/.workflow/.loop/{loopId}/.task/*.json |
| |
| /start -> Trigger ccw-loop skill with --loop-id |
| /pause -> Set status='paused' (skill checks before action) |
@@ -60,13 +60,13 @@ Stateless iterative development loop using Codex single-agent deep interaction p
## Prep Package Integration
When `prep-package.json` exists at `{projectRoot}/.workflow/.loop/prep-package.json`, Phase 1 consumes it to:
- Load pre-built task list from `prep-tasks.jsonl` instead of generating tasks from scratch
- Load pre-built task list from `.task/*.json` files instead of generating tasks from scratch
- Apply auto-loop config (max_iterations, timeout)
- Preserve source provenance and convergence criteria from upstream planning/analysis skills
Prep packages are generated by the interactive prompt `/prompts:prep-loop`, which accepts JSONL from:
- `collaborative-plan-with-file` (tasks.jsonl)
- `analyze-with-file` (tasks.jsonl)
- `collaborative-plan-with-file` (.task/*.json)
- `analyze-with-file` (.task/*.json)
- `brainstorm-to-cycle` (cycle-task.md → converted to task format)
See [phases/00-prep-checklist.md](phases/00-prep-checklist.md) for schema and validation rules.
@@ -151,7 +151,8 @@ close_agent → return finalState
```
{projectRoot}/.workflow/.loop/
├── {loopId}.json # Master state file (API + Skill shared)
├── {loopId}.tasks.jsonl # Task list (API managed)
├── {loopId}/.task/ # Task files directory (API managed)
│ └── TASK-{id}.json # Individual task files (task-schema.json)
└── {loopId}.progress/ # Skill progress files
├── develop.md # Development progress timeline
├── debug.md # Understanding evolution document

View File

@@ -20,7 +20,7 @@ Schema reference for `prep-package.json` consumed by ccw-loop Phase 1. Generated
"source": {
"tool": "collaborative-plan-with-file | analyze-with-file | brainstorm-to-cycle | manual",
"session_id": "string",
"jsonl_path": "absolute path to original JSONL",
"task_dir": "absolute path to source .task/ directory",
"task_count": "number",
"tasks_with_convergence": "number"
},
@@ -40,9 +40,9 @@ Schema reference for `prep-package.json` consumed by ccw-loop Phase 1. Generated
}
```
## prep-tasks.jsonl Schema
## .task/*.json Schema (task-schema.json)
One task per line, each in ccw-loop `develop.tasks[]` format with extended fields:
One task per file in `.task/` directory, each following `task-schema.json` with ccw-loop extended fields:
```json
{
@@ -71,8 +71,8 @@ One task per line, each in ccw-loop `develop.tasks[]` format with extended field
| 2 | target_skill | `=== "ccw-loop"` | Skip prep, use default INIT |
| 3 | project_root | Matches current `projectRoot` | Skip prep, warn mismatch |
| 4 | freshness | `generated_at` within 24h | Skip prep, warn stale |
| 5 | tasks file | `prep-tasks.jsonl` exists and readable | Skip prep, use default INIT |
| 6 | tasks content | At least 1 valid task line in JSONL | Skip prep, use default INIT |
| 5 | tasks dir | `.task/` directory exists with *.json files | Skip prep, use default INIT |
| 6 | tasks content | At least 1 valid task JSON in `.task/` | Skip prep, use default INIT |
## Integration Points
@@ -89,9 +89,9 @@ if (fs.existsSync(prepPath)) {
if (checks.valid) {
prepPackage = raw
// Load pre-built tasks from prep-tasks.jsonl
const tasksPath = `${projectRoot}/.workflow/.loop/prep-tasks.jsonl`
const prepTasks = loadPrepTasks(tasksPath)
// Load pre-built tasks from .task/*.json
const taskDir = `${projectRoot}/.workflow/.loop/.task`
const prepTasks = loadPrepTasks(taskDir)
// → Inject into state.skill_state.develop.tasks
// → Set max_iterations from auto_loop config
} else {

View File

@@ -46,14 +46,14 @@ if (fs.existsSync(prepPath)) {
prepPackage = raw
// Load pre-built tasks
const tasksPath = `${projectRoot}/.workflow/.loop/prep-tasks.jsonl`
prepTasks = loadPrepTasks(tasksPath)
const taskDir = `${projectRoot}/.workflow/.loop/.task`
prepTasks = loadPrepTasks(taskDir)
if (prepTasks && prepTasks.length > 0) {
console.log(`✓ Prep package loaded: ${prepTasks.length} tasks from ${prepPackage.source.tool}`)
console.log(` Checks passed: ${checks.passed.join(', ')}`)
} else {
console.warn(` Prep tasks file empty or invalid, falling back to default INIT`)
console.warn(`Warning: Prep tasks directory empty or invalid, falling back to default INIT`)
prepPackage = null
prepTasks = null
}
@@ -103,12 +103,13 @@ function validateLoopPrepPackage(prep, projectRoot) {
failures.push(`prep-package is ${Math.round(hoursSince)}h old (max 24h), may be stale`)
}
// Check 5: prep-tasks.jsonl must exist
const tasksPath = `${projectRoot}/.workflow/.loop/prep-tasks.jsonl`
if (fs.existsSync(tasksPath)) {
passed.push('prep-tasks.jsonl exists')
// Check 5: .task/ directory must exist with task files
const taskDir = `${projectRoot}/.workflow/.loop/.task`
const taskFiles = Glob(`${taskDir}/*.json`)
if (fs.existsSync(taskDir) && taskFiles.length > 0) {
passed.push(`.task/ exists (${taskFiles.length} files)`)
} else {
failures.push('prep-tasks.jsonl not found')
failures.push('.task/ directory not found or empty')
}
// Check 6: task count > 0
@@ -126,24 +127,24 @@ function validateLoopPrepPackage(prep, projectRoot) {
}
/**
* Load pre-built tasks from prep-tasks.jsonl.
* Load pre-built tasks from .task/*.json directory.
* Returns array of task objects or null on failure.
*/
function loadPrepTasks(tasksPath) {
if (!fs.existsSync(tasksPath)) return null
function loadPrepTasks(taskDir) {
if (!fs.existsSync(taskDir)) return null
const content = Read(tasksPath)
const lines = content.trim().split('\n').filter(l => l.trim())
const taskFiles = Glob(`${taskDir}/*.json`).sort()
const tasks = []
for (const line of lines) {
for (const filePath of taskFiles) {
try {
const task = JSON.parse(line)
const content = Read(filePath)
const task = JSON.parse(content)
if (task.id && task.description) {
tasks.push(task)
}
} catch (e) {
console.warn(` Skipping invalid task line: ${e.message}`)
console.warn(`Warning: Skipping invalid task file ${filePath}: ${e.message}`)
}
}