@supportpages.io/wtfm 0.0.0-stage → 0.3.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 (275) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +23 -0
  3. package/README.md +392 -2
  4. package/dist/actions.d.ts +98 -0
  5. package/dist/actions.js +86 -0
  6. package/dist/actions.js.map +1 -0
  7. package/dist/agent-settings.d.ts +22 -0
  8. package/dist/agent-settings.js +35 -0
  9. package/dist/agent-settings.js.map +1 -0
  10. package/dist/api.d.ts +14 -0
  11. package/dist/api.js +159 -0
  12. package/dist/api.js.map +1 -0
  13. package/dist/article-link.d.ts +16 -0
  14. package/dist/article-link.js +25 -0
  15. package/dist/article-link.js.map +1 -0
  16. package/dist/artifacts.d.ts +45 -0
  17. package/dist/artifacts.js +144 -0
  18. package/dist/artifacts.js.map +1 -0
  19. package/dist/brand.d.ts +4 -0
  20. package/dist/brand.js +9 -0
  21. package/dist/brand.js.map +1 -0
  22. package/dist/bridge.d.ts +2964 -0
  23. package/dist/bridge.js +1036 -0
  24. package/dist/bridge.js.map +1 -0
  25. package/dist/capacity.d.ts +5 -0
  26. package/dist/capacity.js +11 -0
  27. package/dist/capacity.js.map +1 -0
  28. package/dist/credentials.d.ts +13 -0
  29. package/dist/credentials.js +88 -0
  30. package/dist/credentials.js.map +1 -0
  31. package/dist/development-tls.d.ts +8 -0
  32. package/dist/development-tls.js +38 -0
  33. package/dist/development-tls.js.map +1 -0
  34. package/dist/errors.d.ts +15 -0
  35. package/dist/errors.js +18 -0
  36. package/dist/errors.js.map +1 -0
  37. package/dist/export.d.ts +11 -0
  38. package/dist/export.js +91 -0
  39. package/dist/export.js.map +1 -0
  40. package/dist/hosted-operations.d.ts +108 -0
  41. package/dist/hosted-operations.js +120 -0
  42. package/dist/hosted-operations.js.map +1 -0
  43. package/dist/hosting-benefits.d.ts +66 -0
  44. package/dist/hosting-benefits.js +67 -0
  45. package/dist/hosting-benefits.js.map +1 -0
  46. package/dist/index.d.ts +2 -0
  47. package/dist/index.js +49 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/local-inventory.d.ts +22 -0
  50. package/dist/local-inventory.js +59 -0
  51. package/dist/local-inventory.js.map +1 -0
  52. package/dist/local-setup.d.ts +208 -0
  53. package/dist/local-setup.js +140 -0
  54. package/dist/local-setup.js.map +1 -0
  55. package/dist/pairing.d.ts +71 -0
  56. package/dist/pairing.js +235 -0
  57. package/dist/pairing.js.map +1 -0
  58. package/dist/preferences.d.ts +18 -0
  59. package/dist/preferences.js +44 -0
  60. package/dist/preferences.js.map +1 -0
  61. package/dist/progress.d.ts +205 -0
  62. package/dist/progress.js +224 -0
  63. package/dist/progress.js.map +1 -0
  64. package/dist/reminders.d.ts +31 -0
  65. package/dist/reminders.js +73 -0
  66. package/dist/reminders.js.map +1 -0
  67. package/dist/replace-connection.d.ts +6 -0
  68. package/dist/replace-connection.js +77 -0
  69. package/dist/replace-connection.js.map +1 -0
  70. package/dist/repository-actions.d.ts +18 -0
  71. package/dist/repository-actions.js +9 -0
  72. package/dist/repository-actions.js.map +1 -0
  73. package/dist/repository-benefits.d.ts +96 -0
  74. package/dist/repository-benefits.js +64 -0
  75. package/dist/repository-benefits.js.map +1 -0
  76. package/dist/run-update.d.ts +17 -0
  77. package/dist/run-update.js +27 -0
  78. package/dist/run-update.js.map +1 -0
  79. package/dist/runs.d.ts +541 -0
  80. package/dist/runs.js +146 -0
  81. package/dist/runs.js.map +1 -0
  82. package/dist/runtime.d.ts +12 -0
  83. package/dist/runtime.js +58 -0
  84. package/dist/runtime.js.map +1 -0
  85. package/dist/schema.d.ts +277 -0
  86. package/dist/schema.js +66 -0
  87. package/dist/schema.js.map +1 -0
  88. package/dist/server.d.ts +4 -0
  89. package/dist/server.js +298 -0
  90. package/dist/server.js.map +1 -0
  91. package/dist/session.d.ts +1714 -0
  92. package/dist/session.js +619 -0
  93. package/dist/session.js.map +1 -0
  94. package/dist/settings.d.ts +9 -0
  95. package/dist/settings.js +21 -0
  96. package/dist/settings.js.map +1 -0
  97. package/dist/sync.d.ts +495 -0
  98. package/dist/sync.js +191 -0
  99. package/dist/sync.js.map +1 -0
  100. package/dist/telemetry-scrub.d.ts +13 -0
  101. package/dist/telemetry-scrub.js +51 -0
  102. package/dist/telemetry-scrub.js.map +1 -0
  103. package/dist/telemetry.d.ts +73 -0
  104. package/dist/telemetry.js +173 -0
  105. package/dist/telemetry.js.map +1 -0
  106. package/dist/walkthroughs.d.ts +224 -0
  107. package/dist/walkthroughs.js +109 -0
  108. package/dist/walkthroughs.js.map +1 -0
  109. package/dist/workspace.d.ts +14 -0
  110. package/dist/workspace.js +127 -0
  111. package/dist/workspace.js.map +1 -0
  112. package/dist/writer-agent.d.ts +21 -0
  113. package/dist/writer-agent.js +27 -0
  114. package/dist/writer-agent.js.map +1 -0
  115. package/dist/writer-entry.d.ts +171 -0
  116. package/dist/writer-entry.js +233 -0
  117. package/dist/writer-entry.js.map +1 -0
  118. package/dist/writing-style.d.ts +7 -0
  119. package/dist/writing-style.js +52 -0
  120. package/dist/writing-style.js.map +1 -0
  121. package/engine/SYNC.json +4 -0
  122. package/engine/VERSION +1 -0
  123. package/engine/detect-project/README.md +141 -0
  124. package/engine/detect-project/SKILL.md +1421 -0
  125. package/engine/detect-project/assets/desktop/desktop-frame.css +428 -0
  126. package/engine/detect-project/assets/game/game-frame.css +132 -0
  127. package/engine/detect-project/assets/macosui/LICENSE-puppertino.txt +21 -0
  128. package/engine/detect-project/assets/macosui/VERSIONS.txt +1 -0
  129. package/engine/detect-project/assets/macosui/fonts.css +15 -0
  130. package/engine/detect-project/assets/macosui/macos-frame.css +481 -0
  131. package/engine/detect-project/assets/macosui/puppertino.css +2153 -0
  132. package/engine/detect-project/assets/mobileui/LICENSE-fonts.txt +13 -0
  133. package/engine/detect-project/assets/mobileui/LICENSE-framework7.txt +52 -0
  134. package/engine/detect-project/assets/mobileui/VERSIONS.txt +6 -0
  135. package/engine/detect-project/assets/mobileui/device-frame.css +316 -0
  136. package/engine/detect-project/assets/mobileui/f7-color-theme.mjs +1345 -0
  137. package/engine/detect-project/assets/mobileui/f7-icons-names.json +1254 -0
  138. package/engine/detect-project/assets/mobileui/fonts.css +16 -0
  139. package/engine/detect-project/assets/mobileui/framework7-components.css +39 -0
  140. package/engine/detect-project/assets/mobileui/framework7-core.css +5245 -0
  141. package/engine/detect-project/assets/mobileui/icons.css +31 -0
  142. package/engine/detect-project/assets/mobileui/md3-defaults.css +89 -0
  143. package/engine/detect-project/assets/mobileui/platforms.json +46 -0
  144. package/engine/detect-project/assets/tailwind-fallback.css +1729 -0
  145. package/engine/detect-project/assets/webtui/LICENSE-webtui.txt +28 -0
  146. package/engine/detect-project/assets/webtui/VERSIONS.txt +7 -0
  147. package/engine/detect-project/assets/webtui/terminal-frame.css +195 -0
  148. package/engine/detect-project/assets/webtui/theme-catppuccin.css +1 -0
  149. package/engine/detect-project/assets/webtui/theme-everforest.css +1 -0
  150. package/engine/detect-project/assets/webtui/theme-gruvbox.css +1 -0
  151. package/engine/detect-project/assets/webtui/theme-nord.css +1 -0
  152. package/engine/detect-project/assets/webtui/theme-vitesse.css +1 -0
  153. package/engine/detect-project/assets/webtui/themes.json +37 -0
  154. package/engine/detect-project/assets/webtui/webtui-core.css +1 -0
  155. package/engine/detect-project/assets/win32ui/7css.css +2 -0
  156. package/engine/detect-project/assets/win32ui/LICENSE-7css.txt +21 -0
  157. package/engine/detect-project/assets/win32ui/VERSIONS.txt +1 -0
  158. package/engine/detect-project/assets/win32ui/win32-frame.css +278 -0
  159. package/engine/detect-project/package-lock.json +12 -0
  160. package/engine/detect-project/package.json +10 -0
  161. package/engine/detect-project/scripts/apply_runtime_profiles.js +313 -0
  162. package/engine/detect-project/scripts/check_css_health.js +412 -0
  163. package/engine/detect-project/scripts/check_project_map.js +150 -0
  164. package/engine/detect-project/scripts/check_runtime_coverage.js +311 -0
  165. package/engine/detect-project/scripts/check_runtime_recipe_quality.js +184 -0
  166. package/engine/detect-project/scripts/classify_app_type.sh +246 -0
  167. package/engine/detect-project/scripts/classify_surface.sh +95 -0
  168. package/engine/detect-project/scripts/classify_workspace.js +39 -0
  169. package/engine/detect-project/scripts/compile_css.sh +447 -0
  170. package/engine/detect-project/scripts/detect_static.js +645 -0
  171. package/engine/detect-project/scripts/detect_structure.js +187 -0
  172. package/engine/detect-project/scripts/include_census.js +451 -0
  173. package/engine/detect-project/scripts/json_get.js +142 -0
  174. package/engine/detect-project/scripts/merge_json.js +52 -0
  175. package/engine/detect-project/scripts/recommend_model_tier.js +252 -0
  176. package/engine/detect-project/scripts/resolve_route_chains.js +135 -0
  177. package/engine/detect-project/scripts/run_css_build.sh +40 -0
  178. package/engine/detect-project/scripts/sanitize_css.js +83 -0
  179. package/engine/detect-project/scripts/test_classify_surface.js +108 -0
  180. package/engine/detect-project/scripts/test_node_helpers.js +142 -0
  181. package/engine/detect-project/scripts/test_recommend_model_tier.js +119 -0
  182. package/engine/detect-project/scripts/test_resolve_route_chains.js +182 -0
  183. package/engine/detect-project/scripts/test_runtime_coverage.js +323 -0
  184. package/engine/detect-project/scripts/test_runtime_recipe_quality.js +187 -0
  185. package/engine/detect-project/scripts/theme_overrides.js +169 -0
  186. package/engine/detect-project/scripts/write_branding.js +129 -0
  187. package/engine/generate-illustrated-article/SKILL.md +461 -0
  188. package/engine/generate-illustrated-article/contracts/desktop.md +90 -0
  189. package/engine/generate-illustrated-article/contracts/game.md +38 -0
  190. package/engine/generate-illustrated-article/contracts/label-evidence.md +38 -0
  191. package/engine/generate-illustrated-article/contracts/macos.md +79 -0
  192. package/engine/generate-illustrated-article/contracts/mobile.md +40 -0
  193. package/engine/generate-illustrated-article/contracts/terminal.md +29 -0
  194. package/engine/generate-illustrated-article/contracts/win32.md +43 -0
  195. package/engine/generate-illustrated-article/package-lock.json +366 -0
  196. package/engine/generate-illustrated-article/package.json +15 -0
  197. package/engine/generate-illustrated-article/scripts/article_blocks.js +34 -0
  198. package/engine/generate-illustrated-article/scripts/check_article_json.js +105 -0
  199. package/engine/generate-illustrated-article/scripts/emit_walkthrough_signals.js +100 -0
  200. package/engine/generate-illustrated-article/scripts/extract_images.js +187 -0
  201. package/engine/generate-illustrated-article/scripts/generate_content_images.js +376 -0
  202. package/engine/generate-illustrated-article/scripts/include_census.js +451 -0
  203. package/engine/generate-illustrated-article/scripts/inject_assets.js +1691 -0
  204. package/engine/generate-illustrated-article/scripts/jit_mockup_css.js +191 -0
  205. package/engine/generate-illustrated-article/scripts/label_evidence.js +87 -0
  206. package/engine/generate-illustrated-article/scripts/lint_article_copy.js +252 -0
  207. package/engine/generate-illustrated-article/scripts/lint_mockup_fidelity.js +2403 -0
  208. package/engine/generate-illustrated-article/scripts/polish_tickets.js +1148 -0
  209. package/engine/generate-illustrated-article/scripts/related_repos.sh +52 -0
  210. package/engine/generate-illustrated-article/scripts/render_all.js +177 -0
  211. package/engine/generate-illustrated-article/scripts/render_mockup.js +665 -0
  212. package/engine/generate-illustrated-article/scripts/render_ready.js +164 -0
  213. package/engine/generate-illustrated-article/scripts/resolve_workspace.sh +86 -0
  214. package/engine/generate-illustrated-article/scripts/runtime_region_geometry.js +55 -0
  215. package/engine/generate-illustrated-article/scripts/source_paths.js +49 -0
  216. package/engine/generate-illustrated-article/scripts/test_control_visibility.js +30 -0
  217. package/engine/generate-illustrated-article/scripts/test_emit_walkthrough_signals.js +157 -0
  218. package/engine/generate-illustrated-article/scripts/test_generate_content_images.js +168 -0
  219. package/engine/generate-illustrated-article/scripts/test_include_census.js +126 -0
  220. package/engine/generate-illustrated-article/scripts/test_label_evidence.js +49 -0
  221. package/engine/generate-illustrated-article/scripts/test_lint_article_copy.js +138 -0
  222. package/engine/generate-illustrated-article/scripts/test_lint_mockup_fidelity.js +653 -0
  223. package/engine/generate-illustrated-article/scripts/test_node_ports.js +152 -0
  224. package/engine/generate-illustrated-article/scripts/test_polish_tickets.js +481 -0
  225. package/engine/generate-illustrated-article/scripts/test_related_repos.js +64 -0
  226. package/engine/generate-illustrated-article/scripts/test_render_ready.js +85 -0
  227. package/engine/generate-illustrated-article/scripts/test_source_paths.js +68 -0
  228. package/engine/generate-illustrated-article/scripts/trace_hook.js +79 -0
  229. package/engine/generate-illustrated-article/scripts/trace_hook.sh +4 -0
  230. package/engine/generate-illustrated-article/scripts/validate_html.js +114 -0
  231. package/engine/generate-illustrated-article/scripts/watermark.js +69 -0
  232. package/install.sh +14 -0
  233. package/package.json +57 -4
  234. package/scripts/auth.mjs +33 -0
  235. package/scripts/auto-update.mjs +7 -0
  236. package/scripts/build-plugin.mjs +58 -0
  237. package/scripts/build-release.mjs +94 -0
  238. package/scripts/check-release.mjs +40 -0
  239. package/scripts/check-runtime.mjs +10 -0
  240. package/scripts/cli.mjs +8 -0
  241. package/scripts/install.mjs +64 -0
  242. package/scripts/lib/agent-runner.mjs +181 -0
  243. package/scripts/lib/agent-settings.mjs +215 -0
  244. package/scripts/lib/article-skills.mjs +82 -0
  245. package/scripts/lib/auto-update.mjs +50 -0
  246. package/scripts/lib/brand.mjs +9 -0
  247. package/scripts/lib/browser.mjs +12 -0
  248. package/scripts/lib/claude-connection.mjs +33 -0
  249. package/scripts/lib/claude-permissions.mjs +47 -0
  250. package/scripts/lib/claude-plugin.mjs +15 -0
  251. package/scripts/lib/claude-writer.mjs +10 -0
  252. package/scripts/lib/cli-main.mjs +85 -0
  253. package/scripts/lib/cli.mjs +888 -0
  254. package/scripts/lib/codex-config.mjs +51 -0
  255. package/scripts/lib/codex-integration.mjs +61 -0
  256. package/scripts/lib/codex-skill.mjs +34 -0
  257. package/scripts/lib/harness-models.mjs +109 -0
  258. package/scripts/lib/install.mjs +269 -0
  259. package/scripts/lib/managed-writer.mjs +38 -0
  260. package/scripts/lib/planning.mjs +263 -0
  261. package/scripts/lib/prepare-update.mjs +85 -0
  262. package/scripts/lib/refresh-writers.mjs +12 -0
  263. package/scripts/lib/remove.mjs +167 -0
  264. package/scripts/lib/renderer.mjs +34 -0
  265. package/scripts/lib/terminal.mjs +252 -0
  266. package/scripts/lib/uninit.mjs +72 -0
  267. package/scripts/lib/update.mjs +55 -0
  268. package/scripts/lib/writer-recovery.mjs +35 -0
  269. package/scripts/lib/yolo.mjs +362 -0
  270. package/scripts/plugin-session.mjs +65 -0
  271. package/scripts/prepare-update.mjs +12 -0
  272. package/scripts/publish-release.mjs +92 -0
  273. package/scripts/skills/supportpages/SKILL.md +120 -0
  274. package/scripts/smoke-release.mjs +101 -0
  275. package/server.json +27 -0
