@phigon/observer 8.1.0 → 8.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.
- package/README.md +51 -8
- package/dist/bin/guardian-runner-darwin-amd64 +0 -0
- package/dist/bin/guardian-runner-darwin-arm64 +0 -0
- package/dist/bin/guardian-runner-linux-amd64 +0 -0
- package/dist/bin/guardian-runner-linux-arm64 +0 -0
- package/dist/bin/guardian-runner-windows-amd64.exe +0 -0
- package/dist/bin/guardian-runner-windows-arm64.exe +0 -0
- package/dist/src/action-policy.d.ts.map +1 -1
- package/dist/src/action-policy.js +4 -2
- package/dist/src/action-policy.js.map +1 -1
- package/dist/src/activity/adapters/claude.d.ts.map +1 -1
- package/dist/src/activity/adapters/claude.js +19 -1
- package/dist/src/activity/adapters/claude.js.map +1 -1
- package/dist/src/activity/adapters/cline-task.d.ts +7 -0
- package/dist/src/activity/adapters/cline-task.d.ts.map +1 -0
- package/dist/src/activity/adapters/cline-task.js +197 -0
- package/dist/src/activity/adapters/cline-task.js.map +1 -0
- package/dist/src/activity/adapters/cline.d.ts +3 -0
- package/dist/src/activity/adapters/cline.d.ts.map +1 -0
- package/dist/src/activity/adapters/cline.js +102 -0
- package/dist/src/activity/adapters/cline.js.map +1 -0
- package/dist/src/activity/adapters/codex.d.ts.map +1 -1
- package/dist/src/activity/adapters/codex.js +76 -0
- package/dist/src/activity/adapters/codex.js.map +1 -1
- package/dist/src/activity/adapters/copilot-chat.d.ts +3 -0
- package/dist/src/activity/adapters/copilot-chat.d.ts.map +1 -0
- package/dist/src/activity/adapters/copilot-chat.js +176 -0
- package/dist/src/activity/adapters/copilot-chat.js.map +1 -0
- package/dist/src/activity/adapters/copilot.d.ts +2 -1
- package/dist/src/activity/adapters/copilot.d.ts.map +1 -1
- package/dist/src/activity/adapters/copilot.js +173 -2
- package/dist/src/activity/adapters/copilot.js.map +1 -1
- package/dist/src/activity/adapters/cursor.d.ts +3 -0
- package/dist/src/activity/adapters/cursor.d.ts.map +1 -0
- package/dist/src/activity/adapters/cursor.js +86 -0
- package/dist/src/activity/adapters/cursor.js.map +1 -0
- package/dist/src/activity/adapters/factory-droid.d.ts +3 -0
- package/dist/src/activity/adapters/factory-droid.d.ts.map +1 -0
- package/dist/src/activity/adapters/factory-droid.js +126 -0
- package/dist/src/activity/adapters/factory-droid.js.map +1 -0
- package/dist/src/activity/adapters/gemini.d.ts +3 -0
- package/dist/src/activity/adapters/gemini.d.ts.map +1 -0
- package/dist/src/activity/adapters/gemini.js +177 -0
- package/dist/src/activity/adapters/gemini.js.map +1 -0
- package/dist/src/activity/adapters/goose.d.ts +3 -0
- package/dist/src/activity/adapters/goose.d.ts.map +1 -0
- package/dist/src/activity/adapters/goose.js +116 -0
- package/dist/src/activity/adapters/goose.js.map +1 -0
- package/dist/src/activity/adapters/kiro.d.ts +3 -0
- package/dist/src/activity/adapters/kiro.d.ts.map +1 -0
- package/dist/src/activity/adapters/kiro.js +47 -0
- package/dist/src/activity/adapters/kiro.js.map +1 -0
- package/dist/src/activity/adapters/opencode.d.ts.map +1 -1
- package/dist/src/activity/adapters/opencode.js +108 -1
- package/dist/src/activity/adapters/opencode.js.map +1 -1
- package/dist/src/activity/adapters/zed.d.ts +3 -0
- package/dist/src/activity/adapters/zed.d.ts.map +1 -0
- package/dist/src/activity/adapters/zed.js +134 -0
- package/dist/src/activity/adapters/zed.js.map +1 -0
- package/dist/src/activity/collector.d.ts +12 -0
- package/dist/src/activity/collector.d.ts.map +1 -1
- package/dist/src/activity/collector.js +156 -3
- package/dist/src/activity/collector.js.map +1 -1
- package/dist/src/activity/goose-sqlite-source.d.ts +33 -0
- package/dist/src/activity/goose-sqlite-source.d.ts.map +1 -0
- package/dist/src/activity/goose-sqlite-source.js +274 -0
- package/dist/src/activity/goose-sqlite-source.js.map +1 -0
- package/dist/src/activity/index.d.ts +3 -0
- package/dist/src/activity/index.d.ts.map +1 -1
- package/dist/src/activity/index.js +3 -0
- package/dist/src/activity/index.js.map +1 -1
- package/dist/src/activity/ingest.d.ts.map +1 -1
- package/dist/src/activity/ingest.js +2 -1
- package/dist/src/activity/ingest.js.map +1 -1
- package/dist/src/activity/json-document-source.d.ts +136 -0
- package/dist/src/activity/json-document-source.d.ts.map +1 -0
- package/dist/src/activity/json-document-source.js +569 -0
- package/dist/src/activity/json-document-source.js.map +1 -0
- package/dist/src/activity/normalize.d.ts.map +1 -1
- package/dist/src/activity/normalize.js +64 -6
- package/dist/src/activity/normalize.js.map +1 -1
- package/dist/src/activity/opencode-message-tables.d.ts +87 -0
- package/dist/src/activity/opencode-message-tables.d.ts.map +1 -0
- package/dist/src/activity/opencode-message-tables.js +546 -0
- package/dist/src/activity/opencode-message-tables.js.map +1 -0
- package/dist/src/activity/opencode-sqlite-source.d.ts +7 -0
- package/dist/src/activity/opencode-sqlite-source.d.ts.map +1 -1
- package/dist/src/activity/opencode-sqlite-source.js +153 -63
- package/dist/src/activity/opencode-sqlite-source.js.map +1 -1
- package/dist/src/activity/source-reader.d.ts +16 -1
- package/dist/src/activity/source-reader.d.ts.map +1 -1
- package/dist/src/activity/source-reader.js +308 -29
- package/dist/src/activity/source-reader.js.map +1 -1
- package/dist/src/activity/sqlite-connections.d.ts +77 -0
- package/dist/src/activity/sqlite-connections.d.ts.map +1 -0
- package/dist/src/activity/sqlite-connections.js +220 -0
- package/dist/src/activity/sqlite-connections.js.map +1 -0
- package/dist/src/activity/zed-sqlite-source.d.ts +65 -0
- package/dist/src/activity/zed-sqlite-source.d.ts.map +1 -0
- package/dist/src/activity/zed-sqlite-source.js +547 -0
- package/dist/src/activity/zed-sqlite-source.js.map +1 -0
- package/dist/src/agent-action-executor.d.ts +13 -1
- package/dist/src/agent-action-executor.d.ts.map +1 -1
- package/dist/src/agent-action-executor.js +108 -56
- package/dist/src/agent-action-executor.js.map +1 -1
- package/dist/src/agentic-guardian.d.ts.map +1 -1
- package/dist/src/agentic-guardian.js +6 -5
- package/dist/src/agentic-guardian.js.map +1 -1
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +47 -10
- package/dist/src/cli.js.map +1 -1
- package/dist/src/config.d.ts +13 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +99 -3
- package/dist/src/config.js.map +1 -1
- package/dist/src/connection-config.d.ts.map +1 -1
- package/dist/src/connection-config.js +5 -0
- package/dist/src/connection-config.js.map +1 -1
- package/dist/src/content-redaction.d.ts.map +1 -1
- package/dist/src/content-redaction.js +9 -2
- package/dist/src/content-redaction.js.map +1 -1
- package/dist/src/credential-store.d.ts.map +1 -1
- package/dist/src/credential-store.js +2 -1
- package/dist/src/credential-store.js.map +1 -1
- package/dist/src/custom-agent-registry.d.ts.map +1 -1
- package/dist/src/custom-agent-registry.js +2 -1
- package/dist/src/custom-agent-registry.js.map +1 -1
- package/dist/src/discovery/adapters/generic.d.ts.map +1 -1
- package/dist/src/discovery/adapters/generic.js +160 -2
- package/dist/src/discovery/adapters/generic.js.map +1 -1
- package/dist/src/discovery/engine.d.ts +7 -1
- package/dist/src/discovery/engine.d.ts.map +1 -1
- package/dist/src/discovery/engine.js +20 -5
- package/dist/src/discovery/engine.js.map +1 -1
- package/dist/src/discovery/known-agent.d.ts +7 -0
- package/dist/src/discovery/known-agent.d.ts.map +1 -1
- package/dist/src/discovery/known-agent.js +9 -4
- package/dist/src/discovery/known-agent.js.map +1 -1
- package/dist/src/discovery/system-evidence.d.ts +40 -1
- package/dist/src/discovery/system-evidence.d.ts.map +1 -1
- package/dist/src/discovery/system-evidence.js +189 -16
- package/dist/src/discovery/system-evidence.js.map +1 -1
- package/dist/src/event-queue.d.ts.map +1 -1
- package/dist/src/event-queue.js +88 -38
- package/dist/src/event-queue.js.map +1 -1
- package/dist/src/event-spool.d.ts.map +1 -1
- package/dist/src/event-spool.js +58 -10
- package/dist/src/event-spool.js.map +1 -1
- package/dist/src/guardian-containment.d.ts +2 -6
- package/dist/src/guardian-containment.d.ts.map +1 -1
- package/dist/src/guardian-containment.js +12 -63
- package/dist/src/guardian-containment.js.map +1 -1
- package/dist/src/guardian-decision-journal.d.ts.map +1 -1
- package/dist/src/guardian-decision-journal.js +2 -1
- package/dist/src/guardian-decision-journal.js.map +1 -1
- package/dist/src/guardian-managed-exec.d.ts.map +1 -1
- package/dist/src/guardian-managed-exec.js +2 -1
- package/dist/src/guardian-managed-exec.js.map +1 -1
- package/dist/src/guardian-model-bridge.d.ts.map +1 -1
- package/dist/src/guardian-model-bridge.js +2 -1
- package/dist/src/guardian-model-bridge.js.map +1 -1
- package/dist/src/guardian-native.d.ts +0 -1
- package/dist/src/guardian-native.d.ts.map +1 -1
- package/dist/src/guardian-native.js +0 -6
- package/dist/src/guardian-native.js.map +1 -1
- package/dist/src/guardian-process-monitor.d.ts +3 -0
- package/dist/src/guardian-process-monitor.d.ts.map +1 -1
- package/dist/src/guardian-process-monitor.js +8 -0
- package/dist/src/guardian-process-monitor.js.map +1 -1
- package/dist/src/historical-identity-store.d.ts.map +1 -1
- package/dist/src/historical-identity-store.js +2 -1
- package/dist/src/historical-identity-store.js.map +1 -1
- package/dist/src/installation.d.ts.map +1 -1
- package/dist/src/installation.js +3 -2
- package/dist/src/installation.js.map +1 -1
- package/dist/src/machine-command-executor.d.ts +22 -7
- package/dist/src/machine-command-executor.d.ts.map +1 -1
- package/dist/src/machine-command-executor.js +91 -17
- package/dist/src/machine-command-executor.js.map +1 -1
- package/dist/src/pair.d.ts.map +1 -1
- package/dist/src/pair.js +3 -2
- package/dist/src/pair.js.map +1 -1
- package/dist/src/private-directory.d.ts +4 -0
- package/dist/src/private-directory.d.ts.map +1 -0
- package/dist/src/private-directory.js +35 -0
- package/dist/src/private-directory.js.map +1 -0
- package/dist/src/process-tree.d.ts +73 -0
- package/dist/src/process-tree.d.ts.map +1 -0
- package/dist/src/process-tree.js +256 -0
- package/dist/src/process-tree.js.map +1 -0
- package/dist/src/server-authority.d.ts +26 -0
- package/dist/src/server-authority.d.ts.map +1 -0
- package/dist/src/server-authority.js +102 -0
- package/dist/src/server-authority.js.map +1 -0
- package/dist/src/stream-client.d.ts +3 -1
- package/dist/src/stream-client.d.ts.map +1 -1
- package/dist/src/stream-client.js +49 -11
- package/dist/src/stream-client.js.map +1 -1
- package/dist/src/stream-state.d.ts.map +1 -1
- package/dist/src/stream-state.js +2 -1
- package/dist/src/stream-state.js.map +1 -1
- package/dist/src/system-inspection.d.ts +78 -0
- package/dist/src/system-inspection.d.ts.map +1 -0
- package/dist/src/system-inspection.js +281 -0
- package/dist/src/system-inspection.js.map +1 -0
- package/dist/src/update.d.ts.map +1 -1
- package/dist/src/update.js +9 -3
- package/dist/src/update.js.map +1 -1
- package/dist/src/user-notices.d.ts +53 -0
- package/dist/src/user-notices.d.ts.map +1 -0
- package/dist/src/user-notices.js +117 -0
- package/dist/src/user-notices.js.map +1 -0
- package/package.json +1 -1
- package/dist/src/windows-process.d.ts +0 -7
- package/dist/src/windows-process.d.ts.map +0 -1
- package/dist/src/windows-process.js +0 -18
- package/dist/src/windows-process.js.map +0 -1
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/** One exact process lifetime: a PID alone is never an identity. */
|
|
2
|
+
export type ExactProcess = Readonly<{
|
|
3
|
+
processId: number;
|
|
4
|
+
startedAt: Date;
|
|
5
|
+
}>;
|
|
6
|
+
export type TreeStopMode = "stop" | "kill";
|
|
7
|
+
export type TreeStopOutcome = Readonly<{
|
|
8
|
+
outcome: "stale" | "exited" | "access_denied" | "graceful_unsupported" | "console_shared" | "self_target";
|
|
9
|
+
}> | Readonly<{
|
|
10
|
+
outcome: "failed";
|
|
11
|
+
code: string;
|
|
12
|
+
}> | Readonly<{
|
|
13
|
+
outcome: "dispatched";
|
|
14
|
+
rootRunning: boolean;
|
|
15
|
+
/** Verified descendants that were signalled. */
|
|
16
|
+
descendants: number;
|
|
17
|
+
/** Signalled descendants still running at the end of the wait. */
|
|
18
|
+
descendantsRunning: number;
|
|
19
|
+
/** Running descendants the OS would not let the observer stop. */
|
|
20
|
+
descendantsDenied: number;
|
|
21
|
+
}>;
|
|
22
|
+
/** Stops one exact process and the descendants it started. */
|
|
23
|
+
export interface ProcessTreeControl {
|
|
24
|
+
stop(target: ExactProcess, mode: TreeStopMode): Promise<TreeStopOutcome>;
|
|
25
|
+
}
|
|
26
|
+
export type TreeStopReceipt = Readonly<{
|
|
27
|
+
state: "succeeded" | "failed" | "rejected";
|
|
28
|
+
code: string;
|
|
29
|
+
detail: string;
|
|
30
|
+
targetStillRunning: boolean;
|
|
31
|
+
}>;
|
|
32
|
+
/** Plain-language receipts; detail stays within the 256-character journal bound. */
|
|
33
|
+
export declare function describeTreeOutcome(outcome: TreeStopOutcome, graceful: boolean): TreeStopReceipt;
|
|
34
|
+
export declare function defaultProcessTreeControl(platform?: NodeJS.Platform): ProcessTreeControl;
|
|
35
|
+
export type ProcessRow = Readonly<{
|
|
36
|
+
processId: number;
|
|
37
|
+
parentId: number;
|
|
38
|
+
startedAt: number;
|
|
39
|
+
zombie: boolean;
|
|
40
|
+
}>;
|
|
41
|
+
type Signal = "SIGTERM" | "SIGKILL" | 0;
|
|
42
|
+
/**
|
|
43
|
+
* Linux and macOS: one process-table snapshot verifies the root's start time
|
|
44
|
+
* immediately before signalling, and finds descendants whose start is not
|
|
45
|
+
* earlier than their parent's (a stale parent PID cannot adopt them). The
|
|
46
|
+
* observer and everything it started are never members.
|
|
47
|
+
*/
|
|
48
|
+
export declare class UnixProcessTreeControl implements ProcessTreeControl {
|
|
49
|
+
#private;
|
|
50
|
+
constructor(options?: Readonly<{
|
|
51
|
+
list?: () => Promise<ReadonlyMap<number, ProcessRow>>;
|
|
52
|
+
signal?: (processId: number, signal: Signal) => void;
|
|
53
|
+
sleep?: (milliseconds: number) => Promise<void>;
|
|
54
|
+
observerProcessId?: number;
|
|
55
|
+
clock?: () => number;
|
|
56
|
+
}>);
|
|
57
|
+
stop(target: ExactProcess, mode: TreeStopMode): Promise<TreeStopOutcome>;
|
|
58
|
+
}
|
|
59
|
+
export declare function descendantsOf(table: ReadonlyMap<number, ProcessRow>, root: ProcessRow, observerProcessId: number): ProcessRow[];
|
|
60
|
+
export declare function readUnixProcessTable(): Promise<ReadonlyMap<number, ProcessRow>>;
|
|
61
|
+
export declare function parseUnixProcessTable(stdout: string): ReadonlyMap<number, ProcessRow>;
|
|
62
|
+
/**
|
|
63
|
+
* Windows: the native helper holds a handle to every member while it works,
|
|
64
|
+
* so no member's PID can be recycled before the report is written.
|
|
65
|
+
*/
|
|
66
|
+
export declare class WindowsProcessTreeControl implements ProcessTreeControl {
|
|
67
|
+
#private;
|
|
68
|
+
constructor(run?: (args: readonly string[]) => Promise<string>);
|
|
69
|
+
stop(target: ExactProcess, mode: TreeStopMode): Promise<TreeStopOutcome>;
|
|
70
|
+
}
|
|
71
|
+
export declare function parseTreeReport(stdout: string): TreeStopOutcome;
|
|
72
|
+
export {};
|
|
73
|
+
//# sourceMappingURL=process-tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-tree.d.ts","sourceRoot":"","sources":["../../src/process-tree.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { guardianRunnerPath } from "./guardian-native.js";
|
|
3
|
+
/** Plain-language receipts; detail stays within the 256-character journal bound. */
|
|
4
|
+
export function describeTreeOutcome(outcome, graceful) {
|
|
5
|
+
const receipt = (state, code, detail, targetStillRunning) => ({ state, code, detail, targetStillRunning });
|
|
6
|
+
switch (outcome.outcome) {
|
|
7
|
+
case "stale":
|
|
8
|
+
return receipt("rejected", "stale_target", "The process ID now belongs to a different process. Nothing was signalled.", false);
|
|
9
|
+
case "exited":
|
|
10
|
+
return receipt("rejected", "target_already_stopped", "The agent process had already exited. Nothing was signalled.", false);
|
|
11
|
+
case "self_target":
|
|
12
|
+
return receipt("rejected", "self_target_rejected", "Observer refuses to terminate its own process.", true);
|
|
13
|
+
case "access_denied":
|
|
14
|
+
return receipt("failed", "access_denied", "The operating system denied permission to stop this process. It may run as another user or as administrator. It is still running.", true);
|
|
15
|
+
case "graceful_unsupported":
|
|
16
|
+
return receipt("rejected", "graceful_stop_unsupported", "This agent has no window to close and no terminal to press Ctrl+C in, so a graceful stop is not possible. Nothing was sent. Use force stop instead.", true);
|
|
17
|
+
case "console_shared":
|
|
18
|
+
return receipt("rejected", "terminal_shared", "Other programs share this agent's terminal, and Ctrl+C would reach them too. Nothing was sent. Use force stop instead.", true);
|
|
19
|
+
case "failed":
|
|
20
|
+
return receipt("failed", "os_dispatch_failed", `The operating system could not complete the request (${outcome.code}). The agent may still be running.`, true);
|
|
21
|
+
case "dispatched": {
|
|
22
|
+
if (outcome.rootRunning) {
|
|
23
|
+
return receipt("failed", "process_still_running", graceful
|
|
24
|
+
? "The stop request was sent, but the agent is still running after 5 seconds. It was not escalated; use force stop if needed."
|
|
25
|
+
: "Force stop was sent, but the agent still reports running.", true);
|
|
26
|
+
}
|
|
27
|
+
const remaining = outcome.descendantsRunning + outcome.descendantsDenied;
|
|
28
|
+
if (remaining > 0) {
|
|
29
|
+
return receipt("succeeded", "process_stopped_children_running", `The agent process exited, but ${remaining} of its child processes ${remaining === 1 ? "is" : "are"} still running.`, false);
|
|
30
|
+
}
|
|
31
|
+
return receipt("succeeded", "process_stopped", outcome.descendants > 0
|
|
32
|
+
? `The agent process and its ${outcome.descendants} child ${outcome.descendants === 1 ? "process" : "processes"} exited.`
|
|
33
|
+
: "The agent process exited.", false);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function defaultProcessTreeControl(platform = process.platform) {
|
|
38
|
+
return platform === "win32" ? new WindowsProcessTreeControl() : new UnixProcessTreeControl();
|
|
39
|
+
}
|
|
40
|
+
const maxDescendants = 1024;
|
|
41
|
+
// Graceful stop gives the agent time to save state; force stop is immediate.
|
|
42
|
+
const exitWait = { stop: 5_000, kill: 3_000 };
|
|
43
|
+
/**
|
|
44
|
+
* Linux and macOS: one process-table snapshot verifies the root's start time
|
|
45
|
+
* immediately before signalling, and finds descendants whose start is not
|
|
46
|
+
* earlier than their parent's (a stale parent PID cannot adopt them). The
|
|
47
|
+
* observer and everything it started are never members.
|
|
48
|
+
*/
|
|
49
|
+
export class UnixProcessTreeControl {
|
|
50
|
+
#list;
|
|
51
|
+
#signal;
|
|
52
|
+
#sleep;
|
|
53
|
+
#observerProcessId;
|
|
54
|
+
#clock;
|
|
55
|
+
constructor(options = {}) {
|
|
56
|
+
this.#list = options.list ?? readUnixProcessTable;
|
|
57
|
+
this.#signal = options.signal ?? ((processId, signal) => { process.kill(processId, signal); });
|
|
58
|
+
this.#sleep = options.sleep ?? ((milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)));
|
|
59
|
+
this.#observerProcessId = options.observerProcessId ?? process.pid;
|
|
60
|
+
this.#clock = options.clock ?? Date.now;
|
|
61
|
+
}
|
|
62
|
+
async stop(target, mode) {
|
|
63
|
+
if (target.processId === this.#observerProcessId)
|
|
64
|
+
return { outcome: "self_target" };
|
|
65
|
+
let table;
|
|
66
|
+
try {
|
|
67
|
+
table = await this.#list();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return { outcome: "failed", code: "process_table_unavailable" };
|
|
71
|
+
}
|
|
72
|
+
const root = table.get(target.processId);
|
|
73
|
+
if (root === undefined || root.zombie)
|
|
74
|
+
return { outcome: "exited" };
|
|
75
|
+
if (!sameStart(root.startedAt, target.startedAt.getTime()))
|
|
76
|
+
return { outcome: "stale" };
|
|
77
|
+
const descendants = descendantsOf(table, root, this.#observerProcessId);
|
|
78
|
+
const signal = mode === "stop" ? "SIGTERM" : "SIGKILL";
|
|
79
|
+
try {
|
|
80
|
+
this.#signal(root.processId, signal);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
const code = error.code;
|
|
84
|
+
if (code === "ESRCH")
|
|
85
|
+
return { outcome: "exited" };
|
|
86
|
+
if (code === "EPERM")
|
|
87
|
+
return { outcome: "access_denied" };
|
|
88
|
+
return { outcome: "failed", code: String(code ?? "unknown").slice(0, 32) };
|
|
89
|
+
}
|
|
90
|
+
const denied = new Set();
|
|
91
|
+
for (const descendant of descendants) {
|
|
92
|
+
try {
|
|
93
|
+
this.#signal(descendant.processId, signal);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
if (error.code === "EPERM")
|
|
97
|
+
denied.add(descendant.processId);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const members = [root, ...descendants];
|
|
101
|
+
const deadline = this.#clock() + exitWait[mode];
|
|
102
|
+
while (this.#clock() < deadline && members.some((member) => this.#alive(member.processId))) {
|
|
103
|
+
await this.#sleep(100);
|
|
104
|
+
}
|
|
105
|
+
// A final snapshot tells an exited process from a zombie or a reused PID.
|
|
106
|
+
let after;
|
|
107
|
+
try {
|
|
108
|
+
after = await this.#list();
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
after = undefined;
|
|
112
|
+
}
|
|
113
|
+
const running = (member) => {
|
|
114
|
+
if (after === undefined)
|
|
115
|
+
return this.#alive(member.processId);
|
|
116
|
+
const current = after.get(member.processId);
|
|
117
|
+
return current !== undefined && !current.zombie && sameStart(current.startedAt, member.startedAt);
|
|
118
|
+
};
|
|
119
|
+
const stillRunning = descendants.filter(running);
|
|
120
|
+
return {
|
|
121
|
+
outcome: "dispatched",
|
|
122
|
+
rootRunning: running(root),
|
|
123
|
+
descendants: descendants.length,
|
|
124
|
+
// Counted separately so a receipt can say why a child survived.
|
|
125
|
+
descendantsRunning: stillRunning.filter((member) => !denied.has(member.processId)).length,
|
|
126
|
+
descendantsDenied: stillRunning.filter((member) => denied.has(member.processId)).length,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
#alive(processId) {
|
|
130
|
+
try {
|
|
131
|
+
this.#signal(processId, 0);
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
return error.code === "EPERM";
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
export function descendantsOf(table, root, observerProcessId) {
|
|
140
|
+
const children = new Map();
|
|
141
|
+
for (const row of table.values()) {
|
|
142
|
+
if (row.processId === row.parentId)
|
|
143
|
+
continue;
|
|
144
|
+
const siblings = children.get(row.parentId) ?? [];
|
|
145
|
+
siblings.push(row);
|
|
146
|
+
children.set(row.parentId, siblings);
|
|
147
|
+
}
|
|
148
|
+
const found = [];
|
|
149
|
+
const seen = new Set([root.processId]);
|
|
150
|
+
const queue = [root];
|
|
151
|
+
for (let index = 0; index < queue.length && found.length < maxDescendants; index++) {
|
|
152
|
+
const parent = queue[index];
|
|
153
|
+
for (const child of children.get(parent.processId) ?? []) {
|
|
154
|
+
if (seen.has(child.processId) || child.processId <= 1 || child.processId === observerProcessId)
|
|
155
|
+
continue;
|
|
156
|
+
seen.add(child.processId);
|
|
157
|
+
// ps start times have one-second resolution.
|
|
158
|
+
if (child.zombie || child.startedAt < parent.startedAt - 999)
|
|
159
|
+
continue;
|
|
160
|
+
found.push(child);
|
|
161
|
+
queue.push(child);
|
|
162
|
+
if (found.length >= maxDescendants)
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return found;
|
|
167
|
+
}
|
|
168
|
+
function sameStart(observed, expected) {
|
|
169
|
+
return Math.abs(observed - expected) < 1_000;
|
|
170
|
+
}
|
|
171
|
+
export async function readUnixProcessTable() {
|
|
172
|
+
const stdout = await new Promise((resolve, reject) => execFile("ps", ["-A", "-o", "pid=,ppid=,stat=,lstart="], { timeout: 3_000, maxBuffer: 8 << 20, encoding: "utf8", env: { ...process.env, LANG: "C", LC_ALL: "C" } }, (error, output) => error ? reject(error) : resolve(output)));
|
|
173
|
+
return parseUnixProcessTable(stdout);
|
|
174
|
+
}
|
|
175
|
+
export function parseUnixProcessTable(stdout) {
|
|
176
|
+
const table = new Map();
|
|
177
|
+
for (const line of stdout.split(/\r?\n/u)) {
|
|
178
|
+
const match = /^\s*(\d+)\s+(\d+)\s+(\S+)\s+(\S+\s+\S+\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}\s+\d{4})\s*$/u.exec(line);
|
|
179
|
+
if (match === null)
|
|
180
|
+
continue;
|
|
181
|
+
const processId = Number(match[1]);
|
|
182
|
+
const startedAt = Date.parse(match[4]);
|
|
183
|
+
if (!Number.isSafeInteger(processId) || processId < 1 || !Number.isFinite(startedAt))
|
|
184
|
+
continue;
|
|
185
|
+
table.set(processId, { processId, parentId: Number(match[2]), startedAt, zombie: match[3].startsWith("Z") });
|
|
186
|
+
}
|
|
187
|
+
return table;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Windows: the native helper holds a handle to every member while it works,
|
|
191
|
+
* so no member's PID can be recycled before the report is written.
|
|
192
|
+
*/
|
|
193
|
+
export class WindowsProcessTreeControl {
|
|
194
|
+
#run;
|
|
195
|
+
constructor(run) {
|
|
196
|
+
this.#run = run ?? runGuardianHelper;
|
|
197
|
+
}
|
|
198
|
+
async stop(target, mode) {
|
|
199
|
+
let stdout;
|
|
200
|
+
try {
|
|
201
|
+
stdout = await this.#run([
|
|
202
|
+
"--kill-pid", String(target.processId),
|
|
203
|
+
"--started-at", target.startedAt.toISOString(),
|
|
204
|
+
"--tree", ...(mode === "stop" ? ["--graceful"] : []),
|
|
205
|
+
]);
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
const code = error.killed === true
|
|
209
|
+
? "helper_timeout"
|
|
210
|
+
: `helper_${String(error.code ?? "failed")}`;
|
|
211
|
+
return { outcome: "failed", code: code.slice(0, 32) };
|
|
212
|
+
}
|
|
213
|
+
return parseTreeReport(stdout);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
function runGuardianHelper(args) {
|
|
217
|
+
return new Promise((resolve, reject) => execFile(guardianRunnerPath(), args, {
|
|
218
|
+
windowsHide: true, timeout: 20_000, maxBuffer: 16 << 10, encoding: "utf8",
|
|
219
|
+
}, (error, stdout) => error ? reject(error) : resolve(stdout)));
|
|
220
|
+
}
|
|
221
|
+
export function parseTreeReport(stdout) {
|
|
222
|
+
let value;
|
|
223
|
+
try {
|
|
224
|
+
value = JSON.parse(stdout.trim());
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
return { outcome: "failed", code: "helper_report_invalid" };
|
|
228
|
+
}
|
|
229
|
+
if (value === null || typeof value !== "object")
|
|
230
|
+
return { outcome: "failed", code: "helper_report_invalid" };
|
|
231
|
+
const report = value;
|
|
232
|
+
const count = (key) => {
|
|
233
|
+
const item = report[key];
|
|
234
|
+
return typeof item === "number" && Number.isSafeInteger(item) && item >= 0 ? item : 0;
|
|
235
|
+
};
|
|
236
|
+
switch (report["outcome"]) {
|
|
237
|
+
case "stale":
|
|
238
|
+
case "exited":
|
|
239
|
+
case "access_denied":
|
|
240
|
+
case "graceful_unsupported":
|
|
241
|
+
case "console_shared":
|
|
242
|
+
case "self_target":
|
|
243
|
+
return { outcome: report["outcome"] };
|
|
244
|
+
case "dispatched":
|
|
245
|
+
return {
|
|
246
|
+
outcome: "dispatched",
|
|
247
|
+
rootRunning: report["root_running"] === true,
|
|
248
|
+
descendants: count("descendants"),
|
|
249
|
+
descendantsRunning: count("descendants_running"),
|
|
250
|
+
descendantsDenied: count("descendants_denied"),
|
|
251
|
+
};
|
|
252
|
+
default:
|
|
253
|
+
return { outcome: "failed", code: `helper_${String(report["outcome"] ?? "invalid")}`.slice(0, 32) };
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=process-tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-tree.js","sourceRoot":"","sources":["../../src/process-tree.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as tls from "node:tls";
|
|
2
|
+
/**
|
|
3
|
+
* A company's own Phigon server (run by the Phigon app) signs its HTTPS
|
|
4
|
+
* certificate with an authority of its own. The pairing command carries
|
|
5
|
+
* that authority's SHA-256 fingerprint; pairing pins it here, and every
|
|
6
|
+
* later HTTPS and gRPC connection trusts it.
|
|
7
|
+
*/
|
|
8
|
+
export declare const SERVER_AUTHORITY_FILE = "server-ca.pem";
|
|
9
|
+
export declare function serverAuthorityPath(dataDirectory: string): string;
|
|
10
|
+
/** Reads `--server-ca-sha256`: 64 hex characters, with or without colons. */
|
|
11
|
+
export declare function parseAuthorityFingerprint(value: string): string;
|
|
12
|
+
/** Adds an authority to the ones this process trusts for HTTPS and gRPC. */
|
|
13
|
+
export declare function trustAuthority(pem: string): void;
|
|
14
|
+
/** Trusts the authority saved when this computer paired, and returns its file. */
|
|
15
|
+
export declare function trustSavedAuthority(dataDirectory: string): string | undefined;
|
|
16
|
+
export declare function forgetServerAuthority(dataDirectory: string): Promise<void>;
|
|
17
|
+
type Connect = (options: tls.ConnectionOptions, listener: () => void) => tls.TLSSocket;
|
|
18
|
+
/**
|
|
19
|
+
* Finds the certificate in the server's chain whose SHA-256 matches the
|
|
20
|
+
* pinned fingerprint, saves it and trusts it. Nothing is sent to the server
|
|
21
|
+
* on this connection; the requests that follow are verified normally,
|
|
22
|
+
* including the server's name, against the pinned authority.
|
|
23
|
+
*/
|
|
24
|
+
export declare function pinServerAuthority(url: URL, fingerprint: string, dataDirectory: string, connect?: Connect): Promise<string>;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=server-authority.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-authority.d.ts","sourceRoot":"","sources":["../../src/server-authority.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,kBAAkB,CAAC;AAIrD,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,6EAA6E;AAC7E,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM/D;AAED,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAQhD;AAED,kFAAkF;AAClF,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAK7E;AAED,wBAAsB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhF;AAED,KAAK,OAAO,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,iBAAiB,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,GAAG,CAAC,SAAS,CAAC;AAEvF;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,GAAG,EACR,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,OAAqB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAcjB"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { createHash, X509Certificate } from "node:crypto";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { isIP } from "node:net";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import * as tls from "node:tls";
|
|
7
|
+
/**
|
|
8
|
+
* A company's own Phigon server (run by the Phigon app) signs its HTTPS
|
|
9
|
+
* certificate with an authority of its own. The pairing command carries
|
|
10
|
+
* that authority's SHA-256 fingerprint; pairing pins it here, and every
|
|
11
|
+
* later HTTPS and gRPC connection trusts it.
|
|
12
|
+
*/
|
|
13
|
+
export const SERVER_AUTHORITY_FILE = "server-ca.pem";
|
|
14
|
+
const FINGERPRINT = /^[0-9a-f]{64}$/u;
|
|
15
|
+
export function serverAuthorityPath(dataDirectory) {
|
|
16
|
+
return join(dataDirectory, SERVER_AUTHORITY_FILE);
|
|
17
|
+
}
|
|
18
|
+
/** Reads `--server-ca-sha256`: 64 hex characters, with or without colons. */
|
|
19
|
+
export function parseAuthorityFingerprint(value) {
|
|
20
|
+
const normalized = value.trim().toLowerCase().replace(/:/gu, "");
|
|
21
|
+
if (!FINGERPRINT.test(normalized)) {
|
|
22
|
+
throw new Error("--server-ca-sha256 must be the 64-character fingerprint from the Connect machine dialog.");
|
|
23
|
+
}
|
|
24
|
+
return normalized;
|
|
25
|
+
}
|
|
26
|
+
/** Adds an authority to the ones this process trusts for HTTPS and gRPC. */
|
|
27
|
+
export function trustAuthority(pem) {
|
|
28
|
+
if (typeof tls.setDefaultCACertificates !== "function" || typeof tls.getCACertificates !== "function") {
|
|
29
|
+
throw new Error("Connecting to a company's own Phigon server needs Node.js 24.5 or newer. Update Node.js and try again.");
|
|
30
|
+
}
|
|
31
|
+
const current = tls.getCACertificates("default");
|
|
32
|
+
if (!current.some((certificate) => sameCertificate(certificate, pem))) {
|
|
33
|
+
tls.setDefaultCACertificates([...current, pem]);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** Trusts the authority saved when this computer paired, and returns its file. */
|
|
37
|
+
export function trustSavedAuthority(dataDirectory) {
|
|
38
|
+
const file = serverAuthorityPath(dataDirectory);
|
|
39
|
+
if (!existsSync(file))
|
|
40
|
+
return undefined;
|
|
41
|
+
trustAuthority(readFileSync(file, "utf8"));
|
|
42
|
+
return file;
|
|
43
|
+
}
|
|
44
|
+
export async function forgetServerAuthority(dataDirectory) {
|
|
45
|
+
await rm(serverAuthorityPath(dataDirectory), { force: true });
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Finds the certificate in the server's chain whose SHA-256 matches the
|
|
49
|
+
* pinned fingerprint, saves it and trusts it. Nothing is sent to the server
|
|
50
|
+
* on this connection; the requests that follow are verified normally,
|
|
51
|
+
* including the server's name, against the pinned authority.
|
|
52
|
+
*/
|
|
53
|
+
export async function pinServerAuthority(url, fingerprint, dataDirectory, connect = tls.connect) {
|
|
54
|
+
if (url.protocol !== "https:") {
|
|
55
|
+
throw new Error("--server-ca-sha256 needs an https:// control plane URL.");
|
|
56
|
+
}
|
|
57
|
+
const chain = await peerChain(url, connect);
|
|
58
|
+
const match = chain.find((raw) => createHash("sha256").update(raw).digest("hex") === fingerprint);
|
|
59
|
+
if (match === undefined) {
|
|
60
|
+
throw new Error("The server's certificate does not match the fingerprint in the pairing command. Check that this computer is on the right network and that you copied the whole command.");
|
|
61
|
+
}
|
|
62
|
+
const pem = new X509Certificate(match).toString();
|
|
63
|
+
trustAuthority(pem);
|
|
64
|
+
const file = serverAuthorityPath(dataDirectory);
|
|
65
|
+
await writeFile(file, pem, { mode: 0o600 });
|
|
66
|
+
return file;
|
|
67
|
+
}
|
|
68
|
+
function peerChain(url, connect) {
|
|
69
|
+
const host = url.hostname.replace(/^\[|\]$/gu, "");
|
|
70
|
+
const port = Number(url.port || 443);
|
|
71
|
+
return new Promise((resolve, reject) => {
|
|
72
|
+
const socket = connect({
|
|
73
|
+
host,
|
|
74
|
+
port,
|
|
75
|
+
...(isIP(host) ? {} : { servername: host }),
|
|
76
|
+
// Only to read the chain; the fingerprint decides what is trusted.
|
|
77
|
+
rejectUnauthorized: false,
|
|
78
|
+
timeout: 15_000,
|
|
79
|
+
}, () => {
|
|
80
|
+
const chain = [];
|
|
81
|
+
const seen = new Set();
|
|
82
|
+
let certificate = socket.getPeerCertificate(true);
|
|
83
|
+
while (certificate?.raw && !seen.has(certificate.fingerprint256)) {
|
|
84
|
+
seen.add(certificate.fingerprint256);
|
|
85
|
+
chain.push(certificate.raw);
|
|
86
|
+
certificate = certificate.issuerCertificate;
|
|
87
|
+
}
|
|
88
|
+
socket.end();
|
|
89
|
+
resolve(chain);
|
|
90
|
+
});
|
|
91
|
+
socket.once("error", (error) => reject(new Error(`Could not reach ${url.host}: ${error.message}`)));
|
|
92
|
+
socket.once("timeout", () => {
|
|
93
|
+
socket.destroy();
|
|
94
|
+
reject(new Error(`Connecting to ${url.host} timed out. Check that this computer can reach it on the network.`));
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function sameCertificate(a, b) {
|
|
99
|
+
const strip = (pem) => pem.replace(/\s+/gu, "");
|
|
100
|
+
return strip(a) === strip(b);
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=server-authority.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-authority.js","sourceRoot":"","sources":["../../src/server-authority.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,8 @@ export type ObserverStreamMetrics = Readonly<{
|
|
|
15
15
|
lastAcknowledgedSequence: bigint;
|
|
16
16
|
queue: QueueMetrics;
|
|
17
17
|
}>;
|
|
18
|
+
/** What the stream needs from the action executor. */
|
|
19
|
+
export type ActionExecutor = Pick<AgentActionExecutor, "execute" | "manifest">;
|
|
18
20
|
export type StreamClientOptions = Readonly<{
|
|
19
21
|
config: ObserverConfig;
|
|
20
22
|
credentialStore?: CredentialStore;
|
|
@@ -25,7 +27,7 @@ export type StreamClientOptions = Readonly<{
|
|
|
25
27
|
onPolicy?: (policy: CollectionPolicy) => void;
|
|
26
28
|
onCursorReset?: (acknowledgedSequence: bigint, allocationSequence: bigint) => void;
|
|
27
29
|
onAcknowledgement?: (sequence: bigint) => void | Promise<void>;
|
|
28
|
-
actionExecutor?:
|
|
30
|
+
actionExecutor?: ActionExecutor;
|
|
29
31
|
onHistorySync?: (command: HistorySyncCommand) => Promise<HistorySyncResult>;
|
|
30
32
|
handshakeTimeoutMs?: number;
|
|
31
33
|
responseTimeoutMs?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream-client.d.ts","sourceRoot":"","sources":["../../src/stream-client.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAgC,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAOhF,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAExE,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,0CAA0C,CAAC;AAWlD,OAAO,EAKL,KAAK,gBAAgB,EACtB,MAAM,oCAAoC,CAAC;AAK5C,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,KAAK,sBAAsB,GAAG,IAAI,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAOtE,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,wBAAwB,EAAE,MAAM,CAAC;IACjC,KAAK,EAAE,YAAY,CAAC;CACrB,CAAC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,MAAM,EAAE,cAAc,CAAC;IACvB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,UAAU,CAAC,EAAE,sBAAsB,CAAC;IACpC,KAAK,CAAC,EAAE,iBAAiB,CAAC,aAAa,CAAC,CAAC;IACzC,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;IAC5C,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC9C,aAAa,CAAC,EAAE,CACd,oBAAoB,EAAE,MAAM,EAC5B,kBAAkB,EAAE,MAAM,KACvB,IAAI,CAAC;IACV,iBAAiB,CAAC,EAAE,CAClB,QAAQ,EAAE,MAAM,KACb,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,cAAc,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"stream-client.d.ts","sourceRoot":"","sources":["../../src/stream-client.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAgC,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAOhF,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAExE,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,0CAA0C,CAAC;AAWlD,OAAO,EAKL,KAAK,gBAAgB,EACtB,MAAM,oCAAoC,CAAC;AAK5C,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,KAAK,sBAAsB,GAAG,IAAI,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAOtE,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,wBAAwB,EAAE,MAAM,CAAC;IACjC,KAAK,EAAE,YAAY,CAAC;CACrB,CAAC,CAAC;AAEH,sDAAsD;AACtD,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,mBAAmB,EAAE,SAAS,GAAG,UAAU,CAAC,CAAC;AAE/E,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,MAAM,EAAE,cAAc,CAAC;IACvB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,UAAU,CAAC,EAAE,sBAAsB,CAAC;IACpC,KAAK,CAAC,EAAE,iBAAiB,CAAC,aAAa,CAAC,CAAC;IACzC,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;IAC5C,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC9C,aAAa,CAAC,EAAE,CACd,oBAAoB,EAAE,MAAM,EAC5B,kBAAkB,EAAE,MAAM,KACvB,IAAI,CAAC;IACV,iBAAiB,CAAC,EAAE,CAClB,QAAQ,EAAE,MAAM,KACb,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC5E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC,CAAC;AAEH,qBAAa,oBAAoB;;gBA+BnB,OAAO,EAAE,mBAAmB;IA2BxC,OAAO,CAAC,KAAK,EAAE,aAAa,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAWzD,eAAe,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI;IAK1C,cAAc,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAoBrD,GAAG,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA6B7C,OAAO,IAAI,qBAAqB;CAulBjC;AA0FD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,gBAAgB,GACvB,aAAa,CA2If"}
|