mirror of
https://github.com/Fission-AI/OpenSpec.git
synced 2026-10-26 07:13:17 +08:00
* perf(cli): load each command's implementation only when it runs src/cli/index.ts statically imported every command module, so every invocation, even `openspec --version`, loaded 485 modules (zod, yaml, fast-glob, ora, diff and every command) before commander ran. Callers that run the CLI many times, such as editors and agents, paid for that on each call, most on Windows where Node loads modules slowly. Command definitions (names, options, help) stay eager; implementations move behind `await import()` in their actions, the pattern `init` already used. The `register*Command` modules that mixed both are split: the definitions live in src/cli/commands/, and each action body moves unchanged into an exported function in src/commands/. Telemetry, the completion tip, ora in failWithError, and the config profile's drift check and update load on demand too. `--version` and `--help` now load 24 modules (commander and the definitions); median wall time on macOS drops from ~150 ms to ~33 ms (`node -e 0` is 18 ms). Help for every command, completion scripts, exit codes, `--json` output, error messages and telemetry events are byte-identical before and after. test/cli-e2e/startup-modules.test.ts runs the built CLI with a module-recording hook and asserts that `--version` and `--help` load no package but commander and no command implementation, and that a command loads only its own implementation. It fails on main. * docs(contributing): keep the CLI's startup fast * test(cli): compare loaded modules against the real dist/ path Node reports loaded modules by their real paths, so a checkout reached through a symlink or a Windows short name made every module look foreign and the absence checks pass without checking anything. Resolve dist/ with realpathSync.native, fail when no CLI module was recorded, and require --version and --help to exit 0.