sp-rag 0.6.5 → 0.6.7
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 +5 -4
- package/dist/cli.js +4 -1
- package/dist/lib/skill.js +55 -13
- 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.7`
|
|
21
21
|
- binary public: `sp-rag`
|
|
22
22
|
|
|
23
23
|
## Cài từ source trong monorepo
|
|
@@ -71,6 +71,7 @@ Ghi chú:
|
|
|
71
71
|
- với `cursor` và `vscode` ở `scope project`, nếu Sếpp đang đứng sẵn trong repo thì có thể bỏ `--cwd`
|
|
72
72
|
- CLI sẽ tự dùng thư mục hiện tại cho cả MCP lẫn skill
|
|
73
73
|
- 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
|
+
- 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`
|
|
74
75
|
|
|
75
76
|
Ví dụ:
|
|
76
77
|
|
|
@@ -159,7 +160,7 @@ npx sp-rag@latest token verify --token $env:GRAPHRAG_MCP_TOKEN
|
|
|
159
160
|
- `antigravity` -> `SKILL.md`
|
|
160
161
|
- `opencode` -> `SKILL.md`
|
|
161
162
|
- `cursor` -> `.cursor/rules/sp-rag.mdc`
|
|
162
|
-
- `vscode` -> `.github/agents/sp-rag.agent.md` hoặc `~/.copilot/agents/sp-rag.agent.md`
|
|
163
|
+
- `vscode` -> `.github/agents/sp-rag.agent.md` + `.github/copilot-instructions.md` hoặc `~/.copilot/agents/sp-rag.agent.md` + `~/.copilot/instructions/sp-rag.instructions.md`
|
|
163
164
|
|
|
164
165
|
Ghi chú:
|
|
165
166
|
|
|
@@ -189,8 +190,8 @@ Ghi chú:
|
|
|
189
190
|
- `antigravity`: `~/.gemini/antigravity/skills/sp-rag/SKILL.md`
|
|
190
191
|
- `opencode`: `~/.config/opencode/skills/sp-rag/SKILL.md`
|
|
191
192
|
- `cursor` project: `.cursor/rules/sp-rag.mdc`
|
|
192
|
-
- `vscode` project: `.github/agents/sp-rag.agent.md`
|
|
193
|
-
- `vscode` global: `~/.copilot/agents/sp-rag.agent.md`
|
|
193
|
+
- `vscode` project: `.github/agents/sp-rag.agent.md` và `.github/copilot-instructions.md`
|
|
194
|
+
- `vscode` global: `~/.copilot/agents/sp-rag.agent.md` và `~/.copilot/instructions/sp-rag.instructions.md`
|
|
194
195
|
|
|
195
196
|
## Luồng khuyên dùng cho dev mới
|
|
196
197
|
|
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import { runEvaluationSuite } from './lib/eval.js';
|
|
|
4
4
|
import { defaultBaseUrl, defaultMcpServerAlias, defaultMcpUrl, installMcpConfig, resolveMcpConfigPath, } from './lib/mcp-config.js';
|
|
5
5
|
import { fetchJson, fetchText, runDoctor } from './lib/http.js';
|
|
6
6
|
import { installSkill, resolveSkillInstallTarget, } from './lib/skill.js';
|
|
7
|
-
const cliVersion = '0.6.
|
|
7
|
+
const cliVersion = '0.6.7';
|
|
8
8
|
function parseArgv(argv) {
|
|
9
9
|
const positionals = [];
|
|
10
10
|
const options = {};
|
|
@@ -368,6 +368,9 @@ async function runSkillInstall(parsed, defaults, explicitClient) {
|
|
|
368
368
|
docsUrl: optionString(parsed, 'docs-url') ?? defaults.docsUrl,
|
|
369
369
|
});
|
|
370
370
|
process.stdout.write(`Đã cài skill cho ${result.client} tại ${result.path}\n`);
|
|
371
|
+
for (const extraPath of result.paths.slice(1)) {
|
|
372
|
+
process.stdout.write(`Đã cài thêm hướng dẫn cho ${result.client} tại ${extraPath}\n`);
|
|
373
|
+
}
|
|
371
374
|
}
|
|
372
375
|
async function saveResolvedConfig(defaults) {
|
|
373
376
|
return saveCliConfig(buildCliConfig(defaults), defaults.homeDir);
|
package/dist/lib/skill.js
CHANGED
|
@@ -85,11 +85,13 @@ Docs URL: \`${context.docsUrl}\`
|
|
|
85
85
|
3. Use \`get_rendered_docs\` for public, function, or dev docs that were already rendered from the latest graph.
|
|
86
86
|
4. Use \`get_sync_status\`, \`get_sync_runs\`, or \`get_sync_metrics\` when you need to verify commit freshness, investigate failures, or inspect operational history.
|
|
87
87
|
5. Only call \`trigger_code_graph_sync\` when the user explicitly asks to refresh the graph or when a stale graph is the confirmed blocker.
|
|
88
|
+
6. After \`query_context\` returns, synthesize the final answer from \`matched_passages\`, \`top_entities\`, \`top_relations\`, and \`citations\`. Treat \`answer_brief\` as a hint only.
|
|
88
89
|
|
|
89
90
|
## Guardrails
|
|
90
91
|
|
|
91
92
|
- You must call SP-RAG MCP tools first for codebase or domain questions before using local workspace search, grep, or file reads.
|
|
92
93
|
- Prefer MCP-grounded answers before relying on memory.
|
|
94
|
+
- Treat \`answer_brief\` as a hint only. Prefer the richer evidence in \`matched_passages\`, \`top_entities\`, \`top_relations\`, and \`citations\` when writing the final answer.
|
|
93
95
|
- If the evidence may be stale, say so clearly and mention that the graph or docs may need a refresh.
|
|
94
96
|
- Do not trigger sync or import actions unless the user asked for it or the workflow truly requires it.
|
|
95
97
|
- When rendered docs already answer the question, cite or summarize those docs instead of rewriting everything from scratch.
|
|
@@ -108,6 +110,7 @@ alwaysApply: true
|
|
|
108
110
|
- You must call the \`${context.serverAlias}\` MCP server first before using local workspace search, grep, or file reads for codebase and domain questions.
|
|
109
111
|
- Use rendered docs from \`${context.docsUrl}\` when documentation already answers the question.
|
|
110
112
|
- For architecture, domain, entities, relations, and business workflow questions, query MCP first and only then synthesize the answer.
|
|
113
|
+
- Treat \`answer_brief\` only as a hint. Build the final answer from \`matched_passages\`, \`top_entities\`, \`top_relations\`, and \`citations\`.
|
|
111
114
|
- For freshness or operational questions, check sync status, recent runs, and metrics before assuming the graph is current.
|
|
112
115
|
- Only trigger codegraph sync when the user explicitly asks for it or stale evidence is the confirmed blocker.
|
|
113
116
|
- If the evidence may be stale, say so clearly.
|
|
@@ -134,10 +137,12 @@ You must call an SP-RAG MCP tool before using local workspace search, grep, or f
|
|
|
134
137
|
3. Use \`get_rendered_docs\` when public, function, or dev docs may already answer the question.
|
|
135
138
|
4. Use \`get_sync_status\`, \`get_sync_runs\`, or \`get_sync_metrics\` for freshness, incident review, or operational debugging.
|
|
136
139
|
5. Trigger codegraph sync only when the user explicitly requests a refresh or stale evidence is the confirmed blocker.
|
|
140
|
+
6. After \`query_context\` returns, synthesize the final answer from \`matched_passages\`, \`top_entities\`, \`top_relations\`, and \`citations\`. Treat \`answer_brief\` as a hint.
|
|
137
141
|
|
|
138
142
|
## Guardrails
|
|
139
143
|
|
|
140
144
|
- Prefer MCP-grounded evidence before answering from memory.
|
|
145
|
+
- Treat \`answer_brief\` as a hint. Prefer the richer evidence in \`matched_passages\`, \`top_entities\`, \`top_relations\`, and \`citations\` when writing the final answer.
|
|
141
146
|
- Do not use local workspace search, grep, or file reads until SP-RAG MCP has been tried first for the current question.
|
|
142
147
|
- When evidence may be stale, say so clearly and mention that a refresh might be needed.
|
|
143
148
|
- Do not trigger sync or import actions unless the workflow truly requires it.
|
|
@@ -145,6 +150,19 @@ You must call an SP-RAG MCP tool before using local workspace search, grep, or f
|
|
|
145
150
|
- Only fall back to local workspace search or file reads after MCP is unavailable or clearly lacks the needed evidence, and say that you are falling back.
|
|
146
151
|
`;
|
|
147
152
|
}
|
|
153
|
+
function renderVsCodeAlwaysOnInstructions(context) {
|
|
154
|
+
return `# SP-RAG workspace instructions
|
|
155
|
+
|
|
156
|
+
- Always use the \`${context.serverAlias}\` MCP server first for codebase, domain, architecture, workflow, and operational questions before local workspace search, grep, or file reads.
|
|
157
|
+
- Start with \`healthz\` only when connectivity is uncertain or the session is new.
|
|
158
|
+
- Use \`query_context\` first for feature, entity, relation, and business-flow questions.
|
|
159
|
+
- When \`query_context\` returns, synthesize the final answer from \`matched_passages\`, \`top_entities\`, \`top_relations\`, and \`citations\`.
|
|
160
|
+
- Treat \`answer_brief\` as a hint only, not the final answer.
|
|
161
|
+
- Use \`get_rendered_docs\` when rendered docs can answer the question faster than raw code inspection.
|
|
162
|
+
- Only trigger codegraph sync when the user explicitly asks for it or stale graph evidence is the confirmed blocker.
|
|
163
|
+
- If MCP is unavailable or clearly lacks evidence, say so explicitly before falling back to local workspace search or file reads.
|
|
164
|
+
`;
|
|
165
|
+
}
|
|
148
166
|
function renderSkillArtifact(context) {
|
|
149
167
|
switch (context.client) {
|
|
150
168
|
case 'cursor':
|
|
@@ -164,24 +182,45 @@ function renderSkillArtifact(context) {
|
|
|
164
182
|
};
|
|
165
183
|
}
|
|
166
184
|
}
|
|
185
|
+
function createSkillContext(options = {}, client) {
|
|
186
|
+
return {
|
|
187
|
+
client: client ?? options.client ?? 'codex',
|
|
188
|
+
serverAlias: options.serverAlias?.trim() || 'sp-rag',
|
|
189
|
+
mcpUrl: options.mcpUrl?.trim() || 'https://sp-rag.secomapp.com/mcp',
|
|
190
|
+
docsUrl: options.docsUrl?.trim() || 'https://sp-rag.secomapp.com/codegraph/docs/public?format=md',
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
function resolveAdditionalSkillArtifacts(options, resolved, context) {
|
|
194
|
+
if (resolved.client !== 'vscode') {
|
|
195
|
+
return [];
|
|
196
|
+
}
|
|
197
|
+
const workspaceRoot = resolved.scope === 'project'
|
|
198
|
+
? requireProjectCwd('vscode', options.cwd)
|
|
199
|
+
: undefined;
|
|
200
|
+
const instructionsPath = resolved.scope === 'project'
|
|
201
|
+
? path.join(workspaceRoot, '.github', 'copilot-instructions.md')
|
|
202
|
+
: path.join(os.homedir(), '.copilot', 'instructions', 'sp-rag.instructions.md');
|
|
203
|
+
return [
|
|
204
|
+
{
|
|
205
|
+
path: instructionsPath,
|
|
206
|
+
content: renderVsCodeAlwaysOnInstructions(context),
|
|
207
|
+
},
|
|
208
|
+
];
|
|
209
|
+
}
|
|
167
210
|
export function resolveSkillInstallTarget(options = {}) {
|
|
168
211
|
const client = options.client ?? 'codex';
|
|
169
212
|
const scope = normalizeScope(client, options.scope);
|
|
170
213
|
const targetDir = path.resolve(options.targetDir ?? defaultSkillDir(client, options.cwd, scope));
|
|
171
|
-
const artifact = renderSkillArtifact(
|
|
172
|
-
client,
|
|
173
|
-
serverAlias: options.serverAlias?.trim() || 'sp-rag',
|
|
174
|
-
mcpUrl: options.mcpUrl?.trim() || 'https://sp-rag.secomapp.com/mcp',
|
|
175
|
-
docsUrl: options.docsUrl?.trim() || 'https://sp-rag.secomapp.com/codegraph/docs/public?format=md',
|
|
176
|
-
});
|
|
214
|
+
const artifact = renderSkillArtifact(createSkillContext(options, client));
|
|
177
215
|
return {
|
|
178
216
|
client,
|
|
179
217
|
scope,
|
|
180
218
|
path: path.join(targetDir, artifact.fileName),
|
|
219
|
+
paths: [path.join(targetDir, artifact.fileName)],
|
|
181
220
|
};
|
|
182
221
|
}
|
|
183
222
|
export function renderSkill(options) {
|
|
184
|
-
return renderSkillArtifact(options).content;
|
|
223
|
+
return renderSkillArtifact(createSkillContext(options, options.client)).content;
|
|
185
224
|
}
|
|
186
225
|
export function renderCodexSkill(options) {
|
|
187
226
|
return renderSkill({
|
|
@@ -191,17 +230,20 @@ export function renderCodexSkill(options) {
|
|
|
191
230
|
}
|
|
192
231
|
export async function installSkill(options = {}) {
|
|
193
232
|
const resolved = resolveSkillInstallTarget(options);
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
mcpUrl: options.mcpUrl?.trim() || 'https://sp-rag.secomapp.com/mcp',
|
|
198
|
-
docsUrl: options.docsUrl?.trim() || 'https://sp-rag.secomapp.com/codegraph/docs/public?format=md',
|
|
199
|
-
});
|
|
233
|
+
const context = createSkillContext(options, resolved.client);
|
|
234
|
+
const artifact = renderSkillArtifact(context);
|
|
235
|
+
const additionalArtifacts = resolveAdditionalSkillArtifacts(options, resolved, context);
|
|
200
236
|
await mkdir(path.dirname(resolved.path), { recursive: true });
|
|
201
237
|
await writeFile(resolved.path, artifact.content, 'utf8');
|
|
238
|
+
for (const extra of additionalArtifacts) {
|
|
239
|
+
await mkdir(path.dirname(extra.path), { recursive: true });
|
|
240
|
+
await writeFile(extra.path, extra.content, 'utf8');
|
|
241
|
+
}
|
|
242
|
+
const paths = [resolved.path, ...additionalArtifacts.map((entry) => entry.path)];
|
|
202
243
|
return {
|
|
203
244
|
client: resolved.client,
|
|
204
245
|
path: resolved.path,
|
|
246
|
+
paths,
|
|
205
247
|
};
|
|
206
248
|
}
|
|
207
249
|
export async function installCodexSkill(options = {}) {
|