@mmnto/cli 1.111.1 → 1.113.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/doctor-estate.d.ts +43 -0
- package/dist/commands/doctor-estate.d.ts.map +1 -0
- package/dist/commands/doctor-estate.js +262 -0
- package/dist/commands/doctor-estate.js.map +1 -0
- package/dist/commands/doctor-estate.test.d.ts +10 -0
- package/dist/commands/doctor-estate.test.d.ts.map +1 -0
- package/dist/commands/doctor-estate.test.js +611 -0
- package/dist/commands/doctor-estate.test.js.map +1 -0
- package/dist/commands/doctor.d.ts +48 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +171 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/doctor.test.js +410 -11
- package/dist/commands/doctor.test.js.map +1 -1
- package/dist/commands/wt.d.ts +100 -0
- package/dist/commands/wt.d.ts.map +1 -0
- package/dist/commands/wt.js +625 -0
- package/dist/commands/wt.js.map +1 -0
- package/dist/commands/wt.test.d.ts +21 -0
- package/dist/commands/wt.test.d.ts.map +1 -0
- package/dist/commands/wt.test.js +884 -0
- package/dist/commands/wt.test.js.map +1 -0
- package/dist/index.js +76 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,611 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render + artifact tests for `totem doctor --estate` (mmnto-ai/totem#2580).
|
|
3
|
+
*
|
|
4
|
+
* Git is injected (canned porcelain), so these assert the SURFACE — which rows
|
|
5
|
+
* render, what the artifact contains, and that the two never share a stream —
|
|
6
|
+
* rather than the local git install. The husk fixture is a real temp tree
|
|
7
|
+
* because husk evidence is literally a filesystem shape.
|
|
8
|
+
*/
|
|
9
|
+
import * as fs from 'node:fs';
|
|
10
|
+
import * as os from 'node:os';
|
|
11
|
+
import * as path from 'node:path';
|
|
12
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
13
|
+
import { cleanTmpDir } from '../test-utils.js';
|
|
14
|
+
import { doctorEstateCliCommand } from './doctor-estate.js';
|
|
15
|
+
const NOW = Date.parse('2026-08-05T12:00:00.000Z');
|
|
16
|
+
const COMMIT_10_DAYS_AGO = Math.floor((NOW - 10 * 86_400_000) / 1000);
|
|
17
|
+
/**
|
|
18
|
+
* Strip ANSI so assertions are colour-independent regardless of whether
|
|
19
|
+
* picocolors decides this environment supports colour. Constructed via
|
|
20
|
+
* `String.fromCharCode(27)` so no raw ESC control byte is authored into source.
|
|
21
|
+
*/
|
|
22
|
+
const ANSI = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, 'g');
|
|
23
|
+
let root;
|
|
24
|
+
let lines;
|
|
25
|
+
let errSpy;
|
|
26
|
+
let prevHome;
|
|
27
|
+
let prevProfile;
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
root = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'totem-estate-cli-')));
|
|
30
|
+
lines = [];
|
|
31
|
+
// The wt-registry coupling (mmnto-ai/totem#2580 slice 2) reads
|
|
32
|
+
// `~/.totem/worktrees.json` through `os.homedir()`, so HOME/USERPROFILE are
|
|
33
|
+
// pinned at an empty temp home for EVERY test here — otherwise a machine
|
|
34
|
+
// that has actually run `totem wt create` would drag its real recorded roots
|
|
35
|
+
// into these assertions. Tests that need their own home override this and
|
|
36
|
+
// restore to the temp one.
|
|
37
|
+
prevHome = process.env['HOME'];
|
|
38
|
+
prevProfile = process.env['USERPROFILE'];
|
|
39
|
+
process.env['HOME'] = path.join(root, 'home');
|
|
40
|
+
process.env['USERPROFILE'] = path.join(root, 'home');
|
|
41
|
+
errSpy = vi.spyOn(console, 'error').mockImplementation((msg) => {
|
|
42
|
+
lines.push(String(msg).replace(ANSI, ''));
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
afterEach(() => {
|
|
46
|
+
errSpy.mockRestore();
|
|
47
|
+
if (prevHome === undefined)
|
|
48
|
+
delete process.env['HOME'];
|
|
49
|
+
else
|
|
50
|
+
process.env['HOME'] = prevHome;
|
|
51
|
+
if (prevProfile === undefined)
|
|
52
|
+
delete process.env['USERPROFILE'];
|
|
53
|
+
else
|
|
54
|
+
process.env['USERPROFILE'] = prevProfile;
|
|
55
|
+
cleanTmpDir(root);
|
|
56
|
+
});
|
|
57
|
+
function output() {
|
|
58
|
+
return lines.join('\n');
|
|
59
|
+
}
|
|
60
|
+
function fold(p) {
|
|
61
|
+
return process.platform === 'win32' ? path.resolve(p).toLowerCase() : path.resolve(p);
|
|
62
|
+
}
|
|
63
|
+
function mkdir(...segments) {
|
|
64
|
+
const dir = path.join(root, ...segments);
|
|
65
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
66
|
+
return dir;
|
|
67
|
+
}
|
|
68
|
+
function registryOf(...paths) {
|
|
69
|
+
return Object.fromEntries(paths.map((p) => [
|
|
70
|
+
p,
|
|
71
|
+
{ path: p, chunkCount: 1, lastSync: '2026-08-01T00:00:00.000Z', embedder: 'test' },
|
|
72
|
+
]));
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* One repo whose worktree list carries a stale (merged) branch, an
|
|
76
|
+
* indeterminate (clean, unmerged) branch, and nothing else.
|
|
77
|
+
*/
|
|
78
|
+
function fixtureEstate() {
|
|
79
|
+
const repo = mkdir('repo');
|
|
80
|
+
const stale = mkdir('repo-stale');
|
|
81
|
+
const open = mkdir('repo-open');
|
|
82
|
+
const husk = mkdir('zzz-husk');
|
|
83
|
+
fs.writeFileSync(path.join(husk, '.git'), `gitdir: ${path.join(root, 'gone', '.git', 'worktrees', 'zzz-husk').split(path.sep).join('/')}\n`, 'utf-8');
|
|
84
|
+
const listing = [
|
|
85
|
+
`worktree ${repo.split(path.sep).join('/')}`,
|
|
86
|
+
`HEAD ${'a'.repeat(40)}`,
|
|
87
|
+
'branch refs/heads/main',
|
|
88
|
+
'',
|
|
89
|
+
`worktree ${stale.split(path.sep).join('/')}`,
|
|
90
|
+
`HEAD ${'b'.repeat(40)}`,
|
|
91
|
+
'branch refs/heads/2401-done',
|
|
92
|
+
'',
|
|
93
|
+
`worktree ${open.split(path.sep).join('/')}`,
|
|
94
|
+
`HEAD ${'c'.repeat(40)}`,
|
|
95
|
+
'branch refs/heads/2580-estate-sensor',
|
|
96
|
+
'',
|
|
97
|
+
].join('\n');
|
|
98
|
+
const exec = (command, args = []) => {
|
|
99
|
+
// Production argv is `git --no-optional-locks -C <cwd> <verb…>`.
|
|
100
|
+
const cwd = fold(args[2] ?? '');
|
|
101
|
+
const verb = args.slice(3);
|
|
102
|
+
if (verb[0] === 'worktree') {
|
|
103
|
+
if (cwd !== fold(repo))
|
|
104
|
+
throw Object.assign(new Error('not a repo'), { status: 128 });
|
|
105
|
+
return listing;
|
|
106
|
+
}
|
|
107
|
+
// Every fixture path is its own git toplevel unless a test says otherwise.
|
|
108
|
+
if (verb[0] === 'rev-parse' && verb[1] === '--show-toplevel') {
|
|
109
|
+
return cwd.split(path.sep).join('/');
|
|
110
|
+
}
|
|
111
|
+
if (verb[0] === 'rev-parse')
|
|
112
|
+
return 'origin/main';
|
|
113
|
+
if (verb[0] === 'status')
|
|
114
|
+
return '';
|
|
115
|
+
if (verb[0] === 'log')
|
|
116
|
+
return String(COMMIT_10_DAYS_AGO);
|
|
117
|
+
if (verb[0] === 'merge-base') {
|
|
118
|
+
if (verb[2] === 'refs/heads/2401-done')
|
|
119
|
+
return '';
|
|
120
|
+
throw Object.assign(new Error(''), { status: 1 });
|
|
121
|
+
}
|
|
122
|
+
throw Object.assign(new Error(`unexpected verb ${verb.join(' ')}`), { status: 1 });
|
|
123
|
+
};
|
|
124
|
+
return { repo, exec };
|
|
125
|
+
}
|
|
126
|
+
describe('doctorEstateCliCommand — degenerate registry', () => {
|
|
127
|
+
it('renders a named SKIP line and never throws when nothing is registered', async () => {
|
|
128
|
+
await expect(doctorEstateCliCommand({ registryForTest: {}, nowForTest: NOW, cwdForTest: root })).resolves.toBeUndefined();
|
|
129
|
+
expect(output()).toContain('SKIP');
|
|
130
|
+
expect(output()).toContain('no registered repos');
|
|
131
|
+
expect(output()).toContain('totem sync');
|
|
132
|
+
});
|
|
133
|
+
it('emits a valid degenerate artifact under --json (empty registry-status, zeroed summary)', async () => {
|
|
134
|
+
const chunks = [];
|
|
135
|
+
const stdout = vi
|
|
136
|
+
.spyOn(process.stdout, 'write')
|
|
137
|
+
.mockImplementation((chunk) => {
|
|
138
|
+
chunks.push(String(chunk));
|
|
139
|
+
return true;
|
|
140
|
+
});
|
|
141
|
+
try {
|
|
142
|
+
await doctorEstateCliCommand({
|
|
143
|
+
json: true,
|
|
144
|
+
registryForTest: {},
|
|
145
|
+
nowForTest: NOW,
|
|
146
|
+
cwdForTest: root,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
stdout.mockRestore();
|
|
151
|
+
}
|
|
152
|
+
const artifact = JSON.parse(chunks.join(''));
|
|
153
|
+
expect(artifact['estate-schema-version']).toBe(1);
|
|
154
|
+
expect(artifact['registry-status']).toBe('empty');
|
|
155
|
+
expect(artifact['derived-at']).toBe('2026-08-05T12:00:00.000Z');
|
|
156
|
+
expect(artifact['swept-roots']).toEqual([]);
|
|
157
|
+
expect(artifact['excluded-roots']).toEqual([]);
|
|
158
|
+
expect(artifact['summary']).toMatchObject({ repos: 0, worktrees: 0, 'husk-candidates': 0 });
|
|
159
|
+
expect(lines).toEqual([]);
|
|
160
|
+
});
|
|
161
|
+
// `--root` declares a worktree location independently of the registry: an
|
|
162
|
+
// empty registry must not swallow the sweep the operator explicitly asked
|
|
163
|
+
// for. No git call is expected — an empty registry probes nothing and a
|
|
164
|
+
// `.git`-less candidate needs no git.
|
|
165
|
+
it('still sweeps a --root when the registry is empty', async () => {
|
|
166
|
+
const declared = path.join(root, 'declared-root');
|
|
167
|
+
fs.mkdirSync(path.join(declared, 'left-behind', 'node_modules'), { recursive: true });
|
|
168
|
+
const chunks = [];
|
|
169
|
+
const stdout = vi
|
|
170
|
+
.spyOn(process.stdout, 'write')
|
|
171
|
+
.mockImplementation((chunk) => {
|
|
172
|
+
chunks.push(String(chunk));
|
|
173
|
+
return true;
|
|
174
|
+
});
|
|
175
|
+
try {
|
|
176
|
+
await doctorEstateCliCommand({
|
|
177
|
+
json: true,
|
|
178
|
+
registryForTest: {},
|
|
179
|
+
roots: [declared],
|
|
180
|
+
execForTest: () => {
|
|
181
|
+
throw new Error('no git call expected for an empty registry');
|
|
182
|
+
},
|
|
183
|
+
nowForTest: NOW,
|
|
184
|
+
cwdForTest: root,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
finally {
|
|
188
|
+
stdout.mockRestore();
|
|
189
|
+
}
|
|
190
|
+
const artifact = JSON.parse(chunks.join(''));
|
|
191
|
+
expect(artifact['registry-status']).toBe('empty');
|
|
192
|
+
expect(artifact['swept-roots']).toEqual([{ path: declared, kind: 'container' }]);
|
|
193
|
+
const husks = artifact['husk-candidates'];
|
|
194
|
+
expect(husks).toHaveLength(1);
|
|
195
|
+
expect(husks[0].evidence).toBe('container-residue');
|
|
196
|
+
expect(path.basename(husks[0].path)).toBe('left-behind');
|
|
197
|
+
});
|
|
198
|
+
it('reports an unreadable registry as `unreadable`, warning on stderr only (T6)', async () => {
|
|
199
|
+
// The registry is read through `os.homedir()`, so the fixture is a temp
|
|
200
|
+
// HOME carrying a corrupt registry file — the one path that makes
|
|
201
|
+
// `readRegistry` warn and return {} rather than silently returning {} on a
|
|
202
|
+
// missing file.
|
|
203
|
+
const home = path.join(root, 'home');
|
|
204
|
+
fs.mkdirSync(path.join(home, '.totem'), { recursive: true });
|
|
205
|
+
fs.writeFileSync(path.join(home, '.totem', 'registry.json'), '{ not json', 'utf-8');
|
|
206
|
+
const originalHome = process.env['HOME'];
|
|
207
|
+
const originalUserProfile = process.env['USERPROFILE'];
|
|
208
|
+
const chunks = [];
|
|
209
|
+
const stdout = vi
|
|
210
|
+
.spyOn(process.stdout, 'write')
|
|
211
|
+
.mockImplementation((chunk) => {
|
|
212
|
+
chunks.push(String(chunk));
|
|
213
|
+
return true;
|
|
214
|
+
});
|
|
215
|
+
try {
|
|
216
|
+
process.env['HOME'] = home;
|
|
217
|
+
process.env['USERPROFILE'] = home;
|
|
218
|
+
await doctorEstateCliCommand({ json: true, nowForTest: NOW, cwdForTest: root });
|
|
219
|
+
}
|
|
220
|
+
finally {
|
|
221
|
+
stdout.mockRestore();
|
|
222
|
+
if (originalHome === undefined)
|
|
223
|
+
delete process.env['HOME'];
|
|
224
|
+
else
|
|
225
|
+
process.env['HOME'] = originalHome;
|
|
226
|
+
if (originalUserProfile === undefined)
|
|
227
|
+
delete process.env['USERPROFILE'];
|
|
228
|
+
else
|
|
229
|
+
process.env['USERPROFILE'] = originalUserProfile;
|
|
230
|
+
}
|
|
231
|
+
const artifact = JSON.parse(chunks.join(''));
|
|
232
|
+
expect(artifact['registry-status']).toBe('unreadable');
|
|
233
|
+
expect(artifact['summary']).toMatchObject({ repos: 0, worktrees: 0 });
|
|
234
|
+
// The warning rides stderr; stdout carries the artifact and nothing else.
|
|
235
|
+
expect(output()).toContain('Cannot read registry');
|
|
236
|
+
expect(chunks).toHaveLength(1);
|
|
237
|
+
expect(() => JSON.parse(chunks[0])).not.toThrow();
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
describe('doctorEstateCliCommand — human render', () => {
|
|
241
|
+
it('renders a stale row, an indeterminate row, and a husk row with their evidence', async () => {
|
|
242
|
+
const { repo, exec } = fixtureEstate();
|
|
243
|
+
await doctorEstateCliCommand({
|
|
244
|
+
registryForTest: registryOf(repo),
|
|
245
|
+
execForTest: exec,
|
|
246
|
+
nowForTest: NOW,
|
|
247
|
+
cwdForTest: root,
|
|
248
|
+
});
|
|
249
|
+
const text = output();
|
|
250
|
+
expect(text).toContain('stale');
|
|
251
|
+
expect(text).toContain('[2401-done]');
|
|
252
|
+
expect(text).toContain('is an ancestor of origin/main');
|
|
253
|
+
expect(text).toContain('indeterminate');
|
|
254
|
+
expect(text).toContain('[2580-estate-sensor]');
|
|
255
|
+
expect(text).toContain('squash-merged');
|
|
256
|
+
expect(text).toContain('husk');
|
|
257
|
+
expect(text).toContain('[dangling-gitdir-pointer]');
|
|
258
|
+
expect(text).toContain('zzz-husk');
|
|
259
|
+
// Summary + the two disclosure lines (criteria, and what indeterminate means).
|
|
260
|
+
expect(text).toContain('2 worktree(s): 0 active · 1 stale · 1 indeterminate');
|
|
261
|
+
expect(text).toContain('husk criteria');
|
|
262
|
+
expect(text).toContain('Report-only');
|
|
263
|
+
});
|
|
264
|
+
it('renders a MISSING row for a registry path that no longer exists', async () => {
|
|
265
|
+
const { repo, exec } = fixtureEstate();
|
|
266
|
+
const gone = path.join(root, 'vanished');
|
|
267
|
+
await doctorEstateCliCommand({
|
|
268
|
+
registryForTest: registryOf(repo, gone),
|
|
269
|
+
execForTest: exec,
|
|
270
|
+
nowForTest: NOW,
|
|
271
|
+
cwdForTest: root,
|
|
272
|
+
});
|
|
273
|
+
expect(output()).toContain('[MISSING]');
|
|
274
|
+
expect(output()).toContain('vanished');
|
|
275
|
+
});
|
|
276
|
+
it('sweeps a relative --root against the cwd', async () => {
|
|
277
|
+
const { repo, exec } = fixtureEstate();
|
|
278
|
+
mkdir('extra-sweep');
|
|
279
|
+
await doctorEstateCliCommand({
|
|
280
|
+
registryForTest: registryOf(repo),
|
|
281
|
+
execForTest: exec,
|
|
282
|
+
nowForTest: NOW,
|
|
283
|
+
cwdForTest: root,
|
|
284
|
+
roots: ['extra-sweep'],
|
|
285
|
+
});
|
|
286
|
+
expect(output()).toContain(path.join(root, 'extra-sweep'));
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
describe('doctorEstateCliCommand — evidence-model disclosure', () => {
|
|
290
|
+
/** A repo with a container root holding one untracked dir, plus a nested entry. */
|
|
291
|
+
function containerFixture() {
|
|
292
|
+
const repo = mkdir('repo');
|
|
293
|
+
mkdir('repo', '.claude', 'worktrees', 'agent-residue');
|
|
294
|
+
const inside = mkdir('repo', 'packages');
|
|
295
|
+
const listing = [
|
|
296
|
+
`worktree ${repo.split(path.sep).join('/')}`,
|
|
297
|
+
`HEAD ${'a'.repeat(40)}`,
|
|
298
|
+
'branch refs/heads/main',
|
|
299
|
+
'',
|
|
300
|
+
].join('\n');
|
|
301
|
+
const exec = (command, args = []) => {
|
|
302
|
+
const cwd = fold(args[2] ?? '');
|
|
303
|
+
const verb = args.slice(3);
|
|
304
|
+
if (verb[0] === 'rev-parse' && verb[1] === '--show-toplevel') {
|
|
305
|
+
// The nested entry resolves to its ANCESTOR repo.
|
|
306
|
+
return (cwd === fold(inside) ? repo : cwd).split(path.sep).join('/');
|
|
307
|
+
}
|
|
308
|
+
if (verb[0] === 'worktree') {
|
|
309
|
+
if (cwd !== fold(repo))
|
|
310
|
+
throw Object.assign(new Error('not a repo'), { status: 128 });
|
|
311
|
+
return listing;
|
|
312
|
+
}
|
|
313
|
+
if (verb[0] === 'rev-parse')
|
|
314
|
+
return 'origin/main';
|
|
315
|
+
return '';
|
|
316
|
+
};
|
|
317
|
+
return { repo, inside, exec };
|
|
318
|
+
}
|
|
319
|
+
it('renders the NOT GIT ROOT row, a container-residue husk, and kind-annotated roots', async () => {
|
|
320
|
+
const { repo, inside, exec } = containerFixture();
|
|
321
|
+
await doctorEstateCliCommand({
|
|
322
|
+
registryForTest: registryOf(repo, inside),
|
|
323
|
+
execForTest: exec,
|
|
324
|
+
nowForTest: NOW,
|
|
325
|
+
cwdForTest: root,
|
|
326
|
+
});
|
|
327
|
+
const text = output();
|
|
328
|
+
expect(text).toContain('[NOT GIT ROOT]');
|
|
329
|
+
expect(text).toContain(inside);
|
|
330
|
+
expect(text).toContain(repo);
|
|
331
|
+
expect(text).toContain('[container-residue]');
|
|
332
|
+
expect(text).toContain('agent-residue');
|
|
333
|
+
// A2: each swept root is annotated with the kind that set its evidence bar.
|
|
334
|
+
expect(text).toContain(`${path.join(repo, '.claude', 'worktrees')} (container)`);
|
|
335
|
+
expect(text).toContain(`${root} (standard)`);
|
|
336
|
+
});
|
|
337
|
+
it('labels each ledger row with its axis in the human render', async () => {
|
|
338
|
+
const { repo, exec } = containerFixture();
|
|
339
|
+
const broken = mkdir('broken-entry');
|
|
340
|
+
// This entry's toplevel probe fails, producing a registry-source row.
|
|
341
|
+
const wrapped = (command, args = []) => {
|
|
342
|
+
const verb = args.slice(3);
|
|
343
|
+
if (verb[0] === 'rev-parse' &&
|
|
344
|
+
verb[1] === '--show-toplevel' &&
|
|
345
|
+
fold(args[2] ?? '') === fold(broken)) {
|
|
346
|
+
throw Object.assign(new Error('not a git repository'), { status: 128 });
|
|
347
|
+
}
|
|
348
|
+
return exec(command, args);
|
|
349
|
+
};
|
|
350
|
+
await doctorEstateCliCommand({
|
|
351
|
+
registryForTest: registryOf(repo, broken),
|
|
352
|
+
execForTest: wrapped,
|
|
353
|
+
nowForTest: NOW,
|
|
354
|
+
cwdForTest: root,
|
|
355
|
+
});
|
|
356
|
+
const text = output();
|
|
357
|
+
expect(text).toContain(`[registry] ${broken}`);
|
|
358
|
+
expect(text).toContain('rev-parse --show-toplevel failed');
|
|
359
|
+
});
|
|
360
|
+
it('names all four evidence classes by root kind in the criteria line', async () => {
|
|
361
|
+
const { repo, exec } = containerFixture();
|
|
362
|
+
await doctorEstateCliCommand({
|
|
363
|
+
registryForTest: registryOf(repo),
|
|
364
|
+
execForTest: exec,
|
|
365
|
+
nowForTest: NOW,
|
|
366
|
+
cwdForTest: root,
|
|
367
|
+
});
|
|
368
|
+
const text = output();
|
|
369
|
+
expect(text).toContain('container roots');
|
|
370
|
+
expect(text).toContain('LOCATION as evidence');
|
|
371
|
+
expect(text).toContain('container-residue');
|
|
372
|
+
expect(text).toContain('SHAPE evidence');
|
|
373
|
+
expect(text).toContain('dangling `.git` pointer');
|
|
374
|
+
expect(text).toContain('node_modules');
|
|
375
|
+
expect(text).toContain('home repo worktree list');
|
|
376
|
+
expect(text).toContain('Report-only');
|
|
377
|
+
});
|
|
378
|
+
it('carries not-git-root, enclosing-repo, swept-root kinds and ledger sources in the artifact', async () => {
|
|
379
|
+
const { repo, inside, exec } = containerFixture();
|
|
380
|
+
const chunks = [];
|
|
381
|
+
const stdout = vi
|
|
382
|
+
.spyOn(process.stdout, 'write')
|
|
383
|
+
.mockImplementation((chunk) => {
|
|
384
|
+
chunks.push(String(chunk));
|
|
385
|
+
return true;
|
|
386
|
+
});
|
|
387
|
+
try {
|
|
388
|
+
await doctorEstateCliCommand({
|
|
389
|
+
json: true,
|
|
390
|
+
registryForTest: registryOf(repo, inside),
|
|
391
|
+
execForTest: exec,
|
|
392
|
+
nowForTest: NOW,
|
|
393
|
+
cwdForTest: root,
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
finally {
|
|
397
|
+
stdout.mockRestore();
|
|
398
|
+
}
|
|
399
|
+
const artifact = JSON.parse(chunks.join(''));
|
|
400
|
+
const repos = artifact['repos'];
|
|
401
|
+
const nested = repos.find((r) => r['path'] === inside);
|
|
402
|
+
expect(nested['not-git-root']).toBe(true);
|
|
403
|
+
expect(nested['enclosing-repo']).toBe(repo);
|
|
404
|
+
// Presence-only: a verified repo carries neither key.
|
|
405
|
+
expect('not-git-root' in repos.find((r) => r['path'] === repo)).toBe(false);
|
|
406
|
+
const roots = artifact['swept-roots'];
|
|
407
|
+
expect(roots.find((r) => r['path'] === path.join(repo, '.claude', 'worktrees'))['kind']).toBe('container');
|
|
408
|
+
expect(roots.find((r) => r['path'] === root)['kind']).toBe('standard');
|
|
409
|
+
const husks = artifact['husk-candidates'];
|
|
410
|
+
expect(husks.map((h) => h['evidence'])).toContain('container-residue');
|
|
411
|
+
for (const row of artifact['unscannable']) {
|
|
412
|
+
expect(['registry', 'worktree', 'sweep']).toContain(row['source']);
|
|
413
|
+
}
|
|
414
|
+
expect(artifact['summary']).toMatchObject({ 'repos-not-git-root': 1, 'repos-unscannable': 0 });
|
|
415
|
+
});
|
|
416
|
+
});
|
|
417
|
+
describe('doctorEstateCliCommand — the --json artifact owns stdout (invariant 8)', () => {
|
|
418
|
+
it('writes exactly one JSON document and renders no human line', async () => {
|
|
419
|
+
const { repo, exec } = fixtureEstate();
|
|
420
|
+
const chunks = [];
|
|
421
|
+
const stdout = vi
|
|
422
|
+
.spyOn(process.stdout, 'write')
|
|
423
|
+
.mockImplementation((chunk) => {
|
|
424
|
+
chunks.push(String(chunk));
|
|
425
|
+
return true;
|
|
426
|
+
});
|
|
427
|
+
try {
|
|
428
|
+
await doctorEstateCliCommand({
|
|
429
|
+
json: true,
|
|
430
|
+
registryForTest: registryOf(repo),
|
|
431
|
+
execForTest: exec,
|
|
432
|
+
nowForTest: NOW,
|
|
433
|
+
cwdForTest: root,
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
finally {
|
|
437
|
+
stdout.mockRestore();
|
|
438
|
+
}
|
|
439
|
+
expect(chunks).toHaveLength(1);
|
|
440
|
+
expect(chunks[0].endsWith('\n')).toBe(true);
|
|
441
|
+
expect(lines).toEqual([]);
|
|
442
|
+
const artifact = JSON.parse(chunks[0]);
|
|
443
|
+
expect(Object.keys(artifact)).toEqual([
|
|
444
|
+
'estate-schema-version',
|
|
445
|
+
'registry-status',
|
|
446
|
+
'derived-at',
|
|
447
|
+
'swept-roots',
|
|
448
|
+
'excluded-roots',
|
|
449
|
+
'repos',
|
|
450
|
+
'worktrees',
|
|
451
|
+
'husk-candidates',
|
|
452
|
+
'unscannable',
|
|
453
|
+
'summary',
|
|
454
|
+
]);
|
|
455
|
+
expect(artifact['registry-status']).toBe('ok');
|
|
456
|
+
const worktrees = artifact['worktrees'];
|
|
457
|
+
const stale = worktrees.find((w) => w['branch'] === '2401-done');
|
|
458
|
+
const open = worktrees.find((w) => w['branch'] === '2580-estate-sensor');
|
|
459
|
+
expect(stale['class']).toBe('registered-stale');
|
|
460
|
+
expect(stale['ancestry-merged']).toBe(true);
|
|
461
|
+
expect(stale['age-days']).toBe(10);
|
|
462
|
+
expect(open['class']).toBe('registered-indeterminate');
|
|
463
|
+
expect(open['ancestry-merged']).toBe(false);
|
|
464
|
+
// Presence-only optionals: a clean worktree carries no `dirty` key at all.
|
|
465
|
+
expect('dirty' in open).toBe(false);
|
|
466
|
+
expect('locked' in open).toBe(false);
|
|
467
|
+
const husks = artifact['husk-candidates'];
|
|
468
|
+
expect(husks).toHaveLength(1);
|
|
469
|
+
expect(husks[0]['evidence']).toBe('dangling-gitdir-pointer');
|
|
470
|
+
expect(artifact['summary']).toMatchObject({
|
|
471
|
+
repos: 1,
|
|
472
|
+
worktrees: 2,
|
|
473
|
+
stale: 1,
|
|
474
|
+
indeterminate: 1,
|
|
475
|
+
'husk-candidates': 1,
|
|
476
|
+
});
|
|
477
|
+
});
|
|
478
|
+
});
|
|
479
|
+
// ─── wt-registry coupling (mmnto-ai/totem#2580 slice 2) ─
|
|
480
|
+
describe('doctorEstateCliCommand — wt-registry roots', () => {
|
|
481
|
+
/** Write a worktrees.json into the pinned temp HOME. */
|
|
482
|
+
function writeWtRegistry(contents) {
|
|
483
|
+
const dir = path.join(root, 'home', '.totem');
|
|
484
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
485
|
+
fs.writeFileSync(path.join(dir, 'worktrees.json'), contents, 'utf-8');
|
|
486
|
+
}
|
|
487
|
+
async function artifactFor(options) {
|
|
488
|
+
const chunks = [];
|
|
489
|
+
const stdout = vi
|
|
490
|
+
.spyOn(process.stdout, 'write')
|
|
491
|
+
.mockImplementation((chunk) => {
|
|
492
|
+
chunks.push(String(chunk));
|
|
493
|
+
return true;
|
|
494
|
+
});
|
|
495
|
+
try {
|
|
496
|
+
await doctorEstateCliCommand(options);
|
|
497
|
+
}
|
|
498
|
+
finally {
|
|
499
|
+
stdout.mockRestore();
|
|
500
|
+
}
|
|
501
|
+
return JSON.parse(chunks.join(''));
|
|
502
|
+
}
|
|
503
|
+
// Invariant 8: a recorded root stays swept with ZERO live entries under it —
|
|
504
|
+
// the round-3 MINOR-3 remedy. Every husk's own registry entry can be gone
|
|
505
|
+
// and the location is still reachable. Only the DEFAULT `~/.totem/worktrees`
|
|
506
|
+
// carries container semantics (it exists solely to hold worktrees).
|
|
507
|
+
it('sweeps the recorded DEFAULT root as a CONTAINER root with no registry entries at all', async () => {
|
|
508
|
+
const recorded = path.join(root, 'home', '.totem', 'worktrees');
|
|
509
|
+
fs.mkdirSync(path.join(recorded, 'left-behind'), { recursive: true });
|
|
510
|
+
writeWtRegistry(JSON.stringify({ schemaVersion: 1, roots: [recorded], worktrees: {} }, null, 2));
|
|
511
|
+
const artifact = await artifactFor({
|
|
512
|
+
json: true,
|
|
513
|
+
registryForTest: {},
|
|
514
|
+
execForTest: () => {
|
|
515
|
+
throw new Error('no git call expected for an empty registry');
|
|
516
|
+
},
|
|
517
|
+
nowForTest: NOW,
|
|
518
|
+
cwdForTest: root,
|
|
519
|
+
});
|
|
520
|
+
expect(artifact['swept-roots']).toEqual([{ path: recorded, kind: 'container' }]);
|
|
521
|
+
const husks = artifact['husk-candidates'];
|
|
522
|
+
expect(husks).toHaveLength(1);
|
|
523
|
+
expect(husks[0].evidence).toBe('container-residue');
|
|
524
|
+
});
|
|
525
|
+
// A recorded NON-default root proves worktrees live there, not that the
|
|
526
|
+
// location holds nothing else — STANDARD semantics, shape evidence required,
|
|
527
|
+
// so unrelated directories beside the worktrees never read as residue
|
|
528
|
+
// (falsification finding 11).
|
|
529
|
+
it('sweeps a NON-default recorded root as STANDARD — no by-location residue rows', async () => {
|
|
530
|
+
const recorded = path.join(root, 'scratch-root');
|
|
531
|
+
fs.mkdirSync(path.join(recorded, 'unrelated-project'), { recursive: true });
|
|
532
|
+
writeWtRegistry(JSON.stringify({ schemaVersion: 1, roots: [recorded], worktrees: {} }));
|
|
533
|
+
const artifact = await artifactFor({
|
|
534
|
+
json: true,
|
|
535
|
+
registryForTest: {},
|
|
536
|
+
execForTest: () => {
|
|
537
|
+
throw new Error('no git call expected for an empty registry');
|
|
538
|
+
},
|
|
539
|
+
nowForTest: NOW,
|
|
540
|
+
cwdForTest: root,
|
|
541
|
+
});
|
|
542
|
+
expect(artifact['swept-roots']).toEqual([{ path: recorded, kind: 'standard' }]);
|
|
543
|
+
expect(artifact['husk-candidates']).toEqual([]);
|
|
544
|
+
});
|
|
545
|
+
// A recorded root that no longer exists is an EMPTY SWEEP, not a scan hole
|
|
546
|
+
// (the ruling's Q3 filter) — it must not mint an unscannable row.
|
|
547
|
+
it('drops a recorded root that no longer exists, without an unscannable row', async () => {
|
|
548
|
+
const gone = path.join(root, 'vanished-root');
|
|
549
|
+
writeWtRegistry(JSON.stringify({ schemaVersion: 1, roots: [gone], worktrees: {} }));
|
|
550
|
+
const artifact = await artifactFor({
|
|
551
|
+
json: true,
|
|
552
|
+
registryForTest: {},
|
|
553
|
+
nowForTest: NOW,
|
|
554
|
+
cwdForTest: root,
|
|
555
|
+
});
|
|
556
|
+
expect(artifact['swept-roots']).toEqual([]);
|
|
557
|
+
expect(artifact['unscannable']).toEqual([]);
|
|
558
|
+
// Nothing to scan and nothing recorded → the degenerate artifact.
|
|
559
|
+
expect(artifact['summary']).toMatchObject({ repos: 0, worktrees: 0 });
|
|
560
|
+
});
|
|
561
|
+
it('discloses an unreadable worktrees.json on stderr and scans anyway', async () => {
|
|
562
|
+
writeWtRegistry('{ not json');
|
|
563
|
+
const declared = path.join(root, 'declared-root');
|
|
564
|
+
fs.mkdirSync(path.join(declared, 'residue'), { recursive: true });
|
|
565
|
+
const artifact = await artifactFor({
|
|
566
|
+
json: true,
|
|
567
|
+
registryForTest: {},
|
|
568
|
+
roots: [declared],
|
|
569
|
+
nowForTest: NOW,
|
|
570
|
+
cwdForTest: root,
|
|
571
|
+
});
|
|
572
|
+
// Disclosed, not swallowed — and the explicit --root sweep still ran.
|
|
573
|
+
expect(output()).toContain('Cannot read worktree registry');
|
|
574
|
+
expect(artifact['swept-roots']).toEqual([{ path: declared, kind: 'container' }]);
|
|
575
|
+
});
|
|
576
|
+
it('unions recorded roots with an explicit --root, leaving --root behavior unchanged', async () => {
|
|
577
|
+
const recorded = path.join(root, 'recorded-root');
|
|
578
|
+
const declared = path.join(root, 'declared-root');
|
|
579
|
+
fs.mkdirSync(recorded, { recursive: true });
|
|
580
|
+
fs.mkdirSync(declared, { recursive: true });
|
|
581
|
+
writeWtRegistry(JSON.stringify({ schemaVersion: 1, roots: [recorded], worktrees: {} }));
|
|
582
|
+
const artifact = await artifactFor({
|
|
583
|
+
json: true,
|
|
584
|
+
registryForTest: {},
|
|
585
|
+
roots: [declared],
|
|
586
|
+
nowForTest: NOW,
|
|
587
|
+
cwdForTest: root,
|
|
588
|
+
});
|
|
589
|
+
// The operator's per-invocation --root stays a container declaration; the
|
|
590
|
+
// recorded non-default root sweeps standard (shape evidence required).
|
|
591
|
+
expect(artifact['swept-roots']).toEqual([
|
|
592
|
+
{ path: declared, kind: 'container' },
|
|
593
|
+
{ path: recorded, kind: 'standard' },
|
|
594
|
+
]);
|
|
595
|
+
});
|
|
596
|
+
it('honours the wtRootsForTest seam without touching the real home', async () => {
|
|
597
|
+
const seamRoot = path.join(root, 'seam-root');
|
|
598
|
+
fs.mkdirSync(path.join(seamRoot, 'residue'), { recursive: true });
|
|
599
|
+
const artifact = await artifactFor({
|
|
600
|
+
json: true,
|
|
601
|
+
registryForTest: {},
|
|
602
|
+
wtRootsForTest: [seamRoot],
|
|
603
|
+
nowForTest: NOW,
|
|
604
|
+
cwdForTest: root,
|
|
605
|
+
});
|
|
606
|
+
// Seam values flow through the same default-vs-standard partition as
|
|
607
|
+
// production roots — an arbitrary seam root sweeps standard.
|
|
608
|
+
expect(artifact['swept-roots']).toEqual([{ path: seamRoot, kind: 'standard' }]);
|
|
609
|
+
});
|
|
610
|
+
});
|
|
611
|
+
//# sourceMappingURL=doctor-estate.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-estate.test.js","sourceRoot":"","sources":["../../src/commands/doctor-estate.test.ts"],"names":[],"mappings":"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"}
|