synthos 0.8.0 → 0.10.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 (368) hide show
  1. package/README.md +1 -1
  2. package/default-pages/application/page.html +42 -0
  3. package/default-pages/application/page.json +10 -0
  4. package/default-pages/elevenlabs_effects_studio/page.html +1363 -0
  5. package/default-pages/elevenlabs_effects_studio/page.json +11 -0
  6. package/default-pages/elevenlabs_voice_studio/page.html +801 -0
  7. package/default-pages/elevenlabs_voice_studio/page.json +11 -0
  8. package/default-pages/{json_tools.html → json_tools/page.html} +13 -11
  9. package/default-pages/json_tools/page.json +10 -0
  10. package/default-pages/my_notes/notes/a1b2c3d4-e5f6-7890-abcd-ef1234567890.json +5 -0
  11. package/default-pages/my_notes/page.html +132 -0
  12. package/default-pages/{my_notes.json → my_notes/page.json} +2 -2
  13. package/default-pages/neon_asteroids/files/Ambient_Space.mp3 +0 -0
  14. package/default-pages/neon_asteroids/files/Ambient_Space2.mp3 +0 -0
  15. package/default-pages/neon_asteroids/files/Ambient_Space3.mp3 +0 -0
  16. package/default-pages/neon_asteroids/files/Asteroid_Explosion.mp3 +0 -0
  17. package/default-pages/neon_asteroids/files/Hyperspace_Jump.mp3 +0 -0
  18. package/default-pages/neon_asteroids/files/Laser_Fire.mp3 +0 -0
  19. package/default-pages/neon_asteroids/files/Menu_Navigate.mp3 +0 -0
  20. package/default-pages/neon_asteroids/files/Power_Up_Collect.mp3 +0 -0
  21. package/default-pages/neon_asteroids/files/Saucer_Alert.mp3 +0 -0
  22. package/default-pages/neon_asteroids/files/Ship_Thrust.mp3 +0 -0
  23. package/default-pages/neon_asteroids/files/effects.json +74 -0
  24. package/default-pages/neon_asteroids/page.html +1803 -0
  25. package/default-pages/{neon_asteroids.json → neon_asteroids/page.json} +3 -3
  26. package/default-pages/{oregon_trail.html → oregon_trail/page.html} +16 -30
  27. package/default-pages/{oregon_trail.json → oregon_trail/page.json} +2 -2
  28. package/default-pages/retro_game_starter/page.html +1308 -0
  29. package/default-pages/retro_game_starter/page.json +12 -0
  30. package/default-pages/{sidebar_page.html → sidebar_page/page.html} +12 -10
  31. package/default-pages/sidebar_page/page.json +10 -0
  32. package/default-pages/{solar_explorer.html → solar_explorer/page.html} +15 -12
  33. package/default-pages/{solar_explorer.json → solar_explorer/page.json} +2 -2
  34. package/default-pages/{solar_tutorial.html → solar_tutorial/page.html} +12 -10
  35. package/default-pages/solar_tutorial/page.json +10 -0
  36. package/default-pages/{two-panel_page.html → two-panel_page/page.html} +13 -11
  37. package/default-pages/two-panel_page/page.json +10 -0
  38. package/default-pages/{us_map.html → us_map/page.html} +193 -192
  39. package/default-pages/{us_map.json → us_map/page.json} +12 -12
  40. package/default-pages/{us_map_1850.html → us_map_1850/page.html} +326 -325
  41. package/default-pages/{us_map_1850.json → us_map_1850/page.json} +12 -12
  42. package/default-pages/{western_cities_1850.html → western_cities_1850/page.html} +527 -526
  43. package/default-pages/{western_cities_1850.json → western_cities_1850/page.json} +12 -12
  44. package/default-themes/aurora-dawn.json +19 -0
  45. package/default-themes/aurora-dawn.v3.css +198 -0
  46. package/default-themes/aurora-dusk.json +19 -0
  47. package/default-themes/aurora-dusk.v3.css +200 -0
  48. package/default-themes/cosmos-dawn.json +19 -0
  49. package/default-themes/cosmos-dawn.v3.css +198 -0
  50. package/default-themes/cosmos-dusk.json +19 -0
  51. package/default-themes/cosmos-dusk.v3.css +200 -0
  52. package/default-themes/high-contrast-dark.json +19 -0
  53. package/default-themes/high-contrast-dark.v3.css +200 -0
  54. package/default-themes/high-contrast-light.json +19 -0
  55. package/default-themes/high-contrast-light.v3.css +198 -0
  56. package/default-themes/nebula-dawn.v2.css +110 -0
  57. package/default-themes/nebula-dawn.v3.css +199 -0
  58. package/default-themes/nebula-dusk.v2.css +104 -0
  59. package/default-themes/nebula-dusk.v3.css +201 -0
  60. package/default-themes/solar-flare-dawn.json +19 -0
  61. package/default-themes/solar-flare-dawn.v3.css +198 -0
  62. package/default-themes/solar-flare-dusk.json +19 -0
  63. package/default-themes/solar-flare-dusk.v3.css +200 -0
  64. package/dist/agents/index.d.ts +1 -1
  65. package/dist/agents/index.d.ts.map +1 -1
  66. package/dist/agents/index.js +2 -1
  67. package/dist/agents/index.js.map +1 -1
  68. package/dist/agents/openclaw/gatewayManager.d.ts +4 -0
  69. package/dist/agents/openclaw/gatewayManager.d.ts.map +1 -1
  70. package/dist/agents/openclaw/gatewayManager.js +27 -11
  71. package/dist/agents/openclaw/gatewayManager.js.map +1 -1
  72. package/dist/agents/openclaw/openclawProvider.d.ts.map +1 -1
  73. package/dist/agents/openclaw/openclawProvider.js +2 -4
  74. package/dist/agents/openclaw/openclawProvider.js.map +1 -1
  75. package/dist/agents/openclaw/sshTunnelManager.d.ts +2 -0
  76. package/dist/agents/openclaw/sshTunnelManager.d.ts.map +1 -1
  77. package/dist/agents/openclaw/sshTunnelManager.js +31 -12
  78. package/dist/agents/openclaw/sshTunnelManager.js.map +1 -1
  79. package/dist/builders/anthropic.d.ts +31 -0
  80. package/dist/builders/anthropic.d.ts.map +1 -0
  81. package/dist/builders/anthropic.js +227 -0
  82. package/dist/builders/anthropic.js.map +1 -0
  83. package/dist/builders/fireworksai.d.ts +9 -0
  84. package/dist/builders/fireworksai.d.ts.map +1 -0
  85. package/dist/builders/fireworksai.js +57 -0
  86. package/dist/builders/fireworksai.js.map +1 -0
  87. package/dist/builders/index.d.ts +13 -0
  88. package/dist/builders/index.d.ts.map +1 -0
  89. package/dist/builders/index.js +31 -0
  90. package/dist/builders/index.js.map +1 -0
  91. package/dist/builders/openai.d.ts +8 -0
  92. package/dist/builders/openai.d.ts.map +1 -0
  93. package/dist/builders/openai.js +87 -0
  94. package/dist/builders/openai.js.map +1 -0
  95. package/dist/builders/types.d.ts +54 -0
  96. package/dist/builders/types.d.ts.map +1 -0
  97. package/dist/builders/types.js +211 -0
  98. package/dist/builders/types.js.map +1 -0
  99. package/dist/connectors/index.d.ts +1 -1
  100. package/dist/connectors/index.d.ts.map +1 -1
  101. package/dist/connectors/index.js +3 -2
  102. package/dist/connectors/index.js.map +1 -1
  103. package/dist/connectors/registry.d.ts +2 -1
  104. package/dist/connectors/registry.d.ts.map +1 -1
  105. package/dist/connectors/registry.js +31 -8
  106. package/dist/connectors/registry.js.map +1 -1
  107. package/dist/customizer/Customizer.d.ts +62 -0
  108. package/dist/customizer/Customizer.d.ts.map +1 -0
  109. package/dist/customizer/Customizer.js +134 -0
  110. package/dist/customizer/Customizer.js.map +1 -0
  111. package/dist/customizer/index.d.ts +4 -0
  112. package/dist/customizer/index.d.ts.map +1 -0
  113. package/dist/customizer/index.js +9 -0
  114. package/dist/customizer/index.js.map +1 -0
  115. package/dist/files.d.ts +16 -0
  116. package/dist/files.d.ts.map +1 -1
  117. package/dist/files.js +60 -1
  118. package/dist/files.js.map +1 -1
  119. package/dist/index.d.ts +2 -0
  120. package/dist/index.d.ts.map +1 -1
  121. package/dist/index.js +2 -0
  122. package/dist/index.js.map +1 -1
  123. package/dist/init.d.ts +12 -6
  124. package/dist/init.d.ts.map +1 -1
  125. package/dist/init.js +150 -133
  126. package/dist/init.js.map +1 -1
  127. package/dist/migrations.d.ts.map +1 -1
  128. package/dist/migrations.js +23 -10
  129. package/dist/migrations.js.map +1 -1
  130. package/dist/models/anthropic.d.ts +4 -2
  131. package/dist/models/anthropic.d.ts.map +1 -1
  132. package/dist/models/anthropic.js +33 -6
  133. package/dist/models/anthropic.js.map +1 -1
  134. package/dist/models/fireworksai.d.ts.map +1 -1
  135. package/dist/models/fireworksai.js +9 -1
  136. package/dist/models/fireworksai.js.map +1 -1
  137. package/dist/models/index.d.ts +1 -1
  138. package/dist/models/index.d.ts.map +1 -1
  139. package/dist/models/index.js +2 -1
  140. package/dist/models/index.js.map +1 -1
  141. package/dist/models/openai.d.ts +1 -1
  142. package/dist/models/openai.d.ts.map +1 -1
  143. package/dist/models/openai.js +24 -3
  144. package/dist/models/openai.js.map +1 -1
  145. package/dist/models/types.d.ts +20 -1
  146. package/dist/models/types.d.ts.map +1 -1
  147. package/dist/models/types.js +6 -1
  148. package/dist/models/types.js.map +1 -1
  149. package/dist/pages.d.ts +34 -10
  150. package/dist/pages.d.ts.map +1 -1
  151. package/dist/pages.js +229 -79
  152. package/dist/pages.js.map +1 -1
  153. package/dist/service/createCompletePrompt.d.ts +2 -1
  154. package/dist/service/createCompletePrompt.d.ts.map +1 -1
  155. package/dist/service/createCompletePrompt.js +2 -2
  156. package/dist/service/createCompletePrompt.js.map +1 -1
  157. package/dist/service/requiresSettings.d.ts +2 -1
  158. package/dist/service/requiresSettings.d.ts.map +1 -1
  159. package/dist/service/requiresSettings.js +3 -3
  160. package/dist/service/requiresSettings.js.map +1 -1
  161. package/dist/service/server.d.ts +2 -1
  162. package/dist/service/server.d.ts.map +1 -1
  163. package/dist/service/server.js +37 -8
  164. package/dist/service/server.js.map +1 -1
  165. package/dist/service/transformPage.d.ts +47 -20
  166. package/dist/service/transformPage.d.ts.map +1 -1
  167. package/dist/service/transformPage.js +514 -293
  168. package/dist/service/transformPage.js.map +1 -1
  169. package/dist/service/useAgentRoutes.d.ts +2 -1
  170. package/dist/service/useAgentRoutes.d.ts.map +1 -1
  171. package/dist/service/useAgentRoutes.js +17 -14
  172. package/dist/service/useAgentRoutes.js.map +1 -1
  173. package/dist/service/useApiRoutes.d.ts +2 -1
  174. package/dist/service/useApiRoutes.d.ts.map +1 -1
  175. package/dist/service/useApiRoutes.js +287 -172
  176. package/dist/service/useApiRoutes.js.map +1 -1
  177. package/dist/service/useConnectorRoutes.js +17 -17
  178. package/dist/service/useConnectorRoutes.js.map +1 -1
  179. package/dist/service/useDataRoutes.d.ts.map +1 -1
  180. package/dist/service/useDataRoutes.js +13 -10
  181. package/dist/service/useDataRoutes.js.map +1 -1
  182. package/dist/service/useFileRoutes.d.ts +4 -0
  183. package/dist/service/useFileRoutes.d.ts.map +1 -0
  184. package/dist/service/useFileRoutes.js +122 -0
  185. package/dist/service/useFileRoutes.js.map +1 -0
  186. package/dist/service/usePageRoutes.d.ts +2 -1
  187. package/dist/service/usePageRoutes.d.ts.map +1 -1
  188. package/dist/service/usePageRoutes.js +671 -74
  189. package/dist/service/usePageRoutes.js.map +1 -1
  190. package/dist/service/useSharedDataRoutes.d.ts +4 -0
  191. package/dist/service/useSharedDataRoutes.d.ts.map +1 -0
  192. package/dist/service/useSharedDataRoutes.js +107 -0
  193. package/dist/service/useSharedDataRoutes.js.map +1 -0
  194. package/dist/service/useSharedFileRoutes.d.ts +4 -0
  195. package/dist/service/useSharedFileRoutes.d.ts.map +1 -0
  196. package/dist/service/useSharedFileRoutes.js +121 -0
  197. package/dist/service/useSharedFileRoutes.js.map +1 -0
  198. package/dist/settings.d.ts +5 -3
  199. package/dist/settings.d.ts.map +1 -1
  200. package/dist/settings.js +12 -10
  201. package/dist/settings.js.map +1 -1
  202. package/dist/storage/FsStorageProvider.d.ts +25 -0
  203. package/dist/storage/FsStorageProvider.d.ts.map +1 -0
  204. package/dist/storage/FsStorageProvider.js +103 -0
  205. package/dist/storage/FsStorageProvider.js.map +1 -0
  206. package/dist/storage/StorageProvider.d.ts +31 -0
  207. package/dist/storage/StorageProvider.d.ts.map +1 -0
  208. package/dist/storage/StorageProvider.js +3 -0
  209. package/dist/storage/StorageProvider.js.map +1 -0
  210. package/dist/storage/index.d.ts +3 -0
  211. package/dist/storage/index.d.ts.map +1 -0
  212. package/dist/storage/index.js +6 -0
  213. package/dist/storage/index.js.map +1 -0
  214. package/dist/synthos-cli.d.ts.map +1 -1
  215. package/dist/synthos-cli.js +4 -3
  216. package/dist/synthos-cli.js.map +1 -1
  217. package/dist/themes.d.ts +1 -0
  218. package/dist/themes.d.ts.map +1 -1
  219. package/dist/themes.js +65 -28
  220. package/dist/themes.js.map +1 -1
  221. package/migration-rules/v1-to-v2.md +193 -0
  222. package/migration-rules/v2-to-v3.md +481 -0
  223. package/package.json +11 -10
  224. package/required-pages/builder/page.html +43 -0
  225. package/required-pages/builder/page.json +10 -0
  226. package/required-pages/{pages.html → pages/page.html} +238 -233
  227. package/required-pages/pages/page.json +10 -0
  228. package/required-pages/{settings.html → settings/page.html} +389 -275
  229. package/required-pages/settings/page.json +10 -0
  230. package/required-pages/synthos_apis/page.html +846 -0
  231. package/required-pages/synthos_apis/page.json +10 -0
  232. package/required-pages/{synthos_scripts.html → synthos_scripts/page.html} +13 -11
  233. package/required-pages/synthos_scripts/page.json +10 -0
  234. package/src/agents/index.ts +1 -1
  235. package/src/agents/openclaw/gatewayManager.ts +22 -11
  236. package/src/agents/openclaw/openclawProvider.ts +2 -4
  237. package/src/agents/openclaw/sshTunnelManager.ts +19 -11
  238. package/src/builders/anthropic.ts +283 -0
  239. package/src/builders/fireworksai.ts +59 -0
  240. package/src/builders/index.ts +33 -0
  241. package/src/builders/openai.ts +89 -0
  242. package/src/builders/types.ts +261 -0
  243. package/src/connectors/index.ts +1 -1
  244. package/src/connectors/registry.ts +28 -8
  245. package/src/customizer/Customizer.ts +163 -0
  246. package/src/customizer/index.ts +5 -0
  247. package/src/files.ts +57 -0
  248. package/src/index.ts +3 -1
  249. package/src/init.ts +195 -145
  250. package/src/migrations.ts +30 -10
  251. package/src/models/anthropic.ts +40 -10
  252. package/src/models/fireworksai.ts +9 -2
  253. package/src/models/index.ts +1 -1
  254. package/src/models/openai.ts +26 -6
  255. package/src/models/types.ts +31 -1
  256. package/src/pages.ts +230 -77
  257. package/src/service/createCompletePrompt.ts +3 -2
  258. package/src/service/requiresSettings.ts +4 -3
  259. package/src/service/server.ts +36 -9
  260. package/src/service/transformPage.ts +557 -326
  261. package/src/service/useAgentRoutes.ts +19 -14
  262. package/src/service/useApiRoutes.ts +208 -84
  263. package/src/service/useConnectorRoutes.ts +18 -18
  264. package/src/service/useDataRoutes.ts +13 -10
  265. package/src/service/useFileRoutes.ts +128 -0
  266. package/src/service/usePageRoutes.ts +730 -81
  267. package/src/service/useSharedDataRoutes.ts +109 -0
  268. package/src/service/useSharedFileRoutes.ts +127 -0
  269. package/src/settings.ts +14 -10
  270. package/src/storage/FsStorageProvider.ts +87 -0
  271. package/src/storage/StorageProvider.ts +34 -0
  272. package/src/storage/index.ts +2 -0
  273. package/src/synthos-cli.ts +4 -3
  274. package/src/themes.ts +64 -27
  275. package/static-files/favicon.svg +12 -0
  276. package/static-files/fluentlm-instructions.llmd +868 -0
  277. package/static-files/fluentlm-instructions.md +1595 -0
  278. package/static-files/fluentlm.css +4844 -0
  279. package/static-files/fluentlm.js +3602 -0
  280. package/static-files/fluentlm.min.css +1 -0
  281. package/static-files/fluentlm.min.js +1 -0
  282. package/{page-scripts/helpers-v2.js → static-files/helpers.v3.js} +82 -0
  283. package/static-files/page.v3.js +1290 -0
  284. package/static-files/recommended-frameworks.llmd +81 -0
  285. package/static-files/recommended-frameworks.md +137 -0
  286. package/static-files/retro-game.js +877 -0
  287. package/static-files/shell.css +797 -0
  288. package/static-files/theme-dark.css +169 -0
  289. package/static-files/theme-light.css +169 -0
  290. package/tests/builders.spec.ts +139 -0
  291. package/tests/pages.spec.ts +54 -84
  292. package/tests/transformPage.spec.ts +299 -360
  293. package/default-pages/application.html +0 -40
  294. package/default-pages/application.json +0 -1
  295. package/default-pages/json_tools.json +0 -1
  296. package/default-pages/my_notes.html +0 -33
  297. package/default-pages/neon_asteroids.html +0 -77
  298. package/default-pages/sidebar_page.json +0 -1
  299. package/default-pages/solar_tutorial.json +0 -1
  300. package/default-pages/two-panel_page.json +0 -1
  301. package/dist/service/useGatewayRoutes.d.ts +0 -4
  302. package/dist/service/useGatewayRoutes.d.ts.map +0 -1
  303. package/dist/service/useGatewayRoutes.js +0 -168
  304. package/dist/service/useGatewayRoutes.js.map +0 -1
  305. package/page-scripts/page-v2.js +0 -656
  306. package/required-pages/builder.html +0 -48
  307. package/required-pages/builder.json +0 -1
  308. package/required-pages/pages.json +0 -1
  309. package/required-pages/settings.json +0 -1
  310. package/required-pages/synthos_apis.html +0 -327
  311. package/required-pages/synthos_apis.json +0 -1
  312. package/required-pages/synthos_scripts.json +0 -1
  313. package/src/connectors/airtable/connector.json +0 -27
  314. package/src/connectors/alpha-vantage/connector.json +0 -26
  315. package/src/connectors/brave-search/connector.json +0 -26
  316. package/src/connectors/cloudinary/connector.json +0 -27
  317. package/src/connectors/deepl/connector.json +0 -28
  318. package/src/connectors/elevenlabs/connector.json +0 -30
  319. package/src/connectors/giphy/connector.json +0 -27
  320. package/src/connectors/github/connector.json +0 -29
  321. package/src/connectors/huggingface/connector.json +0 -27
  322. package/src/connectors/imgur/connector.json +0 -29
  323. package/src/connectors/instagram/connector.json +0 -43
  324. package/src/connectors/jira/connector.json +0 -28
  325. package/src/connectors/mapbox/connector.json +0 -26
  326. package/src/connectors/nasa/connector.json +0 -27
  327. package/src/connectors/newsapi/connector.json +0 -27
  328. package/src/connectors/notion/connector.json +0 -28
  329. package/src/connectors/open-exchange-rates/connector.json +0 -27
  330. package/src/connectors/openweathermap/connector.json +0 -26
  331. package/src/connectors/pexels/connector.json +0 -27
  332. package/src/connectors/resend/connector.json +0 -29
  333. package/src/connectors/rss2json/connector.json +0 -27
  334. package/src/connectors/sendgrid/connector.json +0 -27
  335. package/src/connectors/spoonacular/connector.json +0 -28
  336. package/src/connectors/stability-ai/connector.json +0 -27
  337. package/src/connectors/twilio/connector.json +0 -28
  338. package/src/connectors/unsplash/connector.json +0 -27
  339. package/src/connectors/wolfram-alpha/connector.json +0 -26
  340. package/src/connectors/youtube-data/connector.json +0 -30
  341. /package/{dist/connectors → service-connectors}/airtable/connector.json +0 -0
  342. /package/{dist/connectors → service-connectors}/alpha-vantage/connector.json +0 -0
  343. /package/{dist/connectors → service-connectors}/brave-search/connector.json +0 -0
  344. /package/{dist/connectors → service-connectors}/cloudinary/connector.json +0 -0
  345. /package/{dist/connectors → service-connectors}/deepl/connector.json +0 -0
  346. /package/{dist/connectors → service-connectors}/elevenlabs/connector.json +0 -0
  347. /package/{dist/connectors → service-connectors}/giphy/connector.json +0 -0
  348. /package/{dist/connectors → service-connectors}/github/connector.json +0 -0
  349. /package/{dist/connectors → service-connectors}/huggingface/connector.json +0 -0
  350. /package/{dist/connectors → service-connectors}/imgur/connector.json +0 -0
  351. /package/{dist/connectors → service-connectors}/instagram/connector.json +0 -0
  352. /package/{dist/connectors → service-connectors}/jira/connector.json +0 -0
  353. /package/{dist/connectors → service-connectors}/mapbox/connector.json +0 -0
  354. /package/{dist/connectors → service-connectors}/nasa/connector.json +0 -0
  355. /package/{dist/connectors → service-connectors}/newsapi/connector.json +0 -0
  356. /package/{dist/connectors → service-connectors}/notion/connector.json +0 -0
  357. /package/{dist/connectors → service-connectors}/open-exchange-rates/connector.json +0 -0
  358. /package/{dist/connectors → service-connectors}/openweathermap/connector.json +0 -0
  359. /package/{dist/connectors → service-connectors}/pexels/connector.json +0 -0
  360. /package/{dist/connectors → service-connectors}/resend/connector.json +0 -0
  361. /package/{dist/connectors → service-connectors}/rss2json/connector.json +0 -0
  362. /package/{dist/connectors → service-connectors}/sendgrid/connector.json +0 -0
  363. /package/{dist/connectors → service-connectors}/spoonacular/connector.json +0 -0
  364. /package/{dist/connectors → service-connectors}/stability-ai/connector.json +0 -0
  365. /package/{dist/connectors → service-connectors}/twilio/connector.json +0 -0
  366. /package/{dist/connectors → service-connectors}/unsplash/connector.json +0 -0
  367. /package/{dist/connectors → service-connectors}/wolfram-alpha/connector.json +0 -0
  368. /package/{dist/connectors → service-connectors}/youtube-data/connector.json +0 -0
