sp-rag 0.4.0 → 0.6.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 +103 -35
- package/dist/cli.js +37 -7
- package/dist/lib/skill.js +119 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# `sp-rag`
|
|
2
2
|
|
|
3
|
-
CLI
|
|
3
|
+
CLI để setup nhanh SP-RAG theo hướng dev-friendly:
|
|
4
4
|
|
|
5
5
|
- lưu cấu hình mặc định để dev không phải nhớ lại URL, client, alias
|
|
6
6
|
- cài MCP config đúng format cho từng client
|
|
7
|
-
- cài skill
|
|
7
|
+
- cài native skill / rule / custom agent cho từng IDE khi có convention ổn định
|
|
8
8
|
- kiểm tra nhanh health và observability của stack
|
|
9
9
|
- gọi sync codegraph/GitNexus theo branch hoặc `commit_sha`
|
|
10
10
|
- đọc docs đã render
|
|
@@ -17,7 +17,7 @@ CLI cho 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.
|
|
20
|
+
- version đang publish: `0.6.0`
|
|
21
21
|
- binary public: `sp-rag`
|
|
22
22
|
|
|
23
23
|
## Cài từ source trong monorepo
|
|
@@ -33,19 +33,81 @@ node dist/index.js doctor
|
|
|
33
33
|
## Cài nhanh qua `npx`
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
|
-
npx sp-rag@latest install --client codex --mcp-token <
|
|
37
|
-
npx sp-rag@latest
|
|
38
|
-
npx sp-rag@latest
|
|
39
|
-
npx sp-rag@latest
|
|
40
|
-
npx sp-rag@latest
|
|
41
|
-
npx sp-rag@latest
|
|
36
|
+
npx sp-rag@latest install --client codex --mcp-token <grc_pat_...> --doctor
|
|
37
|
+
npx sp-rag@latest install --client cursor --scope project --cwd D:/Webs/seo-booster --mcp-token <grc_pat_...>
|
|
38
|
+
npx sp-rag@latest install --client vscode --scope project --cwd D:/Webs/seo-booster --mcp-token <grc_pat_...>
|
|
39
|
+
npx sp-rag@latest token add --token <grc_pat_...> --client codex
|
|
40
|
+
npx sp-rag@latest token verify --token <grc_pat_...>
|
|
41
|
+
npx sp-rag@latest mcp add antigravity --mcp-token <grc_pat_...>
|
|
42
|
+
npx sp-rag@latest mcp add opencode --scope project --cwd D:/Webs/seo-booster --mcp-token <grc_pat_...>
|
|
43
|
+
npx sp-rag@latest skill install --skill-client cursor --scope project --cwd D:/Webs/seo-booster
|
|
44
|
+
npx sp-rag@latest skill install --skill-client vscode --scope project --cwd D:/Webs/seo-booster
|
|
42
45
|
```
|
|
43
46
|
|
|
44
47
|
Tương đương bằng `npm`:
|
|
45
48
|
|
|
46
49
|
```bash
|
|
47
|
-
npm exec --yes sp-rag@latest install -- --client codex --mcp-token <
|
|
48
|
-
npm exec --yes sp-rag@latest token add -- --token <
|
|
50
|
+
npm exec --yes sp-rag@latest install -- --client codex --mcp-token <grc_pat_...> --doctor
|
|
51
|
+
npm exec --yes sp-rag@latest token add -- --token <grc_pat_...> --client codex
|
|
52
|
+
npm exec --yes sp-rag@latest token verify -- --token <grc_pat_...>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Lấy token ở đâu
|
|
56
|
+
|
|
57
|
+
`sp-rag` public bây giờ dùng token gắn với tài khoản thật trên server.
|
|
58
|
+
|
|
59
|
+
Luồng chuẩn:
|
|
60
|
+
|
|
61
|
+
1. đăng nhập dashboard hoặc API account của GraphRAG
|
|
62
|
+
2. tạo `personal access token` qua account hiện tại
|
|
63
|
+
3. dùng chính token `grc_pat_*` đó cho MCP và CLI
|
|
64
|
+
4. kiểm tra token bằng `sp-rag token verify`
|
|
65
|
+
|
|
66
|
+
Điểm quan trọng:
|
|
67
|
+
|
|
68
|
+
- token dev dùng cho MCP nên là `grc_pat_*` của account
|
|
69
|
+
- quyền nhìn thấy tool/resource trên MCP bám theo role của account đó
|
|
70
|
+
- `viewer`, `operator`, `approver`, `admin` sẽ thấy inventory khác nhau
|
|
71
|
+
- `MCP_SERVER_ACCESS_TOKENS_JSON` chỉ còn là fallback legacy/break-glass, không còn là luồng chính cho dev
|
|
72
|
+
|
|
73
|
+
Tự tạo PAT bằng API hiện có:
|
|
74
|
+
|
|
75
|
+
1. lấy session token qua `POST /v1/account/login`
|
|
76
|
+
2. gọi `POST /v1/account/personal-access-tokens`
|
|
77
|
+
3. dùng trường `generated_token`
|
|
78
|
+
|
|
79
|
+
Ví dụ đầy đủ:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
curl -X POST https://sp-rag.secomapp.com/api/v1/account/login \
|
|
83
|
+
-H "Content-Type: application/json" \
|
|
84
|
+
-d '{"email":"dev@example.com","password":"<mật-khẩu>"}'
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Lấy `session_token`, rồi gọi tiếp:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
curl -X POST https://sp-rag.secomapp.com/api/v1/account/personal-access-tokens \
|
|
91
|
+
-H "Authorization: Bearer <grc_sess_...>" \
|
|
92
|
+
-H "Content-Type: application/json" \
|
|
93
|
+
-d '{"label":"SP-RAG CLI","expires_in_days":30}'
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Response sẽ trả `generated_token`, chính là token `grc_pat_*` để đưa vào `sp-rag`.
|
|
97
|
+
|
|
98
|
+
Ví dụ dev dùng token trực tiếp:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npx sp-rag@latest install --client cursor --scope project --cwd D:/Webs/seo-booster --mcp-token <grc_pat_...>
|
|
102
|
+
npx sp-rag@latest token verify --token <grc_pat_...>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Hoặc dùng biến môi trường:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
$env:GRAPHRAG_MCP_TOKEN="<grc_pat_...>"
|
|
109
|
+
npx sp-rag@latest mcp add vscode --scope project --cwd D:/Webs/seo-booster --auth-env-var GRAPHRAG_MCP_TOKEN
|
|
110
|
+
npx sp-rag@latest token verify --token $env:GRAPHRAG_MCP_TOKEN
|
|
49
111
|
```
|
|
50
112
|
|
|
51
113
|
## MCP client được hỗ trợ
|
|
@@ -59,15 +121,18 @@ npm exec --yes sp-rag@latest token add -- --token <token truy cập MCP> --clien
|
|
|
59
121
|
|
|
60
122
|
## Skill client được hỗ trợ
|
|
61
123
|
|
|
62
|
-
- `codex`
|
|
63
|
-
- `claude-code`
|
|
64
|
-
- `antigravity`
|
|
65
|
-
- `opencode`
|
|
124
|
+
- `codex` -> `SKILL.md`
|
|
125
|
+
- `claude-code` -> `SKILL.md`
|
|
126
|
+
- `antigravity` -> `SKILL.md`
|
|
127
|
+
- `opencode` -> `SKILL.md`
|
|
128
|
+
- `cursor` -> `.cursor/rules/sp-rag.mdc`
|
|
129
|
+
- `vscode` -> `.github/agents/sp-rag.agent.md` hoặc `~/.copilot/agents/sp-rag.agent.md`
|
|
66
130
|
|
|
67
131
|
Ghi chú:
|
|
68
132
|
|
|
69
|
-
- `cursor` và `vscode` chỉ cài MCP config, không auto-cài skill mặc định
|
|
70
133
|
- generated skill luôn được render bằng tiếng Anh
|
|
134
|
+
- `cursor` hiện nên dùng `scope project` cho rule `.mdc`
|
|
135
|
+
- `vscode` hỗ trợ cả `scope project` lẫn `scope global`
|
|
71
136
|
- nếu không muốn lưu token literal vào file config client, dùng `sp-rag mcp add --auth-env-var SP_RAG_MCP_TOKEN`
|
|
72
137
|
|
|
73
138
|
## Path mặc định quan trọng
|
|
@@ -84,39 +149,43 @@ Ghi chú:
|
|
|
84
149
|
- `opencode` project: `opencode.json`
|
|
85
150
|
- `opencode` global: `~/.config/opencode/opencode.json`
|
|
86
151
|
|
|
87
|
-
### Skill
|
|
152
|
+
### Skill / rule / custom agent
|
|
88
153
|
|
|
89
154
|
- `codex`: `~/.codex/skills/sp-rag/SKILL.md`
|
|
90
155
|
- `claude-code`: `~/.claude/skills/sp-rag/SKILL.md`
|
|
91
156
|
- `antigravity`: `~/.gemini/antigravity/skills/sp-rag/SKILL.md`
|
|
92
157
|
- `opencode`: `~/.config/opencode/skills/sp-rag/SKILL.md`
|
|
158
|
+
- `cursor` project: `.cursor/rules/sp-rag.mdc`
|
|
159
|
+
- `vscode` project: `.github/agents/sp-rag.agent.md`
|
|
160
|
+
- `vscode` global: `~/.copilot/agents/sp-rag.agent.md`
|
|
93
161
|
|
|
94
|
-
## Luồng
|
|
162
|
+
## Luồng khuyên dùng cho dev mới
|
|
95
163
|
|
|
96
164
|
```bash
|
|
97
|
-
sp-rag install --client codex --mcp-token <
|
|
98
|
-
sp-rag token add --token <
|
|
165
|
+
sp-rag install --client codex --mcp-token <grc_pat_...> --doctor
|
|
166
|
+
sp-rag token add --token <grc_pat_...> --client codex
|
|
167
|
+
sp-rag token verify --token <grc_pat_...>
|
|
99
168
|
sp-rag config show
|
|
100
169
|
sp-rag codegraph status
|
|
101
170
|
sp-rag codegraph watch --interval-ms 2000
|
|
102
171
|
sp-rag codegraph runs --limit 5
|
|
103
172
|
sp-rag codegraph metrics
|
|
104
173
|
sp-rag codegraph recover --reason "Ops dọn stale run sau crash"
|
|
105
|
-
sp-rag mcp add antigravity --mcp-token <
|
|
106
|
-
sp-rag mcp add vscode --scope project --cwd D:/Webs/seo-booster --mcp-token <
|
|
107
|
-
sp-rag mcp add opencode --scope project --cwd D:/Webs/seo-booster --mcp-token <
|
|
174
|
+
sp-rag mcp add antigravity --mcp-token <grc_pat_...>
|
|
175
|
+
sp-rag mcp add vscode --scope project --cwd D:/Webs/seo-booster --mcp-token <grc_pat_...>
|
|
176
|
+
sp-rag mcp add opencode --scope project --cwd D:/Webs/seo-booster --mcp-token <grc_pat_...>
|
|
108
177
|
sp-rag skill install
|
|
109
|
-
sp-rag skill install --skill-client
|
|
110
|
-
sp-rag skill install --skill-client
|
|
111
|
-
sp-rag skill install --skill-client opencode
|
|
178
|
+
sp-rag skill install --skill-client cursor --scope project --cwd D:/Webs/seo-booster
|
|
179
|
+
sp-rag skill install --skill-client vscode --scope project --cwd D:/Webs/seo-booster
|
|
112
180
|
sp-rag eval run --file ./examples/eval-suite.sample.json
|
|
113
181
|
```
|
|
114
182
|
|
|
115
183
|
## Lệnh chính
|
|
116
184
|
|
|
117
185
|
```bash
|
|
118
|
-
sp-rag install --client codex --mcp-token <
|
|
119
|
-
sp-rag token add --token <
|
|
186
|
+
sp-rag install --client codex --mcp-token <grc_pat_...> --doctor
|
|
187
|
+
sp-rag token add --token <grc_pat_...> --client codex
|
|
188
|
+
sp-rag token verify --token <grc_pat_...>
|
|
120
189
|
sp-rag config show
|
|
121
190
|
sp-rag doctor
|
|
122
191
|
sp-rag codegraph status
|
|
@@ -126,14 +195,13 @@ sp-rag codegraph metrics
|
|
|
126
195
|
sp-rag codegraph recover --reason "Ops dọn stale run sau crash"
|
|
127
196
|
sp-rag codegraph sync --branch master --commit-sha <sha> --webhook-token <token webhook codegraph> --gitlab-job-token <ci-job-token>
|
|
128
197
|
sp-rag docs get public --format md
|
|
129
|
-
sp-rag mcp add codex --mcp-token <
|
|
130
|
-
sp-rag mcp add antigravity --mcp-token <
|
|
131
|
-
sp-rag mcp add vscode --scope project --cwd D:/Webs/seo-booster --mcp-token <
|
|
132
|
-
sp-rag mcp add opencode --scope project --cwd D:/Webs/seo-booster --mcp-token <
|
|
198
|
+
sp-rag mcp add codex --mcp-token <grc_pat_...>
|
|
199
|
+
sp-rag mcp add antigravity --mcp-token <grc_pat_...>
|
|
200
|
+
sp-rag mcp add vscode --scope project --cwd D:/Webs/seo-booster --mcp-token <grc_pat_...>
|
|
201
|
+
sp-rag mcp add opencode --scope project --cwd D:/Webs/seo-booster --mcp-token <grc_pat_...>
|
|
133
202
|
sp-rag skill install
|
|
134
|
-
sp-rag skill install --skill-client
|
|
135
|
-
sp-rag skill install --skill-client
|
|
136
|
-
sp-rag skill install --skill-client opencode
|
|
203
|
+
sp-rag skill install --skill-client cursor --scope project --cwd D:/Webs/seo-booster
|
|
204
|
+
sp-rag skill install --skill-client vscode --scope project --cwd D:/Webs/seo-booster
|
|
137
205
|
sp-rag eval run --file ./examples/eval-suite.sample.json
|
|
138
206
|
sp-rag update setup --client codex
|
|
139
207
|
```
|
package/dist/cli.js
CHANGED
|
@@ -56,19 +56,28 @@ function supportedSkillClient(value) {
|
|
|
56
56
|
if (!value) {
|
|
57
57
|
return undefined;
|
|
58
58
|
}
|
|
59
|
-
if (value === 'codex' ||
|
|
59
|
+
if (value === 'codex' ||
|
|
60
|
+
value === 'cursor' ||
|
|
61
|
+
value === 'claude-code' ||
|
|
62
|
+
value === 'antigravity' ||
|
|
63
|
+
value === 'vscode' ||
|
|
64
|
+
value === 'opencode') {
|
|
60
65
|
return value;
|
|
61
66
|
}
|
|
62
|
-
throw new Error('Skill client phải là codex, claude-code, antigravity hoặc opencode.');
|
|
67
|
+
throw new Error('Skill client phải là codex, cursor, claude-code, antigravity, vscode hoặc opencode.');
|
|
63
68
|
}
|
|
64
69
|
function defaultSkillClientForMcpClient(client) {
|
|
65
70
|
switch (client) {
|
|
66
71
|
case 'codex':
|
|
67
72
|
return 'codex';
|
|
73
|
+
case 'cursor':
|
|
74
|
+
return 'cursor';
|
|
68
75
|
case 'claude-code':
|
|
69
76
|
return 'claude-code';
|
|
70
77
|
case 'antigravity':
|
|
71
78
|
return 'antigravity';
|
|
79
|
+
case 'vscode':
|
|
80
|
+
return 'vscode';
|
|
72
81
|
case 'opencode':
|
|
73
82
|
return 'opencode';
|
|
74
83
|
default:
|
|
@@ -128,9 +137,10 @@ function helpText() {
|
|
|
128
137
|
return `sp-rag - CLI cho setup, MCP, codegraph, eval và skill của SP-RAG
|
|
129
138
|
|
|
130
139
|
Lệnh chính:
|
|
131
|
-
sp-rag install [--base-url URL] [--mcp-url URL] [--client codex|cursor|claude-code|antigravity|vscode|opencode] [--skill-client codex|claude-code|antigravity|opencode] [--scope global|project] [--mcp-token TOKEN] [--auth-env-var ENV_VAR] [--target-dir PATH]
|
|
132
|
-
sp-rag init [--base-url URL] [--mcp-url URL] [--client codex|cursor|claude-code|antigravity|vscode|opencode] [--skill-client codex|claude-code|antigravity|opencode] [--scope global|project] [--auth-env-var ENV_VAR] [--target-dir PATH]
|
|
140
|
+
sp-rag install [--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] [--mcp-token TOKEN] [--auth-env-var ENV_VAR] [--target-dir PATH]
|
|
141
|
+
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]
|
|
133
142
|
sp-rag token add --token TOKEN [--client codex|cursor|claude-code|antigravity|vscode|opencode] [--scope global|project] [--cwd PATH]
|
|
143
|
+
sp-rag token verify [--token TOKEN] [--base-url URL]
|
|
134
144
|
sp-rag config show
|
|
135
145
|
sp-rag doctor [--base-url URL]
|
|
136
146
|
sp-rag codegraph status [--base-url URL]
|
|
@@ -141,9 +151,9 @@ Lệnh chính:
|
|
|
141
151
|
sp-rag codegraph sync [--base-url URL] [--branch BRANCH] [--commit-sha SHA] [--force] [--webhook-token TOKEN] [--gitlab-job-token TOKEN]
|
|
142
152
|
sp-rag docs get <public|function|dev> [--base-url URL] [--format md|json|html]
|
|
143
153
|
sp-rag mcp add <codex|cursor|claude-code|antigravity|vscode|opencode> [--url URL] [--scope global|project] [--auth-env-var ENV_VAR] [--mcp-token TOKEN]
|
|
144
|
-
sp-rag skill install [--skill-client codex|claude-code|antigravity|opencode] [--cwd PATH] [--target-dir PATH] [--mcp-url URL] [--docs-url URL]
|
|
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]
|
|
145
155
|
sp-rag eval run --file eval-suite.json [--base-url URL]
|
|
146
|
-
sp-rag update setup [--client codex|cursor|claude-code|antigravity|vscode|opencode] [--skill-client codex|claude-code|antigravity|opencode] [--scope global|project] [--url URL] [--auth-env-var ENV_VAR] [--target-dir PATH]
|
|
156
|
+
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]
|
|
147
157
|
`;
|
|
148
158
|
}
|
|
149
159
|
function buildCliConfig(defaults) {
|
|
@@ -308,6 +318,7 @@ async function runSkillInstall(parsed, defaults) {
|
|
|
308
318
|
const result = await installSkill({
|
|
309
319
|
client,
|
|
310
320
|
cwd: optionString(parsed, 'cwd'),
|
|
321
|
+
scope: supportedScope(optionString(parsed, 'scope')) ?? defaults.defaultScope,
|
|
311
322
|
targetDir: optionString(parsed, 'target-dir') ?? defaults.skillTargetDir,
|
|
312
323
|
serverAlias: optionString(parsed, 'server-alias') ?? defaults.serverAlias,
|
|
313
324
|
mcpUrl: optionString(parsed, 'mcp-url') ?? defaults.mcpUrl,
|
|
@@ -365,6 +376,21 @@ async function runTokenAdd(parsed) {
|
|
|
365
376
|
},
|
|
366
377
|
}, nextDefaults, client);
|
|
367
378
|
}
|
|
379
|
+
async function runTokenVerify(parsed) {
|
|
380
|
+
const defaults = await loadRuntimeDefaults(parsed);
|
|
381
|
+
const token = optionString(parsed, 'token') ?? optionString(parsed, 'mcp-token') ?? defaults.mcpToken;
|
|
382
|
+
if (!token?.trim()) {
|
|
383
|
+
throw new Error('Thiếu token. Dùng --token <token>.');
|
|
384
|
+
}
|
|
385
|
+
const baseUrl = defaults.baseUrl.replace(/\/+$/, '');
|
|
386
|
+
const result = await fetchJson(`${baseUrl}/api/v1/ops/operator-auth`, {
|
|
387
|
+
method: 'GET',
|
|
388
|
+
headers: {
|
|
389
|
+
authorization: `Bearer ${token.trim()}`,
|
|
390
|
+
},
|
|
391
|
+
});
|
|
392
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
393
|
+
}
|
|
368
394
|
async function runConfigShow(parsed) {
|
|
369
395
|
const config = await loadCliConfig(optionString(parsed, 'home-dir'));
|
|
370
396
|
process.stdout.write(`${JSON.stringify(config ?? {}, null, 2)}\n`);
|
|
@@ -417,6 +443,10 @@ export async function runCli(argv) {
|
|
|
417
443
|
await runTokenAdd(parsed);
|
|
418
444
|
return 0;
|
|
419
445
|
}
|
|
446
|
+
if (group === 'token' && action === 'verify') {
|
|
447
|
+
await runTokenVerify(parsed);
|
|
448
|
+
return 0;
|
|
449
|
+
}
|
|
420
450
|
if (group === 'config' && action === 'show') {
|
|
421
451
|
await runConfigShow(parsed);
|
|
422
452
|
return 0;
|
|
@@ -481,7 +511,7 @@ export async function runCli(argv) {
|
|
|
481
511
|
return 0;
|
|
482
512
|
}
|
|
483
513
|
if (group === 'version') {
|
|
484
|
-
process.stdout.write('sp-rag 0.
|
|
514
|
+
process.stdout.write('sp-rag 0.6.0\n');
|
|
485
515
|
return 0;
|
|
486
516
|
}
|
|
487
517
|
process.stdout.write(helpText());
|
package/dist/lib/skill.js
CHANGED
|
@@ -1,31 +1,64 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
4
|
-
|
|
4
|
+
function clientLabel(client) {
|
|
5
5
|
switch (client) {
|
|
6
6
|
case 'codex':
|
|
7
|
-
return
|
|
7
|
+
return 'Codex';
|
|
8
8
|
case 'claude-code':
|
|
9
|
-
return
|
|
9
|
+
return 'Claude Code';
|
|
10
10
|
case 'antigravity':
|
|
11
|
-
return
|
|
11
|
+
return 'Antigravity';
|
|
12
12
|
case 'opencode':
|
|
13
|
-
return
|
|
13
|
+
return 'OpenCode';
|
|
14
|
+
case 'cursor':
|
|
15
|
+
return 'Cursor';
|
|
16
|
+
case 'vscode':
|
|
17
|
+
return 'VS Code';
|
|
14
18
|
}
|
|
15
19
|
}
|
|
16
|
-
function
|
|
20
|
+
function normalizeScope(client, scope) {
|
|
21
|
+
if (scope) {
|
|
22
|
+
return scope;
|
|
23
|
+
}
|
|
24
|
+
switch (client) {
|
|
25
|
+
case 'cursor':
|
|
26
|
+
return 'project';
|
|
27
|
+
case 'vscode':
|
|
28
|
+
return 'project';
|
|
29
|
+
default:
|
|
30
|
+
return 'global';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function requireProjectCwd(client, cwd) {
|
|
34
|
+
if (!cwd?.trim()) {
|
|
35
|
+
throw new Error(`${client} cần --cwd hoặc --target-dir để cài skill theo project.`);
|
|
36
|
+
}
|
|
37
|
+
return path.resolve(cwd);
|
|
38
|
+
}
|
|
39
|
+
export function defaultSkillDir(client = 'codex', cwd, scope) {
|
|
40
|
+
const normalizedScope = normalizeScope(client, scope);
|
|
17
41
|
switch (client) {
|
|
18
42
|
case 'codex':
|
|
19
|
-
return '
|
|
43
|
+
return path.join(os.homedir(), '.codex', 'skills', 'sp-rag');
|
|
20
44
|
case 'claude-code':
|
|
21
|
-
return '
|
|
45
|
+
return path.join(os.homedir(), '.claude', 'skills', 'sp-rag');
|
|
22
46
|
case 'antigravity':
|
|
23
|
-
return '
|
|
47
|
+
return path.join(os.homedir(), '.gemini', 'antigravity', 'skills', 'sp-rag');
|
|
24
48
|
case 'opencode':
|
|
25
|
-
return '
|
|
49
|
+
return path.join(os.homedir(), '.config', 'opencode', 'skills', 'sp-rag');
|
|
50
|
+
case 'cursor':
|
|
51
|
+
if (normalizedScope !== 'project') {
|
|
52
|
+
throw new Error('Cursor rule hiện chỉ nên cài ở scope project qua .cursor/rules.');
|
|
53
|
+
}
|
|
54
|
+
return path.join(requireProjectCwd(client, cwd), '.cursor', 'rules');
|
|
55
|
+
case 'vscode':
|
|
56
|
+
return normalizedScope === 'project'
|
|
57
|
+
? path.join(requireProjectCwd(client, cwd), '.github', 'agents')
|
|
58
|
+
: path.join(os.homedir(), '.copilot', 'agents');
|
|
26
59
|
}
|
|
27
60
|
}
|
|
28
|
-
|
|
61
|
+
function renderSkillMarkdown(context) {
|
|
29
62
|
return `---
|
|
30
63
|
name: sp-rag
|
|
31
64
|
description: Use SP-RAG whenever the user asks about this codebase, internal business domain, rendered docs, import inventory, or codegraph sync status. Prefer MCP-backed evidence before answering from memory.
|
|
@@ -33,10 +66,10 @@ description: Use SP-RAG whenever the user asks about this codebase, internal bus
|
|
|
33
66
|
|
|
34
67
|
# SP-RAG
|
|
35
68
|
|
|
36
|
-
Target client: ${clientLabel(
|
|
37
|
-
Default MCP server alias: \`${
|
|
38
|
-
MCP URL: \`${
|
|
39
|
-
Docs URL: \`${
|
|
69
|
+
Target client: ${clientLabel(context.client)}
|
|
70
|
+
Default MCP server alias: \`${context.serverAlias}\`
|
|
71
|
+
MCP URL: \`${context.mcpUrl}\`
|
|
72
|
+
Docs URL: \`${context.docsUrl}\`
|
|
40
73
|
|
|
41
74
|
## When To Use This Skill
|
|
42
75
|
|
|
@@ -60,6 +93,72 @@ Docs URL: \`${options.docsUrl}\`
|
|
|
60
93
|
- When rendered docs already answer the question, cite or summarize those docs instead of rewriting everything from scratch.
|
|
61
94
|
`;
|
|
62
95
|
}
|
|
96
|
+
function renderCursorRule(context) {
|
|
97
|
+
return `---
|
|
98
|
+
description: Use SP-RAG when the request is about this codebase, internal business workflows, rendered docs, import inventory, or codegraph sync status.
|
|
99
|
+
globs:
|
|
100
|
+
alwaysApply: false
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
# SP-RAG
|
|
104
|
+
|
|
105
|
+
- Prefer the \`${context.serverAlias}\` MCP server at \`${context.mcpUrl}\` before answering from memory.
|
|
106
|
+
- Use rendered docs from \`${context.docsUrl}\` when documentation already answers the question.
|
|
107
|
+
- For architecture, domain, entities, relations, and business workflow questions, query MCP first and only then synthesize the answer.
|
|
108
|
+
- For freshness or operational questions, check sync status, recent runs, and metrics before assuming the graph is current.
|
|
109
|
+
- Only trigger codegraph sync when the user explicitly asks for it or stale evidence is the confirmed blocker.
|
|
110
|
+
- If the evidence may be stale, say so clearly.
|
|
111
|
+
`;
|
|
112
|
+
}
|
|
113
|
+
function renderVsCodeAgent(context) {
|
|
114
|
+
return `---
|
|
115
|
+
name: SP-RAG
|
|
116
|
+
description: Use this custom agent whenever the request is about this codebase, internal business workflows, rendered docs, import inventory, or codegraph sync status.
|
|
117
|
+
tools: ['${context.serverAlias}/*']
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
You are the SP-RAG custom agent for this workspace.
|
|
121
|
+
|
|
122
|
+
Use the \`${context.serverAlias}\` MCP server at \`${context.mcpUrl}\` and the rendered docs URL \`${context.docsUrl}\` as your grounded source of truth.
|
|
123
|
+
|
|
124
|
+
## Recommended Workflow
|
|
125
|
+
|
|
126
|
+
1. Start with \`healthz\` if connectivity or freshness is uncertain.
|
|
127
|
+
2. Use \`query_context\` for architecture, domain, entities, relations, and workflow questions.
|
|
128
|
+
3. Use \`get_rendered_docs\` when public, function, or dev docs may already answer the question.
|
|
129
|
+
4. Use \`get_sync_status\`, \`get_sync_runs\`, or \`get_sync_metrics\` for freshness, incident review, or operational debugging.
|
|
130
|
+
5. Trigger codegraph sync only when the user explicitly requests a refresh or stale evidence is the confirmed blocker.
|
|
131
|
+
|
|
132
|
+
## Guardrails
|
|
133
|
+
|
|
134
|
+
- Prefer MCP-grounded evidence before answering from memory.
|
|
135
|
+
- When evidence may be stale, say so clearly and mention that a refresh might be needed.
|
|
136
|
+
- Do not trigger sync or import actions unless the workflow truly requires it.
|
|
137
|
+
- When rendered docs already answer the question, summarize those docs instead of rewriting everything from scratch.
|
|
138
|
+
`;
|
|
139
|
+
}
|
|
140
|
+
function renderSkillArtifact(context) {
|
|
141
|
+
switch (context.client) {
|
|
142
|
+
case 'cursor':
|
|
143
|
+
return {
|
|
144
|
+
fileName: 'sp-rag.mdc',
|
|
145
|
+
content: renderCursorRule(context),
|
|
146
|
+
};
|
|
147
|
+
case 'vscode':
|
|
148
|
+
return {
|
|
149
|
+
fileName: 'sp-rag.agent.md',
|
|
150
|
+
content: renderVsCodeAgent(context),
|
|
151
|
+
};
|
|
152
|
+
default:
|
|
153
|
+
return {
|
|
154
|
+
fileName: 'SKILL.md',
|
|
155
|
+
content: renderSkillMarkdown(context),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
export function renderSkill(options) {
|
|
160
|
+
return renderSkillArtifact(options).content;
|
|
161
|
+
}
|
|
63
162
|
export function renderCodexSkill(options) {
|
|
64
163
|
return renderSkill({
|
|
65
164
|
client: 'codex',
|
|
@@ -68,16 +167,17 @@ export function renderCodexSkill(options) {
|
|
|
68
167
|
}
|
|
69
168
|
export async function installSkill(options = {}) {
|
|
70
169
|
const client = options.client ?? 'codex';
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
const
|
|
170
|
+
const scope = normalizeScope(client, options.scope);
|
|
171
|
+
const targetDir = path.resolve(options.targetDir ?? defaultSkillDir(client, options.cwd, scope));
|
|
172
|
+
const artifact = renderSkillArtifact({
|
|
74
173
|
client,
|
|
75
174
|
serverAlias: options.serverAlias?.trim() || 'sp-rag',
|
|
76
175
|
mcpUrl: options.mcpUrl?.trim() || 'https://sp-rag.secomapp.com/mcp',
|
|
77
176
|
docsUrl: options.docsUrl?.trim() || 'https://sp-rag.secomapp.com/codegraph/docs/public?format=md',
|
|
78
177
|
});
|
|
178
|
+
const filePath = path.join(targetDir, artifact.fileName);
|
|
79
179
|
await mkdir(targetDir, { recursive: true });
|
|
80
|
-
await writeFile(filePath, content, 'utf8');
|
|
180
|
+
await writeFile(filePath, artifact.content, 'utf8');
|
|
81
181
|
return {
|
|
82
182
|
client,
|
|
83
183
|
path: filePath,
|