mirror of
https://github.com/FranP-code/create-better-t-stack.git
synced 2025-10-12 23:52:15 +00:00
132 lines
3.0 KiB
TypeScript
132 lines
3.0 KiB
TypeScript
import { isCancel, log, multiselect } from "@clack/prompts";
|
|
import { execa } from "execa";
|
|
import pc from "picocolors";
|
|
import type { ProjectConfig } from "../../types";
|
|
import { addPackageDependency } from "../../utils/add-package-deps";
|
|
import { exitCancelled } from "../../utils/errors";
|
|
import { getPackageExecutionCommand } from "../../utils/package-runner";
|
|
import { setupBiome } from "./addons-setup";
|
|
|
|
type UltraciteEditor = "vscode" | "zed";
|
|
type UltraciteRule =
|
|
| "vscode-copilot"
|
|
| "cursor"
|
|
| "windsurf"
|
|
| "zed"
|
|
| "claude"
|
|
| "codex";
|
|
|
|
const EDITORS = {
|
|
vscode: {
|
|
label: "VSCode / Cursor / Windsurf",
|
|
hint: "Visual Studio Code editor configuration",
|
|
},
|
|
zed: {
|
|
label: "Zed",
|
|
hint: "Zed editor configuration",
|
|
},
|
|
} as const;
|
|
|
|
const RULES = {
|
|
"vscode-copilot": {
|
|
label: "VS Code Copilot",
|
|
hint: "GitHub Copilot integration for VS Code",
|
|
},
|
|
cursor: {
|
|
label: "Cursor",
|
|
hint: "Cursor AI editor configuration",
|
|
},
|
|
windsurf: {
|
|
label: "Windsurf",
|
|
hint: "Windsurf editor configuration",
|
|
},
|
|
zed: {
|
|
label: "Zed",
|
|
hint: "Zed editor rules",
|
|
},
|
|
claude: {
|
|
label: "Claude",
|
|
hint: "Claude AI integration",
|
|
},
|
|
codex: {
|
|
label: "Codex",
|
|
hint: "Codex AI integration",
|
|
},
|
|
} as const;
|
|
|
|
export async function setupUltracite(config: ProjectConfig, hasHusky: boolean) {
|
|
const { packageManager, projectDir } = config;
|
|
|
|
try {
|
|
log.info("Setting up Ultracite...");
|
|
|
|
await setupBiome(projectDir);
|
|
|
|
const editors = await multiselect<UltraciteEditor>({
|
|
message: "Choose editors",
|
|
options: Object.entries(EDITORS).map(([key, editor]) => ({
|
|
value: key as UltraciteEditor,
|
|
label: editor.label,
|
|
hint: editor.hint,
|
|
})),
|
|
required: false,
|
|
});
|
|
|
|
if (isCancel(editors)) return exitCancelled("Operation cancelled");
|
|
|
|
const rules = await multiselect<UltraciteRule>({
|
|
message: "Choose rules",
|
|
options: Object.entries(RULES).map(([key, rule]) => ({
|
|
value: key as UltraciteRule,
|
|
label: rule.label,
|
|
hint: rule.hint,
|
|
})),
|
|
required: false,
|
|
});
|
|
|
|
if (isCancel(rules)) return exitCancelled("Operation cancelled");
|
|
|
|
const ultraciteArgs = ["init", "--pm", packageManager];
|
|
|
|
if (editors.length > 0) {
|
|
ultraciteArgs.push("--editors", ...editors);
|
|
}
|
|
|
|
if (rules.length > 0) {
|
|
ultraciteArgs.push("--rules", ...rules);
|
|
}
|
|
|
|
if (hasHusky) {
|
|
ultraciteArgs.push("--features", "husky", "lint-staged");
|
|
}
|
|
|
|
const ultraciteArgsString = ultraciteArgs.join(" ");
|
|
const commandWithArgs = `ultracite@latest ${ultraciteArgsString} --skip-install`;
|
|
|
|
const ultraciteInitCommand = getPackageExecutionCommand(
|
|
packageManager,
|
|
commandWithArgs,
|
|
);
|
|
|
|
await execa(ultraciteInitCommand, {
|
|
cwd: projectDir,
|
|
env: { CI: "true" },
|
|
shell: true,
|
|
});
|
|
|
|
if (hasHusky) {
|
|
await addPackageDependency({
|
|
devDependencies: ["husky", "lint-staged"],
|
|
projectDir,
|
|
});
|
|
}
|
|
|
|
log.success("Ultracite setup successfully!");
|
|
} catch (error) {
|
|
log.error(pc.red("Failed to set up Ultracite"));
|
|
if (error instanceof Error) {
|
|
console.error(pc.red(error.message));
|
|
}
|
|
}
|
|
}
|