create-warlock 5.29.0 → 5.30.0

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.
Files changed (67) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/esm/commands/create-new-app/get-app-path.mjs +1 -1
  3. package/esm/commands/create-new-app/get-app-path.mjs.map +1 -1
  4. package/esm/commands/create-new-app/index.mjs +6 -3
  5. package/esm/commands/create-new-app/index.mjs.map +1 -1
  6. package/esm/commands/create-new-app/types.d.mts +1 -1
  7. package/esm/commands/create-warlock-app/index.mjs +1 -1
  8. package/esm/commands/create-warlock-app/index.mjs.map +1 -1
  9. package/esm/features/agent-kit-targets.mjs +1 -1
  10. package/esm/features/agent-kit-targets.mjs.map +1 -1
  11. package/esm/features/database-drivers.mjs +1 -1
  12. package/esm/features/database-drivers.mjs.map +1 -1
  13. package/esm/features/features-map.mjs +1 -1
  14. package/esm/features/features-map.mjs.map +1 -1
  15. package/esm/flags/assert-flag-combinations.mjs +1 -1
  16. package/esm/flags/assert-flag-combinations.mjs.map +1 -1
  17. package/esm/flags/assert-package-manager.mjs +1 -1
  18. package/esm/flags/assert-package-manager.mjs.map +1 -1
  19. package/esm/flags/definitions.mjs +1 -1
  20. package/esm/flags/definitions.mjs.map +1 -1
  21. package/esm/flags/seed-from-flags.mjs +1 -1
  22. package/esm/flags/seed-from-flags.mjs.map +1 -1
  23. package/esm/helpers/app.mjs +28 -6
  24. package/esm/helpers/app.mjs.map +1 -1
  25. package/esm/helpers/exec.mjs +1 -1
  26. package/esm/helpers/exec.mjs.map +1 -1
  27. package/esm/helpers/insert-import.mjs +1 -1
  28. package/esm/helpers/insert-import.mjs.map +1 -1
  29. package/esm/helpers/package-manager.mjs +22 -2
  30. package/esm/helpers/package-manager.mjs.map +1 -1
  31. package/esm/helpers/paths.mjs +1 -1
  32. package/esm/helpers/paths.mjs.map +1 -1
  33. package/esm/helpers/pnpm-build-approvals.mjs +58 -3
  34. package/esm/helpers/pnpm-build-approvals.mjs.map +1 -1
  35. package/esm/helpers/project-builder-helpers.mjs +1 -1
  36. package/esm/helpers/project-builder-helpers.mjs.map +1 -1
  37. package/esm/helpers/tty.mjs +1 -1
  38. package/esm/helpers/tty.mjs.map +1 -1
  39. package/esm/helpers/warlock-versions.mjs +1 -1
  40. package/esm/helpers/warlock-versions.mjs.map +1 -1
  41. package/esm/index.d.mts +1 -1
  42. package/esm/index.mjs +1 -1
  43. package/esm/index.mjs.map +1 -1
  44. package/esm/prompts/ask-agent-targets.mjs +4 -2
  45. package/esm/prompts/ask-agent-targets.mjs.map +1 -1
  46. package/esm/prompts/ask-ai-features.mjs +5 -3
  47. package/esm/prompts/ask-ai-features.mjs.map +1 -1
  48. package/esm/prompts/ask-project-name.mjs +1 -1
  49. package/esm/prompts/ask-project-name.mjs.map +1 -1
  50. package/esm/prompts/ask-stack.mjs +1 -1
  51. package/esm/prompts/ask-stack.mjs.map +1 -1
  52. package/esm/prompts/fit-to-terminal.mjs +46 -0
  53. package/esm/prompts/fit-to-terminal.mjs.map +1 -0
  54. package/esm/summary.mjs +1 -1
  55. package/esm/summary.mjs.map +1 -1
  56. package/esm/ui/banner.mjs +1 -1
  57. package/esm/ui/banner.mjs.map +1 -1
  58. package/esm/ui/report.mjs +1 -1
  59. package/esm/ui/report.mjs.map +1 -1
  60. package/esm/ui/spinner.mjs +1 -1
  61. package/esm/ui/spinner.mjs.map +1 -1
  62. package/esm/ui/spinners.mjs +1 -1
  63. package/esm/ui/spinners.mjs.map +1 -1
  64. package/llms-full.txt +7 -3
  65. package/package.json +5 -4
  66. package/skills/create-a-warlock-project/SKILL.md +7 -3
  67. package/templates/warlock/src/web/root.tsx +5 -0
