@webskill/sdk 0.2.7 → 0.3.0

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.
Files changed (38) hide show
  1. package/README.md +42 -0
  2. package/dist/browser.d.ts +13 -4
  3. package/dist/browser.js +19 -10
  4. package/dist/{catalogComponents-C_V39rbF-B94i0fW7.js → catalogComponents-C_V39rbF-BOHveMWa.js} +254 -9090
  5. package/dist/client-BCM6Z3yq-qUQNkKrK.js +7787 -0
  6. package/dist/{dist-BQzncxXg.js → dist-8oQRa8Xz.js} +212 -13
  7. package/dist/{dist-CtBLBbEz.js → dist-ZKaM8j06.js} +2 -2
  8. package/dist/{dist-BdOW8N4V.js → dist-rorEJsNi.js} +596 -59
  9. package/dist/governance.d.ts +30 -197
  10. package/dist/governance.js +38 -199
  11. package/dist/{index-BpIK7tJM.d.ts → index-8d-oEDww.d.ts} +215 -2
  12. package/dist/{index-BNQNSDKg.d.ts → index-wiV5X8Rz.d.ts} +21 -4
  13. package/dist/index.d.ts +3 -3
  14. package/dist/index.js +3 -3
  15. package/dist/{jsonRenderRegistry-9GrWP_hE-CMkryt1H.js → jsonRenderRegistry-9GrWP_hE-U6Do3Kid.js} +2 -2
  16. package/dist/mcp.d.ts +5 -3
  17. package/dist/mcp.js +10 -5
  18. package/dist/node.d.ts +338 -4
  19. package/dist/node.js +2338 -4
  20. package/dist/{openUiLibrary-B8-Cvou9-Cu1QZqoT.js → openUiLibrary-B8-Cvou9-BbpNTXS3.js} +2 -2
  21. package/dist/sandboxWorkerEntry.js +12 -3
  22. package/dist/skillVersionStore-DOEI9ptb-BxbYL70B.d.ts +127 -0
  23. package/dist/stdio-CFMoANJJ-BxrTeXh7.js +31 -0
  24. package/dist/{testing-BUoXvm1u.js → testing-CsrG3XLz.js} +1 -1
  25. package/dist/testing.d.ts +1 -1
  26. package/dist/testing.js +1 -1
  27. package/dist/{types-7fnqDVrf-BnRQjVU3.d.ts → types-AmKCKJn_-VGabeXK4.d.ts} +140 -3
  28. package/dist/types-WovEf4ED-CZSDiiBU.js +6215 -0
  29. package/dist/ui-react.d.ts +2 -2
  30. package/dist/ui-react.js +6 -6
  31. package/dist/ui-vue.d.ts +1 -1
  32. package/dist/ui-vue.js +1 -1
  33. package/dist/ui.d.ts +3 -3
  34. package/dist/ui.js +2 -2
  35. package/dist/{webskillLitCatalog-CNaUpasU-CfSRvqCZ.js → webskillLitCatalog-CNaUpasU-BslMcxRZ.js} +1 -1
  36. package/package.json +4 -7
  37. package/dist/dist-CcMIUXeZ.js +0 -1896
  38. package/dist/index-BHL5FWGw.d.ts +0 -240
package/README.md CHANGED
@@ -49,6 +49,12 @@ npm install @webskill/sdk
49
49
  React/Vue integrations require their respective peer dependencies
50
50
  (`react` + `react-dom`, or `vue`), which are optional.
51
51
 
52
+ `zod` ships as a direct dependency: the `@webskill/sdk/ui` catalog references it
53
+ in its static import graph and in its public types, so declaring it optional
54
+ would misrepresent the artifact. Hosts do not need to install it themselves.
55
+ `tar`, `oxc-parser` and `@modelcontextprotocol/sdk` remain optional peers —
56
+ they are loaded lazily and only when the corresponding API is called.
57
+
52
58
  ## Requirements
53
59
 
54
60
  - Node.js >= 22.18 (native type stripping for `.ts` skill scripts)
@@ -214,6 +220,42 @@ import { MockLlmClient, MockUiBridge, InMemoryStore, MemoryArtifactStore } from
214
220
  const llm = new MockLlmClient([{ content: 'deterministic answer' }]);
