crewly 1.20.411 → 1.20.412
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/backend/backend/src/constants.d.ts +25 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +25 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team-export.controller.d.ts +11 -2
- package/dist/backend/backend/src/controllers/team/team-export.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team-export.controller.js +35 -5
- package/dist/backend/backend/src/controllers/team/team-export.controller.js.map +1 -1
- package/dist/backend/backend/src/services/core/team-export.service.d.ts +85 -9
- package/dist/backend/backend/src/services/core/team-export.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/core/team-export.service.js +130 -16
- package/dist/backend/backend/src/services/core/team-export.service.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +25 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +25 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/cli/src/commands/team-export.d.ts +58 -0
- package/dist/cli/cli/src/commands/team-export.d.ts.map +1 -0
- package/dist/cli/cli/src/commands/team-export.js +174 -0
- package/dist/cli/cli/src/commands/team-export.js.map +1 -0
- package/dist/cli/cli/src/index.js +17 -1
- package/dist/cli/cli/src/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -9,10 +9,19 @@
|
|
|
9
9
|
import type { Request, Response } from 'express';
|
|
10
10
|
import type { ApiContext } from '../types.js';
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* A safe file name for a downloaded package.
|
|
13
|
+
*
|
|
14
|
+
* @param teamName - Team name
|
|
15
|
+
* @returns e.g. `crewly-team-ce-site.json`
|
|
16
|
+
*/
|
|
17
|
+
export declare function exportFileName(teamName: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* GET /api/teams/:teamId/export[?download=1]
|
|
13
20
|
*
|
|
14
21
|
* Exports a team and all associated data (config, prompts, norms, cron tasks)
|
|
15
|
-
* as a single JSON bundle for backup or migration
|
|
22
|
+
* as a single portable, secret-free JSON bundle for backup or migration
|
|
23
|
+
* (#880). Owner only. With `download=1` the package itself is the body, as
|
|
24
|
+
* an attachment; otherwise it sits under `data`.
|
|
16
25
|
*
|
|
17
26
|
* @param req - Express request with teamId parameter
|
|
18
27
|
* @param res - Express response with TeamExport JSON
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-export.controller.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/controllers/team/team-export.controller.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"team-export.controller.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/controllers/team/team-export.controller.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAW9C;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB7F;AAED;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB7F"}
|
|
@@ -8,20 +8,45 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { TeamExportService } from '../../services/core/team-export.service.js';
|
|
10
10
|
import { formatError } from '../../utils/format-error.js';
|
|
11
|
+
import { rejectNonOwner } from '../../middleware/caller-identity.middleware.js';
|
|
12
|
+
import { collectSecretEnvValues } from '../../utils/secret-env.js';
|
|
13
|
+
import { TEAM_EXPORT_CONSTANTS } from '../../constants.js';
|
|
14
|
+
/** The refusal an agent gets: a package holds every prompt and schedule of a team. */
|
|
15
|
+
const OWNER_ONLY = { success: false, error: 'owner_only', message: 'Only the owner can export or import a team package.' };
|
|
11
16
|
/**
|
|
12
|
-
*
|
|
17
|
+
* A safe file name for a downloaded package.
|
|
18
|
+
*
|
|
19
|
+
* @param teamName - Team name
|
|
20
|
+
* @returns e.g. `crewly-team-ce-site.json`
|
|
21
|
+
*/
|
|
22
|
+
export function exportFileName(teamName) {
|
|
23
|
+
const slug = teamName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'team';
|
|
24
|
+
return TEAM_EXPORT_CONSTANTS.DOWNLOAD_FILE_NAME.replace('<slug>', slug);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* GET /api/teams/:teamId/export[?download=1]
|
|
13
28
|
*
|
|
14
29
|
* Exports a team and all associated data (config, prompts, norms, cron tasks)
|
|
15
|
-
* as a single JSON bundle for backup or migration
|
|
30
|
+
* as a single portable, secret-free JSON bundle for backup or migration
|
|
31
|
+
* (#880). Owner only. With `download=1` the package itself is the body, as
|
|
32
|
+
* an attachment; otherwise it sits under `data`.
|
|
16
33
|
*
|
|
17
34
|
* @param req - Express request with teamId parameter
|
|
18
35
|
* @param res - Express response with TeamExport JSON
|
|
19
36
|
*/
|
|
20
37
|
export async function exportTeam(req, res) {
|
|
38
|
+
if (rejectNonOwner(req, res, OWNER_ONLY))
|
|
39
|
+
return;
|
|
21
40
|
const { teamId } = req.params;
|
|
22
41
|
try {
|
|
23
42
|
const service = new TeamExportService(this.storageService);
|
|
24
|
-
const exportData = await service.exportTeam(teamId);
|
|
43
|
+
const exportData = await service.exportTeam(teamId, { knownSecrets: collectSecretEnvValues(process.env) });
|
|
44
|
+
if (req.query['download'] === '1' || req.query['download'] === 'true') {
|
|
45
|
+
res.setHeader('Content-Type', 'application/json');
|
|
46
|
+
res.setHeader('Content-Disposition', `attachment; filename="${exportFileName(exportData.team.name)}"`);
|
|
47
|
+
res.send(JSON.stringify(exportData, null, 2));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
25
50
|
res.json({ success: true, data: exportData });
|
|
26
51
|
}
|
|
27
52
|
catch (error) {
|
|
@@ -41,7 +66,11 @@ export async function exportTeam(req, res) {
|
|
|
41
66
|
* @param res - Express response with import result
|
|
42
67
|
*/
|
|
43
68
|
export async function importTeam(req, res) {
|
|
44
|
-
|
|
69
|
+
if (rejectNonOwner(req, res, OWNER_ONLY))
|
|
70
|
+
return;
|
|
71
|
+
// `crewly team export` writes the package itself; a saved API answer still has it under `data`.
|
|
72
|
+
const raw = req.body;
|
|
73
|
+
const data = (raw && typeof raw === 'object' && 'data' in raw && raw.data && typeof raw.data === 'object' ? raw.data : raw);
|
|
45
74
|
if (!data.version || !data.team) {
|
|
46
75
|
res.status(400).json({
|
|
47
76
|
success: false,
|
|
@@ -55,7 +84,8 @@ export async function importTeam(req, res) {
|
|
|
55
84
|
res.json({ success: true, data: result });
|
|
56
85
|
}
|
|
57
86
|
catch (error) {
|
|
58
|
-
|
|
87
|
+
const message = formatError(error);
|
|
88
|
+
res.status(message.startsWith('Unsupported team export version') ? 400 : 500).json({ success: false, message });
|
|
59
89
|
}
|
|
60
90
|
}
|
|
61
91
|
//# sourceMappingURL=team-export.controller.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-export.controller.js","sourceRoot":"","sources":["../../../../../../backend/src/controllers/team/team-export.controller.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAE/E,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"team-export.controller.js","sourceRoot":"","sources":["../../../../../../backend/src/controllers/team/team-export.controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,16 +2,37 @@
|
|
|
2
2
|
* Team Export/Import Service
|
|
3
3
|
*
|
|
4
4
|
* Bundles a team's config, prompts, norms, and cron tasks into a single
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* portable JSON document, and recreates a team from one (issue #880,
|
|
6
|
+
* specs/2026-10-25-team-export-portable.md).
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* A package is portable and secret-free:
|
|
9
|
+
* - the running agent's state (session, status, tickets in hand, login /
|
|
10
|
+
* usage flags) is stripped — the package describes the team, not this
|
|
11
|
+
* install's processes;
|
|
12
|
+
* - every string passes through the secret redactor
|
|
13
|
+
* (`utils/secret-redactor`), and the whole package is scanned once more
|
|
14
|
+
* before it is returned;
|
|
15
|
+
* - the connectors the team's prompts, skills and schedules refer to are
|
|
16
|
+
* listed under `portability.connectors` so the importer knows what to
|
|
17
|
+
* reconnect — grants themselves never travel.
|
|
9
18
|
*
|
|
10
19
|
* @module services/core/team-export.service
|
|
11
20
|
*/
|
|
12
21
|
import type { Team } from '../../types/index.js';
|
|
13
22
|
import type { CronTask } from '../../types/cron-task.types.js';
|
|
14
23
|
import type { StorageService } from './storage.service.js';
|
|
24
|
+
import type { SecretEnvValue } from '../../utils/secret-env.js';
|
|
25
|
+
/** What makes a package portable: what was stripped, masked and must be reconnected. */
|
|
26
|
+
export interface TeamExportPortability {
|
|
27
|
+
/** Secrets masked across the package */
|
|
28
|
+
redactions: number;
|
|
29
|
+
/** Whether a final scan of the serialized package found nothing left to mask */
|
|
30
|
+
scanClean: boolean;
|
|
31
|
+
/** Connectors the team refers to; none of their grants are in the package */
|
|
32
|
+
connectors: string[];
|
|
33
|
+
/** Member fields removed because they describe the running agent, not the team */
|
|
34
|
+
strippedFields: string[];
|
|
35
|
+
}
|
|
15
36
|
/**
|
|
16
37
|
* Complete team export bundle containing all team data.
|
|
17
38
|
*
|
|
@@ -19,10 +40,10 @@ import type { StorageService } from './storage.service.js';
|
|
|
19
40
|
*/
|
|
20
41
|
export interface TeamExport {
|
|
21
42
|
/** Format version for forward compatibility */
|
|
22
|
-
version: '1.0';
|
|
43
|
+
version: '1.0' | '1.1';
|
|
23
44
|
/** ISO timestamp when the export was created */
|
|
24
45
|
exportedAt: string;
|
|
25
|
-
/** Team configuration (config.json content) */
|
|
46
|
+
/** Team configuration (config.json content), runtime state stripped */
|
|
26
47
|
team: Team;
|
|
27
48
|
/** Member prompts: memberId → prompt content */
|
|
28
49
|
prompts: Record<string, string>;
|
|
@@ -30,6 +51,8 @@ export interface TeamExport {
|
|
|
30
51
|
norms: Record<string, string>;
|
|
31
52
|
/** Team-scoped cron tasks */
|
|
32
53
|
cronTasks: CronTask[];
|
|
54
|
+
/** What was stripped, masked and must be reconnected (1.1+) */
|
|
55
|
+
portability?: TeamExportPortability;
|
|
33
56
|
}
|
|
34
57
|
/**
|
|
35
58
|
* Result of a team import operation.
|
|
@@ -43,7 +66,57 @@ export interface TeamImportResult {
|
|
|
43
66
|
normsImported: number;
|
|
44
67
|
/** Number of cron tasks created (with new IDs) */
|
|
45
68
|
cronTasksImported: number;
|
|
69
|
+
/** Connectors the package says the team uses; reconnect them on this install */
|
|
70
|
+
connectorsToReconnect: string[];
|
|
71
|
+
}
|
|
72
|
+
/** Options of {@link TeamExportService.exportTeam}. */
|
|
73
|
+
export interface TeamExportOptions {
|
|
74
|
+
/** Exact secret values to mask wherever they appear (see collectSecretEnvValues) */
|
|
75
|
+
knownSecrets?: readonly SecretEnvValue[];
|
|
46
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* A copy of a team without this install's runtime state: every member is
|
|
79
|
+
* inactive and idle with no session, and the fields that describe the
|
|
80
|
+
* running agent are gone.
|
|
81
|
+
*
|
|
82
|
+
* @param team - Team as stored
|
|
83
|
+
* @returns The portable team and the member field names that were removed
|
|
84
|
+
*/
|
|
85
|
+
export declare function stripRuntimeState(team: Team): {
|
|
86
|
+
team: Team;
|
|
87
|
+
strippedFields: string[];
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Mask secrets in every string of a JSON-ish value, recursively.
|
|
91
|
+
*
|
|
92
|
+
* @param value - Any JSON value
|
|
93
|
+
* @param knownSecrets - Exact values to mask
|
|
94
|
+
* @returns The masked value and how many secrets were masked
|
|
95
|
+
*/
|
|
96
|
+
export declare function redactDeep<T>(value: T, knownSecrets?: readonly SecretEnvValue[]): {
|
|
97
|
+
value: T;
|
|
98
|
+
count: number;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* The connectors a team refers to, from its members' prompts, skills and
|
|
102
|
+
* roles, its norms and its schedules. Matching is by the words in
|
|
103
|
+
* `TEAM_EXPORT_CONSTANTS.CONNECTOR_HINTS`; a hit means "reconnect this
|
|
104
|
+
* after import", never that a grant is included.
|
|
105
|
+
*
|
|
106
|
+
* @param team - Team
|
|
107
|
+
* @param prompts - Member prompts
|
|
108
|
+
* @param norms - Norms
|
|
109
|
+
* @param cronTasks - Schedules
|
|
110
|
+
* @returns Connector ids, sorted
|
|
111
|
+
*/
|
|
112
|
+
export declare function referencedConnectors(team: Team, prompts: Record<string, string>, norms: Record<string, string>, cronTasks: CronTask[]): string[];
|
|
113
|
+
/**
|
|
114
|
+
* Whether a package version can be imported.
|
|
115
|
+
*
|
|
116
|
+
* @param version - `version` of a package
|
|
117
|
+
* @returns True for a supported version
|
|
118
|
+
*/
|
|
119
|
+
export declare function isSupportedExportVersion(version: unknown): version is TeamExport['version'];
|
|
47
120
|
/**
|
|
48
121
|
* Service for exporting and importing complete team bundles.
|
|
49
122
|
*
|
|
@@ -59,7 +132,8 @@ export declare class TeamExportService {
|
|
|
59
132
|
*/
|
|
60
133
|
constructor(storageService: StorageService);
|
|
61
134
|
/**
|
|
62
|
-
* Export a team and all its associated data as a single JSON
|
|
135
|
+
* Export a team and all its associated data as a single portable JSON
|
|
136
|
+
* bundle: runtime state stripped, secrets masked, connectors listed.
|
|
63
137
|
*
|
|
64
138
|
* Collects:
|
|
65
139
|
* - Team config (config.json)
|
|
@@ -68,22 +142,24 @@ export declare class TeamExportService {
|
|
|
68
142
|
* - Cron tasks (cron-tasks.json)
|
|
69
143
|
*
|
|
70
144
|
* @param teamId - ID of the team to export
|
|
145
|
+
* @param options - Known secret values to mask
|
|
71
146
|
* @returns Complete team export bundle
|
|
72
147
|
* @throws Error if team not found
|
|
73
148
|
*/
|
|
74
|
-
exportTeam(teamId: string): Promise<TeamExport>;
|
|
149
|
+
exportTeam(teamId: string, options?: TeamExportOptions): Promise<TeamExport>;
|
|
75
150
|
/**
|
|
76
151
|
* Import a team from a complete export bundle.
|
|
77
152
|
*
|
|
78
153
|
* Creates:
|
|
79
|
-
* - Team via storageService.saveTeam()
|
|
154
|
+
* - Team via storageService.saveTeam() (runtime state stripped, so a 1.0
|
|
155
|
+
* package taken from a running team comes in idle too)
|
|
80
156
|
* - Prompts written to teams/{teamId}/prompts/
|
|
81
157
|
* - Norms written to teams/{teamId}/norms/
|
|
82
158
|
* - Cron tasks with NEW IDs to teams/{teamId}/cron-tasks.json
|
|
83
159
|
*
|
|
84
160
|
* @param data - The team export bundle to import
|
|
85
161
|
* @returns Import result with counts
|
|
86
|
-
* @throws Error if import data is invalid
|
|
162
|
+
* @throws Error if import data is invalid or of an unsupported version
|
|
87
163
|
*/
|
|
88
164
|
importTeam(data: TeamExport): Promise<TeamImportResult>;
|
|
89
165
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-export.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/core/team-export.service.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"team-export.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/core/team-export.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,10 +2,19 @@
|
|
|
2
2
|
* Team Export/Import Service
|
|
3
3
|
*
|
|
4
4
|
* Bundles a team's config, prompts, norms, and cron tasks into a single
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* portable JSON document, and recreates a team from one (issue #880,
|
|
6
|
+
* specs/2026-10-25-team-export-portable.md).
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* A package is portable and secret-free:
|
|
9
|
+
* - the running agent's state (session, status, tickets in hand, login /
|
|
10
|
+
* usage flags) is stripped — the package describes the team, not this
|
|
11
|
+
* install's processes;
|
|
12
|
+
* - every string passes through the secret redactor
|
|
13
|
+
* (`utils/secret-redactor`), and the whole package is scanned once more
|
|
14
|
+
* before it is returned;
|
|
15
|
+
* - the connectors the team's prompts, skills and schedules refer to are
|
|
16
|
+
* listed under `portability.connectors` so the importer knows what to
|
|
17
|
+
* reconnect — grants themselves never travel.
|
|
9
18
|
*
|
|
10
19
|
* @module services/core/team-export.service
|
|
11
20
|
*/
|
|
@@ -13,6 +22,97 @@ import fs from 'fs/promises';
|
|
|
13
22
|
import { existsSync, mkdirSync } from 'fs';
|
|
14
23
|
import * as path from 'path';
|
|
15
24
|
import * as crypto from 'crypto';
|
|
25
|
+
import { redactSecretsWithCount } from '../../utils/secret-redactor.js';
|
|
26
|
+
import { TEAM_EXPORT_CONSTANTS } from '../../constants.js';
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// Helpers
|
|
29
|
+
// =============================================================================
|
|
30
|
+
/**
|
|
31
|
+
* A copy of a team without this install's runtime state: every member is
|
|
32
|
+
* inactive and idle with no session, and the fields that describe the
|
|
33
|
+
* running agent are gone.
|
|
34
|
+
*
|
|
35
|
+
* @param team - Team as stored
|
|
36
|
+
* @returns The portable team and the member field names that were removed
|
|
37
|
+
*/
|
|
38
|
+
export function stripRuntimeState(team) {
|
|
39
|
+
const stripped = new Set();
|
|
40
|
+
const members = team.members.map((member) => {
|
|
41
|
+
const copy = { ...member };
|
|
42
|
+
for (const field of TEAM_EXPORT_CONSTANTS.RUNTIME_MEMBER_FIELDS) {
|
|
43
|
+
if (field in copy) {
|
|
44
|
+
delete copy[field];
|
|
45
|
+
stripped.add(field);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
copy['sessionName'] = '';
|
|
49
|
+
copy['agentStatus'] = 'inactive';
|
|
50
|
+
copy['workingStatus'] = 'idle';
|
|
51
|
+
return copy;
|
|
52
|
+
});
|
|
53
|
+
return { team: { ...team, members }, strippedFields: [...stripped].sort() };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Mask secrets in every string of a JSON-ish value, recursively.
|
|
57
|
+
*
|
|
58
|
+
* @param value - Any JSON value
|
|
59
|
+
* @param knownSecrets - Exact values to mask
|
|
60
|
+
* @returns The masked value and how many secrets were masked
|
|
61
|
+
*/
|
|
62
|
+
export function redactDeep(value, knownSecrets = []) {
|
|
63
|
+
let count = 0;
|
|
64
|
+
const walk = (v) => {
|
|
65
|
+
if (typeof v === 'string') {
|
|
66
|
+
const r = redactSecretsWithCount(v, knownSecrets);
|
|
67
|
+
count += r.count;
|
|
68
|
+
return r.text;
|
|
69
|
+
}
|
|
70
|
+
if (Array.isArray(v))
|
|
71
|
+
return v.map(walk);
|
|
72
|
+
if (v && typeof v === 'object') {
|
|
73
|
+
const out = {};
|
|
74
|
+
for (const [k, inner] of Object.entries(v))
|
|
75
|
+
out[k] = walk(inner);
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
return v;
|
|
79
|
+
};
|
|
80
|
+
return { value: walk(value), count };
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The connectors a team refers to, from its members' prompts, skills and
|
|
84
|
+
* roles, its norms and its schedules. Matching is by the words in
|
|
85
|
+
* `TEAM_EXPORT_CONSTANTS.CONNECTOR_HINTS`; a hit means "reconnect this
|
|
86
|
+
* after import", never that a grant is included.
|
|
87
|
+
*
|
|
88
|
+
* @param team - Team
|
|
89
|
+
* @param prompts - Member prompts
|
|
90
|
+
* @param norms - Norms
|
|
91
|
+
* @param cronTasks - Schedules
|
|
92
|
+
* @returns Connector ids, sorted
|
|
93
|
+
*/
|
|
94
|
+
export function referencedConnectors(team, prompts, norms, cronTasks) {
|
|
95
|
+
const texts = [
|
|
96
|
+
...team.members.flatMap((m) => [m.systemPrompt ?? '', m.role ?? '', ...(m.skillOverrides ?? []), ...(m.skills ?? [])]),
|
|
97
|
+
...Object.values(prompts),
|
|
98
|
+
...Object.values(norms),
|
|
99
|
+
...cronTasks.map((t) => t.taskDescription),
|
|
100
|
+
];
|
|
101
|
+
const haystack = texts.join('\n');
|
|
102
|
+
return Object.entries(TEAM_EXPORT_CONSTANTS.CONNECTOR_HINTS)
|
|
103
|
+
.filter(([, re]) => re.test(haystack))
|
|
104
|
+
.map(([id]) => id)
|
|
105
|
+
.sort();
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Whether a package version can be imported.
|
|
109
|
+
*
|
|
110
|
+
* @param version - `version` of a package
|
|
111
|
+
* @returns True for a supported version
|
|
112
|
+
*/
|
|
113
|
+
export function isSupportedExportVersion(version) {
|
|
114
|
+
return typeof version === 'string' && TEAM_EXPORT_CONSTANTS.SUPPORTED_VERSIONS.includes(version);
|
|
115
|
+
}
|
|
16
116
|
// =============================================================================
|
|
17
117
|
// Service
|
|
18
118
|
// =============================================================================
|
|
@@ -33,7 +133,8 @@ export class TeamExportService {
|
|
|
33
133
|
this.storageService = storageService;
|
|
34
134
|
}
|
|
35
135
|
/**
|
|
36
|
-
* Export a team and all its associated data as a single JSON
|
|
136
|
+
* Export a team and all its associated data as a single portable JSON
|
|
137
|
+
* bundle: runtime state stripped, secrets masked, connectors listed.
|
|
37
138
|
*
|
|
38
139
|
* Collects:
|
|
39
140
|
* - Team config (config.json)
|
|
@@ -42,13 +143,14 @@ export class TeamExportService {
|
|
|
42
143
|
* - Cron tasks (cron-tasks.json)
|
|
43
144
|
*
|
|
44
145
|
* @param teamId - ID of the team to export
|
|
146
|
+
* @param options - Known secret values to mask
|
|
45
147
|
* @returns Complete team export bundle
|
|
46
148
|
* @throws Error if team not found
|
|
47
149
|
*/
|
|
48
|
-
async exportTeam(teamId) {
|
|
150
|
+
async exportTeam(teamId, options = {}) {
|
|
49
151
|
const teams = await this.storageService.getTeams();
|
|
50
|
-
const
|
|
51
|
-
if (!
|
|
152
|
+
const stored = teams.find((t) => t.id === teamId);
|
|
153
|
+
if (!stored) {
|
|
52
154
|
throw new Error(`Team not found: ${teamId}`);
|
|
53
155
|
}
|
|
54
156
|
const teamDir = this.storageService.getTeamDir(teamId);
|
|
@@ -85,34 +187,44 @@ export class TeamExportService {
|
|
|
85
187
|
}
|
|
86
188
|
// Read cron tasks
|
|
87
189
|
const cronTasks = await this.readCronTasks(teamDir);
|
|
88
|
-
|
|
89
|
-
|
|
190
|
+
const { team, strippedFields } = stripRuntimeState(stored);
|
|
191
|
+
const connectors = referencedConnectors(team, prompts, norms, cronTasks);
|
|
192
|
+
const masked = redactDeep({ team, prompts, norms, cronTasks }, options.knownSecrets);
|
|
193
|
+
const portability = { redactions: masked.count, scanClean: true, connectors, strippedFields };
|
|
194
|
+
const bundle = {
|
|
195
|
+
version: TEAM_EXPORT_CONSTANTS.VERSION,
|
|
90
196
|
exportedAt: new Date().toISOString(),
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
norms,
|
|
94
|
-
cronTasks,
|
|
197
|
+
...masked.value,
|
|
198
|
+
portability,
|
|
95
199
|
};
|
|
200
|
+
// One more pass over the serialized package: anything the deep walk could
|
|
201
|
+
// not see (a key name, a number rendered as text) would show up here.
|
|
202
|
+
portability.scanClean = redactSecretsWithCount(JSON.stringify(bundle), options.knownSecrets).count === 0;
|
|
203
|
+
return bundle;
|
|
96
204
|
}
|
|
97
205
|
/**
|
|
98
206
|
* Import a team from a complete export bundle.
|
|
99
207
|
*
|
|
100
208
|
* Creates:
|
|
101
|
-
* - Team via storageService.saveTeam()
|
|
209
|
+
* - Team via storageService.saveTeam() (runtime state stripped, so a 1.0
|
|
210
|
+
* package taken from a running team comes in idle too)
|
|
102
211
|
* - Prompts written to teams/{teamId}/prompts/
|
|
103
212
|
* - Norms written to teams/{teamId}/norms/
|
|
104
213
|
* - Cron tasks with NEW IDs to teams/{teamId}/cron-tasks.json
|
|
105
214
|
*
|
|
106
215
|
* @param data - The team export bundle to import
|
|
107
216
|
* @returns Import result with counts
|
|
108
|
-
* @throws Error if import data is invalid
|
|
217
|
+
* @throws Error if import data is invalid or of an unsupported version
|
|
109
218
|
*/
|
|
110
219
|
async importTeam(data) {
|
|
111
220
|
if (!data.version || !data.team) {
|
|
112
221
|
throw new Error('Invalid team export format: missing version or team data');
|
|
113
222
|
}
|
|
223
|
+
if (!isSupportedExportVersion(data.version)) {
|
|
224
|
+
throw new Error(`Unsupported team export version: ${String(data.version)} (this Crewly reads ${TEAM_EXPORT_CONSTANTS.SUPPORTED_VERSIONS.join(', ')})`);
|
|
225
|
+
}
|
|
114
226
|
// Save the team config
|
|
115
|
-
const team = data.team;
|
|
227
|
+
const { team } = stripRuntimeState(data.team);
|
|
116
228
|
await this.storageService.saveTeam(team);
|
|
117
229
|
const teamDir = this.storageService.getTeamDir(team.id);
|
|
118
230
|
// Write prompts
|
|
@@ -146,11 +258,13 @@ export class TeamExportService {
|
|
|
146
258
|
await fs.writeFile(cronPath, JSON.stringify(cronStore, null, 2), 'utf8');
|
|
147
259
|
cronTasksImported = remapped.length;
|
|
148
260
|
}
|
|
261
|
+
const connectorsToReconnect = data.portability?.connectors ?? referencedConnectors(team, data.prompts ?? {}, data.norms ?? {}, data.cronTasks ?? []);
|
|
149
262
|
return {
|
|
150
263
|
team,
|
|
151
264
|
promptsImported,
|
|
152
265
|
normsImported,
|
|
153
266
|
cronTasksImported,
|
|
267
|
+
connectorsToReconnect,
|
|
154
268
|
};
|
|
155
269
|
}
|
|
156
270
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-export.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/core/team-export.service.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"team-export.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/core/team-export.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -9773,4 +9773,29 @@ export declare const ACTIVITY_LOG_CONSTANTS: {
|
|
|
9773
9773
|
readonly LIMIT: "limit";
|
|
9774
9774
|
};
|
|
9775
9775
|
};
|
|
9776
|
+
/**
|
|
9777
|
+
* Team export packages (`GET /api/teams/:id/export`, `crewly team export`;
|
|
9778
|
+
* issue #880). A package is portable and secret-free: runtime state is
|
|
9779
|
+
* stripped, every string is run through the secret redactor, and the
|
|
9780
|
+
* connectors the team's prompts and skills refer to are listed so the
|
|
9781
|
+
* importer knows what to reconnect.
|
|
9782
|
+
*/
|
|
9783
|
+
export declare const TEAM_EXPORT_CONSTANTS: {
|
|
9784
|
+
/** Format version written by this release */
|
|
9785
|
+
readonly VERSION: "1.1";
|
|
9786
|
+
/** Versions `importTeam` accepts */
|
|
9787
|
+
readonly SUPPORTED_VERSIONS: readonly ["1.0", "1.1"];
|
|
9788
|
+
/** Member fields that describe this install's running agent, never the team */
|
|
9789
|
+
readonly RUNTIME_MEMBER_FIELDS: readonly ["agentId", "currentTickets", "readyAt", "loginRequired", "usageLimited", "runtimeOverride", "capabilities", "lastActivityCheck"];
|
|
9790
|
+
/** Connector id → words in prompts / skill ids / schedules that mean the team uses it */
|
|
9791
|
+
readonly CONNECTOR_HINTS: {
|
|
9792
|
+
readonly 'google-workspace': RegExp;
|
|
9793
|
+
readonly canva: RegExp;
|
|
9794
|
+
readonly 'microsoft-todo': RegExp;
|
|
9795
|
+
readonly whatsapp: RegExp;
|
|
9796
|
+
readonly slack: RegExp;
|
|
9797
|
+
};
|
|
9798
|
+
/** Default file name of a downloaded package (`<slug>` = team name) */
|
|
9799
|
+
readonly DOWNLOAD_FILE_NAME: "crewly-team-<slug>.json";
|
|
9800
|
+
};
|
|
9776
9801
|
//# sourceMappingURL=constants.d.ts.map
|