@decantr/cli 2.1.1 → 2.3.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.
@@ -18,15 +18,18 @@ import {
18
18
  import {
19
19
  buildGuardRegistryContext,
20
20
  createDoctrineMap,
21
+ getCliTelemetryIdentityStatus,
22
+ isOptedIn,
21
23
  optIn,
22
24
  scanAmbientContext,
23
25
  scanProjectInteractions,
24
26
  scanRoutes,
25
27
  scanStyling,
28
+ sendAnalyzeCompletedTelemetry,
26
29
  sendCliCommandTelemetry,
27
30
  sendNewProjectCompletedTelemetry,
28
31
  writeDoctrineMap
29
- } from "./chunk-JYEEXSUX.js";
32
+ } from "./chunk-IEW2QFYI.js";
30
33
 
31
34
  // src/index.ts
32
35
  import { existsSync as existsSync26, mkdirSync as mkdirSync12, readdirSync as readdirSync6, readFileSync as readFileSync19, writeFileSync as writeFileSync15 } from "fs";
@@ -2125,7 +2128,8 @@ var RESET2 = "\x1B[0m";
2125
2128
  var GREEN2 = "\x1B[32m";
2126
2129
  var CYAN = "\x1B[36m";
2127
2130
  var YELLOW = "\x1B[33m";
2128
- function cmdAnalyze(projectRoot = process.cwd(), workspace) {
2131
+ async function cmdAnalyze(projectRoot = process.cwd(), workspace) {
2132
+ const startedAt = Date.now();
2129
2133
  console.log(`
2130
2134
  ${BOLD}Analyzing project...${RESET2}
2131
2135
  `);
@@ -2275,6 +2279,22 @@ ${DIM2}Written to:${RESET2} ${outputPath}`);
2275
2279
  ${YELLOW}Next step:${RESET2} Review ${BOLD}.decantr/brownfield-report.md${RESET2}, then run ${BOLD}decantr init --existing --accept-proposal${RESET2} to attach Decantr using the observed proposal.
2276
2280
  `
2277
2281
  );
2282
+ await sendAnalyzeCompletedTelemetry({
2283
+ componentCount: components.componentCount,
2284
+ dependencyCategoryCount: [
2285
+ dependencies.auth,
2286
+ dependencies.db,
2287
+ dependencies.state,
2288
+ dependencies.styling,
2289
+ dependencies.ui
2290
+ ].filter((items) => items.length > 0).length,
2291
+ durationMs: Date.now() - startedAt,
2292
+ pageCount: components.pageCount,
2293
+ projectRoot,
2294
+ routeCount: routes.routes.length,
2295
+ success: true,
2296
+ targetFramework: project.framework
2297
+ });
2278
2298
  }
2279
2299
 
2280
2300
  // src/commands/create.ts
@@ -2948,7 +2968,7 @@ async function cmdMagic(prompt, projectRoot, options) {
2948
2968
  console.log(
2949
2969
  dim(" Running brownfield analysis instead so you can attach Decantr deliberately.\n")
2950
2970
  );
2951
- cmdAnalyze(projectRoot);
2971
+ await cmdAnalyze(projectRoot);
2952
2972
  console.log(
2953
2973
  `${BOLD2}Recommended next step:${RESET4} ${cyan("decantr init --existing --accept-proposal")}`
2954
2974
  );
@@ -4163,28 +4183,162 @@ function resolveDriftEntries(projectRoot, options) {
4163
4183
  }
4164
4184
  }
4165
4185
 
4186
+ // src/commands/telemetry.ts
4187
+ var BOLD5 = "\x1B[1m";
4188
+ var CYAN6 = "\x1B[36m";
4189
+ var DIM11 = "\x1B[2m";
4190
+ var GREEN11 = "\x1B[32m";
4191
+ var RESET11 = "\x1B[0m";
4192
+ var DEFAULT_API_URL = "https://api.decantr.ai/v1";
4193
+ async function cmdTelemetry(args, projectRoot = process.cwd()) {
4194
+ const subcommand = args[0] ?? "status";
4195
+ const options = parseTelemetryOptions(args.slice(1));
4196
+ if (subcommand === "--help" || subcommand === "-h" || subcommand === "help") {
4197
+ printTelemetryHelp();
4198
+ return;
4199
+ }
4200
+ if (subcommand === "status") {
4201
+ printTelemetryStatus(projectRoot, options);
4202
+ return;
4203
+ }
4204
+ if (subcommand === "link") {
4205
+ await linkTelemetryIdentity(projectRoot, options);
4206
+ return;
4207
+ }
4208
+ throw new Error(`Unknown telemetry command: ${subcommand}`);
4209
+ }
4210
+ function printTelemetryHelp() {
4211
+ console.log(`
4212
+ ${BOLD5}decantr telemetry${RESET11} \u2014 Inspect and link privacy-filtered CLI telemetry identity
4213
+
4214
+ ${BOLD5}Usage:${RESET11}
4215
+ decantr telemetry status [--json]
4216
+ decantr telemetry link [--enable] [--org <slug>] [--label <label>] [--api-key <key>] [--api-url <url>]
4217
+
4218
+ ${BOLD5}Examples:${RESET11}
4219
+ decantr init --telemetry
4220
+ decantr telemetry status
4221
+ decantr login --api-key=<your-key>
4222
+ decantr telemetry link --org my-team --label "CI runner"
4223
+ `);
4224
+ }
4225
+ function printTelemetryStatus(projectRoot, options) {
4226
+ const status = getCliTelemetryIdentityStatus(projectRoot, { create: false });
4227
+ if (options.json) {
4228
+ console.log(JSON.stringify(status, null, 2));
4229
+ return;
4230
+ }
4231
+ console.log(`
4232
+ ${BOLD5}Decantr telemetry${RESET11}`);
4233
+ console.log(` Enabled: ${status.enabled ? `${GREEN11}yes${RESET11}` : "no"}`);
4234
+ console.log(` Project: ${status.hasProjectConfig ? status.projectRoot : "not initialized"}`);
4235
+ console.log(` Install ID: ${status.installId ?? `${DIM11}not created yet${RESET11}`}`);
4236
+ console.log(` Project ID: ${status.projectId ?? `${DIM11}not created yet${RESET11}`}`);
4237
+ if (status.enabled) {
4238
+ console.log(
4239
+ DIM11 + "Run `decantr telemetry link` after login to attach these opaque IDs to your Decantr account/org." + RESET11
4240
+ );
4241
+ } else {
4242
+ console.log(DIM11 + "Run `decantr init --telemetry` or `decantr telemetry link --enable` to opt in." + RESET11);
4243
+ }
4244
+ }
4245
+ async function linkTelemetryIdentity(projectRoot, options) {
4246
+ if (options.enable && !isOptedIn(projectRoot)) {
4247
+ optIn(projectRoot);
4248
+ }
4249
+ if (!isOptedIn(projectRoot)) {
4250
+ throw new Error("This project has not opted into telemetry. Re-run with --enable or use `decantr init --telemetry`.");
4251
+ }
4252
+ const identity = getCliTelemetryIdentityStatus(projectRoot, { create: true });
4253
+ if (!identity.installId && !identity.projectId) {
4254
+ throw new Error("No telemetry identity could be created for this project.");
4255
+ }
4256
+ const apiKey = options.apiKey ?? getApiKeyOrToken();
4257
+ if (!apiKey) {
4258
+ throw new Error("Run `decantr login --api-key=<key>` or pass `--api-key <key>` before linking telemetry.");
4259
+ }
4260
+ const apiUrl = trimTrailingSlashes(options.apiUrl ?? process.env.DECANTR_API_URL ?? DEFAULT_API_URL);
4261
+ const response = await fetch(`${apiUrl}/me/telemetry-link`, {
4262
+ method: "POST",
4263
+ headers: {
4264
+ Authorization: `Bearer ${apiKey}`,
4265
+ "Content-Type": "application/json"
4266
+ },
4267
+ body: JSON.stringify({
4268
+ install_id: identity.installId,
4269
+ project_id: identity.projectId,
4270
+ org_slug: options.org,
4271
+ label: options.label
4272
+ })
4273
+ });
4274
+ if (!response.ok) {
4275
+ const body2 = await response.json().catch(() => null);
4276
+ throw new Error(body2?.error ?? `Telemetry link failed with HTTP ${response.status}.`);
4277
+ }
4278
+ const body = await response.json().catch(() => ({ linked: 0 }));
4279
+ console.log(`${GREEN11}Telemetry identity linked.${RESET11}`);
4280
+ console.log(` Linked: ${body.linked ?? 0}`);
4281
+ console.log(` Install ID: ${identity.installId ?? `${DIM11}none${RESET11}`}`);
4282
+ console.log(` Project ID: ${identity.projectId ?? `${DIM11}none${RESET11}`}`);
4283
+ if (options.org) console.log(` Org: ${CYAN6}${options.org}${RESET11}`);
4284
+ console.log(DIM11 + "These opaque IDs now attribute opted-in CLI usage to your Decantr account/org." + RESET11);
4285
+ }
4286
+ function parseTelemetryOptions(args) {
4287
+ const options = {};
4288
+ for (let i = 0; i < args.length; i++) {
4289
+ const arg = args[i];
4290
+ if (arg === "--enable") {
4291
+ options.enable = true;
4292
+ } else if (arg === "--json") {
4293
+ options.json = true;
4294
+ } else if (arg === "--org" && args[i + 1]) {
4295
+ options.org = args[++i];
4296
+ } else if (arg.startsWith("--org=")) {
4297
+ options.org = arg.slice("--org=".length);
4298
+ } else if (arg === "--label" && args[i + 1]) {
4299
+ options.label = args[++i];
4300
+ } else if (arg.startsWith("--label=")) {
4301
+ options.label = arg.slice("--label=".length);
4302
+ } else if (arg === "--api-key" && args[i + 1]) {
4303
+ options.apiKey = args[++i];
4304
+ } else if (arg.startsWith("--api-key=")) {
4305
+ options.apiKey = arg.slice("--api-key=".length);
4306
+ } else if (arg === "--api-url" && args[i + 1]) {
4307
+ options.apiUrl = args[++i];
4308
+ } else if (arg.startsWith("--api-url=")) {
4309
+ options.apiUrl = arg.slice("--api-url=".length);
4310
+ }
4311
+ }
4312
+ return options;
4313
+ }
4314
+ function trimTrailingSlashes(value) {
4315
+ let end = value.length;
4316
+ while (end > 0 && value.charCodeAt(end - 1) === 47) end -= 1;
4317
+ return value.slice(0, end);
4318
+ }
4319
+
4166
4320
  // src/commands/theme-switch.ts
