@decantr/cli 3.6.2 → 3.8.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.
- package/README.md +23 -22
- package/dist/bin.js +2 -2
- package/dist/{chunk-SIDKK73N.js → chunk-IP2CCX2W.js} +28 -28
- package/dist/{chunk-4HFBFQNN.js → chunk-VULJMJJP.js} +442 -728
- package/dist/{content-health-4KP2EGTI.js → content-health-TDV4LP2C.js} +2 -2
- package/dist/index.js +2 -2
- package/dist/{upgrade-WBFE6EN7.js → upgrade-NN7NTA4L.js} +1 -1
- package/package.json +7 -6
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
scaffoldProject,
|
|
15
15
|
syncRegistry,
|
|
16
16
|
writeExecutionPackBundleArtifacts
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-IP2CCX2W.js";
|
|
18
18
|
import {
|
|
19
19
|
createWorkspaceHealthReport,
|
|
20
20
|
formatWorkspaceHealthMarkdown,
|
|
@@ -72,9 +72,9 @@ 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 dirname8, isAbsolute as isAbsolute4, join as
|
|
77
|
-
import { fileURLToPath as
|
|
75
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync17, readdirSync as readdirSync8, readFileSync as readFileSync21, writeFileSync as writeFileSync20 } from "fs";
|
|
76
|
+
import { basename as basename2, dirname as dirname8, isAbsolute as isAbsolute4, join as join31, relative as relative7, resolve as resolve5 } from "path";
|
|
77
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
78
78
|
import {
|
|
79
79
|
buildGraphImpactContext,
|
|
80
80
|
buildGraphRouteContext,
|
|
@@ -83,7 +83,7 @@ import {
|
|
|
83
83
|
} from "@decantr/core";
|
|
84
84
|
import { evaluateGuard, isV4 as isV48, validateEssence as validateEssence2 } from "@decantr/essence-spec";
|
|
85
85
|
import {
|
|
86
|
-
CONTENT_TYPE_TO_API_CONTENT_TYPE as
|
|
86
|
+
CONTENT_TYPE_TO_API_CONTENT_TYPE as CONTENT_TYPE_TO_API_CONTENT_TYPE2,
|
|
87
87
|
CONTENT_TYPES as GET_CONTENT_TYPES,
|
|
88
88
|
getBlueprintPortfolioMetadata,
|
|
89
89
|
isApiContentType,
|
|
@@ -92,7 +92,7 @@ import {
|
|
|
92
92
|
isPublicBlueprintSet,
|
|
93
93
|
API_CONTENT_TYPES as LIST_CONTENT_TYPES,
|
|
94
94
|
patternToDiscoveryCandidate,
|
|
95
|
-
RegistryAPIClient as
|
|
95
|
+
RegistryAPIClient as RegistryAPIClient2,
|
|
96
96
|
rankPatternCandidates
|
|
97
97
|
} from "@decantr/registry";
|
|
98
98
|
import {
|
|
@@ -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";
|
|
@@ -3153,7 +3018,7 @@ function resolveWorkflowPolicy(input) {
|
|
|
3153
3018
|
} else {
|
|
3154
3019
|
workflowMode = hasRegistryContent ? "greenfield-scaffold" : "greenfield-contract-only";
|
|
3155
3020
|
}
|
|
3156
|
-
const adoptionMode = requestedAdoption ?? input.workflowSeed?.adoptionMode ??
|
|
3021
|
+
const adoptionMode = requestedAdoption ?? input.workflowSeed?.adoptionMode ?? "contract-only";
|
|
3157
3022
|
const contentSource = hasRegistryContent ? input.offline ? "cache" : "official" : "none";
|
|
3158
3023
|
const assistantBridge = requestedAssistantBridge ?? input.workflowSeed?.assistantBridge ?? (workflowMode === "brownfield-attach" && input.detected.existingRuleFiles.length > 0 ? "preview" : "none");
|
|
3159
3024
|
return {
|
|
@@ -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
|
}
|
|
@@ -6019,11 +5885,12 @@ async function cmdMigrate(projectRoot = process.cwd(), args = []) {
|
|
|
6019
5885
|
import { spawnSync } from "child_process";
|
|
6020
5886
|
import { existsSync as existsSync21, mkdirSync as mkdirSync13 } from "fs";
|
|
6021
5887
|
import { join as join23, resolve as resolve3 } from "path";
|
|
6022
|
-
import { fileURLToPath as
|
|
5888
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
6023
5889
|
|
|
6024
5890
|
// src/offline-content.ts
|
|
6025
5891
|
import { cpSync, existsSync as existsSync20, mkdirSync as mkdirSync12 } from "fs";
|
|
6026
|
-
import { join as join22, resolve as resolve2 } from "path";
|
|
5892
|
+
import { dirname as dirname6, join as join22, resolve as resolve2 } from "path";
|
|
5893
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
6027
5894
|
var CONTENT_TYPES2 = ["archetypes", "blueprints", "patterns", "themes", "shells"];
|
|
6028
5895
|
function copyIfExists(source, target) {
|
|
6029
5896
|
if (!existsSync20(source)) return false;
|
|
@@ -6065,12 +5932,24 @@ function seedOfflineRegistry(projectDir, workspaceRoot) {
|
|
|
6065
5932
|
if (copiedCache || copiedCustom) {
|
|
6066
5933
|
return { seeded: true, strategy: "workspace-cache" };
|
|
6067
5934
|
}
|
|
6068
|
-
const
|
|
6069
|
-
if (hydrateContentRoot(projectDir,
|
|
6070
|
-
return { seeded: true, strategy: "
|
|
5935
|
+
const workspaceContentRoot = resolve2(workspaceRoot, "packages", "content");
|
|
5936
|
+
if (hydrateContentRoot(projectDir, workspaceContentRoot)) {
|
|
5937
|
+
return { seeded: true, strategy: "workspace-content-root" };
|
|
5938
|
+
}
|
|
5939
|
+
const installedContentRoot = resolveInstalledContentRoot();
|
|
5940
|
+
if (installedContentRoot && hydrateContentRoot(projectDir, installedContentRoot)) {
|
|
5941
|
+
return { seeded: true, strategy: "installed-content-package" };
|
|
6071
5942
|
}
|
|
6072
5943
|
return { seeded: false, strategy: null };
|
|
6073
5944
|
}
|
|
5945
|
+
function resolveInstalledContentRoot() {
|
|
5946
|
+
try {
|
|
5947
|
+
const entry = fileURLToPath2(import.meta.resolve("@decantr/content"));
|
|
5948
|
+
return resolve2(dirname6(entry), "..");
|
|
5949
|
+
} catch {
|
|
5950
|
+
return null;
|
|
5951
|
+
}
|
|
5952
|
+
}
|
|
6074
5953
|
|
|
6075
5954
|
// src/commands/new-project.ts
|
|
6076
5955
|
var BOLD6 = "\x1B[1m";
|
|
@@ -6175,7 +6054,7 @@ function runArgvCommand(command, args, cwd) {
|
|
|
6175
6054
|
}
|
|
6176
6055
|
}
|
|
6177
6056
|
function resolveInitCommand(initFlags) {
|
|
6178
|
-
const bundledCliEntrypoint =
|
|
6057
|
+
const bundledCliEntrypoint = fileURLToPath3(new URL("./bin.js", import.meta.url));
|
|
6179
6058
|
const cliEntrypoint = existsSync21(bundledCliEntrypoint) ? bundledCliEntrypoint : process.argv[1] && existsSync21(process.argv[1]) ? process.argv[1] : null;
|
|
6180
6059
|
if (cliEntrypoint) {
|
|
6181
6060
|
return {
|
|
@@ -6194,8 +6073,7 @@ async function cmdNewProject(projectName, options) {
|
|
|
6194
6073
|
const projectDir = resolve3(workspaceRoot, projectName);
|
|
6195
6074
|
const bootstrapTarget = resolveBootstrapTarget(options.target);
|
|
6196
6075
|
const bootstrapAdapter = getBootstrapAdapter(bootstrapTarget);
|
|
6197
|
-
const
|
|
6198
|
-
const inferredAdoption = options.adoption || (registryBackedScaffold ? "decantr-css" : "contract-only");
|
|
6076
|
+
const inferredAdoption = options.adoption || "contract-only";
|
|
6199
6077
|
const shouldBootstrapRuntime = Boolean(bootstrapAdapter && inferredAdoption === "decantr-css");
|
|
6200
6078
|
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(projectName)) {
|
|
6201
6079
|
console.error(
|
|
@@ -6240,7 +6118,7 @@ async function cmdNewProject(projectName, options) {
|
|
|
6240
6118
|
)
|
|
6241
6119
|
);
|
|
6242
6120
|
}
|
|
6243
|
-
const packageManager =
|
|
6121
|
+
const packageManager = detectPackageManager3();
|
|
6244
6122
|
if (shouldBootstrapRuntime) {
|
|
6245
6123
|
console.log(heading("Installing dependencies..."));
|
|
6246
6124
|
try {
|
|
@@ -6260,11 +6138,11 @@ ${YELLOW6}Dependency install failed. Run \`${packageManager} install\` manually.
|
|
|
6260
6138
|
console.log(dim3(` Seeded offline registry content from ${seeded.strategy}.`));
|
|
6261
6139
|
} else if (requiresOfflineContent) {
|
|
6262
6140
|
console.log(
|
|
6263
|
-
`${YELLOW6} Offline blueprint/archetype resolution requires local
|
|
6141
|
+
`${YELLOW6} Offline blueprint/archetype resolution requires local content corpus data.${RESET9}`
|
|
6264
6142
|
);
|
|
6265
6143
|
console.log(
|
|
6266
6144
|
dim3(
|
|
6267
|
-
" No parent workspace cache/custom content or
|
|
6145
|
+
" No parent workspace cache/custom content, configured content source, or installed @decantr/content corpus was found."
|
|
6268
6146
|
)
|
|
6269
6147
|
);
|
|
6270
6148
|
console.log("");
|
|
@@ -6275,7 +6153,7 @@ ${YELLOW6}Dependency install failed. Run \`${packageManager} install\` manually.
|
|
|
6275
6153
|
console.log(` ${cyan3(packageManager + " run dev")}`);
|
|
6276
6154
|
console.log(` ${cyan3("decantr sync")} ${dim3("# when online, then rerun decantr init")}`);
|
|
6277
6155
|
console.log(
|
|
6278
|
-
` ${cyan3("DECANTR_CONTENT_DIR=/path/to/
|
|
6156
|
+
` ${cyan3("DECANTR_CONTENT_DIR=/path/to/content decantr init --existing --offline")} ${dim3("# or seed a local content source")}`
|
|
6279
6157
|
);
|
|
6280
6158
|
console.log("");
|
|
6281
6159
|
return;
|
|
@@ -6316,7 +6194,7 @@ ${YELLOW6}Decantr init encountered issues. Run \`decantr init\` manually inside
|
|
|
6316
6194
|
});
|
|
6317
6195
|
}
|
|
6318
6196
|
}
|
|
6319
|
-
function
|
|
6197
|
+
function detectPackageManager3() {
|
|
6320
6198
|
if (existsSync21(join23(process.cwd(), "pnpm-lock.yaml")) || existsSync21(join23(process.cwd(), "pnpm-workspace.yaml"))) {
|
|
6321
6199
|
return "pnpm";
|
|
6322
6200
|
}
|
|
@@ -6330,73 +6208,18 @@ function detectPackageManager4() {
|
|
|
6330
6208
|
}
|
|
6331
6209
|
|
|
6332
6210
|
// src/commands/publish.ts
|
|
6333
|
-
import { existsSync as existsSync22, readFileSync as readFileSync16 } from "fs";
|
|
6334
|
-
import { join as join24 } from "path";
|
|
6335
|
-
import {
|
|
6336
|
-
API_CONTENT_TYPE_TO_CONTENT_TYPE,
|
|
6337
|
-
CONTENT_TYPE_TO_API_CONTENT_TYPE as CONTENT_TYPE_TO_API_CONTENT_TYPE2,
|
|
6338
|
-
RegistryAPIClient,
|
|
6339
|
-
RegistryAPIError
|
|
6340
|
-
} from "@decantr/registry";
|
|
6341
6211
|
async function cmdPublish(type, name, projectRoot = process.cwd()) {
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
}
|
|
6348
|
-
const singularType = API_CONTENT_TYPE_TO_CONTENT_TYPE[type] || type;
|
|
6349
|
-
const pluralType = CONTENT_TYPE_TO_API_CONTENT_TYPE2[type] || CONTENT_TYPE_TO_API_CONTENT_TYPE2[singularType] || `${type}s`;
|
|
6350
|
-
const customPath = join24(projectRoot, ".decantr", "custom", pluralType, `${name}.json`);
|
|
6351
|
-
if (!existsSync22(customPath)) {
|
|
6352
|
-
console.error(`Custom ${singularType} "${name}" not found at ${customPath}`);
|
|
6353
|
-
console.error(`Create one first: decantr create ${singularType} ${name}`);
|
|
6354
|
-
process.exitCode = 1;
|
|
6355
|
-
return;
|
|
6356
|
-
}
|
|
6357
|
-
let data;
|
|
6358
|
-
try {
|
|
6359
|
-
data = JSON.parse(readFileSync16(customPath, "utf-8"));
|
|
6360
|
-
} catch {
|
|
6361
|
-
console.error(`Failed to parse ${customPath}`);
|
|
6362
|
-
process.exitCode = 1;
|
|
6363
|
-
return;
|
|
6364
|
-
}
|
|
6365
|
-
const client = new RegistryAPIClient({
|
|
6366
|
-
apiKey: token
|
|
6367
|
-
});
|
|
6368
|
-
try {
|
|
6369
|
-
const result = await client.publishContent({
|
|
6370
|
-
type: pluralType,
|
|
6371
|
-
slug: name,
|
|
6372
|
-
version: data.version || "1.0.0",
|
|
6373
|
-
data,
|
|
6374
|
-
namespace: "@community",
|
|
6375
|
-
visibility: "public"
|
|
6376
|
-
});
|
|
6377
|
-
console.log(`Published ${singularType}/${name} to @community`);
|
|
6378
|
-
console.log(`Status: ${result.status}`);
|
|
6379
|
-
} catch (err) {
|
|
6380
|
-
if (err instanceof RegistryAPIError) {
|
|
6381
|
-
console.error(`Failed to publish: ${err.message}`);
|
|
6382
|
-
const details = err.details;
|
|
6383
|
-
if (Array.isArray(details?.validationErrors) && details.validationErrors.length > 0) {
|
|
6384
|
-
console.error("Validation errors:");
|
|
6385
|
-
for (const validationError of details.validationErrors) {
|
|
6386
|
-
console.error(` - ${String(validationError)}`);
|
|
6387
|
-
}
|
|
6388
|
-
}
|
|
6389
|
-
} else {
|
|
6390
|
-
console.error(`Failed to publish: ${err.message}`);
|
|
6391
|
-
}
|
|
6392
|
-
process.exitCode = 1;
|
|
6393
|
-
}
|
|
6212
|
+
void projectRoot;
|
|
6213
|
+
console.error(
|
|
6214
|
+
`Hosted community publishing has been retired. Keep ${type}/${name} in the official corpus under packages/content and run \`decantr content check\`.`
|
|
6215
|
+
);
|
|
6216
|
+
process.exitCode = 1;
|
|
6394
6217
|
}
|
|
6395
6218
|
|
|
6396
6219
|
// src/commands/refresh.ts
|
|
6397
6220
|
import { createHash } from "crypto";
|
|
6398
|
-
import { existsSync as
|
|
6399
|
-
import { isAbsolute as isAbsolute3, join as
|
|
6221
|
+
import { existsSync as existsSync22, readdirSync as readdirSync6, readFileSync as readFileSync15, statSync as statSync6 } from "fs";
|
|
6222
|
+
import { isAbsolute as isAbsolute3, join as join24, relative as relative6 } from "path";
|
|
6400
6223
|
import { isV4 as isV45 } from "@decantr/essence-spec";
|
|
6401
6224
|
import { collectMissingPackManifestFiles as collectMissingPackManifestFiles2 } from "@decantr/verifier";
|
|
6402
6225
|
var GREEN10 = "\x1B[32m";
|
|
@@ -6404,13 +6227,13 @@ var RED7 = "\x1B[31m";
|
|
|
6404
6227
|
var DIM10 = "\x1B[2m";
|
|
6405
6228
|
var RESET10 = "\x1B[0m";
|
|
6406
6229
|
function hashFile(path) {
|
|
6407
|
-
return createHash("sha256").update(
|
|
6230
|
+
return createHash("sha256").update(readFileSync15(path)).digest("hex");
|
|
6408
6231
|
}
|
|
6409
6232
|
function walkFiles(dir) {
|
|
6410
|
-
if (!
|
|
6233
|
+
if (!existsSync22(dir)) return [];
|
|
6411
6234
|
const files = [];
|
|
6412
6235
|
for (const entry of readdirSync6(dir, { withFileTypes: true })) {
|
|
6413
|
-
const path =
|
|
6236
|
+
const path = join24(dir, entry.name);
|
|
6414
6237
|
if (entry.isDirectory()) {
|
|
6415
6238
|
files.push(...walkFiles(path));
|
|
6416
6239
|
} else if (entry.isFile()) {
|
|
@@ -6421,15 +6244,15 @@ function walkFiles(dir) {
|
|
|
6421
6244
|
}
|
|
6422
6245
|
function trackedGeneratedFiles(projectRoot) {
|
|
6423
6246
|
const files = [
|
|
6424
|
-
|
|
6425
|
-
...walkFiles(
|
|
6247
|
+
join24(projectRoot, "DECANTR.md"),
|
|
6248
|
+
...walkFiles(join24(projectRoot, ".decantr", "context"))
|
|
6426
6249
|
];
|
|
6427
6250
|
if (!isContractOnlyProject2(projectRoot)) {
|
|
6428
6251
|
files.push(
|
|
6429
|
-
...["global.css", "tokens.css", "treatments.css", "decantr-bridge.css"].map((file) =>
|
|
6252
|
+
...["global.css", "tokens.css", "treatments.css", "decantr-bridge.css"].map((file) => join24(projectRoot, "src", "styles", file)).filter((path) => existsSync22(path))
|
|
6430
6253
|
);
|
|
6431
6254
|
}
|
|
6432
|
-
return files.filter((path) =>
|
|
6255
|
+
return files.filter((path) => existsSync22(path));
|
|
6433
6256
|
}
|
|
6434
6257
|
function snapshotGeneratedFiles(projectRoot) {
|
|
6435
6258
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -6452,33 +6275,33 @@ function fileMtimeMs(path) {
|
|
|
6452
6275
|
}
|
|
6453
6276
|
function newestInputMtime(projectRoot) {
|
|
6454
6277
|
return Math.max(
|
|
6455
|
-
fileMtimeMs(
|
|
6456
|
-
fileMtimeMs(
|
|
6278
|
+
fileMtimeMs(join24(projectRoot, "decantr.essence.json")),
|
|
6279
|
+
fileMtimeMs(join24(projectRoot, ".decantr", "project.json"))
|
|
6457
6280
|
);
|
|
6458
6281
|
}
|
|
6459
6282
|
function isContractOnlyProject2(projectRoot) {
|
|
6460
|
-
const projectJsonPath =
|
|
6461
|
-
if (!
|
|
6283
|
+
const projectJsonPath = join24(projectRoot, ".decantr", "project.json");
|
|
6284
|
+
if (!existsSync22(projectJsonPath)) return false;
|
|
6462
6285
|
try {
|
|
6463
|
-
const projectJson = JSON.parse(
|
|
6286
|
+
const projectJson = JSON.parse(readFileSync15(projectJsonPath, "utf-8"));
|
|
6464
6287
|
return projectJson.initialized?.adoptionMode === "contract-only";
|
|
6465
6288
|
} catch {
|
|
6466
6289
|
return false;
|
|
6467
6290
|
}
|
|
6468
6291
|
}
|
|
6469
6292
|
function checkRefreshFreshness(projectRoot) {
|
|
6470
|
-
const contextDir =
|
|
6293
|
+
const contextDir = join24(projectRoot, ".decantr", "context");
|
|
6471
6294
|
const generated = trackedGeneratedFiles(projectRoot);
|
|
6472
6295
|
const reasons = [];
|
|
6473
6296
|
const packHydrationOptional = isContractOnlyProject2(projectRoot);
|
|
6474
|
-
if (!
|
|
6475
|
-
if (!
|
|
6476
|
-
if (!
|
|
6297
|
+
if (!existsSync22(join24(projectRoot, "DECANTR.md"))) reasons.push("DECANTR.md is missing.");
|
|
6298
|
+
if (!existsSync22(contextDir)) reasons.push(".decantr/context is missing.");
|
|
6299
|
+
if (!existsSync22(join24(contextDir, "scaffold.md"))) {
|
|
6477
6300
|
reasons.push(".decantr/context/scaffold.md is missing.");
|
|
6478
6301
|
}
|
|
6479
|
-
if (!packHydrationOptional && !
|
|
6302
|
+
if (!packHydrationOptional && !existsSync22(join24(contextDir, "pack-manifest.json"))) {
|
|
6480
6303
|
reasons.push(".decantr/context/pack-manifest.json is missing.");
|
|
6481
|
-
} else if (
|
|
6304
|
+
} else if (existsSync22(join24(contextDir, "pack-manifest.json"))) {
|
|
6482
6305
|
const missingPackFiles = collectMissingPackManifestFiles2(projectRoot);
|
|
6483
6306
|
if (missingPackFiles.length > 0) {
|
|
6484
6307
|
reasons.push(
|
|
@@ -6531,7 +6354,7 @@ function summarizeChanges(projectRoot, before, after) {
|
|
|
6531
6354
|
}
|
|
6532
6355
|
function displayGeneratedPath(summary, file, displayRoot) {
|
|
6533
6356
|
if (!displayRoot) return file;
|
|
6534
|
-
const absolutePath =
|
|
6357
|
+
const absolutePath = join24(summary.projectRoot, file);
|
|
6535
6358
|
const relativePath = relative6(displayRoot, absolutePath).replace(/\\/g, "/");
|
|
6536
6359
|
if (relativePath && !relativePath.startsWith("..") && !isAbsolute3(relativePath)) {
|
|
6537
6360
|
return relativePath;
|
|
@@ -6566,15 +6389,15 @@ function printRefreshSummary(summary, displayRoot) {
|
|
|
6566
6389
|
}
|
|
6567
6390
|
}
|
|
6568
6391
|
async function cmdRefresh(projectRoot = process.cwd(), options = {}) {
|
|
6569
|
-
const essencePath =
|
|
6570
|
-
if (!
|
|
6392
|
+
const essencePath = join24(projectRoot, "decantr.essence.json");
|
|
6393
|
+
if (!existsSync22(essencePath)) {
|
|
6571
6394
|
console.error(`${RED7}No decantr.essence.json found. Run \`decantr init\` first.${RESET10}`);
|
|
6572
6395
|
process.exitCode = 1;
|
|
6573
6396
|
return;
|
|
6574
6397
|
}
|
|
6575
6398
|
let essence;
|
|
6576
6399
|
try {
|
|
6577
|
-
const raw =
|
|
6400
|
+
const raw = readFileSync15(essencePath, "utf-8");
|
|
6578
6401
|
const parsed = JSON.parse(raw);
|
|
6579
6402
|
if (!isV45(parsed)) {
|
|
6580
6403
|
console.error(
|
|
@@ -6600,7 +6423,7 @@ async function cmdRefresh(projectRoot = process.cwd(), options = {}) {
|
|
|
6600
6423
|
return;
|
|
6601
6424
|
}
|
|
6602
6425
|
const registryClient = new RegistryClient({
|
|
6603
|
-
cacheDir:
|
|
6426
|
+
cacheDir: join24(projectRoot, ".decantr", "cache"),
|
|
6604
6427
|
offline: options.offline
|
|
6605
6428
|
});
|
|
6606
6429
|
console.log("Regenerating derived files...\n");
|
|
@@ -6632,8 +6455,8 @@ async function cmdRefresh(projectRoot = process.cwd(), options = {}) {
|
|
|
6632
6455
|
|
|
6633
6456
|
// src/commands/registry-mirror.ts
|
|
6634
6457
|
import { mkdirSync as mkdirSync14, writeFileSync as writeFileSync14 } from "fs";
|
|
6635
|
-
import { join as
|
|
6636
|
-
import { API_CONTENT_TYPES, RegistryAPIClient
|
|
6458
|
+
import { join as join25 } from "path";
|
|
6459
|
+
import { API_CONTENT_TYPES, RegistryAPIClient } from "@decantr/registry";
|
|
6637
6460
|
var GREEN11 = "\x1B[32m";
|
|
6638
6461
|
var RED8 = "\x1B[31m";
|
|
6639
6462
|
var DIM11 = "\x1B[2m";
|
|
@@ -6643,7 +6466,7 @@ var RESET11 = "\x1B[0m";
|
|
|
6643
6466
|
var ALL_CONTENT_TYPES = [...API_CONTENT_TYPES];
|
|
6644
6467
|
async function cmdRegistryMirror(projectRoot, options = {}) {
|
|
6645
6468
|
const apiUrl = process.env.DECANTR_API_URL || "https://api.decantr.ai/v1";
|
|
6646
|
-
const apiClient = new
|
|
6469
|
+
const apiClient = new RegistryAPIClient({
|
|
6647
6470
|
baseUrl: apiUrl,
|
|
6648
6471
|
apiKey: process.env.DECANTR_API_KEY || void 0
|
|
6649
6472
|
});
|
|
@@ -6660,7 +6483,7 @@ async function cmdRegistryMirror(projectRoot, options = {}) {
|
|
|
6660
6483
|
process.exitCode = 1;
|
|
6661
6484
|
return;
|
|
6662
6485
|
}
|
|
6663
|
-
const cacheDir =
|
|
6486
|
+
const cacheDir = join25(projectRoot, ".decantr", "cache");
|
|
6664
6487
|
const counts = {};
|
|
6665
6488
|
const failed = [];
|
|
6666
6489
|
console.log(`
|
|
@@ -6670,19 +6493,19 @@ Mirroring registry content to ${DIM11}.decantr/cache/${RESET11}
|
|
|
6670
6493
|
try {
|
|
6671
6494
|
const result = await apiClient.listContent(type, { namespace: "@official" });
|
|
6672
6495
|
const items = result.items;
|
|
6673
|
-
const typeDir =
|
|
6496
|
+
const typeDir = join25(cacheDir, "@official", type);
|
|
6674
6497
|
mkdirSync14(typeDir, { recursive: true });
|
|
6675
|
-
writeFileSync14(
|
|
6498
|
+
writeFileSync14(join25(typeDir, "index.json"), JSON.stringify(result, null, 2));
|
|
6676
6499
|
let itemCount = 0;
|
|
6677
6500
|
for (const item of items) {
|
|
6678
6501
|
const slug = item.slug || item.id;
|
|
6679
6502
|
if (!slug) continue;
|
|
6680
6503
|
try {
|
|
6681
6504
|
const fullItem = await apiClient.getContent(type, "@official", slug);
|
|
6682
|
-
writeFileSync14(
|
|
6505
|
+
writeFileSync14(join25(typeDir, `${slug}.json`), JSON.stringify(fullItem, null, 2));
|
|
6683
6506
|
itemCount++;
|
|
6684
6507
|
} catch {
|
|
6685
|
-
writeFileSync14(
|
|
6508
|
+
writeFileSync14(join25(typeDir, `${slug}.json`), JSON.stringify(item, null, 2));
|
|
6686
6509
|
itemCount++;
|
|
6687
6510
|
}
|
|
6688
6511
|
}
|
|
@@ -6697,8 +6520,8 @@ Mirroring registry content to ${DIM11}.decantr/cache/${RESET11}
|
|
|
6697
6520
|
mirrored_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6698
6521
|
counts
|
|
6699
6522
|
};
|
|
6700
|
-
mkdirSync14(
|
|
6701
|
-
writeFileSync14(
|
|
6523
|
+
mkdirSync14(join25(cacheDir), { recursive: true });
|
|
6524
|
+
writeFileSync14(join25(cacheDir, "mirror-manifest.json"), JSON.stringify(manifest, null, 2));
|
|
6702
6525
|
const totalItems = Object.values(counts).reduce((a, b) => a + b, 0);
|
|
6703
6526
|
console.log("");
|
|
6704
6527
|
if (failed.length > 0) {
|
|
@@ -6715,8 +6538,8 @@ Mirroring registry content to ${DIM11}.decantr/cache/${RESET11}
|
|
|
6715
6538
|
}
|
|
6716
6539
|
|
|
6717
6540
|
// src/commands/remove.ts
|
|
6718
|
-
import { existsSync as
|
|
6719
|
-
import { join as
|
|
6541
|
+
import { existsSync as existsSync23, readFileSync as readFileSync16, rmSync as rmSync2, writeFileSync as writeFileSync15 } from "fs";
|
|
6542
|
+
import { join as join26 } from "path";
|
|
6720
6543
|
import { isV4 as isV46 } from "@decantr/essence-spec";
|
|
6721
6544
|
var GREEN12 = "\x1B[32m";
|
|
6722
6545
|
var RED9 = "\x1B[31m";
|
|
@@ -6724,15 +6547,15 @@ var YELLOW8 = "\x1B[33m";
|
|
|
6724
6547
|
var DIM12 = "\x1B[2m";
|
|
6725
6548
|
var RESET12 = "\x1B[0m";
|
|
6726
6549
|
function readV4Essence2(projectRoot) {
|
|
6727
|
-
const essencePath =
|
|
6728
|
-
if (!
|
|
6550
|
+
const essencePath = join26(projectRoot, "decantr.essence.json");
|
|
6551
|
+
if (!existsSync23(essencePath)) {
|
|
6729
6552
|
console.error(`${RED9}No decantr.essence.json found. Run \`decantr init\` first.${RESET12}`);
|
|
6730
6553
|
process.exitCode = 1;
|
|
6731
6554
|
return null;
|
|
6732
6555
|
}
|
|
6733
6556
|
let parsed;
|
|
6734
6557
|
try {
|
|
6735
|
-
parsed = JSON.parse(
|
|
6558
|
+
parsed = JSON.parse(readFileSync16(essencePath, "utf-8"));
|
|
6736
6559
|
} catch (e) {
|
|
6737
6560
|
console.error(`${RED9}Could not read essence: ${e.message}${RESET12}`);
|
|
6738
6561
|
process.exitCode = 1;
|
|
@@ -6820,20 +6643,20 @@ async function cmdRemoveSection(sectionId, args, projectRoot = process.cwd()) {
|
|
|
6820
6643
|
sections.splice(idx, 1);
|
|
6821
6644
|
recomputeGlobalFeatures(essence);
|
|
6822
6645
|
removeRoutes(essence, sectionId);
|
|
6823
|
-
const contextFile =
|
|
6824
|
-
if (
|
|
6646
|
+
const contextFile = join26(projectRoot, ".decantr", "context", `${sectionId}.md`);
|
|
6647
|
+
if (existsSync23(contextFile)) {
|
|
6825
6648
|
rmSync2(contextFile);
|
|
6826
6649
|
}
|
|
6827
6650
|
writeEssence2(essencePath, essence);
|
|
6828
6651
|
console.log(`${GREEN12}Removed section "${sectionId}".${RESET12}`);
|
|
6829
6652
|
const registryClient = new RegistryClient({
|
|
6830
|
-
cacheDir:
|
|
6653
|
+
cacheDir: join26(projectRoot, ".decantr", "cache")
|
|
6831
6654
|
});
|
|
6832
6655
|
await refreshDerivedFiles(projectRoot, essence, registryClient);
|
|
6833
6656
|
console.log(`${GREEN12}Derived files refreshed.${RESET12}`);
|
|
6834
6657
|
}
|
|
6835
6658
|
async function cmdRemovePage(path, args, projectRoot = process.cwd()) {
|
|
6836
|
-
if (!path
|
|
6659
|
+
if (!path?.includes("/")) {
|
|
6837
6660
|
console.error(`${RED9}Usage: decantr remove page <section>/<page>${RESET12}`);
|
|
6838
6661
|
console.error(`${DIM12}Example: decantr remove page settings/notifications${RESET12}`);
|
|
6839
6662
|
process.exitCode = 1;
|
|
@@ -6870,7 +6693,7 @@ async function cmdRemovePage(path, args, projectRoot = process.cwd()) {
|
|
|
6870
6693
|
}
|
|
6871
6694
|
console.log(`${GREEN12}Removed page "${pageId}" from section "${resolvedSectionId}".${RESET12}`);
|
|
6872
6695
|
const registryClient = new RegistryClient({
|
|
6873
|
-
cacheDir:
|
|
6696
|
+
cacheDir: join26(projectRoot, ".decantr", "cache")
|
|
6874
6697
|
});
|
|
6875
6698
|
await refreshDerivedFiles(projectRoot, essence, registryClient);
|
|
6876
6699
|
console.log(`${GREEN12}Derived files refreshed.${RESET12}`);
|
|
@@ -6913,15 +6736,15 @@ async function cmdRemoveFeature(feature, args, projectRoot = process.cwd()) {
|
|
|
6913
6736
|
const target = sectionId ? `section "${sectionId}" and global` : "global";
|
|
6914
6737
|
console.log(`${GREEN12}Removed feature "${feature}" from ${target} features.${RESET12}`);
|
|
6915
6738
|
const registryClient = new RegistryClient({
|
|
6916
|
-
cacheDir:
|
|
6739
|
+
cacheDir: join26(projectRoot, ".decantr", "cache")
|
|
6917
6740
|
});
|
|
6918
6741
|
await refreshDerivedFiles(projectRoot, essence, registryClient);
|
|
6919
6742
|
console.log(`${GREEN12}Derived files refreshed.${RESET12}`);
|
|
6920
6743
|
}
|
|
6921
6744
|
|
|
6922
6745
|
// src/commands/resolve.ts
|
|
6923
|
-
import { existsSync as
|
|
6924
|
-
import { dirname as dirname7, join as
|
|
6746
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync15, readFileSync as readFileSync17, writeFileSync as writeFileSync16 } from "fs";
|
|
6747
|
+
import { dirname as dirname7, join as join27, resolve as resolve4 } from "path";
|
|
6925
6748
|
var BOLD7 = "\x1B[1m";
|
|
6926
6749
|
var DIM13 = "\x1B[2m";
|
|
6927
6750
|
var GREEN13 = "\x1B[32m";
|
|
@@ -6929,13 +6752,13 @@ var RED10 = "\x1B[31m";
|
|
|
6929
6752
|
var YELLOW9 = "\x1B[33m";
|
|
6930
6753
|
var RESET13 = "\x1B[0m";
|
|
6931
6754
|
function driftLogPath(projectRoot) {
|
|
6932
|
-
return
|
|
6755
|
+
return join27(projectRoot, ".decantr", "drift-log.json");
|
|
6933
6756
|
}
|
|
6934
6757
|
function readDriftLog(projectRoot) {
|
|
6935
6758
|
const path = driftLogPath(projectRoot);
|
|
6936
|
-
if (!
|
|
6759
|
+
if (!existsSync24(path)) return { version: 1, entries: [] };
|
|
6937
6760
|
try {
|
|
6938
|
-
const parsed = JSON.parse(
|
|
6761
|
+
const parsed = JSON.parse(readFileSync17(path, "utf-8"));
|
|
6939
6762
|
return {
|
|
6940
6763
|
version: 1,
|
|
6941
6764
|
entries: Array.isArray(parsed.entries) ? parsed.entries : []
|
|
@@ -7066,8 +6889,8 @@ async function cmdResolve(projectRoot = process.cwd(), args = ["resolve"]) {
|
|
|
7066
6889
|
}
|
|
7067
6890
|
|
|
7068
6891
|
// src/commands/sync-drift.ts
|
|
7069
|
-
import { existsSync as
|
|
7070
|
-
import { join as
|
|
6892
|
+
import { existsSync as existsSync25, readFileSync as readFileSync18, writeFileSync as writeFileSync17 } from "fs";
|
|
6893
|
+
import { join as join28 } from "path";
|
|
7071
6894
|
var GREEN14 = "\x1B[32m";
|
|
7072
6895
|
var RED11 = "\x1B[31m";
|
|
7073
6896
|
var YELLOW10 = "\x1B[33m";
|
|
@@ -7076,8 +6899,8 @@ var DIM14 = "\x1B[2m";
|
|
|
7076
6899
|
var BOLD8 = "\x1B[1m";
|
|
7077
6900
|
var CYAN7 = "\x1B[36m";
|
|
7078
6901
|
async function cmdSyncDrift(projectRoot = process.cwd()) {
|
|
7079
|
-
const driftLogPath2 =
|
|
7080
|
-
if (!
|
|
6902
|
+
const driftLogPath2 = join28(projectRoot, ".decantr", "drift-log.json");
|
|
6903
|
+
if (!existsSync25(driftLogPath2)) {
|
|
7081
6904
|
console.log(`${GREEN14}No drift log found \u2014 no drift recorded.${RESET14}`);
|
|
7082
6905
|
console.log(
|
|
7083
6906
|
`${DIM14}Drift is logged when guard violations are detected during development.${RESET14}`
|
|
@@ -7086,7 +6909,7 @@ async function cmdSyncDrift(projectRoot = process.cwd()) {
|
|
|
7086
6909
|
}
|
|
7087
6910
|
let entries;
|
|
7088
6911
|
try {
|
|
7089
|
-
entries = JSON.parse(
|
|
6912
|
+
entries = JSON.parse(readFileSync18(driftLogPath2, "utf-8"));
|
|
7090
6913
|
} catch {
|
|
7091
6914
|
console.error(`${RED11}Could not parse drift-log.json${RESET14}`);
|
|
7092
6915
|
process.exitCode = 1;
|
|
@@ -7132,8 +6955,8 @@ ${BOLD8}Unresolved Drift Entries (${unresolved.length})${RESET14}
|
|
|
7132
6955
|
console.log("");
|
|
7133
6956
|
}
|
|
7134
6957
|
function resolveDriftEntries(projectRoot, options) {
|
|
7135
|
-
const driftLogPath2 =
|
|
7136
|
-
if (!
|
|
6958
|
+
const driftLogPath2 = join28(projectRoot, ".decantr", "drift-log.json");
|
|
6959
|
+
if (!existsSync25(driftLogPath2)) {
|
|
7137
6960
|
return { success: true };
|
|
7138
6961
|
}
|
|
7139
6962
|
if (options.clear) {
|
|
@@ -7146,7 +6969,7 @@ function resolveDriftEntries(projectRoot, options) {
|
|
|
7146
6969
|
}
|
|
7147
6970
|
let entries;
|
|
7148
6971
|
try {
|
|
7149
|
-
entries = JSON.parse(
|
|
6972
|
+
entries = JSON.parse(readFileSync18(driftLogPath2, "utf-8"));
|
|
7150
6973
|
} catch {
|
|
7151
6974
|
return { success: false, error: "Could not parse drift-log.json" };
|
|
7152
6975
|
}
|
|
@@ -7402,8 +7225,8 @@ function trimTrailingSlashes(value) {
|
|
|
7402
7225
|
}
|
|
7403
7226
|
|
|
7404
7227
|
// src/commands/theme-switch.ts
|
|
7405
|
-
import { existsSync as
|
|
7406
|
-
import { join as
|
|
7228
|
+
import { existsSync as existsSync26, readFileSync as readFileSync19, writeFileSync as writeFileSync18 } from "fs";
|
|
7229
|
+
import { join as join29 } from "path";
|
|
7407
7230
|
import { isV4 as isV47 } from "@decantr/essence-spec";
|
|
7408
7231
|
var GREEN16 = "\x1B[32m";
|
|
7409
7232
|
var RED12 = "\x1B[31m";
|
|
@@ -7420,15 +7243,15 @@ async function cmdThemeSwitch(themeName, args, projectRoot = process.cwd()) {
|
|
|
7420
7243
|
process.exitCode = 1;
|
|
7421
7244
|
return;
|
|
7422
7245
|
}
|
|
7423
|
-
const essencePath =
|
|
7424
|
-
if (!
|
|
7246
|
+
const essencePath = join29(projectRoot, "decantr.essence.json");
|
|
7247
|
+
if (!existsSync26(essencePath)) {
|
|
7425
7248
|
console.error(`${RED12}No decantr.essence.json found. Run \`decantr init\` first.${RESET16}`);
|
|
7426
7249
|
process.exitCode = 1;
|
|
7427
7250
|
return;
|
|
7428
7251
|
}
|
|
7429
7252
|
let parsed;
|
|
7430
7253
|
try {
|
|
7431
|
-
parsed = JSON.parse(
|
|
7254
|
+
parsed = JSON.parse(readFileSync19(essencePath, "utf-8"));
|
|
7432
7255
|
} catch (e) {
|
|
7433
7256
|
console.error(`${RED12}Could not read essence: ${e.message}${RESET16}`);
|
|
7434
7257
|
process.exitCode = 1;
|
|
@@ -7479,7 +7302,7 @@ async function cmdThemeSwitch(themeName, args, projectRoot = process.cwd()) {
|
|
|
7479
7302
|
essence.dna.theme.mode = mode;
|
|
7480
7303
|
}
|
|
7481
7304
|
const registryClient = new RegistryClient({
|
|
7482
|
-
cacheDir:
|
|
7305
|
+
cacheDir: join29(projectRoot, ".decantr", "cache")
|
|
7483
7306
|
});
|
|
7484
7307
|
try {
|
|
7485
7308
|
const themeResult = await registryClient.fetchTheme(themeName);
|
|
@@ -7802,8 +7625,8 @@ async function runSimplifiedInit(blueprints) {
|
|
|
7802
7625
|
}
|
|
7803
7626
|
|
|
7804
7627
|
// src/theme-commands.ts
|
|
7805
|
-
import { existsSync as
|
|
7806
|
-
import { join as
|
|
7628
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync16, readdirSync as readdirSync7, readFileSync as readFileSync20, rmSync as rmSync3, writeFileSync as writeFileSync19 } from "fs";
|
|
7629
|
+
import { join as join30 } from "path";
|
|
7807
7630
|
var REQUIRED_FIELDS = [
|
|
7808
7631
|
"$schema",
|
|
7809
7632
|
"id",
|
|
@@ -7863,11 +7686,11 @@ function validateCustomTheme(theme) {
|
|
|
7863
7686
|
};
|
|
7864
7687
|
}
|
|
7865
7688
|
function createTheme(projectRoot, id, name) {
|
|
7866
|
-
const customThemesDir =
|
|
7867
|
-
const themePath =
|
|
7868
|
-
const howToPath =
|
|
7689
|
+
const customThemesDir = join30(projectRoot, ".decantr", "custom", "themes");
|
|
7690
|
+
const themePath = join30(customThemesDir, `${id}.json`);
|
|
7691
|
+
const howToPath = join30(customThemesDir, "how-to-theme.md");
|
|
7869
7692
|
mkdirSync16(customThemesDir, { recursive: true });
|
|
7870
|
-
if (
|
|
7693
|
+
if (existsSync27(themePath)) {
|
|
7871
7694
|
return {
|
|
7872
7695
|
success: false,
|
|
7873
7696
|
error: `Theme "${id}" already exists at ${themePath}`
|
|
@@ -7875,7 +7698,7 @@ function createTheme(projectRoot, id, name) {
|
|
|
7875
7698
|
}
|
|
7876
7699
|
const skeleton = getThemeSkeleton(id, name);
|
|
7877
7700
|
writeFileSync19(themePath, JSON.stringify(skeleton, null, 2));
|
|
7878
|
-
if (!
|
|
7701
|
+
if (!existsSync27(howToPath)) {
|
|
7879
7702
|
writeFileSync19(howToPath, getHowToThemeDoc());
|
|
7880
7703
|
}
|
|
7881
7704
|
return {
|
|
@@ -7884,17 +7707,17 @@ function createTheme(projectRoot, id, name) {
|
|
|
7884
7707
|
};
|
|
7885
7708
|
}
|
|
7886
7709
|
function listCustomThemes(projectRoot) {
|
|
7887
|
-
const customThemesDir =
|
|
7888
|
-
if (!
|
|
7710
|
+
const customThemesDir = join30(projectRoot, ".decantr", "custom", "themes");
|
|
7711
|
+
if (!existsSync27(customThemesDir)) {
|
|
7889
7712
|
return [];
|
|
7890
7713
|
}
|
|
7891
7714
|
const themes = [];
|
|
7892
7715
|
try {
|
|
7893
7716
|
const files = readdirSync7(customThemesDir).filter((f) => f.endsWith(".json"));
|
|
7894
7717
|
for (const file of files) {
|
|
7895
|
-
const filePath =
|
|
7718
|
+
const filePath = join30(customThemesDir, file);
|
|
7896
7719
|
try {
|
|
7897
|
-
const data = JSON.parse(
|
|
7720
|
+
const data = JSON.parse(readFileSync20(filePath, "utf-8"));
|
|
7898
7721
|
themes.push({
|
|
7899
7722
|
id: data.id || file.replace(".json", ""),
|
|
7900
7723
|
name: data.name || data.id,
|
|
@@ -7909,8 +7732,8 @@ function listCustomThemes(projectRoot) {
|
|
|
7909
7732
|
return themes;
|
|
7910
7733
|
}
|
|
7911
7734
|
function deleteTheme(projectRoot, id) {
|
|
7912
|
-
const themePath =
|
|
7913
|
-
if (!
|
|
7735
|
+
const themePath = join30(projectRoot, ".decantr", "custom", "themes", `${id}.json`);
|
|
7736
|
+
if (!existsSync27(themePath)) {
|
|
7914
7737
|
return {
|
|
7915
7738
|
success: false,
|
|
7916
7739
|
error: `Theme "${id}" not found at ${themePath}`
|
|
@@ -7927,7 +7750,7 @@ function deleteTheme(projectRoot, id) {
|
|
|
7927
7750
|
}
|
|
7928
7751
|
}
|
|
7929
7752
|
function importTheme(projectRoot, sourcePath) {
|
|
7930
|
-
if (!
|
|
7753
|
+
if (!existsSync27(sourcePath)) {
|
|
7931
7754
|
return {
|
|
7932
7755
|
success: false,
|
|
7933
7756
|
errors: [`Source file not found: ${sourcePath}`]
|
|
@@ -7935,7 +7758,7 @@ function importTheme(projectRoot, sourcePath) {
|
|
|
7935
7758
|
}
|
|
7936
7759
|
let theme;
|
|
7937
7760
|
try {
|
|
7938
|
-
theme = JSON.parse(
|
|
7761
|
+
theme = JSON.parse(readFileSync20(sourcePath, "utf-8"));
|
|
7939
7762
|
} catch (e) {
|
|
7940
7763
|
return {
|
|
7941
7764
|
success: false,
|
|
@@ -7951,11 +7774,11 @@ function importTheme(projectRoot, sourcePath) {
|
|
|
7951
7774
|
}
|
|
7952
7775
|
theme.source = "custom";
|
|
7953
7776
|
const id = theme.id;
|
|
7954
|
-
const customThemesDir =
|
|
7955
|
-
const destPath =
|
|
7777
|
+
const customThemesDir = join30(projectRoot, ".decantr", "custom", "themes");
|
|
7778
|
+
const destPath = join30(customThemesDir, `${id}.json`);
|
|
7956
7779
|
mkdirSync16(customThemesDir, { recursive: true });
|
|
7957
|
-
const howToPath =
|
|
7958
|
-
if (!
|
|
7780
|
+
const howToPath = join30(customThemesDir, "how-to-theme.md");
|
|
7781
|
+
if (!existsSync27(howToPath)) {
|
|
7959
7782
|
writeFileSync19(howToPath, getHowToThemeDoc());
|
|
7960
7783
|
}
|
|
7961
7784
|
writeFileSync19(destPath, JSON.stringify(theme, null, 2));
|
|
@@ -8481,86 +8304,19 @@ function generateCuratedPrompt(ctx) {
|
|
|
8481
8304
|
return ctx.workflow === "brownfield-attach" || ctx.workflow === "hybrid-compose" ? generateBrownfieldPrompt(ctx) : generateGreenfieldPrompt(ctx);
|
|
8482
8305
|
}
|
|
8483
8306
|
function getAPIClient() {
|
|
8484
|
-
return new
|
|
8485
|
-
baseUrl: process.env.DECANTR_API_URL || void 0,
|
|
8307
|
+
return new RegistryAPIClient2({
|
|
8308
|
+
baseUrl: process.env.DECANTR_API_URL || process.env.REGISTRY_URL || void 0,
|
|
8486
8309
|
apiKey: process.env.DECANTR_API_KEY || void 0
|
|
8487
8310
|
});
|
|
8488
8311
|
}
|
|
8489
8312
|
function getPublicAPIClient() {
|
|
8490
|
-
return new
|
|
8491
|
-
baseUrl: process.env.DECANTR_API_URL || void 0
|
|
8313
|
+
return new RegistryAPIClient2({
|
|
8314
|
+
baseUrl: process.env.DECANTR_API_URL || process.env.REGISTRY_URL || void 0
|
|
8492
8315
|
});
|
|
8493
8316
|
}
|
|
8494
8317
|
function resolveUserPath(inputPath, cwd = process.cwd()) {
|
|
8495
8318
|
return isAbsolute4(inputPath) ? inputPath : resolve5(cwd, inputPath);
|
|
8496
8319
|
}
|
|
8497
|
-
function extractHostedAssetPaths(indexHtml) {
|
|
8498
|
-
const assetPaths = /* @__PURE__ */ new Set();
|
|
8499
|
-
for (const match of indexHtml.matchAll(/<(?:script|link)[^>]+(?:src|href)="([^"]+)"/g)) {
|
|
8500
|
-
const assetPath = match[1];
|
|
8501
|
-
const assetsIndex = assetPath.indexOf("/assets/");
|
|
8502
|
-
if (assetsIndex === -1) continue;
|
|
8503
|
-
assetPaths.add(assetPath.slice(assetsIndex));
|
|
8504
|
-
}
|
|
8505
|
-
return [...assetPaths];
|
|
8506
|
-
}
|
|
8507
|
-
function readHostedDistSnapshot(distPath) {
|
|
8508
|
-
const resolvedDistPath = distPath ? resolveUserPath(distPath) : join32(process.cwd(), "dist");
|
|
8509
|
-
const indexPath = join32(resolvedDistPath, "index.html");
|
|
8510
|
-
if (!existsSync30(indexPath)) {
|
|
8511
|
-
return void 0;
|
|
8512
|
-
}
|
|
8513
|
-
const indexHtml = readFileSync23(indexPath, "utf-8");
|
|
8514
|
-
const assetPaths = extractHostedAssetPaths(indexHtml);
|
|
8515
|
-
const assets = {};
|
|
8516
|
-
for (const assetPath of assetPaths) {
|
|
8517
|
-
const assetFilePath = join32(resolvedDistPath, assetPath.replace(/^[/\\]+/, ""));
|
|
8518
|
-
if (existsSync30(assetFilePath)) {
|
|
8519
|
-
assets[assetPath] = readFileSync23(assetFilePath, "utf-8");
|
|
8520
|
-
}
|
|
8521
|
-
}
|
|
8522
|
-
return {
|
|
8523
|
-
indexHtml,
|
|
8524
|
-
assets
|
|
8525
|
-
};
|
|
8526
|
-
}
|
|
8527
|
-
function isHostedSourceSnapshotFile(path) {
|
|
8528
|
-
if (/\.d\.ts$/i.test(path)) return false;
|
|
8529
|
-
return /\.(?:[cm]?[jt]sx?)$/i.test(path);
|
|
8530
|
-
}
|
|
8531
|
-
function readHostedSourceSnapshot(sourcePath) {
|
|
8532
|
-
if (!sourcePath) return void 0;
|
|
8533
|
-
const resolvedSourcePath = resolveUserPath(sourcePath);
|
|
8534
|
-
if (!existsSync30(resolvedSourcePath)) {
|
|
8535
|
-
return void 0;
|
|
8536
|
-
}
|
|
8537
|
-
const files = {};
|
|
8538
|
-
const ignoredDirNames = /* @__PURE__ */ new Set([
|
|
8539
|
-
"node_modules",
|
|
8540
|
-
".git",
|
|
8541
|
-
".decantr",
|
|
8542
|
-
"dist",
|
|
8543
|
-
"build",
|
|
8544
|
-
"coverage"
|
|
8545
|
-
]);
|
|
8546
|
-
const rootPrefix = basename2(resolvedSourcePath);
|
|
8547
|
-
const walk = (absoluteDir, relativeDir) => {
|
|
8548
|
-
for (const entry of readdirSync8(absoluteDir, { withFileTypes: true })) {
|
|
8549
|
-
if (ignoredDirNames.has(entry.name)) continue;
|
|
8550
|
-
const absolutePath = join32(absoluteDir, entry.name);
|
|
8551
|
-
const relativePath = join32(relativeDir, entry.name).replace(/\\/g, "/");
|
|
8552
|
-
if (entry.isDirectory()) {
|
|
8553
|
-
walk(absolutePath, relativePath);
|
|
8554
|
-
continue;
|
|
8555
|
-
}
|
|
8556
|
-
if (!entry.isFile()) continue;
|
|
8557
|
-
if (!isHostedSourceSnapshotFile(relativePath)) continue;
|
|
8558
|
-
files[relativePath] = readFileSync23(absolutePath, "utf-8");
|
|
8559
|
-
}
|
|
8560
|
-
};
|
|
8561
|
-
walk(resolvedSourcePath, rootPrefix);
|
|
8562
|
-
return Object.keys(files).length > 0 ? { files } : void 0;
|
|
8563
|
-
}
|
|
8564
8320
|
async function getShowcaseBenchmarkView(view = "shortlist") {
|
|
8565
8321
|
const client = getPublicAPIClient();
|
|
8566
8322
|
if (view === "manifest") {
|
|
@@ -8685,7 +8441,7 @@ async function printRegistryIntelligenceSummary(namespace, jsonOutput = false) {
|
|
|
8685
8441
|
return;
|
|
8686
8442
|
}
|
|
8687
8443
|
const typedSummary = summary;
|
|
8688
|
-
console.log(heading2("
|
|
8444
|
+
console.log(heading2("Content Intelligence Summary"));
|
|
8689
8445
|
console.log(` Namespace: ${typedSummary.namespace ?? "all public content"}`);
|
|
8690
8446
|
console.log(` Generated: ${typedSummary.generated_at}`);
|
|
8691
8447
|
console.log(` Public items: ${typedSummary.totals.total_public_items}`);
|
|
@@ -8748,13 +8504,13 @@ async function printHostedExecutionPackBundle(essencePath, namespace, jsonOutput
|
|
|
8748
8504
|
}
|
|
8749
8505
|
async function compileHostedExecutionPackBundle(essencePath, namespace) {
|
|
8750
8506
|
const client = getPublicAPIClient();
|
|
8751
|
-
const resolvedPath = essencePath ? resolveUserPath(essencePath) :
|
|
8752
|
-
if (!
|
|
8507
|
+
const resolvedPath = essencePath ? resolveUserPath(essencePath) : join31(process.cwd(), "decantr.essence.json");
|
|
8508
|
+
if (!existsSync28(resolvedPath)) {
|
|
8753
8509
|
throw new Error(`Essence file not found at ${resolvedPath}`);
|
|
8754
8510
|
}
|
|
8755
|
-
const essence = JSON.parse(
|
|
8511
|
+
const essence = JSON.parse(readFileSync21(resolvedPath, "utf-8"));
|
|
8756
8512
|
const bundle = await client.compileExecutionPacks(essence, namespace ? { namespace } : void 0);
|
|
8757
|
-
const contextDir =
|
|
8513
|
+
const contextDir = join31(dirname8(resolvedPath), ".decantr", "context");
|
|
8758
8514
|
return { resolvedPath, bundle, contextDir };
|
|
8759
8515
|
}
|
|
8760
8516
|
function writeHostedExecutionPackContextArtifacts(contextDir, bundle) {
|
|
@@ -8762,10 +8518,10 @@ function writeHostedExecutionPackContextArtifacts(contextDir, bundle) {
|
|
|
8762
8518
|
return writeExecutionPackBundleArtifacts(contextDir, bundle);
|
|
8763
8519
|
}
|
|
8764
8520
|
function resolvePagePackIdForRoute(essencePath, route) {
|
|
8765
|
-
if (!
|
|
8521
|
+
if (!existsSync28(essencePath)) {
|
|
8766
8522
|
throw new Error(`Essence file not found at ${essencePath}`);
|
|
8767
8523
|
}
|
|
8768
|
-
const essence = JSON.parse(
|
|
8524
|
+
const essence = JSON.parse(readFileSync21(essencePath, "utf-8"));
|
|
8769
8525
|
if (!isV48(essence)) {
|
|
8770
8526
|
throw new Error("Route-based pack resolution requires Essence v4.0.0.");
|
|
8771
8527
|
}
|
|
@@ -8780,14 +8536,14 @@ function resolvePagePackIdForRoute(essencePath, route) {
|
|
|
8780
8536
|
}
|
|
8781
8537
|
async function printHostedSelectedExecutionPack(packType, id, essencePath, namespace, jsonOutput = false, writeContext = false) {
|
|
8782
8538
|
const client = getPublicAPIClient();
|
|
8783
|
-
const resolvedPath = essencePath ? resolveUserPath(essencePath) :
|
|
8784
|
-
if (!
|
|
8539
|
+
const resolvedPath = essencePath ? resolveUserPath(essencePath) : join31(process.cwd(), "decantr.essence.json");
|
|
8540
|
+
if (!existsSync28(resolvedPath)) {
|
|
8785
8541
|
throw new Error(`Essence file not found at ${resolvedPath}`);
|
|
8786
8542
|
}
|
|
8787
8543
|
if ((packType === "section" || packType === "page" || packType === "mutation") && !id) {
|
|
8788
8544
|
throw new Error(`Pack type "${packType}" requires an id.`);
|
|
8789
8545
|
}
|
|
8790
|
-
const essence = JSON.parse(
|
|
8546
|
+
const essence = JSON.parse(readFileSync21(resolvedPath, "utf-8"));
|
|
8791
8547
|
const selected = await client.selectExecutionPack(
|
|
8792
8548
|
{
|
|
8793
8549
|
essence,
|
|
@@ -8798,17 +8554,17 @@ async function printHostedSelectedExecutionPack(packType, id, essencePath, names
|
|
|
8798
8554
|
);
|
|
8799
8555
|
let writtenContextDir = null;
|
|
8800
8556
|
if (writeContext) {
|
|
8801
|
-
const contextDir =
|
|
8557
|
+
const contextDir = join31(dirname8(resolvedPath), ".decantr", "context");
|
|
8802
8558
|
mkdirSync17(contextDir, { recursive: true });
|
|
8803
8559
|
writeFileSync20(
|
|
8804
|
-
|
|
8560
|
+
join31(contextDir, "pack-manifest.json"),
|
|
8805
8561
|
JSON.stringify(selected.manifest, null, 2) + "\n"
|
|
8806
8562
|
);
|
|
8807
8563
|
const manifestEntry = selected.selector.packType === "scaffold" ? selected.manifest.scaffold : selected.selector.packType === "review" ? selected.manifest.review : selected.selector.packType === "section" ? selected.manifest.sections.find((entry) => entry.id === selected.selector.id) : selected.selector.packType === "page" ? selected.manifest.pages.find((entry) => entry.id === selected.selector.id) : selected.manifest.mutations.find((entry) => entry.id === selected.selector.id);
|
|
8808
8564
|
const markdownFile = manifestEntry?.markdown ?? `${selected.selector.packType}${selected.selector.id ? `-${selected.selector.id}` : ""}-pack.md`;
|
|
8809
8565
|
const jsonFile = manifestEntry?.json ?? `${selected.selector.packType}${selected.selector.id ? `-${selected.selector.id}` : ""}-pack.json`;
|
|
8810
|
-
writeFileSync20(
|
|
8811
|
-
writeFileSync20(
|
|
8566
|
+
writeFileSync20(join31(contextDir, markdownFile), selected.pack.renderedMarkdown);
|
|
8567
|
+
writeFileSync20(join31(contextDir, jsonFile), JSON.stringify(selected.pack, null, 2) + "\n");
|
|
8812
8568
|
writtenContextDir = contextDir;
|
|
8813
8569
|
}
|
|
8814
8570
|
if (jsonOutput) {
|
|
@@ -8833,20 +8589,20 @@ async function printHostedSelectedExecutionPack(packType, id, essencePath, names
|
|
|
8833
8589
|
}
|
|
8834
8590
|
async function printHostedExecutionPackManifest(essencePath, namespace, jsonOutput = false, writeContext = false) {
|
|
8835
8591
|
const client = getPublicAPIClient();
|
|
8836
|
-
const resolvedPath = essencePath ? resolveUserPath(essencePath) :
|
|
8837
|
-
if (!
|
|
8592
|
+
const resolvedPath = essencePath ? resolveUserPath(essencePath) : join31(process.cwd(), "decantr.essence.json");
|
|
8593
|
+
if (!existsSync28(resolvedPath)) {
|
|
8838
8594
|
throw new Error(`Essence file not found at ${resolvedPath}`);
|
|
8839
8595
|
}
|
|
8840
|
-
const essence = JSON.parse(
|
|
8596
|
+
const essence = JSON.parse(readFileSync21(resolvedPath, "utf-8"));
|
|
8841
8597
|
const manifest = await client.getExecutionPackManifest(
|
|
8842
8598
|
essence,
|
|
8843
8599
|
namespace ? { namespace } : void 0
|
|
8844
8600
|
);
|
|
8845
8601
|
let writtenContextDir = null;
|
|
8846
8602
|
if (writeContext) {
|
|
8847
|
-
const contextDir =
|
|
8603
|
+
const contextDir = join31(dirname8(resolvedPath), ".decantr", "context");
|
|
8848
8604
|
mkdirSync17(contextDir, { recursive: true });
|
|
8849
|
-
writeFileSync20(
|
|
8605
|
+
writeFileSync20(join31(contextDir, "pack-manifest.json"), JSON.stringify(manifest, null, 2) + "\n");
|
|
8850
8606
|
writtenContextDir = contextDir;
|
|
8851
8607
|
}
|
|
8852
8608
|
if (jsonOutput) {
|
|
@@ -8867,14 +8623,14 @@ async function printHostedExecutionPackManifest(essencePath, namespace, jsonOutp
|
|
|
8867
8623
|
}
|
|
8868
8624
|
}
|
|
8869
8625
|
async function hydrateHostedExecutionPacksIfMissing(projectRoot, namespace = "@official") {
|
|
8870
|
-
const contextDir =
|
|
8871
|
-
const reviewPackPath =
|
|
8872
|
-
const manifestPath =
|
|
8873
|
-
if (
|
|
8626
|
+
const contextDir = join31(projectRoot, ".decantr", "context");
|
|
8627
|
+
const reviewPackPath = join31(contextDir, "review-pack.json");
|
|
8628
|
+
const manifestPath = join31(contextDir, "pack-manifest.json");
|
|
8629
|
+
if (existsSync28(reviewPackPath) && existsSync28(manifestPath)) {
|
|
8874
8630
|
return { attempted: false, hydrated: false };
|
|
8875
8631
|
}
|
|
8876
|
-
const essencePath =
|
|
8877
|
-
if (!
|
|
8632
|
+
const essencePath = join31(projectRoot, "decantr.essence.json");
|
|
8633
|
+
if (!existsSync28(essencePath)) {
|
|
8878
8634
|
return { attempted: false, hydrated: false };
|
|
8879
8635
|
}
|
|
8880
8636
|
const reviewHydration = await hydrateHostedReviewPackIfMissing(projectRoot, namespace);
|
|
@@ -8883,7 +8639,7 @@ async function hydrateHostedExecutionPacksIfMissing(projectRoot, namespace = "@o
|
|
|
8883
8639
|
}
|
|
8884
8640
|
try {
|
|
8885
8641
|
const client = getPublicAPIClient();
|
|
8886
|
-
const essence = JSON.parse(
|
|
8642
|
+
const essence = JSON.parse(readFileSync21(essencePath, "utf-8"));
|
|
8887
8643
|
const bundle = await client.compileExecutionPacks(essence, { namespace });
|
|
8888
8644
|
mkdirSync17(contextDir, { recursive: true });
|
|
8889
8645
|
writeExecutionPackBundleArtifacts(contextDir, bundle);
|
|
@@ -8893,19 +8649,19 @@ async function hydrateHostedExecutionPacksIfMissing(projectRoot, namespace = "@o
|
|
|
8893
8649
|
}
|
|
8894
8650
|
}
|
|
8895
8651
|
async function hydrateHostedReviewPackIfMissing(projectRoot, namespace = "@official") {
|
|
8896
|
-
const contextDir =
|
|
8897
|
-
const reviewPackPath =
|
|
8898
|
-
const manifestPath =
|
|
8899
|
-
if (
|
|
8652
|
+
const contextDir = join31(projectRoot, ".decantr", "context");
|
|
8653
|
+
const reviewPackPath = join31(contextDir, "review-pack.json");
|
|
8654
|
+
const manifestPath = join31(contextDir, "pack-manifest.json");
|
|
8655
|
+
if (existsSync28(reviewPackPath) && existsSync28(manifestPath)) {
|
|
8900
8656
|
return { attempted: false, hydrated: false };
|
|
8901
8657
|
}
|
|
8902
|
-
const essencePath =
|
|
8903
|
-
if (!
|
|
8658
|
+
const essencePath = join31(projectRoot, "decantr.essence.json");
|
|
8659
|
+
if (!existsSync28(essencePath)) {
|
|
8904
8660
|
return { attempted: false, hydrated: false };
|
|
8905
8661
|
}
|
|
8906
8662
|
try {
|
|
8907
8663
|
const client = getPublicAPIClient();
|
|
8908
|
-
const essence = JSON.parse(
|
|
8664
|
+
const essence = JSON.parse(readFileSync21(essencePath, "utf-8"));
|
|
8909
8665
|
const selected = await client.selectExecutionPack(
|
|
8910
8666
|
{
|
|
8911
8667
|
essence,
|
|
@@ -8914,12 +8670,12 @@ async function hydrateHostedReviewPackIfMissing(projectRoot, namespace = "@offic
|
|
|
8914
8670
|
{ namespace }
|
|
8915
8671
|
);
|
|
8916
8672
|
mkdirSync17(contextDir, { recursive: true });
|
|
8917
|
-
writeFileSync20(
|
|
8673
|
+
writeFileSync20(join31(contextDir, "review-pack.md"), selected.pack.renderedMarkdown);
|
|
8918
8674
|
writeFileSync20(
|
|
8919
|
-
|
|
8675
|
+
join31(contextDir, "review-pack.json"),
|
|
8920
8676
|
JSON.stringify(selected.pack, null, 2) + "\n"
|
|
8921
8677
|
);
|
|
8922
|
-
if (!
|
|
8678
|
+
if (!existsSync28(manifestPath)) {
|
|
8923
8679
|
writeFileSync20(manifestPath, JSON.stringify(selected.manifest, null, 2) + "\n");
|
|
8924
8680
|
}
|
|
8925
8681
|
return { attempted: true, hydrated: true, scope: "review" };
|
|
@@ -8927,72 +8683,6 @@ async function hydrateHostedReviewPackIfMissing(projectRoot, namespace = "@offic
|
|
|
8927
8683
|
return { attempted: true, hydrated: false };
|
|
8928
8684
|
}
|
|
8929
8685
|
}
|
|
8930
|
-
async function printHostedFileCritique(sourcePath, namespace, jsonOutput = false, essencePath, treatmentsPath) {
|
|
8931
|
-
const client = getPublicAPIClient();
|
|
8932
|
-
const resolvedSourcePath = resolveUserPath(sourcePath);
|
|
8933
|
-
const resolvedEssencePath = essencePath ? resolveUserPath(essencePath) : join32(process.cwd(), "decantr.essence.json");
|
|
8934
|
-
const resolvedTreatmentsPath = treatmentsPath ? resolveUserPath(treatmentsPath) : join32(process.cwd(), "src", "styles", "treatments.css");
|
|
8935
|
-
if (!existsSync30(resolvedSourcePath)) {
|
|
8936
|
-
throw new Error(`Source file not found at ${resolvedSourcePath}`);
|
|
8937
|
-
}
|
|
8938
|
-
if (!existsSync30(resolvedEssencePath)) {
|
|
8939
|
-
throw new Error(`Essence file not found at ${resolvedEssencePath}`);
|
|
8940
|
-
}
|
|
8941
|
-
const code = readFileSync23(resolvedSourcePath, "utf-8");
|
|
8942
|
-
const essence = JSON.parse(readFileSync23(resolvedEssencePath, "utf-8"));
|
|
8943
|
-
const treatmentsCss = existsSync30(resolvedTreatmentsPath) ? readFileSync23(resolvedTreatmentsPath, "utf-8") : void 0;
|
|
8944
|
-
const report = await client.critiqueFile(
|
|
8945
|
-
{
|
|
8946
|
-
essence,
|
|
8947
|
-
filePath: sourcePath,
|
|
8948
|
-
code,
|
|
8949
|
-
treatmentsCss
|
|
8950
|
-
},
|
|
8951
|
-
namespace ? { namespace } : void 0
|
|
8952
|
-
);
|
|
8953
|
-
if (jsonOutput) {
|
|
8954
|
-
console.log(JSON.stringify(report, null, 2));
|
|
8955
|
-
return;
|
|
8956
|
-
}
|
|
8957
|
-
console.log(heading2("Hosted File Critique"));
|
|
8958
|
-
console.log(` Source file: ${resolvedSourcePath}`);
|
|
8959
|
-
console.log(` Essence: ${resolvedEssencePath}`);
|
|
8960
|
-
if (treatmentsCss) {
|
|
8961
|
-
console.log(` Treatments: ${resolvedTreatmentsPath}`);
|
|
8962
|
-
}
|
|
8963
|
-
printFileCritiqueReport(report);
|
|
8964
|
-
}
|
|
8965
|
-
async function printHostedProjectAudit(namespace, jsonOutput = false, essencePath, distPath, sourcesPath) {
|
|
8966
|
-
const client = getPublicAPIClient();
|
|
8967
|
-
const resolvedEssencePath = essencePath ? resolveUserPath(essencePath) : join32(process.cwd(), "decantr.essence.json");
|
|
8968
|
-
if (!existsSync30(resolvedEssencePath)) {
|
|
8969
|
-
throw new Error(`Essence file not found at ${resolvedEssencePath}`);
|
|
8970
|
-
}
|
|
8971
|
-
const essence = JSON.parse(readFileSync23(resolvedEssencePath, "utf-8"));
|
|
8972
|
-
const dist = readHostedDistSnapshot(distPath);
|
|
8973
|
-
const sources = readHostedSourceSnapshot(sourcesPath);
|
|
8974
|
-
const report = await client.auditProject(
|
|
8975
|
-
{
|
|
8976
|
-
essence,
|
|
8977
|
-
dist,
|
|
8978
|
-
sources
|
|
8979
|
-
},
|
|
8980
|
-
namespace ? { namespace } : void 0
|
|
8981
|
-
);
|
|
8982
|
-
if (jsonOutput) {
|
|
8983
|
-
console.log(JSON.stringify(report, null, 2));
|
|
8984
|
-
return;
|
|
8985
|
-
}
|
|
8986
|
-
console.log(heading2("Hosted Project Audit"));
|
|
8987
|
-
console.log(` Essence: ${resolvedEssencePath}`);
|
|
8988
|
-
console.log(
|
|
8989
|
-
` Dist snapshot: ${dist ? distPath ? resolveUserPath(distPath) : join32(process.cwd(), "dist") : "none"}`
|
|
8990
|
-
);
|
|
8991
|
-
console.log(
|
|
8992
|
-
` Source snapshot: ${sources && sourcesPath ? resolveUserPath(sourcesPath) : "none"}`
|
|
8993
|
-
);
|
|
8994
|
-
printProjectAuditReport(report);
|
|
8995
|
-
}
|
|
8996
8686
|
function formatBlueprintPortfolioSummary(value) {
|
|
8997
8687
|
const portfolio = getBlueprintPortfolioMetadata(value);
|
|
8998
8688
|
if (!portfolio) return null;
|
|
@@ -9108,21 +8798,21 @@ function findPatternCandidateBySlug(candidates, slug) {
|
|
|
9108
8798
|
function readSuggestCodeContext(projectRoot, route, file) {
|
|
9109
8799
|
const pieces = [];
|
|
9110
8800
|
if (file) {
|
|
9111
|
-
const resolved = isAbsolute4(file) ? file :
|
|
9112
|
-
if (
|
|
9113
|
-
pieces.push(
|
|
8801
|
+
const resolved = isAbsolute4(file) ? file : join31(projectRoot, file);
|
|
8802
|
+
if (existsSync28(resolved)) {
|
|
8803
|
+
pieces.push(readFileSync21(resolved, "utf-8"));
|
|
9114
8804
|
}
|
|
9115
8805
|
}
|
|
9116
8806
|
if (route) {
|
|
9117
|
-
const analysisPath =
|
|
9118
|
-
if (
|
|
8807
|
+
const analysisPath = join31(projectRoot, ".decantr", "analysis.json");
|
|
8808
|
+
if (existsSync28(analysisPath)) {
|
|
9119
8809
|
try {
|
|
9120
|
-
const analysis = JSON.parse(
|
|
8810
|
+
const analysis = JSON.parse(readFileSync21(analysisPath, "utf-8"));
|
|
9121
8811
|
const routeEntry = analysis.routes?.routes?.find((entry) => entry.path === route);
|
|
9122
8812
|
if (routeEntry?.file) {
|
|
9123
|
-
const resolved =
|
|
9124
|
-
if (
|
|
9125
|
-
pieces.push(
|
|
8813
|
+
const resolved = join31(projectRoot, routeEntry.file);
|
|
8814
|
+
if (existsSync28(resolved)) {
|
|
8815
|
+
pieces.push(readFileSync21(resolved, "utf-8"));
|
|
9126
8816
|
}
|
|
9127
8817
|
}
|
|
9128
8818
|
} catch {
|
|
@@ -9208,7 +8898,7 @@ async function cmdSuggest(query, options = {}) {
|
|
|
9208
8898
|
}
|
|
9209
8899
|
}
|
|
9210
8900
|
const registryClient = new RegistryClient({
|
|
9211
|
-
cacheDir:
|
|
8901
|
+
cacheDir: join31(projectRoot, ".decantr", "cache")
|
|
9212
8902
|
});
|
|
9213
8903
|
const code = options.fromCode || options.file ? readSuggestCodeContext(projectRoot, options.route, options.file) : "";
|
|
9214
8904
|
const localMatches = localPatternMatches(projectRoot, [query, code].filter(Boolean).join("\n"));
|
|
@@ -9295,9 +8985,9 @@ async function cmdGet(type, id) {
|
|
|
9295
8985
|
process.exitCode = 1;
|
|
9296
8986
|
return;
|
|
9297
8987
|
}
|
|
9298
|
-
const apiType =
|
|
8988
|
+
const apiType = CONTENT_TYPE_TO_API_CONTENT_TYPE2[type];
|
|
9299
8989
|
const registryClient = new RegistryClient({
|
|
9300
|
-
cacheDir:
|
|
8990
|
+
cacheDir: join31(process.cwd(), ".decantr", "cache")
|
|
9301
8991
|
});
|
|
9302
8992
|
const result = await registryClient.fetchContentItem(apiType, id);
|
|
9303
8993
|
if (result) {
|
|
@@ -9314,10 +9004,10 @@ async function cmdGet(type, id) {
|
|
|
9314
9004
|
return;
|
|
9315
9005
|
}
|
|
9316
9006
|
async function cmdValidate(path) {
|
|
9317
|
-
const essencePath = path ||
|
|
9007
|
+
const essencePath = path || join31(process.cwd(), "decantr.essence.json");
|
|
9318
9008
|
let raw;
|
|
9319
9009
|
try {
|
|
9320
|
-
raw =
|
|
9010
|
+
raw = readFileSync21(essencePath, "utf-8");
|
|
9321
9011
|
} catch {
|
|
9322
9012
|
console.error(error2(`Could not read ${essencePath}`));
|
|
9323
9013
|
process.exitCode = 1;
|
|
@@ -9384,7 +9074,7 @@ async function cmdList(type, sort, recommended, intelligenceSource, blueprintSet
|
|
|
9384
9074
|
return;
|
|
9385
9075
|
}
|
|
9386
9076
|
const registryClient = new RegistryClient({
|
|
9387
|
-
cacheDir:
|
|
9077
|
+
cacheDir: join31(process.cwd(), ".decantr", "cache")
|
|
9388
9078
|
});
|
|
9389
9079
|
const result = await registryClient.fetchContentList(
|
|
9390
9080
|
type,
|
|
@@ -9466,11 +9156,11 @@ ${CYAN10}Telemetry enabled.${RESET18} Decantr will send privacy-filtered CLI pro
|
|
|
9466
9156
|
console.log(`${DIM18}Set "telemetry": false in .decantr/project.json to opt out.${RESET18}`);
|
|
9467
9157
|
}
|
|
9468
9158
|
function readCliPackageVersion2() {
|
|
9469
|
-
const here = dirname8(
|
|
9470
|
-
const candidates = [
|
|
9159
|
+
const here = dirname8(fileURLToPath4(import.meta.url));
|
|
9160
|
+
const candidates = [join31(here, "..", "package.json"), join31(here, "..", "..", "package.json")];
|
|
9471
9161
|
for (const candidate of candidates) {
|
|
9472
9162
|
try {
|
|
9473
|
-
const pkg = JSON.parse(
|
|
9163
|
+
const pkg = JSON.parse(readFileSync21(candidate, "utf-8"));
|
|
9474
9164
|
if (pkg.version) return pkg.version;
|
|
9475
9165
|
} catch {
|
|
9476
9166
|
}
|
|
@@ -9481,19 +9171,19 @@ function timestampForFile() {
|
|
|
9481
9171
|
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
9482
9172
|
}
|
|
9483
9173
|
function backupExistingEssence(projectRoot, label) {
|
|
9484
|
-
const essencePath =
|
|
9485
|
-
if (!
|
|
9486
|
-
const backupPath =
|
|
9174
|
+
const essencePath = join31(projectRoot, "decantr.essence.json");
|
|
9175
|
+
if (!existsSync28(essencePath)) return null;
|
|
9176
|
+
const backupPath = join31(
|
|
9487
9177
|
projectRoot,
|
|
9488
9178
|
`decantr.essence.${label}.${timestampForFile()}.backup.json`
|
|
9489
9179
|
);
|
|
9490
|
-
writeFileSync20(backupPath,
|
|
9180
|
+
writeFileSync20(backupPath, readFileSync21(essencePath, "utf-8"), "utf-8");
|
|
9491
9181
|
return backupPath;
|
|
9492
9182
|
}
|
|
9493
9183
|
function writeBrownfieldProjectJson(input) {
|
|
9494
|
-
const decantrDir =
|
|
9495
|
-
mkdirSync17(
|
|
9496
|
-
mkdirSync17(
|
|
9184
|
+
const decantrDir = join31(input.projectRoot, ".decantr");
|
|
9185
|
+
mkdirSync17(join31(decantrDir, "context"), { recursive: true });
|
|
9186
|
+
mkdirSync17(join31(decantrDir, "cache"), { recursive: true });
|
|
9497
9187
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
9498
9188
|
const projectJson = {
|
|
9499
9189
|
detected: {
|
|
@@ -9534,7 +9224,7 @@ function writeBrownfieldProjectJson(input) {
|
|
|
9534
9224
|
}
|
|
9535
9225
|
}
|
|
9536
9226
|
};
|
|
9537
|
-
writeFileSync20(
|
|
9227
|
+
writeFileSync20(join31(decantrDir, "project.json"), JSON.stringify(projectJson, null, 2) + "\n");
|
|
9538
9228
|
}
|
|
9539
9229
|
async function applyAcceptedBrownfieldProposal(input) {
|
|
9540
9230
|
const proposal = readBrownfieldProposal(input.projectRoot);
|
|
@@ -9550,8 +9240,8 @@ async function applyAcceptedBrownfieldProposal(input) {
|
|
|
9550
9240
|
process.exitCode = 1;
|
|
9551
9241
|
return;
|
|
9552
9242
|
}
|
|
9553
|
-
const essencePath =
|
|
9554
|
-
const hasEssence =
|
|
9243
|
+
const essencePath = join31(input.projectRoot, "decantr.essence.json");
|
|
9244
|
+
const hasEssence = existsSync28(essencePath);
|
|
9555
9245
|
let essence;
|
|
9556
9246
|
let backupPath = null;
|
|
9557
9247
|
if (input.mode === "accept" && hasEssence) {
|
|
@@ -9565,7 +9255,7 @@ async function applyAcceptedBrownfieldProposal(input) {
|
|
|
9565
9255
|
return;
|
|
9566
9256
|
}
|
|
9567
9257
|
if (input.mode === "merge" && hasEssence) {
|
|
9568
|
-
const existing = JSON.parse(
|
|
9258
|
+
const existing = JSON.parse(readFileSync21(essencePath, "utf-8"));
|
|
9569
9259
|
if (!isV48(existing)) {
|
|
9570
9260
|
console.log(
|
|
9571
9261
|
error2(
|
|
@@ -9604,7 +9294,7 @@ async function applyAcceptedBrownfieldProposal(input) {
|
|
|
9604
9294
|
});
|
|
9605
9295
|
writeFileSync20(essencePath, JSON.stringify(essence, null, 2) + "\n", "utf-8");
|
|
9606
9296
|
const registryClient = new RegistryClient({
|
|
9607
|
-
cacheDir:
|
|
9297
|
+
cacheDir: join31(input.projectRoot, ".decantr", "cache"),
|
|
9608
9298
|
offline: true,
|
|
9609
9299
|
projectRoot: input.projectRoot
|
|
9610
9300
|
});
|
|
@@ -9783,7 +9473,7 @@ async function cmdInit(args) {
|
|
|
9783
9473
|
}
|
|
9784
9474
|
}
|
|
9785
9475
|
const registryClient = new RegistryClient({
|
|
9786
|
-
cacheDir:
|
|
9476
|
+
cacheDir: join31(projectRoot, ".decantr", "cache"),
|
|
9787
9477
|
apiUrl: args.registry,
|
|
9788
9478
|
offline: args.offline,
|
|
9789
9479
|
projectRoot
|
|
@@ -10115,7 +9805,7 @@ ${YELLOW13}You're offline. Scaffolding Decantr default.${RESET18}`);
|
|
|
10115
9805
|
if (appliedRuleFiles.length > 0) {
|
|
10116
9806
|
console.log(` ${dim4(`Rule bridge applied: ${appliedRuleFiles.join(", ")}`)}`);
|
|
10117
9807
|
}
|
|
10118
|
-
if (!
|
|
9808
|
+
if (!existsSync28(join31(projectRoot, "package.json"))) {
|
|
10119
9809
|
console.log("");
|
|
10120
9810
|
console.log(
|
|
10121
9811
|
dim4(` Note: ${cyan4("decantr init")} created Decantr contract/context files only.`)
|
|
@@ -10126,7 +9816,7 @@ ${YELLOW13}You're offline. Scaffolding Decantr default.${RESET18}`);
|
|
|
10126
9816
|
)
|
|
10127
9817
|
);
|
|
10128
9818
|
}
|
|
10129
|
-
const hasCompiledPacks =
|
|
9819
|
+
const hasCompiledPacks = existsSync28(join31(projectRoot, ".decantr", "context", "scaffold-pack.md"));
|
|
10130
9820
|
console.log("");
|
|
10131
9821
|
console.log(" Next steps:");
|
|
10132
9822
|
if (hasCompiledPacks) {
|
|
@@ -10166,7 +9856,7 @@ ${YELLOW13}You're offline. Scaffolding Decantr default.${RESET18}`);
|
|
|
10166
9856
|
console.log(` ${cyan4("decantr upgrade")} Update to latest patterns`);
|
|
10167
9857
|
console.log(` ${cyan4("decantr check")} Detect drift issues`);
|
|
10168
9858
|
console.log(` ${cyan4("decantr migrate --to v4")} Migrate older essence files to v4`);
|
|
10169
|
-
const essenceContent =
|
|
9859
|
+
const essenceContent = readFileSync21(result.essencePath, "utf-8");
|
|
10170
9860
|
const essence = JSON.parse(essenceContent);
|
|
10171
9861
|
const validation = validateEssence2(essence);
|
|
10172
9862
|
if (!validation.valid) {
|
|
@@ -10221,16 +9911,16 @@ Validation warnings: ${validation.errors.join(", ")}`));
|
|
|
10221
9911
|
}
|
|
10222
9912
|
}
|
|
10223
9913
|
async function cmdStatus(projectRoot = process.cwd()) {
|
|
10224
|
-
const essencePath =
|
|
10225
|
-
const projectJsonPath =
|
|
9914
|
+
const essencePath = join31(projectRoot, "decantr.essence.json");
|
|
9915
|
+
const projectJsonPath = join31(projectRoot, ".decantr", "project.json");
|
|
10226
9916
|
console.log(heading2("Decantr Project Status"));
|
|
10227
|
-
if (!
|
|
9917
|
+
if (!existsSync28(essencePath)) {
|
|
10228
9918
|
console.log(`${RED13}No decantr.essence.json found.${RESET18}`);
|
|
10229
9919
|
console.log(dim4('Run "decantr init" to create one.'));
|
|
10230
9920
|
return;
|
|
10231
9921
|
}
|
|
10232
9922
|
try {
|
|
10233
|
-
const essence = JSON.parse(
|
|
9923
|
+
const essence = JSON.parse(readFileSync21(essencePath, "utf-8"));
|
|
10234
9924
|
const validation = validateEssence2(essence);
|
|
10235
9925
|
const essenceVersion = isV48(essence) ? "v4" : "legacy";
|
|
10236
9926
|
console.log(`${BOLD11}Essence:${RESET18}`);
|
|
@@ -10278,9 +9968,9 @@ async function cmdStatus(projectRoot = process.cwd()) {
|
|
|
10278
9968
|
}
|
|
10279
9969
|
console.log("");
|
|
10280
9970
|
console.log(`${BOLD11}Sync Status:${RESET18}`);
|
|
10281
|
-
if (
|
|
9971
|
+
if (existsSync28(projectJsonPath)) {
|
|
10282
9972
|
try {
|
|
10283
|
-
const projectJson = JSON.parse(
|
|
9973
|
+
const projectJson = JSON.parse(readFileSync21(projectJsonPath, "utf-8"));
|
|
10284
9974
|
const syncStatus = projectJson.sync?.status || "unknown";
|
|
10285
9975
|
const lastSync = projectJson.sync?.lastSync || "never";
|
|
10286
9976
|
const source = projectJson.sync?.registrySource || "unknown";
|
|
@@ -10298,7 +9988,7 @@ async function cmdStatus(projectRoot = process.cwd()) {
|
|
|
10298
9988
|
}
|
|
10299
9989
|
async function cmdSync() {
|
|
10300
9990
|
const projectRoot = process.cwd();
|
|
10301
|
-
const cacheDir =
|
|
9991
|
+
const cacheDir = join31(projectRoot, ".decantr", "cache");
|
|
10302
9992
|
console.log(heading2("Syncing registry content..."));
|
|
10303
9993
|
const result = await syncRegistry(cacheDir);
|
|
10304
9994
|
if (result.synced.length > 0) {
|
|
@@ -10387,26 +10077,35 @@ function printFileCritiqueReport(report) {
|
|
|
10387
10077
|
console.log(`${BOLD11}Findings:${RESET18}`);
|
|
10388
10078
|
printVerificationFindings(report.findings);
|
|
10389
10079
|
}
|
|
10390
|
-
async function cmdAudit(filePath) {
|
|
10080
|
+
async function cmdAudit(filePath, options = {}) {
|
|
10391
10081
|
const projectRoot = process.cwd();
|
|
10082
|
+
const jsonOutput = options.json === true;
|
|
10392
10083
|
try {
|
|
10393
10084
|
if (filePath) {
|
|
10394
10085
|
const hydration2 = await hydrateHostedReviewPackIfMissing(projectRoot);
|
|
10395
|
-
|
|
10396
|
-
|
|
10086
|
+
if (!jsonOutput) {
|
|
10087
|
+
console.log(heading2(`Critiquing ${filePath}...`));
|
|
10088
|
+
}
|
|
10089
|
+
if (hydration2.hydrated && !jsonOutput) {
|
|
10397
10090
|
console.log(dim4("Hydrated missing review pack from hosted registry."));
|
|
10398
10091
|
console.log("");
|
|
10399
10092
|
}
|
|
10400
10093
|
const report2 = await critiqueProjectFile(filePath, projectRoot);
|
|
10401
|
-
|
|
10094
|
+
if (jsonOutput) {
|
|
10095
|
+
console.log(JSON.stringify(report2, null, 2));
|
|
10096
|
+
} else {
|
|
10097
|
+
printFileCritiqueReport(report2);
|
|
10098
|
+
}
|
|
10402
10099
|
if (report2.findings.some((finding) => finding.severity === "error")) {
|
|
10403
10100
|
process.exitCode = 1;
|
|
10404
10101
|
}
|
|
10405
10102
|
return;
|
|
10406
10103
|
}
|
|
10407
10104
|
const hydration = await hydrateHostedExecutionPacksIfMissing(projectRoot);
|
|
10408
|
-
|
|
10409
|
-
|
|
10105
|
+
if (!jsonOutput) {
|
|
10106
|
+
console.log(heading2("Auditing project..."));
|
|
10107
|
+
}
|
|
10108
|
+
if (hydration.hydrated && !jsonOutput) {
|
|
10410
10109
|
console.log(
|
|
10411
10110
|
dim4(
|
|
10412
10111
|
hydration.scope === "bundle" ? "Hydrated missing execution packs from hosted registry." : "Hydrated missing review pack and manifest from hosted registry."
|
|
@@ -10415,14 +10114,20 @@ async function cmdAudit(filePath) {
|
|
|
10415
10114
|
console.log("");
|
|
10416
10115
|
}
|
|
10417
10116
|
const report = await auditProject(projectRoot);
|
|
10418
|
-
|
|
10117
|
+
if (jsonOutput) {
|
|
10118
|
+
console.log(JSON.stringify(report, null, 2));
|
|
10119
|
+
} else {
|
|
10120
|
+
printProjectAuditReport(report);
|
|
10121
|
+
}
|
|
10419
10122
|
if (!report.valid) {
|
|
10420
10123
|
process.exitCode = 1;
|
|
10421
10124
|
return;
|
|
10422
10125
|
}
|
|
10423
10126
|
if (report.findings.length > 0) {
|
|
10424
|
-
|
|
10425
|
-
|
|
10127
|
+
if (!jsonOutput) {
|
|
10128
|
+
console.log("");
|
|
10129
|
+
console.log(dim4("Project audit completed with advisory findings."));
|
|
10130
|
+
}
|
|
10426
10131
|
}
|
|
10427
10132
|
} catch (e) {
|
|
10428
10133
|
console.log(`${RED13}Error: ${e.message}${RESET18}`);
|
|
@@ -10492,14 +10197,14 @@ ${BOLD11}Examples:${RESET18}
|
|
|
10492
10197
|
process.exitCode = 1;
|
|
10493
10198
|
return;
|
|
10494
10199
|
}
|
|
10495
|
-
const themePath =
|
|
10496
|
-
if (!
|
|
10200
|
+
const themePath = join31(projectRoot, ".decantr", "custom", "themes", `${name}.json`);
|
|
10201
|
+
if (!existsSync28(themePath)) {
|
|
10497
10202
|
console.error(error2(`Theme "${name}" not found at ${themePath}`));
|
|
10498
10203
|
process.exitCode = 1;
|
|
10499
10204
|
return;
|
|
10500
10205
|
}
|
|
10501
10206
|
try {
|
|
10502
|
-
const theme = JSON.parse(
|
|
10207
|
+
const theme = JSON.parse(readFileSync21(themePath, "utf-8"));
|
|
10503
10208
|
const result = validateCustomTheme(theme);
|
|
10504
10209
|
if (result.valid) {
|
|
10505
10210
|
console.log(success4(`Custom theme "${name}" is valid`));
|
|
@@ -10631,7 +10336,7 @@ function withProject(command, projectArg) {
|
|
|
10631
10336
|
return projectArg ? `${command} --project ${projectArg}` : command;
|
|
10632
10337
|
}
|
|
10633
10338
|
function displayProjectPath(workspaceInfo, projectPath) {
|
|
10634
|
-
const absolutePath =
|
|
10339
|
+
const absolutePath = join31(workspaceInfo.appRoot, projectPath);
|
|
10635
10340
|
const relativePath = relative7(workspaceInfo.cwd, absolutePath).replace(/\\/g, "/");
|
|
10636
10341
|
if (relativePath && !relativePath.startsWith("..") && !isAbsolute4(relativePath)) {
|
|
10637
10342
|
return relativePath;
|
|
@@ -10655,7 +10360,7 @@ function graphSourceNodeIdForTaskFile(projectRoot, snapshot, filePath) {
|
|
|
10655
10360
|
candidates.add(trimmed.replace(/\\/g, "/").replace(/^\.\//, ""));
|
|
10656
10361
|
const cwdRelative = projectRelativeGraphPath(projectRoot, trimmed);
|
|
10657
10362
|
if (cwdRelative) candidates.add(cwdRelative);
|
|
10658
|
-
const projectRelative = projectRelativeGraphPath(projectRoot,
|
|
10363
|
+
const projectRelative = projectRelativeGraphPath(projectRoot, join31(projectRoot, trimmed));
|
|
10659
10364
|
if (projectRelative) candidates.add(projectRelative);
|
|
10660
10365
|
for (const candidate of candidates) {
|
|
10661
10366
|
const nodeId = `src:${candidate}`;
|
|
@@ -10729,7 +10434,7 @@ function printWorkspaceProjectSelection(workspaceInfo, commandName = "command")
|
|
|
10729
10434
|
function printMonorepoSetupGuidance(workspaceInfo) {
|
|
10730
10435
|
const candidate = firstWorkspaceCandidate(workspaceInfo);
|
|
10731
10436
|
const attachedProjects = workspaceInfo.appCandidates.filter(
|
|
10732
|
-
(appCandidate) =>
|
|
10437
|
+
(appCandidate) => existsSync28(join31(workspaceInfo.workspaceRoot, appCandidate, "decantr.essence.json"))
|
|
10733
10438
|
);
|
|
10734
10439
|
const firstAttached = attachedProjects[0];
|
|
10735
10440
|
console.log(heading2("Decantr Setup"));
|
|
@@ -10797,7 +10502,7 @@ function printMonorepoSetupGuidance(workspaceInfo) {
|
|
|
10797
10502
|
function resolveWorkflowProject(flags, commandName = "command", options = {}) {
|
|
10798
10503
|
const projectArg = flagString(flags, "project");
|
|
10799
10504
|
const workspaceInfo = resolveWorkspaceInfo(process.cwd(), projectArg);
|
|
10800
|
-
if (projectArg && options.requireExisting !== false && !
|
|
10505
|
+
if (projectArg && options.requireExisting !== false && !existsSync28(workspaceInfo.appRoot)) {
|
|
10801
10506
|
printProjectNotFound(projectArg, commandName);
|
|
10802
10507
|
process.exitCode = 1;
|
|
10803
10508
|
return null;
|
|
@@ -11019,14 +10724,23 @@ function printScanReport(report, projectArg) {
|
|
|
11019
10724
|
console.log("");
|
|
11020
10725
|
printScanGraphPreview(report.graphPreview);
|
|
11021
10726
|
console.log(`${BOLD11}Routes And Styling${RESET18}`);
|
|
11022
|
-
|
|
10727
|
+
const routeSignalCount = report.routes.routeSignalCount ?? report.routes.count;
|
|
10728
|
+
const taskableRouteCount = report.routes.taskableRouteCount ?? report.routes.count;
|
|
10729
|
+
console.log(
|
|
10730
|
+
` Routes: ${taskableRouteCount} taskable / ${routeSignalCount} signal(s) (${report.routes.strategy}, ${report.routes.confidence})`
|
|
10731
|
+
);
|
|
11023
10732
|
for (const route of report.routes.items.slice(0, 8)) {
|
|
11024
10733
|
console.log(` ${cyan4(route.path.padEnd(18))} ${dim4(route.file)}`);
|
|
11025
10734
|
}
|
|
11026
10735
|
if (report.routes.items.length > 8) {
|
|
11027
10736
|
console.log(` ${dim4(`...${report.routes.items.length - 8} more route(s)`)}`);
|
|
11028
10737
|
}
|
|
11029
|
-
console.log(
|
|
10738
|
+
console.log(
|
|
10739
|
+
` Components: ${report.components.componentCount} discovered (${report.components.confidence} confidence)`
|
|
10740
|
+
);
|
|
10741
|
+
if (report.components.limitations?.[0]) {
|
|
10742
|
+
console.log(` ${dim4(report.components.limitations[0])}`);
|
|
10743
|
+
}
|
|
11030
10744
|
console.log(
|
|
11031
10745
|
` Styling: ${report.styling.approach}${report.styling.configFile ? ` (${report.styling.configFile})` : ""}`
|
|
11032
10746
|
);
|
|
@@ -11128,9 +10842,9 @@ async function cmdSetupWorkflow(args) {
|
|
|
11128
10842
|
console.log(` Detected: ${formatDetection(detected)}`);
|
|
11129
10843
|
console.log("");
|
|
11130
10844
|
if (detected.existingEssence) {
|
|
11131
|
-
const hasLocalPatterns =
|
|
11132
|
-
const hasLocalRules =
|
|
11133
|
-
const hasStyleBridge =
|
|
10845
|
+
const hasLocalPatterns = existsSync28(localPatternsPath(workspaceInfo.appRoot));
|
|
10846
|
+
const hasLocalRules = existsSync28(localRulesPath(workspaceInfo.appRoot));
|
|
10847
|
+
const hasStyleBridge = existsSync28(styleBridgePath(workspaceInfo.appRoot));
|
|
11134
10848
|
const verifyCommand = hasLocalPatterns || hasLocalRules ? "decantr verify --brownfield --local-patterns" : "decantr verify --brownfield";
|
|
11135
10849
|
console.log(`${BOLD11}Recommended path:${RESET18} maintain an attached Decantr project`);
|
|
11136
10850
|
console.log(
|
|
@@ -11218,7 +10932,7 @@ async function cmdAdoptWorkflow(args) {
|
|
|
11218
10932
|
const hydratePacks = flagBoolean(flags, "packs", true) && !flagBoolean(flags, "skip-packs") && !flagBoolean(flags, "offline") && process.env.DECANTR_OFFLINE !== "true";
|
|
11219
10933
|
const initCi = flagBoolean(flags, "ci") || flagBoolean(flags, "init-ci");
|
|
11220
10934
|
const assistantBridge = flagString(flags, "assistant-bridge");
|
|
11221
|
-
const hasEssence =
|
|
10935
|
+
const hasEssence = existsSync28(join31(projectRoot, "decantr.essence.json"));
|
|
11222
10936
|
const proposalFlag = flagBoolean(flags, "replace-essence") ? "--replace-essence" : flagBoolean(flags, "merge-proposal") || hasEssence ? "--merge-proposal" : "--accept-proposal";
|
|
11223
10937
|
const steps = [
|
|
11224
10938
|
"analyze current app and write .decantr/brownfield intelligence",
|
|
@@ -11267,7 +10981,7 @@ async function cmdAdoptWorkflow(args) {
|
|
|
11267
10981
|
if (hydratePacks) {
|
|
11268
10982
|
try {
|
|
11269
10983
|
const { bundle, contextDir } = await compileHostedExecutionPackBundle(
|
|
11270
|
-
|
|
10984
|
+
join31(projectRoot, "decantr.essence.json")
|
|
11271
10985
|
);
|
|
11272
10986
|
const written = writeHostedExecutionPackContextArtifacts(
|
|
11273
10987
|
contextDir,
|
|
@@ -11478,9 +11192,9 @@ async function cmdVerifyWorkflow(args) {
|
|
|
11478
11192
|
}
|
|
11479
11193
|
}
|
|
11480
11194
|
function readJsonIfPresent(path) {
|
|
11481
|
-
if (!
|
|
11195
|
+
if (!existsSync28(path)) return null;
|
|
11482
11196
|
try {
|
|
11483
|
-
return JSON.parse(
|
|
11197
|
+
return JSON.parse(readFileSync21(path, "utf-8"));
|
|
11484
11198
|
} catch {
|
|
11485
11199
|
return null;
|
|
11486
11200
|
}
|
|
@@ -11632,7 +11346,7 @@ async function cmdTaskWorkflow(args) {
|
|
|
11632
11346
|
}
|
|
11633
11347
|
const route = routeInput.startsWith("/") ? routeInput : `/${routeInput}`;
|
|
11634
11348
|
const taskSummary = positional.slice(1).join(" ").trim();
|
|
11635
|
-
const essencePath =
|
|
11349
|
+
const essencePath = join31(workspaceInfo.appRoot, "decantr.essence.json");
|
|
11636
11350
|
const essence = readJsonIfPresent(essencePath);
|
|
11637
11351
|
if (!essence) {
|
|
11638
11352
|
console.error(
|
|
@@ -11656,19 +11370,19 @@ async function cmdTaskWorkflow(args) {
|
|
|
11656
11370
|
}
|
|
11657
11371
|
const section = essence.blueprint.sections.find((entry) => entry.id === target.section);
|
|
11658
11372
|
const page = section?.pages.find((entry) => entry.id === target.page);
|
|
11659
|
-
const contextDir =
|
|
11660
|
-
const manifest = readJsonIfPresent(
|
|
11661
|
-
const projectJson = readJsonIfPresent(
|
|
11373
|
+
const contextDir = join31(workspaceInfo.appRoot, ".decantr", "context");
|
|
11374
|
+
const manifest = readJsonIfPresent(join31(contextDir, "pack-manifest.json"));
|
|
11375
|
+
const projectJson = readJsonIfPresent(join31(workspaceInfo.appRoot, ".decantr", "project.json"));
|
|
11662
11376
|
const pagePack = manifest?.pages?.find((entry) => entry.id === target.page);
|
|
11663
11377
|
const sectionPack = manifest?.sections?.find((entry) => entry.id === target.section);
|
|
11664
|
-
const visualManifest = readJsonIfPresent(
|
|
11378
|
+
const visualManifest = readJsonIfPresent(join31(workspaceInfo.appRoot, ".decantr", "evidence", "visual-manifest.json"));
|
|
11665
11379
|
const screenshot = visualManifest?.routes?.find((entry) => entry.route === route)?.screenshot;
|
|
11666
11380
|
const localPatternPackPath = localPatternsPath(workspaceInfo.appRoot);
|
|
11667
11381
|
const localRuleManifestPath = localRulesPath(workspaceInfo.appRoot);
|
|
11668
11382
|
const acceptedStyleBridgePath = styleBridgePath(workspaceInfo.appRoot);
|
|
11669
|
-
const graphDir =
|
|
11670
|
-
const contractCapsulePath =
|
|
11671
|
-
const graphSnapshotPath =
|
|
11383
|
+
const graphDir = join31(workspaceInfo.appRoot, ".decantr", "graph");
|
|
11384
|
+
const contractCapsulePath = join31(graphDir, "contract-capsule.json");
|
|
11385
|
+
const graphSnapshotPath = join31(graphDir, "graph.snapshot.json");
|
|
11672
11386
|
const contractCapsule = readJsonIfPresent(contractCapsulePath);
|
|
11673
11387
|
const graphSnapshot = readJsonIfPresent(graphSnapshotPath);
|
|
11674
11388
|
const routeGraphContext = buildGraphRouteContext(graphSnapshot, route, { task: taskSummary });
|
|
@@ -11711,21 +11425,21 @@ async function cmdTaskWorkflow(args) {
|
|
|
11711
11425
|
projectRoot: workspaceInfo.appRoot,
|
|
11712
11426
|
workflowMode: projectJson?.initialized?.workflowMode ?? null,
|
|
11713
11427
|
adoptionMode: projectJson?.initialized?.adoptionMode ?? null,
|
|
11714
|
-
hasLocalPatterns:
|
|
11715
|
-
hasLocalRules:
|
|
11428
|
+
hasLocalPatterns: existsSync28(localPatternPackPath),
|
|
11429
|
+
hasLocalRules: existsSync28(localRuleManifestPath),
|
|
11716
11430
|
hasPackManifest: Boolean(manifest),
|
|
11717
11431
|
taskSummary,
|
|
11718
|
-
hasStyleBridge:
|
|
11432
|
+
hasStyleBridge: existsSync28(acceptedStyleBridgePath)
|
|
11719
11433
|
});
|
|
11720
11434
|
const readTargets = [
|
|
11721
|
-
pagePack ? displayProjectPath(workspaceInfo,
|
|
11722
|
-
sectionPack ? displayProjectPath(workspaceInfo,
|
|
11723
|
-
manifest?.scaffold?.markdown ? displayProjectPath(workspaceInfo,
|
|
11435
|
+
pagePack ? displayProjectPath(workspaceInfo, join31(".decantr/context", pagePack.markdown)) : null,
|
|
11436
|
+
sectionPack ? displayProjectPath(workspaceInfo, join31(".decantr/context", sectionPack.markdown)) : null,
|
|
11437
|
+
manifest?.scaffold?.markdown ? displayProjectPath(workspaceInfo, join31(".decantr/context", manifest.scaffold.markdown)) : null,
|
|
11724
11438
|
displayProjectPath(workspaceInfo, ".decantr/context/scaffold.md"),
|
|
11725
11439
|
displayProjectPath(workspaceInfo, "DECANTR.md"),
|
|
11726
|
-
|
|
11727
|
-
|
|
11728
|
-
|
|
11440
|
+
existsSync28(localPatternPackPath) ? displayProjectPath(workspaceInfo, ".decantr/local-patterns.json") : null,
|
|
11441
|
+
existsSync28(localRuleManifestPath) ? displayProjectPath(workspaceInfo, ".decantr/rules.json") : null,
|
|
11442
|
+
existsSync28(acceptedStyleBridgePath) ? displayProjectPath(workspaceInfo, ".decantr/style-bridge.json") : null,
|
|
11729
11443
|
contractCapsule ? displayProjectPath(workspaceInfo, ".decantr/graph/contract-capsule.json") : null,
|
|
11730
11444
|
routeGraphContext && !contractCapsule ? displayProjectPath(workspaceInfo, ".decantr/graph/graph.snapshot.json") : null
|
|
11731
11445
|
].filter((value) => Boolean(value));
|
|
@@ -12045,7 +11759,7 @@ async function cmdCodifyWorkflow(args) {
|
|
|
12045
11759
|
const workspaceInfo = resolveWorkflowProject(flags, "codify");
|
|
12046
11760
|
if (!workspaceInfo) return;
|
|
12047
11761
|
if (flagBoolean(flags, "accept")) {
|
|
12048
|
-
if (!
|
|
11762
|
+
if (!existsSync28(localPatternsProposalPath(workspaceInfo.appRoot)) && !existsSync28(localRulesProposalPath(workspaceInfo.appRoot)) && !existsSync28(styleBridgeProposalPath(workspaceInfo.appRoot))) {
|
|
12049
11763
|
console.error(
|
|
12050
11764
|
error2(
|
|
12051
11765
|
"No codify proposal found. Run `decantr codify --from-audit`, `decantr codify --style-bridge`, or `decantr codify` first."
|
|
@@ -12079,14 +11793,14 @@ async function cmdCodifyWorkflow(args) {
|
|
|
12079
11793
|
}
|
|
12080
11794
|
const detected = detectProject(workspaceInfo.appRoot);
|
|
12081
11795
|
const essence = readJsonIfPresent(
|
|
12082
|
-
|
|
11796
|
+
join31(workspaceInfo.appRoot, "decantr.essence.json")
|
|
12083
11797
|
);
|
|
12084
11798
|
const fromAudit = flagBoolean(flags, "from-audit") || flagBoolean(flags, "discover-local-patterns") || flagBoolean(flags, "codify-local-patterns");
|
|
12085
11799
|
const wantsStyleBridge = flagBoolean(flags, "style-bridge");
|
|
12086
11800
|
const mapPatternSlug = flagString(flags, "map-pattern") ?? flagString(flags, "hosted-pattern");
|
|
12087
11801
|
if (mapPatternSlug) {
|
|
12088
11802
|
const registryClient = new RegistryClient({
|
|
12089
|
-
cacheDir:
|
|
11803
|
+
cacheDir: join31(workspaceInfo.appRoot, ".decantr", "cache")
|
|
12090
11804
|
});
|
|
12091
11805
|
const candidates = await loadPatternDiscoveryCandidates(registryClient);
|
|
12092
11806
|
const candidate = findPatternCandidateBySlug(candidates, mapPatternSlug);
|
|
@@ -12171,8 +11885,12 @@ async function cmdCodifyWorkflow(args) {
|
|
|
12171
11885
|
}
|
|
12172
11886
|
async function cmdContentWorkflow(args) {
|
|
12173
11887
|
const subcommand = args[1] ?? "check";
|
|
11888
|
+
if (subcommand === "summary" || subcommand === "compile-packs" || subcommand === "get-pack") {
|
|
11889
|
+
await cmdContentCorpusWorkflow(args, "content");
|
|
11890
|
+
return;
|
|
11891
|
+
}
|
|
12174
11892
|
if (subcommand === "check" || subcommand === "health") {
|
|
12175
|
-
const { cmdContentHealth, parseContentHealthArgs } = await import("./content-health-
|
|
11893
|
+
const { cmdContentHealth, parseContentHealthArgs } = await import("./content-health-TDV4LP2C.js");
|
|
12176
11894
|
await cmdContentHealth(
|
|
12177
11895
|
process.cwd(),
|
|
12178
11896
|
parseContentHealthArgs(["content-health", ...args.slice(2)])
|
|
@@ -12193,19 +11911,74 @@ async function cmdContentWorkflow(args) {
|
|
|
12193
11911
|
return;
|
|
12194
11912
|
}
|
|
12195
11913
|
if (subcommand === "publish") {
|
|
12196
|
-
|
|
12197
|
-
|
|
12198
|
-
|
|
12199
|
-
|
|
12200
|
-
|
|
12201
|
-
|
|
11914
|
+
console.error(
|
|
11915
|
+
error2(
|
|
11916
|
+
"Hosted community publishing has been retired. Add official corpus changes under packages/content and run decantr content check."
|
|
11917
|
+
)
|
|
11918
|
+
);
|
|
11919
|
+
process.exitCode = 1;
|
|
11920
|
+
return;
|
|
11921
|
+
}
|
|
11922
|
+
console.error(error2("Usage: decantr content <check|create|summary|compile-packs|get-pack>"));
|
|
11923
|
+
process.exitCode = 1;
|
|
11924
|
+
}
|
|
11925
|
+
async function cmdContentCorpusWorkflow(args, commandName) {
|
|
11926
|
+
const subcommand = args[1];
|
|
11927
|
+
if (subcommand === "summary") {
|
|
11928
|
+
const namespaceIdx = args.indexOf("--namespace");
|
|
11929
|
+
const namespace = namespaceIdx !== -1 ? args[namespaceIdx + 1] : void 0;
|
|
11930
|
+
const jsonOutput = args.includes("--json");
|
|
11931
|
+
await printRegistryIntelligenceSummary(namespace, jsonOutput);
|
|
11932
|
+
return;
|
|
11933
|
+
}
|
|
11934
|
+
if (subcommand === "compile-packs") {
|
|
11935
|
+
const namespaceIdx = args.indexOf("--namespace");
|
|
11936
|
+
const namespace = namespaceIdx !== -1 ? args[namespaceIdx + 1] : void 0;
|
|
11937
|
+
const jsonOutput = args.includes("--json");
|
|
11938
|
+
const writeContext = args.includes("--write-context");
|
|
11939
|
+
const essencePath = args[2] && !args[2].startsWith("--") ? args[2] : void 0;
|
|
11940
|
+
await printHostedExecutionPackBundle(essencePath, namespace, jsonOutput, writeContext);
|
|
11941
|
+
return;
|
|
11942
|
+
}
|
|
11943
|
+
if (subcommand === "get-pack") {
|
|
11944
|
+
const namespaceIdx = args.indexOf("--namespace");
|
|
11945
|
+
const namespace = namespaceIdx !== -1 ? args[namespaceIdx + 1] : void 0;
|
|
11946
|
+
const jsonOutput = args.includes("--json");
|
|
11947
|
+
const writeContext = args.includes("--write-context");
|
|
11948
|
+
const essenceIdx = args.indexOf("--essence");
|
|
11949
|
+
const essencePath = essenceIdx !== -1 ? args[essenceIdx + 1] : void 0;
|
|
11950
|
+
const packType = args[2] && !args[2].startsWith("--") ? args[2] : void 0;
|
|
11951
|
+
const routeIdx = args.indexOf("--route");
|
|
11952
|
+
const route = routeIdx !== -1 ? args[routeIdx + 1] : void 0;
|
|
11953
|
+
let id = args[3] && !args[3].startsWith("--") ? args[3] : void 0;
|
|
11954
|
+
if (!packType || !["manifest", "scaffold", "review", "section", "page", "mutation"].includes(packType)) {
|
|
11955
|
+
console.error(
|
|
11956
|
+
`${RED13}Usage: decantr ${commandName} get-pack <manifest|scaffold|review|section|page|mutation> [id] [--namespace <namespace>] [--json] [--essence <path>] [--write-context]${RESET18}`
|
|
11957
|
+
);
|
|
12202
11958
|
process.exitCode = 1;
|
|
12203
11959
|
return;
|
|
12204
11960
|
}
|
|
12205
|
-
|
|
11961
|
+
if (packType === "manifest") {
|
|
11962
|
+
await printHostedExecutionPackManifest(essencePath, namespace, jsonOutput, writeContext);
|
|
11963
|
+
return;
|
|
11964
|
+
}
|
|
11965
|
+
if (packType === "page" && route && !id) {
|
|
11966
|
+
const resolvedPath = essencePath ? resolveUserPath(essencePath) : join31(process.cwd(), "decantr.essence.json");
|
|
11967
|
+
id = resolvePagePackIdForRoute(resolvedPath, route);
|
|
11968
|
+
}
|
|
11969
|
+
await printHostedSelectedExecutionPack(
|
|
11970
|
+
packType,
|
|
11971
|
+
id,
|
|
11972
|
+
essencePath,
|
|
11973
|
+
namespace,
|
|
11974
|
+
jsonOutput,
|
|
11975
|
+
writeContext
|
|
11976
|
+
);
|
|
12206
11977
|
return;
|
|
12207
11978
|
}
|
|
12208
|
-
console.error(
|
|
11979
|
+
console.error(
|
|
11980
|
+
`${RED13}Usage: decantr ${commandName} summary [--namespace <namespace>] [--json] | decantr ${commandName} compile-packs [path] [--namespace <namespace>] [--json] [--write-context] | decantr ${commandName} get-pack <manifest|scaffold|review|section|page|mutation> [id] [--namespace <namespace>] [--json] [--essence <path>] [--write-context]${RESET18}`
|
|
11981
|
+
);
|
|
12209
11982
|
process.exitCode = 1;
|
|
12210
11983
|
}
|
|
12211
11984
|
function cmdHelp() {
|
|
@@ -12215,7 +11988,7 @@ ${BOLD11}decantr${RESET18} \u2014 AI Frontend Governance for codebases touched b
|
|
|
12215
11988
|
${BOLD11}Usage:${RESET18}
|
|
12216
11989
|
decantr setup [--project <path>]
|
|
12217
11990
|
decantr scan [--project <path>] [--json]
|
|
12218
|
-
decantr new <name> [--blueprint=X] [--archetype=X] [--theme=X] [--workflow=greenfield] [--adoption=decantr-css] [--telemetry]
|
|
11991
|
+
decantr new <name> [--blueprint=X] [--archetype=X] [--theme=X] [--workflow=greenfield] [--adoption=contract-only|decantr-css] [--telemetry]
|
|
12219
11992
|
decantr adopt [--project <path>] [--base-url <url>] [--evidence] [--ci] [--no-packs] [--yes]
|
|
12220
11993
|
decantr task <route> ["task summary"] [--project <path>] [--since origin/main] [--json]
|
|
12221
11994
|
decantr verify [--project <path>] [--brownfield] [--local-patterns] [health options]
|
|
@@ -12247,11 +12020,9 @@ ${BOLD11}Advanced primitives:${RESET18}
|
|
|
12247
12020
|
decantr get <type> <id>
|
|
12248
12021
|
decantr list <type> [--sort <recommended|recent|name>] [--recommended] [--source <authored|benchmark|hybrid>]
|
|
12249
12022
|
decantr showcase [manifest|shortlist|verification] [--json]
|
|
12250
|
-
decantr
|
|
12251
|
-
decantr
|
|
12252
|
-
decantr
|
|
12253
|
-
decantr registry critique-file <file> [--namespace <namespace>] [--json] [--essence <path>] [--treatments <path>]
|
|
12254
|
-
decantr registry audit-project [--namespace <namespace>] [--json] [--essence <path>] [--dist <path>] [--sources <dir>]
|
|
12023
|
+
decantr content summary [--namespace <namespace>] [--json]
|
|
12024
|
+
decantr content compile-packs [path] [--namespace <namespace>] [--json] [--write-context]
|
|
12025
|
+
decantr content get-pack <manifest|scaffold|review|section|page|mutation> [id] [--namespace <namespace>] [--json] [--essence <path>] [--write-context]
|
|
12255
12026
|
decantr health [--format text|json|markdown] [--ci] [--fail-on error|warn|none]
|
|
12256
12027
|
decantr health --evidence [--browser] [--base-url <url>] [--design-tokens <path>]
|
|
12257
12028
|
decantr health --diagnostics [--json|--markdown]
|
|
@@ -12295,7 +12066,7 @@ ${BOLD11}Init Options:${RESET18}
|
|
|
12295
12066
|
--existing Initialize in existing project
|
|
12296
12067
|
--offline Force offline mode
|
|
12297
12068
|
--yes, -y Accept defaults, skip confirmations
|
|
12298
|
-
--registry Custom
|
|
12069
|
+
--registry Custom API URL (legacy alias; prefer DECANTR_API_URL)
|
|
12299
12070
|
--telemetry Opt this project into privacy-filtered CLI product telemetry
|
|
12300
12071
|
|
|
12301
12072
|
${BOLD11}Commands:${RESET18}
|
|
@@ -12312,7 +12083,7 @@ ${BOLD11}Commands:${RESET18}
|
|
|
12312
12083
|
${cyan4("connect")} Connect Decantr to AI coding tools such as Cursor
|
|
12313
12084
|
${cyan4("codify")} Propose or accept project-owned Brownfield UI patterns, behavior obligations, and rules
|
|
12314
12085
|
${cyan4("studio")} Open a local Project Health dashboard backed by the same report
|
|
12315
|
-
${cyan4("content")}
|
|
12086
|
+
${cyan4("content")} Official content-corpus namespace: check, summary, packs, create
|
|
12316
12087
|
|
|
12317
12088
|
${BOLD11}Advanced commands:${RESET18}
|
|
12318
12089
|
${cyan4("magic")} Greenfield-first intent flow; steers existing apps into analyze + init
|
|
@@ -12328,7 +12099,7 @@ ${BOLD11}Advanced commands:${RESET18}
|
|
|
12328
12099
|
${cyan4("sync-drift")} Review and resolve drift log entries
|
|
12329
12100
|
${cyan4("resolve")} Group source-vs-contract conflicts and print exact resolution actions
|
|
12330
12101
|
${cyan4("graph")} Generate .decantr/graph snapshot, history, manifest, diff, and contract capsule
|
|
12331
|
-
${cyan4("search")} Search official
|
|
12102
|
+
${cyan4("search")} Search official content-corpus vocabulary
|
|
12332
12103
|
${cyan4("suggest")} Suggest patterns or alternatives for a query
|
|
12333
12104
|
${cyan4("get")} Get full details of a vocabulary item
|
|
12334
12105
|
${cyan4("list")} List items by type
|
|
@@ -12336,9 +12107,9 @@ ${BOLD11}Advanced commands:${RESET18}
|
|
|
12336
12107
|
${cyan4("validate")} Validate an Essence v4 file
|
|
12337
12108
|
${cyan4("theme")} Manage custom themes (create, list, validate, delete, import)
|
|
12338
12109
|
${cyan4("create")} Create a custom content item (pattern, theme, blueprint, etc.)
|
|
12339
|
-
${cyan4("publish")}
|
|
12340
|
-
${cyan4("login")}
|
|
12341
|
-
${cyan4("logout")} Remove stored credentials
|
|
12110
|
+
${cyan4("publish")} Legacy retired hosted publishing command
|
|
12111
|
+
${cyan4("login")} Legacy API-key helper for compatibility scripts
|
|
12112
|
+
${cyan4("logout")} Remove stored legacy credentials
|
|
12342
12113
|
${cyan4("analyze")} Brownfield entrypoint: scan an existing project and emit attach guidance
|
|
12343
12114
|
${cyan4("telemetry")} Inspect or link this project's opted-in CLI telemetry identity
|
|
12344
12115
|
${cyan4("export")} Export design tokens to framework format (shadcn, tailwind, css-vars)
|
|
@@ -12353,6 +12124,7 @@ ${BOLD11}Examples:${RESET18}
|
|
|
12353
12124
|
decantr scan
|
|
12354
12125
|
decantr scan --json
|
|
12355
12126
|
decantr new my-app --blueprint=carbon-ai-portal
|
|
12127
|
+
decantr new my-app --blueprint=carbon-ai-portal --adoption=decantr-css
|
|
12356
12128
|
decantr adopt --yes
|
|
12357
12129
|
decantr adopt --project apps/web --yes
|
|
12358
12130
|
decantr task /feed "add saved recipe actions"
|
|
@@ -12405,18 +12177,16 @@ ${BOLD11}Examples:${RESET18}
|
|
|
12405
12177
|
decantr list patterns
|
|
12406
12178
|
decantr showcase shortlist
|
|
12407
12179
|
decantr showcase verification --json
|
|
12408
|
-
decantr
|
|
12409
|
-
decantr
|
|
12410
|
-
decantr
|
|
12411
|
-
decantr
|
|
12412
|
-
decantr
|
|
12413
|
-
decantr registry critique-file src/pages/Home.tsx --namespace @official --json
|
|
12414
|
-
decantr registry audit-project --namespace @official --json
|
|
12415
|
-
decantr registry audit-project --namespace @official --dist dist --sources src
|
|
12180
|
+
decantr content summary --namespace @official
|
|
12181
|
+
decantr content compile-packs decantr.essence.json --json
|
|
12182
|
+
decantr content compile-packs decantr.essence.json --write-context
|
|
12183
|
+
decantr content get-pack manifest --namespace @official --json
|
|
12184
|
+
decantr content get-pack review --namespace @official --write-context
|
|
12416
12185
|
decantr create pattern my-card
|
|
12417
12186
|
|
|
12418
12187
|
${BOLD11}Workflow Model:${RESET18}
|
|
12419
|
-
${cyan4("Greenfield blueprint")} decantr new my-app --blueprint=X --workflow=greenfield --adoption=
|
|
12188
|
+
${cyan4("Greenfield blueprint")} decantr new my-app --blueprint=X --workflow=greenfield --adoption=contract-only
|
|
12189
|
+
${cyan4("Legacy CSS adapter")} decantr new my-app --blueprint=X --adoption=decantr-css
|
|
12420
12190
|
${cyan4("Greenfield contract")} decantr init --workflow=greenfield --adoption=contract-only
|
|
12421
12191
|
${cyan4("Brownfield adoption")} decantr adopt --yes
|
|
12422
12192
|
${cyan4("Brownfield preview")} decantr scan -> decantr adopt --yes
|
|
@@ -12426,10 +12196,10 @@ ${BOLD11}Workflow Model:${RESET18}
|
|
|
12426
12196
|
${cyan4("Drift resolution")} decantr resolve -> codify/init/graph/repair source explicitly
|
|
12427
12197
|
${cyan4("Typed contract graph")} decantr graph -> agent session loads .decantr/graph/contract-capsule.json
|
|
12428
12198
|
${cyan4("Project-owned law")} decantr codify --from-audit -> edit proposal -> decantr codify --accept
|
|
12429
|
-
${cyan4("Hybrid composition")} decantr add/remove, decantr theme switch, decantr
|
|
12199
|
+
${cyan4("Hybrid composition")} decantr add/remove, decantr theme switch, decantr content, decantr upgrade
|
|
12430
12200
|
|
|
12431
12201
|
${BOLD11}Bootstrap adapters:${RESET18}
|
|
12432
|
-
Runnable starter adapters: ${cyan4("react-vite")}, ${cyan4("next-app")}, ${cyan4("vanilla-vite")}, ${cyan4("vue-vite")}, ${cyan4("sveltekit")}, ${cyan4("angular")}, ${cyan4("solid-vite")}
|
|
12202
|
+
Runnable starter adapters are legacy opt-in via ${cyan4("--adoption=decantr-css")}: ${cyan4("react-vite")}, ${cyan4("next-app")}, ${cyan4("vanilla-vite")}, ${cyan4("vue-vite")}, ${cyan4("sveltekit")}, ${cyan4("angular")}, ${cyan4("solid-vite")}
|
|
12433
12203
|
Unsupported targets resolve through ${cyan4("generic-web")} contract-only mode until their starter adapters land.
|
|
12434
12204
|
`);
|
|
12435
12205
|
}
|
|
@@ -12460,7 +12230,7 @@ ${BOLD11}Usage:${RESET18}
|
|
|
12460
12230
|
|
|
12461
12231
|
${BOLD11}Options:${RESET18}
|
|
12462
12232
|
--project App path inside a workspace/monorepo
|
|
12463
|
-
--json Emit the
|
|
12233
|
+
--json Emit the ScanReportV2 JSON to stdout
|
|
12464
12234
|
|
|
12465
12235
|
${BOLD11}Behavior:${RESET18}
|
|
12466
12236
|
Reads local project files, detects frontend framework/routes/styling/static-hosting signals,
|
|
@@ -12602,15 +12372,15 @@ ${BOLD11}Examples:${RESET18}
|
|
|
12602
12372
|
}
|
|
12603
12373
|
function cmdRegistryHelp() {
|
|
12604
12374
|
console.log(`
|
|
12605
|
-
${BOLD11}decantr registry${RESET18} \u2014
|
|
12375
|
+
${BOLD11}decantr registry${RESET18} \u2014 Legacy compatibility alias for content-corpus helpers
|
|
12606
12376
|
|
|
12607
12377
|
${BOLD11}Usage:${RESET18}
|
|
12608
12378
|
decantr registry summary [--namespace <namespace>] [--json]
|
|
12609
12379
|
decantr registry compile-packs [path] [--namespace <namespace>] [--json] [--write-context]
|
|
12610
12380
|
decantr registry get-pack <manifest|scaffold|review|section|page|mutation> [id] [--namespace <namespace>] [--json] [--essence <path>] [--write-context]
|
|
12611
12381
|
decantr registry get-pack page --route <route> [--namespace <namespace>] [--json] [--essence <path>]
|
|
12612
|
-
|
|
12613
|
-
|
|
12382
|
+
|
|
12383
|
+
Prefer the equivalent decantr content commands for new scripts.
|
|
12614
12384
|
`);
|
|
12615
12385
|
}
|
|
12616
12386
|
function cmdThemeHelp() {
|
|
@@ -12753,17 +12523,20 @@ ${BOLD11}Examples:${RESET18}
|
|
|
12753
12523
|
}
|
|
12754
12524
|
function cmdContentHelp() {
|
|
12755
12525
|
console.log(`
|
|
12756
|
-
${BOLD11}decantr content${RESET18} \u2014
|
|
12526
|
+
${BOLD11}decantr content${RESET18} \u2014 Official content-corpus namespace
|
|
12757
12527
|
|
|
12758
12528
|
${BOLD11}Usage:${RESET18}
|
|
12759
12529
|
decantr content check [content-health options]
|
|
12530
|
+
decantr content summary [--namespace <namespace>] [--json]
|
|
12531
|
+
decantr content compile-packs [path] [--namespace <namespace>] [--json] [--write-context]
|
|
12532
|
+
decantr content get-pack <manifest|scaffold|review|section|page|mutation> [id] [--namespace <namespace>] [--json] [--essence <path>] [--write-context]
|
|
12760
12533
|
decantr content create <type> <name>
|
|
12761
|
-
decantr content publish <type> <name>
|
|
12762
12534
|
|
|
12763
12535
|
${BOLD11}Examples:${RESET18}
|
|
12764
12536
|
decantr content check --ci --fail-on error
|
|
12537
|
+
decantr content summary --namespace @official --json
|
|
12538
|
+
decantr content compile-packs decantr.essence.json --write-context
|
|
12765
12539
|
decantr content create pattern my-card
|
|
12766
|
-
decantr content publish pattern my-card
|
|
12767
12540
|
`);
|
|
12768
12541
|
}
|
|
12769
12542
|
function printCommandHelp(command, args) {
|
|
@@ -12840,11 +12613,11 @@ async function main() {
|
|
|
12840
12613
|
}
|
|
12841
12614
|
if (command === "--version" || command === "-v" || command === "version") {
|
|
12842
12615
|
try {
|
|
12843
|
-
const here = dirname8(
|
|
12844
|
-
const candidates = [
|
|
12616
|
+
const here = dirname8(fileURLToPath4(import.meta.url));
|
|
12617
|
+
const candidates = [join31(here, "..", "package.json"), join31(here, "..", "..", "package.json")];
|
|
12845
12618
|
for (const candidate of candidates) {
|
|
12846
|
-
if (
|
|
12847
|
-
const pkg = JSON.parse(
|
|
12619
|
+
if (existsSync28(candidate)) {
|
|
12620
|
+
const pkg = JSON.parse(readFileSync21(candidate, "utf-8"));
|
|
12848
12621
|
if (pkg.version) {
|
|
12849
12622
|
console.log(pkg.version);
|
|
12850
12623
|
return;
|
|
@@ -13041,7 +12814,7 @@ async function main() {
|
|
|
13041
12814
|
break;
|
|
13042
12815
|
}
|
|
13043
12816
|
case "upgrade": {
|
|
13044
|
-
const { cmdUpgrade } = await import("./upgrade-
|
|
12817
|
+
const { cmdUpgrade } = await import("./upgrade-NN7NTA4L.js");
|
|
13045
12818
|
const { flags } = parseLooseArgs(args);
|
|
13046
12819
|
const workspaceInfo = resolveWorkflowProject(flags, "upgrade");
|
|
13047
12820
|
if (!workspaceInfo) break;
|
|
@@ -13095,7 +12868,7 @@ async function main() {
|
|
|
13095
12868
|
cmdContentHealthHelp();
|
|
13096
12869
|
break;
|
|
13097
12870
|
}
|
|
13098
|
-
const { cmdContentHealth, parseContentHealthArgs } = await import("./content-health-
|
|
12871
|
+
const { cmdContentHealth, parseContentHealthArgs } = await import("./content-health-TDV4LP2C.js");
|
|
13099
12872
|
await cmdContentHealth(process.cwd(), parseContentHealthArgs(args));
|
|
13100
12873
|
} catch (e) {
|
|
13101
12874
|
console.error(error2(e.message));
|
|
@@ -13158,7 +12931,8 @@ async function main() {
|
|
|
13158
12931
|
break;
|
|
13159
12932
|
}
|
|
13160
12933
|
case "audit": {
|
|
13161
|
-
|
|
12934
|
+
const filePath = args[1] && !args[1].startsWith("--") ? args[1] : void 0;
|
|
12935
|
+
await cmdAudit(filePath, { json: args.includes("--json") });
|
|
13162
12936
|
break;
|
|
13163
12937
|
}
|
|
13164
12938
|
case "search": {
|
|
@@ -13299,7 +13073,7 @@ async function main() {
|
|
|
13299
13073
|
const requestedView = args[1];
|
|
13300
13074
|
const view = requestedView === "manifest" || requestedView === "shortlist" || requestedView === "verification" ? requestedView : "shortlist";
|
|
13301
13075
|
const jsonOutput = args.includes("--json");
|
|
13302
|
-
if (requestedView
|
|
13076
|
+
if (requestedView?.startsWith("--")) {
|
|
13303
13077
|
await printShowcaseBenchmarks("shortlist", jsonOutput);
|
|
13304
13078
|
break;
|
|
13305
13079
|
}
|
|
@@ -13324,7 +13098,7 @@ async function main() {
|
|
|
13324
13098
|
}
|
|
13325
13099
|
case "login": {
|
|
13326
13100
|
const apiKeyArg = args[1];
|
|
13327
|
-
if (apiKeyArg
|
|
13101
|
+
if (apiKeyArg?.startsWith("--api-key=")) {
|
|
13328
13102
|
const key = apiKeyArg.split("=")[1];
|
|
13329
13103
|
saveCredentials({ access_token: key, api_key: key });
|
|
13330
13104
|
console.log(success4("API key saved."));
|
|
@@ -13408,59 +13182,12 @@ async function main() {
|
|
|
13408
13182
|
const mirrorType = typeIdx !== -1 ? args[typeIdx + 1] : void 0;
|
|
13409
13183
|
await cmdRegistryMirror(process.cwd(), { type: mirrorType });
|
|
13410
13184
|
} else if (subcommand === "summary") {
|
|
13411
|
-
|
|
13412
|
-
const namespace = namespaceIdx !== -1 ? args[namespaceIdx + 1] : void 0;
|
|
13413
|
-
const jsonOutput = args.includes("--json");
|
|
13414
|
-
await printRegistryIntelligenceSummary(namespace, jsonOutput);
|
|
13185
|
+
await cmdContentCorpusWorkflow(args, "registry");
|
|
13415
13186
|
} else if (subcommand === "compile-packs") {
|
|
13416
|
-
|
|
13417
|
-
const namespace = namespaceIdx !== -1 ? args[namespaceIdx + 1] : void 0;
|
|
13418
|
-
const jsonOutput = args.includes("--json");
|
|
13419
|
-
const writeContext = args.includes("--write-context");
|
|
13420
|
-
const essencePath = args[2] && !args[2].startsWith("--") ? args[2] : void 0;
|
|
13421
|
-
await printHostedExecutionPackBundle(essencePath, namespace, jsonOutput, writeContext);
|
|
13187
|
+
await cmdContentCorpusWorkflow(args, "registry");
|
|
13422
13188
|
} else if (subcommand === "get-pack") {
|
|
13423
|
-
|
|
13424
|
-
const namespace = namespaceIdx !== -1 ? args[namespaceIdx + 1] : void 0;
|
|
13425
|
-
const jsonOutput = args.includes("--json");
|
|
13426
|
-
const writeContext = args.includes("--write-context");
|
|
13427
|
-
const essenceIdx = args.indexOf("--essence");
|
|
13428
|
-
const essencePath = essenceIdx !== -1 ? args[essenceIdx + 1] : void 0;
|
|
13429
|
-
const packType = args[2] && !args[2].startsWith("--") ? args[2] : void 0;
|
|
13430
|
-
const routeIdx = args.indexOf("--route");
|
|
13431
|
-
const route = routeIdx !== -1 ? args[routeIdx + 1] : void 0;
|
|
13432
|
-
let id = args[3] && !args[3].startsWith("--") ? args[3] : void 0;
|
|
13433
|
-
if (!packType || !["manifest", "scaffold", "review", "section", "page", "mutation"].includes(packType)) {
|
|
13434
|
-
console.error(
|
|
13435
|
-
`${RED13}Usage: decantr registry get-pack <manifest|scaffold|review|section|page|mutation> [id] [--namespace <namespace>] [--json] [--essence <path>] [--write-context]${RESET18}`
|
|
13436
|
-
);
|
|
13437
|
-
process.exitCode = 1;
|
|
13438
|
-
break;
|
|
13439
|
-
}
|
|
13440
|
-
if (packType === "manifest") {
|
|
13441
|
-
await printHostedExecutionPackManifest(essencePath, namespace, jsonOutput, writeContext);
|
|
13442
|
-
break;
|
|
13443
|
-
}
|
|
13444
|
-
if (packType === "page" && route && !id) {
|
|
13445
|
-
const resolvedPath = essencePath ? resolveUserPath(essencePath) : join32(process.cwd(), "decantr.essence.json");
|
|
13446
|
-
id = resolvePagePackIdForRoute(resolvedPath, route);
|
|
13447
|
-
}
|
|
13448
|
-
await printHostedSelectedExecutionPack(
|
|
13449
|
-
packType,
|
|
13450
|
-
id,
|
|
13451
|
-
essencePath,
|
|
13452
|
-
namespace,
|
|
13453
|
-
jsonOutput,
|
|
13454
|
-
writeContext
|
|
13455
|
-
);
|
|
13189
|
+
await cmdContentCorpusWorkflow(args, "registry");
|
|
13456
13190
|
} else if (subcommand === "critique-file") {
|
|
13457
|
-
const namespaceIdx = args.indexOf("--namespace");
|
|
13458
|
-
const namespace = namespaceIdx !== -1 ? args[namespaceIdx + 1] : void 0;
|
|
13459
|
-
const jsonOutput = args.includes("--json");
|
|
13460
|
-
const essenceIdx = args.indexOf("--essence");
|
|
13461
|
-
const essencePath = essenceIdx !== -1 ? args[essenceIdx + 1] : void 0;
|
|
13462
|
-
const treatmentsIdx = args.indexOf("--treatments");
|
|
13463
|
-
const treatmentsPath = treatmentsIdx !== -1 ? args[treatmentsIdx + 1] : void 0;
|
|
13464
13191
|
const sourcePath = args[2] && !args[2].startsWith("--") ? args[2] : void 0;
|
|
13465
13192
|
if (!sourcePath) {
|
|
13466
13193
|
console.error(
|
|
@@ -13469,27 +13196,14 @@ async function main() {
|
|
|
13469
13196
|
process.exitCode = 1;
|
|
13470
13197
|
break;
|
|
13471
13198
|
}
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
namespace,
|
|
13475
|
-
jsonOutput,
|
|
13476
|
-
essencePath,
|
|
13477
|
-
treatmentsPath
|
|
13478
|
-
);
|
|
13199
|
+
console.error(dim4("Hosted registry critique is retired; running local decantr audit instead."));
|
|
13200
|
+
await cmdAudit(sourcePath, { json: args.includes("--json") });
|
|
13479
13201
|
} else if (subcommand === "audit-project") {
|
|
13480
|
-
|
|
13481
|
-
|
|
13482
|
-
const jsonOutput = args.includes("--json");
|
|
13483
|
-
const essenceIdx = args.indexOf("--essence");
|
|
13484
|
-
const essencePath = essenceIdx !== -1 ? args[essenceIdx + 1] : void 0;
|
|
13485
|
-
const distIdx = args.indexOf("--dist");
|
|
13486
|
-
const distPath = distIdx !== -1 ? args[distIdx + 1] : void 0;
|
|
13487
|
-
const sourcesIdx = args.indexOf("--sources");
|
|
13488
|
-
const sourcesPath = sourcesIdx !== -1 ? args[sourcesIdx + 1] : void 0;
|
|
13489
|
-
await printHostedProjectAudit(namespace, jsonOutput, essencePath, distPath, sourcesPath);
|
|
13202
|
+
console.error(dim4("Hosted registry project audit is retired; running local decantr audit instead."));
|
|
13203
|
+
await cmdAudit(void 0, { json: args.includes("--json") });
|
|
13490
13204
|
} else {
|
|
13491
13205
|
console.error(
|
|
13492
|
-
`${RED13}Usage: decantr registry mirror [--type <type>] | decantr registry summary [--namespace <namespace>] [--json] | decantr registry compile-packs [path] [--namespace <namespace>] [--json] [--write-context] | decantr registry get-pack <manifest|scaffold|review|section|page|mutation> [id] [--namespace <namespace>] [--json] [--essence <path>] [--write-context]
|
|
13206
|
+
`${RED13}Usage: decantr registry mirror [--type <type>] | decantr registry summary [--namespace <namespace>] [--json] | decantr registry compile-packs [path] [--namespace <namespace>] [--json] [--write-context] | decantr registry get-pack <manifest|scaffold|review|section|page|mutation> [id] [--namespace <namespace>] [--json] [--essence <path>] [--write-context]${RESET18}`
|
|
13493
13207
|
);
|
|
13494
13208
|
process.exitCode = 1;
|
|
13495
13209
|
}
|
|
@@ -13640,7 +13354,7 @@ async function main() {
|
|
|
13640
13354
|
mcpOnly: flagBoolean(flags, "mcp-only"),
|
|
13641
13355
|
rulesOnly: flagBoolean(flags, "rules-only"),
|
|
13642
13356
|
routeHint,
|
|
13643
|
-
attached:
|
|
13357
|
+
attached: existsSync28(join31(workspaceInfo.appRoot, "decantr.essence.json"))
|
|
13644
13358
|
});
|
|
13645
13359
|
break;
|
|
13646
13360
|
}
|