lcap-frontend-library 0.0.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 +271 -0
- package/bin/lcap-frontend-library.mjs +3 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +27 -0
- package/dist/init.d.ts +6 -0
- package/dist/init.js +79 -0
- package/dist/sync.d.ts +4 -0
- package/dist/sync.js +70 -0
- package/dist/utils.d.ts +19 -0
- package/dist/utils.js +101 -0
- package/package.json +34 -0
- package/packages/lcap-frontend-library/LEARNINGS.md +11 -0
- package/packages/lcap-frontend-library/SKILL.md +86 -0
- package/packages/lcap-frontend-library/commands/migrate.check.md +287 -0
- package/packages/lcap-frontend-library/commands/migrate.green.md +190 -0
- package/packages/lcap-frontend-library/commands/migrate.plan.md +169 -0
- package/packages/lcap-frontend-library/commands/migrate.red.md +160 -0
- package/packages/lcap-frontend-library/commands/migrate.scan.md +151 -0
- package/packages/lcap-frontend-library/commands/migrate.spec.md +144 -0
- package/packages/lcap-frontend-library/commands/migrate.tasks.md +179 -0
- package/packages/lcap-frontend-library/commands/speckit.create.md +201 -0
- package/packages/lcap-frontend-library/commands/speckit.implement.md +88 -0
- package/packages/lcap-frontend-library/commands/speckit.plan.md +79 -0
- package/packages/lcap-frontend-library/commands/speckit.self-check.md +177 -0
- package/packages/lcap-frontend-library/commands/speckit.specify.md +91 -0
- package/packages/lcap-frontend-library/commands/speckit.tasks.md +61 -0
- package/packages/lcap-frontend-library/references/frontend-design/LICENSE.txt +177 -0
- package/packages/lcap-frontend-library/references/frontend-design/SKILL.md +42 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/SKILL.md +360 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/api.md +331 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/block.md +160 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/i18n.md +95 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/icon.md +27 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/ide/container.md +728 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/ide/element.md +312 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/ide/expression.md +154 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/ide/index.md +113 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/ide/modal.md +189 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/ide/popover.md +171 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/ide.md +799 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/implementation-rules.md +242 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/index.md +27 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/nasl-view-component.md +895 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/accessibility.md +185 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/child.md +82 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/data-source.md +261 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/event.md +171 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/form.md +266 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/function.md +80 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/link.md +137 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/slot.md +128 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/theme-variables-ant-design.md +1470 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/theme-variables-cloud-ui.md +259 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/theme-variables-element-plus.md +580 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/theme-variables-element-ui.md +1007 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/theme-variables-mobile-ui.md +85 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/theme.md +234 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/workflow-guardrails.md +328 -0
- package/packages/lcap-frontend-library/references/nasl-logic-authoring/SKILL.md +201 -0
- package/packages/lcap-frontend-library/scripts/bash/create-component-files.sh +95 -0
- package/packages/lcap-frontend-library/scripts/bash/create-extension-project.sh +109 -0
- package/packages/lcap-frontend-library/scripts/bash/create-logic-files.sh +149 -0
- package/packages/lcap-frontend-library/scripts/bash/create-spec.sh +109 -0
- package/packages/lcap-frontend-library/scripts/bash/get-available-port.sh +35 -0
- package/packages/lcap-frontend-library/scripts/bash/list-specs.sh +19 -0
- package/packages/lcap-frontend-library/scripts/node/setup-extension-project.mjs +166 -0
- package/packages/lcap-frontend-library/templates/component-self-check.md +31 -0
- package/packages/lcap-frontend-library/templates/component-template.md +96 -0
- package/packages/lcap-frontend-library/templates/library-report-template.md +52 -0
- package/packages/lcap-frontend-library/templates/logic-template.md +44 -0
- package/packages/lcap-frontend-library/templates/migration-manifest-template.md +84 -0
- package/packages/lcap-frontend-library/templates/migration-plan-template.md +138 -0
- package/packages/lcap-frontend-library/templates/migration-report-template.md +227 -0
- package/packages/lcap-frontend-library/templates/migration-spec-template.md +135 -0
- package/packages/lcap-frontend-library/templates/migration-tasks-template.md +129 -0
- package/packages/lcap-frontend-library/templates/plan-template.md +299 -0
- package/packages/lcap-frontend-library/templates/self-check-report-template.md +148 -0
- package/packages/lcap-frontend-library/templates/tasks-template.md +81 -0
- package/packages/lcap-frontend-library/workflows/create/flow.md +199 -0
- package/packages/lcap-frontend-library/workflows/evolve/flow.md +249 -0
- package/packages/lcap-frontend-library/workflows/generate/flow.md +10 -0
- package/packages/lcap-frontend-library/workflows/harness/flow.md +82 -0
- package/packages/lcap-frontend-library/workflows/migrate/flow.md +302 -0
- package/packages/lcap-frontend-library/workflows/migrate/knowledge-base.md +564 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# 列出当前项目下的规范需求目录(Spec Driven Development)
|
|
3
|
+
# 用法: .specify/scripts/bash/list-specs.sh
|
|
4
|
+
|
|
5
|
+
current_dir=$(pwd)
|
|
6
|
+
specs_dir="${SPECS_DIR:-$current_dir/specs}"
|
|
7
|
+
|
|
8
|
+
if [ ! -d "$specs_dir" ]; then
|
|
9
|
+
echo "规范需求根目录不存在: $specs_dir"
|
|
10
|
+
echo "可通过环境变量 SPECS_DIR 指定,或先运行 create-spec.sh 创建首个需求目录。"
|
|
11
|
+
exit 0
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
echo "规范需求目录: $specs_dir"
|
|
15
|
+
echo "---"
|
|
16
|
+
for dir in "$specs_dir"/*; do
|
|
17
|
+
[ -d "$dir" ] || continue
|
|
18
|
+
echo " $(basename "$dir")"
|
|
19
|
+
done
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* 扩展依赖库工程初始化:合并 package.json(keywords、Vitest、Playwright devDeps)、
|
|
4
|
+
* 写入 playwright.config.ts、scripts/get-available-port.sh、e2e 目录、合并 .gitignore(Playwright 产物)、注入 Vitest exclude 配置。
|
|
5
|
+
* 用法: node setup-extension-project.mjs <项目根目录>
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, chmodSync } from 'node:fs';
|
|
8
|
+
import { join, dirname } from 'node:path';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
|
|
11
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
|
|
13
|
+
const projectDir = process.argv[2];
|
|
14
|
+
if (!projectDir) {
|
|
15
|
+
console.error('用法: node setup-extension-project.mjs <项目根目录>');
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function detectFramework(projectDirPath, pkg) {
|
|
20
|
+
const keywords = (pkg.keywords || []).map((k) => String(k).toLowerCase());
|
|
21
|
+
if (keywords.includes('react')) return 'react';
|
|
22
|
+
if (keywords.includes('vue3')) return 'vue3';
|
|
23
|
+
if (keywords.includes('vue')) return 'vue2';
|
|
24
|
+
|
|
25
|
+
for (const name of ['vite.config.mjs', 'vite.config.js']) {
|
|
26
|
+
const vitePath = join(projectDirPath, name);
|
|
27
|
+
if (!existsSync(vitePath)) continue;
|
|
28
|
+
const content = readFileSync(vitePath, 'utf8');
|
|
29
|
+
if (content.includes("framework: 'react'")) return 'react';
|
|
30
|
+
if (content.includes("framework: 'vue3'")) return 'vue3';
|
|
31
|
+
if (content.includes("framework: 'vue2'")) return 'vue2';
|
|
32
|
+
}
|
|
33
|
+
return 'vue3';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ─── 1. package.json ───────────────────────────────────────────────────────────
|
|
37
|
+
const pkgPath = join(projectDir, 'package.json');
|
|
38
|
+
const raw = readFileSync(pkgPath, 'utf8');
|
|
39
|
+
const pkg = JSON.parse(raw);
|
|
40
|
+
const framework = detectFramework(projectDir, pkg);
|
|
41
|
+
|
|
42
|
+
if (!Array.isArray(pkg.keywords)) pkg.keywords = [];
|
|
43
|
+
if (!pkg.keywords.includes('AIGC')) pkg.keywords.push('AIGC');
|
|
44
|
+
|
|
45
|
+
pkg.scripts = pkg.scripts && typeof pkg.scripts === 'object' ? pkg.scripts : {};
|
|
46
|
+
pkg.scripts.test = 'vitest run --silent';
|
|
47
|
+
pkg.scripts['test:e2e'] =
|
|
48
|
+
"HTTP_PROXY='' http_proxy='' HTTPS_PROXY='' https_proxy='' E2E_PORT=$(bash scripts/get-available-port.sh) playwright test";
|
|
49
|
+
|
|
50
|
+
pkg.devDependencies =
|
|
51
|
+
pkg.devDependencies && typeof pkg.devDependencies === 'object' ? pkg.devDependencies : {};
|
|
52
|
+
|
|
53
|
+
const ADD_DEV_DEPENDENCIES = {
|
|
54
|
+
'@playwright/test': '^1.58.2',
|
|
55
|
+
jsdom: '^29.0.0',
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
if (framework === 'vue3') {
|
|
59
|
+
ADD_DEV_DEPENDENCIES['@vue/test-utils'] = '^2.4.6';
|
|
60
|
+
} else if (framework === 'vue2') {
|
|
61
|
+
if (!pkg.devDependencies['@vue/test-utils']) {
|
|
62
|
+
ADD_DEV_DEPENDENCIES['@vue/test-utils'] = '^1.3.5';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
Object.entries(ADD_DEV_DEPENDENCIES).forEach(([name, version]) => {
|
|
67
|
+
if (!pkg.devDependencies[name]) {
|
|
68
|
+
pkg.devDependencies[name] = version;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
73
|
+
|
|
74
|
+
// ─── 2. scripts/get-available-port.sh(从 skill 源文件复制到项目内)────────────
|
|
75
|
+
const scriptsDir = join(projectDir, 'scripts');
|
|
76
|
+
if (!existsSync(scriptsDir)) mkdirSync(scriptsDir, { recursive: true });
|
|
77
|
+
|
|
78
|
+
const portScriptSrc = join(__dirname, '..', 'bash', 'get-available-port.sh');
|
|
79
|
+
const portScriptDest = join(scriptsDir, 'get-available-port.sh');
|
|
80
|
+
writeFileSync(portScriptDest, readFileSync(portScriptSrc, 'utf8'));
|
|
81
|
+
chmodSync(portScriptDest, 0o755);
|
|
82
|
+
|
|
83
|
+
// ─── 3. playwright.config.ts ───────────────────────────────────────────────────
|
|
84
|
+
const playwrightConfig = `import { defineConfig, devices } from '@playwright/test';
|
|
85
|
+
|
|
86
|
+
const port = parseInt(process.env.E2E_PORT || '60000', 10);
|
|
87
|
+
|
|
88
|
+
export default defineConfig({
|
|
89
|
+
testDir: './e2e',
|
|
90
|
+
fullyParallel: true,
|
|
91
|
+
forbidOnly: !!process.env.CI,
|
|
92
|
+
retries: process.env.CI ? 2 : 0,
|
|
93
|
+
workers: process.env.CI ? 1 : undefined,
|
|
94
|
+
use: { baseURL: \`http://localhost:\${port}\` },
|
|
95
|
+
webServer: {
|
|
96
|
+
command: \`npm run start -- -p \${port}\`,
|
|
97
|
+
url: \`http://localhost:\${port}\`,
|
|
98
|
+
reuseExistingServer: !process.env.CI,
|
|
99
|
+
},
|
|
100
|
+
projects: [
|
|
101
|
+
{
|
|
102
|
+
name: 'chromium',
|
|
103
|
+
use: {
|
|
104
|
+
...devices['Desktop Chrome'],
|
|
105
|
+
// channel: 'chrome', // TODO: 配置为系统已安装的浏览器 channel(chrome / msedge 等)
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
});
|
|
110
|
+
`;
|
|
111
|
+
|
|
112
|
+
writeFileSync(join(projectDir, 'playwright.config.ts'), playwrightConfig);
|
|
113
|
+
|
|
114
|
+
// ─── 4. .gitignore(追加 Playwright 产物忽略规则)──────────────────────────────
|
|
115
|
+
const gitignorePath = join(projectDir, '.gitignore');
|
|
116
|
+
let gitignoreContent = '';
|
|
117
|
+
if (existsSync(gitignorePath)) {
|
|
118
|
+
gitignoreContent = readFileSync(gitignorePath, 'utf8');
|
|
119
|
+
}
|
|
120
|
+
const gitignoreLinesToAdd = [];
|
|
121
|
+
if (!gitignoreContent.includes('playwright-report')) gitignoreLinesToAdd.push('playwright-report');
|
|
122
|
+
if (!gitignoreContent.includes('test-results')) gitignoreLinesToAdd.push('test-results');
|
|
123
|
+
if (gitignoreLinesToAdd.length > 0) {
|
|
124
|
+
const prefix =
|
|
125
|
+
gitignoreContent === '' ? '' : gitignoreContent.endsWith('\n') ? '\n' : '\n\n';
|
|
126
|
+
const header = gitignoreContent.includes('# Playwright') ? '' : '# Playwright\n';
|
|
127
|
+
writeFileSync(
|
|
128
|
+
gitignorePath,
|
|
129
|
+
gitignoreContent + prefix + header + gitignoreLinesToAdd.join('\n') + '\n',
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// ─── 5. e2e/ 目录(Playwright 测试文件存放位置)───────────────────────────────
|
|
134
|
+
const e2eDir = join(projectDir, 'e2e');
|
|
135
|
+
if (!existsSync(e2eDir)) mkdirSync(e2eDir, { recursive: true });
|
|
136
|
+
|
|
137
|
+
const gitkeep = join(e2eDir, '.gitkeep');
|
|
138
|
+
if (!existsSync(gitkeep)) writeFileSync(gitkeep, '');
|
|
139
|
+
|
|
140
|
+
// ─── 6. vite.config: 注入 Vitest exclude 配置 ───────────────────────────
|
|
141
|
+
function injectVitestExclude(viteConfigPath) {
|
|
142
|
+
if (!existsSync(viteConfigPath)) return;
|
|
143
|
+
let viteConfig = readFileSync(viteConfigPath, 'utf8');
|
|
144
|
+
if (viteConfig.includes('exclude:')) return;
|
|
145
|
+
const replaced = viteConfig.replace(
|
|
146
|
+
/test:\s*\{[\s\S]*?environment:\s*'jsdom',?\s*\}/,
|
|
147
|
+
`test: {\n environment: 'jsdom',\n exclude: ['**/node_modules/**', '**/e2e/**', '**/dist-theme/**'],\n }`,
|
|
148
|
+
);
|
|
149
|
+
if (replaced !== viteConfig) {
|
|
150
|
+
writeFileSync(viteConfigPath, replaced);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
injectVitestExclude(join(projectDir, 'vite.config.mjs'));
|
|
155
|
+
injectVitestExclude(join(projectDir, 'vite.config.js'));
|
|
156
|
+
|
|
157
|
+
const frameworkNote =
|
|
158
|
+
framework === 'vue2'
|
|
159
|
+
? '(vue2:Storybook7 + vite-plugin-vue2;e2e 配置已注入,与 vue3 行为一致)'
|
|
160
|
+
: framework === 'react'
|
|
161
|
+
? '(react 依赖库暂不在本 skill 脚手架支持范围内)'
|
|
162
|
+
: '(vue3:默认模板)';
|
|
163
|
+
|
|
164
|
+
console.log(
|
|
165
|
+
`✅ [${framework}] 已写入 playwright.config.ts、scripts/get-available-port.sh、e2e/、.gitignore,并更新 package.json。${frameworkNote}`,
|
|
166
|
+
);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 组件提交前自检表
|
|
2
|
+
|
|
3
|
+
提交代码前请对照本清单逐项勾选,确保无遗漏。可与 plan.md 的「验收检查清单」及「鲁棒性检查」一并使用。
|
|
4
|
+
|
|
5
|
+
## 数据与状态
|
|
6
|
+
|
|
7
|
+
- [ ] 是否处理了**空数据 / 空 URL** 的情况?(如 `fileUrl`、`data`、`options` 为空或未传时的展示与不报错)
|
|
8
|
+
- [ ] 是否处理了**网络请求失败**或**加载失败**的情况?(有 Error 状态与用户可感知的提示,不白屏不静默)
|
|
9
|
+
- [ ] 异步加载组件是否具备 **Loading / Error / Empty** 的完整状态与 UI?
|
|
10
|
+
|
|
11
|
+
## 布局与交互
|
|
12
|
+
|
|
13
|
+
- [ ] **缩放、翻页、Resize** 等交互在不同容器宽度下是否均正常?(小容器不大面积错位,大容器不溢出或已按 spec 约定处理)
|
|
14
|
+
- [ ] 带工具栏的容器是否已按约定设置默认位置(建议顶部,除非 spec 另有要求)?
|
|
15
|
+
|
|
16
|
+
## 样式与主题
|
|
17
|
+
|
|
18
|
+
- [ ] 样式是否**完全使用** LCAP/平台提供的 **CSS 变量**(见 theme-variables-*.md),无写死颜色/间距?
|
|
19
|
+
- [ ] 是否会被外部 CSS(如父级 `max-width`、`overflow`)意外破坏?根节点透传是否正常?
|
|
20
|
+
- [ ] 组件是否使用 `<style scoped>` 或 `<style module>`?是否存在裸 `<style>` 污染全局?(见 workflow-guardrails 规则 9)
|
|
21
|
+
- [ ] 内联 `:style` 是否仅用于运行时动态计算的值(如 Canvas backgroundImage、prop 计算宽高)?
|
|
22
|
+
|
|
23
|
+
## 测试与验收
|
|
24
|
+
|
|
25
|
+
- [ ] 单测中 Mock 的三方组件事件是否与真实行为一致(经实测或文档确认)?
|
|
26
|
+
- [ ] E2E 是否存在被注释掉或**规避**的失败用例?若有 Timeout 是否已排查并修复?
|
|
27
|
+
- [ ] `npm run test`、`npm run test:e2e` 与 `npm run build` 是否**均已通过**?
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
> 可选:实现阶段可在 tasks 或自检验收时引用本表(`templates/component-self-check.md`)进行最后一轮勾选。
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# [组件中文名称]([组件英文名称])
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
[MANDATORY CHECK] 若为复杂展示/容器类组件(如 PDF、图表、富文本、强依赖容器尺寸):
|
|
5
|
+
1. 「视觉与交互契约」为必填,不得留空或写「不适用」。
|
|
6
|
+
2. 必须明确:初始状态、响应式行为、溢出规则、Resize 行为、可观测 DOM 状态。
|
|
7
|
+
3. 即使用户输入为「完整需求」,若缺失上述契约,也必须补全后再写入 spec。
|
|
8
|
+
-->
|
|
9
|
+
|
|
10
|
+
- **生成时间**:[DATE]
|
|
11
|
+
|
|
12
|
+
## 概述
|
|
13
|
+
|
|
14
|
+
* 组件名称:[组件英文名称]([组件标签: 例如 `<qr-code>`])
|
|
15
|
+
* 技术栈:Vue3
|
|
16
|
+
* 核心职责:[组件核心职责]
|
|
17
|
+
* 适用场景:[典型使用场景描述]
|
|
18
|
+
* 依赖:[依赖成熟三方npm 仓库,及其使用描述]
|
|
19
|
+
|
|
20
|
+
## 功能
|
|
21
|
+
|
|
22
|
+
### 1.[功能名称]
|
|
23
|
+
|
|
24
|
+
#### 描述
|
|
25
|
+
|
|
26
|
+
[功能描述]
|
|
27
|
+
|
|
28
|
+
#### 验收标准
|
|
29
|
+
|
|
30
|
+
- [ ] [验收条件1]
|
|
31
|
+
- [ ] [验收条件2]
|
|
32
|
+
|
|
33
|
+
#### 接口设计
|
|
34
|
+
|
|
35
|
+
[相关属性|事件|插槽设计]
|
|
36
|
+
|
|
37
|
+
#### 使用示例
|
|
38
|
+
|
|
39
|
+
[使用代码示例]
|
|
40
|
+
|
|
41
|
+
## 视觉与交互契约
|
|
42
|
+
|
|
43
|
+
<!-- 复杂展示/容器类组件必填;简单原子组件可简述「不适用」。生成 spec 时必须逐项填充,不得整体留空。 -->
|
|
44
|
+
|
|
45
|
+
### 视觉表现 (Visual Contract)
|
|
46
|
+
|
|
47
|
+
- **初始状态**:[描述未加载/加载中/空数据时的视觉,以及用户“第一眼”看到的比例与布局,如:占满容器、固定宽高比]
|
|
48
|
+
- **响应式行为**:[描述容器尺寸变化时的适配策略,如:容器驱动/内容驱动、等比例缩放、重绘、滚动条出现]
|
|
49
|
+
- **溢出规则**:[描述内容超出时的处理,如:组件内滚动/容器外滚动/裁剪/自动缩放]
|
|
50
|
+
|
|
51
|
+
### 交互副作用 (Interaction Side-effects)
|
|
52
|
+
|
|
53
|
+
- **Resize 行为**:[描述窗口或容器 Resize 时的逻辑,如:重绘/防抖/节流/触发库 API 更新]
|
|
54
|
+
- **可观测 DOM 状态**:[描述验收时可检查的 DOM 特征,如:某元素存在、clientWidth 随 scale 变化、特定 class 切换;供测试与验收标准引用]
|
|
55
|
+
- **其他副作用**:[描述操作对周边或父容器的影响,如:缩放导致布局重排、弹窗对页面滚动的影响;无则填「无」]
|
|
56
|
+
|
|
57
|
+
## 接口定义 (属性 & 事件 & 方法 & 插槽)
|
|
58
|
+
|
|
59
|
+
### 属性
|
|
60
|
+
|
|
61
|
+
<!-- 支持双向绑定的属性:组件内部变更时需通过事件回写父组件,便于 v-model / 设计器绑定 -->
|
|
62
|
+
|
|
63
|
+
| 属性名称 | 描述 | 类型 | 可选值 | 默认值 | 是否双向绑定 |
|
|
64
|
+
|:---|:---|:---|:---|:---|:---|
|
|
65
|
+
|
|
66
|
+
### 事件
|
|
67
|
+
|
|
68
|
+
<!-- 特别注意: 事件参数仅允许有一个 event 参数 -->
|
|
69
|
+
|
|
70
|
+
| 事件名称 | 描述 | 回调参数 | 参数类型 |
|
|
71
|
+
|:---|:---|:---|:---|
|
|
72
|
+
|
|
73
|
+
### 方法
|
|
74
|
+
|
|
75
|
+
<!-- 如果有则生成对应的api -->
|
|
76
|
+
|
|
77
|
+
| 方法名称 | 描述 | 参数 | 返回值 |
|
|
78
|
+
|:---|:---|:---|:---|
|
|
79
|
+
|
|
80
|
+
### 插槽
|
|
81
|
+
|
|
82
|
+
| 插槽名称 | 描述 | 参数 |
|
|
83
|
+
|:---|:---|:---|
|
|
84
|
+
|
|
85
|
+
## 样式定制
|
|
86
|
+
|
|
87
|
+
<!-- 如果组件支持主题/样式定制,列出相关 CSS 变量 -->
|
|
88
|
+
|
|
89
|
+
| CSS 变量 | 描述 | 默认值 |
|
|
90
|
+
|:---|:---|:---|
|
|
91
|
+
|
|
92
|
+
## 注意事项
|
|
93
|
+
|
|
94
|
+
<!-- 使用限制、边界条件、已知问题等 -->
|
|
95
|
+
|
|
96
|
+
* [注意事项1]
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# [库名] — 库级迁移验证报告
|
|
2
|
+
|
|
3
|
+
**验证时间**:[ISO 8601]
|
|
4
|
+
**library_status**:🏁 library-verified / ❌ FAIL
|
|
5
|
+
**触发方式**:自动(末资产 verified)/ 显式 `--finalize-library`
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 资产统计
|
|
10
|
+
|
|
11
|
+
| 类型 | 总数 | ✅ verified | 🚫 blocked |
|
|
12
|
+
|------|------|-------------|------------|
|
|
13
|
+
| component | | | |
|
|
14
|
+
| logic | | | |
|
|
15
|
+
| shared-composable | | | |
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 三门禁证据(库级)
|
|
20
|
+
|
|
21
|
+
| 命令 | 退出码 | 结果摘要 |
|
|
22
|
+
|:---|:---|:---|
|
|
23
|
+
| `npm run test` | | |
|
|
24
|
+
| `npm run build` | | |
|
|
25
|
+
| `npm run test:e2e` | | N/A 若无可 E2E 组件 |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 产物验证(4 项,与 create BUILD-VERIFY 一致)
|
|
30
|
+
|
|
31
|
+
| # | 检查项 | 结果 | 证据 |
|
|
32
|
+
|:--|:---|:---|:---|
|
|
33
|
+
| 1 | package.json name/version | | |
|
|
34
|
+
| 2 | nasl.extension.json 存在 | | |
|
|
35
|
+
| 3 | ZIP 产物存在 | | |
|
|
36
|
+
| 4 | viewComponents 全量非空 | | |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 阻塞资产
|
|
41
|
+
|
|
42
|
+
| 资产名 | 状态 | 原因 |
|
|
43
|
+
|:---|:---|:---|
|
|
44
|
+
| — | — | 无 |
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 总体结论
|
|
49
|
+
|
|
50
|
+
**PASS** / **CONDITIONAL PASS** / **FAIL**
|
|
51
|
+
|
|
52
|
+
**说明**:[如有 CONDITIONAL PASS,列出 ⚠️ 机制差异引用各资产 report.md]
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# [逻辑中文标题]([函数名 snake_case])
|
|
2
|
+
|
|
3
|
+
- **生成时间**:[DATE]
|
|
4
|
+
- **绑定端**:pc / h5 / both
|
|
5
|
+
|
|
6
|
+
## 概述
|
|
7
|
+
|
|
8
|
+
* 函数名:[functionName]
|
|
9
|
+
* 核心职责:[描述]
|
|
10
|
+
* 依赖:[nasl 类型 / 第三方]
|
|
11
|
+
|
|
12
|
+
## 功能
|
|
13
|
+
|
|
14
|
+
### 1. [功能名称]
|
|
15
|
+
|
|
16
|
+
#### 描述
|
|
17
|
+
|
|
18
|
+
[功能描述]
|
|
19
|
+
|
|
20
|
+
#### 验收标准
|
|
21
|
+
|
|
22
|
+
- [ ] [验收条件1]
|
|
23
|
+
- [ ] [验收条件2]
|
|
24
|
+
|
|
25
|
+
#### 接口设计
|
|
26
|
+
|
|
27
|
+
| 参数 | nasl 类型 | 说明 |
|
|
28
|
+
|------|-----------|------|
|
|
29
|
+
| … | … | … |
|
|
30
|
+
|
|
31
|
+
| 返回值 | nasl 类型 | 说明 |
|
|
32
|
+
|--------|-----------|------|
|
|
33
|
+
| … | … | … |
|
|
34
|
+
|
|
35
|
+
#### 使用示例
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
// TS 调用示例
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 注意事项
|
|
42
|
+
|
|
43
|
+
- 须 `import '@nasl/types'`
|
|
44
|
+
- 须 `@NaslLogic` JSDoc
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# [库名] 迁移清单
|
|
2
|
+
|
|
3
|
+
> 资产级状态追踪。每个命令执行时自动更新对应行。
|
|
4
|
+
> 详细报告 → 各资产 `specs/<NN>-<资产名>/report.md`。
|
|
5
|
+
|
|
6
|
+
**源码库**:[Vue2 源码路径]
|
|
7
|
+
**目标工程**:[Vue3 工程路径]
|
|
8
|
+
**最后更新**:[DATE]
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 迁移进度
|
|
13
|
+
|
|
14
|
+
总资产: N | ✅ 完成: X | 🔨 进行中: Y | ⏳ 待开始: Z | 🚫 阻塞: W
|
|
15
|
+
进度: [████████░░] X/N (XX%)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 库级状态
|
|
20
|
+
|
|
21
|
+
| 字段 | 值 |
|
|
22
|
+
|------|-----|
|
|
23
|
+
| library_status | ⏳ in-progress |
|
|
24
|
+
| library_verified_at | — |
|
|
25
|
+
| 末次库级三门禁 | — |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 资产状态表
|
|
30
|
+
|
|
31
|
+
| # | 资产名 | 类型 | 复杂度 | 推荐序号 | depends_on | 状态 | Stories 来源 | Mixin 依赖 |
|
|
32
|
+
|:--|:---|:---|:---|:---|:---|:---|:---|:---|
|
|
33
|
+
| 01 | [资产名] | component / logic / shared-composable | HIGH/MED/LOW | 1 | — | ⏳ pending | block.stories.js | [列表] |
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 状态流转
|
|
38
|
+
|
|
39
|
+
| 状态 | 含义 | 由哪个命令设置 |
|
|
40
|
+
|:---|:---|:---|
|
|
41
|
+
| ⏳ pending | 已识别,未开始 | migrate.scan |
|
|
42
|
+
| 🔍 spec-done | 行为真值已提取 | migrate.spec |
|
|
43
|
+
| 🔄 planned | 迁移方案已制定 | migrate.plan |
|
|
44
|
+
| 📋 tasks-ready | TDD 编排已完成 | migrate.tasks |
|
|
45
|
+
| 🔴 red-in-progress | RED 阶段进行中 | migrate.red |
|
|
46
|
+
| 🔴 red-done | 测试已编码(全 FAIL) | migrate.red |
|
|
47
|
+
| 🟢 green-in-progress | GREEN 阶段进行中 | migrate.green |
|
|
48
|
+
| 🟢 green-done | 实现完成(测试全 PASS) | migrate.green |
|
|
49
|
+
| ✅ verified | 等价性验证通过 | migrate.check |
|
|
50
|
+
| 🚫 blocked | 阻塞(需用户介入) | 断路器触发 |
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 推荐迁移顺序
|
|
55
|
+
|
|
56
|
+
> 由 migrate.scan 计算:shared-composable → logic → component(depends_on 拓扑序)。
|
|
57
|
+
|
|
58
|
+
1. [资产名](类型,推荐序号 1)
|
|
59
|
+
2. ...
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 共享依赖
|
|
64
|
+
|
|
65
|
+
### Mixin 全量清单
|
|
66
|
+
|
|
67
|
+
| Mixin 文件 | 方法数 | 被引用次数 | 引用组件 |
|
|
68
|
+
|:---|:---|:---|:---|
|
|
69
|
+
| [mixin.js] | N | M | [组件1, 组件2] |
|
|
70
|
+
|
|
71
|
+
### 第三方依赖
|
|
72
|
+
|
|
73
|
+
| 库名 | 版本 | 引用组件 |
|
|
74
|
+
|:---|:---|:---|
|
|
75
|
+
| [lib] | ^x.y.z | [组件列表] |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 更新规则
|
|
80
|
+
|
|
81
|
+
- 仅改本表对应行的状态列
|
|
82
|
+
- 状态变更由各 migrate 命令自动驱动
|
|
83
|
+
- 🚫 blocked 时须在对应资产 report.md 中记录详情
|
|
84
|
+
- 禁止手动跳跃状态(必须按流转顺序)
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# [资产名] — 迁移方案
|
|
2
|
+
|
|
3
|
+
**Date**:[YYYY-MM-DD]
|
|
4
|
+
**Input**:`specs/<NN>-<资产名>/spec.md`(行为真值)
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 摘要
|
|
9
|
+
|
|
10
|
+
[3~5 句话概括:迁移对象、核心复杂点、主要技术路线(Mixin 拆分策略、第三方处理、样式方案)。]
|
|
11
|
+
|
|
12
|
+
**资产类型**:component / logic / shared-composable
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 转换策略表
|
|
17
|
+
|
|
18
|
+
> 每项必须引用 KB 章节名(§mixin-composable、§vue3-children-clone、§pitfalls 等)。规则以 knowledge-base 为准,不得凭 AI 记忆。
|
|
19
|
+
|
|
20
|
+
| Vue2 模式 / 决策点 | Vue3 目标 | KB 章节 | 备注 |
|
|
21
|
+
|:---|:---|:---|:---|
|
|
22
|
+
| (按 spec 与 KB 填写) | | | |
|
|
23
|
+
|
|
24
|
+
**logic 资产**:以下节标 **N/A** — api.ts、ideusage、Stories、CSS 变量、Storybook。
|
|
25
|
+
**shared-composable**:以下节标 **N/A** — api.ts、ideusage、Stories。
|
|
26
|
+
|
|
27
|
+
### Mixin → Composable 映射(→ §mixin-composable)
|
|
28
|
+
|
|
29
|
+
| Mixin 文件 | 方法/属性 | 有调用点 | Composable 目标 | 拆分理由 |
|
|
30
|
+
|:---|:---|:---|:---|:---|
|
|
31
|
+
| [mixin.js] | [method] | ✓/✗ | useXxx.ts / 不迁移 | [业务边界说明] |
|
|
32
|
+
|
|
33
|
+
**规则确认**:
|
|
34
|
+
- [ ] 全量方法已列出,无调用点的标记「不迁移」
|
|
35
|
+
- [ ] 按业务边界拆分,非按生命周期
|
|
36
|
+
- [ ] defineExpose 仅暴露原版已有 methods
|
|
37
|
+
- [ ] 副作用配套 onUnmounted 销毁
|
|
38
|
+
|
|
39
|
+
### 样式转换(→ §css-vars + theme-variables-element-plus.md)
|
|
40
|
+
|
|
41
|
+
| 原始变量/硬编码值 | Element Plus 目标变量 | 验证状态 |
|
|
42
|
+
|:---|:---|:---|
|
|
43
|
+
| --cursor-pointer | `pointer`(直接值) | ✓ 存在于文档 |
|
|
44
|
+
| #409eff | `var(--el-color-primary)` | ✓ 存在于文档 |
|
|
45
|
+
| 14px (font-size) | `var(--el-font-size-base)` | ✓ 存在于文档 |
|
|
46
|
+
|
|
47
|
+
**样式隔离**:`<style scoped>`(→ workflow-guardrails 规则 9)
|
|
48
|
+
|
|
49
|
+
### 第三方库处理
|
|
50
|
+
|
|
51
|
+
| 库名 | Vue2 初始化方式 | Vue3 初始化方式 | 注意事项 |
|
|
52
|
+
|:---|:---|:---|:---|
|
|
53
|
+
| [库名] | [如 mounted 内 new Xxx()] | [如 onXxxReady 回调内] | [→ §pitfalls: 第三方 init 时机] |
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 风险与陷阱(→ KB §pitfalls 逐条核对)
|
|
58
|
+
|
|
59
|
+
| # | 陷阱摘要(来自 §pitfalls) | 是否命中 | 预防/处理 |
|
|
60
|
+
|:--|:---|:---|:---|
|
|
61
|
+
| 1 | | ✓/✗ | |
|
|
62
|
+
| … | (与 §pitfalls 叙事条数一致,plan 阶段逐条填写) | | |
|
|
63
|
+
|
|
64
|
+
**预估复杂度**:HIGH / MEDIUM / LOW
|
|
65
|
+
**主要复杂点**:[列出 1-3 个最关键的难点]
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 资产类型说明
|
|
70
|
+
|
|
71
|
+
| 类型 | 本模板使用的节 |
|
|
72
|
+
|------|----------------|
|
|
73
|
+
| component | 全文(含 ideusage、stories、css-vars) |
|
|
74
|
+
| logic | 跳过 ideusage、stories、css-vars、E2E;使用 logic 文件表 |
|
|
75
|
+
| shared-composable | 跳过 api.ts、ideusage、stories、css-vars、E2E;仅 composable + 测试 |
|
|
76
|
+
|
|
77
|
+
### logic 文件路径表(类型=logic 时使用)
|
|
78
|
+
|
|
79
|
+
| 模块 | 产出路径 | 测试层 |
|
|
80
|
+
|------|----------|--------|
|
|
81
|
+
| 逻辑函数 | `src/logics/<name>.ts` | Vitest(返回值) |
|
|
82
|
+
| 导出 | `src/logics/index.ts` | — |
|
|
83
|
+
| 单测 | `src/logics/__tests__/<name>.spec.ts` | — |
|
|
84
|
+
|
|
85
|
+
### shared-composable 文件路径表(类型=shared-composable 时使用)
|
|
86
|
+
|
|
87
|
+
| 模块 | 产出路径 | 测试层 |
|
|
88
|
+
|------|----------|--------|
|
|
89
|
+
| Composable | `src/composables/use<Xxx>.ts` | Vitest(返回值) |
|
|
90
|
+
| 单测 | `src/composables/__tests__/use<Xxx>.spec.ts` | — |
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 文件路径规划表(路径锁定)
|
|
95
|
+
|
|
96
|
+
> 路径为**相对扩展工程根目录**的完整路径,禁止模糊表述。
|
|
97
|
+
|
|
98
|
+
| 模块 | 职责 | 产出路径 | 测试层 | 操作 |
|
|
99
|
+
|:---|:---|:---|:---|:---|
|
|
100
|
+
| api.ts | NASL 接口声明 | `src/components/<name>/api.ts` | — | 新增 |
|
|
101
|
+
| ideusage.json | IDE 设计器配置 | `src/components/<name>/ideusage.json` | — | 新增 |
|
|
102
|
+
| index.vue | UI 组装 + 模板 | `src/components/<name>/index.vue` | Vitest(DOM) + E2E | 新增 |
|
|
103
|
+
| useXxx.ts | [业务逻辑描述] | `src/components/<name>/composables/useXxx.ts` | Vitest(返回值) | 新增 |
|
|
104
|
+
| index.ts | 桶文件导出 | `src/components/<name>/index.ts` | — | 新增 |
|
|
105
|
+
| block.stories | 画布拖拽 story | `src/components/<name>/stories/block.stories.js` | — | 新增 |
|
|
106
|
+
| example.stories | 功能 demo | `src/components/<name>/stories/example.stories.js` | — | 新增 |
|
|
107
|
+
| 单测 | Vitest | `src/components/<name>/__tests__/index.spec.ts` | — | 新增 |
|
|
108
|
+
| E2E | Playwright | `e2e/<name>.spec.ts` | — | 新增 |
|
|
109
|
+
|
|
110
|
+
**测试层说明**(→ workflow-guardrails §8):
|
|
111
|
+
- `Vitest(返回值)` — 纯逻辑,直接断言返回
|
|
112
|
+
- `Vitest(调用参数)` — 调用浏览器 API,仅 mock 验证调用参数
|
|
113
|
+
- `Vitest(DOM) + E2E` — DOM 操作,Vitest 验证结构,E2E 验证渲染
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 复杂度评估
|
|
118
|
+
|
|
119
|
+
| 维度 | 评估 | 说明 |
|
|
120
|
+
|:---|:---|:---|
|
|
121
|
+
| Mixin 数量 | N | [列出] |
|
|
122
|
+
| Props 数量 | N | — |
|
|
123
|
+
| 第三方库 | N | [列出] |
|
|
124
|
+
| **综合复杂度** | HIGH/MEDIUM/LOW | — |
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 用户审批门禁
|
|
129
|
+
|
|
130
|
+
⛔ **以上方案需用户确认后方可进入 migrate.tasks。**
|
|
131
|
+
|
|
132
|
+
**确认要点**:
|
|
133
|
+
- [ ] 转换策略是否合理(每项有 §id 引用)
|
|
134
|
+
- [ ] 文件路径规划是否正确
|
|
135
|
+
- [ ] 已识别风险是否已有应对
|
|
136
|
+
- [ ] 复杂度评估是否准确
|
|
137
|
+
|
|
138
|
+
**隐式审批**:用户回复含 tasks/继续/开始/OK → 视为通过。
|