@xopcai/xopc 0.0.265 → 0.0.267

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/dist/browser-ext/dist/assets/{auth-CknJ00ae.js → auth-D_IL6naL.js} +603 -203
  2. package/dist/browser-ext/dist/assets/sidepanel-CEPaVLjr.css +155 -0
  3. package/dist/browser-ext/dist/background.js +698 -169
  4. package/dist/browser-ext/dist/sidepanel.html +3 -3
  5. package/dist/browser-ext/dist/sidepanel.js +148 -391
  6. package/dist/browser-ext/manifest.json +3 -6
  7. package/dist/extensions/telegram/xopc.extension.json +1 -1
  8. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DRTTU2H3.js → agent-avatar-dicebear-ZrSAMchm.js} +1 -1
  9. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-BsXF7LVi.js → agent-defaults-settings-panel-DiNFN8qS.js} +1 -1
  10. package/dist/gateway/static/root/assets/{agents-DpjWfxYx.js → agents-Bu6Hf59K.js} +1 -1
  11. package/dist/gateway/static/root/assets/{app-management-settings-panel-33Mc81h2.js → app-management-settings-panel-D-L6yjS7.js} +1 -1
  12. package/dist/gateway/static/root/assets/{appearance-settings-C8JECSiJ.js → appearance-settings-BW5eb53j.js} +1 -1
  13. package/dist/gateway/static/root/assets/{apps-page-t64FcxIZ.js → apps-page-CiQIdz3N.js} +1 -1
  14. package/dist/gateway/static/root/assets/{archive-plugin-PzZ6SzfY.js → archive-plugin-DwXvu1p9.js} +1 -1
  15. package/dist/gateway/static/root/assets/{attachment-load-OhLL6K__.js → attachment-load-DqU2BYBp.js} +1 -1
  16. package/dist/gateway/static/root/assets/{automations-page-BpAYwuvx.js → automations-page-C7qoj9Sd.js} +1 -1
  17. package/dist/gateway/static/root/assets/{automations-workspace-B6aTT5IC.js → automations-workspace-CIARTLHO.js} +1 -1
  18. package/dist/gateway/static/root/assets/{binary-plugins-B5XpGsHg.js → binary-plugins-CfplDak2.js} +1 -1
  19. package/dist/gateway/static/root/assets/{block-editor-BgEhoTnN.js → block-editor-CzLs38ru.js} +1 -1
  20. package/dist/gateway/static/root/assets/{browser-automations-page-CBLunDRH.js → browser-automations-page-_SKi8s9b.js} +1 -1
  21. package/dist/gateway/static/root/assets/browser-settings-page-DTdx66sX.js +8 -0
  22. package/dist/gateway/static/root/assets/{capabilities-settings-panel-DftNnICK.js → capabilities-settings-panel-Ck9U0Olx.js} +1 -1
  23. package/dist/gateway/static/root/assets/{channels-settings-CpuWa5qu.js → channels-settings-I_vDpbnl.js} +1 -1
  24. package/dist/gateway/static/root/assets/{chat-terminal-dock-mnPsS_GJ.js → chat-terminal-dock-snvAu3hJ.js} +1 -1
  25. package/dist/gateway/static/root/assets/{connectors-page-D3nHGnNV.js → connectors-page-BmKTnzo1.js} +1 -1
  26. package/dist/gateway/static/root/assets/{cron-expression-NcGBvIfe.js → cron-expression-BhGZSbT6.js} +1 -1
  27. package/dist/gateway/static/root/assets/{date-picker-BrVcl7H5.js → date-picker-Cep5f9b-.js} +1 -1
  28. package/dist/gateway/static/root/assets/{dependency-picker--edd48Y9.js → dependency-picker-BzSEBQku.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-vuyyb6I6.js → desktop-pet-BwX_6Gah.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-settings-DWredJwO.js → desktop-pet-settings-WrbVsU2b.js} +1 -1
  31. package/dist/gateway/static/root/assets/{extension-debug-page-CtBW4ebj.js → extension-debug-page-BdXSwtAZ.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-page-CsUrmtW7.js → extension-page-I95ukbRb.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-settings-page-BUd31AuK.js → extension-settings-page-8zUisBay.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-settings-C6FQv7op.js → gateway-settings-DGj5b9Yv.js} +1 -1
  35. package/dist/gateway/static/root/assets/{heartbeat-settings-CDo1Gjp2.js → heartbeat-settings-BGQxU-Ug.js} +1 -1
  36. package/dist/gateway/static/root/assets/{home-page-D3_uvVJY.js → home-page-BZPpK0A3.js} +1 -1
  37. package/dist/gateway/static/root/assets/{index-Dpu7EKTm.js → index-D2OtD9Wa.js} +8 -8
  38. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CNVmrCrV.js → keyboard-shortcuts-settings-BUe_om99.js} +1 -1
  39. package/dist/gateway/static/root/assets/{local-app-workbench-page-B0IVDvs-.js → local-app-workbench-page-CbQnffS9.js} +1 -1
  40. package/dist/gateway/static/root/assets/{local-apps-page-DvkarvLt.js → local-apps-page-BZaLzfms.js} +1 -1
  41. package/dist/gateway/static/root/assets/{logs-page-BknY0vZf.js → logs-page-WWCHqW_x.js} +1 -1
  42. package/dist/gateway/static/root/assets/{management-settings-DW6hJINQ.js → management-settings-Duf8w-Bl.js} +1 -1
  43. package/dist/gateway/static/root/assets/{media-plugins-DYautOWY.js → media-plugins-2-QfzHmg.js} +1 -1
  44. package/dist/gateway/static/root/assets/{mobile-pairing-wizard-Dgu03cv-.js → mobile-pairing-wizard-DRaVIAt1.js} +1 -1
  45. package/dist/gateway/static/root/assets/{note-detail-panel-Cv9uH6Jq.js → note-detail-panel-BT-fWGxX.js} +3 -3
  46. package/dist/gateway/static/root/assets/{notes-page-DcIAiYJn.js → notes-page-C4705PzN.js} +1 -1
  47. package/dist/gateway/static/root/assets/{page-tabs-DF6Q5XvA.js → page-tabs-DaZ7QpNO.js} +1 -1
  48. package/dist/gateway/static/root/assets/{preview-open-alternatives-CQJH_jAN.js → preview-open-alternatives-CWEuqCmv.js} +1 -1
  49. package/dist/gateway/static/root/assets/{project-detail-page-D65JfNSw.js → project-detail-page-BZegJ6an.js} +1 -1
  50. package/dist/gateway/static/root/assets/{projects-page-BfWF7Sz-.js → projects-page-B7hUHeLI.js} +1 -1
  51. package/dist/gateway/static/root/assets/{remote-access-hub-DA1g4CUD.js → remote-access-hub-BE9hZpdh.js} +1 -1
  52. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-0-bFSBB8.js → runtime-tools-settings-panel-CslkSM-m.js} +1 -1
  53. package/dist/gateway/static/root/assets/{schema-form-csGbhTUr.js → schema-form-B2gvVrBq.js} +1 -1
  54. package/dist/gateway/static/root/assets/{sessions-page-DXPBNhrZ.js → sessions-page-DmAAPMo1.js} +1 -1
  55. package/dist/gateway/static/root/assets/settings-advanced-gate-CvBocGDA.js +1 -0
  56. package/dist/gateway/static/root/assets/{settings-form-section-YdrdY8B3.js → settings-form-section-CmlnuSO3.js} +1 -1
  57. package/dist/gateway/static/root/assets/{settings-page-Cv9waRn3.js → settings-page-DWWgyelT.js} +1 -1
  58. package/dist/gateway/static/root/assets/{setup-status-panel-DPf-_05Z.js → setup-status-panel-CJrN3m1o.js} +1 -1
  59. package/dist/gateway/static/root/assets/{share-preview-page-DBoEHTPn.js → share-preview-page-C12oyIKk.js} +1 -1
  60. package/dist/gateway/static/root/assets/{shares-settings-BQP5yNcO.js → shares-settings-D4BtSiLq.js} +1 -1
  61. package/dist/gateway/static/root/assets/{skill-reload-api-B5T8cgjq.js → skill-reload-api-CzKGn056.js} +1 -1
  62. package/dist/gateway/static/root/assets/{skills-page-D1G8h2Lt.js → skills-page-yhW7LLqk.js} +1 -1
  63. package/dist/gateway/static/root/assets/{skills-page.utils-BNZYTop7.js → skills-page.utils-FaTlq8t-.js} +1 -1
  64. package/dist/gateway/static/root/assets/{system-settings-panel-ByuppbHi.js → system-settings-panel-CMrkoJLN.js} +1 -1
  65. package/dist/gateway/static/root/assets/{task-detail-page-DNmkrF6y.js → task-detail-page-BUaO62cy.js} +1 -1
  66. package/dist/gateway/static/root/assets/{tunnel-api-CxWGpbwr.js → tunnel-api-C2tAZaJz.js} +1 -1
  67. package/dist/gateway/static/root/assets/{use-autosave-B0l4qubU.js → use-autosave-BsDRt4QI.js} +1 -1
  68. package/dist/gateway/static/root/assets/{user-model-page-DMsI6YI7.js → user-model-page-Dy8h1SSJ.js} +1 -1
  69. package/dist/gateway/static/root/assets/{voice-api-key-field-Bcz7boJg.js → voice-api-key-field-CS5heYMP.js} +1 -1
  70. package/dist/gateway/static/root/assets/{work-discovery-overlay-Dujq1j_u.js → work-discovery-overlay-BeSz5Th5.js} +1 -1
  71. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CxNYbLNB.js → workflow-run-setup-panel-BebW0CDK.js} +1 -1
  72. package/dist/gateway/static/root/assets/{workflows-page-Dk1jK2nv.js → workflows-page-CU8jFgPF.js} +1 -1
  73. package/dist/gateway/static/root/index.html +1 -1
  74. package/dist/package.js +1 -1
  75. package/dist/packages/browser-control-contract/src/index.js +30 -1
  76. package/dist/src/agent/agent-manager.js +4 -4
  77. package/dist/src/agent/background-review/run-background-review.js +1 -1
  78. package/dist/src/agent/embedded/model-runtime.js +1 -1
  79. package/dist/src/agent/embedded/run-for-session.js +1 -1
  80. package/dist/src/agent/external-tools/endpoint-provider.js +3 -1
  81. package/dist/src/agent/image/tool-model-config.js +1 -1
  82. package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
  83. package/dist/src/agent/service.js +2 -2
  84. package/dist/src/agent/session/session-inspector.js +1 -1
  85. package/dist/src/agent/skills/hub-lock.js +1 -1
  86. package/dist/src/agent/tasks/task-judge-service.js +3 -3
  87. package/dist/src/agent/tools/factory.js +1 -1
  88. package/dist/src/ai-assist/text-assist.js +1 -1
  89. package/dist/src/auth/credentials.js +2 -2
  90. package/dist/src/auth/oauth/xopc-cloud.js +1 -1
  91. package/dist/src/auth/profiles/store.js +1 -1
  92. package/dist/src/auth/sync-provider-auth.js +2 -2
  93. package/dist/src/browser/automations/runtime-service.d.ts +2 -0
  94. package/dist/src/browser/automations/runtime-service.js +1 -1
  95. package/dist/src/browser/drivers/create-driver.d.ts +2 -1
  96. package/dist/src/browser/drivers/create-driver.js +4 -6
  97. package/dist/src/browser/drivers/extension-driver.d.ts +7 -2
  98. package/dist/src/browser/enrollment.d.ts +8 -0
  99. package/dist/src/browser/enrollment.js +25 -0
  100. package/dist/src/browser/extension-identity.d.ts +2 -0
  101. package/dist/src/browser/extension-identity.js +5 -0
  102. package/dist/src/browser/native-messaging-host.d.ts +6 -3
  103. package/dist/src/browser/native-messaging-host.js +23 -5
  104. package/dist/src/browser/providers/browser-ext-install.d.ts +4 -1
  105. package/dist/src/browser/providers/browser-ext-install.js +47 -8
  106. package/dist/src/browser/providers/extension.js +1 -1
  107. package/dist/src/browser/providers/realtime-extension.d.ts +29 -0
  108. package/dist/src/browser/providers/realtime-extension.js +83 -0
  109. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  110. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  111. package/dist/src/cli/commands/models.js +1 -1
  112. package/dist/src/config/index.js +4 -4
  113. package/dist/src/config/loader.js +2 -2
  114. package/dist/src/config/models-json.js +1 -1
  115. package/dist/src/endpoint-tools/policy.js +10 -3
  116. package/dist/src/extensions/lockfile.js +1 -1
  117. package/dist/src/gateway/agents-admin.js +1 -1
  118. package/dist/src/gateway/file-path-classifier.js +1 -1
  119. package/dist/src/gateway/hono/app.js +6 -1
  120. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  121. package/dist/src/gateway/hono/routes/browser.js +20 -30
  122. package/dist/src/gateway/hono/routes/models.js +1 -1
  123. package/dist/src/gateway/security/origin-check.js +5 -0
  124. package/dist/src/gateway/service/config-coordinator.d.ts +0 -2
  125. package/dist/src/gateway/service/config-coordinator.js +1 -3
  126. package/dist/src/gateway/service.d.ts +0 -11
  127. package/dist/src/gateway/service.js +5 -83
  128. package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
  129. package/dist/src/providers/index.js +2 -2
  130. package/dist/src/providers/model-registry.js +1 -1
  131. package/dist/src/providers/register-runtime-providers.js +1 -1
  132. package/dist/src/storage/sqlite/device-pairing-approval.js +24 -3
  133. package/dist/src/storage/sqlite/device-pairing-repository.d.ts +10 -1
  134. package/dist/src/storage/sqlite/device-pairing-repository.js +6 -5
  135. package/dist/src/storage/sqlite/migrations/157_browser_endpoint_principals.sql +50 -0
  136. package/dist/src/storage/sqlite/migrations/158_browser_native_enrollment.sql +4 -0
  137. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  138. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  139. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  140. package/dist/src/storage/sqlite/schema.js +1 -1
  141. package/dist/src/tui/tui-startup-resources.js +1 -1
  142. package/dist/src/tui/tui.js +1 -1
  143. package/dist/src/work-discovery/service.js +1 -1
  144. package/dist/src/workflows/service/workflow-run-service.js +1 -1
  145. package/package.json +3 -3
  146. package/dist/browser-ext/dist/assets/sidepanel-C69P3v9u.css +0 -113
  147. package/dist/gateway/static/root/assets/browser-settings-page-CSfpPCuD.js +0 -8
  148. package/dist/gateway/static/root/assets/settings-advanced-gate-DxeZm67O.js +0 -1
