synthos 0.10.0 → 0.11.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 (312) hide show
  1. package/README.md +5 -5
  2. package/default-pages/elevenlabs_effects_studio/chat-history.json +1 -0
  3. package/default-pages/elevenlabs_effects_studio/page.html +1345 -1363
  4. package/default-pages/elevenlabs_effects_studio/page.json +13 -11
  5. package/default-pages/elevenlabs_voice_studio/chat-history.json +1 -0
  6. package/default-pages/elevenlabs_voice_studio/page.html +782 -801
  7. package/default-pages/elevenlabs_voice_studio/page.json +13 -11
  8. package/default-pages/json_tools/chat-history.json +1 -0
  9. package/default-pages/json_tools/page.html +70 -90
  10. package/default-pages/json_tools/page.json +12 -10
  11. package/default-pages/my_notes/chat-history.json +1 -0
  12. package/default-pages/my_notes/page.html +115 -131
  13. package/default-pages/my_notes/page.json +14 -12
  14. package/default-pages/neon_asteroids/chat-history.json +1 -0
  15. package/default-pages/neon_asteroids/page.html +1777 -1803
  16. package/default-pages/neon_asteroids/page.json +14 -12
  17. package/default-pages/oregon_trail/chat-history.json +1 -0
  18. package/default-pages/oregon_trail/page.html +290 -307
  19. package/default-pages/oregon_trail/page.json +14 -12
  20. package/default-pages/solar_explorer/chat-history.json +1 -0
  21. package/default-pages/solar_explorer/page.html +1929 -1951
  22. package/default-pages/solar_explorer/page.json +14 -12
  23. package/default-pages/solar_tutorial/chat-history.json +1 -0
  24. package/default-pages/solar_tutorial/page.html +464 -478
  25. package/default-pages/solar_tutorial/page.json +12 -10
  26. package/default-pages/us_map/chat-history.json +1 -0
  27. package/default-pages/us_map/page.html +170 -193
  28. package/default-pages/us_map/page.json +14 -12
  29. package/default-pages/us_map/page.light.png +0 -0
  30. package/default-pages/us_map_1850/chat-history.json +1 -0
  31. package/default-pages/us_map_1850/page.html +302 -326
  32. package/default-pages/us_map_1850/page.json +14 -12
  33. package/default-pages/western_cities_1850/chat-history.json +1 -0
  34. package/default-pages/western_cities_1850/page.html +503 -527
  35. package/default-pages/western_cities_1850/page.json +14 -12
  36. package/default-themes/aurora-dawn.v3.css +15 -14
  37. package/default-themes/aurora-dusk.v3.css +26 -26
  38. package/default-themes/cosmos-dawn.v3.css +15 -14
  39. package/default-themes/cosmos-dusk.v3.css +26 -26
  40. package/default-themes/elemental-dawn.v3.css +200 -0
  41. package/default-themes/nebula-dawn.v3.css +15 -14
  42. package/default-themes/nebula-dusk.v3.css +24 -24
  43. package/default-themes/solar-flare-dawn.v3.css +15 -14
  44. package/default-themes/solar-flare-dusk.v3.css +26 -26
  45. package/dist/builders/anthropic.d.ts +26 -2
  46. package/dist/builders/anthropic.d.ts.map +1 -1
  47. package/dist/builders/anthropic.js +132 -31
  48. package/dist/builders/anthropic.js.map +1 -1
  49. package/dist/builders/claudecode.d.ts +13 -0
  50. package/dist/builders/claudecode.d.ts.map +1 -0
  51. package/dist/builders/claudecode.js +253 -0
  52. package/dist/builders/claudecode.js.map +1 -0
  53. package/dist/builders/index.d.ts +2 -1
  54. package/dist/builders/index.d.ts.map +1 -1
  55. package/dist/builders/index.js +8 -1
  56. package/dist/builders/index.js.map +1 -1
  57. package/dist/builders/openai.js +2 -1
  58. package/dist/builders/openai.js.map +1 -1
  59. package/dist/builders/types.d.ts +31 -7
  60. package/dist/builders/types.d.ts.map +1 -1
  61. package/dist/builders/types.js +60 -28
  62. package/dist/builders/types.js.map +1 -1
  63. package/dist/connectors/types.d.ts +8 -0
  64. package/dist/connectors/types.d.ts.map +1 -1
  65. package/dist/init.d.ts.map +1 -1
  66. package/dist/init.js +13 -6
  67. package/dist/init.js.map +1 -1
  68. package/dist/migrations.d.ts.map +1 -1
  69. package/dist/migrations.js +161 -14
  70. package/dist/migrations.js.map +1 -1
  71. package/dist/models/anthropic.d.ts +1 -0
  72. package/dist/models/anthropic.d.ts.map +1 -1
  73. package/dist/models/anthropic.js +129 -29
  74. package/dist/models/anthropic.js.map +1 -1
  75. package/dist/models/chainOfThought.d.ts.map +1 -1
  76. package/dist/models/chainOfThought.js +32 -19
  77. package/dist/models/chainOfThought.js.map +1 -1
  78. package/dist/models/index.d.ts +2 -2
  79. package/dist/models/index.d.ts.map +1 -1
  80. package/dist/models/index.js +2 -1
  81. package/dist/models/index.js.map +1 -1
  82. package/dist/models/providers.d.ts +1 -0
  83. package/dist/models/providers.d.ts.map +1 -1
  84. package/dist/models/providers.js +12 -4
  85. package/dist/models/providers.js.map +1 -1
  86. package/dist/models/types.d.ts +15 -1
  87. package/dist/models/types.d.ts.map +1 -1
  88. package/dist/models/types.js.map +1 -1
  89. package/dist/pages.d.ts +57 -8
  90. package/dist/pages.d.ts.map +1 -1
  91. package/dist/pages.js +258 -45
  92. package/dist/pages.js.map +1 -1
  93. package/dist/service/createCompletePrompt.d.ts.map +1 -1
  94. package/dist/service/createCompletePrompt.js +5 -0
  95. package/dist/service/createCompletePrompt.js.map +1 -1
  96. package/dist/service/mediaCache.d.ts +36 -0
  97. package/dist/service/mediaCache.d.ts.map +1 -0
  98. package/dist/service/mediaCache.js +182 -0
  99. package/dist/service/mediaCache.js.map +1 -0
  100. package/dist/service/pageValidator.d.ts +25 -0
  101. package/dist/service/pageValidator.d.ts.map +1 -0
  102. package/dist/service/pageValidator.js +315 -0
  103. package/dist/service/pageValidator.js.map +1 -0
  104. package/dist/service/server.d.ts.map +1 -1
  105. package/dist/service/server.js +4 -0
  106. package/dist/service/server.js.map +1 -1
  107. package/dist/service/sharedTableSchema.d.ts +73 -0
  108. package/dist/service/sharedTableSchema.d.ts.map +1 -0
  109. package/dist/service/sharedTableSchema.js +206 -0
  110. package/dist/service/sharedTableSchema.js.map +1 -0
  111. package/dist/service/transformPage.d.ts +49 -11
  112. package/dist/service/transformPage.d.ts.map +1 -1
  113. package/dist/service/transformPage.js +354 -241
  114. package/dist/service/transformPage.js.map +1 -1
  115. package/dist/service/useApiRoutes.d.ts.map +1 -1
  116. package/dist/service/useApiRoutes.js +288 -34
  117. package/dist/service/useApiRoutes.js.map +1 -1
  118. package/dist/service/useConnectorRoutes.d.ts.map +1 -1
  119. package/dist/service/useConnectorRoutes.js +170 -32
  120. package/dist/service/useConnectorRoutes.js.map +1 -1
  121. package/dist/service/useDataRoutes.d.ts.map +1 -1
  122. package/dist/service/useDataRoutes.js +59 -2
  123. package/dist/service/useDataRoutes.js.map +1 -1
  124. package/dist/service/useExtractRoutes.d.ts +4 -0
  125. package/dist/service/useExtractRoutes.d.ts.map +1 -0
  126. package/dist/service/useExtractRoutes.js +304 -0
  127. package/dist/service/useExtractRoutes.js.map +1 -0
  128. package/dist/service/usePageRoutes.d.ts +17 -0
  129. package/dist/service/usePageRoutes.d.ts.map +1 -1
  130. package/dist/service/usePageRoutes.js +1385 -483
  131. package/dist/service/usePageRoutes.js.map +1 -1
  132. package/dist/service/useSharedDataRoutes.d.ts.map +1 -1
  133. package/dist/service/useSharedDataRoutes.js +54 -2
  134. package/dist/service/useSharedDataRoutes.js.map +1 -1
  135. package/dist/settings.d.ts +27 -0
  136. package/dist/settings.d.ts.map +1 -1
  137. package/dist/settings.js +40 -1
  138. package/dist/settings.js.map +1 -1
  139. package/dist/themes.d.ts +0 -5
  140. package/dist/themes.d.ts.map +1 -1
  141. package/dist/themes.js +3 -95
  142. package/dist/themes.js.map +1 -1
  143. package/migration-rules/v2-to-v3.md +277 -119
  144. package/package.json +5 -1
  145. package/{default-pages/application → required-pages/_shell}/page.html +56 -42
  146. package/required-pages/_shell/page.json +14 -0
  147. package/required-pages/_starters/page.html +534 -0
  148. package/required-pages/_starters/page.json +12 -0
  149. package/required-pages/builder/page.html +353 -43
  150. package/required-pages/builder/page.json +12 -10
  151. package/required-pages/pages/page.html +697 -924
  152. package/required-pages/pages/page.json +12 -10
  153. package/required-pages/settings/page.html +1879 -1753
  154. package/required-pages/settings/page.json +12 -10
  155. package/required-pages/synthos_apis/page.html +834 -845
  156. package/required-pages/synthos_apis/page.json +12 -10
  157. package/required-pages/synthos_scripts/page.html +74 -88
  158. package/required-pages/synthos_scripts/page.json +12 -10
  159. package/scripts/append-instructions.py +90 -0
  160. package/scripts/audit-instructions.py +76 -0
  161. package/scripts/cleanup-shell-markup.mjs +112 -0
  162. package/service-connectors/buffer/connector.json +46 -0
  163. package/service-connectors/canva/connector.json +67 -0
  164. package/service-connectors/elevenlabs/connector.json +1 -1
  165. package/src/builders/anthropic.ts +155 -30
  166. package/src/builders/claudecode.ts +310 -0
  167. package/src/builders/index.ts +7 -1
  168. package/src/builders/openai.ts +2 -1
  169. package/src/builders/types.ts +93 -32
  170. package/src/connectors/types.ts +8 -0
  171. package/src/init.ts +13 -7
  172. package/src/migrations.ts +187 -16
  173. package/src/models/anthropic.ts +140 -30
  174. package/src/models/chainOfThought.ts +33 -18
  175. package/src/models/index.ts +2 -2
  176. package/src/models/providers.ts +12 -3
  177. package/src/models/types.ts +21 -1
  178. package/src/pages.ts +271 -35
  179. package/src/service/createCompletePrompt.ts +6 -0
  180. package/src/service/mediaCache.ts +206 -0
  181. package/src/service/pageValidator.ts +337 -0
  182. package/src/service/server.ts +4 -0
  183. package/src/service/sharedTableSchema.ts +236 -0
  184. package/src/service/transformPage.ts +370 -260
  185. package/src/service/useApiRoutes.ts +282 -32
  186. package/src/service/useConnectorRoutes.ts +189 -34
  187. package/src/service/useDataRoutes.ts +198 -116
  188. package/src/service/useExtractRoutes.ts +331 -0
  189. package/src/service/usePageRoutes.ts +1411 -394
  190. package/src/service/useSharedDataRoutes.ts +184 -109
  191. package/src/settings.ts +65 -0
  192. package/src/themes.ts +78 -180
  193. package/starters/blank_starter/chat-history.json +1 -0
  194. package/starters/blank_starter/page.dark.png +0 -0
  195. package/starters/blank_starter/page.html +47 -0
  196. package/starters/blank_starter/page.json +13 -0
  197. package/starters/blank_starter/page.light.png +0 -0
  198. package/starters/calculator_starter/chat-history.json +1 -0
  199. package/starters/calculator_starter/page.dark.png +0 -0
  200. package/starters/calculator_starter/page.html +232 -0
  201. package/starters/calculator_starter/page.json +13 -0
  202. package/starters/calculator_starter/page.light.png +0 -0
  203. package/starters/calendar_starter/chat-history.json +1 -0
  204. package/starters/calendar_starter/page.dark.png +0 -0
  205. package/starters/calendar_starter/page.html +495 -0
  206. package/starters/calendar_starter/page.json +13 -0
  207. package/starters/calendar_starter/page.light.png +0 -0
  208. package/starters/chat_starter/chat-history.json +1 -0
  209. package/starters/chat_starter/page.dark.png +0 -0
  210. package/starters/chat_starter/page.html +351 -0
  211. package/starters/chat_starter/page.json +13 -0
  212. package/starters/chat_starter/page.light.png +0 -0
  213. package/starters/checklist_starter/chat-history.json +1 -0
  214. package/starters/checklist_starter/page.dark.png +0 -0
  215. package/starters/checklist_starter/page.html +437 -0
  216. package/starters/checklist_starter/page.json +13 -0
  217. package/starters/checklist_starter/page.light.png +0 -0
  218. package/starters/dashboard_starter/chat-history.json +1 -0
  219. package/starters/dashboard_starter/page.dark.png +0 -0
  220. package/starters/dashboard_starter/page.html +195 -0
  221. package/starters/dashboard_starter/page.json +13 -0
  222. package/starters/dashboard_starter/page.light.png +0 -0
  223. package/starters/form_starter/chat-history.json +1 -0
  224. package/starters/form_starter/page.dark.png +0 -0
  225. package/starters/form_starter/page.html +313 -0
  226. package/starters/form_starter/page.json +13 -0
  227. package/starters/form_starter/page.light.png +0 -0
  228. package/starters/gallery_starter/chat-history.json +1 -0
  229. package/starters/gallery_starter/page.dark.png +0 -0
  230. package/starters/gallery_starter/page.html +418 -0
  231. package/starters/gallery_starter/page.json +13 -0
  232. package/starters/gallery_starter/page.light.png +0 -0
  233. package/starters/generator_starter/chat-history.json +1 -0
  234. package/starters/generator_starter/page.dark.png +0 -0
  235. package/starters/generator_starter/page.html +261 -0
  236. package/starters/generator_starter/page.json +13 -0
  237. package/starters/generator_starter/page.light.png +0 -0
  238. package/starters/index.html +538 -0
  239. package/starters/kanban_starter/chat-history.json +1 -0
  240. package/starters/kanban_starter/page.dark.png +0 -0
  241. package/starters/kanban_starter/page.html +432 -0
  242. package/starters/kanban_starter/page.json +13 -0
  243. package/starters/kanban_starter/page.light.png +0 -0
  244. package/starters/presentation_builder/chat-history.json +1 -0
  245. package/starters/presentation_builder/page.dark.png +0 -0
  246. package/starters/presentation_builder/page.html +970 -0
  247. package/starters/presentation_builder/page.json +15 -0
  248. package/starters/presentation_builder/page.light.png +0 -0
  249. package/starters/presentation_builder/presentation_voice/voice_config.json +9 -0
  250. package/starters/pulse_starter/chat-history.json +1 -0
  251. package/starters/pulse_starter/page.dark.png +0 -0
  252. package/starters/pulse_starter/page.html +698 -0
  253. package/starters/pulse_starter/page.json +13 -0
  254. package/starters/pulse_starter/page.light.png +0 -0
  255. package/starters/quiz_starter/chat-history.json +1 -0
  256. package/starters/quiz_starter/page.dark.png +0 -0
  257. package/starters/quiz_starter/page.html +292 -0
  258. package/starters/quiz_starter/page.json +13 -0
  259. package/starters/quiz_starter/page.light.png +0 -0
  260. package/starters/reference_starter/chat-history.json +1 -0
  261. package/starters/reference_starter/page.dark.png +0 -0
  262. package/starters/reference_starter/page.html +250 -0
  263. package/starters/reference_starter/page.json +13 -0
  264. package/starters/reference_starter/page.light.png +0 -0
  265. package/starters/retro_game_starter/chat-history.json +1 -0
  266. package/starters/retro_game_starter/page.dark.png +0 -0
  267. package/{default-pages → starters}/retro_game_starter/page.html +1281 -1308
  268. package/starters/retro_game_starter/page.json +15 -0
  269. package/starters/retro_game_starter/page.light.png +0 -0
  270. package/starters/roster_starter/chat-history.json +1 -0
  271. package/starters/roster_starter/page.dark.png +0 -0
  272. package/starters/roster_starter/page.html +600 -0
  273. package/starters/roster_starter/page.json +13 -0
  274. package/starters/roster_starter/page.light.png +0 -0
  275. package/starters/server.js +182 -0
  276. package/starters/start.cmd +1 -0
  277. package/starters/timeline_starter/chat-history.json +1 -0
  278. package/starters/timeline_starter/page.dark.png +0 -0
  279. package/starters/timeline_starter/page.html +446 -0
  280. package/starters/timeline_starter/page.json +13 -0
  281. package/starters/timeline_starter/page.light.png +0 -0
  282. package/starters/tutorial_starter/chat-history.json +1 -0
  283. package/starters/tutorial_starter/page.dark.png +0 -0
  284. package/starters/tutorial_starter/page.html +283 -0
  285. package/starters/tutorial_starter/page.json +13 -0
  286. package/starters/tutorial_starter/page.light.png +0 -0
  287. package/static-files/agent.v3.js +122 -0
  288. package/static-files/connector.v3.js +48 -0
  289. package/static-files/extract.v3.js +188 -0
  290. package/static-files/helpers.v3.js +50 -6
  291. package/static-files/page-bridge.js +114 -0
  292. package/static-files/page.v3.js +1292 -1290
  293. package/static-files/script.v3.js +32 -0
  294. package/static-files/server.v3.js +89 -0
  295. package/static-files/shell-bridge.v3.js +174 -0
  296. package/static-files/shell-modals.v3.js +521 -0
  297. package/static-files/{shell.css → shell.v3.css} +271 -22
  298. package/static-files/shell.v3.js +1865 -0
  299. package/static-files/storage.v3.js +176 -0
  300. package/tests/anthropic.spec.ts +42 -7
  301. package/tests/builders.spec.ts +72 -4
  302. package/tests/pageValidator.spec.ts +548 -0
  303. package/tests/profiles.spec.ts +122 -0
  304. package/tests/providers.spec.ts +1 -1
  305. package/tests/sharedTableSchema.spec.ts +242 -0
  306. package/tests/transformPage.spec.ts +62 -81
  307. package/default-pages/application/page.json +0 -10
  308. package/default-pages/retro_game_starter/page.json +0 -12
  309. package/default-pages/sidebar_page/page.html +0 -51
  310. package/default-pages/sidebar_page/page.json +0 -10
  311. package/default-pages/two-panel_page/page.html +0 -68
  312. package/default-pages/two-panel_page/page.json +0 -10
