airail 0.1.8 → 0.1.10

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
@@ -56,7 +56,7 @@ async function cmdAdd(arg) {
56
56
  throw new Error('');
57
57
  }
58
58
  const packName = path.basename(localPath);
59
- (0, utils_1.installPackFromDir)(localPath, packName, claudeDir);
59
+ (0, utils_1.installPackFromDir)(localPath, claudeDir);
60
60
  config.pack = packName;
61
61
  (0, utils_1.writeAirailJson)(claudeDir, config);
62
62
  console.log((0, colors_1.ok)(`已安装本地规范包: ${packName}`));
@@ -106,8 +106,17 @@ async function cmdAdd(arg) {
106
106
  });
107
107
  }
108
108
  if (config.pack) {
109
- console.log((0, colors_1.warn)(`当前已安装 pack: ${config.pack}`));
110
- console.log((0, colors_1.warn)('一个项目只能安装一个 pack,新 pack 将覆盖现有内容。'));
109
+ const [selectedName] = packNameWithVersion.split('@');
110
+ if (config.pack === selectedName) {
111
+ const yes = await (0, prompts_1.confirm)({ message: `已安装 ${config.pack},是否重新安装以更新?`, default: true });
112
+ if (!yes)
113
+ return;
114
+ }
115
+ else {
116
+ const yes = await (0, prompts_1.confirm)({ message: `当前已安装 ${config.pack},替换为 ${selectedName}?`, default: true });
117
+ if (!yes)
118
+ return;
119
+ }
111
120
  }
112
121
  await installPackFromConfigCenter(packNameWithVersion, claudeDir, config, packs);
113
122
  (0, utils_1.writeAirailJson)(claudeDir, config);
@@ -120,7 +129,7 @@ async function installGitPack(url, packName, claudeDir, config) {
120
129
  ? `git clone --depth 1 --branch ${ref} "${repoUrl}" "${tmpDir}"`
121
130
  : `git clone --depth 1 "${repoUrl}" "${tmpDir}"`;
122
131
  (0, child_process_1.execSync)(cloneCmd, { stdio: 'pipe' });
123
- (0, utils_1.installPackFromDir)(tmpDir, packName, claudeDir);
132
+ (0, utils_1.installPackFromDir)(tmpDir, claudeDir);
124
133
  config.pack = packName;
125
134
  console.log((0, colors_1.ok)(`已安装: ${packName} (来自 ${repoUrl})`));
126
135
  }
@@ -143,7 +152,8 @@ async function installPackFromConfigCenter(packNameWithVersion, claudeDir, confi
143
152
  console.error((0, colors_1.err)(`配置仓库中不存在本地规范包: packs/${packName}/`));
144
153
  throw new Error('');
145
154
  }
146
- (0, utils_1.installPackFromDir)(packDir, packName, claudeDir);
155
+ const oldPackDir = config.pack ? path.join(utils_1.CONFIG_REPO_DIR, 'packs', config.pack) : undefined;
156
+ (0, utils_1.installPackFromDir)(packDir, claudeDir, oldPackDir);
147
157
  config.pack = packName;
148
158
  console.log((0, colors_1.ok)(`已安装: ${pack.name}${pack.version ? ` v${pack.version}` : ''} (来自配置仓库)`));
149
159
  return;
package/dist/cli/index.js CHANGED
@@ -38,7 +38,6 @@ const readline = __importStar(require("readline"));
38
38
  const init_1 = require("./init");
39
39
  const add_1 = require("./add");
40
40
  const clear_1 = require("./clear");
41
- const update_1 = require("./update");
42
41
  const status_1 = require("./status");
43
42
  const config_1 = require("./config");
44
43
  const install_1 = require("./install");
