@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.
Files changed (88) hide show
  1. package/README.md +17 -0
  2. package/dist/.aria-build-stamp.json +4 -0
  3. package/dist/auth/api-key.d.ts +106 -0
  4. package/dist/config.d.ts +28 -0
  5. package/dist/daemon-launcher.d.ts +23 -0
  6. package/dist/daemon-launcher.js +3 -0
  7. package/dist/index-5tav2m70.js +3 -0
  8. package/dist/index-6extw9n6.js +2 -0
  9. package/dist/index-9n50yafd.js +3 -0
  10. package/dist/index-9xs3gn0p.js +2 -0
  11. package/dist/index-ghh3ag4c.js +548 -0
  12. package/dist/index-mnt9k223.js +15 -0
  13. package/dist/index-pe0pkp0v.js +2 -0
  14. package/dist/index-raeajnr7.js +2 -0
  15. package/dist/index-rr0sea4c.js +2 -0
  16. package/dist/index-zge0mhc0.js +3 -0
  17. package/dist/index.d.ts +11 -0
  18. package/dist/index.js +1 -0
  19. package/dist/peer-principal-auth.d.ts +37 -0
  20. package/dist/routes/arions.d.ts +34 -0
  21. package/dist/routes/council.d.ts +15 -0
  22. package/dist/routes/entrypoint-errors.d.ts +7 -0
  23. package/dist/routes/health.d.ts +6 -0
  24. package/dist/routes/invite-relay.d.ts +2 -0
  25. package/dist/routes/local-control.d.ts +3 -0
  26. package/dist/routes/message.d.ts +17 -0
  27. package/dist/routes/network.d.ts +14 -0
  28. package/dist/routes/pair.d.ts +57 -0
  29. package/dist/routes/pair.js +1 -0
  30. package/dist/routes/pipeline-mailbox.d.ts +10 -0
  31. package/dist/routes/relay.d.ts +29 -0
  32. package/dist/routes/resume.d.ts +2 -0
  33. package/dist/routes/run-control-surface.d.ts +24 -0
  34. package/dist/routes/run.d.ts +6 -0
  35. package/dist/routes/runtime-bootstrap.d.ts +3 -0
  36. package/dist/routes/runtime-node-advertisement.d.ts +3 -0
  37. package/dist/routes/runtime-run-room.d.ts +8 -0
  38. package/dist/routes/shared.d.ts +45 -0
  39. package/dist/routes/stream.d.ts +10 -0
  40. package/dist/routes/validation.d.ts +7 -0
  41. package/dist/routes/ws-revocation.d.ts +25 -0
  42. package/dist/runtime/attached-sender-inbox.d.ts +3 -0
  43. package/dist/runtime/authoritative-peer-endpoint.d.ts +27 -0
  44. package/dist/runtime/continuity-bind-suspicion.d.ts +39 -0
  45. package/dist/runtime/continuity-verification.d.ts +54 -0
  46. package/dist/runtime/decorate-runtime-surface.d.ts +2 -0
  47. package/dist/runtime/durable-network-store-surface.d.ts +51 -0
  48. package/dist/runtime/error-diagnostic.d.ts +12 -0
  49. package/dist/runtime/headless-dispatch-handler.d.ts +30 -0
  50. package/dist/runtime/host-supervisor.d.ts +109 -0
  51. package/dist/runtime/host-supervisor.js +1 -0
  52. package/dist/runtime/join-control.d.ts +3 -0
  53. package/dist/runtime/local-control-api.d.ts +63 -0
  54. package/dist/runtime/local-control-api.js +1 -0
  55. package/dist/runtime/local-control-pairing.d.ts +12 -0
  56. package/dist/runtime/local-control-socket.d.ts +48 -0
  57. package/dist/runtime/log-file-sink.d.ts +21 -0
  58. package/dist/runtime/network-read-control.d.ts +17 -0
  59. package/dist/runtime/network-state-stores.d.ts +2 -0
  60. package/dist/runtime/node-metadata.d.ts +22 -0
  61. package/dist/runtime/node-metadata.js +1 -0
  62. package/dist/runtime/node-runtime.d.ts +157 -0
  63. package/dist/runtime/node-store-revocation-store.d.ts +42 -0
  64. package/dist/runtime/node-store.d.ts +184 -0
  65. package/dist/runtime/node-store.js +1 -0
  66. package/dist/runtime/pinned-control-session.d.ts +41 -0
  67. package/dist/runtime/principal-binding-authority.d.ts +173 -0
  68. package/dist/runtime/reachable-control-host.d.ts +5 -0
  69. package/dist/runtime/runtime-admin-api.d.ts +16 -0
  70. package/dist/runtime/runtime-authority-registry.d.ts +55 -0
  71. package/dist/runtime/runtime-autonomous-loop.d.ts +40 -0
  72. package/dist/runtime/runtime-bootstrap-authority.d.ts +5 -0
  73. package/dist/runtime/runtime-bootstrap-record.d.ts +21 -0
  74. package/dist/runtime/runtime-event-journal.d.ts +21 -0
  75. package/dist/runtime/runtime-outbox.d.ts +35 -0
  76. package/dist/runtime/runtime-registry.d.ts +33 -0
  77. package/dist/runtime/runtime-registry.js +1 -0
  78. package/dist/runtime/runtime-run-control.d.ts +71 -0
  79. package/dist/runtime/stale-owner-error.d.ts +13 -0
  80. package/dist/runtime-run-control-0r21xdh5.js +2 -0
  81. package/dist/server.d.ts +84 -0
  82. package/dist/session-history-messages.d.ts +3 -0
  83. package/dist/session-history.d.ts +28 -0
  84. package/dist/shared-4jsvhy6g.js +1 -0
  85. package/dist/types.d.ts +299 -0
  86. package/dist/utils/rate-limiter.d.ts +25 -0
  87. package/dist/utils/sanitize-error.d.ts +10 -0
  88. package/package.json +82 -0