@@ -0,0 +1,481 @@
1
+ # SynthOS v2 → v3 Migration Rules
2
+
3
+ This document covers the migration from SynthOS v2 format to v3 (FluentLM-based).
4
+
5
+ ---
6
+
7
+ ## 1. Theme Migration
8
+
9
+ ### Overview
10
+
11
+ In v2, theme files (~800 lines each) define **both** CSS custom properties and all shell component styles (chat panel, modals, forms, scrollbars, etc.).
12
+
13
+ In v3, component styles live in `fluentlm.css`. Theme files **only** override FluentLM palette variables and set semantic color tokens. This brings each theme down to ~170 lines.
14
+
15
+ ### Structure of a v3 Theme File
16
+
17
+ ```
18
+ :root, .theme-class {
19
+ /* 1. Palette overrides — rebrand FluentLM's default blue to your theme ramp */
20
+ /* 2. Semantic tokens — map palette vars to UI roles (same sections as theme-light/dark.css) */
21
+ }
22
+ ```
23
+
24
+ Zero component CSS. No selectors for `.chat-panel`, `.modal-*`, `.brainstorm-*`, scrollbars, etc.
25
+
26
+ ### Palette Variable Mapping (v2 → v3)
27
+
28
+ #### Brand / Theme Colors
29
+
30
+ | v2 variable | v3 palette variable | Notes |
31
+ |---|---|---|
32
+ | `--accent-primary` | `--themePrimary` | Primary brand color |
33
+ | `--accent-secondary` | `--themeDark` | Darker accent |
34
+ | `--accent-tertiary` | `--themeSecondary` | Secondary accent |
35
+ | — | `--themeDarkAlt` | Interpolated from brand ramp |
36
+ | — | `--themeDarker` | Interpolated from brand ramp |
37
+ | — | `--themeTertiary` | Interpolated from brand ramp |
38
+ | — | `--themeLight` | Interpolated from brand ramp |
39
+ | — | `--themeLighter` | Interpolated from brand ramp |
40
+ | — | `--themeLighterAlt` | Interpolated from brand ramp |
41
+
42
+ #### Neutral Colors — Light Theme
43
+
44
+ | v2 variable | v3 palette variable | Notes |
45
+ |---|---|---|
46
+ | `--bg-tertiary` | `--neutralLighterAlt` | Lightest background |
47
+ | `--bg-primary` | `--neutralLighter` | Primary background |
48
+ | `--bg-secondary` | `--neutralLight` | Secondary background |
49
+ | `--text-secondary` | `--neutralSecondary` | Secondary text |
50
+ | `--text-primary` | `--neutralPrimary` | Primary text |
51
+ | `--white` | `--white` | White |
52
+
53
+ #### Neutral Colors — Dark Theme
54
+
55
+ | v2 variable | v3 palette variable | Notes |
56
+ |---|---|---|
57
+ | `--bg-primary` | `--neutralPrimary` | Dark primary background |
58
+ | `--bg-secondary` | `--neutralDark` | Dark secondary background |
59
+ | `--bg-tertiary` | `--neutralDarker` (custom) | Darkest background |
60
+ | `--text-primary` | `--neutralLighter` | Light text on dark |
61
+ | `--text-secondary` | `--neutralTertiaryAlt` | Secondary text on dark |
62
+
63
+ ### Variables Without FluentLM Equivalents
64
+
65
+ The following v2 variables have **no** FluentLM palette equivalent. If a page uses them, the page author must define them in a page-level `<style>` block:
66
+
67
+ | v2 variable | Typical value (Dawn) | Typical value (Dusk) |
68
+ |---|---|---|
69
+ | `--accent-glow` | `rgba(118,75,162,0.15)` | `rgba(138,43,226,0.3)` |
70
+ | `--border-color` | `rgba(118,75,162,0.25)` | `rgba(138,43,226,0.3)` |
71
+ | `--header-min-height` | `58px` | `58px` |
72
+ | `--header-padding-vertical` | `14px` | `14px` |
73
+ | `--header-padding-horizontal` | `20px` | `20px` |
74
+ | `--header-line-height` | `1.25` | `1.25` |
75
+
76
+ ### Semantic Tokens
77
+
78
+ v3 themes set semantic tokens (e.g. `--bodyBackground`, `--bodyText`, `--link`) by referencing the overridden palette variables. The token assignments follow FluentLM's reference themes:
79
+
80
+ - **Light themes** → follow `static-files/theme-light.css`
81
+ - **Dark themes** → follow `static-files/theme-dark.css`
82
+
83
+ ### What to Remove
84
+
85
+ All CSS rules targeting component selectors. The full list from v2 themes that are now handled by `fluentlm.css`:
86
+
87
+ - Base resets: `*`, `body`, `html`
88
+ - Chat: `.chat-panel`, `.chat-header`, `.chat-messages`, `.chat-message`, etc.
89
+ - Viewer: `.viewer-panel`, `.viewer-panel::before`, `.viewer-panel.full-viewer`
90
+ - Loading: `.loading-overlay`, `.spinner`, `#loadingOverlay`
91
+ - Toggle: `.chat-toggle`, `.chat-toggle-dots`, `.chat-toggle-dot`, etc.
92
+ - Modals: `.modal-overlay`, `.modal-content`, `.modal-header`, etc.
93
+ - Forms: `.form-group`, `.form-label`, `.form-input`, etc.
94
+ - Brainstorm: All `.brainstorm-*` selectors
95
+ - Animations: `@keyframes spin`, `@keyframes nebula-pulse`
96
+ - Scrollbars: All `::-webkit-scrollbar*` rules
97
+ - Attachments: `.attach-btn`, `.attach-menu`, `.attachment-pill*`
98
+ - Save line: `.save-line`, `.save-line-label`
99
+ - Screenshot: `.screenshot-overlay`, `.screenshot-rect`
100
+
101
+ ---
102
+
103
+ ## 2. Shell Chrome Changes
104
+
105
+ ### Chat input
106
+
107
+ v2 used a single-line `<input>` with a separate submit button:
108
+
109
+ ```html
110
+ <!-- v2 -->
111
+ <form action="/" method="POST" id="chatForm" data-locked="true">
112
+ <input type="text" class="chat-input" id="chatInput" name="message" placeholder="Type a message..." data-locked="true">
113
+ <button type="submit" class="chat-submit" data-locked="true">Send</button>
114
+ </form>
115
+ ```
116
+
117
+ v3 replaces this with a multi-line `<textarea>`. The Send button is removed — submission is handled by the v3 page script (Enter to send, Shift+Enter for newline):
118
+
119
+ ```html
120
+ <!-- v3 -->
121
+ <form action="/" method="POST" id="chatForm" data-locked="true">
122
+ <textarea class="chat-input" id="chatInput" name="message" rows="2" placeholder="Type a message..." data-locked="true"></textarea>
123
+ </form>
124
+ ```
125
+
126
+ ### Static script versions
127
+
128
+ v3 pages reference the v3 static files. Update both script tags at the bottom of every page:
129
+
130
+ ```html
131
+ <!-- v2 -->
132
+ <script id="page-helpers" src="/api/page-helpers.js?v=2" data-locked="true"></script>
133
+ <script id="page-script" src="/api/page-script.js?v=2" data-locked="true"></script>
134
+
135
+ <!-- v3 -->
136
+ <script id="page-helpers" src="/api/page-helpers.js?v=3" data-locked="true"></script>
137
+ <script id="page-script" src="/api/page-script.js?v=3" data-locked="true"></script>
138
+ ```
139
+
140
+ ### Migration rules for the LLM (shell chrome)
141
+
142
+ When migrating a v2 page's shell chrome to v3:
143
+
144
+ 1. **Replace the chat input** — swap the `<input type="text">` + `<button>Send</button>` pair with a single `<textarea rows="2">` as shown above.
145
+ 2. **Update script versions** — change `?v=2` to `?v=3` on both `page-helpers.js` and `page-script.js`.
146
+ 3. **Do NOT touch** page-specific `<input>` elements inside `.viewer-panel` — the chat input change only applies to the shell's `#chatForm`.
147
+
148
+ ---
149
+
150
+ ## 3. Page Migration
151
+
152
+ ### Overview
153
+
154
+ v2 pages rely on the v2 theme CSS for **all** styling — shell chrome, viewer layout, and page content. In v3, the theme CSS only provides FluentLM palette tokens. When migrating a v2 page to run under a v3 theme, we must **inline** the v2 styles that the page content depends on so it keeps its look.
155
+
156
+ ### What the framework handles (NOT inlined)
157
+
158
+ The shell chrome CSS (chat panel, modals, toggle, brainstorm, attachments, etc.) will be provided by a framework-level shell stylesheet. Pages do NOT need to carry these rules:
159
+
160
+ - `.chat-panel`, `.chat-header`, `.chat-messages`, `.chat-message`, `.chat-message p`, `.chat-message p strong`, `.chat-message p code`
161
+ - `.link-group`, `.link-group a`
162
+ - `form` (chat form layout), `.chat-input`, `.chat-submit`
163
+ - `.chat-toggle`, `.chat-toggle-dots`, `.chat-toggle-dot`, `body.chat-collapsed *`
164
+ - `.chat-input-wrapper`, `.brainstorm-icon-btn`, `.brainstorm-*`
165
+ - `.modal-overlay`, `.modal-content`, `.modal-header`, `.modal-body`, `.modal-footer`, `.modal-footer-right`
166
+ - `.modal-btn`, `.modal-btn-primary`, `.modal-btn-secondary`, `.modal-btn-danger`
167
+ - `.form-group`, `.form-label`, `.form-input`, `.checkbox-label`
168
+ - `.loading-overlay`, `.spinner`, `#loadingOverlay`
169
+ - `.save-line`, `.save-line-label`
170
+ - `.attach-btn`, `.attach-menu`, `.attach-menu-item`, `.attachment-pill*`
171
+ - `.screenshot-overlay`, `.screenshot-rect`
172
+
173
+ ### What must be inlined into each migrated page
174
+
175
+ The following `<style>` block should be injected into the `<head>` of every migrated v2 page. It provides:
176
+
177
+ 1. **v2 CSS custom properties** — so `var(--bg-primary)` etc. still resolve
178
+ 2. **Viewer panel** styles — layout, background, decorative pseudo-element
179
+ 3. **Global resets** — `*` box-sizing, `body` font/color/layout
180
+ 4. **Scrollbar theming** — custom scrollbar appearance
181
+
182
+ #### Inline style block (nebula-dusk)
183
+
184
+ ```html
185
+ <style id="v2-compat">
186
+ /* --- v2 CSS Custom Properties (nebula-dusk) --- */
187
+ :root {
188
+ --bg-primary: #1a1a2e;
189
+ --bg-secondary: #16213e;
190
+ --bg-tertiary: #0f0f23;
191
+ --accent-primary: #667eea;
192
+ --accent-secondary: #764ba2;
193
+ --accent-tertiary: #f093fb;
194
+ --accent-glow: rgba(138,43,226,0.3);
195
+ --text-primary: #e0e0e0;
196
+ --text-secondary: #b794f6;
197
+ --border-color: rgba(138,43,226,0.3);
198
+ --header-min-height: 58px;
199
+ --header-padding-vertical: 14px;
200
+ --header-padding-horizontal: 20px;
201
+ --header-line-height: 1.25;
202
+ }
203
+
204
+ /* --- Global Reset --- */
205
+ * {
206
+ margin: 0;
207
+ padding: 0;
208
+ box-sizing: border-box;
209
+ }
210
+
211
+ body {
212
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
213
+ background: linear-gradient(135deg, var(--bg-primary) 0%, var(--bg-secondary) 50%, var(--bg-tertiary) 100%);
214
+ color: var(--text-primary);
215
+ height: 100vh;
216
+ display: flex;
217
+ }
218
+
219
+ /* --- Viewer Panel --- */
220
+ .viewer-panel {
221
+ flex: 1;
222
+ min-width: 0;
223
+ padding: 20px 20px 20px 44px;
224
+ background: linear-gradient(135deg, rgba(22,33,62,0.9) 0%, rgba(15,15,35,0.95) 100%);
225
+ display: flex;
226
+ flex-direction: column;
227
+ justify-content: center;
228
+ align-items: center;
229
+ box-shadow: inset 0 0 60px rgba(75,0,130,0.15);
230
+ position: relative;
231
+ overflow: hidden;
232
+ }
233
+
234
+ .viewer-panel::before {
235
+ content: '';
236
+ position: absolute;
237
+ top: -50%;
238
+ left: -50%;
239
+ width: 200%;
240
+ height: 200%;
241
+ background: radial-gradient(ellipse at center, rgba(138,43,226,0.05) 0%, transparent 70%);
242
+ animation: nebula-pulse 8s ease-in-out infinite;
243
+ pointer-events: none;
244
+ }
245
+
246
+ @keyframes nebula-pulse {
247
+ 0%,100% { opacity: 0.5; transform: scale(1); }
248
+ 50% { opacity: 1; transform: scale(1.1); }
249
+ }
250
+
251
+ .viewer-panel.full-viewer {
252
+ padding: 0;
253
+ }
254
+
255
+ /* --- Scrollbar --- */
256
+ ::-webkit-scrollbar { width: 10px; height: 10px; }
257
+ ::-webkit-scrollbar-track { background: rgba(15,15,35,0.6); border-radius: 10px; }
258
+ ::-webkit-scrollbar-thumb {
259
+ background: linear-gradient(180deg, var(--accent-primary) 0%, var(--accent-secondary) 50%, var(--accent-tertiary) 100%);
260
+ border-radius: 10px;
261
+ border: 2px solid rgba(15,15,35,0.6);
262
+ box-shadow: 0 0 10px var(--accent-glow);
263
+ }
264
+ ::-webkit-scrollbar-thumb:hover {
265
+ background: linear-gradient(180deg, var(--accent-tertiary) 0%, var(--accent-secondary) 50%, var(--accent-primary) 100%);
266
+ box-shadow: 0 0 15px rgba(240,147,251,0.5);
267
+ }
268
+ ::-webkit-scrollbar-corner { background: rgba(15,15,35,0.6); }
269
+ * { scrollbar-width: thin; scrollbar-color: var(--accent-secondary) rgba(15,15,35,0.6); }
270
+ </style>
271
+ ```
272
+
273
+ ### Migration rules for the LLM
274
+
275
+ When migrating a v2 page to v3:
276
+
277
+ 1. **Inject the `<style id="v2-compat">` block** into `<head>` as the first child (before any other styles or scripts). This preserves the v2 look while running under a v3 theme.
278
+
279
+ 2. **Do NOT modify** existing page content, classes, or inline styles inside `.viewer-panel`. The v2-compat block ensures all `var()` references continue to resolve.
280
+
281
+ 3. **Do NOT convert** v2 class names to FluentLM `flm-*` classes. That's a separate opt-in redesign, not part of version migration.
282
+
283
+ 4. **Do NOT remove** any existing `<style>` blocks the page already has. The v2-compat block supplements, it doesn't replace.
284
+
285
+ ### Per-theme compat blocks
286
+
287
+ Each v2 theme needs its own compat block because the CSS variable values and hardcoded colors differ. The block above is for **nebula-dusk**. When migrating:
288
+
289
+ - Use the compat block matching the theme the page was originally built under
290
+ - If the original theme is unknown, default to **nebula-dusk** (the system default)
291
+
292
+ ---
293
+
294
+ ## 4. Component Migration
295
+
296
+ ### Overview
297
+
298
+ Component migration (v2 classes → FluentLM `flm-*` classes) is **not** part of the automatic v2→v3 page migration. It is an optional, manual redesign step.
299
+
300
+ ### Why not auto-convert?
301
+
302
+ v2 pages use custom HTML structures with v2-specific classes. FluentLM components have different HTML structures, attributes, and JS wiring. A class-name find-and-replace would break layouts. Instead:
303
+
304
+ - **Migrated v2 pages** keep working as-is via the v2-compat inline styles
305
+ - **New v3 pages** are built fresh using FluentLM components
306
+ - **Manual redesign** can optionally convert a v2 page to use FluentLM components
307
+
308
+ ### Key differences
309
+
310
+ | Aspect | v2 | v3 (FluentLM) |
311
+ |---|---|---|
312
+ | Button | `<button class="modal-btn modal-btn-primary">` | `<button class="flm-button flm-button--primary">` |
313
+ | Input | `<input class="form-input">` | `<input class="flm-textfield-input">` wrapped in `<div class="flm-textfield">` |
314
+ | Modal | `.modal-overlay > .modal-content > .modal-header` | `<div class="flm-dialog">` with `flm-dialog-header` etc. |
315
+ | Colors | `var(--accent-primary)`, `var(--bg-primary)` | `var(--themePrimary)`, `var(--bodyBackground)` |
316
+ | Icons | Manual SVG / emoji | `data-icon="Name"` attribute, auto-injected by FluentLM JS |
317
+ | Theme mode | `.light-mode` / `.dark-mode` on `<html>` | `FluentLM.setTheme('light'/'dark')` or `.fluent-dark` class |
318
+
319
+ ### Pages gallery (required-pages/pages.html)
320
+
321
+ The pages gallery uses FluentLM for dialogs, context menus, search, and pivot tabs, but page links themselves are rendered as **large rounded buttons** (`.page-btn`) rather than `flm-documentcard` cards. This was a deliberate design choice:
322
+
323
+ - Each page link is an `<a class="page-btn">` with `border-radius: 12px` and a centered `.btn-label` text span (120×20px plus padding)
324
+ - Variant classes: `.builder-page` (gradient background), `.pinned` (accent border), `.needs-upgrade` (dashed border + glow animation)
325
+ - The grid uses `display: flex; flex-wrap: wrap; gap: 12px` for layout. **Note:** CSS Grid `gap` did not work reliably inside the viewer panel — flexbox `gap` is the proven alternative
326
+ - Scrolling text animation on hover for names that overflow the button width
327
+ - Context menu uses `flm-contextmenu` + `flm-contextmenu-item`
328
+ - Modals use `flm-dialog-overlay` / `flm-dialog` with `flm-dialog-header/body/footer`
329
+ - Category filtering uses `flm-pivot--tabs` with `flm-pivot-tab` buttons
330
+ - Search uses `flm-searchbox` with `flm-searchbox-input`
331
+ - Toast uses `flm-messagebar--success` with fixed positioning
332
+
333
+ ### Dialog overlay visibility class
334
+
335
+ The `flm-dialog-overlay` is hidden by default (`opacity: 0; pointer-events: none`). To show it programmatically, use `flm-dialog-overlay--open`:
336
+
337
+ ```js
338
+ el.classList.add('flm-dialog-overlay--open'); // show
339
+ el.classList.remove('flm-dialog-overlay--open'); // hide
340
+ ```
341
+
342
+ **Important:** The class is `--open`, not `--visible`. Only `--open` has CSS backing (`opacity: 1; pointer-events: auto`).
343
+ For declarative usage, use `data-dialog-open="id"` / `data-dialog-close` attributes.
344
+
345
+ ### Confirmation dialogs
346
+
347
+ v2 pages use `window.confirm()` or `alert()` for confirmations. v3 pages should use an `flm-dialog-overlay` instead. The pattern:
348
+
349
+ ```html
350
+ <div class="flm-dialog-overlay" id="myConfirm" data-light-dismiss>
351
+ <div class="flm-dialog" style="max-width:400px;width:90%;">
352
+ <div class="flm-dialog-header">
353
+ <h2 class="flm-dialog-title">Confirm</h2>
354
+ </div>
355
+ <div class="flm-dialog-body">
356
+ <p class="flm-text">Are you sure?</p>
357
+ </div>
358
+ <div class="flm-dialog-footer">
359
+ <div style="flex:1;"></div>
360
+ <button class="flm-button" id="confirmCancel">Cancel</button>
361
+ <button class="flm-button" id="confirmOk" style="color:var(--errorText);">Confirm</button>
362
+ </div>
363
+ </div>
364
+ </div>
365
+ ```
366
+
367
+ Open/close programmatically:
368
+
369
+ ```js
370
+ document.getElementById('myConfirm').classList.add('flm-dialog-overlay--open'); // show
371
+ document.getElementById('myConfirm').classList.remove('flm-dialog-overlay--open'); // hide
372
+ ```
373
+
374
+ ### Navigation guards (unsaved changes)
375
+
376
+ When a page tracks dirty state, use a FluentLM confirmation dialog to intercept in-page navigation instead of relying solely on the browser's `beforeunload` prompt.
377
+
378
+ **Key pitfalls and solutions:**
379
+
380
+ 1. **Shell page-script handlers navigate immediately.** Toolbar buttons (`#pagesBtn`, etc.) and link-group anchors have click handlers registered by the page-script that set `window.location` directly. A simple `e.preventDefault()` is not enough — those handlers still fire. Fix: use `e.stopImmediatePropagation()` **and** register in the **capture phase** (`true` as the third argument) so the guard runs before any bubble-phase handlers:
381
+
382
+ ```js
383
+ function guardNavigation(el, url) {
384
+ el.addEventListener('click', function(e) {
385
+ if (!isDirty) return; // clean — let default behavior through
386
+ e.preventDefault();
387
+ e.stopImmediatePropagation(); // block page-script handlers
388
+ showConfirmDialog(url);
389
+ }, true); // capture phase
390
+ }
391
+ ```
392
+
393
+ 2. **Capture the pending URL before closing the dialog.** If your `hideDialog()` helper nulls the pending URL, the leave handler must snapshot it into a local variable first:
394
+
395
+ ```js
396
+ leaveBtn.addEventListener('click', function() {
397
+ var url = pendingNavUrl; // snapshot before hide nulls it
398
+ isDirty = false; // disarm beforeunload
399
+ hideDialog();
400
+ if (url) window.location.href = url;
401
+ });
402
+ ```
403
+
404
+ 3. **Suppress `beforeunload` while the dialog is open.** Otherwise the browser shows its native prompt on top of the themed one:
405
+
406
+ ```js
407
+ window.addEventListener('beforeunload', function(e) {
408
+ if (isDirty && !overlay.classList.contains('flm-dialog-overlay--open')) {
409
+ e.preventDefault();
410
+ }
411
+ });
412
+ ```
413
+
414
+ 4. **Keep `beforeunload` as a fallback.** The themed dialog can only intercept in-page link clicks. Browser close, tab close, and address-bar navigation can only be caught by `beforeunload`.
415
+
416
+ ---
417
+
418
+ ## 5. My Notes Migration — Decisions
419
+
420
+ This section documents design decisions made during the full FluentLM rewrite of `default-pages/my_notes.html`.
421
+
422
+ ### 1. Sidebar is custom layout
423
+
424
+ FluentLM does not provide a sidebar component. The sidebar uses custom layout CSS (`.notes-sidebar` with fixed width, flex column, border) while the **items inside** use `flm-list flm-list--bordered` and `flm-list-item` / `flm-list-item--selected`. This keeps the list items visually consistent with other v3 pages.
425
+
426
+ ### 2. Toast UI editor kept as-is
427
+
428
+ The Toast UI rich text editor is a third-party widget and was not migrated to FluentLM components. Only the **container sizing** (`#editor-container` flex layout) uses layout CSS. The editor's own styles and theme detection (`window.themeInfo.mode`) remain unchanged.
429
+
430
+ ### 3. `confirm()` → `flm-dialog`
431
+
432
+ The browser `window.confirm()` for note deletion was replaced with an `flm-dialog-overlay` + `flm-dialog` confirmation dialog, following the pattern established in §4 (Component Migration — Confirmation dialogs). The dialog uses `flm-dialog-overlay--open` for visibility toggling.
433
+
434
+ ### 4. Sidebar background uses `--defaultStateBackground`, not `--bodyStandoutBackground`
435
+
436
+ Initial attempt used `--bodyStandoutBackground` for the sidebar, but in light themes this token is nearly identical to `--bodyBackground`, producing no visible contrast. `--defaultStateBackground` (used by cards and tiles in settings.html/pages.html) provides reliable contrast in both light and dark themes. The sidebar border was also bumped from 1px to 2px for clearer separation.
437
+
438
+ ### 5. Glow and gradient effects dropped
439
+
440
+ v2 styles used `linear-gradient` backgrounds, `box-shadow` glow effects (`--accent-glow`), and animated hover transforms. These are all removed in the v3 rewrite. FluentLM uses flat semantic tokens (`--bodyBackground`, `--bodyStandoutBackground`, `--neutralLight`) with no glow or gradient effects.
441
+
442
+ ### 6. Button ordering convention
443
+
444
+ In FluentLM dialog footers and action bars, **primary actions (Save, OK) dock rightmost** and **secondary/destructive actions (Delete, Cancel) go to their left**. This is achieved by placing destructive buttons first in HTML source order with `justify-content: flex-end` on the container. The pattern matches the `flm-dialog-footer` layout used in pages.html and the delete confirmation dialog.
445
+
446
+ ### 7. Full component rewrite, not version-bump migration
447
+
448
+ This was a **full rewrite** to FluentLM components, not a v2-compat migration. There is no `<style id="v2-compat">` block — all v2 CSS variables and custom classes were removed and replaced with `flm-*` classes and semantic tokens. The `.light-mode` CSS overrides were also removed since FluentLM handles theme switching automatically.
449
+
450
+ ---
451
+
452
+ ## 6. Games, Animations & Visual-Heavy Pages
453
+
454
+ ### Overview
455
+
456
+ Pages that are primarily canvas-based games, animations, or full-screen visual experiences (e.g. `neon_asteroids`) follow a simplified migration path. These pages typically own all their styling via hardcoded colors and self-contained CSS — they do not depend on v2 theme variables.
457
+
458
+ ### Migration checklist
459
+
460
+ 1. **Add `full-viewer` class** — change `class="viewer-panel"` to `class="viewer-panel full-viewer"` so the content fills the entire viewer area with zero padding. Games and visual pages almost always need this.
461
+
462
+ 2. **Retain all inline styles** — keep the page's existing `<style>` block untouched. These pages use hardcoded colors (e.g. `#0ff`, `#f0f`, `rgba(...)`) and custom fonts, not v2 theme variables. Do not convert them to FluentLM tokens.
463
+
464
+ 3. **No v2-compat block needed** — if the page's `<style>` and inline `style=` attributes do not reference v2 CSS variables (`var(--bg-primary)`, `var(--accent-primary)`, etc.), skip the `<style id="v2-compat">` block entirely. It adds unnecessary weight.
465
+
466
+ 4. **If v2 variables ARE used** — some visual pages may reference a few v2 variables for background or text color. In that case, inject the v2-compat block per §3. But audit first — often only 1–2 variables are used and it may be simpler to replace them with hardcoded values matching the page's aesthetic.
467
+
468
+ 5. **Bump `pageVersion`** — set `"pageVersion": 3` in the page's `page.json`.
469
+
470
+ 6. **Do not convert to FluentLM components** — these pages have no forms, dialogs, or standard UI to migrate. Their content is entirely custom (canvas, SVG, absolute-positioned overlays). Leave the HTML structure and class names as-is.
471
+
472
+ ### Canvas sizing
473
+
474
+ Games that use `<canvas>` typically size to the viewer panel via JavaScript (`viewerPanel.clientWidth` / `clientHeight`). The `full-viewer` class ensures the panel has `padding: 0`, so the canvas fills edge-to-edge. Verify the resize handler still works after migration — it should, since the panel element and ID are unchanged.
475
+
476
+ ### What NOT to change
477
+
478
+ - Game logic scripts — leave all `<script>` blocks untouched
479
+ - Custom fonts (e.g. Google Fonts `<link>` tags) — keep as-is
480
+ - CDN library imports (e.g. html2canvas) — keep as-is
481
+ - Inline `style=` attributes on game elements (e.g. `style="display: none;"` on overlays) — preserve exactly
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "synthos",
3
3
  "author": "Steven Ickman",
