@descryy/runtime-orchestrator 0.4.8 → 0.4.9
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.
- package/package.json +6 -6
- package/dist/attach-to-running-jvm-process.d.ts +0 -86
- package/dist/attach-to-running-jvm-process.d.ts.map +0 -1
- package/dist/attach-to-running-jvm-process.js +0 -408
- package/dist/attach-to-running-jvm-process.js.map +0 -1
- package/dist/attach-to-running-node-process.d.ts +0 -80
- package/dist/attach-to-running-node-process.d.ts.map +0 -1
- package/dist/attach-to-running-node-process.js +0 -290
- package/dist/attach-to-running-node-process.js.map +0 -1
- package/dist/attach-to-running-process.d.ts +0 -83
- package/dist/attach-to-running-process.d.ts.map +0 -1
- package/dist/attach-to-running-process.js +0 -86
- package/dist/attach-to-running-process.js.map +0 -1
- package/dist/cdp-client.d.ts +0 -27
- package/dist/cdp-client.d.ts.map +0 -1
- package/dist/cdp-client.js +0 -98
- package/dist/cdp-client.js.map +0 -1
- package/dist/cgroup-partial-restriction.d.ts +0 -80
- package/dist/cgroup-partial-restriction.d.ts.map +0 -1
- package/dist/cgroup-partial-restriction.js +0 -189
- package/dist/cgroup-partial-restriction.js.map +0 -1
- package/dist/collector-version.d.ts +0 -7
- package/dist/collector-version.d.ts.map +0 -1
- package/dist/collector-version.js +0 -9
- package/dist/collector-version.js.map +0 -1
- package/dist/index.d.ts +0 -19
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -10
- package/dist/index.js.map +0 -1
- package/dist/instrumented-execution.d.ts +0 -135
- package/dist/instrumented-execution.d.ts.map +0 -1
- package/dist/instrumented-execution.js +0 -696
- package/dist/instrumented-execution.js.map +0 -1
- package/dist/jvm-agent/build.d.ts +0 -48
- package/dist/jvm-agent/build.d.ts.map +0 -1
- package/dist/jvm-agent/build.js +0 -129
- package/dist/jvm-agent/build.js.map +0 -1
- package/dist/polling-output-source.d.ts +0 -43
- package/dist/polling-output-source.d.ts.map +0 -1
- package/dist/polling-output-source.js +0 -64
- package/dist/polling-output-source.js.map +0 -1
- package/dist/profile-backend-observation.d.ts +0 -67
- package/dist/profile-backend-observation.d.ts.map +0 -1
- package/dist/profile-backend-observation.js +0 -107
- package/dist/profile-backend-observation.js.map +0 -1
- package/dist/respawn-and-supervise.d.ts +0 -86
- package/dist/respawn-and-supervise.d.ts.map +0 -1
- package/dist/respawn-and-supervise.js +0 -171
- package/dist/respawn-and-supervise.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@descryy/runtime-orchestrator",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Assembles the runtime: controller-spawned services, live process output, collectors from a RuntimeAdapter, and a CollectorContext that can resolve script origins to source roots.",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -25,13 +25,10 @@
|
|
|
25
25
|
"registry": "https://registry.npmjs.org",
|
|
26
26
|
"access": "public"
|
|
27
27
|
},
|
|
28
|
-
"scripts": {
|
|
29
|
-
"build": "tsc -b"
|
|
30
|
-
},
|
|
31
28
|
"dependencies": {
|
|
32
29
|
"@descryy/runtime-contracts": "0.3.3",
|
|
33
30
|
"@descryy/runtime-backend-observation": "0.3.6",
|
|
34
|
-
"@descryy/runtime-controller": "0.3.
|
|
31
|
+
"@descryy/runtime-controller": "0.3.8",
|
|
35
32
|
"@descryy/runtime-evidence-store": "0.4.2",
|
|
36
33
|
"@descryy/runtime-adapter-typescript": "0.3.7",
|
|
37
34
|
"@descryy/runtime-environment-profile": "0.4.5",
|
|
@@ -47,5 +44,8 @@
|
|
|
47
44
|
"@descryy/runtime-adapter-ruby": "0.0.4",
|
|
48
45
|
"@descryy/runtime-adapter-rust": "0.1.5",
|
|
49
46
|
"@descryy/runtime-adapter-swift": "0.1.5"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsc -b"
|
|
50
50
|
}
|
|
51
|
-
}
|
|
51
|
+
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Retroactive attach to an already-running **JVM (Java/Kotlin/…)** process. Not a
|
|
3
|
-
* full CDP-equivalent; see `RT-attach-to-running-jvm-process.md` (decisions-inbox)
|
|
4
|
-
* for what was measured before this was written.
|
|
5
|
-
*
|
|
6
|
-
* **Mechanism, measured against a live JVM, not assumed from docs.** The JVM has
|
|
7
|
-
* no `SIGUSR1`-equivalent, but ships (since JDK 6) HotSpot Dynamic Attach:
|
|
8
|
-
* `VirtualMachine.attach(pid)` creates `.attach_pid<pid>`, signals `SIGQUIT`, and
|
|
9
|
-
* the target's attach-listener thread (already running in every stock HotSpot
|
|
10
|
-
* JVM, nothing to enable at launch) opens a Unix socket at `.java_pid<pid>` and
|
|
11
|
-
* accepts commands — the same thing `jcmd`/`jstack`/`VisualVM` use. Measured:
|
|
12
|
-
* attached to a plain `java QuietServer` with no special flags and no restart,
|
|
13
|
-
* confirming this is genuinely retroactive.
|
|
14
|
-
*
|
|
15
|
-
* **Narrower than CDP.** `VirtualMachine.loadAgent(jar, args)` loads a real Java
|
|
16
|
-
* agent (`Instrumentation`) — more powerful than CDP's remote-debugging protocol
|
|
17
|
-
* in principle, but this slice only uses `Thread.setDefaultUncaughtExceptionHandler`
|
|
18
|
-
* (`jvm-agent/Agent.java`), so it never sees an exception a framework already
|
|
19
|
-
* caught (a try/catch, a servlet error page, `@ExceptionHandler`). RT-201 closed
|
|
20
|
-
* one specific instance of that gap: `Agent.java` also installs a ByteBuddy
|
|
21
|
-
* `ClassFileTransformer` tapping
|
|
22
|
-
* `DispatcherServlet#processHandlerException` — Spring MVC's single stable
|
|
23
|
-
* exception choke point — reported as `"framework-caught-exception"`, parsed
|
|
24
|
-
* below and emitted with `payload.handled === true`. This closes only that one
|
|
25
|
-
* choke point: a catch absorbed inside a `@Service` method, or any non-Spring
|
|
26
|
-
* framework, is still invisible.
|
|
27
|
-
*
|
|
28
|
-
* **No console-output capture** — `System.out`/`err` aren't intercepted; that's
|
|
29
|
-
* `attachToRunningProcess`'s job for a target already logging to a file.
|
|
30
|
-
* `capabilities()` reports `backendLogAccess` unavailable for that reason.
|
|
31
|
-
*
|
|
32
|
-
* **Launcher is a real JDK tool process, not a library call** — no Node/native
|
|
33
|
-
* Attach-API binding exists or is added. `jvm-agent/build.ts` compiles
|
|
34
|
-
* `Attacher.java` once (mtime-cached) and this module spawns it as a short-lived
|
|
35
|
-
* `java` child process.
|
|
36
|
-
*/
|
|
37
|
-
import type { Collector } from "@descryy/runtime-contracts";
|
|
38
|
-
export interface AttachToRunningJvmProcessOptions {
|
|
39
|
-
readonly processId: string;
|
|
40
|
-
/** The pid of the already-running target JVM. Verified alive before attach is attempted, and never spawned or supervised by this collector. */
|
|
41
|
-
readonly pid: number;
|
|
42
|
-
readonly service?: string;
|
|
43
|
-
/** How long to wait for the Attacher helper process to complete the attach + loadAgent call. The attach itself is normally sub-second; generous default for a loaded machine. */
|
|
44
|
-
readonly attachTimeoutMs?: number;
|
|
45
|
-
/** How often to check the agent's output file for new events. */
|
|
46
|
-
readonly pollIntervalMs?: number;
|
|
47
|
-
/**
|
|
48
|
-
* Repo-relative source roots plus the absolute repo root, so a JVM frame's bare
|
|
49
|
-
* basename can be reconstructed into a repo-relative path graph correlation can
|
|
50
|
-
* join on (RT-202, extending RT-162's fix from the log-tailing path to this one).
|
|
51
|
-
*
|
|
52
|
-
* The JVM prints a bare basename (`ProbeApplication.java`), never a path, so
|
|
53
|
-
* `resolveSymbolNode` refuses to match on it alone (RT-031). This collector builds
|
|
54
|
-
* `StackFrame.location` straight from the agent's captured `StackTraceElement`
|
|
55
|
-
* fields, bypassing `createJvmStackTraceParser` entirely, so RT-162's earlier fix
|
|
56
|
-
* there never reached this path — invisible until RT-202, since this mechanism's
|
|
57
|
-
* only prior fixture was in the default package, where reconstruction is a no-op.
|
|
58
|
-
*
|
|
59
|
-
* `reconstructJvmSourcePath` below is a deliberate second copy of
|
|
60
|
-
* `jvm-stack-trace-parser.ts`'s algorithm, not a shared import: this package
|
|
61
|
-
* never takes a real dependency on any `@descryy/runtime-adapter-*` package
|
|
62
|
-
* (JVM's included), and importing the JVM-specific function here would be a
|
|
63
|
-
* bigger architectural change than this gap warrants. Both copies are tiny,
|
|
64
|
-
* pure, and named after the one behaviour they implement.
|
|
65
|
-
*/
|
|
66
|
-
readonly sourceRoots?: {
|
|
67
|
-
readonly repoRoot: string;
|
|
68
|
-
readonly roots: readonly string[];
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Attach to an already-running JVM process via the HotSpot Dynamic Attach
|
|
73
|
-
* mechanism, load a minimal Java agent, and start capturing genuinely
|
|
74
|
-
* uncaught exceptions as `EXCEPTION` evidence from that moment forward.
|
|
75
|
-
*
|
|
76
|
-
* **Retroactive, not historical** — same as the Node slice: an exception
|
|
77
|
-
* thrown before the agent finishes loading is not captured, because the
|
|
78
|
-
* default handler was not installed yet. There is no backlog to catch up on.
|
|
79
|
-
*
|
|
80
|
-
* Discovery, build, and attach all happen inside `start()`, matching every
|
|
81
|
-
* other `Collector` in this repo — a routine failure to attach resolves as
|
|
82
|
-
* `{ available: false, reason }`, never a thrown exception a caller has to
|
|
83
|
-
* remember to catch.
|
|
84
|
-
*/
|
|
85
|
-
export declare function attachToRunningJvmProcess(options: AttachToRunningJvmProcessOptions): Collector;
|
|
86
|
-
//# sourceMappingURL=attach-to-running-jvm-process.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"attach-to-running-jvm-process.d.ts","sourceRoot":"","sources":["../src/attach-to-running-jvm-process.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAOH,OAAO,KAAK,EAAE,SAAS,EAAyF,MAAM,4BAA4B,CAAC;AAMnJ,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,+IAA+I;IAC/I,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,iLAAiL;IACjL,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,iEAAiE;IACjE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;;;;;;;;;;;;;;;;;OAkBG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE;QACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;KACnC,CAAC;CACH;AAoLD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gCAAgC,GAAG,SAAS,CA0N9F"}
|
|
@@ -1,408 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Retroactive attach to an already-running **JVM (Java/Kotlin/…)** process. Not a
|
|
3
|
-
* full CDP-equivalent; see `RT-attach-to-running-jvm-process.md` (decisions-inbox)
|
|
4
|
-
* for what was measured before this was written.
|
|
5
|
-
*
|
|
6
|
-
* **Mechanism, measured against a live JVM, not assumed from docs.** The JVM has
|
|
7
|
-
* no `SIGUSR1`-equivalent, but ships (since JDK 6) HotSpot Dynamic Attach:
|
|
8
|
-
* `VirtualMachine.attach(pid)` creates `.attach_pid<pid>`, signals `SIGQUIT`, and
|
|
9
|
-
* the target's attach-listener thread (already running in every stock HotSpot
|
|
10
|
-
* JVM, nothing to enable at launch) opens a Unix socket at `.java_pid<pid>` and
|
|
11
|
-
* accepts commands — the same thing `jcmd`/`jstack`/`VisualVM` use. Measured:
|
|
12
|
-
* attached to a plain `java QuietServer` with no special flags and no restart,
|
|
13
|
-
* confirming this is genuinely retroactive.
|
|
14
|
-
*
|
|
15
|
-
* **Narrower than CDP.** `VirtualMachine.loadAgent(jar, args)` loads a real Java
|
|
16
|
-
* agent (`Instrumentation`) — more powerful than CDP's remote-debugging protocol
|
|
17
|
-
* in principle, but this slice only uses `Thread.setDefaultUncaughtExceptionHandler`
|
|
18
|
-
* (`jvm-agent/Agent.java`), so it never sees an exception a framework already
|
|
19
|
-
* caught (a try/catch, a servlet error page, `@ExceptionHandler`). RT-201 closed
|
|
20
|
-
* one specific instance of that gap: `Agent.java` also installs a ByteBuddy
|
|
21
|
-
* `ClassFileTransformer` tapping
|
|
22
|
-
* `DispatcherServlet#processHandlerException` — Spring MVC's single stable
|
|
23
|
-
* exception choke point — reported as `"framework-caught-exception"`, parsed
|
|
24
|
-
* below and emitted with `payload.handled === true`. This closes only that one
|
|
25
|
-
* choke point: a catch absorbed inside a `@Service` method, or any non-Spring
|
|
26
|
-
* framework, is still invisible.
|
|
27
|
-
*
|
|
28
|
-
* **No console-output capture** — `System.out`/`err` aren't intercepted; that's
|
|
29
|
-
* `attachToRunningProcess`'s job for a target already logging to a file.
|
|
30
|
-
* `capabilities()` reports `backendLogAccess` unavailable for that reason.
|
|
31
|
-
*
|
|
32
|
-
* **Launcher is a real JDK tool process, not a library call** — no Node/native
|
|
33
|
-
* Attach-API binding exists or is added. `jvm-agent/build.ts` compiles
|
|
34
|
-
* `Attacher.java` once (mtime-cached) and this module spawns it as a short-lived
|
|
35
|
-
* `java` child process.
|
|
36
|
-
*/
|
|
37
|
-
import { existsSync, mkdtempSync, readFileSync, writeFileSync, rmSync } from "node:fs";
|
|
38
|
-
import { tmpdir } from "node:os";
|
|
39
|
-
import { join } from "node:path";
|
|
40
|
-
import { spawnSync } from "node:child_process";
|
|
41
|
-
import { isProcessAlive } from "./attach-to-running-process.js";
|
|
42
|
-
import { buildJvmAgentJar, buildAttacherClass, findToolsJarIfPresent } from "./jvm-agent/build.js";
|
|
43
|
-
import { COLLECTOR_VERSION } from "./collector-version.js";
|
|
44
|
-
/**
|
|
45
|
-
* Reconstructs a repo-relative source path from a JVM frame's fully-qualified
|
|
46
|
-
* declaring class name and basename, or `null` when it can't be done exactly
|
|
47
|
-
* (no source roots, no basename, default-package class, or no candidate exists
|
|
48
|
-
* on disk). See `sourceRoots` doc above for why this duplicates
|
|
49
|
-
* `jvm-stack-trace-parser.ts`'s `reconstructPath` rather than importing it.
|
|
50
|
-
*/
|
|
51
|
-
function reconstructJvmSourcePath(declaringType, file, sourceRoots) {
|
|
52
|
-
if (sourceRoots === undefined || file === null)
|
|
53
|
-
return null;
|
|
54
|
-
if (file.includes("/"))
|
|
55
|
-
return null;
|
|
56
|
-
const lastDot = declaringType.lastIndexOf(".");
|
|
57
|
-
if (lastDot === -1)
|
|
58
|
-
return null;
|
|
59
|
-
const packagePath = declaringType.slice(0, lastDot).split(".").join("/");
|
|
60
|
-
for (const root of sourceRoots.roots) {
|
|
61
|
-
const candidate = `${root}/${packagePath}/${file}`;
|
|
62
|
-
if (existsSync(join(sourceRoots.repoRoot, candidate)))
|
|
63
|
-
return candidate;
|
|
64
|
-
}
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
function isUncaughtExceptionEvent(value) {
|
|
68
|
-
return typeof value === "object" && value !== null && value.type === "uncaught-exception";
|
|
69
|
-
}
|
|
70
|
-
function isFrameworkCaughtExceptionEvent(value) {
|
|
71
|
-
return typeof value === "object" && value !== null && value.type === "framework-caught-exception";
|
|
72
|
-
}
|
|
73
|
-
/** A-F8: target's writer thread confirming detach completed (see `Agent.java`'s `detach()`); `stop()`'s poll loop waits for this. */
|
|
74
|
-
function isAgentDetachedEvent(value) {
|
|
75
|
-
return typeof value === "object" && value !== null && value.type === "agent-detached";
|
|
76
|
-
}
|
|
77
|
-
/** A-F8: target's writer thread disclosing its bounded queue overflowed and events were dropped — never silent (honest-degradation rule). `count` is cumulative since `agentmain` last ran, not a per-tick delta. */
|
|
78
|
-
function isEventsDroppedEvent(value) {
|
|
79
|
-
const v = value;
|
|
80
|
-
return typeof value === "object" && value !== null && v.type === "events-dropped" && typeof v.count === "number";
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* `StackTraceElement.getFileName()` is always a bare name (`"ProbeApplication.java"`,
|
|
84
|
-
* never `"probe/ProbeApplication.java"`) — the JVM never records a package-relative
|
|
85
|
-
* path, only a plain source-file attribute, so it resolves nothing against a graph
|
|
86
|
-
* whose nodes carry repo-relative paths.
|
|
87
|
-
*
|
|
88
|
-
* `className` (fully-qualified, always present) recovers the missing directory.
|
|
89
|
-
* `className.split("$")[0]` drops a nested/anonymous-class suffix (`Outer$Inner`,
|
|
90
|
-
* `Outer$1`) to recover the OUTER class's package — nested classes live in their
|
|
91
|
-
* outer class's file. Result is package-relative, not repo-relative — the fallback
|
|
92
|
-
* `frameToStackFrame` uses when `reconstructJvmSourcePath` can't produce a
|
|
93
|
-
* validated repo-relative path.
|
|
94
|
-
*
|
|
95
|
-
* Deliberately does NOT rename/reshape `frame.fileName` itself — Kotlin breaks the
|
|
96
|
-
* "file name matches class name" assumption (a class `Foo` may live in `Bar.kt`),
|
|
97
|
-
* so only the directory is derived from the class name.
|
|
98
|
-
*/
|
|
99
|
-
function packageRelativeFile(frame) {
|
|
100
|
-
if (frame.fileName === null)
|
|
101
|
-
return null;
|
|
102
|
-
const outerClassName = frame.className.split("$")[0];
|
|
103
|
-
const lastDot = outerClassName.lastIndexOf(".");
|
|
104
|
-
if (lastDot === -1)
|
|
105
|
-
return frame.fileName; // default package — no directory to prepend
|
|
106
|
-
const packagePath = outerClassName.slice(0, lastDot).replaceAll(".", "/");
|
|
107
|
-
return `${packagePath}/${frame.fileName}`;
|
|
108
|
-
}
|
|
109
|
-
function frameToStackFrame(frame, sourceRoots) {
|
|
110
|
-
return {
|
|
111
|
-
location: {
|
|
112
|
-
file: reconstructJvmSourcePath(frame.className, frame.fileName, sourceRoots) ?? packageRelativeFile(frame),
|
|
113
|
-
line: frame.lineNumber > 0 ? frame.lineNumber : null,
|
|
114
|
-
column: null,
|
|
115
|
-
functionName: `${frame.className}.${frame.methodName}`,
|
|
116
|
-
// self-contained: the JVM's own reported state, captured live, never a
|
|
117
|
-
// side artifact resolved through -- same standing as CDP's frames
|
|
118
|
-
reliability: "self-contained",
|
|
119
|
-
resolvedVia: null,
|
|
120
|
-
},
|
|
121
|
-
raw: `${frame.className}.${frame.methodName}(${frame.fileName ?? "unknown"}:${String(frame.lineNumber)})`,
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* A-F10: a lighter check than the Node sibling's, deliberately — HotSpot's own
|
|
126
|
-
* Dynamic Attach already enforces same-uid at the OS level (`VirtualMachine.attach`
|
|
127
|
-
* fails for a different-user pid regardless). What's NOT already enforced is "this
|
|
128
|
-
* pid actually looks like a JVM" — attaching against a non-JVM same-user pid
|
|
129
|
-
* wastes a real attempt for a confusing downstream failure instead of a clear
|
|
130
|
-
* refusal here. `ps`, not `/proc`, for the same Linux/macOS portability reason.
|
|
131
|
-
*/
|
|
132
|
-
function verifyLikelyJvmProcess(pid) {
|
|
133
|
-
const result = spawnSync("ps", ["-o", "comm=", "-p", String(pid)], { encoding: "utf8" });
|
|
134
|
-
const comm = (result.stdout ?? "").trim().split("\n")[0]?.trim().toLowerCase();
|
|
135
|
-
if (result.status !== 0 || comm === undefined || comm === "") {
|
|
136
|
-
return { ok: false, reason: `could not verify pid ${String(pid)}'s command via ps (exit ${String(result.status)}) — refusing to attempt a JVM attach against a process this module cannot confirm the identity of` };
|
|
137
|
-
}
|
|
138
|
-
// covers "java", "javaw", and "java (someapp)" truncation -- allowlists the
|
|
139
|
-
// launcher, never app names
|
|
140
|
-
if (!comm.includes("java")) {
|
|
141
|
-
return { ok: false, reason: `pid ${String(pid)}'s command is "${comm}", which does not look like a JVM — refusing to attempt a Dynamic Attach against a process that is unlikely to have one` };
|
|
142
|
-
}
|
|
143
|
-
return { ok: true };
|
|
144
|
-
}
|
|
145
|
-
function notThisCollectorsJob(what) {
|
|
146
|
-
return { availability: "unavailable", reason: `attachToRunningJvmProcess observes only genuinely uncaught JVM exceptions via a loaded agent's default handler, not ${what}.` };
|
|
147
|
-
}
|
|
148
|
-
/** A-F8: the sentinel `agentmain` argument that means "detach, do not install" — must match `Agent.java`'s own `DETACH_COMMAND` exactly. */
|
|
149
|
-
const DETACH_COMMAND = "DETACH";
|
|
150
|
-
const CAPABILITIES = {
|
|
151
|
-
domObservation: notThisCollectorsJob("DOM inspection"),
|
|
152
|
-
consoleObservation: notThisCollectorsJob("a browser page's console"),
|
|
153
|
-
networkObservation: notThisCollectorsJob("network traffic"),
|
|
154
|
-
// unavailable unlike the Node slice: doesn't intercept System.out/err, that's
|
|
155
|
-
// attachToRunningProcess's job for a target logging to a file
|
|
156
|
-
backendLogAccess: notThisCollectorsJob("console/log output — see attachToRunningProcess for a target logging to a file"),
|
|
157
|
-
distributedTrace: notThisCollectorsJob("trace-id/request-id correlation — the loaded agent extracts none"),
|
|
158
|
-
sourceMapping: { availability: "available", reason: null },
|
|
159
|
-
stackCapture: { availability: "available", reason: null },
|
|
160
|
-
processLifecycle: notThisCollectorsJob("process lifecycle — spawn/ready/exit are ProcessCollector's to observe"),
|
|
161
|
-
databaseObservation: notThisCollectorsJob("database queries"),
|
|
162
|
-
externalServiceObservation: notThisCollectorsJob("outbound external requests"),
|
|
163
|
-
};
|
|
164
|
-
/**
|
|
165
|
-
* Runs the compiled `Attacher` helper against `pid`, loading `agent.jar`
|
|
166
|
-
* with `outputFilePath` as its argument. Resolves once the helper process
|
|
167
|
-
* exits 0 (attach + loadAgent both succeeded); rejects with the helper's own
|
|
168
|
-
* stderr otherwise — never guesses at success from silence.
|
|
169
|
-
*/
|
|
170
|
-
function runAttacher(pid, agentJarPath, outputFilePath, attacherDir, attachTimeoutMs) {
|
|
171
|
-
const toolsJar = findToolsJarIfPresent();
|
|
172
|
-
const classpath = toolsJar !== null ? `${attacherDir}:${toolsJar}` : attacherDir;
|
|
173
|
-
const result = spawnSync("java", ["-cp", classpath, "Attacher", String(pid), agentJarPath, outputFilePath], {
|
|
174
|
-
encoding: "utf8",
|
|
175
|
-
timeout: attachTimeoutMs,
|
|
176
|
-
});
|
|
177
|
-
if (result.error !== undefined) {
|
|
178
|
-
return { ok: false, reason: `attachToRunningJvmProcess: could not launch the java Attacher helper: ${result.error.message}` };
|
|
179
|
-
}
|
|
180
|
-
if (result.status !== 0) {
|
|
181
|
-
const detail = (result.stderr ?? "").trim() || (result.stdout ?? "").trim() || `exit code ${String(result.status)}`;
|
|
182
|
-
return { ok: false, reason: `attachToRunningJvmProcess: Attacher failed to attach to pid ${String(pid)}: ${detail}` };
|
|
183
|
-
}
|
|
184
|
-
return { ok: true };
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Attach to an already-running JVM process via the HotSpot Dynamic Attach
|
|
188
|
-
* mechanism, load a minimal Java agent, and start capturing genuinely
|
|
189
|
-
* uncaught exceptions as `EXCEPTION` evidence from that moment forward.
|
|
190
|
-
*
|
|
191
|
-
* **Retroactive, not historical** — same as the Node slice: an exception
|
|
192
|
-
* thrown before the agent finishes loading is not captured, because the
|
|
193
|
-
* default handler was not installed yet. There is no backlog to catch up on.
|
|
194
|
-
*
|
|
195
|
-
* Discovery, build, and attach all happen inside `start()`, matching every
|
|
196
|
-
* other `Collector` in this repo — a routine failure to attach resolves as
|
|
197
|
-
* `{ available: false, reason }`, never a thrown exception a caller has to
|
|
198
|
-
* remember to catch.
|
|
199
|
-
*/
|
|
200
|
-
export function attachToRunningJvmProcess(options) {
|
|
201
|
-
let stopped = false;
|
|
202
|
-
// A-F8: set once start() actually attaches -- stop() uses this to know whether
|
|
203
|
-
// there's anything to detach, and null means stop() is a pure no-op
|
|
204
|
-
let attached = null;
|
|
205
|
-
// captured so stop() can disclose a detach failure through the same evidence
|
|
206
|
-
// stream start()'s poll loop uses
|
|
207
|
-
let capturedContext = null;
|
|
208
|
-
let detachConfirmed = false;
|
|
209
|
-
function emitCollectorError(reason) {
|
|
210
|
-
const context = capturedContext;
|
|
211
|
-
if (context === null)
|
|
212
|
-
return; // start() never ran far enough to have one
|
|
213
|
-
context.emit({
|
|
214
|
-
timestamp: new Date().toISOString(),
|
|
215
|
-
source: "backend-process",
|
|
216
|
-
service: options.service ?? null,
|
|
217
|
-
process: options.processId,
|
|
218
|
-
eventType: "COLLECTOR_ERROR",
|
|
219
|
-
payload: { raw: reason, collectorId: `attach-jvm-agent:${options.processId}`, error: reason },
|
|
220
|
-
traceId: null,
|
|
221
|
-
requestId: null,
|
|
222
|
-
correlationId: null,
|
|
223
|
-
graphNodeId: null,
|
|
224
|
-
sourceLocation: null,
|
|
225
|
-
stackTrace: null,
|
|
226
|
-
confidence: 1,
|
|
227
|
-
redactionStatus: "pending-redaction",
|
|
228
|
-
collectorVersion: COLLECTOR_VERSION,
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
return {
|
|
232
|
-
collectorId: `attach-jvm-agent:${options.processId}`,
|
|
233
|
-
async start(context) {
|
|
234
|
-
capturedContext = context;
|
|
235
|
-
if (!isProcessAlive(options.pid)) {
|
|
236
|
-
return { available: false, reason: `attachToRunningJvmProcess: pid ${String(options.pid)} is not running — cannot attach to a target that does not exist.` };
|
|
237
|
-
}
|
|
238
|
-
if (process.platform === "win32") {
|
|
239
|
-
return { available: false, reason: "attachToRunningJvmProcess: HotSpot Dynamic Attach as used here relies on a Unix domain socket; not available on win32." };
|
|
240
|
-
}
|
|
241
|
-
// A-F10: checked before spawning the Attacher helper, not after —
|
|
242
|
-
// see verifyLikelyJvmProcess's own doc for why this is a lighter check
|
|
243
|
-
// than the Node sibling's (the OS already enforces same-uid here).
|
|
244
|
-
const identity = verifyLikelyJvmProcess(options.pid);
|
|
245
|
-
if (!identity.ok) {
|
|
246
|
-
return { available: false, reason: `attachToRunningJvmProcess: ${identity.reason}.` };
|
|
247
|
-
}
|
|
248
|
-
let agentJarPath;
|
|
249
|
-
let attacherDir;
|
|
250
|
-
try {
|
|
251
|
-
agentJarPath = await buildJvmAgentJar();
|
|
252
|
-
attacherDir = buildAttacherClass();
|
|
253
|
-
}
|
|
254
|
-
catch (error) {
|
|
255
|
-
return { available: false, reason: error instanceof Error ? error.message : String(error) };
|
|
256
|
-
}
|
|
257
|
-
const dir = mkdtempSync(join(tmpdir(), "descry-jvm-attach-"));
|
|
258
|
-
const outFile = join(dir, "events.log");
|
|
259
|
-
writeFileSync(outFile, "");
|
|
260
|
-
const attachTimeoutMs = options.attachTimeoutMs ?? 10_000;
|
|
261
|
-
const attachResult = runAttacher(options.pid, agentJarPath, outFile, attacherDir, attachTimeoutMs);
|
|
262
|
-
if (!attachResult.ok) {
|
|
263
|
-
return { available: false, reason: attachResult.reason };
|
|
264
|
-
}
|
|
265
|
-
// A-F8: recorded so stop() can run the same Attacher helper a second
|
|
266
|
-
// time with DETACH_COMMAND, and know which output file to watch for
|
|
267
|
-
// confirmation.
|
|
268
|
-
attached = { agentJarPath, attacherDir, outFile, dir, attachTimeoutMs };
|
|
269
|
-
const pollIntervalMs = options.pollIntervalMs ?? 50;
|
|
270
|
-
let consumed = 0;
|
|
271
|
-
const poll = async () => {
|
|
272
|
-
for (;;) {
|
|
273
|
-
if (stopped)
|
|
274
|
-
return;
|
|
275
|
-
if (!existsSync(outFile)) {
|
|
276
|
-
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
277
|
-
continue;
|
|
278
|
-
}
|
|
279
|
-
const whole = readFileSync(outFile, "utf8");
|
|
280
|
-
if (whole.length > consumed) {
|
|
281
|
-
const chunk = whole.slice(consumed);
|
|
282
|
-
consumed = whole.length;
|
|
283
|
-
for (const rawLine of chunk.split("\n")) {
|
|
284
|
-
const line = rawLine.trim();
|
|
285
|
-
if (line === "")
|
|
286
|
-
continue;
|
|
287
|
-
let parsed;
|
|
288
|
-
try {
|
|
289
|
-
parsed = JSON.parse(line);
|
|
290
|
-
}
|
|
291
|
-
catch {
|
|
292
|
-
// in practice cannot happen: Agent.java opens, writes one full
|
|
293
|
-
// line, and closes the file per event, so a poll tick never
|
|
294
|
-
// observes a half-written line. Dropped rather than guessed at
|
|
295
|
-
// if it ever does.
|
|
296
|
-
continue;
|
|
297
|
-
}
|
|
298
|
-
if (isUncaughtExceptionEvent(parsed) || isFrameworkCaughtExceptionEvent(parsed)) {
|
|
299
|
-
const frames = parsed.frames.map((frame) => frameToStackFrame(frame, options.sourceRoots));
|
|
300
|
-
const stackTrace = frames.length > 0
|
|
301
|
-
? { fidelity: "synchronous", frames, primaryFrameIndex: 0 }
|
|
302
|
-
: { fidelity: "synchronous", frames: [], primaryFrameIndex: 0 };
|
|
303
|
-
context.emit({
|
|
304
|
-
timestamp: new Date().toISOString(),
|
|
305
|
-
source: "backend-process",
|
|
306
|
-
service: options.service ?? null,
|
|
307
|
-
process: options.processId,
|
|
308
|
-
eventType: "EXCEPTION",
|
|
309
|
-
// `handled` distinguishes the two channels within one event type
|
|
310
|
-
// rather than adding a new member to a closed vocabulary -- true
|
|
311
|
-
// for RT-201's DispatcherServlet tap, false for genuinely
|
|
312
|
-
// uncaught. Additive: existing .message/.stack consumers unaffected.
|
|
313
|
-
payload: { message: `${parsed.exceptionClass}: ${parsed.message ?? ""}`.trim(), stack: null, handled: parsed.type === "framework-caught-exception" },
|
|
314
|
-
traceId: null,
|
|
315
|
-
requestId: null,
|
|
316
|
-
correlationId: null,
|
|
317
|
-
graphNodeId: null,
|
|
318
|
-
sourceLocation: frames[0]?.location ?? null,
|
|
319
|
-
stackTrace: frames.length > 0 ? stackTrace : null,
|
|
320
|
-
confidence: 1,
|
|
321
|
-
redactionStatus: "pending-redaction",
|
|
322
|
-
collectorVersion: COLLECTOR_VERSION,
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
else if (isAgentDetachedEvent(parsed)) {
|
|
326
|
-
// A-F8: unblocks stop()'s wait loop -- internal bookkeeping, not
|
|
327
|
-
// something observed about the target
|
|
328
|
-
detachConfirmed = true;
|
|
329
|
-
}
|
|
330
|
-
else if (isEventsDroppedEvent(parsed)) {
|
|
331
|
-
// A-F8: the target's bounded queue overflowed, real evidence was
|
|
332
|
-
// lost -- disclosed, not silent. De-duplicated on the Java side
|
|
333
|
-
// (marker written only when the count changes).
|
|
334
|
-
emitCollectorError(`attachToRunningJvmProcess: the target's own event queue has dropped ${String(parsed.count)} event(s) so far (queue capacity exceeded) — some EXCEPTION evidence from this process was never captured.`);
|
|
335
|
-
}
|
|
336
|
-
// "agent-loaded", "framework-instrumentation-installed",
|
|
337
|
-
// "framework-instrumentation-unavailable", "detach-started",
|
|
338
|
-
// "detach-uncaught-handler-restored" / "-restore-failed",
|
|
339
|
-
// "detach-transformer-reset" / "-incomplete" / "-failed", and
|
|
340
|
-
// any future purely-internal marker type: acknowledged by
|
|
341
|
-
// being parsed, not turned into evidence.
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
345
|
-
}
|
|
346
|
-
};
|
|
347
|
-
void poll();
|
|
348
|
-
return { available: true };
|
|
349
|
-
},
|
|
350
|
-
/**
|
|
351
|
-
* A-F8: a real detach, not just halting this module's own poller. Runs the
|
|
352
|
-
* Attacher helper again with `DETACH_COMMAND`, which drives `Agent.java`'s own
|
|
353
|
-
* `detach()` — restoring the JVM's prior default uncaught-exception handler
|
|
354
|
-
* and calling ByteBuddy's `reset()` to remove the `DispatcherServlet`
|
|
355
|
-
* transformer — because leaving either installed for the rest of the target's
|
|
356
|
-
* life is exactly the kind of state a "detach" must not leave behind.
|
|
357
|
-
*
|
|
358
|
-
* `stopped` is deliberately NOT set until after detach is attempted and
|
|
359
|
-
* (bounded) awaited: `poll()` checks `stopped` first on every tick, so setting
|
|
360
|
-
* it early would stop this module from ever reading the target's own
|
|
361
|
-
* "agent-detached" confirmation line.
|
|
362
|
-
*
|
|
363
|
-
* Where a JVM limitation makes true removal impossible, this discloses it via
|
|
364
|
-
* `COLLECTOR_ERROR` rather than pretending `stop()` stopped it. Two disclosed
|
|
365
|
-
* failure shapes: the Attacher helper itself couldn't run (target unreachable,
|
|
366
|
-
* permission denied), or it ran but the writer thread never confirmed detach
|
|
367
|
-
* within the timeout (target under load, or the JVM's own handler/transformer
|
|
368
|
-
* restoration genuinely failed inside `detach()` — narrower diagnostic detail
|
|
369
|
-
* then only visible in the raw output file).
|
|
370
|
-
*
|
|
371
|
-
* A target that has already exited needs no detach — silently a no-op, not a
|
|
372
|
-
* disclosed failure.
|
|
373
|
-
*/
|
|
374
|
-
async stop() {
|
|
375
|
-
const state = attached;
|
|
376
|
-
if (state === null) {
|
|
377
|
-
stopped = true;
|
|
378
|
-
return;
|
|
379
|
-
}
|
|
380
|
-
if (isProcessAlive(options.pid)) {
|
|
381
|
-
const detachAttempt = runAttacher(options.pid, state.agentJarPath, DETACH_COMMAND, state.attacherDir, state.attachTimeoutMs);
|
|
382
|
-
if (detachAttempt.ok) {
|
|
383
|
-
const deadline = Date.now() + Math.min(state.attachTimeoutMs, 5000);
|
|
384
|
-
while (!detachConfirmed && Date.now() < deadline) {
|
|
385
|
-
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
386
|
-
}
|
|
387
|
-
if (!detachConfirmed) {
|
|
388
|
-
emitCollectorError(`attachToRunningJvmProcess: detach was requested but never confirmed by the target within the timeout — its default uncaught-exception handler and DispatcherServlet instrumentation (if installed) may remain in place until the target process itself exits.`);
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
else {
|
|
392
|
-
emitCollectorError(`attachToRunningJvmProcess: detach could not be attempted (${detachAttempt.reason}) — the target's default uncaught-exception handler and DispatcherServlet instrumentation (if installed) remain in place until the target process itself exits.`);
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
stopped = true; // safe now: any detach confirmation has already been drained by poll().
|
|
396
|
-
try {
|
|
397
|
-
rmSync(state.dir, { recursive: true, force: true });
|
|
398
|
-
}
|
|
399
|
-
catch {
|
|
400
|
-
// best-effort cleanup; not worth failing stop() over a leftover temp dir
|
|
401
|
-
}
|
|
402
|
-
},
|
|
403
|
-
capabilities() {
|
|
404
|
-
return CAPABILITIES;
|
|
405
|
-
},
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
|
-
//# sourceMappingURL=attach-to-running-jvm-process.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"attach-to-running-jvm-process.js","sourceRoot":"","sources":["../src/attach-to-running-jvm-process.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Retroactive attach to an already-running **Node** process, via its own inspector
|
|
3
|
-
* protocol (JVM Attach API and ptrace remain out of scope, per
|
|
4
|
-
* `documents/decisions-inbox/RT-attach-to-running-process-scope.md`).
|
|
5
|
-
*
|
|
6
|
-
* Unlike the file-based `attachToRunningProcess`, this needs nothing declared at
|
|
7
|
-
* launch: `SIGUSR1` (POSIX only) turns on the target's inspector after the fact,
|
|
8
|
-
* making `http://127.0.0.1:<port>/json` reachable even on a process never started
|
|
9
|
-
* with `--inspect`.
|
|
10
|
-
*
|
|
11
|
-
* **Disclosed limit:** `SIGUSR1` doesn't report which port the inspector bound —
|
|
12
|
-
* Node prints that to the target's own stderr, unreadable for a process we didn't
|
|
13
|
-
* spawn (RT-024). So discovery tries the default port (9229) unless the caller
|
|
14
|
-
* supplies `discoveryPort`; a genuinely unknown non-default port cannot be
|
|
15
|
-
* discovered (not guessed at by port-scanning, which risks attaching to the wrong
|
|
16
|
-
* process).
|
|
17
|
-
*
|
|
18
|
-
* CDP client is `cdp-client.ts`, not Playwright's console API, which assumes a
|
|
19
|
-
* Target/Page-domain session a Node inspector doesn't have (see that file).
|
|
20
|
-
*
|
|
21
|
-
* **Measured:** a freshly-spawned target has a brief window (sometimes under
|
|
22
|
-
* 100ms) before Node installs its `SIGUSR1` handler; a signal sent inside it hits
|
|
23
|
-
* POSIX's default terminate action instead of toggling the inspector. Irrelevant
|
|
24
|
-
* to attaching to something already running, but real for a caller attaching
|
|
25
|
-
* right after spawning.
|
|
26
|
-
*
|
|
27
|
-
* **Measured side effect:** once CDP connects, V8 no longer terminates on an
|
|
28
|
-
* uncaught exception — it blocks ("Waiting for the debugger to disconnect...")
|
|
29
|
-
* exactly as under `--inspect-brk`, until `stop()` closes the session. Standard
|
|
30
|
-
* CDP/V8 behaviour, not worked around; a caller checking "did the target exit
|
|
31
|
-
* yet?" must call `stop()` first.
|
|
32
|
-
*
|
|
33
|
-
* **Vocabulary:** `Runtime.consoleAPICalled`→`CONSOLE_MESSAGE`,
|
|
34
|
-
* `Runtime.exceptionThrown`→`EXCEPTION`, same `RuntimeEventType`s
|
|
35
|
-
* `browser-console-collector.ts` uses for the browser-page analogues.
|
|
36
|
-
* `source: "backend-process"` (not a new value — `EvidenceSource` names what was
|
|
37
|
-
* observed, not the mechanism). `capabilities()` reports `backendLogAccess`, not
|
|
38
|
-
* `consoleObservation` (reserved for a browser page's console).
|
|
39
|
-
*/
|
|
40
|
-
import type { Collector } from "@descryy/runtime-contracts";
|
|
41
|
-
export interface AttachToRunningNodeProcessOptions {
|
|
42
|
-
readonly processId: string;
|
|
43
|
-
/** The pid of the already-running target. Verified alive before SIGUSR1 is sent, and never spawned or supervised by this collector. */
|
|
44
|
-
readonly pid: number;
|
|
45
|
-
readonly service?: string;
|
|
46
|
-
/** Node's own default inspector bind address. Overridable for a target known to bind elsewhere. */
|
|
47
|
-
readonly discoveryHost?: string;
|
|
48
|
-
/** Node's default inspector port — the only one `SIGUSR1` reliably produces on an unmodified target. See module doc: a non-default port must be supplied here. */
|
|
49
|
-
readonly discoveryPort?: number;
|
|
50
|
-
/** How long to poll the discovery endpoint after sending SIGUSR1 before giving up. The inspector does not bind instantaneously. */
|
|
51
|
-
readonly discoveryTimeoutMs?: number;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Sends `SIGUSR1` to `pid`, then polls `http://<host>:<port>/json` until the
|
|
55
|
-
* inspector answers or `timeoutMs` elapses. Resolves with the first entry's
|
|
56
|
-
* `webSocketDebuggerUrl` — a Node process presents exactly one inspectable
|
|
57
|
-
* target, unlike a browser's `/json` (one per tab).
|
|
58
|
-
*
|
|
59
|
-
* Rejects naming the exact blocker rather than hanging or guessing: dead pid,
|
|
60
|
-
* non-POSIX platform, or a port that never answers (see module doc).
|
|
61
|
-
*/
|
|
62
|
-
export declare function discoverNodeInspectorUrl(pid: number, options?: {
|
|
63
|
-
readonly host?: string;
|
|
64
|
-
readonly port?: number;
|
|
65
|
-
readonly timeoutMs?: number;
|
|
66
|
-
}): Promise<string>;
|
|
67
|
-
/**
|
|
68
|
-
* Attach to an already-running Node process via `SIGUSR1` + CDP, capturing
|
|
69
|
-
* `CONSOLE_MESSAGE`/`EXCEPTION` evidence from that moment forward.
|
|
70
|
-
*
|
|
71
|
-
* **Retroactive, not historical.** Anything logged or thrown before attach is
|
|
72
|
-
* gone — CDP is a live event stream with no buffer of its own (unlike the
|
|
73
|
-
* file-based `attachToRunningProcess`, which recovers pre-attach lines from disk).
|
|
74
|
-
*
|
|
75
|
-
* Discovery/connection happen inside `start()`, matching every other `Collector`
|
|
76
|
-
* here: a routine failure resolves as `{ available: false, reason }`, never a
|
|
77
|
-
* thrown exception.
|
|
78
|
-
*/
|
|
79
|
-
export declare function attachToRunningNodeProcess(options: AttachToRunningNodeProcessOptions): Collector;
|
|
80
|
-
//# sourceMappingURL=attach-to-running-node-process.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"attach-to-running-node-process.d.ts","sourceRoot":"","sources":["../src/attach-to-running-node-process.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAyG,MAAM,4BAA4B,CAAC;AAsCnK,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,uIAAuI;IACvI,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,mGAAmG;IACnG,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,kKAAkK;IAClK,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,mIAAmI;IACnI,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC;AAOD;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5F,OAAO,CAAC,MAAM,CAAC,CA+CjB;AAsED;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,iCAAiC,GAAG,SAAS,CAmHhG"}
|