@webskill/sdk 0.1.5 → 0.2.1

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.
@@ -1,6 +1,6 @@
1
- import { F as SkillDocument, N as SkillCatalogEntry, c as LlmClient, u as LlmMessage, v as UiBridge, w as FileSystemProvider, z as SkillManifest } from "./types-CgNC-oQu-DEcIBJKG.js";
2
- import { $ as SkillStateGuard, lt as WebSkillRuntime, q as RuntimeRun } from "./index-COuOu6gw.js";
3
- import { f as SkillManager } from "./index-Bun1aEf4.js";
1
+ import { F as SkillDocument, N as SkillCatalogEntry, c as LlmClient, u as LlmMessage, v as UiBridge, w as FileSystemProvider, z as SkillManifest } from "./types-CKm5G_eQ-8W8FnP4u.js";
2
+ import { Q as ScriptExecutor, dt as WebSkillRuntime, ft as WebSkillRuntimeDeps, q as RuntimeRun, tt as SkillStateGuard } from "./index-gjFuBevI.js";
3
+ import { d as SkillManager } from "./index-BmzysJX5.js";
4
4
  //#region ../governance/dist/index.d.ts
5
5
  //#region src/types.d.ts
6
6
  type CandidateStatus = 'draft' | 'pending-review' | 'approved' | 'published' | 'rejected';
@@ -32,6 +32,10 @@ interface AuditEvent {
32
32
  actor?: string;
33
33
  ts: string;
34
34
  data?: Record<string, unknown>;
35
+ /** hash 链:上一条事件的 hash(首条为 GENESIS) */
36
+ prevHash?: string;
37
+ /** 本事件规范化载荷 + prevHash 的 sha256 */
38
+ hash?: string;
35
39
  }
