@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.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +11 -0
  3. package/dist/adapters/claude/claude-adapter.d.ts +155 -0
  4. package/dist/adapters/claude/events.d.ts +91 -0
  5. package/dist/adapters/claude/permission-mapping.d.ts +142 -0
  6. package/dist/adapters/claude/process-client.d.ts +103 -0
  7. package/dist/adapters/claude/resolve-approval-mcp-bin.d.ts +45 -0
  8. package/dist/adapters/claude/resolve-bin.d.ts +27 -0
  9. package/dist/adapters/codex/codex-adapter.d.ts +97 -0
  10. package/dist/adapters/codex/events.d.ts +41 -0
  11. package/dist/adapters/codex/permission-mapping.d.ts +107 -0
  12. package/dist/adapters/codex/process-runner.d.ts +86 -0
  13. package/dist/adapters/codex/resolve-bin.d.ts +25 -0
  14. package/dist/adapters/pi/events.d.ts +58 -0
  15. package/dist/adapters/pi/permission-mapping.d.ts +46 -0
  16. package/dist/adapters/pi/pi-adapter.d.ts +29 -0
  17. package/dist/adapters/pi/resolve-bin.d.ts +44 -0
  18. package/dist/adapters/pi/rpc-client.d.ts +101 -0
  19. package/dist/bin/approval-mcp-server.d.ts +69 -0
  20. package/dist/bin/audit-log.d.ts +212 -0
  21. package/dist/bin/byok-agent.d.ts +2 -0
  22. package/dist/bin/byok-agent.js +12347 -0
  23. package/dist/bin/byok-agent.js.map +1 -0
  24. package/dist/bin/byok-approval-mcp.d.ts +2 -0
  25. package/dist/bin/byok-approval-mcp.js +498 -0
  26. package/dist/bin/byok-approval-mcp.js.map +1 -0
  27. package/dist/bin/commands/approvals.d.ts +31 -0
  28. package/dist/bin/commands/approve-reject.d.ts +29 -0
  29. package/dist/bin/commands/doctor.d.ts +15 -0
  30. package/dist/bin/commands/pair.d.ts +7 -0
  31. package/dist/bin/commands/runtimes.d.ts +7 -0
  32. package/dist/bin/commands/service.d.ts +54 -0
  33. package/dist/bin/commands/start.d.ts +21 -0
  34. package/dist/bin/commands/status.d.ts +25 -0
  35. package/dist/bin/commands/support-bundle.d.ts +7 -0
  36. package/dist/bin/commands/tasks.d.ts +27 -0
  37. package/dist/bin/commands/unpair.d.ts +124 -0
  38. package/dist/bin/commands/workspaces.d.ts +16 -0
  39. package/dist/bin/config.d.ts +41 -0
  40. package/dist/bin/control-client.d.ts +50 -0
  41. package/dist/bin/format.d.ts +67 -0
  42. package/dist/bin/runtime-probe.d.ts +34 -0
  43. package/dist/bin/tasks-view.d.ts +49 -0
  44. package/dist/daemon/approvals.d.ts +87 -0
  45. package/dist/daemon/auth-manager.d.ts +52 -0
  46. package/dist/daemon/blob-client.d.ts +22 -0
  47. package/dist/daemon/connection-manager.d.ts +502 -0
  48. package/dist/daemon/control-protocol.d.ts +299 -0
  49. package/dist/daemon/control-server.d.ts +61 -0
  50. package/dist/daemon/create-daemon.d.ts +364 -0
  51. package/dist/daemon/cursor-store.d.ts +30 -0
  52. package/dist/daemon/daemon-owner.d.ts +24 -0
  53. package/dist/daemon/deterministic-jitter.d.ts +20 -0
  54. package/dist/daemon/device-keys.d.ts +45 -0
  55. package/dist/daemon/device-proof-signer.d.ts +41 -0
  56. package/dist/daemon/environment.d.ts +96 -0
  57. package/dist/daemon/git-workspace-store.d.ts +49 -0
  58. package/dist/daemon/git-workspace.d.ts +80 -0
  59. package/dist/daemon/http-client.d.ts +8 -0
  60. package/dist/daemon/journal/journal.d.ts +342 -0
  61. package/dist/daemon/journal/sqlite-journal.d.ts +173 -0
  62. package/dist/daemon/journal/sqlite-support.d.ts +96 -0
  63. package/dist/daemon/journal/storage-policy.d.ts +368 -0
  64. package/dist/daemon/long-poll-transport.d.ts +142 -0
  65. package/dist/daemon/observer.d.ts +345 -0
  66. package/dist/daemon/operational-health.d.ts +87 -0
  67. package/dist/daemon/policy.d.ts +16 -0
  68. package/dist/daemon/progress-batcher.d.ts +31 -0
  69. package/dist/daemon/runtime-capabilities.d.ts +36 -0
  70. package/dist/daemon/session-workspace-store.d.ts +75 -0
  71. package/dist/daemon/store.d.ts +54 -0
  72. package/dist/daemon/task-runner.d.ts +862 -0
  73. package/dist/daemon/truth-memory-client.d.ts +94 -0
  74. package/dist/daemon/url.d.ts +60 -0
  75. package/dist/daemon/ws-transport.d.ts +110 -0
  76. package/dist/diagnostics/diagnostics.d.ts +114 -0
  77. package/dist/diagnostics/support-bundle.d.ts +81 -0
  78. package/dist/index.d.ts +42 -0
  79. package/dist/index.js +10056 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/lifecycle/create-service-lifecycle.d.ts +59 -0
  82. package/dist/lifecycle/exec-runner.d.ts +141 -0
  83. package/dist/lifecycle/launchd.d.ts +55 -0
  84. package/dist/lifecycle/service-types.d.ts +177 -0
  85. package/dist/lifecycle/systemd.d.ts +46 -0
  86. package/dist/lifecycle/winsw.d.ts +64 -0
  87. package/dist/types.d.ts +178 -0
  88. package/dist/util/async-queue.d.ts +45 -0
  89. package/dist/util/atomic-write.d.ts +86 -0
  90. package/dist/util/secure-dir.d.ts +124 -0
  91. 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>;
@@ -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';