businesslens 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/cli.js +17 -104
  3. package/dist/viewer/200.html +1 -1
  4. package/dist/viewer/404.html +1 -1
  5. package/dist/viewer/_nuxt/1AKcmNi5.js +2 -0
  6. package/dist/viewer/_nuxt/B-mP848s.js +1 -0
  7. package/dist/viewer/_nuxt/Bit4pBdc.js +1 -0
  8. package/dist/viewer/_nuxt/BlrFlowCanvas.DQt_5hA7.css +1 -0
  9. package/dist/viewer/_nuxt/BtQ-s_jB.js +2 -0
  10. package/dist/viewer/_nuxt/Dpgwz9sb.js +1 -0
  11. package/dist/viewer/_nuxt/builds/latest.json +1 -1
  12. package/dist/viewer/_nuxt/builds/meta/371c8694-5c47-4dea-84be-d8bb014327ac.json +1 -0
  13. package/dist/viewer/_nuxt/cSnpUPR8.js +1 -0
  14. package/dist/viewer/_nuxt/diagram.worker-DsHz2mkM.js +1 -0
  15. package/dist/viewer/_nuxt/entry.Cn2HYcjJ.css +1 -0
  16. package/dist/viewer/_nuxt/index.M4u1EpFn.css +1 -0
  17. package/dist/viewer/index.html +1 -1
  18. package/docs/business-rules.md +4 -4
  19. package/docs/capabilities.md +4 -4
  20. package/docs/ci.md +1 -1
  21. package/docs/cli-contribute.md +1 -1
  22. package/docs/cli-export.md +1 -1
  23. package/docs/cli-install.md +3 -2
  24. package/docs/cli-lint.md +1 -1
  25. package/docs/cli-open.md +1 -1
  26. package/docs/cli-pull.md +1 -1
  27. package/docs/cli-update.md +1 -1
  28. package/docs/cli-view.md +1 -1
  29. package/docs/cli.md +3 -1
  30. package/docs/domains.md +2 -2
  31. package/docs/entities.md +5 -5
  32. package/docs/integration.md +1 -1
  33. package/docs/interfaces.md +271 -12
  34. package/docs/journeys.md +4 -5
  35. package/docs/product-model.md +25 -22
  36. package/docs/references.md +2 -2
  37. package/docs/skill-businesslens-ideate.md +1 -1
  38. package/docs/skill-businesslens-map.md +1 -1
  39. package/docs/skill-businesslens-verify.md +1 -1
  40. package/docs/skills.md +1 -1
  41. package/docs/with-plan-mode.md +1 -1
  42. package/docs/with-sdd.md +1 -1
  43. package/layers/nuxt/report-viewer/README.md +76 -11
  44. package/layers/nuxt/report-viewer/THIRD_PARTY.md +19 -0
  45. package/layers/nuxt/report-viewer/app/assets/report-topology.css +97 -0
  46. package/layers/nuxt/report-viewer/app/assets/report-viewer.css +74 -0
  47. package/layers/nuxt/report-viewer/app/components/BlrConnections.vue +11 -162
  48. package/layers/nuxt/report-viewer/app/components/BlrDiagram.vue +152 -0
  49. package/layers/nuxt/report-viewer/app/components/BlrEntityLifecycle.vue +12 -14
  50. package/layers/nuxt/report-viewer/app/components/BlrExperienceContents.vue +20 -0
  51. package/layers/nuxt/report-viewer/app/components/BlrFilterBar.vue +73 -0
  52. package/layers/nuxt/report-viewer/app/components/BlrFlowCanvas.vue +115 -328
  53. package/layers/nuxt/report-viewer/app/components/BlrFlowNode.vue +8 -207
  54. package/layers/nuxt/report-viewer/app/components/BlrFlowNodeContent.vue +49 -0
  55. package/layers/nuxt/report-viewer/app/components/BlrFlowRoutedEdge.vue +12 -131
  56. package/layers/nuxt/report-viewer/app/components/BlrInterfaceDelivery.vue +23 -0
  57. package/layers/nuxt/report-viewer/app/components/BlrInterfaceType.vue +33 -3
  58. package/layers/nuxt/report-viewer/app/components/BlrKind.vue +10 -2
  59. package/layers/nuxt/report-viewer/app/components/BlrOverview.vue +192 -299
  60. package/layers/nuxt/report-viewer/app/components/BlrPageBlock.vue +13 -2
  61. package/layers/nuxt/report-viewer/app/components/BlrProductTopology.vue +174 -339
  62. package/layers/nuxt/report-viewer/app/components/BlrRail.vue +9 -51
  63. package/layers/nuxt/report-viewer/app/components/BlrReportShell.vue +357 -921
  64. package/layers/nuxt/report-viewer/app/components/BlrResourceBody.vue +13 -77
  65. package/layers/nuxt/report-viewer/app/components/BlrResourcePage.vue +22 -63
  66. package/layers/nuxt/report-viewer/app/components/BlrScenarios.vue +7 -2
  67. package/layers/nuxt/report-viewer/app/components/BlrTopologyBranch.vue +28 -0
  68. package/layers/nuxt/report-viewer/app/components/BlrTopologyComposition.vue +86 -0
  69. package/layers/nuxt/report-viewer/app/components/BlrTopologyMatrix.vue +72 -0
  70. package/layers/nuxt/report-viewer/app/components/BlrTopologyResource.vue +11 -0
  71. package/layers/nuxt/report-viewer/app/components/BlrTopologyTree.vue +56 -0
  72. package/layers/nuxt/report-viewer/app/components/BusinessLensReportViewer.vue +38 -5
  73. package/layers/nuxt/report-viewer/app/composables/useBlrReadingWidth.ts +11 -0
  74. package/layers/nuxt/report-viewer/app/composables/useBlrReportNavigation.ts +42 -0
  75. package/layers/nuxt/report-viewer/app/composables/useBlrTopologyScroll.ts +54 -0
  76. package/layers/nuxt/report-viewer/app/utils/diagram.ts +106 -0
  77. package/layers/nuxt/report-viewer/app/utils/diagram.worker.ts +3 -0
  78. package/layers/nuxt/report-viewer/app/utils/entityLifecycle.ts +28 -83
  79. package/layers/nuxt/report-viewer/app/utils/pageSections.ts +9 -40
  80. package/layers/nuxt/report-viewer/app/utils/productTopologyViews.ts +32 -109
  81. package/layers/nuxt/report-viewer/app/utils/reportDestinations.ts +41 -0
  82. package/layers/nuxt/report-viewer/app/utils/reportWorkspace.ts +28 -239
  83. package/layers/nuxt/report-viewer/app/utils/resourceCards.ts +9 -4
  84. package/layers/nuxt/report-viewer/app/utils/resourceConnections.ts +185 -0
  85. package/layers/nuxt/report-viewer/app/utils/resourceDocs.ts +3 -5
  86. package/layers/nuxt/report-viewer/app/utils/resourceFacets.ts +64 -16
  87. package/layers/nuxt/report-viewer/app/utils/topologyProjections.ts +221 -0
  88. package/layers/nuxt/report-viewer/app/utils/topologyRelations.ts +113 -0
  89. package/layers/nuxt/report-viewer/app/utils/topologyState.ts +73 -0
  90. package/layers/nuxt/report-viewer/app/utils/topologyTargets.ts +41 -0
  91. package/layers/nuxt/report-viewer/app/utils/topologyTree.ts +58 -0
  92. package/layers/nuxt/report-viewer/app/utils/vocabulary.generated.ts +5 -7
  93. package/layers/nuxt/report-viewer/licenses/ELK-EPL-2.0.md +263 -0
  94. package/layers/nuxt/report-viewer/licenses/diagram-design-MIT.txt +21 -0
  95. package/layers/nuxt/report-viewer/licenses/vue-flow-MIT.txt +20 -0
  96. package/layers/nuxt/report-viewer/nuxt.config.ts +17 -9
  97. package/layers/nuxt/theme/app/assets/theme.css +31 -0
  98. package/package.json +4 -12
  99. package/dist/viewer/_nuxt/CcApCzJy.js +0 -34
  100. package/dist/viewer/_nuxt/CeE3421Y.js +0 -1
  101. package/dist/viewer/_nuxt/CmwFmk8h.js +0 -37
  102. package/dist/viewer/_nuxt/DQ3ZnyMB.js +0 -1
  103. package/dist/viewer/_nuxt/builds/meta/3da08759-853a-4f1f-97f9-21437357aef0.json +0 -1
  104. package/dist/viewer/_nuxt/entry.DsWXLqBw.css +0 -1
  105. package/dist/viewer/_nuxt/index.BeuARo3I.css +0 -1
  106. package/dist/viewer/brand/icons/apple-touch-icon.png +0 -0
  107. package/dist/viewer/brand/icons/businesslens-app-icon.svg +0 -7
  108. package/dist/viewer/brand/icons/businesslens-maskable-icon.svg +0 -7
  109. package/dist/viewer/brand/icons/favicon-32.png +0 -0
  110. package/dist/viewer/brand/icons/favicon.ico +0 -0
  111. package/dist/viewer/brand/icons/favicon.svg +0 -7
  112. package/dist/viewer/brand/icons/icon-1024.png +0 -0
  113. package/dist/viewer/brand/icons/icon-192.png +0 -0
  114. package/dist/viewer/brand/icons/icon-512.png +0 -0
  115. package/dist/viewer/brand/icons/maskable-icon-512.png +0 -0
  116. package/dist/viewer/brand/logo/mark-dark.svg +0 -4
  117. package/dist/viewer/brand/logo/mark.svg +0 -4
  118. package/dist/viewer/brand/logo/wordmark-dark.svg +0 -173
  119. package/dist/viewer/brand/logo/wordmark.svg +0 -173
  120. package/docs/experiences.md +0 -106
  121. package/docs/screens.md +0 -171
  122. package/layers/nuxt/report-viewer/app/components/BlrFlowGroup.vue +0 -126
  123. package/layers/nuxt/report-viewer/app/components/BlrFlowLabel.vue +0 -47
  124. package/layers/nuxt/report-viewer/app/components/BlrFlowSelfEdge.vue +0 -105
  125. package/layers/nuxt/report-viewer/app/components/BlrFlowState.vue +0 -112
  126. package/layers/nuxt/report-viewer/app/utils/flowGraph.ts +0 -824
  127. package/layers/nuxt/report-viewer/app/utils/productTopologyFilters.ts +0 -92
  128. package/layers/nuxt/report-viewer/app/utils/productTopologyGraphs.ts +0 -614
  129. package/layers/nuxt/report-viewer/app/utils/productTopologyLayout.ts +0 -124
