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 +2 -2
- package/dist/package.json +1 -1
- package/dist/src/cli/commands/remove.d.ts +1 -3
- package/dist/src/cli/commands/remove.js +202 -37
- package/dist/src/cli/commands/remove.js.map +1 -1
- package/dist/src/cli/utils/constants.js +4 -1
- package/dist/src/cli/utils/constants.js.map +1 -1
- package/dist/tests/remove-fine-grained.test.d.ts +1 -0
- package/dist/tests/remove-fine-grained.test.js +85 -0
- package/dist/tests/remove-fine-grained.test.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Jarvis Agent Factory · 贾维斯智能体工厂
|
|
2
2
|
|
|
3
3
|
[](./LICENSE)
|
|
4
|
-
[](https://github.com/Wjl1224734792/Jarvis-Agent-Factory/releases)
|
|
5
5
|
[](https://www.npmjs.com/package/jarvis-agent-factory)
|
|
6
6
|
[](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.
|
|
12
|
+
> **v3.49.0** — 细粒度 remove 命令 · 项目级存储隔离 · Agent Team 混合编排 · 33 条指令完整 frontmatter
|
|
13
13
|
|
|
14
14
|
## 快速开始
|
|
15
15
|
|
package/dist/package.json
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { CliOpts } from '../utils/args.js';
|
|
2
2
|
/**
|
|
3
|
-
* jarvis
|
|
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 {
|
|
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
|
-
*
|
|
15
|
+
* 加载 jarvis 安装时写入的 hash 记录
|
|
10
16
|
*/
|
|
11
|
-
function
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
|
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 (
|
|
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
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
74
|
-
|
|
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":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
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
|
|
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
|
|
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