@webpieces/nx-webpieces-rules 0.4.911 → 0.4.913

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 (85) hide show
  1. package/README.md +11 -0
  2. package/executors.json +5 -0
  3. package/package.json +7 -7
  4. package/src/executors/help/executor.js +2 -0
  5. package/src/executors/help/executor.js.map +1 -1
  6. package/src/executors/visualize-runtime/executor.d.ts +3 -1
  7. package/src/executors/visualize-runtime/executor.js +9 -3
  8. package/src/executors/visualize-runtime/executor.js.map +1 -1
  9. package/src/executors/visualize-runtime-goal/executor.d.ts +27 -0
  10. package/src/executors/visualize-runtime-goal/executor.js +98 -0
  11. package/src/executors/visualize-runtime-goal/executor.js.map +1 -0
  12. package/src/executors/visualize-runtime-goal/schema.json +13 -0
  13. package/src/index.d.ts +1 -1
  14. package/src/index.js +3 -1
  15. package/src/index.js.map +1 -1
  16. package/src/lib/graph-color-modes.d.ts +15 -1
  17. package/src/lib/graph-color-modes.js +19 -1
  18. package/src/lib/graph-color-modes.js.map +1 -1
  19. package/src/lib/graph-filter.client.d.ts +9 -2
  20. package/src/lib/graph-filter.client.js +15 -0
  21. package/src/lib/graph-filter.client.js.map +1 -1
  22. package/src/lib/graph-legend.js +1 -1
  23. package/src/lib/graph-legend.js.map +1 -1
  24. package/src/lib/graph-mode-state.client.d.ts +9 -2
  25. package/src/lib/graph-mode-state.client.js +17 -4
  26. package/src/lib/graph-mode-state.client.js.map +1 -1
  27. package/src/lib/graph-page-shell.d.ts +11 -4
  28. package/src/lib/graph-page-shell.js +11 -9
  29. package/src/lib/graph-page-shell.js.map +1 -1
  30. package/src/lib/graph-products.d.ts +22 -3
  31. package/src/lib/graph-products.js +63 -13
  32. package/src/lib/graph-products.js.map +1 -1
  33. package/src/lib/graph-render-model.d.ts +41 -0
  34. package/src/lib/graph-render-model.js +45 -1
  35. package/src/lib/graph-render-model.js.map +1 -1
  36. package/src/lib/graph-visualizer.client.d.ts +7 -1
  37. package/src/lib/graph-visualizer.client.js +37 -4
  38. package/src/lib/graph-visualizer.client.js.map +1 -1
  39. package/src/lib/graph-visualizer.js +1 -1
  40. package/src/lib/graph-visualizer.js.map +1 -1
  41. package/src/lib/runtime-goal-comparison.d.ts +55 -0
  42. package/src/lib/runtime-goal-comparison.js +209 -0
  43. package/src/lib/runtime-goal-comparison.js.map +1 -0
  44. package/src/lib/runtime-goal-details.d.ts +17 -0
  45. package/src/lib/runtime-goal-details.js +118 -0
  46. package/src/lib/runtime-goal-details.js.map +1 -0
  47. package/src/lib/runtime-goal-file.d.ts +72 -0
  48. package/src/lib/runtime-goal-file.js +201 -0
  49. package/src/lib/runtime-goal-file.js.map +1 -0
  50. package/src/lib/runtime-goal-styles.d.ts +10 -0
  51. package/src/lib/runtime-goal-styles.js +25 -0
  52. package/src/lib/runtime-goal-styles.js.map +1 -0
  53. package/src/lib/runtime-goal-validator.d.ts +39 -0
  54. package/src/lib/runtime-goal-validator.js +236 -0
  55. package/src/lib/runtime-goal-validator.js.map +1 -0
  56. package/src/lib/runtime-goal-view.d.ts +22 -0
  57. package/src/lib/runtime-goal-view.js +64 -0
  58. package/src/lib/runtime-goal-view.js.map +1 -0
  59. package/src/lib/runtime-graph-diff.d.ts +107 -0
  60. package/src/lib/runtime-graph-diff.js +346 -0
  61. package/src/lib/runtime-graph-diff.js.map +1 -0
  62. package/src/lib/runtime-html-page.d.ts +8 -0
  63. package/src/lib/runtime-html-page.js +39 -6
  64. package/src/lib/runtime-html-page.js.map +1 -1
  65. package/src/lib/runtime-layout.d.ts +2 -0
  66. package/src/lib/runtime-layout.js +4 -0
  67. package/src/lib/runtime-layout.js.map +1 -1
  68. package/src/lib/runtime-union-graph.d.ts +20 -0
  69. package/src/lib/runtime-union-graph.js +94 -0
  70. package/src/lib/runtime-union-graph.js.map +1 -0
  71. package/src/lib/runtime-viewer-adapter.js +7 -5
  72. package/src/lib/runtime-viewer-adapter.js.map +1 -1
  73. package/src/lib/runtime-visualizer.client.js +7 -3
  74. package/src/lib/runtime-visualizer.client.js.map +1 -1
  75. package/src/lib/runtime-visualizer.d.ts +8 -3
  76. package/src/lib/runtime-visualizer.js +18 -10
  77. package/src/lib/runtime-visualizer.js.map +1 -1
  78. package/src/lib/runtime-viz-options.d.ts +28 -1
  79. package/src/lib/runtime-viz-options.js +36 -2
  80. package/src/lib/runtime-viz-options.js.map +1 -1
  81. package/src/plugin.js +2 -2
  82. package/src/plugin.js.map +1 -1
  83. package/src/runtime-targets.d.ts +6 -0
  84. package/src/runtime-targets.js +17 -0
  85. package/src/runtime-targets.js.map +1 -1
package/README.md CHANGED
@@ -106,6 +106,17 @@ afterward does not establish that refresh succeeded. Browser-open failures print
106
106
  the HTML path for manual opening. Architecture/API validation and CI still run
107
107
  their existing checks independently of visualization.
108
108
 
109
+ ### Runtime goals (proposals)
110
+
111
+ `pnpm nx run architecture:visualize-runtime-goal` draws the hand-authored
112
+ `architecture/runtime-dependencies-goal.json` into
113
+ `tmp/webpieces/runtime-architecture-goal.{dot,html}`; it never generates, never writes
114
+ either JSON file, and fails a missing goal with its path and
115
+ `cp architecture/runtime-dependencies.json architecture/runtime-dependencies-goal.json`.
116
+ `--prepare` explicitly recomputes the goal's derived levels first. Both runtime pages
117
+ offer Color by → **Goal vs Current**, a semantic diff of the two saved files. Details,
118
+ comparison policy and the edit workflow: `docs/architecture/runtime-goal.md`.
119
+
109
120
  ### Color modes and the page shell
110
121
 
111
122
  `architecture/dependencies.html` opens with the graph filling the viewport and every control
package/executors.json CHANGED
@@ -15,6 +15,11 @@
15
15
  "schema": "./src/executors/visualize-runtime/schema.json",
16
16
  "description": "View saved runtime architecture without refreshing; refresh: pnpm nx run architecture:generate"
17
17
  },
18
+ "visualize-runtime-goal": {
19
+ "implementation": "./src/executors/visualize-runtime-goal/executor",
20
+ "schema": "./src/executors/visualize-runtime-goal/schema.json",
21
+ "description": "View the hand-authored runtime goal (architecture/runtime-dependencies-goal.json) with Goal vs Current; --prepare recomputes its derived levels"
22
+ },
18
23
  "validate-runtime-architecture": {
19
24
  "implementation": "./src/executors/validate-runtime-architecture/executor",
20
25
  "schema": "./src/executors/validate-runtime-architecture/schema.json",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/nx-webpieces-rules",
3
- "version": "0.4.911",
3
+ "version": "0.4.913",
4
4
  "description": "Nx-specific webpieces validation rules, graph tooling, executors, and inference plugin.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -20,12 +20,12 @@
20
20
  "README.md"
21
21
  ],
22
22
  "dependencies": {
23
- "@webpieces/api-doc-model": "0.4.911",
24
- "@webpieces/core-util": "0.4.911",
25
- "@webpieces/eslint-rules": "0.4.911",
26
- "@webpieces/rules-config": "0.4.911",
23
+ "@webpieces/api-doc-model": "0.4.913",
24
+ "@webpieces/core-util": "0.4.913",
25
+ "@webpieces/eslint-rules": "0.4.913",
26
+ "@webpieces/rules-config": "0.4.913",
27
27
  "madge": "8.0.0",
28
- "@webpieces/rules-sdk": "0.4.911"
28
+ "@webpieces/rules-sdk": "0.4.913"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "@nx/devkit": ">=18.0.0"
@@ -41,7 +41,7 @@
41
41
  "access": "public"
42
42
  },
43
43
  "devDependencies": {
44
- "@webpieces/tooling-testkit": "0.4.911"
44
+ "@webpieces/tooling-testkit": "0.4.913"
45
45
  },
46
46
  "types": "./src/index.d.ts",
