@webskill/sdk 0.0.4 → 0.0.5

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,4 +1,4 @@
1
- import { A as LlmClient, C as InteractionPolicy, It as FileStat, Jt as SkillInstallSource, Lt as FileSystemProvider, N as LlmResponse, P as LlmStreamEvent, Q as RenderResultRequest, St as bridgeError, T as InteractionResponse, Zt as SkillManifest, ct as ScriptExecutionContext, d as BridgeResponse, dt as ToolDefinition, kt as parseBridgeRequest, l as BridgeCapabilities, lt as ScriptExecutor, m as ExternalToolSource, p as ExternalSkillProvider, pt as ToolResult, rn as VerifyResult, tn as SkillsLockfile, u as BridgeRequest, vt as UiBridge, w as InteractionRequest } from "./index-CqDIreSE.js";
1
+ import { A as InteractionResponse, F as LlmClient, Gt as FileSystemProvider, Lt as parseBridgeRequest, O as InteractionPolicy, Ot as bridgeError, R as LlmResponse, Wt as FileStat, Y as NetworkPolicy, _t as ToolDefinition, an as SkillManifest, c as ApprovalScope, d as BridgeCapabilities, dn as VerifyResult, ht as ScriptExecutor, it as RenderResultRequest, k as InteractionRequest, ln as SkillsLockfile, m as BridgeResponse, mt as ScriptExecutionContext, nn as SkillInstallSource, p as BridgeRequest, v as ExternalSkillProvider, wt as UiBridge, y as ExternalToolSource, yt as ToolResult, z as LlmStreamEvent } from "./index-BQDc-U1x.js";
2
2
  //#region ../browser/dist/index.d.ts
3
3
  //#region src/fs/featureDetection.d.ts
4
4
  /** 检测当前环境是否可用 OPFS(navigator.storage.getDirectory) */
@@ -28,17 +28,22 @@ declare class OpfsProvider implements FileSystemProvider {
28
28
  //#region src/executor/workerBootstrap.d.ts
29
29
  /**
30
30
  * Worker 引导源码(字符串 → Blob URL → new Worker(url, {type:'module'}))。
31
- * 注意:内容为纯 JS,不能含反引号与 ${ 占位(外层用模板字符串内嵌)。
31
+ * 注意:内容为纯 JS,不能含反引号与 ${ 占位(外层用模板字符串内嵌);
32
+ * isNetworkAllowed/networkUrlHost 经函数源码注入(匹配逻辑单一来源在
33
+ * runtime/sandbox/networkPolicy.ts,此处禁止复制实现)。
32
34
  *
33
35
  * 协议(宿主 ↔ Worker):
34
- * - 宿主 → Worker:{type:'load', id, source} 请求加载脚本定义
35
- * - 宿主 → Worker:{type:'execute', id, skillName, runId, source, args} 请求执行
36
+ * - 宿主 → Worker:{type:'load', id, source, networkPolicy?} 请求加载脚本定义
37
+ * - 宿主 → Worker:{type:'execute', id, skillName, runId, source, args, networkPolicy?} 请求执行
36
38
  * - Worker → 宿主:{type:'load-result', id, ok, definition?, error?}
37
39
  * - Worker → 宿主:{type:'execute-result', id, ok, value?, stdout, stderr, error?}
38
40
  * - Worker → 宿主:{type:'bridge', request} 能力桥 RPC(readReference/writeArtifact/confirm)
39
41
  * - 宿主 → Worker:{type:'bridge-response', response}
42
+ * - Worker → 宿主:{type:'network-blocked', host} 网络阻断通知(宿主记 run.warning,URL 脱敏只记 host)
40
43
  *
41
44
  * .js 源码经 data: URL 动态 import;主线程从不 import 技能脚本。
45
+ * 网络管控:包装 fetch / XMLHttpRequest / WebSocket / EventSource,
46
+ * 策略默认 deny-all,由 load/execute 消息携带更新。
42
47
  */
43
48
  declare const WORKER_BOOTSTRAP_SOURCE: string;
44
49
  //#endregion
@@ -116,6 +121,12 @@ declare class BrowserWorkerScriptExecutor implements ScriptExecutor {
116
121
  fs: FileSystemProvider;
117
122
  workerFactory?: WorkerFactory;
118
123
  capabilities?: BridgeCapabilities;
124
+ /** 网络策略:默认 'deny-all'(白名单见 runtime/sandbox/networkPolicy) */
125
+ networkPolicy?: NetworkPolicy;
126
+ /** require-approval 模式的授权询问出口(缺失时 require-approval 一律拒绝) */
127
+ uiBridge?: UiBridge;
128
+ /** 授权粒度:默认 'once-per-run' */
129
+ approvalScope?: ApprovalScope;
119
130
  /** D4 opt-in:配置 esbuild-wasm 资产 URL 后 .ts 经宿主侧转译执行(未配置 .ts → TOOL_UNSUPPORTED) */
120
131
  typescript?: TypeScriptSupportOptions;
121
132
  });
package/dist/browser.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as parseBridgeRequest, B as SkillDiscovery, C as bridgeError, H as WebSkillError, I as SKILLS_LOCKFILE, J as isValidSkillName, L as SKILL_MANIFEST_FILE, O as mergeCatalogEntries, U as buildCatalog, W as buildManifest, Z as parseSkillMarkdown, b as RUN_SNAPSHOT_SCHEMA_VERSION, c as FsRunSnapshotStore, et as resolveInsideRoot, g as ProgressiveRouter, h as OpenAiCompatibleClient, i as AgentLoop, k as normalizeToolContent, nt as verifyManifest, o as FsArtifactStore, p as MockLlmClient, s as FsMemoryStore, tt as validateSkills } from "./dist-COsE72Ct.js";
1
+ import { A as mergeCatalogEntries, B as SKILL_MANIFEST_FILE, G as WebSkillError, K as buildCatalog, M as normalizeToolContent, N as parseBridgeRequest, U as SkillDiscovery, Z as isValidSkillName, _ as ProgressiveRouter, a as CapabilityApproval, at as verifyManifest, c as FsMemoryStore, et as parseSkillMarkdown, g as OpenAiCompatibleClient, i as AgentLoop, it as validateSkills, j as networkUrlHost, k as isNetworkAllowed, l as FsRunSnapshotStore, m as MockLlmClient, q as buildManifest, rt as resolveInsideRoot, s as FsArtifactStore, w as bridgeError, x as RUN_SNAPSHOT_SCHEMA_VERSION, z as SKILLS_LOCKFILE } from "./dist-D405AlPD.js";
2
2
  import { unzipSync } from "fflate";
3
3
 
4
4
  //#region ../browser/dist/index.js
@@ -134,23 +134,92 @@ var OpfsProvider = class {
134
134
  };
135
135
  /**
136
136
  * Worker 引导源码(字符串 → Blob URL → new Worker(url, {type:'module'}))。
137
- * 注意:内容为纯 JS,不能含反引号与 ${ 占位(外层用模板字符串内嵌)。
137
+ * 注意:内容为纯 JS,不能含反引号与 ${ 占位(外层用模板字符串内嵌);
138
+ * isNetworkAllowed/networkUrlHost 经函数源码注入(匹配逻辑单一来源在
139
+ * runtime/sandbox/networkPolicy.ts,此处禁止复制实现)。
138
140
  *
139
141
  * 协议(宿主 ↔ Worker):
140
- * - 宿主 → Worker:{type:'load', id, source} 请求加载脚本定义
141
- * - 宿主 → Worker:{type:'execute', id, skillName, runId, source, args} 请求执行
142
+ * - 宿主 → Worker:{type:'load', id, source, networkPolicy?} 请求加载脚本定义
143
+ * - 宿主 → Worker:{type:'execute', id, skillName, runId, source, args, networkPolicy?} 请求执行
142
144
  * - Worker → 宿主:{type:'load-result', id, ok, definition?, error?}
143
145
  * - Worker → 宿主:{type:'execute-result', id, ok, value?, stdout, stderr, error?}
144
146
  * - Worker → 宿主:{type:'bridge', request} 能力桥 RPC(readReference/writeArtifact/confirm)
145
147
  * - 宿主 → Worker:{type:'bridge-response', response}
148
+ * - Worker → 宿主:{type:'network-blocked', host} 网络阻断通知(宿主记 run.warning,URL 脱敏只记 host)
146
149
  *
147
150
  * .js 源码经 data: URL 动态 import;主线程从不 import 技能脚本。
151
+ * 网络管控:包装 fetch / XMLHttpRequest / WebSocket / EventSource,
152
+ * 策略默认 deny-all,由 load/execute 消息携带更新。
148
153
  */
