airail 0.1.1 → 0.1.3

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/dist/cli/add.js CHANGED
@@ -45,7 +45,7 @@ async function cmdAdd(arg) {
45
45
  const config = (0, utils_1.requireAirailJson)(claudeDir);
46
46
  if (!arg) {
47
47
  console.error((0, colors_1.err)('用法: airail add <包名[@版本]|路径>'));
48
- process.exit(1);
48
+ throw new Error('');
49
49
  }
50
50
  if (config.pack) {
51
51
  console.log((0, colors_1.warn)(`当前已安装 pack: ${config.pack}`));
@@ -56,7 +56,7 @@ async function cmdAdd(arg) {
56
56
  const localPath = path.resolve(arg);
57
57
  if (!fs.existsSync(localPath)) {
58
58
  console.error((0, colors_1.err)(`路径不存在: ${localPath}`));
59
- process.exit(1);
59
+ throw new Error('');
60
60
  }
61
61
  const packName = readPackName(localPath);
62
62
  (0, utils_1.installPackFromDir)(localPath, packName, claudeDir);
@@ -69,7 +69,7 @@ async function cmdAdd(arg) {
69
69
  const rc = (0, utils_1.readRc)();
70
70
  if (!rc.configServer) {
71
71
  console.error((0, colors_1.err)('未配置配置仓库,请先执行: airail config setup'));
72
- process.exit(1);
72
+ throw new Error('');
73
73
  }
74
74
  await installPackFromConfigCenter(arg, claudeDir, config, rc);
75
75
  (0, utils_1.writeAirailJson)(claudeDir, config);
@@ -113,13 +113,13 @@ async function installPackFromConfigCenter(packNameWithVersion, claudeDir, confi
113
113
  }
114
114
  catch (e) {
115
115
  console.error((0, colors_1.err)(`获取规范包列表失败: ${e.message}`));
116
- process.exit(1);
116
+ throw new Error('');
117
117
  }
118
118
  const pack = packs.find(p => p.name === packName);
119
119
  if (!pack) {
120
120
  console.error((0, colors_1.err)(`规范包 "${packName}" 不存在。`));
121
121
  console.log((0, colors_1.info)(`可用规范包: ${packs.map(p => p.name).join(', ')}`));
122
- process.exit(1);
122
+ throw new Error('');
123
123
  }
124
124
  // 使用用户指定的版本,如果没有指定则使用配置仓库的版本
125
125
  const gitRef = userVersion || pack.gitRef;
@@ -104,19 +104,19 @@ async function listConfigs() {
104
104
  const rc = (0, utils_1.readRc)();
105
105
  if (!rc.configServer) {
106
106
  console.error((0, colors_1.err)('未配置配置仓库,请先执行: airail config setup'));
107
- process.exit(1);
107
+ throw new Error('');
108
108
  }
109
109
  try {
110
110
  ensureConfigRepo(rc.configServer, rc.configToken);
111
111
  }
112
112
  catch (e) {
113
113
  console.error((0, colors_1.err)(e.message));
114
- process.exit(1);
114
+ throw new Error('');
115
115
  }
116
116
  const indexPath = path.join(CONFIG_REPO_DIR, 'settings', 'index.json');
117
117
  if (!fs.existsSync(indexPath)) {
118
118
  console.error((0, colors_1.err)('配置仓库中未找到 settings/index.json'));
119
- process.exit(1);
119
+ throw new Error('');
120
120
  }
121
121
  let entries;
122
122
  try {
@@ -124,7 +124,7 @@ async function listConfigs() {
124
124
  }
125
125
  catch (e) {
126
126
  console.error((0, colors_1.err)(`读取配置列表失败: ${e.message}`));
127
- process.exit(1);
127
+ throw new Error('');
128
128
  }
129
129
  if (entries.length === 0) {
130
130
  console.log((0, colors_1.warn)('暂无可用配置。'));
@@ -139,20 +139,20 @@ async function useConfig(name) {
139
139
  const rc = (0, utils_1.readRc)();
140
140
  if (!rc.configServer) {
141
141
  console.error((0, colors_1.err)('未配置配置仓库,请先执行: airail config setup'));
142
- process.exit(1);
142
+ throw new Error('');
143
143
  }
144
144
  try {
145
145
  ensureConfigRepo(rc.configServer, rc.configToken);
146
146
  }
147
147
  catch (e) {
148
148
  console.error((0, colors_1.err)(e.message));
149
- process.exit(1);
149
+ throw new Error('');
150
150
  }
151
151
  // 获取配置清单
152
152
  const indexPath = path.join(CONFIG_REPO_DIR, 'settings', 'index.json');
153
153
  if (!fs.existsSync(indexPath)) {
154
154
  console.error((0, colors_1.err)('配置仓库中未找到 settings/index.json'));
155
- process.exit(1);
155
+ throw new Error('');
156
156
  }
157
157
  let entries;
158
158
  try {
@@ -160,7 +160,7 @@ async function useConfig(name) {
160
160
  }
161
161
  catch (e) {
162
162
  console.error((0, colors_1.err)(`读取配置列表失败: ${e.message}`));
163
- process.exit(1);
163
+ throw new Error('');
164
164
  }
165
165
  if (entries.length === 0) {
166
166
  console.log((0, colors_1.warn)('暂无可用配置。'));
@@ -171,7 +171,7 @@ async function useConfig(name) {
171
171
  if (name) {
172
172
  if (!entries.find(e => e.name === name)) {
173
173
  console.error((0, colors_1.err)(`配置 "${name}" 不存在,可用: ${entries.map(e => e.name).join(', ')}`));
174
- process.exit(1);
174
+ throw new Error('');
175
175
  }
176
176
  chosen = name;
177
177
  }
@@ -188,7 +188,7 @@ async function useConfig(name) {
188
188
  const settingsPath = path.join(CONFIG_REPO_DIR, 'settings', `${chosen}.json`);
189
189
  if (!fs.existsSync(settingsPath)) {
190
190
  console.error((0, colors_1.err)(`配置文件不存在: settings/${chosen}.json`));
191
- process.exit(1);
191
+ throw new Error('');
192
192
  }
193
193
  let content;
194
194
  try {
@@ -197,7 +197,7 @@ async function useConfig(name) {
197
197
  }
198
198
  catch (e) {
199
199
  console.error((0, colors_1.err)(`读取配置失败: ${e.message}`));
200
- process.exit(1);
200
+ throw new Error('');
201
201
  }
202
202
  const globalClaudeDir = path.join(os.homedir(), '.claude');
203
203
  if (!fs.existsSync(globalClaudeDir)) {
package/dist/cli/index.js CHANGED
@@ -59,7 +59,7 @@ function printBanner() {
59
59
  function printHelp() {
60
60
  const cmds = [
61
61
  ['init', '在当前项目初始化 airail'],
62
- ['add <url|路径>', '安装规范包(git URL 或本地路径)'],
62
+ ['add <包名[@版本]|路径>', '安装规范包(从配置仓库或本地路径)'],
63
63
  ['install [工具名]', '安装 CLI 工具(如 claude-code)'],
64
64
  ['clear', '清理 airail 相关内容'],
65
65
  ['update', '更新已安装的规范包'],
@@ -68,7 +68,7 @@ function printHelp() {
68
68
  ['exit', '退出交互模式'],
69
69
  ];
70
70
  const dispWidth = (s) => [...s].reduce((n, c) => n + (c.charCodeAt(0) > 0x7f ? 2 : 1), 0);
71
- const col = 22;
71
+ const col = 30;
72
72
  const lines = cmds.map(([c, d]) => ` ${c}${' '.repeat(Math.max(1, col - dispWidth(c)))}${d}`);
73
73
  console.log(['可用命令:', ...lines].join('\n'));
74
74
  }
@@ -83,21 +83,24 @@ async function executeCommand(cmd, args) {
83
83
  config: () => (0, config_1.cmdConfig)(args[0], ...args.slice(1)),
84
84
  };
85
85
  if (cmd === 'exit') {
86
- return false;
86
+ return { shouldContinue: false, success: true };
87
87
  }
88
88
  const handler = commands[cmd];
89
89
  if (!handler) {
90
90
  console.log(`未知命令: ${cmd}`);
91
91
  printHelp();
92
- return true;
92
+ return { shouldContinue: true, success: false };
93
93
  }
94
94
  try {
95
95
  await handler();
96
+ return { shouldContinue: true, success: true };
96
97
  }
97
98
  catch (e) {
98
- console.error(e.message);
99
+ if (e.message) {
100
+ console.error(e.message);
101
+ }
102
+ return { shouldContinue: true, success: false };
99
103
  }
100
- return true;
101
104
  }
102
105
  function startInteractiveMode() {
103
106
  printBanner();
@@ -116,7 +119,7 @@ function startInteractiveMode() {
116
119
  return;
117
120
  }
118
121
  const [cmd, ...args] = input.split(/\s+/);
119
- const shouldContinue = await executeCommand(cmd, args);
122
+ const { shouldContinue } = await executeCommand(cmd, args);
120
123
  if (!shouldContinue) {
121
124
  rl.close();
122
125
  process.exit(0);
@@ -136,9 +139,9 @@ function runCLI() {
136
139
  return;
137
140
  }
138
141
  // 有参数:直接执行命令(不显示 banner)
139
- executeCommand(cmd, args).then((shouldContinue) => {
140
- if (!shouldContinue) {
141
- process.exit(0);
142
+ executeCommand(cmd, args).then(({ shouldContinue, success }) => {
143
+ if (!shouldContinue || !success) {
144
+ process.exit(success ? 0 : 1);
142
145
  }
143
146
  }).catch((e) => {
144
147
  console.error(e.message);
package/dist/cli/init.js CHANGED
@@ -57,7 +57,7 @@ async function cmdInit() {
57
57
  (0, utils_1.copyTemplateDir)('agents', claudeDir);
58
58
  (0, utils_1.copyTemplateDir)('templates', claudeDir);
59
59
  (0, utils_1.copyTemplateDir)('docs', claudeDir);
60
- (0, utils_1.writeClaude)(cwd);
60
+ (0, utils_1.writeClaude)(claudeDir);
61
61
  (0, utils_1.writeSettings)(claudeDir);
62
62
  const config = {
63
63
  version: '0.1.0',
@@ -69,6 +69,6 @@ async function cmdInit() {
69
69
  console.log((0, colors_1.ok)('斜杠命令已安装'));
70
70
  console.log((0, colors_1.ok)('文档模板已安装'));
71
71
  console.log((0, colors_1.ok)('\nairail 初始化完成!'));
72
- console.log((0, colors_1.warn)('提示:执行 airail add <git-url|路径> 安装规范包。'));
73
- console.log((0, colors_1.warn)('提示:在 Claude Code 中输入 /init-docs 让 AI 分析项目代码并自动填充规范文档。'));
72
+ console.log((0, colors_1.warn)('提示:在 Claude Code 中输入 /init-skills 让 AI 分析项目并生成技能。'));
73
+ console.log((0, colors_1.warn)('提示:在 Claude Code 中输入 /start 了解项目。'));
74
74
  }
@@ -42,10 +42,10 @@ async function cmdUpdate() {
42
42
  const config = (0, utils_1.requireAirailJson)(claudeDir);
43
43
  if (!config.pack) {
44
44
  console.error((0, colors_1.err)('未安装任何 pack,无需更新。'));
45
- process.exit(1);
45
+ throw new Error('');
46
46
  }
47
47
  // 从 airail.json 读取 pack 来源信息(需要扩展 AirailJson 结构)
48
48
  // 暂时简化:提示用户重新 add
49
49
  console.error((0, colors_1.err)('update 功能开发中,请使用 airail add 重新安装。'));
50
- process.exit(1);
50
+ throw new Error('');
51
51
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "airail",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "AI coding assistant framework - enforce coding standards via Claude hooks & skills",
5
5
  "bin": {
6
6
  "airail": "./bin/airail.js"
@@ -0,0 +1,307 @@
1
+ ---
2
+ name: development-workflow
3
+ description: |
4
+ 项目开发工作流和最佳实践。包含开发流程建议、编码最佳实践、技术选型建议。
5
+
6
+ 触发场景:
7
+ - 询问开发流程和工作流
8
+ - 询问最佳实践和开发规范
9
+ - 询问如何组织开发工作
10
+ - 询问技术选型建议
11
+ - 询问命令使用顺序
12
+
13
+ 触发词:开发流程、工作流、最佳实践、开发规范、如何开发、开发建议、技术选型、命令使用、开发顺序、项目管理
14
+ ---
15
+
16
+ # 项目开发工作流和最佳实践
17
+
18
+ ## 概述
19
+
20
+ 本技能提供项目开发的工作流建议、编码最佳实践和技术选型指导,帮助开发者高效、规范地完成项目开发。
21
+
22
+ ---
23
+
24
+ ## 开发流程建议
25
+
26
+ ### 标准开发流程(6步法)
27
+
28
+ 1. **明确需求** → 使用 `/start` 快速了解项目
29
+ - 了解项目结构和技术栈
30
+ - 查看现有功能和代码组织
31
+ - 确认开发环境和依赖
32
+
33
+ 2. **检查规范** → 使用 `/check` 检查代码质量
34
+ - 检查现有代码规范
35
+ - 发现潜在问题
36
+ - 了解项目编码标准
37
+
38
+ 3. **分析进度** → 使用 `/progress` 了解完成情况
39
+ - 查看项目完成度
40
+ - 了解待办事项
41
+ - 评估工作量
42
+
43
+ 4. **开始开发** → 使用 `/dev` 或 `/crud` 快速生成代码
44
+ - 表已存在:使用 `/crud` 快速生成
45
+ - 从零开始:使用 `/dev` 完整开发
46
+ - 遵循项目规范和架构
47
+
48
+ 5. **添加待办** → 使用 `/add-todo` 跟踪任务
49
+ - 记录新发现的任务
50
+ - 标记优先级
51
+ - 设置截止日期
52
+
53
+ 6. **获取建议** → 使用 `/next` 确定下一步方向
54
+ - 分析当前状态
55
+ - 获取优先级建议
56
+ - 规划下一步工作
57
+
58
+ ### 定期维护流程
59
+
60
+ - **每日**:使用 `/add-todo` 记录新任务
61
+ - **每周**:使用 `/check` 检查代码质量
62
+ - **每周**:使用 `/progress` 查看进度
63
+ - **每周**:使用 `/sync` 生成综合报告
64
+ - **每月**:使用 `/next` 规划下一阶段工作
65
+
66
+ ---
67
+
68
+ ## 编码最佳实践
69
+
70
+ ### 1. 单一职责原则
71
+
72
+ **原则**:每个模块、类、方法只负责一件事
73
+
74
+ **实践**:
75
+ - 业务层负责业务逻辑
76
+ - 接口层负责请求处理和参数验证
77
+ - 数据层负责数据访问
78
+ - 工具类负责通用功能
79
+
80
+ **反例**:
81
+ ```
82
+ ❌ Controller 中包含复杂的业务逻辑
83
+ ❌ Service 中直接操作 HTTP 请求
84
+ ❌ 一个方法做多件不相关的事
85
+ ```
86
+
87
+ **正例**:
88
+ ```
89
+ ✅ Controller 只做参数验证和调用 Service
90
+ ✅ Service 专注业务逻辑
91
+ ✅ 每个方法职责清晰
92
+ ```
93
+
94
+ ---
95
+
96
+ ### 2. 查询优化
97
+
98
+ **原则**:规范构建查询条件,避免性能问题
99
+
100
+ **实践**:
101
+ - 使用规范的查询条件构建方式
102
+ - 避免 N+1 查询问题
103
+ - 合理使用索引
104
+ - 分页查询大数据量
105
+
106
+ **查询条件规范**:
107
+ - 精确匹配:ID、状态、类型等
108
+ - 模糊搜索:名称、标题、内容等
109
+ - 范围查询:日期、金额等
110
+ - 关联查询:使用 JOIN 而非多次查询
111
+
112
+ ---
113
+
114
+ ### 3. 权限管理
115
+
116
+ **原则**:所有公开接口必须有权限控制
117
+
118
+ **实践**:
119
+ - 所有接口添加权限注解
120
+ - 按模块划分权限
121
+ - 按操作类型划分权限(查看、新增、修改、删除)
122
+ - 敏感操作增加二次验证
123
+
124
+ **权限分类**:
125
+ - 查看权限:list、query
126
+ - 操作权限:add、edit、remove
127
+ - 特殊权限:export、import、approve
128
+
129
+ ---
130
+
131
+ ### 4. 注释完整
132
+
133
+ **原则**:关键方法必须有完整注释
134
+
135
+ **实践**:
136
+ - 公开接口必须有注释
137
+ - 复杂业务逻辑必须有注释
138
+ - 工具方法必须有注释
139
+ - 注释说明用途、参数、返回值
140
+
141
+ **注释内容**:
142
+ - 方法用途和功能
143
+ - 参数说明(类型、含义、约束)
144
+ - 返回值说明
145
+ - 异常说明
146
+ - 使用示例(如需要)
147
+
148
+ ---
149
+
150
+ ### 5. 定期检查
151
+
152
+ **原则**:每周至少一次运行代码检查和进度查看
153
+
154
+ **实践**:
155
+ - 每周运行 `/check` 检查代码质量
156
+ - 每周运行 `/progress` 查看进度
157
+ - 每周运行 `/sync` 生成综合报告
158
+ - 及时修复发现的问题
159
+
160
+ **检查内容**:
161
+ - 代码规范问题
162
+ - TODO/FIXME 标记
163
+ - 代码重复
164
+ - 性能问题
165
+ - 安全问题
166
+
167
+ ---
168
+
169
+ ## 技术选型建议
170
+
171
+ ### 场景 1:快速生成 CRUD
172
+
173
+ **推荐方案**:`/crud` 命令
174
+
175
+ **适用条件**:
176
+ - 数据库表已存在
177
+ - 只需标准 CRUD 功能
178
+ - 无复杂业务逻辑
179
+
180
+ **优势**:
181
+ - 生成速度快
182
+ - 代码规范统一
183
+ - 减少重复工作
184
+
185
+ ---
186
+
187
+ ### 场景 2:从零开发功能
188
+
189
+ **推荐方案**:`/dev` 命令
190
+
191
+ **适用条件**:
192
+ - 表结构尚未设计
193
+ - 需要完整的开发流程
194
+ - 包含业务逻辑设计
195
+
196
+ **优势**:
197
+ - 包含表设计指导
198
+ - 完整的开发流程
199
+ - 考虑业务逻辑
200
+
201
+ ---
202
+
203
+ ### 场景 3:代码规范检查
204
+
205
+ **推荐方案**:`/check` 命令
206
+
207
+ **适用条件**:
208
+ - 开发完成后
209
+ - 定期检查
210
+ - 发现代码问题
211
+
212
+ **优势**:
213
+ - 及时发现问题
214
+ - 统一代码规范
215
+ - 提升代码质量
216
+
217
+ ---
218
+
219
+ ### 场景 4:项目进度追踪
220
+
221
+ **推荐方案**:`/progress` 命令
222
+
223
+ **适用条件**:
224
+ - 定期了解完成情况
225
+ - 评估工作量
226
+ - 规划下一步工作
227
+
228
+ **优势**:
229
+ - 清晰的进度展示
230
+ - 待办事项统计
231
+ - 完成率分析
232
+
233
+ ---
234
+
235
+ ### 场景 5:全量同步
236
+
237
+ **推荐方案**:`/sync` 命令
238
+
239
+ **适用条件**:
240
+ - 每周整理
241
+ - 发现数据不一致
242
+ - 生成综合报告
243
+
244
+ **优势**:
245
+ - 全量扫描
246
+ - 综合分析
247
+ - 生成报告
248
+
249
+ ---
250
+
251
+ ## 常见问题
252
+
253
+ ### Q1:什么时候使用 /crud,什么时候使用 /dev?
254
+
255
+ **A1**:
256
+ - 表已存在 → 使用 `/crud`
257
+ - 从零开始 → 使用 `/dev`
258
+ - 只需标准 CRUD → 使用 `/crud`
259
+ - 需要复杂业务逻辑 → 使用 `/dev`
260
+
261
+ ---
262
+
263
+ ### Q2:如何保证代码质量?
264
+
265
+ **A2**:
266
+ 1. 开发前:使用 `/check` 了解项目规范
267
+ 2. 开发中:遵循最佳实践
268
+ 3. 开发后:使用 `/check` 检查代码
269
+ 4. 定期:每周运行 `/check` 和 `/sync`
270
+
271
+ ---
272
+
273
+ ### Q3:如何管理待办事项?
274
+
275
+ **A3**:
276
+ 1. 发现任务:使用 `/add-todo` 立即记录
277
+ 2. 查看进度:使用 `/progress` 查看待办
278
+ 3. 获取建议:使用 `/next` 确定优先级
279
+ 4. 定期整理:每周清理已完成任务
280
+
281
+ ---
282
+
283
+ ### Q4:如何规划下一步工作?
284
+
285
+ **A4**:
286
+ 1. 使用 `/next` 获取建议
287
+ 2. 根据优先级排序
288
+ 3. 先处理高优先级任务
289
+ 4. 定期使用 `/progress` 查看进度
290
+
291
+ ---
292
+
293
+ ## 注意事项
294
+
295
+ 1. **遵循项目规范**:每个项目可能有特定的规范,优先遵循项目规范
296
+ 2. **保持代码一致性**:与现有代码保持一致的风格
297
+ 3. **及时记录待办**:发现问题立即记录,避免遗忘
298
+ 4. **定期检查代码**:每周至少一次代码检查
299
+ 5. **持续学习改进**:根据项目经验不断优化工作流
300
+
301
+ ---
302
+
303
+ ## 相关技能
304
+
305
+ - 如果是后端开发规范 → 使用 backend-development 技能
306
+ - 如果是数据库设计规范 → 使用 database-design 技能
307
+ - 如果是 API 设计规范 → 使用 api-design 技能