adspecs 0.1.19 → 0.1.21

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 (74) hide show
  1. package/.adspecs/feature.json +16 -16
  2. package/.adspecs/feature.yml +28 -28
  3. package/.adspecs/paths.json +17 -17
  4. package/.adspecs/templates/04-/345/211/215/347/253/257/345/212/237/350/203/275/350/256/276/350/256/241/346/250/241/346/235/277.md +1 -1
  5. package/.adspecs/templates/05-/345/220/216/347/253/257/344/273/273/345/212/241/346/270/205/345/215/225/346/250/241/346/235/277.md +613 -724
  6. package/.adspecs/templates/05b-/345/211/215/347/253/257/344/273/273/345/212/241/346/270/205/345/215/225/346/250/241/346/235/277.md +51 -51
  7. package/.claude-plugin/marketplace.json +23 -23
  8. package/.claude-plugin/plugin.json +18 -18
  9. package/.qoder-plugin/plugin.json +31 -31
  10. package/CLAUDE.md +1 -5
  11. package/INSTALL.md +3 -3
  12. package/README.md +395 -395
  13. package/bin/adspecs.js +129 -129
  14. package/hooks/commit-queue.js +245 -245
  15. package/hooks/hooks.json +63 -63
  16. package/hooks/session-start.js +44 -44
  17. package/hooks/wiki-queue.js +127 -127
  18. package/package.json +61 -61
  19. package/references/ant6-front-standard/index.md +99 -99
  20. package/references/antd-front-demo/public/mockServiceWorker.js +361 -361
  21. package/references/ecp-end-standard/index.md +63 -63
  22. package/references/python-end-standard/01-Python/345/220/216/347/253/257/347/274/226/347/240/201/350/247/204/350/214/203.md +372 -372
  23. package/references/python-end-standard/02-/346/225/260/346/215/256/345/272/223/350/256/276/350/256/241/344/270/216/344/275/277/347/224/250/350/247/204/350/214/203.md +226 -226
  24. package/references/python-end-standard/03-Celery/345/274/202/346/255/245/344/273/273/345/212/241/350/247/204/350/214/203.md +237 -237
  25. package/references/python-end-standard/04-Redis/344/275/277/347/224/250/350/247/204/350/214/203.md +231 -231
  26. package/scripts/postinstall.js +107 -107
  27. package/scripts/sync-version.js +105 -105
  28. package/skills/.claude/.wiki-update-queue +26 -26
  29. package/skills/adspecs-constitution/SKILL.md +157 -0
  30. package/skills/adspecs-export-word/SKILL.md +498 -498
  31. package/skills/adspecs-export-word/references/md-to-docx.js +862 -862
  32. package/skills/adspecs-export-word/references/package-lock.json +220 -220
  33. package/skills/adspecs-export-word/references/package.json +10 -10
  34. package/skills/adspecs-front-prototype/SKILL.md +405 -405
  35. package/skills/adspecs-front-spec/SKILL.md +4 -4
  36. package/skills/adspecs-front-tasks/SKILL.md +213 -173
  37. package/skills/adspecs-plan/SKILL.md +59 -69
  38. package/skills/adspecs-prd/SKILL.md +13 -5
  39. package/skills/adspecs-prd-to-demo/SKILL.md +532 -0
  40. package/skills/adspecs-tasks/SKILL.md +175 -204
  41. package/skills/adspecs-update-status/SKILL.md +382 -382
  42. package/skills/adspecs-utest/SKILL.md +107 -116
  43. package/skills/grill-me/SKILL.md +7 -0
  44. package/skills/grill-me/agents/openai.yaml +5 -0
  45. package/skills/playwright-cli/SKILL.md +420 -0
  46. package/skills/playwright-cli/references/element-attributes.md +23 -0
  47. package/skills/playwright-cli/references/playwright-tests.md +39 -0
  48. package/skills/playwright-cli/references/request-mocking.md +87 -0
  49. package/skills/playwright-cli/references/running-code.md +241 -0
  50. package/skills/playwright-cli/references/session-management.md +225 -0
  51. package/skills/playwright-cli/references/storage-state.md +275 -0
  52. package/skills/playwright-cli/references/test-generation.md +433 -0
  53. package/skills/playwright-cli/references/tracing.md +139 -0
  54. package/skills/playwright-cli/references/video-recording.md +143 -0
  55. package/skills/playwright-trace/SKILL.md +171 -0
  56. package/skills/project-init/SKILL.md +93 -22
  57. package/skills/project-init/references/front-demo/.claude/settings.local.json +9 -0
  58. package/skills/wiki-update/SKILL.md +232 -232
  59. package/src/commands/doctor.js +197 -197
  60. package/src/commands/init.js +83 -83
  61. package/src/commands/plugin.js +165 -165
  62. package/src/commands/update.js +87 -87
  63. package/src/lib/area-scanner.js +129 -129
  64. package/src/lib/copier.js +104 -104
  65. package/src/lib/dir-utils.js +161 -133
  66. package/src/lib/json-merge.js +114 -114
  67. package/src/lib/paths-defaults.js +37 -37
  68. package/src/lib/prompts.js +428 -347
  69. package/src/lib/readme-gen.js +143 -143
  70. package/src/lib/report.js +338 -327
  71. package/src/lib/scaffolder.js +551 -518
  72. package/src/lib/short-name.js +36 -36
  73. package/src/utils.js +80 -80
  74. package/references/antd-front-demo/.env +0 -15
