@decantr/cli 2.9.3 → 2.9.5
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 -2
- package/dist/bin.js +4 -4
- package/dist/{chunk-VMNUJOEH.js → chunk-3KJ46XY7.js} +119 -70
- package/dist/{chunk-XZFKK6V7.js → chunk-FACL3NXU.js} +54 -3
- package/dist/{chunk-ARR3EPS2.js → chunk-VCUFZB45.js} +2 -2
- package/dist/{chunk-34TZXWIF.js → chunk-WONPNSSI.js} +19 -1
- package/dist/{heal-2BDT7TR5.js → heal-ZQHEHBUJ.js} +1 -1
- package/dist/{health-MB63O56B.js → health-R7AV5G4V.js} +2 -2
- package/dist/index.js +4 -4
- package/dist/{studio-6QGXJBVH.js → studio-2734P63C.js} +3 -3
- package/dist/{workspace-OGFYJA4N.js → workspace-DRHTQ2NG.js} +3 -3
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -176,11 +176,11 @@ decantr verify --workspace --changed --since origin/main
|
|
|
176
176
|
decantr export --to figma-tokens
|
|
177
177
|
```
|
|
178
178
|
|
|
179
|
-
Use `--json` for machines and schema validation, `--markdown` for summaries, `--evidence` for the privacy-redacted Evidence Bundle, and `--prompt <finding-id>` when you want a scoped remediation prompt for an AI assistant. The prompt command prints instructions only; it does not modify source files. In monorepos, prompt commands preserve `--project <path
|
|
179
|
+
Use `--json` for machines and schema validation, `--markdown` for summaries, `--evidence` for the privacy-redacted Evidence Bundle, and `--prompt <finding-id>` when you want a scoped remediation prompt for an AI assistant. The prompt command prints instructions only; it does not modify source files. In monorepos, prompt commands preserve `--project <path>`, include app-prefixed read targets such as `apps/web/DECANTR.md`, and use root-safe runtime commands such as `pnpm --dir apps/web build` so the finding resolves from the same app that produced it. `--browser` uses a project-local Playwright install and a supplied base URL to capture local route screenshots under `.decantr/evidence/screenshots/` and write `.decantr/evidence/visual-manifest.json`; missing Playwright becomes a visible setup finding/message, not a crash or silent skip. `--save-baseline` writes `.decantr/health-baseline.json`; `--since-baseline` writes `.decantr/health-baseline-diff.json` with changed files, route impact, finding deltas, screenshot hash drift, and contract drift. `--design-tokens <path>` compares a Tokens Studio/Figma token JSON export against Decantr CSS token names. `decantr ci --fail-on error` fails only when blocking errors exist; `decantr ci --fail-on warn` also fails on warnings.
|
|
180
180
|
|
|
181
181
|
`decantr ci init` installs `.github/workflows/decantr-ci.yml` for GitHub Actions. The generated workflow installs dependencies at the workspace root, writes JSON/markdown CI artifacts, gates with `decantr ci`, appends the markdown report to the GitHub step summary, and uploads both files as artifacts. Use `--force` to replace an existing workflow or `--fail-on warn` for stricter repositories. In monorepos, add `--project <path>` from the repository root; dependency install stays at the root while CI evaluates the app contract and uploads app-scoped artifacts. Use `--workspace` to generate an aggregate gate. Use `--provider generic` for Jenkins, Please, Buildkite, GitLab, Azure DevOps, or internal deployment tools. Generated CI uses the pinned local package-manager command and does not depend on `@latest`. Project Health remediation prompts are also monorepo-aware, so missing-pack fixes use `apps/web/decantr.essence.json` and CI recommendations include `--project apps/web`.
|
|
182
182
|
|
|
183
|
-
`decantr workspace` is the monorepo reliability namespace. Before attach, `workspace list` shows app candidates. After attach, it also discovers Decantr projects from `.decantr/workspace.json` or by finding `decantr.essence.json` files. Workspace health runs projects with deterministic ordering, concurrency, per-project timeout, failure isolation, and aggregate JSON, and can limit a run to changed projects:
|
|
183
|
+
`decantr workspace` is the monorepo reliability namespace. Before attach, `workspace list` shows app candidates. After attach, it also discovers Decantr projects from `.decantr/workspace.json` or by finding `decantr.essence.json` files, and it distinguishes "attach another app" from the empty-workspace first attach. Workspace health runs projects with deterministic ordering, concurrency, per-project timeout, failure isolation, and aggregate JSON, and can limit a run to changed projects:
|
|
184
184
|
|
|
185
185
|
```bash
|
|
186
186
|
decantr workspace list
|
|
@@ -189,6 +189,8 @@ decantr workspace health --json --output .decantr/workspace-health.json
|
|
|
189
189
|
decantr verify --workspace --changed --since origin/main
|
|
190
190
|
```
|
|
191
191
|
|
|
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.
|
|
193
|
+
|
|
192
194
|
`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`.
|
|
193
195
|
|
|
194
196
|
```bash
|
package/dist/bin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./chunk-
|
|
2
|
+
import "./chunk-3KJ46XY7.js";
|
|
3
3
|
import "./chunk-RXF7ZYGK.js";
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
4
|
+
import "./chunk-VCUFZB45.js";
|
|
5
|
+
import "./chunk-FACL3NXU.js";
|
|
6
|
+
import "./chunk-WONPNSSI.js";
|
|
@@ -22,14 +22,14 @@ import {
|
|
|
22
22
|
listWorkspaceCandidates,
|
|
23
23
|
listWorkspaceProjects,
|
|
24
24
|
shouldFailWorkspaceHealth
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-VCUFZB45.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-FACL3NXU.js";
|
|
33
33
|
import {
|
|
34
34
|
buildGuardRegistryContext,
|
|
35
35
|
createDoctrineMap,
|
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
sendCliCommandTelemetry,
|
|
47
47
|
sendNewProjectCompletedTelemetry,
|
|
48
48
|
writeDoctrineMap
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-WONPNSSI.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";
|
|
@@ -1743,6 +1743,7 @@ import { join as join6 } from "path";
|
|
|
1743
1743
|
import { isV4 as isV42 } from "@decantr/essence-spec";
|
|
1744
1744
|
var GREEN = "\x1B[32m";
|
|
1745
1745
|
var RED = "\x1B[31m";
|
|
1746
|
+
var YELLOW = "\x1B[33m";
|
|
1746
1747
|
var DIM = "\x1B[2m";
|
|
1747
1748
|
var RESET = "\x1B[0m";
|
|
1748
1749
|
function readV4Essence(projectRoot) {
|
|
@@ -1786,6 +1787,36 @@ function normalizeRoute(route) {
|
|
|
1786
1787
|
if (!trimmed || trimmed === "/") return "/";
|
|
1787
1788
|
return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
1788
1789
|
}
|
|
1790
|
+
function resolveSectionForPage(sections, requestedSectionId) {
|
|
1791
|
+
const exact = sections.find((section) => section.id === requestedSectionId);
|
|
1792
|
+
if (exact) return { section: exact, resolvedFromAlias: false };
|
|
1793
|
+
const lower = requestedSectionId.toLowerCase();
|
|
1794
|
+
const roleByAlias = {
|
|
1795
|
+
app: "primary",
|
|
1796
|
+
main: "primary",
|
|
1797
|
+
primary: "primary",
|
|
1798
|
+
public: "public",
|
|
1799
|
+
marketing: "public",
|
|
1800
|
+
auth: "gateway",
|
|
1801
|
+
gateway: "gateway",
|
|
1802
|
+
auxiliary: "auxiliary"
|
|
1803
|
+
};
|
|
1804
|
+
const desiredRole = roleByAlias[lower];
|
|
1805
|
+
if (!desiredRole) return null;
|
|
1806
|
+
const roleMatches = sections.filter((section) => section.role === desiredRole);
|
|
1807
|
+
if (roleMatches.length === 1) return { section: roleMatches[0], resolvedFromAlias: true };
|
|
1808
|
+
if (roleMatches.length > 1) return null;
|
|
1809
|
+
const observedMatch = sections.find((section) => section.id === `observed-${desiredRole}`);
|
|
1810
|
+
return observedMatch ? { section: observedMatch, resolvedFromAlias: true } : null;
|
|
1811
|
+
}
|
|
1812
|
+
function printSectionNotFound(sectionId, sections, pageId) {
|
|
1813
|
+
console.error(`${RED}Section "${sectionId}" not found.${RESET}`);
|
|
1814
|
+
console.error(`${DIM}Available sections: ${sections.map((s) => s.id).join(", ")}${RESET}`);
|
|
1815
|
+
if (pageId && sections.length > 0) {
|
|
1816
|
+
const primary = sections.find((section) => section.role === "primary") ?? sections[0];
|
|
1817
|
+
console.error(`${DIM}Try: decantr add page ${primary.id}/${pageId}${RESET}`);
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1789
1820
|
async function cmdAddSection(archetypeId, args, projectRoot = process.cwd()) {
|
|
1790
1821
|
if (!archetypeId) {
|
|
1791
1822
|
console.error(`${RED}Usage: decantr add section <archetypeId>${RESET}`);
|
|
@@ -1849,15 +1880,18 @@ async function cmdAddPage(path, args, projectRoot = process.cwd()) {
|
|
|
1849
1880
|
if (!loaded) return;
|
|
1850
1881
|
const { essence, essencePath } = loaded;
|
|
1851
1882
|
const sections = essence.blueprint.sections;
|
|
1852
|
-
const
|
|
1853
|
-
if (!
|
|
1854
|
-
|
|
1855
|
-
console.error(`${DIM}Available sections: ${sections.map((s) => s.id).join(", ")}${RESET}`);
|
|
1883
|
+
const resolved = resolveSectionForPage(sections, sectionId);
|
|
1884
|
+
if (!resolved) {
|
|
1885
|
+
printSectionNotFound(sectionId, sections, pageId);
|
|
1856
1886
|
process.exitCode = 1;
|
|
1857
1887
|
return;
|
|
1858
1888
|
}
|
|
1889
|
+
const { section } = resolved;
|
|
1890
|
+
const resolvedSectionId = section.id;
|
|
1859
1891
|
if (section.pages.find((p) => p.id === pageId)) {
|
|
1860
|
-
console.error(
|
|
1892
|
+
console.error(
|
|
1893
|
+
`${RED}Page "${pageId}" already exists in section "${resolvedSectionId}".${RESET}`
|
|
1894
|
+
);
|
|
1861
1895
|
process.exitCode = 1;
|
|
1862
1896
|
return;
|
|
1863
1897
|
}
|
|
@@ -1877,10 +1911,15 @@ async function cmdAddPage(path, args, projectRoot = process.cwd()) {
|
|
|
1877
1911
|
route,
|
|
1878
1912
|
layout: ["hero"]
|
|
1879
1913
|
});
|
|
1880
|
-
routes[route] = { section:
|
|
1914
|
+
routes[route] = { section: resolvedSectionId, page: pageId };
|
|
1881
1915
|
writeEssence(essencePath, essence);
|
|
1916
|
+
if (resolved.resolvedFromAlias) {
|
|
1917
|
+
console.log(
|
|
1918
|
+
`${YELLOW}Resolved section alias "${sectionId}" to "${resolvedSectionId}".${RESET}`
|
|
1919
|
+
);
|
|
1920
|
+
}
|
|
1882
1921
|
console.log(
|
|
1883
|
-
`${GREEN}Added page "${pageId}" to section "${
|
|
1922
|
+
`${GREEN}Added page "${pageId}" to section "${resolvedSectionId}" at route "${route}".${RESET}`
|
|
1884
1923
|
);
|
|
1885
1924
|
const registryClient = new RegistryClient({
|
|
1886
1925
|
cacheDir: join6(projectRoot, ".decantr", "cache")
|
|
@@ -2958,7 +2997,7 @@ var DIM2 = "\x1B[2m";
|
|
|
2958
2997
|
var RESET2 = "\x1B[0m";
|
|
2959
2998
|
var GREEN2 = "\x1B[32m";
|
|
2960
2999
|
var CYAN = "\x1B[36m";
|
|
2961
|
-
var
|
|
3000
|
+
var YELLOW2 = "\x1B[33m";
|
|
2962
3001
|
async function cmdAnalyze(projectRoot = process.cwd(), workspace) {
|
|
2963
3002
|
const startedAt = Date.now();
|
|
2964
3003
|
console.log(`
|
|
@@ -3126,7 +3165,7 @@ ${DIM2}Written to:${RESET2} ${outputPath}`);
|
|
|
3126
3165
|
console.log(`${DIM2}Enrichment backlog:${RESET2} ${intelligenceArtifacts.backlogPath}`);
|
|
3127
3166
|
console.log(
|
|
3128
3167
|
`
|
|
3129
|
-
${
|
|
3168
|
+
${YELLOW2}Next step:${RESET2} Review ${BOLD}${reportDisplayPath}${RESET2}, then run ${BOLD}${recommendedAttachCommand}${RESET2} to attach Decantr using the observed proposal.
|
|
3130
3169
|
`
|
|
3131
3170
|
);
|
|
3132
3171
|
await sendAnalyzeCompletedTelemetry({
|
|
@@ -4257,7 +4296,7 @@ var BOLD3 = "\x1B[1m";
|
|
|
4257
4296
|
var DIM4 = "\x1B[2m";
|
|
4258
4297
|
var GREEN4 = "\x1B[32m";
|
|
4259
4298
|
var RED3 = "\x1B[31m";
|
|
4260
|
-
var
|
|
4299
|
+
var YELLOW3 = "\x1B[33m";
|
|
4261
4300
|
var CYAN2 = "\x1B[36m";
|
|
4262
4301
|
var RESET4 = "\x1B[0m";
|
|
4263
4302
|
function readJson2(path) {
|
|
@@ -4596,7 +4635,7 @@ function buildDoctorReport(root, args) {
|
|
|
4596
4635
|
function colorForStatus(status) {
|
|
4597
4636
|
if (status === "healthy") return GREEN4;
|
|
4598
4637
|
if (status === "needs-setup" || status === "needs-migration") return RED3;
|
|
4599
|
-
return
|
|
4638
|
+
return YELLOW3;
|
|
4600
4639
|
}
|
|
4601
4640
|
function formatDoctorText(report) {
|
|
4602
4641
|
const lines = [
|
|
@@ -4640,7 +4679,7 @@ function formatDoctorText(report) {
|
|
|
4640
4679
|
lines.push(` ${GREEN4}No doctor findings.${RESET4}`);
|
|
4641
4680
|
} else {
|
|
4642
4681
|
for (const issue of report.issues) {
|
|
4643
|
-
const color = issue.severity === "error" ? RED3 : issue.severity === "warn" ?
|
|
4682
|
+
const color = issue.severity === "error" ? RED3 : issue.severity === "warn" ? YELLOW3 : CYAN2;
|
|
4644
4683
|
lines.push(
|
|
4645
4684
|
` ${color}[${issue.severity.toUpperCase()}]${RESET4} ${issue.category}: ${issue.message}`
|
|
4646
4685
|
);
|
|
@@ -4682,6 +4721,16 @@ var GREEN5 = "\x1B[32m";
|
|
|
4682
4721
|
var RED4 = "\x1B[31m";
|
|
4683
4722
|
var DIM5 = "\x1B[2m";
|
|
4684
4723
|
var RESET5 = "\x1B[0m";
|
|
4724
|
+
function readAdoptionMode(projectRoot) {
|
|
4725
|
+
const projectJsonPath = join19(projectRoot, ".decantr", "project.json");
|
|
4726
|
+
if (!existsSync17(projectJsonPath)) return null;
|
|
4727
|
+
try {
|
|
4728
|
+
const parsed = JSON.parse(readFileSync14(projectJsonPath, "utf-8"));
|
|
4729
|
+
return typeof parsed.initialized?.adoptionMode === "string" ? parsed.initialized.adoptionMode : null;
|
|
4730
|
+
} catch {
|
|
4731
|
+
return null;
|
|
4732
|
+
}
|
|
4733
|
+
}
|
|
4685
4734
|
function resolveOutputPath(projectRoot, output, fallback) {
|
|
4686
4735
|
if (!output) return fallback;
|
|
4687
4736
|
return isAbsolute(output) ? output : join19(projectRoot, output);
|
|
@@ -4853,9 +4902,9 @@ async function cmdExport(target, projectRoot, options = {}) {
|
|
|
4853
4902
|
return;
|
|
4854
4903
|
}
|
|
4855
4904
|
if (!existsSync17(tokensPath)) {
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
);
|
|
4905
|
+
const adoptionMode = readAdoptionMode(projectRoot);
|
|
4906
|
+
const message = adoptionMode === "contract-only" ? `No src/styles/tokens.css found. This export reads Decantr CSS tokens, but this project is contract-only Brownfield and may intentionally use its own Tailwind/Sass token system. Export from the app's token source or adopt a style bridge before using \`decantr export --to ${target}\`.` : "No src/styles/tokens.css found. Run `decantr refresh` to generate tokens.";
|
|
4907
|
+
console.error(`${RED4}${message}${RESET5}`);
|
|
4859
4908
|
process.exitCode = 1;
|
|
4860
4909
|
return;
|
|
4861
4910
|
}
|
|
@@ -4936,7 +4985,7 @@ var DIM6 = "\x1B[2m";
|
|
|
4936
4985
|
var RESET6 = "\x1B[0m";
|
|
4937
4986
|
var GREEN6 = "\x1B[32m";
|
|
4938
4987
|
var CYAN3 = "\x1B[36m";
|
|
4939
|
-
var
|
|
4988
|
+
var YELLOW4 = "\x1B[33m";
|
|
4940
4989
|
var MAGENTA = "\x1B[35m";
|
|
4941
4990
|
function success(text) {
|
|
4942
4991
|
return `${GREEN6}${text}${RESET6}`;
|
|
@@ -5157,7 +5206,7 @@ async function cmdMagic(prompt, projectRoot, options) {
|
|
|
5157
5206
|
const essencePath = join20(projectRoot, "decantr.essence.json");
|
|
5158
5207
|
if (existsSync18(essencePath)) {
|
|
5159
5208
|
const projectFlag = options.projectLabel ? ` --project ${options.projectLabel}` : "";
|
|
5160
|
-
console.log(`${
|
|
5209
|
+
console.log(`${YELLOW4} Decantr is already attached to this project.${RESET6}`);
|
|
5161
5210
|
console.log(
|
|
5162
5211
|
dim(" decantr magic is greenfield-first; use task-time context for existing apps.")
|
|
5163
5212
|
);
|
|
@@ -5170,7 +5219,7 @@ async function cmdMagic(prompt, projectRoot, options) {
|
|
|
5170
5219
|
}
|
|
5171
5220
|
const detected = detectProject(projectRoot);
|
|
5172
5221
|
if (hasExistingProjectFootprint(detected)) {
|
|
5173
|
-
console.log(`${
|
|
5222
|
+
console.log(`${YELLOW4} Existing project detected.${RESET6}`);
|
|
5174
5223
|
console.log(
|
|
5175
5224
|
dim(
|
|
5176
5225
|
" decantr magic stays greenfield-first and will not silently bootstrap over an existing app."
|
|
@@ -5480,7 +5529,7 @@ ${GREEN6}${BOLD4}Quality summary:${RESET6}`);
|
|
|
5480
5529
|
);
|
|
5481
5530
|
console.log(` CSS: tokens.css + treatments.css + global.css`);
|
|
5482
5531
|
console.log(
|
|
5483
|
-
` @layer cascade: ${hasLayers ? GREEN6 + "yes" + RESET6 :
|
|
5532
|
+
` @layer cascade: ${hasLayers ? GREEN6 + "yes" + RESET6 : YELLOW4 + "missing" + RESET6}`
|
|
5484
5533
|
);
|
|
5485
5534
|
console.log("");
|
|
5486
5535
|
console.log(`${BOLD4} Ready!${RESET6} Next steps:`);
|
|
@@ -5509,7 +5558,7 @@ import {
|
|
|
5509
5558
|
} from "@decantr/essence-spec";
|
|
5510
5559
|
var GREEN7 = "\x1B[32m";
|
|
5511
5560
|
var RED5 = "\x1B[31m";
|
|
5512
|
-
var
|
|
5561
|
+
var YELLOW5 = "\x1B[33m";
|
|
5513
5562
|
var RESET7 = "\x1B[0m";
|
|
5514
5563
|
var DIM7 = "\x1B[2m";
|
|
5515
5564
|
function migrateEssenceFile(essencePath) {
|
|
@@ -5609,7 +5658,7 @@ async function cmdMigrate(projectRoot = process.cwd(), args = []) {
|
|
|
5609
5658
|
console.log(`${GREEN7}Derived context and execution packs refreshed.${RESET7}`);
|
|
5610
5659
|
}
|
|
5611
5660
|
console.log("");
|
|
5612
|
-
console.log(`${
|
|
5661
|
+
console.log(`${YELLOW5}Review the migrated file and run \`decantr check\` to verify.${RESET7}`);
|
|
5613
5662
|
}
|
|
5614
5663
|
|
|
5615
5664
|
// src/commands/new-project.ts
|
|
@@ -5676,7 +5725,7 @@ var RESET8 = "\x1B[0m";
|
|
|
5676
5725
|
var RED6 = "\x1B[31m";
|
|
5677
5726
|
var GREEN8 = "\x1B[32m";
|
|
5678
5727
|
var CYAN4 = "\x1B[36m";
|
|
5679
|
-
var
|
|
5728
|
+
var YELLOW6 = "\x1B[33m";
|
|
5680
5729
|
function heading(text) {
|
|
5681
5730
|
return `
|
|
5682
5731
|
${BOLD5}${text}${RESET8}
|
|
@@ -5826,7 +5875,7 @@ async function cmdNewProject(projectName, options) {
|
|
|
5826
5875
|
);
|
|
5827
5876
|
} else {
|
|
5828
5877
|
console.log(
|
|
5829
|
-
`${
|
|
5878
|
+
`${YELLOW6} No greenfield bootstrap adapter is available yet for target "${bootstrapTarget.target}" (${bootstrapTarget.packAdapter}).${RESET8}`
|
|
5830
5879
|
);
|
|
5831
5880
|
console.log(
|
|
5832
5881
|
dim2(
|
|
@@ -5842,7 +5891,7 @@ async function cmdNewProject(projectName, options) {
|
|
|
5842
5891
|
} catch {
|
|
5843
5892
|
console.log(
|
|
5844
5893
|
`
|
|
5845
|
-
${
|
|
5894
|
+
${YELLOW6}Dependency install failed. Run \`${packageManager} install\` manually.${RESET8}`
|
|
5846
5895
|
);
|
|
5847
5896
|
}
|
|
5848
5897
|
}
|
|
@@ -5854,7 +5903,7 @@ ${YELLOW5}Dependency install failed. Run \`${packageManager} install\` manually.
|
|
|
5854
5903
|
console.log(dim2(` Seeded offline registry content from ${seeded.strategy}.`));
|
|
5855
5904
|
} else if (requiresOfflineContent) {
|
|
5856
5905
|
console.log(
|
|
5857
|
-
`${
|
|
5906
|
+
`${YELLOW6} Offline blueprint/archetype resolution requires local registry content.${RESET8}`
|
|
5858
5907
|
);
|
|
5859
5908
|
console.log(
|
|
5860
5909
|
dim2(
|
|
@@ -5884,7 +5933,7 @@ ${YELLOW5}Dependency install failed. Run \`${packageManager} install\` manually.
|
|
|
5884
5933
|
} catch {
|
|
5885
5934
|
console.log(
|
|
5886
5935
|
`
|
|
5887
|
-
${
|
|
5936
|
+
${YELLOW6}Decantr init encountered issues. Run \`decantr init\` manually inside ${projectName}/.${RESET8}`
|
|
5888
5937
|
);
|
|
5889
5938
|
}
|
|
5890
5939
|
console.log(success2(`
|
|
@@ -6227,7 +6276,7 @@ var GREEN10 = "\x1B[32m";
|
|
|
6227
6276
|
var RED8 = "\x1B[31m";
|
|
6228
6277
|
var DIM10 = "\x1B[2m";
|
|
6229
6278
|
var CYAN5 = "\x1B[36m";
|
|
6230
|
-
var
|
|
6279
|
+
var YELLOW7 = "\x1B[33m";
|
|
6231
6280
|
var RESET10 = "\x1B[0m";
|
|
6232
6281
|
var ALL_CONTENT_TYPES = [...API_CONTENT_TYPES];
|
|
6233
6282
|
async function cmdRegistryMirror(projectRoot, options = {}) {
|
|
@@ -6291,7 +6340,7 @@ Mirroring registry content to ${DIM10}.decantr/cache/${RESET10}
|
|
|
6291
6340
|
const totalItems = Object.values(counts).reduce((a, b) => a + b, 0);
|
|
6292
6341
|
console.log("");
|
|
6293
6342
|
if (failed.length > 0) {
|
|
6294
|
-
console.log(`${
|
|
6343
|
+
console.log(`${YELLOW7}Mirrored ${totalItems} items (${failed.length} type(s) failed)${RESET10}`);
|
|
6295
6344
|
} else {
|
|
6296
6345
|
console.log(
|
|
6297
6346
|
`${GREEN10}Mirrored ${totalItems} items across ${Object.keys(counts).length} types${RESET10}`
|
|
@@ -6479,7 +6528,7 @@ import { existsSync as existsSync26, readFileSync as readFileSync19, writeFileSy
|
|
|
6479
6528
|
import { join as join28 } from "path";
|
|
6480
6529
|
var GREEN12 = "\x1B[32m";
|
|
6481
6530
|
var RED10 = "\x1B[31m";
|
|
6482
|
-
var
|
|
6531
|
+
var YELLOW8 = "\x1B[33m";
|
|
6483
6532
|
var RESET12 = "\x1B[0m";
|
|
6484
6533
|
var DIM12 = "\x1B[2m";
|
|
6485
6534
|
var BOLD6 = "\x1B[1m";
|
|
@@ -6520,7 +6569,7 @@ ${BOLD6}Unresolved Drift Entries (${unresolved.length})${RESET12}
|
|
|
6520
6569
|
`);
|
|
6521
6570
|
for (let i = 0; i < unresolved.length; i++) {
|
|
6522
6571
|
const entry = unresolved[i];
|
|
6523
|
-
const severityColor = entry.severity === "error" ? RED10 :
|
|
6572
|
+
const severityColor = entry.severity === "error" ? RED10 : YELLOW8;
|
|
6524
6573
|
const icon = entry.severity === "error" ? "x" : "!";
|
|
6525
6574
|
console.log(
|
|
6526
6575
|
` ${severityColor}${icon}${RESET12} ${BOLD6}#${i + 1}${RESET12} [${entry.rule}] ${entry.message}`
|
|
@@ -6804,7 +6853,7 @@ import { join as join29 } from "path";
|
|
|
6804
6853
|
import { isV4 as isV48 } from "@decantr/essence-spec";
|
|
6805
6854
|
var GREEN14 = "\x1B[32m";
|
|
6806
6855
|
var RED11 = "\x1B[31m";
|
|
6807
|
-
var
|
|
6856
|
+
var YELLOW9 = "\x1B[33m";
|
|
6808
6857
|
var DIM14 = "\x1B[2m";
|
|
6809
6858
|
var RESET14 = "\x1B[0m";
|
|
6810
6859
|
var VALID_THEME_SHAPES = ["sharp", "rounded", "pill"];
|
|
@@ -6899,7 +6948,7 @@ async function cmdThemeSwitch(themeName, args, projectRoot = process.cwd()) {
|
|
|
6899
6948
|
console.log(
|
|
6900
6949
|
`${GREEN14}Derived files refreshed (tokens.css, treatments.css, all contexts).${RESET14}`
|
|
6901
6950
|
);
|
|
6902
|
-
console.log(`${
|
|
6951
|
+
console.log(`${YELLOW9}Guard will flag code using old tokens. Run \`decantr check\`.${RESET14}`);
|
|
6903
6952
|
}
|
|
6904
6953
|
|
|
6905
6954
|
// src/prompts.ts
|
|
@@ -6908,7 +6957,7 @@ var BOLD8 = "\x1B[1m";
|
|
|
6908
6957
|
var DIM15 = "\x1B[2m";
|
|
6909
6958
|
var RESET15 = "\x1B[0m";
|
|
6910
6959
|
var GREEN15 = "\x1B[32m";
|
|
6911
|
-
var
|
|
6960
|
+
var YELLOW10 = "\x1B[33m";
|
|
6912
6961
|
var CYAN8 = "\x1B[36m";
|
|
6913
6962
|
function ask(question, defaultValue) {
|
|
6914
6963
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -6948,7 +6997,7 @@ async function confirm(question, defaultYes = true) {
|
|
|
6948
6997
|
}
|
|
6949
6998
|
function warn(message) {
|
|
6950
6999
|
console.log(`
|
|
6951
|
-
${
|
|
7000
|
+
${YELLOW10} Warning: ${message}${RESET15}`);
|
|
6952
7001
|
}
|
|
6953
7002
|
function showDetection(detected) {
|
|
6954
7003
|
console.log(`
|
|
@@ -6967,7 +7016,7 @@ ${CYAN8}Detected project configuration:${RESET15}`);
|
|
|
6967
7016
|
console.log(` Tailwind CSS: ${GREEN15}yes${RESET15}`);
|
|
6968
7017
|
}
|
|
6969
7018
|
if (detected.existingEssence) {
|
|
6970
|
-
console.log(` Existing essence: ${
|
|
7019
|
+
console.log(` Existing essence: ${YELLOW10}yes${RESET15}`);
|
|
6971
7020
|
}
|
|
6972
7021
|
}
|
|
6973
7022
|
async function runInteractivePrompts(detected, archetypes, blueprints, themes, workflowSeed) {
|
|
@@ -7369,7 +7418,7 @@ var RESET16 = "\x1B[0m";
|
|
|
7369
7418
|
var RED12 = "\x1B[31m";
|
|
7370
7419
|
var GREEN16 = "\x1B[32m";
|
|
7371
7420
|
var CYAN9 = "\x1B[36m";
|
|
7372
|
-
var
|
|
7421
|
+
var YELLOW11 = "\x1B[33m";
|
|
7373
7422
|
function heading2(text) {
|
|
7374
7423
|
return `
|
|
7375
7424
|
${BOLD9}${text}${RESET16}
|
|
@@ -8412,7 +8461,7 @@ function printBlueprintPortfolioNotice(blueprint) {
|
|
|
8412
8461
|
if (!portfolio) return;
|
|
8413
8462
|
if (portfolio.visibility === "hidden" || portfolio.maturity === "fold-candidate") {
|
|
8414
8463
|
console.log(
|
|
8415
|
-
`${
|
|
8464
|
+
`${YELLOW11} Warning:${RESET16} blueprint "${blueprint.id}" is folded out of public browsing.`
|
|
8416
8465
|
);
|
|
8417
8466
|
if (portfolio.recommended_alternative) {
|
|
8418
8467
|
console.log(
|
|
@@ -8425,7 +8474,7 @@ function printBlueprintPortfolioNotice(blueprint) {
|
|
|
8425
8474
|
}
|
|
8426
8475
|
if (portfolio.visibility === "labs") {
|
|
8427
8476
|
console.log(
|
|
8428
|
-
`${
|
|
8477
|
+
`${YELLOW11} Note:${RESET16} blueprint "${blueprint.id}" is a Labs blueprint; direct scaffolding is supported, but it is not a default recommendation yet.`
|
|
8429
8478
|
);
|
|
8430
8479
|
}
|
|
8431
8480
|
}
|
|
@@ -8714,7 +8763,7 @@ async function cmdValidate(path) {
|
|
|
8714
8763
|
console.log(heading2("Guard violations:"));
|
|
8715
8764
|
for (const v of violations) {
|
|
8716
8765
|
const vr = v;
|
|
8717
|
-
console.log(` ${
|
|
8766
|
+
console.log(` ${YELLOW11}[${vr.rule}]${RESET16} ${vr.message}`);
|
|
8718
8767
|
if (vr.suggestion) {
|
|
8719
8768
|
console.log(` ${DIM16}Suggestion: ${vr.suggestion}${RESET16}`);
|
|
8720
8769
|
}
|
|
@@ -9048,7 +9097,7 @@ async function cmdInit(args) {
|
|
|
9048
9097
|
console.log(dim3(" Found .decantr/init-seed.json brownfield guidance."));
|
|
9049
9098
|
}
|
|
9050
9099
|
if (detected.existingEssence && !args.existing) {
|
|
9051
|
-
console.log(`${
|
|
9100
|
+
console.log(`${YELLOW11}Warning: decantr.essence.json already exists.${RESET16}`);
|
|
9052
9101
|
const overwrite = await confirm("Overwrite existing configuration?", false);
|
|
9053
9102
|
if (!overwrite) {
|
|
9054
9103
|
console.log(dim3("Cancelled."));
|
|
@@ -9151,7 +9200,7 @@ async function cmdInit(args) {
|
|
|
9151
9200
|
} else if (shouldUseRegistry && !apiAvailable) {
|
|
9152
9201
|
if (!args.blueprint) {
|
|
9153
9202
|
console.log(`
|
|
9154
|
-
${
|
|
9203
|
+
${YELLOW11}You're offline. Scaffolding minimal Decantr project.${RESET16}`);
|
|
9155
9204
|
console.log(
|
|
9156
9205
|
dim3("Run `decantr sync` or `decantr upgrade` when online to pull full registry content.\n")
|
|
9157
9206
|
);
|
|
@@ -9200,7 +9249,7 @@ ${YELLOW10}You're offline. Scaffolding minimal Decantr project.${RESET16}`);
|
|
|
9200
9249
|
return;
|
|
9201
9250
|
}
|
|
9202
9251
|
console.log(`
|
|
9203
|
-
${
|
|
9252
|
+
${YELLOW11}You're offline. Scaffolding Decantr default.${RESET16}`);
|
|
9204
9253
|
console.log(dim3("Run `decantr upgrade` when online, or visit decantr.ai/registry\n"));
|
|
9205
9254
|
selectedBlueprint = "default";
|
|
9206
9255
|
} else if (shouldUseRegistry) {
|
|
@@ -9382,7 +9431,7 @@ ${YELLOW10}You're offline. Scaffolding Decantr default.${RESET16}`);
|
|
|
9382
9431
|
return;
|
|
9383
9432
|
}
|
|
9384
9433
|
console.log(
|
|
9385
|
-
`${
|
|
9434
|
+
`${YELLOW11} Warning: Could not fetch blueprint "${options.blueprint}". Using defaults.${RESET16}`
|
|
9386
9435
|
);
|
|
9387
9436
|
}
|
|
9388
9437
|
} else if (shouldUseRegistry && options.archetype) {
|
|
@@ -9397,7 +9446,7 @@ ${YELLOW10}You're offline. Scaffolding Decantr default.${RESET16}`);
|
|
|
9397
9446
|
return;
|
|
9398
9447
|
}
|
|
9399
9448
|
console.log(
|
|
9400
|
-
`${
|
|
9449
|
+
`${YELLOW11} Warning: Could not fetch archetype "${options.archetype}". Using defaults.${RESET16}`
|
|
9401
9450
|
);
|
|
9402
9451
|
}
|
|
9403
9452
|
}
|
|
@@ -9414,7 +9463,7 @@ ${YELLOW10}You're offline. Scaffolding Decantr default.${RESET16}`);
|
|
|
9414
9463
|
return;
|
|
9415
9464
|
}
|
|
9416
9465
|
console.log(
|
|
9417
|
-
`${
|
|
9466
|
+
`${YELLOW11} Warning: Could not fetch theme "${options.theme}". Using defaults.${RESET16}`
|
|
9418
9467
|
);
|
|
9419
9468
|
}
|
|
9420
9469
|
}
|
|
@@ -9619,7 +9668,7 @@ async function cmdStatus(projectRoot = process.cwd()) {
|
|
|
9619
9668
|
` Guard: ${v4.meta.guard.mode} (DNA: ${v4.meta.guard.dna_enforcement}, Blueprint: ${v4.meta.guard.blueprint_enforcement})`
|
|
9620
9669
|
);
|
|
9621
9670
|
} else {
|
|
9622
|
-
console.log(` ${
|
|
9671
|
+
console.log(` ${YELLOW11}Run \`decantr migrate --to v4\` to upgrade this project.${RESET16}`);
|
|
9623
9672
|
}
|
|
9624
9673
|
} catch (e) {
|
|
9625
9674
|
console.log(` ${RED12}Error reading essence: ${e.message}${RESET16}`);
|
|
@@ -9632,15 +9681,15 @@ async function cmdStatus(projectRoot = process.cwd()) {
|
|
|
9632
9681
|
const syncStatus = projectJson.sync?.status || "unknown";
|
|
9633
9682
|
const lastSync = projectJson.sync?.lastSync || "never";
|
|
9634
9683
|
const source = projectJson.sync?.registrySource || "unknown";
|
|
9635
|
-
const statusColor = syncStatus === "synced" ? GREEN16 :
|
|
9684
|
+
const statusColor = syncStatus === "synced" ? GREEN16 : YELLOW11;
|
|
9636
9685
|
console.log(` Status: ${statusColor}${syncStatus}${RESET16}`);
|
|
9637
9686
|
console.log(` Last sync: ${dim3(lastSync)}`);
|
|
9638
9687
|
console.log(` Source: ${dim3(source)}`);
|
|
9639
9688
|
} catch {
|
|
9640
|
-
console.log(` ${
|
|
9689
|
+
console.log(` ${YELLOW11}Could not read project.json${RESET16}`);
|
|
9641
9690
|
}
|
|
9642
9691
|
} else {
|
|
9643
|
-
console.log(` ${
|
|
9692
|
+
console.log(` ${YELLOW11}No .decantr/project.json found${RESET16}`);
|
|
9644
9693
|
console.log(dim3(' Run "decantr init" to create project files.'));
|
|
9645
9694
|
}
|
|
9646
9695
|
}
|
|
@@ -9653,12 +9702,12 @@ async function cmdSync() {
|
|
|
9653
9702
|
console.log(success3("Sync completed successfully."));
|
|
9654
9703
|
console.log(` Synced: ${result.synced.join(", ")}`);
|
|
9655
9704
|
if (result.failed.length > 0) {
|
|
9656
|
-
console.log(` ${
|
|
9705
|
+
console.log(` ${YELLOW11}Failed: ${result.failed.join(", ")}${RESET16}`);
|
|
9657
9706
|
}
|
|
9658
9707
|
} else {
|
|
9659
|
-
console.log(`${
|
|
9708
|
+
console.log(`${YELLOW11}Could not sync: API unavailable${RESET16}`);
|
|
9660
9709
|
if (result.failed.length > 0) {
|
|
9661
|
-
console.log(` ${
|
|
9710
|
+
console.log(` ${YELLOW11}Failed: ${result.failed.join(", ")}${RESET16}`);
|
|
9662
9711
|
}
|
|
9663
9712
|
}
|
|
9664
9713
|
}
|
|
@@ -9668,7 +9717,7 @@ function printVerificationFindings(findings) {
|
|
|
9668
9717
|
return;
|
|
9669
9718
|
}
|
|
9670
9719
|
for (const finding of findings) {
|
|
9671
|
-
const color = finding.severity === "error" ? RED12 : finding.severity === "warn" ?
|
|
9720
|
+
const color = finding.severity === "error" ? RED12 : finding.severity === "warn" ? YELLOW11 : CYAN9;
|
|
9672
9721
|
console.log(
|
|
9673
9722
|
` ${color}[${finding.severity.toUpperCase()}]${RESET16} ${finding.category}: ${finding.message}`
|
|
9674
9723
|
);
|
|
@@ -10309,7 +10358,7 @@ async function cmdAdoptWorkflow(args) {
|
|
|
10309
10358
|
)
|
|
10310
10359
|
);
|
|
10311
10360
|
} catch (e) {
|
|
10312
|
-
console.log(`${
|
|
10361
|
+
console.log(`${YELLOW11}Pack hydration skipped:${RESET16} ${e.message}`);
|
|
10313
10362
|
console.log(
|
|
10314
10363
|
dim3(
|
|
10315
10364
|
`Run ${compilePacksCommandForProject(projectArg)} after adoption if you want hosted page/review packs.`
|
|
@@ -10320,7 +10369,7 @@ async function cmdAdoptWorkflow(args) {
|
|
|
10320
10369
|
console.log(dim3("Skipping hosted pack hydration in offline mode."));
|
|
10321
10370
|
}
|
|
10322
10371
|
if (runVerify) {
|
|
10323
|
-
const { cmdHealth } = await import("./health-
|
|
10372
|
+
const { cmdHealth } = await import("./health-R7AV5G4V.js");
|
|
10324
10373
|
await cmdHealth(projectRoot, {
|
|
10325
10374
|
browser: runBrowser,
|
|
10326
10375
|
browserBaseUrl: baseUrl,
|
|
@@ -10391,7 +10440,7 @@ async function cmdVerifyWorkflow(args) {
|
|
|
10391
10440
|
return;
|
|
10392
10441
|
}
|
|
10393
10442
|
if (workspaceMode) {
|
|
10394
|
-
const { cmdWorkspace } = await import("./workspace-
|
|
10443
|
+
const { cmdWorkspace } = await import("./workspace-DRHTQ2NG.js");
|
|
10395
10444
|
await cmdWorkspace(process.cwd(), ["workspace", "health", ...withoutWorkflowOnlyFlags(args)]);
|
|
10396
10445
|
return;
|
|
10397
10446
|
}
|
|
@@ -10424,7 +10473,7 @@ async function cmdVerifyWorkflow(args) {
|
|
|
10424
10473
|
}
|
|
10425
10474
|
let guardExitCode;
|
|
10426
10475
|
if (brownfield) {
|
|
10427
|
-
const { cmdHeal, collectCheckIssues } = await import("./heal-
|
|
10476
|
+
const { cmdHeal, collectCheckIssues } = await import("./heal-ZQHEHBUJ.js");
|
|
10428
10477
|
if (quietOutput) {
|
|
10429
10478
|
const result = collectCheckIssues(workspaceInfo.appRoot, { brownfield: true });
|
|
10430
10479
|
guardExitCode = result.issues.some((issue) => issue.type === "error") ? 1 : void 0;
|
|
@@ -10434,7 +10483,7 @@ async function cmdVerifyWorkflow(args) {
|
|
|
10434
10483
|
process.exitCode = void 0;
|
|
10435
10484
|
}
|
|
10436
10485
|
}
|
|
10437
|
-
const { cmdHealth, parseHealthArgs } = await import("./health-
|
|
10486
|
+
const { cmdHealth, parseHealthArgs } = await import("./health-R7AV5G4V.js");
|
|
10438
10487
|
await cmdHealth(workspaceInfo.appRoot, parseHealthArgs(healthArgs));
|
|
10439
10488
|
if (localPatterns) {
|
|
10440
10489
|
const validation = validateLocalLaw(workspaceInfo.appRoot);
|
|
@@ -10442,7 +10491,7 @@ async function cmdVerifyWorkflow(args) {
|
|
|
10442
10491
|
if (!quietOutput) {
|
|
10443
10492
|
console.log("");
|
|
10444
10493
|
console.log(
|
|
10445
|
-
`${
|
|
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))}.`
|
|
10446
10495
|
);
|
|
10447
10496
|
}
|
|
10448
10497
|
process.exitCode = process.exitCode || 1;
|
|
@@ -10458,11 +10507,11 @@ async function cmdVerifyWorkflow(args) {
|
|
|
10458
10507
|
console.log(`${GREEN16}Local rule manifest found:${RESET16} ${validation.rulesPath}`);
|
|
10459
10508
|
} else {
|
|
10460
10509
|
console.log(
|
|
10461
|
-
`${
|
|
10510
|
+
`${YELLOW11}Local rule manifest missing.${RESET16} Run ${cyan3("decantr codify --from-audit")} to propose .decantr/rules.json.`
|
|
10462
10511
|
);
|
|
10463
10512
|
}
|
|
10464
10513
|
for (const warning of validation.warnings.slice(0, 8)) {
|
|
10465
|
-
console.log(`${
|
|
10514
|
+
console.log(`${YELLOW11}warn${RESET16} ${warning}`);
|
|
10466
10515
|
}
|
|
10467
10516
|
if (validation.findings.length > 0) {
|
|
10468
10517
|
console.log("");
|
|
@@ -10615,7 +10664,7 @@ async function cmdTaskWorkflow(args) {
|
|
|
10615
10664
|
console.log("");
|
|
10616
10665
|
console.log(`${BOLD9}Project-owned local law:${RESET16}`);
|
|
10617
10666
|
console.log(
|
|
10618
|
-
` ${
|
|
10667
|
+
` ${YELLOW11}Not codified yet.${RESET16} Run ${cyan3(withProject("decantr codify --from-audit", projectArg))} after adoption.`
|
|
10619
10668
|
);
|
|
10620
10669
|
}
|
|
10621
10670
|
if (context.changedFiles.length > 0) {
|
|
@@ -11414,10 +11463,10 @@ async function main() {
|
|
|
11414
11463
|
case "heal": {
|
|
11415
11464
|
if (command === "heal") {
|
|
11416
11465
|
console.log(
|
|
11417
|
-
`${
|
|
11466
|
+
`${YELLOW11}Note: \`decantr heal\` is deprecated. Use \`decantr check\` instead.${RESET16}`
|
|
11418
11467
|
);
|
|
11419
11468
|
}
|
|
11420
|
-
const { cmdHeal } = await import("./heal-
|
|
11469
|
+
const { cmdHeal } = await import("./heal-ZQHEHBUJ.js");
|
|
11421
11470
|
const { flags } = parseLooseArgs(args);
|
|
11422
11471
|
const workspaceInfo = resolveWorkflowProject(flags, "check");
|
|
11423
11472
|
if (!workspaceInfo) break;
|
|
@@ -11442,7 +11491,7 @@ async function main() {
|
|
|
11442
11491
|
const { flags } = parseLooseArgs(args);
|
|
11443
11492
|
const workspaceInfo = resolveWorkflowProject(flags, "health");
|
|
11444
11493
|
if (!workspaceInfo) break;
|
|
11445
|
-
const { cmdHealth, parseHealthArgs } = await import("./health-
|
|
11494
|
+
const { cmdHealth, parseHealthArgs } = await import("./health-R7AV5G4V.js");
|
|
11446
11495
|
await cmdHealth(workspaceInfo.appRoot, parseHealthArgs(stripProjectArgs(args)));
|
|
11447
11496
|
} catch (e) {
|
|
11448
11497
|
console.error(error2(e.message));
|
|
@@ -11470,7 +11519,7 @@ async function main() {
|
|
|
11470
11519
|
cmdStudioHelp();
|
|
11471
11520
|
break;
|
|
11472
11521
|
}
|
|
11473
|
-
const { cmdStudio, parseStudioArgs } = await import("./studio-
|
|
11522
|
+
const { cmdStudio, parseStudioArgs } = await import("./studio-2734P63C.js");
|
|
11474
11523
|
await cmdStudio(process.cwd(), parseStudioArgs(args));
|
|
11475
11524
|
} catch (e) {
|
|
11476
11525
|
console.error(error2(e.message));
|
|
@@ -11484,7 +11533,7 @@ async function main() {
|
|
|
11484
11533
|
cmdWorkspaceHelp();
|
|
11485
11534
|
break;
|
|
11486
11535
|
}
|
|
11487
|
-
const { cmdWorkspace } = await import("./workspace-
|
|
11536
|
+
const { cmdWorkspace } = await import("./workspace-DRHTQ2NG.js");
|
|
11488
11537
|
await cmdWorkspace(process.cwd(), args);
|
|
11489
11538
|
} catch (e) {
|
|
11490
11539
|
console.error(error2(e.message));
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
sendProjectHealthCiFailedTelemetry,
|
|
4
4
|
sendProjectHealthPromptTelemetry,
|
|
5
5
|
sendProjectHealthReportTelemetry
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-WONPNSSI.js";
|
|
7
7
|
|
|
8
8
|
// src/commands/health.ts
|
|
9
9
|
import { execFileSync } from "child_process";
|
|
@@ -383,6 +383,47 @@ function commandsForFinding(source) {
|
|
|
383
383
|
return ["decantr audit", "decantr health"];
|
|
384
384
|
}
|
|
385
385
|
}
|
|
386
|
+
function detectPackageManager(root) {
|
|
387
|
+
const pkg = readJsonFile(join2(root, "package.json"));
|
|
388
|
+
const declared = pkg?.packageManager?.split("@")[0];
|
|
389
|
+
if (declared === "pnpm" || declared === "npm" || declared === "yarn" || declared === "bun") {
|
|
390
|
+
return declared;
|
|
391
|
+
}
|
|
392
|
+
if (existsSync2(join2(root, "pnpm-lock.yaml"))) return "pnpm";
|
|
393
|
+
if (existsSync2(join2(root, "package-lock.json"))) return "npm";
|
|
394
|
+
if (existsSync2(join2(root, "yarn.lock"))) return "yarn";
|
|
395
|
+
if (existsSync2(join2(root, "bun.lock")) || existsSync2(join2(root, "bun.lockb"))) return "bun";
|
|
396
|
+
return "unknown";
|
|
397
|
+
}
|
|
398
|
+
function buildCommandForProject(workspaceRoot, projectPath) {
|
|
399
|
+
const packageManager = detectPackageManager(workspaceRoot);
|
|
400
|
+
if (projectPath) {
|
|
401
|
+
switch (packageManager) {
|
|
402
|
+
case "pnpm":
|
|
403
|
+
return `pnpm --dir ${projectPath} build`;
|
|
404
|
+
case "yarn":
|
|
405
|
+
return `yarn --cwd ${projectPath} build`;
|
|
406
|
+
case "bun":
|
|
407
|
+
return `bun --cwd ${projectPath} run build`;
|
|
408
|
+
case "npm":
|
|
409
|
+
return `npm --prefix ${projectPath} run build`;
|
|
410
|
+
default:
|
|
411
|
+
return `cd ${projectPath} && npm run build`;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
switch (packageManager) {
|
|
415
|
+
case "pnpm":
|
|
416
|
+
return "pnpm build";
|
|
417
|
+
case "yarn":
|
|
418
|
+
return "yarn build";
|
|
419
|
+
case "bun":
|
|
420
|
+
return "bun run build";
|
|
421
|
+
case "npm":
|
|
422
|
+
return "npm run build";
|
|
423
|
+
default:
|
|
424
|
+
return "npm run build";
|
|
425
|
+
}
|
|
426
|
+
}
|
|
386
427
|
function commandContextForProject(projectRoot) {
|
|
387
428
|
const workspaceInfo = resolveWorkspaceInfo(projectRoot);
|
|
388
429
|
const relativeProjectPath = relative(workspaceInfo.workspaceRoot, projectRoot).replace(
|
|
@@ -394,6 +435,7 @@ function commandContextForProject(projectRoot) {
|
|
|
394
435
|
const essencePath = projectPath ? `${projectPath}/decantr.essence.json` : "decantr.essence.json";
|
|
395
436
|
return {
|
|
396
437
|
projectPath,
|
|
438
|
+
buildCommand: buildCommandForProject(workspaceInfo.workspaceRoot, projectPath),
|
|
397
439
|
compilePacksCommand: `decantr registry compile-packs ${essencePath} --write-context`,
|
|
398
440
|
verifyCommand: `decantr verify${projectFlag}`,
|
|
399
441
|
ciCommand: `decantr ci${projectFlag} --fail-on error`,
|
|
@@ -401,6 +443,7 @@ function commandContextForProject(projectRoot) {
|
|
|
401
443
|
};
|
|
402
444
|
}
|
|
403
445
|
function rewriteHealthCommand(command, context) {
|
|
446
|
+
if (command === "npm run build") return context.buildCommand;
|
|
404
447
|
let rewritten = command.replace(
|
|
405
448
|
/decantr registry compile-packs decantr\.essence\.json --write-context/g,
|
|
406
449
|
context.compilePacksCommand
|
|
@@ -461,17 +504,25 @@ function scopeHealthFindingsToProject(projectRoot, findings) {
|
|
|
461
504
|
message: finding.message,
|
|
462
505
|
evidence: finding.evidence,
|
|
463
506
|
suggestedFix,
|
|
464
|
-
commands
|
|
507
|
+
commands,
|
|
508
|
+
projectPath: context.projectPath
|
|
465
509
|
})
|
|
466
510
|
}
|
|
467
511
|
};
|
|
468
512
|
});
|
|
469
513
|
}
|
|
470
514
|
function buildRemediationPrompt(input) {
|
|
515
|
+
const prefix = input.projectPath ? `${input.projectPath}/` : "";
|
|
516
|
+
const readTargets = [
|
|
517
|
+
`${prefix}DECANTR.md`,
|
|
518
|
+
`${prefix}decantr.essence.json`,
|
|
519
|
+
`${prefix}.decantr/context/scaffold-pack.md`,
|
|
520
|
+
`${prefix}.decantr/context/scaffold.md`
|
|
521
|
+
];
|
|
471
522
|
return [
|
|
472
523
|
"You are fixing one Decantr Project Health finding in this local workspace.",
|
|
473
524
|
"",
|
|
474
|
-
|
|
525
|
+
`Read project-scoped Decantr files if they exist: ${readTargets.map((target) => `\`${target}\``).join(", ")}. For route or page work, read the matching page/section packs before editing.`,
|
|
475
526
|
"",
|
|
476
527
|
`Finding: ${input.id}`,
|
|
477
528
|
`Source: ${input.source}`,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createProjectHealthReport,
|
|
3
3
|
listWorkspaceAppCandidates
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-FACL3NXU.js";
|
|
5
5
|
|
|
6
6
|
// src/commands/workspace.ts
|
|
7
7
|
import { execFileSync } from "child_process";
|
|
@@ -322,7 +322,7 @@ async function cmdWorkspace(workspaceRoot = process.cwd(), args = ["workspace"])
|
|
|
322
322
|
}
|
|
323
323
|
if (unattachedCandidates.length > 0) {
|
|
324
324
|
console.log("");
|
|
325
|
-
console.log("Start by attaching one app:");
|
|
325
|
+
console.log(projects.length > 0 ? "Attach another app:" : "Start by attaching one app:");
|
|
326
326
|
console.log(` ${unattachedCandidates[0].suggestedAdoptCommand}`);
|
|
327
327
|
}
|
|
328
328
|
return;
|
|
@@ -1323,6 +1323,22 @@ var SKIP_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
|
1323
1323
|
".cache"
|
|
1324
1324
|
]);
|
|
1325
1325
|
var MAX_FILE_SIZE = 1024 * 1024;
|
|
1326
|
+
function isNonUiInteractionSource(relativePath) {
|
|
1327
|
+
const normalized2 = relativePath.replace(/\\/g, "/");
|
|
1328
|
+
if (/\.d\.ts$/i.test(normalized2)) return true;
|
|
1329
|
+
if (/(?:^|\/)(?:__tests__|__mocks__|tests?|specs?|fixtures?|mocks?|stories?)(?:\/|$)/i.test(
|
|
1330
|
+
normalized2
|
|
1331
|
+
)) {
|
|
1332
|
+
return true;
|
|
1333
|
+
}
|
|
1334
|
+
if (/\.(?:test|spec|stories?|story|fixture|mock)\.(?:[cm]?[jt]sx?|mdx|html)$/i.test(normalized2)) {
|
|
1335
|
+
return true;
|
|
1336
|
+
}
|
|
1337
|
+
if (/^(?:src\/)?app\/api\//i.test(normalized2)) return true;
|
|
1338
|
+
if (/^(?:src\/)?pages\/api\//i.test(normalized2)) return true;
|
|
1339
|
+
if (/(?:^|\/)route\.[cm]?[jt]s$/i.test(normalized2)) return true;
|
|
1340
|
+
return false;
|
|
1341
|
+
}
|
|
1326
1342
|
function walkSourceTree(rootDir) {
|
|
1327
1343
|
const sources = /* @__PURE__ */ new Map();
|
|
1328
1344
|
function walk2(dir) {
|
|
@@ -1341,12 +1357,14 @@ function walkSourceTree(rootDir) {
|
|
|
1341
1357
|
} catch {
|
|
1342
1358
|
continue;
|
|
1343
1359
|
}
|
|
1360
|
+
const relativePath = relative3(rootDir, fullPath) || entry;
|
|
1344
1361
|
if (s.isDirectory()) {
|
|
1345
1362
|
walk2(fullPath);
|
|
1346
1363
|
} else if (s.isFile() && SCAN_EXTENSIONS.has(extname2(entry))) {
|
|
1347
1364
|
if (s.size > MAX_FILE_SIZE) continue;
|
|
1365
|
+
if (isNonUiInteractionSource(relativePath)) continue;
|
|
1348
1366
|
try {
|
|
1349
|
-
sources.set(
|
|
1367
|
+
sources.set(relativePath, readFileSync8(fullPath, "utf8"));
|
|
1350
1368
|
} catch {
|
|
1351
1369
|
}
|
|
1352
1370
|
}
|
|
@@ -10,8 +10,8 @@ import {
|
|
|
10
10
|
renderProjectHealthCiWorkflow,
|
|
11
11
|
shouldFailHealth,
|
|
12
12
|
writeProjectHealthCiWorkflow
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-FACL3NXU.js";
|
|
14
|
+
import "./chunk-WONPNSSI.js";
|
|
15
15
|
export {
|
|
16
16
|
cmdHealth,
|
|
17
17
|
collectDesignTokenEvidence,
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "./chunk-
|
|
1
|
+
import "./chunk-3KJ46XY7.js";
|
|
2
2
|
import "./chunk-RXF7ZYGK.js";
|
|
3
|
-
import "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
import "./chunk-VCUFZB45.js";
|
|
4
|
+
import "./chunk-FACL3NXU.js";
|
|
5
|
+
import "./chunk-WONPNSSI.js";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createWorkspaceHealthReport
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VCUFZB45.js";
|
|
4
4
|
import {
|
|
5
5
|
createProjectHealthReport
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-FACL3NXU.js";
|
|
7
7
|
import {
|
|
8
8
|
sendStudioHealthRefreshedTelemetry,
|
|
9
9
|
sendStudioStartedTelemetry
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-WONPNSSI.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-VCUFZB45.js";
|
|
11
|
+
import "./chunk-FACL3NXU.js";
|
|
12
|
+
import "./chunk-WONPNSSI.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.5",
|
|
4
4
|
"description": "Decantr CLI - scaffold, audit, inspect Project Health, and maintain Decantr projects from the terminal",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"decantr",
|
|
@@ -48,11 +48,11 @@
|
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"ajv": "^8.20.0",
|
|
51
|
-
"@decantr/
|
|
51
|
+
"@decantr/core": "2.1.0",
|
|
52
52
|
"@decantr/registry": "2.2.0",
|
|
53
|
-
"@decantr/verifier": "2.3.3",
|
|
54
53
|
"@decantr/telemetry": "2.2.1",
|
|
55
|
-
"@decantr/
|
|
54
|
+
"@decantr/essence-spec": "2.0.1",
|
|
55
|
+
"@decantr/verifier": "2.3.3"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"build": "tsup",
|