feat(create-sanity): bundle init logic into single file#759
feat(create-sanity): bundle init logic into single file#759rexxars wants to merge 30 commits intobundled-createfrom
init logic into single file#759Conversation
…rectly Replaces the spawn-wrapper approach with a TypeScript entry point that parses flags using @oclif/core/parser (reusing InitCommand.flags for exact parity) and calls initAction() directly. Uses no-op telemetry stub. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Switch from esbuild to Rollup for the create-sanity standalone bundle to enable better tree-shaking of barrel exports. Rollup resolves @sanity/cli-core source directly via alias plugin so it can tree-shake unused exports from the barrel. Plugins: alias, node-resolve, commonjs, json, esbuild (transpile only). Bundle size is ~13MB (same as esbuild - tree-shaking improvements will come in subsequent tasks with stub removal). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add lightweight error formatting utilities that match oclif's pretty-printed error output (bang prefix, word wrap, clean stacks, suggestions) without depending on @oclif/core. - CLIError: formatted error with oclif-compatible shape so oclif's error handler still recognizes it when thrown from commands - CLIWarning: same but with yellow bang prefix - error()/warn(): standalone functions for printing to stderr Update NonInteractiveError and ProjectRootNotFoundError to extend our CLIError instead of oclif's. Replace oclif ux imports in apiClient.ts and getCliTelemetry.ts with node:util styleText and our warn(). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace oclif ux.warn/ux.stdout with our own warn() from @sanity/cli-core/ux in setupMCP.ts. Replace console.log for stdout output. Replace CLIError with InitError in createOrAppendEnvVars.ts. Remove oclif import from promptForDefaultConfig.ts. These files are transitively bundled into create-sanity, so removing oclif imports here prevents the entire oclif runtime from being pulled into the standalone bundle. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract flag definitions from InitCommand into plain objects in flags.ts with zero @oclif/core imports. These can be consumed by both the oclif command (via toOclifFlags adapter) and create-sanity's standalone entry point (via node:util parseArgs). - flags.ts: POJO flag/arg definitions shared across consumers - flagAdapter.ts: toOclifFlags/toOclifArgs converters - init.ts: uses adapter instead of direct oclif flag helpers - types.ts: env flag validation moved to flagsToInitOptions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rewrite the standalone entry point to use parseArgs instead of @oclif/core/parser, consuming the shared POJO flag definitions directly. This eliminates @oclif/core from the bundle entirely. - Handles --no-<flag> negation via companion boolean flags - Adds --help with formatted flag listing - Validates flag types at runtime - Removes module stubs (no longer needed with Rollup tree-shaking) - Simplifies Rollup config (no typescript external needed) Bundle: 2.9 MB with zero oclif, zero typescript, zero stubs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add stdout/stderr output helpers to @sanity/cli-core/ux to avoid bare console.log/console.error in lint-strict packages - Fix type errors: OclifChar narrowing, oclif overload disambiguation, FlagDef iteration, Output.warn/error signatures, noopTelemetry - Fix lint: eslint-disable for error output layer, perfectionist sorting - Use stdout() from cli-core/ux in setupMCP and promptForDefaultConfig - Add package manager detection for help text (npm/pnpm/yarn) - Handle ERR_PARSE_ARGS_UNKNOWN_OPTION with clean error message - Delete old create-sanity files: build.ts, index.js, test.js, vitest.config.mjs (replaced by rollup config and new test suite) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tests run against the built dist/index.js bundle and cover: - --help output with flag listing - Package manager detection (npm/pnpm/yarn) in help text - Hidden flags not shown in help - -h shorthand - --help precedence over other flags - Invalid flag produces clean error (no stack trace) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove unused devDeps: @oclif/core, tsx - Add debug as devDep (used in rollup.config.ts alias) - Remove unused InitFlagName type export - Add knip ignore for @sanity/cli (imported via relative source paths) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace dynamic import of ImportDatasetCommand with spawning the project's own sanity binary via execa. The dynamic import pulled the entire oclif command tree into the create-sanity bundle because Rollup inlines all dynamic imports. The scaffolded project always has sanity as a dependency, so spawning its binary for dataset import works in both standalone and oclif contexts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The function is 4 lines - no need for a separate package. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace custom detectPackageManager with the shared getRunningPackageManager from @sanity/cli-core/package-manager. Adds bun support for help text (`bun create sanity@latest`). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
create-sanity now handles --help itself via parseArgs, so it never delegates to `sanity init --help`. The --from-create flag, the SanityHelp.replaceInitWithCreateCommand rewriting, and the fromCreate option in InitOptions are all unused. Remove them. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
npm requires `--` to forward flags to the create script (e.g. `npm create sanity@latest -- --template moviedb`). Other package managers don't need it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move flagsToInitOptions, InitCommandFlags, InitCommandArgs, and the narrowing helpers out of types.ts into flagsToInitOptions.ts. types.ts now only contains type definitions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Claude finished @rexxars's task in 4m 9s —— View job Code Review
The old oclif throw new InitError('Env filename (`--env`) must start with `.env`', 3)
The catch block discards the underlying } catch {
output.warn('Sample dataset import failed. ...')
}If the import fails due to auth, network, or an } catch (err) {
subdebug('Dataset import failed: %O', err)
output.warn('Sample dataset import failed. ...')
}
Imports like
|
f51850a to
020c660
Compare
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Add fs.access check before spawning the sanity binary for dataset import. Gives a clear error message instead of a raw ENOENT if dependencies weren't installed correctly. Also fix misleading vitest config comment. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use execa preferLocal instead of manual .bin path (Windows compat) - Fix exit:0 being silently discarded in CLIError (0 || undefined bug) - Remove duplicate --env validation from InitCommand (flagsToInitOptions is the canonical location, shared with create-sanity) - Remove unused overrides parameter from toOclifFlags Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… constraints parseArgs doesn't support oclif features like aliases, option validation, or exclusive constraints. Add post-parse handling: - Register flag aliases (e.g. --project-id) as separate parseArgs options, then resolve them back to canonical names - Validate string flags with `options` against allowed values (--package-manager, --visibility) - Check exclusive constraints and error if conflicting flags are passed Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move all parseArgs logic (option building, alias resolution, negation merging, option/exclusive validation, help printing) out of index.ts into a dedicated parseArgs.ts module. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
895b6fa to
e6848b3
Compare
- Replace ImportDatasetCommand mock with execa mock - Update assertion to match new call signature (binary name, args, options) - Fix env validation exit code expectation (now InitError exit:1, not oclif exit:2) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Establish consistent exit code semantics: - 1: init action runtime failure (auth, missing deps, etc) - 2: flag parsing/validation error (unknown flag, invalid option value, exclusive constraint violation) - 3: domain-specific flag validation (e.g. --env must start with .env) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add pretest script so `pnpm test` builds the bundle before running - Wrap execa call in initStudio with try/catch so dataset import failures produce a clean InitError instead of dumping ExecaError - Add explicit default:false to bare, dataset-default, no-git flags so parseArgs always populates them, matching InitCommandFlags types Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Coverage Delta
Comparing 32 changed files against main @ Overall Coverage
|
- Use helpLabel when defined (e.g. --[no-]git) - Show --[no-] prefix for allowNo boolean flags - Wrap long descriptions to terminal width - Show --help in the options list - Error when both a flag and its alias are passed (--project + --project-id) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
On Windows, environment variables are case-insensitive but process.env preserves the original casing. When overriding npm_config_user_agent in tests, the original key (potentially different casing) wasn't being removed, so the override was ineffective. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rewrite printHelp to match oclif's help formatting:
- Terminal width detection: OCLIF_COLUMNS env > TTY width > 80 fallback,
clamped to minimum 40
- Use wrap-ansi with {hard: true} for description wrapping
- Dynamic left column width based on widest flag label
- Automatic multiline format (flag on own line, description below) when
any description wraps to >4 lines at current terminal width
- Wrap first, then indent (matching oclif's ordering)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
01fd21e to
3d2e1e9
Compare
3d2e1e9 to
a27419e
Compare
…sanity Move mcpMode computation into flagsToInitOptions so the identical logic in init.ts and create-sanity/index.ts cannot diverge. The function now takes an `interactive` boolean and derives both `isUnattended` and `mcpMode` internally. Add deprecation warnings in parseArgs.ts so that create-sanity users see feedback when using --reconfigure, --create-project, or --quickstart (oclif handles this automatically for `sanity init`, but the standalone path was silent). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Description
Note
Part 3/4 of the ongoing work to make
create-sanityfaster by bundling theinitlogicThis mostly completes the work - the remaining part is the telemetry integration and an optional but wanted step at reducing the amount of dependencies we rely on for the init step.
The bundling script has a few hacks that would be nice to get rid of over time, but not the end of the world.
What to review
Testing