crewly 1.20.303 → 1.20.305
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/orchestrator/move-team/SKILL.md +53 -0
- package/config/skills/orchestrator/move-team/execute.sh +42 -0
- package/dist/backend/backend/src/constants.d.ts +82 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +82 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/team-move/team-move.controller.d.ts +39 -0
- package/dist/backend/backend/src/controllers/team-move/team-move.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/team-move/team-move.controller.js +211 -0
- package/dist/backend/backend/src/controllers/team-move/team-move.controller.js.map +1 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +22 -3
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.js +3 -0
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.js +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
- package/dist/backend/backend/src/services/core/storage.service.d.ts +18 -0
- package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/core/storage.service.js +16 -0
- package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.service.d.ts +19 -0
- package/dist/backend/backend/src/services/decisions/decision.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.service.js +46 -0
- package/dist/backend/backend/src/services/decisions/decision.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js +2 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +9 -0
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +25 -0
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +19 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js +41 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/backend/src/services/team-move/team-move-archive.d.ts +122 -0
- package/dist/backend/backend/src/services/team-move/team-move-archive.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-archive.js +202 -0
- package/dist/backend/backend/src/services/team-move/team-move-archive.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-chat.d.ts +59 -0
- package/dist/backend/backend/src/services/team-move/team-move-chat.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-chat.js +133 -0
- package/dist/backend/backend/src/services/team-move/team-move-chat.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-cloud.client.d.ts +102 -0
- package/dist/backend/backend/src/services/team-move/team-move-cloud.client.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-cloud.client.js +217 -0
- package/dist/backend/backend/src/services/team-move/team-move-cloud.client.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-crypto.d.ts +102 -0
- package/dist/backend/backend/src/services/team-move/team-move-crypto.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-crypto.js +348 -0
- package/dist/backend/backend/src/services/team-move/team-move-crypto.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-driver.service.d.ts +209 -0
- package/dist/backend/backend/src/services/team-move/team-move-driver.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-driver.service.js +504 -0
- package/dist/backend/backend/src/services/team-move/team-move-driver.service.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-exporter.d.ts +182 -0
- package/dist/backend/backend/src/services/team-move/team-move-exporter.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-exporter.js +537 -0
- package/dist/backend/backend/src/services/team-move/team-move-exporter.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-fs.d.ts +157 -0
- package/dist/backend/backend/src/services/team-move/team-move-fs.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-fs.js +298 -0
- package/dist/backend/backend/src/services/team-move/team-move-fs.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-git.d.ts +69 -0
- package/dist/backend/backend/src/services/team-move/team-move-git.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-git.js +198 -0
- package/dist/backend/backend/src/services/team-move/team-move-git.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-importer.d.ts +121 -0
- package/dist/backend/backend/src/services/team-move/team-move-importer.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-importer.js +473 -0
- package/dist/backend/backend/src/services/team-move/team-move-importer.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-journal.d.ts +110 -0
- package/dist/backend/backend/src/services/team-move/team-move-journal.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-journal.js +198 -0
- package/dist/backend/backend/src/services/team-move/team-move-journal.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-machines.d.ts +62 -0
- package/dist/backend/backend/src/services/team-move/team-move-machines.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-machines.js +95 -0
- package/dist/backend/backend/src/services/team-move/team-move-machines.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-preflight.d.ts +71 -0
- package/dist/backend/backend/src/services/team-move/team-move-preflight.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-preflight.js +102 -0
- package/dist/backend/backend/src/services/team-move/team-move-preflight.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-runtime.d.ts +29 -0
- package/dist/backend/backend/src/services/team-move/team-move-runtime.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-runtime.js +173 -0
- package/dist/backend/backend/src/services/team-move/team-move-runtime.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-secret-scan.d.ts +50 -0
- package/dist/backend/backend/src/services/team-move/team-move-secret-scan.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-secret-scan.js +96 -0
- package/dist/backend/backend/src/services/team-move/team-move-secret-scan.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-select.d.ts +94 -0
- package/dist/backend/backend/src/services/team-move/team-move-select.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move-select.js +124 -0
- package/dist/backend/backend/src/services/team-move/team-move-select.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move.fixture.d.ts +46 -0
- package/dist/backend/backend/src/services/team-move/team-move.fixture.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move.fixture.js +202 -0
- package/dist/backend/backend/src/services/team-move/team-move.fixture.js.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move.types.d.ts +279 -0
- package/dist/backend/backend/src/services/team-move/team-move.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-move/team-move.types.js +44 -0
- package/dist/backend/backend/src/services/team-move/team-move.types.js.map +1 -0
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +82 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +82 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.js +1 -0
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
- package/dist/cli/backend/src/services/core/storage.service.d.ts +18 -0
- package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/core/storage.service.js +16 -0
- package/dist/cli/backend/src/services/core/storage.service.js.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision.service.d.ts +19 -0
- package/dist/cli/backend/src/services/decisions/decision.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision.service.js +46 -0
- package/dist/cli/backend/src/services/decisions/decision.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +9 -0
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +25 -0
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +19 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js +41 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/cli/cli/src/commands/team-move.d.ts +68 -0
- package/dist/cli/cli/src/commands/team-move.d.ts.map +1 -0
- package/dist/cli/cli/src/commands/team-move.js +159 -0
- package/dist/cli/cli/src/commands/team-move.js.map +1 -0
- package/dist/cli/cli/src/index.js +33 -0
- package/dist/cli/cli/src/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composition of the team move for the running backend: builds the exporter,
|
|
3
|
+
* importer, archiver and driver from the backend's own singletons (storage,
|
|
4
|
+
* task pool, decision cards, Slack team channels, harness status, device
|
|
5
|
+
* identity) so a move changes the live stores through their services and not
|
|
6
|
+
* behind their back.
|
|
7
|
+
*
|
|
8
|
+
* Starting and stopping a team goes through this backend's own REST API with
|
|
9
|
+
* the internal Cloud credential: the owner approved the move in Cloud, and the
|
|
10
|
+
* regular start/stop routes do the tmux and status bookkeeping.
|
|
11
|
+
*
|
|
12
|
+
* @module services/team-move/team-move-runtime
|
|
13
|
+
*/
|
|
14
|
+
import * as path from 'node:path';
|
|
15
|
+
import * as fs from 'node:fs/promises';
|
|
16
|
+
import { safeReadJson, atomicWriteJson } from '../../utils/file-io.utils.js';
|
|
17
|
+
import { collectSecretEnvValues } from '../../utils/secret-env.js';
|
|
18
|
+
import { getLocalApiBaseUrl } from '../../utils/local-api-url.utils.js';
|
|
19
|
+
import { CloudClientService } from '../cloud/cloud-client.service.js';
|
|
20
|
+
import { DeviceIdentityService } from '../cloud/device-identity.service.js';
|
|
21
|
+
import { getCrewlyHomePath } from '../core/crewly-home.utils.js';
|
|
22
|
+
import { internalCredentialHeaders } from '../core/owner-auth.service.js';
|
|
23
|
+
import { DecisionService } from '../decisions/decision.service.js';
|
|
24
|
+
import { getHarnessService } from '../harness/harness.service.js';
|
|
25
|
+
import { collectSettingsSecretValues } from '../security/secret-scrub.service.js';
|
|
26
|
+
import { getSlackTeamChannelService } from '../slack/slack-team-channel.service.js';
|
|
27
|
+
import { TaskPoolService } from '../task-pool/task-pool.service.js';
|
|
28
|
+
import { VersionCheckService } from '../system/version-check.service.js';
|
|
29
|
+
import { TeamMoveArchiver } from './team-move-archive.js';
|
|
30
|
+
import { TeamMoveCloudClient } from './team-move-cloud.client.js';
|
|
31
|
+
import { TeamMoveDriver } from './team-move-driver.service.js';
|
|
32
|
+
import { TeamMoveExporter } from './team-move-exporter.js';
|
|
33
|
+
import { TeamMoveImporter } from './team-move-importer.js';
|
|
34
|
+
import { freeDiskBytes, runPreflight } from './team-move-preflight.js';
|
|
35
|
+
/**
|
|
36
|
+
* Call a team route of this backend as the owner's Cloud-approved action.
|
|
37
|
+
*
|
|
38
|
+
* @param teamId - Team id
|
|
39
|
+
* @param action - `start` or `stop`
|
|
40
|
+
* @returns ok/error from the route
|
|
41
|
+
*/
|
|
42
|
+
async function teamRoute(teamId, action) {
|
|
43
|
+
try {
|
|
44
|
+
const res = await fetch(`${getLocalApiBaseUrl()}/api/teams/${encodeURIComponent(teamId)}/${action}`, {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
headers: { 'Content-Type': 'application/json', ...internalCredentialHeaders('cloud') },
|
|
47
|
+
body: '{}',
|
|
48
|
+
signal: AbortSignal.timeout(120_000),
|
|
49
|
+
});
|
|
50
|
+
const body = (await res.json().catch(() => ({})));
|
|
51
|
+
return res.ok && body.success !== false ? { ok: true } : { ok: false, error: body.error ?? `HTTP ${res.status}` };
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
return { ok: false, error: error instanceof Error ? error.message : String(error) };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Add a Slack channel mapping to the mapping file when the Slack service is
|
|
59
|
+
* not running (it loads the file when it starts).
|
|
60
|
+
*
|
|
61
|
+
* @param home - Crewly home
|
|
62
|
+
* @param mapping - Mapping to add
|
|
63
|
+
* @returns True when added
|
|
64
|
+
*/
|
|
65
|
+
async function adoptMappingInFile(home, mapping) {
|
|
66
|
+
const file = path.join(home, 'slack-team-channels.json');
|
|
67
|
+
const store = await safeReadJson(file, {});
|
|
68
|
+
const mappings = Array.isArray(store.mappings) ? store.mappings : [];
|
|
69
|
+
if (mappings.some((m) => m['teamId'] === mapping['teamId'] || m['slackChannelId'] === mapping['slackChannelId']))
|
|
70
|
+
return false;
|
|
71
|
+
await fs.mkdir(home, { recursive: true });
|
|
72
|
+
await atomicWriteJson(file, { version: 1, autoCreate: store.autoCreate !== false, channelPrefix: store.channelPrefix ?? '', ...store, mappings: [...mappings, mapping] });
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Build the driver for the running backend.
|
|
77
|
+
*
|
|
78
|
+
* @param input - Storage and the relay event source
|
|
79
|
+
* @returns The driver (not started)
|
|
80
|
+
*/
|
|
81
|
+
export function createTeamMoveDriver(input) {
|
|
82
|
+
const home = input.home ?? getCrewlyHomePath();
|
|
83
|
+
const storage = input.storage;
|
|
84
|
+
const cloud = CloudClientService.getInstance();
|
|
85
|
+
const identity = async () => {
|
|
86
|
+
const id = await DeviceIdentityService.getInstance().getOrCreateIdentity();
|
|
87
|
+
return { instanceId: id.deviceId, deviceName: id.deviceName };
|
|
88
|
+
};
|
|
89
|
+
const version = () => VersionCheckService.getInstance().getLocalVersion();
|
|
90
|
+
const client = new TeamMoveCloudClient({
|
|
91
|
+
session: { getToken: () => cloud.getToken(), getCloudUrl: () => cloud.getCloudUrl(), tryRefreshToken: () => cloud.tryRefreshToken() },
|
|
92
|
+
getInstanceId: async () => (await identity()).instanceId,
|
|
93
|
+
});
|
|
94
|
+
const knownSecrets = async () => [...collectSecretEnvValues(process.env), ...(await collectSettingsSecretValues(home))];
|
|
95
|
+
const exporter = new TeamMoveExporter({
|
|
96
|
+
home,
|
|
97
|
+
getTeams: () => storage.getTeams(),
|
|
98
|
+
getProjects: () => storage.getProjects(),
|
|
99
|
+
crewlyVersion: version(),
|
|
100
|
+
source: { instanceId: null, deviceName: null },
|
|
101
|
+
knownSecrets,
|
|
102
|
+
});
|
|
103
|
+
const pool = {
|
|
104
|
+
read: async () => {
|
|
105
|
+
const svc = TaskPoolService.getInstance();
|
|
106
|
+
return { workItems: await svc.getAllItems(), claims: (await svc.getActiveClaims()) };
|
|
107
|
+
},
|
|
108
|
+
removeWorkItems: (ids) => TaskPoolService.getInstance().removeWorkItemsForMove(ids),
|
|
109
|
+
addWorkItems: (items) => TaskPoolService.getInstance().importWorkItems(items),
|
|
110
|
+
};
|
|
111
|
+
const archiver = new TeamMoveArchiver({
|
|
112
|
+
home,
|
|
113
|
+
storage,
|
|
114
|
+
runtime: {
|
|
115
|
+
stopTeam: async (teamId) => {
|
|
116
|
+
await teamRoute(teamId, 'stop');
|
|
117
|
+
},
|
|
118
|
+
startTeam: (teamId) => teamRoute(teamId, 'start'),
|
|
119
|
+
},
|
|
120
|
+
pool,
|
|
121
|
+
decisions: {
|
|
122
|
+
list: async () => ((await DecisionService.getInstance()?.list('all')) ?? []),
|
|
123
|
+
setStatus: async (id, status) => {
|
|
124
|
+
await DecisionService.getInstance()?.setMovedStatus([id], status === 'open');
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
slack: {
|
|
128
|
+
unlink: async (teamId) => {
|
|
129
|
+
const service = getSlackTeamChannelService();
|
|
130
|
+
const mapping = service?.findByTeamId(teamId) ?? null;
|
|
131
|
+
if (service && mapping)
|
|
132
|
+
await service.unlinkTeam(teamId, { archiveSlackChannel: false });
|
|
133
|
+
return mapping;
|
|
134
|
+
},
|
|
135
|
+
adopt: async (mapping) => {
|
|
136
|
+
const service = getSlackTeamChannelService();
|
|
137
|
+
return service ? service.adoptMapping(mapping) : adoptMappingInFile(home, mapping);
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
const runtimeLogins = async () => {
|
|
142
|
+
const statuses = await getHarnessService().status.listStatuses();
|
|
143
|
+
return Object.fromEntries(statuses.map((s) => [s.id, s.installed && s.loginState === 'logged_in']));
|
|
144
|
+
};
|
|
145
|
+
return new TeamMoveDriver({
|
|
146
|
+
home,
|
|
147
|
+
cloud: client,
|
|
148
|
+
source: input.relay,
|
|
149
|
+
identity,
|
|
150
|
+
exporter,
|
|
151
|
+
archiver,
|
|
152
|
+
importer: () => new TeamMoveImporter({
|
|
153
|
+
home,
|
|
154
|
+
crewlyVersion: version(),
|
|
155
|
+
storage,
|
|
156
|
+
addWorkItems: pool.addWorkItems,
|
|
157
|
+
addDecisions: async (decisions) => (await DecisionService.getInstance()?.importMoved(decisions)) ?? 0,
|
|
158
|
+
adoptSlackMapping: async (mapping) => {
|
|
159
|
+
const service = getSlackTeamChannelService();
|
|
160
|
+
return service ? service.adoptMapping(mapping) : adoptMappingInFile(home, mapping);
|
|
161
|
+
},
|
|
162
|
+
startTeam: (teamId) => teamRoute(teamId, 'start'),
|
|
163
|
+
runtimeLogins,
|
|
164
|
+
freeDisk: freeDiskBytes,
|
|
165
|
+
}),
|
|
166
|
+
preflight: (tools) => runPreflight({ crewlyVersion: version(), diskPath: home, runtimeLogins }, tools),
|
|
167
|
+
isTeamIdle: async (teamId) => {
|
|
168
|
+
const team = (await storage.getTeams()).find((t) => t.id === teamId);
|
|
169
|
+
return !team || team.members.every((m) => m.workingStatus !== 'in_progress');
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=team-move-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-move-runtime.js","sourceRoot":"","sources":["../../../../../../backend/src/services/team-move/team-move-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret scan of a package before it leaves the machine.
|
|
3
|
+
*
|
|
4
|
+
* Runs the same detectors as the session-log redactor (token shapes such as
|
|
5
|
+
* Slack, OpenAI/Anthropic, GitHub, Google keys, JWTs, bearer headers, private
|
|
6
|
+
* key blocks, connection strings and `SECRET_NAME=value` assignments) plus the
|
|
7
|
+
* exact secret values this machine holds in its environment and settings. It
|
|
8
|
+
* reports file paths and pattern counts only, never a matched value.
|
|
9
|
+
*
|
|
10
|
+
* @module services/team-move/team-move-secret-scan
|
|
11
|
+
*/
|
|
12
|
+
import type { SecretEnvValue } from '../../utils/secret-env.js';
|
|
13
|
+
import type { PackageFileEntry } from './team-move.types.js';
|
|
14
|
+
import type { StagingArea } from './team-move-fs.js';
|
|
15
|
+
/** One file that holds secrets. */
|
|
16
|
+
export interface SecretFinding {
|
|
17
|
+
/** Package path. */
|
|
18
|
+
path: string;
|
|
19
|
+
/** Number of secret matches (values are never returned). */
|
|
20
|
+
matches: number;
|
|
21
|
+
}
|
|
22
|
+
/** Result of a scan. */
|
|
23
|
+
export interface SecretScanResult {
|
|
24
|
+
filesScanned: number;
|
|
25
|
+
findings: SecretFinding[];
|
|
26
|
+
}
|
|
27
|
+
/** Thrown when a package would carry secrets. */
|
|
28
|
+
export declare class TeamMoveSecretScanError extends Error {
|
|
29
|
+
readonly findings: SecretFinding[];
|
|
30
|
+
constructor(findings: SecretFinding[]);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Scan every file of a staging area.
|
|
34
|
+
*
|
|
35
|
+
* @param staging - The package being built
|
|
36
|
+
* @param files - Its files
|
|
37
|
+
* @param known - Exact secret values (env, settings) to look for
|
|
38
|
+
* @returns Files scanned and the findings
|
|
39
|
+
*/
|
|
40
|
+
export declare function scanStaging(staging: StagingArea, files: readonly PackageFileEntry[], known?: readonly SecretEnvValue[]): Promise<SecretScanResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Whether a flagged file may be left out of the package instead of aborting.
|
|
43
|
+
* Core records (the team config, task pool, decisions, chat records) can never
|
|
44
|
+
* be skipped; free-form notes and project files can.
|
|
45
|
+
*
|
|
46
|
+
* @param packagePath - Package path of the flagged file
|
|
47
|
+
* @returns True when skipping is allowed
|
|
48
|
+
*/
|
|
49
|
+
export declare function isSkippableFinding(packagePath: string): boolean;
|
|
50
|
+
//# sourceMappingURL=team-move-secret-scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-move-secret-scan.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/team-move/team-move-secret-scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAOrD,mCAAmC;AACnC,MAAM,WAAW,aAAa;IAC5B,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAwB;AACxB,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED,iDAAiD;AACjD,qBAAa,uBAAwB,SAAQ,KAAK;IACpC,QAAQ,CAAC,QAAQ,EAAE,aAAa,EAAE;gBAAzB,QAAQ,EAAE,aAAa,EAAE;CAO/C;AAiCD;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,gBAAgB,EAAE,EAAE,KAAK,GAAE,SAAS,cAAc,EAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAS5J;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAO/D"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret scan of a package before it leaves the machine.
|
|
3
|
+
*
|
|
4
|
+
* Runs the same detectors as the session-log redactor (token shapes such as
|
|
5
|
+
* Slack, OpenAI/Anthropic, GitHub, Google keys, JWTs, bearer headers, private
|
|
6
|
+
* key blocks, connection strings and `SECRET_NAME=value` assignments) plus the
|
|
7
|
+
* exact secret values this machine holds in its environment and settings. It
|
|
8
|
+
* reports file paths and pattern counts only, never a matched value.
|
|
9
|
+
*
|
|
10
|
+
* @module services/team-move/team-move-secret-scan
|
|
11
|
+
*/
|
|
12
|
+
import * as fs from 'node:fs/promises';
|
|
13
|
+
import { redactSecretsWithCount } from '../../utils/secret-redactor.js';
|
|
14
|
+
import { looksLikeText } from './team-move-fs.js';
|
|
15
|
+
/** Window read at a time (text is scanned in overlapping windows). */
|
|
16
|
+
const WINDOW_BYTES = 1024 * 1024;
|
|
17
|
+
/** Overlap between windows so a secret cut by a boundary is still seen. */
|
|
18
|
+
const OVERLAP_BYTES = 1024;
|
|
19
|
+
/** Thrown when a package would carry secrets. */
|
|
20
|
+
export class TeamMoveSecretScanError extends Error {
|
|
21
|
+
findings;
|
|
22
|
+
constructor(findings) {
|
|
23
|
+
super(`The secret scan found credentials in ${findings.length} file${findings.length === 1 ? '' : 's'}; nothing was sent. ` +
|
|
24
|
+
`Remove them from: ${findings.slice(0, 10).map((f) => f.path).join(', ')}${findings.length > 10 ? ', ...' : ''}`);
|
|
25
|
+
this.findings = findings;
|
|
26
|
+
this.name = 'TeamMoveSecretScanError';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Count secrets in one file.
|
|
31
|
+
*
|
|
32
|
+
* @param abs - Absolute file path
|
|
33
|
+
* @param known - Exact secret values to look for
|
|
34
|
+
* @returns Number of matches, 0 for binary files
|
|
35
|
+
*/
|
|
36
|
+
async function scanFile(abs, known) {
|
|
37
|
+
const handle = await fs.open(abs, 'r');
|
|
38
|
+
try {
|
|
39
|
+
const stat = await handle.stat();
|
|
40
|
+
const head = Buffer.alloc(Math.min(8192, stat.size));
|
|
41
|
+
await handle.read(head, 0, head.length, 0);
|
|
42
|
+
if (!looksLikeText(head))
|
|
43
|
+
return { matches: 0, scanned: false };
|
|
44
|
+
let matches = 0;
|
|
45
|
+
let position = 0;
|
|
46
|
+
const buf = Buffer.alloc(WINDOW_BYTES + OVERLAP_BYTES);
|
|
47
|
+
// Matches inside the overlap are seen by two windows; counting the first
|
|
48
|
+
// window's tail once is enough, we only need "any", so double counts are fine.
|
|
49
|
+
while (position < stat.size) {
|
|
50
|
+
const { bytesRead } = await handle.read(buf, 0, buf.length, position);
|
|
51
|
+
if (bytesRead === 0)
|
|
52
|
+
break;
|
|
53
|
+
matches += redactSecretsWithCount(buf.subarray(0, bytesRead).toString('utf8'), known).count;
|
|
54
|
+
position += WINDOW_BYTES;
|
|
55
|
+
}
|
|
56
|
+
return { matches, scanned: true };
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
await handle.close();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Scan every file of a staging area.
|
|
64
|
+
*
|
|
65
|
+
* @param staging - The package being built
|
|
66
|
+
* @param files - Its files
|
|
67
|
+
* @param known - Exact secret values (env, settings) to look for
|
|
68
|
+
* @returns Files scanned and the findings
|
|
69
|
+
*/
|
|
70
|
+
export async function scanStaging(staging, files, known = []) {
|
|
71
|
+
const findings = [];
|
|
72
|
+
let filesScanned = 0;
|
|
73
|
+
for (const f of files) {
|
|
74
|
+
const { matches, scanned } = await scanFile(staging.abs(f.path), known);
|
|
75
|
+
if (scanned)
|
|
76
|
+
filesScanned += 1;
|
|
77
|
+
if (matches > 0)
|
|
78
|
+
findings.push({ path: f.path, matches });
|
|
79
|
+
}
|
|
80
|
+
return { filesScanned, findings };
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Whether a flagged file may be left out of the package instead of aborting.
|
|
84
|
+
* Core records (the team config, task pool, decisions, chat records) can never
|
|
85
|
+
* be skipped; free-form notes and project files can.
|
|
86
|
+
*
|
|
87
|
+
* @param packagePath - Package path of the flagged file
|
|
88
|
+
* @returns True when skipping is allowed
|
|
89
|
+
*/
|
|
90
|
+
export function isSkippableFinding(packagePath) {
|
|
91
|
+
return (packagePath.startsWith('projects/') ||
|
|
92
|
+
packagePath.startsWith('handover/') ||
|
|
93
|
+
/^agents\/[^/]+\/sessions\//.test(packagePath) ||
|
|
94
|
+
/^team\/(wiki|norms|sops)\//.test(packagePath));
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=team-move-secret-scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-move-secret-scan.js","sourceRoot":"","sources":["../../../../../../backend/src/services/team-move/team-move-secret-scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which records of the global stores belong to a team. Pure functions: the
|
|
3
|
+
* exporter (source) selects with them, the archiver removes with them.
|
|
4
|
+
*
|
|
5
|
+
* @module services/team-move/team-move-select
|
|
6
|
+
*/
|
|
7
|
+
import type { Team } from '../../types/index.js';
|
|
8
|
+
import type { ScheduledMessage } from '../../types/index.js';
|
|
9
|
+
import type { WorkItem } from '../../types/v2/work-item.types.js';
|
|
10
|
+
import type { TaskClaim } from '../../types/v2/claim.types.js';
|
|
11
|
+
/** What identifies a team's records in the global stores. */
|
|
12
|
+
export interface TeamIdentity {
|
|
13
|
+
teamId: string;
|
|
14
|
+
teamName: string;
|
|
15
|
+
/** Member session names. */
|
|
16
|
+
sessions: ReadonlySet<string>;
|
|
17
|
+
/** Member ids. */
|
|
18
|
+
memberIds: ReadonlySet<string>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Identity of a team.
|
|
22
|
+
*
|
|
23
|
+
* @param team - The team
|
|
24
|
+
* @returns Ids and session names to match records by
|
|
25
|
+
*/
|
|
26
|
+
export declare function identityOf(team: Pick<Team, 'id' | 'name' | 'members'>): TeamIdentity;
|
|
27
|
+
/**
|
|
28
|
+
* Whether a free-form target string names the team or one of its members.
|
|
29
|
+
*
|
|
30
|
+
* @param target - A `target`/`targetTeam`/session field value
|
|
31
|
+
* @param id - Team identity
|
|
32
|
+
* @returns True on a match
|
|
33
|
+
*/
|
|
34
|
+
export declare function targetsTeam(target: unknown, id: TeamIdentity): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Whether a work item is still open.
|
|
37
|
+
*
|
|
38
|
+
* @param wi - Work item
|
|
39
|
+
* @returns True when it is neither terminal nor failed/rejected
|
|
40
|
+
*/
|
|
41
|
+
export declare function isOpenWorkItem(wi: Pick<WorkItem, 'status'>): boolean;
|
|
42
|
+
/** The slice of the pool a team owns. */
|
|
43
|
+
export interface TeamPoolSlice {
|
|
44
|
+
workItems: WorkItem[];
|
|
45
|
+
/** Active claims by team members on selected items (not moved; counted for the report). */
|
|
46
|
+
activeClaims: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Open task-pool items of a team: those aimed at the team or a member, those
|
|
50
|
+
* a member is working on, and their open children.
|
|
51
|
+
*
|
|
52
|
+
* @param pool - The pool file content
|
|
53
|
+
* @param pool.workItems - All work items
|
|
54
|
+
* @param pool.claims - All claims
|
|
55
|
+
* @param id - Team identity
|
|
56
|
+
* @returns Selected items
|
|
57
|
+
*/
|
|
58
|
+
export declare function selectPoolItems(pool: {
|
|
59
|
+
workItems?: WorkItem[];
|
|
60
|
+
claims?: TaskClaim[];
|
|
61
|
+
}, id: TeamIdentity): TeamPoolSlice;
|
|
62
|
+
/**
|
|
63
|
+
* Make a work item safe to start over on the target: nothing is running there
|
|
64
|
+
* yet, so an item that was being worked on goes back to the queue.
|
|
65
|
+
*
|
|
66
|
+
* @param wi - Work item as exported
|
|
67
|
+
* @returns Copy for the target
|
|
68
|
+
*/
|
|
69
|
+
export declare function resetWorkItemForTarget(wi: WorkItem): WorkItem;
|
|
70
|
+
/**
|
|
71
|
+
* Scheduled messages (legacy owner-created reminders) that address a team.
|
|
72
|
+
*
|
|
73
|
+
* @param messages - All scheduled messages
|
|
74
|
+
* @param id - Team identity
|
|
75
|
+
* @returns Those whose `targetTeam` names the team or one of its members
|
|
76
|
+
*/
|
|
77
|
+
export declare function selectScheduledMessages(messages: readonly ScheduledMessage[], id: TeamIdentity): ScheduledMessage[];
|
|
78
|
+
/** The decision fields the selector reads. */
|
|
79
|
+
export interface DecisionLike {
|
|
80
|
+
id: string;
|
|
81
|
+
status: string;
|
|
82
|
+
teamId?: string;
|
|
83
|
+
asker?: string;
|
|
84
|
+
requestedBy?: string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Open decisions/requests to the owner that belong to a team.
|
|
88
|
+
*
|
|
89
|
+
* @param decisions - All decisions
|
|
90
|
+
* @param id - Team identity
|
|
91
|
+
* @returns Pending ones asked by the team or one of its members
|
|
92
|
+
*/
|
|
93
|
+
export declare function selectDecisions<T extends DecisionLike>(decisions: readonly T[], id: TeamIdentity): T[];
|
|
94
|
+
//# sourceMappingURL=team-move-select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-move-select.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/team-move/team-move-select.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAG/D,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC9B,kBAAkB;IAClB,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,YAAY,CAOpF;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,GAAG,OAAO,CAGtE;AAKD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,OAAO,CAEpE;AAED,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,2FAA2F;IAC3F,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IAAE,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAA;CAAE,EAAE,EAAE,EAAE,YAAY,GAAG,aAAa,CAwBvH;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,QAAQ,GAAG,QAAQ,CAQ7D;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EAAE,EAAE,EAAE,YAAY,GAAG,gBAAgB,EAAE,CAEnH;AAED,8CAA8C;AAC9C,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAKD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,YAAY,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,YAAY,GAAG,CAAC,EAAE,CAMtG"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which records of the global stores belong to a team. Pure functions: the
|
|
3
|
+
* exporter (source) selects with them, the archiver removes with them.
|
|
4
|
+
*
|
|
5
|
+
* @module services/team-move/team-move-select
|
|
6
|
+
*/
|
|
7
|
+
import { TERMINAL_WORK_ITEM_STATUSES } from '../../types/v2/work-item.types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Identity of a team.
|
|
10
|
+
*
|
|
11
|
+
* @param team - The team
|
|
12
|
+
* @returns Ids and session names to match records by
|
|
13
|
+
*/
|
|
14
|
+
export function identityOf(team) {
|
|
15
|
+
return {
|
|
16
|
+
teamId: team.id,
|
|
17
|
+
teamName: team.name,
|
|
18
|
+
sessions: new Set(team.members.map((m) => m.sessionName).filter((s) => typeof s === 'string' && s.length > 0)),
|
|
19
|
+
memberIds: new Set(team.members.map((m) => m.id)),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Whether a free-form target string names the team or one of its members.
|
|
24
|
+
*
|
|
25
|
+
* @param target - A `target`/`targetTeam`/session field value
|
|
26
|
+
* @param id - Team identity
|
|
27
|
+
* @returns True on a match
|
|
28
|
+
*/
|
|
29
|
+
export function targetsTeam(target, id) {
|
|
30
|
+
if (typeof target !== 'string' || target.length === 0)
|
|
31
|
+
return false;
|
|
32
|
+
return target === id.teamId || target === id.teamName || id.sessions.has(target) || id.memberIds.has(target);
|
|
33
|
+
}
|
|
34
|
+
/** Work-item statuses that are still open (not finished, cancelled or verified). */
|
|
35
|
+
const OPEN_EXCLUDED = new Set([...TERMINAL_WORK_ITEM_STATUSES, 'failed', 'rejected']);
|
|
36
|
+
/**
|
|
37
|
+
* Whether a work item is still open.
|
|
38
|
+
*
|
|
39
|
+
* @param wi - Work item
|
|
40
|
+
* @returns True when it is neither terminal nor failed/rejected
|
|
41
|
+
*/
|
|
42
|
+
export function isOpenWorkItem(wi) {
|
|
43
|
+
return !OPEN_EXCLUDED.has(wi.status);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Open task-pool items of a team: those aimed at the team or a member, those
|
|
47
|
+
* a member is working on, and their open children.
|
|
48
|
+
*
|
|
49
|
+
* @param pool - The pool file content
|
|
50
|
+
* @param pool.workItems - All work items
|
|
51
|
+
* @param pool.claims - All claims
|
|
52
|
+
* @param id - Team identity
|
|
53
|
+
* @returns Selected items
|
|
54
|
+
*/
|
|
55
|
+
export function selectPoolItems(pool, id) {
|
|
56
|
+
const items = Array.isArray(pool.workItems) ? pool.workItems : [];
|
|
57
|
+
const claims = Array.isArray(pool.claims) ? pool.claims : [];
|
|
58
|
+
const activeByItem = new Map();
|
|
59
|
+
for (const c of claims)
|
|
60
|
+
if (c.status === 'active' && id.sessions.has(c.agentId))
|
|
61
|
+
activeByItem.set(c.workItemId, c);
|
|
62
|
+
const picked = new Map();
|
|
63
|
+
for (const wi of items) {
|
|
64
|
+
if (!isOpenWorkItem(wi))
|
|
65
|
+
continue;
|
|
66
|
+
if (targetsTeam(wi.target, id) || activeByItem.has(wi.id))
|
|
67
|
+
picked.set(wi.id, wi);
|
|
68
|
+
}
|
|
69
|
+
// Open children of picked items follow their parent.
|
|
70
|
+
let grew = true;
|
|
71
|
+
while (grew) {
|
|
72
|
+
grew = false;
|
|
73
|
+
for (const wi of items) {
|
|
74
|
+
if (picked.has(wi.id) || !isOpenWorkItem(wi))
|
|
75
|
+
continue;
|
|
76
|
+
if (wi.parentWorkItemId && picked.has(wi.parentWorkItemId)) {
|
|
77
|
+
picked.set(wi.id, wi);
|
|
78
|
+
grew = true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const activeClaims = [...picked.keys()].filter((k) => activeByItem.has(k)).length;
|
|
83
|
+
return { workItems: [...picked.values()], activeClaims };
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Make a work item safe to start over on the target: nothing is running there
|
|
87
|
+
* yet, so an item that was being worked on goes back to the queue.
|
|
88
|
+
*
|
|
89
|
+
* @param wi - Work item as exported
|
|
90
|
+
* @returns Copy for the target
|
|
91
|
+
*/
|
|
92
|
+
export function resetWorkItemForTarget(wi) {
|
|
93
|
+
const next = { ...wi };
|
|
94
|
+
if (next.status === 'running' || next.status === 'accepted') {
|
|
95
|
+
next.status = 'queued';
|
|
96
|
+
delete next.startedAt;
|
|
97
|
+
next.metadata = { ...(next.metadata ?? {}), movedFromRunning: true };
|
|
98
|
+
}
|
|
99
|
+
return next;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Scheduled messages (legacy owner-created reminders) that address a team.
|
|
103
|
+
*
|
|
104
|
+
* @param messages - All scheduled messages
|
|
105
|
+
* @param id - Team identity
|
|
106
|
+
* @returns Those whose `targetTeam` names the team or one of its members
|
|
107
|
+
*/
|
|
108
|
+
export function selectScheduledMessages(messages, id) {
|
|
109
|
+
return messages.filter((m) => targetsTeam(m.targetTeam, id));
|
|
110
|
+
}
|
|
111
|
+
/** Decision statuses that still wait for the owner. */
|
|
112
|
+
const PENDING_DECISION_STATUSES = new Set(['open', 'parked']);
|
|
113
|
+
/**
|
|
114
|
+
* Open decisions/requests to the owner that belong to a team.
|
|
115
|
+
*
|
|
116
|
+
* @param decisions - All decisions
|
|
117
|
+
* @param id - Team identity
|
|
118
|
+
* @returns Pending ones asked by the team or one of its members
|
|
119
|
+
*/
|
|
120
|
+
export function selectDecisions(decisions, id) {
|
|
121
|
+
return decisions.filter((d) => PENDING_DECISION_STATUSES.has(d.status) &&
|
|
122
|
+
(d.teamId === id.teamId || (typeof d.asker === 'string' && id.sessions.has(d.asker)) || (typeof d.requestedBy === 'string' && id.sessions.has(d.requestedBy))));
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=team-move-select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-move-select.js","sourceRoot":"","sources":["../../../../../../backend/src/services/team-move/team-move-select.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test fixture of the team move: builds a throwaway Crewly home with one team
|
|
3
|
+
* (plus a decoy team that must not travel), its agents' memory, handover notes,
|
|
4
|
+
* a project with `.crewly` data and a git repository, task-pool items,
|
|
5
|
+
* decisions, chat channels and a Slack channel mapping.
|
|
6
|
+
*
|
|
7
|
+
* @module services/team-move/team-move.fixture
|
|
8
|
+
*/
|
|
9
|
+
/** Ids of the fixture. */
|
|
10
|
+
export declare const FIXTURE: {
|
|
11
|
+
readonly teamId: "11111111-1111-4111-8111-111111111111";
|
|
12
|
+
readonly decoyTeamId: "22222222-2222-4222-8222-222222222222";
|
|
13
|
+
readonly projectId: "33333333-3333-4333-8333-333333333333";
|
|
14
|
+
readonly leadId: "aaaaaaaa-0000-4000-8000-000000000001";
|
|
15
|
+
readonly devId: "aaaaaaaa-0000-4000-8000-000000000002";
|
|
16
|
+
readonly leadSession: "movers-lena-aaaaaaaa";
|
|
17
|
+
readonly devSession: "movers-dev-bbbbbbbb";
|
|
18
|
+
readonly decoySession: "decoy-dan-cccccccc";
|
|
19
|
+
readonly channelId: "chan-0001-team-channel";
|
|
20
|
+
readonly dmId: "chan-0002-lena-dm";
|
|
21
|
+
};
|
|
22
|
+
/** A built fixture. */
|
|
23
|
+
export interface Fixture {
|
|
24
|
+
root: string;
|
|
25
|
+
home: string;
|
|
26
|
+
projectDir: string;
|
|
27
|
+
remoteDir: string;
|
|
28
|
+
cleanup(): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Build the source machine.
|
|
32
|
+
*
|
|
33
|
+
* @returns Paths and a cleanup function
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildSourceFixture(): Promise<Fixture>;
|
|
36
|
+
/**
|
|
37
|
+
* An empty target machine.
|
|
38
|
+
*
|
|
39
|
+
* @param root - Fixture root
|
|
40
|
+
* @returns Target home and projects root
|
|
41
|
+
*/
|
|
42
|
+
export declare function buildTargetPaths(root: string): Promise<{
|
|
43
|
+
home: string;
|
|
44
|
+
projectsRoot: string;
|
|
45
|
+
}>;
|
|
46
|
+
//# sourceMappingURL=team-move.fixture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-move.fixture.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/team-move/team-move.fixture.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,0BAA0B;AAC1B,eAAO,MAAM,OAAO;;;;;;;;;;;CAWV,CAAC;AAEX,uBAAuB;AACvB,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AA2BD;;;;GAIG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAiJ3D;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAMpG"}
|