@decantr/cli 2.9.6 → 2.9.7
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 +4 -0
- package/dist/bin.js +5 -5
- package/dist/{chunk-WONPNSSI.js → chunk-4SZ4SEKT.js} +24 -5
- package/dist/{chunk-32H5SFKV.js → chunk-66L74ZNJ.js} +152 -90
- package/dist/{chunk-RXF7ZYGK.js → chunk-IQZCIMQJ.js} +28 -1
- package/dist/{chunk-VCUFZB45.js → chunk-QDMXZSVK.js} +1 -1
- package/dist/{chunk-FACL3NXU.js → chunk-WPP3JEMC.js} +1 -1
- package/dist/{heal-ZQHEHBUJ.js → heal-2UCSPRTK.js} +1 -1
- package/dist/{health-R7AV5G4V.js → health-VAYRQVTF.js} +2 -2
- package/dist/index.js +5 -5
- package/dist/{studio-2734P63C.js → studio-WPETOZRW.js} +3 -3
- package/dist/{upgrade-VON7Y3LG.js → upgrade-7ZYWR2GH.js} +1 -1
- package/dist/{workspace-DRHTQ2NG.js → workspace-PBO3BJRL.js} +3 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -136,12 +136,16 @@ decantr list patterns
|
|
|
136
136
|
decantr showcase verification --json
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
+
`suggest --from-code` uses the selected app's source file to rank both hosted registry patterns and accepted project-owned local patterns, so Brownfield button/card/form law can surface from real code instead of just the text query.
|
|
140
|
+
|
|
139
141
|
## Project Health And Studio
|
|
140
142
|
|
|
141
143
|
`decantr verify` is the workflow command most users should run locally after edits. It delegates to Project Health, can add Brownfield guard validation with `--brownfield`, requires an accepted local pattern pack with `--local-patterns`, scans `.decantr/rules.json` when present, supports workspace mode, and writes evidence to `.decantr/evidence/latest.json` by default when `--evidence` is used.
|
|
142
144
|
|
|
143
145
|
`decantr doctor` explains project/workspace state, adoption mode, generated artifacts, local law, visual evidence, design authority signals, CI wiring, and the next command to run. It is the command to reach for when an app is in a monorepo, has stale Decantr files, or someone is not sure what Decantr expects next.
|
|
144
146
|
|
|
147
|
+
`decantr setup` is non-mutating orientation. In an attached Brownfield app it reflects whether local law is already accepted, so the recommended verify command includes `--local-patterns` only when the project has that layer.
|
|
148
|
+
|
|
145
149
|
`decantr ci` is the blessed non-mutating automation gate. It runs the Project Health surface with adoption-mode-aware local law checks and emits a schema-backed CI report. `decantr ci init` writes root GitHub workflows or portable generic snippets using the detected package manager and pinned local CLI command instead of `@latest`; if the root manifest has not pinned Decantr yet, it prints the exact install command first.
|
|
146
150
|
|
|
147
151
|
`decantr health` remains the advanced project observability primitive. It composes the existing verifier audit, guard checks, brownfield route drift checks, runtime evidence, and execution-pack files into a `ProjectHealthReport` with a status, score, route summary, pack summary, findings, and AI-ready remediation prompts.
|
package/dist/bin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./chunk-
|
|
3
|
-
import "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
2
|
+
import "./chunk-66L74ZNJ.js";
|
|
3
|
+
import "./chunk-IQZCIMQJ.js";
|
|
4
|
+
import "./chunk-QDMXZSVK.js";
|
|
5
|
+
import "./chunk-WPP3JEMC.js";
|
|
6
|
+
import "./chunk-4SZ4SEKT.js";
|
|
@@ -1971,6 +1971,16 @@ var YELLOW = "\x1B[33m";
|
|
|
1971
1971
|
var CYAN = "\x1B[36m";
|
|
1972
1972
|
var RESET = "\x1B[0m";
|
|
1973
1973
|
var DIM = "\x1B[2m";
|
|
1974
|
+
function isContractOnlyProject(projectRoot) {
|
|
1975
|
+
const metadataPath = join10(projectRoot, ".decantr", "project.json");
|
|
1976
|
+
if (!existsSync10(metadataPath)) return false;
|
|
1977
|
+
try {
|
|
1978
|
+
const metadata = JSON.parse(readFileSync10(metadataPath, "utf-8"));
|
|
1979
|
+
return metadata.initialized?.adoptionMode === "contract-only";
|
|
1980
|
+
} catch {
|
|
1981
|
+
return false;
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1974
1984
|
function collectCheckIssues(projectRoot = process.cwd(), options = {}) {
|
|
1975
1985
|
const essencePath = join10(projectRoot, "decantr.essence.json");
|
|
1976
1986
|
if (!existsSync10(essencePath)) {
|
|
@@ -2000,9 +2010,11 @@ function collectCheckIssues(projectRoot = process.cwd(), options = {}) {
|
|
|
2000
2010
|
return { essence, issues, missingEssence: false };
|
|
2001
2011
|
}
|
|
2002
2012
|
let interactionIssues = [];
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2013
|
+
if (!isContractOnlyProject(projectRoot)) {
|
|
2014
|
+
try {
|
|
2015
|
+
interactionIssues = scanProjectInteractions(projectRoot);
|
|
2016
|
+
} catch {
|
|
2017
|
+
}
|
|
2006
2018
|
}
|
|
2007
2019
|
try {
|
|
2008
2020
|
const guardContext = buildGuardRegistryContext(projectRoot);
|
|
@@ -2066,9 +2078,16 @@ async function cmdHeal(projectRoot = process.cwd(), options = {}) {
|
|
|
2066
2078
|
console.log(` ${DIM}Suggestion: ${issue.suggestion}${RESET}`);
|
|
2067
2079
|
}
|
|
2068
2080
|
}
|
|
2069
|
-
console.log(`
|
|
2070
|
-
${YELLOW}Manual fixes required. Review the issues above.${RESET}`);
|
|
2071
2081
|
const hasError = issues.some((i) => i.type === "error");
|
|
2082
|
+
if (hasError) {
|
|
2083
|
+
console.log(`
|
|
2084
|
+
${YELLOW}Manual fixes required. Review the issues above.${RESET}`);
|
|
2085
|
+
} else {
|
|
2086
|
+
console.log(
|
|
2087
|
+
`
|
|
2088
|
+
${YELLOW}Warnings found. Review the issues above or set stricter gates in CI.${RESET}`
|
|
2089
|
+
);
|
|
2090
|
+
}
|
|
2072
2091
|
if (hasError) {
|
|
2073
2092
|
process.exitCode = 1;
|
|
2074
2093
|
}
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
scaffoldProject,
|
|
15
15
|
syncRegistry,
|
|
16
16
|
writeExecutionPackBundleArtifacts
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-IQZCIMQJ.js";
|
|
18
18
|
import {
|
|
19
19
|
createWorkspaceHealthReport,
|
|
20
20
|
formatWorkspaceHealthMarkdown,
|
|
@@ -22,14 +22,14 @@ import {
|
|
|
22
22
|
listWorkspaceCandidates,
|
|
23
23
|
listWorkspaceProjects,
|
|
24
24
|
shouldFailWorkspaceHealth
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-QDMXZSVK.js";
|
|
26
26
|
import {
|
|
27
27
|
createProjectHealthReport,
|
|
28
28
|
formatProjectHealthMarkdown,
|
|
29
29
|
formatProjectHealthText,
|
|
30
30
|
resolveWorkspaceInfo,
|
|
31
31
|
shouldFailHealth
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-WPP3JEMC.js";
|
|
33
33
|
import {
|
|
34
34
|
buildGuardRegistryContext,
|
|
35
35
|
createDoctrineMap,
|
|
@@ -46,11 +46,11 @@ import {
|
|
|
46
46
|
sendCliCommandTelemetry,
|
|
47
47
|
sendNewProjectCompletedTelemetry,
|
|
48
48
|
writeDoctrineMap
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-4SZ4SEKT.js";
|
|
50
50
|
|
|
51
51
|
// src/index.ts
|
|
52
52
|
import { existsSync as existsSync29, mkdirSync as mkdirSync16, readdirSync as readdirSync9, readFileSync as readFileSync22, writeFileSync as writeFileSync19 } from "fs";
|
|
53
|
-
import { basename as basename3, dirname as
|
|
53
|
+
import { basename as basename3, dirname as dirname6, isAbsolute as isAbsolute3, join as join31, relative as relative7, resolve as resolve4 } from "path";
|
|
54
54
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
55
55
|
import { evaluateGuard, isV4 as isV49, validateEssence as validateEssence2 } from "@decantr/essence-spec";
|
|
56
56
|
import {
|
|
@@ -2754,7 +2754,7 @@ function writeBrownfieldIntelligenceArtifacts(input) {
|
|
|
2754
2754
|
|
|
2755
2755
|
// src/detect.ts
|
|
2756
2756
|
import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
|
|
2757
|
-
import { join as join12 } from "path";
|
|
2757
|
+
import { dirname as dirname2, join as join12 } from "path";
|
|
2758
2758
|
var RULE_FILES = [
|
|
2759
2759
|
"CLAUDE.md",
|
|
2760
2760
|
".claude/rules",
|
|
@@ -2766,6 +2766,34 @@ var RULE_FILES = [
|
|
|
2766
2766
|
".github/copilot-instructions.md",
|
|
2767
2767
|
".windsurfrules"
|
|
2768
2768
|
];
|
|
2769
|
+
function readPackageJson(dir) {
|
|
2770
|
+
const path = join12(dir, "package.json");
|
|
2771
|
+
if (!existsSync10(path)) return null;
|
|
2772
|
+
try {
|
|
2773
|
+
return JSON.parse(readFileSync9(path, "utf-8"));
|
|
2774
|
+
} catch {
|
|
2775
|
+
return null;
|
|
2776
|
+
}
|
|
2777
|
+
}
|
|
2778
|
+
function packageManagerFromName(name) {
|
|
2779
|
+
if (name === "pnpm" || name === "yarn" || name === "bun" || name === "npm") return name;
|
|
2780
|
+
return "unknown";
|
|
2781
|
+
}
|
|
2782
|
+
function detectPackageManager(projectRoot) {
|
|
2783
|
+
let current = projectRoot;
|
|
2784
|
+
while (true) {
|
|
2785
|
+
const pkg = readPackageJson(current);
|
|
2786
|
+
const declared = packageManagerFromName(pkg?.packageManager?.split("@")[0]);
|
|
2787
|
+
if (declared !== "unknown") return declared;
|
|
2788
|
+
if (existsSync10(join12(current, "pnpm-lock.yaml"))) return "pnpm";
|
|
2789
|
+
if (existsSync10(join12(current, "yarn.lock"))) return "yarn";
|
|
2790
|
+
if (existsSync10(join12(current, "bun.lockb"))) return "bun";
|
|
2791
|
+
if (existsSync10(join12(current, "package-lock.json"))) return "npm";
|
|
2792
|
+
const parent = dirname2(current);
|
|
2793
|
+
if (parent === current) return "unknown";
|
|
2794
|
+
current = parent;
|
|
2795
|
+
}
|
|
2796
|
+
}
|
|
2769
2797
|
function detectProject(projectRoot = process.cwd()) {
|
|
2770
2798
|
const result = {
|
|
2771
2799
|
framework: "unknown",
|
|
@@ -2782,15 +2810,7 @@ function detectProject(projectRoot = process.cwd()) {
|
|
|
2782
2810
|
result.existingRuleFiles.push(ruleFile);
|
|
2783
2811
|
}
|
|
2784
2812
|
}
|
|
2785
|
-
|
|
2786
|
-
result.packageManager = "pnpm";
|
|
2787
|
-
} else if (existsSync10(join12(projectRoot, "yarn.lock"))) {
|
|
2788
|
-
result.packageManager = "yarn";
|
|
2789
|
-
} else if (existsSync10(join12(projectRoot, "bun.lockb"))) {
|
|
2790
|
-
result.packageManager = "bun";
|
|
2791
|
-
} else if (existsSync10(join12(projectRoot, "package-lock.json"))) {
|
|
2792
|
-
result.packageManager = "npm";
|
|
2793
|
-
}
|
|
2813
|
+
result.packageManager = detectPackageManager(projectRoot);
|
|
2794
2814
|
result.hasTypeScript = existsSync10(join12(projectRoot, "tsconfig.json"));
|
|
2795
2815
|
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"));
|
|
2796
2816
|
if (existsSync10(join12(projectRoot, "next.config.js")) || existsSync10(join12(projectRoot, "next.config.ts")) || existsSync10(join12(projectRoot, "next.config.mjs"))) {
|
|
@@ -3195,7 +3215,7 @@ ${YELLOW2}Next step:${RESET2} Review ${BOLD}${reportDisplayPath}${RESET2}, then
|
|
|
3195
3215
|
|
|
3196
3216
|
// src/commands/ci.ts
|
|
3197
3217
|
import { existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync12, writeFileSync as writeFileSync10 } from "fs";
|
|
3198
|
-
import { dirname as
|
|
3218
|
+
import { dirname as dirname3, join as join16, relative as relative4, resolve } from "path";
|
|
3199
3219
|
|
|
3200
3220
|
// src/local-law.ts
|
|
3201
3221
|
import { execFileSync } from "child_process";
|
|
@@ -3732,7 +3752,7 @@ function parseProvider(value) {
|
|
|
3732
3752
|
if (value === "github" || value === "generic") return value;
|
|
3733
3753
|
throw new Error("Invalid --provider value. Use github or generic.");
|
|
3734
3754
|
}
|
|
3735
|
-
function
|
|
3755
|
+
function detectPackageManager2(root) {
|
|
3736
3756
|
const pkg = readJson(join16(root, "package.json"));
|
|
3737
3757
|
const declared = pkg?.packageManager?.split("@")[0];
|
|
3738
3758
|
if (declared === "pnpm" || declared === "npm" || declared === "yarn" || declared === "bun") {
|
|
@@ -3801,7 +3821,7 @@ function projectSlug(projectPath) {
|
|
|
3801
3821
|
}
|
|
3802
3822
|
function writeOutput(root, path, content) {
|
|
3803
3823
|
const absolute = resolve(root, path);
|
|
3804
|
-
mkdirSync9(
|
|
3824
|
+
mkdirSync9(dirname3(absolute), { recursive: true });
|
|
3805
3825
|
writeFileSync10(absolute, content, "utf-8");
|
|
3806
3826
|
}
|
|
3807
3827
|
function summarizeLocalLaw(projectRoot) {
|
|
@@ -3931,7 +3951,7 @@ function writeCiInit(root, options) {
|
|
|
3931
3951
|
}
|
|
3932
3952
|
const outputRoot = workspaceInfo.workspaceRoot;
|
|
3933
3953
|
const projectPath = options.project ?? (options.workspace || workspaceInfo.appRoot === workspaceInfo.workspaceRoot ? void 0 : relative4(workspaceInfo.workspaceRoot, workspaceInfo.appRoot).replace(/\\/g, "/"));
|
|
3934
|
-
const packageManager =
|
|
3954
|
+
const packageManager = detectPackageManager2(outputRoot);
|
|
3935
3955
|
const command = decantrCommand(packageManager);
|
|
3936
3956
|
const failOn = options.failOn ?? "error";
|
|
3937
3957
|
const provider = options.provider ?? "github";
|
|
@@ -4295,7 +4315,7 @@ function cmdCreate(type, name, projectRoot = process.cwd()) {
|
|
|
4295
4315
|
|
|
4296
4316
|
// src/commands/doctor.ts
|
|
4297
4317
|
import { existsSync as existsSync16, readdirSync as readdirSync6, readFileSync as readFileSync13 } from "fs";
|
|
4298
|
-
import { dirname as
|
|
4318
|
+
import { dirname as dirname4, join as join18, relative as relative5 } from "path";
|
|
4299
4319
|
import { fileURLToPath } from "url";
|
|
4300
4320
|
import { isV4 as isV44 } from "@decantr/essence-spec";
|
|
4301
4321
|
import { collectMissingPackManifestFiles } from "@decantr/verifier";
|
|
@@ -4319,16 +4339,16 @@ function isContractOnlyProject(projectRoot) {
|
|
|
4319
4339
|
return projectJson?.initialized?.adoptionMode === "contract-only";
|
|
4320
4340
|
}
|
|
4321
4341
|
function readCliPackageVersion() {
|
|
4322
|
-
const packagePath = join18(
|
|
4323
|
-
const srcPackagePath = join18(
|
|
4342
|
+
const packagePath = join18(dirname4(fileURLToPath(import.meta.url)), "..", "..", "package.json");
|
|
4343
|
+
const srcPackagePath = join18(dirname4(fileURLToPath(import.meta.url)), "..", "package.json");
|
|
4324
4344
|
const pkg = readJson2(packagePath) ?? readJson2(srcPackagePath);
|
|
4325
4345
|
return pkg?.version ?? "unknown";
|
|
4326
4346
|
}
|
|
4327
|
-
function
|
|
4347
|
+
function readPackageJson2(dir) {
|
|
4328
4348
|
return readJson2(join18(dir, "package.json"));
|
|
4329
4349
|
}
|
|
4330
|
-
function
|
|
4331
|
-
const pkg =
|
|
4350
|
+
function detectPackageManager3(root) {
|
|
4351
|
+
const pkg = readPackageJson2(root);
|
|
4332
4352
|
const declared = pkg?.packageManager?.split("@")[0];
|
|
4333
4353
|
if (declared === "pnpm" || declared === "npm" || declared === "yarn" || declared === "bun") {
|
|
4334
4354
|
return declared;
|
|
@@ -4340,11 +4360,11 @@ function detectPackageManager2(root) {
|
|
|
4340
4360
|
return "unknown";
|
|
4341
4361
|
}
|
|
4342
4362
|
function localCliDependency(root) {
|
|
4343
|
-
const pkg =
|
|
4363
|
+
const pkg = readPackageJson2(root);
|
|
4344
4364
|
return pkg?.devDependencies?.["@decantr/cli"] ?? pkg?.dependencies?.["@decantr/cli"] ?? null;
|
|
4345
4365
|
}
|
|
4346
4366
|
function hasWorkspaceMarker2(root) {
|
|
4347
|
-
const pkg =
|
|
4367
|
+
const pkg = readPackageJson2(root);
|
|
4348
4368
|
return Boolean(
|
|
4349
4369
|
existsSync16(join18(root, "pnpm-workspace.yaml")) || existsSync16(join18(root, "turbo.json")) || existsSync16(join18(root, "nx.json")) || pkg?.workspaces
|
|
4350
4370
|
);
|
|
@@ -4375,7 +4395,7 @@ function hasAnyFile(dir, names) {
|
|
|
4375
4395
|
return null;
|
|
4376
4396
|
}
|
|
4377
4397
|
function packageHasDependency(dir, names) {
|
|
4378
|
-
const pkg =
|
|
4398
|
+
const pkg = readPackageJson2(dir);
|
|
4379
4399
|
const deps = { ...pkg?.dependencies, ...pkg?.devDependencies };
|
|
4380
4400
|
return names.some((name) => Boolean(deps[name]));
|
|
4381
4401
|
}
|
|
@@ -4455,7 +4475,7 @@ function buildDoctorReport(root, args) {
|
|
|
4455
4475
|
const appRoot = workspaceMode ? workspaceRoot : workspaceInfo.appRoot;
|
|
4456
4476
|
const projectMissing = Boolean(projectArg && !existsSync16(appRoot));
|
|
4457
4477
|
const projectPath = appRoot === workspaceRoot ? null : rel(workspaceRoot, appRoot);
|
|
4458
|
-
const packageManager =
|
|
4478
|
+
const packageManager = detectPackageManager3(workspaceRoot);
|
|
4459
4479
|
const cliDependency = localCliDependency(workspaceRoot);
|
|
4460
4480
|
const detected = detectProject(appRoot);
|
|
4461
4481
|
const projectJson = readJson2(join18(appRoot, ".decantr", "project.json"));
|
|
@@ -4723,7 +4743,7 @@ async function cmdDoctor(args = ["doctor"], root = process.cwd()) {
|
|
|
4723
4743
|
|
|
4724
4744
|
// src/commands/export.ts
|
|
4725
4745
|
import { existsSync as existsSync17, mkdirSync as mkdirSync11, readFileSync as readFileSync14, writeFileSync as writeFileSync12 } from "fs";
|
|
4726
|
-
import { dirname as
|
|
4746
|
+
import { dirname as dirname5, isAbsolute, join as join19 } from "path";
|
|
4727
4747
|
var GREEN5 = "\x1B[32m";
|
|
4728
4748
|
var RED4 = "\x1B[31m";
|
|
4729
4749
|
var DIM5 = "\x1B[2m";
|
|
@@ -4977,7 +4997,7 @@ async function cmdExport(target, projectRoot, options = {}) {
|
|
|
4977
4997
|
}
|
|
4978
4998
|
}
|
|
4979
4999
|
function ensureDir(filePath) {
|
|
4980
|
-
const dir =
|
|
5000
|
+
const dir = dirname5(filePath);
|
|
4981
5001
|
if (!existsSync17(dir)) {
|
|
4982
5002
|
mkdirSync11(dir, { recursive: true });
|
|
4983
5003
|
}
|
|
@@ -5890,7 +5910,7 @@ async function cmdNewProject(projectName, options) {
|
|
|
5890
5910
|
)
|
|
5891
5911
|
);
|
|
5892
5912
|
}
|
|
5893
|
-
const packageManager =
|
|
5913
|
+
const packageManager = detectPackageManager4();
|
|
5894
5914
|
if (shouldBootstrapRuntime) {
|
|
5895
5915
|
console.log(heading("Installing dependencies..."));
|
|
5896
5916
|
try {
|
|
@@ -5966,7 +5986,7 @@ ${YELLOW6}Decantr init encountered issues. Run \`decantr init\` manually inside
|
|
|
5966
5986
|
});
|
|
5967
5987
|
}
|
|
5968
5988
|
}
|
|
5969
|
-
function
|
|
5989
|
+
function detectPackageManager4() {
|
|
5970
5990
|
if (existsSync21(join23(process.cwd(), "pnpm-lock.yaml")) || existsSync21(join23(process.cwd(), "pnpm-workspace.yaml"))) {
|
|
5971
5991
|
return "pnpm";
|
|
5972
5992
|
}
|
|
@@ -6365,6 +6385,7 @@ import { join as join27 } from "path";
|
|
|
6365
6385
|
import { isV4 as isV47 } from "@decantr/essence-spec";
|
|
6366
6386
|
var GREEN11 = "\x1B[32m";
|
|
6367
6387
|
var RED9 = "\x1B[31m";
|
|
6388
|
+
var YELLOW8 = "\x1B[33m";
|
|
6368
6389
|
var DIM11 = "\x1B[2m";
|
|
6369
6390
|
var RESET11 = "\x1B[0m";
|
|
6370
6391
|
function readV4Essence2(projectRoot) {
|
|
@@ -6403,6 +6424,27 @@ function readFlagValue2(args, name) {
|
|
|
6403
6424
|
}
|
|
6404
6425
|
return void 0;
|
|
6405
6426
|
}
|
|
6427
|
+
function resolveSectionAlias(sections, requestedSectionId) {
|
|
6428
|
+
const exact = sections.find((section) => section.id === requestedSectionId);
|
|
6429
|
+
if (exact) return { section: exact, resolvedFromAlias: false };
|
|
6430
|
+
const roleByAlias = {
|
|
6431
|
+
app: "primary",
|
|
6432
|
+
main: "primary",
|
|
6433
|
+
primary: "primary",
|
|
6434
|
+
public: "public",
|
|
6435
|
+
marketing: "public",
|
|
6436
|
+
auth: "gateway",
|
|
6437
|
+
gateway: "gateway",
|
|
6438
|
+
auxiliary: "auxiliary"
|
|
6439
|
+
};
|
|
6440
|
+
const desiredRole = roleByAlias[requestedSectionId.toLowerCase()];
|
|
6441
|
+
if (!desiredRole) return null;
|
|
6442
|
+
const roleMatches = sections.filter((section) => section.role === desiredRole);
|
|
6443
|
+
if (roleMatches.length === 1) return { section: roleMatches[0], resolvedFromAlias: true };
|
|
6444
|
+
if (roleMatches.length > 1) return null;
|
|
6445
|
+
const observedMatch = sections.find((section) => section.id === `observed-${desiredRole}`);
|
|
6446
|
+
return observedMatch ? { section: observedMatch, resolvedFromAlias: true } : null;
|
|
6447
|
+
}
|
|
6406
6448
|
function recomputeGlobalFeatures(essence) {
|
|
6407
6449
|
const all = /* @__PURE__ */ new Set();
|
|
6408
6450
|
for (const section of essence.blueprint.sections || []) {
|
|
@@ -6467,24 +6509,31 @@ async function cmdRemovePage(path, args, projectRoot = process.cwd()) {
|
|
|
6467
6509
|
if (!loaded) return;
|
|
6468
6510
|
const { essence, essencePath } = loaded;
|
|
6469
6511
|
const sections = essence.blueprint.sections;
|
|
6470
|
-
const
|
|
6471
|
-
if (!
|
|
6512
|
+
const resolved = resolveSectionAlias(sections, sectionId);
|
|
6513
|
+
if (!resolved) {
|
|
6472
6514
|
console.error(`${RED9}Section "${sectionId}" not found.${RESET11}`);
|
|
6473
6515
|
console.error(`${DIM11}Available sections: ${sections.map((s) => s.id).join(", ")}${RESET11}`);
|
|
6474
6516
|
process.exitCode = 1;
|
|
6475
6517
|
return;
|
|
6476
6518
|
}
|
|
6519
|
+
const { section } = resolved;
|
|
6520
|
+
const resolvedSectionId = section.id;
|
|
6477
6521
|
const pageIdx = section.pages.findIndex((p) => p.id === pageId);
|
|
6478
6522
|
if (pageIdx === -1) {
|
|
6479
|
-
console.error(`${RED9}Page "${pageId}" not found in section "${
|
|
6523
|
+
console.error(`${RED9}Page "${pageId}" not found in section "${resolvedSectionId}".${RESET11}`);
|
|
6480
6524
|
console.error(`${DIM11}Available pages: ${section.pages.map((p) => p.id).join(", ")}${RESET11}`);
|
|
6481
6525
|
process.exitCode = 1;
|
|
6482
6526
|
return;
|
|
6483
6527
|
}
|
|
6484
6528
|
section.pages.splice(pageIdx, 1);
|
|
6485
|
-
removeRoutes(essence,
|
|
6529
|
+
removeRoutes(essence, resolvedSectionId, pageId);
|
|
6486
6530
|
writeEssence2(essencePath, essence);
|
|
6487
|
-
|
|
6531
|
+
if (resolved.resolvedFromAlias) {
|
|
6532
|
+
console.log(
|
|
6533
|
+
`${YELLOW8}Resolved section alias "${sectionId}" to "${resolvedSectionId}".${RESET11}`
|
|
6534
|
+
);
|
|
6535
|
+
}
|
|
6536
|
+
console.log(`${GREEN11}Removed page "${pageId}" from section "${resolvedSectionId}".${RESET11}`);
|
|
6488
6537
|
const registryClient = new RegistryClient({
|
|
6489
6538
|
cacheDir: join27(projectRoot, ".decantr", "cache")
|
|
6490
6539
|
});
|
|
@@ -6504,13 +6553,18 @@ async function cmdRemoveFeature(feature, args, projectRoot = process.cwd()) {
|
|
|
6504
6553
|
sectionId = readFlagValue2(args, "section");
|
|
6505
6554
|
if (sectionId) {
|
|
6506
6555
|
const sections = essence.blueprint.sections;
|
|
6507
|
-
const
|
|
6508
|
-
if (!
|
|
6556
|
+
const resolved = resolveSectionAlias(sections, sectionId);
|
|
6557
|
+
if (!resolved) {
|
|
6509
6558
|
console.error(`${RED9}Section "${sectionId}" not found.${RESET11}`);
|
|
6510
6559
|
console.error(`${DIM11}Available sections: ${sections.map((s) => s.id).join(", ")}${RESET11}`);
|
|
6511
6560
|
process.exitCode = 1;
|
|
6512
6561
|
return;
|
|
6513
6562
|
}
|
|
6563
|
+
const { section } = resolved;
|
|
6564
|
+
if (resolved.resolvedFromAlias) {
|
|
6565
|
+
console.log(`${YELLOW8}Resolved section alias "${sectionId}" to "${section.id}".${RESET11}`);
|
|
6566
|
+
}
|
|
6567
|
+
sectionId = section.id;
|
|
6514
6568
|
const fIdx = section.features.indexOf(feature);
|
|
6515
6569
|
if (fIdx !== -1) {
|
|
6516
6570
|
section.features.splice(fIdx, 1);
|
|
@@ -6535,7 +6589,7 @@ import { existsSync as existsSync26, readFileSync as readFileSync19, writeFileSy
|
|
|
6535
6589
|
import { join as join28 } from "path";
|
|
6536
6590
|
var GREEN12 = "\x1B[32m";
|
|
6537
6591
|
var RED10 = "\x1B[31m";
|
|
6538
|
-
var
|
|
6592
|
+
var YELLOW9 = "\x1B[33m";
|
|
6539
6593
|
var RESET12 = "\x1B[0m";
|
|
6540
6594
|
var DIM12 = "\x1B[2m";
|
|
6541
6595
|
var BOLD6 = "\x1B[1m";
|
|
@@ -6576,7 +6630,7 @@ ${BOLD6}Unresolved Drift Entries (${unresolved.length})${RESET12}
|
|
|
6576
6630
|
`);
|
|
6577
6631
|
for (let i = 0; i < unresolved.length; i++) {
|
|
6578
6632
|
const entry = unresolved[i];
|
|
6579
|
-
const severityColor = entry.severity === "error" ? RED10 :
|
|
6633
|
+
const severityColor = entry.severity === "error" ? RED10 : YELLOW9;
|
|
6580
6634
|
const icon = entry.severity === "error" ? "x" : "!";
|
|
6581
6635
|
console.log(
|
|
6582
6636
|
` ${severityColor}${icon}${RESET12} ${BOLD6}#${i + 1}${RESET12} [${entry.rule}] ${entry.message}`
|
|
@@ -6860,7 +6914,7 @@ import { join as join29 } from "path";
|
|
|
6860
6914
|
import { isV4 as isV48 } from "@decantr/essence-spec";
|
|
6861
6915
|
var GREEN14 = "\x1B[32m";
|
|
6862
6916
|
var RED11 = "\x1B[31m";
|
|
6863
|
-
var
|
|
6917
|
+
var YELLOW10 = "\x1B[33m";
|
|
6864
6918
|
var DIM14 = "\x1B[2m";
|
|
6865
6919
|
var RESET14 = "\x1B[0m";
|
|
6866
6920
|
var VALID_THEME_SHAPES = ["sharp", "rounded", "pill"];
|
|
@@ -6955,7 +7009,7 @@ async function cmdThemeSwitch(themeName, args, projectRoot = process.cwd()) {
|
|
|
6955
7009
|
console.log(
|
|
6956
7010
|
`${GREEN14}Derived files refreshed (tokens.css, treatments.css, all contexts).${RESET14}`
|
|
6957
7011
|
);
|
|
6958
|
-
console.log(`${
|
|
7012
|
+
console.log(`${YELLOW10}Guard will flag code using old tokens. Run \`decantr check\`.${RESET14}`);
|
|
6959
7013
|
}
|
|
6960
7014
|
|
|
6961
7015
|
// src/prompts.ts
|
|
@@ -6964,7 +7018,7 @@ var BOLD8 = "\x1B[1m";
|
|
|
6964
7018
|
var DIM15 = "\x1B[2m";
|
|
6965
7019
|
var RESET15 = "\x1B[0m";
|
|
6966
7020
|
var GREEN15 = "\x1B[32m";
|
|
6967
|
-
var
|
|
7021
|
+
var YELLOW11 = "\x1B[33m";
|
|
6968
7022
|
var CYAN8 = "\x1B[36m";
|
|
6969
7023
|
function ask(question, defaultValue) {
|
|
6970
7024
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -7004,7 +7058,7 @@ async function confirm(question, defaultYes = true) {
|
|
|
7004
7058
|
}
|
|
7005
7059
|
function warn(message) {
|
|
7006
7060
|
console.log(`
|
|
7007
|
-
${
|
|
7061
|
+
${YELLOW11} Warning: ${message}${RESET15}`);
|
|
7008
7062
|
}
|
|
7009
7063
|
function showDetection(detected) {
|
|
7010
7064
|
console.log(`
|
|
@@ -7023,7 +7077,7 @@ ${CYAN8}Detected project configuration:${RESET15}`);
|
|
|
7023
7077
|
console.log(` Tailwind CSS: ${GREEN15}yes${RESET15}`);
|
|
7024
7078
|
}
|
|
7025
7079
|
if (detected.existingEssence) {
|
|
7026
|
-
console.log(` Existing essence: ${
|
|
7080
|
+
console.log(` Existing essence: ${YELLOW11}yes${RESET15}`);
|
|
7027
7081
|
}
|
|
7028
7082
|
}
|
|
7029
7083
|
async function runInteractivePrompts(detected, archetypes, blueprints, themes, workflowSeed) {
|
|
@@ -7425,7 +7479,7 @@ var RESET16 = "\x1B[0m";
|
|
|
7425
7479
|
var RED12 = "\x1B[31m";
|
|
7426
7480
|
var GREEN16 = "\x1B[32m";
|
|
7427
7481
|
var CYAN9 = "\x1B[36m";
|
|
7428
|
-
var
|
|
7482
|
+
var YELLOW12 = "\x1B[33m";
|
|
7429
7483
|
function heading2(text) {
|
|
7430
7484
|
return `
|
|
7431
7485
|
${BOLD9}${text}${RESET16}
|
|
@@ -8207,7 +8261,7 @@ async function compileHostedExecutionPackBundle(essencePath, namespace) {
|
|
|
8207
8261
|
}
|
|
8208
8262
|
const essence = JSON.parse(readFileSync22(resolvedPath, "utf-8"));
|
|
8209
8263
|
const bundle = await client.compileExecutionPacks(essence, namespace ? { namespace } : void 0);
|
|
8210
|
-
const contextDir = join31(
|
|
8264
|
+
const contextDir = join31(dirname6(resolvedPath), ".decantr", "context");
|
|
8211
8265
|
return { resolvedPath, bundle, contextDir };
|
|
8212
8266
|
}
|
|
8213
8267
|
function writeHostedExecutionPackContextArtifacts(contextDir, bundle) {
|
|
@@ -8251,7 +8305,7 @@ async function printHostedSelectedExecutionPack(packType, id, essencePath, names
|
|
|
8251
8305
|
);
|
|
8252
8306
|
let writtenContextDir = null;
|
|
8253
8307
|
if (writeContext) {
|
|
8254
|
-
const contextDir = join31(
|
|
8308
|
+
const contextDir = join31(dirname6(resolvedPath), ".decantr", "context");
|
|
8255
8309
|
mkdirSync16(contextDir, { recursive: true });
|
|
8256
8310
|
writeFileSync19(
|
|
8257
8311
|
join31(contextDir, "pack-manifest.json"),
|
|
@@ -8297,7 +8351,7 @@ async function printHostedExecutionPackManifest(essencePath, namespace, jsonOutp
|
|
|
8297
8351
|
);
|
|
8298
8352
|
let writtenContextDir = null;
|
|
8299
8353
|
if (writeContext) {
|
|
8300
|
-
const contextDir = join31(
|
|
8354
|
+
const contextDir = join31(dirname6(resolvedPath), ".decantr", "context");
|
|
8301
8355
|
mkdirSync16(contextDir, { recursive: true });
|
|
8302
8356
|
writeFileSync19(join31(contextDir, "pack-manifest.json"), JSON.stringify(manifest, null, 2) + "\n");
|
|
8303
8357
|
writtenContextDir = contextDir;
|
|
@@ -8468,7 +8522,7 @@ function printBlueprintPortfolioNotice(blueprint) {
|
|
|
8468
8522
|
if (!portfolio) return;
|
|
8469
8523
|
if (portfolio.visibility === "hidden" || portfolio.maturity === "fold-candidate") {
|
|
8470
8524
|
console.log(
|
|
8471
|
-
`${
|
|
8525
|
+
`${YELLOW12} Warning:${RESET16} blueprint "${blueprint.id}" is folded out of public browsing.`
|
|
8472
8526
|
);
|
|
8473
8527
|
if (portfolio.recommended_alternative) {
|
|
8474
8528
|
console.log(
|
|
@@ -8481,7 +8535,7 @@ function printBlueprintPortfolioNotice(blueprint) {
|
|
|
8481
8535
|
}
|
|
8482
8536
|
if (portfolio.visibility === "labs") {
|
|
8483
8537
|
console.log(
|
|
8484
|
-
`${
|
|
8538
|
+
`${YELLOW12} Note:${RESET16} blueprint "${blueprint.id}" is a Labs blueprint; direct scaffolding is supported, but it is not a default recommendation yet.`
|
|
8485
8539
|
);
|
|
8486
8540
|
}
|
|
8487
8541
|
}
|
|
@@ -8668,7 +8722,10 @@ async function cmdSuggest(query, options = {}) {
|
|
|
8668
8722
|
`Pattern suggestions for "${query}"${contextBits.length > 0 ? ` (${contextBits.join(", ")})` : ""}`
|
|
8669
8723
|
)
|
|
8670
8724
|
);
|
|
8671
|
-
const localMatches = localPatternMatches(
|
|
8725
|
+
const localMatches = localPatternMatches(
|
|
8726
|
+
options.projectRoot,
|
|
8727
|
+
[query, code].filter(Boolean).join("\n")
|
|
8728
|
+
);
|
|
8672
8729
|
if (localMatches.length > 0) {
|
|
8673
8730
|
console.log(`${BOLD9}Project-owned local law:${RESET16}`);
|
|
8674
8731
|
for (const match of localMatches) {
|
|
@@ -8770,7 +8827,7 @@ async function cmdValidate(path) {
|
|
|
8770
8827
|
console.log(heading2("Guard violations:"));
|
|
8771
8828
|
for (const v of violations) {
|
|
8772
8829
|
const vr = v;
|
|
8773
|
-
console.log(` ${
|
|
8830
|
+
console.log(` ${YELLOW12}[${vr.rule}]${RESET16} ${vr.message}`);
|
|
8774
8831
|
if (vr.suggestion) {
|
|
8775
8832
|
console.log(` ${DIM16}Suggestion: ${vr.suggestion}${RESET16}`);
|
|
8776
8833
|
}
|
|
@@ -8876,7 +8933,7 @@ ${CYAN9}Telemetry enabled.${RESET16} Decantr will send privacy-filtered CLI prod
|
|
|
8876
8933
|
console.log(`${DIM16}Set "telemetry": false in .decantr/project.json to opt out.${RESET16}`);
|
|
8877
8934
|
}
|
|
8878
8935
|
function readCliPackageVersion2() {
|
|
8879
|
-
const here =
|
|
8936
|
+
const here = dirname6(fileURLToPath3(import.meta.url));
|
|
8880
8937
|
const candidates = [join31(here, "..", "package.json"), join31(here, "..", "..", "package.json")];
|
|
8881
8938
|
for (const candidate of candidates) {
|
|
8882
8939
|
try {
|
|
@@ -9104,7 +9161,7 @@ async function cmdInit(args) {
|
|
|
9104
9161
|
console.log(dim3(" Found .decantr/init-seed.json brownfield guidance."));
|
|
9105
9162
|
}
|
|
9106
9163
|
if (detected.existingEssence && !args.existing) {
|
|
9107
|
-
console.log(`${
|
|
9164
|
+
console.log(`${YELLOW12}Warning: decantr.essence.json already exists.${RESET16}`);
|
|
9108
9165
|
const overwrite = await confirm("Overwrite existing configuration?", false);
|
|
9109
9166
|
if (!overwrite) {
|
|
9110
9167
|
console.log(dim3("Cancelled."));
|
|
@@ -9207,7 +9264,7 @@ async function cmdInit(args) {
|
|
|
9207
9264
|
} else if (shouldUseRegistry && !apiAvailable) {
|
|
9208
9265
|
if (!args.blueprint) {
|
|
9209
9266
|
console.log(`
|
|
9210
|
-
${
|
|
9267
|
+
${YELLOW12}You're offline. Scaffolding minimal Decantr project.${RESET16}`);
|
|
9211
9268
|
console.log(
|
|
9212
9269
|
dim3("Run `decantr sync` or `decantr upgrade` when online to pull full registry content.\n")
|
|
9213
9270
|
);
|
|
@@ -9256,7 +9313,7 @@ ${YELLOW11}You're offline. Scaffolding minimal Decantr project.${RESET16}`);
|
|
|
9256
9313
|
return;
|
|
9257
9314
|
}
|
|
9258
9315
|
console.log(`
|
|
9259
|
-
${
|
|
9316
|
+
${YELLOW12}You're offline. Scaffolding Decantr default.${RESET16}`);
|
|
9260
9317
|
console.log(dim3("Run `decantr upgrade` when online, or visit decantr.ai/registry\n"));
|
|
9261
9318
|
selectedBlueprint = "default";
|
|
9262
9319
|
} else if (shouldUseRegistry) {
|
|
@@ -9438,7 +9495,7 @@ ${YELLOW11}You're offline. Scaffolding Decantr default.${RESET16}`);
|
|
|
9438
9495
|
return;
|
|
9439
9496
|
}
|
|
9440
9497
|
console.log(
|
|
9441
|
-
`${
|
|
9498
|
+
`${YELLOW12} Warning: Could not fetch blueprint "${options.blueprint}". Using defaults.${RESET16}`
|
|
9442
9499
|
);
|
|
9443
9500
|
}
|
|
9444
9501
|
} else if (shouldUseRegistry && options.archetype) {
|
|
@@ -9453,7 +9510,7 @@ ${YELLOW11}You're offline. Scaffolding Decantr default.${RESET16}`);
|
|
|
9453
9510
|
return;
|
|
9454
9511
|
}
|
|
9455
9512
|
console.log(
|
|
9456
|
-
`${
|
|
9513
|
+
`${YELLOW12} Warning: Could not fetch archetype "${options.archetype}". Using defaults.${RESET16}`
|
|
9457
9514
|
);
|
|
9458
9515
|
}
|
|
9459
9516
|
}
|
|
@@ -9470,7 +9527,7 @@ ${YELLOW11}You're offline. Scaffolding Decantr default.${RESET16}`);
|
|
|
9470
9527
|
return;
|
|
9471
9528
|
}
|
|
9472
9529
|
console.log(
|
|
9473
|
-
`${
|
|
9530
|
+
`${YELLOW12} Warning: Could not fetch theme "${options.theme}". Using defaults.${RESET16}`
|
|
9474
9531
|
);
|
|
9475
9532
|
}
|
|
9476
9533
|
}
|
|
@@ -9675,7 +9732,7 @@ async function cmdStatus(projectRoot = process.cwd()) {
|
|
|
9675
9732
|
` Guard: ${v4.meta.guard.mode} (DNA: ${v4.meta.guard.dna_enforcement}, Blueprint: ${v4.meta.guard.blueprint_enforcement})`
|
|
9676
9733
|
);
|
|
9677
9734
|
} else {
|
|
9678
|
-
console.log(` ${
|
|
9735
|
+
console.log(` ${YELLOW12}Run \`decantr migrate --to v4\` to upgrade this project.${RESET16}`);
|
|
9679
9736
|
}
|
|
9680
9737
|
} catch (e) {
|
|
9681
9738
|
console.log(` ${RED12}Error reading essence: ${e.message}${RESET16}`);
|
|
@@ -9688,15 +9745,15 @@ async function cmdStatus(projectRoot = process.cwd()) {
|
|
|
9688
9745
|
const syncStatus = projectJson.sync?.status || "unknown";
|
|
9689
9746
|
const lastSync = projectJson.sync?.lastSync || "never";
|
|
9690
9747
|
const source = projectJson.sync?.registrySource || "unknown";
|
|
9691
|
-
const statusColor = syncStatus === "synced" ? GREEN16 :
|
|
9748
|
+
const statusColor = syncStatus === "synced" ? GREEN16 : YELLOW12;
|
|
9692
9749
|
console.log(` Status: ${statusColor}${syncStatus}${RESET16}`);
|
|
9693
9750
|
console.log(` Last sync: ${dim3(lastSync)}`);
|
|
9694
9751
|
console.log(` Source: ${dim3(source)}`);
|
|
9695
9752
|
} catch {
|
|
9696
|
-
console.log(` ${
|
|
9753
|
+
console.log(` ${YELLOW12}Could not read project.json${RESET16}`);
|
|
9697
9754
|
}
|
|
9698
9755
|
} else {
|
|
9699
|
-
console.log(` ${
|
|
9756
|
+
console.log(` ${YELLOW12}No .decantr/project.json found${RESET16}`);
|
|
9700
9757
|
console.log(dim3(' Run "decantr init" to create project files.'));
|
|
9701
9758
|
}
|
|
9702
9759
|
}
|
|
@@ -9709,12 +9766,12 @@ async function cmdSync() {
|
|
|
9709
9766
|
console.log(success3("Sync completed successfully."));
|
|
9710
9767
|
console.log(` Synced: ${result.synced.join(", ")}`);
|
|
9711
9768
|
if (result.failed.length > 0) {
|
|
9712
|
-
console.log(` ${
|
|
9769
|
+
console.log(` ${YELLOW12}Failed: ${result.failed.join(", ")}${RESET16}`);
|
|
9713
9770
|
}
|
|
9714
9771
|
} else {
|
|
9715
|
-
console.log(`${
|
|
9772
|
+
console.log(`${YELLOW12}Could not sync: API unavailable${RESET16}`);
|
|
9716
9773
|
if (result.failed.length > 0) {
|
|
9717
|
-
console.log(` ${
|
|
9774
|
+
console.log(` ${YELLOW12}Failed: ${result.failed.join(", ")}${RESET16}`);
|
|
9718
9775
|
}
|
|
9719
9776
|
}
|
|
9720
9777
|
}
|
|
@@ -9724,7 +9781,7 @@ function printVerificationFindings(findings) {
|
|
|
9724
9781
|
return;
|
|
9725
9782
|
}
|
|
9726
9783
|
for (const finding of findings) {
|
|
9727
|
-
const color = finding.severity === "error" ? RED12 : finding.severity === "warn" ?
|
|
9784
|
+
const color = finding.severity === "error" ? RED12 : finding.severity === "warn" ? YELLOW12 : CYAN9;
|
|
9728
9785
|
console.log(
|
|
9729
9786
|
` ${color}[${finding.severity.toUpperCase()}]${RESET16} ${finding.category}: ${finding.message}`
|
|
9730
9787
|
);
|
|
@@ -10231,16 +10288,21 @@ async function cmdSetupWorkflow(args) {
|
|
|
10231
10288
|
console.log(` Detected: ${formatDetection(detected)}`);
|
|
10232
10289
|
console.log("");
|
|
10233
10290
|
if (detected.existingEssence) {
|
|
10291
|
+
const hasLocalPatterns = existsSync29(localPatternsPath(workspaceInfo.appRoot));
|
|
10292
|
+
const hasLocalRules = existsSync29(localRulesPath(workspaceInfo.appRoot));
|
|
10293
|
+
const verifyCommand = hasLocalPatterns || hasLocalRules ? "decantr verify --brownfield --local-patterns" : "decantr verify --brownfield";
|
|
10234
10294
|
console.log(`${BOLD9}Recommended path:${RESET16} maintain an attached Decantr project`);
|
|
10235
10295
|
console.log(
|
|
10236
10296
|
` ${cyan3(withProject('decantr task <route> "<change>"', projectArg))} Prepare LLM context before edits`
|
|
10237
10297
|
);
|
|
10238
10298
|
console.log(
|
|
10239
|
-
` ${cyan3(withProject(
|
|
10240
|
-
);
|
|
10241
|
-
console.log(
|
|
10242
|
-
` ${cyan3(withProject("decantr codify --from-audit", projectArg))} Propose project-owned local law`
|
|
10299
|
+
` ${cyan3(withProject(verifyCommand, projectArg))} Run local health and drift checks`
|
|
10243
10300
|
);
|
|
10301
|
+
if (!hasLocalPatterns || !hasLocalRules) {
|
|
10302
|
+
console.log(
|
|
10303
|
+
` ${cyan3(withProject("decantr codify --from-audit", projectArg))} Propose project-owned local law`
|
|
10304
|
+
);
|
|
10305
|
+
}
|
|
10244
10306
|
return;
|
|
10245
10307
|
}
|
|
10246
10308
|
if (hasFootprint) {
|
|
@@ -10365,7 +10427,7 @@ async function cmdAdoptWorkflow(args) {
|
|
|
10365
10427
|
)
|
|
10366
10428
|
);
|
|
10367
10429
|
} catch (e) {
|
|
10368
|
-
console.log(`${
|
|
10430
|
+
console.log(`${YELLOW12}Pack hydration skipped:${RESET16} ${e.message}`);
|
|
10369
10431
|
console.log(
|
|
10370
10432
|
dim3(
|
|
10371
10433
|
`Run ${compilePacksCommandForProject(projectArg)} after adoption if you want hosted page/review packs.`
|
|
@@ -10376,7 +10438,7 @@ async function cmdAdoptWorkflow(args) {
|
|
|
10376
10438
|
console.log(dim3("Skipping hosted pack hydration in offline mode."));
|
|
10377
10439
|
}
|
|
10378
10440
|
if (runVerify) {
|
|
10379
|
-
const { cmdHealth } = await import("./health-
|
|
10441
|
+
const { cmdHealth } = await import("./health-VAYRQVTF.js");
|
|
10380
10442
|
await cmdHealth(projectRoot, {
|
|
10381
10443
|
browser: runBrowser,
|
|
10382
10444
|
browserBaseUrl: baseUrl,
|
|
@@ -10447,7 +10509,7 @@ async function cmdVerifyWorkflow(args) {
|
|
|
10447
10509
|
return;
|
|
10448
10510
|
}
|
|
10449
10511
|
if (workspaceMode) {
|
|
10450
|
-
const { cmdWorkspace } = await import("./workspace-
|
|
10512
|
+
const { cmdWorkspace } = await import("./workspace-PBO3BJRL.js");
|
|
10451
10513
|
await cmdWorkspace(process.cwd(), ["workspace", "health", ...withoutWorkflowOnlyFlags(args)]);
|
|
10452
10514
|
return;
|
|
10453
10515
|
}
|
|
@@ -10480,7 +10542,7 @@ async function cmdVerifyWorkflow(args) {
|
|
|
10480
10542
|
}
|
|
10481
10543
|
let guardExitCode;
|
|
10482
10544
|
if (brownfield) {
|
|
10483
|
-
const { cmdHeal, collectCheckIssues } = await import("./heal-
|
|
10545
|
+
const { cmdHeal, collectCheckIssues } = await import("./heal-2UCSPRTK.js");
|
|
10484
10546
|
if (quietOutput) {
|
|
10485
10547
|
const result = collectCheckIssues(workspaceInfo.appRoot, { brownfield: true });
|
|
10486
10548
|
guardExitCode = result.issues.some((issue) => issue.type === "error") ? 1 : void 0;
|
|
@@ -10490,7 +10552,7 @@ async function cmdVerifyWorkflow(args) {
|
|
|
10490
10552
|
process.exitCode = void 0;
|
|
10491
10553
|
}
|
|
10492
10554
|
}
|
|
10493
|
-
const { cmdHealth, parseHealthArgs } = await import("./health-
|
|
10555
|
+
const { cmdHealth, parseHealthArgs } = await import("./health-VAYRQVTF.js");
|
|
10494
10556
|
await cmdHealth(workspaceInfo.appRoot, parseHealthArgs(healthArgs));
|
|
10495
10557
|
if (localPatterns) {
|
|
10496
10558
|
const validation = validateLocalLaw(workspaceInfo.appRoot);
|
|
@@ -10498,7 +10560,7 @@ async function cmdVerifyWorkflow(args) {
|
|
|
10498
10560
|
if (!quietOutput) {
|
|
10499
10561
|
console.log("");
|
|
10500
10562
|
console.log(
|
|
10501
|
-
`${
|
|
10563
|
+
`${YELLOW12}Local pattern pack missing.${RESET16} Run ${cyan3(withProject("decantr codify --from-audit", projectArg))}, review the proposal, then run ${cyan3(withProject("decantr codify --accept", projectArg))}.`
|
|
10502
10564
|
);
|
|
10503
10565
|
}
|
|
10504
10566
|
process.exitCode = process.exitCode || 1;
|
|
@@ -10514,11 +10576,11 @@ async function cmdVerifyWorkflow(args) {
|
|
|
10514
10576
|
console.log(`${GREEN16}Local rule manifest found:${RESET16} ${validation.rulesPath}`);
|
|
10515
10577
|
} else {
|
|
10516
10578
|
console.log(
|
|
10517
|
-
`${
|
|
10579
|
+
`${YELLOW12}Local rule manifest missing.${RESET16} Run ${cyan3("decantr codify --from-audit")} to propose .decantr/rules.json.`
|
|
10518
10580
|
);
|
|
10519
10581
|
}
|
|
10520
10582
|
for (const warning of validation.warnings.slice(0, 8)) {
|
|
10521
|
-
console.log(`${
|
|
10583
|
+
console.log(`${YELLOW12}warn${RESET16} ${warning}`);
|
|
10522
10584
|
}
|
|
10523
10585
|
if (validation.findings.length > 0) {
|
|
10524
10586
|
console.log("");
|
|
@@ -10671,7 +10733,7 @@ async function cmdTaskWorkflow(args) {
|
|
|
10671
10733
|
console.log("");
|
|
10672
10734
|
console.log(`${BOLD9}Project-owned local law:${RESET16}`);
|
|
10673
10735
|
console.log(
|
|
10674
|
-
` ${
|
|
10736
|
+
` ${YELLOW12}Not codified yet.${RESET16} Run ${cyan3(withProject("decantr codify --from-audit", projectArg))} after adoption.`
|
|
10675
10737
|
);
|
|
10676
10738
|
}
|
|
10677
10739
|
if (context.changedFiles.length > 0) {
|
|
@@ -11316,7 +11378,7 @@ async function main() {
|
|
|
11316
11378
|
}
|
|
11317
11379
|
if (command === "--version" || command === "-v" || command === "version") {
|
|
11318
11380
|
try {
|
|
11319
|
-
const here =
|
|
11381
|
+
const here = dirname6(fileURLToPath3(import.meta.url));
|
|
11320
11382
|
const candidates = [join31(here, "..", "package.json"), join31(here, "..", "..", "package.json")];
|
|
11321
11383
|
for (const candidate of candidates) {
|
|
11322
11384
|
if (existsSync29(candidate)) {
|
|
@@ -11458,7 +11520,7 @@ async function main() {
|
|
|
11458
11520
|
break;
|
|
11459
11521
|
}
|
|
11460
11522
|
case "upgrade": {
|
|
11461
|
-
const { cmdUpgrade } = await import("./upgrade-
|
|
11523
|
+
const { cmdUpgrade } = await import("./upgrade-7ZYWR2GH.js");
|
|
11462
11524
|
const { flags } = parseLooseArgs(args);
|
|
11463
11525
|
const workspaceInfo = resolveWorkflowProject(flags, "upgrade");
|
|
11464
11526
|
if (!workspaceInfo) break;
|
|
@@ -11470,10 +11532,10 @@ async function main() {
|
|
|
11470
11532
|
case "heal": {
|
|
11471
11533
|
if (command === "heal") {
|
|
11472
11534
|
console.log(
|
|
11473
|
-
`${
|
|
11535
|
+
`${YELLOW12}Note: \`decantr heal\` is deprecated. Use \`decantr check\` instead.${RESET16}`
|
|
11474
11536
|
);
|
|
11475
11537
|
}
|
|
11476
|
-
const { cmdHeal } = await import("./heal-
|
|
11538
|
+
const { cmdHeal } = await import("./heal-2UCSPRTK.js");
|
|
11477
11539
|
const { flags } = parseLooseArgs(args);
|
|
11478
11540
|
const workspaceInfo = resolveWorkflowProject(flags, "check");
|
|
11479
11541
|
if (!workspaceInfo) break;
|
|
@@ -11498,7 +11560,7 @@ async function main() {
|
|
|
11498
11560
|
const { flags } = parseLooseArgs(args);
|
|
11499
11561
|
const workspaceInfo = resolveWorkflowProject(flags, "health");
|
|
11500
11562
|
if (!workspaceInfo) break;
|
|
11501
|
-
const { cmdHealth, parseHealthArgs } = await import("./health-
|
|
11563
|
+
const { cmdHealth, parseHealthArgs } = await import("./health-VAYRQVTF.js");
|
|
11502
11564
|
await cmdHealth(workspaceInfo.appRoot, parseHealthArgs(stripProjectArgs(args)));
|
|
11503
11565
|
} catch (e) {
|
|
11504
11566
|
console.error(error2(e.message));
|
|
@@ -11526,7 +11588,7 @@ async function main() {
|
|
|
11526
11588
|
cmdStudioHelp();
|
|
11527
11589
|
break;
|
|
11528
11590
|
}
|
|
11529
|
-
const { cmdStudio, parseStudioArgs } = await import("./studio-
|
|
11591
|
+
const { cmdStudio, parseStudioArgs } = await import("./studio-WPETOZRW.js");
|
|
11530
11592
|
await cmdStudio(process.cwd(), parseStudioArgs(args));
|
|
11531
11593
|
} catch (e) {
|
|
11532
11594
|
console.error(error2(e.message));
|
|
@@ -11540,7 +11602,7 @@ async function main() {
|
|
|
11540
11602
|
cmdWorkspaceHelp();
|
|
11541
11603
|
break;
|
|
11542
11604
|
}
|
|
11543
|
-
const { cmdWorkspace } = await import("./workspace-
|
|
11605
|
+
const { cmdWorkspace } = await import("./workspace-PBO3BJRL.js");
|
|
11544
11606
|
await cmdWorkspace(process.cwd(), args);
|
|
11545
11607
|
} catch (e) {
|
|
11546
11608
|
console.error(error2(e.message));
|
|
@@ -277,7 +277,15 @@ async function syncRegistry(cacheDir, apiUrl = DEFAULT_API_URL) {
|
|
|
277
277
|
}
|
|
278
278
|
|
|
279
279
|
// src/scaffold.ts
|
|
280
|
-
import {
|
|
280
|
+
import {
|
|
281
|
+
appendFileSync,
|
|
282
|
+
existsSync as existsSync2,
|
|
283
|
+
mkdirSync as mkdirSync2,
|
|
284
|
+
readdirSync as readdirSync2,
|
|
285
|
+
readFileSync as readFileSync2,
|
|
286
|
+
rmSync,
|
|
287
|
+
writeFileSync as writeFileSync2
|
|
288
|
+
} from "fs";
|
|
281
289
|
import { dirname, join as join2 } from "path";
|
|
282
290
|
import { fileURLToPath } from "url";
|
|
283
291
|
import { compileExecutionPackBundle } from "@decantr/core";
|
|
@@ -4504,6 +4512,24 @@ function writeExecutionPackArtifacts(basePathWithoutExtension, pack) {
|
|
|
4504
4512
|
writeFileSync2(jsonPath, JSON.stringify(pack, null, 2) + "\n");
|
|
4505
4513
|
return markdownPath;
|
|
4506
4514
|
}
|
|
4515
|
+
function isManagedExecutionPackArtifact(fileName) {
|
|
4516
|
+
return fileName === "pack-manifest.json" || /^(?:scaffold|review|section-.+-pack|page-.+-pack|mutation-.+-pack)\.(?:md|json)$/.test(
|
|
4517
|
+
fileName
|
|
4518
|
+
);
|
|
4519
|
+
}
|
|
4520
|
+
function removeObsoleteExecutionPackArtifacts(contextDir, writtenPaths) {
|
|
4521
|
+
const expected = /* @__PURE__ */ new Set();
|
|
4522
|
+
for (const path of writtenPaths) {
|
|
4523
|
+
expected.add(path);
|
|
4524
|
+
if (path.endsWith(".md")) expected.add(path.slice(0, -".md".length) + ".json");
|
|
4525
|
+
}
|
|
4526
|
+
for (const entry of readdirSync2(contextDir, { withFileTypes: true })) {
|
|
4527
|
+
if (!entry.isFile()) continue;
|
|
4528
|
+
if (!isManagedExecutionPackArtifact(entry.name)) continue;
|
|
4529
|
+
const fullPath = join2(contextDir, entry.name);
|
|
4530
|
+
if (!expected.has(fullPath)) rmSync(fullPath, { force: true });
|
|
4531
|
+
}
|
|
4532
|
+
}
|
|
4507
4533
|
function writeExecutionPackBundleArtifacts(contextDir, bundle) {
|
|
4508
4534
|
mkdirSync2(contextDir, { recursive: true });
|
|
4509
4535
|
const outputPaths = [];
|
|
@@ -4540,6 +4566,7 @@ function writeExecutionPackBundleArtifacts(contextDir, bundle) {
|
|
|
4540
4566
|
const manifestPath = join2(contextDir, "pack-manifest.json");
|
|
4541
4567
|
writeFileSync2(manifestPath, JSON.stringify(bundle.manifest, null, 2) + "\n");
|
|
4542
4568
|
outputPaths.push(manifestPath);
|
|
4569
|
+
removeObsoleteExecutionPackArtifacts(contextDir, outputPaths);
|
|
4543
4570
|
return {
|
|
4544
4571
|
paths: outputPaths,
|
|
4545
4572
|
scaffoldPackPath,
|
|
@@ -10,8 +10,8 @@ import {
|
|
|
10
10
|
renderProjectHealthCiWorkflow,
|
|
11
11
|
shouldFailHealth,
|
|
12
12
|
writeProjectHealthCiWorkflow
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-WPP3JEMC.js";
|
|
14
|
+
import "./chunk-4SZ4SEKT.js";
|
|
15
15
|
export {
|
|
16
16
|
cmdHealth,
|
|
17
17
|
collectDesignTokenEvidence,
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "./chunk-
|
|
2
|
-
import "./chunk-
|
|
3
|
-
import "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
1
|
+
import "./chunk-66L74ZNJ.js";
|
|
2
|
+
import "./chunk-IQZCIMQJ.js";
|
|
3
|
+
import "./chunk-QDMXZSVK.js";
|
|
4
|
+
import "./chunk-WPP3JEMC.js";
|
|
5
|
+
import "./chunk-4SZ4SEKT.js";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createWorkspaceHealthReport
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QDMXZSVK.js";
|
|
4
4
|
import {
|
|
5
5
|
createProjectHealthReport
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-WPP3JEMC.js";
|
|
7
7
|
import {
|
|
8
8
|
sendStudioHealthRefreshedTelemetry,
|
|
9
9
|
sendStudioStartedTelemetry
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-4SZ4SEKT.js";
|
|
11
11
|
|
|
12
12
|
// src/commands/studio.ts
|
|
13
13
|
import { readFileSync } from "fs";
|
|
@@ -7,9 +7,9 @@ import {
|
|
|
7
7
|
listWorkspaceProjects,
|
|
8
8
|
parseWorkspaceArgs,
|
|
9
9
|
shouldFailWorkspaceHealth
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-QDMXZSVK.js";
|
|
11
|
+
import "./chunk-WPP3JEMC.js";
|
|
12
|
+
import "./chunk-4SZ4SEKT.js";
|
|
13
13
|
export {
|
|
14
14
|
cmdWorkspace,
|
|
15
15
|
createWorkspaceHealthReport,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decantr/cli",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.7",
|
|
4
4
|
"description": "Decantr CLI - scaffold, audit, inspect Project Health, and maintain Decantr projects from the terminal",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"decantr",
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"ajv": "^8.20.0",
|
|
51
51
|
"@decantr/core": "2.1.0",
|
|
52
52
|
"@decantr/registry": "2.2.0",
|
|
53
|
-
"@decantr/essence-spec": "2.0.1",
|
|
54
53
|
"@decantr/verifier": "2.3.3",
|
|
54
|
+
"@decantr/essence-spec": "2.0.1",
|
|
55
55
|
"@decantr/telemetry": "2.2.1"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|