@byok-sdk/client 0.14.0 → 0.16.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 +15 -0
- package/dist/adapters/codex/codex-adapter.d.ts +2 -0
- package/dist/adapters/codex/process-runner.d.ts +16 -17
- package/dist/adapters/detect-outcome.d.ts +18 -0
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.js +189 -50
- package/dist/adapters/index.js.map +1 -1
- package/dist/bin/byok-agent-memory-mcp.js +29 -0
- package/dist/bin/byok-agent-memory-mcp.js.map +1 -1
- package/dist/bin/byok-agent-message-mcp.js +29 -0
- package/dist/bin/byok-agent-message-mcp.js.map +1 -1
- package/dist/bin/byok-agent-team-mcp.js +29 -0
- package/dist/bin/byok-agent-team-mcp.js.map +1 -1
- package/dist/bin/byok-agent.js +3026 -2122
- package/dist/bin/byok-agent.js.map +1 -1
- package/dist/bin/byok-approval-mcp.js +29 -0
- package/dist/bin/byok-approval-mcp.js.map +1 -1
- package/dist/bin/byok-mcp-env.d.ts +2 -0
- package/dist/bin/byok-mcp-env.js +36 -0
- package/dist/bin/byok-mcp-env.js.map +1 -0
- package/dist/bin/commands/doctor.d.ts +3 -0
- package/dist/bin/mcp-env-launcher.d.ts +5 -0
- package/dist/bin/runtime-probe.d.ts +6 -7
- package/dist/daemon/admission-wait.d.ts +2 -0
- package/dist/daemon/agent-egress-spool.d.ts +1 -0
- package/dist/daemon/agent-message-outbox.d.ts +17 -3
- package/dist/daemon/artifact-read.d.ts +7 -0
- package/dist/daemon/connection-manager.d.ts +18 -77
- package/dist/daemon/create-daemon.d.ts +11 -1
- package/dist/daemon/runtime-start.d.ts +3 -0
- package/dist/daemon/store.d.ts +2 -0
- package/dist/daemon/task-runner.d.ts +23 -0
- package/dist/daemon/terminal-commit-queue.d.ts +21 -0
- package/dist/daemon/terminal-identity.d.ts +6 -0
- package/dist/diagnostics/device-doctor.d.ts +46 -0
- package/dist/diagnostics/diagnostics.d.ts +5 -90
- package/dist/diagnostics/operator-actions.d.ts +63 -0
- package/dist/diagnostics/types.d.ts +92 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +2575 -470
- package/dist/index.js.map +1 -1
- package/dist/runtime-detection.d.ts +3 -0
- package/dist/runtime-failure.d.ts +6 -0
- package/dist/sdk-reserved-helper-host.d.ts +1 -1
- package/dist/types.d.ts +20 -10
- package/dist/util/durable-jsonl.d.ts +12 -0
- package/package.json +4 -4
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from 'child_process';
|
|
3
|
+
|
|
4
|
+
async function runMcpEnvLauncher() {
|
|
5
|
+
const key = process.env.BYOK_MCP_ENV_KEY;
|
|
6
|
+
if (!key || !/^BYOK_MCP_PAYLOAD_[A-F0-9]{32}$/.test(key)) throw new Error("invalid MCP environment binding");
|
|
7
|
+
const encoded = process.env[key];
|
|
8
|
+
if (!encoded) throw new Error("missing sealed MCP environment");
|
|
9
|
+
let config;
|
|
10
|
+
try {
|
|
11
|
+
config = JSON.parse(encoded);
|
|
12
|
+
if (!config || typeof config.command !== "string" || !config.command || config.args !== void 0 && (!Array.isArray(config.args) || config.args.some((value) => typeof value !== "string")) || config.env !== void 0 && (typeof config.env !== "object" || config.env === null || Array.isArray(config.env) || Object.values(config.env).some((value) => typeof value !== "string"))) throw new Error();
|
|
13
|
+
} catch {
|
|
14
|
+
throw new Error("invalid sealed MCP environment");
|
|
15
|
+
}
|
|
16
|
+
const env = { ...process.env };
|
|
17
|
+
delete env.BYOK_MCP_ENV_KEY;
|
|
18
|
+
for (const name of Object.keys(env)) if (name.startsWith("BYOK_MCP_PAYLOAD_")) delete env[name];
|
|
19
|
+
Object.assign(env, config.env);
|
|
20
|
+
await new Promise((resolve, reject) => {
|
|
21
|
+
const child = spawn(config.command, config.args ?? [], { env, stdio: "inherit", windowsHide: true });
|
|
22
|
+
child.once("error", () => reject(new Error("MCP child could not be spawned")));
|
|
23
|
+
child.once("close", (code) => {
|
|
24
|
+
if (code === 0) resolve();
|
|
25
|
+
else reject(new Error("MCP child exited unsuccessfully"));
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// src/bin/byok-mcp-env.ts
|
|
31
|
+
runMcpEnvLauncher().catch(() => {
|
|
32
|
+
process.stderr.write("byok-mcp-env: MCP launch failed\n");
|
|
33
|
+
process.exitCode = 1;
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=byok-mcp-env.js.map
|
|
36
|
+
//# sourceMappingURL=byok-mcp-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/bin/mcp-env-launcher.ts","../../src/bin/byok-mcp-env.ts"],"names":[],"mappings":";;;AAMA,eAAsB,iBAAA,GAAmC;AACvD,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,CAAI,gBAAA;AACxB,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,iCAAA,CAAkC,IAAA,CAAK,GAAG,CAAA,EAAG,MAAM,IAAI,KAAA,CAAM,iCAAiC,CAAA;AAC3G,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AAC/B,EAAA,IAAI,CAAC,OAAA,EAAS,MAAM,IAAI,MAAM,gCAAgC,CAAA;AAC9D,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,IAAA,CAAK,MAAM,OAAO,CAAA;AAC3B,IAAA,IAAI,CAAC,MAAA,IAAU,OAAO,MAAA,CAAO,OAAA,KAAY,YAAY,CAAC,MAAA,CAAO,OAAA,IACvD,MAAA,CAAO,IAAA,KAAS,KAAA,CAAA,KAAc,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO,IAAI,CAAA,IAAK,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,CAAA,KAAA,KAAS,OAAO,KAAA,KAAU,QAAQ,CAAA,CAAA,IAChH,MAAA,CAAO,QAAQ,KAAA,CAAA,KAAc,OAAO,MAAA,CAAO,GAAA,KAAQ,QAAA,IAAY,MAAA,CAAO,QAAQ,IAAA,IAAQ,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO,GAAG,CAAA,IAC7G,OAAO,MAAA,CAAO,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CAAA,KAAA,KAAS,OAAO,KAAA,KAAU,QAAQ,CAAA,CAAA,EAAK,MAAM,IAAI,KAAA,EAAM;AAAA,EAC/F,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,MAAM,gCAAgC,CAAA;AAAA,EAClD;AACA,EAAA,MAAM,GAAA,GAAM,EAAE,GAAG,OAAA,CAAQ,GAAA,EAAI;AAC7B,EAAA,OAAO,GAAA,CAAI,gBAAA;AACX,EAAA,KAAA,MAAW,IAAA,IAAQ,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,EAAG,IAAI,IAAA,CAAK,UAAA,CAAW,mBAAmB,CAAA,EAAG,OAAO,GAAA,CAAI,IAAI,CAAA;AAC9F,EAAA,MAAA,CAAO,MAAA,CAAO,GAAA,EAAK,MAAA,CAAO,GAAG,CAAA;AAC7B,EAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAA,KAAW;AAC3C,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,MAAA,CAAO,OAAA,EAAS,OAAO,IAAA,IAAQ,EAAC,EAAG,EAAE,GAAA,EAAK,KAAA,EAAO,SAAA,EAAW,WAAA,EAAa,MAAM,CAAA;AACnG,IAAA,KAAA,CAAM,IAAA,CAAK,SAAS,MAAM,MAAA,CAAO,IAAI,KAAA,CAAM,gCAAgC,CAAC,CAAC,CAAA;AAC7E,IAAA,KAAA,CAAM,IAAA,CAAK,SAAS,CAAA,IAAA,KAAQ;AAC1B,MAAA,IAAI,IAAA,KAAS,GAAG,OAAA,EAAQ;AAAA,WACnB,MAAA,CAAO,IAAI,KAAA,CAAM,iCAAiC,CAAC,CAAA;AAAA,IAC1D,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AACH;;;AC9BA,iBAAA,EAAkB,CAAE,MAAM,MAAM;AAC9B,EAAA,OAAA,CAAQ,MAAA,CAAO,MAAM,mCAAmC,CAAA;AACxD,EAAA,OAAA,CAAQ,QAAA,GAAW,CAAA;AACrB,CAAC,CAAA","file":"byok-mcp-env.js","sourcesContent":["import { spawn } from 'node:child_process';\n\n/** Project one sealed server's env through Codex's documented env_vars channel.\n * No secret or original server argument is carried in the launcher argv.\n * The child remains in Codex's owned process group / Windows Job Object.\n */\nexport async function runMcpEnvLauncher(): Promise<void> {\n const key = process.env.BYOK_MCP_ENV_KEY;\n if (!key || !/^BYOK_MCP_PAYLOAD_[A-F0-9]{32}$/.test(key)) throw new Error('invalid MCP environment binding');\n const encoded = process.env[key];\n if (!encoded) throw new Error('missing sealed MCP environment');\n let config: { command: string; args?: string[]; env?: Record<string, string> };\n try {\n config = JSON.parse(encoded);\n if (!config || typeof config.command !== 'string' || !config.command\n || (config.args !== undefined && (!Array.isArray(config.args) || config.args.some(value => typeof value !== 'string')))\n || (config.env !== undefined && (typeof config.env !== 'object' || config.env === null || Array.isArray(config.env)\n || Object.values(config.env).some(value => typeof value !== 'string')))) throw new Error();\n } catch {\n throw new Error('invalid sealed MCP environment');\n }\n const env = { ...process.env };\n delete env.BYOK_MCP_ENV_KEY;\n for (const name of Object.keys(env)) if (name.startsWith('BYOK_MCP_PAYLOAD_')) delete env[name];\n Object.assign(env, config.env);\n await new Promise<void>((resolve, reject) => {\n const child = spawn(config.command, config.args ?? [], { env, stdio: 'inherit', windowsHide: true });\n child.once('error', () => reject(new Error('MCP child could not be spawned')));\n child.once('close', code => {\n if (code === 0) resolve();\n else reject(new Error('MCP child exited unsuccessfully'));\n });\n });\n}\n","#!/usr/bin/env node\nimport { runMcpEnvLauncher } from './mcp-env-launcher';\n\nrunMcpEnvLauncher().catch(() => {\n process.stderr.write('byok-mcp-env: MCP launch failed\\n');\n process.exitCode = 1;\n});\n"]}
|
|
@@ -3,6 +3,9 @@ import { type CollectDiagnosticsOptions } from '../../diagnostics/diagnostics';
|
|
|
3
3
|
export interface DoctorOptions extends CollectDiagnosticsOptions {
|
|
4
4
|
json?: boolean;
|
|
5
5
|
fix?: boolean;
|
|
6
|
+
repair?: string;
|
|
7
|
+
expectedDeviceId?: string;
|
|
8
|
+
expectedTenantId?: string;
|
|
6
9
|
confirmed?: boolean;
|
|
7
10
|
log?: (line: string) => void;
|
|
8
11
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Project one sealed server's env through Codex's documented env_vars channel.
|
|
2
|
+
* No secret or original server argument is carried in the launcher argv.
|
|
3
|
+
* The child remains in Codex's owned process group / Windows Job Object.
|
|
4
|
+
*/
|
|
5
|
+
export declare function runMcpEnvLauncher(): Promise<void>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RuntimeDetectResult } from '../types';
|
|
1
2
|
import { type RuntimeAdapter } from '../index';
|
|
2
3
|
export declare const RUNTIME_PROBE_TIMEOUT_MS = 5000;
|
|
3
4
|
/** The bundled adapter set `byok-agent status`/`byok-agent runtimes` probe by default — same unset-vs-set allowlist contract as `createDaemon` itself. */
|
|
@@ -13,7 +14,9 @@ export declare function defaultRuntimeAdapters(runtimeAllowlist: string[] | unde
|
|
|
13
14
|
*/
|
|
14
15
|
export interface ProbedRuntime {
|
|
15
16
|
id: string;
|
|
17
|
+
/** Deterministic projection of outcome, never adapter-authored. */
|
|
16
18
|
present: boolean;
|
|
19
|
+
outcome: RuntimeDetectResult['kind'];
|
|
17
20
|
version?: string;
|
|
18
21
|
authPresent?: boolean;
|
|
19
22
|
steer: boolean;
|
|
@@ -21,13 +24,9 @@ export interface ProbedRuntime {
|
|
|
21
24
|
permissionModes: string[];
|
|
22
25
|
}
|
|
23
26
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* resolves `{present: false}` rather than rejecting) — the catch here is a
|
|
28
|
-
* defensive backstop for a `RuntimeAdapter` that doesn't hold that
|
|
29
|
-
* convention, not a workaround for an observed failure in the bundled
|
|
30
|
-
* three.
|
|
27
|
+
* Fresh, parallel local observations. A custom adapter timeout is an observation
|
|
28
|
+
* deadline only: detect() has no cancellation contract. Never expose arbitrary
|
|
29
|
+
* adapter errors or interpret an old/malformed result as available.
|
|
31
30
|
*/
|
|
32
31
|
export declare function probeRuntimes(adapters: readonly RuntimeAdapter[], options?: {
|
|
33
32
|
timeoutMs?: number;
|
|
@@ -20,12 +20,14 @@ export interface AgentMessageOutboxRecord {
|
|
|
20
20
|
export declare class AgentMessageOutboxError extends Error {
|
|
21
21
|
constructor(message: string);
|
|
22
22
|
}
|
|
23
|
-
/** Agent-local
|
|
23
|
+
/** Agent-local append-before-send authority. Only acceptance or explicit terminal archival retires bytes. */
|
|
24
24
|
export declare class AgentMessageOutbox {
|
|
25
25
|
readonly homeDir: string;
|
|
26
26
|
readonly outboxPath: string;
|
|
27
27
|
private readonly pendingByTask;
|
|
28
|
+
private readonly revokedTasks;
|
|
28
29
|
private readonly dispositionByTask;
|
|
30
|
+
private readonly file;
|
|
29
31
|
private nextCursor;
|
|
30
32
|
private logEntries;
|
|
31
33
|
private writeTail;
|
|
@@ -34,7 +36,7 @@ export declare class AgentMessageOutbox {
|
|
|
34
36
|
/** Re-open every existing Agent-local message outbox without following Agent-home symlinks. */
|
|
35
37
|
static recover(agentsRoot: string, tenantId: string): Promise<readonly AgentMessageOutbox[]>;
|
|
36
38
|
records(): readonly AgentMessageOutboxRecord[];
|
|
37
|
-
/**
|
|
39
|
+
/** Records without disposition or local revoke; transport replay additionally requires session binding. */
|
|
38
40
|
retryableRecords(): readonly AgentMessageOutboxRecord[];
|
|
39
41
|
get(taskId: string): AgentMessageOutboxRecord | undefined;
|
|
40
42
|
appendDraft(input: {
|
|
@@ -48,11 +50,23 @@ export declare class AgentMessageOutbox {
|
|
|
48
50
|
readonly maxPendingEvents: number;
|
|
49
51
|
readonly maxPendingBytes: number;
|
|
50
52
|
}): Promise<AgentMessageOutboxRecord>;
|
|
51
|
-
activate(taskId: string, sessionRef: string): Promise<AgentMessageOutboxRecord | undefined>;
|
|
53
|
+
activate(taskId: string, sessionRef: string, isCurrent?: () => boolean): Promise<AgentMessageOutboxRecord | undefined>;
|
|
54
|
+
/** Local lifecycle cancellation, never a synthesized consumer disposition. */
|
|
55
|
+
revoke(taskId: string): Promise<void>;
|
|
56
|
+
/** The same terminal classification used by operator receipts and archival. */
|
|
57
|
+
terminalRecords(): readonly AgentMessageOutboxRecord[];
|
|
58
|
+
private isTerminalEvidence;
|
|
52
59
|
publishPayload(record: AgentMessageOutboxRecord): AgentMessagePublishPayload;
|
|
53
60
|
applyDisposition(taskId: string, input: unknown): Promise<'accepted' | 'held' | 'refused' | 'mismatch' | 'unknown'>;
|
|
54
61
|
private load;
|
|
55
62
|
private appendEntry;
|
|
63
|
+
/**
|
|
64
|
+
* Explicit operator maintenance under the Agent-home single-writer lease.
|
|
65
|
+
* Copy complete terminal evidence durably before removing it from the live log.
|
|
66
|
+
* Archives are audit artifacts, never another replay input. held remains live.
|
|
67
|
+
*/
|
|
68
|
+
archiveTerminalRecords(archiveDirectory: string): Promise<string | undefined>;
|
|
69
|
+
private snapshotEntries;
|
|
56
70
|
private compact;
|
|
57
71
|
private exclusive;
|
|
58
72
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FileHandle } from 'node:fs/promises';
|
|
2
|
+
export declare const DEFAULT_ARTIFACT_LIMITS: Readonly<{
|
|
3
|
+
maxFileBytes: number;
|
|
4
|
+
maxTaskBytes: number;
|
|
5
|
+
}>;
|
|
6
|
+
/** The caller retains fd ownership; no pathname is reopened. */
|
|
7
|
+
export declare function readArtifactBytes(handle: FileHandle, maxBytes: number, signal: AbortSignal, account: (bytes: number) => void): Promise<Buffer>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { HarnessInfo } from '@byok-sdk/protocol';
|
|
1
2
|
import { type CapabilityFlag, type Envelope, type RuntimeInfo, type ToolsetId } from '@byok-sdk/protocol';
|
|
2
3
|
import { AuthManager } from './auth-manager';
|
|
3
4
|
import type { CursorStore } from './cursor-store';
|
|
@@ -14,6 +15,7 @@ export interface ConnectionManagerOptions {
|
|
|
14
15
|
/** U4a Local Agent release version, sent unchanged in `conn.hello`. */
|
|
15
16
|
clientVersion?: string;
|
|
16
17
|
runtimes: RuntimeInfo[];
|
|
18
|
+
harnesses?: HarnessInfo[];
|
|
17
19
|
/** Reads current sorted logical IDs from the validated local registry for every `conn.hello`. */
|
|
18
20
|
getConfiguredToolsets?: () => readonly ToolsetId[];
|
|
19
21
|
auth: AuthManager;
|
|
@@ -73,25 +75,11 @@ export declare class ConnectionManager {
|
|
|
73
75
|
* guarantees in docs/protocol.md §9.
|
|
74
76
|
*/
|
|
75
77
|
private stalledAtSeq;
|
|
76
|
-
/**
|
|
77
|
-
* Design A (Wave 2, F3-on-long-poll): the second, in-memory watermark
|
|
78
|
-
* alongside the durable `cursor`. `cursor` only ever advances AFTER a
|
|
79
|
-
* `task.*` handler's side effects resolve successfully, and is persisted
|
|
80
|
-
* (see `advanceCursor`) — that semantics is unchanged. `deliveredSeq`
|
|
81
|
-
* advances eagerly, the instant a `task.*` envelope is admitted past
|
|
82
|
-
* dedup (see `deliver`/`noteDelivered`), independent of whether its
|
|
83
|
-
* handler has even started, let alone succeeded. It exists so a repeated
|
|
84
|
-
* read at the durable cursor does not re-dispatch an envelope already in
|
|
85
|
-
* flight — `handleOffer` must not start a second adapter session while a
|
|
86
|
-
* first attempt is still running. On WS this same field is written the
|
|
87
|
-
* same way, but since a live WS connection only ever pushes a given `seq`
|
|
88
|
-
* once, it never has an observable effect there beyond mirroring
|
|
89
|
-
* `cursor` (see `dedupWatermark`'s doc comment for why redelivery
|
|
90
|
-
* correctness doesn't depend on resetting it anywhere).
|
|
91
|
-
*/
|
|
92
|
-
private deliveredSeq;
|
|
93
|
-
/** Finding F3: serializes `onEnvelope` calls into a per-connection FIFO — one envelope's handler always fully settles before the next one starts. */
|
|
78
|
+
/** Drain barrier for independently running handlers; not an admission lock. */
|
|
94
79
|
private processingChain;
|
|
80
|
+
private cursorInitialization;
|
|
81
|
+
private completionTail;
|
|
82
|
+
private readonly controlTails;
|
|
95
83
|
/**
|
|
96
84
|
* Design B (finding N4): the ONE outbound queue holds `Envelope` OBJECTS,
|
|
97
85
|
* never re-encoded/rebuilt strings, so a
|
|
@@ -117,38 +105,13 @@ export declare class ConnectionManager {
|
|
|
117
105
|
private terminalError;
|
|
118
106
|
private settledWaiters;
|
|
119
107
|
private pendingCursorSave;
|
|
120
|
-
/**
|
|
121
|
-
* Finding P2 (Fix 2b): seqs currently admitted into `processingChain` but
|
|
122
|
-
* not yet settled — added in `deliver()` the moment a `task.*` envelope is
|
|
123
|
-
* accepted past the ordinary watermark check, removed in `process()`'s
|
|
124
|
-
* `finally` once that specific attempt resolves (success OR failure).
|
|
125
|
-
* While stalled, `dedupWatermark()` deliberately stays frozen below
|
|
126
|
-
* already-delivered seqs (see its own doc comment) so the failed seq's own
|
|
127
|
-
* redelivery can get through — but that same frozen watermark also means
|
|
128
|
-
* every OTHER seq above it rides along on every re-poll too. Without this,
|
|
129
|
-
* a seq already mid-flight (e.g. a `task.offer` whose prepared operation start()
|
|
130
|
-
* hasn't resolved yet) would be re-enqueued into `processingChain` on
|
|
131
|
-
* every such re-poll, piling up duplicate copies that — once the first
|
|
132
|
-
* finally resolves and the chain unwinds through them — run its handler
|
|
133
|
-
* again; for `task.offer` specifically, a second adapter session
|
|
134
|
-
* orphaning the first (`TaskRunner`'s own `this.tasks.has` guard, finding
|
|
135
|
-
* P2c, is the second, independent layer against exactly that).
|
|
136
|
-
*/
|
|
108
|
+
/** Admission dedup while an individual handler is running. */
|
|
137
109
|
private readonly inFlightSeqs;
|
|
138
|
-
/**
|
|
139
|
-
* Finding P2 (Fix 2b): seqs whose handler has already resolved
|
|
140
|
-
* successfully at least once this session, tracked only while a stall is
|
|
141
|
-
* in effect — cleared the moment `stalledAtSeq` itself clears (see
|
|
142
|
-
* `process()`), since once unstalled the ordinary watermark check via
|
|
143
|
-
* `deliveredSeq` already covers everything delivered so far, making this
|
|
144
|
-
* redundant. Needed because the stall-gap-prevention rule in `process()`
|
|
145
|
-
* deliberately does NOT advance `cursor` past a seq above the
|
|
146
|
-
* still-unresolved `stalledAtSeq`, even once that seq's own handler
|
|
147
|
-
* succeeds — so `dedupWatermark()` alone can't distinguish "already
|
|
148
|
-
* succeeded, don't re-run" from "never yet attempted" for anything in
|
|
149
|
-
* that gap.
|
|
150
|
-
*/
|
|
110
|
+
/** Successful side effects retained until their durable acknowledgement. */
|
|
151
111
|
private readonly processedSeqs;
|
|
112
|
+
private readonly failedEnvelopes;
|
|
113
|
+
/** Received work lacking a successful handler receipt, including malformed frames. */
|
|
114
|
+
private readonly unresolvedSeqs;
|
|
152
115
|
/**
|
|
153
116
|
* Finding P3: the pending `drainOutbox` long-poll retry backoff, if any —
|
|
154
117
|
* cancellable so `enterRevoked()` can unblock it immediately instead of
|
|
@@ -303,43 +266,21 @@ export declare class ConnectionManager {
|
|
|
303
266
|
* - F3 (at-most-once): the old code persisted the cursor advance BEFORE
|
|
304
267
|
* `onEnvelope` even ran (fire-and-forget) — a handler that then failed
|
|
305
268
|
* left a redelivery-proof envelope permanently marked processed. Inbound
|
|
306
|
-
*
|
|
307
|
-
*
|
|
269
|
+
* handlers may run independently; their receipt commits are serialized.
|
|
270
|
+
* The cursor only advances
|
|
308
271
|
* AFTER the handler resolves successfully; a rejection leaves the
|
|
309
272
|
* cursor where it was (see `stalledAtSeq`), so a future reconnect's
|
|
310
273
|
* redelivery re-attempts it — safe because every server->daemon type is
|
|
311
274
|
* documented idempotent (protocol §9).
|
|
312
275
|
*/
|
|
313
276
|
private deliver;
|
|
314
|
-
/**
|
|
315
|
-
*
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
* `cursor` (see the constructor). Normally this local watermark is
|
|
319
|
-
* `deliveredSeq` — which is always >= `cursor` (every envelope that
|
|
320
|
-
* reaches `advanceCursor` already passed through `noteDelivered` first,
|
|
321
|
-
* see `deliver`) — so this is the literal `max(cursor, deliveredSeq)` the
|
|
322
|
-
* design calls for, just expressed via that invariant rather than an
|
|
323
|
-
* explicit `Math.max`.
|
|
324
|
-
*
|
|
325
|
-
* While `stalledAtSeq` is set, this collapses to the durable `cursor`
|
|
326
|
-
* alone, deliberately ignoring however far `deliveredSeq` had already run
|
|
327
|
-
* ahead before the failure was known: that's what lets the stalled
|
|
328
|
-
* envelope's own redelivery (and everything after it, right up to a
|
|
329
|
-
* fresh success) get past this same dedup check instead of being
|
|
330
|
-
* self-deduped by the client's own earlier eager tracking of envelopes
|
|
331
|
-
* whose outcome wasn't known yet. No separate "reset deliveredSeq on
|
|
332
|
-
* reconnect" step is needed for this to be correct — collapsing to
|
|
333
|
-
* `cursor` exactly while stalled already produces the right answer on
|
|
334
|
-
* every long-poll retry path. NOT resetting it unconditionally on every
|
|
335
|
-
* retry lets `deliveredSeq` keep doing its job of not re-dispatching
|
|
336
|
-
* something already in flight while a handler is still running.
|
|
337
|
-
*/
|
|
277
|
+
/** A committed terminal can settle a failed offer receipt even if cloud
|
|
278
|
+
* cancellation has since filtered that offer from mailbox replay. */
|
|
279
|
+
retryTaskReceipts(taskId: string): void;
|
|
280
|
+
/** Only a durable acknowledgement can deduplicate a whole prefix. */
|
|
338
281
|
private dedupWatermark;
|
|
339
|
-
/** Design A: eagerly advance the in-memory delivery watermark — called for every `task.*` envelope `deliver()` admits past dedup, regardless of transport or of whether its handler has even started yet. */
|
|
340
|
-
private noteDelivered;
|
|
341
282
|
private process;
|
|
342
|
-
/**
|
|
283
|
+
/** Recorded synchronously at receive, before a later successful receipt can commit. */
|
|
343
284
|
private noteValidationFailure;
|
|
344
285
|
private advanceCursor;
|
|
345
286
|
private quarantineRejectedOutbound;
|
|
@@ -307,6 +307,13 @@ export interface DaemonConfig {
|
|
|
307
307
|
* explicitly instead to opt out of enforcement altogether.
|
|
308
308
|
*/
|
|
309
309
|
maxTaskOutputBytes?: number;
|
|
310
|
+
/** Legacy artifact bytes only: default 16 MiB/file and 64 MiB/task, independent of event output limits. */
|
|
311
|
+
artifactLimits?: {
|
|
312
|
+
maxFileBytes: number;
|
|
313
|
+
maxTaskBytes: number;
|
|
314
|
+
};
|
|
315
|
+
/** Admission and startup deadline, including pure detect/prepare waits; unresolved process owners remain quarantined. Default 30 seconds. */
|
|
316
|
+
startupTimeoutMs?: number;
|
|
310
317
|
/**
|
|
311
318
|
* Per-EVENT inline ceiling (default {@link DEFAULT_MAX_INLINE_EVENT_BYTES},
|
|
312
319
|
* 64 KiB) for the two `AgentEvent` fields a runtime authors freely:
|
|
@@ -528,6 +535,8 @@ export interface DaemonStatus {
|
|
|
528
535
|
revoked: boolean;
|
|
529
536
|
deviceId?: string;
|
|
530
537
|
activeTaskCount: number;
|
|
538
|
+
/** Exact terminal results retained for journal retry; nonzero requires recovery. */
|
|
539
|
+
pendingTerminalCommits: number;
|
|
531
540
|
/** Passthrough of `DaemonConfig.branding` — `undefined` when the product configured none. See `DaemonBranding`. */
|
|
532
541
|
branding?: DaemonBranding;
|
|
533
542
|
/** Local lifecycle/retry budget, separate from transport fallback state. */
|
|
@@ -587,7 +596,8 @@ export interface Daemon {
|
|
|
587
596
|
/** M3-2a: same as {@link approve} but rejects — see that method's doc comment. */
|
|
588
597
|
reject(taskId: string, reason?: string): Promise<void>;
|
|
589
598
|
}
|
|
590
|
-
/**
|
|
599
|
+
/** Custom adapter composition. Available custom descriptors are published through
|
|
600
|
+
* the capability-gated harness inventory; built-in RuntimeId remains closed. */
|
|
591
601
|
export interface DaemonOverrides {
|
|
592
602
|
/** Test-only synchronous kill points; never supplied by production configuration. */
|
|
593
603
|
executionRecoveryFault?: (step: 'terminal:before-send' | 'terminal:queued' | 'outbound:before-post' | 'outbound:after-ack') => void;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { RuntimeOperationStartInput, Session } from '../types';
|
|
2
|
+
/** A deadline withdraws admission; it never invents a quiescence receipt. */
|
|
3
|
+
export declare function startOwnedRuntime(start: (input: RuntimeOperationStartInput) => Promise<Session>, input: RuntimeOperationStartInput, signal: AbortSignal, timeoutMs: number): Promise<Session>;
|
package/dist/daemon/store.d.ts
CHANGED
|
@@ -72,6 +72,8 @@ export declare class DeviceStore {
|
|
|
72
72
|
* identifiable until the synchronous pathname check and unlink complete.
|
|
73
73
|
*/
|
|
74
74
|
remove(): Promise<DeviceMetadata | undefined>;
|
|
75
|
+
/** Rebuild only the non-secret projection, while the caller owns the store lease. */
|
|
76
|
+
reconcileMetadata(authority: DeviceMetadata): Promise<boolean>;
|
|
75
77
|
save(record: DeviceMetadata): Promise<void>;
|
|
76
78
|
private openBounded;
|
|
77
79
|
}
|
|
@@ -228,6 +228,7 @@ export interface TaskRunnerDeps {
|
|
|
228
228
|
agentSessionHandoffs?: AgentSessionHandoffStore;
|
|
229
229
|
deviceId: string;
|
|
230
230
|
send: (envelope: Envelope) => void;
|
|
231
|
+
awaitTerminalCommit?: (taskId: string) => Promise<void>;
|
|
231
232
|
/** Fsync the execution commitment before claim/runtime side effects. */
|
|
232
233
|
beforeClaim?: (taskId: string, runtime: string) => Promise<void>;
|
|
233
234
|
blobClient: BlobResolver;
|
|
@@ -323,6 +324,7 @@ export interface TaskRunnerDeps {
|
|
|
323
324
|
onApprovalDispatched?: (taskId: string, approvalId: string) => void;
|
|
324
325
|
/** Overrides the bounded soft-interrupt window before authoritative `Session.close()` disposal begins. */
|
|
325
326
|
shutdownInterruptTimeoutMs?: number;
|
|
327
|
+
startupTimeoutMs?: number;
|
|
326
328
|
/**
|
|
327
329
|
* M5 batch-3 (workstream 2): overrides {@link DEFAULT_MAX_TASK_OUTPUT_BYTES}
|
|
328
330
|
* — see that constant's own doc comment and `DaemonConfig.maxTaskOutputBytes`
|
|
@@ -332,6 +334,10 @@ export interface TaskRunnerDeps {
|
|
|
332
334
|
* interface (`shutdownInterruptTimeoutMs`, `approvalTimeoutMs`).
|
|
333
335
|
*/
|
|
334
336
|
maxTaskOutputBytes?: number;
|
|
337
|
+
artifactLimits?: {
|
|
338
|
+
maxFileBytes: number;
|
|
339
|
+
maxTaskBytes: number;
|
|
340
|
+
};
|
|
335
341
|
/**
|
|
336
342
|
* Per-event inline ceiling for `tool_use.input` / `tool_result.output` —
|
|
337
343
|
* see `DaemonConfig.maxInlineEventBytes` (`create-daemon.ts`) for the full
|
|
@@ -627,8 +633,13 @@ export declare class TaskRunner {
|
|
|
627
633
|
/** Restore activated, unaccepted message drafts before transport admission on daemon restart. */
|
|
628
634
|
recoverAgentMessageOutboxes(agentsRoot: string): Promise<void>;
|
|
629
635
|
private agentMessageOutbox;
|
|
636
|
+
/** A recovery terminal must not close first-message admission before this durable draft has a disposition. */
|
|
637
|
+
hasPendingRecoveredAgentMessage(taskId: string): boolean;
|
|
630
638
|
/** Retry stable recovered records after a transport handshake/re-handshake. */
|
|
631
639
|
retryRecoveredAgentMessages(): void;
|
|
640
|
+
private canPublishAgentMessage;
|
|
641
|
+
/** All authors and startup use the same queue-time and post-I/O authority check. */
|
|
642
|
+
private activateAgentMessage;
|
|
632
643
|
private sendAgentMessageRecord;
|
|
633
644
|
private handleAgentMessageDisposition;
|
|
634
645
|
/** M4 Phase 2: stop claiming any FUTURE `task.offer` — see `stoppingOffers`'s own doc comment. Idempotent. */
|
|
@@ -670,6 +681,14 @@ export declare class TaskRunner {
|
|
|
670
681
|
* ahead of this method — see `daemon-control-socket.test.ts`'s dedicated
|
|
671
682
|
* regression test for the exact scenario.
|
|
672
683
|
*/
|
|
684
|
+
/** Startup resources have an owner even before a Session can become active. */
|
|
685
|
+
private startupRetryTimer;
|
|
686
|
+
private readonly claimedHarnesses;
|
|
687
|
+
private readonly homeReservations;
|
|
688
|
+
private readonly startupOwners;
|
|
689
|
+
private readonly startupDisposals;
|
|
690
|
+
private disposeStartupOwner;
|
|
691
|
+
private disposeStartupOwnerOnce;
|
|
673
692
|
shutdownActiveTasks(reason: string): Promise<void>;
|
|
674
693
|
/**
|
|
675
694
|
* M5 batch-3 (workstream 2): the ONE shared per-task teardown sequence —
|
|
@@ -701,6 +720,7 @@ export declare class TaskRunner {
|
|
|
701
720
|
* a genuine protocol bug, not a benign race — mirrors `pump()`'s own
|
|
702
721
|
* identity-check guard for the same class of race.
|
|
703
722
|
*/
|
|
723
|
+
private interruptBounded;
|
|
704
724
|
private teardownActiveTask;
|
|
705
725
|
/** Graceful-shutdown caller of {@link teardownActiveTask} — see `shutdownActiveTasks`'s own doc comment. `retryable: true`: nothing about the task/policy itself was ever at fault, only this device's own availability right now. */
|
|
706
726
|
private shutdownTask;
|
|
@@ -1151,7 +1171,10 @@ export declare class TaskRunner {
|
|
|
1151
1171
|
private persistAgentTerminalEvidence;
|
|
1152
1172
|
private retryAgentTerminalEvidence;
|
|
1153
1173
|
private reportAgentTerminalEvidenceFailure;
|
|
1174
|
+
retryTerminalFinalization(taskId: string): Promise<void>;
|
|
1175
|
+
private readonly finalizationAttempts;
|
|
1154
1176
|
private finish;
|
|
1177
|
+
private finishOnce;
|
|
1155
1178
|
private reserveSemanticTerminal;
|
|
1156
1179
|
/** M3-B: bounded insert for `finishedTaskIds` — see its class-level doc comment and `MAX_TRACKED_TASK_IDS`. Evicts the oldest (first-inserted) entry once over cap, same idiom as `ConnectionHub.checkAndRecordDuplicate` (packages/server/src/hub.ts). */
|
|
1157
1180
|
private addFinishedTaskId;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Volatile ownership of exact terminal bytes until the journal accepts them.
|
|
2
|
+
* The journal remains the sole durable authority. Failed receipts stay rejected;
|
|
3
|
+
* only the internal scheduling tail recovers so another task can make progress.
|
|
4
|
+
*/
|
|
5
|
+
export declare class TerminalCommitQueue {
|
|
6
|
+
private readonly committed;
|
|
7
|
+
private readonly pending;
|
|
8
|
+
private tail;
|
|
9
|
+
private timer;
|
|
10
|
+
private stopped;
|
|
11
|
+
constructor(committed: (taskId: string) => void);
|
|
12
|
+
get pendingCount(): number;
|
|
13
|
+
hasPending(taskId: string): boolean;
|
|
14
|
+
enqueue(taskId: string, commit: () => Promise<void>): void;
|
|
15
|
+
receipt(taskId: string): Promise<void>;
|
|
16
|
+
retry(taskId: string): Promise<void>;
|
|
17
|
+
resume(): void;
|
|
18
|
+
stop(): Promise<void>;
|
|
19
|
+
private attempt;
|
|
20
|
+
private armRetry;
|
|
21
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type AgentRef } from '@byok-sdk/protocol';
|
|
2
|
+
/** Project sealed execution facts, never the offer's requested harness. */
|
|
3
|
+
export declare function terminalIdentity(runtimeId: string | undefined, agentRef?: AgentRef): {
|
|
4
|
+
harnessId?: string;
|
|
5
|
+
agentRef?: AgentRef;
|
|
6
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { DaemonConfig } from '../daemon/create-daemon';
|
|
2
|
+
import type { RuntimeAdapter } from '../types';
|
|
3
|
+
import type { DiagnosticsSnapshot } from './types';
|
|
4
|
+
export type { DiagnosticsSnapshot, DiagnosticCheck, DiagnosticStatus } from './types';
|
|
5
|
+
export interface DiagnoseDeviceOptions {
|
|
6
|
+
/** The same adapters used by an embedded host; omitted uses bundled adapters. */
|
|
7
|
+
adapters?: RuntimeAdapter[];
|
|
8
|
+
runtimeProbeTimeoutMs?: number;
|
|
9
|
+
}
|
|
10
|
+
/** Read-only device observation; does not read OS credentials or prove Agent readiness. */
|
|
11
|
+
export declare function diagnoseDevice(config: DaemonConfig, options?: DiagnoseDeviceOptions): Promise<DiagnosticsSnapshot>;
|
|
12
|
+
export interface RepairDeviceEnrollmentMetadataInput {
|
|
13
|
+
confirmed: true;
|
|
14
|
+
/** Obtain both from the host's authorized enrollment target, never from a guessed default. */
|
|
15
|
+
expectedDeviceId: string;
|
|
16
|
+
expectedTenantId: string;
|
|
17
|
+
}
|
|
18
|
+
export interface DeviceMetadataRepairResult {
|
|
19
|
+
action: 'restore-enrollment-metadata';
|
|
20
|
+
scope: 'device';
|
|
21
|
+
/** Metadata readback only; does not imply renewed credentials or a running daemon. */
|
|
22
|
+
status: 'repaired' | 'not-needed';
|
|
23
|
+
}
|
|
24
|
+
declare const MESSAGES: {
|
|
25
|
+
readonly 'confirmation-required': 'Explicit confirmation is required for enrollment metadata repair.';
|
|
26
|
+
readonly 'invalid-target': 'An explicit expected tenant and device are required.';
|
|
27
|
+
readonly 'daemon-running': 'Stop the daemon before enrollment metadata repair.';
|
|
28
|
+
readonly 'store-busy': 'The store is owned by another operation; enrollment metadata repair refused.';
|
|
29
|
+
readonly 'authority-unavailable': 'The OS enrollment authority could not be read.';
|
|
30
|
+
readonly 'authority-missing': 'No complete OS enrollment exists; use explicit authenticated pairing.';
|
|
31
|
+
readonly 'target-mismatch': 'The OS enrollment does not match the expected tenant and device.';
|
|
32
|
+
readonly 'projection-unavailable': 'The enrollment metadata could not be read safely; repair refused.';
|
|
33
|
+
readonly 'repair-failed': 'Enrollment metadata repair did not complete; inspect the state before retrying.';
|
|
34
|
+
};
|
|
35
|
+
export type DeviceMetadataRepairErrorCode = keyof typeof MESSAGES;
|
|
36
|
+
/** Closed diagnostics only: no OS stderr, local paths, authority bytes or nested cause. */
|
|
37
|
+
export declare class DeviceMetadataRepairError extends Error {
|
|
38
|
+
readonly code: DeviceMetadataRepairErrorCode;
|
|
39
|
+
constructor(code: DeviceMetadataRepairErrorCode);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Explicitly restore missing/valid-stale device.json from its existing OS authority.
|
|
43
|
+
* Does not instantiate AuthManager, renew credentials, pair, or start a runtime.
|
|
44
|
+
* Ordinary doctor remains credential-blind; only this confirmed action opens the OS store.
|
|
45
|
+
*/
|
|
46
|
+
export declare function repairDeviceEnrollmentMetadata(config: DaemonConfig, input: RepairDeviceEnrollmentMetadataInput): Promise<DeviceMetadataRepairResult>;
|
|
@@ -1,106 +1,21 @@
|
|
|
1
|
+
import type { DiagnosticsSnapshot } from './types';
|
|
1
2
|
import type { DaemonConfig, RuntimeAdapter } from '../index';
|
|
2
3
|
import { connectControlClient } from '../bin/control-client';
|
|
3
|
-
import
|
|
4
|
-
import { type OperationalHealthFileInspection, OPERATIONAL_HEALTH_FILENAME } from '../daemon/operational-health';
|
|
4
|
+
import { OPERATIONAL_HEALTH_FILENAME } from '../daemon/operational-health';
|
|
5
5
|
export declare const MAX_QUARANTINE_ENTRIES = 100;
|
|
6
6
|
export declare const MAX_QUARANTINE_SCAN_ENTRIES: number;
|
|
7
7
|
export declare const MAX_QUARANTINE_READ_BYTES: number;
|
|
8
8
|
export declare const MAX_DEVICE_RECORD_BYTES: number;
|
|
9
9
|
export declare const MAX_JOURNAL_COPY_BYTES: number;
|
|
10
|
-
export type DiagnosticStatus
|
|
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
|
-
}
|
|
10
|
+
export type { DiagnosticStatus, DiagnosticCheck, DiagnosticsSnapshot } from './types';
|
|
88
11
|
export interface CollectDiagnosticsOptions {
|
|
89
12
|
clock?: () => Date;
|
|
90
13
|
adapters?: RuntimeAdapter[];
|
|
91
14
|
connectControl?: typeof connectControlClient;
|
|
92
15
|
runtimeProbeTimeoutMs?: number;
|
|
93
16
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
reason: 'missing' | 'valid';
|
|
97
|
-
} | {
|
|
98
|
-
status: 'quarantined';
|
|
99
|
-
evidenceName: string;
|
|
100
|
-
manifestName: string;
|
|
101
|
-
sha256: string;
|
|
102
|
-
sizeBytes: number;
|
|
103
|
-
};
|
|
17
|
+
import type { OperationalHealthFixResult } from './types';
|
|
18
|
+
export type { OperationalHealthFixResult } from './types';
|
|
104
19
|
export declare function collectDiagnostics(config: DaemonConfig, storeDir: string, options?: CollectDiagnosticsOptions): Promise<DiagnosticsSnapshot>;
|
|
105
20
|
export declare function stableIdentifierHash(value: string): string;
|
|
106
21
|
/**
|