@decantr/cli 2.1.2 → 2.3.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.
@@ -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,245 @@ function resolveDriftEntries(projectRoot, options) {
4163
4183
  }
4164
4184
  }
4165
4185
 
4186
+ // src/commands/telemetry.ts
4187
+ import { DECANTR_TELEMETRY_EVENT_CATALOG } from "@decantr/telemetry";
4188
+ var BOLD5 = "\x1B[1m";
4189
+ var CYAN6 = "\x1B[36m";
4190
+ var DIM11 = "\x1B[2m";
4191
+ var GREEN11 = "\x1B[32m";
4192
+ var RESET11 = "\x1B[0m";
4193
+ var DEFAULT_API_URL = "https://api.decantr.ai/v1";
4194
+ async function cmdTelemetry(args, projectRoot = process.cwd()) {
4195
+ const subcommand = args[0] ?? "status";
4196
+ const options = parseTelemetryOptions(args.slice(1));
4197
+ if (subcommand === "--help" || subcommand === "-h" || subcommand === "help") {
4198
+ printTelemetryHelp();
4199
+ return;
4200
+ }
4201
+ if (subcommand === "status") {
4202
+ printTelemetryStatus(projectRoot, options);
4203
+ return;
4204
+ }
4205
+ if (subcommand === "explain") {
4206
+ printTelemetryExplain(projectRoot, options);
4207
+ return;
4208
+ }
4209
+ if (subcommand === "link") {
4210
+ await linkTelemetryIdentity(projectRoot, options);
4211
+ return;
4212
+ }
4213
+ throw new Error(`Unknown telemetry command: ${subcommand}`);
4214
+ }
4215
+ function printTelemetryHelp() {
4216
+ console.log(`
4217
+ ${BOLD5}decantr telemetry${RESET11} \u2014 Inspect and link privacy-filtered CLI telemetry identity
4218
+
4219
+ ${BOLD5}Usage:${RESET11}
4220
+ decantr telemetry status [--json]
4221
+ decantr telemetry explain [--json]
4222
+ decantr telemetry link [--enable] [--org <slug>] [--label <label>] [--api-key <key>] [--api-url <url>]
4223
+
4224
+ ${BOLD5}Examples:${RESET11}
4225
+ decantr init --telemetry
4226
+ decantr telemetry status
4227
+ decantr telemetry explain
4228
+ decantr login --api-key=<your-key>
4229
+ decantr telemetry link --org my-team --label "CI runner"
4230
+ `);
4231
+ }
4232
+ function printTelemetryStatus(projectRoot, options) {
4233
+ const status = getCliTelemetryIdentityStatus(projectRoot, { create: false });
4234
+ if (options.json) {
4235
+ console.log(JSON.stringify(status, null, 2));
4236
+ return;
4237
+ }
4238
+ console.log(`
4239
+ ${BOLD5}Decantr telemetry${RESET11}`);
4240
+ console.log(` Enabled: ${status.enabled ? `${GREEN11}yes${RESET11}` : "no"}`);
4241
+ console.log(` Project: ${status.hasProjectConfig ? status.projectRoot : "not initialized"}`);
4242
+ console.log(` Install ID: ${status.installId ?? `${DIM11}not created yet${RESET11}`}`);
4243
+ console.log(` Project ID: ${status.projectId ?? `${DIM11}not created yet${RESET11}`}`);
4244
+ if (status.enabled) {
4245
+ console.log(
4246
+ DIM11 + "Run `decantr telemetry link` after login to attach these opaque IDs to your Decantr account/org." + RESET11
4247
+ );
4248
+ } else {
4249
+ console.log(DIM11 + "Run `decantr init --telemetry` or `decantr telemetry link --enable` to opt in." + RESET11);
4250
+ }
4251
+ }
4252
+ function printTelemetryExplain(projectRoot, options) {
4253
+ const status = getCliTelemetryIdentityStatus(projectRoot, { create: false });
4254
+ const cliEvents = DECANTR_TELEMETRY_EVENT_CATALOG.filter((entry) => entry.allowedSources.includes("cli")).map((entry) => ({
4255
+ name: entry.name,
4256
+ bucket: entry.bucket,
4257
+ privacy: entry.privacy,
4258
+ publicIngest: entry.publicIngest,
4259
+ notes: entry.privacyNotes
4260
+ }));
4261
+ const report = {
4262
+ source: "cli",
4263
+ enabled: status.enabled,
4264
+ hasProjectConfig: status.hasProjectConfig,
4265
+ identifiers: {
4266
+ installId: status.installId ?? null,
4267
+ projectId: status.projectId ?? null,
4268
+ meaning: "Opaque Decantr-generated ids used only when this project has opted into CLI telemetry."
4269
+ },
4270
+ endpoint: process.env.DECANTR_TELEMETRY_ENDPOINT ?? "https://api.decantr.ai/v1/telemetry/events",
4271
+ events: cliEvents,
4272
+ aggregateFields: [
4273
+ "command name",
4274
+ "success or failure",
4275
+ "duration",
4276
+ "workflow and adoption mode",
4277
+ "project scope",
4278
+ "registry source",
4279
+ "aggregate analyze counts",
4280
+ "Project Health status, score, and finding counts",
4281
+ "CI gate outcome",
4282
+ "Studio start and refresh activity",
4283
+ "remediation prompt request outcome"
4284
+ ],
4285
+ neverCollected: [
4286
+ "source code",
4287
+ "prompt text",
4288
+ "local file paths",
4289
+ "repository names",
4290
+ "emails",
4291
+ "secrets",
4292
+ "raw route names",
4293
+ "private package slugs",
4294
+ "health report bodies",
4295
+ "finding evidence"
4296
+ ],
4297
+ controls: {
4298
+ optIn: "Run decantr init --telemetry, decantr new --telemetry, or decantr telemetry link --enable.",
4299
+ optOut: 'Set "telemetry": false in .decantr/project.json.',
4300
+ link: "Run decantr telemetry link after login to attach opaque ids to your Decantr account/org."
4301
+ }
4302
+ };
4303
+ if (options.json) {
4304
+ console.log(JSON.stringify(report, null, 2));
4305
+ return;
4306
+ }
4307
+ console.log(`
4308
+ ${BOLD5}Decantr telemetry explanation${RESET11}`);
4309
+ console.log(` Source: cli`);
4310
+ console.log(` Enabled: ${status.enabled ? `${GREEN11}yes${RESET11}` : "no"}`);
4311
+ console.log(` Install ID: ${status.installId ?? `${DIM11}not created yet${RESET11}`}`);
4312
+ console.log(` Project ID: ${status.projectId ?? `${DIM11}not created yet${RESET11}`}`);
4313
+ console.log(` Events: ${cliEvents.length} CLI event types in the public catalog`);
4314
+ console.log(`
4315
+ ${BOLD5}Aggregate fields${RESET11}`);
4316
+ for (const field of report.aggregateFields) {
4317
+ console.log(` - ${field}`);
4318
+ }
4319
+ console.log(`
4320
+ ${BOLD5}Never collected${RESET11}`);
4321
+ for (const field of report.neverCollected) {
4322
+ console.log(` - ${field}`);
4323
+ }
4324
+ console.log(`
4325
+ ${DIM11}${report.controls.optOut}${RESET11}`);
4326
+ console.log(`${DIM11}${report.controls.link}${RESET11}`);
4327
+ }
4328
+ async function linkTelemetryIdentity(projectRoot, options) {
4329
+ if (options.enable && !isOptedIn(projectRoot)) {
4330
+ optIn(projectRoot);
4331
+ }
4332
+ if (!isOptedIn(projectRoot)) {
4333
+ throw new Error("This project has not opted into telemetry. Re-run with --enable or use `decantr init --telemetry`.");
4334
+ }
4335
+ const identity = getCliTelemetryIdentityStatus(projectRoot, { create: true });
4336
+ if (!identity.installId && !identity.projectId) {
4337
+ throw new Error("No telemetry identity could be created for this project.");
4338
+ }
4339
+ const apiKey = options.apiKey ?? getApiKeyOrToken();
4340
+ if (!apiKey) {
4341
+ throw new Error("Run `decantr login --api-key=<key>` or pass `--api-key <key>` before linking telemetry.");
4342
+ }
4343
+ const apiUrl = trimTrailingSlashes(options.apiUrl ?? process.env.DECANTR_API_URL ?? DEFAULT_API_URL);
4344
+ const response = await fetch(`${apiUrl}/me/telemetry-link`, {
4345
+ method: "POST",
4346
+ headers: {
4347
+ Authorization: `Bearer ${apiKey}`,
4348
+ "Content-Type": "application/json"
4349
+ },
4350
+ body: JSON.stringify({
4351
+ install_id: identity.installId,
4352
+ project_id: identity.projectId,
4353
+ org_slug: options.org,
4354
+ label: options.label
4355
+ })
4356
+ });
4357
+ if (!response.ok) {
4358
+ const body2 = await response.json().catch(() => null);
4359
+ throw new Error(body2?.error ?? `Telemetry link failed with HTTP ${response.status}.`);
4360
+ }
4361
+ const body = await response.json().catch(() => ({ linked: 0 }));
4362
+ console.log(`${GREEN11}Telemetry identity linked.${RESET11}`);
4363
+ console.log(` Linked: ${body.linked ?? 0}`);
4364
+ console.log(` Install ID: ${identity.installId ?? `${DIM11}none${RESET11}`}`);
4365
+ console.log(` Project ID: ${identity.projectId ?? `${DIM11}none${RESET11}`}`);
4366
+ if (options.org) console.log(` Org: ${CYAN6}${options.org}${RESET11}`);
4367
+ console.log(DIM11 + "These opaque IDs now attribute opted-in CLI usage to your Decantr account/org." + RESET11);
4368
+ }
4369
+ function parseTelemetryOptions(args) {
4370
+ const options = {};
4371
+ for (let i = 0; i < args.length; i++) {
4372
+ const arg = args[i];
4373
+ if (arg === "--enable") {
4374
+ options.enable = true;
4375
+ } else if (arg === "--json") {
4376
+ options.json = true;
4377
+ } else if (arg === "--org" && args[i + 1]) {
4378
+ options.org = args[++i];
4379
+ } else if (arg.startsWith("--org=")) {
4380
+ options.org = arg.slice("--org=".length);
4381
+ } else if (arg === "--label" && args[i + 1]) {
4382
+ options.label = args[++i];
4383
+ } else if (arg.startsWith("--label=")) {
4384
+ options.label = arg.slice("--label=".length);
4385
+ } else if (arg === "--api-key" && args[i + 1]) {
4386
+ options.apiKey = args[++i];
4387
+ } else if (arg.startsWith("--api-key=")) {
4388
+ options.apiKey = arg.slice("--api-key=".length);
4389
+ } else if (arg === "--api-url" && args[i + 1]) {
4390
+ options.apiUrl = args[++i];
4391
+ } else if (arg.startsWith("--api-url=")) {
4392
+ options.apiUrl = arg.slice("--api-url=".length);
4393
+ }
4394
+ }
4395
+ return options;
4396
+ }
4397
+ function trimTrailingSlashes(value) {
4398
+ let end = value.length;
4399
+ while (end > 0 && value.charCodeAt(end - 1) === 47) end -= 1;
4400
+ return value.slice(0, end);
4401
+ }
4402
+
4166
4403
  // src/commands/theme-switch.ts