@@ -0,0 +1,173 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ import { type NodeId, type NodeMetadata, type PeerTransportId, type PrincipalFingerprint, type RuntimeBootstrapRecord, type TlsCaFingerprint } from "@aria-cli/tools/network-runtime";
3
+ import type { VerifiedContinuityBind } from "./continuity-verification.js";
4
+ import { type PeerBindingMutation, type PeerBindingRecord, type PeerRevocationRecord, type RevocationConflictRecord } from "./node-store.js";
5
+ declare const VERIFIED_INVITE_CLAIM: unique symbol;
6
+ type SharedSigningPublicKey = RuntimeBootstrapRecord["signingPublicKey"];
7
+ /**
8
+ * A verified invite claim whose signing key fingerprint has been
9
+ * cryptographically verified to match the claimed principal fingerprint.
10
+ *
11
+ * This type can ONLY be obtained by calling `verifyAndClaimInvite()` and
12
+ * receiving a non-error result. The unique-symbol brand makes it impossible
13
+ * to construct manually (outside this module).
14
+ */
15
+ export type VerifiedInviteClaim = {
16
+ readonly [VERIFIED_INVITE_CLAIM]: true;
17
+ readonly nodeId: NodeId;
18
+ readonly principalFingerprint: PrincipalFingerprint;
19
+ readonly signingPublicKey: SharedSigningPublicKey;
20
+ };
21
+ export type InviteClaimError = {
22
+ error: "signing_key_fingerprint_mismatch";
23
+ };
24
+ /**
25
+ * Verify that the signing key fingerprint matches the claimed principal
26
+ * fingerprint, and return a branded `VerifiedInviteClaim` on success.
27
+ *
28
+ * This is the ONLY function that can produce a `VerifiedInviteClaim`.
29
+ * `commitFirstTrustBind()` requires this brand, making it impossible to
30
+ * skip the verification ceremony.
31
+ */
32
+ export declare function verifyAndClaimInvite(input: {
33
+ nodeId: NodeId;
34
+ principalFingerprint: PrincipalFingerprint;
35
+ signingPublicKey: SharedSigningPublicKey;
36
+ }): VerifiedInviteClaim | InviteClaimError;
37
+ type PeerSigningKeyRecord = {
38
+ nodeId: NodeId;
39
+ displayNameSnapshot?: string;
40
+ signingPublicKey: SharedSigningPublicKey;
41
+ };
42
+ type PeerSigningKeyProjection = {
43
+ get?(nodeId: NodeId): SharedSigningPublicKey | undefined;
44
+ getRecord?(nodeId: NodeId): PeerSigningKeyRecord | null | undefined;
45
+ set?(input: {
46
+ nodeId: NodeId;
47
+ displayName: string;
48
+ signingPublicKey: SharedSigningPublicKey;
49
+ } | NodeId, signingPublicKey?: SharedSigningPublicKey, displayNameSnapshot?: string): NodeId;
50
+ };
51
+ type LocalPrincipalBindingProjection = () => {
52
+ nodeId: NodeId;
53
+ displayNameSnapshot?: string;
54
+ signingPublicKey: SharedSigningPublicKey;
55
+ transportPublicKey: PeerTransportId;
56
+ } | undefined;
57
+ export type ResolvedPrincipalBinding = Omit<PeerBindingRecord, "transportPublicKey"> & {
58
+ transportPublicKey: PeerTransportId;
59
+ signingPublicKey?: SharedSigningPublicKey;
60
+ isLocalBinding?: boolean;
61
+ };
62
+ export type VerifiedPrincipalBinding = ResolvedPrincipalBinding & {
63
+ signingPublicKey: SharedSigningPublicKey;
64
+ };
65
+ export type VerifiedAuthoritativePrincipal = {
66
+ nodeId: NodeId;
67
+ principalFingerprint: PrincipalFingerprint;
68
+ transportPublicKey: PeerTransportId;
69
+ signingPublicKey: SharedSigningPublicKey;
70
+ displayNameSnapshot?: string;
71
+ isLocalAuthority?: boolean;
72
+ };
73
+ export type PeerEndpointProjectionResult = {
74
+ kind: "not_found";
75
+ } | {
76
+ kind: "applied" | "idempotent" | "stale";
77
+ binding: ResolvedPrincipalBinding;
78
+ };
79
+ export type ContinuityBaseRecord = {
80
+ nodeId: NodeId;
81
+ principalFingerprint: PrincipalFingerprint;
82
+ continuityRevision: number;
83
+ revocationGeneration?: number;
84
+ displayNameSnapshot?: string;
85
+ binding?: ResolvedPrincipalBinding;
86
+ revokedPeer?: PeerRevocationRecord;
87
+ };
88
+ export declare function principalFingerprintFromSigningPublicKey(publicKeyBase64: SharedSigningPublicKey): PrincipalFingerprint | undefined;
89
+ export type BindingChangeEvent = {
90
+ nodeId: NodeId;
91
+ transportKeyChanged: boolean;
92
+ newTransportPublicKey: string;
93
+ previousTransportPublicKey?: string;
94
+ newPrincipalFingerprint: PrincipalFingerprint;
95
+ previousPrincipalFingerprint?: PrincipalFingerprint;
96
+ continuityRevision: number;
97
+ };
98
+ export declare class PrincipalBindingAuthority {
99
+ private readonly ariaHome;
100
+ private readonly ownerGeneration;
101
+ private readonly peerSigningKeyStore?;
102
+ /** Transport layer notification callback — set by runtime to receive key rotation events. */
103
+ onBindingChanged?: (event: BindingChangeEvent) => void;
104
+ private readonly localBindingProjection?;
105
+ constructor(options: {
106
+ ariaHome: string;
107
+ ownerGeneration?: number;
108
+ peerSigningKeyStore?: PeerSigningKeyProjection;
109
+ localBindingProjection?: LocalPrincipalBindingProjection;
110
+ });
111
+ private openStore;
112
+ private resolveWriteOwnerGeneration;
113
+ private openWritableStore;
114
+ resolveLocalNodeIdentity(): NodeMetadata;
115
+ private resolveLocalVerifiedPrincipal;
116
+ hasRemoteBindings(): boolean;
117
+ resolveRemoteBinding(nodeId: NodeId): ResolvedPrincipalBinding | undefined;
118
+ resolveContinuityBase(nodeId: NodeId): ContinuityBaseRecord | undefined;
119
+ resolveBindingByControlEndpoint(input: {
120
+ host: string;
121
+ port: number;
122
+ }): ResolvedPrincipalBinding | "ambiguous" | undefined;
123
+ listRemoteBindings(): ResolvedPrincipalBinding[];
124
+ listAuthoritativeBindings(): ResolvedPrincipalBinding[];
125
+ resolveLocalBinding(): VerifiedPrincipalBinding | undefined;
126
+ resolveBindingByPrincipalFingerprint(principalFingerprint: PrincipalFingerprint): VerifiedPrincipalBinding | "ambiguous" | undefined;
127
+ resolveVerifiedPrincipalByFingerprint(principalFingerprint: PrincipalFingerprint): VerifiedAuthoritativePrincipal | "ambiguous" | undefined;
128
+ resolveNodeIdFromVerifiedPrincipal(input: {
129
+ claimedNodeId?: NodeId;
130
+ signingPublicKey: SharedSigningPublicKey;
131
+ }): {
132
+ nodeId: NodeId;
133
+ principalFingerprint: PrincipalFingerprint;
134
+ displayNameSnapshot?: string;
135
+ } | undefined;
136
+ commitFirstTrustBind(claim: VerifiedInviteClaim, binding: Omit<PeerBindingMutation, "nodeId" | "principalFingerprint"> & {
137
+ endpointHost?: string;
138
+ endpointPort?: number;
139
+ endpointRevision?: number;
140
+ controlEndpointHost?: string;
141
+ controlEndpointPort?: number;
142
+ controlTlsCaFingerprint?: TlsCaFingerprint;
143
+ projectSigningKey?: boolean;
144
+ }): ResolvedPrincipalBinding;
145
+ private applyVerifiedContinuityMutation;
146
+ commitVerifiedContinuityBind(nodeId: NodeId, verified: VerifiedContinuityBind, projection?: Pick<PeerBindingMutation, "endpointHost" | "endpointPort" | "endpointRevision" | "displayNameSnapshot" | "transportPublicKey" | "controlEndpointHost" | "controlEndpointPort" | "controlTlsCaFingerprint"> & {
147
+ projectSigningKey?: boolean;
148
+ }): ResolvedPrincipalBinding;
149
+ recordRevocationConflict(input: Omit<RevocationConflictRecord, "conflictId" | "recordedAt"> & {
150
+ conflictId?: string;
151
+ recordedAt?: string;
152
+ }): RevocationConflictRecord;
153
+ recordVerifiedRevocation(input: {
154
+ nodeId: NodeId;
155
+ displayNameSnapshot?: string;
156
+ fingerprint: PrincipalFingerprint;
157
+ revokedAt: number;
158
+ revokedBy: NodeId;
159
+ operatorConfirmation?: import("@aria-cli/tools/network-runtime").RevocationOperatorConfirmation;
160
+ reason?: string;
161
+ revocationGeneration?: number;
162
+ }): PeerRevocationRecord;
163
+ commitPeerEndpointProjection(input: {
164
+ nodeId: NodeId;
165
+ endpointHost: string;
166
+ endpointPort: number;
167
+ endpointRevision: number;
168
+ }): PeerEndpointProjectionResult;
169
+ }
170
+ export declare function getPrincipalBindingAuthority(server: FastifyInstance, options?: {
171
+ ownerGeneration?: number;
172
+ }): PrincipalBindingAuthority | undefined;
173
+ export {};
@@ -0,0 +1,5 @@
1
+ export declare function selectReachableControlHost(params: {
2
+ ingressHost?: string;
3
+ peerHost?: string;
4
+ externalHost?: string;
5
+ }): string;
@@ -0,0 +1,16 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ import type { DirectPairRequest, DirectPairResponse, PairRequestDecision, PairRequestResponse, PendingPairRequestView, RevokePeerRequest, RevokePeerResponse } from "@aria-cli/tools";
3
+ export interface RuntimeAdminApi {
4
+ listPendingPairRequests(): Promise<PendingPairRequestView[]>;
5
+ respondToPairRequest(input: PairRequestDecision): Promise<PairRequestResponse>;
6
+ directPair(input: DirectPairRequest): Promise<DirectPairResponse>;
7
+ revokePeer(input: RevokePeerRequest): Promise<RevokePeerResponse>;
8
+ }
9
+ type RuntimeAdminServer = FastifyInstance & {
10
+ ariaPairControl?: FastifyInstance["ariaPairControl"];
11
+ ariaNetworkAdminControl?: FastifyInstance["ariaNetworkAdminControl"];
12
+ };
13
+ export declare function createRuntimeAdminApi(options: {
14
+ server: RuntimeAdminServer;
15
+ }): RuntimeAdminApi;
16
+ export {};
@@ -0,0 +1,55 @@
1
+ /**
2
+ * RuntimeAuthorityRegistry — the single source of truth for arion-scoped
3
+ * and global durable state in the daemon process.
4
+ *
5
+ * Design principle: arion is the shard key for arion-scoped durable state.
6
+ * Every durable store is resolved through this registry. No subsystem
7
+ * instance is created directly by projection code (CLI, headless kernel).
8
+ *
9
+ * Global stores:
10
+ * registry.config() → RunSessionConfig (one per ariaHome)
11
+ * registry.arions() → ArionManager (one per ariaHome)
12
+ *
13
+ * Arion-scoped stores:
14
+ * registry.memoria(arionName) → Memoria (one per arion, lazy)
15
+ * registry.sessionStore(arionName) → SessionHistory-like (one per arion, lazy)
16
+ */
17
+ import { ArionManager } from "@aria-cli/aria";
18
+ import type { MemoriaFactory } from "@aria-cli/aria";
19
+ import type { Memoria } from "@aria-cli/memoria";
20
+ import type { RunSessionConfig } from "@aria-cli/aria";
21
+ import type { RecoverySessionHistory } from "../server.js";
22
+ /**
23
+ * A session store that supports the recovery surface (getSession,
24
+ * getIncompleteSessions, markCompleted) and optionally supports full
25
+ * transcript persistence (replaceConversationMessages, addConversationMessage).
26
+ *
27
+ * When the CLI's SQLite SessionHistory is available, the full surface is present.
28
+ * When only the JSON recovery store is available, only the base surface exists.
29
+ */
30
+ export type ArionSessionStore = RecoverySessionHistory;
31
+ export interface RuntimeAuthorityRegistry {
32
+ /** Global: one config for the whole ariaHome. */
33
+ config(): RunSessionConfig;
34
+ /** Global: one ArionManager for the whole ariaHome. */
35
+ arions(): ArionManager;
36
+ /** Arion-scoped: one session store per arion (lazy, cached). */
37
+ sessionStore(arionName: string): ArionSessionStore | undefined;
38
+ /** Arion-scoped: one Memoria per arion (lazy, cached). */
39
+ memoria(arionName: string): Promise<Memoria>;
40
+ /** The underlying MemoriaFactory (for runner integration). */
41
+ memoriaFactory(): MemoriaFactory;
42
+ /** Shutdown: close all open stores. */
43
+ closeAll(): Promise<void>;
44
+ }
45
+ export interface RuntimeAuthorityRegistryOptions {
46
+ ariaHome: string;
47
+ memoriaFactory: MemoriaFactory;
48
+ /**
49
+ * Optional factory for creating per-arion SQLite session stores.
50
+ * When provided, `sessionStore(arionName)` returns a real SQLite-backed
51
+ * store. When absent, returns undefined (callers fall back to JSON recovery).
52
+ */
53
+ sessionStoreFactory?: (arionName: string) => ArionSessionStore | undefined;
54
+ }
55
+ export declare function createRuntimeAuthorityRegistry(options: RuntimeAuthorityRegistryOptions): RuntimeAuthorityRegistry;
@@ -0,0 +1,40 @@
1
+ import { type DaemonSafetyPolicy, type MemoriaFactory, type RunSessionConfig } 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 MCPServerConfig, type RuntimeAutonomousLoopStatus } from "@aria-cli/tools";
5
+ import type { NodeRuntimeControl } from "./node-runtime.js";
6
+ import type { NodeStore } from "./node-store.js";
7
+ export interface RuntimeAutonomousLoopOptions {
8
+ ariaHome: string;
9
+ arionName: string;
10
+ runtimeControl: Pick<NodeRuntimeControl, "runtimeId" | "nodeId" | "networkManager" | "registerMailbox" | "server" | "revocationStore" | "networkCoordinator">;
11
+ router: ModelRouter;
12
+ memoriaFactory: MemoriaFactory;
13
+ runSessionConfig: RunSessionConfig;
14
+ mcpServers?: MCPServerConfig[];
15
+ authResolver?: AuthResolver;
16
+ intervalMs?: number;
17
+ safetyPolicy?: DaemonSafetyPolicy;
18
+ signal?: AbortSignal;
19
+ nodeStore?: NodeStore;
20
+ }
21
+ export declare class RuntimeAutonomousLoop {
22
+ private readonly options;
23
+ private started;
24
+ private starting;
25
+ private stopController;
26
+ private bootstrapAbortController;
27
+ private startPromise;
28
+ private loopPromise;
29
+ private session;
30
+ private releaseMailbox;
31
+ private lastWakeTickAt;
32
+ private lastCheckpointResult;
33
+ /** Current wake trigger — called by incoming messages to interrupt the sleep. */
34
+ currentWakeTrigger: (() => void) | null;
35
+ constructor(options: RuntimeAutonomousLoopOptions);
36
+ private summarizeSafetyPolicy;
37
+ getStatusSummary(ownerClientKind: LocalControlClientKind | null): RuntimeAutonomousLoopStatus;
38
+ start(): Promise<void>;
39
+ stop(): Promise<void>;
40
+ }
@@ -0,0 +1,5 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ import { type PrincipalFingerprint, type RuntimeBootstrapRecord } from "@aria-cli/tools";
3
+ export declare function assertRuntimeBootstrapControlReady(bootstrap: RuntimeBootstrapRecord, context: string): RuntimeBootstrapRecord;
4
+ export declare function getLocalRuntimeBootstrapOrThrow(server: FastifyInstance, context: string): Promise<RuntimeBootstrapRecord>;
5
+ export declare function resolveRuntimeBootstrapPrincipalTlsIdentity(bootstrap: RuntimeBootstrapRecord, context?: string): PrincipalFingerprint;
@@ -0,0 +1,21 @@
1
+ import type { NetworkManagerRef, NodeId, RuntimeBootstrapPhase, RuntimeBootstrapRecord, RuntimeId, TlsCaFingerprint } from "@aria-cli/tools";
2
+ import { NodeStore } from "./node-store.js";
3
+ export declare function readRuntimeBootstrapRecordFromAriaHome(options: {
4
+ ariaHome: string;
5
+ nodeId: NodeId;
6
+ }): RuntimeBootstrapRecord | null;
7
+ export declare function nextRuntimeBootstrapOwnerGeneration(nodeStore: NodeStore, nodeId: NodeId): number;
8
+ export declare function nextRuntimeBootstrapRevision(nodeStore: NodeStore, nodeId: NodeId, _ownerGeneration: number): number;
9
+ export declare function publishRuntimeBootstrapRecord(options: {
10
+ nodeStore: NodeStore;
11
+ nodeId: NodeId;
12
+ runtimeId: RuntimeId;
13
+ ownerGeneration: number;
14
+ controlPort: number;
15
+ caFingerprint: TlsCaFingerprint;
16
+ caCertPem: string;
17
+ networkManager: NetworkManagerRef;
18
+ displayNameSnapshot?: string;
19
+ phase?: RuntimeBootstrapPhase;
20
+ controlHost?: string;
21
+ }): RuntimeBootstrapRecord;
@@ -0,0 +1,21 @@
1
+ import type { NodeId, RuntimeEvent, RuntimeEventKind, RuntimeId } from "@aria-cli/tools";
2
+ import { NodeStore } from "./node-store.js";
3
+ interface RuntimeEventJournalOptions {
4
+ ariaHome?: string;
5
+ nodeStore?: NodeStore;
6
+ }
7
+ interface RecordRuntimeEventInput {
8
+ nodeId: NodeId;
9
+ runtimeId: RuntimeId;
10
+ kind: RuntimeEventKind;
11
+ payload?: Record<string, unknown>;
12
+ }
13
+ export declare class RuntimeEventJournal {
14
+ private readonly nodeStore;
15
+ private readonly ownsNodeStore;
16
+ constructor(options: RuntimeEventJournalOptions);
17
+ close(): void;
18
+ record(input: RecordRuntimeEventInput): RuntimeEvent;
19
+ list(): RuntimeEvent[];
20
+ }
21
+ export {};
@@ -0,0 +1,35 @@
1
+ import type { DeliveryAck, MailboxRef, NodeId } from "@aria-cli/tools";
2
+ export interface RuntimeOutboxReceiptRecord {
3
+ messageId: string;
4
+ senderNodeId: NodeId;
5
+ recipientNodeId: NodeId;
6
+ transport: string;
7
+ status: "queued_for_route" | "dispatching" | "acked" | "expired";
8
+ deliveryLifecycleRevision: number;
9
+ updatedAt: string;
10
+ }
11
+ export interface RuntimeOutboxReceiptStore {
12
+ readOutboxReceipt(messageId: string): RuntimeOutboxReceiptRecord | null;
13
+ commitOutboxReceipt(input: Omit<RuntimeOutboxReceiptRecord, "updatedAt" | "deliveryLifecycleRevision"> & {
14
+ updatedAt?: string;
15
+ deliveryLifecycleRevision?: number;
16
+ }): RuntimeOutboxReceiptRecord;
17
+ }
18
+ export interface RuntimeOutbox extends Pick<MailboxRef, "sendBestEffort" | "sendDurable"> {
19
+ registerTunnel(nodeId: NodeId, transport: {
20
+ sendPlaintext(data: Buffer): void;
21
+ getState?: () => string;
22
+ isActive?: boolean;
23
+ routeBootstrapOnly?: boolean;
24
+ }): void;
25
+ unregisterTunnel(nodeId: NodeId): void;
26
+ handleDeliveryAck(ack: DeliveryAck): void;
27
+ }
28
+ export interface RuntimeOutboxOptions {
29
+ receiptStore?: RuntimeOutboxReceiptStore;
30
+ localNodeId?: NodeId;
31
+ signingKey?: string;
32
+ onReceiptCommitted?: (receipt: RuntimeOutboxReceiptRecord) => void;
33
+ faultCheckpoint?: (point: "runtime_death_during_durable_send", context: Record<string, unknown>) => void;
34
+ }
35
+ export declare function createRuntimeOutbox(options?: RuntimeOutboxOptions): RuntimeOutbox;
@@ -0,0 +1,33 @@
1
+ import { type NodeId, type RuntimeOwnerRecord } from "@aria-cli/tools";
2
+ export declare const RUNTIME_OWNER_RECORD_SCHEMA_VERSION = 1;
3
+ export type { RuntimeOwnerRecord } from "@aria-cli/tools";
4
+ export declare function resolveRuntimeRootDirectory(): string;
5
+ export declare function runtimeOwnerRecordsDirectory(runtimeRoot: string): string;
6
+ export declare function runtimeSocketsDirectory(runtimeRoot: string): string;
7
+ export declare function runtimeOwnerRecordPathForNodeId(runtimeRoot: string, nodeId: NodeId): string;
8
+ export declare function runtimeSocketPathForNodeId(runtimeRoot: string, nodeId: NodeId): string;
9
+ export declare function canonicalizeRuntimeSocketPath(socketPath: string): string;
10
+ export declare function ensureRuntimeRegistryLayout(runtimeRoot: string): void;
11
+ export declare function readRuntimeOwnerRecord(runtimeRoot: string, nodeId: NodeId): RuntimeOwnerRecord | null;
12
+ export declare function listRuntimeOwnerRecords(runtimeRoot: string): RuntimeOwnerRecord[];
13
+ export declare function writeRuntimeOwnerRecord(runtimeRoot: string, record: RuntimeOwnerRecord): RuntimeOwnerRecord;
14
+ export declare function removeRuntimeOwnerRecord(runtimeRoot: string, nodeId: NodeId): void;
15
+ /**
16
+ * Remove the Unix socket file for a given nodeId.
17
+ * Should be called alongside removeRuntimeOwnerRecord to prevent socket leaks.
18
+ */
19
+ export declare function removeRuntimeSocketForNodeId(runtimeRoot: string, nodeId: NodeId): void;
20
+ /**
21
+ * Garbage-collect orphaned runtime artifacts (sockets and owner records)
22
+ * whose owning process is no longer alive.
23
+ *
24
+ * Called on startup to reclaim resources leaked by hard crashes (SIGKILL,
25
+ * OOM, power loss) where shutdown hooks never ran.
26
+ *
27
+ * Returns the number of artifacts removed for observability.
28
+ */
29
+ export declare function pruneStaleRuntimeArtifacts(runtimeRoot: string): {
30
+ removedOwnerRecords: number;
31
+ removedSockets: number;
32
+ };
33
+ export declare function findRuntimeOwnerRecordByAriaHome(runtimeRoot: string, ariaHome: string): RuntimeOwnerRecord | null;
@@ -0,0 +1 @@
1
+ import{$ as k,R as a,S as b,T as c,U as d,V as e,W as f,X as g,Y as h,Z as i,_ as j,aa as l,ba as m,ca as n,da as o}from"../index-9n50yafd.js";import"../index-5tav2m70.js";import"../index-ghh3ag4c.js";import"../index-9xs3gn0p.js";export{k as writeRuntimeOwnerRecord,d as runtimeSocketsDirectory,f as runtimeSocketPathForNodeId,c as runtimeOwnerRecordsDirectory,e as runtimeOwnerRecordPathForNodeId,b as resolveRuntimeRootDirectory,m as removeRuntimeSocketForNodeId,l as removeRuntimeOwnerRecord,i as readRuntimeOwnerRecord,n as pruneStaleRuntimeArtifacts,j as listRuntimeOwnerRecords,o as findRuntimeOwnerRecordByAriaHome,h as ensureRuntimeRegistryLayout,g as canonicalizeRuntimeSocketPath,a as RUNTIME_OWNER_RECORD_SCHEMA_VERSION};
@@ -0,0 +1,71 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ import { type Message } from "@aria-cli/types";
3
+ import { type PipelineTimingReport, type RunStateData, type TokenUsage, type ToolCallRecord } from "@aria-cli/aria/server-runner";
4
+ import { type RunRequest, type RuntimeRunEvent } from "@aria-cli/tools";
5
+ import type { NativeToolMetadata, ThinkingBlock } from "@aria-cli/types";
6
+ import { type EntrypointRunPolicyInput } from "../routes/shared.js";
7
+ export interface RunRouteRequestBody extends EntrypointRunPolicyInput {
8
+ task: string;
9
+ arion?: string;
10
+ cwd?: string;
11
+ history?: unknown[];
12
+ requestedModel?: string;
13
+ preferredTier?: string;
14
+ }
15
+ export interface RunRouteResponse {
16
+ success: boolean;
17
+ output?: string;
18
+ messages?: Message[];
19
+ toolCalls?: ToolCallRecord[];
20
+ usage?: TokenUsage;
21
+ turnCount?: number;
22
+ thinking?: ThinkingBlock[];
23
+ nativeToolResults?: NativeToolMetadata[];
24
+ traces?: unknown[];
25
+ pipelineTiming?: PipelineTimingReport;
26
+ guardrailEvents?: unknown[];
27
+ handoffs?: unknown[];
28
+ state?: RunStateData;
29
+ error?: string;
30
+ reason?: string;
31
+ diagnostic?: Record<string, unknown>;
32
+ }
33
+ export interface ResumeRouteRequestBody extends EntrypointRunPolicyInput {
34
+ state: unknown;
35
+ arion?: string;
36
+ cwd?: string;
37
+ requestedModel?: string;
38
+ preferredTier?: string;
39
+ }
40
+ export type ResumeRouteResponse = RunRouteResponse;
41
+ export type NormalizedStreamRequest = Omit<RunRequest, "history"> & {
42
+ history?: Message[];
43
+ requestedModel?: string;
44
+ };
45
+ export interface AttachedClientExecutionContext {
46
+ clientId: string;
47
+ }
48
+ export type RunControlLogger = {
49
+ warn(obj: unknown, message: string): void;
50
+ error?: (...args: unknown[]) => void;
51
+ };
52
+ type StreamParseResult = {
53
+ request: NormalizedStreamRequest;
54
+ error?: never;
55
+ } | {
56
+ request?: never;
57
+ error: string;
58
+ };
59
+ export declare function parseStreamRequest(payload: unknown): StreamParseResult;
60
+ export declare function invalidStreamRequest(message: string): AsyncGenerator<RuntimeRunEvent, void, unknown>;
61
+ export declare function submitRunViaRuntimeControl(server: FastifyInstance, requestBody: RunRouteRequestBody, requestLog?: RunControlLogger, attachedClient?: AttachedClientExecutionContext): Promise<{
62
+ status: number;
63
+ body: RunRouteResponse;
64
+ }>;
65
+ export declare function resumeRunViaRuntimeControl(server: FastifyInstance, requestBody: ResumeRouteRequestBody, requestLog?: RunControlLogger, attachedClient?: AttachedClientExecutionContext): Promise<{
66
+ status: number;
67
+ body: ResumeRouteResponse;
68
+ }>;
69
+ export declare function streamRunViaRuntimeControl(server: FastifyInstance, parsed: NormalizedStreamRequest, requestLog?: RunControlLogger, signal?: AbortSignal, attachedClient?: AttachedClientExecutionContext): AsyncGenerator<RuntimeRunEvent, void, unknown>;
70
+ export declare function ensureRuntimeRunControl(server: FastifyInstance): void;
71
+ export {};
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Thrown when a runtime-owned durable store detects that a newer runtime
3
+ * has claimed ownership. The throwing runtime MUST shut down immediately.
4
+ *
5
+ * This error must NEVER be caught except in the runtime main loop shutdown
6
+ * handler. Any try/catch that swallows StaleOwnerError is an architectural bug.
7
+ */
8
+ export declare class StaleOwnerError extends Error {
9
+ readonly kind: "StaleOwnerError";
10
+ readonly claimedGeneration: number;
11
+ readonly currentGeneration: number;
12
+ constructor(claimed: number, current: number);
13
+ }
@@ -0,0 +1,2 @@
1
+ import{a as C,b as l,g as d,h as _f,i as o,j as t}from"./index-zge0mhc0.js";import{D as n,G as v,H as i,I as Of,J as A,M as Tf}from"./index-pe0pkp0v.js";import{ta as Df}from"./index-raeajnr7.js";import"./index-9xs3gn0p.js";import{createRunPipeline as a}from"@aria-cli/aria/server-runner";import{ClientIdSchema as Zf,RunRequestSchema as zf,toNetworkControlRef as Ff}from"@aria-cli/tools";import{canonicalizeDeliveryReceipt as Gf}from"@aria-cli/tools";function ff(R,f){let T=R[f];if(typeof T!=="function")throw Error(`Runtime outbox ${f} not available`);return T.bind(R)}function Rf(R){if(!R)return;let{transport:f,...T}=R;return{...Gf({transport:f==="local_runtime"?"in_process":f,...T})}}function Wf(R){let f=R;return{rawMessage:f,...f.recipientInbox?{recipientInbox:f.recipientInbox}:{},...f.recipientInbox?.kind!=="client"&&typeof f.recipient?.id==="string"?{to:f.recipient.id}:{}}}function m(R,f){let{ariaRuntimeMessageControl:T,ariaRuntimeOutbox:x}=R,O=f?.mailbox,_=typeof f?.bindRelayTransport==="function"?f.bindRelayTransport.bind(f):O&&typeof O.setRelayTransport==="function"?O.setRelayTransport.bind(O):void 0;if(!T&&!x||!_)return()=>{};return _((S,D)=>{if(T){let J=Wf(S);return(D==="best_effort"?T.sendBestEffort(J):T.sendDurable(J)).then((F)=>Rf(F))}try{return(D==="best_effort"?ff(x,"sendBestEffort")(S):ff(x,"sendDurable")(S)).then((F)=>Rf(F))}catch(J){return Promise.reject(J)}}),()=>{}}import{getErrorMessage as xf,getErrorStatusCode as $f}from"@aria-cli/types";var jf=new Set(["ARION_NOT_FOUND","ARION_RESTING","ARION_RETIRED"]);function Jf(R,f=500){let T=$f(R);if(typeof T==="number")return T;if(R&&typeof R==="object"){let O=R.code;if(typeof O==="string"&&jf.has(O))return 400}let x=xf(R).toLowerCase();if(x.includes("not found")||x.includes("resting")||x.includes("retired"))return 400;return f}function q(R,f,T=500){let x=Jf(R,T);return{status:x,message:x<500?xf(R):Of(R,f)}}import{ArionManager as Kf,Room as Qf,deepConsolidation as Xf,parseMentions as Yf}from"@aria-cli/aria/server-arions";async function g(R){let{ariaMemoriaFactory:f,ariaRouter:T}=R,x=new Qf({onRest:(_)=>{let S=performance.now();console.warn(`[room.onRest] START deepConsolidation for arion="${_.name}"`),(async()=>{try{let D=Kf.resolveMemoriaPath(_,_.name),J=await f.get(D);if(await Xf(T,J,_),O)await O.save(_)}catch(D){console.warn(`[room.onRest] deepConsolidation FAILED for "${_.name}":`,D?.message)}finally{console.warn(`[room.onRest] END deepConsolidation for "${_.name}" — ${((performance.now()-S)/1000).toFixed(1)}s`)}})()}}),O=null;try{O=await Tf(f,T)}catch{O=null}return{room:x,manager:O}}async function p(R,f,T){if(!R)return;let x=Yf(T);for(let O of x){if(A(O))continue;try{let _=await R.get(O);if(_?.status==="resting")await R.wake(O),_=await R.get(O);if(_?.status==="active"&&!f.isInRoom(O))f.enter(_)}catch{}}}function s(R){let f=R.ariaSessionHistory;if(!f)return;let T=f;if(typeof T.listSessions==="function"&&typeof T.searchSessionsFts==="function")return f;return}function bf(R,f){let T=R.filter((x)=>{if(!x||typeof x!=="object")return!1;let O=x;return typeof O.id==="string"&&typeof O.name==="string"&&typeof O.durationMs==="number"&&!!O.result&&typeof O.result==="object"});if(T.length===0)return f?[...f]:[];return T.map((x)=>({...x,result:x.result}))}function Ef(R){let f=R[0];if(!f)return"Invalid request";let T=f.path.join(".");if(T==="task")return"task is required";return T&&T.length>0?`${T}: ${f.message}`:f.message}function Vf(R,f){return f!==void 0||R===void 0}function Nf(R,f){return{message:q(R,f).message,diagnostic:n(R)}}function u(R,f,T,x=500){let O=f?.error?{error:(...D)=>f.error?.(...D)}:void 0,{message:_,status:S}=q(R,O,x);return{status:S,body:{success:!1,error:_,...Vf(f,T)?{diagnostic:n(R)}:{}}}}function Sf(R,f,T){let x;try{x=R.observabilityContext?.snapshot()}catch(D){T?.warn({err:D},"Observability snapshot failed"),x=void 0}let _=bf(x?.toolCalls??[],f.toolCalls??[]).map((D)=>({...D,result:{...D.result,..._f(D.name,D.input,D.result)}})),S=f.nativeToolResults&&f.nativeToolResults.length>0?f.nativeToolResults:void 0;return{success:!0,output:f.content,messages:f.messages,toolCalls:_,usage:x?.usage??f.usage,turnCount:x?.turnCount??f.turnCount,thinking:x?.thinkingBlocks?.length?x.thinkingBlocks:void 0,nativeToolResults:S,traces:x?.spans?.length?x.spans:void 0,pipelineTiming:x?.pipelineTiming&&x.pipelineTiming.phases.length>0?x.pipelineTiming:void 0,guardrailEvents:x?.guardrailEvents?.length?x.guardrailEvents:void 0,handoffs:x?.handoffs?.length?x.handoffs:void 0}}function r(R,f){let T=Ff(R.ariaNetworkManager);if(!f?.clientId||!R.ariaAttachedClientControl?.listAttachedClients)return T;let x=()=>R.ariaAttachedClientControl.listAttachedClients({clientId:f.clientId});if(T)return{...T,listAttachedClients:x};return{invite(){throw Error("Network manager not available. Secure networking requires the @aria/wireguard package.")},revokePeer(){throw Error("Network manager not available. Secure networking requires the @aria/wireguard package.")},listPeers(){return[]},status(){return{configured:!1,nodeId:R.ariaNodeId??null,principalFingerprint:null,transportPublicKey:null,listenPort:null,externalEndpoint:null,activePeers:0,totalPeers:0,signingPublicKey:null}},listAttachedClients:x}}function e(R){if(!R)return;return{kind:"client",clientId:Zf.parse(R.clientId)}}async function wf(R,f){if(!f||!R.ariaRuntimeLocalControl?.getRuntimeStatus)return!1;try{return(await R.ariaRuntimeLocalControl.getRuntimeStatus()).autonomousLoop.ownerClientKind==="local-api"}catch{return!1}}function Uf(R){let f=zf.safeParse(R);if(!f.success)return{error:Ef(f.error.issues)};let{history:T,...x}=f.data,O=o(f.data.history);return{request:O?{...x,history:O}:x}}async function*If(R){yield{type:"error",error:{message:R}}}function Pf(R,f){let T=f?.error?{error:(...x)=>f.error?.(...x)}:void 0;switch(R.type){case"error":return{type:"error",error:Nf(R.error,T)};case"text_delta":case"tool_start":case"approval_needed":case"tool_result":case"usage_update":case"turn_complete":case"guardrail_rejected":case"pipeline_timing":case"messages_snapshot":case"native_tool_result":case"thinking_start":case"thinking_delta":case"thinking_end":case"tool_args_delta":case"span_start":case"span_end":case"handoff_start":case"handoff_result":case"paused":return R;default:return null}}async function Hf(R,f,T,x){let{task:O,arion:_}=f,S=e(x),D=T?.error?{error:(...N)=>T.error?.(...N)}:void 0;if(_&&A(_))return{status:400,body:{success:!1,error:`Invalid arion name: "${_}"`}};try{await R.ariaRecoverCrashedSessions?.()}catch(N){T?.warn({err:N},"Per-request crash recovery failed")}let J=v(),F=typeof f.cwd==="string"&&f.cwd.trim().length>0?f.cwd:process.cwd(),c=i(F),{approvalMode:y="pause",askUserAnswers:P=[],history:B,budget:z,maxTurns:h,autonomy:E,allowedTools:W,deniedTools:w,noMemory:H,systemPrompt:L}=f,X=o(B),{ariaMemoriaFactory:k,ariaRouter:K,ariaBasePath:Q,ariaAuthResolver:M}=R,{room:$,manager:b}=await g(R),j;try{await p(b,$,O),j=await a({task:O,arionName:_||void 0,config:{...J,...f.requestedModel?{requestedModel:f.requestedModel}:{},...f.preferredTier?{preferredTier:f.preferredTier}:{}},storagePath:Q,...f.requestedModel?{requestedModel:f.requestedModel}:{},router:K,memoriaFactory:k,mcpServers:c,room:$,...X?{history:X}:{},...H?{skipMemoria:!0}:{},sessionHistory:s(R),authResolver:M??void 0,networkControl:r(R,x),networkManager:R.ariaNetworkManager,runtimeId:R.ariaRuntimeId??void 0,nodeId:R.ariaNodeId??void 0,...S?{runtimeIngressAuthority:{localInboxAddress:S}}:{},runOptionsOverrides:t({workingDir:F,approvalMode:y,askUserAnswers:P,budget:z,maxTurns:h,autonomy:E,allowedTools:W,deniedTools:w,noMemory:H,systemPrompt:L,...S?{inboxAddress:S}:{}})})}catch(N){return $.clear().catch(()=>{}),u(N,T,x)}let V=R.ariaSessionHistory,Y=j.session?.sessionId,U=j.session?.arion?.name??_??J.activeArion;if(Y)V?.upsertSession?.(Y,l(O),{arionName:U});let G=m(R,j.session);try{let N=await j.run(),I=(N.state?.pendingToolCalls?.length??0)>0,Z=C(N.state?.messages??N.messages??[]);if(Y){if(Z.length>0)V?.upsertSession?.(Y,Z,{completed:!I,arionName:U});else if(!I)V?.markCompleted(Y)}if(I)return{status:409,body:{success:!1,error:"Run paused: pending tool calls require approval before resume",state:N.state}};return{status:200,body:Sf(j,N,T)}}catch(N){return u(N,T,x,d(N)?400:500)}finally{G(),$.clear().catch(()=>{})}}async function kf(R,f,T,x){let{arion:O,approvalMode:_="pause",askUserAnswers:S=[],budget:D,maxTurns:J,autonomy:F,allowedTools:c,deniedTools:y,noMemory:P,systemPrompt:B}=f,z=e(x),h=T?.error?{error:(...G)=>T.error?.(...G)}:void 0,E=f.state;if(O&&A(O))return{status:400,body:{success:!1,error:`Invalid arion name: "${O}"`}};try{await R.ariaRecoverCrashedSessions?.()}catch(G){T?.warn({err:G},"Per-request crash recovery failed")}let W=v(),w=typeof f.cwd==="string"&&f.cwd.trim().length>0?f.cwd:process.cwd(),H=i(w),{ariaMemoriaFactory:L,ariaRouter:X,ariaBasePath:k,ariaAuthResolver:K}=R,{room:Q,manager:M}=await g(R),$;try{await p(M,Q,E.input),$=await a({task:E.input,arionName:O||void 0,config:{...W,...f.requestedModel?{requestedModel:f.requestedModel}:{},...f.preferredTier?{preferredTier:f.preferredTier}:{}},storagePath:k,...f.requestedModel?{requestedModel:f.requestedModel}:{},router:X,memoriaFactory:L,mcpServers:H,room:Q,...P?{skipMemoria:!0}:{},sessionHistory:s(R),authResolver:K??void 0,networkControl:r(R,x),networkManager:R.ariaNetworkManager,runtimeId:R.ariaRuntimeId??void 0,nodeId:R.ariaNodeId??void 0,...z?{runtimeIngressAuthority:{localInboxAddress:z}}:{},runOptionsOverrides:t({workingDir:w,approvalMode:_,askUserAnswers:S,budget:D,maxTurns:J,autonomy:F,allowedTools:c,deniedTools:y,noMemory:P,systemPrompt:B,...z?{inboxAddress:z}:{}})})}catch(G){return Q.clear().catch(()=>{}),u(G,T,x)}let b=R.ariaSessionHistory,j=$.session?.sessionId,V=$.session?.arion?.name??O??W.activeArion,Y=C(E.messages??[]),U=m(R,$.session);if(j)b?.upsertSession?.(j,Y.length>0?Y:l(E.input),{arionName:V});try{let G=await $.resume(E),N=(G.state?.pendingToolCalls?.length??0)>0,I=G.state?.messages??G.messages??[],Z=C(I);if(j){if(Z.length>0)b?.upsertSession?.(j,Z,{completed:!N,arionName:V});else if(!N)b?.markCompleted(j)}if(N)return{status:409,body:{success:!1,error:"Run paused: pending tool calls require approval before resume",state:G.state}};return{status:200,body:Sf($,G,T)}}catch(G){return u(G,T,x,d(G)?400:500)}finally{U(),Q.clear().catch(()=>{})}}async function*Mf(R,f,T,x,O){let _=e(O),S=T?.error?{error:(...W)=>T.error?.(...W)}:void 0;if(f.arion&&A(f.arion)){yield{type:"error",error:{message:`Invalid arion name: "${f.arion}"`}};return}try{await R.ariaRecoverCrashedSessions?.()}catch(W){T?.warn({err:W},"Per-request crash recovery failed")}let D=v(),J=typeof f.cwd==="string"&&f.cwd.trim().length>0?f.cwd:process.cwd(),F=i(J),{ariaMemoriaFactory:c,ariaRouter:y,ariaBasePath:P,ariaAuthResolver:B}=R,{room:z,manager:h}=await g(R),E=await wf(R,O);try{await p(h,z,f.task);let W=new AbortController,w=()=>W.abort();x?.addEventListener("abort",w,{once:!0});let H=f.approvalMode||"pause",L=f.askUserAnswers||[],X;try{X=await a({task:f.task,arionName:f.arion||void 0,config:{...D,...f.requestedModel?{requestedModel:f.requestedModel}:{},...f.preferredTier?{preferredTier:f.preferredTier}:{}},storagePath:P,...f.requestedModel?{requestedModel:f.requestedModel}:{},router:y,memoriaFactory:c,abortSignal:W.signal,mcpServers:F,room:z,...f.history?{history:f.history}:{},...f.noMemory?{skipMemoria:!0}:{},sessionHistory:s(R),authResolver:B??void 0,networkControl:r(R,O),networkManager:R.ariaNetworkManager,runtimeId:R.ariaRuntimeId??void 0,nodeId:R.ariaNodeId??void 0,..._?{runtimeIngressAuthority:{localInboxAddress:_}}:{},runOptionsOverrides:t({workingDir:J,approvalMode:H,askUserAnswers:L,budget:f.budget,maxTurns:f.maxTurns,autonomy:f.autonomy,allowedTools:f.allowedTools,deniedTools:f.deniedTools,noMemory:f.noMemory,systemPrompt:f.systemPrompt,..._?{inboxAddress:_}:{}})})}catch(K){x?.removeEventListener("abort",w),yield{type:"error",error:Nf(K,S)};return}let k=()=>{};try{k=m(R,X.session);let K=R.ariaSessionHistory,Q=X.session?.sessionId,M=X.session?.arion?.name??f.arion??D.activeArion;if(Q)K?.upsertSession?.(Q,l(f.task),{arionName:M});let $=!1,b=!1,j=[];for await(let I of X.execute()){let Z=Pf(I,T);if(!Z)continue;if(Z.type==="messages_snapshot")j=Z.messages;if(Z.type==="error")$=!0;if(Z.type==="paused")b=!0;if(yield Z,$||b)break}let V=performance.now(),Y=C(j),U=performance.now();if(Q){if(Y.length>0)K?.upsertSession?.(Q,Y,{completed:!$&&!b&&!W.signal.aborted,arionName:M});else if(!$&&!b&&!W.signal.aborted)K?.markCompleted(Q)}let G=performance.now(),N=G-V;if(N>100)try{process.stderr.write(`[streamRun][DIAG] postLoop: total=${N.toFixed(0)}ms normalize=${(U-V).toFixed(0)}ms upsert=${(G-U).toFixed(0)}ms msgs=${j.length} recovery=${Y.length}
2
+ `)}catch{}}catch(K){yield{type:"error",error:{message:d(K)?K.message??"ask_user requested more answers than provided.":q(K,S).message,diagnostic:n(K)}}}finally{if(k(),x?.removeEventListener("abort",w),E&&X)W.abort(),X.close().catch(()=>{})}}finally{let W=performance.now();console.warn(`[streamRun.finally] room.clear() START (${z.getActive().length} arions)`),z.clear().catch(()=>{}).finally(()=>{console.warn(`[streamRun.finally] room.clear() END — ${((performance.now()-W)/1000).toFixed(1)}s`)})}}function fR(R){let f=R.ariaRunControl;Df(R,"ariaRunControl",{...f,submitRun:async(T,x)=>{let O=await Hf(R,T,void 0,x);return{success:O.body.success,...typeof O.body.output==="string"?{output:O.body.output}:{},...O.body.messages?{messages:O.body.messages}:{},...O.body.toolCalls?{toolCalls:O.body.toolCalls}:{},...O.body.usage?{usage:O.body.usage}:{},...typeof O.body.turnCount==="number"?{turnCount:O.body.turnCount}:{},...O.body.state?{state:O.body.state}:{},...typeof O.body.error==="string"?{error:O.body.error}:{},...O.body.diagnostic?{diagnostic:O.body.diagnostic}:{}}},resumeRun:async(T,x)=>{let O=await kf(R,T,void 0,x);return{...O.body,...O.body.diagnostic?{diagnostic:O.body.diagnostic}:{}}},streamRun:(T,x,O)=>{let _=Uf(T);return _.request?Mf(R,_.request,void 0,x,O):If(_.error)}})}export{Hf as submitRunViaRuntimeControl,Mf as streamRunViaRuntimeControl,kf as resumeRunViaRuntimeControl,Uf as parseStreamRequest,If as invalidStreamRequest,fR as ensureRuntimeRunControl};
@@ -0,0 +1,84 @@
1
+ import Fastify from "fastify";
2
+ import type { MemoriaFactory } from "@aria-cli/aria/server-arions";
3
+ import { type ModelRouter } from "@aria-cli/aria/server-models";
4
+ import { type NodeId, type RuntimeId } from "@aria-cli/tools";
5
+ import { type ServerSessionHistory } from "./session-history.js";
6
+ import { type AttachedLocalHttpClientAuthority } from "./runtime/local-control-socket.js";
7
+ import "./types.js";
8
+ /**
9
+ * Check whether an origin is a localhost address.
10
+ * Uses URL parsing to prevent bypasses like "http://localhost.evil.com".
11
+ */
12
+ export declare function isLocalhostOrigin(origin: string): boolean;
13
+ /**
14
+ * Strip api_key query parameter values from URLs to prevent secret leakage in logs.
15
+ */
16
+ export declare function redactApiKey(url: string | undefined): string | undefined;
17
+ type RecoverySessionHistory = Omit<ServerSessionHistory, "upsertSession"> & {
18
+ upsertSession?: ServerSessionHistory["upsertSession"];
19
+ };
20
+ /**
21
+ * Configuration options for the Aria server
22
+ */
23
+ export interface ServerConfig {
24
+ /** Port to listen on (default: 3000) */
25
+ port?: number;
26
+ /**
27
+ * Host to bind to (default: '127.0.0.1').
28
+ *
29
+ * In mesh mode, set to '0.0.0.0' to accept connections from WireGuard peers.
30
+ * Note: WireGuard operates at the UDP/IP layer — HTTPS traffic flows over the
31
+ * regular network stack, with WireGuard providing encryption transparently.
32
+ * The server does NOT need to bind to a tunnel interface IP. Instead, security
33
+ * is enforced via message signature verification (Ed25519 signing in Mailbox)
34
+ * and route-level cryptographic identity checks.
35
+ */
36
+ host?: string;
37
+ /** Injected MemoriaFactory (for testing; production creates its own) */
38
+ memoriaFactory?: MemoriaFactory;
39
+ /** Injected router (for testing; production creates its own) */
40
+ router?: ModelRouter;
41
+ /** Base path override (for testing; defaults to ~/.aria) */
42
+ basePath?: string;
43
+ /** Recover incomplete sessions on startup (defaults to true outside tests). */
44
+ enableCrashRecovery?: boolean;
45
+ /** Session history source for startup crash recovery (optional). */
46
+ crashRecoverySessionHistory?: RecoverySessionHistory;
47
+ /** Auth resolver for resolving API keys (passed to RunSession for modelOverride). */
48
+ authResolver?: import("@aria-cli/auth").AuthResolver;
49
+ /** Optional NetworkManager for WireGuard peer join/signing-key wiring */
50
+ networkManager?: import("@aria-cli/tools").NetworkManagerRef;
51
+ /** Canonical runtime identity for daemon-backed sends. */
52
+ runtimeId?: RuntimeId;
53
+ /** Durable node identity for runtime-owned local control routes. */
54
+ nodeId?: NodeId;
55
+ /** Single-writer generation for durable runtime-owned identity mutations. */
56
+ ownerGeneration?: number;
57
+ /** TLS certificate and key for HTTPS. When provided, server uses HTTPS. */
58
+ tls?: {
59
+ cert: string;
60
+ key: string;
61
+ };
62
+ /** Suppress Fastify request/response logs (for embedded servers in TUI mode) */
63
+ silent?: boolean;
64
+ /** Active arion whose Memoria should back the server message-store surface. */
65
+ arionName?: string;
66
+ /** Optional attached-local HTTP auth authority for test/runtime embedding. */
67
+ attachedLocalHttpClientAuthority?: AttachedLocalHttpClientAuthority;
68
+ }
69
+ /**
70
+ * Result of createServer containing the Fastify instance and configured listen method
71
+ */
72
+ export interface ServerInstance {
73
+ /** The underlying Fastify server instance */
74
+ server: ReturnType<typeof Fastify>;
75
+ /** Start listening on the configured port and host */
76
+ listen: () => Promise<string>;
77
+ }
78
+ /**
79
+ * Creates and configures a Fastify server instance
80
+ * @param config - Server configuration options
81
+ * @returns ServerInstance with configured server and listen method
82
+ */
83
+ export declare function createServer(config?: ServerConfig): Promise<ServerInstance>;
84
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { RecoverySessionMessage } from "./session-history.js";
2
+ export declare function normalizeRecoveryMessages(messages: ReadonlyArray<unknown>): RecoverySessionMessage[];
3
+ export declare function buildInitialRecoveryMessages(task: string): RecoverySessionMessage[];