machinaos 0.0.78 → 0.0.80
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/.env.template +74 -5
- package/{workflows/AI Assistant_workflow-1778504793388-ou1m1tz2x.json → .machina/workflows/AI Assistant_example_workflow-1779017037684-e2e5da7a.json } +164 -105
- package/{workflows/AI Employee_example_workflow-1777720598005-u4cm858dv.json → .machina/workflows/AI Employee_example_workflow-1779102911870-cbc76c82.json } +582 -328
- package/{workflows/Claude Assistant_workflow-1778380124051-mdibn807c.json → .machina/workflows/Claude Assistant_example_workflow-1779095939967-2369cff4.json } +152 -83
- package/README.md +5 -2
- package/bin/cli.js +2 -2
- package/{machina → cli}/__main__.py +11 -7
- package/cli/_common.py +122 -0
- package/cli/buildenv.py +40 -0
- package/cli/cli.py +204 -0
- package/{machina → cli}/colors.py +10 -2
- package/cli/commands/__init__.py +1 -0
- package/cli/commands/_temporal_specs.py +59 -0
- package/{machina → cli}/commands/build.py +35 -45
- package/cli/commands/clean.py +141 -0
- package/cli/commands/daemon/__init__.py +47 -0
- package/cli/commands/daemon/_state.py +97 -0
- package/cli/commands/daemon/restart.py +14 -0
- package/cli/commands/daemon/start.py +49 -0
- package/cli/commands/daemon/status.py +20 -0
- package/cli/commands/daemon/stop.py +22 -0
- package/{machina → cli}/commands/dev.py +32 -42
- package/{machina → cli}/commands/docs.py +13 -11
- package/{machina → cli}/commands/start.py +69 -62
- package/{machina → cli}/commands/stop.py +7 -10
- package/{machina → cli}/commands/version.py +12 -6
- package/cli/config.py +170 -0
- package/cli/platform_.py +169 -0
- package/{machina → cli}/ports.py +42 -3
- package/{machina → cli}/run.py +29 -2
- package/{machina → cli}/supervisor.py +29 -12
- package/{machina → cli}/tcp.py +6 -2
- package/{machina → cli}/tree.py +38 -11
- package/client/dist/assets/{ActionBar-Du2MSFSz.js → ActionBar-Cjr3TF7g.js} +1 -1
- package/client/dist/assets/{ApiKeyInput-k2LBmBjb.js → ApiKeyInput-DIJE2PVA.js} +1 -1
- package/client/dist/assets/{ApiKeyPanel-C_bV9U0X.js → ApiKeyPanel-CPmye7uh.js} +1 -1
- package/client/dist/assets/{ApiUsageSection-CmVfwZzL.js → ApiUsageSection-TF_7gH2D.js} +1 -1
- package/client/dist/assets/{EmailPanel-CeKIMGu-.js → EmailPanel-Bs-xvbKR.js} +1 -1
- package/client/dist/assets/{OAuthPanel-KA3t3Q2K.js → OAuthPanel-BDtVJhAV.js} +1 -1
- package/client/dist/assets/{QrPairingPanel-NgNpJNuk.js → QrPairingPanel-BwJehTuZ.js} +1 -1
- package/client/dist/assets/{RateLimitSection-Du5YNVIA.js → RateLimitSection-CfNOoPIS.js} +1 -1
- package/client/dist/assets/{StatusCard-DNLyayXc.js → StatusCard-DkwIrgdP.js} +1 -1
- package/client/dist/assets/index-P2FzntoL.js +165 -0
- package/client/dist/index.html +1 -1
- package/client/package.json +1 -1
- package/client/src/Dashboard.tsx +128 -76
- package/client/src/adapters/nodeSpecToDescription.ts +7 -0
- package/client/src/assets/icons/index.test.ts +10 -0
- package/client/src/assets/icons/index.ts +16 -3
- package/client/src/components/AIAgentNode.tsx +8 -8
- package/client/src/components/ParameterRenderer.tsx +6 -3
- package/client/src/components/SkillEditorModal.tsx +1 -0
- package/client/src/components/credentials/panels/EmailPanel.tsx +2 -0
- package/client/src/components/credentials/sections/ProviderDefaultsSection.tsx +2 -0
- package/client/src/components/credentials/sections/RateLimitSection.tsx +1 -0
- package/client/src/components/icons/AIProviderIcons.tsx +1 -0
- package/client/src/components/maps/GoogleMapsPicker.tsx +1 -0
- package/client/src/components/parameterPanel/InputSection.tsx +1 -0
- package/client/src/components/parameterPanel/MasterSkillEditor.tsx +1 -0
- package/client/src/components/parameterPanel/OutputSection.tsx +1 -0
- package/client/src/components/ui/ComponentPalette.tsx +1 -0
- package/client/src/components/ui/MapSelector.tsx +1 -0
- package/client/src/components/ui/NodeContextMenu.tsx +3 -3
- package/client/src/components/ui/SettingsPanel.tsx +1 -0
- package/client/src/components/ui/action-button.tsx +1 -0
- package/client/src/components/ui/badge.tsx +1 -0
- package/client/src/components/ui/button.tsx +1 -0
- package/client/src/components/ui/form.tsx +1 -0
- package/client/src/components/ui/tabs.tsx +1 -0
- package/client/src/contexts/AuthContext.tsx +1 -0
- package/client/src/contexts/ThemeContext.tsx +1 -0
- package/client/src/contexts/WebSocketContext.tsx +104 -34
- package/client/src/hooks/__tests__/useApiKeys.test.ts +2 -2
- package/client/src/hooks/useReactFlowNodes.ts +1 -0
- package/client/src/hooks/useWorkflowValidation.ts +142 -0
- package/client/src/lib/nodeSpec.ts +1 -0
- package/client/src/test/providers.tsx +1 -0
- package/client/src/types/__tests__/cloudEvents.test.ts +5 -2
- package/client/src/types/cloudEvents.ts +19 -7
- package/client/src/utils/nodeUtils.ts +1 -1
- package/client/src/utils/workflow.ts +8 -2
- package/client/src/utils/workflowExport.ts +60 -3
- package/package.json +24 -23
- package/scripts/install.js +16 -27
- package/scripts/migrate_icons.py +3 -1
- package/scripts/migrate_skill_icons.py +6 -7
- package/scripts/postinstall.js +11 -9
- package/server/config/ai_cli_providers.json +2 -3
- package/server/config/credential_providers.json +15 -15
- package/server/config/llm_defaults.json +1 -1
- package/server/config/model_registry.json +416 -611
- package/server/constants.py +285 -223
- package/server/core/__init__.py +1 -1
- package/server/core/cache.py +9 -29
- package/server/core/cleanup.py +12 -24
- package/server/core/config.py +148 -24
- package/server/core/container.py +68 -59
- package/server/core/credential_backends.py +5 -13
- package/server/core/credentials_database.py +13 -43
- package/server/core/database.py +292 -353
- package/server/core/health.py +4 -5
- package/server/core/logging.py +241 -87
- package/server/core/paths.py +285 -0
- package/server/core/tracing.py +2 -8
- package/server/gunicorn.conf.py +1 -0
- package/server/main.py +150 -74
- package/server/middleware/auth.py +18 -24
- package/server/models/__init__.py +1 -1
- package/server/models/auth.py +5 -12
- package/server/models/database.py +36 -68
- package/server/models/node_metadata.py +25 -18
- package/server/nodejs/dist/index.js +107 -0
- package/server/nodes/README.md +11 -5
- package/server/nodes/__init__.py +1 -1
- package/server/nodes/_visuals.py +146 -14
- package/server/nodes/agent/_events.py +124 -0
- package/server/nodes/agent/_handles.py +15 -29
- package/server/nodes/agent/_inline.py +28 -25
- package/server/nodes/agent/_specialized.py +30 -15
- package/server/nodes/agent/{ai_agent.py → ai_agent/__init__.py} +33 -17
- package/server/nodes/agent/ai_agent/meta.json +3 -0
- package/server/nodes/agent/{ai_employee.py → ai_employee/__init__.py} +5 -2
- package/server/nodes/agent/ai_employee/meta.json +3 -0
- package/server/nodes/agent/{android_agent.py → android_agent/__init__.py} +1 -1
- package/server/nodes/agent/android_agent/meta.json +3 -0
- package/server/nodes/agent/{autonomous_agent.py → autonomous_agent/__init__.py} +2 -1
- package/server/nodes/agent/autonomous_agent/meta.json +3 -0
- package/server/nodes/agent/{chat_agent.py → chat_agent/__init__.py} +29 -12
- package/server/nodes/agent/chat_agent/meta.json +3 -0
- package/server/nodes/agent/{claude_code_agent.py → claude_code_agent/__init__.py} +192 -95
- package/server/nodes/agent/claude_code_agent/_handlers.py +169 -0
- package/server/{services/claude_oauth.py → nodes/agent/claude_code_agent/_oauth.py} +26 -13
- package/server/nodes/agent/claude_code_agent/_pool.py +1020 -0
- package/server/nodes/agent/claude_code_agent/_provider.py +513 -0
- package/server/nodes/agent/claude_code_agent/_skills.py +245 -0
- package/server/nodes/agent/claude_code_agent/meta.json +3 -0
- package/server/nodes/agent/{codex_agent.py → codex_agent/__init__.py} +26 -35
- package/server/nodes/agent/codex_agent/meta.json +3 -0
- package/server/nodes/agent/{coding_agent.py → coding_agent/__init__.py} +1 -1
- package/server/nodes/agent/coding_agent/meta.json +3 -0
- package/server/nodes/agent/{consumer_agent.py → consumer_agent/__init__.py} +1 -1
- package/server/nodes/agent/consumer_agent/meta.json +3 -0
- package/server/nodes/agent/{orchestrator_agent.py → orchestrator_agent/__init__.py} +5 -2
- package/server/nodes/agent/orchestrator_agent/meta.json +3 -0
- package/server/nodes/agent/{payments_agent.py → payments_agent/__init__.py} +1 -1
- package/server/nodes/agent/payments_agent/meta.json +3 -0
- package/server/nodes/agent/{productivity_agent.py → productivity_agent/__init__.py} +1 -1
- package/server/nodes/agent/productivity_agent/meta.json +3 -0
- package/server/nodes/agent/{rlm_agent.py → rlm_agent/__init__.py} +18 -17
- package/server/nodes/agent/rlm_agent/meta.json +3 -0
- package/server/nodes/agent/{social_agent.py → social_agent/__init__.py} +1 -1
- package/server/nodes/agent/social_agent/meta.json +3 -0
- package/server/nodes/agent/{task_agent.py → task_agent/__init__.py} +1 -1
- package/server/nodes/agent/task_agent/meta.json +3 -0
- package/server/nodes/agent/{tool_agent.py → tool_agent/__init__.py} +1 -1
- package/server/nodes/agent/tool_agent/meta.json +3 -0
- package/server/nodes/agent/{travel_agent.py → travel_agent/__init__.py} +1 -1
- package/server/nodes/agent/travel_agent/meta.json +3 -0
- package/server/nodes/agent/{web_agent.py → web_agent/__init__.py} +1 -1
- package/server/nodes/agent/web_agent/meta.json +3 -0
- package/server/nodes/android/__init__.py +24 -0
- package/server/nodes/android/_base.py +93 -76
- package/server/nodes/android/_dispatcher.py +140 -223
- package/server/nodes/android/_events.py +154 -0
- package/server/nodes/android/_handlers.py +13 -7
- package/server/nodes/android/_option_loaders.py +1 -4
- package/server/nodes/android/_refresh.py +27 -37
- package/server/nodes/android/_relay/broadcaster.py +25 -41
- package/server/nodes/android/_relay/client.py +23 -42
- package/server/nodes/android/_relay/manager.py +1 -0
- package/server/nodes/android/_relay/protocol.py +6 -0
- package/server/nodes/android/_router.py +48 -133
- package/server/nodes/android/{airplane_mode_control.py → airplane_mode_control/__init__.py} +2 -1
- package/server/nodes/android/airplane_mode_control/meta.json +3 -0
- package/server/nodes/android/{app_launcher.py → app_launcher/__init__.py} +2 -1
- package/server/nodes/android/app_launcher/meta.json +3 -0
- package/server/nodes/android/{app_list.py → app_list/__init__.py} +2 -1
- package/server/nodes/android/app_list/meta.json +3 -0
- package/server/nodes/android/{audio_automation.py → audio_automation/__init__.py} +2 -1
- package/server/nodes/android/audio_automation/meta.json +3 -0
- package/server/nodes/android/{battery_monitor.py → battery_monitor/__init__.py} +2 -1
- package/server/nodes/android/battery_monitor/meta.json +3 -0
- package/server/nodes/android/{bluetooth_automation.py → bluetooth_automation/__init__.py} +2 -1
- package/server/nodes/android/bluetooth_automation/meta.json +3 -0
- package/server/nodes/android/{camera_control.py → camera_control/__init__.py} +2 -1
- package/server/nodes/android/camera_control/meta.json +3 -0
- package/server/nodes/android/{device_state_automation.py → device_state_automation/__init__.py} +2 -1
- package/server/nodes/android/device_state_automation/meta.json +3 -0
- package/server/nodes/android/{environmental_sensors.py → environmental_sensors/__init__.py} +2 -1
- package/server/nodes/android/environmental_sensors/meta.json +3 -0
- package/server/nodes/android/{location.py → location/__init__.py} +2 -1
- package/server/nodes/android/location/meta.json +3 -0
- package/server/nodes/android/{media_control.py → media_control/__init__.py} +2 -1
- package/server/nodes/android/media_control/meta.json +3 -0
- package/server/nodes/android/{motion_detection.py → motion_detection/__init__.py} +2 -1
- package/server/nodes/android/motion_detection/meta.json +3 -0
- package/server/nodes/android/{network_monitor.py → network_monitor/__init__.py} +2 -1
- package/server/nodes/android/network_monitor/meta.json +3 -0
- package/server/nodes/android/{screen_control_automation.py → screen_control_automation/__init__.py} +2 -1
- package/server/nodes/android/screen_control_automation/meta.json +3 -0
- package/server/nodes/android/{system_info.py → system_info/__init__.py} +2 -1
- package/server/nodes/android/system_info/meta.json +3 -0
- package/server/nodes/android/{wifi_automation.py → wifi_automation/__init__.py} +2 -1
- package/server/nodes/android/wifi_automation/meta.json +3 -0
- package/server/nodes/browser/__init__.py +22 -1
- package/server/nodes/browser/_install.py +63 -0
- package/server/nodes/browser/_service.py +21 -25
- package/server/nodes/browser/{browser.py → browser/__init__.py} +58 -25
- package/server/nodes/browser/browser/meta.json +3 -0
- package/server/nodes/chat/{chat_history.py → chat_history/__init__.py} +2 -4
- package/server/nodes/chat/chat_history/meta.json +3 -0
- package/server/nodes/chat/{chat_send.py → chat_send/__init__.py} +2 -4
- package/server/nodes/chat/chat_send/icon.svg +1 -0
- package/server/nodes/chat/chat_send/meta.json +3 -0
- package/server/nodes/code/_base.py +1 -1
- package/server/nodes/code/{javascript_executor.py → javascript_executor/__init__.py} +5 -5
- package/server/nodes/code/javascript_executor/meta.json +3 -0
- package/server/nodes/code/{python_executor.py → python_executor/__init__.py} +32 -14
- package/server/nodes/code/python_executor/meta.json +3 -0
- package/server/nodes/code/{typescript_executor.py → typescript_executor/__init__.py} +5 -5
- package/server/nodes/code/typescript_executor/meta.json +3 -0
- package/server/nodes/document/{document_parser.py → document_parser/__init__.py} +26 -15
- package/server/nodes/document/document_parser/meta.json +3 -0
- package/server/nodes/document/{embedding_generator.py → embedding_generator/__init__.py} +16 -9
- package/server/nodes/document/embedding_generator/meta.json +3 -0
- package/server/nodes/document/{file_downloader.py → file_downloader/__init__.py} +30 -20
- package/server/nodes/document/file_downloader/meta.json +3 -0
- package/server/nodes/document/{http_scraper.py → http_scraper/__init__.py} +31 -21
- package/server/nodes/document/http_scraper/meta.json +3 -0
- package/server/nodes/document/{text_chunker.py → text_chunker/__init__.py} +17 -12
- package/server/nodes/document/text_chunker/meta.json +3 -0
- package/server/nodes/document/{vector_store.py → vector_store/__init__.py} +88 -72
- package/server/nodes/document/vector_store/meta.json +3 -0
- package/server/nodes/email/__init__.py +9 -2
- package/server/nodes/email/_events.py +54 -0
- package/server/nodes/email/_filters.py +3 -3
- package/server/nodes/email/_himalaya.py +95 -50
- package/server/nodes/email/_service.py +23 -13
- package/server/nodes/email/{email_read.py → email_read/__init__.py} +23 -11
- package/server/nodes/email/email_read/icon.svg +6 -0
- package/server/nodes/email/email_read/meta.json +3 -0
- package/server/nodes/email/{email_receive.py → email_receive/__init__.py} +45 -23
- package/server/nodes/email/email_receive/meta.json +3 -0
- package/server/nodes/email/{email_send.py → email_send/__init__.py} +13 -7
- package/server/nodes/email/email_send/meta.json +3 -0
- package/server/nodes/filesystem/_backend.py +1 -5
- package/server/nodes/filesystem/{file_modify.py → file_modify/__init__.py} +10 -5
- package/server/nodes/filesystem/file_modify/meta.json +3 -0
- package/server/nodes/filesystem/{file_read.py → file_read/__init__.py} +7 -3
- package/server/nodes/filesystem/file_read/meta.json +3 -0
- package/server/nodes/filesystem/{fs_search.py → fs_search/__init__.py} +11 -3
- package/server/nodes/filesystem/fs_search/meta.json +3 -0
- package/server/nodes/filesystem/{shell.py → shell/__init__.py} +12 -5
- package/server/nodes/filesystem/shell/meta.json +3 -0
- package/server/nodes/google/__init__.py +12 -0
- package/server/nodes/google/_auth_helper.py +7 -13
- package/server/nodes/google/_base.py +14 -11
- package/server/nodes/google/_credentials.py +2 -1
- package/server/nodes/google/_events.py +47 -0
- package/server/nodes/google/_filters.py +3 -3
- package/server/nodes/google/_gmail.py +70 -47
- package/server/nodes/google/_handlers.py +3 -1
- package/server/nodes/google/_oauth.py +25 -11
- package/server/nodes/google/_option_loaders.py +9 -30
- package/server/nodes/google/_refresh.py +8 -12
- package/server/nodes/google/_router.py +4 -5
- package/server/nodes/google/{calendar.py → calendar/__init__.py} +87 -64
- package/server/nodes/google/calendar/meta.json +3 -0
- package/server/nodes/google/{contacts.py → contacts/__init__.py} +84 -72
- package/server/nodes/google/contacts/meta.json +3 -0
- package/server/nodes/google/{drive.py → drive/__init__.py} +87 -72
- package/server/nodes/google/drive/meta.json +3 -0
- package/server/nodes/google/{gmail.py → gmail/__init__.py} +73 -39
- package/server/nodes/google/gmail/meta.json +3 -0
- package/server/nodes/google/{gmail_receive.py → gmail_receive/__init__.py} +31 -24
- package/server/nodes/google/gmail_receive/icon.svg +7 -0
- package/server/nodes/google/gmail_receive/meta.json +3 -0
- package/server/nodes/google/google.svg +7 -0
- package/server/nodes/google/{sheets.py → sheets/__init__.py} +54 -42
- package/server/nodes/google/sheets/meta.json +3 -0
- package/server/nodes/google/{tasks.py → tasks/__init__.py} +56 -43
- package/server/nodes/google/tasks/meta.json +3 -0
- package/server/nodes/groups.py +28 -28
- package/server/nodes/location/__init__.py +31 -1
- package/server/nodes/location/_credentials.py +1 -6
- package/server/nodes/location/_service.py +88 -107
- package/server/nodes/location/{gmaps_create.py → gmaps_create/__init__.py} +6 -6
- package/server/nodes/location/gmaps_create/meta.json +3 -0
- package/server/nodes/location/{gmaps_locations.py → gmaps_locations/__init__.py} +8 -6
- package/server/nodes/location/gmaps_locations/meta.json +3 -0
- package/server/nodes/location/{gmaps_nearby_places.py → gmaps_nearby_places/__init__.py} +8 -6
- package/server/nodes/location/gmaps_nearby_places/meta.json +3 -0
- package/server/nodes/model/_base.py +10 -7
- package/server/nodes/model/_credentials.py +10 -10
- package/server/nodes/model/_local_validator.py +28 -24
- package/server/nodes/model/{anthropic_chat_model.py → anthropic_chat_model/__init__.py} +5 -3
- package/server/nodes/model/anthropic_chat_model/meta.json +3 -0
- package/server/nodes/model/{cerebras_chat_model.py → cerebras_chat_model/__init__.py} +5 -3
- package/server/nodes/model/cerebras_chat_model/meta.json +3 -0
- package/server/nodes/model/{deepseek_chat_model.py → deepseek_chat_model/__init__.py} +8 -4
- package/server/nodes/model/deepseek_chat_model/meta.json +3 -0
- package/server/nodes/model/{gemini_chat_model.py → gemini_chat_model/__init__.py} +5 -3
- package/server/nodes/model/gemini_chat_model/meta.json +3 -0
- package/server/nodes/model/{groq_chat_model.py → groq_chat_model/__init__.py} +2 -2
- package/server/nodes/model/groq_chat_model/meta.json +3 -0
- package/server/nodes/model/{kimi_chat_model.py → kimi_chat_model/__init__.py} +2 -2
- package/server/nodes/model/kimi_chat_model/meta.json +3 -0
- package/server/nodes/model/{lmstudio_chat_model.py → lmstudio_chat_model/__init__.py} +2 -2
- package/server/nodes/model/lmstudio_chat_model/meta.json +3 -0
- package/server/nodes/model/{mistral_chat_model.py → mistral_chat_model/__init__.py} +2 -2
- package/server/nodes/model/mistral_chat_model/meta.json +3 -0
- package/server/nodes/model/{ollama_chat_model.py → ollama_chat_model/__init__.py} +2 -2
- package/server/nodes/model/ollama_chat_model/meta.json +3 -0
- package/server/nodes/model/{openai_chat_model.py → openai_chat_model/__init__.py} +8 -4
- package/server/nodes/model/openai_chat_model/meta.json +3 -0
- package/server/nodes/model/{openrouter_chat_model.py → openrouter_chat_model/__init__.py} +8 -4
- package/server/nodes/model/openrouter_chat_model/meta.json +3 -0
- package/server/nodes/proxy/_usage.py +14 -15
- package/server/nodes/proxy/{proxy_config.py → proxy_config/__init__.py} +39 -30
- package/server/nodes/proxy/proxy_config/meta.json +3 -0
- package/server/nodes/proxy/{proxy_request.py → proxy_request/__init__.py} +30 -16
- package/server/nodes/proxy/proxy_request/meta.json +3 -0
- package/server/nodes/proxy/{proxy_status.py → proxy_status/__init__.py} +2 -0
- package/server/nodes/proxy/proxy_status/meta.json +3 -0
- package/server/nodes/scheduler/{cron_scheduler.py → cron_scheduler/__init__.py} +96 -23
- package/server/nodes/scheduler/cron_scheduler/_workflow.py +155 -0
- package/server/nodes/scheduler/cron_scheduler/meta.json +3 -0
- package/server/nodes/scheduler/{timer.py → timer/__init__.py} +6 -5
- package/server/nodes/scheduler/timer/meta.json +3 -0
- package/server/nodes/scraper/_credentials.py +0 -1
- package/server/nodes/scraper/{apify_actor.py → apify_actor/__init__.py} +44 -35
- package/server/nodes/scraper/apify_actor/icon.svg +5 -0
- package/server/nodes/scraper/apify_actor/meta.json +3 -0
- package/server/nodes/scraper/{crawlee_scraper.py → crawlee_scraper/__init__.py} +96 -57
- package/server/nodes/scraper/crawlee_scraper/meta.json +3 -0
- package/server/nodes/search/{brave_search.py → brave_search/__init__.py} +6 -5
- package/server/nodes/search/brave_search/icon.svg +3 -0
- package/server/nodes/search/brave_search/meta.json +3 -0
- package/server/nodes/search/{duckduckgo_search.py → duckduckgo_search/__init__.py} +17 -6
- package/server/nodes/search/duckduckgo_search/meta.json +3 -0
- package/server/nodes/search/{perplexity_search.py → perplexity_search/__init__.py} +4 -5
- package/server/nodes/search/perplexity_search/icon.svg +3 -0
- package/server/nodes/search/perplexity_search/meta.json +3 -0
- package/server/nodes/search/{serper_search.py → serper_search/__init__.py} +32 -25
- package/server/nodes/search/serper_search/icon.svg +3 -0
- package/server/nodes/search/serper_search/meta.json +3 -0
- package/server/nodes/skill/__init__.py +21 -1
- package/server/nodes/skill/_expander.py +75 -0
- package/server/nodes/skill/{master_skill.py → master_skill/__init__.py} +2 -8
- package/server/nodes/skill/master_skill/_events.py +84 -0
- package/server/nodes/skill/master_skill/meta.json +3 -0
- package/server/nodes/skill/{simple_memory.py → simple_memory/__init__.py} +8 -16
- package/server/nodes/skill/simple_memory/meta.json +3 -0
- package/server/nodes/social/_base.py +223 -231
- package/server/nodes/social/{social_receive.py → social_receive/__init__.py} +38 -13
- package/server/nodes/social/social_receive/meta.json +3 -0
- package/server/nodes/social/{social_send.py → social_send/__init__.py} +71 -29
- package/server/nodes/social/social_send/icon.svg +1 -0
- package/server/nodes/social/social_send/meta.json +3 -0
- package/server/nodes/stripe/__init__.py +7 -3
- package/server/nodes/stripe/_credentials.py +0 -1
- package/server/nodes/stripe/_handlers.py +18 -7
- package/server/nodes/stripe/_install.py +14 -15
- package/server/nodes/stripe/_source.py +5 -5
- package/server/nodes/stripe/icon.svg +1 -0
- package/server/nodes/stripe/meta.json +3 -0
- package/server/nodes/stripe/stripe_action.py +4 -4
- package/server/nodes/stripe/stripe_receive.py +6 -9
- package/server/nodes/telegram/__init__.py +13 -0
- package/server/nodes/telegram/_credentials.py +2 -7
- package/server/nodes/telegram/_events.py +167 -0
- package/server/nodes/telegram/_filters.py +3 -11
- package/server/nodes/telegram/_handlers.py +17 -7
- package/server/nodes/telegram/_refresh.py +24 -34
- package/server/nodes/telegram/_service.py +29 -45
- package/server/nodes/telegram/meta.json +3 -0
- package/server/nodes/telegram/telegram.svg +3 -0
- package/server/nodes/telegram/telegram_receive.py +38 -18
- package/server/nodes/telegram/telegram_send.py +21 -19
- package/server/nodes/text/{file_handler.py → file_handler/__init__.py} +7 -1
- package/server/nodes/text/file_handler/meta.json +3 -0
- package/server/nodes/text/{text_generator.py → text_generator/__init__.py} +2 -1
- package/server/nodes/text/text_generator/meta.json +3 -0
- package/server/nodes/tool/{agent_builder.py → agent_builder/__init__.py} +105 -100
- package/server/nodes/tool/agent_builder/_events.py +91 -0
- package/server/nodes/tool/agent_builder/meta.json +3 -0
- package/server/nodes/tool/{calculator_tool.py → calculator_tool/__init__.py} +19 -7
- package/server/nodes/tool/calculator_tool/meta.json +3 -0
- package/server/nodes/tool/{current_time_tool.py → current_time_tool/__init__.py} +6 -4
- package/server/nodes/tool/current_time_tool/meta.json +3 -0
- package/server/nodes/tool/{task_manager.py → task_manager/__init__.py} +17 -18
- package/server/nodes/tool/task_manager/meta.json +3 -0
- package/server/nodes/tool/{write_todos.py → write_todos/__init__.py} +20 -6
- package/server/nodes/tool/write_todos/meta.json +3 -0
- package/server/nodes/trigger/{chat_trigger.py → chat_trigger/__init__.py} +11 -7
- package/server/nodes/trigger/chat_trigger/_events.py +53 -0
- package/server/nodes/trigger/chat_trigger/meta.json +3 -0
- package/server/nodes/trigger/{task_trigger.py → task_trigger/__init__.py} +10 -7
- package/server/nodes/trigger/task_trigger/meta.json +3 -0
- package/server/nodes/trigger/{webhook_trigger.py → webhook_trigger/__init__.py} +10 -7
- package/server/nodes/trigger/webhook_trigger/_events.py +54 -0
- package/server/nodes/trigger/webhook_trigger/meta.json +3 -0
- package/server/nodes/twitter/__init__.py +7 -1
- package/server/nodes/twitter/_base.py +86 -61
- package/server/nodes/twitter/_credentials.py +7 -5
- package/server/nodes/twitter/_events.py +101 -0
- package/server/nodes/twitter/_filters.py +9 -9
- package/server/nodes/twitter/_handlers.py +3 -1
- package/server/nodes/twitter/_oauth.py +1 -2
- package/server/nodes/twitter/_refresh.py +8 -12
- package/server/nodes/twitter/{twitter_receive.py → twitter_receive/__init__.py} +7 -7
- package/server/nodes/twitter/twitter_receive/icon.svg +1 -0
- package/server/nodes/twitter/twitter_receive/meta.json +3 -0
- package/server/nodes/twitter/{twitter_search.py → twitter_search/__init__.py} +16 -11
- package/server/nodes/twitter/twitter_search/icon.svg +1 -0
- package/server/nodes/twitter/twitter_search/meta.json +3 -0
- package/server/nodes/twitter/{twitter_send.py → twitter_send/__init__.py} +60 -27
- package/server/nodes/twitter/twitter_send/icon.svg +1 -0
- package/server/nodes/twitter/twitter_send/meta.json +3 -0
- package/server/nodes/twitter/{twitter_user.py → twitter_user/__init__.py} +34 -19
- package/server/nodes/twitter/twitter_user/icon.svg +1 -0
- package/server/nodes/twitter/twitter_user/meta.json +3 -0
- package/server/nodes/utility/{console.py → console/__init__.py} +17 -22
- package/server/nodes/utility/console/meta.json +3 -0
- package/server/nodes/utility/{http_request.py → http_request/__init__.py} +9 -6
- package/server/nodes/utility/http_request/meta.json +3 -0
- package/server/nodes/utility/{process_manager.py → process_manager/__init__.py} +10 -6
- package/server/nodes/utility/process_manager/meta.json +3 -0
- package/server/nodes/utility/team_monitor/meta.json +3 -0
- package/server/nodes/utility/{webhook_response.py → webhook_response/__init__.py} +12 -7
- package/server/nodes/utility/webhook_response/meta.json +3 -0
- package/server/nodes/visuals.json +69 -251
- package/server/nodes/whatsapp/__init__.py +24 -0
- package/server/nodes/whatsapp/_base.py +283 -338
- package/server/nodes/whatsapp/_credentials.py +44 -0
- package/server/nodes/whatsapp/_events.py +277 -0
- package/server/nodes/whatsapp/_filters.py +36 -37
- package/server/nodes/whatsapp/_handlers.py +2 -0
- package/server/nodes/whatsapp/_option_loaders.py +1 -3
- package/server/nodes/whatsapp/_refresh.py +13 -18
- package/server/nodes/whatsapp/_runtime.py +9 -6
- package/server/nodes/whatsapp/_service.py +89 -152
- package/server/nodes/whatsapp/meta.json +3 -0
- package/server/nodes/whatsapp/whatsapp_db.py +116 -54
- package/server/nodes/whatsapp/whatsapp_receive.py +30 -13
- package/server/nodes/whatsapp/whatsapp_send.py +60 -37
- package/server/nodes/workflow/{start.py → start/__init__.py} +1 -4
- package/server/nodes/workflow/start/meta.json +3 -0
- package/server/package-lock.json +3 -3
- package/server/package.json +3 -0
- package/server/pyproject.toml +39 -10
- package/server/requirements.txt +3 -5
- package/server/routers/__init__.py +1 -1
- package/server/routers/auth.py +16 -56
- package/server/routers/database.py +27 -50
- package/server/routers/nodejs_compat.py +25 -87
- package/server/routers/schemas.py +66 -2
- package/server/routers/webhook.py +12 -12
- package/server/routers/websocket.py +312 -1716
- package/server/routers/workflow.py +28 -53
- package/server/scripts/smoke_test_skills.py +178 -0
- package/server/services/__init__.py +1 -1
- package/server/services/_supervisor/process.py +9 -3
- package/server/services/_supervisor/registry.py +3 -3
- package/server/services/_supervisor/util.py +1 -1
- package/server/services/agent_team.py +15 -43
- package/server/services/agent_teams/__init__.py +17 -0
- package/server/services/agent_teams/handlers.py +195 -0
- package/server/services/ai.py +853 -1108
- package/server/services/auth.py +10 -34
- package/server/services/chat_client.py +5 -34
- package/server/services/circuit_breaker.py +2 -6
- package/server/services/cli_agent/__init__.py +28 -4
- package/server/services/cli_agent/_cli_auth.py +61 -0
- package/server/services/cli_agent/_handlers.py +24 -183
- package/server/services/cli_agent/config.py +5 -8
- package/server/services/cli_agent/factory.py +168 -22
- package/server/services/cli_agent/jsonl_watcher.py +380 -0
- package/server/services/cli_agent/lockfile.py +9 -2
- package/server/services/cli_agent/mcp_server.py +110 -34
- package/server/services/cli_agent/protocol.py +37 -19
- package/server/services/cli_agent/providers/__init__.py +8 -4
- package/server/services/cli_agent/providers/google_gemini.py +11 -5
- package/server/services/cli_agent/providers/openai_codex.py +34 -34
- package/server/services/cli_agent/service.py +245 -83
- package/server/services/cli_agent/session.py +409 -229
- package/server/services/cli_agent/transports/__init__.py +47 -0
- package/server/services/cli_agent/transports/base.py +111 -0
- package/server/services/cli_agent/transports/posix.py +196 -0
- package/server/services/cli_agent/transports/windows.py +189 -0
- package/server/services/cli_agent/types.py +45 -18
- package/server/services/cli_agent/workflow_tools.py +28 -15
- package/server/services/compaction.py +68 -52
- package/server/services/credential_registry.py +6 -20
- package/server/services/credentials/__init__.py +18 -0
- package/server/services/credentials/handlers.py +196 -0
- package/server/services/deployment/__init__.py +12 -1
- package/server/services/deployment/canary_registry.py +137 -0
- package/server/services/deployment/handlers.py +382 -0
- package/server/services/deployment/manager.py +653 -163
- package/server/services/deployment/poll_registry.py +2 -6
- package/server/services/deployment/state.py +2 -0
- package/server/services/deployment/triggers.py +87 -93
- package/server/services/event_waiter.py +47 -54
- package/server/services/events/__init__.py +11 -0
- package/server/services/events/admin_handlers.py +368 -0
- package/server/services/events/daemon.py +3 -1
- package/server/services/events/dispatch.py +188 -0
- package/server/services/events/envelope.py +264 -45
- package/server/services/events/oauth_lifecycle.py +98 -42
- package/server/services/events/triggers.py +3 -13
- package/server/services/events/verifiers/hmac_basic.py +1 -1
- package/server/services/events/verifiers/standard_webhooks.py +2 -4
- package/server/services/events/webhook.py +2 -3
- package/server/services/example_loader.py +73 -15
- package/server/services/execution/cache.py +36 -76
- package/server/services/execution/conditions.py +7 -20
- package/server/services/execution/dlq.py +20 -24
- package/server/services/execution/executor.py +234 -265
- package/server/services/execution/models.py +40 -46
- package/server/services/execution/recovery.py +23 -46
- package/server/services/handlers/__init__.py +12 -16
- package/server/services/handlers/todo.py +3 -6
- package/server/services/handlers/tools.py +143 -194
- package/server/services/handlers/triggers.py +24 -23
- package/server/services/llm/config.py +10 -1
- package/server/services/llm/factory.py +16 -4
- package/server/services/llm/messages.py +1 -5
- package/server/services/llm/protocol.py +9 -1
- package/server/services/llm/providers/anthropic.py +23 -12
- package/server/services/llm/providers/gemini.py +43 -22
- package/server/services/llm/providers/openai.py +14 -6
- package/server/services/llm/providers/openrouter.py +6 -1
- package/server/services/markdown_formatter.py +1 -2
- package/server/services/memory/__init__.py +2 -2
- package/server/services/memory/jsonl.py +6 -2
- package/server/services/memory/markdown.py +6 -6
- package/server/services/memory/state.py +6 -5
- package/server/services/memory_store.py +8 -12
- package/server/services/model_registry.py +22 -20
- package/server/services/node_executor.py +85 -80
- package/server/services/node_output_schemas.py +4 -7
- package/server/services/node_registry.py +40 -4
- package/server/services/node_spec.py +3 -7
- package/server/services/nodejs_client.py +4 -14
- package/server/services/oauth_utils.py +11 -7
- package/server/services/parameter_resolver.py +30 -36
- package/server/services/plugin/base.py +321 -38
- package/server/services/plugin/connection.py +12 -7
- package/server/services/plugin/credential.py +80 -22
- package/server/services/plugin/edge_walker.py +128 -105
- package/server/services/plugin/identifiers.py +48 -0
- package/server/services/plugin/interceptor.py +1 -1
- package/server/services/plugin/oauth.py +25 -21
- package/server/services/plugin/operation.py +1 -1
- package/server/services/plugin/polling.py +151 -26
- package/server/services/plugin/registry.py +52 -4
- package/server/services/plugin/routing.py +6 -9
- package/server/services/plugin/scaling.py +36 -18
- package/server/services/plugin/service_factories.py +95 -0
- package/server/services/plugin/shutdown_hooks.py +103 -0
- package/server/services/plugin/social_provider_registry.py +80 -0
- package/server/services/plugin/ws.py +2 -1
- package/server/services/pricing.py +26 -40
- package/server/services/pricing_handlers.py +90 -0
- package/server/services/process_service.py +33 -32
- package/server/services/proxy/models.py +15 -9
- package/server/services/proxy/service.py +26 -40
- package/server/services/rlm/adapters.py +43 -40
- package/server/services/rlm/constants.py +9 -9
- package/server/services/rlm/service.py +57 -45
- package/server/services/scheduler.py +8 -39
- package/server/services/settings/__init__.py +16 -0
- package/server/services/settings/handlers.py +275 -0
- package/server/services/skill_loader.py +53 -45
- package/server/services/skill_prompt.py +8 -6
- package/server/services/skills/__init__.py +23 -0
- package/server/services/skills/handlers.py +479 -0
- package/server/services/status_broadcaster.py +314 -291
- package/server/services/temporal/__init__.py +22 -1
- package/server/services/temporal/_handlers.py +65 -0
- package/server/services/temporal/_install.py +158 -0
- package/server/services/temporal/_refresh.py +57 -0
- package/server/services/temporal/_retry_policies.py +85 -0
- package/server/services/temporal/_runtime.py +181 -0
- package/server/services/temporal/_supervised_runtime.py +102 -0
- package/server/services/temporal/activities.py +168 -11
- package/server/services/temporal/agent_activities.py +683 -0
- package/server/services/temporal/agent_workflow.py +601 -0
- package/server/services/temporal/client.py +58 -13
- package/server/services/temporal/executor.py +2 -3
- package/server/services/temporal/plugin_activities.py +37 -2
- package/server/services/temporal/plugin_registry.py +82 -0
- package/server/services/temporal/polling_trigger_workflow.py +267 -0
- package/server/services/temporal/schedules.py +220 -0
- package/server/services/temporal/search_attributes.py +177 -0
- package/server/services/temporal/trigger_listener_workflow.py +378 -0
- package/server/services/temporal/worker.py +111 -18
- package/server/services/temporal/workflow.py +259 -40
- package/server/services/temporal/ws_client.py +22 -11
- package/server/services/text.py +14 -28
- package/server/services/tracked_http.py +29 -49
- package/server/services/user_auth.py +7 -21
- package/server/services/workflow.py +28 -20
- package/server/services/workflow_import.py +351 -0
- package/server/services/workflow_ops.py +4 -0
- package/server/services/workflow_storage/__init__.py +18 -0
- package/server/services/workflow_storage/handlers.py +132 -0
- package/server/services/workflow_validator.py +209 -0
- package/server/services/ws_handler_registry.py +80 -9
- package/server/skills/assistant/agent-builder-skill/SKILL.md +6 -6
- package/server/tests/conftest.py +54 -3
- package/server/tests/credentials/test_auth_service.py +9 -21
- package/server/tests/credentials/test_credential_broadcasts.py +116 -22
- package/server/tests/credentials/test_credentials_database.py +12 -38
- package/server/tests/credentials/test_encryption.py +3 -9
- package/server/tests/credentials/test_google_oauth.py +1 -3
- package/server/tests/credentials/test_oauth_utils.py +31 -38
- package/server/tests/credentials/test_twitter_oauth.py +1 -3
- package/server/tests/credentials/test_websocket_handlers.py +37 -72
- package/server/tests/fixtures/tool_names_snapshot.json +78 -0
- package/server/tests/llm/test_factory.py +12 -4
- package/server/tests/llm/test_providers.py +25 -32
- package/server/tests/llm/test_wiring.py +27 -22
- package/server/tests/nodes/_compat.py +4 -5
- package/server/tests/nodes/_harness.py +31 -24
- package/server/tests/nodes/_mocks.py +2 -6
- package/server/tests/nodes/test_agent_builder.py +43 -35
- package/server/tests/nodes/test_ai_agents.py +29 -24
- package/server/tests/nodes/test_ai_chat_models.py +3 -9
- package/server/tests/nodes/test_ai_tools.py +29 -24
- package/server/tests/nodes/test_android.py +34 -64
- package/server/tests/nodes/test_chat_utility.py +2 -2
- package/server/tests/nodes/test_code_fs_process.py +26 -84
- package/server/tests/nodes/test_document.py +23 -47
- package/server/tests/nodes/test_email.py +88 -51
- package/server/tests/nodes/test_google_workspace.py +26 -20
- package/server/tests/nodes/test_http_proxy.py +43 -89
- package/server/tests/nodes/test_search.py +3 -9
- package/server/tests/nodes/test_specialized_agents.py +58 -162
- package/server/tests/nodes/test_stripe_plugin.py +25 -5
- package/server/tests/nodes/test_telegram_social.py +33 -37
- package/server/tests/nodes/test_twitter.py +59 -150
- package/server/tests/nodes/test_web_automation.py +21 -51
- package/server/tests/nodes/test_whatsapp.py +13 -19
- package/server/tests/nodes/test_workflow_triggers.py +16 -45
- package/server/tests/services/cli_agent/test_claude_session_events.py +201 -0
- package/server/tests/services/cli_agent/test_jsonl_watcher.py +190 -0
- package/server/tests/services/cli_agent/test_mcp_server.py +67 -29
- package/server/tests/services/cli_agent/test_providers.py +236 -47
- package/server/tests/services/cli_agent/test_service.py +9 -7
- package/server/tests/services/memory/test_jsonl.py +30 -25
- package/server/tests/services/test_events.py +26 -7
- package/server/tests/services/test_identifiers.py +122 -0
- package/server/tests/services/test_process_lifecycle.py +129 -0
- package/server/tests/services/test_supervisor.py +0 -1
- package/server/tests/temporal/__init__.py +0 -0
- package/server/tests/temporal/test_agent_workflow.py +215 -0
- package/server/tests/temporal/test_dispatch.py +231 -0
- package/server/tests/test_admin_handlers.py +394 -0
- package/server/tests/test_auto_skill.py +4 -2
- package/server/tests/test_canary_registry.py +310 -0
- package/server/tests/test_chat_trigger_canary_producer.py +101 -0
- package/server/tests/test_cloudevents_node_parameters.py +129 -0
- package/server/tests/test_credential_icon.py +115 -0
- package/server/tests/test_cron_canary.py +511 -0
- package/server/tests/test_deployment_canary_listener.py +692 -0
- package/server/tests/test_event_framework_phase_a.py +537 -0
- package/server/tests/test_no_raw_prints.py +131 -0
- package/server/tests/test_node_spec.py +196 -103
- package/server/tests/test_parameter_resolver.py +20 -20
- package/server/tests/test_plugin_contract.py +76 -49
- package/server/tests/test_plugin_helpers.py +0 -1
- package/server/tests/test_plugin_self_containment.py +40 -47
- package/server/tests/test_polling_trigger_workflow.py +572 -0
- package/server/tests/test_retry_policies.py +146 -0
- package/server/tests/test_service_factories.py +168 -0
- package/server/tests/test_shutdown_hooks.py +199 -0
- package/server/tests/test_social_provider_registry.py +177 -0
- package/server/tests/test_status_broadcasts.py +214 -63
- package/server/tests/test_task_trigger_canary_producer.py +131 -0
- package/server/tests/test_telegram_trigger_canary_producer.py +113 -0
- package/server/tests/test_tool_registry.py +110 -0
- package/server/tests/test_trigger_listener_workflow.py +365 -0
- package/server/tests/test_whatsapp_trigger_canary_producer.py +164 -0
- package/server/tests/test_workflow_ops.py +1 -3
- package/server/tests/test_workflow_validator.py +791 -0
- package/server/uv.lock +3539 -0
- package/client/dist/assets/index-DQ0nwhec.js +0 -257
- package/client/src/assets/icons/apify/index.ts +0 -19
- package/client/src/assets/icons/browser/index.ts +0 -17
- package/client/src/assets/icons/email/index.ts +0 -22
- package/client/src/assets/icons/google/index.ts +0 -34
- package/client/src/assets/icons/llm/deepseek.svg +0 -1
- package/client/src/assets/icons/llm/index.ts +0 -18
- package/client/src/assets/icons/llm/kimi.svg +0 -1
- package/client/src/assets/icons/llm/mistral.svg +0 -1
- package/client/src/assets/icons/search/index.ts +0 -28
- package/client/src/assets/icons/telegram/index.ts +0 -19
- package/machina/buildenv.py +0 -44
- package/machina/cli.py +0 -55
- package/machina/commands/__init__.py +0 -1
- package/machina/commands/clean.py +0 -80
- package/machina/commands/daemon.py +0 -150
- package/machina/config.py +0 -93
- package/machina/platform_.py +0 -37
- package/machina/pyproject.toml +0 -33
- package/server/nodes/agent/deep_agent.py +0 -103
- package/server/services/agents/__init__.py +0 -9
- package/server/services/agents/adapters.py +0 -199
- package/server/services/agents/constants.py +0 -10
- package/server/services/agents/service.py +0 -297
- package/server/services/cli_agent/providers/anthropic_claude.py +0 -419
- /package/{machina → cli}/README.md +0 -0
- /package/{machina → cli}/__init__.py +0 -0
- /package/{client/src/assets/icons/apify → server/credentials/icons}/apify.svg +0 -0
- /package/{client/src/assets/icons/search/brave.svg → server/credentials/icons/brave_search.svg} +0 -0
- /package/{client/src/assets/icons/email/read.svg → server/credentials/icons/email_himalaya.svg} +0 -0
- /package/{client/src/assets/icons/search → server/credentials/icons}/perplexity.svg +0 -0
- /package/{client/src/assets/icons/search/google.svg → server/credentials/icons/serper.svg} +0 -0
- /package/{client/src/assets → server/credentials}/icons/stripe.svg +0 -0
- /package/{client/src/assets/icons/twitter/x.svg → server/credentials/icons/twitter.svg} +0 -0
- /package/{client/src/assets/icons/browser/chrome.svg → server/nodes/browser/browser/icon.svg} +0 -0
- /package/{client/src/assets/icons/chat/chat.svg → server/nodes/chat/chat_history/icon.svg} +0 -0
- /package/{client/src/assets/icons/code/javascript.svg → server/nodes/code/javascript_executor/icon.svg} +0 -0
- /package/{client/src/assets/icons/code/python.svg → server/nodes/code/python_executor/icon.svg} +0 -0
- /package/{client/src/assets/icons/code/typescript.svg → server/nodes/code/typescript_executor/icon.svg} +0 -0
- /package/{client/src/assets/icons/email/receive.svg → server/nodes/email/email_receive/icon.svg} +0 -0
- /package/{client/src/assets/icons/email/send.svg → server/nodes/email/email_send/icon.svg} +0 -0
- /package/{client/src/assets/icons/google/calendar.svg → server/nodes/google/calendar/icon.svg} +0 -0
- /package/{client/src/assets/icons/google/contacts.svg → server/nodes/google/contacts/icon.svg} +0 -0
- /package/{client/src/assets/icons/google/drive.svg → server/nodes/google/drive/icon.svg} +0 -0
- /package/{client/src/assets/icons/google/gmail.svg → server/nodes/google/gmail/icon.svg} +0 -0
- /package/{client/src/assets/icons/google/sheets.svg → server/nodes/google/sheets/icon.svg} +0 -0
- /package/{client/src/assets/icons/google/tasks.svg → server/nodes/google/tasks/icon.svg} +0 -0
- /package/{client/src/assets/icons/search/duckduckgo.svg → server/nodes/search/duckduckgo_search/icon.svg} +0 -0
- /package/{client/src/assets/icons/social/social.svg → server/nodes/social/social_receive/icon.svg} +0 -0
- /package/{client/src/assets/icons/telegram/telegram.svg → server/nodes/telegram/icon.svg} +0 -0
- /package/server/nodes/utility/{team_monitor.py → team_monitor/__init__.py} +0 -0
- /package/{client/src/assets/icons/whatsapp/whatsapp-db.svg → server/nodes/whatsapp/icon_whatsappDb.svg} +0 -0
- /package/{client/src/assets/icons/whatsapp/whatsapp-receive.svg → server/nodes/whatsapp/icon_whatsappReceive.svg} +0 -0
- /package/{client/src/assets/icons/whatsapp/whatsapp-send.svg → server/nodes/whatsapp/icon_whatsappSend.svg} +0 -0
- /package/{client/src/assets/icons → server/nodes}/whatsapp/whatsapp.svg +0 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"""``machina clean`` -- reset the repo to a fresh-checkout state.
|
|
2
|
+
|
|
3
|
+
Recovery verb: must work even when the env is partially broken
|
|
4
|
+
(missing ``rich`` / ``psutil`` / ``platformdirs`` wheels, half-wiped
|
|
5
|
+
``server/.venv``, etc.). Everything at module load is stdlib + first-party
|
|
6
|
+
helpers (``cli._common`` / ``cli.config`` / ``cli.platform_``). The
|
|
7
|
+
process-killing step (which needs ``psutil`` via :mod:`cli.ports`) is
|
|
8
|
+
lazy-imported inside :func:`clean_command` and degrades to a warning
|
|
9
|
+
if the wheel is missing -- file removal continues regardless.
|
|
10
|
+
|
|
11
|
+
Stops every process listening on the configured ports + orphaned
|
|
12
|
+
project processes, waits for file locks to release, then removes build
|
|
13
|
+
artefacts and venvs.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import shutil
|
|
19
|
+
import time
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
from cli._common import free_all_ports, preflight
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Removed each run -- order doesn't matter, ``shutil.rmtree`` is recursive.
|
|
26
|
+
# Only project-local artefacts. Home-rooted state (``~/.machina/``,
|
|
27
|
+
# ``~/.claude/``, etc.) is the user's; we never touch it from
|
|
28
|
+
# ``machina clean``.
|
|
29
|
+
_TARGETS = [
|
|
30
|
+
"node_modules",
|
|
31
|
+
"client/node_modules",
|
|
32
|
+
"client/dist",
|
|
33
|
+
"client/.vite",
|
|
34
|
+
# Python venvs. ``server/.venv`` is uv's default location for the
|
|
35
|
+
# server's standalone project. ``.venv`` at the repo root is a
|
|
36
|
+
# leftover from the brief workspace-layout experiment -- harmless
|
|
37
|
+
# to wipe alongside if present.
|
|
38
|
+
"server/.venv",
|
|
39
|
+
".venv",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# Children of ``<repo>/.machina/`` to wipe selectively. The bare
|
|
44
|
+
# ``.machina`` entry can't go in ``_TARGETS`` anymore because the
|
|
45
|
+
# ``workflows/`` subtree holds shipped example seeds (git-tracked,
|
|
46
|
+
# imported on first launch by ``services.example_loader``) -- wiping
|
|
47
|
+
# it would force the operator to re-clone to recover. Anything else
|
|
48
|
+
# under ``.machina/`` (claude state, workspaces, credentials.db, ...)
|
|
49
|
+
# is transient runtime state and is fair game.
|
|
50
|
+
_MACHINA_KEEP = frozenset({"workflows"})
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _rmtree_with_retry(path: Path, *, attempts: int = 3, delay: float = 0.1) -> bool:
|
|
54
|
+
"""``shutil.rmtree`` with Windows-friendly retry on file-lock errors."""
|
|
55
|
+
for attempt in range(attempts):
|
|
56
|
+
try:
|
|
57
|
+
shutil.rmtree(path, ignore_errors=False)
|
|
58
|
+
return True
|
|
59
|
+
except OSError as exc:
|
|
60
|
+
if attempt == attempts - 1:
|
|
61
|
+
print(f" warning: could not remove {path.name}: {exc}")
|
|
62
|
+
return False
|
|
63
|
+
time.sleep(delay)
|
|
64
|
+
return False
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _kill_running_processes(cfg, root: Path) -> bool:
|
|
68
|
+
"""Best-effort: kill anything on configured ports + orphaned project
|
|
69
|
+
processes. Returns True if anything was killed (so the caller knows
|
|
70
|
+
to wait for file locks to release before deleting directories).
|
|
71
|
+
|
|
72
|
+
The process-killing path needs ``psutil`` (via :mod:`cli.ports`). If
|
|
73
|
+
it isn't importable -- partially broken env -- we print a warning
|
|
74
|
+
and skip; the directory-removal step still runs.
|
|
75
|
+
"""
|
|
76
|
+
try:
|
|
77
|
+
results = free_all_ports(cfg)
|
|
78
|
+
# ``free_all_ports`` itself lazy-imports ``cli.ports`` -- the
|
|
79
|
+
# outer try/except catches the ImportError if psutil is gone.
|
|
80
|
+
from cli.ports import kill_orphaned_machina_processes
|
|
81
|
+
except ImportError as exc:
|
|
82
|
+
print(f" warning: psutil unavailable ({exc.name}); skipping process cleanup")
|
|
83
|
+
return False
|
|
84
|
+
|
|
85
|
+
killed_ports = 0
|
|
86
|
+
for port, result in zip(cfg.all_ports, results):
|
|
87
|
+
if result.killed_pids:
|
|
88
|
+
print(f" port {port}: killed {len(result.killed_pids)} process(es)")
|
|
89
|
+
killed_ports += len(result.killed_pids)
|
|
90
|
+
|
|
91
|
+
orphaned = kill_orphaned_machina_processes(str(root), exclude_substring="-m cli")
|
|
92
|
+
if orphaned:
|
|
93
|
+
print(f" orphaned: killed {len(orphaned)} process(es)")
|
|
94
|
+
|
|
95
|
+
return bool(killed_ports or orphaned)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def clean_command() -> None:
|
|
99
|
+
cfg, root = preflight()
|
|
100
|
+
|
|
101
|
+
print("Cleaning MachinaOS...")
|
|
102
|
+
|
|
103
|
+
# Step 1+2: kill running processes (best-effort, may degrade)
|
|
104
|
+
print("Stopping running processes...")
|
|
105
|
+
killed_any = _kill_running_processes(cfg, root)
|
|
106
|
+
if killed_any:
|
|
107
|
+
print(" waiting for processes to release file locks...")
|
|
108
|
+
time.sleep(1.0)
|
|
109
|
+
else:
|
|
110
|
+
print(" no running processes found.")
|
|
111
|
+
|
|
112
|
+
# Step 3: remove top-level artefact directories
|
|
113
|
+
print()
|
|
114
|
+
print("Removing directories...")
|
|
115
|
+
for target in _TARGETS:
|
|
116
|
+
path = root / target
|
|
117
|
+
if path.exists():
|
|
118
|
+
print(f" removing: {target}")
|
|
119
|
+
_rmtree_with_retry(path)
|
|
120
|
+
|
|
121
|
+
# Step 4: selectively clean ``<repo>/.machina/`` -- preserve
|
|
122
|
+
# ``workflows/`` (shipped example seeds, see ``_MACHINA_KEEP``);
|
|
123
|
+
# wipe everything else (claude/, workspaces/, *.db, ...) so the
|
|
124
|
+
# repo-local DATA_DIR opt-out gets the same fresh-state treatment.
|
|
125
|
+
machina_dir = root / ".machina"
|
|
126
|
+
if machina_dir.is_dir():
|
|
127
|
+
for child in machina_dir.iterdir():
|
|
128
|
+
if child.name in _MACHINA_KEEP:
|
|
129
|
+
continue
|
|
130
|
+
rel = f".machina/{child.name}"
|
|
131
|
+
print(f" removing: {rel}")
|
|
132
|
+
if child.is_dir():
|
|
133
|
+
_rmtree_with_retry(child)
|
|
134
|
+
else:
|
|
135
|
+
try:
|
|
136
|
+
child.unlink()
|
|
137
|
+
except OSError as exc:
|
|
138
|
+
print(f" warning: could not remove {rel}: {exc}")
|
|
139
|
+
|
|
140
|
+
print()
|
|
141
|
+
print("Done.")
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""``machina daemon`` -- run the backend as a detached process.
|
|
2
|
+
|
|
3
|
+
Pure-Python, all-platforms. No NSSM / systemd / launchd integration.
|
|
4
|
+
Spawns ``uvicorn main:app`` in a new session (POSIX) or detached
|
|
5
|
+
process group (Windows), writes the PID under the project's
|
|
6
|
+
user-data dir (see :func:`cli.platform_.user_data_dir`), and uses
|
|
7
|
+
``psutil`` for tree-kill on stop.
|
|
8
|
+
|
|
9
|
+
Package layout (verb-per-file, following pdm's ``commands/venv/`` and
|
|
10
|
+
hatch's per-verb-folder convention):
|
|
11
|
+
|
|
12
|
+
- :mod:`._state` -- ``pid_dir`` / ``pid_file`` / ``read_pid`` /
|
|
13
|
+
``kill_tree`` / ``detached_kwargs`` (lazy --
|
|
14
|
+
no module-level side effects)
|
|
15
|
+
- :mod:`.start` -- ``daemon start`` verb
|
|
16
|
+
- :mod:`.stop` -- ``daemon stop`` verb
|
|
17
|
+
- :mod:`.status` -- ``daemon status`` verb
|
|
18
|
+
- :mod:`.restart` -- ``daemon restart`` verb
|
|
19
|
+
|
|
20
|
+
For boot-time auto-start, configure your OS service manager separately
|
|
21
|
+
(``systemctl``, ``launchctl``, Task Scheduler) -- this CLI does not
|
|
22
|
+
register itself with the system.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
import typer
|
|
28
|
+
|
|
29
|
+
# The ``app`` Typer instance is declared FIRST so the verb modules can
|
|
30
|
+
# import it via ``from . import app`` and register themselves via
|
|
31
|
+
# ``@app.command``. The verb-module imports BELOW are what trigger that
|
|
32
|
+
# registration -- without them, ``machina daemon`` would be empty.
|
|
33
|
+
app = typer.Typer(
|
|
34
|
+
name="daemon",
|
|
35
|
+
help="Run the MachinaOs backend as a detached process.",
|
|
36
|
+
no_args_is_help=True,
|
|
37
|
+
add_completion=False,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Import order matters only for ``restart`` (which imports ``start_command``
|
|
41
|
+
# + ``stop_command``); list those two first for clarity, then the rest.
|
|
42
|
+
from . import start # noqa: E402,F401
|
|
43
|
+
from . import stop # noqa: E402,F401
|
|
44
|
+
from . import status # noqa: E402,F401
|
|
45
|
+
from . import restart # noqa: E402,F401
|
|
46
|
+
|
|
47
|
+
__all__ = ["app"]
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Shared state for the ``machina daemon`` verbs.
|
|
2
|
+
|
|
3
|
+
PID-file location, detached-spawn kwargs, and the ``psutil``-backed
|
|
4
|
+
tree-kill helper that ``start`` / ``stop`` / ``status`` / ``restart``
|
|
5
|
+
all need. Lives in its own module so each verb file imports only what
|
|
6
|
+
it uses -- no module-level side effects (the PID-dir resolution
|
|
7
|
+
happens inside :func:`pid_dir`, not at import time, so importing this
|
|
8
|
+
module is cheap and doesn't depend on ``platformdirs`` being available
|
|
9
|
+
until the verb actually runs).
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import subprocess
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
import psutil
|
|
18
|
+
|
|
19
|
+
from cli.platform_ import IS_WINDOWS, user_data_dir
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
_PID_FILENAME = "machina-backend.pid"
|
|
23
|
+
_LOG_FILENAME = "backend.log"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def pid_dir() -> Path:
|
|
27
|
+
"""Project's user-data directory -- created on demand by callers."""
|
|
28
|
+
return user_data_dir()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def pid_file() -> Path:
|
|
32
|
+
"""Path to the daemon's PID file."""
|
|
33
|
+
return pid_dir() / _PID_FILENAME
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def log_file() -> Path:
|
|
37
|
+
"""Path to the daemon's stdout/stderr log file."""
|
|
38
|
+
return pid_dir() / _LOG_FILENAME
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def detached_kwargs() -> dict:
|
|
42
|
+
"""Cross-platform "spawn detached, survive parent exit" kwargs.
|
|
43
|
+
|
|
44
|
+
Windows: ``CREATE_NEW_PROCESS_GROUP`` enables later ``CTRL_BREAK_EVENT``;
|
|
45
|
+
``DETACHED_PROCESS`` releases the console handle.
|
|
46
|
+
POSIX: ``start_new_session`` puts the child in its own session, so
|
|
47
|
+
killing the parent (this CLI) doesn't take the daemon down.
|
|
48
|
+
"""
|
|
49
|
+
if IS_WINDOWS:
|
|
50
|
+
return {
|
|
51
|
+
"creationflags": (
|
|
52
|
+
subprocess.DETACHED_PROCESS | subprocess.CREATE_NEW_PROCESS_GROUP
|
|
53
|
+
),
|
|
54
|
+
}
|
|
55
|
+
return {"start_new_session": True}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def read_pid() -> int | None:
|
|
59
|
+
"""Return the live PID from the PID file, or ``None`` if absent /
|
|
60
|
+
corrupt / process no longer exists."""
|
|
61
|
+
pf = pid_file()
|
|
62
|
+
if not pf.exists():
|
|
63
|
+
return None
|
|
64
|
+
try:
|
|
65
|
+
pid = int(pf.read_text().strip())
|
|
66
|
+
except (ValueError, OSError):
|
|
67
|
+
return None
|
|
68
|
+
return pid if psutil.pid_exists(pid) else None
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def kill_tree(pid: int) -> None:
|
|
72
|
+
"""Terminate ``pid`` and all of its descendants. Best-effort.
|
|
73
|
+
|
|
74
|
+
Children are killed first, then the parent is terminated with a
|
|
75
|
+
5-second grace period; falls back to SIGKILL if the parent doesn't
|
|
76
|
+
exit in time. Matches the supervisor's two-phase shutdown
|
|
77
|
+
semantics.
|
|
78
|
+
"""
|
|
79
|
+
try:
|
|
80
|
+
proc = psutil.Process(pid)
|
|
81
|
+
except psutil.NoSuchProcess:
|
|
82
|
+
return
|
|
83
|
+
for child in proc.children(recursive=True):
|
|
84
|
+
try:
|
|
85
|
+
child.kill()
|
|
86
|
+
except psutil.NoSuchProcess:
|
|
87
|
+
pass
|
|
88
|
+
try:
|
|
89
|
+
proc.terminate()
|
|
90
|
+
proc.wait(timeout=5)
|
|
91
|
+
except psutil.NoSuchProcess:
|
|
92
|
+
return
|
|
93
|
+
except psutil.TimeoutExpired:
|
|
94
|
+
try:
|
|
95
|
+
proc.kill()
|
|
96
|
+
except psutil.NoSuchProcess:
|
|
97
|
+
pass
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""``machina daemon restart`` -- stop then start."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from . import app
|
|
6
|
+
from .start import start_command
|
|
7
|
+
from .stop import stop_command
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@app.command("restart")
|
|
11
|
+
def restart_command() -> None:
|
|
12
|
+
"""Stop the backend then start it again; convenience wrapper."""
|
|
13
|
+
stop_command()
|
|
14
|
+
start_command()
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""``machina daemon start`` -- spawn the backend as a detached process."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import subprocess
|
|
6
|
+
|
|
7
|
+
from cli._common import preflight
|
|
8
|
+
from cli.colors import console
|
|
9
|
+
from cli.platform_ import server_dir
|
|
10
|
+
from cli.run import uv_run
|
|
11
|
+
|
|
12
|
+
from . import app
|
|
13
|
+
from ._state import detached_kwargs, log_file, pid_dir, pid_file, read_pid
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@app.command("start")
|
|
17
|
+
def start_command() -> None:
|
|
18
|
+
"""Start the backend in the background; write PID to the project's
|
|
19
|
+
user-data directory."""
|
|
20
|
+
if (existing := read_pid()) is not None:
|
|
21
|
+
console.print(f"[yellow]Already running (pid={existing}).[/]")
|
|
22
|
+
return
|
|
23
|
+
|
|
24
|
+
cfg, root = preflight()
|
|
25
|
+
backend_port = cfg.backend_port
|
|
26
|
+
|
|
27
|
+
pid_dir().mkdir(parents=True, exist_ok=True)
|
|
28
|
+
log_path = log_file()
|
|
29
|
+
log = log_path.open("ab")
|
|
30
|
+
|
|
31
|
+
proc = subprocess.Popen(
|
|
32
|
+
uv_run(
|
|
33
|
+
"uvicorn",
|
|
34
|
+
"main:app",
|
|
35
|
+
"--host",
|
|
36
|
+
"0.0.0.0",
|
|
37
|
+
"--port",
|
|
38
|
+
str(backend_port),
|
|
39
|
+
"--log-level",
|
|
40
|
+
"warning",
|
|
41
|
+
),
|
|
42
|
+
cwd=str(server_dir(root)),
|
|
43
|
+
stdin=subprocess.DEVNULL,
|
|
44
|
+
stdout=log,
|
|
45
|
+
stderr=log,
|
|
46
|
+
**detached_kwargs(),
|
|
47
|
+
)
|
|
48
|
+
pid_file().write_text(str(proc.pid))
|
|
49
|
+
console.print(f"[green]Started pid={proc.pid}[/] (logs: {log_path})")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""``machina daemon status`` -- report whether the backend is running."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
from cli.colors import console
|
|
8
|
+
|
|
9
|
+
from . import app
|
|
10
|
+
from ._state import read_pid
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@app.command("status")
|
|
14
|
+
def status_command() -> None:
|
|
15
|
+
"""Exit 0 if running (and print PID); exit 1 otherwise."""
|
|
16
|
+
pid = read_pid()
|
|
17
|
+
if pid is None:
|
|
18
|
+
console.print("Not running.")
|
|
19
|
+
raise typer.Exit(code=1)
|
|
20
|
+
console.print(f"[green]Running pid={pid}[/]")
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""``machina daemon stop`` -- terminate the detached backend."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from cli.colors import console
|
|
6
|
+
|
|
7
|
+
from . import app
|
|
8
|
+
from ._state import kill_tree, pid_file, read_pid
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@app.command("stop")
|
|
12
|
+
def stop_command() -> None:
|
|
13
|
+
"""Stop the backend if running; clear PID file either way."""
|
|
14
|
+
pid = read_pid()
|
|
15
|
+
pf = pid_file()
|
|
16
|
+
if pid is None:
|
|
17
|
+
console.print("Not running.")
|
|
18
|
+
pf.unlink(missing_ok=True)
|
|
19
|
+
return
|
|
20
|
+
kill_tree(pid)
|
|
21
|
+
pf.unlink(missing_ok=True)
|
|
22
|
+
console.print(f"[green]Stopped pid={pid}[/]")
|
|
@@ -19,19 +19,23 @@ from pathlib import Path
|
|
|
19
19
|
|
|
20
20
|
import typer
|
|
21
21
|
|
|
22
|
-
from
|
|
23
|
-
from
|
|
24
|
-
from
|
|
25
|
-
from
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
from cli._common import build_backend_spec, free_all_ports, preflight
|
|
23
|
+
from cli.colors import console
|
|
24
|
+
from cli.config import load_dev_overrides
|
|
25
|
+
from cli.platform_ import (
|
|
26
|
+
node_modules_dir,
|
|
27
|
+
platform_name,
|
|
28
|
+
static_client_script,
|
|
29
|
+
)
|
|
30
|
+
from cli.buildenv import validate_build
|
|
31
|
+
from cli.supervisor import Manager, ServiceSpec
|
|
32
|
+
from cli.commands._temporal_specs import temporal_specs
|
|
28
33
|
|
|
29
34
|
|
|
30
35
|
def _has_vite(root: Path) -> bool:
|
|
31
|
-
return (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
)
|
|
36
|
+
return (node_modules_dir(root) / "vite").exists() or (
|
|
37
|
+
root / "client" / "node_modules" / "vite"
|
|
38
|
+
).exists()
|
|
35
39
|
|
|
36
40
|
|
|
37
41
|
def _clear_vite_cache(root: Path) -> None:
|
|
@@ -46,9 +50,6 @@ def _clear_vite_cache(root: Path) -> None:
|
|
|
46
50
|
|
|
47
51
|
|
|
48
52
|
def _build_specs(root: Path, cfg, *, daemon: bool, use_vite: bool) -> list[ServiceSpec]:
|
|
49
|
-
static_client = root / "scripts" / "serve-client.js"
|
|
50
|
-
server_dir = root / "server"
|
|
51
|
-
|
|
52
53
|
if use_vite:
|
|
53
54
|
client_spec = ServiceSpec(
|
|
54
55
|
name="client",
|
|
@@ -60,55 +61,44 @@ def _build_specs(root: Path, cfg, *, daemon: bool, use_vite: bool) -> list[Servi
|
|
|
60
61
|
else:
|
|
61
62
|
client_spec = ServiceSpec(
|
|
62
63
|
name="client",
|
|
63
|
-
argv=["node", str(
|
|
64
|
+
argv=["node", str(static_client_script(root))],
|
|
64
65
|
cwd=root,
|
|
65
66
|
ready_port=cfg.client_port,
|
|
66
67
|
)
|
|
67
68
|
|
|
68
69
|
backend_host = "0.0.0.0" if daemon else "127.0.0.1"
|
|
69
|
-
server_spec =
|
|
70
|
-
|
|
71
|
-
argv=[
|
|
72
|
-
"uv", "run", "uvicorn", "main:app",
|
|
73
|
-
"--host", backend_host,
|
|
74
|
-
"--port", str(cfg.backend_port),
|
|
75
|
-
"--log-level", "warning",
|
|
76
|
-
],
|
|
77
|
-
cwd=server_dir,
|
|
78
|
-
ready_port=cfg.backend_port,
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
return [
|
|
82
|
-
client_spec,
|
|
83
|
-
server_spec,
|
|
84
|
-
ServiceSpec(
|
|
85
|
-
name="temporal",
|
|
86
|
-
argv=["temporal", "api"],
|
|
87
|
-
cwd=root,
|
|
88
|
-
ready_port=cfg.temporal_port,
|
|
89
|
-
),
|
|
90
|
-
]
|
|
70
|
+
server_spec = build_backend_spec(cfg, host=backend_host, root=root)
|
|
71
|
+
return [client_spec, server_spec, *temporal_specs(root, cfg)]
|
|
91
72
|
|
|
92
73
|
|
|
93
74
|
def dev_command(
|
|
94
75
|
daemon: bool = typer.Option(
|
|
95
|
-
False,
|
|
76
|
+
False,
|
|
77
|
+
"--daemon",
|
|
78
|
+
help="Bind backend to 0.0.0.0 instead of 127.0.0.1.",
|
|
96
79
|
),
|
|
97
80
|
) -> None:
|
|
98
|
-
|
|
99
|
-
|
|
81
|
+
# Layer ``.env.dev`` (committed) on top of ``.env.template`` + ``.env``
|
|
82
|
+
# so dev state lands at ``<repo>/.machina/`` (per-checkout) instead
|
|
83
|
+
# of ``~/.machina/`` (user home). Called BEFORE ``preflight()`` so
|
|
84
|
+
# ``load_config``'s ``setdefault`` pass sees the dev values already
|
|
85
|
+
# in ``os.environ``. ``machina start`` / ``machina daemon`` skip
|
|
86
|
+
# this hook, falling through to the ``.env.template`` defaults.
|
|
87
|
+
load_dev_overrides()
|
|
88
|
+
cfg, root = preflight()
|
|
100
89
|
os.environ.setdefault("PYTHONUTF8", "1")
|
|
101
90
|
|
|
102
91
|
validate_build(root)
|
|
103
92
|
|
|
104
93
|
console.print("\n[bold]=== MachinaOS Starting ===[/]\n")
|
|
105
94
|
console.print(f"Platform: {platform_name()}")
|
|
106
|
-
console.print(
|
|
95
|
+
console.print(
|
|
96
|
+
f"Mode: {'Daemon (uvicorn)' if daemon else 'Development (uvicorn)'}"
|
|
97
|
+
)
|
|
107
98
|
console.print(f"Ports: {', '.join(str(p) for p in cfg.all_ports)}")
|
|
108
99
|
|
|
109
100
|
console.log("Freeing ports...")
|
|
110
|
-
|
|
111
|
-
kill_port(port)
|
|
101
|
+
free_all_ports(cfg)
|
|
112
102
|
console.log("Ports ready")
|
|
113
103
|
|
|
114
104
|
_clear_vite_cache(root)
|
|
@@ -15,8 +15,8 @@ from pathlib import Path
|
|
|
15
15
|
|
|
16
16
|
import typer
|
|
17
17
|
|
|
18
|
-
from
|
|
19
|
-
from
|
|
18
|
+
from cli.colors import console
|
|
19
|
+
from cli.platform_ import project_root, server_dir
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
app = typer.Typer(
|
|
@@ -52,8 +52,7 @@ def _list_categories(docs_dir: Path) -> list[str]:
|
|
|
52
52
|
if not docs_dir.exists():
|
|
53
53
|
return []
|
|
54
54
|
return sorted(
|
|
55
|
-
d.name for d in docs_dir.iterdir()
|
|
56
|
-
if d.is_dir() and not d.name.startswith("_")
|
|
55
|
+
d.name for d in docs_dir.iterdir() if d.is_dir() and not d.name.startswith("_")
|
|
57
56
|
)
|
|
58
57
|
|
|
59
58
|
|
|
@@ -65,11 +64,13 @@ def _list_docs(docs_dir: Path, category: str) -> list[dict]:
|
|
|
65
64
|
continue
|
|
66
65
|
if path.name.startswith("_") or path.name == "README.md":
|
|
67
66
|
continue
|
|
68
|
-
out.append(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
out.append(
|
|
68
|
+
{
|
|
69
|
+
"rel_path": f"{category}/{path.name}",
|
|
70
|
+
"title": _read_h1(path),
|
|
71
|
+
"node_key": path.stem,
|
|
72
|
+
}
|
|
73
|
+
)
|
|
73
74
|
return out
|
|
74
75
|
|
|
75
76
|
|
|
@@ -125,7 +126,7 @@ def _rewrite_index(root: Path) -> None:
|
|
|
125
126
|
|
|
126
127
|
def _check_completeness(root: Path) -> int:
|
|
127
128
|
documented = _collect_documented_keys(_docs_dir(root))
|
|
128
|
-
registered = _collect_registry_keys(root / "
|
|
129
|
+
registered = _collect_registry_keys(server_dir(root) / "nodes")
|
|
129
130
|
missing = sorted(k for k in registered if k not in documented)
|
|
130
131
|
if not missing:
|
|
131
132
|
console.print(
|
|
@@ -141,7 +142,8 @@ def _check_completeness(root: Path) -> int:
|
|
|
141
142
|
@app.command("nodes", help="Rebuild (or --check) the per-node documentation index.")
|
|
142
143
|
def nodes(
|
|
143
144
|
check: bool = typer.Option(
|
|
144
|
-
False,
|
|
145
|
+
False,
|
|
146
|
+
"--check",
|
|
145
147
|
help="Instead of rewriting, exit 1 if any registered node lacks a doc.",
|
|
146
148
|
),
|
|
147
149
|
) -> None:
|