package/CHANGELOG.md CHANGED
@@ -7,6 +7,42 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.13.0] - 2026-09-12
11
+
12
+ ### Removed
13
+
14
+ - Hidden historical CLI options and command migration messages. Use the commands
15
+ and options shown in help, including `--cwd` and `--scope project|global`.
16
+ - One-off cleanup of old bare-name skills and Claude commands during installation.
17
+
18
+ ## [0.12.0] - 2026-09-10
19
+
20
+ ### Changed
21
+
22
+ - Every page of the report reads the same way: what it is and the ways out of
23
+ it, then tabs for which set you are reading, then what narrows it.
24
+ - Tabs are the report's only switch. Each named reading sits beside List in the
25
+ collection it belongs to; the Cards/Table toggle and the grouping menu are
26
+ gone.
27
+ - Filters sit beside the rows they narrow, one control per axis, on every
28
+ collection whatever its size.
29
+ - Collections group by Domain on their own, and Entities that act lead the list.
30
+ - Overview is the Product's own page, with About, Coverage and References.
31
+ - Compare delivery is now a Capability by Interface matrix.
32
+ - The documentation explains the Product Model. The report explains itself.
33
+ - Report links shared before this release open the Overview.
34
+
35
+ ### Removed
36
+
37
+ - The All resources and connections view. The rail already lists every
38
+ collection with its count, and a resource's connections are on its page.
39
+
40
+ ### Fixed
41
+
42
+ - Icons missing from the local report, including the loading indicator and the
43
+ warning shown while an edit is invalid.
44
+ - Interactive controls now show the hand cursor.
45
+
10
46
  ## [0.11.0] - 2026-09-07
