@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.
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +1 -1
- package/dist/browser.d.ts +151 -4
- package/dist/browser.js +269 -30
- package/dist/{catalogComponents-Dr5dFMAb-DKH_7VPI.js → catalogComponents-DfxxfUvn-T7Ic8QFV.js} +4026 -997
- package/dist/{dist-DnYG2-eY.js → dist-BQe1uglQ.js} +498 -118
- package/dist/{dist-8oQRa8Xz.js → dist-Bev6i6Ip.js} +102 -7
- package/dist/{dist-D0qW6e40.js → dist-CFmkV45C.js} +234 -27
- package/dist/{eventTypes-DjIQpt8Y-Bj3vghj4.js → eventTypes-DbOpAECr-BjcjZVms.js} +15 -2
- package/dist/governance.d.ts +24 -3
- package/dist/governance.js +30 -11
- package/dist/{index-BwsK9lGk.d.ts → index-DXNTIa-6.d.ts} +163 -6
- package/dist/{index-Ba3xFtfz.d.ts → index-lLcCpHE-.d.ts} +2 -2
- package/dist/{index-DkbABR43.d.ts → index-znZjobkr.d.ts} +144 -76
- package/dist/index.d.ts +11 -3
- package/dist/index.js +13 -4
- package/dist/mcp.d.ts +13 -2
- package/dist/mcp.js +19 -5
- package/dist/{memoryArtifactStore-52Zn9npI-BMPYwvoy.js → memoryArtifactStore-52Zn9npI-LbCQaqyx.js} +1 -1
- package/dist/node.d.ts +3 -3
- package/dist/node.js +6 -6
- package/dist/{openUiLibrary-Bdrji9qK-D2LxmM-a.js → openUiLibrary-DURlAxjk-Do_yqg3u.js} +3 -3
- package/dist/{skillVersionStore-Bl-ElD45-CWPvGvoq.d.ts → skillVersionStore-Bl-ElD45-dMJ8Ybhb.d.ts} +1 -1
- package/dist/{testing-CYTFqkDm.js → testing-Csg5ljNm.js} +2 -2
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +2 -2
- package/dist/{types-CcxRLdJG-DCXyw1US.d.ts → types-B3n0cMZu-BDhheIhX.d.ts} +54 -6
- package/dist/ui-react.d.ts +19 -6
- package/dist/ui-react.js +156 -84
- package/dist/ui-vue.d.ts +1 -1
- package/dist/ui-vue.js +2 -2
- package/dist/ui.d.ts +4 -4
- package/dist/ui.js +3 -3
- package/dist/{webskillLitCatalog-_mugzRHx-B_54vxum.js → webskillLitCatalog-DwTwSBFt-BG7kL-Es.js} +22 -3
- 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-
|
|
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 {
|
|
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 {
|
|
2
|
-
import { Et as ScriptExecutor,
|
|
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-
|
|
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
|
-
|
|
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 {
|
|
2
|
-
import { B as bridgeError, C as ProgressiveRouter, S as OpenAiCompatibleClient, U as createWebSkillApi, a as AgentLoop, b as GoogleGenAiClient, c as CapabilityApproval,
|
|
3
|
-
import { n as MockLlmClient } from "./testing-
|
|
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
|
|
576
|
-
if (
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
727
|
-
|
|
728
|
-
|
|
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
|
|
737
|
-
if (
|
|
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
|
|
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))
|
|
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 };
|