4167
4404
  import { existsSync as existsSync23, readFileSync as readFileSync16, writeFileSync as writeFileSync13 } from "fs";
4168
4405
  import { join as join24 } from "path";
4169
4406
  import { isV4 as isV46 } from "@decantr/essence-spec";
4170
- var GREEN11 = "\x1B[32m";
4407
+ var GREEN12 = "\x1B[32m";
4171
4408
  var RED10 = "\x1B[31m";
4172
4409
  var YELLOW7 = "\x1B[33m";
4173
- var DIM11 = "\x1B[2m";
4174
- var RESET11 = "\x1B[0m";
4410
+ var DIM12 = "\x1B[2m";
4411
+ var RESET12 = "\x1B[0m";
4175
4412
  var VALID_THEME_SHAPES = ["sharp", "rounded", "pill"];
4176
4413
  var VALID_THEME_MODES = ["light", "dark", "auto"];
4177
4414
  async function cmdThemeSwitch(themeName, args, projectRoot = process.cwd()) {
4178
4415
  if (!themeName) {
4179
4416
  console.error(
4180
- `${RED10}Usage: decantr theme switch <themeName> [--shape <s>] [--mode <m>]${RESET11}`
4417
+ `${RED10}Usage: decantr theme switch <themeName> [--shape <s>] [--mode <m>]${RESET12}`
4181
4418
  );
4182
4419
  process.exitCode = 1;
4183
4420
  return;
4184
4421
  }
4185
4422
  const essencePath = join24(projectRoot, "decantr.essence.json");
4186
4423
  if (!existsSync23(essencePath)) {
4187
- console.error(`${RED10}No decantr.essence.json found. Run \`decantr init\` first.${RESET11}`);
4424
+ console.error(`${RED10}No decantr.essence.json found. Run \`decantr init\` first.${RESET12}`);
4188
4425
  process.exitCode = 1;
4189
4426
  return;
4190
4427
  }
@@ -4192,13 +4429,13 @@ async function cmdThemeSwitch(themeName, args, projectRoot = process.cwd()) {
4192
4429
  try {
4193
4430
  parsed = JSON.parse(readFileSync16(essencePath, "utf-8"));
4194
4431
  } catch (e) {
4195
- console.error(`${RED10}Could not read essence: ${e.message}${RESET11}`);
4432
+ console.error(`${RED10}Could not read essence: ${e.message}${RESET12}`);
4196
4433
  process.exitCode = 1;
4197
4434
  return;
4198
4435
  }
4199
4436
  if (!isV46(parsed)) {
4200
4437
  console.error(
4201
- `${RED10}Active workflows require Essence v4.0.0. Run \`decantr migrate --to v4\` first.${RESET11}`
4438
+ `${RED10}Active workflows require Essence v4.0.0. Run \`decantr migrate --to v4\` first.${RESET12}`
4202
4439
  );
4203
4440
  process.exitCode = 1;
4204
4441
  return;
@@ -4220,14 +4457,14 @@ async function cmdThemeSwitch(themeName, args, projectRoot = process.cwd()) {
4220
4457
  }
4221
4458
  if (shape && !VALID_THEME_SHAPES.includes(shape)) {
4222
4459
  console.error(
4223
- `${RED10}Invalid shape "${shape}". Must be one of: ${VALID_THEME_SHAPES.join(", ")}.${RESET11}`
4460
+ `${RED10}Invalid shape "${shape}". Must be one of: ${VALID_THEME_SHAPES.join(", ")}.${RESET12}`
4224
4461
  );
4225
4462
  process.exitCode = 1;
4226
4463
  return;
4227
4464
  }
4228
4465
  if (mode && !VALID_THEME_MODES.includes(mode)) {
4229
4466
  console.error(
4230
- `${RED10}Invalid mode "${mode}". Must be one of: ${VALID_THEME_MODES.join(", ")}.${RESET11}`
4467
+ `${RED10}Invalid mode "${mode}". Must be one of: ${VALID_THEME_MODES.join(", ")}.${RESET12}`
4231
4468
  );
4232
4469
  process.exitCode = 1;
4233
4470
  return;
@@ -4257,27 +4494,27 @@ async function cmdThemeSwitch(themeName, args, projectRoot = process.cwd()) {
4257
4494
  } catch {
4258
4495
  }
4259
4496
  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}`);
4497
+ console.log(`${GREEN12}Switched theme: ${oldThemeId} \u2192 ${themeName}${RESET12}`);
4498
+ if (shape) console.log(` ${DIM12}Shape: ${shape}${RESET12}`);
4499
+ if (mode) console.log(` ${DIM12}Mode: ${mode}${RESET12}`);
4263
4500
  await refreshDerivedFiles(projectRoot, essence, registryClient);
4264
4501
  console.log(
4265
- `${GREEN11}Derived files refreshed (tokens.css, treatments.css, all contexts).${RESET11}`
4502
+ `${GREEN12}Derived files refreshed (tokens.css, treatments.css, all contexts).${RESET12}`
4266
4503
  );
4267
- console.log(`${YELLOW7}Guard will flag code using old tokens. Run \`decantr check\`.${RESET11}`);
4504
+ console.log(`${YELLOW7}Guard will flag code using old tokens. Run \`decantr check\`.${RESET12}`);
4268
4505
  }
4269
4506
 
4270
4507
  // src/prompts.ts
4271
4508
  import { createInterface } from "readline";
4272
- var BOLD5 = "\x1B[1m";
4273
- var DIM12 = "\x1B[2m";
4274
- var RESET12 = "\x1B[0m";
4275
- var GREEN12 = "\x1B[32m";
4509
+ var BOLD6 = "\x1B[1m";
4510
+ var DIM13 = "\x1B[2m";
4511
+ var RESET13 = "\x1B[0m";
4512
+ var GREEN13 = "\x1B[32m";
4276
4513
  var YELLOW8 = "\x1B[33m";
4277
- var CYAN6 = "\x1B[36m";
4514
+ var CYAN7 = "\x1B[36m";
4278
4515
  function ask(question, defaultValue) {
4279
4516
  const rl = createInterface({ input: process.stdin, output: process.stdout });
4280
- const prompt = defaultValue ? `${question} ${DIM12}(${defaultValue})${RESET12}: ` : `${question}: `;
4517
+ const prompt = defaultValue ? `${question} ${DIM13}(${defaultValue})${RESET13}: ` : `${question}: `;
4281
4518
  return new Promise((resolve5) => {
4282
4519
  rl.question(prompt, (answer) => {
4283
4520
  rl.close();
@@ -4287,14 +4524,14 @@ function ask(question, defaultValue) {
4287
4524
  }
4288
4525
  async function select(question, options, defaultIdx = 0, allowOther = false) {
4289
4526
  console.log(`
4290
- ${BOLD5}${question}${RESET12}`);
4527
+ ${BOLD6}${question}${RESET13}`);
4291
4528
  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}` : "";
4529
+ const marker = i === defaultIdx ? `${GREEN13}>${RESET13}` : " ";
4530
+ const desc = options[i].description ? ` ${DIM13}\u2014 ${options[i].description}${RESET13}` : "";
4294
4531
  console.log(` ${marker} ${i + 1}. ${options[i].label}${desc}`);
4295
4532
  }
4296
4533
  if (allowOther) {
4297
- console.log(` ${options.length + 1}. ${DIM12}other (enter custom value)${RESET12}`);
4534
+ console.log(` ${options.length + 1}. ${DIM13}other (enter custom value)${RESET13}`);
4298
4535
  }
4299
4536
  const maxIdx = allowOther ? options.length + 1 : options.length;
4300
4537
  const answer = await ask(`Choose (1-${maxIdx})`, String(defaultIdx + 1));
@@ -4313,11 +4550,11 @@ async function confirm(question, defaultYes = true) {
4313
4550
  }
4314
4551
  function warn(message) {
4315
4552
  console.log(`
4316
- ${YELLOW8} Warning: ${message}${RESET12}`);
4553
+ ${YELLOW8} Warning: ${message}${RESET13}`);
4317
4554
  }
4318
4555
  function showDetection(detected) {
4319
4556
  console.log(`
4320
- ${CYAN6}Detected project configuration:${RESET12}`);
4557
+ ${CYAN7}Detected project configuration:${RESET13}`);
4321
4558
  if (detected.framework !== "unknown") {
4322
4559
  const version = detected.version ? ` ${detected.version}` : "";
4323
4560
  console.log(` Framework: ${detected.framework}${version}`);
@@ -4326,13 +4563,13 @@ ${CYAN6}Detected project configuration:${RESET12}`);
4326
4563
  console.log(` Package manager: ${detected.packageManager}`);
4327
4564
  }
4328
4565
  if (detected.hasTypeScript) {
4329
- console.log(` TypeScript: ${GREEN12}yes${RESET12}`);
4566
+ console.log(` TypeScript: ${GREEN13}yes${RESET13}`);
4330
4567
  }
4331
4568
  if (detected.hasTailwind) {
4332
- console.log(` Tailwind CSS: ${GREEN12}yes${RESET12}`);
4569
+ console.log(` Tailwind CSS: ${GREEN13}yes${RESET13}`);
4333
4570
  }
4334
4571
  if (detected.existingEssence) {
4335
- console.log(` Existing essence: ${YELLOW8}yes${RESET12}`);
4572
+ console.log(` Existing essence: ${YELLOW8}yes${RESET13}`);
4336
4573
  }
4337
4574
  }
4338
4575
  async function runInteractivePrompts(detected, archetypes, blueprints, themes, workflowSeed) {
@@ -4406,7 +4643,7 @@ async function runInteractivePrompts(detected, archetypes, blueprints, themes, w
4406
4643
  warn(`This project appears to be ${detected.framework} but you selected ${target}.`);
4407
4644
  const proceed = await confirm("Continue anyway?", false);
4408
4645
  if (!proceed) {
4409
- console.log(`${DIM12}Using detected framework: ${detected.framework}${RESET12}`);
4646
+ console.log(`${DIM13}Using detected framework: ${detected.framework}${RESET13}`);
4410
4647
  }
4411
4648
  }
4412
4649
  const guardMode = await select(
@@ -4797,29 +5034,29 @@ function resolveWorkspaceInfo(cwd, projectArg) {
4797
5034
  }
4798
5035
 
4799
5036
  // src/index.ts
4800
- var BOLD6 = "\x1B[1m";
4801
- var DIM13 = "\x1B[2m";
4802
- var RESET13 = "\x1B[0m";
5037
+ var BOLD7 = "\x1B[1m";
5038
+ var DIM14 = "\x1B[2m";
5039
+ var RESET14 = "\x1B[0m";
4803
5040
  var RED11 = "\x1B[31m";
4804
- var GREEN13 = "\x1B[32m";
4805
- var CYAN7 = "\x1B[36m";
5041
+ var GREEN14 = "\x1B[32m";
5042
+ var CYAN8 = "\x1B[36m";
4806
5043
  var YELLOW9 = "\x1B[33m";
4807
5044
  function heading2(text) {
4808
5045
  return `
4809
- ${BOLD6}${text}${RESET13}
5046
+ ${BOLD7}${text}${RESET14}
4810
5047
  `;
4811
5048
  }
4812
5049
  function success3(text) {
4813
- return `${GREEN13}${text}${RESET13}`;
5050
+ return `${GREEN14}${text}${RESET14}`;
4814
5051
  }
4815
5052
  function error3(text) {
4816
- return `${RED11}${text}${RESET13}`;
5053
+ return `${RED11}${text}${RESET14}`;
4817
5054
  }
4818
5055
  function dim3(text) {
4819
- return `${DIM13}${text}${RESET13}`;
5056
+ return `${DIM14}${text}${RESET14}`;
4820
5057
  }
4821
5058
  function cyan3(text) {
4822
- return `${CYAN7}${text}${RESET13}`;
5059
+ return `${CYAN8}${text}${RESET14}`;
4823
5060
  }
4824
5061
  function formatIntelligenceSummary(intelligence) {
4825
5062
  if (!intelligence) {
@@ -5542,7 +5779,7 @@ async function printHostedExecutionPackBundle(essencePath, namespace, jsonOutput
5542
5779
  console.log(` Files written: ${writtenContextPaths.length}`);
5543
5780
  }
5544
5781
  console.log("");
5545
- console.log(`${BOLD6}Route Plan:${RESET13}`);
5782
+ console.log(`${BOLD7}Route Plan:${RESET14}`);
5546
5783
  for (const route of typedBundle.scaffold.data.routes) {
5547
5784
  const patterns = route.patternIds.length > 0 ? route.patternIds.join(", ") : "none";
5548
5785
  const pageLabel = route.sectionId ? `${route.sectionId}/${route.pageId}` : route.pageId;
@@ -5781,7 +6018,7 @@ async function cmdSearch(query, type, sort, recommended, intelligenceSource) {
5781
6018
  }
5782
6019
  console.log(heading2(`${results.length} result(s) for "${query}"`));
5783
6020
  for (const r of results) {
5784
- console.log(` ${cyan3(r.type.padEnd(12))} ${BOLD6}${r.slug}${RESET13}`);
6021
+ console.log(` ${cyan3(r.type.padEnd(12))} ${BOLD7}${r.slug}${RESET14}`);
5785
6022
  console.log(` ${dim3(r.description || "")}`);
5786
6023
  const intelligenceSummary = formatIntelligenceSummary(r.intelligence);
5787
6024
  if (intelligenceSummary) {
@@ -5812,14 +6049,14 @@ async function cmdSuggest(query, type) {
5812
6049
  const exact = results.filter((r) => r.slug.toLowerCase().includes(queryLower));
5813
6050
  const related = results.filter((r) => !r.slug.toLowerCase().includes(queryLower));
5814
6051
  if (exact.length > 0) {
5815
- console.log(`${BOLD6}Direct matches:${RESET13}`);
6052
+ console.log(`${BOLD7}Direct matches:${RESET14}`);
5816
6053
  for (const r of exact.slice(0, 3)) {
5817
6054
  console.log(` ${cyan3(r.slug)} - ${r.description || ""}`);
5818
6055
  }
5819
6056
  console.log("");
5820
6057
  }
5821
6058
  if (related.length > 0) {
5822
- console.log(`${BOLD6}Related:${RESET13}`);
6059
+ console.log(`${BOLD7}Related:${RESET14}`);
5823
6060
  for (const r of related.slice(0, 5)) {
5824
6061
  console.log(` ${cyan3(r.slug)} - ${r.description || ""}`);
5825
6062
  }
@@ -5883,14 +6120,14 @@ async function cmdValidate(path) {
5883
6120
  return;
5884
6121
  }
5885
6122
  const detectedVersion = isV47(essence) ? "v4" : "legacy";
5886
- console.log(`${DIM13}Detected essence version: ${detectedVersion}${RESET13}`);
6123
+ console.log(`${DIM14}Detected essence version: ${detectedVersion}${RESET14}`);
5887
6124
  const result = validateEssence2(essence);
5888
6125
  if (result.valid) {
5889
6126
  console.log(success3(`Essence is valid (${detectedVersion}).`));
5890
6127
  } else {
5891
6128
  console.error(error3("Validation failed:"));
5892
6129
  for (const err of result.errors) {
5893
- console.error(` ${RED11}${err}${RESET13}`);
6130
+ console.error(` ${RED11}${err}${RESET14}`);
5894
6131
  }
5895
6132
  process.exitCode = 1;
5896
6133
  return;
@@ -5911,9 +6148,9 @@ async function cmdValidate(path) {
5911
6148
  console.log(heading2("Guard violations:"));
5912
6149
  for (const v of violations) {
5913
6150
  const vr = v;
5914
- console.log(` ${YELLOW9}[${vr.rule}]${RESET13} ${vr.message}`);
6151
+ console.log(` ${YELLOW9}[${vr.rule}]${RESET14} ${vr.message}`);
5915
6152
  if (vr.suggestion) {
5916
- console.log(` ${DIM13}Suggestion: ${vr.suggestion}${RESET13}`);
6153
+ console.log(` ${DIM14}Suggestion: ${vr.suggestion}${RESET14}`);
5917
6154
  }
5918
6155
  }
5919
6156
  const hasError = violations.some((v) => v.severity === "error");
@@ -5985,9 +6222,9 @@ function enableCliTelemetry(projectRoot) {
5985
6222
  optIn(projectRoot);
5986
6223
  console.log(
5987
6224
  `
5988
- ${CYAN7}Telemetry enabled.${RESET13} Decantr will send privacy-filtered CLI product telemetry for this project.`
6225
+ ${CYAN8}Telemetry enabled.${RESET14} Decantr will send privacy-filtered CLI product telemetry for this project.`
5989
6226
  );
5990
- console.log(`${DIM13}Set "telemetry": false in .decantr/project.json to opt out.${RESET13}`);
6227
+ console.log(`${DIM14}Set "telemetry": false in .decantr/project.json to opt out.${RESET14}`);
5991
6228
  }
5992
6229
  function readCliPackageVersion() {
5993
6230
  const here = dirname4(fileURLToPath2(import.meta.url));
@@ -6109,7 +6346,7 @@ async function applyAcceptedBrownfieldProposal(input) {
6109
6346
  error3("Brownfield proposal produced an invalid Decantr essence. No files were changed.")
6110
6347
  );
6111
6348
  for (const validationError of validation.errors) {
6112
- console.log(` ${RED11}${validationError}${RESET13}`);
6349
+ console.log(` ${RED11}${validationError}${RESET14}`);
6113
6350
  }
6114
6351
  process.exitCode = 1;
6115
6352
  return;
@@ -6200,7 +6437,7 @@ async function cmdInit(args) {
6200
6437
  console.log(dim3(" Found .decantr/init-seed.json brownfield guidance."));
6201
6438
  }
6202
6439
  if (detected.existingEssence && !args.existing) {
6203
- console.log(`${YELLOW9}Warning: decantr.essence.json already exists.${RESET13}`);
6440
+ console.log(`${YELLOW9}Warning: decantr.essence.json already exists.${RESET14}`);
6204
6441
  const overwrite = await confirm("Overwrite existing configuration?", false);
6205
6442
  if (!overwrite) {
6206
6443
  console.log(dim3("Cancelled."));
@@ -6302,7 +6539,7 @@ async function cmdInit(args) {
6302
6539
  } else if (shouldUseRegistry && !apiAvailable) {
6303
6540
  if (!args.blueprint) {
6304
6541
  console.log(`
6305
- ${YELLOW9}You're offline. Scaffolding minimal Decantr project.${RESET13}`);
6542
+ ${YELLOW9}You're offline. Scaffolding minimal Decantr project.${RESET14}`);
6306
6543
  console.log(
6307
6544
  dim3("Run `decantr sync` or `decantr upgrade` when online to pull full registry content.\n")
6308
6545
  );
@@ -6350,7 +6587,7 @@ ${YELLOW9}You're offline. Scaffolding minimal Decantr project.${RESET13}`);
6350
6587
  return;
6351
6588
  }
6352
6589
  console.log(`
6353
- ${YELLOW9}You're offline. Scaffolding Decantr default.${RESET13}`);
6590
+ ${YELLOW9}You're offline. Scaffolding Decantr default.${RESET14}`);
6354
6591
  console.log(dim3("Run `decantr upgrade` when online, or visit decantr.ai/registry\n"));
6355
6592
  selectedBlueprint = "default";
6356
6593
  } else if (shouldUseRegistry) {
@@ -6531,7 +6768,7 @@ ${YELLOW9}You're offline. Scaffolding Decantr default.${RESET13}`);
6531
6768
  return;
6532
6769
  }
6533
6770
  console.log(
6534
- `${YELLOW9} Warning: Could not fetch blueprint "${options.blueprint}". Using defaults.${RESET13}`
6771
+ `${YELLOW9} Warning: Could not fetch blueprint "${options.blueprint}". Using defaults.${RESET14}`
6535
6772
  );
6536
6773
  }
6537
6774
  } else if (shouldUseRegistry && options.archetype) {
@@ -6546,7 +6783,7 @@ ${YELLOW9}You're offline. Scaffolding Decantr default.${RESET13}`);
6546
6783
  return;
6547
6784
  }
6548
6785
  console.log(
6549
- `${YELLOW9} Warning: Could not fetch archetype "${options.archetype}". Using defaults.${RESET13}`
6786
+ `${YELLOW9} Warning: Could not fetch archetype "${options.archetype}". Using defaults.${RESET14}`
6550
6787
  );
6551
6788
  }
6552
6789
  }
@@ -6563,7 +6800,7 @@ ${YELLOW9}You're offline. Scaffolding Decantr default.${RESET13}`);
6563
6800
  return;
6564
6801
  }
6565
6802
  console.log(
6566
- `${YELLOW9} Warning: Could not fetch theme "${options.theme}". Using defaults.${RESET13}`
6803
+ `${YELLOW9} Warning: Could not fetch theme "${options.theme}". Using defaults.${RESET14}`
6567
6804
  );
6568
6805
  }
6569
6806
  }
@@ -6689,7 +6926,7 @@ Validation warnings: ${validation.errors.join(", ")}`));
6689
6926
  };
6690
6927
  const curatedPrompt = generateCuratedPrompt(promptCtx);
6691
6928
  console.log("");
6692
- console.log(`${BOLD6}Prompt for your AI assistant:${RESET13}`);
6929
+ console.log(`${BOLD7}Prompt for your AI assistant:${RESET14}`);
6693
6930
  console.log(dim3("\u2500".repeat(50)));
6694
6931
  console.log("");
6695
6932
  console.log(curatedPrompt);
@@ -6706,7 +6943,7 @@ async function cmdStatus() {
6706
6943
  const projectJsonPath = join27(projectRoot, ".decantr", "project.json");
6707
6944
  console.log(heading2("Decantr Project Status"));
6708
6945
  if (!existsSync26(essencePath)) {
6709
- console.log(`${RED11}No decantr.essence.json found.${RESET13}`);
6946
+ console.log(`${RED11}No decantr.essence.json found.${RESET14}`);
6710
6947
  console.log(dim3('Run "decantr init" to create one.'));
6711
6948
  return;
6712
6949
  }
@@ -6714,11 +6951,11 @@ async function cmdStatus() {
6714
6951
  const essence = JSON.parse(readFileSync19(essencePath, "utf-8"));
6715
6952
  const validation = validateEssence2(essence);
6716
6953
  const essenceVersion = isV47(essence) ? "v4" : "legacy";
6717
- console.log(`${BOLD6}Essence:${RESET13}`);
6954
+ console.log(`${BOLD7}Essence:${RESET14}`);
6718
6955
  if (validation.valid) {
6719
- console.log(` ${GREEN13}Valid${RESET13} (${essenceVersion})`);
6956
+ console.log(` ${GREEN14}Valid${RESET14} (${essenceVersion})`);
6720
6957
  } else {
6721
- console.log(` ${RED11}Invalid: ${validation.errors.join(", ")}${RESET13}`);
6958
+ console.log(` ${RED11}Invalid: ${validation.errors.join(", ")}${RESET14}`);
6722
6959
  }
6723
6960
  if (isV47(essence)) {
6724
6961
  const v4 = essence;
@@ -6726,7 +6963,7 @@ async function cmdStatus() {
6726
6963
  const flatPages = sections.flatMap((section) => section.pages ?? []);
6727
6964
  const resolvedShell = sections.find((section) => section.role === "primary")?.shell || sections[0]?.shell || v4.blueprint.shell || "unknown";
6728
6965
  const resolvedFeatures = v4.blueprint.features ?? [];
6729
- console.log(` ${BOLD6}DNA:${RESET13}`);
6966
+ console.log(` ${BOLD7}DNA:${RESET14}`);
6730
6967
  console.log(` Theme: ${v4.dna.theme.id} (${v4.dna.theme.mode})`);
6731
6968
  console.log(
6732
6969
  ` Spacing: ${v4.dna.spacing.density} density, ${v4.dna.spacing.content_gap} gap`
@@ -6738,42 +6975,42 @@ async function cmdStatus() {
6738
6975
  );
6739
6976
  console.log(` Accessibility: WCAG ${v4.dna.accessibility.wcag_level}`);
6740
6977
  console.log(` Personality: ${v4.dna.personality.join(", ")}`);
6741
- console.log(` ${BOLD6}Blueprint:${RESET13}`);
6978
+ console.log(` ${BOLD7}Blueprint:${RESET14}`);
6742
6979
  console.log(` Shell: ${resolvedShell}`);
6743
6980
  console.log(` Pages: ${flatPages.length}`);
6744
6981
  console.log(` Sections: ${sections.length}`);
6745
6982
  console.log(
6746
6983
  ` Features: ${resolvedFeatures.length > 0 ? resolvedFeatures.join(", ") : "none"}`
6747
6984
  );
6748
- console.log(` ${BOLD6}Meta:${RESET13}`);
6985
+ console.log(` ${BOLD7}Meta:${RESET14}`);
6749
6986
  console.log(` Archetype: ${v4.meta.archetype}`);
6750
6987
  console.log(` Target: ${v4.meta.target}`);
6751
6988
  console.log(
6752
6989
  ` Guard: ${v4.meta.guard.mode} (DNA: ${v4.meta.guard.dna_enforcement}, Blueprint: ${v4.meta.guard.blueprint_enforcement})`
6753
6990
  );
6754
6991
  } else {
6755
- console.log(` ${YELLOW9}Run \`decantr migrate --to v4\` to upgrade this project.${RESET13}`);
6992
+ console.log(` ${YELLOW9}Run \`decantr migrate --to v4\` to upgrade this project.${RESET14}`);
6756
6993
  }
