* The `init` flow — shared by `codegraph init` and `codegraph install --init` * (#1578): refuse an unsafe root, create `.codegraph/`, build the initial * index under supervision, then the post-index offers. `yes` makes every * offer non-interactive (defaults only), so a container / CI bootstrap n
(
projectPath: string,
options: { index?: boolean; force?: boolean; verbose?: boolean; yes?: boolean },
)
| 615 | * (no `--force` is implied by any caller); an index failure exits 1. |
| 616 | */ |
| 617 | async function runInit( |
| 618 | projectPath: string, |
| 619 | options: { index?: boolean; force?: boolean; verbose?: boolean; yes?: boolean }, |
| 620 | ): Promise<void> { |
| 621 | const clack = await importESM('@clack/prompts'); |
| 622 | |
| 623 | clack.intro('Initializing CodeGraph'); |
| 624 | |
| 625 | try { |
| 626 | // Refuse to index your home directory / a filesystem root — it pulls in |
| 627 | // caches, other projects, and your whole tree (a multi-GB index + watcher |
| 628 | // churn, and on pre-1.0 macOS a machine-crashing fd blowup, #845). |
| 629 | const unsafe = unsafeIndexRootReason(projectPath); |
| 630 | if (unsafe && !options.force) { |
| 631 | clack.log.error(`Refusing to initialize in ${projectPath} — it looks like ${unsafe}.`); |
| 632 | clack.log.info('Run this inside a specific project directory, or pass --force if you really mean to index everything under it.'); |
| 633 | clack.outro(''); |
| 634 | process.exitCode = 1; |
| 635 | return; |
| 636 | } |
| 637 | |
| 638 | if (isInitialized(projectPath)) { |
| 639 | clack.log.warn(`Already initialized in ${projectPath}`); |
| 640 | clack.log.info('Use "codegraph index" to re-index or "codegraph sync" to update'); |
| 641 | try { |
| 642 | const { offerWatchFallback } = await import('../installer'); |
| 643 | await offerWatchFallback(clack, projectPath, { yes: options.yes }); |
| 644 | } catch { /* non-fatal */ } |
| 645 | clack.outro(''); |
| 646 | return; |
| 647 | } |
| 648 | |
| 649 | const { default: CodeGraph, getDatabasePath } = await loadCodeGraph(); |
| 650 | const cg = await CodeGraph.init(projectPath, { index: false }); |
| 651 | clack.log.success(`Initialized in ${projectPath}`); |
| 652 | |
| 653 | // Indexing runs by default now. The legacy -i/--index flag is still |
| 654 | // accepted (so existing muscle memory and scripts don't break) but is a |
| 655 | // no-op — initializing always builds the initial index. |
| 656 | // Supervise the index: self-terminate if orphaned or wedged (#999). |
| 657 | // The DB + WAL paths let the liveness watchdog tell a slow store on |
| 658 | // degraded storage from a true wedge (#1231). |
| 659 | // A closure so we can re-run the exact same supervised, progress-rendered |
| 660 | // index if the user opts gitignored child repos in below (#1156). |
| 661 | const dbPath = getDatabasePath(projectPath); |
| 662 | const runIndex = async (): Promise<IndexResult> => { |
| 663 | const supervision = installCommandSupervision('init', { progressPaths: [dbPath, `${dbPath}-wal`] }); |
| 664 | try { |
| 665 | if (options.verbose) { |
| 666 | return await cg.indexAll({ onProgress: createVerboseProgress(), verbose: true }); |
| 667 | } |
| 668 | process.stdout.write(`${colors.dim}${getGlyphs().rail}${colors.reset}\n`); |
| 669 | const progress = createShimmerProgress(); |
| 670 | const r = await cg.indexAll({ onProgress: progress.onProgress }); |
| 671 | await progress.stop(); |
| 672 | return r; |
| 673 | } finally { |
| 674 | supervision.stop(); |
no test coverage detected