4167
4321
  import { existsSync as existsSync23, readFileSync as readFileSync16, writeFileSync as writeFileSync13 } from "fs";
4168
4322
  import { join as join24 } from "path";
4169
4323
  import { isV4 as isV46 } from "@decantr/essence-spec";
4170
- var GREEN11 = "\x1B[32m";
4324
+ var GREEN12 = "\x1B[32m";
4171
4325
  var RED10 = "\x1B[31m";
4172
4326
  var YELLOW7 = "\x1B[33m";
4173
- var DIM11 = "\x1B[2m";
4174
- var RESET11 = "\x1B[0m";
4327
+ var DIM12 = "\x1B[2m";
4328
+ var RESET12 = "\x1B[0m";
4175
4329
  var VALID_THEME_SHAPES = ["sharp", "rounded", "pill"];
4176
4330
  var VALID_THEME_MODES = ["light", "dark", "auto"];
4177
4331
  async function cmdThemeSwitch(themeName, args, projectRoot = process.cwd()) {
4178
4332
  if (!themeName) {
4179
4333
  console.error(
4180
- `${RED10}Usage: decantr theme switch <themeName> [--shape <s>] [--mode <m>]${RESET11}`
4334
+ `${RED10}Usage: decantr theme switch <themeName> [--shape <s>] [--mode <m>]${RESET12}`
4181
4335
  );
4182
4336
  process.exitCode = 1;
4183
4337
  return;
4184
4338
  }
4185
4339
  const essencePath = join24(projectRoot, "decantr.essence.json");
4186
4340
  if (!existsSync23(essencePath)) {
4187
- console.error(`${RED10}No decantr.essence.json found. Run \`decantr init\` first.${RESET11}`);
4341
+ console.error(`${RED10}No decantr.essence.json found. Run \`decantr init\` first.${RESET12}`);
4188
4342
  process.exitCode = 1;
4189
4343
  return;
4190
4344
  }
@@ -4192,13 +4346,13 @@ async function cmdThemeSwitch(themeName, args, projectRoot = process.cwd()) {
4192
4346
  try {
4193
4347
  parsed = JSON.parse(readFileSync16(essencePath, "utf-8"));
4194
4348
  } catch (e) {
4195
- console.error(`${RED10}Could not read essence: ${e.message}${RESET11}`);
4349
+ console.error(`${RED10}Could not read essence: ${e.message}${RESET12}`);
4196
4350
  process.exitCode = 1;
4197
4351
  return;
4198
4352
  }
4199
4353
  if (!isV46(parsed)) {
4200
4354
  console.error(
4201
- `${RED10}Active workflows require Essence v4.0.0. Run \`decantr migrate --to v4\` first.${RESET11}`
4355
+ `${RED10}Active workflows require Essence v4.0.0. Run \`decantr migrate --to v4\` first.${RESET12}`
4202
4356
  );
4203
4357
  process.exitCode = 1;
4204
4358
  return;
@@ -4220,14 +4374,14 @@ async function cmdThemeSwitch(themeName, args, projectRoot = process.cwd()) {
4220
4374
  }
4221
4375
  if (shape && !VALID_THEME_SHAPES.includes(shape)) {
4222
4376
  console.error(
4223
- `${RED10}Invalid shape "${shape}". Must be one of: ${VALID_THEME_SHAPES.join(", ")}.${RESET11}`
4377
+ `${RED10}Invalid shape "${shape}". Must be one of: ${VALID_THEME_SHAPES.join(", ")}.${RESET12}`
4224
4378
  );
4225
4379
  process.exitCode = 1;
4226
4380
  return;
4227
4381
  }
4228
4382
  if (mode && !VALID_THEME_MODES.includes(mode)) {
4229
4383
  console.error(
4230
- `${RED10}Invalid mode "${mode}". Must be one of: ${VALID_THEME_MODES.join(", ")}.${RESET11}`
4384
+ `${RED10}Invalid mode "${mode}". Must be one of: ${VALID_THEME_MODES.join(", ")}.${RESET12}`
4231
4385
  );
4232
4386
  process.exitCode = 1;
4233
4387
  return;
@@ -4257,27 +4411,27 @@ async function cmdThemeSwitch(themeName, args, projectRoot = process.cwd()) {
4257
4411
  } catch {
4258
4412
  }
4259
4413
  writeFileSync13(essencePath, JSON.stringify(essence, null, 2) + "\n");
4260
- console.log(`${GREEN11}Switched theme: ${oldThemeId} \u2192 ${themeName}${RESET11}`);
4261
- if (shape) console.log(` ${DIM11}Shape: ${shape}${RESET11}`);
4262
- if (mode) console.log(` ${DIM11}Mode: ${mode}${RESET11}`);
4414
+ console.log(`${GREEN12}Switched theme: ${oldThemeId} \u2192 ${themeName}${RESET12}`);
4415
+ if (shape) console.log(` ${DIM12}Shape: ${shape}${RESET12}`);
4416
+ if (mode) console.log(` ${DIM12}Mode: ${mode}${RESET12}`);
4263
4417
  await refreshDerivedFiles(projectRoot, essence, registryClient);
4264
4418
  console.log(
4265
- `${GREEN11}Derived files refreshed (tokens.css, treatments.css, all contexts).${RESET11}`
4419
+ `${GREEN12}Derived files refreshed (tokens.css, treatments.css, all contexts).${RESET12}`
4266
4420
  );
4267
- console.log(`${YELLOW7}Guard will flag code using old tokens. Run \`decantr check\`.${RESET11}`);
4421
+ console.log(`${YELLOW7}Guard will flag code using old tokens. Run \`decantr check\`.${RESET12}`);
4268
4422
  }
4269
4423
 
4270
4424
  // src/prompts.ts
4271
4425
  import { createInterface } from "readline";
4272
- var BOLD5 = "\x1B[1m";
4273
- var DIM12 = "\x1B[2m";
4274
- var RESET12 = "\x1B[0m";
4275
- var GREEN12 = "\x1B[32m";
4426
+ var BOLD6 = "\x1B[1m";
4427
+ var DIM13 = "\x1B[2m";
4428
+ var RESET13 = "\x1B[0m";
4429
+ var GREEN13 = "\x1B[32m";
4276
4430
  var YELLOW8 = "\x1B[33m";
4277
- var CYAN6 = "\x1B[36m";
4431
+ var CYAN7 = "\x1B[36m";
4278
4432
  function ask(question, defaultValue) {
4279
4433
  const rl = createInterface({ input: process.stdin, output: process.stdout });
4280
- const prompt = defaultValue ? `${question} ${DIM12}(${defaultValue})${RESET12}: ` : `${question}: `;
4434
+ const prompt = defaultValue ? `${question} ${DIM13}(${defaultValue})${RESET13}: ` : `${question}: `;
4281
4435
  return new Promise((resolve5) => {
4282
4436
  rl.question(prompt, (answer) => {
4283
4437
  rl.close();
@@ -4287,14 +4441,14 @@ function ask(question, defaultValue) {
4287
4441
  }
4288
4442
  async function select(question, options, defaultIdx = 0, allowOther = false) {
4289
4443
  console.log(`
4290
- ${BOLD5}${question}${RESET12}`);
4444
+ ${BOLD6}${question}${RESET13}`);
4291
4445
  for (let i = 0; i < options.length; i++) {
4292
- const marker = i === defaultIdx ? `${GREEN12}>${RESET12}` : " ";
4293
- const desc = options[i].description ? ` ${DIM12}\u2014 ${options[i].description}${RESET12}` : "";
4446
+ const marker = i === defaultIdx ? `${GREEN13}>${RESET13}` : " ";
4447
+ const desc = options[i].description ? ` ${DIM13}\u2014 ${options[i].description}${RESET13}` : "";
4294
4448
  console.log(` ${marker} ${i + 1}. ${options[i].label}${desc}`);
4295
4449
  }
4296
4450
  if (allowOther) {
4297
- console.log(` ${options.length + 1}. ${DIM12}other (enter custom value)${RESET12}`);
4451
+ console.log(` ${options.length + 1}. ${DIM13}other (enter custom value)${RESET13}`);
4298
4452
  }
4299
4453
  const maxIdx = allowOther ? options.length + 1 : options.length;
4300
4454
  const answer = await ask(`Choose (1-${maxIdx})`, String(defaultIdx + 1));
@@ -4313,11 +4467,11 @@ async function confirm(question, defaultYes = true) {
4313
4467
  }
4314
4468
  function warn(message) {
4315
4469
  console.log(`
4316
- ${YELLOW8} Warning: ${message}${RESET12}`);
4470
+ ${YELLOW8} Warning: ${message}${RESET13}`);
4317
4471
  }
4318
4472
  function showDetection(detected) {
4319
4473
  console.log(`
4320
- ${CYAN6}Detected project configuration:${RESET12}`);
4474
+ ${CYAN7}Detected project configuration:${RESET13}`);
4321
4475
  if (detected.framework !== "unknown") {
4322
4476
  const version = detected.version ? ` ${detected.version}` : "";
4323
4477
  console.log(` Framework: ${detected.framework}${version}`);
@@ -4326,13 +4480,13 @@ ${CYAN6}Detected project configuration:${RESET12}`);
4326
4480
  console.log(` Package manager: ${detected.packageManager}`);
4327
4481
  }
4328
4482
  if (detected.hasTypeScript) {
4329
- console.log(` TypeScript: ${GREEN12}yes${RESET12}`);
4483
+ console.log(` TypeScript: ${GREEN13}yes${RESET13}`);
4330
4484
  }
4331
4485
  if (detected.hasTailwind) {
4332
- console.log(` Tailwind CSS: ${GREEN12}yes${RESET12}`);
4486
+ console.log(` Tailwind CSS: ${GREEN13}yes${RESET13}`);
4333
4487
  }
4334
4488
  if (detected.existingEssence) {
4335
- console.log(` Existing essence: ${YELLOW8}yes${RESET12}`);
4489
+ console.log(` Existing essence: ${YELLOW8}yes${RESET13}`);
4336
4490
  }
4337
4491
  }
4338
4492
  async function runInteractivePrompts(detected, archetypes, blueprints, themes, workflowSeed) {
@@ -4406,7 +4560,7 @@ async function runInteractivePrompts(detected, archetypes, blueprints, themes, w
4406
4560
  warn(`This project appears to be ${detected.framework} but you selected ${target}.`);
4407
4561
  const proceed = await confirm("Continue anyway?", false);
4408
4562
  if (!proceed) {
4409
- console.log(`${DIM12}Using detected framework: ${detected.framework}${RESET12}`);
4563
+ console.log(`${DIM13}Using detected framework: ${detected.framework}${RESET13}`);
4410
4564
  }
4411
4565
  }
4412
4566
  const guardMode = await select(
@@ -4797,29 +4951,29 @@ function resolveWorkspaceInfo(cwd, projectArg) {
4797
4951
  }
4798
4952
 
4799
4953
  // src/index.ts
4800
- var BOLD6 = "\x1B[1m";
4801
- var DIM13 = "\x1B[2m";
4802
- var RESET13 = "\x1B[0m";
4954
+ var BOLD7 = "\x1B[1m";
4955
+ var DIM14 = "\x1B[2m";
4956
+ var RESET14 = "\x1B[0m";
4803
4957
  var RED11 = "\x1B[31m";
4804
- var GREEN13 = "\x1B[32m";
4805
- var CYAN7 = "\x1B[36m";
4958
+ var GREEN14 = "\x1B[32m";
4959
+ var CYAN8 = "\x1B[36m";
4806
4960
  var YELLOW9 = "\x1B[33m";
4807
4961
  function heading2(text) {
4808
4962
  return `
4809
- ${BOLD6}${text}${RESET13}
4963
+ ${BOLD7}${text}${RESET14}
4810
4964
  `;
4811
4965
  }
4812
4966
  function success3(text) {
4813
- return `${GREEN13}${text}${RESET13}`;
4967
+ return `${GREEN14}${text}${RESET14}`;
4814
4968
  }
4815
4969
  function error3(text) {
4816
- return `${RED11}${text}${RESET13}`;
4970
+ return `${RED11}${text}${RESET14}`;
4817
4971
  }
4818
4972
  function dim3(text) {
4819
- return `${DIM13}${text}${RESET13}`;
4973
+ return `${DIM14}${text}${RESET14}`;
4820
4974
  }
4821
4975
  function cyan3(text) {
4822
- return `${CYAN7}${text}${RESET13}`;
4976
+ return `${CYAN8}${text}${RESET14}`;
4823
4977
  }
4824
4978
  function formatIntelligenceSummary(intelligence) {
4825
4979
  if (!intelligence) {
@@ -5542,7 +5696,7 @@ async function printHostedExecutionPackBundle(essencePath, namespace, jsonOutput
5542
5696
  console.log(` Files written: ${writtenContextPaths.length}`);
5543
5697
  }
5544
5698
  console.log("");
5545
- console.log(`${BOLD6}Route Plan:${RESET13}`);
5699
+ console.log(`${BOLD7}Route Plan:${RESET14}`);
5546
5700
  for (const route of typedBundle.scaffold.data.routes) {
5547
5701
  const patterns = route.patternIds.length > 0 ? route.patternIds.join(", ") : "none";
5548
5702
  const pageLabel = route.sectionId ? `${route.sectionId}/${route.pageId}` : route.pageId;
@@ -5781,7 +5935,7 @@ async function cmdSearch(query, type, sort, recommended, intelligenceSource) {
5781
5935
  }
5782
5936
  console.log(heading2(`${results.length} result(s) for "${query}"`));
5783
5937
  for (const r of results) {
5784
- console.log(` ${cyan3(r.type.padEnd(12))} ${BOLD6}${r.slug}${RESET13}`);
5938
+ console.log(` ${cyan3(r.type.padEnd(12))} ${BOLD7}${r.slug}${RESET14}`);
5785
5939
  console.log(` ${dim3(r.description || "")}`);
5786
5940
  const intelligenceSummary = formatIntelligenceSummary(r.intelligence);
5787
5941
  if (intelligenceSummary) {
@@ -5812,14 +5966,14 @@ async function cmdSuggest(query, type) {
5812
5966
  const exact = results.filter((r) => r.slug.toLowerCase().includes(queryLower));
5813
5967
  const related = results.filter((r) => !r.slug.toLowerCase().includes(queryLower));
5814
5968
  if (exact.length > 0) {
5815
- console.log(`${BOLD6}Direct matches:${RESET13}`);
5969
+ console.log(`${BOLD7}Direct matches:${RESET14}`);
5816
5970
  for (const r of exact.slice(0, 3)) {
5817
5971
  console.log(` ${cyan3(r.slug)} - ${r.description || ""}`);
5818
5972
  }
5819
5973
  console.log("");
5820
5974
  }
5821
5975
  if (related.length > 0) {
5822
- console.log(`${BOLD6}Related:${RESET13}`);
5976
+ console.log(`${BOLD7}Related:${RESET14}`);
5823
5977
  for (const r of related.slice(0, 5)) {
5824
5978
  console.log(` ${cyan3(r.slug)} - ${r.description || ""}`);
5825
5979
  }
@@ -5883,14 +6037,14 @@ async function cmdValidate(path) {
5883
6037
  return;
5884
6038
  }
5885
6039
  const detectedVersion = isV47(essence) ? "v4" : "legacy";
5886
- console.log(`${DIM13}Detected essence version: ${detectedVersion}${RESET13}`);
6040
+ console.log(`${DIM14}Detected essence version: ${detectedVersion}${RESET14}`);
5887
6041
  const result = validateEssence2(essence);
5888
6042
  if (result.valid) {
5889
6043
  console.log(success3(`Essence is valid (${detectedVersion}).`));
5890
6044
  } else {
5891
6045
  console.error(error3("Validation failed:"));
5892
6046
  for (const err of result.errors) {
5893
- console.error(` ${RED11}${err}${RESET13}`);
6047
+ console.error(` ${RED11}${err}${RESET14}`);
5894
6048
  }
5895
6049
  process.exitCode = 1;
5896
6050
  return;
@@ -5911,9 +6065,9 @@ async function cmdValidate(path) {
5911
6065
  console.log(heading2("Guard violations:"));
5912
6066
  for (const v of violations) {
5913
6067
  const vr = v;
5914
- console.log(` ${YELLOW9}[${vr.rule}]${RESET13} ${vr.message}`);
6068
+ console.log(` ${YELLOW9}[${vr.rule}]${RESET14} ${vr.message}`);
5915
6069
  if (vr.suggestion) {
5916
- console.log(` ${DIM13}Suggestion: ${vr.suggestion}${RESET13}`);
6070
+ console.log(` ${DIM14}Suggestion: ${vr.suggestion}${RESET14}`);
5917
6071
  }
5918
6072
  }
5919
6073
  const hasError = violations.some((v) => v.severity === "error");
@@ -5985,9 +6139,9 @@ function enableCliTelemetry(projectRoot) {
5985
6139
  optIn(projectRoot);
5986
6140
  console.log(
5987
6141
  `
5988
- ${CYAN7}Telemetry enabled.${RESET13} Decantr will send privacy-filtered CLI product telemetry for this project.`
6142
+ ${CYAN8}Telemetry enabled.${RESET14} Decantr will send privacy-filtered CLI product telemetry for this project.`
5989
6143
  );
5990
- console.log(`${DIM13}Set "telemetry": false in .decantr/project.json to opt out.${RESET13}`);
6144
+ console.log(`${DIM14}Set "telemetry": false in .decantr/project.json to opt out.${RESET14}`);
5991
6145
  }
5992
6146
  function readCliPackageVersion() {
5993
6147
  const here = dirname4(fileURLToPath2(import.meta.url));
@@ -6109,7 +6263,7 @@ async function applyAcceptedBrownfieldProposal(input) {
6109
6263
  error3("Brownfield proposal produced an invalid Decantr essence. No files were changed.")
6110
6264
  );
6111
6265
  for (const validationError of validation.errors) {
6112
- console.log(` ${RED11}${validationError}${RESET13}`);
6266
+ console.log(` ${RED11}${validationError}${RESET14}`);
6113
6267
  }
6114
6268
  process.exitCode = 1;
6115
6269
  return;
@@ -6200,7 +6354,7 @@ async function cmdInit(args) {
6200
6354
  console.log(dim3(" Found .decantr/init-seed.json brownfield guidance."));
6201
6355
  }
6202
6356
  if (detected.existingEssence && !args.existing) {
6203
- console.log(`${YELLOW9}Warning: decantr.essence.json already exists.${RESET13}`);
6357
+ console.log(`${YELLOW9}Warning: decantr.essence.json already exists.${RESET14}`);
6204
6358
  const overwrite = await confirm("Overwrite existing configuration?", false);
6205
6359
  if (!overwrite) {
6206
6360
  console.log(dim3("Cancelled."));
@@ -6302,7 +6456,7 @@ async function cmdInit(args) {
6302
6456
  } else if (shouldUseRegistry && !apiAvailable) {
6303
6457
  if (!args.blueprint) {
6304
6458
  console.log(`
6305
- ${YELLOW9}You're offline. Scaffolding minimal Decantr project.${RESET13}`);
6459
+ ${YELLOW9}You're offline. Scaffolding minimal Decantr project.${RESET14}`);
6306
6460
  console.log(
6307
6461
  dim3("Run `decantr sync` or `decantr upgrade` when online to pull full registry content.\n")
6308
6462
  );
@@ -6350,7 +6504,7 @@ ${YELLOW9}You're offline. Scaffolding minimal Decantr project.${RESET13}`);
6350
6504
  return;
6351
6505
  }
6352
6506
  console.log(`
6353
- ${YELLOW9}You're offline. Scaffolding Decantr default.${RESET13}`);
6507
+ ${YELLOW9}You're offline. Scaffolding Decantr default.${RESET14}`);
6354
6508
  console.log(dim3("Run `decantr upgrade` when online, or visit decantr.ai/registry\n"));
6355
6509
  selectedBlueprint = "default";
6356
6510
  } else if (shouldUseRegistry) {
@@ -6531,7 +6685,7 @@ ${YELLOW9}You're offline. Scaffolding Decantr default.${RESET13}`);
6531
6685
  return;
6532
6686
  }
6533
6687
  console.log(
6534
- `${YELLOW9} Warning: Could not fetch blueprint "${options.blueprint}". Using defaults.${RESET13}`
6688
+ `${YELLOW9} Warning: Could not fetch blueprint "${options.blueprint}". Using defaults.${RESET14}`
6535
6689
  );
6536
6690
  }
6537
6691
  } else if (shouldUseRegistry && options.archetype) {
@@ -6546,7 +6700,7 @@ ${YELLOW9}You're offline. Scaffolding Decantr default.${RESET13}`);
6546
6700
  return;
6547
6701
  }
6548
6702
  console.log(
6549
- `${YELLOW9} Warning: Could not fetch archetype "${options.archetype}". Using defaults.${RESET13}`
6703
+ `${YELLOW9} Warning: Could not fetch archetype "${options.archetype}". Using defaults.${RESET14}`
6550
6704
  );
6551
6705
  }
6552
6706
  }
@@ -6563,7 +6717,7 @@ ${YELLOW9}You're offline. Scaffolding Decantr default.${RESET13}`);
6563
6717
  return;
6564
6718
  }
6565
6719
  console.log(
6566
- `${YELLOW9} Warning: Could not fetch theme "${options.theme}". Using defaults.${RESET13}`
6720
+ `${YELLOW9} Warning: Could not fetch theme "${options.theme}". Using defaults.${RESET14}`
6567
6721
  );
6568
6722
  }
6569
6723
  }
@@ -6689,7 +6843,7 @@ Validation warnings: ${validation.errors.join(", ")}`));
6689
6843
  };
6690
6844
  const curatedPrompt = generateCuratedPrompt(promptCtx);
6691
6845
  console.log("");
6692
- console.log(`${BOLD6}Prompt for your AI assistant:${RESET13}`);
6846
+ console.log(`${BOLD7}Prompt for your AI assistant:${RESET14}`);
6693
6847
  console.log(dim3("\u2500".repeat(50)));
6694
6848
  console.log("");
6695
6849
  console.log(curatedPrompt);
@@ -6706,7 +6860,7 @@ async function cmdStatus() {
6706
6860
  const projectJsonPath = join27(projectRoot, ".decantr", "project.json");
6707
6861
  console.log(heading2("Decantr Project Status"));
6708
6862
  if (!existsSync26(essencePath)) {
6709
- console.log(`${RED11}No decantr.essence.json found.${RESET13}`);
6863
+ console.log(`${RED11}No decantr.essence.json found.${RESET14}`);
6710
6864
  console.log(dim3('Run "decantr init" to create one.'));
6711
6865
  return;
6712
6866
  }
@@ -6714,11 +6868,11 @@ async function cmdStatus() {
6714
6868
  const essence = JSON.parse(readFileSync19(essencePath, "utf-8"));
6715
6869
  const validation = validateEssence2(essence);
6716
6870
  const essenceVersion = isV47(essence) ? "v4" : "legacy";
6717
- console.log(`${BOLD6}Essence:${RESET13}`);
6871
+ console.log(`${BOLD7}Essence:${RESET14}`);
6718
6872
  if (validation.valid) {
6719
- console.log(` ${GREEN13}Valid${RESET13} (${essenceVersion})`);
6873
+ console.log(` ${GREEN14}Valid${RESET14} (${essenceVersion})`);
6720
6874
  } else {
6721
- console.log(` ${RED11}Invalid: ${validation.errors.join(", ")}${RESET13}`);
6875
+ console.log(` ${RED11}Invalid: ${validation.errors.join(", ")}${RESET14}`);
6722
6876
  }
6723
6877
  if (isV47(essence)) {
6724
6878
  const v4 = essence;
@@ -6726,7 +6880,7 @@ async function cmdStatus() {
6726
6880
  const flatPages = sections.flatMap((section) => section.pages ?? []);
6727
6881
  const resolvedShell = sections.find((section) => section.role === "primary")?.shell || sections[0]?.shell || v4.blueprint.shell || "unknown";
6728
6882
  const resolvedFeatures = v4.blueprint.features ?? [];
6729
- console.log(` ${BOLD6}DNA:${RESET13}`);
6883
+ console.log(` ${BOLD7}DNA:${RESET14}`);
6730
6884
  console.log(` Theme: ${v4.dna.theme.id} (${v4.dna.theme.mode})`);
6731
6885
  console.log(
6732
6886
  ` Spacing: ${v4.dna.spacing.density} density, ${v4.dna.spacing.content_gap} gap`
@@ -6738,42 +6892,42 @@ async function cmdStatus() {
6738
6892
  );
6739
6893
  console.log(` Accessibility: WCAG ${v4.dna.accessibility.wcag_level}`);
6740
6894
  console.log(` Personality: ${v4.dna.personality.join(", ")}`);
6741
- console.log(` ${BOLD6}Blueprint:${RESET13}`);
6895
+ console.log(` ${BOLD7}Blueprint:${RESET14}`);
6742
6896
  console.log(` Shell: ${resolvedShell}`);
6743
6897
  console.log(` Pages: ${flatPages.length}`);
6744
6898
  console.log(` Sections: ${sections.length}`);
6745
6899
  console.log(
6746
6900
  ` Features: ${resolvedFeatures.length > 0 ? resolvedFeatures.join(", ") : "none"}`
6747
6901
  );
6748
- console.log(` ${BOLD6}Meta:${RESET13}`);
6902
+ console.log(` ${BOLD7}Meta:${RESET14}`);
6749
6903
  console.log(` Archetype: ${v4.meta.archetype}`);
6750
6904
  console.log(` Target: ${v4.meta.target}`);
6751
6905
  console.log(
6752
6906
  ` Guard: ${v4.meta.guard.mode} (DNA: ${v4.meta.guard.dna_enforcement}, Blueprint: ${v4.meta.guard.blueprint_enforcement})`
6753
6907
  );
6754
6908
  } else {
6755
- console.log(` ${YELLOW9}Run \`decantr migrate --to v4\` to upgrade this project.${RESET13}`);
6909
+ console.log(` ${YELLOW9}Run \`decantr migrate --to v4\` to upgrade this project.${RESET14}`);
6756
6910
  }
6757
6911
  } catch (e) {
6758
- console.log(` ${RED11}Error reading essence: ${e.message}${RESET13}`);
6912
+ console.log(` ${RED11}Error reading essence: ${e.message}${RESET14}`);
6759
6913
  }
6760
6914
  console.log("");
6761
- console.log(`${BOLD6}Sync Status:${RESET13}`);
6915
+ console.log(`${BOLD7}Sync Status:${RESET14}`);
6762
6916
  if (existsSync26(projectJsonPath)) {
6763
6917
  try {
6764
6918
  const projectJson = JSON.parse(readFileSync19(projectJsonPath, "utf-8"));
6765
6919
  const syncStatus = projectJson.sync?.status || "unknown";
6766
6920
  const lastSync = projectJson.sync?.lastSync || "never";
6767
6921
  const source = projectJson.sync?.registrySource || "unknown";
6768
- const statusColor = syncStatus === "synced" ? GREEN13 : YELLOW9;
6769
- console.log(` Status: ${statusColor}${syncStatus}${RESET13}`);
6922
+ const statusColor = syncStatus === "synced" ? GREEN14 : YELLOW9;
6923
+ console.log(` Status: ${statusColor}${syncStatus}${RESET14}`);
6770
6924
  console.log(` Last sync: ${dim3(lastSync)}`);
6771
6925
  console.log(` Source: ${dim3(source)}`);
6772
6926
  } catch {
6773
- console.log(` ${YELLOW9}Could not read project.json${RESET13}`);
6927
+ console.log(` ${YELLOW9}Could not read project.json${RESET14}`);
6774
6928
  }
6775
6929
  } else {
6776
- console.log(` ${YELLOW9}No .decantr/project.json found${RESET13}`);
6930
+ console.log(` ${YELLOW9}No .decantr/project.json found${RESET14}`);
6777
6931
  console.log(dim3(' Run "decantr init" to create project files.'));
6778
6932
  }
6779
6933
  }
@@ -6786,12 +6940,12 @@ async function cmdSync() {
6786
6940
  console.log(success3("Sync completed successfully."));
6787
6941
  console.log(` Synced: ${result.synced.join(", ")}`);
6788
6942
  if (result.failed.length > 0) {
6789
- console.log(` ${YELLOW9}Failed: ${result.failed.join(", ")}${RESET13}`);
6943
+ console.log(` ${YELLOW9}Failed: ${result.failed.join(", ")}${RESET14}`);
6790
6944
  }
6791
6945
  } else {
6792
- console.log(`${YELLOW9}Could not sync: API unavailable${RESET13}`);
6946
+ console.log(`${YELLOW9}Could not sync: API unavailable${RESET14}`);
6793
6947
  if (result.failed.length > 0) {
6794
- console.log(` ${YELLOW9}Failed: ${result.failed.join(", ")}${RESET13}`);
6948
+ console.log(` ${YELLOW9}Failed: ${result.failed.join(", ")}${RESET14}`);
6795
6949
  }
6796
6950
  }
6797
6951
  }
@@ -6801,15 +6955,15 @@ function printVerificationFindings(findings) {
6801
6955
  return;
6802
6956
  }
6803
6957
  for (const finding of findings) {
6804
- const color = finding.severity === "error" ? RED11 : finding.severity === "warn" ? YELLOW9 : CYAN7;
6958
+ const color = finding.severity === "error" ? RED11 : finding.severity === "warn" ? YELLOW9 : CYAN8;
6805
6959
  console.log(
6806
- ` ${color}[${finding.severity.toUpperCase()}]${RESET13} ${finding.category}: ${finding.message}`
6960
+ ` ${color}[${finding.severity.toUpperCase()}]${RESET14} ${finding.category}: ${finding.message}`
6807
6961
  );
6808
6962
  for (const evidence of finding.evidence) {
6809
- console.log(` ${DIM13}${evidence}${RESET13}`);
6963
+ console.log(` ${DIM14}${evidence}${RESET14}`);
6810
6964
  }
6811
6965
  if (finding.suggestedFix) {
6812
- console.log(` ${DIM13}Fix: ${finding.suggestedFix}${RESET13}`);
6966
+ console.log(` ${DIM14}Fix: ${finding.suggestedFix}${RESET14}`);
6813
6967
  }
6814
6968
  }
6815
6969
  }
@@ -6817,10 +6971,10 @@ function printProjectAuditReport(report) {
6817
6971
  if (report.valid) {
6818
6972
  console.log(success3("Project contract is valid."));
6819
6973
  } else {
6820
- console.log(`${RED11}Project audit found blocking issues.${RESET13}`);
6974
+ console.log(`${RED11}Project audit found blocking issues.${RESET14}`);
6821
6975
  }
6822
6976
  console.log("");
6823
- console.log(`${BOLD6}Summary:${RESET13}`);
6977
+ console.log(`${BOLD7}Summary:${RESET14}`);
6824
6978
  console.log(` Essence version: ${report.summary.essenceVersion ?? "missing"}`);
6825
6979
  console.log(` Pages defined: ${report.summary.pageCount}`);
6826
6980
  console.log(` Pack manifest: ${report.summary.packManifestPresent ? "present" : "missing"}`);
@@ -6849,23 +7003,23 @@ function printProjectAuditReport(report) {
6849
7003
  ` Findings: ${report.summary.errorCount} error(s), ${report.summary.warnCount} warn(s), ${report.summary.infoCount} info`
6850
7004
  );
6851
7005
  console.log("");
6852
- console.log(`${BOLD6}Findings:${RESET13}`);
7006
+ console.log(`${BOLD7}Findings:${RESET14}`);
6853
7007
  printVerificationFindings(report.findings);
6854
7008
  }
6855
7009
  function printFileCritiqueReport(report) {
6856
7010
  console.log(success3(`Critiqued ${report.file}`));
6857
7011
  console.log("");
6858
- console.log(`${BOLD6}Summary:${RESET13}`);
7012
+ console.log(`${BOLD7}Summary:${RESET14}`);
6859
7013
  console.log(` Overall score: ${report.overall}/5`);
6860
7014
  console.log(` Focus areas: ${report.focusAreas.join(", ")}`);
6861
7015
  console.log(` Review pack: ${report.reviewPack ? "present" : "missing"}`);
6862
7016
  console.log("");
6863
- console.log(`${BOLD6}Scores:${RESET13}`);
7017
+ console.log(`${BOLD7}Scores:${RESET14}`);
6864
7018
  for (const score of report.scores) {
6865
7019
  console.log(` ${cyan3(score.category.padEnd(20))} ${score.score}/5 ${dim3(score.details)}`);
6866
7020
  }
6867
7021
  console.log("");
6868
- console.log(`${BOLD6}Findings:${RESET13}`);
7022
+ console.log(`${BOLD7}Findings:${RESET14}`);
6869
7023
  printVerificationFindings(report.findings);
6870
7024
  }
6871
7025
  async function cmdAudit(filePath) {
@@ -6906,7 +7060,7 @@ async function cmdAudit(filePath) {
6906
7060
  console.log(dim3("Project audit completed with advisory findings."));
6907
7061
  }
6908
7062
  } catch (e) {
6909
- console.log(`${RED11}Error: ${e.message}${RESET13}`);
7063
+ console.log(`${RED11}Error: ${e.message}${RESET14}`);
6910
7064
  process.exitCode = 1;
6911
7065
  }
6912
7066
  }
@@ -6915,9 +7069,9 @@ async function cmdTheme(args) {
6915
7069
  const projectRoot = process.cwd();
6916
7070
  if (!subcommand || subcommand === "help") {
6917
7071
  console.log(`
6918
- ${BOLD6}decantr theme${RESET13} \u2014 Manage custom themes
7072
+ ${BOLD7}decantr theme${RESET14} \u2014 Manage custom themes
6919
7073
 
6920
- ${BOLD6}Commands:${RESET13}
7074
+ ${BOLD7}Commands:${RESET14}
6921
7075
  ${cyan3("create")} <name> Create a new custom theme
6922
7076
  ${cyan3("create")} <name> --guided Interactive theme creation
6923
7077
  ${cyan3("list")} List custom themes
@@ -6925,7 +7079,7 @@ ${BOLD6}Commands:${RESET13}
6925
7079
  ${cyan3("delete")} <name> Delete a custom theme
6926
7080
  ${cyan3("import")} <path> Import theme from JSON file
6927
7081
 
6928
- ${BOLD6}Examples:${RESET13}
7082
+ ${BOLD7}Examples:${RESET14}
6929
7083
  decantr theme create mytheme
6930
7084
  decantr theme list
6931
7085
  decantr theme validate mytheme
@@ -6988,7 +7142,7 @@ ${BOLD6}Examples:${RESET13}
6988
7142
  } else {
6989
7143
  console.error(error3("Validation failed:"));
6990
7144
  for (const err of result.errors) {
6991
- console.error(` ${RED11}${err}${RESET13}`);
7145
+ console.error(` ${RED11}${err}${RESET14}`);
6992
7146
  }
6993
7147
  process.exitCode = 1;
6994
7148
  }
@@ -7028,7 +7182,7 @@ ${BOLD6}Examples:${RESET13}
7028
7182
  } else {
7029
7183
  console.error(error3("Import failed:"));
7030
7184
  for (const err of result.errors || []) {
7031
- console.error(` ${RED11}${err}${RESET13}`);
7185
+ console.error(` ${RED11}${err}${RESET14}`);
7032
7186
  }
7033
7187
  process.exitCode = 1;
7034
7188
  }
@@ -7051,9 +7205,9 @@ ${BOLD6}Examples:${RESET13}
7051
7205
  }
7052
7206
  function cmdHelp() {
7053
7207
  console.log(`
7054
- ${BOLD6}decantr${RESET13} \u2014 Design intelligence for AI-generated UI
7208
+ ${BOLD7}decantr${RESET14} \u2014 Design intelligence for AI-generated UI
7055
7209
 
7056
- ${BOLD6}Usage:${RESET13}
7210
+ ${BOLD7}Usage:${RESET14}
7057
7211
  decantr new <name> [--blueprint=X] [--archetype=X] [--theme=X] [--workflow=greenfield] [--adoption=decantr-css] [--telemetry]
7058
7212
  decantr magic <prompt> [--dry-run]
7059
7213
  decantr init [options]
@@ -7077,7 +7231,9 @@ ${BOLD6}Usage:${RESET13}
7077
7231
  decantr health [--format text|json|markdown] [--ci] [--fail-on error|warn|none]
7078
7232
  decantr health init-ci [--force] [--project <path>] [--fail-on <error|warn|none>] [--cli-version <version|latest>]
7079
7233
  decantr content-health [--json] [--markdown] [--ci]
7080
- decantr studio [--port 4319] [--host 127.0.0.1]
7234
+ decantr studio [--port 4319] [--host 127.0.0.1] [--report decantr-health.json]
7235
+ decantr telemetry status [--json]
7236
+ decantr telemetry link [--enable] [--org <slug>]
7081
7237
  decantr rules preview [--project=<path>]
7082
7238
  decantr rules apply [--project=<path>]
7083
7239
  decantr validate [path]
@@ -7089,7 +7245,7 @@ ${BOLD6}Usage:${RESET13}
7089
7245
  decantr logout
7090
7246
  decantr help
7091
7247
 
7092
- ${BOLD6}Init Options:${RESET13}
7248
+ ${BOLD7}Init Options:${RESET14}
7093
7249
  --blueprint, -b Blueprint ID
7094
7250
  --theme Theme ID
7095
7251
  --mode Color mode: dark | light | auto
@@ -7111,7 +7267,7 @@ ${BOLD6}Init Options:${RESET13}
7111
7267
  --registry Custom registry URL
7112
7268
  --telemetry Opt this project into privacy-filtered CLI product telemetry
7113
7269
 
7114
- ${BOLD6}Commands:${RESET13}
7270
+ ${BOLD7}Commands:${RESET14}
7115
7271
  ${cyan3("new")} Create a new greenfield workspace and bootstrap the available starter adapter
7116
7272
  ${cyan3("magic")} Greenfield-first intent flow; steers existing apps into analyze + init
7117
7273
  ${cyan3("init")} Attach Decantr contract/context files to an existing project or empty workspace
@@ -7136,13 +7292,14 @@ ${BOLD6}Commands:${RESET13}
7136
7292
  ${cyan3("login")} Authenticate with the Decantr registry
7137
7293
  ${cyan3("logout")} Remove stored credentials
7138
7294
  ${cyan3("analyze")} Brownfield entrypoint: scan an existing project and emit attach guidance
7295
+ ${cyan3("telemetry")} Inspect or link this project's opted-in CLI telemetry identity
7139
7296
  ${cyan3("export")} Export design tokens to framework format (shadcn, tailwind, css-vars)
7140
7297
  ${cyan3("registry")} Registry management and intelligence summary
7141
7298
  ${cyan3("rules")} Preview/apply Decantr assistant bridge blocks to repo rule files
7142
7299
  ${cyan3("upgrade")} Check for content updates from registry
7143
7300
  ${cyan3("help")} Show this help
7144
7301
 
7145
- ${BOLD6}Examples:${RESET13}
7302
+ ${BOLD7}Examples:${RESET14}
7146
7303
  decantr new my-app --blueprint=carbon-ai-portal
7147
7304
  decantr magic "AI chatbot with dark cyber theme \u2014 bold and futuristic"
7148
7305
  decantr init
@@ -7161,6 +7318,9 @@ ${BOLD6}Examples:${RESET13}
7161
7318
  decantr health --ci --fail-on error
7162
7319
  decantr content-health --ci --fail-on error
7163
7320
  decantr studio
7321
+ decantr studio --report decantr-health.json
7322
+ decantr telemetry status
7323
+ decantr telemetry link --enable --org my-team
7164
7324
  decantr audit
7165
7325
  decantr audit src/pages/HomePage.tsx
7166
7326
  decantr migrate --to v4
@@ -7181,30 +7341,30 @@ ${BOLD6}Examples:${RESET13}
7181
7341
  decantr registry audit-project --namespace @official --dist dist --sources src
7182
7342
  decantr create pattern my-card
7183
7343
 
7184
- ${BOLD6}Workflow Model:${RESET13}
7344
+ ${BOLD7}Workflow Model:${RESET14}
7185
7345
  ${cyan3("Greenfield blueprint")} decantr new my-app --blueprint=X --workflow=greenfield --adoption=decantr-css
7186
7346
  ${cyan3("Greenfield contract")} decantr init --workflow=greenfield --adoption=contract-only
7187
7347
  ${cyan3("Brownfield adoption")} decantr analyze -> decantr init --existing --accept-proposal -> decantr check --brownfield
7188
7348
  ${cyan3("Hybrid composition")} decantr add/remove, decantr theme switch, decantr registry, decantr upgrade
7189
7349
 
7190
- ${BOLD6}Bootstrap adapters:${RESET13}
7350
+ ${BOLD7}Bootstrap adapters:${RESET14}
7191
7351
  Runnable starter adapters: ${cyan3("react-vite")}, ${cyan3("next-app")}
7192
7352
  Unsupported targets resolve through ${cyan3("generic-web")} contract-only mode until their starter adapters land.
7193
7353
  `);
7194
7354
  }
7195
7355
  function cmdRulesHelp() {
7196
7356
  console.log(`
7197
- ${BOLD6}decantr rules${RESET13} \u2014 Preview or apply assistant bridge snippets
7357
+ ${BOLD7}decantr rules${RESET14} \u2014 Preview or apply assistant bridge snippets
7198
7358
 
7199
- ${BOLD6}Usage:${RESET13}
7359
+ ${BOLD7}Usage:${RESET14}
7200
7360
  decantr rules preview [--project=<path>]
7201
7361
  decantr rules apply [--project=<path>]
7202
7362
 
7203
- ${BOLD6}Subcommands:${RESET13}
7363
+ ${BOLD7}Subcommands:${RESET14}
7204
7364
  ${cyan3("preview")} Print target-specific Decantr bridge guidance without mutating rule files
7205
7365
  ${cyan3("apply")} Idempotently write Decantr bridge blocks to supported assistant rule files
7206
7366
 
7207
- ${BOLD6}Examples:${RESET13}
7367
+ ${BOLD7}Examples:${RESET14}
7208
7368
  decantr rules preview
7209
7369
  decantr rules preview --project=apps/web
7210
7370
  decantr rules apply --project=apps/web
@@ -7215,9 +7375,9 @@ function isCommandHelpRequest(args) {
7215
7375
  }
7216
7376
  function cmdHealthHelp() {
7217
7377
  console.log(`
7218
- ${BOLD6}decantr health${RESET13} \u2014 Generate a local Project Health report
7378
+ ${BOLD7}decantr health${RESET14} \u2014 Generate a local Project Health report
7219
7379
 
7220
- ${BOLD6}Usage:${RESET13}
7380
+ ${BOLD7}Usage:${RESET14}
7221
7381
  decantr health [--format text|json|markdown] [--output <file>]
7222
7382
  decantr health --json
7223
7383
  decantr health --markdown
@@ -7225,7 +7385,7 @@ ${BOLD6}Usage:${RESET13}
7225
7385
  decantr health --prompt <finding-id>
7226
7386
  decantr health init-ci [--force] [--project <path>] [--fail-on error|warn|none] [--cli-version <version|latest>]
7227
7387
 
7228
- ${BOLD6}Options:${RESET13}
7388
+ ${BOLD7}Options:${RESET14}
7229
7389
  --format Output format: text, json, or markdown
7230
7390
  --json Emit JSON report
7231
7391
  --markdown Emit markdown report
@@ -7234,7 +7394,7 @@ ${BOLD6}Options:${RESET13}
7234
7394
  --fail-on CI threshold: error, warn, or none
7235
7395
  --prompt Print an AI-ready remediation prompt for a finding
7236
7396
 
7237
- ${BOLD6}Examples:${RESET13}
7397
+ ${BOLD7}Examples:${RESET14}
7238
7398
  decantr health
7239
7399
  decantr health --json
7240
7400
  decantr health --markdown --output decantr-health.md
@@ -7245,16 +7405,16 @@ ${BOLD6}Examples:${RESET13}
7245
7405
  }
7246
7406
  function cmdContentHealthHelp() {
7247
7407
  console.log(`
7248
- ${BOLD6}decantr content-health${RESET13} \u2014 Generate a local registry content health report
7408
+ ${BOLD7}decantr content-health${RESET14} \u2014 Generate a local registry content health report
7249
7409
 
7250
- ${BOLD6}Usage:${RESET13}
7410
+ ${BOLD7}Usage:${RESET14}
7251
7411
  decantr content-health [--format text|json|markdown] [--output <file>]
7252
7412
  decantr content-health --json
7253
7413
  decantr content-health --markdown
7254
7414
  decantr content-health --ci [--fail-on error|warn|none]
7255
7415
  decantr content-health --prompt <finding-id>
7256
7416
 
7257
- ${BOLD6}Options:${RESET13}
7417
+ ${BOLD7}Options:${RESET14}
7258
7418
  --format Output format: text, json, or markdown
7259
7419
  --json Emit JSON report
7260
7420
  --markdown Emit markdown report
@@ -7263,7 +7423,7 @@ ${BOLD6}Options:${RESET13}
7263
7423
  --fail-on CI threshold: error, warn, or none
7264
7424
  --prompt Print an AI-ready remediation prompt for a finding
7265
7425
 
7266
- ${BOLD6}Examples:${RESET13}
7426
+ ${BOLD7}Examples:${RESET14}
7267
7427
  decantr content-health
7268
7428
  decantr content-health --json
7269
7429
  decantr content-health --markdown --output content-health.md
@@ -7272,24 +7432,27 @@ ${BOLD6}Examples:${RESET13}
7272
7432
  }
7273
7433
  function cmdStudioHelp() {
7274
7434
  console.log(`
7275
- ${BOLD6}decantr studio${RESET13} \u2014 Run a local Project Health dashboard
7435
+ ${BOLD7}decantr studio${RESET14} \u2014 Run a local Project Health dashboard
7276
7436
 
7277
- ${BOLD6}Usage:${RESET13}
7278
- decantr studio [--port 4319] [--host 127.0.0.1]
7437
+ ${BOLD7}Usage:${RESET14}
7438
+ decantr studio [--port 4319] [--host 127.0.0.1] [--report decantr-health.json]
7279
7439
 
7280
- ${BOLD6}Options:${RESET13}
7440
+ ${BOLD7}Options:${RESET14}
7281
7441
  --port Local port to bind; defaults to 4319
7282
7442
  --host Local host to bind; defaults to 127.0.0.1
7443
+ --report Serve a read-only Project Health JSON artifact instead of scanning the current project
7283
7444
 
7284
- ${BOLD6}Endpoints:${RESET13}
7445
+ ${BOLD7}Endpoints:${RESET14}
7285
7446
  GET /
7286
7447
  GET /api/health
7287
7448
  POST /api/refresh
7288
7449
 
7289
- ${BOLD6}Examples:${RESET13}
7450
+ ${BOLD7}Examples:${RESET14}
7290
7451
  decantr studio
7291
7452
  decantr studio --port 4320
7292
7453
  decantr studio --host 127.0.0.1 --port 4319
7454
+ decantr health --json --output decantr-health.json
7455
+ decantr studio --report decantr-health.json
7293
7456
  `);
7294
7457
  }
7295
7458
  async function main() {
@@ -7414,10 +7577,10 @@ async function main() {
7414
7577
  case "heal": {
7415
7578
  if (command === "heal") {
7416
7579
  console.log(
7417
- `${YELLOW9}Note: \`decantr heal\` is deprecated. Use \`decantr check\` instead.${RESET13}`
7580
+ `${YELLOW9}Note: \`decantr heal\` is deprecated. Use \`decantr check\` instead.${RESET14}`
7418
7581
  );
7419
7582
  }
7420
- const { cmdHeal } = await import("./heal-NWQNJ6PU.js");
7583
+ const { cmdHeal } = await import("./heal-M6PRCIIF.js");
7421
7584
  const telemetryFlag = args.includes("--telemetry");
7422
7585
  const brownfieldFlag = args.includes("--brownfield");
7423
7586
  await cmdHeal(process.cwd(), { telemetry: telemetryFlag, brownfield: brownfieldFlag });
@@ -7429,7 +7592,7 @@ async function main() {
7429
7592
  cmdHealthHelp();
7430
7593
  break;
7431
7594
  }
7432
- const { cmdHealth, parseHealthArgs } = await import("./health-WJJ55W3H.js");
7595
+ const { cmdHealth, parseHealthArgs } = await import("./health-EENY3BFS.js");
7433
7596
  await cmdHealth(process.cwd(), parseHealthArgs(args));
7434
7597
  } catch (e) {
7435
7598
  console.error(error3(e.message));
@@ -7457,7 +7620,7 @@ async function main() {
7457
7620
  cmdStudioHelp();
7458
7621
  break;
7459
7622
  }
7460
- const { cmdStudio, parseStudioArgs } = await import("./studio-FJNGWWRM.js");
7623
+ const { cmdStudio, parseStudioArgs } = await import("./studio-TBJPZZHA.js");
7461
7624
  await cmdStudio(process.cwd(), parseStudioArgs(args));
7462
7625
  } catch (e) {
7463
7626
  console.error(error3(e.message));
@@ -7630,6 +7793,10 @@ async function main() {
7630
7793
  console.log(success3("Logged out. Credentials removed."));
7631
7794
  break;
7632
7795
  }
7796
+ case "telemetry": {
7797
+ await cmdTelemetry(args.slice(1), process.cwd());
7798
+ break;
7799
+ }
7633
7800
  case "create": {
7634
7801
  const type = args[1];
7635
7802
  const name = args[2];
@@ -7688,7 +7855,7 @@ async function main() {
7688
7855
  const id = args[3] && !args[3].startsWith("--") ? args[3] : void 0;
7689
7856
  if (!packType || !["manifest", "scaffold", "review", "section", "page", "mutation"].includes(packType)) {
7690
7857
  console.error(
7691
- `${RED11}Usage: decantr registry get-pack <manifest|scaffold|review|section|page|mutation> [id] [--namespace <namespace>] [--json] [--essence <path>] [--write-context]${RESET13}`
7858
+ `${RED11}Usage: decantr registry get-pack <manifest|scaffold|review|section|page|mutation> [id] [--namespace <namespace>] [--json] [--essence <path>] [--write-context]${RESET14}`
7692
7859
  );
7693
7860
  process.exitCode = 1;
7694
7861
  break;
@@ -7716,7 +7883,7 @@ async function main() {
7716
7883
  const sourcePath = args[2] && !args[2].startsWith("--") ? args[2] : void 0;
7717
7884
  if (!sourcePath) {
7718
7885
  console.error(
7719
- `${RED11}Usage: decantr registry critique-file <file> [--namespace <namespace>] [--json] [--essence <path>] [--treatments <path>]${RESET13}`
7886
+ `${RED11}Usage: decantr registry critique-file <file> [--namespace <namespace>] [--json] [--essence <path>] [--treatments <path>]${RESET14}`
7720
7887
  );
7721
7888
  process.exitCode = 1;
7722
7889
  break;
@@ -7741,7 +7908,7 @@ async function main() {
7741
7908
  await printHostedProjectAudit(namespace, jsonOutput, essencePath, distPath, sourcesPath);
7742
7909
  } else {
7743
7910
  console.error(
7744
- `${RED11}Usage: decantr registry mirror [--type <type>] | decantr registry summary [--namespace <namespace>] [--json] | decantr registry compile-packs [path] [--namespace <namespace>] [--json] [--write-context] | decantr registry get-pack <manifest|scaffold|review|section|page|mutation> [id] [--namespace <namespace>] [--json] [--essence <path>] [--write-context] | decantr registry critique-file <file> [--namespace <namespace>] [--json] [--essence <path>] [--treatments <path>] | decantr registry audit-project [--namespace <namespace>] [--json] [--essence <path>] [--dist <path>] [--sources <dir>]${RESET13}`
7911
+ `${RED11}Usage: decantr registry mirror [--type <type>] | decantr registry summary [--namespace <namespace>] [--json] | decantr registry compile-packs [path] [--namespace <namespace>] [--json] [--write-context] | decantr registry get-pack <manifest|scaffold|review|section|page|mutation> [id] [--namespace <namespace>] [--json] [--essence <path>] [--write-context] | decantr registry critique-file <file> [--namespace <namespace>] [--json] [--essence <path>] [--treatments <path>] | decantr registry audit-project [--namespace <namespace>] [--json] [--essence <path>] [--dist <path>] [--sources <dir>]${RESET14}`
7745
7912
  );
7746
7913
  process.exitCode = 1;
7747
7914
  }
@@ -7857,7 +8024,7 @@ async function main() {
7857
8024
  process.exitCode = 1;
7858
8025
  break;
7859
8026
  }
7860
- cmdAnalyze(workspaceInfo.appRoot, workspaceInfo);
8027
+ await cmdAnalyze(workspaceInfo.appRoot, workspaceInfo);
7861
8028
  break;
7862
8029
  }
7863
8030
  case "rules": {
@@ -7921,7 +8088,7 @@ async function main() {
7921
8088
  console.error("");
7922
8089
  console.error(" Example:");
7923
8090
  console.error(
7924
- ` ${CYAN7}decantr magic "AI agent dashboard \u2014 dark, neon, confident"${RESET13}`
8091
+ ` ${CYAN8}decantr magic "AI agent dashboard \u2014 dark, neon, confident"${RESET14}`
7925
8092
  );
7926
8093
  process.exitCode = 1;
7927
8094
  break;