agent-embassy 2.0.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/CONTRIBUTING.md +19 -34
  3. package/README.md +110 -228
  4. package/SECURITY.md +55 -89
  5. package/dist/src/errors.d.ts +10 -1
  6. package/dist/src/errors.js +3 -1
  7. package/dist/src/errors.js.map +1 -1
  8. package/dist/src/gateway/claude-helper-protocol.d.ts +8 -11
  9. package/dist/src/gateway/claude-helper-protocol.js +12 -11
  10. package/dist/src/gateway/claude-helper-protocol.js.map +1 -1
  11. package/dist/src/gateway/claude-helper-supervisor.d.ts +1 -5
  12. package/dist/src/gateway/claude-helper-supervisor.js +10 -9
  13. package/dist/src/gateway/claude-helper-supervisor.js.map +1 -1
  14. package/dist/src/gateway/claude-helper.js +6 -6
  15. package/dist/src/gateway/claude-helper.js.map +1 -1
  16. package/dist/src/gateway/claude-peer.d.ts +0 -3
  17. package/dist/src/gateway/claude-peer.js +6 -18
  18. package/dist/src/gateway/claude-peer.js.map +1 -1
  19. package/dist/src/gateway/cli.d.ts +17 -6
  20. package/dist/src/gateway/cli.js +912 -261
  21. package/dist/src/gateway/cli.js.map +1 -1
  22. package/dist/src/gateway/codex-socket-holder.d.ts +26 -0
  23. package/dist/src/gateway/codex-socket-holder.js +76 -0
  24. package/dist/src/gateway/codex-socket-holder.js.map +1 -0
  25. package/dist/src/gateway/codex-stateless-transport.js +1 -1
  26. package/dist/src/gateway/codex-stateless-transport.js.map +1 -1
  27. package/dist/src/gateway/config.d.ts +1 -10
  28. package/dist/src/gateway/config.js +4 -10
  29. package/dist/src/gateway/config.js.map +1 -1
  30. package/dist/src/gateway/control.d.ts +45 -77
  31. package/dist/src/gateway/control.js +56 -141
  32. package/dist/src/gateway/control.js.map +1 -1
  33. package/dist/src/gateway/federation-nodes.d.ts +29 -2
  34. package/dist/src/gateway/federation-nodes.js +177 -7
  35. package/dist/src/gateway/federation-nodes.js.map +1 -1
  36. package/dist/src/gateway/peer-client.d.ts +4 -3
  37. package/dist/src/gateway/peer-client.js +22 -13
  38. package/dist/src/gateway/peer-client.js.map +1 -1
  39. package/dist/src/gateway/peer-protocol.d.ts +8 -11
  40. package/dist/src/gateway/peer-protocol.js +5 -12
  41. package/dist/src/gateway/peer-protocol.js.map +1 -1
  42. package/dist/src/gateway/provenance-envelope.d.ts +0 -1
  43. package/dist/src/gateway/provenance-envelope.js +4 -19
  44. package/dist/src/gateway/provenance-envelope.js.map +1 -1
  45. package/dist/src/gateway/providers.d.ts +7 -4
  46. package/dist/src/gateway/providers.js +16 -20
  47. package/dist/src/gateway/providers.js.map +1 -1
  48. package/dist/src/gateway/server.d.ts +3 -12
  49. package/dist/src/gateway/server.js +31 -50
  50. package/dist/src/gateway/server.js.map +1 -1
  51. package/dist/src/gateway/service-agent.d.ts +187 -0
  52. package/dist/src/gateway/service-agent.js +758 -0
  53. package/dist/src/gateway/service-agent.js.map +1 -0
  54. package/dist/src/gateway/service.d.ts +114 -31
  55. package/dist/src/gateway/service.js +461 -566
  56. package/dist/src/gateway/service.js.map +1 -1
  57. package/dist/src/gateway/status-view.d.ts +167 -0
  58. package/dist/src/gateway/status-view.js +488 -0
  59. package/dist/src/gateway/status-view.js.map +1 -0
  60. package/dist/src/gateway/store.d.ts +103 -21
  61. package/dist/src/gateway/store.js +454 -529
  62. package/dist/src/gateway/store.js.map +1 -1
  63. package/dist/src/gateway/types.d.ts +48 -99
  64. package/dist/src/gateway/types.js +15 -52
  65. package/dist/src/gateway/types.js.map +1 -1
  66. package/docs/CONFIGURATION.md +173 -44
  67. package/docs/DELIVERY.md +11 -11
  68. package/docs/GATEWAY-ARCHITECTURE.md +277 -375
  69. package/package.json +4 -12
  70. package/skills/embassy-peer/SKILL.md +65 -90
  71. package/skills/embassy-peer/agents/openai.yaml +1 -1
  72. package/README.zh-CN.md +0 -275
  73. package/assets/live-dashboard/app.css +0 -1619
  74. package/assets/vendor/react/LICENSE +0 -21
  75. package/assets/vendor/react/react-dom.production.min.js +0 -267
  76. package/assets/vendor/react/react.production.min.js +0 -31
  77. package/dist/src/gateway/acp-client.d.ts +0 -110
  78. package/dist/src/gateway/acp-client.js +0 -407
  79. package/dist/src/gateway/acp-client.js.map +0 -1
  80. package/dist/src/gateway/acp-provider.d.ts +0 -66
  81. package/dist/src/gateway/acp-provider.js +0 -275
  82. package/dist/src/gateway/acp-provider.js.map +0 -1
  83. package/dist/src/gateway/cli-copy.d.ts +0 -8
  84. package/dist/src/gateway/cli-copy.en.d.ts +0 -22
  85. package/dist/src/gateway/cli-copy.en.js +0 -62
  86. package/dist/src/gateway/cli-copy.en.js.map +0 -1
  87. package/dist/src/gateway/cli-copy.js +0 -27
  88. package/dist/src/gateway/cli-copy.js.map +0 -1
  89. package/dist/src/gateway/cli-copy.zh-CN.d.ts +0 -22
  90. package/dist/src/gateway/cli-copy.zh-CN.js +0 -62
  91. package/dist/src/gateway/cli-copy.zh-CN.js.map +0 -1
  92. package/dist/src/gateway/codex-doctor.d.ts +0 -36
  93. package/dist/src/gateway/codex-doctor.js +0 -127
  94. package/dist/src/gateway/codex-doctor.js.map +0 -1
  95. package/dist/src/gateway/dashboard-copy.d.ts +0 -7
  96. package/dist/src/gateway/dashboard-copy.en.d.ts +0 -504
  97. package/dist/src/gateway/dashboard-copy.en.js +0 -505
  98. package/dist/src/gateway/dashboard-copy.en.js.map +0 -1
  99. package/dist/src/gateway/dashboard-copy.js +0 -514
  100. package/dist/src/gateway/dashboard-copy.js.map +0 -1
  101. package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +0 -504
  102. package/dist/src/gateway/dashboard-copy.zh-CN.js +0 -505
  103. package/dist/src/gateway/dashboard-copy.zh-CN.js.map +0 -1
  104. package/dist/src/gateway/dashboard-model.d.ts +0 -343
  105. package/dist/src/gateway/dashboard-model.js +0 -1061
  106. package/dist/src/gateway/dashboard-model.js.map +0 -1
  107. package/dist/src/gateway/dashboard.d.ts +0 -20
  108. package/dist/src/gateway/dashboard.js +0 -874
  109. package/dist/src/gateway/dashboard.js.map +0 -1
  110. package/dist/src/gateway/deepseek-detect.d.ts +0 -14
  111. package/dist/src/gateway/deepseek-detect.js +0 -41
  112. package/dist/src/gateway/deepseek-detect.js.map +0 -1
  113. package/dist/src/gateway/live-dashboard-app/app.js +0 -2385
  114. package/dist/src/gateway/live-dashboard-assets.d.ts +0 -10
  115. package/dist/src/gateway/live-dashboard-assets.js +0 -74
  116. package/dist/src/gateway/live-dashboard-assets.js.map +0 -1
  117. package/dist/src/gateway/live-dashboard-command.d.ts +0 -60
  118. package/dist/src/gateway/live-dashboard-command.js +0 -334
  119. package/dist/src/gateway/live-dashboard-command.js.map +0 -1
  120. package/dist/src/gateway/live-dashboard-http.d.ts +0 -39
  121. package/dist/src/gateway/live-dashboard-http.js +0 -383
  122. package/dist/src/gateway/live-dashboard-http.js.map +0 -1
  123. package/dist/src/gateway/live-dashboard-protocol.d.ts +0 -34
  124. package/dist/src/gateway/live-dashboard-protocol.js +0 -114
  125. package/dist/src/gateway/live-dashboard-protocol.js.map +0 -1
  126. package/dist/src/gateway/live-dashboard-server.d.ts +0 -33
  127. package/dist/src/gateway/live-dashboard-server.js +0 -144
  128. package/dist/src/gateway/live-dashboard-server.js.map +0 -1
  129. package/dist/src/gateway/live-dashboard-stream.d.ts +0 -46
  130. package/dist/src/gateway/live-dashboard-stream.js +0 -234
  131. package/dist/src/gateway/live-dashboard-stream.js.map +0 -1
  132. package/dist/src/gateway/live-dashboard.d.ts +0 -28
  133. package/dist/src/gateway/live-dashboard.js +0 -154
  134. package/dist/src/gateway/live-dashboard.js.map +0 -1
  135. package/dist/src/gateway/locale.d.ts +0 -4
  136. package/dist/src/gateway/locale.js +0 -10
  137. package/dist/src/gateway/locale.js.map +0 -1
  138. package/dist/src/gateway/progress-watch-machine.d.ts +0 -45
  139. package/dist/src/gateway/progress-watch-machine.js +0 -70
  140. package/dist/src/gateway/progress-watch-machine.js.map +0 -1
  141. package/docs/CONFIGURATION.zh-CN.md +0 -97
  142. package/docs/DASHBOARD.md +0 -98
  143. package/docs/DASHBOARD.zh-CN.md +0 -49
  144. package/docs/DELIVERY.zh-CN.md +0 -55
