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
@@ -9,12 +9,31 @@ import {
9
9
  loadPageMetadata,
10
10
  savePageState,
11
11
  loadPageState,
12
- updatePageState,
13
12
  listPages,
14
13
  deletePage,
15
14
  copyPage,
16
15
  PAGE_VERSION,
17
16
  } from '../src/pages';
17
+ import { SynthOSConfig } from '../src/init';
18
+ import { FsStorageProvider } from '../src/storage';
19
+
20
+ /** Create a minimal SynthOSConfig for testing. */
21
+ function makeConfig(pagesFolder: string): SynthOSConfig {
22
+ return {
23
+ localFolder: '.synthos',
24
+ pagesFolder,
25
+ requiredPagesFolders: [],
26
+ defaultPagesFolders: [],
27
+ defaultScriptsFolders: [],
28
+ defaultThemesFolders: [],
29
+ staticFilesFolders: [],
30
+ serviceConnectorsFolders: [],
31
+ requiredPages: [],
32
+ storageProvider: new FsStorageProvider(),
33
+ debug: false,
34
+ debugPageUpdates: false,
35
+ };
36
+ }
18
37
 
19
38
  // ---------------------------------------------------------------------------
20
39
  // normalizePageName
@@ -123,15 +142,16 @@ describe('parseMetadata', () => {
123
142
 
124
143
  describe('page I/O', () => {
125
144
  let tmpDir: string;
126
- let pagesFolder: string;
145
+ let config: SynthOSConfig;
127
146
  let fallbackFolder: string;
128
147
 
129
148
  beforeEach(async () => {
130
149
  tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'synthos-test-'));
131
- pagesFolder = path.join(tmpDir, 'synthos');
150
+ const pagesFolder = path.join(tmpDir, 'synthos');
132
151
  fallbackFolder = path.join(tmpDir, 'fallback');
133
152
  await fs.mkdir(pagesFolder, { recursive: true });
134
153
  await fs.mkdir(fallbackFolder, { recursive: true });
154
+ config = makeConfig(pagesFolder);
135
155
  });
136
156
 
137
157
  afterEach(async () => {
@@ -152,8 +172,8 @@ describe('page I/O', () => {
152
172
  pageVersion: 2,
153
173
  mode: 'locked' as const,
154
174
  };
155
- await savePageMetadata(pagesFolder, 'mypage', meta);
156
- const loaded = await loadPageMetadata(pagesFolder, 'mypage');
175
+ await savePageMetadata(config, 'mypage', meta);
176
+ const loaded = await loadPageMetadata(config, 'mypage');
157
177
  assert.ok(loaded);
158
178
  assert.strictEqual(loaded.title, 'Test Page');
159
179
  assert.deepStrictEqual(loaded.categories, ['Tools', 'Dev']);
@@ -163,17 +183,19 @@ describe('page I/O', () => {
163
183
  });
164
184
 
165
185
  it('returns undefined when no metadata file exists', async () => {
166
- const loaded = await loadPageMetadata(pagesFolder, 'nonexistent');
186
+ const loaded = await loadPageMetadata(config, 'nonexistent');
167
187
  assert.strictEqual(loaded, undefined);
168
188
  });
169
189
 
170
190
  it('falls back to fallbackFolder', async () => {
171
- // Write a fallback JSON file
191
+ // Write a fallback JSON file in folder-based structure
192
+ const fallbackPageDir = path.join(fallbackFolder, 'system-page');
193
+ await fs.mkdir(fallbackPageDir, { recursive: true });
172
194
  await fs.writeFile(
173
- path.join(fallbackFolder, 'system-page.json'),
195
+ path.join(fallbackPageDir, 'page.json'),
174
196
  JSON.stringify({ title: 'System', categories: ['System'], pinned: true, pageVersion: 2, mode: 'locked' }),
175
197
  );
176
- const loaded = await loadPageMetadata(pagesFolder, 'system-page', fallbackFolder);
198
+ const loaded = await loadPageMetadata(config, 'system-page', [fallbackFolder]);
177
199
  assert.ok(loaded);
178
200
  assert.strictEqual(loaded.title, 'System');
179
201
  });
@@ -184,89 +206,46 @@ describe('page I/O', () => {
184
206
  describe('savePageState / loadPageState', () => {
185
207
  it('roundtrips page HTML and creates metadata', async () => {
186
208
  const html = '<html><body>Hello</body></html>';
187
- await savePageState(pagesFolder, 'testpage', html, 'Test Title', ['Cat']);
188
- const loaded = await loadPageState(pagesFolder, 'testpage', true);
209
+ await savePageState(config, 'testpage', html, 'Test Title', ['Cat']);
210
+ const loaded = await loadPageState(config, 'testpage');
189
211
  assert.strictEqual(loaded, html);
190
212
 
191
213
  // Metadata should have been created
192
- const meta = await loadPageMetadata(pagesFolder, 'testpage');
214
+ const meta = await loadPageMetadata(config, 'testpage');
193
215
  assert.ok(meta);
194
216
  assert.strictEqual(meta.pageVersion, PAGE_VERSION);
195
217
  });
196
218
 
197
219
  it('returns undefined for non-existent page', async () => {
198
- const loaded = await loadPageState(pagesFolder, 'nope', false);
220
+ const loaded = await loadPageState(config, 'nope');
199
221
  assert.strictEqual(loaded, undefined);
200
222
  });
201
-
202
- it('with reset=true re-reads from disk', async () => {
203
- const html1 = '<html>v1</html>';
204
- const html2 = '<html>v2</html>';
205
- await savePageState(pagesFolder, 'resetpage', html1);
206
- // First load
207
- const first = await loadPageState(pagesFolder, 'resetpage', false);
208
- assert.strictEqual(first, html1);
209
-
210
- // Overwrite the file on disk directly
211
- const pageHtmlPath = path.join(pagesFolder, 'pages', 'resetpage', 'page.html');
212
- await fs.writeFile(pageHtmlPath, html2);
213
-
214
- // Without reset, should return cached version
215
- const cached = await loadPageState(pagesFolder, 'resetpage', false);
216
- assert.strictEqual(cached, html1);
217
-
218
- // With reset, should re-read
219
- const refreshed = await loadPageState(pagesFolder, 'resetpage', true);
220
- assert.strictEqual(refreshed, html2);
221
- });
222
- });
223
-
224
- // -- updatePageState -----------------------------------------------------
225
-
226
- describe('updatePageState', () => {
227
- it('updates in-memory cache', async () => {
228
- await savePageState(pagesFolder, 'cachepage', '<html>original</html>');
229
- await loadPageState(pagesFolder, 'cachepage', false);
230
-
231
- updatePageState('cachepage', '<html>updated</html>');
232
-
233
- // Loading without reset should return updated cache
234
- const loaded = await loadPageState(pagesFolder, 'cachepage', false);
235
- assert.strictEqual(loaded, '<html>updated</html>');
236
- });
237
223
  });
238
224
 
239
225
  // -- listPages -----------------------------------------------------------
240
226
 
241
227
  describe('listPages', () => {
242
228
  it('lists folder-based pages', async () => {
243
- await savePageState(pagesFolder, 'alpha', '<html>A</html>');
244
- await savePageState(pagesFolder, 'beta', '<html>B</html>');
245
- const pages = await listPages(pagesFolder, fallbackFolder);
229
+ await savePageState(config, 'alpha', '<html>A</html>');
230
+ await savePageState(config, 'beta', '<html>B</html>');
231
+ const pages = await listPages(config, [fallbackFolder]);
246
232
  const names = pages.map(p => p.name);
247
233
  assert.ok(names.includes('alpha'));
248
234
  assert.ok(names.includes('beta'));
249
235
  });
250
236
 
251
237
  it('lists legacy flat HTML files', async () => {
252
- await fs.writeFile(path.join(pagesFolder, 'legacy.html'), '<html>Legacy</html>');
253
- const pages = await listPages(pagesFolder, fallbackFolder);
238
+ await fs.writeFile(path.join(config.pagesFolder, 'legacy.html'), '<html>Legacy</html>');
239
+ const pages = await listPages(config, [fallbackFolder]);
254
240
  const legacy = pages.find(p => p.name === 'legacy');
255
241
  assert.ok(legacy);
256
242
  assert.strictEqual(legacy.pageVersion, 1);
257
243
  });
258
244
 
259
- it('lists fallback (required) pages', async () => {
260
- await fs.writeFile(path.join(fallbackFolder, 'builder.html'), '<html>Builder</html>');
261
- const pages = await listPages(pagesFolder, fallbackFolder);
262
- const builder = pages.find(p => p.name === 'builder');
263
- assert.ok(builder);
264
- });
265
-
266
245
  it('returns pages sorted alphabetically', async () => {
267
- await savePageState(pagesFolder, 'zebra', '<html></html>');
268
- await savePageState(pagesFolder, 'apple', '<html></html>');
269
- const pages = await listPages(pagesFolder, fallbackFolder);
246
+ await savePageState(config, 'zebra', '<html></html>');
247
+ await savePageState(config, 'apple', '<html></html>');
248
+ const pages = await listPages(config, [fallbackFolder]);
270
249
  const names = pages.map(p => p.name);
271
250
  const sortedNames = [...names].sort();
272
251
  assert.deepStrictEqual(names, sortedNames);
@@ -276,19 +255,18 @@ describe('page I/O', () => {
276
255
  // -- deletePage ----------------------------------------------------------
277
256
 
278
257
  describe('deletePage', () => {
279
- it('removes folder-based page and clears cache', async () => {
280
- await savePageState(pagesFolder, 'doomed', '<html>bye</html>');
281
- await loadPageState(pagesFolder, 'doomed', false);
258
+ it('removes folder-based page', async () => {
259
+ await savePageState(config, 'doomed', '<html>bye</html>');
282
260
 
283
- await deletePage(pagesFolder, 'doomed');
261
+ await deletePage(config, 'doomed');
284
262
 
285
263
  // Folder should be gone
286
- const folderExists = await fs.access(path.join(pagesFolder, 'pages', 'doomed'))
264
+ const folderExists = await fs.access(path.join(config.pagesFolder, 'pages', 'doomed'))
287
265
  .then(() => true).catch(() => false);
288
266
  assert.strictEqual(folderExists, false);
289
267
 
290
- // Cache should be cleared — loading should return undefined
291
- const loaded = await loadPageState(pagesFolder, 'doomed', true);
268
+ // Loading should return undefined
269
+ const loaded = await loadPageState(config, 'doomed');
292
270
  assert.strictEqual(loaded, undefined);
293
271
  });
294
272
  });
@@ -297,13 +275,13 @@ describe('page I/O', () => {
297
275
 
298
276
  describe('copyPage', () => {
299
277
  it('copies HTML and creates metadata with correct title/categories', async () => {
300
- await savePageState(pagesFolder, 'source', '<html>Source</html>');
301
- await copyPage(pagesFolder, 'source', 'target', 'Copied Page', ['Copy'], fallbackFolder);
278
+ await savePageState(config, 'source', '<html>Source</html>');
279
+ await copyPage(config, 'source', 'target', 'Copied Page', ['Copy'], [fallbackFolder]);
302
280
 
303
- const html = await loadPageState(pagesFolder, 'target', true);
281
+ const html = await loadPageState(config, 'target');
304
282
  assert.strictEqual(html, '<html>Source</html>');
305
283
 
306
- const meta = await loadPageMetadata(pagesFolder, 'target');
284
+ const meta = await loadPageMetadata(config, 'target');
307
285
  assert.ok(meta);
308
286
  assert.strictEqual(meta.title, 'Copied Page');
309
287
  assert.deepStrictEqual(meta.categories, ['Copy']);
@@ -312,17 +290,9 @@ describe('page I/O', () => {
312
290
 
313
291
  it('throws when source page does not exist', async () => {
314
292
  await assert.rejects(
315
- () => copyPage(pagesFolder, 'ghost', 'target', 'T', [], fallbackFolder),
293
+ () => copyPage(config, 'ghost', 'target', 'T', [], [fallbackFolder]),
316
294
  /Source page "ghost" not found/,
317
295
  );
318
296
  });
319
-
320
- it('copies from required pages folder as fallback', async () => {
321
- await fs.writeFile(path.join(fallbackFolder, 'system.html'), '<html>System</html>');
322
- await copyPage(pagesFolder, 'system', 'mycopy', 'My Copy', ['User'], fallbackFolder);
323
-
324
- const html = await loadPageState(pagesFolder, 'mycopy', true);
325
- assert.strictEqual(html, '<html>System</html>');
326
- });
327
297
  });
328
298
  });