@woodsportal/hubspot-kit 1.0.26 → 1.0.29

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/cli.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-GTTIJVAR.js";
10
10
 
11
11
  // src/cli/program.ts
12
- import { readFileSync as readFileSync14 } from "fs";
12
+ import { readFileSync as readFileSync13 } from "fs";
13
13
  import { resolve as resolve21 } from "path";
14
14
  import { Command } from "commander";
15
15
 
@@ -185,14 +185,14 @@ function getKitRoot() {
185
185
  return kitRoot;
186
186
  }
187
187
  function findProjectRoot2(from = process.cwd()) {
188
- const root = findProjectRoot(from);
189
- if (!root) {
188
+ const resolved = findProjectRoot(from);
189
+ if (!resolved) {
190
190
  throw new WpHsError("Could not find woodscli.json in this directory or any parent.", {
191
191
  exitCode: ExitCode.USER_ERROR,
192
- remediation: "Run wp init, wp adopt, or pass --project <path>. Legacy config: wp migrate --yes."
192
+ remediation: "Run wp init, or pass --project <path>. Legacy config: wp migrate --yes."
193
193
  });
194
194
  }
195
- return root;
195
+ return resolved;
196
196
  }
197
197
  function kitPath(...segments) {
198
198
  return resolve2(kitRoot, ...segments);
@@ -205,7 +205,7 @@ function loadConfig(projectRoot) {
205
205
  if (!resolved) {
206
206
  throw new WpHsError(`Missing ${WOODSCLI_CONFIG_FILE}`, {
207
207
  exitCode: ExitCode.USER_ERROR,
208
- remediation: "Run wp init or wp adopt. Legacy woodsportal.hs.json \u2192 run wp migrate --yes."
208
+ remediation: "Run wp init. Legacy woodsportal.hs.json \u2192 run wp migrate --yes."
209
209
  });
210
210
  }
211
211
  let raw;
@@ -293,8 +293,8 @@ function defaultBaselineDir(projectRoot, config) {
293
293
  }
294
294
 
295
295
  // src/cli/commands/doctor.ts
296
- import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
297
- import { join, resolve as resolve5 } from "path";
296
+ import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
297
+ import { join, resolve as resolve6 } from "path";
298
298
 
299
299
  // src/lib/cli-spinner.ts
300
300
  import * as p from "@clack/prompts";
@@ -520,7 +520,7 @@ var VITE_DEV_PEER_DEPS = {
520
520
  tailwindcss: "^4.0.6"
521
521
  };
522
522
  var KIT_DEV_DEP = "@woodsportal/hubspot-kit";
523
- var KIT_DEV_DEP_VERSION = "^1.0.26";
523
+ var KIT_DEV_DEP_VERSION = "^1.0.29";
524
524
  var MODULE_CONFIG_UI_DEPS = [
525
525
  "@dnd-kit/core",
526
526
  "@dnd-kit/sortable",
@@ -533,6 +533,16 @@ function templateDevDependencies() {
533
533
  };
534
534
  }
535
535
 
536
+ // src/lib/upload-only-module.ts
537
+ import { existsSync as existsSync4 } from "fs";
538
+ import { resolve as resolve5 } from "path";
539
+ function isUploadOnlyPreexistingProject(projectRoot, moduleArtifactDirs) {
540
+ if (moduleArtifactDirs.length === 0) return false;
541
+ if (existsSync4(resolve5(projectRoot, "package.json"))) return false;
542
+ if (existsSync4(resolve5(projectRoot, "src"))) return false;
543
+ return moduleArtifactDirs.some((dir) => existsSync4(resolve5(dir, "fields.json")));
544
+ }
545
+
536
546
  // src/cli/commands/doctor.ts
537
547
  function checkNode() {
538
548
  const major = Number(process.versions.node.split(".")[0]);
@@ -598,8 +608,8 @@ function checkConfig(ctx) {
598
608
  function checkEnvFiles(ctx) {
599
609
  return ctx.config.env.tiers.map((tier) => {
600
610
  const file = tier === "dev" ? ".env.dev" : tier === "stg" ? ".env.stg" : ".env.prod";
601
- const path = resolve5(ctx.projectRoot, file);
602
- const ok = existsSync4(path);
611
+ const path = resolve6(ctx.projectRoot, file);
612
+ const ok = existsSync5(path);
603
613
  return {
604
614
  name: `env-${tier}`,
605
615
  ok,
@@ -611,8 +621,8 @@ function checkEnvFiles(ctx) {
611
621
  }
612
622
  function checkBuildId(ctx) {
613
623
  if (isThemeProject(ctx.config) || !usesCdnPipeline(ctx.config)) return null;
614
- const file = resolve5(ctx.projectRoot, ctx.config.cdn.buildIdFile);
615
- const ok = existsSync4(file);
624
+ const file = resolve6(ctx.projectRoot, ctx.config.cdn.buildIdFile);
625
+ const ok = existsSync5(file);
616
626
  return {
617
627
  name: "build-id",
618
628
  ok,
@@ -621,9 +631,23 @@ function checkBuildId(ctx) {
621
631
  severity: "warn"
622
632
  };
623
633
  }
634
+ function isUploadOnlyProject(ctx) {
635
+ const moduleDirs = [resolve6(ctx.projectRoot, ctx.config.module.uploadPath)];
636
+ return isUploadOnlyPreexistingProject(ctx.projectRoot, moduleDirs);
637
+ }
638
+ function checkUploadOnlyNote(ctx) {
639
+ if (!isUploadOnlyProject(ctx)) return null;
640
+ return {
641
+ name: "upload-only-module",
642
+ ok: true,
643
+ message: "Upload-only module (no local dev app)",
644
+ remediation: "Add package.json + src/ via wp init in a new folder, or continue upload-only with wp upload",
645
+ severity: "warn"
646
+ };
647
+ }
624
648
  function checkDevViteConfig(ctx) {
625
- const path = resolve5(ctx.projectRoot, "vite.config.dev.mjs");
626
- const ok = existsSync4(path);
649
+ const path = resolve6(ctx.projectRoot, "vite.config.dev.mjs");
650
+ const ok = existsSync5(path);
627
651
  return {
628
652
  name: "vite-dev-config",
629
653
  ok,
@@ -634,8 +658,8 @@ function checkDevViteConfig(ctx) {
634
658
  }
635
659
  function checkDevEntry(ctx) {
636
660
  const checks = [];
637
- const indexHtml = resolve5(ctx.projectRoot, "index.html");
638
- const hasIndex = existsSync4(indexHtml);
661
+ const indexHtml = resolve6(ctx.projectRoot, "index.html");
662
+ const hasIndex = existsSync5(indexHtml);
639
663
  checks.push({
640
664
  name: "index-html",
641
665
  ok: hasIndex,
@@ -643,8 +667,8 @@ function checkDevEntry(ctx) {
643
667
  remediation: hasIndex ? void 0 : "Re-run wp init or copy index.html from kit templates",
644
668
  severity: "error"
645
669
  });
646
- const localDev = resolve5(ctx.projectRoot, ctx.config.entries.localDev);
647
- const hasEntry = existsSync4(localDev);
670
+ const localDev = resolve6(ctx.projectRoot, ctx.config.entries.localDev);
671
+ const hasEntry = existsSync5(localDev);
648
672
  checks.push({
649
673
  name: "local-dev-entry",
650
674
  ok: hasEntry,
@@ -671,7 +695,7 @@ function checkDevEntry(ctx) {
671
695
  }
672
696
  function checkKitScripts() {
673
697
  const script = kitPath("scripts", "build-cdn.mjs");
674
- const ok = existsSync4(script);
698
+ const ok = existsSync5(script);
675
699
  return {
676
700
  name: "kit-scripts",
677
701
  ok,
@@ -684,8 +708,8 @@ function checkWphsWorkspace(ctx) {
684
708
  const workspace = ctx.config.dev.moduleConfigDir;
685
709
  const checks = [];
686
710
  for (const legacy of [".dev", ".woodsportal"]) {
687
- const legacyPath = resolve5(ctx.projectRoot, legacy);
688
- if (existsSync4(legacyPath)) {
711
+ const legacyPath = resolve6(ctx.projectRoot, legacy);
712
+ if (existsSync5(legacyPath)) {
689
713
  checks.push({
690
714
  name: `legacy-${legacy}`,
691
715
  ok: false,
@@ -695,7 +719,7 @@ function checkWphsWorkspace(ctx) {
695
719
  });
696
720
  }
697
721
  }
698
- if (existsSync4(resolve5(ctx.projectRoot, ".wp-hs-baseline"))) {
722
+ if (existsSync5(resolve6(ctx.projectRoot, ".wp-hs-baseline"))) {
699
723
  checks.push({
700
724
  name: "legacy-baseline",
701
725
  ok: false,
@@ -714,10 +738,10 @@ function checkWphsWorkspace(ctx) {
714
738
  });
715
739
  return checks;
716
740
  }
717
- const wphsRoot = resolve5(ctx.projectRoot, workspace);
741
+ const wphsRoot = resolve6(ctx.projectRoot, workspace);
718
742
  const required = ["config", "assets/branding", "fixtures", "cache", "audit/baseline", "state"];
719
743
  for (const sub of required) {
720
- const ok = existsSync4(join(wphsRoot, sub));
744
+ const ok = existsSync5(join(wphsRoot, sub));
721
745
  checks.push({
722
746
  name: `wphs-${sub.replace(/\//g, "-")}`,
723
747
  ok,
@@ -730,20 +754,20 @@ function checkWphsWorkspace(ctx) {
730
754
  }
731
755
  function checkAdapter(ctx) {
732
756
  if (isThemeProject(ctx.config)) return null;
733
- const adapterPath = resolve5(ctx.projectRoot, ctx.config.dev.adapter);
734
- const ok = existsSync4(adapterPath);
757
+ const adapterPath = resolve6(ctx.projectRoot, ctx.config.dev.adapter);
758
+ const ok = existsSync5(adapterPath);
735
759
  return {
736
760
  name: "wphs-adapter",
737
761
  ok,
738
762
  message: ok ? `${ctx.config.dev.adapter} present` : `${ctx.config.dev.adapter} missing`,
739
- remediation: ok ? void 0 : "Run wp adopt or create wphs.adapter.ts",
763
+ remediation: ok ? void 0 : "Create wphs.adapter.ts (see kit templates)",
740
764
  severity: "warn"
741
765
  };
742
766
  }
743
767
  function checkModuleConfigUiDeps(ctx) {
744
768
  if (isThemeProject(ctx.config)) return [];
745
- const pkgPath = resolve5(ctx.projectRoot, "package.json");
746
- if (!existsSync4(pkgPath)) return [];
769
+ const pkgPath = resolve6(ctx.projectRoot, "package.json");
770
+ if (!existsSync5(pkgPath)) return [];
747
771
  let deps = {};
748
772
  try {
749
773
  const pkg = JSON.parse(readFileSync4(pkgPath, "utf8"));
@@ -763,11 +787,11 @@ function checkModuleConfigUiDeps(ctx) {
763
787
  });
764
788
  }
765
789
  function checkViteInstalled(ctx) {
766
- if (isThemeProject(ctx.config) && !existsSync4(resolve5(ctx.projectRoot, "vite.config.dev.mjs"))) {
790
+ if (isThemeProject(ctx.config) && !existsSync5(resolve6(ctx.projectRoot, "vite.config.dev.mjs"))) {
767
791
  return null;
768
792
  }
769
- const localBin = resolve5(ctx.projectRoot, "node_modules", ".bin", "vite");
770
- const ok = existsSync4(localBin);
793
+ const localBin = resolve6(ctx.projectRoot, "node_modules", ".bin", "vite");
794
+ const ok = existsSync5(localBin);
771
795
  return {
772
796
  name: "vite",
773
797
  ok,
@@ -796,10 +820,16 @@ async function gatherDoctorChecks(ctx) {
796
820
  {
797
821
  title: "Checking Node, Vite, and kit scripts",
798
822
  task: async () => {
799
- checks.push(checkNode(), checkKitScripts(), checkDevViteConfig(ctx), ...checkDevEntry(ctx));
800
- const viteCheck = checkViteInstalled(ctx);
801
- if (viteCheck) checks.push(viteCheck);
802
- checks.push(...checkModuleConfigUiDeps(ctx));
823
+ checks.push(checkNode(), checkKitScripts());
824
+ const uploadOnlyNote = checkUploadOnlyNote(ctx);
825
+ if (uploadOnlyNote) {
826
+ checks.push(uploadOnlyNote);
827
+ } else {
828
+ checks.push(checkDevViteConfig(ctx), ...checkDevEntry(ctx));
829
+ const viteCheck = checkViteInstalled(ctx);
830
+ if (viteCheck) checks.push(viteCheck);
831
+ checks.push(...checkModuleConfigUiDeps(ctx));
832
+ }
803
833
  }
804
834
  },
805
835
  {
@@ -900,7 +930,7 @@ async function runConfigValidate(ctx) {
900
930
  }
901
931
 
902
932
  // src/cli/commands/build.ts
903
- import { resolve as resolve6 } from "path";
933
+ import { resolve as resolve7 } from "path";
904
934
 
905
935
  // src/lib/build-tier.ts
906
936
  var DEFAULT_BUILD_TIER = "dev";
@@ -926,7 +956,7 @@ function buildTasks(ctx, options, run) {
926
956
  title: `Building monolith module (${tier})`,
927
957
  task: async () => {
928
958
  run("run-vite-build.mjs", [
929
- resolve6(ctx.projectRoot, "vite.config.monolith.mjs"),
959
+ resolve7(ctx.projectRoot, "vite.config.monolith.mjs"),
930
960
  ...tierToStgFlag(tier)
931
961
  ]);
932
962
  run("run-hubspot-module-postbuild.mjs");
@@ -940,7 +970,7 @@ function buildTasks(ctx, options, run) {
940
970
  task: async () => {
941
971
  if (options.cdnEsm) {
942
972
  run("run-vite-build.mjs", [
943
- resolve6(ctx.projectRoot, "vite.config.cdn-esm.mjs"),
973
+ resolve7(ctx.projectRoot, "vite.config.cdn-esm.mjs"),
944
974
  ...tierToStgFlag(tier)
945
975
  ]);
946
976
  } else {
@@ -955,7 +985,7 @@ function buildTasks(ctx, options, run) {
955
985
  title: `Building HubSpot module (${tier})`,
956
986
  task: async () => {
957
987
  run("run-vite-build.mjs", [
958
- resolve6(ctx.projectRoot, "vite.config.hubspot.mjs"),
988
+ resolve7(ctx.projectRoot, "vite.config.hubspot.mjs"),
959
989
  ...tierToStgFlag(tier)
960
990
  ]);
961
991
  run("run-hubspot-module-postbuild.mjs");
@@ -1011,7 +1041,7 @@ async function runBuild(ctx, options) {
1011
1041
  command: "build",
1012
1042
  tier,
1013
1043
  ok: true,
1014
- outDir: resolve6(ctx.projectRoot, ctx.config.module.outDir)
1044
+ outDir: resolve7(ctx.projectRoot, ctx.config.module.outDir)
1015
1045
  });
1016
1046
  } else {
1017
1047
  printCommandDone(ctx, "Build complete");
@@ -1025,8 +1055,8 @@ async function runBuild(ctx, options) {
1025
1055
  }
1026
1056
 
1027
1057
  // src/cli/commands/dev.ts
1028
- import { existsSync as existsSync6 } from "fs";
1029
- import { resolve as resolve9 } from "path";
1058
+ import { existsSync as existsSync7 } from "fs";
1059
+ import { resolve as resolve10 } from "path";
1030
1060
  import { spawn } from "child_process";
1031
1061
 
1032
1062
  // src/lib/cli-banner.ts
@@ -1034,14 +1064,14 @@ import pc3 from "picocolors";
1034
1064
 
1035
1065
  // src/lib/kit-version.ts
1036
1066
  import { readFileSync as readFileSync5 } from "fs";
1037
- import { resolve as resolve7 } from "path";
1067
+ import { resolve as resolve8 } from "path";
1038
1068
  var cachedVersion = null;
1039
1069
  function readKitVersion() {
1040
1070
  if (cachedVersion) {
1041
1071
  return cachedVersion;
1042
1072
  }
1043
1073
  try {
1044
- const pkg = JSON.parse(readFileSync5(resolve7(getKitRoot(), "package.json"), "utf8"));
1074
+ const pkg = JSON.parse(readFileSync5(resolve8(getKitRoot(), "package.json"), "utf8"));
1045
1075
  cachedVersion = pkg.version ?? "0.0.0";
1046
1076
  } catch {
1047
1077
  cachedVersion = "0.0.0";
@@ -1150,19 +1180,19 @@ ${tips}
1150
1180
  }
1151
1181
 
1152
1182
  // src/vite/resolve-dev-config.ts
1153
- import { existsSync as existsSync5 } from "fs";
1154
- import { resolve as resolve8 } from "path";
1183
+ import { existsSync as existsSync6 } from "fs";
1184
+ import { resolve as resolve9 } from "path";
1155
1185
  var CONSUMER_DEV_CONFIG = "vite.config.dev.mjs";
1156
1186
  function resolveDevViteConfigPath(projectRoot) {
1157
- const consumerConfig = resolve8(projectRoot, CONSUMER_DEV_CONFIG);
1158
- if (existsSync5(consumerConfig)) {
1187
+ const consumerConfig = resolve9(projectRoot, CONSUMER_DEV_CONFIG);
1188
+ if (existsSync6(consumerConfig)) {
1159
1189
  return consumerConfig;
1160
1190
  }
1161
1191
  return kitPath("vite", "vite.config.dev.mjs");
1162
1192
  }
1163
1193
  function resolveProjectViteBin(projectRoot) {
1164
- const localBin = resolve8(projectRoot, "node_modules", ".bin", "vite");
1165
- if (existsSync5(localBin)) {
1194
+ const localBin = resolve9(projectRoot, "node_modules", ".bin", "vite");
1195
+ if (existsSync6(localBin)) {
1166
1196
  return localBin;
1167
1197
  }
1168
1198
  return "vite";
@@ -1187,8 +1217,8 @@ async function runDev(ctx, options) {
1187
1217
  remediation: "Run yarn install or npm install. If this is an older wp init project, add vite and peers to devDependencies (run wp init again or see @woodsportal/hubspot-kit templates)."
1188
1218
  });
1189
1219
  }
1190
- const consumerConfig = resolve9(ctx.projectRoot, "vite.config.dev.mjs");
1191
- if (!existsSync6(consumerConfig)) {
1220
+ const consumerConfig = resolve10(ctx.projectRoot, "vite.config.dev.mjs");
1221
+ if (!existsSync7(consumerConfig)) {
1192
1222
  throw new WpHsError("vite.config.dev.mjs is missing in the project root.", {
1193
1223
  exitCode: ExitCode.USER_ERROR,
1194
1224
  remediation: "Add vite.config.dev.mjs (see @woodsportal/hubspot-kit templates/module-hybrid-cdn)."
@@ -1217,7 +1247,7 @@ async function runDev(ctx, options) {
1217
1247
  }
1218
1248
 
1219
1249
  // src/cli/commands/deploy.ts
1220
- import { resolve as resolve11 } from "path";
1250
+ import { resolve as resolve12 } from "path";
1221
1251
 
1222
1252
  // src/cli/commands/publish.ts
1223
1253
  async function runPublish(ctx, options) {
@@ -1275,14 +1305,14 @@ async function runPublish(ctx, options) {
1275
1305
  }
1276
1306
 
1277
1307
  // src/cli/commands/upload.ts
1278
- import { resolve as resolve10 } from "path";
1308
+ import { resolve as resolve11 } from "path";
1279
1309
  async function uploadModuleOrTheme(ctx) {
1280
1310
  if (isThemeProject(ctx.config)) {
1281
1311
  const theme = ctx.config.theme;
1282
1312
  if (!theme) {
1283
1313
  throw new WpHsError("theme block missing in woodscli.json", { exitCode: ExitCode.USER_ERROR });
1284
1314
  }
1285
- const srcDir = resolve10(ctx.projectRoot, theme.srcDir);
1315
+ const srcDir = resolve11(ctx.projectRoot, theme.srcDir);
1286
1316
  runCommand("hs", ["cms", "upload", srcDir, theme.uploadPath], {
1287
1317
  cwd: ctx.projectRoot,
1288
1318
  logger: ctx.logger,
@@ -1290,7 +1320,7 @@ async function uploadModuleOrTheme(ctx) {
1290
1320
  });
1291
1321
  return `Uploaded theme ${srcDir} \u2192 ${theme.uploadPath}`;
1292
1322
  }
1293
- const outDir = resolve10(ctx.projectRoot, ctx.config.module.outDir);
1323
+ const outDir = resolve11(ctx.projectRoot, ctx.config.module.outDir);
1294
1324
  const uploadPath = ctx.config.module.uploadPath;
1295
1325
  runCommand("hs", ["cms", "upload", outDir, uploadPath], {
1296
1326
  cwd: ctx.projectRoot,
@@ -1402,7 +1432,7 @@ async function runDeploy(ctx, options) {
1402
1432
  if (!ctx.global.json) {
1403
1433
  printCommandDone(
1404
1434
  ctx,
1405
- `Deploy complete (${resolve11(ctx.projectRoot, ctx.config.module.outDir)} \u2192 ${ctx.config.module.uploadPath})`
1435
+ `Deploy complete (${resolve12(ctx.projectRoot, ctx.config.module.outDir)} \u2192 ${ctx.config.module.uploadPath})`
1406
1436
  );
1407
1437
  }
1408
1438
  return ExitCode.SUCCESS;
@@ -1410,8 +1440,8 @@ async function runDeploy(ctx, options) {
1410
1440
 
1411
1441
  // src/cli/commands/audit.ts
1412
1442
  import { createHash } from "crypto";
1413
- import { cpSync, existsSync as existsSync7, mkdirSync, readFileSync as readFileSync6, readdirSync, rmSync, statSync } from "fs";
1414
- import { resolve as resolve12, join as join2 } from "path";
1443
+ import { cpSync, existsSync as existsSync8, mkdirSync, readFileSync as readFileSync6, readdirSync, rmSync, statSync } from "fs";
1444
+ import { resolve as resolve13, join as join2 } from "path";
1415
1445
  var FORBIDDEN_SHIP_TOKENS = [
1416
1446
  "ModuleConfigOverlay",
1417
1447
  "module-config-store",
@@ -1423,7 +1453,7 @@ function hashFile(path) {
1423
1453
  return createHash("sha256").update(readFileSync6(path)).digest("hex");
1424
1454
  }
1425
1455
  function walkFiles(dir) {
1426
- if (!existsSync7(dir)) return [];
1456
+ if (!existsSync8(dir)) return [];
1427
1457
  const entries = readdirSync(dir);
1428
1458
  const files = [];
1429
1459
  for (const entry of entries) {
@@ -1439,8 +1469,8 @@ function walkFiles(dir) {
1439
1469
  async function runAuditShipBundle(ctx) {
1440
1470
  const root = ctx.projectRoot;
1441
1471
  const targets = [
1442
- resolve12(root, "dist/cdn"),
1443
- resolve12(root, ctx.config.module.outDir)
1472
+ resolve13(root, "dist/cdn"),
1473
+ resolve13(root, ctx.config.module.outDir)
1444
1474
  ];
1445
1475
  const violations = [];
1446
1476
  for (const dir of targets) {
@@ -1473,21 +1503,21 @@ async function runAuditBaselineCapture(ctx, options) {
1473
1503
  const root = ctx.projectRoot;
1474
1504
  const baseline = options.baselineDir ?? defaultBaselineDir(root, ctx.config);
1475
1505
  const sources = [
1476
- { label: "cdn", path: resolve12(root, "dist/cdn") },
1477
- { label: "hubspot", path: resolve12(root, ctx.config.module.outDir) }
1506
+ { label: "cdn", path: resolve13(root, "dist/cdn") },
1507
+ { label: "hubspot", path: resolve13(root, ctx.config.module.outDir) }
1478
1508
  ];
1479
1509
  if (ctx.global.dryRun) {
1480
1510
  ctx.logger.info(`[dry-run] Would capture baseline to ${baseline}`);
1481
1511
  return ExitCode.SUCCESS;
1482
1512
  }
1483
1513
  for (const { label, path } of sources) {
1484
- if (!existsSync7(path)) {
1514
+ if (!existsSync8(path)) {
1485
1515
  throw new WpHsError(`Cannot capture baseline \u2014 missing ${path}`, {
1486
1516
  exitCode: ExitCode.USER_ERROR,
1487
1517
  remediation: "Run wp build before wp audit baseline --capture."
1488
1518
  });
1489
1519
  }
1490
- const target = resolve12(baseline, label);
1520
+ const target = resolve13(baseline, label);
1491
1521
  rmSync(target, { recursive: true, force: true });
1492
1522
  mkdirSync(baseline, { recursive: true });
1493
1523
  cpSync(path, target, { recursive: true });
@@ -1503,13 +1533,13 @@ async function runAuditParity(ctx, options) {
1503
1533
  const root = ctx.projectRoot;
1504
1534
  const baseline = options.baselineDir ?? defaultBaselineDir(root, ctx.config);
1505
1535
  const currentDirs = [
1506
- { label: "cdn", path: resolve12(root, "dist/cdn") },
1507
- { label: "hubspot", path: resolve12(root, ctx.config.module.outDir) }
1536
+ { label: "cdn", path: resolve13(root, "dist/cdn") },
1537
+ { label: "hubspot", path: resolve13(root, ctx.config.module.outDir) }
1508
1538
  ];
1509
1539
  const mismatches = [];
1510
1540
  for (const { label, path } of currentDirs) {
1511
- const baselinePath = resolve12(baseline, label);
1512
- if (!existsSync7(baselinePath)) {
1541
+ const baselinePath = resolve13(baseline, label);
1542
+ if (!existsSync8(baselinePath)) {
1513
1543
  ctx.logger.warn(`No baseline at ${baselinePath} \u2014 skipping ${label} parity`);
1514
1544
  continue;
1515
1545
  }
@@ -1524,8 +1554,8 @@ async function runAuditParity(ctx, options) {
1524
1554
  }
1525
1555
  for (const file of baselineFiles) {
1526
1556
  const rel = file.replace(baselinePath, "");
1527
- const current = resolve12(path, rel.slice(1));
1528
- if (!existsSync7(current)) continue;
1557
+ const current = resolve13(path, rel.slice(1));
1558
+ if (!existsSync8(current)) continue;
1529
1559
  const bh = hashFile(file);
1530
1560
  const ch = hashFile(current);
1531
1561
  if (bh !== ch) {
@@ -1552,7 +1582,7 @@ var SECRET_PATTERNS = [
1552
1582
  ];
1553
1583
  async function runAuditSecrets(ctx) {
1554
1584
  const root = ctx.projectRoot;
1555
- const scanRoots = ["src", "public", ".wphs/config"].map((d) => resolve12(root, d));
1585
+ const scanRoots = ["src", "public", ".wphs/config"].map((d) => resolve13(root, d));
1556
1586
  const findings = [];
1557
1587
  for (const dir of scanRoots) {
1558
1588
  for (const file of walkFiles(dir)) {
@@ -1584,13 +1614,13 @@ async function runAuditSecrets(ctx) {
1584
1614
  }
1585
1615
 
1586
1616
  // src/cli/commands/init.ts
1587
- import { cpSync as cpSync2, existsSync as existsSync10, mkdirSync as mkdirSync3, readdirSync as readdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync3 } from "fs";
1588
- import { basename as basename2, resolve as resolve15 } from "path";
1617
+ import { cpSync as cpSync2, existsSync as existsSync11, mkdirSync as mkdirSync3, readdirSync as readdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync3 } from "fs";
1618
+ import { basename as basename2, resolve as resolve16 } from "path";
1589
1619
  import * as p2 from "@clack/prompts";
1590
1620
 
1591
1621
  // src/lib/init-router-scaffold.ts
1592
- import { existsSync as existsSync8, mkdirSync as mkdirSync2, readFileSync as readFileSync7, rmSync as rmSync2, writeFileSync } from "fs";
1593
- import { resolve as resolve13 } from "path";
1622
+ import { existsSync as existsSync9, mkdirSync as mkdirSync2, readFileSync as readFileSync7, rmSync as rmSync2, writeFileSync } from "fs";
1623
+ import { resolve as resolve14 } from "path";
1594
1624
  var ROUTER_FILES = [
1595
1625
  "src/routes",
1596
1626
  "src/routeTree.gen.ts",
@@ -1604,10 +1634,10 @@ function isModuleTemplate(template) {
1604
1634
  return template === "module-hybrid-cdn" || template === "module-monolith";
1605
1635
  }
1606
1636
  function writeRouterConfig(targetDir, mode) {
1607
- const configDir = resolve13(targetDir, "src/config");
1637
+ const configDir = resolve14(targetDir, "src/config");
1608
1638
  mkdirSync2(configDir, { recursive: true });
1609
1639
  writeFileSync(
1610
- resolve13(configDir, "router.ts"),
1640
+ resolve14(configDir, "router.ts"),
1611
1641
  `/** Router history \u2014 set by \`wp init\`. Hash matches woodsportal-client-frontend (HubSpot CMS embeds). */
1612
1642
  export type RouterHistoryMode = 'hash' | 'browser'
1613
1643
 
@@ -1617,7 +1647,7 @@ export const ROUTER_HISTORY: RouterHistoryMode = '${mode}'
1617
1647
  }
1618
1648
  function writeMountDevPreviewRouter(targetDir) {
1619
1649
  writeFileSync(
1620
- resolve13(targetDir, "src/portal/mount-dev-preview.tsx"),
1650
+ resolve14(targetDir, "src/portal/mount-dev-preview.tsx"),
1621
1651
  `import { mountGreenfieldDev } from '../../.wphs/.kit-bootstrap-greenfield.tsx'
1622
1652
 
1623
1653
  import { App } from '@/app'
@@ -1631,7 +1661,7 @@ export async function mountDevPreview() {
1631
1661
  }
1632
1662
  function writeMountDevPreviewSinglePage(targetDir) {
1633
1663
  writeFileSync(
1634
- resolve13(targetDir, "src/portal/mount-dev-preview.tsx"),
1664
+ resolve14(targetDir, "src/portal/mount-dev-preview.tsx"),
1635
1665
  `import { mountGreenfieldDev } from '../../.wphs/.kit-bootstrap-greenfield.tsx'
1636
1666
 
1637
1667
  import { StarterSinglePage } from '@/features/starter'
@@ -1645,7 +1675,7 @@ export async function mountDevPreview() {
1645
1675
  }
1646
1676
  function writeMountPortalRouter(targetDir) {
1647
1677
  writeFileSync(
1648
- resolve13(targetDir, "src/portal/mount-portal.tsx"),
1678
+ resolve14(targetDir, "src/portal/mount-portal.tsx"),
1649
1679
  `import ReactDOM from 'react-dom/client'
1650
1680
 
1651
1681
  import { App } from '@/app'
@@ -1663,7 +1693,7 @@ export async function mountPortal() {
1663
1693
  }
1664
1694
  function writeMountPortalSinglePage(targetDir) {
1665
1695
  writeFileSync(
1666
- resolve13(targetDir, "src/portal/mount-portal.tsx"),
1696
+ resolve14(targetDir, "src/portal/mount-portal.tsx"),
1667
1697
  `import ReactDOM from 'react-dom/client'
1668
1698
 
1669
1699
  import { StarterSinglePage } from '@/features/starter'
@@ -1680,8 +1710,8 @@ export async function mountPortal() {
1680
1710
  );
1681
1711
  }
1682
1712
  function writeStarterSinglePage(targetDir) {
1683
- const file = resolve13(targetDir, "src/features/starter/components/starter-single-page.tsx");
1684
- if (existsSync8(file)) {
1713
+ const file = resolve14(targetDir, "src/features/starter/components/starter-single-page.tsx");
1714
+ if (existsSync9(file)) {
1685
1715
  return;
1686
1716
  }
1687
1717
  writeFileSync(
@@ -1707,15 +1737,15 @@ export function StarterSinglePage() {
1707
1737
  );
1708
1738
  }
1709
1739
  function removePath(targetDir, relativePath) {
1710
- const full = resolve13(targetDir, relativePath);
1711
- if (!existsSync8(full)) {
1740
+ const full = resolve14(targetDir, relativePath);
1741
+ if (!existsSync9(full)) {
1712
1742
  return;
1713
1743
  }
1714
1744
  rmSync2(full, { recursive: true, force: true });
1715
1745
  }
1716
1746
  function stripTanStackFromPackage(targetDir) {
1717
- const pkgPath = resolve13(targetDir, "package.json");
1718
- if (!existsSync8(pkgPath)) {
1747
+ const pkgPath = resolve14(targetDir, "package.json");
1748
+ if (!existsSync9(pkgPath)) {
1719
1749
  return;
1720
1750
  }
1721
1751
  const pkg = JSON.parse(readFileSync7(pkgPath, "utf8"));
@@ -1745,8 +1775,8 @@ function applyRouterScaffold(targetDir, mode, template) {
1745
1775
  writeRouterConfig(targetDir, mode);
1746
1776
  writeMountDevPreviewRouter(targetDir);
1747
1777
  writeMountPortalRouter(targetDir);
1748
- const featuresIndex = resolve13(targetDir, "src/features/starter/index.ts");
1749
- if (existsSync8(featuresIndex)) {
1778
+ const featuresIndex = resolve14(targetDir, "src/features/starter/index.ts");
1779
+ if (existsSync9(featuresIndex)) {
1750
1780
  let content = readFileSync7(featuresIndex, "utf8");
1751
1781
  if (!content.includes("StarterSinglePage")) {
1752
1782
  content = content.replace(
@@ -1759,8 +1789,8 @@ function applyRouterScaffold(targetDir, mode, template) {
1759
1789
  }
1760
1790
 
1761
1791
  // src/lib/project-setup.ts
1762
- import { copyFileSync, existsSync as existsSync9, writeFileSync as writeFileSync2 } from "fs";
1763
- import { basename, resolve as resolve14 } from "path";
1792
+ import { copyFileSync, existsSync as existsSync10, writeFileSync as writeFileSync2 } from "fs";
1793
+ import { basename, resolve as resolve15 } from "path";
1764
1794
  function envFileForTier(tier) {
1765
1795
  return tier === "dev" ? ".env.dev" : tier === "stg" ? ".env.stg" : ".env.prod";
1766
1796
  }
@@ -1770,13 +1800,13 @@ function tiersToSetup(config, tier) {
1770
1800
  }
1771
1801
  function firstExisting(paths) {
1772
1802
  for (const path of paths) {
1773
- if (existsSync9(path)) return path;
1803
+ if (existsSync10(path)) return path;
1774
1804
  }
1775
1805
  return null;
1776
1806
  }
1777
1807
  function copyMissingFile(projectRoot, targetName, sourceCandidates, dryRun) {
1778
- const target = resolve14(projectRoot, targetName);
1779
- if (existsSync9(target)) {
1808
+ const target = resolve15(projectRoot, targetName);
1809
+ if (existsSync10(target)) {
1780
1810
  return { action: "skipped", path: targetName, detail: "already present" };
1781
1811
  }
1782
1812
  const source = firstExisting(sourceCandidates);
@@ -1798,8 +1828,8 @@ function copyMissingFile(projectRoot, targetName, sourceCandidates, dryRun) {
1798
1828
  };
1799
1829
  }
1800
1830
  function writeMissingFile(projectRoot, targetName, content, dryRun) {
1801
- const target = resolve14(projectRoot, targetName);
1802
- if (existsSync9(target)) {
1831
+ const target = resolve15(projectRoot, targetName);
1832
+ if (existsSync10(target)) {
1803
1833
  return { action: "skipped", path: targetName, detail: "already present" };
1804
1834
  }
1805
1835
  if (!dryRun) {
@@ -1829,8 +1859,8 @@ function applyProjectSetup(ctx, options = {}) {
1829
1859
  const templateDir = kitTemplateDir(config);
1830
1860
  results.push(
1831
1861
  copyMissingFile(projectRoot, HUBSPOT_CONFIG_FILE, [
1832
- resolve14(projectRoot, HUBSPOT_CONFIG_EXAMPLE),
1833
- resolve14(templateDir, HUBSPOT_CONFIG_EXAMPLE),
1862
+ resolve15(projectRoot, HUBSPOT_CONFIG_EXAMPLE),
1863
+ resolve15(templateDir, HUBSPOT_CONFIG_EXAMPLE),
1834
1864
  kitPath("templates", HUBSPOT_CONFIG_EXAMPLE)
1835
1865
  ], dryRun)
1836
1866
  );
@@ -1839,8 +1869,8 @@ function applyProjectSetup(ctx, options = {}) {
1839
1869
  const envExample = `${envFile}.example`;
1840
1870
  results.push(
1841
1871
  copyMissingFile(projectRoot, envFile, [
1842
- resolve14(projectRoot, envExample),
1843
- resolve14(sharedDir, envExample)
1872
+ resolve15(projectRoot, envExample),
1873
+ resolve15(sharedDir, envExample)
1844
1874
  ], dryRun)
1845
1875
  );
1846
1876
  }
@@ -1848,8 +1878,8 @@ function applyProjectSetup(ctx, options = {}) {
1848
1878
  const mirror = config.cdn.mirror;
1849
1879
  results.push(
1850
1880
  copyMissingFile(projectRoot, mirror, [
1851
- resolve14(projectRoot, `${mirror}.example`),
1852
- resolve14(sharedDir, "portal.cdn.json.example")
1881
+ resolve15(projectRoot, `${mirror}.example`),
1882
+ resolve15(sharedDir, "portal.cdn.json.example")
1853
1883
  ], dryRun)
1854
1884
  );
1855
1885
  const buildIdFile = config.cdn.buildIdFile;
@@ -1859,15 +1889,15 @@ function applyProjectSetup(ctx, options = {}) {
1859
1889
  }
1860
1890
  for (const file of templateViteFiles(config)) {
1861
1891
  results.push(
1862
- copyMissingFile(projectRoot, file, [resolve14(templateDir, file)], dryRun)
1892
+ copyMissingFile(projectRoot, file, [resolve15(templateDir, file)], dryRun)
1863
1893
  );
1864
1894
  }
1865
1895
  if (isModuleProject(config) && !isThemeProject(config)) {
1866
1896
  const adapter = config.dev.adapter;
1867
- const adapterPath = resolve14(projectRoot, adapter);
1868
- if (!existsSync9(adapterPath)) {
1869
- const templateAdapter = resolve14(templateDir, "wphs.adapter.ts");
1870
- if (existsSync9(templateAdapter)) {
1897
+ const adapterPath = resolve15(projectRoot, adapter);
1898
+ if (!existsSync10(adapterPath)) {
1899
+ const templateAdapter = resolve15(templateDir, "wphs.adapter.ts");
1900
+ if (existsSync10(templateAdapter)) {
1871
1901
  results.push(copyMissingFile(projectRoot, adapter, [templateAdapter], dryRun));
1872
1902
  } else {
1873
1903
  results.push({
@@ -1884,26 +1914,26 @@ function applyProjectSetup(ctx, options = {}) {
1884
1914
  }
1885
1915
  function copySharedSetupExamples(targetDir) {
1886
1916
  const sharedDir = kitPath("templates", "shared");
1887
- if (!existsSync9(sharedDir)) return;
1917
+ if (!existsSync10(sharedDir)) return;
1888
1918
  for (const name of [
1889
1919
  ".env.dev.example",
1890
1920
  ".env.stg.example",
1891
1921
  ".env.prod.example",
1892
1922
  "portal.cdn.json.example"
1893
1923
  ]) {
1894
- const src = resolve14(sharedDir, name);
1895
- const dest = resolve14(targetDir, name);
1896
- if (existsSync9(src) && !existsSync9(dest)) {
1924
+ const src = resolve15(sharedDir, name);
1925
+ const dest = resolve15(targetDir, name);
1926
+ if (existsSync10(src) && !existsSync10(dest)) {
1897
1927
  copyFileSync(src, dest);
1898
1928
  }
1899
1929
  }
1900
1930
  const hubspotExample = firstExisting([
1901
- resolve14(sharedDir, HUBSPOT_CONFIG_EXAMPLE),
1931
+ resolve15(sharedDir, HUBSPOT_CONFIG_EXAMPLE),
1902
1932
  kitPath("templates", HUBSPOT_CONFIG_EXAMPLE)
1903
1933
  ]);
1904
1934
  if (!hubspotExample) return;
1905
- const destHubspot = resolve14(targetDir, HUBSPOT_CONFIG_EXAMPLE);
1906
- if (!existsSync9(destHubspot) && !existsSync9(resolve14(targetDir, HUBSPOT_CONFIG_FILE))) {
1935
+ const destHubspot = resolve15(targetDir, HUBSPOT_CONFIG_EXAMPLE);
1936
+ if (!existsSync10(destHubspot) && !existsSync10(resolve15(targetDir, HUBSPOT_CONFIG_FILE))) {
1907
1937
  copyFileSync(hubspotExample, destHubspot);
1908
1938
  }
1909
1939
  }
@@ -1919,25 +1949,7 @@ function formatSetupHint(results) {
1919
1949
  return void 0;
1920
1950
  }
1921
1951
 
1922
- // src/lib/project-name.ts
1923
- var PROJECT_NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
1924
- function normalizeProjectName(input) {
1925
- return input.trim().toLowerCase().replace(/[\s_]+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
1926
- }
1927
- function validateProjectName(name) {
1928
- if (!name) return "Project name is required";
1929
- if (!PROJECT_NAME_PATTERN.test(name)) {
1930
- return "Use lowercase letters, numbers, and hyphens (e.g. my-portal-module)";
1931
- }
1932
- if (name.length > 64) return "Project name is too long (max 64 characters)";
1933
- return void 0;
1934
- }
1935
- function moduleOutDirFromSlug(slug) {
1936
- const pascal = slug.split("-").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
1937
- return `dist/${pascal || "HubSpot"}.Module`;
1938
- }
1939
-
1940
- // src/cli/commands/init.ts
1952
+ // src/lib/template-scripts.ts
1941
1953
  var TEMPLATE_SCRIPTS = {
1942
1954
  "module-hybrid-cdn": {
1943
1955
  dev: "wp dev",
@@ -1964,6 +1976,26 @@ var TEMPLATE_SCRIPTS = {
1964
1976
  doctor: "wp doctor"
1965
1977
  }
1966
1978
  };
1979
+
1980
+ // src/lib/project-name.ts
1981
+ var PROJECT_NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
1982
+ function normalizeProjectName(input) {
1983
+ return input.trim().toLowerCase().replace(/[\s_]+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
1984
+ }
1985
+ function validateProjectName(name) {
1986
+ if (!name) return "Project name is required";
1987
+ if (!PROJECT_NAME_PATTERN.test(name)) {
1988
+ return "Use lowercase letters, numbers, and hyphens (e.g. my-portal-module)";
1989
+ }
1990
+ if (name.length > 64) return "Project name is too long (max 64 characters)";
1991
+ return void 0;
1992
+ }
1993
+ function moduleOutDirFromSlug(slug) {
1994
+ const pascal = slug.split("-").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
1995
+ return `dist/${pascal || "HubSpot"}.Module`;
1996
+ }
1997
+
1998
+ // src/cli/commands/init.ts
1967
1999
  function buildConfigForProject(template, projectName, router) {
1968
2000
  const base = { ...DEFAULT_WOODSPORTAL_HS, projectType: template };
1969
2001
  if (template === "theme-starter") {
@@ -1995,7 +2027,7 @@ function buildConfigForProject(template, projectName, router) {
1995
2027
  return config;
1996
2028
  }
1997
2029
  function assertTargetDirIsScaffoldable(targetDir) {
1998
- if (!existsSync10(targetDir)) return;
2030
+ if (!existsSync11(targetDir)) return;
1999
2031
  const entries = readdirSync2(targetDir).filter((entry) => entry !== ".DS_Store");
2000
2032
  if (entries.length > 0) {
2001
2033
  throw new WpHsError(`Target directory is not empty: ${targetDir}`, {
@@ -2006,7 +2038,7 @@ function assertTargetDirIsScaffoldable(targetDir) {
2006
2038
  }
2007
2039
  function resolveInitTargetDir(options, interactiveName) {
2008
2040
  if (options.directory) {
2009
- return resolve15(options.directory);
2041
+ return resolve16(options.directory);
2010
2042
  }
2011
2043
  const parentDir = process.cwd();
2012
2044
  const slug = options.name ?? interactiveName;
@@ -2020,7 +2052,7 @@ function resolveInitTargetDir(options, interactiveName) {
2020
2052
  if (error) {
2021
2053
  throw new WpHsError(error, { exitCode: ExitCode.USER_ERROR });
2022
2054
  }
2023
- return resolve15(parentDir, slug);
2055
+ return resolve16(parentDir, slug);
2024
2056
  }
2025
2057
  async function runInit(ctx, options) {
2026
2058
  const nonInteractive = ctx.global.ci || ctx.global.yes || ctx.global.json;
@@ -2093,7 +2125,7 @@ async function runInit(ctx, options) {
2093
2125
  const slug = projectName ?? basename2(targetDir);
2094
2126
  assertTargetDirIsScaffoldable(targetDir);
2095
2127
  const templateDir = kitPath("templates", template);
2096
- if (!existsSync10(templateDir)) {
2128
+ if (!existsSync11(templateDir)) {
2097
2129
  throw new WpHsError(`Template not found: ${template}`, { exitCode: ExitCode.USER_ERROR });
2098
2130
  }
2099
2131
  if (ctx.global.dryRun) {
@@ -2104,10 +2136,10 @@ async function runInit(ctx, options) {
2104
2136
  cpSync2(templateDir, targetDir, { recursive: true });
2105
2137
  copySharedSetupExamples(targetDir);
2106
2138
  const config = buildConfigForProject(template, slug, router);
2107
- writeFileSync3(resolve15(targetDir, WOODSCLI_CONFIG_FILE), `${JSON.stringify(config, null, 2)}
2139
+ writeFileSync3(resolve16(targetDir, WOODSCLI_CONFIG_FILE), `${JSON.stringify(config, null, 2)}
2108
2140
  `);
2109
- const pkgPath = resolve15(targetDir, "package.json");
2110
- if (existsSync10(pkgPath)) {
2141
+ const pkgPath = resolve16(targetDir, "package.json");
2142
+ if (existsSync11(pkgPath)) {
2111
2143
  const pkg = JSON.parse(readFileSync8(pkgPath, "utf8"));
2112
2144
  pkg.name = slug;
2113
2145
  pkg.scripts = { ...pkg.scripts, ...TEMPLATE_SCRIPTS[template] };
@@ -2126,7 +2158,7 @@ async function runInit(ctx, options) {
2126
2158
  logger: ctx.logger,
2127
2159
  dryRun: false
2128
2160
  });
2129
- const gitignorePath = resolve15(targetDir, ".gitignore");
2161
+ const gitignorePath = resolve16(targetDir, ".gitignore");
2130
2162
  const gitignoreExtras = [
2131
2163
  "hubspot.config.yml",
2132
2164
  ".wphs/config/module-config.local.json",
@@ -2139,7 +2171,7 @@ async function runInit(ctx, options) {
2139
2171
  ".wphs/.kit-bootstrap.tsx",
2140
2172
  ".wphs/.kit-bootstrap-greenfield.tsx"
2141
2173
  ];
2142
- const existing = existsSync10(gitignorePath) ? readFileSync8(gitignorePath, "utf8") : "";
2174
+ const existing = existsSync11(gitignorePath) ? readFileSync8(gitignorePath, "utf8") : "";
2143
2175
  const toAppend = gitignoreExtras.filter((line) => !existing.includes(line)).join("\n");
2144
2176
  if (toAppend) {
2145
2177
  writeFileSync3(gitignorePath, `${existing.trimEnd()}
@@ -2155,100 +2187,8 @@ ${toAppend}
2155
2187
  return ExitCode.SUCCESS;
2156
2188
  }
2157
2189
 
2158
- // src/cli/commands/adopt.ts
2159
- import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync4 } from "fs";
2160
- import { resolve as resolve16 } from "path";
2161
- import { pathToFileURL } from "url";
2162
- import * as p3 from "@clack/prompts";
2163
- async function loadDetectLayout() {
2164
- const mod = await import(pathToFileURL(kitPath("scripts", "detect-layout.mjs")).href);
2165
- return mod.detectProjectLayout;
2166
- }
2167
- async function runAdopt(ctx, _options = {}) {
2168
- const detectProjectLayout = await loadDetectLayout();
2169
- const layout = detectProjectLayout(ctx.projectRoot);
2170
- const configPath = resolve16(ctx.projectRoot, WOODSCLI_CONFIG_FILE);
2171
- if (layout.track === "unknown") {
2172
- throw new WpHsError("Could not detect module or theme layout.", {
2173
- exitCode: ExitCode.USER_ERROR,
2174
- remediation: "Ensure fields.json + module.html (module) or theme.json + templates/ (theme) exist."
2175
- });
2176
- }
2177
- let projectType;
2178
- if (layout.projectType) {
2179
- projectType = layout.projectType;
2180
- } else if (layout.track === "theme") {
2181
- projectType = "theme-starter";
2182
- } else if (existsSync11(resolve16(ctx.projectRoot, "vite.config.monolith.mjs"))) {
2183
- projectType = "module-monolith";
2184
- } else {
2185
- projectType = "module-hybrid-cdn";
2186
- }
2187
- const config = {
2188
- ...DEFAULT_WOODSPORTAL_HS,
2189
- projectType,
2190
- ...layout.track === "theme" ? {
2191
- theme: {
2192
- name: "my-theme",
2193
- uploadPath: "themes/my-theme",
2194
- srcDir: "src/theme",
2195
- themeJson: "src/theme/theme.json"
2196
- }
2197
- } : {}
2198
- };
2199
- if (ctx.global.dryRun) {
2200
- ctx.logger.info(`[dry-run] Would adopt as ${projectType} (${layout.track})`);
2201
- return ExitCode.SUCCESS;
2202
- }
2203
- if (!existsSync11(configPath)) {
2204
- writeFileSync4(configPath, `${JSON.stringify(config, null, 2)}
2205
- `);
2206
- ctx.logger.success(`Created ${WOODSCLI_CONFIG_FILE}`);
2207
- } else if (!layout.projectType) {
2208
- const existing = JSON.parse(readFileSync9(configPath, "utf8"));
2209
- writeFileSync4(configPath, `${JSON.stringify({ ...existing, projectType }, null, 2)}
2210
- `);
2211
- ctx.logger.info(`Set projectType \u2192 ${projectType}`);
2212
- }
2213
- runNodeScript(kitPath("scripts/ensure-wphs-workspace.mjs"), [], {
2214
- cwd: ctx.projectRoot,
2215
- logger: ctx.logger,
2216
- dryRun: false
2217
- });
2218
- const adapterPath = resolve16(ctx.projectRoot, "wphs.adapter.ts");
2219
- if (!existsSync11(adapterPath) && isModuleProject(config)) {
2220
- writeFileSync4(
2221
- adapterPath,
2222
- `import type { HubSpotKitAdapter } from '@woodsportal/hubspot-kit'
2223
-
2224
- const adapter: HubSpotKitAdapter = {
2225
- syncLiveData(built) {
2226
- ;(window as Window & { __WPHS_DATA__?: Record<string, unknown> }).__WPHS_DATA__ = built
2227
- },
2228
- }
2229
-
2230
- export default adapter
2231
- `
2232
- );
2233
- ctx.logger.info("Created wphs.adapter.ts stub");
2234
- }
2235
- if (!ctx.global.ci && !ctx.global.quiet) {
2236
- p3.note(
2237
- [
2238
- `Review ${WOODSCLI_CONFIG_FILE} upload paths`,
2239
- "Implement wphs.adapter.ts for your app (if module)",
2240
- "Run wp setup (copies hubspot.config.yml, .env.*, vite shims)",
2241
- "Patch main.dev.css @source to .wphs/.kit-module-config/**"
2242
- ].join("\n"),
2243
- "Manual follow-ups"
2244
- );
2245
- }
2246
- ctx.logger.success(`Adopted ${layout.track} project (${projectType})`);
2247
- return ExitCode.SUCCESS;
2248
- }
2249
-
2250
2190
  // src/cli/commands/migrate.ts
2251
- import { cpSync as cpSync3, existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync10, readdirSync as readdirSync3, renameSync, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "fs";
2191
+ import { cpSync as cpSync3, existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync9, readdirSync as readdirSync3, renameSync, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
2252
2192
  import { join as join3, resolve as resolve17 } from "path";
2253
2193
  var LEGACY_DIRS = [".dev", ".woodsportal"];
2254
2194
  var LEGACY_BASELINE = ".wp-hs-baseline";
@@ -2303,12 +2243,12 @@ async function runMigrate(ctx, _options = {}) {
2303
2243
  }
2304
2244
  }
2305
2245
  if (existsSync12(woodscliPath)) {
2306
- const raw = JSON.parse(readFileSync10(woodscliPath, "utf8"));
2246
+ const raw = JSON.parse(readFileSync9(woodscliPath, "utf8"));
2307
2247
  if (raw?.dev?.moduleConfigDir && raw.dev.moduleConfigDir !== WPHS_WORKSPACE_DIR) {
2308
2248
  actions.push(`Update dev.moduleConfigDir \u2192 .wphs in project config`);
2309
2249
  if (!ctx.global.dryRun) {
2310
2250
  raw.dev.moduleConfigDir = WPHS_WORKSPACE_DIR;
2311
- writeFileSync5(woodscliPath, `${JSON.stringify(raw, null, 2)}
2251
+ writeFileSync4(woodscliPath, `${JSON.stringify(raw, null, 2)}
2312
2252
  `);
2313
2253
  }
2314
2254
  }
@@ -2337,10 +2277,10 @@ async function runMigrate(ctx, _options = {}) {
2337
2277
  }
2338
2278
 
2339
2279
  // src/cli/commands/examples.ts
2340
- import { readFileSync as readFileSync11 } from "fs";
2280
+ import { readFileSync as readFileSync10 } from "fs";
2341
2281
  function loadManifest() {
2342
2282
  const manifestPath = kitPath("examples", "manifest.json");
2343
- const raw = JSON.parse(readFileSync11(manifestPath, "utf8"));
2283
+ const raw = JSON.parse(readFileSync10(manifestPath, "utf8"));
2344
2284
  return raw.scenarios;
2345
2285
  }
2346
2286
  async function runExamplesList(ctx, options = {}) {
@@ -2373,7 +2313,7 @@ async function runExamplesSmoke(ctx, options = {}) {
2373
2313
  }
2374
2314
 
2375
2315
  // src/cli/commands/fields.ts
2376
- import { cpSync as cpSync4, existsSync as existsSync13, readFileSync as readFileSync12, writeFileSync as writeFileSync6 } from "fs";
2316
+ import { cpSync as cpSync4, existsSync as existsSync13, readFileSync as readFileSync11, writeFileSync as writeFileSync5 } from "fs";
2377
2317
  import { resolve as resolve18 } from "path";
2378
2318
  async function runFieldsSync(ctx, options = {}) {
2379
2319
  const direction = options.direction ?? "pull";
@@ -2406,7 +2346,7 @@ async function runFieldsSync(ctx, options = {}) {
2406
2346
  ctx.logger.info(`[dry-run] Would write ${cachePath} \u2192 ${fieldsPath}`);
2407
2347
  return ExitCode.SUCCESS;
2408
2348
  }
2409
- writeFileSync6(fieldsPath, readFileSync12(cachePath, "utf8"));
2349
+ writeFileSync5(fieldsPath, readFileSync11(cachePath, "utf8"));
2410
2350
  ctx.logger.success(`Restored fields from cache \u2192 ${fieldsPath}`);
2411
2351
  return ExitCode.SUCCESS;
2412
2352
  }
@@ -2543,10 +2483,10 @@ async function runSetup(ctx, options = {}) {
2543
2483
  }
2544
2484
 
2545
2485
  // src/cli/commands/portal.ts
2546
- import * as p4 from "@clack/prompts";
2486
+ import * as p3 from "@clack/prompts";
2547
2487
 
2548
2488
  // src/lib/hubspot-portals.ts
2549
- import { existsSync as existsSync15, readFileSync as readFileSync13 } from "fs";
2489
+ import { existsSync as existsSync15, readFileSync as readFileSync12 } from "fs";
2550
2490
  import { resolve as resolve20 } from "path";
2551
2491
  function stripYamlScalar(value) {
2552
2492
  const trimmed = value.trim();
@@ -2592,13 +2532,13 @@ function readHubSpotPortals(projectRoot) {
2592
2532
  remediation: "Run wp setup, then add your portal + PAT."
2593
2533
  });
2594
2534
  }
2595
- const raw = readFileSync13(configPath, "utf8");
2535
+ const raw = readFileSync12(configPath, "utf8");
2596
2536
  const { defaultPortal, portals } = parseHubSpotConfigPortals(raw);
2597
2537
  return { configPath, defaultPortal, portals };
2598
2538
  }
2599
2539
  function resolvePortalName(portals, nameOrId) {
2600
2540
  const needle = nameOrId.trim();
2601
- return portals.find((p5) => p5.name === needle) ?? portals.find((p5) => p5.portalId === needle) ?? null;
2541
+ return portals.find((p4) => p4.name === needle) ?? portals.find((p4) => p4.portalId === needle) ?? null;
2602
2542
  }
2603
2543
 
2604
2544
  // src/cli/commands/portal.ts
@@ -2653,7 +2593,7 @@ async function runPortalUse(ctx, options = {}) {
2653
2593
  remediation: "wp portal use <name> \xB7 wp portal list"
2654
2594
  });
2655
2595
  }
2656
- const answer = await p4.select({
2596
+ const answer = await p3.select({
2657
2597
  message: "Set default HubSpot portal",
2658
2598
  options: data.portals.map((portal2) => ({
2659
2599
  value: portal2.name,
@@ -2661,7 +2601,7 @@ async function runPortalUse(ctx, options = {}) {
2661
2601
  hint: portal2.name === data.defaultPortal ? `current default \xB7 ${portal2.portalId ?? "no id"}` : portal2.portalId ?? void 0
2662
2602
  }))
2663
2603
  });
2664
- if (p4.isCancel(answer)) {
2604
+ if (p3.isCancel(answer)) {
2665
2605
  throw new WpHsError("Portal selection cancelled", { exitCode: ExitCode.USER_ERROR });
2666
2606
  }
2667
2607
  targetName = answer;
@@ -2722,7 +2662,7 @@ async function runWatch(ctx, options) {
2722
2662
  // src/cli/program.ts
2723
2663
  function readVersion() {
2724
2664
  try {
2725
- const pkg = JSON.parse(readFileSync14(resolve21(getKitRoot(), "package.json"), "utf8"));
2665
+ const pkg = JSON.parse(readFileSync13(resolve21(getKitRoot(), "package.json"), "utf8"));
2726
2666
  return pkg.version ?? "0.0.0";
2727
2667
  } catch {
2728
2668
  return "0.0.0";
@@ -2807,10 +2747,6 @@ function createProgram() {
2807
2747
  );
2808
2748
  }
2809
2749
  );
2810
- program2.command("adopt").description("Detect existing module/theme repo and add WoodsCLI config + .wphs/").action(async () => {
2811
- const global = program2.opts();
2812
- await handle(() => runAdopt(buildContext(global)));
2813
- });
2814
2750
  program2.command("migrate").description("Migrate legacy .dev/ or .wp-hs-baseline/ to .wphs/").action(async () => {
2815
2751
  const global = program2.opts();
2816
2752
  await handle(() => runMigrate(buildContext(global)));