@decantr/cli 3.5.4 → 3.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-GPGBJFMF.js";
2
+ import "./chunk-4O74E2PS.js";
3
3
  import "./chunk-SIDKK73N.js";
4
- import "./chunk-UDBPH25I.js";
5
- import "./chunk-EWUWVQYM.js";
6
- import "./chunk-4WVKE2AQ.js";
4
+ import "./chunk-FIWVRMZN.js";
5
+ import "./chunk-U62GGKUO.js";
6
+ import "./chunk-24JR4ZNG.js";
@@ -328,7 +328,7 @@ function scanAmbientContext(projectRoot) {
328
328
 
329
329
  // src/analyzers/routes.ts
330
330
  import { existsSync as existsSync2, readdirSync as readdirSync2, readFileSync as readFileSync2, statSync as statSync2 } from "fs";
331
- import { join as join2, relative as relative2 } from "path";
331
+ import { extname as extname2, join as join2, relative as relative2 } from "path";
332
332
  var SKIP_DIRS2 = /* @__PURE__ */ new Set(["node_modules", ".next", ".git", "api", "_app", "_document"]);
333
333
  function shouldSkipDir2(name) {
334
334
  return name.startsWith("_") || name.startsWith(".") || SKIP_DIRS2.has(name);
@@ -460,6 +460,16 @@ var ROUTE_VARIABLE_NAMES = "(?:path|pathname|route|currentPath|currentRoute|loca
460
460
  var ROUTE_ASSET_EXTENSION_RE = /\.(?:avif|bmp|css|gif|ico|jpeg|jpg|js|json|map|mp4|pdf|png|svg|webp|woff2?)$/i;
461
461
  var JSX_ROUTE_PATH_RE = /<(?:Route|[A-Z][\w.]*Route)\b[^>]*\bpath\s*=\s*(?:"([^"]+)"|'([^']+)'|{\s*"([^"]+)"\s*}|{\s*'([^']+)'\s*}|{\s*`([^`]+)`\s*})/g;
462
462
  var OBJECT_ROUTE_PATH_RE = /\bpath\s*:\s*(?:"([^"]+)"|'([^']+)'|`([^`]+)`)/g;
463
+ var STATIC_HTML_ENTRY_FILES = [
464
+ "index.html",
465
+ "docs/index.html",
466
+ "src/index.html",
467
+ "public/index.html",
468
+ "dist/index.html"
469
+ ];
470
+ var STATIC_HTML_ROUTE_DIRS = ["demos", "examples"];
471
+ var MAX_STATIC_HTML_ROUTES = 80;
472
+ var MAX_STATIC_HTML_CANDIDATES = 1e3;
463
473
  function collectRouteCandidateFiles(dir, files, depth = 0) {
464
474
  if (depth > 5) return;
465
475
  let entries;
@@ -568,6 +578,65 @@ function collectRouteLiterals(pattern, content, routes) {
568
578
  }
569
579
  return count;
570
580
  }
