@decantr/cli 2.6.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -19
- package/dist/bin.js +1 -1
- package/dist/{chunk-Q5OFRQY6.js → chunk-ZYHR3BGT.js} +638 -10
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -17,9 +17,11 @@ Or run it without installing:
|
|
|
17
17
|
npx @decantr/cli new my-app --blueprint=esports-hq
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
+
Use `decantr setup` when you are unsure which path applies. It detects whether the repo is empty, already attached, or a Brownfield app and recommends the next command.
|
|
20
21
|
Use `decantr new` for a greenfield workspace in a fresh directory. With a blueprint/archetype it uses the runnable adapter and Decantr CSS; without registry content it creates a contract-only workspace unless you explicitly pass `--adoption=decantr-css`.
|
|
21
|
-
Use `decantr
|
|
22
|
-
Use `decantr
|
|
22
|
+
Use `decantr adopt` when you already have an app and want Decantr governance without adopting a blueprint. Brownfield attach is proposal-driven: Decantr inventories the app, writes an observed essence proposal, and only applies it when you explicitly accept or merge it.
|
|
23
|
+
Use `decantr task` before asking an LLM to modify a route, and `decantr verify` after the edit. Use `decantr codify` when you want project-owned UI patterns such as local button/card/shell standards to appear in future task context.
|
|
24
|
+
Use `decantr init`, `decantr analyze`, `decantr check`, and `decantr health` as advanced primitives when you need direct control over one step.
|
|
23
25
|
|
|
24
26
|
Current starter adapter availability:
|
|
25
27
|
|
|
@@ -35,6 +37,12 @@ Current starter adapter availability:
|
|
|
35
37
|
Explicit workflow/adoption flags:
|
|
36
38
|
|
|
37
39
|
```bash
|
|
40
|
+
decantr setup
|
|
41
|
+
decantr adopt --base-url http://localhost:3000 --evidence --yes
|
|
42
|
+
decantr task /feed "add saved recipe actions"
|
|
43
|
+
decantr verify --brownfield
|
|
44
|
+
decantr codify
|
|
45
|
+
decantr codify --accept
|
|
38
46
|
decantr init --workflow=greenfield --adoption=contract-only
|
|
39
47
|
decantr analyze
|
|
40
48
|
decantr init --existing --accept-proposal
|
|
@@ -57,11 +65,12 @@ Monorepos store both `workspaceRoot` and `appRoot`. In non-interactive workspace
|
|
|
57
65
|
|
|
58
66
|
Assistant rule integration is preview-first: `--assistant-bridge=preview` writes `.decantr/context/assistant-bridge.md`, `decantr rules preview` prints the bridge, and `--assistant-bridge=apply` or `decantr rules apply` mutates supported rule files with idempotent marked blocks.
|
|
59
67
|
|
|
60
|
-
Brownfield analysis also writes `.decantr/doctrine-map.json`, a ranked source-precedence map across security/data, architecture, design-system, workflow/CI, feature/business, assistant-specific, stale, and unsafe-to-cite evidence.
|
|
68
|
+
Brownfield analysis also writes `.decantr/doctrine-map.json`, a ranked source-precedence map across security/data, architecture, design-system, workflow/CI, feature/business, assistant-specific, stale, and unsafe-to-cite evidence. It also writes `.decantr/brownfield-intelligence.json`, `.decantr/theme-inventory.json`, and `.decantr/enrichment-backlog.md`. The proposal groups routes into observed semantic domains such as auth, RBAC, billing, reporting, facilities, settings, and public surfaces across Next App/Pages Router, React Router, Angular Router, SvelteKit, Vue Router, and Nuxt file routes. Existing styling systems such as Tailwind, Bootstrap, MUI, Chakra, plain CSS, and Decantr CSS are observed as evidence instead of replaced. Theme variants are observed in the theme inventory without changing Essence V4. `decantr verify --brownfield` uses the Brownfield guard layer to flag actionable missing doctrine coverage, unsafe context, missing assistant bridges, style drift, and unsafe defaults without treating current database migrations as stale docs.
|
|
61
69
|
|
|
62
70
|
## What It Does
|
|
63
71
|
|
|
64
72
|
- scaffolds Decantr projects from blueprints, archetypes, or prompts
|
|
73
|
+
- guides users through human workflow commands: setup, adopt, task, verify, and codify
|
|
65
74
|
- supports explicit workflow lanes: greenfield blueprint, greenfield contract-only, brownfield adoption, and hybrid composition
|
|
66
75
|
- generates execution-pack context files for AI coding assistants
|
|
67
76
|
- audits projects against Decantr contracts
|
|
@@ -75,10 +84,12 @@ Brownfield analysis also writes `.decantr/doctrine-map.json`, a ranked source-pr
|
|
|
75
84
|
## Common Commands
|
|
76
85
|
|
|
77
86
|
```bash
|
|
87
|
+
decantr setup
|
|
78
88
|
decantr new my-app --blueprint=esports-hq
|
|
79
|
-
decantr
|
|
80
|
-
decantr
|
|
81
|
-
decantr
|
|
89
|
+
decantr adopt --base-url http://localhost:3000 --evidence --yes
|
|
90
|
+
decantr task /feed "add saved recipe actions"
|
|
91
|
+
decantr verify --brownfield --local-patterns
|
|
92
|
+
decantr codify
|
|
82
93
|
decantr init --existing --blueprint=esports-hq
|
|
83
94
|
decantr init --workflow=greenfield --adoption=contract-only
|
|
84
95
|
decantr rules preview
|
|
@@ -86,12 +97,12 @@ decantr rules apply
|
|
|
86
97
|
decantr magic "AI-native analytics workspace"
|
|
87
98
|
decantr audit
|
|
88
99
|
decantr check
|
|
89
|
-
decantr
|
|
100
|
+
decantr verify --ci --fail-on error
|
|
90
101
|
decantr studio --port 4319 --host 127.0.0.1
|
|
91
102
|
decantr telemetry status
|
|
92
103
|
decantr telemetry explain
|
|
93
104
|
decantr telemetry link --enable --org <org-slug>
|
|
94
|
-
decantr content
|
|
105
|
+
decantr content check --ci --fail-on error
|
|
95
106
|
decantr registry summary --namespace @official --json
|
|
96
107
|
decantr list blueprints --blueprint-set featured
|
|
97
108
|
decantr list blueprints --blueprint-set certified
|
|
@@ -103,9 +114,16 @@ decantr showcase verification --json
|
|
|
103
114
|
|
|
104
115
|
## Project Health And Studio
|
|
105
116
|
|
|
106
|
-
`decantr
|
|
117
|
+
`decantr verify` is the workflow command most users should run locally and in CI. It delegates to Project Health, can add Brownfield guard validation with `--brownfield`, requires an accepted local pattern pack with `--local-patterns`, supports workspace mode, and writes evidence to `.decantr/evidence/latest.json` by default when `--evidence` is used.
|
|
118
|
+
|
|
119
|
+
`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.
|
|
107
120
|
|
|
108
121
|
```bash
|
|
122
|
+
decantr verify
|
|
123
|
+
decantr verify --brownfield --local-patterns
|
|
124
|
+
decantr verify --base-url http://localhost:3000 --evidence
|
|
125
|
+
decantr verify --since-baseline
|
|
126
|
+
decantr verify init-ci --project apps/registry
|
|
109
127
|
decantr health
|
|
110
128
|
decantr health --format json
|
|
111
129
|
decantr health --markdown --output health.md
|
|
@@ -118,18 +136,18 @@ decantr health --save-baseline
|
|
|
118
136
|
decantr health --since-baseline
|
|
119
137
|
decantr health --design-tokens .decantr/design/figma-tokens.json
|
|
120
138
|
decantr health --json --output decantr-health.json
|
|
121
|
-
decantr
|
|
122
|
-
decantr
|
|
123
|
-
decantr
|
|
124
|
-
decantr
|
|
139
|
+
decantr verify init-ci
|
|
140
|
+
decantr verify init-ci --fail-on warn --cli-version latest --force
|
|
141
|
+
decantr verify init-ci --project apps/registry
|
|
142
|
+
decantr verify init-ci --workspace
|
|
125
143
|
decantr workspace list
|
|
126
|
-
decantr workspace
|
|
144
|
+
decantr verify --workspace --changed --since origin/main
|
|
127
145
|
decantr export --to figma-tokens
|
|
128
146
|
```
|
|
129
147
|
|
|
130
148
|
Use `--json` for machines and schema validation, `--markdown` for CI 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. `--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 setup finding, not a crash. `--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. `--ci --fail-on error` fails only when blocking errors exist; `--ci --fail-on warn` also fails on warnings.
|
|
131
149
|
|
|
132
|
-
`decantr
|
|
150
|
+
`decantr verify init-ci` installs `.github/workflows/decantr-health.yml` for GitHub Actions. The generated workflow installs project dependencies, writes JSON/markdown health artifacts, gates with the Project Health CI command, appends the markdown report to the GitHub step summary, and uploads both files as artifacts. Use `--force` to replace an existing workflow, `--fail-on warn` for stricter repositories, or `--cli-version <version|latest>` to pin the package used by CI. In monorepos, add `--project <path>` from the repository root; dependency install stays at the root while health runs inside the app contract and uploads artifacts from that project path. Use `--workspace` to generate an aggregate gate that runs `decantr workspace health` from the repository root and uploads `.decantr/workspace-health.json` plus `.decantr/workspace-health.md`.
|
|
133
151
|
|
|
134
152
|
`decantr workspace` is the monorepo reliability namespace. It discovers Decantr projects from `.decantr/workspace.json` or by finding `decantr.essence.json` files, runs projects with deterministic ordering, concurrency, per-project timeout, failure isolation, and aggregate JSON, and can limit a run to changed projects:
|
|
135
153
|
|
|
@@ -137,7 +155,7 @@ Use `--json` for machines and schema validation, `--markdown` for CI summaries,
|
|
|
137
155
|
decantr workspace list
|
|
138
156
|
decantr workspace health
|
|
139
157
|
decantr workspace health --json --output .decantr/workspace-health.json
|
|
140
|
-
decantr workspace
|
|
158
|
+
decantr verify --workspace --changed --since origin/main
|
|
141
159
|
```
|
|
142
160
|
|
|
143
161
|
`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`.
|
|
@@ -181,9 +199,11 @@ decantr telemetry link --enable --org <org-slug>
|
|
|
181
199
|
|
|
182
200
|
## Content Health
|
|
183
201
|
|
|
184
|
-
`decantr content
|
|
202
|
+
`decantr content check` is the preferred content-author workflow for registry content repositories such as `decantr-content`. `decantr content-health` remains as a backward-compatible primitive. Content Health is separate from Project Health: Project Health checks an end-user app against its Decantr contract, while Content Health checks published content inputs before they flow into the hosted registry.
|
|
185
203
|
|
|
186
204
|
```bash
|
|
205
|
+
decantr content check
|
|
206
|
+
decantr content check --ci --fail-on error
|
|
187
207
|
decantr content-health
|
|
188
208
|
decantr content-health --json
|
|
189
209
|
decantr content-health --markdown --output content-health.md
|
|
@@ -237,7 +257,7 @@ It covers:
|
|
|
237
257
|
|
|
238
258
|
- greenfield blueprint bootstrap
|
|
239
259
|
- greenfield contract-only
|
|
240
|
-
- brownfield `analyze -> init --existing --accept-proposal -> check --brownfield`
|
|
260
|
+
- brownfield `adopt -> task -> verify`, with `analyze -> init --existing --accept-proposal -> check --brownfield` still covered as primitives
|
|
241
261
|
- brownfield doctrine maps and contract coverage checks
|
|
242
262
|
- brownfield semantic route-domain sectioning
|
|
243
263
|
- direct brownfield compatibility init
|
|
@@ -270,7 +290,7 @@ Recommended read order for AI-assisted scaffolding:
|
|
|
270
290
|
|
|
271
291
|
Treat the compiled execution packs as the source of truth. Use the narrative docs as secondary explanation, start with the shell and route structure first, and run `decantr check` plus `decantr audit` after implementation.
|
|
272
292
|
|
|
273
|
-
For a broader health pass, run `decantr
|
|
293
|
+
For a broader health pass, run `decantr verify` after `refresh`, before opening a pull request, or inside CI. Install the default GitHub Actions gate with `decantr verify init-ci`. Findings include remediation commands and can be turned into focused AI prompts with `decantr health --prompt <finding-id>`.
|
|
274
294
|
|
|
275
295
|
For cold-start harness or certification runs, use only the scaffolded workspace files as the contract. If local scaffold files disagree, stop and report the mismatch rather than relying on repo-global Decantr assumptions.
|
|
276
296
|
|
package/dist/bin.js
CHANGED
|
@@ -8293,14 +8293,483 @@ ${BOLD7}Examples:${RESET14}
|
|
|
8293
8293
|
process.exitCode = 1;
|
|
8294
8294
|
}
|
|
8295
8295
|
}
|
|
8296
|
+
function parseLooseArgs(args, startIndex = 1) {
|
|
8297
|
+
const flags = {};
|
|
8298
|
+
const positional = [];
|
|
8299
|
+
for (let index = startIndex; index < args.length; index += 1) {
|
|
8300
|
+
const arg = args[index];
|
|
8301
|
+
if (arg === "-y") {
|
|
8302
|
+
flags.yes = true;
|
|
8303
|
+
continue;
|
|
8304
|
+
}
|
|
8305
|
+
if (arg.startsWith("--no-")) {
|
|
8306
|
+
flags[arg.slice(5)] = false;
|
|
8307
|
+
continue;
|
|
8308
|
+
}
|
|
8309
|
+
if (arg.startsWith("--")) {
|
|
8310
|
+
const body = arg.slice(2);
|
|
8311
|
+
const equalsIndex = body.indexOf("=");
|
|
8312
|
+
if (equalsIndex !== -1) {
|
|
8313
|
+
flags[body.slice(0, equalsIndex)] = body.slice(equalsIndex + 1);
|
|
8314
|
+
continue;
|
|
8315
|
+
}
|
|
8316
|
+
if (args[index + 1] && !args[index + 1].startsWith("-")) {
|
|
8317
|
+
flags[body] = args[++index];
|
|
8318
|
+
} else {
|
|
8319
|
+
flags[body] = true;
|
|
8320
|
+
}
|
|
8321
|
+
continue;
|
|
8322
|
+
}
|
|
8323
|
+
positional.push(arg);
|
|
8324
|
+
}
|
|
8325
|
+
return { flags, positional };
|
|
8326
|
+
}
|
|
8327
|
+
function flagString(flags, key) {
|
|
8328
|
+
const value = flags[key];
|
|
8329
|
+
return typeof value === "string" ? value : void 0;
|
|
8330
|
+
}
|
|
8331
|
+
function flagBoolean(flags, key, defaultValue = false) {
|
|
8332
|
+
const value = flags[key];
|
|
8333
|
+
if (typeof value === "boolean") return value;
|
|
8334
|
+
if (typeof value === "string") return value !== "false";
|
|
8335
|
+
return defaultValue;
|
|
8336
|
+
}
|
|
8337
|
+
function withoutWorkflowOnlyFlags(args) {
|
|
8338
|
+
const stripped = [];
|
|
8339
|
+
const flagsWithValues = /* @__PURE__ */ new Set(["--project"]);
|
|
8340
|
+
for (let index = 1; index < args.length; index += 1) {
|
|
8341
|
+
const arg = args[index];
|
|
8342
|
+
if (arg === "--brownfield" || arg === "--local-patterns" || arg === "--workspace" || arg === "--baseline") {
|
|
8343
|
+
continue;
|
|
8344
|
+
}
|
|
8345
|
+
if (arg.startsWith("--project=")) {
|
|
8346
|
+
continue;
|
|
8347
|
+
}
|
|
8348
|
+
if (flagsWithValues.has(arg)) {
|
|
8349
|
+
index += 1;
|
|
8350
|
+
continue;
|
|
8351
|
+
}
|
|
8352
|
+
stripped.push(arg);
|
|
8353
|
+
}
|
|
8354
|
+
return stripped;
|
|
8355
|
+
}
|
|
8356
|
+
function resolveWorkflowProject(flags) {
|
|
8357
|
+
const projectArg = flagString(flags, "project");
|
|
8358
|
+
const workspaceInfo = resolveWorkspaceInfo(process.cwd(), projectArg);
|
|
8359
|
+
if (workspaceInfo.requiresProjectSelection) {
|
|
8360
|
+
console.log(error3("This looks like a workspace root with multiple app candidates."));
|
|
8361
|
+
console.log(dim3(`Use --project=<path>. Candidates: ${workspaceInfo.appCandidates.join(", ")}`));
|
|
8362
|
+
process.exitCode = 1;
|
|
8363
|
+
return null;
|
|
8364
|
+
}
|
|
8365
|
+
return workspaceInfo;
|
|
8366
|
+
}
|
|
8367
|
+
function printWorkflowPlan(title, steps) {
|
|
8368
|
+
console.log(heading2(title));
|
|
8369
|
+
console.log(" Decantr will run this workflow:");
|
|
8370
|
+
for (const step of steps) {
|
|
8371
|
+
console.log(` ${cyan3(step)}`);
|
|
8372
|
+
}
|
|
8373
|
+
console.log("");
|
|
8374
|
+
}
|
|
8375
|
+
async function cmdSetupWorkflow(args) {
|
|
8376
|
+
const { flags } = parseLooseArgs(args);
|
|
8377
|
+
const workspaceInfo = resolveWorkflowProject(flags);
|
|
8378
|
+
if (!workspaceInfo) return;
|
|
8379
|
+
const detected = detectProject(workspaceInfo.appRoot);
|
|
8380
|
+
const hasFootprint = detected.framework !== "unknown" || detected.packageManager !== "unknown" || detected.hasTypeScript || detected.hasTailwind || detected.existingRuleFiles.length > 0;
|
|
8381
|
+
console.log(heading2("Decantr Setup"));
|
|
8382
|
+
console.log(` Project: ${workspaceInfo.appRoot}`);
|
|
8383
|
+
console.log(` Detected: ${formatDetection(detected)}`);
|
|
8384
|
+
console.log("");
|
|
8385
|
+
if (detected.existingEssence) {
|
|
8386
|
+
console.log(`${BOLD7}Recommended path:${RESET14} maintain an attached Decantr project`);
|
|
8387
|
+
console.log(` ${cyan3('decantr task <route> "<change>"')} Prepare LLM context before edits`);
|
|
8388
|
+
console.log(` ${cyan3("decantr verify")} Run local health and drift checks`);
|
|
8389
|
+
console.log(` ${cyan3("decantr codify")} Propose project-owned UI patterns`);
|
|
8390
|
+
return;
|
|
8391
|
+
}
|
|
8392
|
+
if (hasFootprint) {
|
|
8393
|
+
console.log(`${BOLD7}Recommended path:${RESET14} brownfield adoption`);
|
|
8394
|
+
console.log(` ${cyan3("decantr adopt --yes")} Analyze, attach, and verify`);
|
|
8395
|
+
console.log(
|
|
8396
|
+
` ${cyan3("decantr adopt --base-url http://localhost:3000 --evidence --yes")} Include visual evidence`
|
|
8397
|
+
);
|
|
8398
|
+
console.log(` ${cyan3("decantr codify")} Propose local UI law`);
|
|
8399
|
+
return;
|
|
8400
|
+
}
|
|
8401
|
+
console.log(`${BOLD7}Recommended path:${RESET14} greenfield start`);
|
|
8402
|
+
console.log(` ${cyan3("decantr new my-app --blueprint=<slug>")}`);
|
|
8403
|
+
console.log(` ${cyan3("decantr init --workflow=greenfield --adoption=contract-only")}`);
|
|
8404
|
+
}
|
|
8405
|
+
async function cmdAdoptWorkflow(args) {
|
|
8406
|
+
const { flags } = parseLooseArgs(args);
|
|
8407
|
+
const workspaceInfo = resolveWorkflowProject(flags);
|
|
8408
|
+
if (!workspaceInfo) return;
|
|
8409
|
+
const projectRoot = workspaceInfo.appRoot;
|
|
8410
|
+
const dryRun = flagBoolean(flags, "dry-run");
|
|
8411
|
+
const yes = flagBoolean(flags, "yes") || flagBoolean(flags, "y");
|
|
8412
|
+
const baseUrl = flagString(flags, "base-url");
|
|
8413
|
+
const runVerify = flagBoolean(flags, "verify", true);
|
|
8414
|
+
const runBrowser = flagBoolean(flags, "browser") || Boolean(baseUrl);
|
|
8415
|
+
const evidence = flagBoolean(flags, "evidence") || runBrowser;
|
|
8416
|
+
const saveBaseline = flagBoolean(flags, "baseline", true) || flagBoolean(flags, "save-baseline");
|
|
8417
|
+
const initCi = flagBoolean(flags, "ci") || flagBoolean(flags, "init-ci");
|
|
8418
|
+
const assistantBridge = flagString(flags, "assistant-bridge");
|
|
8419
|
+
const hasEssence = existsSync27(join28(projectRoot, "decantr.essence.json"));
|
|
8420
|
+
const proposalFlag = flagBoolean(flags, "replace-essence") ? "--replace-essence" : flagBoolean(flags, "merge-proposal") || hasEssence ? "--merge-proposal" : "--accept-proposal";
|
|
8421
|
+
const steps = [
|
|
8422
|
+
"analyze current app and write .decantr/brownfield intelligence",
|
|
8423
|
+
`init --existing ${proposalFlag} as contract-only Brownfield`
|
|
8424
|
+
];
|
|
8425
|
+
if (runVerify) {
|
|
8426
|
+
steps.push(
|
|
8427
|
+
runBrowser ? "verify with Project Health, browser evidence, visual manifest, and baseline" : "verify with Project Health and baseline"
|
|
8428
|
+
);
|
|
8429
|
+
}
|
|
8430
|
+
if (initCi) {
|
|
8431
|
+
steps.push("install Project Health CI gate");
|
|
8432
|
+
}
|
|
8433
|
+
printWorkflowPlan("Decantr Adopt", steps);
|
|
8434
|
+
if (dryRun) {
|
|
8435
|
+
console.log(dim3("Dry run only. No files were written."));
|
|
8436
|
+
return;
|
|
8437
|
+
}
|
|
8438
|
+
if (!yes) {
|
|
8439
|
+
const ok = await confirm("Run this Brownfield adoption workflow?", false);
|
|
8440
|
+
if (!ok) {
|
|
8441
|
+
console.log(dim3("Cancelled."));
|
|
8442
|
+
return;
|
|
8443
|
+
}
|
|
8444
|
+
}
|
|
8445
|
+
await cmdAnalyze(projectRoot, workspaceInfo);
|
|
8446
|
+
if (process.exitCode && process.exitCode !== 0) return;
|
|
8447
|
+
await cmdInit({
|
|
8448
|
+
existing: true,
|
|
8449
|
+
yes: true,
|
|
8450
|
+
project: flagString(flags, "project"),
|
|
8451
|
+
"accept-proposal": proposalFlag === "--accept-proposal",
|
|
8452
|
+
"merge-proposal": proposalFlag === "--merge-proposal",
|
|
8453
|
+
"replace-essence": proposalFlag === "--replace-essence",
|
|
8454
|
+
"assistant-bridge": assistantBridge,
|
|
8455
|
+
telemetry: flagBoolean(flags, "telemetry")
|
|
8456
|
+
});
|
|
8457
|
+
if (process.exitCode && process.exitCode !== 0) return;
|
|
8458
|
+
if (runVerify) {
|
|
8459
|
+
const { cmdHealth } = await import("./health-ETZXWGTW.js");
|
|
8460
|
+
await cmdHealth(projectRoot, {
|
|
8461
|
+
browser: runBrowser,
|
|
8462
|
+
browserBaseUrl: baseUrl,
|
|
8463
|
+
evidence,
|
|
8464
|
+
output: evidence ? ".decantr/evidence/latest.json" : void 0,
|
|
8465
|
+
saveBaseline
|
|
8466
|
+
});
|
|
8467
|
+
}
|
|
8468
|
+
if (initCi) {
|
|
8469
|
+
const { cmdHealth } = await import("./health-ETZXWGTW.js");
|
|
8470
|
+
const ciRoot = flagString(flags, "project") ? process.cwd() : projectRoot;
|
|
8471
|
+
await cmdHealth(ciRoot, {
|
|
8472
|
+
initCi: {
|
|
8473
|
+
projectPath: flagString(flags, "project"),
|
|
8474
|
+
failOn: "error"
|
|
8475
|
+
}
|
|
8476
|
+
});
|
|
8477
|
+
}
|
|
8478
|
+
console.log("");
|
|
8479
|
+
console.log(`${BOLD7}Next useful commands:${RESET14}`);
|
|
8480
|
+
console.log(` ${cyan3('decantr task <route> "<change>"')} Give your LLM route-specific context`);
|
|
8481
|
+
console.log(` ${cyan3("decantr codify")} Propose project-owned UI patterns`);
|
|
8482
|
+
console.log(` ${cyan3("decantr verify --since-baseline")} Compare future work against this baseline`);
|
|
8483
|
+
}
|
|
8484
|
+
async function cmdVerifyWorkflow(args) {
|
|
8485
|
+
const { flags } = parseLooseArgs(args);
|
|
8486
|
+
const workspaceMode = flagBoolean(flags, "workspace");
|
|
8487
|
+
if (args[1] === "init-ci") {
|
|
8488
|
+
const { cmdHealth: cmdHealth2, parseHealthArgs: parseHealthArgs2 } = await import("./health-ETZXWGTW.js");
|
|
8489
|
+
await cmdHealth2(process.cwd(), parseHealthArgs2(["health", ...args.slice(1)]));
|
|
8490
|
+
return;
|
|
8491
|
+
}
|
|
8492
|
+
if (workspaceMode) {
|
|
8493
|
+
const { cmdWorkspace } = await import("./workspace-KSFWRZEX.js");
|
|
8494
|
+
await cmdWorkspace(process.cwd(), ["workspace", "health", ...withoutWorkflowOnlyFlags(args)]);
|
|
8495
|
+
return;
|
|
8496
|
+
}
|
|
8497
|
+
const workspaceInfo = resolveWorkflowProject(flags);
|
|
8498
|
+
if (!workspaceInfo) return;
|
|
8499
|
+
const brownfield = flagBoolean(flags, "brownfield");
|
|
8500
|
+
const localPatterns = flagBoolean(flags, "local-patterns");
|
|
8501
|
+
const evidence = flagBoolean(flags, "evidence");
|
|
8502
|
+
const baseUrl = flagString(flags, "base-url");
|
|
8503
|
+
const healthArgs = ["health", ...withoutWorkflowOnlyFlags(args)];
|
|
8504
|
+
if (flagBoolean(flags, "baseline") && !healthArgs.includes("--save-baseline")) {
|
|
8505
|
+
healthArgs.push("--save-baseline");
|
|
8506
|
+
}
|
|
8507
|
+
if (evidence && !flagString(flags, "output")) {
|
|
8508
|
+
healthArgs.push("--output", ".decantr/evidence/latest.json");
|
|
8509
|
+
}
|
|
8510
|
+
if (baseUrl && !healthArgs.includes("--browser")) {
|
|
8511
|
+
healthArgs.push("--browser");
|
|
8512
|
+
}
|
|
8513
|
+
const quietOutput = flagBoolean(flags, "json") || flagBoolean(flags, "ci") || Boolean(flagString(flags, "output"));
|
|
8514
|
+
if (!quietOutput) {
|
|
8515
|
+
console.log(heading2("Decantr Verify"));
|
|
8516
|
+
console.log(
|
|
8517
|
+
dim3(
|
|
8518
|
+
brownfield ? "Running Brownfield guard validation before Project Health." : "Running Project Health as the canonical reliability gate."
|
|
8519
|
+
)
|
|
8520
|
+
);
|
|
8521
|
+
console.log("");
|
|
8522
|
+
}
|
|
8523
|
+
let guardExitCode;
|
|
8524
|
+
if (brownfield) {
|
|
8525
|
+
const { cmdHeal, collectCheckIssues } = await import("./heal-ZYD6NVGE.js");
|
|
8526
|
+
if (quietOutput) {
|
|
8527
|
+
const result = collectCheckIssues(workspaceInfo.appRoot, { brownfield: true });
|
|
8528
|
+
guardExitCode = result.issues.some((issue) => issue.type === "error") ? 1 : void 0;
|
|
8529
|
+
} else {
|
|
8530
|
+
await cmdHeal(workspaceInfo.appRoot, { brownfield: true });
|
|
8531
|
+
guardExitCode = process.exitCode;
|
|
8532
|
+
process.exitCode = void 0;
|
|
8533
|
+
}
|
|
8534
|
+
}
|
|
8535
|
+
const { cmdHealth, parseHealthArgs } = await import("./health-ETZXWGTW.js");
|
|
8536
|
+
await cmdHealth(workspaceInfo.appRoot, parseHealthArgs(healthArgs));
|
|
8537
|
+
if (localPatterns) {
|
|
8538
|
+
const localPatternsPath = join28(workspaceInfo.appRoot, ".decantr", "local-patterns.json");
|
|
8539
|
+
if (!existsSync27(localPatternsPath)) {
|
|
8540
|
+
console.log("");
|
|
8541
|
+
console.log(
|
|
8542
|
+
`${YELLOW9}Local pattern pack missing.${RESET14} Run ${cyan3("decantr codify --accept")} after reviewing the proposal.`
|
|
8543
|
+
);
|
|
8544
|
+
process.exitCode = process.exitCode || 1;
|
|
8545
|
+
} else {
|
|
8546
|
+
console.log("");
|
|
8547
|
+
console.log(`${GREEN14}Local pattern pack found:${RESET14} ${localPatternsPath}`);
|
|
8548
|
+
}
|
|
8549
|
+
}
|
|
8550
|
+
if (guardExitCode && guardExitCode !== 0 && (!process.exitCode || process.exitCode === 0)) {
|
|
8551
|
+
process.exitCode = guardExitCode;
|
|
8552
|
+
}
|
|
8553
|
+
}
|
|
8554
|
+
function readJsonIfPresent(path) {
|
|
8555
|
+
if (!existsSync27(path)) return null;
|
|
8556
|
+
try {
|
|
8557
|
+
return JSON.parse(readFileSync20(path, "utf-8"));
|
|
8558
|
+
} catch {
|
|
8559
|
+
return null;
|
|
8560
|
+
}
|
|
8561
|
+
}
|
|
8562
|
+
async function cmdTaskWorkflow(args) {
|
|
8563
|
+
const { flags, positional } = parseLooseArgs(args);
|
|
8564
|
+
const workspaceInfo = resolveWorkflowProject(flags);
|
|
8565
|
+
if (!workspaceInfo) return;
|
|
8566
|
+
const routeInput = positional[0];
|
|
8567
|
+
if (!routeInput) {
|
|
8568
|
+
console.error(error3('Usage: decantr task <route> ["task summary"] [--project <path>] [--json]'));
|
|
8569
|
+
process.exitCode = 1;
|
|
8570
|
+
return;
|
|
8571
|
+
}
|
|
8572
|
+
const route = routeInput.startsWith("/") ? routeInput : `/${routeInput}`;
|
|
8573
|
+
const taskSummary = positional.slice(1).join(" ").trim();
|
|
8574
|
+
const essencePath = join28(workspaceInfo.appRoot, "decantr.essence.json");
|
|
8575
|
+
const essence = readJsonIfPresent(essencePath);
|
|
8576
|
+
if (!essence) {
|
|
8577
|
+
console.error(error3("No decantr.essence.json found. Run `decantr adopt` or `decantr init` first."));
|
|
8578
|
+
process.exitCode = 1;
|
|
8579
|
+
return;
|
|
8580
|
+
}
|
|
8581
|
+
if (!isV47(essence)) {
|
|
8582
|
+
console.error(error3("Task context requires Essence v4. Run `decantr migrate --to v4` first."));
|
|
8583
|
+
process.exitCode = 1;
|
|
8584
|
+
return;
|
|
8585
|
+
}
|
|
8586
|
+
const target = essence.blueprint.routes?.[route];
|
|
8587
|
+
if (!target) {
|
|
8588
|
+
const knownRoutes = Object.keys(essence.blueprint.routes ?? {}).sort();
|
|
8589
|
+
console.error(error3(`Route not found in Decantr contract: ${route}`));
|
|
8590
|
+
console.error(dim3(`Known routes: ${knownRoutes.join(", ") || "none"}`));
|
|
8591
|
+
process.exitCode = 1;
|
|
8592
|
+
return;
|
|
8593
|
+
}
|
|
8594
|
+
const section = essence.blueprint.sections.find((entry) => entry.id === target.section);
|
|
8595
|
+
const page = section?.pages.find((entry) => entry.id === target.page);
|
|
8596
|
+
const contextDir = join28(workspaceInfo.appRoot, ".decantr", "context");
|
|
8597
|
+
const manifest = readJsonIfPresent(join28(contextDir, "pack-manifest.json"));
|
|
8598
|
+
const pagePack = manifest?.pages?.find((entry) => entry.id === target.page);
|
|
8599
|
+
const sectionPack = manifest?.sections?.find((entry) => entry.id === target.section);
|
|
8600
|
+
const visualManifest = readJsonIfPresent(join28(workspaceInfo.appRoot, ".decantr", "evidence", "visual-manifest.json"));
|
|
8601
|
+
const screenshot = visualManifest?.routes?.find((entry) => entry.route === route)?.screenshot;
|
|
8602
|
+
const localPatternsPath = join28(workspaceInfo.appRoot, ".decantr", "local-patterns.json");
|
|
8603
|
+
const context = {
|
|
8604
|
+
route,
|
|
8605
|
+
task: taskSummary || null,
|
|
8606
|
+
section: target.section,
|
|
8607
|
+
page: target.page,
|
|
8608
|
+
shell: page?.shell ?? section?.shell ?? null,
|
|
8609
|
+
patterns: page?.layout?.map(extractPatternName) ?? [],
|
|
8610
|
+
read: [
|
|
8611
|
+
pagePack ? join28(".decantr/context", pagePack.markdown) : null,
|
|
8612
|
+
sectionPack ? join28(".decantr/context", sectionPack.markdown) : null,
|
|
8613
|
+
manifest?.scaffold?.markdown ? join28(".decantr/context", manifest.scaffold.markdown) : null,
|
|
8614
|
+
".decantr/context/scaffold.md",
|
|
8615
|
+
"DECANTR.md",
|
|
8616
|
+
existsSync27(localPatternsPath) ? ".decantr/local-patterns.json" : null
|
|
8617
|
+
].filter(Boolean),
|
|
8618
|
+
screenshot: screenshot ?? null
|
|
8619
|
+
};
|
|
8620
|
+
if (flagBoolean(flags, "json")) {
|
|
8621
|
+
console.log(JSON.stringify(context, null, 2));
|
|
8622
|
+
return;
|
|
8623
|
+
}
|
|
8624
|
+
console.log(heading2("Decantr Task Context"));
|
|
8625
|
+
console.log(` Route: ${cyan3(context.route)}`);
|
|
8626
|
+
console.log(` Section/page: ${context.section}/${context.page}`);
|
|
8627
|
+
if (context.shell) console.log(` Shell: ${context.shell}`);
|
|
8628
|
+
if (context.patterns.length > 0) console.log(` Patterns: ${context.patterns.join(", ")}`);
|
|
8629
|
+
if (taskSummary) console.log(` Task: ${taskSummary}`);
|
|
8630
|
+
console.log("");
|
|
8631
|
+
console.log(`${BOLD7}Read before editing:${RESET14}`);
|
|
8632
|
+
for (const path of context.read) {
|
|
8633
|
+
console.log(` ${cyan3(path)}`);
|
|
8634
|
+
}
|
|
8635
|
+
if (context.screenshot) {
|
|
8636
|
+
console.log("");
|
|
8637
|
+
console.log(`${BOLD7}Visual evidence:${RESET14}`);
|
|
8638
|
+
console.log(` ${cyan3(context.screenshot)}`);
|
|
8639
|
+
}
|
|
8640
|
+
console.log("");
|
|
8641
|
+
console.log(`${BOLD7}LLM instruction:${RESET14}`);
|
|
8642
|
+
console.log(
|
|
8643
|
+
" Preserve the existing runtime and styling system. Use the route pack, section context, local patterns, and visual evidence above as the task contract before changing code."
|
|
8644
|
+
);
|
|
8645
|
+
}
|
|
8646
|
+
async function cmdCodifyWorkflow(args) {
|
|
8647
|
+
const { flags } = parseLooseArgs(args);
|
|
8648
|
+
const workspaceInfo = resolveWorkflowProject(flags);
|
|
8649
|
+
if (!workspaceInfo) return;
|
|
8650
|
+
const decantrDir = join28(workspaceInfo.appRoot, ".decantr");
|
|
8651
|
+
const proposalPathLocal = join28(decantrDir, "local-patterns.proposal.json");
|
|
8652
|
+
const acceptedPath = join28(decantrDir, "local-patterns.json");
|
|
8653
|
+
if (flagBoolean(flags, "accept")) {
|
|
8654
|
+
if (!existsSync27(proposalPathLocal)) {
|
|
8655
|
+
console.error(error3("No .decantr/local-patterns.proposal.json found. Run `decantr codify` first."));
|
|
8656
|
+
process.exitCode = 1;
|
|
8657
|
+
return;
|
|
8658
|
+
}
|
|
8659
|
+
writeFileSync16(acceptedPath, readFileSync20(proposalPathLocal, "utf-8"), "utf-8");
|
|
8660
|
+
console.log(success3(`Accepted local pattern pack: ${acceptedPath}`));
|
|
8661
|
+
console.log(dim3("Run `decantr verify --local-patterns` to require the pack during verification."));
|
|
8662
|
+
return;
|
|
8663
|
+
}
|
|
8664
|
+
mkdirSync13(decantrDir, { recursive: true });
|
|
8665
|
+
const detected = detectProject(workspaceInfo.appRoot);
|
|
8666
|
+
const essence = readJsonIfPresent(join28(workspaceInfo.appRoot, "decantr.essence.json"));
|
|
8667
|
+
const routes = essence && isV47(essence) ? Object.keys(essence.blueprint.routes ?? {}).sort() : [];
|
|
8668
|
+
const proposal = {
|
|
8669
|
+
version: 1,
|
|
8670
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8671
|
+
status: "proposal",
|
|
8672
|
+
source: "decantr codify",
|
|
8673
|
+
project: {
|
|
8674
|
+
framework: detected.framework,
|
|
8675
|
+
packageManager: detected.packageManager,
|
|
8676
|
+
hasTailwind: detected.hasTailwind,
|
|
8677
|
+
ruleFiles: detected.existingRuleFiles,
|
|
8678
|
+
routeCount: routes.length
|
|
8679
|
+
},
|
|
8680
|
+
purpose: "Project-owned Brownfield UI law. Review and edit before accepting; Decantr does not treat this as authoritative until copied to .decantr/local-patterns.json.",
|
|
8681
|
+
patterns: [
|
|
8682
|
+
{
|
|
8683
|
+
id: "button",
|
|
8684
|
+
role: "Actions and command triggers",
|
|
8685
|
+
decide: "Define primary, secondary, tertiary, destructive, icon-only, and loading button variants from this app.",
|
|
8686
|
+
evidenceToCollect: ["component wrapper path", "allowed classes/tokens", "forbidden raw <button> usage"]
|
|
8687
|
+
},
|
|
8688
|
+
{
|
|
8689
|
+
id: "surface-card",
|
|
8690
|
+
role: "Cards, panels, and content surfaces",
|
|
8691
|
+
decide: "Define the canonical card background, border, radius, shadow, padding, and hover treatment.",
|
|
8692
|
+
evidenceToCollect: ["shared card component", "token/class recipe", "allowed density variants"]
|
|
8693
|
+
},
|
|
8694
|
+
{
|
|
8695
|
+
id: "page-shell",
|
|
8696
|
+
role: "Route shell, nav, spacing, and scroll ownership",
|
|
8697
|
+
decide: "Define which layout owns max width, gutters, sticky chrome, and scroll containers.",
|
|
8698
|
+
evidenceToCollect: ["root layout path", "page template path", "responsive breakpoints"]
|
|
8699
|
+
},
|
|
8700
|
+
{
|
|
8701
|
+
id: "form-control",
|
|
8702
|
+
role: "Inputs, labels, validation, and form actions",
|
|
8703
|
+
decide: "Define input height, label placement, error copy, disabled state, and focus treatment.",
|
|
8704
|
+
evidenceToCollect: ["form field wrapper", "validation pattern", "accessibility expectations"]
|
|
8705
|
+
}
|
|
8706
|
+
],
|
|
8707
|
+
starterRules: [
|
|
8708
|
+
"Prefer project-owned wrappers for repeated primitives once they exist.",
|
|
8709
|
+
"Avoid raw hex/rgb values in component templates unless explicitly documented as dynamic data.",
|
|
8710
|
+
"Avoid static inline styles for reusable visual treatment.",
|
|
8711
|
+
"When adding a new route, map it to an existing local pattern before inventing a new visual variant."
|
|
8712
|
+
],
|
|
8713
|
+
nextSteps: [
|
|
8714
|
+
"Edit this proposal with real component paths and token/class recipes.",
|
|
8715
|
+
"Run decantr codify --accept after review.",
|
|
8716
|
+
"Use decantr task <route> before LLM edits so local patterns appear in the task context.",
|
|
8717
|
+
"Wire mechanical enforcement through ESLint/Biome/project tests for rules Decantr cannot reliably infer."
|
|
8718
|
+
]
|
|
8719
|
+
};
|
|
8720
|
+
writeFileSync16(proposalPathLocal, JSON.stringify(proposal, null, 2) + "\n", "utf-8");
|
|
8721
|
+
console.log(success3(`Wrote local pattern proposal: ${proposalPathLocal}`));
|
|
8722
|
+
console.log(dim3("Review it, add real component paths/token recipes, then run `decantr codify --accept`."));
|
|
8723
|
+
}
|
|
8724
|
+
async function cmdContentWorkflow(args) {
|
|
8725
|
+
const subcommand = args[1] ?? "check";
|
|
8726
|
+
if (subcommand === "check" || subcommand === "health") {
|
|
8727
|
+
const { cmdContentHealth, parseContentHealthArgs } = await import("./content-health-QQHBR6XG.js");
|
|
8728
|
+
await cmdContentHealth(process.cwd(), parseContentHealthArgs(["content-health", ...args.slice(2)]));
|
|
8729
|
+
return;
|
|
8730
|
+
}
|
|
8731
|
+
if (subcommand === "create") {
|
|
8732
|
+
const type = args[2];
|
|
8733
|
+
const name = args[3];
|
|
8734
|
+
if (!type || !name) {
|
|
8735
|
+
console.error(error3("Usage: decantr content create <type> <name>"));
|
|
8736
|
+
process.exitCode = 1;
|
|
8737
|
+
return;
|
|
8738
|
+
}
|
|
8739
|
+
cmdCreate(type, name);
|
|
8740
|
+
return;
|
|
8741
|
+
}
|
|
8742
|
+
if (subcommand === "publish") {
|
|
8743
|
+
const type = args[2];
|
|
8744
|
+
const name = args[3];
|
|
8745
|
+
if (!type || !name) {
|
|
8746
|
+
console.error(error3("Usage: decantr content publish <type> <name>"));
|
|
8747
|
+
process.exitCode = 1;
|
|
8748
|
+
return;
|
|
8749
|
+
}
|
|
8750
|
+
await cmdPublish(type, name);
|
|
8751
|
+
return;
|
|
8752
|
+
}
|
|
8753
|
+
console.error(error3("Usage: decantr content <check|create|publish>"));
|
|
8754
|
+
process.exitCode = 1;
|
|
8755
|
+
}
|
|
8296
8756
|
function cmdHelp() {
|
|
8297
8757
|
console.log(`
|
|
8298
8758
|
${BOLD7}decantr${RESET14} \u2014 Design intelligence for AI-generated UI
|
|
8299
8759
|
|
|
8300
8760
|
${BOLD7}Usage:${RESET14}
|
|
8761
|
+
decantr setup [--project <path>]
|
|
8301
8762
|
decantr new <name> [--blueprint=X] [--archetype=X] [--theme=X] [--workflow=greenfield] [--adoption=decantr-css] [--telemetry]
|
|
8302
|
-
decantr
|
|
8763
|
+
decantr adopt [--project <path>] [--base-url <url>] [--evidence] [--ci] [--yes]
|
|
8764
|
+
decantr task <route> ["task summary"] [--project <path>] [--json]
|
|
8765
|
+
decantr verify [--project <path>] [--brownfield] [--local-patterns] [health options]
|
|
8766
|
+
decantr codify [--accept] [--project <path>]
|
|
8767
|
+
decantr studio [--port 4319] [--host 127.0.0.1] [--report decantr-health.json] [--workspace]
|
|
8768
|
+
|
|
8769
|
+
${BOLD7}Advanced primitives:${RESET14}
|
|
8303
8770
|
decantr init [options]
|
|
8771
|
+
decantr analyze
|
|
8772
|
+
decantr magic <prompt> [--dry-run]
|
|
8304
8773
|
decantr status
|
|
8305
8774
|
decantr sync
|
|
8306
8775
|
decantr audit [file]
|
|
@@ -8324,8 +8793,8 @@ ${BOLD7}Usage:${RESET14}
|
|
|
8324
8793
|
decantr health init-ci [--force] [--project <path>] [--workspace] [--fail-on <error|warn|none>] [--cli-version <version|latest>]
|
|
8325
8794
|
decantr workspace list [--json]
|
|
8326
8795
|
decantr workspace health [--json] [--changed --since origin/main]
|
|
8796
|
+
decantr content check [--json] [--markdown] [--ci]
|
|
8327
8797
|
decantr content-health [--json] [--markdown] [--ci]
|
|
8328
|
-
decantr studio [--port 4319] [--host 127.0.0.1] [--report decantr-health.json] [--workspace]
|
|
8329
8798
|
decantr telemetry status [--json]
|
|
8330
8799
|
decantr telemetry explain [--json]
|
|
8331
8800
|
decantr telemetry link [--enable] [--org <slug>]
|
|
@@ -8335,7 +8804,6 @@ ${BOLD7}Usage:${RESET14}
|
|
|
8335
8804
|
decantr theme <subcommand>
|
|
8336
8805
|
decantr create <type> <name>
|
|
8337
8806
|
decantr publish <type> <name>
|
|
8338
|
-
decantr analyze
|
|
8339
8807
|
decantr login
|
|
8340
8808
|
decantr logout
|
|
8341
8809
|
decantr help
|
|
@@ -8363,14 +8831,22 @@ ${BOLD7}Init Options:${RESET14}
|
|
|
8363
8831
|
--telemetry Opt this project into privacy-filtered CLI product telemetry
|
|
8364
8832
|
|
|
8365
8833
|
${BOLD7}Commands:${RESET14}
|
|
8834
|
+
${cyan3("setup")} Detect project state and recommend the right Decantr workflow
|
|
8366
8835
|
${cyan3("new")} Create a new greenfield workspace and bootstrap the available starter adapter
|
|
8836
|
+
${cyan3("adopt")} Brownfield one-liner: analyze, attach, verify, and show next steps
|
|
8837
|
+
${cyan3("task")} Prepare route/task context for an AI coding assistant
|
|
8838
|
+
${cyan3("verify")} One reliability gate over Project Health, Brownfield checks, baselines, and evidence
|
|
8839
|
+
${cyan3("codify")} Propose or accept project-owned Brownfield UI patterns
|
|
8840
|
+
${cyan3("studio")} Open a local Project Health dashboard backed by the same report
|
|
8841
|
+
${cyan3("content")} Content-author namespace: check, create, publish
|
|
8842
|
+
|
|
8843
|
+
${BOLD7}Advanced commands:${RESET14}
|
|
8367
8844
|
${cyan3("magic")} Greenfield-first intent flow; steers existing apps into analyze + init
|
|
8368
8845
|
${cyan3("init")} Attach Decantr contract/context files to an existing project or empty workspace
|
|
8369
8846
|
${cyan3("status")} Show project status, DNA axioms, and blueprint info
|
|
8370
8847
|
${cyan3("health")} Generate a local Project Health report [--json] [--markdown] [--ci]; use health init-ci to install a GitHub Actions gate
|
|
8371
8848
|
${cyan3("workspace")} Discover and aggregate health across Decantr projects in a monorepo
|
|
8372
8849
|
${cyan3("content-health")} Generate a local registry content health report [--json] [--markdown] [--ci]
|
|
8373
|
-
${cyan3("studio")} Open a local Project Health dashboard backed by the same report
|
|
8374
8850
|
${cyan3("sync")} Sync registry content from API
|
|
8375
8851
|
${cyan3("audit")} Audit the project or critique a specific file against compiled packs
|
|
8376
8852
|
${cyan3("migrate")} Migrate older essence files to v4 format (with .pre-v4.backup.json backup)
|
|
@@ -8396,7 +8872,15 @@ ${BOLD7}Commands:${RESET14}
|
|
|
8396
8872
|
${cyan3("help")} Show this help
|
|
8397
8873
|
|
|
8398
8874
|
${BOLD7}Examples:${RESET14}
|
|
8875
|
+
decantr setup
|
|
8399
8876
|
decantr new my-app --blueprint=carbon-ai-portal
|
|
8877
|
+
decantr adopt --base-url http://localhost:3000 --evidence --yes
|
|
8878
|
+
decantr task /feed "add saved recipe actions"
|
|
8879
|
+
decantr verify --brownfield --local-patterns
|
|
8880
|
+
decantr verify --since-baseline
|
|
8881
|
+
decantr codify
|
|
8882
|
+
decantr codify --accept
|
|
8883
|
+
decantr content check --ci --fail-on error
|
|
8400
8884
|
decantr magic "AI chatbot with dark cyber theme \u2014 bold and futuristic"
|
|
8401
8885
|
decantr init
|
|
8402
8886
|
decantr analyze
|
|
@@ -8409,13 +8893,13 @@ ${BOLD7}Examples:${RESET14}
|
|
|
8409
8893
|
decantr rules apply
|
|
8410
8894
|
decantr status
|
|
8411
8895
|
decantr health
|
|
8412
|
-
decantr
|
|
8413
|
-
decantr
|
|
8414
|
-
decantr
|
|
8896
|
+
decantr verify init-ci
|
|
8897
|
+
decantr verify init-ci --project apps/web
|
|
8898
|
+
decantr verify --ci --fail-on error
|
|
8415
8899
|
decantr health --evidence --output .decantr/evidence/latest.json
|
|
8416
8900
|
decantr workspace list
|
|
8417
|
-
decantr workspace
|
|
8418
|
-
decantr content
|
|
8901
|
+
decantr verify --workspace --changed --since origin/main
|
|
8902
|
+
decantr content check --ci --fail-on error
|
|
8419
8903
|
decantr studio
|
|
8420
8904
|
decantr studio --report decantr-health.json
|
|
8421
8905
|
decantr telemetry status
|
|
@@ -8444,7 +8928,9 @@ ${BOLD7}Examples:${RESET14}
|
|
|
8444
8928
|
${BOLD7}Workflow Model:${RESET14}
|
|
8445
8929
|
${cyan3("Greenfield blueprint")} decantr new my-app --blueprint=X --workflow=greenfield --adoption=decantr-css
|
|
8446
8930
|
${cyan3("Greenfield contract")} decantr init --workflow=greenfield --adoption=contract-only
|
|
8447
|
-
${cyan3("Brownfield adoption")} decantr
|
|
8931
|
+
${cyan3("Brownfield adoption")} decantr adopt --base-url <url> --evidence --yes
|
|
8932
|
+
${cyan3("Daily LLM work")} decantr task <route> "<change>" -> decantr verify
|
|
8933
|
+
${cyan3("Project-owned law")} decantr codify -> edit proposal -> decantr codify --accept
|
|
8448
8934
|
${cyan3("Hybrid composition")} decantr add/remove, decantr theme switch, decantr registry, decantr upgrade
|
|
8449
8935
|
|
|
8450
8936
|
${BOLD7}Bootstrap adapters:${RESET14}
|
|
@@ -8611,9 +9097,127 @@ ${BOLD7}Usage:${RESET14}
|
|
|
8611
9097
|
decantr theme import <path>
|
|
8612
9098
|
`);
|
|
8613
9099
|
}
|
|
9100
|
+
function cmdSetupHelp() {
|
|
9101
|
+
console.log(`
|
|
9102
|
+
${BOLD7}decantr setup${RESET14} \u2014 Detect the project state and recommend the right Decantr path
|
|
9103
|
+
|
|
9104
|
+
${BOLD7}Usage:${RESET14}
|
|
9105
|
+
decantr setup [--project <path>]
|
|
9106
|
+
|
|
9107
|
+
${BOLD7}Examples:${RESET14}
|
|
9108
|
+
decantr setup
|
|
9109
|
+
decantr setup --project apps/web
|
|
9110
|
+
`);
|
|
9111
|
+
}
|
|
9112
|
+
function cmdAdoptHelp() {
|
|
9113
|
+
console.log(`
|
|
9114
|
+
${BOLD7}decantr adopt${RESET14} \u2014 Brownfield one-liner: analyze, attach, verify, and show the next step
|
|
9115
|
+
|
|
9116
|
+
${BOLD7}Usage:${RESET14}
|
|
9117
|
+
decantr adopt [--project <path>] [--yes] [--dry-run]
|
|
9118
|
+
decantr adopt --base-url <url> [--evidence] [--ci] [--yes]
|
|
9119
|
+
|
|
9120
|
+
${BOLD7}Options:${RESET14}
|
|
9121
|
+
--project App path inside a workspace/monorepo
|
|
9122
|
+
--yes, -y Run without confirmation
|
|
9123
|
+
--dry-run Show the workflow without writing files
|
|
9124
|
+
--base-url Include browser evidence against this dev server URL
|
|
9125
|
+
--evidence Write .decantr/evidence/latest.json
|
|
9126
|
+
--baseline Save a health baseline (default)
|
|
9127
|
+
--no-baseline Skip baseline save
|
|
9128
|
+
--no-verify Skip the verification step
|
|
9129
|
+
--ci, --init-ci Install the Project Health CI gate after adoption
|
|
9130
|
+
--telemetry Opt this project into privacy-filtered CLI product telemetry
|
|
9131
|
+
--merge-proposal Merge the observed proposal into an existing essence
|
|
9132
|
+
--replace-essence Replace an existing essence with backup
|
|
9133
|
+
|
|
9134
|
+
${BOLD7}Examples:${RESET14}
|
|
9135
|
+
decantr adopt --yes
|
|
9136
|
+
decantr adopt --base-url http://localhost:3000 --evidence --yes
|
|
9137
|
+
decantr adopt --project apps/web --ci --yes
|
|
9138
|
+
`);
|
|
9139
|
+
}
|
|
9140
|
+
function cmdVerifyHelp() {
|
|
9141
|
+
console.log(`
|
|
9142
|
+
${BOLD7}decantr verify${RESET14} \u2014 One reliability command for local work, CI, and LLM agent loops
|
|
9143
|
+
|
|
9144
|
+
${BOLD7}Usage:${RESET14}
|
|
9145
|
+
decantr verify [--project <path>] [--brownfield] [--local-patterns]
|
|
9146
|
+
decantr verify --base-url <url> --evidence
|
|
9147
|
+
decantr verify --since-baseline
|
|
9148
|
+
decantr verify --workspace [--changed --since origin/main]
|
|
9149
|
+
decantr verify init-ci [health init-ci options]
|
|
9150
|
+
|
|
9151
|
+
${BOLD7}Examples:${RESET14}
|
|
9152
|
+
decantr verify
|
|
9153
|
+
decantr verify --brownfield --local-patterns
|
|
9154
|
+
decantr verify --base-url http://localhost:3000 --evidence
|
|
9155
|
+
decantr verify --workspace --changed --since origin/main
|
|
9156
|
+
decantr verify init-ci --project apps/web
|
|
9157
|
+
`);
|
|
9158
|
+
}
|
|
9159
|
+
function cmdTaskHelp() {
|
|
9160
|
+
console.log(`
|
|
9161
|
+
${BOLD7}decantr task${RESET14} \u2014 Prepare compact route/task context for an AI coding assistant
|
|
9162
|
+
|
|
9163
|
+
${BOLD7}Usage:${RESET14}
|
|
9164
|
+
decantr task <route> ["task summary"] [--project <path>] [--json]
|
|
9165
|
+
|
|
9166
|
+
${BOLD7}Examples:${RESET14}
|
|
9167
|
+
decantr task /feed "add saved recipe actions"
|
|
9168
|
+
decantr task /profile --json
|
|
9169
|
+
`);
|
|
9170
|
+
}
|
|
9171
|
+
function cmdCodifyHelp() {
|
|
9172
|
+
console.log(`
|
|
9173
|
+
${BOLD7}decantr codify${RESET14} \u2014 Propose or accept project-owned Brownfield UI patterns
|
|
9174
|
+
|
|
9175
|
+
${BOLD7}Usage:${RESET14}
|
|
9176
|
+
decantr codify [--project <path>]
|
|
9177
|
+
decantr codify --accept [--project <path>]
|
|
9178
|
+
|
|
9179
|
+
${BOLD7}Examples:${RESET14}
|
|
9180
|
+
decantr codify
|
|
9181
|
+
decantr codify --accept
|
|
9182
|
+
decantr verify --local-patterns
|
|
9183
|
+
`);
|
|
9184
|
+
}
|
|
9185
|
+
function cmdContentHelp() {
|
|
9186
|
+
console.log(`
|
|
9187
|
+
${BOLD7}decantr content${RESET14} \u2014 Content-author namespace for registry content repositories
|
|
9188
|
+
|
|
9189
|
+
${BOLD7}Usage:${RESET14}
|
|
9190
|
+
decantr content check [content-health options]
|
|
9191
|
+
decantr content create <type> <name>
|
|
9192
|
+
decantr content publish <type> <name>
|
|
9193
|
+
|
|
9194
|
+
${BOLD7}Examples:${RESET14}
|
|
9195
|
+
decantr content check --ci --fail-on error
|
|
9196
|
+
decantr content create pattern my-card
|
|
9197
|
+
decantr content publish pattern my-card
|
|
9198
|
+
`);
|
|
9199
|
+
}
|
|
8614
9200
|
function printCommandHelp(command, args) {
|
|
8615
9201
|
if (!isCommandHelpRequest(args)) return false;
|
|
8616
9202
|
switch (command) {
|
|
9203
|
+
case "setup":
|
|
9204
|
+
cmdSetupHelp();
|
|
9205
|
+
return true;
|
|
9206
|
+
case "adopt":
|
|
9207
|
+
cmdAdoptHelp();
|
|
9208
|
+
return true;
|
|
9209
|
+
case "verify":
|
|
9210
|
+
cmdVerifyHelp();
|
|
9211
|
+
return true;
|
|
9212
|
+
case "task":
|
|
9213
|
+
cmdTaskHelp();
|
|
9214
|
+
return true;
|
|
9215
|
+
case "codify":
|
|
9216
|
+
cmdCodifyHelp();
|
|
9217
|
+
return true;
|
|
9218
|
+
case "content":
|
|
9219
|
+
cmdContentHelp();
|
|
9220
|
+
return true;
|
|
8617
9221
|
case "health":
|
|
8618
9222
|
cmdHealthHelp();
|
|
8619
9223
|
return true;
|
|
@@ -8672,6 +9276,30 @@ async function main() {
|
|
|
8672
9276
|
return;
|
|
8673
9277
|
}
|
|
8674
9278
|
switch (command) {
|
|
9279
|
+
case "setup": {
|
|
9280
|
+
await cmdSetupWorkflow(args);
|
|
9281
|
+
break;
|
|
9282
|
+
}
|
|
9283
|
+
case "adopt": {
|
|
9284
|
+
await cmdAdoptWorkflow(args);
|
|
9285
|
+
break;
|
|
9286
|
+
}
|
|
9287
|
+
case "task": {
|
|
9288
|
+
await cmdTaskWorkflow(args);
|
|
9289
|
+
break;
|
|
9290
|
+
}
|
|
9291
|
+
case "verify": {
|
|
9292
|
+
await cmdVerifyWorkflow(args);
|
|
9293
|
+
break;
|
|
9294
|
+
}
|
|
9295
|
+
case "codify": {
|
|
9296
|
+
await cmdCodifyWorkflow(args);
|
|
9297
|
+
break;
|
|
9298
|
+
}
|
|
9299
|
+
case "content": {
|
|
9300
|
+
await cmdContentWorkflow(args);
|
|
9301
|
+
break;
|
|
9302
|
+
}
|
|
8675
9303
|
case "new": {
|
|
8676
9304
|
const newName = args[1];
|
|
8677
9305
|
if (!newName) {
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decantr/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "Decantr CLI - scaffold, audit, inspect Project Health, and maintain Decantr projects from the terminal",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"decantr",
|
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"ajv": "^8.20.0",
|
|
51
51
|
"@decantr/core": "2.1.0",
|
|
52
|
+
"@decantr/verifier": "2.2.0",
|
|
52
53
|
"@decantr/registry": "2.2.0",
|
|
53
54
|
"@decantr/telemetry": "2.2.1",
|
|
54
|
-
"@decantr/verifier": "2.2.0",
|
|
55
55
|
"@decantr/essence-spec": "2.0.1"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|