toc-ocra 0.2.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 (101) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +70 -0
  3. package/assets/icon.svg +1 -0
  4. package/dist/plugin/renderer.css +2 -0
  5. package/dist/plugin/renderer.css.map +7 -0
  6. package/dist/plugin/renderer.js +2 -0
  7. package/dist/plugin/renderer.js.map +7 -0
  8. package/dist/src/config.d.ts +66 -0
  9. package/dist/src/config.js +173 -0
  10. package/dist/src/config.js.map +1 -0
  11. package/dist/src/control/pairing.d.ts +44 -0
  12. package/dist/src/control/pairing.js +99 -0
  13. package/dist/src/control/pairing.js.map +1 -0
  14. package/dist/src/exec/script-runner.d.ts +9 -0
  15. package/dist/src/exec/script-runner.js +110 -0
  16. package/dist/src/exec/script-runner.js.map +1 -0
  17. package/dist/src/health/server.d.ts +74 -0
  18. package/dist/src/health/server.js +248 -0
  19. package/dist/src/health/server.js.map +1 -0
  20. package/dist/src/index.d.ts +2 -0
  21. package/dist/src/index.js +173 -0
  22. package/dist/src/index.js.map +1 -0
  23. package/dist/src/logging/diagnostic-log.d.ts +16 -0
  24. package/dist/src/logging/diagnostic-log.js +128 -0
  25. package/dist/src/logging/diagnostic-log.js.map +1 -0
  26. package/dist/src/providers/cli/claude.d.ts +2 -0
  27. package/dist/src/providers/cli/claude.js +48 -0
  28. package/dist/src/providers/cli/claude.js.map +1 -0
  29. package/dist/src/providers/cli/codex.d.ts +2 -0
  30. package/dist/src/providers/cli/codex.js +67 -0
  31. package/dist/src/providers/cli/codex.js.map +1 -0
  32. package/dist/src/providers/cli/gemini.d.ts +2 -0
  33. package/dist/src/providers/cli/gemini.js +30 -0
  34. package/dist/src/providers/cli/gemini.js.map +1 -0
  35. package/dist/src/providers/cli/grok.d.ts +2 -0
  36. package/dist/src/providers/cli/grok.js +29 -0
  37. package/dist/src/providers/cli/grok.js.map +1 -0
  38. package/dist/src/providers/cli/opencode.d.ts +2 -0
  39. package/dist/src/providers/cli/opencode.js +29 -0
  40. package/dist/src/providers/cli/opencode.js.map +1 -0
  41. package/dist/src/providers/detection.d.ts +11 -0
  42. package/dist/src/providers/detection.js +96 -0
  43. package/dist/src/providers/detection.js.map +1 -0
  44. package/dist/src/providers/model-catalog-collector.d.ts +22 -0
  45. package/dist/src/providers/model-catalog-collector.js +66 -0
  46. package/dist/src/providers/model-catalog-collector.js.map +1 -0
  47. package/dist/src/providers/model-catalog.d.ts +45 -0
  48. package/dist/src/providers/model-catalog.js +382 -0
  49. package/dist/src/providers/model-catalog.js.map +1 -0
  50. package/dist/src/providers/provider.d.ts +49 -0
  51. package/dist/src/providers/provider.js +63 -0
  52. package/dist/src/providers/provider.js.map +1 -0
  53. package/dist/src/providers/registry.d.ts +31 -0
  54. package/dist/src/providers/registry.js +60 -0
  55. package/dist/src/providers/registry.js.map +1 -0
  56. package/dist/src/runs/orphan-registry.d.ts +24 -0
  57. package/dist/src/runs/orphan-registry.js +63 -0
  58. package/dist/src/runs/orphan-registry.js.map +1 -0
  59. package/dist/src/runs/process-tree.d.ts +21 -0
  60. package/dist/src/runs/process-tree.js +95 -0
  61. package/dist/src/runs/process-tree.js.map +1 -0
  62. package/dist/src/runs/run-supervisor.d.ts +63 -0
  63. package/dist/src/runs/run-supervisor.js +285 -0
  64. package/dist/src/runs/run-supervisor.js.map +1 -0
  65. package/dist/src/runtime/agent-runtime.d.ts +68 -0
  66. package/dist/src/runtime/agent-runtime.js +340 -0
  67. package/dist/src/runtime/agent-runtime.js.map +1 -0
  68. package/dist/src/runtime/agent-service.d.ts +33 -0
  69. package/dist/src/runtime/agent-service.js +181 -0
  70. package/dist/src/runtime/agent-service.js.map +1 -0
  71. package/dist/src/runtime/cli/hydrate-shell-path.d.ts +33 -0
  72. package/dist/src/runtime/cli/hydrate-shell-path.js +173 -0
  73. package/dist/src/runtime/cli/hydrate-shell-path.js.map +1 -0
  74. package/dist/src/session/terminal-line-sanitizer.d.ts +7 -0
  75. package/dist/src/session/terminal-line-sanitizer.js +21 -0
  76. package/dist/src/session/terminal-line-sanitizer.js.map +1 -0
  77. package/dist/src/session/terminal-tail-buffer.d.ts +70 -0
  78. package/dist/src/session/terminal-tail-buffer.js +149 -0
  79. package/dist/src/session/terminal-tail-buffer.js.map +1 -0
  80. package/dist/src/shared/cli-detection-types.d.ts +19 -0
  81. package/dist/src/shared/cli-detection-types.js +2 -0
  82. package/dist/src/shared/cli-detection-types.js.map +1 -0
  83. package/dist/src/shared/node-cli-command-resolution.d.ts +19 -0
  84. package/dist/src/shared/node-cli-command-resolution.js +173 -0
  85. package/dist/src/shared/node-cli-command-resolution.js.map +1 -0
  86. package/dist/src/transport/gateway-client.d.ts +38 -0
  87. package/dist/src/transport/gateway-client.js +73 -0
  88. package/dist/src/transport/gateway-client.js.map +1 -0
  89. package/dist/src/types/protocol.d.ts +172 -0
  90. package/dist/src/types/protocol.js +55 -0
  91. package/dist/src/types/protocol.js.map +1 -0
  92. package/dist/src/workspace/directory-browser.d.ts +17 -0
  93. package/dist/src/workspace/directory-browser.js +47 -0
  94. package/dist/src/workspace/directory-browser.js.map +1 -0
  95. package/dist/src/workspace/workspace-manager.d.ts +41 -0
  96. package/dist/src/workspace/workspace-manager.js +436 -0
  97. package/dist/src/workspace/workspace-manager.js.map +1 -0
  98. package/locales/en.json +66 -0
  99. package/locales/zh-CN.json +66 -0
  100. package/package.json +90 -0
  101. package/scripts/service.mjs +174 -0
