@roamcode.ai/server 1.4.5 → 2.0.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/dist/index.d.ts +23 -2103
- package/dist/index.js +859 -9442
- package/dist/start.d.ts +105 -217
- package/dist/start.js +675 -6367
- package/package.json +3 -4
- package/dist/container/relay.js +0 -2742
- package/dist/relay-start.d.ts +0 -134
- package/dist/relay-start.js +0 -2737
package/dist/start.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { FastifyInstance } from 'fastify';
|
|
2
|
-
import { z } from 'zod';
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* Wiring for the mcp-send server (Claude → user attachments). When present, the spawn layer writes a
|
|
@@ -361,143 +360,14 @@ interface SessionStore {
|
|
|
361
360
|
readonly mode: StoreMode;
|
|
362
361
|
}
|
|
363
362
|
|
|
364
|
-
type DeviceScope = "direct"
|
|
363
|
+
type DeviceScope = "direct";
|
|
365
364
|
interface PairingTicket {
|
|
366
365
|
/** One-time capability carried by the pairing URL. Never persisted in plaintext. */
|
|
367
366
|
secret: string;
|
|
368
367
|
expiresAt: number;
|
|
369
|
-
/** Exact product surfaces the resulting device credential can reach. */
|
|
370
368
|
scopes: DeviceScope[];
|
|
371
369
|
}
|
|
372
370
|
|
|
373
|
-
declare const CloudAutomationWebhookRegistrationSchema: z.ZodObject<{
|
|
374
|
-
hookId: z.ZodString;
|
|
375
|
-
automationId: z.ZodString;
|
|
376
|
-
triggerId: z.ZodString;
|
|
377
|
-
secretHash: z.ZodString;
|
|
378
|
-
enabled: z.ZodBoolean;
|
|
379
|
-
}, z.core.$strict>;
|
|
380
|
-
declare const CloudAutomationInvocationSchema: z.ZodObject<{
|
|
381
|
-
id: z.ZodUUID;
|
|
382
|
-
automationId: z.ZodString;
|
|
383
|
-
triggerId: z.ZodString;
|
|
384
|
-
hookId: z.ZodString;
|
|
385
|
-
createdAt: z.ZodNumber;
|
|
386
|
-
}, z.core.$strict>;
|
|
387
|
-
type CloudAutomationWebhookRegistration = z.infer<typeof CloudAutomationWebhookRegistrationSchema>;
|
|
388
|
-
type CloudAutomationInvocation = z.infer<typeof CloudAutomationInvocationSchema>;
|
|
389
|
-
|
|
390
|
-
type TeamStoreMode = "sqlite" | "memory-fallback";
|
|
391
|
-
type TeamMemberKind = "person" | "service";
|
|
392
|
-
type TeamMemberStatus = "active" | "suspended" | "removed";
|
|
393
|
-
type TeamRole = "viewer" | "operator" | "node-admin" | "workspace-manager" | "extension-manager" | "policy-admin" | "organization-admin";
|
|
394
|
-
type TeamScopeType = "team" | "host" | "workspace";
|
|
395
|
-
type TeamPrincipalType = "device" | "host" | "local" | "relay";
|
|
396
|
-
type TeamPermission = "team:read" | "sessions:read" | "sessions:operate" | "attention:read" | "attention:manage" | "presence:read" | "presence:write" | "workspaces:manage" | "extensions:manage" | "policy:manage" | "members:manage" | "node-access:manage" | "audit:read" | "fleet:read";
|
|
397
|
-
interface TeamRecord {
|
|
398
|
-
id: string;
|
|
399
|
-
name: string;
|
|
400
|
-
authorizationEnabled: boolean;
|
|
401
|
-
revision: number;
|
|
402
|
-
createdAt: number;
|
|
403
|
-
updatedAt: number;
|
|
404
|
-
}
|
|
405
|
-
interface TeamMember {
|
|
406
|
-
id: string;
|
|
407
|
-
displayName: string;
|
|
408
|
-
kind: TeamMemberKind;
|
|
409
|
-
status: TeamMemberStatus;
|
|
410
|
-
revision: number;
|
|
411
|
-
createdAt: number;
|
|
412
|
-
updatedAt: number;
|
|
413
|
-
}
|
|
414
|
-
interface TeamRoleBinding {
|
|
415
|
-
id: string;
|
|
416
|
-
memberId: string;
|
|
417
|
-
role: TeamRole;
|
|
418
|
-
scopeType: TeamScopeType;
|
|
419
|
-
scopeId?: string;
|
|
420
|
-
createdAt: number;
|
|
421
|
-
}
|
|
422
|
-
interface TeamPrincipalBinding {
|
|
423
|
-
actorType: TeamPrincipalType;
|
|
424
|
-
actorId: string;
|
|
425
|
-
memberId: string;
|
|
426
|
-
createdAt: number;
|
|
427
|
-
}
|
|
428
|
-
interface TeamAuthorizationResource {
|
|
429
|
-
hostId?: string;
|
|
430
|
-
workspaceId?: string;
|
|
431
|
-
}
|
|
432
|
-
interface TeamAuthorizationDecision {
|
|
433
|
-
allowed: boolean;
|
|
434
|
-
reason: "local-break-glass" | "not-enforced" | "unbound" | "inactive" | "role" | "missing-permission";
|
|
435
|
-
member?: TeamMember;
|
|
436
|
-
roles: TeamRole[];
|
|
437
|
-
}
|
|
438
|
-
interface TeamStore {
|
|
439
|
-
readonly mode: TeamStoreMode;
|
|
440
|
-
getTeam(): TeamRecord | null;
|
|
441
|
-
createTeam(input: {
|
|
442
|
-
name: string;
|
|
443
|
-
ownerName: string;
|
|
444
|
-
ownerPrincipal: {
|
|
445
|
-
actorType: TeamPrincipalType;
|
|
446
|
-
actorId: string;
|
|
447
|
-
};
|
|
448
|
-
}, now?: number): {
|
|
449
|
-
team: TeamRecord;
|
|
450
|
-
owner: TeamMember;
|
|
451
|
-
};
|
|
452
|
-
updateTeam(input: {
|
|
453
|
-
name?: string;
|
|
454
|
-
authorizationEnabled?: boolean;
|
|
455
|
-
}, expectedRevision: number, now?: number): TeamRecord;
|
|
456
|
-
listMembers(opts?: {
|
|
457
|
-
includeRemoved?: boolean;
|
|
458
|
-
}): TeamMember[];
|
|
459
|
-
getMember(id: string): TeamMember | undefined;
|
|
460
|
-
createMember(input: {
|
|
461
|
-
displayName: string;
|
|
462
|
-
kind?: TeamMemberKind;
|
|
463
|
-
}, now?: number): TeamMember;
|
|
464
|
-
updateMember(id: string, input: {
|
|
465
|
-
displayName?: string;
|
|
466
|
-
status?: TeamMemberStatus;
|
|
467
|
-
}, expectedRevision: number, now?: number): TeamMember | undefined;
|
|
468
|
-
listRoleBindings(memberId?: string): TeamRoleBinding[];
|
|
469
|
-
grantRole(input: {
|
|
470
|
-
memberId: string;
|
|
471
|
-
role: TeamRole;
|
|
472
|
-
scopeType?: TeamScopeType;
|
|
473
|
-
scopeId?: string;
|
|
474
|
-
}, now?: number): TeamRoleBinding;
|
|
475
|
-
setNodeAccessRole(input: {
|
|
476
|
-
memberId: string;
|
|
477
|
-
nodeId: string;
|
|
478
|
-
role: "viewer" | "operator" | "node-admin";
|
|
479
|
-
}, now?: number): TeamRoleBinding;
|
|
480
|
-
revokeRole(id: string, now?: number): boolean;
|
|
481
|
-
listPrincipalBindings(memberId?: string): TeamPrincipalBinding[];
|
|
482
|
-
bindPrincipal(input: {
|
|
483
|
-
memberId: string;
|
|
484
|
-
actorType: TeamPrincipalType;
|
|
485
|
-
actorId: string;
|
|
486
|
-
}, now?: number): TeamPrincipalBinding;
|
|
487
|
-
unbindPrincipal(actorType: TeamPrincipalType, actorId: string, now?: number): boolean;
|
|
488
|
-
memberForPrincipal(actorType: TeamPrincipalType, actorId: string): TeamMember | undefined;
|
|
489
|
-
authorize(actorType: TeamPrincipalType, actorId: string, permission: TeamPermission, resource?: TeamAuthorizationResource): TeamAuthorizationDecision;
|
|
490
|
-
close(): void;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
type CloudAuthorizationSnapshotStatus = "unavailable" | "pending" | "active" | "expired";
|
|
494
|
-
interface CloudAuthorizationState {
|
|
495
|
-
status: CloudAuthorizationSnapshotStatus;
|
|
496
|
-
revision?: number;
|
|
497
|
-
notBefore?: number;
|
|
498
|
-
expiresAt?: number;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
371
|
declare global {
|
|
502
372
|
/** Stable package version injected by tsup. Source/test builds fall back to package.json. */
|
|
503
373
|
const __SERVER_VERSION__: string | undefined;
|
|
@@ -845,7 +715,7 @@ declare class TerminalManager {
|
|
|
845
715
|
private killTmux;
|
|
846
716
|
}
|
|
847
717
|
|
|
848
|
-
type InputLeaseActorType = "device" | "host" | "local"
|
|
718
|
+
type InputLeaseActorType = "device" | "host" | "local";
|
|
849
719
|
interface InputLeasePrincipal {
|
|
850
720
|
actorType: InputLeaseActorType;
|
|
851
721
|
actorId: string;
|
|
@@ -928,27 +798,107 @@ declare class InputLeaseCoordinator {
|
|
|
928
798
|
private emit;
|
|
929
799
|
}
|
|
930
800
|
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
801
|
+
type TeamStoreMode = "sqlite" | "memory-fallback";
|
|
802
|
+
type TeamMemberKind = "person" | "service";
|
|
803
|
+
type TeamMemberStatus = "active" | "suspended" | "removed";
|
|
804
|
+
type TeamRole = "viewer" | "operator" | "node-admin" | "workspace-manager" | "extension-manager" | "policy-admin" | "organization-admin";
|
|
805
|
+
type TeamScopeType = "team" | "host" | "workspace";
|
|
806
|
+
type TeamPrincipalType = "device" | "host" | "local";
|
|
807
|
+
type TeamPermission = "team:read" | "sessions:read" | "sessions:operate" | "attention:read" | "attention:manage" | "presence:read" | "presence:write" | "workspaces:manage" | "extensions:manage" | "policy:manage" | "members:manage" | "node-access:manage" | "audit:read" | "fleet:read";
|
|
808
|
+
interface TeamRecord {
|
|
809
|
+
id: string;
|
|
810
|
+
name: string;
|
|
811
|
+
authorizationEnabled: boolean;
|
|
812
|
+
revision: number;
|
|
813
|
+
createdAt: number;
|
|
814
|
+
updatedAt: number;
|
|
815
|
+
}
|
|
816
|
+
interface TeamMember {
|
|
817
|
+
id: string;
|
|
818
|
+
displayName: string;
|
|
819
|
+
kind: TeamMemberKind;
|
|
820
|
+
status: TeamMemberStatus;
|
|
821
|
+
revision: number;
|
|
822
|
+
createdAt: number;
|
|
823
|
+
updatedAt: number;
|
|
824
|
+
}
|
|
825
|
+
interface TeamRoleBinding {
|
|
826
|
+
id: string;
|
|
827
|
+
memberId: string;
|
|
828
|
+
role: TeamRole;
|
|
829
|
+
scopeType: TeamScopeType;
|
|
830
|
+
scopeId?: string;
|
|
831
|
+
createdAt: number;
|
|
940
832
|
}
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
833
|
+
interface TeamPrincipalBinding {
|
|
834
|
+
actorType: TeamPrincipalType;
|
|
835
|
+
actorId: string;
|
|
836
|
+
memberId: string;
|
|
837
|
+
createdAt: number;
|
|
838
|
+
}
|
|
839
|
+
interface TeamAuthorizationResource {
|
|
840
|
+
hostId?: string;
|
|
841
|
+
workspaceId?: string;
|
|
842
|
+
}
|
|
843
|
+
interface TeamAuthorizationDecision {
|
|
844
|
+
allowed: boolean;
|
|
845
|
+
reason: "local-break-glass" | "not-enforced" | "unbound" | "inactive" | "role" | "missing-permission";
|
|
846
|
+
member?: TeamMember;
|
|
847
|
+
roles: TeamRole[];
|
|
848
|
+
}
|
|
849
|
+
interface TeamStore {
|
|
850
|
+
readonly mode: TeamStoreMode;
|
|
851
|
+
getTeam(): TeamRecord | null;
|
|
852
|
+
createTeam(input: {
|
|
853
|
+
name: string;
|
|
854
|
+
ownerName: string;
|
|
855
|
+
ownerPrincipal: {
|
|
856
|
+
actorType: TeamPrincipalType;
|
|
857
|
+
actorId: string;
|
|
858
|
+
};
|
|
859
|
+
}, now?: number): {
|
|
860
|
+
team: TeamRecord;
|
|
861
|
+
owner: TeamMember;
|
|
862
|
+
};
|
|
863
|
+
updateTeam(input: {
|
|
864
|
+
name?: string;
|
|
865
|
+
authorizationEnabled?: boolean;
|
|
866
|
+
}, expectedRevision: number, now?: number): TeamRecord;
|
|
867
|
+
listMembers(opts?: {
|
|
868
|
+
includeRemoved?: boolean;
|
|
869
|
+
}): TeamMember[];
|
|
870
|
+
getMember(id: string): TeamMember | undefined;
|
|
871
|
+
createMember(input: {
|
|
872
|
+
displayName: string;
|
|
873
|
+
kind?: TeamMemberKind;
|
|
874
|
+
}, now?: number): TeamMember;
|
|
875
|
+
updateMember(id: string, input: {
|
|
876
|
+
displayName?: string;
|
|
877
|
+
status?: TeamMemberStatus;
|
|
878
|
+
}, expectedRevision: number, now?: number): TeamMember | undefined;
|
|
879
|
+
listRoleBindings(memberId?: string): TeamRoleBinding[];
|
|
880
|
+
grantRole(input: {
|
|
881
|
+
memberId: string;
|
|
882
|
+
role: TeamRole;
|
|
883
|
+
scopeType?: TeamScopeType;
|
|
884
|
+
scopeId?: string;
|
|
885
|
+
}, now?: number): TeamRoleBinding;
|
|
886
|
+
setNodeAccessRole(input: {
|
|
887
|
+
memberId: string;
|
|
888
|
+
nodeId: string;
|
|
889
|
+
role: "viewer" | "operator" | "node-admin";
|
|
890
|
+
}, now?: number): TeamRoleBinding;
|
|
891
|
+
revokeRole(id: string, now?: number): boolean;
|
|
892
|
+
listPrincipalBindings(memberId?: string): TeamPrincipalBinding[];
|
|
893
|
+
bindPrincipal(input: {
|
|
894
|
+
memberId: string;
|
|
895
|
+
actorType: TeamPrincipalType;
|
|
896
|
+
actorId: string;
|
|
897
|
+
}, now?: number): TeamPrincipalBinding;
|
|
898
|
+
unbindPrincipal(actorType: TeamPrincipalType, actorId: string, now?: number): boolean;
|
|
899
|
+
memberForPrincipal(actorType: TeamPrincipalType, actorId: string): TeamMember | undefined;
|
|
900
|
+
authorize(actorType: TeamPrincipalType, actorId: string, permission: TeamPermission, resource?: TeamAuthorizationResource): TeamAuthorizationDecision;
|
|
901
|
+
close(): void;
|
|
952
902
|
}
|
|
953
903
|
|
|
954
904
|
type PolicyStoreMode = "sqlite" | "memory-fallback";
|
|
@@ -962,7 +912,6 @@ interface EnterprisePolicy {
|
|
|
962
912
|
allowDangerousProviderModes: boolean;
|
|
963
913
|
allowFileTransfer: boolean;
|
|
964
914
|
extensionMode: ExtensionPolicyMode;
|
|
965
|
-
allowRelay: boolean;
|
|
966
915
|
updateMode: UpdatePolicyMode;
|
|
967
916
|
revision: number;
|
|
968
917
|
createdAt: number;
|
|
@@ -976,7 +925,6 @@ interface EnterprisePolicyUpdate {
|
|
|
976
925
|
allowDangerousProviderModes?: boolean;
|
|
977
926
|
allowFileTransfer?: boolean;
|
|
978
927
|
extensionMode?: ExtensionPolicyMode;
|
|
979
|
-
allowRelay?: boolean;
|
|
980
928
|
updateMode?: UpdatePolicyMode;
|
|
981
929
|
}
|
|
982
930
|
interface PolicyStore {
|
|
@@ -1106,36 +1054,15 @@ declare class PresenceCoordinator {
|
|
|
1106
1054
|
private emit;
|
|
1107
1055
|
}
|
|
1108
1056
|
|
|
1109
|
-
type RelayRpcMethod = "GET" | "HEAD" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
1110
|
-
interface RelayRpcRequest {
|
|
1111
|
-
id: string;
|
|
1112
|
-
method: RelayRpcMethod;
|
|
1113
|
-
path: string;
|
|
1114
|
-
headers: Record<string, string>;
|
|
1115
|
-
body?: Buffer;
|
|
1116
|
-
}
|
|
1117
|
-
interface RelayRpcResponse {
|
|
1118
|
-
id: string;
|
|
1119
|
-
status: number;
|
|
1120
|
-
headers: Record<string, string>;
|
|
1121
|
-
body?: string;
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
1057
|
interface CreateServerResult {
|
|
1125
1058
|
app: FastifyInstance;
|
|
1126
1059
|
authGate: AuthGate;
|
|
1127
1060
|
/** Issue a five-minute, one-use pairing capability without exposing the host's master token. */
|
|
1128
1061
|
issuePairing(): PairingTicket;
|
|
1129
|
-
/** Internal E2E-relay bridge. It authenticates relay-scoped devices through the exact normal route hooks. */
|
|
1130
|
-
dispatchRelayRequest(token: string, request: RelayRpcRequest): Promise<RelayRpcResponse>;
|
|
1131
|
-
/** Issues a relay-principal terminal ticket without exposing the bridge's process-local capability. */
|
|
1132
|
-
issueRelayTerminalTicket(token: string): Promise<string>;
|
|
1133
|
-
/** Process-local loopback headers for streamed relay HTTP. Never expose these outside this server process. */
|
|
1134
|
-
relayLoopbackHeaders(token: string, headers?: Record<string, string>): Record<string, string>;
|
|
1135
1062
|
/** Exposed so startServer can late-bind the MCP attach config (after listen() resolves the port) —
|
|
1136
1063
|
* this is what gives the terminal's claude send_image/send_file. */
|
|
1137
1064
|
terminalManager: TerminalManager;
|
|
1138
|
-
/** Exposed for
|
|
1065
|
+
/** Exposed for team composition and isolated ownership tests. */
|
|
1139
1066
|
inputLeases: InputLeaseCoordinator;
|
|
1140
1067
|
teamStore: TeamStore;
|
|
1141
1068
|
policyStore: PolicyStore;
|
|
@@ -1143,33 +1070,6 @@ interface CreateServerResult {
|
|
|
1143
1070
|
presence: PresenceCoordinator;
|
|
1144
1071
|
/** False when tmux/node-pty is unavailable → terminal sessions are disabled (startServer warns loudly). */
|
|
1145
1072
|
terminalAvailable: boolean;
|
|
1146
|
-
/** Privacy-bounded webhook routing records synchronized to an optional managed control plane. */
|
|
1147
|
-
automationWebhookRegistrations(): CloudAutomationWebhookRegistration[];
|
|
1148
|
-
/** Durably accepts one control-plane signal; the invocation id makes redelivery idempotent. */
|
|
1149
|
-
acceptCloudAutomationInvocation(invocation: CloudAutomationInvocation): Promise<void>;
|
|
1150
|
-
}
|
|
1151
|
-
|
|
1152
|
-
type RelayHostStatus = "idle" | "connecting" | "online" | "reconnecting" | "stopped";
|
|
1153
|
-
interface RelayHostMetrics {
|
|
1154
|
-
status: RelayHostStatus;
|
|
1155
|
-
activeChannels: number;
|
|
1156
|
-
acceptedChannels: number;
|
|
1157
|
-
rejectedChannels: number;
|
|
1158
|
-
completedRequests: number;
|
|
1159
|
-
failedRequests: number;
|
|
1160
|
-
reconnects: number;
|
|
1161
|
-
activeTransfers: number;
|
|
1162
|
-
completedTransfers: number;
|
|
1163
|
-
failedTransfers: number;
|
|
1164
|
-
streamedRequestBytes: number;
|
|
1165
|
-
streamedResponseBytes: number;
|
|
1166
|
-
}
|
|
1167
|
-
interface RelayHostConnector {
|
|
1168
|
-
start(): void;
|
|
1169
|
-
stop(): Promise<void>;
|
|
1170
|
-
waitUntilReady(timeoutMs?: number): Promise<void>;
|
|
1171
|
-
closeDevice(deviceId: string): void;
|
|
1172
|
-
metrics(): RelayHostMetrics;
|
|
1173
1073
|
}
|
|
1174
1074
|
|
|
1175
1075
|
declare function providerPreflightWarning(name: string, availability: ProviderAvailability): string | undefined;
|
|
@@ -1190,22 +1090,10 @@ declare function claudePreflightWarning(availability: ClaudeAvailability): strin
|
|
|
1190
1090
|
* (the probe is short-timeout-guarded). Injectable probe + log sink so it's testable without a spawn.
|
|
1191
1091
|
*/
|
|
1192
1092
|
declare function runClaudePreflight(probe: ClaudeVersionProbe, warn?: (msg: string) => void): Promise<void>;
|
|
1193
|
-
|
|
1194
|
-
/** Shared control-plane transport seam for isolated embedding and startup tests. */
|
|
1195
|
-
fetch?: typeof globalThis.fetch;
|
|
1196
|
-
}
|
|
1197
|
-
declare function cloudHostCapabilities(input: {
|
|
1198
|
-
authorizationVersion: number;
|
|
1199
|
-
terminalAvailable: boolean;
|
|
1200
|
-
relayEnabled: boolean;
|
|
1201
|
-
managedDeviceEnrollmentEnabled: boolean;
|
|
1202
|
-
}): string[];
|
|
1203
|
-
declare function startServer(env?: NodeJS.ProcessEnv, options?: StartServerOptions): Promise<CreateServerResult & {
|
|
1093
|
+
declare function startServer(env?: NodeJS.ProcessEnv): Promise<CreateServerResult & {
|
|
1204
1094
|
url: string;
|
|
1205
1095
|
token?: string;
|
|
1206
1096
|
tokenGenerated: boolean;
|
|
1207
|
-
relayHost?: RelayHostConnector;
|
|
1208
|
-
cloudHostRuntime?: CloudHostRuntime;
|
|
1209
1097
|
}>;
|
|
1210
1098
|
|
|
1211
|
-
export {
|
|
1099
|
+
export { claudePreflightWarning, providerPreflightWarning, runClaudePreflight, runProviderPreflight, startServer };
|