@@ -1 +1 @@
1
- {"version":3,"file":"warlock-versions.mjs","names":[],"sources":["../../../../../../create-warlock/src/helpers/warlock-versions.ts"],"sourcesContent":["/**\n * Resolving the version to stamp onto the generated project's `@warlock.js/*`\n * dependencies.\n *\n * ## Why this file exists\n *\n * The scaffolder used to stamp its OWN version onto every sibling package\n * (`\"@warlock.js/core\": \"4.16.2\"`). That is only correct while the scaffolder's\n * version is published — and it usually is not: the release tooling bumps the\n * source version on every build, including `--no-publish` builds, so between\n * publishes the working tree carries a version that exists nowhere on the\n * registry. Every project scaffolded in that window pinned eight dependencies\n * to a version npm cannot resolve, and the install died with `ETARGET`.\n *\n * ## The rule\n *\n * Never write a dependency version we have not established exists. Resolution\n * order, per package:\n *\n * 1. the scaffolder's own version, IF the registry has it published — this\n * preserves the lockstep guarantee the pin was introduced for;\n * 2. otherwise the registry's `latest` — the newest thing that actually\n * exists, with a note explaining the substitution;\n * 3. otherwise (registry unreachable) a caret range floored to the major,\n * e.g. `^4.0.0` — always satisfiable by any published 4.x, and the\n * scaffold-time install writes a lockfile that freezes the result anyway.\n *\n * A package that resolves to nothing (404 — never published) is reported, not\n * papered over: it is the difference between \"your install failed\" and \"the\n * feature you asked for does not exist yet\".\n */\n\nimport { getJsonFile } from \"@warlock.js/fs\";\nimport { packageRoot, template } from \"./paths\";\n\nexport type VersionSource =\n \"own-version\" | \"registry-latest\" | \"range-fallback\";\n\nexport type ResolvedVersion = {\n package: string;\n /** The exact version or range to write into the generated package.json. */\n version: string;\n source: VersionSource;\n};\n\nexport type VersionResolution = {\n /** package name -> version/range to stamp. */\n versions: Record<string, string>;\n /** Human-readable notes worth showing before the install runs. */\n notes: string[];\n /** Packages the registry does not know about at all. */\n unpublished: string[];\n /** True when the registry could not be reached and ranges were guessed. */\n offline: boolean;\n};\n\nconst REGISTRY_TIMEOUT_MS = 6_000;\n\n/**\n * Registry to query. `npm_config_registry` is set by npm/npx when the\n * scaffolder runs through them, so a private mirror is honoured for free.\n */\nfunction registryUrl(): string {\n const registry =\n process.env.npm_config_registry?.trim() || \"https://registry.npmjs.org\";\n\n return registry.replace(/\\/+$/, \"\");\n}\n\n/** `4.16.2` -> `^4.0.0`; anything unparseable -> `latest`. */\nexport function fallbackRange(version: string): string {\n const major = /^\\s*v?(\\d+)\\./.exec(version)?.[1];\n\n return major ? `^${major}.0.0` : \"latest\";\n}\n\ntype Packument = {\n \"dist-tags\"?: Record<string, string>;\n versions?: Record<string, unknown>;\n};\n\n/**\n * Fetch the abbreviated packument for a package. Returns `undefined` when the\n * registry cannot be reached (network / timeout) and `null` when the registry\n * answers that the package does not exist.\n */\nasync function fetchPackument(\n packageName: string,\n): Promise<Packument | null | undefined> {\n const url = `${registryUrl()}/${packageName.replace(\"/\", \"%2F\")}`;\n\n try {\n const response = await fetch(url, {\n headers: { accept: \"application/vnd.npm.install-v1+json\" },\n signal: AbortSignal.timeout(REGISTRY_TIMEOUT_MS),\n });\n\n // 404 (public) and 401 (scoped package the registry hides) both mean the\n // same thing to us: there is nothing here to install.\n if (response.status === 404 || response.status === 401) return null;\n\n if (!response.ok) return undefined;\n\n return (await response.json()) as Packument;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Resolve one package against the registry. Pure aside from the fetch, so the\n * decision table above is readable in one place.\n */\nasync function resolvePackage(\n packageName: string,\n ownVersion: string,\n): Promise<ResolvedVersion & { published: boolean; reachable: boolean }> {\n const packument = await fetchPackument(packageName);\n\n if (packument === undefined) {\n return {\n package: packageName,\n version: fallbackRange(ownVersion),\n source: \"range-fallback\",\n published: true,\n reachable: false,\n };\n }\n\n if (packument === null) {\n return {\n package: packageName,\n version: fallbackRange(ownVersion),\n source: \"range-fallback\",\n published: false,\n reachable: true,\n };\n }\n\n if (packument.versions?.[ownVersion]) {\n return {\n package: packageName,\n version: ownVersion,\n source: \"own-version\",\n published: true,\n reachable: true,\n };\n }\n\n const latest = packument[\"dist-tags\"]?.latest;\n\n if (latest) {\n return {\n package: packageName,\n version: latest,\n source: \"registry-latest\",\n published: true,\n reachable: true,\n };\n }\n\n return {\n package: packageName,\n version: fallbackRange(ownVersion),\n source: \"range-fallback\",\n published: true,\n reachable: true,\n };\n}\n\n/**\n * Every `@warlock.js/*` dependency the template declares. Read from the\n * template rather than the copied project so resolution can start before (or\n * in parallel with) the copy.\n */\nexport function templateWarlockDependencies(): string[] {\n const templatePackageJson = getJsonFile(\n `${template(\"warlock\")}/package.json`,\n ) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n\n const names = new Set<string>();\n\n for (const field of [\"dependencies\", \"devDependencies\"] as const) {\n for (const name of Object.keys(templatePackageJson[field] ?? {})) {\n if (name.startsWith(\"@warlock.js/\")) names.add(name);\n }\n }\n\n return [...names];\n}\n\n/** The scaffolder's own published version, i.e. the lockstep candidate. */\nexport function scaffolderVersion(): string {\n return (getJsonFile(packageRoot(\"package.json\")) as { version: string })\n .version;\n}\n\nlet cached: Promise<VersionResolution> | undefined;\n\n/**\n * Resolve the versions to stamp, once per process.\n *\n * Never throws and never blocks a scaffold: the worst case is the caret\n * fallback plus a note saying so.\n */\nexport function resolveWarlockVersions(\n packages: string[] = templateWarlockDependencies(),\n ownVersion: string = scaffolderVersion(),\n): Promise<VersionResolution> {\n if (cached) return cached;\n\n cached = (async (): Promise<VersionResolution> => {\n const resolutions = await Promise.all(\n packages.map(name => resolvePackage(name, ownVersion)),\n );\n\n const versions: Record<string, string> = {};\n const notes: string[] = [];\n const unpublished: string[] = [];\n const substituted: ResolvedVersion[] = [];\n\n let offline = false;\n\n for (const resolution of resolutions) {\n versions[resolution.package] = resolution.version;\n\n if (!resolution.reachable) offline = true;\n if (!resolution.published) unpublished.push(resolution.package);\n if (resolution.source === \"registry-latest\") substituted.push(resolution);\n }\n\n if (offline) {\n notes.push(\n `Could not reach the npm registry — pinning @warlock.js/* to ${fallbackRange(ownVersion)} instead of an exact version.`,\n );\n }\n\n if (substituted.length > 0) {\n const latest = substituted[0].version;\n\n notes.push(\n `create-warlock ${ownVersion} is not published yet — pinning @warlock.js/* to the latest published version (${latest}).`,\n );\n }\n\n if (unpublished.length > 0) {\n notes.push(\n `Not published on the registry: ${unpublished.join(\", \")} — the install will fail until they are released.`,\n );\n }\n\n return { versions, notes, unpublished, offline };\n })();\n\n return cached;\n}\n\n/** Test/CLI seam: forget the memoized resolution. */\nexport function resetWarlockVersionsCache() {\n cached = undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwDA,MAAM,sBAAsB;;;;;AAM5B,SAAS,cAAsB;CAI7B,QAFE,QAAQ,IAAI,qBAAqB,KAAK,KAAK,6BAE9B,CAAC,QAAQ,QAAQ,EAAE;AACpC;;AAGA,SAAgB,cAAc,SAAyB;CACrD,MAAM,QAAQ,gBAAgB,KAAK,OAAO,CAAC,GAAG;CAE9C,OAAO,QAAQ,IAAI,MAAM,QAAQ;AACnC;;;;;;AAYA,eAAe,eACb,aACuC;CACvC,MAAM,MAAM,GAAG,YAAY,EAAE,GAAG,YAAY,QAAQ,KAAK,KAAK;CAE9D,IAAI;EACF,MAAM,WAAW,MAAM,MAAM,KAAK;GAChC,SAAS,EAAE,QAAQ,sCAAsC;GACzD,QAAQ,YAAY,QAAQ,mBAAmB;EACjD,CAAC;EAID,IAAI,SAAS,WAAW,OAAO,SAAS,WAAW,KAAK,OAAO;EAE/D,IAAI,CAAC,SAAS,IAAI,OAAO;EAEzB,OAAQ,MAAM,SAAS,KAAK;CAC9B,QAAQ;EACN;CACF;AACF;;;;;AAMA,eAAe,eACb,aACA,YACuE;CACvE,MAAM,YAAY,MAAM,eAAe,WAAW;CAElD,IAAI,cAAc,QAChB,OAAO;EACL,SAAS;EACT,SAAS,cAAc,UAAU;EACjC,QAAQ;EACR,WAAW;EACX,WAAW;CACb;CAGF,IAAI,cAAc,MAChB,OAAO;EACL,SAAS;EACT,SAAS,cAAc,UAAU;EACjC,QAAQ;EACR,WAAW;EACX,WAAW;CACb;CAGF,IAAI,UAAU,WAAW,aACvB,OAAO;EACL,SAAS;EACT,SAAS;EACT,QAAQ;EACR,WAAW;EACX,WAAW;CACb;CAGF,MAAM,SAAS,UAAU,YAAY,EAAE;CAEvC,IAAI,QACF,OAAO;EACL,SAAS;EACT,SAAS;EACT,QAAQ;EACR,WAAW;EACX,WAAW;CACb;CAGF,OAAO;EACL,SAAS;EACT,SAAS,cAAc,UAAU;EACjC,QAAQ;EACR,WAAW;EACX,WAAW;CACb;AACF;;;;;;AAOA,SAAgB,8BAAwC;CACtD,MAAM,sBAAsB,YAC1B,GAAG,SAAS,SAAS,EAAE,cACzB;CAKA,MAAM,wBAAQ,IAAI,IAAY;CAE9B,KAAK,MAAM,SAAS,CAAC,gBAAgB,iBAAiB,GACpD,KAAK,MAAM,QAAQ,OAAO,KAAK,oBAAoB,UAAU,CAAC,CAAC,GAC7D,IAAI,KAAK,WAAW,cAAc,GAAG,MAAM,IAAI,IAAI;CAIvD,OAAO,CAAC,GAAG,KAAK;AAClB;;AAGA,SAAgB,oBAA4B;CAC1C,OAAQ,YAAY,YAAY,cAAc,CAAC,CAAC,CAC7C;AACL;AAEA,IAAI;;;;;;;AAQJ,SAAgB,uBACd,WAAqB,4BAA4B,GACjD,aAAqB,kBAAkB,GACX;CAC5B,IAAI,QAAQ,OAAO;CAEnB,UAAU,YAAwC;EAChD,MAAM,cAAc,MAAM,QAAQ,IAChC,SAAS,KAAI,SAAQ,eAAe,MAAM,UAAU,CAAC,CACvD;EAEA,MAAM,WAAmC,CAAC;EAC1C,MAAM,QAAkB,CAAC;EACzB,MAAM,cAAwB,CAAC;EAC/B,MAAM,cAAiC,CAAC;EAExC,IAAI,UAAU;EAEd,KAAK,MAAM,cAAc,aAAa;GACpC,SAAS,WAAW,WAAW,WAAW;GAE1C,IAAI,CAAC,WAAW,WAAW,UAAU;GACrC,IAAI,CAAC,WAAW,WAAW,YAAY,KAAK,WAAW,OAAO;GAC9D,IAAI,WAAW,WAAW,mBAAmB,YAAY,KAAK,UAAU;EAC1E;EAEA,IAAI,SACF,MAAM,KACJ,+DAA+D,cAAc,UAAU,EAAE,8BAC3F;EAGF,IAAI,YAAY,SAAS,GAAG;GAC1B,MAAM,SAAS,YAAY,EAAE,CAAC;GAE9B,MAAM,KACJ,kBAAkB,WAAW,iFAAiF,OAAO,GACvH;EACF;EAEA,IAAI,YAAY,SAAS,GACvB,MAAM,KACJ,kCAAkC,YAAY,KAAK,IAAI,EAAE,kDAC3D;EAGF,OAAO;GAAE;GAAU;GAAO;GAAa;EAAQ;CACjD,EAAC,CAAE;CAEH,OAAO;AACT"}
1
+ {"version":3,"file":"warlock-versions.mjs","names":[],"sources":["../../../../../../../packages/create-warlock/src/helpers/warlock-versions.ts"],"sourcesContent":["/**\n * Resolving the version to stamp onto the generated project's `@warlock.js/*`\n * dependencies.\n *\n * ## Why this file exists\n *\n * The scaffolder used to stamp its OWN version onto every sibling package\n * (`\"@warlock.js/core\": \"4.16.2\"`). That is only correct while the scaffolder's\n * version is published — and it usually is not: the release tooling bumps the\n * source version on every build, including `--no-publish` builds, so between\n * publishes the working tree carries a version that exists nowhere on the\n * registry. Every project scaffolded in that window pinned eight dependencies\n * to a version npm cannot resolve, and the install died with `ETARGET`.\n *\n * ## The rule\n *\n * Never write a dependency version we have not established exists. Resolution\n * order, per package:\n *\n * 1. the scaffolder's own version, IF the registry has it published — this\n * preserves the lockstep guarantee the pin was introduced for;\n * 2. otherwise the registry's `latest` — the newest thing that actually\n * exists, with a note explaining the substitution;\n * 3. otherwise (registry unreachable) a caret range floored to the major,\n * e.g. `^4.0.0` — always satisfiable by any published 4.x, and the\n * scaffold-time install writes a lockfile that freezes the result anyway.\n *\n * A package that resolves to nothing (404 — never published) is reported, not\n * papered over: it is the difference between \"your install failed\" and \"the\n * feature you asked for does not exist yet\".\n */\n\nimport { getJsonFile } from \"@warlock.js/fs\";\nimport { packageRoot, template } from \"./paths\";\n\nexport type VersionSource =\n \"own-version\" | \"registry-latest\" | \"range-fallback\";\n\nexport type ResolvedVersion = {\n package: string;\n /** The exact version or range to write into the generated package.json. */\n version: string;\n source: VersionSource;\n};\n\nexport type VersionResolution = {\n /** package name -> version/range to stamp. */\n versions: Record<string, string>;\n /** Human-readable notes worth showing before the install runs. */\n notes: string[];\n /** Packages the registry does not know about at all. */\n unpublished: string[];\n /** True when the registry could not be reached and ranges were guessed. */\n offline: boolean;\n};\n\nconst REGISTRY_TIMEOUT_MS = 6_000;\n\n/**\n * Registry to query. `npm_config_registry` is set by npm/npx when the\n * scaffolder runs through them, so a private mirror is honoured for free.\n */\nfunction registryUrl(): string {\n const registry =\n process.env.npm_config_registry?.trim() || \"https://registry.npmjs.org\";\n\n return registry.replace(/\\/+$/, \"\");\n}\n\n/** `4.16.2` -> `^4.0.0`; anything unparseable -> `latest`. */\nexport function fallbackRange(version: string): string {\n const major = /^\\s*v?(\\d+)\\./.exec(version)?.[1];\n\n return major ? `^${major}.0.0` : \"latest\";\n}\n\ntype Packument = {\n \"dist-tags\"?: Record<string, string>;\n versions?: Record<string, unknown>;\n};\n\n/**\n * Fetch the abbreviated packument for a package. Returns `undefined` when the\n * registry cannot be reached (network / timeout) and `null` when the registry\n * answers that the package does not exist.\n */\nasync function fetchPackument(\n packageName: string,\n): Promise<Packument | null | undefined> {\n const url = `${registryUrl()}/${packageName.replace(\"/\", \"%2F\")}`;\n\n try {\n const response = await fetch(url, {\n headers: { accept: \"application/vnd.npm.install-v1+json\" },\n signal: AbortSignal.timeout(REGISTRY_TIMEOUT_MS),\n });\n\n // 404 (public) and 401 (scoped package the registry hides) both mean the\n // same thing to us: there is nothing here to install.\n if (response.status === 404 || response.status === 401) return null;\n\n if (!response.ok) return undefined;\n\n return (await response.json()) as Packument;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Resolve one package against the registry. Pure aside from the fetch, so the\n * decision table above is readable in one place.\n */\nasync function resolvePackage(\n packageName: string,\n ownVersion: string,\n): Promise<ResolvedVersion & { published: boolean; reachable: boolean }> {\n const packument = await fetchPackument(packageName);\n\n if (packument === undefined) {\n return {\n package: packageName,\n version: fallbackRange(ownVersion),\n source: \"range-fallback\",\n published: true,\n reachable: false,\n };\n }\n\n if (packument === null) {\n return {\n package: packageName,\n version: fallbackRange(ownVersion),\n source: \"range-fallback\",\n published: false,\n reachable: true,\n };\n }\n\n if (packument.versions?.[ownVersion]) {\n return {\n package: packageName,\n version: ownVersion,\n source: \"own-version\",\n published: true,\n reachable: true,\n };\n }\n\n const latest = packument[\"dist-tags\"]?.latest;\n\n if (latest) {\n return {\n package: packageName,\n version: latest,\n source: \"registry-latest\",\n published: true,\n reachable: true,\n };\n }\n\n return {\n package: packageName,\n version: fallbackRange(ownVersion),\n source: \"range-fallback\",\n published: true,\n reachable: true,\n };\n}\n\n/**\n * Every `@warlock.js/*` dependency the template declares. Read from the\n * template rather than the copied project so resolution can start before (or\n * in parallel with) the copy.\n */\nexport function templateWarlockDependencies(): string[] {\n const templatePackageJson = getJsonFile(\n `${template(\"warlock\")}/package.json`,\n ) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n\n const names = new Set<string>();\n\n for (const field of [\"dependencies\", \"devDependencies\"] as const) {\n for (const name of Object.keys(templatePackageJson[field] ?? {})) {\n if (name.startsWith(\"@warlock.js/\")) names.add(name);\n }\n }\n\n return [...names];\n}\n\n/** The scaffolder's own published version, i.e. the lockstep candidate. */\nexport function scaffolderVersion(): string {\n return (getJsonFile(packageRoot(\"package.json\")) as { version: string })\n .version;\n}\n\nlet cached: Promise<VersionResolution> | undefined;\n\n/**\n * Resolve the versions to stamp, once per process.\n *\n * Never throws and never blocks a scaffold: the worst case is the caret\n * fallback plus a note saying so.\n */\nexport function resolveWarlockVersions(\n packages: string[] = templateWarlockDependencies(),\n ownVersion: string = scaffolderVersion(),\n): Promise<VersionResolution> {\n if (cached) return cached;\n\n cached = (async (): Promise<VersionResolution> => {\n const resolutions = await Promise.all(\n packages.map(name => resolvePackage(name, ownVersion)),\n );\n\n const versions: Record<string, string> = {};\n const notes: string[] = [];\n const unpublished: string[] = [];\n const substituted: ResolvedVersion[] = [];\n\n let offline = false;\n\n for (const resolution of resolutions) {\n versions[resolution.package] = resolution.version;\n\n if (!resolution.reachable) offline = true;\n if (!resolution.published) unpublished.push(resolution.package);\n if (resolution.source === \"registry-latest\") substituted.push(resolution);\n }\n\n if (offline) {\n notes.push(\n `Could not reach the npm registry — pinning @warlock.js/* to ${fallbackRange(ownVersion)} instead of an exact version.`,\n );\n }\n\n if (substituted.length > 0) {\n const latest = substituted[0].version;\n\n notes.push(\n `create-warlock ${ownVersion} is not published yet — pinning @warlock.js/* to the latest published version (${latest}).`,\n );\n }\n\n if (unpublished.length > 0) {\n notes.push(\n `Not published on the registry: ${unpublished.join(\", \")} — the install will fail until they are released.`,\n );\n }\n\n return { versions, notes, unpublished, offline };\n })();\n\n return cached;\n}\n\n/** Test/CLI seam: forget the memoized resolution. */\nexport function resetWarlockVersionsCache() {\n cached = undefined;\n}\n"],"mappings":"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"}
package/esm/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { CliFlags } from "./commands/create-new-app/types.mjs";
2
2
 
3
- //#region ../create-warlock/src/index.d.ts
3
+ //#region ../../packages/create-warlock/src/index.d.ts
4
4
  /**
5
5
  * Parse the scaffolder's own CLI flags for non-interactive mode.
6
6
  *
package/esm/index.mjs CHANGED
@@ -4,7 +4,7 @@ import createNewApp from "./commands/create-new-app/index.mjs";
4
4
  import { buildHelpText } from "./flags/definitions.mjs";
5
5
  import { getJsonFile } from "@warlock.js/fs";
6
6
 
7
- //#region ../create-warlock/src/index.ts
7
+ //#region ../../packages/create-warlock/src/index.ts
8
8
  const valueFlags = [
9
9
  "name",
10
10
  "db",
package/esm/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../../create-warlock/src/index.ts"],"sourcesContent":["import { getJsonFile } from \"@warlock.js/fs\";\nimport createNewApp from \"./commands/create-new-app\";\nimport { CliFlags, Stack } from \"./commands/create-new-app/types\";\nimport { NO_DATABASE } from \"./features/database-drivers\";\nimport { buildHelpText } from \"./flags/definitions\";\nimport { packageRoot } from \"./helpers/paths\";\n\nconst valueFlags = [\"name\", \"db\", \"pm\", \"features\", \"ai\", \"agents\", \"stack\"];\n\nconst HELP_TEXT = buildHelpText();\n\n/**\n * Parse the scaffolder's own CLI flags for non-interactive mode.\n *\n * @example\n * create-warlock my-app --db=postgres --features=test,herald --ai=ai-openai,ai-anthropic --yes\n */\nexport function parseFlags(argv: string[]): CliFlags {\n const flags: CliFlags = {};\n const positionals: string[] = [];\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n\n if (!arg.startsWith(\"-\")) {\n positionals.push(arg);\n continue;\n }\n\n const equalIndex = arg.indexOf(\"=\");\n const key = (equalIndex === -1 ? arg : arg.slice(0, equalIndex)).replace(\n /^-+/,\n \"\",\n );\n let value: string | undefined =\n equalIndex === -1 ? undefined : arg.slice(equalIndex + 1);\n\n // Value-taking flags may use either `--key=value` or `--key value`.\n if (valueFlags.includes(key) && value === undefined) {\n const next = argv[i + 1];\n\n if (next && !next.startsWith(\"-\")) {\n value = next;\n i++;\n }\n }\n\n switch (key) {\n case \"help\":\n case \"h\":\n flags.help = true;\n break;\n case \"version\":\n case \"v\":\n flags.version = true;\n break;\n case \"yes\":\n case \"y\":\n flags.yes = true;\n break;\n case \"git\":\n flags.git = true;\n break;\n case \"no-git\":\n flags.git = false;\n break;\n case \"jwt\":\n flags.jwt = true;\n break;\n case \"no-jwt\":\n flags.jwt = false;\n break;\n case \"name\":\n flags.name = value;\n break;\n case \"db\":\n flags.db = value;\n break;\n case \"no-db\":\n // Opt out of a database entirely — equivalent to `--db=none`.\n flags.db = NO_DATABASE;\n break;\n case \"pm\":\n // Keep an explicitly supplied but valueless `--pm` distinguishable\n // from omitting the flag. The command validator rejects this empty\n // value instead of silently selecting the preferred manager.\n flags.pm = value ?? \"\";\n break;\n case \"features\":\n flags.features = splitList(value);\n break;\n case \"ai\":\n flags.ai = splitList(value);\n break;\n case \"agents\":\n flags.agents = splitList(value);\n break;\n case \"stack\":\n flags.stack = value as Stack;\n break;\n case \"interactive\":\n case \"customize\":\n flags.interactive = true;\n break;\n }\n }\n\n if (!flags.name && positionals.length > 0) {\n flags.name = positionals[0];\n }\n\n return flags;\n}\n\nfunction splitList(value: string | undefined): string[] {\n if (!value) return [];\n\n return value\n .split(\",\")\n .map(item => item.trim())\n .filter(Boolean);\n}\n\n/**\n * Read this package's own `version` field. A plain JSON read — no network\n * call, no write, nothing else touched — so `--version` stays a pure,\n * side-effect-free exit.\n */\nexport function packageVersion(): string {\n return (getJsonFile(packageRoot(\"package.json\")) as { version: string })\n .version;\n}\n\nexport default function createApp() {\n const flags = parseFlags(process.argv.slice(2));\n\n // `--help` and `--version` must exit before anything that touches the\n // filesystem, the network, or a prompt — they win over every other flag,\n // including a positional project name.\n if (flags.help) {\n console.log(HELP_TEXT);\n process.exit(0);\n return;\n }\n\n if (flags.version) {\n console.log(packageVersion());\n process.exit(0);\n return;\n }\n\n // An unexpected throw must surface as a readable error AND a non-zero exit\n // code — never as a stack trace the user scrolls past on the way to a green\n // banner (there is no banner after this point).\n Promise.resolve(createNewApp(flags)).catch((error: unknown) => {\n console.error();\n console.error(\n ` create-warlock failed: ${(error as Error)?.message ?? String(error)}`,\n );\n console.error();\n\n process.exit(1);\n });\n}\n"],"mappings":";;;;;;;AAOA,MAAM,aAAa;CAAC;CAAQ;CAAM;CAAM;CAAY;CAAM;CAAU;AAAO;AAE3E,MAAM,YAAY,cAAc;;;;;;;AAQhC,SAAgB,WAAW,MAA0B;CACnD,MAAM,QAAkB,CAAC;CACzB,MAAM,cAAwB,CAAC;CAE/B,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;EACpC,MAAM,MAAM,KAAK;EAEjB,IAAI,CAAC,IAAI,WAAW,GAAG,GAAG;GACxB,YAAY,KAAK,GAAG;GACpB;EACF;EAEA,MAAM,aAAa,IAAI,QAAQ,GAAG;EAClC,MAAM,OAAO,eAAe,KAAK,MAAM,IAAI,MAAM,GAAG,UAAU,EAAC,CAAE,QAC/D,OACA,EACF;EACA,IAAI,QACF,eAAe,KAAK,SAAY,IAAI,MAAM,aAAa,CAAC;EAG1D,IAAI,WAAW,SAAS,GAAG,KAAK,UAAU,QAAW;GACnD,MAAM,OAAO,KAAK,IAAI;GAEtB,IAAI,QAAQ,CAAC,KAAK,WAAW,GAAG,GAAG;IACjC,QAAQ;IACR;GACF;EACF;EAEA,QAAQ,KAAR;GACE,KAAK;GACL,KAAK;IACH,MAAM,OAAO;IACb;GACF,KAAK;GACL,KAAK;IACH,MAAM,UAAU;IAChB;GACF,KAAK;GACL,KAAK;IACH,MAAM,MAAM;IACZ;GACF,KAAK;IACH,MAAM,MAAM;IACZ;GACF,KAAK;IACH,MAAM,MAAM;IACZ;GACF,KAAK;IACH,MAAM,MAAM;IACZ;GACF,KAAK;IACH,MAAM,MAAM;IACZ;GACF,KAAK;IACH,MAAM,OAAO;IACb;GACF,KAAK;IACH,MAAM,KAAK;IACX;GACF,KAAK;IAEH,MAAM,KAAK;IACX;GACF,KAAK;IAIH,MAAM,KAAK,SAAS;IACpB;GACF,KAAK;IACH,MAAM,WAAW,UAAU,KAAK;IAChC;GACF,KAAK;IACH,MAAM,KAAK,UAAU,KAAK;IAC1B;GACF,KAAK;IACH,MAAM,SAAS,UAAU,KAAK;IAC9B;GACF,KAAK;IACH,MAAM,QAAQ;IACd;GACF,KAAK;GACL,KAAK;IACH,MAAM,cAAc;IACpB;EACJ;CACF;CAEA,IAAI,CAAC,MAAM,QAAQ,YAAY,SAAS,GACtC,MAAM,OAAO,YAAY;CAG3B,OAAO;AACT;AAEA,SAAS,UAAU,OAAqC;CACtD,IAAI,CAAC,OAAO,OAAO,CAAC;CAEpB,OAAO,MACJ,MAAM,GAAG,CAAC,CACV,KAAI,SAAQ,KAAK,KAAK,CAAC,CAAC,CACxB,OAAO,OAAO;AACnB;;;;;;AAOA,SAAgB,iBAAyB;CACvC,OAAQ,YAAY,YAAY,cAAc,CAAC,CAAC,CAC7C;AACL;AAEA,SAAwB,YAAY;CAClC,MAAM,QAAQ,WAAW,QAAQ,KAAK,MAAM,CAAC,CAAC;CAK9C,IAAI,MAAM,MAAM;EACd,QAAQ,IAAI,SAAS;EACrB,QAAQ,KAAK,CAAC;EACd;CACF;CAEA,IAAI,MAAM,SAAS;EACjB,QAAQ,IAAI,eAAe,CAAC;EAC5B,QAAQ,KAAK,CAAC;EACd;CACF;CAKA,QAAQ,QAAQ,aAAa,KAAK,CAAC,CAAC,CAAC,OAAO,UAAmB;EAC7D,QAAQ,MAAM;EACd,QAAQ,MACN,4BAA6B,OAAiB,WAAW,OAAO,KAAK,GACvE;EACA,QAAQ,MAAM;EAEd,QAAQ,KAAK,CAAC;CAChB,CAAC;AACH"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../packages/create-warlock/src/index.ts"],"sourcesContent":["import { getJsonFile } from \"@warlock.js/fs\";\nimport createNewApp from \"./commands/create-new-app\";\nimport { CliFlags, Stack } from \"./commands/create-new-app/types\";\nimport { NO_DATABASE } from \"./features/database-drivers\";\nimport { buildHelpText } from \"./flags/definitions\";\nimport { packageRoot } from \"./helpers/paths\";\n\nconst valueFlags = [\"name\", \"db\", \"pm\", \"features\", \"ai\", \"agents\", \"stack\"];\n\nconst HELP_TEXT = buildHelpText();\n\n/**\n * Parse the scaffolder's own CLI flags for non-interactive mode.\n *\n * @example\n * create-warlock my-app --db=postgres --features=test,herald --ai=ai-openai,ai-anthropic --yes\n */\nexport function parseFlags(argv: string[]): CliFlags {\n const flags: CliFlags = {};\n const positionals: string[] = [];\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n\n if (!arg.startsWith(\"-\")) {\n positionals.push(arg);\n continue;\n }\n\n const equalIndex = arg.indexOf(\"=\");\n const key = (equalIndex === -1 ? arg : arg.slice(0, equalIndex)).replace(\n /^-+/,\n \"\",\n );\n let value: string | undefined =\n equalIndex === -1 ? undefined : arg.slice(equalIndex + 1);\n\n // Value-taking flags may use either `--key=value` or `--key value`.\n if (valueFlags.includes(key) && value === undefined) {\n const next = argv[i + 1];\n\n if (next && !next.startsWith(\"-\")) {\n value = next;\n i++;\n }\n }\n\n switch (key) {\n case \"help\":\n case \"h\":\n flags.help = true;\n break;\n case \"version\":\n case \"v\":\n flags.version = true;\n break;\n case \"yes\":\n case \"y\":\n flags.yes = true;\n break;\n case \"git\":\n flags.git = true;\n break;\n case \"no-git\":\n flags.git = false;\n break;\n case \"jwt\":\n flags.jwt = true;\n break;\n case \"no-jwt\":\n flags.jwt = false;\n break;\n case \"name\":\n flags.name = value;\n break;\n case \"db\":\n flags.db = value;\n break;\n case \"no-db\":\n // Opt out of a database entirely — equivalent to `--db=none`.\n flags.db = NO_DATABASE;\n break;\n case \"pm\":\n // Keep an explicitly supplied but valueless `--pm` distinguishable\n // from omitting the flag. The command validator rejects this empty\n // value instead of silently selecting the preferred manager.\n flags.pm = value ?? \"\";\n break;\n case \"features\":\n flags.features = splitList(value);\n break;\n case \"ai\":\n flags.ai = splitList(value);\n break;\n case \"agents\":\n flags.agents = splitList(value);\n break;\n case \"stack\":\n flags.stack = value as Stack;\n break;\n case \"interactive\":\n case \"customize\":\n flags.interactive = true;\n break;\n }\n }\n\n if (!flags.name && positionals.length > 0) {\n flags.name = positionals[0];\n }\n\n return flags;\n}\n\nfunction splitList(value: string | undefined): string[] {\n if (!value) return [];\n\n return value\n .split(\",\")\n .map(item => item.trim())\n .filter(Boolean);\n}\n\n/**\n * Read this package's own `version` field. A plain JSON read — no network\n * call, no write, nothing else touched — so `--version` stays a pure,\n * side-effect-free exit.\n */\nexport function packageVersion(): string {\n return (getJsonFile(packageRoot(\"package.json\")) as { version: string })\n .version;\n}\n\nexport default function createApp() {\n const flags = parseFlags(process.argv.slice(2));\n\n // `--help` and `--version` must exit before anything that touches the\n // filesystem, the network, or a prompt — they win over every other flag,\n // including a positional project name.\n if (flags.help) {\n console.log(HELP_TEXT);\n process.exit(0);\n return;\n }\n\n if (flags.version) {\n console.log(packageVersion());\n process.exit(0);\n return;\n }\n\n // An unexpected throw must surface as a readable error AND a non-zero exit\n // code — never as a stack trace the user scrolls past on the way to a green\n // banner (there is no banner after this point).\n Promise.resolve(createNewApp(flags)).catch((error: unknown) => {\n console.error();\n console.error(\n ` create-warlock failed: ${(error as Error)?.message ?? String(error)}`,\n );\n console.error();\n\n process.exit(1);\n });\n}\n"],"mappings":";;;;;;;AAOA,MAAM,aAAa;CAAC;CAAQ;CAAM;CAAM;CAAY;CAAM;CAAU;AAAO;AAE3E,MAAM,YAAY,cAAc;;;;;;;AAQhC,SAAgB,WAAW,MAA0B;CACnD,MAAM,QAAkB,CAAC;CACzB,MAAM,cAAwB,CAAC;CAE/B,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;EACpC,MAAM,MAAM,KAAK;EAEjB,IAAI,CAAC,IAAI,WAAW,GAAG,GAAG;GACxB,YAAY,KAAK,GAAG;GACpB;EACF;EAEA,MAAM,aAAa,IAAI,QAAQ,GAAG;EAClC,MAAM,OAAO,eAAe,KAAK,MAAM,IAAI,MAAM,GAAG,UAAU,EAAC,CAAE,QAC/D,OACA,EACF;EACA,IAAI,QACF,eAAe,KAAK,SAAY,IAAI,MAAM,aAAa,CAAC;EAG1D,IAAI,WAAW,SAAS,GAAG,KAAK,UAAU,QAAW;GACnD,MAAM,OAAO,KAAK,IAAI;GAEtB,IAAI,QAAQ,CAAC,KAAK,WAAW,GAAG,GAAG;IACjC,QAAQ;IACR;GACF;EACF;EAEA,QAAQ,KAAR;GACE,KAAK;GACL,KAAK;IACH,MAAM,OAAO;IACb;GACF,KAAK;GACL,KAAK;IACH,MAAM,UAAU;IAChB;GACF,KAAK;GACL,KAAK;IACH,MAAM,MAAM;IACZ;GACF,KAAK;IACH,MAAM,MAAM;IACZ;GACF,KAAK;IACH,MAAM,MAAM;IACZ;GACF,KAAK;IACH,MAAM,MAAM;IACZ;GACF,KAAK;IACH,MAAM,MAAM;IACZ;GACF,KAAK;IACH,MAAM,OAAO;IACb;GACF,KAAK;IACH,MAAM,KAAK;IACX;GACF,KAAK;IAEH,MAAM,KAAK;IACX;GACF,KAAK;IAIH,MAAM,KAAK,SAAS;IACpB;GACF,KAAK;IACH,MAAM,WAAW,UAAU,KAAK;IAChC;GACF,KAAK;IACH,MAAM,KAAK,UAAU,KAAK;IAC1B;GACF,KAAK;IACH,MAAM,SAAS,UAAU,KAAK;IAC9B;GACF,KAAK;IACH,MAAM,QAAQ;IACd;GACF,KAAK;GACL,KAAK;IACH,MAAM,cAAc;IACpB;EACJ;CACF;CAEA,IAAI,CAAC,MAAM,QAAQ,YAAY,SAAS,GACtC,MAAM,OAAO,YAAY;CAG3B,OAAO;AACT;AAEA,SAAS,UAAU,OAAqC;CACtD,IAAI,CAAC,OAAO,OAAO,CAAC;CAEpB,OAAO,MACJ,MAAM,GAAG,CAAC,CACV,KAAI,SAAQ,KAAK,KAAK,CAAC,CAAC,CACxB,OAAO,OAAO;AACnB;;;;;;AAOA,SAAgB,iBAAyB;CACvC,OAAQ,YAAY,YAAY,cAAc,CAAC,CAAC,CAC7C;AACL;AAEA,SAAwB,YAAY;CAClC,MAAM,QAAQ,WAAW,QAAQ,KAAK,MAAM,CAAC,CAAC;CAK9C,IAAI,MAAM,MAAM;EACd,QAAQ,IAAI,SAAS;EACrB,QAAQ,KAAK,CAAC;EACd;CACF;CAEA,IAAI,MAAM,SAAS;EACjB,QAAQ,IAAI,eAAe,CAAC;EAC5B,QAAQ,KAAK,CAAC;EACd;CACF;CAKA,QAAQ,QAAQ,aAAa,KAAK,CAAC,CAAC,CAAC,OAAO,UAAmB;EAC7D,QAAQ,MAAM;EACd,QAAQ,MACN,4BAA6B,OAAiB,WAAW,OAAO,KAAK,GACvE;EACA,QAAQ,MAAM;EAEd,QAAQ,KAAK,CAAC;CAChB,CAAC;AACH"}
@@ -1,7 +1,8 @@
1
1
  import { BUILTIN_AGENT_KIT_TARGETS, DEFAULT_AGENT_KIT_TARGET, getValidAgentKitTargets } from "../features/agent-kit-targets.mjs";
2
+ import { multiselectMaxItems } from "./fit-to-terminal.mjs";
2
3
  import { cancel, isCancel, multiselect } from "@clack/prompts";
3
4
 
4
- //#region ../create-warlock/src/prompts/ask-agent-targets.ts
5
+ //#region ../../packages/create-warlock/src/prompts/ask-agent-targets.ts
5
6
  /**
6
7
  * Which `agent-kit` targets to derive per-agent docs and skills for.
7
8
  *
@@ -27,7 +28,8 @@ async function askAgentTargets(requested) {
27
28
  label: target
28
29
  })),
29
30
  initialValues: initialSelection(requested, targets),
30
- required: false
31
+ required: false,
32
+ maxItems: multiselectMaxItems(targets.length)
31
33
  });
32
34
  if (isCancel(answer)) {
33
35
  cancel("Agent selection cancelled");
@@ -1 +1 @@
1
- {"version":3,"file":"ask-agent-targets.mjs","names":[],"sources":["../../../../../../create-warlock/src/prompts/ask-agent-targets.ts"],"sourcesContent":["import { cancel, isCancel, multiselect } from \"@clack/prompts\";\nimport {\n BUILTIN_AGENT_KIT_TARGETS,\n DEFAULT_AGENT_KIT_TARGET,\n getValidAgentKitTargets,\n} from \"../features/agent-kit-targets\";\n\n/**\n * Which `agent-kit` targets to derive per-agent docs and skills for.\n *\n * The valid target list is not a literal we own — it comes from the installed\n * `@mongez/agent-kit`, or a cached network fetch, and\n * {@link getValidAgentKitTargets} THROWS when neither is available. That is\n * the right behaviour for `--agents=something-unusual`, where guessing would\n * be worse than failing. It is the wrong behaviour here: this prompt sits\n * five questions into the wizard, and an offline laptop must not lose four\n * already-given answers to a failed HTTP request.\n *\n * So an unreachable list is not fatal — it narrows the menu to the built-in\n * targets and SAYS SO, rather than either crashing or silently pretending\n * that is the whole list.\n */\nexport async function askAgentTargets(\n requested: string[] | undefined,\n): Promise<string[]> {\n const { targets: known, complete } = await availableTargets();\n const targets = reconcileRequested(requested, known, complete);\n\n const answer = await multiselect({\n message: complete\n ? \"Which coding agents should this project be set up for?\"\n : \"Which coding agents should this project be set up for? (offline — showing built-in targets only)\",\n options: targets.map(target => ({ value: target, label: target })),\n initialValues: initialSelection(requested, targets),\n required: false,\n });\n\n if (isCancel(answer)) {\n cancel(\"Agent selection cancelled\");\n process.exit(0);\n }\n\n const selected = answer as string[];\n\n return selected.length > 0 ? selected : [DEFAULT_AGENT_KIT_TARGET];\n}\n\n/**\n * The target list, plus whether it is the REAL one. `complete: false` means\n * the lookup failed and these are only the offline built-ins.\n */\nasync function availableTargets(): Promise<{\n targets: string[];\n complete: boolean;\n}> {\n try {\n return { targets: await getValidAgentKitTargets(), complete: true };\n } catch {\n return { targets: [...BUILTIN_AGENT_KIT_TARGETS], complete: false };\n }\n}\n\n/**\n * What `--agents` asked for has to end up among the OPTIONS, or it would be\n * pre-ticked invisibly and then silently dropped — the same defect this\n * wizard's other flags already had.\n *\n * With a complete list, an unrecognised target is refused, naming the valid\n * ones, exactly as `resolveAgentTargets` does for the non-interactive path.\n * With an incomplete one, we have no authority to call anything invalid, so\n * the requested targets are offered alongside the built-ins instead of being\n * judged.\n */\nfunction reconcileRequested(\n requested: string[] | undefined,\n known: string[],\n complete: boolean,\n): string[] {\n if (!requested || requested.length === 0) return known;\n\n const unknown = requested.filter(target => !known.includes(target));\n\n if (unknown.length === 0) return known;\n\n if (complete) {\n cancel(\n `Unknown agent-kit target(s): ${unknown.join(\", \")} — valid targets: ${known\n .slice()\n .sort()\n .join(\", \")}`,\n );\n process.exit(1);\n }\n\n return [...known, ...unknown];\n}\n\n/**\n * Pre-tick what `--agents` asked for. Everything it names is among the\n * options by now, so nothing is filtered away here.\n */\nfunction initialSelection(\n requested: string[] | undefined,\n targets: string[],\n): string[] {\n const wanted =\n requested && requested.length > 0 ? requested : [DEFAULT_AGENT_KIT_TARGET];\n\n return wanted.filter(target => targets.includes(target));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAsBA,eAAsB,gBACpB,WACmB;CACnB,MAAM,EAAE,SAAS,OAAO,aAAa,MAAM,iBAAiB;CAC5D,MAAM,UAAU,mBAAmB,WAAW,OAAO,QAAQ;CAE7D,MAAM,SAAS,MAAM,YAAY;EAC/B,SAAS,WACL,2DACA;EACJ,SAAS,QAAQ,KAAI,YAAW;GAAE,OAAO;GAAQ,OAAO;EAAO,EAAE;EACjE,eAAe,iBAAiB,WAAW,OAAO;EAClD,UAAU;CACZ,CAAC;CAED,IAAI,SAAS,MAAM,GAAG;EACpB,OAAO,2BAA2B;EAClC,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,WAAW;CAEjB,OAAO,SAAS,SAAS,IAAI,WAAW,CAAC,wBAAwB;AACnE;;;;;AAMA,eAAe,mBAGZ;CACD,IAAI;EACF,OAAO;GAAE,SAAS,MAAM,wBAAwB;GAAG,UAAU;EAAK;CACpE,QAAQ;EACN,OAAO;GAAE,SAAS,CAAC,GAAG,yBAAyB;GAAG,UAAU;EAAM;CACpE;AACF;;;;;;;;;;;;AAaA,SAAS,mBACP,WACA,OACA,UACU;CACV,IAAI,CAAC,aAAa,UAAU,WAAW,GAAG,OAAO;CAEjD,MAAM,UAAU,UAAU,QAAO,WAAU,CAAC,MAAM,SAAS,MAAM,CAAC;CAElE,IAAI,QAAQ,WAAW,GAAG,OAAO;CAEjC,IAAI,UAAU;EACZ,OACE,gCAAgC,QAAQ,KAAK,IAAI,EAAE,oBAAoB,MACpE,MAAM,CAAC,CACP,KAAK,CAAC,CACN,KAAK,IAAI,GACd;EACA,QAAQ,KAAK,CAAC;CAChB;CAEA,OAAO,CAAC,GAAG,OAAO,GAAG,OAAO;AAC9B;;;;;AAMA,SAAS,iBACP,WACA,SACU;CAIV,QAFE,aAAa,UAAU,SAAS,IAAI,YAAY,CAAC,wBAAwB,EAE9D,CAAC,QAAO,WAAU,QAAQ,SAAS,MAAM,CAAC;AACzD"}
1
+ {"version":3,"file":"ask-agent-targets.mjs","names":[],"sources":["../../../../../../../packages/create-warlock/src/prompts/ask-agent-targets.ts"],"sourcesContent":["import { cancel, isCancel, multiselect } from \"@clack/prompts\";\nimport {\n BUILTIN_AGENT_KIT_TARGETS,\n DEFAULT_AGENT_KIT_TARGET,\n getValidAgentKitTargets,\n} from \"../features/agent-kit-targets\";\nimport { multiselectMaxItems } from \"./fit-to-terminal\";\n\n/**\n * Which `agent-kit` targets to derive per-agent docs and skills for.\n *\n * The valid target list is not a literal we own — it comes from the installed\n * `@mongez/agent-kit`, or a cached network fetch, and\n * {@link getValidAgentKitTargets} THROWS when neither is available. That is\n * the right behaviour for `--agents=something-unusual`, where guessing would\n * be worse than failing. It is the wrong behaviour here: this prompt sits\n * five questions into the wizard, and an offline laptop must not lose four\n * already-given answers to a failed HTTP request.\n *\n * So an unreachable list is not fatal — it narrows the menu to the built-in\n * targets and SAYS SO, rather than either crashing or silently pretending\n * that is the whole list.\n */\nexport async function askAgentTargets(\n requested: string[] | undefined,\n): Promise<string[]> {\n const { targets: known, complete } = await availableTargets();\n const targets = reconcileRequested(requested, known, complete);\n\n const answer = await multiselect({\n message: complete\n ? \"Which coding agents should this project be set up for?\"\n : \"Which coding agents should this project be set up for? (offline — showing built-in targets only)\",\n options: targets.map(target => ({ value: target, label: target })),\n initialValues: initialSelection(requested, targets),\n required: false,\n maxItems: multiselectMaxItems(targets.length),\n });\n\n if (isCancel(answer)) {\n cancel(\"Agent selection cancelled\");\n process.exit(0);\n }\n\n const selected = answer as string[];\n\n return selected.length > 0 ? selected : [DEFAULT_AGENT_KIT_TARGET];\n}\n\n/**\n * The target list, plus whether it is the REAL one. `complete: false` means\n * the lookup failed and these are only the offline built-ins.\n */\nasync function availableTargets(): Promise<{\n targets: string[];\n complete: boolean;\n}> {\n try {\n return { targets: await getValidAgentKitTargets(), complete: true };\n } catch {\n return { targets: [...BUILTIN_AGENT_KIT_TARGETS], complete: false };\n }\n}\n\n/**\n * What `--agents` asked for has to end up among the OPTIONS, or it would be\n * pre-ticked invisibly and then silently dropped — the same defect this\n * wizard's other flags already had.\n *\n * With a complete list, an unrecognised target is refused, naming the valid\n * ones, exactly as `resolveAgentTargets` does for the non-interactive path.\n * With an incomplete one, we have no authority to call anything invalid, so\n * the requested targets are offered alongside the built-ins instead of being\n * judged.\n */\nfunction reconcileRequested(\n requested: string[] | undefined,\n known: string[],\n complete: boolean,\n): string[] {\n if (!requested || requested.length === 0) return known;\n\n const unknown = requested.filter(target => !known.includes(target));\n\n if (unknown.length === 0) return known;\n\n if (complete) {\n cancel(\n `Unknown agent-kit target(s): ${unknown.join(\", \")} — valid targets: ${known\n .slice()\n .sort()\n .join(\", \")}`,\n );\n process.exit(1);\n }\n\n return [...known, ...unknown];\n}\n\n/**\n * Pre-tick what `--agents` asked for. Everything it names is among the\n * options by now, so nothing is filtered away here.\n */\nfunction initialSelection(\n requested: string[] | undefined,\n targets: string[],\n): string[] {\n const wanted =\n requested && requested.length > 0 ? requested : [DEFAULT_AGENT_KIT_TARGET];\n\n return wanted.filter(target => targets.includes(target));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAuBA,eAAsB,gBACpB,WACmB;CACnB,MAAM,EAAE,SAAS,OAAO,aAAa,MAAM,iBAAiB;CAC5D,MAAM,UAAU,mBAAmB,WAAW,OAAO,QAAQ;CAE7D,MAAM,SAAS,MAAM,YAAY;EAC/B,SAAS,WACL,2DACA;EACJ,SAAS,QAAQ,KAAI,YAAW;GAAE,OAAO;GAAQ,OAAO;EAAO,EAAE;EACjE,eAAe,iBAAiB,WAAW,OAAO;EAClD,UAAU;EACV,UAAU,oBAAoB,QAAQ,MAAM;CAC9C,CAAC;CAED,IAAI,SAAS,MAAM,GAAG;EACpB,OAAO,2BAA2B;EAClC,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,WAAW;CAEjB,OAAO,SAAS,SAAS,IAAI,WAAW,CAAC,wBAAwB;AACnE;;;;;AAMA,eAAe,mBAGZ;CACD,IAAI;EACF,OAAO;GAAE,SAAS,MAAM,wBAAwB;GAAG,UAAU;EAAK;CACpE,QAAQ;EACN,OAAO;GAAE,SAAS,CAAC,GAAG,yBAAyB;GAAG,UAAU;EAAM;CACpE;AACF;;;;;;;;;;;;AAaA,SAAS,mBACP,WACA,OACA,UACU;CACV,IAAI,CAAC,aAAa,UAAU,WAAW,GAAG,OAAO;CAEjD,MAAM,UAAU,UAAU,QAAO,WAAU,CAAC,MAAM,SAAS,MAAM,CAAC;CAElE,IAAI,QAAQ,WAAW,GAAG,OAAO;CAEjC,IAAI,UAAU;EACZ,OACE,gCAAgC,QAAQ,KAAK,IAAI,EAAE,oBAAoB,MACpE,MAAM,CAAC,CACP,KAAK,CAAC,CACN,KAAK,IAAI,GACd;EACA,QAAQ,KAAK,CAAC;CAChB;CAEA,OAAO,CAAC,GAAG,OAAO,GAAG,OAAO;AAC9B;;;;;AAMA,SAAS,iBACP,WACA,SACU;CAIV,QAFE,aAAa,UAAU,SAAS,IAAI,YAAY,CAAC,wBAAwB,EAE9D,CAAC,QAAO,WAAU,QAAQ,SAAS,MAAM,CAAC;AACzD"}
@@ -1,7 +1,8 @@
1
1
  import { getAiPackageOptions, getAiProviderOptions } from "../features/features-map.mjs";
2
+ import { fitOptionsToWidth, multiselectMaxItems } from "./fit-to-terminal.mjs";
2
3
  import { isCancel, log, multiselect } from "@clack/prompts";
3
4
 
4
- //#region ../create-warlock/src/prompts/ask-ai-features.ts
5
+ //#region ../../packages/create-warlock/src/prompts/ask-ai-features.ts
5
6
  const NO_AI = "none";
6
7
  const aiOptions = [
7
8
  ...getAiProviderOptions(),
@@ -18,9 +19,10 @@ async function askAiFeatures(initialValues = []) {
18
19
  while (true) {
19
20
  const answer = await multiselect({
20
21
  message: "Add AI packages? Providers + capabilities — the core AI package is included automatically",
21
- options: aiOptions,
22
+ options: fitOptionsToWidth(aiOptions),
22
23
  initialValues: selectedValues,
23
- required: false
24
+ required: false,
25
+ maxItems: multiselectMaxItems(aiOptions.length)
24
26
  });
25
27
  if (isCancel(answer)) return answer;
26
28
  const selected = answer;
@@ -1 +1 @@
1
- {"version":3,"file":"ask-ai-features.mjs","names":[],"sources":["../../../../../../create-warlock/src/prompts/ask-ai-features.ts"],"sourcesContent":["import { isCancel, log, multiselect } from \"@clack/prompts\";\nimport {\n getAiPackageOptions,\n getAiProviderOptions,\n} from \"../features/features-map\";\n\nconst NO_AI = \"none\";\n\nconst aiOptions = [\n ...getAiProviderOptions(),\n ...getAiPackageOptions(),\n {\n value: NO_AI,\n label: \"None\",\n hint: \"Do not add AI providers or capability packages\",\n },\n];\n\n/** Ask for optional AI packages without leaking the UI-only None sentinel. */\nexport async function askAiFeatures(\n initialValues: string[] = [],\n): Promise<string[] | symbol> {\n let selectedValues = initialValues.filter(value => value !== NO_AI);\n\n while (true) {\n const answer = await multiselect({\n message:\n \"Add AI packages? Providers + capabilities — the core AI package is included automatically\",\n options: aiOptions,\n initialValues: selectedValues,\n required: false,\n });\n\n if (isCancel(answer)) return answer;\n\n const selected = answer as string[];\n\n if (!selected.includes(NO_AI)) return selected;\n\n if (selected.length === 1) return [];\n\n log.warn(\"Choose None by itself, or select one or more AI packages.\");\n\n selectedValues = selected.filter(value => value !== NO_AI);\n }\n}\n"],"mappings":";;;;AAMA,MAAM,QAAQ;AAEd,MAAM,YAAY;CAChB,GAAG,qBAAqB;CACxB,GAAG,oBAAoB;CACvB;EACE,OAAO;EACP,OAAO;EACP,MAAM;CACR;AACF;;AAGA,eAAsB,cACpB,gBAA0B,CAAC,GACC;CAC5B,IAAI,iBAAiB,cAAc,QAAO,UAAS,UAAU,KAAK;CAElE,OAAO,MAAM;EACX,MAAM,SAAS,MAAM,YAAY;GAC/B,SACE;GACF,SAAS;GACT,eAAe;GACf,UAAU;EACZ,CAAC;EAED,IAAI,SAAS,MAAM,GAAG,OAAO;EAE7B,MAAM,WAAW;EAEjB,IAAI,CAAC,SAAS,SAAS,KAAK,GAAG,OAAO;EAEtC,IAAI,SAAS,WAAW,GAAG,OAAO,CAAC;EAEnC,IAAI,KAAK,2DAA2D;EAEpE,iBAAiB,SAAS,QAAO,UAAS,UAAU,KAAK;CAC3D;AACF"}
1
+ {"version":3,"file":"ask-ai-features.mjs","names":[],"sources":["../../../../../../../packages/create-warlock/src/prompts/ask-ai-features.ts"],"sourcesContent":["import { isCancel, log, multiselect } from \"@clack/prompts\";\nimport {\n getAiPackageOptions,\n getAiProviderOptions,\n} from \"../features/features-map\";\nimport { fitOptionsToWidth, multiselectMaxItems } from \"./fit-to-terminal\";\n\nconst NO_AI = \"none\";\n\nconst aiOptions = [\n ...getAiProviderOptions(),\n ...getAiPackageOptions(),\n {\n value: NO_AI,\n label: \"None\",\n hint: \"Do not add AI providers or capability packages\",\n },\n];\n\n/** Ask for optional AI packages without leaking the UI-only None sentinel. */\nexport async function askAiFeatures(\n initialValues: string[] = [],\n): Promise<string[] | symbol> {\n let selectedValues = initialValues.filter(value => value !== NO_AI);\n\n while (true) {\n const answer = await multiselect({\n message:\n \"Add AI packages? Providers + capabilities — the core AI package is included automatically\",\n options: fitOptionsToWidth(aiOptions),\n initialValues: selectedValues,\n required: false,\n maxItems: multiselectMaxItems(aiOptions.length),\n });\n\n if (isCancel(answer)) return answer;\n\n const selected = answer as string[];\n\n if (!selected.includes(NO_AI)) return selected;\n\n if (selected.length === 1) return [];\n\n log.warn(\"Choose None by itself, or select one or more AI packages.\");\n\n selectedValues = selected.filter(value => value !== NO_AI);\n }\n}\n"],"mappings":";;;;;AAOA,MAAM,QAAQ;AAEd,MAAM,YAAY;CAChB,GAAG,qBAAqB;CACxB,GAAG,oBAAoB;CACvB;EACE,OAAO;EACP,OAAO;EACP,MAAM;CACR;AACF;;AAGA,eAAsB,cACpB,gBAA0B,CAAC,GACC;CAC5B,IAAI,iBAAiB,cAAc,QAAO,UAAS,UAAU,KAAK;CAElE,OAAO,MAAM;EACX,MAAM,SAAS,MAAM,YAAY;GAC/B,SACE;GACF,SAAS,kBAAkB,SAAS;GACpC,eAAe;GACf,UAAU;GACV,UAAU,oBAAoB,UAAU,MAAM;EAChD,CAAC;EAED,IAAI,SAAS,MAAM,GAAG,OAAO;EAE7B,MAAM,WAAW;EAEjB,IAAI,CAAC,SAAS,SAAS,KAAK,GAAG,OAAO;EAEtC,IAAI,SAAS,WAAW,GAAG,OAAO,CAAC;EAEnC,IAAI,KAAK,2DAA2D;EAEpE,iBAAiB,SAAS,QAAO,UAAS,UAAU,KAAK;CAC3D;AACF"}
@@ -1,6 +1,6 @@
1
1
  import { cancel, isCancel, text } from "@clack/prompts";
2
2
 
3
- //#region ../create-warlock/src/prompts/ask-project-name.ts
3
+ //#region ../../packages/create-warlock/src/prompts/ask-project-name.ts
4
4
  /**
5
5
  * The project name is the one answer with no sane default, so every
6
6
  * interactive path has to ask it. It lives here so the default path and the
@@ -1 +1 @@
1
- {"version":3,"file":"ask-project-name.mjs","names":[],"sources":["../../../../../../create-warlock/src/prompts/ask-project-name.ts"],"sourcesContent":["import { cancel, isCancel, text } from \"@clack/prompts\";\n\n/**\n * The project name is the one answer with no sane default, so every\n * interactive path has to ask it. It lives here so the default path and the\n * full wizard ask it with the SAME wording and the same cancel handling —\n * and so a name already collected by one path can simply be handed to the\n * other instead of being asked a second time.\n */\nexport async function askProjectName(): Promise<string> {\n const answer = await text({\n message: \"What shall we call your project?\",\n placeholder: \"my-warlock-app\",\n });\n\n if (isCancel(answer) || !answer.trim()) {\n cancel(\"A project name is required to continue\");\n process.exit(0);\n }\n\n return answer;\n}\n"],"mappings":";;;;;;;;;;AASA,eAAsB,iBAAkC;CACtD,MAAM,SAAS,MAAM,KAAK;EACxB,SAAS;EACT,aAAa;CACf,CAAC;CAED,IAAI,SAAS,MAAM,KAAK,CAAC,OAAO,KAAK,GAAG;EACtC,OAAO,wCAAwC;EAC/C,QAAQ,KAAK,CAAC;CAChB;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"ask-project-name.mjs","names":[],"sources":["../../../../../../../packages/create-warlock/src/prompts/ask-project-name.ts"],"sourcesContent":["import { cancel, isCancel, text } from \"@clack/prompts\";\n\n/**\n * The project name is the one answer with no sane default, so every\n * interactive path has to ask it. It lives here so the default path and the\n * full wizard ask it with the SAME wording and the same cancel handling —\n * and so a name already collected by one path can simply be handed to the\n * other instead of being asked a second time.\n */\nexport async function askProjectName(): Promise<string> {\n const answer = await text({\n message: \"What shall we call your project?\",\n placeholder: \"my-warlock-app\",\n });\n\n if (isCancel(answer) || !answer.trim()) {\n cancel(\"A project name is required to continue\");\n process.exit(0);\n }\n\n return answer;\n}\n"],"mappings":";;;;;;;;;;AASA,eAAsB,iBAAkC;CACtD,MAAM,SAAS,MAAM,KAAK;EACxB,SAAS;EACT,aAAa;CACf,CAAC;CAED,IAAI,SAAS,MAAM,KAAK,CAAC,OAAO,KAAK,GAAG;EACtC,OAAO,wCAAwC;EAC/C,QAAQ,KAAK,CAAC;CAChB;CAEA,OAAO;AACT"}
@@ -1,6 +1,6 @@
1
1
  import { cancel, isCancel, select } from "@clack/prompts";
2
2
 
3
- //#region ../create-warlock/src/prompts/ask-stack.ts
3
+ //#region ../../packages/create-warlock/src/prompts/ask-stack.ts
4
4
  /**
5
5
  * The structural question in the default (non-`--interactive`) interactive
6
6
  * path: does the generated app need server-rendered web pages, or is it an
@@ -1 +1 @@
1
- {"version":3,"file":"ask-stack.mjs","names":[],"sources":["../../../../../../create-warlock/src/prompts/ask-stack.ts"],"sourcesContent":["import { cancel, isCancel, select } from \"@clack/prompts\";\nimport type { SetupChoice } from \"../commands/create-new-app/types\";\n\n/**\n * The structural question in the default (non-`--interactive`) interactive\n * path: does the generated app need server-rendered web pages, or is it an\n * API only? The following database prompt is shared by both presets; the\n * remaining choices stay behind flags or the Customize wizard.\n *\n * The third entry is not a third stack: `customize` selects the FLOW, handing\n * the run to the full wizard (`--customize`) so every one of those reversible\n * choices gets asked instead of defaulted. It sits in this menu because a flag\n * nobody is told about is a feature nobody has.\n */\nexport async function askStack(): Promise<SetupChoice> {\n const answer = await select({\n message: \"What are we building?\",\n options: [\n {\n value: \"api\",\n label: \"API only\",\n hint: \"A REST API, no server-rendered pages\",\n },\n {\n value: \"web\",\n label: \"Full-stack web\",\n hint: \"API + server-rendered React pages (SSR)\",\n },\n {\n value: \"customize\",\n label: \"Customize\",\n hint: \"Pick package manager, database, features, AI providers and coding agents one by one\",\n },\n ],\n initialValue: \"api\",\n });\n\n if (isCancel(answer)) {\n cancel(\"Setup cancelled\");\n process.exit(0);\n }\n\n return answer as SetupChoice;\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,eAAsB,WAAiC;CACrD,MAAM,SAAS,MAAM,OAAO;EAC1B,SAAS;EACT,SAAS;GACP;IACE,OAAO;IACP,OAAO;IACP,MAAM;GACR;GACA;IACE,OAAO;IACP,OAAO;IACP,MAAM;GACR;GACA;IACE,OAAO;IACP,OAAO;IACP,MAAM;GACR;EACF;EACA,cAAc;CAChB,CAAC;CAED,IAAI,SAAS,MAAM,GAAG;EACpB,OAAO,iBAAiB;EACxB,QAAQ,KAAK,CAAC;CAChB;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"ask-stack.mjs","names":[],"sources":["../../../../../../../packages/create-warlock/src/prompts/ask-stack.ts"],"sourcesContent":["import { cancel, isCancel, select } from \"@clack/prompts\";\nimport type { SetupChoice } from \"../commands/create-new-app/types\";\n\n/**\n * The structural question in the default (non-`--interactive`) interactive\n * path: does the generated app need server-rendered web pages, or is it an\n * API only? The following database prompt is shared by both presets; the\n * remaining choices stay behind flags or the Customize wizard.\n *\n * The third entry is not a third stack: `customize` selects the FLOW, handing\n * the run to the full wizard (`--customize`) so every one of those reversible\n * choices gets asked instead of defaulted. It sits in this menu because a flag\n * nobody is told about is a feature nobody has.\n */\nexport async function askStack(): Promise<SetupChoice> {\n const answer = await select({\n message: \"What are we building?\",\n options: [\n {\n value: \"api\",\n label: \"API only\",\n hint: \"A REST API, no server-rendered pages\",\n },\n {\n value: \"web\",\n label: \"Full-stack web\",\n hint: \"API + server-rendered React pages (SSR)\",\n },\n {\n value: \"customize\",\n label: \"Customize\",\n hint: \"Pick package manager, database, features, AI providers and coding agents one by one\",\n },\n ],\n initialValue: \"api\",\n });\n\n if (isCancel(answer)) {\n cancel(\"Setup cancelled\");\n process.exit(0);\n }\n\n return answer as SetupChoice;\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,eAAsB,WAAiC;CACrD,MAAM,SAAS,MAAM,OAAO;EAC1B,SAAS;EACT,SAAS;GACP;IACE,OAAO;IACP,OAAO;IACP,MAAM;GACR;GACA;IACE,OAAO;IACP,OAAO;IACP,MAAM;GACR;GACA;IACE,OAAO;IACP,OAAO;IACP,MAAM;GACR;EACF;EACA,cAAc;CAChB,CAAC;CAED,IAAI,SAAS,MAAM,GAAG;EACpB,OAAO,iBAAiB;EACxB,QAAQ,KAAK,CAAC;CAChB;CAEA,OAAO;AACT"}
@@ -0,0 +1,46 @@
1
+ //#region ../../packages/create-warlock/src/prompts/fit-to-terminal.ts
2
+ /** Used when the output is not a terminal (piped, CI) and reports no size. */
3
+ const FALLBACK_COLUMNS = 80;
4
+ const FALLBACK_ROWS = 24;
5
+ /** Lines a multiselect draws besides its options: message, bars, scroll markers, a spare line. */
6
+ const PROMPT_CHROME_LINES = 6;
7
+ /** clack never shows fewer than five options, whatever maxItems says. */
8
+ const MIN_VISIBLE_OPTIONS = 5;
9
+ /** `│ ◻ ` before the label, ` (` and `)` around the hint. */
10
+ const ROW_PREFIX_WIDTH = 5;
11
+ const HINT_BRACKETS_WIDTH = 3;
12
+ /** Below this many characters a hint says nothing useful, so it is dropped. */
13
+ const MIN_HINT_WIDTH = 12;
14
+ /**
15
+ * How many options a multiselect may show at once in a terminal `rows` lines
16
+ * tall. clack scrolls the rest.
17
+ */
18
+ function multiselectMaxItems(optionCount, rows = process.stdout.rows) {
19
+ const fit = Math.max(MIN_VISIBLE_OPTIONS, (rows && rows > 0 ? rows : FALLBACK_ROWS) - PROMPT_CHROME_LINES);
20
+ return Math.min(optionCount, fit);
21
+ }
22
+ /**
23
+ * Shorten each option's hint so its row (label and hint) fits on one line of a
24
+ * terminal `columns` wide. A hint with too little room left is dropped.
25
+ */
26
+ function fitOptionsToWidth(options, columns = process.stdout.columns) {
27
+ const width = (columns && columns > 0 ? columns : FALLBACK_COLUMNS) - 1;
28
+ return options.map((option) => {
29
+ if (!option.hint) return option;
30
+ const room = width - ROW_PREFIX_WIDTH - option.label.length - HINT_BRACKETS_WIDTH;
31
+ if (option.hint.length <= room) return option;
32
+ if (room < MIN_HINT_WIDTH) {
33
+ const withoutHint = { ...option };
34
+ delete withoutHint.hint;
35
+ return withoutHint;
36
+ }
37
+ return {
38
+ ...option,
39
+ hint: `${option.hint.slice(0, room - 1).trimEnd()}…`
40
+ };
41
+ });
42
+ }
43
+
44
+ //#endregion
45
+ export { fitOptionsToWidth, multiselectMaxItems };
46
+ //# sourceMappingURL=fit-to-terminal.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fit-to-terminal.mjs","names":[],"sources":["../../../../../../../packages/create-warlock/src/prompts/fit-to-terminal.ts"],"sourcesContent":["/**\n * Sizing for clack list prompts, so a prompt never draws more lines than the\n * terminal shows.\n *\n * clack redraws a prompt by moving the cursor up as many lines as its last\n * frame had `\\n`s. When the frame is taller than the terminal, or a row is\n * wider than the terminal and wraps, the cursor cannot reach the old lines:\n * every redraw then prints a fresh copy of the list below the last one.\n * Keeping each row on one line and the option list within the terminal's\n * height avoids both.\n */\n\ntype ListOption = { label: string; hint?: string };\n\n/** Used when the output is not a terminal (piped, CI) and reports no size. */\nconst FALLBACK_COLUMNS = 80;\nconst FALLBACK_ROWS = 24;\n\n/** Lines a multiselect draws besides its options: message, bars, scroll markers, a spare line. */\nconst PROMPT_CHROME_LINES = 6;\n\n/** clack never shows fewer than five options, whatever maxItems says. */\nconst MIN_VISIBLE_OPTIONS = 5;\n\n/** `│ ◻ ` before the label, ` (` and `)` around the hint. */\nconst ROW_PREFIX_WIDTH = 5;\nconst HINT_BRACKETS_WIDTH = 3;\n\n/** Below this many characters a hint says nothing useful, so it is dropped. */\nconst MIN_HINT_WIDTH = 12;\n\n/**\n * How many options a multiselect may show at once in a terminal `rows` lines\n * tall. clack scrolls the rest.\n */\nexport function multiselectMaxItems(\n optionCount: number,\n rows = process.stdout.rows,\n): number {\n const height = rows && rows > 0 ? rows : FALLBACK_ROWS;\n const fit = Math.max(MIN_VISIBLE_OPTIONS, height - PROMPT_CHROME_LINES);\n\n return Math.min(optionCount, fit);\n}\n\n/**\n * Shorten each option's hint so its row (label and hint) fits on one line of a\n * terminal `columns` wide. A hint with too little room left is dropped.\n */\nexport function fitOptionsToWidth<Option extends ListOption>(\n options: readonly Option[],\n columns = process.stdout.columns,\n): Option[] {\n const width = (columns && columns > 0 ? columns : FALLBACK_COLUMNS) - 1;\n\n return options.map(option => {\n if (!option.hint) return option;\n\n const room =\n width - ROW_PREFIX_WIDTH - option.label.length - HINT_BRACKETS_WIDTH;\n\n if (option.hint.length <= room) return option;\n\n if (room < MIN_HINT_WIDTH) {\n const withoutHint = { ...option };\n\n delete withoutHint.hint;\n\n return withoutHint;\n }\n\n return { ...option, hint: `${option.hint.slice(0, room - 1).trimEnd()}…` };\n });\n}\n"],"mappings":";;AAeA,MAAM,mBAAmB;AACzB,MAAM,gBAAgB;;AAGtB,MAAM,sBAAsB;;AAG5B,MAAM,sBAAsB;;AAG5B,MAAM,mBAAmB;AACzB,MAAM,sBAAsB;;AAG5B,MAAM,iBAAiB;;;;;AAMvB,SAAgB,oBACd,aACA,OAAO,QAAQ,OAAO,MACd;CAER,MAAM,MAAM,KAAK,IAAI,sBADN,QAAQ,OAAO,IAAI,OAAO,iBACU,mBAAmB;CAEtE,OAAO,KAAK,IAAI,aAAa,GAAG;AAClC;;;;;AAMA,SAAgB,kBACd,SACA,UAAU,QAAQ,OAAO,SACf;CACV,MAAM,SAAS,WAAW,UAAU,IAAI,UAAU,oBAAoB;CAEtE,OAAO,QAAQ,KAAI,WAAU;EAC3B,IAAI,CAAC,OAAO,MAAM,OAAO;EAEzB,MAAM,OACJ,QAAQ,mBAAmB,OAAO,MAAM,SAAS;EAEnD,IAAI,OAAO,KAAK,UAAU,MAAM,OAAO;EAEvC,IAAI,OAAO,gBAAgB;GACzB,MAAM,cAAc,EAAE,GAAG,OAAO;GAEhC,OAAO,YAAY;GAEnB,OAAO;EACT;EAEA,OAAO;GAAE,GAAG;GAAQ,MAAM,GAAG,OAAO,KAAK,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;EAAG;CAC3E,CAAC;AACH"}
package/esm/summary.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { getDatabaseLabel } from "./features/database-drivers.mjs";
2
2
  import { colors } from "@mongez/copper";
3
3
 
4
- //#region ../create-warlock/src/summary.ts
4
+ //#region ../../packages/create-warlock/src/summary.ts
5
5
  /**
6
6
  * Print what the scaffolder decided on the user's behalf, and how to change
7
7
  * each decision — required because almost every choice is now a default
@@ -1 +1 @@
1
- {"version":3,"file":"summary.mjs","names":[],"sources":["../../../../../create-warlock/src/summary.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport { AppOptions } from \"./commands/create-new-app/types\";\nimport { getDatabaseLabel } from \"./features/database-drivers\";\n\n/** What decisions.spec.ts / the terminal actually needs to render the summary. */\nexport type Decisions = {\n packageManager: string;\n options: AppOptions;\n};\n\n/**\n * Print what the scaffolder decided on the user's behalf, and how to change\n * each decision — required because almost every choice is now a default\n * rather than a prompt, so this is the only place a user sees them.\n */\nexport function printDecisionsSummary({\n packageManager,\n options,\n}: Decisions): void {\n const databaseLabel = getDatabaseLabel(options.databaseDriver);\n\n const headline = [\n `Using ${packageManager}`,\n `database: ${databaseLabel}`,\n `agent-kit targets: ${options.agents.join(\", \")}`,\n ].join(\" · \");\n\n console.log();\n console.log(colors.cyan(headline));\n console.log(\n colors.dim(\n \" change these — package manager: --pm, database: --db/--no-db, agents: --agents, \" +\n \"features: --features, ai: --ai, git: --git/--no-git, jwt: --jwt/--no-jwt — \" +\n \"or re-run with --interactive for the full wizard. Package-manager-level choices \" +\n \"(husky, lint config, etc.) can also be edited directly in the generated project.\",\n ),\n );\n console.log();\n}\n"],"mappings":";;;;;;;;;AAeA,SAAgB,sBAAsB,EACpC,gBACA,WACkB;CAClB,MAAM,gBAAgB,iBAAiB,QAAQ,cAAc;CAE7D,MAAM,WAAW;EACf,SAAS;EACT,aAAa;EACb,sBAAsB,QAAQ,OAAO,KAAK,IAAI;CAChD,CAAC,CAAC,KAAK,KAAK;CAEZ,QAAQ,IAAI;CACZ,QAAQ,IAAI,OAAO,KAAK,QAAQ,CAAC;CACjC,QAAQ,IACN,OAAO,IACL,+TAIF,CACF;CACA,QAAQ,IAAI;AACd"}
1
+ {"version":3,"file":"summary.mjs","names":[],"sources":["../../../../../../packages/create-warlock/src/summary.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport { AppOptions } from \"./commands/create-new-app/types\";\nimport { getDatabaseLabel } from \"./features/database-drivers\";\n\n/** What decisions.spec.ts / the terminal actually needs to render the summary. */\nexport type Decisions = {\n packageManager: string;\n options: AppOptions;\n};\n\n/**\n * Print what the scaffolder decided on the user's behalf, and how to change\n * each decision — required because almost every choice is now a default\n * rather than a prompt, so this is the only place a user sees them.\n */\nexport function printDecisionsSummary({\n packageManager,\n options,\n}: Decisions): void {\n const databaseLabel = getDatabaseLabel(options.databaseDriver);\n\n const headline = [\n `Using ${packageManager}`,\n `database: ${databaseLabel}`,\n `agent-kit targets: ${options.agents.join(\", \")}`,\n ].join(\" · \");\n\n console.log();\n console.log(colors.cyan(headline));\n console.log(\n colors.dim(\n \" change these — package manager: --pm, database: --db/--no-db, agents: --agents, \" +\n \"features: --features, ai: --ai, git: --git/--no-git, jwt: --jwt/--no-jwt — \" +\n \"or re-run with --interactive for the full wizard. Package-manager-level choices \" +\n \"(husky, lint config, etc.) can also be edited directly in the generated project.\",\n ),\n );\n console.log();\n}\n"],"mappings":";;;;;;;;;AAeA,SAAgB,sBAAsB,EACpC,gBACA,WACkB;CAClB,MAAM,gBAAgB,iBAAiB,QAAQ,cAAc;CAE7D,MAAM,WAAW;EACf,SAAS;EACT,aAAa;EACb,sBAAsB,QAAQ,OAAO,KAAK,IAAI;CAChD,CAAC,CAAC,KAAK,KAAK;CAEZ,QAAQ,IAAI;CACZ,QAAQ,IAAI,OAAO,KAAK,QAAQ,CAAC;CACjC,QAAQ,IACN,OAAO,IACL,+TAIF,CACF;CACA,QAAQ,IAAI;AACd"}
package/esm/ui/banner.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { colors } from "@mongez/copper";
2
2
 
3
- //#region ../create-warlock/src/ui/banner.ts
3
+ //#region ../../packages/create-warlock/src/ui/banner.ts
4
4
  const warlockTextAnsi = `
5
5
  \x1b[49m
6
6
  \x1b[49m \x1b[38;2;252;238;36m██╗ ██╗ █████╗ ██████╗ ██╗ ██████╗ ██████╗██╗ ██╗ \x1b[38;2;252;238;36m ██╗ ███████╗\x1b[m
@@ -1 +1 @@
1
- {"version":3,"file":"banner.mjs","names":[],"sources":["../../../../../../create-warlock/src/ui/banner.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\n\nexport const warlockTextAnsi = `\n\\x1b[49m\n\\x1b[49m \\x1b[38;2;252;238;36m██╗ ██╗ █████╗ ██████╗ ██╗ ██████╗ ██████╗██╗ ██╗ \\x1b[38;2;252;238;36m ██╗ ███████╗\\x1b[m\n\\x1b[49m \\x1b[38;2;250;235;34m██║ ██║██╔══██╗██╔══██╗██║ ██╔═══██╗██╔════╝██║ ██╔╝ \\x1b[38;2;250;235;34m ██║ ██╔════╝\\x1b[m\n\\x1b[49m \\x1b[38;2;248;233;32m██║ █╗ ██║███████║██████╔╝██║ ██║ ██║██║ █████╔╝ \\x1b[38;2;248;233;32m ██║ ███████╗\\x1b[m\n\\x1b[49m \\x1b[38;2;246;231;30m██║███╗██║██╔══██║██╔══██╗██║ ██║ ██║██║ ██╔═██╗ \\x1b[38;2;246;231;30m██ ██║ ╚════██║\\x1b[m\n\\x1b[49m \\x1b[38;2;244;229;28m╚███╔███╔╝██║ ██║██║ ██║███████╗╚██████╔╝╚██████╗██║ ██╗ \\x1b[38;2;244;229;28m╚█████╔╝ ███████║\\x1b[m\n\\x1b[49m \\x1b[38;2;242;227;26m ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝ \\x1b[38;2;242;227;26m ╚════╝ ╚══════╝\\x1b[m\n\\x1b[49m\n`;\n\nexport const warlockLogoAnsi = `\\x1b[49m \\x1b[38;2;247;232;77;49m▄\\x1b[38;2;235;228;105;49m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;247;241;62;49m▄\\x1b[38;2;251;243;29;48;2;245;240;69m▄\\x1b[38;2;224;224;112;48;2;246;238;52m▄\\x1b[49m \\x1b[38;2;246;240;65;49m▄\\x1b[38;2;252;238;32;48;2;250;237;68m▄\\x1b[38;2;246;236;76;48;2;246;237;52m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;245;234;80;49m▄\\x1b[38;2;246;238;58;49m▄\\x1b[49m \\x1b[49;38;2;240;232;72m▀\\x1b[49;38;2;237;237;100m▀\\x1b[49m \\x1b[38;2;236;236;132;49m▄\\x1b[38;2;253;244;30;48;2;255;235;78m▄\\x1b[38;2;254;233;21;48;2;247;240;49m▄\\x1b[38;2;249;206;52;48;2;253;234;25m▄\\x1b[49;38;2;246;212;65m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;246;233;50;49m▄\\x1b[38;2;250;235;26;48;2;237;228;118m▄\\x1b[38;2;251;232;21;48;2;249;237;38m▄\\x1b[38;2;249;231;20;48;2;251;234;21m▄\\x1b[38;2;248;230;21;48;2;252;232;20m▄\\x1b[38;2;248;230;21;48;2;248;233;25m▄\\x1b[38;2;248;231;22;48;2;245;236;68m▄\\x1b[38;2;247;233;32;49m▄\\x1b[38;2;242;226;87;49m▄\\x1b[49m \\x1b[38;2;227;227;99;49m▄\\x1b[38;2;250;235;43;49m▄\\x1b[38;2;253;235;28;48;2;244;233;69m▄\\x1b[38;2;254;226;25;48;2;252;237;25m▄\\x1b[38;2;253;199;25;48;2;253;229;24m▄\\x1b[38;2;247;205;73;48;2;253;201;27m▄\\x1b[49;38;2;235;206;88m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;239;226;86;49m▄\\x1b[38;2;250;235;34;49m▄\\x1b[38;2;252;234;19;48;2;243;231;71m▄\\x1b[38;2;251;233;19;48;2;251;234;28m▄\\x1b[38;2;250;233;19;48;2;251;233;20m▄\\x1b[38;2;251;233;20;48;2;250;232;20m▄\\x1b[38;2;253;235;25;48;2;251;231;20m▄\\x1b[38;2;245;232;53;48;2;251;232;20m▄\\x1b[38;2;245;228;57;48;2;250;232;22m▄\\x1b[38;2;247;229;39;48;2;248;231;22m▄\\x1b[38;2;247;232;22;48;2;248;229;21m▄\\x1b[38;2;247;231;21;48;2;248;229;20m▄\\x1b[38;2;247;230;20;48;2;247;230;22m▄\\x1b[38;2;248;230;20;48;2;246;234;38m▄\\x1b[38;2;250;232;28;48;2;239;230;123m▄\\x1b[38;2;250;231;49;49m▄\\x1b[38;2;235;216;78;49m▄\\x1b[49m \\x1b[38;2;246;235;53;49m▄\\x1b[38;2;251;236;23;48;2;244;232;75m▄\\x1b[38;2;252;233;21;48;2;252;236;27m▄\\x1b[38;2;253;227;26;48;2;253;233;23m▄\\x1b[38;2;253;201;29;48;2;253;228;30m▄\\x1b[38;2;253;199;27;48;2;253;201;26m▄\\x1b[38;2;232;197;104;48;2;249;201;47m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;247;232;50;49m▄\\x1b[38;2;250;233;28;48;2;245;226;98m▄\\x1b[38;2;252;232;20;48;2;249;234;40m▄\\x1b[38;2;251;231;20;48;2;253;236;23m▄\\x1b[38;2;251;232;20;48;2;252;233;19m▄\\x1b[38;2;252;234;22;48;2;250;233;19m▄\\x1b[38;2;250;235;38;48;2;251;233;20m▄\\x1b[38;2;241;231;68;48;2;252;235;24m▄\\x1b[49;38;2;249;234;47m▀\\x1b[49;38;2;242;229;78m▀\\x1b[49m \\x1b[49;38;2;247;229;54m▀\\x1b[38;2;241;227;99;48;2;247;231;33m▄\\x1b[38;2;248;233;50;48;2;247;232;22m▄\\x1b[38;2;250;229;28;48;2;249;230;22m▄\\x1b[38;2;254;226;26;48;2;253;224;23m▄\\x1b[38;2;235;221;94;48;2;249;221;35m▄\\x1b[49m \\x1b[38;2;243;237;61;49m▄\\x1b[38;2;251;237;28;48;2;243;236;87m▄\\x1b[38;2;251;234;20;48;2;250;236;36m▄\\x1b[38;2;252;232;21;48;2;252;234;21m▄\\x1b[38;2;251;225;23;48;2;251;232;21m▄\\x1b[38;2;250;198;26;48;2;251;225;24m▄\\x1b[38;2;253;197;26;48;2;251;199;27m▄\\x1b[38;2;252;200;38;48;2;255;199;28m▄\\x1b[49;38;2;245;202;65m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;244;235;52;48;2;219;219;128m▄\\x1b[38;2;247;234;53;49m▄\\x1b[38;2;235;216;118;49m▄\\x1b[49m \\x1b[38;2;246;236;50;49m▄\\x1b[38;2;253;238;21;48;2;249;234;58m▄\\x1b[38;2;251;234;20;48;2;250;236;33m▄\\x1b[38;2;251;233;19;48;2;252;234;21m▄\\x1b[38;2;252;233;21;48;2;251;232;19m▄\\x1b[38;2;252;233;26;48;2;251;231;20m▄\\x1b[38;2;249;233;43;48;2;253;233;21m▄\\x1b[49;38;2;252;236;30m▀\\x1b[49;38;2;246;236;57m▀\\x1b[49m \\x1b[38;2;242;235;87;49m▄\\x1b[49m \\x1b[49;38;2;246;229;106m▀\\x1b[49;38;2;247;227;62m▀\\x1b[49m \\x1b[49;38;2;248;237;47m▀\\x1b[38;2;245;232;62;48;2;247;234;35m▄\\x1b[38;2;253;231;26;48;2;252;234;23m▄\\x1b[38;2;253;204;27;48;2;253;226;23m▄\\x1b[38;2;252;199;34;48;2;252;200;26m▄\\x1b[38;2;247;203;52;48;2;253;197;26m▄\\x1b[49;38;2;251;199;35m▀\\x1b[49;38;2;241;207;96m▀\\x1b[49m \\x1b[38;2;246;238;65;49m▄\\x1b[38;2;250;226;39;49m▄\\x1b[38;2;238;221;59;49m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;242;235;52;48;2;248;235;48m▄\\x1b[38;2;251;234;24;48;2;251;234;23m▄\\x1b[38;2;251;232;21;48;2;250;237;38m▄\\x1b[38;2;248;233;20;48;2;244;236;69m▄\\x1b[38;2;246;236;44;49m▄\\x1b[38;2;243;238;64;49m▄\\x1b[49m \\x1b[49;38;2;235;228;87m▀\\x1b[49;38;2;247;231;40m▀\\x1b[38;2;242;230;96;48;2;248;234;24m▄\\x1b[38;2;239;226;78;48;2;252;235;23m▄\\x1b[49;38;2;250;234;35m▀\\x1b[49;38;2;239;233;98m▀\\x1b[49m \\x1b[38;2;252;242;36;48;2;246;243;65m▄\\x1b[38;2;252;240;31;48;2;251;245;46m▄\\x1b[38;2;248;241;106;49m▄\\x1b[49m \\x1b[38;2;241;241;85;49m▄\\x1b[38;2;250;238;34;48;2;244;234;69m▄\\x1b[38;2;246;216;49;48;2;253;234;31m▄\\x1b[38;2;228;215;121;48;2;252;210;33m▄\\x1b[49;38;2;248;205;53m▀\\x1b[49m \\x1b[38;2;238;238;85;49m▄\\x1b[38;2;243;233;63;49m▄\\x1b[38;2;251;237;23;48;2;246;237;79m▄\\x1b[38;2;253;234;22;48;2;247;234;52m▄\\x1b[38;2;253;214;24;48;2;254;233;26m▄\\x1b[38;2;249;210;44;48;2;252;212;31m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[49;38;2;228;228;67m▀\\x1b[38;2;250;235;32;48;2;252;237;25m▄\\x1b[38;2;252;223;25;48;2;250;227;23m▄\\x1b[38;2;250;213;27;48;2;248;230;19m▄\\x1b[38;2;247;224;25;48;2;247;230;19m▄\\x1b[38;2;247;229;19;48;2;246;233;20m▄\\x1b[38;2;248;231;22;48;2;243;234;51m▄\\x1b[38;2;247;233;22;48;2;236;227;76m▄\\x1b[38;2;243;233;67;49m▄\\x1b[49m \\x1b[38;2;250;238;38;48;2;240;235;82m▄\\x1b[38;2;251;235;20;48;2;253;240;20m▄\\x1b[38;2;252;232;22;48;2;253;235;23m▄\\x1b[38;2;252;237;34;48;2;250;242;52m▄\\x1b[49m \\x1b[49;38;2;242;234;57m▀\\x1b[49;38;2;233;233;78m▀\\x1b[49m \\x1b[38;2;244;233;98;49m▄\\x1b[38;2;251;236;35;49m▄\\x1b[38;2;252;236;22;48;2;243;232;72m▄\\x1b[38;2;252;235;25;48;2;252;239;28m▄\\x1b[38;2;251;233;21;48;2;250;234;20m▄\\x1b[38;2;252;220;25;48;2;251;234;21m▄\\x1b[38;2;251;203;25;48;2;253;229;23m▄\\x1b[38;2;253;205;26;48;2;253;206;25m▄\\x1b[38;2;248;209;53;48;2;250;211;51m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[49;38;2;242;230;81m▀\\x1b[49;38;2;249;218;33m▀\\x1b[38;2;242;212;73;48;2;250;214;26m▄\\x1b[38;2;248;210;32;48;2;251;212;26m▄\\x1b[38;2;248;213;26;48;2;249;210;26m▄\\x1b[38;2;251;214;26;48;2;248;228;27m▄\\x1b[38;2;250;214;27;48;2;250;231;20m▄\\x1b[38;2;248;226;24;48;2;248;232;19m▄\\x1b[38;2;247;231;19;48;2;245;234;26m▄\\x1b[38;2;247;232;20;48;2;240;230;78m▄\\x1b[38;2;245;236;35;49m▄\\x1b[38;2;241;234;86;49m▄\\x1b[49m \\x1b[38;2;250;237;45;49m▄\\x1b[38;2;251;234;20;48;2;251;237;25m▄\\x1b[38;2;248;231;21;48;2;249;233;22m▄\\x1b[38;2;247;230;20;48;2;248;231;21m▄\\x1b[38;2;249;230;21;48;2;252;233;22m▄\\x1b[38;2;252;238;35;48;2;249;239;60m▄\\x1b[49m \\x1b[38;2;223;207;143;49m▄\\x1b[38;2;248;232;43;49m▄\\x1b[38;2;250;233;21;48;2;237;219;109m▄\\x1b[38;2;251;232;20;48;2;249;232;44m▄\\x1b[38;2;252;232;21;48;2;251;233;22m▄\\x1b[38;2;252;230;21;48;2;252;233;20m▄\\x1b[38;2;253;215;26;48;2;253;233;20m▄\\x1b[38;2;253;200;29;48;2;253;228;27m▄\\x1b[38;2;254;203;28;48;2;252;203;26m▄\\x1b[38;2;249;207;48;48;2;252;203;26m▄\\x1b[38;2;242;215;74;48;2;253;204;27m▄\\x1b[49;38;2;249;209;50m▀\\x1b[49;38;2;241;213;99m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[49;38;2;243;213;61m▀\\x1b[38;2;231;219;85;48;2;248;216;32m▄\\x1b[38;2;245;214;58;48;2;250;215;26m▄\\x1b[38;2;248;214;32;48;2;252;212;27m▄\\x1b[38;2;250;215;26;48;2;249;217;27m▄\\x1b[38;2;250;215;27;48;2;247;227;23m▄\\x1b[38;2;247;220;28;48;2;246;231;20m▄\\x1b[38;2;246;230;21;48;2;246;234;23m▄\\x1b[38;2;251;235;24;48;2;247;237;45m▄\\x1b[38;2;242;237;101;49m▄\\x1b[49m \\x1b[38;2;248;239;63;49m▄\\x1b[38;2;252;235;20;48;2;252;237;26m▄\\x1b[48;2;249;232;20m \\x1b[38;2;250;231;22;48;2;247;230;20m▄\\x1b[38;2;248;232;34;48;2;247;230;21m▄\\x1b[38;2;248;232;22;48;2;248;231;21m▄\\x1b[38;2;249;233;21;48;2;253;235;25m▄\\x1b[38;2;251;240;38;48;2;246;241;79m▄\\x1b[49m \\x1b[38;2;252;237;26;48;2;244;236;59m▄\\x1b[38;2;252;233;20;48;2;250;233;23m▄\\x1b[48;2;251;232;20m \\x1b[38;2;252;230;22;48;2;251;231;20m▄\\x1b[38;2;253;214;24;48;2;251;231;20m▄\\x1b[38;2;253;200;28;48;2;252;225;22m▄\\x1b[38;2;250;203;41;48;2;252;203;26m▄\\x1b[38;2;248;205;64;48;2;253;198;28m▄\\x1b[49;38;2;249;202;46m▀\\x1b[49;38;2;246;207;62m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[49;38;2;245;216;88m▀\\x1b[49;38;2;246;216;52m▀\\x1b[38;2;242;216;78;48;2;248;216;31m▄\\x1b[38;2;249;217;38;48;2;250;215;27m▄\\x1b[38;2;250;222;30;48;2;247;227;26m▄\\x1b[48;2;248;232;23m \\x1b[38;2;252;237;28;48;2;251;241;41m▄\\x1b[38;2;238;238;119;49m▄\\x1b[49m \\x1b[38;2;243;235;85;49m▄\\x1b[38;2;252;238;21;48;2;252;240;29m▄\\x1b[38;2;252;234;23;48;2;251;234;22m▄\\x1b[38;2;254;234;22;48;2;252;233;22m▄\\x1b[38;2;248;227;59;48;2;251;232;38m▄\\x1b[38;2;244;234;96;48;2;248;235;51m▄\\x1b[38;2;251;238;32;48;2;249;235;24m▄\\x1b[38;2;250;236;23;48;2;249;234;21m▄\\x1b[38;2;252;234;22;48;2;253;236;25m▄\\x1b[38;2;251;244;44;48;2;246;246;103m▄\\x1b[49m \\x1b[38;2;251;240;33;48;2;238;232;81m▄\\x1b[38;2;249;233;21;48;2;251;236;19m▄\\x1b[38;2;253;227;24;48;2;252;231;21m▄\\x1b[38;2;254;204;26;48;2;252;224;23m▄\\x1b[38;2;248;206;55;48;2;253;206;27m▄\\x1b[49;38;2;250;204;40m▀\\x1b[49;38;2;246;207;60m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;246;215;54;48;2;242;211;53m▄\\x1b[38;2;253;217;20;48;2;248;216;35m▄\\x1b[38;2;250;221;23;48;2;246;219;57m▄\\x1b[38;2;245;232;39;49m▄\\x1b[38;2;245;234;65;49m▄\\x1b[49m \\x1b[38;2;243;219;121;48;2;250;221;50m▄\\x1b[38;2;252;221;33;48;2;251;222;30m▄\\x1b[38;2;250;228;31;48;2;248;231;26m▄\\x1b[38;2;249;232;23;48;2;251;234;23m▄\\x1b[38;2;253;238;29;48;2;249;242;63m▄\\x1b[49m \\x1b[38;2;235;235;112;49m▄\\x1b[38;2;251;236;21;48;2;251;240;34m▄\\x1b[38;2;250;232;23;48;2;251;234;21m▄\\x1b[38;2;253;230;24;48;2;252;233;23m▄\\x1b[38;2;250;222;52;48;2;251;227;36m▄\\x1b[49m \\x1b[38;2;248;241;69;48;2;248;238;48m▄\\x1b[38;2;251;239;28;48;2;250;238;25m▄\\x1b[38;2;250;236;24;48;2;251;235;23m▄\\x1b[38;2;252;234;23;48;2;252;238;26m▄\\x1b[38;2;248;240;59;48;2;239;239;128m▄\\x1b[49m \\x1b[38;2;247;239;52;48;2;244;233;100m▄\\x1b[38;2;249;234;20;48;2;252;238;23m▄\\x1b[38;2;252;231;22;48;2;250;232;22m▄\\x1b[38;2;253;207;25;48;2;253;216;26m▄\\x1b[38;2;250;208;54;48;2;252;207;37m▄\\x1b[49m \\x1b[38;2;241;227;71;49m▄\\x1b[38;2;247;213;44;49m▄\\x1b[38;2;253;208;29;48;2;237;211;88m▄\\x1b[38;2;254;205;28;48;2;248;213;47m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;245;230;60;48;2;242;224;49m▄\\x1b[38;2;249;236;23;48;2;249;233;21m▄\\x1b[38;2;252;235;26;48;2;250;231;20m▄\\x1b[38;2;249;234;30;48;2;249;233;21m▄\\x1b[38;2;254;236;27;48;2;252;236;25m▄\\x1b[38;2;249;238;49;48;2;247;241;52m▄\\x1b[49m \\x1b[38;2;245;216;64;48;2;250;222;59m▄\\x1b[38;2;252;220;31;48;2;252;223;33m▄\\x1b[38;2;249;229;27;48;2;248;231;24m▄\\x1b[38;2;248;230;21;48;2;251;233;22m▄\\x1b[38;2;248;235;29;48;2;242;235;85m▄\\x1b[38;2;251;235;24;48;2;250;242;49m▄\\x1b[38;2;250;231;23;48;2;250;233;22m▄\\x1b[38;2;253;225;23;48;2;252;230;24m▄\\x1b[38;2;250;215;49;48;2;253;222;28m▄\\x1b[49;38;2;244;222;89m▀\\x1b[49m \\x1b[38;2;247;234;63;48;2;248;238;46m▄\\x1b[38;2;251;238;25;48;2;250;237;25m▄\\x1b[38;2;250;233;22;48;2;250;234;21m▄\\x1b[38;2;251;233;21;48;2;252;237;26m▄\\x1b[38;2;244;232;62;49m▄\\x1b[38;2;249;232;21;48;2;252;239;24m▄\\x1b[38;2;250;231;22;48;2;249;231;22m▄\\x1b[38;2;252;212;25;48;2;252;225;23m▄\\x1b[38;2;251;209;55;48;2;253;204;27m▄\\x1b[49;38;2;239;206;99m▀\\x1b[49m \\x1b[38;2;250;237;49;48;2;250;242;50m▄\\x1b[38;2;251;234;22;48;2;252;231;25m▄\\x1b[38;2;253;227;27;48;2;253;212;26m▄\\x1b[38;2;254;206;26;48;2;254;204;25m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;253;239;29;48;2;238;230;84m▄\\x1b[38;2;254;234;24;48;2;253;238;23m▄\\x1b[38;2;253;209;29;48;2;254;233;26m▄\\x1b[38;2;244;216;71;48;2;241;220;99m▄\\x1b[49m \\x1b[38;2;247;217;53;48;2;250;218;44m▄\\x1b[38;2;251;217;31;48;2;250;222;31m▄\\x1b[38;2;247;228;24;48;2;245;229;20m▄\\x1b[48;2;245;229;19m \\x1b[38;2;246;229;19;48;2;247;229;20m▄\\x1b[38;2;253;224;24;48;2;251;229;23m▄\\x1b[38;2;249;211;52;48;2;253;213;27m▄\\x1b[49;38;2;244;210;68m▀\\x1b[49m \\x1b[38;2;249;234;57;48;2;249;237;39m▄\\x1b[38;2;250;235;23;48;2;250;234;24m▄\\x1b[38;2;247;231;19;48;2;247;230;19m▄\\x1b[38;2;244;229;16;48;2;247;230;18m▄\\x1b[38;2;246;229;18;48;2;246;230;19m▄\\x1b[38;2;253;223;23;48;2;252;228;21m▄\\x1b[38;2;253;206;37;48;2;253;208;26m▄\\x1b[49;38;2;251;211;57m▀\\x1b[49m \\x1b[38;2;250;239;47;48;2;250;239;50m▄\\x1b[38;2;250;236;23;48;2;249;235;22m▄\\x1b[38;2;254;231;28;48;2;254;229;26m▄\\x1b[38;2;255;209;26;48;2;254;209;27m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;245;239;70;49m▄\\x1b[38;2;253;241;21;48;2;250;243;39m▄\\x1b[38;2;251;208;32;48;2;254;237;23m▄\\x1b[38;2;248;210;82;48;2;252;208;31m▄\\x1b[49;38;2;245;213;78m▀\\x1b[49m \\x1b[38;2;246;218;70;48;2;252;217;33m▄\\x1b[38;2;250;220;29;48;2;248;225;27m▄\\x1b[38;2;248;229;24;48;2;245;229;20m▄\\x1b[38;2;253;223;23;48;2;251;228;21m▄\\x1b[38;2;252;209;33;48;2;253;211;26m▄\\x1b[49;38;2;242;208;64m▀\\x1b[49m \\x1b[49;38;2;237;237;91m▀\\x1b[38;2;246;235;64;48;2;251;237;29m▄\\x1b[38;2;248;237;24;48;2;248;233;23m▄\\x1b[38;2;247;233;21;48;2;245;231;18m▄\\x1b[38;2;253;230;23;48;2;249;230;19m▄\\x1b[38;2;253;206;30;48;2;253;209;24m▄\\x1b[38;2;239;223;96;48;2;249;207;58m▄\\x1b[49m \\x1b[38;2;247;239;50;48;2;247;239;47m▄\\x1b[38;2;249;236;23;48;2;250;236;23m▄\\x1b[48;2;254;230;27m \\x1b[38;2;254;209;27;48;2;254;209;26m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;235;235;78;49m▄\\x1b[38;2;253;240;32;48;2;234;234;90m▄\\x1b[38;2;249;224;34;48;2;253;242;25m▄\\x1b[38;2;245;214;92;48;2;251;215;32m▄\\x1b[49;38;2;240;209;85m▀\\x1b[49m \\x1b[38;2;245;235;64;49m▄\\x1b[38;2;253;239;32;48;2;239;231;112m▄\\x1b[38;2;246;239;82;49m▄\\x1b[49m \\x1b[49;38;2;246;219;73m▀\\x1b[38;2;249;221;48;48;2;252;220;29m▄\\x1b[38;2;254;222;27;48;2;253;228;27m▄\\x1b[38;2;253;208;28;48;2;254;210;24m▄\\x1b[38;2;237;219;73;48;2;244;208;63m▄\\x1b[49m \\x1b[38;2;249;236;42;49m▄\\x1b[38;2;250;234;23;49m▄\\x1b[38;2;249;231;24;49m▄\\x1b[38;2;248;228;34;49m▄\\x1b[38;2;243;226;99;49m▄\\x1b[49m \\x1b[49;38;2;242;242;67m▀\\x1b[38;2;248;238;57;48;2;252;238;26m▄\\x1b[38;2;253;236;26;48;2;251;235;23m▄\\x1b[38;2;253;213;26;48;2;253;227;24m▄\\x1b[38;2;247;209;62;48;2;247;209;61m▄\\x1b[49m \\x1b[38;2;247;239;49;48;2;247;239;47m▄\\x1b[38;2;250;234;23;48;2;250;235;22m▄\\x1b[38;2;254;228;28;48;2;254;230;28m▄\\x1b[38;2;254;207;26;48;2;254;208;26m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;246;237;59;49m▄\\x1b[38;2;249;236;35;48;2;249;240;43m▄\\x1b[49;38;2;249;233;39m▀\\x1b[49;38;2;237;219;109m▀\\x1b[49m \\x1b[38;2;239;234;80;49m▄\\x1b[38;2;251;241;38;49m▄\\x1b[38;2;252;239;32;48;2;252;242;48m▄\\x1b[38;2;249;237;37;48;2;253;239;24m▄\\x1b[38;2;245;233;57;48;2;254;236;21m▄\\x1b[38;2;237;237;128;48;2;251;239;47m▄\\x1b[49m \\x1b[49;38;2;244;221;68m▀\\x1b[38;2;252;216;33;48;2;254;216;24m▄\\x1b[38;2;244;211;78;48;2;245;211;57m▄\\x1b[49m \\x1b[38;2;250;238;31;48;2;250;239;49m▄\\x1b[38;2;249;233;20;48;2;251;235;20m▄\\x1b[38;2;246;232;19;48;2;249;232;19m▄\\x1b[38;2;246;231;19;48;2;248;231;19m▄\\x1b[38;2;251;232;21;48;2;251;230;20m▄\\x1b[38;2;253;217;25;48;2;250;222;34m▄\\x1b[38;2;243;225;103;49m▄\\x1b[49m \\x1b[49;38;2;238;230;85m▀\\x1b[38;2;251;237;40;48;2;253;238;27m▄\\x1b[38;2;237;219;83;48;2;250;212;43m▄\\x1b[49m \\x1b[38;2;248;238;53;49m▄\\x1b[38;2;252;234;34;48;2;250;237;49m▄\\x1b[38;2;253;220;26;48;2;252;233;23m▄\\x1b[38;2;252;202;28;48;2;253;225;29m▄\\x1b[38;2;254;204;26;48;2;254;205;26m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;240;229;56;48;2;247;232;62m▄\\x1b[49;38;2;249;238;37m▀\\x1b[49m \\x1b[49;38;2;231;231;110m▀\\x1b[49;38;2;244;241;45m▀\\x1b[49;38;2;239;239;63m▀\\x1b[49m \\x1b[49;38;2;241;217;88m▀\\x1b[49m \\x1b[38;2;249;236;52;48;2;249;237;33m▄\\x1b[38;2;250;237;24;48;2;248;234;22m▄\\x1b[38;2;250;234;21;48;2;246;233;19m▄\\x1b[38;2;251;230;21;48;2;247;233;19m▄\\x1b[38;2;253;210;26;48;2;252;230;22m▄\\x1b[38;2;251;207;36;48;2;253;209;27m▄\\x1b[49;38;2;243;219;95m▀\\x1b[49m \\x1b[49;38;2;241;223;96m▀\\x1b[49m \\x1b[38;2;242;233;67;49m▄\\x1b[38;2;249;236;41;49m▄\\x1b[38;2;253;237;23;48;2;245;232;63m▄\\x1b[38;2;253;226;24;48;2;251;238;38m▄\\x1b[38;2;251;201;26;48;2;252;234;23m▄\\x1b[38;2;251;198;26;48;2;251;210;25m▄\\x1b[38;2;253;202;29;48;2;251;199;25m▄\\x1b[38;2;251;203;42;48;2;253;201;28m▄\\x1b[38;2;229;211;123;48;2;253;203;32m▄\\x1b[49m \\x1b[m\n\\x1b[38;2;222;222;144;49m▄\\x1b[38;2;229;220;123;48;2;234;225;98m▄\\x1b[49;38;2;228;215;121m▀\\x1b[49m \\x1b[38;2;248;236;46;49m▄\\x1b[38;2;252;236;21;48;2;243;230;66m▄\\x1b[38;2;251;233;20;48;2;249;234;38m▄\\x1b[38;2;251;231;20;48;2;248;234;33m▄\\x1b[38;2;248;231;20;48;2;244;229;67m▄\\x1b[38;2;244;233;47;49m▄\\x1b[38;2;236;236;70;49m▄\\x1b[49m \\x1b[49;38;2;247;212;46m▀\\x1b[49;38;2;250;209;30m▀\\x1b[38;2;240;225;150;48;2;251;202;30m▄\\x1b[49;38;2;252;203;36m▀\\x1b[49;38;2;241;212;90m▀\\x1b[49m \\x1b[38;2;235;235;98;49m▄\\x1b[38;2;243;235;63;49m▄\\x1b[38;2;251;238;25;48;2;237;228;73m▄\\x1b[38;2;253;236;20;48;2;247;234;52m▄\\x1b[38;2;254;230;22;48;2;252;238;23m▄\\x1b[38;2;252;206;26;48;2;253;233;21m▄\\x1b[38;2;253;198;28;48;2;252;217;25m▄\\x1b[38;2;252;201;36;48;2;252;196;26m▄\\x1b[38;2;240;205;70;48;2;252;199;28m▄\\x1b[49;38;2;250;202;38m▀\\x1b[49;38;2;241;213;88m▀\\x1b[49m \\x1b[m\n\\x1b[49;38;2;207;207;191m▀\\x1b[49m \\x1b[38;2;236;232;82;49m▄\\x1b[38;2;248;239;48;49m▄\\x1b[49m \\x1b[49;38;2;244;231;69m▀\\x1b[49;38;2;249;233;29m▀\\x1b[38;2;244;228;69;48;2;248;234;23m▄\\x1b[38;2;249;233;28;48;2;247;231;21m▄\\x1b[38;2;247;232;25;48;2;247;230;20m▄\\x1b[38;2;248;231;23;48;2;248;231;19m▄\\x1b[38;2;249;232;23;48;2;247;233;20m▄\\x1b[38;2;249;233;24;48;2;246;237;59m▄\\x1b[38;2;248;237;29;48;2;242;242;77m▄\\x1b[38;2;244;240;76;49m▄\\x1b[49m \\x1b[38;2;241;234;99;49m▄\\x1b[38;2;250;238;41;49m▄\\x1b[38;2;253;237;26;48;2;242;232;79m▄\\x1b[38;2;253;236;25;48;2;252;240;27m▄\\x1b[38;2;254;233;24;48;2;254;236;20m▄\\x1b[38;2;251;210;29;48;2;253;235;21m▄\\x1b[38;2;251;197;28;48;2;253;225;23m▄\\x1b[38;2;246;202;53;48;2;254;200;27m▄\\x1b[49;38;2;253;199;32m▀\\x1b[49;38;2;245;207;64m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[49;38;2;231;219;97m▀\\x1b[49;38;2;243;229;58m▀\\x1b[49m \\x1b[49;38;2;237;237;91m▀\\x1b[49;38;2;246;231;56m▀\\x1b[38;2;246;238;68;48;2;246;233;22m▄\\x1b[38;2;245;230;48;48;2;246;233;21m▄\\x1b[38;2;247;235;23;48;2;247;232;19m▄\\x1b[38;2;246;233;21;48;2;247;232;18m▄\\x1b[38;2;247;232;20;48;2;248;232;18m▄\\x1b[38;2;247;231;19;48;2;246;234;29m▄\\x1b[38;2;247;232;20;48;2;240;230;80m▄\\x1b[38;2;246;233;34;49m▄\\x1b[38;2;245;231;52;49m▄\\x1b[38;2;250;233;23;48;2;225;225;105m▄\\x1b[38;2;252;233;19;48;2;248;234;46m▄\\x1b[38;2;253;233;20;48;2;253;235;21m▄\\x1b[38;2;254;232;21;48;2;253;234;20m▄\\x1b[38;2;252;217;24;48;2;254;234;20m▄\\x1b[38;2;253;202;35;48;2;254;230;23m▄\\x1b[38;2;246;211;84;48;2;253;201;28m▄\\x1b[49;38;2;250;203;46m▀\\x1b[49;38;2;247;206;82m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[49;38;2;247;226;63m▀\\x1b[49;38;2;247;232;36m▀\\x1b[38;2;245;229;57;48;2;246;232;22m▄\\x1b[38;2;247;230;31;48;2;248;232;21m▄\\x1b[38;2;247;232;21;48;2;247;231;19m▄\\x1b[38;2;247;233;19;48;2;246;231;18m▄\\x1b[38;2;247;232;17;48;2;246;231;17m▄\\x1b[38;2;251;232;19;48;2;249;232;17m▄\\x1b[38;2;253;221;24;48;2;252;232;20m▄\\x1b[38;2;249;207;48;48;2;253;229;22m▄\\x1b[38;2;248;209;72;48;2;253;207;28m▄\\x1b[49;38;2;245;202;59m▀\\x1b[49;38;2;237;200;109m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[49;38;2;242;230;89m▀\\x1b[49;38;2;247;232;50m▀\\x1b[38;2;244;227;72;48;2;249;233;28m▄\\x1b[38;2;244;218;55;48;2;252;231;23m▄\\x1b[49;38;2;250;215;37m▀\\x1b[49;38;2;244;206;65m▀\\x1b[49m \\x1b[m\n`;\n\n/**\n * Get the intro banner with ASCII art\n */\nexport function getIntroBanner(version: string): string {\n const versionLine = `v${version}`;\n const totalWidth = 38; // Total width inside the box\n const padding = \" \".repeat(totalWidth - 3 - versionLine.length); // 3 is for leading spaces \" \"\n\n return `\n ${colors.magentaBright(\"╭──────────────────────────────────────╮\")}\n ${colors.magentaBright(\"│\")} ${colors.magentaBright(\"│\")}\n ${colors.magentaBright(\"│\")} 🧙 ${colors.bold(colors.yellowBright(\"WARLOCK.JS\"))} ${colors.magentaBright(\"│\")}\n ${colors.magentaBright(\"│\")} ${colors.cyan(\"The Magical Node.js Framework\")} ${colors.magentaBright(\"│\")}\n ${colors.magentaBright(\"│\")} ${colors.magentaBright(\"│\")}\n ${colors.magentaBright(\"│\")} ${colors.green(versionLine)}${padding}${colors.magentaBright(\"│\")}\n ${colors.magentaBright(\"│\")} ${colors.magentaBright(\"│\")}\n ${colors.magentaBright(\"╰──────────────────────────────────────╯\")}\n`;\n}\n\n/**\n * Display the intro banner\n */\nexport function showIntroBanner(version: string): void {\n console.log(warlockLogoAnsi);\n console.log(warlockTextAnsi);\n console.log(getIntroBanner(version));\n}\n\n/**\n * Get the success screen with project summary\n */\nexport function getSuccessScreen(options: {\n projectName: string;\n database: string;\n features: string[];\n packageManager: string;\n}): string {\n const { projectName, database, features, packageManager } = options;\n\n // Format features text\n let featuresText = features.join(\", \");\n if (features.length === 0) {\n featuresText = \"none\";\n }\n\n // Calculate dynamic width\n const baseLabelLength = 10; // \"Project: \".length\n const padding = 6; // 3 spaces left, 3 spaces right padding for text inside box\n\n const projectLineLen = projectName.length + baseLabelLength;\n const dbLineLen = database.length + baseLabelLength;\n const featuresLineLen = featuresText.length + baseLabelLength;\n\n // Find the longest line to determine box width\n // Ensure minimum width of 50 for aesthetics\n const maxContentLength = Math.max(\n projectLineLen,\n dbLineLen,\n featuresLineLen,\n 40,\n );\n const boxWidth = maxContentLength + padding + 2; // +2 for borders │\n\n // Helper to generate borders\n const createBorder = (start: string, end: string) =>\n colors.magentaBright(start + \"─\".repeat(boxWidth - 2) + end);\n\n // Helper to pad content lines\n const padLine = (label: string, value: string, isFeature = false) => {\n const valueColor = (text: string) => {\n if (isFeature && text === \"none\") return colors.dim(text);\n return colors.white(text);\n };\n\n const labelPart = colors.dim(label.padEnd(10)); // \"Project: \"\n const valuePart = valueColor(value);\n\n // Calculate visible length for padding\n const contentVisibleLength = 3 + 10 + value.length;\n const remaining = boxWidth - 2 - contentVisibleLength; // -2 for borders\n\n return (\n colors.magentaBright(\"│\") +\n \" \" +\n labelPart +\n valuePart +\n \" \".repeat(remaining) +\n colors.magentaBright(\"│\")\n );\n };\n\n const emptyLine =\n colors.magentaBright(\"│\") +\n \" \".repeat(boxWidth - 2) +\n colors.magentaBright(\"│\");\n\n const headerText = \"🎉 YOUR PROJECT IS READY! 🎉\";\n const headerPadding = Math.floor((boxWidth - 2 - headerText.length) / 2);\n const headerLine =\n colors.magentaBright(\"│\") +\n \" \".repeat(headerPadding) +\n colors.bold(colors.green(headerText)) +\n \" \".repeat(boxWidth - 2 - headerPadding - headerText.length) +\n colors.magentaBright(\"│\");\n\n const devCommand =\n packageManager === \"npm\" ? \"npm run dev\" : `${packageManager} dev`;\n\n return `\n ${createBorder(\"╭\", \"╮\")}\n ${emptyLine}\n ${headerLine}\n ${emptyLine}\n ${padLine(\"Project:\", projectName)}\n ${padLine(\"Database:\", database)}\n ${padLine(\"Features:\", featuresText, true)}\n ${emptyLine}\n ${createBorder(\"╰\", \"╯\")}\n\n ${colors.bold(colors.cyan(\"🚀 Next steps:\"))}\n\n ${colors.cyan(\"cd\")} ${projectName}\n ${colors.cyan(devCommand)}\n\n ${colors.dim(\"💡 Pro tip: Install the\")} ${colors.yellow(\"Generator Z\")} ${colors.dim(\"extension in VSCode\")}\n ${colors.dim(\"for helpful code snippets and productivity boosters!\")}\n\n ${colors.dim(\"📚 Docs:\")} ${colors.cyan(\"https://warlock.js.org\")}\n ${colors.dim(\"⭐ Star us:\")} ${colors.cyan(\"https://github.com/warlockjs/framework\")}\n`;\n}\n\n/**\n * Display the success screen\n */\nexport function showSuccessScreen(options: {\n projectName: string;\n database: string;\n features: string[];\n packageManager: string;\n}): void {\n console.log(getSuccessScreen(options));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"banner.mjs","names":[],"sources":["../../../../../../../packages/create-warlock/src/ui/banner.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\n\nexport const warlockTextAnsi = `\n\\x1b[49m\n\\x1b[49m \\x1b[38;2;252;238;36m██╗ ██╗ █████╗ ██████╗ ██╗ ██████╗ ██████╗██╗ ██╗ \\x1b[38;2;252;238;36m ██╗ ███████╗\\x1b[m\n\\x1b[49m \\x1b[38;2;250;235;34m██║ ██║██╔══██╗██╔══██╗██║ ██╔═══██╗██╔════╝██║ ██╔╝ \\x1b[38;2;250;235;34m ██║ ██╔════╝\\x1b[m\n\\x1b[49m \\x1b[38;2;248;233;32m██║ █╗ ██║███████║██████╔╝██║ ██║ ██║██║ █████╔╝ \\x1b[38;2;248;233;32m ██║ ███████╗\\x1b[m\n\\x1b[49m \\x1b[38;2;246;231;30m██║███╗██║██╔══██║██╔══██╗██║ ██║ ██║██║ ██╔═██╗ \\x1b[38;2;246;231;30m██ ██║ ╚════██║\\x1b[m\n\\x1b[49m \\x1b[38;2;244;229;28m╚███╔███╔╝██║ ██║██║ ██║███████╗╚██████╔╝╚██████╗██║ ██╗ \\x1b[38;2;244;229;28m╚█████╔╝ ███████║\\x1b[m\n\\x1b[49m \\x1b[38;2;242;227;26m ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝ \\x1b[38;2;242;227;26m ╚════╝ ╚══════╝\\x1b[m\n\\x1b[49m\n`;\n\nexport const warlockLogoAnsi = `\\x1b[49m \\x1b[38;2;247;232;77;49m▄\\x1b[38;2;235;228;105;49m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;247;241;62;49m▄\\x1b[38;2;251;243;29;48;2;245;240;69m▄\\x1b[38;2;224;224;112;48;2;246;238;52m▄\\x1b[49m \\x1b[38;2;246;240;65;49m▄\\x1b[38;2;252;238;32;48;2;250;237;68m▄\\x1b[38;2;246;236;76;48;2;246;237;52m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;245;234;80;49m▄\\x1b[38;2;246;238;58;49m▄\\x1b[49m \\x1b[49;38;2;240;232;72m▀\\x1b[49;38;2;237;237;100m▀\\x1b[49m \\x1b[38;2;236;236;132;49m▄\\x1b[38;2;253;244;30;48;2;255;235;78m▄\\x1b[38;2;254;233;21;48;2;247;240;49m▄\\x1b[38;2;249;206;52;48;2;253;234;25m▄\\x1b[49;38;2;246;212;65m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;246;233;50;49m▄\\x1b[38;2;250;235;26;48;2;237;228;118m▄\\x1b[38;2;251;232;21;48;2;249;237;38m▄\\x1b[38;2;249;231;20;48;2;251;234;21m▄\\x1b[38;2;248;230;21;48;2;252;232;20m▄\\x1b[38;2;248;230;21;48;2;248;233;25m▄\\x1b[38;2;248;231;22;48;2;245;236;68m▄\\x1b[38;2;247;233;32;49m▄\\x1b[38;2;242;226;87;49m▄\\x1b[49m \\x1b[38;2;227;227;99;49m▄\\x1b[38;2;250;235;43;49m▄\\x1b[38;2;253;235;28;48;2;244;233;69m▄\\x1b[38;2;254;226;25;48;2;252;237;25m▄\\x1b[38;2;253;199;25;48;2;253;229;24m▄\\x1b[38;2;247;205;73;48;2;253;201;27m▄\\x1b[49;38;2;235;206;88m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;239;226;86;49m▄\\x1b[38;2;250;235;34;49m▄\\x1b[38;2;252;234;19;48;2;243;231;71m▄\\x1b[38;2;251;233;19;48;2;251;234;28m▄\\x1b[38;2;250;233;19;48;2;251;233;20m▄\\x1b[38;2;251;233;20;48;2;250;232;20m▄\\x1b[38;2;253;235;25;48;2;251;231;20m▄\\x1b[38;2;245;232;53;48;2;251;232;20m▄\\x1b[38;2;245;228;57;48;2;250;232;22m▄\\x1b[38;2;247;229;39;48;2;248;231;22m▄\\x1b[38;2;247;232;22;48;2;248;229;21m▄\\x1b[38;2;247;231;21;48;2;248;229;20m▄\\x1b[38;2;247;230;20;48;2;247;230;22m▄\\x1b[38;2;248;230;20;48;2;246;234;38m▄\\x1b[38;2;250;232;28;48;2;239;230;123m▄\\x1b[38;2;250;231;49;49m▄\\x1b[38;2;235;216;78;49m▄\\x1b[49m \\x1b[38;2;246;235;53;49m▄\\x1b[38;2;251;236;23;48;2;244;232;75m▄\\x1b[38;2;252;233;21;48;2;252;236;27m▄\\x1b[38;2;253;227;26;48;2;253;233;23m▄\\x1b[38;2;253;201;29;48;2;253;228;30m▄\\x1b[38;2;253;199;27;48;2;253;201;26m▄\\x1b[38;2;232;197;104;48;2;249;201;47m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;247;232;50;49m▄\\x1b[38;2;250;233;28;48;2;245;226;98m▄\\x1b[38;2;252;232;20;48;2;249;234;40m▄\\x1b[38;2;251;231;20;48;2;253;236;23m▄\\x1b[38;2;251;232;20;48;2;252;233;19m▄\\x1b[38;2;252;234;22;48;2;250;233;19m▄\\x1b[38;2;250;235;38;48;2;251;233;20m▄\\x1b[38;2;241;231;68;48;2;252;235;24m▄\\x1b[49;38;2;249;234;47m▀\\x1b[49;38;2;242;229;78m▀\\x1b[49m \\x1b[49;38;2;247;229;54m▀\\x1b[38;2;241;227;99;48;2;247;231;33m▄\\x1b[38;2;248;233;50;48;2;247;232;22m▄\\x1b[38;2;250;229;28;48;2;249;230;22m▄\\x1b[38;2;254;226;26;48;2;253;224;23m▄\\x1b[38;2;235;221;94;48;2;249;221;35m▄\\x1b[49m \\x1b[38;2;243;237;61;49m▄\\x1b[38;2;251;237;28;48;2;243;236;87m▄\\x1b[38;2;251;234;20;48;2;250;236;36m▄\\x1b[38;2;252;232;21;48;2;252;234;21m▄\\x1b[38;2;251;225;23;48;2;251;232;21m▄\\x1b[38;2;250;198;26;48;2;251;225;24m▄\\x1b[38;2;253;197;26;48;2;251;199;27m▄\\x1b[38;2;252;200;38;48;2;255;199;28m▄\\x1b[49;38;2;245;202;65m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;244;235;52;48;2;219;219;128m▄\\x1b[38;2;247;234;53;49m▄\\x1b[38;2;235;216;118;49m▄\\x1b[49m \\x1b[38;2;246;236;50;49m▄\\x1b[38;2;253;238;21;48;2;249;234;58m▄\\x1b[38;2;251;234;20;48;2;250;236;33m▄\\x1b[38;2;251;233;19;48;2;252;234;21m▄\\x1b[38;2;252;233;21;48;2;251;232;19m▄\\x1b[38;2;252;233;26;48;2;251;231;20m▄\\x1b[38;2;249;233;43;48;2;253;233;21m▄\\x1b[49;38;2;252;236;30m▀\\x1b[49;38;2;246;236;57m▀\\x1b[49m \\x1b[38;2;242;235;87;49m▄\\x1b[49m \\x1b[49;38;2;246;229;106m▀\\x1b[49;38;2;247;227;62m▀\\x1b[49m \\x1b[49;38;2;248;237;47m▀\\x1b[38;2;245;232;62;48;2;247;234;35m▄\\x1b[38;2;253;231;26;48;2;252;234;23m▄\\x1b[38;2;253;204;27;48;2;253;226;23m▄\\x1b[38;2;252;199;34;48;2;252;200;26m▄\\x1b[38;2;247;203;52;48;2;253;197;26m▄\\x1b[49;38;2;251;199;35m▀\\x1b[49;38;2;241;207;96m▀\\x1b[49m \\x1b[38;2;246;238;65;49m▄\\x1b[38;2;250;226;39;49m▄\\x1b[38;2;238;221;59;49m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;242;235;52;48;2;248;235;48m▄\\x1b[38;2;251;234;24;48;2;251;234;23m▄\\x1b[38;2;251;232;21;48;2;250;237;38m▄\\x1b[38;2;248;233;20;48;2;244;236;69m▄\\x1b[38;2;246;236;44;49m▄\\x1b[38;2;243;238;64;49m▄\\x1b[49m \\x1b[49;38;2;235;228;87m▀\\x1b[49;38;2;247;231;40m▀\\x1b[38;2;242;230;96;48;2;248;234;24m▄\\x1b[38;2;239;226;78;48;2;252;235;23m▄\\x1b[49;38;2;250;234;35m▀\\x1b[49;38;2;239;233;98m▀\\x1b[49m \\x1b[38;2;252;242;36;48;2;246;243;65m▄\\x1b[38;2;252;240;31;48;2;251;245;46m▄\\x1b[38;2;248;241;106;49m▄\\x1b[49m \\x1b[38;2;241;241;85;49m▄\\x1b[38;2;250;238;34;48;2;244;234;69m▄\\x1b[38;2;246;216;49;48;2;253;234;31m▄\\x1b[38;2;228;215;121;48;2;252;210;33m▄\\x1b[49;38;2;248;205;53m▀\\x1b[49m \\x1b[38;2;238;238;85;49m▄\\x1b[38;2;243;233;63;49m▄\\x1b[38;2;251;237;23;48;2;246;237;79m▄\\x1b[38;2;253;234;22;48;2;247;234;52m▄\\x1b[38;2;253;214;24;48;2;254;233;26m▄\\x1b[38;2;249;210;44;48;2;252;212;31m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[49;38;2;228;228;67m▀\\x1b[38;2;250;235;32;48;2;252;237;25m▄\\x1b[38;2;252;223;25;48;2;250;227;23m▄\\x1b[38;2;250;213;27;48;2;248;230;19m▄\\x1b[38;2;247;224;25;48;2;247;230;19m▄\\x1b[38;2;247;229;19;48;2;246;233;20m▄\\x1b[38;2;248;231;22;48;2;243;234;51m▄\\x1b[38;2;247;233;22;48;2;236;227;76m▄\\x1b[38;2;243;233;67;49m▄\\x1b[49m \\x1b[38;2;250;238;38;48;2;240;235;82m▄\\x1b[38;2;251;235;20;48;2;253;240;20m▄\\x1b[38;2;252;232;22;48;2;253;235;23m▄\\x1b[38;2;252;237;34;48;2;250;242;52m▄\\x1b[49m \\x1b[49;38;2;242;234;57m▀\\x1b[49;38;2;233;233;78m▀\\x1b[49m \\x1b[38;2;244;233;98;49m▄\\x1b[38;2;251;236;35;49m▄\\x1b[38;2;252;236;22;48;2;243;232;72m▄\\x1b[38;2;252;235;25;48;2;252;239;28m▄\\x1b[38;2;251;233;21;48;2;250;234;20m▄\\x1b[38;2;252;220;25;48;2;251;234;21m▄\\x1b[38;2;251;203;25;48;2;253;229;23m▄\\x1b[38;2;253;205;26;48;2;253;206;25m▄\\x1b[38;2;248;209;53;48;2;250;211;51m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[49;38;2;242;230;81m▀\\x1b[49;38;2;249;218;33m▀\\x1b[38;2;242;212;73;48;2;250;214;26m▄\\x1b[38;2;248;210;32;48;2;251;212;26m▄\\x1b[38;2;248;213;26;48;2;249;210;26m▄\\x1b[38;2;251;214;26;48;2;248;228;27m▄\\x1b[38;2;250;214;27;48;2;250;231;20m▄\\x1b[38;2;248;226;24;48;2;248;232;19m▄\\x1b[38;2;247;231;19;48;2;245;234;26m▄\\x1b[38;2;247;232;20;48;2;240;230;78m▄\\x1b[38;2;245;236;35;49m▄\\x1b[38;2;241;234;86;49m▄\\x1b[49m \\x1b[38;2;250;237;45;49m▄\\x1b[38;2;251;234;20;48;2;251;237;25m▄\\x1b[38;2;248;231;21;48;2;249;233;22m▄\\x1b[38;2;247;230;20;48;2;248;231;21m▄\\x1b[38;2;249;230;21;48;2;252;233;22m▄\\x1b[38;2;252;238;35;48;2;249;239;60m▄\\x1b[49m \\x1b[38;2;223;207;143;49m▄\\x1b[38;2;248;232;43;49m▄\\x1b[38;2;250;233;21;48;2;237;219;109m▄\\x1b[38;2;251;232;20;48;2;249;232;44m▄\\x1b[38;2;252;232;21;48;2;251;233;22m▄\\x1b[38;2;252;230;21;48;2;252;233;20m▄\\x1b[38;2;253;215;26;48;2;253;233;20m▄\\x1b[38;2;253;200;29;48;2;253;228;27m▄\\x1b[38;2;254;203;28;48;2;252;203;26m▄\\x1b[38;2;249;207;48;48;2;252;203;26m▄\\x1b[38;2;242;215;74;48;2;253;204;27m▄\\x1b[49;38;2;249;209;50m▀\\x1b[49;38;2;241;213;99m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[49;38;2;243;213;61m▀\\x1b[38;2;231;219;85;48;2;248;216;32m▄\\x1b[38;2;245;214;58;48;2;250;215;26m▄\\x1b[38;2;248;214;32;48;2;252;212;27m▄\\x1b[38;2;250;215;26;48;2;249;217;27m▄\\x1b[38;2;250;215;27;48;2;247;227;23m▄\\x1b[38;2;247;220;28;48;2;246;231;20m▄\\x1b[38;2;246;230;21;48;2;246;234;23m▄\\x1b[38;2;251;235;24;48;2;247;237;45m▄\\x1b[38;2;242;237;101;49m▄\\x1b[49m \\x1b[38;2;248;239;63;49m▄\\x1b[38;2;252;235;20;48;2;252;237;26m▄\\x1b[48;2;249;232;20m \\x1b[38;2;250;231;22;48;2;247;230;20m▄\\x1b[38;2;248;232;34;48;2;247;230;21m▄\\x1b[38;2;248;232;22;48;2;248;231;21m▄\\x1b[38;2;249;233;21;48;2;253;235;25m▄\\x1b[38;2;251;240;38;48;2;246;241;79m▄\\x1b[49m \\x1b[38;2;252;237;26;48;2;244;236;59m▄\\x1b[38;2;252;233;20;48;2;250;233;23m▄\\x1b[48;2;251;232;20m \\x1b[38;2;252;230;22;48;2;251;231;20m▄\\x1b[38;2;253;214;24;48;2;251;231;20m▄\\x1b[38;2;253;200;28;48;2;252;225;22m▄\\x1b[38;2;250;203;41;48;2;252;203;26m▄\\x1b[38;2;248;205;64;48;2;253;198;28m▄\\x1b[49;38;2;249;202;46m▀\\x1b[49;38;2;246;207;62m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[49;38;2;245;216;88m▀\\x1b[49;38;2;246;216;52m▀\\x1b[38;2;242;216;78;48;2;248;216;31m▄\\x1b[38;2;249;217;38;48;2;250;215;27m▄\\x1b[38;2;250;222;30;48;2;247;227;26m▄\\x1b[48;2;248;232;23m \\x1b[38;2;252;237;28;48;2;251;241;41m▄\\x1b[38;2;238;238;119;49m▄\\x1b[49m \\x1b[38;2;243;235;85;49m▄\\x1b[38;2;252;238;21;48;2;252;240;29m▄\\x1b[38;2;252;234;23;48;2;251;234;22m▄\\x1b[38;2;254;234;22;48;2;252;233;22m▄\\x1b[38;2;248;227;59;48;2;251;232;38m▄\\x1b[38;2;244;234;96;48;2;248;235;51m▄\\x1b[38;2;251;238;32;48;2;249;235;24m▄\\x1b[38;2;250;236;23;48;2;249;234;21m▄\\x1b[38;2;252;234;22;48;2;253;236;25m▄\\x1b[38;2;251;244;44;48;2;246;246;103m▄\\x1b[49m \\x1b[38;2;251;240;33;48;2;238;232;81m▄\\x1b[38;2;249;233;21;48;2;251;236;19m▄\\x1b[38;2;253;227;24;48;2;252;231;21m▄\\x1b[38;2;254;204;26;48;2;252;224;23m▄\\x1b[38;2;248;206;55;48;2;253;206;27m▄\\x1b[49;38;2;250;204;40m▀\\x1b[49;38;2;246;207;60m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;246;215;54;48;2;242;211;53m▄\\x1b[38;2;253;217;20;48;2;248;216;35m▄\\x1b[38;2;250;221;23;48;2;246;219;57m▄\\x1b[38;2;245;232;39;49m▄\\x1b[38;2;245;234;65;49m▄\\x1b[49m \\x1b[38;2;243;219;121;48;2;250;221;50m▄\\x1b[38;2;252;221;33;48;2;251;222;30m▄\\x1b[38;2;250;228;31;48;2;248;231;26m▄\\x1b[38;2;249;232;23;48;2;251;234;23m▄\\x1b[38;2;253;238;29;48;2;249;242;63m▄\\x1b[49m \\x1b[38;2;235;235;112;49m▄\\x1b[38;2;251;236;21;48;2;251;240;34m▄\\x1b[38;2;250;232;23;48;2;251;234;21m▄\\x1b[38;2;253;230;24;48;2;252;233;23m▄\\x1b[38;2;250;222;52;48;2;251;227;36m▄\\x1b[49m \\x1b[38;2;248;241;69;48;2;248;238;48m▄\\x1b[38;2;251;239;28;48;2;250;238;25m▄\\x1b[38;2;250;236;24;48;2;251;235;23m▄\\x1b[38;2;252;234;23;48;2;252;238;26m▄\\x1b[38;2;248;240;59;48;2;239;239;128m▄\\x1b[49m \\x1b[38;2;247;239;52;48;2;244;233;100m▄\\x1b[38;2;249;234;20;48;2;252;238;23m▄\\x1b[38;2;252;231;22;48;2;250;232;22m▄\\x1b[38;2;253;207;25;48;2;253;216;26m▄\\x1b[38;2;250;208;54;48;2;252;207;37m▄\\x1b[49m \\x1b[38;2;241;227;71;49m▄\\x1b[38;2;247;213;44;49m▄\\x1b[38;2;253;208;29;48;2;237;211;88m▄\\x1b[38;2;254;205;28;48;2;248;213;47m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;245;230;60;48;2;242;224;49m▄\\x1b[38;2;249;236;23;48;2;249;233;21m▄\\x1b[38;2;252;235;26;48;2;250;231;20m▄\\x1b[38;2;249;234;30;48;2;249;233;21m▄\\x1b[38;2;254;236;27;48;2;252;236;25m▄\\x1b[38;2;249;238;49;48;2;247;241;52m▄\\x1b[49m \\x1b[38;2;245;216;64;48;2;250;222;59m▄\\x1b[38;2;252;220;31;48;2;252;223;33m▄\\x1b[38;2;249;229;27;48;2;248;231;24m▄\\x1b[38;2;248;230;21;48;2;251;233;22m▄\\x1b[38;2;248;235;29;48;2;242;235;85m▄\\x1b[38;2;251;235;24;48;2;250;242;49m▄\\x1b[38;2;250;231;23;48;2;250;233;22m▄\\x1b[38;2;253;225;23;48;2;252;230;24m▄\\x1b[38;2;250;215;49;48;2;253;222;28m▄\\x1b[49;38;2;244;222;89m▀\\x1b[49m \\x1b[38;2;247;234;63;48;2;248;238;46m▄\\x1b[38;2;251;238;25;48;2;250;237;25m▄\\x1b[38;2;250;233;22;48;2;250;234;21m▄\\x1b[38;2;251;233;21;48;2;252;237;26m▄\\x1b[38;2;244;232;62;49m▄\\x1b[38;2;249;232;21;48;2;252;239;24m▄\\x1b[38;2;250;231;22;48;2;249;231;22m▄\\x1b[38;2;252;212;25;48;2;252;225;23m▄\\x1b[38;2;251;209;55;48;2;253;204;27m▄\\x1b[49;38;2;239;206;99m▀\\x1b[49m \\x1b[38;2;250;237;49;48;2;250;242;50m▄\\x1b[38;2;251;234;22;48;2;252;231;25m▄\\x1b[38;2;253;227;27;48;2;253;212;26m▄\\x1b[38;2;254;206;26;48;2;254;204;25m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;253;239;29;48;2;238;230;84m▄\\x1b[38;2;254;234;24;48;2;253;238;23m▄\\x1b[38;2;253;209;29;48;2;254;233;26m▄\\x1b[38;2;244;216;71;48;2;241;220;99m▄\\x1b[49m \\x1b[38;2;247;217;53;48;2;250;218;44m▄\\x1b[38;2;251;217;31;48;2;250;222;31m▄\\x1b[38;2;247;228;24;48;2;245;229;20m▄\\x1b[48;2;245;229;19m \\x1b[38;2;246;229;19;48;2;247;229;20m▄\\x1b[38;2;253;224;24;48;2;251;229;23m▄\\x1b[38;2;249;211;52;48;2;253;213;27m▄\\x1b[49;38;2;244;210;68m▀\\x1b[49m \\x1b[38;2;249;234;57;48;2;249;237;39m▄\\x1b[38;2;250;235;23;48;2;250;234;24m▄\\x1b[38;2;247;231;19;48;2;247;230;19m▄\\x1b[38;2;244;229;16;48;2;247;230;18m▄\\x1b[38;2;246;229;18;48;2;246;230;19m▄\\x1b[38;2;253;223;23;48;2;252;228;21m▄\\x1b[38;2;253;206;37;48;2;253;208;26m▄\\x1b[49;38;2;251;211;57m▀\\x1b[49m \\x1b[38;2;250;239;47;48;2;250;239;50m▄\\x1b[38;2;250;236;23;48;2;249;235;22m▄\\x1b[38;2;254;231;28;48;2;254;229;26m▄\\x1b[38;2;255;209;26;48;2;254;209;27m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;245;239;70;49m▄\\x1b[38;2;253;241;21;48;2;250;243;39m▄\\x1b[38;2;251;208;32;48;2;254;237;23m▄\\x1b[38;2;248;210;82;48;2;252;208;31m▄\\x1b[49;38;2;245;213;78m▀\\x1b[49m \\x1b[38;2;246;218;70;48;2;252;217;33m▄\\x1b[38;2;250;220;29;48;2;248;225;27m▄\\x1b[38;2;248;229;24;48;2;245;229;20m▄\\x1b[38;2;253;223;23;48;2;251;228;21m▄\\x1b[38;2;252;209;33;48;2;253;211;26m▄\\x1b[49;38;2;242;208;64m▀\\x1b[49m \\x1b[49;38;2;237;237;91m▀\\x1b[38;2;246;235;64;48;2;251;237;29m▄\\x1b[38;2;248;237;24;48;2;248;233;23m▄\\x1b[38;2;247;233;21;48;2;245;231;18m▄\\x1b[38;2;253;230;23;48;2;249;230;19m▄\\x1b[38;2;253;206;30;48;2;253;209;24m▄\\x1b[38;2;239;223;96;48;2;249;207;58m▄\\x1b[49m \\x1b[38;2;247;239;50;48;2;247;239;47m▄\\x1b[38;2;249;236;23;48;2;250;236;23m▄\\x1b[48;2;254;230;27m \\x1b[38;2;254;209;27;48;2;254;209;26m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;235;235;78;49m▄\\x1b[38;2;253;240;32;48;2;234;234;90m▄\\x1b[38;2;249;224;34;48;2;253;242;25m▄\\x1b[38;2;245;214;92;48;2;251;215;32m▄\\x1b[49;38;2;240;209;85m▀\\x1b[49m \\x1b[38;2;245;235;64;49m▄\\x1b[38;2;253;239;32;48;2;239;231;112m▄\\x1b[38;2;246;239;82;49m▄\\x1b[49m \\x1b[49;38;2;246;219;73m▀\\x1b[38;2;249;221;48;48;2;252;220;29m▄\\x1b[38;2;254;222;27;48;2;253;228;27m▄\\x1b[38;2;253;208;28;48;2;254;210;24m▄\\x1b[38;2;237;219;73;48;2;244;208;63m▄\\x1b[49m \\x1b[38;2;249;236;42;49m▄\\x1b[38;2;250;234;23;49m▄\\x1b[38;2;249;231;24;49m▄\\x1b[38;2;248;228;34;49m▄\\x1b[38;2;243;226;99;49m▄\\x1b[49m \\x1b[49;38;2;242;242;67m▀\\x1b[38;2;248;238;57;48;2;252;238;26m▄\\x1b[38;2;253;236;26;48;2;251;235;23m▄\\x1b[38;2;253;213;26;48;2;253;227;24m▄\\x1b[38;2;247;209;62;48;2;247;209;61m▄\\x1b[49m \\x1b[38;2;247;239;49;48;2;247;239;47m▄\\x1b[38;2;250;234;23;48;2;250;235;22m▄\\x1b[38;2;254;228;28;48;2;254;230;28m▄\\x1b[38;2;254;207;26;48;2;254;208;26m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;246;237;59;49m▄\\x1b[38;2;249;236;35;48;2;249;240;43m▄\\x1b[49;38;2;249;233;39m▀\\x1b[49;38;2;237;219;109m▀\\x1b[49m \\x1b[38;2;239;234;80;49m▄\\x1b[38;2;251;241;38;49m▄\\x1b[38;2;252;239;32;48;2;252;242;48m▄\\x1b[38;2;249;237;37;48;2;253;239;24m▄\\x1b[38;2;245;233;57;48;2;254;236;21m▄\\x1b[38;2;237;237;128;48;2;251;239;47m▄\\x1b[49m \\x1b[49;38;2;244;221;68m▀\\x1b[38;2;252;216;33;48;2;254;216;24m▄\\x1b[38;2;244;211;78;48;2;245;211;57m▄\\x1b[49m \\x1b[38;2;250;238;31;48;2;250;239;49m▄\\x1b[38;2;249;233;20;48;2;251;235;20m▄\\x1b[38;2;246;232;19;48;2;249;232;19m▄\\x1b[38;2;246;231;19;48;2;248;231;19m▄\\x1b[38;2;251;232;21;48;2;251;230;20m▄\\x1b[38;2;253;217;25;48;2;250;222;34m▄\\x1b[38;2;243;225;103;49m▄\\x1b[49m \\x1b[49;38;2;238;230;85m▀\\x1b[38;2;251;237;40;48;2;253;238;27m▄\\x1b[38;2;237;219;83;48;2;250;212;43m▄\\x1b[49m \\x1b[38;2;248;238;53;49m▄\\x1b[38;2;252;234;34;48;2;250;237;49m▄\\x1b[38;2;253;220;26;48;2;252;233;23m▄\\x1b[38;2;252;202;28;48;2;253;225;29m▄\\x1b[38;2;254;204;26;48;2;254;205;26m▄\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[38;2;240;229;56;48;2;247;232;62m▄\\x1b[49;38;2;249;238;37m▀\\x1b[49m \\x1b[49;38;2;231;231;110m▀\\x1b[49;38;2;244;241;45m▀\\x1b[49;38;2;239;239;63m▀\\x1b[49m \\x1b[49;38;2;241;217;88m▀\\x1b[49m \\x1b[38;2;249;236;52;48;2;249;237;33m▄\\x1b[38;2;250;237;24;48;2;248;234;22m▄\\x1b[38;2;250;234;21;48;2;246;233;19m▄\\x1b[38;2;251;230;21;48;2;247;233;19m▄\\x1b[38;2;253;210;26;48;2;252;230;22m▄\\x1b[38;2;251;207;36;48;2;253;209;27m▄\\x1b[49;38;2;243;219;95m▀\\x1b[49m \\x1b[49;38;2;241;223;96m▀\\x1b[49m \\x1b[38;2;242;233;67;49m▄\\x1b[38;2;249;236;41;49m▄\\x1b[38;2;253;237;23;48;2;245;232;63m▄\\x1b[38;2;253;226;24;48;2;251;238;38m▄\\x1b[38;2;251;201;26;48;2;252;234;23m▄\\x1b[38;2;251;198;26;48;2;251;210;25m▄\\x1b[38;2;253;202;29;48;2;251;199;25m▄\\x1b[38;2;251;203;42;48;2;253;201;28m▄\\x1b[38;2;229;211;123;48;2;253;203;32m▄\\x1b[49m \\x1b[m\n\\x1b[38;2;222;222;144;49m▄\\x1b[38;2;229;220;123;48;2;234;225;98m▄\\x1b[49;38;2;228;215;121m▀\\x1b[49m \\x1b[38;2;248;236;46;49m▄\\x1b[38;2;252;236;21;48;2;243;230;66m▄\\x1b[38;2;251;233;20;48;2;249;234;38m▄\\x1b[38;2;251;231;20;48;2;248;234;33m▄\\x1b[38;2;248;231;20;48;2;244;229;67m▄\\x1b[38;2;244;233;47;49m▄\\x1b[38;2;236;236;70;49m▄\\x1b[49m \\x1b[49;38;2;247;212;46m▀\\x1b[49;38;2;250;209;30m▀\\x1b[38;2;240;225;150;48;2;251;202;30m▄\\x1b[49;38;2;252;203;36m▀\\x1b[49;38;2;241;212;90m▀\\x1b[49m \\x1b[38;2;235;235;98;49m▄\\x1b[38;2;243;235;63;49m▄\\x1b[38;2;251;238;25;48;2;237;228;73m▄\\x1b[38;2;253;236;20;48;2;247;234;52m▄\\x1b[38;2;254;230;22;48;2;252;238;23m▄\\x1b[38;2;252;206;26;48;2;253;233;21m▄\\x1b[38;2;253;198;28;48;2;252;217;25m▄\\x1b[38;2;252;201;36;48;2;252;196;26m▄\\x1b[38;2;240;205;70;48;2;252;199;28m▄\\x1b[49;38;2;250;202;38m▀\\x1b[49;38;2;241;213;88m▀\\x1b[49m \\x1b[m\n\\x1b[49;38;2;207;207;191m▀\\x1b[49m \\x1b[38;2;236;232;82;49m▄\\x1b[38;2;248;239;48;49m▄\\x1b[49m \\x1b[49;38;2;244;231;69m▀\\x1b[49;38;2;249;233;29m▀\\x1b[38;2;244;228;69;48;2;248;234;23m▄\\x1b[38;2;249;233;28;48;2;247;231;21m▄\\x1b[38;2;247;232;25;48;2;247;230;20m▄\\x1b[38;2;248;231;23;48;2;248;231;19m▄\\x1b[38;2;249;232;23;48;2;247;233;20m▄\\x1b[38;2;249;233;24;48;2;246;237;59m▄\\x1b[38;2;248;237;29;48;2;242;242;77m▄\\x1b[38;2;244;240;76;49m▄\\x1b[49m \\x1b[38;2;241;234;99;49m▄\\x1b[38;2;250;238;41;49m▄\\x1b[38;2;253;237;26;48;2;242;232;79m▄\\x1b[38;2;253;236;25;48;2;252;240;27m▄\\x1b[38;2;254;233;24;48;2;254;236;20m▄\\x1b[38;2;251;210;29;48;2;253;235;21m▄\\x1b[38;2;251;197;28;48;2;253;225;23m▄\\x1b[38;2;246;202;53;48;2;254;200;27m▄\\x1b[49;38;2;253;199;32m▀\\x1b[49;38;2;245;207;64m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[49;38;2;231;219;97m▀\\x1b[49;38;2;243;229;58m▀\\x1b[49m \\x1b[49;38;2;237;237;91m▀\\x1b[49;38;2;246;231;56m▀\\x1b[38;2;246;238;68;48;2;246;233;22m▄\\x1b[38;2;245;230;48;48;2;246;233;21m▄\\x1b[38;2;247;235;23;48;2;247;232;19m▄\\x1b[38;2;246;233;21;48;2;247;232;18m▄\\x1b[38;2;247;232;20;48;2;248;232;18m▄\\x1b[38;2;247;231;19;48;2;246;234;29m▄\\x1b[38;2;247;232;20;48;2;240;230;80m▄\\x1b[38;2;246;233;34;49m▄\\x1b[38;2;245;231;52;49m▄\\x1b[38;2;250;233;23;48;2;225;225;105m▄\\x1b[38;2;252;233;19;48;2;248;234;46m▄\\x1b[38;2;253;233;20;48;2;253;235;21m▄\\x1b[38;2;254;232;21;48;2;253;234;20m▄\\x1b[38;2;252;217;24;48;2;254;234;20m▄\\x1b[38;2;253;202;35;48;2;254;230;23m▄\\x1b[38;2;246;211;84;48;2;253;201;28m▄\\x1b[49;38;2;250;203;46m▀\\x1b[49;38;2;247;206;82m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[49;38;2;247;226;63m▀\\x1b[49;38;2;247;232;36m▀\\x1b[38;2;245;229;57;48;2;246;232;22m▄\\x1b[38;2;247;230;31;48;2;248;232;21m▄\\x1b[38;2;247;232;21;48;2;247;231;19m▄\\x1b[38;2;247;233;19;48;2;246;231;18m▄\\x1b[38;2;247;232;17;48;2;246;231;17m▄\\x1b[38;2;251;232;19;48;2;249;232;17m▄\\x1b[38;2;253;221;24;48;2;252;232;20m▄\\x1b[38;2;249;207;48;48;2;253;229;22m▄\\x1b[38;2;248;209;72;48;2;253;207;28m▄\\x1b[49;38;2;245;202;59m▀\\x1b[49;38;2;237;200;109m▀\\x1b[49m \\x1b[m\n\\x1b[49m \\x1b[49;38;2;242;230;89m▀\\x1b[49;38;2;247;232;50m▀\\x1b[38;2;244;227;72;48;2;249;233;28m▄\\x1b[38;2;244;218;55;48;2;252;231;23m▄\\x1b[49;38;2;250;215;37m▀\\x1b[49;38;2;244;206;65m▀\\x1b[49m \\x1b[m\n`;\n\n/**\n * Get the intro banner with ASCII art\n */\nexport function getIntroBanner(version: string): string {\n const versionLine = `v${version}`;\n const totalWidth = 38; // Total width inside the box\n const padding = \" \".repeat(totalWidth - 3 - versionLine.length); // 3 is for leading spaces \" \"\n\n return `\n ${colors.magentaBright(\"╭──────────────────────────────────────╮\")}\n ${colors.magentaBright(\"│\")} ${colors.magentaBright(\"│\")}\n ${colors.magentaBright(\"│\")} 🧙 ${colors.bold(colors.yellowBright(\"WARLOCK.JS\"))} ${colors.magentaBright(\"│\")}\n ${colors.magentaBright(\"│\")} ${colors.cyan(\"The Magical Node.js Framework\")} ${colors.magentaBright(\"│\")}\n ${colors.magentaBright(\"│\")} ${colors.magentaBright(\"│\")}\n ${colors.magentaBright(\"│\")} ${colors.green(versionLine)}${padding}${colors.magentaBright(\"│\")}\n ${colors.magentaBright(\"│\")} ${colors.magentaBright(\"│\")}\n ${colors.magentaBright(\"╰──────────────────────────────────────╯\")}\n`;\n}\n\n/**\n * Display the intro banner\n */\nexport function showIntroBanner(version: string): void {\n console.log(warlockLogoAnsi);\n console.log(warlockTextAnsi);\n console.log(getIntroBanner(version));\n}\n\n/**\n * Get the success screen with project summary\n */\nexport function getSuccessScreen(options: {\n projectName: string;\n database: string;\n features: string[];\n packageManager: string;\n}): string {\n const { projectName, database, features, packageManager } = options;\n\n // Format features text\n let featuresText = features.join(\", \");\n if (features.length === 0) {\n featuresText = \"none\";\n }\n\n // Calculate dynamic width\n const baseLabelLength = 10; // \"Project: \".length\n const padding = 6; // 3 spaces left, 3 spaces right padding for text inside box\n\n const projectLineLen = projectName.length + baseLabelLength;\n const dbLineLen = database.length + baseLabelLength;\n const featuresLineLen = featuresText.length + baseLabelLength;\n\n // Find the longest line to determine box width\n // Ensure minimum width of 50 for aesthetics\n const maxContentLength = Math.max(\n projectLineLen,\n dbLineLen,\n featuresLineLen,\n 40,\n );\n const boxWidth = maxContentLength + padding + 2; // +2 for borders │\n\n // Helper to generate borders\n const createBorder = (start: string, end: string) =>\n colors.magentaBright(start + \"─\".repeat(boxWidth - 2) + end);\n\n // Helper to pad content lines\n const padLine = (label: string, value: string, isFeature = false) => {\n const valueColor = (text: string) => {\n if (isFeature && text === \"none\") return colors.dim(text);\n return colors.white(text);\n };\n\n const labelPart = colors.dim(label.padEnd(10)); // \"Project: \"\n const valuePart = valueColor(value);\n\n // Calculate visible length for padding\n const contentVisibleLength = 3 + 10 + value.length;\n const remaining = boxWidth - 2 - contentVisibleLength; // -2 for borders\n\n return (\n colors.magentaBright(\"│\") +\n \" \" +\n labelPart +\n valuePart +\n \" \".repeat(remaining) +\n colors.magentaBright(\"│\")\n );\n };\n\n const emptyLine =\n colors.magentaBright(\"│\") +\n \" \".repeat(boxWidth - 2) +\n colors.magentaBright(\"│\");\n\n const headerText = \"🎉 YOUR PROJECT IS READY! 🎉\";\n const headerPadding = Math.floor((boxWidth - 2 - headerText.length) / 2);\n const headerLine =\n colors.magentaBright(\"│\") +\n \" \".repeat(headerPadding) +\n colors.bold(colors.green(headerText)) +\n \" \".repeat(boxWidth - 2 - headerPadding - headerText.length) +\n colors.magentaBright(\"│\");\n\n const devCommand =\n packageManager === \"npm\" ? \"npm run dev\" : `${packageManager} dev`;\n\n return `\n ${createBorder(\"╭\", \"╮\")}\n ${emptyLine}\n ${headerLine}\n ${emptyLine}\n ${padLine(\"Project:\", projectName)}\n ${padLine(\"Database:\", database)}\n ${padLine(\"Features:\", featuresText, true)}\n ${emptyLine}\n ${createBorder(\"╰\", \"╯\")}\n\n ${colors.bold(colors.cyan(\"🚀 Next steps:\"))}\n\n ${colors.cyan(\"cd\")} ${projectName}\n ${colors.cyan(devCommand)}\n\n ${colors.dim(\"💡 Pro tip: Install the\")} ${colors.yellow(\"Generator Z\")} ${colors.dim(\"extension in VSCode\")}\n ${colors.dim(\"for helpful code snippets and productivity boosters!\")}\n\n ${colors.dim(\"📚 Docs:\")} ${colors.cyan(\"https://warlock.js.org\")}\n ${colors.dim(\"⭐ Star us:\")} ${colors.cyan(\"https://github.com/warlockjs/framework\")}\n`;\n}\n\n/**\n * Display the success screen\n */\nexport function showSuccessScreen(options: {\n projectName: string;\n database: string;\n features: string[];\n packageManager: string;\n}): void {\n console.log(getSuccessScreen(options));\n}\n"],"mappings":"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"}
package/esm/ui/report.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { tail } from "../helpers/exec.mjs";
2
2
  import { colors } from "@mongez/copper";
3
3
 
4
- //#region ../create-warlock/src/ui/report.ts
4
+ //#region ../../packages/create-warlock/src/ui/report.ts
5
5
  const bullet = colors.red("✖");
6
6
  /**
7
7
  * The command line, its exit status, and the tail of what it printed.
@@ -1 +1 @@
1
- {"version":3,"file":"report.mjs","names":[],"sources":["../../../../../../create-warlock/src/ui/report.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport type { CommandResult } from \"../helpers/exec\";\nimport { tail } from \"../helpers/exec\";\n\n/**\n * Failure reporting for the scaffolder.\n *\n * The house rule this module enforces: a step that did not succeed is never\n * described as if it did, and a failure always carries three things — WHAT ran,\n * HOW it ended (exit code), and ENOUGH of its output to act on. \"Something went\n * wrong, add it later\" is not a report.\n */\n\n/** A step that did not do what the user asked for. */\nexport type Problem = {\n /** The step, e.g. `Dependency install`. */\n step: string;\n /** One-line summary of what is now missing / broken. */\n detail: string;\n /** The command behind the failure, when there was one. */\n result?: CommandResult;\n /** Extra guidance: how to retry, what to check. */\n hints?: string[];\n};\n\nconst bullet = colors.red(\"✖\");\n\n/**\n * The command line, its exit status, and the tail of what it printed.\n */\nfunction describeCommand(result: CommandResult): string[] {\n const lines: string[] = [];\n\n lines.push(`${colors.dim(\"command:\")} ${colors.white(result.command)}`);\n\n if (result.cwd) {\n lines.push(`${colors.dim(\"in:\")} ${colors.white(result.cwd)}`);\n }\n\n if (result.error) {\n lines.push(\n `${colors.dim(\"failed:\")} ${colors.white(result.error.message || String(result.error))}`,\n );\n } else if (result.signal) {\n lines.push(`${colors.dim(\"killed:\")} ${colors.white(result.signal)}`);\n } else {\n lines.push(\n `${colors.dim(\"exited:\")} ${colors.white(`code ${result.code}`)}`,\n );\n }\n\n const output = tail(result.stderr) || tail(result.stdout);\n\n if (output) {\n lines.push(colors.dim(\"output:\"));\n\n for (const line of output.split(\"\\n\")) {\n lines.push(` ${colors.dim(line)}`);\n }\n }\n\n return lines;\n}\n\nfunction printProblem(problem: Problem) {\n console.log(` ${bullet} ${colors.bold(colors.red(problem.step))}`);\n console.log(` ${colors.white(problem.detail)}`);\n\n if (problem.result) {\n for (const line of describeCommand(problem.result)) {\n console.log(` ${line}`);\n }\n }\n\n for (const hint of problem.hints ?? []) {\n console.log(` ${colors.yellow(\"→\")} ${colors.yellow(hint)}`);\n }\n\n console.log();\n}\n\n/**\n * Report a failure the scaffold cannot continue past, and leave the process\n * with a non-zero exit code. Nothing after this point may print a success.\n */\nexport function failFatally(problem: Problem): never {\n console.log();\n console.log(colors.bold(colors.red(\" SCAFFOLD FAILED\")));\n console.log();\n\n printProblem(problem);\n\n console.log(\n colors.dim(\n \" The project directory was left in place so you can inspect it.\",\n ),\n );\n console.log();\n\n process.exit(1);\n}\n\n/**\n * Report the steps that failed on a scaffold that otherwise completed, and say\n * plainly what the project does NOT have as a result.\n */\nexport function showProblems(problems: Problem[]) {\n if (problems.length === 0) return;\n\n console.log();\n console.log(\n colors.bold(\n colors.yellow(\n ` COMPLETED WITH ${problems.length} PROBLEM${problems.length === 1 ? \"\" : \"S\"}`,\n ),\n ),\n );\n console.log();\n\n for (const problem of problems) {\n printProblem(problem);\n }\n}\n\n/** Neutral, non-failing information — e.g. which versions got pinned and why. */\nexport function showNotes(notes: string[]) {\n for (const note of notes) {\n console.log(` ${colors.yellow(\"!\")} ${colors.dim(note)}`);\n }\n\n if (notes.length > 0) console.log();\n}\n\n/**\n * A scaffold that finished with problems still produced a project, so print the\n * same facts the success screen would — minus the celebration, and listing only\n * what is actually installed.\n */\nexport function showPartialScreen(options: {\n projectName: string;\n database: string;\n features: string[];\n missingFeatures: string[];\n packageManager: string;\n}): void {\n const { projectName, database, features, missingFeatures, packageManager } =\n options;\n\n const devCommand =\n packageManager === \"npm\" ? \"npm run dev\" : `${packageManager} dev`;\n\n console.log(\n ` ${colors.bold(colors.yellow(\"⚠ PROJECT CREATED — BUT NOT AS REQUESTED\"))}`,\n );\n console.log();\n console.log(` ${colors.dim(\"Project: \")}${colors.white(projectName)}`);\n console.log(` ${colors.dim(\"Database: \")}${colors.white(database)}`);\n console.log(\n ` ${colors.dim(\"Installed:\")}${colors.white(features.length > 0 ? \" \" + features.join(\", \") : \" none\")}`,\n );\n\n if (missingFeatures.length > 0) {\n console.log(\n ` ${colors.dim(\"Missing: \")}${colors.red(missingFeatures.join(\", \"))}`,\n );\n }\n\n console.log();\n console.log(` ${colors.dim(\"Fix the problems above, then:\")}`);\n console.log();\n console.log(` ${colors.cyan(\"cd\")} ${projectName}`);\n\n if (missingFeatures.length > 0) {\n console.log(\n ` ${colors.cyan(`npx warlock add ${missingFeatures.join(\" \")}`)}`,\n );\n }\n\n console.log(` ${colors.cyan(devCommand)}`);\n console.log();\n}\n\n/**\n * Turn an npm/yarn/pnpm failure into actionable guidance where we can\n * recognise it. `ETARGET` in particular is the signature of a dependency\n * pinned to a version that was never published — the bug this whole reporting\n * path was written for.\n */\nexport function installFailureHints(result: CommandResult | undefined) {\n const output = `${result?.stdout ?? \"\"}${result?.stderr ?? \"\"}`;\n const projectDirectory =\n result?.cwd ?? \"the already-created project directory\";\n const command = result?.command ?? \"the install command\";\n const npmArboristFailure =\n command.startsWith(\"npm \") &&\n /Cannot read properties of null \\(reading 'edgesOut'\\)/i.test(output);\n\n if (npmArboristFailure) {\n return [\n \"Detected npm 10.9.x: its Arborist peer-dependency resolver has a defect (`edgesOut`); this is not a problem with your project.\",\n `To finish from ${projectDirectory}: run \\`cd ${projectDirectory}\\`, then \\`npm install -g npm@11\\` and \\`${command}\\`.`,\n `Or, from ${projectDirectory}, install with \\`pnpm install\\` or \\`yarn install\\`.`,\n ];\n }\n\n const logPath = output.match(\n /A complete log of this run can be found in:\\s*(\\S+)/i,\n )?.[1];\n const hints = [\n `The project remains at ${projectDirectory}; \\`${command}\\` failed there.`,\n logPath\n ? `Review the package manager's log at ${logPath} before retrying.`\n : \"Review the package manager's own log path in the output above before retrying.\",\n ];\n\n if (/ETARGET|No matching version found/i.test(output)) {\n hints.push(\n \"A dependency is pinned to a version that does not exist on the registry — check the @warlock.js/* versions in package.json.\",\n );\n }\n\n if (/ENOTFOUND|ETIMEDOUT|ECONNREFUSED|network/i.test(output)) {\n hints.push(\"The registry was unreachable — check your network or proxy.\");\n }\n\n if (/EACCES|EPERM/i.test(output)) {\n hints.push(\n \"Permission denied — check the directory's ownership before retrying.\",\n );\n }\n\n return hints;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"report.mjs","names":[],"sources":["../../../../../../../packages/create-warlock/src/ui/report.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport type { CommandResult } from \"../helpers/exec\";\nimport { tail } from \"../helpers/exec\";\n\n/**\n * Failure reporting for the scaffolder.\n *\n * The house rule this module enforces: a step that did not succeed is never\n * described as if it did, and a failure always carries three things — WHAT ran,\n * HOW it ended (exit code), and ENOUGH of its output to act on. \"Something went\n * wrong, add it later\" is not a report.\n */\n\n/** A step that did not do what the user asked for. */\nexport type Problem = {\n /** The step, e.g. `Dependency install`. */\n step: string;\n /** One-line summary of what is now missing / broken. */\n detail: string;\n /** The command behind the failure, when there was one. */\n result?: CommandResult;\n /** Extra guidance: how to retry, what to check. */\n hints?: string[];\n};\n\nconst bullet = colors.red(\"✖\");\n\n/**\n * The command line, its exit status, and the tail of what it printed.\n */\nfunction describeCommand(result: CommandResult): string[] {\n const lines: string[] = [];\n\n lines.push(`${colors.dim(\"command:\")} ${colors.white(result.command)}`);\n\n if (result.cwd) {\n lines.push(`${colors.dim(\"in:\")} ${colors.white(result.cwd)}`);\n }\n\n if (result.error) {\n lines.push(\n `${colors.dim(\"failed:\")} ${colors.white(result.error.message || String(result.error))}`,\n );\n } else if (result.signal) {\n lines.push(`${colors.dim(\"killed:\")} ${colors.white(result.signal)}`);\n } else {\n lines.push(\n `${colors.dim(\"exited:\")} ${colors.white(`code ${result.code}`)}`,\n );\n }\n\n const output = tail(result.stderr) || tail(result.stdout);\n\n if (output) {\n lines.push(colors.dim(\"output:\"));\n\n for (const line of output.split(\"\\n\")) {\n lines.push(` ${colors.dim(line)}`);\n }\n }\n\n return lines;\n}\n\nfunction printProblem(problem: Problem) {\n console.log(` ${bullet} ${colors.bold(colors.red(problem.step))}`);\n console.log(` ${colors.white(problem.detail)}`);\n\n if (problem.result) {\n for (const line of describeCommand(problem.result)) {\n console.log(` ${line}`);\n }\n }\n\n for (const hint of problem.hints ?? []) {\n console.log(` ${colors.yellow(\"→\")} ${colors.yellow(hint)}`);\n }\n\n console.log();\n}\n\n/**\n * Report a failure the scaffold cannot continue past, and leave the process\n * with a non-zero exit code. Nothing after this point may print a success.\n */\nexport function failFatally(problem: Problem): never {\n console.log();\n console.log(colors.bold(colors.red(\" SCAFFOLD FAILED\")));\n console.log();\n\n printProblem(problem);\n\n console.log(\n colors.dim(\n \" The project directory was left in place so you can inspect it.\",\n ),\n );\n console.log();\n\n process.exit(1);\n}\n\n/**\n * Report the steps that failed on a scaffold that otherwise completed, and say\n * plainly what the project does NOT have as a result.\n */\nexport function showProblems(problems: Problem[]) {\n if (problems.length === 0) return;\n\n console.log();\n console.log(\n colors.bold(\n colors.yellow(\n ` COMPLETED WITH ${problems.length} PROBLEM${problems.length === 1 ? \"\" : \"S\"}`,\n ),\n ),\n );\n console.log();\n\n for (const problem of problems) {\n printProblem(problem);\n }\n}\n\n/** Neutral, non-failing information — e.g. which versions got pinned and why. */\nexport function showNotes(notes: string[]) {\n for (const note of notes) {\n console.log(` ${colors.yellow(\"!\")} ${colors.dim(note)}`);\n }\n\n if (notes.length > 0) console.log();\n}\n\n/**\n * A scaffold that finished with problems still produced a project, so print the\n * same facts the success screen would — minus the celebration, and listing only\n * what is actually installed.\n */\nexport function showPartialScreen(options: {\n projectName: string;\n database: string;\n features: string[];\n missingFeatures: string[];\n packageManager: string;\n}): void {\n const { projectName, database, features, missingFeatures, packageManager } =\n options;\n\n const devCommand =\n packageManager === \"npm\" ? \"npm run dev\" : `${packageManager} dev`;\n\n console.log(\n ` ${colors.bold(colors.yellow(\"⚠ PROJECT CREATED — BUT NOT AS REQUESTED\"))}`,\n );\n console.log();\n console.log(` ${colors.dim(\"Project: \")}${colors.white(projectName)}`);\n console.log(` ${colors.dim(\"Database: \")}${colors.white(database)}`);\n console.log(\n ` ${colors.dim(\"Installed:\")}${colors.white(features.length > 0 ? \" \" + features.join(\", \") : \" none\")}`,\n );\n\n if (missingFeatures.length > 0) {\n console.log(\n ` ${colors.dim(\"Missing: \")}${colors.red(missingFeatures.join(\", \"))}`,\n );\n }\n\n console.log();\n console.log(` ${colors.dim(\"Fix the problems above, then:\")}`);\n console.log();\n console.log(` ${colors.cyan(\"cd\")} ${projectName}`);\n\n if (missingFeatures.length > 0) {\n console.log(\n ` ${colors.cyan(`npx warlock add ${missingFeatures.join(\" \")}`)}`,\n );\n }\n\n console.log(` ${colors.cyan(devCommand)}`);\n console.log();\n}\n\n/**\n * Turn an npm/yarn/pnpm failure into actionable guidance where we can\n * recognise it. `ETARGET` in particular is the signature of a dependency\n * pinned to a version that was never published — the bug this whole reporting\n * path was written for.\n */\nexport function installFailureHints(result: CommandResult | undefined) {\n const output = `${result?.stdout ?? \"\"}${result?.stderr ?? \"\"}`;\n const projectDirectory =\n result?.cwd ?? \"the already-created project directory\";\n const command = result?.command ?? \"the install command\";\n const npmArboristFailure =\n command.startsWith(\"npm \") &&\n /Cannot read properties of null \\(reading 'edgesOut'\\)/i.test(output);\n\n if (npmArboristFailure) {\n return [\n \"Detected npm 10.9.x: its Arborist peer-dependency resolver has a defect (`edgesOut`); this is not a problem with your project.\",\n `To finish from ${projectDirectory}: run \\`cd ${projectDirectory}\\`, then \\`npm install -g npm@11\\` and \\`${command}\\`.`,\n `Or, from ${projectDirectory}, install with \\`pnpm install\\` or \\`yarn install\\`.`,\n ];\n }\n\n const logPath = output.match(\n /A complete log of this run can be found in:\\s*(\\S+)/i,\n )?.[1];\n const hints = [\n `The project remains at ${projectDirectory}; \\`${command}\\` failed there.`,\n logPath\n ? `Review the package manager's log at ${logPath} before retrying.`\n : \"Review the package manager's own log path in the output above before retrying.\",\n ];\n\n if (/ETARGET|No matching version found/i.test(output)) {\n hints.push(\n \"A dependency is pinned to a version that does not exist on the registry — check the @warlock.js/* versions in package.json.\",\n );\n }\n\n if (/ENOTFOUND|ETIMEDOUT|ECONNREFUSED|network/i.test(output)) {\n hints.push(\"The registry was unreachable — check your network or proxy.\");\n }\n\n if (/EACCES|EPERM/i.test(output)) {\n hints.push(\n \"Permission denied — check the directory's ownership before retrying.\",\n );\n }\n\n return hints;\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { spinner } from "@clack/prompts";
2
2
  import { colors } from "@mongez/copper";
3
3
 
4
- //#region ../create-warlock/src/ui/spinner.ts
4
+ //#region ../../packages/create-warlock/src/ui/spinner.ts
5
5
  /**
6
6
  * A spinner that animates on a real terminal and stays quiet everywhere else.
7
7
  *
@@ -1 +1 @@
1
- {"version":3,"file":"spinner.mjs","names":["spinner","clackSpinner"],"sources":["../../../../../../create-warlock/src/ui/spinner.ts"],"sourcesContent":["import { spinner as clackSpinner } from \"@clack/prompts\";\nimport { colors } from \"@mongez/copper\";\n\n/**\n * The subset of the spinner surface the scaffolder actually drives: a step is\n * started, optionally re-messaged, and stopped with a success/failure code.\n * Deliberately identical to `@clack/prompts`' spinner so the animated path can\n * be returned as-is on a real terminal.\n */\nexport type Spinner = {\n /** Begin the step (starts the animation on a TTY). */\n start: (message?: string) => void;\n /** End the step. `code` 0 is success; anything else is a failure. */\n stop: (message?: string, code?: number) => void;\n /** Update the in-flight message (animation-only). */\n message: (message?: string) => void;\n};\n\n/**\n * A spinner that animates on a real terminal and stays quiet everywhere else.\n *\n * `@clack/prompts`' spinner drives its animation from a `setInterval` that\n * rewrites the current line several times a second using cursor-move escapes.\n * On a TTY those escapes redraw one line in place. On a NON-TTY (a pipe, CI, an\n * agent harness) `process.stdout.isTTY` is `undefined` and the escapes do\n * nothing, so every frame lands as a fresh chunk of output: a single ~21s\n * install step alone buries the log under hundreds of near-identical lines.\n *\n * The animation is a courtesy for a human watching a live terminal; it has no\n * value in a captured log. So on a non-TTY we skip the frame loop entirely and\n * print exactly one line when the step starts and one when it stops — the\n * progress stays legible without the flood. See `specs/spinner.spec.ts`.\n */\nexport function spinner(): Spinner {\n if (process.stdout.isTTY) {\n return clackSpinner();\n }\n\n // Match @clack's own message hygiene: it strips a trailing \"...\" because the\n // animated dots stand in for it. Our static lines carry no dots, so drop them.\n const clean = (message = \"\"): string => message.replace(/\\.+$/, \"\");\n\n return {\n start(message = \"\") {\n process.stdout.write(`${colors.magenta(\"○\")} ${clean(message)}\\n`);\n },\n stop(message = \"\", code = 0) {\n const symbol = code === 0 ? colors.green(\"✓\") : colors.red(\"✖\");\n\n process.stdout.write(`${symbol} ${clean(message)}\\n`);\n },\n message() {\n // Intermediate messages exist only to animate the live line. On a non-TTY\n // the start and stop lines already tell the whole story, so this is a\n // deliberate no-op — the alternative is one extra line per update, which\n // is exactly the flood this module exists to prevent.\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAiCA,SAAgBA,YAAmB;CACjC,IAAI,QAAQ,OAAO,OACjB,OAAOC,QAAa;CAKtB,MAAM,SAAS,UAAU,OAAe,QAAQ,QAAQ,QAAQ,EAAE;CAElE,OAAO;EACL,MAAM,UAAU,IAAI;GAClB,QAAQ,OAAO,MAAM,GAAG,OAAO,QAAQ,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,GAAG;EACnE;EACA,KAAK,UAAU,IAAI,OAAO,GAAG;GAC3B,MAAM,SAAS,SAAS,IAAI,OAAO,MAAM,GAAG,IAAI,OAAO,IAAI,GAAG;GAE9D,QAAQ,OAAO,MAAM,GAAG,OAAO,GAAG,MAAM,OAAO,EAAE,GAAG;EACtD;EACA,UAAU,CAKV;CACF;AACF"}
1
+ {"version":3,"file":"spinner.mjs","names":["spinner","clackSpinner"],"sources":["../../../../../../../packages/create-warlock/src/ui/spinner.ts"],"sourcesContent":["import { spinner as clackSpinner } from \"@clack/prompts\";\nimport { colors } from \"@mongez/copper\";\n\n/**\n * The subset of the spinner surface the scaffolder actually drives: a step is\n * started, optionally re-messaged, and stopped with a success/failure code.\n * Deliberately identical to `@clack/prompts`' spinner so the animated path can\n * be returned as-is on a real terminal.\n */\nexport type Spinner = {\n /** Begin the step (starts the animation on a TTY). */\n start: (message?: string) => void;\n /** End the step. `code` 0 is success; anything else is a failure. */\n stop: (message?: string, code?: number) => void;\n /** Update the in-flight message (animation-only). */\n message: (message?: string) => void;\n};\n\n/**\n * A spinner that animates on a real terminal and stays quiet everywhere else.\n *\n * `@clack/prompts`' spinner drives its animation from a `setInterval` that\n * rewrites the current line several times a second using cursor-move escapes.\n * On a TTY those escapes redraw one line in place. On a NON-TTY (a pipe, CI, an\n * agent harness) `process.stdout.isTTY` is `undefined` and the escapes do\n * nothing, so every frame lands as a fresh chunk of output: a single ~21s\n * install step alone buries the log under hundreds of near-identical lines.\n *\n * The animation is a courtesy for a human watching a live terminal; it has no\n * value in a captured log. So on a non-TTY we skip the frame loop entirely and\n * print exactly one line when the step starts and one when it stops — the\n * progress stays legible without the flood. See `specs/spinner.spec.ts`.\n */\nexport function spinner(): Spinner {\n if (process.stdout.isTTY) {\n return clackSpinner();\n }\n\n // Match @clack's own message hygiene: it strips a trailing \"...\" because the\n // animated dots stand in for it. Our static lines carry no dots, so drop them.\n const clean = (message = \"\"): string => message.replace(/\\.+$/, \"\");\n\n return {\n start(message = \"\") {\n process.stdout.write(`${colors.magenta(\"○\")} ${clean(message)}\\n`);\n },\n stop(message = \"\", code = 0) {\n const symbol = code === 0 ? colors.green(\"✓\") : colors.red(\"✖\");\n\n process.stdout.write(`${symbol} ${clean(message)}\\n`);\n },\n message() {\n // Intermediate messages exist only to animate the live line. On a non-TTY\n // the start and stop lines already tell the whole story, so this is a\n // deliberate no-op — the alternative is one extra line per update, which\n // is exactly the flood this module exists to prevent.\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAiCA,SAAgBA,YAAmB;CACjC,IAAI,QAAQ,OAAO,OACjB,OAAOC,QAAa;CAKtB,MAAM,SAAS,UAAU,OAAe,QAAQ,QAAQ,QAAQ,EAAE;CAElE,OAAO;EACL,MAAM,UAAU,IAAI;GAClB,QAAQ,OAAO,MAAM,GAAG,OAAO,QAAQ,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,GAAG;EACnE;EACA,KAAK,UAAU,IAAI,OAAO,GAAG;GAC3B,MAAM,SAAS,SAAS,IAAI,OAAO,MAAM,GAAG,IAAI,OAAO,IAAI,GAAG;GAE9D,QAAQ,OAAO,MAAM,GAAG,OAAO,GAAG,MAAM,OAAO,EAAE,GAAG;EACtD;EACA,UAAU,CAKV;CACF;AACF"}
@@ -1,4 +1,4 @@
1
- //#region ../create-warlock/src/ui/spinners.ts
1
+ //#region ../../packages/create-warlock/src/ui/spinners.ts
2
2
  /**
3
3
  * Themed spinner messages for the wizard.
4
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"spinners.mjs","names":[],"sources":["../../../../../../create-warlock/src/ui/spinners.ts"],"sourcesContent":["/**\n * Themed spinner messages for the wizard.\n *\n * Every step has BOTH a success and a failure message, and the orchestrator\n * picks between them from the step's actual result. A spinner that can only\n * stop with a cheerful message is a spinner that lies.\n */\nexport const spinnerMessages = {\n installingDeps: \"Summoning dependencies...\",\n depsInstalled: \"Dependencies materialized!\",\n depsFailed: \"Dependencies could not be installed\",\n\n initializingGit: \"Initializing grimoire (git)...\",\n gitInitialized: \"Grimoire initialized!\",\n gitFailed: \"Git repository was not initialized\",\n\n generatingJwt: \"Forging secret keys...\",\n jwtGenerated: \"Secret keys forged!\",\n jwtFailed: \"Secret keys were NOT generated\",\n\n warmingCache: \"Charging magical circuits...\",\n cacheWarmed: \"Circuits charged!\",\n cacheWarmFailed:\n \"Cache could not be warmed (harmless — it builds on first run)\",\n\n addingFeatures: \"Weaving in your features...\",\n featuresAdded: \"Features woven in!\",\n featuresPartial: \"Some features were not added\",\n featuresFailed: \"No features could be added\",\n\n copyingTemplate: \"Preparing your spellbook...\",\n templateCopied: \"Spellbook ready!\",\n templateFailed: \"The project template could not be copied\",\n} as const;\n"],"mappings":";;;;;;;;AAOA,MAAa,kBAAkB;CAC7B,gBAAgB;CAChB,eAAe;CACf,YAAY;CAEZ,iBAAiB;CACjB,gBAAgB;CAChB,WAAW;CAEX,eAAe;CACf,cAAc;CACd,WAAW;CAEX,cAAc;CACd,aAAa;CACb,iBACE;CAEF,gBAAgB;CAChB,eAAe;CACf,iBAAiB;CACjB,gBAAgB;CAEhB,iBAAiB;CACjB,gBAAgB;CAChB,gBAAgB;AAClB"}
1
+ {"version":3,"file":"spinners.mjs","names":[],"sources":["../../../../../../../packages/create-warlock/src/ui/spinners.ts"],"sourcesContent":["/**\n * Themed spinner messages for the wizard.\n *\n * Every step has BOTH a success and a failure message, and the orchestrator\n * picks between them from the step's actual result. A spinner that can only\n * stop with a cheerful message is a spinner that lies.\n */\nexport const spinnerMessages = {\n installingDeps: \"Summoning dependencies...\",\n depsInstalled: \"Dependencies materialized!\",\n depsFailed: \"Dependencies could not be installed\",\n\n initializingGit: \"Initializing grimoire (git)...\",\n gitInitialized: \"Grimoire initialized!\",\n gitFailed: \"Git repository was not initialized\",\n\n generatingJwt: \"Forging secret keys...\",\n jwtGenerated: \"Secret keys forged!\",\n jwtFailed: \"Secret keys were NOT generated\",\n\n warmingCache: \"Charging magical circuits...\",\n cacheWarmed: \"Circuits charged!\",\n cacheWarmFailed:\n \"Cache could not be warmed (harmless — it builds on first run)\",\n\n addingFeatures: \"Weaving in your features...\",\n featuresAdded: \"Features woven in!\",\n featuresPartial: \"Some features were not added\",\n featuresFailed: \"No features could be added\",\n\n copyingTemplate: \"Preparing your spellbook...\",\n templateCopied: \"Spellbook ready!\",\n templateFailed: \"The project template could not be copied\",\n} as const;\n"],"mappings":";;;;;;;;AAOA,MAAa,kBAAkB;CAC7B,gBAAgB;CAChB,eAAe;CACf,YAAY;CAEZ,iBAAiB;CACjB,gBAAgB;CAChB,WAAW;CAEX,eAAe;CACf,cAAc;CACd,WAAW;CAEX,cAAc;CACd,aAAa;CACb,iBACE;CAEF,gBAAgB;CAChB,eAAe;CACf,iBAAiB;CACjB,gBAAgB;CAEhB,iBAAiB;CACjB,gBAAgB;CAChB,gBAAgB;AAClB"}