nterminal 1.3.4 → 1.3.5

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 (113) hide show
  1. package/bin/nterminal.js +8 -3
  2. package/dist/client/assets/MarkdownPreview-BIrwUAaa.js +1 -0
  3. package/dist/client/assets/{TranscriptMarkdownBody-H8ZsISc6.js → TranscriptMarkdownBody-CI0ztvMX.js} +1 -1
  4. package/dist/client/assets/{index-DxfBq-4P.js → index-EN8ngMgv.js} +1 -1
  5. package/dist/client/assets/index-JQJ1Eet1.js +58 -0
  6. package/dist/client/assets/index-xkL4h3qt.css +1 -0
  7. package/dist/client/index.html +2 -2
  8. package/dist/scripts/hooks.js +83 -0
  9. package/dist/scripts/hooks.js.map +1 -0
  10. package/dist/server/accounts/accountService.d.ts +23 -1
  11. package/dist/server/accounts/accountService.js +235 -103
  12. package/dist/server/accounts/accountService.js.map +1 -1
  13. package/dist/server/accounts/providerRequests.d.ts +12 -0
  14. package/dist/server/accounts/providerRequests.js +159 -0
  15. package/dist/server/accounts/providerRequests.js.map +1 -0
  16. package/dist/server/agent/agentRoutes.js +11 -0
  17. package/dist/server/agent/agentRoutes.js.map +1 -1
  18. package/dist/server/hooks/helperJournal.d.ts +16 -0
  19. package/dist/server/hooks/helperJournal.js +74 -0
  20. package/dist/server/hooks/helperJournal.js.map +1 -0
  21. package/dist/server/hooks/hookBinding.d.ts +39 -0
  22. package/dist/server/hooks/hookBinding.js +91 -0
  23. package/dist/server/hooks/hookBinding.js.map +1 -0
  24. package/dist/server/hooks/hookFiles.d.ts +24 -0
  25. package/dist/server/hooks/hookFiles.js +160 -0
  26. package/dist/server/hooks/hookFiles.js.map +1 -0
  27. package/dist/server/hooks/hookInstallation.d.ts +79 -0
  28. package/dist/server/hooks/hookInstallation.js +978 -0
  29. package/dist/server/hooks/hookInstallation.js.map +1 -0
  30. package/dist/server/hooks/hookProcess.d.ts +5 -0
  31. package/dist/server/hooks/hookProcess.js +85 -0
  32. package/dist/server/hooks/hookProcess.js.map +1 -0
  33. package/dist/server/hooks/hookReceiver.d.ts +66 -0
  34. package/dist/server/hooks/hookReceiver.js +549 -0
  35. package/dist/server/hooks/hookReceiver.js.map +1 -0
  36. package/dist/server/hooks/lifecycle.d.ts +40 -0
  37. package/dist/server/hooks/lifecycle.js +200 -0
  38. package/dist/server/hooks/lifecycle.js.map +1 -0
  39. package/dist/server/hooks/publicationLock.d.ts +3 -0
  40. package/dist/server/hooks/publicationLock.js +137 -0
  41. package/dist/server/hooks/publicationLock.js.map +1 -0
  42. package/dist/server/hooks/verifiedLock.d.ts +24 -0
  43. package/dist/server/hooks/verifiedLock.js +207 -0
  44. package/dist/server/hooks/verifiedLock.js.map +1 -0
  45. package/dist/server/http.d.ts +4 -0
  46. package/dist/server/http.js +6 -0
  47. package/dist/server/http.js.map +1 -1
  48. package/dist/server/index.js +69 -2
  49. package/dist/server/index.js.map +1 -1
  50. package/dist/server/notifications/agentCompletionMonitor.d.ts +16 -1
  51. package/dist/server/notifications/agentCompletionMonitor.js +261 -47
  52. package/dist/server/notifications/agentCompletionMonitor.js.map +1 -1
  53. package/dist/server/notifications/completionNotificationRouter.d.ts +2 -0
  54. package/dist/server/notifications/completionNotificationRouter.js +9 -0
  55. package/dist/server/notifications/completionNotificationRouter.js.map +1 -1
  56. package/dist/server/routes/accountRoutes.js +11 -0
  57. package/dist/server/routes/accountRoutes.js.map +1 -1
  58. package/dist/server/routes/activityRoutes.d.ts +13 -0
  59. package/dist/server/routes/activityRoutes.js +165 -0
  60. package/dist/server/routes/activityRoutes.js.map +1 -0
  61. package/dist/server/routes/agentManagementRoutes.js +8 -1
  62. package/dist/server/routes/agentManagementRoutes.js.map +1 -1
  63. package/dist/server/routes/hookRoutes.d.ts +16 -0
  64. package/dist/server/routes/hookRoutes.js +77 -0
  65. package/dist/server/routes/hookRoutes.js.map +1 -0
  66. package/dist/server/routes/terminalRoutes.js +4 -0
  67. package/dist/server/routes/terminalRoutes.js.map +1 -1
  68. package/dist/server/routes/transcriptQuery.d.ts +2 -1
  69. package/dist/server/routes/transcriptQuery.js +3 -1
  70. package/dist/server/routes/transcriptQuery.js.map +1 -1
  71. package/dist/server/terminal/PtyAdapter.d.ts +18 -0
  72. package/dist/server/terminal/PtyAdapter.js.map +1 -1
  73. package/dist/server/terminal/TerminalManager.d.ts +61 -0
  74. package/dist/server/terminal/TerminalManager.js +665 -12
  75. package/dist/server/terminal/TerminalManager.js.map +1 -1
  76. package/dist/server/terminal/TmuxPtyAdapter.d.ts +14 -2
  77. package/dist/server/terminal/TmuxPtyAdapter.js +99 -15
  78. package/dist/server/terminal/TmuxPtyAdapter.js.map +1 -1
  79. package/dist/server/terminal/activityChannel.d.ts +57 -0
  80. package/dist/server/terminal/activityChannel.js +166 -0
  81. package/dist/server/terminal/activityChannel.js.map +1 -0
  82. package/dist/server/terminal/agentTranscriptStatus.d.ts +12 -0
  83. package/dist/server/terminal/agentTranscriptStatus.js +78 -7
  84. package/dist/server/terminal/agentTranscriptStatus.js.map +1 -1
  85. package/dist/server/terminal/codexTranscriptSource.d.ts +2 -0
  86. package/dist/server/terminal/codexTranscriptSource.js +41 -37
  87. package/dist/server/terminal/codexTranscriptSource.js.map +1 -1
  88. package/dist/server/terminal/subagentSources.js +2 -1
  89. package/dist/server/terminal/subagentSources.js.map +1 -1
  90. package/dist/server/terminal/transcriptHeader.d.ts +85 -0
  91. package/dist/server/terminal/transcriptHeader.js +376 -0
  92. package/dist/server/terminal/transcriptHeader.js.map +1 -0
  93. package/dist/server/terminal/transcriptHistory.d.ts +16 -2
  94. package/dist/server/terminal/transcriptHistory.js +120 -21
  95. package/dist/server/terminal/transcriptHistory.js.map +1 -1
  96. package/dist/server/terminal/transcriptStore.d.ts +6 -0
  97. package/dist/server/terminal/transcriptStore.js +222 -26
  98. package/dist/server/terminal/transcriptStore.js.map +1 -1
  99. package/dist/shared/activityProbe.d.ts +10 -0
  100. package/dist/shared/activityProbe.js +24 -0
  101. package/dist/shared/activityProbe.js.map +1 -0
  102. package/dist/shared/protocol.d.ts +45 -0
  103. package/dist/shared/protocol.js.map +1 -1
  104. package/dist/shared/types.d.ts +9 -1
  105. package/docs/features.md +10 -0
  106. package/docs/provider-hooks.md +287 -0
  107. package/docs/terminal-history.md +10 -0
  108. package/package.json +2 -1
  109. package/scripts/nterminal-hook.cjs +171 -0
  110. package/scripts/nterminalctl +26 -2
  111. package/dist/client/assets/MarkdownPreview-DjDO4lEl.js +0 -1
  112. package/dist/client/assets/index-CIYazAGv.css +0 -1
  113. package/dist/client/assets/index-DwvLN_WJ.js +0 -56
