@webskill/sdk 0.7.0 → 0.9.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 (35) hide show
  1. package/dist/agent.d.ts +1 -1
  2. package/dist/agent.js +1 -1
  3. package/dist/browser.d.ts +151 -4
  4. package/dist/browser.js +269 -30
  5. package/dist/{catalogComponents-Dr5dFMAb-DKH_7VPI.js → catalogComponents-DfxxfUvn-T7Ic8QFV.js} +4026 -997
  6. package/dist/{dist-DnYG2-eY.js → dist-BQe1uglQ.js} +498 -118
  7. package/dist/{dist-8oQRa8Xz.js → dist-Bev6i6Ip.js} +102 -7
  8. package/dist/{dist-D0qW6e40.js → dist-CFmkV45C.js} +234 -27
  9. package/dist/{eventTypes-DjIQpt8Y-Bj3vghj4.js → eventTypes-DbOpAECr-BjcjZVms.js} +15 -2
  10. package/dist/governance.d.ts +24 -3
  11. package/dist/governance.js +30 -11
  12. package/dist/{index-BwsK9lGk.d.ts → index-DXNTIa-6.d.ts} +163 -6
  13. package/dist/{index-Ba3xFtfz.d.ts → index-lLcCpHE-.d.ts} +2 -2
  14. package/dist/{index-DkbABR43.d.ts → index-znZjobkr.d.ts} +144 -76
  15. package/dist/index.d.ts +11 -3
  16. package/dist/index.js +13 -4
  17. package/dist/mcp.d.ts +13 -2
  18. package/dist/mcp.js +19 -5
  19. package/dist/{memoryArtifactStore-52Zn9npI-BMPYwvoy.js → memoryArtifactStore-52Zn9npI-LbCQaqyx.js} +1 -1
  20. package/dist/node.d.ts +3 -3
  21. package/dist/node.js +6 -6
  22. package/dist/{openUiLibrary-Bdrji9qK-D2LxmM-a.js → openUiLibrary-DURlAxjk-Do_yqg3u.js} +3 -3
  23. package/dist/{skillVersionStore-Bl-ElD45-CWPvGvoq.d.ts → skillVersionStore-Bl-ElD45-dMJ8Ybhb.d.ts} +1 -1
  24. package/dist/{testing-CYTFqkDm.js → testing-Csg5ljNm.js} +2 -2
  25. package/dist/testing.d.ts +1 -1
  26. package/dist/testing.js +2 -2
  27. package/dist/{types-CcxRLdJG-DCXyw1US.d.ts → types-B3n0cMZu-BDhheIhX.d.ts} +54 -6
  28. package/dist/ui-react.d.ts +19 -6
  29. package/dist/ui-react.js +156 -84
  30. package/dist/ui-vue.d.ts +1 -1
  31. package/dist/ui-vue.js +2 -2
  32. package/dist/ui.d.ts +4 -4
  33. package/dist/ui.js +3 -3
  34. package/dist/{webskillLitCatalog-_mugzRHx-B_54vxum.js → webskillLitCatalog-DwTwSBFt-BG7kL-Es.js} +22 -3
  35. package/package.json +2 -2
package/dist/agent.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { $ as TodoListener, A as PagePerceptionReader, B as SKILL_GENERATION_SYSTEM_PROMPT, C as PageActionRequest, D as PageAuditSink, E as PageActionUi, F as PerceptionAuditSink, G as SkillGenerator, H as SkillGenerationOutcome, I as PerceptionCaptureOptions, J as SubAgentRunner, K as SkillGeneratorOptions, L as PerceptionRecord, M as ParentBudget, N as PerceivedImage, O as PagePerceptionPolicy, P as PerceivedNode, Q as TodoList, R as PerceptionResult, S as PageActionRecord, T as PageActionToolSourceOptions, U as SkillGenerationPolicy, V as SkillCandidateSink, W as SkillGenerationToolSourceOptions, X as TodoEvent, Y as TODO_SYSTEM_PROMPT, Z as TodoItem, _ as PageActionExecutor, a as DelegationOrchestratorOptions, at as createPagePerceptionToolSource, b as PageActionPolicy, c as DelegationToolSourceOptions, ct as withDelegationOrigin, d as ImageCaptureBudget, et as TodoStatus, f as MANAGE_TODO_TOOL, g as PERCEPTION_SYSTEM_PROMPT, h as PERCEIVE_PAGE_TOOL, i as DelegationOrchestrator, it as createPageActionToolSource, j as PagePerceptionToolSourceOptions, k as PagePerceptionPolicyOptions, l as GENERATE_SKILL_TOOL, m as PAGE_ACTION_TOOL, n as DELEGATION_SYSTEM_PROMPT, nt as TodoToolSourceOptions, o as DelegationRequest, ot as createSkillGenerationToolSource, p as PAGE_ACTION_SYSTEM_PROMPT, q as SubAgentRunInput, r as DelegationBudget, rt as createDelegationToolSource, s as DelegationResult, st as createTodoToolSource, t as DELEGATE_TASK_TOOL, tt as TodoStore, u as GeneratedSkillDraft, v as PageActionKind, w as PageActionScope, x as PageActionPolicyOptions, y as PageActionOutcome, z as PerceptionScope } from "./index-Ba3xFtfz.js";
1
+ import { $ as TodoListener, A as PagePerceptionReader, B as SKILL_GENERATION_SYSTEM_PROMPT, C as PageActionRequest, D as PageAuditSink, E as PageActionUi, F as PerceptionAuditSink, G as SkillGenerator, H as SkillGenerationOutcome, I as PerceptionCaptureOptions, J as SubAgentRunner, K as SkillGeneratorOptions, L as PerceptionRecord, M as ParentBudget, N as PerceivedImage, O as PagePerceptionPolicy, P as PerceivedNode, Q as TodoList, R as PerceptionResult, S as PageActionRecord, T as PageActionToolSourceOptions, U as SkillGenerationPolicy, V as SkillCandidateSink, W as SkillGenerationToolSourceOptions, X as TodoEvent, Y as TODO_SYSTEM_PROMPT, Z as TodoItem, _ as PageActionExecutor, a as DelegationOrchestratorOptions, at as createPagePerceptionToolSource, b as PageActionPolicy, c as DelegationToolSourceOptions, ct as withDelegationOrigin, d as ImageCaptureBudget, et as TodoStatus, f as MANAGE_TODO_TOOL, g as PERCEPTION_SYSTEM_PROMPT, h as PERCEIVE_PAGE_TOOL, i as DelegationOrchestrator, it as createPageActionToolSource, j as PagePerceptionToolSourceOptions, k as PagePerceptionPolicyOptions, l as GENERATE_SKILL_TOOL, m as PAGE_ACTION_TOOL, n as DELEGATION_SYSTEM_PROMPT, nt as TodoToolSourceOptions, o as DelegationRequest, ot as createSkillGenerationToolSource, p as PAGE_ACTION_SYSTEM_PROMPT, q as SubAgentRunInput, r as DelegationBudget, rt as createDelegationToolSource, s as DelegationResult, st as createTodoToolSource, t as DELEGATE_TASK_TOOL, tt as TodoStore, u as GeneratedSkillDraft, v as PageActionKind, w as PageActionScope, x as PageActionPolicyOptions, y as PageActionOutcome, z as PerceptionScope } from "./index-lLcCpHE-.js";
2
2
  export { DELEGATE_TASK_TOOL, DELEGATION_SYSTEM_PROMPT, type DelegationBudget, DelegationOrchestrator, type DelegationOrchestratorOptions, type DelegationRequest, type DelegationResult, type DelegationToolSourceOptions, GENERATE_SKILL_TOOL, type GeneratedSkillDraft, type ImageCaptureBudget, MANAGE_TODO_TOOL, PAGE_ACTION_SYSTEM_PROMPT, PAGE_ACTION_TOOL, PERCEIVE_PAGE_TOOL, PERCEPTION_SYSTEM_PROMPT, type PageActionExecutor, type PageActionKind, type PageActionOutcome, PageActionPolicy, type PageActionPolicyOptions, type PageActionRecord, type PageActionRequest, type PageActionScope, type PageActionToolSourceOptions, type PageActionUi, type PageAuditSink, PagePerceptionPolicy, type PagePerceptionPolicyOptions, type PagePerceptionReader, type PagePerceptionToolSourceOptions, type ParentBudget, type PerceivedImage, type PerceivedNode, type PerceptionAuditSink, type PerceptionCaptureOptions, type PerceptionRecord, type PerceptionResult, type PerceptionScope, SKILL_GENERATION_SYSTEM_PROMPT, type SkillCandidateSink, type SkillGenerationOutcome, type SkillGenerationPolicy, type SkillGenerationToolSourceOptions, SkillGenerator, type SkillGeneratorOptions, type SubAgentRunInput, type SubAgentRunner, TODO_SYSTEM_PROMPT, type TodoEvent, type TodoItem, type TodoList, type TodoListener, type TodoStatus, TodoStore, type TodoToolSourceOptions, createDelegationToolSource, createPageActionToolSource, createPagePerceptionToolSource, createSkillGenerationToolSource, createTodoToolSource, withDelegationOrigin };