@@ -1,43 +1,353 @@
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>
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>
8
+ html, body, .viewer-panel { height: 100%; margin: 0; }
9
+ .builder-carousel-wrap {
10
+ height: 100%;
11
+ display: flex;
12
+ flex-direction: column;
13
+ background: var(--bodyBackground, #ffffff);
14
+ color: var(--bodyText, #1f1f1f);
15
+ overflow: hidden;
16
+ }
17
+ .carousel-header {
18
+ padding: 28px 32px 18px;
19
+ display: flex;
20
+ flex-direction: column;
21
+ gap: 16px;
22
+ flex: 0 0 auto;
23
+ }
24
+ .carousel-header-text { display: flex; flex-direction: column; gap: 6px; }
25
+ .carousel-title { font-size: 22px; font-weight: 600; }
26
+ .carousel-hint { font-size: 14px; color: var(--bodySubtext, #605e5c); }
27
+ .carousel-search {
28
+ width: 360px;
29
+ max-width: 100%;
30
+ padding: 10px 14px;
31
+ border: 1px solid var(--inputBorder, #8a8886);
32
+ border-radius: 6px;
33
+ font-size: 14px;
34
+ background: var(--bodyBackground, #ffffff);
35
+ color: var(--bodyText, #1f1f1f);
36
+ font-family: inherit;
37
+ box-sizing: border-box;
38
+ }
39
+ .carousel-search:focus {
40
+ outline: none;
41
+ border-color: var(--themePrimary, #0078d4);
42
+ box-shadow: 0 0 0 1px var(--themePrimary, #0078d4);
43
+ }
44
+ .carousel-row {
45
+ flex: 1 1 auto;
46
+ min-height: 0;
47
+ display: grid;
48
+ grid-template-columns: repeat(auto-fill, 300px);
49
+ grid-auto-rows: min-content;
50
+ gap: 20px;
51
+ padding: 24px 32px 32px;
52
+ overflow-y: auto;
53
+ overflow-x: hidden;
54
+ align-content: start;
55
+ justify-content: start;
56
+ }
57
+ .starter-card {
58
+ width: 300px;
59
+ min-height: 288px;
60
+ border-radius: 12px;
61
+ overflow: hidden;
62
+ background: var(--defaultStateBackground, #faf9f8);
63
+ border: 1px solid color-mix(in srgb, var(--inputBorder, #8a8886) 40%, transparent);
64
+ cursor: pointer;
65
+ display: flex;
66
+ flex-direction: column;
67
+ align-self: start;
68
+ transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
69
+ }
70
+ .starter-card:hover {
71
+ transform: translateY(-2px);
72
+ border-color: var(--themePrimary, #0078d4);
73
+ box-shadow: 0 8px 24px rgba(0,0,0,.14),
74
+ 0 0 0 1px var(--themePrimary, #0078d4);
75
+ }
76
+ .starter-card:focus {
77
+ outline: none;
78
+ border-color: var(--themePrimary, #0078d4);
79
+ box-shadow: 0 0 0 2px var(--themePrimary, #0078d4);
80
+ }
81
+ .starter-card-img {
82
+ flex: 0 0 200px;
83
+ width: 100%;
84
+ height: 200px;
85
+ min-height: 200px;
86
+ display: block;
87
+ background-color: var(--bodyBackgroundHovered, #f3f2f1);
88
+ background-size: cover;
89
+ background-position: top center;
90
+ background-repeat: no-repeat;
91
+ }
92
+ .starter-card-footer {
93
+ flex: 0 0 auto;
94
+ padding: 14px 18px;
95
+ border-top: 1px solid var(--bodyDivider, #edebe9);
96
+ background: var(--defaultStateBackground, #faf9f8);
97
+ display: flex;
98
+ flex-direction: column;
99
+ gap: 4px;
100
+ box-sizing: border-box;
101
+ }
102
+ .starter-card-title {
103
+ font-size: 16px;
104
+ font-weight: 600;
105
+ color: var(--bodyText, #1f1f1f);
106
+ white-space: nowrap;
107
+ overflow: hidden;
108
+ text-overflow: ellipsis;
109
+ }
110
+ .starter-card-desc {
111
+ font-size: 13px;
112
+ line-height: 1.4;
113
+ color: var(--bodySubtext, #605e5c);
114
+ display: -webkit-box;
115
+ -webkit-line-clamp: 2;
116
+ -webkit-box-orient: vertical;
117
+ overflow: hidden;
118
+ min-height: calc(13px * 1.4 * 2);
119
+ }
120
+ .empty-results {
121
+ grid-column: 1 / -1;
122
+ color: var(--bodySubtext, #605e5c);
123
+ font-size: 14px;
124
+ }
125
+ .carousel-loading {
126
+ grid-column: 1 / -1;
127
+ font-size: 14px;
128
+ color: var(--bodySubtext, #605e5c);
129
+ }
130
+ </style>
131
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js"></script>
132
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/14.1.1/marked.min.js"></script>
133
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/11.1.0/mermaid.min.js"></script>
134
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
135
+ <script id="page-info" src="/api/page-info.js?page=builder"></script>
136
+ </head>
137
+ <body>
138
+ <div class="viewer-panel" id="viewerPanel" style="padding: 0;">
139
+ <div class="builder-carousel-wrap">
140
+ <div class="carousel-header">
141
+ <div class="carousel-header-text">
142
+ <div class="carousel-title">Pick a starter, or just describe what you want.</div>
143
+ <div class="carousel-hint">Click a card to start from its scaffold, or type into the chat to build from a blank page.</div>
144
+ </div>
145
+ <input type="search" class="carousel-search" id="starterSearch" placeholder="Search starters..." autocomplete="off">
146
+ </div>
147
+ <div class="carousel-row" id="carouselRow">
148
+ <div class="carousel-loading">Loading starters…</div>
149
+ </div>
150
+ </div>
151
+ <div id="loadingOverlay" class="loading-overlay"><div class="spinner"></div></div>
152
+ </div>
153
+ <div id="instructions" style="display: none;" data-locked="true"></div>
154
+ <div id="thoughts" style="display: none;" data-locked="true"></div>
155
+ <script id="builder-carousel">
156
+ (function() {
157
+ 'use strict';
158
+ var BLANK_NAME = 'blank_starter';
159
+ var MRU_TABLE = 'builder_mru';
160
+ var MRU_ID = 'builder';
161
+ var MRU_CAP = 20;
162
+
163
+ var starters = [];
164
+ var mru = [];
165
+ var searchTerm = '';
166
+ var carouselRow = document.getElementById('carouselRow');
167
+ var searchInput = document.getElementById('starterSearch');
168
+
169
+ function themeVariant() {
170
+ var html = document.documentElement;
171
+ if (html.classList.contains('dark-mode')) return 'dark';
172
+ if (html.classList.contains('light-mode')) return 'light';
173
+ // Fallback: if /api/theme-info.js set window.themeInfo, infer from there
174
+ if (window.themeInfo && window.themeInfo.mode) {
175
+ return window.themeInfo.mode === 'dark' ? 'dark' : 'light';
176
+ }
177
+ return 'light';
178
+ }
179
+
180
+ function imageUrlFor(name) {
181
+ return '/api/starters/' + encodeURIComponent(name) + '/screenshot/' + themeVariant();
182
+ }
183
+
184
+ function displayName(p) { return p.title || p.name; }
185
+ function description(p) { return p.description || ''; }
186
+
187
+ function navigateToStarter(name) {
188
+ var url = '/builder/' + encodeURIComponent(name);
189
+ var firstRun = new URLSearchParams(window.location.search).get('firstRun');
190
+ if (firstRun) {
191
+ url += '?firstRun=' + encodeURIComponent(firstRun);
192
+ }
193
+ if (window.synthos && window.synthos.shell && typeof window.synthos.shell.navigate === 'function') {
194
+ window.synthos.shell.navigate(url);
195
+ } else {
196
+ window.location.href = url;
197
+ }
198
+ }
199
+
200
+ async function recordMru(name) {
201
+ if (name === BLANK_NAME) return;
202
+ mru = [name].concat(mru.filter(function(s) { return s !== name; })).slice(0, MRU_CAP);
203
+ try {
204
+ if (window.synthos && window.synthos.shared && window.synthos.shared.data) {
205
+ await window.synthos.shared.data.save(MRU_TABLE, { id: MRU_ID, starters: mru });
206
+ }
207
+ } catch (e) {
208
+ console.error('Failed to save builder MRU:', e);
209
+ }
210
+ }
211
+
212
+ async function loadMru() {
213
+ try {
214
+ if (window.synthos && window.synthos.shared && window.synthos.shared.data) {
215
+ var rec = await window.synthos.shared.data.get(MRU_TABLE, MRU_ID);
216
+ if (rec && Array.isArray(rec.starters)) {
217
+ mru = rec.starters.filter(function(s) { return typeof s === 'string'; }).slice(0, MRU_CAP);
218
+ return;
219
+ }
220
+ }
221
+ } catch (e) {
222
+ console.error('Failed to load builder MRU:', e);
223
+ }
224
+ mru = [];
225
+ }
226
+
227
+ function sortedForDisplay() {
228
+ var blank = starters.filter(function(p) { return p.name === BLANK_NAME; });
229
+ var rest = starters.filter(function(p) { return p.name !== BLANK_NAME; });
230
+ var term = searchTerm.trim().toLowerCase();
231
+
232
+ if (term) {
233
+ // Search mode: ignore the Blank pin; surface all matches in MRU-first order.
234
+ var filtered = starters.filter(function(p) {
235
+ return displayName(p).toLowerCase().indexOf(term) !== -1
236
+ || description(p).toLowerCase().indexOf(term) !== -1;
237
+ });
238
+ return filtered.sort(function(a, b) {
239
+ var ai = mru.indexOf(a.name);
240
+ var bi = mru.indexOf(b.name);
241
+ if (ai !== -1 && bi !== -1) return ai - bi;
242
+ if (ai !== -1) return -1;
243
+ if (bi !== -1) return 1;
244
+ return displayName(a).localeCompare(displayName(b));
245
+ });
246
+ }
247
+
248
+ // No search: blank first, then MRU order, then alphabetical.
249
+ var inMru = [];
250
+ var notInMru = [];
251
+ rest.forEach(function(p) {
252
+ if (mru.indexOf(p.name) !== -1) inMru.push(p);
253
+ else notInMru.push(p);
254
+ });
255
+ inMru.sort(function(a, b) { return mru.indexOf(a.name) - mru.indexOf(b.name); });
256
+ notInMru.sort(function(a, b) { return displayName(a).localeCompare(displayName(b)); });
257
+ return blank.concat(inMru, notInMru);
258
+ }
259
+
260
+ function renderCarousel() {
261
+ carouselRow.innerHTML = '';
262
+ var ordered = sortedForDisplay();
263
+ if (ordered.length === 0) {
264
+ var empty = document.createElement('div');
265
+ empty.className = 'empty-results';
266
+ empty.textContent = 'No starters match — describe what you want and we\'ll start from a blank page.';
267
+ carouselRow.appendChild(empty);
268
+ return;
269
+ }
270
+ ordered.forEach(function(p) {
271
+ var card = document.createElement('div');
272
+ card.className = 'starter-card';
273
+ card.tabIndex = 0;
274
+ card.dataset.starter = p.name;
275
+ card.title = displayName(p);
276
+
277
+ var img = document.createElement('div');
278
+ img.className = 'starter-card-img';
279
+ img.style.backgroundImage = "url('" + imageUrlFor(p.name) + "')";
280
+
281
+ var footer = document.createElement('div');
282
+ footer.className = 'starter-card-footer';
283
+
284
+ var titleEl = document.createElement('div');
285
+ titleEl.className = 'starter-card-title';
286
+ titleEl.textContent = displayName(p);
287
+
288
+ var descEl = document.createElement('div');
289
+ descEl.className = 'starter-card-desc';
290
+ descEl.textContent = description(p);
291
+
292
+ footer.appendChild(titleEl);
293
+ footer.appendChild(descEl);
294
+ card.appendChild(img);
295
+ card.appendChild(footer);
296
+
297
+ async function pick() {
298
+ await recordMru(p.name);
299
+ navigateToStarter(p.name);
300
+ }
301
+ card.addEventListener('click', pick);
302
+ card.addEventListener('keydown', function(e) {
303
+ if (e.key === 'Enter' || e.key === ' ') {
304
+ e.preventDefault();
305
+ pick();
306
+ }
307
+ });
308
+
309
+ carouselRow.appendChild(card);
310
+ });
311
+ }
312
+
313
+ function refreshCardImages() {
314
+ carouselRow.querySelectorAll('.starter-card').forEach(function(card) {
315
+ var name = card.dataset.starter;
316
+ if (!name) return;
317
+ var imgEl = card.querySelector('.starter-card-img');
318
+ if (imgEl) imgEl.style.backgroundImage = "url('" + imageUrlFor(name) + "')";
319
+ });
320
+ }
321
+
322
+ // Re-resolve card image variants when the theme class on <html> flips.
323
+ var observer = new MutationObserver(refreshCardImages);
324
+ observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
325
+
326
+ searchInput.addEventListener('input', function(e) {
327
+ searchTerm = e.target.value;
328
+ renderCarousel();
329
+ });
330
+
331
+ async function loadStartersFromApi() {
332
+ try {
333
+ var res = await fetch('/api/pages');
334
+ if (!res.ok) throw new Error('pages fetch failed');
335
+ var allPages = await res.json();
336
+ starters = allPages.filter(function(p) {
337
+ return Array.isArray(p.categories) && p.categories.indexOf('_Starters') !== -1;
338
+ });
339
+ } catch (e) {
340
+ console.error('Failed to load starters:', e);
341
+ starters = [];
342
+ }
343
+ }
344
+
345
+ (async function() {
346
+ await Promise.all([loadStartersFromApi(), loadMru()]);
347
+ renderCarousel();
348
+ })();
349
+ })();
350
+ </script>
351
+ <script id="page-helpers" src="/api/page-helpers.js?v=3" data-locked="true"></script>
352
+ <script id="page-script" src="/api/page-script.js?v=3" data-locked="true"></script>
353
+ </body></html>
@@ -1,10 +1,12 @@
1
- {
2
- "title": "Page Builder",
3
- "categories": [
4
- "System"
5
- ],
6
- "pinned": true,
7
- "showInAll": true,
8
- "pageVersion": 3,
9
- "mode": "unlocked"
10
- }
1
+ {
2
+ "title": "Page Builder",
3
+ "categories": [
4
+ "System"
5
+ ],
6
+ "pinned": true,
7
+ "showInAll": false,
8
+ "pageVersion": 3,
9
+ "mode": "unlocked",
10
+ "greeting": "Pick a starter above to scaffold a page, or just describe what you want and I'll build it from a blank page.",
11
+ "firstRunGreeting": "<p><strong>Welcome to SynthOS!</strong></p><p>You're all set up and ready to start creating. This is the <strong>Builder</strong> — your main workspace. There are two ways to begin:</p><ul><li><strong>Pick a starter</strong> above — each card is a ready-made scaffold (calculator, dashboard, gallery, quiz, kanban, and more) that you can customize through chat.</li><li><strong>Describe what you want</strong> in the chat below — I'll build it from a blank page. Dashboards, tools, games, visualizations, forms, calculators — if it can be expressed as a web page, you can build it through conversation.</li></ul><p><strong>How pages work:</strong></p><ul><li>Each creation lives on its own <strong>page</strong>. When you save, it gets a name and becomes part of your collection.</li><li>The <strong>Pages</strong> button (in the link bar above) takes you to the <strong>Pages Gallery</strong> where you can browse, open, and manage all your saved creations.</li></ul><p><strong>Key actions:</strong></p><ul><li><strong>Save</strong> — saves your current page. You'll be prompted for a name the first time. <em>Save often!</em> Your work only persists when you save it.</li><li><strong>Reset</strong> — clears the current page back to a blank slate. Useful when you want to start fresh on something new.</li></ul><p>When you're ready, we recommend trying the <a href=\"/solar_tutorial\">Solar Tutorial</a> — it's a guided walkthrough that will show you the basics of creating with SynthOS step by step.</p><p>Have fun building!</p>"
12
+ }