@getcoherent/cli 0.6.45 → 0.6.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-U6M76BKY.js +50 -0
- package/dist/chunk-XPBD3L7V.js +260 -0
- package/dist/index.js +249 -181
- package/dist/tsc-ai-fix-O3EMRWV2.js +98 -0
- package/dist/tsc-autofix-S5PKMFSC.js +16 -0
- package/package.json +10 -10
- package/LICENSE +0 -21
package/dist/index.js
CHANGED
|
@@ -53,6 +53,10 @@ import {
|
|
|
53
53
|
savePlan,
|
|
54
54
|
updateArchitecturePlan
|
|
55
55
|
} from "./chunk-VLBVBF6V.js";
|
|
56
|
+
import {
|
|
57
|
+
isValidTsx,
|
|
58
|
+
safeWrite
|
|
59
|
+
} from "./chunk-U6M76BKY.js";
|
|
56
60
|
import {
|
|
57
61
|
toKebabCase,
|
|
58
62
|
toTitleCase
|
|
@@ -5018,6 +5022,70 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
|
|
|
5018
5022
|
allFixes.forEach((f) => console.log(chalk8.dim(` ${f}`)));
|
|
5019
5023
|
}
|
|
5020
5024
|
await writeFile(filePath, codeToWrite);
|
|
5025
|
+
try {
|
|
5026
|
+
const { runTscCheck, applyDeterministicFixes } = await import("./tsc-autofix-S5PKMFSC.js");
|
|
5027
|
+
const tscBackups = /* @__PURE__ */ new Map();
|
|
5028
|
+
const relPath = filePath.replace(projectRoot + "/", "").replace(projectRoot + "\\", "");
|
|
5029
|
+
const tscErrors = runTscCheck(projectRoot).filter((e) => e.file === relPath);
|
|
5030
|
+
if (tscErrors.length > 0) {
|
|
5031
|
+
const bestSnapshot = codeToWrite;
|
|
5032
|
+
const detResult = await applyDeterministicFixes(tscErrors, projectRoot, tscBackups);
|
|
5033
|
+
let bestErrorCount = Math.min(tscErrors.length, tscErrors.length - detResult.fixed.length);
|
|
5034
|
+
if (detResult.fixed.length > 0) {
|
|
5035
|
+
codeToWrite = await readFile(filePath);
|
|
5036
|
+
console.log(
|
|
5037
|
+
chalk8.green(` \u2714 Fixed ${tscErrors.length - detResult.remaining.length} TypeScript error(s)`)
|
|
5038
|
+
);
|
|
5039
|
+
}
|
|
5040
|
+
if (detResult.remaining.length > 0 && aiProvider) {
|
|
5041
|
+
try {
|
|
5042
|
+
const ai = await createAIProvider(aiProvider);
|
|
5043
|
+
if (ai.editPageCode) {
|
|
5044
|
+
const errorList = detResult.remaining.map((e) => `Line ${e.line}: [${e.code}] ${e.message.split("\n")[0]}`).join("\n");
|
|
5045
|
+
const tscFixed = await ai.editPageCode(
|
|
5046
|
+
codeToWrite,
|
|
5047
|
+
`Fix these TypeScript errors:
|
|
5048
|
+
${errorList}
|
|
5049
|
+
|
|
5050
|
+
Keep all existing functionality intact.`,
|
|
5051
|
+
page.name || page.id || "Page"
|
|
5052
|
+
);
|
|
5053
|
+
if (tscFixed && tscFixed.length > 100) {
|
|
5054
|
+
const { code: reFixed } = await autoFixCode(tscFixed, autoFixCtx);
|
|
5055
|
+
await writeFile(filePath, reFixed);
|
|
5056
|
+
const afterErrors = runTscCheck(projectRoot).filter((e) => e.file === relPath);
|
|
5057
|
+
if (afterErrors.length > bestErrorCount) {
|
|
5058
|
+
await writeFile(filePath, bestSnapshot);
|
|
5059
|
+
codeToWrite = bestSnapshot;
|
|
5060
|
+
console.log(
|
|
5061
|
+
chalk8.yellow(` \u26A0 AI fix regressed TypeScript errors. Reverted to best version.`)
|
|
5062
|
+
);
|
|
5063
|
+
} else {
|
|
5064
|
+
codeToWrite = reFixed;
|
|
5065
|
+
console.log(
|
|
5066
|
+
chalk8.green(
|
|
5067
|
+
` \u2714 Fixed ${detResult.remaining.length - afterErrors.length} TypeScript error(s) via AI`
|
|
5068
|
+
)
|
|
5069
|
+
);
|
|
5070
|
+
}
|
|
5071
|
+
}
|
|
5072
|
+
}
|
|
5073
|
+
} catch (tscAiErr) {
|
|
5074
|
+
console.log(
|
|
5075
|
+
chalk8.dim(
|
|
5076
|
+
` \u26A0 AI tsc fix skipped: ${tscAiErr instanceof Error ? tscAiErr.message : "unknown"}`
|
|
5077
|
+
)
|
|
5078
|
+
);
|
|
5079
|
+
}
|
|
5080
|
+
}
|
|
5081
|
+
}
|
|
5082
|
+
} catch (tscErr) {
|
|
5083
|
+
console.log(
|
|
5084
|
+
chalk8.dim(
|
|
5085
|
+
` \u26A0 TypeScript check skipped: ${tscErr instanceof Error ? tscErr.message : "unknown"}`
|
|
5086
|
+
)
|
|
5087
|
+
);
|
|
5088
|
+
}
|
|
5021
5089
|
const pageIdx = dsm.getConfig().pages.findIndex((p) => p.id === page.id);
|
|
5022
5090
|
if (pageIdx !== -1) {
|
|
5023
5091
|
const cfg = dsm.getConfig();
|
|
@@ -8084,8 +8152,8 @@ async function regenerateDocsCommand() {
|
|
|
8084
8152
|
|
|
8085
8153
|
// src/commands/fix.ts
|
|
8086
8154
|
import chalk15 from "chalk";
|
|
8087
|
-
import { readdirSync as readdirSync7, readFileSync as
|
|
8088
|
-
import { resolve as resolve8, join as
|
|
8155
|
+
import { readdirSync as readdirSync7, readFileSync as readFileSync10, existsSync as existsSync14, rmSync as rmSync5, mkdirSync as mkdirSync7 } from "fs";
|
|
8156
|
+
import { resolve as resolve8, join as join11, relative as relative5, basename as basename3 } from "path";
|
|
8089
8157
|
import {
|
|
8090
8158
|
DesignSystemManager as DesignSystemManager9,
|
|
8091
8159
|
ComponentManager as ComponentManager5,
|
|
@@ -8094,54 +8162,6 @@ import {
|
|
|
8094
8162
|
loadManifest as loadManifest9,
|
|
8095
8163
|
saveManifest as saveManifest5
|
|
8096
8164
|
} from "@getcoherent/core";
|
|
8097
|
-
|
|
8098
|
-
// src/commands/fix-validation.ts
|
|
8099
|
-
import { createRequire } from "module";
|
|
8100
|
-
import { existsSync as existsSync14, readFileSync as readFileSync10, writeFileSync as writeFileSync9 } from "fs";
|
|
8101
|
-
import { join as join11 } from "path";
|
|
8102
|
-
var cachedTs = null;
|
|
8103
|
-
var cachedProjectRoot = null;
|
|
8104
|
-
function isValidTsx(code, projectRoot, ext = ".tsx") {
|
|
8105
|
-
if (ext !== ".tsx" && ext !== ".ts") return true;
|
|
8106
|
-
const pkgJson = join11(projectRoot, "package.json");
|
|
8107
|
-
if (!existsSync14(pkgJson)) return true;
|
|
8108
|
-
try {
|
|
8109
|
-
if (!cachedTs || cachedProjectRoot !== projectRoot) {
|
|
8110
|
-
const req = createRequire(pkgJson);
|
|
8111
|
-
cachedTs = req("typescript");
|
|
8112
|
-
cachedProjectRoot = projectRoot;
|
|
8113
|
-
}
|
|
8114
|
-
const sf = cachedTs.createSourceFile(
|
|
8115
|
-
"check.tsx",
|
|
8116
|
-
code,
|
|
8117
|
-
cachedTs.ScriptTarget.Latest,
|
|
8118
|
-
false,
|
|
8119
|
-
cachedTs.ScriptKind.TSX
|
|
8120
|
-
);
|
|
8121
|
-
const diagnostics = sf.parseDiagnostics;
|
|
8122
|
-
return !diagnostics || diagnostics.length === 0;
|
|
8123
|
-
} catch {
|
|
8124
|
-
return true;
|
|
8125
|
-
}
|
|
8126
|
-
}
|
|
8127
|
-
function safeWrite(filePath, newContent, projectRoot, backups) {
|
|
8128
|
-
if (!backups.has(filePath)) {
|
|
8129
|
-
try {
|
|
8130
|
-
backups.set(filePath, readFileSync10(filePath, "utf-8"));
|
|
8131
|
-
} catch {
|
|
8132
|
-
}
|
|
8133
|
-
}
|
|
8134
|
-
const ext = filePath.slice(filePath.lastIndexOf("."));
|
|
8135
|
-
writeFileSync9(filePath, newContent, "utf-8");
|
|
8136
|
-
if (!isValidTsx(newContent, projectRoot, ext)) {
|
|
8137
|
-
const original = backups.get(filePath);
|
|
8138
|
-
if (original) writeFileSync9(filePath, original, "utf-8");
|
|
8139
|
-
return { ok: false };
|
|
8140
|
-
}
|
|
8141
|
-
return { ok: true };
|
|
8142
|
-
}
|
|
8143
|
-
|
|
8144
|
-
// src/commands/fix.ts
|
|
8145
8165
|
function extractComponentIdsFromCode2(code) {
|
|
8146
8166
|
const ids = /* @__PURE__ */ new Set();
|
|
8147
8167
|
const allMatches = code.matchAll(/@\/components\/((?:ui\/)?[a-z0-9-]+)/g);
|
|
@@ -8159,7 +8179,7 @@ function listTsxFiles(dir) {
|
|
|
8159
8179
|
try {
|
|
8160
8180
|
const entries = readdirSync7(dir, { withFileTypes: true });
|
|
8161
8181
|
for (const e of entries) {
|
|
8162
|
-
const full =
|
|
8182
|
+
const full = join11(dir, e.name);
|
|
8163
8183
|
if (e.isDirectory() && e.name !== "node_modules" && !e.name.startsWith(".")) {
|
|
8164
8184
|
files.push(...listTsxFiles(full));
|
|
8165
8185
|
} else if (e.isFile() && e.name.endsWith(".tsx")) {
|
|
@@ -8190,8 +8210,8 @@ async function fixCommand(opts = {}) {
|
|
|
8190
8210
|
console.log(chalk15.cyan("\ncoherent fix\n"));
|
|
8191
8211
|
}
|
|
8192
8212
|
if (!skipCache) {
|
|
8193
|
-
const nextDir =
|
|
8194
|
-
if (
|
|
8213
|
+
const nextDir = join11(projectRoot, ".next");
|
|
8214
|
+
if (existsSync14(nextDir)) {
|
|
8195
8215
|
if (!dryRun) rmSync5(nextDir, { recursive: true, force: true });
|
|
8196
8216
|
fixes.push("Cleared build cache");
|
|
8197
8217
|
console.log(chalk15.green(" \u2714 Cleared build cache"));
|
|
@@ -8218,7 +8238,7 @@ async function fixCommand(opts = {}) {
|
|
|
8218
8238
|
const componentsTsxFiles = listTsxFiles(resolve8(projectRoot, "components"));
|
|
8219
8239
|
const allComponentIds = /* @__PURE__ */ new Set();
|
|
8220
8240
|
for (const file of [...allTsxFiles, ...componentsTsxFiles]) {
|
|
8221
|
-
const content =
|
|
8241
|
+
const content = readFileSync10(file, "utf-8");
|
|
8222
8242
|
extractComponentIdsFromCode2(content).forEach((id) => allComponentIds.add(id));
|
|
8223
8243
|
}
|
|
8224
8244
|
let dsm = null;
|
|
@@ -8238,7 +8258,7 @@ async function fixCommand(opts = {}) {
|
|
|
8238
8258
|
} else {
|
|
8239
8259
|
const fileName = toKebabCase(id) + ".tsx";
|
|
8240
8260
|
const filePath = resolve8(projectRoot, "components", "ui", fileName);
|
|
8241
|
-
if (!
|
|
8261
|
+
if (!existsSync14(filePath)) missingFiles.push(id);
|
|
8242
8262
|
}
|
|
8243
8263
|
}
|
|
8244
8264
|
const provider = getComponentProvider();
|
|
@@ -8287,7 +8307,7 @@ async function fixCommand(opts = {}) {
|
|
|
8287
8307
|
}
|
|
8288
8308
|
}
|
|
8289
8309
|
}
|
|
8290
|
-
if (!dsm &&
|
|
8310
|
+
if (!dsm && existsSync14(project.configPath)) {
|
|
8291
8311
|
dsm = new DesignSystemManager9(project.configPath);
|
|
8292
8312
|
await dsm.load();
|
|
8293
8313
|
}
|
|
@@ -8296,8 +8316,8 @@ async function fixCommand(opts = {}) {
|
|
|
8296
8316
|
let derivedName = null;
|
|
8297
8317
|
try {
|
|
8298
8318
|
const pkgPath = resolve8(projectRoot, "package.json");
|
|
8299
|
-
if (
|
|
8300
|
-
const pkg = JSON.parse(
|
|
8319
|
+
if (existsSync14(pkgPath)) {
|
|
8320
|
+
const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
|
|
8301
8321
|
if (typeof pkg.name === "string" && pkg.name) {
|
|
8302
8322
|
derivedName = toTitleCase2(pkg.name);
|
|
8303
8323
|
}
|
|
@@ -8334,8 +8354,8 @@ async function fixCommand(opts = {}) {
|
|
|
8334
8354
|
const configName = dsm.getConfig().name;
|
|
8335
8355
|
if (configName && configName !== "My App") {
|
|
8336
8356
|
const appLayoutPath = resolve8(projectRoot, "app", "(app)", "layout.tsx");
|
|
8337
|
-
if (
|
|
8338
|
-
let appLayoutCode =
|
|
8357
|
+
if (existsSync14(appLayoutPath)) {
|
|
8358
|
+
let appLayoutCode = readFileSync10(appLayoutPath, "utf-8");
|
|
8339
8359
|
if (appLayoutCode.includes("My App")) {
|
|
8340
8360
|
appLayoutCode = appLayoutCode.replace(/My App/g, configName);
|
|
8341
8361
|
if (!dryRun) {
|
|
@@ -8353,11 +8373,11 @@ async function fixCommand(opts = {}) {
|
|
|
8353
8373
|
}
|
|
8354
8374
|
}
|
|
8355
8375
|
const sharedDir = resolve8(projectRoot, "components", "shared");
|
|
8356
|
-
if (
|
|
8376
|
+
if (existsSync14(sharedDir)) {
|
|
8357
8377
|
try {
|
|
8358
8378
|
for (const f of readdirSync7(sharedDir).filter((n) => n.endsWith(".tsx"))) {
|
|
8359
|
-
const sharedPath =
|
|
8360
|
-
const sharedCode =
|
|
8379
|
+
const sharedPath = join11(sharedDir, f);
|
|
8380
|
+
const sharedCode = readFileSync10(sharedPath, "utf-8");
|
|
8361
8381
|
if (sharedCode.includes("My App")) {
|
|
8362
8382
|
const updated = sharedCode.replace(/My App/g, configName);
|
|
8363
8383
|
if (!dryRun) {
|
|
@@ -8381,7 +8401,7 @@ async function fixCommand(opts = {}) {
|
|
|
8381
8401
|
let syntaxFixed = 0;
|
|
8382
8402
|
for (const file of userTsxFiles) {
|
|
8383
8403
|
try {
|
|
8384
|
-
const content =
|
|
8404
|
+
const content = readFileSync10(file, "utf-8");
|
|
8385
8405
|
const fixed = fixUnescapedLtInJsx(
|
|
8386
8406
|
fixEscapedClosingQuotes(sanitizeMetadataStrings(ensureUseClientIfNeeded(content)))
|
|
8387
8407
|
);
|
|
@@ -8399,7 +8419,9 @@ async function fixCommand(opts = {}) {
|
|
|
8399
8419
|
}
|
|
8400
8420
|
}
|
|
8401
8421
|
} catch (err) {
|
|
8402
|
-
remaining.push(
|
|
8422
|
+
remaining.push(
|
|
8423
|
+
`${relative5(projectRoot, file)}: syntax fix error \u2014 ${err instanceof Error ? err.message : "unknown"}`
|
|
8424
|
+
);
|
|
8403
8425
|
}
|
|
8404
8426
|
}
|
|
8405
8427
|
if (syntaxFixed > 0) {
|
|
@@ -8422,7 +8444,7 @@ async function fixCommand(opts = {}) {
|
|
|
8422
8444
|
console.log(chalk15.green(` \u2714 Verified group layouts: ${layoutTypes}`));
|
|
8423
8445
|
const hasSidebar = plan.groups.some((g) => g.layout === "sidebar" || g.layout === "both");
|
|
8424
8446
|
const sidebarPath = resolve8(projectRoot, "components", "shared", "sidebar.tsx");
|
|
8425
|
-
if (hasSidebar && !
|
|
8447
|
+
if (hasSidebar && !existsSync14(sidebarPath) && !dryRun) {
|
|
8426
8448
|
if (!dsm) {
|
|
8427
8449
|
dsm = new DesignSystemManager9(project.configPath);
|
|
8428
8450
|
await dsm.load();
|
|
@@ -8441,8 +8463,8 @@ async function fixCommand(opts = {}) {
|
|
|
8441
8463
|
}
|
|
8442
8464
|
if (hasSidebar && !dryRun) {
|
|
8443
8465
|
const rootLayoutPath = resolve8(projectRoot, "app", "layout.tsx");
|
|
8444
|
-
if (
|
|
8445
|
-
let rootCode =
|
|
8466
|
+
if (existsSync14(rootLayoutPath)) {
|
|
8467
|
+
let rootCode = readFileSync10(rootLayoutPath, "utf-8");
|
|
8446
8468
|
if (rootCode.includes("<Header")) {
|
|
8447
8469
|
rootCode = rootCode.replace(/import\s*\{[^}]*Header[^}]*\}[^;\n]*[;\n]?\s*/g, "").replace(/import\s*\{[^}]*Footer[^}]*\}[^;\n]*[;\n]?\s*/g, "").replace(/import\s+ShowWhenNotAuthRoute[^;\n]*[;\n]?\s*/g, "").replace(/<ShowWhenNotAuthRoute>[\s\S]*?<\/ShowWhenNotAuthRoute>/g, (match) => {
|
|
8448
8470
|
const inner = match.replace(/<\/?ShowWhenNotAuthRoute>/g, "").trim();
|
|
@@ -8460,8 +8482,8 @@ async function fixCommand(opts = {}) {
|
|
|
8460
8482
|
}
|
|
8461
8483
|
}
|
|
8462
8484
|
const publicLayoutPath = resolve8(projectRoot, "app", "(public)", "layout.tsx");
|
|
8463
|
-
const publicExists =
|
|
8464
|
-
const needsPublicLayout = !publicExists || !
|
|
8485
|
+
const publicExists = existsSync14(publicLayoutPath);
|
|
8486
|
+
const needsPublicLayout = !publicExists || !readFileSync10(publicLayoutPath, "utf-8").includes("<Header");
|
|
8465
8487
|
if (needsPublicLayout) {
|
|
8466
8488
|
const { buildPublicLayoutCodeForSidebar } = await import("./code-generator-YSGVHVNN.js");
|
|
8467
8489
|
mkdirSync7(resolve8(projectRoot, "app", "(public)"), { recursive: true });
|
|
@@ -8474,8 +8496,8 @@ async function fixCommand(opts = {}) {
|
|
|
8474
8496
|
}
|
|
8475
8497
|
}
|
|
8476
8498
|
const sidebarComponentPath2 = resolve8(projectRoot, "components", "shared", "sidebar.tsx");
|
|
8477
|
-
if (
|
|
8478
|
-
const existingSidebarCode =
|
|
8499
|
+
if (existsSync14(sidebarComponentPath2)) {
|
|
8500
|
+
const existingSidebarCode = readFileSync10(sidebarComponentPath2, "utf-8");
|
|
8479
8501
|
const sidebarConfigName = dsm?.getConfig().name ?? "";
|
|
8480
8502
|
const hasWrongName = existingSidebarCode.includes("My App") && sidebarConfigName !== "My App";
|
|
8481
8503
|
const hasTrigger = existingSidebarCode.includes("SidebarTrigger");
|
|
@@ -8503,7 +8525,7 @@ async function fixCommand(opts = {}) {
|
|
|
8503
8525
|
}
|
|
8504
8526
|
const rootPagePath = resolve8(projectRoot, "app", "page.tsx");
|
|
8505
8527
|
const publicPagePath = resolve8(projectRoot, "app", "(public)", "page.tsx");
|
|
8506
|
-
if (
|
|
8528
|
+
if (existsSync14(rootPagePath) && !existsSync14(publicPagePath)) {
|
|
8507
8529
|
const { renameSync } = await import("fs");
|
|
8508
8530
|
mkdirSync7(resolve8(projectRoot, "app", "(public)"), { recursive: true });
|
|
8509
8531
|
renameSync(rootPagePath, publicPagePath);
|
|
@@ -8511,7 +8533,7 @@ async function fixCommand(opts = {}) {
|
|
|
8511
8533
|
console.log(chalk15.green(" \u2714 Moved app/page.tsx \u2192 app/(public)/page.tsx (gets Header/Footer)"));
|
|
8512
8534
|
}
|
|
8513
8535
|
const themeTogglePath = resolve8(projectRoot, "components", "shared", "theme-toggle.tsx");
|
|
8514
|
-
if (!
|
|
8536
|
+
if (!existsSync14(themeTogglePath)) {
|
|
8515
8537
|
const { generateThemeToggleCode } = await import("./code-generator-YSGVHVNN.js");
|
|
8516
8538
|
mkdirSync7(resolve8(projectRoot, "components", "shared"), { recursive: true });
|
|
8517
8539
|
const themeResult = safeWrite(themeTogglePath, generateThemeToggleCode(), projectRoot, backups);
|
|
@@ -8528,8 +8550,8 @@ async function fixCommand(opts = {}) {
|
|
|
8528
8550
|
console.log(chalk15.yellow(` \u26A0 Layout repair skipped: ${err instanceof Error ? err.message : "unknown error"}`));
|
|
8529
8551
|
}
|
|
8530
8552
|
const appLayoutRepairPath = resolve8(projectRoot, "app", "(app)", "layout.tsx");
|
|
8531
|
-
if (
|
|
8532
|
-
const appLayoutCode =
|
|
8553
|
+
if (existsSync14(appLayoutRepairPath) && dsm) {
|
|
8554
|
+
const appLayoutCode = readFileSync10(appLayoutRepairPath, "utf-8");
|
|
8533
8555
|
const isMinimal = appLayoutCode.length < 500 && !appLayoutCode.includes("Header") && !appLayoutCode.includes("Footer") && !appLayoutCode.includes("Sidebar") && !appLayoutCode.includes("SidebarProvider") && !appLayoutCode.includes("SidebarTrigger") && !appLayoutCode.includes("Sheet");
|
|
8534
8556
|
const navType = dsm.getConfig().navigation?.type || "header";
|
|
8535
8557
|
if (isMinimal && navType !== "none") {
|
|
@@ -8557,7 +8579,7 @@ async function fixCommand(opts = {}) {
|
|
|
8557
8579
|
const qualityFixDetails = [];
|
|
8558
8580
|
for (const file of allValidationFiles) {
|
|
8559
8581
|
try {
|
|
8560
|
-
const content =
|
|
8582
|
+
const content = readFileSync10(file, "utf-8");
|
|
8561
8583
|
const { code: autoFixed, fixes: fileFixes } = await autoFixCode(content);
|
|
8562
8584
|
if (autoFixed !== content) {
|
|
8563
8585
|
if (!dryRun) {
|
|
@@ -8575,7 +8597,9 @@ async function fixCommand(opts = {}) {
|
|
|
8575
8597
|
}
|
|
8576
8598
|
}
|
|
8577
8599
|
} catch (err) {
|
|
8578
|
-
remaining.push(
|
|
8600
|
+
remaining.push(
|
|
8601
|
+
`${relative5(projectRoot, file)}: quality fix error \u2014 ${err instanceof Error ? err.message : "unknown"}`
|
|
8602
|
+
);
|
|
8579
8603
|
}
|
|
8580
8604
|
}
|
|
8581
8605
|
if (qualityFixCount > 0) {
|
|
@@ -8590,7 +8614,7 @@ async function fixCommand(opts = {}) {
|
|
|
8590
8614
|
let mockFixed = 0;
|
|
8591
8615
|
for (const file of allValidationFiles) {
|
|
8592
8616
|
try {
|
|
8593
|
-
const content =
|
|
8617
|
+
const content = readFileSync10(file, "utf-8");
|
|
8594
8618
|
const mockIssues = validateMockData(content);
|
|
8595
8619
|
if (mockIssues.length > 0) {
|
|
8596
8620
|
const fixed = applyMockDataFixes(content, mockIssues);
|
|
@@ -8605,7 +8629,9 @@ async function fixCommand(opts = {}) {
|
|
|
8605
8629
|
}
|
|
8606
8630
|
}
|
|
8607
8631
|
} catch (fileErr) {
|
|
8608
|
-
remaining.push(
|
|
8632
|
+
remaining.push(
|
|
8633
|
+
`${relative5(projectRoot, file)}: mock data fix error \u2014 ${fileErr instanceof Error ? fileErr.message : "unknown"}`
|
|
8634
|
+
);
|
|
8609
8635
|
}
|
|
8610
8636
|
}
|
|
8611
8637
|
if (mockFixed > 0) {
|
|
@@ -8619,7 +8645,7 @@ async function fixCommand(opts = {}) {
|
|
|
8619
8645
|
for (const file of modifiedFiles) {
|
|
8620
8646
|
if (!backups.has(file)) continue;
|
|
8621
8647
|
const before = backups.get(file);
|
|
8622
|
-
const after =
|
|
8648
|
+
const after = readFileSync10(file, "utf-8");
|
|
8623
8649
|
const issues = verifyIncrementalEdit(before, after);
|
|
8624
8650
|
if (issues.length > 0) {
|
|
8625
8651
|
for (const issue of issues) {
|
|
@@ -8632,7 +8658,7 @@ async function fixCommand(opts = {}) {
|
|
|
8632
8658
|
const fileIssues = [];
|
|
8633
8659
|
for (const file of allValidationFiles) {
|
|
8634
8660
|
try {
|
|
8635
|
-
const code =
|
|
8661
|
+
const code = readFileSync10(file, "utf-8");
|
|
8636
8662
|
const relativePath = file.replace(projectRoot + "/", "");
|
|
8637
8663
|
const baseName = file.split("/").pop() || "";
|
|
8638
8664
|
const isAuthPage = relativePath.includes("(auth)");
|
|
@@ -8656,7 +8682,9 @@ async function fixCommand(opts = {}) {
|
|
|
8656
8682
|
const report = formatIssues(filteredIssues);
|
|
8657
8683
|
fileIssues.push({ path: relativePath, report });
|
|
8658
8684
|
} catch (err) {
|
|
8659
|
-
remaining.push(
|
|
8685
|
+
remaining.push(
|
|
8686
|
+
`${relative5(projectRoot, file)}: validation error \u2014 ${err instanceof Error ? err.message : "unknown"}`
|
|
8687
|
+
);
|
|
8660
8688
|
}
|
|
8661
8689
|
}
|
|
8662
8690
|
try {
|
|
@@ -8740,26 +8768,66 @@ async function fixCommand(opts = {}) {
|
|
|
8740
8768
|
}
|
|
8741
8769
|
try {
|
|
8742
8770
|
const tsconfigPath = resolve8(projectRoot, "tsconfig.json");
|
|
8743
|
-
if (
|
|
8744
|
-
const {
|
|
8745
|
-
|
|
8746
|
-
|
|
8747
|
-
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8751
|
-
|
|
8752
|
-
|
|
8753
|
-
|
|
8754
|
-
|
|
8755
|
-
|
|
8756
|
-
|
|
8757
|
-
|
|
8758
|
-
|
|
8771
|
+
if (existsSync14(tsconfigPath)) {
|
|
8772
|
+
const { runTscCheck, applyDeterministicFixes } = await import("./tsc-autofix-S5PKMFSC.js");
|
|
8773
|
+
const { applyAiFixes } = await import("./tsc-ai-fix-O3EMRWV2.js");
|
|
8774
|
+
const tscErrors = runTscCheck(projectRoot);
|
|
8775
|
+
if (tscErrors.length === 0) {
|
|
8776
|
+
fixes.push("TypeScript compilation clean");
|
|
8777
|
+
console.log(chalk15.green(" \u2714 TypeScript compilation clean"));
|
|
8778
|
+
} else {
|
|
8779
|
+
const detResult = await applyDeterministicFixes(tscErrors, projectRoot, backups);
|
|
8780
|
+
if (detResult.fixed.length > 0) {
|
|
8781
|
+
fixes.push(`TypeScript: fixed ${detResult.fixed.length} file(s) deterministically`);
|
|
8782
|
+
console.log(chalk15.green(` \u2714 TypeScript: fixed ${detResult.fixed.length} file(s) deterministically`));
|
|
8783
|
+
}
|
|
8784
|
+
if (detResult.remaining.length > 0) {
|
|
8785
|
+
let aiProvider;
|
|
8786
|
+
try {
|
|
8787
|
+
const { createAIProvider: createAIProvider2 } = await import("./ai-provider-CGSIYFZT.js");
|
|
8788
|
+
aiProvider = await createAIProvider2("auto");
|
|
8789
|
+
} catch {
|
|
8790
|
+
}
|
|
8791
|
+
if (aiProvider?.editPageCode) {
|
|
8792
|
+
console.log(chalk15.dim(` \u23F3 Using AI to fix ${detResult.remaining.length} TypeScript error(s)...`));
|
|
8793
|
+
const aiResult = await applyAiFixes(detResult.remaining, projectRoot, backups, aiProvider);
|
|
8794
|
+
if (aiResult.fixed.length > 0) {
|
|
8795
|
+
fixes.push(`TypeScript: fixed ${aiResult.fixed.length} file(s) via AI`);
|
|
8796
|
+
console.log(chalk15.green(` \u2714 TypeScript: fixed ${aiResult.fixed.length} file(s) via AI`));
|
|
8797
|
+
}
|
|
8798
|
+
if (aiResult.failed.length > 0) {
|
|
8799
|
+
for (const e of aiResult.failed.slice(0, 10)) {
|
|
8800
|
+
remaining.push(`${e.file}(${e.line}): [${e.code}] ${e.message.split("\n")[0]}`);
|
|
8801
|
+
}
|
|
8802
|
+
if (aiResult.failed.length > 10) {
|
|
8803
|
+
remaining.push(`... and ${aiResult.failed.length - 10} more TypeScript errors`);
|
|
8804
|
+
}
|
|
8805
|
+
console.log(chalk15.yellow(` \u26A0 TypeScript: ${aiResult.failed.length} error(s) remaining`));
|
|
8806
|
+
}
|
|
8807
|
+
} else {
|
|
8808
|
+
for (const e of detResult.remaining.slice(0, 10)) {
|
|
8809
|
+
remaining.push(`${e.file}(${e.line}): [${e.code}] ${e.message.split("\n")[0]}`);
|
|
8810
|
+
}
|
|
8811
|
+
if (detResult.remaining.length > 10) {
|
|
8812
|
+
remaining.push(`... and ${detResult.remaining.length - 10} more TypeScript errors`);
|
|
8813
|
+
}
|
|
8814
|
+
console.log(
|
|
8815
|
+
chalk15.yellow(
|
|
8816
|
+
` \u26A0 TypeScript: ${detResult.remaining.length} error(s) remaining. Configure API key for auto-fix.`
|
|
8817
|
+
)
|
|
8818
|
+
);
|
|
8819
|
+
}
|
|
8820
|
+
}
|
|
8821
|
+
const finalErrors = runTscCheck(projectRoot);
|
|
8822
|
+
if (finalErrors.length === 0) {
|
|
8823
|
+
console.log(chalk15.green(" \u2714 TypeScript compilation now clean"));
|
|
8824
|
+
}
|
|
8759
8825
|
}
|
|
8760
|
-
if (errorLines.length > 10) remaining.push(`... and ${errorLines.length - 10} more TypeScript errors`);
|
|
8761
|
-
console.log(chalk15.yellow(` \u26A0 TypeScript: ${errorLines.length} error(s)`));
|
|
8762
8826
|
}
|
|
8827
|
+
} catch (err) {
|
|
8828
|
+
console.log(
|
|
8829
|
+
chalk15.yellow(` \u26A0 TypeScript check skipped: ${err instanceof Error ? err.message : "unknown error"}`)
|
|
8830
|
+
);
|
|
8763
8831
|
}
|
|
8764
8832
|
if (fixes.length === 0 && totalErrors === 0 && totalWarnings === 0 && remaining.length === 0) {
|
|
8765
8833
|
console.log(chalk15.green("\n \u2705 Everything looks good \u2014 no issues found\n"));
|
|
@@ -8790,7 +8858,7 @@ async function fixCommand(opts = {}) {
|
|
|
8790
8858
|
// src/commands/check.ts
|
|
8791
8859
|
import chalk16 from "chalk";
|
|
8792
8860
|
import { resolve as resolve9 } from "path";
|
|
8793
|
-
import { readdirSync as readdirSync8, readFileSync as
|
|
8861
|
+
import { readdirSync as readdirSync8, readFileSync as readFileSync11, statSync as statSync3, existsSync as existsSync15 } from "fs";
|
|
8794
8862
|
import { loadManifest as loadManifest10 } from "@getcoherent/core";
|
|
8795
8863
|
var EXCLUDED_DIRS = /* @__PURE__ */ new Set(["node_modules", "design-system"]);
|
|
8796
8864
|
function findTsxFiles(dir) {
|
|
@@ -8847,7 +8915,7 @@ async function checkCommand(opts = {}) {
|
|
|
8847
8915
|
"NATIVE_TABLE"
|
|
8848
8916
|
]);
|
|
8849
8917
|
for (const file of files) {
|
|
8850
|
-
const code =
|
|
8918
|
+
const code = readFileSync11(file, "utf-8");
|
|
8851
8919
|
const relativePath = file.replace(projectRoot + "/", "");
|
|
8852
8920
|
const baseName = file.split("/").pop() || "";
|
|
8853
8921
|
const isAuthPage = relativePath.includes("(auth)");
|
|
@@ -8889,7 +8957,7 @@ async function checkCommand(opts = {}) {
|
|
|
8889
8957
|
routeSet.add("/");
|
|
8890
8958
|
routeSet.add("#");
|
|
8891
8959
|
for (const file of files) {
|
|
8892
|
-
const code =
|
|
8960
|
+
const code = readFileSync11(file, "utf-8");
|
|
8893
8961
|
const relativePath = file.replace(projectRoot + "/", "");
|
|
8894
8962
|
const lines = code.split("\n");
|
|
8895
8963
|
const linkHrefRe = /href\s*=\s*["'](\/[a-z0-9/-]*)["']/gi;
|
|
@@ -8922,7 +8990,7 @@ async function checkCommand(opts = {}) {
|
|
|
8922
8990
|
if (manifest.shared.length > 0) {
|
|
8923
8991
|
for (const entry of manifest.shared) {
|
|
8924
8992
|
const fullPath = resolve9(project.root, entry.file);
|
|
8925
|
-
if (!
|
|
8993
|
+
if (!existsSync15(fullPath)) {
|
|
8926
8994
|
result.pages.withErrors++;
|
|
8927
8995
|
if (!opts.json) console.log(chalk16.red(`
|
|
8928
8996
|
\u2717 Missing shared component file: ${entry.id} (${entry.file})`));
|
|
@@ -8947,7 +9015,7 @@ async function checkCommand(opts = {}) {
|
|
|
8947
9015
|
let _nameMismatch = 0;
|
|
8948
9016
|
for (const entry of manifest.shared) {
|
|
8949
9017
|
const filePath = resolve9(projectRoot, entry.file);
|
|
8950
|
-
const fileExists =
|
|
9018
|
+
const fileExists = existsSync15(filePath);
|
|
8951
9019
|
if (!fileExists) {
|
|
8952
9020
|
_orphaned++;
|
|
8953
9021
|
if (!opts.json) {
|
|
@@ -8957,7 +9025,7 @@ async function checkCommand(opts = {}) {
|
|
|
8957
9025
|
continue;
|
|
8958
9026
|
}
|
|
8959
9027
|
try {
|
|
8960
|
-
const code =
|
|
9028
|
+
const code = readFileSync11(filePath, "utf-8");
|
|
8961
9029
|
const actualExports = extractExportedComponentNames(code);
|
|
8962
9030
|
if (actualExports.length > 0 && !actualExports.includes(entry.name)) {
|
|
8963
9031
|
_nameMismatch++;
|
|
@@ -9025,7 +9093,7 @@ async function checkCommand(opts = {}) {
|
|
|
9025
9093
|
id: e.id,
|
|
9026
9094
|
name: e.name,
|
|
9027
9095
|
type: e.type,
|
|
9028
|
-
status:
|
|
9096
|
+
status: existsSync15(resolve9(projectRoot, e.file)) ? "ok" : "unused",
|
|
9029
9097
|
message: "",
|
|
9030
9098
|
suggestions: void 0
|
|
9031
9099
|
}))
|
|
@@ -9039,11 +9107,11 @@ async function checkCommand(opts = {}) {
|
|
|
9039
9107
|
const { inferPageTypeFromRoute: inferPageTypeFromRoute2 } = await import("./design-constraints-HGNEY3W3.js");
|
|
9040
9108
|
const manifest = await loadManifest10(projectRoot);
|
|
9041
9109
|
const appDir = resolve9(projectRoot, "app");
|
|
9042
|
-
const pageFiles =
|
|
9110
|
+
const pageFiles = existsSync15(appDir) ? findTsxFiles(appDir) : [];
|
|
9043
9111
|
if (manifest.shared.length > 0 && pageFiles.length > 0) {
|
|
9044
9112
|
const reuseWarnings = [];
|
|
9045
9113
|
for (const file of pageFiles) {
|
|
9046
|
-
const code =
|
|
9114
|
+
const code = readFileSync11(file, "utf-8");
|
|
9047
9115
|
const relativePath = file.replace(projectRoot + "/", "");
|
|
9048
9116
|
const route = "/" + relativePath.replace(/^app\//, "").replace(/\/page\.tsx$/, "").replace(/^\(.*?\)\//, "");
|
|
9049
9117
|
const pageType = inferPageTypeFromRoute2(route);
|
|
@@ -9154,12 +9222,12 @@ import {
|
|
|
9154
9222
|
generateSharedComponent as generateSharedComponent4,
|
|
9155
9223
|
integrateSharedLayoutIntoRootLayout as integrateSharedLayoutIntoRootLayout2
|
|
9156
9224
|
} from "@getcoherent/core";
|
|
9157
|
-
import { existsSync as
|
|
9225
|
+
import { existsSync as existsSync16 } from "fs";
|
|
9158
9226
|
import { resolve as resolve10 } from "path";
|
|
9159
9227
|
|
|
9160
9228
|
// src/utils/ds-files.ts
|
|
9161
9229
|
import { mkdir as mkdir3, writeFile as writeFile4 } from "fs/promises";
|
|
9162
|
-
import { join as
|
|
9230
|
+
import { join as join12, dirname as dirname5 } from "path";
|
|
9163
9231
|
import { DesignSystemGenerator } from "@getcoherent/core";
|
|
9164
9232
|
var SHARED_DS_KEYS = [
|
|
9165
9233
|
"app/design-system/shared/page.tsx",
|
|
@@ -9173,7 +9241,7 @@ async function writeDesignSystemFiles(projectRoot, config2, options) {
|
|
|
9173
9241
|
const toWrite = options?.sharedOnly ? new Map([...files].filter(([path3]) => SHARED_DS_KEYS.includes(path3))) : files;
|
|
9174
9242
|
const written = [];
|
|
9175
9243
|
for (const [relativePath, content] of toWrite) {
|
|
9176
|
-
const fullPath =
|
|
9244
|
+
const fullPath = join12(projectRoot, relativePath);
|
|
9177
9245
|
await mkdir3(dirname5(fullPath), { recursive: true });
|
|
9178
9246
|
await writeFile4(fullPath, content, "utf-8");
|
|
9179
9247
|
written.push(relativePath);
|
|
@@ -9309,7 +9377,7 @@ function createComponentsCommand() {
|
|
|
9309
9377
|
if (updated) console.log(chalk22.cyan(" Updated app/layout.tsx to use shared layout components.\n"));
|
|
9310
9378
|
}
|
|
9311
9379
|
const sharedPagePath = resolve10(project.root, "app/design-system/shared/page.tsx");
|
|
9312
|
-
if (!
|
|
9380
|
+
if (!existsSync16(sharedPagePath)) {
|
|
9313
9381
|
try {
|
|
9314
9382
|
const dsm = new DesignSystemManager10(project.configPath);
|
|
9315
9383
|
await dsm.load();
|
|
@@ -9335,8 +9403,8 @@ function createComponentsCommand() {
|
|
|
9335
9403
|
import chalk23 from "chalk";
|
|
9336
9404
|
import ora6 from "ora";
|
|
9337
9405
|
import { writeFile as writeFile5, mkdir as mkdir4 } from "fs/promises";
|
|
9338
|
-
import { resolve as resolve11, join as
|
|
9339
|
-
import { existsSync as
|
|
9406
|
+
import { resolve as resolve11, join as join13, dirname as dirname6 } from "path";
|
|
9407
|
+
import { existsSync as existsSync17 } from "fs";
|
|
9340
9408
|
import {
|
|
9341
9409
|
FigmaClient,
|
|
9342
9410
|
parseFigmaFileResponse,
|
|
@@ -9483,7 +9551,7 @@ async function importFigmaAction(urlOrKey, opts) {
|
|
|
9483
9551
|
stats.filesWritten.push(filePath);
|
|
9484
9552
|
return;
|
|
9485
9553
|
}
|
|
9486
|
-
const fullPath =
|
|
9554
|
+
const fullPath = join13(projectRoot, filePath);
|
|
9487
9555
|
await mkdir4(dirname6(fullPath), { recursive: true });
|
|
9488
9556
|
await writeFile5(fullPath, content, "utf-8");
|
|
9489
9557
|
stats.filesWritten.push(filePath);
|
|
@@ -9585,7 +9653,7 @@ async function importFigmaAction(urlOrKey, opts) {
|
|
|
9585
9653
|
spinner.start("Updating design-system.config.ts...");
|
|
9586
9654
|
const configPath = resolve11(projectRoot, DESIGN_SYSTEM_CONFIG_PATH);
|
|
9587
9655
|
const dsm = new DesignSystemManager11(configPath);
|
|
9588
|
-
if (
|
|
9656
|
+
if (existsSync17(configPath)) {
|
|
9589
9657
|
await dsm.load();
|
|
9590
9658
|
const existing = dsm.getConfig();
|
|
9591
9659
|
dsm.updateConfig({
|
|
@@ -9614,8 +9682,8 @@ export const config = ${JSON.stringify(fullConfig, null, 2)} as const
|
|
|
9614
9682
|
stats.configUpdated = true;
|
|
9615
9683
|
spinner.succeed("design-system.config.ts updated");
|
|
9616
9684
|
spinner.start("Ensuring root layout...");
|
|
9617
|
-
const layoutPath =
|
|
9618
|
-
if (!
|
|
9685
|
+
const layoutPath = join13(projectRoot, "app/layout.tsx");
|
|
9686
|
+
if (!existsSync17(layoutPath)) {
|
|
9619
9687
|
await mkdir4(dirname6(layoutPath), { recursive: true });
|
|
9620
9688
|
await writeFile5(layoutPath, MINIMAL_ROOT_LAYOUT, "utf-8");
|
|
9621
9689
|
stats.filesWritten.push("app/layout.tsx");
|
|
@@ -9705,8 +9773,8 @@ async function dsRegenerateCommand() {
|
|
|
9705
9773
|
// src/commands/update.ts
|
|
9706
9774
|
import chalk25 from "chalk";
|
|
9707
9775
|
import ora8 from "ora";
|
|
9708
|
-
import { readFileSync as
|
|
9709
|
-
import { join as
|
|
9776
|
+
import { readFileSync as readFileSync12, existsSync as existsSync18 } from "fs";
|
|
9777
|
+
import { join as join14 } from "path";
|
|
9710
9778
|
import { DesignSystemManager as DesignSystemManager13, CLI_VERSION as CLI_VERSION4 } from "@getcoherent/core";
|
|
9711
9779
|
|
|
9712
9780
|
// src/utils/migrations.ts
|
|
@@ -9875,20 +9943,20 @@ var EXPECTED_CSS_VARS = [
|
|
|
9875
9943
|
"--sidebar-ring"
|
|
9876
9944
|
];
|
|
9877
9945
|
function checkMissingCssVars(projectRoot) {
|
|
9878
|
-
const globalsPath =
|
|
9879
|
-
if (!
|
|
9946
|
+
const globalsPath = join14(projectRoot, "app", "globals.css");
|
|
9947
|
+
if (!existsSync18(globalsPath)) return [];
|
|
9880
9948
|
try {
|
|
9881
|
-
const content =
|
|
9949
|
+
const content = readFileSync12(globalsPath, "utf-8");
|
|
9882
9950
|
return EXPECTED_CSS_VARS.filter((v) => !content.includes(v));
|
|
9883
9951
|
} catch {
|
|
9884
9952
|
return [];
|
|
9885
9953
|
}
|
|
9886
9954
|
}
|
|
9887
9955
|
function patchGlobalsCss(projectRoot, missingVars) {
|
|
9888
|
-
const globalsPath =
|
|
9889
|
-
if (!
|
|
9890
|
-
const { writeFileSync:
|
|
9891
|
-
let content =
|
|
9956
|
+
const globalsPath = join14(projectRoot, "app", "globals.css");
|
|
9957
|
+
if (!existsSync18(globalsPath) || missingVars.length === 0) return;
|
|
9958
|
+
const { writeFileSync: writeFileSync11 } = __require("fs");
|
|
9959
|
+
let content = readFileSync12(globalsPath, "utf-8");
|
|
9892
9960
|
const defaultValues = {
|
|
9893
9961
|
"--chart-1": "220 70% 50%",
|
|
9894
9962
|
"--chart-2": "160 60% 45%",
|
|
@@ -9916,7 +9984,7 @@ function patchGlobalsCss(projectRoot, missingVars) {
|
|
|
9916
9984
|
const lightSectionEnd = content.indexOf("}");
|
|
9917
9985
|
if (lightSectionEnd > 0) {
|
|
9918
9986
|
content = content.slice(0, lightSectionEnd) + "\n" + injection + "\n" + content.slice(lightSectionEnd);
|
|
9919
|
-
|
|
9987
|
+
writeFileSync11(globalsPath, content, "utf-8");
|
|
9920
9988
|
}
|
|
9921
9989
|
}
|
|
9922
9990
|
|
|
@@ -9966,26 +10034,26 @@ async function undoCommand(options) {
|
|
|
9966
10034
|
// src/commands/sync.ts
|
|
9967
10035
|
import chalk27 from "chalk";
|
|
9968
10036
|
import ora9 from "ora";
|
|
9969
|
-
import { existsSync as
|
|
9970
|
-
import { join as
|
|
10037
|
+
import { existsSync as existsSync19, readFileSync as readFileSync13 } from "fs";
|
|
10038
|
+
import { join as join15, relative as relative6, dirname as dirname7 } from "path";
|
|
9971
10039
|
import { readdir as readdir3, readFile as readFile4 } from "fs/promises";
|
|
9972
10040
|
import { DesignSystemManager as DesignSystemManager14 } from "@getcoherent/core";
|
|
9973
10041
|
import { loadManifest as loadManifest12, saveManifest as saveManifest6, findSharedComponent } from "@getcoherent/core";
|
|
9974
10042
|
function extractTokensFromProject(projectRoot) {
|
|
9975
10043
|
const lightColors = {};
|
|
9976
10044
|
const darkColors = {};
|
|
9977
|
-
const globalsPath =
|
|
9978
|
-
if (
|
|
9979
|
-
const css =
|
|
10045
|
+
const globalsPath = join15(projectRoot, "app", "globals.css");
|
|
10046
|
+
if (existsSync19(globalsPath)) {
|
|
10047
|
+
const css = readFileSync13(globalsPath, "utf-8");
|
|
9980
10048
|
const rootMatch = css.match(/:root\s*\{([^}]+)\}/s);
|
|
9981
10049
|
if (rootMatch) parseVarsInto(rootMatch[1], lightColors);
|
|
9982
10050
|
const darkMatch = css.match(/\.dark\s*\{([^}]+)\}/s);
|
|
9983
10051
|
if (darkMatch) parseVarsInto(darkMatch[1], darkColors);
|
|
9984
10052
|
}
|
|
9985
|
-
const layoutPath =
|
|
10053
|
+
const layoutPath = join15(projectRoot, "app", "layout.tsx");
|
|
9986
10054
|
let layoutCode = "";
|
|
9987
|
-
if (
|
|
9988
|
-
layoutCode =
|
|
10055
|
+
if (existsSync19(layoutPath)) {
|
|
10056
|
+
layoutCode = readFileSync13(layoutPath, "utf-8");
|
|
9989
10057
|
const rootInline = layoutCode.match(/:root\s*\{([^}]+)\}/s);
|
|
9990
10058
|
if (rootInline && Object.keys(lightColors).length === 0) {
|
|
9991
10059
|
parseVarsInto(rootInline[1], lightColors);
|
|
@@ -10003,7 +10071,7 @@ function extractTokensFromProject(projectRoot) {
|
|
|
10003
10071
|
defaultMode = "dark";
|
|
10004
10072
|
}
|
|
10005
10073
|
let radius;
|
|
10006
|
-
const allCss = [
|
|
10074
|
+
const allCss = [existsSync19(globalsPath) ? readFileSync13(globalsPath, "utf-8") : "", layoutCode].join("\n");
|
|
10007
10075
|
const radiusMatch = allCss.match(/--radius:\s*([^;]+);/);
|
|
10008
10076
|
if (radiusMatch) radius = radiusMatch[1].trim();
|
|
10009
10077
|
return {
|
|
@@ -10026,8 +10094,8 @@ function parseVarsInto(block, target) {
|
|
|
10026
10094
|
}
|
|
10027
10095
|
async function detectCustomComponents(projectRoot, allPageCode) {
|
|
10028
10096
|
const results = [];
|
|
10029
|
-
const componentsDir =
|
|
10030
|
-
if (!
|
|
10097
|
+
const componentsDir = join15(projectRoot, "components");
|
|
10098
|
+
if (!existsSync19(componentsDir)) return results;
|
|
10031
10099
|
const files = [];
|
|
10032
10100
|
await walkForTsx(componentsDir, files, ["ui"]);
|
|
10033
10101
|
const fileResults = await Promise.all(
|
|
@@ -10054,7 +10122,7 @@ async function walkForTsx(dir, files, skipDirs) {
|
|
|
10054
10122
|
return;
|
|
10055
10123
|
}
|
|
10056
10124
|
for (const e of entries) {
|
|
10057
|
-
const full =
|
|
10125
|
+
const full = join15(dir, e.name);
|
|
10058
10126
|
if (e.isDirectory()) {
|
|
10059
10127
|
if (skipDirs.includes(e.name) || e.name.startsWith(".")) continue;
|
|
10060
10128
|
await walkForTsx(full, files, skipDirs);
|
|
@@ -10128,7 +10196,7 @@ async function discoverPages(appDir) {
|
|
|
10128
10196
|
return;
|
|
10129
10197
|
}
|
|
10130
10198
|
for (const entry of entries) {
|
|
10131
|
-
const full =
|
|
10199
|
+
const full = join15(dir, entry.name);
|
|
10132
10200
|
if (entry.isDirectory()) {
|
|
10133
10201
|
if (["design-system", "api", "_not-found"].includes(entry.name)) continue;
|
|
10134
10202
|
if (entry.name.startsWith(".")) continue;
|
|
@@ -10217,8 +10285,8 @@ async function syncCommand(options = {}) {
|
|
|
10217
10285
|
if (dryRun) console.log(chalk27.yellow(" [dry-run] No files will be written\n"));
|
|
10218
10286
|
const spinner = ora9("Scanning project files...").start();
|
|
10219
10287
|
try {
|
|
10220
|
-
const appDir =
|
|
10221
|
-
if (!
|
|
10288
|
+
const appDir = join15(project.root, "app");
|
|
10289
|
+
if (!existsSync19(appDir)) {
|
|
10222
10290
|
spinner.fail("No app/ directory found");
|
|
10223
10291
|
process.exit(1);
|
|
10224
10292
|
}
|
|
@@ -10448,53 +10516,53 @@ async function syncCommand(options = {}) {
|
|
|
10448
10516
|
// src/commands/migrate.ts
|
|
10449
10517
|
import chalk28 from "chalk";
|
|
10450
10518
|
import ora10 from "ora";
|
|
10451
|
-
import { existsSync as
|
|
10452
|
-
import { join as
|
|
10519
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync8, cpSync, rmSync as rmSync6, writeFileSync as writeFileSync9, readFileSync as readFileSync14, readdirSync as readdirSync9 } from "fs";
|
|
10520
|
+
import { join as join16 } from "path";
|
|
10453
10521
|
function backupDir(projectRoot) {
|
|
10454
10522
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
10455
|
-
return
|
|
10523
|
+
return join16(projectRoot, ".coherent", "backups", `pre-migrate-${ts}`);
|
|
10456
10524
|
}
|
|
10457
10525
|
function guardPath(projectRoot) {
|
|
10458
|
-
return
|
|
10526
|
+
return join16(projectRoot, ".coherent", "migration-in-progress");
|
|
10459
10527
|
}
|
|
10460
10528
|
function createBackup2(projectRoot) {
|
|
10461
|
-
const uiDir =
|
|
10529
|
+
const uiDir = join16(projectRoot, "components", "ui");
|
|
10462
10530
|
const dest = backupDir(projectRoot);
|
|
10463
10531
|
mkdirSync8(dest, { recursive: true });
|
|
10464
|
-
if (
|
|
10465
|
-
cpSync(uiDir,
|
|
10532
|
+
if (existsSync20(uiDir)) {
|
|
10533
|
+
cpSync(uiDir, join16(dest, "components-ui"), { recursive: true });
|
|
10466
10534
|
}
|
|
10467
|
-
const configPath =
|
|
10468
|
-
if (
|
|
10469
|
-
cpSync(configPath,
|
|
10535
|
+
const configPath = join16(projectRoot, "design-system.config.ts");
|
|
10536
|
+
if (existsSync20(configPath)) {
|
|
10537
|
+
cpSync(configPath, join16(dest, "design-system.config.ts"));
|
|
10470
10538
|
}
|
|
10471
10539
|
return dest;
|
|
10472
10540
|
}
|
|
10473
10541
|
function setGuard(projectRoot, backupPath) {
|
|
10474
10542
|
const guard = guardPath(projectRoot);
|
|
10475
|
-
mkdirSync8(
|
|
10476
|
-
|
|
10543
|
+
mkdirSync8(join16(projectRoot, ".coherent"), { recursive: true });
|
|
10544
|
+
writeFileSync9(guard, JSON.stringify({ backup: backupPath, startedAt: (/* @__PURE__ */ new Date()).toISOString() }));
|
|
10477
10545
|
}
|
|
10478
10546
|
function clearGuard(projectRoot) {
|
|
10479
10547
|
const guard = guardPath(projectRoot);
|
|
10480
|
-
if (
|
|
10548
|
+
if (existsSync20(guard)) rmSync6(guard);
|
|
10481
10549
|
}
|
|
10482
10550
|
function rollback(projectRoot) {
|
|
10483
10551
|
const guard = guardPath(projectRoot);
|
|
10484
|
-
if (!
|
|
10552
|
+
if (!existsSync20(guard)) return false;
|
|
10485
10553
|
try {
|
|
10486
|
-
const data = JSON.parse(
|
|
10554
|
+
const data = JSON.parse(readFileSync14(guard, "utf-8"));
|
|
10487
10555
|
const backup = data.backup;
|
|
10488
|
-
if (!
|
|
10489
|
-
const uiBackup =
|
|
10490
|
-
const uiDir =
|
|
10491
|
-
if (
|
|
10492
|
-
if (
|
|
10556
|
+
if (!existsSync20(backup)) return false;
|
|
10557
|
+
const uiBackup = join16(backup, "components-ui");
|
|
10558
|
+
const uiDir = join16(projectRoot, "components", "ui");
|
|
10559
|
+
if (existsSync20(uiBackup)) {
|
|
10560
|
+
if (existsSync20(uiDir)) rmSync6(uiDir, { recursive: true });
|
|
10493
10561
|
cpSync(uiBackup, uiDir, { recursive: true });
|
|
10494
10562
|
}
|
|
10495
|
-
const configBackup =
|
|
10496
|
-
const configDest =
|
|
10497
|
-
if (
|
|
10563
|
+
const configBackup = join16(backup, "design-system.config.ts");
|
|
10564
|
+
const configDest = join16(projectRoot, "design-system.config.ts");
|
|
10565
|
+
if (existsSync20(configBackup)) {
|
|
10498
10566
|
cpSync(configBackup, configDest);
|
|
10499
10567
|
}
|
|
10500
10568
|
clearGuard(projectRoot);
|
|
@@ -10522,13 +10590,13 @@ async function migrateAction(options) {
|
|
|
10522
10590
|
return;
|
|
10523
10591
|
}
|
|
10524
10592
|
const guard = guardPath(projectRoot);
|
|
10525
|
-
if (
|
|
10593
|
+
if (existsSync20(guard)) {
|
|
10526
10594
|
console.log(chalk28.yellow("A migration is already in progress."));
|
|
10527
10595
|
console.log(chalk28.dim("Run `coherent migrate --rollback` to undo, or delete .coherent/migration-in-progress"));
|
|
10528
10596
|
return;
|
|
10529
10597
|
}
|
|
10530
|
-
const uiDir =
|
|
10531
|
-
if (!
|
|
10598
|
+
const uiDir = join16(projectRoot, "components", "ui");
|
|
10599
|
+
if (!existsSync20(uiDir)) {
|
|
10532
10600
|
console.log(chalk28.yellow("No components/ui directory found. Nothing to migrate."));
|
|
10533
10601
|
return;
|
|
10534
10602
|
}
|
|
@@ -10554,8 +10622,8 @@ Found ${migratable.length} component(s) to migrate:`));
|
|
|
10554
10622
|
setGuard(projectRoot, backup);
|
|
10555
10623
|
try {
|
|
10556
10624
|
for (const id of migratable) {
|
|
10557
|
-
const filePath =
|
|
10558
|
-
if (
|
|
10625
|
+
const filePath = join16(uiDir, `${id}.tsx`);
|
|
10626
|
+
if (existsSync20(filePath)) rmSync6(filePath);
|
|
10559
10627
|
}
|
|
10560
10628
|
const results = await provider.installBatch(migratable, projectRoot, { force: true });
|
|
10561
10629
|
let migrated = 0;
|
|
@@ -10577,20 +10645,20 @@ Found ${migratable.length} component(s) to migrate:`));
|
|
|
10577
10645
|
}
|
|
10578
10646
|
|
|
10579
10647
|
// src/utils/update-notifier.ts
|
|
10580
|
-
import { existsSync as
|
|
10581
|
-
import { join as
|
|
10648
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync9, readFileSync as readFileSync15, writeFileSync as writeFileSync10 } from "fs";
|
|
10649
|
+
import { join as join17 } from "path";
|
|
10582
10650
|
import { homedir } from "os";
|
|
10583
10651
|
import chalk29 from "chalk";
|
|
10584
10652
|
import { CLI_VERSION as CLI_VERSION5 } from "@getcoherent/core";
|
|
10585
10653
|
var DEBUG5 = process.env.COHERENT_DEBUG === "1";
|
|
10586
10654
|
var PACKAGE_NAME = "@getcoherent/cli";
|
|
10587
|
-
var CACHE_DIR =
|
|
10588
|
-
var CACHE_FILE =
|
|
10655
|
+
var CACHE_DIR = join17(homedir(), ".coherent");
|
|
10656
|
+
var CACHE_FILE = join17(CACHE_DIR, "update-check.json");
|
|
10589
10657
|
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
10590
10658
|
function readCache() {
|
|
10591
10659
|
try {
|
|
10592
|
-
if (!
|
|
10593
|
-
const raw =
|
|
10660
|
+
if (!existsSync21(CACHE_FILE)) return null;
|
|
10661
|
+
const raw = readFileSync15(CACHE_FILE, "utf-8");
|
|
10594
10662
|
return JSON.parse(raw);
|
|
10595
10663
|
} catch (e) {
|
|
10596
10664
|
if (DEBUG5) console.error("Failed to read update cache:", e);
|
|
@@ -10599,8 +10667,8 @@ function readCache() {
|
|
|
10599
10667
|
}
|
|
10600
10668
|
function writeCache(data) {
|
|
10601
10669
|
try {
|
|
10602
|
-
if (!
|
|
10603
|
-
|
|
10670
|
+
if (!existsSync21(CACHE_DIR)) mkdirSync9(CACHE_DIR, { recursive: true });
|
|
10671
|
+
writeFileSync10(CACHE_FILE, JSON.stringify(data), "utf-8");
|
|
10604
10672
|
} catch (e) {
|
|
10605
10673
|
if (DEBUG5) console.error("Failed to write update cache:", e);
|
|
10606
10674
|
}
|