@aria-cli/server 1.0.19
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 +17 -0
- package/dist/.aria-build-stamp.json +4 -0
- package/dist/auth/api-key.d.ts +106 -0
- package/dist/config.d.ts +28 -0
- package/dist/daemon-launcher.d.ts +23 -0
- package/dist/daemon-launcher.js +3 -0
- package/dist/index-5tav2m70.js +3 -0
- package/dist/index-6extw9n6.js +2 -0
- package/dist/index-9n50yafd.js +3 -0
- package/dist/index-9xs3gn0p.js +2 -0
- package/dist/index-ghh3ag4c.js +548 -0
- package/dist/index-mnt9k223.js +15 -0
- package/dist/index-pe0pkp0v.js +2 -0
- package/dist/index-raeajnr7.js +2 -0
- package/dist/index-rr0sea4c.js +2 -0
- package/dist/index-zge0mhc0.js +3 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +1 -0
- package/dist/peer-principal-auth.d.ts +37 -0
- package/dist/routes/arions.d.ts +34 -0
- package/dist/routes/council.d.ts +15 -0
- package/dist/routes/entrypoint-errors.d.ts +7 -0
- package/dist/routes/health.d.ts +6 -0
- package/dist/routes/invite-relay.d.ts +2 -0
- package/dist/routes/local-control.d.ts +3 -0
- package/dist/routes/message.d.ts +17 -0
- package/dist/routes/network.d.ts +14 -0
- package/dist/routes/pair.d.ts +57 -0
- package/dist/routes/pair.js +1 -0
- package/dist/routes/pipeline-mailbox.d.ts +10 -0
- package/dist/routes/relay.d.ts +29 -0
- package/dist/routes/resume.d.ts +2 -0
- package/dist/routes/run-control-surface.d.ts +24 -0
- package/dist/routes/run.d.ts +6 -0
- package/dist/routes/runtime-bootstrap.d.ts +3 -0
- package/dist/routes/runtime-node-advertisement.d.ts +3 -0
- package/dist/routes/runtime-run-room.d.ts +8 -0
- package/dist/routes/shared.d.ts +45 -0
- package/dist/routes/stream.d.ts +10 -0
- package/dist/routes/validation.d.ts +7 -0
- package/dist/routes/ws-revocation.d.ts +25 -0
- package/dist/runtime/attached-sender-inbox.d.ts +3 -0
- package/dist/runtime/authoritative-peer-endpoint.d.ts +27 -0
- package/dist/runtime/continuity-bind-suspicion.d.ts +39 -0
- package/dist/runtime/continuity-verification.d.ts +54 -0
- package/dist/runtime/decorate-runtime-surface.d.ts +2 -0
- package/dist/runtime/durable-network-store-surface.d.ts +51 -0
- package/dist/runtime/error-diagnostic.d.ts +12 -0
- package/dist/runtime/headless-dispatch-handler.d.ts +30 -0
- package/dist/runtime/host-supervisor.d.ts +109 -0
- package/dist/runtime/host-supervisor.js +1 -0
- package/dist/runtime/join-control.d.ts +3 -0
- package/dist/runtime/local-control-api.d.ts +63 -0
- package/dist/runtime/local-control-api.js +1 -0
- package/dist/runtime/local-control-pairing.d.ts +12 -0
- package/dist/runtime/local-control-socket.d.ts +48 -0
- package/dist/runtime/log-file-sink.d.ts +21 -0
- package/dist/runtime/network-read-control.d.ts +17 -0
- package/dist/runtime/network-state-stores.d.ts +2 -0
- package/dist/runtime/node-metadata.d.ts +22 -0
- package/dist/runtime/node-metadata.js +1 -0
- package/dist/runtime/node-runtime.d.ts +157 -0
- package/dist/runtime/node-store-revocation-store.d.ts +42 -0
- package/dist/runtime/node-store.d.ts +184 -0
- package/dist/runtime/node-store.js +1 -0
- package/dist/runtime/pinned-control-session.d.ts +41 -0
- package/dist/runtime/principal-binding-authority.d.ts +173 -0
- package/dist/runtime/reachable-control-host.d.ts +5 -0
- package/dist/runtime/runtime-admin-api.d.ts +16 -0
- package/dist/runtime/runtime-authority-registry.d.ts +55 -0
- package/dist/runtime/runtime-autonomous-loop.d.ts +40 -0
- package/dist/runtime/runtime-bootstrap-authority.d.ts +5 -0
- package/dist/runtime/runtime-bootstrap-record.d.ts +21 -0
- package/dist/runtime/runtime-event-journal.d.ts +21 -0
- package/dist/runtime/runtime-outbox.d.ts +35 -0
- package/dist/runtime/runtime-registry.d.ts +33 -0
- package/dist/runtime/runtime-registry.js +1 -0
- package/dist/runtime/runtime-run-control.d.ts +71 -0
- package/dist/runtime/stale-owner-error.d.ts +13 -0
- package/dist/runtime-run-control-0r21xdh5.js +2 -0
- package/dist/server.d.ts +84 -0
- package/dist/session-history-messages.d.ts +3 -0
- package/dist/session-history.d.ts +28 -0
- package/dist/shared-4jsvhy6g.js +1 -0
- package/dist/types.d.ts +299 -0
- package/dist/utils/rate-limiter.d.ts +25 -0
- package/dist/utils/sanitize-error.d.ts +10 -0
- package/package.json +82 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { FastifyInstance } from "fastify";
|
|
2
|
+
import type { AcceptInviteRequest, AcceptInviteResponse, AcceptInviteTokenRequest, AcceptInviteTokenResponse, AttachedClientAuth, AttachedClientView, CancelInviteRequest, CancelInviteResponse, CreateInviteRequest, CreateInviteResponse, DirectPairRequest, DirectPairResponse, InboxCursor, InboxListRequest, InvitePeerRequest, InvitePeerResult, NearbyPeerView, OutboundMessage, PairRequestDecision, PairRequestResponse, PendingInviteView, PendingPairRequestView, PeerViewEvent, RepairPeerRequest, RepairPeerResponse, RevokePeerRequest, RevokePeerResponse, ResumeRunRequest, RuntimeRunEvent, RunRequest, RunResult, RuntimeDeliveryReceipt, RuntimeQueuedReceipt, RuntimeBootstrapRecord, RuntimeAutonomousLoopCommand, RuntimeStatus, PersistedInboxEvent, RuntimeEvent, RuntimeEventCursor } from "@aria-cli/tools";
|
|
3
|
+
export type { AcceptInviteRequest, AcceptInviteResponse, AcceptInviteTokenRequest, AcceptInviteTokenResponse, AttachedClientAuth, AttachedClientLeaseGrant, AttachedClientView, CancelInviteRequest, CancelInviteResponse, CreateInviteRequest, CreateInviteResponse, DirectPairRequest, DirectPairResponse, InboxCursor, InboxListRequest, InvitePeerRequest, InvitePeerResult, OutboundMessage, PairRequestDecision, PairRequestResponse, PendingInviteView, PendingPairRequestView, PeerViewEvent, RunRequest, RunResult, RepairPeerRequest, RepairPeerResponse, RevokePeerRequest, RevokePeerResponse, ResumeRunRequest, RuntimeRunEvent, RuntimeDeliveryReceipt, RuntimeEvent, RuntimeEventCursor, RuntimeQueuedReceipt, RuntimeBootstrapRecord, RuntimeAutonomousLoopCommand, RuntimeStatus, PersistedInboxEvent, } from "@aria-cli/tools";
|
|
4
|
+
type LocalControlServer = FastifyInstance & {
|
|
5
|
+
ariaRunControl?: FastifyInstance["ariaRunControl"];
|
|
6
|
+
ariaRuntimeMessageControl?: FastifyInstance["ariaRuntimeMessageControl"];
|
|
7
|
+
ariaRuntimeBootstrapControl?: FastifyInstance["ariaRuntimeBootstrapControl"];
|
|
8
|
+
ariaPeerLocalControl?: FastifyInstance["ariaPeerLocalControl"];
|
|
9
|
+
ariaPairControl?: FastifyInstance["ariaPairControl"];
|
|
10
|
+
ariaNetworkAdminControl?: FastifyInstance["ariaNetworkAdminControl"];
|
|
11
|
+
};
|
|
12
|
+
export interface RunHandle {
|
|
13
|
+
runId: string;
|
|
14
|
+
wait(): Promise<RunResult>;
|
|
15
|
+
}
|
|
16
|
+
export interface LocalControlApi {
|
|
17
|
+
submitRun(request: RunRequest): Promise<RunHandle>;
|
|
18
|
+
resumeRun(request: ResumeRunRequest): Promise<RunResult>;
|
|
19
|
+
streamRun(request: RunRequest, signal?: AbortSignal): AsyncIterable<RuntimeRunEvent>;
|
|
20
|
+
subscribeRuntimeEvents(cursor?: RuntimeEventCursor): AsyncIterable<RuntimeEvent>;
|
|
21
|
+
sendBestEffort(message: OutboundMessage): Promise<RuntimeQueuedReceipt>;
|
|
22
|
+
sendDurable(message: OutboundMessage): Promise<RuntimeDeliveryReceipt>;
|
|
23
|
+
listInbox(request?: InboxListRequest): Promise<PersistedInboxEvent[]>;
|
|
24
|
+
subscribeInbox(cursor?: InboxCursor): AsyncIterable<PersistedInboxEvent>;
|
|
25
|
+
listPeers(): Promise<PeerViewEvent[]>;
|
|
26
|
+
listNearbyPeers(): Promise<NearbyPeerView[]>;
|
|
27
|
+
subscribePeers(): AsyncIterable<PeerViewEvent>;
|
|
28
|
+
getRuntimeStatus(): Promise<RuntimeStatus>;
|
|
29
|
+
startAutonomousLoop?(input?: RuntimeAutonomousLoopCommand): Promise<RuntimeStatus>;
|
|
30
|
+
stopAutonomousLoop?(): Promise<RuntimeStatus>;
|
|
31
|
+
getRuntimeBootstrap(): Promise<RuntimeBootstrapRecord>;
|
|
32
|
+
listPendingPairRequests(): Promise<PendingPairRequestView[]>;
|
|
33
|
+
respondToPairRequest(input: PairRequestDecision): Promise<PairRequestResponse>;
|
|
34
|
+
createInvite(input: CreateInviteRequest): Promise<CreateInviteResponse>;
|
|
35
|
+
listPendingInvites(): Promise<PendingInviteView[]>;
|
|
36
|
+
acceptInviteToken(input: AcceptInviteTokenRequest): Promise<AcceptInviteTokenResponse>;
|
|
37
|
+
cancelInvite(input: CancelInviteRequest): Promise<CancelInviteResponse>;
|
|
38
|
+
invitePeer(input: InvitePeerRequest): Promise<InvitePeerResult>;
|
|
39
|
+
acceptInvite(input: AcceptInviteRequest): Promise<AcceptInviteResponse>;
|
|
40
|
+
directPair(input: DirectPairRequest): Promise<DirectPairResponse>;
|
|
41
|
+
revokePeer(input: RevokePeerRequest): Promise<RevokePeerResponse>;
|
|
42
|
+
repairPeer(input: RepairPeerRequest): Promise<RepairPeerResponse>;
|
|
43
|
+
}
|
|
44
|
+
type AttachedClientAwareLocalControlApi = LocalControlApi & {
|
|
45
|
+
submitRunAsAttachedClient?(auth: AttachedClientAuth, request: RunRequest): Promise<RunHandle>;
|
|
46
|
+
resumeRunAsAttachedClient?(auth: AttachedClientAuth, request: ResumeRunRequest): Promise<RunResult>;
|
|
47
|
+
streamRunAsAttachedClient?(auth: AttachedClientAuth, request: RunRequest, signal?: AbortSignal): AsyncIterable<RuntimeRunEvent>;
|
|
48
|
+
sendBestEffortAsAttachedClient?(auth: AttachedClientAuth, message: OutboundMessage): Promise<RuntimeQueuedReceipt>;
|
|
49
|
+
sendDurableAsAttachedClient?(auth: AttachedClientAuth, message: OutboundMessage): Promise<RuntimeDeliveryReceipt>;
|
|
50
|
+
};
|
|
51
|
+
export interface AttachedLocalControlApi extends LocalControlApi {
|
|
52
|
+
listAttachedClients(): Promise<AttachedClientView[]>;
|
|
53
|
+
listDirectClientInbox(request?: InboxListRequest): Promise<PersistedInboxEvent[]>;
|
|
54
|
+
subscribeDirectClientInbox(cursor?: InboxCursor): AsyncIterable<PersistedInboxEvent>;
|
|
55
|
+
}
|
|
56
|
+
export declare function createLocalControlApi(options: {
|
|
57
|
+
status: RuntimeStatus | (() => Promise<RuntimeStatus> | RuntimeStatus);
|
|
58
|
+
startAutonomousLoop?: (input?: RuntimeAutonomousLoopCommand) => Promise<RuntimeStatus>;
|
|
59
|
+
stopAutonomousLoop?: () => Promise<RuntimeStatus>;
|
|
60
|
+
server?: LocalControlServer;
|
|
61
|
+
pollIntervalMs?: number;
|
|
62
|
+
subscribeRuntimeEvents?: (cursor?: RuntimeEventCursor) => AsyncIterable<RuntimeEvent>;
|
|
63
|
+
}): AttachedClientAwareLocalControlApi;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Q as a}from"../index-rr0sea4c.js";import"../index-9xs3gn0p.js";export{a as createLocalControlApi};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FastifyInstance } from "fastify";
|
|
2
|
+
import { type CreateInviteRequest, type CreateInviteResponse, type InvitePeerRequest, type InvitePeerResult, type PendingInviteView, type AcceptInviteTokenRequest, type AcceptInviteTokenResponse, type CancelInviteRequest, type CancelInviteResponse, type RepairPeerRequest, type RepairPeerResponse } from "@aria-cli/tools";
|
|
3
|
+
export declare class LocalControlRepairError extends Error {
|
|
4
|
+
readonly statusCode: number;
|
|
5
|
+
constructor(statusCode: number, message: string);
|
|
6
|
+
}
|
|
7
|
+
export declare function createInviteViaRuntimeControl(server: FastifyInstance, input: CreateInviteRequest): Promise<CreateInviteResponse>;
|
|
8
|
+
export declare function listPendingInvitesViaRuntimeControl(server: FastifyInstance): PendingInviteView[];
|
|
9
|
+
export declare function acceptInviteTokenViaRuntimeControl(server: FastifyInstance, input: AcceptInviteTokenRequest): Promise<AcceptInviteTokenResponse>;
|
|
10
|
+
export declare function cancelInviteViaRuntimeControl(server: FastifyInstance, input: CancelInviteRequest): CancelInviteResponse;
|
|
11
|
+
export declare function invitePeerViaRuntimeControl(server: FastifyInstance, request: InvitePeerRequest): Promise<InvitePeerResult>;
|
|
12
|
+
export declare function repairPeerViaRuntimeControl(server: FastifyInstance, request: RepairPeerRequest): RepairPeerResponse;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { FastifyInstance, FastifyRequest } from "fastify";
|
|
2
|
+
import type { AttachedClientAuth, InboxCursor, AttachedClientView, InboxListRequest, LocalControlSocketAttachClientRequest, LocalControlSocketAttachClientResponse, LocalControlSocketDetachClientRequest, LocalControlSocketDetachClientResponse, NearbyPeerView, PersistedInboxEvent, PeerViewEvent, RuntimeEvent, RuntimeEventCursor } from "@aria-cli/tools";
|
|
3
|
+
import type { LocalControlApi } from "./local-control-api.js";
|
|
4
|
+
import { type AttachedClientAuthErrorReason } from "./error-diagnostic.js";
|
|
5
|
+
export { LOCAL_HTTP_CLIENT_ID_HEADER, LOCAL_HTTP_CLIENT_PROOF_HEADER } from "@aria-cli/tools";
|
|
6
|
+
export interface AttachedLocalHttpClientAuthority {
|
|
7
|
+
authorizeAttachedClient(clientId: string, clientAuthToken: string): boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface LocalControlSocketServer {
|
|
10
|
+
socketPath: string;
|
|
11
|
+
close(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export interface CreateLocalControlSocketServerOptions {
|
|
14
|
+
socketPath: string;
|
|
15
|
+
localControl: LocalControlApi;
|
|
16
|
+
listInbox(request?: InboxListRequest): Promise<PersistedInboxEvent[]>;
|
|
17
|
+
listPeers(): Promise<PeerViewEvent[]>;
|
|
18
|
+
listNearbyPeers(): Promise<NearbyPeerView[]>;
|
|
19
|
+
listAttachedClients?(auth: AttachedClientAuth): Promise<AttachedClientView[]>;
|
|
20
|
+
listDirectClientInbox?(auth: AttachedClientAuth, request?: InboxListRequest): Promise<PersistedInboxEvent[]>;
|
|
21
|
+
subscribeDirectClientInbox?(auth: AttachedClientAuth, cursor?: InboxCursor): AsyncIterable<PersistedInboxEvent>;
|
|
22
|
+
authorizeAttachedClient?(auth: AttachedClientAuth): boolean;
|
|
23
|
+
subscribeRuntimeEvents(cursor?: RuntimeEventCursor): AsyncIterable<RuntimeEvent>;
|
|
24
|
+
attachClient(input: LocalControlSocketAttachClientRequest): Promise<LocalControlSocketAttachClientResponse>;
|
|
25
|
+
onClientLeaseSocket?(clientId: string, socket: import("node:net").Socket): void;
|
|
26
|
+
detachClient(input: LocalControlSocketDetachClientRequest): Promise<LocalControlSocketDetachClientResponse>;
|
|
27
|
+
/** Register a callback that fires when the daemon receives a new peer message.
|
|
28
|
+
* Used by watchInbox to push messages to clients in real-time. */
|
|
29
|
+
onMessageReceived?(callback: () => void): void;
|
|
30
|
+
/** Optional structured logger for diagnostic events (auth rejections, etc.) */
|
|
31
|
+
log?(level: "info" | "warn" | "error", message: string): void;
|
|
32
|
+
}
|
|
33
|
+
export declare function installAttachedLocalHttpClientAuthority(server: FastifyInstance, authority: AttachedLocalHttpClientAuthority): void;
|
|
34
|
+
export type AttachedLocalHttpClientAuthResult = {
|
|
35
|
+
ok: true;
|
|
36
|
+
clientId: string;
|
|
37
|
+
} | {
|
|
38
|
+
ok: false;
|
|
39
|
+
error: "attached-local-client-only";
|
|
40
|
+
reason: AttachedClientAuthErrorReason;
|
|
41
|
+
};
|
|
42
|
+
export declare function authorizeAttachedLocalHttpClient(server: FastifyInstance, request: FastifyRequest | {
|
|
43
|
+
headers: Record<string, unknown>;
|
|
44
|
+
}): AttachedLocalHttpClientAuthResult;
|
|
45
|
+
export declare function hasAttachedLocalHttpClientHeaders(request: FastifyRequest | {
|
|
46
|
+
headers: Record<string, unknown>;
|
|
47
|
+
}): boolean;
|
|
48
|
+
export declare function createLocalControlSocketServer(options: CreateLocalControlSocketServerOptions): Promise<LocalControlSocketServer>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable JSONL log sink for headless processes (daemon, server).
|
|
3
|
+
*
|
|
4
|
+
* Design decisions:
|
|
5
|
+
* - Sync writes (appendFileSync): crash-safe. At most one line lost on kill.
|
|
6
|
+
* Async buffering would lose an entire batch on OOM/jetsam.
|
|
7
|
+
* - JSONL format: machine-queryable (`jq`), human-readable, grep-friendly.
|
|
8
|
+
* - ANSI stripped: file sinks have no terminal; color codes are noise.
|
|
9
|
+
* - Size-based rotation: prevents unbounded growth. Checked every N writes
|
|
10
|
+
* to amortize the stat() cost.
|
|
11
|
+
* - mkdir on construction: the sink must be wirable before ariaHome is
|
|
12
|
+
* fully initialized.
|
|
13
|
+
*/
|
|
14
|
+
import type { LogSink } from "@aria-cli/types";
|
|
15
|
+
export interface FileLogSinkOptions {
|
|
16
|
+
/** Maximum file size in bytes before rotation (default 50 MB). */
|
|
17
|
+
maxBytes?: number;
|
|
18
|
+
/** Number of rotated files to keep (default 3). */
|
|
19
|
+
maxFiles?: number;
|
|
20
|
+
}
|
|
21
|
+
export declare function createFileLogSink(filePath: string, options?: FileLogSinkOptions): LogSink;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FastifyInstance } from "fastify";
|
|
2
|
+
import "../types.js";
|
|
3
|
+
import { type NodeId, type PeerTransportId } from "@aria-cli/tools/network-runtime";
|
|
4
|
+
export type ListedPeerView = {
|
|
5
|
+
nodeId: NodeId;
|
|
6
|
+
transportPublicKey: PeerTransportId;
|
|
7
|
+
displayNameSnapshot?: string;
|
|
8
|
+
status: string;
|
|
9
|
+
endpointHost: string | null;
|
|
10
|
+
endpointPort: number | null;
|
|
11
|
+
endpointRevision: number;
|
|
12
|
+
lastHandshake: number | null;
|
|
13
|
+
createdAt: number;
|
|
14
|
+
updatedAt: number;
|
|
15
|
+
};
|
|
16
|
+
export declare function listPeerViewsFromRuntime(server: FastifyInstance): ListedPeerView[];
|
|
17
|
+
export declare function ensureNetworkReadControl(server: FastifyInstance): void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type NodeId } from "@aria-cli/tools/network-runtime";
|
|
2
|
+
export declare const NODE_METADATA_SCHEMA_VERSION = 1;
|
|
3
|
+
export interface ResolvedNode {
|
|
4
|
+
ariaHome: string;
|
|
5
|
+
metadataPath: string;
|
|
6
|
+
nodeId: NodeId;
|
|
7
|
+
createdAt: string;
|
|
8
|
+
schemaVersion: number;
|
|
9
|
+
migratedFromLegacy: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function canonicalizeAriaHome(ariaHome: string): string;
|
|
12
|
+
export declare function nodeMetadataPathForAriaHome(ariaHome: string): string;
|
|
13
|
+
export declare function resolveOrCreateNode(options: {
|
|
14
|
+
ariaHome: string;
|
|
15
|
+
}): Promise<ResolvedNode>;
|
|
16
|
+
export declare function resolveConfiguredNode(options: {
|
|
17
|
+
ariaHome: string;
|
|
18
|
+
nodeId: NodeId;
|
|
19
|
+
}): Promise<ResolvedNode>;
|
|
20
|
+
export declare function readResolvedNodeSync(options: {
|
|
21
|
+
ariaHome: string;
|
|
22
|
+
}): ResolvedNode | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ea as a,fa as b,ga as c,ha as d,ia as e,ja as f}from"../index-5tav2m70.js";import"../index-ghh3ag4c.js";import"../index-9xs3gn0p.js";export{d as resolveOrCreateNode,e as resolveConfiguredNode,f as readResolvedNodeSync,c as nodeMetadataPathForAriaHome,b as canonicalizeAriaHome,a as NODE_METADATA_SCHEMA_VERSION};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { NetworkIntelligenceCoordinator, type MemoriaFactory } from "@aria-cli/aria";
|
|
2
|
+
import type { AuthResolver } from "@aria-cli/auth";
|
|
3
|
+
import type { ModelRouter } from "@aria-cli/models";
|
|
4
|
+
import { type LocalControlClientKind, type NetworkManagerRef, type NodeId, type PrincipalFingerprint, type RevocationOperatorConfirmation, type TlsCaFingerprint, type RuntimeId } from "@aria-cli/tools";
|
|
5
|
+
import { createServer } from "../server.js";
|
|
6
|
+
import { type LocalControlApi } from "./local-control-api.js";
|
|
7
|
+
import { NodeStore } from "./node-store.js";
|
|
8
|
+
import { type RuntimeAdminApi } from "./runtime-admin-api.js";
|
|
9
|
+
import { type RuntimeOutbox } from "./runtime-outbox.js";
|
|
10
|
+
export interface NodeRuntimeMailbox {
|
|
11
|
+
registerTunnel(nodeId: NodeId, transport: {
|
|
12
|
+
sendPlaintext(data: Buffer): void;
|
|
13
|
+
routeBootstrapOnly?: boolean;
|
|
14
|
+
}): void;
|
|
15
|
+
unregisterTunnel(nodeId: NodeId): void;
|
|
16
|
+
}
|
|
17
|
+
export interface NodeRuntimeOptions {
|
|
18
|
+
arionName: string;
|
|
19
|
+
ariaHome: string;
|
|
20
|
+
nodeId: NodeId;
|
|
21
|
+
runtimeLifecycle?: "scoped" | "persistent";
|
|
22
|
+
runtimeSocketPath?: string;
|
|
23
|
+
memoriaFactory?: MemoriaFactory;
|
|
24
|
+
router?: ModelRouter;
|
|
25
|
+
authResolver?: AuthResolver;
|
|
26
|
+
signal?: AbortSignal;
|
|
27
|
+
networkManager?: NetworkManagerRef;
|
|
28
|
+
nodeStore?: NodeStore;
|
|
29
|
+
port?: number;
|
|
30
|
+
silent?: boolean;
|
|
31
|
+
mailboxRef?: {
|
|
32
|
+
current: NodeRuntimeMailbox | null;
|
|
33
|
+
};
|
|
34
|
+
onTransportEstablished?: (displayNameSnapshot: string, transport: {
|
|
35
|
+
sendPlaintext(data: Buffer): void;
|
|
36
|
+
}) => void;
|
|
37
|
+
onTransportTornDown?: (displayNameSnapshot: string) => void;
|
|
38
|
+
runSessionConfig?: import("@aria-cli/aria").RunSessionConfig;
|
|
39
|
+
mcpServers?: import("@aria-cli/tools").MCPServerConfig[];
|
|
40
|
+
daemonSafetyPolicy?: import("@aria-cli/aria").DaemonSafetyPolicy;
|
|
41
|
+
autonomousIntervalMs?: number;
|
|
42
|
+
ownerClientKind?: LocalControlClientKind;
|
|
43
|
+
ownerGeneration?: number;
|
|
44
|
+
ownerGenerationHint?: number;
|
|
45
|
+
faultCheckpoint?: (point: "after_proof_validation_before_commit" | "after_persist_before_ack" | "runtime_death_during_durable_send", context: Record<string, unknown>) => void;
|
|
46
|
+
}
|
|
47
|
+
export interface NodeRuntimeCerts {
|
|
48
|
+
caCert: string;
|
|
49
|
+
serverCert: string;
|
|
50
|
+
serverKey: string;
|
|
51
|
+
fingerprint: TlsCaFingerprint;
|
|
52
|
+
}
|
|
53
|
+
type RuntimeRevocationAuthority = {
|
|
54
|
+
revoke(event: {
|
|
55
|
+
nodeId: NodeId;
|
|
56
|
+
displayNameSnapshot?: string;
|
|
57
|
+
fingerprint: PrincipalFingerprint;
|
|
58
|
+
revokedAt: number;
|
|
59
|
+
localNodeId: NodeId;
|
|
60
|
+
operatorConfirmation: RevocationOperatorConfirmation;
|
|
61
|
+
reason?: string;
|
|
62
|
+
revocationGeneration?: number;
|
|
63
|
+
}): void;
|
|
64
|
+
isPeerRevoked(nodeId: NodeId): boolean;
|
|
65
|
+
read?(nodeId: NodeId): {
|
|
66
|
+
nodeId: NodeId;
|
|
67
|
+
displayNameSnapshot?: string;
|
|
68
|
+
fingerprint: PrincipalFingerprint;
|
|
69
|
+
revokedAt: number;
|
|
70
|
+
localNodeId: NodeId;
|
|
71
|
+
operatorConfirmation: RevocationOperatorConfirmation;
|
|
72
|
+
reason?: string;
|
|
73
|
+
revocationGeneration?: number;
|
|
74
|
+
} | null;
|
|
75
|
+
getPeerRevocationGeneration?(nodeId: NodeId): number | null;
|
|
76
|
+
clearRevocationForNodeId(nodeId: NodeId, expectedGeneration?: number): boolean;
|
|
77
|
+
list(): Array<{
|
|
78
|
+
nodeId: NodeId;
|
|
79
|
+
displayNameSnapshot?: string;
|
|
80
|
+
fingerprint: PrincipalFingerprint;
|
|
81
|
+
revokedAt: number;
|
|
82
|
+
localNodeId: NodeId;
|
|
83
|
+
operatorConfirmation: RevocationOperatorConfirmation;
|
|
84
|
+
reason?: string;
|
|
85
|
+
revocationGeneration?: number;
|
|
86
|
+
}>;
|
|
87
|
+
};
|
|
88
|
+
export interface NodeRuntimeControl {
|
|
89
|
+
nodeId: NodeId;
|
|
90
|
+
runtimeId: RuntimeId;
|
|
91
|
+
displayNameSnapshot?: string;
|
|
92
|
+
port: number;
|
|
93
|
+
networkManager: NetworkManagerRef;
|
|
94
|
+
server: Awaited<ReturnType<typeof createServer>>;
|
|
95
|
+
certs: NodeRuntimeCerts;
|
|
96
|
+
runtimeOutbox: RuntimeOutbox;
|
|
97
|
+
revocationStore: RuntimeRevocationAuthority | undefined;
|
|
98
|
+
networkCoordinator: NetworkIntelligenceCoordinator | undefined;
|
|
99
|
+
localControl: LocalControlApi;
|
|
100
|
+
runtimeAdmin: RuntimeAdminApi;
|
|
101
|
+
waitForInitialDiscovery: () => Promise<void>;
|
|
102
|
+
registerMailbox: (mailbox: NodeRuntimeMailbox) => () => void;
|
|
103
|
+
}
|
|
104
|
+
export interface NodeRuntimeAutonomousLoopBootstrapOptions {
|
|
105
|
+
memoriaFactory?: MemoriaFactory;
|
|
106
|
+
router?: ModelRouter;
|
|
107
|
+
authResolver?: AuthResolver;
|
|
108
|
+
runSessionConfig?: import("@aria-cli/aria").RunSessionConfig;
|
|
109
|
+
mcpServers?: import("@aria-cli/tools").MCPServerConfig[];
|
|
110
|
+
daemonSafetyPolicy?: import("@aria-cli/aria").DaemonSafetyPolicy;
|
|
111
|
+
autonomousIntervalMs?: number;
|
|
112
|
+
}
|
|
113
|
+
export declare class NodeRuntime {
|
|
114
|
+
private readonly options;
|
|
115
|
+
readonly nodeId: NodeId;
|
|
116
|
+
private readonly runtimeIdValue;
|
|
117
|
+
private started;
|
|
118
|
+
private runtimeControl;
|
|
119
|
+
private networkStateStore;
|
|
120
|
+
private relayPollTimer;
|
|
121
|
+
private stunClient;
|
|
122
|
+
private discoveryService;
|
|
123
|
+
private mdnsDiscovery;
|
|
124
|
+
private privateLanDiscovery;
|
|
125
|
+
private nearbyPeerDiscovery;
|
|
126
|
+
private nodeStore;
|
|
127
|
+
private ownsNetworkManager;
|
|
128
|
+
private ownsNodeStore;
|
|
129
|
+
private bootstrapOwnerGeneration;
|
|
130
|
+
private unsubscribeRuntimeIngressListener;
|
|
131
|
+
private unsubscribeTransportListener;
|
|
132
|
+
private localControlSocket;
|
|
133
|
+
private autonomousLoop;
|
|
134
|
+
private autonomousLoopStartPromise;
|
|
135
|
+
private autonomousLoopBootstrap;
|
|
136
|
+
private networkingReadyResolve;
|
|
137
|
+
private networkingReadyReject;
|
|
138
|
+
readonly networkingReady: Promise<void>;
|
|
139
|
+
constructor(options: NodeRuntimeOptions);
|
|
140
|
+
get runtimeId(): RuntimeId;
|
|
141
|
+
private resolvedBootstrapOwnerGeneration;
|
|
142
|
+
private nextBootstrapRevision;
|
|
143
|
+
private resolveBootstrapControlHost;
|
|
144
|
+
private isRecoverableDaemonBindError;
|
|
145
|
+
private daemonBindCandidates;
|
|
146
|
+
private publishBootstrapPhase;
|
|
147
|
+
configureAutonomousLoop(options: NodeRuntimeAutonomousLoopBootstrapOptions): NodeRuntimeAutonomousLoopBootstrapOptions;
|
|
148
|
+
private summarizeAutonomousLoopSafetyPolicy;
|
|
149
|
+
private getAutonomousLoopStatus;
|
|
150
|
+
stopAutonomousLoop(): Promise<void>;
|
|
151
|
+
startAutonomousLoop(): Promise<void>;
|
|
152
|
+
start(): Promise<void>;
|
|
153
|
+
private startNetworkingSubsystems;
|
|
154
|
+
shutdown(): Promise<void>;
|
|
155
|
+
control(): NodeRuntimeControl;
|
|
156
|
+
}
|
|
157
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { NodeId, PrincipalFingerprint, RevocationOperatorConfirmation } from "@aria-cli/tools/network-runtime";
|
|
2
|
+
export declare function createNodeStoreBackedRevocationStore(input: {
|
|
3
|
+
ariaHome: string;
|
|
4
|
+
ownerGeneration: number;
|
|
5
|
+
}): {
|
|
6
|
+
revoke(event: {
|
|
7
|
+
nodeId: NodeId;
|
|
8
|
+
displayNameSnapshot?: string;
|
|
9
|
+
fingerprint: PrincipalFingerprint;
|
|
10
|
+
revokedAt: number;
|
|
11
|
+
localNodeId: NodeId;
|
|
12
|
+
operatorConfirmation: RevocationOperatorConfirmation;
|
|
13
|
+
reason?: string;
|
|
14
|
+
revocationGeneration?: number;
|
|
15
|
+
}): void;
|
|
16
|
+
isPeerRevoked(nodeId: NodeId): boolean;
|
|
17
|
+
read(nodeId: NodeId): {
|
|
18
|
+
localNodeId: string & import("zod").$brand<"NodeId">;
|
|
19
|
+
nodeId: NodeId;
|
|
20
|
+
displayNameSnapshot?: string;
|
|
21
|
+
fingerprint: PrincipalFingerprint;
|
|
22
|
+
revokedAt: number;
|
|
23
|
+
revokedBy: NodeId;
|
|
24
|
+
operatorConfirmation: RevocationOperatorConfirmation;
|
|
25
|
+
reason?: string;
|
|
26
|
+
revocationGeneration: number;
|
|
27
|
+
} | null;
|
|
28
|
+
getPeerRevocationGeneration(nodeId: NodeId): number | null;
|
|
29
|
+
clearRevocationForNodeId(nodeId: NodeId, expectedGeneration?: number): boolean;
|
|
30
|
+
list(): {
|
|
31
|
+
localNodeId: string & import("zod").$brand<"NodeId">;
|
|
32
|
+
nodeId: NodeId;
|
|
33
|
+
displayNameSnapshot?: string;
|
|
34
|
+
fingerprint: PrincipalFingerprint;
|
|
35
|
+
revokedAt: number;
|
|
36
|
+
revokedBy: NodeId;
|
|
37
|
+
operatorConfirmation: RevocationOperatorConfirmation;
|
|
38
|
+
reason?: string;
|
|
39
|
+
revocationGeneration: number;
|
|
40
|
+
}[];
|
|
41
|
+
close(): void;
|
|
42
|
+
};
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { type NodeId, type NodeMetadata, type PeerTransportId, type PrincipalFingerprint, type TlsCaFingerprint, type RevocationOperatorConfirmation, type RuntimeBootstrapRecord, type RuntimeEvent, type RuntimeEventKind, type RuntimeOwnerRecord, type RuntimeId } from "@aria-cli/tools/network-runtime";
|
|
2
|
+
export { StaleOwnerError } from "./stale-owner-error.js";
|
|
3
|
+
export declare const NODE_STORE_SCHEMA_VERSION = 1;
|
|
4
|
+
interface NodeStoreOptions {
|
|
5
|
+
ariaHome: string;
|
|
6
|
+
/**
|
|
7
|
+
* Owner generation for this runtime instance. When provided, the store
|
|
8
|
+
* claims the epoch atomically on construction and rejects all durable
|
|
9
|
+
* writes if a newer generation has taken over (throws StaleOwnerError).
|
|
10
|
+
*
|
|
11
|
+
* Omit only for read-only administrative access (e.g. supervisor queries,
|
|
12
|
+
* migration tools). Write operations on an unfenced store throw.
|
|
13
|
+
*/
|
|
14
|
+
ownerGeneration?: number;
|
|
15
|
+
}
|
|
16
|
+
interface RuntimeEventRecordInput {
|
|
17
|
+
nodeId: NodeId;
|
|
18
|
+
runtimeId: RuntimeId;
|
|
19
|
+
kind: RuntimeEventKind;
|
|
20
|
+
payload?: Record<string, unknown>;
|
|
21
|
+
eventId?: string;
|
|
22
|
+
recordedAt?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface PeerBindingRecord {
|
|
25
|
+
nodeId: NodeId;
|
|
26
|
+
principalFingerprint: PrincipalFingerprint;
|
|
27
|
+
transportPublicKey: PeerTransportId;
|
|
28
|
+
continuityRevision: number;
|
|
29
|
+
endpointHost?: string;
|
|
30
|
+
endpointPort?: number;
|
|
31
|
+
endpointRevision?: number;
|
|
32
|
+
displayNameSnapshot?: string;
|
|
33
|
+
controlEndpointHost?: string;
|
|
34
|
+
controlEndpointPort?: number;
|
|
35
|
+
controlTlsCaFingerprint?: TlsCaFingerprint;
|
|
36
|
+
updatedAt: string;
|
|
37
|
+
}
|
|
38
|
+
export type PeerBindingMutation = Omit<PeerBindingRecord, "updatedAt">;
|
|
39
|
+
export type PeerEndpointProjectionCommitResult = {
|
|
40
|
+
kind: "not_found";
|
|
41
|
+
} | {
|
|
42
|
+
kind: "applied" | "idempotent" | "stale";
|
|
43
|
+
binding: PeerBindingRecord;
|
|
44
|
+
};
|
|
45
|
+
export declare function isEquivalentPeerBinding(existing: PeerBindingMutation, candidate: PeerBindingMutation): boolean;
|
|
46
|
+
export interface IngressReceiptRecord {
|
|
47
|
+
messageId: string;
|
|
48
|
+
senderNodeId: NodeId;
|
|
49
|
+
senderFingerprint: PrincipalFingerprint;
|
|
50
|
+
runtimeId: RuntimeId;
|
|
51
|
+
receivedAt: string;
|
|
52
|
+
}
|
|
53
|
+
export interface IngressReceiptCommitResult extends IngressReceiptRecord {
|
|
54
|
+
duplicate: boolean;
|
|
55
|
+
}
|
|
56
|
+
export interface OutboxReceiptRecord {
|
|
57
|
+
messageId: string;
|
|
58
|
+
senderNodeId: NodeId;
|
|
59
|
+
recipientNodeId: NodeId;
|
|
60
|
+
transport: string;
|
|
61
|
+
status: "queued_for_route" | "dispatching" | "acked" | "expired";
|
|
62
|
+
deliveryLifecycleRevision: number;
|
|
63
|
+
updatedAt: string;
|
|
64
|
+
}
|
|
65
|
+
export interface PeerRevocationRecord {
|
|
66
|
+
nodeId: NodeId;
|
|
67
|
+
displayNameSnapshot?: string;
|
|
68
|
+
fingerprint: PrincipalFingerprint;
|
|
69
|
+
revokedAt: number;
|
|
70
|
+
revokedBy: NodeId;
|
|
71
|
+
operatorConfirmation: RevocationOperatorConfirmation;
|
|
72
|
+
reason?: string;
|
|
73
|
+
revocationGeneration: number;
|
|
74
|
+
}
|
|
75
|
+
export interface RevocationConflictRecord {
|
|
76
|
+
conflictId: string;
|
|
77
|
+
nodeId: NodeId;
|
|
78
|
+
previousFingerprint?: PrincipalFingerprint;
|
|
79
|
+
conflictingFingerprint: PrincipalFingerprint;
|
|
80
|
+
reason: string;
|
|
81
|
+
recordedAt: string;
|
|
82
|
+
}
|
|
83
|
+
export declare function nodeStorePathForAriaHome(ariaHome: string): string;
|
|
84
|
+
export declare class NodeStore {
|
|
85
|
+
readonly ariaHome: string;
|
|
86
|
+
readonly dbPath: string;
|
|
87
|
+
private readonly db;
|
|
88
|
+
private readonly ownerGeneration;
|
|
89
|
+
constructor(options: NodeStoreOptions);
|
|
90
|
+
/**
|
|
91
|
+
* Atomically claim the owner epoch. If the stored generation is already
|
|
92
|
+
* higher, another runtime has taken over — throw StaleOwnerError.
|
|
93
|
+
*/
|
|
94
|
+
private claimEpoch;
|
|
95
|
+
/**
|
|
96
|
+
* Assert that this store instance is still the current owner.
|
|
97
|
+
* Called inside every durable write method. Throws StaleOwnerError
|
|
98
|
+
* if a newer runtime has claimed the epoch since construction.
|
|
99
|
+
*
|
|
100
|
+
* Must be called inside the same SQLite transaction as the write.
|
|
101
|
+
*/
|
|
102
|
+
private assertOwnership;
|
|
103
|
+
close(): void;
|
|
104
|
+
readNodeMetadata(): NodeMetadata | null;
|
|
105
|
+
writeNodeMetadata(metadata: NodeMetadata): NodeMetadata;
|
|
106
|
+
readRuntimeOwnerRecord(nodeId: NodeId): RuntimeOwnerRecord | null;
|
|
107
|
+
readRuntimeBootstrapRecord(nodeId: NodeId): RuntimeBootstrapRecord | null;
|
|
108
|
+
writeRuntimeOwnerRecord(record: RuntimeOwnerRecord): RuntimeOwnerRecord;
|
|
109
|
+
writeRuntimeBootstrapRecord(record: RuntimeBootstrapRecord): RuntimeBootstrapRecord;
|
|
110
|
+
removeRuntimeOwnerRecord(nodeId: NodeId): void;
|
|
111
|
+
clearRuntimeOwnerRecords(): number;
|
|
112
|
+
clearRuntimeBootstrapRecords(): number;
|
|
113
|
+
resolveOrCreateNode(): NodeMetadata;
|
|
114
|
+
appendRuntimeEvent(input: RuntimeEventRecordInput): RuntimeEvent;
|
|
115
|
+
listRuntimeEvents(): RuntimeEvent[];
|
|
116
|
+
clearRuntimeEvents(): number;
|
|
117
|
+
commitRuntimeBootstrapRecord(record: RuntimeBootstrapRecord): RuntimeBootstrapRecord;
|
|
118
|
+
readPeerBinding(nodeId: NodeId): PeerBindingRecord | null;
|
|
119
|
+
listPeerBindings(): PeerBindingRecord[];
|
|
120
|
+
/**
|
|
121
|
+
* Get the current transport state for a peer.
|
|
122
|
+
* Returns 'unknown' if the peer doesn't exist (safe default).
|
|
123
|
+
*/
|
|
124
|
+
getPeerTransportState(nodeId: NodeId): string;
|
|
125
|
+
/**
|
|
126
|
+
* Set the transport state for a peer.
|
|
127
|
+
* Only valid for existing peer bindings.
|
|
128
|
+
*/
|
|
129
|
+
setPeerTransportState(nodeId: NodeId, transportState: "unknown" | "endpoint_known" | "connecting" | "connected" | "degraded" | "disconnected"): void;
|
|
130
|
+
commitPeerEndpointProjection(input: {
|
|
131
|
+
nodeId: NodeId;
|
|
132
|
+
endpointHost: string;
|
|
133
|
+
endpointPort: number;
|
|
134
|
+
endpointRevision: number;
|
|
135
|
+
updatedAt?: string;
|
|
136
|
+
}): PeerEndpointProjectionCommitResult;
|
|
137
|
+
commitPairContinuity(input: Omit<PeerBindingRecord, "updatedAt"> & {
|
|
138
|
+
updatedAt?: string;
|
|
139
|
+
}): PeerBindingRecord;
|
|
140
|
+
commitPairContinuityClearingRevocation(input: Omit<PeerBindingRecord, "updatedAt"> & {
|
|
141
|
+
updatedAt?: string;
|
|
142
|
+
expectedRevocationGeneration: number;
|
|
143
|
+
}): PeerBindingRecord;
|
|
144
|
+
readPeerRevocation(nodeId: NodeId): PeerRevocationRecord | null;
|
|
145
|
+
getPeerRevocationGeneration(nodeId: NodeId): number | null;
|
|
146
|
+
revoke(input: {
|
|
147
|
+
nodeId: NodeId;
|
|
148
|
+
displayNameSnapshot?: string;
|
|
149
|
+
fingerprint: PrincipalFingerprint;
|
|
150
|
+
revokedAt: number;
|
|
151
|
+
localNodeId: NodeId;
|
|
152
|
+
operatorConfirmation: RevocationOperatorConfirmation;
|
|
153
|
+
reason?: string;
|
|
154
|
+
revocationGeneration?: number;
|
|
155
|
+
}): void;
|
|
156
|
+
readRevocation(nodeId: NodeId): PeerRevocationRecord | null;
|
|
157
|
+
listRevocations(): PeerRevocationRecord[];
|
|
158
|
+
isPeerRevoked(nodeId: NodeId): boolean;
|
|
159
|
+
clearRevocationForNodeId(nodeId: NodeId, expectedGeneration?: number): boolean;
|
|
160
|
+
commitPeerRevocation(input: Omit<PeerRevocationRecord, "operatorConfirmation" | "revocationGeneration"> & {
|
|
161
|
+
operatorConfirmation?: RevocationOperatorConfirmation;
|
|
162
|
+
revocationGeneration?: number;
|
|
163
|
+
}): PeerRevocationRecord;
|
|
164
|
+
deletePeerBinding(nodeId: NodeId): boolean;
|
|
165
|
+
restorePeerBinding(nodeId: NodeId, snapshot: PeerBindingRecord | null): void;
|
|
166
|
+
readIngressReceipt(messageId: string): IngressReceiptRecord | null;
|
|
167
|
+
commitIngressReceipt(input: Omit<IngressReceiptRecord, "receivedAt"> & {
|
|
168
|
+
receivedAt?: string;
|
|
169
|
+
}): IngressReceiptCommitResult;
|
|
170
|
+
readOutboxReceipt(messageId: string): OutboxReceiptRecord | null;
|
|
171
|
+
commitOutboxReceipt(input: Omit<OutboxReceiptRecord, "updatedAt" | "deliveryLifecycleRevision"> & {
|
|
172
|
+
updatedAt?: string;
|
|
173
|
+
deliveryLifecycleRevision?: number;
|
|
174
|
+
}): OutboxReceiptRecord;
|
|
175
|
+
listRevocationConflicts(): RevocationConflictRecord[];
|
|
176
|
+
commitRevocationConflict(input: Omit<RevocationConflictRecord, "conflictId" | "recordedAt"> & {
|
|
177
|
+
conflictId?: string;
|
|
178
|
+
recordedAt?: string;
|
|
179
|
+
}): RevocationConflictRecord;
|
|
180
|
+
private ensureSchema;
|
|
181
|
+
}
|
|
182
|
+
export declare function resolveOrCreateNode(options: {
|
|
183
|
+
ariaHome: string;
|
|
184
|
+
}): Promise<import("./node-metadata.js").ResolvedNode>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ua as a,va as b,wa as c,xa as d,ya as e,za as f}from"../index-ghh3ag4c.js";import"../index-9xs3gn0p.js";export{f as resolveOrCreateNode,d as nodeStorePathForAriaHome,c as isEquivalentPeerBinding,a as StaleOwnerError,e as NodeStore,b as NODE_STORE_SCHEMA_VERSION};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type TlsCaFingerprint } from "@aria-cli/tools/network-runtime";
|
|
2
|
+
declare const PINNED_CONTROL_SESSION: unique symbol;
|
|
3
|
+
/**
|
|
4
|
+
* A control-plane session whose TLS CA fingerprint has been verified to match
|
|
5
|
+
* the expected fingerprint from a trusted source (invite token, stored binding,
|
|
6
|
+
* or local bootstrap).
|
|
7
|
+
*
|
|
8
|
+
* This type can ONLY be obtained by calling `createPinnedControlSession()` and
|
|
9
|
+
* receiving a non-error result. The unique-symbol brand makes it impossible
|
|
10
|
+
* to construct manually (outside this module).
|
|
11
|
+
*
|
|
12
|
+
* All mutating control-plane requests (pair, join, register, heartbeat, revoke)
|
|
13
|
+
* should require a `PinnedControlSession` instead of raw host:port, ensuring
|
|
14
|
+
* TLS pinning cannot be bypassed.
|
|
15
|
+
*/
|
|
16
|
+
export type PinnedControlSession = {
|
|
17
|
+
readonly [PINNED_CONTROL_SESSION]: true;
|
|
18
|
+
readonly host: string;
|
|
19
|
+
readonly port: number;
|
|
20
|
+
readonly pinnedCaFingerprint: TlsCaFingerprint;
|
|
21
|
+
readonly caCertPem: string;
|
|
22
|
+
};
|
|
23
|
+
export type PinnedControlSessionError = {
|
|
24
|
+
error: "ca_fingerprint_mismatch";
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Verify that the CA certificate's fingerprint matches the expected fingerprint,
|
|
28
|
+
* and return a branded `PinnedControlSession` on success.
|
|
29
|
+
*
|
|
30
|
+
* This is the ONLY function that can produce a `PinnedControlSession`.
|
|
31
|
+
* Control-plane request functions should require this brand, making it
|
|
32
|
+
* impossible to make mutating requests without first completing the
|
|
33
|
+
* TLS CA verification ceremony.
|
|
34
|
+
*/
|
|
35
|
+
export declare function createPinnedControlSession(input: {
|
|
36
|
+
host: string;
|
|
37
|
+
port: number;
|
|
38
|
+
expectedCaFingerprint: TlsCaFingerprint;
|
|
39
|
+
caCertPem: string;
|
|
40
|
+
}): PinnedControlSession | PinnedControlSessionError;
|
|
41
|
+
export {};
|