@byok-sdk/client 0.1.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/LICENSE +21 -0
- package/README.md +11 -0
- package/dist/adapters/claude/claude-adapter.d.ts +155 -0
- package/dist/adapters/claude/events.d.ts +91 -0
- package/dist/adapters/claude/permission-mapping.d.ts +142 -0
- package/dist/adapters/claude/process-client.d.ts +103 -0
- package/dist/adapters/claude/resolve-approval-mcp-bin.d.ts +45 -0
- package/dist/adapters/claude/resolve-bin.d.ts +27 -0
- package/dist/adapters/codex/codex-adapter.d.ts +97 -0
- package/dist/adapters/codex/events.d.ts +41 -0
- package/dist/adapters/codex/permission-mapping.d.ts +107 -0
- package/dist/adapters/codex/process-runner.d.ts +86 -0
- package/dist/adapters/codex/resolve-bin.d.ts +25 -0
- package/dist/adapters/pi/events.d.ts +58 -0
- package/dist/adapters/pi/permission-mapping.d.ts +46 -0
- package/dist/adapters/pi/pi-adapter.d.ts +29 -0
- package/dist/adapters/pi/resolve-bin.d.ts +44 -0
- package/dist/adapters/pi/rpc-client.d.ts +101 -0
- package/dist/bin/approval-mcp-server.d.ts +69 -0
- package/dist/bin/audit-log.d.ts +212 -0
- package/dist/bin/byok-agent.d.ts +2 -0
- package/dist/bin/byok-agent.js +12347 -0
- package/dist/bin/byok-agent.js.map +1 -0
- package/dist/bin/byok-approval-mcp.d.ts +2 -0
- package/dist/bin/byok-approval-mcp.js +498 -0
- package/dist/bin/byok-approval-mcp.js.map +1 -0
- package/dist/bin/commands/approvals.d.ts +31 -0
- package/dist/bin/commands/approve-reject.d.ts +29 -0
- package/dist/bin/commands/doctor.d.ts +15 -0
- package/dist/bin/commands/pair.d.ts +7 -0
- package/dist/bin/commands/runtimes.d.ts +7 -0
- package/dist/bin/commands/service.d.ts +54 -0
- package/dist/bin/commands/start.d.ts +21 -0
- package/dist/bin/commands/status.d.ts +25 -0
- package/dist/bin/commands/support-bundle.d.ts +7 -0
- package/dist/bin/commands/tasks.d.ts +27 -0
- package/dist/bin/commands/unpair.d.ts +124 -0
- package/dist/bin/commands/workspaces.d.ts +16 -0
- package/dist/bin/config.d.ts +41 -0
- package/dist/bin/control-client.d.ts +50 -0
- package/dist/bin/format.d.ts +67 -0
- package/dist/bin/runtime-probe.d.ts +34 -0
- package/dist/bin/tasks-view.d.ts +49 -0
- package/dist/daemon/approvals.d.ts +87 -0
- package/dist/daemon/auth-manager.d.ts +52 -0
- package/dist/daemon/blob-client.d.ts +22 -0
- package/dist/daemon/connection-manager.d.ts +502 -0
- package/dist/daemon/control-protocol.d.ts +299 -0
- package/dist/daemon/control-server.d.ts +61 -0
- package/dist/daemon/create-daemon.d.ts +364 -0
- package/dist/daemon/cursor-store.d.ts +30 -0
- package/dist/daemon/daemon-owner.d.ts +24 -0
- package/dist/daemon/deterministic-jitter.d.ts +20 -0
- package/dist/daemon/device-keys.d.ts +45 -0
- package/dist/daemon/device-proof-signer.d.ts +41 -0
- package/dist/daemon/environment.d.ts +96 -0
- package/dist/daemon/git-workspace-store.d.ts +49 -0
- package/dist/daemon/git-workspace.d.ts +80 -0
- package/dist/daemon/http-client.d.ts +8 -0
- package/dist/daemon/journal/journal.d.ts +342 -0
- package/dist/daemon/journal/sqlite-journal.d.ts +173 -0
- package/dist/daemon/journal/sqlite-support.d.ts +96 -0
- package/dist/daemon/journal/storage-policy.d.ts +368 -0
- package/dist/daemon/long-poll-transport.d.ts +142 -0
- package/dist/daemon/observer.d.ts +345 -0
- package/dist/daemon/operational-health.d.ts +87 -0
- package/dist/daemon/policy.d.ts +16 -0
- package/dist/daemon/progress-batcher.d.ts +31 -0
- package/dist/daemon/runtime-capabilities.d.ts +36 -0
- package/dist/daemon/session-workspace-store.d.ts +75 -0
- package/dist/daemon/store.d.ts +54 -0
- package/dist/daemon/task-runner.d.ts +862 -0
- package/dist/daemon/truth-memory-client.d.ts +94 -0
- package/dist/daemon/url.d.ts +60 -0
- package/dist/daemon/ws-transport.d.ts +110 -0
- package/dist/diagnostics/diagnostics.d.ts +114 -0
- package/dist/diagnostics/support-bundle.d.ts +81 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +10056 -0
- package/dist/index.js.map +1 -0
- package/dist/lifecycle/create-service-lifecycle.d.ts +59 -0
- package/dist/lifecycle/exec-runner.d.ts +141 -0
- package/dist/lifecycle/launchd.d.ts +55 -0
- package/dist/lifecycle/service-types.d.ts +177 -0
- package/dist/lifecycle/systemd.d.ts +46 -0
- package/dist/lifecycle/winsw.d.ts +64 -0
- package/dist/types.d.ts +178 -0
- package/dist/util/async-queue.d.ts +45 -0
- package/dist/util/atomic-write.d.ts +86 -0
- package/dist/util/secure-dir.d.ts +124 -0
- package/package.json +66 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { type ContentHash, type TruthRecordKind, type TruthRecordSelector } from '@byok-sdk/core';
|
|
2
|
+
import type { DeviceProofSigner } from './device-proof-signer';
|
|
3
|
+
export interface TruthManifestRecord {
|
|
4
|
+
readonly kind: TruthRecordKind;
|
|
5
|
+
readonly recordKey: string;
|
|
6
|
+
readonly rev: number;
|
|
7
|
+
readonly contentHash: ContentHash;
|
|
8
|
+
readonly byteSize: number;
|
|
9
|
+
readonly label?: string;
|
|
10
|
+
readonly updatedAt: string;
|
|
11
|
+
}
|
|
12
|
+
export interface TruthManifestQueryInput {
|
|
13
|
+
readonly kind?: TruthRecordKind;
|
|
14
|
+
readonly keyPrefix?: string;
|
|
15
|
+
readonly limit?: number;
|
|
16
|
+
}
|
|
17
|
+
/** Cloud-agnostic local semantic selection. It sees metadata and no body bytes. */
|
|
18
|
+
export interface MemorySelector {
|
|
19
|
+
select(manifest: readonly TruthManifestRecord[]): readonly TruthRecordSelector[] | Promise<readonly TruthRecordSelector[]>;
|
|
20
|
+
}
|
|
21
|
+
/** A body reaches this seam only after manifest equality, byte-size and SHA-256 checks. */
|
|
22
|
+
export interface VerifiedTruthRecord extends TruthManifestRecord {
|
|
23
|
+
readonly bytes: Uint8Array;
|
|
24
|
+
}
|
|
25
|
+
/** The only value returned by `loadSelected`; runtime prompt/context shape stays host-owned. */
|
|
26
|
+
export interface LocalMemoryFilter<Context> {
|
|
27
|
+
filter(records: readonly VerifiedTruthRecord[]): Context | Promise<Context>;
|
|
28
|
+
}
|
|
29
|
+
export interface TruthMemoryMetric {
|
|
30
|
+
readonly kind: 'truth.snapshot.large';
|
|
31
|
+
readonly selector: TruthRecordSelector;
|
|
32
|
+
readonly byteSize: number;
|
|
33
|
+
readonly thresholdBytes: number;
|
|
34
|
+
}
|
|
35
|
+
export interface TruthMemoryClientOptions {
|
|
36
|
+
readonly serverUrl: string;
|
|
37
|
+
readonly signer: DeviceProofSigner;
|
|
38
|
+
/** Exact http(s) origins permitted to receive object-download grants. An empty list disables object reads. */
|
|
39
|
+
readonly allowedObjectDownloadOrigins: readonly string[];
|
|
40
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
41
|
+
readonly requestId?: () => string;
|
|
42
|
+
readonly onMetric?: (metric: TruthMemoryMetric) => void;
|
|
43
|
+
}
|
|
44
|
+
export type TruthWriteBody = {
|
|
45
|
+
readonly kind: 'inline';
|
|
46
|
+
readonly content: string;
|
|
47
|
+
} | {
|
|
48
|
+
readonly kind: 'object';
|
|
49
|
+
readonly contentHash: string;
|
|
50
|
+
readonly byteSize: number;
|
|
51
|
+
};
|
|
52
|
+
export interface TruthSnapshotWriteInput {
|
|
53
|
+
readonly kind: 'profile' | 'memory';
|
|
54
|
+
readonly recordKey: string;
|
|
55
|
+
readonly expectedRev: number;
|
|
56
|
+
readonly body: TruthWriteBody;
|
|
57
|
+
readonly requestId: string;
|
|
58
|
+
readonly label?: string;
|
|
59
|
+
}
|
|
60
|
+
export interface TruthSnapshotCandidateInput {
|
|
61
|
+
readonly kind: 'profile' | 'memory';
|
|
62
|
+
readonly recordKey: string;
|
|
63
|
+
readonly expectedRev: number;
|
|
64
|
+
readonly body: TruthWriteBody;
|
|
65
|
+
readonly label?: string;
|
|
66
|
+
}
|
|
67
|
+
export interface TruthTerminalWriteInput {
|
|
68
|
+
readonly taskId: string;
|
|
69
|
+
readonly body: TruthWriteBody;
|
|
70
|
+
readonly requestId: string;
|
|
71
|
+
readonly label?: string;
|
|
72
|
+
readonly snapshots?: readonly TruthSnapshotCandidateInput[];
|
|
73
|
+
}
|
|
74
|
+
export interface TruthWriteResult {
|
|
75
|
+
readonly primary: TruthManifestRecord;
|
|
76
|
+
readonly snapshots: readonly TruthManifestRecord[];
|
|
77
|
+
readonly replayed: boolean;
|
|
78
|
+
}
|
|
79
|
+
export type TruthMemoryClientErrorCode = 'truth_http_failed' | 'truth_response_invalid' | 'truth_selection_invalid' | 'truth_manifest_changed' | 'truth_content_size_mismatch' | 'truth_content_hash_mismatch' | 'truth_object_url_rejected' | 'truth_write_invalid' | 'truth_write_confirmation_mismatch';
|
|
80
|
+
export declare class TruthMemoryClientError extends Error {
|
|
81
|
+
readonly code: TruthMemoryClientErrorCode;
|
|
82
|
+
readonly status?: number | undefined;
|
|
83
|
+
constructor(code: TruthMemoryClientErrorCode, message: string, status?: number | undefined);
|
|
84
|
+
}
|
|
85
|
+
/** Proof-only client for S6 truth records. It never sends a bearer token. */
|
|
86
|
+
export declare class TruthMemoryClient {
|
|
87
|
+
#private;
|
|
88
|
+
private readonly options;
|
|
89
|
+
constructor(options: TruthMemoryClientOptions);
|
|
90
|
+
listManifest(query?: TruthManifestQueryInput): Promise<readonly TruthManifestRecord[]>;
|
|
91
|
+
loadSelected<Context>(selector: MemorySelector, filter: LocalMemoryFilter<Context>, query?: TruthManifestQueryInput): Promise<Context>;
|
|
92
|
+
writeSnapshot(input: TruthSnapshotWriteInput): Promise<TruthWriteResult>;
|
|
93
|
+
writeTerminal(input: TruthTerminalWriteInput): Promise<TruthWriteResult>;
|
|
94
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** Normalize a configured `serverUrl` (http/https/ws/wss, any path) to an http(s) base with no path/query. */
|
|
2
|
+
export declare function toHttpBase(serverUrl: string): string;
|
|
3
|
+
/** Derive the `/byok/ws` WebSocket URL from a configured `serverUrl`. */
|
|
4
|
+
export declare function toWsUrl(serverUrl: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* M5: thrown by {@link assertServerUrlAllowed} — see that function's own doc
|
|
7
|
+
* comment for the full allow/deny rule this names. Deliberately ONE error
|
|
8
|
+
* type for every way the gate can refuse a `serverUrl` (plaintext-to-remote,
|
|
9
|
+
* or a scheme this SDK's transport has no meaning for at all): a catching
|
|
10
|
+
* caller only ever needs "the configured server URL failed the
|
|
11
|
+
* transport-security gate", never which specific sub-case fired — the
|
|
12
|
+
* message text (not the type) carries that detail.
|
|
13
|
+
*/
|
|
14
|
+
export declare class InsecureServerUrlError extends Error {
|
|
15
|
+
constructor(message: string);
|
|
16
|
+
}
|
|
17
|
+
export interface AssertServerUrlAllowedOptions {
|
|
18
|
+
/**
|
|
19
|
+
* Explicit escape hatch: when `true`, a `http:`/`ws:` `serverUrl` whose
|
|
20
|
+
* host is NOT loopback is allowed through instead of throwing. Does
|
|
21
|
+
* nothing for an unsupported scheme (see {@link assertServerUrlAllowed}'s
|
|
22
|
+
* own doc comment) — that rejection is unconditional. Threaded from
|
|
23
|
+
* `DaemonConfig.dangerouslyAllowInsecureRemote`; this function itself
|
|
24
|
+
* never logs anything when the hatch is exercised — it stays a pure,
|
|
25
|
+
* synchronous, easily-unit-testable gate — so a caller that sets this
|
|
26
|
+
* true is expected to emit its own warning (see `create-daemon.ts`'s
|
|
27
|
+
* `checkServerUrl`).
|
|
28
|
+
*/
|
|
29
|
+
dangerouslyAllowInsecureRemote?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* M5: transport-security gate for a configured `serverUrl` — refuses
|
|
33
|
+
* plaintext (`ws:`/`http:`) transport to any non-loopback host, so a device
|
|
34
|
+
* can never be talked into pairing with (and sending its pairing code /
|
|
35
|
+
* device credentials to) a remote host in the clear. Call this ONCE at each
|
|
36
|
+
* real entry point a raw, operator-supplied `serverUrl` first enters the
|
|
37
|
+
* client (`create-daemon.ts`'s `pair()`/`start()`) rather than inside
|
|
38
|
+
* `toHttpBase`/`toWsUrl` themselves: ws-transport, the long-poll fallback,
|
|
39
|
+
* and blob-client all read `serverUrl` from that SAME `DaemonConfig`, never
|
|
40
|
+
* an independently-supplied URL of their own, so those two call sites are
|
|
41
|
+
* already the single common path every one of them goes through.
|
|
42
|
+
*
|
|
43
|
+
* Rules, checked in order:
|
|
44
|
+
* - `https:`/`wss:` — always allowed, any host (TLS is the actual
|
|
45
|
+
* plaintext-network defense; this gate has nothing further to add there).
|
|
46
|
+
* - `http:`/`ws:` — allowed only when the hostname is loopback: exactly
|
|
47
|
+
* `localhost` or any `*.localhost` subdomain, an IPv4 literal in
|
|
48
|
+
* `127.0.0.0/8`, or the IPv6 loopback `::1` — see {@link isLoopbackHostname}.
|
|
49
|
+
* - `http:`/`ws:` to any other host — refused with a clear, typed
|
|
50
|
+
* {@link InsecureServerUrlError} naming the offending URL and the fix
|
|
51
|
+
* (use `wss:`/`https:`, or pass `dangerouslyAllowInsecureRemote: true` if
|
|
52
|
+
* this is a deliberate, understood exception) — UNLESS
|
|
53
|
+
* `opts.dangerouslyAllowInsecureRemote` is `true`.
|
|
54
|
+
* - Any other scheme (or a `serverUrl` that fails to parse as a URL at
|
|
55
|
+
* all) — always refused, regardless of `dangerouslyAllowInsecureRemote`:
|
|
56
|
+
* the escape hatch is specifically for "plaintext to a remote host I
|
|
57
|
+
* understand the risk of", not "a scheme this transport doesn't
|
|
58
|
+
* implement at all".
|
|
59
|
+
*/
|
|
60
|
+
export declare function assertServerUrlAllowed(rawUrl: string, opts?: AssertServerUrlAllowedOptions): void;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { type CapabilityFlag, type Envelope, type RuntimeInfo } from '@byok-sdk/protocol';
|
|
2
|
+
export type ConnectionState = 'connecting' | 'open' | 'closed' | 'degraded' | 'revoked';
|
|
3
|
+
/** The WS upgrade itself was rejected with a non-101 HTTP status (e.g. 401 for an expired/invalid bearer token). Surfaced via `onConnectOutcome` so `ConnectionManager` can force a reactive token renewal before the next attempt (protocol §6.2, "reactively on 401"). */
|
|
4
|
+
export declare class WsUnexpectedStatusError extends Error {
|
|
5
|
+
readonly status: number;
|
|
6
|
+
constructor(status: number);
|
|
7
|
+
}
|
|
8
|
+
export interface BackoffOptions {
|
|
9
|
+
baseMs?: number;
|
|
10
|
+
maxMs?: number;
|
|
11
|
+
factor?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface LivenessOptions {
|
|
14
|
+
/** Terminate and reconnect if no data/ping arrives for this long. Default 75s (server pings every 30s per the pinned heartbeat convention). */
|
|
15
|
+
timeoutMs?: number;
|
|
16
|
+
/** How often to check for silence. Default: timeoutMs/3, floored at 1s. */
|
|
17
|
+
checkIntervalMs?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface WsTransportOptions {
|
|
20
|
+
serverUrl: string;
|
|
21
|
+
/** Resolves the current valid bearer token; called fresh before every connect attempt (initial and every reconnect) so a proactively-renewed token is always used. */
|
|
22
|
+
getToken: () => Promise<string>;
|
|
23
|
+
deviceId: string;
|
|
24
|
+
productId: string;
|
|
25
|
+
capabilities: CapabilityFlag[];
|
|
26
|
+
/** Detected runtimes, sent on every `conn.hello` (protocol §10 gap #4/#11). */
|
|
27
|
+
runtimes?: RuntimeInfo[];
|
|
28
|
+
/** The redelivery cursor to send as `conn.hello.cursor` (protocol §9) — read fresh on every connect so a value learned mid-connection is used on the next reconnect. */
|
|
29
|
+
getCursor?: () => number | undefined;
|
|
30
|
+
onEnvelope: (envelope: Envelope) => void;
|
|
31
|
+
onStateChange?: (state: ConnectionState) => void;
|
|
32
|
+
/**
|
|
33
|
+
* Fired the moment `conn.ack` is processed and the connection becomes
|
|
34
|
+
* usable — independent of `onConnectOutcome`, which only fires on close (a
|
|
35
|
+
* healthy, still-open connection never reaches it). Carries the ack's own
|
|
36
|
+
* `capabilities` (untyped `string[]` on the wire, forward-compat — a
|
|
37
|
+
* server may advertise a flag this build doesn't recognize yet), so a
|
|
38
|
+
* caller can learn what the CURRENTLY connected server understands (e.g.
|
|
39
|
+
* the `approval_resolved` capability flag — see
|
|
40
|
+
* `ConnectionManager.getServerCapabilities`) instead of it being silently
|
|
41
|
+
* discarded after the handshake completes.
|
|
42
|
+
*/
|
|
43
|
+
onAcked?: (capabilities: string[]) => void;
|
|
44
|
+
/**
|
|
45
|
+
* Fired once per connection attempt when the socket closes, reporting
|
|
46
|
+
* whether that attempt ever reached `conn.ack` (`acked`) before closing,
|
|
47
|
+
* and the causing error when the attempt failed before a socket even
|
|
48
|
+
* opened (e.g. `getToken()` rejecting). Used by `ConnectionManager` to
|
|
49
|
+
* count consecutive failures for the long-poll fallback (protocol §8).
|
|
50
|
+
*/
|
|
51
|
+
onConnectOutcome?: (acked: boolean, err?: unknown) => void;
|
|
52
|
+
backoff?: BackoffOptions;
|
|
53
|
+
liveness?: LivenessOptions;
|
|
54
|
+
/** Deterministic automatic reconnect delay. Manual `connect({auto:false})` never reaches this scheduler. */
|
|
55
|
+
reconnectDelayMs?: (attempt: number, baseDelayMs: number) => number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The daemon's outbound-only WS connection: opens, sends `conn.hello`, waits
|
|
59
|
+
* for `conn.ack`, and reconnects with capped exponential backoff + jitter on
|
|
60
|
+
* drop.
|
|
61
|
+
*
|
|
62
|
+
* Design B (finding N4): this transport is a stateless drainer — it holds no
|
|
63
|
+
* outbound queue of its own. `ConnectionManager` owns the single shared
|
|
64
|
+
* outbox both transports drain from (so a transport switch never strands a
|
|
65
|
+
* queued envelope); `sendNow` just attempts to hand one envelope to the
|
|
66
|
+
* live socket right now and reports back whether that actually happened,
|
|
67
|
+
* leaving all queueing/retry policy to the caller.
|
|
68
|
+
*
|
|
69
|
+
* Auto-reconnect can be paused (`stopAutoReconnect`) and single attempts
|
|
70
|
+
* made on demand (`connect({ auto: false })`) — used by `ConnectionManager`
|
|
71
|
+
* to probe WS recovery every few minutes while long-polling, without this
|
|
72
|
+
* transport's own backoff loop fighting that cadence.
|
|
73
|
+
*/
|
|
74
|
+
export declare class WsTransport {
|
|
75
|
+
private readonly opts;
|
|
76
|
+
private socket;
|
|
77
|
+
private closedByUser;
|
|
78
|
+
private autoReconnect;
|
|
79
|
+
private acked;
|
|
80
|
+
private everAckedThisAttempt;
|
|
81
|
+
private reconnectAttempt;
|
|
82
|
+
private reconnectTimer;
|
|
83
|
+
private livenessTimer;
|
|
84
|
+
private lastActivity;
|
|
85
|
+
private lastUnexpectedStatus;
|
|
86
|
+
private ackWaiters;
|
|
87
|
+
constructor(opts: WsTransportOptions);
|
|
88
|
+
connect(opts?: {
|
|
89
|
+
auto?: boolean;
|
|
90
|
+
}): void;
|
|
91
|
+
/** Stop scheduling further reconnect attempts (any pending one is cancelled too); the current socket, if any, is left alone. Used when handing retry ownership to a slower external cadence (e.g. the long-poll fallback's periodic WS probe). */
|
|
92
|
+
stopAutoReconnect(): void;
|
|
93
|
+
/** Resume normal auto-reconnect-on-close behavior (does not itself trigger a connect — only affects future closes). */
|
|
94
|
+
resumeAutoReconnect(): void;
|
|
95
|
+
get isOpen(): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Attempt to send ONE envelope right now; returns whether it actually went
|
|
98
|
+
* out. `false` means the socket isn't currently open+acked — the caller
|
|
99
|
+
* (`ConnectionManager.drainOutbox`, Design B/finding N4) owns re-queueing
|
|
100
|
+
* and retrying later (e.g. on the next `onAcked`), since this transport no
|
|
101
|
+
* longer buffers anything itself.
|
|
102
|
+
*/
|
|
103
|
+
sendNow(envelope: Envelope): boolean;
|
|
104
|
+
waitForAck(timeoutMs?: number): Promise<void>;
|
|
105
|
+
close(): void;
|
|
106
|
+
private openSocket;
|
|
107
|
+
private scheduleReconnect;
|
|
108
|
+
private startLivenessCheck;
|
|
109
|
+
private stopLivenessCheck;
|
|
110
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { DaemonConfig, RuntimeAdapter } from '../index';
|
|
2
|
+
import { connectControlClient } from '../bin/control-client';
|
|
3
|
+
import type { ControlStatusResult } from '../daemon/control-protocol';
|
|
4
|
+
import { type OperationalHealthFileInspection, OPERATIONAL_HEALTH_FILENAME } from '../daemon/operational-health';
|
|
5
|
+
export declare const MAX_QUARANTINE_ENTRIES = 100;
|
|
6
|
+
export declare const MAX_QUARANTINE_SCAN_ENTRIES: number;
|
|
7
|
+
export declare const MAX_QUARANTINE_READ_BYTES: number;
|
|
8
|
+
export declare const MAX_DEVICE_RECORD_BYTES: number;
|
|
9
|
+
export declare const MAX_JOURNAL_COPY_BYTES: number;
|
|
10
|
+
export type DiagnosticStatus = 'pass' | 'warn' | 'fail';
|
|
11
|
+
export interface DiagnosticCheck {
|
|
12
|
+
id: 'config' | 'device' | 'runtimes' | 'control' | 'health' | 'journal' | 'workspace' | 'quarantine';
|
|
13
|
+
status: DiagnosticStatus;
|
|
14
|
+
summary: string;
|
|
15
|
+
}
|
|
16
|
+
export interface DiagnosticsSnapshot {
|
|
17
|
+
version: 1;
|
|
18
|
+
generatedAt: string;
|
|
19
|
+
product: {
|
|
20
|
+
nameHash: string;
|
|
21
|
+
idHash: string;
|
|
22
|
+
};
|
|
23
|
+
system: {
|
|
24
|
+
node: string;
|
|
25
|
+
platform: NodeJS.Platform;
|
|
26
|
+
arch: string;
|
|
27
|
+
sqliteAvailable: boolean;
|
|
28
|
+
};
|
|
29
|
+
config: {
|
|
30
|
+
serverProtocol: 'http' | 'https' | 'ws' | 'wss' | 'invalid' | 'unsupported';
|
|
31
|
+
customStoreDir: boolean;
|
|
32
|
+
hostedJournal: boolean;
|
|
33
|
+
runtimeAllowlistCount?: number;
|
|
34
|
+
};
|
|
35
|
+
device: {
|
|
36
|
+
status: 'paired' | 'unpaired' | 'unavailable';
|
|
37
|
+
deviceIdHash?: string;
|
|
38
|
+
};
|
|
39
|
+
runtimes: Array<{
|
|
40
|
+
idHash: string;
|
|
41
|
+
present: boolean;
|
|
42
|
+
versionPresent: boolean;
|
|
43
|
+
authPresent?: boolean;
|
|
44
|
+
steer: boolean;
|
|
45
|
+
resume: boolean;
|
|
46
|
+
permissionModeCount: number;
|
|
47
|
+
}>;
|
|
48
|
+
control: {
|
|
49
|
+
status: 'offline';
|
|
50
|
+
reason: string;
|
|
51
|
+
} | {
|
|
52
|
+
status: 'online';
|
|
53
|
+
pid: number;
|
|
54
|
+
uptimeMs: number;
|
|
55
|
+
transport: string;
|
|
56
|
+
activeTaskCount: number;
|
|
57
|
+
pendingApprovalCount: number;
|
|
58
|
+
operationalHealth: ControlStatusResult['operationalHealth'];
|
|
59
|
+
storage?: ControlStatusResult['storage'];
|
|
60
|
+
};
|
|
61
|
+
health: OperationalHealthFileInspection;
|
|
62
|
+
journal: {
|
|
63
|
+
status: 'missing' | 'present' | 'corrupt' | 'unavailable';
|
|
64
|
+
sizeBytes?: number;
|
|
65
|
+
walBytes?: number;
|
|
66
|
+
integrity?: 'ok' | 'not-checked';
|
|
67
|
+
reason?: string;
|
|
68
|
+
};
|
|
69
|
+
workspace: {
|
|
70
|
+
status: 'available' | 'missing' | 'unavailable';
|
|
71
|
+
writable?: boolean;
|
|
72
|
+
reason?: string;
|
|
73
|
+
};
|
|
74
|
+
quarantine: {
|
|
75
|
+
status: 'available' | 'missing' | 'unavailable';
|
|
76
|
+
count: number;
|
|
77
|
+
scannedCount: number;
|
|
78
|
+
truncated: boolean;
|
|
79
|
+
entries: Array<{
|
|
80
|
+
nameHash: string;
|
|
81
|
+
sizeBytes: number;
|
|
82
|
+
modifiedAt: string;
|
|
83
|
+
}>;
|
|
84
|
+
reason?: string;
|
|
85
|
+
};
|
|
86
|
+
checks: DiagnosticCheck[];
|
|
87
|
+
}
|
|
88
|
+
export interface CollectDiagnosticsOptions {
|
|
89
|
+
clock?: () => Date;
|
|
90
|
+
adapters?: RuntimeAdapter[];
|
|
91
|
+
connectControl?: typeof connectControlClient;
|
|
92
|
+
runtimeProbeTimeoutMs?: number;
|
|
93
|
+
}
|
|
94
|
+
export type OperationalHealthFixResult = {
|
|
95
|
+
status: 'not-needed';
|
|
96
|
+
reason: 'missing' | 'valid';
|
|
97
|
+
} | {
|
|
98
|
+
status: 'quarantined';
|
|
99
|
+
evidenceName: string;
|
|
100
|
+
manifestName: string;
|
|
101
|
+
sha256: string;
|
|
102
|
+
sizeBytes: number;
|
|
103
|
+
};
|
|
104
|
+
export declare function collectDiagnostics(config: DaemonConfig, storeDir: string, options?: CollectDiagnosticsOptions): Promise<DiagnosticsSnapshot>;
|
|
105
|
+
export declare function stableIdentifierHash(value: string): string;
|
|
106
|
+
/**
|
|
107
|
+
* The only S7-b repair: preserve a confirmed-corrupt health file in the
|
|
108
|
+
* never-auto-delete quarantine. Callers must separately enforce the CLI's
|
|
109
|
+
* `--fix --yes` and offline-daemon preconditions.
|
|
110
|
+
*/
|
|
111
|
+
export declare function quarantineCorruptOperationalHealth(storeDir: string, options?: {
|
|
112
|
+
clock?: () => Date;
|
|
113
|
+
}): Promise<OperationalHealthFixResult>;
|
|
114
|
+
export { OPERATIONAL_HEALTH_FILENAME };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { DaemonConfig, DaemonEvent } from '../index';
|
|
2
|
+
import { type EnsureSecureDirOptions } from '../util/secure-dir';
|
|
3
|
+
import { type CollectDiagnosticsOptions, type DiagnosticsSnapshot } from './diagnostics';
|
|
4
|
+
export declare const MAX_SUPPORT_AUDIT_TAIL_BYTES: number;
|
|
5
|
+
export declare const MAX_SUPPORT_AUDIT_FACTS = 200;
|
|
6
|
+
export interface SupportBundle {
|
|
7
|
+
version: 1;
|
|
8
|
+
generatedAt: string;
|
|
9
|
+
product: {
|
|
10
|
+
nameHash: string;
|
|
11
|
+
idHash: string;
|
|
12
|
+
};
|
|
13
|
+
system: DiagnosticsSnapshot['system'];
|
|
14
|
+
config: {
|
|
15
|
+
serverProtocol: 'http' | 'https' | 'ws' | 'wss' | 'invalid' | 'unsupported';
|
|
16
|
+
customStoreDir: boolean;
|
|
17
|
+
hostedJournal: boolean;
|
|
18
|
+
runtimeAllowlistCount?: number;
|
|
19
|
+
};
|
|
20
|
+
device: {
|
|
21
|
+
status: DiagnosticsSnapshot['device']['status'];
|
|
22
|
+
deviceIdHash?: string;
|
|
23
|
+
};
|
|
24
|
+
runtimes: DiagnosticsSnapshot['runtimes'];
|
|
25
|
+
control: {
|
|
26
|
+
status: 'offline';
|
|
27
|
+
} | {
|
|
28
|
+
status: 'online';
|
|
29
|
+
pid: number;
|
|
30
|
+
uptimeMs: number;
|
|
31
|
+
transport: 'connecting' | 'open' | 'closed' | 'degraded' | 'revoked' | 'unavailable';
|
|
32
|
+
activeTaskCount: number;
|
|
33
|
+
pendingApprovalCount: number;
|
|
34
|
+
operationalHealth: {
|
|
35
|
+
availability: 'unavailable';
|
|
36
|
+
} | {
|
|
37
|
+
availability: 'available';
|
|
38
|
+
state: 'healthy' | 'degraded' | 'recovering';
|
|
39
|
+
failureCount: number;
|
|
40
|
+
windowMs: number;
|
|
41
|
+
failureThreshold: number;
|
|
42
|
+
crashCount: number;
|
|
43
|
+
lastCrashAt?: string;
|
|
44
|
+
currentRunStartedAt?: string;
|
|
45
|
+
};
|
|
46
|
+
storagePresent: boolean;
|
|
47
|
+
};
|
|
48
|
+
health: DiagnosticsSnapshot['health'];
|
|
49
|
+
journal: DiagnosticsSnapshot['journal'];
|
|
50
|
+
workspace: DiagnosticsSnapshot['workspace'];
|
|
51
|
+
quarantine: {
|
|
52
|
+
status: DiagnosticsSnapshot['quarantine']['status'];
|
|
53
|
+
count: number;
|
|
54
|
+
scannedCount: number;
|
|
55
|
+
truncated: boolean;
|
|
56
|
+
entries: DiagnosticsSnapshot['quarantine']['entries'];
|
|
57
|
+
};
|
|
58
|
+
checks: Array<Pick<DiagnosticsSnapshot['checks'][number], 'id' | 'status'>>;
|
|
59
|
+
recentEvents: {
|
|
60
|
+
status: 'available' | 'missing' | 'unavailable';
|
|
61
|
+
included: number;
|
|
62
|
+
sourceBytesRead: number;
|
|
63
|
+
sourceTruncated: boolean;
|
|
64
|
+
facts: Array<{
|
|
65
|
+
kind: DaemonEvent['kind'];
|
|
66
|
+
ts: string;
|
|
67
|
+
}>;
|
|
68
|
+
};
|
|
69
|
+
redaction: {
|
|
70
|
+
policy: 'allowlist-v1';
|
|
71
|
+
omitted: string[];
|
|
72
|
+
transformed: string[];
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export declare function createSupportBundle(config: DaemonConfig, storeDir: string, options?: CollectDiagnosticsOptions): Promise<SupportBundle>;
|
|
76
|
+
/**
|
|
77
|
+
* Publish a complete bundle at a previously-unused path. The same-directory
|
|
78
|
+
* hard-link makes publication atomic and `EEXIST`-safe: no reader can see a
|
|
79
|
+
* partial JSON file and an existing operator artifact is never overwritten.
|
|
80
|
+
*/
|
|
81
|
+
export declare function writeSupportBundle(outputPath: string, bundle: SupportBundle, secureFileOptions?: EnsureSecureDirOptions): Promise<void>;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type { RuntimeAdapter, RuntimeCapabilities, RuntimeDetectResult, Session, TaskContext, GitWorkspaceConfig, } from './types';
|
|
2
|
+
export { PolicyUnsupportedError, SteerUnsupportedError } from './types';
|
|
3
|
+
export type { RuntimeEnvironmentRequirements } from './daemon/environment';
|
|
4
|
+
export { GitWorkspaceManager, GitWorkspaceError, isGitWorkspaceConfig, prependGitWorkspaceGuidance } from './daemon/git-workspace';
|
|
5
|
+
export type { GitWorkspaceObservation, GitWorkspaceLease, GitWorkspaceOptions, GitErrorCategory } from './daemon/git-workspace';
|
|
6
|
+
export { GitWorkspaceStore } from './daemon/git-workspace-store';
|
|
7
|
+
export type { GitWorkspaceLedger, GitWorkspaceLedgerRecord, GitWorkspacePhase } from './daemon/git-workspace-store';
|
|
8
|
+
export { createDaemon, createDaemonWithAdapters } from './daemon/create-daemon';
|
|
9
|
+
export type { Daemon, DaemonConfig, DaemonStatus, DaemonOverrides, DaemonBranding, HostedJournalConfig } from './daemon/create-daemon';
|
|
10
|
+
export type { OperationalHealthSnapshot, OperationalHealthState } from './daemon/operational-health';
|
|
11
|
+
export { journalHash, JournalUnavailableError, JournalCorruptError, JournalRecordTooLargeError, JournalUnknownTaskError, JournalClosedError, } from './daemon/journal/journal';
|
|
12
|
+
export type { LocalTaskJournal, JournalIdentity, JournalReceipt, ReceivedEnvelopeRecord, AdmissionRecord, LocalTransitionRecord, LocalTerminalRecord, TerminalTruthState, RecoverableTask, RecoveryOutcome, RecoveryDisposition, LocalStorageUsage, StorageCategory, CategoryUsage, CleanableCategory, CleanupCandidate, CleanupResult, CompactOptions, CompactResult, } from './daemon/journal/journal';
|
|
13
|
+
export { SqliteLocalTaskJournal, JOURNAL_DB_FILENAME, JOURNAL_QUARANTINE_DIRNAME } from './daemon/journal/sqlite-journal';
|
|
14
|
+
export type { SqliteLocalTaskJournalOptions } from './daemon/journal/sqlite-journal';
|
|
15
|
+
export { LocalStoragePressureEngine, LocalStoragePolicyError, LocalStorageEmergencyError, resolveLocalStoragePolicy, computePressureState, cleanupOrderFor, cleanupEligibleAt, createFilesystemCleanupExecutor, createStatfsFreeBytesProvider, JOURNAL_TASK_REF_PREFIX, DEFAULT_SOFT_BUDGET_RATIO, DEFAULT_HARD_BUDGET_RATIO, DEFAULT_ACK_CRITICAL_RESERVE_BYTES, DEFAULT_CLEANUP_BATCH_LIMIT, DEFAULT_INCREMENTAL_VACUUM_PAGES, DEFAULT_NORMAL_COMPACTION_INTERVAL_MS, DEFAULT_PRESSURE_COMPACTION_INTERVAL_MS, DEFAULT_RETENTION_MS, DEFAULT_LOG_ROTATION, } from './daemon/journal/storage-policy';
|
|
16
|
+
export type { LocalStoragePolicy, LocalStoragePolicyInput, LocalStoragePressureEngineOptions, LogRotationPolicy, CompactionPolicy, StoragePressureState, StoragePressureEvent, StorageMeasurement, StorageStatusSnapshot, StorageTickResult, CleanupExecutor, CleanupExecution, TimerLike, } from './daemon/journal/storage-policy';
|
|
17
|
+
export type { DeviceRecord } from './daemon/store';
|
|
18
|
+
export { AuthManager, DeviceRevokedError } from './daemon/auth-manager';
|
|
19
|
+
export { StoredDeviceProofSigner } from './daemon/device-proof-signer';
|
|
20
|
+
export type { DeviceProofRequest, DeviceProofSigner, StoredDeviceProofSignerOptions, } from './daemon/device-proof-signer';
|
|
21
|
+
export { TruthMemoryClient, TruthMemoryClientError } from './daemon/truth-memory-client';
|
|
22
|
+
export type { LocalMemoryFilter, MemorySelector, TruthManifestQueryInput, TruthManifestRecord, TruthMemoryClientErrorCode, TruthMemoryClientOptions, TruthMemoryMetric, TruthSnapshotCandidateInput, TruthSnapshotWriteInput, TruthTerminalWriteInput, TruthWriteBody, TruthWriteResult, VerifiedTruthRecord, } from './daemon/truth-memory-client';
|
|
23
|
+
export type { ConnectionState } from './daemon/ws-transport';
|
|
24
|
+
export { BlobClient } from './daemon/blob-client';
|
|
25
|
+
export type { BlobResolver } from './daemon/blob-client';
|
|
26
|
+
export { DaemonObserver } from './daemon/observer';
|
|
27
|
+
export type { DaemonEvent, DaemonEventKind, DaemonEventListener, DaemonTaskInfo, Unsubscribe } from './daemon/observer';
|
|
28
|
+
export { createServiceLifecycle, UnsupportedServicePlatformError } from './lifecycle/create-service-lifecycle';
|
|
29
|
+
export type { CreateServiceLifecycleOptions } from './lifecycle/create-service-lifecycle';
|
|
30
|
+
export { nodeAgentProgram, sanitizeServiceName } from './lifecycle/service-types';
|
|
31
|
+
export type { NodeAgentProgramOptions, ServiceDefinition, ServiceInstallOptions, ServiceLifecycle, ServiceProgram, ServiceStatusResult, } from './lifecycle/service-types';
|
|
32
|
+
export { generateLaunchdPlist } from './lifecycle/launchd';
|
|
33
|
+
export { generateSystemdUnit } from './lifecycle/systemd';
|
|
34
|
+
export { generateWinswXml } from './lifecycle/winsw';
|
|
35
|
+
export { ensureSecureDir, buildIcaclsArgs, SecureDirHardeningError } from './util/secure-dir';
|
|
36
|
+
export type { EnsureSecureDirOptions } from './util/secure-dir';
|
|
37
|
+
export { PiAdapter } from './adapters/pi/pi-adapter';
|
|
38
|
+
export type { PiAdapterOptions } from './adapters/pi/pi-adapter';
|
|
39
|
+
export { PI_PACKAGE_NAME } from './adapters/pi/resolve-bin';
|
|
40
|
+
export { ClaudeAdapter } from './adapters/claude/claude-adapter';
|
|
41
|
+
export type { ClaudeAdapterOptions } from './adapters/claude/claude-adapter';
|
|
42
|
+
export { CodexAdapter, type CodexAdapterOptions } from './adapters/codex/codex-adapter';
|