@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
@@ -1,5 +1,5 @@
1
- import { ft as uiCatalog } from "./dist-CtBLBbEz.js";
2
- import { n as catalogComponentImpls } from "./catalogComponents-C_V39rbF-B94i0fW7.js";
1
+ import { ft as uiCatalog } from "./dist-ZKaM8j06.js";
2
+ import { n as catalogComponentImpls } from "./catalogComponents-C_V39rbF-BOHveMWa.js";
3
3
  import { z } from "zod";
4
4
  import { Component, Fragment, createContext, useCallback, useContext, useEffect, useInsertionEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -151,6 +151,7 @@ function setupNetworkGuards(task) {
151
151
  */
152
152
  const internalExit = process.reallyExit.bind(process);
153
153
  function stripProcessEscapeHatches() {
154
+ const remaining = [];
154
155
  for (const key of [
155
156
  "binding",
156
157
  "_linkedBinding",
@@ -158,9 +159,17 @@ function stripProcessEscapeHatches() {
158
159
  "openStdin",
159
160
  "reallyExit",
160
161
  "abort"
161
- ]) try {
162
- Reflect.deleteProperty(process, key);
163
- } catch {}
162
+ ]) {
163
+ try {
164
+ Reflect.deleteProperty(process, key);
165
+ } catch {}
166
+ if (key in process) remaining.push(key);
167
+ }
168
+ if (remaining.length > 0) {
169
+ const err = /* @__PURE__ */ new Error(`Sandbox hardening failed: cannot remove process escape hatches (${remaining.join(", ")})`);
170
+ err.code = "TOOL_EXECUTION_FAILED";
171
+ throw err;
172
+ }
164
173
  }
165
174
  async function main() {
166
175
  const task = workerData;
@@ -0,0 +1,127 @@
1
+ import { P as FileSystemProvider, X as SkillCatalogEntry, rt as SkillManifest } from "./types-AmKCKJn_-VGabeXK4.js";
2
+ //#region ../governance/dist/skillVersionStore-DOEI9ptb.d.ts
3
+ //#region src/types.d.ts
4
+ type CandidateStatus = 'draft' | 'pending-review' | 'approved' | 'published' | 'rejected';
5
+ type CandidateSource = 'runtime-miss' | 'document' | 'manual';
6
+ type CandidateRisk = 'low' | 'medium' | 'high';
7
+ interface CandidateFile {
8
+ path: string;
9
+ kind: 'skill-md' | 'script' | 'reference' | 'asset';
10
+ content: string;
11
+ }
12
+ interface CandidateSkill {
13
+ id: string;
14
+ name: string;
15
+ description: string;
16
+ status: CandidateStatus;
17
+ source: CandidateSource;
18
+ risk: CandidateRisk;
19
+ riskReasons: string[];
20
+ files: CandidateFile[];
21
+ suggestedTests?: string[];
22
+ createdAt: string;
23
+ updatedAt: string;
24
+ metadata?: Record<string, unknown>;
25
+ }
26
+ interface AuditEvent {
27
+ id: string;
28
+ type: string;
29
+ target: string;
30
+ actor?: string;
31
+ ts: string;
32
+ data?: Record<string, unknown>;
33
+ /** hash 链:上一条事件的 hash(首条为 GENESIS) */
34
+ prevHash?: string;
35
+ /** 本事件规范化载荷 + prevHash 的 sha256 */
36
+ hash?: string;
37
+ }
38
+ interface AuditLog {
39
+ append(event: Omit<AuditEvent, 'id' | 'ts'> & {
40
+ id?: string;
41
+ ts?: string;
42
+ }): Promise<AuditEvent>;
43
+ query(filter: {
44
+ target?: string;
45
+ type?: string;
46
+ since?: string;
47
+ }): Promise<AuditEvent[]>;
48
+ }
49
+ interface SkillVersion {
50
+ versionId: string;
51
+ parentVersionId?: string;
52
+ createdAt: string;
53
+ reason: string;
54
+ manifest: SkillManifest;
55
+ auditEventId?: string;
56
+ /** 发布时捕获的技能归档(zip 相对路径,applyRollback 恢复用;0.2.0 起记录) */
57
+ archivePath?: string;
58
+ }
59
+ type SkillState = 'active' | 'quarantined' | 'deprecated' | 'disabled';
60
+ //#endregion
61
+ //#region src/candidate/candidateStore.d.ts
62
+ /** 逐文件持久化的候选存储:<managedRoot>/.webskill/candidates/<id>.json */
63
+ declare class CandidateStore {
64
+ #private;
65
+ constructor(deps: {
66
+ root: string;
67
+ fs: FileSystemProvider;
68
+ });
69
+ save(candidate: CandidateSkill): Promise<void>;
70
+ get(id: string): Promise<CandidateSkill>;
71
+ list(): Promise<CandidateSkill[]>;
72
+ updateStatus(id: string, status: CandidateStatus, now?: string): Promise<CandidateSkill>;
73
+ }
74
+ /** 硬门禁:仅 published 可转换为 Catalog 条目,否则 APPROVAL_REQUIRED */
75
+ declare function candidateToCatalogEntry(candidate: CandidateSkill): SkillCatalogEntry;
76
+ //#endregion
77
+ //#region src/approval/policies.d.ts
78
+ interface ApprovalDecision {
79
+ needsHuman: boolean;
80
+ reason: string;
81
+ }
82
+ interface ApprovalPolicy {
83
+ evaluate(candidate: CandidateSkill): ApprovalDecision;
84
+ }
85
+ /** 默认策略:任何候选都必须人工审批 */
86
+ declare class AlwaysHumanApprovalPolicy implements ApprovalPolicy {
87
+ evaluate(candidate: CandidateSkill): ApprovalDecision;
88
+ }
89
+ /** 规则组合策略:首个命中的规则胜出,全部未命中走 fallback(默认 AlwaysHuman) */
90
+ declare class CompositeApprovalPolicy implements ApprovalPolicy {
91
+ #private;
92
+ constructor(rules: Array<(candidate: CandidateSkill) => ApprovalDecision | undefined>, fallback?: ApprovalPolicy);
93
+ evaluate(candidate: CandidateSkill): ApprovalDecision;
94
+ }
95
+ //#endregion
96
+ //#region src/versioning/skillVersionStore.d.ts
97
+ /** 版本存储:manifest 快照 + parentVersionId 链;回滚 = 追加新版本(谱系不断)。
98
+ * 保留策略:maxArchivesPerSkill(默认 5)超出时清理最旧版本(json + zip 归档一并删除)。 */
99
+ declare class SkillVersionStore {
100
+ #private;
101
+ constructor(deps: {
102
+ root: string;
103
+ fs: FileSystemProvider;
104
+ now?: () => string;
105
+ createId?: () => string;
106
+ audit?: AuditLog;
107
+ /** 每技能保留的版本/归档上限(默认 5,超出清理最旧) */
108
+ maxArchivesPerSkill?: number;
109
+ });
110
+ add(skillName: string, input: {
111
+ reason: string;
112
+ manifest: SkillManifest;
113
+ parentVersionId?: string;
114
+ archive?: Uint8Array;
115
+ }): Promise<SkillVersion>;
116
+ /** 读取版本归档字节(applyRollback 用;未捕获归档的旧版本 → GOVERNANCE_FAILED) */
117
+ readArchive(skillName: string, versionId: string): Promise<Uint8Array>;
118
+ list(skillName: string): Promise<SkillVersion[]>;
119
+ get(skillName: string, versionId: string): Promise<SkillVersion>;
120
+ /** 回滚:基于旧 manifest 追加新版本 + skill.rolled_back 审计 */
121
+ rollback(skillName: string, targetVersionId: string, input: {
122
+ actor?: string;
123
+ reason?: string;
124
+ }): Promise<SkillVersion>;
125
+ }
126
+ //#endregion
127
+ export { AuditLog as a, CandidateSkill as c, CandidateStore as d, CompositeApprovalPolicy as f, candidateToCatalogEntry as g, SkillVersionStore as h, AuditEvent as i, CandidateSource as l, SkillVersion as m, ApprovalDecision as n, CandidateFile as o, SkillState as p, ApprovalPolicy as r, CandidateRisk as s, AlwaysHumanApprovalPolicy as t, CandidateStatus as u };
@@ -0,0 +1,31 @@
1
+ import { y as JSONRPCMessageSchema } from "./types-WovEf4ED-CZSDiiBU.js";
2
+
3
+ //#region ../node/dist/stdio-CFMoANJJ.js
4
+ /**
5
+ * Buffers a continuous stdio stream into discrete JSON-RPC messages.
6
+ */
7
+ var ReadBuffer = class {
8
+ append(chunk) {
9
+ this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk;
10
+ }
11
+ readMessage() {
12
+ if (!this._buffer) return null;
13
+ const index = this._buffer.indexOf("\n");
14
+ if (index === -1) return null;
15
+ const line = this._buffer.toString("utf8", 0, index).replace(/\r$/, "");
16
+ this._buffer = this._buffer.subarray(index + 1);
17
+ return deserializeMessage(line);
18
+ }
19
+ clear() {
20
+ this._buffer = void 0;
21
+ }
22
+ };
23
+ function deserializeMessage(line) {
24
+ return JSONRPCMessageSchema.parse(JSON.parse(line));
25
+ }
26
+ function serializeMessage(message) {
27
+ return JSON.stringify(message) + "\n";
28
+ }
29
+
30
+ //#endregion
31
+ export { ReadBuffer, deserializeMessage, serializeMessage };
@@ -1,4 +1,4 @@
1
- import { u as WebSkillError } from "./dist-BQzncxXg.js";
1
+ import { m as WebSkillError } from "./dist-8oQRa8Xz.js";
2
2
 
3
3
  //#region ../runtime/dist/testing.js
4
4
  /**
package/dist/testing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { c as LlmClient, d as LlmResponse, f as LlmStreamEvent, h as MemoryStore, l as LlmCompleteInput, n as ArtifactStore, o as InteractionRequest, s as InteractionResponse, t as Artifact, v as UiBridge } from "./types-7fnqDVrf-BnRQjVU3.js";
1
+ import { c as LlmClient, d as LlmResponse, f as LlmStreamEvent, h as MemoryStore, l as LlmCompleteInput, n as ArtifactStore, o as InteractionRequest, s as InteractionResponse, t as Artifact, v as UiBridge } from "./types-AmKCKJn_-VGabeXK4.js";
2
2
  import { a as loadGoogleConfigFromEnv, i as loadAnthropicConfigFromEnv, n as LlmEnvConfig, o as loadLlmConfigFromEnv, r as ProviderEnvConfig } from "./env-BPUBZCwJ-4jat_SVG.js";
3
3
  //#region ../runtime/dist/testing.d.ts
4
4
  //#region src/llm/mockLlmClient.d.ts
package/dist/testing.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as MemoryArtifactStore } from "./memoryArtifactStore-C9lFVqPF-yFz6yJj0.js";
2
2
  import { n as loadGoogleConfigFromEnv, r as loadLlmConfigFromEnv, t as loadAnthropicConfigFromEnv } from "./env--jJB-TSX-04klhTYi.js";
3
- import { n as MockLlmClient, r as MockUiBridge, t as InMemoryStore } from "./testing-BUoXvm1u.js";
3
+ import { n as MockLlmClient, r as MockUiBridge, t as InMemoryStore } from "./testing-CsrG3XLz.js";
4
4
 
5
5
  export { InMemoryStore, MemoryArtifactStore, MockLlmClient, MockUiBridge, loadAnthropicConfigFromEnv, loadGoogleConfigFromEnv, loadLlmConfigFromEnv };
@@ -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' | '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' | 'SKILL_UNKNOWN_ALLOWED_TOOL' | 'SKILL_UNKNOWN_DEPENDENCY' | 'SKILL_CIRCULAR_DEPENDENCY' | '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' | 'SKILL_UNKNOWN_ALLOWED_TOOL' | 'SKILL_UNKNOWN_DEPENDENCY' | 'SKILL_CIRCULAR_DEPENDENCY' | 'GOVERNANCE_FAILED' | 'RUN_SNAPSHOT_NOT_FOUND' | 'RUN_SNAPSHOT_EXPIRED' | 'RUN_SNAPSHOT_INCOMPATIBLE' | 'RUN_TRACE_INCOMPATIBLE' | 'SESSION_INCOMPATIBLE' | 'SIGNATURE_MISSING' | 'SIGNATURE_MALFORMED' | 'SIGNATURE_UNTRUSTED_KEY' | 'SIGNATURE_MISMATCH' | 'SIGNATURE_UNSUPPORTED' | 'MCP_STDIO_SPAWN_FAILED' | 'MCP_STDIO_EXITED' | 'MCP_STDIO_TIMEOUT';
4
4
  /**
5
5
  * 所有公开 API 抛出的结构化错误,code 供上层可编程处理
6
6
  * @stable
@@ -91,6 +91,29 @@ interface VerifyResult {
91
91
  declare const SKILL_MANIFEST_FILE = "webskill.skill-manifest.json";
92
92
  /** managed root 下的锁定文件名(不参与 files 列表与 digest) */
93
93
  declare const SKILLS_LOCKFILE = "skills.lock.json";
94
+ /** 技能目录内的签名文件名(不参与 files 列表与 digest) */
95
+ declare const SKILL_SIGNATURE_FILE = "webskill.skill-signature.json";
96
+ /**
97
+ * 不参与 digest 的技能目录内文件。
98
+ *
99
+ * 这份名单原本在 node / browser / console / core 各抄一份,签名文件一旦漏抄一处,
100
+ * 写签名就会改变该处算出的 digest、让签名当场自我失效——而且只在「先签盘上的包、
101
+ * 再从盘上验」时才暴露。收成一处是为了让「漏抄」这件事不再可能发生。
102
+ */
103
+ declare const MANIFEST_EXCLUDED_FILES: ReadonlySet<string>;
104
+ /**
105
+ * 技能管理器的最小端口。
106
+ *
107
+ * 只声明**环境无关的调用方实际用到的方法**:治理层需要卸载技能,但不该因此
108
+ * 依赖 `@webskill/node` 的 `SkillManager` 类——那会把 `node:*` 类型拖进
109
+ * `/governance` 的 d.ts chunk(D21)。刻意不镜像 `SkillManager` 的全部方法,
110
+ * 否则只是换个名字保留同一份耦合。
111
+ *
112
+ * @stable
113
+ */
114
+ interface SkillManagerPort {
115
+ uninstall(name: string): Promise<void>;
116
+ }
94
117
  type Sha256Fn = (data: Uint8Array | string) => string | Promise<string>;
95
118
  /** 整体 digest:逐文件 "<path>:<sha256>\n" 拼接串(文件按 path 排序)的 sha256(hash 由调用方提供,可为 WebCrypto 异步实现) */
96
119
  declare function computeDigest(files: Array<{
@@ -144,6 +167,118 @@ interface FileSystemProvider {
144
167
  withRoot?(root: string): FileSystemProvider;
145
168
  }
146
169
  //#endregion
170
+ //#region src/skill/signature.d.ts
171
+ declare const SIGNATURE_SCHEMA_VERSION = 1;
172
+ /** `webskill.skill-signature.json` 的落盘形态 */
173
+ interface SkillSignature {
174
+ schemaVersion: number;
175
+ algorithm: 'ed25519';
176
+ /** 公钥 SHA-256 的前 16 字节 hex */
177
+ keyId: string;
178
+ /** base64url,raw 32 bytes */
179
+ publicKey: string;
180
+ /** base64url,raw 64 bytes */
181
+ signature: string;
182
+ signedAt: string;
183
+ }
184
+ /** 未签名包的处置策略;0.3.0 默认 `warn`,0.4.0 与 D10 一起收紧 */
185
+ type UnsignedPolicy = 'allow' | 'warn' | 'deny';
186
+ interface TrustedKey {
187
+ keyId: string;
188
+ publicKey: string;
189
+ label: string;
190
+ addedAt: string;
191
+ }
192
+ interface TrustedKeyStore {
193
+ list(): Promise<TrustedKey[]>;
194
+ get(keyId: string): Promise<TrustedKey | undefined>;
195
+ add(key: Omit<TrustedKey, 'addedAt'>): Promise<void>;
196
+ remove(keyId: string): Promise<void>;
197
+ }
198
+ interface SignatureVerdict {
199
+ ok: boolean;
200
+ /** 未签名且策略放行时为 true;调用方据此决定是否发 warning 事件 */
201
+ unsigned: boolean;
202
+ /** 验签通过时是信任库里的 keyId */
203
+ keyId?: string;
204
+ /** 放行但需提醒的原因(英文,进审计与 UI) */
205
+ warning?: string;
206
+ }
207
+ /**
208
+ * 验签结论的审计投递口。governance 的 `FsAuditLog` 结构上满足它,
209
+ * 因此宿主可以直接传进来——core 不反向依赖 governance。
210
+ */
211
+ interface SignatureAuditSink {
212
+ append(event: {
213
+ type: string;
214
+ target: string;
215
+ data?: Record<string, unknown>;
216
+ }): Promise<unknown>;
217
+ }
218
+ /** 已导入的密钥句柄;真实 WebCrypto `CryptoKey` 结构上兼容 */
219
+ interface CryptoKeyLike {
220
+ readonly type: string;
221
+ readonly algorithm: {
222
+ readonly name: string;
223
+ };
224
+ }
225
+ /**
226
+ * 签名载荷:固定键序手写拼装,**不依赖 JSON.stringify 的属性顺序**
227
+ * (对象字面量顺序与运行时插入顺序不是同一件事,签验两侧字节必须逐字一致)。
228
+ *
229
+ * 载荷带 skill/version 而非裸 digest:只签 digest 时,同内容不同名的两个包
230
+ * 签名可以互换,等于允许把 A 技能的签名挪到 B 技能上。
231
+ */
232
+ declare function signaturePayloadBytes(manifest: SkillManifest): Uint8Array;
233
+ declare function keyIdOf(publicKey: Uint8Array): Promise<string>;
234
+ /** 从技能目录读签名文件;文件不存在返回 undefined(缺签名由策略层判定,不是错误) */
235
+ declare function readSkillSignature(fs: FileSystemProvider, skillRoot: string): Promise<SkillSignature | undefined>;
236
+ /**
237
+ * 验签。四种失败各自一个错误码,因为宿主的处置完全不同:
238
+ * 缺签名要引导选策略,坏文件要提示重下,不受信的 key 要引导添加密钥,
239
+ * 而验签不通过是安全事件,不提供「继续」。
240
+ *
241
+ * 包内自带的 publicKey **不产生任何信任**——它只是让「摘要不匹配」与
242
+ * 「公钥不受信」两种失败可区分。信任判定只认信任库里的 keyId。
243
+ */
244
+ declare function verifySkillSignature(input: {
245
+ manifest: SkillManifest;
246
+ signature: SkillSignature | undefined;
247
+ trustedKeys: TrustedKeyStore;
248
+ policy: {
249
+ unsigned: UnsignedPolicy;
250
+ };
251
+ }): Promise<SignatureVerdict>;
252
+ /**
253
+ * 为已生成 manifest 的技能产出签名。生产与测试走同一条路径——
254
+ * 只提供 CLI 会让测试无法覆盖真正被调用的代码。
255
+ *
256
+ * `publicKey` 必须显式传入:WebCrypto 没有「由私钥导出公钥」的 API,
257
+ * 密钥对的两半只能一起来。
258
+ */
259
+ declare function signSkill(input: {
260
+ manifest: SkillManifest;
261
+ /** 已导入的密钥句柄,或 pkcs8 DER 字节 */
262
+ privateKey: CryptoKeyLike | Uint8Array;
263
+ /** raw 32 字节公钥 */
264
+ publicKey: Uint8Array;
265
+ signedAt?: string;
266
+ }): Promise<SkillSignature>;
267
+ /**
268
+ * `FileSystemProvider` 后端的信任库:单个 JSON 文件,写入走原子替换。
269
+ *
270
+ * 「OPFS 还是 IndexedDB 还是宿主注入」不在这层回答——`FileSystemProvider`
271
+ * 已经是那层抽象,浏览器里落在哪由宿主注入的 fs 决定。
272
+ */
273
+ declare class FsTrustedKeyStore implements TrustedKeyStore {
274
+ #private;
275
+ constructor(fs: FileSystemProvider, path: string);
276
+ list(): Promise<TrustedKey[]>;
277
+ get(keyId: string): Promise<TrustedKey | undefined>;
278
+ add(key: Omit<TrustedKey, 'addedAt'>): Promise<void>;
279
+ remove(keyId: string): Promise<void>;
280
+ }
281
+ //#endregion
147
282
  //#region src/fs/memoryFs.d.ts
148
283
  /** 内存文件系统:路径一律规范化为 `/` 分隔,写入自动创建父目录 */
149
284
  declare class MemoryFS implements FileSystemProvider {
@@ -405,7 +540,7 @@ declare function escapeXml(text: string): string;
405
540
  declare function renderAvailableSkillsXml(catalog: SkillCatalog): string;
406
541
  declare const xmlRenderer: CatalogRenderer;
407
542
  //#endregion
408
- //#region ../runtime/dist/types-7fnqDVrf.d.ts
543
+ //#region ../runtime/dist/types-AmKCKJn_.d.ts
409
544
  //#region src/llm/streamTypes.d.ts
410
545
  /** 流式 LLM 事件(OpenAI SSE / Vercel fullStream 统一映射) */
411
546
  type LlmStreamEvent = {
@@ -437,6 +572,8 @@ interface LlmToolCall {
437
572
  id: string;
438
573
  name: string;
439
574
  arguments: Record<string, unknown>;
575
+ /** 流式拼接后的 arguments 不是合法 JSON 时的错误描述;设置时 arguments 不可信 */
576
+ argumentsParseError?: string;
440
577
  }
441
578
  interface LlmResponse {
442
579
  content?: string;
@@ -741,4 +878,4 @@ interface MemoryStore {
741
878
  transaction?<T>(scope: string, fn: (inner: MemoryStore) => Promise<T>): Promise<T>;
742
879
  }
743
880
  //#endregion
744
- export { SkillSource as $, DEFAULT_ARCHIVE_LIMITS as A, SKILL_NAME_PATTERN as B, UiSurfaceDrafts as C, renderCatalogJson as Ct, UiSurfaceSnapshot as D, validateSkills as Dt, UiSurfacePatch as E, unzipWithLimits as Et, MemoryFS as F, SkillDocument as G, SkillCatalog as H, RemoteUrlPolicy as I, SkillLocation as J, SkillInstallSource as K, SKILLS_LOCKFILE as L, FileStat as M, FileSystemProvider as N, ArchiveLimits as O, verifyManifest as Ot, JsonSchema as P, SkillReader as Q, SKILL_MANIFEST_FILE as R, UiSurfaceActionResponse as S, renderAvailableSkillsXml as St, UiSurfaceFormField as T, resolveInsideRoot as Tt, SkillCatalogEntry as U, SKILL_PACK_FILE as V, SkillDiscovery as W, SkillMetadata as X, SkillManifest as Y, SkillPackManifest as Z, RenderResultRequest as _, messageOf as _t, InteractionPolicy as a, assertRemoteUrlAllowed as at, UiSurfaceAction as b, parseSkillPackManifest as bt, LlmClient as c, buildCatalog as ct, LlmResponse as d, checkSkillRules as dt, SkillsLockfile as et, LlmStreamEvent as f, computeDigest as ft, RenderBlock as g, jsonRenderer as gt, MemoryStore as h, isValidSkillName as ht, FormField as i, WebSkillErrorCode as it, DiscoveryResult as j, CatalogRenderer as k, xmlRenderer as kt, LlmCompleteInput as l, buildManifest as lt, LlmToolSpec as m, exportSkills as mt, ArtifactStore as n, VerifyResult as nt, InteractionRequest as o, assertSafePathSegment as ot, LlmToolCall as p, escapeXml as pt, SkillIssue as q, ChartSpec as r, WebSkillError as rt, InteractionResponse as s, atomicWriteText as st, Artifact as t, ValidationReport as tt, LlmMessage as u, checkDependencyCycles as ut, UiBridge as v, normalizePath as vt, UiSurfaceEvent as w, resolveArchiveLimits as wt, UiSurfaceActionRequest as x, readResponseWithLimit as xt, UiSurface as y, parseSkillMarkdown as yt, SKILL_NAME_MAX_LENGTH as z };
881
+ export { SkillInstallSource as $, CryptoKeyLike as A, messageOf as At, SIGNATURE_SCHEMA_VERSION as B, signSkill as Bt, UiSurfaceDrafts as C, checkSkillRules as Ct, UiSurfaceSnapshot as D, isValidSkillName as Dt, UiSurfacePatch as E, exportSkills as Et, FsTrustedKeyStore as F, readSkillSignature as Ft, SKILL_PACK_FILE as G, verifySkillSignature as Gt, SKILL_MANIFEST_FILE as H, unzipWithLimits as Ht, JsonSchema as I, renderAvailableSkillsXml as It, SignatureVerdict as J, SKILL_SIGNATURE_FILE as K, xmlRenderer as Kt, MANIFEST_EXCLUDED_FILES as L, renderCatalogJson as Lt, DiscoveryResult as M, parseSkillMarkdown as Mt, FileStat as N, parseSkillPackManifest as Nt, ArchiveLimits as O, jsonRenderer as Ot, FileSystemProvider as P, readResponseWithLimit as Pt, SkillDocument as Q, MemoryFS as R, resolveArchiveLimits as Rt, UiSurfaceActionResponse as S, checkDependencyCycles as St, UiSurfaceFormField as T, escapeXml as Tt, SKILL_NAME_MAX_LENGTH as U, validateSkills as Ut, SKILLS_LOCKFILE as V, signaturePayloadBytes as Vt, SKILL_NAME_PATTERN as W, verifyManifest as Wt, SkillCatalogEntry as X, SkillCatalog as Y, SkillDiscovery as Z, RenderResultRequest as _, assertRemoteUrlAllowed as _t, InteractionPolicy as a, SkillPackManifest as at, UiSurfaceAction as b, buildCatalog as bt, LlmClient as c, SkillSource as ct, LlmResponse as d, TrustedKeyStore as dt, SkillIssue as et, LlmStreamEvent as f, UnsignedPolicy as ft, RenderBlock as g, WebSkillErrorCode as gt, MemoryStore as h, WebSkillError as ht, FormField as i, SkillMetadata as it, DEFAULT_ARCHIVE_LIMITS as j, normalizePath as jt, CatalogRenderer as k, keyIdOf as kt, LlmCompleteInput as l, SkillsLockfile as lt, LlmToolSpec as m, VerifyResult as mt, ArtifactStore as n, SkillManagerPort as nt, InteractionRequest as o, SkillReader as ot, LlmToolCall as p, ValidationReport as pt, SignatureAuditSink as q, ChartSpec as r, SkillManifest as rt, InteractionResponse as s, SkillSignature as st, Artifact as t, SkillLocation as tt, LlmMessage as u, TrustedKey as ut, UiBridge as v, assertSafePathSegment as vt, UiSurfaceEvent as w, computeDigest as wt, UiSurfaceActionRequest as x, buildManifest as xt, UiSurface as y, atomicWriteText as yt, RemoteUrlPolicy as z, resolveInsideRoot as zt };