@pentoshi/clai 3.9.4 → 3.9.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 (91) hide show
  1. package/dist/app/controllers/session-controller.d.ts +0 -8
  2. package/dist/app/controllers/session-controller.js +4 -20
  3. package/dist/app/controllers/session-controller.js.map +1 -1
  4. package/dist/index.js +8 -21
  5. package/dist/index.js.map +1 -1
  6. package/dist/repl.js +0 -10
  7. package/dist/repl.js.map +1 -1
  8. package/dist/tools/definitions.js +0 -95
  9. package/dist/tools/definitions.js.map +1 -1
  10. package/dist/tools/jobs.js +70 -2
  11. package/dist/tools/jobs.js.map +1 -1
  12. package/dist/tools/registry.js +0 -4
  13. package/dist/tools/registry.js.map +1 -1
  14. package/dist/tui-v2/bootstrap/composition-root.d.ts +0 -3
  15. package/dist/tui-v2/bootstrap/composition-root.js +0 -3
  16. package/dist/tui-v2/bootstrap/composition-root.js.map +1 -1
  17. package/dist/tui-v2/bootstrap/start-tui-v2.js +0 -10
  18. package/dist/tui-v2/bootstrap/start-tui-v2.js.map +1 -1
  19. package/dist/types.d.ts +0 -5
  20. package/dist/version.generated.d.ts +2 -2
  21. package/dist/version.generated.js +2 -2
  22. package/package.json +1 -1
  23. package/dist/app/adapters/current-interactive-sessions-adapter.d.ts +0 -4
  24. package/dist/app/adapters/current-interactive-sessions-adapter.js +0 -11
  25. package/dist/app/adapters/current-interactive-sessions-adapter.js.map +0 -1
  26. package/dist/app/controllers/cancel-all-result.d.ts +0 -8
  27. package/dist/app/controllers/cancel-all-result.js +0 -32
  28. package/dist/app/controllers/cancel-all-result.js.map +0 -1
  29. package/dist/app/ports/interactive-sessions-port.d.ts +0 -21
  30. package/dist/app/ports/interactive-sessions-port.js +0 -9
  31. package/dist/app/ports/interactive-sessions-port.js.map +0 -1
  32. package/dist/interactive-session/artifact-writer.d.ts +0 -54
  33. package/dist/interactive-session/artifact-writer.js +0 -161
  34. package/dist/interactive-session/artifact-writer.js.map +0 -1
  35. package/dist/interactive-session/cleanup.d.ts +0 -36
  36. package/dist/interactive-session/cleanup.js +0 -157
  37. package/dist/interactive-session/cleanup.js.map +0 -1
  38. package/dist/interactive-session/config.d.ts +0 -118
  39. package/dist/interactive-session/config.js +0 -141
  40. package/dist/interactive-session/config.js.map +0 -1
  41. package/dist/interactive-session/input-policy.d.ts +0 -41
  42. package/dist/interactive-session/input-policy.js +0 -163
  43. package/dist/interactive-session/input-policy.js.map +0 -1
  44. package/dist/interactive-session/manager.d.ts +0 -107
  45. package/dist/interactive-session/manager.js +0 -927
  46. package/dist/interactive-session/manager.js.map +0 -1
  47. package/dist/interactive-session/output-store.d.ts +0 -81
  48. package/dist/interactive-session/output-store.js +0 -239
  49. package/dist/interactive-session/output-store.js.map +0 -1
  50. package/dist/interactive-session/output-view.d.ts +0 -20
  51. package/dist/interactive-session/output-view.js +0 -142
  52. package/dist/interactive-session/output-view.js.map +0 -1
  53. package/dist/interactive-session/recovery-journal.d.ts +0 -55
  54. package/dist/interactive-session/recovery-journal.js +0 -115
  55. package/dist/interactive-session/recovery-journal.js.map +0 -1
  56. package/dist/interactive-session/registry.d.ts +0 -59
  57. package/dist/interactive-session/registry.js +0 -170
  58. package/dist/interactive-session/registry.js.map +0 -1
  59. package/dist/interactive-session/runtime.d.ts +0 -107
  60. package/dist/interactive-session/runtime.js +0 -191
  61. package/dist/interactive-session/runtime.js.map +0 -1
  62. package/dist/interactive-session/session-runtime.d.ts +0 -50
  63. package/dist/interactive-session/session-runtime.js +0 -63
  64. package/dist/interactive-session/session-runtime.js.map +0 -1
  65. package/dist/interactive-session/streaming-redactor.d.ts +0 -53
  66. package/dist/interactive-session/streaming-redactor.js +0 -263
  67. package/dist/interactive-session/streaming-redactor.js.map +0 -1
  68. package/dist/interactive-session/telemetry.d.ts +0 -30
  69. package/dist/interactive-session/telemetry.js +0 -47
  70. package/dist/interactive-session/telemetry.js.map +0 -1
  71. package/dist/interactive-session/transport-factory.d.ts +0 -8
  72. package/dist/interactive-session/transport-factory.js +0 -16
  73. package/dist/interactive-session/transport-factory.js.map +0 -1
  74. package/dist/interactive-session/transport-node-pty.d.ts +0 -49
  75. package/dist/interactive-session/transport-node-pty.js +0 -219
  76. package/dist/interactive-session/transport-node-pty.js.map +0 -1
  77. package/dist/interactive-session/transport-pipe.d.ts +0 -9
  78. package/dist/interactive-session/transport-pipe.js +0 -215
  79. package/dist/interactive-session/transport-pipe.js.map +0 -1
  80. package/dist/interactive-session/transport.d.ts +0 -104
  81. package/dist/interactive-session/transport.js +0 -89
  82. package/dist/interactive-session/transport.js.map +0 -1
  83. package/dist/interactive-session/types.d.ts +0 -254
  84. package/dist/interactive-session/types.js +0 -191
  85. package/dist/interactive-session/types.js.map +0 -1
  86. package/dist/os/process-identity.d.ts +0 -46
  87. package/dist/os/process-identity.js +0 -147
  88. package/dist/os/process-identity.js.map +0 -1
  89. package/dist/tools/interactive-session-tools.d.ts +0 -11
  90. package/dist/tools/interactive-session-tools.js +0 -261
  91. package/dist/tools/interactive-session-tools.js.map +0 -1