581
+ function htmlRouteFromFile(file) {
582
+ let withoutExt = file.slice(0, -extname2(file).length).replace(/\\/g, "/");
583
+ if (withoutExt.endsWith("/index")) withoutExt = withoutExt.slice(0, -"/index".length);
584
+ if (withoutExt === "index" || withoutExt === "docs" || withoutExt === "src" || withoutExt === "public" || withoutExt === "dist") {
585
+ return "/";
586
+ }
587
+ return `/${withoutExt.split("/").filter(Boolean).join("/")}` || "/";
588
+ }
589
+ function collectStaticHtmlFiles(dir, projectRoot, files, depth = 0) {
590
+ if (depth > 5 || files.length >= MAX_STATIC_HTML_CANDIDATES) return;
591
+ let entries;
592
+ try {
593
+ entries = readdirSync2(dir).sort();
594
+ } catch {
595
+ return;
596
+ }
597
+ for (const entry of entries) {
598
+ if (files.length >= MAX_STATIC_HTML_CANDIDATES) return;
599
+ if (entry.startsWith(".") || entry === "node_modules") continue;
600
+ const fullPath = join2(dir, entry);
601
+ try {
602
+ const stat = statSync2(fullPath);
603
+ if (stat.isDirectory()) {
604
+ collectStaticHtmlFiles(fullPath, projectRoot, files, depth + 1);
605
+ } else if (stat.isFile() && /\.(?:html|htm)$/i.test(entry)) {
606
+ files.push(relative2(projectRoot, fullPath).replace(/\\/g, "/"));
607
+ }
608
+ } catch {
609
+ }
610
+ }
611
+ }
612
+ function staticHtmlFilePriority(file) {
613
+ const base = file.split("/").pop()?.toLowerCase();
614
+ if (base === "index.html" || base === "index.htm") return 0;
615
+ if (base === "default.html" || base === "default.htm") return 1;
616
+ return 2;
617
+ }
618
+ function scanStaticHtmlRoutes(projectRoot) {
619
+ const routes = /* @__PURE__ */ new Map();
620
+ for (const file of STATIC_HTML_ENTRY_FILES) {
621
+ if (!existsSync2(join2(projectRoot, file))) continue;
622
+ routes.set("/", { path: "/", file, hasLayout: false });
623
+ break;
624
+ }
625
+ for (const dir of STATIC_HTML_ROUTE_DIRS) {
626
+ const fullDir = join2(projectRoot, dir);
627
+ if (!existsSync2(fullDir)) continue;
628
+ const files = [];
629
+ collectStaticHtmlFiles(fullDir, projectRoot, files);
630
+ for (const file of files.sort(
631
+ (a, b) => staticHtmlFilePriority(a) - staticHtmlFilePriority(b) || a.localeCompare(b)
632
+ )) {
633
+ const routePath = htmlRouteFromFile(file);
634
+ if (routes.has(routePath)) continue;
635
+ routes.set(routePath, { path: routePath, file, hasLayout: false });
636
+ }
637
+ }
638
+ return [...routes.values()].slice(0, MAX_STATIC_HTML_ROUTES);
639
+ }
571
640
  function detectPathnameBranchRoutes(content) {
572
641
  const routes = /* @__PURE__ */ new Set();
573
642
  const comparison = new RegExp(
@@ -739,6 +808,10 @@ function scanRoutes(projectRoot) {
739
808
  if (reactRouterRoutes.length > 0) {
740
809
  return { strategy: "react-router", routes: reactRouterRoutes };
741
810
  }
811
+ const staticHtmlRoutes = scanStaticHtmlRoutes(projectRoot);
812
+ if (staticHtmlRoutes.length > 0) {
813
+ return { strategy: "static-html", routes: staticHtmlRoutes };
814
+ }
742
815
  return { strategy: "none", routes: [] };
743
816
  }
744
817
 
@@ -1534,7 +1607,7 @@ function buildGuardRegistryContext(projectRoot = process.cwd()) {
1534
1607
 
1535
1608
  // src/lib/scan-interactions.ts
1536
1609
  import { existsSync as existsSync8, readdirSync as readdirSync6, readFileSync as readFileSync8, statSync as statSync4 } from "fs";
1537
- import { extname as extname2, join as join8, relative as relative4 } from "path";
1610
+ import { extname as extname3, join as join8, relative as relative4 } from "path";
1538
1611
  import { verifyInteractionsInSource } from "@decantr/verifier";
1539
1612
  var SCAN_EXTENSIONS = /* @__PURE__ */ new Set([".tsx", ".jsx", ".ts", ".js", ".html", ".mdx"]);
1540
1613
  var SKIP_DIRECTORIES = /* @__PURE__ */ new Set([
@@ -1586,7 +1659,7 @@ function walkSourceTree(rootDir) {
1586
1659
  const relativePath = relative4(rootDir, fullPath) || entry;
1587
1660
  if (s.isDirectory()) {
1588
1661
  walk2(fullPath);
1589
- } else if (s.isFile() && SCAN_EXTENSIONS.has(extname2(entry))) {
1662
+ } else if (s.isFile() && SCAN_EXTENSIONS.has(extname3(entry))) {
1590
1663
  if (s.size > MAX_FILE_SIZE) continue;
1591
1664
  if (isNonUiInteractionSource(relativePath)) continue;
1592
1665
  try {
@@ -22,7 +22,7 @@ import {
22
22
  listWorkspaceCandidates,
23
23
  listWorkspaceProjects,
24
24
  shouldFailWorkspaceHealth
25
- } from "./chunk-UDBPH25I.js";
25
+ } from "./chunk-FIWVRMZN.js";
26
26
  import {
27
27
  acceptBrownfieldLocalLaw,
28
28
  acceptStyleBridge,
@@ -52,7 +52,7 @@ import {
52
52
  writeBrownfieldCodifyProposal,
53
53
  writeHostedPatternMappingProposal,
54
54
  writeStyleBridgeProposal
55
- } from "./chunk-EWUWVQYM.js";
55
+ } from "./chunk-U62GGKUO.js";
56
56
  import {
57
57
  buildGuardRegistryContext,
58
58
  createDoctrineMap,
@@ -69,7 +69,7 @@ import {
69
69
  sendCliCommandTelemetry,
70
70
  sendNewProjectCompletedTelemetry,
71
71
  writeDoctrineMap
72
- } from "./chunk-4WVKE2AQ.js";
72
+ } from "./chunk-24JR4ZNG.js";
73
73
 
74
74
  // src/index.ts
75
75
  import { existsSync as existsSync29, mkdirSync as mkdirSync16, readdirSync as readdirSync8, readFileSync as readFileSync22, writeFileSync as writeFileSync19 } from "fs";
@@ -2940,6 +2940,21 @@ var RULE_FILES = [
2940
2940
  ".github/copilot-instructions.md",
2941
2941
  ".windsurfrules"
2942
2942
  ];
2943
+ var STATIC_HTML_ENTRY_FILES = [
2944
+ "index.html",
2945
+ "docs/index.html",
2946
+ "src/index.html",
2947
+ "public/index.html",
2948
+ "dist/index.html"
2949
+ ];
2950
+ var STATIC_HTML_ROUTE_DIRS = ["demos", "examples"];
2951
+ function hasAnyFile(projectRoot, relPaths) {
2952
+ return relPaths.some((relPath) => existsSync10(join12(projectRoot, relPath)));
2953
+ }
2954
+ function hasStaticHtmlSurface(projectRoot) {
2955
+ if (hasAnyFile(projectRoot, STATIC_HTML_ENTRY_FILES)) return true;
2956
+ return STATIC_HTML_ROUTE_DIRS.some((dir) => existsSync10(join12(projectRoot, dir, "index.html")));
2957
+ }
2943
2958
  function readPackageJson(dir) {
2944
2959
  const path = join12(dir, "package.json");
2945
2960
  if (!existsSync10(path)) return null;
@@ -3045,8 +3060,8 @@ function detectProject(projectRoot = process.cwd()) {
3045
3060
  } catch {
3046
3061
  }
3047
3062
  }
3048
- if (result.framework === "unknown" && !existsSync10(packageJsonPath)) {
3049
- if (existsSync10(join12(projectRoot, "index.html"))) {
3063
+ if (result.framework === "unknown") {
3064
+ if (hasStaticHtmlSurface(projectRoot)) {
3050
3065
  result.framework = "html";
3051
3066
  }
3052
3067
  }
@@ -4251,7 +4266,7 @@ function rel(root, path) {
4251
4266
  const value = relative4(root, path).replace(/\\/g, "/");
4252
4267
  return value || ".";
4253
4268
  }
4254
- function hasAnyFile(dir, names) {
4269
+ function hasAnyFile2(dir, names) {
4255
4270
  for (const name of names) {
4256
4271
  const path = join17(dir, name);
4257
4272
  if (existsSync15(path)) return name;
@@ -4280,7 +4295,7 @@ function detectDesignAuthority(workspaceRoot, appRoot) {
4280
4295
  }
4281
4296
  for (const root of [appRoot, workspaceRoot]) {
4282
4297
  const label = root === appRoot ? "app" : "workspace";
4283
- const tailwind = hasAnyFile(root, [
4298
+ const tailwind = hasAnyFile2(root, [
4284
4299
  "tailwind.config.js",
4285
4300
  "tailwind.config.ts",
4286
4301
  "tailwind.config.mjs",
@@ -11078,7 +11093,7 @@ async function cmdAdoptWorkflow(args) {
11078
11093
  await cmdGraph(projectRoot, { displayRoot: process.cwd() });
11079
11094
  if (process.exitCode && process.exitCode !== 0) return;
11080
11095
  if (runVerify) {
11081
- const { cmdHealth } = await import("./health-WO2BQYIC.js");
11096
+ const { cmdHealth } = await import("./health-RRIM7YAV.js");
11082
11097
  await cmdHealth(projectRoot, {
11083
11098
  browser: runBrowser,
11084
11099
  browserBaseUrl: baseUrl,
@@ -11152,7 +11167,7 @@ async function cmdVerifyWorkflow(args) {
11152
11167
  return;
11153
11168
  }
11154
11169
  if (workspaceMode) {
11155
- const { cmdWorkspace } = await import("./workspace-G6PN53XI.js");
11170
+ const { cmdWorkspace } = await import("./workspace-47XLOUGD.js");
11156
11171
  await cmdWorkspace(process.cwd(), ["workspace", "health", ...withoutWorkflowOnlyFlags(args)]);
11157
11172
  return;
11158
11173
  }
@@ -11185,7 +11200,7 @@ async function cmdVerifyWorkflow(args) {
11185
11200
  }
11186
11201
  let guardExitCode;
11187
11202
  if (brownfield) {
11188
- const { cmdHeal, collectCheckIssues } = await import("./heal-4BQCO4ST.js");
11203
+ const { cmdHeal, collectCheckIssues } = await import("./heal-2FK63EQE.js");
11189
11204
  if (quietOutput) {
11190
11205
  const result = collectCheckIssues(workspaceInfo.appRoot, { brownfield: true });
11191
11206
  guardExitCode = result.issues.some((issue) => issue.type === "error") ? 1 : void 0;
@@ -11195,7 +11210,7 @@ async function cmdVerifyWorkflow(args) {
11195
11210
  process.exitCode = void 0;
11196
11211
  }
11197
11212
  }
11198
- const { cmdHealth, parseHealthArgs } = await import("./health-WO2BQYIC.js");
11213
+ const { cmdHealth, parseHealthArgs } = await import("./health-RRIM7YAV.js");
11199
11214
  await cmdHealth(workspaceInfo.appRoot, parseHealthArgs(healthArgs));
11200
11215
  if (localPatterns) {
11201
11216
  const validation = validateLocalLaw(workspaceInfo.appRoot);
@@ -12832,7 +12847,7 @@ async function main() {
12832
12847
  `${YELLOW13}Note: \`decantr heal\` is deprecated. Use \`decantr check\` instead.${RESET17}`
12833
12848
  );
12834
12849
  }
12835
- const { cmdHeal } = await import("./heal-4BQCO4ST.js");
12850
+ const { cmdHeal } = await import("./heal-2FK63EQE.js");
12836
12851
  const { flags } = parseLooseArgs(args);
12837
12852
  const workspaceInfo = resolveWorkflowProject(flags, "check");
12838
12853
  if (!workspaceInfo) break;
@@ -12857,7 +12872,7 @@ async function main() {
12857
12872
  const { flags } = parseLooseArgs(args);
12858
12873
  const workspaceInfo = resolveWorkflowProject(flags, "health");
12859
12874
  if (!workspaceInfo) break;
12860
- const { cmdHealth, parseHealthArgs } = await import("./health-WO2BQYIC.js");
12875
+ const { cmdHealth, parseHealthArgs } = await import("./health-RRIM7YAV.js");
12861
12876
  await cmdHealth(workspaceInfo.appRoot, parseHealthArgs(stripProjectArgs(args)));
12862
12877
  } catch (e) {
12863
12878
  console.error(error2(e.message));
@@ -12885,7 +12900,7 @@ async function main() {
12885
12900
  cmdStudioHelp();
12886
12901
  break;
12887
12902
  }
12888
- const { cmdStudio, parseStudioArgs } = await import("./studio-TXFV3PDM.js");
12903
+ const { cmdStudio, parseStudioArgs } = await import("./studio-RGXIJL3J.js");
12889
12904
  await cmdStudio(process.cwd(), parseStudioArgs(args));
12890
12905
  } catch (e) {
12891
12906
  console.error(error2(e.message));
@@ -12899,7 +12914,7 @@ async function main() {
12899
12914
  cmdWorkspaceHelp();
12900
12915
  break;
12901
12916
  }
12902
- const { cmdWorkspace } = await import("./workspace-G6PN53XI.js");
12917
+ const { cmdWorkspace } = await import("./workspace-47XLOUGD.js");
12903
12918
  await cmdWorkspace(process.cwd(), args);
12904
12919
  } catch (e) {
12905
12920
  console.error(error2(e.message));
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createProjectHealthReport,
3
3
  listWorkspaceAppCandidates
4
- } from "./chunk-EWUWVQYM.js";
4
+ } from "./chunk-U62GGKUO.js";
5
5
 
6
6
  // src/commands/workspace.ts
7
7
  import { execFileSync } from "child_process";
@@ -3,7 +3,7 @@ import {
3
3
  sendProjectHealthCiFailedTelemetry,
4
4
  sendProjectHealthPromptTelemetry,
5
5
  sendProjectHealthReportTelemetry
6
- } from "./chunk-4WVKE2AQ.js";
6
+ } from "./chunk-24JR4ZNG.js";
7
7
 
8
8
  // src/commands/health.ts
9
9
  import { execFileSync as execFileSync2 } from "child_process";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  cmdHeal,
3
3
  collectCheckIssues
4
- } from "./chunk-4WVKE2AQ.js";
4
+ } from "./chunk-24JR4ZNG.js";
5
5
  export {
6
6
  cmdHeal,
7
7
  collectCheckIssues
@@ -13,8 +13,8 @@ import {
13
13
  renderProjectHealthCiWorkflow,
14
14
  shouldFailHealth,
15
15
  writeProjectHealthCiWorkflow
16
- } from "./chunk-EWUWVQYM.js";
17
- import "./chunk-4WVKE2AQ.js";
16
+ } from "./chunk-U62GGKUO.js";
17
+ import "./chunk-24JR4ZNG.js";
18
18
  export {
19
19
  cmdHealth,
20
20
  collectDesignTokenEvidence,
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import "./chunk-GPGBJFMF.js";
1
+ import "./chunk-4O74E2PS.js";
2
2
  import "./chunk-SIDKK73N.js";
3
- import "./chunk-UDBPH25I.js";
4
- import "./chunk-EWUWVQYM.js";
5
- import "./chunk-4WVKE2AQ.js";
3
+ import "./chunk-FIWVRMZN.js";
4
+ import "./chunk-U62GGKUO.js";
5
+ import "./chunk-24JR4ZNG.js";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  createWorkspaceHealthReport
3
- } from "./chunk-UDBPH25I.js";
3
+ } from "./chunk-FIWVRMZN.js";
4
4
  import {
5
5
  createProjectHealthReport
6
- } from "./chunk-EWUWVQYM.js";
6
+ } from "./chunk-U62GGKUO.js";
7
7
  import {
8
8
  sendStudioHealthRefreshedTelemetry,
9
9
  sendStudioStartedTelemetry
10
- } from "./chunk-4WVKE2AQ.js";
10
+ } from "./chunk-24JR4ZNG.js";
11
11
 
12
12
  // src/commands/studio.ts
13
13
  import { existsSync, readFileSync } from "fs";
@@ -7,9 +7,9 @@ import {
7
7
  listWorkspaceProjects,
8
8
  parseWorkspaceArgs,
9
9
  shouldFailWorkspaceHealth
10
- } from "./chunk-UDBPH25I.js";
11
- import "./chunk-EWUWVQYM.js";
12
- import "./chunk-4WVKE2AQ.js";
10
+ } from "./chunk-FIWVRMZN.js";
11
+ import "./chunk-U62GGKUO.js";
12
+ import "./chunk-24JR4ZNG.js";
13
13
  export {
14
14
  cmdWorkspace,
15
15
  createWorkspaceHealthReport,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decantr/cli",
3
- "version": "3.5.4",
3
+ "version": "3.5.5",
4
4
  "description": "Decantr CLI - adopt, verify, graph, and govern frontend codebases touched by AI agents",
5
5
  "keywords": [
6
6
  "decantr",
@@ -49,11 +49,11 @@
49
49
  },
50
50
  "dependencies": {
51
51
  "ajv": "^8.20.0",
52
- "@decantr/essence-spec": "3.4.0",
53
52
  "@decantr/core": "3.5.0",
54
- "@decantr/telemetry": "3.4.0",
53
+ "@decantr/essence-spec": "3.4.0",
55
54
  "@decantr/registry": "3.4.0",
56
- "@decantr/verifier": "3.5.4"
55
+ "@decantr/telemetry": "3.4.0",
56
+ "@decantr/verifier": "3.5.5"
57
57
  },
58
58
  "scripts": {
59
59
  "build": "tsup",