claude-coder 1.9.2 → 1.10.0

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.
Files changed (81) hide show
  1. package/README.md +236 -214
  2. package/bin/cli.js +170 -155
  3. package/package.json +55 -55
  4. package/recipes/_shared/roles/developer.md +11 -11
  5. package/recipes/_shared/roles/product.md +12 -12
  6. package/recipes/_shared/roles/tester.md +12 -12
  7. package/recipes/_shared/test/report-format.md +86 -86
  8. package/recipes/backend/base.md +27 -27
  9. package/recipes/backend/components/auth.md +18 -18
  10. package/recipes/backend/components/crud-api.md +18 -18
  11. package/recipes/backend/components/file-service.md +15 -15
  12. package/recipes/backend/manifest.json +20 -20
  13. package/recipes/backend/test/api-test.md +25 -25
  14. package/recipes/console/base.md +37 -37
  15. package/recipes/console/components/modal-form.md +20 -20
  16. package/recipes/console/components/pagination.md +17 -17
  17. package/recipes/console/components/search.md +17 -17
  18. package/recipes/console/components/table-list.md +18 -18
  19. package/recipes/console/components/tabs.md +14 -14
  20. package/recipes/console/components/tree.md +15 -15
  21. package/recipes/console/components/upload.md +15 -15
  22. package/recipes/console/manifest.json +24 -24
  23. package/recipes/console/test/crud-e2e.md +47 -47
  24. package/recipes/h5/base.md +26 -26
  25. package/recipes/h5/components/animation.md +11 -11
  26. package/recipes/h5/components/countdown.md +11 -11
  27. package/recipes/h5/components/share.md +11 -11
  28. package/recipes/h5/components/swiper.md +11 -11
  29. package/recipes/h5/manifest.json +21 -21
  30. package/recipes/h5/test/h5-e2e.md +20 -20
  31. package/src/commands/auth.js +420 -420
  32. package/src/commands/setup-modules/helpers.js +100 -100
  33. package/src/commands/setup-modules/index.js +25 -25
  34. package/src/commands/setup-modules/mcp.js +115 -115
  35. package/src/commands/setup-modules/provider.js +260 -260
  36. package/src/commands/setup-modules/safety.js +47 -47
  37. package/src/commands/setup-modules/simplify.js +52 -52
  38. package/src/commands/setup.js +172 -172
  39. package/src/common/assets.js +259 -245
  40. package/src/common/config.js +147 -125
  41. package/src/common/constants.js +55 -55
  42. package/src/common/indicator.js +260 -260
  43. package/src/common/interaction.js +170 -170
  44. package/src/common/logging.js +77 -77
  45. package/src/common/sdk.js +48 -50
  46. package/src/common/tasks.js +88 -88
  47. package/src/common/utils.js +214 -213
  48. package/src/core/coding.js +35 -33
  49. package/src/core/design.js +268 -0
  50. package/src/core/go.js +264 -264
  51. package/src/core/hooks.js +514 -500
  52. package/src/core/init.js +175 -166
  53. package/src/core/plan.js +194 -188
  54. package/src/core/prompts.js +292 -247
  55. package/src/core/repair.js +36 -36
  56. package/src/core/runner.js +471 -471
  57. package/src/core/scan.js +94 -93
  58. package/src/core/session.js +294 -280
  59. package/src/core/simplify.js +76 -74
  60. package/src/core/state.js +120 -105
  61. package/src/index.js +80 -76
  62. package/templates/{codingSystem.md → coding/system.md} +65 -65
  63. package/templates/{codingUser.md → coding/user.md} +18 -17
  64. package/templates/design/base.md +103 -0
  65. package/templates/design/fixSystem.md +71 -0
  66. package/templates/design/fixUser.md +3 -0
  67. package/templates/design/init.md +304 -0
  68. package/templates/design/system.md +108 -0
  69. package/templates/design/user.md +11 -0
  70. package/templates/{goSystem.md → go/system.md} +130 -130
  71. package/templates/{bash-process.md → other/bash-process.md} +12 -12
  72. package/templates/{coreProtocol.md → other/coreProtocol.md} +30 -29
  73. package/templates/{guidance.json → other/guidance.json} +72 -72
  74. package/templates/{requirements.example.md → other/requirements.example.md} +57 -57
  75. package/templates/{test_rule.md → other/test_rule.md} +192 -194
  76. package/templates/{web-testing.md → other/web-testing.md} +17 -17
  77. package/templates/{planSystem.md → plan/system.md} +78 -78
  78. package/templates/{planUser.md → plan/user.md} +10 -9
  79. package/templates/{scanSystem.md → scan/system.md} +120 -120
  80. package/templates/{scanUser.md → scan/user.md} +10 -10
  81. package/types/index.d.ts +217 -217
