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.
Files changed (139) hide show
  1. package/config/skills/orchestrator/move-team/SKILL.md +53 -0
  2. package/config/skills/orchestrator/move-team/execute.sh +42 -0
  3. package/dist/backend/backend/src/constants.d.ts +82 -0
  4. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  5. package/dist/backend/backend/src/constants.js +82 -0
  6. package/dist/backend/backend/src/constants.js.map +1 -1
  7. package/dist/backend/backend/src/controllers/team-move/team-move.controller.d.ts +39 -0
  8. package/dist/backend/backend/src/controllers/team-move/team-move.controller.d.ts.map +1 -0
  9. package/dist/backend/backend/src/controllers/team-move/team-move.controller.js +211 -0
  10. package/dist/backend/backend/src/controllers/team-move/team-move.controller.js.map +1 -0
  11. package/dist/backend/backend/src/index.d.ts.map +1 -1
  12. package/dist/backend/backend/src/index.js +22 -3
  13. package/dist/backend/backend/src/index.js.map +1 -1
  14. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  15. package/dist/backend/backend/src/routes/api.routes.js +3 -0
  16. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  17. package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
  18. package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
  19. package/dist/backend/backend/src/services/cloud/cloud-sync.types.js +1 -0
  20. package/dist/backend/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
  21. package/dist/backend/backend/src/services/core/storage.service.d.ts +18 -0
  22. package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
  23. package/dist/backend/backend/src/services/core/storage.service.js +16 -0
  24. package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
  25. package/dist/backend/backend/src/services/decisions/decision.service.d.ts +19 -0
  26. package/dist/backend/backend/src/services/decisions/decision.service.d.ts.map +1 -1
  27. package/dist/backend/backend/src/services/decisions/decision.service.js +46 -0
  28. package/dist/backend/backend/src/services/decisions/decision.service.js.map +1 -1
  29. package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
  30. package/dist/backend/backend/src/services/slack/slack-initializer.js +2 -1
  31. package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
  32. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +9 -0
  33. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  34. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +25 -0
  35. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  36. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +19 -0
  37. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  38. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +41 -0
  39. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  40. package/dist/backend/backend/src/services/team-move/team-move-archive.d.ts +122 -0
  41. package/dist/backend/backend/src/services/team-move/team-move-archive.d.ts.map +1 -0
  42. package/dist/backend/backend/src/services/team-move/team-move-archive.js +202 -0
  43. package/dist/backend/backend/src/services/team-move/team-move-archive.js.map +1 -0
  44. package/dist/backend/backend/src/services/team-move/team-move-chat.d.ts +59 -0
  45. package/dist/backend/backend/src/services/team-move/team-move-chat.d.ts.map +1 -0
  46. package/dist/backend/backend/src/services/team-move/team-move-chat.js +133 -0
  47. package/dist/backend/backend/src/services/team-move/team-move-chat.js.map +1 -0
  48. package/dist/backend/backend/src/services/team-move/team-move-cloud.client.d.ts +102 -0
  49. package/dist/backend/backend/src/services/team-move/team-move-cloud.client.d.ts.map +1 -0
  50. package/dist/backend/backend/src/services/team-move/team-move-cloud.client.js +217 -0
  51. package/dist/backend/backend/src/services/team-move/team-move-cloud.client.js.map +1 -0
  52. package/dist/backend/backend/src/services/team-move/team-move-crypto.d.ts +102 -0
  53. package/dist/backend/backend/src/services/team-move/team-move-crypto.d.ts.map +1 -0
  54. package/dist/backend/backend/src/services/team-move/team-move-crypto.js +348 -0
  55. package/dist/backend/backend/src/services/team-move/team-move-crypto.js.map +1 -0
  56. package/dist/backend/backend/src/services/team-move/team-move-driver.service.d.ts +209 -0
  57. package/dist/backend/backend/src/services/team-move/team-move-driver.service.d.ts.map +1 -0
  58. package/dist/backend/backend/src/services/team-move/team-move-driver.service.js +504 -0
  59. package/dist/backend/backend/src/services/team-move/team-move-driver.service.js.map +1 -0
  60. package/dist/backend/backend/src/services/team-move/team-move-exporter.d.ts +182 -0
  61. package/dist/backend/backend/src/services/team-move/team-move-exporter.d.ts.map +1 -0
  62. package/dist/backend/backend/src/services/team-move/team-move-exporter.js +537 -0
  63. package/dist/backend/backend/src/services/team-move/team-move-exporter.js.map +1 -0
  64. package/dist/backend/backend/src/services/team-move/team-move-fs.d.ts +157 -0
  65. package/dist/backend/backend/src/services/team-move/team-move-fs.d.ts.map +1 -0
  66. package/dist/backend/backend/src/services/team-move/team-move-fs.js +298 -0
  67. package/dist/backend/backend/src/services/team-move/team-move-fs.js.map +1 -0
  68. package/dist/backend/backend/src/services/team-move/team-move-git.d.ts +69 -0
  69. package/dist/backend/backend/src/services/team-move/team-move-git.d.ts.map +1 -0
  70. package/dist/backend/backend/src/services/team-move/team-move-git.js +198 -0
  71. package/dist/backend/backend/src/services/team-move/team-move-git.js.map +1 -0
  72. package/dist/backend/backend/src/services/team-move/team-move-importer.d.ts +121 -0
  73. package/dist/backend/backend/src/services/team-move/team-move-importer.d.ts.map +1 -0
  74. package/dist/backend/backend/src/services/team-move/team-move-importer.js +473 -0
  75. package/dist/backend/backend/src/services/team-move/team-move-importer.js.map +1 -0
  76. package/dist/backend/backend/src/services/team-move/team-move-journal.d.ts +110 -0
  77. package/dist/backend/backend/src/services/team-move/team-move-journal.d.ts.map +1 -0
  78. package/dist/backend/backend/src/services/team-move/team-move-journal.js +198 -0
  79. package/dist/backend/backend/src/services/team-move/team-move-journal.js.map +1 -0
  80. package/dist/backend/backend/src/services/team-move/team-move-machines.d.ts +62 -0
  81. package/dist/backend/backend/src/services/team-move/team-move-machines.d.ts.map +1 -0
  82. package/dist/backend/backend/src/services/team-move/team-move-machines.js +95 -0
  83. package/dist/backend/backend/src/services/team-move/team-move-machines.js.map +1 -0
  84. package/dist/backend/backend/src/services/team-move/team-move-preflight.d.ts +71 -0
  85. package/dist/backend/backend/src/services/team-move/team-move-preflight.d.ts.map +1 -0
  86. package/dist/backend/backend/src/services/team-move/team-move-preflight.js +102 -0
  87. package/dist/backend/backend/src/services/team-move/team-move-preflight.js.map +1 -0
  88. package/dist/backend/backend/src/services/team-move/team-move-runtime.d.ts +29 -0
  89. package/dist/backend/backend/src/services/team-move/team-move-runtime.d.ts.map +1 -0
  90. package/dist/backend/backend/src/services/team-move/team-move-runtime.js +173 -0
  91. package/dist/backend/backend/src/services/team-move/team-move-runtime.js.map +1 -0
  92. package/dist/backend/backend/src/services/team-move/team-move-secret-scan.d.ts +50 -0
  93. package/dist/backend/backend/src/services/team-move/team-move-secret-scan.d.ts.map +1 -0
  94. package/dist/backend/backend/src/services/team-move/team-move-secret-scan.js +96 -0
  95. package/dist/backend/backend/src/services/team-move/team-move-secret-scan.js.map +1 -0
  96. package/dist/backend/backend/src/services/team-move/team-move-select.d.ts +94 -0
  97. package/dist/backend/backend/src/services/team-move/team-move-select.d.ts.map +1 -0
  98. package/dist/backend/backend/src/services/team-move/team-move-select.js +124 -0
  99. package/dist/backend/backend/src/services/team-move/team-move-select.js.map +1 -0
  100. package/dist/backend/backend/src/services/team-move/team-move.fixture.d.ts +46 -0
  101. package/dist/backend/backend/src/services/team-move/team-move.fixture.d.ts.map +1 -0
  102. package/dist/backend/backend/src/services/team-move/team-move.fixture.js +202 -0
  103. package/dist/backend/backend/src/services/team-move/team-move.fixture.js.map +1 -0
  104. package/dist/backend/backend/src/services/team-move/team-move.types.d.ts +279 -0
  105. package/dist/backend/backend/src/services/team-move/team-move.types.d.ts.map +1 -0
  106. package/dist/backend/backend/src/services/team-move/team-move.types.js +44 -0
  107. package/dist/backend/backend/src/services/team-move/team-move.types.js.map +1 -0
  108. package/dist/backend/build-info.json +2 -2
  109. package/dist/cli/backend/src/constants.d.ts +82 -0
  110. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  111. package/dist/cli/backend/src/constants.js +82 -0
  112. package/dist/cli/backend/src/constants.js.map +1 -1
  113. package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
  114. package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
  115. package/dist/cli/backend/src/services/cloud/cloud-sync.types.js +1 -0
  116. package/dist/cli/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
  117. package/dist/cli/backend/src/services/core/storage.service.d.ts +18 -0
  118. package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -1
  119. package/dist/cli/backend/src/services/core/storage.service.js +16 -0
  120. package/dist/cli/backend/src/services/core/storage.service.js.map +1 -1
  121. package/dist/cli/backend/src/services/decisions/decision.service.d.ts +19 -0
  122. package/dist/cli/backend/src/services/decisions/decision.service.d.ts.map +1 -1
  123. package/dist/cli/backend/src/services/decisions/decision.service.js +46 -0
  124. package/dist/cli/backend/src/services/decisions/decision.service.js.map +1 -1
  125. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +9 -0
  126. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  127. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +25 -0
  128. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  129. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +19 -0
  130. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  131. package/dist/cli/backend/src/services/task-pool/task-pool.service.js +41 -0
  132. package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  133. package/dist/cli/cli/src/commands/team-move.d.ts +68 -0
  134. package/dist/cli/cli/src/commands/team-move.d.ts.map +1 -0
  135. package/dist/cli/cli/src/commands/team-move.js +159 -0
  136. package/dist/cli/cli/src/commands/team-move.js.map +1 -0
  137. package/dist/cli/cli/src/index.js +33 -0
  138. package/dist/cli/cli/src/index.js.map +1 -1
  139. 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"}