claude-code-workflow 6.0.5 → 6.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/action-planning-agent.md +1 -1
- package/.claude/agents/cli-execution-agent.md +269 -269
- package/.claude/agents/cli-explore-agent.md +182 -182
- package/.claude/agents/context-search-agent.md +582 -582
- package/.claude/agents/memory-bridge.md +93 -93
- package/.claude/commands/cli/cli-init.md +1 -1
- package/.claude/commands/memory/docs-full-cli.md +471 -471
- package/.claude/commands/memory/docs-related-cli.md +386 -386
- package/.claude/commands/memory/docs.md +615 -615
- package/.claude/commands/memory/load.md +1 -1
- package/.claude/commands/memory/update-full.md +332 -332
- package/.claude/commands/memory/update-related.md +5 -5
- package/.claude/commands/workflow/init.md +1 -1
- package/.claude/commands/workflow/lite-fix.md +621 -621
- package/.claude/commands/workflow/lite-plan.md +592 -592
- package/.claude/commands/workflow/tools/context-gather.md +434 -434
- package/.claude/commands/workflow/ui-design/generate.md +504 -504
- package/.claude/commands/workflow/ui-design/import-from-code.md +537 -537
- package/.claude/scripts/classify-folders.sh +4 -0
- package/.claude/scripts/convert_tokens_to_css.sh +4 -0
- package/.claude/scripts/detect_changed_modules.sh +5 -1
- package/.claude/scripts/discover-design-files.sh +87 -83
- package/.claude/scripts/generate_module_docs.sh +717 -713
- package/.claude/scripts/get_modules_by_depth.sh +5 -1
- package/.claude/scripts/ui-generate-preview.sh +4 -0
- package/.claude/scripts/ui-instantiate-prototypes.sh +4 -0
- package/.claude/scripts/update_module_claude.sh +4 -0
- package/.claude/skills/command-guide/index/all-commands.json +1 -12
- package/.claude/skills/command-guide/index/by-category.json +1 -12
- package/.claude/skills/command-guide/index/by-use-case.json +1 -12
- package/.claude/skills/command-guide/index/essential-commands.json +1 -12
- package/.claude/skills/command-guide/reference/agents/action-planning-agent.md +127 -71
- package/.claude/skills/command-guide/reference/agents/cli-execution-agent.md +269 -269
- package/.claude/skills/command-guide/reference/agents/cli-explore-agent.md +182 -182
- package/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md +18 -38
- package/.claude/skills/command-guide/reference/agents/context-search-agent.md +582 -577
- package/.claude/skills/command-guide/reference/agents/memory-bridge.md +93 -93
- package/.claude/skills/command-guide/reference/commands/cli/cli-init.md +1 -1
- package/.claude/skills/command-guide/reference/commands/memory/docs-full-cli.md +471 -471
- package/.claude/skills/command-guide/reference/commands/memory/docs-related-cli.md +386 -386
- package/.claude/skills/command-guide/reference/commands/memory/docs.md +615 -610
- package/.claude/skills/command-guide/reference/commands/memory/load.md +1 -1
- package/.claude/skills/command-guide/reference/commands/memory/update-full.md +332 -332
- package/.claude/skills/command-guide/reference/commands/memory/update-related.md +5 -5
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/artifacts.md +299 -451
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/auto-parallel.md +14 -37
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/synthesis.md +252 -350
- package/.claude/skills/command-guide/reference/commands/workflow/init.md +2 -2
- package/.claude/skills/command-guide/reference/commands/workflow/lite-execute.md +52 -0
- package/.claude/skills/command-guide/reference/commands/workflow/lite-fix.md +621 -602
- package/.claude/skills/command-guide/reference/commands/workflow/lite-plan.md +46 -36
- package/.claude/skills/command-guide/reference/commands/workflow/review-fix.md +18 -58
- package/.claude/skills/command-guide/reference/commands/workflow/review-module-cycle.md +22 -52
- package/.claude/skills/command-guide/reference/commands/workflow/review-session-cycle.md +19 -48
- package/.claude/skills/command-guide/reference/commands/workflow/session/start.md +25 -5
- package/.claude/skills/command-guide/reference/commands/workflow/tdd-plan.md +1 -1
- package/.claude/skills/command-guide/reference/commands/workflow/test-fix-gen.md +7 -7
- package/.claude/skills/command-guide/reference/commands/workflow/tools/context-gather.md +434 -434
- package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-agent.md +151 -11
- package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-tdd.md +4 -4
- package/.claude/skills/command-guide/reference/commands/workflow/tools/test-task-generate.md +1 -1
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/generate.md +504 -504
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/import-from-code.md +537 -537
- package/.claude/workflows/context-search-strategy.md +77 -77
- package/.claude/workflows/tool-strategy.md +90 -71
- package/.claude/workflows/workflow-architecture.md +1 -1
- package/README.md +285 -285
- package/ccw/src/cli.js +7 -0
- package/ccw/src/commands/tool.js +217 -0
- package/ccw/src/core/dashboard-generator.js +18 -3
- package/ccw/src/core/lite-scanner.js +35 -11
- package/ccw/src/core/server.js +531 -46
- package/ccw/src/templates/dashboard-css/01-base.css +161 -0
- package/ccw/src/templates/dashboard-css/02-session.css +726 -0
- package/ccw/src/templates/dashboard-css/03-tasks.css +512 -0
- package/ccw/src/templates/dashboard-css/04-lite-tasks.css +843 -0
- package/ccw/src/templates/dashboard-css/05-context.css +2206 -0
- package/ccw/src/templates/dashboard-css/06-cards.css +1570 -0
- package/ccw/src/templates/dashboard-css/07-managers.css +936 -0
- package/ccw/src/templates/dashboard-css/08-review.css +1266 -0
- package/ccw/src/templates/dashboard-css/09-explorer.css +1397 -0
- package/ccw/src/templates/dashboard-js/components/global-notifications.js +219 -0
- package/ccw/src/templates/dashboard-js/components/hook-manager.js +10 -0
- package/ccw/src/templates/dashboard-js/components/mcp-manager.js +11 -1
- package/ccw/src/templates/dashboard-js/components/navigation.js +11 -5
- package/ccw/src/templates/dashboard-js/components/tabs-context.js +20 -20
- package/ccw/src/templates/dashboard-js/components/tabs-other.js +11 -11
- package/ccw/src/templates/dashboard-js/components/theme.js +29 -1
- package/ccw/src/templates/dashboard-js/main.js +4 -0
- package/ccw/src/templates/dashboard-js/state.js +5 -0
- package/ccw/src/templates/dashboard-js/views/explorer.js +852 -0
- package/ccw/src/templates/dashboard-js/views/home.js +13 -9
- package/ccw/src/templates/dashboard-js/views/hook-manager.js +8 -5
- package/ccw/src/templates/dashboard-js/views/lite-tasks.js +21 -16
- package/ccw/src/templates/dashboard-js/views/mcp-manager.js +90 -19
- package/ccw/src/templates/dashboard-js/views/project-overview.js +15 -11
- package/ccw/src/templates/dashboard-js/views/review-session.js +3 -3
- package/ccw/src/templates/dashboard-js/views/session-detail.js +38 -28
- package/ccw/src/templates/dashboard.html +129 -28
- package/ccw/src/tools/classify-folders.js +204 -0
- package/ccw/src/tools/convert-tokens-to-css.js +250 -0
- package/ccw/src/tools/detect-changed-modules.js +288 -0
- package/ccw/src/tools/discover-design-files.js +134 -0
- package/ccw/src/tools/edit-file.js +266 -0
- package/ccw/src/tools/generate-module-docs.js +416 -0
- package/ccw/src/tools/get-modules-by-depth.js +308 -0
- package/ccw/src/tools/index.js +176 -0
- package/ccw/src/tools/ui-generate-preview.js +327 -0
- package/ccw/src/tools/ui-instantiate-prototypes.js +301 -0
- package/ccw/src/tools/update-module-claude.js +380 -0
- package/package.json +1 -1
- package/.claude/skills/command-guide/reference/commands/workflow/status.md +0 -352
- package/ccw/src/core/server.js.bak +0 -385
- package/ccw/src/core/server_original.bak +0 -385
- package/ccw/src/templates/dashboard.css +0 -8187
- package/ccw/src/templates/dashboard_tailwind.html +0 -42
- package/ccw/src/templates/dashboard_test.html +0 -37
- package/ccw/src/templates/tailwind-base.css +0 -212
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Command - Execute and manage CCW tools
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { listTools, executeTool, getTool, getAllToolSchemas } from '../tools/index.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* List all available tools
|
|
10
|
+
*/
|
|
11
|
+
async function listAction() {
|
|
12
|
+
const tools = listTools();
|
|
13
|
+
|
|
14
|
+
if (tools.length === 0) {
|
|
15
|
+
console.log(chalk.yellow('No tools registered'));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
console.log(chalk.bold.cyan('\nAvailable Tools:\n'));
|
|
20
|
+
|
|
21
|
+
for (const tool of tools) {
|
|
22
|
+
console.log(chalk.bold.white(` ${tool.name}`));
|
|
23
|
+
console.log(chalk.gray(` ${tool.description}`));
|
|
24
|
+
|
|
25
|
+
if (tool.parameters?.properties) {
|
|
26
|
+
const props = tool.parameters.properties;
|
|
27
|
+
const required = tool.parameters.required || [];
|
|
28
|
+
|
|
29
|
+
console.log(chalk.gray(' Parameters:'));
|
|
30
|
+
for (const [name, schema] of Object.entries(props)) {
|
|
31
|
+
const req = required.includes(name) ? chalk.red('*') : '';
|
|
32
|
+
const defaultVal = schema.default !== undefined ? chalk.gray(` (default: ${schema.default})`) : '';
|
|
33
|
+
console.log(chalk.gray(` - ${name}${req}: ${schema.description}${defaultVal}`));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
console.log();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Show tool schema in MCP-compatible JSON format
|
|
42
|
+
*/
|
|
43
|
+
async function schemaAction(options) {
|
|
44
|
+
const { name } = options;
|
|
45
|
+
|
|
46
|
+
if (name) {
|
|
47
|
+
const tool = getTool(name);
|
|
48
|
+
if (!tool) {
|
|
49
|
+
console.error(chalk.red(`Tool not found: ${name}`));
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const schema = {
|
|
54
|
+
name: tool.name,
|
|
55
|
+
description: tool.description,
|
|
56
|
+
inputSchema: {
|
|
57
|
+
type: 'object',
|
|
58
|
+
properties: tool.parameters?.properties || {},
|
|
59
|
+
required: tool.parameters?.required || []
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
console.log(JSON.stringify(schema, null, 2));
|
|
63
|
+
} else {
|
|
64
|
+
const schemas = getAllToolSchemas();
|
|
65
|
+
console.log(JSON.stringify({ tools: schemas }, null, 2));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Read from stdin if available
|
|
71
|
+
*/
|
|
72
|
+
async function readStdin() {
|
|
73
|
+
// Check if stdin is a TTY (interactive terminal)
|
|
74
|
+
if (process.stdin.isTTY) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return new Promise((resolve, reject) => {
|
|
79
|
+
let data = '';
|
|
80
|
+
|
|
81
|
+
process.stdin.setEncoding('utf8');
|
|
82
|
+
|
|
83
|
+
process.stdin.on('readable', () => {
|
|
84
|
+
let chunk;
|
|
85
|
+
while ((chunk = process.stdin.read()) !== null) {
|
|
86
|
+
data += chunk;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
process.stdin.on('end', () => {
|
|
91
|
+
resolve(data.trim() || null);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
process.stdin.on('error', (err) => {
|
|
95
|
+
reject(err);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Smart JSON parser with Windows path handling
|
|
102
|
+
*/
|
|
103
|
+
function parseJsonWithPathFix(jsonString) {
|
|
104
|
+
try {
|
|
105
|
+
// Try normal parse first
|
|
106
|
+
return JSON.parse(jsonString);
|
|
107
|
+
} catch (firstError) {
|
|
108
|
+
// If parsing fails, try to fix Windows paths
|
|
109
|
+
try {
|
|
110
|
+
// Pattern: "path": "X:\..." or "path":"X:\..."
|
|
111
|
+
const fixedJson = jsonString.replace(
|
|
112
|
+
/("(?:path|file|target|source|dest|destination)":\s*")([A-Za-z]:[^"]+)"/g,
|
|
113
|
+
(match, prefix, path) => {
|
|
114
|
+
// Convert backslashes to forward slashes (universal)
|
|
115
|
+
const fixedPath = path.replace(/\\/g, '/');
|
|
116
|
+
return `${prefix}${fixedPath}"`;
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
return JSON.parse(fixedJson);
|
|
121
|
+
} catch (secondError) {
|
|
122
|
+
// If still fails, throw original error with helpful message
|
|
123
|
+
const errorMsg = firstError.message;
|
|
124
|
+
const hint = errorMsg.includes('escaped character') || errorMsg.includes('position')
|
|
125
|
+
? '\n\n' + chalk.yellow('Hint: Windows paths in JSON need forward slashes or double backslashes:') +
|
|
126
|
+
'\n ' + chalk.green('✓ "D:/Claude_dms3/file.md"') +
|
|
127
|
+
'\n ' + chalk.green('✓ "D:\\\\Claude_dms3\\\\file.md"') +
|
|
128
|
+
'\n ' + chalk.red('✗ "D:\\Claude_dms3\\file.md"')
|
|
129
|
+
: '';
|
|
130
|
+
|
|
131
|
+
throw new Error(errorMsg + hint);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Execute a tool with given parameters
|
|
138
|
+
*/
|
|
139
|
+
async function execAction(toolName, jsonInput, options) {
|
|
140
|
+
if (!toolName) {
|
|
141
|
+
console.error(chalk.red('Tool name is required'));
|
|
142
|
+
console.error(chalk.gray('Usage: ccw tool exec <tool-name> \'{"param": "value"}\''));
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const tool = getTool(toolName);
|
|
147
|
+
if (!tool) {
|
|
148
|
+
console.error(chalk.red(`Tool not found: ${toolName}`));
|
|
149
|
+
console.error(chalk.gray('Use "ccw tool list" to see available tools'));
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Parse JSON input (default format)
|
|
154
|
+
let params = {};
|
|
155
|
+
|
|
156
|
+
if (jsonInput) {
|
|
157
|
+
try {
|
|
158
|
+
params = parseJsonWithPathFix(jsonInput);
|
|
159
|
+
} catch (error) {
|
|
160
|
+
console.error(chalk.red(`Invalid JSON: ${error.message}`));
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Check for stdin input (for piped commands)
|
|
166
|
+
const stdinData = await readStdin();
|
|
167
|
+
if (stdinData) {
|
|
168
|
+
// If tool has an 'input' parameter, use it
|
|
169
|
+
// Otherwise, try to parse stdin as JSON and merge with params
|
|
170
|
+
if (tool.parameters?.properties?.input) {
|
|
171
|
+
params.input = stdinData;
|
|
172
|
+
} else {
|
|
173
|
+
try {
|
|
174
|
+
const stdinJson = JSON.parse(stdinData);
|
|
175
|
+
params = { ...stdinJson, ...params };
|
|
176
|
+
} catch {
|
|
177
|
+
// If not JSON, store as 'input' anyway
|
|
178
|
+
params.input = stdinData;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Execute tool
|
|
184
|
+
const result = await executeTool(toolName, params);
|
|
185
|
+
|
|
186
|
+
// Always output JSON
|
|
187
|
+
console.log(JSON.stringify(result, null, 2));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Tool command entry point
|
|
192
|
+
*/
|
|
193
|
+
export async function toolCommand(subcommand, args, options) {
|
|
194
|
+
// Handle subcommands
|
|
195
|
+
switch (subcommand) {
|
|
196
|
+
case 'list':
|
|
197
|
+
await listAction();
|
|
198
|
+
break;
|
|
199
|
+
case 'schema':
|
|
200
|
+
await schemaAction({ name: args });
|
|
201
|
+
break;
|
|
202
|
+
case 'exec':
|
|
203
|
+
await execAction(args, options.json, options);
|
|
204
|
+
break;
|
|
205
|
+
default:
|
|
206
|
+
console.log(chalk.bold.cyan('\nCCW Tool System\n'));
|
|
207
|
+
console.log('Subcommands:');
|
|
208
|
+
console.log(chalk.gray(' list List all available tools'));
|
|
209
|
+
console.log(chalk.gray(' schema [name] Show tool schema (JSON)'));
|
|
210
|
+
console.log(chalk.gray(' exec <name> Execute a tool'));
|
|
211
|
+
console.log();
|
|
212
|
+
console.log('Examples:');
|
|
213
|
+
console.log(chalk.gray(' ccw tool list'));
|
|
214
|
+
console.log(chalk.gray(' ccw tool schema edit_file'));
|
|
215
|
+
console.log(chalk.gray(' ccw tool exec edit_file \'{"path":"file.txt","oldText":"old","newText":"new"}\''));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
@@ -8,10 +8,22 @@ const __dirname = dirname(__filename);
|
|
|
8
8
|
// Bundled template paths
|
|
9
9
|
const UNIFIED_TEMPLATE = join(__dirname, '../templates/dashboard.html');
|
|
10
10
|
const JS_FILE = join(__dirname, '../templates/dashboard.js');
|
|
11
|
-
const
|
|
11
|
+
const MODULE_CSS_DIR = join(__dirname, '../templates/dashboard-css');
|
|
12
12
|
const WORKFLOW_TEMPLATE = join(__dirname, '../templates/workflow-dashboard.html');
|
|
13
13
|
const REVIEW_TEMPLATE = join(__dirname, '../templates/review-cycle-dashboard.html');
|
|
14
14
|
|
|
15
|
+
// Modular CSS files in load order
|
|
16
|
+
const MODULE_CSS_FILES = [
|
|
17
|
+
'01-base.css',
|
|
18
|
+
'02-session.css',
|
|
19
|
+
'03-tasks.css',
|
|
20
|
+
'04-lite-tasks.css',
|
|
21
|
+
'05-context.css',
|
|
22
|
+
'06-cards.css',
|
|
23
|
+
'07-managers.css',
|
|
24
|
+
'08-review.css'
|
|
25
|
+
];
|
|
26
|
+
|
|
15
27
|
const MODULE_FILES = [
|
|
16
28
|
'utils.js',
|
|
17
29
|
'state.js',
|
|
@@ -63,8 +75,11 @@ export async function generateDashboard(data) {
|
|
|
63
75
|
function generateFromUnifiedTemplate(data) {
|
|
64
76
|
let html = readFileSync(UNIFIED_TEMPLATE, 'utf8');
|
|
65
77
|
|
|
66
|
-
// Read CSS
|
|
67
|
-
let cssContent =
|
|
78
|
+
// Read and concatenate modular CSS files in load order
|
|
79
|
+
let cssContent = MODULE_CSS_FILES.map(file => {
|
|
80
|
+
const filePath = join(MODULE_CSS_DIR, file);
|
|
81
|
+
return existsSync(filePath) ? readFileSync(filePath, 'utf8') : '';
|
|
82
|
+
}).join('\n\n');
|
|
68
83
|
|
|
69
84
|
// Read JS content
|
|
70
85
|
let jsContent = '';
|
|
@@ -54,20 +54,36 @@ function scanLiteDir(dir, type) {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
|
-
* Load plan.json from session directory
|
|
57
|
+
* Load plan.json or fix-plan.json from session directory
|
|
58
58
|
* @param {string} sessionPath - Session directory path
|
|
59
59
|
* @returns {Object|null} - Plan data or null
|
|
60
60
|
*/
|
|
61
61
|
function loadPlanJson(sessionPath) {
|
|
62
|
+
// Try fix-plan.json first (for lite-fix), then plan.json (for lite-plan)
|
|
63
|
+
const fixPlanPath = join(sessionPath, 'fix-plan.json');
|
|
62
64
|
const planPath = join(sessionPath, 'plan.json');
|
|
63
|
-
if (!existsSync(planPath)) return null;
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
// Try fix-plan.json first
|
|
67
|
+
if (existsSync(fixPlanPath)) {
|
|
68
|
+
try {
|
|
69
|
+
const content = readFileSync(fixPlanPath, 'utf8');
|
|
70
|
+
return JSON.parse(content);
|
|
71
|
+
} catch {
|
|
72
|
+
// Continue to try plan.json
|
|
73
|
+
}
|
|
70
74
|
}
|
|
75
|
+
|
|
76
|
+
// Fallback to plan.json
|
|
77
|
+
if (existsSync(planPath)) {
|
|
78
|
+
try {
|
|
79
|
+
const content = readFileSync(planPath, 'utf8');
|
|
80
|
+
return JSON.parse(content);
|
|
81
|
+
} catch {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return null;
|
|
71
87
|
}
|
|
72
88
|
|
|
73
89
|
/**
|
|
@@ -91,6 +107,7 @@ function loadTaskJsons(sessionPath) {
|
|
|
91
107
|
f.startsWith('IMPL-') ||
|
|
92
108
|
f.startsWith('TASK-') ||
|
|
93
109
|
f.startsWith('task-') ||
|
|
110
|
+
f.startsWith('diagnosis-') ||
|
|
94
111
|
/^T\d+\.json$/i.test(f)
|
|
95
112
|
))
|
|
96
113
|
.map(f => {
|
|
@@ -109,12 +126,18 @@ function loadTaskJsons(sessionPath) {
|
|
|
109
126
|
}
|
|
110
127
|
}
|
|
111
128
|
|
|
112
|
-
// Method 2: Check plan.json for embedded tasks array
|
|
129
|
+
// Method 2: Check plan.json or fix-plan.json for embedded tasks array
|
|
113
130
|
if (tasks.length === 0) {
|
|
131
|
+
// Try fix-plan.json first (for lite-fix), then plan.json (for lite-plan)
|
|
132
|
+
const fixPlanPath = join(sessionPath, 'fix-plan.json');
|
|
114
133
|
const planPath = join(sessionPath, 'plan.json');
|
|
115
|
-
|
|
134
|
+
|
|
135
|
+
const planFile = existsSync(fixPlanPath) ? fixPlanPath :
|
|
136
|
+
existsSync(planPath) ? planPath : null;
|
|
137
|
+
|
|
138
|
+
if (planFile) {
|
|
116
139
|
try {
|
|
117
|
-
const plan = JSON.parse(readFileSync(
|
|
140
|
+
const plan = JSON.parse(readFileSync(planFile, 'utf8'));
|
|
118
141
|
if (Array.isArray(plan.tasks)) {
|
|
119
142
|
tasks = plan.tasks.map(t => normalizeTask(t));
|
|
120
143
|
}
|
|
@@ -124,13 +147,14 @@ function loadTaskJsons(sessionPath) {
|
|
|
124
147
|
}
|
|
125
148
|
}
|
|
126
149
|
|
|
127
|
-
// Method 3: Check for task-*.json files in session root
|
|
150
|
+
// Method 3: Check for task-*.json and diagnosis-*.json files in session root
|
|
128
151
|
if (tasks.length === 0) {
|
|
129
152
|
try {
|
|
130
153
|
const rootTasks = readdirSync(sessionPath)
|
|
131
154
|
.filter(f => f.endsWith('.json') && (
|
|
132
155
|
f.startsWith('task-') ||
|
|
133
156
|
f.startsWith('TASK-') ||
|
|
157
|
+
f.startsWith('diagnosis-') ||
|
|
134
158
|
/^T\d+\.json$/i.test(f)
|
|
135
159
|
))
|
|
136
160
|
.map(f => {
|