6757
6994
  } catch (e) {
6758
- console.log(` ${RED11}Error reading essence: ${e.message}${RESET13}`);
6995
+ console.log(` ${RED11}Error reading essence: ${e.message}${RESET14}`);
6759
6996
  }
6760
6997
  console.log("");
6761
- console.log(`${BOLD6}Sync Status:${RESET13}`);
6998
+ console.log(`${BOLD7}Sync Status:${RESET14}`);
6762
6999
  if (existsSync26(projectJsonPath)) {
6763
7000
  try {
6764
7001
  const projectJson = JSON.parse(readFileSync19(projectJsonPath, "utf-8"));
6765
7002
  const syncStatus = projectJson.sync?.status || "unknown";
6766
7003
  const lastSync = projectJson.sync?.lastSync || "never";
6767
7004
  const source = projectJson.sync?.registrySource || "unknown";
6768
- const statusColor = syncStatus === "synced" ? GREEN13 : YELLOW9;
6769
- console.log(` Status: ${statusColor}${syncStatus}${RESET13}`);
7005
+ const statusColor = syncStatus === "synced" ? GREEN14 : YELLOW9;
7006
+ console.log(` Status: ${statusColor}${syncStatus}${RESET14}`);
6770
7007
  console.log(` Last sync: ${dim3(lastSync)}`);
6771
7008
  console.log(` Source: ${dim3(source)}`);
6772
7009
  } catch {
6773
- console.log(` ${YELLOW9}Could not read project.json${RESET13}`);
7010
+ console.log(` ${YELLOW9}Could not read project.json${RESET14}`);
6774
7011
  }
6775
7012
  } else {
6776
- console.log(` ${YELLOW9}No .decantr/project.json found${RESET13}`);
7013
+ console.log(` ${YELLOW9}No .decantr/project.json found${RESET14}`);
6777
7014
  console.log(dim3(' Run "decantr init" to create project files.'));
6778
7015
  }
