@webskill/sdk 0.2.3 → 0.2.4

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/browser.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as FileStat, I as SkillInstallSource, K as VerifyResult, W as SkillsLockfile, _ as RenderResultRequest, a as InteractionPolicy, c as LlmClient, d as LlmResponse, f as LlmStreamEvent, o as InteractionRequest, s as InteractionResponse, v as UiBridge, w as FileSystemProvider, y as ArchiveLimits, z as SkillManifest } from "./types-CKm5G_eQ-8W8FnP4u.js";
2
- import { N as NetworkPolicy, Q as ScriptExecutor, Z as ScriptExecutionContext, d as BridgeCapabilities, it as ToolResult, m as BridgeResponse, nt as ToolDefinition, p as BridgeRequest, pt as bridgeError, u as ApprovalScope, ut as WebSkillApi, v as ExternalSkillProvider, wt as parseBridgeRequest, y as ExternalToolSource } from "./index-gjFuBevI.js";
1
+ import { C as FileStat, I as SkillInstallSource, K as VerifyResult, W as SkillsLockfile, _ as RenderResultRequest, a as InteractionPolicy, c as LlmClient, d as LlmResponse, f as LlmStreamEvent, o as InteractionRequest, s as InteractionResponse, v as UiBridge, w as FileSystemProvider, y as ArchiveLimits, z as SkillManifest } from "./types-CKm5G_eQ-BqyXnvoR.js";
2
+ import { Et as parseBridgeRequest, N as NetworkPolicy, Q as ScriptExecutor, Z as ScriptExecutionContext, d as BridgeCapabilities, it as ToolResult, m as BridgeResponse, nt as ToolDefinition, p as BridgeRequest, pt as bridgeError, u as ApprovalScope, ut as WebSkillApi, v as ExternalSkillProvider, y as ExternalToolSource } from "./index-DZShzhon.js";
3
3
  //#region ../browser/dist/index.d.ts
4
4
  //#region src/fs/featureDetection.d.ts
5
5
  /** 检测当前环境是否可用 OPFS(navigator.storage.getDirectory) */
@@ -15,6 +15,7 @@ declare class OpfsProvider implements FileSystemProvider {
15
15
  });
16
16
  readText(p: string): Promise<string>;
17
17
  writeText(p: string, content: string): Promise<void>;
18
+ appendText(p: string, content: string): Promise<void>;
18
19
  readBinary(p: string): Promise<Uint8Array>;
19
20
  writeBinary(p: string, content: Uint8Array): Promise<void>;
20
21
  exists(p: string): Promise<boolean>;
package/dist/browser.js CHANGED
@@ -1,6 +1,6 @@
1
- import { A as unzipWithLimits, C as parseSkillMarkdown, M as verifyManifest, T as readResponseWithLimit, b as isValidSkillName, c as SkillDiscovery, f as atomicWriteText, i as SKILL_MANIFEST_FILE, j as validateSkills, k as resolveInsideRoot, m as buildManifest, p as buildCatalog, r as SKILLS_LOCKFILE, s as SKILL_PACK_FILE, u as WebSkillError, w as parseSkillPackManifest, y as exportSkills } from "./dist-D0saNPi_.js";
2
- import { A as isNetworkAllowed, C as bridgeError, E as createWebSkillApi, M as networkUrlHost, N as normalizeToolContent, P as parseBridgeRequest, c as FsArtifactStore, h as ProgressiveRouter, i as AgentLoop, j as mergeCatalogEntries, l as FsMemoryStore, m as OpenAiCompatibleClient, o as CapabilityApproval, u as FsRunSnapshotStore, y as RUN_SNAPSHOT_SCHEMA_VERSION } from "./dist-NM4Mylx4.js";
3
- import { n as MockLlmClient } from "./testing-B4pq6JYa.js";
1
+ import { A as unzipWithLimits, C as parseSkillMarkdown, M as verifyManifest, T as readResponseWithLimit, b as isValidSkillName, c as SkillDiscovery, f as atomicWriteText, i as SKILL_MANIFEST_FILE, j as validateSkills, k as resolveInsideRoot, m as buildManifest, p as buildCatalog, r as SKILLS_LOCKFILE, s as SKILL_PACK_FILE, u as WebSkillError, w as parseSkillPackManifest, y as exportSkills } from "./dist-D7MsoMPx.js";
2
+ import { A as isNetworkAllowed, C as bridgeError, E as createWebSkillApi, F as normalizeToolError, I as parseBridgeRequest, M as networkUrlHost, P as normalizeToolContent, c as FsArtifactStore, h as ProgressiveRouter, i as AgentLoop, j as mergeCatalogEntries, l as FsMemoryStore, m as OpenAiCompatibleClient, o as CapabilityApproval, u as FsRunSnapshotStore, y as RUN_SNAPSHOT_SCHEMA_VERSION } from "./dist-CV64gN62.js";
3
+ import { n as MockLlmClient } from "./testing-BN18eqbD.js";
4
4
 
5
5
  //#region ../browser/dist/index.js
6
6
  /** 检测当前环境是否可用 OPFS(navigator.storage.getDirectory) */