@@ -0,0 +1,340 @@
1
+ import { join } from 'node:path';
2
+ import { executeScript } from '../exec/script-runner.js';
3
+ import { createDiagnosticLogger } from '../logging/diagnostic-log.js';
4
+ import { cliDetection } from '../providers/detection.js';
5
+ import { ModelCatalogCollector } from '../providers/model-catalog-collector.js';
6
+ import { OrphanRegistry } from '../runs/orphan-registry.js';
7
+ import { RunSupervisor } from '../runs/run-supervisor.js';
8
+ import { GatewayClient, GatewayError } from '../transport/gateway-client.js';
9
+ import { listDirectory } from '../workspace/directory-browser.js';
10
+ import { WorkspaceManager } from '../workspace/workspace-manager.js';
11
+ import { CliModelsPayloadSchema, DEFAULT_POLICY, FsListPayloadSchema, WorkspaceScanPayloadSchema, WorkspaceSyncPayloadSchema, RunCancelPayloadSchema, RunStartPayloadSchema, RunTailPayloadSchema, ScriptRunPayloadSchema, SqlRunPayloadSchema } from '../types/protocol.js';
12
+ const sleep = (ms, signal) => new Promise((resolve) => {
13
+ const timer = setTimeout(resolve, ms);
14
+ signal?.addEventListener('abort', () => { clearTimeout(timer); resolve(); }, { once: true });
15
+ });
16
+ /**
17
+ * The agent's main loop, with no persistent connection:
18
+ * - heartbeat every `heartbeatInterval` seconds (liveness + reconciliation)
19
+ * - long-poll for commands, handling each one concurrently
20
+ * - run reports retried until the server acknowledges them
21
+ */
22
+ export class AgentRuntime {
23
+ config;
24
+ version;
25
+ logger;
26
+ client;
27
+ runs;
28
+ orphans;
29
+ workspaces;
30
+ stopController = new AbortController();
31
+ startedAt = new Date().toISOString();
32
+ detection;
33
+ policy = DEFAULT_POLICY;
34
+ heartbeatInterval = 30;
35
+ pollWait = 25;
36
+ lastHeartbeatOk = false;
37
+ lastError;
38
+ /** The server rejected the device token (revoked or unpaired). */
39
+ unauthorized = false;
40
+ ownsLogger;
41
+ deviceName;
42
+ /** Finish reports not yet acknowledged; retried on every heartbeat. */
43
+ pendingReports = new Map();
44
+ /** Model catalogs of the installed CLIs; re-read in the background. */
45
+ models = new ModelCatalogCollector();
46
+ catalogReport;
47
+ catalogRefresh;
48
+ /** Hash of the catalogs the server has stored (from its heartbeat reply). */
49
+ serverCatalogHash;
50
+ constructor(config, version, logger) {
51
+ this.config = config;
52
+ this.version = version;
53
+ this.ownsLogger = !logger;
54
+ this.logger = logger ?? createDiagnosticLogger(config.logFile, { level: config.logLevel, maxAgeMs: 5 * 60 * 1_000 });
55
+ this.client = new GatewayClient(config);
56
+ this.deviceName = config.deviceName;
57
+ const reporter = {
58
+ started: async (runId, report) => {
59
+ await this.retry(() => this.client.runStarted(runId, report), 3);
60
+ },
61
+ finished: async (runId, report) => {
62
+ this.pendingReports.set(runId, report);
63
+ await this.flushReport(runId);
64
+ }
65
+ };
66
+ this.workspaces = new WorkspaceManager(config, this.logger);
67
+ this.orphans = new OrphanRegistry(join(config.dataDir, 'active-runs.json'));
68
+ this.runs = new RunSupervisor(config, this.logger, reporter, this.orphans);
69
+ }
70
+ async start() {
71
+ // A previous agent that crashed may have left CLI processes running.
72
+ const reaped = await this.orphans.reapPrevious();
73
+ if (reaped.length > 0)
74
+ this.logger.warn('orphan-runs-stopped', { runIds: reaped.map((r) => r.runId) });
75
+ this.detection = await cliDetection.detect();
76
+ await this.refreshCatalogs();
77
+ await this.heartbeat();
78
+ void this.heartbeatLoop();
79
+ void this.pollLoop();
80
+ this.logger.info('agent-started', { serverUrl: this.config.serverUrl, deviceId: this.config.deviceId });
81
+ process.stdout.write(`toc-ocra ${this.version} 已启动:${this.config.serverUrl}(设备 ${this.deviceName})\n`);
82
+ }
83
+ async stop() {
84
+ this.stopController.abort();
85
+ await this.runs.disposeAll();
86
+ this.logger.info('agent-stopped');
87
+ if (this.ownsLogger)
88
+ this.logger.close();
89
+ }
90
+ /** Current state, for the local dashboard and the plugin. */
91
+ snapshot() {
92
+ return {
93
+ deviceId: this.config.deviceId,
94
+ deviceName: this.deviceName,
95
+ serverUrl: this.config.serverUrl,
96
+ connected: this.lastHeartbeatOk,
97
+ activeSessions: this.runs.activeCount,
98
+ storedRuns: this.runs.recentRuns().length,
99
+ startedAt: this.startedAt,
100
+ runs: this.runs.recentRuns().map((run) => ({ runId: run.runId, status: run.status, sessionId: run.workstationId, updatedAt: new Date(run.at).toISOString() })),
101
+ capabilities: this.detection?.detectedIds ?? [],
102
+ ...(this.detection ? { detection: this.detection } : {}),
103
+ ...(!this.lastHeartbeatOk && this.lastError ? { connectionError: this.lastError } : {}),
104
+ unauthorized: this.unauthorized,
105
+ activeRunIds: this.runs.activeRunIds()
106
+ };
107
+ }
108
+ /** Re-detects installed CLIs and pushes the change with the next heartbeat. */
109
+ async refreshDetection() {
110
+ this.detection = await cliDetection.detect(true);
111
+ void this.refreshCatalogs({ force: true });
112
+ return this.detection;
113
+ }
114
+ // ---- Heartbeat ----
115
+ async heartbeatLoop() {
116
+ while (!this.stopController.signal.aborted) {
117
+ await sleep(this.heartbeatInterval * 1_000, this.stopController.signal);
118
+ if (this.stopController.signal.aborted)
119
+ return;
120
+ await this.heartbeat();
121
+ }
122
+ }
123
+ async heartbeat() {
124
+ for (const runId of [...this.pendingReports.keys()])
125
+ await this.flushReport(runId, 1);
126
+ // Catalogs go up only when they differ from what the server holds.
127
+ const report = this.catalogReport;
128
+ const sendCatalogs = report !== undefined && report.hash !== this.serverCatalogHash;
129
+ try {
130
+ const response = await this.client.heartbeat({
131
+ agent_version: this.version,
132
+ hostname: this.config.hostname,
133
+ capabilities: this.capabilitySummary(),
134
+ active_runs: this.runs.activeRunIds(),
135
+ ...(sendCatalogs ? { model_catalogs: report } : {})
136
+ });
137
+ this.serverCatalogHash = response.model_catalog_hash ?? (sendCatalogs ? report.hash : this.serverCatalogHash);
138
+ this.policy = response.policy ?? DEFAULT_POLICY;
139
+ this.heartbeatInterval = Math.min(Math.max(response.heartbeat_interval || 30, 5), 120);
140
+ this.pollWait = Math.min(Math.max(response.poll_wait || 25, 1), 30);
141
+ this.deviceName = response.device_name || this.deviceName;
142
+ if (!this.lastHeartbeatOk)
143
+ this.logger.info('heartbeat-ok', { deviceId: response.device_id });
144
+ this.lastHeartbeatOk = true;
145
+ this.unauthorized = false;
146
+ }
147
+ catch (error) {
148
+ this.noteFailure('heartbeat', error);
149
+ }
150
+ // Re-read changed catalogs for the next heartbeat, off the heartbeat path.
151
+ void this.refreshCatalogs();
152
+ }
153
+ /** Re-reads catalogs whose sources changed; concurrent calls share one run. */
154
+ refreshCatalogs(options = {}) {
155
+ if (this.catalogRefresh && !options.force)
156
+ return this.catalogRefresh;
157
+ const run = (async () => {
158
+ try {
159
+ this.catalogReport = await this.models.collect(this.detection?.detectedIds ?? [], options);
160
+ }
161
+ catch (error) {
162
+ this.logger.warn('model-catalog-failed', { error: error instanceof Error ? error.message : String(error) });
163
+ }
164
+ })();
165
+ const tracked = run.finally(() => { if (this.catalogRefresh === tracked)
166
+ this.catalogRefresh = undefined; });
167
+ this.catalogRefresh = tracked;
168
+ return tracked;
169
+ }
170
+ capabilitySummary() {
171
+ const snapshot = this.detection;
172
+ if (!snapshot)
173
+ return { providers: [] };
174
+ return {
175
+ providers: snapshot.providers.map((p) => ({ id: p.id, installed: p.installed, runnable: p.available, version: p.version ?? '', path: p.resolvedPath ?? '' })),
176
+ detected_ids: snapshot.detectedIds,
177
+ refreshed_at: snapshot.refreshedAt
178
+ };
179
+ }
180
+ noteFailure(where, error) {
181
+ const reason = error instanceof Error ? error.message : String(error);
182
+ const unauthorized = error instanceof GatewayError && error.unauthorized;
183
+ if (this.lastHeartbeatOk || this.lastError?.reason !== reason) {
184
+ this.logger.warn(`${where}-failed`, { error: reason });
185
+ if (unauthorized)
186
+ process.stderr.write('设备凭据已失效(可能已解除配对),请在「设备代理」插件里重新绑定,或运行 toc-ocra enroll\n');
187
+ }
188
+ this.unauthorized = unauthorized;
189
+ this.lastHeartbeatOk = false;
190
+ this.lastError = { reason, at: new Date().toISOString() };
191
+ }
192
+ // ---- Commands ----
193
+ async pollLoop() {
194
+ let backoff = 1_000;
195
+ while (!this.stopController.signal.aborted) {
196
+ try {
197
+ const commands = await this.client.poll(this.pollWait, this.stopController.signal);
198
+ backoff = 1_000;
199
+ for (const command of commands)
200
+ void this.handle(command);
201
+ }
202
+ catch (error) {
203
+ if (this.stopController.signal.aborted)
204
+ return;
205
+ this.noteFailure('poll', error);
206
+ const unauthorized = error instanceof GatewayError && error.unauthorized;
207
+ await sleep(unauthorized ? 60_000 : backoff, this.stopController.signal);
208
+ backoff = Math.min(backoff * 2, 30_000);
209
+ }
210
+ }
211
+ }
212
+ async handle(command) {
213
+ this.logger.info('command-received', { commandId: command.id, type: command.type });
214
+ let outcome;
215
+ try {
216
+ outcome = await this.execute(command);
217
+ }
218
+ catch (error) {
219
+ outcome = { success: false, error: error instanceof Error ? error.message : String(error) };
220
+ }
221
+ await this.retry(() => this.client.commandResult(command.id, outcome), 5).catch((error) => {
222
+ this.logger.warn('command-result-failed', { commandId: command.id, error: error instanceof Error ? error.message : String(error) });
223
+ });
224
+ }
225
+ async execute(command) {
226
+ switch (command.type) {
227
+ case 'run.start': {
228
+ const payload = RunStartPayloadSchema.parse(command.payload);
229
+ await this.runs.start(payload);
230
+ return { success: true, result: { accepted: true } };
231
+ }
232
+ case 'run.cancel': {
233
+ const payload = RunCancelPayloadSchema.parse(command.payload);
234
+ const cancelled = await this.runs.cancel(payload.run_id);
235
+ return { success: true, result: { cancelled } };
236
+ }
237
+ case 'run.tail': {
238
+ const payload = RunTailPayloadSchema.parse(command.payload);
239
+ const tail = this.runs.tail({ ...(payload.run_id ? { runId: payload.run_id } : {}), ...(payload.workstation_id ? { workstationId: payload.workstation_id } : {}) }, payload.lines ?? 200, payload.before_cursor);
240
+ return { success: true, result: tail };
241
+ }
242
+ case 'workstation.create': {
243
+ // Headless workstations need no local setup: a session starts with
244
+ // the first turn. Acknowledge so the workstation becomes ready.
245
+ const workstationId = String(command.payload?.workstation_id ?? command.workstation_id);
246
+ return { success: true, session_key: workstationId, result: { ready: true } };
247
+ }
248
+ case 'cli.detect':
249
+ this.detection = await cliDetection.detect(true);
250
+ void this.refreshCatalogs({ force: true });
251
+ return { success: true, result: this.capabilitySummary() };
252
+ case 'cli.models': {
253
+ // Manual refresh: re-read now (one CLI, or all installed ones).
254
+ const payload = CliModelsPayloadSchema.parse(command.payload ?? {});
255
+ await this.refreshCatalogs({ force: true, ...(payload.agent_type ? { only: payload.agent_type.toLowerCase() } : {}) });
256
+ if (!this.catalogReport)
257
+ return { success: false, error: '读取模型目录失败' };
258
+ return { success: true, result: this.catalogReport };
259
+ }
260
+ case 'script.run': {
261
+ const payload = ScriptRunPayloadSchema.parse(command.payload);
262
+ this.checkPolicy('script', payload.policy);
263
+ const workdir = await this.runs.validateWorkdir(payload.workdir || this.config.allowedRoots[0]);
264
+ const result = await executeScript(payload.cmd, workdir, payload.timeout_s);
265
+ return { success: result.exitCode === 0, result, ...(result.exitCode === 0 ? {} : { error: `exit ${result.exitCode}` }) };
266
+ }
267
+ case 'fs.list': {
268
+ const payload = FsListPayloadSchema.parse(command.payload ?? {});
269
+ return { success: true, result: await listDirectory(payload.path, this.config.allowedRoots) };
270
+ }
271
+ case 'workspace.scan': {
272
+ const payload = WorkspaceScanPayloadSchema.parse(command.payload);
273
+ return { success: true, result: await this.workspaces.scan(payload) };
274
+ }
275
+ case 'workspace.sync': {
276
+ const payload = WorkspaceSyncPayloadSchema.parse(command.payload);
277
+ const result = await this.workspaces.sync(payload);
278
+ return { success: !result.error, result, ...(result.error ? { error: result.error } : {}) };
279
+ }
280
+ case 'sql.run': {
281
+ const payload = SqlRunPayloadSchema.parse(command.payload);
282
+ this.checkPolicy('sql', payload.policy);
283
+ return { success: false, error: 'SQL 执行器尚未接入(策略已放行,执行器是预留接口)' };
284
+ }
285
+ default:
286
+ return { success: false, error: `不支持的指令:${command.type}` };
287
+ }
288
+ }
289
+ /**
290
+ * Script / SQL run only when the server policy allows it and the local
291
+ * owner has not switched it off. The policy attached to the command was
292
+ * checked by the server at enqueue time, so it wins over the (up to one
293
+ * heartbeat old) cached copy. New policy fields (read-only SQL,
294
+ * allowlists) are enforced here.
295
+ */
296
+ checkPolicy(kind, commandPolicy) {
297
+ const localOff = kind === 'script' ? this.config.disableScript : this.config.disableSql;
298
+ const policy = commandPolicy ?? this.policy;
299
+ const enabled = !localOff && policy[kind].enabled;
300
+ if (!enabled)
301
+ throw new Error(kind === 'script' ? '该设备未开启脚本执行' : '该设备未开启 SQL 执行');
302
+ }
303
+ // ---- Reports ----
304
+ async flushReport(runId, attempts = 6) {
305
+ const report = this.pendingReports.get(runId);
306
+ if (!report)
307
+ return;
308
+ try {
309
+ await this.retry(() => this.client.runFinished(runId, report), attempts);
310
+ this.pendingReports.delete(runId);
311
+ this.runs.markReported(runId);
312
+ }
313
+ catch (error) {
314
+ // 404: the server no longer knows the run; nothing left to report.
315
+ if (error instanceof GatewayError && (error.status === 404 || /not found/i.test(error.message))) {
316
+ this.pendingReports.delete(runId);
317
+ this.runs.markReported(runId);
318
+ return;
319
+ }
320
+ this.logger.warn('run-report-pending', { runId, error: error instanceof Error ? error.message : String(error) });
321
+ }
322
+ }
323
+ async retry(action, attempts) {
324
+ let delay = 500;
325
+ for (let attempt = 1;; attempt++) {
326
+ try {
327
+ return await action();
328
+ }
329
+ catch (error) {
330
+ // A logical error (HTTP 200, success=false) or a 4xx will not change on retry.
331
+ const permanent = error instanceof GatewayError && (error.status === 200 || (error.status >= 400 && error.status < 500 && error.status !== 429));
332
+ if (permanent || attempt >= attempts || this.stopController.signal.aborted)
333
+ throw error;
334
+ await sleep(delay, this.stopController.signal);
335
+ delay = Math.min(delay * 2, 10_000);
336
+ }
337
+ }
338
+ }
339
+ }
340
+ //# sourceMappingURL=agent-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-runtime.js","sourceRoot":"","sources":["../../../src/runtime/agent-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAGhC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAExD,OAAO,EAAE,sBAAsB,EAAyB,MAAM,8BAA8B,CAAA;AAC5F,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAA;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAoB,MAAM,2BAA2B,CAAA;AAE3E,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAA;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAA;AACpE,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,mBAAmB,EACnB,0BAA0B,EAC1B,0BAA0B,EAC1B,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EAKpB,MAAM,sBAAsB,CAAA;AAE7B,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,MAAoB,EAAE,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;IAChF,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;IACrC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAA,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;AAC7F,CAAC,CAAC,CAAA;AAIF;;;;;GAKG;AACH,MAAM,OAAO,YAAY;IA2BM;IAAsC;IA1BlD,MAAM,CAAkB;IACxB,MAAM,CAAe;IACrB,IAAI,CAAe;IACnB,OAAO,CAAgB;IACvB,UAAU,CAAkB;IAC5B,cAAc,GAAG,IAAI,eAAe,EAAE,CAAA;IACtC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAC7C,SAAS,CAAuB;IAChC,MAAM,GAAiB,cAAc,CAAA;IACrC,iBAAiB,GAAG,EAAE,CAAA;IACtB,QAAQ,GAAG,EAAE,CAAA;IACb,eAAe,GAAG,KAAK,CAAA;IACvB,SAAS,CAA4C;IAC7D,kEAAkE;IAC1D,YAAY,GAAG,KAAK,CAAA;IACX,UAAU,CAAS;IAC5B,UAAU,CAAQ;IAC1B,uEAAuE;IACtD,cAAc,GAAG,IAAI,GAAG,EAA6B,CAAA;IACtE,uEAAuE;IACtD,MAAM,GAAG,IAAI,qBAAqB,EAAE,CAAA;IAC7C,aAAa,CAAgC;IAC7C,cAAc,CAA2B;IACjD,6EAA6E;IACrE,iBAAiB,CAAoB;IAE7C,YAA6B,MAAmB,EAAmB,OAAe,EAAE,MAAyB;QAAhF,WAAM,GAAN,MAAM,CAAa;QAAmB,YAAO,GAAP,OAAO,CAAQ;QAChF,IAAI,CAAC,UAAU,GAAG,CAAC,MAAM,CAAA;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,sBAAsB,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,CAAA;QACpH,IAAI,CAAC,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAA;QACvC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAA;QACnC,MAAM,QAAQ,GAAgB;YAC5B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;gBAC/B,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;YAClE,CAAC;YACD,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;gBAChC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;gBACtC,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;YAC/B,CAAC;SACF,CAAA;QACD,IAAI,CAAC,UAAU,GAAG,IAAI,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAC3D,IAAI,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAA;QAC3E,IAAI,CAAC,IAAI,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IAC5E,CAAC;IAED,KAAK,CAAC,KAAK;QACT,qEAAqE;QACrE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAA;QAChD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QACtG,IAAI,CAAC,SAAS,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,CAAA;QAC5C,MAAM,IAAI,CAAC,eAAe,EAAE,CAAA;QAC5B,MAAM,IAAI,CAAC,SAAS,EAAE,CAAA;QACtB,KAAK,IAAI,CAAC,aAAa,EAAE,CAAA;QACzB,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAA;QACpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;QACvG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,OAAO,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,OAAO,IAAI,CAAC,UAAU,KAAK,CAAC,CAAA;IACxG,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAA;QAC3B,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAA;QAC5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;QACjC,IAAI,IAAI,CAAC,UAAU;YAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;IAC1C,CAAC;IAED,6DAA6D;IAC7D,QAAQ;QACN,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC9B,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS;YAChC,SAAS,EAAE,IAAI,CAAC,eAAe;YAC/B,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW;YACrC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,MAAM;YACzC,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,aAAa,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAC9J,YAAY,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,IAAI,EAAE;YAC/C,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,GAAG,CAAC,CAAC,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvF,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;SACvC,CAAA;IACH,CAAC;IAED,+EAA+E;IAC/E,KAAK,CAAC,gBAAgB;QACpB,IAAI,CAAC,SAAS,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAChD,KAAK,IAAI,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QAC1C,OAAO,IAAI,CAAC,SAAS,CAAA;IACvB,CAAC;IAED,sBAAsB;IAEd,KAAK,CAAC,aAAa;QACzB,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAC3C,MAAM,KAAK,CAAC,IAAI,CAAC,iBAAiB,GAAG,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;YACvE,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO;gBAAE,OAAM;YAC9C,MAAM,IAAI,CAAC,SAAS,EAAE,CAAA;QACxB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,SAAS;QACrB,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;YAAE,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;QACrF,mEAAmE;QACnE,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAA;QACjC,MAAM,YAAY,GAAG,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAA;QACnF,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;gBAC3C,aAAa,EAAE,IAAI,CAAC,OAAO;gBAC3B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;gBAC9B,YAAY,EAAE,IAAI,CAAC,iBAAiB,EAAE;gBACtC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;gBACrC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpD,CAAC,CAAA;YACF,IAAI,CAAC,iBAAiB,GAAG,QAAQ,CAAC,kBAAkB,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;YAC7G,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,cAAc,CAAA;YAC/C,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,kBAAkB,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;YACtF,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;YACnE,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,WAAW,IAAI,IAAI,CAAC,UAAU,CAAA;YACzD,IAAI,CAAC,IAAI,CAAC,eAAe;gBAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAA;YAC7F,IAAI,CAAC,eAAe,GAAG,IAAI,CAAA;YAC3B,IAAI,CAAC,YAAY,GAAG,KAAK,CAAA;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;QACtC,CAAC;QACD,2EAA2E;QAC3E,KAAK,IAAI,CAAC,eAAe,EAAE,CAAA;IAC7B,CAAC;IAED,+EAA+E;IACvE,eAAe,CAAC,UAA8C,EAAE;QACtE,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,OAAO,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,cAAc,CAAA;QACrE,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE;YACtB,IAAI,CAAC;gBACH,IAAI,CAAC,aAAa,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,IAAI,EAAE,EAAE,OAAO,CAAC,CAAA;YAC5F,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YAC7G,CAAC;QACH,CAAC,CAAC,EAAE,CAAA;QACJ,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,cAAc,KAAK,OAAO;YAAE,IAAI,CAAC,cAAc,GAAG,SAAS,CAAA,CAAC,CAAC,CAAC,CAAA;QAC3G,IAAI,CAAC,cAAc,GAAG,OAAO,CAAA;QAC7B,OAAO,OAAO,CAAA;IAChB,CAAC;IAEO,iBAAiB;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAA;QAC/B,IAAI,CAAC,QAAQ;YAAE,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,CAAA;QACvC,OAAO;YACL,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC,CAAC;YAC7J,YAAY,EAAE,QAAQ,CAAC,WAAW;YAClC,YAAY,EAAE,QAAQ,CAAC,WAAW;SACnC,CAAA;IACH,CAAC;IAEO,WAAW,CAAC,KAAa,EAAE,KAAc;QAC/C,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACrE,MAAM,YAAY,GAAG,KAAK,YAAY,YAAY,IAAI,KAAK,CAAC,YAAY,CAAA;QACxE,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;YAC9D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;YACtD,IAAI,YAAY;gBAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAA;QAClG,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;QAChC,IAAI,CAAC,eAAe,GAAG,KAAK,CAAA;QAC5B,IAAI,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAA;IAC3D,CAAC;IAED,qBAAqB;IAEb,KAAK,CAAC,QAAQ;QACpB,IAAI,OAAO,GAAG,KAAK,CAAA;QACnB,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAC3C,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;gBAClF,OAAO,GAAG,KAAK,CAAA;gBACf,KAAK,MAAM,OAAO,IAAI,QAAQ;oBAAE,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YAC3D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO;oBAAE,OAAM;gBAC9C,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;gBAC/B,MAAM,YAAY,GAAG,KAAK,YAAY,YAAY,IAAI,KAAK,CAAC,YAAY,CAAA;gBACxE,MAAM,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;gBACxE,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,EAAE,MAAM,CAAC,CAAA;YACzC,CAAC;QACH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,OAAsB;QACzC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;QACnF,IAAI,OAAuB,CAAA;QAC3B,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;QAC7F,CAAC;QACD,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACxF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QACrI,CAAC,CAAC,CAAA;IACJ,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,OAAsB;QAC1C,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,MAAM,OAAO,GAAG,qBAAqB,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;gBAC5D,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;gBAC9B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAA;YACtD,CAAC;YACD,KAAK,YAAY,CAAC,CAAC,CAAC;gBAClB,MAAM,OAAO,GAAG,sBAAsB,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;gBAC7D,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;gBACxD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,EAAE,CAAA;YACjD,CAAC;YACD,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,MAAM,OAAO,GAAG,oBAAoB,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;gBAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;gBAChN,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;YACxC,CAAC;YACD,KAAK,oBAAoB,CAAC,CAAC,CAAC;gBAC1B,mEAAmE;gBACnE,gEAAgE;gBAChE,MAAM,aAAa,GAAG,MAAM,CAAE,OAAO,CAAC,OAAwC,EAAE,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC,CAAA;gBACzH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAA;YAC/E,CAAC;YACD,KAAK,YAAY;gBACf,IAAI,CAAC,SAAS,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;gBAChD,KAAK,IAAI,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;gBAC1C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAA;YAC5D,KAAK,YAAY,CAAC,CAAC,CAAC;gBAClB,gEAAgE;gBAChE,MAAM,OAAO,GAAG,sBAAsB,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAA;gBACnE,MAAM,IAAI,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;gBACtH,IAAI,CAAC,IAAI,CAAC,aAAa;oBAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,CAAA;gBACrE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,CAAA;YACtD,CAAC;YACD,KAAK,YAAY,CAAC,CAAC,CAAC;gBAClB,MAAM,OAAO,GAAG,sBAAsB,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;gBAC7D,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;gBAC1C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAA;gBAC/F,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;gBAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAA;YAC3H,CAAC;YACD,KAAK,SAAS,CAAC,CAAC,CAAC;gBACf,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAA;gBAChE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAA;YAC/F,CAAC;YACD,KAAK,gBAAgB,CAAC,CAAC,CAAC;gBACtB,MAAM,OAAO,GAAG,0BAA0B,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;gBACjE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAA;YACvE,CAAC;YACD,KAAK,gBAAgB,CAAC,CAAC,CAAC;gBACtB,MAAM,OAAO,GAAG,0BAA0B,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;gBACjE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBAClD,OAAO,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAA;YAC7F,CAAC;YACD,KAAK,SAAS,CAAC,CAAC,CAAC;gBACf,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;gBAC1D,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;gBACvC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAA;YACjE,CAAC;YACD;gBACE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,OAAO,CAAC,IAAI,EAAE,EAAE,CAAA;QAC9D,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACK,WAAW,CAAC,IAAsB,EAAE,aAAuC;QACjF,MAAM,QAAQ,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAA;QACvF,MAAM,MAAM,GAAG,aAAa,IAAI,IAAI,CAAC,MAAM,CAAA;QAC3C,MAAM,OAAO,GAAG,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAA;QACjD,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC,CAAA;IACnF,CAAC;IAED,oBAAoB;IAEZ,KAAK,CAAC,WAAW,CAAC,KAAa,EAAE,QAAQ,GAAG,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAC7C,IAAI,CAAC,MAAM;YAAE,OAAM;QACnB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAA;YACxE,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACjC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,mEAAmE;YACnE,IAAI,KAAK,YAAY,YAAY,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;gBAChG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;gBACjC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;gBAC7B,OAAM;YACR,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAClH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,KAAK,CAAI,MAAwB,EAAE,QAAgB;QAC/D,IAAI,KAAK,GAAG,GAAG,CAAA;QACf,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,OAAO,MAAM,MAAM,EAAE,CAAA;YACvB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,+EAA+E;gBAC/E,MAAM,SAAS,GAAG,KAAK,YAAY,YAAY,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAA;gBAChJ,IAAI,SAAS,IAAI,OAAO,IAAI,QAAQ,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO;oBAAE,MAAM,KAAK,CAAA;gBACvF,MAAM,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;gBAC9C,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,MAAM,CAAC,CAAA;YACrC,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,33 @@
1
+ /** Bumped when the control API changes incompatibly. */
2
+ export declare const CONTROL_PROTOCOL_VERSION = 1;
3
+ /**
4
+ * The long-running `toc-ocra run` process. It owns the local server (the
5
+ * dashboard plus the plugin control API) and runs the agent runtime while
6
+ * this machine is enrolled. Pairing and unpairing from the plugin start and
7
+ * stop the runtime without restarting the process.
8
+ */
9
+ export declare class AgentService {
10
+ private readonly version;
11
+ private config;
12
+ private readonly logger;
13
+ private readonly pairing;
14
+ private readonly server;
15
+ private runtime;
16
+ private detection;
17
+ private readonly startedAt;
18
+ /** Serializes enroll / unpair so two clicks cannot race. */
19
+ private transition;
20
+ constructor(version: string);
21
+ start(): Promise<void>;
22
+ stop(): Promise<void>;
23
+ private startRuntime;
24
+ private stopRuntime;
25
+ private detect;
26
+ private idleSnapshot;
27
+ /** What the plugin shows; never includes the device or control token. */
28
+ private status;
29
+ private controlApi;
30
+ private serialize;
31
+ }
32
+ /** The platform names echo_admin uses for devices. */
33
+ export declare function devicePlatform(platform: NodeJS.Platform): 'mac' | 'win' | 'linux';
@@ -0,0 +1,181 @@
1
+ import { clearEnrollment, enrollDevice, loadBaseConfig, normalizeServerUrl } from '../config.js';
2
+ import { PairingStore } from '../control/pairing.js';
3
+ import { ControlError, HealthServer } from '../health/server.js';
4
+ import { createDiagnosticLogger } from '../logging/diagnostic-log.js';
5
+ import { cliDetection } from '../providers/detection.js';
6
+ import { AgentRuntime } from './agent-runtime.js';
7
+ /** Bumped when the control API changes incompatibly. */
8
+ export const CONTROL_PROTOCOL_VERSION = 1;
9
+ /**
10
+ * The long-running `toc-ocra run` process. It owns the local server (the
11
+ * dashboard plus the plugin control API) and runs the agent runtime while
12
+ * this machine is enrolled. Pairing and unpairing from the plugin start and
13
+ * stop the runtime without restarting the process.
14
+ */
15
+ export class AgentService {
16
+ version;
17
+ config;
18
+ logger;
19
+ pairing;
20
+ server;
21
+ runtime;
22
+ detection;
23
+ startedAt = new Date().toISOString();
24
+ /** Serializes enroll / unpair so two clicks cannot race. */
25
+ transition = Promise.resolve();
26
+ constructor(version) {
27
+ this.version = version;
28
+ this.config = loadBaseConfig();
29
+ this.logger = createDiagnosticLogger(this.config.logFile, { level: this.config.logLevel, maxAgeMs: 5 * 60 * 1_000 });
30
+ this.pairing = new PairingStore(this.config.dataDir);
31
+ this.server = new HealthServer(this.config.healthHost, this.config.healthPort, () => this.runtime?.snapshot() ?? this.idleSnapshot(), this.config.logFile, this.logger, async (refresh) => (this.runtime ? (refresh ? this.runtime.refreshDetection() : this.runtime.snapshot().detection ?? this.detect(false)) : this.detect(refresh)), this.controlApi());
32
+ }
33
+ async start() {
34
+ await this.pairing.init();
35
+ try {
36
+ await this.server.start();
37
+ }
38
+ catch (error) {
39
+ // Without the local server the plugin cannot reach this machine; the
40
+ // agent still runs if it is enrolled.
41
+ this.logger.warn('health-server-unavailable', { error: errorMessage(error) });
42
+ process.stderr.write(`本机服务端口 ${this.config.healthHost}:${this.config.healthPort} 不可用(${errorMessage(error)}),插件将无法连接\n`);
43
+ }
44
+ process.stdout.write(`toc-ocra ${this.version} 本机服务:http://${this.config.healthHost}:${this.server.boundPort}\n`);
45
+ process.stdout.write(`插件连接码:${this.pairing.connectionCode}(之后可运行 toc-ocra code 查看)\n`);
46
+ if (this.config.token)
47
+ await this.startRuntime();
48
+ else
49
+ process.stdout.write('本机尚未绑定服务器,请在「设备代理」插件中完成绑定\n');
50
+ }
51
+ async stop() {
52
+ await this.runtime?.stop();
53
+ this.runtime = undefined;
54
+ await this.server.stop();
55
+ await this.pairing.dispose();
56
+ this.logger.close();
57
+ }
58
+ async startRuntime() {
59
+ const runtime = new AgentRuntime(this.config, this.version, this.logger);
60
+ this.runtime = runtime;
61
+ await runtime.start();
62
+ }
63
+ async stopRuntime() {
64
+ const runtime = this.runtime;
65
+ this.runtime = undefined;
66
+ await runtime?.stop();
67
+ }
68
+ async detect(refresh) {
69
+ this.detection = await cliDetection.detect(refresh);
70
+ return this.detection;
71
+ }
72
+ idleSnapshot() {
73
+ return {
74
+ deviceId: '',
75
+ connected: false,
76
+ activeSessions: 0,
77
+ storedRuns: 0,
78
+ startedAt: this.startedAt,
79
+ runs: [],
80
+ ...(this.detection ? { detection: this.detection } : {})
81
+ };
82
+ }
83
+ /** What the plugin shows; never includes the device or control token. */
84
+ async status() {
85
+ const snapshot = this.runtime?.snapshot();
86
+ const detection = snapshot?.detection ?? this.detection ?? (await this.detect(false));
87
+ return {
88
+ version: this.version,
89
+ protocol: CONTROL_PROTOCOL_VERSION,
90
+ hostname: this.config.hostname,
91
+ platform: devicePlatform(this.config.platform),
92
+ started_at: this.startedAt,
93
+ paired: Boolean(this.config.token),
94
+ running: Boolean(this.runtime),
95
+ device_id: this.config.deviceId,
96
+ device_name: snapshot?.deviceName ?? this.config.deviceName,
97
+ server_url: this.config.token ? this.config.serverUrl : '',
98
+ connected: snapshot?.connected ?? false,
99
+ unauthorized: snapshot?.unauthorized ?? false,
100
+ connection_error: snapshot?.connectionError?.reason ?? '',
101
+ active_runs: snapshot?.activeRunIds.length ?? 0,
102
+ allowed_roots: this.config.allowedRoots,
103
+ token_from_env: Boolean(process.env.TOC_OCRA_TOKEN),
104
+ providers: detection.providers.map((provider) => ({
105
+ id: provider.id,
106
+ installed: provider.installed,
107
+ runnable: provider.available,
108
+ version: provider.version ?? ''
109
+ }))
110
+ };
111
+ }
112
+ controlApi() {
113
+ return {
114
+ info: () => ({ name: 'toc-ocra', version: this.version, protocol: CONTROL_PROTOCOL_VERSION, paired: Boolean(this.config.token) }),
115
+ pair: (code) => this.pairing.pair(code),
116
+ authorize: (header) => this.pairing.authorize(header),
117
+ status: () => this.status(),
118
+ enroll: (input) => this.serialize(async () => {
119
+ const code = typeof input.code === 'string' ? input.code.trim() : '';
120
+ const rawUrl = typeof input.serverUrl === 'string' ? input.serverUrl.trim() : '';
121
+ if (!code)
122
+ throw new ControlError(400, '缺少配对码', 'code_required');
123
+ let serverUrl;
124
+ try {
125
+ serverUrl = normalizeServerUrl(rawUrl);
126
+ }
127
+ catch {
128
+ throw new ControlError(400, `服务器地址无效:${rawUrl || '(空)'}`, 'invalid_server_url');
129
+ }
130
+ if (process.env.TOC_OCRA_TOKEN)
131
+ throw new ControlError(409, '设备令牌来自环境变量 TOC_OCRA_TOKEN,请先移除该变量再绑定', 'token_from_env');
132
+ // Enroll first: if the code is wrong the current binding keeps running.
133
+ let enrolled;
134
+ try {
135
+ enrolled = await enrollDevice({ code, serverUrl, configPath: this.config.configPath, agentVersion: this.version });
136
+ }
137
+ catch (error) {
138
+ throw new ControlError(400, errorMessage(error), 'enroll_failed');
139
+ }
140
+ await this.stopRuntime();
141
+ this.config = loadBaseConfig();
142
+ this.logger.info('device-enrolled', { deviceId: enrolled.deviceId, serverUrl: enrolled.serverUrl });
143
+ await this.startRuntime();
144
+ return this.status();
145
+ }),
146
+ unpair: () => this.serialize(async () => {
147
+ if (process.env.TOC_OCRA_TOKEN)
148
+ throw new ControlError(409, '设备令牌来自环境变量 TOC_OCRA_TOKEN,请先移除该变量', 'token_from_env');
149
+ await this.stopRuntime();
150
+ await clearEnrollment(this.config.configPath);
151
+ this.config = loadBaseConfig();
152
+ this.logger.info('device-unpaired');
153
+ return this.status();
154
+ }),
155
+ detect: async () => {
156
+ if (this.runtime)
157
+ await this.runtime.refreshDetection();
158
+ else
159
+ await this.detect(true);
160
+ return this.status();
161
+ }
162
+ };
163
+ }
164
+ serialize(action) {
165
+ const next = this.transition.then(action, action);
166
+ this.transition = next.catch(() => undefined);
167
+ return next;
168
+ }
169
+ }
170
+ /** The platform names echo_admin uses for devices. */
171
+ export function devicePlatform(platform) {
172
+ if (platform === 'darwin')
173
+ return 'mac';
174
+ if (platform === 'win32')
175
+ return 'win';
176
+ return 'linux';
177
+ }
178
+ function errorMessage(error) {
179
+ return error instanceof Error ? error.message : String(error);
180
+ }
181
+ //# sourceMappingURL=agent-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-service.js","sourceRoot":"","sources":["../../../src/runtime/agent-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ export type ShellHydrationFailureReason = 'none' | 'no_shell' | 'timeout' | 'spawn_error' | 'empty_path';
2
+ export type HydrationResult = {
3
+ ok: true;
4
+ segments: string[];
5
+ failureReason: 'none';
6
+ } | {
7
+ ok: false;
8
+ segments: [];
9
+ failureReason: Exclude<ShellHydrationFailureReason, 'none'>;
10
+ };
11
+ /** @internal - tests need a clean hydration cache between cases. */
12
+ export declare function _resetHydrateShellPathCache(): void;
13
+ type HydrateOptions = {
14
+ force?: boolean;
15
+ /** Override for tests — defaults to running `spawn` against the real shell. */
16
+ spawner?: (shell: string) => Promise<HydrationResult>;
17
+ /** Override for tests — defaults to `pickShell()`. */
18
+ shellOverride?: string | null;
19
+ };
20
+ /**
21
+ * Spawn the user's login shell once and return the PATH it would export.
22
+ * Caches the promise for the lifetime of the process — call
23
+ * `_resetHydrateShellPathCache()` in tests or `hydrateShellPath({ force: true })`
24
+ * when the user asks to re-probe (e.g. after installing a new CLI).
25
+ */
26
+ export declare function hydrateShellPath(options?: HydrateOptions): Promise<HydrationResult>;
27
+ /**
28
+ * Promote shell-discovered PATH segments to the front of process.env.PATH,
29
+ * preserving shell ordering and avoiding duplicates. Returns the segments that
30
+ * were newly added so callers can log/telemetry on nontrivial hydrations.
31
+ */
32
+ export declare function mergePathSegments(segments: string[]): string[];
33
+ export {};