@trusty-squire/mcp 1.1.13 → 1.1.14-rc.10

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 (163) hide show
  1. package/README.md +94 -110
  2. package/{LICENSE → assets/licenses/browser-use-MIT.txt} +1 -1
  3. package/dist/api-client.d.ts +9 -0
  4. package/dist/api-client.d.ts.map +1 -1
  5. package/dist/api-client.js +11 -0
  6. package/dist/api-client.js.map +1 -1
  7. package/dist/bin.js +7 -1
  8. package/dist/bin.js.map +1 -1
  9. package/dist/bot/broker/admission-context.d.ts +11 -0
  10. package/dist/bot/broker/admission-context.d.ts.map +1 -0
  11. package/dist/bot/broker/admission-context.js +17 -0
  12. package/dist/bot/broker/admission-context.js.map +1 -0
  13. package/dist/bot/broker/authority.d.ts +76 -0
  14. package/dist/bot/broker/authority.d.ts.map +1 -0
  15. package/dist/bot/broker/authority.js +528 -0
  16. package/dist/bot/broker/authority.js.map +1 -0
  17. package/dist/bot/broker/custody.d.ts +20 -0
  18. package/dist/bot/broker/custody.d.ts.map +1 -0
  19. package/dist/bot/broker/custody.js +10 -0
  20. package/dist/bot/broker/custody.js.map +1 -0
  21. package/dist/bot/broker/daemon.d.ts +24 -0
  22. package/dist/bot/broker/daemon.d.ts.map +1 -0
  23. package/dist/bot/broker/daemon.js +371 -0
  24. package/dist/bot/broker/daemon.js.map +1 -0
  25. package/dist/bot/broker/discovery.d.ts +9 -0
  26. package/dist/bot/broker/discovery.d.ts.map +1 -0
  27. package/dist/bot/broker/discovery.js +167 -0
  28. package/dist/bot/broker/discovery.js.map +1 -0
  29. package/dist/bot/broker/dispatch-journal.d.ts +71 -0
  30. package/dist/bot/broker/dispatch-journal.d.ts.map +1 -0
  31. package/dist/bot/broker/dispatch-journal.js +319 -0
  32. package/dist/bot/broker/dispatch-journal.js.map +1 -0
  33. package/dist/bot/broker/forwarder.d.ts +35 -0
  34. package/dist/bot/broker/forwarder.d.ts.map +1 -0
  35. package/dist/bot/broker/forwarder.js +150 -0
  36. package/dist/bot/broker/forwarder.js.map +1 -0
  37. package/dist/bot/broker/identity-lane.d.ts +3 -0
  38. package/dist/bot/broker/identity-lane.d.ts.map +1 -0
  39. package/dist/bot/broker/identity-lane.js +15 -0
  40. package/dist/bot/broker/identity-lane.js.map +1 -0
  41. package/dist/bot/broker/lineage.d.ts +3 -0
  42. package/dist/bot/broker/lineage.d.ts.map +1 -0
  43. package/dist/bot/broker/lineage.js +16 -0
  44. package/dist/bot/broker/lineage.js.map +1 -0
  45. package/dist/bot/broker/maintenance.d.ts +4 -0
  46. package/dist/bot/broker/maintenance.d.ts.map +1 -0
  47. package/dist/bot/broker/maintenance.js +49 -0
  48. package/dist/bot/broker/maintenance.js.map +1 -0
  49. package/dist/bot/broker/operator.d.ts +48 -0
  50. package/dist/bot/broker/operator.d.ts.map +1 -0
  51. package/dist/bot/broker/operator.js +523 -0
  52. package/dist/bot/broker/operator.js.map +1 -0
  53. package/dist/bot/broker/qualification.d.ts +5 -0
  54. package/dist/bot/broker/qualification.d.ts.map +1 -0
  55. package/dist/bot/broker/qualification.js +67 -0
  56. package/dist/bot/broker/qualification.js.map +1 -0
  57. package/dist/bot/broker/runtime.d.ts +36 -0
  58. package/dist/bot/broker/runtime.d.ts.map +1 -0
  59. package/dist/bot/broker/runtime.js +202 -0
  60. package/dist/bot/broker/runtime.js.map +1 -0
  61. package/dist/bot/broker/scheduler.d.ts +20 -0
  62. package/dist/bot/broker/scheduler.d.ts.map +1 -0
  63. package/dist/bot/broker/scheduler.js +94 -0
  64. package/dist/bot/broker/scheduler.js.map +1 -0
  65. package/dist/bot/broker/transport.d.ts +27 -0
  66. package/dist/bot/broker/transport.d.ts.map +1 -0
  67. package/dist/bot/broker/transport.js +265 -0
  68. package/dist/bot/broker/transport.js.map +1 -0
  69. package/dist/bot/browser-process-owner.d.ts +75 -0
  70. package/dist/bot/browser-process-owner.d.ts.map +1 -0
  71. package/dist/bot/browser-process-owner.js +939 -0
  72. package/dist/bot/browser-process-owner.js.map +1 -0
  73. package/dist/bot/browser-process-runtime.d.ts +168 -0
  74. package/dist/bot/browser-process-runtime.d.ts.map +1 -0
  75. package/dist/bot/browser-process-runtime.js +940 -0
  76. package/dist/bot/browser-process-runtime.js.map +1 -0
  77. package/dist/bot/browser-use-capture.d.ts +15 -0
  78. package/dist/bot/browser-use-capture.d.ts.map +1 -0
  79. package/dist/bot/browser-use-capture.js +975 -0
  80. package/dist/bot/browser-use-capture.js.map +1 -0
  81. package/dist/bot/browser-use-paint-order.d.ts +12 -0
  82. package/dist/bot/browser-use-paint-order.d.ts.map +1 -0
  83. package/dist/bot/browser-use-paint-order.js +73 -0
  84. package/dist/bot/browser-use-paint-order.js.map +1 -0
  85. package/dist/bot/browser-use-serializer.d.ts +67 -0
  86. package/dist/bot/browser-use-serializer.d.ts.map +1 -0
  87. package/dist/bot/browser-use-serializer.js +1027 -0
  88. package/dist/bot/browser-use-serializer.js.map +1 -0
  89. package/dist/bot/browser.d.ts +158 -264
  90. package/dist/bot/browser.d.ts.map +1 -1
  91. package/dist/bot/browser.js +1681 -2830
  92. package/dist/bot/browser.js.map +1 -1
  93. package/dist/bot/compact-observation-v2.d.ts +54 -45
  94. package/dist/bot/compact-observation-v2.d.ts.map +1 -1
  95. package/dist/bot/compact-observation-v2.js +454 -165
  96. package/dist/bot/compact-observation-v2.js.map +1 -1
  97. package/dist/bot/credential-shape.d.ts.map +1 -1
  98. package/dist/bot/credential-shape.js +7 -0
  99. package/dist/bot/credential-shape.js.map +1 -1
  100. package/dist/bot/identity-runtime.d.ts +56 -0
  101. package/dist/bot/identity-runtime.d.ts.map +1 -0
  102. package/dist/bot/identity-runtime.js +141 -0
  103. package/dist/bot/identity-runtime.js.map +1 -0
  104. package/dist/bot/mutation-dispatch-evidence.d.ts +13 -0
  105. package/dist/bot/mutation-dispatch-evidence.d.ts.map +1 -0
  106. package/dist/bot/mutation-dispatch-evidence.js +19 -0
  107. package/dist/bot/mutation-dispatch-evidence.js.map +1 -0
  108. package/dist/bot/owned-pages.d.ts +16 -0
  109. package/dist/bot/owned-pages.d.ts.map +1 -0
  110. package/dist/bot/owned-pages.js +58 -0
  111. package/dist/bot/owned-pages.js.map +1 -0
  112. package/dist/bot/page-driver.d.ts +37 -0
  113. package/dist/bot/page-driver.d.ts.map +1 -0
  114. package/dist/bot/page-driver.js +303 -0
  115. package/dist/bot/page-driver.js.map +1 -0
  116. package/dist/bot/pay-operator.d.ts +1 -0
  117. package/dist/bot/pay-operator.d.ts.map +1 -1
  118. package/dist/bot/pay-operator.js +10 -0
  119. package/dist/bot/pay-operator.js.map +1 -1
  120. package/dist/bot/profile.d.ts +9 -0
  121. package/dist/bot/profile.d.ts.map +1 -1
  122. package/dist/bot/profile.js +16 -11
  123. package/dist/bot/profile.js.map +1 -1
  124. package/dist/bot/provision-session.d.ts +32 -7
  125. package/dist/bot/provision-session.d.ts.map +1 -1
  126. package/dist/bot/provision-session.js +1008 -471
  127. package/dist/bot/provision-session.js.map +1 -1
  128. package/dist/bot/session/lifecycle.d.ts +5 -2
  129. package/dist/bot/session/lifecycle.d.ts.map +1 -1
  130. package/dist/bot/session/lifecycle.js +303 -34
  131. package/dist/bot/session/lifecycle.js.map +1 -1
  132. package/dist/bot/session/multisession-flag.d.ts +2 -0
  133. package/dist/bot/session/multisession-flag.d.ts.map +1 -0
  134. package/dist/bot/session/multisession-flag.js +23 -0
  135. package/dist/bot/session/multisession-flag.js.map +1 -0
  136. package/dist/install/cli.d.ts.map +1 -1
  137. package/dist/install/cli.js +2 -1
  138. package/dist/install/cli.js.map +1 -1
  139. package/dist/server-instance-registry.d.ts +18 -6
  140. package/dist/server-instance-registry.d.ts.map +1 -1
  141. package/dist/server-instance-registry.js +49 -28
  142. package/dist/server-instance-registry.js.map +1 -1
  143. package/dist/server.d.ts +6 -3
  144. package/dist/server.d.ts.map +1 -1
  145. package/dist/server.js +122 -29
  146. package/dist/server.js.map +1 -1
  147. package/dist/tools/audit-log.d.ts.map +1 -1
  148. package/dist/tools/audit-log.js +1 -5
  149. package/dist/tools/audit-log.js.map +1 -1
  150. package/dist/tools/audit-rollup.d.ts +2 -5
  151. package/dist/tools/audit-rollup.d.ts.map +1 -1
  152. package/dist/tools/audit-rollup.js +0 -0
  153. package/dist/tools/audit-rollup.js.map +1 -1
  154. package/dist/tools/credential-mutations.d.ts +16 -16
  155. package/dist/tools/index.js +2 -2
  156. package/dist/tools/index.js.map +1 -1
  157. package/dist/tools/operate-pay.d.ts +18 -18
  158. package/dist/tools/provision-drive.d.ts +263 -555
  159. package/dist/tools/provision-drive.d.ts.map +1 -1
  160. package/dist/tools/provision-drive.js +404 -1139
  161. package/dist/tools/provision-drive.js.map +1 -1
  162. package/dist/tools/use-credential.d.ts +6 -6
  163. package/package.json +1 -1