@@ -57,6 +57,22 @@ var OpfsProvider = class {
57
57
  async writeText(p, content) {
58
58
  await this.writeBinary(p, new TextEncoder().encode(content));
59
59
  }
60
+ async appendText(p, content) {
61
+ await this.#wrap(p, async () => {
62
+ const segments = this.#segments(p);
63
+ const name = segments.pop();
64
+ if (!name) throw new WebSkillError("FS_NOT_FOUND", `Invalid file path: ${p}`);
65
+ const handle = await (await this.#walkDir(`/${segments.join("/")}`, true)).getFileHandle(name, { create: true });
66
+ const size = (await handle.getFile()).size;
67
+ const writable = await handle.createWritable({ keepExistingData: true });
68
+ await writable.write({
69
+ type: "write",
70
+ position: size,
71
+ data: content
72
+ });
73
+ await writable.close();
74
+ });
75
+ }
60
76
  async readBinary(p) {
61
77
  return this.#wrap(p, async () => {
62
78
  const handle = await this.#walkFile(p);
@@ -232,6 +248,16 @@ function loadModule(source) {
232
248
  return import(url);
233
249
  }
234
250
 
251
+ function assertSerializable(value) {
252
+ try {
253
+ structuredClone(value);
254
+ } catch (e) {
255
+ var err = new Error('Script returned a non-serializable value: ' + String((e && e.message) || e));
256
+ err.code = 'TOOL_EXECUTION_FAILED';
257
+ throw err;
258
+ }
259
+ }
260
+
235
261
  function postError(type, id, code, message, extra) {
236
262
  var msg = { type: type, id: id, ok: false, error: { code: code, message: message } };
237
263
  if (extra) Object.assign(msg, extra);
@@ -326,6 +352,7 @@ self.onmessage = async function (event) {
326
352
  throw new Error('Script does not export a run function');
327
353
  }
328
354
  var value = await mod2.run(msg.args, makeContext(msg));
355
+ assertSerializable(value);
329
356
  self.postMessage({
330
357
  type: 'execute-result', id: msg.id, ok: true,
331
358
  value: value === undefined ? null : value,
@@ -940,12 +967,13 @@ var BrowserWorkerScriptExecutor = class {
940
967
  }, timeoutMs, (bridgeRequest) => this.#handleBridge(bridgeRequest, context), (host) => context.onWarning?.(`Network request blocked by sandbox network policy: ${host}`));
941
968
  if (!response.ok) {
942
969
  const stderrSummary = response.stderr?.length ? ` | stderr: ${response.stderr.join(" | ").slice(0, 500)}` : "";
970
+ const normalized = normalizeToolError(response.error?.code, response.error?.message ?? "script execution failed");
943
971
  return {
944
972
  ok: false,
945
973
  content: [],
946
974
  error: {
947
- code: response.error?.code ?? "TOOL_EXECUTION_FAILED",
948
- message: `${response.error?.message ?? "script execution failed"}${stderrSummary}`
975
+ code: normalized.code,
976
+ message: `${normalized.message}${stderrSummary}`
949
977
  }
950
978
  };
951
979
  }
@@ -1,4 +1,4 @@
1
- import { C as parseSkillMarkdown, E as renderAvailableSkillsXml, c as SkillDiscovery, d as assertSafePathSegment, j as validateSkills, k as resolveInsideRoot, l as SkillReader, p as buildCatalog, u as WebSkillError } from "./dist-D0saNPi_.js";
1
+ import { C as parseSkillMarkdown, E as renderAvailableSkillsXml, c as SkillDiscovery, d as assertSafePathSegment, j as validateSkills, k as resolveInsideRoot, l as SkillReader, p as buildCatalog, u as WebSkillError } from "./dist-D7MsoMPx.js";
2
2
  import { t as MemoryArtifactStore } from "./memoryArtifactStore-C9lFVqPF-yFz6yJj0.js";
3
3
 
4
4
  //#region ../runtime/dist/index.js
@@ -272,7 +272,7 @@ var AnthropicClient = class {
272
272
  "content-type": "application/json",
273
273
  "x-api-key": this.#config.apiKey,
274
274
  "anthropic-version": ANTHROPIC_VERSION,
275
- "anthropic-dangerous-direct-browser-access": "true"
275
+ ...this.#config.dangerouslyAllowDirectBrowserAccess ? { "anthropic-dangerous-direct-browser-access": "true" } : {}
276
276
  };
277
277
  }
278
278
  async complete(input) {
@@ -571,7 +571,7 @@ var GoogleGenAiClient = class {
571
571
  }
572
572
  async #post(input, stream) {
573
573
  const model = input.model ?? this.#config.model;
574
- const action = stream ? `:streamGenerateContent?alt=sse&key=${encodeURIComponent(this.#config.apiKey)}` : `:generateContent?key=${encodeURIComponent(this.#config.apiKey)}`;
574
+ const action = stream ? ":streamGenerateContent?alt=sse" : ":generateContent";
575
575
  const { systemInstruction, contents } = toGenAiContents(input.messages);
576
576
  const body = { contents };
577
577
  if (systemInstruction) body["systemInstruction"] = systemInstruction;
@@ -581,7 +581,10 @@ var GoogleGenAiClient = class {
581
581
  try {
582
582
  res = await this.#fetch(`${this.#baseUrl()}/v1beta/models/${encodeURIComponent(model)}${action}`, {
583
583
  method: "POST",
584
- headers: { "content-type": "application/json" },
584
+ headers: {
585
+ "content-type": "application/json",
586
+ "x-goog-api-key": this.#config.apiKey
587
+ },
585
588
  body: JSON.stringify(body),
586
589
  signal: input.signal ?? (this.#config.requestTimeoutMs ? AbortSignal.timeout(this.#config.requestTimeoutMs) : null)
587
590
  });
@@ -597,7 +600,7 @@ var GoogleGenAiClient = class {
597
600
  /** 轻量探测(GET /v1beta/models),集成测试据此决定 skip */
598
601
  async checkAvailability() {
599
602
  try {
600
- return (await this.#fetch(`${this.#baseUrl()}/v1beta/models?key=${encodeURIComponent(this.#config.apiKey)}`)).ok;
603
+ return (await this.#fetch(`${this.#baseUrl()}/v1beta/models`, { headers: { "x-goog-api-key": this.#config.apiKey } })).ok;
601
604
  } catch {
602
605
  return false;
603
606
  }
@@ -846,11 +849,12 @@ const ASK_USER_TOOL = {
846
849
  */
847
850
  function createScriptContext(deps) {
848
851
  const { fs, artifactStore, skillName, skillRoot, runId, confirm, onWarning, onArtifactCreated } = deps;
852
+ const readFs = fs.withRoot?.(skillRoot) ?? fs;
849
853
  return {
850
854
  skillName,
851
855
  runId,
852
856
  async readReference(relativePath) {
853
- return fs.readText(resolveInsideRoot(skillRoot, `references/${relativePath}`));
857
+ return readFs.readText(resolveInsideRoot(skillRoot, `references/${relativePath}`));
854
858
  },
855
859
  async writeArtifact(path, content, options) {
856
860
  const artifact = typeof content === "string" ? await artifactStore.createTextArtifact({
@@ -1734,14 +1738,20 @@ var AgentLoop = class {
1734
1738
  const text = JSON.stringify(result);
1735
1739
  const max = this.#config.toolResultMaxBytes;
1736
1740
  if (text.length <= max) return text;
1737
- const artifact = await this.#deps.artifactStore.createTextArtifact({
1738
- runId: state.runId,
1739
- path: `tool-results/${call.id}.json`,
1740
- content: text
1741
- });
1741
+ let note;
1742
+ try {
1743
+ note = `full tool result saved as artifact "${(await this.#deps.artifactStore.createTextArtifact({
1744
+ runId: state.runId,
1745
+ path: `tool-results/${call.id}.json`,
1746
+ content: text
1747
+ })).id}"`;
1748
+ } catch (e) {
1749
+ state.trace.record("run.warning", { message: `Failed to persist oversized tool result artifact for "${call.name}": ${messageOf$1(e)}` });
1750
+ note = "full result discarded (artifact store unavailable)";
1751
+ }
1742
1752
  const head = text.slice(0, Math.floor(max * .6));
1743
1753
  const tail = text.slice(-Math.floor(max * .3));
1744
- return `${head}\n...[truncated ${text.length - head.length - tail.length} chars; full tool result saved as artifact "${artifact.id}"]...\n${tail}`;
1754
+ return `${head}\n...[truncated ${text.length - head.length - tail.length} chars; ${note}]...\n${tail}`;
1745
1755
  }
1746
1756
  /** SkillStateGuard 判定(无注入默认全放行;仅显式 false 拦截) */
1747
1757
  async #guardDenied(kind, skillName) {
@@ -2637,6 +2647,67 @@ function networkUrlHost(url) {
2637
2647
  return "(unparseable-url)";
2638
2648
  }
2639
2649
  }
2650
+ /** WebSkillErrorCode 全量白名单(错误码归一用;与 core errors.ts 保持同步) */
2651
+ const WHITELIST = /* @__PURE__ */ new Set([
2652
+ "FS_NOT_FOUND",
2653
+ "FS_PATH_OUTSIDE_ROOT",
2654
+ "SKILL_NOT_FOUND",
2655
+ "SKILL_INVALID_METADATA",
2656
+ "SKILL_INVALID_NAME",
2657
+ "SKILL_DUPLICATE_NAME",
2658
+ "SKILL_UNSUPPORTED_SCRIPT",
2659
+ "VALIDATION_FAILED",
2660
+ "TOOL_NOT_FOUND",
2661
+ "TOOL_EXECUTION_FAILED",
2662
+ "NETWORK_BLOCKED",
2663
+ "TOOL_UNSUPPORTED",
2664
+ "TOOL_SCHEMA_UNAVAILABLE",
2665
+ "RUN_TIMEOUT",
2666
+ "RUN_MAX_TURNS_EXCEEDED",
2667
+ "RUN_FAILED",
2668
+ "RUN_CANCELLED",
2669
+ "RUN_INTERACTION_TIMEOUT",
2670
+ "UI_UNAVAILABLE",
2671
+ "LLM_UNAVAILABLE",
2672
+ "LLM_REQUEST_FAILED",
2673
+ "INSTALL_FAILED",
2674
+ "UNINSTALL_FAILED",
2675
+ "EXPORT_FAILED",
2676
+ "INTEGRITY_FAILED",
2677
+ "FS_PERMISSION_DENIED",
2678
+ "MCP_ENDPOINT_UNAVAILABLE",
2679
+ "MCP_TOOL_NOT_FOUND",
2680
+ "CANDIDATE_INVALID",
2681
+ "APPROVAL_REQUIRED",
2682
+ "SKILL_QUARANTINED",
2683
+ "SKILL_DISABLED",
2684
+ "SKILL_UNKNOWN_ALLOWED_TOOL",
2685
+ "SKILL_UNKNOWN_DEPENDENCY",
2686
+ "SKILL_CIRCULAR_DEPENDENCY",
2687
+ "GOVERNANCE_FAILED",
2688
+ "RUN_SNAPSHOT_NOT_FOUND",
2689
+ "RUN_SNAPSHOT_EXPIRED",
2690
+ "RUN_SNAPSHOT_INCOMPATIBLE"
2691
+ ]);
2692
+ /**
2693
+ * 错误码白名单归一:沙箱/桥消息里出现的非白名单码(DOMException 数值码、
2694
+ * Node 任意 ERR_* 码等)一律归为 TOOL_EXECUTION_FAILED。
2695
+ */
2696
+ function normalizeErrorCode(code) {
2697
+ return typeof code === "string" && WHITELIST.has(code) ? code : "TOOL_EXECUTION_FAILED";
2698
+ }
2699
+ /** 归一化后的 (code, message):非白名单码保留在 message 尾部([original code: X]) */
2700
+ function normalizeToolError(code, message) {
2701
+ const normalized = normalizeErrorCode(code);
2702
+ if (typeof code === "string" && normalized === code) return {
2703
+ code: normalized,
2704
+ message
2705
+ };
2706
+ return {
2707
+ code: normalized,
2708
+ message: `${message} [original code: ${String(code)}]`
2709
+ };
2710
+ }
2640
2711
  /**
2641
2712
  * Per-capability 强制授权判定(宿主侧,browser/node 执行器共用单一来源)。
2642
2713
  * 'require-approval' 模式下经注入的 UiBridge 发 authorize 交互;
@@ -2661,6 +2732,7 @@ var CapabilityApproval = class CapabilityApproval {
2661
2732
  async authorize(input) {
2662
2733
  const { runId, capability, mode } = input;
2663
2734
  if (mode === false) return "disabled";
2735
+ if (mode !== true && mode !== "require-approval") return "disabled";
2664
2736
  if (mode !== "require-approval") return "allowed";
2665
2737
  if (this.#scope === "once-per-run" && this.#approved.get(runId)?.has(capability)) return "allowed";
2666
2738
  if (!this.#uiBridge) return "denied";
@@ -2688,4 +2760,4 @@ var CapabilityApproval = class CapabilityApproval {
2688
2760
  };
2689
2761
 
2690
2762
  //#endregion
2691
- export { isNetworkAllowed as A, bridgeError as C, extractChartSpec as D, createWebSkillApi as E, resolveToolName as F, schemaToForm as I, toLlmToolSpec as L, networkUrlHost as M, normalizeToolContent as N, fromVercelResult as O, parseBridgeRequest as P, toVercelToolSpecs as R, WebSkillRuntime as S, createScriptContext as T, READ_SKILL_FILE_TOOL as _, AnthropicClient as a, SerializingMemoryStore as b, FsArtifactStore as c, FullDisclosureRouter as d, GoogleGenAiClient as f, READ_SKILL_FILE_INPUT_SCHEMA as g, ProgressiveRouter as h, AgentLoop as i, mergeCatalogEntries as j, fromVercelStreamPart as k, FsMemoryStore as l, OpenAiCompatibleClient as m, ASK_USER_TOOL as n, CapabilityApproval as o, HookRunner as p, ASK_USER_TOOL_NAME as r, EventBus as s, ASK_USER_INPUT_SCHEMA as t, FsRunSnapshotStore as u, READ_SKILL_FILE_TOOL_NAME as v, buildRenderResult as w, TraceRecorder as x, RUN_SNAPSHOT_SCHEMA_VERSION as y };
2763
+ export { isNetworkAllowed as A, toVercelToolSpecs as B, bridgeError as C, extractChartSpec as D, createWebSkillApi as E, normalizeToolError as F, parseBridgeRequest as I, resolveToolName as L, networkUrlHost as M, normalizeErrorCode as N, fromVercelResult as O, normalizeToolContent as P, schemaToForm as R, WebSkillRuntime as S, createScriptContext as T, READ_SKILL_FILE_TOOL as _, AnthropicClient as a, SerializingMemoryStore as b, FsArtifactStore as c, FullDisclosureRouter as d, GoogleGenAiClient as f, READ_SKILL_FILE_INPUT_SCHEMA as g, ProgressiveRouter as h, AgentLoop as i, mergeCatalogEntries as j, fromVercelStreamPart as k, FsMemoryStore as l, OpenAiCompatibleClient as m, ASK_USER_TOOL as n, CapabilityApproval as o, HookRunner as p, ASK_USER_TOOL_NAME as r, EventBus as s, ASK_USER_INPUT_SCHEMA as t, FsRunSnapshotStore as u, READ_SKILL_FILE_TOOL_NAME as v, buildRenderResult as w, TraceRecorder as x, RUN_SNAPSHOT_SCHEMA_VERSION as y, toLlmToolSpec as z };
@@ -1,4 +1,4 @@
1
- import { u as WebSkillError } from "./dist-D0saNPi_.js";
1
+ import { u as WebSkillError } from "./dist-D7MsoMPx.js";
2
2
 
3
3
  //#region ../ui/dist/index.js
4
4
  /** 提交值按请求类型归形(WebFormBridge 与框架组件库共享单一来源) */
@@ -1,5 +1,5 @@
1
- import { A as unzipWithLimits, C as parseSkillMarkdown, M as verifyManifest, O as resolveArchiveLimits, T as readResponseWithLimit, b as isValidSkillName, f as atomicWriteText, i as SKILL_MANIFEST_FILE, j as validateSkills, k as resolveInsideRoot, m as buildManifest, r as SKILLS_LOCKFILE, s as SKILL_PACK_FILE, u as WebSkillError, w as parseSkillPackManifest, y as exportSkills } from "./dist-D0saNPi_.js";
2
- import { A as isNetworkAllowed, C as bridgeError, M as networkUrlHost, N as normalizeToolContent, P as parseBridgeRequest, c as FsArtifactStore, l as FsMemoryStore, o as CapabilityApproval } from "./dist-NM4Mylx4.js";
1
+ import { A as unzipWithLimits, C as parseSkillMarkdown, M as verifyManifest, O as resolveArchiveLimits, T as readResponseWithLimit, b as isValidSkillName, f as atomicWriteText, i as SKILL_MANIFEST_FILE, j as validateSkills, k as resolveInsideRoot, m as buildManifest, r as SKILLS_LOCKFILE, s as SKILL_PACK_FILE, u as WebSkillError, w as parseSkillPackManifest, y as exportSkills } from "./dist-D7MsoMPx.js";
2
+ import { A as isNetworkAllowed, C as bridgeError, F as normalizeToolError, I as parseBridgeRequest, M as networkUrlHost, P as normalizeToolContent, c as FsArtifactStore, l as FsMemoryStore, o as CapabilityApproval } from "./dist-CV64gN62.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { unzipSync, zipSync } from "fflate";
5
5
  import { existsSync, promises, realpathSync } from "node:fs";
@@ -37,13 +37,16 @@ async function realpathNearest(platformPath) {
37
37
  * 可选 root 模式:构造传入 root 后,read/write 操作先做 realpath 包含校验
38
38
  * (root 与目标都 realpath 后前缀比对),经符号链接逃逸 root → FS_PATH_OUTSIDE_ROOT。
39
39
  */
40
- var NodeFS = class {
40
+ var NodeFS = class NodeFS {
41
41
  kind = "node";
42
42
  #root;
43
43
  constructor(deps = {}) {
44
44
  this.#root = deps.root;
45
45
  }
46
- /** root 模式:目标 realpath 必须落在 root realpath 前缀内(符号链接逃逸防护) */
46
+ /** root 模式:全部方法(read/write/exists/stat/list/mkdir/remove/rename)目标 realpath 必须落在 root realpath 前缀内 */
47
+ withRoot(root) {
48
+ return new NodeFS({ root });
49
+ }
47
50
  async #assertContained(p) {
48
51
  if (!this.#root) return;
49
52
  const rootReal = await promises.realpath(toPlatform$4(this.#root));
@@ -64,6 +67,12 @@ var NodeFS = class {
64
67
  await promises.mkdir(path.dirname(target), { recursive: true });
65
68
  await promises.writeFile(target, content, "utf8");
66
69
  }
70
+ async appendText(p, content) {
71
+ await this.#assertContained(p);
72
+ const target = toPlatform$4(p);
73
+ await promises.mkdir(path.dirname(target), { recursive: true });
74
+ await promises.appendFile(target, content, "utf8");
75
+ }
67
76
  async readBinary(p) {
68
77
  await this.#assertContained(p);
69
78
  try {
@@ -79,6 +88,7 @@ var NodeFS = class {
79
88
  await promises.writeFile(target, content);
80
89
  }
81
90
  async exists(p) {
91
+ await this.#assertContained(p);
82
92
  try {
83
93
  await promises.access(toPlatform$4(p));
84
94
  return true;
@@ -87,6 +97,7 @@ var NodeFS = class {
87
97
  }
88
98
  }
89
99
  async stat(p) {
100
+ await this.#assertContained(p);
90
101
  try {
91
102
  const s = await promises.stat(toPlatform$4(p));
92
103
  return {
@@ -100,6 +111,7 @@ var NodeFS = class {
100
111
  }
101
112
  }
102
113
  async list(p) {
114
+ await this.#assertContained(p);
103
115
  let dirents;
104
116
  try {
105
117
  dirents = await promises.readdir(toPlatform$4(p), { withFileTypes: true });
@@ -112,9 +124,11 @@ var NodeFS = class {
112
124
  }));
113
125
  }
114
126
  async mkdir(p) {
127
+ await this.#assertContained(p);
115
128
  await promises.mkdir(toPlatform$4(p), { recursive: true });
116
129
  }
117
130
  async remove(p, options) {
131
+ await this.#assertContained(p);
118
132
  try {
119
133
  await promises.rm(toPlatform$4(p), { recursive: options?.recursive ?? false });
120
134
  } catch (e) {
@@ -122,6 +136,8 @@ var NodeFS = class {
122
136
  }
123
137
  }
124
138
  async rename(from, to) {
139
+ await this.#assertContained(from);
140
+ await this.#assertContained(to);
125
141
  await promises.mkdir(path.dirname(toPlatform$4(to)), { recursive: true });
126
142
  try {
127
143
  await promises.rename(toPlatform$4(from), toPlatform$4(to));
@@ -381,12 +397,13 @@ var SandboxedScriptExecutor = class {
381
397
  }, timeoutMs, (request) => this.#handleBridge(request, context), (host) => context.onWarning?.(`Network request blocked by sandbox network policy: ${host}`));
382
398
  if (!result.ok) {
383
399
  const stderrSummary = result.stderr?.length ? ` | stderr: ${result.stderr.join(" | ").slice(0, 500)}` : "";
400
+ const normalized = normalizeToolError(result.error?.code, result.error?.message ?? "script execution failed");
384
401
  return {
385
402
  ok: false,
386
403
  content: [],
387
404
  error: {
388
- code: result.error?.code ?? "TOOL_EXECUTION_FAILED",
389
- message: `${result.error?.message ?? "script execution failed"}${stderrSummary}`
405
+ code: normalized.code,
406
+ message: `${normalized.message}${stderrSummary}`
390
407
  }
391
408
  };
392
409
  }
@@ -463,7 +480,7 @@ var SandboxedScriptExecutor = class {
463
480
  });
464
481
  worker.on("error", (e) => done(() => reject(e)));
465
482
  worker.on("exit", (code) => {
466
- if (code !== 0) done(() => reject(new WebSkillError("TOOL_EXECUTION_FAILED", `Sandbox worker exited with code ${code}`)));
483
+ if (!settled) done(() => reject(new WebSkillError("TOOL_EXECUTION_FAILED", `Sandbox worker exited ${code === null ? "by signal" : `with code ${code}`} without producing a result`)));
467
484
  });
468
485
  });
469
486
  }
@@ -713,12 +730,13 @@ var ProcessSandboxExecutor = class {
713
730
  }, timeoutMs, (request) => this.#handleBridge(request, context), (host) => context.onWarning?.(`Network request blocked by sandbox network policy: ${host}`));
714
731
  if (!result.ok) {
715
732
  const stderrSummary = result.stderr?.length ? ` | stderr: ${result.stderr.join(" | ").slice(0, 500)}` : "";
733
+ const normalized = normalizeToolError(result.error?.code, result.error?.message ?? "script execution failed");
716
734
  return {
717
735
  ok: false,
718
736
  content: [],
719
737
  error: {
720
- code: result.error?.code ?? "TOOL_EXECUTION_FAILED",
721
- message: `${result.error?.message ?? "script execution failed"}${stderrSummary}`
738
+ code: normalized.code,
739
+ message: `${normalized.message}${stderrSummary}`
722
740
  }
723
741
  };
724
742
  }
@@ -111,6 +111,18 @@ var MemoryFS = class {
111
111
  async writeText(path, content) {
112
112
  await this.writeBinary(path, new TextEncoder().encode(content));
113
113
  }
114
+ async appendText(path, content) {
115
+ const key = this.#normalize(path);
116
+ const existing = this.#entries.get(key);
117
+ if (existing && existing.type !== "file") throw new WebSkillError("FS_PERMISSION_DENIED", `Cannot append to a directory: ${key}`);
118
+ const prior = existing ? new TextDecoder().decode(existing.content) : "";
119
+ this.#ensureParents(key);
120
+ this.#entries.set(key, {
121
+ type: "file",
122
+ content: new TextEncoder().encode(prior + content),
123
+ mtimeMs: Date.now()
124
+ });
125
+ }
114
126
  async readBinary(path) {
115
127
  return this.#getFile(this.#normalize(path)).content;
116
128
  }
@@ -203,7 +215,9 @@ function normalizePath(path) {
203
215
  * 拒绝空串、`.`、`..`、含 `/` 或 `\`、含 `:`(Windows 盘符/ADS)。
204
216
  * 违规抛 FS_PATH_OUTSIDE_ROOT(kind 用于错误消息定位,如 "runId")。
205
217
  */
218
+ const CONTROL_CHARS_RE = /[\x00-\x1f\x7f]/;
206
219
  function assertSafePathSegment(segment, kind) {
220
+ if (CONTROL_CHARS_RE.test(segment)) throw new WebSkillError("FS_PATH_OUTSIDE_ROOT", `Invalid ${kind} (control characters including NUL are not allowed): ${JSON.stringify(segment)}`);
207
221
  if (segment === "" || segment === "." || segment === ".." || segment.includes("/") || segment.includes("\\") || segment.includes(":")) throw new WebSkillError("FS_PATH_OUTSIDE_ROOT", `Invalid ${kind} (must be a single safe path segment): ${JSON.stringify(segment)}`);
208
222
  }
209
223
  /**
@@ -221,6 +235,7 @@ function resolveInsideRoot(root, relativePath) {
221
235
  if (relativePath.trim() === "") fail("empty path");
222
236
  if (relativePath.startsWith("/") || relativePath.startsWith("\\") || /^[a-zA-Z]:[\\/]/.test(relativePath)) fail("absolute paths not allowed");
223
237
  const segments = relativePath.replace(/\\/g, "/").split("/");
238
+ if (CONTROL_CHARS_RE.test(relativePath)) fail("control characters including NUL are not allowed");
224
239
  if (segments.some((s) => s === "..")) fail("`..` segments not allowed");
225
240
  const clean = segments.filter((s) => s !== "" && s !== ".");
226
241
  if (clean.length === 0) fail("path resolves to empty");
@@ -392,6 +407,7 @@ async function exportSkills(fs, input) {
392
407
  for (const root of input.roots) {
393
408
  const base = root.replace(/\/+$/, "");
394
409
  const manifest = await input.manifestBuilder(base);
410
+ if (!isValidSkillName(manifest.name)) throw new WebSkillError("EXPORT_FAILED", `Skill "${manifest.name}" has an invalid name and cannot be exported to a skill pack`);
395
411
  skills.push({
396
412
  name: manifest.name,
397
413
  digest: manifest.integrity.digest
@@ -427,7 +443,7 @@ function parseSkillPackManifest(text) {
427
443
  for (const entry of record["skills"]) {
428
444
  if (typeof entry !== "object" || entry === null) invalid("skill entry is not an object");
429
445
  const { name, digest } = entry;
430
- if (typeof name !== "string" || name === "") invalid("skill entry missing a valid \"name\"");
446
+ if (typeof name !== "string" || name === "" || !isValidSkillName(name)) invalid(`skill entry has an invalid name: ${JSON.stringify(name)}`);
431
447
  if (typeof digest !== "string" || digest === "") invalid(`skill "${name}" missing a valid "digest"`);
432
448
  }
433
449
  return raw;
@@ -468,6 +484,14 @@ async function unzipWithLimits(data, limits) {
468
484
  const unzip = new Unzip();
469
485
  unzip.register(UnzipInflate);
470
486
  unzip.onfile = (file) => {
487
+ if (file.name.startsWith("/") || file.name.startsWith("\\") || /^[a-zA-Z]:[\\/]/.test(file.name)) {
488
+ failure = new WebSkillError("INSTALL_FAILED", `Archive entry escapes the destination root: ${file.name}`);
489
+ return;
490
+ }
491
+ if (file.name.replace(/\\/g, "/").split("/").some((s) => s === "..") || /[\x00-\x1f\x7f]/.test(file.name)) {
492
+ failure = new WebSkillError("INSTALL_FAILED", `Archive entry escapes the destination root: ${file.name}`);
493
+ return;
494
+ }
471
495
  if (file.name.endsWith("/")) {
472
496
  entries.push([file.name, /* @__PURE__ */ new Uint8Array(0)]);
473
497
  return;
@@ -579,7 +603,7 @@ var SkillDiscovery = class {
579
603
  const candidates = [];
580
604
  const knownSkillNames = /* @__PURE__ */ new Set();
581
605
  const adjacency = /* @__PURE__ */ new Map();
582
- for (const root of this.#roots) {
606
+ for (const [rootIndex, root] of this.#roots.entries()) {
583
607
  if (!await this.#fs.exists(root)) {
584
608
  issues.push({
585
609
  code: "FS_NOT_FOUND",
@@ -604,6 +628,7 @@ var SkillDiscovery = class {
604
628
  candidates.push({
605
629
  dirName,
606
630
  skillRoot,
631
+ rootIndex,
607
632
  hasSkillMd,
608
633
  metadata,
609
634
  parseError,
@@ -616,6 +641,7 @@ var SkillDiscovery = class {
616
641
  }
617
642
  }));
618
643
  }
644
+ candidates.sort((a, b) => a.rootIndex - b.rootIndex || a.dirName.localeCompare(b.dirName));
619
645
  const cycles = checkDependencyCycles(adjacency);
620
646
  const claimedNames = /* @__PURE__ */ new Set();
621
647
  for (const candidate of candidates) {
@@ -1,6 +1,6 @@
1
- import { F as SkillDocument, N as SkillCatalogEntry, c as LlmClient, u as LlmMessage, v as UiBridge, w as FileSystemProvider, z as SkillManifest } from "./types-CKm5G_eQ-8W8FnP4u.js";
2
- import { Q as ScriptExecutor, dt as WebSkillRuntime, ft as WebSkillRuntimeDeps, q as RuntimeRun, tt as SkillStateGuard } from "./index-gjFuBevI.js";
3
- import { d as SkillManager } from "./index-iqcz3_NS.js";
1
+ import { F as SkillDocument, N as SkillCatalogEntry, c as LlmClient, u as LlmMessage, v as UiBridge, w as FileSystemProvider, z as SkillManifest } from "./types-CKm5G_eQ-BqyXnvoR.js";
2
+ import { Q as ScriptExecutor, dt as WebSkillRuntime, ft as WebSkillRuntimeDeps, q as RuntimeRun, tt as SkillStateGuard } from "./index-DZShzhon.js";
3
+ import { d as SkillManager } from "./index-DrHelz72.js";
4
4
  //#region ../governance/dist/index.d.ts
5
5
  //#region src/types.d.ts
6
6
  type CandidateStatus = 'draft' | 'pending-review' | 'approved' | 'published' | 'rejected';
@@ -209,7 +209,12 @@ interface AuditChainVerification {
209
209
  brokenAt?: number;
210
210
  reason?: string;
211
211
  }
212
- /** JSONL 追加的审计日志:<managedRoot>/.webskill/audit.jsonl;跨实例可恢复查询;prevHash 链可校验完整性 */
212
+ /**
213
+ * JSONL 追加式审计日志(<managedRoot>/.webskill/audit.jsonl):
214
+ * 真追加(fs.appendText,不整读改写)+ lastHash 内存缓存(同实例不重读)。
215
+ * 语义:**tamper-evident, not tamper-proof**——verifyChain 能检出篡改/删除/换序,
216
+ * 但不阻止有写权限者直接改写文件;更强保证需要签名信任体系(未排期)。
217
+ */
213
218
  declare class FsAuditLog implements AuditLog {
214
219
  #private;
215
220
  constructor(deps: {
@@ -1,6 +1,6 @@
1
- import { A as unzipWithLimits, b as isValidSkillName, d as assertSafePathSegment, j as validateSkills, k as resolveInsideRoot, u as WebSkillError } from "./dist-D0saNPi_.js";
2
- import { S as WebSkillRuntime } from "./dist-NM4Mylx4.js";
3
- import { i as NodeFS, s as ProcessSandboxExecutor, u as exportArchive } from "./dist-CvIMVwr3.js";
1
+ import { A as unzipWithLimits, b as isValidSkillName, d as assertSafePathSegment, j as validateSkills, k as resolveInsideRoot, u as WebSkillError } from "./dist-D7MsoMPx.js";
2
+ import { S as WebSkillRuntime } from "./dist-CV64gN62.js";
3
+ import { i as NodeFS, s as ProcessSandboxExecutor, u as exportArchive } from "./dist-Chgf2tcy.js";
4
4
  import path from "node:path";
5
5
  import { tmpdir } from "node:os";
6
6
  import { mkdtemp } from "node:fs/promises";
@@ -404,29 +404,42 @@ function canonical(event) {
404
404
  prevHash: event.prevHash
405
405
  });
406
406
  }
407
- /** JSONL 追加的审计日志:<managedRoot>/.webskill/audit.jsonl;跨实例可恢复查询;prevHash 链可校验完整性 */
407
+ /**
408
+ * JSONL 追加式审计日志(<managedRoot>/.webskill/audit.jsonl):
409
+ * 真追加(fs.appendText,不整读改写)+ lastHash 内存缓存(同实例不重读)。
410
+ * 语义:**tamper-evident, not tamper-proof**——verifyChain 能检出篡改/删除/换序,
411
+ * 但不阻止有写权限者直接改写文件;更强保证需要签名信任体系(未排期)。
412
+ */
408
413
  var FsAuditLog = class {
409
414
  #root;
410
415
  #fs;
411
416
  #now;
412
417
  #createId;
418
+ /** lastHash 内存缓存(同实例内追加不重读文件) */
419
+ #lastHash;
420
+ #lastHashSeeded = false;
413
421
  constructor(deps) {
414
422
  this.#root = deps.root.replace(/\/+$/, "");
415
423
  this.#fs = deps.fs;
416
424
  this.#now = deps.now;
417
425
  this.#createId = deps.createId;
418
426
  }
419
- async append(event) {
427
+ /** 首追加时播种 lastHash(读一次尾部;尾行损坏 → 抛错,不静默重开链) */
428
+ async #seedLastHash() {
429
+ this.#lastHashSeeded = true;
420
430
  const path = fileOf$1(this.#root);
421
- const existing = await this.#fs.exists(path) ? await this.#fs.readText(path) : "";
422
- const lines = existing.split("\n").filter((l) => l.trim() !== "");
423
- let prevHash = "GENESIS";
424
- if (lines.length > 0) try {
431
+ if (!await this.#fs.exists(path)) return "GENESIS";
432
+ const lines = (await this.#fs.readText(path)).split("\n").filter((l) => l.trim() !== "");
433
+ if (lines.length === 0) return "GENESIS";
434
+ try {
425
435
  const last = JSON.parse(lines.at(-1));
426
- prevHash = last.hash ?? sha256Hex(canonical(last));
427
- } catch {
428
- prevHash = "GENESIS";
436
+ return last.hash ?? sha256Hex(canonical(last));
437
+ } catch (e) {
438
+ throw new WebSkillError("GOVERNANCE_FAILED", `Audit log tail line at ${path} is corrupted; refusing to append (the chain must not silently restart)`, e);
429
439
  }
440
+ }
441
+ async append(event) {
442
+ const prevHash = this.#lastHashSeeded ? this.#lastHash : await this.#seedLastHash();
430
443
  const full = {
431
444
  id: event.id ?? this.#createId?.() ?? `audit-${Math.random().toString(36).slice(2, 10)}`,
432
445
  ts: event.ts ?? this.#now?.() ?? (/* @__PURE__ */ new Date()).toISOString(),
@@ -437,8 +450,8 @@ var FsAuditLog = class {
437
450
  prevHash
438
451
  };
439
452
  full.hash = sha256Hex(canonical(full));
440
- const prefix = existing === "" || existing.endsWith("\n") ? existing : `${existing}\n`;
441
- await this.#fs.writeText(path, `${prefix}${JSON.stringify(full)}\n`);
453
+ await this.#fs.appendText(fileOf$1(this.#root), `${JSON.stringify(full)}\n`);
454
+ this.#lastHash = full.hash;
442
455
  return full;
443
456
  }
444
457
  async query(filter) {
@@ -448,7 +461,12 @@ var FsAuditLog = class {
448
461
  const events = [];
449
462
  for (const line of raw.split("\n")) {
450
463
  if (line.trim() === "") continue;
451
- const event = JSON.parse(line);
464
+ let event;
465
+ try {
466
+ event = JSON.parse(line);
467
+ } catch {
468
+ continue;
469
+ }
452
470
  if (filter.target !== void 0 && event.target !== filter.target) continue;
453
471
  if (filter.type !== void 0 && event.type !== filter.type) continue;
454
472
  if (filter.since !== void 0 && event.ts < filter.since) continue;
@@ -1,4 +1,4 @@
1
- import { F as SkillDocument, G as ValidationReport, I as SkillInstallSource, M as SkillCatalog, N as SkillCatalogEntry, P as SkillDiscovery, S as DiscoveryResult, T as JsonSchema, _ as RenderResultRequest, a as InteractionPolicy, c as LlmClient, d as LlmResponse, f as LlmStreamEvent, g as RenderBlock, h as MemoryStore, i as FormField, l as LlmCompleteInput, m as LlmToolSpec, n as ArtifactStore, o as InteractionRequest, r as ChartSpec, t as Artifact, u as LlmMessage, v as UiBridge, w as FileSystemProvider, z as SkillManifest } from "./types-CKm5G_eQ-8W8FnP4u.js";
1
+ import { F as SkillDocument, G as ValidationReport, I as SkillInstallSource, J as WebSkillErrorCode, M as SkillCatalog, N as SkillCatalogEntry, P as SkillDiscovery, S as DiscoveryResult, T as JsonSchema, _ as RenderResultRequest, a as InteractionPolicy, c as LlmClient, d as LlmResponse, f as LlmStreamEvent, g as RenderBlock, h as MemoryStore, i as FormField, l as LlmCompleteInput, m as LlmToolSpec, n as ArtifactStore, o as InteractionRequest, r as ChartSpec, t as Artifact, u as LlmMessage, v as UiBridge, w as FileSystemProvider, z as SkillManifest } from "./types-CKm5G_eQ-BqyXnvoR.js";
2
2
  //#region ../runtime/dist/index.d.ts
3
3
  //#region src/llm/openAiCompatibleClient.d.ts
4
4
  interface OpenAiCompatibleClientConfig {
@@ -33,6 +33,11 @@ interface AnthropicClientConfig {
33
33
  requestTimeoutMs?: number;
34
34
  /** max_tokens(Messages API 必填),默认 4096 */
35
35
  maxTokens?: number;
36
+ /**
37
+ * 浏览器直调 opt-in:true 时发送 anthropic-dangerous-direct-browser-access 头
38
+ * (默认 false 不发——仅在明确运行于浏览器且无服务端代理时开启)
39
+ */
40
+ dangerouslyAllowDirectBrowserAccess?: boolean;
36
41
  }
37
42
  /** Anthropic Messages API 客户端(零依赖 fetch;Node/浏览器通用) */
38
43
  declare class AnthropicClient implements LlmClient {
@@ -540,6 +545,18 @@ declare function isNetworkAllowed(policy: NetworkPolicy, url: string): boolean;
540
545
  /** 阻断 trace 用的脱敏 host(解析失败返回占位,不记录完整 URL) */
541
546
  declare function networkUrlHost(url: string): string;
542
547
  //#endregion
548
+ //#region src/sandbox/errorCodes.d.ts
549
+ /**
550
+ * 错误码白名单归一:沙箱/桥消息里出现的非白名单码(DOMException 数值码、
551
+ * Node 任意 ERR_* 码等)一律归为 TOOL_EXECUTION_FAILED。
552
+ */
553
+ declare function normalizeErrorCode(code: unknown): WebSkillErrorCode;
554
+ /** 归一化后的 (code, message):非白名单码保留在 message 尾部([original code: X]) */
555
+ declare function normalizeToolError(code: unknown, message: string): {
556
+ code: WebSkillErrorCode;
557
+ message: string;
558
+ };
559
+ //#endregion
543
560
  //#region src/sandbox/approval.d.ts
544
561
  /** 桥消息对应的三类能力 */
545
562
  type BridgeCapability = 'readReference' | 'writeArtifact' | 'confirm';
@@ -810,4 +827,4 @@ declare class WebSkillRuntime {
810
827
  resumeRun(runId: string): Promise<RunResult>;
811
828
  }
812
829
  //#endregion
813
- export { SerializingMemoryStore as $, LifecycleHook as A, RUN_SNAPSHOT_SCHEMA_VERSION as B, FullDisclosureRouter as C, normalizeToolContent as Ct, HookRunnerOptions as D, toLlmToolSpec as Dt, HookRunner as E, schemaToForm as Et, OpenAiCompatibleClientConfig as F, RunTerminationReason as G, RunResult as H, ProgressiveRouter as I, RuntimeSession as J, RuntimePhase as K, READ_SKILL_FILE_INPUT_SCHEMA as L, LifecycleListener as M, NetworkPolicy as N, InstalledSkillManifest as O, toVercelToolSpecs as Ot, OpenAiCompatibleClient as P, ScriptExecutor as Q, READ_SKILL_FILE_TOOL as R, FsRunSnapshotStore as S, networkUrlHost as St, GoogleGenAiClientConfig as T, resolveToolName as Tt, RunSnapshot as U, RouteResult as V, RunSnapshotStore as W, SchemaInferer as X, RuntimeSessionHandle as Y, ScriptExecutionContext as Z, EventBus as _, extractChartSpec as _t, AgentLoopConfig as a, TraceClock as at, FsArtifactStore as b, isNetworkAllowed as bt, AnthropicClientConfig as c, TraceRecorder as ct, BridgeCapabilities as d, WebSkillRuntime as dt, SkillRouter as et, BridgeCapability as f, WebSkillRuntimeDeps as ft, CapabilityMode as g, createWebSkillApi as gt, CapabilityApproval as h, createScriptContext as ht, AgentLoop as i, ToolResult as it, LifecycleHookContext as j, LifecycleEvent as k, ApprovalDecision as l, VercelToolSpec as lt, BridgeResponse as m, buildRenderResult as mt, ASK_USER_TOOL as n, ToolDefinition as nt, AgentLoopDeps as o, TraceEvent as ot, BridgeRequest as p, bridgeError as pt, RuntimeRun as q, ASK_USER_TOOL_NAME as r, ToolResolution as rt, AnthropicClient as s, TraceEventType as st, ASK_USER_INPUT_SCHEMA as t, SkillStateGuard as tt, ApprovalScope as u, WebSkillApi as ut, ExternalSkillProvider as v, fromVercelResult as vt, GoogleGenAiClient as w, parseBridgeRequest as wt, FsMemoryStore as x, mergeCatalogEntries as xt, ExternalToolSource as y, fromVercelStreamPart as yt, READ_SKILL_FILE_TOOL_NAME as z };
830
+ export { SerializingMemoryStore as $, LifecycleHook as A, toVercelToolSpecs as At, RUN_SNAPSHOT_SCHEMA_VERSION as B, FullDisclosureRouter as C, normalizeErrorCode as Ct, HookRunnerOptions as D, resolveToolName as Dt, HookRunner as E, parseBridgeRequest as Et, OpenAiCompatibleClientConfig as F, RunTerminationReason as G, RunResult as H, ProgressiveRouter as I, RuntimeSession as J, RuntimePhase as K, READ_SKILL_FILE_INPUT_SCHEMA as L, LifecycleListener as M, NetworkPolicy as N, InstalledSkillManifest as O, schemaToForm as Ot, OpenAiCompatibleClient as P, ScriptExecutor as Q, READ_SKILL_FILE_TOOL as R, FsRunSnapshotStore as S, networkUrlHost as St, GoogleGenAiClientConfig as T, normalizeToolError as Tt, RunSnapshot as U, RouteResult as V, RunSnapshotStore as W, SchemaInferer as X, RuntimeSessionHandle as Y, ScriptExecutionContext as Z, EventBus as _, extractChartSpec as _t, AgentLoopConfig as a, TraceClock as at, FsArtifactStore as b, isNetworkAllowed as bt, AnthropicClientConfig as c, TraceRecorder as ct, BridgeCapabilities as d, WebSkillRuntime as dt, SkillRouter as et, BridgeCapability as f, WebSkillRuntimeDeps as ft, CapabilityMode as g, createWebSkillApi as gt, CapabilityApproval as h, createScriptContext as ht, AgentLoop as i, ToolResult as it, LifecycleHookContext as j, LifecycleEvent as k, toLlmToolSpec as kt, ApprovalDecision as l, VercelToolSpec as lt, BridgeResponse as m, buildRenderResult as mt, ASK_USER_TOOL as n, ToolDefinition as nt, AgentLoopDeps as o, TraceEvent as ot, BridgeRequest as p, bridgeError as pt, RuntimeRun as q, ASK_USER_TOOL_NAME as r, ToolResolution as rt, AnthropicClient as s, TraceEventType as st, ASK_USER_INPUT_SCHEMA as t, SkillStateGuard as tt, ApprovalScope as u, WebSkillApi as ut, ExternalSkillProvider as v, fromVercelResult as vt, GoogleGenAiClient as w, normalizeToolContent as wt, FsMemoryStore as x, mergeCatalogEntries as xt, ExternalToolSource as y, fromVercelStreamPart as yt, READ_SKILL_FILE_TOOL_NAME as z };
@@ -1,5 +1,5 @@
1
- import { C as FileStat, I as SkillInstallSource, K as VerifyResult, T as JsonSchema, W as SkillsLockfile, _ as RenderResultRequest, o as InteractionRequest, s as InteractionResponse, v as UiBridge, w as FileSystemProvider, y as ArchiveLimits, z as SkillManifest } from "./types-CKm5G_eQ-8W8FnP4u.js";
2
- import { N as NetworkPolicy, Q as ScriptExecutor, X as SchemaInferer, Z as ScriptExecutionContext, b as FsArtifactStore, d as BridgeCapabilities, it as ToolResult, nt as ToolDefinition, u as ApprovalScope, x as FsMemoryStore } from "./index-gjFuBevI.js";
1
+ import { C as FileStat, I as SkillInstallSource, K as VerifyResult, T as JsonSchema, W as SkillsLockfile, _ as RenderResultRequest, o as InteractionRequest, s as InteractionResponse, v as UiBridge, w as FileSystemProvider, y as ArchiveLimits, z as SkillManifest } from "./types-CKm5G_eQ-BqyXnvoR.js";
2
+ import { N as NetworkPolicy, Q as ScriptExecutor, X as SchemaInferer, Z as ScriptExecutionContext, b as FsArtifactStore, d as BridgeCapabilities, it as ToolResult, nt as ToolDefinition, u as ApprovalScope, x as FsMemoryStore } from "./index-DZShzhon.js";
3
3
  import { Readable, Writable } from "node:stream";
4
4
  //#region ../node/dist/index.d.ts
5
5
  //#region src/fs/nodeFs.d.ts
@@ -14,8 +14,11 @@ declare class NodeFS implements FileSystemProvider {
14
14
  constructor(deps?: {
15
15
  root?: string;
16
16
  });
17
+ /** root 模式:全部方法(read/write/exists/stat/list/mkdir/remove/rename)目标 realpath 必须落在 root realpath 前缀内 */
18
+ withRoot(root: string): NodeFS;
17
19
  readText(p: string): Promise<string>;
18
20
  writeText(p: string, content: string): Promise<void>;
21
+ appendText(p: string, content: string): Promise<void>;
19
22
  readBinary(p: string): Promise<Uint8Array>;
20
23
  writeBinary(p: string, content: Uint8Array): Promise<void>;
21
24
  exists(p: string): Promise<boolean>;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { $ as checkDependencyCycles, A as SKILL_NAME_PATTERN, B as SkillMetadata, C as FileStat, D as SKILLS_LOCKFILE, E as MemoryFS, F as SkillDocument, G as ValidationReport, H as SkillReader, I as SkillInstallSource, J as WebSkillErrorCode, K as VerifyResult, L as SkillIssue, M as SkillCatalog, N as SkillCatalogEntry, O as SKILL_MANIFEST_FILE, P as SkillDiscovery, Q as buildManifest, R as SkillLocation, S as DiscoveryResult, T as JsonSchema, U as SkillSource, V as SkillPackManifest, W as SkillsLockfile, X as atomicWriteText, Y as assertSafePathSegment, Z as buildCatalog, _ as RenderResultRequest, _t as xmlRenderer, a as InteractionPolicy, at as jsonRenderer, b as CatalogRenderer, c as LlmClient, ct as parseSkillPackManifest, d as LlmResponse, dt as renderCatalogJson, et as checkSkillRules, f as LlmStreamEvent, ft as resolveArchiveLimits, g as RenderBlock, gt as verifyManifest, h as MemoryStore, ht as validateSkills, i as FormField, it as isValidSkillName, j as SKILL_PACK_FILE, k as SKILL_NAME_MAX_LENGTH, l as LlmCompleteInput, lt as readResponseWithLimit, m as LlmToolSpec, mt as unzipWithLimits, n as ArtifactStore, nt as escapeXml, o as InteractionRequest, ot as normalizePath, p as LlmToolCall, pt as resolveInsideRoot, q as WebSkillError, r as ChartSpec, rt as exportSkills, s as InteractionResponse, st as parseSkillMarkdown, t as Artifact, tt as computeDigest, u as LlmMessage, ut as renderAvailableSkillsXml, v as UiBridge, w as FileSystemProvider, x as DEFAULT_ARCHIVE_LIMITS, y as ArchiveLimits, z as SkillManifest } from "./types-CKm5G_eQ-8W8FnP4u.js";
2
- import { $ as SerializingMemoryStore, A as LifecycleHook, B as RUN_SNAPSHOT_SCHEMA_VERSION, C as FullDisclosureRouter, Ct as normalizeToolContent, D as HookRunnerOptions, Dt as toLlmToolSpec, E as HookRunner, Et as schemaToForm, F as OpenAiCompatibleClientConfig, G as RunTerminationReason, H as RunResult, I as ProgressiveRouter, J as RuntimeSession, K as RuntimePhase, L as READ_SKILL_FILE_INPUT_SCHEMA, M as LifecycleListener, N as NetworkPolicy, O as InstalledSkillManifest, Ot as toVercelToolSpecs, P as OpenAiCompatibleClient, Q as ScriptExecutor, R as READ_SKILL_FILE_TOOL, S as FsRunSnapshotStore, St as networkUrlHost, T as GoogleGenAiClientConfig, Tt as resolveToolName, U as RunSnapshot, V as RouteResult, W as RunSnapshotStore, X as SchemaInferer, Y as RuntimeSessionHandle, Z as ScriptExecutionContext, _ as EventBus, _t as extractChartSpec, a as AgentLoopConfig, at as TraceClock, b as FsArtifactStore, bt as isNetworkAllowed, c as AnthropicClientConfig, ct as TraceRecorder, d as BridgeCapabilities, dt as WebSkillRuntime, et as SkillRouter, f as BridgeCapability, ft as WebSkillRuntimeDeps, g as CapabilityMode, gt as createWebSkillApi, h as CapabilityApproval, ht as createScriptContext, i as AgentLoop, it as ToolResult, j as LifecycleHookContext, k as LifecycleEvent, l as ApprovalDecision, lt as VercelToolSpec, m as BridgeResponse, mt as buildRenderResult, n as ASK_USER_TOOL, nt as ToolDefinition, o as AgentLoopDeps, ot as TraceEvent, p as BridgeRequest, pt as bridgeError, q as RuntimeRun, r as ASK_USER_TOOL_NAME, rt as ToolResolution, s as AnthropicClient, st as TraceEventType, t as ASK_USER_INPUT_SCHEMA, tt as SkillStateGuard, u as ApprovalScope, ut as WebSkillApi, v as ExternalSkillProvider, vt as fromVercelResult, w as GoogleGenAiClient, wt as parseBridgeRequest, x as FsMemoryStore, xt as mergeCatalogEntries, y as ExternalToolSource, yt as fromVercelStreamPart, z as READ_SKILL_FILE_TOOL_NAME } from "./index-gjFuBevI.js";
3
- export { ASK_USER_INPUT_SCHEMA, ASK_USER_TOOL, ASK_USER_TOOL_NAME, AgentLoop, type AgentLoopConfig, type AgentLoopDeps, AnthropicClient, type AnthropicClientConfig, type ApprovalDecision, type ApprovalScope, type ArchiveLimits, type Artifact, type ArtifactStore, type BridgeCapabilities, type BridgeCapability, type BridgeRequest, type BridgeResponse, CapabilityApproval, type CapabilityMode, type CatalogRenderer, type ChartSpec, DEFAULT_ARCHIVE_LIMITS, type DiscoveryResult, EventBus, type ExternalSkillProvider, type ExternalToolSource, type FileStat, type FileSystemProvider, type FormField, FsArtifactStore, FsMemoryStore, FsRunSnapshotStore, FullDisclosureRouter, GoogleGenAiClient, type GoogleGenAiClientConfig, HookRunner, type HookRunnerOptions, type InstalledSkillManifest, type InteractionPolicy, type InteractionRequest, type InteractionResponse, type JsonSchema, type LifecycleEvent, type LifecycleHook, type LifecycleHookContext, type LifecycleListener, type LlmClient, type LlmCompleteInput, type LlmMessage, type LlmResponse, type LlmStreamEvent, type LlmToolCall, type LlmToolSpec, MemoryFS, type MemoryStore, type NetworkPolicy, OpenAiCompatibleClient, type OpenAiCompatibleClientConfig, ProgressiveRouter, READ_SKILL_FILE_INPUT_SCHEMA, READ_SKILL_FILE_TOOL, READ_SKILL_FILE_TOOL_NAME, RUN_SNAPSHOT_SCHEMA_VERSION, type RenderBlock, type RenderResultRequest, type RouteResult, type RunResult, type RunSnapshot, type RunSnapshotStore, type RunTerminationReason, type RuntimePhase, type RuntimeRun, type RuntimeSession, type RuntimeSessionHandle, SKILLS_LOCKFILE, SKILL_MANIFEST_FILE, SKILL_NAME_MAX_LENGTH, SKILL_NAME_PATTERN, SKILL_PACK_FILE, type SchemaInferer, type ScriptExecutionContext, type ScriptExecutor, SerializingMemoryStore, type SkillCatalog, type SkillCatalogEntry, SkillDiscovery, type SkillDocument, type SkillInstallSource, type SkillIssue, type SkillLocation, type SkillManifest, type SkillMetadata, type SkillPackManifest, SkillReader, type SkillRouter, type SkillSource, type SkillStateGuard, type SkillsLockfile, type ToolDefinition, type ToolResolution, type ToolResult, type TraceClock, type TraceEvent, type TraceEventType, TraceRecorder, type UiBridge, type ValidationReport, type VercelToolSpec, type VerifyResult, type WebSkillApi, WebSkillError, type WebSkillErrorCode, WebSkillRuntime, type WebSkillRuntimeDeps, assertSafePathSegment, atomicWriteText, bridgeError, buildCatalog, buildManifest, buildRenderResult, checkDependencyCycles, checkSkillRules, computeDigest, createScriptContext, createWebSkillApi, escapeXml, exportSkills, extractChartSpec, fromVercelResult, fromVercelStreamPart, isNetworkAllowed, isValidSkillName, jsonRenderer, mergeCatalogEntries, networkUrlHost, normalizePath, normalizeToolContent, parseBridgeRequest, parseSkillMarkdown, parseSkillPackManifest, readResponseWithLimit, renderAvailableSkillsXml, renderCatalogJson, resolveArchiveLimits, resolveInsideRoot, resolveToolName, schemaToForm, toLlmToolSpec, toVercelToolSpecs, unzipWithLimits, validateSkills, verifyManifest, xmlRenderer };
1
+ import { $ as checkDependencyCycles, A as SKILL_NAME_PATTERN, B as SkillMetadata, C as FileStat, D as SKILLS_LOCKFILE, E as MemoryFS, F as SkillDocument, G as ValidationReport, H as SkillReader, I as SkillInstallSource, J as WebSkillErrorCode, K as VerifyResult, L as SkillIssue, M as SkillCatalog, N as SkillCatalogEntry, O as SKILL_MANIFEST_FILE, P as SkillDiscovery, Q as buildManifest, R as SkillLocation, S as DiscoveryResult, T as JsonSchema, U as SkillSource, V as SkillPackManifest, W as SkillsLockfile, X as atomicWriteText, Y as assertSafePathSegment, Z as buildCatalog, _ as RenderResultRequest, _t as xmlRenderer, a as InteractionPolicy, at as jsonRenderer, b as CatalogRenderer, c as LlmClient, ct as parseSkillPackManifest, d as LlmResponse, dt as renderCatalogJson, et as checkSkillRules, f as LlmStreamEvent, ft as resolveArchiveLimits, g as RenderBlock, gt as verifyManifest, h as MemoryStore, ht as validateSkills, i as FormField, it as isValidSkillName, j as SKILL_PACK_FILE, k as SKILL_NAME_MAX_LENGTH, l as LlmCompleteInput, lt as readResponseWithLimit, m as LlmToolSpec, mt as unzipWithLimits, n as ArtifactStore, nt as escapeXml, o as InteractionRequest, ot as normalizePath, p as LlmToolCall, pt as resolveInsideRoot, q as WebSkillError, r as ChartSpec, rt as exportSkills, s as InteractionResponse, st as parseSkillMarkdown, t as Artifact, tt as computeDigest, u as LlmMessage, ut as renderAvailableSkillsXml, v as UiBridge, w as FileSystemProvider, x as DEFAULT_ARCHIVE_LIMITS, y as ArchiveLimits, z as SkillManifest } from "./types-CKm5G_eQ-BqyXnvoR.js";
2
+ import { $ as SerializingMemoryStore, A as LifecycleHook, At as toVercelToolSpecs, B as RUN_SNAPSHOT_SCHEMA_VERSION, C as FullDisclosureRouter, Ct as normalizeErrorCode, D as HookRunnerOptions, Dt as resolveToolName, E as HookRunner, Et as parseBridgeRequest, F as OpenAiCompatibleClientConfig, G as RunTerminationReason, H as RunResult, I as ProgressiveRouter, J as RuntimeSession, K as RuntimePhase, L as READ_SKILL_FILE_INPUT_SCHEMA, M as LifecycleListener, N as NetworkPolicy, O as InstalledSkillManifest, Ot as schemaToForm, P as OpenAiCompatibleClient, Q as ScriptExecutor, R as READ_SKILL_FILE_TOOL, S as FsRunSnapshotStore, St as networkUrlHost, T as GoogleGenAiClientConfig, Tt as normalizeToolError, U as RunSnapshot, V as RouteResult, W as RunSnapshotStore, X as SchemaInferer, Y as RuntimeSessionHandle, Z as ScriptExecutionContext, _ as EventBus, _t as extractChartSpec, a as AgentLoopConfig, at as TraceClock, b as FsArtifactStore, bt as isNetworkAllowed, c as AnthropicClientConfig, ct as TraceRecorder, d as BridgeCapabilities, dt as WebSkillRuntime, et as SkillRouter, f as BridgeCapability, ft as WebSkillRuntimeDeps, g as CapabilityMode, gt as createWebSkillApi, h as CapabilityApproval, ht as createScriptContext, i as AgentLoop, it as ToolResult, j as LifecycleHookContext, k as LifecycleEvent, kt as toLlmToolSpec, l as ApprovalDecision, lt as VercelToolSpec, m as BridgeResponse, mt as buildRenderResult, n as ASK_USER_TOOL, nt as ToolDefinition, o as AgentLoopDeps, ot as TraceEvent, p as BridgeRequest, pt as bridgeError, q as RuntimeRun, r as ASK_USER_TOOL_NAME, rt as ToolResolution, s as AnthropicClient, st as TraceEventType, t as ASK_USER_INPUT_SCHEMA, tt as SkillStateGuard, u as ApprovalScope, ut as WebSkillApi, v as ExternalSkillProvider, vt as fromVercelResult, w as GoogleGenAiClient, wt as normalizeToolContent, x as FsMemoryStore, xt as mergeCatalogEntries, y as ExternalToolSource, yt as fromVercelStreamPart, z as READ_SKILL_FILE_TOOL_NAME } from "./index-DZShzhon.js";
3
+ export { ASK_USER_INPUT_SCHEMA, ASK_USER_TOOL, ASK_USER_TOOL_NAME, AgentLoop, type AgentLoopConfig, type AgentLoopDeps, AnthropicClient, type AnthropicClientConfig, type ApprovalDecision, type ApprovalScope, type ArchiveLimits, type Artifact, type ArtifactStore, type BridgeCapabilities, type BridgeCapability, type BridgeRequest, type BridgeResponse, CapabilityApproval, type CapabilityMode, type CatalogRenderer, type ChartSpec, DEFAULT_ARCHIVE_LIMITS, type DiscoveryResult, EventBus, type ExternalSkillProvider, type ExternalToolSource, type FileStat, type FileSystemProvider, type FormField, FsArtifactStore, FsMemoryStore, FsRunSnapshotStore, FullDisclosureRouter, GoogleGenAiClient, type GoogleGenAiClientConfig, HookRunner, type HookRunnerOptions, type InstalledSkillManifest, type InteractionPolicy, type InteractionRequest, type InteractionResponse, type JsonSchema, type LifecycleEvent, type LifecycleHook, type LifecycleHookContext, type LifecycleListener, type LlmClient, type LlmCompleteInput, type LlmMessage, type LlmResponse, type LlmStreamEvent, type LlmToolCall, type LlmToolSpec, MemoryFS, type MemoryStore, type NetworkPolicy, OpenAiCompatibleClient, type OpenAiCompatibleClientConfig, ProgressiveRouter, READ_SKILL_FILE_INPUT_SCHEMA, READ_SKILL_FILE_TOOL, READ_SKILL_FILE_TOOL_NAME, RUN_SNAPSHOT_SCHEMA_VERSION, type RenderBlock, type RenderResultRequest, type RouteResult, type RunResult, type RunSnapshot, type RunSnapshotStore, type RunTerminationReason, type RuntimePhase, type RuntimeRun, type RuntimeSession, type RuntimeSessionHandle, SKILLS_LOCKFILE, SKILL_MANIFEST_FILE, SKILL_NAME_MAX_LENGTH, SKILL_NAME_PATTERN, SKILL_PACK_FILE, type SchemaInferer, type ScriptExecutionContext, type ScriptExecutor, SerializingMemoryStore, type SkillCatalog, type SkillCatalogEntry, SkillDiscovery, type SkillDocument, type SkillInstallSource, type SkillIssue, type SkillLocation, type SkillManifest, type SkillMetadata, type SkillPackManifest, SkillReader, type SkillRouter, type SkillSource, type SkillStateGuard, type SkillsLockfile, type ToolDefinition, type ToolResolution, type ToolResult, type TraceClock, type TraceEvent, type TraceEventType, TraceRecorder, type UiBridge, type ValidationReport, type VercelToolSpec, type VerifyResult, type WebSkillApi, WebSkillError, type WebSkillErrorCode, WebSkillRuntime, type WebSkillRuntimeDeps, assertSafePathSegment, atomicWriteText, bridgeError, buildCatalog, buildManifest, buildRenderResult, checkDependencyCycles, checkSkillRules, computeDigest, createScriptContext, createWebSkillApi, escapeXml, exportSkills, extractChartSpec, fromVercelResult, fromVercelStreamPart, isNetworkAllowed, isValidSkillName, jsonRenderer, mergeCatalogEntries, networkUrlHost, normalizeErrorCode, normalizePath, normalizeToolContent, normalizeToolError, parseBridgeRequest, parseSkillMarkdown, parseSkillPackManifest, readResponseWithLimit, renderAvailableSkillsXml, renderCatalogJson, resolveArchiveLimits, resolveInsideRoot, resolveToolName, schemaToForm, toLlmToolSpec, toVercelToolSpecs, unzipWithLimits, validateSkills, verifyManifest, xmlRenderer };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as unzipWithLimits, C as parseSkillMarkdown, D as renderCatalogJson, E as renderAvailableSkillsXml, M as verifyManifest, N as xmlRenderer, O as resolveArchiveLimits, S as normalizePath, T as readResponseWithLimit, _ as computeDigest, a as SKILL_NAME_MAX_LENGTH, b as isValidSkillName, c as SkillDiscovery, d as assertSafePathSegment, f as atomicWriteText, g as checkSkillRules, h as checkDependencyCycles, i as SKILL_MANIFEST_FILE, j as validateSkills, k as resolveInsideRoot, l as SkillReader, m as buildManifest, n as MemoryFS, o as SKILL_NAME_PATTERN, p as buildCatalog, r as SKILLS_LOCKFILE, s as SKILL_PACK_FILE, t as DEFAULT_ARCHIVE_LIMITS, u as WebSkillError, v as escapeXml, w as parseSkillPackManifest, x as jsonRenderer, y as exportSkills } from "./dist-D0saNPi_.js";
2
- import { A as isNetworkAllowed, C as bridgeError, D as extractChartSpec, E as createWebSkillApi, F as resolveToolName, I as schemaToForm, L as toLlmToolSpec, M as networkUrlHost, N as normalizeToolContent, O as fromVercelResult, P as parseBridgeRequest, R as toVercelToolSpecs, S as WebSkillRuntime, T as createScriptContext, _ as READ_SKILL_FILE_TOOL, a as AnthropicClient, b as SerializingMemoryStore, c as FsArtifactStore, d as FullDisclosureRouter, f as GoogleGenAiClient, g as READ_SKILL_FILE_INPUT_SCHEMA, h as ProgressiveRouter, i as AgentLoop, j as mergeCatalogEntries, k as fromVercelStreamPart, l as FsMemoryStore, m as OpenAiCompatibleClient, n as ASK_USER_TOOL, o as CapabilityApproval, p as HookRunner, r as ASK_USER_TOOL_NAME, s as EventBus, t as ASK_USER_INPUT_SCHEMA, u as FsRunSnapshotStore, v as READ_SKILL_FILE_TOOL_NAME, w as buildRenderResult, x as TraceRecorder, y as RUN_SNAPSHOT_SCHEMA_VERSION } from "./dist-NM4Mylx4.js";
1
+ import { A as unzipWithLimits, C as parseSkillMarkdown, D as renderCatalogJson, E as renderAvailableSkillsXml, M as verifyManifest, N as xmlRenderer, O as resolveArchiveLimits, S as normalizePath, T as readResponseWithLimit, _ as computeDigest, a as SKILL_NAME_MAX_LENGTH, b as isValidSkillName, c as SkillDiscovery, d as assertSafePathSegment, f as atomicWriteText, g as checkSkillRules, h as checkDependencyCycles, i as SKILL_MANIFEST_FILE, j as validateSkills, k as resolveInsideRoot, l as SkillReader, m as buildManifest, n as MemoryFS, o as SKILL_NAME_PATTERN, p as buildCatalog, r as SKILLS_LOCKFILE, s as SKILL_PACK_FILE, t as DEFAULT_ARCHIVE_LIMITS, u as WebSkillError, v as escapeXml, w as parseSkillPackManifest, x as jsonRenderer, y as exportSkills } from "./dist-D7MsoMPx.js";
2
+ import { A as isNetworkAllowed, B as toVercelToolSpecs, C as bridgeError, D as extractChartSpec, E as createWebSkillApi, F as normalizeToolError, I as parseBridgeRequest, L as resolveToolName, M as networkUrlHost, N as normalizeErrorCode, O as fromVercelResult, P as normalizeToolContent, R as schemaToForm, S as WebSkillRuntime, T as createScriptContext, _ as READ_SKILL_FILE_TOOL, a as AnthropicClient, b as SerializingMemoryStore, c as FsArtifactStore, d as FullDisclosureRouter, f as GoogleGenAiClient, g as READ_SKILL_FILE_INPUT_SCHEMA, h as ProgressiveRouter, i as AgentLoop, j as mergeCatalogEntries, k as fromVercelStreamPart, l as FsMemoryStore, m as OpenAiCompatibleClient, n as ASK_USER_TOOL, o as CapabilityApproval, p as HookRunner, r as ASK_USER_TOOL_NAME, s as EventBus, t as ASK_USER_INPUT_SCHEMA, u as FsRunSnapshotStore, v as READ_SKILL_FILE_TOOL_NAME, w as buildRenderResult, x as TraceRecorder, y as RUN_SNAPSHOT_SCHEMA_VERSION, z as toLlmToolSpec } from "./dist-CV64gN62.js";
3
3
 
4
- export { ASK_USER_INPUT_SCHEMA, ASK_USER_TOOL, ASK_USER_TOOL_NAME, AgentLoop, AnthropicClient, CapabilityApproval, DEFAULT_ARCHIVE_LIMITS, EventBus, FsArtifactStore, FsMemoryStore, FsRunSnapshotStore, FullDisclosureRouter, GoogleGenAiClient, HookRunner, MemoryFS, OpenAiCompatibleClient, ProgressiveRouter, READ_SKILL_FILE_INPUT_SCHEMA, READ_SKILL_FILE_TOOL, READ_SKILL_FILE_TOOL_NAME, RUN_SNAPSHOT_SCHEMA_VERSION, SKILLS_LOCKFILE, SKILL_MANIFEST_FILE, SKILL_NAME_MAX_LENGTH, SKILL_NAME_PATTERN, SKILL_PACK_FILE, SerializingMemoryStore, SkillDiscovery, SkillReader, TraceRecorder, WebSkillError, WebSkillRuntime, assertSafePathSegment, atomicWriteText, bridgeError, buildCatalog, buildManifest, buildRenderResult, checkDependencyCycles, checkSkillRules, computeDigest, createScriptContext, createWebSkillApi, escapeXml, exportSkills, extractChartSpec, fromVercelResult, fromVercelStreamPart, isNetworkAllowed, isValidSkillName, jsonRenderer, mergeCatalogEntries, networkUrlHost, normalizePath, normalizeToolContent, parseBridgeRequest, parseSkillMarkdown, parseSkillPackManifest, readResponseWithLimit, renderAvailableSkillsXml, renderCatalogJson, resolveArchiveLimits, resolveInsideRoot, resolveToolName, schemaToForm, toLlmToolSpec, toVercelToolSpecs, unzipWithLimits, validateSkills, verifyManifest, xmlRenderer };
4
+ export { ASK_USER_INPUT_SCHEMA, ASK_USER_TOOL, ASK_USER_TOOL_NAME, AgentLoop, AnthropicClient, CapabilityApproval, DEFAULT_ARCHIVE_LIMITS, EventBus, FsArtifactStore, FsMemoryStore, FsRunSnapshotStore, FullDisclosureRouter, GoogleGenAiClient, HookRunner, MemoryFS, OpenAiCompatibleClient, ProgressiveRouter, READ_SKILL_FILE_INPUT_SCHEMA, READ_SKILL_FILE_TOOL, READ_SKILL_FILE_TOOL_NAME, RUN_SNAPSHOT_SCHEMA_VERSION, SKILLS_LOCKFILE, SKILL_MANIFEST_FILE, SKILL_NAME_MAX_LENGTH, SKILL_NAME_PATTERN, SKILL_PACK_FILE, SerializingMemoryStore, SkillDiscovery, SkillReader, TraceRecorder, WebSkillError, WebSkillRuntime, assertSafePathSegment, atomicWriteText, bridgeError, buildCatalog, buildManifest, buildRenderResult, checkDependencyCycles, checkSkillRules, computeDigest, createScriptContext, createWebSkillApi, escapeXml, exportSkills, extractChartSpec, fromVercelResult, fromVercelStreamPart, isNetworkAllowed, isValidSkillName, jsonRenderer, mergeCatalogEntries, networkUrlHost, normalizeErrorCode, normalizePath, normalizeToolContent, normalizeToolError, parseBridgeRequest, parseSkillMarkdown, parseSkillPackManifest, readResponseWithLimit, renderAvailableSkillsXml, renderCatalogJson, resolveArchiveLimits, resolveInsideRoot, resolveToolName, schemaToForm, toLlmToolSpec, toVercelToolSpecs, unzipWithLimits, validateSkills, verifyManifest, xmlRenderer };
package/dist/mcp.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as SkillDocument, N as SkillCatalogEntry, T as JsonSchema, m as LlmToolSpec } from "./types-CKm5G_eQ-8W8FnP4u.js";
2
- import { it as ToolResult, v as ExternalSkillProvider, xt as mergeCatalogEntries, y as ExternalToolSource } from "./index-gjFuBevI.js";
1
+ import { F as SkillDocument, N as SkillCatalogEntry, T as JsonSchema, m as LlmToolSpec } from "./types-CKm5G_eQ-BqyXnvoR.js";
2
+ import { it as ToolResult, v as ExternalSkillProvider, xt as mergeCatalogEntries, y as ExternalToolSource } from "./index-DZShzhon.js";
3
3
  import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
4
4
  import { JSONRPCMessage } from "@modelcontextprotocol/sdk/types.js";
5
5
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -63,7 +63,7 @@ declare class MessageChannelTransport implements Transport {
63
63
  /** endpoint 名 → client 注册表;单调版本号,事件驱动等待(禁止轮询) */
64
64
  declare class EndpointRegistry<TClient> {
65
65
  #private;
66
- /** 注册新 endpoint;重名抛错 */
66
+ /** 注册新 endpoint;重名抛错;含 `__`(endpoint:tool 分隔符)或保留名 mcp 拒绝 */
67
67
  register(endpoint: string, client: TClient): void;
68
68
  /** 热替换 client,版本号 +1 */
69
69
  set(endpoint: string, client: TClient): void;
package/dist/mcp.js CHANGED
@@ -1,5 +1,5 @@
1
- import { u as WebSkillError } from "./dist-D0saNPi_.js";
2
- import { N as normalizeToolContent, j as mergeCatalogEntries } from "./dist-NM4Mylx4.js";
1
+ import { u as WebSkillError } from "./dist-D7MsoMPx.js";
2
+ import { P as normalizeToolContent, j as mergeCatalogEntries } from "./dist-CV64gN62.js";
3
3
 
4
4
  //#region ../mcp/dist/index.js
5
5
  /**
@@ -117,8 +117,9 @@ var EndpointRegistry = class {
117
117
  #clients = /* @__PURE__ */ new Map();
118
118
  #versions = /* @__PURE__ */ new Map();
119
119
  #waiters = /* @__PURE__ */ new Map();
120
- /** 注册新 endpoint;重名抛错 */
120
+ /** 注册新 endpoint;重名抛错;含 `__`(endpoint:tool 分隔符)或保留名 mcp 拒绝 */
121
121
  register(endpoint, client) {
122
+ if (endpoint.includes("__") || endpoint === "mcp") throw new Error(`Endpoint name ${JSON.stringify(endpoint)} is not allowed (no "__" segments, "mcp" is reserved)`);
122
123
  if (this.#clients.has(endpoint)) throw new Error(`Endpoint "${endpoint}" is already registered`);
123
124
  this.#clients.set(endpoint, client);
124
125
  this.#versions.set(endpoint, (this.#versions.get(endpoint) ?? 0) + 1);
@@ -172,6 +173,8 @@ var EndpointRegistry = class {
172
173
  }
173
174
  };
174
175
  const messageOf$3 = (e) => e instanceof Error ? e.message : String(e);
176
+ /** MCP 结果单项 text 上限(64KB) */
177
+ const MAX_MCP_RESULT_TEXT_BYTES = 64 * 1024;
175
178
  const failure$1 = (code, message) => ({
176
179
  ok: false,
177
180
  content: [],
@@ -235,14 +238,16 @@ var McpToolResolver = class {
235
238
  });
236
239
  return names;
237
240
  }
238
- /** CallToolResult → ToolResult;isError 转失败;content 经共享归一 */
241
+ /** CallToolResult → ToolResult;isError 转失败;形状消毒(无 content 且无 isError 不当作 ok)+ 大小上限 */
239
242
  #normalizeCallResult(raw) {
240
243
  const result = raw;
244
+ if (result?.isError !== true && result?.content === void 0) return failure$1("MCP_ENDPOINT_UNAVAILABLE", `MCP tool returned a malformed result (no "content" and no "isError"): ${messageOf$3(raw).slice(0, 200)}`);
241
245
  const content = normalizeToolContent(result?.content ?? raw);
242
246
  if (result?.isError === true) {
243
247
  const text = content.map((c) => c.text ?? "").filter(Boolean).join("\n");
244
248
  return failure$1("TOOL_EXECUTION_FAILED", text || "MCP tool returned an error");
245
249
  }
250
+ for (const item of content) if (item.text !== void 0 && item.text.length > MAX_MCP_RESULT_TEXT_BYTES) item.text = `${item.text.slice(0, MAX_MCP_RESULT_TEXT_BYTES)}…[truncated ${item.text.length - MAX_MCP_RESULT_TEXT_BYTES} chars]`;
246
251
  return {
247
252
  ok: true,
248
253
  content
@@ -414,7 +419,7 @@ var ExperimentalWebMcpAdapter = class {
414
419
  this.#enabled = options?.enabled ?? false;
415
420
  }
416
421
  isAvailable() {
417
- return typeof this.#resolveApi()?.executeTool === "function";
422
+ return this.#enabled && typeof this.#resolveApi()?.executeTool === "function";
418
423
  }
419
424
  /** 工具清单(listTools 缺失/失败时返回 undefined);描述含 inputSchema 时透传 */
420
425
  async listTools() {
@@ -549,7 +554,12 @@ const messageOf = (e) => e instanceof Error ? e.message : String(e);
549
554
  */
550
555
  async function connectRemoteEndpoint(registry, config) {
551
556
  const { Client, SSEClientTransport, StreamableHTTPClientTransport } = await loadMcpSdk();
552
- const url = new URL(config.url);
557
+ let url;
558
+ try {
559
+ url = new URL(config.url);
560
+ } catch (e) {
561
+ throw new WebSkillError("MCP_ENDPOINT_UNAVAILABLE", `Invalid remote MCP endpoint URL for "${config.endpoint}": ${JSON.stringify(config.url)}`, e);
562
+ }
553
563
  const requestInit = config.headers ? { headers: config.headers } : void 0;
554
564
  const transport = config.transport === "sse" ? new SSEClientTransport(url, { ...requestInit ? { requestInit } : {} }) : new StreamableHTTPClientTransport(url, { ...requestInit ? { requestInit } : {} });
555
565
  const client = new Client({
@@ -570,7 +580,14 @@ async function connectRemoteEndpoint(registry, config) {
570
580
  } catch {}
571
581
  throw unavailable(e);
572
582
  }
573
- registry.register(config.endpoint, client);
583
+ try {
584
+ registry.register(config.endpoint, client);
585
+ } catch (e) {
586
+ try {
587
+ await client.close();
588
+ } catch {}
589
+ throw unavailable(e);
590
+ }
574
591
  let closed = false;
575
592
  return { close: async () => {
576
593
  if (closed) return;
package/dist/node.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { D as SKILLS_LOCKFILE, I as SkillInstallSource, K as VerifyResult, O as SKILL_MANIFEST_FILE, W as SkillsLockfile, z as SkillManifest } from "./types-CKm5G_eQ-8W8FnP4u.js";
2
- import { ht as createScriptContext } from "./index-gjFuBevI.js";
1
+ import { D as SKILLS_LOCKFILE, I as SkillInstallSource, K as VerifyResult, O as SKILL_MANIFEST_FILE, W as SkillsLockfile, z as SkillManifest } from "./types-CKm5G_eQ-BqyXnvoR.js";
2
+ import { ht as createScriptContext } from "./index-DZShzhon.js";
3
3
  import { n as LlmEnvConfig, s as probeLlmCapabilities, t as LlmCapabilities } from "./env-BPUBZCwJ-4jat_SVG.js";
4
- import { a as NodeScriptExecutor, c as ProcessSandboxOptions, d as SkillManager, f as exportArchive, i as NodeFS, l as SandboxOptions, n as FileArtifactStore, o as OxcSchemaInferer, p as readArchiveManifest, r as FileMemoryStore, s as ProcessSandboxExecutor, t as CliUiBridge, u as SandboxedScriptExecutor } from "./index-iqcz3_NS.js";
4
+ import { a as NodeScriptExecutor, c as ProcessSandboxOptions, d as SkillManager, f as exportArchive, i as NodeFS, l as SandboxOptions, n as FileArtifactStore, o as OxcSchemaInferer, p as readArchiveManifest, r as FileMemoryStore, s as ProcessSandboxExecutor, t as CliUiBridge, u as SandboxedScriptExecutor } from "./index-DrHelz72.js";
5
5
  export { CliUiBridge, FileArtifactStore, FileMemoryStore, type LlmCapabilities, type LlmEnvConfig, NodeFS, NodeScriptExecutor, OxcSchemaInferer, ProcessSandboxExecutor, type ProcessSandboxOptions, SKILLS_LOCKFILE, SKILL_MANIFEST_FILE, type SandboxOptions, SandboxedScriptExecutor, type SkillInstallSource, SkillManager, type SkillManifest, type SkillsLockfile, type VerifyResult, createScriptContext, exportArchive, probeLlmCapabilities, readArchiveManifest };
package/dist/node.js CHANGED
@@ -1,6 +1,6 @@
1
- import { i as SKILL_MANIFEST_FILE, r as SKILLS_LOCKFILE } from "./dist-D0saNPi_.js";
2
- import { T as createScriptContext } from "./dist-NM4Mylx4.js";
1
+ import { i as SKILL_MANIFEST_FILE, r as SKILLS_LOCKFILE } from "./dist-D7MsoMPx.js";
2
+ import { T as createScriptContext } from "./dist-CV64gN62.js";
3
3
  import { i as probeLlmCapabilities } from "./env--jJB-TSX-04klhTYi.js";
4
- import { a as NodeScriptExecutor, c as SandboxedScriptExecutor, d as readArchiveManifest, i as NodeFS, l as SkillManager, n as FileArtifactStore, o as OxcSchemaInferer, r as FileMemoryStore, s as ProcessSandboxExecutor, t as CliUiBridge, u as exportArchive } from "./dist-CvIMVwr3.js";
4
+ import { a as NodeScriptExecutor, c as SandboxedScriptExecutor, d as readArchiveManifest, i as NodeFS, l as SkillManager, n as FileArtifactStore, o as OxcSchemaInferer, r as FileMemoryStore, s as ProcessSandboxExecutor, t as CliUiBridge, u as exportArchive } from "./dist-Chgf2tcy.js";
5
5
 
6
6
  export { CliUiBridge, FileArtifactStore, FileMemoryStore, NodeFS, NodeScriptExecutor, OxcSchemaInferer, ProcessSandboxExecutor, SKILLS_LOCKFILE, SKILL_MANIFEST_FILE, SandboxedScriptExecutor, SkillManager, createScriptContext, exportArchive, probeLlmCapabilities, readArchiveManifest };
@@ -16,6 +16,16 @@ import { mkdtemp, rm, writeFile } from "node:fs/promises";
16
16
  * runtime/sandbox/networkPolicy.ts);node:net 裸模块为已知残余面(文档明示)。
17
17
  * .js 走 data: URL 导入(permission 下实证可用);.ts 走中性临时目录 file URL。
18
18
  */
19
+ /** 不可序列化返回值统一报错(不静默丢数据;0.2.4 跨执行器语义统一) */
20
+ function assertSerializable(value) {
21
+ try {
22
+ structuredClone(value);
23
+ } catch (e) {
24
+ const err = /* @__PURE__ */ new Error(`Script returned a non-serializable value: ${e instanceof Error ? e.message : String(e)}`);
25
+ err.code = "TOOL_EXECUTION_FAILED";
26
+ throw err;
27
+ }
28
+ }
19
29
  const send = (message) => {
20
30
  process.send?.(message);
21
31
  };
@@ -164,6 +174,7 @@ async function main(task) {
164
174
  };
165
175
  const runFn = mod["run"];
166
176
  const value = await runFn(task.args ?? {}, context);
177
+ assertSerializable(value);
167
178
  send({
168
179
  type: "execute-result",
169
180
  ok: true,
@@ -67,6 +67,16 @@ async function loadModule(scriptPath, scriptSource) {
67
67
  }
68
68
  return await import(`${pathToFileURL(scriptPath).href}?t=${Date.now()}`);
69
69
  }
70
+ /** 不可序列化返回值统一报错(不静默丢数据;0.2.4 跨执行器语义统一) */
71
+ function assertSerializable(value) {
72
+ try {
73
+ structuredClone(value);
74
+ } catch (e) {
75
+ const err = /* @__PURE__ */ new Error(`Script returned a non-serializable value: ${e instanceof Error ? e.message : String(e)}`);
76
+ err.code = "TOOL_EXECUTION_FAILED";
77
+ throw err;
78
+ }
79
+ }
70
80
  function post(message) {
71
81
  port.postMessage(message);
72
82
  }
@@ -216,6 +226,7 @@ async function main() {
216
226
  };
217
227
  const runFn = mod["run"];
218
228
  const value = await runFn(task.args ?? {}, context);
229
+ assertSerializable(value);
219
230
  post({
220
231
  type: "execute-result",
221
232
  ok: true,
@@ -1,4 +1,4 @@
1
- import { u as WebSkillError } from "./dist-D0saNPi_.js";
1
+ import { u as WebSkillError } from "./dist-D7MsoMPx.js";
2
2
 
3
3
  //#region ../runtime/dist/testing.js
4
4
  /**
package/dist/testing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { c as LlmClient, d as LlmResponse, f as LlmStreamEvent, h as MemoryStore, l as LlmCompleteInput, n as ArtifactStore, o as InteractionRequest, s as InteractionResponse, t as Artifact, v as UiBridge } from "./types-CKm5G_eQ-8W8FnP4u.js";
1
+ import { c as LlmClient, d as LlmResponse, f as LlmStreamEvent, h as MemoryStore, l as LlmCompleteInput, n as ArtifactStore, o as InteractionRequest, s as InteractionResponse, t as Artifact, v as UiBridge } from "./types-CKm5G_eQ-BqyXnvoR.js";
2
2
  import { a as loadGoogleConfigFromEnv, i as loadAnthropicConfigFromEnv, n as LlmEnvConfig, o as loadLlmConfigFromEnv, r as ProviderEnvConfig } from "./env-BPUBZCwJ-4jat_SVG.js";
3
3
  //#region ../runtime/dist/testing.d.ts
4
4
  //#region src/llm/mockLlmClient.d.ts
package/dist/testing.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as MemoryArtifactStore } from "./memoryArtifactStore-C9lFVqPF-yFz6yJj0.js";
2
2
  import { n as loadGoogleConfigFromEnv, r as loadLlmConfigFromEnv, t as loadAnthropicConfigFromEnv } from "./env--jJB-TSX-04klhTYi.js";
3
- import { n as MockLlmClient, r as MockUiBridge, t as InMemoryStore } from "./testing-B4pq6JYa.js";
3
+ import { n as MockLlmClient, r as MockUiBridge, t as InMemoryStore } from "./testing-BN18eqbD.js";
4
4
 
5
5
  export { InMemoryStore, MemoryArtifactStore, MockLlmClient, MockUiBridge, loadAnthropicConfigFromEnv, loadGoogleConfigFromEnv, loadLlmConfigFromEnv };
@@ -118,6 +118,8 @@ interface FileSystemProvider {
118
118
  readonly kind: string;
119
119
  readText(path: string): Promise<string>;
120
120
  writeText(path: string, content: string): Promise<void>;
121
+ /** 真追加(审计日志等 append-only 账本;不整读改写) */
122
+ appendText(path: string, content: string): Promise<void>;
121
123
  readBinary(path: string): Promise<Uint8Array>;
122
124
  writeBinary(path: string, content: Uint8Array): Promise<void>;
123
125
  exists(path: string): Promise<boolean>;
@@ -129,6 +131,11 @@ interface FileSystemProvider {
129
131
  }): Promise<void>;
130
132
  /** 原子重命名(lockfile 等先写临时文件再 rename 的场景;实现侧无原生 rename 时 copy+remove 兜底) */
131
133
  rename(from: string, to: string): Promise<void>;
134
+ /**
135
+ * 可选:返回 root 限定视图(realpath 包含校验全方法生效)。
136
+ * 实现:NodeFS 支持;缺省(无此方法)时调用方按词法校验降级。
137
+ */
138
+ withRoot?(root: string): FileSystemProvider;
132
139
  }
133
140
  //#endregion
134
141
  //#region src/fs/memoryFs.d.ts
@@ -139,6 +146,7 @@ declare class MemoryFS implements FileSystemProvider {
139
146
  constructor();
140
147
  readText(path: string): Promise<string>;
141
148
  writeText(path: string, content: string): Promise<void>;
149
+ appendText(path: string, content: string): Promise<void>;
142
150
  readBinary(path: string): Promise<Uint8Array>;
143
151
  writeBinary(path: string, content: Uint8Array): Promise<void>;
144
152
  exists(path: string): Promise<boolean>;
@@ -158,11 +166,6 @@ declare function atomicWriteText(fs: FileSystemProvider, path: string, content:
158
166
  //#region src/fs/pathSecurity.d.ts
159
167
  /** 统一分隔符为 `/`,去除 `.` 段与重复分隔符(不解析 `..`) */
160
168
  declare function normalizePath(path: string): string;
161
- /**
162
- * 外部标识(runId、candidateId、skillName、versionId 等)作为单一路径段使用前的统一校验:
163
- * 拒绝空串、`.`、`..`、含 `/` 或 `\`、含 `:`(Windows 盘符/ADS)。
164
- * 违规抛 FS_PATH_OUTSIDE_ROOT(kind 用于错误消息定位,如 "runId")。
165
- */
166
169
  declare function assertSafePathSegment(segment: string, kind: string): void;
167
170
  /**
168
171
  * 将相对路径安全地解析到 root 之内。
@@ -1,4 +1,4 @@
1
- import { _ as RenderResultRequest, o as InteractionRequest, s as InteractionResponse, v as UiBridge } from "./types-CKm5G_eQ-8W8FnP4u.js";
1
+ import { _ as RenderResultRequest, o as InteractionRequest, s as InteractionResponse, v as UiBridge } from "./types-CKm5G_eQ-BqyXnvoR.js";
2
2
  //#region ../ui-react/dist/index.d.ts
3
3
  //#region src/bridgeState.d.ts
4
4
  /**
package/dist/ui-react.js CHANGED
@@ -1,4 +1,4 @@
1
- import { S as renderMiniMarkdown, m as collectValues, w as shapeInteractionValue, x as renderMiniChart, y as interactionToFormModel } from "./dist-BJobG0i-.js";
1
+ import { S as renderMiniMarkdown, m as collectValues, w as shapeInteractionValue, x as renderMiniChart, y as interactionToFormModel } from "./dist-CeNAzFYi.js";
2
2
  import { useLayoutEffect, useRef, useState, useSyncExternalStore } from "react";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
 
package/dist/ui-vue.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as RenderResultRequest, o as InteractionRequest, s as InteractionResponse, v as UiBridge } from "./types-CKm5G_eQ-8W8FnP4u.js";
1
+ import { _ as RenderResultRequest, o as InteractionRequest, s as InteractionResponse, v as UiBridge } from "./types-CKm5G_eQ-BqyXnvoR.js";
2
2
  import { PropType } from "vue";
3
3
  //#region ../ui-vue/dist/index.d.ts
4
4
  //#region src/bridgeState.d.ts
package/dist/ui-vue.js CHANGED
@@ -1,4 +1,4 @@
1
- import { S as renderMiniMarkdown, m as collectValues, w as shapeInteractionValue, x as renderMiniChart, y as interactionToFormModel } from "./dist-BJobG0i-.js";
1
+ import { S as renderMiniMarkdown, m as collectValues, w as shapeInteractionValue, x as renderMiniChart, y as interactionToFormModel } from "./dist-CeNAzFYi.js";
2
2
  import { defineComponent, h, reactive, ref } from "vue";
3
3
 
4
4
  //#region ../ui-vue/dist/index.js
package/dist/ui.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { _ as RenderResultRequest, g as RenderBlock, o as InteractionRequest, r as ChartSpec, s as InteractionResponse, v as UiBridge } from "./types-CKm5G_eQ-8W8FnP4u.js";
2
- import { mt as buildRenderResult } from "./index-gjFuBevI.js";
1
+ import { _ as RenderResultRequest, g as RenderBlock, o as InteractionRequest, r as ChartSpec, s as InteractionResponse, v as UiBridge } from "./types-CKm5G_eQ-BqyXnvoR.js";
2
+ import { mt as buildRenderResult } from "./index-DZShzhon.js";
3
3
  //#region ../ui/dist/index.d.ts
4
4
  //#region src/model/formModel.d.ts
5
5
  interface FormModel {
package/dist/ui.js CHANGED
@@ -1,4 +1,4 @@
1
- import { w as buildRenderResult } from "./dist-NM4Mylx4.js";
2
- import { C as renderRenderResult, D as toVercelToolInvocation, E as toOpenUiLang, S as renderMiniMarkdown, T as toA2uiMessages, _ as fromOpenUiAction, a as CHART_PALETTE, b as renderBlocks, c as OPENUI_SUBMIT_ACTION, d as WEBSKILL_STYLES_CSS, f as WebFormBridge, g as fromA2uiAction, h as ensureStyles, i as A2UI_VERSION, l as VERCEL_INTERACTION_TOOL_NAME, m as collectValues, n as A2UI_CANCEL_ACTION, o as LitRendererBridge, p as chartToTable, r as A2UI_SUBMIT_ACTION, s as OPENUI_CANCEL_ACTION, t as A2UI_BASIC_CATALOG_ID, u as VercelUiBridge, v as fromVercelToolResult, w as shapeInteractionValue, x as renderMiniChart, y as interactionToFormModel } from "./dist-BJobG0i-.js";
1
+ import { w as buildRenderResult } from "./dist-CV64gN62.js";
2
+ import { C as renderRenderResult, D as toVercelToolInvocation, E as toOpenUiLang, S as renderMiniMarkdown, T as toA2uiMessages, _ as fromOpenUiAction, a as CHART_PALETTE, b as renderBlocks, c as OPENUI_SUBMIT_ACTION, d as WEBSKILL_STYLES_CSS, f as WebFormBridge, g as fromA2uiAction, h as ensureStyles, i as A2UI_VERSION, l as VERCEL_INTERACTION_TOOL_NAME, m as collectValues, n as A2UI_CANCEL_ACTION, o as LitRendererBridge, p as chartToTable, r as A2UI_SUBMIT_ACTION, s as OPENUI_CANCEL_ACTION, t as A2UI_BASIC_CATALOG_ID, u as VercelUiBridge, v as fromVercelToolResult, w as shapeInteractionValue, x as renderMiniChart, y as interactionToFormModel } from "./dist-CeNAzFYi.js";
3
3
 
4
4
  export { A2UI_BASIC_CATALOG_ID, A2UI_CANCEL_ACTION, A2UI_SUBMIT_ACTION, A2UI_VERSION, CHART_PALETTE, LitRendererBridge, OPENUI_CANCEL_ACTION, OPENUI_SUBMIT_ACTION, VERCEL_INTERACTION_TOOL_NAME, VercelUiBridge, WEBSKILL_STYLES_CSS, WebFormBridge, buildRenderResult, chartToTable, collectValues, ensureStyles, fromA2uiAction, fromOpenUiAction, fromVercelToolResult, interactionToFormModel, renderBlocks, renderMiniChart, renderMiniMarkdown, renderRenderResult, shapeInteractionValue, toA2uiMessages, toOpenUiLang, toVercelToolInvocation };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webskill/sdk",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "WebSkill \u2014 browser/Node agent skill runtime (skills, tools, MCP, governance, UI)",
5
5
  "license": "MIT",
6
6
  "type": "module",