@shikeai/knowledge 0.0.0-stage → 0.8.1
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/cordis.patch.yml +10 -0
- package/dist/index.es.js +29148 -0
- package/lib/client.js +9618 -0
- package/lib/client.js.map +1 -0
- package/lib/index.js +375 -0
- package/package.json +66 -4
- package/README.md +0 -3
package/lib/index.js
ADDED
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import z from "@deepseek-ai/schemastery";
|
|
2
|
+
//#region package.json
|
|
3
|
+
var version = "0.8.1";
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region src/host-entry.js
|
|
6
|
+
/**
|
|
7
|
+
* DSH 插件 Host 半区入口(Node 侧,构建为 lib/index.js)
|
|
8
|
+
*
|
|
9
|
+
* v0.9.1 重构:MCP 接入配置改走 DSH settings namespace(settings.yaml 活配置通道):
|
|
10
|
+
* 1. settings namespace —— apply 经 ctx.inject(['settings']) 调用
|
|
11
|
+
* settings.register('knowledge', McpSettingsSchema) 注册 namespace(applies 默认
|
|
12
|
+
* 'live';注册随本插件 fiber 自动清理;dsh-settings-file 把用户层持久化到
|
|
13
|
+
* ~/.dsh/settings.yaml,重启不丢)。client 半区经远程 settingsController 的
|
|
14
|
+
* describe/mutate 读写该 namespace(远程面无 register/update——注册仅宿主侧)
|
|
15
|
+
* 2. scope.watch 驱动重连 —— namespace 提交变更(client 写入)触发 watch 回调 →
|
|
16
|
+
* createMcp 销毁旧连接、重建并重新注册工具,无需 patchReload / apply 重调用
|
|
17
|
+
* 3. 零依赖 MCP Streamable HTTP 客户端 —— initialize / notifications/initialized /
|
|
18
|
+
* tools/list(分页)/ tools/call,把知识库 MCP 服务器的工具经 ctx.tools.register
|
|
19
|
+
* 注册为 mcp__knowledge__<name>,智能体会话直接可用;会话失效(HTTP 404/400)
|
|
20
|
+
* 自动重新握手重试一次;初始连接 3 次退避重试后放弃并留日志
|
|
21
|
+
* 4. 显式连接生命周期(createMcp / disposeMcp)—— 模块级 currentCleanup 保存当前
|
|
22
|
+
* 连接句柄;createMcp 进入即 disposeMcp 销毁旧连接再按需重建(url 为空仅销毁),
|
|
23
|
+
* 清理函数同步登记覆盖「握手在途时上下文销毁」的并发窗口
|
|
24
|
+
*
|
|
25
|
+
* 历史结论(v0.8~v0.9.0 踩坑,勿回退):settings namespace 是注册制——describe 只
|
|
26
|
+
* 返回 settings.register 注册过的 namespace,composition 条目 id ≠ namespace,条目
|
|
27
|
+
* Config 不在 describe 视图中;dsh-mcp-client 的 union schema Config 无法经 settings
|
|
28
|
+
* 通道驱动(volatileForm 死路);远程 settings 面无 register(client 侧兜底注册永不
|
|
29
|
+
* 成立)。
|
|
30
|
+
*
|
|
31
|
+
* 运行时依赖:@deepseek-ai/schemastery(构造 namespace schema,版本与 profile 一致,
|
|
32
|
+
* 构建时打进 bundle);其余仅使用全局 fetch(Node 18+)与宿主注入的 ctx 能力。
|
|
33
|
+
*/
|
|
34
|
+
/** 插件标识(与包名一致,bundle patch 的 name 字段对应) */
|
|
35
|
+
const name = "@shikeai/knowledge";
|
|
36
|
+
/** 不声明硬依赖:tools 服务在 apply 内按需经 ctx.inject 动态获取(缺失不阻断激活) */
|
|
37
|
+
const inject = [];
|
|
38
|
+
/** knowledge settings namespace(client 半区 host-mcp-sync.js 的 MCP_NS 同名) */
|
|
39
|
+
const MCP_SETTINGS_NS = "knowledge";
|
|
40
|
+
/**
|
|
41
|
+
* namespace schema:{ url, token }
|
|
42
|
+
* token 不标记 role('secret'):远程 describe 会脱敏 secret 字段,client 半区需要
|
|
43
|
+
* 回读完整值做幂等比对;本地 settings.yaml 明文存储与 v0.8 桥接行为一致
|
|
44
|
+
*/
|
|
45
|
+
const McpSettingsSchema = z.object({
|
|
46
|
+
url: z.string().default(""),
|
|
47
|
+
token: z.string().default("")
|
|
48
|
+
});
|
|
49
|
+
/** 已注册的 namespace scope(fiber 存续期复用;dispose 时复位,下次 apply 重新注册) */
|
|
50
|
+
let registeredScope = null;
|
|
51
|
+
/** 当前 scope.watch 的注销函数 */
|
|
52
|
+
let unwatchScope = null;
|
|
53
|
+
const PROTOCOL_VERSION = "2025-06-18";
|
|
54
|
+
const CLIENT_INFO = {
|
|
55
|
+
name: "@shikeai/knowledge",
|
|
56
|
+
version
|
|
57
|
+
};
|
|
58
|
+
const ACCEPT = "application/json, text/event-stream";
|
|
59
|
+
const SESSION_HEADER = "mcp-session-id";
|
|
60
|
+
const RPC_TIMEOUT_MS = 15e3;
|
|
61
|
+
let rpcSeq = 0;
|
|
62
|
+
/**
|
|
63
|
+
* 单次 JSON-RPC 调用(application/json 与 text/event-stream 响应自适应;
|
|
64
|
+
* initialize 响应头中的 mcp-session-id 经 onSession 回调带回)
|
|
65
|
+
*/
|
|
66
|
+
async function mcpRpc(url, token, sessionId, method, params, options = {}) {
|
|
67
|
+
const id = ++rpcSeq;
|
|
68
|
+
const headers = {
|
|
69
|
+
"Content-Type": "application/json",
|
|
70
|
+
Accept: ACCEPT
|
|
71
|
+
};
|
|
72
|
+
if (token) headers.Authorization = `Bearer ${token}`;
|
|
73
|
+
if (sessionId) headers[SESSION_HEADER] = sessionId;
|
|
74
|
+
const controller = new AbortController();
|
|
75
|
+
const timer = setTimeout(() => controller.abort(/* @__PURE__ */ new Error(`MCP ${method} 超时`)), RPC_TIMEOUT_MS);
|
|
76
|
+
let res;
|
|
77
|
+
try {
|
|
78
|
+
res = await fetch(url, {
|
|
79
|
+
method: "POST",
|
|
80
|
+
headers,
|
|
81
|
+
body: JSON.stringify({
|
|
82
|
+
jsonrpc: "2.0",
|
|
83
|
+
id,
|
|
84
|
+
method,
|
|
85
|
+
params
|
|
86
|
+
}),
|
|
87
|
+
signal: controller.signal
|
|
88
|
+
});
|
|
89
|
+
} finally {
|
|
90
|
+
clearTimeout(timer);
|
|
91
|
+
}
|
|
92
|
+
if (!res.ok) {
|
|
93
|
+
const text = await res.text().catch(() => "");
|
|
94
|
+
const error = /* @__PURE__ */ new Error(`MCP ${method} HTTP ${res.status}${text ? `:${text.slice(0, 200)}` : ""}`);
|
|
95
|
+
error.status = res.status;
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
if (method === "initialize") {
|
|
99
|
+
const sid = res.headers.get(SESSION_HEADER);
|
|
100
|
+
if (sid) options.onSession?.(sid);
|
|
101
|
+
}
|
|
102
|
+
const contentType = res.headers.get("content-type") || "";
|
|
103
|
+
let message;
|
|
104
|
+
if (contentType.includes("text/event-stream")) {
|
|
105
|
+
message = await readSseMessage(res, id);
|
|
106
|
+
if (!message) throw new Error(`MCP ${method}:SSE 流中未收到 id=${id} 的响应`);
|
|
107
|
+
} else message = await res.json();
|
|
108
|
+
if (message.error) throw new Error(`MCP ${method} 失败:${message.error.message || JSON.stringify(message.error)}`);
|
|
109
|
+
return message.result;
|
|
110
|
+
}
|
|
111
|
+
/** 从 SSE 流中解析出 id 匹配的 JSON-RPC 响应(读完即取消,不挂住连接) */
|
|
112
|
+
async function readSseMessage(res, wantId) {
|
|
113
|
+
const reader = res.body.getReader();
|
|
114
|
+
const decoder = new TextDecoder();
|
|
115
|
+
let buffer = "";
|
|
116
|
+
try {
|
|
117
|
+
for (;;) {
|
|
118
|
+
const { done, value } = await reader.read();
|
|
119
|
+
if (done) break;
|
|
120
|
+
buffer += decoder.decode(value, { stream: true });
|
|
121
|
+
let index;
|
|
122
|
+
while ((index = buffer.indexOf("\n\n")) >= 0) {
|
|
123
|
+
const block = buffer.slice(0, index);
|
|
124
|
+
buffer = buffer.slice(index + 2);
|
|
125
|
+
for (const line of block.split("\n")) {
|
|
126
|
+
if (!line.startsWith("data:")) continue;
|
|
127
|
+
const data = line.slice(5).trim();
|
|
128
|
+
if (!data) continue;
|
|
129
|
+
try {
|
|
130
|
+
const message = JSON.parse(data);
|
|
131
|
+
if (message.id === wantId) return message;
|
|
132
|
+
} catch {}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
} finally {
|
|
137
|
+
try {
|
|
138
|
+
await reader.cancel();
|
|
139
|
+
} catch {}
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
/** 通知类消息(无 id;202/200 均视为成功) */
|
|
144
|
+
async function mcpNotify(url, token, sessionId, method, params) {
|
|
145
|
+
const headers = {
|
|
146
|
+
"Content-Type": "application/json",
|
|
147
|
+
Accept: ACCEPT
|
|
148
|
+
};
|
|
149
|
+
if (token) headers.Authorization = `Bearer ${token}`;
|
|
150
|
+
if (sessionId) headers[SESSION_HEADER] = sessionId;
|
|
151
|
+
const res = await fetch(url, {
|
|
152
|
+
method: "POST",
|
|
153
|
+
headers,
|
|
154
|
+
body: JSON.stringify({
|
|
155
|
+
jsonrpc: "2.0",
|
|
156
|
+
method,
|
|
157
|
+
params
|
|
158
|
+
})
|
|
159
|
+
});
|
|
160
|
+
if (!res.ok && res.status !== 202) throw new Error(`MCP 通知 ${method} HTTP ${res.status}`);
|
|
161
|
+
try {
|
|
162
|
+
await res.body?.cancel();
|
|
163
|
+
} catch {}
|
|
164
|
+
}
|
|
165
|
+
/** MCP 握手:initialize → notifications/initialized → tools/list(分页取全) */
|
|
166
|
+
async function handshake(url, token, session) {
|
|
167
|
+
const initialize = async () => {
|
|
168
|
+
let sessionId = "";
|
|
169
|
+
await mcpRpc(url, token, "", "initialize", {
|
|
170
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
171
|
+
capabilities: {},
|
|
172
|
+
clientInfo: CLIENT_INFO
|
|
173
|
+
}, { onSession: (sid) => {
|
|
174
|
+
sessionId = sid;
|
|
175
|
+
} });
|
|
176
|
+
await mcpNotify(url, token, sessionId, "notifications/initialized", {});
|
|
177
|
+
session.id = sessionId;
|
|
178
|
+
return sessionId;
|
|
179
|
+
};
|
|
180
|
+
await initialize();
|
|
181
|
+
const list = [];
|
|
182
|
+
let cursor;
|
|
183
|
+
do {
|
|
184
|
+
const result = await mcpRpc(url, token, session.id, "tools/list", cursor ? { cursor } : {});
|
|
185
|
+
list.push(...result?.tools ?? []);
|
|
186
|
+
cursor = result?.nextCursor;
|
|
187
|
+
} while (cursor);
|
|
188
|
+
return list;
|
|
189
|
+
}
|
|
190
|
+
/** content 数组转纯文本(text 项拼接;无 text 项时 JSON 兜底) */
|
|
191
|
+
function textOfContent(content) {
|
|
192
|
+
if (!Array.isArray(content)) return "";
|
|
193
|
+
const texts = content.filter((item) => item && item.type === "text").map((item) => item.text ?? "");
|
|
194
|
+
if (texts.length) return texts.join("\n");
|
|
195
|
+
return content.length ? JSON.stringify(content) : "";
|
|
196
|
+
}
|
|
197
|
+
/** tools/call:会话失效(HTTP 404/400)时重新握手一次后重试 */
|
|
198
|
+
async function callTool(url, token, session, rawName, args) {
|
|
199
|
+
try {
|
|
200
|
+
return await mcpRpc(url, token, session.id, "tools/call", {
|
|
201
|
+
name: rawName,
|
|
202
|
+
arguments: args
|
|
203
|
+
});
|
|
204
|
+
} catch (error) {
|
|
205
|
+
if (error?.status !== 404 && error?.status !== 400) throw error;
|
|
206
|
+
console.info(`[knowledge] MCP 会话失效(HTTP ${error.status}),重新握手后重试 ${rawName}`);
|
|
207
|
+
await handshake(url, token, session);
|
|
208
|
+
return await mcpRpc(url, token, session.id, "tools/call", {
|
|
209
|
+
name: rawName,
|
|
210
|
+
arguments: args
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/** 构建单个 DSH 工具定义(形状对齐 dsh-mcp-client 的 createToolDefinition) */
|
|
215
|
+
function makeToolDefinition(tool, url, token, session) {
|
|
216
|
+
const rawName = tool.name;
|
|
217
|
+
return {
|
|
218
|
+
name: `mcp__knowledge__${rawName}`,
|
|
219
|
+
description: tool.description || "",
|
|
220
|
+
parameters: tool.inputSchema || {
|
|
221
|
+
type: "object",
|
|
222
|
+
properties: {}
|
|
223
|
+
},
|
|
224
|
+
output: {
|
|
225
|
+
schema: {
|
|
226
|
+
type: "object",
|
|
227
|
+
properties: {
|
|
228
|
+
content: {
|
|
229
|
+
type: "array",
|
|
230
|
+
items: {}
|
|
231
|
+
},
|
|
232
|
+
structuredContent: {
|
|
233
|
+
type: "object",
|
|
234
|
+
properties: {},
|
|
235
|
+
required: []
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
required: ["content"],
|
|
239
|
+
additionalProperties: false
|
|
240
|
+
},
|
|
241
|
+
render(_args, value) {
|
|
242
|
+
return [{
|
|
243
|
+
type: "text",
|
|
244
|
+
text: textOfContent(value?.content)
|
|
245
|
+
}];
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
execute: async (args) => {
|
|
249
|
+
const result = await callTool(url, token, session, rawName, args ?? {});
|
|
250
|
+
if (result?.isError) throw new Error(textOfContent(result.content) || "知识库工具执行失败");
|
|
251
|
+
const out = { content: result?.content ?? [] };
|
|
252
|
+
if (result?.structuredContent !== void 0) out.structuredContent = result.structuredContent;
|
|
253
|
+
return out;
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
/** 当前 MCP 连接的清理函数(mcpClient 实例句柄等价物;null = 无活动连接) */
|
|
258
|
+
let currentCleanup = null;
|
|
259
|
+
/** disposeMcp:销毁当前 MCP 连接并注销已注册工具(幂等,可安全重复调用) */
|
|
260
|
+
function disposeMcp() {
|
|
261
|
+
const cleanup = currentCleanup;
|
|
262
|
+
currentCleanup = null;
|
|
263
|
+
if (cleanup) cleanup();
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* createMcp:销毁旧连接后建立新连接并注册工具(apply 首次加载与配置变更热更新共用入口)
|
|
267
|
+
* - 进入即同步登记本次清理函数:覆盖「握手在途时上下文被销毁」的并发窗口,
|
|
268
|
+
* 清理后握手循环 / 工具注册经 state.disposed 短路,不产生僵尸工具
|
|
269
|
+
* - 连接失败(3 次退避重试后)解除登记并留日志,等待下次配置变更或 DSH 重启重试
|
|
270
|
+
*/
|
|
271
|
+
async function createMcp(tools, url, token) {
|
|
272
|
+
disposeMcp();
|
|
273
|
+
if (!url) {
|
|
274
|
+
console.info("[knowledge] MCP 接入点未配置(url 为空):设置页配置服务器后自动同步重连");
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const state = { disposed: false };
|
|
278
|
+
const disposers = [];
|
|
279
|
+
const cleanup = () => {
|
|
280
|
+
state.disposed = true;
|
|
281
|
+
while (disposers.length) try {
|
|
282
|
+
disposers.pop()();
|
|
283
|
+
} catch {}
|
|
284
|
+
};
|
|
285
|
+
currentCleanup = cleanup;
|
|
286
|
+
const session = { id: "" };
|
|
287
|
+
let list = null;
|
|
288
|
+
let lastError = null;
|
|
289
|
+
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
290
|
+
if (state.disposed) return;
|
|
291
|
+
try {
|
|
292
|
+
list = await handshake(url, token, session);
|
|
293
|
+
break;
|
|
294
|
+
} catch (error) {
|
|
295
|
+
lastError = error;
|
|
296
|
+
console.warn(`[knowledge] MCP 连接失败(第 ${attempt}/3 次)`, error?.message || error);
|
|
297
|
+
if (attempt < 3) await new Promise((resolve) => setTimeout(resolve, attempt * 1e3));
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (state.disposed) return;
|
|
301
|
+
if (!list) {
|
|
302
|
+
currentCleanup = null;
|
|
303
|
+
console.warn("[knowledge] MCP 连接最终失败(配置变更或重启 DSH 后重试)", lastError?.message || "");
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
console.info(`[knowledge] MCP 已连接:服务器暴露 ${list.length} 个工具`);
|
|
307
|
+
for (const tool of list) {
|
|
308
|
+
if (state.disposed) return;
|
|
309
|
+
if (!tool || typeof tool.name !== "string" || !tool.name) continue;
|
|
310
|
+
try {
|
|
311
|
+
const dispose = tools.register(makeToolDefinition(tool, url, token, session));
|
|
312
|
+
if (typeof dispose === "function") disposers.push(dispose);
|
|
313
|
+
} catch (error) {
|
|
314
|
+
console.warn(`[knowledge] 工具 ${tool.name} 注册失败`, error?.message || error);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
console.info("[knowledge] MCP 工具注册完成(mcp__knowledge__*)");
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* 插件 apply:注册 knowledge settings namespace 并驱动 MCP 连接生命周期
|
|
321
|
+
* - namespace 注册(幂等,重复 apply 复用已注册 scope;随本插件 fiber 自动清理,
|
|
322
|
+
* applies 默认 'live')。注册完成后 client 半区的 describe/mutate 才能查到并
|
|
323
|
+
* 写入该 namespace——这是「设置页 MCP 未就绪」问题的根因修复点
|
|
324
|
+
* - scope.watch:client 半区经远程 settingsController mutate 写入 namespace 后,
|
|
325
|
+
* 以提交的新值 createMcp 销毁旧连接、重建并重新注册工具(无需 patchReload)
|
|
326
|
+
* - 初次建连:以 scope.get() 当前解析值直接建连(watch 仅在提交变更后触发)
|
|
327
|
+
*/
|
|
328
|
+
function apply(ctx) {
|
|
329
|
+
ctx.effect(() => {
|
|
330
|
+
disposeMcp();
|
|
331
|
+
if (unwatchScope) {
|
|
332
|
+
try {
|
|
333
|
+
unwatchScope();
|
|
334
|
+
} catch {}
|
|
335
|
+
unwatchScope = null;
|
|
336
|
+
}
|
|
337
|
+
registeredScope = null;
|
|
338
|
+
});
|
|
339
|
+
try {
|
|
340
|
+
ctx.inject(["settings", "tools"], (injectedCtx) => {
|
|
341
|
+
const settingsSvc = injectedCtx.settings;
|
|
342
|
+
if (!settingsSvc || typeof settingsSvc.register !== "function") {
|
|
343
|
+
console.warn("[knowledge] 宿主 settings 服务无 register 能力,MCP 配置通道不可用");
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
const toolsSvc = injectedCtx.tools;
|
|
347
|
+
const tools = typeof toolsSvc?.register === "function" ? toolsSvc : toolsSvc?.tools;
|
|
348
|
+
if (!tools || typeof tools.register !== "function") {
|
|
349
|
+
console.warn("[knowledge] 宿主 tools 服务无 register 能力,MCP 工具未注册");
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
if (!registeredScope) {
|
|
353
|
+
try {
|
|
354
|
+
registeredScope = settingsSvc.register(MCP_SETTINGS_NS, McpSettingsSchema);
|
|
355
|
+
} catch (error) {
|
|
356
|
+
console.warn("[knowledge] settings namespace 注册失败,MCP 配置通道不可用", error?.message || error);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
console.info(`[knowledge] settings namespace '${MCP_SETTINGS_NS}' 已注册(MCP 配置通道就绪)`);
|
|
360
|
+
}
|
|
361
|
+
if (unwatchScope) try {
|
|
362
|
+
unwatchScope();
|
|
363
|
+
} catch {}
|
|
364
|
+
unwatchScope = registeredScope.watch((next) => {
|
|
365
|
+
createMcp(tools, String(next?.url ?? "").trim(), String(next?.token ?? ""));
|
|
366
|
+
});
|
|
367
|
+
const value = registeredScope.get() || {};
|
|
368
|
+
createMcp(tools, String(value.url ?? "").trim(), String(value.token ?? ""));
|
|
369
|
+
});
|
|
370
|
+
} catch (error) {
|
|
371
|
+
console.warn("[knowledge] settings/tools 服务注入失败,MCP 未就绪", error?.message || error);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
//#endregion
|
|
375
|
+
export { apply, inject, name };
|
package/package.json
CHANGED
|
@@ -1,6 +1,68 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shikeai/knowledge",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.8.1",
|
|
4
|
+
"description": "时刻AI平台桌面端知识库插件(DSH/Cordis 插件):知识管理(右侧抽屉 + 插件管理页官方插件条目)、成员权限、MCP RAG 检索服务、服务器配置项用户中心云持久化",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./lib/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./lib/index.js",
|
|
9
|
+
"./client": "./lib/client.js",
|
|
10
|
+
"./standalone": "./dist/index.es.js",
|
|
11
|
+
"./dist/*": "./dist/*",
|
|
12
|
+
"./public/*": "./public/*",
|
|
13
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
14
|
+
"./package.json": "./package.json"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"lib",
|
|
18
|
+
"dist",
|
|
19
|
+
"public",
|
|
20
|
+
"cordis.patch.yml",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"dsh": {
|
|
24
|
+
"bundle": {
|
|
25
|
+
"patch": "./cordis.patch.yml"
|
|
26
|
+
},
|
|
27
|
+
"client": {
|
|
28
|
+
"platform": "web",
|
|
29
|
+
"inject": []
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"dev": "vite",
|
|
34
|
+
"build": "tsdown && vite build",
|
|
35
|
+
"build:lib": "tsdown",
|
|
36
|
+
"build:lib:watch": "tsdown --watch",
|
|
37
|
+
"build:standalone": "vite build",
|
|
38
|
+
"preview": "vite preview"
|
|
39
|
+
},
|
|
40
|
+
"keywords": [
|
|
41
|
+
"shikeai",
|
|
42
|
+
"knowledge",
|
|
43
|
+
"dsh",
|
|
44
|
+
"deepseek-harness",
|
|
45
|
+
"cordis",
|
|
46
|
+
"plugin"
|
|
47
|
+
],
|
|
48
|
+
"author": "shikeai",
|
|
49
|
+
"license": "PolyForm-Noncommercial-1.0.0",
|
|
50
|
+
"private": false,
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=18"
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"@deepseek-ai/schemastery": "3.18.2"
|
|
56
|
+
},
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"react": "^18.0.0",
|
|
59
|
+
"react-dom": "^18.0.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@vitejs/plugin-react": "^4.3.3",
|
|
63
|
+
"react": "^18.3.1",
|
|
64
|
+
"react-dom": "^18.3.1",
|
|
65
|
+
"tsdown": "^0.22.2",
|
|
66
|
+
"vite": "^5.4.10"
|
|
67
|
+
}
|
|
68
|
+
}
|
package/README.md
DELETED