@roamcode.ai/server 1.2.0 → 1.3.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/container/relay.js +751 -37
- package/dist/index.d.ts +1732 -8
- package/dist/index.js +7632 -1266
- package/dist/relay-start.d.ts +4 -0
- package/dist/relay-start.js +751 -37
- package/dist/start.d.ts +156 -99
- package/dist/start.js +12155 -6614
- package/package.json +2 -2
package/dist/start.d.ts
CHANGED
|
@@ -184,7 +184,7 @@ type AuthCheckResult = {
|
|
|
184
184
|
* WebSocket upgrade.
|
|
185
185
|
*
|
|
186
186
|
* Proxy lockout caveat: the lockout is keyed by `clientKey` (`request.ip`).
|
|
187
|
-
* Behind a reverse proxy
|
|
187
|
+
* Behind a reverse proxy, `request.ip` is the proxy's IP
|
|
188
188
|
* for EVERY client, collapsing the per-client lockout to one shared key. To
|
|
189
189
|
* stop that from self-DoS-ing the sole legitimate user, {@link check} validates
|
|
190
190
|
* the token FIRST: a CORRECT token is ALWAYS accepted, even while its key is
|
|
@@ -369,6 +369,117 @@ interface PairingTicket {
|
|
|
369
369
|
scopes: DeviceScope[];
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
+
type TeamStoreMode = "sqlite" | "memory-fallback";
|
|
373
|
+
type TeamMemberKind = "person" | "service";
|
|
374
|
+
type TeamMemberStatus = "active" | "suspended" | "removed";
|
|
375
|
+
type TeamRole = "viewer" | "operator" | "node-admin" | "workspace-manager" | "extension-manager" | "policy-admin" | "organization-admin";
|
|
376
|
+
type TeamScopeType = "team" | "host" | "workspace";
|
|
377
|
+
type TeamPrincipalType = "device" | "host" | "local" | "relay";
|
|
378
|
+
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";
|
|
379
|
+
interface TeamRecord {
|
|
380
|
+
id: string;
|
|
381
|
+
name: string;
|
|
382
|
+
authorizationEnabled: boolean;
|
|
383
|
+
revision: number;
|
|
384
|
+
createdAt: number;
|
|
385
|
+
updatedAt: number;
|
|
386
|
+
}
|
|
387
|
+
interface TeamMember {
|
|
388
|
+
id: string;
|
|
389
|
+
displayName: string;
|
|
390
|
+
kind: TeamMemberKind;
|
|
391
|
+
status: TeamMemberStatus;
|
|
392
|
+
revision: number;
|
|
393
|
+
createdAt: number;
|
|
394
|
+
updatedAt: number;
|
|
395
|
+
}
|
|
396
|
+
interface TeamRoleBinding {
|
|
397
|
+
id: string;
|
|
398
|
+
memberId: string;
|
|
399
|
+
role: TeamRole;
|
|
400
|
+
scopeType: TeamScopeType;
|
|
401
|
+
scopeId?: string;
|
|
402
|
+
createdAt: number;
|
|
403
|
+
}
|
|
404
|
+
interface TeamPrincipalBinding {
|
|
405
|
+
actorType: TeamPrincipalType;
|
|
406
|
+
actorId: string;
|
|
407
|
+
memberId: string;
|
|
408
|
+
createdAt: number;
|
|
409
|
+
}
|
|
410
|
+
interface TeamAuthorizationResource {
|
|
411
|
+
hostId?: string;
|
|
412
|
+
workspaceId?: string;
|
|
413
|
+
}
|
|
414
|
+
interface TeamAuthorizationDecision {
|
|
415
|
+
allowed: boolean;
|
|
416
|
+
reason: "local-break-glass" | "not-enforced" | "unbound" | "inactive" | "role" | "missing-permission";
|
|
417
|
+
member?: TeamMember;
|
|
418
|
+
roles: TeamRole[];
|
|
419
|
+
}
|
|
420
|
+
interface TeamStore {
|
|
421
|
+
readonly mode: TeamStoreMode;
|
|
422
|
+
getTeam(): TeamRecord | null;
|
|
423
|
+
createTeam(input: {
|
|
424
|
+
name: string;
|
|
425
|
+
ownerName: string;
|
|
426
|
+
ownerPrincipal: {
|
|
427
|
+
actorType: TeamPrincipalType;
|
|
428
|
+
actorId: string;
|
|
429
|
+
};
|
|
430
|
+
}, now?: number): {
|
|
431
|
+
team: TeamRecord;
|
|
432
|
+
owner: TeamMember;
|
|
433
|
+
};
|
|
434
|
+
updateTeam(input: {
|
|
435
|
+
name?: string;
|
|
436
|
+
authorizationEnabled?: boolean;
|
|
437
|
+
}, expectedRevision: number, now?: number): TeamRecord;
|
|
438
|
+
listMembers(opts?: {
|
|
439
|
+
includeRemoved?: boolean;
|
|
440
|
+
}): TeamMember[];
|
|
441
|
+
getMember(id: string): TeamMember | undefined;
|
|
442
|
+
createMember(input: {
|
|
443
|
+
displayName: string;
|
|
444
|
+
kind?: TeamMemberKind;
|
|
445
|
+
}, now?: number): TeamMember;
|
|
446
|
+
updateMember(id: string, input: {
|
|
447
|
+
displayName?: string;
|
|
448
|
+
status?: TeamMemberStatus;
|
|
449
|
+
}, expectedRevision: number, now?: number): TeamMember | undefined;
|
|
450
|
+
listRoleBindings(memberId?: string): TeamRoleBinding[];
|
|
451
|
+
grantRole(input: {
|
|
452
|
+
memberId: string;
|
|
453
|
+
role: TeamRole;
|
|
454
|
+
scopeType?: TeamScopeType;
|
|
455
|
+
scopeId?: string;
|
|
456
|
+
}, now?: number): TeamRoleBinding;
|
|
457
|
+
setNodeAccessRole(input: {
|
|
458
|
+
memberId: string;
|
|
459
|
+
nodeId: string;
|
|
460
|
+
role: "viewer" | "operator" | "node-admin";
|
|
461
|
+
}, now?: number): TeamRoleBinding;
|
|
462
|
+
revokeRole(id: string, now?: number): boolean;
|
|
463
|
+
listPrincipalBindings(memberId?: string): TeamPrincipalBinding[];
|
|
464
|
+
bindPrincipal(input: {
|
|
465
|
+
memberId: string;
|
|
466
|
+
actorType: TeamPrincipalType;
|
|
467
|
+
actorId: string;
|
|
468
|
+
}, now?: number): TeamPrincipalBinding;
|
|
469
|
+
unbindPrincipal(actorType: TeamPrincipalType, actorId: string, now?: number): boolean;
|
|
470
|
+
memberForPrincipal(actorType: TeamPrincipalType, actorId: string): TeamMember | undefined;
|
|
471
|
+
authorize(actorType: TeamPrincipalType, actorId: string, permission: TeamPermission, resource?: TeamAuthorizationResource): TeamAuthorizationDecision;
|
|
472
|
+
close(): void;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
type CloudAuthorizationSnapshotStatus = "unavailable" | "pending" | "active" | "expired";
|
|
476
|
+
interface CloudAuthorizationState {
|
|
477
|
+
status: CloudAuthorizationSnapshotStatus;
|
|
478
|
+
revision?: number;
|
|
479
|
+
notBefore?: number;
|
|
480
|
+
expiresAt?: number;
|
|
481
|
+
}
|
|
482
|
+
|
|
372
483
|
declare global {
|
|
373
484
|
/** Stable package version injected by tsup. Source/test builds fall back to package.json. */
|
|
374
485
|
const __SERVER_VERSION__: string | undefined;
|
|
@@ -689,6 +800,17 @@ declare class TerminalManager {
|
|
|
689
800
|
private cleanupRecordPaths;
|
|
690
801
|
private applyRuntimeSignal;
|
|
691
802
|
write(id: string, data: string): void;
|
|
803
|
+
/**
|
|
804
|
+
* Start a newly-created automation Session and submit its task exactly once. `create()` is intentionally
|
|
805
|
+
* lazy, so writing before an attach would be a silent no-op; this method first owns a private attachment,
|
|
806
|
+
* waits for the provider TUI's idle composer (not merely a banner/auth/trust frame), then sends one bracketed
|
|
807
|
+
* paste and releases the attachment.
|
|
808
|
+
* The task never enters argv, logs, audit metadata, or a WebSocket URL.
|
|
809
|
+
*/
|
|
810
|
+
bootstrapTask(id: string, task: string, options?: {
|
|
811
|
+
readyTimeoutMs?: number;
|
|
812
|
+
signal?: AbortSignal;
|
|
813
|
+
}): Promise<void>;
|
|
692
814
|
resize(id: string, cols: number, rows: number): void;
|
|
693
815
|
stop(id: string): void;
|
|
694
816
|
get(id: string): TerminalMeta | undefined;
|
|
@@ -788,102 +910,26 @@ declare class InputLeaseCoordinator {
|
|
|
788
910
|
private emit;
|
|
789
911
|
}
|
|
790
912
|
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
status:
|
|
811
|
-
revision: number;
|
|
812
|
-
createdAt: number;
|
|
813
|
-
updatedAt: number;
|
|
814
|
-
}
|
|
815
|
-
interface TeamRoleBinding {
|
|
816
|
-
id: string;
|
|
817
|
-
memberId: string;
|
|
818
|
-
role: TeamRole;
|
|
819
|
-
scopeType: TeamScopeType;
|
|
820
|
-
scopeId?: string;
|
|
821
|
-
createdAt: number;
|
|
822
|
-
}
|
|
823
|
-
interface TeamPrincipalBinding {
|
|
824
|
-
actorType: TeamPrincipalType;
|
|
825
|
-
actorId: string;
|
|
826
|
-
memberId: string;
|
|
827
|
-
createdAt: number;
|
|
828
|
-
}
|
|
829
|
-
interface TeamAuthorizationResource {
|
|
830
|
-
hostId?: string;
|
|
831
|
-
workspaceId?: string;
|
|
832
|
-
}
|
|
833
|
-
interface TeamAuthorizationDecision {
|
|
834
|
-
allowed: boolean;
|
|
835
|
-
reason: "local-break-glass" | "not-enforced" | "unbound" | "inactive" | "role" | "missing-permission";
|
|
836
|
-
member?: TeamMember;
|
|
837
|
-
roles: TeamRole[];
|
|
838
|
-
}
|
|
839
|
-
interface TeamStore {
|
|
840
|
-
readonly mode: TeamStoreMode;
|
|
841
|
-
getTeam(): TeamRecord | null;
|
|
842
|
-
createTeam(input: {
|
|
843
|
-
name: string;
|
|
844
|
-
ownerName: string;
|
|
845
|
-
ownerPrincipal: {
|
|
846
|
-
actorType: TeamPrincipalType;
|
|
847
|
-
actorId: string;
|
|
848
|
-
};
|
|
849
|
-
}, now?: number): {
|
|
850
|
-
team: TeamRecord;
|
|
851
|
-
owner: TeamMember;
|
|
852
|
-
};
|
|
853
|
-
updateTeam(input: {
|
|
854
|
-
name?: string;
|
|
855
|
-
authorizationEnabled?: boolean;
|
|
856
|
-
}, expectedRevision: number, now?: number): TeamRecord;
|
|
857
|
-
listMembers(opts?: {
|
|
858
|
-
includeRemoved?: boolean;
|
|
859
|
-
}): TeamMember[];
|
|
860
|
-
getMember(id: string): TeamMember | undefined;
|
|
861
|
-
createMember(input: {
|
|
862
|
-
displayName: string;
|
|
863
|
-
kind?: TeamMemberKind;
|
|
864
|
-
}, now?: number): TeamMember;
|
|
865
|
-
updateMember(id: string, input: {
|
|
866
|
-
displayName?: string;
|
|
867
|
-
status?: TeamMemberStatus;
|
|
868
|
-
}, expectedRevision: number, now?: number): TeamMember | undefined;
|
|
869
|
-
listRoleBindings(memberId?: string): TeamRoleBinding[];
|
|
870
|
-
grantRole(input: {
|
|
871
|
-
memberId: string;
|
|
872
|
-
role: TeamRole;
|
|
873
|
-
scopeType?: TeamScopeType;
|
|
874
|
-
scopeId?: string;
|
|
875
|
-
}, now?: number): TeamRoleBinding;
|
|
876
|
-
revokeRole(id: string, now?: number): boolean;
|
|
877
|
-
listPrincipalBindings(memberId?: string): TeamPrincipalBinding[];
|
|
878
|
-
bindPrincipal(input: {
|
|
879
|
-
memberId: string;
|
|
880
|
-
actorType: TeamPrincipalType;
|
|
881
|
-
actorId: string;
|
|
882
|
-
}, now?: number): TeamPrincipalBinding;
|
|
883
|
-
unbindPrincipal(actorType: TeamPrincipalType, actorId: string, now?: number): boolean;
|
|
884
|
-
memberForPrincipal(actorType: TeamPrincipalType, actorId: string): TeamMember | undefined;
|
|
885
|
-
authorize(actorType: TeamPrincipalType, actorId: string, permission: TeamPermission, resource?: TeamAuthorizationResource): TeamAuthorizationDecision;
|
|
886
|
-
close(): void;
|
|
913
|
+
interface CloudHostRuntimeStatus {
|
|
914
|
+
running: boolean;
|
|
915
|
+
heartbeatFailures: number;
|
|
916
|
+
authorizationFailures: number;
|
|
917
|
+
authorizationIssue?: CloudHostAuthorizationIssue;
|
|
918
|
+
lastHeartbeatAt?: number;
|
|
919
|
+
lastAuthorizationAt?: number;
|
|
920
|
+
authorization: CloudAuthorizationState;
|
|
921
|
+
}
|
|
922
|
+
type CloudHostAuthorizationIssue = "connectivity" | "credential-rejected" | "invalid-control-plane-response" | "authorization-verification-failed" | "trust-expired";
|
|
923
|
+
interface CloudHostRuntime {
|
|
924
|
+
start(): void;
|
|
925
|
+
stop(): Promise<void>;
|
|
926
|
+
sendHeartbeat(state?: "ready" | "draining"): Promise<void>;
|
|
927
|
+
refreshAuthorizationKeyset(): Promise<boolean>;
|
|
928
|
+
refreshAuthorizationSnapshot(): Promise<number>;
|
|
929
|
+
syncAuthorization(): Promise<number>;
|
|
930
|
+
/** Waits out an older in-flight poll, then starts a snapshot request from the resulting durable revision. */
|
|
931
|
+
syncAuthorizationFresh(): Promise<number>;
|
|
932
|
+
status(): CloudHostRuntimeStatus;
|
|
887
933
|
}
|
|
888
934
|
|
|
889
935
|
type PolicyStoreMode = "sqlite" | "memory-fallback";
|
|
@@ -1121,11 +1167,22 @@ declare function claudePreflightWarning(availability: ClaudeAvailability): strin
|
|
|
1121
1167
|
* (the probe is short-timeout-guarded). Injectable probe + log sink so it's testable without a spawn.
|
|
1122
1168
|
*/
|
|
1123
1169
|
declare function runClaudePreflight(probe: ClaudeVersionProbe, warn?: (msg: string) => void): Promise<void>;
|
|
1124
|
-
|
|
1170
|
+
interface StartServerOptions {
|
|
1171
|
+
/** Shared control-plane transport seam for isolated embedding and startup tests. */
|
|
1172
|
+
fetch?: typeof globalThis.fetch;
|
|
1173
|
+
}
|
|
1174
|
+
declare function cloudHostCapabilities(input: {
|
|
1175
|
+
authorizationVersion: number;
|
|
1176
|
+
terminalAvailable: boolean;
|
|
1177
|
+
relayEnabled: boolean;
|
|
1178
|
+
managedDeviceEnrollmentEnabled: boolean;
|
|
1179
|
+
}): string[];
|
|
1180
|
+
declare function startServer(env?: NodeJS.ProcessEnv, options?: StartServerOptions): Promise<CreateServerResult & {
|
|
1125
1181
|
url: string;
|
|
1126
1182
|
token?: string;
|
|
1127
1183
|
tokenGenerated: boolean;
|
|
1128
1184
|
relayHost?: RelayHostConnector;
|
|
1185
|
+
cloudHostRuntime?: CloudHostRuntime;
|
|
1129
1186
|
}>;
|
|
1130
1187
|
|
|
1131
|
-
export { claudePreflightWarning, providerPreflightWarning, runClaudePreflight, runProviderPreflight, startServer };
|
|
1188
|
+
export { type StartServerOptions, claudePreflightWarning, cloudHostCapabilities, providerPreflightWarning, runClaudePreflight, runProviderPreflight, startServer };
|