215
221
  ```
216
222
 
223
+ ## `allowed-tools`
224
+
225
+ A skill may narrow the tool surface it needs by declaring `allowed-tools` in its
226
+ `SKILL.md` frontmatter. Three kinds of tools can be listed:
227
+
228
+ ```yaml
229
+ allowed-tools:
230
+ - render # a script of this skill (scripts/render.ts)
231
+ - endpoint:github/create_issue # one tool of an MCP endpoint
232
+ - endpoint:github/* # every tool of an MCP endpoint
233
+ - mcp#read_file # one page-provided (WebMCP) tool
234
+ ```
235
+
236
+ Matching rules:
237
+
238
+ - Only whole-entry matches and a trailing `/*` are supported. Wildcards in any
239
+ other position are not, and a bare `endpoint:github` is **not** a prefix
240
+ wildcard — it simply matches nothing.
241
+ - A bare identifier means a script of the declaring skill only. It never grants
242
+ access to another skill's script of the same name.
243
+
244
+ When several skills are active at the same time:
245
+
246
+ | Situation | Result |
247
+ | ---------------------------------------- | -------------------------------------------------------------------------------------------------------- |
248
+ | No active skill declares `allowed-tools` | Unrestricted |
249
+ | At least one active skill declares it | A tool is allowed if it matches any declaring skill's list, **or** if some active skill declares nothing |
250
+
251
+ Enforcement level differs per tool kind in 0.3.0:
252
+
253
+ - **Scripts** — enforced since 0.0.5: a script outside the list is not
254
+ registered, and calling it by name returns `TOOL_NOT_FOUND`.
255
+ - **MCP / WebMCP tools** — 0.3.0 only records a `run.warning` naming the tool
256
+ and the entry to add, and still allows the call. This becomes a rejection in
257
+ 0.4.0, so treat the warning as a build error in your own pipeline.
258
+
217
259
  ## Stability
218
260
 
219
261
  This package follows semver starting at 0.1.0. Public symbols carry JSDoc
package/dist/browser.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { K as SkillInstallSource, M as FileStat, N as FileSystemProvider, O as ArchiveLimits, Y as SkillManifest, _ as RenderResultRequest, a as InteractionPolicy, c as LlmClient, d as LlmResponse, et as SkillsLockfile, f as LlmStreamEvent, nt as VerifyResult, o as InteractionRequest, s as InteractionResponse, v as UiBridge } from "./types-7fnqDVrf-BnRQjVU3.js";
2
- import { Dt 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-BpIK7tJM.js";
1
+ import { $ as SkillInstallSource, N as FileStat, O as ArchiveLimits, P as FileSystemProvider, _ as RenderResultRequest, a as InteractionPolicy, c as LlmClient, d as LlmResponse, f as LlmStreamEvent, lt as SkillsLockfile, mt as VerifyResult, o as InteractionRequest, rt as SkillManifest, s as InteractionResponse, v as UiBridge } from "./types-AmKCKJn_-VGabeXK4.js";
2
+ import { Ct as WebSkillApi, Et as bridgeError, F as NetworkPolicy, Vt as parseBridgeRequest, _t as ToolResult, ct as ScriptExecutor, d as BridgeCapabilities, ht as ToolDefinition, m as BridgeResponse, p as BridgeRequest, st as ScriptExecutionContext, u as ApprovalScope, v as ExternalSkillProvider, y as ExternalToolSource } from "./index-8d-oEDww.js";
3
3
  //#region ../browser/dist/index.d.ts
4
4
  //#region src/fs/featureDetection.d.ts
5
5
  /** 检测当前环境是否可用 OPFS(navigator.storage.getDirectory) */
