@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.
- package/README.md +42 -0
- package/dist/browser.d.ts +13 -4
- package/dist/browser.js +19 -10
- package/dist/{catalogComponents-C_V39rbF-B94i0fW7.js → catalogComponents-C_V39rbF-BOHveMWa.js} +254 -9090
- package/dist/client-BCM6Z3yq-qUQNkKrK.js +7787 -0
- package/dist/{dist-BQzncxXg.js → dist-8oQRa8Xz.js} +212 -13
- package/dist/{dist-CtBLBbEz.js → dist-ZKaM8j06.js} +2 -2
- package/dist/{dist-BdOW8N4V.js → dist-rorEJsNi.js} +596 -59
- package/dist/governance.d.ts +30 -197
- package/dist/governance.js +38 -199
- package/dist/{index-BpIK7tJM.d.ts → index-8d-oEDww.d.ts} +215 -2
- package/dist/{index-BNQNSDKg.d.ts → index-wiV5X8Rz.d.ts} +21 -4
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/{jsonRenderRegistry-9GrWP_hE-CMkryt1H.js → jsonRenderRegistry-9GrWP_hE-U6Do3Kid.js} +2 -2
- package/dist/mcp.d.ts +5 -3
- package/dist/mcp.js +10 -5
- package/dist/node.d.ts +338 -4
- package/dist/node.js +2338 -4
- package/dist/{openUiLibrary-B8-Cvou9-Cu1QZqoT.js → openUiLibrary-B8-Cvou9-BbpNTXS3.js} +2 -2
- package/dist/sandboxWorkerEntry.js +12 -3
- package/dist/skillVersionStore-DOEI9ptb-BxbYL70B.d.ts +127 -0
- package/dist/stdio-CFMoANJJ-BxrTeXh7.js +31 -0
- package/dist/{testing-BUoXvm1u.js → testing-CsrG3XLz.js} +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/dist/{types-7fnqDVrf-BnRQjVU3.d.ts → types-AmKCKJn_-VGabeXK4.d.ts} +140 -3
- package/dist/types-WovEf4ED-CZSDiiBU.js +6215 -0
- package/dist/ui-react.d.ts +2 -2
- package/dist/ui-react.js +6 -6
- package/dist/ui-vue.d.ts +1 -1
- package/dist/ui-vue.js +1 -1
- package/dist/ui.d.ts +3 -3
- package/dist/ui.js +2 -2
- package/dist/{webskillLitCatalog-CNaUpasU-CfSRvqCZ.js → webskillLitCatalog-CNaUpasU-BslMcxRZ.js} +1 -1
- package/package.json +4 -7
- package/dist/dist-CcMIUXeZ.js +0 -1896
- 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 {
|
|
2
|
-
import {
|
|
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 {
|
|
2
|
-
import {
|
|
3
|
-
import { n as MockLlmClient } from "./testing-
|
|
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
|
-
${
|
|
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 (
|
|
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);
|