sp-rag 0.6.1 → 0.6.2
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 +52 -22
- package/dist/cli.js +176 -44
- package/dist/lib/skill.js +22 -9
- 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.2`
|
|
21
21
|
- binary public: `sp-rag`
|
|
22
22
|
|
|
23
23
|
## Cài từ source trong monorepo
|
|
@@ -36,22 +36,47 @@ 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
|
|
39
|
+
npx sp-rag@latest add --client claude-code --scope project --cwd D:/Webs/seo-booster
|
|
40
|
+
npx sp-rag@latest explain --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
41
|
+
npx sp-rag@latest token add --token <grc_pat_...>
|
|
40
42
|
npx sp-rag@latest token verify --token <grc_pat_...>
|
|
41
|
-
npx sp-rag@latest mcp add antigravity
|
|
42
|
-
npx sp-rag@latest mcp add opencode --scope project --cwd D:/Webs/seo-booster
|
|
43
|
-
npx sp-rag@latest skill install --
|
|
44
|
-
npx sp-rag@latest skill install --
|
|
43
|
+
npx sp-rag@latest mcp add antigravity
|
|
44
|
+
npx sp-rag@latest mcp add opencode --scope project --cwd D:/Webs/seo-booster
|
|
45
|
+
npx sp-rag@latest skill install --client cursor --scope project --cwd D:/Webs/seo-booster
|
|
46
|
+
npx sp-rag@latest skill install --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
45
47
|
```
|
|
46
48
|
|
|
47
49
|
Tương đương bằng `npm`:
|
|
48
50
|
|
|
49
51
|
```bash
|
|
50
52
|
npm exec --yes sp-rag@latest install -- --client codex --mcp-token <grc_pat_...> --doctor
|
|
51
|
-
npm exec --yes sp-rag@latest
|
|
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 explain -- --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
55
|
+
npm exec --yes sp-rag@latest token add -- --token <grc_pat_...>
|
|
52
56
|
npm exec --yes sp-rag@latest token verify -- --token <grc_pat_...>
|
|
53
57
|
```
|
|
54
58
|
|
|
59
|
+
## Flow gọn cho dev
|
|
60
|
+
|
|
61
|
+
Flow khuyên dùng sau khi đã có `grc_pat_*`:
|
|
62
|
+
|
|
63
|
+
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 chỉ muốn làm một nửa, dùng `mcp add` hoặc `skill install`
|
|
66
|
+
4. khi đổi token, chỉ cần `token add`
|
|
67
|
+
5. khi muốn kiểm tra máy đang được cấu hình ra sao, dùng `explain`
|
|
68
|
+
|
|
69
|
+
Ví dụ:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
sp-rag install --client vscode --scope project --cwd D:/Webs/seo-booster --mcp-token <grc_pat_...> --doctor
|
|
73
|
+
sp-rag add --client cursor --scope project --cwd D:/Webs/seo-booster
|
|
74
|
+
sp-rag mcp add antigravity
|
|
75
|
+
sp-rag skill install --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
76
|
+
sp-rag token add --token <grc_pat_moi>
|
|
77
|
+
sp-rag explain --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
78
|
+
```
|
|
79
|
+
|
|
55
80
|
## Lấy token ở đâu
|
|
56
81
|
|
|
57
82
|
`sp-rag` public bây giờ dùng token gắn với tài khoản thật trên server.
|
|
@@ -101,6 +126,7 @@ Ví dụ dev dùng token trực tiếp:
|
|
|
101
126
|
```bash
|
|
102
127
|
npx sp-rag@latest install --client cursor --scope project --cwd D:/Webs/seo-booster --mcp-token <grc_pat_...>
|
|
103
128
|
npx sp-rag@latest token verify --token <grc_pat_...>
|
|
129
|
+
npx sp-rag@latest explain --client cursor --scope project --cwd D:/Webs/seo-booster
|
|
104
130
|
```
|
|
105
131
|
|
|
106
132
|
Hoặc dùng biến môi trường:
|
|
@@ -164,7 +190,9 @@ Ghi chú:
|
|
|
164
190
|
|
|
165
191
|
```bash
|
|
166
192
|
sp-rag install --client codex --mcp-token <grc_pat_...> --doctor
|
|
167
|
-
sp-rag
|
|
193
|
+
sp-rag add --client cursor --scope project --cwd D:/Webs/seo-booster
|
|
194
|
+
sp-rag explain --client codex
|
|
195
|
+
sp-rag token add --token <grc_pat_...>
|
|
168
196
|
sp-rag token verify --token <grc_pat_...>
|
|
169
197
|
sp-rag config show
|
|
170
198
|
sp-rag codegraph status
|
|
@@ -172,12 +200,12 @@ sp-rag codegraph watch --interval-ms 2000
|
|
|
172
200
|
sp-rag codegraph runs --limit 5
|
|
173
201
|
sp-rag codegraph metrics
|
|
174
202
|
sp-rag codegraph recover --reason "Ops dọn stale run sau crash"
|
|
175
|
-
sp-rag mcp add antigravity
|
|
176
|
-
sp-rag mcp add vscode --scope project --cwd D:/Webs/seo-booster
|
|
177
|
-
sp-rag mcp add opencode --scope project --cwd D:/Webs/seo-booster
|
|
178
|
-
sp-rag skill install
|
|
179
|
-
sp-rag skill install --
|
|
180
|
-
sp-rag skill install --
|
|
203
|
+
sp-rag mcp add antigravity
|
|
204
|
+
sp-rag mcp add vscode --scope project --cwd D:/Webs/seo-booster
|
|
205
|
+
sp-rag mcp add opencode --scope project --cwd D:/Webs/seo-booster
|
|
206
|
+
sp-rag skill install --client codex
|
|
207
|
+
sp-rag skill install --client cursor --scope project --cwd D:/Webs/seo-booster
|
|
208
|
+
sp-rag skill install --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
181
209
|
sp-rag eval run --file ./examples/eval-suite.sample.json
|
|
182
210
|
```
|
|
183
211
|
|
|
@@ -185,7 +213,9 @@ sp-rag eval run --file ./examples/eval-suite.sample.json
|
|
|
185
213
|
|
|
186
214
|
```bash
|
|
187
215
|
sp-rag install --client codex --mcp-token <grc_pat_...> --doctor
|
|
188
|
-
sp-rag
|
|
216
|
+
sp-rag add --client cursor --scope project --cwd D:/Webs/seo-booster
|
|
217
|
+
sp-rag explain --client codex
|
|
218
|
+
sp-rag token add --token <grc_pat_...>
|
|
189
219
|
sp-rag token verify --token <grc_pat_...>
|
|
190
220
|
sp-rag config show
|
|
191
221
|
sp-rag doctor
|
|
@@ -196,13 +226,13 @@ sp-rag codegraph metrics
|
|
|
196
226
|
sp-rag codegraph recover --reason "Ops dọn stale run sau crash"
|
|
197
227
|
sp-rag codegraph sync --branch master --commit-sha <sha> --webhook-token <token webhook codegraph> --gitlab-job-token <ci-job-token>
|
|
198
228
|
sp-rag docs get public --format md
|
|
199
|
-
sp-rag mcp add codex
|
|
200
|
-
sp-rag mcp add antigravity
|
|
201
|
-
sp-rag mcp add vscode --scope project --cwd D:/Webs/seo-booster
|
|
202
|
-
sp-rag mcp add opencode --scope project --cwd D:/Webs/seo-booster
|
|
203
|
-
sp-rag skill install
|
|
204
|
-
sp-rag skill install --
|
|
205
|
-
sp-rag skill install --
|
|
229
|
+
sp-rag mcp add codex
|
|
230
|
+
sp-rag mcp add antigravity
|
|
231
|
+
sp-rag mcp add vscode --scope project --cwd D:/Webs/seo-booster
|
|
232
|
+
sp-rag mcp add opencode --scope project --cwd D:/Webs/seo-booster
|
|
233
|
+
sp-rag skill install --client codex
|
|
234
|
+
sp-rag skill install --client cursor --scope project --cwd D:/Webs/seo-booster
|
|
235
|
+
sp-rag skill install --client vscode --scope project --cwd D:/Webs/seo-booster
|
|
206
236
|
sp-rag eval run --file ./examples/eval-suite.sample.json
|
|
207
237
|
sp-rag update setup --client codex
|
|
208
238
|
```
|
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { loadCliConfig, saveCliConfig, } from './lib/config-store.js';
|
|
3
3
|
import { runEvaluationSuite } from './lib/eval.js';
|
|
4
|
-
import { defaultBaseUrl, defaultMcpServerAlias, defaultMcpUrl, installMcpConfig, } from './lib/mcp-config.js';
|
|
4
|
+
import { defaultBaseUrl, defaultMcpServerAlias, defaultMcpUrl, installMcpConfig, resolveMcpConfigPath, } from './lib/mcp-config.js';
|
|
5
5
|
import { fetchJson, fetchText, runDoctor } from './lib/http.js';
|
|
6
|
-
import { installSkill, } from './lib/skill.js';
|
|
6
|
+
import { installSkill, resolveSkillInstallTarget, } from './lib/skill.js';
|
|
7
7
|
function parseArgv(argv) {
|
|
8
8
|
const positionals = [];
|
|
9
9
|
const options = {};
|
|
@@ -111,8 +111,11 @@ async function loadRuntimeDefaults(parsed) {
|
|
|
111
111
|
const docsUrl = optionString(parsed, 'docs-url') ??
|
|
112
112
|
config?.docsUrl ??
|
|
113
113
|
`${baseUrl.replace(/\/+$/, '')}/codegraph/docs/public?format=md`;
|
|
114
|
-
const
|
|
114
|
+
const explicitClient = supportedClient(optionString(parsed, 'client'));
|
|
115
|
+
const defaultClient = explicitClient ?? supportedClient(config?.defaultClient);
|
|
115
116
|
const defaultScope = supportedScope(optionString(parsed, 'scope') ?? config?.defaultScope);
|
|
117
|
+
const explicitSkillClient = supportedSkillClient(optionString(parsed, 'skill-client'));
|
|
118
|
+
const derivedSkillClient = defaultSkillClientForMcpClient(defaultClient);
|
|
116
119
|
return {
|
|
117
120
|
config,
|
|
118
121
|
homeDir,
|
|
@@ -127,21 +130,58 @@ async function loadRuntimeDefaults(parsed) {
|
|
|
127
130
|
optionString(parsed, 'token') ??
|
|
128
131
|
process.env['SP_RAG_MCP_TOKEN']?.trim() ??
|
|
129
132
|
config?.mcpToken,
|
|
130
|
-
skillClient:
|
|
133
|
+
skillClient: explicitSkillClient ??
|
|
134
|
+
(explicitClient ? defaultSkillClientForMcpClient(explicitClient) : undefined) ??
|
|
131
135
|
config?.skillClient ??
|
|
132
|
-
|
|
136
|
+
derivedSkillClient,
|
|
133
137
|
skillTargetDir: optionString(parsed, 'target-dir') ?? config?.skillTargetDir,
|
|
134
138
|
};
|
|
135
139
|
}
|
|
140
|
+
function resolveSelectedClient(parsed, defaults, explicitClient) {
|
|
141
|
+
return supportedClient(explicitClient ??
|
|
142
|
+
optionString(parsed, 'client') ??
|
|
143
|
+
parsed.positionals[2] ??
|
|
144
|
+
defaults.defaultClient);
|
|
145
|
+
}
|
|
146
|
+
function resolveSelectedSkillClient(parsed, defaults, client) {
|
|
147
|
+
return (supportedSkillClient(optionString(parsed, 'client')) ??
|
|
148
|
+
supportedSkillClient(optionString(parsed, 'skill-client')) ??
|
|
149
|
+
(client ? defaultSkillClientForMcpClient(client) : undefined) ??
|
|
150
|
+
defaults.skillClient);
|
|
151
|
+
}
|
|
152
|
+
function deriveDefaultsForClient(parsed, defaults, client) {
|
|
153
|
+
const nextClient = client ?? defaults.defaultClient;
|
|
154
|
+
const nextScope = supportedScope(optionString(parsed, 'scope')) ?? defaults.defaultScope;
|
|
155
|
+
const nextSkillClient = resolveSelectedSkillClient(parsed, defaults, nextClient);
|
|
156
|
+
return {
|
|
157
|
+
...defaults,
|
|
158
|
+
defaultClient: nextClient,
|
|
159
|
+
defaultScope: nextScope,
|
|
160
|
+
skillClient: nextSkillClient,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function resolveAuthForMcp(parsed, defaults) {
|
|
164
|
+
const authToken = optionString(parsed, 'mcp-token') ?? defaults.mcpToken;
|
|
165
|
+
const authEnvVar = optionString(parsed, 'auth-env-var') ?? defaults.authEnvVar;
|
|
166
|
+
if (!authToken?.trim() && !authEnvVar?.trim()) {
|
|
167
|
+
throw new Error('Chưa có token MCP trong config. Hãy chạy sp-rag install --client <client> --mcp-token <token> hoặc sp-rag token add --token <token>.');
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
authToken: authToken?.trim(),
|
|
171
|
+
authEnvVar: authEnvVar?.trim(),
|
|
172
|
+
};
|
|
173
|
+
}
|
|
136
174
|
function helpText() {
|
|
137
175
|
return `sp-rag - CLI cho setup, MCP, codegraph, eval và skill của SP-RAG
|
|
138
176
|
|
|
139
177
|
Lệnh chính:
|
|
140
|
-
sp-rag install
|
|
178
|
+
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]
|
|
179
|
+
sp-rag add --client codex|cursor|claude-code|antigravity|vscode|opencode [--scope global|project] [--cwd PATH] [--target-dir PATH]
|
|
141
180
|
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]
|
|
142
|
-
sp-rag token add --token TOKEN
|
|
181
|
+
sp-rag token add --token TOKEN
|
|
143
182
|
sp-rag token verify [--token TOKEN] [--base-url URL]
|
|
144
183
|
sp-rag config show
|
|
184
|
+
sp-rag explain [--client codex|cursor|claude-code|antigravity|vscode|opencode] [--scope global|project] [--cwd PATH]
|
|
145
185
|
sp-rag doctor [--base-url URL]
|
|
146
186
|
sp-rag codegraph status [--base-url URL]
|
|
147
187
|
sp-rag codegraph watch [--base-url URL] [--interval-ms N] [--max-polls N]
|
|
@@ -151,7 +191,7 @@ Lệnh chính:
|
|
|
151
191
|
sp-rag codegraph sync [--base-url URL] [--branch BRANCH] [--commit-sha SHA] [--force] [--webhook-token TOKEN] [--gitlab-job-token TOKEN]
|
|
152
192
|
sp-rag docs get <public|function|dev> [--base-url URL] [--format md|json|html]
|
|
153
193
|
sp-rag mcp add <codex|cursor|claude-code|antigravity|vscode|opencode> [--url URL] [--scope global|project] [--auth-env-var ENV_VAR] [--mcp-token TOKEN]
|
|
154
|
-
sp-rag skill install [--skill-client codex|cursor|claude-code|antigravity|vscode|opencode] [--scope global|project] [--cwd PATH] [--target-dir PATH] [--mcp-url URL] [--docs-url URL]
|
|
194
|
+
sp-rag skill install [--client codex|cursor|claude-code|antigravity|vscode|opencode] [--skill-client codex|cursor|claude-code|antigravity|vscode|opencode] [--scope global|project] [--cwd PATH] [--target-dir PATH] [--mcp-url URL] [--docs-url URL]
|
|
155
195
|
sp-rag eval run --file eval-suite.json [--base-url URL]
|
|
156
196
|
sp-rag update setup [--client codex|cursor|claude-code|antigravity|vscode|opencode] [--skill-client codex|cursor|claude-code|antigravity|vscode|opencode] [--scope global|project] [--url URL] [--auth-env-var ENV_VAR] [--target-dir PATH]
|
|
157
197
|
`;
|
|
@@ -296,7 +336,7 @@ async function runDocsGet(parsed) {
|
|
|
296
336
|
process.stdout.write(`${result}${result.endsWith('\n') ? '' : '\n'}`);
|
|
297
337
|
}
|
|
298
338
|
async function runMcpAdd(parsed, defaults, explicitClient) {
|
|
299
|
-
const client =
|
|
339
|
+
const client = resolveSelectedClient(parsed, defaults, explicitClient);
|
|
300
340
|
if (!client) {
|
|
301
341
|
throw new Error('Thiếu client. Dùng codex, cursor, claude-code, antigravity, vscode hoặc opencode.');
|
|
302
342
|
}
|
|
@@ -304,17 +344,15 @@ async function runMcpAdd(parsed, defaults, explicitClient) {
|
|
|
304
344
|
client,
|
|
305
345
|
url: optionString(parsed, 'url') ?? defaults.mcpUrl,
|
|
306
346
|
scope: supportedScope(optionString(parsed, 'scope')) ?? defaults.defaultScope,
|
|
307
|
-
authEnvVar:
|
|
308
|
-
authToken:
|
|
347
|
+
authEnvVar: resolveAuthForMcp(parsed, defaults).authEnvVar,
|
|
348
|
+
authToken: resolveAuthForMcp(parsed, defaults).authToken,
|
|
309
349
|
cwd: optionString(parsed, 'cwd'),
|
|
310
350
|
serverAlias: optionString(parsed, 'server-alias') ?? defaults.serverAlias,
|
|
311
351
|
});
|
|
312
352
|
process.stdout.write(`Đã cập nhật cấu hình MCP cho ${result.client} tại ${result.path} (${result.scope}).\n`);
|
|
313
353
|
}
|
|
314
|
-
async function runSkillInstall(parsed, defaults) {
|
|
315
|
-
const client =
|
|
316
|
-
defaults.skillClient ??
|
|
317
|
-
'codex';
|
|
354
|
+
async function runSkillInstall(parsed, defaults, explicitClient) {
|
|
355
|
+
const client = resolveSelectedSkillClient(parsed, defaults, explicitClient) ?? 'codex';
|
|
318
356
|
const result = await installSkill({
|
|
319
357
|
client,
|
|
320
358
|
cwd: optionString(parsed, 'cwd'),
|
|
@@ -326,26 +364,60 @@ async function runSkillInstall(parsed, defaults) {
|
|
|
326
364
|
});
|
|
327
365
|
process.stdout.write(`Đã cài skill cho ${result.client} tại ${result.path}\n`);
|
|
328
366
|
}
|
|
367
|
+
async function saveResolvedConfig(defaults) {
|
|
368
|
+
return saveCliConfig(buildCliConfig(defaults), defaults.homeDir);
|
|
369
|
+
}
|
|
370
|
+
async function runClientSetup(parsed, defaults, client) {
|
|
371
|
+
const nextDefaults = deriveDefaultsForClient(parsed, defaults, client);
|
|
372
|
+
const configPath = await saveResolvedConfig(nextDefaults);
|
|
373
|
+
process.stdout.write(`Đã lưu config CLI tại ${configPath}\n`);
|
|
374
|
+
if (!optionFlag(parsed, 'skip-mcp')) {
|
|
375
|
+
await runMcpAdd(parsed, nextDefaults, client);
|
|
376
|
+
}
|
|
377
|
+
if (!optionFlag(parsed, 'skip-skill')) {
|
|
378
|
+
await runSkillInstall(parsed, nextDefaults, client);
|
|
379
|
+
}
|
|
380
|
+
if (optionFlag(parsed, 'doctor')) {
|
|
381
|
+
const results = await runDoctor({ baseUrl: nextDefaults.baseUrl });
|
|
382
|
+
for (const result of results) {
|
|
383
|
+
process.stdout.write(`${result.ok ? 'OK' : 'FAIL'} ${result.name} ${result.status} ${result.url}\n`);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
329
387
|
async function runInit(parsed) {
|
|
330
388
|
const defaults = await loadRuntimeDefaults(parsed);
|
|
331
|
-
const
|
|
332
|
-
const
|
|
389
|
+
const client = resolveSelectedClient(parsed, defaults);
|
|
390
|
+
const nextDefaults = deriveDefaultsForClient(parsed, defaults, client);
|
|
391
|
+
const configPath = await saveResolvedConfig(nextDefaults);
|
|
333
392
|
process.stdout.write(`Đã lưu config CLI tại ${configPath}\n`);
|
|
334
|
-
if (!optionFlag(parsed, 'skip-mcp') &&
|
|
335
|
-
await runMcpAdd(parsed,
|
|
393
|
+
if (!optionFlag(parsed, 'skip-mcp') && client) {
|
|
394
|
+
await runMcpAdd(parsed, nextDefaults, client);
|
|
336
395
|
}
|
|
337
|
-
if (!optionFlag(parsed, 'skip-skill') &&
|
|
338
|
-
await runSkillInstall(parsed,
|
|
396
|
+
if (!optionFlag(parsed, 'skip-skill') && nextDefaults.skillClient) {
|
|
397
|
+
await runSkillInstall(parsed, nextDefaults, client);
|
|
339
398
|
}
|
|
340
399
|
if (optionFlag(parsed, 'doctor')) {
|
|
341
|
-
const results = await runDoctor({ baseUrl:
|
|
400
|
+
const results = await runDoctor({ baseUrl: nextDefaults.baseUrl });
|
|
342
401
|
for (const result of results) {
|
|
343
402
|
process.stdout.write(`${result.ok ? 'OK' : 'FAIL'} ${result.name} ${result.status} ${result.url}\n`);
|
|
344
403
|
}
|
|
345
404
|
}
|
|
346
405
|
}
|
|
347
406
|
async function runInstall(parsed) {
|
|
348
|
-
await
|
|
407
|
+
const defaults = await loadRuntimeDefaults(parsed);
|
|
408
|
+
const client = resolveSelectedClient(parsed, defaults);
|
|
409
|
+
if (!client) {
|
|
410
|
+
throw new Error('Thiếu client. Dùng sp-rag install --client <client> --mcp-token <token>.');
|
|
411
|
+
}
|
|
412
|
+
await runClientSetup(parsed, defaults, client);
|
|
413
|
+
}
|
|
414
|
+
async function runAdd(parsed) {
|
|
415
|
+
const defaults = await loadRuntimeDefaults(parsed);
|
|
416
|
+
const client = resolveSelectedClient(parsed, defaults);
|
|
417
|
+
if (!client) {
|
|
418
|
+
throw new Error('Thiếu client. Dùng sp-rag add --client <client>.');
|
|
419
|
+
}
|
|
420
|
+
await runClientSetup(parsed, defaults, client);
|
|
349
421
|
}
|
|
350
422
|
async function runTokenAdd(parsed) {
|
|
351
423
|
const defaults = await loadRuntimeDefaults(parsed);
|
|
@@ -357,24 +429,9 @@ async function runTokenAdd(parsed) {
|
|
|
357
429
|
...defaults,
|
|
358
430
|
mcpToken: token.trim(),
|
|
359
431
|
};
|
|
360
|
-
const configPath = await
|
|
432
|
+
const configPath = await saveResolvedConfig(nextDefaults);
|
|
361
433
|
process.stdout.write(`Đã lưu token MCP tại ${configPath}\n`);
|
|
362
|
-
|
|
363
|
-
return;
|
|
364
|
-
}
|
|
365
|
-
const client = supportedClient(optionString(parsed, 'client') ?? defaults.defaultClient);
|
|
366
|
-
if (!client) {
|
|
367
|
-
process.stdout.write('Chưa có client mặc định để cập nhật MCP config. Dùng thêm --client nếu muốn ghi ngay.\n');
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
await runMcpAdd({
|
|
371
|
-
...parsed,
|
|
372
|
-
positionals: ['mcp', 'add', client],
|
|
373
|
-
options: {
|
|
374
|
-
...parsed.options,
|
|
375
|
-
'mcp-token': token.trim(),
|
|
376
|
-
},
|
|
377
|
-
}, nextDefaults, client);
|
|
434
|
+
return;
|
|
378
435
|
}
|
|
379
436
|
async function runTokenVerify(parsed) {
|
|
380
437
|
const defaults = await loadRuntimeDefaults(parsed);
|
|
@@ -395,6 +452,73 @@ async function runConfigShow(parsed) {
|
|
|
395
452
|
const config = await loadCliConfig(optionString(parsed, 'home-dir'));
|
|
396
453
|
process.stdout.write(`${JSON.stringify(config ?? {}, null, 2)}\n`);
|
|
397
454
|
}
|
|
455
|
+
async function runExplain(parsed) {
|
|
456
|
+
const defaults = await loadRuntimeDefaults(parsed);
|
|
457
|
+
const client = resolveSelectedClient(parsed, defaults);
|
|
458
|
+
const scope = supportedScope(optionString(parsed, 'scope')) ?? defaults.defaultScope;
|
|
459
|
+
const tokenStatus = defaults.mcpToken?.trim()
|
|
460
|
+
? 'đã lưu'
|
|
461
|
+
: defaults.authEnvVar?.trim()
|
|
462
|
+
? `dùng biến môi trường ${defaults.authEnvVar}`
|
|
463
|
+
: 'chưa có';
|
|
464
|
+
const lines = [];
|
|
465
|
+
lines.push('## Cấu hình hiện tại');
|
|
466
|
+
lines.push(`- Base URL: ${defaults.baseUrl}`);
|
|
467
|
+
lines.push(`- MCP URL: ${defaults.mcpUrl}`);
|
|
468
|
+
lines.push(`- Client mặc định: ${defaults.defaultClient ?? 'chưa có'}`);
|
|
469
|
+
lines.push(`- Scope mặc định: ${defaults.defaultScope ?? 'chưa có'}`);
|
|
470
|
+
lines.push(`- Token MCP đang ở trạng thái: ${tokenStatus}`);
|
|
471
|
+
if (client) {
|
|
472
|
+
try {
|
|
473
|
+
const mcpTarget = resolveMcpConfigPath({
|
|
474
|
+
client,
|
|
475
|
+
url: defaults.mcpUrl,
|
|
476
|
+
scope,
|
|
477
|
+
cwd: optionString(parsed, 'cwd'),
|
|
478
|
+
});
|
|
479
|
+
lines.push(`- File MCP cho ${client}: ${mcpTarget.path}`);
|
|
480
|
+
}
|
|
481
|
+
catch (error) {
|
|
482
|
+
lines.push(`- File MCP cho ${client}: không xác định được (${error instanceof Error ? error.message : String(error)})`);
|
|
483
|
+
}
|
|
484
|
+
try {
|
|
485
|
+
const skillClient = resolveSelectedSkillClient(parsed, defaults, client) ??
|
|
486
|
+
defaultSkillClientForMcpClient(client);
|
|
487
|
+
if (skillClient) {
|
|
488
|
+
const skillTarget = resolveSkillInstallTarget({
|
|
489
|
+
client: skillClient,
|
|
490
|
+
scope,
|
|
491
|
+
cwd: optionString(parsed, 'cwd'),
|
|
492
|
+
targetDir: optionString(parsed, 'target-dir') ?? defaults.skillTargetDir,
|
|
493
|
+
serverAlias: defaults.serverAlias,
|
|
494
|
+
mcpUrl: defaults.mcpUrl,
|
|
495
|
+
docsUrl: defaults.docsUrl,
|
|
496
|
+
});
|
|
497
|
+
lines.push(`- File skill cho ${client}: ${skillTarget.path}`);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
catch (error) {
|
|
501
|
+
lines.push(`- File skill cho ${client}: không xác định được (${error instanceof Error ? error.message : String(error)})`);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
lines.push('');
|
|
505
|
+
lines.push('## Cách dùng chuẩn');
|
|
506
|
+
if (!defaults.mcpToken?.trim() && !defaults.authEnvVar?.trim()) {
|
|
507
|
+
lines.push('- Máy này chưa có token MCP. Hãy chạy:');
|
|
508
|
+
lines.push(` sp-rag install --client ${client ?? 'vscode'} --mcp-token <token>`);
|
|
509
|
+
}
|
|
510
|
+
else {
|
|
511
|
+
const chosenClient = client ?? defaults.defaultClient ?? 'vscode';
|
|
512
|
+
const chosenSkillClient = resolveSelectedSkillClient(parsed, defaults, client) ?? chosenClient;
|
|
513
|
+
lines.push('- Nếu muốn cài đầy đủ MCP + skill cho client mới, hãy chạy:');
|
|
514
|
+
lines.push(` sp-rag add --client ${chosenClient}`);
|
|
515
|
+
lines.push('- Nếu chỉ muốn cập nhật MCP, hãy chạy:');
|
|
516
|
+
lines.push(` sp-rag mcp add ${chosenClient}`);
|
|
517
|
+
lines.push('- Nếu chỉ muốn cài lại skill, hãy chạy:');
|
|
518
|
+
lines.push(` sp-rag skill install --client ${chosenSkillClient}`);
|
|
519
|
+
}
|
|
520
|
+
process.stdout.write(`${lines.join('\n')}\n`);
|
|
521
|
+
}
|
|
398
522
|
async function runEval(parsed) {
|
|
399
523
|
const filePath = optionString(parsed, 'file');
|
|
400
524
|
if (!filePath) {
|
|
@@ -412,15 +536,15 @@ async function runEval(parsed) {
|
|
|
412
536
|
}
|
|
413
537
|
async function runUpdateSetup(parsed) {
|
|
414
538
|
const defaults = await loadRuntimeDefaults(parsed);
|
|
415
|
-
const client =
|
|
539
|
+
const client = resolveSelectedClient(parsed, defaults);
|
|
416
540
|
if (client) {
|
|
417
541
|
await runMcpAdd({
|
|
418
542
|
...parsed,
|
|
419
543
|
positionals: ['mcp', 'add', client],
|
|
420
544
|
}, defaults, client);
|
|
421
545
|
}
|
|
422
|
-
if (!optionFlag(parsed, 'skip-skill') && defaults
|
|
423
|
-
await runSkillInstall(parsed, defaults);
|
|
546
|
+
if (!optionFlag(parsed, 'skip-skill') && resolveSelectedSkillClient(parsed, defaults, client)) {
|
|
547
|
+
await runSkillInstall(parsed, defaults, client);
|
|
424
548
|
}
|
|
425
549
|
}
|
|
426
550
|
export async function runCli(argv) {
|
|
@@ -435,6 +559,10 @@ export async function runCli(argv) {
|
|
|
435
559
|
await runInstall(parsed);
|
|
436
560
|
return 0;
|
|
437
561
|
}
|
|
562
|
+
if (group === 'add') {
|
|
563
|
+
await runAdd(parsed);
|
|
564
|
+
return 0;
|
|
565
|
+
}
|
|
438
566
|
if (group === 'init') {
|
|
439
567
|
await runInit(parsed);
|
|
440
568
|
return 0;
|
|
@@ -451,6 +579,10 @@ export async function runCli(argv) {
|
|
|
451
579
|
await runConfigShow(parsed);
|
|
452
580
|
return 0;
|
|
453
581
|
}
|
|
582
|
+
if (group === 'explain') {
|
|
583
|
+
await runExplain(parsed);
|
|
584
|
+
return 0;
|
|
585
|
+
}
|
|
454
586
|
if (group === 'doctor') {
|
|
455
587
|
const defaults = await loadRuntimeDefaults(parsed);
|
|
456
588
|
const results = await runDoctor({
|
|
@@ -511,7 +643,7 @@ export async function runCli(argv) {
|
|
|
511
643
|
return 0;
|
|
512
644
|
}
|
|
513
645
|
if (group === 'version') {
|
|
514
|
-
process.stdout.write('sp-rag 0.6.
|
|
646
|
+
process.stdout.write('sp-rag 0.6.2\n');
|
|
515
647
|
return 0;
|
|
516
648
|
}
|
|
517
649
|
process.stdout.write(helpText());
|
package/dist/lib/skill.js
CHANGED
|
@@ -156,6 +156,22 @@ function renderSkillArtifact(context) {
|
|
|
156
156
|
};
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
|
+
export function resolveSkillInstallTarget(options = {}) {
|
|
160
|
+
const client = options.client ?? 'codex';
|
|
161
|
+
const scope = normalizeScope(client, options.scope);
|
|
162
|
+
const targetDir = path.resolve(options.targetDir ?? defaultSkillDir(client, options.cwd, scope));
|
|
163
|
+
const artifact = renderSkillArtifact({
|
|
164
|
+
client,
|
|
165
|
+
serverAlias: options.serverAlias?.trim() || 'sp-rag',
|
|
166
|
+
mcpUrl: options.mcpUrl?.trim() || 'https://sp-rag.secomapp.com/mcp',
|
|
167
|
+
docsUrl: options.docsUrl?.trim() || 'https://sp-rag.secomapp.com/codegraph/docs/public?format=md',
|
|
168
|
+
});
|
|
169
|
+
return {
|
|
170
|
+
client,
|
|
171
|
+
scope,
|
|
172
|
+
path: path.join(targetDir, artifact.fileName),
|
|
173
|
+
};
|
|
174
|
+
}
|
|
159
175
|
export function renderSkill(options) {
|
|
160
176
|
return renderSkillArtifact(options).content;
|
|
161
177
|
}
|
|
@@ -166,21 +182,18 @@ export function renderCodexSkill(options) {
|
|
|
166
182
|
});
|
|
167
183
|
}
|
|
168
184
|
export async function installSkill(options = {}) {
|
|
169
|
-
const
|
|
170
|
-
const scope = normalizeScope(client, options.scope);
|
|
171
|
-
const targetDir = path.resolve(options.targetDir ?? defaultSkillDir(client, options.cwd, scope));
|
|
185
|
+
const resolved = resolveSkillInstallTarget(options);
|
|
172
186
|
const artifact = renderSkillArtifact({
|
|
173
|
-
client,
|
|
187
|
+
client: resolved.client,
|
|
174
188
|
serverAlias: options.serverAlias?.trim() || 'sp-rag',
|
|
175
189
|
mcpUrl: options.mcpUrl?.trim() || 'https://sp-rag.secomapp.com/mcp',
|
|
176
190
|
docsUrl: options.docsUrl?.trim() || 'https://sp-rag.secomapp.com/codegraph/docs/public?format=md',
|
|
177
191
|
});
|
|
178
|
-
|
|
179
|
-
await
|
|
180
|
-
await writeFile(filePath, artifact.content, 'utf8');
|
|
192
|
+
await mkdir(path.dirname(resolved.path), { recursive: true });
|
|
193
|
+
await writeFile(resolved.path, artifact.content, 'utf8');
|
|
181
194
|
return {
|
|
182
|
-
client,
|
|
183
|
-
path:
|
|
195
|
+
client: resolved.client,
|
|
196
|
+
path: resolved.path,
|
|
184
197
|
};
|
|
185
198
|
}
|
|
186
199
|
export async function installCodexSkill(options = {}) {
|