36
40
  interface AuditLog {
37
41
  append(event: Omit<AuditEvent, 'id' | 'ts'> & {
@@ -51,6 +55,8 @@ interface SkillVersion {
51
55
  reason: string;
52
56
  manifest: SkillManifest;
53
57
  auditEventId?: string;
58
+ /** 发布时捕获的技能归档(zip 相对路径,applyRollback 恢复用;0.2.0 起记录) */
59
+ archivePath?: string;
54
60
  }
55
61
  type SkillState = 'active' | 'quarantined' | 'deprecated' | 'disabled';
56
62
  //#endregion
@@ -151,7 +157,10 @@ declare class SkillVersionStore {
151
157
  reason: string;
152
158
  manifest: SkillManifest;
153
159
  parentVersionId?: string;
160
+ archive?: Uint8Array;
154
161
  }): Promise<SkillVersion>;
162
+ /** 读取版本归档字节(applyRollback 用;未捕获归档的旧版本 → GOVERNANCE_FAILED) */
163
+ readArchive(skillName: string, versionId: string): Promise<Uint8Array>;
155
164
  list(skillName: string): Promise<SkillVersion[]>;
156
165
  get(skillName: string, versionId: string): Promise<SkillVersion>;
157
166
  /** 回滚:基于旧 manifest 追加新版本 + skill.rolled_back 审计 */
@@ -182,10 +191,25 @@ declare class ApprovalWorkflow {
182
191
  publish(candidateId: string, input: {
183
192
  actor: string;
184
193
  }): Promise<SkillManifest>;
194
+ /**
195
+ * 真实回滚(受审批保护:仅经显式 actor 调用并全程审计):
196
+ * 版本归档解包 → staging 校验 → 原子安装(复用安装管线 swap)→ 追加新版本 + 审计。
197
+ * RepairPlanner 的 rollback 选项(targetVersionId)经本方法执行。
198
+ */
199
+ applyRollback(skillName: string, versionId: string, input: {
200
+ actor: string;
201
+ reason?: string;
202
+ }): Promise<SkillManifest>;
185
203
  }
186
204
  //#endregion
187
205
  //#region src/audit/fsAuditLog.d.ts
188
- /** JSONL 追加的审计日志:<managedRoot>/.webskill/audit.jsonl;跨实例可恢复查询 */
206
+ interface AuditChainVerification {
207
+ ok: boolean;
208
+ /** 首个断链位置(行号,0 起;ok 时 undefined) */
209
+ brokenAt?: number;
210
+ reason?: string;
211
+ }
212
+ /** JSONL 追加的审计日志:<managedRoot>/.webskill/audit.jsonl;跨实例可恢复查询;prevHash 链可校验完整性 */
189
213
  declare class FsAuditLog implements AuditLog {
190
214
  #private;
191
215
  constructor(deps: {
@@ -194,7 +218,7 @@ declare class FsAuditLog implements AuditLog {
194
218
  now?: () => string;
195
219
  createId?: () => string;
196
220
  });
197
- append(event: Omit<AuditEvent, 'id' | 'ts'> & {
221
+ append(event: Omit<AuditEvent, 'id' | 'ts' | 'prevHash' | 'hash'> & {
198
222
  id?: string;
199
223
  ts?: string;
200
224
  }): Promise<AuditEvent>;
@@ -203,6 +227,8 @@ declare class FsAuditLog implements AuditLog {
203
227
  type?: string;
204
228
  since?: string;
205
229
  }): Promise<AuditEvent[]>;
230
+ /** hash 链完整性校验:逐行重算 hash 并核对 prevHash 链接 */
231
+ verifyChain(): Promise<AuditChainVerification>;
206
232
  }
207
233
  //#endregion
208
234
  //#region src/repair/failureAnalyzer.d.ts
@@ -234,7 +260,7 @@ interface RepairOption {
234
260
  }
235
261
  /**
236
262
  * 修订选项规划:patch(按诊断给具体文件变更)/ rollback(有旧版本时)/ quarantine。
237
- * 注意:任何 option 的 apply 都必须经 ApprovalWorkflow 审批后执行。
263
+ * 注意:任何 option 的 apply 都必须经 ApprovalWorkflow 审批后执行;rollback 选项(targetVersionId)经 ApprovalWorkflow.applyRollback 真实恢复文件。
238
264
  */
239
265
  declare class RepairPlanner {
240
266
  plan(input: {
@@ -331,6 +357,16 @@ declare class EvaluationRunner {
331
357
  run(tasks: EvaluationTask[]): Promise<EvaluationReport>;
332
358
  }
333
359
  //#endregion
360
+ //#region src/evaluation/evaluationRuntime.d.ts
361
+ /**
362
+ * 治理评估专用 runtime 装配(不可信技能试用路径):
363
+ * 默认注入 ProcessSandboxExecutor(fork + --permission 真实进程隔离);
364
+ * 可配置 executor 切回 SandboxedScriptExecutor(worker_threads 能力面收敛形态)。
365
+ */
366
+ declare function createEvaluationRuntime(deps: WebSkillRuntimeDeps & {
367
+ executor?: ScriptExecutor;
368
+ }): WebSkillRuntime;
369
+ //#endregion
334
370
  //#region src/evaluation/testSuggestion.d.ts
335
371
  /** 失败 trace → 回归评估任务建议(prompt 复现 + expected 错误模式) */
336
372
  declare function suggestFromFailedRun(run: RuntimeRun): EvaluationTask;
@@ -448,4 +484,4 @@ declare function createMissHook(deps: {
448
484
  */
449
485
  declare function completeText(llm: LlmClient, messages: LlmMessage[]): Promise<string>;
450
486
  //#endregion
451
- export { AlwaysHumanApprovalPolicy, type ApprovalDecision, type ApprovalPolicy, ApprovalWorkflow, type AuditEvent, type AuditLog, type CandidateFile, type CandidateRisk, type CandidateSkill, type CandidateSource, type CandidateStatus, CandidateStore, CompositeApprovalPolicy, DependencyGraph, DocumentSkillExtractor, type EvaluationReport, type EvaluationResult, EvaluationRunner, type EvaluationTask, FailureAnalyzer, type FailureDiagnosis, FsAuditLog, LlmCandidateGenerator, type RepairOption, RepairPlanner, SCORING_WEIGHTS, type ScoreInput, SimilarityDetector, SkillScorer, type SkillState, SkillStatePolicy, type SkillVersion, SkillVersionStore, type SourceDocument, candidateToCatalogEntry, completeText, createMissHook, jaccardSimilarity, normalizeCandidate, normalizeCandidateFiles, normalizeRisk, parseJsonObject, readDocument, sanitizeCandidateName, suggestFromFailedRun, validateCandidate };
487
+ export { AlwaysHumanApprovalPolicy, type ApprovalDecision, type ApprovalPolicy, ApprovalWorkflow, type AuditEvent, type AuditLog, type CandidateFile, type CandidateRisk, type CandidateSkill, type CandidateSource, type CandidateStatus, CandidateStore, CompositeApprovalPolicy, DependencyGraph, DocumentSkillExtractor, type EvaluationReport, type EvaluationResult, EvaluationRunner, type EvaluationTask, FailureAnalyzer, type FailureDiagnosis, FsAuditLog, LlmCandidateGenerator, type RepairOption, RepairPlanner, SCORING_WEIGHTS, type ScoreInput, SimilarityDetector, SkillScorer, type SkillState, SkillStatePolicy, type SkillVersion, SkillVersionStore, type SourceDocument, candidateToCatalogEntry, completeText, createEvaluationRuntime, createMissHook, jaccardSimilarity, normalizeCandidate, normalizeCandidateFiles, normalizeRisk, parseJsonObject, readDocument, sanitizeCandidateName, suggestFromFailedRun, validateCandidate };
@@ -1,5 +1,6 @@
1
- import { A as validateSkills, O as resolveInsideRoot, d as assertSafePathSegment, u as WebSkillError, y as isValidSkillName } from "./dist-fZFZaf43.js";
2
- import { i as NodeFS } from "./dist-LIFS3ZjI.js";
1
+ import { A as unzipWithLimits, b as isValidSkillName, d as assertSafePathSegment, j as validateSkills, k as resolveInsideRoot, u as WebSkillError } from "./dist-D0saNPi_.js";
2
+ import { S as WebSkillRuntime } from "./dist-DrySSQ5R.js";
3
+ import { i as NodeFS, s as ProcessSandboxExecutor, u as exportArchive } from "./dist-BRGQcLqR.js";
3
4
  import path from "node:path";
4
5
  import { tmpdir } from "node:os";
5
6
  import { mkdtemp } from "node:fs/promises";
@@ -307,9 +308,15 @@ var ApprovalWorkflow = class {
307
308
  type: "local",
308
309
  path: skillDir
309
310
  });
311
+ const archiveOut = `${stagingRoot}/version-archive.zip`;
312
+ await exportArchive(this.#fs, `${this.#skillManager.managedRoot}/${candidate.name}`, {
313
+ format: "zip",
314
+ outPath: archiveOut
315
+ });
310
316
  await this.#versions.add(candidate.name, {
311
317
  reason: `Publish candidate ${candidateId}`,
312
- manifest
318
+ manifest,
319
+ archive: await this.#fs.readBinary(archiveOut)
313
320
  });
314
321
  await this.#store.updateStatus(candidateId, "published");
315
322
  await this.#audit.append({
@@ -325,11 +332,79 @@ var ApprovalWorkflow = class {
325
332
  } catch (e) {
326
333
  if (e instanceof WebSkillError) throw e;
327
334
  throw new WebSkillError("GOVERNANCE_FAILED", `Failed to publish candidate "${candidateId}": ${messageOf$1(e)}`, e);
335
+ } finally {
336
+ try {
337
+ await this.#fs.remove(stagingRoot, { recursive: true });
338
+ } catch {}
339
+ }
340
+ }
341
+ /**
342
+ * 真实回滚(受审批保护:仅经显式 actor 调用并全程审计):
343
+ * 版本归档解包 → staging 校验 → 原子安装(复用安装管线 swap)→ 追加新版本 + 审计。
344
+ * RepairPlanner 的 rollback 选项(targetVersionId)经本方法执行。
345
+ */
346
+ async applyRollback(skillName, versionId, input) {
347
+ assertSafePathSegment(skillName, "skill name");
348
+ assertSafePathSegment(versionId, "version id");
349
+ const version = await this.#versions.get(skillName, versionId);
350
+ const archive = await this.#versions.readArchive(skillName, versionId);
351
+ const stagingRoot = (await mkdtemp(path.join(tmpdir(), "webskill-rollback-"))).split(path.sep).join("/");
352
+ try {
353
+ const skillDir = `${stagingRoot}/${skillName}`;
354
+ for (const [rel, content] of await unzipWithLimits(archive)) {
355
+ if (rel.endsWith("/")) continue;
356
+ await this.#fs.writeBinary(resolveInsideRoot(skillDir, rel), content);
357
+ }
358
+ const report = await validateSkills(this.#fs, [stagingRoot]);
359
+ if (!report.ok) {
360
+ const errors = report.issues.filter((i) => i.severity === "error");
361
+ throw new WebSkillError("GOVERNANCE_FAILED", `Rollback archive of "${skillName}" failed validation: ${errors.map((i) => i.message).join("; ")}`, errors);
362
+ }
363
+ const manifest = await this.#skillManager.install({
364
+ type: "local",
365
+ path: skillDir
366
+ });
367
+ if (manifest.integrity.digest !== version.manifest.integrity.digest) throw new WebSkillError("GOVERNANCE_FAILED", `Rollback of "${skillName}" to version "${versionId}" produced a digest mismatch: expected ${version.manifest.integrity.digest}, got ${manifest.integrity.digest}`);
368
+ await this.#versions.add(skillName, {
369
+ reason: input.reason ?? `Rollback to version ${versionId}`,
370
+ manifest,
371
+ archive
372
+ });
373
+ await this.#audit.append({
374
+ type: "skill.rolled_back",
375
+ target: skillName,
376
+ actor: input.actor,
377
+ data: {
378
+ targetVersionId: versionId,
379
+ reason: input.reason
380
+ }
381
+ });
382
+ return manifest;
383
+ } catch (e) {
384
+ if (e instanceof WebSkillError) throw e;
385
+ throw new WebSkillError("GOVERNANCE_FAILED", `Failed to roll back "${skillName}" to version "${versionId}": ${messageOf$1(e)}`, e);
386
+ } finally {
387
+ try {
388
+ await this.#fs.remove(stagingRoot, { recursive: true });
389
+ } catch {}
328
390
  }