4
- "description": "The Hyper-Personalized App Builder That Turns Everyone Into a Programmer.",
5
- "version": "0.8.0",
4
+ "description": "The Hyper-Personalized App Builder That Turns Everyone into a Programmer.",
5
+ "version": "0.10.0",
6
6
  "license": "MIT",
7
7
  "keywords": [
8
8
  "synthos",
9
9
  "ai"
10
10
  ],
11
11
  "bugs": {
12
- "url": "https://github.com/Stevenic/synthos/issues"
12
+ "url": "https://github.com/Stevenic-microsoft/synthtabs/issues"
13
13
  },
14
14
  "repository": {
15
15
  "type": "git",
16
- "url": "https://github.com/Stevenic/synthos.git"
16
+ "url": "https://github.com/Stevenic-microsoft/synthtabs.git"
17
17
  },
18
18
  "main": "./dist/index.js",
19
19
  "types": "./dist/index.d.ts",
@@ -45,22 +45,23 @@
45
45
  "typescript": "^4.2.3"
46
46
  },
47
47
  "scripts": {
48
- "build": "tsc -b && node scripts/copy-connector-json.js",
48
+ "build": "tsc -b",
49
49
  "clean": "rimraf dist tsconfig.tsbuildinfo node_modules",
50
- "start": "node ./bin/synthos.js",
50
+ "start": "node ./bin/synthos.js start",
51
51
  "test": "npm run build && npm run test:mocha",
52
- "test:mocha": "nyc ts-mocha tests/**/*.spec.ts"
52
+ "test:mocha": "nyc ts-mocha tests/**/*.spec.ts teams-tests/**/*.spec.ts"
53
53
  },
