@webskill/sdk 0.0.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/dist/mcp.js ADDED
@@ -0,0 +1,513 @@
1
+ import { D as normalizeToolContent, E as mergeCatalogEntries, R as WebSkillError } from "./dist-B_ldNWwT.js";
2
+ import { fromJSONSchema } from "zod";
3
+
4
+ //#region ../mcp/dist/index.js
5
+ /**
6
+ * JSON-RPC 2.0 消息校验(守卫)。
7
+ * 规则:jsonrpc === '2.0';请求/通知有 method;响应有 id 且 result/error 恰好其一;
8
+ * error 必须含数值 code 与字符串 message。
9
+ */
10
+ function validateJsonRpcMessage(value) {
11
+ if (typeof value !== "object" || value === null) return false;
12
+ const msg = value;
13
+ if (msg["jsonrpc"] !== "2.0") return false;
14
+ const hasMethod = typeof msg["method"] === "string";
15
+ const hasValidId = typeof msg["id"] === "string" || typeof msg["id"] === "number" || msg["id"] === null;
16
+ const hasResult = "result" in msg;
17
+ const hasError = "error" in msg;
18
+ if (hasMethod) {
19
+ if ("id" in msg && !hasValidId) return false;
20
+ return !hasResult && !hasError;
21
+ }
22
+ if (!hasValidId) return false;
23
+ if (hasResult === hasError) return false;
24
+ if (hasError) {
25
+ const error = msg["error"];
26
+ if (typeof error !== "object" || error === null) return false;
27
+ const e = error;
28
+ return typeof e["code"] === "number" && typeof e["message"] === "string";
29
+ }
30
+ return true;
31
+ }
32
+ const currentOrigin = () => globalThis.location?.origin;
33
+ /**
34
+ * 跑在 MessageChannel/MessagePort 端点间的 MCP Transport。
35
+ * 入站双重校验(origin 白名单 + JSON-RPC),失败走 onerror 不静默。
36
+ */
37
+ var MessageChannelTransport = class {
38
+ onclose;
39
+ onerror;
40
+ onmessage;
41
+ #port;
42
+ #allowedOrigins;
43
+ #connectionTimeoutMs;
44
+ #state = "idle";
45
+ #listener;
46
+ #connectionTimer;
47
+ constructor(port, options = {}) {
48
+ this.#port = port;
49
+ this.#connectionTimeoutMs = options.connectionTimeoutMs ?? 0;
50
+ if (options.allowedOrigins !== void 0) this.#allowedOrigins = options.allowedOrigins;
51
+ else {
52
+ const origin = currentOrigin();
53
+ this.#allowedOrigins = origin ? [origin] : void 0;
54
+ }
55
+ }
56
+ get state() {
57
+ return this.#state;
58
+ }
59
+ async start() {
60
+ if (this.#state !== "idle") throw new Error(`MessageChannelTransport cannot start from state "${this.#state}"`);
61
+ this.#listener = (event) => this.#onInbound(event);
62
+ this.#port.addEventListener("message", this.#listener);
63
+ this.#port.start?.();
64
+ this.#state = "listening";
65
+ if (this.#connectionTimeoutMs > 0) this.#connectionTimer = setTimeout(() => {
66
+ if (this.#state !== "listening") return;
67
+ this.#state = "failed";
68
+ this.onerror?.(/* @__PURE__ */ new Error(`MessageChannelTransport connection timed out after ${this.#connectionTimeoutMs}ms`));
69
+ }, this.#connectionTimeoutMs);
70
+ }
71
+ async send(message) {
72
+ if (this.#state !== "listening" && this.#state !== "connected") throw new Error(`MessageChannelTransport cannot send in state "${this.#state}"`);
73
+ this.#port.postMessage(message);
74
+ }
75
+ async close() {
76
+ if (this.#state === "closed") return;
77
+ if (this.#connectionTimer) clearTimeout(this.#connectionTimer);
78
+ if (this.#listener) {
79
+ this.#port.removeEventListener("message", this.#listener);
80
+ this.#listener = void 0;
81
+ }
82
+ this.#port.close?.();
83
+ this.#state = "closed";
84
+ this.onclose?.();
85
+ }
86
+ #originAllowed(origin) {
87
+ if (this.#allowedOrigins === void 0) return true;
88
+ if (this.#allowedOrigins.includes("*")) return true;
89
+ if (origin === void 0 || origin === "") return true;
90
+ return this.#allowedOrigins.includes(origin);
91
+ }
92
+ #onInbound(event) {
93
+ if (this.#state !== "listening" && this.#state !== "connected") return;
94
+ if (!this.#originAllowed(event.origin)) {
95
+ this.onerror?.(/* @__PURE__ */ new Error(`MessageChannelTransport rejected message from origin "${event.origin ?? ""}"`));
96
+ return;
97
+ }
98
+ if (!validateJsonRpcMessage(event.data)) {
99
+ this.onerror?.(/* @__PURE__ */ new Error("MessageChannelTransport rejected invalid JSON-RPC message"));
100
+ return;
101
+ }
102
+ if (this.#connectionTimer) clearTimeout(this.#connectionTimer);
103
+ this.#state = "connected";
104
+ this.onmessage?.(event.data);
105
+ }
106
+ };
107
+ /** endpoint 名 → client 注册表;单调版本号,事件驱动等待(禁止轮询) */
108
+ var EndpointRegistry = class {
109
+ #clients = /* @__PURE__ */ new Map();
110
+ #versions = /* @__PURE__ */ new Map();
111
+ #waiters = /* @__PURE__ */ new Map();
112
+ /** 注册新 endpoint;重名抛错 */
113
+ register(endpoint, client) {
114
+ if (this.#clients.has(endpoint)) throw new Error(`Endpoint "${endpoint}" is already registered`);
115
+ this.#clients.set(endpoint, client);
116
+ this.#versions.set(endpoint, (this.#versions.get(endpoint) ?? 0) + 1);
117
+ this.#flushWaiters(endpoint);
118
+ }
119
+ /** 热替换 client,版本号 +1 */
120
+ set(endpoint, client) {
121
+ this.#clients.set(endpoint, client);
122
+ this.#versions.set(endpoint, (this.#versions.get(endpoint) ?? 0) + 1);
123
+ this.#flushWaiters(endpoint);
124
+ }
125
+ get(endpoint) {
126
+ const client = this.#clients.get(endpoint);
127
+ if (!client) throw new WebSkillError("MCP_ENDPOINT_UNAVAILABLE", `Endpoint "${endpoint}" is not registered`);
128
+ return client;
129
+ }
130
+ unregister(endpoint) {
131
+ this.#clients.delete(endpoint);
132
+ }
133
+ version(endpoint) {
134
+ return this.#versions.get(endpoint) ?? 0;
135
+ }
136
+ endpoints() {
137
+ return [...this.#clients.keys()];
138
+ }
139
+ /** 事件驱动等待 endpoint 出现;超时 reject */
140
+ waitFor(endpoint, timeoutMs) {
141
+ const existing = this.#clients.get(endpoint);
142
+ if (existing) return Promise.resolve(existing);
143
+ return new Promise((resolve, reject) => {
144
+ const timer = setTimeout(() => {
145
+ const queue = this.#waiters.get(endpoint);
146
+ if (queue) this.#waiters.set(endpoint, queue.filter((w) => w !== onAvailable));
147
+ reject(new WebSkillError("MCP_ENDPOINT_UNAVAILABLE", `Timed out after ${timeoutMs}ms waiting for endpoint "${endpoint}"`));
148
+ }, timeoutMs);
149
+ const onAvailable = (client) => {
150
+ clearTimeout(timer);
151
+ resolve(client);
152
+ };
153
+ const queue = this.#waiters.get(endpoint) ?? [];
154
+ queue.push(onAvailable);
155
+ this.#waiters.set(endpoint, queue);
156
+ });
157
+ }
158
+ #flushWaiters(endpoint) {
159
+ const client = this.#clients.get(endpoint);
160
+ const queue = this.#waiters.get(endpoint);
161
+ if (!client || !queue) return;
162
+ this.#waiters.delete(endpoint);
163
+ for (const resolve of queue) resolve(client);
164
+ }
165
+ };
166
+ const messageOf$2 = (e) => e instanceof Error ? e.message : String(e);
167
+ const failure$1 = (code, message) => ({
168
+ ok: false,
169
+ content: [],
170
+ error: {
171
+ code,
172
+ message
173
+ }
174
+ });
175
+ /**
176
+ * endpoint:toolName 调用 + 工具清单缓存(TTL 默认 1s + registry 版本号双失效)。
177
+ */
178
+ var McpToolResolver = class {
179
+ #registry;
180
+ #cacheTtlMs;
181
+ #cache = /* @__PURE__ */ new Map();
182
+ constructor(registry, options) {
183
+ this.#registry = registry;
184
+ this.#cacheTtlMs = options?.cacheTtlMs ?? 1e3;
185
+ }
186
+ async call(endpoint, toolName, args) {
187
+ let client;
188
+ try {
189
+ client = this.#registry.get(endpoint);
190
+ } catch (e) {
191
+ return failure$1("MCP_ENDPOINT_UNAVAILABLE", messageOf$2(e));
192
+ }
193
+ let names;
194
+ try {
195
+ names = await this.#toolNames(endpoint, client);
196
+ } catch (e) {
197
+ return failure$1("MCP_ENDPOINT_UNAVAILABLE", `Failed to list tools: ${messageOf$2(e)}`);
198
+ }
199
+ if (!names.has(toolName)) {
200
+ this.#cache.delete(endpoint);
201
+ try {
202
+ names = await this.#toolNames(endpoint, client);
203
+ } catch (e) {
204
+ return failure$1("MCP_ENDPOINT_UNAVAILABLE", `Failed to list tools: ${messageOf$2(e)}`);
205
+ }
206
+ if (!names.has(toolName)) return failure$1("MCP_TOOL_NOT_FOUND", `Tool "${toolName}" not found on endpoint "${endpoint}"`);
207
+ }
208
+ try {
209
+ const raw = await client.callTool({
210
+ name: toolName,
211
+ arguments: args
212
+ });
213
+ return this.#normalizeCallResult(raw);
214
+ } catch (e) {
215
+ return failure$1("MCP_ENDPOINT_UNAVAILABLE", `Tool "${toolName}" on endpoint "${endpoint}" failed: ${messageOf$2(e)}`);
216
+ }
217
+ }
218
+ async #toolNames(endpoint, client) {
219
+ const cached = this.#cache.get(endpoint);
220
+ if (cached && Date.now() < cached.expiresAt && cached.version === this.#registry.version(endpoint)) return cached.names;
221
+ const { tools } = await client.listTools();
222
+ const names = new Set(tools.map((t) => t.name));
223
+ this.#cache.set(endpoint, {
224
+ names,
225
+ expiresAt: Date.now() + this.#cacheTtlMs,
226
+ version: this.#registry.version(endpoint)
227
+ });
228
+ return names;
229
+ }
230
+ /** CallToolResult → ToolResult;isError 转失败;content 经共享归一 */
231
+ #normalizeCallResult(raw) {
232
+ const result = raw;
233
+ const content = normalizeToolContent(result?.content ?? raw);
234
+ if (result?.isError === true) {
235
+ const text = content.map((c) => c.text ?? "").filter(Boolean).join("\n");
236
+ return failure$1("TOOL_EXECUTION_FAILED", text || "MCP tool returned an error");
237
+ }
238
+ return {
239
+ ok: true,
240
+ content
241
+ };
242
+ }
243
+ };
244
+ /**
245
+ * LLM 可见名消毒(OpenAI 工具名只允许 [a-zA-Z0-9_-])。
246
+ * 约定:`endpoint:tool` ↔ `endpoint__tool`,`mcp#tool` ↔ `mcp__tool`;
247
+ * 反向映射基于已知前缀,无歧义。
248
+ */
249
+ function endpointToolLlmName(endpoint, toolName) {
250
+ return `${endpoint}__${toolName}`;
251
+ }
252
+ function parseEndpointToolLlmName(endpoint, llmName) {
253
+ const prefix = `${endpoint}__`;
254
+ return llmName.startsWith(prefix) && llmName.length > prefix.length ? llmName.slice(prefix.length) : void 0;
255
+ }
256
+ function webMcpToolLlmName(toolName) {
257
+ return `mcp__${toolName}`;
258
+ }
259
+ function parseWebMcpToolLlmName(llmName) {
260
+ return llmName.startsWith("mcp__") && llmName.length > 5 ? llmName.slice(5) : void 0;
261
+ }
262
+ const messageOf$1 = (e) => e instanceof Error ? e.message : String(e);
263
+ const textOfContent = (content) => {
264
+ if (typeof content === "string") return content;
265
+ if (typeof content === "object" && content !== null) {
266
+ const c = content;
267
+ if (typeof c.text === "string") return c.text;
268
+ }
269
+ return "";
270
+ };
271
+ /**
272
+ * 消费端:endpoint 的 prompts → 临时技能(source:'mcp',随 endpoint 生灭);
273
+ * resources → 可读 references(readFile 的 path 即 resource URI)。
274
+ */
275
+ var TemporarySkillProvider = class {
276
+ #registry;
277
+ #endpoint;
278
+ constructor(deps) {
279
+ this.#registry = deps.registry;
280
+ this.#endpoint = deps.endpoint;
281
+ }
282
+ /** endpoint 未注册时返回空(断开即技能消失) */
283
+ async listSkills() {
284
+ let client;
285
+ try {
286
+ client = this.#registry.get(this.#endpoint);
287
+ } catch {
288
+ return [];
289
+ }
290
+ const { prompts } = await client.listPrompts();
291
+ const resources = await client.listResources().catch(() => ({ resources: [] }));
292
+ return prompts.map((p) => ({
293
+ name: p.name,
294
+ description: p.description ?? "",
295
+ root: `mcp://${this.#endpoint}/prompts/${p.name}`,
296
+ source: "mcp",
297
+ hasScripts: false,
298
+ hasReferences: resources.resources.length > 0,
299
+ hasAssets: false
300
+ }));
301
+ }
302
+ async loadSkill(name) {
303
+ const client = this.#client();
304
+ let result;
305
+ try {
306
+ result = await client.getPrompt({ name });
307
+ } catch (e) {
308
+ throw new WebSkillError("SKILL_NOT_FOUND", `Prompt "${name}" not found on endpoint "${this.#endpoint}": ${messageOf$1(e)}`, e);
309
+ }
310
+ const body = (result.messages ?? []).map((m) => textOfContent(m.content)).filter(Boolean).join("\n\n");
311
+ return {
312
+ metadata: {
313
+ name,
314
+ description: result.description ?? ""
315
+ },
316
+ body,
317
+ location: {
318
+ skillRoot: `mcp://${this.#endpoint}/prompts/${name}`,
319
+ skillMdPath: `mcp://${this.#endpoint}/prompts/${name}`,
320
+ source: "mcp"
321
+ }
322
+ };
323
+ }
324
+ /** path 即 resource URI;blob 内容转 base64 标注 */
325
+ async readFile(name, relativePath) {
326
+ const { contents = [] } = await this.#client().readResource({ uri: relativePath });
327
+ return contents.map((c) => typeof c.text === "string" ? c.text : `[base64 ${c.mimeType ?? "application/octet-stream"}] ${c.blob ?? ""}`).join("\n");
328
+ }
329
+ #client() {
330
+ try {
331
+ return this.#registry.get(this.#endpoint);
332
+ } catch (e) {
333
+ throw new WebSkillError("MCP_ENDPOINT_UNAVAILABLE", messageOf$1(e), e);
334
+ }
335
+ }
336
+ };
337
+ /** 注册端:在页面 MCP server 上一行声明动态技能(prompt + resources + tools) */
338
+ function serveSkillAsMcp(server, skill) {
339
+ server.registerPrompt(skill.name, { description: skill.description }, async () => ({ messages: [{
340
+ role: "user",
341
+ content: {
342
+ type: "text",
343
+ text: skill.body
344
+ }
345
+ }] }));
346
+ for (const resource of skill.resources ?? []) server.registerResource(resource.name ?? resource.uri, resource.uri, { mimeType: resource.mimeType ?? "text/plain" }, async (uri) => ({ contents: [{
347
+ uri: uri.href,
348
+ text: resource.text,
349
+ mimeType: resource.mimeType ?? "text/plain"
350
+ }] }));
351
+ for (const tool of skill.tools ?? []) server.registerTool(tool.name, {
352
+ description: tool.description ?? "",
353
+ ...tool.inputSchema ? { inputSchema: fromJSONSchema(tool.inputSchema) } : {}
354
+ }, async (args) => {
355
+ return { content: normalizeToolContent(await tool.handler(args ?? {})).map((item) => item.type === "text" ? {
356
+ type: "text",
357
+ text: item.text ?? ""
358
+ } : {
359
+ type: "text",
360
+ text: JSON.stringify(item.data ?? null)
361
+ }) };
362
+ });
363
+ }
364
+ /**
365
+ * 本地/临时 Catalog 合并:同名本地优先;mcp:// URI 保留用于强制指定临时技能。
366
+ * 实现单一来源在 runtime(runtime 自身合并也用同一函数)。
367
+ */
368
+ const catalogMerge = mergeCatalogEntries;
369
+ const messageOf = (e) => e instanceof Error ? e.message : String(e);
370
+ const failure = (code, message) => ({
371
+ ok: false,
372
+ content: [],
373
+ error: {
374
+ code,
375
+ message
376
+ }
377
+ });
378
+ /** 从 listTools 返回值提取工具描述(容忍数组或 {tools:[]} 两种形状) */
379
+ function extractToolDescriptors(raw) {
380
+ const list = Array.isArray(raw) ? raw : typeof raw === "object" && raw !== null && Array.isArray(raw.tools) ? raw.tools : void 0;
381
+ if (!list) return void 0;
382
+ return list.filter((t) => typeof t === "object" && t !== null).map((t) => ({
383
+ name: String(t["name"] ?? ""),
384
+ ...typeof t["description"] === "string" ? { description: t["description"] } : {},
385
+ ...typeof t["inputSchema"] === "object" && t["inputSchema"] !== null ? { inputSchema: t["inputSchema"] } : {}
386
+ })).filter((t) => t.name !== "");
387
+ }
388
+ /**
389
+ * Experimental WebMCP Adapter(mcp# 分支):默认关闭显式启用;
390
+ * 不可用 TOOL_UNSUPPORTED;工具不存在 MCP_TOOL_NOT_FOUND。
391
+ * api 可传对象或惰性解析函数(页面异步注入 modelContext 的场景)。
392
+ */
393
+ var ExperimentalWebMcpAdapter = class {
394
+ #resolveApi;
395
+ #enabled;
396
+ constructor(api, options) {
397
+ this.#resolveApi = typeof api === "function" ? api : () => api;
398
+ this.#enabled = options?.enabled ?? false;
399
+ }
400
+ isAvailable() {
401
+ return typeof this.#resolveApi()?.executeTool === "function";
402
+ }
403
+ /** 工具清单(listTools 缺失/失败时返回 undefined);描述含 inputSchema 时透传 */
404
+ async listTools() {
405
+ const api = this.#resolveApi();
406
+ if (typeof api?.listTools !== "function") return void 0;
407
+ try {
408
+ return extractToolDescriptors(await api.listTools());
409
+ } catch {
410
+ return;
411
+ }
412
+ }
413
+ /** 工具名清单(listTools 缺失/失败时返回 undefined) */
414
+ async listToolNames() {
415
+ return (await this.listTools())?.map((t) => t.name);
416
+ }
417
+ async call(toolName, args) {
418
+ if (!this.#enabled) return failure("TOOL_UNSUPPORTED", "WebMCP adapter is disabled (enable it explicitly to use mcp# tools)");
419
+ const api = this.#resolveApi();
420
+ if (typeof api?.executeTool !== "function") return failure("TOOL_UNSUPPORTED", "navigator.modelContext is not available");
421
+ if (typeof api.listTools === "function") try {
422
+ const names = extractToolDescriptors(await api.listTools())?.map((t) => t.name);
423
+ if (names && !names.includes(toolName)) return failure("MCP_TOOL_NOT_FOUND", `WebMCP tool "${toolName}" not found`);
424
+ } catch {}
425
+ try {
426
+ return {
427
+ ok: true,
428
+ content: normalizeToolContent(await api.executeTool(toolName, JSON.stringify(args)))
429
+ };
430
+ } catch (e) {
431
+ return failure("TOOL_EXECUTION_FAILED", `WebMCP tool "${toolName}" failed: ${messageOf(e)}`);
432
+ }
433
+ }
434
+ };
435
+ /**
436
+ * runtime 扩展点实现:endpoint 注册表 + WebMCP adapter 一处装配。
437
+ * LLM 可见名:endpoint__tool / mcp__tool;call 时反向映射。
438
+ */
439
+ var McpRuntimePlugin = class {
440
+ kind = "mcp";
441
+ #registry;
442
+ #resolver;
443
+ #webMcp;
444
+ #configuredEndpoints;
445
+ constructor(deps) {
446
+ this.#registry = deps.registry;
447
+ this.#resolver = deps.resolver ?? new McpToolResolver(deps.registry);
448
+ this.#webMcp = deps.webMcp;
449
+ this.#configuredEndpoints = deps.endpoints ?? [];
450
+ }
451
+ #endpoints() {
452
+ return [.../* @__PURE__ */ new Set([...this.#configuredEndpoints, ...this.#registry.endpoints()])];
453
+ }
454
+ async listToolSpecs() {
455
+ const specs = [];
456
+ for (const endpoint of this.#endpoints()) try {
457
+ const { tools } = await this.#registry.get(endpoint).listTools();
458
+ for (const tool of tools) specs.push({
459
+ name: endpointToolLlmName(endpoint, tool.name),
460
+ ...tool.description ? { description: `[${endpoint}] ${tool.description}` } : {},
461
+ inputSchema: typeof tool.inputSchema === "object" && tool.inputSchema !== null ? tool.inputSchema : {
462
+ type: "object",
463
+ properties: {}
464
+ }
465
+ });
466
+ } catch {}
467
+ if (this.#webMcp?.isAvailable()) {
468
+ const tools = await this.#webMcp.listTools();
469
+ for (const tool of tools ?? []) specs.push({
470
+ name: webMcpToolLlmName(tool.name),
471
+ description: tool.description ?? `[webmcp] ${tool.name}`,
472
+ inputSchema: typeof tool.inputSchema === "object" && tool.inputSchema !== null ? tool.inputSchema : {
473
+ type: "object",
474
+ properties: {}
475
+ }
476
+ });
477
+ }
478
+ return specs;
479
+ }
480
+ canHandle(llmToolName) {
481
+ if (parseWebMcpToolLlmName(llmToolName) !== void 0) return true;
482
+ return this.#endpoints().some((endpoint) => parseEndpointToolLlmName(endpoint, llmToolName) !== void 0);
483
+ }
484
+ async call(llmToolName, args) {
485
+ const webMcpTool = parseWebMcpToolLlmName(llmToolName);
486
+ if (webMcpTool !== void 0) {
487
+ if (!this.#webMcp) return {
488
+ ok: false,
489
+ content: [],
490
+ error: {
491
+ code: "TOOL_UNSUPPORTED",
492
+ message: "WebMCP adapter is not configured"
493
+ }
494
+ };
495
+ return this.#webMcp.call(webMcpTool, args);
496
+ }
497
+ for (const endpoint of this.#endpoints()) {
498
+ const toolName = parseEndpointToolLlmName(endpoint, llmToolName);
499
+ if (toolName !== void 0) return this.#resolver.call(endpoint, toolName, args);
500
+ }
501
+ return {
502
+ ok: false,
503
+ content: [],
504
+ error: {
505
+ code: "TOOL_NOT_FOUND",
506
+ message: `No MCP endpoint handles tool "${llmToolName}"`
507
+ }
508
+ };
509
+ }
510
+ };
511
+
512
+ //#endregion
513
+ export { EndpointRegistry, ExperimentalWebMcpAdapter, McpRuntimePlugin, McpToolResolver, MessageChannelTransport, TemporarySkillProvider, catalogMerge, endpointToolLlmName, parseEndpointToolLlmName, parseWebMcpToolLlmName, serveSkillAsMcp, validateJsonRpcMessage, webMcpToolLlmName };
package/dist/node.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { yt as createScriptContext } from "./index-88KNOnbr.js";
2
+ import { _ as loadLlmConfigFromEnv, a as LlmEnvConfig, c as SKILLS_LOCKFILE, d as SandboxedScriptExecutor, f as SkillManager, g as VerifyResult, h as SkillsLockfile, i as LlmCapabilities, l as SKILL_MANIFEST_FILE, m as SkillSource, n as FileArtifactStore, o as NodeFS, p as SkillManifest, r as FileMemoryStore, s as NodeScriptExecutor, t as CliUiBridge, u as SandboxOptions, v as probeLlmCapabilities, y as readArchiveManifest } from "./index-Bq-bTWh3.js";
3
+ export { CliUiBridge, FileArtifactStore, FileMemoryStore, type LlmCapabilities, type LlmEnvConfig, NodeFS, NodeScriptExecutor, SKILLS_LOCKFILE, SKILL_MANIFEST_FILE, type SandboxOptions, SandboxedScriptExecutor, SkillManager, type SkillManifest, type SkillSource, type SkillsLockfile, type VerifyResult, createScriptContext, loadLlmConfigFromEnv, probeLlmCapabilities, readArchiveManifest };
package/dist/node.js ADDED
@@ -0,0 +1,4 @@
1
+ import { C as createScriptContext } from "./dist-B_ldNWwT.js";
2
+ import { a as NodeScriptExecutor, c as SandboxedScriptExecutor, d as probeLlmCapabilities, f as readArchiveManifest, i as NodeFS, l as SkillManager, n as FileArtifactStore, o as SKILLS_LOCKFILE, r as FileMemoryStore, s as SKILL_MANIFEST_FILE, t as CliUiBridge, u as loadLlmConfigFromEnv } from "./dist-9fczg9Pa.js";
3
+
4
+ export { CliUiBridge, FileArtifactStore, FileMemoryStore, NodeFS, NodeScriptExecutor, SKILLS_LOCKFILE, SKILL_MANIFEST_FILE, SandboxedScriptExecutor, SkillManager, createScriptContext, loadLlmConfigFromEnv, probeLlmCapabilities, readArchiveManifest };
@@ -0,0 +1,40 @@
1
+ import { C as InteractionRequest, X as RenderResultRequest, pt as UiBridge, w as InteractionResponse } from "./index-88KNOnbr.js";
2
+ //#region ../ui-react/dist/index.d.ts
3
+ //#region src/bridgeState.d.ts
4
+ /**
5
+ * React 桥接状态:UiBridge 实现 + useSyncExternalStore 兼容订阅。
6
+ * 应用创建实例传给 Runtime 与组件:<InteractionForm bridge={bridge} />。
7
+ */
8
+ declare class ReactBridgeState implements UiBridge {
9
+ #private;
10
+ pending: InteractionRequest | null;
11
+ latestResult: RenderResultRequest | null;
12
+ streamingText: string;
13
+ /** React useSyncExternalStore 兼容订阅 */
14
+ subscribe: (listener: () => void) => (() => void);
15
+ request(input: InteractionRequest): Promise<InteractionResponse>;
16
+ /** 组件提交/取消回调 */
17
+ resolve(response: InteractionResponse): void;
18
+ renderResult(input: RenderResultRequest): Promise<void>;
19
+ onTextDelta(_runId: string, delta: string): Promise<void>;
20
+ }
21
+ //#endregion
22
+ //#region src/components/InteractionForm.d.ts
23
+ /** 订阅 bridge.pending 渲染交互表单;提交/取消经 bridge.resolve 回传 */
24
+ declare function InteractionForm({ bridge }: {
25
+ bridge: ReactBridgeState;
26
+ }): import("react").JSX.Element | null;
27
+ //#endregion
28
+ //#region src/components/ResultBlocks.d.ts
29
+ /** 订阅 bridge.latestResult 渲染五种 RenderBlock */
30
+ declare function ResultBlocks({ bridge }: {
31
+ bridge: ReactBridgeState;
32
+ }): import("react").JSX.Element | null;
33
+ //#endregion
34
+ //#region src/components/StreamingText.d.ts
35
+ /** 订阅 bridge.streamingText 增量渲染流式文本 */
36
+ declare function StreamingText({ bridge }: {
37
+ bridge: ReactBridgeState;
38
+ }): import("react").JSX.Element | null;
39
+ //#endregion
40
+ export { InteractionForm, ReactBridgeState, ResultBlocks, StreamingText };