jarvis-agent-factory 3.48.3 → 3.49.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  # Jarvis Agent Factory · 贾维斯智能体工厂
2
2
 
3
3
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](./LICENSE)
4
- [![Version](https://img.shields.io/badge/version-v3.48.2-green)](https://github.com/Wjl1224734792/Jarvis-Agent-Factory/releases)
4
+ [![Version](https://img.shields.io/badge/version-v3.49.0-green)](https://github.com/Wjl1224734792/Jarvis-Agent-Factory/releases)
5
5
  [![npm](https://img.shields.io/npm/v/jarvis-agent-factory)](https://www.npmjs.com/package/jarvis-agent-factory)
6
6
  [![Visual Primitives MCP](https://img.shields.io/badge/DeepSeek-Visual%20Primitives%20MCP-purple)](https://github.com/Wjl1224734792/visual-primitives-mcp)
7
7
  <br>💡 **纯文本模型(如 DeepSeek)主力用户** → 搭配 [Visual Primitives MCP](https://github.com/Wjl1224734792/visual-primitives-mcp) 获得视觉理解能力
@@ -9,7 +9,7 @@
9
9
 
10
10
  AI 编程助手配置集 + MCP 编排引擎。从想法到交付的完整软件开发流水线,<br>**仅支持 Claude Code**。
11
11
 
12
- > **v3.48.2** — 项目级存储隔离 · Agent Team 混合编排 · 33 条指令完整 frontmatter · 9 条流水线工程级规范
12
+ > **v3.49.0** — 细粒度 remove 命令 · 项目级存储隔离 · Agent Team 混合编排 · 33 条指令完整 frontmatter
13
13
 
14
14
  ## 快速开始
15
15
 
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jarvis-agent-factory",
3
- "version": "3.48.3",
3
+ "version": "3.49.0",
4
4
  "description": "Jarvis Agent Factory CLI — Claude Code 多智能体 AI 编程助手配置安装器 | Multi-agent AI coding assistant config installer for Claude Code",
5
5
  "keywords": [
6
6
  "jarvis",
@@ -1,7 +1,5 @@
1
1
  import type { CliOpts } from '../utils/args.js';
2
2
  /**
3
- * jarvis remove <platform...> [path] — 从项目移除指定平台配置
4
- * 别名: jarvis rm
5
- * 若不指定平台参数,则默认移除全部平台
3
+ * 细粒度移除——只删除 jarvis 安装的文件,保护用户自定义内容
6
4
  */
7
5
  export declare function execute(opts: CliOpts, positional: string[]): Promise<void>;
@@ -1,39 +1,45 @@
1
- import { resolve } from 'node:path';
2
- import { existsSync, rmSync } from 'node:fs';
3
- import { homedir } from 'node:os';
1
+ import { resolve, join } from 'node:path';
2
+ import { existsSync, rmSync, readdirSync, statSync, readFileSync, writeFileSync } from 'node:fs';
4
3
  import { resolveScope } from '../utils/scope.js';
5
4
  import { resolveTarget } from '../utils/resolve.js';
6
5
  import { PLATFORMS, ALL_PLATFORMS, GLOBAL_ROOTS } from '../utils/constants.js';
7
- import { confirm } from '../utils/io.js';
6
+ import { getHashFilePath } from '../../hash-paths.js';
7
+ import { readMcpConfig } from '../../shared/mcp-config.js';
8
+ /** settings.json 中记录 jarvis 管理的 hook key 的字段 */
9
+ const MANAGED_HOOKS_KEY = '_jarvisManagedHooks';
10
+ /** 安装时使用的子目录列表 */
11
+ const INSTALL_BUCKETS = ['agents', 'commands', 'skills'];
12
+ /** MCP server 白名单:安装时添加的 server(仅删除这些) */
13
+ const JARVIS_MCP_SERVERS = new Set(['jarvis-engine', 'playwright']);
8
14
  /**
9
- * 移除平台的 MCP 配置文件
15
+ * 加载 jarvis 安装时写入的 hash 记录
10
16
  */
11
- function removeMcp(platform, target, isGlobal) {
12
- const files = {
13
- claude: '.mcp.json',
14
- opencode: 'opencode.json',
15
- codex: '.codex/config.toml',
16
- };
17
- const f = files[platform];
18
- if (!f)
19
- return;
20
- const dest = isGlobal ? resolve(homedir(), f) : resolve(target, f);
21
- if (existsSync(dest)) {
22
- rmSync(dest, { recursive: true, force: true });
23
- console.log(` - ${f.padEnd(18)} removed`);
17
+ function loadHashes(hashFilePath) {
18
+ try {
19
+ return existsSync(hashFilePath) ? JSON.parse(readFileSync(hashFilePath, 'utf-8')) : {};
20
+ }
21
+ catch {
22
+ return {};
24
23
  }
25
24
  }
26
25
  /**
27
- * jarvis remove <platform...> [path] — 从项目移除指定平台配置
28
- * 别名: jarvis rm
29
- * 若不指定平台参数,则默认移除全部平台
26
+ * 细粒度移除——只删除 jarvis 安装的文件,保护用户自定义内容
30
27
  */
31
28
  export async function execute(opts, positional) {
32
29
  const platforms = [];
33
30
  let path = '.';
31
+ let dryRun = false;
32
+ let listOnly = false;
33
+ // 解析参数
34
34
  for (let i = 1; i < positional.length; i++) {
35
35
  const p = positional[i];
36
- if (PLATFORMS[p]) {
36
+ if (p === '--dry-run') {
37
+ dryRun = true;
38
+ }
39
+ else if (p === '--list') {
40
+ listOnly = true;
41
+ }
42
+ else if (PLATFORMS[p]) {
37
43
  platforms.push(p);
38
44
  }
39
45
  else if (!p.startsWith('-')) {
@@ -41,8 +47,7 @@ export async function execute(opts, positional) {
41
47
  }
42
48
  }
43
49
  if (platforms.length === 0) {
44
- if (positional.length === 1) {
45
- // 无平台参数时默认移除全部平台
50
+ if (positional.length <= 1 + (dryRun ? 1 : 0) + (listOnly ? 1 : 0)) {
46
51
  platforms.push(...ALL_PLATFORMS);
47
52
  }
48
53
  else {
@@ -53,27 +58,187 @@ export async function execute(opts, positional) {
53
58
  }
54
59
  const isGlobal = await resolveScope(opts);
55
60
  const target = resolveTarget(path, isGlobal);
61
+ const hashFilePath = getHashFilePath(target, isGlobal);
62
+ const hashes = loadHashes(hashFilePath);
63
+ if (listOnly) {
64
+ console.log(`\n📋 Jarvis-tracked files — ${isGlobal ? '~ (全局)' : target}\n`);
65
+ printTrackedFiles(platforms, target, isGlobal, hashes);
66
+ return;
67
+ }
68
+ const mode = dryRun ? '🔍 DRY RUN' : '🗑';
69
+ console.log(`\n${mode} Removing jarvis-installed configs — ${isGlobal ? '~ (全局)' : target}\n`);
70
+ let totalRemoved = 0;
56
71
  for (const name of platforms) {
57
72
  const dir = isGlobal
58
73
  ? GLOBAL_ROOTS[name]
59
74
  : resolve(target, PLATFORMS[name].dir);
60
- if (existsSync(dir)) {
61
- if (!opts.yes) {
62
- const ok = await confirm(` Remove ${dir}? [y/N] `);
63
- if (!ok) {
64
- console.log(` ⏭ Skipped ${name}`);
65
- continue;
75
+ if (!existsSync(dir)) {
76
+ console.log(` ⏭ ${PLATFORMS[name].dir.padEnd(10)} not found`);
77
+ continue;
78
+ }
79
+ // 按 bucket 细粒度删除:只删除 hash 记录匹配的文件
80
+ for (const bucket of INSTALL_BUCKETS) {
81
+ const bucketDir = join(dir, bucket);
82
+ if (!existsSync(bucketDir))
83
+ continue;
84
+ totalRemoved += removeBucketFiles(bucketDir, hashes, dryRun);
85
+ }
86
+ // 细粒度移除 settings.json 中的 jarvis hooks 和 env
87
+ removeJarvisSettings(dir, dryRun);
88
+ // 细粒度移除 MCP 配置中 jarvis 相关的 server
89
+ removeJarvisMcp(name, target, isGlobal, dryRun);
90
+ }
91
+ // 清理 hash 记录文件本身
92
+ if (!dryRun && existsSync(hashFilePath)) {
93
+ rmSync(hashFilePath);
94
+ console.log(` - ${hashFilePath}`);
95
+ totalRemoved++;
96
+ }
97
+ console.log(`\n✅ ${dryRun ? 'DRY RUN complete (no changes made)' : 'Done!'} (${totalRemoved} items removed)\n`);
98
+ }
99
+ /**
100
+ * 删除目录中 hash 匹配的 jarvis 安装文件
101
+ */
102
+ function removeBucketFiles(bucketDir, hashes, dryRun) {
103
+ let removed = 0;
104
+ try {
105
+ const entries = readdirSync(bucketDir);
106
+ for (const entry of entries) {
107
+ const fullPath = join(bucketDir, entry);
108
+ const isDir = statSync(fullPath).isDirectory();
109
+ if (isDir) {
110
+ // 递归处理 skills 子目录
111
+ removed += removeBucketFiles(fullPath, hashes, dryRun);
112
+ }
113
+ else {
114
+ // 只删除 hash 记录中存在的文件(jarvis 安装的)
115
+ if (hashes[fullPath]) {
116
+ if (!dryRun)
117
+ rmSync(fullPath);
118
+ console.log(` - ${entry}`);
119
+ removed++;
66
120
  }
67
121
  }
68
- rmSync(dir, { recursive: true, force: true });
69
- console.log(` - ${PLATFORMS[name].dir.padEnd(10)} removed`);
70
- // 同时移除 MCP 配置
71
- removeMcp(name, target, isGlobal);
72
122
  }
73
- else {
74
- console.log(` ⏭ ${PLATFORMS[name].dir.padEnd(10)} not found`);
123
+ // 删除空目录
124
+ try {
125
+ const remaining = readdirSync(bucketDir);
126
+ if (remaining.length === 0 && !dryRun) {
127
+ rmSync(bucketDir, { recursive: true });
128
+ }
129
+ }
130
+ catch { /* ignore */ }
131
+ }
132
+ catch { /* ignore */ }
133
+ return removed;
134
+ }
135
+ /**
136
+ * 细粒度移除 settings.json 中 jarvis 管理的 hooks 和 env
137
+ */
138
+ function removeJarvisSettings(claudeDir, dryRun) {
139
+ const settingsFile = join(claudeDir, 'settings.json');
140
+ if (!existsSync(settingsFile))
141
+ return;
142
+ try {
143
+ const content = readFileSync(settingsFile, 'utf-8');
144
+ const settings = JSON.parse(content);
145
+ let changed = false;
146
+ // 移除 jarvis 管理的 hooks
147
+ const managedHooks = Array.isArray(settings[MANAGED_HOOKS_KEY]) ? settings[MANAGED_HOOKS_KEY] : [];
148
+ if (managedHooks.length > 0 && settings.hooks) {
149
+ for (const key of managedHooks) {
150
+ if (key in (settings.hooks || {})) {
151
+ delete settings.hooks[key];
152
+ console.log(` - settings.json hooks.${key}`);
153
+ changed = true;
154
+ }
155
+ }
156
+ if (settings.hooks && Object.keys(settings.hooks).length === 0) {
157
+ delete settings.hooks;
158
+ }
159
+ }
160
+ // 移除 jarvis 新增的 env 项(保留用户自定义的)
161
+ const jarvisEnvKeys = ['CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS'];
162
+ if (settings.env) {
163
+ for (const key of jarvisEnvKeys) {
164
+ if (key in settings.env) {
165
+ delete settings.env[key];
166
+ console.log(` - settings.json env.${key}`);
167
+ changed = true;
168
+ }
169
+ }
170
+ if (Object.keys(settings.env).length === 0) {
171
+ delete settings.env;
172
+ }
173
+ }
174
+ // 移除 hook 管理标记
175
+ if (MANAGED_HOOKS_KEY in settings) {
176
+ delete settings[MANAGED_HOOKS_KEY];
177
+ changed = true;
178
+ }
179
+ if (changed && !dryRun) {
180
+ writeFileSync(settingsFile, JSON.stringify(settings, null, 2) + '\n');
181
+ }
182
+ }
183
+ catch { /* ignore */ }
184
+ }
185
+ /**
186
+ * 细粒度移除 MCP 配置中 jarvis 安装的 server 条目
187
+ */
188
+ function removeJarvisMcp(platform, target, isGlobal, dryRun) {
189
+ if (platform !== 'claude')
190
+ return;
191
+ const projectRoot = isGlobal ? GLOBAL_ROOTS.claude : target;
192
+ const mcpFile = resolve(projectRoot, '.mcp.json');
193
+ if (!existsSync(mcpFile))
194
+ return;
195
+ try {
196
+ const existing = readMcpConfig(projectRoot);
197
+ if (!existing)
198
+ return;
199
+ const mcpKey = existing.mcpServers ? 'mcpServers' : 'mcp';
200
+ const servers = existing[mcpKey];
201
+ if (!servers)
202
+ return;
203
+ let changed = false;
204
+ for (const name of JARVIS_MCP_SERVERS) {
205
+ if (name in servers) {
206
+ delete servers[name];
207
+ console.log(` - ${mcpKey}.${name}`);
208
+ changed = true;
209
+ }
210
+ }
211
+ if (changed) {
212
+ if (Object.keys(servers).length === 0) {
213
+ delete existing[mcpKey];
214
+ }
215
+ if (!dryRun) {
216
+ writeFileSync(mcpFile, JSON.stringify(existing, null, 2) + '\n');
217
+ }
218
+ }
219
+ }
220
+ catch { /* ignore */ }
221
+ }
222
+ /**
223
+ * 列出 jarvis 跟踪的文件
224
+ */
225
+ function printTrackedFiles(platforms, target, isGlobal, hashes) {
226
+ const trackedFiles = Object.keys(hashes).filter(f => {
227
+ for (const name of platforms) {
228
+ const dir = isGlobal ? GLOBAL_ROOTS[name] : resolve(target, PLATFORMS[name]?.dir || '');
229
+ if (f.startsWith(dir))
230
+ return true;
231
+ }
232
+ return false;
233
+ });
234
+ if (trackedFiles.length === 0) {
235
+ console.log(' (no tracked files found)');
236
+ }
237
+ else {
238
+ for (const f of trackedFiles) {
239
+ console.log(` ${f}`);
75
240
  }
241
+ console.log(`\n Total: ${trackedFiles.length} files`);
76
242
  }
77
- console.log(`\n✅ Done!\n`);
78
243
  }
79
244
  //# sourceMappingURL=remove.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"remove.js","sourceRoot":"","sources":["../../../../src/cli/commands/remove.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"remove.js","sourceRoot":"","sources":["../../../../src/cli/commands/remove.ts"],"names":[],"mappings":"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"}
@@ -55,7 +55,7 @@ Usage:
55
55
  jarvis [path] ≡ jarvis init [path]
56
56
  jarvis init [path] Bootstrap project with all platforms + MCP
57
57
  jarvis add <p...> [path] Add platform(s) to project
58
- jarvis remove <p...> [path] Remove platform(s) from project
58
+ jarvis remove [p...] [path] Fine-grained remove (hash-aware, only jarvis-installed)
59
59
  jarvis upgrade [path] Upgrade to latest config version
60
60
  jarvis diff [path] Show what files would change on upgrade
61
61
  jarvis engine start [--port=N] Start MCP orchestration engine
@@ -80,6 +80,9 @@ Examples:
80
80
  jarvis init my-app Bootstrap new project
81
81
  jarvis add claude Add Claude Code to current directory
82
82
  jarvis add claude -g Add Claude Code globally
83
+ jarvis remove claude Fine-grained remove (only jarvis-installed files)
84
+ jarvis remove --dry-run Preview what would be removed
85
+ jarvis remove --list List jarvis-tracked files
83
86
  jarvis engine start Start MCP orchestration engine
84
87
  jarvis web Start web dashboard (≡ engine start)
85
88
  jarvis upgrade Upgrade all configs
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/cli/utils/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC;;;GAGG;AACH,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,SAAS,WAAW,CAAC,QAAgB;IACnC,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;YAC5E,8CAA8C;YAC9C,IAAI,GAAG,CAAC,IAAI,KAAK,sBAAsB,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;gBAC5E,OAAO,GAAG,CAAC;YACb,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;QAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAClC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,yCAAyC;IACzC,OAAO,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;AAE/C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AACjF,MAAM,CAAC,MAAM,WAAW,GAAW,GAAG,CAAC,OAAO,CAAC;AAC/C,MAAM,CAAC,MAAM,QAAQ,GAAW,GAAG,CAAC,IAAI,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,SAAS,GAAkD;IACtE,MAAM,EAAI,EAAE,GAAG,EAAE,SAAS,EAAG,IAAI,EAAE,mDAAmD,EAAE;IACxF,QAAQ,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,oDAAoD,EAAE;IAC1F,KAAK,EAAK,EAAE,GAAG,EAAE,QAAQ,EAAI,IAAI,EAAE,iDAAiD,EAAE;CACvF,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAEpD;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,4BAA4B,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;eAyBjC,SAAS,CAAC,MAAM,CAAC,IAAI;eACrB,SAAS,CAAC,QAAQ,CAAC,IAAI;eACvB,SAAS,CAAC,KAAK,CAAC,IAAI;;;;;;;;;;;CAWlC,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAA2B;IAClD,MAAM,EAAI,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC;IACvC,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC;IACnD,KAAK,EAAK,OAAO,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC;CACvC,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/cli/utils/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC;;;GAGG;AACH,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,SAAS,WAAW,CAAC,QAAgB;IACnC,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;YAC5E,8CAA8C;YAC9C,IAAI,GAAG,CAAC,IAAI,KAAK,sBAAsB,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;gBAC5E,OAAO,GAAG,CAAC;YACb,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;QAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAClC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,yCAAyC;IACzC,OAAO,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;AAE/C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AACjF,MAAM,CAAC,MAAM,WAAW,GAAW,GAAG,CAAC,OAAO,CAAC;AAC/C,MAAM,CAAC,MAAM,QAAQ,GAAW,GAAG,CAAC,IAAI,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,SAAS,GAAkD;IACtE,MAAM,EAAI,EAAE,GAAG,EAAE,SAAS,EAAG,IAAI,EAAE,mDAAmD,EAAE;IACxF,QAAQ,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,oDAAoD,EAAE;IAC1F,KAAK,EAAK,EAAE,GAAG,EAAE,QAAQ,EAAI,IAAI,EAAE,iDAAiD,EAAE;CACvF,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAEpD;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,4BAA4B,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;eAyBjC,SAAS,CAAC,MAAM,CAAC,IAAI;eACrB,SAAS,CAAC,QAAQ,CAAC,IAAI;eACvB,SAAS,CAAC,KAAK,CAAC,IAAI;;;;;;;;;;;;;;CAclC,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAA2B;IAClD,MAAM,EAAI,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC;IACvC,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC;IACnD,KAAK,EAAK,OAAO,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC;CACvC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,85 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { resolve, join } from 'node:path';
3
+ import { existsSync, mkdirSync, rmSync, writeFileSync, readFileSync } from 'node:fs';
4
+ import { tmpdir } from 'node:os';
5
+ import { getHashFilePath } from '../src/hash-paths.js';
6
+ const TEST_DIR = resolve(tmpdir(), `jarvis-remove-test-${Date.now()}`);
7
+ describe('fine-grained remove', () => {
8
+ beforeEach(() => {
9
+ if (existsSync(TEST_DIR))
10
+ rmSync(TEST_DIR, { recursive: true });
11
+ mkdirSync(TEST_DIR, { recursive: true });
12
+ });
13
+ afterEach(() => {
14
+ if (existsSync(TEST_DIR))
15
+ rmSync(TEST_DIR, { recursive: true });
16
+ });
17
+ it('should track installed files via hash records', () => {
18
+ // Simulate what install does: write hash records
19
+ const hashFile = getHashFilePath(TEST_DIR, false);
20
+ const agentsDir = join(TEST_DIR, '.claude', 'agents');
21
+ mkdirSync(agentsDir, { recursive: true });
22
+ // Create a "jarvis-installed" file
23
+ const agentFile = join(agentsDir, 'test-agent.md');
24
+ writeFileSync(agentFile, '---\ndescription: test\n---\n# Test Agent');
25
+ // Record hash
26
+ const hashes = {};
27
+ hashes[agentFile] = 'abc123';
28
+ const hashDir = resolve(hashFile, '..');
29
+ if (!existsSync(hashDir))
30
+ mkdirSync(hashDir, { recursive: true });
31
+ writeFileSync(hashFile, JSON.stringify(hashes, null, 2));
32
+ // Verify hash file exists and tracks the file
33
+ expect(existsSync(hashFile)).toBe(true);
34
+ const loaded = JSON.parse(readFileSync(hashFile, 'utf-8'));
35
+ expect(loaded[agentFile]).toBe('abc123');
36
+ });
37
+ it('should preserve user custom files not in hash records', () => {
38
+ const agentsDir = join(TEST_DIR, '.claude', 'agents');
39
+ mkdirSync(agentsDir, { recursive: true });
40
+ // Jarvis-installed file (tracked)
41
+ const jarvisFile = join(agentsDir, 'jarvis-agent.md');
42
+ writeFileSync(jarvisFile, '# jarvis agent');
43
+ // User's custom file (not tracked)
44
+ const userFile = join(agentsDir, 'my-custom-agent.md');
45
+ writeFileSync(userFile, '# my agent');
46
+ // Hash records only track jarvis file
47
+ const hashFile = getHashFilePath(TEST_DIR, false);
48
+ const hashes = {};
49
+ hashes[jarvisFile] = 'def456';
50
+ const hashDir = resolve(hashFile, '..');
51
+ if (!existsSync(hashDir))
52
+ mkdirSync(hashDir, { recursive: true });
53
+ writeFileSync(hashFile, JSON.stringify(hashes, null, 2));
54
+ // Simulate remove: only delete tracked files
55
+ const loaded = JSON.parse(readFileSync(hashFile, 'utf-8'));
56
+ // Jarvis file tracked → should be removable
57
+ expect(loaded[jarvisFile]).toBeDefined();
58
+ // User file NOT tracked → should NOT be in hash records
59
+ expect(loaded[userFile]).toBeUndefined();
60
+ // Verify both files still exist (hash-based removal only deletes tracked)
61
+ expect(existsSync(jarvisFile)).toBe(true);
62
+ expect(existsSync(userFile)).toBe(true);
63
+ });
64
+ it('should track settings.json managed hooks', () => {
65
+ const claudeDir = join(TEST_DIR, '.claude');
66
+ mkdirSync(claudeDir, { recursive: true });
67
+ const settings = {
68
+ env: { CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: '1' },
69
+ hooks: {
70
+ PostToolUse: [{ matcher: 'Agent', hooks: [{ type: 'command', command: 'jarvis hook gate-check' }] }],
71
+ Stop: [{ hooks: [{ type: 'command', command: 'jarvis hook status' }] }],
72
+ },
73
+ _jarvisManagedHooks: ['PostToolUse', 'Stop'],
74
+ permissions: { allow: ['Bash(git:*)'] },
75
+ };
76
+ writeFileSync(join(claudeDir, 'settings.json'), JSON.stringify(settings, null, 2));
77
+ // Verify managed hooks are tracked
78
+ const loaded = JSON.parse(readFileSync(join(claudeDir, 'settings.json'), 'utf-8'));
79
+ expect(loaded._jarvisManagedHooks).toEqual(['PostToolUse', 'Stop']);
80
+ expect(loaded.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS).toBe('1');
81
+ // User's custom permissions should be preserved
82
+ expect(loaded.permissions.allow).toContain('Bash(git:*)');
83
+ });
84
+ });
85
+ //# sourceMappingURL=remove-fine-grained.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-fine-grained.test.js","sourceRoot":"","sources":["../../tests/remove-fine-grained.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jarvis-agent-factory",
3
- "version": "3.48.3",
3
+ "version": "3.49.0",
4
4
  "description": "Jarvis Agent Factory CLI — Claude Code 多智能体 AI 编程助手配置安装器 | Multi-agent AI coding assistant config installer for Claude Code",
5
5
  "keywords": [
6
6
  "jarvis",