@decantr/cli 3.8.0 → 3.8.1

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.
@@ -14,7 +14,7 @@ import {
14
14
  scaffoldProject,
15
15
  syncRegistry,
16
16
  writeExecutionPackBundleArtifacts
17
- } from "./chunk-IP2CCX2W.js";
17
+ } from "./chunk-JK3DYOHA.js";
18
18
  import {
19
19
  createWorkspaceHealthReport,
20
20
  formatWorkspaceHealthMarkdown,
@@ -22,7 +22,7 @@ import {
22
22
  listWorkspaceCandidates,
23
23
  listWorkspaceProjects,
24
24
  shouldFailWorkspaceHealth
25
- } from "./chunk-56HUEUO3.js";
25
+ } from "./chunk-W242I6CS.js";
26
26
  import {
27
27
  acceptBrownfieldLocalLaw,
28
28
  acceptStyleBridge,
@@ -52,7 +52,7 @@ import {
52
52
  writeBrownfieldCodifyProposal,
53
53
  writeHostedPatternMappingProposal,
54
54
  writeStyleBridgeProposal
55
- } from "./chunk-WAGVDMJV.js";
55
+ } from "./chunk-PFFNEN7L.js";
56
56
  import {
57
57
  buildGuardRegistryContext,
58
58
  createDoctrineMap,
@@ -69,7 +69,7 @@ import {
69
69
  sendCliCommandTelemetry,
70
70
  sendNewProjectCompletedTelemetry,
71
71
  writeDoctrineMap
72
- } from "./chunk-24JR4ZNG.js";
72
+ } from "./chunk-2UC6YYVZ.js";
73
73
 
74
74
  // src/index.ts
75
75
  import { existsSync as existsSync28, mkdirSync as mkdirSync17, readdirSync as readdirSync8, readFileSync as readFileSync21, writeFileSync as writeFileSync20 } from "fs";