47
47
  "bin": {
@@ -15,6 +15,7 @@ async function helpExecutor(options, context) {
15
15
  console.log(' npm run arch:generate # Explicitly refresh architecture/API/runtime facts');
16
16
  console.log(' npm run arch:visualize # View saved snapshot (does not refresh)');
17
17
  console.log(' npm run arch:visualize-runtime # View saved runtime snapshot (does not refresh)');
18
+ console.log(' npm run arch:visualize-runtime-goal # View the runtime goal proposal + Goal vs Current (never generates)');
18
19
  console.log('');
19
20
  console.log(' Validation:');
20
21
  console.log(' npm run arch:validate # Quick validation (no-cycles)');
@@ -29,6 +30,7 @@ async function helpExecutor(options, context) {
29
30
  console.log(' nx run architecture:generate # Explicitly refresh architecture/API/runtime facts');
30
31
  console.log(' nx run architecture:visualize # View saved snapshot (does not refresh)');
31
32
  console.log(' nx run architecture:visualize-runtime # View saved runtime snapshot (does not refresh)');
33
+ console.log(' nx run architecture:visualize-runtime-goal # View the runtime goal proposal (--prepare recomputes its levels)');
32
34
  console.log(' nx run architecture:validate-no-architecture-cycles # Check for circular project dependencies');
33
35
  console.log(' nx run architecture:validate-architecture-unchanged # Validate against blessed graph');
34
36
  console.log('');
@@ -1 +1 @@
1
- {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/help/executor.ts"],"names":[],"mappings":";;AAMA,+BAyDC;AAzDc,KAAK,UAAU,YAAY,CACtC,OAA4B,EAC5B,OAAwB;IAExB,mBAAmB;IACnB,MAAM,KAAK,GAAG,iBAAiB,CAAC;IAChC,MAAM,IAAI,GAAG,SAAS,CAAC;IACvB,MAAM,KAAK,GAAG,SAAS,CAAC;IAExB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,wDAAwD,KAAK,EAAE,CAAC,CAAC;IACrF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,mDAAmD,KAAK,EAAE,CAAC,CAAC;IAC/E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,gGAAgG,CAAC,CAAC;IAC9G,OAAO,CAAC,GAAG,CAAC,qFAAqF,CAAC,CAAC;IACnG,OAAO,CAAC,GAAG,CAAC,6FAA6F,CAAC,CAAC;IAC3G,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,2EAA2E,CAAC,CAAC;IACzF,OAAO,CAAC,GAAG,CAAC,uFAAuF,CAAC,CAAC;IACrG,OAAO,CAAC,GAAG,CAAC,mFAAmF,CAAC,CAAC;IACjG,OAAO,CAAC,GAAG,CAAC,2EAA2E,CAAC,CAAC;IACzF,OAAO,CAAC,GAAG,CAAC,oFAAoF,CAAC,CAAC;IAClG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,2BAA2B,KAAK,EAAE,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,8GAA8G,CAAC,CAAC;IAC5H,OAAO,CAAC,GAAG,CAAC,mGAAmG,CAAC,CAAC;IACjH,OAAO,CAAC,GAAG,CAAC,2GAA2G,CAAC,CAAC;IACzH,OAAO,CAAC,GAAG,CAAC,oGAAoG,CAAC,CAAC;IAClH,OAAO,CAAC,GAAG,CAAC,2FAA2F,CAAC,CAAC;IACzG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,sGAAsG,CAAC,CAAC;IACpH,OAAO,CAAC,GAAG,CAAC,6FAA6F,CAAC,CAAC;IAC3G,OAAO,CAAC,GAAG,CAAC,oFAAoF,CAAC,CAAC;IAClG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,6EAA6E,CAAC,CAAC;IAC3F,OAAO,CAAC,GAAG,CAAC,sEAAsE,CAAC,CAAC;IACpF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC;IAC9E,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,kBAAkB,KAAK,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,wBAAwB,KAAK,uCAAuC,CAAC,CAAC;IAC5F,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,iCAAiC,KAAK,6BAA6B,CAAC,CAAC;IAC3F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC7B,CAAC","sourcesContent":["import type { ExecutorContext } from '@nx/devkit';\n\nexport interface HelpExecutorOptions {}\n\ntype HelpExecutorResult = { success: true };\n\nexport default async function helpExecutor(\n options: HelpExecutorOptions,\n context: ExecutorContext\n): Promise<HelpExecutorResult> {\n // ANSI color codes\n const GREEN = '\\x1b[32m\\x1b[1m';\n const BOLD = '\\x1b[1m';\n const RESET = '\\x1b[0m';\n\n console.log('');\n console.log(`${GREEN}💡 @webpieces/nx-webpieces-rules - Available Commands${RESET}`);\n console.log('');\n console.log(`${BOLD}📝 Available npm scripts (convenient shortcuts):${RESET}`);\n console.log('');\n console.log(' Architecture graph:');\n console.log(' npm run arch:generate # Explicitly refresh architecture/API/runtime facts');\n console.log(' npm run arch:visualize # View saved snapshot (does not refresh)');\n console.log(' npm run arch:visualize-runtime # View saved runtime snapshot (does not refresh)');\n console.log('');\n console.log(' Validation:');\n console.log(' npm run arch:validate # Quick validation (no-cycles)');\n console.log(' npm run arch:validate-all # Full arch validation (+ unchanged check)');\n console.log(' npm run arch:check-circular # Check all projects for circular deps');\n console.log(' npm run arch:check-circular-affected # Check affected projects only');\n console.log(' npm run arch:validate-complete # Complete validation (arch + circular)');\n console.log('');\n console.log(`${BOLD}📝 Available Nx targets:${RESET}`);\n console.log('');\n console.log(' Workspace-level architecture validation:');\n console.log(' nx run architecture:generate # Explicitly refresh architecture/API/runtime facts');\n console.log(' nx run architecture:visualize # View saved snapshot (does not refresh)');\n console.log(' nx run architecture:visualize-runtime # View saved runtime snapshot (does not refresh)');\n console.log(' nx run architecture:validate-no-architecture-cycles # Check for circular project dependencies');\n console.log(' nx run architecture:validate-architecture-unchanged # Validate against blessed graph');\n console.log('');\n console.log(' Per-project file import cycle checking:');\n console.log(' nx run <project>:validate-no-file-import-cycles # Check project for file import cycles');\n console.log(' nx affected --target=validate-no-file-import-cycles # Check all affected projects');\n console.log(' nx run-many --target=validate-no-file-import-cycles --all # Check all projects');\n console.log('');\n console.log(' Per-project CI target (lint + build + test):');\n console.log(' nx run <project>:ci # Run lint, build, test together');\n console.log(' nx run-many --target=ci --all # Run ci for all projects');\n console.log('');\n console.log(' Execution order (test waits for build via targetDefaults):');\n console.log(' ci (nx:noop)');\n console.log(' ├── lint ─────────────────┐');\n console.log(' ├── build ────────────────┼── run in parallel');\n console.log(' └── test ─────────────────┘');\n console.log(' └── depends on build (waits)');\n console.log('');\n console.log(`${GREEN}💡 Quick start:${RESET}`);\n console.log(` ${BOLD}npm run arch:generate${RESET} # Generate the graph first`);\n console.log(` ${BOLD}npm run arch:validate-complete${RESET} # Run complete validation`);\n console.log('');\n\n return { success: true };\n}\n"]}
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/help/executor.ts"],"names":[],"mappings":";;AAMA,+BA2DC;AA3Dc,KAAK,UAAU,YAAY,CACtC,OAA4B,EAC5B,OAAwB;IAExB,mBAAmB;IACnB,MAAM,KAAK,GAAG,iBAAiB,CAAC;IAChC,MAAM,IAAI,GAAG,SAAS,CAAC;IACvB,MAAM,KAAK,GAAG,SAAS,CAAC;IAExB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,wDAAwD,KAAK,EAAE,CAAC,CAAC;IACrF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,mDAAmD,KAAK,EAAE,CAAC,CAAC;IAC/E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,gGAAgG,CAAC,CAAC;IAC9G,OAAO,CAAC,GAAG,CAAC,qFAAqF,CAAC,CAAC;IACnG,OAAO,CAAC,GAAG,CAAC,6FAA6F,CAAC,CAAC;IAC3G,OAAO,CAAC,GAAG,CAAC,iHAAiH,CAAC,CAAC;IAC/H,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,2EAA2E,CAAC,CAAC;IACzF,OAAO,CAAC,GAAG,CAAC,uFAAuF,CAAC,CAAC;IACrG,OAAO,CAAC,GAAG,CAAC,mFAAmF,CAAC,CAAC;IACjG,OAAO,CAAC,GAAG,CAAC,2EAA2E,CAAC,CAAC;IACzF,OAAO,CAAC,GAAG,CAAC,oFAAoF,CAAC,CAAC;IAClG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,2BAA2B,KAAK,EAAE,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,8GAA8G,CAAC,CAAC;IAC5H,OAAO,CAAC,GAAG,CAAC,mGAAmG,CAAC,CAAC;IACjH,OAAO,CAAC,GAAG,CAAC,2GAA2G,CAAC,CAAC;IACzH,OAAO,CAAC,GAAG,CAAC,6HAA6H,CAAC,CAAC;IAC3I,OAAO,CAAC,GAAG,CAAC,oGAAoG,CAAC,CAAC;IAClH,OAAO,CAAC,GAAG,CAAC,2FAA2F,CAAC,CAAC;IACzG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,sGAAsG,CAAC,CAAC;IACpH,OAAO,CAAC,GAAG,CAAC,6FAA6F,CAAC,CAAC;IAC3G,OAAO,CAAC,GAAG,CAAC,oFAAoF,CAAC,CAAC;IAClG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,6EAA6E,CAAC,CAAC;IAC3F,OAAO,CAAC,GAAG,CAAC,sEAAsE,CAAC,CAAC;IACpF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC;IAC9E,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,kBAAkB,KAAK,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,wBAAwB,KAAK,uCAAuC,CAAC,CAAC;IAC5F,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,iCAAiC,KAAK,6BAA6B,CAAC,CAAC;IAC3F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC7B,CAAC","sourcesContent":["import type { ExecutorContext } from '@nx/devkit';\n\nexport interface HelpExecutorOptions {}\n\ntype HelpExecutorResult = { success: true };\n\nexport default async function helpExecutor(\n options: HelpExecutorOptions,\n context: ExecutorContext\n): Promise<HelpExecutorResult> {\n // ANSI color codes\n const GREEN = '\\x1b[32m\\x1b[1m';\n const BOLD = '\\x1b[1m';\n const RESET = '\\x1b[0m';\n\n console.log('');\n console.log(`${GREEN}💡 @webpieces/nx-webpieces-rules - Available Commands${RESET}`);\n console.log('');\n console.log(`${BOLD}📝 Available npm scripts (convenient shortcuts):${RESET}`);\n console.log('');\n console.log(' Architecture graph:');\n console.log(' npm run arch:generate # Explicitly refresh architecture/API/runtime facts');\n console.log(' npm run arch:visualize # View saved snapshot (does not refresh)');\n console.log(' npm run arch:visualize-runtime # View saved runtime snapshot (does not refresh)');\n console.log(' npm run arch:visualize-runtime-goal # View the runtime goal proposal + Goal vs Current (never generates)');\n console.log('');\n console.log(' Validation:');\n console.log(' npm run arch:validate # Quick validation (no-cycles)');\n console.log(' npm run arch:validate-all # Full arch validation (+ unchanged check)');\n console.log(' npm run arch:check-circular # Check all projects for circular deps');\n console.log(' npm run arch:check-circular-affected # Check affected projects only');\n console.log(' npm run arch:validate-complete # Complete validation (arch + circular)');\n console.log('');\n console.log(`${BOLD}📝 Available Nx targets:${RESET}`);\n console.log('');\n console.log(' Workspace-level architecture validation:');\n console.log(' nx run architecture:generate # Explicitly refresh architecture/API/runtime facts');\n console.log(' nx run architecture:visualize # View saved snapshot (does not refresh)');\n console.log(' nx run architecture:visualize-runtime # View saved runtime snapshot (does not refresh)');\n console.log(' nx run architecture:visualize-runtime-goal # View the runtime goal proposal (--prepare recomputes its levels)');\n console.log(' nx run architecture:validate-no-architecture-cycles # Check for circular project dependencies');\n console.log(' nx run architecture:validate-architecture-unchanged # Validate against blessed graph');\n console.log('');\n console.log(' Per-project file import cycle checking:');\n console.log(' nx run <project>:validate-no-file-import-cycles # Check project for file import cycles');\n console.log(' nx affected --target=validate-no-file-import-cycles # Check all affected projects');\n console.log(' nx run-many --target=validate-no-file-import-cycles --all # Check all projects');\n console.log('');\n console.log(' Per-project CI target (lint + build + test):');\n console.log(' nx run <project>:ci # Run lint, build, test together');\n console.log(' nx run-many --target=ci --all # Run ci for all projects');\n console.log('');\n console.log(' Execution order (test waits for build via targetDefaults):');\n console.log(' ci (nx:noop)');\n console.log(' ├── lint ─────────────────┐');\n console.log(' ├── build ────────────────┼── run in parallel');\n console.log(' └── test ─────────────────┘');\n console.log(' └── depends on build (waits)');\n console.log('');\n console.log(`${GREEN}💡 Quick start:${RESET}`);\n console.log(` ${BOLD}npm run arch:generate${RESET} # Generate the graph first`);\n console.log(` ${BOLD}npm run arch:validate-complete${RESET} # Run complete validation`);\n console.log('');\n\n return { success: true };\n}\n"]}
@@ -2,7 +2,9 @@
2
2
  * Visualize Runtime Executor
3
3
  *
4
4
  * Renders the runtime microservice graph (committed
5
- * architecture/runtime-dependencies.json) to DOT + HTML and opens it.
5
+ * architecture/runtime-dependencies.json) to DOT + HTML and opens it. When a runtime goal
6
+ * (architecture/runtime-dependencies-goal.json, #1239) is present, the page also carries the
7
+ * Goal vs Current comparison; when it is absent or unusable, the page says why instead.
6
8
  *
7
9
  * Usage: nx run architecture:visualize-runtime
8
10
  */
@@ -3,7 +3,9 @@
3
3
  * Visualize Runtime Executor
4
4
  *
5
5
  * Renders the runtime microservice graph (committed
6
- * architecture/runtime-dependencies.json) to DOT + HTML and opens it.
6
+ * architecture/runtime-dependencies.json) to DOT + HTML and opens it. When a runtime goal
7
+ * (architecture/runtime-dependencies-goal.json, #1239) is present, the page also carries the
8
+ * Goal vs Current comparison; when it is absent or unusable, the page says why instead.
7
9
  *
8
10
  * Usage: nx run architecture:visualize-runtime
9
11
  */
@@ -19,6 +21,7 @@ const rules_config_1 = require("@webpieces/rules-config");
19
21
  const runtime_visualizer_1 = require("../../lib/runtime-visualizer");
20
22
  const runtime_config_1 = require("../../lib/runtime-config");
21
23
  const graph_visualizer_1 = require("../../lib/graph-visualizer");
24
+ const runtime_goal_view_1 = require("../../lib/runtime-goal-view");
22
25
  const toError_1 = require("../../toError");
23
26
  async function runExecutor(_options, context) {
24
27
  const workspaceRoot = context.root;
@@ -30,8 +33,11 @@ async function runExecutor(_options, context) {
30
33
  const graph = snapshot.loadRuntime(workspaceRoot);
31
34
  const config = (0, runtime_config_1.loadRuntimeConfig)(workspaceRoot);
32
35
  const projects = fs.existsSync(path.join(workspaceRoot, graph_loader_1.DEFAULT_GRAPH_PATH)) ? snapshot.loadProjects(workspaceRoot, graph_loader_1.DEFAULT_GRAPH_PATH).projects : null;
33
- const options = new runtime_visualizer_1.RuntimeVizOptions(config.showExternalNodes, projects, workspaceRoot);
34
- const vizPaths = (0, runtime_visualizer_1.writeRuntimeVisualization)(graph, workspaceRoot, undefined, options);
36
+ const options = new runtime_visualizer_1.RuntimeVizOptions(config.showExternalNodes, projects, workspaceRoot, runtime_visualizer_1.RuntimePageKind.CURRENT);
37
+ const inputs = new runtime_goal_view_1.RuntimeComparisonInputs(snapshot);
38
+ const comparison = inputs.view(graph, inputs.goal(workspaceRoot), options);
39
+ console.log(comparison.available ? `Goal vs Current: ${comparison.summary}` : `Goal vs Current unavailable: ${comparison.reason}`);
40
+ const vizPaths = (0, runtime_visualizer_1.writeRuntimeVisualization)(graph, workspaceRoot, 'WebPieces Runtime Architecture', options, comparison);
35
41
  console.log(`✅ Generated: ${vizPaths.dotPath}`);
36
42
  console.log(`✅ Generated: ${vizPaths.htmlPath}`);
37
43
  if (projects !== null)
@@ -1 +1 @@
1
- {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/visualize-runtime/executor.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAsBH,8BAoCC;;AAxDD,+CAAyB;AACzB,mDAA6B;AAC7B,yDAA4D;AAC5D,yDAA8F;AAE9F,6DAAyD;AACzD,0DAAgF;AAChF,qEAA4F;AAC5F,6DAA6D;AAC7D,iEAA6D;AAC7D,2CAAwC;AAUzB,KAAK,UAAU,WAAW,CACrC,QAAiC,EACjC,OAAwB;IAExB,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IACnC,MAAM,QAAQ,GAAkB,IAAI,8BAAa,EAAE,CAAC;IAEpD,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IAEhC,uIAAuI;IACvI,IAAI,CAAC;QACD,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAA,kCAAiB,EAAC,aAAa,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,iCAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,aAAa,EAAE,iCAAkB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;QACxJ,MAAM,OAAO,GAAG,IAAI,sCAAiB,CAAC,MAAM,CAAC,iBAAiB,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;QACzF,MAAM,QAAQ,GAAG,IAAA,8CAAyB,EAAC,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QACrF,OAAO,CAAC,GAAG,CAAC,gBAAgB,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,gBAAgB,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;QACjD,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,4BAAa,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,EAAE,QAAQ,EAAE,qCAAsB,CAAC,CAAC,CAAC;aAC/I,CAAC;YAAC,IAAI,4BAAa,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAC,OAAO,CAAC,GAAG,CAAC,mHAAmH,CAAC,CAAC;QAAC,CAAC;QAEvM,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;QACxD,IAAI,IAAI,kCAAe,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7D,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,2CAA2C,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;QAChF,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,IAAA,iBAAO,EAAC,GAAG,CAAC,CAAC;QAC3B,MAAM,QAAQ,GAAG,KAAK,YAAY,4BAAa,CAAC,CAAC,CAAC,IAAA,qCAAsB,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;QAChG,OAAO,CAAC,KAAK,CAAC,4EAA4E,EAAE,QAAQ,CAAC,CAAC;QACtG,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;AACL,CAAC","sourcesContent":["/**\n * Visualize Runtime Executor\n *\n * Renders the runtime microservice graph (committed\n * architecture/runtime-dependencies.json) to DOT + HTML and opens it.\n *\n * Usage: nx run architecture:visualize-runtime\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { DEFAULT_GRAPH_PATH } from '../../lib/graph-loader';\nimport { ImpactRefresh, ImpactSidecar, VISUALIZE_IMPACT_KINDS } from '../../lib/graph-impact';\nimport type { ExecutorContext } from '@nx/devkit';\nimport { SavedSnapshot } from '../../lib/saved-snapshot';\nimport { RuleFailError, renderRuleFailForHuman } from '@webpieces/rules-config';\nimport { writeRuntimeVisualization, RuntimeVizOptions } from '../../lib/runtime-visualizer';\nimport { loadRuntimeConfig } from '../../lib/runtime-config';\nimport { GraphVisualizer } from '../../lib/graph-visualizer';\nimport { toError } from '../../toError';\n\nexport interface VisualizeRuntimeOptions {\n // No options.\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\nexport default async function runExecutor(\n _options: VisualizeRuntimeOptions,\n context: ExecutorContext,\n): Promise<ExecutorResult> {\n const workspaceRoot = context.root;\n const snapshot: SavedSnapshot = new SavedSnapshot();\n\n console.log('\\n🎨 Runtime Microservice Visualization\\n');\n console.log(snapshot.message());\n\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- Nx command rendering boundary; success:false propagates failure to Nx\n try {\n const graph = snapshot.loadRuntime(workspaceRoot);\n const config = loadRuntimeConfig(workspaceRoot);\n const projects = fs.existsSync(path.join(workspaceRoot, DEFAULT_GRAPH_PATH)) ? snapshot.loadProjects(workspaceRoot, DEFAULT_GRAPH_PATH).projects : null;\n const options = new RuntimeVizOptions(config.showExternalNodes, projects, workspaceRoot);\n const vizPaths = writeRuntimeVisualization(graph, workspaceRoot, undefined, options);\n console.log(`✅ Generated: ${vizPaths.dotPath}`);\n console.log(`✅ Generated: ${vizPaths.htmlPath}`);\n if (projects !== null) console.log(await new ImpactRefresh().run(path.dirname(vizPaths.htmlPath), workspaceRoot, projects, VISUALIZE_IMPACT_KINDS));\n else { new ImpactSidecar().remove(path.dirname(vizPaths.htmlPath)); console.log('Impact and framework metadata unavailable: no saved project graph. Refresh explicitly with architecture:generate.'); }\n\n console.log('\\n🌐 Opening visualization in browser...');\n if (new GraphVisualizer().openVisualization(vizPaths.htmlPath)) {\n console.log('✅ Browser opened');\n } else {\n console.log(`⚠️ Could not auto-open. Open manually: ${vizPaths.htmlPath}`);\n }\n\n return { success: true };\n } catch (err: unknown) {\n const error = toError(err);\n const rendered = error instanceof RuleFailError ? renderRuleFailForHuman(error) : error.message;\n console.error('❌ Runtime visualization failed for architecture/runtime-dependencies.json:', rendered);\n return { success: false };\n }\n}\n"]}
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/visualize-runtime/executor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Visualize Runtime Executor\n *\n * Renders the runtime microservice graph (committed\n * architecture/runtime-dependencies.json) to DOT + HTML and opens it. When a runtime goal\n * (architecture/runtime-dependencies-goal.json, #1239) is present, the page also carries the\n * Goal vs Current comparison; when it is absent or unusable, the page says why instead.\n *\n * Usage: nx run architecture:visualize-runtime\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { DEFAULT_GRAPH_PATH } from '../../lib/graph-loader';\nimport { ImpactRefresh, ImpactSidecar, VISUALIZE_IMPACT_KINDS } from '../../lib/graph-impact';\nimport type { ExecutorContext } from '@nx/devkit';\nimport { SavedSnapshot } from '../../lib/saved-snapshot';\nimport { RuleFailError, renderRuleFailForHuman } from '@webpieces/rules-config';\nimport { writeRuntimeVisualization, RuntimeVizOptions, RuntimePageKind } from '../../lib/runtime-visualizer';\nimport { loadRuntimeConfig } from '../../lib/runtime-config';\nimport { GraphVisualizer } from '../../lib/graph-visualizer';\nimport { RuntimeComparisonInputs } from '../../lib/runtime-goal-view';\nimport { toError } from '../../toError';\n\nexport interface VisualizeRuntimeOptions {\n // No options.\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\nexport default async function runExecutor(\n _options: VisualizeRuntimeOptions,\n context: ExecutorContext,\n): Promise<ExecutorResult> {\n const workspaceRoot = context.root;\n const snapshot: SavedSnapshot = new SavedSnapshot();\n\n console.log('\\n🎨 Runtime Microservice Visualization\\n');\n console.log(snapshot.message());\n\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- Nx command rendering boundary; success:false propagates failure to Nx\n try {\n const graph = snapshot.loadRuntime(workspaceRoot);\n const config = loadRuntimeConfig(workspaceRoot);\n const projects = fs.existsSync(path.join(workspaceRoot, DEFAULT_GRAPH_PATH)) ? snapshot.loadProjects(workspaceRoot, DEFAULT_GRAPH_PATH).projects : null;\n const options = new RuntimeVizOptions(config.showExternalNodes, projects, workspaceRoot, RuntimePageKind.CURRENT);\n const inputs = new RuntimeComparisonInputs(snapshot);\n const comparison = inputs.view(graph, inputs.goal(workspaceRoot), options);\n console.log(comparison.available ? `Goal vs Current: ${comparison.summary}` : `Goal vs Current unavailable: ${comparison.reason}`);\n const vizPaths = writeRuntimeVisualization(graph, workspaceRoot, 'WebPieces Runtime Architecture', options, comparison);\n console.log(`✅ Generated: ${vizPaths.dotPath}`);\n console.log(`✅ Generated: ${vizPaths.htmlPath}`);\n if (projects !== null) console.log(await new ImpactRefresh().run(path.dirname(vizPaths.htmlPath), workspaceRoot, projects, VISUALIZE_IMPACT_KINDS));\n else { new ImpactSidecar().remove(path.dirname(vizPaths.htmlPath)); console.log('Impact and framework metadata unavailable: no saved project graph. Refresh explicitly with architecture:generate.'); }\n\n console.log('\\n🌐 Opening visualization in browser...');\n if (new GraphVisualizer().openVisualization(vizPaths.htmlPath)) {\n console.log('✅ Browser opened');\n } else {\n console.log(`⚠️ Could not auto-open. Open manually: ${vizPaths.htmlPath}`);\n }\n\n return { success: true };\n } catch (err: unknown) {\n const error = toError(err);\n const rendered = error instanceof RuleFailError ? renderRuleFailForHuman(error) : error.message;\n console.error('❌ Runtime visualization failed for architecture/runtime-dependencies.json:', rendered);\n return { success: false };\n }\n}\n"]}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Visualize Runtime Goal Executor (#1239)
3
+ *
4
+ * Renders the hand-authored runtime PROPOSAL, architecture/runtime-dependencies-goal.json, with the
5
+ * same shared runtime renderer as visualize-runtime, into its own files:
6
+ * tmp/webpieces/runtime-architecture-goal.{dot,html}. It never generates anything from source first,
7
+ * never writes either JSON input, and never overwrites the current page.
8
+ *
9
+ * The page carries Goal vs Current when the saved current graph is usable; otherwise that mode says
10
+ * why. A missing goal fails with its expected path and how to start one — the current graph is never
11
+ * rendered in its place.
12
+ *
13
+ * `--prepare` is the one explicit, WRITING step: it recomputes the goal's derived levels, self-queue
14
+ * flags, contract queues and maxLevel with the generator's own level machinery, saves the goal, and
15
+ * then views it.
16
+ *
17
+ * Usage: nx run architecture:visualize-runtime-goal [--prepare]
18
+ */
19
+ import type { ExecutorContext } from '@nx/devkit';
20
+ export interface VisualizeRuntimeGoalOptions {
21
+ /** Recompute and SAVE the goal's derived levels before viewing. Viewing alone never writes. */
22
+ prepare?: boolean;
23
+ }
24
+ export interface ExecutorResult {
25
+ success: boolean;
26
+ }
27
+ export default function runExecutor(options: VisualizeRuntimeGoalOptions, context: ExecutorContext): Promise<ExecutorResult>;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ /**
3
+ * Visualize Runtime Goal Executor (#1239)
4
+ *
5
+ * Renders the hand-authored runtime PROPOSAL, architecture/runtime-dependencies-goal.json, with the
6
+ * same shared runtime renderer as visualize-runtime, into its own files:
7
+ * tmp/webpieces/runtime-architecture-goal.{dot,html}. It never generates anything from source first,
8
+ * never writes either JSON input, and never overwrites the current page.
9
+ *
10
+ * The page carries Goal vs Current when the saved current graph is usable; otherwise that mode says
11
+ * why. A missing goal fails with its expected path and how to start one — the current graph is never
12
+ * rendered in its place.
13
+ *
14
+ * `--prepare` is the one explicit, WRITING step: it recomputes the goal's derived levels, self-queue
15
+ * flags, contract queues and maxLevel with the generator's own level machinery, saves the goal, and
16
+ * then views it.
17
+ *
18
+ * Usage: nx run architecture:visualize-runtime-goal [--prepare]
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.default = runExecutor;
22
+ const tslib_1 = require("tslib");
23
+ const fs = tslib_1.__importStar(require("fs"));
24
+ const path = tslib_1.__importStar(require("path"));
25
+ const rules_config_1 = require("@webpieces/rules-config");
26
+ const graph_loader_1 = require("../../lib/graph-loader");
27
+ const graph_impact_1 = require("../../lib/graph-impact");
28
+ const saved_snapshot_1 = require("../../lib/saved-snapshot");
29
+ const runtime_visualizer_1 = require("../../lib/runtime-visualizer");
30
+ const runtime_config_1 = require("../../lib/runtime-config");
31
+ const graph_visualizer_1 = require("../../lib/graph-visualizer");
32
+ const runtime_goal_view_1 = require("../../lib/runtime-goal-view");
33
+ const runtime_goal_file_1 = require("../../lib/runtime-goal-file");
34
+ const toError_1 = require("../../toError");
35
+ // webpieces-disable no-function-outside-class -- Nx executor entry point: Nx requires a default-exported function
36
+ async function runExecutor(options, context) {
37
+ const workspaceRoot = context.root;
38
+ const goalFile = new runtime_goal_file_1.RuntimeGoalFile();
39
+ const snapshot = new saved_snapshot_1.SavedSnapshot();
40
+ console.log('\n🎯 Runtime Goal Visualization\n');
41
+ console.log(new runtime_goal_file_1.RuntimeGoalProvenance().message());
42
+ // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- Nx command rendering boundary; success:false propagates failure to Nx
43
+ try {
44
+ const goal = options.prepare === true ? prepared(goalFile, workspaceRoot) : goalFile.load(workspaceRoot);
45
+ reportDrift(goalFile, goal);
46
+ const config = (0, runtime_config_1.loadRuntimeConfig)(workspaceRoot);
47
+ const projects = fs.existsSync(path.join(workspaceRoot, graph_loader_1.DEFAULT_GRAPH_PATH)) ? snapshot.loadProjects(workspaceRoot, graph_loader_1.DEFAULT_GRAPH_PATH).projects : null;
48
+ const vizOptions = new runtime_visualizer_1.RuntimeVizOptions(config.showExternalNodes, projects, workspaceRoot, runtime_visualizer_1.RuntimePageKind.GOAL);
49
+ const inputs = new runtime_goal_view_1.RuntimeComparisonInputs(snapshot, goalFile);
50
+ const comparison = inputs.view(inputs.current(workspaceRoot), goal, vizOptions);
51
+ console.log(comparison.available ? `Goal vs Current: ${comparison.summary}` : `Goal vs Current unavailable: ${comparison.reason}`);
52
+ const vizPaths = (0, runtime_visualizer_1.writeRuntimeVisualization)(goal, workspaceRoot, 'Goal / Proposed Runtime Architecture', vizOptions, comparison);
53
+ console.log(`✅ Generated: ${vizPaths.dotPath}`);
54
+ console.log(`✅ Generated: ${vizPaths.htmlPath}`);
55
+ if (projects !== null)
56
+ console.log(await new graph_impact_1.ImpactRefresh().run(path.dirname(vizPaths.htmlPath), workspaceRoot, projects, graph_impact_1.VISUALIZE_IMPACT_KINDS));
57
+ else {
58
+ new graph_impact_1.ImpactSidecar().remove(path.dirname(vizPaths.htmlPath));
59
+ console.log('Impact and framework metadata unavailable: no saved project graph. Proposed services carry their goal facts only.');
60
+ }
61
+ console.log('\n🌐 Opening visualization in browser...');
62
+ if (new graph_visualizer_1.GraphVisualizer().openVisualization(vizPaths.htmlPath))
63
+ console.log('✅ Browser opened');
64
+ else
65
+ console.log(`⚠️ Could not auto-open. Open manually: ${vizPaths.htmlPath}`);
66
+ return { success: true };
67
+ }
68
+ catch (err) {
69
+ const error = (0, toError_1.toError)(err);
70
+ const rendered = error instanceof rules_config_1.RuleFailError ? (0, rules_config_1.renderRuleFailForHuman)(error) : error.message;
71
+ console.error(`❌ Runtime goal visualization failed for ${goalFile.goalPath}:`, rendered);
72
+ return { success: false };
73
+ }
74
+ }
75
+ // webpieces-disable no-function-outside-class -- executor step helper, sibling of runExecutor
76
+ function prepared(goalFile, workspaceRoot) {
77
+ const preparation = goalFile.prepare(workspaceRoot);
78
+ if (!preparation.written)
79
+ console.log(`✅ ${goalFile.goalPath} derived facts already consistent; nothing written.`);
80
+ else if (preparation.changes.length === 0)
81
+ console.log(`✍️ Prepared ${goalFile.goalPath}: rewrote explanatory levelBecause text only.`);
82
+ else
83
+ console.log(`✍️ Prepared ${goalFile.goalPath}:\n ${preparation.changes.join('\n ')}`);
84
+ return preparation.graph;
85
+ }
86
+ // webpieces-disable no-function-outside-class -- executor step helper, sibling of runExecutor
87
+ function reportDrift(goalFile, goal) {
88
+ const drift = goalFile.drift(goal);
89
+ if (drift.cycle !== null) {
90
+ console.warn(`⚠️ ${drift.cycle}\n Rendered with its saved levels. ${goalFile.cycleOption().text}`);
91
+ return;
92
+ }
93
+ if (drift.differences.length === 0)
94
+ return;
95
+ console.warn(`⚠️ ${goalFile.goalPath} saves derived facts that disagree with its relationships (rendered as saved):\n ` +
96
+ `${drift.differences.join('\n ')}\n Recompute them explicitly: ${runtime_goal_file_1.RUNTIME_GOAL_PREPARE_COMMAND}`);
97
+ }
98
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/visualize-runtime-goal/executor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Visualize Runtime Goal Executor (#1239)\n *\n * Renders the hand-authored runtime PROPOSAL, architecture/runtime-dependencies-goal.json, with the\n * same shared runtime renderer as visualize-runtime, into its own files:\n * tmp/webpieces/runtime-architecture-goal.{dot,html}. It never generates anything from source first,\n * never writes either JSON input, and never overwrites the current page.\n *\n * The page carries Goal vs Current when the saved current graph is usable; otherwise that mode says\n * why. A missing goal fails with its expected path and how to start one — the current graph is never\n * rendered in its place.\n *\n * `--prepare` is the one explicit, WRITING step: it recomputes the goal's derived levels, self-queue\n * flags, contract queues and maxLevel with the generator's own level machinery, saves the goal, and\n * then views it.\n *\n * Usage: nx run architecture:visualize-runtime-goal [--prepare]\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { ExecutorContext } from '@nx/devkit';\nimport { RuleFailError, renderRuleFailForHuman } from '@webpieces/rules-config';\nimport { DEFAULT_GRAPH_PATH } from '../../lib/graph-loader';\nimport { ImpactRefresh, ImpactSidecar, VISUALIZE_IMPACT_KINDS } from '../../lib/graph-impact';\nimport { SavedSnapshot } from '../../lib/saved-snapshot';\nimport { writeRuntimeVisualization, RuntimeVizOptions, RuntimePageKind } from '../../lib/runtime-visualizer';\nimport { loadRuntimeConfig } from '../../lib/runtime-config';\nimport { GraphVisualizer } from '../../lib/graph-visualizer';\nimport { RuntimeComparisonInputs } from '../../lib/runtime-goal-view';\nimport { RuntimeGoalFile, RuntimeGoalProvenance, RUNTIME_GOAL_PREPARE_COMMAND } from '../../lib/runtime-goal-file';\nimport type { RuntimeGraph } from '../../lib/runtime-graph-model';\nimport { toError } from '../../toError';\n\nexport interface VisualizeRuntimeGoalOptions {\n /** Recompute and SAVE the goal's derived levels before viewing. Viewing alone never writes. */\n prepare?: boolean;\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\n// webpieces-disable no-function-outside-class -- Nx executor entry point: Nx requires a default-exported function\nexport default async function runExecutor(\n options: VisualizeRuntimeGoalOptions,\n context: ExecutorContext,\n): Promise<ExecutorResult> {\n const workspaceRoot = context.root;\n const goalFile = new RuntimeGoalFile();\n const snapshot = new SavedSnapshot();\n\n console.log('\\n🎯 Runtime Goal Visualization\\n');\n console.log(new RuntimeGoalProvenance().message());\n\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- Nx command rendering boundary; success:false propagates failure to Nx\n try {\n const goal = options.prepare === true ? prepared(goalFile, workspaceRoot) : goalFile.load(workspaceRoot);\n reportDrift(goalFile, goal);\n const config = loadRuntimeConfig(workspaceRoot);\n const projects = fs.existsSync(path.join(workspaceRoot, DEFAULT_GRAPH_PATH)) ? snapshot.loadProjects(workspaceRoot, DEFAULT_GRAPH_PATH).projects : null;\n const vizOptions = new RuntimeVizOptions(config.showExternalNodes, projects, workspaceRoot, RuntimePageKind.GOAL);\n const inputs = new RuntimeComparisonInputs(snapshot, goalFile);\n const comparison = inputs.view(inputs.current(workspaceRoot), goal, vizOptions);\n console.log(comparison.available ? `Goal vs Current: ${comparison.summary}` : `Goal vs Current unavailable: ${comparison.reason}`);\n const vizPaths = writeRuntimeVisualization(goal, workspaceRoot, 'Goal / Proposed Runtime Architecture', vizOptions, comparison);\n console.log(`✅ Generated: ${vizPaths.dotPath}`);\n console.log(`✅ Generated: ${vizPaths.htmlPath}`);\n if (projects !== null) console.log(await new ImpactRefresh().run(path.dirname(vizPaths.htmlPath), workspaceRoot, projects, VISUALIZE_IMPACT_KINDS));\n else { new ImpactSidecar().remove(path.dirname(vizPaths.htmlPath)); console.log('Impact and framework metadata unavailable: no saved project graph. Proposed services carry their goal facts only.'); }\n\n console.log('\\n🌐 Opening visualization in browser...');\n if (new GraphVisualizer().openVisualization(vizPaths.htmlPath)) console.log('✅ Browser opened');\n else console.log(`⚠️ Could not auto-open. Open manually: ${vizPaths.htmlPath}`);\n return { success: true };\n } catch (err: unknown) {\n const error = toError(err);\n const rendered = error instanceof RuleFailError ? renderRuleFailForHuman(error) : error.message;\n console.error(`❌ Runtime goal visualization failed for ${goalFile.goalPath}:`, rendered);\n return { success: false };\n }\n}\n\n// webpieces-disable no-function-outside-class -- executor step helper, sibling of runExecutor\nfunction prepared(goalFile: RuntimeGoalFile, workspaceRoot: string): RuntimeGraph {\n const preparation = goalFile.prepare(workspaceRoot);\n if (!preparation.written) console.log(`✅ ${goalFile.goalPath} derived facts already consistent; nothing written.`);\n else if (preparation.changes.length === 0) console.log(`✍️ Prepared ${goalFile.goalPath}: rewrote explanatory levelBecause text only.`);\n else console.log(`✍️ Prepared ${goalFile.goalPath}:\\n ${preparation.changes.join('\\n ')}`);\n return preparation.graph;\n}\n\n// webpieces-disable no-function-outside-class -- executor step helper, sibling of runExecutor\nfunction reportDrift(goalFile: RuntimeGoalFile, goal: RuntimeGraph): void {\n const drift = goalFile.drift(goal);\n if (drift.cycle !== null) {\n console.warn(`⚠️ ${drift.cycle}\\n Rendered with its saved levels. ${goalFile.cycleOption().text}`);\n return;\n }\n if (drift.differences.length === 0) return;\n console.warn(\n `⚠️ ${goalFile.goalPath} saves derived facts that disagree with its relationships (rendered as saved):\\n ` +\n `${drift.differences.join('\\n ')}\\n Recompute them explicitly: ${RUNTIME_GOAL_PREPARE_COMMAND}`,\n );\n}\n"]}
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "title": "Visualize Runtime Goal Executor",
4
+ "description": "View the hand-authored runtime goal (architecture/runtime-dependencies-goal.json) as DOT + HTML, with Goal vs Current. Viewing never writes; --prepare explicitly recomputes the goal's derived levels first.",
5
+ "type": "object",
6
+ "properties": {
7
+ "prepare": {
8
+ "type": "boolean",
9
+ "description": "Recompute and save the goal's derived levels, self-queue flags, contract queues and maxLevel before viewing."
10
+ }
11
+ },
12
+ "required": []
13
+ }
package/src/index.d.ts CHANGED
@@ -28,7 +28,7 @@ export type { ApiDocMode } from './configs/api-doc-rules-config';
28
28
  export { ApiClientPackagesEntry, ApiLibDependenciesConfig, ApiLibPathConfig, FrameworkFolderEntry, FrameworkFolderConfig, ProductDependencyEntry, ProductTagsConfig } from './configs/tag-truth-configs';
29
29
  export { GraphRenderModel, RenderNode, RenderEdge, NodeTags } from './lib/graph-render-model';
30
30
  export { GraphMode, NodeModeDots, LegendFacts, ProductCount } from './lib/graph-color-modes';
31
- export { ProductMembership, RuntimeProductMembership, ProductPalette, ProductColor, ProductBoundary } from './lib/graph-products';
31
+ export { ProductMembership, RuntimeProductMembership, ProductPalette, ProductColor, ProductPaletteSlot, PRODUCT_PALETTE_SLOTS, ProductBoundary, } from './lib/graph-products';
32
32
  export { ProductDependencyMatrix } from './lib/product-dependencies';
33
33
  export { ProductResolver, ProductResolution, PRODUCT_TAG_PREFIX } from './lib/product-resolver';
34
34
  export { EntryPointLevels } from './lib/graph-entry-levels';
package/src/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EntryPointLevels = exports.PRODUCT_TAG_PREFIX = exports.ProductResolution = exports.ProductResolver = exports.ProductDependencyMatrix = exports.ProductBoundary = exports.ProductColor = exports.ProductPalette = exports.RuntimeProductMembership = exports.ProductMembership = exports.ProductCount = exports.LegendFacts = exports.NodeModeDots = exports.GraphMode = exports.NodeTags = exports.RenderEdge = exports.RenderNode = exports.GraphRenderModel = exports.ProductTagsConfig = exports.ProductDependencyEntry = exports.FrameworkFolderConfig = exports.FrameworkFolderEntry = exports.ApiLibPathConfig = exports.ApiLibDependenciesConfig = exports.ApiClientPackagesEntry = exports.ApiRulesForMcpConfig = exports.ApiRulesForOpenApiConfig = exports.API_DOC_MODES = exports.NoRootUnionApiTypeConfig = exports.WiringFormatConfig = exports.ValidateEslintSyncConfig = exports.ValidateVersionsLockedConfig = exports.ValidatePackageJsonConfig = exports.ValidateNoArchitectureCyclesConfig = exports.ValidateArchitectureUnchangedConfig = exports.MissingDesignAnnotationConfig = exports.DiGraphConfig = exports.NxWiringConfig = exports.RuntimeArchitectureConfig = exports.NoFileImportCyclesConfig = exports.STRUCTURAL_MODES = exports.createNodesV2 = void 0;
3
+ exports.EntryPointLevels = exports.PRODUCT_TAG_PREFIX = exports.ProductResolution = exports.ProductResolver = exports.ProductDependencyMatrix = exports.ProductBoundary = exports.PRODUCT_PALETTE_SLOTS = exports.ProductPaletteSlot = exports.ProductColor = exports.ProductPalette = exports.RuntimeProductMembership = exports.ProductMembership = exports.ProductCount = exports.LegendFacts = exports.NodeModeDots = exports.GraphMode = exports.NodeTags = exports.RenderEdge = exports.RenderNode = exports.GraphRenderModel = exports.ProductTagsConfig = exports.ProductDependencyEntry = exports.FrameworkFolderConfig = exports.FrameworkFolderEntry = exports.ApiLibPathConfig = exports.ApiLibDependenciesConfig = exports.ApiClientPackagesEntry = exports.ApiRulesForMcpConfig = exports.ApiRulesForOpenApiConfig = exports.API_DOC_MODES = exports.NoRootUnionApiTypeConfig = exports.WiringFormatConfig = exports.ValidateEslintSyncConfig = exports.ValidateVersionsLockedConfig = exports.ValidatePackageJsonConfig = exports.ValidateNoArchitectureCyclesConfig = exports.ValidateArchitectureUnchangedConfig = exports.MissingDesignAnnotationConfig = exports.DiGraphConfig = exports.NxWiringConfig = exports.RuntimeArchitectureConfig = exports.NoFileImportCyclesConfig = exports.STRUCTURAL_MODES = exports.createNodesV2 = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  tslib_1.__exportStar(require("./lib/graph-generator"), exports);
6
6
  tslib_1.__exportStar(require("./lib/graph-sorter"), exports);
@@ -62,6 +62,8 @@ Object.defineProperty(exports, "ProductMembership", { enumerable: true, get: fun
62
62
  Object.defineProperty(exports, "RuntimeProductMembership", { enumerable: true, get: function () { return graph_products_1.RuntimeProductMembership; } });
63
63
  Object.defineProperty(exports, "ProductPalette", { enumerable: true, get: function () { return graph_products_1.ProductPalette; } });
64
64
  Object.defineProperty(exports, "ProductColor", { enumerable: true, get: function () { return graph_products_1.ProductColor; } });
65
+ Object.defineProperty(exports, "ProductPaletteSlot", { enumerable: true, get: function () { return graph_products_1.ProductPaletteSlot; } });
66
+ Object.defineProperty(exports, "PRODUCT_PALETTE_SLOTS", { enumerable: true, get: function () { return graph_products_1.PRODUCT_PALETTE_SLOTS; } });
65
67
  Object.defineProperty(exports, "ProductBoundary", { enumerable: true, get: function () { return graph_products_1.ProductBoundary; } });
66
68
  var product_dependencies_1 = require("./lib/product-dependencies");
67
69
  Object.defineProperty(exports, "ProductDependencyMatrix", { enumerable: true, get: function () { return product_dependencies_1.ProductDependencyMatrix; } });
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/tooling/nx-webpieces-rules/src/index.ts"],"names":[],"mappings":";;;;AAAA,gEAAsC;AACtC,6DAAmC;AACnC,iEAAuC;AACvC,kEAAwC;AACxC,6DAAmC;AACnC,iEAAuC;AACvC,+DAAqC;AACrC,mEAAyC;AACzC,6EAAmD;AACnD,6DAAmC;AACnC,iEAAuC;AACvC,6DAAmC;AACnC,2EAAiD;AACjD,uEAA6C;AAC7C,qCAAyC;AAChC,8FADA,sBAAa,OACA;AACtB,kBAAe,EAAE,IAAI,EAAE,+BAA+B,EAAE,aAAa,EAAb,sBAAa,EAAE,CAAC;AAExE,uDAAyU;AAAhU,gHAAA,gBAAgB,OAAA;AAAE,wHAAA,wBAAwB,OAAA;AAAE,yHAAA,yBAAyB,OAAA;AAAE,8GAAA,cAAc,OAAA;AAAE,6GAAA,aAAa,OAAA;AAAE,6HAAA,6BAA6B,OAAA;AAAE,mIAAA,mCAAmC,OAAA;AAAE,kIAAA,kCAAkC,OAAA;AAAE,yHAAA,yBAAyB,OAAA;AAAE,4HAAA,4BAA4B,OAAA;AAAE,wHAAA,wBAAwB,OAAA;AAExS,uEAAoE;AAA3D,0HAAA,kBAAkB,OAAA;AAC3B,uEAA0E;AAAjE,gIAAA,wBAAwB,OAAA;AACjC,uEAA+G;AAAtG,qHAAA,aAAa,OAAA;AAAE,gIAAA,wBAAwB,OAAA;AAAE,4HAAA,oBAAoB,OAAA;AAEtE,iEAAyM;AAAhM,2HAAA,sBAAsB,OAAA;AAAE,6HAAA,wBAAwB,OAAA;AAAE,qHAAA,gBAAgB,OAAA;AAAE,yHAAA,oBAAoB,OAAA;AAAE,0HAAA,qBAAqB,OAAA;AAAE,2HAAA,sBAAsB,OAAA;AAAE,sHAAA,iBAAiB,OAAA;AAEnK,+DAA8F;AAArF,sHAAA,gBAAgB,OAAA;AAAE,gHAAA,UAAU,OAAA;AAAE,gHAAA,UAAU,OAAA;AAAE,8GAAA,QAAQ,OAAA;AAC3D,6DAA6F;AAApF,8GAAA,SAAS,OAAA;AAAE,iHAAA,YAAY,OAAA;AAAE,gHAAA,WAAW,OAAA;AAAE,iHAAA,YAAY,OAAA;AAC3D,uDAAkI;AAAzH,mHAAA,iBAAiB,OAAA;AAAE,0HAAA,wBAAwB,OAAA;AAAE,gHAAA,cAAc,OAAA;AAAE,8GAAA,YAAY,OAAA;AAAE,iHAAA,eAAe,OAAA;AACnG,mEAAqE;AAA5D,+HAAA,uBAAuB,OAAA;AAChC,2DAAgG;AAAvF,mHAAA,eAAe,OAAA;AAAE,qHAAA,iBAAiB,OAAA;AAAE,sHAAA,kBAAkB,OAAA;AAC/D,+DAA4D;AAAnD,sHAAA,gBAAgB,OAAA","sourcesContent":["export * from './lib/graph-generator';\nexport * from './lib/graph-sorter';\nexport * from './lib/graph-comparator';\nexport * from './lib/package-validator';\nexport * from './lib/graph-loader';\nexport * from './lib/graph-visualizer';\nexport * from './lib/graph-metadata';\nexport * from './lib/framework-resolver';\nexport * from './lib/runtime-participant-resolver';\nexport * from './lib/project-info';\nexport * from './lib/responsibilities';\nexport * from './lib/di-graph/dot';\nexport * from './lib/di-graph/design-visualizer';\nexport * from './lib/di-graph/design-finder';\nimport { createNodesV2 } from './plugin';\nexport { createNodesV2 };\nexport default { name: '@webpieces/nx-webpieces-rules', createNodesV2 };\n\nexport { STRUCTURAL_MODES, NoFileImportCyclesConfig, RuntimeArchitectureConfig, NxWiringConfig, DiGraphConfig, MissingDesignAnnotationConfig, ValidateArchitectureUnchangedConfig, ValidateNoArchitectureCyclesConfig, ValidatePackageJsonConfig, ValidateVersionsLockedConfig, ValidateEslintSyncConfig } from './configs/rule-configs';\nexport type { StructuralMode } from './configs/rule-configs';\nexport { WiringFormatConfig } from './configs/wiring-format-config';\nexport { NoRootUnionApiTypeConfig } from './configs/no-root-union-config';\nexport { API_DOC_MODES, ApiRulesForOpenApiConfig, ApiRulesForMcpConfig } from './configs/api-doc-rules-config';\nexport type { ApiDocMode } from './configs/api-doc-rules-config';\nexport { ApiClientPackagesEntry, ApiLibDependenciesConfig, ApiLibPathConfig, FrameworkFolderEntry, FrameworkFolderConfig, ProductDependencyEntry, ProductTagsConfig } from './configs/tag-truth-configs';\n\nexport { GraphRenderModel, RenderNode, RenderEdge, NodeTags } from './lib/graph-render-model';\nexport { GraphMode, NodeModeDots, LegendFacts, ProductCount } from './lib/graph-color-modes';\nexport { ProductMembership, RuntimeProductMembership, ProductPalette, ProductColor, ProductBoundary } from './lib/graph-products';\nexport { ProductDependencyMatrix } from './lib/product-dependencies';\nexport { ProductResolver, ProductResolution, PRODUCT_TAG_PREFIX } from './lib/product-resolver';\nexport { EntryPointLevels } from './lib/graph-entry-levels';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/tooling/nx-webpieces-rules/src/index.ts"],"names":[],"mappings":";;;;AAAA,gEAAsC;AACtC,6DAAmC;AACnC,iEAAuC;AACvC,kEAAwC;AACxC,6DAAmC;AACnC,iEAAuC;AACvC,+DAAqC;AACrC,mEAAyC;AACzC,6EAAmD;AACnD,6DAAmC;AACnC,iEAAuC;AACvC,6DAAmC;AACnC,2EAAiD;AACjD,uEAA6C;AAC7C,qCAAyC;AAChC,8FADA,sBAAa,OACA;AACtB,kBAAe,EAAE,IAAI,EAAE,+BAA+B,EAAE,aAAa,EAAb,sBAAa,EAAE,CAAC;AAExE,uDAAyU;AAAhU,gHAAA,gBAAgB,OAAA;AAAE,wHAAA,wBAAwB,OAAA;AAAE,yHAAA,yBAAyB,OAAA;AAAE,8GAAA,cAAc,OAAA;AAAE,6GAAA,aAAa,OAAA;AAAE,6HAAA,6BAA6B,OAAA;AAAE,mIAAA,mCAAmC,OAAA;AAAE,kIAAA,kCAAkC,OAAA;AAAE,yHAAA,yBAAyB,OAAA;AAAE,4HAAA,4BAA4B,OAAA;AAAE,wHAAA,wBAAwB,OAAA;AAExS,uEAAoE;AAA3D,0HAAA,kBAAkB,OAAA;AAC3B,uEAA0E;AAAjE,gIAAA,wBAAwB,OAAA;AACjC,uEAA+G;AAAtG,qHAAA,aAAa,OAAA;AAAE,gIAAA,wBAAwB,OAAA;AAAE,4HAAA,oBAAoB,OAAA;AAEtE,iEAAyM;AAAhM,2HAAA,sBAAsB,OAAA;AAAE,6HAAA,wBAAwB,OAAA;AAAE,qHAAA,gBAAgB,OAAA;AAAE,yHAAA,oBAAoB,OAAA;AAAE,0HAAA,qBAAqB,OAAA;AAAE,2HAAA,sBAAsB,OAAA;AAAE,sHAAA,iBAAiB,OAAA;AAEnK,+DAA8F;AAArF,sHAAA,gBAAgB,OAAA;AAAE,gHAAA,UAAU,OAAA;AAAE,gHAAA,UAAU,OAAA;AAAE,8GAAA,QAAQ,OAAA;AAC3D,6DAA6F;AAApF,8GAAA,SAAS,OAAA;AAAE,iHAAA,YAAY,OAAA;AAAE,gHAAA,WAAW,OAAA;AAAE,iHAAA,YAAY,OAAA;AAC3D,uDAQ8B;AAP1B,mHAAA,iBAAiB,OAAA;AACjB,0HAAA,wBAAwB,OAAA;AACxB,gHAAA,cAAc,OAAA;AACd,8GAAA,YAAY,OAAA;AACZ,oHAAA,kBAAkB,OAAA;AAClB,uHAAA,qBAAqB,OAAA;AACrB,iHAAA,eAAe,OAAA;AAEnB,mEAAqE;AAA5D,+HAAA,uBAAuB,OAAA;AAChC,2DAAgG;AAAvF,mHAAA,eAAe,OAAA;AAAE,qHAAA,iBAAiB,OAAA;AAAE,sHAAA,kBAAkB,OAAA;AAC/D,+DAA4D;AAAnD,sHAAA,gBAAgB,OAAA","sourcesContent":["export * from './lib/graph-generator';\nexport * from './lib/graph-sorter';\nexport * from './lib/graph-comparator';\nexport * from './lib/package-validator';\nexport * from './lib/graph-loader';\nexport * from './lib/graph-visualizer';\nexport * from './lib/graph-metadata';\nexport * from './lib/framework-resolver';\nexport * from './lib/runtime-participant-resolver';\nexport * from './lib/project-info';\nexport * from './lib/responsibilities';\nexport * from './lib/di-graph/dot';\nexport * from './lib/di-graph/design-visualizer';\nexport * from './lib/di-graph/design-finder';\nimport { createNodesV2 } from './plugin';\nexport { createNodesV2 };\nexport default { name: '@webpieces/nx-webpieces-rules', createNodesV2 };\n\nexport { STRUCTURAL_MODES, NoFileImportCyclesConfig, RuntimeArchitectureConfig, NxWiringConfig, DiGraphConfig, MissingDesignAnnotationConfig, ValidateArchitectureUnchangedConfig, ValidateNoArchitectureCyclesConfig, ValidatePackageJsonConfig, ValidateVersionsLockedConfig, ValidateEslintSyncConfig } from './configs/rule-configs';\nexport type { StructuralMode } from './configs/rule-configs';\nexport { WiringFormatConfig } from './configs/wiring-format-config';\nexport { NoRootUnionApiTypeConfig } from './configs/no-root-union-config';\nexport { API_DOC_MODES, ApiRulesForOpenApiConfig, ApiRulesForMcpConfig } from './configs/api-doc-rules-config';\nexport type { ApiDocMode } from './configs/api-doc-rules-config';\nexport { ApiClientPackagesEntry, ApiLibDependenciesConfig, ApiLibPathConfig, FrameworkFolderEntry, FrameworkFolderConfig, ProductDependencyEntry, ProductTagsConfig } from './configs/tag-truth-configs';\n\nexport { GraphRenderModel, RenderNode, RenderEdge, NodeTags } from './lib/graph-render-model';\nexport { GraphMode, NodeModeDots, LegendFacts, ProductCount } from './lib/graph-color-modes';\nexport {\n ProductMembership,\n RuntimeProductMembership,\n ProductPalette,\n ProductColor,\n ProductPaletteSlot,\n PRODUCT_PALETTE_SLOTS,\n ProductBoundary,\n} from './lib/graph-products';\nexport { ProductDependencyMatrix } from './lib/product-dependencies';\nexport { ProductResolver, ProductResolution, PRODUCT_TAG_PREFIX } from './lib/product-resolver';\nexport { EntryPointLevels } from './lib/graph-entry-levels';\n"]}
@@ -36,7 +36,9 @@ export declare enum GraphMode {
36
36
  RUNTIME = "runtime",
37
37
  ARCHITECTURE = "architecture",
38
38
  IMPACT = "impact",
39
- PRODUCT = "product"
39
+ PRODUCT = "product",
40
+ /** Runtime pages only (#1239): the saved goal compared with the saved current graph. */
41
+ GOAL = "goal"
40
42
  }
41
43
  /** One selectable mode as the drawer's Color-by pulldown shows it. */
42
44
  export declare class ModeInfo {
@@ -47,6 +49,11 @@ export declare class ModeInfo {
47
49
  }
48
50
  /** In key order: `1` selects the first, `2` the second, `3` the third, `4` the fourth. */
49
51
  export declare const GRAPH_MODES: readonly ModeInfo[];
52
+ /**
53
+ * The runtime page's Color-by menu: the four shared modes plus Goal vs Current (#1239), key `5`. The
54
+ * build-dependency and DI viewers never list it.
55
+ */
56
+ export declare const RUNTIME_GRAPH_MODES: readonly ModeInfo[];
50
57
  /** Text on a light fill. */
51
58
  export declare const DARK_TEXT = "#1a1c22";
52
59
  /** Text on a dark fill. */
@@ -140,6 +147,13 @@ export declare class LegendFacts {
140
147
  noRuntime: boolean;
141
148
  /** One count per declared product, in palette (sorted-name) order; empty when none is declared. */
142
149
  products: ProductCount[];
150
+ /**
151
+ * The ONE palette every box was painted with (#1244), built over the full declared product set.
152
+ * The legend, the Filter's product chips and the crossing edges read their colors from it, never
153
+ * from a palette of their own: collision resolution depends on the set, so a second palette built
154
+ * from a subset could disagree with the boxes.
155
+ */
156
+ palette: ProductPalette;
143
157
  /** Boxes shared by every product (two or more declared). */
144
158
  sharedByAll: number;
145
159
  /** Boxes in no product. */
@@ -31,7 +31,7 @@
31
31
  * products' boxes; this mode keeps every box and makes ownership visible.
32
32
  */
33
33
  Object.defineProperty(exports, "__esModule", { value: true });
34
- exports.NodeModeStyler = exports.LegendFacts = exports.ProductCount = exports.NodeModeDots = exports.NodeFacts = exports.IMPACT_UNTOUCHED = exports.IMPACT_BUILD_INPUT_BORDER = exports.IMPACT_BUILD_INPUT = exports.IMPACT_AFFECTED = exports.IMPACT_TOUCHED = exports.ROLE_STYLES = exports.RoleStyle = exports.STRIPED_CLASS = exports.NO_RUNTIME_COLOR = exports.FRAMEWORK_ORDER = exports.BASE_ORDER = exports.FRAMEWORK_STYLES = exports.FrameworkStyle = exports.LIGHT_TEXT = exports.DARK_TEXT = exports.GRAPH_MODES = exports.ModeInfo = exports.GraphMode = void 0;
34
+ exports.NodeModeStyler = exports.LegendFacts = exports.ProductCount = exports.NodeModeDots = exports.NodeFacts = exports.IMPACT_UNTOUCHED = exports.IMPACT_BUILD_INPUT_BORDER = exports.IMPACT_BUILD_INPUT = exports.IMPACT_AFFECTED = exports.IMPACT_TOUCHED = exports.ROLE_STYLES = exports.RoleStyle = exports.STRIPED_CLASS = exports.NO_RUNTIME_COLOR = exports.FRAMEWORK_ORDER = exports.BASE_ORDER = exports.FRAMEWORK_STYLES = exports.FrameworkStyle = exports.LIGHT_TEXT = exports.DARK_TEXT = exports.RUNTIME_GRAPH_MODES = exports.GRAPH_MODES = exports.ModeInfo = exports.GraphMode = void 0;
35
35
  const rules_sdk_1 = require("@webpieces/rules-sdk");
36
36
  const dot_syntax_1 = require("./dot-syntax");
37
37
  const graph_products_1 = require("./graph-products");
@@ -41,6 +41,8 @@ var GraphMode;
41
41
  GraphMode["ARCHITECTURE"] = "architecture";
42
42
  GraphMode["IMPACT"] = "impact";
43
43
  GraphMode["PRODUCT"] = "product";
44
+ /** Runtime pages only (#1239): the saved goal compared with the saved current graph. */
45
+ GraphMode["GOAL"] = "goal";
44
46
  })(GraphMode || (exports.GraphMode = GraphMode = {}));
45
47
  /** One selectable mode as the drawer's Color-by pulldown shows it. */
46
48
  class ModeInfo {
@@ -61,6 +63,14 @@ exports.GRAPH_MODES = [
61
63
  new ModeInfo(GraphMode.IMPACT, 'Impact', 'what changed'),
62
64
  new ModeInfo(GraphMode.PRODUCT, 'Product', 'which products it belongs to'),
63
65
  ];
66
+ /**
67
+ * The runtime page's Color-by menu: the four shared modes plus Goal vs Current (#1239), key `5`. The
68
+ * build-dependency and DI viewers never list it.
69
+ */
70
+ exports.RUNTIME_GRAPH_MODES = [
71
+ ...exports.GRAPH_MODES,
72
+ new ModeInfo(GraphMode.GOAL, 'Goal vs Current', 'Current → Goal proposal'),
73
+ ];
64
74
  /** Text on a light fill. */
65
75
  exports.DARK_TEXT = '#1a1c22';
66
76
  /** Text on a dark fill. */
@@ -219,6 +229,13 @@ class LegendFacts {
219
229
  noRuntime = false;
220
230
  /** One count per declared product, in palette (sorted-name) order; empty when none is declared. */
221
231
  products = [];
232
+ /**
233
+ * The ONE palette every box was painted with (#1244), built over the full declared product set.
234
+ * The legend, the Filter's product chips and the crossing edges read their colors from it, never
235
+ * from a palette of their own: collision resolution depends on the set, so a second palette built
236
+ * from a subset could disagree with the boxes.
237
+ */
238
+ palette = new graph_products_1.ProductPalette([]);
222
239
  /** Boxes shared by every product (two or more declared). */
223
240
  sharedByAll = 0;
224
241
  /** Boxes in no product. */
@@ -290,6 +307,7 @@ class NodeModeStyler {
290
307
  }
291
308
  /** The Product section's counts: per product (total, and only-this-product), shared-by-all, none. */
292
309
  recordProducts(legend, facts, palette) {
310
+ legend.palette = palette;
293
311
  if (legend.products.length === 0 && palette.colors.length > 0) {
294
312
  legend.products = palette.names().map((product) => new ProductCount(product, 0, 0));
295
313
  }