Skip to content

Commit 94be7ad

Browse files
rsbhclaude
andcommitted
fix: chronicle start runs Nitro production server instead of Vite preview
Replace Vite preview() with spawning node .output/server/index.mjs for proper SSR, API routes, and search in production. Checks build exists, forwards signals to child process. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent eef9f1e commit 94be7ad

1 file changed

Lines changed: 37 additions & 14 deletions

File tree

  • packages/chronicle/src/cli/commands
Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,52 @@
1+
import { existsSync } from 'node:fs';
2+
import path from 'node:path';
3+
import { spawn } from 'node:child_process';
14
import chalk from 'chalk';
25
import { Command } from 'commander';
36
import { loadCLIConfig } from '@/cli/utils/config';
4-
import { PACKAGE_ROOT } from '@/cli/utils/resolve';
5-
import { linkContent } from '@/cli/utils/scaffold';
7+
8+
function resolveServerEntry(projectRoot: string, preset?: string): string {
9+
if (preset === 'vercel' || preset === 'vercel-static') {
10+
return path.resolve(projectRoot, '.vercel/output/server/index.mjs');
11+
}
12+
return path.resolve(projectRoot, '.output/server/index.mjs');
13+
}
614

715
export const startCommand = new Command('start')
816
.description('Start production server')
917
.option('-p, --port <port>', 'Port number', '3000')
1018
.option('--config <path>', 'Path to chronicle.yaml')
11-
.option('--host <host>', 'Host address', 'localhost')
19+
.option('--host <host>', 'Host address', '0.0.0.0')
20+
.option('--preset <preset>', 'Deploy preset (must match build preset)')
1221
.action(async options => {
13-
const { config, projectRoot, configPath } = await loadCLIConfig(options.config);
14-
const port = parseInt(options.port, 10);
15-
await linkContent(projectRoot, config);
22+
const { config, projectRoot } = await loadCLIConfig(options.config);
23+
const preset = options.preset ?? config.preset;
24+
const serverEntry = resolveServerEntry(projectRoot, preset);
1625

17-
console.log(chalk.cyan('Starting production server...'));
26+
if (!existsSync(serverEntry)) {
27+
console.error(chalk.red(`No build found at ${serverEntry}`));
28+
console.error(chalk.red('Run `chronicle build` first.'));
29+
process.exit(1);
30+
}
1831

19-
const { preview } = await import('vite');
20-
const { createViteConfig } = await import('@/server/vite-config');
32+
console.log(chalk.cyan('Starting production server...'));
2133

22-
const viteConfig = await createViteConfig({ packageRoot: PACKAGE_ROOT, projectRoot, configPath });
23-
const server = await preview({
24-
...viteConfig,
25-
preview: { port, host: options.host }
34+
const child = spawn(process.execPath, [serverEntry], {
35+
stdio: 'inherit',
36+
env: {
37+
...process.env,
38+
PORT: options.port,
39+
HOST: options.host,
40+
},
2641
});
2742

28-
server.printUrls();
43+
const shutdown = () => {
44+
child.kill('SIGTERM');
45+
};
46+
process.once('SIGINT', shutdown);
47+
process.once('SIGTERM', shutdown);
48+
49+
child.on('exit', (code) => {
50+
process.exit(code ?? 0);
51+
});
2952
});

0 commit comments

Comments
 (0)