@decantr/cli 3.6.2 → 3.7.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.
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
scaffoldProject,
|
|
15
15
|
syncRegistry,
|
|
16
16
|
writeExecutionPackBundleArtifacts
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-NDH3BDXY.js";
|
|
18
18
|
import {
|
|
19
19
|
createWorkspaceHealthReport,
|
|
20
20
|
formatWorkspaceHealthMarkdown,
|
|
@@ -72,8 +72,8 @@ import {
|
|
|
72
72
|
} from "./chunk-24JR4ZNG.js";
|
|
73
73
|
|
|
74
74
|
// src/index.ts
|
|
75
|
-
import { existsSync as
|
|
76
|
-
import { basename as basename2, dirname as
|
|
75
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync17, readdirSync as readdirSync8, readFileSync as readFileSync22, writeFileSync as writeFileSync20 } from "fs";
|
|
76
|
+
import { basename as basename2, dirname as dirname7, isAbsolute as isAbsolute4, join as join32, relative as relative7, resolve as resolve5 } from "path";
|
|
77
77
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
78
78
|
import {
|
|
79
79
|
buildGraphImpactContext,
|
|
@@ -2027,7 +2027,7 @@ async function cmdAddSection(archetypeId, args, projectRoot = process.cwd()) {
|
|
|
2027
2027
|
console.log(`${GREEN}Derived files refreshed.${RESET}`);
|
|
2028
2028
|
}
|
|
2029
2029
|
async function cmdAddPage(path, args, projectRoot = process.cwd()) {
|
|
2030
|
-
if (!path
|
|
2030
|
+
if (!path?.includes("/")) {
|
|
2031
2031
|
console.error(`${RED}Usage: decantr add page <section>/<page>${RESET}`);
|
|
2032
2032
|
console.error(`${DIM}Example: decantr add page settings/notifications${RESET}`);
|
|
2033
2033
|
process.exitCode = 1;
|
|
@@ -2054,7 +2054,8 @@ async function cmdAddPage(path, args, projectRoot = process.cwd()) {
|
|
|
2054
2054
|
return;
|
|
2055
2055
|
}
|
|
2056
2056
|
const route = normalizeRoute(readFlagValue(args, "route") ?? pageId);
|
|
2057
|
-
|
|
2057
|
+
essence.blueprint.routes ??= {};
|
|
2058
|
+
const routes = essence.blueprint.routes;
|
|
2058
2059
|
const existingRoute = routes[route];
|
|
2059
2060
|
if (existingRoute) {
|
|
2060
2061
|
console.error(
|
|
@@ -2927,157 +2928,21 @@ function writeBrownfieldIntelligenceArtifacts(input) {
|
|
|
2927
2928
|
}
|
|
2928
2929
|
|
|
2929
2930
|
// src/detect.ts
|
|
2930
|
-
import { existsSync as existsSync10
|
|
2931
|
-
import {
|
|
2932
|
-
|
|
2933
|
-
"CLAUDE.md",
|
|
2934
|
-
".claude/rules",
|
|
2935
|
-
".cursorrules",
|
|
2936
|
-
".cursor/rules",
|
|
2937
|
-
"AGENTS.md",
|
|
2938
|
-
"GEMINI.md",
|
|
2939
|
-
"copilot-instructions.md",
|
|
2940
|
-
".github/copilot-instructions.md",
|
|
2941
|
-
".windsurfrules"
|
|
2942
|
-
];
|
|
2943
|
-
var STATIC_HTML_ENTRY_FILES = [
|
|
2944
|
-
"index.html",
|
|
2945
|
-
"docs/index.html",
|
|
2946
|
-
"src/index.html",
|
|
2947
|
-
"public/index.html",
|
|
2948
|
-
"dist/index.html"
|
|
2949
|
-
];
|
|
2950
|
-
var STATIC_HTML_ROUTE_DIRS = ["demos", "examples"];
|
|
2951
|
-
function hasAnyFile(projectRoot, relPaths) {
|
|
2952
|
-
return relPaths.some((relPath) => existsSync10(join12(projectRoot, relPath)));
|
|
2953
|
-
}
|
|
2954
|
-
function hasStaticHtmlSurface(projectRoot) {
|
|
2955
|
-
if (hasAnyFile(projectRoot, STATIC_HTML_ENTRY_FILES)) return true;
|
|
2956
|
-
return STATIC_HTML_ROUTE_DIRS.some((dir) => existsSync10(join12(projectRoot, dir, "index.html")));
|
|
2957
|
-
}
|
|
2958
|
-
function readPackageJson(dir) {
|
|
2959
|
-
const path = join12(dir, "package.json");
|
|
2960
|
-
if (!existsSync10(path)) return null;
|
|
2961
|
-
try {
|
|
2962
|
-
return JSON.parse(readFileSync9(path, "utf-8"));
|
|
2963
|
-
} catch {
|
|
2964
|
-
return null;
|
|
2965
|
-
}
|
|
2966
|
-
}
|
|
2967
|
-
function packageManagerFromName(name) {
|
|
2968
|
-
if (name === "pnpm" || name === "yarn" || name === "bun" || name === "npm") return name;
|
|
2969
|
-
return "unknown";
|
|
2970
|
-
}
|
|
2971
|
-
function detectPackageManager(projectRoot) {
|
|
2972
|
-
let current = projectRoot;
|
|
2973
|
-
while (true) {
|
|
2974
|
-
const pkg = readPackageJson(current);
|
|
2975
|
-
const declared = packageManagerFromName(pkg?.packageManager?.split("@")[0]);
|
|
2976
|
-
if (declared !== "unknown") return declared;
|
|
2977
|
-
if (existsSync10(join12(current, "pnpm-lock.yaml"))) return "pnpm";
|
|
2978
|
-
if (existsSync10(join12(current, "yarn.lock"))) return "yarn";
|
|
2979
|
-
if (existsSync10(join12(current, "bun.lockb"))) return "bun";
|
|
2980
|
-
if (existsSync10(join12(current, "package-lock.json"))) return "npm";
|
|
2981
|
-
const parent = dirname2(current);
|
|
2982
|
-
if (parent === current) return "unknown";
|
|
2983
|
-
current = parent;
|
|
2984
|
-
}
|
|
2985
|
-
}
|
|
2931
|
+
import { existsSync as existsSync10 } from "fs";
|
|
2932
|
+
import { join as join12 } from "path";
|
|
2933
|
+
import { discoverProject } from "@decantr/verifier";
|
|
2986
2934
|
function detectProject(projectRoot = process.cwd()) {
|
|
2987
|
-
const
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2935
|
+
const discovery = discoverProject(projectRoot);
|
|
2936
|
+
return {
|
|
2937
|
+
framework: discovery.project.framework,
|
|
2938
|
+
version: discovery.project.frameworkVersion ?? void 0,
|
|
2939
|
+
packageManager: discovery.project.packageManager,
|
|
2940
|
+
hasTypeScript: discovery.project.hasTypeScript,
|
|
2941
|
+
hasTailwind: discovery.project.hasTailwind,
|
|
2942
|
+
existingRuleFiles: discovery.assistant.ruleFiles,
|
|
2943
|
+
existingEssence: existsSync10(join12(projectRoot, "decantr.essence.json")),
|
|
2994
2944
|
projectRoot
|
|
2995
2945
|
};
|
|
2996
|
-
result.existingEssence = existsSync10(join12(projectRoot, "decantr.essence.json"));
|
|
2997
|
-
for (const ruleFile of RULE_FILES) {
|
|
2998
|
-
if (existsSync10(join12(projectRoot, ruleFile))) {
|
|
2999
|
-
result.existingRuleFiles.push(ruleFile);
|
|
3000
|
-
}
|
|
3001
|
-
}
|
|
3002
|
-
result.packageManager = detectPackageManager(projectRoot);
|
|
3003
|
-
result.hasTypeScript = existsSync10(join12(projectRoot, "tsconfig.json"));
|
|
3004
|
-
result.hasTailwind = existsSync10(join12(projectRoot, "tailwind.config.js")) || existsSync10(join12(projectRoot, "tailwind.config.ts")) || existsSync10(join12(projectRoot, "tailwind.config.mjs")) || existsSync10(join12(projectRoot, "tailwind.config.cjs"));
|
|
3005
|
-
if (existsSync10(join12(projectRoot, "next.config.js")) || existsSync10(join12(projectRoot, "next.config.ts")) || existsSync10(join12(projectRoot, "next.config.mjs"))) {
|
|
3006
|
-
result.framework = "nextjs";
|
|
3007
|
-
result.version = getPackageVersion(projectRoot, "next");
|
|
3008
|
-
return result;
|
|
3009
|
-
}
|
|
3010
|
-
if (existsSync10(join12(projectRoot, "nuxt.config.js")) || existsSync10(join12(projectRoot, "nuxt.config.ts"))) {
|
|
3011
|
-
result.framework = "nuxt";
|
|
3012
|
-
result.version = getPackageVersion(projectRoot, "nuxt");
|
|
3013
|
-
return result;
|
|
3014
|
-
}
|
|
3015
|
-
if (existsSync10(join12(projectRoot, "astro.config.mjs")) || existsSync10(join12(projectRoot, "astro.config.ts"))) {
|
|
3016
|
-
result.framework = "astro";
|
|
3017
|
-
result.version = getPackageVersion(projectRoot, "astro");
|
|
3018
|
-
return result;
|
|
3019
|
-
}
|
|
3020
|
-
if (existsSync10(join12(projectRoot, "svelte.config.js")) || existsSync10(join12(projectRoot, "svelte.config.ts"))) {
|
|
3021
|
-
result.framework = "svelte";
|
|
3022
|
-
result.version = getPackageVersion(projectRoot, "svelte");
|
|
3023
|
-
return result;
|
|
3024
|
-
}
|
|
3025
|
-
if (existsSync10(join12(projectRoot, "angular.json"))) {
|
|
3026
|
-
result.framework = "angular";
|
|
3027
|
-
result.version = getPackageVersion(projectRoot, "@angular/core");
|
|
3028
|
-
return result;
|
|
3029
|
-
}
|
|
3030
|
-
const packageJsonPath = join12(projectRoot, "package.json");
|
|
3031
|
-
if (existsSync10(packageJsonPath)) {
|
|
3032
|
-
try {
|
|
3033
|
-
const packageJson = JSON.parse(readFileSync9(packageJsonPath, "utf-8"));
|
|
3034
|
-
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
3035
|
-
if (deps.next) {
|
|
3036
|
-
result.framework = "nextjs";
|
|
3037
|
-
result.version = deps.next.replace(/^\^|~/, "");
|
|
3038
|
-
} else if (deps.nuxt) {
|
|
3039
|
-
result.framework = "nuxt";
|
|
3040
|
-
result.version = deps.nuxt.replace(/^\^|~/, "");
|
|
3041
|
-
} else if (deps.astro) {
|
|
3042
|
-
result.framework = "astro";
|
|
3043
|
-
result.version = deps.astro.replace(/^\^|~/, "");
|
|
3044
|
-
} else if (deps.svelte) {
|
|
3045
|
-
result.framework = "svelte";
|
|
3046
|
-
result.version = deps.svelte.replace(/^\^|~/, "");
|
|
3047
|
-
} else if (deps["@angular/core"]) {
|
|
3048
|
-
result.framework = "angular";
|
|
3049
|
-
result.version = deps["@angular/core"].replace(/^\^|~/, "");
|
|
3050
|
-
} else if (deps["solid-js"]) {
|
|
3051
|
-
result.framework = "solid";
|
|
3052
|
-
result.version = deps["solid-js"].replace(/^\^|~/, "");
|
|
3053
|
-
} else if (deps.vue) {
|
|
3054
|
-
result.framework = "vue";
|
|
3055
|
-
result.version = deps.vue.replace(/^\^|~/, "");
|
|
3056
|
-
} else if (deps.react) {
|
|
3057
|
-
result.framework = "react";
|
|
3058
|
-
result.version = deps.react.replace(/^\^|~/, "");
|
|
3059
|
-
}
|
|
3060
|
-
} catch {
|
|
3061
|
-
}
|
|
3062
|
-
}
|
|
3063
|
-
if (result.framework === "unknown") {
|
|
3064
|
-
if (hasStaticHtmlSurface(projectRoot)) {
|
|
3065
|
-
result.framework = "html";
|
|
3066
|
-
}
|
|
3067
|
-
}
|
|
3068
|
-
return result;
|
|
3069
|
-
}
|
|
3070
|
-
function getPackageVersion(projectRoot, packageName) {
|
|
3071
|
-
const packageJsonPath = join12(projectRoot, "package.json");
|
|
3072
|
-
if (!existsSync10(packageJsonPath)) return void 0;
|
|
3073
|
-
try {
|
|
3074
|
-
const packageJson = JSON.parse(readFileSync9(packageJsonPath, "utf-8"));
|
|
3075
|
-
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
3076
|
-
const version = deps[packageName];
|
|
3077
|
-
return version?.replace(/^\^|~/, "");
|
|
3078
|
-
} catch {
|
|
3079
|
-
return void 0;
|
|
3080
|
-
}
|
|
3081
2946
|
}
|
|
3082
2947
|
function formatDetection(detected) {
|
|
3083
2948
|
const lines = [];
|
|
@@ -3104,7 +2969,7 @@ function formatDetection(detected) {
|
|
|
3104
2969
|
}
|
|
3105
2970
|
|
|
3106
2971
|
// src/workflow-model.ts
|
|
3107
|
-
import { existsSync as existsSync11, readFileSync as
|
|
2972
|
+
import { existsSync as existsSync11, readFileSync as readFileSync9 } from "fs";
|
|
3108
2973
|
import { join as join13 } from "path";
|
|
3109
2974
|
function inferSuggestedShell(layout) {
|
|
3110
2975
|
if (layout.hasSidebar) return "sidebar-main";
|
|
@@ -3197,7 +3062,7 @@ function readBrownfieldInitSeed(projectRoot) {
|
|
|
3197
3062
|
return null;
|
|
3198
3063
|
}
|
|
3199
3064
|
try {
|
|
3200
|
-
const parsed = JSON.parse(
|
|
3065
|
+
const parsed = JSON.parse(readFileSync9(seedPath, "utf-8"));
|
|
3201
3066
|
if (parsed.workflow !== "brownfield-adoption") {
|
|
3202
3067
|
return null;
|
|
3203
3068
|
}
|
|
@@ -3406,8 +3271,8 @@ ${YELLOW2}Next step:${RESET2} Review ${BOLD}${reportDisplayPath}${RESET2}, then
|
|
|
3406
3271
|
}
|
|
3407
3272
|
|
|
3408
3273
|
// src/commands/ci.ts
|
|
3409
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as
|
|
3410
|
-
import { dirname as
|
|
3274
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync9 } from "fs";
|
|
3275
|
+
import { dirname as dirname2, join as join15, relative as relative3, resolve } from "path";
|
|
3411
3276
|
import { DECANTR_CI_REPORT_V2_SCHEMA_URL } from "@decantr/verifier";
|
|
3412
3277
|
var BOLD2 = "\x1B[1m";
|
|
3413
3278
|
var DIM3 = "\x1B[2m";
|
|
@@ -3418,7 +3283,7 @@ var CI_SCHEMA = DECANTR_CI_REPORT_V2_SCHEMA_URL;
|
|
|
3418
3283
|
function readJson(path) {
|
|
3419
3284
|
if (!existsSync13(path)) return null;
|
|
3420
3285
|
try {
|
|
3421
|
-
return JSON.parse(
|
|
3286
|
+
return JSON.parse(readFileSync10(path, "utf-8"));
|
|
3422
3287
|
} catch {
|
|
3423
3288
|
return null;
|
|
3424
3289
|
}
|
|
@@ -3461,7 +3326,7 @@ function parseProvider(value) {
|
|
|
3461
3326
|
if (value === "github" || value === "generic") return value;
|
|
3462
3327
|
throw new Error("Invalid --provider value. Use github or generic.");
|
|
3463
3328
|
}
|
|
3464
|
-
function
|
|
3329
|
+
function detectPackageManager(root) {
|
|
3465
3330
|
const pkg = readJson(join15(root, "package.json"));
|
|
3466
3331
|
const declared = pkg?.packageManager?.split("@")[0];
|
|
3467
3332
|
if (declared === "pnpm" || declared === "npm" || declared === "yarn" || declared === "bun") {
|
|
@@ -3530,7 +3395,7 @@ function projectSlug(projectPath) {
|
|
|
3530
3395
|
}
|
|
3531
3396
|
function writeOutput(root, path, content) {
|
|
3532
3397
|
const absolute = resolve(root, path);
|
|
3533
|
-
mkdirSync8(
|
|
3398
|
+
mkdirSync8(dirname2(absolute), { recursive: true });
|
|
3534
3399
|
writeFileSync9(absolute, content, "utf-8");
|
|
3535
3400
|
}
|
|
3536
3401
|
function summarizeLocalLaw(projectRoot) {
|
|
@@ -3821,7 +3686,7 @@ function writeCiInit(root, options) {
|
|
|
3821
3686
|
}
|
|
3822
3687
|
const outputRoot = workspaceInfo.workspaceRoot;
|
|
3823
3688
|
const projectPath = options.project ?? (options.workspace || workspaceInfo.appRoot === workspaceInfo.workspaceRoot ? void 0 : relative3(workspaceInfo.workspaceRoot, workspaceInfo.appRoot).replace(/\\/g, "/"));
|
|
3824
|
-
const packageManager =
|
|
3689
|
+
const packageManager = detectPackageManager(outputRoot);
|
|
3825
3690
|
const command = decantrCommand(packageManager);
|
|
3826
3691
|
const failOn = options.failOn ?? "error";
|
|
3827
3692
|
const provider = options.provider ?? "github";
|
|
@@ -3981,8 +3846,8 @@ async function cmdCi(args = ["ci"], root = process.cwd()) {
|
|
|
3981
3846
|
}
|
|
3982
3847
|
|
|
3983
3848
|
// src/commands/connect.ts
|
|
3984
|
-
import { existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as
|
|
3985
|
-
import { dirname as
|
|
3849
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync11, writeFileSync as writeFileSync10 } from "fs";
|
|
3850
|
+
import { dirname as dirname3, isAbsolute, join as join16, relative as relative4 } from "path";
|
|
3986
3851
|
var GREEN4 = "\x1B[32m";
|
|
3987
3852
|
var CYAN2 = "\x1B[36m";
|
|
3988
3853
|
var DIM4 = "\x1B[2m";
|
|
@@ -4018,7 +3883,7 @@ function projectPathForConnection(input) {
|
|
|
4018
3883
|
}
|
|
4019
3884
|
function readCursorMcpConfig(path) {
|
|
4020
3885
|
if (!existsSync14(path)) return {};
|
|
4021
|
-
const parsed = JSON.parse(
|
|
3886
|
+
const parsed = JSON.parse(readFileSync11(path, "utf-8"));
|
|
4022
3887
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
4023
3888
|
throw new Error(`${path} must contain a JSON object.`);
|
|
4024
3889
|
}
|
|
@@ -4067,8 +3932,8 @@ Preserve the detected framework (${input.detected.framework}), package manager (
|
|
|
4067
3932
|
}
|
|
4068
3933
|
function writeTextIfChanged(path, content, preview) {
|
|
4069
3934
|
if (preview) return { path, action: "preview" };
|
|
4070
|
-
mkdirSync9(
|
|
4071
|
-
if (existsSync14(path) &&
|
|
3935
|
+
mkdirSync9(dirname3(path), { recursive: true });
|
|
3936
|
+
if (existsSync14(path) && readFileSync11(path, "utf-8") === content) {
|
|
4072
3937
|
return { path, action: "unchanged" };
|
|
4073
3938
|
}
|
|
4074
3939
|
writeFileSync10(path, content, "utf-8");
|
|
@@ -4378,8 +4243,8 @@ function cmdCreate(type, name, projectRoot = process.cwd()) {
|
|
|
4378
4243
|
}
|
|
4379
4244
|
|
|
4380
4245
|
// src/commands/doctor.ts
|
|
4381
|
-
import { existsSync as existsSync16, readdirSync as readdirSync5, readFileSync as
|
|
4382
|
-
import { dirname as
|
|
4246
|
+
import { existsSync as existsSync16, readdirSync as readdirSync5, readFileSync as readFileSync12, statSync as statSync5 } from "fs";
|
|
4247
|
+
import { dirname as dirname4, join as join18, relative as relative5 } from "path";
|
|
4383
4248
|
import { fileURLToPath } from "url";
|
|
4384
4249
|
import { isV4 as isV43 } from "@decantr/essence-spec";
|
|
4385
4250
|
import { collectMissingPackManifestFiles } from "@decantr/verifier";
|
|
@@ -4393,7 +4258,7 @@ var RESET5 = "\x1B[0m";
|
|
|
4393
4258
|
function readJson2(path) {
|
|
4394
4259
|
if (!existsSync16(path)) return null;
|
|
4395
4260
|
try {
|
|
4396
|
-
return JSON.parse(
|
|
4261
|
+
return JSON.parse(readFileSync12(path, "utf-8"));
|
|
4397
4262
|
} catch {
|
|
4398
4263
|
return null;
|
|
4399
4264
|
}
|
|
@@ -4403,16 +4268,16 @@ function isContractOnlyProject(projectRoot) {
|
|
|
4403
4268
|
return projectJson?.initialized?.adoptionMode === "contract-only" || projectJson?.initialized?.adoptionMode === "style-bridge";
|
|
4404
4269
|
}
|
|
4405
4270
|
function readCliPackageVersion() {
|
|
4406
|
-
const packagePath = join18(
|
|
4407
|
-
const srcPackagePath = join18(
|
|
4271
|
+
const packagePath = join18(dirname4(fileURLToPath(import.meta.url)), "..", "..", "package.json");
|
|
4272
|
+
const srcPackagePath = join18(dirname4(fileURLToPath(import.meta.url)), "..", "package.json");
|
|
4408
4273
|
const pkg = readJson2(packagePath) ?? readJson2(srcPackagePath);
|
|
4409
4274
|
return pkg?.version ?? "unknown";
|
|
4410
4275
|
}
|
|
4411
|
-
function
|
|
4276
|
+
function readPackageJson(dir) {
|
|
4412
4277
|
return readJson2(join18(dir, "package.json"));
|
|
4413
4278
|
}
|
|
4414
|
-
function
|
|
4415
|
-
const pkg =
|
|
4279
|
+
function detectPackageManager2(root) {
|
|
4280
|
+
const pkg = readPackageJson(root);
|
|
4416
4281
|
const declared = pkg?.packageManager?.split("@")[0];
|
|
4417
4282
|
if (declared === "pnpm" || declared === "npm" || declared === "yarn" || declared === "bun") {
|
|
4418
4283
|
return declared;
|
|
@@ -4424,11 +4289,11 @@ function detectPackageManager3(root) {
|
|
|
4424
4289
|
return "unknown";
|
|
4425
4290
|
}
|
|
4426
4291
|
function localCliDependency(root) {
|
|
4427
|
-
const pkg =
|
|
4292
|
+
const pkg = readPackageJson(root);
|
|
4428
4293
|
return pkg?.devDependencies?.["@decantr/cli"] ?? pkg?.dependencies?.["@decantr/cli"] ?? null;
|
|
4429
4294
|
}
|
|
4430
4295
|
function hasWorkspaceMarker2(root) {
|
|
4431
|
-
const pkg =
|
|
4296
|
+
const pkg = readPackageJson(root);
|
|
4432
4297
|
return Boolean(
|
|
4433
4298
|
existsSync16(join18(root, "pnpm-workspace.yaml")) || existsSync16(join18(root, "turbo.json")) || existsSync16(join18(root, "nx.json")) || pkg?.workspaces
|
|
4434
4299
|
);
|
|
@@ -4451,7 +4316,7 @@ function rel(root, path) {
|
|
|
4451
4316
|
const value = relative5(root, path).replace(/\\/g, "/");
|
|
4452
4317
|
return value || ".";
|
|
4453
4318
|
}
|
|
4454
|
-
function
|
|
4319
|
+
function hasAnyFile(dir, names) {
|
|
4455
4320
|
for (const name of names) {
|
|
4456
4321
|
const path = join18(dir, name);
|
|
4457
4322
|
if (existsSync16(path)) return name;
|
|
@@ -4459,7 +4324,7 @@ function hasAnyFile2(dir, names) {
|
|
|
4459
4324
|
return null;
|
|
4460
4325
|
}
|
|
4461
4326
|
function packageHasDependency(dir, names) {
|
|
4462
|
-
const pkg =
|
|
4327
|
+
const pkg = readPackageJson(dir);
|
|
4463
4328
|
const deps = { ...pkg?.dependencies, ...pkg?.devDependencies };
|
|
4464
4329
|
return names.some((name) => Boolean(deps[name]));
|
|
4465
4330
|
}
|
|
@@ -4480,7 +4345,7 @@ function detectDesignAuthority(workspaceRoot, appRoot) {
|
|
|
4480
4345
|
}
|
|
4481
4346
|
for (const root of [appRoot, workspaceRoot]) {
|
|
4482
4347
|
const label = root === appRoot ? "app" : "workspace";
|
|
4483
|
-
const tailwind =
|
|
4348
|
+
const tailwind = hasAnyFile(root, [
|
|
4484
4349
|
"tailwind.config.js",
|
|
4485
4350
|
"tailwind.config.ts",
|
|
4486
4351
|
"tailwind.config.mjs",
|
|
@@ -4506,13 +4371,13 @@ function findCiFiles(root) {
|
|
|
4506
4371
|
for (const entry of readdirSync5(workflows, { withFileTypes: true })) {
|
|
4507
4372
|
if (!entry.isFile()) continue;
|
|
4508
4373
|
const path = join18(workflows, entry.name);
|
|
4509
|
-
const text =
|
|
4374
|
+
const text = readFileSync12(path, "utf-8");
|
|
4510
4375
|
if (text.includes("decantr")) files.push(rel(root, path));
|
|
4511
4376
|
}
|
|
4512
4377
|
}
|
|
4513
4378
|
for (const candidate of ["Jenkinsfile", ".gitlab-ci.yml", "azure-pipelines.yml", "BUILD"]) {
|
|
4514
4379
|
const path = join18(root, candidate);
|
|
4515
|
-
if (pathIsFile(path) &&
|
|
4380
|
+
if (pathIsFile(path) && readFileSync12(path, "utf-8").includes("decantr")) {
|
|
4516
4381
|
files.push(candidate);
|
|
4517
4382
|
}
|
|
4518
4383
|
}
|
|
@@ -4690,7 +4555,7 @@ function buildDoctorReport(root, args) {
|
|
|
4690
4555
|
const appRoot = workspaceMode ? workspaceRoot : workspaceInfo.appRoot;
|
|
4691
4556
|
const projectMissing = Boolean(projectArg && !existsSync16(appRoot));
|
|
4692
4557
|
const projectPath = appRoot === workspaceRoot ? null : rel(workspaceRoot, appRoot);
|
|
4693
|
-
const packageManager =
|
|
4558
|
+
const packageManager = detectPackageManager2(workspaceRoot);
|
|
4694
4559
|
const cliDependency = localCliDependency(workspaceRoot);
|
|
4695
4560
|
const detected = detectProject(appRoot);
|
|
4696
4561
|
const projectJson = readJson2(join18(appRoot, ".decantr", "project.json"));
|
|
@@ -5069,8 +4934,8 @@ async function cmdDoctor(args = ["doctor"], root = process.cwd()) {
|
|
|
5069
4934
|
}
|
|
5070
4935
|
|
|
5071
4936
|
// src/commands/export.ts
|
|
5072
|
-
import { existsSync as existsSync17, mkdirSync as mkdirSync11, readFileSync as
|
|
5073
|
-
import { dirname as
|
|
4937
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync11, readFileSync as readFileSync13, writeFileSync as writeFileSync12 } from "fs";
|
|
4938
|
+
import { dirname as dirname5, isAbsolute as isAbsolute2, join as join19 } from "path";
|
|
5074
4939
|
var GREEN6 = "\x1B[32m";
|
|
5075
4940
|
var RED4 = "\x1B[31m";
|
|
5076
4941
|
var DIM6 = "\x1B[2m";
|
|
@@ -5079,7 +4944,7 @@ function readAdoptionMode(projectRoot) {
|
|
|
5079
4944
|
const projectJsonPath = join19(projectRoot, ".decantr", "project.json");
|
|
5080
4945
|
if (!existsSync17(projectJsonPath)) return null;
|
|
5081
4946
|
try {
|
|
5082
|
-
const parsed = JSON.parse(
|
|
4947
|
+
const parsed = JSON.parse(readFileSync13(projectJsonPath, "utf-8"));
|
|
5083
4948
|
return typeof parsed.initialized?.adoptionMode === "string" ? parsed.initialized.adoptionMode : null;
|
|
5084
4949
|
} catch {
|
|
5085
4950
|
return null;
|
|
@@ -5120,9 +4985,10 @@ var TAILWIND_COLOR_MAP = {
|
|
|
5120
4985
|
function parseTokensCSS(css) {
|
|
5121
4986
|
const tokens = /* @__PURE__ */ new Map();
|
|
5122
4987
|
const re = /(--d-[\w-]+)\s*:\s*([^;]+);/g;
|
|
5123
|
-
let match;
|
|
5124
|
-
while (
|
|
4988
|
+
let match = re.exec(css);
|
|
4989
|
+
while (match !== null) {
|
|
5125
4990
|
tokens.set(match[1], match[2].trim());
|
|
4991
|
+
match = re.exec(css);
|
|
5126
4992
|
}
|
|
5127
4993
|
return tokens;
|
|
5128
4994
|
}
|
|
@@ -5262,7 +5128,7 @@ async function cmdExport(target, projectRoot, options = {}) {
|
|
|
5262
5128
|
process.exitCode = 1;
|
|
5263
5129
|
return;
|
|
5264
5130
|
}
|
|
5265
|
-
const tokensCSS =
|
|
5131
|
+
const tokensCSS = readFileSync13(tokensPath, "utf-8");
|
|
5266
5132
|
const tokens = parseTokensCSS(tokensCSS);
|
|
5267
5133
|
if (tokens.size === 0) {
|
|
5268
5134
|
console.error(`${RED4}No --d-* tokens found in tokens.css.${RESET6}`);
|
|
@@ -5324,7 +5190,7 @@ async function cmdExport(target, projectRoot, options = {}) {
|
|
|
5324
5190
|
}
|
|
5325
5191
|
}
|
|
5326
5192
|
function ensureDir(filePath) {
|
|
5327
|
-
const dir =
|
|
5193
|
+
const dir = dirname5(filePath);
|
|
5328
5194
|
if (!existsSync17(dir)) {
|
|
5329
5195
|
mkdirSync11(dir, { recursive: true });
|
|
5330
5196
|
}
|
|
@@ -5902,7 +5768,7 @@ ${GREEN7}${BOLD5}Quality summary:${RESET7}`);
|
|
|
5902
5768
|
}
|
|
5903
5769
|
|
|
5904
5770
|
// src/commands/migrate.ts
|
|
5905
|
-
import { copyFileSync, existsSync as existsSync19, readFileSync as
|
|
5771
|
+
import { copyFileSync, existsSync as existsSync19, readFileSync as readFileSync14, writeFileSync as writeFileSync13 } from "fs";
|
|
5906
5772
|
import { join as join21 } from "path";
|
|
5907
5773
|
import {
|
|
5908
5774
|
isV4 as isV44,
|
|
@@ -5921,7 +5787,7 @@ function migrateEssenceFile(essencePath) {
|
|
|
5921
5787
|
}
|
|
5922
5788
|
let raw;
|
|
5923
5789
|
try {
|
|
5924
|
-
raw =
|
|
5790
|
+
raw = readFileSync14(essencePath, "utf-8");
|
|
5925
5791
|
} catch (e) {
|
|
5926
5792
|
return { success: false, error: `Could not read ${essencePath}: ${e.message}` };
|
|
5927
5793
|
}
|
|
@@ -6240,7 +6106,7 @@ async function cmdNewProject(projectName, options) {
|
|
|
6240
6106
|
)
|
|
6241
6107
|
);
|
|
6242
6108
|
}
|
|
6243
|
-
const packageManager =
|
|
6109
|
+
const packageManager = detectPackageManager3();
|
|
6244
6110
|
if (shouldBootstrapRuntime) {
|
|
6245
6111
|
console.log(heading("Installing dependencies..."));
|
|
6246
6112
|
try {
|
|
@@ -6316,7 +6182,7 @@ ${YELLOW6}Decantr init encountered issues. Run \`decantr init\` manually inside
|
|
|
6316
6182
|
});
|
|
6317
6183
|
}
|
|
6318
6184
|
}
|
|
6319
|
-
function
|
|
6185
|
+
function detectPackageManager3() {
|
|
6320
6186
|
if (existsSync21(join23(process.cwd(), "pnpm-lock.yaml")) || existsSync21(join23(process.cwd(), "pnpm-workspace.yaml"))) {
|
|
6321
6187
|
return "pnpm";
|
|
6322
6188
|
}
|
|
@@ -6330,7 +6196,7 @@ function detectPackageManager4() {
|
|
|
6330
6196
|
}
|
|
6331
6197
|
|
|
6332
6198
|
// src/commands/publish.ts
|
|
6333
|
-
import { existsSync as existsSync22, readFileSync as
|
|
6199
|
+
import { existsSync as existsSync22, readFileSync as readFileSync15 } from "fs";
|
|
6334
6200
|
import { join as join24 } from "path";
|
|
6335
6201
|
import {
|
|
6336
6202
|
API_CONTENT_TYPE_TO_CONTENT_TYPE,
|
|
@@ -6356,7 +6222,7 @@ async function cmdPublish(type, name, projectRoot = process.cwd()) {
|
|
|
6356
6222
|
}
|
|
6357
6223
|
let data;
|
|
6358
6224
|
try {
|
|
6359
|
-
data = JSON.parse(
|
|
6225
|
+
data = JSON.parse(readFileSync15(customPath, "utf-8"));
|
|
6360
6226
|
} catch {
|
|
6361
6227
|
console.error(`Failed to parse ${customPath}`);
|
|
6362
6228
|
process.exitCode = 1;
|
|
@@ -6395,7 +6261,7 @@ async function cmdPublish(type, name, projectRoot = process.cwd()) {
|
|
|
6395
6261
|
|
|
6396
6262
|
// src/commands/refresh.ts
|
|
6397
6263
|
import { createHash } from "crypto";
|
|
6398
|
-
import { existsSync as existsSync23, readdirSync as readdirSync6, readFileSync as
|
|
6264
|
+
import { existsSync as existsSync23, readdirSync as readdirSync6, readFileSync as readFileSync16, statSync as statSync6 } from "fs";
|
|
6399
6265
|
import { isAbsolute as isAbsolute3, join as join25, relative as relative6 } from "path";
|
|
6400
6266
|
import { isV4 as isV45 } from "@decantr/essence-spec";
|
|
6401
6267
|
import { collectMissingPackManifestFiles as collectMissingPackManifestFiles2 } from "@decantr/verifier";
|
|
@@ -6404,7 +6270,7 @@ var RED7 = "\x1B[31m";
|
|
|
6404
6270
|
var DIM10 = "\x1B[2m";
|
|
6405
6271
|
var RESET10 = "\x1B[0m";
|
|
6406
6272
|
function hashFile(path) {
|
|
6407
|
-
return createHash("sha256").update(
|
|
6273
|
+
return createHash("sha256").update(readFileSync16(path)).digest("hex");
|
|
6408
6274
|
}
|
|
6409
6275
|
function walkFiles(dir) {
|
|
6410
6276
|
if (!existsSync23(dir)) return [];
|
|
@@ -6460,7 +6326,7 @@ function isContractOnlyProject2(projectRoot) {
|
|
|
6460
6326
|
const projectJsonPath = join25(projectRoot, ".decantr", "project.json");
|
|
6461
6327
|
if (!existsSync23(projectJsonPath)) return false;
|
|
6462
6328
|
try {
|
|
6463
|
-
const projectJson = JSON.parse(
|
|
6329
|
+
const projectJson = JSON.parse(readFileSync16(projectJsonPath, "utf-8"));
|
|
6464
6330
|
return projectJson.initialized?.adoptionMode === "contract-only";
|
|
6465
6331
|
} catch {
|
|
6466
6332
|
return false;
|
|
@@ -6574,7 +6440,7 @@ async function cmdRefresh(projectRoot = process.cwd(), options = {}) {
|
|
|
6574
6440
|
}
|
|
6575
6441
|
let essence;
|
|
6576
6442
|
try {
|
|
6577
|
-
const raw =
|
|
6443
|
+
const raw = readFileSync16(essencePath, "utf-8");
|
|
6578
6444
|
const parsed = JSON.parse(raw);
|
|
6579
6445
|
if (!isV45(parsed)) {
|
|
6580
6446
|
console.error(
|
|
@@ -6715,7 +6581,7 @@ Mirroring registry content to ${DIM11}.decantr/cache/${RESET11}
|
|
|
6715
6581
|
}
|
|
6716
6582
|
|
|
6717
6583
|
// src/commands/remove.ts
|
|
6718
|
-
import { existsSync as
|
|
6584
|
+
import { existsSync as existsSync24, readFileSync as readFileSync17, rmSync as rmSync2, writeFileSync as writeFileSync15 } from "fs";
|
|
6719
6585
|
import { join as join27 } from "path";
|
|
6720
6586
|
import { isV4 as isV46 } from "@decantr/essence-spec";
|
|
6721
6587
|
var GREEN12 = "\x1B[32m";
|
|
@@ -6725,14 +6591,14 @@ var DIM12 = "\x1B[2m";
|
|
|
6725
6591
|
var RESET12 = "\x1B[0m";
|
|
6726
6592
|
function readV4Essence2(projectRoot) {
|
|
6727
6593
|
const essencePath = join27(projectRoot, "decantr.essence.json");
|
|
6728
|
-
if (!
|
|
6594
|
+
if (!existsSync24(essencePath)) {
|
|
6729
6595
|
console.error(`${RED9}No decantr.essence.json found. Run \`decantr init\` first.${RESET12}`);
|
|
6730
6596
|
process.exitCode = 1;
|
|
6731
6597
|
return null;
|
|
6732
6598
|
}
|
|
6733
6599
|
let parsed;
|
|
6734
6600
|
try {
|
|
6735
|
-
parsed = JSON.parse(
|
|
6601
|
+
parsed = JSON.parse(readFileSync17(essencePath, "utf-8"));
|
|
6736
6602
|
} catch (e) {
|
|
6737
6603
|
console.error(`${RED9}Could not read essence: ${e.message}${RESET12}`);
|
|
6738
6604
|
process.exitCode = 1;
|
|
@@ -6821,7 +6687,7 @@ async function cmdRemoveSection(sectionId, args, projectRoot = process.cwd()) {
|
|
|
6821
6687
|
recomputeGlobalFeatures(essence);
|
|
6822
6688
|
removeRoutes(essence, sectionId);
|
|
6823
6689
|
const contextFile = join27(projectRoot, ".decantr", "context", `${sectionId}.md`);
|
|
6824
|
-
if (
|
|
6690
|
+
if (existsSync24(contextFile)) {
|
|
6825
6691
|
rmSync2(contextFile);
|
|
6826
6692
|
}
|
|
6827
6693
|
writeEssence2(essencePath, essence);
|
|
@@ -6833,7 +6699,7 @@ async function cmdRemoveSection(sectionId, args, projectRoot = process.cwd()) {
|
|
|
6833
6699
|
console.log(`${GREEN12}Derived files refreshed.${RESET12}`);
|
|
6834
6700
|
}
|
|
6835
6701
|
async function cmdRemovePage(path, args, projectRoot = process.cwd()) {
|
|
6836
|
-
if (!path
|
|
6702
|
+
if (!path?.includes("/")) {
|
|
6837
6703
|
console.error(`${RED9}Usage: decantr remove page <section>/<page>${RESET12}`);
|
|
6838
6704
|
console.error(`${DIM12}Example: decantr remove page settings/notifications${RESET12}`);
|
|
6839
6705
|
process.exitCode = 1;
|
|
@@ -6920,8 +6786,8 @@ async function cmdRemoveFeature(feature, args, projectRoot = process.cwd()) {
|
|
|
6920
6786
|
}
|
|
6921
6787
|
|
|
6922
6788
|
// src/commands/resolve.ts
|
|
6923
|
-
import { existsSync as
|
|
6924
|
-
import { dirname as
|
|
6789
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync15, readFileSync as readFileSync18, writeFileSync as writeFileSync16 } from "fs";
|
|
6790
|
+
import { dirname as dirname6, join as join28, resolve as resolve4 } from "path";
|
|
6925
6791
|
var BOLD7 = "\x1B[1m";
|
|
6926
6792
|
var DIM13 = "\x1B[2m";
|
|
6927
6793
|
var GREEN13 = "\x1B[32m";
|
|
@@ -6933,9 +6799,9 @@ function driftLogPath(projectRoot) {
|
|
|
6933
6799
|
}
|
|
6934
6800
|
function readDriftLog(projectRoot) {
|
|
6935
6801
|
const path = driftLogPath(projectRoot);
|
|
6936
|
-
if (!
|
|
6802
|
+
if (!existsSync25(path)) return { version: 1, entries: [] };
|
|
6937
6803
|
try {
|
|
6938
|
-
const parsed = JSON.parse(
|
|
6804
|
+
const parsed = JSON.parse(readFileSync18(path, "utf-8"));
|
|
6939
6805
|
return {
|
|
6940
6806
|
version: 1,
|
|
6941
6807
|
entries: Array.isArray(parsed.entries) ? parsed.entries : []
|
|
@@ -6946,7 +6812,7 @@ function readDriftLog(projectRoot) {
|
|
|
6946
6812
|
}
|
|
6947
6813
|
function writeDriftLog(projectRoot, log) {
|
|
6948
6814
|
const path = driftLogPath(projectRoot);
|
|
6949
|
-
mkdirSync15(
|
|
6815
|
+
mkdirSync15(dirname6(path), { recursive: true });
|
|
6950
6816
|
writeFileSync16(path, `${JSON.stringify(log, null, 2)}
|
|
6951
6817
|
`, "utf-8");
|
|
6952
6818
|
}
|
|
@@ -7066,7 +6932,7 @@ async function cmdResolve(projectRoot = process.cwd(), args = ["resolve"]) {
|
|
|
7066
6932
|
}
|
|
7067
6933
|
|
|
7068
6934
|
// src/commands/sync-drift.ts
|
|
7069
|
-
import { existsSync as
|
|
6935
|
+
import { existsSync as existsSync26, readFileSync as readFileSync19, writeFileSync as writeFileSync17 } from "fs";
|
|
7070
6936
|
import { join as join29 } from "path";
|
|
7071
6937
|
var GREEN14 = "\x1B[32m";
|
|
7072
6938
|
var RED11 = "\x1B[31m";
|
|
@@ -7077,7 +6943,7 @@ var BOLD8 = "\x1B[1m";
|
|
|
7077
6943
|
var CYAN7 = "\x1B[36m";
|
|
7078
6944
|
async function cmdSyncDrift(projectRoot = process.cwd()) {
|
|
7079
6945
|
const driftLogPath2 = join29(projectRoot, ".decantr", "drift-log.json");
|
|
7080
|
-
if (!
|
|
6946
|
+
if (!existsSync26(driftLogPath2)) {
|
|
7081
6947
|
console.log(`${GREEN14}No drift log found \u2014 no drift recorded.${RESET14}`);
|
|
7082
6948
|
console.log(
|
|
7083
6949
|
`${DIM14}Drift is logged when guard violations are detected during development.${RESET14}`
|
|
@@ -7086,7 +6952,7 @@ async function cmdSyncDrift(projectRoot = process.cwd()) {
|
|
|
7086
6952
|
}
|
|
7087
6953
|
let entries;
|
|
7088
6954
|
try {
|
|
7089
|
-
entries = JSON.parse(
|
|
6955
|
+
entries = JSON.parse(readFileSync19(driftLogPath2, "utf-8"));
|
|
7090
6956
|
} catch {
|
|
7091
6957
|
console.error(`${RED11}Could not parse drift-log.json${RESET14}`);
|
|
7092
6958
|
process.exitCode = 1;
|
|
@@ -7133,7 +6999,7 @@ ${BOLD8}Unresolved Drift Entries (${unresolved.length})${RESET14}
|
|
|
7133
6999
|
}
|
|
7134
7000
|
function resolveDriftEntries(projectRoot, options) {
|
|
7135
7001
|
const driftLogPath2 = join29(projectRoot, ".decantr", "drift-log.json");
|
|
7136
|
-
if (!
|
|
7002
|
+
if (!existsSync26(driftLogPath2)) {
|
|
7137
7003
|
return { success: true };
|
|
7138
7004
|
}
|
|
7139
7005
|
if (options.clear) {
|
|
@@ -7146,7 +7012,7 @@ function resolveDriftEntries(projectRoot, options) {
|
|
|
7146
7012
|
}
|
|
7147
7013
|
let entries;
|
|
7148
7014
|
try {
|
|
7149
|
-
entries = JSON.parse(
|
|
7015
|
+
entries = JSON.parse(readFileSync19(driftLogPath2, "utf-8"));
|
|
7150
7016
|
} catch {
|
|
7151
7017
|
return { success: false, error: "Could not parse drift-log.json" };
|
|
7152
7018
|
}
|
|
@@ -7402,7 +7268,7 @@ function trimTrailingSlashes(value) {
|
|
|
7402
7268
|
}
|
|
7403
7269
|
|
|
7404
7270
|
// src/commands/theme-switch.ts
|
|
7405
|
-
import { existsSync as
|
|
7271
|
+
import { existsSync as existsSync27, readFileSync as readFileSync20, writeFileSync as writeFileSync18 } from "fs";
|
|
7406
7272
|
import { join as join30 } from "path";
|
|
7407
7273
|
import { isV4 as isV47 } from "@decantr/essence-spec";
|
|
7408
7274
|
var GREEN16 = "\x1B[32m";
|
|
@@ -7421,14 +7287,14 @@ async function cmdThemeSwitch(themeName, args, projectRoot = process.cwd()) {
|
|
|
7421
7287
|
return;
|
|
7422
7288
|
}
|
|
7423
7289
|
const essencePath = join30(projectRoot, "decantr.essence.json");
|
|
7424
|
-
if (!
|
|
7290
|
+
if (!existsSync27(essencePath)) {
|
|
7425
7291
|
console.error(`${RED12}No decantr.essence.json found. Run \`decantr init\` first.${RESET16}`);
|
|
7426
7292
|
process.exitCode = 1;
|
|
7427
7293
|
return;
|
|
7428
7294
|
}
|
|
7429
7295
|
let parsed;
|
|
7430
7296
|
try {
|
|
7431
|
-
parsed = JSON.parse(
|
|
7297
|
+
parsed = JSON.parse(readFileSync20(essencePath, "utf-8"));
|
|
7432
7298
|
} catch (e) {
|
|
7433
7299
|
console.error(`${RED12}Could not read essence: ${e.message}${RESET16}`);
|
|
7434
7300
|
process.exitCode = 1;
|
|
@@ -7802,7 +7668,7 @@ async function runSimplifiedInit(blueprints) {
|
|
|
7802
7668
|
}
|
|
7803
7669
|
|
|
7804
7670
|
// src/theme-commands.ts
|
|
7805
|
-
import { existsSync as
|
|
7671
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync16, readdirSync as readdirSync7, readFileSync as readFileSync21, rmSync as rmSync3, writeFileSync as writeFileSync19 } from "fs";
|
|
7806
7672
|
import { join as join31 } from "path";
|
|
7807
7673
|
var REQUIRED_FIELDS = [
|
|
7808
7674
|
"$schema",
|
|
@@ -7867,7 +7733,7 @@ function createTheme(projectRoot, id, name) {
|
|
|
7867
7733
|
const themePath = join31(customThemesDir, `${id}.json`);
|
|
7868
7734
|
const howToPath = join31(customThemesDir, "how-to-theme.md");
|
|
7869
7735
|
mkdirSync16(customThemesDir, { recursive: true });
|
|
7870
|
-
if (
|
|
7736
|
+
if (existsSync28(themePath)) {
|
|
7871
7737
|
return {
|
|
7872
7738
|
success: false,
|
|
7873
7739
|
error: `Theme "${id}" already exists at ${themePath}`
|
|
@@ -7875,7 +7741,7 @@ function createTheme(projectRoot, id, name) {
|
|
|
7875
7741
|
}
|
|
7876
7742
|
const skeleton = getThemeSkeleton(id, name);
|
|
7877
7743
|
writeFileSync19(themePath, JSON.stringify(skeleton, null, 2));
|
|
7878
|
-
if (!
|
|
7744
|
+
if (!existsSync28(howToPath)) {
|
|
7879
7745
|
writeFileSync19(howToPath, getHowToThemeDoc());
|
|
7880
7746
|
}
|
|
7881
7747
|
return {
|
|
@@ -7885,7 +7751,7 @@ function createTheme(projectRoot, id, name) {
|
|
|
7885
7751
|
}
|
|
7886
7752
|
function listCustomThemes(projectRoot) {
|
|
7887
7753
|
const customThemesDir = join31(projectRoot, ".decantr", "custom", "themes");
|
|
7888
|
-
if (!
|
|
7754
|
+
if (!existsSync28(customThemesDir)) {
|
|
7889
7755
|
return [];
|
|
7890
7756
|
}
|
|
7891
7757
|
const themes = [];
|
|
@@ -7894,7 +7760,7 @@ function listCustomThemes(projectRoot) {
|
|
|
7894
7760
|
for (const file of files) {
|
|
7895
7761
|
const filePath = join31(customThemesDir, file);
|
|
7896
7762
|
try {
|
|
7897
|
-
const data = JSON.parse(
|
|
7763
|
+
const data = JSON.parse(readFileSync21(filePath, "utf-8"));
|
|
7898
7764
|
themes.push({
|
|
7899
7765
|
id: data.id || file.replace(".json", ""),
|
|
7900
7766
|
name: data.name || data.id,
|
|
@@ -7910,7 +7776,7 @@ function listCustomThemes(projectRoot) {
|
|
|
7910
7776
|
}
|
|
7911
7777
|
function deleteTheme(projectRoot, id) {
|
|
7912
7778
|
const themePath = join31(projectRoot, ".decantr", "custom", "themes", `${id}.json`);
|
|
7913
|
-
if (!
|
|
7779
|
+
if (!existsSync28(themePath)) {
|
|
7914
7780
|
return {
|
|
7915
7781
|
success: false,
|
|
7916
7782
|
error: `Theme "${id}" not found at ${themePath}`
|
|
@@ -7927,7 +7793,7 @@ function deleteTheme(projectRoot, id) {
|
|
|
7927
7793
|
}
|
|
7928
7794
|
}
|
|
7929
7795
|
function importTheme(projectRoot, sourcePath) {
|
|
7930
|
-
if (!
|
|
7796
|
+
if (!existsSync28(sourcePath)) {
|
|
7931
7797
|
return {
|
|
7932
7798
|
success: false,
|
|
7933
7799
|
errors: [`Source file not found: ${sourcePath}`]
|
|
@@ -7935,7 +7801,7 @@ function importTheme(projectRoot, sourcePath) {
|
|
|
7935
7801
|
}
|
|
7936
7802
|
let theme;
|
|
7937
7803
|
try {
|
|
7938
|
-
theme = JSON.parse(
|
|
7804
|
+
theme = JSON.parse(readFileSync21(sourcePath, "utf-8"));
|
|
7939
7805
|
} catch (e) {
|
|
7940
7806
|
return {
|
|
7941
7807
|
success: false,
|
|
@@ -7955,7 +7821,7 @@ function importTheme(projectRoot, sourcePath) {
|
|
|
7955
7821
|
const destPath = join31(customThemesDir, `${id}.json`);
|
|
7956
7822
|
mkdirSync16(customThemesDir, { recursive: true });
|
|
7957
7823
|
const howToPath = join31(customThemesDir, "how-to-theme.md");
|
|
7958
|
-
if (!
|
|
7824
|
+
if (!existsSync28(howToPath)) {
|
|
7959
7825
|
writeFileSync19(howToPath, getHowToThemeDoc());
|
|
7960
7826
|
}
|
|
7961
7827
|
writeFileSync19(destPath, JSON.stringify(theme, null, 2));
|
|
@@ -8507,16 +8373,16 @@ function extractHostedAssetPaths(indexHtml) {
|
|
|
8507
8373
|
function readHostedDistSnapshot(distPath) {
|
|
8508
8374
|
const resolvedDistPath = distPath ? resolveUserPath(distPath) : join32(process.cwd(), "dist");
|
|
8509
8375
|
const indexPath = join32(resolvedDistPath, "index.html");
|
|
8510
|
-
if (!
|
|
8376
|
+
if (!existsSync29(indexPath)) {
|
|
8511
8377
|
return void 0;
|
|
8512
8378
|
}
|
|
8513
|
-
const indexHtml =
|
|
8379
|
+
const indexHtml = readFileSync22(indexPath, "utf-8");
|
|
8514
8380
|
const assetPaths = extractHostedAssetPaths(indexHtml);
|
|
8515
8381
|
const assets = {};
|
|
8516
8382
|
for (const assetPath of assetPaths) {
|
|
8517
8383
|
const assetFilePath = join32(resolvedDistPath, assetPath.replace(/^[/\\]+/, ""));
|
|
8518
|
-
if (
|
|
8519
|
-
assets[assetPath] =
|
|
8384
|
+
if (existsSync29(assetFilePath)) {
|
|
8385
|
+
assets[assetPath] = readFileSync22(assetFilePath, "utf-8");
|
|
8520
8386
|
}
|
|
8521
8387
|
}
|
|
8522
8388
|
return {
|
|
@@ -8531,7 +8397,7 @@ function isHostedSourceSnapshotFile(path) {
|
|
|
8531
8397
|
function readHostedSourceSnapshot(sourcePath) {
|
|
8532
8398
|
if (!sourcePath) return void 0;
|
|
8533
8399
|
const resolvedSourcePath = resolveUserPath(sourcePath);
|
|
8534
|
-
if (!
|
|
8400
|
+
if (!existsSync29(resolvedSourcePath)) {
|
|
8535
8401
|
return void 0;
|
|
8536
8402
|
}
|
|
8537
8403
|
const files = {};
|
|
@@ -8555,7 +8421,7 @@ function readHostedSourceSnapshot(sourcePath) {
|
|
|
8555
8421
|
}
|
|
8556
8422
|
if (!entry.isFile()) continue;
|
|
8557
8423
|
if (!isHostedSourceSnapshotFile(relativePath)) continue;
|
|
8558
|
-
files[relativePath] =
|
|
8424
|
+
files[relativePath] = readFileSync22(absolutePath, "utf-8");
|
|
8559
8425
|
}
|
|
8560
8426
|
};
|
|
8561
8427
|
walk(resolvedSourcePath, rootPrefix);
|
|
@@ -8749,12 +8615,12 @@ async function printHostedExecutionPackBundle(essencePath, namespace, jsonOutput
|
|
|
8749
8615
|
async function compileHostedExecutionPackBundle(essencePath, namespace) {
|
|
8750
8616
|
const client = getPublicAPIClient();
|
|
8751
8617
|
const resolvedPath = essencePath ? resolveUserPath(essencePath) : join32(process.cwd(), "decantr.essence.json");
|
|
8752
|
-
if (!
|
|
8618
|
+
if (!existsSync29(resolvedPath)) {
|
|
8753
8619
|
throw new Error(`Essence file not found at ${resolvedPath}`);
|
|
8754
8620
|
}
|
|
8755
|
-
const essence = JSON.parse(
|
|
8621
|
+
const essence = JSON.parse(readFileSync22(resolvedPath, "utf-8"));
|
|
8756
8622
|
const bundle = await client.compileExecutionPacks(essence, namespace ? { namespace } : void 0);
|
|
8757
|
-
const contextDir = join32(
|
|
8623
|
+
const contextDir = join32(dirname7(resolvedPath), ".decantr", "context");
|
|
8758
8624
|
return { resolvedPath, bundle, contextDir };
|
|
8759
8625
|
}
|
|
8760
8626
|
function writeHostedExecutionPackContextArtifacts(contextDir, bundle) {
|
|
@@ -8762,10 +8628,10 @@ function writeHostedExecutionPackContextArtifacts(contextDir, bundle) {
|
|
|
8762
8628
|
return writeExecutionPackBundleArtifacts(contextDir, bundle);
|
|
8763
8629
|
}
|
|
8764
8630
|
function resolvePagePackIdForRoute(essencePath, route) {
|
|
8765
|
-
if (!
|
|
8631
|
+
if (!existsSync29(essencePath)) {
|
|
8766
8632
|
throw new Error(`Essence file not found at ${essencePath}`);
|
|
8767
8633
|
}
|
|
8768
|
-
const essence = JSON.parse(
|
|
8634
|
+
const essence = JSON.parse(readFileSync22(essencePath, "utf-8"));
|
|
8769
8635
|
if (!isV48(essence)) {
|
|
8770
8636
|
throw new Error("Route-based pack resolution requires Essence v4.0.0.");
|
|
8771
8637
|
}
|
|
@@ -8781,13 +8647,13 @@ function resolvePagePackIdForRoute(essencePath, route) {
|
|
|
8781
8647
|
async function printHostedSelectedExecutionPack(packType, id, essencePath, namespace, jsonOutput = false, writeContext = false) {
|
|
8782
8648
|
const client = getPublicAPIClient();
|
|
8783
8649
|
const resolvedPath = essencePath ? resolveUserPath(essencePath) : join32(process.cwd(), "decantr.essence.json");
|
|
8784
|
-
if (!
|
|
8650
|
+
if (!existsSync29(resolvedPath)) {
|
|
8785
8651
|
throw new Error(`Essence file not found at ${resolvedPath}`);
|
|
8786
8652
|
}
|
|
8787
8653
|
if ((packType === "section" || packType === "page" || packType === "mutation") && !id) {
|
|
8788
8654
|
throw new Error(`Pack type "${packType}" requires an id.`);
|
|
8789
8655
|
}
|
|
8790
|
-
const essence = JSON.parse(
|
|
8656
|
+
const essence = JSON.parse(readFileSync22(resolvedPath, "utf-8"));
|
|
8791
8657
|
const selected = await client.selectExecutionPack(
|
|
8792
8658
|
{
|
|
8793
8659
|
essence,
|
|
@@ -8798,7 +8664,7 @@ async function printHostedSelectedExecutionPack(packType, id, essencePath, names
|
|
|
8798
8664
|
);
|
|
8799
8665
|
let writtenContextDir = null;
|
|
8800
8666
|
if (writeContext) {
|
|
8801
|
-
const contextDir = join32(
|
|
8667
|
+
const contextDir = join32(dirname7(resolvedPath), ".decantr", "context");
|
|
8802
8668
|
mkdirSync17(contextDir, { recursive: true });
|
|
8803
8669
|
writeFileSync20(
|
|
8804
8670
|
join32(contextDir, "pack-manifest.json"),
|
|
@@ -8834,17 +8700,17 @@ async function printHostedSelectedExecutionPack(packType, id, essencePath, names
|
|
|
8834
8700
|
async function printHostedExecutionPackManifest(essencePath, namespace, jsonOutput = false, writeContext = false) {
|
|
8835
8701
|
const client = getPublicAPIClient();
|
|
8836
8702
|
const resolvedPath = essencePath ? resolveUserPath(essencePath) : join32(process.cwd(), "decantr.essence.json");
|
|
8837
|
-
if (!
|
|
8703
|
+
if (!existsSync29(resolvedPath)) {
|
|
8838
8704
|
throw new Error(`Essence file not found at ${resolvedPath}`);
|
|
8839
8705
|
}
|
|
8840
|
-
const essence = JSON.parse(
|
|
8706
|
+
const essence = JSON.parse(readFileSync22(resolvedPath, "utf-8"));
|
|
8841
8707
|
const manifest = await client.getExecutionPackManifest(
|
|
8842
8708
|
essence,
|
|
8843
8709
|
namespace ? { namespace } : void 0
|
|
8844
8710
|
);
|
|
8845
8711
|
let writtenContextDir = null;
|
|
8846
8712
|
if (writeContext) {
|
|
8847
|
-
const contextDir = join32(
|
|
8713
|
+
const contextDir = join32(dirname7(resolvedPath), ".decantr", "context");
|
|
8848
8714
|
mkdirSync17(contextDir, { recursive: true });
|
|
8849
8715
|
writeFileSync20(join32(contextDir, "pack-manifest.json"), JSON.stringify(manifest, null, 2) + "\n");
|
|
8850
8716
|
writtenContextDir = contextDir;
|
|
@@ -8870,11 +8736,11 @@ async function hydrateHostedExecutionPacksIfMissing(projectRoot, namespace = "@o
|
|
|
8870
8736
|
const contextDir = join32(projectRoot, ".decantr", "context");
|
|
8871
8737
|
const reviewPackPath = join32(contextDir, "review-pack.json");
|
|
8872
8738
|
const manifestPath = join32(contextDir, "pack-manifest.json");
|
|
8873
|
-
if (
|
|
8739
|
+
if (existsSync29(reviewPackPath) && existsSync29(manifestPath)) {
|
|
8874
8740
|
return { attempted: false, hydrated: false };
|
|
8875
8741
|
}
|
|
8876
8742
|
const essencePath = join32(projectRoot, "decantr.essence.json");
|
|
8877
|
-
if (!
|
|
8743
|
+
if (!existsSync29(essencePath)) {
|
|
8878
8744
|
return { attempted: false, hydrated: false };
|
|
8879
8745
|
}
|
|
8880
8746
|
const reviewHydration = await hydrateHostedReviewPackIfMissing(projectRoot, namespace);
|
|
@@ -8883,7 +8749,7 @@ async function hydrateHostedExecutionPacksIfMissing(projectRoot, namespace = "@o
|
|
|
8883
8749
|
}
|
|
8884
8750
|
try {
|
|
8885
8751
|
const client = getPublicAPIClient();
|
|
8886
|
-
const essence = JSON.parse(
|
|
8752
|
+
const essence = JSON.parse(readFileSync22(essencePath, "utf-8"));
|
|
8887
8753
|
const bundle = await client.compileExecutionPacks(essence, { namespace });
|
|
8888
8754
|
mkdirSync17(contextDir, { recursive: true });
|
|
8889
8755
|
writeExecutionPackBundleArtifacts(contextDir, bundle);
|
|
@@ -8896,16 +8762,16 @@ async function hydrateHostedReviewPackIfMissing(projectRoot, namespace = "@offic
|
|
|
8896
8762
|
const contextDir = join32(projectRoot, ".decantr", "context");
|
|
8897
8763
|
const reviewPackPath = join32(contextDir, "review-pack.json");
|
|
8898
8764
|
const manifestPath = join32(contextDir, "pack-manifest.json");
|
|
8899
|
-
if (
|
|
8765
|
+
if (existsSync29(reviewPackPath) && existsSync29(manifestPath)) {
|
|
8900
8766
|
return { attempted: false, hydrated: false };
|
|
8901
8767
|
}
|
|
8902
8768
|
const essencePath = join32(projectRoot, "decantr.essence.json");
|
|
8903
|
-
if (!
|
|
8769
|
+
if (!existsSync29(essencePath)) {
|
|
8904
8770
|
return { attempted: false, hydrated: false };
|
|
8905
8771
|
}
|
|
8906
8772
|
try {
|
|
8907
8773
|
const client = getPublicAPIClient();
|
|
8908
|
-
const essence = JSON.parse(
|
|
8774
|
+
const essence = JSON.parse(readFileSync22(essencePath, "utf-8"));
|
|
8909
8775
|
const selected = await client.selectExecutionPack(
|
|
8910
8776
|
{
|
|
8911
8777
|
essence,
|
|
@@ -8919,7 +8785,7 @@ async function hydrateHostedReviewPackIfMissing(projectRoot, namespace = "@offic
|
|
|
8919
8785
|
join32(contextDir, "review-pack.json"),
|
|
8920
8786
|
JSON.stringify(selected.pack, null, 2) + "\n"
|
|
8921
8787
|
);
|
|
8922
|
-
if (!
|
|
8788
|
+
if (!existsSync29(manifestPath)) {
|
|
8923
8789
|
writeFileSync20(manifestPath, JSON.stringify(selected.manifest, null, 2) + "\n");
|
|
8924
8790
|
}
|
|
8925
8791
|
return { attempted: true, hydrated: true, scope: "review" };
|
|
@@ -8932,15 +8798,15 @@ async function printHostedFileCritique(sourcePath, namespace, jsonOutput = false
|
|
|
8932
8798
|
const resolvedSourcePath = resolveUserPath(sourcePath);
|
|
8933
8799
|
const resolvedEssencePath = essencePath ? resolveUserPath(essencePath) : join32(process.cwd(), "decantr.essence.json");
|
|
8934
8800
|
const resolvedTreatmentsPath = treatmentsPath ? resolveUserPath(treatmentsPath) : join32(process.cwd(), "src", "styles", "treatments.css");
|
|
8935
|
-
if (!
|
|
8801
|
+
if (!existsSync29(resolvedSourcePath)) {
|
|
8936
8802
|
throw new Error(`Source file not found at ${resolvedSourcePath}`);
|
|
8937
8803
|
}
|
|
8938
|
-
if (!
|
|
8804
|
+
if (!existsSync29(resolvedEssencePath)) {
|
|
8939
8805
|
throw new Error(`Essence file not found at ${resolvedEssencePath}`);
|
|
8940
8806
|
}
|
|
8941
|
-
const code =
|
|
8942
|
-
const essence = JSON.parse(
|
|
8943
|
-
const treatmentsCss =
|
|
8807
|
+
const code = readFileSync22(resolvedSourcePath, "utf-8");
|
|
8808
|
+
const essence = JSON.parse(readFileSync22(resolvedEssencePath, "utf-8"));
|
|
8809
|
+
const treatmentsCss = existsSync29(resolvedTreatmentsPath) ? readFileSync22(resolvedTreatmentsPath, "utf-8") : void 0;
|
|
8944
8810
|
const report = await client.critiqueFile(
|
|
8945
8811
|
{
|
|
8946
8812
|
essence,
|
|
@@ -8965,10 +8831,10 @@ async function printHostedFileCritique(sourcePath, namespace, jsonOutput = false
|
|
|
8965
8831
|
async function printHostedProjectAudit(namespace, jsonOutput = false, essencePath, distPath, sourcesPath) {
|
|
8966
8832
|
const client = getPublicAPIClient();
|
|
8967
8833
|
const resolvedEssencePath = essencePath ? resolveUserPath(essencePath) : join32(process.cwd(), "decantr.essence.json");
|
|
8968
|
-
if (!
|
|
8834
|
+
if (!existsSync29(resolvedEssencePath)) {
|
|
8969
8835
|
throw new Error(`Essence file not found at ${resolvedEssencePath}`);
|
|
8970
8836
|
}
|
|
8971
|
-
const essence = JSON.parse(
|
|
8837
|
+
const essence = JSON.parse(readFileSync22(resolvedEssencePath, "utf-8"));
|
|
8972
8838
|
const dist = readHostedDistSnapshot(distPath);
|
|
8973
8839
|
const sources = readHostedSourceSnapshot(sourcesPath);
|
|
8974
8840
|
const report = await client.auditProject(
|
|
@@ -9109,20 +8975,20 @@ function readSuggestCodeContext(projectRoot, route, file) {
|
|
|
9109
8975
|
const pieces = [];
|
|
9110
8976
|
if (file) {
|
|
9111
8977
|
const resolved = isAbsolute4(file) ? file : join32(projectRoot, file);
|
|
9112
|
-
if (
|
|
9113
|
-
pieces.push(
|
|
8978
|
+
if (existsSync29(resolved)) {
|
|
8979
|
+
pieces.push(readFileSync22(resolved, "utf-8"));
|
|
9114
8980
|
}
|
|
9115
8981
|
}
|
|
9116
8982
|
if (route) {
|
|
9117
8983
|
const analysisPath = join32(projectRoot, ".decantr", "analysis.json");
|
|
9118
|
-
if (
|
|
8984
|
+
if (existsSync29(analysisPath)) {
|
|
9119
8985
|
try {
|
|
9120
|
-
const analysis = JSON.parse(
|
|
8986
|
+
const analysis = JSON.parse(readFileSync22(analysisPath, "utf-8"));
|
|
9121
8987
|
const routeEntry = analysis.routes?.routes?.find((entry) => entry.path === route);
|
|
9122
8988
|
if (routeEntry?.file) {
|
|
9123
8989
|
const resolved = join32(projectRoot, routeEntry.file);
|
|
9124
|
-
if (
|
|
9125
|
-
pieces.push(
|
|
8990
|
+
if (existsSync29(resolved)) {
|
|
8991
|
+
pieces.push(readFileSync22(resolved, "utf-8"));
|
|
9126
8992
|
}
|
|
9127
8993
|
}
|
|
9128
8994
|
} catch {
|
|
@@ -9317,7 +9183,7 @@ async function cmdValidate(path) {
|
|
|
9317
9183
|
const essencePath = path || join32(process.cwd(), "decantr.essence.json");
|
|
9318
9184
|
let raw;
|
|
9319
9185
|
try {
|
|
9320
|
-
raw =
|
|
9186
|
+
raw = readFileSync22(essencePath, "utf-8");
|
|
9321
9187
|
} catch {
|
|
9322
9188
|
console.error(error2(`Could not read ${essencePath}`));
|
|
9323
9189
|
process.exitCode = 1;
|
|
@@ -9466,11 +9332,11 @@ ${CYAN10}Telemetry enabled.${RESET18} Decantr will send privacy-filtered CLI pro
|
|
|
9466
9332
|
console.log(`${DIM18}Set "telemetry": false in .decantr/project.json to opt out.${RESET18}`);
|
|
9467
9333
|
}
|
|
9468
9334
|
function readCliPackageVersion2() {
|
|
9469
|
-
const here =
|
|
9335
|
+
const here = dirname7(fileURLToPath3(import.meta.url));
|
|
9470
9336
|
const candidates = [join32(here, "..", "package.json"), join32(here, "..", "..", "package.json")];
|
|
9471
9337
|
for (const candidate of candidates) {
|
|
9472
9338
|
try {
|
|
9473
|
-
const pkg = JSON.parse(
|
|
9339
|
+
const pkg = JSON.parse(readFileSync22(candidate, "utf-8"));
|
|
9474
9340
|
if (pkg.version) return pkg.version;
|
|
9475
9341
|
} catch {
|
|
9476
9342
|
}
|
|
@@ -9482,12 +9348,12 @@ function timestampForFile() {
|
|
|
9482
9348
|
}
|
|
9483
9349
|
function backupExistingEssence(projectRoot, label) {
|
|
9484
9350
|
const essencePath = join32(projectRoot, "decantr.essence.json");
|
|
9485
|
-
if (!
|
|
9351
|
+
if (!existsSync29(essencePath)) return null;
|
|
9486
9352
|
const backupPath = join32(
|
|
9487
9353
|
projectRoot,
|
|
9488
9354
|
`decantr.essence.${label}.${timestampForFile()}.backup.json`
|
|
9489
9355
|
);
|
|
9490
|
-
writeFileSync20(backupPath,
|
|
9356
|
+
writeFileSync20(backupPath, readFileSync22(essencePath, "utf-8"), "utf-8");
|
|
9491
9357
|
return backupPath;
|
|
9492
9358
|
}
|
|
9493
9359
|
function writeBrownfieldProjectJson(input) {
|
|
@@ -9551,7 +9417,7 @@ async function applyAcceptedBrownfieldProposal(input) {
|
|
|
9551
9417
|
return;
|
|
9552
9418
|
}
|
|
9553
9419
|
const essencePath = join32(input.projectRoot, "decantr.essence.json");
|
|
9554
|
-
const hasEssence =
|
|
9420
|
+
const hasEssence = existsSync29(essencePath);
|
|
9555
9421
|
let essence;
|
|
9556
9422
|
let backupPath = null;
|
|
9557
9423
|
if (input.mode === "accept" && hasEssence) {
|
|
@@ -9565,7 +9431,7 @@ async function applyAcceptedBrownfieldProposal(input) {
|
|
|
9565
9431
|
return;
|
|
9566
9432
|
}
|
|
9567
9433
|
if (input.mode === "merge" && hasEssence) {
|
|
9568
|
-
const existing = JSON.parse(
|
|
9434
|
+
const existing = JSON.parse(readFileSync22(essencePath, "utf-8"));
|
|
9569
9435
|
if (!isV48(existing)) {
|
|
9570
9436
|
console.log(
|
|
9571
9437
|
error2(
|
|
@@ -10115,7 +9981,7 @@ ${YELLOW13}You're offline. Scaffolding Decantr default.${RESET18}`);
|
|
|
10115
9981
|
if (appliedRuleFiles.length > 0) {
|
|
10116
9982
|
console.log(` ${dim4(`Rule bridge applied: ${appliedRuleFiles.join(", ")}`)}`);
|
|
10117
9983
|
}
|
|
10118
|
-
if (!
|
|
9984
|
+
if (!existsSync29(join32(projectRoot, "package.json"))) {
|
|
10119
9985
|
console.log("");
|
|
10120
9986
|
console.log(
|
|
10121
9987
|
dim4(` Note: ${cyan4("decantr init")} created Decantr contract/context files only.`)
|
|
@@ -10126,7 +9992,7 @@ ${YELLOW13}You're offline. Scaffolding Decantr default.${RESET18}`);
|
|
|
10126
9992
|
)
|
|
10127
9993
|
);
|
|
10128
9994
|
}
|
|
10129
|
-
const hasCompiledPacks =
|
|
9995
|
+
const hasCompiledPacks = existsSync29(join32(projectRoot, ".decantr", "context", "scaffold-pack.md"));
|
|
10130
9996
|
console.log("");
|
|
10131
9997
|
console.log(" Next steps:");
|
|
10132
9998
|
if (hasCompiledPacks) {
|
|
@@ -10166,7 +10032,7 @@ ${YELLOW13}You're offline. Scaffolding Decantr default.${RESET18}`);
|
|
|
10166
10032
|
console.log(` ${cyan4("decantr upgrade")} Update to latest patterns`);
|
|
10167
10033
|
console.log(` ${cyan4("decantr check")} Detect drift issues`);
|
|
10168
10034
|
console.log(` ${cyan4("decantr migrate --to v4")} Migrate older essence files to v4`);
|
|
10169
|
-
const essenceContent =
|
|
10035
|
+
const essenceContent = readFileSync22(result.essencePath, "utf-8");
|
|
10170
10036
|
const essence = JSON.parse(essenceContent);
|
|
10171
10037
|
const validation = validateEssence2(essence);
|
|
10172
10038
|
if (!validation.valid) {
|
|
@@ -10224,13 +10090,13 @@ async function cmdStatus(projectRoot = process.cwd()) {
|
|
|
10224
10090
|
const essencePath = join32(projectRoot, "decantr.essence.json");
|
|
10225
10091
|
const projectJsonPath = join32(projectRoot, ".decantr", "project.json");
|
|
10226
10092
|
console.log(heading2("Decantr Project Status"));
|
|
10227
|
-
if (!
|
|
10093
|
+
if (!existsSync29(essencePath)) {
|
|
10228
10094
|
console.log(`${RED13}No decantr.essence.json found.${RESET18}`);
|
|
10229
10095
|
console.log(dim4('Run "decantr init" to create one.'));
|
|
10230
10096
|
return;
|
|
10231
10097
|
}
|
|
10232
10098
|
try {
|
|
10233
|
-
const essence = JSON.parse(
|
|
10099
|
+
const essence = JSON.parse(readFileSync22(essencePath, "utf-8"));
|
|
10234
10100
|
const validation = validateEssence2(essence);
|
|
10235
10101
|
const essenceVersion = isV48(essence) ? "v4" : "legacy";
|
|
10236
10102
|
console.log(`${BOLD11}Essence:${RESET18}`);
|
|
@@ -10278,9 +10144,9 @@ async function cmdStatus(projectRoot = process.cwd()) {
|
|
|
10278
10144
|
}
|
|
10279
10145
|
console.log("");
|
|
10280
10146
|
console.log(`${BOLD11}Sync Status:${RESET18}`);
|
|
10281
|
-
if (
|
|
10147
|
+
if (existsSync29(projectJsonPath)) {
|
|
10282
10148
|
try {
|
|
10283
|
-
const projectJson = JSON.parse(
|
|
10149
|
+
const projectJson = JSON.parse(readFileSync22(projectJsonPath, "utf-8"));
|
|
10284
10150
|
const syncStatus = projectJson.sync?.status || "unknown";
|
|
10285
10151
|
const lastSync = projectJson.sync?.lastSync || "never";
|
|
10286
10152
|
const source = projectJson.sync?.registrySource || "unknown";
|
|
@@ -10493,13 +10359,13 @@ ${BOLD11}Examples:${RESET18}
|
|
|
10493
10359
|
return;
|
|
10494
10360
|
}
|
|
10495
10361
|
const themePath = join32(projectRoot, ".decantr", "custom", "themes", `${name}.json`);
|
|
10496
|
-
if (!
|
|
10362
|
+
if (!existsSync29(themePath)) {
|
|
10497
10363
|
console.error(error2(`Theme "${name}" not found at ${themePath}`));
|
|
10498
10364
|
process.exitCode = 1;
|
|
10499
10365
|
return;
|
|
10500
10366
|
}
|
|
10501
10367
|
try {
|
|
10502
|
-
const theme = JSON.parse(
|
|
10368
|
+
const theme = JSON.parse(readFileSync22(themePath, "utf-8"));
|
|
10503
10369
|
const result = validateCustomTheme(theme);
|
|
10504
10370
|
if (result.valid) {
|
|
10505
10371
|
console.log(success4(`Custom theme "${name}" is valid`));
|
|
@@ -10729,7 +10595,7 @@ function printWorkspaceProjectSelection(workspaceInfo, commandName = "command")
|
|
|
10729
10595
|
function printMonorepoSetupGuidance(workspaceInfo) {
|
|
10730
10596
|
const candidate = firstWorkspaceCandidate(workspaceInfo);
|
|
10731
10597
|
const attachedProjects = workspaceInfo.appCandidates.filter(
|
|
10732
|
-
(appCandidate) =>
|
|
10598
|
+
(appCandidate) => existsSync29(join32(workspaceInfo.workspaceRoot, appCandidate, "decantr.essence.json"))
|
|
10733
10599
|
);
|
|
10734
10600
|
const firstAttached = attachedProjects[0];
|
|
10735
10601
|
console.log(heading2("Decantr Setup"));
|
|
@@ -10797,7 +10663,7 @@ function printMonorepoSetupGuidance(workspaceInfo) {
|
|
|
10797
10663
|
function resolveWorkflowProject(flags, commandName = "command", options = {}) {
|
|
10798
10664
|
const projectArg = flagString(flags, "project");
|
|
10799
10665
|
const workspaceInfo = resolveWorkspaceInfo(process.cwd(), projectArg);
|
|
10800
|
-
if (projectArg && options.requireExisting !== false && !
|
|
10666
|
+
if (projectArg && options.requireExisting !== false && !existsSync29(workspaceInfo.appRoot)) {
|
|
10801
10667
|
printProjectNotFound(projectArg, commandName);
|
|
10802
10668
|
process.exitCode = 1;
|
|
10803
10669
|
return null;
|
|
@@ -11019,14 +10885,23 @@ function printScanReport(report, projectArg) {
|
|
|
11019
10885
|
console.log("");
|
|
11020
10886
|
printScanGraphPreview(report.graphPreview);
|
|
11021
10887
|
console.log(`${BOLD11}Routes And Styling${RESET18}`);
|
|
11022
|
-
|
|
10888
|
+
const routeSignalCount = report.routes.routeSignalCount ?? report.routes.count;
|
|
10889
|
+
const taskableRouteCount = report.routes.taskableRouteCount ?? report.routes.count;
|
|
10890
|
+
console.log(
|
|
10891
|
+
` Routes: ${taskableRouteCount} taskable / ${routeSignalCount} signal(s) (${report.routes.strategy}, ${report.routes.confidence})`
|
|
10892
|
+
);
|
|
11023
10893
|
for (const route of report.routes.items.slice(0, 8)) {
|
|
11024
10894
|
console.log(` ${cyan4(route.path.padEnd(18))} ${dim4(route.file)}`);
|
|
11025
10895
|
}
|
|
11026
10896
|
if (report.routes.items.length > 8) {
|
|
11027
10897
|
console.log(` ${dim4(`...${report.routes.items.length - 8} more route(s)`)}`);
|
|
11028
10898
|
}
|
|
11029
|
-
console.log(
|
|
10899
|
+
console.log(
|
|
10900
|
+
` Components: ${report.components.componentCount} discovered (${report.components.confidence} confidence)`
|
|
10901
|
+
);
|
|
10902
|
+
if (report.components.limitations?.[0]) {
|
|
10903
|
+
console.log(` ${dim4(report.components.limitations[0])}`);
|
|
10904
|
+
}
|
|
11030
10905
|
console.log(
|
|
11031
10906
|
` Styling: ${report.styling.approach}${report.styling.configFile ? ` (${report.styling.configFile})` : ""}`
|
|
11032
10907
|
);
|
|
@@ -11128,9 +11003,9 @@ async function cmdSetupWorkflow(args) {
|
|
|
11128
11003
|
console.log(` Detected: ${formatDetection(detected)}`);
|
|
11129
11004
|
console.log("");
|
|
11130
11005
|
if (detected.existingEssence) {
|
|
11131
|
-
const hasLocalPatterns =
|
|
11132
|
-
const hasLocalRules =
|
|
11133
|
-
const hasStyleBridge =
|
|
11006
|
+
const hasLocalPatterns = existsSync29(localPatternsPath(workspaceInfo.appRoot));
|
|
11007
|
+
const hasLocalRules = existsSync29(localRulesPath(workspaceInfo.appRoot));
|
|
11008
|
+
const hasStyleBridge = existsSync29(styleBridgePath(workspaceInfo.appRoot));
|
|
11134
11009
|
const verifyCommand = hasLocalPatterns || hasLocalRules ? "decantr verify --brownfield --local-patterns" : "decantr verify --brownfield";
|
|
11135
11010
|
console.log(`${BOLD11}Recommended path:${RESET18} maintain an attached Decantr project`);
|
|
11136
11011
|
console.log(
|
|
@@ -11218,7 +11093,7 @@ async function cmdAdoptWorkflow(args) {
|
|
|
11218
11093
|
const hydratePacks = flagBoolean(flags, "packs", true) && !flagBoolean(flags, "skip-packs") && !flagBoolean(flags, "offline") && process.env.DECANTR_OFFLINE !== "true";
|
|
11219
11094
|
const initCi = flagBoolean(flags, "ci") || flagBoolean(flags, "init-ci");
|
|
11220
11095
|
const assistantBridge = flagString(flags, "assistant-bridge");
|
|
11221
|
-
const hasEssence =
|
|
11096
|
+
const hasEssence = existsSync29(join32(projectRoot, "decantr.essence.json"));
|
|
11222
11097
|
const proposalFlag = flagBoolean(flags, "replace-essence") ? "--replace-essence" : flagBoolean(flags, "merge-proposal") || hasEssence ? "--merge-proposal" : "--accept-proposal";
|
|
11223
11098
|
const steps = [
|
|
11224
11099
|
"analyze current app and write .decantr/brownfield intelligence",
|
|
@@ -11478,9 +11353,9 @@ async function cmdVerifyWorkflow(args) {
|
|
|
11478
11353
|
}
|
|
11479
11354
|
}
|
|
11480
11355
|
function readJsonIfPresent(path) {
|
|
11481
|
-
if (!
|
|
11356
|
+
if (!existsSync29(path)) return null;
|
|
11482
11357
|
try {
|
|
11483
|
-
return JSON.parse(
|
|
11358
|
+
return JSON.parse(readFileSync22(path, "utf-8"));
|
|
11484
11359
|
} catch {
|
|
11485
11360
|
return null;
|
|
11486
11361
|
}
|
|
@@ -11711,11 +11586,11 @@ async function cmdTaskWorkflow(args) {
|
|
|
11711
11586
|
projectRoot: workspaceInfo.appRoot,
|
|
11712
11587
|
workflowMode: projectJson?.initialized?.workflowMode ?? null,
|
|
11713
11588
|
adoptionMode: projectJson?.initialized?.adoptionMode ?? null,
|
|
11714
|
-
hasLocalPatterns:
|
|
11715
|
-
hasLocalRules:
|
|
11589
|
+
hasLocalPatterns: existsSync29(localPatternPackPath),
|
|
11590
|
+
hasLocalRules: existsSync29(localRuleManifestPath),
|
|
11716
11591
|
hasPackManifest: Boolean(manifest),
|
|
11717
11592
|
taskSummary,
|
|
11718
|
-
hasStyleBridge:
|
|
11593
|
+
hasStyleBridge: existsSync29(acceptedStyleBridgePath)
|
|
11719
11594
|
});
|
|
11720
11595
|
const readTargets = [
|
|
11721
11596
|
pagePack ? displayProjectPath(workspaceInfo, join32(".decantr/context", pagePack.markdown)) : null,
|
|
@@ -11723,9 +11598,9 @@ async function cmdTaskWorkflow(args) {
|
|
|
11723
11598
|
manifest?.scaffold?.markdown ? displayProjectPath(workspaceInfo, join32(".decantr/context", manifest.scaffold.markdown)) : null,
|
|
11724
11599
|
displayProjectPath(workspaceInfo, ".decantr/context/scaffold.md"),
|
|
11725
11600
|
displayProjectPath(workspaceInfo, "DECANTR.md"),
|
|
11726
|
-
|
|
11727
|
-
|
|
11728
|
-
|
|
11601
|
+
existsSync29(localPatternPackPath) ? displayProjectPath(workspaceInfo, ".decantr/local-patterns.json") : null,
|
|
11602
|
+
existsSync29(localRuleManifestPath) ? displayProjectPath(workspaceInfo, ".decantr/rules.json") : null,
|
|
11603
|
+
existsSync29(acceptedStyleBridgePath) ? displayProjectPath(workspaceInfo, ".decantr/style-bridge.json") : null,
|
|
11729
11604
|
contractCapsule ? displayProjectPath(workspaceInfo, ".decantr/graph/contract-capsule.json") : null,
|
|
11730
11605
|
routeGraphContext && !contractCapsule ? displayProjectPath(workspaceInfo, ".decantr/graph/graph.snapshot.json") : null
|
|
11731
11606
|
].filter((value) => Boolean(value));
|
|
@@ -12045,7 +11920,7 @@ async function cmdCodifyWorkflow(args) {
|
|
|
12045
11920
|
const workspaceInfo = resolveWorkflowProject(flags, "codify");
|
|
12046
11921
|
if (!workspaceInfo) return;
|
|
12047
11922
|
if (flagBoolean(flags, "accept")) {
|
|
12048
|
-
if (!
|
|
11923
|
+
if (!existsSync29(localPatternsProposalPath(workspaceInfo.appRoot)) && !existsSync29(localRulesProposalPath(workspaceInfo.appRoot)) && !existsSync29(styleBridgeProposalPath(workspaceInfo.appRoot))) {
|
|
12049
11924
|
console.error(
|
|
12050
11925
|
error2(
|
|
12051
11926
|
"No codify proposal found. Run `decantr codify --from-audit`, `decantr codify --style-bridge`, or `decantr codify` first."
|
|
@@ -12460,7 +12335,7 @@ ${BOLD11}Usage:${RESET18}
|
|
|
12460
12335
|
|
|
12461
12336
|
${BOLD11}Options:${RESET18}
|
|
12462
12337
|
--project App path inside a workspace/monorepo
|
|
12463
|
-
--json Emit the
|
|
12338
|
+
--json Emit the ScanReportV2 JSON to stdout
|
|
12464
12339
|
|
|
12465
12340
|
${BOLD11}Behavior:${RESET18}
|
|
12466
12341
|
Reads local project files, detects frontend framework/routes/styling/static-hosting signals,
|
|
@@ -12840,11 +12715,11 @@ async function main() {
|
|
|
12840
12715
|
}
|
|
12841
12716
|
if (command === "--version" || command === "-v" || command === "version") {
|
|
12842
12717
|
try {
|
|
12843
|
-
const here =
|
|
12718
|
+
const here = dirname7(fileURLToPath3(import.meta.url));
|
|
12844
12719
|
const candidates = [join32(here, "..", "package.json"), join32(here, "..", "..", "package.json")];
|
|
12845
12720
|
for (const candidate of candidates) {
|
|
12846
|
-
if (
|
|
12847
|
-
const pkg = JSON.parse(
|
|
12721
|
+
if (existsSync29(candidate)) {
|
|
12722
|
+
const pkg = JSON.parse(readFileSync22(candidate, "utf-8"));
|
|
12848
12723
|
if (pkg.version) {
|
|
12849
12724
|
console.log(pkg.version);
|
|
12850
12725
|
return;
|
|
@@ -13041,7 +12916,7 @@ async function main() {
|
|
|
13041
12916
|
break;
|
|
13042
12917
|
}
|
|
13043
12918
|
case "upgrade": {
|
|
13044
|
-
const { cmdUpgrade } = await import("./upgrade-
|
|
12919
|
+
const { cmdUpgrade } = await import("./upgrade-4BUQAYBU.js");
|
|
13045
12920
|
const { flags } = parseLooseArgs(args);
|
|
13046
12921
|
const workspaceInfo = resolveWorkflowProject(flags, "upgrade");
|
|
13047
12922
|
if (!workspaceInfo) break;
|
|
@@ -13299,7 +13174,7 @@ async function main() {
|
|
|
13299
13174
|
const requestedView = args[1];
|
|
13300
13175
|
const view = requestedView === "manifest" || requestedView === "shortlist" || requestedView === "verification" ? requestedView : "shortlist";
|
|
13301
13176
|
const jsonOutput = args.includes("--json");
|
|
13302
|
-
if (requestedView
|
|
13177
|
+
if (requestedView?.startsWith("--")) {
|
|
13303
13178
|
await printShowcaseBenchmarks("shortlist", jsonOutput);
|
|
13304
13179
|
break;
|
|
13305
13180
|
}
|
|
@@ -13324,7 +13199,7 @@ async function main() {
|
|
|
13324
13199
|
}
|
|
13325
13200
|
case "login": {
|
|
13326
13201
|
const apiKeyArg = args[1];
|
|
13327
|
-
if (apiKeyArg
|
|
13202
|
+
if (apiKeyArg?.startsWith("--api-key=")) {
|
|
13328
13203
|
const key = apiKeyArg.split("=")[1];
|
|
13329
13204
|
saveCredentials({ access_token: key, api_key: key });
|
|
13330
13205
|
console.log(success4("API key saved."));
|
|
@@ -13640,7 +13515,7 @@ async function main() {
|
|
|
13640
13515
|
mcpOnly: flagBoolean(flags, "mcp-only"),
|
|
13641
13516
|
rulesOnly: flagBoolean(flags, "rules-only"),
|
|
13642
13517
|
routeHint,
|
|
13643
|
-
attached:
|
|
13518
|
+
attached: existsSync29(join32(workspaceInfo.appRoot, "decantr.essence.json"))
|
|
13644
13519
|
});
|
|
13645
13520
|
break;
|
|
13646
13521
|
}
|