@@ -0,0 +1,83 @@
1
+ import { getBrowserTabBindingById } from "../../storage/sqlite/browser-tab-binding-repository.js";
2
+ import { BROWSER_CONTROL_ENDPOINT_TOOL_NAME } from "../../../packages/browser-control-contract/src/index.js";
3
+ import crypto from "node:crypto";
4
+ //#region src/browser/providers/realtime-extension.ts
5
+ var RealtimeExtensionBrowserProvider = class {
6
+ name = "extension";
7
+ connectionTimeout;
8
+ commandTimeout;
9
+ constructor(runtime, config = {}) {
10
+ this.runtime = runtime;
11
+ this.connectionTimeout = config.connectionTimeout ?? 3e4;
12
+ this.commandTimeout = config.commandTimeout ?? 3e4;
13
+ }
14
+ async start() {}
15
+ async waitForConnection(timeoutMs = this.connectionTimeout) {
16
+ const deadline = Date.now() + timeoutMs;
17
+ while (!this.currentEndpoint()) {
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
+ await new Promise((resolve) => setTimeout(resolve, 200));
20
+ }
21
+ }
22
+ async send(input, timeoutMs = this.commandTimeout, visualFallback = true) {
23
+ const endpoint = this.endpointForInput(input);
24
+ if (!endpoint) throw new Error("Extension not connected to this Gateway. Open the xopc Chrome extension and connect it first.");
25
+ const tool = this.runtime.registry.getTool(endpoint.endpointId, BROWSER_CONTROL_ENDPOINT_TOOL_NAME);
26
+ if (!tool) throw new Error("Connected browser extension does not support authenticated Realtime browser control. Reload or update the extension.");
27
+ const id = crypto.randomUUID();
28
+ const controller = new AbortController();
29
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
30
+ try {
31
+ const value = (await this.runtime.invocations.invoke({
32
+ endpointId: endpoint.endpointId,
33
+ toolCallId: `browser-control:${id}`,
34
+ toolName: tool.descriptor.name,
35
+ arguments: {
36
+ input,
37
+ timeoutMs,
38
+ visualFallback
39
+ },
40
+ descriptorRevision: tool.revision,
41
+ signal: controller.signal
42
+ })).content.find((item) => item.type === "json");
43
+ if (!value || !value.value || typeof value.value !== "object") throw new Error("Browser extension returned an invalid Realtime result");
44
+ return {
45
+ id,
46
+ connectionId: endpoint.endpointId,
47
+ result: value.value
48
+ };
49
+ } finally {
50
+ clearTimeout(timer);
51
+ }
52
+ }
53
+ isConnected() {
54
+ return Boolean(this.currentEndpoint());
55
+ }
56
+ getConnectionStatus() {
57
+ const endpoint = this.currentEndpoint();
58
+ return {
59
+ socketConnected: Boolean(endpoint),
60
+ connected: Boolean(endpoint),
61
+ protocolVersion: endpoint ? 4 : null,
62
+ expectedProtocolVersion: 4,
63
+ extensionVersion: endpoint?.appVersion ?? null,
64
+ principalId: endpoint?.principalId ?? null,
65
+ transport: "gateway-realtime"
66
+ };
67
+ }
68
+ async shutdown() {}
69
+ endpointForInput(input) {
70
+ if (input.target?.kind === "attached_tab") {
71
+ const binding = getBrowserTabBindingById(input.target.bindingId);
72
+ const endpoint = binding ? this.runtime.registry.get(binding.endpointId) : void 0;
73
+ if (!binding || !endpoint || endpoint.principalId !== binding.principalId) return void 0;
74
+ return endpoint;
75
+ }
76
+ return this.currentEndpoint();
77
+ }
78
+ currentEndpoint() {
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)[0];
80
+ }
81
+ };
82
+ //#endregion
83
+ export { RealtimeExtensionBrowserProvider };
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
52
52
  id: "database-schema",