package/src/core/scan.js CHANGED
@@ -1,93 +1,94 @@
1
- 'use strict';
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const { log } = require('../common/config');
6
- const { assets } = require('../common/assets');
7
- const { buildSystemPrompt, buildScanPrompt } = require('./prompts');
8
- const { Session } = require('./session');
9
- const { RETRY } = require('../common/constants');
10
-
11
- function hasCodeFiles(projectRoot) {
12
- const markers = [
13
- 'package.json', 'pyproject.toml', 'requirements.txt', 'setup.py',
14
- 'Cargo.toml', 'go.mod', 'pom.xml', 'build.gradle',
15
- 'Makefile', 'Dockerfile', 'docker-compose.yml',
16
- 'README.md', 'main.py', 'app.py', 'index.js', 'index.ts',
17
- ];
18
- for (const m of markers) {
19
- if (fs.existsSync(path.join(projectRoot, m))) return true;
20
- }
21
- for (const d of ['src', 'lib', 'app', 'backend', 'frontend', 'web', 'server', 'client']) {
22
- if (fs.existsSync(path.join(projectRoot, d)) && fs.statSync(path.join(projectRoot, d)).isDirectory()) return true;
23
- }
24
- return false;
25
- }
26
-
27
- function validateProfile() {
28
- if (!assets.exists('profile')) return { valid: false, issues: ['profile 不存在'] };
29
-
30
- const profile = assets.readJson('profile', null);
31
- if (!profile) return { valid: false, issues: ['profile 解析失败'] };
32
- const issues = [];
33
-
34
- if (!profile.tech_stack?.backend?.framework && !profile.tech_stack?.frontend?.framework) {
35
- issues.push('tech_stack 缺少 backend 或 frontend 框架');
36
- }
37
- if (profile.tech_stack?.backend?.framework && (!profile.services || profile.services.length === 0)) {
38
- issues.push('有后端框架但 services 为空(缺少启动命令和端口)');
39
- }
40
- if (!profile.existing_docs || profile.existing_docs.length === 0) {
41
- issues.push('existing_docs 为空(至少需要 README.md)');
42
- }
43
-
44
- return { valid: issues.length === 0, issues };
45
- }
46
-
47
- async function executeScan(config, opts = {}) {
48
- const maxAttempts = RETRY.SCAN_ATTEMPTS;
49
-
50
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
51
- log('info', `初始化尝试 ${attempt} / ${maxAttempts} ...`);
52
-
53
- const projectType = hasCodeFiles(opts.projectRoot || assets.projectRoot) ? 'existing' : 'new';
54
- const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, '');
55
-
56
- const result = await Session.run('scan', config, {
57
- logFileName: `scan_${dateStr}.log`,
58
- label: `scan (${projectType})`,
59
-
60
- async execute(session) {
61
- log('info', `正在调用 Claude Code 执行项目扫描(${projectType}项目)...`);
62
-
63
- const prompt = buildScanPrompt(projectType);
64
- const queryOpts = session.buildQueryOptions(opts);
65
- queryOpts.systemPrompt = buildSystemPrompt('scan');
66
-
67
- const { cost } = await session.runQuery(prompt, queryOpts);
68
- return { cost };
69
- },
70
- });
71
-
72
- if (assets.exists('profile')) {
73
- const profileCheck = validateProfile();
74
- if (!profileCheck.valid) {
75
- log('warn', `profile 质量问题: ${profileCheck.issues.join('; ')}`);
76
- }
77
- log('ok', '项目扫描完成');
78
- return { success: true, cost: result.cost };
79
- }
80
-
81
- if (attempt < maxAttempts) {
82
- log('warn', '初始化未完成,将重试...');
83
- }
84
- }
85
-
86
- log('error', `初始化失败:已重试 ${maxAttempts} 次,关键文件仍未生成`);
87
- return { success: false, cost: null };
88
- }
89
-
90
- module.exports = {
91
- executeScan,
92
- validateProfile,
93
- };
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { log, printModeBanner } = require('../common/config');
6
+ const { assets } = require('../common/assets');
7
+ const { buildSystemPrompt, buildScanPrompt } = require('./prompts');
8
+ const { Session } = require('./session');
9
+ const { RETRY } = require('../common/constants');
10
+
11
+ function hasCodeFiles(projectRoot) {
12
+ const markers = [
13
+ 'package.json', 'pyproject.toml', 'requirements.txt', 'setup.py',
14
+ 'Cargo.toml', 'go.mod', 'pom.xml', 'build.gradle',
15
+ 'Makefile', 'Dockerfile', 'docker-compose.yml',
16
+ 'README.md', 'main.py', 'app.py', 'index.js', 'index.ts',
17
+ ];
18
+ for (const m of markers) {
19
+ if (fs.existsSync(path.join(projectRoot, m))) return true;
20
+ }
21
+ for (const d of ['src', 'lib', 'app', 'backend', 'frontend', 'web', 'server', 'client']) {
22
+ if (fs.existsSync(path.join(projectRoot, d)) && fs.statSync(path.join(projectRoot, d)).isDirectory()) return true;
23
+ }
24
+ return false;
25
+ }
26
+
27
+ function validateProfile() {
28
+ if (!assets.exists('profile')) return { valid: false, issues: ['profile 不存在'] };
29
+
30
+ const profile = assets.readJson('profile', null);
31
+ if (!profile) return { valid: false, issues: ['profile 解析失败'] };
32
+ const issues = [];
33
+
34
+ if (!profile.tech_stack?.backend?.framework && !profile.tech_stack?.frontend?.framework) {
35
+ issues.push('tech_stack 缺少 backend 或 frontend 框架');
36
+ }
37
+ if (profile.tech_stack?.backend?.framework && (!profile.services || profile.services.length === 0)) {
38
+ issues.push('有后端框架但 services 为空(缺少启动命令和端口)');
39
+ }
40
+ if (!profile.existing_docs || profile.existing_docs.length === 0) {
41
+ issues.push('existing_docs 为空(至少需要 README.md)');
42
+ }
43
+
44
+ return { valid: issues.length === 0, issues };
45
+ }
46
+
47
+ async function executeScan(config, opts = {}) {
48
+ const maxAttempts = RETRY.SCAN_ATTEMPTS;
49
+
50
+ const projectType = hasCodeFiles(opts.projectRoot || assets.projectRoot) ? 'existing' : 'new';
51
+ printModeBanner('scan', projectType === 'existing' ? '已有项目' : '全新项目', config?.model);
52
+
53
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
54
+ log('info', `初始化尝试 ${attempt} / ${maxAttempts} ...`);
55
+ const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, '');
56
+
57
+ const result = await Session.run('scan', config, {
58
+ logFileName: `scan_${dateStr}.log`,
59
+ label: `scan (${projectType})`,
60
+
61
+ async execute(session) {
62
+ log('info', `正在调用 Claude Code 执行项目扫描(${projectType}项目)...`);
63
+
64
+ const prompt = buildScanPrompt(projectType);
65
+ const queryOpts = session.buildQueryOptions(opts);
66
+ queryOpts.systemPrompt = buildSystemPrompt('scan');
67
+
68
+ const { cost } = await session.runQuery(prompt, queryOpts);
69
+ return { cost };
70
+ },
71
+ });
72
+
73
+ if (assets.exists('profile')) {
74
+ const profileCheck = validateProfile();
75
+ if (!profileCheck.valid) {
76
+ log('warn', `profile 质量问题: ${profileCheck.issues.join('; ')}`);
77
+ }
78
+ log('ok', '项目扫描完成');
79
+ return { success: true, cost: result.cost };
80
+ }
81
+
82
+ if (attempt < maxAttempts) {
83
+ log('warn', '初始化未完成,将重试...');
84
+ }
85
+ }
86
+
87
+ log('error', `初始化失败:已重试 ${maxAttempts} 次,关键文件仍未生成`);
88
+ return { success: false, cost: null };
89
+ }
90
+
91
+ module.exports = {
92
+ executeScan,
93
+ validateProfile,
94
+ };