6779
7016
  }
@@ -6786,12 +7023,12 @@ async function cmdSync() {
6786
7023
  console.log(success3("Sync completed successfully."));
6787
7024
  console.log(` Synced: ${result.synced.join(", ")}`);
6788
7025
  if (result.failed.length > 0) {
6789
- console.log(` ${YELLOW9}Failed: ${result.failed.join(", ")}${RESET13}`);
7026
+ console.log(` ${YELLOW9}Failed: ${result.failed.join(", ")}${RESET14}`);
6790
7027
  }
6791
7028
  } else {
6792
- console.log(`${YELLOW9}Could not sync: API unavailable${RESET13}`);
7029
+ console.log(`${YELLOW9}Could not sync: API unavailable${RESET14}`);
6793
7030
  if (result.failed.length > 0) {
6794
- console.log(` ${YELLOW9}Failed: ${result.failed.join(", ")}${RESET13}`);
7031
+ console.log(` ${YELLOW9}Failed: ${result.failed.join(", ")}${RESET14}`);
6795
7032
  }
6796
7033
  }
6797
7034
  }
@@ -6801,15 +7038,15 @@ function printVerificationFindings(findings) {
6801
7038
  return;
6802
7039
  }
6803
7040
  for (const finding of findings) {
6804
- const color = finding.severity === "error" ? RED11 : finding.severity === "warn" ? YELLOW9 : CYAN7;
7041
+ const color = finding.severity === "error" ? RED11 : finding.severity === "warn" ? YELLOW9 : CYAN8;
6805
7042
  console.log(
6806
- ` ${color}[${finding.severity.toUpperCase()}]${RESET13} ${finding.category}: ${finding.message}`
7043
+ ` ${color}[${finding.severity.toUpperCase()}]${RESET14} ${finding.category}: ${finding.message}`
6807
7044
  );
6808
7045
  for (const evidence of finding.evidence) {
6809
- console.log(` ${DIM13}${evidence}${RESET13}`);
7046
+ console.log(` ${DIM14}${evidence}${RESET14}`);
6810
7047
  }
6811
7048
  if (finding.suggestedFix) {
6812
- console.log(` ${DIM13}Fix: ${finding.suggestedFix}${RESET13}`);
7049
+ console.log(` ${DIM14}Fix: ${finding.suggestedFix}${RESET14}`);
6813
7050
  }
6814
7051
  }
