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.
- package/.adspecs/feature.json +16 -16
- package/.adspecs/feature.yml +28 -28
- package/.adspecs/paths.json +17 -17
- 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
- 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
- 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
- package/.claude-plugin/marketplace.json +23 -23
- package/.claude-plugin/plugin.json +18 -18
- package/.qoder-plugin/plugin.json +31 -31
- package/CLAUDE.md +1 -5
- package/INSTALL.md +3 -3
- package/README.md +395 -395
- package/bin/adspecs.js +129 -129
- package/hooks/commit-queue.js +245 -245
- package/hooks/hooks.json +63 -63
- package/hooks/session-start.js +44 -44
- package/hooks/wiki-queue.js +127 -127
- package/package.json +61 -61
- package/references/ant6-front-standard/index.md +99 -99
- package/references/antd-front-demo/public/mockServiceWorker.js +361 -361
- package/references/ecp-end-standard/index.md +63 -63
- 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
- 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
- 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
- package/references/python-end-standard/04-Redis/344/275/277/347/224/250/350/247/204/350/214/203.md +231 -231
- package/scripts/postinstall.js +107 -107
- package/scripts/sync-version.js +105 -105
- package/skills/.claude/.wiki-update-queue +26 -26
- package/skills/adspecs-constitution/SKILL.md +157 -0
- package/skills/adspecs-export-word/SKILL.md +498 -498
- package/skills/adspecs-export-word/references/md-to-docx.js +862 -862
- package/skills/adspecs-export-word/references/package-lock.json +220 -220
- package/skills/adspecs-export-word/references/package.json +10 -10
- package/skills/adspecs-front-prototype/SKILL.md +405 -405
- package/skills/adspecs-front-spec/SKILL.md +4 -4
- package/skills/adspecs-front-tasks/SKILL.md +213 -173
- package/skills/adspecs-plan/SKILL.md +59 -69
- package/skills/adspecs-prd/SKILL.md +13 -5
- package/skills/adspecs-prd-to-demo/SKILL.md +532 -0
- package/skills/adspecs-tasks/SKILL.md +175 -204
- package/skills/adspecs-update-status/SKILL.md +382 -382
- package/skills/adspecs-utest/SKILL.md +107 -116
- package/skills/grill-me/SKILL.md +7 -0
- package/skills/grill-me/agents/openai.yaml +5 -0
- package/skills/playwright-cli/SKILL.md +420 -0
- package/skills/playwright-cli/references/element-attributes.md +23 -0
- package/skills/playwright-cli/references/playwright-tests.md +39 -0
- package/skills/playwright-cli/references/request-mocking.md +87 -0
- package/skills/playwright-cli/references/running-code.md +241 -0
- package/skills/playwright-cli/references/session-management.md +225 -0
- package/skills/playwright-cli/references/storage-state.md +275 -0
- package/skills/playwright-cli/references/test-generation.md +433 -0
- package/skills/playwright-cli/references/tracing.md +139 -0
- package/skills/playwright-cli/references/video-recording.md +143 -0
- package/skills/playwright-trace/SKILL.md +171 -0
- package/skills/project-init/SKILL.md +93 -22
- package/skills/project-init/references/front-demo/.claude/settings.local.json +9 -0
- package/skills/wiki-update/SKILL.md +232 -232
- package/src/commands/doctor.js +197 -197
- package/src/commands/init.js +83 -83
- package/src/commands/plugin.js +165 -165
- package/src/commands/update.js +87 -87
- package/src/lib/area-scanner.js +129 -129
- package/src/lib/copier.js +104 -104
- package/src/lib/dir-utils.js +161 -133
- package/src/lib/json-merge.js +114 -114
- package/src/lib/paths-defaults.js +37 -37
- package/src/lib/prompts.js +428 -347
- package/src/lib/readme-gen.js +143 -143
- package/src/lib/report.js +338 -327
- package/src/lib/scaffolder.js +551 -518
- package/src/lib/short-name.js +36 -36
- package/src/utils.js +80 -80
- package/references/antd-front-demo/.env +0 -15
package/src/lib/short-name.js
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* project_short_name 自动推导
|
|
5
|
-
*
|
|
6
|
-
* 规则(与 project-init SKILL.md 保持一致):
|
|
7
|
-
* 1. 从 project_name 中提取所有英文字母和数字(去除中文、空格、连字符、下划线等)
|
|
8
|
-
* 2. 转为小写
|
|
9
|
-
* 3. 如果结果为空(项目名称全中文),则从 project_dir 推导(去除连字符和下划线)
|
|
10
|
-
* 4. 如果仍为空,使用 'project' 作为默认值
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* 推导 project_short_name
|
|
15
|
-
* @param {string} projectName - 项目完整名称
|
|
16
|
-
* @param {string} projectDir - 项目目录名(可选)
|
|
17
|
-
* @returns {string} 仅包含英文字母和数字的小写短名称
|
|
18
|
-
*/
|
|
19
|
-
function deriveShortName(projectName, projectDir) {
|
|
20
|
-
// 1. 从 project_name 提取英文字母和数字
|
|
21
|
-
if (projectName) {
|
|
22
|
-
const fromName = projectName.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
|
|
23
|
-
if (fromName) return fromName;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// 2. 从 project_dir 推导(去除连字符和下划线)
|
|
27
|
-
if (projectDir) {
|
|
28
|
-
const fromDir = projectDir.replace(/[-_\s]/g, '').toLowerCase();
|
|
29
|
-
if (fromDir) return fromDir;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// 3. 默认值
|
|
33
|
-
return 'project';
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
module.exports = { deriveShortName };
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* project_short_name 自动推导
|
|
5
|
+
*
|
|
6
|
+
* 规则(与 project-init SKILL.md 保持一致):
|
|
7
|
+
* 1. 从 project_name 中提取所有英文字母和数字(去除中文、空格、连字符、下划线等)
|
|
8
|
+
* 2. 转为小写
|
|
9
|
+
* 3. 如果结果为空(项目名称全中文),则从 project_dir 推导(去除连字符和下划线)
|
|
10
|
+
* 4. 如果仍为空,使用 'project' 作为默认值
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 推导 project_short_name
|
|
15
|
+
* @param {string} projectName - 项目完整名称
|
|
16
|
+
* @param {string} projectDir - 项目目录名(可选)
|
|
17
|
+
* @returns {string} 仅包含英文字母和数字的小写短名称
|
|
18
|
+
*/
|
|
19
|
+
function deriveShortName(projectName, projectDir) {
|
|
20
|
+
// 1. 从 project_name 提取英文字母和数字
|
|
21
|
+
if (projectName) {
|
|
22
|
+
const fromName = projectName.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
|
|
23
|
+
if (fromName) return fromName;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// 2. 从 project_dir 推导(去除连字符和下划线)
|
|
27
|
+
if (projectDir) {
|
|
28
|
+
const fromDir = projectDir.replace(/[-_\s]/g, '').toLowerCase();
|
|
29
|
+
if (fromDir) return fromDir;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 3. 默认值
|
|
33
|
+
return 'project';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = { deriveShortName };
|
package/src/utils.js
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* adspecs CLI 通用工具
|
|
5
|
-
*
|
|
6
|
-
* 此模块作为 package.json 的 "main" 入口,
|
|
7
|
-
* 供其他 Node.js 脚本 require('adspecs') 时使用。
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const path = require('path');
|
|
11
|
-
const fs = require('fs');
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* 获取插件根目录(即 adspecs/ 目录)
|
|
15
|
-
* @returns {string}
|
|
16
|
-
*/
|
|
17
|
-
function getPluginDir() {
|
|
18
|
-
return path.resolve(__dirname, '..');
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* 获取 package.json 内容
|
|
23
|
-
* @returns {object}
|
|
24
|
-
*/
|
|
25
|
-
function getPkg() {
|
|
26
|
-
const pkgPath = path.join(getPluginDir(), 'package.json');
|
|
27
|
-
return JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* 获取版本号
|
|
32
|
-
* @returns {string}
|
|
33
|
-
*/
|
|
34
|
-
function getVersion() {
|
|
35
|
-
return getPkg().version;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* 判断目标路径是否在 adspecs 插件目录内
|
|
40
|
-
* @param {string} targetPath
|
|
41
|
-
* @returns {boolean}
|
|
42
|
-
*/
|
|
43
|
-
function isInsidePlugin(targetPath) {
|
|
44
|
-
const pluginDir = getPluginDir();
|
|
45
|
-
const resolved = path.resolve(targetPath);
|
|
46
|
-
return resolved.startsWith(pluginDir);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* 安全读取 JSON 文件
|
|
51
|
-
* @param {string} filePath
|
|
52
|
-
* @param {object} [fallback]
|
|
53
|
-
* @returns {object|null}
|
|
54
|
-
*/
|
|
55
|
-
function safeReadJson(filePath, fallback = null) {
|
|
56
|
-
try {
|
|
57
|
-
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
58
|
-
} catch {
|
|
59
|
-
return fallback;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* 安全写入 JSON 文件(带 2 空格缩进 + 尾部换行)
|
|
65
|
-
* @param {string} filePath
|
|
66
|
-
* @param {object} data
|
|
67
|
-
*/
|
|
68
|
-
function safeWriteJson(filePath, data) {
|
|
69
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
70
|
-
fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n', 'utf8');
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
module.exports = {
|
|
74
|
-
getPluginDir,
|
|
75
|
-
getPkg,
|
|
76
|
-
getVersion,
|
|
77
|
-
isInsidePlugin,
|
|
78
|
-
safeReadJson,
|
|
79
|
-
safeWriteJson,
|
|
80
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* adspecs CLI 通用工具
|
|
5
|
+
*
|
|
6
|
+
* 此模块作为 package.json 的 "main" 入口,
|
|
7
|
+
* 供其他 Node.js 脚本 require('adspecs') 时使用。
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 获取插件根目录(即 adspecs/ 目录)
|
|
15
|
+
* @returns {string}
|
|
16
|
+
*/
|
|
17
|
+
function getPluginDir() {
|
|
18
|
+
return path.resolve(__dirname, '..');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 获取 package.json 内容
|
|
23
|
+
* @returns {object}
|
|
24
|
+
*/
|
|
25
|
+
function getPkg() {
|
|
26
|
+
const pkgPath = path.join(getPluginDir(), 'package.json');
|
|
27
|
+
return JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 获取版本号
|
|
32
|
+
* @returns {string}
|
|
33
|
+
*/
|
|
34
|
+
function getVersion() {
|
|
35
|
+
return getPkg().version;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 判断目标路径是否在 adspecs 插件目录内
|
|
40
|
+
* @param {string} targetPath
|
|
41
|
+
* @returns {boolean}
|
|
42
|
+
*/
|
|
43
|
+
function isInsidePlugin(targetPath) {
|
|
44
|
+
const pluginDir = getPluginDir();
|
|
45
|
+
const resolved = path.resolve(targetPath);
|
|
46
|
+
return resolved.startsWith(pluginDir);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 安全读取 JSON 文件
|
|
51
|
+
* @param {string} filePath
|
|
52
|
+
* @param {object} [fallback]
|
|
53
|
+
* @returns {object|null}
|
|
54
|
+
*/
|
|
55
|
+
function safeReadJson(filePath, fallback = null) {
|
|
56
|
+
try {
|
|
57
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
58
|
+
} catch {
|
|
59
|
+
return fallback;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* 安全写入 JSON 文件(带 2 空格缩进 + 尾部换行)
|
|
65
|
+
* @param {string} filePath
|
|
66
|
+
* @param {object} data
|
|
67
|
+
*/
|
|
68
|
+
function safeWriteJson(filePath, data) {
|
|
69
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
70
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n', 'utf8');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = {
|
|
74
|
+
getPluginDir,
|
|
75
|
+
getPkg,
|
|
76
|
+
getVersion,
|
|
77
|
+
isInsidePlugin,
|
|
78
|
+
safeReadJson,
|
|
79
|
+
safeWriteJson,
|
|
80
|
+
};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# 应用标题
|
|
2
|
-
VITE_APP_TITLE=演示环境
|
|
3
|
-
VITE_APP_SIDEBAR_TITLE=演示环境
|
|
4
|
-
VITE_APP_BRAND_TITLE=演示环境
|
|
5
|
-
|
|
6
|
-
# 应用命名空间
|
|
7
|
-
VITE_APP_NAMESPACE=front-demo
|
|
8
|
-
|
|
9
|
-
# 请求路径
|
|
10
|
-
VITE_BASE_URL=
|
|
11
|
-
# 接口地址
|
|
12
|
-
VITE_API_BASE_URL=/admin-api
|
|
13
|
-
|
|
14
|
-
# 是否开启模拟数据(Demo 项目默认开启)
|
|
15
|
-
VITE_MOCK_ENABLED=true
|