53
53
  label: "Database schema",
54
54
  status: "pass",
55
- message: `SQLite schema v${status.dbVersion} (current release v156).`,
55
+ message: `SQLite schema v${status.dbVersion} (current release v158).`,
56
56
  hints: []
57
57
  };
58
58
  }
@@ -1,6 +1,6 @@
1
1
  import { getAgentDefaultModelRef, init_schema, parseModelRef } from "../../../../config/schema.js";
2
- import { init_loader, loadConfig } from "../../../../config/loader.js";
3
2
  import { PROVIDER_ENV_MAP, getApiKeyFromEnv, init_env_keys } from "../../../../providers/env-keys.js";
3
+ import { init_loader, loadConfig } from "../../../../config/loader.js";
4
4
  import { existsSync } from "node:fs";
5
5
  //#region src/cli/commands/doctor/checks/provider-auth.ts
6
6
  init_loader();
@@ -1,6 +1,6 @@
1
1
  import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
2
- import { loadConfig, saveConfig } from "../../config/loader.js";
3
2
  import { CredentialResolver, init_credentials } from "../../auth/credentials.js";
3
+ import { loadConfig, saveConfig } from "../../config/loader.js";
4
4
  import { getAllModels, getAvailableModels, getConfiguredProviders, getProviderAuthState, getProviderDisplayName, init_providers, isProviderConfigured, providerSupportsApiKey, providerSupportsOAuth, resolveModel } from "../../providers/index.js";
5
5
  import { formatExamples, register } from "../registry.js";
6
6
  import { getContextWithOpts } from "../context.js";