6815
7052
  }
@@ -6817,10 +7054,10 @@ function printProjectAuditReport(report) {
6817
7054
  if (report.valid) {
6818
7055
  console.log(success3("Project contract is valid."));
6819
7056
  } else {
6820
- console.log(`${RED11}Project audit found blocking issues.${RESET13}`);
7057
+ console.log(`${RED11}Project audit found blocking issues.${RESET14}`);
6821
7058
  }
6822
7059
  console.log("");
6823
- console.log(`${BOLD6}Summary:${RESET13}`);
7060
+ console.log(`${BOLD7}Summary:${RESET14}`);
6824
7061
  console.log(` Essence version: ${report.summary.essenceVersion ?? "missing"}`);
6825
7062
  console.log(` Pages defined: ${report.summary.pageCount}`);
6826
7063
  console.log(` Pack manifest: ${report.summary.packManifestPresent ? "present" : "missing"}`);
@@ -6849,23 +7086,23 @@ function printProjectAuditReport(report) {
6849
7086
  ` Findings: ${report.summary.errorCount} error(s), ${report.summary.warnCount} warn(s), ${report.summary.infoCount} info`
6850
7087
  );
6851
7088
  console.log("");
6852
- console.log(`${BOLD6}Findings:${RESET13}`);
7089
+ console.log(`${BOLD7}Findings:${RESET14}`);
6853
7090
  printVerificationFindings(report.findings);
6854
7091
  }