@@ -1,133 +1,161 @@
1
- 'use strict';
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
-
6
- /**
7
- * 目录检测工具
8
- *
9
- * 提供目录存在性、内容状态检测能力,支撑冲突决策和模式升级检测。
10
- */
11
-
12
- /**
13
- * 检查目录是否包含任何实际文件(递归,遇到第一个文件即返回 true)
14
- *
15
- * @param {string} dirPath - 目录绝对路径
16
- * @returns {boolean} 目录存在且包含至少一个文件
17
- */
18
- function hasAnyFile(dirPath) {
19
- if (!fs.existsSync(dirPath)) return false;
20
-
21
- let stat;
22
- try {
23
- stat = fs.statSync(dirPath);
24
- } catch {
25
- return false;
26
- }
27
- if (!stat.isDirectory()) return false;
28
-
29
- let entries;
30
- try {
31
- entries = fs.readdirSync(dirPath, { withFileTypes: true });
32
- } catch {
33
- return false;
34
- }
35
-
36
- for (const entry of entries) {
37
- const fullPath = path.join(dirPath, entry.name);
38
- if (entry.isFile()) {
39
- return true;
40
- }
41
- if (entry.isDirectory() && hasAnyFile(fullPath)) {
42
- return true;
43
- }
44
- }
45
-
46
- return false;
47
- }
48
-
49
- /**
50
- * 检查目录是否"仅有空子目录"(没有任何文件)
51
- *
52
- * 用于检测简易模式产物特征:40-project_conventions/ 下仅有空子目录结构
53
- * (frontend-standard/、end-standard/),没有实际文件。
54
- *
55
- * @param {string} dirPath - 目录绝对路径
56
- * @returns {boolean} 目录存在且所有子项都是空目录(即无任何文件)
57
- */
58
- function isEmptyDirectoryTree(dirPath) {
59
- if (!fs.existsSync(dirPath)) return false;
60
-
61
- let stat;
62
- try {
63
- stat = fs.statSync(dirPath);
64
- } catch {
65
- return false;
66
- }
67
- if (!stat.isDirectory()) return false;
68
-
69
- // 如果有任何文件 → 不是空目录树
70
- return !hasAnyFile(dirPath);
71
- }
72
-
73
- /**
74
- * 统计目录下的实际文件数量
75
- *
76
- * @param {string} dirPath - 目录绝对路径
77
- * @returns {number} 文件总数
78
- */
79
- function countFiles(dirPath) {
80
- if (!fs.existsSync(dirPath)) return 0;
81
-
82
- let stat;
83
- try {
84
- stat = fs.statSync(dirPath);
85
- } catch {
86
- return 0;
87
- }
88
- if (!stat.isDirectory()) return 0;
89
-
90
- let count = 0;
91
- let entries;
92
- try {
93
- entries = fs.readdirSync(dirPath, { withFileTypes: true });
94
- } catch {
95
- return 0;
96
- }
97
-
98
- for (const entry of entries) {
99
- const fullPath = path.join(dirPath, entry.name);
100
- if (entry.isFile()) {
101
- count++;
102
- } else if (entry.isDirectory()) {
103
- count += countFiles(fullPath);
104
- }
105
- }
106
- return count;
107
- }
108
-
109
- /**
110
- * 列出目录下的所有子目录名(不递归)
111
- *
112
- * @param {string} dirPath - 目录绝对路径
113
- * @returns {string[]} 子目录名列表
114
- */
115
- function listSubdirs(dirPath) {
116
- if (!fs.existsSync(dirPath)) return [];
117
-
118
- let entries;
119
- try {
120
- entries = fs.readdirSync(dirPath, { withFileTypes: true });
121
- } catch {
122
- return [];
123
- }
124
-
125
- return entries.filter((e) => e.isDirectory()).map((e) => e.name);
126
- }
127
-
128
- module.exports = {
129
- hasAnyFile,
130
- isEmptyDirectoryTree,
131
- countFiles,
132
- listSubdirs,
133
- };
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ /**
7
+ * 目录检测工具
8
+ *
9
+ * 提供目录存在性、内容状态检测能力,支撑冲突决策和模式升级检测。
10
+ */
11
+
12
+ /**
13
+ * 检查目录是否包含任何实际文件(递归,遇到第一个文件即返回 true)
14
+ *
15
+ * @param {string} dirPath - 目录绝对路径
16
+ * @returns {boolean} 目录存在且包含至少一个文件
17
+ */
18
+ function hasAnyFile(dirPath) {
19
+ if (!fs.existsSync(dirPath)) return false;
20
+
21
+ let stat;
22
+ try {
23
+ stat = fs.statSync(dirPath);
24
+ } catch {
25
+ return false;
26
+ }
27
+ if (!stat.isDirectory()) return false;
28
+
29
+ let entries;
30
+ try {
31
+ entries = fs.readdirSync(dirPath, { withFileTypes: true });
32
+ } catch {
33
+ return false;
34
+ }
35
+
36
+ for (const entry of entries) {
37
+ const fullPath = path.join(dirPath, entry.name);
38
+ if (entry.isFile()) {
39
+ return true;
40
+ }
41
+ if (entry.isDirectory() && hasAnyFile(fullPath)) {
42
+ return true;
43
+ }
44
+ }
45
+
46
+ return false;
47
+ }
48
+
49
+ /**
50
+ * 检查目录是否"仅有空子目录"(没有任何文件)
51
+ *
52
+ * 用于检测简易模式产物特征:40-project_conventions/ 下仅有空子目录结构
53
+ * (frontend-standard/、end-standard/),没有实际文件。
54
+ *
55
+ * @param {string} dirPath - 目录绝对路径
56
+ * @returns {boolean} 目录存在且所有子项都是空目录(即无任何文件)
57
+ */
58
+ function isEmptyDirectoryTree(dirPath) {
59
+ if (!fs.existsSync(dirPath)) return false;
60
+
61
+ let stat;
62
+ try {
63
+ stat = fs.statSync(dirPath);
64
+ } catch {
65
+ return false;
66
+ }
67
+ if (!stat.isDirectory()) return false;
68
+
69
+ // 如果有任何文件 → 不是空目录树
70
+ return !hasAnyFile(dirPath);
71
+ }
72
+
73
+ /**
74
+ * 统计目录下的实际文件数量
75
+ *
76
+ * @param {string} dirPath - 目录绝对路径
77
+ * @returns {number} 文件总数
78
+ */
79
+ function countFiles(dirPath) {
80
+ if (!fs.existsSync(dirPath)) return 0;
81
+
82
+ let stat;
83
+ try {
84
+ stat = fs.statSync(dirPath);
85
+ } catch {
86
+ return 0;
87
+ }
88
+ if (!stat.isDirectory()) return 0;
89
+
90
+ let count = 0;
91
+ let entries;
92
+ try {
93
+ entries = fs.readdirSync(dirPath, { withFileTypes: true });
94
+ } catch {
95
+ return 0;
96
+ }
97
+
98
+ for (const entry of entries) {
99
+ const fullPath = path.join(dirPath, entry.name);
100
+ if (entry.isFile()) {
101
+ count++;
102
+ } else if (entry.isDirectory()) {
103
+ count += countFiles(fullPath);
104
+ }
105
+ }
106
+ return count;
107
+ }
108
+
109
+ /**
110
+ * 列出目录下的所有子目录名(不递归)
111
+ *
112
+ * @param {string} dirPath - 目录绝对路径
113
+ * @returns {string[]} 子目录名列表
114
+ */
115
+ function listSubdirs(dirPath) {
116
+ if (!fs.existsSync(dirPath)) return [];
117
+
118
+ let entries;
119
+ try {
120
+ entries = fs.readdirSync(dirPath, { withFileTypes: true });
121
+ } catch {
122
+ return [];
123
+ }
124
+
125
+ return entries.filter((e) => e.isDirectory()).map((e) => e.name);
126
+ }
127
+
128
+ /**
129
+ * 列出目录下的所有文件名(不递归)
130
+ *
131
+ * @param {string} dirPath - 目录绝对路径
132
+ * @returns {string[]} 文件名列表
133
+ */
134
+ function listFiles(dirPath) {
135
+ if (!fs.existsSync(dirPath)) return [];
136
+
137
+ let stat;
138
+ try {
139
+ stat = fs.statSync(dirPath);
140
+ } catch {
141
+ return [];
142
+ }
143
+ if (!stat.isDirectory()) return [];
144
+
145
+ let entries;
146
+ try {
147
+ entries = fs.readdirSync(dirPath, { withFileTypes: true });
148
+ } catch {
149
+ return [];
150
+ }
151
+
152
+ return entries.filter((e) => e.isFile()).map((e) => e.name);
153
+ }
154
+
155
+ module.exports = {
156
+ hasAnyFile,
157
+ isEmptyDirectoryTree,
158
+ countFiles,
159
+ listSubdirs,
160
+ listFiles,
161
+ };
@@ -1,114 +1,114 @@
1
- 'use strict';
2
-
3
- const fs = require('fs');
4
-
5
- /**
6
- * JSON 属性补全工具
7
- *
8
- * 用于 feature.json / project.json 等配置文件的合并:
9
- * - 已有文件中缺失的 key → 从 references 补充(使用 references 的默认值)
10
- * - 已有文件中已存在的 key → 保留已有值,不覆盖
11
- * - 已有文件中额外的自定义 key → 保留,不删除
12
- */
13
-
14
- /**
15
- * 合并两个 JSON 对象的顶层属性
16
- *
17
- * @param {object} existing - 目标项目中的已有内容
18
- * @param {object} reference - 插件 references 中的初始模板
19
- * @returns {{ merged: object, addedKeys: string[] }} 合并后的对象 + 被补全的 key 列表
20
- */
21
- function mergeProperties(existing, reference) {
22
- const merged = { ...existing };
23
- const addedKeys = [];
24
-
25
- for (const key of Object.keys(reference)) {
26
- if (!(key in merged)) {
27
- merged[key] = reference[key];
28
- addedKeys.push(key);
29
- }
30
- }
31
-
32
- return { merged, addedKeys };
33
- }
34
-
35
- /**
36
- * 读取并合并 JSON 文件
37
- *
38
- * @param {string} targetPath - 目标项目中的 JSON 文件路径
39
- * @param {string} referencePath - 插件 references 中的 JSON 文件路径
40
- * @returns {{ merged: object, addedKeys: string[], created: boolean }} 合并结果
41
- */
42
- function mergeJsonFile(targetPath, referencePath) {
43
- const reference = JSON.parse(fs.readFileSync(referencePath, 'utf8'));
44
-
45
- if (!fs.existsSync(targetPath)) {
46
- // 文件不存在,直接用 references 内容创建
47
- fs.mkdirSync(require('path').dirname(targetPath), { recursive: true });
48
- fs.writeFileSync(targetPath, JSON.stringify(reference, null, 2) + '\n', 'utf8');
49
- return { merged: reference, addedKeys: Object.keys(reference), created: true };
50
- }
51
-
52
- const existing = JSON.parse(fs.readFileSync(targetPath, 'utf8'));
53
- const { merged, addedKeys } = mergeProperties(existing, reference);
54
-
55
- if (addedKeys.length > 0) {
56
- fs.writeFileSync(targetPath, JSON.stringify(merged, null, 2) + '\n', 'utf8');
57
- }
58
-
59
- return { merged, addedKeys, created: false };
60
- }
61
-
62
- /**
63
- * 合并 project.json 字段(特殊处理:已有字段用新值更新,缺失字段补默认值)
64
- *
65
- * 与 feature.json 的合并规则不同:
66
- * - project.json 中 project_name / company_name 等字段 → 用本次收集的最新值更新
67
- * - 已有文件中额外的自定义属性 → 保留不删除
68
- * - references 中有但已有文件中缺失的属性 → 补充默认值
69
- *
70
- * @param {string} targetPath - .adspecs/project.json 路径
71
- * @param {object} newValues - 本次收集的项目信息
72
- * @param {string} referencePath - 插件 references 中的 project.json 路径
73
- */
74
- function mergeProjectJson(targetPath, newValues, referencePath) {
75
- const reference = JSON.parse(fs.readFileSync(referencePath, 'utf8'));
76
- let existing = {};
77
-
78
- if (fs.existsSync(targetPath)) {
79
- existing = JSON.parse(fs.readFileSync(targetPath, 'utf8'));
80
- }
81
-
82
- // 1. 从 references 补充缺失的属性(使用默认值)
83
- const merged = { ...reference };
84
-
85
- // 2. 已有文件中额外的自定义属性 → 保留
86
- for (const key of Object.keys(existing)) {
87
- if (!(key in merged)) {
88
- merged[key] = existing[key];
89
- }
90
- }
91
-
92
- // 3. 本次收集的最新值覆盖(仅限已知字段)
93
- for (const [key, value] of Object.entries(newValues)) {
94
- if (value !== undefined && value !== null) {
95
- merged[key] = value;
96
- }
97
- }
98
-
99
- // 4. 添加创建时间
100
- if (!merged.created_at) {
101
- merged.created_at = new Date().toISOString().slice(0, 10);
102
- }
103
-
104
- fs.mkdirSync(require('path').dirname(targetPath), { recursive: true });
105
- fs.writeFileSync(targetPath, JSON.stringify(merged, null, 2) + '\n', 'utf8');
106
-
107
- return merged;
108
- }
109
-
110
- module.exports = {
111
- mergeProperties,
112
- mergeJsonFile,
113
- mergeProjectJson,
114
- };
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+
5
+ /**
6
+ * JSON 属性补全工具
7
+ *
8
+ * 用于 feature.json / project.json 等配置文件的合并:
9
+ * - 已有文件中缺失的 key → 从 references 补充(使用 references 的默认值)
10
+ * - 已有文件中已存在的 key → 保留已有值,不覆盖
11
+ * - 已有文件中额外的自定义 key → 保留,不删除
12
+ */
13
+
14
+ /**
15
+ * 合并两个 JSON 对象的顶层属性
16
+ *
17
+ * @param {object} existing - 目标项目中的已有内容
18
+ * @param {object} reference - 插件 references 中的初始模板
19
+ * @returns {{ merged: object, addedKeys: string[] }} 合并后的对象 + 被补全的 key 列表
20
+ */
21
+ function mergeProperties(existing, reference) {
22
+ const merged = { ...existing };
23
+ const addedKeys = [];
24
+
25
+ for (const key of Object.keys(reference)) {
26
+ if (!(key in merged)) {
27
+ merged[key] = reference[key];
28
+ addedKeys.push(key);
29
+ }
30
+ }
31
+
32
+ return { merged, addedKeys };
33
+ }
34
+
35
+ /**
36
+ * 读取并合并 JSON 文件
37
+ *
38
+ * @param {string} targetPath - 目标项目中的 JSON 文件路径
39
+ * @param {string} referencePath - 插件 references 中的 JSON 文件路径
40
+ * @returns {{ merged: object, addedKeys: string[], created: boolean }} 合并结果
41
+ */
42
+ function mergeJsonFile(targetPath, referencePath) {
43
+ const reference = JSON.parse(fs.readFileSync(referencePath, 'utf8'));
44
+
45
+ if (!fs.existsSync(targetPath)) {
46
+ // 文件不存在,直接用 references 内容创建
47
+ fs.mkdirSync(require('path').dirname(targetPath), { recursive: true });
48
+ fs.writeFileSync(targetPath, JSON.stringify(reference, null, 2) + '\n', 'utf8');
49
+ return { merged: reference, addedKeys: Object.keys(reference), created: true };
50
+ }
51
+
52
+ const existing = JSON.parse(fs.readFileSync(targetPath, 'utf8'));
53
+ const { merged, addedKeys } = mergeProperties(existing, reference);
54
+
55
+ if (addedKeys.length > 0) {
56
+ fs.writeFileSync(targetPath, JSON.stringify(merged, null, 2) + '\n', 'utf8');
57
+ }
58
+
59
+ return { merged, addedKeys, created: false };
60
+ }
61
+
62
+ /**
63
+ * 合并 project.json 字段(特殊处理:已有字段用新值更新,缺失字段补默认值)
64
+ *
65
+ * 与 feature.json 的合并规则不同:
66
+ * - project.json 中 project_name / company_name 等字段 → 用本次收集的最新值更新
67
+ * - 已有文件中额外的自定义属性 → 保留不删除
68
+ * - references 中有但已有文件中缺失的属性 → 补充默认值
69
+ *
70
+ * @param {string} targetPath - .adspecs/project.json 路径
71
+ * @param {object} newValues - 本次收集的项目信息
72
+ * @param {string} referencePath - 插件 references 中的 project.json 路径
73
+ */
74
+ function mergeProjectJson(targetPath, newValues, referencePath) {
75
+ const reference = JSON.parse(fs.readFileSync(referencePath, 'utf8'));
76
+ let existing = {};
77
+
78
+ if (fs.existsSync(targetPath)) {
79
+ existing = JSON.parse(fs.readFileSync(targetPath, 'utf8'));
80
+ }
81
+
82
+ // 1. 从 references 补充缺失的属性(使用默认值)
83
+ const merged = { ...reference };
84
+
85
+ // 2. 已有文件中额外的自定义属性 → 保留
86
+ for (const key of Object.keys(existing)) {
87
+ if (!(key in merged)) {
88
+ merged[key] = existing[key];
89
+ }
90
+ }
91
+
92
+ // 3. 本次收集的最新值覆盖(仅限已知字段)
93
+ for (const [key, value] of Object.entries(newValues)) {
94
+ if (value !== undefined && value !== null) {
95
+ merged[key] = value;
96
+ }
97
+ }
98
+
99
+ // 4. 添加创建时间
100
+ if (!merged.created_at) {
101
+ merged.created_at = new Date().toISOString().slice(0, 10);
102
+ }
103
+
104
+ fs.mkdirSync(require('path').dirname(targetPath), { recursive: true });
105
+ fs.writeFileSync(targetPath, JSON.stringify(merged, null, 2) + '\n', 'utf8');
106
+
107
+ return merged;
108
+ }
109
+
110
+ module.exports = {
111
+ mergeProperties,
112
+ mergeJsonFile,
113
+ mergeProjectJson,
114
+ };
@@ -1,37 +1,37 @@
1
- 'use strict';
2
-
3
- /**
4
- * .adspecs/paths.json 默认配置
5
- *
6
- * 各技能读取 paths.json 时,对缺失的 key 使用这些默认值。
7
- * 与各技能 SKILL.md 中的硬编码默认值保持一致。
8
- */
9
-
10
- const DEFAULT_PATHS = {
11
- biz_analysis_dir: 'docs/00-customer-requirements',
12
- architecture_dir: 'docs/10-architecture',
13
- research_output_dir: 'docs/02-prd',
14
- sow_dir: 'docs/05-sow',
15
- prd_dir: 'docs/20-prd',
16
- design_dir: 'docs/30-system-design',
17
- test_report_dir: 'docs/80-development',
18
- export_dir: 'docs/90-export',
19
- wiki_dir: 'wiki',
20
- };
21
-
22
- /**
23
- * 生成 paths.json 内容
24
- * @returns {object} 完整的 paths.json 对象
25
- */
26
- function generatePathsConfig() {
27
- return {
28
- $schema: 'adspecs plugin path configuration',
29
- version: 1,
30
- paths: { ...DEFAULT_PATHS },
31
- };
32
- }
33
-
34
- module.exports = {
35
- DEFAULT_PATHS,
36
- generatePathsConfig,
37
- };
1
+ 'use strict';
2
+
3
+ /**
4
+ * .adspecs/paths.json 默认配置
5
+ *
6
+ * 各技能读取 paths.json 时,对缺失的 key 使用这些默认值。
7
+ * 与各技能 SKILL.md 中的硬编码默认值保持一致。
8
+ */
9
+
10
+ const DEFAULT_PATHS = {
11
+ biz_analysis_dir: 'docs/00-customer-requirements',
12
+ architecture_dir: 'docs/10-architecture',
13
+ research_output_dir: 'docs/02-prd',
14
+ sow_dir: 'docs/05-sow',
15
+ prd_dir: 'docs/20-prd',
16
+ design_dir: 'docs/30-system-design',
17
+ test_report_dir: 'docs/80-development',
18
+ export_dir: 'docs/90-export',
19
+ wiki_dir: 'wiki',
20
+ };
21
+
22
+ /**
23
+ * 生成 paths.json 内容
24
+ * @returns {object} 完整的 paths.json 对象
25
+ */
26
+ function generatePathsConfig() {
27
+ return {
28
+ $schema: 'adspecs plugin path configuration',
29
+ version: 1,
30
+ paths: { ...DEFAULT_PATHS },
31
+ };
32
+ }
33
+
34
+ module.exports = {
35
+ DEFAULT_PATHS,
36
+ generatePathsConfig,
37
+ };