@decantr/cli 2.9.7 → 2.9.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,7 +17,7 @@ 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
+ 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 right entry path.
21
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`.
22
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, hydrates hosted execution packs when online, and only applies the contract when you explicitly accept or merge it.
23
23
  Use `decantr doctor` when the next step is unclear, `decantr task` before asking an LLM to modify a route, `decantr verify` after the edit, and `decantr ci` in required automation. Use `decantr codify --from-audit` when you want project-owned UI patterns and local rules such as button/card/shell/theme standards to appear in future task context and verification.
@@ -96,6 +96,12 @@ Brownfield analysis also writes `.decantr/doctrine-map.json`, a ranked source-pr
96
96
  - syncs paginated hosted registry content into a full slug-keyed local cache for offline guards and context generation
97
97
  - validates, refreshes, and maintains `decantr.essence.json`
98
98
 
99
+ ## Security And Permissions
100
+
101
+ The CLI is intentionally a local project inspector and artifact writer. It reads selected project/workspace files, package manifests, routing/style/config files, `.decantr` artifacts, and Decantr cache/config files. It writes `decantr.essence.json`, `DECANTR.md`, `.decantr/*`, generated context packs, optional CI workflows/snippets, optional style/export files, and auth/telemetry config only when explicitly requested.
102
+
103
+ Telemetry is disabled by default. Hosted registry, hosted pack hydration, hosted critique/audit, and browser evidence are explicit command paths; screenshots and Evidence Bundles stay local unless a hosted workflow is invoked. Release audits prove the installed package with `npm pack --dry-run --json`. See [security permissions](https://decantr.ai/reference/security-permissions.md).
104
+
99
105
  ## Common Commands
100
106
 
101
107
  ```bash
@@ -142,7 +148,7 @@ decantr showcase verification --json
142
148
 
143
149
  `decantr verify` is the workflow command most users should run locally after edits. It delegates to Project Health, can add Brownfield guard validation with `--brownfield`, requires an accepted local pattern pack with `--local-patterns`, scans `.decantr/rules.json` when present, supports workspace mode, and writes evidence to `.decantr/evidence/latest.json` by default when `--evidence` is used.
144
150
 
145
- `decantr doctor` explains project/workspace state, adoption mode, generated artifacts, local law, visual evidence, design authority signals, CI wiring, and the next command to run. It is the command to reach for when an app is in a monorepo, has stale Decantr files, or someone is not sure what Decantr expects next.
151
+ `decantr doctor` explains project/workspace state, adoption mode, generated artifacts, local law, visual evidence, design authority signals, CI wiring, and an ordered next-step queue. It is the command to reach for when an app is in a monorepo, has stale Decantr files, or someone is not sure what Decantr expects next.
146
152
 
147
153
  `decantr setup` is non-mutating orientation. In an attached Brownfield app it reflects whether local law is already accepted, so the recommended verify command includes `--local-patterns` only when the project has that layer.
148
154
 
package/dist/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-66L74ZNJ.js";
2
+ import "./chunk-JSILTE5V.js";
3
3
  import "./chunk-IQZCIMQJ.js";
4
4
  import "./chunk-QDMXZSVK.js";
5
5
  import "./chunk-WPP3JEMC.js";
@@ -3025,7 +3025,8 @@ var RESET2 = "\x1B[0m";
3025
3025
  var GREEN2 = "\x1B[32m";
3026
3026
  var CYAN = "\x1B[36m";
3027
3027
  var YELLOW2 = "\x1B[33m";
3028
- async function cmdAnalyze(projectRoot = process.cwd(), workspace) {
3028
+ async function cmdAnalyze(projectRoot = process.cwd(), workspace, options = {}) {
3029
+ const printNextStep = options.printNextStep ?? true;
3029
3030
  const startedAt = Date.now();
3030
3031
  console.log(`
3031
3032
  ${BOLD}Analyzing project...${RESET2}
@@ -3190,11 +3191,13 @@ ${DIM2}Written to:${RESET2} ${outputPath}`);
3190
3191
  console.log(`${DIM2}Brownfield intelligence:${RESET2} ${intelligenceArtifacts.intelligencePath}`);
3191
3192
  console.log(`${DIM2}Theme inventory:${RESET2} ${intelligenceArtifacts.themeInventoryPath}`);
3192
3193
  console.log(`${DIM2}Enrichment backlog:${RESET2} ${intelligenceArtifacts.backlogPath}`);
3193
- console.log(
3194
- `
3194
+ if (printNextStep) {
3195
+ console.log(
3196
+ `
3195
3197
  ${YELLOW2}Next step:${RESET2} Review ${BOLD}${reportDisplayPath}${RESET2}, then run ${BOLD}${recommendedAttachCommand}${RESET2} to attach Decantr using the observed proposal.
3196
3198
  `
3197
- );
3199
+ );
3200
+ }
3198
3201
  await sendAnalyzeCompletedTelemetry({
3199
3202
  componentCount: components.componentCount,
3200
3203
  dependencyCategoryCount: [
@@ -4462,6 +4465,10 @@ function statusFromIssues(issues, essenceVersion) {
4462
4465
  }
4463
4466
  return "healthy";
4464
4467
  }
4468
+ function appendUnique(commands, command) {
4469
+ if (!command) return;
4470
+ if (!commands.includes(command)) commands.push(command);
4471
+ }
4465
4472
  function buildDoctorReport(root, args) {
4466
4473
  let projectArg;
4467
4474
  for (let index = 1; index < args.length; index += 1) {
@@ -4495,6 +4502,8 @@ function buildDoctorReport(root, args) {
4495
4502
  const workflowMode = projectJson?.initialized?.workflowMode ?? null;
4496
4503
  const adoptionMode = projectJson?.initialized?.adoptionMode ?? null;
4497
4504
  const packHydrationOptional = adoptionMode === "contract-only";
4505
+ const localPatternsPresent = existsSync16(localPatternsPath(appRoot));
4506
+ const localRulesPresent = existsSync16(localRulesPath(appRoot));
4498
4507
  const missingPackReferences = workspaceMode ? projects.flatMap(
4499
4508
  (project) => collectMissingPackManifestFiles(join18(workspaceRoot, project.path)).map(
4500
4509
  (missing) => `${project.path}/${missing.relativePath}`
@@ -4587,7 +4596,7 @@ function buildDoctorReport(root, args) {
4587
4596
  nextCommand: "decantr registry compile-packs <app-path>/decantr.essence.json --write-context"
4588
4597
  });
4589
4598
  }
4590
- if (workflowMode === "brownfield-attach" && !existsSync16(localPatternsPath(appRoot))) {
4599
+ if (workflowMode === "brownfield-attach" && !localPatternsPresent) {
4591
4600
  issues.push({
4592
4601
  category: "local-law",
4593
4602
  severity: "info",
@@ -4615,7 +4624,39 @@ function buildDoctorReport(root, args) {
4615
4624
  issues,
4616
4625
  workspaceMode || workspaceInfo.requiresProjectSelection ? "4.0.0" : essenceVersion
4617
4626
  );
4618
- const recommendedNextCommand = issues.find((issue) => issue.category === "workspace" && issue.nextCommand)?.nextCommand ?? issues.find((issue) => issue.nextCommand)?.nextCommand ?? (workspaceMode ? "decantr ci --workspace" : projectPath ? `decantr ci --project ${projectPath}` : "decantr ci");
4627
+ const projectFlag = projectPath ? ` --project ${projectPath}` : "";
4628
+ const verifyCommand = workflowMode === "brownfield-attach" ? `decantr verify --brownfield --local-patterns${projectFlag}` : workspaceMode ? "decantr ci --workspace" : `decantr verify${projectFlag}`;
4629
+ const ciCommand = workspaceMode ? "decantr ci --workspace --fail-on error" : `decantr ci${projectFlag} --fail-on error`;
4630
+ const recommendedNextCommands = [];
4631
+ const blockingIssue = issues.find((issue) => issue.category === "workspace" && issue.nextCommand) ?? issues.find(
4632
+ (issue) => (issue.category === "setup" || issue.category === "migration") && issue.nextCommand
4633
+ );
4634
+ if (blockingIssue) {
4635
+ appendUnique(recommendedNextCommands, blockingIssue.nextCommand);
4636
+ } else {
4637
+ appendUnique(
4638
+ recommendedNextCommands,
4639
+ issues.find((issue) => issue.category === "ci" && issue.message.includes("not pinned"))?.nextCommand
4640
+ );
4641
+ if (workflowMode === "brownfield-attach" && !localPatternsPresent) {
4642
+ appendUnique(recommendedNextCommands, `decantr codify --from-audit${projectFlag}`);
4643
+ appendUnique(recommendedNextCommands, `decantr codify --accept${projectFlag}`);
4644
+ }
4645
+ appendUnique(
4646
+ recommendedNextCommands,
4647
+ issues.find((issue) => issue.category === "generated-artifact")?.nextCommand
4648
+ );
4649
+ appendUnique(
4650
+ recommendedNextCommands,
4651
+ issues.find((issue) => issue.category === "ci" && issue.message.includes("No Decantr CI"))?.nextCommand
4652
+ );
4653
+ if (workflowMode === "brownfield-attach") {
4654
+ appendUnique(recommendedNextCommands, `decantr task <route> "<change>"${projectFlag}`);
4655
+ }
4656
+ appendUnique(recommendedNextCommands, verifyCommand);
4657
+ appendUnique(recommendedNextCommands, ciCommand);
4658
+ }
4659
+ const recommendedNextCommand = recommendedNextCommands[0] ?? ciCommand;
4619
4660
  return {
4620
4661
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
4621
4662
  workspaceRoot,
@@ -4647,8 +4688,8 @@ function buildDoctorReport(root, args) {
4647
4688
  missingReferencedFiles: missingPackReferences.slice(0, 25)
4648
4689
  },
4649
4690
  localLaw: {
4650
- patternsPresent: existsSync16(localPatternsPath(appRoot)),
4651
- rulesPresent: existsSync16(localRulesPath(appRoot))
4691
+ patternsPresent: localPatternsPresent,
4692
+ rulesPresent: localRulesPresent
4652
4693
  },
4653
4694
  visualEvidence: {
4654
4695
  manifestPresent: existsSync16(join18(appRoot, ".decantr", "evidence", "visual-manifest.json"))
@@ -4656,7 +4697,8 @@ function buildDoctorReport(root, args) {
4656
4697
  designAuthority,
4657
4698
  status,
4658
4699
  issues,
4659
- recommendedNextCommand
4700
+ recommendedNextCommand,
4701
+ recommendedNextCommands
4660
4702
  };
4661
4703
  }
4662
4704
  function colorForStatus(status) {
@@ -4713,13 +4755,20 @@ function formatDoctorText(report) {
4713
4755
  if (issue.nextCommand) lines.push(` ${DIM4}${issue.nextCommand}${RESET4}`);
4714
4756
  }
4715
4757
  }
4716
- lines.push("", `${BOLD3}Next:${RESET4}`, ` ${report.recommendedNextCommand}`, "");
4758
+ lines.push("", `${BOLD3}Next steps:${RESET4}`);
4759
+ for (const [index, command] of report.recommendedNextCommands.entries()) {
4760
+ lines.push(` ${index + 1}. ${command}`);
4761
+ }
4762
+ if (report.recommendedNextCommands.length === 0) {
4763
+ lines.push(` ${report.recommendedNextCommand}`);
4764
+ }
4765
+ lines.push("");
4717
4766
  return `${lines.join("\n")}
4718
4767
  `;
4719
4768
  }
4720
4769
  function cmdDoctorHelp() {
4721
4770
  console.log(`
4722
- ${BOLD3}decantr doctor${RESET4} \u2014 Explain Decantr state and the next command to run
4771
+ ${BOLD3}decantr doctor${RESET4} \u2014 Explain Decantr state and the next commands to run
4723
4772
 
4724
4773
  ${BOLD3}Usage:${RESET4}
4725
4774
  decantr doctor [--project <path>] [--workspace] [--json]
@@ -10399,8 +10448,10 @@ async function cmdAdoptWorkflow(args) {
10399
10448
  return;
10400
10449
  }
10401
10450
  }
10402
- await cmdAnalyze(projectRoot, workspaceInfo);
10451
+ await cmdAnalyze(projectRoot, workspaceInfo, { printNextStep: false });
10403
10452
  if (process.exitCode && process.exitCode !== 0) return;
10453
+ const initCommand = projectArg ? `decantr init --project ${projectArg} --existing ${proposalFlag}` : `decantr init --existing ${proposalFlag}`;
10454
+ console.log(dim3(`Analysis artifacts written; continuing with ${initCommand}.`));
10404
10455
  await cmdInit({
10405
10456
  existing: true,
10406
10457
  yes: true,
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import "./chunk-66L74ZNJ.js";
1
+ import "./chunk-JSILTE5V.js";
2
2
  import "./chunk-IQZCIMQJ.js";
3
3
  import "./chunk-QDMXZSVK.js";
4
4
  import "./chunk-WPP3JEMC.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decantr/cli",
3
- "version": "2.9.7",
3
+ "version": "2.9.8",
4
4
  "description": "Decantr CLI - scaffold, audit, inspect Project Health, and maintain Decantr projects from the terminal",
5
5
  "keywords": [
6
6
  "decantr",
@@ -49,10 +49,10 @@
49
49
  "dependencies": {
50
50
  "ajv": "^8.20.0",
51
51
  "@decantr/core": "2.1.0",
52
- "@decantr/registry": "2.2.0",
53
52
  "@decantr/verifier": "2.3.3",
53
+ "@decantr/telemetry": "2.2.1",
54
54
  "@decantr/essence-spec": "2.0.1",
55
- "@decantr/telemetry": "2.2.1"
55
+ "@decantr/registry": "2.2.0"
56
56
  },
57
57
  "scripts": {
58
58
  "build": "tsup",