jarvis-agent-factory 3.48.2 → 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 +10 -6
- 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
|
|
|
@@ -37,9 +37,10 @@ jarvis web # 启动 Web 面板(按需)
|
|
|
37
37
|
|------|------|
|
|
38
38
|
| **MCP 编排引擎** | FSM 硬约束 Gate A→B→C→C1→C1.5→C2→D→E,跳过/回退被拒绝 |
|
|
39
39
|
| **零手动启动** | MCP stdio 自动拉起引擎,Claude Code 开箱即用 |
|
|
40
|
+
| **Agent Team 支持** | `jarvis init` 自动启用 `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS`,Team + SubAgent 混合编排 |
|
|
40
41
|
| **轻量编排** | `/jarvis-lite` 按任务类型智能映射 Gate 入口,跳过无关闸门 |
|
|
41
42
|
| **多流水线类型** | full / frontend / backend / lite / refactor / hotfix / migrate / evaluate / debug 九种模式,按需选择 |
|
|
42
|
-
|
|
|
43
|
+
| **项目级存储隔离** | `<project>/.jarvis/` 独立数据库 + PID,每个项目跨会话记忆不跨项目共享 |
|
|
43
44
|
| **会话管理** | 会话命名(MCP session_set_name)· 归档/删除 · 置顶 · 指令标签(/jarvis 等) |
|
|
44
45
|
| **Web 面板** | Hash 路由(#/dashboard #/archive #/agents)· SSE 实时推送 · 产物文档阅读器 · Gate Timeline · Agent 配置页 |
|
|
45
46
|
| **远程面板** | 单 HTML 文件下载即可打开,无需本地 web 构建 |
|
|
@@ -47,6 +48,7 @@ jarvis web # 启动 Web 面板(按需)
|
|
|
47
48
|
| **浏览器测试** | 文档驱动工作流:test-doc-writer → test-executor → fix-retest 闭环 |
|
|
48
49
|
| **智能安装** | Hash 对比只覆盖变更文件,用户自定义自动保留 |
|
|
49
50
|
| **智能 MCP 合并** | `jarvis upgrade` / `jarvis init` 增量合并 MCP 配置,不覆盖用户自定义服务 |
|
|
51
|
+
| **智能 env 合并** | `jarvis init` 增量合并 settings.json env,保护用户自定义环境变量 |
|
|
50
52
|
| **Hook/Plugin** | Claude Code hooks + MCP 全覆盖 |
|
|
51
53
|
| **平台扩展** | `platform_info` MCP 工具 + `/api/platforms` REST 端点 |
|
|
52
54
|
| **零原生依赖** | Node 22.5+ 内置 `node:sqlite`,安装秒级完成 |
|
|
@@ -298,8 +300,9 @@ test-doc-writer → test-executor → fix-retest
|
|
|
298
300
|
| | Claude Code |
|
|
299
301
|
|---|:--:|
|
|
300
302
|
| Agents | 69 |
|
|
301
|
-
| Commands |
|
|
303
|
+
| Commands | 33 |
|
|
302
304
|
| Skills | 34 |
|
|
305
|
+
| Pipeline | 9 条流水线(full/lite/frontend/backend/refactor/hotfix/migrate/evaluate/debug) |
|
|
303
306
|
| 钩子 | settings.json |
|
|
304
307
|
| MCP | `.mcp.json` |
|
|
305
308
|
|
|
@@ -313,12 +316,13 @@ test-doc-writer → test-executor → fix-retest
|
|
|
313
316
|
| 轻量入口跳转 | `gate_jump` MCP 工具(lite 模式) | 👆 编排者手动 |
|
|
314
317
|
| 跳过/回退 Gate 拒绝 | FSM 硬约束 | 🔄 自动 |
|
|
315
318
|
| 操作前 Gate 检查 | `gate_check` MCP 工具 | 🔄 自动 |
|
|
319
|
+
| Team/SubAgent 策略 | `pipeline_guide` → `team_strategy` + `agent_mode` | 👆 按需 |
|
|
316
320
|
| 流程指引 | `pipeline_guide` MCP 工具 | 👆 按需 |
|
|
317
321
|
| 平台信息 | `platform_info` MCP 工具 | 👆 按需 |
|
|
318
322
|
| 会话命名 | `session_set_name` MCP 工具 | 👆 按需 |
|
|
319
323
|
| 流水线状态 | Dashboard + SSE 实时推送 | 👆 按需 |
|
|
320
|
-
|
|
|
321
|
-
|
|
|
324
|
+
| 项目级会话隔离 | `<project>/.jarvis/engine.db` 独立数据库 | 🔄 自动 |
|
|
325
|
+
| Agent 配置 | Web 面板配置 → `.md`/`.toml` 文件同步 | 👆 保存时触发 |
|
|
322
326
|
|
|
323
327
|
## 发布流程
|
|
324
328
|
|
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