@@ -1751,7 +1751,7 @@ function generateBrownfieldReport(proposal, ambient, doctrine) {
1751
1751
  lines.push("## Non-Goals By Default");
1752
1752
  lines.push("");
1753
1753
  lines.push(
1754
- "- Does not install Decantr CSS, switch themes, replace layouts, rewrite docs, mutate assistant rules, or import registry patterns unless explicitly requested."
1754
+ "- Does not install Decantr CSS, switch themes, replace layouts, rewrite docs, mutate assistant rules, or import official corpus patterns unless explicitly requested."
1755
1755
  );
1756
1756
  lines.push(
1757
1757
  "- Does not treat stale migration or completion summaries as current doctrine without verification."
@@ -1763,7 +1763,7 @@ function generateBrownfieldReport(proposal, ambient, doctrine) {
1763
1763
  "- Existing framework, routes, layout shell, feature names, styling signals, and ambient doctrine were used as evidence for the proposal."
1764
1764
  );
1765
1765
  lines.push(
1766
- "- Decantr registry content, Decantr CSS, and default Decantr themes were not accepted as brownfield defaults."
1766
+ "- Decantr official corpus content, Decantr CSS, and default Decantr themes were not accepted as brownfield defaults."
1767
1767
  );
1768
1768
  lines.push("");
1769
1769
  lines.push("## Uncertain Evidence");
@@ -3051,7 +3051,7 @@ function createBrownfieldInitSeed(detected, layout, styling) {
3051
3051
  existing: true,
3052
3052
  notes: [
3053
3053
  "Use decantr init --existing to attach Decantr contract and context files to this project.",
3054
- "Registry content is optional during brownfield adoption.",
3054
+ "Official corpus content is optional during brownfield adoption.",
3055
3055
  "Use decantr add/remove, decantr theme switch, and registry commands later for hybrid composition."
3056
3056
  ]
3057
3057
  };
@@ -4109,7 +4109,7 @@ decantr theme validate mytheme
4109
4109
 
4110
4110
  ## Reference
4111
4111
 
4112
- See registry themes for examples:
4112
+ See official corpus themes for examples:
4113
4113
 
4114
4114
  \`\`\`bash
4115
4115
  decantr get theme auradecantism
@@ -6135,7 +6135,7 @@ ${YELLOW6}Dependency install failed. Run \`${packageManager} install\` manually.
6135
6135
  );
6136
6136
  const seeded = options.offline ? seedOfflineRegistry(projectDir, workspaceRoot) : { seeded: false, strategy: null };
6137
6137
  if (seeded.seeded) {
6138
- console.log(dim3(` Seeded offline registry content from ${seeded.strategy}.`));
6138
+ console.log(dim3(` Seeded offline official content from ${seeded.strategy}.`));
6139
6139
  } else if (requiresOfflineContent) {
6140
6140
  console.log(
6141
6141
  `${YELLOW6} Offline blueprint/archetype resolution requires local content corpus data.${RESET9}`
@@ -6487,7 +6487,7 @@ async function cmdRegistryMirror(projectRoot, options = {}) {
6487
6487
  const counts = {};
6488
6488
  const failed = [];
6489
6489
  console.log(`
6490
- Mirroring registry content to ${DIM11}.decantr/cache/${RESET11}
6490
+ Mirroring official content to ${DIM11}.decantr/cache/${RESET11}
6491
6491
  `);
6492
6492
  for (const type of types) {
6493
6493
  try {
@@ -7002,7 +7002,6 @@ var CYAN8 = "\x1B[36m";
7002
7002
  var DIM15 = "\x1B[2m";
7003
7003
  var GREEN15 = "\x1B[32m";
7004
7004
  var RESET15 = "\x1B[0m";
7005
- var DEFAULT_API_URL = "https://api.decantr.ai/v1";
7006
7005
  async function cmdTelemetry(args, projectRoot = process.cwd()) {
7007
7006
  const subcommand = args[0] ?? "status";
7008
7007
  const options = parseTelemetryOptions(args.slice(1));
@@ -7026,7 +7025,7 @@ async function cmdTelemetry(args, projectRoot = process.cwd()) {
7026
7025
  }
7027
7026
  function printTelemetryHelp() {
7028
7027
  console.log(`
7029
- ${BOLD9}decantr telemetry${RESET15} \u2014 Inspect and link privacy-filtered CLI telemetry identity
7028
+ ${BOLD9}decantr telemetry${RESET15} \u2014 Inspect caller-configured private CLI telemetry
7030
7029
 
7031
7030
  ${BOLD9}Usage:${RESET15}
7032
7031
  decantr telemetry status [--json]
@@ -7034,11 +7033,13 @@ ${BOLD9}Usage:${RESET15}
7034
7033
  decantr telemetry link [--enable] [--org <slug>] [--label <label>] [--api-key <key>] [--api-url <url>]
7035
7034
 
7036
7035
  ${BOLD9}Examples:${RESET15}
7037
- decantr init --telemetry
7036
+ DECANTR_TELEMETRY_ENDPOINT=https://telemetry.example/v1/events decantr init --telemetry
7038
7037
  decantr telemetry status
7039
7038
  decantr telemetry explain
7040
- decantr login --api-key=<your-key>
7041
- decantr telemetry link --org my-team --label "CI runner"
7039
+ decantr telemetry link --api-url https://telemetry.example/v1 --api-key <key> --org my-team
7040
+
7041
+ Decantr does not operate a hosted telemetry sink. Delivery and identity linking are
7042
+ available only for caller-configured private infrastructure.
7042
7043
  `);
7043
7044
  }
7044
7045
  function printTelemetryStatus(projectRoot, options) {
@@ -7050,12 +7051,20 @@ function printTelemetryStatus(projectRoot, options) {
7050
7051
  console.log(`
7051
7052
  ${BOLD9}Decantr telemetry${RESET15}`);
7052
7053
  console.log(` Enabled: ${status.enabled ? `${GREEN15}yes${RESET15}` : "no"}`);
7054
+ console.log(
7055
+ ` Delivery: ${status.endpointConfigured ? `${GREEN15}configured${RESET15}` : `${DIM15}inactive${RESET15}`}`
7056
+ );
7057
+ if (status.endpoint) console.log(` Endpoint: ${status.endpoint}`);
7053
7058
  console.log(` Project: ${status.hasProjectConfig ? status.projectRoot : "not initialized"}`);
7054
7059
  console.log(` Install ID: ${status.installId ?? `${DIM15}not created yet${RESET15}`}`);
7055
7060
  console.log(` Project ID: ${status.projectId ?? `${DIM15}not created yet${RESET15}`}`);
7056
- if (status.enabled) {
7061
+ if (status.enabled && status.endpointConfigured) {
7062
+ console.log(
7063
+ DIM15 + "Events can be sent only to the caller-configured endpoint shown above." + RESET15
7064
+ );
7065
+ } else if (status.enabled) {
7057
7066
  console.log(
7058
- DIM15 + "Run `decantr telemetry link` after login to attach these opaque IDs to your Decantr account/org." + RESET15
7067
+ DIM15 + "The local preference is enabled, but no events are sent until DECANTR_TELEMETRY_ENDPOINT is configured." + RESET15
7059
7068
  );
7060
7069
  } else {
7061
7070
  console.log(
@@ -7077,13 +7086,14 @@ function printTelemetryExplain(projectRoot, options) {
7077
7086
  const report = {
7078
7087
  source: "cli",
7079
7088
  enabled: status.enabled,
7089
+ delivery: status.endpointConfigured ? "caller-configured" : "inactive",
7080
7090
  hasProjectConfig: status.hasProjectConfig,
7081
7091
  identifiers: {
7082
7092
  installId: status.installId ?? null,
7083
7093
  projectId: status.projectId ?? null,
7084
7094
  meaning: "Opaque Decantr-generated ids used only when this project has opted into CLI telemetry."
7085
7095
  },
7086
- endpoint: process.env.DECANTR_TELEMETRY_ENDPOINT ?? "https://api.decantr.ai/v1/telemetry/events",
7096
+ endpoint: status.endpoint ?? null,
7087
7097
  events: cliEvents,
7088
7098
  aggregateFields: [
7089
7099
  "command name",
@@ -7091,7 +7101,7 @@ function printTelemetryExplain(projectRoot, options) {
7091
7101
  "duration",
7092
7102
  "workflow and adoption mode",
7093
7103
  "project scope",
7094
- "registry source",
7104
+ "content source",
7095
7105
  "aggregate analyze counts",
7096
7106
  "Project Health status, score, and finding counts",
7097
7107
  "CI gate outcome",
@@ -7113,7 +7123,8 @@ function printTelemetryExplain(projectRoot, options) {
7113
7123
  controls: {
7114
7124
  optIn: "Run decantr init --telemetry, decantr new --telemetry, or decantr telemetry link --enable.",
7115
7125
  optOut: 'Set "telemetry": false in .decantr/project.json.',
7116
- link: "Run decantr telemetry link after login to attach opaque ids to your Decantr account/org."
7126
+ delivery: "Set DECANTR_TELEMETRY_ENDPOINT to a caller-controlled private event sink. Decantr has no hosted telemetry sink.",
7127
+ link: "Private deployments may run decantr telemetry link with --api-url and --api-key to attach opaque ids."
7117
7128
  }
7118
7129
  };
7119
7130
  if (options.json) {
@@ -7124,6 +7135,8 @@ function printTelemetryExplain(projectRoot, options) {
7124
7135
  ${BOLD9}Decantr telemetry explanation${RESET15}`);
7125
7136
  console.log(` Source: cli`);
7126
7137
  console.log(` Enabled: ${status.enabled ? `${GREEN15}yes${RESET15}` : "no"}`);
7138
+ console.log(` Delivery: ${report.delivery}`);
7139
+ if (status.endpoint) console.log(` Endpoint: ${status.endpoint}`);
7127
7140
  console.log(` Install ID: ${status.installId ?? `${DIM15}not created yet${RESET15}`}`);
7128
7141
  console.log(` Project ID: ${status.projectId ?? `${DIM15}not created yet${RESET15}`}`);
7129
7142
  console.log(` Events: ${cliEvents.length} CLI event types in the public catalog`);
@@ -7139,9 +7152,21 @@ ${BOLD9}Never collected${RESET15}`);
7139
7152
  }
7140
7153
  console.log(`
7141
7154
  ${DIM15}${report.controls.optOut}${RESET15}`);
7155
+ console.log(`${DIM15}${report.controls.delivery}${RESET15}`);
7142
7156
  console.log(`${DIM15}${report.controls.link}${RESET15}`);
7143
7157
  }
7144
7158
  async function linkTelemetryIdentity(projectRoot, options) {
7159
+ const configuredApiUrl = options.apiUrl ?? process.env.DECANTR_TELEMETRY_IDENTITY_API_URL?.trim();
7160
+ if (!configuredApiUrl) {
7161
+ throw new Error(
7162
+ "Decantr hosted telemetry identity linking is retired. Private deployments must pass --api-url or set DECANTR_TELEMETRY_IDENTITY_API_URL."
7163
+ );
7164
+ }
7165
+ const apiUrl = normalizePrivateApiUrl(configuredApiUrl);
7166
+ const apiKey = options.apiKey ?? getApiKeyOrToken();
7167
+ if (!apiKey) {
7168
+ throw new Error("Pass --api-key <key> for the caller-configured private telemetry API.");
7169
+ }
7145
7170
  if (options.enable && !isOptedIn(projectRoot)) {
7146
7171
  optIn(projectRoot);
7147
7172
  }
@@ -7154,15 +7179,6 @@ async function linkTelemetryIdentity(projectRoot, options) {
7154
7179
  if (!identity.installId && !identity.projectId) {
7155
7180
  throw new Error("No telemetry identity could be created for this project.");
7156
7181
  }
7157
- const apiKey = options.apiKey ?? getApiKeyOrToken();
7158
- if (!apiKey) {
7159
- throw new Error(
7160
- "Run `decantr login --api-key=<key>` or pass `--api-key <key>` before linking telemetry."
7161
- );
7162
- }
7163
- const apiUrl = trimTrailingSlashes(
7164
- options.apiUrl ?? process.env.DECANTR_API_URL ?? DEFAULT_API_URL
7165
- );
7166
7182
  const response = await fetch(`${apiUrl}/me/telemetry-link`, {
7167
7183
  method: "POST",
7168
7184
  headers: {
@@ -7223,6 +7239,16 @@ function trimTrailingSlashes(value) {
7223
7239
  while (end > 0 && value.charCodeAt(end - 1) === 47) end -= 1;
7224
7240
  return value.slice(0, end);
7225
7241
  }
7242
+ function normalizePrivateApiUrl(value) {
7243
+ const normalized = trimTrailingSlashes(value.trim());
7244
+ try {
7245
+ const url = new URL(normalized);
7246
+ if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error();
7247
+ } catch {
7248
+ throw new Error("Telemetry identity API URL must be an absolute HTTP(S) URL.");
7249
+ }
7250
+ return normalized;
7251
+ }
7226
7252
 
7227
7253
  // src/commands/theme-switch.ts
7228
7254
  import { existsSync as existsSync26, readFileSync as readFileSync19, writeFileSync as writeFileSync18 } from "fs";
@@ -7596,7 +7622,7 @@ async function runSimplifiedInit(blueprints) {
7596
7622
  const question = (q) => new Promise((resolve6) => rl.question(q, resolve6));
7597
7623
  console.log("\n? What blueprint would you like to scaffold?\n");
7598
7624
  console.log(" 1. Decantr default (recommended)");
7599
- console.log(" 2. Search registry...\n");
7625
+ console.log(" 2. Search official content...\n");
7600
7626
  const choice = await question("Enter choice (1 or 2): ");
7601
7627
  if (choice === "1" || choice === "") {
7602
7628
  rl.close();
@@ -8261,7 +8287,7 @@ function generateBrownfieldPrompt(ctx) {
8261
8287
  );
8262
8288
  }
8263
8289
  lines.push(
8264
- ctx.workflow === "hybrid-compose" ? "- Registry content is part of this task. Layer it onto the current app through existing route/component anchors before creating new runtime structure." : "- Registry content is optional in this workflow unless the task explicitly asks for blueprint/theme/pattern enrichment."
8290
+ ctx.workflow === "hybrid-compose" ? "- Official corpus content is part of this task. Layer it onto the current app through existing route/component anchors before creating new runtime structure." : "- Official corpus content is optional in this workflow unless the task explicitly asks for blueprint/theme/pattern enrichment."
8265
8291
  );
8266
8292
  lines.push(
8267
8293
  "- Do not invent routes, sections, shells, themes, or features that are not present in the compiled packs."
@@ -8948,13 +8974,13 @@ async function cmdSuggest(query, options = {}) {
8948
8974
  console.log(` ${cyan4(match.id)}${details ? ` ${dim4(details)}` : ""}`);
8949
8975
  }
8950
8976
  console.log("");
8951
- console.log(`${BOLD11}Registry patterns:${RESET18}`);
8977
+ console.log(`${BOLD11}Official content patterns:${RESET18}`);
8952
8978
  }
8953
8979
  if (matches.length === 0) {
8954
- console.log(dim4("No hosted/bundled registry patterns matched this query."));
8980
+ console.log(dim4("No official or bundled content patterns matched this query."));
8955
8981
  console.log("");
8956
8982
  console.log(
8957
- dim4('Use local law first, or run "decantr list patterns" to browse registry options.')
8983
+ dim4('Use local law first, or run "decantr list patterns" to browse official content.')
8958
8984
  );
8959
8985
  return;
8960
8986
  }
@@ -9099,7 +9125,7 @@ async function cmdList(type, sort, recommended, intelligenceSource, blueprintSet
9099
9125
  const customItems = registryClient.listCustomContent("themes");
9100
9126
  const customIds = new Set(customItems.map((c) => c.id));
9101
9127
  const registryItems = items.filter((i) => !customIds.has(i.id));
9102
- console.log(heading2(`Registry themes (${registryItems.length}):`));
9128
+ console.log(heading2(`Official themes (${registryItems.length}):`));
9103
9129
  for (const item of registryItems) {
9104
9130
  console.log(` ${cyan4(item.id)} ${dim4(item.description || item.name || "")}`);
9105
9131
  }
@@ -9149,10 +9175,10 @@ async function cmdList(type, sort, recommended, intelligenceSource, blueprintSet
9149
9175
  }
9150
9176
  function enableCliTelemetry(projectRoot) {
9151
9177
  optIn(projectRoot);
9152
- console.log(
9153
- `
9154
- ${CYAN10}Telemetry enabled.${RESET18} Decantr will send privacy-filtered CLI product telemetry for this project.`
9155
- );
9178
+ const status = getCliTelemetryIdentityStatus(projectRoot);
9179
+ const message = status.endpointConfigured ? "Privacy-filtered CLI telemetry can be sent to the configured private endpoint." : "The local preference is enabled, but no events are sent until DECANTR_TELEMETRY_ENDPOINT is configured.";
9180
+ console.log(`
9181
+ ${CYAN10}Telemetry preference enabled.${RESET18} ${message}`);
9156
9182
  console.log(`${DIM18}Set "telemetry": false in .decantr/project.json to opt out.${RESET18}`);
9157
9183
  }
9158
9184
  function readCliPackageVersion2() {
@@ -9458,7 +9484,7 @@ async function cmdInit(args) {
9458
9484
  if (args.offline && shouldUseRegistry) {
9459
9485
  offlineSeed = seedOfflineRegistry(projectRoot, projectRoot);
9460
9486
  if (offlineSeed.seeded) {
9461
- console.log(dim4(` Seeded offline registry content from ${offlineSeed.strategy}.`));
9487
+ console.log(dim4(` Seeded offline official content from ${offlineSeed.strategy}.`));
9462
9488
  } else if (requestedBlueprint || requestedArchetype) {
9463
9489
  console.log(
9464
9490
  error2("\nOffline blueprint/archetype scaffolding requires a local Decantr content source.")
@@ -9495,7 +9521,9 @@ async function cmdInit(args) {
9495
9521
  console.log(`
9496
9522
  ${YELLOW13}You're offline. Scaffolding minimal Decantr project.${RESET18}`);
9497
9523
  console.log(
9498
- dim4("Run `decantr sync` or `decantr upgrade` when online to pull full registry content.\n")
9524
+ dim4(
9525
+ "Run `decantr sync` or `decantr upgrade` when online to pull the latest official content.\n"
9526
+ )
9499
9527
  );
9500
9528
  const result2 = scaffoldMinimal(projectRoot, {
9501
9529
  workflowMode: policy.workflowMode,
@@ -9530,12 +9558,12 @@ ${YELLOW13}You're offline. Scaffolding minimal Decantr project.${RESET18}`);
9530
9558
  if (requestedBlueprint || requestedArchetype) {
9531
9559
  console.log(
9532
9560
  error2(
9533
- "\nThe requested blueprint/archetype could not be resolved from the hosted registry or local cache."
9561
+ "\nThe requested blueprint/archetype could not be resolved from the official content API or local cache."
9534
9562
  )
9535
9563
  );
9536
9564
  console.log(
9537
9565
  dim4(
9538
- "Run `decantr sync`, set DECANTR_CONTENT_DIR, or retry when the registry is reachable."
9566
+ "Run `decantr sync`, set DECANTR_CONTENT_DIR, or retry when the content API is reachable."
9539
9567
  )
9540
9568
  );
9541
9569
  process.exitCode = 1;
@@ -9543,10 +9571,12 @@ ${YELLOW13}You're offline. Scaffolding minimal Decantr project.${RESET18}`);
9543
9571
  }
9544
9572
  console.log(`
9545
9573
  ${YELLOW13}You're offline. Scaffolding Decantr default.${RESET18}`);
9546
- console.log(dim4("Run `decantr upgrade` when online, or visit decantr.ai/registry\n"));
9574
+ console.log(
9575
+ dim4("Run `decantr upgrade` when online, or see decantr.ai/reference/content-health.md\n")
9576
+ );
9547
9577
  selectedBlueprint = "default";
9548
9578
  } else if (shouldUseRegistry) {
9549
- console.log(dim4("Fetching registry content..."));
9579
+ console.log(dim4("Fetching official content..."));
9550
9580
  const blueprintsResult2 = await registryClient.fetchBlueprints();
9551
9581
  registrySource = blueprintsResult2.source.type === "api" ? "api" : "cache";
9552
9582
  const { selectedBlueprint: selected } = await runSimplifiedInit(blueprintsResult2.data.items);
@@ -9719,7 +9749,7 @@ ${YELLOW13}You're offline. Scaffolding Decantr default.${RESET18}`);
9719
9749
  } else {
9720
9750
  if (requestedBlueprint) {
9721
9751
  console.log(error2(` Error: Could not fetch blueprint "${options.blueprint}".`));
9722
- console.log(dim4("Resolve local registry content or retry against the hosted registry."));
9752
+ console.log(dim4("Resolve local corpus content or retry against the content API."));
9723
9753
  process.exitCode = 1;
9724
9754
  return;
9725
9755
  }
@@ -9734,7 +9764,7 @@ ${YELLOW13}You're offline. Scaffolding Decantr default.${RESET18}`);
9734
9764
  } else {
9735
9765
  if (requestedArchetype) {
9736
9766
  console.log(error2(` Error: Could not fetch archetype "${options.archetype}".`));
9737
- console.log(dim4("Resolve local registry content or retry against the hosted registry."));
9767
+ console.log(dim4("Resolve local corpus content or retry against the content API."));
9738
9768
  process.exitCode = 1;
9739
9769
  return;
9740
9770
  }
@@ -9751,7 +9781,7 @@ ${YELLOW13}You're offline. Scaffolding Decantr default.${RESET18}`);
9751
9781
  } else {
9752
9782
  if (requestedTheme) {
9753
9783
  console.log(error2(` Error: Could not fetch theme "${options.theme}".`));
9754
- console.log(dim4("Resolve local registry content or retry against the hosted registry."));
9784
+ console.log(dim4("Resolve local corpus content or retry against the content API."));
9755
9785
  process.exitCode = 1;
9756
9786
  return;
9757
9787
  }
@@ -9832,7 +9862,7 @@ ${YELLOW13}You're offline. Scaffolding Decantr default.${RESET18}`);
9832
9862
  );
9833
9863
  console.log(" 5. Build the shell and route structure first, then implement the pages");
9834
9864
  console.log(" 6. Run decantr check and decantr audit after implementation");
9835
- console.log(" 7. Explore more at decantr.ai/registry");
9865
+ console.log(" 7. Review the official corpus at decantr.ai/reference/content-health.md");
9836
9866
  } else {
9837
9867
  console.log(" 1. Fix the validation issue reported above");
9838
9868
  console.log(" 2. Run decantr refresh to restore compiled execution packs");
@@ -9848,9 +9878,9 @@ ${YELLOW13}You're offline. Scaffolding Decantr default.${RESET18}`);
9848
9878
  console.log(" Commands:");
9849
9879
  console.log(` ${cyan4("decantr status")} Project health`);
9850
9880
  console.log(` ${cyan4("decantr health")} Contract health report`);
9851
- console.log(` ${cyan4("decantr content-health")} Registry content health report`);
9881
+ console.log(` ${cyan4("decantr content-health")} Official content health report`);
9852
9882
  console.log(` ${cyan4("decantr studio")} Local health dashboard`);
9853
- console.log(` ${cyan4("decantr search")} Search registry`);
9883
+ console.log(` ${cyan4("decantr search")} Search official content`);
9854
9884
  console.log(` ${cyan4("decantr get")} Fetch content details`);
9855
9885
  console.log(` ${cyan4("decantr validate")} Check essence file`);
9856
9886
  console.log(` ${cyan4("decantr upgrade")} Update to latest patterns`);
@@ -9907,7 +9937,7 @@ Validation warnings: ${validation.errors.join(", ")}`));
9907
9937
  console.log(dim4("\u2500".repeat(50)));
9908
9938
  console.log("");
9909
9939
  if (registrySource === "cache") {
9910
- console.log(dim4('Run "decantr sync" when online to get the latest registry content.'));
9940
+ console.log(dim4('Run "decantr sync" when online to get the latest official content.'));
9911
9941
  }
9912
9942
  }
9913
9943
  async function cmdStatus(projectRoot = process.cwd()) {
@@ -9989,7 +10019,7 @@ async function cmdStatus(projectRoot = process.cwd()) {
9989
10019
  async function cmdSync() {
9990
10020
  const projectRoot = process.cwd();
9991
10021
  const cacheDir = join31(projectRoot, ".decantr", "cache");
9992
- console.log(heading2("Syncing registry content..."));
10022
+ console.log(heading2("Syncing official content..."));
9993
10023
  const result = await syncRegistry(cacheDir);
9994
10024
  if (result.synced.length > 0) {
9995
10025
  console.log(success4("Sync completed successfully."));
@@ -10087,7 +10117,7 @@ async function cmdAudit(filePath, options = {}) {
10087
10117
  console.log(heading2(`Critiquing ${filePath}...`));
10088
10118
  }
10089
10119
  if (hydration2.hydrated && !jsonOutput) {
10090
- console.log(dim4("Hydrated missing review pack from hosted registry."));
10120
+ console.log(dim4("Hydrated missing review pack from the content API."));
10091
10121
  console.log("");
10092
10122
  }
10093
10123
  const report2 = await critiqueProjectFile(filePath, projectRoot);
@@ -10108,7 +10138,7 @@ async function cmdAudit(filePath, options = {}) {
10108
10138
  if (hydration.hydrated && !jsonOutput) {
10109
10139
  console.log(
10110
10140
  dim4(
10111
- hydration.scope === "bundle" ? "Hydrated missing execution packs from hosted registry." : "Hydrated missing review pack and manifest from hosted registry."
10141
+ hydration.scope === "bundle" ? "Hydrated missing execution packs from the content API." : "Hydrated missing review pack and manifest from the content API."
10112
10142
  )
10113
10143
  );
10114
10144
  console.log("");
@@ -11006,7 +11036,7 @@ async function cmdAdoptWorkflow(args) {
11006
11036
  await cmdGraph(projectRoot, { displayRoot: process.cwd() });
11007
11037
  if (process.exitCode && process.exitCode !== 0) return;
11008
11038
  if (runVerify) {
11009
- const { cmdHealth } = await import("./health-KUPBUU3B.js");
11039
+ const { cmdHealth } = await import("./health-WZ562PRA.js");
11010
11040
  await cmdHealth(projectRoot, {
11011
11041
  browser: runBrowser,
11012
11042
  browserBaseUrl: baseUrl,
@@ -11080,7 +11110,7 @@ async function cmdVerifyWorkflow(args) {
11080
11110
  return;
11081
11111
  }
11082
11112
  if (workspaceMode) {
11083
- const { cmdWorkspace } = await import("./workspace-QAZ3F4VT.js");
11113
+ const { cmdWorkspace } = await import("./workspace-EDP7QG7T.js");
11084
11114
  await cmdWorkspace(process.cwd(), ["workspace", "health", ...withoutWorkflowOnlyFlags(args)]);
11085
11115
  return;
11086
11116
  }
@@ -11113,7 +11143,7 @@ async function cmdVerifyWorkflow(args) {
11113
11143
  }
11114
11144
  let guardExitCode;
11115
11145
  if (brownfield) {
11116
- const { cmdHeal, collectCheckIssues } = await import("./heal-2FK63EQE.js");
11146
+ const { cmdHeal, collectCheckIssues } = await import("./heal-AEMYO7T2.js");
11117
11147
  if (quietOutput) {
11118
11148
  const result = collectCheckIssues(workspaceInfo.appRoot, { brownfield: true });
11119
11149
  guardExitCode = result.issues.some((issue) => issue.type === "error") ? 1 : void 0;
@@ -11123,7 +11153,7 @@ async function cmdVerifyWorkflow(args) {
11123
11153
  process.exitCode = void 0;
11124
11154
  }
11125
11155
  }
11126
- const { cmdHealth, parseHealthArgs } = await import("./health-KUPBUU3B.js");
11156
+ const { cmdHealth, parseHealthArgs } = await import("./health-WZ562PRA.js");
11127
11157
  await cmdHealth(workspaceInfo.appRoot, parseHealthArgs(healthArgs));
11128
11158
  if (localPatterns) {
11129
11159
  const validation = validateLocalLaw(workspaceInfo.appRoot);
@@ -11808,7 +11838,7 @@ async function cmdCodifyWorkflow(args) {
11808
11838
  const suggestions = rankPatternCandidates({ query: mapPatternSlug, limit: 5 }, candidates);
11809
11839
  console.error(error2(`Could not find pattern "${mapPatternSlug}" to map into local law.`));
11810
11840
  if (suggestions.length > 0) {
11811
- console.error(dim4("Closest registry patterns:"));
11841
+ console.error(dim4("Closest official content patterns:"));
11812
11842
  for (const suggestion of suggestions) {
11813
11843
  const slug2 = suggestion.candidate.slug || suggestion.candidate.id;
11814
11844
  console.error(dim4(` ${slug2} - ${suggestion.candidate.name ?? slug2}`));
@@ -11824,12 +11854,12 @@ async function cmdCodifyWorkflow(args) {
11824
11854
  const slug = candidate.slug || candidate.id;
11825
11855
  console.log(
11826
11856
  success4(
11827
- `${result.replacedExisting ? "Updated" : "Wrote"} hosted pattern mapping proposal: ${result.patternPath}`
11857
+ `${result.replacedExisting ? "Updated" : "Wrote"} content pattern mapping proposal: ${result.patternPath}`
11828
11858
  )
11829
11859
  );
11830
11860
  console.log(
11831
11861
  dim4(
11832
- `Mapped registry pattern "${slug}" into local pattern "${result.localPatternId}" as advisory Hybrid law. No source files were changed.`
11862
+ `Mapped official content pattern "${slug}" into local pattern "${result.localPatternId}" as advisory Hybrid law. No source files were changed.`
11833
11863
  )
11834
11864
  );
11835
11865
  console.log(
@@ -11890,7 +11920,7 @@ async function cmdContentWorkflow(args) {
11890
11920
  return;
11891
11921
  }
11892
11922
  if (subcommand === "check" || subcommand === "health") {
11893
- const { cmdContentHealth, parseContentHealthArgs } = await import("./content-health-TDV4LP2C.js");
11923
+ const { cmdContentHealth, parseContentHealthArgs } = await import("./content-health-PYGEZZOV.js");
11894
11924
  await cmdContentHealth(
11895
11925
  process.cwd(),
11896
11926
  parseContentHealthArgs(["content-health", ...args.slice(2)])
@@ -12036,7 +12066,7 @@ ${BOLD11}Advanced primitives:${RESET18}
12036
12066
  decantr content-health [--json] [--markdown] [--ci]
12037
12067
  decantr telemetry status [--json]
12038
12068
  decantr telemetry explain [--json]
12039
- decantr telemetry link [--enable] [--org <slug>]
12069
+ decantr telemetry link --api-url <private-url> --api-key <key> [--enable] [--org <slug>]
12040
12070
  decantr rules preview [--project=<path>]
12041
12071
  decantr rules apply [--project=<path>]
12042
12072
  decantr validate [path]
@@ -12067,7 +12097,7 @@ ${BOLD11}Init Options:${RESET18}
12067
12097
  --offline Force offline mode
12068
12098
  --yes, -y Accept defaults, skip confirmations
12069
12099
  --registry Custom API URL (legacy alias; prefer DECANTR_API_URL)
12070
- --telemetry Opt this project into privacy-filtered CLI product telemetry
12100
+ --telemetry Enable the local preference; delivery requires DECANTR_TELEMETRY_ENDPOINT
12071
12101
 
12072
12102
  ${BOLD11}Commands:${RESET18}
12073
12103
  ${cyan4("setup")} Detect project state and recommend the right Decantr workflow
@@ -12111,12 +12141,12 @@ ${BOLD11}Advanced commands:${RESET18}
12111
12141
  ${cyan4("login")} Legacy API-key helper for compatibility scripts
12112
12142
  ${cyan4("logout")} Remove stored legacy credentials
12113
12143
  ${cyan4("analyze")} Brownfield entrypoint: scan an existing project and emit attach guidance
12114
- ${cyan4("telemetry")} Inspect or link this project's opted-in CLI telemetry identity
12144
+ ${cyan4("telemetry")} Inspect caller-configured private CLI telemetry
12115
12145
  ${cyan4("export")} Export design tokens to framework format (shadcn, tailwind, css-vars)
12116
- ${cyan4("registry")} Registry management and intelligence summary
12146
+ ${cyan4("registry")} Legacy alias for content-corpus and pack helpers
12117
12147
  ${cyan4("rules")} Preview/apply Decantr assistant bridge blocks to repo rule files
12118
12148
  ${cyan4("connect")} Configure editor-specific Decantr rules and MCP where supported
12119
- ${cyan4("upgrade")} Check for content updates from registry
12149
+ ${cyan4("upgrade")} Check for official content updates
12120
12150
  ${cyan4("help")} Show this help
12121
12151
 
12122
12152
  ${BOLD11}Examples:${RESET18}
@@ -12166,7 +12196,7 @@ ${BOLD11}Examples:${RESET18}
12166
12196
  decantr studio --report decantr-health.json
12167
12197
  decantr telemetry status
12168
12198
  decantr telemetry explain
12169
- decantr telemetry link --enable --org my-team
12199
+ decantr telemetry link --api-url https://telemetry.example/v1 --api-key <key>
12170
12200
  decantr audit
12171
12201
  decantr audit src/pages/HomePage.tsx
12172
12202
  decantr migrate --to v4
@@ -12429,7 +12459,7 @@ ${BOLD11}Options:${RESET18}
12429
12459
  --no-verify Skip the verification step
12430
12460
  --no-packs Skip hosted execution-pack hydration
12431
12461
  --ci, --init-ci Install the Decantr CI gate after adoption
12432
- --telemetry Opt this project into privacy-filtered CLI product telemetry
12462
+ --telemetry Enable the local preference; delivery requires DECANTR_TELEMETRY_ENDPOINT
12433
12463
  --merge-proposal Merge the observed proposal into an existing essence
12434
12464
  --replace-essence Replace an existing essence with backup
12435
12465
 
@@ -12814,7 +12844,7 @@ async function main() {
12814
12844
  break;
12815
12845
  }
12816
12846
  case "upgrade": {
12817
- const { cmdUpgrade } = await import("./upgrade-NN7NTA4L.js");
12847
+ const { cmdUpgrade } = await import("./upgrade-5ZE4VR3R.js");
12818
12848
  const { flags } = parseLooseArgs(args);
12819
12849
  const workspaceInfo = resolveWorkflowProject(flags, "upgrade");
12820
12850
  if (!workspaceInfo) break;
@@ -12829,7 +12859,7 @@ async function main() {
12829
12859
  `${YELLOW13}Note: \`decantr heal\` is deprecated. Use \`decantr check\` instead.${RESET18}`
12830
12860
  );
12831
12861
  }
