synthos 0.8.0 → 0.9.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 +1822 -0
- package/default-pages/{neon_asteroids.json → neon_asteroids/page.json} +3 -3
- package/default-pages/{oregon_trail.html → oregon_trail/page.html} +14 -12
- 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} +14 -11
- 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.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 +57 -0
- package/dist/customizer/Customizer.d.ts.map +1 -0
- package/dist/customizer/Customizer.js +124 -0
- package/dist/customizer/Customizer.js.map +1 -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.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +10 -6
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +96 -113
- 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 +30 -7
- package/dist/pages.d.ts.map +1 -1
- package/dist/pages.js +177 -55
- package/dist/pages.js.map +1 -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 +5 -2
- package/dist/service/useAgentRoutes.js.map +1 -1
- package/dist/service/useApiRoutes.d.ts.map +1 -1
- package/dist/service/useApiRoutes.js +237 -136
- package/dist/service/useApiRoutes.js.map +1 -1
- package/dist/service/useConnectorRoutes.js +6 -6
- package/dist/service/useConnectorRoutes.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.map +1 -1
- package/dist/service/usePageRoutes.js +648 -67
- 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 +104 -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 +1 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +1 -0
- package/dist/settings.js.map +1 -1
- 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 +28 -15
- 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 +151 -0
- package/src/customizer/index.ts +5 -0
- package/src/files.ts +57 -0
- package/src/index.ts +2 -1
- package/src/init.ts +137 -123
- 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 +176 -54
- package/src/service/server.ts +36 -9
- package/src/service/transformPage.ts +557 -326
- package/src/service/useAgentRoutes.ts +7 -2
- package/src/service/useApiRoutes.ts +150 -41
- package/src/service/useConnectorRoutes.ts +7 -7
- package/src/service/useFileRoutes.ts +127 -0
- package/src/service/usePageRoutes.ts +720 -73
- package/src/service/useSharedDataRoutes.ts +106 -0
- package/src/service/useSharedFileRoutes.ts +126 -0
- package/src/settings.ts +2 -0
- package/src/synthos-cli.ts +4 -3
- package/src/themes.ts +25 -14
- 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 +8 -8
- 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/agents/a2a/a2aProvider.d.ts +0 -3
- package/dist/agents/discovery.d.ts +0 -30
- package/dist/agents/openclaw/openclawProvider.d.ts +0 -3
- package/dist/agents/types.d.ts +0 -64
- package/dist/connectors/index.d.ts +0 -3
- package/dist/connectors/types.d.ts +0 -84
- package/dist/index.d.ts +0 -7
- package/dist/migrations.d.ts +0 -12
- package/dist/models/chainOfThought.d.ts +0 -12
- package/dist/models/fireworksai.d.ts +0 -30
- package/dist/models/logCompletePrompt.d.ts +0 -3
- package/dist/models/providers.d.ts +0 -8
- package/dist/models/utils.d.ts +0 -6
- package/dist/scripts.d.ts +0 -15
- package/dist/service/createCompletePrompt.d.ts +0 -5
- package/dist/service/debugLog.d.ts +0 -11
- package/dist/service/generateImage.d.ts +0 -32
- package/dist/service/index.d.ts +0 -8
- package/dist/service/modelInstructions.d.ts +0 -7
- package/dist/service/requiresSettings.d.ts +0 -3
- package/dist/service/server.d.ts +0 -4
- package/dist/service/useApiRoutes.d.ts +0 -4
- package/dist/service/useConnectorRoutes.d.ts +0 -4
- package/dist/service/useDataRoutes.d.ts +0 -4
- 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/dist/service/usePageRoutes.d.ts +0 -5
- package/dist/synthos-cli.d.ts +0 -2
- 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
|
@@ -4,55 +4,100 @@
|
|
|
4
4
|
<title>SynthOS - Settings</title>
|
|
5
5
|
<script id="theme-info" src="/api/theme-info.js" data-locked="true"></script>
|
|
6
6
|
<link id="theme-css" rel="stylesheet" href="/api/theme.css" data-locked="true">
|
|
7
|
-
<style>.settings-title{font-size:22px;font-weight:700;min-height:var(--header-min-height);padding:var(--header-padding-vertical) var(--header-padding-horizontal);line-height:var(--header-line-height);display:flex;align-items:center;justify-content:center;box-sizing:border-box;background:linear-gradient(135deg,var(--accent-primary),var(--accent-secondary));color:#fff;border-radius:12px 12px 0 0;width:100%;box-shadow:0 6px 25px var(--accent-glow);letter-spacing:2px;text-shadow:0 2px 10px rgba(0,0,0,.3)}.settings-container{display:flex;flex-direction:column;width:100%;flex-grow:1;background:rgba(15,15,35,.8);border-radius:0 0 12px 12px;border:1px solid rgba(138,43,226,.2);border-top:none;overflow:hidden}.accordion-section{display:flex;flex-direction:column;flex-shrink:0;overflow:hidden;border-bottom:1px solid var(--border-color)}.accordion-section:last-child{border-bottom:none}.accordion-section.active{flex-shrink:1;flex-grow:1;min-height:0}.accordion-header{display:flex;justify-content:space-between;align-items:center;width:100%;padding:16px 25px;background:none;border:none;color:var(--text-primary);font-size:15px;font-weight:600;cursor:pointer;transition:background .3s;letter-spacing:.5px;flex-shrink:0}.accordion-header:hover{background:rgba(138,43,226,.05)}.accordion-section.active .accordion-header{background:rgba(138,43,226,.08)}.accordion-chevron{font-size:11px;color:var(--text-secondary);transition:transform .3s}.accordion-section.active .accordion-chevron{transform:rotate(180deg)}.accordion-body{display:none;flex-direction:column;flex-grow:1;min-height:0;overflow:hidden}.accordion-section.active .accordion-body{display:flex}.accordion-content{display:flex;flex-direction:column;gap:15px;overflow-y:auto;padding:20px 25px;flex-grow:1}.button-row{display:flex;justify-content:flex-end;padding:15px 25px;border-top:1px solid var(--border-color);flex-shrink:0}.apply-btn{padding:12px 30px;border:none;border-radius:12px;font-size:15px;background:linear-gradient(135deg,var(--accent-primary) 0,var(--accent-secondary) 50%,var(--accent-tertiary) 100%);color:#fff;cursor:pointer;transition:.3s;font-weight:600;letter-spacing:1px;box-shadow:0 4px 20px rgba(102,126,234,.4)}.apply-btn:hover{transform:translateY(-2px);box-shadow:0 6px 25px rgba(102,126,234,.6)}.apply-btn:active{transform:translateY(0)}.form-group{display:flex;flex-direction:column;width:100%}.form-group label{display:block;margin-bottom:8px;color:var(--text-secondary);font-weight:600;font-size:14px}.form-group input,.form-group select,.form-group textarea{width:100%;padding:14px 18px;border-radius:12px;border:1px solid var(--border-color);background:rgba(15,15,35,.8);color:var(--text-primary);font-size:14px;transition:.3s;box-shadow:inset 0 2px 10px rgba(0,0,0,.3)}.form-group input:focus,.form-group select:focus,.form-group textarea:focus{outline:0;border-color:rgba(183,148,246,.6);box-shadow:inset 0 2px 10px rgba(0,0,0,.3),0 0 20px var(--accent-glow)}.form-group input::placeholder,.form-group textarea::placeholder{color:rgba(183,148,246,.5)}.form-group textarea{resize:vertical;min-height:100px}.form-group select{cursor:pointer;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23b794f6' d='M6 8L1 3h10z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 15px center}.form-group select option{background:var(--bg-tertiary);color:var(--text-primary);padding:10px}.info-text{color:rgba(183,148,246,.7);font-size:13px;line-height:1.6;text-align:center;padding:15px;background:rgba(15,15,35,.4);border-radius:10px;border:1px solid var(--border-color)}.info-text a{color:var(--accent-tertiary);text-decoration:none;transition:.3s;font-weight:500}.info-text a:hover{color:var(--text-secondary);text-shadow:0 0 10px var(--accent-glow)}.config-required-banner{padding:12px 20px;background:rgba(255,180,50,.12);border:1px solid rgba(255,180,50,.3);border-radius:10px;color:rgba(255,200,100,.9);font-size:13px;font-weight:500;text-align:center;line-height:1.5}.model-card{border:1px solid var(--border-color);border-radius:12px;padding:18px;display:flex;flex-direction:column;gap:12px;background:rgba(15,15,35,.3)}.model-card-title{font-size:14px;font-weight:700;color:var(--text-primary);letter-spacing:.5px;margin:0}.filter-bar{display:flex;align-items:center;gap:8px;flex-wrap:nowrap}.filter-btn{padding:6px 14px;border-radius:20px;border:1px solid var(--border-color);background:0 0;color:var(--text-secondary);font-size:13px;cursor:pointer;transition:.2s;white-space:nowrap;flex-shrink:0}.filter-btn:hover{border-color:var(--accent-primary);color:var(--accent-primary)}.filter-btn.active{background:linear-gradient(135deg,var(--accent-primary),var(--accent-secondary));color:#fff;border-color:transparent}.services-grid{display:grid;grid-template-columns:1fr;gap:12px}.service-card{border-radius:12px;border:1px solid var(--border-color);background:rgba(15,15,35,.5);padding:18px;transition:.3s}.service-card:hover{border-color:rgba(138,43,226,.3)}.service-card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.service-card-name{font-size:15px;font-weight:600;color:var(--text-primary)}.service-card-category{font-size:11px;color:var(--text-secondary);background:rgba(138,43,226,.15);padding:2px 8px;border-radius:10px}.service-card-desc{font-size:13px;color:var(--text-secondary);line-height:1.5;margin-bottom:12px}.service-card-fields{display:flex;flex-direction:column;gap:8px}.service-card-fields input{width:100%;padding:10px 14px;border-radius:8px;border:1px solid var(--border-color);background:rgba(15,15,35,.8);color:var(--text-primary);font-size:13px;transition:.3s;box-shadow:inset 0 2px 8px rgba(0,0,0,.2)}.service-card-fields input:focus{outline:0;border-color:rgba(183,148,246,.6);box-shadow:inset 0 2px 8px rgba(0,0,0,.2),0 0 15px var(--accent-glow)}.service-card-fields input::placeholder{color:rgba(183,148,246,.5)}.toggle-switch{position:relative;width:44px;height:24px;flex-shrink:0}.toggle-switch input{opacity:0;width:0;height:0}.toggle-slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background:rgba(100,100,100,.4);border-radius:24px;transition:.3s}.toggle-slider:before{content:"";position:absolute;height:18px;width:18px;left:3px;bottom:3px;background:#fff;border-radius:50%;transition:.3s}.toggle-switch input:checked+.toggle-slider{background:linear-gradient(135deg,var(--accent-primary),var(--accent-secondary))}.toggle-switch input:checked+.toggle-slider:before{transform:translateX(20px)}.light-mode .settings-container{background:rgba(255,255,255,.8)}.light-mode .accordion-header:hover{background:rgba(118,75,162,.05)}.light-mode .accordion-section.active .accordion-header{background:rgba(118,75,162,.06)}.light-mode .form-group input,.light-mode .form-group select,.light-mode .form-group textarea{background:rgba(255,255,255,.8);box-shadow:inset 0 2px 10px rgba(118,75,162,.05)}.light-mode .form-group input:focus,.light-mode .form-group select:focus,.light-mode .form-group textarea:focus{box-shadow:inset 0 2px 10px rgba(118,75,162,.05),0 0 20px var(--accent-glow)}.light-mode .form-group input::placeholder,.light-mode .form-group textarea::placeholder{color:rgba(107,79,138,.5)}.light-mode .info-text{color:rgba(107,79,138,.7);background:rgba(255,255,255,.4)}.light-mode .config-required-banner{background:rgba(200,150,50,.1);border-color:rgba(200,150,50,.3);color:rgba(160,120,30,.9)}.light-mode .model-card{background:rgba(255,255,255,.3)}.light-mode .service-card{background:rgba(255,255,255,.5)}.light-mode .service-card-fields input{background:rgba(255,255,255,.8);box-shadow:inset 0 2px 8px rgba(118,75,162,.05)}.light-mode .service-card-fields input:focus{box-shadow:inset 0 2px 8px rgba(118,75,162,.05),0 0 15px var(--accent-glow)}.light-mode .service-card-fields input::placeholder{color:rgba(107,79,138,.5)}.model-card.disabled{opacity:0.35;pointer-events:none;user-select:none;transition:opacity .3s}.wizard-hidden{display:none !important}.more-settings-link{display:inline-block;color:var(--accent-tertiary);font-size:13px;cursor:pointer;text-decoration:none;padding:4px 0;transition:.3s;user-select:none}.more-settings-link:hover{color:var(--text-secondary);text-shadow:0 0 10px var(--accent-glow)}.light-mode .model-card.disabled{opacity:0.35}.accordion-section.disabled .accordion-header{opacity:0.35;pointer-events:none;cursor:default}.apply-btn:disabled{opacity:0.35;pointer-events:none;cursor:default}.connector-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:12px}.connector-tile{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:20px 12px;border-radius:14px;border:1px solid var(--border-color);background:linear-gradient(160deg,rgba(30,30,60,.6),rgba(20,20,50,.8));cursor:pointer;transition:transform .2s,box-shadow .2s,border-color .2s;gap:8px}.connector-tile:hover{transform:translateY(-3px);box-shadow:0 6px 20px var(--accent-glow);border-color:var(--accent-primary)}.connector-tile.configured{background:linear-gradient(160deg,rgba(60,30,90,.6),rgba(40,20,70,.8));border-color:var(--accent-secondary);box-shadow:0 2px 12px var(--accent-glow)}.connector-tile-name{font-size:14px;font-weight:600;color:var(--text-primary)}.connector-category{font-size:11px;color:var(--text-secondary);background:rgba(138,43,226,.15);padding:2px 8px;border-radius:10px}.search-input{margin-left:auto;width:180px;min-width:120px;flex-shrink:0;padding:6px 14px;border-radius:20px;border:1px solid var(--border-color);background:rgba(15,15,35,.8);color:var(--text-primary);font-size:13px;transition:.3s}.search-input:focus{outline:0;border-color:rgba(183,148,246,.6)}.search-input::placeholder{color:rgba(183,148,246,.5)}.filter-buttons-container{display:flex;gap:8px;flex-shrink:1;min-width:0;overflow:hidden;flex-wrap:nowrap}.conn-modal-content{background:rgba(20,20,50,.95);border:1px solid var(--border-color);border-radius:16px;padding:28px;max-width:520px;width:90%;max-height:85vh;display:flex;flex-direction:column;gap:16px;box-shadow:0 8px 40px rgba(0,0,0,.5);overflow-y:auto}.conn-modal-title{font-size:18px;font-weight:700;color:var(--text-primary)}.conn-modal-desc{font-size:13px;color:var(--text-secondary);line-height:1.5}.conn-modal-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:8px}.conn-modal-btn{padding:12px 24px;border:none;border-radius:12px;font-size:14px;background:linear-gradient(135deg,var(--accent-primary) 0,var(--accent-secondary) 50%,var(--accent-tertiary) 100%);color:#fff;cursor:pointer;transition:.3s;font-weight:600;letter-spacing:.5px;box-shadow:0 4px 20px rgba(102,126,234,.4)}.conn-modal-btn:hover{transform:translateY(-2px);box-shadow:0 6px 25px rgba(102,126,234,.6)}.conn-modal-btn.cancel{background:rgba(100,100,100,.4);box-shadow:none}.conn-modal-btn.cancel:hover{background:rgba(100,100,100,.6);transform:translateY(-1px)}.conn-modal-btn.remove{background:rgba(180,50,50,.6);box-shadow:none}.conn-modal-btn.remove:hover{background:rgba(200,60,60,.8);transform:translateY(-1px)}.light-mode .connector-tile{background:linear-gradient(160deg,rgba(240,235,255,.8),rgba(250,248,255,.9))}.light-mode .connector-tile.configured{background:linear-gradient(160deg,rgba(220,200,255,.8),rgba(235,220,255,.9))}.light-mode .search-input{background:rgba(255,255,255,.8)}.light-mode .search-input::placeholder{color:rgba(107,79,138,.5)}.more-dropdown{position:relative;flex-shrink:0}.more-btn{position:relative}.more-menu{position:absolute;top:100%;left:0;margin-top:4px;min-width:150px;max-height:250px;overflow-y:auto;border-radius:8px;padding:4px 0;box-shadow:0 8px 30px rgba(0,0,0,.4);display:none;border:1px solid var(--border-color);background:rgba(30,30,50,.95);z-index:100}.more-menu.show{display:block}.more-menu-item{padding:8px 16px;font-size:13px;cursor:pointer;color:var(--text-primary);transition:background .15s;white-space:nowrap}.more-menu-item:hover{background:linear-gradient(135deg,rgba(102,126,234,.3) 0,rgba(118,75,162,.3) 100%)}.more-menu-item.active{background:linear-gradient(135deg,rgba(102,126,234,.2) 0,rgba(118,75,162,.2) 100%);color:var(--accent-tertiary)}.conn-tooltip{position:fixed;padding:8px 12px;background:var(--bg-tertiary,#0f0f23);color:var(--text-secondary,#b794f6);border:1px solid var(--border-color,rgba(138,43,226,0.3));border-radius:8px;font-size:12px;line-height:1.5;max-width:260px;pointer-events:none;z-index:10000;box-shadow:0 4px 16px rgba(0,0,0,.4);opacity:0;transition:opacity .15s}.conn-tooltip.visible{opacity:1}.light-mode .more-menu{background:rgba(255,255,255,.97);box-shadow:0 8px 30px rgba(0,0,0,.15)}.light-mode .conn-modal-content{background:rgba(250,248,255,.98)}.agent-toggle-row{display:flex;align-items:center;gap:10px}.agent-list{display:flex;flex-direction:column;gap:0;max-height:400px;overflow-y:auto;border:1px solid var(--border-color);border-radius:12px}.agent-row{display:flex;align-items:center;gap:12px;padding:12px 16px;border-bottom:1px solid var(--border-color);cursor:pointer;transition:background .15s}.agent-row:last-child{border-bottom:none}.agent-row:hover{background:rgba(138,43,226,.06)}.agent-row.selected{background:rgba(138,43,226,.1)}.agent-row-info{flex:1;min-width:0;display:flex;align-items:center;gap:10px}.agent-row-name{font-size:14px;font-weight:600;color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.agent-row-desc{font-size:12px;color:var(--text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}.agent-row-badge{font-size:11px;color:var(--text-secondary);background:rgba(138,43,226,.15);padding:2px 8px;border-radius:10px;white-space:nowrap;flex-shrink:0}.agent-status-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.agent-status-dot.connected{background:#4ade80}.agent-status-dot.disconnected{background:rgba(100,100,100,.5)}.agent-row-actions{display:flex;align-items:center;gap:8px;flex-shrink:0}.agent-chat-panel{border:1px solid var(--border-color);border-radius:12px;margin-top:12px;overflow:hidden;display:none}.agent-chat-panel.open{display:flex;flex-direction:column}.agent-chat-header{display:flex;justify-content:space-between;align-items:center;padding:10px 16px;background:rgba(138,43,226,.08);font-size:13px;font-weight:600;color:var(--text-primary)}.agent-chat-close{background:none;border:none;color:var(--text-secondary);cursor:pointer;font-size:16px;padding:0 4px}.agent-chat-close:hover{color:var(--text-primary)}.agent-chat-messages{max-height:250px;overflow-y:auto;padding:12px 16px;display:flex;flex-direction:column;gap:8px;font-size:13px}.agent-chat-msg{padding:8px 12px;border-radius:10px;max-width:85%;line-height:1.5;word-wrap:break-word;white-space:pre-wrap}.agent-chat-msg.user{background:linear-gradient(135deg,var(--accent-primary),var(--accent-secondary));color:#fff;align-self:flex-end}.agent-chat-msg.agent{background:rgba(15,15,35,.4);color:var(--text-primary);align-self:flex-start;border:1px solid var(--border-color)}.agent-chat-msg.error{background:rgba(180,50,50,.2);color:rgba(255,150,150,.9);align-self:center;font-size:12px}.agent-chat-msg.status{color:var(--text-secondary);align-self:center;font-size:12px;font-style:italic}.agent-chat-input-row{display:flex;gap:8px;padding:12px 16px;border-top:1px solid var(--border-color)}.agent-chat-input{flex:1;padding:10px 14px;border-radius:10px;border:1px solid var(--border-color);background:rgba(15,15,35,.8);color:var(--text-primary);font-size:13px}.agent-chat-input:focus{outline:0;border-color:rgba(183,148,246,.6)}.agent-chat-input::placeholder{color:rgba(183,148,246,.5)}.agent-chat-send{padding:10px 18px;border:none;border-radius:10px;font-size:13px;background:linear-gradient(135deg,var(--accent-primary),var(--accent-secondary));color:#fff;cursor:pointer;font-weight:600;transition:.2s}.agent-chat-send:hover{transform:translateY(-1px)}.agent-chat-send:disabled{opacity:.5;pointer-events:none}.light-mode .agent-list{border-color:rgba(118,75,162,.15)}.light-mode .agent-row:hover{background:rgba(118,75,162,.05)}.light-mode .agent-row.selected{background:rgba(118,75,162,.08)}.light-mode .agent-chat-msg.agent{background:rgba(255,255,255,.6)}.light-mode .agent-chat-input{background:rgba(255,255,255,.8)}</style>
|
|
7
|
+
<style>
|
|
8
|
+
/* Layout-specific rules only — all component styling via FluentLM */
|
|
9
|
+
#settingsBtn { opacity: 0.4; pointer-events: none; }
|
|
10
|
+
.accordion-section { display: flex; flex-direction: column; flex-shrink: 0; overflow: hidden; border-bottom: 1px solid var(--neutralLight); }
|
|
11
|
+
.accordion-section:last-child { border-bottom: none; }
|
|
12
|
+
.accordion-section.active { flex-shrink: 1; flex-grow: 1; min-height: 0; }
|
|
13
|
+
.accordion-header { display: flex; justify-content: space-between; align-items: center; width: 100%; padding: 14px 20px; background: none; border: none; color: var(--bodyText); font-size: 15px; font-weight: 600; cursor: pointer; transition: background .2s; flex-shrink: 0; }
|
|
14
|
+
.accordion-header:hover { background: var(--defaultHoverBackground); }
|
|
15
|
+
.accordion-section.active .accordion-header { background: var(--defaultHoverBackground); }
|
|
16
|
+
.accordion-chevron { font-size: 11px; color: var(--bodySubtext); transition: transform .3s; }
|
|
17
|
+
.accordion-section.active .accordion-chevron { transform: rotate(180deg); }
|
|
18
|
+
.accordion-body { display: none; flex-direction: column; flex-grow: 1; min-height: 0; overflow: hidden; }
|
|
19
|
+
.accordion-section.active .accordion-body { display: flex; }
|
|
20
|
+
.accordion-content { display: flex; flex-direction: column; gap: 15px; overflow-y: auto; padding: 20px; flex-grow: 1; }
|
|
21
|
+
.button-row { display: flex; justify-content: flex-end; padding: 12px 20px; border-top: 1px solid var(--neutralLight); flex-shrink: 0; }
|
|
22
|
+
.wizard-hidden { display: none !important; }
|
|
23
|
+
.model-card { border: 1px solid var(--neutralLight); border-radius: 8px; padding: 16px; display: flex; flex-direction: column; gap: 12px; background: var(--defaultStateBackground); }
|
|
24
|
+
.model-card.disabled { opacity: 0.35; pointer-events: none; user-select: none; }
|
|
25
|
+
.accordion-section.disabled .accordion-header { opacity: 0.35; pointer-events: none; cursor: default; }
|
|
26
|
+
.connector-grid { display: flex; flex-wrap: wrap; gap: 12px; }
|
|
27
|
+
.connector-tile { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 18px 12px; border-radius: 12px; border: 1px solid var(--neutralLight); background: var(--defaultStateBackground); cursor: pointer; transition: background .2s, border-color .2s, box-shadow .2s, transform .15s; gap: 8px; min-width: 130px; }
|
|
28
|
+
.connector-tile:hover { background: var(--defaultHoverBackground); border-color: var(--themePrimary); box-shadow: 0 4px 12px rgba(0,0,0,.1); transform: translateY(-1px); }
|
|
29
|
+
.connector-tile.configured { border-color: var(--themePrimary); box-shadow: 0 2px 8px var(--themeLighter); }
|
|
30
|
+
.filter-bar { display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; }
|
|
31
|
+
.filter-buttons-container { display: flex; gap: 8px; flex-shrink: 1; min-width: 0; overflow: hidden; flex-wrap: nowrap; }
|
|
32
|
+
.more-dropdown { position: relative; flex-shrink: 0; }
|
|
33
|
+
.more-menu { position: absolute; top: 100%; left: 0; margin-top: 4px; min-width: 150px; max-height: 250px; overflow-y: auto; display: none; z-index: 100; }
|
|
34
|
+
.agent-chat-panel { border: 1px solid var(--neutralLight); border-radius: 8px; margin-top: 12px; overflow: hidden; display: none; }
|
|
35
|
+
.agent-chat-panel.open { display: flex; flex-direction: column; }
|
|
36
|
+
.agent-chat-header { display: flex; justify-content: space-between; align-items: center; padding: 10px 16px; background: var(--defaultHoverBackground); font-size: 13px; font-weight: 600; color: var(--bodyText); }
|
|
37
|
+
.agent-chat-messages { max-height: 250px; overflow-y: auto; padding: 12px 16px; display: flex; flex-direction: column; gap: 8px; font-size: 13px; }
|
|
38
|
+
.agent-chat-msg { padding: 8px 12px; border-radius: 10px; max-width: 85%; line-height: 1.5; word-wrap: break-word; white-space: pre-wrap; }
|
|
39
|
+
.agent-chat-msg.user { background: var(--themePrimary); color: #fff; align-self: flex-end; }
|
|
40
|
+
.agent-chat-msg.agent { background: var(--defaultStateBackground); color: var(--bodyText); align-self: flex-start; border: 1px solid var(--neutralLight); }
|
|
41
|
+
.agent-chat-msg.error { background: var(--errorBackground); color: var(--errorText); align-self: center; font-size: 12px; }
|
|
42
|
+
.agent-chat-msg.status { color: var(--bodySubtext); align-self: center; font-size: 12px; font-style: italic; }
|
|
43
|
+
.agent-chat-input-row { display: flex; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--neutralLight); }
|
|
44
|
+
</style>
|
|
8
45
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js"></script>
|
|
9
46
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/14.1.1/marked.min.js"></script>
|
|
10
47
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/11.1.0/mermaid.min.js"></script>
|
|
48
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
|
|
11
49
|
</head>
|
|
12
50
|
<body>
|
|
51
|
+
<div class="shell-toolbar" data-locked="true">
|
|
52
|
+
<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>
|
|
53
|
+
<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>
|
|
54
|
+
<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>
|
|
55
|
+
<div class="shell-toolbar-spacer" data-locked="true"></div>
|
|
56
|
+
<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>
|
|
57
|
+
</div>
|
|
13
58
|
<div class="chat-panel" data-locked="true">
|
|
14
|
-
<div class="chat-header" data-locked="true">
|
|
59
|
+
<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>
|
|
15
60
|
<div class="chat-messages" id="chatMessages" data-locked="true">
|
|
16
61
|
<div class="chat-message" id="defaultGreeting">
|
|
17
|
-
<p><strong>SynthOS:</strong>
|
|
18
|
-
<p>
|
|
62
|
+
<p><strong>SynthOS:</strong> This is where you can customize your experience. Change your theme and toolbar layout under <strong>Appearance</strong>, configure AI models under <strong>Page Building & Chat</strong>, or set up integrations under <strong>Connectors</strong> and <strong>Agents</strong>.</p>
|
|
63
|
+
<p>Click <strong>Apply</strong> when you're ready to save your changes.</p>
|
|
19
64
|
</div>
|
|
20
65
|
<div class="chat-message" id="firstRunGreeting" style="display:none;">
|
|
21
66
|
<p><strong>SynthOS:</strong> Welcome to SynthOS! We're glad you're here.</p>
|
|
22
67
|
<p>Before you can start building, we need to connect to an AI provider. Just pick your provider below, paste in your API key, and you'll be ready to go.</p>
|
|
23
68
|
<p>You can always come back to this page later to change your theme or enable additional features.</p>
|
|
24
69
|
</div>
|
|
25
|
-
</div>
|
|
26
|
-
<div class="link-group" data-locked="true">
|
|
27
|
-
<a href="#" id="saveLink" data-locked="true">Save</a>
|
|
28
|
-
<a href="/pages" id="pagesLink" data-locked="true">Pages</a>
|
|
29
|
-
<a href="#" id="resetLink" data-locked="true">Reset</a>
|
|
30
|
-
</div>
|
|
70
|
+
</div>
|
|
31
71
|
<form action="/" method="POST" id="chatForm" data-locked="true">
|
|
32
|
-
<
|
|
33
|
-
<button type="submit" class="chat-submit" data-locked="true">Send</button>
|
|
72
|
+
<textarea class="chat-input" id="chatInput" name="message" rows="2" placeholder="Type a message..." data-locked="true"></textarea>
|
|
34
73
|
</form>
|
|
35
74
|
</div>
|
|
36
75
|
<div class="viewer-panel" id="viewerPanel" style="justify-content: flex-start; align-items: stretch;">
|
|
37
|
-
<div
|
|
38
|
-
|
|
76
|
+
<div style="padding: 16px 20px; border-bottom: 1px solid var(--neutralLight);">
|
|
77
|
+
<span class="flm-text flm-text--xLarge flm-text--bold">Settings</span>
|
|
78
|
+
</div>
|
|
79
|
+
<div class="flm-stack" style="flex-grow: 1; overflow: hidden;">
|
|
39
80
|
|
|
40
|
-
<div class="accordion-section active" data-section="
|
|
81
|
+
<div class="accordion-section active" data-section="appearance">
|
|
41
82
|
<button class="accordion-header">
|
|
42
|
-
<span>
|
|
83
|
+
<span>Appearance</span>
|
|
43
84
|
<span class="accordion-chevron">▾</span>
|
|
44
85
|
</button>
|
|
45
86
|
<div class="accordion-body">
|
|
46
87
|
<div class="accordion-content">
|
|
47
|
-
<div class="
|
|
48
|
-
<label for="theme">Theme</label>
|
|
49
|
-
<select id="theme">
|
|
88
|
+
<div class="flm-textfield">
|
|
89
|
+
<label class="flm-label" for="theme">Theme</label>
|
|
90
|
+
<select id="theme" class="flm-textfield-input">
|
|
50
91
|
<option value="">Loading themes...</option>
|
|
51
92
|
</select>
|
|
52
93
|
</div>
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
94
|
+
<div class="flm-textfield">
|
|
95
|
+
<label class="flm-label" for="toolbarPosition">Toolbar Position</label>
|
|
96
|
+
<select id="toolbarPosition" class="flm-textfield-input">
|
|
97
|
+
<option value="left">Left</option>
|
|
98
|
+
<option value="right">Right</option>
|
|
99
|
+
</select>
|
|
100
|
+
</div>
|
|
56
101
|
</div>
|
|
57
102
|
</div>
|
|
58
103
|
</div>
|
|
@@ -64,79 +109,76 @@
|
|
|
64
109
|
</button>
|
|
65
110
|
<div class="accordion-body">
|
|
66
111
|
<div class="accordion-content">
|
|
67
|
-
<div id="configBanner" class="
|
|
112
|
+
<div id="configBanner" class="flm-messagebar flm-messagebar--warning" style="display:none;">
|
|
68
113
|
Model configuration is required before you can use SynthOS. Please fill in the Page Builder fields below and click Apply.
|
|
69
114
|
</div>
|
|
70
115
|
|
|
71
116
|
<div class="model-card" id="builderCard">
|
|
72
|
-
<
|
|
73
|
-
<div class="
|
|
74
|
-
<label for="provider-builder">Provider</label>
|
|
75
|
-
<select id="provider-builder" required="">
|
|
117
|
+
<span class="flm-text flm-text--mediumPlus flm-text--bold">Page Builder Model</span>
|
|
118
|
+
<div class="flm-textfield">
|
|
119
|
+
<label class="flm-label" for="provider-builder">Provider</label>
|
|
120
|
+
<select id="provider-builder" class="flm-textfield-input" required="">
|
|
76
121
|
<option value="">Select a provider</option>
|
|
77
122
|
</select>
|
|
78
123
|
</div>
|
|
79
|
-
<div class="
|
|
80
|
-
<label for="serviceApiKey-builder">API Key</label>
|
|
81
|
-
<input type="password" id="serviceApiKey-builder" placeholder="Enter your API Key" required="">
|
|
82
|
-
<div id="providerInstructions" class="info
|
|
124
|
+
<div class="flm-textfield" id="fg-apikey-builder">
|
|
125
|
+
<label class="flm-label" for="serviceApiKey-builder">API Key</label>
|
|
126
|
+
<input type="password" id="serviceApiKey-builder" class="flm-textfield-input" placeholder="Enter your API Key" required="">
|
|
127
|
+
<div id="providerInstructions" class="flm-messagebar flm-messagebar--info" style="display:none;margin-top:8px;"></div>
|
|
83
128
|
</div>
|
|
84
|
-
<div class="
|
|
85
|
-
<label for="model-builder">Model</label>
|
|
86
|
-
<select id="model-builder" required="">
|
|
129
|
+
<div class="flm-textfield" id="fg-model-builder">
|
|
130
|
+
<label class="flm-label" for="model-builder">Model</label>
|
|
131
|
+
<select id="model-builder" class="flm-textfield-input" required="">
|
|
87
132
|
<option value="">Select a model</option>
|
|
88
133
|
</select>
|
|
89
134
|
</div>
|
|
90
|
-
<a id="moreSettingsLink" class="
|
|
91
|
-
<div class="
|
|
92
|
-
<label for="maxTokens-builder">Max Output Tokens</label>
|
|
93
|
-
<input type="number" id="maxTokens-builder" placeholder="Enter max token count" required="">
|
|
135
|
+
<a id="moreSettingsLink" class="flm-link" style="font-size:13px;">▾ More settings</a>
|
|
136
|
+
<div class="flm-textfield" id="fg-maxTokens-builder">
|
|
137
|
+
<label class="flm-label" for="maxTokens-builder">Max Output Tokens</label>
|
|
138
|
+
<input type="number" id="maxTokens-builder" class="flm-textfield-input" placeholder="Enter max token count" required="">
|
|
94
139
|
</div>
|
|
95
|
-
<div class="
|
|
96
|
-
<label for="instructions-builder">Additional Instructions</label>
|
|
97
|
-
<textarea id="instructions-builder" placeholder="Enter any additional instructions"></textarea>
|
|
140
|
+
<div class="flm-textfield" id="fg-instructions-builder">
|
|
141
|
+
<label class="flm-label" for="instructions-builder">Additional Instructions</label>
|
|
142
|
+
<textarea id="instructions-builder" class="flm-textfield-input" placeholder="Enter any additional instructions"></textarea>
|
|
98
143
|
</div>
|
|
99
144
|
</div>
|
|
100
145
|
|
|
101
146
|
<div class="model-card" id="chatCard">
|
|
102
|
-
<
|
|
103
|
-
<div class="
|
|
104
|
-
<label for="provider-chat">Provider</label>
|
|
105
|
-
<select id="provider-chat" required="">
|
|
147
|
+
<span class="flm-text flm-text--mediumPlus flm-text--bold">Chat Model</span>
|
|
148
|
+
<div class="flm-textfield" id="fg-provider-chat">
|
|
149
|
+
<label class="flm-label" for="provider-chat">Provider</label>
|
|
150
|
+
<select id="provider-chat" class="flm-textfield-input" required="">
|
|
106
151
|
<option value="">Select a provider</option>
|
|
107
152
|
</select>
|
|
108
153
|
</div>
|
|
109
|
-
<div class="
|
|
110
|
-
<label for="serviceApiKey-chat">API Key</label>
|
|
111
|
-
<input type="password" id="serviceApiKey-chat" placeholder="Enter your API Key" required="">
|
|
154
|
+
<div class="flm-textfield" id="fg-apikey-chat">
|
|
155
|
+
<label class="flm-label" for="serviceApiKey-chat">API Key</label>
|
|
156
|
+
<input type="password" id="serviceApiKey-chat" class="flm-textfield-input" placeholder="Enter your API Key" required="">
|
|
112
157
|
</div>
|
|
113
|
-
<div class="
|
|
114
|
-
<label for="model-chat">Model</label>
|
|
115
|
-
<select id="model-chat" required="">
|
|
158
|
+
<div class="flm-textfield" id="fg-model-chat">
|
|
159
|
+
<label class="flm-label" for="model-chat">Model</label>
|
|
160
|
+
<select id="model-chat" class="flm-textfield-input" required="">
|
|
116
161
|
<option value="">Select a model</option>
|
|
117
162
|
</select>
|
|
118
163
|
</div>
|
|
119
|
-
<a id="moreSettingsLinkChat" class="
|
|
120
|
-
<div class="
|
|
121
|
-
<label for="maxTokens-chat">Max Output Tokens</label>
|
|
122
|
-
<input type="number" id="maxTokens-chat" placeholder="Enter max token count" required="">
|
|
164
|
+
<a id="moreSettingsLinkChat" class="flm-link" style="font-size:13px;">▾ More settings</a>
|
|
165
|
+
<div class="flm-textfield" id="fg-maxTokens-chat">
|
|
166
|
+
<label class="flm-label" for="maxTokens-chat">Max Output Tokens</label>
|
|
167
|
+
<input type="number" id="maxTokens-chat" class="flm-textfield-input" placeholder="Enter max token count" required="">
|
|
123
168
|
</div>
|
|
124
|
-
<div class="
|
|
125
|
-
<label for="instructions-chat">Additional Instructions</label>
|
|
126
|
-
<textarea id="instructions-chat" placeholder="Enter any additional instructions"></textarea>
|
|
169
|
+
<div class="flm-textfield" id="fg-instructions-chat">
|
|
170
|
+
<label class="flm-label" for="instructions-chat">Additional Instructions</label>
|
|
171
|
+
<textarea id="instructions-chat" class="flm-textfield-input" placeholder="Enter any additional instructions"></textarea>
|
|
127
172
|
</div>
|
|
128
173
|
</div>
|
|
129
174
|
|
|
130
175
|
</div>
|
|
131
|
-
<div class="button-row">
|
|
132
|
-
<button class="apply-btn" data-apply="models">Apply</button>
|
|
133
|
-
</div>
|
|
134
176
|
</div>
|
|
135
177
|
</div>
|
|
136
178
|
|
|
137
179
|
<div class="accordion-section" data-section="connectors">
|
|
138
180
|
<button class="accordion-header">
|
|
139
|
-
<span>Connectors <span style="display:inline-block;margin-left:6px;padding:1px 7px;font-size:10px;font-weight:600;letter-spacing:.5px;border-radius:6px;background:var(--
|
|
181
|
+
<span>Connectors <span style="display:inline-block;margin-left:6px;padding:1px 7px;font-size:10px;font-weight:600;letter-spacing:.5px;border-radius:6px;background:var(--themePrimary);color:#fff;vertical-align:middle;line-height:16px;text-transform:uppercase;">Preview</span></span>
|
|
140
182
|
<span class="accordion-chevron">▾</span>
|
|
141
183
|
</button>
|
|
142
184
|
<div class="accordion-body">
|
|
@@ -144,10 +186,12 @@
|
|
|
144
186
|
<div class="filter-bar" id="connectorFilterBar">
|
|
145
187
|
<div class="filter-buttons-container" id="connectorFilterButtons"></div>
|
|
146
188
|
<div class="more-dropdown" id="connMoreDropdown" style="display:none;">
|
|
147
|
-
<button class="
|
|
148
|
-
<div class="more-menu" id="connMoreMenu"></div>
|
|
189
|
+
<button class="flm-button flm-button--subtle" id="connMoreBtn">More <i class="flm-icon" data-icon="ChevronDown"></i></button>
|
|
190
|
+
<div class="flm-contextmenu more-menu" id="connMoreMenu"></div>
|
|
191
|
+
</div>
|
|
192
|
+
<div class="flm-searchbox" id="connectorSearchBox">
|
|
193
|
+
<input class="flm-searchbox-input" type="text" id="connectorSearch" placeholder="Search connectors...">
|
|
149
194
|
</div>
|
|
150
|
-
<input type="text" class="search-input" id="connectorSearch" placeholder="Search connectors...">
|
|
151
195
|
</div>
|
|
152
196
|
<div class="connector-grid" id="connectorGrid"></div>
|
|
153
197
|
</div>
|
|
@@ -156,28 +200,28 @@
|
|
|
156
200
|
|
|
157
201
|
<div class="accordion-section" data-section="agents">
|
|
158
202
|
<button class="accordion-header">
|
|
159
|
-
<span>Agents <span style="display:inline-block;margin-left:6px;padding:1px 7px;font-size:10px;font-weight:600;letter-spacing:.5px;border-radius:6px;background:var(--
|
|
203
|
+
<span>Agents <span style="display:inline-block;margin-left:6px;padding:1px 7px;font-size:10px;font-weight:600;letter-spacing:.5px;border-radius:6px;background:var(--themePrimary);color:#fff;vertical-align:middle;line-height:16px;text-transform:uppercase;">Preview</span></span>
|
|
160
204
|
<span class="accordion-chevron">▾</span>
|
|
161
205
|
</button>
|
|
162
206
|
<div class="accordion-body">
|
|
163
207
|
<div class="accordion-content">
|
|
164
|
-
<div
|
|
165
|
-
<
|
|
166
|
-
<button class="
|
|
208
|
+
<div class="flm-stack flm-stack--horizontal flm-stack--space-between" style="align-items:center;margin-bottom:12px;">
|
|
209
|
+
<span class="flm-text flm-text--small flm-text--secondary">Configure agents (A2A or OpenClaw) that your pages can communicate with.</span>
|
|
210
|
+
<button class="flm-button flm-button--primary" id="addAgentBtn" style="white-space:nowrap;">+ Add Agent</button>
|
|
167
211
|
</div>
|
|
168
|
-
<div class="
|
|
169
|
-
<div id="agentEmptyState" style="display:none;text-align:center;padding:30px;color:var(--
|
|
212
|
+
<div class="flm-list flm-list--bordered" id="agentList"></div>
|
|
213
|
+
<div id="agentEmptyState" style="display:none;text-align:center;padding:30px;color:var(--bodySubtext);font-size:14px;">
|
|
170
214
|
No agents configured yet. Click "+ Add Agent" to get started.
|
|
171
215
|
</div>
|
|
172
216
|
<div class="agent-chat-panel" id="agentChatPanel">
|
|
173
217
|
<div class="agent-chat-header">
|
|
174
218
|
<span id="agentChatTitle">Chat with Agent</span>
|
|
175
|
-
<button class="
|
|
219
|
+
<button class="flm-button flm-button--subtle flm-button--icon" id="agentChatClose" aria-label="Close chat" data-icon="Cancel"></button>
|
|
176
220
|
</div>
|
|
177
221
|
<div class="agent-chat-messages" id="agentChatMessages"></div>
|
|
178
222
|
<div class="agent-chat-input-row">
|
|
179
|
-
<input type="text" class="
|
|
180
|
-
<button class="
|
|
223
|
+
<input type="text" class="flm-textfield-input" id="agentChatInput" placeholder="Type a test message..." style="flex:1;">
|
|
224
|
+
<button class="flm-button flm-button--primary" id="agentChatSendBtn">Send</button>
|
|
181
225
|
</div>
|
|
182
226
|
</div>
|
|
183
227
|
</div>
|
|
@@ -185,125 +229,152 @@
|
|
|
185
229
|
</div>
|
|
186
230
|
|
|
187
231
|
</div>
|
|
232
|
+
<div class="button-row" id="applyRow">
|
|
233
|
+
<button class="flm-button" id="applyBtn">Apply</button>
|
|
234
|
+
</div>
|
|
188
235
|
<div id="loadingOverlay" class="loading-overlay"><div class="spinner"></div></div>
|
|
189
236
|
</div>
|
|
190
|
-
<div class="
|
|
191
|
-
<div class="
|
|
192
|
-
<div class="
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
<
|
|
237
|
+
<div class="flm-dialog-overlay" id="agentModal">
|
|
238
|
+
<div class="flm-dialog" style="max-width:520px;width:90%;max-height:85vh;overflow-y:auto;">
|
|
239
|
+
<div class="flm-dialog-header">
|
|
240
|
+
<h2 class="flm-dialog-title" id="agentModalTitle">Add Agent</h2>
|
|
241
|
+
</div>
|
|
242
|
+
<div class="flm-dialog-body">
|
|
243
|
+
<div class="flm-stack" style="gap:10px;" id="agentFormGroup">
|
|
244
|
+
<div class="flm-textfield">
|
|
245
|
+
<label class="flm-label">Agent Type</label>
|
|
246
|
+
<div class="flm-stack flm-stack--horizontal" style="gap:8px;">
|
|
247
|
+
<button class="flm-pivot-tab flm-pivot-tab--active" id="agentTypeA2A">A2A Agent</button>
|
|
248
|
+
<button class="flm-pivot-tab" id="agentTypeOpenClaw">OpenClaw Agent</button>
|
|
249
|
+
</div>
|
|
199
250
|
</div>
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
251
|
+
<div class="flm-textfield">
|
|
252
|
+
<label class="flm-label" for="agentUrl">Agent URL</label>
|
|
253
|
+
<div class="flm-stack flm-stack--horizontal" style="gap:8px;">
|
|
254
|
+
<input type="text" id="agentUrl" class="flm-textfield-input" placeholder="https://example.com" style="flex:1;">
|
|
255
|
+
<button class="flm-button flm-button--primary" id="agentDiscoverBtn" style="white-space:nowrap;">Discover</button>
|
|
256
|
+
</div>
|
|
257
|
+
<span id="agentUrlHint" class="flm-text flm-text--small flm-text--secondary" style="margin-top:4px;">Enter a URL and click Discover to auto-fill from the agent card, or fill in the fields manually.</span>
|
|
206
258
|
</div>
|
|
207
|
-
<div id="
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
<label for="agentToken">Token</label>
|
|
211
|
-
<input type="password" id="agentToken" placeholder="Gateway authentication token">
|
|
212
|
-
</div>
|
|
213
|
-
<div class="form-group" id="agentSessionKeyGroup" style="margin-bottom:10px;display:none;">
|
|
214
|
-
<label for="agentSessionKey">Default Session Key</label>
|
|
215
|
-
<input type="text" id="agentSessionKey" placeholder="e.g. agent:main:main">
|
|
216
|
-
</div>
|
|
217
|
-
<div id="agentSshTunnelGroup" style="display:none;margin-bottom:10px;">
|
|
218
|
-
<div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;cursor:pointer;" id="agentSshTunnelToggleHeader">
|
|
219
|
-
<span style="font-size:12px;color:var(--text-secondary);" id="agentSshTunnelArrow">▶</span>
|
|
220
|
-
<label style="margin:0;cursor:pointer;font-size:13px;font-weight:600;color:var(--text-secondary);">SSH Tunnel</label>
|
|
221
|
-
<label class="toggle-switch" style="margin-left:auto;" onclick="event.stopPropagation();">
|
|
222
|
-
<input type="checkbox" id="agentSshTunnelEnabled">
|
|
223
|
-
<span class="toggle-slider"></span>
|
|
224
|
-
</label>
|
|
259
|
+
<div class="flm-textfield" id="agentTokenGroup" style="display:none;">
|
|
260
|
+
<label class="flm-label" for="agentToken">Token</label>
|
|
261
|
+
<input type="password" id="agentToken" class="flm-textfield-input" placeholder="Gateway authentication token">
|
|
225
262
|
</div>
|
|
226
|
-
<div id="
|
|
227
|
-
<
|
|
228
|
-
|
|
229
|
-
|
|
263
|
+
<div class="flm-textfield" id="agentSessionKeyGroup" style="display:none;">
|
|
264
|
+
<label class="flm-label" for="agentSessionKey">Default Session Key</label>
|
|
265
|
+
<input type="text" id="agentSessionKey" class="flm-textfield-input" placeholder="e.g. agent:main:main">
|
|
266
|
+
</div>
|
|
267
|
+
<div id="agentSshTunnelGroup" style="display:none;">
|
|
268
|
+
<div class="flm-stack flm-stack--horizontal" style="align-items:center;gap:8px;cursor:pointer;margin-bottom:8px;" id="agentSshTunnelToggleHeader">
|
|
269
|
+
<span class="flm-text flm-text--small flm-text--secondary" id="agentSshTunnelArrow">▶</span>
|
|
270
|
+
<label class="flm-label" style="margin:0;cursor:pointer;">SSH Tunnel</label>
|
|
271
|
+
<label class="flm-toggle flm-toggle--inline" style="margin-left:auto;" onclick="event.stopPropagation();">
|
|
272
|
+
<input type="checkbox" class="flm-toggle-input" id="agentSshTunnelEnabled">
|
|
273
|
+
<span class="flm-toggle-track"><span class="flm-toggle-thumb"></span></span>
|
|
274
|
+
</label>
|
|
230
275
|
</div>
|
|
231
|
-
<div
|
|
232
|
-
<
|
|
233
|
-
|
|
276
|
+
<div id="agentSshTunnelFields" style="display:none;padding-left:4px;" class="flm-stack" >
|
|
277
|
+
<div class="flm-textfield" style="margin-bottom:8px;">
|
|
278
|
+
<label class="flm-label" for="agentSshCommand" style="font-size:12px;">SSH Command</label>
|
|
279
|
+
<input type="text" id="agentSshCommand" class="flm-textfield-input" placeholder="ssh -p 22 -N -L 18789:127.0.0.1:43901 root@0.0.0.0">
|
|
280
|
+
</div>
|
|
281
|
+
<div class="flm-textfield" style="margin-bottom:8px;">
|
|
282
|
+
<label class="flm-label" for="agentSshPassword" style="font-size:12px;">Password</label>
|
|
283
|
+
<input type="password" id="agentSshPassword" class="flm-textfield-input" placeholder="SSH password">
|
|
284
|
+
</div>
|
|
234
285
|
</div>
|
|
235
286
|
</div>
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
287
|
+
<div class="flm-textfield">
|
|
288
|
+
<label class="flm-label" for="agentName">Name</label>
|
|
289
|
+
<input type="text" id="agentName" class="flm-textfield-input" placeholder="My Agent">
|
|
290
|
+
</div>
|
|
291
|
+
<div class="flm-textfield">
|
|
292
|
+
<label class="flm-label" for="agentDescription">Description</label>
|
|
293
|
+
<textarea id="agentDescription" class="flm-textfield-input" placeholder="Describe what this agent does and when to use it..." style="min-height:60px;"></textarea>
|
|
294
|
+
</div>
|
|
295
|
+
<div id="agentSkillsPreview" style="display:none;padding:10px;border-radius:8px;border:1px solid var(--neutralLight);background:var(--defaultStateBackground);">
|
|
296
|
+
<span class="flm-text flm-text--small flm-text--semibold flm-text--secondary" style="margin-bottom:4px;display:block;">Discovered Skills</span>
|
|
297
|
+
<div id="agentSkillsList" class="flm-text flm-text--small flm-text--secondary"></div>
|
|
298
|
+
</div>
|
|
248
299
|
</div>
|
|
249
300
|
</div>
|
|
250
|
-
<div class="
|
|
251
|
-
<button class="
|
|
252
|
-
<button class="
|
|
253
|
-
<button class="
|
|
301
|
+
<div class="flm-dialog-footer">
|
|
302
|
+
<button class="flm-button flm-button--primary" id="agentSaveBtn">Save</button>
|
|
303
|
+
<button class="flm-button" id="agentCancelBtn">Cancel</button>
|
|
304
|
+
<button class="flm-button" id="agentRemoveBtn" style="display:none;color:var(--errorText);">Remove</button>
|
|
254
305
|
</div>
|
|
255
306
|
</div>
|
|
256
307
|
</div>
|
|
257
|
-
<div class="
|
|
258
|
-
<div class="
|
|
259
|
-
<div class="
|
|
260
|
-
|
|
261
|
-
<div id="connectorOnboarding" style="display:none;">
|
|
262
|
-
<a id="connectorOnboardingLink" href="#" target="_blank"
|
|
263
|
-
style="color:var(--accent-tertiary);font-size:13px;font-weight:500;text-decoration:none;transition:.3s;">
|
|
264
|
-
Get your API key →
|
|
265
|
-
</a>
|
|
266
|
-
<ol id="connectorOnboardingSteps"
|
|
267
|
-
style="font-size:13px;color:var(--text-secondary);margin:8px 0 0;padding-left:20px;line-height:1.8;">
|
|
268
|
-
</ol>
|
|
308
|
+
<div class="flm-dialog-overlay" id="connectorModal">
|
|
309
|
+
<div class="flm-dialog" style="max-width:520px;width:90%;max-height:85vh;overflow-y:auto;">
|
|
310
|
+
<div class="flm-dialog-header">
|
|
311
|
+
<h2 class="flm-dialog-title" id="connectorModalTitle"></h2>
|
|
269
312
|
</div>
|
|
270
|
-
<div
|
|
271
|
-
<
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
<div id="connectorManualGroup">
|
|
281
|
-
<div class="form-group" style="margin-bottom:10px;">
|
|
282
|
-
<label for="oauth-field-accessToken">Access Token</label>
|
|
283
|
-
<input type="password" id="oauth-field-accessToken" placeholder="Paste token from Graph API Explorer">
|
|
313
|
+
<div class="flm-dialog-body">
|
|
314
|
+
<div class="flm-stack" style="gap:12px;">
|
|
315
|
+
<span class="flm-text flm-text--small flm-text--secondary" id="connectorModalDesc"></span>
|
|
316
|
+
<div id="connectorOnboarding" style="display:none;">
|
|
317
|
+
<a id="connectorOnboardingLink" class="flm-link" href="#" target="_blank">
|
|
318
|
+
Get your API key →
|
|
319
|
+
</a>
|
|
320
|
+
<ol id="connectorOnboardingSteps"
|
|
321
|
+
style="font-size:13px;color:var(--bodySubtext);margin:8px 0 0;padding-left:20px;line-height:1.8;">
|
|
322
|
+
</ol>
|
|
284
323
|
</div>
|
|
285
|
-
<div
|
|
286
|
-
<label
|
|
287
|
-
<input type="
|
|
324
|
+
<div id="connectorApiKeyGroup" class="flm-textfield">
|
|
325
|
+
<label class="flm-label" for="connectorApiKey">API Key</label>
|
|
326
|
+
<input type="password" id="connectorApiKey" class="flm-textfield-input" placeholder="Enter your API key">
|
|
327
|
+
</div>
|
|
328
|
+
<div id="connectorOAuthGroup" style="display:none;">
|
|
329
|
+
<div id="connectorOAuthStatus" style="margin-bottom:12px;font-size:13px;line-height:1.5;"></div>
|
|
330
|
+
<div id="connectorOAuthModeToggle" class="flm-stack flm-stack--horizontal" style="gap:8px;margin-bottom:12px;">
|
|
331
|
+
<button class="flm-pivot-tab flm-pivot-tab--active" id="oauthModeManual">Manual Token</button>
|
|
332
|
+
<button class="flm-pivot-tab" id="oauthModeApp">OAuth App</button>
|
|
333
|
+
</div>
|
|
334
|
+
<div id="connectorManualGroup">
|
|
335
|
+
<div class="flm-textfield" style="margin-bottom:10px;">
|
|
336
|
+
<label class="flm-label" for="oauth-field-accessToken">Access Token</label>
|
|
337
|
+
<input type="password" id="oauth-field-accessToken" class="flm-textfield-input" placeholder="Paste token from Graph API Explorer">
|
|
338
|
+
</div>
|
|
339
|
+
<div class="flm-textfield" style="margin-bottom:10px;">
|
|
340
|
+
<label class="flm-label" for="oauth-field-userId">IG User ID <span class="flm-text--secondary" style="font-weight:400;">(optional)</span></label>
|
|
341
|
+
<input type="text" id="oauth-field-userId" class="flm-textfield-input" placeholder="Instagram Business Account ID">
|
|
342
|
+
</div>
|
|
343
|
+
</div>
|
|
344
|
+
<div id="connectorAppGroup" style="display:none;">
|
|
345
|
+
<div id="connectorOAuthFields" class="flm-stack" style="gap:10px;"></div>
|
|
346
|
+
<button class="flm-button flm-button--primary" id="connectorConnectBtn" style="width:100%;margin-top:8px;margin-bottom:8px;">Connect with OAuth</button>
|
|
347
|
+
</div>
|
|
348
|
+
<button class="flm-button" id="connectorDisconnectBtn" style="width:100%;display:none;color:var(--errorText);">Disconnect</button>
|
|
349
|
+
</div>
|
|
350
|
+
<div class="flm-stack flm-stack--horizontal" style="align-items:center;gap:12px;">
|
|
351
|
+
<label class="flm-label" for="connectorEnabled" style="margin-bottom:0;">Enabled</label>
|
|
352
|
+
<label class="flm-toggle flm-toggle--inline">
|
|
353
|
+
<input type="checkbox" class="flm-toggle-input" id="connectorEnabled">
|
|
354
|
+
<span class="flm-toggle-track"><span class="flm-toggle-thumb"></span></span>
|
|
355
|
+
</label>
|
|
288
356
|
</div>
|
|
289
357
|
</div>
|
|
290
|
-
<div id="connectorAppGroup" style="display:none;">
|
|
291
|
-
<div class="form-group" id="connectorOAuthFields"></div>
|
|
292
|
-
<button class="conn-modal-btn" id="connectorConnectBtn" style="width:100%;margin-bottom:8px;">Connect with OAuth</button>
|
|
293
|
-
</div>
|
|
294
|
-
<button class="conn-modal-btn remove" id="connectorDisconnectBtn" style="width:100%;display:none;">Disconnect</button>
|
|
295
358
|
</div>
|
|
296
|
-
<div class="
|
|
297
|
-
<
|
|
298
|
-
<
|
|
299
|
-
|
|
300
|
-
<span class="toggle-slider"></span>
|
|
301
|
-
</label>
|
|
359
|
+
<div class="flm-dialog-footer">
|
|
360
|
+
<button class="flm-button flm-button--primary" id="connectorSaveBtn">Save</button>
|
|
361
|
+
<button class="flm-button" id="connectorCancelBtn">Cancel</button>
|
|
362
|
+
<button class="flm-button" id="connectorRemoveBtn" style="color:var(--errorText);">Remove</button>
|
|
302
363
|
</div>
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
364
|
+
</div>
|
|
365
|
+
</div>
|
|
366
|
+
<div class="flm-dialog-overlay" id="unsavedDialog" data-light-dismiss>
|
|
367
|
+
<div class="flm-dialog" style="max-width:400px;width:90%;">
|
|
368
|
+
<div class="flm-dialog-header">
|
|
369
|
+
<h2 class="flm-dialog-title">Unsaved Changes</h2>
|
|
370
|
+
</div>
|
|
371
|
+
<div class="flm-dialog-body">
|
|
372
|
+
<p class="flm-text">You have unsaved changes. Do you want to discard them and leave this page?</p>
|
|
373
|
+
</div>
|
|
374
|
+
<div class="flm-dialog-footer">
|
|
375
|
+
<div style="flex:1;"></div>
|
|
376
|
+
<button class="flm-button" id="unsavedStayBtn">Stay</button>
|
|
377
|
+
<button class="flm-button" id="unsavedLeaveBtn" style="color:var(--errorText);">Discard & Leave</button>
|
|
307
378
|
</div>
|
|
308
379
|
</div>
|
|
309
380
|
</div>
|
|
@@ -341,7 +412,7 @@ document.querySelectorAll('.accordion-header').forEach(function(header) {
|
|
|
341
412
|
// --- URL param: open requested tab ---
|
|
342
413
|
var params = new URLSearchParams(window.location.search);
|
|
343
414
|
var tabParam = params.get('tab');
|
|
344
|
-
if (tabParam && ['
|
|
415
|
+
if (tabParam && ['appearance', 'models', 'connectors', 'agents'].indexOf(tabParam) !== -1) {
|
|
345
416
|
openSection(tabParam);
|
|
346
417
|
}
|
|
347
418
|
|
|
@@ -371,7 +442,7 @@ function getAllConnectorCategories() {
|
|
|
371
442
|
function calculateConnectorVisibleCats() {
|
|
372
443
|
var allCats = getAllConnectorCategories();
|
|
373
444
|
var filterBar = document.getElementById('connectorFilterBar');
|
|
374
|
-
var searchEl = document.getElementById('
|
|
445
|
+
var searchEl = document.getElementById('connectorSearchBox');
|
|
375
446
|
var moreDropdown = document.getElementById('connMoreDropdown');
|
|
376
447
|
if (!filterBar) return;
|
|
377
448
|
|
|
@@ -379,7 +450,7 @@ function calculateConnectorVisibleCats() {
|
|
|
379
450
|
|
|
380
451
|
// Measure button widths
|
|
381
452
|
var temp = document.createElement('button');
|
|
382
|
-
temp.className = '
|
|
453
|
+
temp.className = 'flm-pivot-tab';
|
|
383
454
|
temp.style.visibility = 'hidden';
|
|
384
455
|
temp.style.position = 'absolute';
|
|
385
456
|
document.body.appendChild(temp);
|
|
@@ -456,14 +527,14 @@ function renderConnectorFilterBar() {
|
|
|
456
527
|
|
|
457
528
|
// "All" button
|
|
458
529
|
var allBtn = document.createElement('button');
|
|
459
|
-
allBtn.className = '
|
|
530
|
+
allBtn.className = 'flm-pivot-tab' + (activeConnectorCategory === 'All' ? ' flm-pivot-tab--active' : '');
|
|
460
531
|
allBtn.textContent = 'All';
|
|
461
532
|
allBtn.addEventListener('click', function() { setConnectorCategory('All'); });
|
|
462
533
|
container.appendChild(allBtn);
|
|
463
534
|
|
|
464
535
|
// "Enabled" button (fixed, always visible)
|
|
465
536
|
var enabledBtn = document.createElement('button');
|
|
466
|
-
enabledBtn.className = '
|
|
537
|
+
enabledBtn.className = 'flm-pivot-tab' + (activeConnectorCategory === 'Enabled' ? ' flm-pivot-tab--active' : '');
|
|
467
538
|
enabledBtn.textContent = 'Enabled';
|
|
468
539
|
enabledBtn.addEventListener('click', function() { setConnectorCategory('Enabled'); });
|
|
469
540
|
container.appendChild(enabledBtn);
|
|
@@ -471,7 +542,7 @@ function renderConnectorFilterBar() {
|
|
|
471
542
|
// Visible category buttons
|
|
472
543
|
connVisibleCats.forEach(function(cat) {
|
|
473
544
|
var btn = document.createElement('button');
|
|
474
|
-
btn.className = '
|
|
545
|
+
btn.className = 'flm-pivot-tab' + (activeConnectorCategory === cat ? ' flm-pivot-tab--active' : '');
|
|
475
546
|
btn.textContent = cat;
|
|
476
547
|
btn.addEventListener('click', function() { setConnectorCategory(cat); });
|
|
477
548
|
container.appendChild(btn);
|
|
@@ -480,14 +551,17 @@ function renderConnectorFilterBar() {
|
|
|
480
551
|
// Overflow dropdown
|
|
481
552
|
if (connOverflowCats.length > 0) {
|
|
482
553
|
moreDropdown.style.display = '';
|
|
483
|
-
moreBtn.className = '
|
|
554
|
+
moreBtn.className = 'flm-button flm-button--subtle' + (connOverflowCats.indexOf(activeConnectorCategory) !== -1 ? ' flm-pivot-tab--active' : '');
|
|
484
555
|
connOverflowCats.forEach(function(cat) {
|
|
485
|
-
var item = document.createElement('
|
|
486
|
-
item.className = '
|
|
487
|
-
|
|
556
|
+
var item = document.createElement('button');
|
|
557
|
+
item.className = 'flm-contextmenu-item' + (activeConnectorCategory === cat ? ' flm-contextmenu-item--checked' : '');
|
|
558
|
+
var itemText = document.createElement('span');
|
|
559
|
+
itemText.className = 'flm-contextmenu-item-text';
|
|
560
|
+
itemText.textContent = cat;
|
|
561
|
+
item.appendChild(itemText);
|
|
488
562
|
item.addEventListener('click', function() {
|
|
489
563
|
setConnectorCategory(cat);
|
|
490
|
-
moreMenu.classList.remove('
|
|
564
|
+
moreMenu.classList.remove('flm-contextmenu--visible');
|
|
491
565
|
});
|
|
492
566
|
moreMenu.appendChild(item);
|
|
493
567
|
});
|
|
@@ -511,43 +585,6 @@ function loadConnectors() {
|
|
|
511
585
|
});
|
|
512
586
|
}
|
|
513
587
|
|
|
514
|
-
// --- Connector tooltip ---
|
|
515
|
-
var connTip = document.createElement('div');
|
|
516
|
-
connTip.className = 'conn-tooltip';
|
|
517
|
-
document.body.appendChild(connTip);
|
|
518
|
-
var connTipTimer = null;
|
|
519
|
-
|
|
520
|
-
function showConnTip(el, text) {
|
|
521
|
-
clearTimeout(connTipTimer);
|
|
522
|
-
connTip.textContent = text;
|
|
523
|
-
connTip.style.display = 'block';
|
|
524
|
-
connTip.classList.remove('visible');
|
|
525
|
-
var r = el.getBoundingClientRect();
|
|
526
|
-
var tw = connTip.offsetWidth;
|
|
527
|
-
var th = connTip.offsetHeight;
|
|
528
|
-
// Position below the tile by default
|
|
529
|
-
var left = r.left + (r.width / 2) - (tw / 2);
|
|
530
|
-
var top = r.bottom + 6;
|
|
531
|
-
// Clamp horizontal
|
|
532
|
-
if (left < 4) left = 4;
|
|
533
|
-
if (left + tw > window.innerWidth - 4) left = window.innerWidth - tw - 4;
|
|
534
|
-
// Flip above if it would go off bottom
|
|
535
|
-
if (top + th > window.innerHeight - 4) {
|
|
536
|
-
top = r.top - th - 6;
|
|
537
|
-
}
|
|
538
|
-
connTip.style.left = left + 'px';
|
|
539
|
-
connTip.style.top = top + 'px';
|
|
540
|
-
void connTip.offsetWidth;
|
|
541
|
-
connTip.classList.add('visible');
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
function hideConnTip() {
|
|
545
|
-
clearTimeout(connTipTimer);
|
|
546
|
-
connTip.classList.remove('visible');
|
|
547
|
-
connTip.style.display = 'none';
|
|
548
|
-
}
|
|
549
|
-
hideConnTip();
|
|
550
|
-
|
|
551
588
|
function renderConnectorGrid() {
|
|
552
589
|
var grid = document.getElementById('connectorGrid');
|
|
553
590
|
var searchTerm = (document.getElementById('connectorSearch').value || '').toLowerCase();
|
|
@@ -563,19 +600,16 @@ function renderConnectorGrid() {
|
|
|
563
600
|
}).forEach(function(c) {
|
|
564
601
|
var tile = document.createElement('div');
|
|
565
602
|
tile.className = 'connector-tile' + (c.configured ? ' configured' : '');
|
|
603
|
+
tile.setAttribute('data-tooltip', c.description);
|
|
566
604
|
tile.addEventListener('click', function() { openConnectorModal(c.id); });
|
|
567
605
|
|
|
568
|
-
tile.addEventListener('mouseenter', function() {
|
|
569
|
-
connTipTimer = setTimeout(function() { showConnTip(tile, c.description); }, 400);
|
|
570
|
-
});
|
|
571
|
-
tile.addEventListener('mouseleave', hideConnTip);
|
|
572
|
-
|
|
573
606
|
var name = document.createElement('div');
|
|
574
|
-
name.className = '
|
|
607
|
+
name.className = 'flm-text flm-text--semibold';
|
|
575
608
|
name.textContent = c.name;
|
|
576
609
|
|
|
577
|
-
var cat = document.createElement('
|
|
578
|
-
cat.className = '
|
|
610
|
+
var cat = document.createElement('span');
|
|
611
|
+
cat.className = 'flm-text flm-text--small flm-text--secondary';
|
|
612
|
+
cat.style.cssText = 'background:var(--defaultHoverBackground);padding:2px 8px;border-radius:10px;';
|
|
579
613
|
cat.textContent = c.category;
|
|
580
614
|
|
|
581
615
|
tile.appendChild(name);
|
|
@@ -618,14 +652,15 @@ function openConnectorModal(id) {
|
|
|
618
652
|
fieldsContainer.innerHTML = '';
|
|
619
653
|
(detail.fields || []).forEach(function(f) {
|
|
620
654
|
var wrap = document.createElement('div');
|
|
621
|
-
wrap.className = '
|
|
622
|
-
wrap.style.marginBottom = '10px';
|
|
655
|
+
wrap.className = 'flm-textfield';
|
|
623
656
|
var lbl = document.createElement('label');
|
|
657
|
+
lbl.className = 'flm-label';
|
|
624
658
|
lbl.textContent = f.label;
|
|
625
659
|
lbl.setAttribute('for', 'oauth-field-' + f.name);
|
|
626
660
|
var inp = document.createElement('input');
|
|
627
661
|
inp.type = f.type;
|
|
628
662
|
inp.id = 'oauth-field-' + f.name;
|
|
663
|
+
inp.className = 'flm-textfield-input';
|
|
629
664
|
inp.placeholder = detail.hasKey ? '(saved — leave blank to keep)' : 'Enter ' + f.label;
|
|
630
665
|
wrap.appendChild(lbl);
|
|
631
666
|
wrap.appendChild(inp);
|
|
@@ -647,7 +682,7 @@ function openConnectorModal(id) {
|
|
|
647
682
|
var modeToggle = document.getElementById('connectorOAuthModeToggle');
|
|
648
683
|
if (detail.connected) {
|
|
649
684
|
var displayName = detail.accountName || detail.name;
|
|
650
|
-
statusEl.innerHTML = '<span style="color:var(--
|
|
685
|
+
statusEl.innerHTML = '<span style="color:var(--themePrimary);">Connected as <strong>' + displayName + '</strong></span>';
|
|
651
686
|
statusEl.style.display = '';
|
|
652
687
|
disconnectBtn.style.display = '';
|
|
653
688
|
modeToggle.style.display = 'none';
|
|
@@ -662,7 +697,7 @@ function openConnectorModal(id) {
|
|
|
662
697
|
document.getElementById('connectorApiKey').placeholder = detail.hasKey ? '(key saved — leave blank to keep)' : 'Enter your API key';
|
|
663
698
|
}
|
|
664
699
|
|
|
665
|
-
document.getElementById('connectorModal').
|
|
700
|
+
document.getElementById('connectorModal').classList.add('flm-dialog-overlay--open');
|
|
666
701
|
});
|
|
667
702
|
}
|
|
668
703
|
|
|
@@ -672,15 +707,15 @@ function setOAuthMode(mode) {
|
|
|
672
707
|
currentOAuthMode = mode;
|
|
673
708
|
document.getElementById('connectorManualGroup').style.display = mode === 'manual' ? '' : 'none';
|
|
674
709
|
document.getElementById('connectorAppGroup').style.display = mode === 'app' ? '' : 'none';
|
|
675
|
-
document.getElementById('oauthModeManual').className = '
|
|
676
|
-
document.getElementById('oauthModeApp').className = '
|
|
710
|
+
document.getElementById('oauthModeManual').className = 'flm-pivot-tab' + (mode === 'manual' ? ' flm-pivot-tab--active' : '');
|
|
711
|
+
document.getElementById('oauthModeApp').className = 'flm-pivot-tab' + (mode === 'app' ? ' flm-pivot-tab--active' : '');
|
|
677
712
|
}
|
|
678
713
|
|
|
679
714
|
document.getElementById('oauthModeManual').addEventListener('click', function() { setOAuthMode('manual'); });
|
|
680
715
|
document.getElementById('oauthModeApp').addEventListener('click', function() { setOAuthMode('app'); });
|
|
681
716
|
|
|
682
717
|
function closeConnectorModal() {
|
|
683
|
-
document.getElementById('connectorModal').
|
|
718
|
+
document.getElementById('connectorModal').classList.remove('flm-dialog-overlay--open');
|
|
684
719
|
currentConnectorId = null;
|
|
685
720
|
}
|
|
686
721
|
|
|
@@ -765,10 +800,10 @@ document.getElementById('connectorSearch').addEventListener('input', renderConne
|
|
|
765
800
|
// More dropdown toggle
|
|
766
801
|
document.getElementById('connMoreBtn').addEventListener('click', function(e) {
|
|
767
802
|
e.stopPropagation();
|
|
768
|
-
document.getElementById('connMoreMenu').classList.toggle('
|
|
803
|
+
document.getElementById('connMoreMenu').classList.toggle('flm-contextmenu--visible');
|
|
769
804
|
});
|
|
770
805
|
document.addEventListener('click', function() {
|
|
771
|
-
document.getElementById('connMoreMenu').classList.remove('
|
|
806
|
+
document.getElementById('connMoreMenu').classList.remove('flm-contextmenu--visible');
|
|
772
807
|
});
|
|
773
808
|
|
|
774
809
|
// Resize observer — recalculate visible categories when filter bar resizes
|
|
@@ -821,26 +856,29 @@ function renderAgentList() {
|
|
|
821
856
|
|
|
822
857
|
agentList.forEach(function(a) {
|
|
823
858
|
var row = document.createElement('div');
|
|
824
|
-
row.className = '
|
|
859
|
+
row.className = 'flm-list-item';
|
|
860
|
+
row.style.cssText = 'display:flex;align-items:center;gap:12px;padding:12px 16px;cursor:pointer;';
|
|
825
861
|
|
|
826
862
|
// Status dot (openclaw only)
|
|
827
863
|
if (a.provider === 'openclaw') {
|
|
828
864
|
var dot = document.createElement('div');
|
|
829
|
-
dot.
|
|
865
|
+
dot.style.cssText = 'width:8px;height:8px;border-radius:50%;flex-shrink:0;background:' + (a.connected ? 'var(--successText)' : 'var(--disabledText)');
|
|
830
866
|
dot.title = a.connected ? 'Connected' : 'Disconnected';
|
|
831
867
|
row.appendChild(dot);
|
|
832
868
|
}
|
|
833
869
|
|
|
834
870
|
// Info section
|
|
835
871
|
var info = document.createElement('div');
|
|
836
|
-
info.className = '
|
|
872
|
+
info.className = 'flm-list-item-content';
|
|
873
|
+
info.style.cssText = 'flex:1;min-width:0;display:flex;align-items:center;gap:10px;';
|
|
837
874
|
|
|
838
|
-
var nameEl = document.createElement('
|
|
839
|
-
nameEl.className = '
|
|
875
|
+
var nameEl = document.createElement('span');
|
|
876
|
+
nameEl.className = 'flm-list-item-primary flm-text--semibold flm-text--nowrap';
|
|
840
877
|
nameEl.textContent = a.name;
|
|
841
878
|
|
|
842
|
-
var descEl = document.createElement('
|
|
843
|
-
descEl.className = '
|
|
879
|
+
var descEl = document.createElement('span');
|
|
880
|
+
descEl.className = 'flm-list-item-secondary flm-text--nowrap';
|
|
881
|
+
descEl.style.cssText = 'flex:1;min-width:0;';
|
|
844
882
|
descEl.textContent = a.description || '';
|
|
845
883
|
|
|
846
884
|
info.appendChild(nameEl);
|
|
@@ -848,21 +886,21 @@ function renderAgentList() {
|
|
|
848
886
|
row.appendChild(info);
|
|
849
887
|
|
|
850
888
|
// Badge
|
|
851
|
-
var badge = document.createElement('
|
|
852
|
-
badge.className = '
|
|
889
|
+
var badge = document.createElement('span');
|
|
890
|
+
badge.className = 'flm-text flm-text--small flm-text--secondary';
|
|
891
|
+
badge.style.cssText = 'background:var(--defaultHoverBackground);padding:2px 8px;border-radius:10px;white-space:nowrap;flex-shrink:0;';
|
|
853
892
|
badge.textContent = a.provider === 'openclaw' ? 'OpenClaw' : 'A2A';
|
|
854
893
|
row.appendChild(badge);
|
|
855
894
|
|
|
856
895
|
// Actions
|
|
857
896
|
var actions = document.createElement('div');
|
|
858
|
-
actions.
|
|
897
|
+
actions.style.cssText = 'display:flex;align-items:center;gap:8px;flex-shrink:0;';
|
|
859
898
|
|
|
860
899
|
// Chat or Reconnect button (depending on connection state)
|
|
861
900
|
var isDisconnected = a.provider === 'openclaw' && a.enabled !== false && !a.connected;
|
|
862
901
|
var chatBtn = document.createElement('button');
|
|
863
|
-
chatBtn.className = '
|
|
864
|
-
chatBtn.style.
|
|
865
|
-
chatBtn.style.padding = '4px 10px';
|
|
902
|
+
chatBtn.className = 'flm-button flm-button--subtle';
|
|
903
|
+
chatBtn.style.cssText = 'font-size:12px;padding:4px 10px;';
|
|
866
904
|
if (isDisconnected) {
|
|
867
905
|
chatBtn.textContent = 'Reconnect';
|
|
868
906
|
chatBtn.addEventListener('click', (function(agent) {
|
|
@@ -886,10 +924,9 @@ function renderAgentList() {
|
|
|
886
924
|
|
|
887
925
|
// Edit button
|
|
888
926
|
var editBtn = document.createElement('button');
|
|
889
|
-
editBtn.className = '
|
|
927
|
+
editBtn.className = 'flm-button flm-button--subtle';
|
|
890
928
|
editBtn.textContent = 'Edit';
|
|
891
|
-
editBtn.style.
|
|
892
|
-
editBtn.style.padding = '4px 10px';
|
|
929
|
+
editBtn.style.cssText = 'font-size:12px;padding:4px 10px;';
|
|
893
930
|
editBtn.addEventListener('click', function(e) {
|
|
894
931
|
e.stopPropagation();
|
|
895
932
|
openAgentEditModal(a);
|
|
@@ -898,9 +935,10 @@ function renderAgentList() {
|
|
|
898
935
|
|
|
899
936
|
// Enable/disable toggle
|
|
900
937
|
var toggleLabel = document.createElement('label');
|
|
901
|
-
toggleLabel.className = 'toggle-
|
|
938
|
+
toggleLabel.className = 'flm-toggle flm-toggle--inline';
|
|
902
939
|
var toggleInput = document.createElement('input');
|
|
903
940
|
toggleInput.type = 'checkbox';
|
|
941
|
+
toggleInput.className = 'flm-toggle-input';
|
|
904
942
|
toggleInput.checked = a.enabled !== false;
|
|
905
943
|
toggleInput.addEventListener('click', function(e) { e.stopPropagation(); });
|
|
906
944
|
toggleInput.addEventListener('change', (function(agentId, inp) {
|
|
@@ -912,10 +950,13 @@ function renderAgentList() {
|
|
|
912
950
|
}).then(function() { loadAgents(); });
|
|
913
951
|
};
|
|
914
952
|
})(a.id, toggleInput));
|
|
915
|
-
var
|
|
916
|
-
|
|
953
|
+
var toggleTrack = document.createElement('span');
|
|
954
|
+
toggleTrack.className = 'flm-toggle-track';
|
|
955
|
+
var toggleThumb = document.createElement('span');
|
|
956
|
+
toggleThumb.className = 'flm-toggle-thumb';
|
|
957
|
+
toggleTrack.appendChild(toggleThumb);
|
|
917
958
|
toggleLabel.appendChild(toggleInput);
|
|
918
|
-
toggleLabel.appendChild(
|
|
959
|
+
toggleLabel.appendChild(toggleTrack);
|
|
919
960
|
actions.appendChild(toggleLabel);
|
|
920
961
|
|
|
921
962
|
row.appendChild(actions);
|
|
@@ -1049,8 +1090,8 @@ document.getElementById('agentChatInput').addEventListener('keydown', function(e
|
|
|
1049
1090
|
|
|
1050
1091
|
function setAgentType(type) {
|
|
1051
1092
|
currentAgentType = type;
|
|
1052
|
-
document.getElementById('agentTypeA2A').className = '
|
|
1053
|
-
document.getElementById('agentTypeOpenClaw').className = '
|
|
1093
|
+
document.getElementById('agentTypeA2A').className = 'flm-pivot-tab' + (type === 'a2a' ? ' flm-pivot-tab--active' : '');
|
|
1094
|
+
document.getElementById('agentTypeOpenClaw').className = 'flm-pivot-tab' + (type === 'openclaw' ? ' flm-pivot-tab--active' : '');
|
|
1054
1095
|
document.getElementById('agentTokenGroup').style.display = type === 'openclaw' ? '' : 'none';
|
|
1055
1096
|
document.getElementById('agentSessionKeyGroup').style.display = type === 'openclaw' ? '' : 'none';
|
|
1056
1097
|
document.getElementById('agentSshTunnelGroup').style.display = type === 'openclaw' ? '' : 'none';
|
|
@@ -1083,7 +1124,7 @@ function resetAgentModal() {
|
|
|
1083
1124
|
function openAgentAddModal() {
|
|
1084
1125
|
resetAgentModal();
|
|
1085
1126
|
document.getElementById('agentModalTitle').textContent = 'Add Agent';
|
|
1086
|
-
document.getElementById('agentModal').
|
|
1127
|
+
document.getElementById('agentModal').classList.add('flm-dialog-overlay--open');
|
|
1087
1128
|
}
|
|
1088
1129
|
|
|
1089
1130
|
function openAgentEditModal(agent) {
|
|
@@ -1110,11 +1151,11 @@ function openAgentEditModal(agent) {
|
|
|
1110
1151
|
}
|
|
1111
1152
|
}
|
|
1112
1153
|
document.getElementById('agentRemoveBtn').style.display = '';
|
|
1113
|
-
document.getElementById('agentModal').
|
|
1154
|
+
document.getElementById('agentModal').classList.add('flm-dialog-overlay--open');
|
|
1114
1155
|
}
|
|
1115
1156
|
|
|
1116
1157
|
function closeAgentModal() {
|
|
1117
|
-
document.getElementById('agentModal').
|
|
1158
|
+
document.getElementById('agentModal').classList.remove('flm-dialog-overlay--open');
|
|
1118
1159
|
resetAgentModal();
|
|
1119
1160
|
}
|
|
1120
1161
|
|
|
@@ -1130,7 +1171,7 @@ function renderSkillsList(skills) {
|
|
|
1130
1171
|
container.innerHTML = skills.map(function(s) {
|
|
1131
1172
|
var label = s.name || s.id || 'Skill';
|
|
1132
1173
|
var desc = s.description ? ' — ' + s.description : '';
|
|
1133
|
-
return '<span style="display:inline-block;padding:2px 8px;margin:2px;border-radius:8px;background:
|
|
1174
|
+
return '<span style="display:inline-block;padding:2px 8px;margin:2px;border-radius:8px;background:var(--defaultHoverBackground);font-size:11px;">' + label + desc + '</span>';
|
|
1134
1175
|
}).join('');
|
|
1135
1176
|
}
|
|
1136
1177
|
|
|
@@ -1310,6 +1351,7 @@ function saveAllSettings() {
|
|
|
1310
1351
|
var body = {
|
|
1311
1352
|
version: 2,
|
|
1312
1353
|
theme: document.getElementById('theme').value,
|
|
1354
|
+
toolbarPosition: document.getElementById('toolbarPosition').value,
|
|
1313
1355
|
models: models,
|
|
1314
1356
|
features: []
|
|
1315
1357
|
};
|
|
@@ -1320,6 +1362,7 @@ function saveAllSettings() {
|
|
|
1320
1362
|
body: JSON.stringify(body)
|
|
1321
1363
|
}).then(function(response) {
|
|
1322
1364
|
if (response.ok || response.redirected) {
|
|
1365
|
+
settingsDirty = false;
|
|
1323
1366
|
if (wizardActive) {
|
|
1324
1367
|
window.location.href = '/builder?firstRun=true';
|
|
1325
1368
|
} else {
|
|
@@ -1334,8 +1377,65 @@ function saveAllSettings() {
|
|
|
1334
1377
|
});
|
|
1335
1378
|
}
|
|
1336
1379
|
|
|
1337
|
-
|
|
1338
|
-
|
|
1380
|
+
var settingsDirty = false;
|
|
1381
|
+
var applyBtn = document.getElementById('applyBtn');
|
|
1382
|
+
|
|
1383
|
+
function markDirty() {
|
|
1384
|
+
settingsDirty = true;
|
|
1385
|
+
applyBtn.classList.add('flm-button--primary');
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
applyBtn.addEventListener('click', saveAllSettings);
|
|
1389
|
+
|
|
1390
|
+
// --- Unsaved-changes confirmation dialog ---
|
|
1391
|
+
var unsavedOverlay = document.getElementById('unsavedDialog');
|
|
1392
|
+
var pendingNavUrl = null;
|
|
1393
|
+
|
|
1394
|
+
function showUnsavedDialog(url) {
|
|
1395
|
+
pendingNavUrl = url;
|
|
1396
|
+
unsavedOverlay.classList.add('flm-dialog-overlay--open');
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
function hideUnsavedDialog() {
|
|
1400
|
+
unsavedOverlay.classList.remove('flm-dialog-overlay--open');
|
|
1401
|
+
pendingNavUrl = null;
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
document.getElementById('unsavedStayBtn').addEventListener('click', hideUnsavedDialog);
|
|
1405
|
+
document.getElementById('unsavedLeaveBtn').addEventListener('click', function() {
|
|
1406
|
+
var url = pendingNavUrl; // capture before hideUnsavedDialog nulls it
|
|
1407
|
+
settingsDirty = false; // disarm beforeunload
|
|
1408
|
+
hideUnsavedDialog();
|
|
1409
|
+
if (url) window.location.href = url;
|
|
1410
|
+
});
|
|
1411
|
+
|
|
1412
|
+
// Light-dismiss (click overlay backdrop)
|
|
1413
|
+
var unsavedMouseDownTarget = null;
|
|
1414
|
+
unsavedOverlay.addEventListener('mousedown', function(e) { unsavedMouseDownTarget = e.target; });
|
|
1415
|
+
unsavedOverlay.addEventListener('click', function(e) {
|
|
1416
|
+
if (e.target === this && unsavedMouseDownTarget === this) hideUnsavedDialog();
|
|
1417
|
+
unsavedMouseDownTarget = null;
|
|
1418
|
+
});
|
|
1419
|
+
|
|
1420
|
+
// Guard in-page navigation links
|
|
1421
|
+
function guardNavigation(el, url) {
|
|
1422
|
+
el.addEventListener('click', function(e) {
|
|
1423
|
+
if (!settingsDirty) return; // clean — let default behavior through
|
|
1424
|
+
e.preventDefault();
|
|
1425
|
+
e.stopImmediatePropagation(); // block page-script handlers from navigating
|
|
1426
|
+
showUnsavedDialog(url);
|
|
1427
|
+
}, true); // capture phase — run before other handlers
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
guardNavigation(document.getElementById('pagesLink'), '/pages');
|
|
1431
|
+
guardNavigation(document.getElementById('pagesBtn'), '/pages');
|
|
1432
|
+
|
|
1433
|
+
// Fallback for browser close / address-bar navigation only.
|
|
1434
|
+
// Skip when the FluentLM dialog is already handling the confirmation.
|
|
1435
|
+
window.addEventListener('beforeunload', function(e) {
|
|
1436
|
+
if (settingsDirty && !unsavedOverlay.classList.contains('flm-dialog-overlay--open')) {
|
|
1437
|
+
e.preventDefault();
|
|
1438
|
+
}
|
|
1339
1439
|
});
|
|
1340
1440
|
|
|
1341
1441
|
// --- Provider helpers ---
|
|
@@ -1450,9 +1550,9 @@ function updateWizardVisibility() {
|
|
|
1450
1550
|
}
|
|
1451
1551
|
|
|
1452
1552
|
function updateApplyButton() {
|
|
1453
|
-
var
|
|
1553
|
+
var btn = document.getElementById('applyBtn');
|
|
1454
1554
|
if (!wizardActive) {
|
|
1455
|
-
|
|
1555
|
+
btn.disabled = false;
|
|
1456
1556
|
return;
|
|
1457
1557
|
}
|
|
1458
1558
|
var hasProvider = !!document.getElementById('provider-builder').value;
|
|
@@ -1460,7 +1560,8 @@ function updateApplyButton() {
|
|
|
1460
1560
|
var hasModel = !!document.getElementById('model-builder').value;
|
|
1461
1561
|
var hasTokens = !!document.getElementById('maxTokens-builder').value;
|
|
1462
1562
|
var ready = hasProvider && hasKey && hasModel && hasTokens;
|
|
1463
|
-
|
|
1563
|
+
btn.disabled = !ready;
|
|
1564
|
+
if (ready) btn.classList.add('flm-button--primary');
|
|
1464
1565
|
}
|
|
1465
1566
|
|
|
1466
1567
|
function autoPopulateChatCard() {
|
|
@@ -1555,10 +1656,23 @@ Promise.all([
|
|
|
1555
1656
|
return '<option value="' + t + '">' + t + '</option>';
|
|
1556
1657
|
}).join('');
|
|
1557
1658
|
document.getElementById('theme').value = currentTheme;
|
|
1659
|
+
document.getElementById('toolbarPosition').value = data.toolbarPosition || 'left';
|
|
1558
1660
|
|
|
1559
1661
|
loadConnectors();
|
|
1560
1662
|
loadAgents();
|
|
1561
1663
|
|
|
1664
|
+
// Attach dirty-tracking listeners to all settings controls
|
|
1665
|
+
['theme', 'toolbarPosition', 'provider-builder', 'serviceApiKey-builder', 'model-builder',
|
|
1666
|
+
'maxTokens-builder', 'instructions-builder', 'provider-chat',
|
|
1667
|
+
'serviceApiKey-chat', 'model-chat', 'maxTokens-chat', 'instructions-chat'
|
|
1668
|
+
].forEach(function(id) {
|
|
1669
|
+
var el = document.getElementById(id);
|
|
1670
|
+
if (el) {
|
|
1671
|
+
el.addEventListener('input', markDirty);
|
|
1672
|
+
el.addEventListener('change', markDirty);
|
|
1673
|
+
}
|
|
1674
|
+
});
|
|
1675
|
+
|
|
1562
1676
|
var isFirstRun = params.get('firstRun') === '1';
|
|
1563
1677
|
|
|
1564
1678
|
if (!isConfigured) {
|
|
@@ -1599,7 +1713,7 @@ Promise.all([
|
|
|
1599
1713
|
openSection('models');
|
|
1600
1714
|
|
|
1601
1715
|
// Disable other accordion tabs
|
|
1602
|
-
document.querySelector('.accordion-section[data-section="
|
|
1716
|
+
document.querySelector('.accordion-section[data-section="appearance"]').classList.add('disabled');
|
|
1603
1717
|
document.querySelector('.accordion-section[data-section="connectors"]').classList.add('disabled');
|
|
1604
1718
|
document.querySelector('.accordion-section[data-section="agents"]').classList.add('disabled');
|
|
1605
1719
|
|
|
@@ -1625,8 +1739,8 @@ Promise.all([
|
|
|
1625
1739
|
builderProviderSelect.insertBefore(placeholder, builderProviderSelect.firstChild);
|
|
1626
1740
|
builderProviderSelect.value = '';
|
|
1627
1741
|
|
|
1628
|
-
// Disable Apply
|
|
1629
|
-
document.
|
|
1742
|
+
// Disable Apply button until configured
|
|
1743
|
+
document.getElementById('applyBtn').disabled = true;
|
|
1630
1744
|
|
|
1631
1745
|
updateWizardVisibility();
|
|
1632
1746
|
}
|
|
@@ -1634,6 +1748,6 @@ Promise.all([
|
|
|
1634
1748
|
console.error('Error fetching settings:', error);
|
|
1635
1749
|
});
|
|
1636
1750
|
</script>
|
|
1637
|
-
<script id="page-helpers" src="/api/page-helpers.js?v=
|
|
1638
|
-
<script id="page-script" src="/api/page-script.js?v=
|
|
1751
|
+
<script id="page-helpers" src="/api/page-helpers.js?v=3" data-locked="true"></script>
|
|
1752
|
+
<script id="page-script" src="/api/page-script.js?v=3" data-locked="true"></script>
|
|
1639
1753
|
</body></html>
|