@@ -32,8 +32,9 @@ declare class OpfsProvider implements FileSystemProvider {
32
32
  /**
33
33
  * Worker 引导源码(字符串 → Blob URL → new Worker(url, {type:'module'}))。
34
34
  * 注意:内容为纯 JS,不能含反引号与 ${ 占位(外层用模板字符串内嵌);
35
- * isNetworkAllowed/networkUrlHost 经函数源码注入(匹配逻辑单一来源在
36
- * runtime/sandbox/networkPolicy.ts,此处禁止复制实现)。
35
+ * isNetworkAllowed/networkUrlHost 经 networkPolicyLibSource() 注入(匹配逻辑单一来源在
36
+ * runtime/sandbox/networkPolicy.ts,此处禁止复制实现)。该辅助把函数源码绑定到固定变量名,
37
+ * 消费方生产构建压缩改名后仍可调用(0.2.8 C4)。
37
38
  *
38
39
  * 协议(宿主 ↔ Worker):
39
40
  * - 宿主 → Worker:{type:'load', id, source, networkPolicy?} 请求加载脚本定义
@@ -296,6 +297,12 @@ type WorkerEvent = {
296
297
  type: 'text-delta';
297
298
  runId: string;
298
299
  delta: string;
300
+ } |
301
+ /** 不阻断 run 但宿主应当知晓的降级(如外部技能提供者报错导致技能缺失) */
302
+ {
303
+ type: 'host-warning';
304
+ runId: string;
305
+ message: string;
299
306
  };
300
307
  /** Worker 内全局作用域最小接口(postMessage + 消息监听) */
301
308
  interface WorkerScopeLike {
@@ -336,6 +343,8 @@ interface WorkerRuntimeClientDeps {
336
343
  uiBridge?: UiBridge;
337
344
  /** 单次请求超时(默认 120_000ms);超时返回结构化 error 响应(不 reject) */
338
345
  timeoutMs?: number;
346
+ /** 不阻断 run 的降级告警出口(默认 console.warn) */
347
+ onWarning?(runId: string, message: string): void;
339
348
  }
340
349
  /** 主线程客户端:init/run/cancel/status/dispose 的 Promise API + 交互转发 */
341
350
  declare class WorkerRuntimeClient {
package/dist/browser.js CHANGED
@@ -1,6 +1,6 @@
1
- import { C as messageOf, D as readResponseWithLimit, E as parseSkillPackManifest, M as unzipWithLimits, N as validateSkills, P as verifyManifest, T as parseSkillMarkdown, b as exportSkills, c as SkillDiscovery, d as assertRemoteUrlAllowed, h as buildManifest, i as SKILL_MANIFEST_FILE, j as resolveInsideRoot, m as buildCatalog, p as atomicWriteText, r as SKILLS_LOCKFILE, s as SKILL_PACK_FILE, u as WebSkillError, x as isValidSkillName } from "./dist-BQzncxXg.js";
2
- import { C as bridgeError, E as createWebSkillApi, F as normalizeToolContent, I as normalizeToolError, L as parseBridgeRequest, M as mergeCatalogEntries, N as networkUrlHost, c as FsArtifactStore, h as ProgressiveRouter, i as AgentLoop, j as isNetworkAllowed, l as FsMemoryStore, m as OpenAiCompatibleClient, o as CapabilityApproval, u as FsRunSnapshotStore, y as RUN_SNAPSHOT_SCHEMA_VERSION } from "./dist-BdOW8N4V.js";
3
- import { n as MockLlmClient } from "./testing-BUoXvm1u.js";
1
+ import { A as parseSkillMarkdown, B as unzipWithLimits, H as verifyManifest, L as resolveInsideRoot, M as readResponseWithLimit, O as messageOf, T as isValidSkillName, V as validateSkills, _ as atomicWriteText, f as SkillDiscovery, h as assertRemoteUrlAllowed, j as parseSkillPackManifest, m as WebSkillError, o as SKILLS_LOCKFILE, r as MANIFEST_EXCLUDED_FILES, s as SKILL_MANIFEST_FILE, u as SKILL_PACK_FILE, v as buildCatalog, w as exportSkills, y as buildManifest } from "./dist-8oQRa8Xz.js";
2
+ import { A as createWebSkillApi, B as normalizeToolContent, D as bridgeError, H as parseBridgeRequest, I as mergeCatalogEntries, L as networkPolicyLibSource, V as normalizeToolError, _ as ProgressiveRouter, c as FsArtifactStore, g as OpenAiCompatibleClient, i as AgentLoop, l as FsMemoryStore, o as CapabilityApproval, u as FsRunSnapshotStore, x as RUN_SNAPSHOT_SCHEMA_VERSION } from "./dist-rorEJsNi.js";
3
+ import { n as MockLlmClient } from "./testing-CsrG3XLz.js";
4
4
 
5
5
  //#region ../browser/dist/index.js
6
6
  /** 检测当前环境是否可用 OPFS(navigator.storage.getDirectory) */
@@ -157,8 +157,9 @@ var OpfsProvider = class {
157
157
  /**
158
158
  * Worker 引导源码(字符串 → Blob URL → new Worker(url, {type:'module'}))。
159
159
  * 注意:内容为纯 JS,不能含反引号与 ${ 占位(外层用模板字符串内嵌);
160
- * isNetworkAllowed/networkUrlHost 经函数源码注入(匹配逻辑单一来源在
161
- * runtime/sandbox/networkPolicy.ts,此处禁止复制实现)。
160
+ * isNetworkAllowed/networkUrlHost 经 networkPolicyLibSource() 注入(匹配逻辑单一来源在
161
+ * runtime/sandbox/networkPolicy.ts,此处禁止复制实现)。该辅助把函数源码绑定到固定变量名,
162
+ * 消费方生产构建压缩改名后仍可调用(0.2.8 C4)。
162
163
  *
163
164
  * 协议(宿主 ↔ Worker):
164
165
  * - 宿主 → Worker:{type:'load', id, source, networkPolicy?} 请求加载脚本定义
@@ -180,9 +181,7 @@ var pending = new Map();
180
181
  var bridgeSeq = 0;
181
182
  var networkPolicy = 'deny-all';
182
183
 
183
- ${isNetworkAllowed.toString()}
184
-
185
- ${networkUrlHost.toString()}
184
+ ${networkPolicyLibSource()}
186
185
 
187
186
  function resolveUrl(raw) {
188
187
  try {
@@ -703,10 +702,9 @@ var BrowserSkillManager = class {
703
702
  }
704
703
  }
705
704
  async #createManifest(skillRoot, input) {
706
- const excluded = /* @__PURE__ */ new Set([SKILL_MANIFEST_FILE, SKILLS_LOCKFILE]);
707
705
  const files = [];
708
706
  for (const rel of (await listFiles(this.#fs, skillRoot)).sort()) {
709
- if (excluded.has(rel.split("/").pop() ?? "")) continue;
707
+ if (MANIFEST_EXCLUDED_FILES.has(rel.split("/").pop() ?? "")) continue;
710
708
  const content = await this.#fs.readBinary(`${skillRoot}/${rel}`);
711
709
  files.push({
712
710
  path: rel,
@@ -1180,6 +1178,11 @@ function parseWorkerEvent(data) {
1180
1178
  runId: data["runId"],
1181
1179
  delta: data["delta"]
1182
1180
  } : void 0;
1181
+ if (data["type"] === "host-warning") return isNonEmptyString(data["runId"]) && isNonEmptyString(data["message"]) ? {
1182
+ type: "host-warning",
1183
+ runId: data["runId"],
1184
+ message: data["message"]
1185
+ } : void 0;
1183
1186
  if (!isNonEmptyString(data["id"])) return;
1184
1187
  switch (data["type"]) {
1185
1188
  case "ready": return {
@@ -1499,10 +1502,12 @@ var WorkerRuntimeClient = class {
1499
1502
  #timeoutMs;
1500
1503
  #pending = /* @__PURE__ */ new Map();
1501
1504
  #seq = 0;
1505
+ #onWarning;
1502
1506
  constructor(deps) {
1503
1507
  this.#worker = deps.worker;
1504
1508
  this.#uiBridge = deps.uiBridge;
1505
1509
  this.#timeoutMs = deps.timeoutMs ?? 12e4;
1510
+ this.#onWarning = deps.onWarning ?? ((runId, message) => console.warn(`[webskill] run ${runId}: ${message}`));
1506
1511
  this.#worker.addEventListener("message", (event) => {
1507
1512
  this.#onMessage(event.data);
1508
1513
  });
@@ -1623,6 +1628,10 @@ var WorkerRuntimeClient = class {
1623
1628
  await this.#uiBridge?.onTextDelta?.(event.runId, event.delta);
1624
1629
  return;
1625
1630
  }
1631
+ if (event.type === "host-warning") {
1632
+ this.#onWarning(event.runId, event.message);
1633
+ return;
1634
+ }
1626
1635
  const pending = this.#pending.get(event.id);
1627
1636
  if (pending) {
1628
1637
  this.#pending.delete(event.id);