Skip to content
This repository was archived by the owner on Jun 4, 2026. It is now read-only.

Commit b9646da

Browse files
Chrisclaude
andcommitted
fix(repair): --fix-index defaults to off (opt-in, not opt-out)
Commander's .option('--no-fix-index') makes the underlying boolean default to TRUE, which was the opposite of what PR #15 advertised. Running `boxel doctor repair-realm <url>` silently rewrote index.json/cards-grid.json by default, destroying customized index files (caught by backspace on Checkly-prerendered realm). Flip to .option('--fix-index') across all 4 command surfaces: - repair-realm (hidden top-level) - repair-realms (hidden top-level) - doctor repair-realm - doctor repair-realms Now the default matches the documentation: index.json is untouched unless --fix-index is explicitly passed. Added 2 regression tests that exercise the commander parsing directly (the previous tests only checked the handler-level fallback, which ran AFTER commander had already set fixIndex=true). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent fe08909 commit b9646da

2 files changed

Lines changed: 33 additions & 4 deletions

File tree

src/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ program
458458
.option('--match-endpoint')
459459
.option('--include-personal')
460460
.option('--force')
461-
.option('--no-fix-index')
461+
.option('--fix-index')
462462
.option('--no-touch-index')
463463
.option('--reconcile-matrix')
464464
.option('--dry-run')
@@ -476,7 +476,7 @@ program
476476
.option('--match-endpoint')
477477
.option('--include-personal')
478478
.option('--force')
479-
.option('--no-fix-index')
479+
.option('--fix-index')
480480
.option('--no-touch-index')
481481
.option('--no-reconcile-matrix')
482482
.option('--dry-run')
@@ -502,7 +502,7 @@ doctorCmd
502502
.option('--match-endpoint', 'Restore name to endpoint-derived title (e.g., welcome-gorilla -> Welcome Gorilla)')
503503
.option('--include-personal', 'Allow repairing the special personal realm (skipped by default)')
504504
.option('--force', 'Overwrite name/icon/background even if present')
505-
.option('--no-fix-index', 'Skip index.json/cards-grid.json repair')
505+
.option('--fix-index', 'Rewrite index.json/cards-grid.json starter cards (opt-in; destructive to customized index files)')
506506
.option('--no-touch-index', 'Skip touch mutation in index.json meta')
507507
.option('--reconcile-matrix', 'Also reconcile app.boxel.realms entry for this realm URL')
508508
.option('--dry-run', 'Show proposed repairs without sending changes')
@@ -528,7 +528,7 @@ doctorCmd
528528
.option('--match-endpoint', 'Restore names to endpoint-derived title case')
529529
.option('--include-personal', 'Include the special personal realm (excluded by default)')
530530
.option('--force', 'Force overwrite of name/icon/background')
531-
.option('--no-fix-index', 'Skip index.json/cards-grid.json repair')
531+
.option('--fix-index', 'Rewrite index.json/cards-grid.json starter cards (opt-in; destructive to customized index files)')
532532
.option('--no-touch-index', 'Skip touch mutation in index.json meta')
533533
.option('--no-reconcile-matrix', 'Skip app.boxel.realms reconciliation')
534534
.option('--dry-run', 'Show proposed repairs without sending changes')

test/commands/repair.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,32 @@ describe('repair-realms batch defaults', () => {
137137
expect(matchEndpoint).toBe(true);
138138
});
139139
});
140+
141+
// Regression test for the bug Buck found on PR #15:
142+
// `.option('--no-fix-index')` makes commander default fixIndex to TRUE, which
143+
// silently destroyed customized index.json files (breaking Checkly prerendering).
144+
// The fix is to use `.option('--fix-index')` (opt-in, default undefined → false).
145+
// If a future commit flips it back, this test catches it before release.
146+
describe('repair commander flag parsing', () => {
147+
it('defaults fixIndex to undefined (false after nullish coalesce)', async () => {
148+
const { Command } = await import('commander');
149+
const cmd = new Command()
150+
.option('--fix-index', 'Rewrite index.json/cards-grid.json starter cards')
151+
.option('--no-touch-index', 'Skip touch mutation in index.json meta');
152+
153+
cmd.parse(['node', 'test', 'some-arg'], { from: 'node' });
154+
const opts = cmd.opts();
155+
expect(opts.fixIndex).toBeUndefined();
156+
expect((opts.fixIndex as boolean | undefined) ?? false).toBe(false);
157+
// touchIndex stays default-on because --no-touch-index means "disable touch"
158+
expect(opts.touchIndex).toBe(true);
159+
});
160+
161+
it('enables fixIndex when --fix-index is passed', async () => {
162+
const { Command } = await import('commander');
163+
const cmd = new Command().option('--fix-index', 'Rewrite index.json/cards-grid.json starter cards');
164+
165+
cmd.parse(['node', 'test', '--fix-index'], { from: 'node' });
166+
expect(cmd.opts().fixIndex).toBe(true);
167+
});
168+
});

0 commit comments

Comments
 (0)