@routerhub/agent-rules 1.0.6

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/AGENTS.base.md ADDED
@@ -0,0 +1,61 @@
1
+ # Copilot Agent Rules - Base
2
+
3
+ 以下规则适用于所有使用此规则包的项目。各项目可通过 `AGENTS.private.md` 添加项目特定规则。
4
+
5
+ ## 语言与回答
6
+
7
+ - 始终使用中文回答。
8
+
9
+ ## 文件与目录约束
10
+
11
+ - 不能随意修改核心业务文件和 API 相关代码。
12
+ - 不要编写或修改 `README.md`(由项目维护)。
13
+ - 先用`typings.d.ts` 中的类型定义,如果没有再自定义 TypeScript类型
14
+
15
+ ## 样式与 UI 约束
16
+
17
+ - 新增或修改样式时,统一使用 `*.module.scss`,不要在业务页面新增普通 `.css` 样式。
18
+ - `scss` 中的类名统一使用小驼峰命名(如 `topupButton`),不使用下划线或中划线。
19
+ - 不允许使用 `span` 标签选择器。
20
+ - 如果必须存在类名(历史代码场景),类名使用小驼峰命名,不使用下划线或中划线。
21
+
22
+ ## 命名与类型约束
23
+
24
+ - 参数名、变量名应与 `typings.d.ts` 中字段命名保持一致。
25
+ - 命名使用小驼峰或大驼峰,不使用下划线命名。
26
+ - 变量或值命名时,至少使用两个单词。
27
+ - TS 中不允许使用 `as`,不允许使用 `any`。
28
+ - 组件 `props` 能复用类型时,必须优先复用,不要重复定义。
29
+
30
+ ## 常量与业务规则
31
+
32
+ - 禁止硬编码数字判断;统一使用常量或枚举,并定义在 `Const.ts` 或 `constants.ts`。
33
+ - `tab` 索引统一使用常量。
34
+ - 时间相关处理统一使用 `dayjs`。
35
+ - 数据回显优先使用对象展开运算符(`...`)。
36
+
37
+ ## 代码风格与结构
38
+
39
+ - 不允许写 `class`,统一使用函数式编程。
40
+ - 不要写 `try/catch`。
41
+ - 当同一个组件被复用时,传入 `fromType`(值为当前页面名)用于区分来源;组件内部差异逻辑基于 `fromType` 分支。
42
+
43
+ ## 组件复用规则
44
+
45
+ - **优先复用项目中已存在的组件**,写新功能时尽量不要创建新组件。
46
+ - 检查现有组件库中是否有可复用的基础组件(如表格、卡片、按钮、容器等)。
47
+ - 能通过 `props` 定制的场景,不要创建新组件;优先改进现有组件的 `props` 接口。
48
+ - 任何公共使用频率高的组件应统一维护,避免样式和逻辑分散。
49
+
50
+ ## 自动化测试规则
51
+
52
+ - 自动化测试默认必须使用真实接口数据,禁止使用 mock/route.fulfill/本地伪造返回;仅在明确同意的情况下才允许使用模拟数据。
53
+ - 编写自动化测试时,关键步骤之间需间隔 2 秒后再执行下一步,以保证操作过程可观察。
54
+ - 自动化测试执行完毕后,自动打开 UI 界面,允许开发者进行手动验证。
55
+
56
+ ## 优先级声明
57
+
58
+ - 若规则之间有冲突,按以下优先级执行:
59
+ 1. 项目私有规则(AGENTS.private.md)
60
+ 2. 基础规则(此文件)
61
+ 3. 隐含约定
@@ -0,0 +1,51 @@
1
+ # 项目私有规则模板
2
+
3
+ 以下是项目特定规则的示例。请根据实际项目情况修改。
4
+
5
+ ## 文件与目录约束
6
+
7
+ - 不能修改 `src/apis/api` 下的任何内容
8
+ - 不能修改 `src/core` 下的核心模块
9
+
10
+ ## 项目特定的连接配置
11
+
12
+ - 测试环境 API:https://test-api.example.com
13
+ - 生产环境 API:https://api.example.com
14
+ - 内部工具地址:https://internal-tools.example.com
15
+
16
+ ## 组件库路径
17
+
18
+ - UI 组件:`src/components/ui/`
19
+ - 业务组件:`src/components/business/`
20
+ - 表格组件使用:`TableBase` 或 `TablePricing`
21
+ - 卡片组件使用:`CardBase`
22
+
23
+ ## 接口与数据
24
+
25
+ - API 响应统一通过 `src/types/api.ts` 定义
26
+ - 数据转换统一通过 `src/utils/transform.ts` 完成
27
+ - 所有业务数据应经过验证,不信任 API 返回
28
+
29
+ ## 业务流程规范
30
+
31
+ - 支付流程必须经过风控检查
32
+ - 用户认证使用统一的 `AuthContext`
33
+ - 权限控制通过 `usePermission` hook 实现
34
+
35
+ ## 禁止使用
36
+
37
+ - 不允许直接操作 DOM(使用 React ref)
38
+ - 不允许使用 localStorage 存储敏感信息
39
+ - 不允许直接 fetch,必须通过 `apiClient` 工具
40
+
41
+ ## 测试要求
42
+
43
+ - 所有业务逻辑必须有单元测试
44
+ - 页面级别测试必须包括主流程和错误流程
45
+ - 不允许使用真实账户进行自动化测试
46
+
47
+ ## 代码审批要求
48
+
49
+ - PR 必须通过 ESLint 检查
50
+ - PR 必须通过单元测试
51
+ - PR 必须至少有 1 名代码审批者同意
package/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # @routerhub/agent-rules
2
+
3
+ 只做两件事:
4
+
5
+ 1. 生成项目可用的 `AGENTS.md`
6
+ 2. 自动监听 `AGENTS.private.md` 并同步
7
+
8
+ ## 安装
9
+
10
+ 在你的项目里安装:
11
+
12
+ ```bash
13
+ pnpm add -D concurrently https://github.com/routerhub/agentRules.git#v1.0.6
14
+ ```
15
+
16
+ ## 使用
17
+
18
+ 修改项目package.json中的scripts中的启动命令,改成类似下面这种,
19
+
20
+ ```json
21
+ {
22
+ "scripts": {
23
+ "dev": "concurrently \"next dev\" \"agent-rules watch\""
24
+ }
25
+ }
26
+ ```
27
+
28
+ 作用:
29
+ - 监听 `AGENTS.private.md` 变更
30
+ - 变更后自动重新同步 `AGENTS.md`
31
+
32
+
33
+ ## 如何打tag
34
+ ```
35
+ git tag v1.0.5
36
+ git push --tags
37
+ ```
package/merge.js ADDED
@@ -0,0 +1,211 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * 合并规则脚本
5
+ *
6
+ * 使用方式:
7
+ * node merge.js [command]
8
+ *
9
+ * command:
10
+ * init 初始化 AGENTS.md,并在缺失时创建 AGENTS.private.md 模板
11
+ * sync 重新生成项目根目录下的 AGENTS.md
12
+ * watch 监听 AGENTS.private.md 变化并自动同步
13
+ */
14
+
15
+ const fs = require('fs')
16
+ const path = require('path')
17
+
18
+ const packageRoot = __dirname
19
+ const currentRoot = process.cwd()
20
+
21
+ let syncTimer = null
22
+ let isSyncing = false
23
+ let pendingSync = false
24
+
25
+ function getDefaultConfig() {
26
+ return {
27
+ output: path.join(currentRoot, 'AGENTS.md'),
28
+ baseRulesPath: path.join(packageRoot, 'AGENTS.base.md'),
29
+ privateRulesPath: path.join(currentRoot, 'AGENTS.private.md'),
30
+ }
31
+ }
32
+
33
+ function readFileIfExists(filePath) {
34
+ try {
35
+ if (fs.existsSync(filePath)) {
36
+ return fs.readFileSync(filePath, 'utf-8')
37
+ }
38
+ } catch (e) {
39
+ console.warn(`无法读取文件 ${filePath}:`, e.message)
40
+ }
41
+ return null
42
+ }
43
+
44
+ function mergeAgents(config) {
45
+ const {
46
+ output = getDefaultConfig().output,
47
+ baseRulesPath = getDefaultConfig().baseRulesPath,
48
+ privateRulesPath = getDefaultConfig().privateRulesPath,
49
+ } = config
50
+
51
+ console.log('📦 开始合并规则文件...')
52
+ console.log(` 基础规则: ${baseRulesPath}`)
53
+ console.log(` 私有规则: ${privateRulesPath}`)
54
+ console.log(` 输出文件: ${output}`)
55
+
56
+ const baseRules = readFileIfExists(baseRulesPath)
57
+ if (!baseRules) {
58
+ console.error(`❌ 基础规则文件不存在: ${baseRulesPath}`)
59
+ process.exit(1)
60
+ }
61
+
62
+ const privateRules = readFileIfExists(privateRulesPath)
63
+
64
+ let merged = baseRules
65
+
66
+ if (privateRules) {
67
+ merged += '\n\n---\n\n'
68
+ merged += '# 项目私有规则\n\n'
69
+ merged += '以下规则仅适用于本项目,会覆盖基础规则中的相同部分。\n\n'
70
+ merged += privateRules
71
+ }
72
+
73
+ try {
74
+ fs.writeFileSync(output, merged, 'utf-8')
75
+ console.log(`✅ 规则已合并到 ${output}`)
76
+ } catch (e) {
77
+ console.error(`❌ 写入文件失败 ${output}:`, e.message)
78
+ process.exit(1)
79
+ }
80
+ }
81
+
82
+ function initAgents() {
83
+ const privateTemplatePath = path.join(packageRoot, 'AGENTS.private.example.md')
84
+ const privateOutputPath = path.join(currentRoot, 'AGENTS.private.md')
85
+
86
+ mergeAgents(getDefaultConfig())
87
+
88
+ if (!fs.existsSync(privateOutputPath) && fs.existsSync(privateTemplatePath)) {
89
+ fs.copyFileSync(privateTemplatePath, privateOutputPath)
90
+ console.log(`✅ 已创建私有规则模板 ${privateOutputPath}`)
91
+ }
92
+
93
+ console.log('✅ 初始化完成,后续执行 agent-rules sync 即可刷新 AGENTS.md')
94
+ }
95
+
96
+ function runSync(triggerSource) {
97
+ if (isSyncing) {
98
+ pendingSync = true
99
+ return
100
+ }
101
+
102
+ isSyncing = true
103
+ console.log(`[agent-rules:watch] ${triggerSource} -> 执行同步`)
104
+
105
+ mergeAgents(getDefaultConfig())
106
+
107
+ isSyncing = false
108
+
109
+ if (pendingSync) {
110
+ pendingSync = false
111
+ runSync('检测到等待中的改动')
112
+ }
113
+ }
114
+
115
+ function scheduleSync(triggerSource) {
116
+ if (syncTimer) {
117
+ clearTimeout(syncTimer)
118
+ }
119
+
120
+ syncTimer = setTimeout(() => {
121
+ syncTimer = null
122
+ runSync(triggerSource)
123
+ }, 300)
124
+ }
125
+
126
+ function watchAgents() {
127
+ const privateRulesName = 'AGENTS.private.md'
128
+ const privateRulesPath = path.join(currentRoot, privateRulesName)
129
+ const privateTemplatePath = path.join(packageRoot, 'AGENTS.private.example.md')
130
+
131
+ // 不存在则从模板创建
132
+ if (!fs.existsSync(privateRulesPath) && fs.existsSync(privateTemplatePath)) {
133
+ fs.copyFileSync(privateTemplatePath, privateRulesPath)
134
+ console.log(`[agent-rules:watch] 已创建 ${privateRulesPath},请按项目情况修改`)
135
+ }
136
+
137
+ runSync('启动监听')
138
+
139
+ fs.watch(currentRoot, (eventType, fileName) => {
140
+ const normalizedFileName = typeof fileName === 'string' ? fileName : ''
141
+ if (normalizedFileName !== privateRulesName) {
142
+ return
143
+ }
144
+
145
+ scheduleSync(`${privateRulesName} 已变更`)
146
+ })
147
+
148
+ console.log(`[agent-rules:watch] 正在监听 ${privateRulesPath}`)
149
+
150
+ process.on('SIGINT', () => {
151
+ process.exit(0)
152
+ })
153
+
154
+ process.on('SIGTERM', () => {
155
+ process.exit(0)
156
+ })
157
+ }
158
+
159
+ function main() {
160
+ const command = process.argv[2]
161
+
162
+ if (command === '--help' || command === '-h' || command === 'help') {
163
+ console.log('agent-rules 使用说明:')
164
+ console.log(' agent-rules 初始化 AGENTS.md,并在缺失时创建 AGENTS.private.md 模板')
165
+ console.log(' agent-rules init 初始化 AGENTS.md,并在缺失时创建 AGENTS.private.md 模板')
166
+ console.log(' agent-rules sync 重新生成项目根目录下的 AGENTS.md')
167
+ console.log(' agent-rules watch 监听 AGENTS.private.md,变更后自动同步 AGENTS.md')
168
+ console.log(' agent-rules help 查看帮助')
169
+ return
170
+ }
171
+
172
+ if (!command || command === 'init') {
173
+ initAgents()
174
+ return
175
+ }
176
+
177
+ if (command === 'sync') {
178
+ mergeAgents(getDefaultConfig())
179
+ return
180
+ }
181
+
182
+ if (command === 'watch') {
183
+ watchAgents()
184
+ return
185
+ }
186
+
187
+ const configPath = command
188
+
189
+ let config = {}
190
+
191
+ if (fs.existsSync(configPath)) {
192
+ try {
193
+ const configContent = fs.readFileSync(configPath, 'utf-8')
194
+ config = JSON.parse(configContent)
195
+ console.log(`📄 已加载配置文件: ${configPath}`)
196
+ } catch (e) {
197
+ console.error(`❌ 配置文件解析失败 ${configPath}:`, e.message)
198
+ process.exit(1)
199
+ }
200
+ } else {
201
+ console.log(`⚠️ 配置文件不存在 ${configPath},使用默认配置`)
202
+ }
203
+
204
+ mergeAgents(config)
205
+ }
206
+
207
+ if (require.main === module) {
208
+ main()
209
+ }
210
+
211
+ module.exports = { mergeAgents, readFileIfExists, initAgents, getDefaultConfig, watchAgents }
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@routerhub/agent-rules",
3
+ "version": "1.0.6",
4
+ "description": "Shared Copilot agent rules and guidelines for RouterHub projects",
5
+ "main": "AGENTS.base.md",
6
+ "bin": {
7
+ "agent-rules": "merge.js"
8
+ },
9
+ "files": [
10
+ "AGENTS.base.md",
11
+ "merge.js",
12
+ "AGENTS.private.example.md",
13
+ "postinstall.js",
14
+ "package.json"
15
+ ],
16
+ "scripts": {
17
+ "merge": "node merge.js",
18
+ "sync": "node merge.js sync",
19
+ "init": "node merge.js init",
20
+ "watch": "node merge.js watch",
21
+ "postinstall": "node postinstall.js"
22
+ },
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/routerhub/agent-rules"
26
+ },
27
+ "keywords": [
28
+ "copilot",
29
+ "agent",
30
+ "rules",
31
+ "guidelines"
32
+ ],
33
+ "author": "RouterHub Team",
34
+ "license": "MIT",
35
+ "engines": {
36
+ "node": ">=16.0.0"
37
+ }
38
+ }
package/postinstall.js ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+
3
+ console.log('')
4
+ console.log('[agent-rules] 安装完成')
5
+ console.log('[agent-rules] 下一步执行: npx agent-rules')
6
+ console.log('[agent-rules] 或显式初始化: npx agent-rules init')
7
+ console.log('[agent-rules] 以后同步规则: npx agent-rules sync')
8
+ console.log('[agent-rules] 查看帮助: npx agent-rules help')
9
+ console.log('')