Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ for (const op of operations) {
}

// CLI-only commands that bypass the operation layer
const CLI_ONLY = new Set(['init', 'upgrade', 'post-upgrade', 'check-update', 'integrations', 'publish', 'check-backlinks', 'lint', 'report', 'import', 'export', 'files', 'embed', 'serve', 'call', 'config', 'doctor', 'migrate', 'eval', 'sync', 'extract', 'features', 'autopilot', 'graph-query', 'jobs', 'agent', 'apply-migrations', 'skillpack-check', 'skillpack', 'resolvers', 'integrity', 'repair-jsonb', 'orphans', 'sources', 'mounts', 'dream', 'check-resolvable', 'routing-eval', 'skillify', 'smoke-test', 'providers', 'storage', 'repos', 'code-def', 'code-refs', 'reindex-code', 'reindex-frontmatter', 'code-callers', 'code-callees', 'frontmatter', 'auth', 'friction', 'claw-test', 'book-mirror', 'takes', 'think', 'salience', 'anomalies', 'transcripts', 'models', 'remote', 'recall', 'forget']);
const CLI_ONLY = new Set(['init', 'upgrade', 'post-upgrade', 'check-update', 'integrations', 'publish', 'check-backlinks', 'lint', 'report', 'import', 'export', 'files', 'embed', 'serve', 'call', 'config', 'doctor', 'migrate', 'eval', 'sync', 'extract', 'features', 'autopilot', 'graph-query', 'jobs', 'agent', 'apply-migrations', 'skillpack-check', 'skillpack', 'resolvers', 'integrity', 'repair-jsonb', 'orphans', 'sources', 'mounts', 'dream', 'check-resolvable', 'routing-eval', 'skillify', 'smoke-test', 'providers', 'storage', 'repos', 'code-def', 'code-refs', 'reindex', 'reindex-code', 'reindex-frontmatter', 'code-callers', 'code-callees', 'frontmatter', 'auth', 'friction', 'claw-test', 'book-mirror', 'takes', 'think', 'salience', 'anomalies', 'transcripts', 'models', 'remote', 'recall', 'forget']);
// CLI-only commands whose handlers print their own --help text. These are
// excluded from the generic short-circuit so detailed per-command and
// per-subcommand usage stays reachable.
Expand Down
35 changes: 35 additions & 0 deletions test/reindex.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import { describe, test, expect, beforeAll, afterAll, beforeEach } from 'bun:test';
import { readFileSync } from 'fs';
import { PGLiteEngine } from '../src/core/pglite-engine.ts';
import { runReindex } from '../src/commands/reindex.ts';
import { MARKDOWN_CHUNKER_VERSION } from '../src/core/chunkers/recursive.ts';
Expand Down Expand Up @@ -136,3 +137,37 @@ describe('gbrain reindex --markdown (v0.32.7)', () => {
expect(result.reindexed).toBe(1);
});
});

describe('gbrain reindex — CLI registration regression', () => {
const REPO_ROOT = new URL('..', import.meta.url).pathname;
const cliSource = readFileSync(new URL('../src/cli.ts', import.meta.url), 'utf-8');

test("'reindex' appears in CLI_ONLY set (not just 'reindex-code' / 'reindex-frontmatter')", () => {
// Regression guard: case 'reindex' lives in handleCliOnly's switch, so
// dispatch can only reach it when 'reindex' is in CLI_ONLY. Without
// this token, `gbrain reindex` exits with "Unknown command: reindex"
// before ever entering handleCliOnly.
const cliOnlyLine = cliSource.split('\n').find(l => l.includes('const CLI_ONLY = new Set('));
expect(cliOnlyLine).toBeDefined();
expect(cliOnlyLine!).toMatch(/'reindex',/);
});

test("subprocess `gbrain reindex --markdown --help` does not report 'Unknown command'", async () => {
const proc = Bun.spawn(
['bun', 'run', 'src/cli.ts', 'reindex', '--markdown', '--help'],
{
cwd: REPO_ROOT,
stdout: 'pipe',
stderr: 'pipe',
env: { ...process.env, DATABASE_URL: '' },
},
);
const stderr = await new Response(proc.stderr).text();
const stdout = await new Response(proc.stdout).text();
await proc.exited;
// Either prints help OR fails on something else (e.g. connect / args).
// The one outcome that MUST NOT happen is the dispatch-layer
// "Unknown command: reindex" exit-1 path. That's the bug this PR fixes.
expect(stderr + stdout).not.toContain('Unknown command: reindex');
});
});
Loading