mirror of
https://github.com/FranP-code/create-better-t-stack.git
synced 2025-10-12 23:52:15 +00:00
feat(cli): update ultracite rules and add autocomplete multiselect in ultracite and ruler
This commit is contained in:
@@ -66,7 +66,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@biomejs/js-api": "^3.0.0",
|
"@biomejs/js-api": "^3.0.0",
|
||||||
"@biomejs/wasm-nodejs": "^2.2.0",
|
"@biomejs/wasm-nodejs": "^2.2.0",
|
||||||
"@clack/prompts": "^0.11.0",
|
"@clack/prompts": "^1.0.0-alpha.4",
|
||||||
"consola": "^3.4.2",
|
"consola": "^3.4.2",
|
||||||
"execa": "^9.6.0",
|
"execa": "^9.6.0",
|
||||||
"fs-extra": "^11.3.1",
|
"fs-extra": "^11.3.1",
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { isCancel, log, multiselect, spinner } from "@clack/prompts";
|
import {
|
||||||
|
isCancel,
|
||||||
|
log,
|
||||||
|
autocompleteMultiselect,
|
||||||
|
spinner,
|
||||||
|
} from "@clack/prompts";
|
||||||
import { execa } from "execa";
|
import { execa } from "execa";
|
||||||
import fs from "fs-extra";
|
import fs from "fs-extra";
|
||||||
import pc from "picocolors";
|
import pc from "picocolors";
|
||||||
@@ -61,14 +66,16 @@ export async function setupVibeRules(config: ProjectConfig) {
|
|||||||
opencode: { label: "OpenCode" },
|
opencode: { label: "OpenCode" },
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
const selectedEditors = await multiselect<keyof typeof EDITORS>({
|
const selectedEditors = await autocompleteMultiselect<keyof typeof EDITORS>(
|
||||||
message: "Select AI assistants for Ruler",
|
{
|
||||||
options: Object.entries(EDITORS).map(([key, v]) => ({
|
message: "Select AI assistants for Ruler",
|
||||||
value: key as keyof typeof EDITORS,
|
options: Object.entries(EDITORS).map(([key, v]) => ({
|
||||||
label: v.label,
|
value: key as keyof typeof EDITORS,
|
||||||
})),
|
label: v.label,
|
||||||
required: false,
|
})),
|
||||||
});
|
required: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
if (isCancel(selectedEditors)) return exitCancelled("Operation cancelled");
|
if (isCancel(selectedEditors)) return exitCancelled("Operation cancelled");
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
import { isCancel, log, multiselect } from "@clack/prompts";
|
import {
|
||||||
|
autocompleteMultiselect,
|
||||||
|
group,
|
||||||
|
log,
|
||||||
|
multiselect,
|
||||||
|
} from "@clack/prompts";
|
||||||
import { execa } from "execa";
|
import { execa } from "execa";
|
||||||
import pc from "picocolors";
|
import pc from "picocolors";
|
||||||
import type { ProjectConfig } from "../../types";
|
import type { ProjectConfig } from "../../types";
|
||||||
@@ -14,43 +19,79 @@ type UltraciteRule =
|
|||||||
| "windsurf"
|
| "windsurf"
|
||||||
| "zed"
|
| "zed"
|
||||||
| "claude"
|
| "claude"
|
||||||
| "codex";
|
| "codex"
|
||||||
|
| "kiro"
|
||||||
|
| "cline"
|
||||||
|
| "amp"
|
||||||
|
| "aider"
|
||||||
|
| "firebase-studio"
|
||||||
|
| "open-hands"
|
||||||
|
| "gemini-cli"
|
||||||
|
| "junie"
|
||||||
|
| "augmentcode"
|
||||||
|
| "kilo-code"
|
||||||
|
| "goose";
|
||||||
|
|
||||||
const EDITORS = {
|
const EDITORS = {
|
||||||
vscode: {
|
vscode: {
|
||||||
label: "VSCode / Cursor / Windsurf",
|
label: "VSCode / Cursor / Windsurf",
|
||||||
hint: "Visual Studio Code editor configuration",
|
|
||||||
},
|
},
|
||||||
zed: {
|
zed: {
|
||||||
label: "Zed",
|
label: "Zed",
|
||||||
hint: "Zed editor configuration",
|
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
const RULES = {
|
const RULES = {
|
||||||
"vscode-copilot": {
|
"vscode-copilot": {
|
||||||
label: "VS Code Copilot",
|
label: "VS Code Copilot",
|
||||||
hint: "GitHub Copilot integration for VS Code",
|
|
||||||
},
|
},
|
||||||
cursor: {
|
cursor: {
|
||||||
label: "Cursor",
|
label: "Cursor",
|
||||||
hint: "Cursor AI editor configuration",
|
|
||||||
},
|
},
|
||||||
windsurf: {
|
windsurf: {
|
||||||
label: "Windsurf",
|
label: "Windsurf",
|
||||||
hint: "Windsurf editor configuration",
|
|
||||||
},
|
},
|
||||||
zed: {
|
zed: {
|
||||||
label: "Zed",
|
label: "Zed",
|
||||||
hint: "Zed editor rules",
|
|
||||||
},
|
},
|
||||||
claude: {
|
claude: {
|
||||||
label: "Claude",
|
label: "Claude",
|
||||||
hint: "Claude AI integration",
|
|
||||||
},
|
},
|
||||||
codex: {
|
codex: {
|
||||||
label: "Codex",
|
label: "Codex",
|
||||||
hint: "Codex AI integration",
|
},
|
||||||
|
kiro: {
|
||||||
|
label: "Kiro",
|
||||||
|
},
|
||||||
|
cline: {
|
||||||
|
label: "Cline",
|
||||||
|
},
|
||||||
|
amp: {
|
||||||
|
label: "Amp",
|
||||||
|
},
|
||||||
|
aider: {
|
||||||
|
label: "Aider",
|
||||||
|
},
|
||||||
|
"firebase-studio": {
|
||||||
|
label: "Firebase Studio",
|
||||||
|
},
|
||||||
|
"open-hands": {
|
||||||
|
label: "Open Hands",
|
||||||
|
},
|
||||||
|
"gemini-cli": {
|
||||||
|
label: "Gemini CLI",
|
||||||
|
},
|
||||||
|
junie: {
|
||||||
|
label: "Junie",
|
||||||
|
},
|
||||||
|
augmentcode: {
|
||||||
|
label: "AugmentCode",
|
||||||
|
},
|
||||||
|
"kilo-code": {
|
||||||
|
label: "Kilo Code",
|
||||||
|
},
|
||||||
|
goose: {
|
||||||
|
label: "Goose",
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
@@ -62,29 +103,36 @@ export async function setupUltracite(config: ProjectConfig, hasHusky: boolean) {
|
|||||||
|
|
||||||
await setupBiome(projectDir);
|
await setupBiome(projectDir);
|
||||||
|
|
||||||
const editors = await multiselect<UltraciteEditor>({
|
const result = await group(
|
||||||
message: "Choose editors",
|
{
|
||||||
options: Object.entries(EDITORS).map(([key, editor]) => ({
|
editors: () =>
|
||||||
value: key as UltraciteEditor,
|
multiselect<UltraciteEditor>({
|
||||||
label: editor.label,
|
message: "Choose editors",
|
||||||
hint: editor.hint,
|
options: Object.entries(EDITORS).map(([key, editor]) => ({
|
||||||
})),
|
value: key as UltraciteEditor,
|
||||||
required: true,
|
label: editor.label,
|
||||||
});
|
})),
|
||||||
|
required: true,
|
||||||
|
}),
|
||||||
|
rules: () =>
|
||||||
|
autocompleteMultiselect<UltraciteRule>({
|
||||||
|
message: "Choose rules",
|
||||||
|
options: Object.entries(RULES).map(([key, rule]) => ({
|
||||||
|
value: key as UltraciteRule,
|
||||||
|
label: rule.label,
|
||||||
|
})),
|
||||||
|
required: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onCancel: () => {
|
||||||
|
exitCancelled("Operation cancelled");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
if (isCancel(editors)) return exitCancelled("Operation cancelled");
|
const editors = result.editors as UltraciteEditor[];
|
||||||
|
const rules = result.rules as UltraciteRule[];
|
||||||
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: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isCancel(rules)) return exitCancelled("Operation cancelled");
|
|
||||||
|
|
||||||
const ultraciteArgs = ["init", "--pm", packageManager];
|
const ultraciteArgs = ["init", "--pm", packageManager];
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export async function getProjectName(initialName?: string): Promise<string> {
|
|||||||
initialValue: initialName,
|
initialValue: initialName,
|
||||||
defaultValue: defaultName,
|
defaultValue: defaultName,
|
||||||
validate: (value) => {
|
validate: (value) => {
|
||||||
const nameToUse = value.trim() || defaultName;
|
const nameToUse = String(value ?? "").trim() || defaultName;
|
||||||
|
|
||||||
const finalDirName = path.basename(nameToUse);
|
const finalDirName = path.basename(nameToUse);
|
||||||
const validationError = validateDirectoryName(finalDirName);
|
const validationError = validateDirectoryName(finalDirName);
|
||||||
|
|||||||
6
bun.lock
6
bun.lock
@@ -22,7 +22,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@biomejs/js-api": "^3.0.0",
|
"@biomejs/js-api": "^3.0.0",
|
||||||
"@biomejs/wasm-nodejs": "^2.2.0",
|
"@biomejs/wasm-nodejs": "^2.2.0",
|
||||||
"@clack/prompts": "^0.11.0",
|
"@clack/prompts": "^1.0.0-alpha.4",
|
||||||
"consola": "^3.4.2",
|
"consola": "^3.4.2",
|
||||||
"execa": "^9.6.0",
|
"execa": "^9.6.0",
|
||||||
"fs-extra": "^11.3.1",
|
"fs-extra": "^11.3.1",
|
||||||
@@ -273,9 +273,9 @@
|
|||||||
|
|
||||||
"@biomejs/wasm-nodejs": ["@biomejs/wasm-nodejs@2.2.0", "", {}, "sha512-jTN0IdKqt8EOPAzMGYKzeNykOKljZBRwABO2N6rEaC5CzJEhS3CuApdjqWpK/TMsVfw694gA3qhNNRhyFI2mWg=="],
|
"@biomejs/wasm-nodejs": ["@biomejs/wasm-nodejs@2.2.0", "", {}, "sha512-jTN0IdKqt8EOPAzMGYKzeNykOKljZBRwABO2N6rEaC5CzJEhS3CuApdjqWpK/TMsVfw694gA3qhNNRhyFI2mWg=="],
|
||||||
|
|
||||||
"@clack/core": ["@clack/core@0.5.0", "", { "dependencies": { "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow=="],
|
"@clack/core": ["@clack/core@1.0.0-alpha.4", "", { "dependencies": { "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-VCtU+vjyKPMSakVrB9q1bOnXN7QW/w4+YQDQCOF59GrzydW+169i0fVx/qzRRXJgt8KGj/pZZ/JxXroFZIDByg=="],
|
||||||
|
|
||||||
"@clack/prompts": ["@clack/prompts@0.11.0", "", { "dependencies": { "@clack/core": "0.5.0", "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw=="],
|
"@clack/prompts": ["@clack/prompts@1.0.0-alpha.4", "", { "dependencies": { "@clack/core": "1.0.0-alpha.4", "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-KnmtDF2xQGoI5AlBme9akHtvCRV0RKAARUXHBQO2tMwnY8B08/4zPWigT7uLK25UPrMCEqnyQPkKRjNdhPbf8g=="],
|
||||||
|
|
||||||
"@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.0", "", { "dependencies": { "mime": "^3.0.0" } }, "sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA=="],
|
"@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.0", "", { "dependencies": { "mime": "^3.0.0" } }, "sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA=="],
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user