6855
7092
  function printFileCritiqueReport(report) {
6856
7093
  console.log(success3(`Critiqued ${report.file}`));
6857
7094
  console.log("");
6858
- console.log(`${BOLD6}Summary:${RESET13}`);
7095
+ console.log(`${BOLD7}Summary:${RESET14}`);
6859
7096
  console.log(` Overall score: ${report.overall}/5`);
6860
7097
  console.log(` Focus areas: ${report.focusAreas.join(", ")}`);
6861
7098
  console.log(` Review pack: ${report.reviewPack ? "present" : "missing"}`);
6862
7099
  console.log("");
6863
- console.log(`${BOLD6}Scores:${RESET13}`);
7100
+ console.log(`${BOLD7}Scores:${RESET14}`);
6864
7101
  for (const score of report.scores) {
6865
7102
  console.log(` ${cyan3(score.category.padEnd(20))} ${score.score}/5 ${dim3(score.details)}`);
6866
7103
  }
6867
7104
  console.log("");
6868
- console.log(`${BOLD6}Findings:${RESET13}`);
7105
+ console.log(`${BOLD7}Findings:${RESET14}`);
6869
7106
  printVerificationFindings(report.findings);
6870
7107
  }
6871
7108
  async function cmdAudit(filePath) {
@@ -6906,7 +7143,7 @@ async function cmdAudit(filePath) {
6906
7143
  console.log(dim3("Project audit completed with advisory findings."));
6907
7144
  }
6908
7145
  } catch (e) {
6909
- console.log(`${RED11}Error: ${e.message}${RESET13}`);
7146
+ console.log(`${RED11}Error: ${e.message}${RESET14}`);
6910
7147
  process.exitCode = 1;
6911
7148
  }
6912
7149
  }
