claude-coder 1.10.0 → 1.10.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/README.md +239 -236
- package/bin/cli.js +170 -170
- package/package.json +55 -55
- package/recipes/_shared/roles/developer.md +11 -11
- package/recipes/_shared/roles/product.md +12 -12
- package/recipes/_shared/roles/tester.md +12 -12
- package/recipes/_shared/test/report-format.md +86 -86
- package/recipes/backend/base.md +27 -27
- package/recipes/backend/components/auth.md +18 -18
- package/recipes/backend/components/crud-api.md +18 -18
- package/recipes/backend/components/file-service.md +15 -15
- package/recipes/backend/manifest.json +20 -20
- package/recipes/backend/test/api-test.md +25 -25
- package/recipes/console/base.md +37 -37
- package/recipes/console/components/modal-form.md +20 -20
- package/recipes/console/components/pagination.md +17 -17
- package/recipes/console/components/search.md +17 -17
- package/recipes/console/components/table-list.md +18 -18
- package/recipes/console/components/tabs.md +14 -14
- package/recipes/console/components/tree.md +15 -15
- package/recipes/console/components/upload.md +15 -15
- package/recipes/console/manifest.json +24 -24
- package/recipes/console/test/crud-e2e.md +47 -47
- package/recipes/h5/base.md +26 -26
- package/recipes/h5/components/animation.md +11 -11
- package/recipes/h5/components/countdown.md +11 -11
- package/recipes/h5/components/share.md +11 -11
- package/recipes/h5/components/swiper.md +11 -11
- package/recipes/h5/manifest.json +21 -21
- package/recipes/h5/test/h5-e2e.md +20 -20
- package/src/commands/auth.js +420 -420
- package/src/commands/setup-modules/helpers.js +100 -100
- package/src/commands/setup-modules/index.js +25 -25
- package/src/commands/setup-modules/mcp.js +115 -115
- package/src/commands/setup-modules/provider.js +260 -260
- package/src/commands/setup-modules/safety.js +47 -47
- package/src/commands/setup-modules/simplify.js +52 -52
- package/src/commands/setup.js +172 -172
- package/src/common/assets.js +259 -259
- package/src/common/config.js +147 -147
- package/src/common/constants.js +55 -55
- package/src/common/indicator.js +260 -260
- package/src/common/interaction.js +170 -170
- package/src/common/logging.js +77 -77
- package/src/common/sdk.js +48 -48
- package/src/common/tasks.js +88 -88
- package/src/common/utils.js +215 -214
- package/src/core/coding.js +35 -35
- package/src/core/design.js +268 -268
- package/src/core/go.js +264 -264
- package/src/core/hooks.js +514 -514
- package/src/core/init.js +175 -175
- package/src/core/plan.js +194 -194
- package/src/core/prompts.js +292 -292
- package/src/core/repair.js +36 -36
- package/src/core/runner.js +438 -471
- package/src/core/scan.js +94 -94
- package/src/core/session.js +294 -294
- package/src/core/simplify.js +76 -76
- package/src/core/state.js +120 -120
- package/src/index.js +80 -80
- package/templates/coding/system.md +65 -65
- package/templates/coding/user.md +18 -18
- package/templates/design/base.md +103 -103
- package/templates/design/fixSystem.md +71 -71
- package/templates/design/fixUser.md +3 -3
- package/templates/design/init.md +304 -304
- package/templates/design/system.md +108 -108
- package/templates/design/user.md +11 -11
- package/templates/go/system.md +130 -130
- package/templates/other/bash-process.md +12 -12
- package/templates/other/coreProtocol.md +30 -30
- package/templates/other/guidance.json +72 -72
- package/templates/other/requirements.example.md +57 -57
- package/templates/other/test_rule.md +192 -192
- package/templates/other/web-testing.md +17 -17
- package/templates/plan/system.md +78 -78
- package/templates/plan/user.md +9 -9
- package/templates/scan/system.md +120 -120
- package/templates/scan/user.md +10 -10
- package/types/index.d.ts +217 -217
package/src/core/simplify.js
CHANGED
|
@@ -1,76 +1,76 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { log, printModeBanner } = require('../common/config');
|
|
4
|
-
const { assets } = require('../common/assets');
|
|
5
|
-
const { Session } = require('./session');
|
|
6
|
-
const { execSync } = require('child_process');
|
|
7
|
-
|
|
8
|
-
const AUTO_COMMIT_MSG = 'style: auto simplify';
|
|
9
|
-
|
|
10
|
-
function getSmartDiffRange(projectRoot, fallbackN) {
|
|
11
|
-
try {
|
|
12
|
-
const hash = execSync(
|
|
13
|
-
`git log --grep='${AUTO_COMMIT_MSG}' -1 --format='%H'`,
|
|
14
|
-
{ cwd: projectRoot, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] },
|
|
15
|
-
).trim();
|
|
16
|
-
if (hash) return { range: `${hash}..HEAD`, label: `自上次 auto simplify 以来` };
|
|
17
|
-
} catch { /* ignore */ }
|
|
18
|
-
return { range: `HEAD~${fallbackN}..HEAD`, label: `最近 ${fallbackN} 个 commit` };
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function commitIfDirty(projectRoot) {
|
|
22
|
-
try {
|
|
23
|
-
execSync('git diff --quiet HEAD', { cwd: projectRoot, stdio: 'pipe' });
|
|
24
|
-
} catch {
|
|
25
|
-
execSync(`git add -A && git commit -m "${AUTO_COMMIT_MSG}"`, { cwd: projectRoot, stdio: 'pipe' });
|
|
26
|
-
log('ok', `代码优化已提交: ${AUTO_COMMIT_MSG}`);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async function executeSimplify(config, focus = null, opts = {}) {
|
|
31
|
-
const n = opts.n || 3;
|
|
32
|
-
const projectRoot = assets.projectRoot;
|
|
33
|
-
|
|
34
|
-
const { range, label } = getSmartDiffRange(projectRoot, n);
|
|
35
|
-
|
|
36
|
-
printModeBanner('simplify', label, config?.model);
|
|
37
|
-
|
|
38
|
-
let diff = '';
|
|
39
|
-
try {
|
|
40
|
-
diff = execSync(`git diff ${range}`, { cwd: projectRoot, encoding: 'utf8', maxBuffer: 50 * 1024 * 1024 });
|
|
41
|
-
} catch (err) {
|
|
42
|
-
log('warn', `无法获取 diff (${label}): ${err.message}`);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (!diff.trim()) {
|
|
46
|
-
log('info', `无变更需要审查 (${label})`);
|
|
47
|
-
return { success: true };
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const focusLine = focus ? `\n审查聚焦方向:${focus}` : '';
|
|
51
|
-
const prompt = `/simplify\n\n审查范围:${label}${focusLine}\n\n${diff.slice(0, 50000)}`;
|
|
52
|
-
const dateStr = new Date().toISOString().replace(/[-:T]/g, '').slice(0, 12);
|
|
53
|
-
|
|
54
|
-
const result = await Session.run('simplify', config, {
|
|
55
|
-
logFileName: `simplify_${dateStr}.log`,
|
|
56
|
-
label: 'simplify',
|
|
57
|
-
|
|
58
|
-
async execute(session) {
|
|
59
|
-
log('info', `正在审查代码变更 (${label})...`);
|
|
60
|
-
|
|
61
|
-
const queryOpts = session.buildQueryOptions(opts);
|
|
62
|
-
queryOpts.disallowedTools = ['askUserQuestion'];
|
|
63
|
-
|
|
64
|
-
await session.runQuery(prompt, queryOpts, { continue: true });
|
|
65
|
-
log('ok', '代码审查完成');
|
|
66
|
-
|
|
67
|
-
return {};
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
commitIfDirty(projectRoot);
|
|
72
|
-
|
|
73
|
-
return result;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
module.exports = { executeSimplify };
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { log, printModeBanner } = require('../common/config');
|
|
4
|
+
const { assets } = require('../common/assets');
|
|
5
|
+
const { Session } = require('./session');
|
|
6
|
+
const { execSync } = require('child_process');
|
|
7
|
+
|
|
8
|
+
const AUTO_COMMIT_MSG = 'style: auto simplify';
|
|
9
|
+
|
|
10
|
+
function getSmartDiffRange(projectRoot, fallbackN) {
|
|
11
|
+
try {
|
|
12
|
+
const hash = execSync(
|
|
13
|
+
`git log --grep='${AUTO_COMMIT_MSG}' -1 --format='%H'`,
|
|
14
|
+
{ cwd: projectRoot, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] },
|
|
15
|
+
).trim();
|
|
16
|
+
if (hash) return { range: `${hash}..HEAD`, label: `自上次 auto simplify 以来` };
|
|
17
|
+
} catch { /* ignore */ }
|
|
18
|
+
return { range: `HEAD~${fallbackN}..HEAD`, label: `最近 ${fallbackN} 个 commit` };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function commitIfDirty(projectRoot) {
|
|
22
|
+
try {
|
|
23
|
+
execSync('git diff --quiet HEAD', { cwd: projectRoot, stdio: 'pipe' });
|
|
24
|
+
} catch {
|
|
25
|
+
execSync(`git add -A && git commit -m "${AUTO_COMMIT_MSG}"`, { cwd: projectRoot, stdio: 'pipe' });
|
|
26
|
+
log('ok', `代码优化已提交: ${AUTO_COMMIT_MSG}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function executeSimplify(config, focus = null, opts = {}) {
|
|
31
|
+
const n = opts.n || 3;
|
|
32
|
+
const projectRoot = assets.projectRoot;
|
|
33
|
+
|
|
34
|
+
const { range, label } = getSmartDiffRange(projectRoot, n);
|
|
35
|
+
|
|
36
|
+
printModeBanner('simplify', label, config?.model);
|
|
37
|
+
|
|
38
|
+
let diff = '';
|
|
39
|
+
try {
|
|
40
|
+
diff = execSync(`git diff ${range}`, { cwd: projectRoot, encoding: 'utf8', maxBuffer: 50 * 1024 * 1024 });
|
|
41
|
+
} catch (err) {
|
|
42
|
+
log('warn', `无法获取 diff (${label}): ${err.message}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!diff.trim()) {
|
|
46
|
+
log('info', `无变更需要审查 (${label})`);
|
|
47
|
+
return { success: true };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const focusLine = focus ? `\n审查聚焦方向:${focus}` : '';
|
|
51
|
+
const prompt = `/simplify\n\n审查范围:${label}${focusLine}\n\n${diff.slice(0, 50000)}`;
|
|
52
|
+
const dateStr = new Date().toISOString().replace(/[-:T]/g, '').slice(0, 12);
|
|
53
|
+
|
|
54
|
+
const result = await Session.run('simplify', config, {
|
|
55
|
+
logFileName: `simplify_${dateStr}.log`,
|
|
56
|
+
label: 'simplify',
|
|
57
|
+
|
|
58
|
+
async execute(session) {
|
|
59
|
+
log('info', `正在审查代码变更 (${label})...`);
|
|
60
|
+
|
|
61
|
+
const queryOpts = session.buildQueryOptions(opts);
|
|
62
|
+
queryOpts.disallowedTools = ['askUserQuestion'];
|
|
63
|
+
|
|
64
|
+
await session.runQuery(prompt, queryOpts, { continue: true });
|
|
65
|
+
log('ok', '代码审查完成');
|
|
66
|
+
|
|
67
|
+
return {};
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
commitIfDirty(projectRoot);
|
|
72
|
+
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = { executeSimplify };
|
package/src/core/state.js
CHANGED
|
@@ -1,120 +1,120 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { assets } = require('../common/assets');
|
|
4
|
-
const { getFeatures } = require('../common/tasks');
|
|
5
|
-
const { TASK_STATUSES } = require('../common/constants');
|
|
6
|
-
|
|
7
|
-
// ─── Harness State (harness_state.json) ───────────────────
|
|
8
|
-
|
|
9
|
-
const DEFAULT_STATE = Object.freeze({
|
|
10
|
-
version: 1,
|
|
11
|
-
next_task_id: 1,
|
|
12
|
-
next_priority: 1,
|
|
13
|
-
session_count: 0,
|
|
14
|
-
last_simplify_session: 0,
|
|
15
|
-
current_task_id: null,
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
function loadState() {
|
|
19
|
-
return assets.readJson('harnessState', { ...DEFAULT_STATE });
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function saveState(data) {
|
|
23
|
-
assets.writeJson('harnessState', data);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function extractIdNum(id) {
|
|
27
|
-
const m = String(id).match(/(\d+)$/);
|
|
28
|
-
return m ? parseInt(m[1], 10) : 0;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function syncAfterPlan() {
|
|
32
|
-
const state = loadState();
|
|
33
|
-
const tasks = assets.readJson('tasks', null);
|
|
34
|
-
if (!tasks || !tasks.features) return state;
|
|
35
|
-
|
|
36
|
-
const features = tasks.features;
|
|
37
|
-
state.next_task_id = features.reduce((max, f) => Math.max(max, extractIdNum(f.id)), 0) + 1;
|
|
38
|
-
state.next_priority = features.reduce((max, f) => Math.max(max, f.priority || 0), 0) + 1;
|
|
39
|
-
saveState(state);
|
|
40
|
-
return state;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// ─── Task Scheduling ──────────────────────────────────────
|
|
44
|
-
|
|
45
|
-
function selectNextTask(taskData) {
|
|
46
|
-
const features = getFeatures(taskData);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function isAllDone(taskData) {
|
|
69
|
-
const features = getFeatures(taskData);
|
|
70
|
-
return features.length > 0 && features.every(f => f.status === 'done');
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// ─── Progress & Counters ──────────────────────────────────
|
|
74
|
-
|
|
75
|
-
function appendProgress(entry) {
|
|
76
|
-
let progress = assets.readJson('progress', { sessions: [] });
|
|
77
|
-
if (!Array.isArray(progress.sessions)) progress.sessions = [];
|
|
78
|
-
progress.sessions.push(entry);
|
|
79
|
-
assets.writeJson('progress', progress);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function incrementSession() {
|
|
83
|
-
const state = loadState();
|
|
84
|
-
state.session_count++;
|
|
85
|
-
saveState(state);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function markSimplifyDone() {
|
|
89
|
-
const state = loadState();
|
|
90
|
-
state.last_simplify_session = state.session_count;
|
|
91
|
-
saveState(state);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// ─── Design State Helpers ─────────────────────────────────
|
|
95
|
-
|
|
96
|
-
function loadDesignState() {
|
|
97
|
-
const state = loadState();
|
|
98
|
-
return state.design || {};
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function saveDesignState(designData) {
|
|
102
|
-
const state = loadState();
|
|
103
|
-
state.design = { ...state.design, ...designData };
|
|
104
|
-
saveState(state);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
module.exports = {
|
|
108
|
-
DEFAULT_STATE,
|
|
109
|
-
loadState,
|
|
110
|
-
saveState,
|
|
111
|
-
syncAfterPlan,
|
|
112
|
-
selectNextTask,
|
|
113
|
-
isAllDone,
|
|
114
|
-
appendProgress,
|
|
115
|
-
incrementSession,
|
|
116
|
-
markSimplifyDone,
|
|
117
|
-
loadDesignState,
|
|
118
|
-
saveDesignState,
|
|
119
|
-
TASK_STATUSES,
|
|
120
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { assets } = require('../common/assets');
|
|
4
|
+
const { getFeatures } = require('../common/tasks');
|
|
5
|
+
const { TASK_STATUSES } = require('../common/constants');
|
|
6
|
+
|
|
7
|
+
// ─── Harness State (harness_state.json) ───────────────────
|
|
8
|
+
|
|
9
|
+
const DEFAULT_STATE = Object.freeze({
|
|
10
|
+
version: 1,
|
|
11
|
+
next_task_id: 1,
|
|
12
|
+
next_priority: 1,
|
|
13
|
+
session_count: 0,
|
|
14
|
+
last_simplify_session: 0,
|
|
15
|
+
current_task_id: null,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
function loadState() {
|
|
19
|
+
return assets.readJson('harnessState', { ...DEFAULT_STATE });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function saveState(data) {
|
|
23
|
+
assets.writeJson('harnessState', data);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function extractIdNum(id) {
|
|
27
|
+
const m = String(id).match(/(\d+)$/);
|
|
28
|
+
return m ? parseInt(m[1], 10) : 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function syncAfterPlan() {
|
|
32
|
+
const state = loadState();
|
|
33
|
+
const tasks = assets.readJson('tasks', null);
|
|
34
|
+
if (!tasks || !tasks.features) return state;
|
|
35
|
+
|
|
36
|
+
const features = tasks.features;
|
|
37
|
+
state.next_task_id = features.reduce((max, f) => Math.max(max, extractIdNum(f.id)), 0) + 1;
|
|
38
|
+
state.next_priority = features.reduce((max, f) => Math.max(max, f.priority || 0), 0) + 1;
|
|
39
|
+
saveState(state);
|
|
40
|
+
return state;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// ─── Task Scheduling ──────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
function selectNextTask(taskData) {
|
|
46
|
+
const features = getFeatures(taskData);
|
|
47
|
+
const byPriority = (a, b) => (a.priority || 999) - (b.priority || 999);
|
|
48
|
+
|
|
49
|
+
const pending = features.filter(f => f.status === 'pending')
|
|
50
|
+
.filter(f => {
|
|
51
|
+
const deps = f.depends_on || [];
|
|
52
|
+
return deps.every(depId => {
|
|
53
|
+
const dep = features.find(x => x.id === depId);
|
|
54
|
+
return dep && dep.status === 'done';
|
|
55
|
+
});
|
|
56
|
+
})
|
|
57
|
+
.sort(byPriority);
|
|
58
|
+
if (pending.length > 0) return pending[0];
|
|
59
|
+
|
|
60
|
+
const active = features.filter(f => f.status === 'in_progress' || f.status === 'testing')
|
|
61
|
+
.sort(byPriority);
|
|
62
|
+
if (active.length > 0) return active[0];
|
|
63
|
+
|
|
64
|
+
const failed = features.filter(f => f.status === 'failed').sort(byPriority);
|
|
65
|
+
return failed[0] || null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function isAllDone(taskData) {
|
|
69
|
+
const features = getFeatures(taskData);
|
|
70
|
+
return features.length > 0 && features.every(f => f.status === 'done');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ─── Progress & Counters ──────────────────────────────────
|
|
74
|
+
|
|
75
|
+
function appendProgress(entry) {
|
|
76
|
+
let progress = assets.readJson('progress', { sessions: [] });
|
|
77
|
+
if (!Array.isArray(progress.sessions)) progress.sessions = [];
|
|
78
|
+
progress.sessions.push(entry);
|
|
79
|
+
assets.writeJson('progress', progress);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function incrementSession() {
|
|
83
|
+
const state = loadState();
|
|
84
|
+
state.session_count++;
|
|
85
|
+
saveState(state);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function markSimplifyDone() {
|
|
89
|
+
const state = loadState();
|
|
90
|
+
state.last_simplify_session = state.session_count;
|
|
91
|
+
saveState(state);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ─── Design State Helpers ─────────────────────────────────
|
|
95
|
+
|
|
96
|
+
function loadDesignState() {
|
|
97
|
+
const state = loadState();
|
|
98
|
+
return state.design || {};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function saveDesignState(designData) {
|
|
102
|
+
const state = loadState();
|
|
103
|
+
state.design = { ...state.design, ...designData };
|
|
104
|
+
saveState(state);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
module.exports = {
|
|
108
|
+
DEFAULT_STATE,
|
|
109
|
+
loadState,
|
|
110
|
+
saveState,
|
|
111
|
+
syncAfterPlan,
|
|
112
|
+
selectNextTask,
|
|
113
|
+
isAllDone,
|
|
114
|
+
appendProgress,
|
|
115
|
+
incrementSession,
|
|
116
|
+
markSimplifyDone,
|
|
117
|
+
loadDesignState,
|
|
118
|
+
saveDesignState,
|
|
119
|
+
TASK_STATUSES,
|
|
120
|
+
};
|
package/src/index.js
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const { loadConfig, log } = require('./common/config');
|
|
6
|
-
const { assets } = require('./common/assets');
|
|
7
|
-
const { Session } = require('./core/session');
|
|
8
|
-
|
|
9
|
-
/** @typedef {{ max?: number, pause?: number, dryRun?: boolean, readFile?: string, model?: string, n?: number, planOnly?: boolean, interactive?: boolean, reset?: boolean, deployTemplates?: boolean, projectRoot?: string, reqFile?: string }} MainOpts */
|
|
10
|
-
|
|
11
|
-
function checkReady(command) {
|
|
12
|
-
if (['init', 'scan'].includes(command)) return;
|
|
13
|
-
|
|
14
|
-
if (!assets.exists('profile')) {
|
|
15
|
-
throw new Error('文件缺失: project_profile.json,请运行 claude-coder init 初始化项目');
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* 应用入口:初始化资产、加载配置、分发命令
|
|
21
|
-
* @param {string} command - 命令名称(init | scan | plan | run | go | simplify)
|
|
22
|
-
* @param {string} input - 位置参数(需求文本等)
|
|
23
|
-
* @param {MainOpts} [opts={}] - CLI 选项
|
|
24
|
-
* @returns {Promise<Object|void>}
|
|
25
|
-
*/
|
|
26
|
-
async function main(command, input, opts = {}) {
|
|
27
|
-
assets.init(opts.projectRoot || process.cwd());
|
|
28
|
-
assets.ensureDirs();
|
|
29
|
-
const config = loadConfig();
|
|
30
|
-
|
|
31
|
-
if (!opts.model) opts.model = config.defaultOpus || config.model;
|
|
32
|
-
|
|
33
|
-
if (opts.readFile) {
|
|
34
|
-
const reqPath = path.resolve(assets.projectRoot, opts.readFile);
|
|
35
|
-
if (!fs.existsSync(reqPath)) {
|
|
36
|
-
throw new Error(`文件不存在: ${reqPath}`);
|
|
37
|
-
}
|
|
38
|
-
opts.reqFile = reqPath;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
checkReady(command);
|
|
42
|
-
|
|
43
|
-
const displayModel = opts.model || '(default)';
|
|
44
|
-
log('ok', `模型: ${config.provider || 'claude'} (${displayModel}), 命令: ${command}`);
|
|
45
|
-
|
|
46
|
-
switch (command) {
|
|
47
|
-
case 'init': {
|
|
48
|
-
const { executeInit } = require('./core/init');
|
|
49
|
-
return executeInit(config, opts);
|
|
50
|
-
}
|
|
51
|
-
case 'scan': {
|
|
52
|
-
const { executeScan } = require('./core/scan');
|
|
53
|
-
return executeScan(config, opts);
|
|
54
|
-
}
|
|
55
|
-
case 'simplify': {
|
|
56
|
-
const { executeSimplify } = require('./core/simplify');
|
|
57
|
-
return executeSimplify(config, input, opts);
|
|
58
|
-
}
|
|
59
|
-
case 'plan': {
|
|
60
|
-
const { executePlan } = require('./core/plan');
|
|
61
|
-
return executePlan(config, input, opts);
|
|
62
|
-
}
|
|
63
|
-
case 'run': {
|
|
64
|
-
const { executeRun } = require('./core/runner');
|
|
65
|
-
return executeRun(config, opts);
|
|
66
|
-
}
|
|
67
|
-
case 'go': {
|
|
68
|
-
const { executeGo } = require('./core/go');
|
|
69
|
-
return executeGo(config, input, opts);
|
|
70
|
-
}
|
|
71
|
-
case 'design': {
|
|
72
|
-
const { executeDesign } = require('./core/design');
|
|
73
|
-
return executeDesign(config, input, opts);
|
|
74
|
-
}
|
|
75
|
-
default:
|
|
76
|
-
throw new Error(`未知命令: ${command}`);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
module.exports = { main, Session };
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { loadConfig, log } = require('./common/config');
|
|
6
|
+
const { assets } = require('./common/assets');
|
|
7
|
+
const { Session } = require('./core/session');
|
|
8
|
+
|
|
9
|
+
/** @typedef {{ max?: number, pause?: number, dryRun?: boolean, readFile?: string, model?: string, n?: number, planOnly?: boolean, interactive?: boolean, reset?: boolean, deployTemplates?: boolean, projectRoot?: string, reqFile?: string }} MainOpts */
|
|
10
|
+
|
|
11
|
+
function checkReady(command) {
|
|
12
|
+
if (['init', 'scan'].includes(command)) return;
|
|
13
|
+
|
|
14
|
+
if (!assets.exists('profile')) {
|
|
15
|
+
throw new Error('文件缺失: project_profile.json,请运行 claude-coder init 初始化项目');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 应用入口:初始化资产、加载配置、分发命令
|
|
21
|
+
* @param {string} command - 命令名称(init | scan | plan | run | go | simplify)
|
|
22
|
+
* @param {string} input - 位置参数(需求文本等)
|
|
23
|
+
* @param {MainOpts} [opts={}] - CLI 选项
|
|
24
|
+
* @returns {Promise<Object|void>}
|
|
25
|
+
*/
|
|
26
|
+
async function main(command, input, opts = {}) {
|
|
27
|
+
assets.init(opts.projectRoot || process.cwd());
|
|
28
|
+
assets.ensureDirs();
|
|
29
|
+
const config = loadConfig();
|
|
30
|
+
|
|
31
|
+
if (!opts.model) opts.model = config.defaultOpus || config.model;
|
|
32
|
+
|
|
33
|
+
if (opts.readFile) {
|
|
34
|
+
const reqPath = path.resolve(assets.projectRoot, opts.readFile);
|
|
35
|
+
if (!fs.existsSync(reqPath)) {
|
|
36
|
+
throw new Error(`文件不存在: ${reqPath}`);
|
|
37
|
+
}
|
|
38
|
+
opts.reqFile = reqPath;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
checkReady(command);
|
|
42
|
+
|
|
43
|
+
const displayModel = opts.model || '(default)';
|
|
44
|
+
log('ok', `模型: ${config.provider || 'claude'} (${displayModel}), 命令: ${command}`);
|
|
45
|
+
|
|
46
|
+
switch (command) {
|
|
47
|
+
case 'init': {
|
|
48
|
+
const { executeInit } = require('./core/init');
|
|
49
|
+
return executeInit(config, opts);
|
|
50
|
+
}
|
|
51
|
+
case 'scan': {
|
|
52
|
+
const { executeScan } = require('./core/scan');
|
|
53
|
+
return executeScan(config, opts);
|
|
54
|
+
}
|
|
55
|
+
case 'simplify': {
|
|
56
|
+
const { executeSimplify } = require('./core/simplify');
|
|
57
|
+
return executeSimplify(config, input, opts);
|
|
58
|
+
}
|
|
59
|
+
case 'plan': {
|
|
60
|
+
const { executePlan } = require('./core/plan');
|
|
61
|
+
return executePlan(config, input, opts);
|
|
62
|
+
}
|
|
63
|
+
case 'run': {
|
|
64
|
+
const { executeRun } = require('./core/runner');
|
|
65
|
+
return executeRun(config, opts);
|
|
66
|
+
}
|
|
67
|
+
case 'go': {
|
|
68
|
+
const { executeGo } = require('./core/go');
|
|
69
|
+
return executeGo(config, input, opts);
|
|
70
|
+
}
|
|
71
|
+
case 'design': {
|
|
72
|
+
const { executeDesign } = require('./core/design');
|
|
73
|
+
return executeDesign(config, input, opts);
|
|
74
|
+
}
|
|
75
|
+
default:
|
|
76
|
+
throw new Error(`未知命令: ${command}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
module.exports = { main, Session };
|