@@ -0,0 +1,20 @@
1
+ import type { BrowserController } from "../browser.js";
2
+ /** Installed only by the browser-owning broker entrypoint, never by MCP
3
+ * clients. Lifecycle keeps the existing drain/audit/cleanup transaction. */
4
+ export interface BrokerBrowserCustody {
5
+ acquire(options: {
6
+ profileDir?: string;
7
+ proxyUrl?: string;
8
+ }): Promise<{
9
+ browser: BrowserController;
10
+ profileDir: string;
11
+ }>;
12
+ cleanupAdmission(sessionId: string): Promise<boolean>;
13
+ orphanAdmission(sessionId: string): Promise<void>;
14
+ orphan(browser: BrowserController): Promise<void>;
15
+ release(browser: BrowserController): Promise<void>;
16
+ identity<T>(operation: () => Promise<T>): Promise<T>;
17
+ }
18
+ export declare function installBrokerBrowserCustody(value: BrokerBrowserCustody): void;
19
+ export declare function brokerBrowserCustody(): BrokerBrowserCustody | undefined;
20
+ //# sourceMappingURL=custody.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custody.d.ts","sourceRoot":"","sources":["../../../src/bot/broker/custody.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD;4EAC4E;AAC5E,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,OAAO,EAAE;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,iBAAiB,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChE,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,QAAQ,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACtD;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAG7E;AACD,wBAAgB,oBAAoB,IAAI,oBAAoB,GAAG,SAAS,CAEvE"}
@@ -0,0 +1,10 @@
1
+ let custody;
2
+ export function installBrokerBrowserCustody(value) {
3
+ if (custody !== undefined)
4
+ throw new Error("Broker browser custody is already installed");
5
+ custody = value;
6
+ }
7
+ export function brokerBrowserCustody() {
8
+ return custody;
9
+ }
10
+ //# sourceMappingURL=custody.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custody.js","sourceRoot":"","sources":["../../../src/bot/broker/custody.ts"],"names":[],"mappings":"AAeA,IAAI,OAAyC,CAAC;AAC9C,MAAM,UAAU,2BAA2B,CAAC,KAA2B;IACrE,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC1F,OAAO,GAAG,KAAK,CAAC;AAClB,CAAC;AACD,MAAM,UAAU,oBAAoB;IAClC,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,24 @@
1
+ export declare function brokerDrainAllowsMethod(method: string): boolean;
2
+ export declare function brokerStartupAllowsMethod(retainedCustody: boolean, method: string): boolean;
3
+ export declare function brokerShutdownCleanupComplete(inventory: {
4
+ active: number;
5
+ quarantined: number;
6
+ admitting: number;
7
+ }, closeRuntime: () => Promise<boolean>, timeoutMs?: number): Promise<boolean>;
8
+ export declare function brokerIdleTimeoutMs(env?: NodeJS.ProcessEnv): number | undefined;
9
+ export declare function brokerIdleShutdownEligible(input: {
10
+ closing: boolean;
11
+ draining: boolean;
12
+ connectedClients: number;
13
+ idleTimeout: number | undefined;
14
+ inventory: {
15
+ active: number;
16
+ quarantined: number;
17
+ admitting: number;
18
+ };
19
+ hasReconnectGrace: boolean;
20
+ }): boolean;
21
+ /** Explicit foreground service entrypoint. A supervisor may retain the broker;
22
+ * ordinary clients cannot stop it while another connection owns sessions. */
23
+ export declare function runBrokerDaemon(): Promise<void>;
24
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../../src/bot/broker/daemon.ts"],"names":[],"mappings":"AA8BA,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,wBAAgB,yBAAyB,CAAC,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAE3F;AAED,wBAAsB,6BAA6B,CACjD,SAAS,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EACrE,YAAY,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EACpC,SAAS,SAA0C,GAClD,OAAO,CAAC,OAAO,CAAC,CAclB;AAmCD,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,GAAG,SAAS,CAM5F;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IAChD,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,SAAS,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE,iBAAiB,EAAE,OAAO,CAAC;CAC5B,GAAG,OAAO,CAWV;AAED;6EAC6E;AAC7E,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CA8SrD"}
@@ -0,0 +1,371 @@
1
+ import { brokerElectionRoot, brokerIsSupervised, publishEndpointOwner } from "./discovery.js";
2
+ import { DispatchJournal } from "./dispatch-journal.js";
3
+ import { lstat, unlink, mkdir } from "node:fs/promises";
4
+ import { dirname, join } from "node:path";
5
+ import { createHash } from "node:crypto";
6
+ import { createSessionGuard, setServingAccountId } from "../../session-guard.js";
7
+ import { setSelfManagedChromeTerminationSignalExitEnabled } from "../browser.js";
8
+ import { startOwnerProcessReaper } from "../owner-process-reaper.js";
9
+ import { acquireProfileOperationGuard, ProfileBusyError, profilePathIdentity, CHROME_PROFILE_DIR, waitForProfileFree, } from "../profile.js";
10
+ import { installBrokerBrowserCustody } from "./custody.js";
11
+ import { BrokerRuntime } from "./runtime.js";
12
+ import { OperatorBroker } from "./operator.js";
13
+ import { BrokerRefusal } from "./scheduler.js";
14
+ import { BrokerClient, listenBroker } from "./transport.js";
15
+ const MIN_BROKER_IDLE_TIMEOUT_MS = 60_000;
16
+ const DEFAULT_BROKER_IDLE_TIMEOUT_MS = 5 * 60_000;
17
+ const DEFAULT_BROKER_DRAIN_CLEANUP_TIMEOUT_MS = 3_000;
18
+ const SUPERVISOR_ATTACH_TIMEOUT_MS = 10_000;
19
+ const SUPERVISOR_ATTACH_POLL_MS = 100;
20
+ const DRAIN_RECOVERY_METHODS = new Set(["recover", "reclaim", "acknowledge", "confirm_start"]);
21
+ const STARTUP_RECONCILIATION_METHODS = new Set(["recover", "reclaim"]);
22
+ export function brokerDrainAllowsMethod(method) {
23
+ return DRAIN_RECOVERY_METHODS.has(method);
24
+ }
25
+ export function brokerStartupAllowsMethod(retainedCustody, method) {
26
+ return !retainedCustody || STARTUP_RECONCILIATION_METHODS.has(method);
27
+ }
28
+ export async function brokerShutdownCleanupComplete(inventory, closeRuntime, timeoutMs = DEFAULT_BROKER_DRAIN_CLEANUP_TIMEOUT_MS) {
29
+ if (inventory.active !== 0 || inventory.quarantined !== 0 || inventory.admitting !== 0)
30
+ return false;
31
+ let timer;
32
+ try {
33
+ return await Promise.race([
34
+ closeRuntime().catch(() => false),
35
+ new Promise((resolve) => {
36
+ timer = setTimeout(() => resolve(false), timeoutMs);
37
+ }),
38
+ ]);
39
+ }
40
+ finally {
41
+ if (timer !== undefined)
42
+ clearTimeout(timer);
43
+ }
44
+ }
45
+ function brokerUnavailable(error) {
46
+ const code = error.code;
47
+ return (code === "ENOENT" || code === "ECONNREFUSED" || error.code === "broker_lost");
48
+ }
49
+ async function attachSupervisor(path, token) {
50
+ let client;
51
+ try {
52
+ client = await BrokerClient.connectSupervisor(path, token);
53
+ await client.call("supervise", {});
54
+ return true;
55
+ }
56
+ catch (error) {
57
+ if (brokerUnavailable(error))
58
+ return false;
59
+ throw error;
60
+ }
61
+ finally {
62
+ await client?.close().catch(() => undefined);
63
+ }
64
+ }
65
+ async function waitForSupervisorAttachment(path, token) {
66
+ const deadline = Date.now() + SUPERVISOR_ATTACH_TIMEOUT_MS;
67
+ while (Date.now() < deadline) {
68
+ if (await attachSupervisor(path, token))
69
+ return;
70
+ await new Promise((resolve) => setTimeout(resolve, SUPERVISOR_ATTACH_POLL_MS));
71
+ }
72
+ throw new BrokerRefusal("broker_unavailable", "Supervised broker did not become available within 10 seconds");
73
+ }
74
+ export function brokerIdleTimeoutMs(env = process.env) {
75
+ if (["1", "true"].includes((env.TRUSTY_SQUIRE_BROKER_SUPERVISED ?? "").toLowerCase()))
76
+ return undefined;
77
+ const configured = Number(env.TRUSTY_SQUIRE_BROKER_IDLE_TIMEOUT_MS);
78
+ if (!Number.isFinite(configured) || configured <= 0)
79
+ return DEFAULT_BROKER_IDLE_TIMEOUT_MS;
80
+ return Math.max(MIN_BROKER_IDLE_TIMEOUT_MS, configured);
81
+ }
82
+ export function brokerIdleShutdownEligible(input) {
83
+ return (!input.closing &&
84
+ !input.draining &&
85
+ input.connectedClients === 0 &&
86
+ input.idleTimeout !== undefined &&
87
+ !input.hasReconnectGrace &&
88
+ input.inventory.active === 0 &&
89
+ input.inventory.quarantined === 0 &&
90
+ input.inventory.admitting === 0);
91
+ }
92
+ /** Explicit foreground service entrypoint. A supervisor may retain the broker;
93
+ * ordinary clients cannot stop it while another connection owns sessions. */
94
+ export async function runBrokerDaemon() {
95
+ const path = process.env.TRUSTY_SQUIRE_BROKER_SOCKET;
96
+ if (path === undefined)
97
+ throw new Error("TRUSTY_SQUIRE_BROKER_SOCKET must name a private local socket");
98
+ const parent = await lstat(dirname(path));
99
+ if (!parent.isDirectory() || (parent.mode & 0o077) !== 0 || parent.uid !== process.getuid?.()) {
100
+ throw new Error("Broker socket directory must be owned by this user with mode 0700");
101
+ }
102
+ const guard = createSessionGuard();
103
+ const session = await guard.bind();
104
+ if (session?.account_id === undefined || session.agent_session_token === undefined)
105
+ throw new Error("Broker requires an enrolled account; run connect first");
106
+ setServingAccountId(session.account_id);
107
+ const cellId = createHash("sha256")
108
+ .update(JSON.stringify([session.account_id, profilePathIdentity(CHROME_PROFILE_DIR)]))
109
+ .digest("hex");
110
+ const supervised = brokerIsSupervised();
111
+ const electionRoot = brokerElectionRoot(CHROME_PROFILE_DIR);
112
+ await mkdir(electionRoot, { recursive: true, mode: 0o700 });
113
+ let election;
114
+ if (supervised) {
115
+ try {
116
+ election = acquireProfileOperationGuard(CHROME_PROFILE_DIR, electionRoot);
117
+ }
118
+ catch (error) {
119
+ if (!(error instanceof ProfileBusyError))
120
+ throw error;
121
+ await waitForSupervisorAttachment(path, session.agent_session_token);
122
+ return;
123
+ }
124
+ }
125
+ const runtime = new BrokerRuntime(session.account_id);
126
+ installBrokerBrowserCustody(runtime);
127
+ setSelfManagedChromeTerminationSignalExitEnabled(false);
128
+ startOwnerProcessReaper();
129
+ // Broker election is anchored beside the canonical profile, independent of
130
+ // each client's socket path or TMPDIR. Retain it through plain-login maintenance.
131
+ const profileElection = election ?? acquireProfileOperationGuard(CHROME_PROFILE_DIR, electionRoot);
132
+ runtime.claimProfile();
133
+ const journal = new DispatchJournal(join(profilePathIdentity(CHROME_PROFILE_DIR), "trusty-squire-broker-dispatch.jsonl"));
134
+ await journal.expirePendingStartDeliveries();
135
+ const retainedXataPreDispatchAuthorization = await journal.retainedXataPreDispatchAuthorization();
136
+ // A retained `entered` record must not launch/adopt a browser, but the
137
+ // broker endpoint has to exist so an explicit durable recovery can repair
138
+ // it. Parsing states here still fails startup on a malformed journal.
139
+ let startupReconciliation = retainedXataPreDispatchAuthorization !== undefined &&
140
+ (await journal.hasOnlyAuthorizedPreDispatchFailure(retainedXataPreDispatchAuthorization));
141
+ if (!startupReconciliation)
142
+ await journal.assertReconciled();
143
+ const operator = new OperatorBroker({
144
+ accountId: session.account_id,
145
+ agentSessionToken: session.agent_session_token,
146
+ apiBaseUrl: session.api_base_url,
147
+ registryBaseUrl: process.env.ADAPTER_REGISTRY_URL ?? "https://registry.trustysquire.ai",
148
+ }, cellId, journal, retainedXataPreDispatchAuthorization);
149
+ const connected = new Set();
150
+ let closing = false;
151
+ let draining = false;
152
+ let listenerClosed = false;
153
+ let cleanupRunning = false;
154
+ let maintenanceOwner;
155
+ let maintenanceReady = false;
156
+ let idleTimer;
157
+ let runtimeClose;
158
+ let idleTimeout = brokerIdleTimeoutMs();
159
+ const closeRuntime = () => {
160
+ if (runtimeClose === undefined) {
161
+ runtimeClose = runtime.close().finally(() => {
162
+ runtimeClose = undefined;
163
+ });
164
+ }
165
+ return runtimeClose;
166
+ };
167
+ const restoreMaintenance = async () => {
168
+ const refreshed = await guard.bind();
169
+ if (refreshed === null)
170
+ throw new Error("Enrolled account session is missing");
171
+ operator.refreshCredentials(refreshed);
172
+ runtime.resume();
173
+ runtime.claimProfile();
174
+ operator.authority.rotateEpoch();
175
+ maintenanceOwner = undefined;
176
+ maintenanceReady = false;
177
+ };
178
+ const listener = await listenBroker(path, {
179
+ authenticate: async (token, agentId, lineageCredential, supervisor) => await operator.authenticate(token, agentId, lineageCredential, supervisor),
180
+ connected: async (principal) => {
181
+ await operator.connected(principal);
182
+ connected.add(principal.clientId);
183
+ if (idleTimer !== undefined)
184
+ clearTimeout(idleTimer);
185
+ },
186
+ call: async (principal, method, params, id) => {
187
+ connected.add(principal.clientId);
188
+ if (idleTimer !== undefined)
189
+ clearTimeout(idleTimer);
190
+ if (closing || (draining && !brokerDrainAllowsMethod(method)))
191
+ throw new BrokerRefusal("broker_draining", "Broker is draining; only durable recovery is available");
192
+ if (principal.supervisor && method !== "supervise")
193
+ throw new BrokerRefusal("unauthorized", "Supervisor connections may only supervise");
194
+ const report = await guard.inspect();
195
+ if (report.problem !== null)
196
+ throw new Error(report.problem.message);
197
+ if (runtime.browserLost() && method === "reclaim")
198
+ throw new BrokerRefusal("browser_lost", "Browser transport is lost; the pending start cannot be recovered");
199
+ if (method === "supervise") {
200
+ if (!principal.supervisor)
201
+ throw new BrokerRefusal("unauthorized", "Supervisor identity is required");
202
+ idleTimeout = undefined;
203
+ return { state: "supervised" };
204
+ }
205
+ if (method === "recover") {
206
+ const result = await operator.recover(principal, params);
207
+ if (startupReconciliation && retainedXataPreDispatchAuthorization !== undefined)
208
+ startupReconciliation = await journal.hasOnlyAuthorizedPreDispatchFailure(retainedXataPreDispatchAuthorization);
209
+ return result;
210
+ }
211
+ if (!brokerStartupAllowsMethod(startupReconciliation, method))
212
+ throw new BrokerRefusal("outcome_unknown", "Prior broker lost mutation custody; only explicit reconciliation is available");
213
+ if (method === "reclaim")
214
+ return await operator.reclaim(principal);
215
+ if (method === "acknowledge") {
216
+ if (typeof params.requestId !== "string")
217
+ throw new Error("A broker acknowledgement requires its request ID");
218
+ await operator.acknowledge(principal, params.requestId);
219
+ return {};
220
+ }
221
+ if (method === "confirm_start") {
222
+ await operator.confirmStartDelivery(principal, params);
223
+ return {};
224
+ }
225
+ if ((await journal.hasOutstanding(undefined, principal.forwarderId)) &&
226
+ !(method === "tool" && (await operator.canContinuePaymentStatus(principal, params))))
227
+ throw new BrokerRefusal("outcome_unknown", "Prior mutation outcome awaits reconciliation; reconnect without replaying it");
228
+ if (method === "maintenance") {
229
+ if (maintenanceOwner !== undefined && maintenanceOwner !== principal.clientId)
230
+ throw new Error("Identity maintenance is already owned");
231
+ maintenanceOwner = principal.clientId;
232
+ const inventory = operator.authority.inventory();
233
+ const ready = inventory.active === 0 &&
234
+ inventory.quarantined === 0 &&
235
+ inventory.admitting === 0 &&
236
+ (await runtime.close());
237
+ maintenanceReady = ready;
238
+ return { state: ready ? "ready" : "draining", ...inventory };
239
+ }
240
+ if (method === "resume") {
241
+ if (maintenanceOwner !== principal.clientId)
242
+ throw new Error("Identity maintenance is not owned by this client");
243
+ if (!(await waitForProfileFree(CHROME_PROFILE_DIR, { deadlineMs: 0 })))
244
+ throw new Error("Plain login browser is still open");
245
+ await restoreMaintenance();
246
+ return { state: "resumed" };
247
+ }
248
+ if (maintenanceOwner !== undefined &&
249
+ (params.name === "operate_start" ||
250
+ (params.name === "operate_recipe_run" &&
251
+ params.args?.session_id === undefined)))
252
+ throw new Error("Identity maintenance is draining; retry after connect completes");
253
+ if (runtime.browserLost()) {
254
+ operator.authority.fenceRuntime();
255
+ await operator.reap();
256
+ const inventory = operator.authority.inventory();
257
+ if (inventory.active === 0 && inventory.quarantined === 0 && inventory.admitting === 0) {
258
+ await journal.assertReconciled();
259
+ if (!(await runtime.close()))
260
+ throw new Error("Old browser cleanup is not proven");
261
+ runtime.resume();
262
+ runtime.claimProfile();
263
+ operator.authority.rotateEpoch();
264
+ }
265
+ else
266
+ throw new Error("browser_lost: old session outcomes remain in custody; do not replay mutations");
267
+ }
268
+ return await operator.call(principal, method, params, id);
269
+ },
270
+ disconnect: async (principal, explicit) => {
271
+ await operator.disconnect(principal, explicit);
272
+ connected.delete(principal.clientId);
273
+ if (maintenanceOwner === principal.clientId && !maintenanceReady)
274
+ maintenanceOwner = undefined;
275
+ if (maintenanceOwner === principal.clientId &&
276
+ (await waitForProfileFree(CHROME_PROFILE_DIR, { deadlineMs: 0 })))
277
+ await restoreMaintenance();
278
+ scheduleShutdownIfIdle();
279
+ },
280
+ });
281
+ await publishEndpointOwner(path);
282
+ function scheduleShutdownIfIdle() {
283
+ if (idleTimer !== undefined)
284
+ clearTimeout(idleTimer);
285
+ idleTimer = undefined;
286
+ if (!brokerIdleShutdownEligible({
287
+ closing,
288
+ draining,
289
+ connectedClients: connected.size,
290
+ idleTimeout,
291
+ inventory: operator.authority.inventory(),
292
+ hasReconnectGrace: operator.authority.hasReconnectGrace(),
293
+ }))
294
+ return;
295
+ idleTimer = setTimeout(() => {
296
+ idleTimer = undefined;
297
+ void shutdown();
298
+ }, idleTimeout);
299
+ idleTimer.unref();
300
+ }
301
+ const shutdown = async (explicitDrain = false) => {
302
+ if (closing ||
303
+ (!explicitDrain &&
304
+ !brokerIdleShutdownEligible({
305
+ closing,
306
+ draining,
307
+ connectedClients: connected.size,
308
+ idleTimeout,
309
+ inventory: operator.authority.inventory(),
310
+ hasReconnectGrace: operator.authority.hasReconnectGrace(),
311
+ })))
312
+ return;
313
+ draining = true;
314
+ if (idleTimer !== undefined)
315
+ clearTimeout(idleTimer);
316
+ if (!(await brokerShutdownCleanupComplete(operator.authority.inventory(), closeRuntime))) {
317
+ process.stderr.write("[browser-broker] cleanup unproven; retaining physical custody\n");
318
+ return;
319
+ }
320
+ closing = true;
321
+ if (!listenerClosed) {
322
+ listenerClosed = true;
323
+ await listener.close();
324
+ }
325
+ await unlink(`${path}.owner.json`).catch(() => undefined);
326
+ profileElection.release();
327
+ process.exit(0);
328
+ };
329
+ const requestDrain = async () => {
330
+ draining = true;
331
+ if (idleTimer !== undefined)
332
+ clearTimeout(idleTimer);
333
+ await operator.reap(Number.POSITIVE_INFINITY);
334
+ await shutdown(true);
335
+ };
336
+ const reap = setInterval(() => {
337
+ if (cleanupRunning)
338
+ return;
339
+ cleanupRunning = true;
340
+ void operator
341
+ .reap()
342
+ .then(async () => {
343
+ if (maintenanceOwner !== undefined &&
344
+ !connected.has(maintenanceOwner) &&
345
+ maintenanceReady &&
346
+ (await waitForProfileFree(CHROME_PROFILE_DIR, { deadlineMs: 0 }))) {
347
+ await restoreMaintenance();
348
+ }
349
+ if (draining)
350
+ await shutdown(true);
351
+ else if (connected.size === 0 && idleTimeout !== undefined && idleTimer === undefined)
352
+ scheduleShutdownIfIdle();
353
+ })
354
+ .catch((error) => {
355
+ process.stderr.write(`[browser-broker] cleanup retained: ${error instanceof Error ? error.message : String(error)}\n`);
356
+ })
357
+ .finally(() => {
358
+ cleanupRunning = false;
359
+ });
360
+ }, 5000);
361
+ // This timer keeps quarantined payment/outcome custody alive after sockets close.
362
+ process.once("SIGINT", () => {
363
+ void requestDrain();
364
+ });
365
+ process.once("SIGTERM", () => {
366
+ void requestDrain();
367
+ });
368
+ process.once("exit", () => clearInterval(reap));
369
+ process.stderr.write(`[browser-broker] listening cell=${cellId} pid=${process.pid}\n`);
370
+ }
371
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../../src/bot/broker/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { BrokerClient } from "./transport.js";
2
+ export declare function brokerElectionRoot(profileDir?: string): string;
3
+ export declare function brokerLaunchRoot(profileDir?: string): string;
4
+ export declare function brokerEnvironment(env: NodeJS.ProcessEnv, path: string): NodeJS.ProcessEnv;
5
+ export declare function brokerIsSupervised(env?: NodeJS.ProcessEnv): boolean;
6
+ export declare function publishEndpointOwner(path: string): Promise<void>;
7
+ export declare function reclaimDeadBrokerEndpoint(path: string): Promise<void>;
8
+ export declare function connectOrLaunchBroker(path: string, token: string, lineageCredential?: string): Promise<BrokerClient>;
9
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/bot/broker/discovery.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAc9C,wBAAgB,kBAAkB,CAAC,UAAU,SAAqB,GAAG,MAAM,CAE1E;AAED,wBAAgB,gBAAgB,CAAC,UAAU,SAAqB,GAAG,MAAM,CAExE;AAgDD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAIzF;AAED,wBAAgB,kBAAkB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAEhF;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBtE;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsC3E;AAED,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,YAAY,CAAC,CA6DvB"}
@@ -0,0 +1,167 @@
1
+ import { spawn } from "node:child_process";
2
+ import { lstat, mkdir, readFile, unlink, writeFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { acquireProfileOperationGuard, ProfileBusyError, processBirthIdentity, processBirthIdentityState, profilePathIdentity, CHROME_PROFILE_DIR, waitForProfileFree, } from "../profile.js";
6
+ import { BrokerClient } from "./transport.js";
7
+ import { BrokerRefusal } from "./scheduler.js";
8
+ const BROKER_CONNECT_TIMEOUT_MS = 10_000;
9
+ const BROKER_CONNECT_POLL_MS = 100;
10
+ export function brokerElectionRoot(profileDir = CHROME_PROFILE_DIR) {
11
+ return join(dirname(profilePathIdentity(profileDir)), ".trusty-squire-broker-leases");
12
+ }
13
+ export function brokerLaunchRoot(profileDir = CHROME_PROFILE_DIR) {
14
+ return join(brokerElectionRoot(profileDir), "launch");
15
+ }
16
+ async function prepareBrokerElectionRoot(profileDir) {
17
+ const root = brokerElectionRoot(profileDir);
18
+ await mkdir(root, { recursive: true, mode: 0o700 });
19
+ return root;
20
+ }
21
+ async function brokerElectionIsHeld(profileDir) {
22
+ const root = await prepareBrokerElectionRoot(profileDir);
23
+ try {
24
+ const lease = acquireProfileOperationGuard(profileDir, root);
25
+ lease.release();
26
+ return false;
27
+ }
28
+ catch (error) {
29
+ if (error instanceof ProfileBusyError)
30
+ return true;
31
+ throw error;
32
+ }
33
+ }
34
+ function isUnavailable(error) {
35
+ const code = error.code;
36
+ return code === "ENOENT" || code === "ECONNREFUSED";
37
+ }
38
+ async function waitForBroker(path, token, lineageCredential, failure) {
39
+ const deadline = Date.now() + BROKER_CONNECT_TIMEOUT_MS;
40
+ while (Date.now() < deadline) {
41
+ const launchFailure = failure?.();
42
+ if (launchFailure !== undefined)
43
+ throw launchFailure;
44
+ try {
45
+ return await BrokerClient.connect(path, token, lineageCredential);
46
+ }
47
+ catch (error) {
48
+ if (!isUnavailable(error))
49
+ throw error;
50
+ }
51
+ await new Promise((resolve) => setTimeout(resolve, BROKER_CONNECT_POLL_MS));
52
+ }
53
+ throw new BrokerRefusal("broker_unavailable", "Broker did not become available within 10 seconds; no operator command was dispatched");
54
+ }
55
+ export function brokerEnvironment(env, path) {
56
+ const brokerEnv = { ...env };
57
+ delete brokerEnv.TRUSTY_SQUIRE_FORWARDER_CREDENTIAL;
58
+ return { ...brokerEnv, TRUSTY_SQUIRE_BROKER_SOCKET: path };
59
+ }
60
+ export function brokerIsSupervised(env = process.env) {
61
+ return ["1", "true"].includes((env.TRUSTY_SQUIRE_BROKER_SUPERVISED ?? "").toLowerCase());
62
+ }
63
+ export async function publishEndpointOwner(path) {
64
+ const identity = processBirthIdentity(process.pid);
65
+ if (identity === null)
66
+ throw new BrokerRefusal("ownership_unknown", "Cannot establish broker process birth identity");
67
+ const socket = await lstat(path);
68
+ await writeFile(`${path}.owner.json`, JSON.stringify({
69
+ version: 1,
70
+ ...identity,
71
+ profileDir: profilePathIdentity(CHROME_PROFILE_DIR),
72
+ inode: socket.ino,
73
+ device: socket.dev,
74
+ }), { mode: 0o600, flag: "wx" });
75
+ }
76
+ export async function reclaimDeadBrokerEndpoint(path) {
77
+ let owner;
78
+ try {
79
+ owner = JSON.parse(await readFile(`${path}.owner.json`, "utf8"));
80
+ }
81
+ catch {
82
+ throw new BrokerRefusal("broker_unavailable", "Endpoint ownership is unknown; refusing to remove it");
83
+ }
84
+ const profileDir = profilePathIdentity(CHROME_PROFILE_DIR);
85
+ if (owner.version !== 1 ||
86
+ !Number.isSafeInteger(owner.pid) ||
87
+ typeof owner.start_time !== "string" ||
88
+ owner.profileDir !== profileDir ||
89
+ processBirthIdentityState(owner) !== "stale") {
90
+ throw new BrokerRefusal("broker_unavailable", "Endpoint belongs to a live or unproven broker");
91
+ }
92
+ const lease = acquireProfileOperationGuard(profileDir, await prepareBrokerElectionRoot(profileDir));
93
+ try {
94
+ if (!(await waitForProfileFree(profileDir, { deadlineMs: 0 })))
95
+ throw new BrokerRefusal("profile_busy", "Old browser is still being reaped");
96
+ const socket = await lstat(path).catch(() => null);
97
+ const latest = await readFile(`${path}.owner.json`, "utf8");
98
+ if (JSON.stringify(JSON.parse(latest)) !== JSON.stringify(owner))
99
+ throw new BrokerRefusal("broker_unavailable", "Endpoint ownership changed");
100
+ if (socket !== null && (socket.ino !== owner.inode || socket.dev !== owner.device))
101
+ throw new BrokerRefusal("broker_unavailable", "Endpoint was replaced");
102
+ if (socket !== null)
103
+ await unlink(path);
104
+ await unlink(`${path}.owner.json`);
105
+ }
106
+ finally {
107
+ lease.release();
108
+ }
109
+ }
110
+ export async function connectOrLaunchBroker(path, token, lineageCredential) {
111
+ try {
112
+ return await BrokerClient.connect(path, token, lineageCredential);
113
+ }
114
+ catch (error) {
115
+ const code = error.code;
116
+ if (!isUnavailable(error))
117
+ throw error;
118
+ if (brokerIsSupervised())
119
+ throw new BrokerRefusal("broker_unavailable", "Supervised broker is unavailable; refusing to create a competing browser owner");
120
+ if (code === "ECONNREFUSED")
121
+ await reclaimDeadBrokerEndpoint(path);
122
+ // A cleanly stopped broker removes its socket but may have left its owner
123
+ // record if interrupted during final unlink. Reclaim only with birth proof.
124
+ else if (await lstat(`${path}.owner.json`).then(() => true, () => false))
125
+ await reclaimDeadBrokerEndpoint(path);
126
+ }
127
+ const profileDir = profilePathIdentity(CHROME_PROFILE_DIR);
128
+ if (await brokerElectionIsHeld(profileDir))
129
+ return await waitForBroker(path, token, lineageCredential);
130
+ let launchLease;
131
+ try {
132
+ const launchRoot = brokerLaunchRoot(profileDir);
133
+ await mkdir(launchRoot, { recursive: true, mode: 0o700 });
134
+ launchLease = acquireProfileOperationGuard(profileDir, launchRoot);
135
+ }
136
+ catch (error) {
137
+ if (error instanceof ProfileBusyError)
138
+ return await waitForBroker(path, token, lineageCredential);
139
+ throw error;
140
+ }
141
+ try {
142
+ try {
143
+ return await BrokerClient.connect(path, token, lineageCredential);
144
+ }
145
+ catch (error) {
146
+ if (!isUnavailable(error))
147
+ throw error;
148
+ }
149
+ if (await brokerElectionIsHeld(profileDir))
150
+ return await waitForBroker(path, token, lineageCredential);
151
+ const child = spawn(process.execPath, [fileURLToPath(new URL("../../bin.js", import.meta.url)), "broker"], {
152
+ detached: true,
153
+ stdio: "ignore",
154
+ env: brokerEnvironment(process.env, path),
155
+ });
156
+ let failure;
157
+ child.once("error", (error) => {
158
+ failure = error;
159
+ });
160
+ child.unref();
161
+ return await waitForBroker(path, token, lineageCredential, () => failure);
162
+ }
163
+ finally {
164
+ launchLease.release();
165
+ }
166
+ }
167
+ //# sourceMappingURL=discovery.js.map