sp-rag 0.6.11 → 0.6.12
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 +38 -22
- package/dist/cli.js +63 -8
- package/dist/lib/config-store.js +6 -1
- package/dist/lib/mcp-config.js +96 -0
- package/dist/lib/skill.js +36 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ CLI để setup nhanh SP-RAG theo hướng dev-friendly:
|
|
|
17
17
|
## Trạng thái package
|
|
18
18
|
|
|
19
19
|
- package npm public: `sp-rag`
|
|
20
|
-
- version đang publish: `0.6.
|
|
20
|
+
- version đang publish: `0.6.12`
|
|
21
21
|
- binary public: `sp-rag`
|
|
22
22
|
|
|
23
23
|
## Cài từ source trong monorepo
|
|
@@ -36,8 +36,10 @@ node dist/index.js doctor
|
|
|
36
36
|
npx sp-rag@latest install --client codex --mcp-token <grc_pat_...> --doctor
|
|
37
37
|
npx sp-rag@latest install --client cursor --scope project --cwd D:/Webs/seo-booster --mcp-token <grc_pat_...>
|
|
38
38
|
npx sp-rag@latest install --client vscode --scope project --cwd D:/Webs/seo-booster --mcp-token <grc_pat_...>
|
|
39
|
-
npx sp-rag@latest add --client claude-code --scope project --cwd D:/Webs/seo-booster
|
|
40
|
-
npx sp-rag@latest
|
|
39
|
+
npx sp-rag@latest add --client claude-code --scope project --cwd D:/Webs/seo-booster
|
|
40
|
+
npx sp-rag@latest update --client claude-code --scope project --cwd D:/Webs/seo-booster
|
|
41
|
+
npx sp-rag@latest uninstall --client claude-code --scope project --cwd D:/Webs/seo-booster
|
|
42
|
+
npx sp-rag@latest explain --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
41
43
|
npx sp-rag@latest token add --token <grc_pat_...>
|
|
42
44
|
npx sp-rag@latest token verify --token <grc_pat_...>
|
|
43
45
|
npx sp-rag@latest mcp add antigravity
|
|
@@ -50,8 +52,10 @@ Tương đương bằng `npm`:
|
|
|
50
52
|
|
|
51
53
|
```bash
|
|
52
54
|
npm exec --yes sp-rag@latest install -- --client codex --mcp-token <grc_pat_...> --doctor
|
|
53
|
-
npm exec --yes sp-rag@latest add -- --client claude-code --scope project --cwd D:/Webs/seo-booster
|
|
54
|
-
npm exec --yes sp-rag@latest
|
|
55
|
+
npm exec --yes sp-rag@latest add -- --client claude-code --scope project --cwd D:/Webs/seo-booster
|
|
56
|
+
npm exec --yes sp-rag@latest update -- --client claude-code --scope project --cwd D:/Webs/seo-booster
|
|
57
|
+
npm exec --yes sp-rag@latest uninstall -- --client claude-code --scope project --cwd D:/Webs/seo-booster
|
|
58
|
+
npm exec --yes sp-rag@latest explain -- --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
55
59
|
npm exec --yes sp-rag@latest token add -- --token <grc_pat_...>
|
|
56
60
|
npm exec --yes sp-rag@latest token verify -- --token <grc_pat_...>
|
|
57
61
|
```
|
|
@@ -61,24 +65,29 @@ npm exec --yes sp-rag@latest token verify -- --token <grc_pat_...>
|
|
|
61
65
|
Flow khuyên dùng sau khi đã có `grc_pat_*`:
|
|
62
66
|
|
|
63
67
|
1. chạy `install` đúng một lần cho client đầu tiên, có kèm `--mcp-token`
|
|
64
|
-
2. từ lần sau, dùng `add --client ...` để cài thêm MCP + skill cho client khác mà không phải nhập lại token
|
|
65
|
-
3. khi
|
|
66
|
-
4. khi
|
|
67
|
-
5. khi muốn
|
|
68
|
+
2. từ lần sau, dùng `add --client ...` để cài thêm MCP + skill cho client khác mà không phải nhập lại token
|
|
69
|
+
3. khi muốn cập nhật lại MCP + skill mà giữ token cũ, dùng `update`
|
|
70
|
+
4. khi muốn gỡ sạch MCP + skill + config CLI do `sp-rag` tạo, dùng `uninstall`
|
|
71
|
+
5. khi chỉ muốn làm một nửa, dùng `mcp add` hoặc `skill install`
|
|
72
|
+
6. khi đổi token, chỉ cần `token add`
|
|
73
|
+
7. khi muốn kiểm tra máy đang được cấu hình ra sao, dùng `explain`
|
|
68
74
|
|
|
69
75
|
Ghi chú:
|
|
70
76
|
|
|
71
|
-
- với `cursor` và `vscode` ở `scope project`, nếu Sếpp đang đứng sẵn trong repo thì có thể bỏ `--cwd`
|
|
72
|
-
- CLI sẽ tự dùng thư mục hiện tại cho cả MCP lẫn skill
|
|
73
|
-
-
|
|
77
|
+
- với `cursor` và `vscode` ở `scope project`, nếu Sếpp đang đứng sẵn trong repo thì có thể bỏ `--cwd`
|
|
78
|
+
- CLI sẽ tự dùng thư mục hiện tại cho cả MCP lẫn skill
|
|
79
|
+
- `update` sẽ tự tính lại target project từ `--cwd` hoặc thư mục hiện tại, không dùng target cũ lệch project nếu user không truyền `--target-dir`
|
|
80
|
+
- rule/agent mới đã được tăng độ ưu tiên MCP-first, giảm khả năng model nhảy thẳng sang grep/read file local
|
|
74
81
|
- skill mới cũng dặn model tổng hợp từ `matched_passages`, `top_entities`, `top_relations`, `citations`; không bê nguyên `answer_brief`
|
|
75
82
|
|
|
76
83
|
Ví dụ:
|
|
77
84
|
|
|
78
85
|
```bash
|
|
79
|
-
sp-rag install --client vscode --scope project --cwd D:/Webs/seo-booster --mcp-token <grc_pat_...> --doctor
|
|
80
|
-
sp-rag add --client cursor --scope project --cwd D:/Webs/seo-booster
|
|
81
|
-
sp-rag
|
|
86
|
+
sp-rag install --client vscode --scope project --cwd D:/Webs/seo-booster --mcp-token <grc_pat_...> --doctor
|
|
87
|
+
sp-rag add --client cursor --scope project --cwd D:/Webs/seo-booster
|
|
88
|
+
sp-rag update --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
89
|
+
sp-rag uninstall --client claude-code --scope project --cwd D:/Webs/seo-booster
|
|
90
|
+
sp-rag mcp add antigravity
|
|
82
91
|
sp-rag skill install --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
83
92
|
sp-rag token add --token <grc_pat_moi>
|
|
84
93
|
sp-rag explain --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
@@ -186,7 +195,8 @@ Ghi chú:
|
|
|
186
195
|
### Skill / rule / custom agent
|
|
187
196
|
|
|
188
197
|
- `codex`: `~/.codex/skills/sp-rag/SKILL.md`
|
|
189
|
-
- `claude-code
|
|
198
|
+
- `claude-code` project: `.claude/skills/sp-rag/SKILL.md`
|
|
199
|
+
- `claude-code` global skill-only override: `~/.claude/skills/sp-rag/SKILL.md`
|
|
190
200
|
- `antigravity`: `~/.gemini/antigravity/skills/sp-rag/SKILL.md`
|
|
191
201
|
- `opencode`: `~/.config/opencode/skills/sp-rag/SKILL.md`
|
|
192
202
|
- `cursor` project: `.cursor/rules/sp-rag.mdc`
|
|
@@ -197,8 +207,10 @@ Ghi chú:
|
|
|
197
207
|
|
|
198
208
|
```bash
|
|
199
209
|
sp-rag install --client codex --mcp-token <grc_pat_...> --doctor
|
|
200
|
-
sp-rag add --client cursor --scope project --cwd D:/Webs/seo-booster
|
|
201
|
-
sp-rag
|
|
210
|
+
sp-rag add --client cursor --scope project --cwd D:/Webs/seo-booster
|
|
211
|
+
sp-rag update --client cursor --scope project --cwd D:/Webs/seo-booster
|
|
212
|
+
sp-rag uninstall --client cursor --scope project --cwd D:/Webs/seo-booster
|
|
213
|
+
sp-rag explain --client codex
|
|
202
214
|
sp-rag token add --token <grc_pat_...>
|
|
203
215
|
sp-rag token verify --token <grc_pat_...>
|
|
204
216
|
sp-rag config show
|
|
@@ -212,8 +224,10 @@ sp-rag mcp add vscode --scope project --cwd D:/Webs/seo-booster
|
|
|
212
224
|
sp-rag mcp add opencode --scope project --cwd D:/Webs/seo-booster
|
|
213
225
|
sp-rag skill install --client codex
|
|
214
226
|
sp-rag skill install --client cursor --scope project --cwd D:/Webs/seo-booster
|
|
215
|
-
sp-rag skill install --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
216
|
-
sp-rag eval run --file ./examples/eval-suite.sample.json
|
|
227
|
+
sp-rag skill install --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
228
|
+
sp-rag eval run --file ./examples/eval-suite.sample.json
|
|
229
|
+
sp-rag update --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
230
|
+
sp-rag uninstall --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
217
231
|
```
|
|
218
232
|
|
|
219
233
|
## Lệnh chính
|
|
@@ -240,8 +254,10 @@ sp-rag mcp add opencode --scope project --cwd D:/Webs/seo-booster
|
|
|
240
254
|
sp-rag skill install --client codex
|
|
241
255
|
sp-rag skill install --client cursor --scope project --cwd D:/Webs/seo-booster
|
|
242
256
|
sp-rag skill install --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
243
|
-
sp-rag eval run --file ./examples/eval-suite.sample.json
|
|
244
|
-
sp-rag update
|
|
257
|
+
sp-rag eval run --file ./examples/eval-suite.sample.json
|
|
258
|
+
sp-rag update --client codex
|
|
259
|
+
sp-rag update setup --client codex
|
|
260
|
+
sp-rag uninstall --client codex
|
|
245
261
|
```
|
|
246
262
|
|
|
247
263
|
## `doctor` kiểm gì
|
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
|
-
import { loadCliConfig, saveCliConfig, } from './lib/config-store.js';
|
|
2
|
+
import { clearCliConfig, loadCliConfig, saveCliConfig, } from './lib/config-store.js';
|
|
3
3
|
import { runEvaluationSuite } from './lib/eval.js';
|
|
4
|
-
import { defaultBaseUrl, defaultMcpServerAlias, defaultMcpUrl, installMcpConfig, resolveMcpConfigPath, } from './lib/mcp-config.js';
|
|
4
|
+
import { defaultBaseUrl, defaultMcpServerAlias, defaultMcpUrl, installMcpConfig, removeMcpConfig, resolveMcpConfigPath, } from './lib/mcp-config.js';
|
|
5
5
|
import { diagnoseMcpConfig, formatMcpDoctorResult } from './lib/doctor.js';
|
|
6
6
|
import { fetchJson, fetchText, runDoctor } from './lib/http.js';
|
|
7
|
-
import { installSkill, resolveSkillInstallTarget, } from './lib/skill.js';
|
|
7
|
+
import { installSkill, removeSkill, resolveSkillInstallTarget, } from './lib/skill.js';
|
|
8
8
|
let cliVersionPromise;
|
|
9
9
|
async function resolveCliVersion() {
|
|
10
10
|
if (!cliVersionPromise) {
|
|
@@ -205,9 +205,11 @@ function helpText() {
|
|
|
205
205
|
return `sp-rag - CLI cho setup, MCP, codegraph, eval và skill của SP-RAG
|
|
206
206
|
|
|
207
207
|
Lệnh chính:
|
|
208
|
-
sp-rag install --client codex|cursor|claude-code|antigravity|vscode|opencode [--base-url URL] [--mcp-url URL] [--scope global|project] [--mcp-token TOKEN] [--auth-env-var ENV_VAR] [--target-dir PATH] [--doctor]
|
|
209
|
-
sp-rag add --client codex|cursor|claude-code|antigravity|vscode|opencode [--scope global|project] [--cwd PATH] [--target-dir PATH]
|
|
210
|
-
sp-rag
|
|
208
|
+
sp-rag install --client codex|cursor|claude-code|antigravity|vscode|opencode [--base-url URL] [--mcp-url URL] [--scope global|project] [--mcp-token TOKEN] [--auth-env-var ENV_VAR] [--target-dir PATH] [--doctor]
|
|
209
|
+
sp-rag add --client codex|cursor|claude-code|antigravity|vscode|opencode [--scope global|project] [--cwd PATH] [--target-dir PATH]
|
|
210
|
+
sp-rag update [--client codex|cursor|claude-code|antigravity|vscode|opencode] [--scope global|project] [--cwd PATH] [--target-dir PATH] [--doctor]
|
|
211
|
+
sp-rag uninstall [--client codex|cursor|claude-code|antigravity|vscode|opencode] [--scope global|project] [--cwd PATH] [--target-dir PATH]
|
|
212
|
+
sp-rag init [--base-url URL] [--mcp-url URL] [--client codex|cursor|claude-code|antigravity|vscode|opencode] [--skill-client codex|cursor|claude-code|antigravity|vscode|opencode] [--scope global|project] [--auth-env-var ENV_VAR] [--target-dir PATH]
|
|
211
213
|
sp-rag token add --token TOKEN
|
|
212
214
|
sp-rag token verify [--token TOKEN] [--base-url URL]
|
|
213
215
|
sp-rag config show
|
|
@@ -597,6 +599,50 @@ async function runUpdateSetup(parsed) {
|
|
|
597
599
|
await runSkillInstall(parsed, defaults, client);
|
|
598
600
|
}
|
|
599
601
|
}
|
|
602
|
+
async function runUpdate(parsed) {
|
|
603
|
+
const defaults = await loadRuntimeDefaults(parsed);
|
|
604
|
+
const client = resolveSelectedClient(parsed, defaults);
|
|
605
|
+
if (!client) {
|
|
606
|
+
throw new Error('Thiếu client. Dùng sp-rag update --client <client>.');
|
|
607
|
+
}
|
|
608
|
+
await runClientSetup(parsed, defaults, client);
|
|
609
|
+
}
|
|
610
|
+
async function runUninstall(parsed) {
|
|
611
|
+
const defaults = await loadRuntimeDefaults(parsed);
|
|
612
|
+
const client = resolveSelectedClient(parsed, defaults);
|
|
613
|
+
if (!client) {
|
|
614
|
+
throw new Error('Thiếu client. Dùng sp-rag uninstall --client <client>.');
|
|
615
|
+
}
|
|
616
|
+
const scope = supportedScope(optionString(parsed, 'scope')) ?? defaults.defaultScope;
|
|
617
|
+
const mcpResult = await removeMcpConfig({
|
|
618
|
+
client,
|
|
619
|
+
url: optionString(parsed, 'url') ?? defaults.mcpUrl,
|
|
620
|
+
scope,
|
|
621
|
+
cwd: optionString(parsed, 'cwd'),
|
|
622
|
+
serverAlias: optionString(parsed, 'server-alias') ?? defaults.serverAlias,
|
|
623
|
+
});
|
|
624
|
+
process.stdout.write(`${mcpResult.removed ? 'Đã gỡ' : 'Không tìm thấy'} cấu hình MCP cho ${mcpResult.client} tại ${mcpResult.path} (${mcpResult.scope}).\n`);
|
|
625
|
+
const skillClient = resolveSelectedSkillClient(parsed, defaults, client);
|
|
626
|
+
if (skillClient) {
|
|
627
|
+
const skillResult = await removeSkill({
|
|
628
|
+
client: skillClient,
|
|
629
|
+
cwd: optionString(parsed, 'cwd'),
|
|
630
|
+
scope,
|
|
631
|
+
targetDir: optionString(parsed, 'target-dir'),
|
|
632
|
+
serverAlias: optionString(parsed, 'server-alias') ?? defaults.serverAlias,
|
|
633
|
+
mcpUrl: optionString(parsed, 'mcp-url') ?? defaults.mcpUrl,
|
|
634
|
+
docsUrl: optionString(parsed, 'docs-url') ?? defaults.docsUrl,
|
|
635
|
+
});
|
|
636
|
+
for (const removedPath of skillResult.removedPaths) {
|
|
637
|
+
process.stdout.write(`Đã gỡ skill cho ${skillResult.client} tại ${removedPath}\n`);
|
|
638
|
+
}
|
|
639
|
+
if (skillResult.removedPaths.length === 0) {
|
|
640
|
+
process.stdout.write(`Không tìm thấy skill cần gỡ cho ${skillResult.client}.\n`);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
const configPath = await clearCliConfig(defaults.homeDir);
|
|
644
|
+
process.stdout.write(`Đã xóa config CLI tại ${configPath}\n`);
|
|
645
|
+
}
|
|
600
646
|
export async function runCli(argv) {
|
|
601
647
|
const parsed = parseArgv(argv);
|
|
602
648
|
const [group, action] = parsed.positionals;
|
|
@@ -695,8 +741,17 @@ export async function runCli(argv) {
|
|
|
695
741
|
if (group === 'eval' && action === 'run') {
|
|
696
742
|
return runEval(parsed);
|
|
697
743
|
}
|
|
698
|
-
if (group === 'update' && action === 'setup') {
|
|
699
|
-
|
|
744
|
+
if (group === 'update' && (!action || action === 'setup')) {
|
|
745
|
+
if (action === 'setup') {
|
|
746
|
+
await runUpdateSetup(parsed);
|
|
747
|
+
}
|
|
748
|
+
else {
|
|
749
|
+
await runUpdate(parsed);
|
|
750
|
+
}
|
|
751
|
+
return 0;
|
|
752
|
+
}
|
|
753
|
+
if (group === 'uninstall') {
|
|
754
|
+
await runUninstall(parsed);
|
|
700
755
|
return 0;
|
|
701
756
|
}
|
|
702
757
|
if (group === 'version') {
|
package/dist/lib/config-store.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
4
4
|
function stripUndefined(value) {
|
|
5
5
|
return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));
|
|
6
6
|
}
|
|
@@ -37,3 +37,8 @@ export async function saveCliConfig(config, homeDir) {
|
|
|
37
37
|
await writeFile(filePath, `${JSON.stringify(normalized, null, 2)}\n`, 'utf8');
|
|
38
38
|
return filePath;
|
|
39
39
|
}
|
|
40
|
+
export async function clearCliConfig(homeDir) {
|
|
41
|
+
const filePath = resolveCliConfigPath(homeDir);
|
|
42
|
+
await rm(filePath, { force: true });
|
|
43
|
+
return filePath;
|
|
44
|
+
}
|
package/dist/lib/mcp-config.js
CHANGED
|
@@ -85,6 +85,30 @@ function upsertObjectEntryPreservingAliasByEndpoint(base, sectionKey, entryKey,
|
|
|
85
85
|
[sectionKey]: section,
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
|
+
function removeObjectEntryByAliasOrEndpoint(base, sectionKey, entryKey, endpointKey, endpointValue) {
|
|
89
|
+
const section = base[sectionKey] && typeof base[sectionKey] === 'object'
|
|
90
|
+
? { ...base[sectionKey] }
|
|
91
|
+
: {};
|
|
92
|
+
const targetEndpoint = normalizeEndpoint(endpointValue);
|
|
93
|
+
let removed = false;
|
|
94
|
+
for (const [alias, value] of Object.entries(section)) {
|
|
95
|
+
if (!value || typeof value !== 'object') {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const candidateEndpoint = normalizeEndpoint(value[endpointKey]);
|
|
99
|
+
if (alias === entryKey || (targetEndpoint && candidateEndpoint === targetEndpoint)) {
|
|
100
|
+
delete section[alias];
|
|
101
|
+
removed = true;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
next: {
|
|
106
|
+
...base,
|
|
107
|
+
[sectionKey]: section,
|
|
108
|
+
},
|
|
109
|
+
removed,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
88
112
|
function vscodeGlobalConfigPath(home) {
|
|
89
113
|
if (process.platform === 'win32') {
|
|
90
114
|
const appData = process.env['APPDATA']?.trim() || path.join(home, 'AppData', 'Roaming');
|
|
@@ -122,6 +146,23 @@ export function upsertCodexConfig(existing, options) {
|
|
|
122
146
|
}
|
|
123
147
|
return `${cleaned ? `${cleaned}\n\n` : ''}${lines.join('\n')}\n`;
|
|
124
148
|
}
|
|
149
|
+
export function removeCodexConfigContent(existing, serverAlias) {
|
|
150
|
+
const alias = serverAlias.trim();
|
|
151
|
+
const aliasPattern = escapeRegex(alias);
|
|
152
|
+
let removed = false;
|
|
153
|
+
const withoutHeaders = existing.replace(new RegExp(`(?:^|\\n)\\[mcp_servers\\.(?:"${aliasPattern}"|${aliasPattern})\\.headers\\][\\s\\S]*?(?=(?:\\n\\[[^\\n]+\\])|$)`, 'g'), () => {
|
|
154
|
+
removed = true;
|
|
155
|
+
return '';
|
|
156
|
+
});
|
|
157
|
+
const cleaned = withoutHeaders.replace(new RegExp(`(?:^|\\n)\\[mcp_servers\\.(?:"${aliasPattern}"|${aliasPattern})\\][\\s\\S]*?(?=(?:\\n\\[[^\\n]+\\])|$)`, 'g'), () => {
|
|
158
|
+
removed = true;
|
|
159
|
+
return '';
|
|
160
|
+
});
|
|
161
|
+
return {
|
|
162
|
+
content: `${cleaned.trimEnd()}${cleaned.trimEnd() ? '\n' : ''}`,
|
|
163
|
+
removed,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
125
166
|
export function upsertJsonMcpConfig(existing, options) {
|
|
126
167
|
const base = parseJsonObject(existing);
|
|
127
168
|
const serverConfig = withHeaders({
|
|
@@ -279,3 +320,58 @@ export async function installMcpConfig(options) {
|
|
|
279
320
|
await writeFile(resolved.path, content, 'utf8');
|
|
280
321
|
return resolved;
|
|
281
322
|
}
|
|
323
|
+
export async function removeMcpConfig(options) {
|
|
324
|
+
const resolved = resolveMcpConfigPath(options);
|
|
325
|
+
const existing = await readFile(resolved.path, 'utf8').catch((error) => {
|
|
326
|
+
if (error.code === 'ENOENT') {
|
|
327
|
+
return '';
|
|
328
|
+
}
|
|
329
|
+
throw error;
|
|
330
|
+
});
|
|
331
|
+
const alias = options.serverAlias?.trim() || defaultMcpServerAlias();
|
|
332
|
+
const url = options.url.trim();
|
|
333
|
+
let content = existing;
|
|
334
|
+
let removed = false;
|
|
335
|
+
if (existing.trim()) {
|
|
336
|
+
switch (resolved.client) {
|
|
337
|
+
case 'codex': {
|
|
338
|
+
const result = removeCodexConfigContent(existing, alias);
|
|
339
|
+
content = result.content;
|
|
340
|
+
removed = result.removed;
|
|
341
|
+
break;
|
|
342
|
+
}
|
|
343
|
+
case 'cursor':
|
|
344
|
+
case 'claude-code': {
|
|
345
|
+
const result = removeObjectEntryByAliasOrEndpoint(parseJsonObject(existing), 'mcpServers', alias, 'url', url);
|
|
346
|
+
content = `${JSON.stringify(result.next, null, 2)}\n`;
|
|
347
|
+
removed = result.removed;
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
case 'antigravity': {
|
|
351
|
+
const result = removeObjectEntryByAliasOrEndpoint(parseJsonObject(existing), 'mcpServers', alias, 'serverUrl', url);
|
|
352
|
+
content = `${JSON.stringify(result.next, null, 2)}\n`;
|
|
353
|
+
removed = result.removed;
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
case 'vscode': {
|
|
357
|
+
const result = removeObjectEntryByAliasOrEndpoint(parseJsonObject(existing), 'servers', alias, 'url', url);
|
|
358
|
+
content = `${JSON.stringify(result.next, null, 2)}\n`;
|
|
359
|
+
removed = result.removed;
|
|
360
|
+
break;
|
|
361
|
+
}
|
|
362
|
+
case 'opencode': {
|
|
363
|
+
const result = removeObjectEntryByAliasOrEndpoint(parseJsonObject(existing), 'mcp', alias, 'url', url);
|
|
364
|
+
content = `${JSON.stringify(result.next, null, 2)}\n`;
|
|
365
|
+
removed = result.removed;
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if (removed) {
|
|
371
|
+
await writeFile(resolved.path, content, 'utf8');
|
|
372
|
+
}
|
|
373
|
+
return {
|
|
374
|
+
...resolved,
|
|
375
|
+
removed,
|
|
376
|
+
};
|
|
377
|
+
}
|
package/dist/lib/skill.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { mkdir, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
4
4
|
const seoBoosterRemoteUrl = 'https://gitlab.com/secomapp/development/seo-booster.git';
|
|
5
5
|
const seoBoosterProjectGuard = [
|
|
6
6
|
'- SP-RAG chỉ dành cho repo seo-booster.',
|
|
@@ -260,6 +260,41 @@ export async function installSkill(options = {}) {
|
|
|
260
260
|
paths,
|
|
261
261
|
};
|
|
262
262
|
}
|
|
263
|
+
async function removeIfSpRagArtifact(filePath) {
|
|
264
|
+
const content = await readFile(filePath, 'utf8').catch((error) => {
|
|
265
|
+
if (error.code === 'ENOENT') {
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
throw error;
|
|
269
|
+
});
|
|
270
|
+
if (content === null) {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
if (!content.includes('SP-RAG') && !content.includes('sp-rag')) {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
await rm(filePath, { force: true });
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
export async function removeSkill(options = {}) {
|
|
280
|
+
const resolved = resolveSkillInstallTarget(options);
|
|
281
|
+
const context = createSkillContext(options, resolved.client);
|
|
282
|
+
const paths = [
|
|
283
|
+
resolved.path,
|
|
284
|
+
...resolveAdditionalSkillArtifacts(options, resolved, context).map((entry) => entry.path),
|
|
285
|
+
];
|
|
286
|
+
const removedPaths = [];
|
|
287
|
+
for (const filePath of paths) {
|
|
288
|
+
if (await removeIfSpRagArtifact(filePath)) {
|
|
289
|
+
removedPaths.push(filePath);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return {
|
|
293
|
+
client: resolved.client,
|
|
294
|
+
paths,
|
|
295
|
+
removedPaths,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
263
298
|
export async function installCodexSkill(options = {}) {
|
|
264
299
|
return installSkill({
|
|
265
300
|
...options,
|