@@ -1,161 +0,0 @@
1
- /**
2
- * Bounded, owner-private artifact capture for one interactive session.
3
- *
4
- * The writer only ever receives canonical redacted bytes, so nothing sensitive
5
- * becomes durable. Chunk names contain only the opaque session id and an index —
6
- * never a command, cwd, or timestamp that could identify the workload.
7
- */
8
- import { createWriteStream } from "node:fs";
9
- import { mkdir } from "node:fs/promises";
10
- import { createHash } from "node:crypto";
11
- import { join } from "node:path";
12
- import { getArtifactDir } from "../store/paths.js";
13
- export class BoundedArtifactWriter {
14
- options;
15
- stream;
16
- streamDone;
17
- completedStreams = [];
18
- chunks = [];
19
- hash = createHash("sha256");
20
- index = 0;
21
- currentChunkBytes = 0;
22
- capturedBytes = 0;
23
- dropped = 0;
24
- pendingBytes = 0;
25
- digest = "";
26
- closePromise;
27
- writeError;
28
- backpressured = new Set();
29
- limitReached = false;
30
- failed = false;
31
- constructor(options) {
32
- this.options = options;
33
- }
34
- get path() {
35
- return join(this.options.directory, `${this.options.sessionId}.log`);
36
- }
37
- reference() {
38
- return {
39
- path: this.path,
40
- bytes: this.capturedBytes,
41
- droppedBytes: this.dropped,
42
- redacted: true,
43
- };
44
- }
45
- receipt() {
46
- return {
47
- ...this.reference(),
48
- chunks: [...this.chunks],
49
- sha256: this.digest,
50
- };
51
- }
52
- append(bytes) {
53
- if (this.failed || this.closePromise)
54
- return true;
55
- let data = bytes;
56
- const remaining = Math.max(0, this.options.captureBytes - this.capturedBytes);
57
- if (data.length > remaining) {
58
- this.dropped += data.length - remaining;
59
- data = data.subarray(0, remaining);
60
- this.limitReached = this.options.onLimit === "terminate";
61
- }
62
- let writable = true;
63
- while (data.length > 0) {
64
- if (!this.stream || this.currentChunkBytes >= this.options.chunkBytes) {
65
- this.rotate();
66
- }
67
- const room = this.options.chunkBytes - this.currentChunkBytes;
68
- const part = data.subarray(0, room);
69
- const stream = this.stream;
70
- const accepted = stream.write(Buffer.from(part));
71
- if (!accepted) {
72
- this.backpressured.add(stream);
73
- this.pendingBytes += part.length;
74
- }
75
- writable = accepted && writable;
76
- this.hash.update(part);
77
- this.digest = this.hash.copy().digest("hex");
78
- this.capturedBytes += part.length;
79
- this.currentChunkBytes += part.length;
80
- data = data.subarray(part.length);
81
- }
82
- if (this.writeError)
83
- this.failed = true;
84
- if (this.pendingBytes > this.options.persistenceQueueBytes)
85
- this.failed = true;
86
- return writable;
87
- }
88
- async waitForDrain() {
89
- const blocked = [...this.backpressured].filter((stream) => stream.writableNeedDrain);
90
- if (blocked.length === 0) {
91
- this.pendingBytes = 0;
92
- return;
93
- }
94
- await Promise.all(blocked.map((stream) => new Promise((resolve) => {
95
- const done = () => {
96
- stream.off("drain", done);
97
- stream.off("finish", done);
98
- stream.off("error", done);
99
- this.backpressured.delete(stream);
100
- resolve();
101
- };
102
- stream.once("drain", done);
103
- stream.once("finish", done);
104
- stream.once("error", done);
105
- })));
106
- this.pendingBytes = 0;
107
- }
108
- close() {
109
- if (this.closePromise)
110
- return this.closePromise;
111
- this.finishCurrentStream();
112
- this.closePromise = Promise.all(this.completedStreams).then(() => {
113
- if (this.writeError) {
114
- this.failed = true;
115
- throw this.writeError;
116
- }
117
- });
118
- return this.closePromise;
119
- }
120
- finishCurrentStream() {
121
- if (!this.stream || !this.streamDone)
122
- return;
123
- const stream = this.stream;
124
- const done = this.streamDone;
125
- this.stream = undefined;
126
- this.streamDone = undefined;
127
- stream.end();
128
- this.completedStreams.push(done);
129
- }
130
- rotate() {
131
- this.finishCurrentStream();
132
- const path = this.index === 0 ? this.path : `${this.path}.${this.index}`;
133
- this.index += 1;
134
- this.currentChunkBytes = 0;
135
- this.chunks.push(path);
136
- const stream = createWriteStream(path, { flags: "w", mode: 0o600 });
137
- this.stream = stream;
138
- this.streamDone = new Promise((resolve) => {
139
- stream.once("finish", resolve);
140
- stream.once("error", (error) => {
141
- this.writeError ??= error;
142
- this.failed = true;
143
- resolve();
144
- });
145
- });
146
- }
147
- }
148
- /** Create the owner-only artifact directory for one session. */
149
- export async function createArtifactWriter(options) {
150
- const directory = join(options.baseDir ?? getArtifactDir(), `interactive-${options.sessionId}`);
151
- await mkdir(directory, { recursive: true, mode: 0o700 });
152
- return new BoundedArtifactWriter({
153
- sessionId: options.sessionId,
154
- directory,
155
- captureBytes: options.captureBytes,
156
- chunkBytes: options.chunkBytes,
157
- persistenceQueueBytes: options.persistenceQueueBytes,
158
- onLimit: options.onLimit,
159
- });
160
- }
161
- //# sourceMappingURL=artifact-writer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"artifact-writer.js","sourceRoot":"","sources":["../../src/interactive-session/artifact-writer.ts"],"names":[],"mappings":"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"}
@@ -1,36 +0,0 @@
1
- /**
2
- * Identity-safe, single-winner teardown.
3
- *
4
- * Every termination trigger — explicit close, process exit, owner cancellation,
5
- * idle/lifetime timeout, conversation teardown, application shutdown — funnels
6
- * through `FinalizeOnce`, so exactly one execution owns the terminal transition
7
- * and repeated Close returns the recorded result without signalling again.
8
- */
9
- import { type ProcessIdentityComparison } from "../os/process-identity.js";
10
- import type { RecoveryJournal } from "./recovery-journal.js";
11
- import type { SessionRegistry } from "./registry.js";
12
- import type { SessionRuntime } from "./session-runtime.js";
13
- import { type CloseResult, type TerminationReason } from "./types.js";
14
- export interface CleanupDeps {
15
- readonly registry: SessionRegistry;
16
- readonly journal: RecoveryJournal;
17
- readonly onFinalized?: ((runtime: SessionRuntime) => void) | undefined;
18
- readonly process?: Partial<CleanupProcessDeps> | undefined;
19
- }
20
- export interface CleanupProcessDeps {
21
- readonly isAlive: (pid: number | undefined) => boolean;
22
- readonly compareIdentity: (pid: number | undefined, identity: string | undefined) => ProcessIdentityComparison;
23
- readonly hasLiveDescendants: (pid: number) => Promise<boolean>;
24
- }
25
- export declare class CleanupCoordinator {
26
- private readonly deps;
27
- private readonly process;
28
- constructor(deps: CleanupDeps);
29
- /** Idempotent: later callers join the first execution's promise. */
30
- close(runtime: SessionRuntime, reason: TerminationReason, deadlineMs: number): Promise<CloseResult>;
31
- private execute;
32
- private waitForOutputDrain;
33
- private waitForExit;
34
- /** True when a verified descendant or the root is still alive. */
35
- private verifyAbsence;
36
- }
@@ -1,157 +0,0 @@
1
- /**
2
- * Identity-safe, single-winner teardown.
3
- *
4
- * Every termination trigger — explicit close, process exit, owner cancellation,
5
- * idle/lifetime timeout, conversation teardown, application shutdown — funnels
6
- * through `FinalizeOnce`, so exactly one execution owns the terminal transition
7
- * and repeated Close returns the recorded result without signalling again.
8
- */
9
- import { processIdentityTracker, } from "../os/process-identity.js";
10
- import { hasLiveDescendants, processAlive } from "../os/process-tree.js";
11
- import { artifactReference, isTerminalState, sessionError, } from "./types.js";
12
- const POLL_INTERVAL_MS = 50;
13
- const defaultProcessDeps = {
14
- isAlive: processAlive,
15
- compareIdentity: (pid, identity) => processIdentityTracker.compare(pid, identity),
16
- hasLiveDescendants,
17
- };
18
- function delay(ms) {
19
- return new Promise((resolve) => {
20
- const timer = setTimeout(resolve, ms);
21
- timer.unref?.();
22
- });
23
- }
24
- /** Terminal state chosen by the cleanup owner from its winning reason. */
25
- function terminalStateFor(reason, processExited, cleanupFailed) {
26
- if (cleanupFailed)
27
- return "failed";
28
- if (reason === "process-exit" || processExited)
29
- return "exited";
30
- if (reason === "launch-failure")
31
- return "failed";
32
- return "closed";
33
- }
34
- export class CleanupCoordinator {
35
- deps;
36
- process;
37
- constructor(deps) {
38
- this.deps = deps;
39
- this.process = { ...defaultProcessDeps, ...deps.process };
40
- }
41
- /** Idempotent: later callers join the first execution's promise. */
42
- close(runtime, reason, deadlineMs) {
43
- if (isTerminalState(runtime.record.state) && runtime.finalize.started) {
44
- return runtime.finalize.join();
45
- }
46
- return runtime.finalize.run(reason, () => this.execute(runtime, reason, deadlineMs));
47
- }
48
- async execute(runtime, reason, deadlineMs) {
49
- const record = runtime.record;
50
- const started = Date.now();
51
- const remaining = () => Math.max(0, deadlineMs - (Date.now() - started));
52
- // Commit `closing` before any termination action so later input is rejected.
53
- this.deps.registry.transition(record, "closing", { terminationReason: reason });
54
- runtime.input.rejectAll({ status: "not-delivered", deliveredBytes: 0 });
55
- let error;
56
- let cleanupVerified = true;
57
- if (!runtime.processExited && this.process.isAlive(runtime.transport.pid)) {
58
- const identity = this.process.compareIdentity(runtime.transport.pid, runtime.transport.identity);
59
- if (identity === "match") {
60
- await runtime.transport.requestTreeTermination("graceful");
61
- const graceMs = Math.min(runtime.config.gracefulCloseMs, remaining());
62
- await this.waitForExit(runtime, graceMs);
63
- if (!runtime.processExited && this.process.isAlive(runtime.transport.pid)) {
64
- await runtime.transport.requestTreeTermination("forceful");
65
- await this.waitForExit(runtime, remaining());
66
- }
67
- }
68
- else if (identity === "unknown") {
69
- // Ownership is unproven, so signalling could hit a recycled pid.
70
- cleanupVerified = false;
71
- }
72
- // `mismatch` and `gone` mean this pid is no longer ours: nothing to signal.
73
- }
74
- await this.waitForOutputDrain(runtime, remaining());
75
- // Final captured output must reach the store before resources close.
76
- runtime.output.finish();
77
- runtime.syncCursors();
78
- try {
79
- await runtime.artifact.close();
80
- }
81
- catch {
82
- error ??= sessionError({
83
- code: "PERSIST_FAILED",
84
- operation: "close",
85
- sessionId: record.id,
86
- message: "Session output artifact could not be flushed during cleanup.",
87
- details: { artifactPath: runtime.artifact.path },
88
- });
89
- }
90
- const survivors = await this.verifyAbsence(runtime, remaining());
91
- if (survivors) {
92
- cleanupVerified = false;
93
- error ??= sessionError({
94
- code: "CLEANUP_FAILED",
95
- operation: "close",
96
- sessionId: record.id,
97
- message: "A descendant of this interactive session was still alive after the close deadline.",
98
- details: { survivingDescendants: 1, elapsedMs: Date.now() - started },
99
- });
100
- }
101
- runtime.timers.clearAll();
102
- runtime.releaseListeners();
103
- await runtime.transport.dispose();
104
- runtime.output.dispose();
105
- runtime.disposed = true;
106
- this.deps.journal.remove(record.id);
107
- record.artifact = runtime.artifact.receipt();
108
- const state = terminalStateFor(reason, runtime.processExited, error !== undefined);
109
- this.deps.registry.transition(record, state, {
110
- terminationReason: reason,
111
- ...(record.processOutcome ? { processOutcome: record.processOutcome } : {}),
112
- cleanupVerified,
113
- now: Date.now(),
114
- });
115
- this.deps.onFinalized?.(runtime);
116
- return {
117
- operation: "close",
118
- sessionId: record.id,
119
- state: record.state,
120
- ...(record.terminationReason ? { terminationReason: record.terminationReason } : {}),
121
- ...(record.processOutcome ? { processOutcome: record.processOutcome } : {}),
122
- cleanupVerified,
123
- artifact: artifactReference(record.artifact),
124
- ...(error ? { error } : {}),
125
- };
126
- }
127
- async waitForOutputDrain(runtime, budgetMs) {
128
- const wait = runtime.transport.waitForOutputDrain;
129
- if (!wait || budgetMs <= 0)
130
- return;
131
- await Promise.race([wait.call(runtime.transport), delay(budgetMs)]).catch(() => undefined);
132
- }
133
- async waitForExit(runtime, budgetMs) {
134
- const deadline = Date.now() + Math.max(0, budgetMs);
135
- while (Date.now() < deadline) {
136
- if (runtime.processExited || !this.process.isAlive(runtime.transport.pid))
137
- return;
138
- await delay(POLL_INTERVAL_MS);
139
- }
140
- }
141
- /** True when a verified descendant or the root is still alive. */
142
- async verifyAbsence(runtime, budgetMs) {
143
- const pid = runtime.transport.pid;
144
- if (pid <= 0)
145
- return false;
146
- if (this.process.isAlive(pid)) {
147
- const identity = this.process.compareIdentity(pid, runtime.transport.identity);
148
- // A mismatch means the pid was recycled: our process is gone.
149
- if (identity === "match")
150
- return true;
151
- }
152
- if (budgetMs <= 0)
153
- return false;
154
- return await this.process.hasLiveDescendants(pid);
155
- }
156
- }
157
- //# sourceMappingURL=cleanup.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../../src/interactive-session/cleanup.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,sBAAsB,GAEvB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAIzE,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,YAAY,GAKb,MAAM,YAAY,CAAC;AAEpB,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAkB5B,MAAM,kBAAkB,GAAuB;IAC7C,OAAO,EAAE,YAAY;IACrB,eAAe,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,CAAC,sBAAsB,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC;IACjF,kBAAkB;CACnB,CAAC;AAEF,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACtC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,0EAA0E;AAC1E,SAAS,gBAAgB,CACvB,MAAyB,EACzB,aAAsB,EACtB,aAAsB;IAEtB,IAAI,aAAa;QAAE,OAAO,QAAQ,CAAC;IACnC,IAAI,MAAM,KAAK,cAAc,IAAI,aAAa;QAAE,OAAO,QAAQ,CAAC;IAChE,IAAI,MAAM,KAAK,gBAAgB;QAAE,OAAO,QAAQ,CAAC;IACjD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,OAAO,kBAAkB;IAGA;IAFZ,OAAO,CAAqB;IAE7C,YAA6B,IAAiB;QAAjB,SAAI,GAAJ,IAAI,CAAa;QAC5C,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,kBAAkB,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IAC5D,CAAC;IAED,oEAAoE;IACpE,KAAK,CACH,OAAuB,EACvB,MAAyB,EACzB,UAAkB;QAElB,IAAI,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YACtE,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAG,CAAC;QAClC,CAAC;QACD,OAAO,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IACvF,CAAC;IAEO,KAAK,CAAC,OAAO,CACnB,OAAuB,EACvB,MAAyB,EACzB,UAAkB;QAElB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;QAEjF,6EAA6E;QAC7E,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,iBAAiB,EAAE,MAAM,EAAE,CAAC,CAAC;QAEhF,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC;QAExE,IAAI,KAA8B,CAAC;QACnC,IAAI,eAAe,GAAG,IAAI,CAAC;QAE3B,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1E,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAC3C,OAAO,CAAC,SAAS,CAAC,GAAG,EACrB,OAAO,CAAC,SAAS,CAAC,QAAQ,CAC3B,CAAC;YACF,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;gBACzB,MAAM,OAAO,CAAC,SAAS,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC;gBAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,SAAS,EAAE,CAAC,CAAC;gBACtE,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBACzC,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC1E,MAAM,OAAO,CAAC,SAAS,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC;oBAC3D,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC;iBAAM,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAClC,iEAAiE;gBACjE,eAAe,GAAG,KAAK,CAAC;YAC1B,CAAC;YACD,4EAA4E;QAC9E,CAAC;QAED,MAAM,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;QAEpD,qEAAqE;QACrE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACxB,OAAO,CAAC,WAAW,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,KAAK,KAAK,YAAY,CAAC;gBACrB,IAAI,EAAE,gBAAgB;gBACtB,SAAS,EAAE,OAAO;gBAClB,SAAS,EAAE,MAAM,CAAC,EAAE;gBACpB,OAAO,EAAE,8DAA8D;gBACvE,OAAO,EAAE,EAAE,YAAY,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;aACjD,CAAC,CAAC;QACL,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;QACjE,IAAI,SAAS,EAAE,CAAC;YACd,eAAe,GAAG,KAAK,CAAC;YACxB,KAAK,KAAK,YAAY,CAAC;gBACrB,IAAI,EAAE,gBAAgB;gBACtB,SAAS,EAAE,OAAO;gBAClB,SAAS,EAAE,MAAM,CAAC,EAAE;gBACpB,OAAO,EACL,oFAAoF;gBACtF,OAAO,EAAE,EAAE,oBAAoB,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE;aACtE,CAAC,CAAC;QACL,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC1B,OAAO,CAAC,gBAAgB,EAAE,CAAC;QAC3B,MAAM,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QAClC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACzB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAEpC,MAAM,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC;QACnF,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE;YAC3C,iBAAiB,EAAE,MAAM;YACzB,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3E,eAAe;YACf,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE;SAChB,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,CAAC;QAEjC,OAAO;YACL,SAAS,EAAE,OAAO;YAClB,SAAS,EAAE,MAAM,CAAC,EAAE;YACpB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpF,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3E,eAAe;YACf,QAAQ,EAAE,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC;YAC5C,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5B,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,OAAuB,EAAE,QAAgB;QACxE,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,kBAAkB,CAAC;QAClD,IAAI,CAAC,IAAI,IAAI,QAAQ,IAAI,CAAC;YAAE,OAAO;QACnC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC7F,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,OAAuB,EAAE,QAAgB;QACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;YAC7B,IAAI,OAAO,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC;gBAAE,OAAO;YAClF,MAAM,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,kEAAkE;IAC1D,KAAK,CAAC,aAAa,CACzB,OAAuB,EACvB,QAAgB;QAEhB,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC;QAClC,IAAI,GAAG,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QAC3B,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAC/E,8DAA8D;YAC9D,IAAI,QAAQ,KAAK,OAAO;gBAAE,OAAO,IAAI,CAAC;QACxC,CAAC;QACD,IAAI,QAAQ,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QAChC,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACpD,CAAC;CACF"}
@@ -1,118 +0,0 @@
1
- /**
2
- * Interactive-session configuration: documented defaults, validated ranges, and
3
- * a runtime kill switch. Every value is validated before a slot is reserved or a
4
- * process is launched so an out-of-range setting can never produce a live child.
5
- */
6
- import { type SessionOperation, type TerminalDimensions } from "./types.js";
7
- export interface InteractiveSessionConfig {
8
- enabled: boolean;
9
- liveSessionLimit: number;
10
- quietIntervalMs: number;
11
- startDeadlineMs: number;
12
- sendDeadlineMs: number;
13
- closeDeadlineMs: number;
14
- gracefulCloseMs: number;
15
- pageBytes: number;
16
- memoryWindowBytes: number;
17
- queuedInputBytes: number;
18
- artifactCaptureBytes: number;
19
- artifactChunkBytes: number;
20
- persistenceQueueBytes: number;
21
- /** Undefined disables the timeout. */
22
- idleTimeoutMs: number | undefined;
23
- lifetimeTimeoutMs: number | undefined;
24
- /** Behavior when artifact capture reaches its limit. */
25
- onOutputLimit: "terminate" | "continue";
26
- /** Max bytes retained for cross-chunk secret matching. */
27
- redactionOverlapBytes: number;
28
- }
29
- interface Range {
30
- readonly min: number;
31
- readonly max: number;
32
- }
33
- export declare const INTERACTIVE_SESSION_RANGES: {
34
- readonly liveSessionLimit: {
35
- readonly min: 1;
36
- readonly max: 32;
37
- };
38
- readonly quietIntervalMs: {
39
- readonly min: 25;
40
- readonly max: 5000;
41
- };
42
- readonly startDeadlineMs: {
43
- readonly min: 100;
44
- readonly max: 120000;
45
- };
46
- readonly sendDeadlineMs: {
47
- readonly min: 100;
48
- readonly max: 120000;
49
- };
50
- readonly closeDeadlineMs: {
51
- readonly min: 100;
52
- readonly max: 120000;
53
- };
54
- readonly gracefulCloseMs: {
55
- readonly min: 0;
56
- readonly max: 30000;
57
- };
58
- readonly pageBytes: {
59
- readonly min: 1024;
60
- readonly max: 1048576;
61
- };
62
- readonly memoryWindowBytes: {
63
- readonly min: 65536;
64
- readonly max: 16777216;
65
- };
66
- readonly queuedInputBytes: {
67
- readonly min: 1024;
68
- readonly max: 1048576;
69
- };
70
- readonly artifactCaptureBytes: {
71
- readonly min: 1048576;
72
- readonly max: 1073741824;
73
- };
74
- readonly artifactChunkBytes: {
75
- readonly min: 65536;
76
- readonly max: 16777216;
77
- };
78
- readonly persistenceQueueBytes: {
79
- readonly min: 65536;
80
- readonly max: 16777216;
81
- };
82
- readonly idleTimeoutMs: {
83
- readonly min: 1000;
84
- readonly max: 86400000;
85
- };
86
- readonly lifetimeTimeoutMs: {
87
- readonly min: 1000;
88
- readonly max: 604800000;
89
- };
90
- readonly redactionOverlapBytes: {
91
- readonly min: 256;
92
- readonly max: 65536;
93
- };
94
- };
95
- export type RangedConfigField = keyof typeof INTERACTIVE_SESSION_RANGES;
96
- export declare const DIMENSION_RANGE: Range;
97
- export declare const DEFAULT_DIMENSIONS: TerminalDimensions;
98
- /** Hard cap for a blocking read wait, independent of send deadlines. */
99
- export declare const MAX_READ_WAIT_MS = 30000;
100
- export declare const MAX_LIST_SUMMARIES = 50;
101
- export declare const INTERACTIVE_SESSION_DEFAULTS: InteractiveSessionConfig;
102
- /** Env kill switch. Disables only the seven interactive tools. */
103
- export declare const KILL_SWITCH_ENV = "CLAI_DISABLE_INTERACTIVE_SESSIONS";
104
- export type InteractiveSessionOverrides = Partial<InteractiveSessionConfig>;
105
- /**
106
- * Resolve the effective configuration. Throws `INVALID_CONFIGURATION` for any
107
- * out-of-range value so callers fail before allocating resources.
108
- */
109
- export declare function resolveInteractiveSessionConfig(overrides?: InteractiveSessionOverrides, operation?: SessionOperation): InteractiveSessionConfig;
110
- export declare function isInteractiveSessionsEnabled(config?: InteractiveSessionConfig): boolean;
111
- /** Per-operation timeout override, validated against the same bounds. */
112
- export declare function resolveDeadline(field: "startDeadlineMs" | "sendDeadlineMs" | "closeDeadlineMs", override: number | undefined, config: InteractiveSessionConfig, operation: SessionOperation): number;
113
- export declare function resolveQuietInterval(override: number | undefined, config: InteractiveSessionConfig, operation: SessionOperation): number;
114
- export declare function resolveOptionalTimeout(field: "idleTimeoutMs" | "lifetimeTimeoutMs", override: number | undefined, config: InteractiveSessionConfig, operation: SessionOperation): number | undefined;
115
- /** Validate requested dimensions before any lookup or process mutation. */
116
- export declare function resolveDimensions(columns: number | undefined, rows: number | undefined, operation: SessionOperation): TerminalDimensions;
117
- export declare function clampReadWait(waitMs: number | undefined): number;
118
- export {};
@@ -1,141 +0,0 @@
1
- /**
2
- * Interactive-session configuration: documented defaults, validated ranges, and
3
- * a runtime kill switch. Every value is validated before a slot is reserved or a
4
- * process is launched so an out-of-range setting can never produce a live child.
5
- */
6
- import { throwSessionError, } from "./types.js";
7
- export const INTERACTIVE_SESSION_RANGES = {
8
- liveSessionLimit: { min: 1, max: 32 },
9
- quietIntervalMs: { min: 25, max: 5_000 },
10
- startDeadlineMs: { min: 100, max: 120_000 },
11
- sendDeadlineMs: { min: 100, max: 120_000 },
12
- closeDeadlineMs: { min: 100, max: 120_000 },
13
- gracefulCloseMs: { min: 0, max: 30_000 },
14
- pageBytes: { min: 1_024, max: 1_048_576 },
15
- memoryWindowBytes: { min: 65_536, max: 16_777_216 },
16
- queuedInputBytes: { min: 1_024, max: 1_048_576 },
17
- artifactCaptureBytes: { min: 1_048_576, max: 1_073_741_824 },
18
- artifactChunkBytes: { min: 65_536, max: 16_777_216 },
19
- persistenceQueueBytes: { min: 65_536, max: 16_777_216 },
20
- idleTimeoutMs: { min: 1_000, max: 86_400_000 },
21
- lifetimeTimeoutMs: { min: 1_000, max: 604_800_000 },
22
- redactionOverlapBytes: { min: 256, max: 65_536 },
23
- };
24
- export const DIMENSION_RANGE = { min: 2, max: 1_000 };
25
- export const DEFAULT_DIMENSIONS = { columns: 80, rows: 24 };
26
- /** Hard cap for a blocking read wait, independent of send deadlines. */
27
- export const MAX_READ_WAIT_MS = 30_000;
28
- export const MAX_LIST_SUMMARIES = 50;
29
- export const INTERACTIVE_SESSION_DEFAULTS = {
30
- enabled: true,
31
- liveSessionLimit: 4,
32
- quietIntervalMs: 250,
33
- startDeadlineMs: 10_000,
34
- sendDeadlineMs: 30_000,
35
- closeDeadlineMs: 10_000,
36
- gracefulCloseMs: 2_000,
37
- pageBytes: 12_000,
38
- memoryWindowBytes: 1_048_576,
39
- queuedInputBytes: 65_536,
40
- artifactCaptureBytes: 67_108_864,
41
- artifactChunkBytes: 1_048_576,
42
- persistenceQueueBytes: 1_048_576,
43
- idleTimeoutMs: undefined,
44
- lifetimeTimeoutMs: undefined,
45
- onOutputLimit: "terminate",
46
- redactionOverlapBytes: 4_096,
47
- };
48
- /** Env kill switch. Disables only the seven interactive tools. */
49
- export const KILL_SWITCH_ENV = "CLAI_DISABLE_INTERACTIVE_SESSIONS";
50
- function envDisabled() {
51
- const raw = process.env[KILL_SWITCH_ENV];
52
- if (raw === undefined)
53
- return false;
54
- const normalized = raw.trim().toLowerCase();
55
- return normalized === "1" || normalized === "true" || normalized === "yes";
56
- }
57
- function invalid(field, message, operation) {
58
- throwSessionError({
59
- code: "INVALID_CONFIGURATION",
60
- operation,
61
- message,
62
- details: { field },
63
- });
64
- }
65
- function checkRange(field, value, operation) {
66
- const { min, max } = INTERACTIVE_SESSION_RANGES[field];
67
- if (!Number.isInteger(value) || value < min || value > max) {
68
- invalid(field, `${field} must be an integer between ${min} and ${max}.`, operation);
69
- }
70
- return value;
71
- }
72
- /**
73
- * Resolve the effective configuration. Throws `INVALID_CONFIGURATION` for any
74
- * out-of-range value so callers fail before allocating resources.
75
- */
76
- export function resolveInteractiveSessionConfig(overrides = {}, operation = "start") {
77
- const merged = { ...INTERACTIVE_SESSION_DEFAULTS, ...overrides };
78
- for (const field of Object.keys(INTERACTIVE_SESSION_RANGES)) {
79
- const value = merged[field];
80
- if (value === undefined)
81
- continue;
82
- if (typeof value !== "number") {
83
- invalid(field, `${field} must be a number.`, operation);
84
- }
85
- checkRange(field, value, operation);
86
- }
87
- if (merged.artifactChunkBytes > merged.artifactCaptureBytes) {
88
- invalid("artifactChunkBytes", "artifactChunkBytes cannot exceed artifactCaptureBytes.", operation);
89
- }
90
- if (merged.onOutputLimit !== "terminate" && merged.onOutputLimit !== "continue") {
91
- invalid("onOutputLimit", "onOutputLimit must be terminate or continue.", operation);
92
- }
93
- return { ...merged, enabled: merged.enabled && !envDisabled() };
94
- }
95
- export function isInteractiveSessionsEnabled(config = resolveInteractiveSessionConfig()) {
96
- return config.enabled;
97
- }
98
- /** Per-operation timeout override, validated against the same bounds. */
99
- export function resolveDeadline(field, override, config, operation) {
100
- if (override === undefined)
101
- return config[field];
102
- return checkRange(field, override, operation);
103
- }
104
- export function resolveQuietInterval(override, config, operation) {
105
- if (override === undefined)
106
- return config.quietIntervalMs;
107
- return checkRange("quietIntervalMs", override, operation);
108
- }
109
- export function resolveOptionalTimeout(field, override, config, operation) {
110
- if (override === undefined)
111
- return config[field];
112
- return checkRange(field, override, operation);
113
- }
114
- /** Validate requested dimensions before any lookup or process mutation. */
115
- export function resolveDimensions(columns, rows, operation) {
116
- const resolved = {
117
- columns: columns ?? DEFAULT_DIMENSIONS.columns,
118
- rows: rows ?? DEFAULT_DIMENSIONS.rows,
119
- };
120
- for (const [field, value] of Object.entries(resolved)) {
121
- if (!Number.isInteger(value) ||
122
- value < DIMENSION_RANGE.min ||
123
- value > DIMENSION_RANGE.max) {
124
- throwSessionError({
125
- code: "INVALID_REQUEST",
126
- operation,
127
- message: `${field} must be an integer between ${DIMENSION_RANGE.min} and ${DIMENSION_RANGE.max}.`,
128
- details: { field },
129
- });
130
- }
131
- }
132
- return resolved;
133
- }
134
- export function clampReadWait(waitMs) {
135
- if (waitMs === undefined)
136
- return 0;
137
- if (!Number.isFinite(waitMs) || waitMs < 0)
138
- return 0;
139
- return Math.min(Math.floor(waitMs), MAX_READ_WAIT_MS);
140
- }
141
- //# sourceMappingURL=config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/interactive-session/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,iBAAiB,GAGlB,MAAM,YAAY,CAAC;AA8BpB,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,gBAAgB,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IACrC,eAAe,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE;IACxC,eAAe,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE;IAC3C,cAAc,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE;IAC1C,eAAe,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE;IAC3C,eAAe,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE;IACxC,SAAS,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE;IACzC,iBAAiB,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE;IACnD,gBAAgB,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE;IAChD,oBAAoB,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,EAAE;IAC5D,kBAAkB,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE;IACpD,qBAAqB,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE;IACvD,aAAa,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE;IAC9C,iBAAiB,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE;IACnD,qBAAqB,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE;CACR,CAAC;AAI3C,MAAM,CAAC,MAAM,eAAe,GAAU,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;AAC7D,MAAM,CAAC,MAAM,kBAAkB,GAAuB,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AAChF,wEAAwE;AACxE,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AACvC,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAErC,MAAM,CAAC,MAAM,4BAA4B,GAA6B;IACpE,OAAO,EAAE,IAAI;IACb,gBAAgB,EAAE,CAAC;IACnB,eAAe,EAAE,GAAG;IACpB,eAAe,EAAE,MAAM;IACvB,cAAc,EAAE,MAAM;IACtB,eAAe,EAAE,MAAM;IACvB,eAAe,EAAE,KAAK;IACtB,SAAS,EAAE,MAAM;IACjB,iBAAiB,EAAE,SAAS;IAC5B,gBAAgB,EAAE,MAAM;IACxB,oBAAoB,EAAE,UAAU;IAChC,kBAAkB,EAAE,SAAS;IAC7B,qBAAqB,EAAE,SAAS;IAChC,aAAa,EAAE,SAAS;IACxB,iBAAiB,EAAE,SAAS;IAC5B,aAAa,EAAE,WAAW;IAC1B,qBAAqB,EAAE,KAAK;CAC7B,CAAC;AAEF,kEAAkE;AAClE,MAAM,CAAC,MAAM,eAAe,GAAG,mCAAmC,CAAC;AAEnE,SAAS,WAAW;IAClB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACzC,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACpC,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5C,OAAO,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,KAAK,CAAC;AAC7E,CAAC;AAED,SAAS,OAAO,CACd,KAAa,EACb,OAAe,EACf,SAA2B;IAE3B,iBAAiB,CAAC;QAChB,IAAI,EAAE,uBAAuB;QAC7B,SAAS;QACT,OAAO;QACP,OAAO,EAAE,EAAE,KAAK,EAAE;KACnB,CAAC,CAAC;AACL,CAAC;AAED,SAAS,UAAU,CACjB,KAAwB,EACxB,KAAa,EACb,SAA2B;IAE3B,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,0BAA0B,CAAC,KAAK,CAAC,CAAC;IACvD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;QAC3D,OAAO,CACL,KAAK,EACL,GAAG,KAAK,+BAA+B,GAAG,QAAQ,GAAG,GAAG,EACxD,SAAS,CACV,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAID;;;GAGG;AACH,MAAM,UAAU,+BAA+B,CAC7C,YAAyC,EAAE,EAC3C,YAA8B,OAAO;IAErC,MAAM,MAAM,GAAG,EAAE,GAAG,4BAA4B,EAAE,GAAG,SAAS,EAAE,CAAC;IACjE,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAwB,EAAE,CAAC;QACnF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,CAAC,KAAK,EAAE,GAAG,KAAK,oBAAoB,EAAE,SAAS,CAAC,CAAC;QAC1D,CAAC;QACD,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IACtC,CAAC;IACD,IAAI,MAAM,CAAC,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,EAAE,CAAC;QAC5D,OAAO,CACL,oBAAoB,EACpB,wDAAwD,EACxD,SAAS,CACV,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,aAAa,KAAK,WAAW,IAAI,MAAM,CAAC,aAAa,KAAK,UAAU,EAAE,CAAC;QAChF,OAAO,CAAC,eAAe,EAAE,8CAA8C,EAAE,SAAS,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,SAAmC,+BAA+B,EAAE;IAEpE,OAAO,MAAM,CAAC,OAAO,CAAC;AACxB,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,eAAe,CAC7B,KAA+D,EAC/D,QAA4B,EAC5B,MAAgC,EAChC,SAA2B;IAE3B,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACjD,OAAO,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,QAA4B,EAC5B,MAAgC,EAChC,SAA2B;IAE3B,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,eAAe,CAAC;IAC1D,OAAO,UAAU,CAAC,iBAAiB,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,KAA4C,EAC5C,QAA4B,EAC5B,MAAgC,EAChC,SAA2B;IAE3B,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACjD,OAAO,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AAChD,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,iBAAiB,CAC/B,OAA2B,EAC3B,IAAwB,EACxB,SAA2B;IAE3B,MAAM,QAAQ,GAAG;QACf,OAAO,EAAE,OAAO,IAAI,kBAAkB,CAAC,OAAO;QAC9C,IAAI,EAAE,IAAI,IAAI,kBAAkB,CAAC,IAAI;KACtC,CAAC;IACF,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtD,IACE,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;YACxB,KAAK,GAAG,eAAe,CAAC,GAAG;YAC3B,KAAK,GAAG,eAAe,CAAC,GAAG,EAC3B,CAAC;YACD,iBAAiB,CAAC;gBAChB,IAAI,EAAE,iBAAiB;gBACvB,SAAS;gBACT,OAAO,EAAE,GAAG,KAAK,+BAA+B,eAAe,CAAC,GAAG,QAAQ,eAAe,CAAC,GAAG,GAAG;gBACjG,OAAO,EAAE,EAAE,KAAK,EAAE;aACnB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAA0B;IACtD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IACrD,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC,CAAC;AACxD,CAAC"}