@decantr/cli 2.9.5 → 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 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.
@@ -189,7 +193,7 @@ decantr workspace health --json --output .decantr/workspace-health.json
189
193
  decantr verify --workspace --changed --since origin/main
190
194
  ```
191
195
 
192
- In observed Brownfield projects, common section shorthands are accepted for page additions when they resolve unambiguously. For example, `decantr add page app/settings --route /settings --project apps/web` resolves `app` to the single primary section, such as `observed-primary`, so docs and LLM prompts do not have to guess generated section IDs first.
196
+ In observed Brownfield projects, common section shorthands are accepted for page and feature additions when they resolve unambiguously. For example, `decantr add page app/settings --route /settings --project apps/web` and `decantr add feature saved-recipes --section app --project apps/web` resolve `app` to the single primary section, such as `observed-primary`, so docs and LLM prompts do not have to guess generated section IDs first.
193
197
 
194
198
  `decantr studio` starts a local-only dashboard powered by the same report. It uses Node built-ins only and serves `GET /`, `GET /api/health`, and `POST /api/refresh`.
195
199
 
package/dist/bin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-3KJ46XY7.js";
3
- import "./chunk-RXF7ZYGK.js";
4
- import "./chunk-VCUFZB45.js";
5
- import "./chunk-FACL3NXU.js";
6
- import "./chunk-WONPNSSI.js";
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
- try {
2004
- interactionIssues = scanProjectInteractions(projectRoot);
2005
- } catch {
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-RXF7ZYGK.js";
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-VCUFZB45.js";
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-FACL3NXU.js";
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-WONPNSSI.js";
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 dirname5, isAbsolute as isAbsolute3, join as join31, relative as relative7, resolve as resolve4 } from "path";
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 {
@@ -1940,16 +1940,23 @@ async function cmdAddFeature(feature, args, projectRoot = process.cwd()) {
1940
1940
  sectionId = readFlagValue(args, "section");
1941
1941
  if (sectionId) {
1942
1942
  const sections = essence.blueprint.sections;
1943
- const section = sections.find((s) => s.id === sectionId);
1944
- if (!section) {
1945
- console.error(`${RED}Section "${sectionId}" not found.${RESET}`);
1946
- console.error(`${DIM}Available sections: ${sections.map((s) => s.id).join(", ")}${RESET}`);
1943
+ const resolved = resolveSectionForPage(sections, sectionId);
1944
+ if (!resolved) {
1945
+ printSectionNotFound(sectionId, sections);
1947
1946
  process.exitCode = 1;
1948
1947
  return;
1949
1948
  }
1949
+ const { section } = resolved;
1950
+ const resolvedSectionId = section.id;
1950
1951
  if (!section.features.includes(feature)) {
1951
1952
  section.features.push(feature);
1952
1953
  }
1954
+ if (resolved.resolvedFromAlias) {
1955
+ console.log(
1956
+ `${YELLOW}Resolved section alias "${sectionId}" to "${resolvedSectionId}".${RESET}`
1957
+ );
1958
+ }
1959
+ sectionId = resolvedSectionId;
1953
1960
  }
1954
1961
  if (!essence.blueprint.features.includes(feature)) {
1955
1962
  essence.blueprint.features.push(feature);
@@ -2747,7 +2754,7 @@ function writeBrownfieldIntelligenceArtifacts(input) {
2747
2754
 
2748
2755
  // src/detect.ts
2749
2756
  import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
2750
- import { join as join12 } from "path";
2757
+ import { dirname as dirname2, join as join12 } from "path";
2751
2758
  var RULE_FILES = [
2752
2759
  "CLAUDE.md",
2753
2760
  ".claude/rules",
@@ -2759,6 +2766,34 @@ var RULE_FILES = [
2759
2766
  ".github/copilot-instructions.md",
2760
2767
  ".windsurfrules"
2761
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
+ }
2762
2797
  function detectProject(projectRoot = process.cwd()) {
2763
2798
  const result = {
2764
2799
  framework: "unknown",
@@ -2775,15 +2810,7 @@ function detectProject(projectRoot = process.cwd()) {
2775
2810
  result.existingRuleFiles.push(ruleFile);
2776
2811
  }
2777
2812
  }
2778
- if (existsSync10(join12(projectRoot, "pnpm-lock.yaml"))) {
2779
- result.packageManager = "pnpm";
2780
- } else if (existsSync10(join12(projectRoot, "yarn.lock"))) {
2781
- result.packageManager = "yarn";
2782
- } else if (existsSync10(join12(projectRoot, "bun.lockb"))) {
2783
- result.packageManager = "bun";
2784
- } else if (existsSync10(join12(projectRoot, "package-lock.json"))) {
2785
- result.packageManager = "npm";
2786
- }
2813
+ result.packageManager = detectPackageManager(projectRoot);
2787
2814
  result.hasTypeScript = existsSync10(join12(projectRoot, "tsconfig.json"));
2788
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"));
2789
2816
  if (existsSync10(join12(projectRoot, "next.config.js")) || existsSync10(join12(projectRoot, "next.config.ts")) || existsSync10(join12(projectRoot, "next.config.mjs"))) {
@@ -3188,7 +3215,7 @@ ${YELLOW2}Next step:${RESET2} Review ${BOLD}${reportDisplayPath}${RESET2}, then
3188
3215
 
3189
3216
  // src/commands/ci.ts
3190
3217
  import { existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync12, writeFileSync as writeFileSync10 } from "fs";
3191
- import { dirname as dirname2, join as join16, relative as relative4, resolve } from "path";
3218
+ import { dirname as dirname3, join as join16, relative as relative4, resolve } from "path";
3192
3219
 
3193
3220
  // src/local-law.ts
3194
3221
  import { execFileSync } from "child_process";
@@ -3725,7 +3752,7 @@ function parseProvider(value) {
3725
3752
  if (value === "github" || value === "generic") return value;
3726
3753
  throw new Error("Invalid --provider value. Use github or generic.");
3727
3754
  }
3728
- function detectPackageManager(root) {
3755
+ function detectPackageManager2(root) {
3729
3756
  const pkg = readJson(join16(root, "package.json"));
3730
3757
  const declared = pkg?.packageManager?.split("@")[0];
3731
3758
  if (declared === "pnpm" || declared === "npm" || declared === "yarn" || declared === "bun") {
@@ -3794,7 +3821,7 @@ function projectSlug(projectPath) {
3794
3821
  }
3795
3822
  function writeOutput(root, path, content) {
3796
3823
  const absolute = resolve(root, path);
3797
- mkdirSync9(dirname2(absolute), { recursive: true });
3824
+ mkdirSync9(dirname3(absolute), { recursive: true });
3798
3825
  writeFileSync10(absolute, content, "utf-8");
3799
3826
  }
3800
3827
  function summarizeLocalLaw(projectRoot) {
@@ -3924,7 +3951,7 @@ function writeCiInit(root, options) {
3924
3951
  }
3925
3952
  const outputRoot = workspaceInfo.workspaceRoot;
3926
3953
  const projectPath = options.project ?? (options.workspace || workspaceInfo.appRoot === workspaceInfo.workspaceRoot ? void 0 : relative4(workspaceInfo.workspaceRoot, workspaceInfo.appRoot).replace(/\\/g, "/"));
3927
- const packageManager = detectPackageManager(outputRoot);
3954
+ const packageManager = detectPackageManager2(outputRoot);
3928
3955
  const command = decantrCommand(packageManager);
3929
3956
  const failOn = options.failOn ?? "error";
3930
3957
  const provider = options.provider ?? "github";
@@ -4288,7 +4315,7 @@ function cmdCreate(type, name, projectRoot = process.cwd()) {
4288
4315
 
4289
4316
  // src/commands/doctor.ts
4290
4317
  import { existsSync as existsSync16, readdirSync as readdirSync6, readFileSync as readFileSync13 } from "fs";
4291
- import { dirname as dirname3, join as join18, relative as relative5 } from "path";
4318
+ import { dirname as dirname4, join as join18, relative as relative5 } from "path";
4292
4319
  import { fileURLToPath } from "url";
4293
4320
  import { isV4 as isV44 } from "@decantr/essence-spec";
4294
4321
  import { collectMissingPackManifestFiles } from "@decantr/verifier";
@@ -4312,16 +4339,16 @@ function isContractOnlyProject(projectRoot) {
4312
4339
  return projectJson?.initialized?.adoptionMode === "contract-only";
4313
4340
  }
4314
4341
  function readCliPackageVersion() {
4315
- const packagePath = join18(dirname3(fileURLToPath(import.meta.url)), "..", "..", "package.json");
4316
- const srcPackagePath = join18(dirname3(fileURLToPath(import.meta.url)), "..", "package.json");
4342
+ const packagePath = join18(dirname4(fileURLToPath(import.meta.url)), "..", "..", "package.json");
4343
+ const srcPackagePath = join18(dirname4(fileURLToPath(import.meta.url)), "..", "package.json");
4317
4344
  const pkg = readJson2(packagePath) ?? readJson2(srcPackagePath);
4318
4345
  return pkg?.version ?? "unknown";
4319
4346
  }
4320
- function readPackageJson(dir) {
4347
+ function readPackageJson2(dir) {
4321
4348
  return readJson2(join18(dir, "package.json"));
4322
4349
  }
4323
- function detectPackageManager2(root) {
4324
- const pkg = readPackageJson(root);
4350
+ function detectPackageManager3(root) {
4351
+ const pkg = readPackageJson2(root);
4325
4352
  const declared = pkg?.packageManager?.split("@")[0];
4326
4353
  if (declared === "pnpm" || declared === "npm" || declared === "yarn" || declared === "bun") {
4327
4354
  return declared;
@@ -4333,11 +4360,11 @@ function detectPackageManager2(root) {
4333
4360
  return "unknown";
4334
4361
  }
4335
4362
  function localCliDependency(root) {
4336
- const pkg = readPackageJson(root);
4363
+ const pkg = readPackageJson2(root);
4337
4364
  return pkg?.devDependencies?.["@decantr/cli"] ?? pkg?.dependencies?.["@decantr/cli"] ?? null;
4338
4365
  }
4339
4366
  function hasWorkspaceMarker2(root) {
4340
- const pkg = readPackageJson(root);
4367
+ const pkg = readPackageJson2(root);
4341
4368
  return Boolean(
4342
4369
  existsSync16(join18(root, "pnpm-workspace.yaml")) || existsSync16(join18(root, "turbo.json")) || existsSync16(join18(root, "nx.json")) || pkg?.workspaces
4343
4370
  );
@@ -4368,7 +4395,7 @@ function hasAnyFile(dir, names) {
4368
4395
  return null;
4369
4396
  }
4370
4397
  function packageHasDependency(dir, names) {
4371
- const pkg = readPackageJson(dir);
4398
+ const pkg = readPackageJson2(dir);
4372
4399
  const deps = { ...pkg?.dependencies, ...pkg?.devDependencies };
4373
4400
  return names.some((name) => Boolean(deps[name]));
4374
4401
  }
@@ -4448,7 +4475,7 @@ function buildDoctorReport(root, args) {
4448
4475
  const appRoot = workspaceMode ? workspaceRoot : workspaceInfo.appRoot;
4449
4476
  const projectMissing = Boolean(projectArg && !existsSync16(appRoot));
4450
4477
  const projectPath = appRoot === workspaceRoot ? null : rel(workspaceRoot, appRoot);
4451
- const packageManager = detectPackageManager2(workspaceRoot);
4478
+ const packageManager = detectPackageManager3(workspaceRoot);
4452
4479
  const cliDependency = localCliDependency(workspaceRoot);
4453
4480
  const detected = detectProject(appRoot);
4454
4481
  const projectJson = readJson2(join18(appRoot, ".decantr", "project.json"));
@@ -4716,7 +4743,7 @@ async function cmdDoctor(args = ["doctor"], root = process.cwd()) {
4716
4743
 
4717
4744
  // src/commands/export.ts
4718
4745
  import { existsSync as existsSync17, mkdirSync as mkdirSync11, readFileSync as readFileSync14, writeFileSync as writeFileSync12 } from "fs";
4719
- import { dirname as dirname4, isAbsolute, join as join19 } from "path";
4746
+ import { dirname as dirname5, isAbsolute, join as join19 } from "path";
4720
4747
  var GREEN5 = "\x1B[32m";
4721
4748
  var RED4 = "\x1B[31m";
4722
4749
  var DIM5 = "\x1B[2m";
@@ -4970,7 +4997,7 @@ async function cmdExport(target, projectRoot, options = {}) {
4970
4997
  }
4971
4998
  }
4972
4999
  function ensureDir(filePath) {
4973
- const dir = dirname4(filePath);
5000
+ const dir = dirname5(filePath);
4974
5001
  if (!existsSync17(dir)) {
4975
5002
  mkdirSync11(dir, { recursive: true });
4976
5003
  }
@@ -5883,7 +5910,7 @@ async function cmdNewProject(projectName, options) {
5883
5910
  )
5884
5911
  );
5885
5912
  }
5886
- const packageManager = detectPackageManager3();
5913
+ const packageManager = detectPackageManager4();
5887
5914
  if (shouldBootstrapRuntime) {
5888
5915
  console.log(heading("Installing dependencies..."));
5889
5916
  try {
@@ -5959,7 +5986,7 @@ ${YELLOW6}Decantr init encountered issues. Run \`decantr init\` manually inside
5959
5986
  });
5960
5987
  }
5961
5988
  }
5962
- function detectPackageManager3() {
5989
+ function detectPackageManager4() {
5963
5990
  if (existsSync21(join23(process.cwd(), "pnpm-lock.yaml")) || existsSync21(join23(process.cwd(), "pnpm-workspace.yaml"))) {
5964
5991
  return "pnpm";
5965
5992
  }
@@ -6358,6 +6385,7 @@ import { join as join27 } from "path";
6358
6385
  import { isV4 as isV47 } from "@decantr/essence-spec";
6359
6386
  var GREEN11 = "\x1B[32m";
6360
6387
  var RED9 = "\x1B[31m";
6388
+ var YELLOW8 = "\x1B[33m";
6361
6389
  var DIM11 = "\x1B[2m";
6362
6390
  var RESET11 = "\x1B[0m";
6363
6391
  function readV4Essence2(projectRoot) {
@@ -6396,6 +6424,27 @@ function readFlagValue2(args, name) {
6396
6424
  }
6397
6425
  return void 0;
6398
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
+ }
6399
6448
  function recomputeGlobalFeatures(essence) {
6400
6449
  const all = /* @__PURE__ */ new Set();
6401
6450
  for (const section of essence.blueprint.sections || []) {
@@ -6460,24 +6509,31 @@ async function cmdRemovePage(path, args, projectRoot = process.cwd()) {
6460
6509
  if (!loaded) return;
6461
6510
  const { essence, essencePath } = loaded;
6462
6511
  const sections = essence.blueprint.sections;
6463
- const section = sections.find((s) => s.id === sectionId);
6464
- if (!section) {
6512
+ const resolved = resolveSectionAlias(sections, sectionId);
6513
+ if (!resolved) {
6465
6514
  console.error(`${RED9}Section "${sectionId}" not found.${RESET11}`);
6466
6515
  console.error(`${DIM11}Available sections: ${sections.map((s) => s.id).join(", ")}${RESET11}`);
6467
6516
  process.exitCode = 1;
6468
6517
  return;
6469
6518
  }
6519
+ const { section } = resolved;
6520
+ const resolvedSectionId = section.id;
6470
6521
  const pageIdx = section.pages.findIndex((p) => p.id === pageId);
6471
6522
  if (pageIdx === -1) {
6472
- console.error(`${RED9}Page "${pageId}" not found in section "${sectionId}".${RESET11}`);
6523
+ console.error(`${RED9}Page "${pageId}" not found in section "${resolvedSectionId}".${RESET11}`);
6473
6524
  console.error(`${DIM11}Available pages: ${section.pages.map((p) => p.id).join(", ")}${RESET11}`);
6474
6525
  process.exitCode = 1;
6475
6526
  return;
6476
6527
  }
6477
6528
  section.pages.splice(pageIdx, 1);
6478
- removeRoutes(essence, sectionId, pageId);
6529
+ removeRoutes(essence, resolvedSectionId, pageId);
6479
6530
  writeEssence2(essencePath, essence);
6480
- console.log(`${GREEN11}Removed page "${pageId}" from section "${sectionId}".${RESET11}`);
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}`);
6481
6537
  const registryClient = new RegistryClient({
6482
6538
  cacheDir: join27(projectRoot, ".decantr", "cache")
6483
6539
  });
