machinaos 0.0.76 → 0.0.78
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 +143 -107
- package/client/dist/assets/ActionBar-Du2MSFSz.js +1 -0
- package/client/dist/assets/ApiKeyInput-k2LBmBjb.js +1 -0
- package/client/dist/assets/ApiKeyPanel-C_bV9U0X.js +1 -0
- package/client/dist/assets/ApiUsageSection-CmVfwZzL.js +1 -0
- package/client/dist/assets/EmailPanel-CeKIMGu-.js +1 -0
- package/client/dist/assets/OAuthPanel-KA3t3Q2K.js +1 -0
- package/client/dist/assets/QrPairingPanel-NgNpJNuk.js +1 -0
- package/client/dist/assets/RateLimitSection-Du5YNVIA.js +1 -0
- package/client/dist/assets/StatusCard-DNLyayXc.js +1 -0
- package/client/dist/assets/index-DQ0nwhec.js +257 -0
- package/client/dist/assets/index-DxmbVskS.css +1 -0
- package/client/dist/assets/vendor-flow-CZmBvHRo.js +1 -0
- package/client/dist/assets/vendor-icons-CVrPjN2Q.js +22 -0
- package/client/dist/assets/vendor-markdown-CRou3yQ5.js +62 -0
- package/client/dist/assets/vendor-misc-C4VxKHs5.js +1 -0
- package/client/dist/assets/vendor-query-SzWcOU0G.js +1 -0
- package/client/dist/assets/vendor-radix-Dnos29jG.js +56 -0
- package/client/dist/assets/vendor-react-DvWIbVx0.js +1 -0
- package/client/dist/index.html +37 -3
- package/client/index.html +28 -1
- package/client/package.json +44 -40
- package/client/src/App.tsx +2 -0
- package/client/src/Dashboard.tsx +157 -45
- package/client/src/ParameterPanel.tsx +3 -5
- package/client/src/adapters/nodeSpecToDescription.ts +1 -0
- package/client/src/assets/icons/NodeIcon.tsx +32 -0
- package/client/src/assets/icons/index.ts +4 -0
- package/client/src/assets/icons/stripe.svg +1 -0
- package/client/src/assets/icons/themedGlyphs.ts +404 -0
- package/client/src/components/AIAgentNode.tsx +77 -53
- package/client/src/components/GenericNode.tsx +34 -52
- package/client/src/components/OutputPanel.tsx +64 -147
- package/client/src/components/ParameterRenderer.tsx +5 -3
- package/client/src/components/SkillEditorModal.tsx +9 -18
- package/client/src/components/SquareNode.tsx +97 -115
- package/client/src/components/StartNode.tsx +32 -42
- package/client/src/components/SvgFilterDefs.tsx +54 -0
- package/client/src/components/TeamMonitorNode.tsx +12 -14
- package/client/src/components/ToolkitNode.tsx +35 -60
- package/client/src/components/TriggerNode.tsx +43 -77
- package/client/src/components/__tests__/CredentialsModal.test.tsx +49 -45
- package/client/src/components/credentials/CredentialsModal.tsx +98 -30
- package/client/src/components/credentials/CredentialsPalette.tsx +73 -5
- package/client/src/components/credentials/catalogueAdapter.ts +17 -1
- package/client/src/components/credentials/panels/ApiKeyPanel.tsx +102 -37
- package/client/src/components/credentials/panels/EmailPanel.tsx +7 -19
- package/client/src/components/credentials/panels/OAuthPanel.tsx +5 -1
- package/client/src/components/credentials/panels/QrPairingPanel.tsx +1 -3
- package/client/src/components/credentials/primitives/ActionBar.tsx +7 -11
- package/client/src/components/credentials/primitives/OAuthConnect.tsx +19 -28
- package/client/src/components/credentials/sections/ProviderDefaultsSection.tsx +24 -3
- package/client/src/components/credentials/types.ts +12 -2
- package/client/src/components/credentials/useCredentialPanel.ts +43 -19
- package/client/src/components/icons/AIProviderIcons.tsx +16 -0
- package/client/src/components/onboarding/OnboardingWizard.tsx +23 -63
- package/client/src/components/onboarding/nodeRoleClasses.ts +23 -0
- package/client/src/components/onboarding/steps/CanvasStep.tsx +15 -21
- package/client/src/components/onboarding/steps/ConceptsStep.tsx +2 -11
- package/client/src/components/onboarding/steps/GetStartedStep.tsx +2 -10
- package/client/src/components/parameterPanel/InputSection.tsx +9 -7
- package/client/src/components/parameterPanel/MasterSkillEditor.tsx +84 -198
- package/client/src/components/parameterPanel/MiddleSection.tsx +57 -80
- package/client/src/components/parameterPanel/ToolSchemaEditor.tsx +31 -25
- package/client/src/components/parameterPanel/__tests__/InputSection.test.tsx +7 -2
- package/client/src/components/ui/AIResultModal.tsx +1 -1
- package/client/src/components/ui/CollapsibleSection.tsx +9 -5
- package/client/src/components/ui/CommandPalette.tsx +147 -0
- package/client/src/components/ui/CommandPaletteHost.tsx +189 -0
- package/client/src/components/ui/ComponentItem.tsx +13 -7
- package/client/src/components/ui/ComponentPalette.tsx +24 -13
- package/client/src/components/ui/ConsolePanel.tsx +19 -11
- package/client/src/components/ui/DropCap.tsx +28 -0
- package/client/src/components/ui/EditableNodeLabel.tsx +10 -2
- package/client/src/components/ui/InputNodesPanel.tsx +1 -1
- package/client/src/components/ui/Modal.tsx +38 -6
- package/client/src/components/ui/OutputDisplayPanel.tsx +1 -1
- package/client/src/components/ui/SettingsPanel.tsx +42 -13
- package/client/src/components/ui/StatusBar.tsx +108 -0
- package/client/src/components/ui/ThemeSwitcher.tsx +109 -0
- package/client/src/components/ui/TopToolbar.tsx +42 -25
- package/client/src/components/ui/WorkflowSidebar.tsx +32 -16
- package/client/src/components/ui/action-button.tsx +40 -15
- package/client/src/components/ui/button.tsx +24 -1
- package/client/src/components/ui/dropdown-menu.tsx +24 -2
- package/client/src/components/ui/input.tsx +19 -2
- package/client/src/components/ui/select.tsx +15 -0
- package/client/src/components/ui/textarea.tsx +15 -2
- package/client/src/contexts/AuthContext.tsx +148 -109
- package/client/src/contexts/ThemeContext.tsx +93 -17
- package/client/src/contexts/WebSocketContext.tsx +373 -206
- package/client/src/contexts/__tests__/AuthContext.test.tsx +221 -0
- package/client/src/hooks/__tests__/useDragVariable.test.ts +7 -1
- package/client/src/hooks/__tests__/useWorkflowOpsListener.test.ts +142 -0
- package/client/src/hooks/useAppTheme.ts +209 -7
- package/client/src/hooks/useAutoSkillEdges.ts +7 -2
- package/client/src/hooks/useCatalogueQuery.ts +67 -1
- package/client/src/hooks/useDragVariable.ts +1 -1
- package/client/src/hooks/useNodeAllowlist.ts +115 -8
- package/client/src/hooks/useOnboarding.ts +20 -8
- package/client/src/hooks/useParameterPanel.ts +2 -1
- package/client/src/hooks/useReactFlowNodes.ts +2 -1
- package/client/src/hooks/useSound.ts +185 -0
- package/client/src/hooks/useWorkflowManagement.ts +6 -8
- package/client/src/hooks/useWorkflowOpsListener.ts +90 -0
- package/client/src/index.css +65 -3
- package/client/src/lib/__tests__/connectionConfig.test.ts +91 -0
- package/client/src/lib/aiModelProviders.ts +8 -0
- package/client/src/lib/connectionConfig.ts +107 -0
- package/client/src/lib/queryPersist.ts +13 -5
- package/client/src/lib/sound.ts +393 -0
- package/client/src/main.tsx +20 -0
- package/client/src/store/useAppStore.ts +26 -0
- package/client/src/styles/canvasAnimations.ts +37 -36
- package/client/src/styles/theme.ts +36 -20
- package/client/src/test/setup.ts +1 -0
- package/client/src/themes/atomic.css +253 -0
- package/client/src/themes/base.css +373 -0
- package/client/src/themes/cyber.css +890 -0
- package/client/src/themes/dark.css +70 -0
- package/client/src/themes/edo.css +246 -0
- package/client/src/themes/greek.css +293 -0
- package/client/src/themes/light.css +78 -0
- package/client/src/themes/plague.css +253 -0
- package/client/src/themes/renaissance.css +727 -0
- package/client/src/themes/rot.css +249 -0
- package/client/src/themes/steampunk.css +272 -0
- package/client/src/themes/surveillance.css +289 -0
- package/client/src/themes/wasteland.css +250 -0
- package/client/src/types/INodeProperties.ts +5 -0
- package/client/src/types/NodeTypes.ts +11 -1
- package/client/src/types/__tests__/cloudEvents.test.ts +99 -0
- package/client/src/types/cloudEvents.ts +78 -0
- package/client/src/vite-env.d.ts +7 -0
- package/client/tsconfig.json +1 -1
- package/client/vite.config.js +62 -2
- package/install.ps1 +1 -1
- package/install.sh +1 -1
- package/machina/commands/build.py +51 -7
- package/machina/pyproject.toml +4 -0
- package/machina/supervisor.py +12 -2
- package/machina/tree.py +71 -21
- package/package.json +4 -4
- package/scripts/install.js +16 -1
- package/server/config/ai_cli_providers.json +54 -0
- package/server/config/credential_providers.json +109 -2
- package/server/config/llm_defaults.json +24 -0
- package/server/config/model_registry.json +338 -499
- package/server/config/node_allowlist.json +16 -1
- package/server/config/pricing.json +8 -0
- package/server/constants.py +38 -15
- package/server/core/container.py +2 -2
- package/server/core/credentials_database.py +35 -2
- package/server/core/logging.py +4 -3
- package/server/main.py +99 -13
- package/server/models/node_metadata.py +1 -0
- package/server/nodejs/package.json +8 -6
- package/server/nodejs/src/index.ts +22 -5
- package/server/nodes/README.md +31 -4
- package/server/nodes/agent/_inline.py +2 -0
- package/server/nodes/agent/_specialized.py +6 -3
- package/server/nodes/agent/ai_agent.py +13 -3
- package/server/nodes/agent/chat_agent.py +6 -3
- package/server/nodes/agent/claude_code_agent.py +287 -75
- package/server/nodes/agent/codex_agent.py +239 -0
- package/server/nodes/agent/deep_agent.py +3 -3
- package/server/nodes/agent/rlm_agent.py +3 -3
- package/server/nodes/android/__init__.py +31 -1
- package/server/nodes/android/_base.py +9 -5
- package/server/{services/android_service.py → nodes/android/_dispatcher.py} +2 -2
- package/server/nodes/android/_handlers.py +154 -0
- package/server/nodes/android/_option_loaders.py +44 -0
- package/server/nodes/android/_refresh.py +127 -0
- package/server/{services/android → nodes/android/_relay}/client.py +4 -4
- package/server/{routers/android.py → nodes/android/_router.py} +27 -8
- package/server/nodes/browser/browser.py +2 -2
- package/server/nodes/code/_base.py +6 -2
- package/server/nodes/code/_claude_code.py +134 -0
- package/server/nodes/document/embedding_generator.py +3 -3
- package/server/nodes/document/http_scraper.py +3 -3
- package/server/nodes/document/vector_store.py +5 -5
- package/server/nodes/email/__init__.py +11 -1
- package/server/nodes/email/_filters.py +21 -0
- package/server/{services/himalaya_service.py → nodes/email/_himalaya.py} +6 -10
- package/server/{services/email_service.py → nodes/email/_service.py} +9 -13
- package/server/nodes/email/email_read.py +1 -1
- package/server/nodes/email/email_receive.py +54 -5
- package/server/nodes/email/email_send.py +1 -1
- package/server/nodes/filesystem/shell.py +24 -1
- package/server/nodes/google/__init__.py +55 -1
- package/server/{services/handlers/google_auth.py → nodes/google/_auth_helper.py} +8 -5
- package/server/nodes/google/_base.py +2 -2
- package/server/nodes/google/_credentials.py +5 -5
- package/server/nodes/google/_filters.py +25 -0
- package/server/nodes/google/_handlers.py +57 -0
- package/server/{services/google_oauth.py → nodes/google/_oauth.py} +195 -162
- package/server/nodes/google/_option_loaders.py +107 -0
- package/server/nodes/google/_refresh.py +66 -0
- package/server/nodes/google/_router.py +131 -0
- package/server/nodes/google/gmail_receive.py +41 -4
- package/server/nodes/groups.py +1 -0
- package/server/nodes/location/_credentials.py +45 -1
- package/server/{services/maps.py → nodes/location/_service.py} +18 -3
- package/server/nodes/location/gmaps_create.py +4 -4
- package/server/nodes/location/gmaps_locations.py +4 -4
- package/server/nodes/location/gmaps_nearby_places.py +4 -4
- package/server/nodes/model/_base.py +8 -3
- package/server/nodes/model/_credentials.py +96 -8
- package/server/nodes/model/_local_validator.py +345 -0
- package/server/nodes/model/lmstudio_chat_model.py +23 -0
- package/server/nodes/model/ollama_chat_model.py +25 -0
- package/server/nodes/proxy/_usage.py +2 -2
- package/server/nodes/proxy/proxy_config.py +14 -14
- package/server/nodes/proxy/proxy_request.py +4 -4
- package/server/nodes/scraper/_credentials.py +29 -1
- package/server/nodes/scraper/apify_actor.py +9 -9
- package/server/nodes/scraper/crawlee_scraper.py +5 -5
- package/server/nodes/search/brave_search.py +4 -0
- package/server/nodes/search/perplexity_search.py +9 -0
- package/server/nodes/search/serper_search.py +3 -0
- package/server/nodes/skill/simple_memory.py +12 -0
- package/server/nodes/social/_base.py +2 -2
- package/server/nodes/stripe/__init__.py +46 -0
- package/server/nodes/stripe/_credentials.py +33 -0
- package/server/nodes/stripe/_handlers.py +270 -0
- package/server/nodes/stripe/_install.py +127 -0
- package/server/nodes/stripe/_source.py +174 -0
- package/server/nodes/stripe/stripe_action.py +81 -0
- package/server/nodes/stripe/stripe_receive.py +92 -0
- package/server/nodes/telegram/_credentials.py +52 -1
- package/server/nodes/telegram/_handlers.py +19 -18
- package/server/nodes/telegram/_service.py +134 -32
- package/server/nodes/telegram/telegram_send.py +5 -6
- package/server/nodes/text/file_handler.py +2 -2
- package/server/nodes/text/text_generator.py +2 -2
- package/server/nodes/tool/agent_builder.py +630 -0
- package/server/nodes/tool/task_manager.py +144 -2
- package/server/nodes/twitter/__init__.py +38 -1
- package/server/nodes/twitter/_base.py +7 -7
- package/server/nodes/twitter/_credentials.py +1 -1
- package/server/nodes/twitter/_filters.py +37 -0
- package/server/nodes/twitter/_handlers.py +77 -0
- package/server/nodes/twitter/_oauth.py +124 -0
- package/server/nodes/twitter/_refresh.py +78 -0
- package/server/nodes/twitter/_router.py +29 -0
- package/server/nodes/twitter/twitter_receive.py +4 -0
- package/server/nodes/visuals.json +64 -19
- package/server/nodes/whatsapp/__init__.py +45 -5
- package/server/nodes/whatsapp/_base.py +3 -3
- package/server/nodes/whatsapp/_filters.py +137 -0
- package/server/nodes/whatsapp/_handlers.py +167 -0
- package/server/nodes/whatsapp/_option_loaders.py +68 -0
- package/server/nodes/whatsapp/_refresh.py +62 -0
- package/server/nodes/whatsapp/_runtime.py +1 -1
- package/server/pyproject.toml +29 -7
- package/server/routers/schemas.py +2 -2
- package/server/routers/webhook.py +26 -9
- package/server/routers/websocket.py +149 -810
- package/server/services/ai.py +89 -8
- package/server/services/auth.py +220 -43
- package/server/services/claude_oauth.py +126 -100
- package/server/services/cli_agent/__init__.py +78 -0
- package/server/services/cli_agent/_handlers.py +237 -0
- package/server/services/cli_agent/config.py +112 -0
- package/server/services/cli_agent/factory.py +48 -0
- package/server/services/cli_agent/lockfile.py +141 -0
- package/server/services/cli_agent/mcp_server.py +482 -0
- package/server/services/cli_agent/protocol.py +173 -0
- package/server/services/cli_agent/providers/__init__.py +9 -0
- package/server/services/cli_agent/providers/anthropic_claude.py +419 -0
- package/server/services/cli_agent/providers/google_gemini.py +80 -0
- package/server/services/cli_agent/providers/openai_codex.py +310 -0
- package/server/services/cli_agent/service.py +607 -0
- package/server/services/cli_agent/session.py +618 -0
- package/server/services/cli_agent/types.py +227 -0
- package/server/services/cli_agent/workflow_tools.py +233 -0
- package/server/services/credential_registry.py +26 -1
- package/server/services/deployment/manager.py +26 -145
- package/server/services/deployment/poll_registry.py +59 -0
- package/server/services/event_waiter.py +76 -246
- package/server/services/events/__init__.py +54 -0
- package/server/services/events/cli.py +78 -0
- package/server/services/events/daemon.py +163 -0
- package/server/services/events/envelope.py +281 -0
- package/server/services/events/lifecycle.py +99 -0
- package/server/services/events/oauth_lifecycle.py +534 -0
- package/server/services/events/polling.py +60 -0
- package/server/services/events/push.py +36 -0
- package/server/services/events/source.py +63 -0
- package/server/services/events/triggers.py +118 -0
- package/server/services/events/verifiers/__init__.py +25 -0
- package/server/services/events/verifiers/base.py +28 -0
- package/server/services/events/verifiers/github.py +25 -0
- package/server/services/events/verifiers/hmac_basic.py +32 -0
- package/server/services/events/verifiers/standard_webhooks.py +47 -0
- package/server/services/events/verifiers/stripe.py +42 -0
- package/server/services/events/webhook.py +105 -0
- package/server/services/handlers/tools.py +28 -186
- package/server/services/llm/config.py +7 -0
- package/server/services/llm/factory.py +8 -2
- package/server/services/memory/__init__.py +52 -0
- package/server/services/memory/jsonl.py +80 -0
- package/server/services/memory/markdown.py +65 -0
- package/server/services/memory/state.py +112 -0
- package/server/services/memory/vector_store.py +40 -0
- package/server/services/model_registry.py +76 -0
- package/server/services/node_allowlist.py +71 -15
- package/server/services/node_executor.py +2 -2
- package/server/services/node_output_schemas.py +21 -10
- package/server/services/node_spec.py +1 -1
- package/server/services/oauth_utils.py +1 -1
- package/server/services/plugin/__init__.py +2 -0
- package/server/services/plugin/base.py +44 -2
- package/server/services/plugin/credential.py +288 -1
- package/server/services/plugin/deps.py +105 -0
- package/server/services/plugin/edge_walker.py +12 -4
- package/server/services/plugin/oauth.py +381 -0
- package/server/services/plugin/polling.py +247 -0
- package/server/services/plugin/registry.py +145 -0
- package/server/services/plugin/singleton.py +65 -0
- package/server/services/plugin/ws.py +81 -0
- package/server/services/process_service.py +31 -2
- package/server/services/status_broadcaster.py +155 -238
- package/server/services/temporal/workflow.py +7 -7
- package/server/services/workflow.py +21 -3
- package/server/services/ws_handler_registry.py +111 -28
- package/server/skills/GUIDE.md +16 -1
- package/server/skills/assistant/agent-builder-skill/SKILL.md +166 -0
- package/server/skills/payments_agent/stripe-skill/SKILL.md +306 -0
- package/server/tests/credentials/test_auth_service.py +16 -9
- package/server/tests/credentials/test_credential_broadcasts.py +219 -0
- package/server/tests/credentials/test_google_oauth.py +6 -6
- package/server/tests/credentials/test_oauth_utils.py +1 -1
- package/server/tests/credentials/test_twitter_oauth.py +2 -2
- package/server/tests/credentials/test_websocket_handlers.py +44 -20
- package/server/tests/llm/test_factory.py +1 -0
- package/server/tests/llm/test_wiring.py +5 -1
- package/server/tests/nodes/_compat.py +24 -24
- package/server/tests/nodes/test_agent_builder.py +439 -0
- package/server/tests/nodes/test_ai_tools.py +18 -14
- package/server/tests/nodes/test_code_fs_process.py +17 -8
- package/server/tests/nodes/test_email.py +10 -9
- package/server/tests/nodes/test_google_workspace.py +2 -2
- package/server/tests/nodes/test_specialized_agents.py +100 -53
- package/server/tests/nodes/test_stripe_plugin.py +293 -0
- package/server/tests/nodes/test_telegram_social.py +4 -4
- package/server/tests/nodes/test_twitter.py +1 -1
- package/server/tests/nodes/test_web_automation.py +2 -2
- package/server/tests/nodes/test_whatsapp.py +9 -9
- package/server/tests/services/cli_agent/__init__.py +0 -0
- package/server/tests/services/cli_agent/test_mcp_server.py +432 -0
- package/server/tests/services/cli_agent/test_providers.py +358 -0
- package/server/tests/services/cli_agent/test_service.py +298 -0
- package/server/tests/services/memory/__init__.py +0 -0
- package/server/tests/services/memory/test_jsonl.py +188 -0
- package/server/tests/services/test_events.py +333 -0
- package/server/tests/test_node_spec.py +56 -16
- package/server/tests/test_plugin_helpers.py +116 -0
- package/server/tests/test_plugin_self_containment.py +486 -0
- package/server/tests/test_status_broadcasts.py +425 -0
- package/workflows/{AI Assistant_workflow-1777421105154-0m4snkzjf.json → AI Assistant_workflow-1778504793388-ou1m1tz2x.json } +70 -266
- package/workflows/{AI Employee_workflow-1777720598005-u4cm858dv.json → AI Employee_example_workflow-1777720598005-u4cm858dv.json } +112 -112
- package/workflows/Claude Assistant_workflow-1778380124051-mdibn807c.json +709 -0
- package/client/dist/assets/ActionBar-vzPpSR77.js +0 -1
- package/client/dist/assets/ApiKeyInput-Ds7AKFe8.js +0 -1
- package/client/dist/assets/ApiKeyPanel-gfblELep.js +0 -1
- package/client/dist/assets/ApiUsageSection-BMNWTe2r.js +0 -1
- package/client/dist/assets/EmailPanel-B1Om64p5.js +0 -1
- package/client/dist/assets/OAuthPanel-CXyQYGBz.js +0 -1
- package/client/dist/assets/QrPairingPanel-BgNuI1we.js +0 -1
- package/client/dist/assets/RateLimitSection-YYK8sx1T.js +0 -1
- package/client/dist/assets/StatusCard-DuYA5hJR.js +0 -1
- package/client/dist/assets/index-D9tZfgvi.js +0 -363
- package/client/dist/assets/index-al7snTkG.css +0 -1
- package/client/src/components/credentials/providers.tsx +0 -177
- package/server/routers/google.py +0 -277
- package/server/routers/maps.py +0 -142
- package/server/routers/twitter.py +0 -365
- package/server/services/claude_code_service.py +0 -106
- package/server/services/memory.py +0 -159
- package/server/services/node_option_loaders/__init__.py +0 -77
- package/server/services/node_option_loaders/android_loaders.py +0 -55
- package/server/services/node_option_loaders/google_loaders.py +0 -97
- package/server/services/node_option_loaders/whatsapp_loaders.py +0 -69
- package/server/services/twitter_oauth.py +0 -411
- package/server/services/websocket_client.py +0 -29
- /package/server/{services/android → nodes/android/_relay}/__init__.py +0 -0
- /package/server/{services/android → nodes/android/_relay}/broadcaster.py +0 -0
- /package/server/{services/android → nodes/android/_relay}/manager.py +0 -0
- /package/server/{services/android → nodes/android/_relay}/protocol.py +0 -0
- /package/server/{services/browser_service.py → nodes/browser/_service.py} +0 -0
- /package/server/{services/whatsapp_service.py → nodes/whatsapp/_service.py} +0 -0
- /package/server/skills/{task_agent → assistant}/write-todos-skill/SKILL.md +0 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CommandPaletteHost — Dashboard-level command list registration.
|
|
3
|
+
*
|
|
4
|
+
* Owns the canonical command set that the global ⌘K palette surfaces.
|
|
5
|
+
* Receives every action as a handler prop (Dashboard already has them
|
|
6
|
+
* in scope) plus the active theme controls; assembles a `CommandItem[]`
|
|
7
|
+
* with stable IDs, hints, and keyboard shortcuts and renders the
|
|
8
|
+
* underlying CommandPalette.
|
|
9
|
+
*
|
|
10
|
+
* New shell action: add a handler to `Handlers`, wire it through from
|
|
11
|
+
* Dashboard, append a `CommandItem` to `commands` below. No edits to
|
|
12
|
+
* the CommandPalette primitive itself.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import * as React from 'react';
|
|
16
|
+
import {
|
|
17
|
+
Settings as SettingsIcon,
|
|
18
|
+
KeyRound,
|
|
19
|
+
Save,
|
|
20
|
+
Play,
|
|
21
|
+
Square,
|
|
22
|
+
FilePlus,
|
|
23
|
+
FolderOpen,
|
|
24
|
+
PanelLeftClose,
|
|
25
|
+
PanelRightClose,
|
|
26
|
+
Terminal,
|
|
27
|
+
Palette as PaletteIcon,
|
|
28
|
+
Download,
|
|
29
|
+
Upload,
|
|
30
|
+
} from 'lucide-react';
|
|
31
|
+
import { CommandPalette, type CommandItem } from './CommandPalette';
|
|
32
|
+
import { AVAILABLE_THEMES, useTheme, type ThemeName } from '../../contexts/ThemeContext';
|
|
33
|
+
|
|
34
|
+
interface Handlers {
|
|
35
|
+
save: () => void;
|
|
36
|
+
newWorkflow: () => void;
|
|
37
|
+
open: () => void;
|
|
38
|
+
run: () => void;
|
|
39
|
+
stop: () => void;
|
|
40
|
+
isDeploying: boolean;
|
|
41
|
+
exportFile: () => void;
|
|
42
|
+
importJSON: () => void;
|
|
43
|
+
openSettings: () => void;
|
|
44
|
+
openCredentials: () => void;
|
|
45
|
+
toggleSidebar: () => void;
|
|
46
|
+
toggleComponentPalette: () => void;
|
|
47
|
+
toggleConsolePanel: () => void;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const THEME_LABEL: Record<ThemeName, string> = {
|
|
51
|
+
light: 'Light',
|
|
52
|
+
dark: 'Dark',
|
|
53
|
+
renaissance: 'Renaissance',
|
|
54
|
+
greek: 'Greek',
|
|
55
|
+
edo: 'Edo',
|
|
56
|
+
steampunk: 'Steampunk',
|
|
57
|
+
atomic: 'Atomic Modern',
|
|
58
|
+
cyber: 'Cyber-Tyranny',
|
|
59
|
+
wasteland: 'Wasteland',
|
|
60
|
+
rot: 'Necromantic Rot',
|
|
61
|
+
plague: 'Plague City',
|
|
62
|
+
surveillance: 'Surveillance',
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
interface Props {
|
|
66
|
+
open: boolean;
|
|
67
|
+
onOpenChange: (open: boolean) => void;
|
|
68
|
+
handlers: Handlers;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const CommandPaletteHost: React.FC<Props> = ({ open, onOpenChange, handlers }) => {
|
|
72
|
+
const { theme, setTheme } = useTheme();
|
|
73
|
+
|
|
74
|
+
const commands: CommandItem[] = React.useMemo(() => {
|
|
75
|
+
const list: CommandItem[] = [
|
|
76
|
+
// ── Workflow ───────────────────────────────────────────────────
|
|
77
|
+
{
|
|
78
|
+
id: 'workflow.new',
|
|
79
|
+
label: 'New Workflow',
|
|
80
|
+
group: 'Workflow',
|
|
81
|
+
icon: FilePlus,
|
|
82
|
+
onRun: handlers.newWorkflow,
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: 'workflow.open',
|
|
86
|
+
label: 'Open Workflow',
|
|
87
|
+
group: 'Workflow',
|
|
88
|
+
icon: FolderOpen,
|
|
89
|
+
onRun: handlers.open,
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: 'workflow.save',
|
|
93
|
+
label: 'Save Workflow',
|
|
94
|
+
group: 'Workflow',
|
|
95
|
+
icon: Save,
|
|
96
|
+
shortcut: '⌘S',
|
|
97
|
+
onRun: handlers.save,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: 'workflow.export',
|
|
101
|
+
label: 'Export Workflow',
|
|
102
|
+
group: 'Workflow',
|
|
103
|
+
icon: Download,
|
|
104
|
+
onRun: handlers.exportFile,
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: 'workflow.import',
|
|
108
|
+
label: 'Import Workflow',
|
|
109
|
+
group: 'Workflow',
|
|
110
|
+
icon: Upload,
|
|
111
|
+
onRun: handlers.importJSON,
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
// ── Run ────────────────────────────────────────────────────────
|
|
115
|
+
handlers.isDeploying
|
|
116
|
+
? {
|
|
117
|
+
id: 'run.stop',
|
|
118
|
+
label: 'Stop Workflow',
|
|
119
|
+
group: 'Run',
|
|
120
|
+
icon: Square,
|
|
121
|
+
onRun: handlers.stop,
|
|
122
|
+
}
|
|
123
|
+
: {
|
|
124
|
+
id: 'run.start',
|
|
125
|
+
label: 'Start Workflow',
|
|
126
|
+
group: 'Run',
|
|
127
|
+
icon: Play,
|
|
128
|
+
onRun: handlers.run,
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
// ── Open panels ────────────────────────────────────────────────
|
|
132
|
+
{
|
|
133
|
+
id: 'open.settings',
|
|
134
|
+
label: 'Open Settings',
|
|
135
|
+
group: 'Open',
|
|
136
|
+
icon: SettingsIcon,
|
|
137
|
+
onRun: handlers.openSettings,
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
id: 'open.credentials',
|
|
141
|
+
label: 'Open Credentials',
|
|
142
|
+
group: 'Open',
|
|
143
|
+
icon: KeyRound,
|
|
144
|
+
onRun: handlers.openCredentials,
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
// ── View toggles ───────────────────────────────────────────────
|
|
148
|
+
{
|
|
149
|
+
id: 'view.sidebar',
|
|
150
|
+
label: 'Toggle Sidebar',
|
|
151
|
+
group: 'View',
|
|
152
|
+
icon: PanelLeftClose,
|
|
153
|
+
onRun: handlers.toggleSidebar,
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
id: 'view.palette',
|
|
157
|
+
label: 'Toggle Component Palette',
|
|
158
|
+
group: 'View',
|
|
159
|
+
icon: PanelRightClose,
|
|
160
|
+
onRun: handlers.toggleComponentPalette,
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
id: 'view.console',
|
|
164
|
+
label: 'Toggle Console / Chat Panel',
|
|
165
|
+
group: 'View',
|
|
166
|
+
icon: Terminal,
|
|
167
|
+
onRun: handlers.toggleConsolePanel,
|
|
168
|
+
},
|
|
169
|
+
];
|
|
170
|
+
|
|
171
|
+
// ── Theme switch ─────────────────────────────────────────────────
|
|
172
|
+
for (const name of AVAILABLE_THEMES) {
|
|
173
|
+
list.push({
|
|
174
|
+
id: `theme.${name}`,
|
|
175
|
+
label: `Switch theme: ${THEME_LABEL[name]}`,
|
|
176
|
+
group: 'Theme',
|
|
177
|
+
icon: PaletteIcon,
|
|
178
|
+
hint: name === theme ? 'active' : undefined,
|
|
179
|
+
onRun: () => setTheme(name),
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return list;
|
|
184
|
+
}, [handlers, theme, setTheme]);
|
|
185
|
+
|
|
186
|
+
return <CommandPalette open={open} onOpenChange={onOpenChange} commands={commands} />;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export default CommandPaletteHost;
|
|
@@ -22,6 +22,8 @@ const ComponentItem: React.FC<ComponentItemProps> = ({ definition: localDefiniti
|
|
|
22
22
|
const iconRaw = spec?.icon ?? definition.icon;
|
|
23
23
|
|
|
24
24
|
return (
|
|
25
|
+
// bg-bg-app + border-default match the handoff `.comp` card.
|
|
26
|
+
// Hover lifts via translate + outline + soft tint backdrop.
|
|
25
27
|
<Card
|
|
26
28
|
size="sm"
|
|
27
29
|
draggable
|
|
@@ -31,13 +33,17 @@ const ComponentItem: React.FC<ComponentItemProps> = ({ definition: localDefiniti
|
|
|
31
33
|
}}
|
|
32
34
|
onDragEnd={() => setIsDragging(false)}
|
|
33
35
|
className={cn(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
// `comp` + `row` are handoff structural hooks: comp activates
|
|
37
|
+
// per-theme component-card decorations (left accent bar on Cyber,
|
|
38
|
+
// boomerang corners on Atomic, gold border on Renaissance hover);
|
|
39
|
+
// row enables the global hover-sound delegate.
|
|
40
|
+
'comp row group relative flex-row items-center gap-3 px-3 py-2 cursor-grab select-none',
|
|
41
|
+
'border-border-default bg-bg-app transition-all duration-150 ease-out',
|
|
42
|
+
'hover:-translate-y-0.5 hover:bg-bg-hover hover:ring-2 hover:ring-foreground/15 hover:shadow-md',
|
|
37
43
|
isDragging && 'opacity-50',
|
|
38
44
|
)}
|
|
39
45
|
>
|
|
40
|
-
<div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-md bg-
|
|
46
|
+
<div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-md bg-bg-elevated ring-1 ring-border-default/40">
|
|
41
47
|
<NodeIcon
|
|
42
48
|
icon={iconRaw}
|
|
43
49
|
className="h-5 w-5 text-lg"
|
|
@@ -46,16 +52,16 @@ const ComponentItem: React.FC<ComponentItemProps> = ({ definition: localDefiniti
|
|
|
46
52
|
</div>
|
|
47
53
|
|
|
48
54
|
<div className="min-w-0 flex-1">
|
|
49
|
-
<div className="truncate text-sm font-medium text-
|
|
55
|
+
<div className="truncate font-display text-sm font-medium text-fg-default">
|
|
50
56
|
{definition.displayName}
|
|
51
57
|
</div>
|
|
52
|
-
<div className="truncate text-xs leading-tight text-muted
|
|
58
|
+
<div className="truncate text-xs leading-tight text-fg-muted">
|
|
53
59
|
{definition.description}
|
|
54
60
|
</div>
|
|
55
61
|
</div>
|
|
56
62
|
|
|
57
63
|
<GripVertical
|
|
58
|
-
className="h-4 w-4 shrink-0 text-
|
|
64
|
+
className="h-4 w-4 shrink-0 text-fg-faint opacity-50 transition-opacity group-hover:opacity-80"
|
|
59
65
|
aria-hidden
|
|
60
66
|
/>
|
|
61
67
|
</Card>
|
|
@@ -27,7 +27,7 @@ const ComponentPalette: React.FC<ComponentPaletteProps> = ({
|
|
|
27
27
|
specsReady = false,
|
|
28
28
|
}) => {
|
|
29
29
|
const theme = useAppTheme();
|
|
30
|
-
const {
|
|
30
|
+
const { isBlocked, isAllowed } = useNodeAllowlist();
|
|
31
31
|
|
|
32
32
|
// Backend-driven group metadata via the shared WS-in-queryFn hook.
|
|
33
33
|
// `useNodeGroups` returns the full query result so we can render a
|
|
@@ -55,9 +55,16 @@ const ComponentPalette: React.FC<ComponentPaletteProps> = ({
|
|
|
55
55
|
const definitions = listCachedNodeSpecs().map(nodeSpecToDescription);
|
|
56
56
|
|
|
57
57
|
const filteredDefinitions = definitions.filter((definition) => {
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
|
|
58
|
+
// Backend allowlist (server/config/node_allowlist.json). Two-tier:
|
|
59
|
+
// 1. `disabled_groups` + `disabled_nodes` — absolute blocklist
|
|
60
|
+
// enforced in BOTH normal and dev mode. The node's group
|
|
61
|
+
// array is passed so `disabled_groups` fires on every plugin
|
|
62
|
+
// in the group (e.g. all 16 android service nodes hidden by
|
|
63
|
+
// one entry).
|
|
64
|
+
// 2. `enabled_nodes` — positive allowlist applied only in
|
|
65
|
+
// normal mode; dev/pro mode bypasses it.
|
|
66
|
+
if (isBlocked(definition.name, definition.group)) return false;
|
|
67
|
+
if (!proMode && !isAllowed(definition.name)) return false;
|
|
61
68
|
|
|
62
69
|
// Filter by search query
|
|
63
70
|
if (searchQuery.trim()) {
|
|
@@ -99,7 +106,7 @@ const ComponentPalette: React.FC<ComponentPaletteProps> = ({
|
|
|
99
106
|
});
|
|
100
107
|
|
|
101
108
|
return categories;
|
|
102
|
-
}, [searchQuery, proMode, groupIndex,
|
|
109
|
+
}, [searchQuery, proMode, groupIndex, isBlocked, isAllowed, specsReady]);
|
|
103
110
|
|
|
104
111
|
const totalComponents = Object.values(categorizedComponents).reduce(
|
|
105
112
|
(acc, components) => acc + components.length,
|
|
@@ -107,19 +114,23 @@ const ComponentPalette: React.FC<ComponentPaletteProps> = ({
|
|
|
107
114
|
);
|
|
108
115
|
|
|
109
116
|
return (
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
117
|
+
// Palette shell: `palette` co-class activates per-theme decorations
|
|
118
|
+
// (panel textures, neon side-glow on Cyber, marble grain on Greek).
|
|
119
|
+
<div className="palette flex h-full w-full flex-col overflow-hidden border-l border-border-default bg-bg-panel">
|
|
120
|
+
{/* Header Section — bg-bg-app drops one elevation step. */}
|
|
121
|
+
<div className="border-b border-border-default bg-bg-app p-4">
|
|
113
122
|
<div className="mb-3 flex items-center justify-between">
|
|
114
|
-
<h2 className="text-base font-semibold text-
|
|
115
|
-
|
|
123
|
+
<h2 className="font-display text-base font-semibold tracking-[var(--type-tracking-display)] text-fg-default [text-transform:var(--type-uppercase)]">
|
|
124
|
+
Components
|
|
125
|
+
</h2>
|
|
126
|
+
<Badge variant="secondary" className="font-mono text-xs font-medium">
|
|
116
127
|
{totalComponents}
|
|
117
128
|
</Badge>
|
|
118
129
|
</div>
|
|
119
130
|
|
|
120
131
|
{/* Search Input */}
|
|
121
132
|
<div className="relative">
|
|
122
|
-
<Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-
|
|
133
|
+
<Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-fg-faint" />
|
|
123
134
|
<Input
|
|
124
135
|
type="text"
|
|
125
136
|
placeholder="Search..."
|
|
@@ -135,7 +146,7 @@ const ComponentPalette: React.FC<ComponentPaletteProps> = ({
|
|
|
135
146
|
{groupsLoading ? (
|
|
136
147
|
<PaletteSkeleton />
|
|
137
148
|
) : Object.keys(categorizedComponents).length === 0 ? (
|
|
138
|
-
<div className="flex flex-col items-center px-6 py-12 text-center text-muted
|
|
149
|
+
<div className="flex flex-col items-center px-6 py-12 text-center text-fg-muted">
|
|
139
150
|
<Search className="mb-3 h-12 w-12 opacity-50" />
|
|
140
151
|
<p className="text-sm">
|
|
141
152
|
No components found matching "{searchQuery}"
|
|
@@ -167,7 +178,7 @@ const ComponentPalette: React.FC<ComponentPaletteProps> = ({
|
|
|
167
178
|
fallback={<span>📦</span>}
|
|
168
179
|
/>
|
|
169
180
|
</span>
|
|
170
|
-
<span className="text-sm font-semibold text-
|
|
181
|
+
<span className="font-display text-sm font-semibold tracking-[var(--type-tracking-display)] text-fg-default [text-transform:var(--type-uppercase)]">
|
|
171
182
|
{config.label}
|
|
172
183
|
</span>
|
|
173
184
|
</div>
|
|
@@ -362,8 +362,11 @@ const ConsolePanel: React.FC<ConsolePanelProps> = ({
|
|
|
362
362
|
// ------------------------------ Render ------------------------------
|
|
363
363
|
|
|
364
364
|
return (
|
|
365
|
+
// `chat` co-class is the design-handoff structural hook for per-theme
|
|
366
|
+
// panel decorations (parchment vellum on Renaissance, neon cyan
|
|
367
|
+
// top-glow on Cyber, washi noise on Edo, etc.).
|
|
365
368
|
<div
|
|
366
|
-
className="relative"
|
|
369
|
+
className="chat relative"
|
|
367
370
|
onWheel={e => {
|
|
368
371
|
// Prevent scroll from propagating to the canvas/page when the cursor
|
|
369
372
|
// is over the panel header, resize handle, or non-scrollable areas.
|
|
@@ -386,7 +389,7 @@ const ConsolePanel: React.FC<ConsolePanelProps> = ({
|
|
|
386
389
|
{/* Panel Header */}
|
|
387
390
|
<div
|
|
388
391
|
onClick={onToggle}
|
|
389
|
-
className="flex cursor-pointer items-center justify-between border-t border-border bg-
|
|
392
|
+
className="flex cursor-pointer items-center justify-between border-t border-border-default bg-bg-elevated px-3 py-1.5 select-none"
|
|
390
393
|
>
|
|
391
394
|
<div className="flex items-center gap-2">
|
|
392
395
|
<ChevronDown
|
|
@@ -395,7 +398,7 @@ const ConsolePanel: React.FC<ConsolePanelProps> = ({
|
|
|
395
398
|
!isOpen && 'rotate-180'
|
|
396
399
|
)}
|
|
397
400
|
/>
|
|
398
|
-
<span className="flex items-center gap-1.5 text-sm font-semibold text-
|
|
401
|
+
<span className="flex items-center gap-1.5 font-display text-sm font-semibold tracking-[var(--type-tracking-display)] text-fg-default [text-transform:var(--type-uppercase)]">
|
|
399
402
|
Chat / Console
|
|
400
403
|
{(consoleLogs.length > 0 || (chatMessages && chatMessages.length > 0)) && (
|
|
401
404
|
<Badge variant="secondary" className="text-xs">
|
|
@@ -411,7 +414,7 @@ const ConsolePanel: React.FC<ConsolePanelProps> = ({
|
|
|
411
414
|
ref={containerRef}
|
|
412
415
|
style={{ height: isOpen ? `${panelHeight}px` : '0px' }}
|
|
413
416
|
className={cn(
|
|
414
|
-
'flex flex-row overflow-hidden bg-
|
|
417
|
+
'flex flex-row overflow-hidden bg-bg-app',
|
|
415
418
|
'max-h-[calc(100vh-90px)]',
|
|
416
419
|
(isResizing || isHorizontalResizing) ? '[transition:none]' : 'transition-[height] duration-200 ease-in-out'
|
|
417
420
|
)}
|
|
@@ -422,9 +425,9 @@ const ConsolePanel: React.FC<ConsolePanelProps> = ({
|
|
|
422
425
|
className="relative flex flex-col overflow-hidden"
|
|
423
426
|
>
|
|
424
427
|
{/* Header */}
|
|
425
|
-
<div className="flex min-h-[32px] items-center justify-between border-b border-border bg-
|
|
428
|
+
<div className="flex min-h-[32px] items-center justify-between border-b border-border-default bg-bg-elevated px-3 py-1.5">
|
|
426
429
|
<div className="flex items-center gap-2">
|
|
427
|
-
<span className="flex items-center gap-1.5 text-sm font-semibold text-
|
|
430
|
+
<span className="flex items-center gap-1.5 font-display text-sm font-semibold tracking-[var(--type-tracking-display)] text-fg-default [text-transform:var(--type-uppercase)]">
|
|
428
431
|
Chat
|
|
429
432
|
{chatMessages && chatMessages.length > 0 && (
|
|
430
433
|
<Badge variant="success" className="text-xs">{chatMessages.length}</Badge>
|
|
@@ -483,10 +486,15 @@ const ConsolePanel: React.FC<ConsolePanelProps> = ({
|
|
|
483
486
|
<div
|
|
484
487
|
key={`${msg.timestamp}-${index}`}
|
|
485
488
|
className={cn(
|
|
486
|
-
|
|
489
|
+
// `chat-msg` + `chat-msg-user` / `chat-msg-bot`
|
|
490
|
+
// co-classes activate per-theme bubble decorations
|
|
491
|
+
// (Renaissance: gold-foil user / vellum bot with
|
|
492
|
+
// ✦ marker; Cyber: > USER:: / < NODE:: prefixes
|
|
493
|
+
// with neon glow; etc.).
|
|
494
|
+
'chat-msg max-w-[80%] px-3 py-2 break-words',
|
|
487
495
|
isUser
|
|
488
|
-
? 'mr-0 ml-auto rounded-l-xl rounded-tr-xl rounded-br-sm bg-node-agent-soft'
|
|
489
|
-
: 'mr-auto ml-0 rounded-r-xl rounded-tl-xl rounded-bl-sm bg-
|
|
496
|
+
? 'chat-msg-user mr-0 ml-auto rounded-l-xl rounded-tr-xl rounded-br-sm bg-node-agent-soft'
|
|
497
|
+
: 'chat-msg-bot mr-auto ml-0 rounded-r-xl rounded-tl-xl rounded-bl-sm border border-border-default bg-bg-elevated'
|
|
490
498
|
)}
|
|
491
499
|
>
|
|
492
500
|
{isUser ? (
|
|
@@ -512,7 +520,7 @@ const ConsolePanel: React.FC<ConsolePanelProps> = ({
|
|
|
512
520
|
</div>
|
|
513
521
|
|
|
514
522
|
{/* Input */}
|
|
515
|
-
<div className="flex items-center gap-2 border-t border-border bg-
|
|
523
|
+
<div className="flex items-center gap-2 border-t border-border-default bg-bg-elevated px-4 py-2.5">
|
|
516
524
|
<Input
|
|
517
525
|
ref={chatInputRef}
|
|
518
526
|
type="text"
|
|
@@ -549,7 +557,7 @@ const ConsolePanel: React.FC<ConsolePanelProps> = ({
|
|
|
549
557
|
{/* ===================== Console / Terminal Section (right) ===================== */}
|
|
550
558
|
<div className="flex flex-1 flex-col overflow-hidden">
|
|
551
559
|
{/* Header with tabs + filters */}
|
|
552
|
-
<div className="flex min-h-[32px] items-center justify-between border-b border-border bg-
|
|
560
|
+
<div className="flex min-h-[32px] items-center justify-between border-b border-border-default bg-bg-elevated px-3 py-1.5">
|
|
553
561
|
{/* Tab buttons */}
|
|
554
562
|
<div className="flex items-center gap-1">
|
|
555
563
|
<button
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wraps content (typically a heading or first paragraph) with the
|
|
3
|
+
* `v-display drop-cap` className so theme CSS rules like the
|
|
4
|
+
* Renaissance `.v-display.drop-cap::first-letter` rule fire on the
|
|
5
|
+
* first letter. Under themes that don't define a drop-cap rule it's a
|
|
6
|
+
* no-op (just two extra class names on the wrapper).
|
|
7
|
+
*/
|
|
8
|
+
import React from 'react';
|
|
9
|
+
|
|
10
|
+
export interface DropCapProps {
|
|
11
|
+
as?: 'h1' | 'h2' | 'h3' | 'p' | 'span' | 'div';
|
|
12
|
+
className?: string;
|
|
13
|
+
children: React.ReactNode;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const DropCap: React.FC<DropCapProps> = ({
|
|
17
|
+
as: Tag = 'span',
|
|
18
|
+
className = '',
|
|
19
|
+
children,
|
|
20
|
+
}) => {
|
|
21
|
+
return (
|
|
22
|
+
<Tag className={`v-display drop-cap ${className}`.trim()}>
|
|
23
|
+
{children}
|
|
24
|
+
</Tag>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default DropCap;
|
|
@@ -98,7 +98,11 @@ const EditableNodeLabel: React.FC<EditableNodeLabelProps> = ({
|
|
|
98
98
|
onBlur={handleSave}
|
|
99
99
|
onClick={(e) => e.stopPropagation()}
|
|
100
100
|
className={cn(
|
|
101
|
-
|
|
101
|
+
// Both `sq-node-label` and `node-label` co-classes always emit so
|
|
102
|
+
// per-theme CSS rules fire for whichever parent topology this
|
|
103
|
+
// label sits inside (`.sq-node` for square, `.node` for
|
|
104
|
+
// rectangular). Wave 26.B.
|
|
105
|
+
'sq-node-label node-label mt-2 h-auto max-w-[120px] border-accent px-1 py-0.5 text-center text-xs font-medium',
|
|
102
106
|
className
|
|
103
107
|
)}
|
|
104
108
|
/>
|
|
@@ -110,7 +114,11 @@ const EditableNodeLabel: React.FC<EditableNodeLabelProps> = ({
|
|
|
110
114
|
onDoubleClick={onActivate}
|
|
111
115
|
title="Double-click to rename"
|
|
112
116
|
className={cn(
|
|
113
|
-
|
|
117
|
+
// Both `sq-node-label` and `node-label` co-classes always emit so
|
|
118
|
+
// per-theme CSS rules fire for whichever parent topology this
|
|
119
|
+
// label sits inside (`.sq-node` for square, `.node` for
|
|
120
|
+
// rectangular). Wave 26.B.
|
|
121
|
+
'sq-node-label node-label mt-2 max-w-[120px] cursor-text text-center text-xs leading-tight font-medium text-foreground',
|
|
114
122
|
className
|
|
115
123
|
)}
|
|
116
124
|
>
|
|
@@ -19,7 +19,7 @@ interface InputDataItem {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
const InputNodesPanel: React.FC<InputNodesPanelProps> = ({ nodeId }) => {
|
|
22
|
-
const
|
|
22
|
+
const currentWorkflow = useAppStore((s) => s.currentWorkflow);
|
|
23
23
|
const { getNodeOutput } = useWebSocket();
|
|
24
24
|
const [inputData, setInputData] = useState<InputDataItem[]>([]);
|
|
25
25
|
const [loading, setLoading] = useState(false);
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* if you need a new prop.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import React from 'react';
|
|
12
|
+
import React, { useEffect, useRef } from 'react';
|
|
13
13
|
import { X, Settings } from 'lucide-react';
|
|
14
14
|
import {
|
|
15
15
|
Dialog,
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
} from '@/components/ui/dialog';
|
|
22
22
|
import { Dialog as DialogPrimitive } from 'radix-ui';
|
|
23
23
|
import { cn } from '@/lib/utils';
|
|
24
|
+
import { Sounds } from '@/lib/sound';
|
|
24
25
|
|
|
25
26
|
interface ModalProps {
|
|
26
27
|
isOpen: boolean;
|
|
@@ -62,14 +63,40 @@ const Modal: React.FC<ModalProps> = ({
|
|
|
62
63
|
}) => {
|
|
63
64
|
const showHeader = Boolean(title || headerActions);
|
|
64
65
|
|
|
66
|
+
// Fire per-theme open/close sounds on isOpen transitions only — not
|
|
67
|
+
// on first mount (use a previous-value ref to detect the actual
|
|
68
|
+
// edge). Sounds.play is a no-op when the engine is disabled.
|
|
69
|
+
const prevOpenRef = useRef(isOpen);
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
const prev = prevOpenRef.current;
|
|
72
|
+
if (prev !== isOpen) {
|
|
73
|
+
Sounds.play(isOpen ? 'modalOpen' : 'modalClose');
|
|
74
|
+
prevOpenRef.current = isOpen;
|
|
75
|
+
}
|
|
76
|
+
}, [isOpen]);
|
|
77
|
+
|
|
65
78
|
return (
|
|
66
79
|
<Dialog open={isOpen} onOpenChange={(next) => { if (!next) onClose(); }}>
|
|
67
80
|
<DialogPortal>
|
|
68
|
-
|
|
81
|
+
{/* bg-bg-overlay reads --bg-overlay (each theme owns its own
|
|
82
|
+
scrim alpha + tone — Renaissance uses ink-brown, Cyber uses
|
|
83
|
+
void-near-black, light/dark use plain blacks). */}
|
|
84
|
+
<DialogOverlay className="bg-bg-overlay supports-backdrop-filter:backdrop-blur-xs" />
|
|
69
85
|
<DialogPrimitive.Content
|
|
70
86
|
data-slot="dialog-content"
|
|
71
87
|
className={cn(
|
|
72
|
-
|
|
88
|
+
// bg-bg-app + border-border-default consume the new-contract
|
|
89
|
+
// tokens directly so modals inherit the surface hierarchy
|
|
90
|
+
// defined by the active theme (parchment under Renaissance,
|
|
91
|
+
// void under Cyber).
|
|
92
|
+
//
|
|
93
|
+
// `modal` + `modal-frame` are the design-handoff structural
|
|
94
|
+
// hooks — per-theme CSS targets these classes for nailed-up
|
|
95
|
+
// borders (Plague), gilded corners (Renaissance), neon
|
|
96
|
+
// scanlines (Cyber), double-rule frames (Greek), parchment
|
|
97
|
+
// textures (Renaissance) on the modal content.
|
|
98
|
+
'modal modal-frame',
|
|
99
|
+
'fixed top-1/2 left-1/2 z-50 flex -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-lg border border-border-default bg-bg-app shadow-2xl outline-none',
|
|
73
100
|
'data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 duration-100',
|
|
74
101
|
className
|
|
75
102
|
)}
|
|
@@ -81,15 +108,20 @@ const Modal: React.FC<ModalProps> = ({
|
|
|
81
108
|
}}
|
|
82
109
|
>
|
|
83
110
|
{showHeader ? (
|
|
84
|
-
|
|
85
|
-
|
|
111
|
+
// Header: bg-bg-panel sits one elevation step above bg-bg-app
|
|
112
|
+
// (panel surface above page surface). font-display + tracking
|
|
113
|
+
// + text-transform are theme-driven so titles read as Cinzel
|
|
114
|
+
// uppercase under Renaissance and Major Mono Display under
|
|
115
|
+
// Cyber, while staying clean sans-serif under light/dark.
|
|
116
|
+
<div className="modal-head relative flex w-full items-center border-b border-border-default bg-bg-panel px-5 py-3">
|
|
117
|
+
<DialogTitle className="absolute left-5 flex items-center gap-2 font-display text-base font-semibold tracking-[var(--type-tracking-display)] text-fg-default [text-transform:var(--type-uppercase)]">
|
|
86
118
|
<Settings className="h-4 w-4 opacity-70" />
|
|
87
119
|
{title}
|
|
88
120
|
</DialogTitle>
|
|
89
121
|
<div className="flex flex-1 items-center justify-center">{headerActions}</div>
|
|
90
122
|
<DialogClose
|
|
91
123
|
onClick={onClose}
|
|
92
|
-
className="absolute right-5 inline-flex h-8 w-8 items-center justify-center rounded-md text-muted
|
|
124
|
+
className="absolute right-5 inline-flex h-8 w-8 items-center justify-center rounded-md text-fg-muted transition-colors hover:bg-bg-hover hover:text-fg-default"
|
|
93
125
|
aria-label="Close"
|
|
94
126
|
>
|
|
95
127
|
<X className="h-[18px] w-[18px]" />
|
|
@@ -156,7 +156,7 @@ const OutputDisplayPanel: React.FC<OutputDisplayPanelProps> = ({ results, onClea
|
|
|
156
156
|
<div className="flex items-center justify-between border-b border-border bg-background px-4 py-3">
|
|
157
157
|
<div className="flex items-center gap-2">
|
|
158
158
|
<Play className="h-4 w-4 text-success" />
|
|
159
|
-
<span className="text-sm font-semibold text-
|
|
159
|
+
<span className="font-display text-sm font-semibold tracking-[var(--type-tracking-display)] text-fg-default [text-transform:var(--type-uppercase)]">Execution Results</span>
|
|
160
160
|
<Badge variant="secondary" className="text-xs">{results.length}</Badge>
|
|
161
161
|
</div>
|
|
162
162
|
{onClear && (
|