@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/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 (Caddy / Cloudflare) `request.ip` is the proxy's IP
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
- type TeamStoreMode = "sqlite" | "memory-fallback";
792
- type TeamMemberKind = "person" | "service";
793
- type TeamMemberStatus = "active" | "suspended" | "removed";
794
- type TeamRole = "viewer" | "operator" | "workspace-manager" | "extension-manager" | "policy-admin" | "organization-admin";
795
- type TeamScopeType = "team" | "host" | "workspace";
796
- type TeamPrincipalType = "device" | "host" | "local" | "relay";
797
- type TeamPermission = "team:read" | "sessions:read" | "sessions:operate" | "attention:read" | "attention:manage" | "presence:read" | "presence:write" | "workspaces:manage" | "extensions:manage" | "policy:manage" | "members:manage" | "audit:read" | "fleet:read";
798
- interface TeamRecord {
799
- id: string;
800
- name: string;
801
- authorizationEnabled: boolean;
802
- revision: number;
803
- createdAt: number;
804
- updatedAt: number;
805
- }
806
- interface TeamMember {
807
- id: string;
808
- displayName: string;
809
- kind: TeamMemberKind;
810
- status: TeamMemberStatus;
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
- declare function startServer(env?: NodeJS.ProcessEnv): Promise<CreateServerResult & {
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 };