@pm_zhousl/xinyun-ai-init 1.1.3 → 1.1.5
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/init/xinyun-ai-init/README.md +80 -2
- package/init/xinyun-ai-init/templates/AGENTS.template.md +10 -0
- package/init/xinyun-ai-init/templates/core-rules.template.md +34 -0
- package/init/xinyun-ai-init/templates/current-task.template.md +4 -0
- package/init/xinyun-ai-init/templates/manifest.template.json +4 -3
- package/init/xinyun-ai-init/templates/project-check.template.md +1 -0
- package/init/xinyun-ai-init/templates/project-guide.template.md +4 -0
- package/init/xinyun-ai-init/templates/workstreams-readme.template.md +5 -1
- package/init/xinyun-ai-init/version.json +2 -2
- package/package.json +2 -1
- package/scripts/verify-init-package.js +226 -0
|
@@ -65,6 +65,8 @@ CLI 只负责生成 `xinyun-ai-init/`,不创建 `xinyun-ai/`,也不修改业
|
|
|
65
65
|
- 是否影响 UI:
|
|
66
66
|
- 是否影响配置:
|
|
67
67
|
- 前端改动模式:样式微调 / 新页面 / 页面重写 / 组件重构 / 不涉及
|
|
68
|
+
- Git 模式:单仓库 / 多仓库 / 混合仓库 / 未发现
|
|
69
|
+
- Git 影响范围:
|
|
68
70
|
|
|
69
71
|
## 4. 预计修改文件
|
|
70
72
|
|
|
@@ -98,6 +100,31 @@ UI 类需求至少判断前端改动模式:样式微调 / 新页面 / 页面
|
|
|
98
100
|
|
|
99
101
|
普通聊天、临时咨询、无长期价值排查不沉淀。
|
|
100
102
|
|
|
103
|
+
## 前端官方组件与 API 优先
|
|
104
|
+
|
|
105
|
+
前端组件调用、框架 API 和交互能力优先使用官方组件、官方 API、官方推荐写法或项目已有封装。
|
|
106
|
+
|
|
107
|
+
- 微信小程序:优先使用官方基础组件、官方 API、页面配置和项目已有封装。
|
|
108
|
+
- uni-app:优先使用 uni-app 官方组件、`uni.*` API、官方生命周期和项目已有封装。
|
|
109
|
+
- Vue2 / Vue3:优先使用 Vue 官方组件组织方式、官方响应式 / 生命周期 / 组合式或选项式 API,以及项目已有组件体系。
|
|
110
|
+
- React:优先使用 React 官方组件模式、Hooks、受控组件等官方推荐方式,以及项目已有组件体系。
|
|
111
|
+
- 确需第三方库、自定义组件或自造工具时,必须在改动计划中说明原因、影响范围和替代方案。
|
|
112
|
+
|
|
113
|
+
## 商业逻辑与变现流程理解
|
|
114
|
+
|
|
115
|
+
当需求涉及金额、订单、权益、结算、优惠、积分、分润、提现、会员等级、支付状态或退款等商业逻辑时,AI 必须先做触发式业务理解。
|
|
116
|
+
|
|
117
|
+
触发后先梳理:
|
|
118
|
+
|
|
119
|
+
- 业务目标
|
|
120
|
+
- 关键角色
|
|
121
|
+
- 资金 / 权益 / 状态流转
|
|
122
|
+
- 数据库、API、UI 和测试数据影响
|
|
123
|
+
- 风险点
|
|
124
|
+
- 验收标准
|
|
125
|
+
|
|
126
|
+
该规则只在相关需求触发时启用,不默认创建 `xinyun-ai/business/`,也不在首次初始化阶段生成大量商业分析文档。
|
|
127
|
+
|
|
101
128
|
## 统一入口与旧规则失效
|
|
102
129
|
|
|
103
130
|
当前项目 AI 规则以 `xinyun-ai/` 为准,`AGENTS.md` 只作为入口文件,指向 `xinyun-ai/`。
|
|
@@ -207,6 +234,29 @@ xinyun-ai/index/project-index.json
|
|
|
207
234
|
- 回复先给结论,再给依据路径,再给待确认问题。
|
|
208
235
|
- 不沿用用户已经纠正或否定的旧方向。
|
|
209
236
|
|
|
237
|
+
## Git 工作区与危险操作门禁
|
|
238
|
+
|
|
239
|
+
如果项目使用 Git,AI 必须先识别 Git 托管模式:
|
|
240
|
+
|
|
241
|
+
- 单仓库:根目录一个 `.git`,所有端在同一仓库中。
|
|
242
|
+
- 多仓库:各端口目录各自有 `.git`,例如 `server/`、`admin/`、`app/` 分别托管。
|
|
243
|
+
- 混合仓库:根目录有 `.git`,部分子端口也有独立 `.git`。
|
|
244
|
+
- 无 Git:当前项目未发现 Git,标注 `未在项目中发现`,不强行初始化。
|
|
245
|
+
|
|
246
|
+
涉及代码、配置、数据库、依赖、构建脚本、测试逻辑、API、UI 或业务流程改动时,改动计划必须说明:
|
|
247
|
+
|
|
248
|
+
- Git 模式
|
|
249
|
+
- 涉及仓库
|
|
250
|
+
- 当前分支
|
|
251
|
+
- 工作区是否干净
|
|
252
|
+
- 是否需要新分支
|
|
253
|
+
- 是否建议拆分 commit
|
|
254
|
+
- 是否涉及 tag / 发布
|
|
255
|
+
|
|
256
|
+
AI 可以读取 Git 状态、总结 diff、建议 commit message 和 tag;未获用户明确确认前,不得自动执行 `commit`、`tag`、`push`、`pull`、`merge`、`rebase`、`reset`、`checkout` 回滚或切分支。
|
|
257
|
+
|
|
258
|
+
多端多仓库改动后,应按仓库分别输出交付摘要和建议 commit message,不要混成一个提交建议。
|
|
259
|
+
|
|
210
260
|
## 按需补齐
|
|
211
261
|
|
|
212
262
|
后续识别到新端、模块或能力时,只在 `xinyun-ai/` 内补齐对应目录和说明文件。
|
|
@@ -219,9 +269,36 @@ xinyun-ai/index/project-index.json
|
|
|
219
269
|
- 问题排查:`xinyun-ai/problems/`
|
|
220
270
|
- 需求:`xinyun-ai/requirements/`
|
|
221
271
|
- 技术经验:`xinyun-ai/rules-candidates/`
|
|
272
|
+
- 全局影响审视:`xinyun-ai/global-review/`
|
|
222
273
|
|
|
223
274
|
新目录创建后必须更新 `xinyun-ai/manifest.json` 和 `xinyun-ai/index/project-index.json`。
|
|
224
275
|
|
|
276
|
+
## 通用项目全局视角
|
|
277
|
+
|
|
278
|
+
新增功能、大改、重构、跨端改动、目录 / 规则 / 索引调整时,AI 必须先做全局影响审视。
|
|
279
|
+
|
|
280
|
+
小改可以只在改动计划中简写全局影响;新功能、大改、重构、跨端改动、目录 / 规则 / 索引调整,应按需创建或更新:
|
|
281
|
+
|
|
282
|
+
```md
|
|
283
|
+
xinyun-ai/global-review/
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
全局审视不代替改动计划,它是改动计划前的影响检查。
|
|
287
|
+
|
|
288
|
+
建议审视层:
|
|
289
|
+
|
|
290
|
+
- 入口层
|
|
291
|
+
- 目录层
|
|
292
|
+
- 索引层
|
|
293
|
+
- 任务层
|
|
294
|
+
- 规则层
|
|
295
|
+
- 多端层
|
|
296
|
+
- 数据层
|
|
297
|
+
- API 层
|
|
298
|
+
- UI 层
|
|
299
|
+
- 验证层
|
|
300
|
+
- 交接层
|
|
301
|
+
|
|
225
302
|
## 会话工作台
|
|
226
303
|
|
|
227
304
|
首次初始化不创建会话工作台。复杂任务中可按需创建:
|
|
@@ -273,5 +350,6 @@ npx --yes @pm_zhousl/xinyun-ai-init@latest --force
|
|
|
273
350
|
5. 识别到的端、模块、技术栈、本地启动线索。
|
|
274
351
|
6. 数据库、API、测试体系发现情况。
|
|
275
352
|
7. CodeGraph 与索引状态。
|
|
276
|
-
8.
|
|
277
|
-
9.
|
|
353
|
+
8. Git 模式、涉及仓库、当前分支和工作区状态。
|
|
354
|
+
9. 待确认问题。
|
|
355
|
+
10. 后续日常开发和问题排查短指令。
|
|
@@ -30,6 +30,16 @@
|
|
|
30
30
|
|
|
31
31
|
说明:用户发送 `xinyun-ai-init` 一句话入口后,视为已授权 AI 创建或补齐最小 `xinyun-ai/` 与本入口文件;该授权不包含业务代码、配置、数据库、API、UI 或业务流程修改。
|
|
32
32
|
|
|
33
|
+
## 前端与 Git 安全边界
|
|
34
|
+
|
|
35
|
+
前端组件调用、框架 API 和交互能力优先使用官方组件、官方 API、官方推荐写法或项目已有封装。微信小程序、uni-app、Vue2、Vue3、React 等框架中,能用官方能力解决的,不优先引入第三方组件或自造工具。
|
|
36
|
+
|
|
37
|
+
确需第三方库、自定义组件或自造工具时,必须先说明原因、影响范围和替代方案,并等待用户确认。
|
|
38
|
+
|
|
39
|
+
如果项目使用 Git,AI 必须识别单仓库 / 多仓库 / 混合仓库 / 无 Git 模式,并在改动计划中说明涉及仓库、当前分支、工作区是否干净、是否建议新分支、是否建议拆分 commit、是否涉及 tag / 发布。
|
|
40
|
+
|
|
41
|
+
未获用户明确确认前,AI 不得自动执行 `commit`、`tag`、`push`、`pull`、`merge`、`rebase`、`reset`、`checkout` 回滚或切分支。
|
|
42
|
+
|
|
33
43
|
AI 接手本项目时,请先读取:
|
|
34
44
|
|
|
35
45
|
- `xinyun-ai/README.md`
|
|
@@ -46,6 +46,8 @@
|
|
|
46
46
|
- 是否影响 UI:
|
|
47
47
|
- 是否影响配置:
|
|
48
48
|
- 前端改动模式:样式微调 / 新页面 / 页面重写 / 组件重构 / 不涉及
|
|
49
|
+
- Git 模式:单仓库 / 多仓库 / 混合仓库 / 未发现
|
|
50
|
+
- Git 影响范围:
|
|
49
51
|
|
|
50
52
|
## 4. 预计修改文件
|
|
51
53
|
|
|
@@ -73,6 +75,21 @@
|
|
|
73
75
|
- 新页面或页面重写必须先说明页面结构方案,且不得顺手修改无关页面。
|
|
74
76
|
- 普通聊天、临时咨询、无长期价值排查不沉淀。
|
|
75
77
|
|
|
78
|
+
## 前端官方组件与 API 优先
|
|
79
|
+
|
|
80
|
+
- 前端组件调用、框架 API 和交互能力优先使用官方组件、官方 API、官方推荐写法或项目已有封装。
|
|
81
|
+
- 微信小程序优先使用官方基础组件、官方 API、页面配置和项目已有封装。
|
|
82
|
+
- uni-app 优先使用 uni-app 官方组件、`uni.*` API、官方生命周期和项目已有封装。
|
|
83
|
+
- Vue2 / Vue3 优先使用 Vue 官方组件组织方式、官方响应式 / 生命周期 / 组合式或选项式 API,以及项目已有组件体系。
|
|
84
|
+
- React 优先使用 React 官方组件模式、Hooks、受控组件等官方推荐方式,以及项目已有组件体系。
|
|
85
|
+
- 确需第三方库、自定义组件或自造工具时,必须在改动计划中说明原因、影响范围和替代方案。
|
|
86
|
+
|
|
87
|
+
## 商业逻辑与变现流程理解
|
|
88
|
+
|
|
89
|
+
- 当需求涉及金额、订单、权益、结算、优惠、积分、分润、提现、会员等级、支付状态或退款等商业逻辑时,先做触发式业务理解。
|
|
90
|
+
- 触发后先梳理业务目标、关键角色、资金 / 权益 / 状态流转、数据库 / API / UI / 测试数据影响、风险点和验收标准。
|
|
91
|
+
- 该规则只在相关需求触发时启用,不默认创建 `xinyun-ai/business/`。
|
|
92
|
+
|
|
76
93
|
## 检索与回复
|
|
77
94
|
|
|
78
95
|
- 先读 `AGENTS.md`、`xinyun-ai/manifest.json`、`xinyun-ai/index/project-index.json`、`xinyun-ai/current-task.md`。
|
|
@@ -82,6 +99,15 @@
|
|
|
82
99
|
- 回复先给结论,再给依据路径,再给待确认问题。
|
|
83
100
|
- 不沿用用户已经纠正或否定的旧方向。
|
|
84
101
|
|
|
102
|
+
## Git 工作区与危险操作门禁
|
|
103
|
+
|
|
104
|
+
- 如果项目使用 Git,先识别 Git 模式:单仓库 / 多仓库 / 混合仓库 / 无 Git。
|
|
105
|
+
- 无 Git 时标注 `未在项目中发现`,不强行初始化。
|
|
106
|
+
- 涉及代码、配置、数据库、依赖、构建脚本、测试逻辑、API、UI 或业务流程改动时,改动计划必须说明涉及仓库、当前分支、工作区是否干净、是否需要新分支、是否建议拆分 commit、是否涉及 tag / 发布。
|
|
107
|
+
- AI 可以读取 Git 状态、总结 diff、建议 commit message 和 tag。
|
|
108
|
+
- 未获用户明确确认前,不得自动执行 `commit`、`tag`、`push`、`pull`、`merge`、`rebase`、`reset`、`checkout` 回滚或切分支。
|
|
109
|
+
- 多端多仓库改动后,应按仓库分别输出交付摘要和建议 commit message。
|
|
110
|
+
|
|
85
111
|
## 框架适配
|
|
86
112
|
|
|
87
113
|
- 框架适配规则位于 `xinyun-ai-init/rules/frameworks/`。
|
|
@@ -105,6 +131,14 @@
|
|
|
105
131
|
|
|
106
132
|
复杂任务可按需创建 `xinyun-ai/index/session-current.md`。该文件只记录本轮临时线索,不是项目事实源。
|
|
107
133
|
|
|
134
|
+
## 通用项目全局视角
|
|
135
|
+
|
|
136
|
+
- 新增功能、大改、重构、跨端改动、目录 / 规则 / 索引调整时,先做全局影响审视。
|
|
137
|
+
- 小改可以只在改动计划中简写全局影响。
|
|
138
|
+
- 需要落盘时按需创建或更新 `xinyun-ai/global-review/`。
|
|
139
|
+
- 全局审视不代替改动计划,它是改动计划前的影响检查。
|
|
140
|
+
- 建议审视入口层、目录层、索引层、任务层、规则层、多端层、数据层、API 层、UI 层、验证层和交接层。
|
|
141
|
+
|
|
108
142
|
## 自我学习
|
|
109
143
|
|
|
110
144
|
发现可复用经验时,先记录为候选经验。候选经验必须标注来源、适用范围、可信度、状态和最后验证时间。用户确认后,才能合并进正式规则。
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"projectName": "",
|
|
3
|
-
"xinyunAiVersion": "1.1.
|
|
4
|
-
"scriptVersion": "2026.07.
|
|
3
|
+
"xinyunAiVersion": "1.1.5",
|
|
4
|
+
"scriptVersion": "2026.07.15",
|
|
5
5
|
"schemaVersion": "1",
|
|
6
6
|
"initializationMode": "fast",
|
|
7
7
|
"expansionMode": "triggered",
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"overall": "quick",
|
|
11
11
|
"workstreams": {},
|
|
12
12
|
"database": "unknown",
|
|
13
|
-
"api": "unknown"
|
|
13
|
+
"api": "unknown",
|
|
14
|
+
"git": "unknown"
|
|
14
15
|
},
|
|
15
16
|
"codegraph": { "enabled": false, "status": "unknown" },
|
|
16
17
|
"index": { "primary": "json_markdown", "sqlite": "optional" },
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"packageName": "xinyun-ai-init",
|
|
3
3
|
"displayName": "欣芸技术开发 Agent 流初始化包",
|
|
4
|
-
"version": "1.1.
|
|
5
|
-
"scriptVersion": "2026.07.
|
|
4
|
+
"version": "1.1.5",
|
|
5
|
+
"scriptVersion": "2026.07.15",
|
|
6
6
|
"schemaVersion": "1",
|
|
7
7
|
"defaultMode": "fast-init",
|
|
8
8
|
"targetWorkspace": "xinyun-ai",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pm_zhousl/xinyun-ai-init",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"description": "欣芸技术开发 Agent 流初始化包",
|
|
5
5
|
"bin": {
|
|
6
6
|
"xinyun-ai-init": "bin/xinyun-ai-init.js"
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"README.md"
|
|
13
13
|
],
|
|
14
14
|
"scripts": {
|
|
15
|
+
"verify:init": "node ./scripts/verify-init-package.js",
|
|
15
16
|
"publish:token": "powershell -ExecutionPolicy Bypass -File ./scripts/publish-with-token.ps1",
|
|
16
17
|
"publish:token:dry": "powershell -ExecutionPolicy Bypass -File ./scripts/publish-with-token.ps1 -DryRun"
|
|
17
18
|
},
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
|
|
6
|
+
const root = path.resolve(__dirname, "..");
|
|
7
|
+
const initRoot = path.join(root, "init", "xinyun-ai-init");
|
|
8
|
+
|
|
9
|
+
const checks = [];
|
|
10
|
+
|
|
11
|
+
function rel(filePath) {
|
|
12
|
+
return path.relative(root, filePath).replace(/\\/g, "/");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function readText(relativePath) {
|
|
16
|
+
const filePath = path.join(root, relativePath);
|
|
17
|
+
return fs.readFileSync(filePath, "utf8");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function addCheck(name, ok, detail) {
|
|
21
|
+
checks.push({ name, ok, detail });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function requireFile(relativePath) {
|
|
25
|
+
const filePath = path.join(root, relativePath);
|
|
26
|
+
addCheck(`文件存在:${relativePath}`, fs.existsSync(filePath), "缺少必需文件");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function requireIncludes(relativePath, snippets) {
|
|
30
|
+
const content = readText(relativePath);
|
|
31
|
+
for (const snippet of snippets) {
|
|
32
|
+
addCheck(
|
|
33
|
+
`${relativePath} 包含:${snippet}`,
|
|
34
|
+
content.includes(snippet),
|
|
35
|
+
`未找到关键文本:${snippet}`
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function requireJson(relativePath) {
|
|
41
|
+
try {
|
|
42
|
+
JSON.parse(readText(relativePath));
|
|
43
|
+
addCheck(`JSON 可解析:${relativePath}`, true);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
addCheck(`JSON 可解析:${relativePath}`, false, error.message);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function requireMarkdownBalanced(relativePath) {
|
|
50
|
+
const content = readText(relativePath);
|
|
51
|
+
const fenceCount = (content.match(/```/g) || []).length;
|
|
52
|
+
addCheck(
|
|
53
|
+
`Markdown 代码块闭合:${relativePath}`,
|
|
54
|
+
fenceCount % 2 === 0,
|
|
55
|
+
`代码块围栏数量为 ${fenceCount}`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function walkFiles(dirPath) {
|
|
60
|
+
const result = [];
|
|
61
|
+
for (const entry of fs.readdirSync(dirPath, { withFileTypes: true })) {
|
|
62
|
+
const entryPath = path.join(dirPath, entry.name);
|
|
63
|
+
if (entry.isDirectory()) {
|
|
64
|
+
result.push(...walkFiles(entryPath));
|
|
65
|
+
} else {
|
|
66
|
+
result.push(entryPath);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function verifyPackageFiles() {
|
|
73
|
+
const packageJson = JSON.parse(readText("package.json"));
|
|
74
|
+
const expectedFiles = ["bin/", "init/", "scripts/", "README.md"];
|
|
75
|
+
|
|
76
|
+
for (const expected of expectedFiles) {
|
|
77
|
+
addCheck(
|
|
78
|
+
`package.json files 包含:${expected}`,
|
|
79
|
+
Array.isArray(packageJson.files) && packageJson.files.includes(expected),
|
|
80
|
+
"发布文件白名单缺少该路径"
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
addCheck(
|
|
85
|
+
"package.json scripts 包含 verify:init",
|
|
86
|
+
packageJson.scripts && packageJson.scripts["verify:init"] === "node ./scripts/verify-init-package.js",
|
|
87
|
+
"缺少发布前校验命令"
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function verifyCliBoundary() {
|
|
92
|
+
const cli = readText("bin/xinyun-ai-init.js");
|
|
93
|
+
|
|
94
|
+
requireIncludes("bin/xinyun-ai-init.js", [
|
|
95
|
+
"This CLI only creates xinyun-ai-init/",
|
|
96
|
+
"It does not create xinyun-ai/ or modify business code",
|
|
97
|
+
"printNextStep",
|
|
98
|
+
]);
|
|
99
|
+
|
|
100
|
+
addCheck(
|
|
101
|
+
"CLI 目标目录仅为 xinyun-ai-init",
|
|
102
|
+
cli.includes('const target = path.join(cwd, "xinyun-ai-init");'),
|
|
103
|
+
"CLI 不应直接创建 xinyun-ai/"
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function verifyInitRules() {
|
|
108
|
+
requireIncludes("init/xinyun-ai-init/README.md", [
|
|
109
|
+
"用户发送一句话入口后,AI 可以按本 README 和 `templates/` 创建或补齐首次最小落盘清单。",
|
|
110
|
+
"该授权只覆盖 AI 工作区初始化,不代表授权修改业务代码",
|
|
111
|
+
"标准改动计划",
|
|
112
|
+
"前端改动模式:样式微调 / 新页面 / 页面重写 / 组件重构 / 不涉及",
|
|
113
|
+
"当前项目 AI 规则以 `xinyun-ai/` 为准",
|
|
114
|
+
"旧 AI 文档、旧 docs、旧提示词、旧规则文件只作为历史线索,不作为执行依据",
|
|
115
|
+
"ThinkPHP、uni-app、微信小程序",
|
|
116
|
+
"涉及 SQL / 数据库改动时,必须单独输出 SQL 执行提醒",
|
|
117
|
+
"商业逻辑",
|
|
118
|
+
"xinyun-ai/global-review/",
|
|
119
|
+
"Git 工作区与危险操作门禁",
|
|
120
|
+
"单仓库",
|
|
121
|
+
"多仓库",
|
|
122
|
+
"混合仓库",
|
|
123
|
+
"commit",
|
|
124
|
+
"push",
|
|
125
|
+
"rebase",
|
|
126
|
+
"前端官方组件与 API 优先",
|
|
127
|
+
"微信小程序",
|
|
128
|
+
"uni.*",
|
|
129
|
+
"Vue2 / Vue3",
|
|
130
|
+
"React",
|
|
131
|
+
"第三方库",
|
|
132
|
+
]);
|
|
133
|
+
|
|
134
|
+
requireIncludes("init/xinyun-ai-init/templates/AGENTS.template.md", [
|
|
135
|
+
"当前项目 AI 规则以 `xinyun-ai/` 为准",
|
|
136
|
+
"任何代码、配置、数据库、依赖、构建脚本、测试逻辑、API 行为、UI 行为或业务流程修改前",
|
|
137
|
+
"只有用户明确回复“确认执行”“可以修改”“按方案改”“同意”等类似内容后",
|
|
138
|
+
"前端组件调用、框架 API 和交互能力优先使用官方组件",
|
|
139
|
+
"单仓库 / 多仓库 / 混合仓库 / 无 Git",
|
|
140
|
+
"不得自动执行 `commit`、`tag`、`push`、`pull`、`merge`、`rebase`、`reset`、`checkout` 回滚或切分支",
|
|
141
|
+
]);
|
|
142
|
+
|
|
143
|
+
requireIncludes("init/xinyun-ai-init/templates/core-rules.template.md", [
|
|
144
|
+
"标准改动计划",
|
|
145
|
+
"前端改动模式:样式微调 / 新页面 / 页面重写 / 组件重构 / 不涉及",
|
|
146
|
+
"有 CodeGraph 时,结构性问题优先使用 CodeGraph",
|
|
147
|
+
"发现可复用经验时,先记录为候选经验",
|
|
148
|
+
"前端官方组件与 API 优先",
|
|
149
|
+
"uni.*",
|
|
150
|
+
"Vue2 / Vue3",
|
|
151
|
+
"React 官方组件模式",
|
|
152
|
+
"Git 工作区与危险操作门禁",
|
|
153
|
+
"单仓库 / 多仓库 / 混合仓库 / 无 Git",
|
|
154
|
+
"不得自动执行 `commit`、`tag`、`push`、`pull`、`merge`、`rebase`、`reset`、`checkout` 回滚或切分支",
|
|
155
|
+
]);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function verifyFrameworkRules() {
|
|
159
|
+
const required = [
|
|
160
|
+
"init/xinyun-ai-init/rules/frameworks/README.md",
|
|
161
|
+
"init/xinyun-ai-init/rules/frameworks/backend/php/thinkphp.md",
|
|
162
|
+
"init/xinyun-ai-init/rules/frameworks/frontend/uni-app.md",
|
|
163
|
+
"init/xinyun-ai-init/rules/frameworks/frontend/wechat-miniprogram.md",
|
|
164
|
+
];
|
|
165
|
+
|
|
166
|
+
for (const file of required) {
|
|
167
|
+
requireFile(file);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
requireIncludes("init/xinyun-ai-init/rules/frameworks/backend/php/thinkphp.md", [
|
|
171
|
+
"topthink/framework",
|
|
172
|
+
"think\\facade",
|
|
173
|
+
]);
|
|
174
|
+
requireIncludes("init/xinyun-ai-init/rules/frameworks/frontend/uni-app.md", [
|
|
175
|
+
"pages.json",
|
|
176
|
+
"vite-plugin-uni",
|
|
177
|
+
]);
|
|
178
|
+
requireIncludes("init/xinyun-ai-init/rules/frameworks/frontend/wechat-miniprogram.md", [
|
|
179
|
+
"project.config.json",
|
|
180
|
+
".wxml",
|
|
181
|
+
]);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function verifyJsonAndMarkdown() {
|
|
185
|
+
const jsonFiles = walkFiles(initRoot).filter((filePath) => filePath.endsWith(".json"));
|
|
186
|
+
const mdFiles = walkFiles(initRoot).filter((filePath) => filePath.endsWith(".md"));
|
|
187
|
+
|
|
188
|
+
for (const filePath of jsonFiles) {
|
|
189
|
+
requireJson(rel(filePath));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
for (const filePath of mdFiles) {
|
|
193
|
+
requireMarkdownBalanced(rel(filePath));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function main() {
|
|
198
|
+
requireFile("bin/xinyun-ai-init.js");
|
|
199
|
+
requireFile("init/xinyun-ai-init/README.md");
|
|
200
|
+
requireFile("init/xinyun-ai-init/version.json");
|
|
201
|
+
|
|
202
|
+
verifyPackageFiles();
|
|
203
|
+
verifyCliBoundary();
|
|
204
|
+
verifyInitRules();
|
|
205
|
+
verifyFrameworkRules();
|
|
206
|
+
verifyJsonAndMarkdown();
|
|
207
|
+
|
|
208
|
+
const failed = checks.filter((check) => !check.ok);
|
|
209
|
+
|
|
210
|
+
for (const check of checks) {
|
|
211
|
+
const prefix = check.ok ? "[PASS]" : "[FAIL]";
|
|
212
|
+
console.log(`${prefix} ${check.name}`);
|
|
213
|
+
if (!check.ok && check.detail) {
|
|
214
|
+
console.log(` ${check.detail}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
console.log("");
|
|
219
|
+
console.log(`[xinyun-ai-init verify] ${checks.length - failed.length}/${checks.length} checks passed.`);
|
|
220
|
+
|
|
221
|
+
if (failed.length > 0) {
|
|
222
|
+
process.exit(1);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
main();
|