crewly 1.11.5 → 1.12.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/config/skills/agent/onboarding/synthesize-hierarchy/SKILL.md +65 -0
- package/config/skills/agent/onboarding/synthesize-hierarchy/execute.sh +61 -0
- package/config/skills/agent/web-search/SKILL.md +70 -0
- package/config/skills/agent/web-search/execute.sh +170 -0
- package/config/skills/agent/web-search/skill.json +23 -0
- package/dist/backend/backend/src/constants.d.ts +34 -1
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +34 -1
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.d.ts +22 -0
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.js +58 -0
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.js +3 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/orchestrator-onboarding/orchestrator-onboarding.controller.d.ts +27 -0
- package/dist/backend/backend/src/controllers/orchestrator-onboarding/orchestrator-onboarding.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/orchestrator-onboarding/orchestrator-onboarding.controller.js +108 -0
- package/dist/backend/backend/src/controllers/orchestrator-onboarding/orchestrator-onboarding.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/orchestrator-onboarding/orchestrator-onboarding.routes.d.ts +6 -2
- package/dist/backend/backend/src/controllers/orchestrator-onboarding/orchestrator-onboarding.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/orchestrator-onboarding/orchestrator-onboarding.routes.js +9 -3
- package/dist/backend/backend/src/controllers/orchestrator-onboarding/orchestrator-onboarding.routes.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +36 -2
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts +18 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +24 -2
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -1
- package/dist/backend/backend/src/services/backup/backup-archive.service.d.ts +90 -0
- package/dist/backend/backend/src/services/backup/backup-archive.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/backup/backup-archive.service.js +309 -0
- package/dist/backend/backend/src/services/backup/backup-archive.service.js.map +1 -0
- package/dist/backend/backend/src/services/backup/backup-cloud.client.d.ts +75 -0
- package/dist/backend/backend/src/services/backup/backup-cloud.client.d.ts.map +1 -0
- package/dist/backend/backend/src/services/backup/backup-cloud.client.js +134 -0
- package/dist/backend/backend/src/services/backup/backup-cloud.client.js.map +1 -0
- package/dist/backend/backend/src/services/backup/backup-restore.service.d.ts +78 -0
- package/dist/backend/backend/src/services/backup/backup-restore.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/backup/backup-restore.service.js +358 -0
- package/dist/backend/backend/src/services/backup/backup-restore.service.js.map +1 -0
- package/dist/backend/backend/src/services/backup/backup.types.d.ts +163 -0
- package/dist/backend/backend/src/services/backup/backup.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/backup/backup.types.js +13 -0
- package/dist/backend/backend/src/services/backup/backup.types.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-sync.service.d.ts +29 -2
- package/dist/backend/backend/src/services/cloud/cloud-sync.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.service.js +97 -13
- package/dist/backend/backend/src/services/cloud/cloud-sync.service.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.d.ts +102 -0
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js +164 -0
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js.map +1 -0
- package/dist/backend/backend/src/services/fission/fission-guard.service.d.ts +21 -0
- package/dist/backend/backend/src/services/fission/fission-guard.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/fission/fission-guard.service.js +30 -0
- package/dist/backend/backend/src/services/fission/fission-guard.service.js.map +1 -1
- package/dist/backend/backend/src/services/intent-task/intent-classifier.rules.d.ts +4 -0
- package/dist/backend/backend/src/services/intent-task/intent-classifier.rules.d.ts.map +1 -1
- package/dist/backend/backend/src/services/intent-task/intent-classifier.rules.js +8 -0
- package/dist/backend/backend/src/services/intent-task/intent-classifier.rules.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/onboarding/materialize-team.d.ts +79 -58
- package/dist/backend/backend/src/services/orchestrator/onboarding/materialize-team.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/onboarding/materialize-team.js +140 -65
- package/dist/backend/backend/src/services/orchestrator/onboarding/materialize-team.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/onboarding/synthesize-hierarchy.d.ts +117 -0
- package/dist/backend/backend/src/services/orchestrator/onboarding/synthesize-hierarchy.d.ts.map +1 -0
- package/dist/backend/backend/src/services/orchestrator/onboarding/synthesize-hierarchy.js +189 -0
- package/dist/backend/backend/src/services/orchestrator/onboarding/synthesize-hierarchy.js.map +1 -0
- package/dist/backend/backend/src/services/orchestrator/onboarding-mode-loader.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/onboarding-mode-loader.js +1 -0
- package/dist/backend/backend/src/services/orchestrator/onboarding-mode-loader.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/onboarding-mode.skill-allowlist.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/onboarding-mode.skill-allowlist.js +2 -0
- package/dist/backend/backend/src/services/orchestrator/onboarding-mode.skill-allowlist.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/prompts/onboarding-mode.prompt.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/prompts/onboarding-mode.prompt.js +17 -1
- package/dist/backend/backend/src/services/orchestrator/prompts/onboarding-mode.prompt.js.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts +50 -0
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.js +71 -0
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.js.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts +18 -0
- package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler.service.js +75 -1
- package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
- package/dist/backend/backend/src/services/session/pty/pty-session-backend.d.ts +115 -0
- package/dist/backend/backend/src/services/session/pty/pty-session-backend.d.ts.map +1 -1
- package/dist/backend/backend/src/services/session/pty/pty-session-backend.js +189 -3
- package/dist/backend/backend/src/services/session/pty/pty-session-backend.js.map +1 -1
- package/dist/backend/backend/src/services/session/pty/pty-session.d.ts +28 -0
- package/dist/backend/backend/src/services/session/pty/pty-session.d.ts.map +1 -1
- package/dist/backend/backend/src/services/session/pty/pty-session.js +61 -1
- package/dist/backend/backend/src/services/session/pty/pty-session.js.map +1 -1
- package/dist/backend/backend/src/services/template/template.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/template/template.service.js +67 -2
- package/dist/backend/backend/src/services/template/template.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/cascade-request-status.d.ts +19 -1
- package/dist/backend/backend/src/services/v3/cascade-request-status.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/cascade-request-status.js +39 -2
- package/dist/backend/backend/src/services/v3/cascade-request-status.js.map +1 -1
- package/dist/backend/backend/src/services/v3/escalation-router.service.d.ts +41 -0
- package/dist/backend/backend/src/services/v3/escalation-router.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/escalation-router.service.js +169 -0
- package/dist/backend/backend/src/services/v3/escalation-router.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/request-cascade.subscriber.d.ts +4 -1
- package/dist/backend/backend/src/services/v3/request-cascade.subscriber.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/request-cascade.subscriber.js +21 -0
- package/dist/backend/backend/src/services/v3/request-cascade.subscriber.js.map +1 -1
- package/dist/backend/backend/src/types/intent-task.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/intent-task.types.js +8 -0
- package/dist/backend/backend/src/types/intent-task.types.js.map +1 -1
- package/dist/backend/backend/src/types/v2/request.types.d.ts +1 -1
- package/dist/backend/backend/src/types/v2/request.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/v2/request.types.js +1 -0
- package/dist/backend/backend/src/types/v2/request.types.js.map +1 -1
- package/dist/cli/backend/src/constants.d.ts +34 -1
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +34 -1
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/controllers/cloud/cloud-google-auth.controller.d.ts +70 -0
- package/dist/cli/backend/src/controllers/cloud/cloud-google-auth.controller.d.ts.map +1 -0
- package/dist/cli/backend/src/controllers/cloud/cloud-google-auth.controller.js +427 -0
- package/dist/cli/backend/src/controllers/cloud/cloud-google-auth.controller.js.map +1 -0
- package/dist/cli/backend/src/services/backup/backup-archive.service.d.ts +90 -0
- package/dist/cli/backend/src/services/backup/backup-archive.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/backup/backup-archive.service.js +309 -0
- package/dist/cli/backend/src/services/backup/backup-archive.service.js.map +1 -0
- package/dist/cli/backend/src/services/backup/backup-cloud.client.d.ts +75 -0
- package/dist/cli/backend/src/services/backup/backup-cloud.client.d.ts.map +1 -0
- package/dist/cli/backend/src/services/backup/backup-cloud.client.js +134 -0
- package/dist/cli/backend/src/services/backup/backup-cloud.client.js.map +1 -0
- package/dist/cli/backend/src/services/backup/backup-restore.service.d.ts +78 -0
- package/dist/cli/backend/src/services/backup/backup-restore.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/backup/backup-restore.service.js +358 -0
- package/dist/cli/backend/src/services/backup/backup-restore.service.js.map +1 -0
- package/dist/cli/backend/src/services/backup/backup.types.d.ts +163 -0
- package/dist/cli/backend/src/services/backup/backup.types.d.ts.map +1 -0
- package/dist/cli/backend/src/services/backup/backup.types.js +13 -0
- package/dist/cli/backend/src/services/backup/backup.types.js.map +1 -0
- package/dist/cli/backend/src/services/cloud/cloud-client.service.d.ts +410 -0
- package/dist/cli/backend/src/services/cloud/cloud-client.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/cloud/cloud-client.service.js +863 -0
- package/dist/cli/backend/src/services/cloud/cloud-client.service.js.map +1 -0
- package/dist/cli/backend/src/services/cloud/cloud-sync.service.d.ts +292 -0
- package/dist/cli/backend/src/services/cloud/cloud-sync.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/cloud/cloud-sync.service.js +1093 -0
- package/dist/cli/backend/src/services/cloud/cloud-sync.service.js.map +1 -0
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts +328 -0
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -0
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.js +171 -0
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.js.map +1 -0
- package/dist/cli/backend/src/services/cloud/device-identity.service.d.ts +89 -0
- package/dist/cli/backend/src/services/cloud/device-identity.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/cloud/device-identity.service.js +148 -0
- package/dist/cli/backend/src/services/cloud/device-identity.service.js.map +1 -0
- package/dist/cli/backend/src/services/user/user-identity.service.d.ts +86 -0
- package/dist/cli/backend/src/services/user/user-identity.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/user/user-identity.service.js +190 -0
- package/dist/cli/backend/src/services/user/user-identity.service.js.map +1 -0
- package/dist/cli/cli/src/commands/backup.d.ts +31 -0
- package/dist/cli/cli/src/commands/backup.d.ts.map +1 -0
- package/dist/cli/cli/src/commands/backup.js +280 -0
- package/dist/cli/cli/src/commands/backup.js.map +1 -0
- package/dist/cli/cli/src/index.js +10 -0
- package/dist/cli/cli/src/index.js.map +1 -1
- package/package.json +9 -3
- package/packages/crewly-agent/README.md +27 -0
- package/packages/crewly-agent/bin/crewly-agent +33 -0
- package/packages/crewly-agent/package.json +39 -0
- package/packages/crewly-agent/src/cli.ts +168 -0
- package/packages/crewly-agent/src/runtime/agent-runner.service.test.ts +2355 -0
- package/packages/crewly-agent/src/runtime/agent-runner.service.ts +1827 -0
- package/packages/crewly-agent/src/runtime/agent-stream.service.test.ts +153 -0
- package/packages/crewly-agent/src/runtime/agent-stream.service.ts +225 -0
- package/packages/crewly-agent/src/runtime/agent-worker.test.ts +171 -0
- package/packages/crewly-agent/src/runtime/agent-worker.ts +193 -0
- package/packages/crewly-agent/src/runtime/api-client.ts +143 -0
- package/packages/crewly-agent/src/runtime/approval-queue.service.ts +307 -0
- package/packages/crewly-agent/src/runtime/audit-log.service.test.ts +208 -0
- package/packages/crewly-agent/src/runtime/audit-log.service.ts +332 -0
- package/packages/crewly-agent/src/runtime/audit-trail.service.test.ts +178 -0
- package/packages/crewly-agent/src/runtime/audit-trail.service.ts +151 -0
- package/packages/crewly-agent/src/runtime/auditor-tools.test.ts +274 -0
- package/packages/crewly-agent/src/runtime/auditor-tools.ts +311 -0
- package/packages/crewly-agent/src/runtime/cloud-config.ts +67 -0
- package/packages/crewly-agent/src/runtime/deepseek-sse-transform.test.ts +165 -0
- package/packages/crewly-agent/src/runtime/deepseek-sse-transform.ts +168 -0
- package/packages/crewly-agent/src/runtime/env-isolation.service.ts +246 -0
- package/packages/crewly-agent/src/runtime/in-process-log-buffer.test.ts +280 -0
- package/packages/crewly-agent/src/runtime/in-process-log-buffer.ts +317 -0
- package/packages/crewly-agent/src/runtime/index.ts +38 -0
- package/packages/crewly-agent/src/runtime/mcp-tool-bridge.test.ts +352 -0
- package/packages/crewly-agent/src/runtime/mcp-tool-bridge.ts +244 -0
- package/packages/crewly-agent/src/runtime/model-manager.test.ts +326 -0
- package/packages/crewly-agent/src/runtime/model-manager.ts +363 -0
- package/packages/crewly-agent/src/runtime/output-filter.service.ts +175 -0
- package/packages/crewly-agent/src/runtime/prompt-guard.service.ts +303 -0
- package/packages/crewly-agent/src/runtime/rate-limiter.test.ts +228 -0
- package/packages/crewly-agent/src/runtime/rate-limiter.ts +353 -0
- package/packages/crewly-agent/src/runtime/tool-registry.test.ts +2510 -0
- package/packages/crewly-agent/src/runtime/tool-registry.ts +2104 -0
- package/packages/crewly-agent/src/runtime/types.test.ts +519 -0
- package/packages/crewly-agent/src/runtime/types.ts +637 -0
- package/packages/crewly-agent/src/runtime/web-search.tool.test.ts +131 -0
- package/packages/crewly-agent/src/runtime/web-search.tool.ts +140 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the Workspace Backup feature.
|
|
3
|
+
*
|
|
4
|
+
* A backup is a single `.tar.gz` archive containing a top-level
|
|
5
|
+
* `manifest.json` plus the captured `CREWLY_HOME` globals, each project's
|
|
6
|
+
* `.crewly/` tree, and (optionally) `chat.db`. See
|
|
7
|
+
* specs/2026-06-07-workspace-backup.md.
|
|
8
|
+
*
|
|
9
|
+
* @module services/backup/backup.types
|
|
10
|
+
*/
|
|
11
|
+
/** Manifest schema version — bump on any breaking layout/field change. */
|
|
12
|
+
export declare const BACKUP_SCHEMA_VERSION = 1;
|
|
13
|
+
/** A single captured file recorded in the manifest for integrity + listing. */
|
|
14
|
+
export interface BackupFileEntry {
|
|
15
|
+
/** Path inside the archive, relative to the archive root. */
|
|
16
|
+
path: string;
|
|
17
|
+
/** SHA-256 of the file content (hex). */
|
|
18
|
+
sha256: string;
|
|
19
|
+
/** Size in bytes. */
|
|
20
|
+
bytes: number;
|
|
21
|
+
}
|
|
22
|
+
/** Git provenance for a captured project so restore can re-clone the source tree. */
|
|
23
|
+
export interface BackupProjectGit {
|
|
24
|
+
/** `origin` remote URL, or null when not a git repo / no origin. */
|
|
25
|
+
remote: string | null;
|
|
26
|
+
/** HEAD commit sha, or null when unavailable. */
|
|
27
|
+
commit: string | null;
|
|
28
|
+
}
|
|
29
|
+
/** One project's captured `.crewly/` data + provenance. */
|
|
30
|
+
export interface BackupProjectEntry {
|
|
31
|
+
/** Stable project id (from projects.json). */
|
|
32
|
+
id: string;
|
|
33
|
+
/** Human-readable project name. */
|
|
34
|
+
name: string;
|
|
35
|
+
/** Absolute path on the SOURCE machine (used for restore path-rewriting). */
|
|
36
|
+
sourcePath: string;
|
|
37
|
+
/** Git provenance for re-clone on restore. */
|
|
38
|
+
git: BackupProjectGit;
|
|
39
|
+
/** Captured files under `projects/<id>/` in the archive. */
|
|
40
|
+
files: BackupFileEntry[];
|
|
41
|
+
}
|
|
42
|
+
/** chat.db capture record. */
|
|
43
|
+
export interface BackupChatDb {
|
|
44
|
+
/** Whether chat.db was included (false when excluded or the native module is absent). */
|
|
45
|
+
included: boolean;
|
|
46
|
+
/** SHA-256 of the captured db, when included. */
|
|
47
|
+
sha256?: string;
|
|
48
|
+
/** Size in bytes, when included. */
|
|
49
|
+
bytes?: number;
|
|
50
|
+
/** Reason it was skipped, when not included. */
|
|
51
|
+
skippedReason?: string;
|
|
52
|
+
}
|
|
53
|
+
/** Encryption envelope descriptor. v1 archives are unencrypted on disk; Cloud adds SSE. */
|
|
54
|
+
export interface BackupCrypto {
|
|
55
|
+
/** `none` for v1 local archives. `sse` once parked in the cloud. */
|
|
56
|
+
mode: 'none' | 'sse';
|
|
57
|
+
}
|
|
58
|
+
/** Top-level archive manifest. */
|
|
59
|
+
export interface BackupManifest {
|
|
60
|
+
schemaVersion: number;
|
|
61
|
+
crewlyVersion: string;
|
|
62
|
+
/** ISO timestamp — the logical point-in-time of the snapshot. */
|
|
63
|
+
createdAt: string;
|
|
64
|
+
/** Source device id (observability only; NEVER restored). */
|
|
65
|
+
sourceDeviceId: string | null;
|
|
66
|
+
sourceDeviceName: string | null;
|
|
67
|
+
/** Source `CREWLY_HOME` absolute path — restore uses it for path rewriting. */
|
|
68
|
+
sourceHomePath: string;
|
|
69
|
+
/** Owner account (JWT `sub`/googleId). Null for local-only archives; stamped by Cloud on upload. */
|
|
70
|
+
ownerSub: string | null;
|
|
71
|
+
/** Captured CREWLY_HOME global files (relative to `home/` in the archive). */
|
|
72
|
+
global: BackupFileEntry[];
|
|
73
|
+
/** Captured per-project `.crewly/` data. */
|
|
74
|
+
projects: BackupProjectEntry[];
|
|
75
|
+
chatDb: BackupChatDb;
|
|
76
|
+
crypto: BackupCrypto;
|
|
77
|
+
}
|
|
78
|
+
/** Options for building an archive. */
|
|
79
|
+
export interface CreateBackupOptions {
|
|
80
|
+
/** Output archive path. Defaults to `CREWLY_HOME/backups/workspace-<ts>.tar.gz`. */
|
|
81
|
+
outPath?: string;
|
|
82
|
+
/** Exclude chat.db (smaller archive, avoids SQLite capture). Default false. */
|
|
83
|
+
excludeChatDb?: boolean;
|
|
84
|
+
/** Override CREWLY_HOME (tests). Defaults to getCrewlyHomePath(). */
|
|
85
|
+
homePath?: string;
|
|
86
|
+
/** ISO timestamp for the snapshot point. Defaults to caller-supplied now (no Date in lib). */
|
|
87
|
+
createdAt: string;
|
|
88
|
+
/** Owner sub to stamp (usually null locally; Cloud stamps on upload). */
|
|
89
|
+
ownerSub?: string | null;
|
|
90
|
+
/** Source device id/name for the manifest (observability). */
|
|
91
|
+
sourceDeviceId?: string | null;
|
|
92
|
+
sourceDeviceName?: string | null;
|
|
93
|
+
}
|
|
94
|
+
/** Result of a successful archive build. */
|
|
95
|
+
export interface CreateBackupResult {
|
|
96
|
+
archivePath: string;
|
|
97
|
+
manifest: BackupManifest;
|
|
98
|
+
/** Total uncompressed bytes captured (for quota/UX). */
|
|
99
|
+
totalBytes: number;
|
|
100
|
+
}
|
|
101
|
+
/** How to handle a target that already has overlapping data. */
|
|
102
|
+
export type RestoreMode = 'abort' | 'overwrite';
|
|
103
|
+
/** Options for restoring an archive onto this machine. */
|
|
104
|
+
export interface RestoreOptions {
|
|
105
|
+
/** Archive (.tar.gz) to restore. */
|
|
106
|
+
archivePath: string;
|
|
107
|
+
/** Target CREWLY_HOME. Defaults to getCrewlyHomePath(). */
|
|
108
|
+
homePath?: string;
|
|
109
|
+
/** Conflict policy. Default 'abort'. */
|
|
110
|
+
mode?: RestoreMode;
|
|
111
|
+
/**
|
|
112
|
+
* Source→target absolute path remap for projects, e.g.
|
|
113
|
+
* `{ '/Users/alice/web': '/Users/bob/web' }`. When a source path isn't
|
|
114
|
+
* mapped, restore reuses it if it exists on the target, else records a
|
|
115
|
+
* warning and skips that project's `.crewly/` write.
|
|
116
|
+
*/
|
|
117
|
+
pathMap?: Record<string, string>;
|
|
118
|
+
/** ISO timestamp used to name the pre-restore rollback snapshot. */
|
|
119
|
+
now: string;
|
|
120
|
+
}
|
|
121
|
+
/** One project's restore plan entry. */
|
|
122
|
+
export interface RestoreProjectPlan {
|
|
123
|
+
id: string;
|
|
124
|
+
name: string;
|
|
125
|
+
sourcePath: string;
|
|
126
|
+
/** Resolved target path (pathMap → existing sourcePath → null when unresolved). */
|
|
127
|
+
targetPath: string | null;
|
|
128
|
+
git: {
|
|
129
|
+
remote: string | null;
|
|
130
|
+
commit: string | null;
|
|
131
|
+
};
|
|
132
|
+
/** Whether the resolved target path currently exists on this machine. */
|
|
133
|
+
targetExists: boolean;
|
|
134
|
+
}
|
|
135
|
+
/** Non-destructive restore plan (dry-run). */
|
|
136
|
+
export interface RestorePlan {
|
|
137
|
+
/** False when mode='abort' and conflicts exist (apply would refuse). */
|
|
138
|
+
ok: boolean;
|
|
139
|
+
manifestCreatedAt: string;
|
|
140
|
+
sourceHomePath: string;
|
|
141
|
+
/** Stable ids present on BOTH the backup and this machine (would be overwritten). */
|
|
142
|
+
conflicts: {
|
|
143
|
+
teams: string[];
|
|
144
|
+
projects: string[];
|
|
145
|
+
};
|
|
146
|
+
globalFileCount: number;
|
|
147
|
+
projects: RestoreProjectPlan[];
|
|
148
|
+
chatDbIncluded: boolean;
|
|
149
|
+
/** Things to regenerate (device identity) / discard (runtime/session). */
|
|
150
|
+
regenerated: string[];
|
|
151
|
+
discarded: string[];
|
|
152
|
+
warnings: string[];
|
|
153
|
+
}
|
|
154
|
+
/** Result of an applied restore. */
|
|
155
|
+
export interface RestoreResult {
|
|
156
|
+
restoredGlobalFiles: number;
|
|
157
|
+
restoredProjects: number;
|
|
158
|
+
chatDbRestored: boolean;
|
|
159
|
+
/** Where the pre-restore snapshot of the current CREWLY_HOME was saved. */
|
|
160
|
+
rollbackSnapshotPath: string;
|
|
161
|
+
warnings: string[];
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=backup.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup.types.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/backup/backup.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the Workspace Backup feature.
|
|
3
|
+
*
|
|
4
|
+
* A backup is a single `.tar.gz` archive containing a top-level
|
|
5
|
+
* `manifest.json` plus the captured `CREWLY_HOME` globals, each project's
|
|
6
|
+
* `.crewly/` tree, and (optionally) `chat.db`. See
|
|
7
|
+
* specs/2026-06-07-workspace-backup.md.
|
|
8
|
+
*
|
|
9
|
+
* @module services/backup/backup.types
|
|
10
|
+
*/
|
|
11
|
+
/** Manifest schema version — bump on any breaking layout/field change. */
|
|
12
|
+
export const BACKUP_SCHEMA_VERSION = 1;
|
|
13
|
+
//# sourceMappingURL=backup.types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup.types.js","sourceRoot":"","sources":["../../../../../../backend/src/services/backup/backup.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC"}
|
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud Client Service
|
|
3
|
+
*
|
|
4
|
+
* Singleton service responsible for all interactions with CrewlyAI Cloud.
|
|
5
|
+
* Handles authentication, premium template fetching, and subscription
|
|
6
|
+
* status synchronization.
|
|
7
|
+
*
|
|
8
|
+
* Premium templates are loaded into memory only — never written to disk
|
|
9
|
+
* to prevent IP leakage.
|
|
10
|
+
*
|
|
11
|
+
* @module services/cloud/cloud-client.service
|
|
12
|
+
*/
|
|
13
|
+
import { type CloudTier, type CloudConnectionStatus } from '../../constants.js';
|
|
14
|
+
/**
|
|
15
|
+
* Persisted cloud config stored at ~/.crewly/cloud/config.json.
|
|
16
|
+
* Enables auto-reconnect on backend restart.
|
|
17
|
+
*/
|
|
18
|
+
export interface PersistedCloudConfig {
|
|
19
|
+
cloudUrl: string;
|
|
20
|
+
token: string;
|
|
21
|
+
tier: string;
|
|
22
|
+
connectedAt: string;
|
|
23
|
+
/** Refresh token for auto-renewing expired access tokens */
|
|
24
|
+
refreshToken?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Relay-signed access JWT (distinct from the access `token`). Persisted so
|
|
27
|
+
* the BrowserProxy can re-register on backend restart without waiting for a
|
|
28
|
+
* fresh validate round-trip. Never the Google/Supabase token — see the
|
|
29
|
+
* RELAY-TOKEN-TYPE invariant in the long-term browser-relay fix design.
|
|
30
|
+
*/
|
|
31
|
+
relayToken?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Decode the `exp` (expiry, seconds since epoch) claim from a JWT without
|
|
35
|
+
* verifying its signature. Returns null when the token is malformed or has
|
|
36
|
+
* no `exp`. Used to schedule proactive relay-token refresh before expiry so
|
|
37
|
+
* a continuously-open relay socket never carries an expired token.
|
|
38
|
+
*
|
|
39
|
+
* @param token - JWT string (may be null)
|
|
40
|
+
* @returns The `exp` claim in seconds, or null when unavailable
|
|
41
|
+
*/
|
|
42
|
+
export declare function decodeJwtExp(token: string | null): number | null;
|
|
43
|
+
/** Summary of a premium template returned by the cloud listing endpoint. */
|
|
44
|
+
export interface CloudTemplateSummary {
|
|
45
|
+
/** Unique template identifier */
|
|
46
|
+
id: string;
|
|
47
|
+
/** Human-readable template name */
|
|
48
|
+
name: string;
|
|
49
|
+
/** Short description */
|
|
50
|
+
description: string;
|
|
51
|
+
/** Minimum subscription tier required */
|
|
52
|
+
requiredTier: CloudTier;
|
|
53
|
+
/** Category tag (e.g. "dev-team", "marketing") */
|
|
54
|
+
category: string;
|
|
55
|
+
}
|
|
56
|
+
/** Full detail for a single premium template (in-memory only). */
|
|
57
|
+
export interface CloudTemplateDetail {
|
|
58
|
+
/** Unique template identifier */
|
|
59
|
+
id: string;
|
|
60
|
+
/** Human-readable template name */
|
|
61
|
+
name: string;
|
|
62
|
+
/** Full description */
|
|
63
|
+
description: string;
|
|
64
|
+
/** Minimum subscription tier required */
|
|
65
|
+
requiredTier: CloudTier;
|
|
66
|
+
/** Category tag */
|
|
67
|
+
category: string;
|
|
68
|
+
/** Team member role definitions */
|
|
69
|
+
roles: Array<{
|
|
70
|
+
role: string;
|
|
71
|
+
prompt: string;
|
|
72
|
+
}>;
|
|
73
|
+
/** Task orchestration config */
|
|
74
|
+
orchestration: Record<string, unknown>;
|
|
75
|
+
}
|
|
76
|
+
/** A relay device returned by the Cloud devices API. */
|
|
77
|
+
export interface CloudRelayDevice {
|
|
78
|
+
/** Device/session ID */
|
|
79
|
+
sessionId: string;
|
|
80
|
+
/** Device role */
|
|
81
|
+
role: 'orchestrator' | 'agent';
|
|
82
|
+
/** Device state */
|
|
83
|
+
state: 'waiting' | 'paired' | 'disconnected';
|
|
84
|
+
/** Paired peer device ID */
|
|
85
|
+
pairedWith: string | null;
|
|
86
|
+
/** ISO registration timestamp */
|
|
87
|
+
registeredAt: string;
|
|
88
|
+
/** ISO last heartbeat timestamp */
|
|
89
|
+
lastHeartbeatAt: string;
|
|
90
|
+
/** Human-readable device name (legacy field) */
|
|
91
|
+
name?: string;
|
|
92
|
+
/** Human-readable device name returned by Cloud API */
|
|
93
|
+
deviceName?: string;
|
|
94
|
+
/** Unique device identifier */
|
|
95
|
+
deviceId?: string;
|
|
96
|
+
}
|
|
97
|
+
/** Current cloud connection state exposed by getStatus(). */
|
|
98
|
+
export interface CloudStatus {
|
|
99
|
+
/** Whether the client is currently connected */
|
|
100
|
+
connectionStatus: CloudConnectionStatus;
|
|
101
|
+
/** Cloud API base URL (set after connect) */
|
|
102
|
+
cloudUrl: string | null;
|
|
103
|
+
/** Current subscription tier */
|
|
104
|
+
tier: CloudTier;
|
|
105
|
+
/** ISO timestamp of last successful sync */
|
|
106
|
+
lastSyncAt: string | null;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* CloudClientService singleton.
|
|
110
|
+
*
|
|
111
|
+
* Manages the lifecycle of the connection between a local Crewly instance
|
|
112
|
+
* and CrewlyAI Cloud. All cloud API calls are made via native fetch with
|
|
113
|
+
* bearer-token authentication.
|
|
114
|
+
*/
|
|
115
|
+
export declare class CloudClientService {
|
|
116
|
+
private static instance;
|
|
117
|
+
private readonly logger;
|
|
118
|
+
/** Cloud API base URL (e.g. "https://api.crewlyai.com") */
|
|
119
|
+
private cloudUrl;
|
|
120
|
+
/** Bearer token obtained during connect() */
|
|
121
|
+
private token;
|
|
122
|
+
/** Refresh token for auto-renewing expired access tokens */
|
|
123
|
+
private refreshToken;
|
|
124
|
+
/** Current connection status */
|
|
125
|
+
private connectionStatus;
|
|
126
|
+
/** Subscription tier reported by cloud */
|
|
127
|
+
private tier;
|
|
128
|
+
/** Timestamp of the most recent successful cloud API call */
|
|
129
|
+
private lastSyncAt;
|
|
130
|
+
/** Timer for proactive token refresh (fires 5 min before expiry) */
|
|
131
|
+
private refreshTimer;
|
|
132
|
+
/** Guard to prevent concurrent refresh attempts */
|
|
133
|
+
private refreshInProgress;
|
|
134
|
+
/** Callbacks invoked when the access token is refreshed */
|
|
135
|
+
private tokenRefreshCallbacks;
|
|
136
|
+
/**
|
|
137
|
+
* Relay-signed access JWT used by BrowserProxyService to register with the
|
|
138
|
+
* Cloud Relay as role 'agent'. First-class, stored credential — distinct
|
|
139
|
+
* from the access `token` and decoupled from socket lifetime. NEVER the
|
|
140
|
+
* Google/Supabase access token (RELAY-TOKEN-TYPE invariant).
|
|
141
|
+
*/
|
|
142
|
+
private relayToken;
|
|
143
|
+
/** Parsed `exp` (seconds) of {@link relayToken}, for proactive refresh. */
|
|
144
|
+
private relayTokenExp;
|
|
145
|
+
/** Timer for proactive relay-token refresh (fires SKEW before exp). */
|
|
146
|
+
private relayRefreshTimer;
|
|
147
|
+
/** Callbacks invoked when the relay token is refreshed (distinct channel). */
|
|
148
|
+
private relayTokenRefreshCallbacks;
|
|
149
|
+
private constructor();
|
|
150
|
+
/**
|
|
151
|
+
* Get the singleton instance.
|
|
152
|
+
*
|
|
153
|
+
* @returns CloudClientService instance
|
|
154
|
+
*/
|
|
155
|
+
static getInstance(): CloudClientService;
|
|
156
|
+
/**
|
|
157
|
+
* Reset the singleton (for testing).
|
|
158
|
+
*/
|
|
159
|
+
static resetInstance(): void;
|
|
160
|
+
/**
|
|
161
|
+
* Connect to CrewlyAI Cloud by verifying the provided token.
|
|
162
|
+
*
|
|
163
|
+
* Calls the cloud auth endpoint to validate credentials and retrieve
|
|
164
|
+
* the subscription tier. On success the service transitions to
|
|
165
|
+
* "connected" status.
|
|
166
|
+
*
|
|
167
|
+
* @param cloudUrl - Base URL of the CrewlyAI Cloud API
|
|
168
|
+
* @param token - Authentication token (API key or JWT)
|
|
169
|
+
* @returns Object with connection result
|
|
170
|
+
* @throws Error when the auth request fails or token is invalid
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```ts
|
|
174
|
+
* const client = CloudClientService.getInstance();
|
|
175
|
+
* await client.connect('https://api.crewlyai.com', 'sk-abc123');
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
connect(cloudUrl: string, token: string, refreshToken?: string): Promise<{
|
|
179
|
+
success: boolean;
|
|
180
|
+
tier: CloudTier;
|
|
181
|
+
}>;
|
|
182
|
+
/**
|
|
183
|
+
* Connect using a locally verified JWT (no remote API call needed).
|
|
184
|
+
*
|
|
185
|
+
* Used when the JWT was issued by this same instance or the JWT secret
|
|
186
|
+
* is shared between OSS and Cloud. Avoids the round-trip to the cloud
|
|
187
|
+
* auth endpoint.
|
|
188
|
+
*
|
|
189
|
+
* @param cloudUrl - Base URL of the CrewlyAI Cloud API
|
|
190
|
+
* @param token - JWT access token (already verified locally)
|
|
191
|
+
* @param tier - Subscription tier extracted from the JWT payload
|
|
192
|
+
* @param refreshToken - Optional refresh token for auto-renewal
|
|
193
|
+
*/
|
|
194
|
+
connectLocal(cloudUrl: string, token: string, tier: CloudTier, refreshToken?: string): void;
|
|
195
|
+
/**
|
|
196
|
+
* Disconnect from CrewlyAI Cloud.
|
|
197
|
+
*
|
|
198
|
+
* Clears stored credentials and resets the connection state.
|
|
199
|
+
*/
|
|
200
|
+
disconnect(): void;
|
|
201
|
+
/**
|
|
202
|
+
* Path to the persisted cloud config file.
|
|
203
|
+
*/
|
|
204
|
+
static getConfigPath(): string;
|
|
205
|
+
/**
|
|
206
|
+
* Load persisted cloud config from disk.
|
|
207
|
+
* Returns null if file doesn't exist or is invalid.
|
|
208
|
+
*/
|
|
209
|
+
loadPersistedConfig(): Promise<PersistedCloudConfig | null>;
|
|
210
|
+
/**
|
|
211
|
+
* Persist current cloud connection config to disk for auto-reconnect.
|
|
212
|
+
*/
|
|
213
|
+
private persistConfig;
|
|
214
|
+
/**
|
|
215
|
+
* Remove persisted cloud config from disk (on disconnect).
|
|
216
|
+
*/
|
|
217
|
+
private removePersistedConfig;
|
|
218
|
+
/**
|
|
219
|
+
* Fetch the list of premium templates available on CrewlyAI Cloud.
|
|
220
|
+
*
|
|
221
|
+
* Requires an active cloud connection.
|
|
222
|
+
*
|
|
223
|
+
* @returns Array of template summaries
|
|
224
|
+
* @throws Error when not connected or fetch fails
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```ts
|
|
228
|
+
* const templates = await client.getTemplates();
|
|
229
|
+
* console.log(templates.map(t => t.name));
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
getTemplates(): Promise<CloudTemplateSummary[]>;
|
|
233
|
+
/**
|
|
234
|
+
* Fetch full detail for a single premium template.
|
|
235
|
+
*
|
|
236
|
+
* The returned data is held in memory only and must never be
|
|
237
|
+
* persisted to disk.
|
|
238
|
+
*
|
|
239
|
+
* @param id - Template identifier
|
|
240
|
+
* @returns Template detail object
|
|
241
|
+
* @throws Error when not connected, template not found, or fetch fails
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```ts
|
|
245
|
+
* const detail = await client.getTemplateDetail('tpl-tiktok-ops');
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
248
|
+
getTemplateDetail(id: string): Promise<CloudTemplateDetail>;
|
|
249
|
+
/**
|
|
250
|
+
* Get the stored cloud API base URL (set during connect).
|
|
251
|
+
*
|
|
252
|
+
* @returns Cloud URL or null if not connected
|
|
253
|
+
*/
|
|
254
|
+
getCloudUrl(): string | null;
|
|
255
|
+
/**
|
|
256
|
+
* Get the current cloud connection status and subscription tier.
|
|
257
|
+
*
|
|
258
|
+
* @returns Current status snapshot
|
|
259
|
+
*/
|
|
260
|
+
getStatus(): CloudStatus;
|
|
261
|
+
/**
|
|
262
|
+
* Check whether the client is currently connected to cloud.
|
|
263
|
+
*
|
|
264
|
+
* @returns true if connected
|
|
265
|
+
*/
|
|
266
|
+
isConnected(): boolean;
|
|
267
|
+
/**
|
|
268
|
+
* Check whether the cloud token has expired (401/403 from cloud API).
|
|
269
|
+
*
|
|
270
|
+
* @returns true if the token has expired
|
|
271
|
+
*/
|
|
272
|
+
isTokenExpired(): boolean;
|
|
273
|
+
/**
|
|
274
|
+
* Get the current subscription tier.
|
|
275
|
+
*
|
|
276
|
+
* @returns Current tier value
|
|
277
|
+
*/
|
|
278
|
+
getTier(): CloudTier;
|
|
279
|
+
/**
|
|
280
|
+
* Fetch the list of devices registered to this user from Cloud.
|
|
281
|
+
*
|
|
282
|
+
* Proxies GET /api/v1/relay/devices on crewlyai.com and returns
|
|
283
|
+
* the device list for the authenticated user.
|
|
284
|
+
*
|
|
285
|
+
* @returns Array of cloud relay devices
|
|
286
|
+
* @throws Error when not connected or fetch fails
|
|
287
|
+
*/
|
|
288
|
+
fetchCloudDevices(): Promise<CloudRelayDevice[]>;
|
|
289
|
+
/**
|
|
290
|
+
* Set the refresh token for auto-renewal.
|
|
291
|
+
*
|
|
292
|
+
* Called by the connect controller after OAuth login provides a refresh token.
|
|
293
|
+
*
|
|
294
|
+
* @param refreshToken - Refresh token string
|
|
295
|
+
*/
|
|
296
|
+
setRefreshToken(refreshToken: string): void;
|
|
297
|
+
/**
|
|
298
|
+
* Get the current access token (for CloudSyncService token updates).
|
|
299
|
+
*
|
|
300
|
+
* @returns Current access token or null
|
|
301
|
+
*/
|
|
302
|
+
getToken(): string | null;
|
|
303
|
+
/**
|
|
304
|
+
* Register a callback to be invoked whenever the access token is refreshed.
|
|
305
|
+
* Used by BrowserProxyService to update its relay auth token in real-time.
|
|
306
|
+
*
|
|
307
|
+
* @param callback - Function receiving the new access token string
|
|
308
|
+
*/
|
|
309
|
+
onTokenRefresh(callback: (newToken: string) => void): void;
|
|
310
|
+
/**
|
|
311
|
+
* Get the current relay-signed token (for BrowserProxyService registration).
|
|
312
|
+
*
|
|
313
|
+
* This is DISTINCT from {@link getToken} (the access/HTTP token). The
|
|
314
|
+
* BrowserProxy must register with the relay token, never the access token —
|
|
315
|
+
* see the RELAY-TOKEN-TYPE invariant. Returns null until a relay token has
|
|
316
|
+
* been minted by the Cloud validate/refresh endpoint.
|
|
317
|
+
*
|
|
318
|
+
* @returns Current relay token or null
|
|
319
|
+
*/
|
|
320
|
+
getRelayToken(): string | null;
|
|
321
|
+
/**
|
|
322
|
+
* Register a callback invoked whenever the relay token is refreshed.
|
|
323
|
+
*
|
|
324
|
+
* Distinct subscription channel from {@link onTokenRefresh}: subscribers
|
|
325
|
+
* here (BrowserProxyService) receive the relay-signed token, never the
|
|
326
|
+
* access token. Decoupling the channels prevents the proxy from ever being
|
|
327
|
+
* fed the wrong token type on refresh.
|
|
328
|
+
*
|
|
329
|
+
* @param callback - Function receiving the new relay token string
|
|
330
|
+
*/
|
|
331
|
+
onRelayTokenRefresh(callback: (newRelayToken: string) => void): void;
|
|
332
|
+
/**
|
|
333
|
+
* Store a freshly-minted relay token as a first-class credential, parse its
|
|
334
|
+
* expiry, schedule proactive refresh, persist it, and notify subscribers.
|
|
335
|
+
*
|
|
336
|
+
* Centralizes relay-token handling so every code path that obtains one
|
|
337
|
+
* (connect, refresh, validate) treats it identically. Persistence is
|
|
338
|
+
* fire-and-forget; a persist failure must not break the refresh chain.
|
|
339
|
+
*
|
|
340
|
+
* @param relayToken - The relay-signed access JWT from Cloud
|
|
341
|
+
*/
|
|
342
|
+
private storeRelayToken;
|
|
343
|
+
/**
|
|
344
|
+
* Attempt to refresh the access token using the stored refresh token.
|
|
345
|
+
*
|
|
346
|
+
* Issues a new access token locally (since both access and refresh tokens
|
|
347
|
+
* are signed with the same HMAC secret on this OSS instance).
|
|
348
|
+
*
|
|
349
|
+
* @returns true if refresh succeeded, false if no refresh token or refresh failed
|
|
350
|
+
*/
|
|
351
|
+
tryRefreshToken(): Promise<boolean>;
|
|
352
|
+
/**
|
|
353
|
+
* Schedule a proactive token refresh 5 minutes before expiry.
|
|
354
|
+
*
|
|
355
|
+
* Parses the JWT `exp` claim and sets a timer. If the token has
|
|
356
|
+
* less than 5 minutes remaining, refreshes immediately.
|
|
357
|
+
*
|
|
358
|
+
* @param token - JWT access token to extract expiry from
|
|
359
|
+
*/
|
|
360
|
+
private scheduleTokenRefresh;
|
|
361
|
+
/**
|
|
362
|
+
* Schedule a proactive relay-token refresh `RELAY_REFRESH_SKEW_S` seconds
|
|
363
|
+
* before the relay token's real `exp`.
|
|
364
|
+
*
|
|
365
|
+
* The relay token (~60min TTL) is decoupled from the access token, so it
|
|
366
|
+
* needs its own refresh schedule. When the timer fires it calls
|
|
367
|
+
* {@link fetchRelayTokenFromValidate}, which re-mints a relay token and
|
|
368
|
+
* stores it (re-arming this timer). This keeps a continuously-open relay
|
|
369
|
+
* socket from ever carrying an expired token — the DURABLE-CREDENTIAL
|
|
370
|
+
* invariant. Driven by the JWT `exp` claim, not a wall-clock heuristic.
|
|
371
|
+
*/
|
|
372
|
+
private scheduleRelayTokenRefresh;
|
|
373
|
+
/**
|
|
374
|
+
* Fetch relay token by calling Cloud validate endpoint.
|
|
375
|
+
* Used after connectLocal() to get a Cloud-signed relay JWT
|
|
376
|
+
* without blocking the connection flow.
|
|
377
|
+
*
|
|
378
|
+
* @returns Promise that resolves when relay token is fetched (or skipped)
|
|
379
|
+
*/
|
|
380
|
+
private fetchRelayTokenFromValidate;
|
|
381
|
+
/**
|
|
382
|
+
* Throw if the client is not in a connected state.
|
|
383
|
+
*
|
|
384
|
+
* @throws Error when not connected
|
|
385
|
+
*/
|
|
386
|
+
private ensureConnected;
|
|
387
|
+
/**
|
|
388
|
+
* Build the standard authorization headers for cloud API requests.
|
|
389
|
+
*
|
|
390
|
+
* @returns Headers object with Authorization and Content-Type
|
|
391
|
+
*/
|
|
392
|
+
private authHeaders;
|
|
393
|
+
/**
|
|
394
|
+
* Check if an HTTP status code indicates an authentication/authorization failure.
|
|
395
|
+
*
|
|
396
|
+
* @param status - HTTP status code
|
|
397
|
+
* @returns true if the status is 401 or 403
|
|
398
|
+
*/
|
|
399
|
+
private isAuthError;
|
|
400
|
+
/**
|
|
401
|
+
* Handle a 401/403 response from the cloud API by transitioning
|
|
402
|
+
* the connection status to TOKEN_EXPIRED. This signals the frontend
|
|
403
|
+
* to show a reconnect prompt instead of a raw error.
|
|
404
|
+
*
|
|
405
|
+
* @param context - Description of the failed operation (for logging)
|
|
406
|
+
* @param status - HTTP status code from the cloud API
|
|
407
|
+
*/
|
|
408
|
+
private handleAuthFailure;
|
|
409
|
+
}
|
|
410
|
+
//# sourceMappingURL=cloud-client.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-client.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/cloud/cloud-client.service.ts"],"names":[],"mappings":"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"}
|