@@ -6915,9 +7152,9 @@ async function cmdTheme(args) {
6915
7152
  const projectRoot = process.cwd();
6916
7153
  if (!subcommand || subcommand === "help") {
6917
7154
  console.log(`
6918
- ${BOLD6}decantr theme${RESET13} \u2014 Manage custom themes
7155
+ ${BOLD7}decantr theme${RESET14} \u2014 Manage custom themes
6919
7156
 
6920
- ${BOLD6}Commands:${RESET13}
7157
+ ${BOLD7}Commands:${RESET14}
6921
7158
  ${cyan3("create")} <name> Create a new custom theme
6922
7159
  ${cyan3("create")} <name> --guided Interactive theme creation
6923
7160
  ${cyan3("list")} List custom themes
@@ -6925,7 +7162,7 @@ ${BOLD6}Commands:${RESET13}
6925
7162
  ${cyan3("delete")} <name> Delete a custom theme
6926
7163
  ${cyan3("import")} <path> Import theme from JSON file
6927
7164
 
6928
- ${BOLD6}Examples:${RESET13}
7165
+ ${BOLD7}Examples:${RESET14}
6929
7166
  decantr theme create mytheme
6930
7167
  decantr theme list
6931
7168
  decantr theme validate mytheme
@@ -6988,7 +7225,7 @@ ${BOLD6}Examples:${RESET13}
6988
7225
  } else {
6989
7226
  console.error(error3("Validation failed:"));
6990
7227
  for (const err of result.errors) {
6991
- console.error(` ${RED11}${err}${RESET13}`);
7228
+ console.error(` ${RED11}${err}${RESET14}`);
6992
7229
  }
6993
7230
  process.exitCode = 1;
6994
7231
  }
@@ -7028,7 +7265,7 @@ ${BOLD6}Examples:${RESET13}
7028
7265
  } else {
7029
7266
  console.error(error3("Import failed:"));
7030
7267
  for (const err of result.errors || []) {
7031
- console.error(` ${RED11}${err}${RESET13}`);
7268
+ console.error(` ${RED11}${err}${RESET14}`);
7032
7269
  }
7033
7270
  process.exitCode = 1;
7034
7271
  }
@@ -7051,9 +7288,9 @@ ${BOLD6}Examples:${RESET13}
7051
7288
  }
7052
7289
  function cmdHelp() {
7053
7290
  console.log(`
7054
- ${BOLD6}decantr${RESET13} \u2014 Design intelligence for AI-generated UI
7291
+ ${BOLD7}decantr${RESET14} \u2014 Design intelligence for AI-generated UI
7055
7292
 
7056
- ${BOLD6}Usage:${RESET13}
7293
+ ${BOLD7}Usage:${RESET14}
7057
7294
  decantr new <name> [--blueprint=X] [--archetype=X] [--theme=X] [--workflow=greenfield] [--adoption=decantr-css] [--telemetry]
7058
7295
  decantr magic <prompt> [--dry-run]
7059
7296
  decantr init [options]
@@ -7078,6 +7315,9 @@ ${BOLD6}Usage:${RESET13}
7078
7315
  decantr health init-ci [--force] [--project <path>] [--fail-on <error|warn|none>] [--cli-version <version|latest>]
7079
7316
  decantr content-health [--json] [--markdown] [--ci]
7080
7317
  decantr studio [--port 4319] [--host 127.0.0.1] [--report decantr-health.json]
7318
+ decantr telemetry status [--json]
7319
+ decantr telemetry explain [--json]
7320
+ decantr telemetry link [--enable] [--org <slug>]
7081
7321
  decantr rules preview [--project=<path>]
7082
7322
  decantr rules apply [--project=<path>]
7083
7323
  decantr validate [path]
@@ -7089,7 +7329,7 @@ ${BOLD6}Usage:${RESET13}
7089
7329
  decantr logout
7090
7330
  decantr help
7091
7331
 
7092
- ${BOLD6}Init Options:${RESET13}
7332
+ ${BOLD7}Init Options:${RESET14}
7093
7333
  --blueprint, -b Blueprint ID
7094
7334
  --theme Theme ID
7095
7335
  --mode Color mode: dark | light | auto
@@ -7111,7 +7351,7 @@ ${BOLD6}Init Options:${RESET13}
7111
7351
  --registry Custom registry URL
7112
7352
  --telemetry Opt this project into privacy-filtered CLI product telemetry
7113
7353
 
7114
- ${BOLD6}Commands:${RESET13}
7354
+ ${BOLD7}Commands:${RESET14}
7115
7355
  ${cyan3("new")} Create a new greenfield workspace and bootstrap the available starter adapter
7116
7356
  ${cyan3("magic")} Greenfield-first intent flow; steers existing apps into analyze + init
7117
7357
  ${cyan3("init")} Attach Decantr contract/context files to an existing project or empty workspace
@@ -7136,13 +7376,14 @@ ${BOLD6}Commands:${RESET13}
7136
7376
  ${cyan3("login")} Authenticate with the Decantr registry
7137
7377
  ${cyan3("logout")} Remove stored credentials
7138
7378
  ${cyan3("analyze")} Brownfield entrypoint: scan an existing project and emit attach guidance
7379
+ ${cyan3("telemetry")} Inspect or link this project's opted-in CLI telemetry identity
7139
7380
  ${cyan3("export")} Export design tokens to framework format (shadcn, tailwind, css-vars)
7140
7381
  ${cyan3("registry")} Registry management and intelligence summary
7141
7382
  ${cyan3("rules")} Preview/apply Decantr assistant bridge blocks to repo rule files
7142
7383
  ${cyan3("upgrade")} Check for content updates from registry
7143
7384
  ${cyan3("help")} Show this help
7144
7385
 
7145
- ${BOLD6}Examples:${RESET13}
7386
+ ${BOLD7}Examples:${RESET14}
7146
7387
  decantr new my-app --blueprint=carbon-ai-portal
7147
7388
  decantr magic "AI chatbot with dark cyber theme \u2014 bold and futuristic"
7148
7389
  decantr init
@@ -7162,6 +7403,9 @@ ${BOLD6}Examples:${RESET13}
7162
7403
  decantr content-health --ci --fail-on error
7163
7404
  decantr studio
7164
7405
  decantr studio --report decantr-health.json
7406
+ decantr telemetry status
7407
+ decantr telemetry explain
7408
+ decantr telemetry link --enable --org my-team
7165
7409
  decantr audit
7166
7410
  decantr audit src/pages/HomePage.tsx
7167
7411
  decantr migrate --to v4
@@ -7182,30 +7426,30 @@ ${BOLD6}Examples:${RESET13}
7182
7426
  decantr registry audit-project --namespace @official --dist dist --sources src
7183
7427
  decantr create pattern my-card
7184
7428
 
7185
- ${BOLD6}Workflow Model:${RESET13}
7429
+ ${BOLD7}Workflow Model:${RESET14}
7186
7430
  ${cyan3("Greenfield blueprint")} decantr new my-app --blueprint=X --workflow=greenfield --adoption=decantr-css
7187
7431
  ${cyan3("Greenfield contract")} decantr init --workflow=greenfield --adoption=contract-only
7188
7432
  ${cyan3("Brownfield adoption")} decantr analyze -> decantr init --existing --accept-proposal -> decantr check --brownfield
7189
7433
  ${cyan3("Hybrid composition")} decantr add/remove, decantr theme switch, decantr registry, decantr upgrade
7190
7434
 
7191
- ${BOLD6}Bootstrap adapters:${RESET13}
7435
+ ${BOLD7}Bootstrap adapters:${RESET14}
7192
7436
  Runnable starter adapters: ${cyan3("react-vite")}, ${cyan3("next-app")}
7193
7437
  Unsupported targets resolve through ${cyan3("generic-web")} contract-only mode until their starter adapters land.
7194
7438
  `);
7195
7439
  }
7196
7440
  function cmdRulesHelp() {
7197
7441
  console.log(`
7198
- ${BOLD6}decantr rules${RESET13} \u2014 Preview or apply assistant bridge snippets
7442
+ ${BOLD7}decantr rules${RESET14} \u2014 Preview or apply assistant bridge snippets
7199
7443
 
7200
- ${BOLD6}Usage:${RESET13}
7444
+ ${BOLD7}Usage:${RESET14}
7201
7445
  decantr rules preview [--project=<path>]
7202
7446
  decantr rules apply [--project=<path>]
7203
7447
 
7204
- ${BOLD6}Subcommands:${RESET13}
7448
+ ${BOLD7}Subcommands:${RESET14}
7205
7449
  ${cyan3("preview")} Print target-specific Decantr bridge guidance without mutating rule files
7206
7450
  ${cyan3("apply")} Idempotently write Decantr bridge blocks to supported assistant rule files
7207
7451
 
7208
- ${BOLD6}Examples:${RESET13}
7452
+ ${BOLD7}Examples:${RESET14}
7209
7453
  decantr rules preview
7210
7454
  decantr rules preview --project=apps/web
7211
7455
  decantr rules apply --project=apps/web
@@ -7216,9 +7460,9 @@ function isCommandHelpRequest(args) {
7216
7460
  }
7217
7461
  function cmdHealthHelp() {
7218
7462
  console.log(`
7219
- ${BOLD6}decantr health${RESET13} \u2014 Generate a local Project Health report
7463
+ ${BOLD7}decantr health${RESET14} \u2014 Generate a local Project Health report
7220
7464
 
7221
- ${BOLD6}Usage:${RESET13}
7465
+ ${BOLD7}Usage:${RESET14}
7222
7466
  decantr health [--format text|json|markdown] [--output <file>]
7223
7467
  decantr health --json
7224
7468
  decantr health --markdown
@@ -7226,7 +7470,7 @@ ${BOLD6}Usage:${RESET13}
7226
7470
  decantr health --prompt <finding-id>
7227
7471
  decantr health init-ci [--force] [--project <path>] [--fail-on error|warn|none] [--cli-version <version|latest>]
7228
7472
 
7229
- ${BOLD6}Options:${RESET13}
7473
+ ${BOLD7}Options:${RESET14}
7230
7474
  --format Output format: text, json, or markdown
7231
7475
  --json Emit JSON report
7232
7476
  --markdown Emit markdown report
@@ -7235,7 +7479,7 @@ ${BOLD6}Options:${RESET13}
7235
7479
  --fail-on CI threshold: error, warn, or none
7236
7480
  --prompt Print an AI-ready remediation prompt for a finding
7237
7481
 
7238
- ${BOLD6}Examples:${RESET13}
7482
+ ${BOLD7}Examples:${RESET14}
7239
7483
  decantr health
7240
7484
  decantr health --json
7241
7485
  decantr health --markdown --output decantr-health.md
@@ -7246,16 +7490,16 @@ ${BOLD6}Examples:${RESET13}
7246
7490
  }
7247
7491
  function cmdContentHealthHelp() {
7248
7492
  console.log(`
7249
- ${BOLD6}decantr content-health${RESET13} \u2014 Generate a local registry content health report
7493
+ ${BOLD7}decantr content-health${RESET14} \u2014 Generate a local registry content health report
7250
7494
 
7251
- ${BOLD6}Usage:${RESET13}
7495
+ ${BOLD7}Usage:${RESET14}
7252
7496
  decantr content-health [--format text|json|markdown] [--output <file>]
7253
7497
  decantr content-health --json
7254
7498
  decantr content-health --markdown
7255
7499
  decantr content-health --ci [--fail-on error|warn|none]
7256
7500
  decantr content-health --prompt <finding-id>
7257
7501
 
7258
- ${BOLD6}Options:${RESET13}
7502
+ ${BOLD7}Options:${RESET14}
7259
7503
  --format Output format: text, json, or markdown
7260
7504
  --json Emit JSON report
7261
7505
  --markdown Emit markdown report
@@ -7264,7 +7508,7 @@ ${BOLD6}Options:${RESET13}
7264
7508
  --fail-on CI threshold: error, warn, or none
7265
7509
  --prompt Print an AI-ready remediation prompt for a finding
7266
7510
 
7267
- ${BOLD6}Examples:${RESET13}
7511
+ ${BOLD7}Examples:${RESET14}
7268
7512
  decantr content-health
7269
7513
  decantr content-health --json
7270
7514
  decantr content-health --markdown --output content-health.md
@@ -7273,22 +7517,22 @@ ${BOLD6}Examples:${RESET13}
7273
7517
  }
7274
7518
  function cmdStudioHelp() {
7275
7519
  console.log(`
7276
- ${BOLD6}decantr studio${RESET13} \u2014 Run a local Project Health dashboard
7520
+ ${BOLD7}decantr studio${RESET14} \u2014 Run a local Project Health dashboard
7277
7521
 
7278
- ${BOLD6}Usage:${RESET13}
7522
+ ${BOLD7}Usage:${RESET14}
7279
7523
  decantr studio [--port 4319] [--host 127.0.0.1] [--report decantr-health.json]
7280
7524
 
7281
- ${BOLD6}Options:${RESET13}
7525
+ ${BOLD7}Options:${RESET14}
7282
7526
  --port Local port to bind; defaults to 4319
7283
7527
  --host Local host to bind; defaults to 127.0.0.1
7284
7528
  --report Serve a read-only Project Health JSON artifact instead of scanning the current project
7285
7529
 
7286
- ${BOLD6}Endpoints:${RESET13}
7530
+ ${BOLD7}Endpoints:${RESET14}
7287
7531
  GET /
7288
7532
  GET /api/health
7289
7533
  POST /api/refresh
7290
7534
 
7291
- ${BOLD6}Examples:${RESET13}
7535
+ ${BOLD7}Examples:${RESET14}
7292
7536
  decantr studio
7293
7537
  decantr studio --port 4320
7294
7538
  decantr studio --host 127.0.0.1 --port 4319
@@ -7418,10 +7662,10 @@ async function main() {
7418
7662
  case "heal": {
7419
7663
  if (command === "heal") {
7420
7664
  console.log(
7421
- `${YELLOW9}Note: \`decantr heal\` is deprecated. Use \`decantr check\` instead.${RESET13}`
7665
+ `${YELLOW9}Note: \`decantr heal\` is deprecated. Use \`decantr check\` instead.${RESET14}`
7422
7666
  );
7423
7667
  }
7424
- const { cmdHeal } = await import("./heal-NWQNJ6PU.js");
7668
+ const { cmdHeal } = await import("./heal-M6PRCIIF.js");
7425
7669
  const telemetryFlag = args.includes("--telemetry");
7426
7670
  const brownfieldFlag = args.includes("--brownfield");
7427
7671
  await cmdHeal(process.cwd(), { telemetry: telemetryFlag, brownfield: brownfieldFlag });
@@ -7433,7 +7677,7 @@ async function main() {
7433
7677
  cmdHealthHelp();
7434
7678
  break;
7435
7679
  }
7436
- const { cmdHealth, parseHealthArgs } = await import("./health-WJJ55W3H.js");
7680
+ const { cmdHealth, parseHealthArgs } = await import("./health-EENY3BFS.js");
7437
7681
  await cmdHealth(process.cwd(), parseHealthArgs(args));
7438
7682
  } catch (e) {
7439
7683
  console.error(error3(e.message));
@@ -7461,7 +7705,7 @@ async function main() {
7461
7705
  cmdStudioHelp();
7462
7706
  break;
7463
7707
  }
7464
- const { cmdStudio, parseStudioArgs } = await import("./studio-7XAXWRVN.js");
7708
+ const { cmdStudio, parseStudioArgs } = await import("./studio-TBJPZZHA.js");
7465
7709
  await cmdStudio(process.cwd(), parseStudioArgs(args));
7466
7710
  } catch (e) {
7467
7711
  console.error(error3(e.message));
@@ -7634,6 +7878,10 @@ async function main() {
7634
7878
  console.log(success3("Logged out. Credentials removed."));
7635
7879
  break;
7636
7880
  }
7881
+ case "telemetry": {
7882
+ await cmdTelemetry(args.slice(1), process.cwd());
7883
+ break;
7884
+ }
7637
7885
  case "create": {
7638
7886
  const type = args[1];
7639
7887
  const name = args[2];
@@ -7692,7 +7940,7 @@ async function main() {
7692
7940
  const id = args[3] && !args[3].startsWith("--") ? args[3] : void 0;
7693
7941
  if (!packType || !["manifest", "scaffold", "review", "section", "page", "mutation"].includes(packType)) {
7694
7942
  console.error(
7695
- `${RED11}Usage: decantr registry get-pack <manifest|scaffold|review|section|page|mutation> [id] [--namespace <namespace>] [--json] [--essence <path>] [--write-context]${RESET13}`
7943
+ `${RED11}Usage: decantr registry get-pack <manifest|scaffold|review|section|page|mutation> [id] [--namespace <namespace>] [--json] [--essence <path>] [--write-context]${RESET14}`
7696
7944
  );
7697
7945
  process.exitCode = 1;
7698
7946
  break;
@@ -7720,7 +7968,7 @@ async function main() {
7720
7968
  const sourcePath = args[2] && !args[2].startsWith("--") ? args[2] : void 0;
7721
7969
  if (!sourcePath) {
7722
7970
  console.error(
7723
- `${RED11}Usage: decantr registry critique-file <file> [--namespace <namespace>] [--json] [--essence <path>] [--treatments <path>]${RESET13}`
7971
+ `${RED11}Usage: decantr registry critique-file <file> [--namespace <namespace>] [--json] [--essence <path>] [--treatments <path>]${RESET14}`
7724
7972
  );
7725
7973
  process.exitCode = 1;
7726
7974
  break;
@@ -7745,7 +7993,7 @@ async function main() {
7745
7993
  await printHostedProjectAudit(namespace, jsonOutput, essencePath, distPath, sourcesPath);
7746
7994
  } else {
7747
7995
  console.error(
7748
- `${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}`
7996
+ `${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}`
7749
7997
  );
7750
7998
  process.exitCode = 1;
7751
7999
  }
@@ -7861,7 +8109,7 @@ async function main() {
7861
8109
  process.exitCode = 1;
7862
8110
  break;
7863
8111
  }
7864
- cmdAnalyze(workspaceInfo.appRoot, workspaceInfo);
8112
+ await cmdAnalyze(workspaceInfo.appRoot, workspaceInfo);
7865
8113
  break;
7866
8114
  }
7867
8115
  case "rules": {
@@ -7925,7 +8173,7 @@ async function main() {
7925
8173
  console.error("");
7926
8174
  console.error(" Example:");
7927
8175
  console.error(
7928
- ` ${CYAN7}decantr magic "AI agent dashboard \u2014 dark, neon, confident"${RESET13}`
8176
+ ` ${CYAN8}decantr magic "AI agent dashboard \u2014 dark, neon, confident"${RESET14}`
7929
8177
  );
7930
8178
  process.exitCode = 1;
7931
8179
  break;