@xopcai/xopc 0.0.274 → 0.0.275
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/browser-ext/_locales/en/messages.json +215 -0
- package/dist/browser-ext/_locales/zh_CN/messages.json +215 -0
- package/dist/browser-ext/dist/assets/{auth-O8RiOF3l.js → auth-ClQTK565.js} +97 -38
- package/dist/browser-ext/dist/assets/{sidepanel-C86O7q5Y.css → sidepanel-CeGqObOa.css} +41 -20
- package/dist/browser-ext/dist/background.js +36 -4
- package/dist/browser-ext/dist/sidepanel.html +2 -2
- package/dist/browser-ext/dist/sidepanel.js +416 -299
- package/dist/browser-ext/manifest.json +6 -4
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BckaANxj.js → agent-avatar-dicebear-Dx6x7MXq.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-B8eyC6K1.js → agent-defaults-settings-panel-BuxTpjkf.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-CSWj_yo1.js → agents-_f9HEOol.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-DY-Zbgmt.js → app-management-settings-panel-BYKWXcVl.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-CoJR7ZRl.js → appearance-settings-BmhSJc4X.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-DYTnK9lL.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-BwAlRT53.js → archive-plugin-BY6ncIeE.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-R835uxgL.js → attachment-load-B6cw8KtO.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-BEZy0P_u.js → automations-page-D1WwsSf3.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-CjF56MI_.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-CESFx3yb.js → binary-plugins-CC-wYm0K.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-DDJcf2wR.js → block-editor-D8rh9KNe.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automations-page-BH4lSfr5.js → browser-automations-page-CMrffyct.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-1onvP1Se.js +8 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-C9ZSJxjr.js +8 -0
- package/dist/gateway/static/root/assets/channels-settings-CvLTnI99.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-D8U97O95.js → chat-terminal-dock-F_dUdZ8l.js} +2 -2
- package/dist/gateway/static/root/assets/connectors-page-D7NHV8B2.js +2 -0
- package/dist/gateway/static/root/assets/{date-picker-7sDSMswL.js → date-picker-MHuajwQ-.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-DMIC86ZW.js → dependency-picker-BcMJJI9X.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-BtdiY5jK.js → desktop-pet-DlNm_7H0.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-D_B8azDH.js → desktop-pet-settings-BI1JQMnE.js} +1 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-Cp5jO5B_.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-CoFKb01d.js → extension-debug-page-DZr0GkkA.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CEkNsCAY.js → extension-page-QsHoQ6VX.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-Bi2R8P5j.js → extension-settings-page-I2YX4Tzb.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-GwfQu8rN.js +1 -0
- package/dist/gateway/static/root/assets/{heartbeat-settings-DQtelFiU.js → heartbeat-settings-D-hVYXzL.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-SEW_0k8Q.js +1 -0
- package/dist/gateway/static/root/assets/{index-SxqsTD4i.js → index-DfZZLrWp.js} +34 -34
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BuYmZS1K.js → keyboard-shortcuts-settings-D_I-hiG2.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-BcY7wIHs.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-CExnZyGZ.js → local-apps-page-DniZuXJJ.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-CA5ArMoN.js → logs-page-DIiOMrJ_.js} +2 -2
- package/dist/gateway/static/root/assets/{management-settings-1UiJPrkX.js → management-settings-BPw41YX6.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-nNFOk9HL.js → media-plugins-BoP3LSQz.js} +1 -1
- package/dist/gateway/static/root/assets/note-detail-panel-BI2xr54R.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-CM7Ns8i1.js +8 -0
- package/dist/gateway/static/root/assets/{page-tabs-CRombigq.js → page-tabs-B21WfV92.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-Bcuj43lk.js → preview-open-alternatives-BZoDpPqV.js} +1 -1
- package/dist/gateway/static/root/assets/{proactive-card-Cb3Xeoyx.js → proactive-card-Bw9CbzUX.js} +1 -1
- package/dist/gateway/static/root/assets/{proactive-page-TbF9KVpm.js → proactive-page-Czw_CEDB.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-jOECabbf.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-Ck9j5q0x.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-2xcpaLTC.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-BudlvBu-.js → runtime-tools-settings-panel-Bz5gIRjy.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-Ch3MEX4h.js → schema-form-CqM0ntNm.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-CE9MK60k.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-D0grhQan.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-CIA1AA-A.js → settings-form-section-LqcDYJ2m.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-B0Khoduh.js → settings-page-BpvBmheO.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-CYuqNzWH.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-Cj9XWg-X.js → share-preview-page-F3qhAryJ.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-B4wSoQM3.js +1 -0
- package/dist/gateway/static/root/assets/{skill-reload-api-BM4Ezjbx.js → skill-reload-api-C3LD7fkR.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-Dyh1kf9t.js → skills-page-D9fI548d.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-DsQZkMti.js → skills-page.utils-DZNmyYqU.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-BSho_Tpk.js → system-settings-panel-CMsmFOhV.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-DRwTJ8E0.js +1 -0
- package/dist/gateway/static/root/assets/{tunnel-api-4DUHxSQG.js → tunnel-api-DGaqXwql.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-BG8Yx7hj.js → use-autosave-bXCl0Y0j.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-B3RjDSri.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-DYXwDhHq.js → voice-api-key-field-Cx9rl7mP.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-CQqjzaRo.js → work-discovery-overlay-ywJpaqKp.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-C5H-Fd-U.js → workflow-run-setup-panel-DyGukxOL.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-CifIqO2B.js +6 -0
- package/dist/gateway/static/root/index.html +1 -1
- package/dist/package.js +1 -1
- package/dist/src/agent/child-agent-factory.d.ts +3 -0
- package/dist/src/agent/child-agent-factory.js +2 -1
- package/dist/src/agent/external-tools/endpoint-provider.js +1 -1
- package/dist/src/agent/tools/factory.d.ts +1 -0
- package/dist/src/agent/tools/factory.js +21 -4
- package/dist/src/agent/workflow/workflow-child-tools.js +2 -0
- package/dist/src/browser/providers/browser-ext-install.d.ts +1 -1
- package/dist/src/browser/providers/browser-ext-install.js +8 -3
- package/dist/src/browser/providers/realtime-extension.d.ts +4 -1
- package/dist/src/browser/providers/realtime-extension.js +26 -10
- package/dist/src/browser/readiness.d.ts +4 -1
- package/dist/src/browser/readiness.js +11 -5
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/gateway/gateway-workflow-host.types.d.ts +2 -0
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/routes/browser.js +24 -11
- package/dist/src/gateway/hono/routes/endpoint-tools.js +9 -0
- package/dist/src/gateway/hono/routes/models.js +6 -0
- package/dist/src/gateway/hono/routes/voice.js +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/providers/model-catalog-persistence.js +4 -0
- package/dist/src/providers/model-catalog-types.d.ts +1 -0
- package/dist/src/providers/xopc-cloud-model-source.js +12 -1
- package/dist/src/storage/sqlite/endpoint-session-binding-repository.d.ts +1 -0
- package/dist/src/storage/sqlite/endpoint-session-binding-repository.js +9 -1
- package/dist/src/storage/sqlite/index.d.ts +1 -1
- package/dist/src/storage/sqlite/index.js +2 -2
- package/dist/src/workflows/service/workflow-run-service.js +4 -1
- package/package.json +3 -3
- package/dist/gateway/static/root/assets/apps-page-CSMvkuot.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-CpaI13J7.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-CbTooPd2.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-C4LZWHhv.js +0 -8
- package/dist/gateway/static/root/assets/channels-settings-BAljmSa7.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-CVRMjNNr.js +0 -2
- package/dist/gateway/static/root/assets/device-pairing-wizard-Dmh3Nh4d.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-q9p3sduo.js +0 -1
- package/dist/gateway/static/root/assets/home-page-COpGnTFZ.js +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-DV_17Zxc.js +0 -2
- package/dist/gateway/static/root/assets/note-detail-panel-B5OQ0fBY.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-CVPPMVDl.js +0 -8
- package/dist/gateway/static/root/assets/project-detail-page-B9OQ2l9x.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-DCqSTNkY.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-d9Fg70gX.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-D8RiQ-ag.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DVH_l6Hr.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-COJFl4N_.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-_OuE6A0G.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-B5HWM12k.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-IjVyv5jj.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-D1hMyPsY.js +0 -6
|
@@ -30,12 +30,15 @@ const STAGING_MAX_AGE_MS = 3600 * 1e3;
|
|
|
30
30
|
const INSTALLED_ARTIFACT_NAMES = [
|
|
31
31
|
"manifest.json",
|
|
32
32
|
"dist",
|
|
33
|
-
"icons"
|
|
33
|
+
"icons",
|
|
34
|
+
"_locales"
|
|
34
35
|
];
|
|
35
36
|
const BROWSER_EXT_REQUIRED_FILES = [
|
|
36
37
|
"manifest.json",
|
|
37
38
|
"dist/background.js",
|
|
38
|
-
"dist/sidepanel.html"
|
|
39
|
+
"dist/sidepanel.html",
|
|
40
|
+
"_locales/en/messages.json",
|
|
41
|
+
"_locales/zh_CN/messages.json"
|
|
39
42
|
];
|
|
40
43
|
function moduleDir() {
|
|
41
44
|
return dirname(fileURLToPath(import.meta.url));
|
|
@@ -53,7 +56,8 @@ function browserExtContentHash(dir) {
|
|
|
53
56
|
const relativePaths = [
|
|
54
57
|
"manifest.json",
|
|
55
58
|
...collectFiles("dist"),
|
|
56
|
-
...collectFiles("icons")
|
|
59
|
+
...collectFiles("icons"),
|
|
60
|
+
...collectFiles("_locales")
|
|
57
61
|
].sort();
|
|
58
62
|
for (const relativePath of relativePaths) {
|
|
59
63
|
hash.update(relativePath);
|
|
@@ -220,6 +224,7 @@ function copyBundledTree(src, dest) {
|
|
|
220
224
|
mkdirSync(dest, { recursive: true });
|
|
221
225
|
copyBundledFile(join(src, "manifest.json"), join(dest, "manifest.json"));
|
|
222
226
|
copyBundledDirectory(join(src, "dist"), join(dest, "dist"));
|
|
227
|
+
copyBundledDirectory(join(src, "_locales"), join(dest, "_locales"));
|
|
223
228
|
for (const icon of BROWSER_EXT_ICON_FILES) {
|
|
224
229
|
const iconSrc = join(src, "icons", icon);
|
|
225
230
|
if (existsSync(iconSrc)) copyBundledFile(iconSrc, join(dest, "icons", icon));
|
|
@@ -21,9 +21,12 @@ export declare class RealtimeExtensionBrowserProvider {
|
|
|
21
21
|
expectedProtocolVersion: number;
|
|
22
22
|
extensionVersion: string;
|
|
23
23
|
principalId: string;
|
|
24
|
+
endpointCount: number;
|
|
25
|
+
selectionRequired: boolean;
|
|
24
26
|
transport: "gateway-realtime";
|
|
25
27
|
};
|
|
26
28
|
shutdown(): Promise<void>;
|
|
27
29
|
private endpointForInput;
|
|
28
|
-
private
|
|
30
|
+
private defaultEndpoint;
|
|
31
|
+
private browserEndpoints;
|
|
29
32
|
}
|
|
@@ -14,14 +14,18 @@ var RealtimeExtensionBrowserProvider = class {
|
|
|
14
14
|
async start() {}
|
|
15
15
|
async waitForConnection(timeoutMs = this.connectionTimeout) {
|
|
16
16
|
const deadline = Date.now() + timeoutMs;
|
|
17
|
-
while (
|
|
17
|
+
while (this.browserEndpoints().length === 0) {
|
|
18
18
|
if (Date.now() >= deadline) throw new Error(`Extension connection timeout after ${timeoutMs}ms. Open the xopc Chrome extension and connect it to this Gateway.`);
|
|
19
19
|
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
async send(input, timeoutMs = this.commandTimeout, visualFallback = true) {
|
|
23
23
|
const endpoint = this.endpointForInput(input);
|
|
24
|
-
if (!endpoint)
|
|
24
|
+
if (!endpoint) {
|
|
25
|
+
if (input.target?.kind === "endpoint") throw new Error(`The Chrome endpoint bound to this Session is offline (${input.target.endpointId}). Reconnect that browser or bind another one.`);
|
|
26
|
+
if (this.browserEndpoints().length > 1) throw new Error("Multiple Chrome extensions are connected. Attach this Session to a tab or choose a browser device first.");
|
|
27
|
+
throw new Error("Extension not connected to this Gateway. Open the xopc Chrome extension and connect it first.");
|
|
28
|
+
}
|
|
25
29
|
const tool = this.runtime.registry.getTool(endpoint.endpointId, BROWSER_CONTROL_ENDPOINT_TOOL_NAME);
|
|
26
30
|
if (!tool) throw new Error("Connected browser extension does not support authenticated Realtime browser control. Reload or update the extension.");
|
|
27
31
|
const id = crypto.randomUUID();
|
|
@@ -51,17 +55,20 @@ var RealtimeExtensionBrowserProvider = class {
|
|
|
51
55
|
}
|
|
52
56
|
}
|
|
53
57
|
isConnected() {
|
|
54
|
-
return
|
|
58
|
+
return this.browserEndpoints().length > 0;
|
|
55
59
|
}
|
|
56
60
|
getConnectionStatus() {
|
|
57
|
-
const
|
|
61
|
+
const endpoints = this.browserEndpoints();
|
|
62
|
+
const endpoint = endpoints.length === 1 ? endpoints[0] : void 0;
|
|
58
63
|
return {
|
|
59
|
-
socketConnected:
|
|
60
|
-
connected:
|
|
61
|
-
protocolVersion:
|
|
64
|
+
socketConnected: endpoints.length > 0,
|
|
65
|
+
connected: endpoints.length > 0,
|
|
66
|
+
protocolVersion: endpoints.length > 0 ? 4 : null,
|
|
62
67
|
expectedProtocolVersion: 4,
|
|
63
68
|
extensionVersion: endpoint?.appVersion ?? null,
|
|
64
69
|
principalId: endpoint?.principalId ?? null,
|
|
70
|
+
endpointCount: endpoints.length,
|
|
71
|
+
selectionRequired: endpoints.length > 1,
|
|
65
72
|
transport: "gateway-realtime"
|
|
66
73
|
};
|
|
67
74
|
}
|
|
@@ -73,10 +80,19 @@ var RealtimeExtensionBrowserProvider = class {
|
|
|
73
80
|
if (!binding || !endpoint || endpoint.principalId !== binding.principalId) return void 0;
|
|
74
81
|
return endpoint;
|
|
75
82
|
}
|
|
76
|
-
|
|
83
|
+
if (input.target?.kind === "endpoint") {
|
|
84
|
+
const endpoint = this.runtime.registry.get(input.target.endpointId);
|
|
85
|
+
if (!endpoint || endpoint.kind !== "browser" || !endpoint.tools.some((tool) => tool.descriptor.name === "browser.control")) return;
|
|
86
|
+
return endpoint;
|
|
87
|
+
}
|
|
88
|
+
return this.defaultEndpoint();
|
|
89
|
+
}
|
|
90
|
+
defaultEndpoint() {
|
|
91
|
+
const endpoints = this.browserEndpoints();
|
|
92
|
+
return endpoints.length === 1 ? endpoints[0] : void 0;
|
|
77
93
|
}
|
|
78
|
-
|
|
79
|
-
return this.runtime.registry.list().filter((endpoint) => endpoint.kind === "browser" && endpoint.tools.some((tool) => tool.descriptor.name === "browser.control")).sort((left, right) => right.lastHeartbeatAt - left.lastHeartbeatAt)
|
|
94
|
+
browserEndpoints() {
|
|
95
|
+
return this.runtime.registry.list().filter((endpoint) => endpoint.kind === "browser" && endpoint.tools.some((tool) => tool.descriptor.name === "browser.control")).sort((left, right) => right.lastHeartbeatAt - left.lastHeartbeatAt);
|
|
80
96
|
}
|
|
81
97
|
};
|
|
82
98
|
//#endregion
|
|
@@ -12,4 +12,7 @@ export declare class BrowserNotReadyError extends Error {
|
|
|
12
12
|
constructor(hint: BrowserSetupHint);
|
|
13
13
|
}
|
|
14
14
|
export declare function buildBrowserSetupDeepLink(driver: BrowserDriverKind): string;
|
|
15
|
-
export declare function checkBrowserReadiness(cfg: Config | undefined
|
|
15
|
+
export declare function checkBrowserReadiness(cfg: Config | undefined, options?: {
|
|
16
|
+
extensionConnected?: boolean;
|
|
17
|
+
checkExtensionInstall?: boolean;
|
|
18
|
+
}): Promise<BrowserNotReadyError | null>;
|
|
@@ -14,17 +14,23 @@ var BrowserNotReadyError = class extends Error {
|
|
|
14
14
|
function buildBrowserSetupDeepLink(driver) {
|
|
15
15
|
return `/settings/agent-browser?driver=${driver}`;
|
|
16
16
|
}
|
|
17
|
-
async function checkBrowserReadiness(cfg) {
|
|
17
|
+
async function checkBrowserReadiness(cfg, options = {}) {
|
|
18
18
|
if (!cfg?.browser.enabled) return null;
|
|
19
19
|
const driver = cfg.browser.driver;
|
|
20
20
|
let detail = null;
|
|
21
21
|
let reason = null;
|
|
22
22
|
try {
|
|
23
23
|
if (driver.kind === "extension") {
|
|
24
|
-
|
|
25
|
-
if (
|
|
26
|
-
reason = "
|
|
27
|
-
detail = "Chrome extension
|
|
24
|
+
if (options.extensionConnected) return null;
|
|
25
|
+
if (options.checkExtensionInstall === false) {
|
|
26
|
+
reason = "extension_not_connected";
|
|
27
|
+
detail = "No authenticated Chrome extension endpoint is connected.";
|
|
28
|
+
} else {
|
|
29
|
+
const { browserExtDoctor } = await import("./providers/browser-ext-install.js");
|
|
30
|
+
if (!(await browserExtDoctor()).installed) {
|
|
31
|
+
reason = "extension_not_installed";
|
|
32
|
+
detail = "Chrome extension artifacts are not installed.";
|
|
33
|
+
}
|
|
28
34
|
}
|
|
29
35
|
} else if (driver.kind === "playwright") if (driver.executablePath) await access(driver.executablePath);
|
|
30
36
|
else {
|
|
@@ -4,8 +4,8 @@ import { saveConfig } from "../../config/loader.js";
|
|
|
4
4
|
import { resolveGatewayLocalClientHost } from "../../config/gateway-bind.js";
|
|
5
5
|
import { formatExamples, register } from "../registry.js";
|
|
6
6
|
import "../../config/index.js";
|
|
7
|
-
import { provisionEagerRuntimes } from "../../runtime-tools/bootstrap.js";
|
|
8
7
|
import { colors } from "../utils/colors.js";
|
|
8
|
+
import { provisionEagerRuntimes } from "../../runtime-tools/bootstrap.js";
|
|
9
9
|
import { initWorkspace } from "../utils/init-workspace.js";
|
|
10
10
|
import { setupModel } from "./onboard/model.js";
|
|
11
11
|
import { getChannelConfigurators } from "./onboard/channels/registry.js";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Config } from '../config/schema.js';
|
|
2
|
+
import type { EndpointToolRuntime } from '../endpoint-tools/index.js';
|
|
2
3
|
import type { MessageBus } from '../infra/bus/index.js';
|
|
3
4
|
import type { SessionStore } from '../session/store.js';
|
|
4
5
|
export interface GatewayWorkflowAgentSurface {
|
|
@@ -10,6 +11,7 @@ export interface GatewayWorkflowHost {
|
|
|
10
11
|
readonly currentWorkspacePath: string;
|
|
11
12
|
readonly messageBusInstance: MessageBus;
|
|
12
13
|
readonly agentService: GatewayWorkflowAgentSurface;
|
|
14
|
+
readonly endpointTools?: EndpointToolRuntime;
|
|
13
15
|
emit(event: string, payload: unknown): void;
|
|
14
16
|
readonly sessionIndexInstance: {
|
|
15
17
|
getStore(): SessionStore;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { shouldSilence, stripHeartbeatToken } from "../../heartbeat/tokens.js";
|
|
4
|
-
import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
|
|
5
4
|
import { isWithinActiveHours } from "../../heartbeat/active-hours.js";
|
|
6
5
|
import { isHeartbeatContentEmpty } from "../../heartbeat/content-check.js";
|
|
6
|
+
import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
|
|
7
7
|
import { createHeartbeatWake } from "../../heartbeat/wake.js";
|
|
8
8
|
import { resolveHeartbeatMdPath } from "../workspace-heartbeat-path.js";
|
|
9
9
|
import { readFile } from "fs/promises";
|
|
@@ -10,12 +10,12 @@ import { getGatewayPrincipal } from "../../security/gateway-principal.js";
|
|
|
10
10
|
import { getConnInfo } from "@hono/node-server/conninfo";
|
|
11
11
|
//#region src/gateway/hono/routes/browser.ts
|
|
12
12
|
/** Browser Control status, approvals, and driver diagnostics. */
|
|
13
|
-
async function extensionStatus(service) {
|
|
14
|
-
const
|
|
15
|
-
const
|
|
13
|
+
async function extensionStatus(service, includeLocalArtifacts) {
|
|
14
|
+
const endpoints = service.endpointTools.registry.list().filter((item) => item.kind === "browser" && item.tools.some((tool) => tool.descriptor.name === "browser.control")).sort((left, right) => right.lastHeartbeatAt - left.lastHeartbeatAt);
|
|
15
|
+
const endpoint = endpoints[0];
|
|
16
|
+
const connected = endpoints.length > 0;
|
|
16
17
|
const extensionVersion = endpoint?.appVersion ?? null;
|
|
17
|
-
const
|
|
18
|
-
const doctor = await browserExtDoctor({ runtimeExtensionVersion: extensionVersion ?? void 0 });
|
|
18
|
+
const doctor = includeLocalArtifacts ? await import("../../../browser/providers/browser-ext-install.js").then(({ browserExtDoctor }) => browserExtDoctor({ runtimeExtensionVersion: extensionVersion ?? void 0 })) : void 0;
|
|
19
19
|
return {
|
|
20
20
|
running: true,
|
|
21
21
|
socketConnected: connected,
|
|
@@ -24,7 +24,15 @@ async function extensionStatus(service) {
|
|
|
24
24
|
protocolVersion: connected ? 4 : null,
|
|
25
25
|
expectedProtocolVersion: 4,
|
|
26
26
|
extensionVersion,
|
|
27
|
-
|
|
27
|
+
endpoints: endpoints.map((item) => ({
|
|
28
|
+
endpointId: item.endpointId,
|
|
29
|
+
principalId: item.principalId,
|
|
30
|
+
displayName: item.displayName,
|
|
31
|
+
platform: item.platform,
|
|
32
|
+
appVersion: item.appVersion,
|
|
33
|
+
lastHeartbeatAt: item.lastHeartbeatAt
|
|
34
|
+
})),
|
|
35
|
+
artifacts: { ...doctor ? {
|
|
28
36
|
installed: doctor.installed,
|
|
29
37
|
bundledAvailable: doctor.bundledAvailable,
|
|
30
38
|
extensionDir: doctor.extensionDir,
|
|
@@ -33,9 +41,9 @@ async function extensionStatus(service) {
|
|
|
33
41
|
needsRefresh: doctor.needsRefresh,
|
|
34
42
|
needsChromeReload: doctor.needsChromeReload,
|
|
35
43
|
nativeHost: doctor.nativeHost
|
|
36
|
-
},
|
|
44
|
+
} : {} },
|
|
37
45
|
bridgeHeld: false,
|
|
38
|
-
refCount:
|
|
46
|
+
refCount: endpoints.length,
|
|
39
47
|
transport: "gateway-realtime"
|
|
40
48
|
};
|
|
41
49
|
}
|
|
@@ -148,7 +156,7 @@ function registerBrowserRoutes(authenticated, deps) {
|
|
|
148
156
|
});
|
|
149
157
|
authenticated.get("/api/browser/extension-status", async (c) => {
|
|
150
158
|
try {
|
|
151
|
-
return c.json(await extensionStatus(service));
|
|
159
|
+
return c.json(await extensionStatus(service, isLocalOwnerRequest(c, service)));
|
|
152
160
|
} catch (error) {
|
|
153
161
|
return c.json({
|
|
154
162
|
running: false,
|
|
@@ -160,6 +168,7 @@ function registerBrowserRoutes(authenticated, deps) {
|
|
|
160
168
|
});
|
|
161
169
|
authenticated.get("/api/browser/status", async (c) => {
|
|
162
170
|
const config = service.currentConfig.browser;
|
|
171
|
+
const localManagementAvailable = isLocalOwnerRequest(c, service);
|
|
163
172
|
if (!config.enabled) return c.json({
|
|
164
173
|
ok: true,
|
|
165
174
|
payload: {
|
|
@@ -168,15 +177,19 @@ function registerBrowserRoutes(authenticated, deps) {
|
|
|
168
177
|
state: "disabled"
|
|
169
178
|
}
|
|
170
179
|
});
|
|
171
|
-
const
|
|
172
|
-
const driverStatus = config.driver.kind === "extension" ? await extensionStatus(service).catch((error) => ({ error: error instanceof Error ? error.message : String(error) })) : config.driver.kind === "playwright" ? await import("../../../browser/providers/playwright-doctor.js").then(({ playwrightChromiumDoctor }) => playwrightChromiumDoctor()) : void 0;
|
|
180
|
+
const driverStatus = config.driver.kind === "extension" ? await extensionStatus(service, localManagementAvailable).catch((error) => ({ error: error instanceof Error ? error.message : String(error) })) : config.driver.kind === "playwright" ? await import("../../../browser/providers/playwright-doctor.js").then(({ playwrightChromiumDoctor }) => playwrightChromiumDoctor()) : void 0;
|
|
173
181
|
const extensionConnected = config.driver.kind === "extension" ? driverStatus.connected === true : true;
|
|
182
|
+
const readiness = await checkBrowserReadiness(service.currentConfig, {
|
|
183
|
+
extensionConnected,
|
|
184
|
+
checkExtensionInstall: localManagementAvailable
|
|
185
|
+
});
|
|
174
186
|
const extensionProtocolDetail = config.driver.kind === "extension" && "socketConnected" in driverStatus && driverStatus.socketConnected && !driverStatus.connected ? `Chrome extension protocol ${driverStatus.protocolVersion ?? "unknown"} does not match ${driverStatus.expectedProtocolVersion ?? "the gateway"}. Reload the extension in Chrome.` : void 0;
|
|
175
187
|
return c.json({
|
|
176
188
|
ok: true,
|
|
177
189
|
payload: {
|
|
178
190
|
enabled: true,
|
|
179
191
|
driverKind: config.driver.kind,
|
|
192
|
+
localManagementAvailable,
|
|
180
193
|
state: !readiness && extensionConnected ? "ready" : "needs_attention",
|
|
181
194
|
reason: readiness?.hint.reason ?? (extensionConnected ? void 0 : "extension_not_connected"),
|
|
182
195
|
detail: readiness?.hint.detail ?? extensionProtocolDetail,
|
|
@@ -177,6 +177,15 @@ function registerEndpointToolRoutes(authenticated, deps) {
|
|
|
177
177
|
message: "Invalid endpoint binding"
|
|
178
178
|
}
|
|
179
179
|
}, 400);
|
|
180
|
+
const gatewayPrincipal = getGatewayPrincipal(c);
|
|
181
|
+
const endpoint = deps.service.endpointTools.registry.get(parsed.data.endpointId);
|
|
182
|
+
if (gatewayPrincipal.kind === "device" && (!endpoint || !gatewayPrincipal.deviceId || endpoint.principalId !== gatewayPrincipal.deviceId)) return c.json({
|
|
183
|
+
ok: false,
|
|
184
|
+
error: {
|
|
185
|
+
code: "FORBIDDEN",
|
|
186
|
+
message: "Endpoint does not belong to this device"
|
|
187
|
+
}
|
|
188
|
+
}, 403);
|
|
180
189
|
try {
|
|
181
190
|
const binding = deps.service.endpointTools.bindings.bind(c.req.param("sessionKey"), parsed.data.endpointId);
|
|
182
191
|
return c.json({
|
|
@@ -28,6 +28,10 @@ init_providers();
|
|
|
28
28
|
init_credentials();
|
|
29
29
|
init_model_catalog_store();
|
|
30
30
|
init_plugin_registry();
|
|
31
|
+
function catalogDisplayNames(providerId, modelId) {
|
|
32
|
+
const model = getModelCatalogStore().getSource(providerId)?.models.find((item) => item.id === modelId);
|
|
33
|
+
return model?.displayNames ? { displayNames: model.displayNames } : {};
|
|
34
|
+
}
|
|
31
35
|
function readModelsJsonProviderApiKey(providerId) {
|
|
32
36
|
const { config } = loadModelsJson(resolveModelsJsonPath());
|
|
33
37
|
const key = (config.providers?.[providerId.trim()])?.apiKey;
|
|
@@ -292,6 +296,7 @@ function registerModelsRoutes(authenticated, deps) {
|
|
|
292
296
|
const models = sortModelsForPicker(await getAvailableModels()).map((m) => ({
|
|
293
297
|
id: `${m.provider}/${m.id}`,
|
|
294
298
|
name: m.name,
|
|
299
|
+
...catalogDisplayNames(m.provider, m.id),
|
|
295
300
|
provider: m.provider,
|
|
296
301
|
contextWindow: m.contextWindow ?? 128e3,
|
|
297
302
|
maxTokens: m.maxTokens ?? 4096,
|
|
@@ -656,6 +661,7 @@ function registerModelsRoutes(authenticated, deps) {
|
|
|
656
661
|
const models = sortModelsForPicker(allModels).map((m) => ({
|
|
657
662
|
id: `${m.provider}/${m.id}`,
|
|
658
663
|
name: m.name,
|
|
664
|
+
...catalogDisplayNames(m.provider, m.id),
|
|
659
665
|
provider: m.provider,
|
|
660
666
|
contextWindow: m.contextWindow ?? 128e3,
|
|
661
667
|
maxTokens: m.maxTokens ?? 4096,
|
|
@@ -19,8 +19,8 @@ import { resolveOmniRoute } from "../../../voice/realtime/omniRoute.js";
|
|
|
19
19
|
import { VoiceSessionCreationError, resolveStreamingStt, resolveStreamingTts } from "../../../voice/realtime/runtime.js";
|
|
20
20
|
import { getGatewayPrincipal } from "../../security/gateway-principal.js";
|
|
21
21
|
import { createGatewayRouteLogger } from "../lib/route-logger.js";
|
|
22
|
-
import { listLocalVoiceModelStatuses, removeLocalVoiceModel, startLocalVoiceModelInstall } from "../../../voice/local/model-manager.js";
|
|
23
22
|
import { listTtsProvidersForApi } from "../../../voice/tts/list-providers.js";
|
|
23
|
+
import { listLocalVoiceModelStatuses, removeLocalVoiceModel, startLocalVoiceModelInstall } from "../../../voice/local/model-manager.js";
|
|
24
24
|
import { z } from "zod";
|
|
25
25
|
//#region src/gateway/hono/routes/voice.ts
|
|
26
26
|
init_providers();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, shouldSilence, stripHeartbeatToken } from "./tokens.js";
|
|
2
|
-
import { appendCronEventLines } from "./event-prompt.js";
|
|
3
2
|
import { isWithinActiveHours } from "./active-hours.js";
|
|
4
3
|
import { isHeartbeatContentEmpty } from "./content-check.js";
|
|
4
|
+
import { appendCronEventLines } from "./event-prompt.js";
|
|
5
5
|
import { createHeartbeatWake } from "./wake.js";
|
|
6
6
|
export { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, appendCronEventLines, createHeartbeatWake, isHeartbeatContentEmpty, isWithinActiveHours, shouldSilence, stripHeartbeatToken };
|
|
@@ -62,6 +62,10 @@ var init_model_catalog_persistence = __esmMin((() => {
|
|
|
62
62
|
catalogModelSchema = z.object({
|
|
63
63
|
id: z.string().min(1),
|
|
64
64
|
name: z.string().min(1),
|
|
65
|
+
displayNames: z.object({
|
|
66
|
+
"zh-CN": z.string().min(1).optional(),
|
|
67
|
+
en: z.string().min(1).optional()
|
|
68
|
+
}).strict().optional(),
|
|
65
69
|
availability: z.enum(["available", "unavailable"]),
|
|
66
70
|
kind: z.enum([
|
|
67
71
|
"language",
|
|
@@ -52,7 +52,8 @@ var XopcCloudModelSource = class {
|
|
|
52
52
|
const tts = kind === "tts" ? parseTtsCapabilities(model.xopc?.capabilities, model.xopc?.defaultVoice) : void 0;
|
|
53
53
|
const catalogModel = {
|
|
54
54
|
id: model.id,
|
|
55
|
-
name: model.id,
|
|
55
|
+
name: typeof model.xopc?.displayName === "string" && model.xopc.displayName.trim() ? model.xopc.displayName.trim() : model.id,
|
|
56
|
+
...parseDisplayNames(model.xopc?.displayNames),
|
|
56
57
|
kind,
|
|
57
58
|
input,
|
|
58
59
|
output,
|
|
@@ -180,5 +181,15 @@ function parseImageGenerationCapabilities(value) {
|
|
|
180
181
|
maxInputImages: Number.isSafeInteger(raw.maxInputImages) && Number(raw.maxInputImages) > 0 ? Number(raw.maxInputImages) : 0
|
|
181
182
|
};
|
|
182
183
|
}
|
|
184
|
+
function parseDisplayNames(value) {
|
|
185
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
186
|
+
const raw = value;
|
|
187
|
+
const displayNames = {};
|
|
188
|
+
for (const locale of ["zh-CN", "en"]) {
|
|
189
|
+
const name = raw[locale];
|
|
190
|
+
if (typeof name === "string" && name.trim()) displayNames[locale] = name.trim();
|
|
191
|
+
}
|
|
192
|
+
return Object.keys(displayNames).length ? { displayNames } : {};
|
|
193
|
+
}
|
|
183
194
|
//#endregion
|
|
184
195
|
export { XopcCloudModelError, XopcCloudModelSource };
|
|
@@ -6,3 +6,4 @@ export interface StoredEndpointSessionBinding {
|
|
|
6
6
|
export declare function getEndpointSessionBinding(sessionKey: string): StoredEndpointSessionBinding | undefined;
|
|
7
7
|
export declare function setEndpointSessionBinding(binding: StoredEndpointSessionBinding): StoredEndpointSessionBinding;
|
|
8
8
|
export declare function deleteEndpointSessionBinding(sessionKey: string): boolean;
|
|
9
|
+
export declare function deleteEndpointSessionBindingsByPrincipal(principalId: string): number;
|
|
@@ -28,5 +28,13 @@ function setEndpointSessionBinding(binding) {
|
|
|
28
28
|
function deleteEndpointSessionBinding(sessionKey) {
|
|
29
29
|
return getSqliteDatabase().prepare("DELETE FROM endpoint_session_bindings WHERE session_key = ?").run(sessionKey).changes > 0;
|
|
30
30
|
}
|
|
31
|
+
function deleteEndpointSessionBindingsByPrincipal(principalId) {
|
|
32
|
+
return Number(getSqliteDatabase().prepare(`
|
|
33
|
+
DELETE FROM endpoint_session_bindings
|
|
34
|
+
WHERE endpoint_id IN (
|
|
35
|
+
SELECT endpoint_id FROM endpoint_instance_bindings WHERE principal_id = ?
|
|
36
|
+
)
|
|
37
|
+
`).run(principalId).changes);
|
|
38
|
+
}
|
|
31
39
|
//#endregion
|
|
32
|
-
export { deleteEndpointSessionBinding, getEndpointSessionBinding, setEndpointSessionBinding };
|
|
40
|
+
export { deleteEndpointSessionBinding, deleteEndpointSessionBindingsByPrincipal, getEndpointSessionBinding, setEndpointSessionBinding };
|
|
@@ -5,7 +5,7 @@ export { DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, } from './m
|
|
|
5
5
|
export { discoverSqlMigrations, listRegisteredMigrationTargets } from './migrations/discover.js';
|
|
6
6
|
export { closeXopcDatabase, getXopcDatabase, isXopcDatabaseOpen, openXopcDatabase, requireXopcDatabase, resetXopcDatabaseSingletonForTest, type OpenXopcDatabaseOptions, type XopcDatabase, } from './connection.js';
|
|
7
7
|
export { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';
|
|
8
|
-
export { deleteEndpointSessionBinding, getEndpointSessionBinding, setEndpointSessionBinding, type StoredEndpointSessionBinding, } from './endpoint-session-binding-repository.js';
|
|
8
|
+
export { deleteEndpointSessionBinding, deleteEndpointSessionBindingsByPrincipal, getEndpointSessionBinding, setEndpointSessionBinding, type StoredEndpointSessionBinding, } from './endpoint-session-binding-repository.js';
|
|
9
9
|
export { deleteBrowserTabBinding, deleteBrowserTabBindingsByEndpoint, deleteBrowserTabBindingsByPrincipal, getBrowserTabBinding, getBrowserTabBindingById, setBrowserTabBinding, } from './browser-tab-binding-repository.js';
|
|
10
10
|
export { authenticateDeviceAccessToken, buildRefreshProofMessage, createDevice, getDevice, issueDeviceTokenPair, listDevices, revokeDevice, rotateDeviceRefreshToken, type DeviceAccessIdentity, type DevicePlatform, type DevicePublicKeyJwk, type DeviceRecord, type DeviceTokenPair, } from './device-access-repository.js';
|
|
11
11
|
export { clearGatewayIdentityForTest, getOrCreateGatewayIdentity, signGatewayPayload, type GatewayIdentity, } from './gateway-identity-repository.js';
|
|
@@ -6,7 +6,7 @@ import { XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_SCHEMA_VERSION, applyPendingMi
|
|
|
6
6
|
import { ensureXopcDatabaseSchema } from "./schema.js";
|
|
7
7
|
import { closeXopcDatabase, getXopcDatabase, isXopcDatabaseOpen, openXopcDatabase, requireXopcDatabase, resetXopcDatabaseSingletonForTest } from "./connection.js";
|
|
8
8
|
import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
|
|
9
|
-
import { deleteEndpointSessionBinding, getEndpointSessionBinding, setEndpointSessionBinding } from "./endpoint-session-binding-repository.js";
|
|
9
|
+
import { deleteEndpointSessionBinding, deleteEndpointSessionBindingsByPrincipal, getEndpointSessionBinding, setEndpointSessionBinding } from "./endpoint-session-binding-repository.js";
|
|
10
10
|
import { deleteBrowserTabBinding, deleteBrowserTabBindingsByEndpoint, deleteBrowserTabBindingsByPrincipal, getBrowserTabBinding, getBrowserTabBindingById, setBrowserTabBinding } from "./browser-tab-binding-repository.js";
|
|
11
11
|
import { authenticateDeviceAccessToken, buildRefreshProofMessage, createDevice, getDevice, issueDeviceTokenPair, listDevices, revokeDevice, rotateDeviceRefreshToken } from "./device-access-repository.js";
|
|
12
12
|
import { clearGatewayIdentityForTest, getOrCreateGatewayIdentity, signGatewayPayload } from "./gateway-identity-repository.js";
|
|
@@ -40,4 +40,4 @@ import { appendConnectorExecutionAudit, claimConnectorWebhookDelivery, completeC
|
|
|
40
40
|
import { getConnectorAccount, listConnectorAccounts, reconcileConnectorAccount, refreshConnectorAccountCurrent } from "./connector-account-repository.js";
|
|
41
41
|
import { getConnectorSyncPolicy, getConnectorSyncPolicyForConnection, listConnectorSyncPolicies, upsertConnectorSyncPolicy } from "./connector-sync-policy-repository.js";
|
|
42
42
|
import { getUserTrustPolicy, setUserTrustPolicy } from "./user-trust-repository.js";
|
|
43
|
-
export { COMPOSER_INPUT_HISTORY_LIMIT, DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, acknowledgeHomeAttention, appendCompactionBoundaryIfUnchanged, appendComposerInputHistory, appendConnectorExecutionAudit, appendTranscriptEntry, applyPendingMigrations, authenticateDeviceAccessToken, bindEndpointPrincipal, buildDefaultSessionMetadata, buildGlobalSessionStats, buildRefreshProofMessage, buildRelationshipPrompt, cancelQueuedSessionInput, claimConnectorWebhookDelivery, claimContextExtractionRun, claimKnowledgeSourceItems, claimNextConnectorLearningJob, claimNextSessionInput, classifyStoredRow, clearComposerInputHistory, clearGatewayIdentityForTest, closeTemporalAssertions, closeXopcDatabase, completeConnectorWebhookDelivery, completeKnowledgeSourceItemSynthesis, consumeClarificationApproval, consumeClarificationResume, consumeConnectorApproval, countKnowledgeSourceItems, createClarificationWait, createCollaborationRule, createConnectorApproval, createContextEvidence, createDevice, createDevicePairingSetup, createEndpointPrincipal, createObjectLinkRecord, createTemporalAssertion, decideConnectorApproval, deleteBrowserTabBinding, deleteBrowserTabBindingsByEndpoint, deleteBrowserTabBindingsByPrincipal, deleteConnectorConnection, deleteConnectorInstallation, deleteEndpointSessionBinding, deleteKnowledgeSourceItems, deleteNoteAgentContextRecord, deleteNoteRecord, deleteObjectLinkRecord, deleteSessionConfig, deleteSessionRecord, discoverSqlMigrations, enqueueConnectorLearningJob, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, findSessionInput, findSessionKeyBySessionId, finishContextExtractionRun, finishEndpointToolInvocationAudit, finishKnowledgeSyncRun, finishSessionInputRun, getActiveClarification, getActivityEventRecord, getBrowserTabBinding, getBrowserTabBindingById, getCachedConnectorCatalogEntry, getClarification, getClarificationResumeInput, getClarificationSnapshot, getCollaborationRule, getConnectorAccount, getConnectorApproval, getConnectorConnection, getConnectorInstallation, getConnectorSyncPolicy, getConnectorSyncPolicyForConnection, getContextExtractionRun, getCurrentSessionId, getDevice, getEndpointPrincipal, getEndpointSessionBinding, getGlobalSessionStats, getInteractionState, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, getNoteAgentContextRecord, getNoteRecord, getOrCreateGatewayIdentity, getRelationshipSettings, getSessionConfig, getSessionInputById, getSessionInputState, getSessionMetadata, getSessionPersistedLevels, getSessionTaskPlan, getSqliteDatabase, getUserPeopleIndexState, getUserPerson, getUserTrustPolicy, getXopcDatabase, hasIndependentExtractionOutput, hasSessionConfig, incrementSessionStatsOnAppend, insertSessionInput, inspectSchemaMigrationStatus, isClarificationSuspended, isDevicePairingSetupActive, isHomeAttentionAcknowledged, isProactiveSupportAllowed, isXopcDatabaseOpen, issueDeviceTokenPair, linkContextObjects, listActiveSessionInputRuns, listActivityRecords, listCachedConnectorCatalogEntries, listCollaborationRules, listCompactionBoundaries, listComposerInputHistory, listConnectorAccounts, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, listConnectorLearningJobs, listConnectorSyncPolicies, listContextExtractionOutputs, listContextExtractionRuns, listContextObjectRelations, listDevices, listEndpointPrincipals, listEndpointToolInvocationAudits, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listNoteRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, listTemporalAssertions, listUserPeople, loadCompactionSourceSnapshot, loadLlmMessagesForSession, loadTranscriptHistoryRowsForSession, loadTranscriptRows, loadTranscriptRowsForSession, mergeUserPeople, metadataToSessionInsert, mutateQueuedSessionInput, openXopcDatabase, paginateTranscriptMessages, patchSessionMetadata, pruneBoundedKnowledgeSourceItems, readSchemaVersion, readSchemaVersionForTest, reconcileConnectorAccount, recordActivityEvent, recoverSessionInputState, recoverStaleConnectorLearningJobs, refreshConnectorAccountCurrent, releaseConnectorWebhookDelivery, replaceConnectorCatalogEntries, replaceLatestSessionTurnAndQueueInput, replaceTranscriptRows, replaceUserPeopleIndex, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveClarification, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreBeforeCompactionBoundary, revokeDevice, revokeEndpointPrincipal, rotateDeviceRefreshToken, runSqliteWriteTransaction, searchSessionTranscript, sessionConfigRowToConfig, sessionRowToMetadata, setBrowserTabBinding, setCollaborationRuleStatus, setConnectorLearningPaused, setEndpointSessionBinding, setInteractionState, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, setKnowledgeSourceItemSynthesisStatus, setSessionConfig, setSessionInputStatus, setSessionTaskPlan, setUserTrustPolicy, signGatewayPayload, startEndpointToolInvocationAudit, startKnowledgeSyncRun, summarizeUserPeople, supersedeActiveClarification, touchEndpointPrincipal, transcriptEntryRowToStoredRow, updateConnectorLearningJob, updateInteractionStateFromMessage, updateRelationshipSettings, updateSessionConfig, updateSessionStats, updateUserPerson, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation, upsertConnectorSyncPolicy, upsertKnowledgeSourceItems, upsertNoteAgentContextRecord, upsertNoteRecord, validateLatestSessionTurnTarget };
|
|
43
|
+
export { COMPOSER_INPUT_HISTORY_LIMIT, DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, acknowledgeHomeAttention, appendCompactionBoundaryIfUnchanged, appendComposerInputHistory, appendConnectorExecutionAudit, appendTranscriptEntry, applyPendingMigrations, authenticateDeviceAccessToken, bindEndpointPrincipal, buildDefaultSessionMetadata, buildGlobalSessionStats, buildRefreshProofMessage, buildRelationshipPrompt, cancelQueuedSessionInput, claimConnectorWebhookDelivery, claimContextExtractionRun, claimKnowledgeSourceItems, claimNextConnectorLearningJob, claimNextSessionInput, classifyStoredRow, clearComposerInputHistory, clearGatewayIdentityForTest, closeTemporalAssertions, closeXopcDatabase, completeConnectorWebhookDelivery, completeKnowledgeSourceItemSynthesis, consumeClarificationApproval, consumeClarificationResume, consumeConnectorApproval, countKnowledgeSourceItems, createClarificationWait, createCollaborationRule, createConnectorApproval, createContextEvidence, createDevice, createDevicePairingSetup, createEndpointPrincipal, createObjectLinkRecord, createTemporalAssertion, decideConnectorApproval, deleteBrowserTabBinding, deleteBrowserTabBindingsByEndpoint, deleteBrowserTabBindingsByPrincipal, deleteConnectorConnection, deleteConnectorInstallation, deleteEndpointSessionBinding, deleteEndpointSessionBindingsByPrincipal, deleteKnowledgeSourceItems, deleteNoteAgentContextRecord, deleteNoteRecord, deleteObjectLinkRecord, deleteSessionConfig, deleteSessionRecord, discoverSqlMigrations, enqueueConnectorLearningJob, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, findSessionInput, findSessionKeyBySessionId, finishContextExtractionRun, finishEndpointToolInvocationAudit, finishKnowledgeSyncRun, finishSessionInputRun, getActiveClarification, getActivityEventRecord, getBrowserTabBinding, getBrowserTabBindingById, getCachedConnectorCatalogEntry, getClarification, getClarificationResumeInput, getClarificationSnapshot, getCollaborationRule, getConnectorAccount, getConnectorApproval, getConnectorConnection, getConnectorInstallation, getConnectorSyncPolicy, getConnectorSyncPolicyForConnection, getContextExtractionRun, getCurrentSessionId, getDevice, getEndpointPrincipal, getEndpointSessionBinding, getGlobalSessionStats, getInteractionState, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, getNoteAgentContextRecord, getNoteRecord, getOrCreateGatewayIdentity, getRelationshipSettings, getSessionConfig, getSessionInputById, getSessionInputState, getSessionMetadata, getSessionPersistedLevels, getSessionTaskPlan, getSqliteDatabase, getUserPeopleIndexState, getUserPerson, getUserTrustPolicy, getXopcDatabase, hasIndependentExtractionOutput, hasSessionConfig, incrementSessionStatsOnAppend, insertSessionInput, inspectSchemaMigrationStatus, isClarificationSuspended, isDevicePairingSetupActive, isHomeAttentionAcknowledged, isProactiveSupportAllowed, isXopcDatabaseOpen, issueDeviceTokenPair, linkContextObjects, listActiveSessionInputRuns, listActivityRecords, listCachedConnectorCatalogEntries, listCollaborationRules, listCompactionBoundaries, listComposerInputHistory, listConnectorAccounts, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, listConnectorLearningJobs, listConnectorSyncPolicies, listContextExtractionOutputs, listContextExtractionRuns, listContextObjectRelations, listDevices, listEndpointPrincipals, listEndpointToolInvocationAudits, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listNoteRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, listTemporalAssertions, listUserPeople, loadCompactionSourceSnapshot, loadLlmMessagesForSession, loadTranscriptHistoryRowsForSession, loadTranscriptRows, loadTranscriptRowsForSession, mergeUserPeople, metadataToSessionInsert, mutateQueuedSessionInput, openXopcDatabase, paginateTranscriptMessages, patchSessionMetadata, pruneBoundedKnowledgeSourceItems, readSchemaVersion, readSchemaVersionForTest, reconcileConnectorAccount, recordActivityEvent, recoverSessionInputState, recoverStaleConnectorLearningJobs, refreshConnectorAccountCurrent, releaseConnectorWebhookDelivery, replaceConnectorCatalogEntries, replaceLatestSessionTurnAndQueueInput, replaceTranscriptRows, replaceUserPeopleIndex, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveClarification, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreBeforeCompactionBoundary, revokeDevice, revokeEndpointPrincipal, rotateDeviceRefreshToken, runSqliteWriteTransaction, searchSessionTranscript, sessionConfigRowToConfig, sessionRowToMetadata, setBrowserTabBinding, setCollaborationRuleStatus, setConnectorLearningPaused, setEndpointSessionBinding, setInteractionState, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, setKnowledgeSourceItemSynthesisStatus, setSessionConfig, setSessionInputStatus, setSessionTaskPlan, setUserTrustPolicy, signGatewayPayload, startEndpointToolInvocationAudit, startKnowledgeSyncRun, summarizeUserPeople, supersedeActiveClarification, touchEndpointPrincipal, transcriptEntryRowToStoredRow, updateConnectorLearningJob, updateInteractionStateFromMessage, updateRelationshipSettings, updateSessionConfig, updateSessionStats, updateUserPerson, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation, upsertConnectorSyncPolicy, upsertKnowledgeSourceItems, upsertNoteAgentContextRecord, upsertNoteRecord, validateLatestSessionTurnTarget };
|
|
@@ -567,7 +567,10 @@ var WorkflowRunService = class {
|
|
|
567
567
|
getDefaultModel: () => resolveModel(gatewayService.agentService.getModelForSession(params.sessionKey)),
|
|
568
568
|
getConfig: () => gatewayService.currentConfig,
|
|
569
569
|
sessionStore: gatewayService.sessionIndexInstance.getStore(),
|
|
570
|
-
buildChildTools: (childOptions) => this.options.buildChildTools(
|
|
570
|
+
buildChildTools: (childOptions) => this.options.buildChildTools({
|
|
571
|
+
...childOptions,
|
|
572
|
+
endpointTools: gatewayService.endpointTools
|
|
573
|
+
})
|
|
571
574
|
});
|
|
572
575
|
return new WorkflowEngine({
|
|
573
576
|
cwd: workspace,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xopcai/xopc",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.275",
|
|
4
4
|
"description": "Local-first personal AI assistant with reviewable user understanding, durable tasks, workflows, automations, and local or cloud models.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -167,9 +167,9 @@
|
|
|
167
167
|
"vue": "^3.5.35",
|
|
168
168
|
"@xopcai/browser-control-contract": "0.1.0",
|
|
169
169
|
"@xopcai/endpoint-tools-protocol": "0.0.0",
|
|
170
|
+
"@xopcai/gateway-contract": "0.0.0",
|
|
170
171
|
"@xopcai/realtime-client": "0.0.0",
|
|
171
|
-
"@xopcai/realtime-protocol": "0.0.0"
|
|
172
|
-
"@xopcai/gateway-contract": "0.0.0"
|
|
172
|
+
"@xopcai/realtime-protocol": "0.0.0"
|
|
173
173
|
},
|
|
174
174
|
"scripts": {
|
|
175
175
|
"assets:brand": "node scripts/generate-brand-assets.mjs",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{a as t,n,t as r}from"./vendor-react-BOUWij0V.js";import{h as i,t as a}from"./chunk-KS7C4IRE-Cq1tE_3b.js";import{a as o,i as s,o as c,r as l,s as u,t as d}from"./dist-CpzYSoz7.js";import{t as f}from"./check-DUBLcKHA.js";import{t as p}from"./external-link-DjqjBmc3.js";import{t as m}from"./markdown-view-B2IR4E2r.js";import{t as h}from"./loader-circle-CifKLtgG.js";import{t as g}from"./plus-Q2yW6OE7.js";import{t as _}from"./x-B_N4OPjy.js";import{t as v}from"./messages-BGc-OJWg.js";import{a as y,c as b,i as x,n as S,r as C}from"./locale-store-BkJ7g35d.js";import{t as w}from"./cn-JdwAhgNB.js";import{a as T,i as E}from"./vendor-swr-BIWyz7Rc.js";import{t as D}from"./button-B11EPpor.js";import{t as O}from"./skeleton-BwbyijEw.js";import{Ba as k,Ga as A,Ha as j,Hs as ee,Ic as M,La as N,Ou as te,Va as P,Vs as ne,Yi as F,gu as I,lc as L,ou as R,pc as z,sc as re,so as B,za as V}from"./index-SxqsTD4i.js";import{t as H}from"./page-tabs-CRombigq.js";var U=e(t(),1),W=n();function G(e){return e===`builtin`||e===`user`?e:`marketplace`}async function K(e){try{let t=await e.json();if(typeof t.error==`string`)return t.error;if(t.error&&typeof t.error==`object`&&typeof t.error.message==`string`)return t.error.message;if(typeof t.message==`string`)return t.message}catch{}return e.statusText||`HTTP ${e.status}`}async function ie(e){let t=await x(C(`/api/marketplace/packages/${encodeURIComponent(e.trim())}`),{cache:`no-store`});if(!t.ok)throw Error(await K(t));let n=await t.json();if(!n.ok||!n.payload?.id)throw Error(n.error??`Invalid response`);return n.payload}async function q(e){let t=await x(C(`/api/marketplace/install`),{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});if(!t.ok)throw Error(await K(t));let n=await t.json();if(!n.ok||!n.payload?.extensionId)throw Error(n.error??`Invalid response`);return n.payload}async function J(e){let t=await x(C(`/api/extensions/bundled/activation`),{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({extensionId:e.extensionId.trim(),enabled:e.enabled})});if(!t.ok)throw Error(await K(t));let n=await t.json();if(!n.ok||!n.payload)throw Error(n.error?.message??`Invalid response`);return n.payload}async function Y(e){let t=await x(C(`/api/marketplace/uninstall`),{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({extensionId:e})});if(!t.ok)throw Error(await K(t));let n=await t.json();if(!n.ok||!n.payload)throw Error(n.error??`Invalid response`);return n.payload}var X=r();function ae(e,t){let n=e.find(e=>e.id===t);return n?n.source===`bundled`?`bundled`:`user`:`absent`}var Z={q:``,debounced:``,detailPkg:null,rowBusy:null,actionError:null,restartHint:null};function Q({className:e}){let t=v(S(e=>e.language)).extensionsPage,n=b(e=>!!e.sessionKey),r=V(),{mutate:i}=T(),[a,o]=(0,U.useReducer)(F,Z),{q:s,debounced:c,detailPkg:l,rowBusy:u,actionError:d,restartHint:f}=a,p=n?`marketplace-${c}`:null;(0,U.useEffect)(()=>{let e=window.setTimeout(()=>o({type:`patch`,patch:{debounced:s.trim()}}),300);return()=>window.clearTimeout(e)},[s]);let{data:m,isLoading:g,error:_}=E(p,async()=>y(c.length>0?C(`/api/marketplace?q=${encodeURIComponent(c)}`):C(`/api/marketplace`)),{revalidateOnFocus:!1}),x=(0,U.useCallback)(()=>{i(`gateway-extensions-list`),A()},[i]),D=(0,U.useCallback)(async(e,n)=>{o({type:`patch`,patch:{actionError:null,restartHint:null,rowBusy:e}});try{let r=await q({name:e,overwrite:n});x(),r.requiresGatewayRestart&&o({type:`patch`,patch:{restartHint:t.marketplaceRestartHint}})}catch(e){throw o({type:`patch`,patch:{actionError:e instanceof Error?e.message:t.marketplaceInstallFailed}}),e}finally{o({type:`patch`,patch:{rowBusy:null}})}},[t.marketplaceInstallFailed,t.marketplaceRestartHint,x]),k=(0,U.useCallback)(async e=>{o({type:`patch`,patch:{actionError:null,restartHint:null,rowBusy:e}});try{let n=await Y(e);x(),n.requiresGatewayRestart&&o({type:`patch`,patch:{restartHint:t.marketplaceRestartHint}})}catch(e){throw o({type:`patch`,patch:{actionError:e instanceof Error?e.message:t.marketplaceUninstallFailed}}),e}finally{o({type:`patch`,patch:{rowBusy:null}})}},[t.marketplaceRestartHint,t.marketplaceUninstallFailed,x]),j=m?.extensions??[];return(0,X.jsxs)(`div`,{className:w(`flex flex-col gap-4`,e),children:[(0,X.jsxs)(`div`,{className:`relative`,children:[(0,X.jsx)(z,{className:`pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-fg-muted`,strokeWidth:1.75,"aria-hidden":!0}),(0,X.jsx)(`input`,{type:`search`,value:s,onChange:e=>o({type:`patch`,patch:{q:e.target.value}}),placeholder:t.marketplaceSearchPlaceholder,className:`ui-input h-10 w-full rounded-lg border border-edge bg-surface-base pl-9 pr-3 text-sm text-fg placeholder:text-fg-muted`})]}),_?(0,X.jsx)(`p`,{className:`text-sm text-fg-muted`,children:_ instanceof Error?_.message:t.marketplaceLoadFailed}):null,d?(0,X.jsx)(`p`,{className:`text-sm text-red-600 dark:text-red-400`,children:d}):null,f?(0,X.jsx)(`p`,{className:`text-sm text-fg-muted`,children:f}):null,g&&!m?(0,X.jsx)(`ul`,{className:`flex flex-col gap-3`,"aria-label":t.marketplaceLoading,children:[0,1,2].map(e=>(0,X.jsx)(`li`,{className:`rounded-xl bg-surface-panel p-4 shadow-surface`,children:(0,X.jsxs)(`div`,{className:`flex items-start justify-between gap-4`,children:[(0,X.jsxs)(`div`,{className:`min-w-0 flex-1 space-y-2.5`,children:[(0,X.jsx)(O,{className:`h-5 w-40`}),(0,X.jsx)(O,{className:`h-4 w-full max-w-xl`}),(0,X.jsx)(O,{className:`h-4 w-2/3 max-w-md`})]}),(0,X.jsx)(O,{className:`h-8 w-20`})]})},e))}):(0,X.jsx)(`ul`,{className:`flex flex-col gap-3`,children:j.length===0?(0,X.jsx)(`li`,{className:`text-sm text-fg-muted`,children:t.marketplaceEmpty}):j.map(e=>{let n=ae(r,e.id),i=u===e.id;return(0,X.jsx)(`li`,{className:`list-none`,children:(0,X.jsxs)(`div`,{role:`button`,tabIndex:0,"aria-label":`${e.name}, ${t.marketplaceDetailTitle}`,onClick:()=>o({type:`patch`,patch:{detailPkg:e.id}}),onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),o({type:`patch`,patch:{detailPkg:e.id}}))},className:w(`flex w-full cursor-pointer flex-wrap items-start gap-3 rounded-xl bg-surface-panel p-4 text-left shadow-surface`,`transition-[transform,background-color,box-shadow] duration-150 ease-out`,`hover:bg-surface-hover/40`,`active:scale-[0.992] active:bg-surface-hover/55`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-surface-panel`,`dark:hover:bg-surface-hover/25 dark:active:bg-surface-hover/35`),children:[(0,X.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,X.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,X.jsx)(`h3`,{className:`font-semibold text-fg`,children:e.name}),e.verified?(0,X.jsx)(R,{className:`size-4 shrink-0 text-emerald-600 dark:text-emerald-400`,strokeWidth:1.75,"aria-label":`Verified`}):null,e.version?(0,X.jsx)(`span`,{className:`text-xs text-fg-muted`,children:e.version}):null]}),e.description?(0,X.jsx)(`p`,{className:`mt-1 line-clamp-2 text-sm text-fg-muted`,children:e.description}):null,(0,X.jsx)(`div`,{className:`mt-2 flex flex-wrap gap-1.5`,children:(e.categories??[]).map(e=>(0,X.jsx)(`span`,{className:`rounded-md border border-edge bg-surface-panel px-2 py-0.5 text-[11px] text-fg-muted`,children:e},e))}),(0,X.jsxs)(`p`,{className:`mt-2 flex items-center gap-1.5 text-xs text-fg-muted`,children:[(0,X.jsx)(M,{className:`size-3.5 shrink-0`,strokeWidth:1.75,"aria-hidden":!0}),(0,X.jsx)(`code`,{className:`rounded bg-surface-panel px-1 py-0.5`,children:e.npmPackage})]})]}),(0,X.jsx)(`div`,{role:`group`,className:`flex shrink-0 flex-col items-end gap-2 sm:min-w-[9rem]`,onClick:e=>e.stopPropagation(),onKeyDown:e=>e.stopPropagation(),children:n===`bundled`?(0,X.jsx)(`span`,{className:`rounded-md bg-surface-hover px-2 py-1 text-[11px] font-medium text-fg-muted`,children:t.marketplaceBuiltin}):n===`user`?(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(`span`,{className:`text-[11px] font-medium text-fg-muted`,children:t.marketplaceInstalled}),(0,X.jsxs)(`button`,{type:`button`,disabled:i,onClick:()=>{window.confirm(t.marketplaceUninstallConfirm)&&k(e.id).catch(()=>{})},className:w(`inline-flex items-center justify-center gap-1.5 rounded-lg border border-edge px-3 py-2 text-xs font-medium text-fg`,`transition-colors active:scale-[0.98] active:bg-surface-hover/80`,`hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,`disabled:pointer-events-none disabled:opacity-50`),children:[i?(0,X.jsx)(h,{className:`size-3.5 animate-spin`,"aria-hidden":!0}):(0,X.jsx)(ee,{className:`size-3.5`,strokeWidth:2,"aria-hidden":!0}),t.marketplaceUninstall]})]}):(0,X.jsx)(`button`,{type:`button`,onClick:()=>o({type:`patch`,patch:{detailPkg:e.id}}),className:w(`inline-flex w-full items-center justify-center rounded-lg border border-edge px-3 py-2 text-xs font-medium text-fg`,`transition-[transform,background-color] active:scale-[0.98]`,`hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`),children:t.marketplaceReview})})]})},e.id)})}),l?(0,X.jsx)($,{packageName:l,copy:t,extensions:r,onClose:()=>o({type:`patch`,patch:{detailPkg:null}}),onInstall:D,onUninstall:k}):null]})}function $(e){let t=(0,W.c)(102),{packageName:n,copy:r,extensions:i,onClose:s,onInstall:f,onUninstall:p}=e,[g,v]=(0,U.useState)(!1),[y,x]=(0,U.useState)(!1),S=b(ue)?`ext-mp-detail-${n}`:null,C;t[0]===n?C=t[1]:(C=async()=>ie(n),t[0]=n,t[1]=C);let T;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(T={revalidateOnFocus:!1},t[2]=T):T=t[2];let{data:D,error:k,isLoading:A}=E(S,C,T),j;t[3]!==i||t[4]!==n?(j=ae(i,n),t[3]=i,t[4]=n,t[5]=j):j=t[5];let M=j,N=M===`user`,P=D?.manifest?.permissions,F,I,L,R,z,B,V,H,G,K,q;if(t[6]!==r.detailBack||t[7]!==r.detailClose||t[8]!==r.marketplaceAuthor||t[9]!==r.marketplaceCodeRisk||t[10]!==r.marketplaceDependencies||t[11]!==r.marketplaceDetailLoadFailed||t[12]!==r.marketplaceDetailReadmeHeading||t[13]!==r.marketplaceDetailTitle||t[14]!==r.marketplaceDownloads||t[15]!==r.marketplaceIntegrity||t[16]!==r.marketplaceIntegrityVerified||t[17]!==r.marketplaceLifecycleScripts||t[18]!==r.marketplaceLoadFailed||t[19]!==r.marketplaceLoading||t[20]!==r.marketplaceNoReadme||t[21]!==r.marketplacePermissions||t[22]!==r.marketplacePermissionsNone||t[23]!==r.marketplaceRiskConfirm||t[24]!==r.marketplaceRiskTitle||t[25]!==r.marketplaceUnavailableBody||t[26]!==r.marketplaceUnavailableTitle||t[27]!==r.marketplaceVersion||t[28]!==D||t[29]!==k||t[30]!==M||t[31]!==A||t[32]!==s||t[33]!==P||t[34]!==y){let e=P&&typeof P==`object`&&!Array.isArray(P)?Object.entries(P):[],n;t[46]!==r.marketplaceNoReadme||t[47]!==D?(n=D?.readme?.trim()||(D?.description?.trim()?`### ${D.name}\n\n${D.description}`:`*${r.marketplaceNoReadme}*`),t[46]=r.marketplaceNoReadme,t[47]=D,t[48]=n):n=t[48];let i=n;L=d,R=!0,t[49]===s?z=t[50]:(z=e=>!e&&s(),t[49]=s,t[50]=z),I=c,t[51]===Symbol.for(`react.memo_cache_sentinel`)?(q=(0,X.jsx)(o,{className:`xopc-dialog-overlay fixed inset-0 z-[130] bg-scrim`}),t[51]=q):q=t[51],F=l,H=`fixed left-1/2 top-1/2 z-[131] flex h-[min(44rem,calc(100vh-1.5rem))] w-[min(42rem,calc(100vw-1.5rem))] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-xl border border-edge bg-surface-panel shadow-elevated`,G=le;let a;t[52]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,X.jsx)(te,{className:`size-5`}),t[52]=a):a=t[52];let f;t[53]!==r.detailBack||t[54]!==s?(f=(0,X.jsx)(`button`,{type:`button`,onClick:s,className:`inline-flex size-9 items-center justify-center rounded-lg text-fg-muted hover:bg-surface-hover hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,"aria-label":r.detailBack,children:a}),t[53]=r.detailBack,t[54]=s,t[55]=f):f=t[55];let p;t[56]===r.marketplaceDetailTitle?p=t[57]:(p=(0,X.jsx)(u,{className:`min-w-0 flex-1 truncate text-center text-sm font-semibold text-fg`,children:r.marketplaceDetailTitle}),t[56]=r.marketplaceDetailTitle,t[57]=p);let h;t[58]===Symbol.for(`react.memo_cache_sentinel`)?(h=(0,X.jsx)(_,{className:`size-5`}),t[58]=h):h=t[58];let g;t[59]!==r.detailClose||t[60]!==s?(g=(0,X.jsx)(`button`,{type:`button`,onClick:s,className:`inline-flex size-9 items-center justify-center rounded-lg text-fg-muted hover:bg-surface-hover hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,"aria-label":r.detailClose,children:h}),t[59]=r.detailClose,t[60]=s,t[61]=g):g=t[61],t[62]!==f||t[63]!==p||t[64]!==g?(K=(0,X.jsxs)(`div`,{className:`flex shrink-0 items-center justify-between gap-2 border-b border-edge px-4 py-3`,children:[f,p,g]}),t[62]=f,t[63]=p,t[64]=g,t[65]=K):K=t[65],B=`min-h-0 flex-1 overflow-y-auto p-5`,V=A&&!D?(0,X.jsxs)(`div`,{className:`space-y-4`,"aria-label":r.marketplaceLoading,children:[(0,X.jsx)(O,{className:`h-6 w-48`}),(0,X.jsx)(O,{className:`h-4 w-28`}),(0,X.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,X.jsx)(O,{className:`h-12`}),(0,X.jsx)(O,{className:`h-12`})]}),(0,X.jsx)(O,{className:`h-28 w-full`}),(0,X.jsx)(O,{className:`h-36 w-full`})]}):k?(0,X.jsxs)(`div`,{className:`rounded-lg border border-red-300/70 bg-red-50 p-4 text-sm dark:border-red-900 dark:bg-red-950/30`,children:[(0,X.jsx)(`p`,{className:`font-medium text-red-700 dark:text-red-300`,children:r.marketplaceDetailLoadFailed}),(0,X.jsx)(`p`,{className:`mt-1 break-words text-red-600 dark:text-red-400`,children:k instanceof Error?k.message:r.marketplaceLoadFailed})]}):D?(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(`h3`,{className:`text-lg font-semibold text-fg`,children:D.name}),(0,X.jsx)(`p`,{className:`mt-1 text-xs text-fg-muted`,children:(0,X.jsx)(`code`,{className:`rounded bg-surface-panel px-1 py-0.5`,children:D.id})}),(0,X.jsxs)(`dl`,{className:`mt-3 grid gap-2 text-xs text-fg-muted sm:grid-cols-2`,children:[(0,X.jsxs)(`div`,{children:[(0,X.jsx)(`dt`,{className:`font-medium text-fg`,children:r.marketplaceAuthor}),(0,X.jsx)(`dd`,{children:D.author.username})]}),(0,X.jsxs)(`div`,{children:[(0,X.jsx)(`dt`,{className:`font-medium text-fg`,children:r.marketplaceVersion}),(0,X.jsx)(`dd`,{children:D.latestVersion.version})]}),(0,X.jsxs)(`div`,{children:[(0,X.jsx)(`dt`,{className:`font-medium text-fg`,children:r.marketplaceDownloads}),(0,X.jsx)(`dd`,{children:D.downloads})]})]}),M===`bundled`?null:(0,X.jsxs)(`section`,{className:`mt-5 space-y-3 rounded-lg border border-edge bg-surface-base p-4`,children:[(0,X.jsxs)(`div`,{className:`flex items-start gap-2.5`,children:[D.installability.available?(0,X.jsx)(re,{className:`mt-0.5 size-5 shrink-0 text-emerald-600 dark:text-emerald-400`,"aria-hidden":!0}):(0,X.jsx)(ne,{className:`mt-0.5 size-5 shrink-0 text-amber-600 dark:text-amber-400`,"aria-hidden":!0}),(0,X.jsxs)(`div`,{className:`min-w-0`,children:[(0,X.jsx)(`h4`,{className:`text-sm font-semibold text-fg`,children:D.installability.available?r.marketplaceRiskTitle:r.marketplaceUnavailableTitle}),(0,X.jsx)(`p`,{className:`mt-1 text-xs leading-relaxed text-fg-muted`,children:D.installability.available?r.marketplaceCodeRisk:D.installability.reason??r.marketplaceUnavailableBody})]})]}),D.installability.available?(0,X.jsxs)(X.Fragment,{children:[(0,X.jsxs)(`dl`,{className:`grid gap-2 text-xs text-fg-muted sm:grid-cols-2`,children:[(0,X.jsxs)(`div`,{children:[(0,X.jsx)(`dt`,{className:`font-medium text-fg`,children:r.marketplaceIntegrity}),(0,X.jsx)(`dd`,{children:r.marketplaceIntegrityVerified})]}),(0,X.jsxs)(`div`,{children:[(0,X.jsx)(`dt`,{className:`font-medium text-fg`,children:r.marketplaceDependencies}),(0,X.jsx)(`dd`,{children:D.packageSummary?.dependencyCount??0})]})]}),(0,X.jsxs)(`div`,{className:`text-xs text-fg-muted`,children:[(0,X.jsx)(`p`,{className:`font-medium text-fg`,children:r.marketplacePermissions}),e.length>0?(0,X.jsx)(`ul`,{className:`mt-1 space-y-1`,children:e.map(ce)}):(0,X.jsx)(`p`,{className:`mt-1`,children:r.marketplacePermissionsNone})]}),(D.packageSummary?.lifecycleScripts.length??0)>0?(0,X.jsxs)(`p`,{className:`text-xs leading-relaxed text-amber-700 dark:text-amber-300`,children:[r.marketplaceLifecycleScripts,`: `,D.packageSummary?.lifecycleScripts.join(`, `)]}):null,(0,X.jsxs)(`label`,{className:`flex cursor-pointer items-start gap-2 text-sm text-fg`,children:[(0,X.jsx)(`input`,{type:`checkbox`,checked:y,onChange:e=>x(e.target.checked),className:`mt-0.5 size-4 rounded border-edge accent-[var(--color-accent)]`}),(0,X.jsx)(`span`,{children:r.marketplaceRiskConfirm})]})]}):null]}),D.readme?.trim()?(0,X.jsx)(`h4`,{className:`mb-2 mt-6 text-sm font-semibold text-fg`,children:r.marketplaceDetailReadmeHeading}):null,(0,X.jsx)(`div`,{className:`markdown-content min-w-0 break-words text-sm`,children:(0,X.jsx)(m,{content:i})})]}):null,t[6]=r.detailBack,t[7]=r.detailClose,t[8]=r.marketplaceAuthor,t[9]=r.marketplaceCodeRisk,t[10]=r.marketplaceDependencies,t[11]=r.marketplaceDetailLoadFailed,t[12]=r.marketplaceDetailReadmeHeading,t[13]=r.marketplaceDetailTitle,t[14]=r.marketplaceDownloads,t[15]=r.marketplaceIntegrity,t[16]=r.marketplaceIntegrityVerified,t[17]=r.marketplaceLifecycleScripts,t[18]=r.marketplaceLoadFailed,t[19]=r.marketplaceLoading,t[20]=r.marketplaceNoReadme,t[21]=r.marketplacePermissions,t[22]=r.marketplacePermissionsNone,t[23]=r.marketplaceRiskConfirm,t[24]=r.marketplaceRiskTitle,t[25]=r.marketplaceUnavailableBody,t[26]=r.marketplaceUnavailableTitle,t[27]=r.marketplaceVersion,t[28]=D,t[29]=k,t[30]=M,t[31]=A,t[32]=s,t[33]=P,t[34]=y,t[35]=F,t[36]=I,t[37]=L,t[38]=R,t[39]=z,t[40]=B,t[41]=V,t[42]=H,t[43]=G,t[44]=K,t[45]=q}else F=t[35],I=t[36],L=t[37],R=t[38],z=t[39],B=t[40],V=t[41],H=t[42],G=t[43],K=t[44],q=t[45];let J;t[66]!==B||t[67]!==V?(J=(0,X.jsx)(`div`,{className:B,children:V}),t[66]=B,t[67]=V,t[68]=J):J=t[68];let Y;t[69]!==g||t[70]!==r.marketplaceBuiltinGoBuiltin||t[71]!==r.marketplaceBuiltinManageHint||t[72]!==r.marketplaceInstall||t[73]!==r.marketplaceReinstall||t[74]!==r.marketplaceReinstallConfirm||t[75]!==r.marketplaceUninstall||t[76]!==r.marketplaceUninstallConfirm||t[77]!==D||t[78]!==M||t[79]!==s||t[80]!==f||t[81]!==p||t[82]!==n||t[83]!==y||t[84]!==N?(Y=D?(0,X.jsx)(`div`,{className:`flex shrink-0 flex-wrap items-center justify-end gap-2 border-t border-edge-subtle px-5 py-4`,children:M===`bundled`?(0,X.jsxs)(`div`,{className:`flex w-full flex-col items-stretch gap-2`,children:[(0,X.jsx)(`p`,{className:`text-sm leading-relaxed text-fg-muted`,children:r.marketplaceBuiltinManageHint}),(0,X.jsx)(a,{to:`/extensions?tab=builtin`,onClick:s,className:`inline-flex w-fit items-center justify-center rounded-lg border border-edge px-3 py-2 text-sm font-medium text-fg hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,children:r.marketplaceBuiltinGoBuiltin})]}):(0,X.jsxs)(X.Fragment,{children:[(0,X.jsxs)(`button`,{type:`button`,disabled:g||!D.installability.available||!y,onClick:()=>{N&&!window.confirm(r.marketplaceReinstallConfirm)||(v(!0),f(n,N).catch(se).finally(()=>v(!1)))},className:w(`inline-flex items-center justify-center gap-1.5 rounded-lg px-3 py-2 text-sm font-medium`,`bg-accent text-white shadow-surface hover:bg-accent-hover`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-surface-panel`,`disabled:pointer-events-none disabled:opacity-50`),children:[g?(0,X.jsx)(h,{className:`size-4 animate-spin`,"aria-hidden":!0}):null,N?r.marketplaceReinstall:r.marketplaceInstall]}),N?(0,X.jsxs)(`button`,{type:`button`,disabled:g,onClick:()=>{window.confirm(r.marketplaceUninstallConfirm)&&(v(!0),p(n).then(()=>s()).catch(oe).finally(()=>v(!1)))},className:w(`inline-flex items-center justify-center gap-1.5 rounded-lg border border-edge px-3 py-2 text-sm font-medium text-fg`,`hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,`disabled:pointer-events-none disabled:opacity-50`),children:[(0,X.jsx)(ee,{className:`size-4 shrink-0`,"aria-hidden":!0}),r.marketplaceUninstall]}):null]})}):null,t[69]=g,t[70]=r.marketplaceBuiltinGoBuiltin,t[71]=r.marketplaceBuiltinManageHint,t[72]=r.marketplaceInstall,t[73]=r.marketplaceReinstall,t[74]=r.marketplaceReinstallConfirm,t[75]=r.marketplaceUninstall,t[76]=r.marketplaceUninstallConfirm,t[77]=D,t[78]=M,t[79]=s,t[80]=f,t[81]=p,t[82]=n,t[83]=y,t[84]=N,t[85]=Y):Y=t[85];let Z;t[86]!==F||t[87]!==J||t[88]!==Y||t[89]!==H||t[90]!==G||t[91]!==K?(Z=(0,X.jsxs)(F,{className:H,onOpenAutoFocus:G,children:[K,J,Y]}),t[86]=F,t[87]=J,t[88]=Y,t[89]=H,t[90]=G,t[91]=K,t[92]=Z):Z=t[92];let Q;t[93]!==I||t[94]!==Z||t[95]!==q?(Q=(0,X.jsxs)(I,{children:[q,Z]}),t[93]=I,t[94]=Z,t[95]=q,t[96]=Q):Q=t[96];let $;return t[97]!==L||t[98]!==R||t[99]!==z||t[100]!==Q?($=(0,X.jsx)(L,{defaultOpen:R,onOpenChange:z,children:Q}),t[97]=L,t[98]=R,t[99]=z,t[100]=Q,t[101]=$):$=t[101],$}function oe(){}function se(){}function ce(e){let[t,n]=e;return(0,X.jsxs)(`li`,{className:`break-words`,children:[(0,X.jsx)(`code`,{children:t}),`: `,Array.isArray(n)?n.join(`, `):String(n)]},t)}function le(e){return e.preventDefault()}function ue(e){return!!e.sessionKey}function de(){let e=S(e=>e.language),t=v(e),n=B(e=>e.setPageHeader),r=B(e=>e.clearPageHeader),o=V(),s=k(),[c,l]=i(),u=G(c.get(`tab`)),d=c.get(`q`)??``,[f,p]=(0,U.useState)(u),[m,h]=(0,U.useState)(d),[_,y]=(0,U.useState)(null),b=c.toString(),x=(0,U.useRef)(b);if(x.current!==b){x.current=b;let e=G(c.get(`tab`)),t=c.get(`q`)??``;p(t=>t===e?t:e),h(e=>e===t?e:t)}(0,U.useEffect)(()=>{l(e=>{let t=new URLSearchParams(e),n=m.trim();return n?t.set(`q`,n):t.delete(`q`),f===`marketplace`?t.delete(`tab`):t.set(`tab`,f),t.toString()===e.toString()?e:t},{replace:!0})},[f,m,l]);let C=(0,U.useMemo)(()=>o.filter(e=>e.source===`bundled`),[o]),w=(0,U.useMemo)(()=>o.filter(e=>e.source!==`bundled`),[o]),T=f===`builtin`?C:w,E=(0,U.useMemo)(()=>{let t=m.trim().toLowerCase(),n=T;return t&&(n=n.filter(e=>(e.name??``).toLowerCase().includes(t)||e.id.toLowerCase().includes(t)||(e.description??``).toLowerCase().includes(t))),n.toSorted((t,n)=>t.hasUi===n.hasUi?(t.name||t.id).localeCompare(n.name||n.id,e):t.hasUi?-1:1)},[T,m,e]);if((0,U.useEffect)(()=>{y(e=>{if(!e)return e;let t=o.find(t=>t.id===e.id);return t?fe(e)===fe(t)&&e.active===t.active?e:t:null})},[o]),(0,U.useLayoutEffect)(()=>(n({startExtra:null,main:(0,X.jsx)(`div`,{className:`min-w-0`,children:(0,X.jsx)(`h1`,{className:`truncate text-base font-semibold tracking-tight text-fg`,children:t.extensionsPage.title})}),end:(0,X.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,X.jsx)(D,{asChild:!0,variant:`secondary`,className:`h-9`,children:(0,X.jsxs)(a,{to:`/local-apps`,"aria-label":t.extensionsPage.openLocalApps,title:t.extensionsPage.openLocalApps,children:[(0,X.jsx)(I,{className:`size-4`}),(0,X.jsx)(`span`,{className:`hidden sm:inline`,children:t.extensionsPage.openLocalApps})]})}),(0,X.jsx)(D,{asChild:!0,variant:`primary`,className:`h-9`,children:(0,X.jsxs)(a,{to:`/local-apps/new`,children:[(0,X.jsx)(g,{className:`size-4`}),t.extensionsPage.createLocalApp]})})]})}),()=>r()),[r,t.extensionsPage.createLocalApp,t.extensionsPage.openLocalApps,t.extensionsPage.title,n]),s&&f!==`marketplace`)return(0,X.jsx)(ye,{});let O=f!==`marketplace`&&T.length>0;return(0,X.jsxs)(`div`,{className:`flex min-h-0 min-w-0 flex-1 flex-col bg-surface-panel`,children:[(0,X.jsxs)(`div`,{className:`mx-auto w-full max-w-7xl px-4 py-7 sm:px-6 lg:px-8 lg:py-9`,children:[(0,X.jsxs)(`div`,{className:`mb-6 flex flex-col gap-3 border-b border-edge-subtle pb-4 sm:flex-row sm:items-center sm:justify-between`,children:[(0,X.jsx)(H,{items:[{id:`marketplace`,label:t.extensionsPage.tabMarketplace},{id:`builtin`,label:t.extensionsPage.tabBuiltin,count:C.length},{id:`user`,label:t.extensionsPage.tabUser,count:w.length}],activeTab:f,onChange:p,ariaLabel:t.extensionsPage.extensionsNavAria,tabIdPrefix:`extensions-tab`,panelIdPrefix:`extensions-panel`,className:`flex-wrap`}),O?(0,X.jsxs)(`div`,{className:`relative w-full min-w-0 sm:max-w-xs`,children:[(0,X.jsx)(z,{className:`pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-fg-muted`,"aria-hidden":!0}),(0,X.jsx)(`input`,{type:`search`,value:m,onChange:e=>h(e.target.value),placeholder:t.extensionsPage.searchPlaceholder,className:`w-full rounded-lg border border-edge bg-surface-base py-2 pl-9 pr-3 text-sm text-fg placeholder:text-fg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,autoComplete:`off`})]}):null]}),f===`marketplace`?(0,X.jsx)(Q,{}):f===`builtin`&&C.length===0?(0,X.jsx)(xe,{message:t.extensionsPage.emptyBuiltin}):f===`user`&&w.length===0?(0,X.jsx)(xe,{message:t.extensionsPage.emptyUser}):E.length===0?(0,X.jsx)(`p`,{className:`px-3 py-14 text-center text-sm text-fg-muted sm:px-5 xl:px-6`,children:t.extensionsPage.noSearchResults}):(0,X.jsx)(`div`,{className:`grid gap-4 sm:grid-cols-2 lg:grid-cols-3`,children:E.map(e=>(0,X.jsx)(ge,{extension:e,copy:t.extensionsPage,showSourceBadge:f===`user`,onOpen:()=>y(e)},e.id))})]}),_?(0,X.jsx)(_e,{extension:_,copy:t.extensionsPage,onClose:()=>y(null)},_.id):null]})}function fe(e){return e.activationEligible??e.active}function pe(e,t){return e.source===`bundled`?t.providerBundled:e.source===`global`?t.providerGlobal:e.source===`workspace`?t.providerWorkspace:t.providerOther}function me(e,t){return e.source===`global`?t.badgeSourceGlobal:e.source===`workspace`?t.badgeSourceWorkspace:t.badgeSourceOther}function he(e,t){let n=fe(e);return n&&e.active?t.runStateLive:n&&!e.active?t.runStatePendingOn:!n&&e.active?t.runStatePendingOff:t.runStateOff}function ge(e){let t=(0,W.c)(45),{extension:n,copy:r,showSourceBadge:i,onOpen:a}=e,o;t[0]===n?o=t[1]:(o=fe(n),t[0]=n,t[1]=o);let s=o,c=n.hasUi?r.cardTooltipHasUi:r.cardTooltipNoUi,l;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(l=w(`group flex w-full flex-col rounded-xl border border-edge-subtle bg-surface-base p-4 text-left shadow-surface transition-colors`,`hover:bg-surface-hover/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,`dark:hover:bg-surface-hover/25`),t[2]=l):l=t[2];let u=n.name||n.id,d;t[3]===u?d=t[4]:(d=u.charAt(0).toUpperCase(),t[3]=u,t[4]=d);let p;t[5]===d?p=t[6]:(p=(0,X.jsx)(`div`,{className:`flex size-12 shrink-0 items-center justify-center rounded-xl bg-accent-soft text-base font-semibold text-accent-fg`,"aria-hidden":!0,children:d}),t[5]=d,t[6]=p);let m;t[7]===n.name?m=t[8]:(m=(0,X.jsx)(`h2`,{className:`truncate text-sm font-semibold text-fg`,children:n.name}),t[7]=n.name,t[8]=m);let h;t[9]===n.version?h=t[10]:(h=n.version?(0,X.jsxs)(`span`,{className:`text-[11px] text-fg-muted`,children:[`v`,n.version]}):null,t[9]=n.version,t[10]=h);let _;t[11]!==m||t[12]!==h?(_=(0,X.jsxs)(`div`,{className:`min-w-0`,children:[m,h]}),t[11]=m,t[12]=h,t[13]=_):_=t[13];let v;t[14]!==r.statusEnabled||t[15]!==s?(v=s?(0,X.jsxs)(`span`,{className:`inline-flex shrink-0 items-center gap-1 rounded-full bg-surface-hover px-2 py-0.5 text-[11px] font-medium text-fg-muted`,children:[(0,X.jsx)(f,{className:`size-3`,strokeWidth:2.5,"aria-hidden":!0}),r.statusEnabled]}):(0,X.jsx)(`span`,{className:`flex size-8 shrink-0 items-center justify-center rounded-full border-2 border-accent text-accent`,"aria-hidden":!0,children:(0,X.jsx)(g,{className:`size-4`,strokeWidth:2.5})}),t[14]=r.statusEnabled,t[15]=s,t[16]=v):v=t[16];let y;t[17]!==_||t[18]!==v?(y=(0,X.jsxs)(`div`,{className:`flex items-start justify-between gap-2`,children:[_,v]}),t[17]=_,t[18]=v,t[19]=y):y=t[19];let b;t[20]!==r.cardNoDescription||t[21]!==n.description?(b=n.description?.trim()||r.cardNoDescription,t[20]=r.cardNoDescription,t[21]=n.description,t[22]=b):b=t[22];let x;t[23]===b?x=t[24]:(x=(0,X.jsx)(`p`,{className:`mt-2 line-clamp-2 text-xs leading-relaxed text-fg-muted`,children:b}),t[23]=b,t[24]=x);let S=n.hasUi?r.badgeKindUi:r.badgeKindBackend,C;t[25]!==S||t[26]!==c?(C=(0,X.jsx)(`span`,{title:c,className:`rounded-md bg-surface-hover px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-fg-muted`,children:S}),t[25]=S,t[26]=c,t[27]=C):C=t[27];let T;t[28]!==r||t[29]!==n||t[30]!==i?(T=n.source===`bundled`?(0,X.jsx)(`span`,{className:`rounded-md bg-surface-hover px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-fg-muted`,children:r.badgeBundled}):i?(0,X.jsx)(`span`,{title:pe(n,r),className:`rounded-md bg-surface-hover px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-fg-muted`,children:me(n,r)}):null,t[28]=r,t[29]=n,t[30]=i,t[31]=T):T=t[31];let E;t[32]!==C||t[33]!==T?(E=(0,X.jsxs)(`div`,{className:`mt-2 flex flex-wrap gap-1.5`,children:[C,T]}),t[32]=C,t[33]=T,t[34]=E):E=t[34];let D;t[35]!==y||t[36]!==x||t[37]!==E?(D=(0,X.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[y,x,E]}),t[35]=y,t[36]=x,t[37]=E,t[38]=D):D=t[38];let O;t[39]!==D||t[40]!==p?(O=(0,X.jsxs)(`div`,{className:`flex gap-3`,children:[p,D]}),t[39]=D,t[40]=p,t[41]=O):O=t[41];let k;return t[42]!==a||t[43]!==O?(k=(0,X.jsx)(`button`,{type:`button`,onClick:a,className:l,children:O}),t[42]=a,t[43]=O,t[44]=k):k=t[44],k}function _e({extension:e,copy:t,onClose:n}){let{mutate:r}=T(),[i,f]=(0,U.useState)(!1),[m,g]=(0,U.useState)(null),[v,y]=(0,U.useState)(!1),b=e.activationEligible===!0,x=(0,U.useCallback)(async()=>{if(e.source===`bundled`){g(null),y(!1),f(!0);try{let{requiresGatewayRestart:t}=await J({extensionId:e.id,enabled:!b});await r(`gateway-extensions-list`),A(),y(t)}catch(e){g(e instanceof Error?e.message:t.builtinToggleFailed)}finally{f(!1)}}},[b,t.builtinToggleFailed,e.id,e.source,r]),S=e.ui?.contributions?.pages??[],C=e.ui?.contributions?.settingsPanels??[],E=e.ui?.contributions?.chatWidgets??[],O=e.ui?.contributions?.sidebarPanels??[],k=S.find(e=>e.showInNav)??S[0],ee=C[0],M=k?N(e.id,k):null,ne=ee?`/settings/ext/${e.id}/${ee.id}`:e.hasConfigSchema||P(e)?`/settings/ext/${e.id}`:null;return(0,X.jsx)(d,{defaultOpen:!0,onOpenChange:e=>!e&&n(),children:(0,X.jsxs)(c,{children:[(0,X.jsx)(o,{className:`xopc-dialog-overlay fixed inset-0 z-[130] bg-scrim`}),(0,X.jsxs)(l,{className:`fixed left-1/2 top-1/2 z-[131] flex max-h-[min(90vh,44rem)] w-[min(42rem,calc(100vw-1.5rem))] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-xl border border-edge bg-surface-panel shadow-elevated`,onOpenAutoFocus:e=>e.preventDefault(),children:[(0,X.jsxs)(`div`,{className:`flex shrink-0 items-center justify-between gap-2 border-b border-edge px-4 py-3`,children:[(0,X.jsx)(`button`,{type:`button`,onClick:n,className:`inline-flex size-9 items-center justify-center rounded-lg text-fg-muted hover:bg-surface-hover hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,"aria-label":t.detailBack,children:(0,X.jsx)(te,{className:`size-5`})}),(0,X.jsx)(u,{className:`min-w-0 flex-1 truncate text-center text-sm font-semibold text-fg`,children:t.detailTitle}),(0,X.jsxs)(s,{className:`sr-only`,children:[e.name,` (`,e.id,`)`]}),(0,X.jsx)(`button`,{type:`button`,onClick:n,className:`inline-flex size-9 items-center justify-center rounded-lg text-fg-muted hover:bg-surface-hover hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,"aria-label":t.detailClose,children:(0,X.jsx)(_,{className:`size-5`})})]}),(0,X.jsxs)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-5`,children:[(0,X.jsxs)(`div`,{className:`flex flex-wrap items-start gap-4`,children:[(0,X.jsx)(`div`,{className:`flex size-16 shrink-0 items-center justify-center rounded-2xl bg-accent-soft text-xl font-semibold text-accent-fg`,"aria-hidden":!0,children:(e.name||e.id).charAt(0).toUpperCase()}),(0,X.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,X.jsx)(`h3`,{className:`text-lg font-semibold text-fg`,children:e.name}),(0,X.jsxs)(`p`,{className:`mt-0.5 text-sm text-fg-muted`,children:[t.detailProviderPrefix,` `,pe(e,t)]}),e.version?(0,X.jsxs)(`p`,{className:`mt-1 text-xs text-fg-muted`,children:[`v`,e.version]}):null]})]}),(0,X.jsx)(`p`,{className:`mt-5 text-sm leading-relaxed text-fg`,children:e.description?.trim()||t.detailNoDescription}),e.hasUi?null:(0,X.jsx)(`p`,{className:`mt-3 text-xs text-fg-muted`,children:t.backendOnlyHint}),(0,X.jsx)(`p`,{className:`mt-2 text-xs text-fg-muted`,children:he(e,t)}),e.source===`bundled`?(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(`p`,{className:`mt-4 rounded-lg bg-surface-hover/40 px-3 py-2 text-xs text-fg-muted shadow-surface dark:bg-surface-hover/20`,children:t.builtinConfigHint}),(0,X.jsxs)(`div`,{className:`mt-3 rounded-lg bg-surface-hover/40 p-3 shadow-surface dark:bg-surface-hover/20`,children:[(0,X.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,X.jsx)(`span`,{className:`text-xs font-medium text-fg`,children:t.builtinRuntimeToggle}),(0,X.jsx)(D,{type:`button`,variant:`secondary`,disabled:i,onClick:()=>void x(),className:`shrink-0 py-1.5 text-xs`,children:i?(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(h,{className:`mr-1.5 size-3.5 shrink-0 animate-spin`,"aria-hidden":!0}),t.builtinToggleBusy]}):b?t.builtinToggleDisable:t.builtinToggleEnable})]}),m?(0,X.jsx)(`p`,{className:`mt-2 text-xs text-rose-600 dark:text-rose-400`,children:m}):null,v?(0,X.jsx)(`p`,{className:`mt-2 text-xs text-fg-muted`,children:t.builtinToggleRestartHint}):null]})]}):(0,X.jsx)(`p`,{className:`mt-4 rounded-lg bg-surface-hover/40 px-3 py-2 text-xs text-fg-muted shadow-surface dark:bg-surface-hover/20`,children:t.cliManageHint}),e.hasUi&&(S.length>0||C.length>0||E.length>0)?(0,X.jsxs)(`section`,{className:`mt-8`,children:[(0,X.jsx)(`h4`,{className:`mb-3 text-sm font-semibold text-fg`,children:t.detailSectionFeatures}),(0,X.jsxs)(`div`,{className:`flex flex-wrap gap-1.5`,children:[(0,X.jsx)(ve,{template:t.badgePages,count:S.length,hidden:S.length===0}),(0,X.jsx)(ve,{template:t.badgeSettings,count:C.length,hidden:C.length===0}),(0,X.jsx)(ve,{template:t.badgeWidgets,count:E.length,hidden:E.length===0}),(0,X.jsx)(ve,{template:t.badgeSidebar,count:O.length,hidden:O.length===0})]})]}):null,j(e)&&(M||ne)?(0,X.jsxs)(`div`,{className:`mt-6 flex flex-wrap gap-2 border-t border-edge-subtle pt-4`,children:[M?(0,X.jsxs)(a,{to:M,onClick:n,className:w(`inline-flex items-center gap-1.5 rounded-lg border border-edge px-3 py-2 text-sm font-medium text-fg`,`hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`),children:[(0,X.jsx)(p,{className:`size-4 shrink-0 opacity-80`,"aria-hidden":!0}),t.open]}):null,ne?(0,X.jsxs)(a,{to:ne,onClick:n,className:w(`inline-flex items-center gap-1.5 rounded-lg border border-edge px-3 py-2 text-sm font-medium text-fg`,`hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`),children:[(0,X.jsx)(L,{className:`size-4 shrink-0 opacity-80`,"aria-hidden":!0}),t.openSettings]}):null]}):null,(0,X.jsx)(`p`,{className:`mt-6 text-[11px] leading-relaxed text-fg-muted`,children:t.restartNote})]})]})]})})}function ve(e){let t=(0,W.c)(6),{template:n,count:r,hidden:i}=e;if(i||r===0)return null;let a;if(t[0]!==r||t[1]!==n){let e;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(e=/\{\{count\}\}/g,t[3]=e):e=t[3],a=n.replace(e,String(r)),t[0]=r,t[1]=n,t[2]=a}else a=t[2];let o;return t[4]===a?o=t[5]:(o=(0,X.jsx)(`span`,{className:`inline-flex items-center rounded-md bg-surface-hover px-2 py-0.5 text-[11px] font-medium text-fg-muted`,children:a}),t[4]=a,t[5]=o),o}function ye(){let e=(0,W.c)(5),t,n,r;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,X.jsx)(`div`,{className:`mb-6 h-8 w-40 max-w-full animate-pulse rounded-md bg-surface-hover`}),n=(0,X.jsx)(`div`,{className:`mb-2 h-4 w-full max-w-md animate-pulse rounded bg-surface-hover`}),r=(0,X.jsx)(`div`,{className:`mb-5 h-9 w-full max-w-lg animate-pulse rounded-full bg-surface-hover`}),e[0]=t,e[1]=n,e[2]=r):(t=e[0],n=e[1],r=e[2]);let i;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(i=[`ap0`,`ap1`,`ap2`,`ap3`,`ap4`,`ap5`],e[3]=i):i=e[3];let a;return e[4]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,X.jsx)(`div`,{className:`flex min-h-0 min-w-0 flex-1 flex-col bg-surface-panel`,children:(0,X.jsxs)(`div`,{className:`w-full px-3 py-8 sm:px-5 xl:px-6`,children:[t,n,r,(0,X.jsx)(`div`,{className:`mt-6 grid gap-4 sm:grid-cols-2 lg:grid-cols-3`,children:i.map(be)})]})}),e[4]=a):a=e[4],a}function be(e){return(0,X.jsx)(`div`,{className:`h-36 animate-pulse rounded-xl border border-edge-subtle bg-surface-base shadow-surface`},e)}function xe(e){let t=(0,W.c)(2),{message:n}=e,r;return t[0]===n?r=t[1]:(r=(0,X.jsx)(`div`,{className:`flex min-h-[min(40vh,16rem)] flex-col items-center justify-center rounded-xl border border-edge-subtle bg-surface-base px-4 py-12 text-center shadow-surface`,children:(0,X.jsx)(`p`,{className:`text-sm text-fg-muted`,children:n})}),t[0]=n,t[1]=r),r}export{de as ExtensionsPage};
|