11
47
 
12
48
  ### Fixed
@@ -719,6 +755,7 @@ Initial public launch of the repository.
719
755
  `docs/format.md`.
720
756
  - Claude plugin manifest and marketplace entry.
721
757
 
758
+ [0.12.0]: https://github.com/businesslens/pdd/compare/v0.11.0...v0.12.0
722
759
  [0.11.0]: https://github.com/businesslens/pdd/compare/v0.10.0...v0.11.0
723
760
  [0.10.0]: https://github.com/businesslens/pdd/compare/v0.9.0...v0.10.0
724
761
  [0.9.0]: https://github.com/businesslens/pdd/compare/v0.8.0...v0.9.0
package/dist/cli.js CHANGED
@@ -2,8 +2,9 @@
2
2
  import { INTERFACE_TYPES, ProductReportV13Schema, REPORT_SCHEMA_VERSION, bulletList, containsPlace, containsStructuralHeading, decisionPoints, interfaceOf, isId, isQualifiedId, operationPlaces, parseCodeTarget, parseMarkdown, parseProductReport, permissionTargetSelectsOperation, projectPortableReport, qualify, screenStates, section, supportingSections, validateBlueprintReport, validatePermissionBehavior, validateProductReport } from "./portable-DmgFo37G.js";
3
3
  import { MAX_PRODUCT_LOGO_BYTES, PRODUCT_LOGO_FILENAME, validateProductLogo } from "./logo-ByUBSRUb.js";
4
4
  import { reportDigest } from "./report-digest-BtjFf-4A.js";
5
+ import { createRequire } from "node:module";
5
6
  import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
6
- import { Command, CommanderError, Help, InvalidArgumentError, Option } from "commander";
7
+ import { Command, CommanderError, Help, InvalidArgumentError } from "commander";
7
8
  import { execFileSync, spawn, spawnSync } from "node:child_process";
8
9
  import { closeSync, constants, cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, rmdirSync, watch, writeFileSync } from "node:fs";
