crewly 1.20.245 → 1.20.247

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 (26) hide show
  1. package/dist/backend/backend/src/constants.d.ts +20 -0
  2. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  3. package/dist/backend/backend/src/constants.js +20 -0
  4. package/dist/backend/backend/src/constants.js.map +1 -1
  5. package/dist/backend/backend/src/index.d.ts +2 -0
  6. package/dist/backend/backend/src/index.d.ts.map +1 -1
  7. package/dist/backend/backend/src/index.js +22 -0
  8. package/dist/backend/backend/src/index.js.map +1 -1
  9. package/dist/backend/backend/src/services/system/scheduled-commands.service.d.ts +130 -0
  10. package/dist/backend/backend/src/services/system/scheduled-commands.service.d.ts.map +1 -0
  11. package/dist/backend/backend/src/services/system/scheduled-commands.service.js +286 -0
  12. package/dist/backend/backend/src/services/system/scheduled-commands.service.js.map +1 -0
  13. package/dist/backend/backend/src/services/worktree/docker-reclaim.d.ts +54 -0
  14. package/dist/backend/backend/src/services/worktree/docker-reclaim.d.ts.map +1 -0
  15. package/dist/backend/backend/src/services/worktree/docker-reclaim.js +102 -0
  16. package/dist/backend/backend/src/services/worktree/docker-reclaim.js.map +1 -0
  17. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.d.ts +8 -0
  18. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.d.ts.map +1 -1
  19. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.js +23 -0
  20. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.js.map +1 -1
  21. package/dist/backend/build-info.json +2 -2
  22. package/dist/cli/backend/src/constants.d.ts +20 -0
  23. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  24. package/dist/cli/backend/src/constants.js +20 -0
  25. package/dist/cli/backend/src/constants.js.map +1 -1
  26. package/package.json +1 -1
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Scheduled commands runner.
3
+ *
4
+ * Runs host commands listed in `<CREWLY_HOME>/scheduled-commands.json` on an
5
+ * interval. It exists because launchd jobs cannot read ~/Desktop (TCC), while
6
+ * the backend can. Design rules:
7
+ * - The list is read from disk only. There is deliberately no API route or
8
+ * trigger action that adds an entry: that would be arbitrary shell
9
+ * execution through the API.
10
+ * - No file = no jobs = feature off.
11
+ * - Each run is spawned DETACHED (own process group, unref'd, output to a log
12
+ * file) so a Crewly restart cannot kill it mid-way (a rollout cut in half
13
+ * leaves a mixed fleet).
14
+ * - A run never starts while the previous one is alive: checked by the pid we
15
+ * spawned and, when `lockFile` is set, by the pid inside the command's own
16
+ * lock file (a stale pid counts as dead).
17
+ * - Every skip is logged at debug; a run is logged at info only when spawned.
18
+ *
19
+ * Config shape: `[{name, cwd, command, args?, intervalMinutes, enabled?, lockFile?}]`.
20
+ *
21
+ * @module services/system/scheduled-commands
22
+ */
23
+ import { type ChildProcess, type SpawnOptions } from 'child_process';
24
+ /** One validated entry from the config file. */
25
+ export interface ScheduledCommand {
26
+ /** Unique name (used in the log file name) */
27
+ name: string;
28
+ /** Absolute working directory */
29
+ cwd: string;
30
+ /** Executable, run without a shell */
31
+ command: string;
32
+ /** Arguments */
33
+ args: string[];
34
+ /** Minutes between runs */
35
+ intervalMinutes: number;
36
+ /** Absolute path of the command's own lock file (holds a pid), optional */
37
+ lockFile?: string;
38
+ }
39
+ /** Result of reading the config file. */
40
+ export interface LoadedScheduledCommands {
41
+ /** Enabled, valid entries */
42
+ entries: ScheduledCommand[];
43
+ /** Entries in the file that were valid but disabled */
44
+ disabled: number;
45
+ /** Why the file or an entry was not used (one line each) */
46
+ warnings: string[];
47
+ }
48
+ /** Minimal logger contract. */
49
+ export interface ScheduledCommandsLogger {
50
+ debug(message: string, meta?: Record<string, unknown>): void;
51
+ info(message: string, meta?: Record<string, unknown>): void;
52
+ warn(message: string, meta?: Record<string, unknown>): void;
53
+ error(message: string, meta?: Record<string, unknown>): void;
54
+ }
55
+ /** Injection points (tests replace the process and filesystem edges). */
56
+ export interface ScheduledCommandsDeps {
57
+ /** Path of the config file */
58
+ configPath: string;
59
+ /** Directory for per-command log files */
60
+ logDir: string;
61
+ logger: ScheduledCommandsLogger;
62
+ /** child_process.spawn */
63
+ spawn?: (command: string, args: string[], options: SpawnOptions) => ChildProcess;
64
+ /** True when a process with this pid exists */
65
+ isPidAlive?: (pid: number) => boolean;
66
+ /** Reads a text file; throws when missing */
67
+ readFile?: (file: string) => string;
68
+ /** True when the path exists */
69
+ pathExists?: (file: string) => boolean;
70
+ /** Opens the log file for appending and returns an fd */
71
+ openLog?: (file: string) => number;
72
+ /** Closes an fd */
73
+ closeLog?: (fd: number) => void;
74
+ }
75
+ /**
76
+ * True when a process with this pid exists (signal 0 probe).
77
+ *
78
+ * @param pid - Process id
79
+ * @returns Whether it is alive
80
+ */
81
+ export declare function defaultIsPidAlive(pid: number): boolean;
82
+ /**
83
+ * Parse and validate the config text.
84
+ *
85
+ * Invalid input never throws: it yields zero entries and a warning.
86
+ *
87
+ * @param text - File contents
88
+ * @returns Entries, disabled count and warnings
89
+ */
90
+ export declare function parseScheduledCommands(text: string): LoadedScheduledCommands;
91
+ /** Outcome of one tick for one entry (also returned to tests). */
92
+ export type RunOutcome = 'spawned' | 'skipped-running' | 'skipped-lock' | 'skipped-no-cwd' | 'spawn-failed';
93
+ /**
94
+ * Interval runner for owner-configured host commands.
95
+ */
96
+ export declare class ScheduledCommandsService {
97
+ private readonly deps;
98
+ private entries;
99
+ private timers;
100
+ /** Last spawned pid per entry name */
101
+ private readonly lastPid;
102
+ /**
103
+ * @param deps - Paths, logger and optional process/filesystem overrides
104
+ */
105
+ constructor(deps: ScheduledCommandsDeps);
106
+ /**
107
+ * Load the config and schedule every enabled entry.
108
+ *
109
+ * Logs "N scheduled command(s) loaded" every time, including 0.
110
+ * A missing file is the normal off state (info); an unreadable or
111
+ * invalid file logs one warn line.
112
+ *
113
+ * @returns Number of jobs scheduled
114
+ */
115
+ start(): number;
116
+ /** Cancel all timers. Spawned children are NOT touched (they are detached). */
117
+ stop(): void;
118
+ /**
119
+ * Try to run one entry now.
120
+ *
121
+ * Skips (debug log) when the previous run or the command's own lock holder
122
+ * is alive, or the cwd is missing (warn). Never claims a run happened
123
+ * when it was skipped.
124
+ *
125
+ * @param entry - Entry to run
126
+ * @returns What happened
127
+ */
128
+ runEntry(entry: ScheduledCommand): RunOutcome;
129
+ }
130
+ //# sourceMappingURL=scheduled-commands.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduled-commands.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/system/scheduled-commands.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,286 @@
1
+ /**
2
+ * Scheduled commands runner.
3
+ *
4
+ * Runs host commands listed in `<CREWLY_HOME>/scheduled-commands.json` on an
5
+ * interval. It exists because launchd jobs cannot read ~/Desktop (TCC), while
6
+ * the backend can. Design rules:
7
+ * - The list is read from disk only. There is deliberately no API route or
8
+ * trigger action that adds an entry: that would be arbitrary shell
9
+ * execution through the API.
10
+ * - No file = no jobs = feature off.
11
+ * - Each run is spawned DETACHED (own process group, unref'd, output to a log
12
+ * file) so a Crewly restart cannot kill it mid-way (a rollout cut in half
13
+ * leaves a mixed fleet).
14
+ * - A run never starts while the previous one is alive: checked by the pid we
15
+ * spawned and, when `lockFile` is set, by the pid inside the command's own
16
+ * lock file (a stale pid counts as dead).
17
+ * - Every skip is logged at debug; a run is logged at info only when spawned.
18
+ *
19
+ * Config shape: `[{name, cwd, command, args?, intervalMinutes, enabled?, lockFile?}]`.
20
+ *
21
+ * @module services/system/scheduled-commands
22
+ */
23
+ import { spawn as nodeSpawn } from 'child_process';
24
+ import { closeSync, existsSync, mkdirSync, openSync, readFileSync } from 'fs';
25
+ import * as os from 'os';
26
+ import * as path from 'path';
27
+ import { SCHEDULED_COMMANDS } from '../../constants.js';
28
+ /**
29
+ * Expand a leading `~` to the home directory.
30
+ *
31
+ * @param p - Path from the config file
32
+ * @returns Path with `~` expanded
33
+ */
34
+ function expandHome(p) {
35
+ if (p === '~')
36
+ return os.homedir();
37
+ if (p.startsWith('~/'))
38
+ return path.join(os.homedir(), p.slice(2));
39
+ return p;
40
+ }
41
+ /**
42
+ * True when a process with this pid exists (signal 0 probe).
43
+ *
44
+ * @param pid - Process id
45
+ * @returns Whether it is alive
46
+ */
47
+ export function defaultIsPidAlive(pid) {
48
+ if (!Number.isInteger(pid) || pid <= 0)
49
+ return false;
50
+ try {
51
+ process.kill(pid, 0);
52
+ return true;
53
+ }
54
+ catch (err) {
55
+ // EPERM = exists but not ours: still alive.
56
+ return err.code === 'EPERM';
57
+ }
58
+ }
59
+ /**
60
+ * Parse and validate the config text.
61
+ *
62
+ * Invalid input never throws: it yields zero entries and a warning.
63
+ *
64
+ * @param text - File contents
65
+ * @returns Entries, disabled count and warnings
66
+ */
67
+ export function parseScheduledCommands(text) {
68
+ const out = { entries: [], disabled: 0, warnings: [] };
69
+ let raw;
70
+ try {
71
+ raw = JSON.parse(text);
72
+ }
73
+ catch (err) {
74
+ out.warnings.push(`config is not valid JSON (${err instanceof Error ? err.message : String(err)}); 0 jobs`);
75
+ return out;
76
+ }
77
+ if (!Array.isArray(raw)) {
78
+ out.warnings.push('config must be a JSON array; 0 jobs');
79
+ return out;
80
+ }
81
+ const seen = new Set();
82
+ raw.forEach((item, i) => {
83
+ const label = `entry ${i}`;
84
+ if (!item || typeof item !== 'object') {
85
+ out.warnings.push(`${label}: not an object; skipped`);
86
+ return;
87
+ }
88
+ const e = item;
89
+ if (typeof e.name !== 'string' || !SCHEDULED_COMMANDS.NAME_PATTERN.test(e.name)) {
90
+ out.warnings.push(`${label}: name must match ${SCHEDULED_COMMANDS.NAME_PATTERN}; skipped`);
91
+ return;
92
+ }
93
+ if (seen.has(e.name)) {
94
+ out.warnings.push(`${label} (${e.name}): duplicate name; skipped`);
95
+ return;
96
+ }
97
+ if (typeof e.command !== 'string' || e.command.trim() === '') {
98
+ out.warnings.push(`${label} (${e.name}): command is required; skipped`);
99
+ return;
100
+ }
101
+ if (typeof e.cwd !== 'string' || !path.isAbsolute(expandHome(e.cwd))) {
102
+ out.warnings.push(`${label} (${e.name}): cwd must be an absolute path; skipped`);
103
+ return;
104
+ }
105
+ if (e.args !== undefined && (!Array.isArray(e.args) || e.args.some((a) => typeof a !== 'string'))) {
106
+ out.warnings.push(`${label} (${e.name}): args must be an array of strings; skipped`);
107
+ return;
108
+ }
109
+ if (typeof e.intervalMinutes !== 'number' ||
110
+ !Number.isFinite(e.intervalMinutes) ||
111
+ e.intervalMinutes < SCHEDULED_COMMANDS.MIN_INTERVAL_MINUTES) {
112
+ out.warnings.push(`${label} (${e.name}): intervalMinutes must be a number >= ${SCHEDULED_COMMANDS.MIN_INTERVAL_MINUTES}; skipped`);
113
+ return;
114
+ }
115
+ if (e.lockFile !== undefined && (typeof e.lockFile !== 'string' || !path.isAbsolute(expandHome(e.lockFile)))) {
116
+ out.warnings.push(`${label} (${e.name}): lockFile must be an absolute path; skipped`);
117
+ return;
118
+ }
119
+ seen.add(e.name);
120
+ if (e.enabled === false) {
121
+ out.disabled++;
122
+ return;
123
+ }
124
+ out.entries.push({
125
+ name: e.name,
126
+ cwd: expandHome(e.cwd),
127
+ command: e.command,
128
+ args: e.args ?? [],
129
+ intervalMinutes: e.intervalMinutes,
130
+ lockFile: typeof e.lockFile === 'string' ? expandHome(e.lockFile) : undefined,
131
+ });
132
+ });
133
+ return out;
134
+ }
135
+ /**
136
+ * Interval runner for owner-configured host commands.
137
+ */
138
+ export class ScheduledCommandsService {
139
+ deps;
140
+ entries = [];
141
+ timers = [];
142
+ /** Last spawned pid per entry name */
143
+ lastPid = new Map();
144
+ /**
145
+ * @param deps - Paths, logger and optional process/filesystem overrides
146
+ */
147
+ constructor(deps) {
148
+ this.deps = {
149
+ spawn: nodeSpawn,
150
+ isPidAlive: defaultIsPidAlive,
151
+ readFile: (f) => readFileSync(f, 'utf-8'),
152
+ pathExists: existsSync,
153
+ openLog: (f) => {
154
+ mkdirSync(path.dirname(f), { recursive: true });
155
+ return openSync(f, 'a');
156
+ },
157
+ closeLog: closeSync,
158
+ ...deps,
159
+ };
160
+ }
161
+ /**
162
+ * Load the config and schedule every enabled entry.
163
+ *
164
+ * Logs "N scheduled command(s) loaded" every time, including 0.
165
+ * A missing file is the normal off state (info); an unreadable or
166
+ * invalid file logs one warn line.
167
+ *
168
+ * @returns Number of jobs scheduled
169
+ */
170
+ start() {
171
+ this.stop();
172
+ let text;
173
+ try {
174
+ text = this.deps.readFile(this.deps.configPath);
175
+ }
176
+ catch (err) {
177
+ if (err.code === 'ENOENT') {
178
+ this.deps.logger.info('0 scheduled command(s) loaded (no config file)', { path: this.deps.configPath });
179
+ }
180
+ else {
181
+ this.deps.logger.warn('0 scheduled command(s) loaded: config unreadable', {
182
+ path: this.deps.configPath,
183
+ error: err instanceof Error ? err.message : String(err),
184
+ });
185
+ }
186
+ return 0;
187
+ }
188
+ const loaded = parseScheduledCommands(text);
189
+ loaded.warnings.forEach((w) => this.deps.logger.warn(`scheduled-commands: ${w}`));
190
+ this.entries = loaded.entries;
191
+ this.deps.logger.info(`${loaded.entries.length} scheduled command(s) loaded`, {
192
+ disabled: loaded.disabled,
193
+ invalid: loaded.warnings.length,
194
+ names: loaded.entries.map((e) => e.name),
195
+ });
196
+ for (const entry of this.entries) {
197
+ const every = entry.intervalMinutes * SCHEDULED_COMMANDS.MS_PER_MINUTE;
198
+ const first = setTimeout(() => this.runEntry(entry), SCHEDULED_COMMANDS.INITIAL_DELAY_MS);
199
+ const repeat = setInterval(() => this.runEntry(entry), every);
200
+ first.unref();
201
+ repeat.unref();
202
+ this.timers.push(first, repeat);
203
+ }
204
+ return this.entries.length;
205
+ }
206
+ /** Cancel all timers. Spawned children are NOT touched (they are detached). */
207
+ stop() {
208
+ for (const t of this.timers) {
209
+ clearTimeout(t);
210
+ clearInterval(t);
211
+ }
212
+ this.timers = [];
213
+ this.entries = [];
214
+ }
215
+ /**
216
+ * Try to run one entry now.
217
+ *
218
+ * Skips (debug log) when the previous run or the command's own lock holder
219
+ * is alive, or the cwd is missing (warn). Never claims a run happened
220
+ * when it was skipped.
221
+ *
222
+ * @param entry - Entry to run
223
+ * @returns What happened
224
+ */
225
+ runEntry(entry) {
226
+ const { logger, isPidAlive } = this.deps;
227
+ const prev = this.lastPid.get(entry.name);
228
+ if (prev !== undefined && isPidAlive(prev)) {
229
+ logger.debug(`scheduled-commands: ${entry.name} skipped, previous run pid ${prev} still alive`);
230
+ return 'skipped-running';
231
+ }
232
+ if (entry.lockFile) {
233
+ let holder = NaN;
234
+ try {
235
+ holder = parseInt(this.deps.readFile(entry.lockFile).trim(), 10);
236
+ }
237
+ catch {
238
+ // No lock file = nobody holds it.
239
+ }
240
+ if (Number.isInteger(holder) && isPidAlive(holder)) {
241
+ logger.debug(`scheduled-commands: ${entry.name} skipped, lock held by pid ${holder}`);
242
+ return 'skipped-lock';
243
+ }
244
+ }
245
+ if (!this.deps.pathExists(entry.cwd)) {
246
+ logger.warn(`scheduled-commands: ${entry.name} not run, cwd missing`, { cwd: entry.cwd });
247
+ return 'skipped-no-cwd';
248
+ }
249
+ let fd = -1;
250
+ try {
251
+ const logFile = path.join(this.deps.logDir, SCHEDULED_COMMANDS.LOG_FILE_TEMPLATE.replace('{name}', entry.name));
252
+ fd = this.deps.openLog(logFile);
253
+ const child = this.deps.spawn(entry.command, entry.args, {
254
+ cwd: entry.cwd,
255
+ detached: true,
256
+ stdio: ['ignore', fd, fd],
257
+ });
258
+ child.on('error', (err) => logger.error(`scheduled-commands: ${entry.name} failed to start`, { error: err.message }));
259
+ child.unref();
260
+ if (child.pid === undefined) {
261
+ logger.error(`scheduled-commands: ${entry.name} did not start (no pid)`);
262
+ return 'spawn-failed';
263
+ }
264
+ this.lastPid.set(entry.name, child.pid);
265
+ logger.info(`scheduled-commands: ${entry.name} started`, { pid: child.pid, cwd: entry.cwd });
266
+ return 'spawned';
267
+ }
268
+ catch (err) {
269
+ logger.error(`scheduled-commands: ${entry.name} spawn threw`, {
270
+ error: err instanceof Error ? err.message : String(err),
271
+ });
272
+ return 'spawn-failed';
273
+ }
274
+ finally {
275
+ if (fd >= 0) {
276
+ try {
277
+ this.deps.closeLog(fd);
278
+ }
279
+ catch {
280
+ // Already closed.
281
+ }
282
+ }
283
+ }
284
+ }
285
+ }
286
+ //# sourceMappingURL=scheduled-commands.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduled-commands.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/system/scheduled-commands.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Docker reclaim for the low-disk pass.
3
+ *
4
+ * Agents that deploy build images on this machine all day; Docker Desktop's
5
+ * disk grew 23 GB in one night (2026-10-07) and took the Mac to 2.3 GB free
6
+ * while the worktree janitor found "nothing safe to delete". Only things that
7
+ * can be rebuilt or pulled again are removed:
8
+ *
9
+ * - older tags of registry images (`host/repo:tag`) — the newest tag of
10
+ * each repository stays, so the next build still has its layers; an image
11
+ * a container uses cannot be removed (docker refuses, we move on)
12
+ * - dangling images
13
+ * - build cache beyond a few GB, for the default builder and every
14
+ * docker-container (buildx) builder
15
+ *
16
+ * Never volumes, never containers. Skipped when the docker CLI or daemon is
17
+ * not there. Never throws.
18
+ *
19
+ * @module services/worktree/docker-reclaim
20
+ */
21
+ /** Runs a docker command; resolves stdout, rejects on failure. */
22
+ export type DockerExec = (args: string[], timeoutMs: number) => Promise<string>;
23
+ /** What a reclaim did. */
24
+ export interface DockerReclaimResult {
25
+ /** Docker was reachable */
26
+ ran: boolean;
27
+ /** Image tags removed */
28
+ removedImages: string[];
29
+ }
30
+ /** Build cache kept per builder. */
31
+ export declare const DOCKER_RECLAIM_KEEP_STORAGE = "3gb";
32
+ /**
33
+ * Older tags of each registry repository, newest first in `docker images`
34
+ * output (which lists newest first).
35
+ *
36
+ * @param listing - `docker images --format '{{.Repository}} {{.Tag}}'` output
37
+ * @returns `repo:tag` names to remove
38
+ */
39
+ export declare function olderRegistryTags(listing: string): string[];
40
+ /**
41
+ * Names of docker-container (buildx) builders.
42
+ *
43
+ * @param listing - `docker buildx ls` output
44
+ * @returns Builder names
45
+ */
46
+ export declare function containerBuilders(listing: string): string[];
47
+ /**
48
+ * Free what Docker holds that can be rebuilt or pulled again.
49
+ *
50
+ * @param exec - docker runner (tests)
51
+ * @returns What was done
52
+ */
53
+ export declare function reclaimDocker(exec?: DockerExec): Promise<DockerReclaimResult>;
54
+ //# sourceMappingURL=docker-reclaim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-reclaim.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/worktree/docker-reclaim.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,kEAAkE;AAClE,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEhF,0BAA0B;AAC1B,MAAM,WAAW,mBAAmB;IACnC,2BAA2B;IAC3B,GAAG,EAAE,OAAO,CAAC;IACb,yBAAyB;IACzB,aAAa,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,oCAAoC;AACpC,eAAO,MAAM,2BAA2B,QAAQ,CAAC;AAUjD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAY3D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ3D;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,IAAI,GAAE,UAAwB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAoBhG"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Docker reclaim for the low-disk pass.
3
+ *
4
+ * Agents that deploy build images on this machine all day; Docker Desktop's
5
+ * disk grew 23 GB in one night (2026-10-07) and took the Mac to 2.3 GB free
6
+ * while the worktree janitor found "nothing safe to delete". Only things that
7
+ * can be rebuilt or pulled again are removed:
8
+ *
9
+ * - older tags of registry images (`host/repo:tag`) — the newest tag of
10
+ * each repository stays, so the next build still has its layers; an image
11
+ * a container uses cannot be removed (docker refuses, we move on)
12
+ * - dangling images
13
+ * - build cache beyond a few GB, for the default builder and every
14
+ * docker-container (buildx) builder
15
+ *
16
+ * Never volumes, never containers. Skipped when the docker CLI or daemon is
17
+ * not there. Never throws.
18
+ *
19
+ * @module services/worktree/docker-reclaim
20
+ */
21
+ import { execFile } from 'child_process';
22
+ /** Build cache kept per builder. */
23
+ export const DOCKER_RECLAIM_KEEP_STORAGE = '3gb';
24
+ const defaultExec = (args, timeoutMs) => new Promise((resolve, reject) => {
25
+ execFile('docker', args, { timeout: timeoutMs, maxBuffer: 8 * 1024 * 1024 }, (err, stdout) => {
26
+ if (err)
27
+ reject(err);
28
+ else
29
+ resolve(String(stdout));
30
+ });
31
+ });
32
+ /**
33
+ * Older tags of each registry repository, newest first in `docker images`
34
+ * output (which lists newest first).
35
+ *
36
+ * @param listing - `docker images --format '{{.Repository}} {{.Tag}}'` output
37
+ * @returns `repo:tag` names to remove
38
+ */
39
+ export function olderRegistryTags(listing) {
40
+ const seen = new Set();
41
+ const out = [];
42
+ for (const line of listing.split('\n')) {
43
+ const [repo, tag] = line.trim().split(/\s+/);
44
+ if (!repo || !tag || tag === '<none>' || repo === '<none>')
45
+ continue;
46
+ // Only images that live in a registry (`host/...`): they can be pulled again.
47
+ if (!repo.includes('/') || !repo.split('/')[0].includes('.'))
48
+ continue;
49
+ if (seen.has(repo))
50
+ out.push(`${repo}:${tag}`);
51
+ else
52
+ seen.add(repo);
53
+ }
54
+ return out;
55
+ }
56
+ /**
57
+ * Names of docker-container (buildx) builders.
58
+ *
59
+ * @param listing - `docker buildx ls` output
60
+ * @returns Builder names
61
+ */
62
+ export function containerBuilders(listing) {
63
+ const out = [];
64
+ for (const line of listing.split('\n')) {
65
+ if (/^\s|\\_/.test(line))
66
+ continue;
67
+ const [name, driver] = line.trim().split(/\s+/);
68
+ if (name && driver === 'docker-container')
69
+ out.push(name.replace(/\*$/, ''));
70
+ }
71
+ return out;
72
+ }
73
+ /**
74
+ * Free what Docker holds that can be rebuilt or pulled again.
75
+ *
76
+ * @param exec - docker runner (tests)
77
+ * @returns What was done
78
+ */
79
+ export async function reclaimDocker(exec = defaultExec) {
80
+ const result = { ran: false, removedImages: [] };
81
+ try {
82
+ await exec(['info', '--format', '{{.ServerVersion}}'], 15_000);
83
+ }
84
+ catch {
85
+ return result;
86
+ }
87
+ result.ran = true;
88
+ const listing = await exec(['images', '--format', '{{.Repository}} {{.Tag}}'], 30_000).catch(() => '');
89
+ for (const ref of olderRegistryTags(listing)) {
90
+ const ok = await exec(['rmi', ref], 60_000).then(() => true, () => false);
91
+ if (ok)
92
+ result.removedImages.push(ref);
93
+ }
94
+ await exec(['image', 'prune', '-f'], 120_000).catch(() => '');
95
+ await exec(['builder', 'prune', '-f', '--keep-storage', DOCKER_RECLAIM_KEEP_STORAGE], 300_000).catch(() => '');
96
+ const builders = containerBuilders(await exec(['buildx', 'ls'], 30_000).catch(() => ''));
97
+ for (const b of builders) {
98
+ await exec(['buildx', 'prune', '--builder', b, '-f', '--keep-storage', DOCKER_RECLAIM_KEEP_STORAGE], 300_000).catch(() => '');
99
+ }
100
+ return result;
101
+ }
102
+ //# sourceMappingURL=docker-reclaim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-reclaim.js","sourceRoot":"","sources":["../../../../../../backend/src/services/worktree/docker-reclaim.ts"],"names":[],"mappings":"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"}
@@ -72,6 +72,7 @@
72
72
  */
