prisma-next 0.8.0-dev.4 → 0.8.0-dev.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +2 -2
- package/dist/cli.mjs.map +1 -1
- package/dist/exports/init-output.mjs +1 -1
- package/dist/{init-CVBXQidr.mjs → init-1-s6FvGv.mjs} +99 -52
- package/dist/init-1-s6FvGv.mjs.map +1 -0
- package/dist/{output-nBJ6NvsE.mjs → output-DEg3SSnJ.mjs} +2 -2
- package/dist/{output-nBJ6NvsE.mjs.map → output-DEg3SSnJ.mjs.map} +1 -1
- package/package.json +10 -10
- package/dist/init-CVBXQidr.mjs.map +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -35,8 +35,8 @@ Exit codes (see CLI Style Guide § Exit Codes):
|
|
|
35
35
|
"prisma-next init --no-install # skip pnpm/npm install + emit",
|
|
36
36
|
"prisma-next init --no-skill # skip the agent-skill install (air-gapped / restricted env)"
|
|
37
37
|
]);
|
|
38
|
-
return addGlobalOptions(command).option("--target <db>", "Database target: postgres or mongodb").option("--authoring <style>", "Schema authoring style: psl or typescript").option("--schema-path <path>", "Where to write the starter schema (default: prisma/contract.prisma)").option("--force", "Overwrite an existing scaffold without prompting").option("--write-env", "Write a .env file from .env.example (gitignored; default: only .env.example)").option("--probe-db", "Connect to DATABASE_URL once and check the server version against the target minimum (opt-in; off by default)").option("--strict-probe", "Treat a failed --probe-db as fatal (no-op without --probe-db; init is offline-by-default)").option("--no-install", "Skip dependency installation and contract emission").option("--no-skill", "Skip
|
|
39
|
-
const { runInit } = await import("./init-
|
|
38
|
+
return addGlobalOptions(command).option("--target <db>", "Database target: postgres or mongodb").option("--authoring <style>", "Schema authoring style: psl or typescript").option("--schema-path <path>", "Where to write the starter schema (default: prisma/contract.prisma)").option("--force", "Overwrite an existing scaffold without prompting").option("--write-env", "Write a .env file from .env.example (gitignored; default: only .env.example)").option("--probe-db", "Connect to DATABASE_URL once and check the server version against the target minimum (opt-in; off by default)").option("--strict-probe", "Treat a failed --probe-db as fatal (no-op without --probe-db; init is offline-by-default)").option("--no-install", "Skip dependency installation and contract emission").option("--no-skill", "Skip Prisma Next skills install (air-gapped CI, restricted registries, etc.)").action(async (options) => {
|
|
39
|
+
const { runInit } = await import("./init-1-s6FvGv.mjs");
|
|
40
40
|
const flags = parseGlobalFlags(options);
|
|
41
41
|
const canPrompt = deriveCanPrompt({
|
|
42
42
|
flagsInteractive: flags.interactive,
|
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/commands/init/index.ts","../src/utils/suggest-command.ts","../src/cli.ts"],"sourcesContent":["import { Command } from 'commander';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../../utils/command-helpers';\nimport { type CommonCommandOptions, parseGlobalFlags } from '../../utils/global-flags';\nimport {\n INIT_EXIT_EMIT_FAILED,\n INIT_EXIT_INSTALL_FAILED,\n INIT_EXIT_INTERNAL_ERROR,\n INIT_EXIT_OK,\n INIT_EXIT_PRECONDITION,\n INIT_EXIT_SKILL_INSTALL_FAILED,\n INIT_EXIT_USER_ABORTED,\n} from './exit-codes';\n\n/**\n * Commander.js parsed options for `init`. The init-specific options live\n * alongside the inherited `CommonCommandOptions` global flags.\n *\n * `target` and `authoring` are typed as plain `string` here because\n * Commander.js does not enforce enums at parse time — the validation /\n * normalisation happens in `inputs.ts::resolveInitInputs`, which can\n * raise a structured `errorInitInvalidFlagValue` with the full set of\n * allowed values.\n */\ninterface InitCommandOptions extends CommonCommandOptions {\n readonly target?: string;\n readonly authoring?: string;\n readonly schemaPath?: string;\n readonly force?: boolean;\n readonly writeEnv?: boolean;\n readonly probeDb?: boolean;\n readonly strictProbe?: boolean;\n readonly install?: boolean;\n readonly skill?: boolean;\n}\n\nexport function createInitCommand(): Command {\n const command = new Command('init');\n setCommandDescriptions(\n command,\n 'Initialize a new Prisma Next project',\n 'Scaffolds config, schema, and runtime files, installs dependencies,\\n' +\n 'and emits the contract. Gets you from zero to typed queries in one step.\\n' +\n '\\n' +\n 'Run interactively for a guided experience, or supply --target / --authoring\\n' +\n 'and --yes for a fully scriptable run (CI, AI coding agents, automation).\\n' +\n '\\n' +\n 'Exit codes (see CLI Style Guide § Exit Codes):\\n' +\n ` ${INIT_EXIT_OK} OK Init succeeded.\\n` +\n ` ${INIT_EXIT_INTERNAL_ERROR} INTERNAL_ERROR Unexpected bug in prisma-next (please report).\\n` +\n ` ${INIT_EXIT_PRECONDITION} PRECONDITION Bad flags / missing prerequisite (e.g. no package.json).\\n` +\n ` ${INIT_EXIT_USER_ABORTED} USER_ABORTED User cancelled an interactive prompt.\\n` +\n ` ${INIT_EXIT_INSTALL_FAILED} INSTALL_FAILED Dependency installation failed (init-specific).\\n` +\n ` ${INIT_EXIT_EMIT_FAILED} EMIT_FAILED \\`contract emit\\` failed after install (init-specific).\\n` +\n ` ${INIT_EXIT_SKILL_INSTALL_FAILED} SKILL_INSTALL_FAILED Agent-skill install failed (re-run with --no-skill to skip).`,\n );\n setCommandExamples(command, [\n 'prisma-next init',\n 'prisma-next init --yes --target postgres --authoring psl',\n 'prisma-next init --yes --target mongodb --authoring typescript --json',\n 'prisma-next init --yes --force --target postgres --authoring psl # overwrite an existing scaffold',\n 'prisma-next init --no-install # skip pnpm/npm install + emit',\n 'prisma-next init --no-skill # skip the agent-skill install (air-gapped / restricted env)',\n ]);\n\n return addGlobalOptions(command)\n .option('--target <db>', 'Database target: postgres or mongodb')\n .option('--authoring <style>', 'Schema authoring style: psl or typescript')\n .option(\n '--schema-path <path>',\n 'Where to write the starter schema (default: prisma/contract.prisma)',\n )\n .option('--force', 'Overwrite an existing scaffold without prompting')\n .option(\n '--write-env',\n 'Write a .env file from .env.example (gitignored; default: only .env.example)',\n )\n .option(\n '--probe-db',\n 'Connect to DATABASE_URL once and check the server version against the target minimum (opt-in; off by default)',\n )\n .option(\n '--strict-probe',\n 'Treat a failed --probe-db as fatal (no-op without --probe-db; init is offline-by-default)',\n )\n .option('--no-install', 'Skip dependency installation and contract emission')\n .option(\n '--no-skill',\n 'Skip the @prisma-next/skills install (air-gapped CI, restricted registries, etc.)',\n )\n .action(async (options: InitCommandOptions) => {\n const { runInit } = await import('./init');\n const flags = parseGlobalFlags(options);\n const canPrompt = deriveCanPrompt({\n flagsInteractive: flags.interactive,\n optionInteractive: options.interactive,\n stdinIsTTY: Boolean(process.stdin.isTTY),\n });\n const exitCode = await runInit(process.cwd(), { options, flags, canPrompt });\n process.exit(exitCode);\n });\n}\n\n/**\n * Bridges the action handler's two TTY checks (stdout via `flags`, stdin\n * via `process.stdin.isTTY`) into the `canPrompt` boolean `runInit`\n * consumes.\n *\n * Per the [Style Guide § Interactivity](../../../../../../../docs/CLI%20Style%20Guide.md#interactivity):\n *\n * - `flags.interactive` governs *decoration* (TerminalUI, intro/outro,\n * spinners) and is derived from stdout-TTY by `parseGlobalFlags`,\n * honouring `--interactive` / `--no-interactive`.\n * - Prompting additionally requires a stdin TTY — closing stdin is a\n * common signal in CI / agent environments even when stdout stays\n * attached.\n * - `--interactive` is the explicit override: when the user passes it,\n * we honour it (e.g. testing flows where stdin is stubbed).\n *\n * Exported so callers and tests can derive the same value without\n * touching `process` globals.\n */\nexport function deriveCanPrompt(opts: {\n readonly flagsInteractive: boolean | undefined;\n readonly optionInteractive: boolean | undefined;\n readonly stdinIsTTY: boolean;\n}): boolean {\n if (opts.optionInteractive === true) return true;\n if (opts.flagsInteractive === false) return false;\n return opts.stdinIsTTY;\n}\n","import { distance } from 'closest-match';\n\n/**\n * Suggests similar command names for a mistyped input.\n *\n * Uses Levenshtein distance to find close matches. Only suggests commands\n * within a reasonable distance threshold (40% of the input length, minimum 2).\n * Returns up to 3 suggestions in case of ties.\n *\n * @returns Array of suggested command names (empty if nothing is close enough).\n */\nexport function suggestCommands(input: string, candidates: readonly string[]): string[] {\n if (candidates.length === 0) return [];\n\n // Threshold: at most 40% of the input length (min 2) to avoid absurd suggestions\n const maxDistance = Math.max(2, Math.ceil(input.length * 0.4));\n\n const scored = candidates\n .map((name) => ({ name, dist: distance(input, name) }))\n .filter((entry) => entry.dist <= maxDistance)\n .sort((a, b) => a.dist - b.dist);\n\n if (scored.length === 0) return [];\n\n // Take the best distance, then include ties (up to 3)\n const bestDist = scored[0]!.dist;\n return scored\n .filter((entry) => entry.dist === bestDist)\n .slice(0, 3)\n .map((entry) => entry.name);\n}\n","import { Command } from 'commander';\nimport { createContractEmitCommand } from './commands/contract-emit';\nimport { createContractInferCommand } from './commands/contract-infer';\nimport { createInitCommand } from './commands/init';\nimport { installShutdownHandlers } from './utils/shutdown';\n\n// Install SIGINT/SIGTERM handlers before anything else\ninstallShutdownHandlers();\n\nimport { createDbInitCommand } from './commands/db-init';\nimport { createDbSchemaCommand } from './commands/db-schema';\nimport { createDbSignCommand } from './commands/db-sign';\nimport { createDbUpdateCommand } from './commands/db-update';\nimport { createDbVerifyCommand } from './commands/db-verify';\nimport { createMigrationApplyCommand } from './commands/migration-apply';\nimport { createMigrationNewCommand } from './commands/migration-new';\nimport { createMigrationPlanCommand } from './commands/migration-plan';\nimport { createMigrationRefCommand } from './commands/migration-ref';\nimport { createMigrationShowCommand } from './commands/migration-show';\nimport { createMigrationStatusCommand } from './commands/migration-status';\nimport { setCommandDescriptions } from './utils/command-helpers';\nimport { formatCommandHelp, formatRootHelp } from './utils/formatters/help';\nimport { parseGlobalFlags } from './utils/global-flags';\nimport { suggestCommands } from './utils/suggest-command';\n\n/**\n * Formats the \"Did you mean ...?\" hint for an unknown command.\n */\nfunction formatSuggestion(input: string, candidates: readonly string[]): string {\n const suggestions = suggestCommands(\n input,\n candidates.map((c) => c),\n );\n if (suggestions.length === 0) return '';\n if (suggestions.length === 1) return `\\nDid you mean ${suggestions[0]}?\\n`;\n return `\\nDid you mean one of these?\\n${suggestions.map((s) => ` ${s}`).join('\\n')}\\n`;\n}\n\nconst program = new Command();\n\nprogram.name('prisma-next').description('Prisma Next CLI').version('0.0.1');\n\n// Override version option description to match capitalization style\nconst versionOption = program.options.find((opt) => opt.flags.includes('--version'));\nif (versionOption) {\n versionOption.description = 'Output the version number';\n}\n\nprogram.configureOutput({\n writeErr: () => {\n // Suppress all default error output - we handle errors in exitOverride\n },\n writeOut: (str) => {\n // Commander routes explicitly-requested `--help` (success-path help)\n // through writeOut; per the Style Guide § Output Conventions rule 8,\n // user-requested help is data and goes to stdout. Error-path help\n // (e.g. usage shown after an unknown command) goes through writeErr,\n // which stays suppressed because we render that ourselves with the\n // matching error envelope.\n //\n // Explicit `--version` is short-circuited before `program.parse()`\n // (see the argv pre-scan at the bottom of this file), so it does not\n // reach this writer.\n process.stdout.write(str);\n },\n});\n\n// Customize root help output to use our styled format\nconst rootHelpFormatter = (cmd: Command) => {\n const flags = parseGlobalFlags({});\n return formatRootHelp({ program: cmd, flags });\n};\n\nprogram.configureHelp({\n formatHelp: rootHelpFormatter,\n subcommandDescription: () => '',\n});\n\n// Override exit to handle unhandled errors (fail fast cases)\n// Commands handle structured errors themselves via process.exit()\nprogram.exitOverride((err) => {\n if (err) {\n const errorCode = (err as { code?: string }).code;\n const errorMessage = String(err.message ?? '');\n const errorName = err.name ?? '';\n\n // Unknown command/argument → exit 2 (CLI usage error)\n const isUnknownCommandError =\n errorCode === 'commander.unknownCommand' ||\n errorCode === 'commander.unknownArgument' ||\n (errorName === 'CommanderError' &&\n (errorMessage.includes('unknown command') || errorMessage.includes('unknown argument')));\n if (isUnknownCommandError) {\n const flags = parseGlobalFlags({});\n const match = errorMessage.match(/unknown command ['\"]([^'\"]+)['\"]/);\n const commandName = match ? match[1] : process.argv[3] || process.argv[2] || 'unknown';\n\n const firstArg = process.argv[2];\n const parentCommand = firstArg\n ? program.commands.find((cmd) => cmd.name() === firstArg)\n : undefined;\n\n if (parentCommand && commandName !== firstArg) {\n const subNames = parentCommand.commands.map((c) => c.name());\n process.stderr.write(\n `Unknown command: ${commandName}${formatSuggestion(commandName!, subNames)}\\n`,\n );\n const helpText = formatCommandHelp({ command: parentCommand, flags });\n process.stderr.write(`${helpText}\\n`);\n } else {\n const topNames = program.commands.map((c) => c.name());\n process.stderr.write(\n `Unknown command: ${commandName}${formatSuggestion(commandName!, topNames)}\\n`,\n );\n const helpText = formatRootHelp({ program, flags });\n process.stderr.write(`${helpText}\\n`);\n }\n process.exit(2);\n return;\n }\n\n // Help requests → exit 0\n const isHelpError =\n errorCode === 'commander.help' ||\n errorCode === 'commander.helpDisplayed' ||\n errorCode === 'outputHelp' ||\n errorMessage === '(outputHelp)' ||\n errorMessage.includes('outputHelp') ||\n (errorName === 'CommanderError' && errorMessage.includes('outputHelp'));\n if (isHelpError) {\n process.exit(0);\n return;\n }\n\n // Missing required arguments → exit 2 (CLI usage error)\n const isMissingArgumentError =\n errorCode === 'commander.missingArgument' ||\n errorCode === 'commander.missingMandatoryOptionValue' ||\n (errorName === 'CommanderError' &&\n (errorMessage.includes('missing') || errorMessage.includes('required')));\n if (isMissingArgumentError) {\n process.exit(2);\n return;\n }\n\n // Unhandled error → exit 1\n process.stderr.write(`Unhandled error: ${err.message}\\n`);\n if (err.stack) {\n process.stderr.write(`${err.stack}\\n`);\n }\n process.exit(1);\n }\n process.exit(0);\n});\n\n// Register contract subcommand\nconst contractCommand = new Command('contract');\nsetCommandDescriptions(\n contractCommand,\n 'Contract management commands',\n 'Define and emit your application data contract. The contract describes your schema as a\\n' +\n 'declarative data structure that can be signed and verified against your database.',\n);\ncontractCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\n// Add emit subcommand to contract\nconst contractEmitCommand = createContractEmitCommand();\ncontractCommand.addCommand(contractEmitCommand);\n\n// Add infer subcommand to contract\nconst contractInferCommand = createContractInferCommand();\ncontractCommand.addCommand(contractInferCommand);\n\n// Register contract command\nprogram.addCommand(contractCommand);\n\n// Register db subcommand\nconst dbCommand = new Command('db');\nsetCommandDescriptions(\n dbCommand,\n 'Database management commands',\n 'Verify and sign your database with your contract. Ensure your database schema matches\\n' +\n 'your contract, and sign it to record the contract hash for future verification.',\n);\ndbCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\n// Add verify subcommand to db\nconst dbVerifyCommand = createDbVerifyCommand();\ndbCommand.addCommand(dbVerifyCommand);\n\n// Add init subcommand to db\nconst dbInitCommand = createDbInitCommand();\ndbCommand.addCommand(dbInitCommand);\n\n// Add update subcommand to db\nconst dbUpdateCommand = createDbUpdateCommand();\ndbCommand.addCommand(dbUpdateCommand);\n\n// Add schema subcommand to db\nconst dbSchemaCommand = createDbSchemaCommand();\ndbCommand.addCommand(dbSchemaCommand);\n\n// Add sign subcommand to db\nconst dbSignCommand = createDbSignCommand();\ndbCommand.addCommand(dbSignCommand);\n\n// Register db command\nprogram.addCommand(dbCommand);\n\n// Register migration subcommand\nconst migrationCommand = new Command('migration');\nsetCommandDescriptions(\n migrationCommand,\n 'On-disk migration management commands',\n 'Plan, apply, and scaffold on-disk migration packages. Migrations are\\n' +\n 'contract-to-contract edges stored as versioned directories under migrations/.',\n);\nmigrationCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\nconst migrationPlanCommand = createMigrationPlanCommand();\nmigrationCommand.addCommand(migrationPlanCommand);\n\nconst migrationNewCommand = createMigrationNewCommand();\nmigrationCommand.addCommand(migrationNewCommand);\n\nconst migrationShowCommand = createMigrationShowCommand();\nmigrationCommand.addCommand(migrationShowCommand);\n\nconst migrationStatusCommand = createMigrationStatusCommand();\nmigrationCommand.addCommand(migrationStatusCommand);\n\nconst migrationApplyCommand = createMigrationApplyCommand();\nmigrationCommand.addCommand(migrationApplyCommand);\n\nconst migrationRefCommand = createMigrationRefCommand();\nmigrationCommand.addCommand(migrationRefCommand);\n\nprogram.addCommand(migrationCommand);\n\n// Register init command (top-level, not nested)\nconst initCommand = createInitCommand();\nprogram.addCommand(initCommand);\n\n// Create help command\nconst helpCommand = new Command('help')\n .description('Show usage instructions')\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .action(() => {\n const flags = parseGlobalFlags({});\n const helpText = formatRootHelp({ program, flags });\n // The `help` command was invoked explicitly: help is the data the\n // caller asked for. Per Style Guide § Output Conventions rule 8,\n // explicit help goes to stdout with exit code 0.\n process.stdout.write(`${helpText}\\n`);\n process.exit(0);\n });\n\nprogram.addCommand(helpCommand);\n\n// Set help as the default action when no command is provided. The user\n// did not invoke `--help`; we are voluntarily showing usage to help them\n// recover from an underspecified invocation, so the help text is\n// decoration around an implicit \"what did you want me to do?\" and goes\n// to stderr (Style Guide § Output Conventions rule 8).\n//\n// FOLLOW-UP: the exit code here is 0 today, but a no-arg invocation is\n// arguably a usage error (PRECONDITION → exit 2) for consistency with\n// the unknown-command path. Out of scope for the explicit-help routing\n// work; revisit when tightening exit-code semantics across the CLI.\nprogram.action(() => {\n const flags = parseGlobalFlags({});\n const helpText = formatRootHelp({ program, flags });\n process.stderr.write(`${helpText}\\n`);\n process.exit(0);\n});\n\n// Check if a command was invoked with no arguments (just the command name)\n// or if an unrecognized command was provided\nconst args = process.argv.slice(2);\nif (args.length > 0) {\n const commandName = args[0];\n // Handle version option explicitly since we suppress default output\n if (commandName === '--version' || commandName === '-V') {\n // Version is data → stdout\n process.stdout.write(`${program.version()}\\n`);\n process.exit(0);\n }\n // Skip command check for global options like --help, -h\n const isGlobalOption = commandName === '--help' || commandName === '-h';\n if (!isGlobalOption) {\n // Check if this is a recognized command\n const command = program.commands.find((cmd) => cmd.name() === commandName);\n\n if (!command) {\n // Unrecognized command → exit 2 (CLI usage error)\n const flags = parseGlobalFlags({});\n const topNames = program.commands.map((c) => c.name());\n process.stderr.write(\n `Unknown command: ${commandName}${formatSuggestion(commandName!, topNames)}\\n`,\n );\n const helpText = formatRootHelp({ program, flags });\n process.stderr.write(`${helpText}\\n`);\n process.exit(2);\n } else if (command.commands.length > 0 && args.length === 1) {\n // Parent command called with no subcommand. Same shape as the\n // no-args case above: the user did not request help, we are\n // voluntarily rendering it as decoration around an underspecified\n // invocation, so it goes to stderr per Style Guide § Output\n // Conventions rule 8. Exit code 0 today; the FOLLOW-UP note on\n // `program.action` applies here too (arguably should be 2).\n const flags = parseGlobalFlags({});\n const helpText = formatCommandHelp({ command, flags });\n process.stderr.write(`${helpText}\\n`);\n process.exit(0);\n }\n }\n}\n\nprogram.parse();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/commands/init/index.ts","../src/utils/suggest-command.ts","../src/cli.ts"],"sourcesContent":["import { Command } from 'commander';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../../utils/command-helpers';\nimport { type CommonCommandOptions, parseGlobalFlags } from '../../utils/global-flags';\nimport {\n INIT_EXIT_EMIT_FAILED,\n INIT_EXIT_INSTALL_FAILED,\n INIT_EXIT_INTERNAL_ERROR,\n INIT_EXIT_OK,\n INIT_EXIT_PRECONDITION,\n INIT_EXIT_SKILL_INSTALL_FAILED,\n INIT_EXIT_USER_ABORTED,\n} from './exit-codes';\n\n/**\n * Commander.js parsed options for `init`. The init-specific options live\n * alongside the inherited `CommonCommandOptions` global flags.\n *\n * `target` and `authoring` are typed as plain `string` here because\n * Commander.js does not enforce enums at parse time — the validation /\n * normalisation happens in `inputs.ts::resolveInitInputs`, which can\n * raise a structured `errorInitInvalidFlagValue` with the full set of\n * allowed values.\n */\ninterface InitCommandOptions extends CommonCommandOptions {\n readonly target?: string;\n readonly authoring?: string;\n readonly schemaPath?: string;\n readonly force?: boolean;\n readonly writeEnv?: boolean;\n readonly probeDb?: boolean;\n readonly strictProbe?: boolean;\n readonly install?: boolean;\n readonly skill?: boolean;\n}\n\nexport function createInitCommand(): Command {\n const command = new Command('init');\n setCommandDescriptions(\n command,\n 'Initialize a new Prisma Next project',\n 'Scaffolds config, schema, and runtime files, installs dependencies,\\n' +\n 'and emits the contract. Gets you from zero to typed queries in one step.\\n' +\n '\\n' +\n 'Run interactively for a guided experience, or supply --target / --authoring\\n' +\n 'and --yes for a fully scriptable run (CI, AI coding agents, automation).\\n' +\n '\\n' +\n 'Exit codes (see CLI Style Guide § Exit Codes):\\n' +\n ` ${INIT_EXIT_OK} OK Init succeeded.\\n` +\n ` ${INIT_EXIT_INTERNAL_ERROR} INTERNAL_ERROR Unexpected bug in prisma-next (please report).\\n` +\n ` ${INIT_EXIT_PRECONDITION} PRECONDITION Bad flags / missing prerequisite (e.g. no package.json).\\n` +\n ` ${INIT_EXIT_USER_ABORTED} USER_ABORTED User cancelled an interactive prompt.\\n` +\n ` ${INIT_EXIT_INSTALL_FAILED} INSTALL_FAILED Dependency installation failed (init-specific).\\n` +\n ` ${INIT_EXIT_EMIT_FAILED} EMIT_FAILED \\`contract emit\\` failed after install (init-specific).\\n` +\n ` ${INIT_EXIT_SKILL_INSTALL_FAILED} SKILL_INSTALL_FAILED Agent-skill install failed (re-run with --no-skill to skip).`,\n );\n setCommandExamples(command, [\n 'prisma-next init',\n 'prisma-next init --yes --target postgres --authoring psl',\n 'prisma-next init --yes --target mongodb --authoring typescript --json',\n 'prisma-next init --yes --force --target postgres --authoring psl # overwrite an existing scaffold',\n 'prisma-next init --no-install # skip pnpm/npm install + emit',\n 'prisma-next init --no-skill # skip the agent-skill install (air-gapped / restricted env)',\n ]);\n\n return addGlobalOptions(command)\n .option('--target <db>', 'Database target: postgres or mongodb')\n .option('--authoring <style>', 'Schema authoring style: psl or typescript')\n .option(\n '--schema-path <path>',\n 'Where to write the starter schema (default: prisma/contract.prisma)',\n )\n .option('--force', 'Overwrite an existing scaffold without prompting')\n .option(\n '--write-env',\n 'Write a .env file from .env.example (gitignored; default: only .env.example)',\n )\n .option(\n '--probe-db',\n 'Connect to DATABASE_URL once and check the server version against the target minimum (opt-in; off by default)',\n )\n .option(\n '--strict-probe',\n 'Treat a failed --probe-db as fatal (no-op without --probe-db; init is offline-by-default)',\n )\n .option('--no-install', 'Skip dependency installation and contract emission')\n .option(\n '--no-skill',\n 'Skip Prisma Next skills install (air-gapped CI, restricted registries, etc.)',\n )\n .action(async (options: InitCommandOptions) => {\n const { runInit } = await import('./init');\n const flags = parseGlobalFlags(options);\n const canPrompt = deriveCanPrompt({\n flagsInteractive: flags.interactive,\n optionInteractive: options.interactive,\n stdinIsTTY: Boolean(process.stdin.isTTY),\n });\n const exitCode = await runInit(process.cwd(), { options, flags, canPrompt });\n process.exit(exitCode);\n });\n}\n\n/**\n * Bridges the action handler's two TTY checks (stdout via `flags`, stdin\n * via `process.stdin.isTTY`) into the `canPrompt` boolean `runInit`\n * consumes.\n *\n * Per the [Style Guide § Interactivity](../../../../../../../docs/CLI%20Style%20Guide.md#interactivity):\n *\n * - `flags.interactive` governs *decoration* (TerminalUI, intro/outro,\n * spinners) and is derived from stdout-TTY by `parseGlobalFlags`,\n * honouring `--interactive` / `--no-interactive`.\n * - Prompting additionally requires a stdin TTY — closing stdin is a\n * common signal in CI / agent environments even when stdout stays\n * attached.\n * - `--interactive` is the explicit override: when the user passes it,\n * we honour it (e.g. testing flows where stdin is stubbed).\n *\n * Exported so callers and tests can derive the same value without\n * touching `process` globals.\n */\nexport function deriveCanPrompt(opts: {\n readonly flagsInteractive: boolean | undefined;\n readonly optionInteractive: boolean | undefined;\n readonly stdinIsTTY: boolean;\n}): boolean {\n if (opts.optionInteractive === true) return true;\n if (opts.flagsInteractive === false) return false;\n return opts.stdinIsTTY;\n}\n","import { distance } from 'closest-match';\n\n/**\n * Suggests similar command names for a mistyped input.\n *\n * Uses Levenshtein distance to find close matches. Only suggests commands\n * within a reasonable distance threshold (40% of the input length, minimum 2).\n * Returns up to 3 suggestions in case of ties.\n *\n * @returns Array of suggested command names (empty if nothing is close enough).\n */\nexport function suggestCommands(input: string, candidates: readonly string[]): string[] {\n if (candidates.length === 0) return [];\n\n // Threshold: at most 40% of the input length (min 2) to avoid absurd suggestions\n const maxDistance = Math.max(2, Math.ceil(input.length * 0.4));\n\n const scored = candidates\n .map((name) => ({ name, dist: distance(input, name) }))\n .filter((entry) => entry.dist <= maxDistance)\n .sort((a, b) => a.dist - b.dist);\n\n if (scored.length === 0) return [];\n\n // Take the best distance, then include ties (up to 3)\n const bestDist = scored[0]!.dist;\n return scored\n .filter((entry) => entry.dist === bestDist)\n .slice(0, 3)\n .map((entry) => entry.name);\n}\n","import { Command } from 'commander';\nimport { createContractEmitCommand } from './commands/contract-emit';\nimport { createContractInferCommand } from './commands/contract-infer';\nimport { createInitCommand } from './commands/init';\nimport { installShutdownHandlers } from './utils/shutdown';\n\n// Install SIGINT/SIGTERM handlers before anything else\ninstallShutdownHandlers();\n\nimport { createDbInitCommand } from './commands/db-init';\nimport { createDbSchemaCommand } from './commands/db-schema';\nimport { createDbSignCommand } from './commands/db-sign';\nimport { createDbUpdateCommand } from './commands/db-update';\nimport { createDbVerifyCommand } from './commands/db-verify';\nimport { createMigrationApplyCommand } from './commands/migration-apply';\nimport { createMigrationNewCommand } from './commands/migration-new';\nimport { createMigrationPlanCommand } from './commands/migration-plan';\nimport { createMigrationRefCommand } from './commands/migration-ref';\nimport { createMigrationShowCommand } from './commands/migration-show';\nimport { createMigrationStatusCommand } from './commands/migration-status';\nimport { setCommandDescriptions } from './utils/command-helpers';\nimport { formatCommandHelp, formatRootHelp } from './utils/formatters/help';\nimport { parseGlobalFlags } from './utils/global-flags';\nimport { suggestCommands } from './utils/suggest-command';\n\n/**\n * Formats the \"Did you mean ...?\" hint for an unknown command.\n */\nfunction formatSuggestion(input: string, candidates: readonly string[]): string {\n const suggestions = suggestCommands(\n input,\n candidates.map((c) => c),\n );\n if (suggestions.length === 0) return '';\n if (suggestions.length === 1) return `\\nDid you mean ${suggestions[0]}?\\n`;\n return `\\nDid you mean one of these?\\n${suggestions.map((s) => ` ${s}`).join('\\n')}\\n`;\n}\n\nconst program = new Command();\n\nprogram.name('prisma-next').description('Prisma Next CLI').version('0.0.1');\n\n// Override version option description to match capitalization style\nconst versionOption = program.options.find((opt) => opt.flags.includes('--version'));\nif (versionOption) {\n versionOption.description = 'Output the version number';\n}\n\nprogram.configureOutput({\n writeErr: () => {\n // Suppress all default error output - we handle errors in exitOverride\n },\n writeOut: (str) => {\n // Commander routes explicitly-requested `--help` (success-path help)\n // through writeOut; per the Style Guide § Output Conventions rule 8,\n // user-requested help is data and goes to stdout. Error-path help\n // (e.g. usage shown after an unknown command) goes through writeErr,\n // which stays suppressed because we render that ourselves with the\n // matching error envelope.\n //\n // Explicit `--version` is short-circuited before `program.parse()`\n // (see the argv pre-scan at the bottom of this file), so it does not\n // reach this writer.\n process.stdout.write(str);\n },\n});\n\n// Customize root help output to use our styled format\nconst rootHelpFormatter = (cmd: Command) => {\n const flags = parseGlobalFlags({});\n return formatRootHelp({ program: cmd, flags });\n};\n\nprogram.configureHelp({\n formatHelp: rootHelpFormatter,\n subcommandDescription: () => '',\n});\n\n// Override exit to handle unhandled errors (fail fast cases)\n// Commands handle structured errors themselves via process.exit()\nprogram.exitOverride((err) => {\n if (err) {\n const errorCode = (err as { code?: string }).code;\n const errorMessage = String(err.message ?? '');\n const errorName = err.name ?? '';\n\n // Unknown command/argument → exit 2 (CLI usage error)\n const isUnknownCommandError =\n errorCode === 'commander.unknownCommand' ||\n errorCode === 'commander.unknownArgument' ||\n (errorName === 'CommanderError' &&\n (errorMessage.includes('unknown command') || errorMessage.includes('unknown argument')));\n if (isUnknownCommandError) {\n const flags = parseGlobalFlags({});\n const match = errorMessage.match(/unknown command ['\"]([^'\"]+)['\"]/);\n const commandName = match ? match[1] : process.argv[3] || process.argv[2] || 'unknown';\n\n const firstArg = process.argv[2];\n const parentCommand = firstArg\n ? program.commands.find((cmd) => cmd.name() === firstArg)\n : undefined;\n\n if (parentCommand && commandName !== firstArg) {\n const subNames = parentCommand.commands.map((c) => c.name());\n process.stderr.write(\n `Unknown command: ${commandName}${formatSuggestion(commandName!, subNames)}\\n`,\n );\n const helpText = formatCommandHelp({ command: parentCommand, flags });\n process.stderr.write(`${helpText}\\n`);\n } else {\n const topNames = program.commands.map((c) => c.name());\n process.stderr.write(\n `Unknown command: ${commandName}${formatSuggestion(commandName!, topNames)}\\n`,\n );\n const helpText = formatRootHelp({ program, flags });\n process.stderr.write(`${helpText}\\n`);\n }\n process.exit(2);\n return;\n }\n\n // Help requests → exit 0\n const isHelpError =\n errorCode === 'commander.help' ||\n errorCode === 'commander.helpDisplayed' ||\n errorCode === 'outputHelp' ||\n errorMessage === '(outputHelp)' ||\n errorMessage.includes('outputHelp') ||\n (errorName === 'CommanderError' && errorMessage.includes('outputHelp'));\n if (isHelpError) {\n process.exit(0);\n return;\n }\n\n // Missing required arguments → exit 2 (CLI usage error)\n const isMissingArgumentError =\n errorCode === 'commander.missingArgument' ||\n errorCode === 'commander.missingMandatoryOptionValue' ||\n (errorName === 'CommanderError' &&\n (errorMessage.includes('missing') || errorMessage.includes('required')));\n if (isMissingArgumentError) {\n process.exit(2);\n return;\n }\n\n // Unhandled error → exit 1\n process.stderr.write(`Unhandled error: ${err.message}\\n`);\n if (err.stack) {\n process.stderr.write(`${err.stack}\\n`);\n }\n process.exit(1);\n }\n process.exit(0);\n});\n\n// Register contract subcommand\nconst contractCommand = new Command('contract');\nsetCommandDescriptions(\n contractCommand,\n 'Contract management commands',\n 'Define and emit your application data contract. The contract describes your schema as a\\n' +\n 'declarative data structure that can be signed and verified against your database.',\n);\ncontractCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\n// Add emit subcommand to contract\nconst contractEmitCommand = createContractEmitCommand();\ncontractCommand.addCommand(contractEmitCommand);\n\n// Add infer subcommand to contract\nconst contractInferCommand = createContractInferCommand();\ncontractCommand.addCommand(contractInferCommand);\n\n// Register contract command\nprogram.addCommand(contractCommand);\n\n// Register db subcommand\nconst dbCommand = new Command('db');\nsetCommandDescriptions(\n dbCommand,\n 'Database management commands',\n 'Verify and sign your database with your contract. Ensure your database schema matches\\n' +\n 'your contract, and sign it to record the contract hash for future verification.',\n);\ndbCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\n// Add verify subcommand to db\nconst dbVerifyCommand = createDbVerifyCommand();\ndbCommand.addCommand(dbVerifyCommand);\n\n// Add init subcommand to db\nconst dbInitCommand = createDbInitCommand();\ndbCommand.addCommand(dbInitCommand);\n\n// Add update subcommand to db\nconst dbUpdateCommand = createDbUpdateCommand();\ndbCommand.addCommand(dbUpdateCommand);\n\n// Add schema subcommand to db\nconst dbSchemaCommand = createDbSchemaCommand();\ndbCommand.addCommand(dbSchemaCommand);\n\n// Add sign subcommand to db\nconst dbSignCommand = createDbSignCommand();\ndbCommand.addCommand(dbSignCommand);\n\n// Register db command\nprogram.addCommand(dbCommand);\n\n// Register migration subcommand\nconst migrationCommand = new Command('migration');\nsetCommandDescriptions(\n migrationCommand,\n 'On-disk migration management commands',\n 'Plan, apply, and scaffold on-disk migration packages. Migrations are\\n' +\n 'contract-to-contract edges stored as versioned directories under migrations/.',\n);\nmigrationCommand.configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n subcommandDescription: () => '',\n});\n\nconst migrationPlanCommand = createMigrationPlanCommand();\nmigrationCommand.addCommand(migrationPlanCommand);\n\nconst migrationNewCommand = createMigrationNewCommand();\nmigrationCommand.addCommand(migrationNewCommand);\n\nconst migrationShowCommand = createMigrationShowCommand();\nmigrationCommand.addCommand(migrationShowCommand);\n\nconst migrationStatusCommand = createMigrationStatusCommand();\nmigrationCommand.addCommand(migrationStatusCommand);\n\nconst migrationApplyCommand = createMigrationApplyCommand();\nmigrationCommand.addCommand(migrationApplyCommand);\n\nconst migrationRefCommand = createMigrationRefCommand();\nmigrationCommand.addCommand(migrationRefCommand);\n\nprogram.addCommand(migrationCommand);\n\n// Register init command (top-level, not nested)\nconst initCommand = createInitCommand();\nprogram.addCommand(initCommand);\n\n// Create help command\nconst helpCommand = new Command('help')\n .description('Show usage instructions')\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .action(() => {\n const flags = parseGlobalFlags({});\n const helpText = formatRootHelp({ program, flags });\n // The `help` command was invoked explicitly: help is the data the\n // caller asked for. Per Style Guide § Output Conventions rule 8,\n // explicit help goes to stdout with exit code 0.\n process.stdout.write(`${helpText}\\n`);\n process.exit(0);\n });\n\nprogram.addCommand(helpCommand);\n\n// Set help as the default action when no command is provided. The user\n// did not invoke `--help`; we are voluntarily showing usage to help them\n// recover from an underspecified invocation, so the help text is\n// decoration around an implicit \"what did you want me to do?\" and goes\n// to stderr (Style Guide § Output Conventions rule 8).\n//\n// FOLLOW-UP: the exit code here is 0 today, but a no-arg invocation is\n// arguably a usage error (PRECONDITION → exit 2) for consistency with\n// the unknown-command path. Out of scope for the explicit-help routing\n// work; revisit when tightening exit-code semantics across the CLI.\nprogram.action(() => {\n const flags = parseGlobalFlags({});\n const helpText = formatRootHelp({ program, flags });\n process.stderr.write(`${helpText}\\n`);\n process.exit(0);\n});\n\n// Check if a command was invoked with no arguments (just the command name)\n// or if an unrecognized command was provided\nconst args = process.argv.slice(2);\nif (args.length > 0) {\n const commandName = args[0];\n // Handle version option explicitly since we suppress default output\n if (commandName === '--version' || commandName === '-V') {\n // Version is data → stdout\n process.stdout.write(`${program.version()}\\n`);\n process.exit(0);\n }\n // Skip command check for global options like --help, -h\n const isGlobalOption = commandName === '--help' || commandName === '-h';\n if (!isGlobalOption) {\n // Check if this is a recognized command\n const command = program.commands.find((cmd) => cmd.name() === commandName);\n\n if (!command) {\n // Unrecognized command → exit 2 (CLI usage error)\n const flags = parseGlobalFlags({});\n const topNames = program.commands.map((c) => c.name());\n process.stderr.write(\n `Unknown command: ${commandName}${formatSuggestion(commandName!, topNames)}\\n`,\n );\n const helpText = formatRootHelp({ program, flags });\n process.stderr.write(`${helpText}\\n`);\n process.exit(2);\n } else if (command.commands.length > 0 && args.length === 1) {\n // Parent command called with no subcommand. Same shape as the\n // no-args case above: the user did not request help, we are\n // voluntarily rendering it as decoration around an underspecified\n // invocation, so it goes to stderr per Style Guide § Output\n // Conventions rule 8. Exit code 0 today; the FOLLOW-UP note on\n // `program.action` applies here too (arguably should be 2).\n const flags = parseGlobalFlags({});\n const helpText = formatCommandHelp({ command, flags });\n process.stderr.write(`${helpText}\\n`);\n process.exit(0);\n }\n }\n}\n\nprogram.parse();\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as InitOutputSchema } from "../output-
|
|
1
|
+
import { t as InitOutputSchema } from "../output-DEg3SSnJ.mjs";
|
|
2
2
|
export { InitOutputSchema };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as CliStructuredError } from "./cli-errors-D3_sMh2K.mjs";
|
|
2
2
|
import { i as formatErrorOutput, r as formatErrorJson, t as TerminalUI } from "./terminal-ui-C_hFNbAn.mjs";
|
|
3
|
-
import { i as renderInitOutro, n as buildNextSteps, r as formatInitJson, t as InitOutputSchema } from "./output-
|
|
3
|
+
import { i as renderInitOutro, n as buildNextSteps, r as formatInitJson, t as InitOutputSchema } from "./output-DEg3SSnJ.mjs";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { basename, dirname, extname, isAbsolute, join, normalize } from "pathe";
|
|
6
6
|
import * as clack from "@clack/prompts";
|
|
@@ -9,6 +9,9 @@ import { execFile } from "node:child_process";
|
|
|
9
9
|
import { promisify } from "node:util";
|
|
10
10
|
import { detect, getUserAgent } from "package-manager-detector/detect";
|
|
11
11
|
import { applyEdits, modify, parse, printParseErrorCode } from "jsonc-parser";
|
|
12
|
+
//#region package.json
|
|
13
|
+
var version = "0.8.0-dev.5";
|
|
14
|
+
//#endregion
|
|
12
15
|
//#region src/commands/init/errors.ts
|
|
13
16
|
/**
|
|
14
17
|
* Re-init in non-interactive mode without `--force`. Distinct from the
|
|
@@ -213,7 +216,7 @@ function errorInitEmitFailed(options) {
|
|
|
213
216
|
}
|
|
214
217
|
/**
|
|
215
218
|
* The project-level agent-skill install (`npx skills add
|
|
216
|
-
*
|
|
219
|
+
* prisma/prisma-next#v<version>`) failed after a successful dependency
|
|
217
220
|
* install + emit. The project's scaffold remains on disk; the user
|
|
218
221
|
* can either fix the underlying issue (network, registry, PATH) and
|
|
219
222
|
* run the install command manually, or re-run `init --no-skill` to
|
|
@@ -223,7 +226,7 @@ function errorInitEmitFailed(options) {
|
|
|
223
226
|
* semantics. Maps to exit code `6 = SKILL_INSTALL_FAILED`.
|
|
224
227
|
*/
|
|
225
228
|
function errorInitSkillInstallFailed(options) {
|
|
226
|
-
return new CliStructuredError("5013", "Failed to install
|
|
229
|
+
return new CliStructuredError("5013", "Failed to install Prisma Next skills", {
|
|
227
230
|
domain: "CLI",
|
|
228
231
|
why: `\`${options.skillInstallCommand}\` exited with an error: ${options.cause}`,
|
|
229
232
|
fix: `Either:
|
|
@@ -240,41 +243,79 @@ function errorInitSkillInstallFailed(options) {
|
|
|
240
243
|
//#region src/commands/init/agent-skill-install.ts
|
|
241
244
|
const exec = promisify(execFile);
|
|
242
245
|
/**
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
246
|
+
* Default base for the GitHub-URL form `<owner>/<repo>` consumed by
|
|
247
|
+
* upstream `skills add`. Each `SkillSource` joins this base with its
|
|
248
|
+
* own subpath (and optional `#ref` for version-pinned clusters).
|
|
249
|
+
*/
|
|
250
|
+
const DEFAULT_AGENT_SKILL_BASE = "prisma/prisma-next";
|
|
251
|
+
const DEFAULT_AGENT_SKILL_SOURCES = [
|
|
252
|
+
{
|
|
253
|
+
subpath: "skills",
|
|
254
|
+
ref: "cli",
|
|
255
|
+
description: "usage skills (version-locked to installed Prisma Next)"
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
subpath: "skills/upgrade",
|
|
259
|
+
ref: null,
|
|
260
|
+
description: "upgrade skill (always tracks `main`)"
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
subpath: "skills/extension-author",
|
|
264
|
+
ref: null,
|
|
265
|
+
description: "extension-author skill (always tracks `main`)"
|
|
266
|
+
}
|
|
267
|
+
];
|
|
268
|
+
/**
|
|
269
|
+
* Test-only escape hatch for pinning the install base to a local
|
|
270
|
+
* checkout. Production runs leave this unset, so installs always use
|
|
271
|
+
* `DEFAULT_AGENT_SKILL_BASE`.
|
|
272
|
+
*
|
|
273
|
+
* When set to an absolute filesystem path (typical for tests), the
|
|
274
|
+
* `#ref` fragment is dropped — local-path mode in upstream's CLI does
|
|
275
|
+
* not accept refs, and the local clone has whatever content the test
|
|
276
|
+
* checked into it anyway. When set to anything else (e.g. a fork name
|
|
277
|
+
* `myuser/prisma-next`), the ref policy is preserved.
|
|
254
278
|
*/
|
|
255
|
-
|
|
279
|
+
function resolveAgentSkillBase() {
|
|
280
|
+
const override = process.env["PRISMA_NEXT_SKILLS_BASE"]?.trim();
|
|
281
|
+
return override && override.length > 0 ? override : DEFAULT_AGENT_SKILL_BASE;
|
|
282
|
+
}
|
|
283
|
+
function isLocalPath(base) {
|
|
284
|
+
return base.startsWith("/") || /^[a-zA-Z]:[\\/]/.test(base);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Build the `<base>/<subpath>[#ref]` URL the `skills` CLI will
|
|
288
|
+
* resolve. Exported for unit tests so the per-source format can be
|
|
289
|
+
* asserted without going through the full install loop.
|
|
290
|
+
*/
|
|
291
|
+
function formatSkillSourceUrl(source) {
|
|
292
|
+
const base = resolveAgentSkillBase();
|
|
293
|
+
const url = `${base}/${source.subpath}`;
|
|
294
|
+
if (source.ref === null) return url;
|
|
295
|
+
if (isLocalPath(base)) return url;
|
|
296
|
+
if (source.ref === "cli") return `${url}#v${version}`;
|
|
297
|
+
return url;
|
|
298
|
+
}
|
|
256
299
|
/**
|
|
257
|
-
* The skill-install command, formatted for the
|
|
258
|
-
* package manager. `npx`/`pnpm dlx`/`bunx` are
|
|
259
|
-
* user; we pick the variant that matches the
|
|
260
|
-
* so a single project consistently uses one
|
|
300
|
+
* The skill-install command for one source, formatted for the
|
|
301
|
+
* project's detected package manager. `npx`/`pnpm dlx`/`bunx` are
|
|
302
|
+
* interchangeable to the user; we pick the variant that matches the
|
|
303
|
+
* rest of the install step so a single project consistently uses one
|
|
304
|
+
* runner.
|
|
261
305
|
*
|
|
262
306
|
* `--all` auto-selects every skill in the cluster and every detected
|
|
263
307
|
* agent runtime, skipping the multi-select prompts the `skills` CLI
|
|
264
308
|
* shows by default. A non-interactive scaffold step cannot present
|
|
265
|
-
* prompts
|
|
266
|
-
* router skill routes between the workflow-scoped siblings). Users who
|
|
267
|
-
* want a narrower install run `npx skills add @prisma-next/skills`
|
|
268
|
-
* themselves after `init` with the flags they want.
|
|
309
|
+
* prompts.
|
|
269
310
|
*
|
|
270
311
|
* Exported for unit tests so the per-PM dispatch can be asserted
|
|
271
312
|
* without a live subprocess.
|
|
272
313
|
*/
|
|
273
|
-
function formatSkillInstallCommand(pm) {
|
|
314
|
+
function formatSkillInstallCommand(pm, source) {
|
|
274
315
|
const args = [
|
|
275
316
|
"skills",
|
|
276
317
|
"add",
|
|
277
|
-
|
|
318
|
+
formatSkillSourceUrl(source),
|
|
278
319
|
"--all"
|
|
279
320
|
];
|
|
280
321
|
switch (pm) {
|
|
@@ -300,29 +341,35 @@ function commandToExec(command) {
|
|
|
300
341
|
};
|
|
301
342
|
}
|
|
302
343
|
/**
|
|
303
|
-
* Runs the project-level skill install
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
344
|
+
* Runs the project-level skill install for every source in
|
|
345
|
+
* `DEFAULT_AGENT_SKILL_SOURCES`, in order. Returns
|
|
346
|
+
* `{ ok: true, commands }` on success; throws a structured
|
|
347
|
+
* `errorInitSkillInstallFailed` on the first failure (subsequent
|
|
348
|
+
* sources are not attempted — the user opted into Prisma Next by
|
|
349
|
+
* running `init` and a partial install would leave the project in an
|
|
350
|
+
* ambiguous state). The throw is intentionally fatal — project-level
|
|
351
|
+
* skill install is unconditional (modulo `--no-skill`).
|
|
309
352
|
*/
|
|
310
353
|
async function runProjectLevelSkillInstall(ctx) {
|
|
311
|
-
const
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
command
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}
|
|
354
|
+
const commands = [];
|
|
355
|
+
for (const source of DEFAULT_AGENT_SKILL_SOURCES) {
|
|
356
|
+
const command = formatSkillInstallCommand(ctx.pm, source);
|
|
357
|
+
const { file, args } = commandToExec(command);
|
|
358
|
+
try {
|
|
359
|
+
await exec(file, args, { cwd: ctx.baseDir });
|
|
360
|
+
commands.push(command);
|
|
361
|
+
} catch (err) {
|
|
362
|
+
throw errorInitSkillInstallFailed({
|
|
363
|
+
skillInstallCommand: command,
|
|
364
|
+
filesWritten: ctx.filesWritten,
|
|
365
|
+
cause: redactSecrets$1(readChildStderr$1(err)) || (err instanceof Error ? err.message : String(err))
|
|
366
|
+
});
|
|
367
|
+
}
|
|
325
368
|
}
|
|
369
|
+
return {
|
|
370
|
+
ok: true,
|
|
371
|
+
commands
|
|
372
|
+
};
|
|
326
373
|
}
|
|
327
374
|
function readChildStderr$1(err) {
|
|
328
375
|
if (err instanceof Error && "stderr" in err) return String(err.stderr ?? "");
|
|
@@ -345,7 +392,7 @@ function redactSecrets$1(stderr) {
|
|
|
345
392
|
/**
|
|
346
393
|
* Hand-rolled skill stub path that init must not leave behind. Removed
|
|
347
394
|
* on every init run so a project's `.agents/skills/prisma-next/` does
|
|
348
|
-
* not shadow the
|
|
395
|
+
* not shadow the installed Prisma Next skill cluster.
|
|
349
396
|
*/
|
|
350
397
|
const LEGACY_SKILL_FILE = ".agents/skills/prisma-next/SKILL.md";
|
|
351
398
|
//#endregion
|
|
@@ -1916,20 +1963,20 @@ async function runInit(baseDir, runOptions) {
|
|
|
1916
1963
|
filesWritten
|
|
1917
1964
|
}));
|
|
1918
1965
|
}
|
|
1919
|
-
const
|
|
1966
|
+
const manualProjectSkillSummary = DEFAULT_AGENT_SKILL_SOURCES.map((source) => formatSkillInstallCommand(install.effectivePm, source)).map((c) => `\`${c}\``).join(" && ");
|
|
1920
1967
|
let skillRegistered = false;
|
|
1921
|
-
if (!inputs.installProjectSkill) warnings.push(`Skipped
|
|
1922
|
-
else if (install.skipped) warnings.push(`Skipped
|
|
1968
|
+
if (!inputs.installProjectSkill) warnings.push(`Skipped Prisma Next agent-skill install (--no-skill). To install the skills later, run: ${manualProjectSkillSummary}`);
|
|
1969
|
+
else if (install.skipped) warnings.push(`Skipped Prisma Next agent-skill install because --no-install was passed. After you run install manually, install the skills with: ${manualProjectSkillSummary}`);
|
|
1923
1970
|
else {
|
|
1924
1971
|
const spinner = ui.spinner();
|
|
1925
|
-
spinner.start("Registering
|
|
1972
|
+
spinner.start("Registering Prisma Next skills with the agent runtime...");
|
|
1926
1973
|
try {
|
|
1927
1974
|
const project = await runProjectLevelSkillInstall({
|
|
1928
1975
|
baseDir,
|
|
1929
1976
|
pm: install.effectivePm,
|
|
1930
1977
|
filesWritten
|
|
1931
1978
|
});
|
|
1932
|
-
spinner.stop(`Registered
|
|
1979
|
+
spinner.stop(`Registered Prisma Next skills (project level) — ran ${project.commands.map((c) => `\`${c}\``).join(", ")}`);
|
|
1933
1980
|
skillRegistered = true;
|
|
1934
1981
|
} catch (error) {
|
|
1935
1982
|
spinner.stop("Agent-skill install failed");
|
|
@@ -2285,4 +2332,4 @@ function sanitisePackageName(raw) {
|
|
|
2285
2332
|
//#endregion
|
|
2286
2333
|
export { runInit };
|
|
2287
2334
|
|
|
2288
|
-
//# sourceMappingURL=init-
|
|
2335
|
+
//# sourceMappingURL=init-1-s6FvGv.mjs.map
|