@@ -63,7 +62,6 @@ function printHelp() {
63
62
  ['add <包名[@版本]|路径>', '安装规范包(从配置仓库或本地路径)'],
64
63
  ['install', '安装 CLI 工具'],
65
64
  ['clear', '清理 airail 相关内容'],
66
- ['update', '更新已安装的规范包'],
67
65
  ['config [子命令]', '管理团队配置仓库 (setup / list / use)'],
68
66
  ['status', '查看已安装的技能'],
69
67
  ['ver', '查看 airail 版本'],
@@ -80,7 +78,6 @@ async function executeCommand(cmd, args) {
80
78
  add: () => (0, add_1.cmdAdd)(args[0]),
81
79
  install: () => (0, install_1.cmdInstall)(),
82
80
  clear: clear_1.cmdClear,
83
- update: update_1.cmdUpdate,
84
81
  status: status_1.cmdStatus,
85
82
  config: () => (0, config_1.cmdConfig)(args[0], ...args.slice(1)),
86
83
  ver: version_1.cmdVersion,
package/dist/utils.js CHANGED
@@ -42,9 +42,7 @@ exports.requireAirailJson = requireAirailJson;
42
42
  exports.readRc = readRc;
43
43
  exports.writeRc = writeRc;
44
44
  exports.installPackFromDir = installPackFromDir;
45
- exports.installSkillsFromDir = installSkillsFromDir;
46
45
  exports.copyBuiltinSkills = copyBuiltinSkills;
47
- exports.removePackSkills = removePackSkills;
48
46
  exports.copyDir = copyDir;
49
47
  exports.copyHooks = copyHooks;
50
48
  exports.copyTemplateDir = copyTemplateDir;
@@ -143,42 +141,41 @@ function writeRc(patch) {
143
141
  fs.writeFileSync(RC_PATH, JSON.stringify({ ...current, ...patch }, null, 2));
144
142
  }
145
143
  // ─── pack 安装 ────────────────────────────────────────────────────────────────
144
+ const PACK_SUBDIRS = ['skills', 'commands', 'agents', 'hooks', 'templates'];
146
145
  /**
147
- * 安装 pack
148
- * - skills/ .claude/skills/(带 packName 前缀)
149
- * - commands/agents/hooks/templates/ → .claude/ 对应目录(全量覆盖)
146
+ * 按旧 pack 目录结构,删除 .claude/ 中对应的文件/目录
147
+ * 只删除旧 pack 里存在的条目,不影响其他文件
150
148
  */
151
- function installPackFromDir(packDir, packName, claudeDir) {
152
- // 删除旧 pack skills
153
- removePackSkills(claudeDir);
154
- // 安装新 pack skills
155
- installSkillsFromDir(packDir, packName, claudeDir);
156
- // 覆盖 commands / agents / hooks / templates
157
- for (const sub of ['commands', 'agents', 'hooks', 'templates']) {
158
- const src = path.join(packDir, sub);
159
- const dest = path.join(claudeDir, sub);
160
- if (fs.existsSync(src)) {
161
- fs.rmSync(dest, { recursive: true, force: true });
162
- copyDir(src, dest);
149
+ function removeOldPackFiles(oldPackDir, claudeDir) {
150
+ for (const sub of PACK_SUBDIRS) {
151
+ const srcSub = path.join(oldPackDir, sub);
152
+ const destSub = path.join(claudeDir, sub);
153
+ if (!fs.existsSync(srcSub) || !fs.existsSync(destSub))
154
+ continue;
155
+ for (const entry of fs.readdirSync(srcSub, { withFileTypes: true })) {
156
+ const target = path.join(destSub, entry.name);
157
+ if (fs.existsSync(target)) {
158
+ fs.rmSync(target, { recursive: true, force: true });
159
+ }
163
160
  }
164
161
  }
165
162
  }
166
- // ─── skills ───────────────────────────────────────────────────────────────────
167
- /** pack/skills/ 平铺复制到 .claude/skills/(带 packName 前缀) */
168
- function installSkillsFromDir(packDir, packName, claudeDir) {
169
- const skillsSrc = path.join(packDir, 'skills');
170
- if (!fs.existsSync(skillsSrc)) {
171
- console.warn(`规范包 "${packName}" 中未找到 skills/ 目录。`);
172
- return;
163
+ /**
164
+ * 安装 pack:pack 子目录与 .claude/ 1:1 对应,无前缀
165
+ * @param oldPackDir 旧 pack 目录(已知时传入,用于精确删除旧文件)
166
+ */
167
+ function installPackFromDir(packDir, claudeDir, oldPackDir) {
168
+ if (oldPackDir && fs.existsSync(oldPackDir)) {
169
+ removeOldPackFiles(oldPackDir, claudeDir);
173
170
  }
174
- const skillsDest = path.join(claudeDir, 'skills');
175
- fs.mkdirSync(skillsDest, { recursive: true });
176
- for (const entry of fs.readdirSync(skillsSrc, { withFileTypes: true })) {
177
- if (!entry.isDirectory())
178
- continue;
179
- copyDir(path.join(skillsSrc, entry.name), path.join(skillsDest, `${packName}-${entry.name}`));
171
+ for (const sub of PACK_SUBDIRS) {
172
+ const src = path.join(packDir, sub);
173
+ if (fs.existsSync(src)) {
174
+ copyDir(src, path.join(claudeDir, sub));
175
+ }
180
176
  }
181
177
  }
178
+ // ─── skills ───────────────────────────────────────────────────────────────────
182
179
  /** 复制内置 skills(templates/skills/ 下的所有子目录)到 .claude/skills/ */
183
180
  function copyBuiltinSkills(claudeDir) {
184
181
  const src = path.join(exports.PKG_ROOT, 'src/templates/skills');
@@ -194,19 +191,6 @@ function copyBuiltinSkills(claudeDir) {
194
191
  copyDir(path.join(src, entry.name), path.join(skillsDest, entry.name));
195
192
  }
196
193
  }
197
- /** 删除所有 pack 安装的 skills(即带 - 前缀的) */
198
- function removePackSkills(claudeDir) {
199
- const skillsDir = path.join(claudeDir, 'skills');
200
- if (!fs.existsSync(skillsDir))
201
- return;
202
- for (const entry of fs.readdirSync(skillsDir, { withFileTypes: true })) {
203
- if (!entry.isDirectory())
204
- continue;
205
- if (entry.name.includes('-')) {
206
- fs.rmSync(path.join(skillsDir, entry.name), { recursive: true, force: true });
207
- }
208
- }
209
- }
210
194
  // ─── 内置模板工具 ──────────────────────────────────────────────────────────────
211
195
  function copyDir(src, dest) {
212
196
  fs.mkdirSync(dest, { recursive: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "airail",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "AI coding assistant framework - enforce coding standards via Claude hooks & skills",
5
5
  "bin": {
6
6
  "airail": "./bin/airail.js"
@@ -1,51 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.cmdUpdate = cmdUpdate;
37
- const path = __importStar(require("path"));
38
- const utils_1 = require("../utils");
39
- const colors_1 = require("./colors");
40
- async function cmdUpdate() {
41
- const claudeDir = path.join(process.cwd(), '.claude');
42
- const config = (0, utils_1.requireAirailJson)(claudeDir);
43
- if (!config.pack) {
44
- console.error((0, colors_1.err)('未安装任何 pack,无需更新。'));
45
- throw new Error('');
46
- }
47
- // 从 airail.json 读取 pack 来源信息(需要扩展 AirailJson 结构)
48
- // 暂时简化:提示用户重新 add
49
- console.error((0, colors_1.err)('update 功能开发中,请使用 airail add 重新安装。'));
50
- throw new Error('');
51
- }