329
391
  }
330
392
  };
331
393
  const fileOf$1 = (root) => `${root}/.webskill/audit.jsonl`;
332
- /** JSONL 追加的审计日志:<managedRoot>/.webskill/audit.jsonl;跨实例可恢复查询 */
394
+ const sha256Hex = (text) => createHash("sha256").update(text, "utf8").digest("hex");
395
+ /** 链字段之外的规范化事件载荷(hash 计算输入) */
396
+ function canonical(event) {
397
+ return JSON.stringify({
398
+ id: event.id,
399
+ ts: event.ts,
400
+ type: event.type,
401
+ target: event.target,
402
+ actor: event.actor,
403
+ data: event.data,
404
+ prevHash: event.prevHash
405
+ });
406
+ }
407
+ /** JSONL 追加的审计日志:<managedRoot>/.webskill/audit.jsonl;跨实例可恢复查询;prevHash 链可校验完整性 */
333
408
  var FsAuditLog = class {
334
409
  #root;
335
410
  #fs;
@@ -342,16 +417,26 @@ var FsAuditLog = class {
342
417
  this.#createId = deps.createId;
343
418
  }
344
419
  async append(event) {
420
+ const path = fileOf$1(this.#root);
421
+ const existing = await this.#fs.exists(path) ? await this.#fs.readText(path) : "";
422
+ const lines = existing.split("\n").filter((l) => l.trim() !== "");
423
+ let prevHash = "GENESIS";
424
+ if (lines.length > 0) try {
425
+ const last = JSON.parse(lines.at(-1));
426
+ prevHash = last.hash ?? sha256Hex(canonical(last));
427
+ } catch {
428
+ prevHash = "GENESIS";
429
+ }
345
430
  const full = {
346
431
  id: event.id ?? this.#createId?.() ?? `audit-${Math.random().toString(36).slice(2, 10)}`,
347
432
  ts: event.ts ?? this.#now?.() ?? (/* @__PURE__ */ new Date()).toISOString(),
348
433
  type: event.type,
349
434
  target: event.target,
350
435
  ...event.actor !== void 0 ? { actor: event.actor } : {},
351
- ...event.data !== void 0 ? { data: event.data } : {}
436
+ ...event.data !== void 0 ? { data: event.data } : {},
437
+ prevHash
352
438
  };
353
- const path = fileOf$1(this.#root);
354
- const existing = await this.#fs.exists(path) ? await this.#fs.readText(path) : "";
439
+ full.hash = sha256Hex(canonical(full));
355
440
  const prefix = existing === "" || existing.endsWith("\n") ? existing : `${existing}\n`;
356
441
  await this.#fs.writeText(path, `${prefix}${JSON.stringify(full)}\n`);
357
442
  return full;
@@ -371,6 +456,38 @@ var FsAuditLog = class {
371
456
  }
372
457
  return events;
373
458
  }
459
+ /** hash 链完整性校验:逐行重算 hash 并核对 prevHash 链接 */
460
+ async verifyChain() {
461
+ const path = fileOf$1(this.#root);
462
+ if (!await this.#fs.exists(path)) return { ok: true };
463
+ const lines = (await this.#fs.readText(path)).split("\n").filter((l) => l.trim() !== "");
464
+ let expectedPrev = "GENESIS";
465
+ for (let i = 0; i < lines.length; i++) {
466
+ let event;
467
+ try {
468
+ event = JSON.parse(lines[i]);
469
+ } catch {
470
+ return {
471
+ ok: false,
472
+ brokenAt: i,
473
+ reason: "line is not valid JSON"
474
+ };
475
+ }
476
+ if (event.prevHash !== expectedPrev) return {
477
+ ok: false,
478
+ brokenAt: i,
479
+ reason: "prevHash link mismatch (events may have been removed or reordered)"
480
+ };
481
+ const expectedHash = sha256Hex(canonical(event));
482
+ if (event.hash !== expectedHash) return {
483
+ ok: false,
484
+ brokenAt: i,
485
+ reason: "event hash mismatch (event content was tampered)"
486
+ };
487
+ expectedPrev = event.hash;
488
+ }
489
+ return { ok: true };
490
+ }
374
491
  };
375
492
  const dirOf = (root, skillName) => {
376
493
  assertSafePathSegment(skillName, "skill name");
@@ -400,9 +517,20 @@ var SkillVersionStore = class {
400
517
  manifest: input.manifest
401
518
  };
402
519
  assertSafePathSegment(version.versionId, "version id");
520
+ if (input.archive) {
521
+ const archivePath = `${dirOf(this.#root, skillName)}/${version.versionId}.zip`;
522
+ await this.#fs.writeBinary(archivePath, input.archive);
523
+ version.archivePath = archivePath;
524
+ }
403
525
  await this.#fs.writeText(`${dirOf(this.#root, skillName)}/${version.versionId}.json`, JSON.stringify(version, null, 2));
404
526
  return version;
405
527
  }
528
+ /** 读取版本归档字节(applyRollback 用;未捕获归档的旧版本 → GOVERNANCE_FAILED) */
529
+ async readArchive(skillName, versionId) {
530
+ const version = await this.get(skillName, versionId);
531
+ if (!version.archivePath || !await this.#fs.exists(version.archivePath)) throw new WebSkillError("GOVERNANCE_FAILED", `Version "${versionId}" of skill "${skillName}" has no captured archive (recorded before archive capture existed)`);
532
+ return this.#fs.readBinary(version.archivePath);
533
+ }
406
534
  async list(skillName) {
407
535
  const dir = dirOf(this.#root, skillName);
408
536
  if (!await this.#fs.exists(dir)) return [];
@@ -484,7 +612,7 @@ var FailureAnalyzer = class {
484
612
  };
485
613
  /**
486
614
  * 修订选项规划:patch(按诊断给具体文件变更)/ rollback(有旧版本时)/ quarantine。
487
- * 注意:任何 option 的 apply 都必须经 ApprovalWorkflow 审批后执行。
615
+ * 注意:任何 option 的 apply 都必须经 ApprovalWorkflow 审批后执行;rollback 选项(targetVersionId)经 ApprovalWorkflow.applyRollback 真实恢复文件。
488
616
  */
489
617
  var RepairPlanner = class {
490
618
  plan(input) {
@@ -522,6 +650,8 @@ var SkillStatePolicy = class {
522
650
  #audit;
523
651
  #failureThreshold;
524
652
  #loaded;
653
+ /** 缓存文件 mtime(states.json 外部变更时按 mtime 重载) */
654
+ #loadedMtimeMs;
525
655
  constructor(deps) {
526
656
  this.#root = deps.root.replace(/\/+$/, "");
527
657
  this.#fs = deps.fs;
@@ -529,17 +659,33 @@ var SkillStatePolicy = class {
529
659
  this.#failureThreshold = deps.failureThreshold ?? 3;
530
660
  }
531
661
  async #load() {
532
- if (this.#loaded) return this.#loaded;
533
662
  const path = fileOf(this.#root);
663
+ if (this.#loaded) try {
664
+ const stat = await this.#fs.stat(path);
665
+ if (stat.mtimeMs !== void 0 && stat.mtimeMs === this.#loadedMtimeMs) return this.#loaded;
666
+ } catch {
667
+ return this.#loaded;
668
+ }
534
669
  this.#loaded = await this.#fs.exists(path) ? JSON.parse(await this.#fs.readText(path)) : {
535
670
  states: {},
536
671
  failures: {}
537
672
  };
673
+ try {
674
+ this.#loadedMtimeMs = (await this.#fs.stat(path)).mtimeMs;
675
+ } catch {
676
+ this.#loadedMtimeMs = void 0;
677
+ }
538
678
  return this.#loaded;
539
679
  }
540
680
  async #persist() {
541
681
  const data = await this.#load();
542
- await this.#fs.writeText(fileOf(this.#root), JSON.stringify(data, null, 2));
682
+ const path = fileOf(this.#root);
683
+ await this.#fs.writeText(path, JSON.stringify(data, null, 2));
684
+ try {
685
+ this.#loadedMtimeMs = (await this.#fs.stat(path)).mtimeMs;
686
+ } catch {
687
+ this.#loadedMtimeMs = void 0;
688
+ }
543
689
  }
544
690
  async getState(skillName) {
545
691
  assertSafePathSegment(skillName, "skill name");
@@ -695,6 +841,17 @@ var EvaluationRunner = class {
695
841
  };
696
842
  }
697
843
  };
844
+ /**
845
+ * 治理评估专用 runtime 装配(不可信技能试用路径):
846
+ * 默认注入 ProcessSandboxExecutor(fork + --permission 真实进程隔离);
847
+ * 可配置 executor 切回 SandboxedScriptExecutor(worker_threads 能力面收敛形态)。
848
+ */
849
+ function createEvaluationRuntime(deps) {
850
+ return new WebSkillRuntime({
851
+ ...deps,
852
+ executor: deps.executor ?? new ProcessSandboxExecutor(deps.fs)
853
+ });
854
+ }
698
855
  /** 失败 trace → 回归评估任务建议(prompt 复现 + expected 错误模式) */
699
856
  function suggestFromFailedRun(run) {
700
857
  const errorPatterns = run.trace.filter((e) => e.type === "tool.failed" || e.type === "run.failed").map((e) => String(e.data?.["code"] ?? e.message ?? "")).filter(Boolean);
@@ -880,4 +1037,4 @@ function createMissHook(deps) {
880
1037
  }
881
1038
 
882
1039
  //#endregion
883
- export { AlwaysHumanApprovalPolicy, ApprovalWorkflow, CandidateStore, CompositeApprovalPolicy, DependencyGraph, DocumentSkillExtractor, EvaluationRunner, FailureAnalyzer, FsAuditLog, LlmCandidateGenerator, RepairPlanner, SCORING_WEIGHTS, SimilarityDetector, SkillScorer, SkillStatePolicy, SkillVersionStore, candidateToCatalogEntry, completeText, createMissHook, jaccardSimilarity, normalizeCandidate, normalizeCandidateFiles, normalizeRisk, parseJsonObject, readDocument, sanitizeCandidateName, suggestFromFailedRun, validateCandidate };
1040
+ export { AlwaysHumanApprovalPolicy, ApprovalWorkflow, CandidateStore, CompositeApprovalPolicy, DependencyGraph, DocumentSkillExtractor, EvaluationRunner, FailureAnalyzer, FsAuditLog, LlmCandidateGenerator, RepairPlanner, SCORING_WEIGHTS, SimilarityDetector, SkillScorer, SkillStatePolicy, SkillVersionStore, candidateToCatalogEntry, completeText, createEvaluationRuntime, createMissHook, jaccardSimilarity, normalizeCandidate, normalizeCandidateFiles, normalizeRisk, parseJsonObject, readDocument, sanitizeCandidateName, suggestFromFailedRun, validateCandidate };
@@ -1,5 +1,5 @@
1
- import { C as FileStat, I as SkillInstallSource, K as VerifyResult, T as JsonSchema, W as SkillsLockfile, _ as RenderResultRequest, o as InteractionRequest, s as InteractionResponse, v as UiBridge, w as FileSystemProvider, y as ArchiveLimits, z as SkillManifest } from "./types-CgNC-oQu-DEcIBJKG.js";
2
- import { N as NetworkPolicy, X as ScriptExecutionContext, Y as SchemaInferer, Z as ScriptExecutor, b as FsArtifactStore, d as BridgeCapabilities, et as ToolDefinition, nt as ToolResult, u as ApprovalScope, x as FsMemoryStore } from "./index-COuOu6gw.js";
1
+ import { C as FileStat, I as SkillInstallSource, K as VerifyResult, T as JsonSchema, W as SkillsLockfile, _ as RenderResultRequest, o as InteractionRequest, s as InteractionResponse, v as UiBridge, w as FileSystemProvider, y as ArchiveLimits, z as SkillManifest } from "./types-CKm5G_eQ-8W8FnP4u.js";
2
+ import { N as NetworkPolicy, Q as ScriptExecutor, X as SchemaInferer, Z as ScriptExecutionContext, b as FsArtifactStore, d as BridgeCapabilities, it as ToolResult, nt as ToolDefinition, u as ApprovalScope, x as FsMemoryStore } from "./index-gjFuBevI.js";
3
3
  import { Readable, Writable } from "node:stream";
4
4
  //#region ../node/dist/index.d.ts
5
5
  //#region src/fs/nodeFs.d.ts
@@ -25,6 +25,7 @@ declare class NodeFS implements FileSystemProvider {
25
25
  remove(p: string, options?: {
26
26
  recursive?: boolean;
27
27
  }): Promise<void>;
28
+ rename(from: string, to: string): Promise<void>;
28
29
  }
29
30
  //#endregion
30
31
  //#region src/executor/nodeScriptExecutor.d.ts
@@ -87,6 +88,43 @@ declare class SandboxedScriptExecutor implements ScriptExecutor {
87
88
  }): Promise<ToolResult>;
88
89
  }
89
90
  //#endregion
91
+ //#region src/executor/processSandboxExecutor.d.ts
92
+ interface ProcessSandboxOptions {
93
+ /** 温池大小(并发上限;执行后 kill 并补位重生),默认 2 */
94
+ poolSize?: number;
95
+ capabilities?: BridgeCapabilities;
96
+ /** 网络策略:默认 'deny-all'(权限模型无网络维度,补丁兜底;node:net 裸模块为已知残余面) */
97
+ networkPolicy?: NetworkPolicy;
98
+ /** require-approval 模式的授权询问出口 */
99
+ uiBridge?: UiBridge;
100
+ /** 授权粒度:默认 'once-per-run' */
101
+ approvalScope?: ApprovalScope;
102
+ }
103
+ /**
104
+ * child_process.fork + --permission 进程沙箱(真实进程隔离)。
105
+ * 每个子进程以 `--permission --allow-fs-read=<入口目录> --allow-fs-read=<skillRoot>
106
+ * --allow-fs-write=<artifactDir>` 启动:fs 维度由权限模型管控(experimental),
107
+ * 子进程/Worker/addons 默认禁;网络无权限维度仍靠 fetch/WebSocket patch。
108
+ * 能力桥协议与 worker_threads 沙箱同一形态(readReference/writeArtifact/confirm + 授权)。
109
+ * 温池(默认 2):同 skillRoot 复用子进程;执行后 kill 并补位重生;并发上限即池大小。
110
+ * 超时 kill(同步死循环可杀);非零退出码 → TOOL_EXECUTION_FAILED。
111
+ */
112
+ declare class ProcessSandboxExecutor implements ScriptExecutor {
113
+ #private;
114
+ constructor(fs: FileSystemProvider, options?: ProcessSandboxOptions);
115
+ get poolSize(): number;
116
+ /** 池全部子进程销毁(测试收尾/进程退出前调用) */
117
+ dispose(): Promise<void>;
118
+ loadDefinition(skillRoot: string, scriptName: string): Promise<ToolDefinition>;
119
+ execute(input: {
120
+ skillRoot: string;
121
+ scriptName: string;
122
+ args: Record<string, unknown>;
123
+ context: ScriptExecutionContext;
124
+ timeoutMs: number;
125
+ }): Promise<ToolResult>;
126
+ }
127
+ //#endregion
90
128
  //#region src/schema/oxcSchemaInferer.d.ts
91
129
  /**
92
130
  * D2 Schema 推导(OXC 静态文本分析,宿主侧执行,不进沙箱)。
@@ -163,6 +201,8 @@ declare class SkillManager {
163
201
  /** install/uninstall 成功后的变更回调(宿主接线缓存失效,如 WebSkillRuntime.invalidate) */
164
202
  onChanged?: () => void;
165
203
  });
204
+ /** 托管根目录(治理发布归档捕获等只读场景) */
205
+ get managedRoot(): string;
166
206
  install(source: SkillInstallSource, options?: {
167
207
  expectedSha256?: string;
168
208
  }): Promise<SkillManifest>;
@@ -180,42 +220,12 @@ declare class SkillManager {
180
220
  }
181
221
  //#endregion
182
222
  //#region src/skillManagement/export/archiveExporter.d.ts
223
+ /** 导出技能目录全部文件(含 manifest)为 zip/tar 归档,返回 outPath */
224
+ declare function exportArchive(fs: FileSystemProvider, skillRoot: string, options: {
225
+ format: 'zip' | 'tar';
226
+ outPath: string;
227
+ }): Promise<string>;
183
228
  /** 只解出归档中的 webskill.skill-manifest.json 条目(安装前预览) */
184
229
  declare function readArchiveManifest(fs: FileSystemProvider, archivePath: string): Promise<SkillManifest>;
185
230
  //#endregion
186
- //#region src/env.d.ts
187
- interface LlmEnvConfig {
188
- baseUrl: string;
189
- apiKey: string;
190
- model: string;
191
- }
192
- /** per-provider env 配置(baseUrl 可选,客户端自带默认) */
193
- interface ProviderEnvConfig {
194
- apiKey: string;
195
- model: string;
196
- baseUrl?: string;
197
- }
198
- /**
199
- * 读取 VITE_BASE_URL / VITE_API_KEY / VITE_MODEL_NAME;缺项返回 undefined 供测试 skip 判断。
200
- */
201
- declare function loadLlmConfigFromEnv(dotenvPath?: string): LlmEnvConfig | undefined;
202
- /** ANTHROPIC_API_KEY / ANTHROPIC_MODEL(可选 ANTHROPIC_BASE_URL);缺项返回 undefined */
203
- declare function loadAnthropicConfigFromEnv(dotenvPath?: string): ProviderEnvConfig | undefined;
204
- /** GOOGLE_API_KEY / GOOGLE_MODEL(可选 GOOGLE_BASE_URL);缺项返回 undefined */
205
- declare function loadGoogleConfigFromEnv(dotenvPath?: string): ProviderEnvConfig | undefined;
206
- interface LlmCapabilities {
207
- available: boolean;
208
- nonStreaming: boolean;
209
- reason?: string;
210
- }
211
- /**
212
- * 探测 LLM 能力(结果模块级缓存):
213
- * - available:GET /models 可达(与 checkAvailability 同语义)
214
- * - nonStreaming:最小非流式 chat completion(max_tokens=1,短超时);
215
- * HTTP 400/404 或明确不支持非流式的错误 → false
216
- * - streaming 能力由 available 推断(SSE 解析在 SDK 侧实现)
217
- * 环境变量 VITE_LLM_NON_STREAMING=0 可显式强制 nonStreaming=false(模拟流式-only 回归)。
218
- */
219
- declare function probeLlmCapabilities(config: LlmEnvConfig): Promise<LlmCapabilities>;
220
- //#endregion
221
- export { readArchiveManifest as _, LlmEnvConfig as a, OxcSchemaInferer as c, SandboxedScriptExecutor as d, SkillManager as f, probeLlmCapabilities as g, loadLlmConfigFromEnv as h, LlmCapabilities as i, ProviderEnvConfig as l, loadGoogleConfigFromEnv as m, FileArtifactStore as n, NodeFS as o, loadAnthropicConfigFromEnv as p, FileMemoryStore as r, NodeScriptExecutor as s, CliUiBridge as t, SandboxOptions as u };
231
+ export { NodeScriptExecutor as a, ProcessSandboxOptions as c, SkillManager as d, exportArchive as f, NodeFS as i, SandboxOptions as l, FileArtifactStore as n, OxcSchemaInferer as o, readArchiveManifest as p, FileMemoryStore as r, ProcessSandboxExecutor as s, CliUiBridge as t, SandboxedScriptExecutor as u };
@@ -1,4 +1,4 @@
1
- import { F as SkillDocument, G as ValidationReport, I as SkillInstallSource, M as SkillCatalog, N as SkillCatalogEntry, P as SkillDiscovery, S as DiscoveryResult, T as JsonSchema, _ as RenderResultRequest, a as InteractionPolicy, c as LlmClient, d as LlmResponse, f as LlmStreamEvent, g as RenderBlock, h as MemoryStore, i as FormField, l as LlmCompleteInput, m as LlmToolSpec, n as ArtifactStore, o as InteractionRequest, r as ChartSpec, t as Artifact, u as LlmMessage, v as UiBridge, w as FileSystemProvider, z as SkillManifest } from "./types-CgNC-oQu-DEcIBJKG.js";
1
+ import { F as SkillDocument, G as ValidationReport, I as SkillInstallSource, M as SkillCatalog, N as SkillCatalogEntry, P as SkillDiscovery, S as DiscoveryResult, T as JsonSchema, _ as RenderResultRequest, a as InteractionPolicy, c as LlmClient, d as LlmResponse, f as LlmStreamEvent, g as RenderBlock, h as MemoryStore, i as FormField, l as LlmCompleteInput, m as LlmToolSpec, n as ArtifactStore, o as InteractionRequest, r as ChartSpec, t as Artifact, u as LlmMessage, v as UiBridge, w as FileSystemProvider, z as SkillManifest } from "./types-CKm5G_eQ-8W8FnP4u.js";
2
2
  //#region ../runtime/dist/index.d.ts
3
3
  //#region src/llm/openAiCompatibleClient.d.ts
4
4
  interface OpenAiCompatibleClientConfig {
@@ -295,6 +295,12 @@ interface RuntimeRun {
295
295
  interface RunResult {
296
296
  output: string;
297
297
  run: RuntimeRun;
298
+ /** 最终消息历史(多会话延续用;含 system/user/assistant/tool) */
299
+ messages: LlmMessage[];
300
+ }
301
+ /** createSession 返回的会话句柄:跨 run 延续消息历史 */
302
+ interface RuntimeSessionHandle extends RuntimeSession {
303
+ run(prompt: string): Promise<RunResult>;
298
304
  }
299
305
  //#endregion
300
306
  //#region src/interaction/renderResult.d.ts
@@ -417,6 +423,26 @@ declare class FsMemoryStore implements MemoryStore {
417
423
  clear(scope?: string): Promise<void>;
418
424
  }
419
425
  //#endregion
426
+ //#region src/memory/serializingMemoryStore.d.ts
427
+ /**
428
+ * per-scope 串行化 MemoryStore 装饰器:同一 scope 的 get/set/delete/list
429
+ * 按 promise 链串行(并发 run 的 read-modify-write 不丢计数)。
430
+ */
431
+ declare class SerializingMemoryStore implements MemoryStore {
432
+ #private;
433
+ constructor(inner: MemoryStore);
434
+ get(scope: string, key: string): Promise<unknown>;
435
+ set(scope: string, key: string, value: unknown): Promise<void>;
436
+ delete(scope: string, key: string): Promise<void>;
437
+ list(scope: string): Promise<Array<{
438
+ key: string;
439
+ value: unknown;
440
+ }>>;
441
+ clear(scope?: string): Promise<void>;
442
+ /** scope 级原子段:read-modify-write 全段在 promise 链内串行执行(fn 收到底层 store) */
443
+ transaction<T>(scope: string, fn: (inner: MemoryStore) => Promise<T>): Promise<T>;
444
+ }
445
+ //#endregion
420
446
  //#region src/artifacts/fsArtifactStore.d.ts
421
447
  /**
422
448
  * 基于 FileSystemProvider 的 ArtifactStore:产物落盘 <root>/<runId>/<path>,
@@ -531,6 +557,8 @@ declare class CapabilityApproval {
531
557
  uiBridge?: UiBridge;
532
558
  scope?: ApprovalScope;
533
559
  });
560
+ /** run 终态清理授权记录(宿主在 run 结束后调用;同时有 LRU 上限兜底) */
561
+ clearRun(runId: string): void;
534
562
  authorize(input: {
535
563
  runId: string;
536
564
  capability: BridgeCapability;
@@ -600,6 +628,10 @@ interface RunSnapshot {
600
628
  activatedTools: ToolDefinition[];
601
629
  /** 等待中的交互(恢复时重新发起,表单重新渲染) */
602
630
  pendingInteraction: InteractionRequest;
631
+ /** $chart 等内容收集的渲染块(0.2.0 起跨 resume 保留;旧快照缺省视为空) */
632
+ renderBlocks?: RenderBlock[];
633
+ /** 交互 id 序号(resume 后续算,避免 id 冲突;旧快照缺省从 0 起) */
634
+ interactionSeq?: number;
603
635
  /** 进入 interrupted 时计算的过期时间 */
604
636
  interactionExpiresAt: string;
605
637
  config: {
@@ -620,6 +652,10 @@ interface RunSnapshotStore {
620
652
  /**
621
653
  * FileSystemProvider 后端的快照存储:<root>/<runId>.snapshot.json。
622
654
  * 坏 JSON → RUN_SNAPSHOT_INCOMPATIBLE 并自动清理坏文件;runId 过路径安全校验。
655
+ * save/list 时顺带清理已过 interactionExpiresAt 的过期快照。
656
+ *
657
+ * 数据敏感性说明:快照含完整对话历史(用户输入、工具结果、可能的凭据片段),
658
+ * 以明文 JSON 落盘于宿主提供的 fs;宿主应将其视为会话数据同等保护。
623
659
  * @experimental
624
660
  */
625
661
  declare class FsRunSnapshotStore implements RunSnapshotStore {
@@ -683,6 +719,8 @@ declare class AgentLoop {
683
719
  userPrompt: string;
684
720
  route: RouteResult;
685
721
  runId?: string;
722
+ /** 多会话历史延续:插入 system 与本轮 user 之间(不含 system 消息) */
723
+ history?: LlmMessage[];
686
724
  }): Promise<RunResult>;
687
725
  /**
688
726
  * D3 恢复:以快照重建 LoopState,重新发起等待中的交互(表单重新渲染),
@@ -740,6 +778,8 @@ declare class WebSkillRuntime {
740
778
  #private;
741
779
  constructor(deps: WebSkillRuntimeDeps);
742
780
  get session(): RuntimeSession;
781
+ /** 当前装配的脚本执行器(治理默认执行器断言等只读场景) */
782
+ get executor(): ScriptExecutor | undefined;
743
783
  /** 生命周期事件总线(只读观测) */
744
784
  get events(): EventBus;
745
785
  /**
@@ -747,8 +787,18 @@ declare class WebSkillRuntime {
747
787
  * 与 SkillManager onChanged 接线:`new SkillManager({ ..., onChanged: () => runtime.invalidate() })`。
748
788
  */
749
789
  invalidate(): void;
790
+ /**
791
+ * 多会话:session 对象的 run(prompt) 跨 run 延续消息历史(同一 session 对话上下文连续)。
792
+ * 既有 runtime.run(prompt) 保持无状态单次语义不变。
793
+ */
794
+ createSession(options?: {
795
+ sessionId?: string;
796
+ }): RuntimeSessionHandle;
750
797
  discover(): Promise<DiscoveryResult>;
751
- run(userPrompt: string): Promise<RunResult>;
798
+ run(userPrompt: string, options?: {
799
+ sessionId?: string;
800
+ history?: LlmMessage[];
801
+ }): Promise<RunResult>;
752
802
  /** D3:列出可恢复的 interrupted run(供 UI 展示"未完成任务") */
753
803
  listInterruptedRuns(): Promise<RunSnapshot[]>;
754
804
  /**
@@ -760,4 +810,4 @@ declare class WebSkillRuntime {
760
810
  resumeRun(runId: string): Promise<RunResult>;
761
811
  }
762
812
  //#endregion
763
- export { SkillStateGuard as $, LifecycleHook as A, RUN_SNAPSHOT_SCHEMA_VERSION as B, FullDisclosureRouter as C, resolveToolName as Ct, HookRunnerOptions as D, HookRunner as E, toVercelToolSpecs as Et, OpenAiCompatibleClientConfig as F, RunTerminationReason as G, RunResult as H, ProgressiveRouter as I, RuntimeSession as J, RuntimePhase as K, READ_SKILL_FILE_INPUT_SCHEMA as L, LifecycleListener as M, NetworkPolicy as N, InstalledSkillManifest as O, OpenAiCompatibleClient as P, SkillRouter as Q, READ_SKILL_FILE_TOOL as R, FsRunSnapshotStore as S, parseBridgeRequest as St, GoogleGenAiClientConfig as T, toLlmToolSpec as Tt, RunSnapshot as U, RouteResult as V, RunSnapshotStore as W, ScriptExecutionContext as X, SchemaInferer as Y, ScriptExecutor as Z, EventBus as _, fromVercelStreamPart as _t, AgentLoopConfig as a, TraceEventType as at, FsArtifactStore as b, networkUrlHost as bt, AnthropicClientConfig as c, WebSkillApi as ct, BridgeCapabilities as d, bridgeError as dt, ToolDefinition as et, BridgeCapability as f, buildRenderResult as ft, CapabilityMode as g, fromVercelResult as gt, CapabilityApproval as h, extractChartSpec as ht, AgentLoop as i, TraceEvent as it, LifecycleHookContext as j, LifecycleEvent as k, ApprovalDecision as l, WebSkillRuntime as lt, BridgeResponse as m, createWebSkillApi as mt, ASK_USER_TOOL as n, ToolResult as nt, AgentLoopDeps as o, TraceRecorder as ot, BridgeRequest as p, createScriptContext as pt, RuntimeRun as q, ASK_USER_TOOL_NAME as r, TraceClock as rt, AnthropicClient as s, VercelToolSpec as st, ASK_USER_INPUT_SCHEMA as t, ToolResolution as tt, ApprovalScope as u, WebSkillRuntimeDeps as ut, ExternalSkillProvider as v, isNetworkAllowed as vt, GoogleGenAiClient as w, schemaToForm as wt, FsMemoryStore as x, normalizeToolContent as xt, ExternalToolSource as y, mergeCatalogEntries as yt, READ_SKILL_FILE_TOOL_NAME as z };
813
+ export { SerializingMemoryStore as $, LifecycleHook as A, RUN_SNAPSHOT_SCHEMA_VERSION as B, FullDisclosureRouter as C, normalizeToolContent as Ct, HookRunnerOptions as D, toLlmToolSpec as Dt, HookRunner as E, schemaToForm as Et, OpenAiCompatibleClientConfig as F, RunTerminationReason as G, RunResult as H, ProgressiveRouter as I, RuntimeSession as J, RuntimePhase as K, READ_SKILL_FILE_INPUT_SCHEMA as L, LifecycleListener as M, NetworkPolicy as N, InstalledSkillManifest as O, toVercelToolSpecs as Ot, OpenAiCompatibleClient as P, ScriptExecutor as Q, READ_SKILL_FILE_TOOL as R, FsRunSnapshotStore as S, networkUrlHost as St, GoogleGenAiClientConfig as T, resolveToolName as Tt, RunSnapshot as U, RouteResult as V, RunSnapshotStore as W, SchemaInferer as X, RuntimeSessionHandle as Y, ScriptExecutionContext as Z, EventBus as _, extractChartSpec as _t, AgentLoopConfig as a, TraceClock as at, FsArtifactStore as b, isNetworkAllowed as bt, AnthropicClientConfig as c, TraceRecorder as ct, BridgeCapabilities as d, WebSkillRuntime as dt, SkillRouter as et, BridgeCapability as f, WebSkillRuntimeDeps as ft, CapabilityMode as g, createWebSkillApi as gt, CapabilityApproval as h, createScriptContext as ht, AgentLoop as i, ToolResult as it, LifecycleHookContext as j, LifecycleEvent as k, ApprovalDecision as l, VercelToolSpec as lt, BridgeResponse as m, buildRenderResult as mt, ASK_USER_TOOL as n, ToolDefinition as nt, AgentLoopDeps as o, TraceEvent as ot, BridgeRequest as p, bridgeError as pt, RuntimeRun as q, ASK_USER_TOOL_NAME as r, ToolResolution as rt, AnthropicClient as s, TraceEventType as st, ASK_USER_INPUT_SCHEMA as t, SkillStateGuard as tt, ApprovalScope as u, WebSkillApi as ut, ExternalSkillProvider as v, fromVercelResult as vt, GoogleGenAiClient as w, parseBridgeRequest as wt, FsMemoryStore as x, mergeCatalogEntries as xt, ExternalToolSource as y, fromVercelStreamPart as yt, READ_SKILL_FILE_TOOL_NAME as z };