54
54
  "files": [
55
55
  "dist",
56
56
  "bin",
57
57
  "src",
58
- "tests",
59
58
  "default-pages",
60
59
  "default-scripts",
61
60
  "default-themes",
62
- "page-scripts",
61
+ "static-files",
63
62
  "required-pages",
64
- "images"
63
+ "service-connectors",
64
+ "migration-rules",
65
+ "tests"
65
66
  ]
66
67
  }
@@ -0,0 +1,43 @@
1
+ <!DOCTYPE html><html lang="en"><head>
2
+ <meta charset="UTF-8">
3
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
4
+ <title>SynthOS</title>
5
+ <script id="theme-info" src="/api/theme-info.js" data-locked="true"></script>
6
+ <link id="theme-css" rel="stylesheet" href="/api/theme.css" data-locked="true">
7
+ <style>.idle-container{position:absolute;width:100%;height:100%;pointer-events:none;opacity:1;transition:opacity 1s ease-out}.idle-container.hidden{opacity:0}.breathing-orb{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:80px;height:80px;border-radius:50%;background:radial-gradient(circle,rgba(102,126,234,.15) 0,transparent 70%);animation:4s ease-in-out infinite breathe}.breathing-orb::before{content:'';position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:8px;height:8px;border-radius:50%;background:rgba(183,148,246,.6);box-shadow:0 0 20px rgba(183,148,246,.4);animation:4s ease-in-out infinite core-pulse}@keyframes breathe{0%,100%{width:80px;height:80px;opacity:.3}50%{width:120px;height:120px;opacity:.6}}@keyframes core-pulse{0%,100%{opacity:.4;box-shadow:0 0 20px rgba(183,148,246,.3)}50%{opacity:.8;box-shadow:0 0 30px rgba(183,148,246,.5)}}.orbit-ring{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:200px;height:200px;border:1px solid rgba(102,126,234,.1);border-radius:50%;animation:20s linear infinite orbit-rotate}.orbit-ring::after{content:'';position:absolute;top:-3px;left:50%;transform:translateX(-50%);width:6px;height:6px;background:rgba(240,147,251,.5);border-radius:50%;box-shadow:0 0 10px rgba(240,147,251,.3)}@keyframes orbit-rotate{from{transform:translate(-50%,-50%) rotate(0)}to{transform:translate(-50%,-50%) rotate(360deg)}}</style>
8
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js"></script>
9
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/14.1.1/marked.min.js"></script>
10
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/11.1.0/mermaid.min.js"></script>
11
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
12
+ <script id="page-info" src="/api/page-info.js?page=builder"></script>
13
+ </head>
14
+ <body>
15
+ <div class="shell-toolbar" data-locked="true">
16
+ <button class="shell-toolbar-btn" id="builderToggle" aria-label="Page Builder" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M7 18.5H6.2c-1.77 0-3.2-1.43-3.2-3.2V7.7C3 5.93 4.43 4.5 6.2 4.5h11.6c1.77 0 3.2 1.43 3.2 3.2v7.6c0 1.77-1.43 3.2-3.2 3.2H12l-4.2 3.2c-.5.38-1.2.02-1.2-.6V18.5Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><circle cx="8.5" cy="11.5" r="1" fill="currentColor"/><circle cx="12" cy="11.5" r="1" fill="currentColor"/><circle cx="15.5" cy="11.5" r="1" fill="currentColor"/></svg></button>
17
+ <button class="shell-toolbar-btn" id="pagesBtn" aria-label="View All Pages" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none"><rect x="3" y="3" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M6 7.5h5M6 10h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="18" y="3" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M21 7.5h5M21 10h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="3" y="18" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M6 22.5h5M6 25h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="18" y="18" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M21 22.5h5M21 25h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></button>
18
+ <button class="shell-toolbar-btn" id="saveBtn" aria-label="Save Page" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M17 21v-8H7v8" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M7 3v5h8" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></svg></button>
19
+ <div class="shell-toolbar-spacer" data-locked="true"></div>
20
+ <button class="shell-toolbar-btn" id="settingsBtn" aria-label="Settings" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" stroke="currentColor" stroke-width="1.8"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
21
+ </div>
22
+ <div class="chat-panel" data-locked="true">
23
+ <div class="chat-header" data-locked="true"><span>Page Builder</span><button class="chat-header-close" id="builderClose" aria-label="Close builder" data-locked="true">&times;</button></div>
24
+ <div class="chat-messages" id="chatMessages" data-locked="true">
25
+ <div class="chat-message" id="defaultGreeting"><p><strong>SynthOS:</strong> What can I create for you? Ask "what can you do?" or "how does this work?" to learn more. Remember to save often!</p></div>
26
+ </div>
27
+ <form action="/" method="POST" id="chatForm" data-locked="true">
28
+ <textarea class="chat-input" id="chatInput" name="message" rows="2" placeholder="Type a message..." data-locked="true"></textarea>
29
+ </form>
30
+ </div>
31
+ <div class="viewer-panel" id="viewerPanel">
32
+ <div class="idle-container" id="idleAnimation">
33
+ <div class="orbit-ring"></div>
34
+ <div class="breathing-orb"></div>
35
+ </div>
36
+ <div id="loadingOverlay" class="loading-overlay"><div class="spinner"></div></div>
37
+ </div>
38
+ <div id="instructions" style="display: none;" data-locked="true"></div>
39
+ <div id="thoughts" style="display: none;" data-locked="true"></div>
40
+ <script id="idle-animation">function hideIdleAnimation(){const idleContainer=document.getElementById("idleAnimation");idleContainer&&(idleContainer.classList.add("hidden"),setTimeout(()=>{idleContainer.style.display="none"},1e3))}function showIdleAnimation(){const idleContainer=document.getElementById("idleAnimation");idleContainer&&(idleContainer.style.display="block",setTimeout(()=>{idleContainer.classList.remove("hidden")},10))}</script>
41
+ <script id="page-helpers" src="/api/page-helpers.js?v=3" data-locked="true"></script>
42
+ <script id="page-script" src="/api/page-script.js?v=3" data-locked="true"></script>
43
+ </body></html>
@@ -0,0 +1,10 @@
1
+ {
2
+ "title": "Page Builder",
3
+ "categories": [
4
+ "System"
5
+ ],
6
+ "pinned": true,
7
+ "showInAll": true,
8
+ "pageVersion": 3,
9
+ "mode": "unlocked"
10
+ }