149
154
  const WORKER_BOOTSTRAP_SOURCE = String.raw`
150
155
  'use strict';
151
156
 
152
157
  var pending = new Map();
153
158
  var bridgeSeq = 0;
159
+ var networkPolicy = 'deny-all';
160
+
161
+ ${isNetworkAllowed.toString()}
162
+
163
+ ${networkUrlHost.toString()}
164
+
165
+ function resolveUrl(raw) {
166
+ try {
167
+ return new URL(raw, self.location.href).href;
168
+ } catch (e) {
169
+ return String(raw);
170
+ }
171
+ }
172
+
173
+ function networkGate(rawUrl) {
174
+ var url = resolveUrl(rawUrl);
175
+ if (isNetworkAllowed(networkPolicy, url)) return null;
176
+ var host = networkUrlHost(url);
177
+ self.postMessage({ type: 'network-blocked', host: host });
178
+ var err = new Error('Network request blocked by sandbox network policy: ' + host);
179
+ err.code = 'NETWORK_BLOCKED';
180
+ return err;
181
+ }
182
+
183
+ if (typeof self.fetch === 'function') {
184
+ var originalFetch = self.fetch;
185
+ self.fetch = function (input, init) {
186
+ var raw = typeof input === 'string' ? input : input && input.url ? input.url : String(input);
187
+ var blocked = networkGate(raw);
188
+ if (blocked) return Promise.reject(blocked);
189
+ return originalFetch.call(this, input, init);
190
+ };
191
+ }
192
+
193
+ if (typeof XMLHttpRequest !== 'undefined') {
194
+ var originalXhrOpen = XMLHttpRequest.prototype.open;
195
+ XMLHttpRequest.prototype.open = function (method, url) {
196
+ var blocked = networkGate(url);
197
+ if (blocked) throw blocked;
198
+ return originalXhrOpen.apply(this, arguments);
199
+ };
200
+ }
201
+
202
+ if (typeof WebSocket !== 'undefined') {
203
+ var OriginalWebSocket = WebSocket;
204
+ self.WebSocket = function (url, protocols) {
205
+ var blocked = networkGate(url);
206
+ if (blocked) throw blocked;
207
+ return protocols === undefined
208
+ ? new OriginalWebSocket(url)
209
+ : new OriginalWebSocket(url, protocols);
210
+ };
211
+ self.WebSocket.prototype = OriginalWebSocket.prototype;
212
+ }
213
+
214
+ if (typeof EventSource !== 'undefined') {
215
+ var OriginalEventSource = EventSource;
216
+ self.EventSource = function (url, config) {
217
+ var blocked = networkGate(url);
218
+ if (blocked) throw blocked;
219
+ return config === undefined ? new OriginalEventSource(url) : new OriginalEventSource(url, config);
220
+ };
221
+ self.EventSource.prototype = OriginalEventSource.prototype;
222
+ }
154
223
 
155
224
  function loadModule(source) {
156
225
  var url = 'data:text/javascript;charset=utf-8,' + encodeURIComponent(source);
@@ -212,6 +281,7 @@ self.onmessage = async function (event) {
212
281
  }
213
282
 
214
283
  if (msg.type === 'load') {
284
+ if (msg.networkPolicy !== undefined) networkPolicy = msg.networkPolicy;
215
285
  try {
216
286
  var mod = await loadModule(msg.source);
217
287
  self.postMessage({
@@ -225,12 +295,13 @@ self.onmessage = async function (event) {
225
295
  },
226
296
  });
227
297
  } catch (e) {
228
- postError('load-result', msg.id, 'TOOL_EXECUTION_FAILED', String((e && e.message) || e));
298
+ postError('load-result', msg.id, (e && e.code) || 'TOOL_EXECUTION_FAILED', String((e && e.message) || e));
229
299
  }
230
300
  return;
231
301
  }
232
302
 
233
303
  if (msg.type === 'execute') {
304
+ if (msg.networkPolicy !== undefined) networkPolicy = msg.networkPolicy;
234
305
  var stdout = [];
235
306
  var stderr = [];
236
307
  var originals = {
@@ -543,6 +614,8 @@ var BrowserWorkerScriptExecutor = class {
543
614
  #fs;
544
615
  #workerFactory;
545
616
  #capabilities;
617
+ #networkPolicy;
618
+ #approval;
546
619
  #transpiler;
547
620
  constructor(deps) {
548
621
  this.#fs = deps.fs;
@@ -556,6 +629,11 @@ var BrowserWorkerScriptExecutor = class {
556
629
  writeArtifact: deps.capabilities?.writeArtifact ?? true,
557
630
  confirm: deps.capabilities?.confirm ?? true
558
631
  };
632
+ this.#networkPolicy = deps.networkPolicy ?? "deny-all";
633
+ this.#approval = new CapabilityApproval({
634
+ ...deps.uiBridge ? { uiBridge: deps.uiBridge } : {},
635
+ ...deps.approvalScope ? { scope: deps.approvalScope } : {}
636
+ });
559
637
  }
560
638
  /** 定位 scripts/<name>.js;.ts → TOOL_UNSUPPORTED(D4);冲突/缺失结构化报错 */
561
639
  async #locateScript(skillRoot, scriptName) {
@@ -584,7 +662,8 @@ var BrowserWorkerScriptExecutor = class {
584
662
  const data = await this.#request(worker, {
585
663
  type: "load",
586
664
  id: "load-1",
587
- source: script.source
665
+ source: script.source,
666
+ networkPolicy: this.#networkPolicy
588
667
  });
589
668
  if (!data.ok) throw new WebSkillError("TOOL_EXECUTION_FAILED", `Failed to load script "${scriptName}": ${data.error?.message ?? "unknown error"}`);
590
669
  return {
@@ -621,8 +700,9 @@ var BrowserWorkerScriptExecutor = class {
621
700
  skillName: context.skillName,
622
701
  runId: context.runId,
623
702
  source: script.source,
624
- args
625
- }, timeoutMs, (bridgeRequest) => this.#handleBridge(bridgeRequest, context));
703
+ args,
704
+ networkPolicy: this.#networkPolicy
705
+ }, timeoutMs, (bridgeRequest) => this.#handleBridge(bridgeRequest, context), (host) => context.onWarning?.(`Network request blocked by sandbox network policy: ${host}`));
626
706
  if (!response.ok) {
627
707
  const stderrSummary = response.stderr?.length ? ` | stderr: ${response.stderr.join(" | ").slice(0, 500)}` : "";
628
708
  return {
@@ -656,8 +736,8 @@ var BrowserWorkerScriptExecutor = class {
656
736
  worker.terminate();
657
737
  }
658
738
  }
659
- /** 发消息并按 id 等回包;可选超时;onBridge 处理执行期间的能力桥请求 */
660
- #request(worker, message, timeoutMs, onBridge) {
739
+ /** 发消息并按 id 等回包;可选超时;onBridge 处理执行期间的能力桥请求;onNetworkBlocked 收网络阻断通知 */
740
+ #request(worker, message, timeoutMs, onBridge, onNetworkBlocked) {
661
741
  const id = String(message["id"]);
662
742
  return new Promise((resolve, reject) => {
663
743
  let settled = false;
@@ -670,6 +750,10 @@ var BrowserWorkerScriptExecutor = class {
670
750
  worker.addEventListener("message", (event) => {
671
751
  const data = event.data;
672
752
  if (!data || typeof data !== "object") return;
753
+ if (data.type === "network-blocked") {
754
+ if (typeof data.host === "string") onNetworkBlocked?.(data.host);
755
+ return;
756
+ }
673
757
  if (data.type === "bridge" && onBridge) {
674
758
  const request = parseBridgeRequest(data.request);
675
759
  const respond = (response) => worker.postMessage({
@@ -691,20 +775,36 @@ var BrowserWorkerScriptExecutor = class {
691
775
  worker.postMessage(message);
692
776
  });
693
777
  }
694
- /** 能力桥宿主侧处理:能力关闭即 TOOL_UNSUPPORTED;readReference/writeArtifact/confirm 委托 context */
778
+ /** 能力桥宿主侧处理:能力关闭/授权拒绝即 TOOL_UNSUPPORTED;判定逻辑共用 runtime/sandbox/approval */
695
779
  async #handleBridge(request, context) {
696
- const unsupported = (capability) => bridgeError(request.id, "TOOL_UNSUPPORTED", `Capability "${capability}" is disabled`);
780
+ const gate = async (capability, message, details) => {
781
+ const decision = await this.#approval.authorize({
782
+ runId: context.runId,
783
+ capability,
784
+ mode: this.#capabilities[capability],
785
+ message,
786
+ ...details !== void 0 ? { details } : {}
787
+ });
788
+ if (decision === "allowed") return void 0;
789
+ return bridgeError(request.id, "TOOL_UNSUPPORTED", decision === "disabled" ? `Capability "${capability}" is disabled` : `Capability "${capability}" was denied by the user`);
790
+ };
697
791
  try {
698
792
  switch (request.kind) {
699
- case "readReference":
700
- if (!this.#capabilities.readReference) return unsupported("readReference");
793
+ case "readReference": {
794
+ const denied = await gate("readReference", `Script "${context.skillName}" wants to read reference "${request.path}"`, { path: request.path });
795
+ if (denied) return denied;
701
796
  return {
702
797
  id: request.id,
703
798
  ok: true,
704
799
  value: await context.readReference(request.path)
705
800
  };
801
+ }
706
802
  case "writeArtifact": {
707
- if (!this.#capabilities.writeArtifact) return unsupported("writeArtifact");
803
+ const denied = await gate("writeArtifact", `Script "${context.skillName}" wants to write artifact "${request.path}"`, {
804
+ path: request.path,
805
+ mimeType: request.mimeType
806
+ });
807
+ if (denied) return denied;
708
808
  const content = typeof request.content === "string" ? request.content : new Uint8Array(request.content);
709
809
  const artifact = await context.writeArtifact(request.path, content, { ...request.mimeType ? { mimeType: request.mimeType } : {} });
710
810
  return {
@@ -713,13 +813,16 @@ var BrowserWorkerScriptExecutor = class {
713
813
  value: artifact
714
814
  };
715
815
  }
716
- case "confirm":
717
- if (!this.#capabilities.confirm || !context.confirm) return unsupported("confirm");
816
+ case "confirm": {
817
+ if (!context.confirm) return bridgeError(request.id, "TOOL_UNSUPPORTED", "Capability \"confirm\" is disabled");
818
+ const denied = await gate("confirm", `Script "${context.skillName}" asks for confirmation: ${request.message}`);
819
+ if (denied) return denied;
718
820
  return {
719
821
  id: request.id,
720
822
  ok: true,
721
823
  value: await context.confirm(request.message)
722
824
  };
825
+ }
723
826
  }
724
827
  } catch (e) {
725
828
  return bridgeError(request.id, e instanceof WebSkillError ? e.code : "TOOL_EXECUTION_FAILED", messageOf(e));
@@ -5,10 +5,11 @@ function shapeInteractionValue(model, values) {
5
5
  case "ask": return values["answer"];
6
6
  case "confirm": return values["confirmed"] === true;
7
7
  case "select": return values["selected"];
8
+ case "authorize": return true;
8
9
  case "form": return values;
9
10
  }
10
11
  }
11
- /** 四类 InteractionRequest → 统一中间模型(框架无关) */
12
+ /** 五类 InteractionRequest → 统一中间模型(框架无关) */
12
13
  function interactionToFormModel(request) {
13
14
  switch (request.type) {
14
15
  case "ask": return {
@@ -63,6 +64,14 @@ function interactionToFormModel(request) {
63
64
  submitLabel: "Select",
64
65
  cancelLabel: "Cancel"
65
66
  };
67
+ case "authorize": return {
68
+ kind: "authorize",
69
+ title: "Authorization required",
70
+ message: request.message,
71
+ controls: [],
72
+ submitLabel: "Allow",
73
+ cancelLabel: "Deny"
74
+ };
66
75
  }
67
76
  }
68
77
  const isEmpty = (v) => v === void 0 || v === "";
@@ -551,6 +560,15 @@ function toOpenUiLang(request) {
551
560
  options: request.options
552
561
  }];
553
562
  break;
563
+ case "authorize":
564
+ title = "Authorization required";
565
+ fields = [{
566
+ name: "approved",
567
+ label: request.message,
568
+ control: "boolean",
569
+ defaultValue: false
570
+ }];
571
+ break;
554
572
  }
555
573
  lines.push(...fieldStatements(fields));
556
574
  const children = fields.map((_, i) => `f${i}`);
@@ -617,7 +635,11 @@ function toA2uiMessages(request) {
617
635
  components.push(text("title", request.title, "h3"));
618
636
  children.push("title");
619
637
  }
620
- const message = request.type === "ask" || request.type === "confirm" || request.type === "select" ? request.message : void 0;
638
+ if (request.type === "authorize") {
639
+ components.push(text("title", "Authorization required", "h3"));
640
+ children.push("title");
641
+ }
642
+ const message = request.type === "ask" || request.type === "confirm" || request.type === "select" || request.type === "authorize" ? request.message : void 0;
621
643
  if (message) {
622
644
  components.push(text("message", message));
623
645
  children.push("message");
@@ -632,7 +654,7 @@ function toA2uiMessages(request) {
632
654
  label: request.message,
633
655
  type: "boolean",
634
656
  defaultValue: request.defaultValue ?? true
635
- }] : [{
657
+ }] : request.type === "authorize" ? [] : [{
636
658
  name: "selected",
637
659
  label: request.message,
638
660
  type: "select",
@@ -675,7 +697,7 @@ function toA2uiMessages(request) {
675
697
  });
676
698
  children.push(`field_${field.name}`);
677
699
  }
678
- components.push(text("submit_label", "Submit"));
700
+ components.push(text("submit_label", request.type === "authorize" ? "Allow" : "Submit"));
679
701
  components.push({
680
702
  id: "submit",
681
703
  component: "Button",
@@ -686,7 +708,7 @@ function toA2uiMessages(request) {
686
708
  context: { requestId: request.id }
687
709
  } }
688
710
  });
689
- components.push(text("cancel_label", "Cancel"));
711
+ components.push(text("cancel_label", request.type === "authorize" ? "Deny" : "Cancel"));
690
712
  components.push({
691
713
  id: "cancel",
692
714
  component: "Button",
@@ -15359,13 +15381,15 @@ var LitRendererBridge = class {
15359
15381
  const surfaces = processor.getClientDataModel("v0.9.1")?.surfaces;
15360
15382
  const formValues = typeof surfaces?.[surfaceId] === "object" && surfaces[surfaceId] !== null ? surfaces[surfaceId]["form"] ?? action.context : action.context;
15361
15383
  cleanup(surfaceEl);
15362
- resolve(fromA2uiAction({
15384
+ const response = fromA2uiAction({
15363
15385
  ...action,
15364
15386
  context: {
15365
15387
  ...action.context,
15366
15388
  values: formValues
15367
15389
  }
15368
- }));
15390
+ });
15391
+ if (input.type === "authorize" && !response.cancelled) response.value = true;
15392
+ resolve(response);
15369
15393
  }, { version: "v0.9.1" });
15370
15394
  processor.onSurfaceCreated((surface) => {
15371
15395
  const el = this.#doc.createElement("a2ui-surface");
@@ -259,6 +259,15 @@ function checkSkillRules(input) {
259
259
  severity: "error",
260
260
  message: `Unsupported script file in scripts/ of directory ${dirName}: ${fileName} (only .ts/.js and .schema.json sidecars allowed)`
261
261
  });
262
+ const allowedTools = metadata?.["allowed-tools"];
263
+ if (Array.isArray(allowedTools)) {
264
+ const scriptNames = new Set((input.scriptFileNames ?? []).filter((f) => SCRIPT_EXTENSION_RE.test(f)).map((f) => f.replace(SCRIPT_EXTENSION_RE, "")));
265
+ for (const entry of allowedTools) if (typeof entry === "string" && !scriptNames.has(entry)) issues.push({
266
+ code: "SKILL_UNKNOWN_ALLOWED_TOOL",
267
+ severity: "warning",
268
+ message: `allowed-tools entry ${JSON.stringify(entry)} of directory ${dirName} does not match any script in scripts/`
269
+ });
270
+ }
262
271
  return issues;
263
272
  }
264
273
  /** 由条目列表构建 Catalog,保证按名称排序 */
@@ -908,7 +917,7 @@ const ASK_USER_TOOL = {
908
917
  * 不暴露 fs 本体(沙箱语义,对齐 deferred-items D1)。
909
918
  */
910
919
  function createScriptContext(deps) {
911
- const { fs, artifactStore, skillName, skillRoot, runId, confirm } = deps;
920
+ const { fs, artifactStore, skillName, skillRoot, runId, confirm, onWarning } = deps;
912
921
  return {
913
922
  skillName,
914
923
  runId,
@@ -928,7 +937,8 @@ function createScriptContext(deps) {
928
937
  mimeType: options?.mimeType
929
938
  });
930
939
  },
931
- ...confirm ? { confirm } : {}
940
+ ...confirm ? { confirm } : {},
941
+ ...onWarning ? { onWarning } : {}
932
942
  };
933
943
  }
934
944
  /**
@@ -1310,6 +1320,91 @@ function bridgeError(id, code, message) {
1310
1320
  }
1311
1321
  };
1312
1322
  }
1323
+ /**
1324
+ * 判定 URL 是否被策略放行:
1325
+ * - 'deny-all'(默认)全拒;'allow-all' 全放
1326
+ * - { allow } 条目支持三种写法:
1327
+ * - 精确域名 'api.example.com'(忽略端口与路径)
1328
+ * - 通配 '*.example.com'(含 apex 与任意深度子域)
1329
+ * - 源 'http://localhost:3000'(协议 + host + port 全等)
1330
+ * - URL 解析失败一律拒绝
1331
+ */
1332
+ function isNetworkAllowed(policy, url) {
1333
+ if (policy === "allow-all") return true;
1334
+ if (policy === "deny-all" || !policy || typeof policy !== "object") return false;
1335
+ var allow = policy.allow;
1336
+ if (!Array.isArray(allow)) return false;
1337
+ var parsed;
1338
+ try {
1339
+ parsed = new URL(url);
1340
+ } catch {
1341
+ return false;
1342
+ }
1343
+ var host = parsed.hostname.toLowerCase();
1344
+ for (var i = 0; i < allow.length; i++) {
1345
+ var entry = allow[i];
1346
+ if (typeof entry !== "string" || entry === "") continue;
1347
+ if (entry.indexOf("://") !== -1) {
1348
+ try {
1349
+ if (new URL(entry).origin === parsed.origin) return true;
1350
+ } catch {}
1351
+ continue;
1352
+ }
1353
+ var rule = entry.toLowerCase();
1354
+ if (rule.indexOf("*.") === 0) {
1355
+ var suffix = rule.slice(2);
1356
+ if (host === suffix || host.endsWith("." + suffix)) return true;
1357
+ } else if (host === rule) return true;
1358
+ }
1359
+ return false;
1360
+ }
1361
+ /** 阻断 trace 用的脱敏 host(解析失败返回占位,不记录完整 URL) */
1362
+ function networkUrlHost(url) {
1363
+ try {
1364
+ return new URL(url).hostname;
1365
+ } catch {
1366
+ return "(unparseable-url)";
1367
+ }
1368
+ }
1369
+ /**
1370
+ * Per-capability 强制授权判定(宿主侧,browser/node 执行器共用单一来源)。
1371
+ * 'require-approval' 模式下经注入的 UiBridge 发 authorize 交互;
1372
+ * once-per-run(默认)在 run 内记忆已批准能力,every-call 每次调用都问。
1373
+ */
1374
+ var CapabilityApproval = class {
1375
+ #uiBridge;
1376
+ #scope;
1377
+ /** runId → 已批准能力集合(once-per-run 记忆) */
1378
+ #approved = /* @__PURE__ */ new Map();
1379
+ #seq = 0;
1380
+ constructor(deps = {}) {
1381
+ this.#uiBridge = deps.uiBridge;
1382
+ this.#scope = deps.scope ?? "once-per-run";
1383
+ }
1384
+ async authorize(input) {
1385
+ const { runId, capability, mode } = input;
1386
+ if (mode === false) return "disabled";
1387
+ if (mode !== "require-approval") return "allowed";
1388
+ if (this.#scope === "once-per-run" && this.#approved.get(runId)?.has(capability)) return "allowed";
1389
+ if (!this.#uiBridge) return "denied";
1390
+ if ((await this.#uiBridge.request({
1391
+ type: "authorize",
1392
+ id: `authorize-${runId}-${capability}-${++this.#seq}`,
1393
+ capability,
1394
+ message: input.message,
1395
+ ...input.details !== void 0 ? { details: input.details } : {}
1396
+ })).value !== true) return "denied";
1397
+ if (this.#scope === "once-per-run") {
1398
+ let set = this.#approved.get(runId);
1399
+ if (!set) {
1400
+ set = /* @__PURE__ */ new Set();
1401
+ this.#approved.set(runId, set);
1402
+ }
1403
+ set.add(capability);
1404
+ }
1405
+ return "allowed";
1406
+ }
1407
+ };
1313
1408
  /** 结构化 trace 记录器;时钟与 id 工厂可注入(golden trace 用固定值保证确定性) */