@@ -6497,13 +6553,18 @@ async function cmdRemoveFeature(feature, args, projectRoot = process.cwd()) {
6497
6553
  sectionId = readFlagValue2(args, "section");
6498
6554
  if (sectionId) {
6499
6555
  const sections = essence.blueprint.sections;
6500
- const section = sections.find((s) => s.id === sectionId);
6501
- if (!section) {
6556
+ const resolved = resolveSectionAlias(sections, sectionId);
6557
+ if (!resolved) {
6502
6558
  console.error(`${RED9}Section "${sectionId}" not found.${RESET11}`);
6503
6559
  console.error(`${DIM11}Available sections: ${sections.map((s) => s.id).join(", ")}${RESET11}`);
6504
6560
  process.exitCode = 1;
6505
6561
  return;
6506
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;
6507
6568
  const fIdx = section.features.indexOf(feature);
6508
6569
  if (fIdx !== -1) {
6509
6570
  section.features.splice(fIdx, 1);
@@ -6528,7 +6589,7 @@ import { existsSync as existsSync26, readFileSync as readFileSync19, writeFileSy
6528
6589
  import { join as join28 } from "path";
6529
6590
  var GREEN12 = "\x1B[32m";
6530
6591
  var RED10 = "\x1B[31m";
6531
- var YELLOW8 = "\x1B[33m";
6592
+ var YELLOW9 = "\x1B[33m";
6532
6593
  var RESET12 = "\x1B[0m";
6533
6594
  var DIM12 = "\x1B[2m";
6534
6595
  var BOLD6 = "\x1B[1m";
@@ -6569,7 +6630,7 @@ ${BOLD6}Unresolved Drift Entries (${unresolved.length})${RESET12}
6569
6630
  `);
6570
6631
  for (let i = 0; i < unresolved.length; i++) {
6571
6632
  const entry = unresolved[i];
6572
- const severityColor = entry.severity === "error" ? RED10 : YELLOW8;
6633
+ const severityColor = entry.severity === "error" ? RED10 : YELLOW9;
6573
6634
  const icon = entry.severity === "error" ? "x" : "!";
6574
6635
  console.log(
6575
6636
  ` ${severityColor}${icon}${RESET12} ${BOLD6}#${i + 1}${RESET12} [${entry.rule}] ${entry.message}`
@@ -6853,7 +6914,7 @@ import { join as join29 } from "path";
6853
6914
  import { isV4 as isV48 } from "@decantr/essence-spec";
6854
6915
  var GREEN14 = "\x1B[32m";
6855
6916
  var RED11 = "\x1B[31m";
6856
- var YELLOW9 = "\x1B[33m";
6917
+ var YELLOW10 = "\x1B[33m";
6857
6918
  var DIM14 = "\x1B[2m";
6858
6919
  var RESET14 = "\x1B[0m";
6859
6920
  var VALID_THEME_SHAPES = ["sharp", "rounded", "pill"];
@@ -6948,7 +7009,7 @@ async function cmdThemeSwitch(themeName, args, projectRoot = process.cwd()) {
6948
7009
  console.log(
6949
7010
  `${GREEN14}Derived files refreshed (tokens.css, treatments.css, all contexts).${RESET14}`
6950
7011
  );
6951
- console.log(`${YELLOW9}Guard will flag code using old tokens. Run \`decantr check\`.${RESET14}`);
7012
+ console.log(`${YELLOW10}Guard will flag code using old tokens. Run \`decantr check\`.${RESET14}`);
6952
7013
  }
6953
7014
 
6954
7015
  // src/prompts.ts
@@ -6957,7 +7018,7 @@ var BOLD8 = "\x1B[1m";
6957
7018
  var DIM15 = "\x1B[2m";
6958
7019
  var RESET15 = "\x1B[0m";
6959
7020
  var GREEN15 = "\x1B[32m";
6960
- var YELLOW10 = "\x1B[33m";
7021
+ var YELLOW11 = "\x1B[33m";
6961
7022
  var CYAN8 = "\x1B[36m";
6962
7023
  function ask(question, defaultValue) {
6963
7024
  const rl = createInterface({ input: process.stdin, output: process.stdout });
@@ -6997,7 +7058,7 @@ async function confirm(question, defaultYes = true) {
6997
7058
  }
6998
7059
  function warn(message) {
6999
7060
  console.log(`
7000
- ${YELLOW10} Warning: ${message}${RESET15}`);
7061
+ ${YELLOW11} Warning: ${message}${RESET15}`);
7001
7062
  }
7002
7063
  function showDetection(detected) {
7003
7064
  console.log(`
@@ -7016,7 +7077,7 @@ ${CYAN8}Detected project configuration:${RESET15}`);
7016
7077
  console.log(` Tailwind CSS: ${GREEN15}yes${RESET15}`);
7017
7078
  }
7018
7079
  if (detected.existingEssence) {
7019
- console.log(` Existing essence: ${YELLOW10}yes${RESET15}`);
7080
+ console.log(` Existing essence: ${YELLOW11}yes${RESET15}`);
7020
7081
  }
7021
7082
  }
7022
7083
  async function runInteractivePrompts(detected, archetypes, blueprints, themes, workflowSeed) {
@@ -7418,7 +7479,7 @@ var RESET16 = "\x1B[0m";
7418
7479
  var RED12 = "\x1B[31m";
7419
7480
  var GREEN16 = "\x1B[32m";
7420
7481
  var CYAN9 = "\x1B[36m";
7421
- var YELLOW11 = "\x1B[33m";
7482
+ var YELLOW12 = "\x1B[33m";
7422
7483
  function heading2(text) {
7423
7484
  return `
7424
7485
  ${BOLD9}${text}${RESET16}
@@ -8200,7 +8261,7 @@ async function compileHostedExecutionPackBundle(essencePath, namespace) {
8200
8261
  }
8201
8262
  const essence = JSON.parse(readFileSync22(resolvedPath, "utf-8"));
8202
8263
  const bundle = await client.compileExecutionPacks(essence, namespace ? { namespace } : void 0);
8203
- const contextDir = join31(dirname5(resolvedPath), ".decantr", "context");
8264
+ const contextDir = join31(dirname6(resolvedPath), ".decantr", "context");
8204
8265
  return { resolvedPath, bundle, contextDir };
8205
8266
  }
8206
8267
  function writeHostedExecutionPackContextArtifacts(contextDir, bundle) {
@@ -8244,7 +8305,7 @@ async function printHostedSelectedExecutionPack(packType, id, essencePath, names
8244
8305
  );
8245
8306
  let writtenContextDir = null;
8246
8307
  if (writeContext) {
8247
- const contextDir = join31(dirname5(resolvedPath), ".decantr", "context");
8308
+ const contextDir = join31(dirname6(resolvedPath), ".decantr", "context");
8248
8309
  mkdirSync16(contextDir, { recursive: true });
8249
8310
  writeFileSync19(
8250
8311
  join31(contextDir, "pack-manifest.json"),
@@ -8290,7 +8351,7 @@ async function printHostedExecutionPackManifest(essencePath, namespace, jsonOutp
8290
8351
  );
8291
8352
  let writtenContextDir = null;
8292
8353
  if (writeContext) {
8293
- const contextDir = join31(dirname5(resolvedPath), ".decantr", "context");
8354
+ const contextDir = join31(dirname6(resolvedPath), ".decantr", "context");
8294
8355
  mkdirSync16(contextDir, { recursive: true });
8295
8356
  writeFileSync19(join31(contextDir, "pack-manifest.json"), JSON.stringify(manifest, null, 2) + "\n");
8296
8357
  writtenContextDir = contextDir;
@@ -8461,7 +8522,7 @@ function printBlueprintPortfolioNotice(blueprint) {
8461
8522
  if (!portfolio) return;
8462
8523
  if (portfolio.visibility === "hidden" || portfolio.maturity === "fold-candidate") {
8463
8524
  console.log(
8464
- `${YELLOW11} Warning:${RESET16} blueprint "${blueprint.id}" is folded out of public browsing.`
8525
+ `${YELLOW12} Warning:${RESET16} blueprint "${blueprint.id}" is folded out of public browsing.`
8465
8526
  );
8466
8527
  if (portfolio.recommended_alternative) {
8467
8528
  console.log(
@@ -8474,7 +8535,7 @@ function printBlueprintPortfolioNotice(blueprint) {
8474
8535
  }
8475
8536
  if (portfolio.visibility === "labs") {
8476
8537
  console.log(
8477
- `${YELLOW11} Note:${RESET16} blueprint "${blueprint.id}" is a Labs blueprint; direct scaffolding is supported, but it is not a default recommendation yet.`
8538
+ `${YELLOW12} Note:${RESET16} blueprint "${blueprint.id}" is a Labs blueprint; direct scaffolding is supported, but it is not a default recommendation yet.`
8478
8539
  );
8479
8540
  }
8480
8541
  }
@@ -8661,7 +8722,10 @@ async function cmdSuggest(query, options = {}) {
8661
8722
  `Pattern suggestions for "${query}"${contextBits.length > 0 ? ` (${contextBits.join(", ")})` : ""}`
8662
8723
  )
8663
8724
  );
8664
- const localMatches = localPatternMatches(options.projectRoot, query);
8725
+ const localMatches = localPatternMatches(
8726
+ options.projectRoot,
8727
+ [query, code].filter(Boolean).join("\n")
8728
+ );
8665
8729
  if (localMatches.length > 0) {
8666
8730
  console.log(`${BOLD9}Project-owned local law:${RESET16}`);
8667
8731
  for (const match of localMatches) {
@@ -8763,7 +8827,7 @@ async function cmdValidate(path) {
8763
8827
  console.log(heading2("Guard violations:"));
8764
8828
  for (const v of violations) {
8765
8829
  const vr = v;
8766
- console.log(` ${YELLOW11}[${vr.rule}]${RESET16} ${vr.message}`);
8830
+ console.log(` ${YELLOW12}[${vr.rule}]${RESET16} ${vr.message}`);
8767
8831
  if (vr.suggestion) {
8768
8832
  console.log(` ${DIM16}Suggestion: ${vr.suggestion}${RESET16}`);
8769
8833
  }
@@ -8869,7 +8933,7 @@ ${CYAN9}Telemetry enabled.${RESET16} Decantr will send privacy-filtered CLI prod
8869
8933
  console.log(`${DIM16}Set "telemetry": false in .decantr/project.json to opt out.${RESET16}`);
8870
8934
  }
8871
8935
  function readCliPackageVersion2() {
8872
- const here = dirname5(fileURLToPath3(import.meta.url));
8936
+ const here = dirname6(fileURLToPath3(import.meta.url));
8873
8937
  const candidates = [join31(here, "..", "package.json"), join31(here, "..", "..", "package.json")];
8874
8938
  for (const candidate of candidates) {
8875
8939
  try {
@@ -9097,7 +9161,7 @@ async function cmdInit(args) {
9097
9161
  console.log(dim3(" Found .decantr/init-seed.json brownfield guidance."));
9098
9162
  }
9099
9163
  if (detected.existingEssence && !args.existing) {
9100
- console.log(`${YELLOW11}Warning: decantr.essence.json already exists.${RESET16}`);
9164
+ console.log(`${YELLOW12}Warning: decantr.essence.json already exists.${RESET16}`);
9101
9165
  const overwrite = await confirm("Overwrite existing configuration?", false);
9102
9166
  if (!overwrite) {
9103
9167
  console.log(dim3("Cancelled."));
@@ -9200,7 +9264,7 @@ async function cmdInit(args) {
9200
9264
  } else if (shouldUseRegistry && !apiAvailable) {
9201
9265
  if (!args.blueprint) {
9202
9266
  console.log(`
9203
- ${YELLOW11}You're offline. Scaffolding minimal Decantr project.${RESET16}`);
9267
+ ${YELLOW12}You're offline. Scaffolding minimal Decantr project.${RESET16}`);
9204
9268
  console.log(
9205
9269
  dim3("Run `decantr sync` or `decantr upgrade` when online to pull full registry content.\n")
9206
9270
  );
@@ -9249,7 +9313,7 @@ ${YELLOW11}You're offline. Scaffolding minimal Decantr project.${RESET16}`);
9249
9313
  return;
9250
9314
  }
9251
9315
  console.log(`
9252
- ${YELLOW11}You're offline. Scaffolding Decantr default.${RESET16}`);
9316
+ ${YELLOW12}You're offline. Scaffolding Decantr default.${RESET16}`);
9253
9317
  console.log(dim3("Run `decantr upgrade` when online, or visit decantr.ai/registry\n"));
9254
9318
  selectedBlueprint = "default";
9255
9319
  } else if (shouldUseRegistry) {
@@ -9431,7 +9495,7 @@ ${YELLOW11}You're offline. Scaffolding Decantr default.${RESET16}`);
9431
9495
  return;
9432
9496
  }
9433
9497
  console.log(
9434
- `${YELLOW11} Warning: Could not fetch blueprint "${options.blueprint}". Using defaults.${RESET16}`
9498
+ `${YELLOW12} Warning: Could not fetch blueprint "${options.blueprint}". Using defaults.${RESET16}`
9435
9499
  );
9436
9500
  }
9437
9501
  } else if (shouldUseRegistry && options.archetype) {
@@ -9446,7 +9510,7 @@ ${YELLOW11}You're offline. Scaffolding Decantr default.${RESET16}`);
9446
9510
  return;
9447
9511
  }
9448
9512
  console.log(
9449
- `${YELLOW11} Warning: Could not fetch archetype "${options.archetype}". Using defaults.${RESET16}`
9513
+ `${YELLOW12} Warning: Could not fetch archetype "${options.archetype}". Using defaults.${RESET16}`
9450
9514
  );
9451
9515
  }
9452
9516
  }
@@ -9463,7 +9527,7 @@ ${YELLOW11}You're offline. Scaffolding Decantr default.${RESET16}`);
9463
9527
  return;
9464
9528
  }
9465
9529
  console.log(
9466
- `${YELLOW11} Warning: Could not fetch theme "${options.theme}". Using defaults.${RESET16}`
9530
+ `${YELLOW12} Warning: Could not fetch theme "${options.theme}". Using defaults.${RESET16}`
9467
9531
  );
9468
9532
  }
9469
9533
  }
@@ -9668,7 +9732,7 @@ async function cmdStatus(projectRoot = process.cwd()) {
9668
9732
  ` Guard: ${v4.meta.guard.mode} (DNA: ${v4.meta.guard.dna_enforcement}, Blueprint: ${v4.meta.guard.blueprint_enforcement})`
9669
9733
  );
9670
9734
  } else {
9671
- console.log(` ${YELLOW11}Run \`decantr migrate --to v4\` to upgrade this project.${RESET16}`);
9735
+ console.log(` ${YELLOW12}Run \`decantr migrate --to v4\` to upgrade this project.${RESET16}`);
9672
9736
  }
9673
9737
  } catch (e) {
9674
9738
  console.log(` ${RED12}Error reading essence: ${e.message}${RESET16}`);
@@ -9681,15 +9745,15 @@ async function cmdStatus(projectRoot = process.cwd()) {
9681
9745
  const syncStatus = projectJson.sync?.status || "unknown";
9682
9746
  const lastSync = projectJson.sync?.lastSync || "never";
9683
9747
  const source = projectJson.sync?.registrySource || "unknown";
9684
- const statusColor = syncStatus === "synced" ? GREEN16 : YELLOW11;
9748
+ const statusColor = syncStatus === "synced" ? GREEN16 : YELLOW12;
9685
9749
  console.log(` Status: ${statusColor}${syncStatus}${RESET16}`);
9686
9750
  console.log(` Last sync: ${dim3(lastSync)}`);
9687
9751
  console.log(` Source: ${dim3(source)}`);
9688
9752
  } catch {
9689
- console.log(` ${YELLOW11}Could not read project.json${RESET16}`);
9753
+ console.log(` ${YELLOW12}Could not read project.json${RESET16}`);
9690
9754
  }
9691
9755
  } else {
9692
- console.log(` ${YELLOW11}No .decantr/project.json found${RESET16}`);
9756
+ console.log(` ${YELLOW12}No .decantr/project.json found${RESET16}`);
9693
9757
  console.log(dim3(' Run "decantr init" to create project files.'));
9694
9758
  }
9695
9759
  }
@@ -9702,12 +9766,12 @@ async function cmdSync() {
9702
9766
  console.log(success3("Sync completed successfully."));
9703
9767
  console.log(` Synced: ${result.synced.join(", ")}`);
9704
9768
  if (result.failed.length > 0) {
9705
- console.log(` ${YELLOW11}Failed: ${result.failed.join(", ")}${RESET16}`);
9769
+ console.log(` ${YELLOW12}Failed: ${result.failed.join(", ")}${RESET16}`);
9706
9770
  }
9707
9771
  } else {
9708
- console.log(`${YELLOW11}Could not sync: API unavailable${RESET16}`);
9772
+ console.log(`${YELLOW12}Could not sync: API unavailable${RESET16}`);
9709
9773
  if (result.failed.length > 0) {
9710
- console.log(` ${YELLOW11}Failed: ${result.failed.join(", ")}${RESET16}`);
9774
+ console.log(` ${YELLOW12}Failed: ${result.failed.join(", ")}${RESET16}`);
9711
9775
  }
9712
9776
  }
9713
9777
  }
@@ -9717,7 +9781,7 @@ function printVerificationFindings(findings) {
9717
9781
  return;
9718
9782
  }
9719
9783
  for (const finding of findings) {
9720
- const color = finding.severity === "error" ? RED12 : finding.severity === "warn" ? YELLOW11 : CYAN9;
9784
+ const color = finding.severity === "error" ? RED12 : finding.severity === "warn" ? YELLOW12 : CYAN9;
9721
9785
  console.log(
9722
9786
  ` ${color}[${finding.severity.toUpperCase()}]${RESET16} ${finding.category}: ${finding.message}`
9723
9787
  );
@@ -10224,16 +10288,21 @@ async function cmdSetupWorkflow(args) {
10224
10288
  console.log(` Detected: ${formatDetection(detected)}`);
10225
10289
  console.log("");
10226
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";
10227
10294
  console.log(`${BOLD9}Recommended path:${RESET16} maintain an attached Decantr project`);
10228
10295
  console.log(
10229
10296
  ` ${cyan3(withProject('decantr task <route> "<change>"', projectArg))} Prepare LLM context before edits`
10230
10297
  );
10231
10298
  console.log(
10232
- ` ${cyan3(withProject("decantr verify --brownfield", projectArg))} Run local health and drift checks`
10233
- );
10234
- console.log(
10235
- ` ${cyan3(withProject("decantr codify --from-audit", projectArg))} Propose project-owned local law`
10299
+ ` ${cyan3(withProject(verifyCommand, projectArg))} Run local health and drift checks`
10236
10300
  );
10301
+ if (!hasLocalPatterns || !hasLocalRules) {
10302
+ console.log(
10303
+ ` ${cyan3(withProject("decantr codify --from-audit", projectArg))} Propose project-owned local law`
10304
+ );
10305
+ }
10237
10306
  return;
10238
10307
  }
10239
10308
  if (hasFootprint) {
@@ -10358,7 +10427,7 @@ async function cmdAdoptWorkflow(args) {
10358
10427
  )
10359
10428
  );
10360
10429
  } catch (e) {
10361
- console.log(`${YELLOW11}Pack hydration skipped:${RESET16} ${e.message}`);
10430
+ console.log(`${YELLOW12}Pack hydration skipped:${RESET16} ${e.message}`);
10362
10431
  console.log(
10363
10432
  dim3(
10364
10433
  `Run ${compilePacksCommandForProject(projectArg)} after adoption if you want hosted page/review packs.`
@@ -10369,7 +10438,7 @@ async function cmdAdoptWorkflow(args) {
10369
10438
  console.log(dim3("Skipping hosted pack hydration in offline mode."));
10370
10439
  }
10371
10440
  if (runVerify) {
10372
- const { cmdHealth } = await import("./health-R7AV5G4V.js");
10441
+ const { cmdHealth } = await import("./health-VAYRQVTF.js");
10373
10442
  await cmdHealth(projectRoot, {
10374
10443
  browser: runBrowser,
10375
10444
  browserBaseUrl: baseUrl,
@@ -10440,7 +10509,7 @@ async function cmdVerifyWorkflow(args) {
10440
10509
  return;
10441
10510
  }
10442
10511
  if (workspaceMode) {
10443
- const { cmdWorkspace } = await import("./workspace-DRHTQ2NG.js");
10512
+ const { cmdWorkspace } = await import("./workspace-PBO3BJRL.js");
10444
10513
  await cmdWorkspace(process.cwd(), ["workspace", "health", ...withoutWorkflowOnlyFlags(args)]);
10445
10514
  return;
10446
10515
  }
@@ -10473,7 +10542,7 @@ async function cmdVerifyWorkflow(args) {
10473
10542
  }
10474
10543
  let guardExitCode;
10475
10544
  if (brownfield) {
10476
- const { cmdHeal, collectCheckIssues } = await import("./heal-ZQHEHBUJ.js");
10545
+ const { cmdHeal, collectCheckIssues } = await import("./heal-2UCSPRTK.js");
10477
10546
  if (quietOutput) {
10478
10547
  const result = collectCheckIssues(workspaceInfo.appRoot, { brownfield: true });
10479
10548
  guardExitCode = result.issues.some((issue) => issue.type === "error") ? 1 : void 0;
@@ -10483,7 +10552,7 @@ async function cmdVerifyWorkflow(args) {
10483
10552
  process.exitCode = void 0;
10484
10553
  }
10485
10554
  }
10486
- const { cmdHealth, parseHealthArgs } = await import("./health-R7AV5G4V.js");
10555
+ const { cmdHealth, parseHealthArgs } = await import("./health-VAYRQVTF.js");
10487
10556
  await cmdHealth(workspaceInfo.appRoot, parseHealthArgs(healthArgs));
10488
10557
  if (localPatterns) {
10489
10558
  const validation = validateLocalLaw(workspaceInfo.appRoot);
@@ -10491,7 +10560,7 @@ async function cmdVerifyWorkflow(args) {
10491
10560
  if (!quietOutput) {
10492
10561
  console.log("");
10493
10562
  console.log(
10494
- `${YELLOW11}Local pattern pack missing.${RESET16} Run ${cyan3(withProject("decantr codify --from-audit", projectArg))}, review the proposal, then run ${cyan3(withProject("decantr codify --accept", projectArg))}.`
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))}.`
10495
10564
  );
10496
10565
  }
10497
10566
  process.exitCode = process.exitCode || 1;
@@ -10507,11 +10576,11 @@ async function cmdVerifyWorkflow(args) {
10507
10576
  console.log(`${GREEN16}Local rule manifest found:${RESET16} ${validation.rulesPath}`);
10508
10577
  } else {
10509
10578
  console.log(
10510
- `${YELLOW11}Local rule manifest missing.${RESET16} Run ${cyan3("decantr codify --from-audit")} to propose .decantr/rules.json.`
10579
+ `${YELLOW12}Local rule manifest missing.${RESET16} Run ${cyan3("decantr codify --from-audit")} to propose .decantr/rules.json.`
10511
10580
  );
10512
10581
  }
10513
10582
  for (const warning of validation.warnings.slice(0, 8)) {
10514
- console.log(`${YELLOW11}warn${RESET16} ${warning}`);
10583
+ console.log(`${YELLOW12}warn${RESET16} ${warning}`);
10515
10584
  }
10516
10585
  if (validation.findings.length > 0) {
10517
10586
  console.log("");
@@ -10664,7 +10733,7 @@ async function cmdTaskWorkflow(args) {
10664
10733
  console.log("");
10665
10734
  console.log(`${BOLD9}Project-owned local law:${RESET16}`);
10666
10735
  console.log(
10667
- ` ${YELLOW11}Not codified yet.${RESET16} Run ${cyan3(withProject("decantr codify --from-audit", projectArg))} after adoption.`
10736
+ ` ${YELLOW12}Not codified yet.${RESET16} Run ${cyan3(withProject("decantr codify --from-audit", projectArg))} after adoption.`
10668
10737
  );
10669
10738
  }
10670
10739
  if (context.changedFiles.length > 0) {
@@ -11309,7 +11378,7 @@ async function main() {
11309
11378
  }
11310
11379
  if (command === "--version" || command === "-v" || command === "version") {
11311
11380
  try {
11312
- const here = dirname5(fileURLToPath3(import.meta.url));
11381
+ const here = dirname6(fileURLToPath3(import.meta.url));
11313
11382
  const candidates = [join31(here, "..", "package.json"), join31(here, "..", "..", "package.json")];
11314
11383
  for (const candidate of candidates) {
11315
11384
  if (existsSync29(candidate)) {
@@ -11451,7 +11520,7 @@ async function main() {
11451
11520
  break;
11452
11521
  }
11453
11522
  case "upgrade": {
11454
- const { cmdUpgrade } = await import("./upgrade-VON7Y3LG.js");
11523
+ const { cmdUpgrade } = await import("./upgrade-7ZYWR2GH.js");
11455
11524
  const { flags } = parseLooseArgs(args);
11456
11525
  const workspaceInfo = resolveWorkflowProject(flags, "upgrade");
11457
11526
  if (!workspaceInfo) break;
@@ -11463,10 +11532,10 @@ async function main() {
11463
11532
  case "heal": {
11464
11533
  if (command === "heal") {
11465
11534
  console.log(
11466
- `${YELLOW11}Note: \`decantr heal\` is deprecated. Use \`decantr check\` instead.${RESET16}`
11535
+ `${YELLOW12}Note: \`decantr heal\` is deprecated. Use \`decantr check\` instead.${RESET16}`
11467
11536
  );
11468
11537
  }
11469
- const { cmdHeal } = await import("./heal-ZQHEHBUJ.js");
11538
+ const { cmdHeal } = await import("./heal-2UCSPRTK.js");
11470
11539
  const { flags } = parseLooseArgs(args);
11471
11540
  const workspaceInfo = resolveWorkflowProject(flags, "check");
11472
11541
  if (!workspaceInfo) break;
@@ -11491,7 +11560,7 @@ async function main() {
11491
11560
  const { flags } = parseLooseArgs(args);
11492
11561
  const workspaceInfo = resolveWorkflowProject(flags, "health");
11493
11562
  if (!workspaceInfo) break;
11494
- const { cmdHealth, parseHealthArgs } = await import("./health-R7AV5G4V.js");
11563
+ const { cmdHealth, parseHealthArgs } = await import("./health-VAYRQVTF.js");
11495
11564
  await cmdHealth(workspaceInfo.appRoot, parseHealthArgs(stripProjectArgs(args)));
11496
11565
  } catch (e) {
11497
11566
  console.error(error2(e.message));
@@ -11519,7 +11588,7 @@ async function main() {
11519
11588
  cmdStudioHelp();
11520
11589
  break;
11521
11590
  }
11522
- const { cmdStudio, parseStudioArgs } = await import("./studio-2734P63C.js");
11591
+ const { cmdStudio, parseStudioArgs } = await import("./studio-WPETOZRW.js");
11523
11592
  await cmdStudio(process.cwd(), parseStudioArgs(args));
11524
11593
  } catch (e) {
11525
11594
  console.error(error2(e.message));
@@ -11533,7 +11602,7 @@ async function main() {
11533
11602
  cmdWorkspaceHelp();
11534
11603
  break;
11535
11604
  }
11536
- const { cmdWorkspace } = await import("./workspace-DRHTQ2NG.js");
11605
+ const { cmdWorkspace } = await import("./workspace-PBO3BJRL.js");
11537
11606
  await cmdWorkspace(process.cwd(), args);
11538
11607
  } catch (e) {
11539
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 { appendFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
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,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createProjectHealthReport,
3
3
  listWorkspaceAppCandidates
4
- } from "./chunk-FACL3NXU.js";
4
+ } from "./chunk-WPP3JEMC.js";
5
5
 
6
6
  // src/commands/workspace.ts
7
7
  import { execFileSync } from "child_process";
@@ -3,7 +3,7 @@ import {
3
3
  sendProjectHealthCiFailedTelemetry,
4
4
  sendProjectHealthPromptTelemetry,
5
5
  sendProjectHealthReportTelemetry
6
- } from "./chunk-WONPNSSI.js";
6
+ } from "./chunk-4SZ4SEKT.js";
7
7
 
8
8
  // src/commands/health.ts
9
9
  import { execFileSync } from "child_process";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  cmdHeal,
3
3
  collectCheckIssues
4
- } from "./chunk-WONPNSSI.js";
4
+ } from "./chunk-4SZ4SEKT.js";
5
5
  export {
6
6
  cmdHeal,
7
7
  collectCheckIssues
@@ -10,8 +10,8 @@ import {
10
10
  renderProjectHealthCiWorkflow,
11
11
  shouldFailHealth,
12
12
  writeProjectHealthCiWorkflow
13
- } from "./chunk-FACL3NXU.js";
14
- import "./chunk-WONPNSSI.js";
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-3KJ46XY7.js";
2
- import "./chunk-RXF7ZYGK.js";
3
- import "./chunk-VCUFZB45.js";
4
- import "./chunk-FACL3NXU.js";
5
- import "./chunk-WONPNSSI.js";
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-VCUFZB45.js";
3
+ } from "./chunk-QDMXZSVK.js";
4
4
  import {
5
5
  createProjectHealthReport
6
- } from "./chunk-FACL3NXU.js";
6
+ } from "./chunk-WPP3JEMC.js";
7
7
  import {
8
8
  sendStudioHealthRefreshedTelemetry,
9
9
  sendStudioStartedTelemetry
10
- } from "./chunk-WONPNSSI.js";
10
+ } from "./chunk-4SZ4SEKT.js";
11
11
 
12
12
  // src/commands/studio.ts
13
13
  import { readFileSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  RegistryClient,
3
3
  refreshDerivedFiles
4
- } from "./chunk-RXF7ZYGK.js";
4
+ } from "./chunk-IQZCIMQJ.js";
5
5
 
6
6
  // src/commands/upgrade.ts
7
7
  import { existsSync, readFileSync, writeFileSync } from "fs";
@@ -7,9 +7,9 @@ import {
7
7
  listWorkspaceProjects,
8
8
  parseWorkspaceArgs,
9
9
  shouldFailWorkspaceHealth
10
- } from "./chunk-VCUFZB45.js";
11
- import "./chunk-FACL3NXU.js";
12
- import "./chunk-WONPNSSI.js";
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.5",
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,9 +50,9 @@
50
50
  "ajv": "^8.20.0",
51
51
  "@decantr/core": "2.1.0",
52
52
  "@decantr/registry": "2.2.0",
53
- "@decantr/telemetry": "2.2.1",
53
+ "@decantr/verifier": "2.3.3",
54
54
  "@decantr/essence-spec": "2.0.1",
55
- "@decantr/verifier": "2.3.3"
55
+ "@decantr/telemetry": "2.2.1"
56
56
  },
57
57
  "scripts": {
58
58
  "build": "tsup",