@@ -0,0 +1,169 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /*
5
+ * theme_overrides.js — Given detection JSON + framework name, emit theme-aware
6
+ * CSS overrides (CSS custom properties + component class overrides) on stdout.
7
+ *
8
+ * When source compilation fails and we fall back to a framework CDN, the
9
+ * vanilla CDN doesn't know about the project's brand colours. This script
10
+ * generates the targeted overrides so things like .btn-primary, --bs-primary,
11
+ * and font-family settings render with the detected theme.
12
+ *
13
+ * Usage: node theme_overrides.js <detection_json> <framework>
14
+ * — writes the override CSS to stdout
15
+ */
16
+
17
+ const fs = require('fs');
18
+
19
+ /** Python-style truthiness: empty strings, arrays and objects are false. */
20
+ function truthy(value) {
21
+ if (Array.isArray(value)) return value.length > 0;
22
+ if (value !== null && typeof value === 'object') return Object.keys(value).length > 0;
23
+ return Boolean(value);
24
+ }
25
+
26
+ function orEmpty(value) {
27
+ return truthy(value) ? value : {};
28
+ }
29
+
30
+ function hexToRgb(hex) {
31
+ const h = String(hex).replace(/^#+/, '');
32
+ if (h.length !== 6) return [0, 0, 0];
33
+ // Throw on non-hex digits, as the caller treats a failed run as "no overrides".
34
+ return [0, 2, 4].map(i => {
35
+ const pair = h.slice(i, i + 2);
36
+ if (!/^[0-9a-fA-F]{2}$/.test(pair)) throw new Error(`invalid hex colour: ${hex}`);
37
+ return parseInt(pair, 16);
38
+ });
39
+ }
40
+
41
+ function isValid(value) {
42
+ return truthy(value) && value !== 'null' && value !== 'None';
43
+ }
44
+
45
+ function overrideCss(detect, framework) {
46
+ // Detection JSON may have theme tokens at the top level (skill convention)
47
+ // OR nested under theme_overrides (analyzer convention). Support both.
48
+ const overrides = detect.theme_overrides ?? {};
49
+ const colors = { ...orEmpty(overrides.colors) };
50
+ const custom = orEmpty(overrides.custom_colors);
51
+ const fonts = orEmpty(overrides.fonts);
52
+ const radius = overrides.border_radius;
53
+
54
+ // Skill-style fallback: pick up default_colors + scss_vars from top level
55
+ if (!truthy(colors)) {
56
+ const dc = orEmpty(detect.default_colors);
57
+ // Translate {primary, accent} → {primary, secondary}
58
+ if (truthy(dc.primary)) colors.primary = dc.primary;
59
+ if (truthy(dc.accent)) colors.secondary = dc.accent;
60
+ const sv = orEmpty(detect.scss_vars);
61
+ for (const key of ['success', 'danger', 'warning', 'info', 'body-color']) {
62
+ if (truthy(sv[key])) colors[key.replaceAll('-', '_')] = sv[key];
63
+ }
64
+ }
65
+
66
+ const bodyFont = fonts.body;
67
+ const headingFont = fonts.heading;
68
+ const lines = ['', '/* Theme overrides from project variables */', ':root {'];
69
+
70
+ if (framework === 'bootstrap') {
71
+ for (const [name, val] of Object.entries(colors)) {
72
+ if (!isValid(val)) continue;
73
+ const [r, g, b] = hexToRgb(val);
74
+ lines.push(` --bs-${name}: ${val};`);
75
+ lines.push(` --bs-${name}-rgb: ${r}, ${g}, ${b};`);
76
+ }
77
+ if (isValid(bodyFont)) lines.push(` --bs-body-font-family: ${bodyFont};`);
78
+ if (isValid(headingFont)) lines.push(` --bs-heading-font-family: ${headingFont};`);
79
+ if (isValid(radius)) lines.push(` --bs-border-radius: ${radius};`);
80
+ lines.push('}');
81
+
82
+ for (const [name, val] of Object.entries(custom)) {
83
+ if (!isValid(val)) continue;
84
+ const safe = name.replaceAll('_', '-');
85
+ lines.push(`.text-${safe} { color: ${val} !important; }`);
86
+ lines.push(`.bg-${safe} { background-color: ${val} !important; }`);
87
+ }
88
+
89
+ const primary = colors.primary;
90
+ const secondary = colors.secondary;
91
+ if (isValid(primary)) {
92
+ lines.push(`.btn-primary { background-color: ${primary}; border-color: ${primary}; }`);
93
+ lines.push(`.btn-primary:hover { background-color: ${primary}; border-color: ${primary}; opacity: 0.9; }`);
94
+ lines.push(`.btn-outline-primary { color: ${primary}; border-color: ${primary}; }`);
95
+ lines.push(`.btn-outline-primary:hover { background-color: ${primary}; border-color: ${primary}; color: #fff; }`);
96
+ lines.push(`a { color: ${primary}; }`);
97
+ lines.push(`.text-primary { color: ${primary} !important; }`);
98
+ lines.push(`.bg-primary { background-color: ${primary} !important; }`);
99
+ }
100
+ if (isValid(secondary)) {
101
+ lines.push(`.btn-secondary { background-color: ${secondary}; border-color: ${secondary}; }`);
102
+ }
103
+ } else if (framework === 'tailwind') {
104
+ for (const [name, val] of Object.entries(colors)) {
105
+ if (isValid(val)) lines.push(` --color-${name}: ${val};`);
106
+ }
107
+ if (isValid(bodyFont)) lines.push(` font-family: ${bodyFont};`);
108
+ if (isValid(headingFont)) lines.push(` --font-heading: ${headingFont};`);
109
+ if (isValid(radius)) lines.push(` --radius: ${radius};`);
110
+ lines.push('}');
111
+
112
+ if (isValid(headingFont)) lines.push(`h1, h2, h3, h4, h5, h6 { font-family: ${headingFont}; }`);
113
+
114
+ for (const [name, val] of Object.entries({ ...colors, ...custom })) {
115
+ if (!isValid(val)) continue;
116
+ const safe = name.replaceAll('_', '-');
117
+ lines.push(`.text-${safe} { color: ${val}; }`);
118
+ lines.push(`.bg-${safe} { background-color: ${val}; }`);
119
+ }
120
+ } else {
121
+ // Generic: plain CSS custom properties + utility classes
122
+ for (const [name, val] of Object.entries(colors)) {
123
+ if (isValid(val)) lines.push(` --color-${name}: ${val};`);
124
+ }
125
+ if (isValid(bodyFont)) lines.push(` font-family: ${bodyFont};`);
126
+ if (isValid(headingFont)) lines.push(` --font-heading: ${headingFont};`);
127
+ if (isValid(radius)) lines.push(` --border-radius: ${radius};`);
128
+ lines.push('}');
129
+
130
+ for (const [name, val] of Object.entries(custom)) {
131
+ if (!isValid(val)) continue;
132
+ const safe = name.replaceAll('_', '-');
133
+ lines.push(`.text-${safe} { color: ${val} !important; }`);
134
+ lines.push(`.bg-${safe} { background-color: ${val} !important; }`);
135
+ }
136
+ }
137
+
138
+ let out = lines.join('\n') + '\n';
139
+
140
+ // Append sanitized extra_css if detection captured any
141
+ const extra = overrides.extra_css ?? '';
142
+ if (isValid(extra)) {
143
+ const badPatterns = [
144
+ /^@tailwind\b/, /^@theme\b/, /^@plugin\b/, /^@custom-variant\b/,
145
+ /^@apply\b/, /^@config\b/, /^@source\b/, /^@utility\b/,
146
+ /^@layer\b/, /^@import\s+["']tailwindcss/,
147
+ ];
148
+ const clean = String(extra).split('\n')
149
+ .filter(line => !badPatterns.some(pattern => pattern.test(line.trim())))
150
+ .join('\n').trim();
151
+ if (clean) out += `\n/* Extra project overrides */\n${clean}\n`;
152
+ }
153
+
154
+ return out;
155
+ }
156
+
157
+ function main() {
158
+ if (process.argv.length !== 4) {
159
+ process.stderr.write('Usage: theme_overrides.js <detection_json> <framework>\n');
160
+ process.exit(1);
161
+ }
162
+ const [detectPath, framework] = process.argv.slice(2);
163
+ const detect = JSON.parse(fs.readFileSync(detectPath, 'utf8'));
164
+ process.stdout.write(overrideCss(detect, framework));
165
+ }
166
+
167
+ if (require.main === module) main();
168
+
169
+ module.exports = { overrideCss };
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /*
5
+ * write_branding.js — write or patch branding.json for each app type, so the
6
+ * detect-project steps need no inline Python.
7
+ *
8
+ * Usage:
9
+ * node write_branding.js web <brand_dir> <compilation_method> <css_bytes>
10
+ * (merges <brand_dir>/branding-detect.json into <brand_dir>/branding.json)
11
+ * node write_branding.js terminal <branding.json> <theme_attr> <background> <accent> <css_bytes>
12
+ * node write_branding.js mobile <branding.json> <platform> <platform_attr> <primary> <background> <css_bytes>
13
+ * node write_branding.js desktop <branding.json> <platform> <window_chrome> <css_bytes> (patch)
14
+ * node write_branding.js win32 <branding.json> <css_bytes>
15
+ * node write_branding.js macos <branding.json> <css_bytes>
16
+ * node write_branding.js game <branding.json> <engine> <logical_w> <logical_h> <display_w> <display_h> <css_bytes> (patch)
17
+ */
18
+
19
+ const fs = require('fs');
20
+ const path = require('path');
21
+
22
+ function int(value, name) {
23
+ const text = String(value ?? '').trim();
24
+ if (!/^-?\d+$/.test(text)) throw new Error(`${name} must be an integer, got "${value}"`);
25
+ return Number(text);
26
+ }
27
+
28
+ function readJson(file) {
29
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
30
+ }
31
+
32
+ function writeJson(file, value) {
33
+ fs.writeFileSync(file, JSON.stringify(value, null, 2));
34
+ }
35
+
36
+ function now() {
37
+ return new Date().toISOString();
38
+ }
39
+
40
+ const MODES = {
41
+ web: ([brandDir, method, cssBytes]) => {
42
+ const result = { ...readJson(path.join(brandDir, 'branding-detect.json')) };
43
+ result.compiled_css_path = 'branding.css';
44
+ result.compilation_method = method;
45
+ result.compiled_css_bytes = int(cssBytes, 'css_bytes');
46
+ result.generated_at = now().replace(/\.\d{3}Z$/, 'Z');
47
+ return [path.join(brandDir, 'branding.json'), result];
48
+ },
49
+ terminal: ([file, attr, background, accent, cssBytes]) => [file, {
50
+ framework: 'terminal',
51
+ app_type: 'terminal',
52
+ compiled_css_path: 'branding.css',
53
+ compilation_method: 'webtui_vendored',
54
+ compiled_css_bytes: int(cssBytes, 'css_bytes'),
55
+ terminal_theme: attr,
56
+ default_colors: { primary: accent, background },
57
+ generated_at: now(),
58
+ }],
59
+ mobile: ([file, platform, attr, primary, background, cssBytes]) => [file, {
60
+ framework: 'mobile',
61
+ app_type: 'mobile',
62
+ compiled_css_path: 'branding.css',
63
+ compilation_method: 'framework7_vendored',
64
+ compiled_css_bytes: int(cssBytes, 'css_bytes'),
65
+ platform,
66
+ platform_attr: attr,
67
+ mobile_theme: 'light',
68
+ default_colors: { primary, background },
69
+ generated_at: now(),
70
+ }],
71
+ desktop: ([file, platform, chrome, cssBytes]) => {
72
+ const branding = readJson(file);
73
+ branding.app_type = 'desktop';
74
+ branding.platform = platform; // macos | windows
75
+ branding.window_chrome = chrome; // native | hybrid | custom (main window)
76
+ branding.compiled_css_bytes = int(cssBytes, 'css_bytes');
77
+ return [file, branding];
78
+ },
79
+ win32: ([file, cssBytes]) => [file, {
80
+ framework: 'win32',
81
+ app_type: 'win32',
82
+ compiled_css_path: 'branding.css',
83
+ compilation_method: '7css_vendored',
84
+ compiled_css_bytes: int(cssBytes, 'css_bytes'),
85
+ platform: 'windows',
86
+ default_colors: { primary: '#3399ff', background: '#f0f0f0', confidence: 'low' },
87
+ generated_at: now(),
88
+ }],
89
+ macos: ([file, cssBytes]) => [file, {
90
+ framework: 'macos',
91
+ app_type: 'macos',
92
+ compiled_css_path: 'branding.css',
93
+ compilation_method: 'puppertino_vendored',
94
+ compiled_css_bytes: int(cssBytes, 'css_bytes'),
95
+ platform: 'macos',
96
+ default_colors: { primary: '#007aff', background: '#f6f6f6', confidence: 'low' },
97
+ generated_at: now(),
98
+ }],
99
+ game: ([file, engine, lw, lh, dw, dh, cssBytes]) => {
100
+ const branding = readJson(file);
101
+ branding.app_type = 'game';
102
+ branding.engine = engine;
103
+ branding.canvas_size = { width: int(lw, 'logical_w'), height: int(lh, 'logical_h') };
104
+ branding.display_size = { width: int(dw, 'display_w'), height: int(dh, 'display_h') };
105
+ branding.compiled_css_bytes = int(cssBytes, 'css_bytes');
106
+ return [file, branding];
107
+ },
108
+ };
109
+
110
+ const ARITY = { web: 3, terminal: 5, mobile: 6, desktop: 4, win32: 2, macos: 2, game: 7 };
111
+
112
+ function main(argv) {
113
+ const [mode, ...args] = argv;
114
+ if (!MODES[mode] || args.length !== ARITY[mode]) {
115
+ process.stderr.write('Usage: write_branding.js <web|terminal|mobile|desktop|win32|macos|game> <args…> (see the header)\n');
116
+ return 2;
117
+ }
118
+ const [file, value] = MODES[mode](args);
119
+ writeJson(file, value);
120
+ return 0;
121
+ }
122
+
123
+ if (require.main === module) {
124
+ try { process.exitCode = main(process.argv.slice(2)); }
125
+ catch (error) {
126
+ process.stderr.write(`write_branding: ${error.message}\n`);
127
+ process.exitCode = 1;
128
+ }
129
+ }