package/dist/agent.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as parseSkillMarkdown, O as messageOf, T as isValidSkillName, m as WebSkillError } from "./dist-8oQRa8Xz.js";
1
+ import { M as messageOf, P as parseSkillMarkdown, h as WebSkillError, k as isValidSkillName } from "./dist-Bev6i6Ip.js";
2
2
 
3
3
  //#region ../agent/dist/index.js
4
4
  const STATUSES = [
package/dist/browser.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { A as ArchiveLimits, F as FileStat, I as FileSystemProvider, _ as MemoryStore, _t as UnsignedPolicy, bt as WebSkillError, c as InteractionResponse, ht as TrustedKeyStore, l as LlmClient, m as LlmStreamEvent, o as InteractionPolicy, p as LlmResponse, pt as SkillsLockfile, rt as SkillInstallSource, s as InteractionRequest, st as SkillManifest, u as LlmCompleteInput, x as UiBridge, y as RenderResultRequest, yt as VerifyResult } from "./types-CcxRLdJG-DCXyw1US.js";
2
- import { Et as ScriptExecutor, Fn as parseBridgeRequest, Kt as ToolResult, O as ExternalSkillProvider, Tt as ScriptExecutionContext, Wt as ToolDefinition, Y as NetworkPolicy, _ as BridgeCapabilities, b as BridgeResponse, cn as WebSkillApi, f as ApprovalScope, k as ExternalToolSource, pn as bridgeError, y as BridgeRequest } from "./index-DkbABR43.js";
3
- import { A as PagePerceptionReader, C as PageActionRequest, I as PerceptionCaptureOptions, P as PerceivedNode, R as PerceptionResult, _ as PageActionExecutor, w as PageActionScope, y as PageActionOutcome, z as PerceptionScope } from "./index-Ba3xFtfz.js";
1
+ import { Ct as WebSkillError, I as FileStat, L as FileSystemProvider, St as VerifyResult, _ as MemoryStore, bt as UnsignedPolicy, c as InteractionResponse, gt as SkillsLockfile, j as ArchiveLimits, l as LlmClient, m as LlmStreamEvent, o as InteractionPolicy, ot as SkillInstallSource, p as LlmResponse, s as InteractionRequest, u as LlmCompleteInput, ut as SkillManifest, vt as TrustedKeyStore, x as UiBridge, y as RenderResultRequest } from "./types-B3n0cMZu-BDhheIhX.js";
2
+ import { Et as ScriptExecutor, O as ExternalSkillProvider, Tt as ScriptExecutionContext, Vn as parseBridgeRequest, Y as NetworkPolicy, Yt as ToolResult, _ as BridgeCapabilities, _n as bridgeError, b as BridgeResponse, f as ApprovalScope, fn as WebSkillApi, k as ExternalToolSource, qt as ToolDefinition, y as BridgeRequest } from "./index-znZjobkr.js";
3
+ import { A as PagePerceptionReader, C as PageActionRequest, I as PerceptionCaptureOptions, O as PagePerceptionPolicy, P as PerceivedNode, R as PerceptionResult, _ as PageActionExecutor, w as PageActionScope, y as PageActionOutcome, z as PerceptionScope } from "./index-lLcCpHE-.js";
4
4
  //#region ../browser/dist/index.d.ts
5
5
  //#region src/fs/featureDetection.d.ts
6
6
  /** 检测当前环境是否可用 OPFS(navigator.storage.getDirectory) */
@@ -86,6 +86,11 @@ declare class BrowserSkillManager {
86
86
  constructor(deps: {
87
87
  fs: FileSystemProvider;
88
88
  managedRoot: string;
89
+ /**
90
+ * 宿主的只读技能根(如 `/skills`)。Library 列的是 Catalog 全集,
91
+ * 不告诉管理器这些根,导出本地技能会报「is not installed」(FR-19.5)。
92
+ */
93
+ skillRoots?: readonly string[];
89
94
  fetchImpl?: typeof fetch;
90
95
  /** 归档体积三重上限(缺省 DEFAULT_ARCHIVE_LIMITS) */
91
96
  archiveLimits?: ArchiveLimits;
@@ -111,6 +116,8 @@ declare class BrowserSkillManager {
111
116
  });
112
117
  install(source: SkillInstallSource, options?: {
113
118
  expectedSha256?: string;
119
+ /** 缺省接受替换(升级/重装靠它);`reject` 供「新建」这类不该覆盖的调用方声明意图 */
120
+ replace?: 'allow' | 'reject';
114
121
  }): Promise<SkillManifest>;
115
122
  /**
116
123
  * 浏览器导出(单技能与包集同构:始终产出含 webskill.skill-pack.json 的 zip 字节,
@@ -120,6 +127,12 @@ declare class BrowserSkillManager {
120
127
  uninstall(name: string): Promise<void>;
121
128
  verifyIntegrity(name: string): Promise<VerifyResult>;
122
129
  listInstalled(): Promise<SkillsLockfile>;
130
+ /**
131
+ * 库里已有的技能名:managed 目录 + 宿主声明的只读根。读失败按「库为空」处理,不阻断安装。
132
+ * 与 `listInstalled()` 的区别是**含本地技能**(后者只看安装账本)。
133
+ * @experimental
134
+ */
135
+ listSkillNames(): Promise<string[]>;
123
136
  }
124
137
  //#endregion
125
138
  //#region src/skillManagement/zipExtract.d.ts
@@ -643,4 +656,138 @@ declare function openMemoryEncryptionKey(name?: string): Promise<CryptoKey>;
643
656
  /** 删除本地数据加密密钥;清除画像与记录时一并调用,避免留下解不开的旧密文 @experimental */
644
657
  declare function deleteMemoryEncryptionKey(name?: string): Promise<void>;
645
658
  //#endregion
646
- export { type BridgeCapabilities, type BridgeRequest, type BridgeResponse, BrowserSkillManager, BrowserWorkerScriptExecutor, type CaptureFailure, type CaptureLevel, type CapturedImage, type ChromeBuiltinAvailability, ChromeBuiltinLlmClient, type CompressResult, type ConfiguredLlmClient, type DictationAvailability, type DictationOptions, type DictationSession, type DomPageActionExecutor, type DomPageActionOptions, type DomPerceptionReader, type DomPerceptionReaderOptions, IframeWorkerLike, type LlmClientConfig, type LlmEntryConfig, type MainToWorkerMessage, OpfsProvider, type SandboxMode, type SerializedError, TsTranspiler, type TypeScriptSupportOptions, WORKER_BOOTSTRAP_SOURCE, type WorkerEvent, type WorkerFactory, type WorkerLike, type WorkerRequest, WorkerRuntimeClient, type WorkerRuntimeClientDeps, type WorkerRuntimeHostOverrides, type WorkerScopeLike, WorkerUiBridge, bridgeError, captureElementImage, checkDictationAvailability, compressImageToBudget, createDomPageActionExecutor, createDomPerceptionReader, createEncryptedMemoryStore, createIframeWorker, createLlmClient, deleteMemoryEncryptionKey, extractZipWeb, generateMemoryEncryptionKey, installWebSkillNavigator, isCapturableElement, isCaptureFailure, isEncryptedMemoryValue, isOpfsAvailable, openMemoryEncryptionKey, parseBridgeRequest, parseMainMessage, parseWorkerEvent, probeChromeBuiltinAvailability, sha256HexWeb, startDictation, startWorkerRuntimeHost };
659
+ //#region src/host/portMatrix.d.ts
660
+ /**
661
+ * 浏览器宿主装配(分册 17)。
662
+ *
663
+ * 本子路径**刻意不 import** `ChatbotHostAdapter` / `ConsoleBackend` / `ConnectFacade`:
664
+ * 它们分别在 `@webskill/chatbot` 与 `@webskill/console`,而 sdk 依赖不到那两个包
665
+ * (反过来让 sdk 依赖 app 包会把依赖方向倒过来,见偏差 D-18)。
666
+ * 这里只声明**结构等价**的形状,靠 TS 的结构类型系统在宿主侧自动对上。
667
+ *
668
+ * 代价是结构等价靠手工维持:上游接口加了必填字段而这里没跟,
669
+ * 只有宿主赋值时才会报错。因此配了一条测试侧的真实赋值断言(T-17-A),
670
+ * 那条判据是本方案成立的前提,不是可选项。
671
+ */
672
+ /**
673
+ * 端口矩阵覆盖的宿主面。
674
+ * `chatbot-config` 与 `chatbot-adapter` 分开:两者是不同的接口(`ChatbotConfig` / `ChatbotHostAdapter`),
675
+ * 把它们归成一面会让探测去错误的对象上找字段,永远报 missing。
676
+ */
677
+ type HostSurface = 'chatbot-adapter' | 'chatbot-config' | 'console-backend' | 'connect-facade';
678
+ /** 本版只区分浏览器与 Node:矩阵要能表达「tar 在 node 上是应有的」,否则 not-applicable 会变成无条件结论 */
679
+ type HostKind = 'browser' | 'node';
680
+ type PortApplicability = 'expected' | 'not-applicable';
681
+ interface PortSpec {
682
+ id: string;
683
+ surface: HostSurface;
684
+ /** 在该 surface 上探测的字段名 */
685
+ key: string;
686
+ applicability: Readonly<Record<HostKind, PortApplicability>>;
687
+ /** `not-applicable` 时是原因,`expected` 时是接入指引 */
688
+ note: string;
689
+ }
690
+ /**
691
+ * 端口 × 宿主类型的**唯一定义**(AC-17.4)。
692
+ * About 页与装配工厂都读这一份;护栏 `port-matrix-single-source` 盯着不许再抄。
693
+ */
694
+ declare const HOST_PORT_MATRIX: readonly PortSpec[];
695
+ /**
696
+ * 第四态 `unknown` 表示「这个 surface 没交给我看」,不是「没接」。
697
+ * About 页拿不到 `ChatbotHostAdapter` 实例(console 不依赖 chatbot),
698
+ * 只能自检两个面——把没看到的报成「未接线」是错的说法。
699
+ */
700
+ type PortStatus = 'wired' | 'missing' | 'not-applicable' | 'unknown';
701
+ interface PortReport extends PortSpec {
702
+ status: PortStatus;
703
+ }
704
+ interface InspectHostWiringInput {
705
+ kind?: HostKind;
706
+ /** 只对提供了的 surface 出结论;未提供的整面记为 `unknown` */
707
+ surfaces: Partial<Record<HostSurface, Record<string, unknown> | undefined>>;
708
+ }
709
+ declare function inspectHostWiring(input: InspectHostWiringInput): PortReport[];
710
+ /** 缺口 = 该接却没接的项;`unknown` 不算缺口,没看到不等于没接 */
711
+ declare function missingPorts(reports: readonly PortReport[]): PortReport[];
712
+ //#endregion
713
+ //#region src/host/createBrowserChatbotHost.d.ts
714
+ /**
715
+ * 浏览器宿主装配工厂(分册 17 FR-17.1 / 偏差 D-18)。
716
+ *
717
+ * 三个目标接口分属 chatbot 与 console,sdk 依赖不到它们;反过来让 sdk 依赖 app 包
718
+ * 会倒转依赖方向,让 chatbot 依赖 console 又违反 FR-20.5。所以这里只声明**结构等价**的形状,
719
+ * 宿主侧 `const a: ChatbotHostAdapter = bundle.chatbotAdapter` 靠结构类型自动成立。
720
+ *
721
+ * 结构等价是**手工维持**的——上游加必填字段这里不会红,只有宿主赋值时才报错。
722
+ * `packages/browser/test/hostAssembly.test.ts` 里做了真实赋值(T-17-A),
723
+ * 那条判据是本方案成立的前提。
724
+ */
725
+ /**
726
+ * 与 `ChatbotHostAdapter` 结构等价的最小形状。
727
+ *
728
+ * `navigation` 是**必填**:跳 console 是宿主的路由决定,工厂造不出合理缺省。
729
+ * `skillCandidates` **不在这里**——它长在 `ChatbotConfig` 上,不是 adapter 的字段。
730
+ */
731
+ interface HostChatbotAdapterShape {
732
+ storage: FileSystemProvider;
733
+ skillRoots: string[];
734
+ navigation: HostNavigationShape;
735
+ skillManager: BrowserSkillManager;
736
+ pagePerception?: PagePerceptionPolicy;
737
+ }
738
+ /** 与 `ChatbotHostAdapter['navigation']` 结构等价 */
739
+ interface HostNavigationShape {
740
+ openConsole(): void;
741
+ openConsoleTrace?(runId: string): void;
742
+ openConsoleCandidate?(candidateId: string): void;
743
+ }
744
+ /** 与 `ConsoleBackend` 结构等价的最小形状 */
745
+ interface HostConsoleBackendShape {
746
+ catalog(): Promise<unknown>;
747
+ install?: unknown;
748
+ exportSkill?: unknown;
749
+ exportSkillTar?: unknown;
750
+ verifyIntegrity?: unknown;
751
+ writeSkillFile?: unknown;
752
+ listVersions?: unknown;
753
+ runs?: unknown;
754
+ sessions?: unknown;
755
+ }
756
+ /** 与 `ConnectFacade` 结构等价的最小形状 */
757
+ interface HostConnectFacadeShape {
758
+ listEndpoints(): Promise<unknown[]>;
759
+ listTools(): Promise<unknown[]>;
760
+ temporarySkills?: unknown;
761
+ }
762
+ interface BrowserHostBundle {
763
+ readonly chatbotAdapter: HostChatbotAdapterShape;
764
+ readonly consoleBackend: HostConsoleBackendShape;
765
+ readonly connectFacade: HostConnectFacadeShape;
766
+ }
767
+ /**
768
+ * 逃生口(FR-17.1 硬要求):任一件都可替换,其余仍由工厂提供。
769
+ * 没有它,宿主会绕过工厂自建全套装配——那等于工厂没做。
770
+ */
771
+ interface BrowserHostOverrides {
772
+ chatbotAdapter?: HostChatbotAdapterShape;
773
+ consoleBackend?: HostConsoleBackendShape;
774
+ connectFacade?: HostConnectFacadeShape;
775
+ }
776
+ interface BrowserHostOptions {
777
+ /** 必填:没有合理默认值 */
778
+ fs: FileSystemProvider;
779
+ /** 受管技能目录(安装 / 回滚的作用点) */
780
+ managedRoot: string;
781
+ /** 只读技能根;本地技能从这里被发现 */
782
+ skillRoots: string[];
783
+ /** 必填:跳 console 是宿主的路由,工厂无从缺省 */
784
+ navigation: HostNavigationShape;
785
+ /** opt-in 的能力保持可选:强制必填只会逼宿主传 undefined,把类型检查变成形式 */
786
+ pagePerception?: PagePerceptionPolicy;
787
+ consoleBackend?: HostConsoleBackendShape;
788
+ connectFacade?: HostConnectFacadeShape;
789
+ overrides?: BrowserHostOverrides;
790
+ }
791
+ declare function createBrowserChatbotHost(options: BrowserHostOptions): BrowserHostBundle;
792
+ //#endregion
793
+ export { type BridgeCapabilities, type BridgeRequest, type BridgeResponse, type BrowserHostBundle, type BrowserHostOptions, type BrowserHostOverrides, BrowserSkillManager, BrowserWorkerScriptExecutor, type CaptureFailure, type CaptureLevel, type CapturedImage, type ChromeBuiltinAvailability, ChromeBuiltinLlmClient, type CompressResult, type ConfiguredLlmClient, type DictationAvailability, type DictationOptions, type DictationSession, type DomPageActionExecutor, type DomPageActionOptions, type DomPerceptionReader, type DomPerceptionReaderOptions, HOST_PORT_MATRIX, type HostChatbotAdapterShape, type HostConnectFacadeShape, type HostConsoleBackendShape, type HostKind, type HostSurface, IframeWorkerLike, type InspectHostWiringInput, type LlmClientConfig, type LlmEntryConfig, type MainToWorkerMessage, OpfsProvider, type PortApplicability, type PortReport, type PortSpec, type PortStatus, type SandboxMode, type SerializedError, TsTranspiler, type TypeScriptSupportOptions, WORKER_BOOTSTRAP_SOURCE, type WorkerEvent, type WorkerFactory, type WorkerLike, type WorkerRequest, WorkerRuntimeClient, type WorkerRuntimeClientDeps, type WorkerRuntimeHostOverrides, type WorkerScopeLike, WorkerUiBridge, bridgeError, captureElementImage, checkDictationAvailability, compressImageToBudget, createBrowserChatbotHost, createDomPageActionExecutor, createDomPerceptionReader, createEncryptedMemoryStore, createIframeWorker, createLlmClient, deleteMemoryEncryptionKey, extractZipWeb, generateMemoryEncryptionKey, inspectHostWiring, installWebSkillNavigator, isCapturableElement, isCaptureFailure, isEncryptedMemoryValue, isOpfsAvailable, missingPorts, openMemoryEncryptionKey, parseBridgeRequest, parseMainMessage, parseWorkerEvent, probeChromeBuiltinAvailability, sha256HexWeb, startDictation, startWorkerRuntimeHost };
package/dist/browser.js CHANGED
@@ -1,6 +1,6 @@
1
- import { A as parseSkillMarkdown, B as unzipWithLimits, H as verifyManifest, L as resolveInsideRoot, M as readResponseWithLimit, N as readSkillSignature, O as messageOf, T as isValidSkillName, U as verifySkillSignature, 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 { B as bridgeError, C as ProgressiveRouter, S as OpenAiCompatibleClient, U as createWebSkillApi, a as AgentLoop, b as GoogleGenAiClient, c as CapabilityApproval, ct as normalizeToolError, g as FsRunSnapshotStore, h as FsMemoryStore, it as networkPolicyLibSource, lt as parseBridgeRequest, m as FsArtifactStore, nt as mergeCatalogEntries, o as AnthropicClient, st as normalizeToolContent } from "./dist-D0qW6e40.js";
3
- import { n as MockLlmClient } from "./testing-CYTFqkDm.js";
1
+ import { D as exportSkills, F as parseSkillPackManifest, G as unzipWithLimits, I as readResponseWithLimit, J as verifySkillSignature, K as validateSkills, L as readSkillSignature, M as messageOf, O as isAtomicTempPath, P as parseSkillMarkdown, T as detectSkillArchiveShapeFromFs, V as resolveInsideRoot, b as buildManifest, c as SKILL_MANIFEST_FILE, d as SKILL_PACK_FILE, g as assertRemoteUrlAllowed, h as WebSkillError, i as MANIFEST_EXCLUDED_FILES, k as isValidSkillName, p as SkillDiscovery, q as verifyManifest, s as SKILLS_LOCKFILE, v as atomicWriteText, y as buildCatalog } from "./dist-Bev6i6Ip.js";
2
+ import { B as bridgeError, C as ProgressiveRouter, S as OpenAiCompatibleClient, U as createWebSkillApi, a as AgentLoop, b as GoogleGenAiClient, c as CapabilityApproval, dt as parseBridgeRequest, g as FsRunSnapshotStore, h as FsMemoryStore, it as mergeCatalogEntries, lt as normalizeToolContent, m as FsArtifactStore, o as AnthropicClient, ot as networkPolicyLibSource, ut as normalizeToolError } from "./dist-CFmkV45C.js";
3
+ import { n as MockLlmClient } from "./testing-Csg5ljNm.js";
4
4
 
5
5
  //#region ../browser/dist/index.js
6
6
  /** 检测当前环境是否可用 OPFS(navigator.storage.getDirectory) */
@@ -155,6 +155,20 @@ var OpfsProvider = class {
155
155
  }
156
156
  async rename(from, to) {
157
157
  if ((await this.stat(from)).type === "directory") throw new WebSkillError("FS_PERMISSION_DENIED", `rename of directories is not supported on OPFS: ${from}`);
158
+ const fromSegments = this.#segments(from);
159
+ const fromName = fromSegments.pop();
160
+ if (!fromName) throw new WebSkillError("FS_NOT_FOUND", `Invalid path: ${from}`);
161
+ const toSegments = this.#segments(to);
162
+ const toName = toSegments.pop();
163
+ if (!toName) throw new WebSkillError("FS_NOT_FOUND", `Invalid path: ${to}`);
164
+ const file = await (await this.#walkDir(`/${fromSegments.join("/")}`, false)).getFileHandle(fromName);
165
+ const mover = file.move;
166
+ if (`/${fromSegments.join("/")}` === `/${toSegments.join("/")}` && typeof mover === "function") {
167
+ await this.#wrap(from, async () => {
168
+ await mover.call(file, toName);
169
+ });
170
+ return;
171
+ }
158
172
  await this.writeBinary(to, await this.readBinary(from));
159
173
  await this.remove(from);
160
174
  }
@@ -444,23 +458,23 @@ async function sha256HexWeb(data) {
444
458
  const digest = await crypto.subtle.digest("SHA-256", bytes);
445
459
  return [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, "0")).join("");
446
460
  }
447
- /** 递归拷贝目录(含子目录与二进制文件) */
461
+ /** 递归拷贝目录(含子目录与二进制文件;原子写中断残留的 `.tmp-*` 不拷贝) */
448
462
  async function copyDir(fs, from, to) {
449
463
  await fs.mkdir(to);
450
464
  for (const entry of await fs.list(from)) {
451
465
  const name = entry.path.split("/").pop() ?? "";
452
466
  if (entry.type === "directory") await copyDir(fs, entry.path, `${to}/${name}`);
453
- else await fs.writeBinary(`${to}/${name}`, await fs.readBinary(entry.path));
467
+ else if (!isAtomicTempPath(name)) await fs.writeBinary(`${to}/${name}`, await fs.readBinary(entry.path));
454
468
  }
455
469
  }
456
- /** 递归列出目录内全部文件(相对路径,posix 分隔) */
470
+ /** 递归列出目录内全部文件(相对路径,posix 分隔;原子写中断残留的 `.tmp-*` 不计入) */
457
471
  async function listFiles(fs, root, prefix = "") {
458
472
  const out = [];
459
473
  for (const entry of await fs.list(root)) {
460
474
  const name = entry.path.split("/").pop() ?? "";
461
475
  const rel = prefix === "" ? name : `${prefix}/${name}`;
462
476
  if (entry.type === "directory") out.push(...await listFiles(fs, entry.path, rel));
463
- else out.push(rel);
477
+ else if (!isAtomicTempPath(name)) out.push(rel);
464
478
  }
465
479
  return out;
466
480
  }
@@ -490,7 +504,8 @@ const PRESERVED_INSTALL_CODES = /* @__PURE__ */ new Set([
490
504
  "SIGNATURE_MALFORMED",
491
505
  "SIGNATURE_UNTRUSTED_KEY",
492
506
  "SIGNATURE_MISMATCH",
493
- "SIGNATURE_UNSUPPORTED"
507
+ "SIGNATURE_UNSUPPORTED",
508
+ "SKILL_DUPLICATE_NAME"
494
509
  ]);
495
510
  const asInstallFailed = (e) => e instanceof WebSkillError && (e.code === "INSTALL_FAILED" || e.code === "TOOL_UNSUPPORTED" || PRESERVED_INSTALL_CODES.has(e.code)) ? e : new WebSkillError("INSTALL_FAILED", `Install failed: ${messageOf(e)}`, e);
496
511
  const lockfilePath = (root) => `${root}/${SKILLS_LOCKFILE}`;
@@ -510,6 +525,8 @@ const EMPTY_TRUSTED_KEYS = {
510
525
  var BrowserSkillManager = class {
511
526
  #fs;
512
527
  #managedRoot;
528
+ /** 只读技能根(宿主自带的本地技能):参与导出与依赖存在性判定,但不可卸载 */
529
+ #skillRoots;
513
530
  #fetchImpl;
514
531
  #archiveLimits;
515
532
  #onChanged;
@@ -519,6 +536,7 @@ var BrowserSkillManager = class {
519
536
  constructor(deps) {
520
537
  this.#fs = deps.fs;
521
538
  this.#managedRoot = deps.managedRoot.replace(/\/+$/, "");
539
+ this.#skillRoots = (deps.skillRoots ?? []).map((root) => root.replace(/\/+$/, ""));
522
540
  this.#fetchImpl = deps.fetchImpl;
523
541
  this.#archiveLimits = deps.archiveLimits;
524
542
  this.#onChanged = deps.onChanged;
@@ -572,17 +590,16 @@ var BrowserSkillManager = class {
572
590
  const contentDir = `${stagingRoot}/content`;
573
591
  await fs.mkdir(contentDir);
574
592
  await extractZipWeb(fs, data, contentDir, this.#archiveLimits);
575
- const packFilePath = `${contentDir}/${SKILL_PACK_FILE}`;
576
- if (await fs.exists(packFilePath)) return (await this.#installPack({
577
- contentDir,
578
- manifest: parseSkillPackManifest(await fs.readText(packFilePath))
579
- }, source, stagingRoot))[0];
580
- let skillDir = contentDir;
581
- if (!await fs.exists(`${contentDir}/SKILL.md`)) {
582
- const dirs = (await fs.list(contentDir)).filter((e) => e.type === "directory");
583
- if (dirs.length === 1 && await fs.exists(`${dirs[0]?.path}/SKILL.md`)) skillDir = dirs[0].path;
584
- else throw new WebSkillError("INSTALL_FAILED", "Archive does not contain a SKILL.md at its root or in a single top-level directory");
593
+ const detection = await detectSkillArchiveShapeFromFs(fs, contentDir);
594
+ if (detection.shape === "invalid") throw new WebSkillError("INSTALL_FAILED", detection.reason ?? "Archive layout is not recognised");
595
+ if (detection.shape === "pack-set") {
596
+ const packRoot = detection.rootDir === void 0 ? contentDir : `${contentDir}/${detection.rootDir}`;
597
+ return (await this.#installPack({
598
+ contentDir: packRoot,
599
+ manifest: parseSkillPackManifest(await fs.readText(`${packRoot}/${SKILL_PACK_FILE}`))
600
+ }, source, stagingRoot))[0];
585
601
  }
602
+ const skillDir = detection.rootDir === void 0 ? contentDir : `${contentDir}/${detection.rootDir}`;
586
603
  let name;
587
604
  let version;
588
605
  try {
@@ -593,13 +610,18 @@ var BrowserSkillManager = class {
593
610
  throw new WebSkillError("INSTALL_FAILED", `Failed to read skill name from SKILL.md: ${messageOf(e)}`, e);
594
611
  }
595
612
  if (!isValidSkillName(name)) throw new WebSkillError("INSTALL_FAILED", `Invalid skill name in SKILL.md (path traversal rejected): ${JSON.stringify(name)}`);
613
+ if (options?.replace === "reject" && await fs.exists(`${this.#managedRoot}/${name}`)) throw new WebSkillError("SKILL_DUPLICATE_NAME", `A skill named "${name}" is already installed. Installing it again replaces the existing files; use the packages flow if that is intended.`);
596
614
  const finalRoot = `${stagingRoot}/final`;
597
615
  const finalDir = `${finalRoot}/${name}`;
598
616
  await copyDir(fs, skillDir, finalDir);
599
- const report = await validateSkills(fs, [finalRoot]);
617
+ const report = await validateSkills(fs, [finalRoot], { extraKnownSkillNames: await this.listSkillNames() });
600
618
  if (!report.ok) {
601
- const errors = report.issues.filter((i) => i.severity === "error");
602
- throw new WebSkillError("INSTALL_FAILED", `Skill "${name}" failed validation: ${errors.map((i) => i.message).join("; ")}`, errors);
619
+ const errors = report.issues.filter((i) => i.severity === "error" && i.code !== "SKILL_UNKNOWN_DEPENDENCY");
620
+ for (const issue of report.issues) if (issue.code === "SKILL_UNKNOWN_DEPENDENCY") this.#onWarning?.({
621
+ skill: name,
622
+ message: issue.message
623
+ });
624
+ if (errors.length > 0) throw new WebSkillError("INSTALL_FAILED", `Skill "${name}" failed validation: ${errors.map((i) => i.message).join("; ")}`, errors);
603
625
  }
604
626
  const manifest = await this.#createManifest(finalDir, {
605
627
  name,
@@ -714,6 +736,21 @@ var BrowserSkillManager = class {
714
736
  throw asInstallFailed(e);
715
737
  }
716
738
  }
739
+ /** 技能的真实根:先 managed,再只读根。都没有则 undefined */
740
+ async #resolveSkillRoot(name) {
741
+ const managed = `${this.#managedRoot}/${name}`;
742
+ if (await this.#fs.exists(managed)) return {
743
+ root: managed,
744
+ managed: true
745
+ };
746
+ for (const base of this.#skillRoots) {
747
+ const candidate = `${base}/${name}`;
748
+ if (await this.#fs.exists(candidate)) return {
749
+ root: candidate,
750
+ managed: false
751
+ };
752
+ }
753
+ }
717
754
  /**
718
755
  * 浏览器导出(单技能与包集同构:始终产出含 webskill.skill-pack.json 的 zip 字节,
719
756
  * 统一安装路径;保存/下载由应用层处理)。
@@ -721,11 +758,13 @@ var BrowserSkillManager = class {
721
758
  async exportArchive(names) {
722
759
  const list = Array.isArray(names) ? names : [names];
723
760
  if (list.length === 0) throw new WebSkillError("EXPORT_FAILED", "exportArchive requires at least one skill name");
724
- const roots = list.map((name) => {
761
+ const roots = [];
762
+ for (const name of list) {
725
763
  if (!isValidSkillName(name)) throw new WebSkillError("EXPORT_FAILED", `Invalid skill name (path traversal rejected): ${JSON.stringify(name)}`);
726
- return `${this.#managedRoot}/${name}`;
727
- });
728
- for (const [index, root] of roots.entries()) if (!await this.#fs.exists(root)) throw new WebSkillError("EXPORT_FAILED", `Skill "${list[index]}" is not installed`);
764
+ const resolved = await this.#resolveSkillRoot(name);
765
+ if (resolved === void 0) throw new WebSkillError("EXPORT_FAILED", `Skill "${name}" is not installed`);
766
+ roots.push(resolved.root);
767
+ }
729
768
  return exportSkills(this.#fs, {
730
769
  roots,
731
770
  manifestBuilder: (root) => this.#readManifest(root)
@@ -733,8 +772,10 @@ var BrowserSkillManager = class {
733
772
  }
734
773
  async uninstall(name) {
735
774
  if (!isValidSkillName(name)) throw new WebSkillError("UNINSTALL_FAILED", `Invalid skill name (path traversal rejected): ${JSON.stringify(name)}`);
736
- const targetDir = `${this.#managedRoot}/${name}`;
737
- if (!await this.#fs.exists(targetDir)) throw new WebSkillError("UNINSTALL_FAILED", `Skill "${name}" is not installed`);
775
+ const resolved = await this.#resolveSkillRoot(name);
776
+ if (resolved === void 0) throw new WebSkillError("UNINSTALL_FAILED", `Skill "${name}" is not installed`);
777
+ if (!resolved.managed) throw new WebSkillError("UNINSTALL_FAILED", `Skill "${name}" ships with the host application and is not managed by the skill manager; remove it from the host's skill root instead.`);
778
+ const targetDir = resolved.root;
738
779
  try {
739
780
  await this.#fs.remove(targetDir, { recursive: true });
740
781
  await this.#removeLockEntry(name);
@@ -763,6 +804,22 @@ var BrowserSkillManager = class {
763
804
  throw new WebSkillError("INTEGRITY_FAILED", `Skills lockfile at ${path} is corrupted: ${messageOf(e)}`, e);
764
805
  }
765
806
  }
807
+ /**
808
+ * 库里已有的技能名:managed 目录 + 宿主声明的只读根。读失败按「库为空」处理,不阻断安装。
809
+ * 与 `listInstalled()` 的区别是**含本地技能**(后者只看安装账本)。
810
+ * @experimental
811
+ */
812
+ async listSkillNames() {
813
+ const names = [];
814
+ for (const root of [this.#managedRoot, ...this.#skillRoots]) {
815
+ if (!await this.#fs.exists(root).catch(() => false)) continue;
816
+ for (const stat of await this.#fs.list(root).catch(() => [])) {
817
+ const name = stat.path.split("/").pop() ?? "";
818
+ if (stat.type === "directory" && isValidSkillName(name)) names.push(name);
819
+ }
820
+ }
821
+ return names;
822
+ }
766
823
  async #createManifest(skillRoot, input) {
767
824
  const files = [];
768
825
  for (const rel of (await listFiles(this.#fs, skillRoot)).sort()) {
@@ -782,12 +839,21 @@ var BrowserSkillManager = class {
782
839
  files,
783
840
  sha256: sha256HexWeb
784
841
  });
785
- await this.#fs.writeText(`${skillRoot}/${SKILL_MANIFEST_FILE}`, JSON.stringify(manifest, null, 2));
842
+ await atomicWriteText(this.#fs, `${skillRoot}/${SKILL_MANIFEST_FILE}`, JSON.stringify(manifest, null, 2));
786
843
  return manifest;
787
844
  }
788
845
  async #readManifest(skillRoot) {
789
846
  const path = `${skillRoot}/${SKILL_MANIFEST_FILE}`;
790
- if (!await this.#fs.exists(path)) throw new WebSkillError("INTEGRITY_FAILED", `Skill manifest not found at ${path} (was the skill installed via BrowserSkillManager?)`);
847
+ if (!await this.#fs.exists(path)) {
848
+ const name = skillRoot.split("/").pop() ?? skillRoot;
849
+ return this.#createManifest(skillRoot, {
850
+ name,
851
+ source: {
852
+ type: "local",
853
+ path: skillRoot
854
+ }
855
+ });
856
+ }
791
857
  try {
792
858
  return JSON.parse(await this.#fs.readText(path));
793
859
  } catch (e) {
@@ -2670,6 +2736,179 @@ async function deleteMemoryEncryptionKey(name = "user-profile") {
2670
2736
  db.close();
2671
2737
  }
2672
2738
  }
2739
+ /**
2740
+ * 端口 × 宿主类型的**唯一定义**(AC-17.4)。
2741
+ * About 页与装配工厂都读这一份;护栏 `port-matrix-single-source` 盯着不许再抄。
2742
+ */
2743
+ const HOST_PORT_MATRIX = [
2744
+ {
2745
+ id: "install / uninstall",
2746
+ surface: "console-backend",
2747
+ key: "install",
2748
+ applicability: {
2749
+ browser: "expected",
2750
+ node: "expected"
2751
+ },
2752
+ note: "Wire ConsoleBackend.install to let the console install and remove skills."
2753
+ },
2754
+ {
2755
+ id: "export (zip)",
2756
+ surface: "console-backend",
2757
+ key: "exportSkill",
2758
+ applicability: {
2759
+ browser: "expected",
2760
+ node: "expected"
2761
+ },
2762
+ note: "Wire ConsoleBackend.exportSkill to enable zip export."
2763
+ },
2764
+ {
2765
+ id: "export (tar)",
2766
+ surface: "console-backend",
2767
+ key: "exportSkillTar",
2768
+ applicability: {
2769
+ browser: "not-applicable",
2770
+ node: "expected"
2771
+ },
2772
+ note: "Browsers have no tar toolchain in the platform; zip export covers the same need."
2773
+ },
2774
+ {
2775
+ id: "integrity",
2776
+ surface: "console-backend",
2777
+ key: "verifyIntegrity",
2778
+ applicability: {
2779
+ browser: "expected",
2780
+ node: "expected"
2781
+ },
2782
+ note: "Wire ConsoleBackend.verifyIntegrity to enable the integrity report."
2783
+ },
2784
+ {
2785
+ id: "editing",
2786
+ surface: "console-backend",
2787
+ key: "writeSkillFile",
2788
+ applicability: {
2789
+ browser: "expected",
2790
+ node: "expected"
2791
+ },
2792
+ note: "Wire ConsoleBackend.writeSkillFile to enable in-place skill editing."
2793
+ },
2794
+ {
2795
+ id: "versions",
2796
+ surface: "console-backend",
2797
+ key: "listVersions",
2798
+ applicability: {
2799
+ browser: "expected",
2800
+ node: "expected"
2801
+ },
2802
+ note: "Wire ConsoleBackend.listVersions to show version history and rollback."
2803
+ },
2804
+ {
2805
+ id: "runs",
2806
+ surface: "console-backend",
2807
+ key: "runs",
2808
+ applicability: {
2809
+ browser: "expected",
2810
+ node: "expected"
2811
+ },
2812
+ note: "Wire ConsoleBackend.runs to read run history; without it the runs pages have no source."
2813
+ },
2814
+ {
2815
+ id: "sessions",
2816
+ surface: "console-backend",
2817
+ key: "sessions",
2818
+ applicability: {
2819
+ browser: "expected",
2820
+ node: "expected"
2821
+ },
2822
+ note: "Wire ConsoleBackend.sessions to list chat sessions."
2823
+ },
2824
+ {
2825
+ id: "page perception",
2826
+ surface: "chatbot-adapter",
2827
+ key: "pagePerception",
2828
+ applicability: {
2829
+ browser: "expected",
2830
+ node: "not-applicable"
2831
+ },
2832
+ note: "Page perception reads the live DOM; there is no page outside a browser."
2833
+ },
2834
+ {
2835
+ id: "skill candidates",
2836
+ surface: "chatbot-config",
2837
+ key: "skillCandidates",
2838
+ applicability: {
2839
+ browser: "expected",
2840
+ node: "expected"
2841
+ },
2842
+ note: "Wire skillCandidates so skill-miss suggestions can be reviewed in the console."
2843
+ },
2844
+ {
2845
+ id: "remote endpoints",
2846
+ surface: "connect-facade",
2847
+ key: "listEndpoints",
2848
+ applicability: {
2849
+ browser: "expected",
2850
+ node: "expected"
2851
+ },
2852
+ note: "Wire ConnectFacade.listEndpoints to manage remote MCP endpoints."
2853
+ },
2854
+ {
2855
+ id: "page-declared skills",
2856
+ surface: "connect-facade",
2857
+ key: "temporarySkills",
2858
+ applicability: {
2859
+ browser: "expected",
2860
+ node: "not-applicable"
2861
+ },
2862
+ note: "Page-declared temporary skills come from the document; Node hosts have none."
2863
+ }
2864
+ ];
2865
+ function inspectHostWiring(input) {
2866
+ const kind = input.kind ?? "browser";
2867
+ return HOST_PORT_MATRIX.map((spec) => {
2868
+ if (!(spec.surface in input.surfaces)) return {
2869
+ ...spec,
2870
+ status: "unknown"
2871
+ };
2872
+ if (spec.applicability[kind] === "not-applicable") return {
2873
+ ...spec,
2874
+ status: "not-applicable"
2875
+ };
2876
+ const surface = input.surfaces[spec.surface];
2877
+ const wired = surface !== void 0 && surface[spec.key] !== void 0;
2878
+ return {
2879
+ ...spec,
2880
+ status: wired ? "wired" : "missing"
2881
+ };
2882
+ });
2883
+ }
2884
+ /** 缺口 = 该接却没接的项;`unknown` 不算缺口,没看到不等于没接 */
2885
+ function missingPorts(reports) {
2886
+ return reports.filter((report) => report.status === "missing");
2887
+ }
2888
+ function createBrowserChatbotHost(options) {
2889
+ const { fs, managedRoot, skillRoots, navigation, overrides } = options;
2890
+ const chatbotAdapter = {
2891
+ storage: fs,
2892
+ skillRoots,
2893
+ navigation,
2894
+ skillManager: new BrowserSkillManager({
2895
+ fs,
2896
+ managedRoot,
2897
+ skillRoots
2898
+ }),
2899
+ ...options.pagePerception !== void 0 ? { pagePerception: options.pagePerception } : {}
2900
+ };
2901
+ const consoleBackend = options.consoleBackend ?? { catalog: async () => ({ entries: [] }) };
2902
+ const connectFacade = options.connectFacade ?? {
2903
+ listEndpoints: async () => [],
2904
+ listTools: async () => []
2905
+ };
2906
+ return {
2907
+ chatbotAdapter: overrides?.chatbotAdapter ?? chatbotAdapter,
2908
+ consoleBackend: overrides?.consoleBackend ?? consoleBackend,
2909
+ connectFacade: overrides?.connectFacade ?? connectFacade
2910
+ };
2911
+ }
2673
2912
 
2674
2913
  //#endregion
2675
- export { BrowserSkillManager, BrowserWorkerScriptExecutor, ChromeBuiltinLlmClient, IframeWorkerLike, OpfsProvider, TsTranspiler, WORKER_BOOTSTRAP_SOURCE, WorkerRuntimeClient, WorkerUiBridge, bridgeError, captureElementImage, checkDictationAvailability, compressImageToBudget, createDomPageActionExecutor, createDomPerceptionReader, createEncryptedMemoryStore, createIframeWorker, createLlmClient, deleteMemoryEncryptionKey, extractZipWeb, generateMemoryEncryptionKey, installWebSkillNavigator, isCapturableElement, isCaptureFailure, isEncryptedMemoryValue, isOpfsAvailable, openMemoryEncryptionKey, parseBridgeRequest, parseMainMessage, parseWorkerEvent, probeChromeBuiltinAvailability, sha256HexWeb, startDictation, startWorkerRuntimeHost };
2914
+ export { BrowserSkillManager, BrowserWorkerScriptExecutor, ChromeBuiltinLlmClient, HOST_PORT_MATRIX, IframeWorkerLike, OpfsProvider, TsTranspiler, WORKER_BOOTSTRAP_SOURCE, WorkerRuntimeClient, WorkerUiBridge, bridgeError, captureElementImage, checkDictationAvailability, compressImageToBudget, createBrowserChatbotHost, createDomPageActionExecutor, createDomPerceptionReader, createEncryptedMemoryStore, createIframeWorker, createLlmClient, deleteMemoryEncryptionKey, extractZipWeb, generateMemoryEncryptionKey, inspectHostWiring, installWebSkillNavigator, isCapturableElement, isCaptureFailure, isEncryptedMemoryValue, isOpfsAvailable, missingPorts, openMemoryEncryptionKey, parseBridgeRequest, parseMainMessage, parseWorkerEvent, probeChromeBuiltinAvailability, sha256HexWeb, startDictation, startWorkerRuntimeHost };