@@ -2,15 +2,15 @@ import { ENV_VARS, XOPC_DB_FILENAME, resolveHomeDir, resolveStateDir, resolveXop
2
2
  import { TelegramAccountConfigSchema, TelegramConfigSchema, TelegramGroupConfigSchema, TelegramTopicConfigSchema } from "../../extensions/telegram/src/config-schema.js";
3
3
  import { WeixinAccountConfigSchema, WeixinConfigSchema } from "../../extensions/weixin/src/config-schema.js";
4
4
  import { AgentImageGenerationModelSchema, AgentModelRefSchema, AgentModelsSchema, AgentsConfigSchema, BindingMatchSchema, BindingRuleSchema, BindingsConfigSchema, BrowserConfigSchema, ChannelsConfigSchema, CommandsConfigSchema, ConfigSchema, ConnectorsConfigSchema, ExperimentalConfigSchema, ExtensionSecurityConfigSchema, ExtensionSlotsConfigSchema, ExtensionsConfigSchema, GatewayAuthRateLimitSchema, GatewayAuthSchema, GatewayBindModeSchema, GatewayChannelConnectDeferModeSchema, GatewayConfigSchema, GatewayModeSchema, GatewayRemoteSchema, GatewaySecuritySchema, GatewayTailscaleConsentSchema, GatewayTailscaleSchema, GatewayTlsSchema, GatewayTrustedProxySchema, GatewayWebchatConfigSchema, HeartbeatConfigSchema, McpConfigSchema, McpOAuthConfigSchema, McpServerSchema, MediaUnderstandingCapabilitiesSchema, MediaUnderstandingModelSchema, MessagesConfigSchema, ModelCatalogConfigSchema, ModelsDevConfigSchema, ProviderAuthConfigSchema, ProviderAzureConfigSchema, ProviderRequestOverridesSchema, ProvidersConfigSchema, RuntimeToolsConfigSchema, STTConfigSchema, STTFallbackConfigSchema, STTProviderConfigSchema, SearchProviderEntrySchema, SessionConfigSchema, SessionDmScopeSchema, SessionResetByTypeSchema, SessionResetConfigSchema, SessionResetModeSchema, SessionScopeSchema, SessionStorageConfigSchema, TTSConfigSchema, TTSEdgeConfigSchema, TTSFallbackConfigSchema, TTSModelOverridesConfigSchema, TTSProviderConfigSchema, TTSSummarizationConfigSchema, ToolsConfigSchema, ToolsMediaAudioConfigSchema, ToolsMediaConfigSchema, TuiConfigSchema, TunnelConfigSchema, TunnelConsentSchema, UpdateAutoConfigSchema, UpdateConfigSchema, VoiceConfigSchema, VoiceRefinementConfigSchema, WebSearchConfigSchema, WebToolsConfigSchema, WebsiteBlocklistSchema, WorkspaceConfigSchema, WorkspaceImportConfigSchema, getAgentDefaultImageGenerationModelConfig, getAgentDefaultImageModelConfig, getAgentDefaultModelRef, init_schema, parseModelRef } from "./schema.js";
5
- import { applyConfigOverrides, getConfigOverrides, resetConfigOverrides, setConfigOverride, unsetConfigOverride } from "./runtime-overrides.js";
5
+ import { clearConfigValueCache, getAllowedCommands, getCacheStats, init_resolve_config_value, resolveConfigValue, resolveHeaders, testApiKeyResolution } from "./resolve-config-value.js";
6
6
  import { expandWorkspacePathString, init_workspace_path, normalizeWorkspaceDir, resolveWorkspaceRoot } from "./workspace-path.js";
7
7
  import { resolveDefaultAgentWorkspaceDir } from "./workspace-defaults.js";
8
8
  import { resolveAgentDir as resolveAgentDir$1, resolveAgentHomeDir as resolveAgentHomeDir$1, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
9
- import { extractProfileAgentId, resolveEffectiveAgentConfigForAgent, resolveEffectiveAgentConfigForSession, resolveEffectiveAgentProfile, resolveEffectiveAgentProfileForSession } from "./agent-profile.js";
10
9
  import { FILENAMES, WORKSPACE_FILES, existsSync, hasBundledExtensionManifest, init_paths, resolveAgentAuthProfilesPath, resolveAgentDir, resolveAgentHomeDir, resolveAgentProfileDir, resolveAgentProfileMarkdownPath, resolveAuthProfilesPath, resolveBinDir, resolveBundledExtensionsDir, resolveBundledSkillsDir, resolveConfigPath, resolveCredentialsDir, resolveExtensionSdkPath, resolveExtensionsDir, resolveExtensionsLockPath, resolveInboxDir, resolveInboxMessagePath, resolveInboxPendingDir, resolveInboxProcessedDir, resolveLogPath, resolveLogsDir, resolveMcpOAuthPath, resolveModelsJsonPath, resolveNodeBinDir, resolveNodeBinPath, resolveNodeToolsDir, resolveNpmBinPath, resolveOAuthPath, resolvePidPath, resolveSkillPath, resolveSkillsCachePath, resolveSkillsDir, resolveSkillsLockPath, resolveSocketPath, resolveStatusPath, resolveToolsDir, resolveWorkspaceExtensionsDir, resolveWorkspaceFile, resolveWorkspaceStateDir, resolveWorkspaceStatePath, resolveXopcBinPath } from "./paths.js";
11
- import { init_loader, loadConfig, saveConfig } from "./loader.js";
12
- import { clearConfigValueCache, getAllowedCommands, getCacheStats, init_resolve_config_value, resolveConfigValue, resolveHeaders, testApiKeyResolution } from "./resolve-config-value.js";
13
10
  import { CustomModelSchema, ImageGenerationCapabilitiesSchema, ImageGenerationModelSchema, ImageGenerationProviderSchema, ModelOverrideSchema, ModelsJsonSchema, OpenAICompatSchema, OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema, OpenRouterRoutingSchema, ProviderConfigSchema, VercelGatewayRoutingSchema, getDefaultModelValues, init_models_json, loadModelsJson, modelsJsonExists, saveModelsJson, validateModelsConfig } from "./models-json.js";
11
+ import { init_loader, loadConfig, saveConfig } from "./loader.js";
12
+ import { applyConfigOverrides, getConfigOverrides, resetConfigOverrides, setConfigOverride, unsetConfigOverride } from "./runtime-overrides.js";
13
+ import { extractProfileAgentId, resolveEffectiveAgentConfigForAgent, resolveEffectiveAgentConfigForSession, resolveEffectiveAgentProfile, resolveEffectiveAgentProfileForSession } from "./agent-profile.js";
14
14
  import { canonicalizeConfiguredMcpServer, isKnownCliMcpTypeAlias, normalizeConfiguredMcpServers, resolveXopcMcpTransportAlias } from "./mcp-config-normalize.js";
15
15
  import { formatThinkingLevels, listThinkingLevels, normalizeElevatedMode, normalizeReasoningLevel, normalizeThinkLevel, normalizeVerboseLevel, thinkLevelToNumber } from "../agent/transcript/thinking-types.js";
16
16
  import { getWorkspacePath } from "./workspace-path-helpers.js";
@@ -2,10 +2,10 @@ import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
2
  import { createLogger } from "../utils/logger/index.js";
3
3
  import { init_logger } from "../utils/logger.js";
4
4
  import { ConfigSchema, init_schema } from "./schema.js";
5
- import { init_paths, resolveConfigPath } from "./paths.js";
6
5
  import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
7
- import { assertChannelPluginConfigs, init_validate_channel_configs } from "./validate-channel-configs.js";
6
+ import { init_paths, resolveConfigPath } from "./paths.js";
8
7
  import { init_resolution, setActivePlatformDiscovery } from "../platform/resolution.js";
8
+ import { assertChannelPluginConfigs, init_validate_channel_configs } from "./validate-channel-configs.js";
9
9
  import { dirname } from "path";
10
10
  import { existsSync, mkdirSync, promises, readFileSync } from "fs";
11
11
  import { config } from "dotenv";
@@ -1,6 +1,6 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
- import { init_paths, resolveModelsJsonPath } from "./paths.js";
3
2
  import { init_write_file_atomic, writeTextAtomicSync } from "../infra/write-file-atomic.js";
3
+ import { init_paths, resolveModelsJsonPath } from "./paths.js";
4
4
  import { existsSync, readFileSync } from "fs";
5
5
  import { z } from "zod";
6
6
  //#region src/config/models-json.ts
@@ -1,11 +1,13 @@
1
1
  import { ENDPOINT_CONTACT_LIST_OUTPUT_SCHEMA, ENDPOINT_CONTACT_OUTPUT_SCHEMA, ENDPOINT_FILE_OUTPUT_SCHEMA, ENDPOINT_TEXT_OUTPUT_SCHEMA, canonicalJson } from "../../packages/endpoint-tools-protocol/src/index.js";
2
+ import { BROWSER_CONTROL_ENDPOINT_INPUT_SCHEMA, BROWSER_CONTROL_ENDPOINT_OUTPUT_SCHEMA } from "../../packages/browser-control-contract/src/index.js";
2
3
  import Ajv2020 from "ajv/dist/2020.js";
3
4
  //#region src/endpoint-tools/policy.ts
4
5
  var EndpointToolPolicyError = class extends Error {};
5
- function contract(policyId, outputSchema, resultKinds, permissions, legacyPolicyIds = []) {
6
+ function contract(policyId, outputSchema, resultKinds, permissions, legacyPolicyIds = [], inputSchema) {
6
7
  return {
7
8
  policyId,
8
9
  legacyPolicyIds,
10
+ inputSchema,
9
11
  outputSchema,
10
12
  resultKinds,
11
13
  permissions
@@ -31,7 +33,8 @@ const POLICY_BY_TOOL = {
31
33
  "mobile.notification.show": contract("user.foreground-write", ENDPOINT_TEXT_OUTPUT_SCHEMA, ["text"], ["notifications"]),
32
34
  "mobile.device.get_info": contract("public.background-read", ENDPOINT_TEXT_OUTPUT_SCHEMA, ["text"], []),
33
35
  "mobile.clipboard.write": contract("user.foreground-write", ENDPOINT_TEXT_OUTPUT_SCHEMA, ["text"], ["clipboard-write"]),
34
- "mobile.app.open_url": contract("user.foreground-write", ENDPOINT_TEXT_OUTPUT_SCHEMA, ["text"], ["open-external-url"])
36
+ "mobile.app.open_url": contract("user.foreground-write", ENDPOINT_TEXT_OUTPUT_SCHEMA, ["text"], ["open-external-url"]),
37
+ "browser.control": contract("browser.control", BROWSER_CONTROL_ENDPOINT_OUTPUT_SCHEMA, ["json"], ["browser-control"], [], BROWSER_CONTROL_ENDPOINT_INPUT_SCHEMA)
35
38
  };
36
39
  var EndpointToolPolicy = class {
37
40
  ajv = new Ajv2020({
@@ -43,7 +46,7 @@ var EndpointToolPolicy = class {
43
46
  const contract = POLICY_BY_TOOL[descriptor.name];
44
47
  if (!contract) throw new EndpointToolPolicyError(`Tool ${descriptor.name} has no trusted server policy`);
45
48
  if (descriptor.policyId !== contract.policyId && !contract.legacyPolicyIds.includes(descriptor.policyId)) throw new EndpointToolPolicyError(`Tool ${descriptor.name} does not match its trusted server policy`);
46
- if (canonicalJson(descriptor.outputSchema) !== canonicalJson(contract.outputSchema) || canonicalJson(descriptor.resultKinds) !== canonicalJson(contract.resultKinds) || canonicalJson([...descriptor.requiredPermissions].sort()) !== canonicalJson([...contract.permissions].sort())) throw new EndpointToolPolicyError(`Tool ${descriptor.name} does not match its trusted server contract`);
49
+ if (contract.inputSchema && canonicalJson(descriptor.inputSchema) !== canonicalJson(contract.inputSchema) || canonicalJson(descriptor.outputSchema) !== canonicalJson(contract.outputSchema) || canonicalJson(descriptor.resultKinds) !== canonicalJson(contract.resultKinds) || canonicalJson([...descriptor.requiredPermissions].sort()) !== canonicalJson([...contract.permissions].sort())) throw new EndpointToolPolicyError(`Tool ${descriptor.name} does not match its trusted server contract`);
47
50
  this.validatePolicyFields(descriptor);
48
51
  try {
49
52
  this.ajv.compile(descriptor.outputSchema);
@@ -79,6 +82,10 @@ var EndpointToolPolicy = class {
79
82
  if (descriptor.effect === "read") throw new EndpointToolPolicyError(`Mutating tool ${descriptor.name} cannot declare a read effect`);
80
83
  if (descriptor.confirmation !== "always" || !descriptor.requiresForeground || descriptor.sensitivity !== "personal" || descriptor.requiredPermissions.length === 0) throw new EndpointToolPolicyError(`Mutating tool ${descriptor.name} violates its trusted policy`);
81
84
  return;
85
+ case "browser.control":
86
+ this.assertFields(descriptor, "write", "never", false, "personal");
87
+ if (descriptor.requiredPermissions.length !== 1 || descriptor.requiredPermissions[0] !== "browser-control" || descriptor.timeoutMs !== 12e4 || descriptor.maxConcurrency !== 4 || descriptor.supportsCancellation !== true || descriptor.idempotent !== false) throw new EndpointToolPolicyError(`Browser tool ${descriptor.name} violates its trusted policy`);
88
+ return;
82
89
  default: throw new EndpointToolPolicyError(`Unknown endpoint policy: ${descriptor.policyId}`);
83
90
  }
84
91
  }
@@ -1,7 +1,7 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
- import { init_paths, resolveExtensionsDir, resolveExtensionsLockPath } from "../config/paths.js";
4
3
  import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
4
+ import { init_paths, resolveExtensionsDir, resolveExtensionsLockPath } from "../config/paths.js";
5
5
  import { dirname, join } from "path";
6
6
  import { existsSync } from "fs";
7
7
  import { mkdir, readFile } from "fs/promises";
@@ -1,6 +1,6 @@
1
1
  import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentDir, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, resolveUserPath, validateAgentIdForNewAgent } from "../agent/agent-scope.js";
2
- import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
3
2
  import { WORKSPACE_FILES, init_paths } from "../config/paths.js";
3
+ import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
4
4
  import { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES, REQUIRED_AGENT_PROFILE_MARKDOWN_FILE_SET } from "../agent/context/workspace.js";
5
5
  import { isPathUnderWorkspace, resolveWorkspaceSafePath } from "./workspace-editor-path.js";
6
6
  import { seedAgentProfileMarkdownFiles } from "../agent/context/workspace-seed.js";
@@ -1,7 +1,7 @@
1
1
  import { init_paths_state, resolveStateDir } from "../config/paths-state.js";
2
2
  import { init_agent_scope, resolveAgentProfileDir } from "../agent/agent-scope.js";
3
- import { extractProfileAgentId } from "../config/agent-profile.js";
4
3
  import { init_paths, resolveConfigPath, resolveSkillsDir } from "../config/paths.js";
4
+ import { extractProfileAgentId } from "../config/agent-profile.js";
5
5
  import { isBareProfileMarkdownFileName, resolveProfileMarkdownPathIfBareName } from "../agent/tools/tool-paths.js";
6
6
  import { isPathUnderWorkspace, resolveWorkspaceSafePath } from "./workspace-editor-path.js";
7
7
  import { basename, isAbsolute, resolve } from "node:path";
@@ -5,6 +5,7 @@ import { resolveAllowedBrowserOrigins, resolveGatewayServiceListenPort } from ".
5
5
  import { resolveGatewayEffectiveHost } from "../../config/gateway-bind.js";
6
6
  import { loadTunnelState } from "../../tunnel/tunnel-state.js";
7
7
  import { resolveReverseProxyPublicUrl } from "../public-url.js";
8
+ import { BROWSER_EXTENSION_ID } from "../../browser/extension-identity.js";
8
9
  import { maxSessionInputRequestBodyBytes } from "../chat-limits.js";
9
10
  import { isLoopbackIpAddress, isTrustedProxyAddress } from "../client-ip.js";
10
11
  import { buildGatewayConsoleCspHeader } from "../security/csp.js";
@@ -65,7 +66,11 @@ function createHonoApp(config) {
65
66
  return [];
66
67
  }
67
68
  };
68
- const resolveAllBrowserOrigins = () => [...resolveBrowserOrigins(), ...resolvePairedBrowserExtensionOrigins()];
69
+ const resolveAllBrowserOrigins = () => [
70
+ ...resolveBrowserOrigins(),
71
+ `chrome-extension://${BROWSER_EXTENSION_ID}`,
72
+ ...resolvePairedBrowserExtensionOrigins()
73
+ ];
69
74
  /**
70
75
  * TCP source for the in-flight request, normalized for trusted-proxy checks.
71
76
  * Returns undefined when the runtime doesn't expose conninfo (tests, mocks).
@@ -1,9 +1,9 @@
1
1
  import { ContextPlanningConfigSchema, KnowledgeMemoryConfigSchema, UserModelConfigSchema, init_config } from "../../../user-context/config.js";
2
2
  import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveDefaultAgentId } from "../../../agent/agent-scope.js";
3
3
  import { resolveModelsJsonPath } from "../../../config/paths.js";
4
- import { buildChannelCatalogForConfig, buildChannelCatalogFromSnapshot, getChannelSetupStatus, init_channel_catalog_service } from "../../../channels/catalog/channel-catalog-service.js";
5
4
  import { init_models_json, loadModelsJson } from "../../../config/models-json.js";
6
5
  import { CredentialResolver, init_credentials } from "../../../auth/credentials.js";
6
+ import { buildChannelCatalogForConfig, buildChannelCatalogFromSnapshot, getChannelSetupStatus, init_channel_catalog_service } from "../../../channels/catalog/channel-catalog-service.js";
7
7
  import { getProviderRegistry, init_plugin_registry } from "../../../providers/plugin-registry.js";
8
8
  import { getAllProviders, init_providers, isProviderConfigured } from "../../../providers/index.js";
9
9
  import { normalizeConfiguredMcpServers } from "../../../config/mcp-config-normalize.js";
@@ -1,6 +1,7 @@
1
1
  import { deleteBrowserTabBinding, getBrowserTabBinding, setBrowserTabBinding } from "../../../storage/sqlite/browser-tab-binding-repository.js";
2
2
  import { browserTabBindingRequestSchema } from "../../../../packages/gateway-contract/src/browser-tab-binding.js";
3
3
  import { getDevice } from "../../../storage/sqlite/device-access-repository.js";
4
+ import "../../../../packages/browser-control-contract/src/index.js";
4
5
  import { decideBrowserApproval, listBrowserApprovals } from "../../../browser/policy/approval-store.js";
5
6
  import { createBrowserDriver } from "../../../browser/drivers/create-driver.js";
6
7
  import { checkBrowserReadiness } from "../../../browser/readiness.js";
@@ -9,34 +10,19 @@ import { getGatewayPrincipal } from "../../security/gateway-principal.js";
9
10
  import { getConnInfo } from "@hono/node-server/conninfo";
10
11
  //#region src/gateway/hono/routes/browser.ts
11
12
  /** Browser Control status, approvals, and driver diagnostics. */
12
- const EXTENSION_ENDPOINT = "http://127.0.0.1:19820/";
13
- async function extensionStatus() {
14
- const { getExtensionBrowserServerSnapshot } = await import("../../../browser/providers/extension-ws-acquire.js");
15
- const snapshot = getExtensionBrowserServerSnapshot();
16
- let running = snapshot.active;
17
- let socketConnected = false;
18
- let connected = false;
19
- let protocolVersion = null;
20
- let expectedProtocolVersion = null;
21
- let extensionVersion = null;
22
- try {
23
- const payload = await (await fetch(EXTENSION_ENDPOINT, { signal: AbortSignal.timeout(2e3) })).json();
24
- running ||= payload.ok === true;
25
- socketConnected = payload.socketConnected ?? payload.connected === true;
26
- connected = payload.connected === true;
27
- protocolVersion = typeof payload.protocolVersion === "number" ? payload.protocolVersion : null;
28
- expectedProtocolVersion = typeof payload.expectedProtocolVersion === "number" ? payload.expectedProtocolVersion : null;
29
- extensionVersion = typeof payload.extensionVersion === "string" ? payload.extensionVersion : null;
30
- } catch {}
13
+ async function extensionStatus(service) {
14
+ const endpoint = 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)[0];
15
+ const connected = Boolean(endpoint);
16
+ const extensionVersion = endpoint?.appVersion ?? null;
31
17
  const { browserExtDoctor } = await import("../../../browser/providers/browser-ext-install.js");
32
18
  const doctor = await browserExtDoctor({ runtimeExtensionVersion: extensionVersion ?? void 0 });
33
19
  return {
34
- running,
35
- socketConnected,
20
+ running: true,
21
+ socketConnected: connected,
36
22
  connected,
37
23
  driverKind: "extension",
38
- protocolVersion,
39
- expectedProtocolVersion,
24
+ protocolVersion: connected ? 4 : null,
25
+ expectedProtocolVersion: 4,
40
26
  extensionVersion,
41
27
  artifacts: {
42
28
  installed: doctor.installed,
@@ -45,10 +31,12 @@ async function extensionStatus() {
45
31
  xopcVersion: doctor.xopcVersion,
46
32
  installedVersion: doctor.installedVersion,
47
33
  needsRefresh: doctor.needsRefresh,
48
- needsChromeReload: doctor.needsChromeReload || socketConnected && !connected
34
+ needsChromeReload: doctor.needsChromeReload,
35
+ nativeHost: doctor.nativeHost
49
36
  },
50
- bridgeHeld: snapshot.active,
51
- refCount: snapshot.refCount
37
+ bridgeHeld: false,
38
+ refCount: connected ? 1 : 0,
39
+ transport: "gateway-realtime"
52
40
  };
53
41
  }
54
42
  function isLocalOwnerRequest(c, service) {
@@ -156,7 +144,7 @@ function registerBrowserRoutes(authenticated, deps) {
156
144
  });
157
145
  authenticated.get("/api/browser/extension-status", async (c) => {
158
146
  try {
159
- return c.json(await extensionStatus());
147
+ return c.json(await extensionStatus(service));
160
148
  } catch (error) {
161
149
  return c.json({
162
150
  running: false,
@@ -177,7 +165,7 @@ function registerBrowserRoutes(authenticated, deps) {
177
165
  }
178
166
  });
179
167
  const readiness = await checkBrowserReadiness(service.currentConfig);
180
- const driverStatus = config.driver.kind === "extension" ? await extensionStatus().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;
168
+ 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;
181
169
  const extensionConnected = config.driver.kind === "extension" ? driverStatus.connected === true : true;
182
170
  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;
183
171
  return c.json({
@@ -204,7 +192,7 @@ function registerBrowserRoutes(authenticated, deps) {
204
192
  const startedAt = Date.now();
205
193
  let driver;
206
194
  try {
207
- driver = await createBrowserDriver(service.currentConfig.browser);
195
+ driver = await createBrowserDriver(service.currentConfig.browser, service.endpointTools);
208
196
  await driver.connect();
209
197
  return c.json({
210
198
  ok: true,
@@ -229,12 +217,14 @@ function registerBrowserRoutes(authenticated, deps) {
229
217
  }, 403);
230
218
  const body = await c.req.json().catch(() => ({}));
231
219
  try {
232
- const { browserExtDoctor, ensureBrowserExtensionArtifacts } = await import("../../../browser/providers/browser-ext-install.js");
220
+ const { browserExtDoctor, ensureBrowserExtensionArtifacts, installBrowserNativeMessagingHost } = await import("../../../browser/providers/browser-ext-install.js");
233
221
  const result = await ensureBrowserExtensionArtifacts({ force: body.force === true });
222
+ const nativeHost = await installBrowserNativeMessagingHost({ configPath: service.getHealth().configPath });
234
223
  return c.json({
235
224
  ok: true,
236
225
  payload: {
237
226
  ...result,
227
+ nativeHost,
238
228
  doctor: await browserExtDoctor()
239
229
  }
240
230
  });
@@ -1,5 +1,5 @@
1
- import { resolveModelsJsonPath } from "../../../config/paths.js";
2
1
  import { init_resolve_config_value, testApiKeyResolution } from "../../../config/resolve-config-value.js";
2
+ import { resolveModelsJsonPath } from "../../../config/paths.js";
3
3
  import { init_models_json, loadModelsJson, saveModelsJson, validateModelsConfig } from "../../../config/models-json.js";
4
4
  import { getModelCatalogStore, init_model_catalog_store } from "../../../providers/model-catalog-store.js";
5
5
  import { getModelRegistry } from "../../../providers/model-registry.js";
@@ -15,6 +15,11 @@ function isLoopbackHost(hostname) {
15
15
  function parseOriginHost(originRaw) {
16
16
  const trimmed = (originRaw ?? "").trim();
17
17
  if (!trimmed || trimmed === "null") return null;
18
+ if (isChromeExtensionOrigin(trimmed)) return {
19
+ origin: trimmed.toLowerCase(),
20
+ host: "",
21
+ hostname: ""
22
+ };
18
23
  try {
19
24
  const url = new URL(trimmed);
20
25
  return {
@@ -41,8 +41,6 @@ export interface GatewayConfigCoordinatorOptions {
41
41
  getChannelManager: () => ChannelManager;
42
42
  getHeartbeatService: () => HeartbeatService | null;
43
43
  getExtensionLoader: () => ExtensionLoader | null;
44
- /** Re-evaluate browser-extension server attachment after agent defaults change. */
45
- reconcileBrowserExtensionServer: () => Promise<void>;
46
44
  /** Sync deterministic user-model maintenance automations after config changes. */
47
45
  reconcileMemoryMaintenanceAutomations: () => Promise<void>;
48
46
  /** Latest channel status snapshot for the `channels.status` event. */
@@ -1,7 +1,7 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
- import { loadConfig, saveConfig } from "../../config/loader.js";
4
3
  import { getModelRegistry } from "../../providers/model-registry.js";
4
+ import { loadConfig, saveConfig } from "../../config/loader.js";
5
5
  import { init_providers } from "../../providers/index.js";
6
6
  import { disposeAllSessionMcpRuntimes } from "../../agent/mcp/bundle-mcp-runtime.js";
7
7
  import { reloadImageGenerationProviders } from "../../agent/image/generation/provider-registry.js";
@@ -223,7 +223,6 @@ var GatewayConfigCoordinator = class {
223
223
  log.debug("Reloading agent defaults...");
224
224
  this.opts.setConfig(newConfig);
225
225
  this.opts.getAgentService().applyAgentDefaultsFromConfig(newConfig);
226
- this.opts.reconcileBrowserExtensionServer();
227
226
  this.opts.reconcileMemoryMaintenanceAutomations().catch((err) => {
228
227
  const em = err instanceof Error ? err.message : String(err);
229
228
  log.warn({
@@ -350,7 +349,6 @@ var GatewayConfigCoordinator = class {
350
349
  this.opts.setConfig(reloaded);
351
350
  if (sanitizeTunnelConfig(reloaded)) await saveConfig(reloaded, this.opts.configPath);
352
351
  this.opts.getAgentService().applyAgentDefaultsFromConfig(reloaded);
353
- await this.opts.reconcileBrowserExtensionServer();
354
352
  await this.opts.reconcileMemoryMaintenanceAutomations().catch((err) => {
355
353
  const em = err instanceof Error ? err.message : String(err);
356
354
  log.warn({
@@ -39,10 +39,6 @@ export declare class GatewayService {
39
39
  private notesService;
40
40
  private extensionLoader;
41
41
  private extensionMetadataSnapshot;
42
- private browserExtensionProvider;
43
- private browserExtensionRelease;
44
- /** `${host}:${port}` when the gateway holds the extension bridge listener. */
45
- private browserExtensionBindKey;
46
42
  private heartbeatService;
47
43
  private sessionIndex;
48
44
  private running;
@@ -198,13 +194,6 @@ export declare class GatewayService {
198
194
  */
199
195
  onHttpListening(): Promise<void>;
200
196
  stop(): Promise<void>;
201
- /** Start the browser extension WebSocket server when its driver is active. */
202
- private startBrowserExtensionServerIfNeeded;
203
- /**
204
- * Start/stop/rebind the Chrome extension bridge.
205
- * PATCH saves update config in memory without re-running gateway startup, so this must run on save too.
206
- */
207
- reconcileBrowserExtensionServer(): Promise<void>;
208
197
  /**
209
198
  * Start processing outbound messages and send through channels
210
199
  */
@@ -12,16 +12,16 @@ import { getSessionConfig } from "../storage/sqlite/config-repository.js";
12
12
  import "../storage/sqlite/index.js";
13
13
  import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
14
14
  import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agent/agent-scope.js";
15
- import { buildSessionKey, init_session_key, sanitizeSegment } from "../routing/session-key.js";
16
- import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
17
- import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
18
15
  import { init_paths, resolveConfigPath, resolveExtensionsDir } from "../config/paths.js";
16
+ import { prewarmModelRegistry } from "../providers/model-registry.js";
19
17
  import { areExtensionsGloballyDisabled } from "../extensions/discover-extensions.js";
20
18
  import { buildExtensionMetadataSnapshot } from "../extensions/extension-metadata-snapshot.js";
21
19
  import { buildChannelCatalogForConfig, buildChannelCatalogFromSnapshot, init_channel_catalog_service } from "../channels/catalog/channel-catalog-service.js";
22
20
  import { loadConfig, saveConfig } from "../config/loader.js";
23
- import { prewarmModelRegistry } from "../providers/model-registry.js";
21
+ import { buildSessionKey, init_session_key, sanitizeSegment } from "../routing/session-key.js";
22
+ import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
24
23
  import { init_providers, providers_exports } from "../providers/index.js";
24
+ import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
25
25
  import { TaskRepository } from "../tasks/task-repository.js";
26
26
  import { TaskConversationRepository } from "../tasks/task-conversation-repository.js";
27
27
  import { getEmbeddedExecutionSession } from "../agent/embedded/execution-context.js";
@@ -152,10 +152,6 @@ var GatewayService = class {
152
152
  notesService;
153
153
  extensionLoader = null;
154
154
  extensionMetadataSnapshot = null;
155
- browserExtensionProvider = null;
156
- browserExtensionRelease = null;
157
- /** `${host}:${port}` when the gateway holds the extension bridge listener. */
158
- browserExtensionBindKey = null;
159
155
  heartbeatService = null;
160
156
  sessionIndex;
161
157
  running = false;
@@ -249,6 +245,7 @@ var GatewayService = class {
249
245
  get browserAutomations() {
250
246
  if (!this.browserAutomationService) this.browserAutomationService = createRuntimeBrowserAutomationService({
251
247
  getConfig: () => this.config,
248
+ endpointTools: this.endpointTools,
252
249
  emit: (type, payload) => this.emit(type, payload)
253
250
  });
254
251
  return this.browserAutomationService;
@@ -520,7 +517,6 @@ var GatewayService = class {
520
517
  getChannelManager: () => this.channelManager,
521
518
  getHeartbeatService: () => this.heartbeatService,
522
519
  getExtensionLoader: () => this.extensionLoader,
523
- reconcileBrowserExtensionServer: () => this.reconcileBrowserExtensionServer(),
524
520
  reconcileMemoryMaintenanceAutomations: () => this.reconcileMemoryMaintenanceAutomations(),
525
521
  getChannelsStatus: () => this.getChannelsStatus(),
526
522
  emit: (type, payload) => this.emit(type, payload)
@@ -1099,7 +1095,6 @@ var GatewayService = class {
1099
1095
  workspaceId: this.currentWorkspacePath
1100
1096
  }) });
1101
1097
  import("../browser/providers/browser-ext-install.js").then(({ ensureBrowserExtensionOnStartup }) => ensureBrowserExtensionOnStartup(this.config)).catch((err) => log.warn({ err }, "Browser extension artifact ensure failed"));
1102
- await trace.measure("browser-extension.start", () => this.startBrowserExtensionServerIfNeeded());
1103
1098
  this.agentService.start().catch((err) => {
1104
1099
  log.error({ err }, "Agent service error");
1105
1100
  });
@@ -1260,12 +1255,6 @@ var GatewayService = class {
1260
1255
  this.connectedKnowledgeCoordinator?.stop();
1261
1256
  this.connectedKnowledgeCoordinator = null;
1262
1257
  await this.browserAutomationService?.shutdown();
1263
- if (this.browserExtensionRelease) {
1264
- await this.browserExtensionRelease();
1265
- this.browserExtensionRelease = null;
1266
- }
1267
- this.browserExtensionProvider = null;
1268
- this.browserExtensionBindKey = null;
1269
1258
  registerClarificationChannelRuntime(null);
1270
1259
  this.connectionRecovery.stop();
1271
1260
  this.agentRunner.disposeClarifications();
@@ -1288,73 +1277,6 @@ var GatewayService = class {
1288
1277
  closeXopcDatabase();
1289
1278
  log.debug("Gateway service stopped");
1290
1279
  }
1291
- /** Start the browser extension WebSocket server when its driver is active. */
1292
- async startBrowserExtensionServerIfNeeded() {
1293
- await this.reconcileBrowserExtensionServer();
1294
- }
1295
- /**
1296
- * Start/stop/rebind the Chrome extension bridge.
1297
- * PATCH saves update config in memory without re-running gateway startup, so this must run on save too.
1298
- */
1299
- async reconcileBrowserExtensionServer() {
1300
- const driver = this.config.browser.driver;
1301
- const bridgeConfig = this.config.browser.enabled && driver.kind === "extension" ? {
1302
- host: "127.0.0.1",
1303
- port: 19820,
1304
- connectionTimeout: this.config.browser.limits.actionTimeoutMs,
1305
- commandTimeout: this.config.browser.limits.actionTimeoutMs
1306
- } : null;
1307
- if (!bridgeConfig) {
1308
- if (this.browserExtensionRelease) {
1309
- await this.browserExtensionRelease();
1310
- this.browserExtensionRelease = null;
1311
- this.browserExtensionProvider = null;
1312
- this.browserExtensionBindKey = null;
1313
- log.debug("Browser extension WebSocket server stopped because its driver is inactive");
1314
- }
1315
- return;
1316
- }
1317
- const { port, host, connectionTimeout, commandTimeout } = bridgeConfig;
1318
- const bindKey = `${host}:${port}`;
1319
- if (this.browserExtensionRelease && this.browserExtensionBindKey === bindKey) return;
1320
- if (this.browserExtensionRelease) {
1321
- await this.browserExtensionRelease();
1322
- this.browserExtensionRelease = null;
1323
- this.browserExtensionProvider = null;
1324
- this.browserExtensionBindKey = null;
1325
- }
1326
- try {
1327
- const { acquireExtensionBrowserServer } = await import("../browser/providers/extension-ws-acquire.js");
1328
- const { provider, release } = await acquireExtensionBrowserServer({
1329
- port,
1330
- host,
1331
- connectionTimeout,
1332
- commandTimeout
1333
- });
1334
- this.browserExtensionProvider = provider;
1335
- this.browserExtensionRelease = release;
1336
- this.browserExtensionBindKey = bindKey;
1337
- log.info({
1338
- port,
1339
- host
1340
- }, "Browser extension WS server started");
1341
- } catch (err) {
1342
- if ((err && typeof err === "object" && "code" in err ? err.code : void 0) === "EADDRINUSE") {
1343
- log.warn({
1344
- err,
1345
- phase: "browser_extension_ws",
1346
- bindPort: port,
1347
- bindHost: host,
1348
- hint: "Another process holds the browser extension bridge port 19820. Stop it before starting xopc."
1349
- }, `Browser extension WS server port is already in use: ${host}:${port}`);
1350
- return;
1351
- }
1352
- log.error({
1353
- err,
1354
- phase: "browser_extension_ws"
1355
- }, `Failed to start browser extension WS server: ${err instanceof Error ? err.message : String(err)}`);
1356
- }
1357
- }
1358
1280
  /**
1359
1281
  * Start processing outbound messages and send through channels
1360
1282
  */
@@ -1,5 +1,5 @@
1
- import { init_sync_provider_auth, resolveProviderApiKeyForAgentSync } from "../../auth/sync-provider-auth.js";
2
1
  import { getApiKeyFromEnv, init_env_keys } from "../env-keys.js";
2
+ import { init_sync_provider_auth, resolveProviderApiKeyForAgentSync } from "../../auth/sync-provider-auth.js";
3
3
  import { getDefaultAuthProfileStore } from "./auth-profile-store.js";
4
4
  //#region src/providers/auth-runtime/resolve-auth.ts
5
5
  init_env_keys();
@@ -1,11 +1,11 @@
1
1
  import { __esmMin, __exportAll } from "../../_virtual/_rolldown/runtime.js";
2
2
  import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
3
- import { getModelOAuthProviderIds, init_registry } from "../auth/oauth/registry.js";
4
- import { hasProviderAuthOnDiskSync, init_sync_provider_auth } from "../auth/sync-provider-auth.js";
5
3
  import { PROVIDER_ENV_MAP, getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
6
4
  import { init_model_ref, splitProviderModelRef } from "./model-ref.js";
7
5
  import { ModelRegistry, getModelRegistry, init_model_registry, prewarmModelRegistry, resetModelRegistry } from "./model-registry.js";
6
+ import { getModelOAuthProviderIds, init_registry } from "../auth/oauth/registry.js";
8
7
  import { CredentialResolver, hasCredentials, init_credentials } from "../auth/credentials.js";
8
+ import { hasProviderAuthOnDiskSync, init_sync_provider_auth } from "../auth/sync-provider-auth.js";
9
9
  import { EXTENSION_PROVIDER_BASE_URL, init_constants } from "./constants.js";
10
10
  import { applyOfficialModelMetadataCorrections, getSupplementalModels, init_model_supplements } from "./model-supplements.js";
11
11
  import { getProviderRegistry, init_plugin_registry } from "./plugin-registry.js";