sp-rag 0.6.1 → 0.6.3
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 +185 -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.3`
|
|
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,14 +1,19 @@
|
|
|
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
|
+
const cliVersion = '0.6.3';
|
|
7
8
|
function parseArgv(argv) {
|
|
8
9
|
const positionals = [];
|
|
9
10
|
const options = {};
|
|
10
11
|
for (let index = 0; index < argv.length; index += 1) {
|
|
11
12
|
const current = argv[index];
|
|
13
|
+
if (current === '-v') {
|
|
14
|
+
options['version'] = true;
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
12
17
|
if (!current.startsWith('--')) {
|
|
13
18
|
positionals.push(current);
|
|
14
19
|
continue;
|
|
@@ -111,8 +116,11 @@ async function loadRuntimeDefaults(parsed) {
|
|
|
111
116
|
const docsUrl = optionString(parsed, 'docs-url') ??
|
|
112
117
|
config?.docsUrl ??
|
|
113
118
|
`${baseUrl.replace(/\/+$/, '')}/codegraph/docs/public?format=md`;
|
|
114
|
-
const
|
|
119
|
+
const explicitClient = supportedClient(optionString(parsed, 'client'));
|
|
120
|
+
const defaultClient = explicitClient ?? supportedClient(config?.defaultClient);
|
|
115
121
|
const defaultScope = supportedScope(optionString(parsed, 'scope') ?? config?.defaultScope);
|
|
122
|
+
const explicitSkillClient = supportedSkillClient(optionString(parsed, 'skill-client'));
|
|
123
|
+
const derivedSkillClient = defaultSkillClientForMcpClient(defaultClient);
|
|
116
124
|
return {
|
|
117
125
|
config,
|
|
118
126
|
homeDir,
|
|
@@ -127,21 +135,58 @@ async function loadRuntimeDefaults(parsed) {
|
|
|
127
135
|
optionString(parsed, 'token') ??
|
|
128
136
|
process.env['SP_RAG_MCP_TOKEN']?.trim() ??
|
|
129
137
|
config?.mcpToken,
|
|
130
|
-
skillClient:
|
|
138
|
+
skillClient: explicitSkillClient ??
|
|
139
|
+
(explicitClient ? defaultSkillClientForMcpClient(explicitClient) : undefined) ??
|
|
131
140
|
config?.skillClient ??
|
|
132
|
-
|
|
141
|
+
derivedSkillClient,
|
|
133
142
|
skillTargetDir: optionString(parsed, 'target-dir') ?? config?.skillTargetDir,
|
|
134
143
|
};
|
|
135
144
|
}
|
|
145
|
+
function resolveSelectedClient(parsed, defaults, explicitClient) {
|
|
146
|
+
return supportedClient(explicitClient ??
|
|
147
|
+
optionString(parsed, 'client') ??
|
|
148
|
+
parsed.positionals[2] ??
|
|
149
|
+
defaults.defaultClient);
|
|
150
|
+
}
|
|
151
|
+
function resolveSelectedSkillClient(parsed, defaults, client) {
|
|
152
|
+
return (supportedSkillClient(optionString(parsed, 'client')) ??
|
|
153
|
+
supportedSkillClient(optionString(parsed, 'skill-client')) ??
|
|
154
|
+
(client ? defaultSkillClientForMcpClient(client) : undefined) ??
|
|
155
|
+
defaults.skillClient);
|
|
156
|
+
}
|
|
157
|
+
function deriveDefaultsForClient(parsed, defaults, client) {
|
|
158
|
+
const nextClient = client ?? defaults.defaultClient;
|
|
159
|
+
const nextScope = supportedScope(optionString(parsed, 'scope')) ?? defaults.defaultScope;
|
|
160
|
+
const nextSkillClient = resolveSelectedSkillClient(parsed, defaults, nextClient);
|
|
161
|
+
return {
|
|
162
|
+
...defaults,
|
|
163
|
+
defaultClient: nextClient,
|
|
164
|
+
defaultScope: nextScope,
|
|
165
|
+
skillClient: nextSkillClient,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function resolveAuthForMcp(parsed, defaults) {
|
|
169
|
+
const authToken = optionString(parsed, 'mcp-token') ?? defaults.mcpToken;
|
|
170
|
+
const authEnvVar = optionString(parsed, 'auth-env-var') ?? defaults.authEnvVar;
|
|
171
|
+
if (!authToken?.trim() && !authEnvVar?.trim()) {
|
|
172
|
+
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>.');
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
authToken: authToken?.trim(),
|
|
176
|
+
authEnvVar: authEnvVar?.trim(),
|
|
177
|
+
};
|
|
178
|
+
}
|
|
136
179
|
function helpText() {
|
|
137
180
|
return `sp-rag - CLI cho setup, MCP, codegraph, eval và skill của SP-RAG
|
|
138
181
|
|
|
139
182
|
Lệnh chính:
|
|
140
|
-
sp-rag install
|
|
183
|
+
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]
|
|
184
|
+
sp-rag add --client codex|cursor|claude-code|antigravity|vscode|opencode [--scope global|project] [--cwd PATH] [--target-dir PATH]
|
|
141
185
|
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
|
|
186
|
+
sp-rag token add --token TOKEN
|
|
143
187
|
sp-rag token verify [--token TOKEN] [--base-url URL]
|
|
144
188
|
sp-rag config show
|
|
189
|
+
sp-rag explain [--client codex|cursor|claude-code|antigravity|vscode|opencode] [--scope global|project] [--cwd PATH]
|
|
145
190
|
sp-rag doctor [--base-url URL]
|
|
146
191
|
sp-rag codegraph status [--base-url URL]
|
|
147
192
|
sp-rag codegraph watch [--base-url URL] [--interval-ms N] [--max-polls N]
|
|
@@ -151,7 +196,7 @@ Lệnh chính:
|
|
|
151
196
|
sp-rag codegraph sync [--base-url URL] [--branch BRANCH] [--commit-sha SHA] [--force] [--webhook-token TOKEN] [--gitlab-job-token TOKEN]
|
|
152
197
|
sp-rag docs get <public|function|dev> [--base-url URL] [--format md|json|html]
|
|
153
198
|
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]
|
|
199
|
+
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
200
|
sp-rag eval run --file eval-suite.json [--base-url URL]
|
|
156
201
|
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
202
|
`;
|
|
@@ -296,7 +341,7 @@ async function runDocsGet(parsed) {
|
|
|
296
341
|
process.stdout.write(`${result}${result.endsWith('\n') ? '' : '\n'}`);
|
|
297
342
|
}
|
|
298
343
|
async function runMcpAdd(parsed, defaults, explicitClient) {
|
|
299
|
-
const client =
|
|
344
|
+
const client = resolveSelectedClient(parsed, defaults, explicitClient);
|
|
300
345
|
if (!client) {
|
|
301
346
|
throw new Error('Thiếu client. Dùng codex, cursor, claude-code, antigravity, vscode hoặc opencode.');
|
|
302
347
|
}
|
|
@@ -304,17 +349,15 @@ async function runMcpAdd(parsed, defaults, explicitClient) {
|
|
|
304
349
|
client,
|
|
305
350
|
url: optionString(parsed, 'url') ?? defaults.mcpUrl,
|
|
306
351
|
scope: supportedScope(optionString(parsed, 'scope')) ?? defaults.defaultScope,
|
|
307
|
-
authEnvVar:
|
|
308
|
-
authToken:
|
|
352
|
+
authEnvVar: resolveAuthForMcp(parsed, defaults).authEnvVar,
|
|
353
|
+
authToken: resolveAuthForMcp(parsed, defaults).authToken,
|
|
309
354
|
cwd: optionString(parsed, 'cwd'),
|
|
310
355
|
serverAlias: optionString(parsed, 'server-alias') ?? defaults.serverAlias,
|
|
311
356
|
});
|
|
312
357
|
process.stdout.write(`Đã cập nhật cấu hình MCP cho ${result.client} tại ${result.path} (${result.scope}).\n`);
|
|
313
358
|
}
|
|
314
|
-
async function runSkillInstall(parsed, defaults) {
|
|
315
|
-
const client =
|
|
316
|
-
defaults.skillClient ??
|
|
317
|
-
'codex';
|
|
359
|
+
async function runSkillInstall(parsed, defaults, explicitClient) {
|
|
360
|
+
const client = resolveSelectedSkillClient(parsed, defaults, explicitClient) ?? 'codex';
|
|
318
361
|
const result = await installSkill({
|
|
319
362
|
client,
|
|
320
363
|
cwd: optionString(parsed, 'cwd'),
|
|
@@ -326,26 +369,60 @@ async function runSkillInstall(parsed, defaults) {
|
|
|
326
369
|
});
|
|
327
370
|
process.stdout.write(`Đã cài skill cho ${result.client} tại ${result.path}\n`);
|
|
328
371
|
}
|
|
372
|
+
async function saveResolvedConfig(defaults) {
|
|
373
|
+
return saveCliConfig(buildCliConfig(defaults), defaults.homeDir);
|
|
374
|
+
}
|
|
375
|
+
async function runClientSetup(parsed, defaults, client) {
|
|
376
|
+
const nextDefaults = deriveDefaultsForClient(parsed, defaults, client);
|
|
377
|
+
const configPath = await saveResolvedConfig(nextDefaults);
|
|
378
|
+
process.stdout.write(`Đã lưu config CLI tại ${configPath}\n`);
|
|
379
|
+
if (!optionFlag(parsed, 'skip-mcp')) {
|
|
380
|
+
await runMcpAdd(parsed, nextDefaults, client);
|
|
381
|
+
}
|
|
382
|
+
if (!optionFlag(parsed, 'skip-skill')) {
|
|
383
|
+
await runSkillInstall(parsed, nextDefaults, client);
|
|
384
|
+
}
|
|
385
|
+
if (optionFlag(parsed, 'doctor')) {
|
|
386
|
+
const results = await runDoctor({ baseUrl: nextDefaults.baseUrl });
|
|
387
|
+
for (const result of results) {
|
|
388
|
+
process.stdout.write(`${result.ok ? 'OK' : 'FAIL'} ${result.name} ${result.status} ${result.url}\n`);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
329
392
|
async function runInit(parsed) {
|
|
330
393
|
const defaults = await loadRuntimeDefaults(parsed);
|
|
331
|
-
const
|
|
332
|
-
const
|
|
394
|
+
const client = resolveSelectedClient(parsed, defaults);
|
|
395
|
+
const nextDefaults = deriveDefaultsForClient(parsed, defaults, client);
|
|
396
|
+
const configPath = await saveResolvedConfig(nextDefaults);
|
|
333
397
|
process.stdout.write(`Đã lưu config CLI tại ${configPath}\n`);
|
|
334
|
-
if (!optionFlag(parsed, 'skip-mcp') &&
|
|
335
|
-
await runMcpAdd(parsed,
|
|
398
|
+
if (!optionFlag(parsed, 'skip-mcp') && client) {
|
|
399
|
+
await runMcpAdd(parsed, nextDefaults, client);
|
|
336
400
|
}
|
|
337
|
-
if (!optionFlag(parsed, 'skip-skill') &&
|
|
338
|
-
await runSkillInstall(parsed,
|
|
401
|
+
if (!optionFlag(parsed, 'skip-skill') && nextDefaults.skillClient) {
|
|
402
|
+
await runSkillInstall(parsed, nextDefaults, client);
|
|
339
403
|
}
|
|
340
404
|
if (optionFlag(parsed, 'doctor')) {
|
|
341
|
-
const results = await runDoctor({ baseUrl:
|
|
405
|
+
const results = await runDoctor({ baseUrl: nextDefaults.baseUrl });
|
|
342
406
|
for (const result of results) {
|
|
343
407
|
process.stdout.write(`${result.ok ? 'OK' : 'FAIL'} ${result.name} ${result.status} ${result.url}\n`);
|
|
344
408
|
}
|
|
345
409
|
}
|
|
346
410
|
}
|
|
347
411
|
async function runInstall(parsed) {
|
|
348
|
-
await
|
|
412
|
+
const defaults = await loadRuntimeDefaults(parsed);
|
|
413
|
+
const client = resolveSelectedClient(parsed, defaults);
|
|
414
|
+
if (!client) {
|
|
415
|
+
throw new Error('Thiếu client. Dùng sp-rag install --client <client> --mcp-token <token>.');
|
|
416
|
+
}
|
|
417
|
+
await runClientSetup(parsed, defaults, client);
|
|
418
|
+
}
|
|
419
|
+
async function runAdd(parsed) {
|
|
420
|
+
const defaults = await loadRuntimeDefaults(parsed);
|
|
421
|
+
const client = resolveSelectedClient(parsed, defaults);
|
|
422
|
+
if (!client) {
|
|
423
|
+
throw new Error('Thiếu client. Dùng sp-rag add --client <client>.');
|
|
424
|
+
}
|
|
425
|
+
await runClientSetup(parsed, defaults, client);
|
|
349
426
|
}
|
|
350
427
|
async function runTokenAdd(parsed) {
|
|
351
428
|
const defaults = await loadRuntimeDefaults(parsed);
|
|
@@ -357,24 +434,9 @@ async function runTokenAdd(parsed) {
|
|
|
357
434
|
...defaults,
|
|
358
435
|
mcpToken: token.trim(),
|
|
359
436
|
};
|
|
360
|
-
const configPath = await
|
|
437
|
+
const configPath = await saveResolvedConfig(nextDefaults);
|
|
361
438
|
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);
|
|
439
|
+
return;
|
|
378
440
|
}
|
|
379
441
|
async function runTokenVerify(parsed) {
|
|
380
442
|
const defaults = await loadRuntimeDefaults(parsed);
|
|
@@ -395,6 +457,73 @@ async function runConfigShow(parsed) {
|
|
|
395
457
|
const config = await loadCliConfig(optionString(parsed, 'home-dir'));
|
|
396
458
|
process.stdout.write(`${JSON.stringify(config ?? {}, null, 2)}\n`);
|
|
397
459
|
}
|
|
460
|
+
async function runExplain(parsed) {
|
|
461
|
+
const defaults = await loadRuntimeDefaults(parsed);
|
|
462
|
+
const client = resolveSelectedClient(parsed, defaults);
|
|
463
|
+
const scope = supportedScope(optionString(parsed, 'scope')) ?? defaults.defaultScope;
|
|
464
|
+
const tokenStatus = defaults.mcpToken?.trim()
|
|
465
|
+
? 'đã lưu'
|
|
466
|
+
: defaults.authEnvVar?.trim()
|
|
467
|
+
? `dùng biến môi trường ${defaults.authEnvVar}`
|
|
468
|
+
: 'chưa có';
|
|
469
|
+
const lines = [];
|
|
470
|
+
lines.push('## Cấu hình hiện tại');
|
|
471
|
+
lines.push(`- Base URL: ${defaults.baseUrl}`);
|
|
472
|
+
lines.push(`- MCP URL: ${defaults.mcpUrl}`);
|
|
473
|
+
lines.push(`- Client mặc định: ${defaults.defaultClient ?? 'chưa có'}`);
|
|
474
|
+
lines.push(`- Scope mặc định: ${defaults.defaultScope ?? 'chưa có'}`);
|
|
475
|
+
lines.push(`- Token MCP đang ở trạng thái: ${tokenStatus}`);
|
|
476
|
+
if (client) {
|
|
477
|
+
try {
|
|
478
|
+
const mcpTarget = resolveMcpConfigPath({
|
|
479
|
+
client,
|
|
480
|
+
url: defaults.mcpUrl,
|
|
481
|
+
scope,
|
|
482
|
+
cwd: optionString(parsed, 'cwd'),
|
|
483
|
+
});
|
|
484
|
+
lines.push(`- File MCP cho ${client}: ${mcpTarget.path}`);
|
|
485
|
+
}
|
|
486
|
+
catch (error) {
|
|
487
|
+
lines.push(`- File MCP cho ${client}: không xác định được (${error instanceof Error ? error.message : String(error)})`);
|
|
488
|
+
}
|
|
489
|
+
try {
|
|
490
|
+
const skillClient = resolveSelectedSkillClient(parsed, defaults, client) ??
|
|
491
|
+
defaultSkillClientForMcpClient(client);
|
|
492
|
+
if (skillClient) {
|
|
493
|
+
const skillTarget = resolveSkillInstallTarget({
|
|
494
|
+
client: skillClient,
|
|
495
|
+
scope,
|
|
496
|
+
cwd: optionString(parsed, 'cwd'),
|
|
497
|
+
targetDir: optionString(parsed, 'target-dir') ?? defaults.skillTargetDir,
|
|
498
|
+
serverAlias: defaults.serverAlias,
|
|
499
|
+
mcpUrl: defaults.mcpUrl,
|
|
500
|
+
docsUrl: defaults.docsUrl,
|
|
501
|
+
});
|
|
502
|
+
lines.push(`- File skill cho ${client}: ${skillTarget.path}`);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
catch (error) {
|
|
506
|
+
lines.push(`- File skill cho ${client}: không xác định được (${error instanceof Error ? error.message : String(error)})`);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
lines.push('');
|
|
510
|
+
lines.push('## Cách dùng chuẩn');
|
|
511
|
+
if (!defaults.mcpToken?.trim() && !defaults.authEnvVar?.trim()) {
|
|
512
|
+
lines.push('- Máy này chưa có token MCP. Hãy chạy:');
|
|
513
|
+
lines.push(` sp-rag install --client ${client ?? 'vscode'} --mcp-token <token>`);
|
|
514
|
+
}
|
|
515
|
+
else {
|
|
516
|
+
const chosenClient = client ?? defaults.defaultClient ?? 'vscode';
|
|
517
|
+
const chosenSkillClient = resolveSelectedSkillClient(parsed, defaults, client) ?? chosenClient;
|
|
518
|
+
lines.push('- Nếu muốn cài đầy đủ MCP + skill cho client mới, hãy chạy:');
|
|
519
|
+
lines.push(` sp-rag add --client ${chosenClient}`);
|
|
520
|
+
lines.push('- Nếu chỉ muốn cập nhật MCP, hãy chạy:');
|
|
521
|
+
lines.push(` sp-rag mcp add ${chosenClient}`);
|
|
522
|
+
lines.push('- Nếu chỉ muốn cài lại skill, hãy chạy:');
|
|
523
|
+
lines.push(` sp-rag skill install --client ${chosenSkillClient}`);
|
|
524
|
+
}
|
|
525
|
+
process.stdout.write(`${lines.join('\n')}\n`);
|
|
526
|
+
}
|
|
398
527
|
async function runEval(parsed) {
|
|
399
528
|
const filePath = optionString(parsed, 'file');
|
|
400
529
|
if (!filePath) {
|
|
@@ -412,21 +541,25 @@ async function runEval(parsed) {
|
|
|
412
541
|
}
|
|
413
542
|
async function runUpdateSetup(parsed) {
|
|
414
543
|
const defaults = await loadRuntimeDefaults(parsed);
|
|
415
|
-
const client =
|
|
544
|
+
const client = resolveSelectedClient(parsed, defaults);
|
|
416
545
|
if (client) {
|
|
417
546
|
await runMcpAdd({
|
|
418
547
|
...parsed,
|
|
419
548
|
positionals: ['mcp', 'add', client],
|
|
420
549
|
}, defaults, client);
|
|
421
550
|
}
|
|
422
|
-
if (!optionFlag(parsed, 'skip-skill') && defaults
|
|
423
|
-
await runSkillInstall(parsed, defaults);
|
|
551
|
+
if (!optionFlag(parsed, 'skip-skill') && resolveSelectedSkillClient(parsed, defaults, client)) {
|
|
552
|
+
await runSkillInstall(parsed, defaults, client);
|
|
424
553
|
}
|
|
425
554
|
}
|
|
426
555
|
export async function runCli(argv) {
|
|
427
556
|
const parsed = parseArgv(argv);
|
|
428
557
|
const [group, action] = parsed.positionals;
|
|
429
558
|
try {
|
|
559
|
+
if (optionFlag(parsed, 'version')) {
|
|
560
|
+
process.stdout.write(`sp-rag ${cliVersion}\n`);
|
|
561
|
+
return 0;
|
|
562
|
+
}
|
|
430
563
|
if (!group || group === 'help' || group === '--help') {
|
|
431
564
|
process.stdout.write(helpText());
|
|
432
565
|
return 0;
|
|
@@ -435,6 +568,10 @@ export async function runCli(argv) {
|
|
|
435
568
|
await runInstall(parsed);
|
|
436
569
|
return 0;
|
|
437
570
|
}
|
|
571
|
+
if (group === 'add') {
|
|
572
|
+
await runAdd(parsed);
|
|
573
|
+
return 0;
|
|
574
|
+
}
|
|
438
575
|
if (group === 'init') {
|
|
439
576
|
await runInit(parsed);
|
|
440
577
|
return 0;
|
|
@@ -451,6 +588,10 @@ export async function runCli(argv) {
|
|
|
451
588
|
await runConfigShow(parsed);
|
|
452
589
|
return 0;
|
|
453
590
|
}
|
|
591
|
+
if (group === 'explain') {
|
|
592
|
+
await runExplain(parsed);
|
|
593
|
+
return 0;
|
|
594
|
+
}
|
|
454
595
|
if (group === 'doctor') {
|
|
455
596
|
const defaults = await loadRuntimeDefaults(parsed);
|
|
456
597
|
const results = await runDoctor({
|
|
@@ -511,7 +652,7 @@ export async function runCli(argv) {
|
|
|
511
652
|
return 0;
|
|
512
653
|
}
|
|
513
654
|
if (group === 'version') {
|
|
514
|
-
process.stdout.write(
|
|
655
|
+
process.stdout.write(`sp-rag ${cliVersion}\n`);
|
|
515
656
|
return 0;
|
|
516
657
|
}
|
|
517
658
|
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 = {}) {
|