@@ -1,144 +0,0 @@
1
- import { createServer, } from "node:http";
2
- import { BridgeError } from "../errors.js";
3
- import { LIVE_DASHBOARD_LIMITS } from "./live-dashboard-protocol.js";
4
- export const defaultLiveDashboardHttpFactory = {
5
- createServer: (listener) => {
6
- const server = createServer({
7
- insecureHTTPParser: false,
8
- maxHeaderSize: LIVE_DASHBOARD_LIMITS.maximumHeaderBytes,
9
- }, listener);
10
- return server;
11
- },
12
- };
13
- function isIpv4LoopbackAddress(address) {
14
- if (address === null || typeof address === "string")
15
- return false;
16
- return (address.address === "127.0.0.1" &&
17
- address.family === "IPv4" &&
18
- Number.isSafeInteger(address.port) &&
19
- address.port > 0 &&
20
- address.port <= 65_535);
21
- }
22
- async function closeServer(server) {
23
- await new Promise((resolve, reject) => {
24
- let closeFinished = false;
25
- let forceFinished = false;
26
- let closeError;
27
- let forceError;
28
- const settle = () => {
29
- if (!closeFinished || !forceFinished)
30
- return;
31
- const error = closeError ?? forceError;
32
- if (error === undefined)
33
- resolve();
34
- else
35
- reject(error);
36
- };
37
- try {
38
- server.close((error) => {
39
- closeError = error;
40
- closeFinished = true;
41
- settle();
42
- });
43
- }
44
- catch (error) {
45
- reject(error);
46
- return;
47
- }
48
- try {
49
- server.closeAllConnections?.();
50
- }
51
- catch (error) {
52
- forceError = error;
53
- }
54
- forceFinished = true;
55
- settle();
56
- });
57
- }
58
- function normalizedBindError(error, port) {
59
- if ("code" in error &&
60
- error.code === "EADDRINUSE") {
61
- return new BridgeError("LIVE_DASHBOARD_PORT_IN_USE", `Live dashboard port ${port} is already in use. Close the holding process or choose another with --port <n>.`, true);
62
- }
63
- return error;
64
- }
65
- export async function bindLiveDashboardServer(server, port, signal) {
66
- server.maxConnections = LIVE_DASHBOARD_LIMITS.maximumConnections;
67
- server.headersTimeout = LIVE_DASHBOARD_LIMITS.headersTimeoutMs;
68
- server.requestTimeout = LIVE_DASHBOARD_LIMITS.requestTimeoutMs;
69
- server.keepAliveTimeout = LIVE_DASHBOARD_LIMITS.keepAliveTimeoutMs;
70
- // Port 0 is retained only as a test-owned real-listener seam. Production
71
- // configuration accepts 1024..65535 and always requests a stable port.
72
- if (!Number.isSafeInteger(port) || port < 0 || port > 65_535) {
73
- throw new Error("LIVE_DASHBOARD_PORT_INVALID");
74
- }
75
- if (signal?.aborted === true) {
76
- throw new Error("LIVE_DASHBOARD_BIND_ABORTED");
77
- }
78
- await new Promise((resolve, reject) => {
79
- let settled = false;
80
- const cleanup = () => {
81
- server.off("error", onError);
82
- server.off("listening", onListening);
83
- signal?.removeEventListener("abort", onAbort);
84
- };
85
- const onListening = () => {
86
- if (settled)
87
- return;
88
- settled = true;
89
- cleanup();
90
- resolve();
91
- };
92
- const onError = (error) => {
93
- if (settled)
94
- return;
95
- settled = true;
96
- cleanup();
97
- reject(normalizedBindError(error, port));
98
- };
99
- const onAbort = () => {
100
- if (settled)
101
- return;
102
- settled = true;
103
- cleanup();
104
- try {
105
- server.close(() => undefined);
106
- }
107
- catch {
108
- // The listener may not yet have entered Node's listening state.
109
- }
110
- server.closeAllConnections?.();
111
- reject(new Error("LIVE_DASHBOARD_BIND_ABORTED"));
112
- };
113
- server.once("error", onError);
114
- server.once("listening", onListening);
115
- signal?.addEventListener("abort", onAbort, { once: true });
116
- try {
117
- server.listen({
118
- host: "127.0.0.1",
119
- port,
120
- exclusive: true,
121
- });
122
- }
123
- catch (error) {
124
- onError(error instanceof Error
125
- ? error
126
- : new Error("LIVE_DASHBOARD_BIND_FAILED"));
127
- }
128
- });
129
- const address = server.address();
130
- if (!isIpv4LoopbackAddress(address) ||
131
- (port !== 0 && address.port !== port)) {
132
- await closeServer(server).catch(() => undefined);
133
- throw new Error("LIVE_DASHBOARD_BIND_NOT_IPV4_LOOPBACK");
134
- }
135
- let closeInFlight;
136
- return {
137
- address: { host: "127.0.0.1", port: address.port },
138
- close: () => {
139
- closeInFlight ??= closeServer(server);
140
- return closeInFlight;
141
- },
142
- };
143
- }
144
- //# sourceMappingURL=live-dashboard-server.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"live-dashboard-server.js","sourceRoot":"","sources":["../../../src/gateway/live-dashboard-server.ts"],"names":[],"mappings":"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"}
@@ -1,46 +0,0 @@
1
- import { type LiveDashboardViewModel } from "./dashboard-model.js";
2
- import type { GatewayPublicSnapshot } from "./types.js";
3
- export type LiveDashboardSnapshotRevision = string | number;
4
- export type LiveDashboardObservation = Readonly<{
5
- snapshotRevision: LiveDashboardSnapshotRevision;
6
- snapshot: GatewayPublicSnapshot;
7
- }>;
8
- export type LiveDashboardObserver = Readonly<{
9
- observe(): Promise<LiveDashboardObservation>;
10
- }>;
11
- export type LiveDashboardClock = Readonly<{
12
- now(): number;
13
- setInterval(callback: () => void, milliseconds: number): unknown;
14
- clearInterval(handle: unknown): void;
15
- }>;
16
- export declare const defaultLiveDashboardClock: LiveDashboardClock;
17
- export type LiveDashboardStreamWriter = Readonly<{
18
- write(chunk: string): boolean;
19
- onDrain(callback: () => void): void;
20
- onClose(callback: () => void): void;
21
- end(): void;
22
- }>;
23
- export type LiveDashboardStreamEvent = Readonly<{
24
- streamRevision: number;
25
- snapshotRevision: LiveDashboardSnapshotRevision;
26
- reset: boolean;
27
- model: LiveDashboardViewModel;
28
- }>;
29
- export type LiveDashboardStreamHub = Readonly<{
30
- add(writer: LiveDashboardStreamWriter): Readonly<{
31
- ok: true;
32
- close(): void;
33
- }> | Readonly<{
34
- ok: false;
35
- safeCode: "LIVE_STREAM_LIMIT";
36
- }>;
37
- latest(): LiveDashboardStreamEvent | undefined;
38
- pollNow(): Promise<void>;
39
- refresh(): Promise<LiveDashboardStreamEvent | undefined>;
40
- shutdown(): void;
41
- streamCount(): number;
42
- }>;
43
- export declare function createLiveDashboardStreamHub(options: Readonly<{
44
- observer: LiveDashboardObserver;
45
- clock?: LiveDashboardClock;
46
- }>): LiveDashboardStreamHub;
@@ -1,234 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { buildLiveDashboardViewModel, } from "./dashboard-model.js";
3
- import { LIVE_DASHBOARD_LIMITS } from "./live-dashboard-protocol.js";
4
- export const defaultLiveDashboardClock = {
5
- now: Date.now,
6
- setInterval: (callback, milliseconds) => setInterval(callback, milliseconds),
7
- clearInterval: (handle) => clearInterval(handle),
8
- };
9
- function normalizeRevision(revision) {
10
- if (typeof revision === "number" &&
11
- Number.isSafeInteger(revision) &&
12
- revision >= 0) {
13
- return revision;
14
- }
15
- if (typeof revision === "string" &&
16
- /^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$/u.test(revision)) {
17
- return revision;
18
- }
19
- throw new Error("LIVE_DASHBOARD_REVISION_INVALID");
20
- }
21
- const TIME_DERIVED_KEY = /(?:Ms|At)$/u;
22
- function stripTimeDerived(value) {
23
- if (Array.isArray(value))
24
- return value.map(stripTimeDerived);
25
- if (value !== null && typeof value === "object") {
26
- const out = {};
27
- for (const [key, entry] of Object.entries(value)) {
28
- if (TIME_DERIVED_KEY.test(key))
29
- continue;
30
- out[key] = stripTimeDerived(entry);
31
- }
32
- return out;
33
- }
34
- return value;
35
- }
36
- function fingerprint(model) {
37
- // Clock-derived fields (`…Ms` durations, `…At` timestamps) advance even when
38
- // the broker's public semantics have not changed. Stripping them by key
39
- // shape keeps this fingerprint aligned with the gateway's semantic-revision
40
- // contract without a hand-mirrored exclusion list — the list drifted from
41
- // the view model and produced a false "Source restarted" banner every poll.
42
- return createHash("sha256")
43
- .update(JSON.stringify(stripTimeDerived(model)))
44
- .digest("hex");
45
- }
46
- function isRevisionReset(previous, next) {
47
- // A reset is a regression of the source revision; observer loss is handled
48
- // by the caller. "Same revision, changed content" is a publish signal, never
49
- // a restart signal.
50
- return (typeof previous === "number" &&
51
- typeof next === "number" &&
52
- next < previous);
53
- }
54
- function snapshotFrame(event) {
55
- return `id: ${event.streamRevision}\nevent: snapshot\ndata: ${JSON.stringify(event)}\n\n`;
56
- }
57
- function unavailableFrame() {
58
- return "event: observer_unavailable\ndata: {\"safeCode\":\"LIVE_OBSERVER_UNAVAILABLE\"}\n\n";
59
- }
60
- export function createLiveDashboardStreamHub(options) {
61
- const clock = options.clock ?? defaultLiveDashboardClock;
62
- const streams = new Set();
63
- let interval;
64
- let pollInFlight;
65
- let latest;
66
- let previousSourceRevision;
67
- let streamRevision = 0;
68
- let observerUnavailable = false;
69
- let stopped = false;
70
- const closeStream = (stream) => {
71
- if (stream.closed)
72
- return;
73
- stream.closed = true;
74
- streams.delete(stream);
75
- delete stream.queued;
76
- try {
77
- stream.writer.end();
78
- }
79
- catch {
80
- // Closing a disconnected browser is best effort.
81
- }
82
- if (streams.size === 0 && interval !== undefined) {
83
- clock.clearInterval(interval);
84
- interval = undefined;
85
- }
86
- };
87
- const flush = (stream, frame) => {
88
- if (stream.closed)
89
- return;
90
- const now = clock.now();
91
- if (stream.blockedAt !== undefined) {
92
- if (now - stream.blockedAt >=
93
- LIVE_DASHBOARD_LIMITS.backpressureTimeoutMs) {
94
- closeStream(stream);
95
- return;
96
- }
97
- stream.queued = frame;
98
- return;
99
- }
100
- try {
101
- const accepted = stream.writer.write(frame);
102
- stream.lastEmissionAt = now;
103
- if (!accepted)
104
- stream.blockedAt = now;
105
- }
106
- catch {
107
- closeStream(stream);
108
- }
109
- };
110
- const broadcast = (frame) => {
111
- for (const stream of [...streams])
112
- flush(stream, frame);
113
- };
114
- const tickMaintenance = () => {
115
- const now = clock.now();
116
- for (const stream of [...streams]) {
117
- if (stream.blockedAt !== undefined &&
118
- now - stream.blockedAt >=
119
- LIVE_DASHBOARD_LIMITS.backpressureTimeoutMs) {
120
- closeStream(stream);
121
- continue;
122
- }
123
- if (stream.blockedAt === undefined &&
124
- now - stream.lastEmissionAt >=
125
- LIVE_DASHBOARD_LIMITS.heartbeatIntervalMs) {
126
- flush(stream, `: heartbeat ${now}\n\n`);
127
- }
128
- }
129
- };
130
- const performPoll = async (allowWithoutStreams) => {
131
- if (stopped || (!allowWithoutStreams && streams.size === 0))
132
- return undefined;
133
- try {
134
- const observed = await options.observer.observe();
135
- if (stopped)
136
- return undefined;
137
- const nextRevision = normalizeRevision(observed.snapshotRevision);
138
- const model = buildLiveDashboardViewModel(observed.snapshot);
139
- const nextFingerprint = fingerprint(model);
140
- const changed = latest?.fingerprint !== nextFingerprint;
141
- const reset = observerUnavailable ||
142
- (previousSourceRevision !== undefined &&
143
- isRevisionReset(previousSourceRevision, nextRevision));
144
- const shouldPublish = latest === undefined || changed || reset;
145
- previousSourceRevision = nextRevision;
146
- observerUnavailable = false;
147
- if (shouldPublish) {
148
- streamRevision += 1;
149
- const event = {
150
- streamRevision,
151
- snapshotRevision: nextRevision,
152
- reset,
153
- model,
154
- };
155
- latest = { event, fingerprint: nextFingerprint };
156
- broadcast(snapshotFrame(event));
157
- }
158
- return latest?.event;
159
- }
160
- catch {
161
- if (!observerUnavailable) {
162
- observerUnavailable = true;
163
- broadcast(unavailableFrame());
164
- }
165
- return undefined;
166
- }
167
- };
168
- const requestPoll = (allowWithoutStreams) => {
169
- if (pollInFlight !== undefined)
170
- return pollInFlight;
171
- pollInFlight = performPoll(allowWithoutStreams).finally(() => {
172
- pollInFlight = undefined;
173
- });
174
- return pollInFlight;
175
- };
176
- const pollNow = async () => {
177
- if (stopped || streams.size === 0)
178
- return;
179
- await requestPoll(false);
180
- };
181
- const startPolling = () => {
182
- if (interval !== undefined || stopped || streams.size === 0)
183
- return;
184
- interval = clock.setInterval(() => {
185
- tickMaintenance();
186
- void pollNow();
187
- }, LIVE_DASHBOARD_LIMITS.pollIntervalMs);
188
- void pollNow();
189
- };
190
- return {
191
- add: (writer) => {
192
- if (stopped || streams.size >= LIVE_DASHBOARD_LIMITS.maximumStreams) {
193
- return { ok: false, safeCode: "LIVE_STREAM_LIMIT" };
194
- }
195
- const stream = {
196
- writer,
197
- lastEmissionAt: clock.now(),
198
- closed: false,
199
- };
200
- streams.add(stream);
201
- writer.onDrain(() => {
202
- if (stream.closed || stream.blockedAt === undefined)
203
- return;
204
- delete stream.blockedAt;
205
- const queued = stream.queued;
206
- delete stream.queued;
207
- if (queued !== undefined)
208
- flush(stream, queued);
209
- });
210
- writer.onClose(() => closeStream(stream));
211
- if (latest !== undefined)
212
- flush(stream, snapshotFrame(latest.event));
213
- startPolling();
214
- return { ok: true, close: () => closeStream(stream) };
215
- },
216
- latest: () => latest?.event,
217
- pollNow,
218
- refresh: async () => await requestPoll(true),
219
- shutdown: () => {
220
- if (stopped)
221
- return;
222
- stopped = true;
223
- if (interval !== undefined) {
224
- clock.clearInterval(interval);
225
- interval = undefined;
226
- }
227
- broadcast("event: shutdown\ndata: {\"safeCode\":\"LIVE_DASHBOARD_SHUTDOWN\"}\n\n");
228
- for (const stream of [...streams])
229
- closeStream(stream);
230
- },
231
- streamCount: () => streams.size,
232
- };
233
- }
234
- //# sourceMappingURL=live-dashboard-stream.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"live-dashboard-stream.js","sourceRoot":"","sources":["../../../src/gateway/live-dashboard-stream.ts"],"names":[],"mappings":"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"}
@@ -1,28 +0,0 @@
1
- import { type DashboardLocale } from "./dashboard-copy.js";
2
- import { type LiveDashboardActionExecutor } from "./live-dashboard-http.js";
3
- import { type LiveDashboardHttpFactory, type LiveDashboardServerAddress } from "./live-dashboard-server.js";
4
- import { type LiveDashboardClock, type LiveDashboardObserver } from "./live-dashboard-stream.js";
5
- export type LiveDashboardDependencies = Readonly<{
6
- http?: LiveDashboardHttpFactory;
7
- clock?: LiveDashboardClock;
8
- openDashboard?: (url: string) => Promise<void> | void;
9
- }>;
10
- export type StartLiveDashboardOptions = Readonly<{
11
- port: number;
12
- observer: LiveDashboardObserver;
13
- actions: LiveDashboardActionExecutor;
14
- locale?: DashboardLocale;
15
- signal?: AbortSignal;
16
- dependencies?: LiveDashboardDependencies;
17
- }>;
18
- export type RunningLiveDashboard = Readonly<{
19
- address: LiveDashboardServerAddress;
20
- url: string;
21
- close(): Promise<void>;
22
- }>;
23
- export declare class LiveDashboardStartupCancelledError extends Error {
24
- readonly code: "LIVE_DASHBOARD_START_CANCELLED";
25
- constructor();
26
- }
27
- export declare function isLiveDashboardStartupCancelled(error: unknown): error is LiveDashboardStartupCancelledError;
28
- export declare function startLiveDashboard(options: StartLiveDashboardOptions): Promise<RunningLiveDashboard>;
@@ -1,154 +0,0 @@
1
- import { getDashboardCopy, } from "./dashboard-copy.js";
2
- import { renderLiveDashboardAssets } from "./live-dashboard-assets.js";
3
- import { createLiveDashboardRequestHandler, } from "./live-dashboard-http.js";
4
- import { liveDashboardSecurityHeaders } from "./live-dashboard-protocol.js";
5
- import { bindLiveDashboardServer, defaultLiveDashboardHttpFactory, } from "./live-dashboard-server.js";
6
- import { createLiveDashboardStreamHub, } from "./live-dashboard-stream.js";
7
- export class LiveDashboardStartupCancelledError extends Error {
8
- code = "LIVE_DASHBOARD_START_CANCELLED";
9
- constructor() {
10
- super("Live dashboard startup was cancelled.");
11
- this.name = "LiveDashboardStartupCancelledError";
12
- }
13
- }
14
- export function isLiveDashboardStartupCancelled(error) {
15
- return (error instanceof LiveDashboardStartupCancelledError ||
16
- (typeof error === "object" &&
17
- error !== null &&
18
- "code" in error &&
19
- error.code === "LIVE_DASHBOARD_START_CANCELLED"));
20
- }
21
- function throwIfStartupCancelled(signal) {
22
- if (signal?.aborted === true) {
23
- throw new LiveDashboardStartupCancelledError();
24
- }
25
- }
26
- async function awaitStartupStep(operation, signal, onLateSuccess) {
27
- if (signal === undefined)
28
- return operation;
29
- if (signal.aborted) {
30
- void operation.then((value) => Promise.resolve(onLateSuccess?.(value)).catch(() => undefined), () => undefined);
31
- throw new LiveDashboardStartupCancelledError();
32
- }
33
- return await new Promise((resolve, reject) => {
34
- let settled = false;
35
- const onAbort = () => {
36
- if (settled)
37
- return;
38
- settled = true;
39
- signal.removeEventListener("abort", onAbort);
40
- reject(new LiveDashboardStartupCancelledError());
41
- };
42
- signal.addEventListener("abort", onAbort, { once: true });
43
- void operation.then((value) => {
44
- if (settled) {
45
- void Promise.resolve(onLateSuccess?.(value)).catch(() => undefined);
46
- return;
47
- }
48
- settled = true;
49
- signal.removeEventListener("abort", onAbort);
50
- resolve(value);
51
- }, (error) => {
52
- if (settled)
53
- return;
54
- settled = true;
55
- signal.removeEventListener("abort", onAbort);
56
- reject(error);
57
- });
58
- });
59
- }
60
- function notReadyHandler(lang) {
61
- const body = `${getDashboardCopy(lang)["live.http.starting"]}\n`;
62
- return (_request, response) => {
63
- if (response.headersSent) {
64
- response.end();
65
- return;
66
- }
67
- response.writeHead(503, {
68
- ...liveDashboardSecurityHeaders(),
69
- "Content-Type": "text/plain; charset=utf-8",
70
- "Content-Length": String(Buffer.byteLength(body, "utf8")),
71
- });
72
- response.end(body);
73
- };
74
- }
75
- export async function startLiveDashboard(options) {
76
- throwIfStartupCancelled(options.signal);
77
- const dependencies = options.dependencies ?? {};
78
- const http = dependencies.http ?? defaultLiveDashboardHttpFactory;
79
- const locale = options.locale ?? "en";
80
- const assets = renderLiveDashboardAssets(locale);
81
- const hub = createLiveDashboardStreamHub({
82
- observer: options.observer,
83
- ...(dependencies.clock === undefined ? {} : { clock: dependencies.clock }),
84
- });
85
- let activeHandler = notReadyHandler(locale);
86
- const server = http.createServer((request, response) => {
87
- void activeHandler(request, response);
88
- });
89
- let bound;
90
- let url;
91
- try {
92
- bound = await bindLiveDashboardServer(server, options.port, options.signal);
93
- throwIfStartupCancelled(options.signal);
94
- const expectedHost = `${bound.address.host}:${bound.address.port}`;
95
- const expectedOrigin = `http://${expectedHost}`;
96
- url = `${expectedOrigin}/`;
97
- activeHandler = createLiveDashboardRequestHandler({
98
- expectedHost,
99
- expectedOrigin,
100
- lang: locale,
101
- assets,
102
- hub,
103
- actions: options.actions,
104
- ...(dependencies.clock === undefined
105
- ? {}
106
- : { now: dependencies.clock.now }),
107
- });
108
- if (dependencies.openDashboard !== undefined) {
109
- await awaitStartupStep(Promise.resolve(dependencies.openDashboard(url)), options.signal);
110
- }
111
- throwIfStartupCancelled(options.signal);
112
- }
113
- catch (error) {
114
- hub.shutdown();
115
- await bound?.close().catch(() => undefined);
116
- if (options.signal?.aborted === true) {
117
- throw new LiveDashboardStartupCancelledError();
118
- }
119
- throw error;
120
- }
121
- let closeInFlight;
122
- const close = async () => {
123
- if (closeInFlight !== undefined)
124
- return closeInFlight;
125
- closeInFlight = (async () => {
126
- options.signal?.removeEventListener("abort", onAbortAfterReady);
127
- hub.shutdown();
128
- let closeError;
129
- try {
130
- await bound.close();
131
- }
132
- catch (error) {
133
- closeError = error;
134
- }
135
- if (closeError !== undefined)
136
- throw closeError;
137
- })();
138
- return closeInFlight;
139
- };
140
- const onAbortAfterReady = () => {
141
- void close().catch(() => undefined);
142
- };
143
- options.signal?.addEventListener("abort", onAbortAfterReady, { once: true });
144
- if (options.signal?.aborted === true) {
145
- await close();
146
- throw new LiveDashboardStartupCancelledError();
147
- }
148
- return {
149
- address: bound.address,
150
- url,
151
- close,
152
- };
153
- }
154
- //# sourceMappingURL=live-dashboard.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"live-dashboard.js","sourceRoot":"","sources":["../../../src/gateway/live-dashboard.ts"],"names":[],"mappings":"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"}
@@ -1,4 +0,0 @@
1
- export declare const dashboardLocales: readonly ["en", "zh-CN"];
2
- export type DashboardLocale = (typeof dashboardLocales)[number];
3
- export declare function isDashboardLocale(value: unknown): value is DashboardLocale;
4
- export declare function assertDashboardLocale(value: unknown): asserts value is DashboardLocale;
@@ -1,10 +0,0 @@
1
- export const dashboardLocales = ["en", "zh-CN"];
2
- export function isDashboardLocale(value) {
3
- return value === "en" || value === "zh-CN";
4
- }
5
- export function assertDashboardLocale(value) {
6
- if (!isDashboardLocale(value)) {
7
- throw new Error("DASHBOARD_LOCALE_UNSUPPORTED");
8
- }
9
- }
10
- //# sourceMappingURL=locale.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"locale.js","sourceRoot":"","sources":["../../../src/gateway/locale.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE,OAAO,CAAU,CAAC;AAIzD,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,OAAO,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,KAAc;IAEd,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;AACH,CAAC"}