@ppdocs/mcp 3.2.7 → 3.2.9
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/dist/tools/index.js +12 -9
- package/dist/tools/init.d.ts +3 -4
- package/dist/tools/init.js +9 -12
- package/dist/tools/kg_status.d.ts +2 -1
- package/dist/tools/kg_status.js +2 -2
- package/dist/tools/shared.d.ts +7 -0
- package/dist/tools/shared.js +4 -0
- package/dist/web/ui.js +4 -3
- package/package.json +1 -1
package/dist/tools/index.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* 📝 工作流: kg_task, kg_files, kg_discuss (3个)
|
|
9
9
|
* 🔬 代码分析: code_scan, code_query, code_impact, code_context (4个)
|
|
10
10
|
*/
|
|
11
|
+
import { createContext } from './shared.js';
|
|
11
12
|
import { registerInitTool } from './init.js';
|
|
12
13
|
import { registerStatusTool } from './kg_status.js';
|
|
13
14
|
import { registerDocTools } from './docs.js';
|
|
@@ -18,18 +19,20 @@ import { registerFileTools } from './files.js';
|
|
|
18
19
|
import { registerDiscussionTools } from './discussion.js';
|
|
19
20
|
import { registerAnalyzerTools } from './analyzer.js';
|
|
20
21
|
export function registerTools(server, projectId, user, onProjectChange) {
|
|
21
|
-
//
|
|
22
|
-
|
|
22
|
+
// 创建共享可变上下文 — 所有工具捕获此对象引用
|
|
23
|
+
const ctx = createContext(projectId, user);
|
|
24
|
+
// 🔗 初始化 (kg_init — 运行时项目切换,更新 ctx)
|
|
25
|
+
registerInitTool(server, ctx, onProjectChange || (() => { }));
|
|
23
26
|
// 📊 导航 (kg_status + kg_tree在docs中)
|
|
24
|
-
registerStatusTool(server,
|
|
27
|
+
registerStatusTool(server, ctx);
|
|
25
28
|
// 📚 知识 (kg_doc + kg_tree + kg_projects + kg_rules)
|
|
26
|
-
registerDocTools(server, projectId);
|
|
27
|
-
registerProjectTools(server, projectId);
|
|
28
|
-
registerRuleTools(server, projectId);
|
|
29
|
+
registerDocTools(server, ctx.projectId);
|
|
30
|
+
registerProjectTools(server, ctx.projectId);
|
|
31
|
+
registerRuleTools(server, ctx.projectId);
|
|
29
32
|
// 📝 工作流 (kg_task + kg_files + kg_discuss)
|
|
30
|
-
registerTaskTools(server, projectId, user);
|
|
33
|
+
registerTaskTools(server, ctx.projectId, ctx.user);
|
|
31
34
|
registerFileTools(server);
|
|
32
|
-
registerDiscussionTools(server, projectId);
|
|
35
|
+
registerDiscussionTools(server, ctx.projectId);
|
|
33
36
|
// 🔬 代码分析 (不变)
|
|
34
|
-
registerAnalyzerTools(server, projectId);
|
|
37
|
+
registerAnalyzerTools(server, ctx.projectId);
|
|
35
38
|
}
|
package/dist/tools/init.d.ts
CHANGED
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
* - 智能体调用 kg_init 传入 projectPath
|
|
6
6
|
* - MCP 从该路径读取 .ppdocs 配置
|
|
7
7
|
* - 重新初始化 HTTP Client 指向正确项目
|
|
8
|
-
* -
|
|
8
|
+
* - 更新共享 McpContext,所有工具自动获取新 projectId
|
|
9
9
|
*/
|
|
10
10
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
11
|
-
|
|
12
|
-
export declare function
|
|
13
|
-
export declare function registerInitTool(server: McpServer, defaultProjectId: string, onProjectChange: (newProjectId: string, newApiUrl: string) => void): void;
|
|
11
|
+
import { type McpContext } from './shared.js';
|
|
12
|
+
export declare function registerInitTool(server: McpServer, ctx: McpContext, onProjectChange: (newProjectId: string, newApiUrl: string) => void): void;
|
package/dist/tools/init.js
CHANGED
|
@@ -5,20 +5,15 @@
|
|
|
5
5
|
* - 智能体调用 kg_init 传入 projectPath
|
|
6
6
|
* - MCP 从该路径读取 .ppdocs 配置
|
|
7
7
|
* - 重新初始化 HTTP Client 指向正确项目
|
|
8
|
-
* -
|
|
8
|
+
* - 更新共享 McpContext,所有工具自动获取新 projectId
|
|
9
9
|
*/
|
|
10
10
|
import * as fs from 'fs';
|
|
11
11
|
import * as path from 'path';
|
|
12
12
|
import { z } from 'zod';
|
|
13
13
|
import { initClient } from '../storage/httpClient.js';
|
|
14
14
|
import { wrap, safeTool } from './shared.js';
|
|
15
|
-
//
|
|
16
|
-
let currentProjectId = null;
|
|
15
|
+
// 当前会话的 API URL (用于幂等检查)
|
|
17
16
|
let currentApiUrl = null;
|
|
18
|
-
/** 获取当前已初始化的 projectId */
|
|
19
|
-
export function getActiveProjectId() {
|
|
20
|
-
return currentProjectId;
|
|
21
|
-
}
|
|
22
17
|
/** 尝试从指定目录读取 .ppdocs 配置 */
|
|
23
18
|
function readPpdocsFrom(dir) {
|
|
24
19
|
const configPath = path.join(dir, '.ppdocs');
|
|
@@ -38,8 +33,8 @@ function readPpdocsFrom(dir) {
|
|
|
38
33
|
return null;
|
|
39
34
|
}
|
|
40
35
|
}
|
|
41
|
-
export function registerInitTool(server,
|
|
42
|
-
server.tool('kg_init', '🔗 项目上下文初始化 — 读取指定目录的 .ppdocs 配置,切换 MCP
|
|
36
|
+
export function registerInitTool(server, ctx, onProjectChange) {
|
|
37
|
+
server.tool('kg_init', '🔗 项目上下文初始化 — 读取指定目录的 .ppdocs 配置,切换 MCP 连接到对应项目。首次对话必须调用。不传 projectPath 则使用当前工作目录', {
|
|
43
38
|
projectPath: z.string().optional().describe('项目根目录的绝对路径(含 .ppdocs 文件),不传则使用 cwd'),
|
|
44
39
|
}, async ({ projectPath }) => safeTool(async () => {
|
|
45
40
|
const targetDir = projectPath || process.cwd();
|
|
@@ -52,7 +47,7 @@ export function registerInitTool(server, defaultProjectId, onProjectChange) {
|
|
|
52
47
|
`或通过 WebUI 绑定项目:\n` +
|
|
53
48
|
` npx @ppdocs/mcp webui`);
|
|
54
49
|
}
|
|
55
|
-
// 2.
|
|
50
|
+
// 2. 幂等检查
|
|
56
51
|
if (currentApiUrl === config.apiUrl) {
|
|
57
52
|
return wrap(`✅ 项目上下文已就绪 (无需切换)\n\n` +
|
|
58
53
|
`📂 项目: ${config.projectId}\n` +
|
|
@@ -61,9 +56,11 @@ export function registerInitTool(server, defaultProjectId, onProjectChange) {
|
|
|
61
56
|
}
|
|
62
57
|
// 3. 重新初始化 HTTP Client
|
|
63
58
|
initClient(config.apiUrl);
|
|
64
|
-
currentProjectId = config.projectId;
|
|
65
59
|
currentApiUrl = config.apiUrl;
|
|
66
|
-
// 4.
|
|
60
|
+
// 4. 更新共享上下文 — 所有工具立刻获得新 projectId
|
|
61
|
+
ctx.projectId = config.projectId;
|
|
62
|
+
ctx.user = config.user;
|
|
63
|
+
// 5. 通知主进程
|
|
67
64
|
onProjectChange(config.projectId, config.apiUrl);
|
|
68
65
|
return wrap(`✅ 项目上下文已初始化\n\n` +
|
|
69
66
|
`📂 项目: ${config.projectId}\n` +
|
|
@@ -2,4 +2,5 @@
|
|
|
2
2
|
* 📊 kg_status — 项目速览仪表盘 (新增)
|
|
3
3
|
*/
|
|
4
4
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
-
|
|
5
|
+
import { type McpContext } from './shared.js';
|
|
6
|
+
export declare function registerStatusTool(server: McpServer, ctx: McpContext): void;
|
package/dist/tools/kg_status.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { getClient } from '../storage/httpClient.js';
|
|
5
5
|
import { wrap, safeTool } from './shared.js';
|
|
6
|
-
export function registerStatusTool(server,
|
|
6
|
+
export function registerStatusTool(server, ctx) {
|
|
7
7
|
const client = () => getClient();
|
|
8
8
|
server.tool('kg_status', '📊 项目速览仪表盘 — 一键了解项目健康。返回: 文档总数、目录数、活跃任务数、最近变更。每次对话开始建议首先调用', {}, async () => safeTool(async () => {
|
|
9
9
|
const [docs, activeTasks] = await Promise.all([
|
|
@@ -20,7 +20,7 @@ export function registerStatusTool(server, projectId) {
|
|
|
20
20
|
statusMap.set(s, (statusMap.get(s) || 0) + 1);
|
|
21
21
|
}
|
|
22
22
|
const lines = [
|
|
23
|
-
`📊 项目速览 [${projectId}]`,
|
|
23
|
+
`📊 项目速览 [${ctx.projectId}]`,
|
|
24
24
|
``,
|
|
25
25
|
`📄 文档: ${docCount} 个 | 📁 目录: ${dirCount} 个`,
|
|
26
26
|
`📝 活跃任务: ${activeTasks.length} 个`,
|
package/dist/tools/shared.d.ts
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
* 合并原 helpers.ts + 新增 safeTool / withCross 模式
|
|
4
4
|
*/
|
|
5
5
|
import type { DocData } from '../storage/types.js';
|
|
6
|
+
/** 运行时可变上下文 — 所有工具通过引用获取最新值 */
|
|
7
|
+
export interface McpContext {
|
|
8
|
+
projectId: string;
|
|
9
|
+
user: string;
|
|
10
|
+
}
|
|
11
|
+
/** 创建可变上下文对象 (工具闭包捕获此对象的引用,kg_init 更新其属性) */
|
|
12
|
+
export declare function createContext(projectId: string, user: string): McpContext;
|
|
6
13
|
export declare function wrap(text: string): {
|
|
7
14
|
content: {
|
|
8
15
|
type: "text";
|
package/dist/tools/shared.js
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
* MCP 工具共享模块
|
|
3
3
|
* 合并原 helpers.ts + 新增 safeTool / withCross 模式
|
|
4
4
|
*/
|
|
5
|
+
/** 创建可变上下文对象 (工具闭包捕获此对象的引用,kg_init 更新其属性) */
|
|
6
|
+
export function createContext(projectId, user) {
|
|
7
|
+
return { projectId, user };
|
|
8
|
+
}
|
|
5
9
|
// ==================== MCP 返回包装 ====================
|
|
6
10
|
export function wrap(text) {
|
|
7
11
|
return { content: [{ type: 'text', text }] };
|
package/dist/web/ui.js
CHANGED
|
@@ -111,7 +111,8 @@ function init(){
|
|
|
111
111
|
var entry=items[i].webkitGetAsEntry&&items[i].webkitGetAsEntry();
|
|
112
112
|
if(entry&&entry.isDirectory){
|
|
113
113
|
go('add',{addStep:1,addDir:entry.name});
|
|
114
|
-
toast('📂 检测到 '+entry.name+'
|
|
114
|
+
toast('📂 检测到 '+entry.name+',请补全绝对路径后发送授权');
|
|
115
|
+
setTimeout(function(){var inp=document.getElementById('iDir');if(inp){inp.focus();inp.setSelectionRange(0,0)}},150);
|
|
115
116
|
return;
|
|
116
117
|
}
|
|
117
118
|
}
|
|
@@ -193,14 +194,14 @@ function renderAddStep1(){
|
|
|
193
194
|
return '<span class="back" onclick="cancelAuth();go(\\x27list\\x27)">← 返回项目列表</span>'+
|
|
194
195
|
'<div class="card no-hover"><div class="section"><h2>➕ 添加项目</h2>'+
|
|
195
196
|
'<p style="font-size:13px;color:#64748b;margin-bottom:12px">点击发送授权,在主机端 PPDocs 应用中选择项目并批准</p>'+
|
|
196
|
-
'<div class="fg"><label>本地项目目录 (可选,MCP安装时需要)</label><input id="iDir" value="'+S.addDir+'" placeholder="
|
|
197
|
+
'<div class="fg"><label>本地项目目录 (可选,MCP安装时需要)</label><input id="iDir" value="'+S.addDir+'" placeholder="Win: D:\\\\projects\\\\app Mac: /Users/xxx/app" oninput="S.addDir=this.value"></div>'+
|
|
197
198
|
'<div class="btn-row"><button class="btn btn-p" onclick="doAuthStart()">📡 发送授权请求</button></div>'+
|
|
198
199
|
'</div></div>';
|
|
199
200
|
}
|
|
200
201
|
|
|
201
202
|
function doAuthStart(){
|
|
202
203
|
var dir=(document.getElementById('iDir')?document.getElementById('iDir').value:'').trim();
|
|
203
|
-
if(dir&&!/^[A-Za-z]:[\\\\\\/]
|
|
204
|
+
if(dir&&!/^[A-Za-z]:[\\\\\\/]|^\\/|^~\//.test(dir)){toast('路径需为绝对路径(D:\\xxx 或 /Users/xxx)或留空','err');return}
|
|
204
205
|
S.addDir=dir;
|
|
205
206
|
api('/api/auth/start',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({localDir:dir||''})}).then(function(r){
|
|
206
207
|
if(!r.ok){toast(r.error||'授权请求失败','err');return}
|