12832
- const { cmdHeal } = await import("./heal-2FK63EQE.js");
12862
+ const { cmdHeal } = await import("./heal-AEMYO7T2.js");
12833
12863
  const { flags } = parseLooseArgs(args);
12834
12864
  const workspaceInfo = resolveWorkflowProject(flags, "check");
12835
12865
  if (!workspaceInfo) break;
@@ -12854,7 +12884,7 @@ async function main() {
12854
12884
  const { flags } = parseLooseArgs(args);
12855
12885
  const workspaceInfo = resolveWorkflowProject(flags, "health");
12856
12886
  if (!workspaceInfo) break;
12857
- const { cmdHealth, parseHealthArgs } = await import("./health-KUPBUU3B.js");
12887
+ const { cmdHealth, parseHealthArgs } = await import("./health-WZ562PRA.js");
12858
12888
  await cmdHealth(workspaceInfo.appRoot, parseHealthArgs(stripProjectArgs(args)));
12859
12889
  } catch (e) {
12860
12890
  console.error(error2(e.message));
@@ -12868,7 +12898,7 @@ async function main() {
12868
12898
  cmdContentHealthHelp();
12869
12899
  break;
12870
12900
  }
12871
- const { cmdContentHealth, parseContentHealthArgs } = await import("./content-health-TDV4LP2C.js");
12901
+ const { cmdContentHealth, parseContentHealthArgs } = await import("./content-health-PYGEZZOV.js");
12872
12902
  await cmdContentHealth(process.cwd(), parseContentHealthArgs(args));
12873
12903
  } catch (e) {
12874
12904
  console.error(error2(e.message));
@@ -12882,7 +12912,7 @@ async function main() {
12882
12912
  cmdStudioHelp();
12883
12913
  break;
12884
12914
  }
12885
- const { cmdStudio, parseStudioArgs } = await import("./studio-J6Z3AUAR.js");
12915
+ const { cmdStudio, parseStudioArgs } = await import("./studio-6Q2G4PTT.js");
12886
12916
  await cmdStudio(process.cwd(), parseStudioArgs(args));
12887
12917
  } catch (e) {
12888
12918
  console.error(error2(e.message));
@@ -12896,7 +12926,7 @@ async function main() {
12896
12926
  cmdWorkspaceHelp();
12897
12927
  break;
12898
12928
  }
12899
- const { cmdWorkspace } = await import("./workspace-QAZ3F4VT.js");
12929
+ const { cmdWorkspace } = await import("./workspace-EDP7QG7T.js");
12900
12930
  await cmdWorkspace(process.cwd(), args);
12901
12931
  } catch (e) {
12902
12932
  console.error(error2(e.message));
@@ -13196,10 +13226,14 @@ async function main() {
13196
13226
  process.exitCode = 1;
13197
13227
  break;
13198
13228
  }
13199
- console.error(dim4("Hosted registry critique is retired; running local decantr audit instead."));
13229
+ console.error(
13230
+ dim4("Hosted registry critique is retired; running local decantr audit instead.")
13231
+ );
13200
13232
  await cmdAudit(sourcePath, { json: args.includes("--json") });
13201
13233
  } else if (subcommand === "audit-project") {
13202
- console.error(dim4("Hosted registry project audit is retired; running local decantr audit instead."));
13234
+ console.error(
13235
+ dim4("Hosted registry project audit is retired; running local decantr audit instead.")
13236
+ );
13203
13237
  await cmdAudit(void 0, { json: args.includes("--json") });
13204
13238
  } else {
13205
13239
  console.error(