1314
1409
  var TraceRecorder = class {
1315
1410
  #runId;
@@ -1938,6 +2033,13 @@ var AgentLoop = class {
1938
2033
  if (!root) return "";
1939
2034
  const executor = this.#deps.executor;
1940
2035
  if (!executor) return "";
2036
+ let allowedTools;
2037
+ try {
2038
+ const { metadata } = parseSkillMarkdown(await this.#deps.fs.readText(`${root}/SKILL.md`));
2039
+ const raw = metadata["allowed-tools"];
2040
+ if (raw !== void 0) if (Array.isArray(raw)) allowedTools = raw.filter((e) => typeof e === "string");
2041
+ else state.trace.record("run.warning", { message: `Skill "${skillName}" has a non-array "allowed-tools" metadata entry; ignored` });
2042
+ } catch {}
1941
2043
  const loaded = [];
1942
2044
  let scriptFiles = [];
1943
2045
  try {
@@ -1948,6 +2050,7 @@ var AgentLoop = class {
1948
2050
  for (const file of scriptFiles) {
1949
2051
  const match = /^(.*)\.(ts|js)$/.exec(file);
1950
2052
  if (!match?.[1]) continue;
2053
+ if (allowedTools && !allowedTools.includes(match[1])) continue;
1951
2054
  try {
1952
2055
  const def = await executor.loadDefinition(root, match[1]);
1953
2056
  await this.#enrichDefinition(root, match[1], def, state);
@@ -1982,10 +2085,12 @@ var AgentLoop = class {
1982
2085
  async #handleScriptTool(call, skillName, scriptName, state) {
1983
2086
  const root = this.#deps.skillIndex.get(skillName);
1984
2087
  if (!root) return toolError("TOOL_NOT_FOUND", `Skill "${skillName}" is not in the catalog`);
1985
- let args = call.arguments;
2088
+ if (!this.#deps.executor) return toolError("TOOL_UNSUPPORTED", `No script executor is configured; script tool "${call.name}" cannot run`);
1986
2089
  const def = state.activatedTools.get(call.name);
1987
- const missing = (def?.inputSchema?.required ?? []).filter((key) => args[key] === void 0);
1988
- if (missing.length > 0 && this.#deps.uiBridge && this.#policy.missingParams === "user" && def?.inputSchema) try {
2090
+ if (!def) return toolError("TOOL_NOT_FOUND", `Tool "${call.name}" is not available for skill "${skillName}"`);
2091
+ let args = call.arguments;
2092
+ const missing = (def.inputSchema?.required ?? []).filter((key) => args[key] === void 0);
2093
+ if (missing.length > 0 && this.#deps.uiBridge && this.#policy.missingParams === "user" && def.inputSchema) try {
1989
2094
  const value = await this.#interact(state, {
1990
2095
  type: "form",
1991
2096
  id: this.#nextInteractionId(state),
@@ -2003,14 +2108,14 @@ var AgentLoop = class {
2003
2108
  if (e instanceof BridgeRequestError) return toolError("UI_UNAVAILABLE", `Parameter form failed: ${e.message}`);
2004
2109
  throw e;
2005
2110
  }
2006
- if (!this.#deps.executor) return toolError("TOOL_UNSUPPORTED", `No script executor is configured; script tool "${call.name}" cannot run`);
2007
2111
  const context = createScriptContext({
2008
2112
  fs: this.#deps.fs,
2009
2113
  artifactStore: this.#deps.artifactStore,
2010
2114
  skillName,
2011
2115
  skillRoot: root,
2012
2116
  runId: state.runId,
2013
- confirm: (message) => this.#confirm(message, state)
2117
+ confirm: (message) => this.#confirm(message, state),
2118
+ onWarning: (message) => state.trace.record("run.warning", { message })
2014
2119
  });
2015
2120
  try {
2016
2121
  const before = new Set((await this.#deps.artifactStore.listArtifacts(state.runId)).map((a) => a.id));
@@ -2325,4 +2430,4 @@ var WebSkillRuntime = class {
2325
2430
  };
2326
2431
 
2327
2432
  //#endregion
2328
- export { renderCatalogJson as $, parseBridgeRequest as A, SkillDiscovery as B, bridgeError as C, fromVercelStreamPart as D, fromVercelResult as E, MemoryFS as F, checkSkillRules as G, WebSkillError as H, SKILLS_LOCKFILE as I, isValidSkillName as J, computeDigest as K, SKILL_MANIFEST_FILE as L, schemaToForm as M, toLlmToolSpec as N, mergeCatalogEntries as O, toVercelToolSpecs as P, renderAvailableSkillsXml as Q, SKILL_NAME_MAX_LENGTH as R, WebSkillRuntime as S, createScriptContext as T, buildCatalog as U, SkillReader as V, buildManifest as W, normalizePath as X, jsonRenderer as Y, parseSkillMarkdown as Z, READ_SKILL_FILE_INPUT_SCHEMA as _, EventBus as a, RUN_SNAPSHOT_SCHEMA_VERSION as b, FsRunSnapshotStore as c, InMemoryStore as d, resolveInsideRoot as et, MemoryArtifactStore as f, ProgressiveRouter as g, OpenAiCompatibleClient as h, AgentLoop as i, resolveToolName as j, normalizeToolContent as k, FullDisclosureRouter as l, MockUiBridge as m, ASK_USER_TOOL as n, verifyManifest as nt, FsArtifactStore as o, MockLlmClient as p, escapeXml as q, ASK_USER_TOOL_NAME as r, xmlRenderer as rt, FsMemoryStore as s, ASK_USER_INPUT_SCHEMA as t, validateSkills as tt, HookRunner as u, READ_SKILL_FILE_TOOL as v, buildRenderResult as w, TraceRecorder as x, READ_SKILL_FILE_TOOL_NAME as y, SKILL_NAME_PATTERN as z };
2433
+ export { normalizePath as $, mergeCatalogEntries as A, SKILL_MANIFEST_FILE as B, WebSkillRuntime as C, fromVercelResult as D, createScriptContext as E, schemaToForm as F, WebSkillError as G, SKILL_NAME_PATTERN as H, toLlmToolSpec as I, checkSkillRules as J, buildCatalog as K, toVercelToolSpecs as L, normalizeToolContent as M, parseBridgeRequest as N, fromVercelStreamPart as O, resolveToolName as P, jsonRenderer as Q, MemoryFS as R, TraceRecorder as S, buildRenderResult as T, SkillDiscovery as U, SKILL_NAME_MAX_LENGTH as V, SkillReader as W, escapeXml as X, computeDigest as Y, isValidSkillName as Z, ProgressiveRouter as _, CapabilityApproval as a, verifyManifest as at, READ_SKILL_FILE_TOOL_NAME as b, FsMemoryStore as c, HookRunner as d, parseSkillMarkdown as et, InMemoryStore as f, OpenAiCompatibleClient as g, MockUiBridge as h, AgentLoop as i, validateSkills as it, networkUrlHost as j, isNetworkAllowed as k, FsRunSnapshotStore as l, MockLlmClient as m, ASK_USER_TOOL as n, renderCatalogJson as nt, EventBus as o, xmlRenderer as ot, MemoryArtifactStore as p, buildManifest as q, ASK_USER_TOOL_NAME as r, resolveInsideRoot as rt, FsArtifactStore as s, ASK_USER_INPUT_SCHEMA as t, renderAvailableSkillsXml as tt, FullDisclosureRouter as u, READ_SKILL_FILE_INPUT_SCHEMA as v, bridgeError as w, RUN_SNAPSHOT_SCHEMA_VERSION as x, READ_SKILL_FILE_TOOL as y, SKILLS_LOCKFILE as z };
@@ -1,4 +1,4 @@
1
- import { A as parseBridgeRequest, C as bridgeError, H as WebSkillError, I as SKILLS_LOCKFILE, J as isValidSkillName, L as SKILL_MANIFEST_FILE, W as buildManifest, Z as parseSkillMarkdown, et as resolveInsideRoot, k as normalizeToolContent, nt as verifyManifest, o as FsArtifactStore, s as FsMemoryStore, tt as validateSkills } from "./dist-COsE72Ct.js";
1
+ import { B as SKILL_MANIFEST_FILE, G as WebSkillError, M as normalizeToolContent, N as parseBridgeRequest, Z as isValidSkillName, a as CapabilityApproval, at as verifyManifest, c as FsMemoryStore, et as parseSkillMarkdown, it as validateSkills, j as networkUrlHost, k as isNetworkAllowed, q as buildManifest, rt as resolveInsideRoot, s as FsArtifactStore, w as bridgeError, z as SKILLS_LOCKFILE } from "./dist-D405AlPD.js";
2
2
  import { existsSync, promises, readFileSync } from "node:fs";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath, pathToFileURL } from "node:url";
@@ -224,6 +224,11 @@ var NodeScriptExecutor = class {
224
224
  const baseName = (p) => p.split("/").pop() ?? p;
225
225
  const toPlatform$1 = (p) => p.split("/").join(path.sep);
226
226
  const messageOf$5 = (e) => e instanceof Error ? e.message : String(e);
227
+ /**
228
+ * 网络策略判定函数源码(注入 Worker;匹配逻辑单一来源在
229
+ * runtime/sandbox/networkPolicy.ts,Worker 线程不走 vitest 别名故注入而非 import)
230
+ */
231
+ const NETWORK_POLICY_LIB = `${isNetworkAllowed.toString()}\n${networkUrlHost.toString()}`;
227
232
  /** Worker 入口文件:src 为同目录 .ts;dist 为 dist/executor/ 下的 .js */
228
233
  function workerEntryPath() {
229
234
  const dir = path.dirname(fileURLToPath(import.meta.url));
@@ -245,6 +250,8 @@ var SandboxedScriptExecutor = class {
245
250
  #fs;
246
251
  #options;
247
252
  #capabilities;
253
+ #networkPolicy;
254
+ #approval;
248
255
  constructor(fs, options = {}) {
249
256
  this.#fs = fs;
250
257
  this.#options = options;
@@ -253,6 +260,11 @@ var SandboxedScriptExecutor = class {
253
260
  writeArtifact: options.capabilities?.writeArtifact ?? true,
254
261
  confirm: options.capabilities?.confirm ?? true
255
262
  };
263
+ this.#networkPolicy = options.networkPolicy ?? "deny-all";
264
+ this.#approval = new CapabilityApproval({
265
+ ...options.uiBridge ? { uiBridge: options.uiBridge } : {},
266
+ ...options.approvalScope ? { scope: options.approvalScope } : {}
267
+ });
256
268
  }
257
269
  async #locateScript(skillRoot, scriptName) {
258
270
  const tsPath = `${skillRoot}/scripts/${scriptName}.ts`;
@@ -302,7 +314,7 @@ var SandboxedScriptExecutor = class {
302
314
  skillName: context.skillName,
303
315
  runId: context.runId,
304
316
  args
305
- }, timeoutMs, (request) => this.#handleBridge(request, context));
317
+ }, timeoutMs, (request) => this.#handleBridge(request, context), (host) => context.onWarning?.(`Network request blocked by sandbox network policy: ${host}`));
306
318
  if (!result.ok) {
307
319
  const stderrSummary = result.stderr?.length ? ` | stderr: ${result.stderr.join(" | ").slice(0, 500)}` : "";
308
320
  return {
@@ -335,12 +347,16 @@ var SandboxedScriptExecutor = class {
335
347
  }
336
348
  }
337
349
  /** 起独立 Worker 执行任务;超时 terminate(同步死循环可杀);非零退出码 → TOOL_EXECUTION_FAILED */
338
- #runWorker(workerData, timeoutMs = 3e4, onBridge) {
350
+ #runWorker(workerData, timeoutMs = 3e4, onBridge, onNetworkBlocked) {
339
351
  const envWhitelist = this.#options.envWhitelist ?? [];
340
352
  const env = Object.fromEntries(envWhitelist.filter((key) => process.env[key] !== void 0).map((key) => [key, process.env[key]]));
341
353
  return new Promise((resolve, reject) => {
342
354
  const worker = new Worker(workerEntryPath(), {
343
- workerData,
355
+ workerData: {
356
+ ...workerData,
357
+ networkPolicy: this.#networkPolicy,
358
+ networkPolicyLib: NETWORK_POLICY_LIB
359
+ },
344
360
  env,
345
361
  resourceLimits: this.#options.resourceLimits ?? {
346
362
  maxOldGenerationSizeMb: 64,
@@ -361,6 +377,10 @@ var SandboxedScriptExecutor = class {
361
377
  fn();
362
378
  };
363
379
  worker.on("message", (msg) => {
380
+ if (msg?.type === "network-blocked") {
381
+ if (typeof msg.host === "string") onNetworkBlocked?.(msg.host);
382
+ return;
383
+ }
364
384
  if (msg?.type === "bridge" && onBridge) {
365
385
  const request = parseBridgeRequest(msg.request);
366
386
  const respond = (response) => worker.postMessage({
@@ -382,20 +402,36 @@ var SandboxedScriptExecutor = class {
382
402
  });
383
403
  });
384
404
  }
385
- /** 能力桥宿主侧处理:能力关闭即 TOOL_UNSUPPORTED;委托 context */
405
+ /** 能力桥宿主侧处理:能力关闭/授权拒绝即 TOOL_UNSUPPORTED;判定逻辑共用 runtime/sandbox/approval */
386
406
  async #handleBridge(request, context) {
387
- const unsupported = (capability) => bridgeError(request.id, "TOOL_UNSUPPORTED", `Capability "${capability}" is disabled`);
407
+ const gate = async (capability, message, details) => {
408
+ const decision = await this.#approval.authorize({
409
+ runId: context.runId,
410
+ capability,
411
+ mode: this.#capabilities[capability],
412
+ message,
413
+ ...details !== void 0 ? { details } : {}
414
+ });
415
+ if (decision === "allowed") return void 0;
416
+ return bridgeError(request.id, "TOOL_UNSUPPORTED", decision === "disabled" ? `Capability "${capability}" is disabled` : `Capability "${capability}" was denied by the user`);
417
+ };
388
418
  try {
389
419
  switch (request.kind) {
390
- case "readReference":
391
- if (!this.#capabilities.readReference) return unsupported("readReference");
420
+ case "readReference": {
421
+ const denied = await gate("readReference", `Script "${context.skillName}" wants to read reference "${request.path}"`, { path: request.path });
422
+ if (denied) return denied;
392
423
  return {
393
424
  id: request.id,
394
425
  ok: true,
395
426
  value: await context.readReference(request.path)
396
427
  };
428
+ }
397
429
  case "writeArtifact": {
398
- if (!this.#capabilities.writeArtifact) return unsupported("writeArtifact");
430
+ const denied = await gate("writeArtifact", `Script "${context.skillName}" wants to write artifact "${request.path}"`, {
431
+ path: request.path,
432
+ mimeType: request.mimeType
433
+ });
434
+ if (denied) return denied;
399
435
  const content = typeof request.content === "string" ? request.content : new Uint8Array(request.content);
400
436
  const artifact = await context.writeArtifact(request.path, content, { ...request.mimeType ? { mimeType: request.mimeType } : {} });
401
437
  return {
@@ -404,13 +440,16 @@ var SandboxedScriptExecutor = class {
404
440
  value: artifact
405
441
  };
406
442
  }
407
- case "confirm":
408
- if (!this.#capabilities.confirm || !context.confirm) return unsupported("confirm");
443
+ case "confirm": {
444
+ if (!context.confirm) return bridgeError(request.id, "TOOL_UNSUPPORTED", "Capability \"confirm\" is disabled");
445
+ const denied = await gate("confirm", `Script "${context.skillName}" asks for confirmation: ${request.message}`);
446
+ if (denied) return denied;
409
447
  return {
410
448
  id: request.id,
411
449
  ok: true,
412
450
  value: await context.confirm(request.message)
413
451
  };
452
+ }
414
453
  }
415
454
  } catch (e) {
416
455
  return bridgeError(request.id, e instanceof WebSkillError ? e.code : "TOOL_EXECUTION_FAILED", messageOf$5(e));
@@ -615,7 +654,8 @@ var FileMemoryStore = class extends FsMemoryStore {
615
654
  };
616
655
  /**
617
656
  * 命令行 UiBridge:ask→问答,confirm→y/n(带默认值),
618
- * form→逐字段提示(显示默认值与必填标记),select→编号列表。
657
+ * form→逐字段提示(显示默认值与必填标记),select→编号列表,
658
+ * authorize→授权询问(默认拒绝,仅显式 y/yes 批准)。
619
659
  * 输入/输出流可注入(测试用 PassThrough)。
620
660
  */
621
661
  var CliUiBridge = class {
@@ -659,6 +699,14 @@ var CliUiBridge = class {
659
699
  value: option ? option.value : void 0
660
700
  };
661
701
  }
702
+ case "authorize": {
703
+ this.#write(`[authorization required: ${input.capability}]\n`);
704
+ const answer = (await this.#question(`${input.message} [y/N] `)).trim().toLowerCase();
705
+ return {
706
+ id: input.id,
707
+ value: answer === "y" || answer === "yes"
708
+ };
709
+ }
662
710
  }
663
711
  }
664
712
  async progress(input) {
@@ -1,5 +1,5 @@
1
- import { A as LlmClient, Gt as SkillCatalogEntry, Lt as FileSystemProvider, M as LlmMessage, Zt as SkillManifest, at as RuntimeRun, bt as WebSkillRuntime, vt as UiBridge } from "./index-CqDIreSE.js";
2
- import { d as SkillManager } from "./index-BsbfEiaC.js";
1
+ import { $t as SkillCatalogEntry, Et as WebSkillRuntime, F as LlmClient, Gt as FileSystemProvider, L as LlmMessage, an as SkillManifest, dt as RuntimeRun, wt as UiBridge } from "./index-BQDc-U1x.js";
2
+ import { d as SkillManager } from "./index-aEple804.js";
3
3
  //#region ../governance/dist/index.d.ts
4
4
  //#region src/types.d.ts
5
5
  type CandidateStatus = 'draft' | 'pending-review' | 'approved' | 'published' | 'rejected';
@@ -1,5 +1,5 @@
1
- import { H as WebSkillError, J as isValidSkillName, et as resolveInsideRoot, tt as validateSkills } from "./dist-COsE72Ct.js";
2
- import { i as NodeFS } from "./dist-Bvhbxrrt.js";
1
+ import { G as WebSkillError, Z as isValidSkillName, it as validateSkills, rt as resolveInsideRoot } from "./dist-D405AlPD.js";
2
+ import { i as NodeFS } from "./dist-Ixnb-hNR.js";
3
3
  import path from "node:path";
4
4
  import { mkdtemp } from "node:fs/promises";
5
5
  import { tmpdir } from "node:os";
@@ -1,6 +1,6 @@
1
1
  //#region ../core/dist/index.d.ts
2
2
  //#region src/errors.d.ts
3
- type WebSkillErrorCode = 'FS_NOT_FOUND' | 'FS_PATH_OUTSIDE_ROOT' | 'SKILL_NOT_FOUND' | 'SKILL_INVALID_METADATA' | 'SKILL_INVALID_NAME' | 'SKILL_DUPLICATE_NAME' | 'SKILL_UNSUPPORTED_SCRIPT' | 'VALIDATION_FAILED' | 'TOOL_NOT_FOUND' | 'TOOL_EXECUTION_FAILED' | 'TOOL_UNSUPPORTED' | 'TOOL_SCHEMA_UNAVAILABLE' | 'RUN_TIMEOUT' | 'RUN_MAX_TURNS_EXCEEDED' | 'RUN_FAILED' | 'RUN_CANCELLED' | 'RUN_INTERACTION_TIMEOUT' | 'UI_UNAVAILABLE' | 'LLM_UNAVAILABLE' | 'LLM_REQUEST_FAILED' | 'INSTALL_FAILED' | 'UNINSTALL_FAILED' | 'EXPORT_FAILED' | 'INTEGRITY_FAILED' | 'FS_PERMISSION_DENIED' | 'MCP_ENDPOINT_UNAVAILABLE' | 'MCP_TOOL_NOT_FOUND' | 'CANDIDATE_INVALID' | 'APPROVAL_REQUIRED' | 'SKILL_QUARANTINED' | 'SKILL_DISABLED' | 'GOVERNANCE_FAILED' | 'RUN_SNAPSHOT_NOT_FOUND' | 'RUN_SNAPSHOT_EXPIRED' | 'RUN_SNAPSHOT_INCOMPATIBLE';
3
+ type WebSkillErrorCode = 'FS_NOT_FOUND' | 'FS_PATH_OUTSIDE_ROOT' | 'SKILL_NOT_FOUND' | 'SKILL_INVALID_METADATA' | 'SKILL_INVALID_NAME' | 'SKILL_DUPLICATE_NAME' | 'SKILL_UNSUPPORTED_SCRIPT' | 'VALIDATION_FAILED' | 'TOOL_NOT_FOUND' | 'TOOL_EXECUTION_FAILED' | 'NETWORK_BLOCKED' | 'TOOL_UNSUPPORTED' | 'TOOL_SCHEMA_UNAVAILABLE' | 'RUN_TIMEOUT' | 'RUN_MAX_TURNS_EXCEEDED' | 'RUN_FAILED' | 'RUN_CANCELLED' | 'RUN_INTERACTION_TIMEOUT' | 'UI_UNAVAILABLE' | 'LLM_UNAVAILABLE' | 'LLM_REQUEST_FAILED' | 'INSTALL_FAILED' | 'UNINSTALL_FAILED' | 'EXPORT_FAILED' | 'INTEGRITY_FAILED' | 'FS_PERMISSION_DENIED' | 'MCP_ENDPOINT_UNAVAILABLE' | 'MCP_TOOL_NOT_FOUND' | 'CANDIDATE_INVALID' | 'APPROVAL_REQUIRED' | 'SKILL_QUARANTINED' | 'SKILL_DISABLED' | 'GOVERNANCE_FAILED' | 'RUN_SNAPSHOT_NOT_FOUND' | 'RUN_SNAPSHOT_EXPIRED' | 'RUN_SNAPSHOT_INCOMPATIBLE';
4
4
  /** 所有公开 API 抛出的结构化错误,code 供上层可编程处理 */
5
5
  declare class WebSkillError extends Error {
6
6
  readonly code: WebSkillErrorCode;
@@ -472,6 +472,8 @@ interface ScriptExecutionContext {
472
472
  }): Promise<Artifact>;
473
473
  /** 脚本主动请求人在环确认;策略见 InteractionPolicy.confirmations */
474
474
  confirm?(message: string): Promise<boolean>;
475
+ /** 宿主侧降级 warning 出口(网络阻断等;引擎接线到 run.warning trace) */
476
+ onWarning?(message: string): void;
475
477
  }
476
478
  /** Schema 推导 port:纯文本静态分析脚本源码 → JSON Schema(best-effort) */
477
479
  interface SchemaInferer {
@@ -547,6 +549,8 @@ declare function createScriptContext(deps: {
547
549
  runId: string;
548
550
  /** 提供时暴露 context.confirm(由引擎按交互策略实现) */
549
551
  confirm?: (message: string) => Promise<boolean>;
552
+ /** 宿主侧降级 warning 出口(网络阻断等;引擎接线到 run.warning trace) */
553
+ onWarning?: (message: string) => void;
550
554
  }): ScriptExecutionContext;
551
555
  //#endregion
552
556
  //#region src/interaction/types.d.ts
@@ -573,6 +577,13 @@ type InteractionRequest = {
573
577
  label: string;
574
578
  value: unknown;
575
579
  }>;
580
+ } | {
581
+ /** 能力强制授权(require-approval):与脚本自发 confirm 区分,UI 渲染为授权样式 */
582
+ type: 'authorize';
583
+ id: string;
584
+ capability: 'readReference' | 'writeArtifact' | 'confirm';
585
+ message: string;
586
+ details?: unknown;
576
587
  };
577
588
  interface InteractionResponse {
578
589
  id: string;
@@ -891,16 +902,72 @@ interface BridgeResponse {
891
902
  message: string;
892
903
  };
893
904
  }
905
+ /**
906
+ * 能力模式:true 直通 / false 关闭(TOOL_UNSUPPORTED)/ 'require-approval' 调用前强制授权
907
+ * (布尔语义与现状完全兼容)
908
+ */
909
+ type CapabilityMode = boolean | 'require-approval';
910
+ /** 授权粒度:'once-per-run'(默认,run 内同类能力批准一次)/ 'every-call'(每次调用都问) */
911
+ type ApprovalScope = 'once-per-run' | 'every-call';
894
912
  /** 三能力独立开关;缺省全开,显式 false 即关闭(TOOL_UNSUPPORTED) */
895
913
  interface BridgeCapabilities {
896
- readReference?: boolean;
897
- writeArtifact?: boolean;
898
- confirm?: boolean;
914
+ readReference?: CapabilityMode;
915
+ writeArtifact?: CapabilityMode;
916
+ confirm?: CapabilityMode;
899
917
  }
900
918
  /** 入站校验:非法 kind / 缺 id / 缺字段 → undefined(调用方忽略并记 warning) */
901
919
  declare function parseBridgeRequest(data: unknown): BridgeRequest | undefined;
902
920
  declare function bridgeError(id: string, code: string, message: string): BridgeResponse;
903
921
  //#endregion
922
+ //#region src/sandbox/networkPolicy.d.ts
923
+ /**
924
+ * 网络策略类型 + 匹配逻辑(单一来源:browser worker 经函数字符串注入、
925
+ * node worker 直接 import,禁止各自重复实现)。
926
+ *
927
+ * 注意:isNetworkAllowed 会被 toString() 内嵌进浏览器 Worker bootstrap,
928
+ * 函数体必须自包含(不引用模块内其它符号),且不得使用模板字符串/反引号。
929
+ */
930
+ type NetworkPolicy = 'deny-all' | 'allow-all' | {
931
+ allow: string[];
932
+ };
933
+ /**
934
+ * 判定 URL 是否被策略放行:
935
+ * - 'deny-all'(默认)全拒;'allow-all' 全放
936
+ * - { allow } 条目支持三种写法:
937
+ * - 精确域名 'api.example.com'(忽略端口与路径)
938
+ * - 通配 '*.example.com'(含 apex 与任意深度子域)
939
+ * - 源 'http://localhost:3000'(协议 + host + port 全等)
940
+ * - URL 解析失败一律拒绝
941
+ */
942
+ declare function isNetworkAllowed(policy: NetworkPolicy, url: string): boolean;
943
+ /** 阻断 trace 用的脱敏 host(解析失败返回占位,不记录完整 URL) */
944
+ declare function networkUrlHost(url: string): string;
945
+ //#endregion
946
+ //#region src/sandbox/approval.d.ts
947
+ /** 桥消息对应的三类能力 */
948
+ type BridgeCapability = 'readReference' | 'writeArtifact' | 'confirm';
949
+ /** allowed 放行;denied 用户拒绝/无法询问;disabled 能力关闭(两者都回 TOOL_UNSUPPORTED,仅消息不同) */
950
+ type ApprovalDecision = 'allowed' | 'denied' | 'disabled';
951
+ /**
952
+ * Per-capability 强制授权判定(宿主侧,browser/node 执行器共用单一来源)。
953
+ * 'require-approval' 模式下经注入的 UiBridge 发 authorize 交互;
954
+ * once-per-run(默认)在 run 内记忆已批准能力,every-call 每次调用都问。
955
+ */
956
+ declare class CapabilityApproval {
957
+ #private;
958
+ constructor(deps?: {
959
+ uiBridge?: UiBridge;
960
+ scope?: ApprovalScope;
961
+ });
962
+ authorize(input: {
963
+ runId: string;
964
+ capability: BridgeCapability;
965
+ mode: CapabilityMode;
966
+ message: string;
967
+ details?: unknown;
968
+ }): Promise<ApprovalDecision>;
969
+ }
970
+ //#endregion
904
971
  //#region src/trace/traceRecorder.d.ts
905
972
  interface TraceClock {
906
973
  now?: () => string;
@@ -1103,4 +1170,4 @@ declare class WebSkillRuntime {
1103
1170
  resumeRun(runId: string): Promise<RunResult>;
1104
1171
  }
1105
1172
  //#endregion
1106
- export { RouteResult as $, SkillReader as $t, LlmClient as A, resolveToolName as At, MockLlmHandler as B, SKILLS_LOCKFILE as Bt, InteractionPolicy as C, buildRenderResult as Ct, LifecycleHook as D, mergeCatalogEntries as Dt, LifecycleEvent as E, fromVercelStreamPart as Et, LlmToolCall as F, DiscoveryResult as Ft, OpenAiCompatibleClientConfig as G, SkillCatalogEntry as Gt, MockUiAnswer as H, SKILL_NAME_MAX_LENGTH as Ht, LlmToolSpec as I, FileStat as It, READ_SKILL_FILE_TOOL as J, SkillInstallSource as Jt, ProgressiveRouter as K, SkillDiscovery as Kt, MemoryArtifactStore as L, FileSystemProvider as Lt, LlmMessage as M, toLlmToolSpec as Mt, LlmResponse as N, toVercelToolSpecs as Nt, LifecycleHookContext as O, normalizeToolContent as Ot, LlmStreamEvent as P, CatalogRenderer as Pt, RenderResultRequest as Q, SkillMetadata as Qt, MemoryStore as R, JsonSchema as Rt, InMemoryStore as S, bridgeError as St, InteractionResponse as T, fromVercelResult as Tt, MockUiBridge as U, SKILL_NAME_PATTERN as Ut, MockLlmQueueItem as V, SKILL_MANIFEST_FILE as Vt, OpenAiCompatibleClient as W, SkillCatalog as Wt, RUN_SNAPSHOT_SCHEMA_VERSION as X, SkillLocation as Xt, READ_SKILL_FILE_TOOL_NAME as Y, SkillIssue as Yt, RenderBlock as Z, SkillManifest as Zt, FsMemoryStore as _, resolveInsideRoot as _n, TraceRecorder as _t, AgentLoopConfig as a, WebSkillErrorCode as an, RuntimeRun as at, HookRunner as b, xmlRenderer as bn, WebSkillRuntime as bt, ArtifactStore as c, checkSkillRules as cn, ScriptExecutionContext as ct, BridgeResponse as d, isValidSkillName as dn, ToolDefinition as dt, SkillSource as en, RunResult as et, EventBus as f, jsonRenderer as fn, ToolResolution as ft, FsArtifactStore as g, renderCatalogJson as gn, TraceEventType as gt, FormField as h, renderAvailableSkillsXml as hn, TraceEvent as ht, AgentLoop as i, WebSkillError as in, RuntimePhase as it, LlmCompleteInput as j, schemaToForm as jt, LifecycleListener as k, parseBridgeRequest as kt, BridgeCapabilities as l, computeDigest as ln, ScriptExecutor as lt, ExternalToolSource as m, parseSkillMarkdown as mn, TraceClock as mt, ASK_USER_TOOL as n, ValidationReport as nn, RunSnapshotStore as nt, AgentLoopDeps as o, buildCatalog as on, RuntimeSession as ot, ExternalSkillProvider as p, normalizePath as pn, ToolResult as pt, READ_SKILL_FILE_INPUT_SCHEMA as q, SkillDocument as qt, ASK_USER_TOOL_NAME as r, VerifyResult as rn, RunTerminationReason as rt, Artifact as s, buildManifest as sn, SchemaInferer as st, ASK_USER_INPUT_SCHEMA as t, SkillsLockfile as tn, RunSnapshot as tt, BridgeRequest as u, escapeXml as un, SkillRouter as ut, FsRunSnapshotStore as v, validateSkills as vn, UiBridge as vt, InteractionRequest as w, createScriptContext as wt, HookRunnerOptions as x, WebSkillRuntimeDeps as xt, FullDisclosureRouter as y, verifyManifest as yn, VercelToolSpec as yt, MockLlmClient as z, MemoryFS as zt };
1173
+ export { READ_SKILL_FILE_INPUT_SCHEMA as $, SkillCatalogEntry as $t, InteractionResponse as A, createScriptContext as At, LlmToolCall as B, toLlmToolSpec as Bt, FsRunSnapshotStore as C, renderAvailableSkillsXml as Cn, TraceRecorder as Ct, InMemoryStore as D, verifyManifest as Dn, WebSkillRuntimeDeps as Dt, HookRunnerOptions as E, validateSkills as En, WebSkillRuntime as Et, LlmClient as F, networkUrlHost as Ft, MockLlmHandler as G, FileSystemProvider as Gt, MemoryArtifactStore as H, CatalogRenderer as Ht, LlmCompleteInput as I, normalizeToolContent as It, MockUiBridge as J, SKILLS_LOCKFILE as Jt, MockLlmQueueItem as K, JsonSchema as Kt, LlmMessage as L, parseBridgeRequest as Lt, LifecycleHook as M, fromVercelStreamPart as Mt, LifecycleHookContext as N, isNetworkAllowed as Nt, InteractionPolicy as O, xmlRenderer as On, bridgeError as Ot, LifecycleListener as P, mergeCatalogEntries as Pt, ProgressiveRouter as Q, SkillCatalog as Qt, LlmResponse as R, resolveToolName as Rt, FsMemoryStore as S, parseSkillMarkdown as Sn, TraceEventType as St, HookRunner as T, resolveInsideRoot as Tn, VercelToolSpec as Tt, MemoryStore as U, DiscoveryResult as Ut, LlmToolSpec as V, toVercelToolSpecs as Vt, MockLlmClient as W, FileStat as Wt, OpenAiCompatibleClient as X, SKILL_NAME_MAX_LENGTH as Xt, NetworkPolicy as Y, SKILL_MANIFEST_FILE as Yt, OpenAiCompatibleClientConfig as Z, SKILL_NAME_PATTERN as Zt, EventBus as _, computeDigest as _n, ToolDefinition as _t, AgentLoopConfig as a, SkillManifest as an, RouteResult as at, FormField as b, jsonRenderer as bn, TraceClock as bt, ApprovalScope as c, SkillSource as cn, RunSnapshotStore as ct, BridgeCapabilities as d, VerifyResult as dn, RuntimeRun as dt, SkillDiscovery as en, READ_SKILL_FILE_TOOL as et, BridgeCapability as f, WebSkillError as fn, RuntimeSession as ft, CapabilityMode as g, checkSkillRules as gn, SkillRouter as gt, CapabilityApproval as h, buildManifest as hn, ScriptExecutor as ht, AgentLoop as i, SkillLocation as in, RenderResultRequest as it, LifecycleEvent as j, fromVercelResult as jt, InteractionRequest as k, buildRenderResult as kt, Artifact as l, SkillsLockfile as ln, RunTerminationReason as lt, BridgeResponse as m, buildCatalog as mn, ScriptExecutionContext as mt, ASK_USER_TOOL as n, SkillInstallSource as nn, RUN_SNAPSHOT_SCHEMA_VERSION as nt, AgentLoopDeps as o, SkillMetadata as on, RunResult as ot, BridgeRequest as p, WebSkillErrorCode as pn, SchemaInferer as pt, MockUiAnswer as q, MemoryFS as qt, ASK_USER_TOOL_NAME as r, SkillIssue as rn, RenderBlock as rt, ApprovalDecision as s, SkillReader as sn, RunSnapshot as st, ASK_USER_INPUT_SCHEMA as t, SkillDocument as tn, READ_SKILL_FILE_TOOL_NAME as tt, ArtifactStore as u, ValidationReport as un, RuntimePhase as ut, ExternalSkillProvider as v, escapeXml as vn, ToolResolution as vt, FullDisclosureRouter as w, renderCatalogJson as wn, UiBridge as wt, FsArtifactStore as x, normalizePath as xn, TraceEvent as xt, ExternalToolSource as y, isValidSkillName as yn, ToolResult as yt, LlmStreamEvent as z, schemaToForm as zt };
@@ -1,4 +1,4 @@
1
- import { It as FileStat, Jt as SkillInstallSource, Lt as FileSystemProvider, Q as RenderResultRequest, Rt as JsonSchema, T as InteractionResponse, Zt as SkillManifest, _ as FsMemoryStore, ct as ScriptExecutionContext, dt as ToolDefinition, g as FsArtifactStore, l as BridgeCapabilities, lt as ScriptExecutor, pt as ToolResult, rn as VerifyResult, st as SchemaInferer, tn as SkillsLockfile, vt as UiBridge, w as InteractionRequest } from "./index-CqDIreSE.js";
1
+ import { A as InteractionResponse, Gt as FileSystemProvider, Kt as JsonSchema, S as FsMemoryStore, Wt as FileStat, Y as NetworkPolicy, _t as ToolDefinition, an as SkillManifest, c as ApprovalScope, d as BridgeCapabilities, dn as VerifyResult, ht as ScriptExecutor, it as RenderResultRequest, k as InteractionRequest, ln as SkillsLockfile, mt as ScriptExecutionContext, nn as SkillInstallSource, pt as SchemaInferer, wt as UiBridge, x as FsArtifactStore, yt as ToolResult } from "./index-BQDc-U1x.js";
2
2
  import { Readable, Writable } from "node:stream";
3
3
  //#region ../node/dist/index.d.ts
4
4
  //#region src/fs/nodeFs.d.ts
@@ -47,6 +47,12 @@ interface SandboxOptions {
47
47
  /** env 白名单(仅这些变量传入 Worker;默认空) */
48
48
  envWhitelist?: string[];
49
49
  capabilities?: BridgeCapabilities;
50
+ /** 网络策略:默认 'deny-all'(白名单见 runtime/sandbox/networkPolicy) */
51
+ networkPolicy?: NetworkPolicy;
52
+ /** require-approval 模式的授权询问出口(缺失时 require-approval 一律拒绝) */
53
+ uiBridge?: UiBridge;
54
+ /** 授权粒度:默认 'once-per-run' */
55
+ approvalScope?: ApprovalScope;
50
56
  }
51
57
  /**
52
58
  * D1:worker_threads 沙箱脚本执行器。
@@ -105,7 +111,8 @@ declare class FileMemoryStore extends FsMemoryStore {
105
111
  //#region src/ui/cliUiBridge.d.ts
106
112
  /**
107
113
  * 命令行 UiBridge:ask→问答,confirm→y/n(带默认值),
108
- * form→逐字段提示(显示默认值与必填标记),select→编号列表。
114
+ * form→逐字段提示(显示默认值与必填标记),select→编号列表,
115
+ * authorize→授权询问(默认拒绝,仅显式 y/yes 批准)。
109
116
  * 输入/输出流可注入(测试用 PassThrough)。
110
117
  */
111
118
  declare class CliUiBridge implements UiBridge {
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { $ as RouteResult, $t as SkillReader, A as LlmClient, At as resolveToolName, B as MockLlmHandler, Bt as SKILLS_LOCKFILE, C as InteractionPolicy, Ct as buildRenderResult, D as LifecycleHook, Dt as mergeCatalogEntries, E as LifecycleEvent, Et as fromVercelStreamPart, F as LlmToolCall, Ft as DiscoveryResult, G as OpenAiCompatibleClientConfig, Gt as SkillCatalogEntry, H as MockUiAnswer, Ht as SKILL_NAME_MAX_LENGTH, I as LlmToolSpec, It as FileStat, J as READ_SKILL_FILE_TOOL, Jt as SkillInstallSource, K as ProgressiveRouter, Kt as SkillDiscovery, L as MemoryArtifactStore, Lt as FileSystemProvider, M as LlmMessage, Mt as toLlmToolSpec, N as LlmResponse, Nt as toVercelToolSpecs, O as LifecycleHookContext, Ot as normalizeToolContent, P as LlmStreamEvent, Pt as CatalogRenderer, Q as RenderResultRequest, Qt as SkillMetadata, R as MemoryStore, Rt as JsonSchema, S as InMemoryStore, St as bridgeError, T as InteractionResponse, Tt as fromVercelResult, U as MockUiBridge, Ut as SKILL_NAME_PATTERN, V as MockLlmQueueItem, Vt as SKILL_MANIFEST_FILE, W as OpenAiCompatibleClient, Wt as SkillCatalog, X as RUN_SNAPSHOT_SCHEMA_VERSION, Xt as SkillLocation, Y as READ_SKILL_FILE_TOOL_NAME, Yt as SkillIssue, Z as RenderBlock, Zt as SkillManifest, _ as FsMemoryStore, _n as resolveInsideRoot, _t as TraceRecorder, a as AgentLoopConfig, an as WebSkillErrorCode, at as RuntimeRun, b as HookRunner, bn as xmlRenderer, bt as WebSkillRuntime, c as ArtifactStore, cn as checkSkillRules, ct as ScriptExecutionContext, d as BridgeResponse, dn as isValidSkillName, dt as ToolDefinition, en as SkillSource, et as RunResult, f as EventBus, fn as jsonRenderer, ft as ToolResolution, g as FsArtifactStore, gn as renderCatalogJson, gt as TraceEventType, h as FormField, hn as renderAvailableSkillsXml, ht as TraceEvent, i as AgentLoop, in as WebSkillError, it as RuntimePhase, j as LlmCompleteInput, jt as schemaToForm, k as LifecycleListener, kt as parseBridgeRequest, l as BridgeCapabilities, ln as computeDigest, lt as ScriptExecutor, m as ExternalToolSource, mn as parseSkillMarkdown, mt as TraceClock, n as ASK_USER_TOOL, nn as ValidationReport, nt as RunSnapshotStore, o as AgentLoopDeps, on as buildCatalog, ot as RuntimeSession, p as ExternalSkillProvider, pn as normalizePath, pt as ToolResult, q as READ_SKILL_FILE_INPUT_SCHEMA, qt as SkillDocument, r as ASK_USER_TOOL_NAME, rn as VerifyResult, rt as RunTerminationReason, s as Artifact, sn as buildManifest, st as SchemaInferer, t as ASK_USER_INPUT_SCHEMA, tn as SkillsLockfile, tt as RunSnapshot, u as BridgeRequest, un as escapeXml, ut as SkillRouter, v as FsRunSnapshotStore, vn as validateSkills, vt as UiBridge, w as InteractionRequest, wt as createScriptContext, x as HookRunnerOptions, xt as WebSkillRuntimeDeps, y as FullDisclosureRouter, yn as verifyManifest, yt as VercelToolSpec, z as MockLlmClient, zt as MemoryFS } from "./index-CqDIreSE.js";
2
- export { ASK_USER_INPUT_SCHEMA, ASK_USER_TOOL, ASK_USER_TOOL_NAME, AgentLoop, type AgentLoopConfig, type AgentLoopDeps, type Artifact, type ArtifactStore, type BridgeCapabilities, type BridgeRequest, type BridgeResponse, type CatalogRenderer, type DiscoveryResult, EventBus, type ExternalSkillProvider, type ExternalToolSource, type FileStat, type FileSystemProvider, type FormField, FsArtifactStore, FsMemoryStore, FsRunSnapshotStore, FullDisclosureRouter, HookRunner, type HookRunnerOptions, InMemoryStore, 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, MemoryArtifactStore, MemoryFS, type MemoryStore, MockLlmClient, type MockLlmHandler, type MockLlmQueueItem, type MockUiAnswer, MockUiBridge, 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, SKILLS_LOCKFILE, SKILL_MANIFEST_FILE, SKILL_NAME_MAX_LENGTH, SKILL_NAME_PATTERN, type SchemaInferer, type ScriptExecutionContext, type ScriptExecutor, type SkillCatalog, type SkillCatalogEntry, SkillDiscovery, type SkillDocument, type SkillInstallSource, type SkillIssue, type SkillLocation, type SkillManifest, type SkillMetadata, SkillReader, type SkillRouter, type SkillSource, type SkillsLockfile, type ToolDefinition, type ToolResolution, type ToolResult, type TraceClock, type TraceEvent, type TraceEventType, TraceRecorder, type UiBridge, type ValidationReport, type VercelToolSpec, type VerifyResult, WebSkillError, type WebSkillErrorCode, WebSkillRuntime, type WebSkillRuntimeDeps, bridgeError, buildCatalog, buildManifest, buildRenderResult, checkSkillRules, computeDigest, createScriptContext, escapeXml, fromVercelResult, fromVercelStreamPart, isValidSkillName, jsonRenderer, mergeCatalogEntries, normalizePath, normalizeToolContent, parseBridgeRequest, parseSkillMarkdown, renderAvailableSkillsXml, renderCatalogJson, resolveInsideRoot, resolveToolName, schemaToForm, toLlmToolSpec, toVercelToolSpecs, validateSkills, verifyManifest, xmlRenderer };
1
+ import { $ as READ_SKILL_FILE_INPUT_SCHEMA, $t as SkillCatalogEntry, A as InteractionResponse, At as createScriptContext, B as LlmToolCall, Bt as toLlmToolSpec, C as FsRunSnapshotStore, Cn as renderAvailableSkillsXml, Ct as TraceRecorder, D as InMemoryStore, Dn as verifyManifest, Dt as WebSkillRuntimeDeps, E as HookRunnerOptions, En as validateSkills, Et as WebSkillRuntime, F as LlmClient, Ft as networkUrlHost, G as MockLlmHandler, Gt as FileSystemProvider, H as MemoryArtifactStore, Ht as CatalogRenderer, I as LlmCompleteInput, It as normalizeToolContent, J as MockUiBridge, Jt as SKILLS_LOCKFILE, K as MockLlmQueueItem, Kt as JsonSchema, L as LlmMessage, Lt as parseBridgeRequest, M as LifecycleHook, Mt as fromVercelStreamPart, N as LifecycleHookContext, Nt as isNetworkAllowed, O as InteractionPolicy, On as xmlRenderer, Ot as bridgeError, P as LifecycleListener, Pt as mergeCatalogEntries, Q as ProgressiveRouter, Qt as SkillCatalog, R as LlmResponse, Rt as resolveToolName, S as FsMemoryStore, Sn as parseSkillMarkdown, St as TraceEventType, T as HookRunner, Tn as resolveInsideRoot, Tt as VercelToolSpec, U as MemoryStore, Ut as DiscoveryResult, V as LlmToolSpec, Vt as toVercelToolSpecs, W as MockLlmClient, Wt as FileStat, X as OpenAiCompatibleClient, Xt as SKILL_NAME_MAX_LENGTH, Y as NetworkPolicy, Yt as SKILL_MANIFEST_FILE, Z as OpenAiCompatibleClientConfig, Zt as SKILL_NAME_PATTERN, _ as EventBus, _n as computeDigest, _t as ToolDefinition, a as AgentLoopConfig, an as SkillManifest, at as RouteResult, b as FormField, bn as jsonRenderer, bt as TraceClock, c as ApprovalScope, cn as SkillSource, ct as RunSnapshotStore, d as BridgeCapabilities, dn as VerifyResult, dt as RuntimeRun, en as SkillDiscovery, et as READ_SKILL_FILE_TOOL, f as BridgeCapability, fn as WebSkillError, ft as RuntimeSession, g as CapabilityMode, gn as checkSkillRules, gt as SkillRouter, h as CapabilityApproval, hn as buildManifest, ht as ScriptExecutor, i as AgentLoop, in as SkillLocation, it as RenderResultRequest, j as LifecycleEvent, jt as fromVercelResult, k as InteractionRequest, kt as buildRenderResult, l as Artifact, ln as SkillsLockfile, lt as RunTerminationReason, m as BridgeResponse, mn as buildCatalog, mt as ScriptExecutionContext, n as ASK_USER_TOOL, nn as SkillInstallSource, nt as RUN_SNAPSHOT_SCHEMA_VERSION, o as AgentLoopDeps, on as SkillMetadata, ot as RunResult, p as BridgeRequest, pn as WebSkillErrorCode, pt as SchemaInferer, q as MockUiAnswer, qt as MemoryFS, r as ASK_USER_TOOL_NAME, rn as SkillIssue, rt as RenderBlock, s as ApprovalDecision, sn as SkillReader, st as RunSnapshot, t as ASK_USER_INPUT_SCHEMA, tn as SkillDocument, tt as READ_SKILL_FILE_TOOL_NAME, u as ArtifactStore, un as ValidationReport, ut as RuntimePhase, v as ExternalSkillProvider, vn as escapeXml, vt as ToolResolution, w as FullDisclosureRouter, wn as renderCatalogJson, wt as UiBridge, x as FsArtifactStore, xn as normalizePath, xt as TraceEvent, y as ExternalToolSource, yn as isValidSkillName, yt as ToolResult, z as LlmStreamEvent, zt as schemaToForm } from "./index-BQDc-U1x.js";
2
+ export { ASK_USER_INPUT_SCHEMA, ASK_USER_TOOL, ASK_USER_TOOL_NAME, AgentLoop, type AgentLoopConfig, type AgentLoopDeps, type ApprovalDecision, type ApprovalScope, type Artifact, type ArtifactStore, type BridgeCapabilities, type BridgeCapability, type BridgeRequest, type BridgeResponse, CapabilityApproval, type CapabilityMode, type CatalogRenderer, type DiscoveryResult, EventBus, type ExternalSkillProvider, type ExternalToolSource, type FileStat, type FileSystemProvider, type FormField, FsArtifactStore, FsMemoryStore, FsRunSnapshotStore, FullDisclosureRouter, HookRunner, type HookRunnerOptions, InMemoryStore, 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, MemoryArtifactStore, MemoryFS, type MemoryStore, MockLlmClient, type MockLlmHandler, type MockLlmQueueItem, type MockUiAnswer, MockUiBridge, 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, SKILLS_LOCKFILE, SKILL_MANIFEST_FILE, SKILL_NAME_MAX_LENGTH, SKILL_NAME_PATTERN, type SchemaInferer, type ScriptExecutionContext, type ScriptExecutor, type SkillCatalog, type SkillCatalogEntry, SkillDiscovery, type SkillDocument, type SkillInstallSource, type SkillIssue, type SkillLocation, type SkillManifest, type SkillMetadata, SkillReader, type SkillRouter, type SkillSource, type SkillsLockfile, type ToolDefinition, type ToolResolution, type ToolResult, type TraceClock, type TraceEvent, type TraceEventType, TraceRecorder, type UiBridge, type ValidationReport, type VercelToolSpec, type VerifyResult, WebSkillError, type WebSkillErrorCode, WebSkillRuntime, type WebSkillRuntimeDeps, bridgeError, buildCatalog, buildManifest, buildRenderResult, checkSkillRules, computeDigest, createScriptContext, escapeXml, fromVercelResult, fromVercelStreamPart, isNetworkAllowed, isValidSkillName, jsonRenderer, mergeCatalogEntries, networkUrlHost, normalizePath, normalizeToolContent, parseBridgeRequest, parseSkillMarkdown, renderAvailableSkillsXml, renderCatalogJson, resolveInsideRoot, resolveToolName, schemaToForm, toLlmToolSpec, toVercelToolSpecs, validateSkills, verifyManifest, xmlRenderer };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import { $ as renderCatalogJson, A as parseBridgeRequest, B as SkillDiscovery, C as bridgeError, D as fromVercelStreamPart, E as fromVercelResult, F as MemoryFS, G as checkSkillRules, H as WebSkillError, I as SKILLS_LOCKFILE, J as isValidSkillName, K as computeDigest, L as SKILL_MANIFEST_FILE, M as schemaToForm, N as toLlmToolSpec, O as mergeCatalogEntries, P as toVercelToolSpecs, Q as renderAvailableSkillsXml, R as SKILL_NAME_MAX_LENGTH, S as WebSkillRuntime, T as createScriptContext, U as buildCatalog, V as SkillReader, W as buildManifest, X as normalizePath, Y as jsonRenderer, Z as parseSkillMarkdown, _ as READ_SKILL_FILE_INPUT_SCHEMA, a as EventBus, b as RUN_SNAPSHOT_SCHEMA_VERSION, c as FsRunSnapshotStore, d as InMemoryStore, et as resolveInsideRoot, f as MemoryArtifactStore, g as ProgressiveRouter, h as OpenAiCompatibleClient, i as AgentLoop, j as resolveToolName, k as normalizeToolContent, l as FullDisclosureRouter, m as MockUiBridge, n as ASK_USER_TOOL, nt as verifyManifest, o as FsArtifactStore, p as MockLlmClient, q as escapeXml, r as ASK_USER_TOOL_NAME, rt as xmlRenderer, s as FsMemoryStore, t as ASK_USER_INPUT_SCHEMA, tt as validateSkills, u as HookRunner, v as READ_SKILL_FILE_TOOL, w as buildRenderResult, x as TraceRecorder, y as READ_SKILL_FILE_TOOL_NAME, z as SKILL_NAME_PATTERN } from "./dist-COsE72Ct.js";
1
+ import { $ as normalizePath, A as mergeCatalogEntries, B as SKILL_MANIFEST_FILE, C as WebSkillRuntime, D as fromVercelResult, E as createScriptContext, F as schemaToForm, G as WebSkillError, H as SKILL_NAME_PATTERN, I as toLlmToolSpec, J as checkSkillRules, K as buildCatalog, L as toVercelToolSpecs, M as normalizeToolContent, N as parseBridgeRequest, O as fromVercelStreamPart, P as resolveToolName, Q as jsonRenderer, R as MemoryFS, S as TraceRecorder, T as buildRenderResult, U as SkillDiscovery, V as SKILL_NAME_MAX_LENGTH, W as SkillReader, X as escapeXml, Y as computeDigest, Z as isValidSkillName, _ as ProgressiveRouter, a as CapabilityApproval, at as verifyManifest, b as READ_SKILL_FILE_TOOL_NAME, c as FsMemoryStore, d as HookRunner, et as parseSkillMarkdown, f as InMemoryStore, g as OpenAiCompatibleClient, h as MockUiBridge, i as AgentLoop, it as validateSkills, j as networkUrlHost, k as isNetworkAllowed, l as FsRunSnapshotStore, m as MockLlmClient, n as ASK_USER_TOOL, nt as renderCatalogJson, o as EventBus, ot as xmlRenderer, p as MemoryArtifactStore, q as buildManifest, r as ASK_USER_TOOL_NAME, rt as resolveInsideRoot, s as FsArtifactStore, t as ASK_USER_INPUT_SCHEMA, tt as renderAvailableSkillsXml, u as FullDisclosureRouter, v as READ_SKILL_FILE_INPUT_SCHEMA, w as bridgeError, x as RUN_SNAPSHOT_SCHEMA_VERSION, y as READ_SKILL_FILE_TOOL, z as SKILLS_LOCKFILE } from "./dist-D405AlPD.js";
2
2
 
3
- export { ASK_USER_INPUT_SCHEMA, ASK_USER_TOOL, ASK_USER_TOOL_NAME, AgentLoop, EventBus, FsArtifactStore, FsMemoryStore, FsRunSnapshotStore, FullDisclosureRouter, HookRunner, InMemoryStore, MemoryArtifactStore, MemoryFS, MockLlmClient, MockUiBridge, 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, SkillDiscovery, SkillReader, TraceRecorder, WebSkillError, WebSkillRuntime, bridgeError, buildCatalog, buildManifest, buildRenderResult, checkSkillRules, computeDigest, createScriptContext, escapeXml, fromVercelResult, fromVercelStreamPart, isValidSkillName, jsonRenderer, mergeCatalogEntries, normalizePath, normalizeToolContent, parseBridgeRequest, parseSkillMarkdown, renderAvailableSkillsXml, renderCatalogJson, resolveInsideRoot, resolveToolName, schemaToForm, toLlmToolSpec, toVercelToolSpecs, validateSkills, verifyManifest, xmlRenderer };
3
+ export { ASK_USER_INPUT_SCHEMA, ASK_USER_TOOL, ASK_USER_TOOL_NAME, AgentLoop, CapabilityApproval, EventBus, FsArtifactStore, FsMemoryStore, FsRunSnapshotStore, FullDisclosureRouter, HookRunner, InMemoryStore, MemoryArtifactStore, MemoryFS, MockLlmClient, MockUiBridge, 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, SkillDiscovery, SkillReader, TraceRecorder, WebSkillError, WebSkillRuntime, bridgeError, buildCatalog, buildManifest, buildRenderResult, checkSkillRules, computeDigest, createScriptContext, escapeXml, fromVercelResult, fromVercelStreamPart, isNetworkAllowed, isValidSkillName, jsonRenderer, mergeCatalogEntries, networkUrlHost, normalizePath, normalizeToolContent, parseBridgeRequest, parseSkillMarkdown, renderAvailableSkillsXml, renderCatalogJson, resolveInsideRoot, resolveToolName, schemaToForm, toLlmToolSpec, toVercelToolSpecs, validateSkills, verifyManifest, xmlRenderer };
package/dist/mcp.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Dt as mergeCatalogEntries, Gt as SkillCatalogEntry, I as LlmToolSpec, Rt as JsonSchema, m as ExternalToolSource, p as ExternalSkillProvider, pt as ToolResult, qt as SkillDocument } from "./index-CqDIreSE.js";
1
+ import { $t as SkillCatalogEntry, Kt as JsonSchema, Pt as mergeCatalogEntries, V as LlmToolSpec, tn as SkillDocument, v as ExternalSkillProvider, y as ExternalToolSource, yt as ToolResult } from "./index-BQDc-U1x.js";
2
2
  import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
3
3
  import { JSONRPCMessage } from "@modelcontextprotocol/sdk/types.js";
4
4
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
package/dist/mcp.js CHANGED
@@ -1,4 +1,4 @@
1
- import { H as WebSkillError, O as mergeCatalogEntries, k as normalizeToolContent } from "./dist-COsE72Ct.js";
1
+ import { A as mergeCatalogEntries, G as WebSkillError, M as normalizeToolContent } from "./dist-D405AlPD.js";
2
2
  import { fromJSONSchema } from "zod";
3
3
 
4
4
  //#region ../mcp/dist/index.js
package/dist/node.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { Bt as SKILLS_LOCKFILE, Jt as SkillInstallSource, Vt as SKILL_MANIFEST_FILE, Zt as SkillManifest, rn as VerifyResult, tn as SkillsLockfile, wt as createScriptContext } from "./index-CqDIreSE.js";
2
- import { a as LlmEnvConfig, c as OxcSchemaInferer, d as SkillManager, f as loadLlmConfigFromEnv, i as LlmCapabilities, l as SandboxOptions, m as readArchiveManifest, n as FileArtifactStore, o as NodeFS, p as probeLlmCapabilities, r as FileMemoryStore, s as NodeScriptExecutor, t as CliUiBridge, u as SandboxedScriptExecutor } from "./index-BsbfEiaC.js";
1
+ import { At as createScriptContext, Jt as SKILLS_LOCKFILE, Yt as SKILL_MANIFEST_FILE, an as SkillManifest, dn as VerifyResult, ln as SkillsLockfile, nn as SkillInstallSource } from "./index-BQDc-U1x.js";
2
+ import { a as LlmEnvConfig, c as OxcSchemaInferer, d as SkillManager, f as loadLlmConfigFromEnv, i as LlmCapabilities, l as SandboxOptions, m as readArchiveManifest, n as FileArtifactStore, o as NodeFS, p as probeLlmCapabilities, r as FileMemoryStore, s as NodeScriptExecutor, t as CliUiBridge, u as SandboxedScriptExecutor } from "./index-aEple804.js";
3
3
  export { CliUiBridge, FileArtifactStore, FileMemoryStore, type LlmCapabilities, type LlmEnvConfig, NodeFS, NodeScriptExecutor, OxcSchemaInferer, SKILLS_LOCKFILE, SKILL_MANIFEST_FILE, type SandboxOptions, SandboxedScriptExecutor, SkillManager, type SkillManifest, type SkillInstallSource as SkillSource, type SkillsLockfile, type VerifyResult, createScriptContext, loadLlmConfigFromEnv, probeLlmCapabilities, readArchiveManifest };
package/dist/node.js CHANGED
@@ -1,4 +1,4 @@
1
- import { I as SKILLS_LOCKFILE, L as SKILL_MANIFEST_FILE, T as createScriptContext } from "./dist-COsE72Ct.js";
2
- import { a as NodeScriptExecutor, c as SkillManager, d as readArchiveManifest, i as NodeFS, l as loadLlmConfigFromEnv, n as FileArtifactStore, o as OxcSchemaInferer, r as FileMemoryStore, s as SandboxedScriptExecutor, t as CliUiBridge, u as probeLlmCapabilities } from "./dist-Bvhbxrrt.js";
1
+ import { B as SKILL_MANIFEST_FILE, E as createScriptContext, z as SKILLS_LOCKFILE } from "./dist-D405AlPD.js";
2
+ import { a as NodeScriptExecutor, c as SkillManager, d as readArchiveManifest, i as NodeFS, l as loadLlmConfigFromEnv, n as FileArtifactStore, o as OxcSchemaInferer, r as FileMemoryStore, s as SandboxedScriptExecutor, t as CliUiBridge, u as probeLlmCapabilities } from "./dist-Ixnb-hNR.js";
3
3
 
4
4
  export { CliUiBridge, FileArtifactStore, FileMemoryStore, NodeFS, NodeScriptExecutor, OxcSchemaInferer, SKILLS_LOCKFILE, SKILL_MANIFEST_FILE, SandboxedScriptExecutor, SkillManager, createScriptContext, loadLlmConfigFromEnv, probeLlmCapabilities, readArchiveManifest };
@@ -1,4 +1,4 @@
1
- import { Q as RenderResultRequest, T as InteractionResponse, vt as UiBridge, w as InteractionRequest } from "./index-CqDIreSE.js";
1
+ import { A as InteractionResponse, it as RenderResultRequest, k as InteractionRequest, wt as UiBridge } from "./index-BQDc-U1x.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 { _ as interactionToFormModel, f as collectValues, x as shapeInteractionValue, y as renderMiniMarkdown } from "./dist-RcqvzAGF.js";
1
+ import { _ as interactionToFormModel, f as collectValues, x as shapeInteractionValue, y as renderMiniMarkdown } from "./dist-BM-VcQ90.js";
2
2
  import { useLayoutEffect, useRef, useState, useSyncExternalStore } from "react";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
 
@@ -145,7 +145,7 @@ function InteractionForm({ bridge }) {
145
145
  className: "webskill-form__title",
146
146
  children: model.title
147
147
  }) : null,
148
- model.message && model.kind === "form" ? /* @__PURE__ */ jsx("p", {
148
+ model.message && (model.kind === "form" || model.kind === "authorize") ? /* @__PURE__ */ jsx("p", {
149
149
  className: "webskill-form__message",
150
150
  children: model.message
151
151
  }) : null,
package/dist/ui-vue.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Q as RenderResultRequest, T as InteractionResponse, vt as UiBridge, w as InteractionRequest } from "./index-CqDIreSE.js";
1
+ import { A as InteractionResponse, it as RenderResultRequest, k as InteractionRequest, wt as UiBridge } from "./index-BQDc-U1x.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 { _ as interactionToFormModel, f as collectValues, x as shapeInteractionValue, y as renderMiniMarkdown } from "./dist-RcqvzAGF.js";
1
+ import { _ as interactionToFormModel, f as collectValues, x as shapeInteractionValue, y as renderMiniMarkdown } from "./dist-BM-VcQ90.js";
2
2
  import { defineComponent, h, reactive, ref } from "vue";
3
3
 
4
4
  //#region ../ui-vue/dist/index.js
@@ -112,7 +112,7 @@ const InteractionForm = defineComponent({
112
112
  }
113
113
  }, [
114
114
  model.title ? h("div", { class: "webskill-form__title" }, model.title) : null,
115
- model.message && model.kind === "form" ? h("p", { class: "webskill-form__message" }, model.message) : null,
115
+ model.message && (model.kind === "form" || model.kind === "authorize") ? h("p", { class: "webskill-form__message" }, model.message) : null,
116
116
  ...model.controls.map((control) => h("div", { key: control.name }, [renderControl(control), invalid.value.includes(control.name) ? h("div", { class: "webskill-form__error" }, "This field is required") : null])),
117
117
  h("div", { class: "webskill-form__actions" }, [h("button", {
118
118
  type: "submit",
package/dist/ui.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { Ct as buildRenderResult, Q as RenderResultRequest, T as InteractionResponse, Z as RenderBlock, vt as UiBridge, w as InteractionRequest } from "./index-CqDIreSE.js";
1
+ import { A as InteractionResponse, it as RenderResultRequest, k as InteractionRequest, kt as buildRenderResult, rt as RenderBlock, wt as UiBridge } from "./index-BQDc-U1x.js";
2
2
  //#region ../ui/dist/index.d.ts
3
3
  //#region src/model/formModel.d.ts
4
4
  interface FormModel {
5
- kind: 'ask' | 'confirm' | 'form' | 'select';
5
+ kind: 'ask' | 'confirm' | 'form' | 'select' | 'authorize';
6
6
  title?: string;
7
7
  message?: string;
8
8
  controls: ControlModel[];
@@ -23,7 +23,7 @@ interface ControlModel {
23
23
  }
24
24
  /** 提交值按请求类型归形(WebFormBridge 与框架组件库共享单一来源) */
25
25
  declare function shapeInteractionValue(model: FormModel, values: Record<string, unknown>): unknown;
26
- /** 四类 InteractionRequest → 统一中间模型(框架无关) */
26
+ /** 五类 InteractionRequest → 统一中间模型(框架无关) */
27
27
  declare function interactionToFormModel(request: InteractionRequest): FormModel;
28
28
  //#endregion
29
29
  //#region src/model/collectValues.d.ts
package/dist/ui.js CHANGED
@@ -1,4 +1,4 @@
1
- import { w as buildRenderResult } from "./dist-COsE72Ct.js";
2
- import { C as toOpenUiLang, S as toA2uiMessages, _ as interactionToFormModel, a as LitRendererBridge, b as renderRenderResult, c as VERCEL_INTERACTION_TOOL_NAME, d as WebFormBridge, f as collectValues, g as fromVercelToolResult, h as fromOpenUiAction, i as A2UI_VERSION, l as VercelUiBridge, m as fromA2uiAction, n as A2UI_CANCEL_ACTION, o as OPENUI_CANCEL_ACTION, p as ensureStyles, r as A2UI_SUBMIT_ACTION, s as OPENUI_SUBMIT_ACTION, t as A2UI_BASIC_CATALOG_ID, u as WEBSKILL_STYLES_CSS, v as renderBlocks, w as toVercelToolInvocation, x as shapeInteractionValue, y as renderMiniMarkdown } from "./dist-RcqvzAGF.js";
1
+ import { T as buildRenderResult } from "./dist-D405AlPD.js";
2
+ import { C as toOpenUiLang, S as toA2uiMessages, _ as interactionToFormModel, a as LitRendererBridge, b as renderRenderResult, c as VERCEL_INTERACTION_TOOL_NAME, d as WebFormBridge, f as collectValues, g as fromVercelToolResult, h as fromOpenUiAction, i as A2UI_VERSION, l as VercelUiBridge, m as fromA2uiAction, n as A2UI_CANCEL_ACTION, o as OPENUI_CANCEL_ACTION, p as ensureStyles, r as A2UI_SUBMIT_ACTION, s as OPENUI_SUBMIT_ACTION, t as A2UI_BASIC_CATALOG_ID, u as WEBSKILL_STYLES_CSS, v as renderBlocks, w as toVercelToolInvocation, x as shapeInteractionValue, y as renderMiniMarkdown } from "./dist-BM-VcQ90.js";
3
3
 
4
4
  export { A2UI_BASIC_CATALOG_ID, A2UI_CANCEL_ACTION, A2UI_SUBMIT_ACTION, A2UI_VERSION, LitRendererBridge, OPENUI_CANCEL_ACTION, OPENUI_SUBMIT_ACTION, VERCEL_INTERACTION_TOOL_NAME, VercelUiBridge, WEBSKILL_STYLES_CSS, WebFormBridge, buildRenderResult, collectValues, ensureStyles, fromA2uiAction, fromOpenUiAction, fromVercelToolResult, interactionToFormModel, renderBlocks, renderMiniMarkdown, renderRenderResult, shapeInteractionValue, toA2uiMessages, toOpenUiLang, toVercelToolInvocation };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webskill/sdk",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "WebSkill — browser/Node agent skill runtime (skills, tools, MCP, governance, UI)",
5
5
  "license": "MIT",
6
6
  "type": "module",