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.
- package/README.md +1 -1
- package/default-pages/application/page.html +42 -0
- package/default-pages/application/page.json +10 -0
- package/default-pages/elevenlabs_effects_studio/page.html +1363 -0
- package/default-pages/elevenlabs_effects_studio/page.json +11 -0
- package/default-pages/elevenlabs_voice_studio/page.html +801 -0
- package/default-pages/elevenlabs_voice_studio/page.json +11 -0
- package/default-pages/{json_tools.html → json_tools/page.html} +13 -11
- package/default-pages/json_tools/page.json +10 -0
- package/default-pages/my_notes/notes/a1b2c3d4-e5f6-7890-abcd-ef1234567890.json +5 -0
- package/default-pages/my_notes/page.html +132 -0
- package/default-pages/{my_notes.json → my_notes/page.json} +2 -2
- package/default-pages/neon_asteroids/files/Ambient_Space.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Ambient_Space2.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Ambient_Space3.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Asteroid_Explosion.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Hyperspace_Jump.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Laser_Fire.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Menu_Navigate.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Power_Up_Collect.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Saucer_Alert.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Ship_Thrust.mp3 +0 -0
- package/default-pages/neon_asteroids/files/effects.json +74 -0
- package/default-pages/neon_asteroids/page.html +1803 -0
- package/default-pages/{neon_asteroids.json → neon_asteroids/page.json} +3 -3
- package/default-pages/{oregon_trail.html → oregon_trail/page.html} +16 -30
- package/default-pages/{oregon_trail.json → oregon_trail/page.json} +2 -2
- package/default-pages/retro_game_starter/page.html +1308 -0
- package/default-pages/retro_game_starter/page.json +12 -0
- package/default-pages/{sidebar_page.html → sidebar_page/page.html} +12 -10
- package/default-pages/sidebar_page/page.json +10 -0
- package/default-pages/{solar_explorer.html → solar_explorer/page.html} +15 -12
- package/default-pages/{solar_explorer.json → solar_explorer/page.json} +2 -2
- package/default-pages/{solar_tutorial.html → solar_tutorial/page.html} +12 -10
- package/default-pages/solar_tutorial/page.json +10 -0
- package/default-pages/{two-panel_page.html → two-panel_page/page.html} +13 -11
- package/default-pages/two-panel_page/page.json +10 -0
- package/default-pages/{us_map.html → us_map/page.html} +193 -192
- package/default-pages/{us_map.json → us_map/page.json} +12 -12
- package/default-pages/{us_map_1850.html → us_map_1850/page.html} +326 -325
- package/default-pages/{us_map_1850.json → us_map_1850/page.json} +12 -12
- package/default-pages/{western_cities_1850.html → western_cities_1850/page.html} +527 -526
- package/default-pages/{western_cities_1850.json → western_cities_1850/page.json} +12 -12
- package/default-themes/aurora-dawn.json +19 -0
- package/default-themes/aurora-dawn.v3.css +198 -0
- package/default-themes/aurora-dusk.json +19 -0
- package/default-themes/aurora-dusk.v3.css +200 -0
- package/default-themes/cosmos-dawn.json +19 -0
- package/default-themes/cosmos-dawn.v3.css +198 -0
- package/default-themes/cosmos-dusk.json +19 -0
- package/default-themes/cosmos-dusk.v3.css +200 -0
- package/default-themes/high-contrast-dark.json +19 -0
- package/default-themes/high-contrast-dark.v3.css +200 -0
- package/default-themes/high-contrast-light.json +19 -0
- package/default-themes/high-contrast-light.v3.css +198 -0
- package/default-themes/nebula-dawn.v2.css +110 -0
- package/default-themes/nebula-dawn.v3.css +199 -0
- package/default-themes/nebula-dusk.v2.css +104 -0
- package/default-themes/nebula-dusk.v3.css +201 -0
- package/default-themes/solar-flare-dawn.json +19 -0
- package/default-themes/solar-flare-dawn.v3.css +198 -0
- package/default-themes/solar-flare-dusk.json +19 -0
- package/default-themes/solar-flare-dusk.v3.css +200 -0
- package/dist/agents/index.d.ts +1 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +2 -1
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/openclaw/gatewayManager.d.ts +4 -0
- package/dist/agents/openclaw/gatewayManager.d.ts.map +1 -1
- package/dist/agents/openclaw/gatewayManager.js +27 -11
- package/dist/agents/openclaw/gatewayManager.js.map +1 -1
- package/dist/agents/openclaw/openclawProvider.d.ts.map +1 -1
- package/dist/agents/openclaw/openclawProvider.js +2 -4
- package/dist/agents/openclaw/openclawProvider.js.map +1 -1
- package/dist/agents/openclaw/sshTunnelManager.d.ts +2 -0
- package/dist/agents/openclaw/sshTunnelManager.d.ts.map +1 -1
- package/dist/agents/openclaw/sshTunnelManager.js +31 -12
- package/dist/agents/openclaw/sshTunnelManager.js.map +1 -1
- package/dist/builders/anthropic.d.ts +31 -0
- package/dist/builders/anthropic.d.ts.map +1 -0
- package/dist/builders/anthropic.js +227 -0
- package/dist/builders/anthropic.js.map +1 -0
- package/dist/builders/fireworksai.d.ts +9 -0
- package/dist/builders/fireworksai.d.ts.map +1 -0
- package/dist/builders/fireworksai.js +57 -0
- package/dist/builders/fireworksai.js.map +1 -0
- package/dist/builders/index.d.ts +13 -0
- package/dist/builders/index.d.ts.map +1 -0
- package/dist/builders/index.js +31 -0
- package/dist/builders/index.js.map +1 -0
- package/dist/builders/openai.d.ts +8 -0
- package/dist/builders/openai.d.ts.map +1 -0
- package/dist/builders/openai.js +87 -0
- package/dist/builders/openai.js.map +1 -0
- package/dist/builders/types.d.ts +54 -0
- package/dist/builders/types.d.ts.map +1 -0
- package/dist/builders/types.js +211 -0
- package/dist/builders/types.js.map +1 -0
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.d.ts.map +1 -1
- package/dist/connectors/index.js +3 -2
- package/dist/connectors/index.js.map +1 -1
- package/dist/connectors/registry.d.ts +2 -1
- package/dist/connectors/registry.d.ts.map +1 -1
- package/dist/connectors/registry.js +31 -8
- package/dist/connectors/registry.js.map +1 -1
- package/dist/customizer/Customizer.d.ts +62 -0
- package/dist/customizer/Customizer.d.ts.map +1 -0
- package/dist/customizer/Customizer.js +134 -0
- package/dist/customizer/Customizer.js.map +1 -0
- package/dist/customizer/index.d.ts +4 -0
- package/dist/customizer/index.d.ts.map +1 -0
- package/dist/customizer/index.js +9 -0
- package/dist/customizer/index.js.map +1 -0
- package/dist/files.d.ts +16 -0
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +60 -1
- package/dist/files.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +12 -6
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +150 -133
- package/dist/init.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +23 -10
- package/dist/migrations.js.map +1 -1
- package/dist/models/anthropic.d.ts +4 -2
- package/dist/models/anthropic.d.ts.map +1 -1
- package/dist/models/anthropic.js +33 -6
- package/dist/models/anthropic.js.map +1 -1
- package/dist/models/fireworksai.d.ts.map +1 -1
- package/dist/models/fireworksai.js +9 -1
- package/dist/models/fireworksai.js.map +1 -1
- package/dist/models/index.d.ts +1 -1
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/index.js +2 -1
- package/dist/models/index.js.map +1 -1
- package/dist/models/openai.d.ts +1 -1
- package/dist/models/openai.d.ts.map +1 -1
- package/dist/models/openai.js +24 -3
- package/dist/models/openai.js.map +1 -1
- package/dist/models/types.d.ts +20 -1
- package/dist/models/types.d.ts.map +1 -1
- package/dist/models/types.js +6 -1
- package/dist/models/types.js.map +1 -1
- package/dist/pages.d.ts +34 -10
- package/dist/pages.d.ts.map +1 -1
- package/dist/pages.js +229 -79
- package/dist/pages.js.map +1 -1
- package/dist/service/createCompletePrompt.d.ts +2 -1
- package/dist/service/createCompletePrompt.d.ts.map +1 -1
- package/dist/service/createCompletePrompt.js +2 -2
- package/dist/service/createCompletePrompt.js.map +1 -1
- package/dist/service/requiresSettings.d.ts +2 -1
- package/dist/service/requiresSettings.d.ts.map +1 -1
- package/dist/service/requiresSettings.js +3 -3
- package/dist/service/requiresSettings.js.map +1 -1
- package/dist/service/server.d.ts +2 -1
- package/dist/service/server.d.ts.map +1 -1
- package/dist/service/server.js +37 -8
- package/dist/service/server.js.map +1 -1
- package/dist/service/transformPage.d.ts +47 -20
- package/dist/service/transformPage.d.ts.map +1 -1
- package/dist/service/transformPage.js +514 -293
- package/dist/service/transformPage.js.map +1 -1
- package/dist/service/useAgentRoutes.d.ts +2 -1
- package/dist/service/useAgentRoutes.d.ts.map +1 -1
- package/dist/service/useAgentRoutes.js +17 -14
- package/dist/service/useAgentRoutes.js.map +1 -1
- package/dist/service/useApiRoutes.d.ts +2 -1
- package/dist/service/useApiRoutes.d.ts.map +1 -1
- package/dist/service/useApiRoutes.js +287 -172
- package/dist/service/useApiRoutes.js.map +1 -1
- package/dist/service/useConnectorRoutes.js +17 -17
- package/dist/service/useConnectorRoutes.js.map +1 -1
- package/dist/service/useDataRoutes.d.ts.map +1 -1
- package/dist/service/useDataRoutes.js +13 -10
- package/dist/service/useDataRoutes.js.map +1 -1
- package/dist/service/useFileRoutes.d.ts +4 -0
- package/dist/service/useFileRoutes.d.ts.map +1 -0
- package/dist/service/useFileRoutes.js +122 -0
- package/dist/service/useFileRoutes.js.map +1 -0
- package/dist/service/usePageRoutes.d.ts +2 -1
- package/dist/service/usePageRoutes.d.ts.map +1 -1
- package/dist/service/usePageRoutes.js +671 -74
- package/dist/service/usePageRoutes.js.map +1 -1
- package/dist/service/useSharedDataRoutes.d.ts +4 -0
- package/dist/service/useSharedDataRoutes.d.ts.map +1 -0
- package/dist/service/useSharedDataRoutes.js +107 -0
- package/dist/service/useSharedDataRoutes.js.map +1 -0
- package/dist/service/useSharedFileRoutes.d.ts +4 -0
- package/dist/service/useSharedFileRoutes.d.ts.map +1 -0
- package/dist/service/useSharedFileRoutes.js +121 -0
- package/dist/service/useSharedFileRoutes.js.map +1 -0
- package/dist/settings.d.ts +5 -3
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +12 -10
- package/dist/settings.js.map +1 -1
- package/dist/storage/FsStorageProvider.d.ts +25 -0
- package/dist/storage/FsStorageProvider.d.ts.map +1 -0
- package/dist/storage/FsStorageProvider.js +103 -0
- package/dist/storage/FsStorageProvider.js.map +1 -0
- package/dist/storage/StorageProvider.d.ts +31 -0
- package/dist/storage/StorageProvider.d.ts.map +1 -0
- package/dist/storage/StorageProvider.js +3 -0
- package/dist/storage/StorageProvider.js.map +1 -0
- package/dist/storage/index.d.ts +3 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +6 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/synthos-cli.d.ts.map +1 -1
- package/dist/synthos-cli.js +4 -3
- package/dist/synthos-cli.js.map +1 -1
- package/dist/themes.d.ts +1 -0
- package/dist/themes.d.ts.map +1 -1
- package/dist/themes.js +65 -28
- package/dist/themes.js.map +1 -1
- package/migration-rules/v1-to-v2.md +193 -0
- package/migration-rules/v2-to-v3.md +481 -0
- package/package.json +11 -10
- package/required-pages/builder/page.html +43 -0
- package/required-pages/builder/page.json +10 -0
- package/required-pages/{pages.html → pages/page.html} +238 -233
- package/required-pages/pages/page.json +10 -0
- package/required-pages/{settings.html → settings/page.html} +389 -275
- package/required-pages/settings/page.json +10 -0
- package/required-pages/synthos_apis/page.html +846 -0
- package/required-pages/synthos_apis/page.json +10 -0
- package/required-pages/{synthos_scripts.html → synthos_scripts/page.html} +13 -11
- package/required-pages/synthos_scripts/page.json +10 -0
- package/src/agents/index.ts +1 -1
- package/src/agents/openclaw/gatewayManager.ts +22 -11
- package/src/agents/openclaw/openclawProvider.ts +2 -4
- package/src/agents/openclaw/sshTunnelManager.ts +19 -11
- package/src/builders/anthropic.ts +283 -0
- package/src/builders/fireworksai.ts +59 -0
- package/src/builders/index.ts +33 -0
- package/src/builders/openai.ts +89 -0
- package/src/builders/types.ts +261 -0
- package/src/connectors/index.ts +1 -1
- package/src/connectors/registry.ts +28 -8
- package/src/customizer/Customizer.ts +163 -0
- package/src/customizer/index.ts +5 -0
- package/src/files.ts +57 -0
- package/src/index.ts +3 -1
- package/src/init.ts +195 -145
- package/src/migrations.ts +30 -10
- package/src/models/anthropic.ts +40 -10
- package/src/models/fireworksai.ts +9 -2
- package/src/models/index.ts +1 -1
- package/src/models/openai.ts +26 -6
- package/src/models/types.ts +31 -1
- package/src/pages.ts +230 -77
- package/src/service/createCompletePrompt.ts +3 -2
- package/src/service/requiresSettings.ts +4 -3
- package/src/service/server.ts +36 -9
- package/src/service/transformPage.ts +557 -326
- package/src/service/useAgentRoutes.ts +19 -14
- package/src/service/useApiRoutes.ts +208 -84
- package/src/service/useConnectorRoutes.ts +18 -18
- package/src/service/useDataRoutes.ts +13 -10
- package/src/service/useFileRoutes.ts +128 -0
- package/src/service/usePageRoutes.ts +730 -81
- package/src/service/useSharedDataRoutes.ts +109 -0
- package/src/service/useSharedFileRoutes.ts +127 -0
- package/src/settings.ts +14 -10
- package/src/storage/FsStorageProvider.ts +87 -0
- package/src/storage/StorageProvider.ts +34 -0
- package/src/storage/index.ts +2 -0
- package/src/synthos-cli.ts +4 -3
- package/src/themes.ts +64 -27
- package/static-files/favicon.svg +12 -0
- package/static-files/fluentlm-instructions.llmd +868 -0
- package/static-files/fluentlm-instructions.md +1595 -0
- package/static-files/fluentlm.css +4844 -0
- package/static-files/fluentlm.js +3602 -0
- package/static-files/fluentlm.min.css +1 -0
- package/static-files/fluentlm.min.js +1 -0
- package/{page-scripts/helpers-v2.js → static-files/helpers.v3.js} +82 -0
- package/static-files/page.v3.js +1290 -0
- package/static-files/recommended-frameworks.llmd +81 -0
- package/static-files/recommended-frameworks.md +137 -0
- package/static-files/retro-game.js +877 -0
- package/static-files/shell.css +797 -0
- package/static-files/theme-dark.css +169 -0
- package/static-files/theme-light.css +169 -0
- package/tests/builders.spec.ts +139 -0
- package/tests/pages.spec.ts +54 -84
- package/tests/transformPage.spec.ts +299 -360
- package/default-pages/application.html +0 -40
- package/default-pages/application.json +0 -1
- package/default-pages/json_tools.json +0 -1
- package/default-pages/my_notes.html +0 -33
- package/default-pages/neon_asteroids.html +0 -77
- package/default-pages/sidebar_page.json +0 -1
- package/default-pages/solar_tutorial.json +0 -1
- package/default-pages/two-panel_page.json +0 -1
- package/dist/service/useGatewayRoutes.d.ts +0 -4
- package/dist/service/useGatewayRoutes.d.ts.map +0 -1
- package/dist/service/useGatewayRoutes.js +0 -168
- package/dist/service/useGatewayRoutes.js.map +0 -1
- package/page-scripts/page-v2.js +0 -656
- package/required-pages/builder.html +0 -48
- package/required-pages/builder.json +0 -1
- package/required-pages/pages.json +0 -1
- package/required-pages/settings.json +0 -1
- package/required-pages/synthos_apis.html +0 -327
- package/required-pages/synthos_apis.json +0 -1
- package/required-pages/synthos_scripts.json +0 -1
- package/src/connectors/airtable/connector.json +0 -27
- package/src/connectors/alpha-vantage/connector.json +0 -26
- package/src/connectors/brave-search/connector.json +0 -26
- package/src/connectors/cloudinary/connector.json +0 -27
- package/src/connectors/deepl/connector.json +0 -28
- package/src/connectors/elevenlabs/connector.json +0 -30
- package/src/connectors/giphy/connector.json +0 -27
- package/src/connectors/github/connector.json +0 -29
- package/src/connectors/huggingface/connector.json +0 -27
- package/src/connectors/imgur/connector.json +0 -29
- package/src/connectors/instagram/connector.json +0 -43
- package/src/connectors/jira/connector.json +0 -28
- package/src/connectors/mapbox/connector.json +0 -26
- package/src/connectors/nasa/connector.json +0 -27
- package/src/connectors/newsapi/connector.json +0 -27
- package/src/connectors/notion/connector.json +0 -28
- package/src/connectors/open-exchange-rates/connector.json +0 -27
- package/src/connectors/openweathermap/connector.json +0 -26
- package/src/connectors/pexels/connector.json +0 -27
- package/src/connectors/resend/connector.json +0 -29
- package/src/connectors/rss2json/connector.json +0 -27
- package/src/connectors/sendgrid/connector.json +0 -27
- package/src/connectors/spoonacular/connector.json +0 -28
- package/src/connectors/stability-ai/connector.json +0 -27
- package/src/connectors/twilio/connector.json +0 -28
- package/src/connectors/unsplash/connector.json +0 -27
- package/src/connectors/wolfram-alpha/connector.json +0 -26
- package/src/connectors/youtube-data/connector.json +0 -30
- /package/{dist/connectors → service-connectors}/airtable/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/alpha-vantage/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/brave-search/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/cloudinary/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/deepl/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/elevenlabs/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/giphy/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/github/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/huggingface/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/imgur/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/instagram/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/jira/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/mapbox/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/nasa/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/newsapi/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/notion/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/open-exchange-rates/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/openweathermap/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/pexels/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/resend/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/rss2json/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/sendgrid/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/spoonacular/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/stability-ai/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/twilio/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/unsplash/connector.json +0 -0
- /package/{dist/connectors → service-connectors}/wolfram-alpha/connector.json +0 -0
- /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
|
|
5
|
-
"version": "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/
|
|
12
|
+
"url": "https://github.com/Stevenic-microsoft/synthtabs/issues"
|
|
13
13
|
},
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
16
|
-
"url": "https://github.com/Stevenic/
|
|
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
|
|
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
|
-
"
|
|
61
|
+
"static-files",
|
|
63
62
|
"required-pages",
|
|
64
|
-
"
|
|
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">×</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>
|