@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,447 @@
1
+ #!/bin/bash
2
+ # compile_css.sh — Attempt to compile a project's CSS from source using its
3
+ # own build tools (tailwindcss, sass, postcss). Falls back to CDN download +
4
+ # synthesised theme overrides + Tailwind utility fallback if source compilation
5
+ # fails.
6
+ #
7
+ # Takes arbitrary project / output paths, so it runs the same way in a local
8
+ # checkout and in a container.
9
+ #
10
+ # Usage:
11
+ # compile_css.sh <project_dir> <detection_json> <output_css_path>
12
+ #
13
+ # Exit codes:
14
+ # 0 — CSS produced (via source compilation, CDN, or fallback synthesis)
15
+ # Method written to <output_css_path>.method.txt
16
+ # 1 — total failure (no CSS produced)
17
+
18
+ set -e
19
+
20
+ PROJECT_DIR="$1"
21
+ DETECT_JSON="$2"
22
+ OUTPUT_CSS="$3"
23
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
24
+
25
+ if [ -z "$PROJECT_DIR" ] || [ -z "$DETECT_JSON" ] || [ -z "$OUTPUT_CSS" ]; then
26
+ echo "Usage: compile_css.sh <project_dir> <detection_json> <output_css_path>" >&2
27
+ exit 1
28
+ fi
29
+ if [ ! -d "$PROJECT_DIR" ]; then
30
+ echo "Error: project_dir does not exist: $PROJECT_DIR" >&2
31
+ exit 1
32
+ fi
33
+ if [ ! -f "$DETECT_JSON" ]; then
34
+ echo "Error: detection_json not found: $DETECT_JSON" >&2
35
+ exit 1
36
+ fi
37
+
38
+ _timeout() {
39
+ if command -v gtimeout &>/dev/null; then
40
+ gtimeout "$@"
41
+ elif command -v timeout &>/dev/null; then
42
+ timeout "$@"
43
+ else
44
+ # No timeout command available — just run it
45
+ shift
46
+ "$@"
47
+ fi
48
+ }
49
+
50
+ # Parse the detection JSON for the fields we need.
51
+ FRAMEWORK=$(node "$SCRIPT_DIR/json_get.js" "$DETECT_JSON" framework none 2>/dev/null || echo "none")
52
+ FRAMEWORK="${FRAMEWORK%%+*}" # primary framework if hybrid
53
+ VERSION=$(node "$SCRIPT_DIR/json_get.js" "$DETECT_JSON" framework_version "" 2>/dev/null || echo "")
54
+ [ -n "$VERSION" ] || VERSION=$(node "$SCRIPT_DIR/json_get.js" "$DETECT_JSON" version "" 2>/dev/null || echo "")
55
+ SCSS_ENTRY=$(node "$SCRIPT_DIR/json_get.js" "$DETECT_JSON" scss_entry "" 2>/dev/null)
56
+ TW_ENTRY=$(node "$SCRIPT_DIR/json_get.js" "$DETECT_JSON" tailwind_entry "" 2>/dev/null)
57
+ TW_CONFIG=$(node "$SCRIPT_DIR/json_get.js" "$DETECT_JSON" tailwind_config "" 2>/dev/null)
58
+ POSTCSS_CONFIG=$(node "$SCRIPT_DIR/json_get.js" "$DETECT_JSON" postcss_config "" 2>/dev/null)
59
+
60
+ # Derive scss/tailwind entries from sources if not explicit. Includes
61
+ # bundler-pipeline entries (webpacker/shakapacker/vite put the @tailwind +
62
+ # custom @apply component layer in app/javascript or app/frontend, often as
63
+ # .scss) — these hold the project's own component classes (e.g. .base-input),
64
+ # so finding the real entry beats synthesizing a bare one that omits them.
65
+ if [ -z "$TW_ENTRY" ] && [ "$FRAMEWORK" = "tailwind" ]; then
66
+ for candidate in \
67
+ app/assets/tailwind/application.css \
68
+ app/assets/tailwind/index.css \
69
+ app/javascript/application.css \
70
+ app/javascript/application.scss \
71
+ app/javascript/packs/application.css \
72
+ app/javascript/packs/application.scss \
73
+ app/javascript/stylesheets/application.css \
74
+ app/javascript/stylesheets/application.scss \
75
+ app/frontend/entrypoints/application.css \
76
+ app/frontend/entrypoints/application.scss \
77
+ app/frontend/stylesheets/application.css \
78
+ src/index.css \
79
+ src/styles/globals.css \
80
+ src/styles/main.css \
81
+ styles/globals.css \
82
+ styles/main.css \
83
+ app/globals.css; do
84
+ if [ -f "$PROJECT_DIR/$candidate" ]; then
85
+ TW_ENTRY="$candidate"
86
+ break
87
+ fi
88
+ done
89
+ fi
90
+
91
+ # Same fallback for SCSS — covers projects where detection JSON didn't capture
92
+ # the scss_entry (older detector runs, weird webpacker setups, etc.)
93
+ if [ -z "$SCSS_ENTRY" ]; then
94
+ for candidate in \
95
+ app/frontend/packs/application.scss \
96
+ app/frontend/styling/application.scss \
97
+ app/javascript/packs/application.scss \
98
+ app/assets/stylesheets/application.scss \
99
+ app/assets/stylesheets/application.sass \
100
+ src/styles/main.scss \
101
+ src/styles/application.scss \
102
+ src/styles/globals.scss \
103
+ src/main.scss \
104
+ src/index.scss \
105
+ styles/main.scss; do
106
+ if [ -f "$PROJECT_DIR/$candidate" ]; then
107
+ SCSS_ENTRY="$candidate"
108
+ break
109
+ fi
110
+ done
111
+ fi
112
+
113
+ # Detect package manager
114
+ PKG_MGR="npm"
115
+ if [ -f "$PROJECT_DIR/yarn.lock" ] && command -v yarn &>/dev/null; then
116
+ PKG_MGR="yarn"
117
+ elif [ -f "$PROJECT_DIR/pnpm-lock.yaml" ] && command -v pnpm &>/dev/null; then
118
+ PKG_MGR="pnpm"
119
+ fi
120
+
121
+ COMPILE_METHOD="none"
122
+ > "$OUTPUT_CSS"
123
+
124
+ # ─── Helpers ─────────────────────────────────────────────────────────────────
125
+
126
+ # Many projects commit their fully-compiled stylesheet: tailwindcss-rails writes
127
+ # app/assets/builds/tailwind.css, cssbundling-rails writes app/assets/builds/*.css.
128
+ # That artifact is the real build the app actually ships — every utility the
129
+ # views use is already in it — so it's both more reliable than recompiling in the
130
+ # container (no npm/network/CLI-version roulette; tailwindcss-rails has no node
131
+ # tailwind dependency to compile against at all) and more faithful than the
132
+ # utility fallback. Prefer it whenever a non-trivial one exists.
133
+ try_prebuilt_css() {
134
+ local f found="" size dir
135
+ # Named build outputs across frameworks: Rails (tailwindcss-/cssbundling-rails),
136
+ # Phoenix (priv/static/assets), Vite (dist/assets), esbuild/cssbundling (public).
137
+ for f in app/assets/builds/tailwind.css \
138
+ app/assets/builds/application.css \
139
+ app/assets/builds/application.tailwind.css \
140
+ priv/static/assets/app.css \
141
+ priv/static/assets/css/app.css \
142
+ public/assets/application.css \
143
+ public/build/assets/app.css \
144
+ dist/assets/index.css \
145
+ dist/index.css; do
146
+ if [ -f "$PROJECT_DIR/$f" ] && [ "$(wc -c < "$PROJECT_DIR/$f")" -gt 5000 ]; then
147
+ found="$f"; break
148
+ fi
149
+ done
150
+ # Otherwise take the largest non-vendor stylesheet in any known build dir
151
+ # (handles hashed/non-standard names from cssbundling, Vite, Next, esbuild).
152
+ if [ -z "$found" ]; then
153
+ for dir in app/assets/builds priv/static/assets priv/static/assets/css \
154
+ dist/assets dist .next/static/css \
155
+ public/assets public/build public/build/assets public/css static/css; do
156
+ [ -d "$PROJECT_DIR/$dir" ] || continue
157
+ for f in "$PROJECT_DIR/$dir"/*.css; do
158
+ [ -f "$f" ] || continue
159
+ case "$(basename "$f")" in *vendor*|*chunk*|*runtime*) continue ;; esac
160
+ [ "$(wc -c < "$f")" -gt 5000 ] || continue
161
+ if [ -z "$found" ] || [ "$(wc -c < "$f")" -gt "$(wc -c < "$PROJECT_DIR/$found")" ]; then
162
+ found="${f#"$PROJECT_DIR"/}"
163
+ fi
164
+ done
165
+ done
166
+ fi
167
+ [ -z "$found" ] && return 1
168
+
169
+ size=$(wc -c < "$PROJECT_DIR/$found")
170
+ echo " Pre-built CSS: $found ($size bytes)" >&2
171
+ cat "$PROJECT_DIR/$found" > "$OUTPUT_CSS"
172
+ echo "" >> "$OUTPUT_CSS"
173
+ COMPILE_METHOD="prebuilt"
174
+ return 0
175
+ }
176
+
177
+ # Pick a Tailwind config to compile against. Real apps sometimes split Tailwind
178
+ # across several configs — a base holding theme/plugins (often with NO `content`)
179
+ # plus sibling configs that add the `content` globs (e.g. docuseal's
180
+ # tailwind.{application,form,dynamic}.config.js). Compiling the content-less base
181
+ # purges every utility, so prefer a config that declares a `content: [` array,
182
+ # favouring an app-wide one. Matches `content:[` specifically so theme keys like
183
+ # `base-content` don't false-positive. Echoes a repo-relative path; returns 1 if none.
184
+ pick_tw_config() {
185
+ local c
186
+ for c in "$TW_CONFIG" tailwind.application.config.js tailwind.config.js; do
187
+ [ -n "$c" ] && [ -f "$PROJECT_DIR/$c" ] && \
188
+ grep -qE 'content[[:space:]]*:[[:space:]]*\[' "$PROJECT_DIR/$c" && { echo "$c"; return 0; }
189
+ done
190
+ for c in "$PROJECT_DIR"/tailwind*.config.js; do
191
+ [ -f "$c" ] && grep -qE 'content[[:space:]]*:[[:space:]]*\[' "$c" && { echo "${c#"$PROJECT_DIR"/}"; return 0; }
192
+ done
193
+ return 1
194
+ }
195
+
196
+ try_source_compile() {
197
+ echo " Source compile: $FRAMEWORK $VERSION" >&2
198
+
199
+ if [ ! -f "$PROJECT_DIR/package.json" ]; then
200
+ echo " No package.json — skipping npm-based compilation" >&2
201
+ return 1
202
+ fi
203
+
204
+ # Install if node_modules is missing
205
+ if [ ! -d "$PROJECT_DIR/node_modules" ]; then
206
+ echo " Running $PKG_MGR install --ignore-scripts (may take a minute)..." >&2
207
+ if ! ( cd "$PROJECT_DIR" && _timeout 180 $PKG_MGR install --ignore-scripts >/tmp/npm_out.log 2>&1 ); then
208
+ echo " $PKG_MGR install failed" >&2
209
+ tail -10 /tmp/npm_out.log >&2
210
+ return 1
211
+ fi
212
+ echo " Install OK" >&2
213
+ else
214
+ echo " node_modules already present — skipping install" >&2
215
+ fi
216
+
217
+ case "$FRAMEWORK" in
218
+ tailwind)
219
+ # Detect Tailwind major version (installed pkg first; @import in the
220
+ # entry CSS as a v4 tell when the package isn't resolvable).
221
+ local tw_ver tw_major
222
+ tw_ver=$( ( cd "$PROJECT_DIR" && node -e "try{console.log(require('./node_modules/tailwindcss/package.json').version)}catch(e){}" 2>/dev/null ) || echo "")
223
+ tw_major="${tw_ver%%.*}"
224
+ if [ -z "$tw_major" ] && [ -n "$TW_ENTRY" ] && grep -q '@import.*tailwindcss' "$PROJECT_DIR/$TW_ENTRY" 2>/dev/null; then
225
+ tw_major="4"
226
+ fi
227
+
228
+ # v4 is CSS-first and needs a real entry. Try it when one exists; on
229
+ # miss, fall through to the v3 path (which can synthesize an entry).
230
+ if [ "$tw_major" = "4" ] && [ -n "$TW_ENTRY" ] && [ -f "$PROJECT_DIR/$TW_ENTRY" ]; then
231
+ echo " Compiling Tailwind v4 ($tw_ver)..." >&2
232
+ if ! ( cd "$PROJECT_DIR" && npm ls @tailwindcss/cli 2>/dev/null | grep -q '@tailwindcss/cli' ); then
233
+ ( cd "$PROJECT_DIR" && npm install --no-save @tailwindcss/cli >/dev/null 2>&1 || true )
234
+ fi
235
+ if ( cd "$PROJECT_DIR" && _timeout 180 npx @tailwindcss/cli -i "$TW_ENTRY" -o "$OUTPUT_CSS" >/tmp/compile_out.log 2>&1 ); then
236
+ COMPILE_METHOD="tailwind_v4"
237
+ return 0
238
+ fi
239
+ echo " Tailwind v4 compile failed" >&2
240
+ tail -5 /tmp/compile_out.log >&2
241
+ fi
242
+
243
+ # Tailwind v3 (or v4 fallthrough). Many real apps build CSS through a
244
+ # bundler (shakapacker/webpack/esbuild) and ship NO standalone entry
245
+ # CSS — the @tailwind directives live in the JS pipeline — and often
246
+ # split Tailwind across multiple configs (base = theme/plugins,
247
+ # siblings = `content` globs). When there's no usable entry, synthesize
248
+ # one and compile against a config that declares content, so plugin
249
+ # component layers (e.g. daisyUI `.btn`/`.input`) and the project theme
250
+ # make it into the output instead of falling back to bare utilities.
251
+ echo " Compiling Tailwind v3..." >&2
252
+ # Prefer a content-bearing config (handles multi-config setups where
253
+ # the base config has no `content`); fall back to the detected one.
254
+ local tw_input="$TW_ENTRY" tmp_input="" tw_cfg
255
+ tw_cfg=$(pick_tw_config) || tw_cfg="$TW_CONFIG"
256
+ if [ -z "$tw_input" ] || [ ! -f "$PROJECT_DIR/$tw_input" ]; then
257
+ if [ -z "$tw_cfg" ]; then
258
+ echo " No Tailwind entry file and no config with content globs" >&2
259
+ return 1
260
+ fi
261
+ tmp_input="${TMPDIR:-/tmp}/rtfm_tw_in_$$.css"
262
+ printf '@tailwind base;\n@tailwind components;\n@tailwind utilities;\n' > "$tmp_input"
263
+ tw_input="$tmp_input"
264
+ echo " No entry CSS — synthesised input; config=$tw_cfg" >&2
265
+ else
266
+ echo " Entry CSS=$tw_input; config=${tw_cfg:-<default>}" >&2
267
+ fi
268
+ local tw_args=(-i "$tw_input" -o "$OUTPUT_CSS")
269
+ if [ -n "$tw_cfg" ] && [ -f "$PROJECT_DIR/$tw_cfg" ]; then
270
+ tw_args=(-c "$tw_cfg" "${tw_args[@]}")
271
+ fi
272
+ if ( cd "$PROJECT_DIR" && _timeout 180 npx tailwindcss "${tw_args[@]}" >/tmp/compile_out.log 2>&1 ); then
273
+ [ -n "$tmp_input" ] && rm -f "$tmp_input"
274
+ COMPILE_METHOD="tailwind_v3"
275
+ return 0
276
+ fi
277
+ [ -n "$tmp_input" ] && rm -f "$tmp_input"
278
+ echo " Tailwind v3 compile failed" >&2
279
+ tail -5 /tmp/compile_out.log >&2
280
+ return 1
281
+ ;;
282
+
283
+ bootstrap|bulma|foundation|scss|webpixels)
284
+ if [ -z "$SCSS_ENTRY" ] || [ ! -f "$PROJECT_DIR/$SCSS_ENTRY" ]; then
285
+ echo " No SCSS entry file" >&2
286
+ return 1
287
+ fi
288
+ echo " Compiling SCSS via npx sass..." >&2
289
+ if ( cd "$PROJECT_DIR" && _timeout 180 npx sass "$SCSS_ENTRY" "$OUTPUT_CSS" \
290
+ --load-path=node_modules --load-path=. \
291
+ --no-source-map --style=expanded >/tmp/compile_out.log 2>&1 ); then
292
+ COMPILE_METHOD="sass"
293
+ return 0
294
+ fi
295
+ echo " SCSS compile failed" >&2
296
+ tail -5 /tmp/compile_out.log >&2
297
+ return 1
298
+ ;;
299
+
300
+ postcss)
301
+ local pc_entry="${TW_ENTRY:-${SCSS_ENTRY}}"
302
+ if [ -z "$POSTCSS_CONFIG" ] || [ -z "$pc_entry" ] || [ ! -f "$PROJECT_DIR/$pc_entry" ]; then
303
+ echo " Missing PostCSS config or entry" >&2
304
+ return 1
305
+ fi
306
+ echo " Compiling via npx postcss..." >&2
307
+ if ( cd "$PROJECT_DIR" && _timeout 180 npx postcss "$pc_entry" -o "$OUTPUT_CSS" \
308
+ --config "$POSTCSS_CONFIG" >/tmp/compile_out.log 2>&1 ); then
309
+ COMPILE_METHOD="postcss"
310
+ return 0
311
+ fi
312
+ echo " PostCSS compile failed" >&2
313
+ tail -5 /tmp/compile_out.log >&2
314
+ return 1
315
+ ;;
316
+
317
+ plain_css|custom)
318
+ # Concatenate the project's listed CSS files
319
+ local css_files
320
+ css_files=$(node "$SCRIPT_DIR/json_get.js" "$DETECT_JSON" "css_files[]" "" 2>/dev/null)
321
+ if [ -z "$css_files" ]; then
322
+ return 1
323
+ fi
324
+ while IFS= read -r css_path; do
325
+ [ -z "$css_path" ] && continue
326
+ if [ -f "$PROJECT_DIR/$css_path" ]; then
327
+ echo " Including: $css_path" >&2
328
+ cat "$PROJECT_DIR/$css_path" >> "$OUTPUT_CSS"
329
+ echo "" >> "$OUTPUT_CSS"
330
+ fi
331
+ done <<< "$css_files"
332
+ if [ -s "$OUTPUT_CSS" ]; then
333
+ COMPILE_METHOD="plain_css"
334
+ return 0
335
+ fi
336
+ return 1
337
+ ;;
338
+
339
+ *)
340
+ echo " No source-compile strategy for: $FRAMEWORK" >&2
341
+ return 1
342
+ ;;
343
+ esac
344
+ }
345
+
346
+ try_cdn_fallback() {
347
+ echo " Falling back to CDN + synthesised overrides..." >&2
348
+ > "$OUTPUT_CSS"
349
+
350
+ case "$FRAMEWORK" in
351
+ bootstrap)
352
+ local bs_ver="${VERSION:-5.3.0}"
353
+ bs_ver=$(echo "$bs_ver" | sed 's/^[v^~]//')
354
+ echo " Fetching Bootstrap $bs_ver..." >&2
355
+ curl -sL "https://cdn.jsdelivr.net/npm/bootstrap@${bs_ver}/dist/css/bootstrap.min.css" >> "$OUTPUT_CSS" 2>/dev/null || \
356
+ curl -sL "https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" >> "$OUTPUT_CSS" 2>/dev/null || true
357
+ echo "" >> "$OUTPUT_CSS"
358
+ ;;
359
+ webpixels)
360
+ local wp_ver="${VERSION:-latest}"
361
+ wp_ver=$(echo "$wp_ver" | sed 's/^[v^~]//')
362
+ echo " Fetching @webpixels/css $wp_ver..." >&2
363
+ # Webpixels wraps Bootstrap — bundle both so the mockup gets Bootstrap reset + webpixels components
364
+ curl -sL "https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" >> "$OUTPUT_CSS" 2>/dev/null || true
365
+ echo "" >> "$OUTPUT_CSS"
366
+ curl -sL "https://cdn.jsdelivr.net/npm/@webpixels/css@${wp_ver}/dist/index.css" >> "$OUTPUT_CSS" 2>/dev/null || true
367
+ echo "" >> "$OUTPUT_CSS"
368
+ ;;
369
+ bulma)
370
+ local bl_ver="${VERSION:-0.9.4}"
371
+ bl_ver=$(echo "$bl_ver" | sed 's/^[v^~]//')
372
+ echo " Fetching Bulma $bl_ver..." >&2
373
+ curl -sL "https://cdn.jsdelivr.net/npm/bulma@${bl_ver}/css/bulma.min.css" >> "$OUTPUT_CSS" 2>/dev/null || true
374
+ echo "" >> "$OUTPUT_CSS"
375
+ ;;
376
+ foundation)
377
+ local fd_ver="${VERSION:-6.8.1}"
378
+ fd_ver=$(echo "$fd_ver" | sed 's/^[v^~]//')
379
+ echo " Fetching Foundation $fd_ver..." >&2
380
+ curl -sL "https://cdn.jsdelivr.net/npm/foundation-sites@${fd_ver}/dist/css/foundation.min.css" >> "$OUTPUT_CSS" 2>/dev/null || true
381
+ echo "" >> "$OUTPUT_CSS"
382
+ ;;
383
+ tailwind|custom|none)
384
+ echo " Generating Tailwind utility fallback..." >&2
385
+ cat "$SCRIPT_DIR/../assets/tailwind-fallback.css" >> "$OUTPUT_CSS" 2>/dev/null
386
+ echo "" >> "$OUTPUT_CSS"
387
+ ;;
388
+ esac
389
+
390
+ # Generate theme overrides from detection JSON
391
+ node "$SCRIPT_DIR/theme_overrides.js" "$DETECT_JSON" "$FRAMEWORK" >> "$OUTPUT_CSS" 2>/dev/null || true
392
+
393
+ COMPILE_METHOD="fallback_synthesis"
394
+ }
395
+
396
+ # ─── Run ─────────────────────────────────────────────────────────────────────
397
+
398
+ if try_prebuilt_css; then
399
+ echo " Used committed pre-built CSS ($COMPILE_METHOD)" >&2
400
+ elif try_source_compile; then
401
+ echo " Source compile succeeded ($COMPILE_METHOD)" >&2
402
+ else
403
+ try_cdn_fallback
404
+ echo " Used CDN fallback ($COMPILE_METHOD)" >&2
405
+ fi
406
+
407
+ # Append additional CDN links the project loads (FontAwesome, tippy, etc.)
408
+ EXTRA_CDN=$(node "$SCRIPT_DIR/json_get.js" "$DETECT_JSON" "cdn_links[]" "" 2>/dev/null)
409
+ if [ -n "$EXTRA_CDN" ]; then
410
+ while IFS= read -r url; do
411
+ [ -z "$url" ] || [ "$url" = "null" ] && continue
412
+ echo " Fetching CDN: $url" >&2
413
+ curl -sL "$url" >> "$OUTPUT_CSS" 2>/dev/null || true
414
+ echo "" >> "$OUTPUT_CSS"
415
+ done <<< "$EXTRA_CDN"
416
+ fi
417
+
418
+ # Prepend font @imports (must be at the top per CSS spec)
419
+ FONT_LINKS=$(node "$SCRIPT_DIR/json_get.js" "$DETECT_JSON" "font_links[]" "" 2>/dev/null)
420
+ # Also support skill schema (google_fonts at top level)
421
+ if [ -z "$FONT_LINKS" ]; then
422
+ FONT_LINKS=$(node "$SCRIPT_DIR/json_get.js" "$DETECT_JSON" "google_fonts[]" "" 2>/dev/null)
423
+ fi
424
+ if [ -n "$FONT_LINKS" ]; then
425
+ FONT_IMPORTS=""
426
+ while IFS= read -r url; do
427
+ [ -z "$url" ] || [ "$url" = "null" ] && continue
428
+ FONT_IMPORTS="${FONT_IMPORTS}@import url('${url}');\n"
429
+ done <<< "$FONT_LINKS"
430
+ if [ -n "$FONT_IMPORTS" ]; then
431
+ TMP=$(mktemp)
432
+ printf '%b\n' "$FONT_IMPORTS" > "$TMP"
433
+ cat "$OUTPUT_CSS" >> "$TMP"
434
+ mv "$TMP" "$OUTPUT_CSS"
435
+ fi
436
+ fi
437
+
438
+ # Sanitize: strip un-compilable directives that may have leaked in
439
+ node "$SCRIPT_DIR/sanitize_css.js" "$OUTPUT_CSS" 2>&1 >&2 || true
440
+
441
+ # Record the method used
442
+ echo "$COMPILE_METHOD" > "${OUTPUT_CSS}.method.txt"
443
+
444
+ CSS_SIZE=$(wc -c < "$OUTPUT_CSS" 2>/dev/null || echo "0")
445
+ echo " Output: $OUTPUT_CSS ($CSS_SIZE bytes, method=$COMPILE_METHOD)" >&2
446
+
447
+ [ -s "$OUTPUT_CSS" ] && exit 0 || exit 1