9
10
  import { createInterface } from "node:readline/promises";
@@ -3886,25 +3887,6 @@ const BUSINESSLENS_SKILLS = [
3886
3887
  "businesslens-verify"
3887
3888
  ];
3888
3889
  const MANIFEST_FILE = ".businesslens-install.json";
3889
- const LEGACY_SKILLS = [
3890
- "businesslens-init",
3891
- "businesslens-sync",
3892
- "businesslens-deep-dive",
3893
- "businesslens-doctor",
3894
- "businesslens-contribute",
3895
- "businesslens-implement",
3896
- "businesslens-validate",
3897
- "businesslens-plan",
3898
- "businesslens-publish",
3899
- "map",
3900
- "sync",
3901
- "deep-dive",
3902
- "publish",
3903
- "analyze-repo",
3904
- "validate-report",
3905
- "submit-report",
3906
- "push-report"
3907
- ];
3908
3890
  function bundledSkillsDir() {
3909
3891
  const here = dirname(fileURLToPath(import.meta.url));
3910
3892
  for (const candidate of [
@@ -3918,9 +3900,6 @@ const SKILL_DIRECTORY_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
3918
3900
  function isSkillDirectoryName(name) {
3919
3901
  return typeof name === "string" && SKILL_DIRECTORY_NAME.test(name);
3920
3902
  }
3921
- function isBusinessLensSkillName(name) {
3922
- return name.startsWith("businesslens-") || LEGACY_SKILLS.includes(name);
3923
- }
3924
3903
  function ownedChildPath(skillsDir, name) {
3925
3904
  if (!isSkillDirectoryName(name)) return void 0;
3926
3905
  const target = resolve(skillsDir, name);
@@ -3956,36 +3935,6 @@ function assertInstallTargets(cwd, targets, options = {}) {
3956
3935
  assertSafeTargets(skillsDir, readManifest(skillsDir), Boolean(options.force));
3957
3936
  }
3958
3937
  }
3959
- function removeLegacySkills(skillsDir, existing) {
3960
- const removed = [];
3961
- for (const name of LEGACY_SKILLS) {
3962
- const target = ownedChildPath(skillsDir, name);
3963
- if (target === void 0) continue;
3964
- if (!existsSync(target) || !existing?.skills.includes(name)) continue;
3965
- rmSync(target, {
3966
- recursive: true,
3967
- force: true
3968
- });
3969
- removed.push(name);
3970
- }
3971
- return removed;
3972
- }
3973
- function removeLegacyCommands(cwd, target) {
3974
- if (target.scope !== "project" || target.provider.id !== "claude") return [];
3975
- const project = resolve(cwd);
3976
- const commandFile = join(project, ".claude", "commands", "businesslens", "init.md");
3977
- if (!existsSync(commandFile)) return [];
3978
- try {
3979
- const source = readFileSync(commandFile, "utf8");
3980
- if (!source.includes("BusinessLens") && !source.includes(".businesslens/")) return [];
3981
- } catch {
3982
- return [];
3983
- }
3984
- rmSync(commandFile, { force: true });
3985
- const commandDirectory = dirname(commandFile);
3986
- if (readdirSync(commandDirectory).length === 0) rmSync(commandDirectory, { recursive: true });
3987
- return [relative(project, commandFile)];
3988
- }
3989
3938
  function writeManifest(skillsDir, manifest) {
3990
3939
  const file = join(skillsDir, MANIFEST_FILE);
3991
3940
  const temporary = `${file}.${randomUUID()}.tmp`;
@@ -4025,14 +3974,12 @@ function installSkillsToTarget(cwd, target, version, options = {}) {
4025
3974
  mkdirSync(skillsDir, { recursive: true });
4026
3975
  const existing = readManifest(skillsDir);
4027
3976
  assertSafeTargets(skillsDir, existing, Boolean(options.force));
4028
- const staleSkills = (existing?.skills ?? []).filter((previous) => !BUSINESSLENS_SKILLS.includes(previous)).filter(isBusinessLensSkillName).map((previous) => ownedChildPath(skillsDir, previous)).filter((stale) => stale !== void 0 && existsSync(stale));
3977
+ const staleSkills = (existing?.skills ?? []).filter((previous) => !BUSINESSLENS_SKILLS.includes(previous)).filter((name) => name.startsWith("businesslens-")).map((previous) => ownedChildPath(skillsDir, previous)).filter((stale) => stale !== void 0 && existsSync(stale));
4029
3978
  for (const name of BUSINESSLENS_SKILLS) installSkill(sourceRoot, skillsDir, name);
4030
- const removedLegacySkills = removeLegacySkills(skillsDir, existing);
4031
3979
  for (const stale of staleSkills) if (existsSync(stale)) rmSync(stale, {
4032
3980
  recursive: true,
4033
3981
  force: true
4034
3982
  });
4035
- const removedLegacyCommands = removeLegacyCommands(cwd, target);
4036
3983
  const now = (/* @__PURE__ */ new Date()).toISOString();
4037
3984
  writeManifest(skillsDir, {
4038
3985
  schema: 1,
@@ -4046,9 +3993,7 @@ function installSkillsToTarget(cwd, target, version, options = {}) {
4046
3993
  });
4047
3994
  return {
4048
3995
  ...target,
4049
- skillsDir,
4050
- removedLegacySkills,
4051
- removedLegacyCommands
3996
+ skillsDir
4052
3997
  };
4053
3998
  }
4054
3999
  function findManagedInstallations(cwd, providers, scopes, home) {
@@ -4075,14 +4020,9 @@ function canPrompt(options) {
4075
4020
  return !options.yes && Boolean(process.stdin.isTTY && process.stdout.isTTY);
4076
4021
  }
4077
4022
  function resolveScope(options) {
4078
- const aliases = [options.project ? "project" : void 0, options.global || options.user ? "global" : void 0].filter(Boolean);
4079
- if (aliases.length > 1) throw new UsageError("Choose only one of --project, --global, or --user.");
4080
- const explicit = options.scope?.trim().toLowerCase();
4081
- if (explicit && explicit !== "project" && explicit !== "global" && explicit !== "user") throw new UsageError("--scope must be project or global.");
4082
- const normalized = explicit === "user" ? "global" : explicit;
4083
- const alias = aliases[0];
4084
- if (normalized && alias && normalized !== alias) throw new UsageError("--scope conflicts with the selected scope flag.");
4085
- return normalized || alias;
4023
+ const scope$1 = options.scope?.trim().toLowerCase();
4024
+ if (scope$1 && scope$1 !== "project" && scope$1 !== "global") throw new UsageError("--scope must be project or global.");
4025
+ return scope$1;
4086
4026
  }
4087
4027
  function printDetected(cwd) {
4088
4028
  const detected = detectProviders(cwd);
@@ -4185,10 +4125,6 @@ async function runInstall(cwd, options = {}) {
4185
4125
  const roots = results.map((result) => formatDisplayPath(dirname(result.skillsDir)));
4186
4126
  console.log(`Installed BusinessLens into: ${roots.join(", ")} (${scope$1}).`);
4187
4127
  console.log(`Installed skills: ${BUSINESSLENS_SKILLS.join(", ")}.`);
4188
- const removed = results.flatMap((result) => result.removedLegacySkills);
4189
- if (removed.length > 0) console.log(`Removed retired BusinessLens skills: ${[...new Set(removed)].join(", ")}.`);
4190
- const removedCommands = results.flatMap((result) => result.removedLegacyCommands);
4191
- if (removedCommands.length > 0) console.log(`Removed retired BusinessLens commands: ${[...new Set(removedCommands)].join(", ")}.`);
4192
4128
  return 0;
4193
4129
  } catch (error) {
4194
4130
  console.error(error.message);
@@ -4387,15 +4323,9 @@ async function runPull(cwd, name, options, dependencies = {}) {
4387
4323
  //#endregion
4388
4324
  //#region src/commands/update.ts
4389
4325
  function resolveScopes(options) {
4390
- const aliases = [options.project ? "project" : void 0, options.global || options.user ? "global" : void 0].filter(Boolean);
4391
- if (aliases.length > 1) throw new UsageError("Choose only one of --project, --global, or --user.");
4392
- if (!options.scope && aliases.length === 0) return ["project", "global"];
4393
- const normalized = options.scope?.trim().toLowerCase();
4394
- if (normalized && normalized !== "project" && normalized !== "global" && normalized !== "user") throw new UsageError("--scope must be project or global.");
4395
- const scope$1 = normalized === "user" ? "global" : normalized;
4396
- if (scope$1 && aliases[0] && scope$1 !== aliases[0]) throw new UsageError("--scope conflicts with the selected scope flag.");
4397
- if ((scope$1 || aliases[0]) === "project") return ["project"];
4398
- if ((scope$1 || aliases[0]) === "global") return ["global"];
4326
+ const scope$1 = options.scope?.trim().toLowerCase();
4327
+ if (!scope$1) return ["project", "global"];
4328
+ if (scope$1 === "project" || scope$1 === "global") return [scope$1];
4399
4329
  throw new UsageError("--scope must be project or global.");
4400
4330
  }
4401
4331
  async function runUpdate(cwd, options = {}) {
@@ -4431,6 +4361,7 @@ const HEALTH_PATH = "/_businesslens/health";
4431
4361
  const LOGO_PATH = "/_businesslens/logo.svg";
4432
4362
  const ASSET_PREFIX = "/_businesslens/file/";
4433
4363
  const VIEWER_ROOT = fileURLToPath(new URL("./viewer/", import.meta.url));
4364
+ const BRAND_ROOT = resolve(createRequire(import.meta.url).resolve("businesslens/package.json"), "../layers/nuxt/theme/public/brand");
4434
4365
  /** 25 MB. A product asset is a mockup or a capture, never a build output. */
4435
4366
  const MAX_ASSET_BYTES = 25 * 1024 * 1024;
4436
4367
  const CONTENT_TYPES = {
@@ -4730,7 +4661,7 @@ function requestHandler(options, store, streams, port$1) {
4730
4661
  });
4731
4662
  return;
4732
4663
  }
4733
- const file = staticFile(viewerRoot, pathname);
4664
+ const file = staticFile(viewerRoot, pathname) ?? (pathname.startsWith("/brand/") ? staticFile(BRAND_ROOT, pathname.slice(7)) : void 0);
4734
4665
  if (!file) {
4735
4666
  json(response, 404, { message: "Not found." }, head);
4736
4667
  return;
@@ -4842,8 +4773,8 @@ async function runView(cwd, options) {
4842
4773
  //#endregion
4843
4774
  //#region src/cli.ts
4844
4775
  function cwdFor(command) {
4845
- const { cwd, C: legacyCwd } = command.optsWithGlobals();
4846
- return resolve(process.cwd(), cwd || legacyCwd || ".");
4776
+ const { cwd } = command.optsWithGlobals();
4777
+ return resolve(process.cwd(), cwd || ".");
4847
4778
  }
4848
4779
  function scope(value) {
4849
4780
  const normalized = value.trim().toLowerCase();
@@ -4856,14 +4787,6 @@ function port(value) {
4856
4787
  if (parsed < 1 || parsed > 65535) throw new InvalidArgumentError("expected an integer from 1 to 65535");
4857
4788
  return parsed;
4858
4789
  }
4859
- function legacyScopeOptions(command) {
4860
- return command.addOption(new Option("--project").hideHelp()).addOption(new Option("--global").hideHelp()).addOption(new Option("--user").hideHelp());
4861
- }
4862
- function retiredCommand(program, name, replacement) {
4863
- program.command(`${name} [arguments...]`, { hidden: true }).allowUnknownOption(true).description(`Use businesslens ${replacement}`).action((_arguments, _options, command) => {
4864
- command.error(`error: \`businesslens ${name}\` has moved. Use \`businesslens ${replacement}\`.`);
4865
- });
4866
- }
4867
4790
  function commandsBeforeOptions(output) {
4868
4791
  const trailingNewline = output.endsWith("\n") ? "\n" : "";
4869
4792
  const sections = output.trimEnd().split(/\n{2,}/);
@@ -4875,17 +4798,17 @@ function commandsBeforeOptions(output) {
4875
4798
  return sections.join("\n\n") + trailingNewline;
4876
4799
  }
4877
4800
  function createProgram(setExitCode) {
4878
- const program = new Command().name("businesslens").description("Product-Driven Development for coding agents").usage("<command> [options]").option("-c, --cwd <path>", "Run from another directory").addOption(new Option("-C <path>").hideHelp().conflicts("cwd")).version(cliVersion(), "-V, --version", "Show the CLI version").helpOption("-h, --help", "Show help for command").helpCommand("help [command]", "Show help for command").showSuggestionAfterError().configureHelp({
4801
+ const program = new Command().name("businesslens").description("Product-Driven Development for coding agents").usage("<command> [options]").option("-c, --cwd <path>", "Run from another directory").version(cliVersion(), "-V, --version", "Show the CLI version").helpOption("-h, --help", "Show help for command").helpCommand("help [command]", "Show help for command").showSuggestionAfterError().configureHelp({
4879
4802
  showGlobalOptions: true,
4880
4803
  formatHelp(command, helper) {
4881
4804
  const output = Help.prototype.formatHelp.call(helper, command, helper);
4882
4805
  return command.parent ? output : commandsBeforeOptions(output);
4883
4806
  }
4884
4807
  }).exitOverride();
4885
- legacyScopeOptions(program.command("install").summary("Install BusinessLens skills").description("Install BusinessLens skills for detected AI harnesses.").option("--providers <list>", "Comma-separated providers: claude,codex,cursor,gemini,github").option("--scope <scope>", "Installation scope: project or global", scope).option("--yes", "Accept detected providers and default to project scope").option("--force", "Replace an unmarked colliding BusinessLens skill directory")).action(async (options, command) => {
4808
+ program.command("install").summary("Install BusinessLens skills").description("Install BusinessLens skills for detected AI harnesses.").option("--providers <list>", "Comma-separated providers: claude,codex,cursor,gemini,github").option("--scope <scope>", "Installation scope: project or global", scope).option("--yes", "Accept detected providers and default to project scope").option("--force", "Replace an unmarked colliding BusinessLens skill directory").action(async (options, command) => {
4886
4809
  setExitCode(await runInstall(cwdFor(command), options));
4887
4810
  });
4888
- legacyScopeOptions(program.command("update").summary("Update managed skill installations").description("Update BusinessLens-managed skill installations.").option("--providers <list>", "Limit discovery to: claude,codex,cursor,gemini,github").option("--scope <scope>", "Installation scope: project or global", scope).option("--force", "Replace an unmarked collision inside a managed installation")).action(async (options, command) => {
4811
+ program.command("update").summary("Update managed skill installations").description("Update BusinessLens-managed skill installations.").option("--providers <list>", "Limit discovery to: claude,codex,cursor,gemini,github").option("--scope <scope>", "Installation scope: project or global", scope).option("--force", "Replace an unmarked collision inside a managed installation").action(async (options, command) => {
4889
4812
  setExitCode(await runUpdate(cwdFor(command), options));
4890
4813
  });
4891
4814
  program.command("lint").summary("Lint a Product Model").description("Lint the current .businesslens/ Product Model.").option("--json", "Write the lint result as JSON").action((options, command) => {
@@ -4913,16 +4836,6 @@ function createProgram(setExitCode) {
4913
4836
  blueprint.command("contribute").summary("Contribute a Blueprint").description("Propose the current Product Model for the Blueprint catalog.").option("--yes", "Skip the confirmation prompt").action(async (options, command) => {
4914
4837
  setExitCode(await runContribute(cwdFor(command), { yes: Boolean(options.yes) }));
4915
4838
  });
4916
- for (const name of [
4917
- "export",
4918
- "open",
4919
- "pull",
4920
- "contribute"
4921
- ]) retiredCommand(program, name, `blueprint ${name}`);
4922
- retiredCommand(program, "build", "blueprint export");
4923
- program.command("validate [arguments...]", { hidden: true }).allowUnknownOption(true).action((_arguments, _options, command) => {
4924
- command.error("error: `businesslens validate` has been renamed. Use `businesslens lint`.");
4925
- });
4926
4839
  return program;
4927
4840
  }
4928
4841
  async function main(argv = process.argv) {
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/_nuxt/entry.DsWXLqBw.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CmwFmk8h.js"><script type="module" src="/_nuxt/CmwFmk8h.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-500.BwxPsW7a.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/DQ3ZnyMB.js"><script>"use strict";(()=>{const o=window,e=document.documentElement,c=["dark","light"],s=getStorageValue("localStorage","nuxt-color-mode")||"light";let r=s==="system"?f():s;const l=e.getAttribute("data-color-mode-forced");l&&(r=l),i(r),o["__NUXT_COLOR_MODE__"]={preference:s,value:r,getColorScheme:f,addColorScheme:i,removeColorScheme:d};function i(t){const a=""+t+"",n="";e.classList?e.classList.add(a):e.className+=" "+a,n&&e.setAttribute("data-"+n,t)}function d(t){const a=""+t+"",n="";e.classList?e.classList.remove(a):e.className=e.className.replace(new RegExp(a,"g"),""),n&&e.removeAttribute("data-"+n)}function u(t){return o.matchMedia("(prefers-color-scheme"+t+")")}function f(){if(o.matchMedia&&u("").media!=="not all"){for(const t of c)if(u(":"+t).matches)return t}return"light"}})();function getStorageValue(o,e){switch(o){case"localStorage":try{return window.localStorage.getItem(e)}catch{return null}case"sessionStorage":try{return window.sessionStorage.getItem(e)}catch{return null}case"cookie":try{return getCookie(e)}catch{return null}default:return null}}function getCookie(o){const c=("; "+window.document.cookie).split("; "+o+"=");if(c.length===2){const s=c.pop();return s?s.split(";").shift():null}}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{pddVersion:"0.11.0"},app:{baseURL:"/",buildId:"3da08759-853a-4f1f-97f9-21437357aef0",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1788770970157,false]</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/_nuxt/entry.Cn2HYcjJ.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/_nuxt/BtQ-s_jB.js"><script type="module" src="/_nuxt/BtQ-s_jB.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-404.VJcZ3YVw.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/cSnpUPR8.js"><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-500.BwxPsW7a.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/B-mP848s.js"><script>"use strict";(()=>{const o=window,e=document.documentElement,c=["dark","light"],s=getStorageValue("localStorage","nuxt-color-mode")||"light";let r=s==="system"?f():s;const l=e.getAttribute("data-color-mode-forced");l&&(r=l),i(r),o["__NUXT_COLOR_MODE__"]={preference:s,value:r,getColorScheme:f,addColorScheme:i,removeColorScheme:d};function i(t){const a=""+t+"",n="";e.classList?e.classList.add(a):e.className+=" "+a,n&&e.setAttribute("data-"+n,t)}function d(t){const a=""+t+"",n="";e.classList?e.classList.remove(a):e.className=e.className.replace(new RegExp(a,"g"),""),n&&e.removeAttribute("data-"+n)}function u(t){return o.matchMedia("(prefers-color-scheme"+t+")")}function f(){if(o.matchMedia&&u("").media!=="not all"){for(const t of c)if(u(":"+t).matches)return t}return"light"}})();function getStorageValue(o,e){switch(o){case"localStorage":try{return window.localStorage.getItem(e)}catch{return null}case"sessionStorage":try{return window.sessionStorage.getItem(e)}catch{return null}case"cookie":try{return getCookie(e)}catch{return null}default:return null}}function getCookie(o){const c=("; "+window.document.cookie).split("; "+o+"=");if(c.length===2){const s=c.pop();return s?s.split(";").shift():null}}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{pddVersion:"0.13.0"},app:{baseURL:"/",buildId:"371c8694-5c47-4dea-84be-d8bb014327ac",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1789218321077,false]</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/_nuxt/entry.DsWXLqBw.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CmwFmk8h.js"><script type="module" src="/_nuxt/CmwFmk8h.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-500.BwxPsW7a.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/DQ3ZnyMB.js"><script>"use strict";(()=>{const o=window,e=document.documentElement,c=["dark","light"],s=getStorageValue("localStorage","nuxt-color-mode")||"light";let r=s==="system"?f():s;const l=e.getAttribute("data-color-mode-forced");l&&(r=l),i(r),o["__NUXT_COLOR_MODE__"]={preference:s,value:r,getColorScheme:f,addColorScheme:i,removeColorScheme:d};function i(t){const a=""+t+"",n="";e.classList?e.classList.add(a):e.className+=" "+a,n&&e.setAttribute("data-"+n,t)}function d(t){const a=""+t+"",n="";e.classList?e.classList.remove(a):e.className=e.className.replace(new RegExp(a,"g"),""),n&&e.removeAttribute("data-"+n)}function u(t){return o.matchMedia("(prefers-color-scheme"+t+")")}function f(){if(o.matchMedia&&u("").media!=="not all"){for(const t of c)if(u(":"+t).matches)return t}return"light"}})();function getStorageValue(o,e){switch(o){case"localStorage":try{return window.localStorage.getItem(e)}catch{return null}case"sessionStorage":try{return window.sessionStorage.getItem(e)}catch{return null}case"cookie":try{return getCookie(e)}catch{return null}default:return null}}function getCookie(o){const c=("; "+window.document.cookie).split("; "+o+"=");if(c.length===2){const s=c.pop();return s?s.split(";").shift():null}}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{pddVersion:"0.11.0"},app:{baseURL:"/",buildId:"3da08759-853a-4f1f-97f9-21437357aef0",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1788770970157,false]</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/_nuxt/entry.Cn2HYcjJ.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/_nuxt/BtQ-s_jB.js"><script type="module" src="/_nuxt/BtQ-s_jB.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-404.VJcZ3YVw.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/cSnpUPR8.js"><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-500.BwxPsW7a.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/B-mP848s.js"><script>"use strict";(()=>{const o=window,e=document.documentElement,c=["dark","light"],s=getStorageValue("localStorage","nuxt-color-mode")||"light";let r=s==="system"?f():s;const l=e.getAttribute("data-color-mode-forced");l&&(r=l),i(r),o["__NUXT_COLOR_MODE__"]={preference:s,value:r,getColorScheme:f,addColorScheme:i,removeColorScheme:d};function i(t){const a=""+t+"",n="";e.classList?e.classList.add(a):e.className+=" "+a,n&&e.setAttribute("data-"+n,t)}function d(t){const a=""+t+"",n="";e.classList?e.classList.remove(a):e.className=e.className.replace(new RegExp(a,"g"),""),n&&e.removeAttribute("data-"+n)}function u(t){return o.matchMedia("(prefers-color-scheme"+t+")")}function f(){if(o.matchMedia&&u("").media!=="not all"){for(const t of c)if(u(":"+t).matches)return t}return"light"}})();function getStorageValue(o,e){switch(o){case"localStorage":try{return window.localStorage.getItem(e)}catch{return null}case"sessionStorage":try{return window.sessionStorage.getItem(e)}catch{return null}case"cookie":try{return getCookie(e)}catch{return null}default:return null}}function getCookie(o){const c=("; "+window.document.cookie).split("; "+o+"=");if(c.length===2){const s=c.pop();return s?s.split(";").shift():null}}</script></head><body><div id="__nuxt" class="isolate"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{pddVersion:"0.13.0"},app:{baseURL:"/",buildId:"371c8694-5c47-4dea-84be-d8bb014327ac",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1789218321077,false]</script></body></html>