73
73
  import { type StatFsFn } from './low-disk-guard.js';
74
74
  import { type ScratchSweepSummary } from './scratch-janitor.js';
75
+ import { type DockerReclaimResult } from './docker-reclaim.js';
75
76
  import { type TraceDiskResult } from '../trace/trace-store.js';
76
77
  /**
77
78
  * Why a worktree is kept, or why it may go. (`not-agent-worktree` is retired:
@@ -200,6 +201,8 @@ export interface WorktreeJanitorOptions {
200
201
  sizeOf?: (p: string) => Promise<number | null>;
201
202
  /** Low-disk notice state file (default `<CREWLY_HOME>/disk-janitor-state.json`); null = in memory */
202
203
  statePath?: string | null;
204
+ /** Docker reclaim on low disk (default: the real one, except under jest); null = never */
205
+ reclaimDocker?: (() => Promise<DockerReclaimResult>) | null;
203
206
  /** Environment for the kill switch (default process.env) */
204
207
  env?: NodeJS.ProcessEnv;
205
208
  /** Logger (default: component logger `WorktreeJanitor`) */
@@ -314,6 +317,11 @@ export declare class WorktreeJanitorService {
314
317
  private readNoticeState;
315
318
  private writeNoticeState;
316
319
  private doCheckDisk;
320
+ /**
321
+ * Docker images and build cache that can be pulled or rebuilt again
322
+ * (docker-reclaim.ts). Never throws.
323
+ */
324
+ private reclaimDockerSpace;
317
325
  /** Sizes of everything a pass left on disk that the owner could act on. */
318
326
  private keptItems;
319
327
  private git;
@@ -1 +1 @@
1
- {"version":3,"file":"worktree-janitor.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/worktree/worktree-janitor.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worktree-janitor.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/worktree/worktree-janitor.service.ts"],"names":[],"mappings":"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"}