@@ -0,0 +1,549 @@
1
+ import { randomBytes, timingSafeEqual } from 'node:crypto';
2
+ import { constants } from 'node:fs';
3
+ import { chmod, lstat, mkdir, open, readlink, realpath, rename, unlink } from 'node:fs/promises';
4
+ import { createServer } from 'node:http';
5
+ import { createConnection } from 'node:net';
6
+ import path from 'node:path';
7
+ import { syncDirectory } from './hookFiles.js';
8
+ import { acquireVerifiedLock, VerifiedLockError } from './verifiedLock.js';
9
+ import { acquirePublicationGate } from './publicationLock.js';
10
+ import { isLowPriorityLifecycleEvent } from './lifecycle.js';
11
+ const MAX_BODY = 64 * 1024;
12
+ // Tool events (sync or `async: true`) may use at most MAX_PENDING slots and
13
+ // are coalesced per session. Start/stop/completion events may use the
14
+ // reserve up to MAX_PRIORITY_PENDING and evict queued tool events, so a Stop
15
+ // is never refused while tool events are waiting.
16
+ const MAX_PENDING = 32;
17
+ const MAX_PRIORITY_PENDING = 48;
18
+ const MAX_CONNECTIONS = 32;
19
+ // Process proofs run concurrently per class, so parallel tool events can never
20
+ // take the slots a synchronous Stop/prompt boundary needs.
21
+ const MAX_VALIDATING = 4;
22
+ const MAX_PRIORITY_VALIDATING = 4;
23
+ // Unfinished request bodies, before the event class is known. Helpers send
24
+ // their body at once, so only a stalled local client ever holds these.
25
+ const MAX_READING = 16;
26
+ const REQUEST_MS = 600;
27
+ const STOP_MS = 250;
28
+ const PROBE_MS = 100;
29
+ const DIAGNOSTIC_MS = 1000;
30
+ const ID = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,255}$/;
31
+ const ERRORS = new Set(['authentication_error', 'rate_limit_error', 'api_error', 'overloaded_error',
32
+ 'server_error', 'timeout', 'permission_denied', 'cancelled', 'provider_error', 'rate_limit', 'overloaded',
33
+ 'authentication_failed', 'oauth_org_not_allowed', 'account_on_hold', 'billing_error', 'invalid_request',
34
+ 'model_not_found', 'max_output_tokens', 'cloud_credential_error', 'unknown']);
35
+ const KEYS = new Set(['provider', 'event', 'sessionId', 'transcriptPath', 'cwd', 'turnId', 'promptId',
36
+ 'agentId', 'pid', 'ancestors', 'occurredAt', 'eventId', 'background', 'stopHookActive', 'hasBackgroundTasks', 'notificationType', 'error']);
37
+ function record(value) {
38
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
39
+ }
40
+ function validate(value) {
41
+ if (!record(value) || Object.keys(value).some(key => !KEYS.has(key)))
42
+ throw new Error('schema');
43
+ if (value.provider !== 'codex' && value.provider !== 'claude')
44
+ throw new Error('provider');
45
+ if (typeof value.event !== 'string' || !/^[A-Za-z][A-Za-z0-9_-]{0,63}$/.test(value.event))
46
+ throw new Error('event');
47
+ if (typeof value.sessionId !== 'string' || !ID.test(value.sessionId))
48
+ throw new Error('session');
49
+ if (!Number.isSafeInteger(value.pid) || Number(value.pid) < 1 || Number(value.pid) > 0x7fffffff)
50
+ throw new Error('pid');
51
+ if (typeof value.eventId !== 'string' || !/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(value.eventId))
52
+ throw new Error('id');
53
+ if (typeof value.occurredAt !== 'string' || value.occurredAt.length !== 24
54
+ || !Number.isFinite(Date.parse(value.occurredAt)) || new Date(value.occurredAt).toISOString() !== value.occurredAt
55
+ || Math.abs(Date.now() - Date.parse(value.occurredAt)) > 60_000)
56
+ throw new Error('time');
57
+ for (const key of ['turnId', 'promptId', 'agentId']) {
58
+ if (value[key] !== undefined && (typeof value[key] !== 'string' || !ID.test(value[key])))
59
+ throw new Error('id');
60
+ }
61
+ for (const key of ['cwd', 'transcriptPath']) {
62
+ const item = value[key];
63
+ if (item !== undefined && (typeof item !== 'string' || item.length > 4096 || !path.isAbsolute(item)
64
+ || /[\x00-\x1f\x7f]/.test(item)))
65
+ throw new Error('path');
66
+ }
67
+ for (const key of ['background', 'stopHookActive', 'hasBackgroundTasks']) {
68
+ if (value[key] !== undefined && typeof value[key] !== 'boolean')
69
+ throw new Error('flag');
70
+ }
71
+ if (value.error !== undefined && (typeof value.error !== 'string' || !ERRORS.has(value.error)))
72
+ throw new Error('error');
73
+ if (value.notificationType !== undefined && (typeof value.notificationType !== 'string'
74
+ || !/^[a-z][a-z0-9_]{0,63}$/.test(value.notificationType)))
75
+ throw new Error('notification');
76
+ if (!Array.isArray(value.ancestors) || value.ancestors.length < 2 || value.ancestors.length > 64)
77
+ throw new Error('chain');
78
+ const seen = new Set();
79
+ for (const ancestor of value.ancestors) {
80
+ if (!record(ancestor) || Object.keys(ancestor).length !== 2 || !Number.isSafeInteger(ancestor.pid)
81
+ || Number(ancestor.pid) < 1 || Number(ancestor.pid) > 0x7fffffff || seen.has(Number(ancestor.pid))
82
+ || typeof ancestor.startTicks !== 'string' || !/^\d{1,20}$/.test(ancestor.startTicks))
83
+ throw new Error('chain');
84
+ seen.add(Number(ancestor.pid));
85
+ }
86
+ if (value.ancestors[0].pid !== value.pid)
87
+ throw new Error('helper');
88
+ return value;
89
+ }
90
+ async function boundedFile(file, limit, options = {}) {
91
+ const handle = await open(file, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
92
+ try {
93
+ const info = await handle.stat();
94
+ if (!info.isFile() || (options.privateFile && (info.uid !== process.getuid?.() || (info.mode & 0o777) !== 0o600)))
95
+ throw new Error('file');
96
+ const buffer = Buffer.alloc(limit + 1);
97
+ const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
98
+ if (bytesRead > limit && !options.prefix)
99
+ throw new Error('size');
100
+ return buffer.subarray(0, Math.min(bytesRead, limit)).toString('utf8');
101
+ }
102
+ finally {
103
+ await handle.close();
104
+ }
105
+ }
106
+ async function readEndpoint(hooksDir) {
107
+ let contents;
108
+ try {
109
+ contents = await boundedFile(path.join(hooksDir, 'endpoint.json'), 4096, { privateFile: true });
110
+ }
111
+ catch (error) {
112
+ if (error.code === 'ENOENT')
113
+ return null;
114
+ throw error;
115
+ }
116
+ let value;
117
+ try {
118
+ value = JSON.parse(contents);
119
+ }
120
+ catch {
121
+ throw new Error('Unsafe existing hook endpoint');
122
+ }
123
+ if (!record(value) || value.version !== 1 || typeof value.generation !== 'string' || !/^[0-9a-f]{32}$/.test(value.generation)
124
+ || typeof value.token !== 'string' || !/^[0-9a-f]{64}$/.test(value.token)
125
+ || typeof value.socketPath !== 'string' || value.socketPath !== path.join(hooksDir, `r-${value.generation}.sock`)
126
+ || Buffer.byteLength(value.socketPath) > 103)
127
+ throw new Error('Unsafe existing hook endpoint');
128
+ return value;
129
+ }
130
+ async function endpointActive(endpoint) {
131
+ let info;
132
+ try {
133
+ info = await lstat(endpoint.socketPath);
134
+ }
135
+ catch (error) {
136
+ if (error.code === 'ENOENT')
137
+ return false;
138
+ throw error;
139
+ }
140
+ if (!info.isSocket() || info.uid !== process.getuid?.() || (info.mode & 0o777) !== 0o600)
141
+ throw new Error('Unsafe existing hook socket');
142
+ return new Promise((resolve, reject) => {
143
+ // Any listener owns the endpoint. Do not send HTTP, credentials, or event data to probe it.
144
+ const socket = createConnection({ path: endpoint.socketPath });
145
+ const timer = setTimeout(() => finish(new Error('Existing hook endpoint probe timed out')), PROBE_MS);
146
+ let settled = false;
147
+ const finish = (error, active = false) => {
148
+ if (settled)
149
+ return;
150
+ settled = true;
151
+ clearTimeout(timer);
152
+ socket.destroy();
153
+ if (error)
154
+ reject(error);
155
+ else
156
+ resolve(active);
157
+ };
158
+ socket.once('connect', () => finish(null, true));
159
+ socket.once('error', (error) => {
160
+ if (error.code === 'ENOENT' || error.code === 'ECONNREFUSED')
161
+ finish(null);
162
+ else
163
+ finish(new Error('Could not verify existing hook endpoint'));
164
+ });
165
+ });
166
+ }
167
+ async function processStat(pid) {
168
+ const raw = await boundedFile(`/proc/${pid}/stat`, 4096);
169
+ const fields = raw.slice(raw.lastIndexOf(')') + 2).trim().split(/\s+/);
170
+ if (!raw.startsWith(`${pid} (`) || !/^\d+$/.test(fields[1] ?? '')
171
+ || !/^\d{1,20}$/.test(fields[19] ?? '') || fields[0] === 'Z' || fields[0] === 'X')
172
+ throw new Error('process');
173
+ return { ppid: Number(fields[1]), startTicks: fields[19] };
174
+ }
175
+ async function processProvider(pid) {
176
+ try {
177
+ const executable = (await readlink(`/proc/${pid}/exe`)).replace(/ \(deleted\)$/, '');
178
+ const binary = path.basename(executable);
179
+ if (binary === 'codex' || binary === 'claude')
180
+ return binary;
181
+ if (/\/claude\/versions\/\d+\.\d+\.\d+(?:[-+][\w.-]+)?$/.test(executable))
182
+ return 'claude';
183
+ if (binary !== 'node' && binary !== 'nodejs')
184
+ return null;
185
+ // Inspect only the entrypoint, never search prompt-bearing arguments for a provider name.
186
+ const args = (await boundedFile(`/proc/${pid}/cmdline`, 16384, { prefix: true })).split('\0');
187
+ const script = args[1] ?? '';
188
+ if (path.basename(script) === 'codex' || /\/@openai\/codex\/(?:bin\/)?codex\.js$/.test(script))
189
+ return 'codex';
190
+ if (path.basename(script) === 'claude' || /\/@anthropic-ai\/claude-code\/cli\.js$/.test(script))
191
+ return 'claude';
192
+ return null;
193
+ }
194
+ catch {
195
+ return null;
196
+ }
197
+ }
198
+ async function proveProcess(event, hooksDir) {
199
+ const owner = await lstat(`/proc/${event.pid}`);
200
+ if (owner.uid !== process.getuid?.())
201
+ throw new Error('owner');
202
+ const executable = path.basename(await readlink(`/proc/${event.pid}/exe`));
203
+ if (executable !== 'node' && executable !== 'nodejs')
204
+ throw new Error('helper');
205
+ const args = (await boundedFile(`/proc/${event.pid}/cmdline`, 16384, { prefix: true })).split('\0');
206
+ if (args[1] !== path.join(hooksDir, 'forward.cjs'))
207
+ throw new Error('helper');
208
+ const providerIndex = args.indexOf('--provider', 2);
209
+ const endpointIndex = args.indexOf('--endpoint', 2);
210
+ if (providerIndex < 2 || args[providerIndex + 1] !== event.provider || endpointIndex < 2
211
+ || args[endpointIndex + 1] !== path.join(hooksDir, 'endpoint.json'))
212
+ throw new Error('arguments');
213
+ let providerFound = false;
214
+ for (let index = 0; index < event.ancestors.length; index++) {
215
+ const ancestor = event.ancestors[index];
216
+ const actual = await processStat(ancestor.pid);
217
+ if (actual.startTicks !== ancestor.startTicks || actual.ppid !== (event.ancestors[index + 1]?.pid ?? 0))
218
+ throw new Error('ancestry');
219
+ if (index > 0 && !providerFound) {
220
+ const provider = await processProvider(ancestor.pid);
221
+ if (provider && provider !== event.provider)
222
+ throw new Error('provider');
223
+ providerFound = provider === event.provider;
224
+ }
225
+ }
226
+ if (!providerFound)
227
+ throw new Error('provider');
228
+ // Recheck after the asynchronous executable lookups to catch exit/reparent/PID reuse.
229
+ for (let index = 0; index < event.ancestors.length; index++) {
230
+ const ancestor = event.ancestors[index];
231
+ const actual = await processStat(ancestor.pid);
232
+ if (actual.startTicks !== ancestor.startTicks || actual.ppid !== (event.ancestors[index + 1]?.pid ?? 0))
233
+ throw new Error('ancestry');
234
+ }
235
+ }
236
+ /** Opt-in only: construction does not create files, listen, or install provider hooks. */
237
+ export class HookReceiver {
238
+ options;
239
+ server;
240
+ endpoint;
241
+ hooksDir = '';
242
+ sockets = new Set();
243
+ queue = [];
244
+ validatingTool = 0;
245
+ validatingPriority = 0;
246
+ reading = 0;
247
+ worker;
248
+ lifecycle = Promise.resolve();
249
+ noisyDiagnosticAt = new Map();
250
+ constructor(options) {
251
+ this.options = options;
252
+ }
253
+ start() {
254
+ const operation = this.lifecycle.then(() => this.startInternal());
255
+ this.lifecycle = operation.catch(() => undefined);
256
+ return operation;
257
+ }
258
+ stop() {
259
+ const operation = this.lifecycle.then(() => this.stopInternal());
260
+ this.lifecycle = operation.catch(() => undefined);
261
+ return operation;
262
+ }
263
+ diagnostic(code) {
264
+ if (code === 'rejected' || code === 'overloaded') {
265
+ const now = performance.now();
266
+ const previous = this.noisyDiagnosticAt.get(code);
267
+ if (previous !== undefined && now - previous < DIAGNOSTIC_MS)
268
+ return;
269
+ this.noisyDiagnosticAt.set(code, now);
270
+ }
271
+ try {
272
+ this.options.onDiagnostic?.({ code });
273
+ }
274
+ catch { /* Diagnostics cannot interrupt providers or shutdown. */ }
275
+ }
276
+ async publication(work) {
277
+ const lock = path.join(this.hooksDir, '.endpoint-publication-lock');
278
+ let guard;
279
+ let releaseGate;
280
+ for (let attempt = 0;; attempt++) {
281
+ try {
282
+ guard = await acquireVerifiedLock(lock, this.options.procRoot, this.options.machineIdPath);
283
+ releaseGate = await acquirePublicationGate(this.hooksDir, guard.identity, this.options.procRoot);
284
+ break;
285
+ }
286
+ catch (error) {
287
+ if (guard) {
288
+ await guard.release();
289
+ guard = undefined;
290
+ }
291
+ const retryable = error instanceof VerifiedLockError && error.retryable;
292
+ if (!retryable || attempt >= 20) {
293
+ this.diagnostic(retryable ? 'publication_contended' : 'publication_unavailable');
294
+ throw error;
295
+ }
296
+ await new Promise(resolve => setTimeout(resolve, 10));
297
+ }
298
+ }
299
+ try {
300
+ return await work();
301
+ }
302
+ finally {
303
+ try {
304
+ await releaseGate();
305
+ }
306
+ finally {
307
+ await guard.release();
308
+ }
309
+ }
310
+ }
311
+ async startInternal() {
312
+ if (this.server)
313
+ return;
314
+ if (this.worker)
315
+ throw new Error('Previous hook handler has not finished');
316
+ if (process.platform !== 'linux' || !process.getuid)
317
+ throw new Error('Hooks require Linux procfs and Unix sockets');
318
+ await mkdir(this.options.stateDir, { recursive: true, mode: 0o700 });
319
+ this.hooksDir = path.join(await realpath(this.options.stateDir), 'hooks');
320
+ await mkdir(this.hooksDir, { mode: 0o700 }).catch(error => { if (error.code !== 'EEXIST')
321
+ throw error; });
322
+ const directory = await lstat(this.hooksDir);
323
+ if (!directory.isDirectory() || directory.uid !== process.getuid())
324
+ throw new Error('Unsafe hooks directory');
325
+ await chmod(this.hooksDir, 0o700);
326
+ const generation = randomBytes(16).toString('hex');
327
+ const endpoint = { version: 1, generation, token: randomBytes(32).toString('hex'),
328
+ socketPath: path.join(this.hooksDir, `r-${generation}.sock`) };
329
+ if (Buffer.byteLength(endpoint.socketPath) > 103)
330
+ throw new Error('Hook socket path is too long');
331
+ const server = createServer({ maxHeaderSize: 4096, requestTimeout: REQUEST_MS, headersTimeout: REQUEST_MS }, (request, response) => { void this.receive(request, response, endpoint); });
332
+ server.maxHeadersCount = 16;
333
+ server.maxRequestsPerSocket = 1;
334
+ server.on('connection', socket => {
335
+ if (this.sockets.size >= MAX_CONNECTIONS) {
336
+ socket.destroy();
337
+ return;
338
+ }
339
+ this.sockets.add(socket);
340
+ const timer = setTimeout(() => socket.destroy(), REQUEST_MS);
341
+ timer.unref();
342
+ socket.on('error', () => { });
343
+ socket.once('close', () => { clearTimeout(timer); this.sockets.delete(socket); });
344
+ });
345
+ server.on('clientError', (_error, socket) => socket.destroy());
346
+ this.server = server;
347
+ this.endpoint = endpoint;
348
+ const temporary = path.join(this.hooksDir, `.endpoint-${generation}.tmp`);
349
+ try {
350
+ await new Promise((resolve, reject) => {
351
+ server.once('error', reject);
352
+ server.listen(endpoint.socketPath, () => { server.removeListener('error', reject); resolve(); });
353
+ });
354
+ server.on('error', () => this.diagnostic('rejected'));
355
+ await chmod(endpoint.socketPath, 0o600);
356
+ await this.publication(async () => {
357
+ const existing = await readEndpoint(this.hooksDir);
358
+ if (existing && await endpointActive(existing))
359
+ throw new Error('Hook receiver is already active for this state directory');
360
+ const file = await open(temporary, 'wx', 0o600);
361
+ try {
362
+ await file.chmod(0o600);
363
+ await file.writeFile(JSON.stringify(endpoint));
364
+ await file.sync();
365
+ }
366
+ finally {
367
+ await file.close();
368
+ }
369
+ await rename(temporary, path.join(this.hooksDir, 'endpoint.json'));
370
+ await syncDirectory(this.hooksDir);
371
+ });
372
+ }
373
+ catch (error) {
374
+ await unlink(temporary).catch(() => undefined);
375
+ await this.stopInternal();
376
+ throw error;
377
+ }
378
+ }
379
+ async receive(request, response, endpoint) {
380
+ const reply = (status) => {
381
+ response.writeHead(status, { 'content-type': 'application/json', connection: 'close' });
382
+ response.end('{}');
383
+ request.resume();
384
+ };
385
+ if (this.endpoint !== endpoint || request.method !== 'POST' || request.url !== '/hook') {
386
+ reply(404);
387
+ return;
388
+ }
389
+ const expected = Buffer.from(`Bearer ${endpoint.token}`);
390
+ const supplied = Buffer.from(request.headers.authorization ?? '');
391
+ const padded = Buffer.alloc(expected.length);
392
+ supplied.copy(padded, 0, 0, expected.length);
393
+ if (!timingSafeEqual(expected, padded) || supplied.length !== expected.length) {
394
+ reply(401);
395
+ return;
396
+ }
397
+ if (request.headers['content-type'] !== 'application/json' || request.headers['content-encoding']) {
398
+ reply(415);
399
+ return;
400
+ }
401
+ if (Number(request.headers['content-length'] ?? 0) > MAX_BODY) {
402
+ reply(413);
403
+ return;
404
+ }
405
+ // The event type is unknown until validated: refuse early only when even
406
+ // a priority event could not be admitted (no evictable tool events).
407
+ const proving = this.validatingTool + this.validatingPriority;
408
+ if (this.reading >= MAX_READING || (this.queue.length + proving + (this.worker ? 1 : 0) >= MAX_PRIORITY_PENDING
409
+ && !this.queue.some(queued => isLowPriorityLifecycleEvent(queued)))) {
410
+ this.diagnostic('overloaded');
411
+ reply(503);
412
+ return;
413
+ }
414
+ // Body reads are bounded by MAX_CONNECTIONS x MAX_BODY; the costly proof is
415
+ // gated per event class once the type is known.
416
+ let slot;
417
+ let readingBody = true;
418
+ this.reading++;
419
+ try {
420
+ let bytes = 0;
421
+ const chunks = [];
422
+ for await (const chunk of request) {
423
+ bytes += chunk.length;
424
+ if (bytes > MAX_BODY) {
425
+ reply(413);
426
+ return;
427
+ }
428
+ chunks.push(chunk);
429
+ }
430
+ this.reading--;
431
+ readingBody = false;
432
+ const event = validate(JSON.parse(Buffer.concat(chunks, bytes).toString('utf8')));
433
+ if (isLowPriorityLifecycleEvent(event)) {
434
+ if (this.validatingTool >= MAX_VALIDATING) {
435
+ this.diagnostic('overloaded');
436
+ reply(503);
437
+ return;
438
+ }
439
+ slot = 'tool';
440
+ this.validatingTool++;
441
+ }
442
+ else {
443
+ if (this.validatingPriority >= MAX_PRIORITY_VALIDATING) {
444
+ this.diagnostic('overloaded');
445
+ reply(503);
446
+ return;
447
+ }
448
+ slot = 'priority';
449
+ this.validatingPriority++;
450
+ }
451
+ await proveProcess(event, this.hooksDir);
452
+ if (this.endpoint !== endpoint || response.destroyed)
453
+ return;
454
+ if (!this.admit(event)) {
455
+ this.diagnostic('overloaded');
456
+ reply(503);
457
+ return;
458
+ }
459
+ this.queue.push(event);
460
+ reply(202);
461
+ this.pump();
462
+ }
463
+ catch {
464
+ this.diagnostic('rejected');
465
+ if (!response.destroyed && !response.headersSent)
466
+ reply(400);
467
+ }
468
+ finally {
469
+ if (readingBody)
470
+ this.reading--;
471
+ if (slot === 'tool')
472
+ this.validatingTool--;
473
+ else if (slot === 'priority')
474
+ this.validatingPriority--;
475
+ }
476
+ }
477
+ // Bounded admission after validation, when the event type is known.
478
+ admit(event) {
479
+ const pending = this.queue.length + (this.worker ? 1 : 0);
480
+ if (isLowPriorityLifecycleEvent(event)) {
481
+ // A newer tool event for the same session supersedes a queued one;
482
+ // both only mark the session working.
483
+ const index = this.queue.findIndex(queued => isLowPriorityLifecycleEvent(queued)
484
+ && queued.provider === event.provider && queued.sessionId === event.sessionId);
485
+ if (index >= 0) {
486
+ this.queue.splice(index, 1);
487
+ return true;
488
+ }
489
+ return pending < MAX_PENDING;
490
+ }
491
+ if (pending < MAX_PRIORITY_PENDING)
492
+ return true;
493
+ const index = this.queue.findIndex(queued => isLowPriorityLifecycleEvent(queued));
494
+ if (index < 0)
495
+ return false;
496
+ this.queue.splice(index, 1);
497
+ this.diagnostic('overloaded');
498
+ return true;
499
+ }
500
+ pump() {
501
+ if (this.worker || !this.endpoint || !this.queue.length)
502
+ return;
503
+ const event = this.queue.shift();
504
+ // One callback at a time; receipt acknowledges ingestion, not reducer completion.
505
+ this.worker = Promise.resolve().then(() => this.options.onEvent(event)).catch(() => {
506
+ this.diagnostic('handler_failed');
507
+ }).finally(() => { this.worker = undefined; this.pump(); });
508
+ }
509
+ async stopInternal() {
510
+ const server = this.server;
511
+ const endpoint = this.endpoint;
512
+ this.server = undefined;
513
+ this.endpoint = undefined;
514
+ if (this.queue.length)
515
+ this.diagnostic('shutdown_dropped');
516
+ this.queue = [];
517
+ if (server) {
518
+ const closed = new Promise(resolve => server.close(() => resolve()));
519
+ for (const socket of this.sockets)
520
+ socket.destroy();
521
+ await closed;
522
+ }
523
+ if (endpoint) {
524
+ try {
525
+ await this.publication(async () => {
526
+ const file = path.join(this.hooksDir, 'endpoint.json');
527
+ const current = await readEndpoint(this.hooksDir);
528
+ if (!current)
529
+ return;
530
+ if (current.generation === endpoint.generation && current.token === endpoint.token && current.socketPath === endpoint.socketPath) {
531
+ await unlink(file);
532
+ await syncDirectory(this.hooksDir);
533
+ }
534
+ });
535
+ }
536
+ catch {
537
+ this.diagnostic('cleanup_failed');
538
+ }
539
+ }
540
+ if (this.worker) {
541
+ let timer;
542
+ await Promise.race([this.worker, new Promise(resolve => {
543
+ timer = setTimeout(() => { this.diagnostic('shutdown_timeout'); resolve(); }, STOP_MS);
544
+ })]);
545
+ clearTimeout(timer);
546
+ }
547
+ }
548
+ }
549
+ //# sourceMappingURL=hookReceiver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hookReceiver.js","sourceRoot":"","sources":["../../../src/server/hooks/hookReceiver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,EAAE,YAAY,EAA0D,MAAM,WAAW,CAAC;AACjG,OAAO,EAAE,gBAAgB,EAAe,MAAM,UAAU,CAAC;AACzD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAA0B,MAAM,mBAAmB,CAAC;AACnG,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AA6C7D,MAAM,QAAQ,GAAG,EAAE,GAAG,IAAI,CAAC;AAC3B,4EAA4E;AAC5E,sEAAsE;AACtE,6EAA6E;AAC7E,kDAAkD;AAClD,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAChC,MAAM,eAAe,GAAG,EAAE,CAAC;AAC3B,+EAA+E;AAC/E,2DAA2D;AAC3D,MAAM,cAAc,GAAG,CAAC,CAAC;AACzB,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAClC,2EAA2E;AAC3E,uEAAuE;AACvE,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,UAAU,GAAG,GAAG,CAAC;AACvB,MAAM,OAAO,GAAG,GAAG,CAAC;AACpB,MAAM,QAAQ,GAAG,GAAG,CAAC;AACrB,MAAM,aAAa,GAAG,IAAI,CAAC;AAC3B,MAAM,EAAE,GAAG,qCAAqC,CAAC;AACjD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,sBAAsB,EAAE,kBAAkB,EAAE,WAAW,EAAE,kBAAkB;IACjG,cAAc,EAAE,SAAS,EAAE,mBAAmB,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY;IACzG,uBAAuB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB;IACvG,iBAAiB,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,SAAS,CAAC,CAAC,CAAC;AAChF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU;IACnG,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC,CAAC;AAE9I,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;IAChG,IAAI,KAAK,CAAC,QAAQ,KAAK,OAAO,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;IAC3F,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,+BAA+B,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IACpH,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;IACjG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;IACxH,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,uEAAuE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7J,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,KAAK,EAAE;WACrE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,UAAU;WAC/G,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3F,KAAK,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,CAAC;QACpD,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,SAAS,IAAI,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,QAAQ,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAW,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5H,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,gBAAgB,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;eAC9F,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9D,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,CAAC,EAAE,CAAC;QACzE,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3F,CAAC;IACD,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IACzH,IAAI,KAAK,CAAC,gBAAgB,KAAK,SAAS,IAAI,CAAC,OAAO,KAAK,CAAC,gBAAgB,KAAK,QAAQ;WAClF,CAAC,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;IAC9F,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3H,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC;eAC7F,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,UAAU,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;eAC/F,OAAO,QAAQ,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;QAClH,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;IACpE,OAAO,KAA6B,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,KAAa,EAAE,UAAuD,EAAE;IAC/G,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IAClG,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,KAAK,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;QAC3I,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QACvC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACrE,IAAI,SAAS,GAAG,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;QAClE,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACzE,CAAC;YAAS,CAAC;QAAC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IAAC,CAAC;AACrC,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,QAAgB;IAC1C,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QAAC,QAAQ,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IAAC,CAAC;IACxG,OAAO,KAAK,EAAE,CAAC;QAAC,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAAC,MAAM,KAAK,CAAC;IAAC,CAAC;IACnG,IAAI,KAAc,CAAC;IACnB,IAAI,CAAC;QAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAAC,CAAC;IACjG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;WACxH,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;WACtE,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,KAAK,CAAC,UAAU,OAAO,CAAC;WAC9G,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACjG,OAAO,KAAgC,CAAC;AAC1C,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,QAAsB;IAClD,IAAI,IAAI,CAAC;IACT,IAAI,CAAC;QAAC,IAAI,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAAC,CAAC;IAChD,OAAO,KAAK,EAAE,CAAC;QAAC,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAAC,MAAM,KAAK,CAAC;IAAC,CAAC;IACpG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,GAAG,KAAK,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACzI,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,4FAA4F;QAC5F,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QAC/D,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QACtG,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,MAAM,MAAM,GAAG,CAAC,KAAmB,EAAE,MAAM,GAAG,KAAK,EAAE,EAAE;YACrD,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,KAAK;gBAAE,MAAM,CAAC,KAAK,CAAC,CAAC;;gBAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAA4B,EAAE,EAAE;YACpD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;gBAAE,MAAM,CAAC,IAAI,CAAC,CAAC;;gBACtE,MAAM,CAAC,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,GAAW;IACpC,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,SAAS,GAAG,OAAO,EAAE,IAAI,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACvE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;WAC5D,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;IAChH,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,CAAE,EAAE,CAAC;AAC9D,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,GAAW;IACxC,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,CAAC,MAAM,QAAQ,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QACrF,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACzC,IAAI,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,QAAQ;YAAE,OAAO,MAAM,CAAC;QAC7D,IAAI,oDAAoD,CAAC,IAAI,CAAC,UAAU,CAAC;YAAE,OAAO,QAAQ,CAAC;QAC3F,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC1D,0FAA0F;QAC1F,MAAM,IAAI,GAAG,CAAC,MAAM,WAAW,CAAC,SAAS,GAAG,UAAU,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9F,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,OAAO,IAAI,wCAAwC,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,OAAO,OAAO,CAAC;QAC/G,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,QAAQ,IAAI,wCAAwC,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,OAAO,QAAQ,CAAC;QACjH,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;AAC1B,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,KAAgB,EAAE,QAAgB;IAC5D,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,SAAS,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IAChD,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,CAAC,MAAM,EAAE,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,QAAQ,CAAC,SAAS,KAAK,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;IAC3E,IAAI,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;IAChF,MAAM,IAAI,GAAG,CAAC,MAAM,WAAW,CAAC,SAAS,KAAK,CAAC,GAAG,UAAU,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACpG,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9E,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IACpD,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IACpD,IAAI,aAAa,GAAG,CAAC,IAAI,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,QAAQ,IAAI,aAAa,GAAG,CAAC;WACnF,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;IACpG,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAC5D,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAE,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;QACrI,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YACrD,IAAI,QAAQ,IAAI,QAAQ,KAAK,KAAK,CAAC,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;YACzE,aAAa,GAAG,QAAQ,KAAK,KAAK,CAAC,QAAQ,CAAC;QAC9C,CAAC;IACH,CAAC;IACD,IAAI,CAAC,aAAa;QAAE,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;IAChD,sFAAsF;IACtF,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAC5D,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAE,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;IACvI,CAAC;AACH,CAAC;AAED,0FAA0F;AAC1F,MAAM,OAAO,YAAY;IAaM;IAZrB,MAAM,CAAqB;IAC3B,QAAQ,CAA2B;IACnC,QAAQ,GAAG,EAAE,CAAC;IACd,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAC5B,KAAK,GAAgB,EAAE,CAAC;IACxB,cAAc,GAAG,CAAC,CAAC;IACnB,kBAAkB,GAAG,CAAC,CAAC;IACvB,OAAO,GAAG,CAAC,CAAC;IACZ,MAAM,CAA4B;IAClC,SAAS,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7C,iBAAiB,GAAG,IAAI,GAAG,EAAkC,CAAC;IAEtE,YAA6B,OAA4B;QAA5B,YAAO,GAAP,OAAO,CAAqB;IAAG,CAAC;IAE7D,KAAK;QACH,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;QAClE,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAClD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI;QACF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QACjE,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAClD,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,UAAU,CAAC,IAA4B;QAC7C,IAAI,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;YACjD,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClD,IAAI,QAAQ,KAAK,SAAS,IAAI,GAAG,GAAG,QAAQ,GAAG,aAAa;gBAAE,OAAO;YACrE,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,CAAC;YAAC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,yDAAyD,CAAC,CAAC;IACpH,CAAC;IAEO,KAAK,CAAC,WAAW,CAAI,IAAsB;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,4BAA4B,CAAC,CAAC;QACpE,IAAI,KAAoC,CAAC;QACzC,IAAI,WAA8C,CAAC;QACnD,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,KAAK,GAAG,MAAM,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;gBAC3F,WAAW,GAAG,MAAM,sBAAsB,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACjG,MAAM;YACR,CAAC;YACD,OAAO,KAAK,EAAE,CAAC;gBACb,IAAI,KAAK,EAAE,CAAC;oBAAC,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;oBAAC,KAAK,GAAG,SAAS,CAAC;gBAAC,CAAC;gBACxD,MAAM,SAAS,GAAG,KAAK,YAAY,iBAAiB,IAAI,KAAK,CAAC,SAAS,CAAC;gBACxE,IAAI,CAAC,SAAS,IAAI,OAAO,IAAI,EAAE,EAAE,CAAC;oBAChC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC;oBACjF,MAAM,KAAK,CAAC;gBACd,CAAC;gBACD,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QACD,IAAI,CAAC;YAAC,OAAO,MAAM,IAAI,EAAE,CAAC;QAAC,CAAC;gBACpB,CAAC;YACP,IAAI,CAAC;gBAAC,MAAM,WAAY,EAAE,CAAC;YAAC,CAAC;oBAAS,CAAC;gBAAC,MAAM,KAAM,CAAC,OAAO,EAAE,CAAC;YAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC3E,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACpH,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;QAC1E,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1G,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7C,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,SAAS,CAAC,GAAG,KAAK,OAAO,CAAC,MAAM,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC9G,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAClC,MAAM,UAAU,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAiB,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;YAC7F,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,UAAU,OAAO,CAAC,EAAE,CAAC;QACjE,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAClG,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,EACzG,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9E,MAAM,CAAC,eAAe,GAAG,EAAE,CAAC;QAC5B,MAAM,CAAC,oBAAoB,GAAG,CAAC,CAAC;QAChC,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC,EAAE;YAC/B,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,eAAe,EAAE,CAAC;gBAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAAC,OAAO;YAAC,CAAC;YACvE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACzB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;YAC7D,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpF,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,UAAU,MAAM,CAAC,CAAC;QAC1E,IAAI,CAAC;YACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAC7B,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACnG,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;YACtD,MAAM,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YACxC,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE;gBAChC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACnD,IAAI,QAAQ,IAAI,MAAM,cAAc,CAAC,QAAQ,CAAC;oBAAE,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;gBAC5H,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;gBAChD,IAAI,CAAC;oBAAC,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;oBAAC,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;oBAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;gBAAC,CAAC;wBAAS,CAAC;oBAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;gBAAC,CAAC;gBACnI,MAAM,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC;gBACnE,MAAM,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrC,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YAC/C,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;YAC1B,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,OAAwB,EAAE,QAAwB,EAAE,QAAsB;QAC9F,MAAM,KAAK,GAAG,CAAC,MAAc,EAAE,EAAE;YAC/B,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;YACxF,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACnB,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,CAAC,CAAC;QACF,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QAC/G,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;QACzD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC7C,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC7C,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;YAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QACtG,IAAI,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QAC1H,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,GAAG,QAAQ,EAAE,CAAC;YAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QACtF,yEAAyE;QACzE,qEAAqE;QACrE,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,kBAAkB,CAAC;QAC9D,IAAI,IAAI,CAAC,OAAO,IAAI,WAAW,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,oBAAoB;eAC1G,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,2BAA2B,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAAC,OAAO;QACpD,CAAC;QACD,4EAA4E;QAC5E,gDAAgD;QAChD,IAAI,IAAqC,CAAC;QAC1C,IAAI,WAAW,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC;YACH,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAClC,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC;gBACtB,IAAI,KAAK,GAAG,QAAQ,EAAE,CAAC;oBAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBAAC,OAAO;gBAAC,CAAC;gBAC7C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;YACD,IAAI,CAAC,OAAO,EAAE,CAAC;YAAC,WAAW,GAAG,KAAK,CAAC;YACpC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAClF,IAAI,2BAA2B,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvC,IAAI,IAAI,CAAC,cAAc,IAAI,cAAc,EAAE,CAAC;oBAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;oBAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBAAC,OAAO;gBAAC,CAAC;gBACjG,IAAI,GAAG,MAAM,CAAC;gBAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACvC,CAAC;iBAAM,CAAC;gBACN,IAAI,IAAI,CAAC,kBAAkB,IAAI,uBAAuB,EAAE,CAAC;oBAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;oBAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBAAC,OAAO;gBAAC,CAAC;gBAC9G,IAAI,GAAG,UAAU,CAAC;gBAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC/C,CAAC;YACD,MAAM,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzC,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,SAAS;gBAAE,OAAO;YAC7D,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;gBAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAAC,OAAO;YAAC,CAAC;YAC9E,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,KAAK,CAAC,GAAG,CAAC,CAAC;YACX,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YAC5B,IAAI,CAAC,QAAQ,CAAC,SAAS,IAAI,CAAC,QAAQ,CAAC,WAAW;gBAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/D,CAAC;gBAAS,CAAC;YACT,IAAI,WAAW;gBAAE,IAAI,CAAC,OAAO,EAAE,CAAC;YAChC,IAAI,IAAI,KAAK,MAAM;gBAAE,IAAI,CAAC,cAAc,EAAE,CAAC;iBACtC,IAAI,IAAI,KAAK,UAAU;gBAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,oEAAoE;IAC5D,KAAK,CAAC,KAAgB;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,IAAI,2BAA2B,CAAC,KAAK,CAAC,EAAE,CAAC;YACvC,mEAAmE;YACnE,sCAAsC;YACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,2BAA2B,CAAC,MAAM,CAAC;mBAC3E,MAAM,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,IAAI,MAAM,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;YACjF,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;gBAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBAAC,OAAO,IAAI,CAAC;YAAC,CAAC;YAC7D,OAAO,OAAO,GAAG,WAAW,CAAC;QAC/B,CAAC;QACD,IAAI,OAAO,GAAG,oBAAoB;YAAE,OAAO,IAAI,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,2BAA2B,CAAC,MAAM,CAAC,CAAC,CAAC;QAClF,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,IAAI;QACV,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO;QAChE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAG,CAAC;QAClC,kFAAkF;QAClF,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACjF,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC;IAEO,KAAK,CAAC,YAAY;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC1B,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;QAC3D,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,MAAM,GAAG,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAC3E,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO;gBAAE,MAAM,CAAC,OAAO,EAAE,CAAC;YACpD,MAAM,MAAM,CAAC;QACf,CAAC;QACD,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE;oBAChC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;oBACvD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAClD,IAAI,CAAC,OAAO;wBAAE,OAAO;oBACrB,IAAI,OAAO,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,IAAI,OAAO,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC;wBACjI,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;wBACnB,MAAM,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBACrC,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBAAC,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;YAAC,CAAC;QAChD,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,KAAiC,CAAC;YACtC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE;oBAC3D,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;gBACzF,CAAC,CAAC,CAAC,CAAC,CAAC;YACL,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,40 @@
1
+ import type { TerminalSummary } from '../../shared/types.js';
2
+ import type { AgentTranscriptCompletion } from '../terminal/agentTranscriptStatus.js';
3
+ export interface LifecycleEvent {
4
+ provider: 'codex' | 'claude';
5
+ event: string;
6
+ sessionId: string;
7
+ eventId: string;
8
+ occurredAt: string;
9
+ turnId?: string;
10
+ promptId?: string;
11
+ agentId?: string;
12
+ background?: boolean;
13
+ notificationType?: string;
14
+ hasBackgroundTasks?: boolean;
15
+ }
16
+ type Status = NonNullable<TerminalSummary['agentStatus']>;
17
+ export interface LifecycleState {
18
+ status: Status;
19
+ turn: string | null;
20
+ segment: number;
21
+ lastEventAt: number;
22
+ seen: string[];
23
+ finishedTurns: string[];
24
+ stopPending: boolean;
25
+ pendingWork?: boolean;
26
+ recovery?: {
27
+ turn: string | null;
28
+ after: number;
29
+ activeTurn: boolean;
30
+ failure?: {
31
+ eventId: string;
32
+ occurredAt: string;
33
+ };
34
+ };
35
+ }
36
+ export declare function isLowPriorityLifecycleEvent(event: Pick<LifecycleEvent, 'event' | 'agentId' | 'background'>): boolean;
37
+ export declare function reduceLifecycle(previous: LifecycleState | undefined, event: LifecycleEvent): LifecycleState | undefined;
38
+ /** Confirm from a post-turn marker, not from assistant text or inactivity. */
39
+ export declare function reconcileLifecycle(previous: LifecycleState, completion: AgentTranscriptCompletion | undefined): LifecycleState;
40
+ export {};