machinaos 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (288) hide show
  1. package/.env.template +71 -0
  2. package/LICENSE +21 -0
  3. package/README.md +87 -0
  4. package/bin/cli.js +159 -0
  5. package/client/.dockerignore +45 -0
  6. package/client/Dockerfile +68 -0
  7. package/client/eslint.config.js +29 -0
  8. package/client/index.html +13 -0
  9. package/client/nginx.conf +66 -0
  10. package/client/package.json +48 -0
  11. package/client/src/App.tsx +27 -0
  12. package/client/src/Dashboard.tsx +1173 -0
  13. package/client/src/ParameterPanel.tsx +301 -0
  14. package/client/src/components/AIAgentNode.tsx +321 -0
  15. package/client/src/components/APIKeyValidator.tsx +118 -0
  16. package/client/src/components/ClaudeChatModelNode.tsx +18 -0
  17. package/client/src/components/ConditionalEdge.tsx +189 -0
  18. package/client/src/components/CredentialsModal.tsx +306 -0
  19. package/client/src/components/EdgeConditionEditor.tsx +443 -0
  20. package/client/src/components/GeminiChatModelNode.tsx +18 -0
  21. package/client/src/components/GenericNode.tsx +357 -0
  22. package/client/src/components/LocationParameterPanel.tsx +154 -0
  23. package/client/src/components/ModelNode.tsx +286 -0
  24. package/client/src/components/OpenAIChatModelNode.tsx +18 -0
  25. package/client/src/components/OutputPanel.tsx +471 -0
  26. package/client/src/components/ParameterRenderer.tsx +1874 -0
  27. package/client/src/components/SkillEditorModal.tsx +417 -0
  28. package/client/src/components/SquareNode.tsx +797 -0
  29. package/client/src/components/StartNode.tsx +250 -0
  30. package/client/src/components/ToolkitNode.tsx +365 -0
  31. package/client/src/components/TriggerNode.tsx +463 -0
  32. package/client/src/components/auth/LoginPage.tsx +247 -0
  33. package/client/src/components/auth/ProtectedRoute.tsx +59 -0
  34. package/client/src/components/base/BaseChatModelNode.tsx +271 -0
  35. package/client/src/components/icons/AIProviderIcons.tsx +50 -0
  36. package/client/src/components/maps/GoogleMapsPicker.tsx +137 -0
  37. package/client/src/components/maps/MapsPreviewPanel.tsx +110 -0
  38. package/client/src/components/maps/index.ts +26 -0
  39. package/client/src/components/parameterPanel/InputSection.tsx +1094 -0
  40. package/client/src/components/parameterPanel/LocationPanelLayout.tsx +65 -0
  41. package/client/src/components/parameterPanel/MapsSection.tsx +92 -0
  42. package/client/src/components/parameterPanel/MiddleSection.tsx +571 -0
  43. package/client/src/components/parameterPanel/OutputSection.tsx +81 -0
  44. package/client/src/components/parameterPanel/ParameterPanelLayout.tsx +82 -0
  45. package/client/src/components/parameterPanel/ToolSchemaEditor.tsx +436 -0
  46. package/client/src/components/parameterPanel/index.ts +42 -0
  47. package/client/src/components/shared/DataPanel.tsx +142 -0
  48. package/client/src/components/shared/JSONTreeRenderer.tsx +106 -0
  49. package/client/src/components/ui/AIResultModal.tsx +204 -0
  50. package/client/src/components/ui/AndroidSettingsPanel.tsx +401 -0
  51. package/client/src/components/ui/CodeEditor.tsx +81 -0
  52. package/client/src/components/ui/CollapsibleSection.tsx +88 -0
  53. package/client/src/components/ui/ComponentItem.tsx +154 -0
  54. package/client/src/components/ui/ComponentPalette.tsx +321 -0
  55. package/client/src/components/ui/ConsolePanel.tsx +1074 -0
  56. package/client/src/components/ui/ErrorBoundary.tsx +196 -0
  57. package/client/src/components/ui/InputNodesPanel.tsx +204 -0
  58. package/client/src/components/ui/MapSelector.tsx +314 -0
  59. package/client/src/components/ui/Modal.tsx +149 -0
  60. package/client/src/components/ui/NodeContextMenu.tsx +192 -0
  61. package/client/src/components/ui/NodeOutputPanel.tsx +1150 -0
  62. package/client/src/components/ui/OutputDisplayPanel.tsx +381 -0
  63. package/client/src/components/ui/SettingsPanel.tsx +243 -0
  64. package/client/src/components/ui/TopToolbar.tsx +736 -0
  65. package/client/src/components/ui/WhatsAppSettingsPanel.tsx +345 -0
  66. package/client/src/components/ui/WorkflowSidebar.tsx +294 -0
  67. package/client/src/config/antdTheme.ts +186 -0
  68. package/client/src/config/api.ts +54 -0
  69. package/client/src/contexts/AuthContext.tsx +221 -0
  70. package/client/src/contexts/ThemeContext.tsx +42 -0
  71. package/client/src/contexts/WebSocketContext.tsx +1971 -0
  72. package/client/src/factories/baseChatModelFactory.ts +256 -0
  73. package/client/src/hooks/useAndroidOperations.ts +164 -0
  74. package/client/src/hooks/useApiKeyValidation.ts +107 -0
  75. package/client/src/hooks/useApiKeys.ts +238 -0
  76. package/client/src/hooks/useAppTheme.ts +17 -0
  77. package/client/src/hooks/useComponentPalette.ts +51 -0
  78. package/client/src/hooks/useCopyPaste.ts +155 -0
  79. package/client/src/hooks/useDragAndDrop.ts +124 -0
  80. package/client/src/hooks/useDragVariable.ts +88 -0
  81. package/client/src/hooks/useExecution.ts +313 -0
  82. package/client/src/hooks/useParameterPanel.ts +176 -0
  83. package/client/src/hooks/useReactFlowNodes.ts +189 -0
  84. package/client/src/hooks/useToolSchema.ts +209 -0
  85. package/client/src/hooks/useWhatsApp.ts +196 -0
  86. package/client/src/hooks/useWorkflowManagement.ts +46 -0
  87. package/client/src/index.css +315 -0
  88. package/client/src/main.tsx +19 -0
  89. package/client/src/nodeDefinitions/aiAgentNodes.ts +336 -0
  90. package/client/src/nodeDefinitions/aiModelNodes.ts +340 -0
  91. package/client/src/nodeDefinitions/androidDeviceNodes.ts +140 -0
  92. package/client/src/nodeDefinitions/androidServiceNodes.ts +383 -0
  93. package/client/src/nodeDefinitions/chatNodes.ts +135 -0
  94. package/client/src/nodeDefinitions/codeNodes.ts +54 -0
  95. package/client/src/nodeDefinitions/documentNodes.ts +379 -0
  96. package/client/src/nodeDefinitions/index.ts +15 -0
  97. package/client/src/nodeDefinitions/locationNodes.ts +463 -0
  98. package/client/src/nodeDefinitions/schedulerNodes.ts +220 -0
  99. package/client/src/nodeDefinitions/skillNodes.ts +211 -0
  100. package/client/src/nodeDefinitions/toolNodes.ts +198 -0
  101. package/client/src/nodeDefinitions/utilityNodes.ts +284 -0
  102. package/client/src/nodeDefinitions/whatsappNodes.ts +865 -0
  103. package/client/src/nodeDefinitions/workflowNodes.ts +41 -0
  104. package/client/src/nodeDefinitions.ts +104 -0
  105. package/client/src/schemas/workflowSchema.ts +264 -0
  106. package/client/src/services/dynamicParameterService.ts +96 -0
  107. package/client/src/services/execution/aiAgentExecutionService.ts +35 -0
  108. package/client/src/services/executionService.ts +232 -0
  109. package/client/src/services/workflowApi.ts +91 -0
  110. package/client/src/store/useAppStore.ts +582 -0
  111. package/client/src/styles/theme.ts +508 -0
  112. package/client/src/styles/zIndex.ts +17 -0
  113. package/client/src/types/ComponentTypes.ts +39 -0
  114. package/client/src/types/EdgeCondition.ts +231 -0
  115. package/client/src/types/INodeProperties.ts +288 -0
  116. package/client/src/types/NodeTypes.ts +28 -0
  117. package/client/src/utils/formatters.ts +33 -0
  118. package/client/src/utils/googleMapsLoader.ts +140 -0
  119. package/client/src/utils/locationUtils.ts +85 -0
  120. package/client/src/utils/nodeUtils.ts +31 -0
  121. package/client/src/utils/workflow.ts +30 -0
  122. package/client/src/utils/workflowExport.ts +120 -0
  123. package/client/src/vite-env.d.ts +12 -0
  124. package/client/tailwind.config.js +60 -0
  125. package/client/tsconfig.json +25 -0
  126. package/client/tsconfig.node.json +11 -0
  127. package/client/vite.config.js +35 -0
  128. package/docker-compose.prod.yml +107 -0
  129. package/docker-compose.yml +104 -0
  130. package/docs-MachinaOs/README.md +85 -0
  131. package/docs-MachinaOs/deployment/docker.mdx +228 -0
  132. package/docs-MachinaOs/deployment/production.mdx +345 -0
  133. package/docs-MachinaOs/docs.json +75 -0
  134. package/docs-MachinaOs/faq.mdx +309 -0
  135. package/docs-MachinaOs/favicon.svg +5 -0
  136. package/docs-MachinaOs/installation.mdx +160 -0
  137. package/docs-MachinaOs/introduction.mdx +114 -0
  138. package/docs-MachinaOs/logo/dark.svg +6 -0
  139. package/docs-MachinaOs/logo/light.svg +6 -0
  140. package/docs-MachinaOs/nodes/ai-agent.mdx +216 -0
  141. package/docs-MachinaOs/nodes/ai-models.mdx +240 -0
  142. package/docs-MachinaOs/nodes/android.mdx +411 -0
  143. package/docs-MachinaOs/nodes/overview.mdx +181 -0
  144. package/docs-MachinaOs/nodes/schedulers.mdx +316 -0
  145. package/docs-MachinaOs/nodes/webhooks.mdx +330 -0
  146. package/docs-MachinaOs/nodes/whatsapp.mdx +305 -0
  147. package/docs-MachinaOs/quickstart.mdx +119 -0
  148. package/docs-MachinaOs/tutorials/ai-agent-workflow.mdx +177 -0
  149. package/docs-MachinaOs/tutorials/android-automation.mdx +242 -0
  150. package/docs-MachinaOs/tutorials/first-workflow.mdx +134 -0
  151. package/docs-MachinaOs/tutorials/whatsapp-automation.mdx +185 -0
  152. package/nul +0 -0
  153. package/package.json +70 -0
  154. package/scripts/build.js +158 -0
  155. package/scripts/check-ports.ps1 +33 -0
  156. package/scripts/clean.js +40 -0
  157. package/scripts/docker.js +93 -0
  158. package/scripts/kill-port.ps1 +154 -0
  159. package/scripts/start.js +210 -0
  160. package/scripts/stop.js +325 -0
  161. package/server/.dockerignore +44 -0
  162. package/server/Dockerfile +45 -0
  163. package/server/constants.py +249 -0
  164. package/server/core/__init__.py +1 -0
  165. package/server/core/cache.py +461 -0
  166. package/server/core/config.py +128 -0
  167. package/server/core/container.py +99 -0
  168. package/server/core/database.py +1211 -0
  169. package/server/core/logging.py +314 -0
  170. package/server/main.py +289 -0
  171. package/server/middleware/__init__.py +5 -0
  172. package/server/middleware/auth.py +89 -0
  173. package/server/models/__init__.py +1 -0
  174. package/server/models/auth.py +52 -0
  175. package/server/models/cache.py +24 -0
  176. package/server/models/database.py +211 -0
  177. package/server/models/nodes.py +455 -0
  178. package/server/package.json +9 -0
  179. package/server/pyproject.toml +72 -0
  180. package/server/requirements.txt +83 -0
  181. package/server/routers/__init__.py +1 -0
  182. package/server/routers/android.py +294 -0
  183. package/server/routers/auth.py +203 -0
  184. package/server/routers/database.py +151 -0
  185. package/server/routers/maps.py +142 -0
  186. package/server/routers/nodejs_compat.py +289 -0
  187. package/server/routers/webhook.py +90 -0
  188. package/server/routers/websocket.py +2127 -0
  189. package/server/routers/whatsapp.py +761 -0
  190. package/server/routers/workflow.py +200 -0
  191. package/server/services/__init__.py +1 -0
  192. package/server/services/ai.py +2415 -0
  193. package/server/services/android/__init__.py +27 -0
  194. package/server/services/android/broadcaster.py +114 -0
  195. package/server/services/android/client.py +608 -0
  196. package/server/services/android/manager.py +78 -0
  197. package/server/services/android/protocol.py +165 -0
  198. package/server/services/android_service.py +588 -0
  199. package/server/services/auth.py +131 -0
  200. package/server/services/chat_client.py +160 -0
  201. package/server/services/deployment/__init__.py +12 -0
  202. package/server/services/deployment/manager.py +706 -0
  203. package/server/services/deployment/state.py +47 -0
  204. package/server/services/deployment/triggers.py +275 -0
  205. package/server/services/event_waiter.py +785 -0
  206. package/server/services/execution/__init__.py +77 -0
  207. package/server/services/execution/cache.py +769 -0
  208. package/server/services/execution/conditions.py +373 -0
  209. package/server/services/execution/dlq.py +132 -0
  210. package/server/services/execution/executor.py +1351 -0
  211. package/server/services/execution/models.py +531 -0
  212. package/server/services/execution/recovery.py +235 -0
  213. package/server/services/handlers/__init__.py +126 -0
  214. package/server/services/handlers/ai.py +355 -0
  215. package/server/services/handlers/android.py +260 -0
  216. package/server/services/handlers/code.py +278 -0
  217. package/server/services/handlers/document.py +598 -0
  218. package/server/services/handlers/http.py +193 -0
  219. package/server/services/handlers/polyglot.py +105 -0
  220. package/server/services/handlers/tools.py +845 -0
  221. package/server/services/handlers/triggers.py +107 -0
  222. package/server/services/handlers/utility.py +822 -0
  223. package/server/services/handlers/whatsapp.py +476 -0
  224. package/server/services/maps.py +289 -0
  225. package/server/services/memory_store.py +103 -0
  226. package/server/services/node_executor.py +375 -0
  227. package/server/services/parameter_resolver.py +218 -0
  228. package/server/services/polyglot_client.py +169 -0
  229. package/server/services/scheduler.py +155 -0
  230. package/server/services/skill_loader.py +417 -0
  231. package/server/services/status_broadcaster.py +826 -0
  232. package/server/services/temporal/__init__.py +23 -0
  233. package/server/services/temporal/activities.py +344 -0
  234. package/server/services/temporal/client.py +76 -0
  235. package/server/services/temporal/executor.py +147 -0
  236. package/server/services/temporal/worker.py +251 -0
  237. package/server/services/temporal/workflow.py +355 -0
  238. package/server/services/temporal/ws_client.py +236 -0
  239. package/server/services/text.py +111 -0
  240. package/server/services/user_auth.py +172 -0
  241. package/server/services/websocket_client.py +29 -0
  242. package/server/services/workflow.py +597 -0
  243. package/server/skills/android-skill/SKILL.md +82 -0
  244. package/server/skills/assistant-personality/SKILL.md +45 -0
  245. package/server/skills/code-skill/SKILL.md +140 -0
  246. package/server/skills/http-skill/SKILL.md +161 -0
  247. package/server/skills/maps-skill/SKILL.md +170 -0
  248. package/server/skills/memory-skill/SKILL.md +154 -0
  249. package/server/skills/scheduler-skill/SKILL.md +84 -0
  250. package/server/skills/whatsapp-skill/SKILL.md +283 -0
  251. package/server/uv.lock +2916 -0
  252. package/server/whatsapp-rpc/.dockerignore +30 -0
  253. package/server/whatsapp-rpc/Dockerfile +44 -0
  254. package/server/whatsapp-rpc/Dockerfile.web +17 -0
  255. package/server/whatsapp-rpc/README.md +139 -0
  256. package/server/whatsapp-rpc/cli.js +95 -0
  257. package/server/whatsapp-rpc/configs/config.yaml +7 -0
  258. package/server/whatsapp-rpc/docker-compose.yml +35 -0
  259. package/server/whatsapp-rpc/docs/API.md +410 -0
  260. package/server/whatsapp-rpc/go.mod +67 -0
  261. package/server/whatsapp-rpc/go.sum +203 -0
  262. package/server/whatsapp-rpc/package.json +30 -0
  263. package/server/whatsapp-rpc/schema.json +1294 -0
  264. package/server/whatsapp-rpc/scripts/clean.cjs +66 -0
  265. package/server/whatsapp-rpc/scripts/cli.js +162 -0
  266. package/server/whatsapp-rpc/src/go/cmd/server/main.go +91 -0
  267. package/server/whatsapp-rpc/src/go/config/config.go +49 -0
  268. package/server/whatsapp-rpc/src/go/rpc/rpc.go +446 -0
  269. package/server/whatsapp-rpc/src/go/rpc/server.go +112 -0
  270. package/server/whatsapp-rpc/src/go/whatsapp/history.go +166 -0
  271. package/server/whatsapp-rpc/src/go/whatsapp/messages.go +390 -0
  272. package/server/whatsapp-rpc/src/go/whatsapp/service.go +2130 -0
  273. package/server/whatsapp-rpc/src/go/whatsapp/types.go +261 -0
  274. package/server/whatsapp-rpc/src/python/pyproject.toml +15 -0
  275. package/server/whatsapp-rpc/src/python/whatsapp_rpc/__init__.py +4 -0
  276. package/server/whatsapp-rpc/src/python/whatsapp_rpc/client.py +427 -0
  277. package/server/whatsapp-rpc/web/app.py +609 -0
  278. package/server/whatsapp-rpc/web/requirements.txt +6 -0
  279. package/server/whatsapp-rpc/web/rpc_client.py +427 -0
  280. package/server/whatsapp-rpc/web/static/openapi.yaml +59 -0
  281. package/server/whatsapp-rpc/web/templates/base.html +150 -0
  282. package/server/whatsapp-rpc/web/templates/contacts.html +240 -0
  283. package/server/whatsapp-rpc/web/templates/dashboard.html +320 -0
  284. package/server/whatsapp-rpc/web/templates/groups.html +328 -0
  285. package/server/whatsapp-rpc/web/templates/messages.html +465 -0
  286. package/server/whatsapp-rpc/web/templates/messaging.html +681 -0
  287. package/server/whatsapp-rpc/web/templates/send.html +259 -0
  288. package/server/whatsapp-rpc/web/templates/settings.html +459 -0
@@ -0,0 +1,186 @@
1
+ import { ThemeConfig } from 'antd';
2
+ import { solarized, lightColors, darkColors } from '../styles/theme';
3
+
4
+ export const lightTheme: ThemeConfig = {
5
+ token: {
6
+ // Primary colors - using Solarized palette
7
+ colorPrimary: solarized.blue,
8
+ colorSuccess: lightColors.success,
9
+ colorWarning: solarized.yellow,
10
+ colorError: solarized.red,
11
+ colorInfo: solarized.cyan,
12
+
13
+ // Background colors
14
+ colorBgBase: lightColors.background,
15
+ colorBgContainer: lightColors.background,
16
+ colorBgElevated: lightColors.backgroundElevated,
17
+ colorBgLayout: lightColors.backgroundPanel,
18
+
19
+ // Text colors
20
+ colorText: lightColors.text,
21
+ colorTextSecondary: lightColors.textSecondary,
22
+ colorTextTertiary: lightColors.textMuted,
23
+
24
+ // Border colors
25
+ colorBorder: lightColors.border,
26
+ colorBorderSecondary: lightColors.backgroundAlt,
27
+
28
+ // Border and layout
29
+ borderRadius: 6,
30
+ borderRadiusLG: 8,
31
+ borderRadiusOuter: 4,
32
+
33
+ // Typography
34
+ fontSize: 14,
35
+ fontSizeLG: 16,
36
+ fontSizeSM: 12,
37
+ fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
38
+
39
+ // Spacing
40
+ padding: 12,
41
+ paddingLG: 16,
42
+ paddingSM: 8,
43
+ paddingXS: 6,
44
+
45
+ // Component specific
46
+ controlHeight: 32,
47
+ controlHeightSM: 24,
48
+ controlHeightLG: 40,
49
+
50
+ // Box shadow
51
+ boxShadowSecondary: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
52
+ },
53
+ components: {
54
+ Card: {
55
+ borderRadius: 6,
56
+ paddingLG: 12,
57
+ },
58
+ Collapse: {
59
+ borderRadius: 6,
60
+ headerBg: lightColors.backgroundPanel,
61
+ },
62
+ Button: {
63
+ borderRadius: 6,
64
+ },
65
+ Input: {
66
+ borderRadius: 6,
67
+ },
68
+ Select: {
69
+ borderRadius: 6,
70
+ },
71
+ Form: {
72
+ itemMarginBottom: 16,
73
+ verticalLabelPadding: '0 0 4px',
74
+ },
75
+ Typography: {
76
+ fontSize: 14,
77
+ },
78
+ Tag: {
79
+ borderRadius: 4,
80
+ fontSize: 11,
81
+ },
82
+ Badge: {
83
+ fontSize: 11,
84
+ },
85
+ },
86
+ };
87
+
88
+ export const darkTheme: ThemeConfig = {
89
+ token: {
90
+ // Primary colors - using Solarized palette
91
+ colorPrimary: solarized.blue,
92
+ colorSuccess: solarized.green,
93
+ colorWarning: solarized.yellow,
94
+ colorError: solarized.red,
95
+ colorInfo: solarized.cyan,
96
+
97
+ // Background colors - using Solarized dark
98
+ colorBgBase: darkColors.background,
99
+ colorBgContainer: darkColors.backgroundAlt,
100
+ colorBgElevated: darkColors.backgroundElevated,
101
+ colorBgLayout: darkColors.background,
102
+
103
+ // Text colors
104
+ colorText: darkColors.text,
105
+ colorTextSecondary: darkColors.textSecondary,
106
+ colorTextTertiary: darkColors.textMuted,
107
+
108
+ // Border colors
109
+ colorBorder: darkColors.border,
110
+ colorBorderSecondary: darkColors.borderHover,
111
+
112
+ // Border and layout
113
+ borderRadius: 6,
114
+ borderRadiusLG: 8,
115
+ borderRadiusOuter: 4,
116
+
117
+ // Typography
118
+ fontSize: 14,
119
+ fontSizeLG: 16,
120
+ fontSizeSM: 12,
121
+ fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
122
+
123
+ // Spacing
124
+ padding: 12,
125
+ paddingLG: 16,
126
+ paddingSM: 8,
127
+ paddingXS: 6,
128
+
129
+ // Component specific
130
+ controlHeight: 32,
131
+ controlHeightSM: 24,
132
+ controlHeightLG: 40,
133
+
134
+ // Box shadow
135
+ boxShadowSecondary: '0 4px 12px 0 rgba(0, 0, 0, 0.4)',
136
+ },
137
+ components: {
138
+ Card: {
139
+ borderRadius: 6,
140
+ paddingLG: 12,
141
+ colorBgContainer: darkColors.backgroundAlt,
142
+ },
143
+ Collapse: {
144
+ borderRadius: 6,
145
+ headerBg: darkColors.backgroundAlt,
146
+ contentBg: darkColors.background,
147
+ },
148
+ Button: {
149
+ borderRadius: 6,
150
+ },
151
+ Input: {
152
+ borderRadius: 6,
153
+ colorBgContainer: darkColors.backgroundAlt,
154
+ colorBorder: darkColors.border,
155
+ },
156
+ Select: {
157
+ borderRadius: 6,
158
+ colorBgContainer: darkColors.backgroundAlt,
159
+ colorBorder: darkColors.border,
160
+ },
161
+ Form: {
162
+ itemMarginBottom: 16,
163
+ verticalLabelPadding: '0 0 4px',
164
+ },
165
+ Typography: {
166
+ fontSize: 14,
167
+ },
168
+ Tag: {
169
+ borderRadius: 4,
170
+ fontSize: 11,
171
+ },
172
+ Badge: {
173
+ fontSize: 11,
174
+ },
175
+ Modal: {
176
+ contentBg: darkColors.backgroundAlt,
177
+ headerBg: darkColors.backgroundAlt,
178
+ },
179
+ Tooltip: {
180
+ colorBgSpotlight: darkColors.backgroundElevated,
181
+ },
182
+ },
183
+ };
184
+
185
+ // Legacy export for backwards compatibility
186
+ export const antdTheme = lightTheme;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Centralized API Configuration
3
+ * Single source of truth for all backend service URLs
4
+ */
5
+
6
+ interface ApiConfig {
7
+ readonly PYTHON_BASE_URL: string;
8
+ readonly WHATSAPP_BASE_URL: string;
9
+ readonly AUTH_ENABLED: boolean;
10
+ }
11
+
12
+ /**
13
+ * Get API configuration from environment variables with fallback defaults
14
+ */
15
+ function getApiConfig(): ApiConfig {
16
+ const viteEnv = (import.meta as any).env || {};
17
+
18
+ // In production (non-localhost), use relative URLs (same origin)
19
+ const isProduction = typeof window !== 'undefined' &&
20
+ !window.location.hostname.includes('localhost') &&
21
+ !window.location.hostname.includes('127.0.0.1');
22
+
23
+ return {
24
+ // Python FastAPI backend (port 3010 in dev, same origin in prod)
25
+ PYTHON_BASE_URL: viteEnv.VITE_PYTHON_SERVICE_URL || (isProduction ? '' : 'http://localhost:3010'),
26
+
27
+ // WhatsApp Go service (port 3012) - typically not called directly from frontend
28
+ WHATSAPP_BASE_URL: viteEnv.VITE_WHATSAPP_SERVICE_URL || (isProduction ? '' : 'http://localhost:3012'),
29
+
30
+ // Authentication enabled (default true, set VITE_AUTH_ENABLED=false to disable)
31
+ AUTH_ENABLED: viteEnv.VITE_AUTH_ENABLED !== 'false',
32
+ };
33
+ }
34
+
35
+ /**
36
+ * API Configuration singleton
37
+ * Import this in services instead of hardcoding URLs
38
+ *
39
+ * @example
40
+ * import { API_CONFIG } from '../config/api';
41
+ * fetch(`${API_CONFIG.PYTHON_BASE_URL}/api/workflow/execute-node`);
42
+ */
43
+ export const API_CONFIG = getApiConfig();
44
+
45
+ /**
46
+ * Helper to build API endpoint URLs
47
+ */
48
+ export const buildApiUrl = (path: string, baseUrl: string = API_CONFIG.PYTHON_BASE_URL): string => {
49
+ // Ensure path starts with /
50
+ const normalizedPath = path.startsWith('/') ? path : `/${path}`;
51
+ // Remove trailing slash from baseUrl
52
+ const normalizedBase = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
53
+ return `${normalizedBase}${normalizedPath}`;
54
+ };
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Authentication Context for user session management.
3
+ *
4
+ * Provides:
5
+ * - Login/logout/register functions
6
+ * - Current user state
7
+ * - Authentication status
8
+ * - Auth mode (single-owner vs multi-user)
9
+ */
10
+
11
+ import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
12
+ import { API_CONFIG } from '../config/api';
13
+
14
+ export interface User {
15
+ id: number;
16
+ email: string;
17
+ display_name: string;
18
+ is_owner: boolean;
19
+ }
20
+
21
+ export interface AuthStatus {
22
+ auth_mode: 'single' | 'multi';
23
+ authenticated: boolean;
24
+ user: User | null;
25
+ can_register: boolean;
26
+ }
27
+
28
+ interface AuthContextType {
29
+ user: User | null;
30
+ isAuthenticated: boolean;
31
+ isLoading: boolean;
32
+ authMode: 'single' | 'multi';
33
+ canRegister: boolean;
34
+ error: string | null;
35
+ login: (email: string, password: string) => Promise<boolean>;
36
+ register: (email: string, password: string, displayName: string) => Promise<boolean>;
37
+ logout: () => Promise<void>;
38
+ checkAuth: () => Promise<void>;
39
+ }
40
+
41
+ const AuthContext = createContext<AuthContextType | undefined>(undefined);
42
+
43
+ const getApiBase = () => `${API_CONFIG.PYTHON_BASE_URL}/api/auth`;
44
+
45
+ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
46
+ // When auth is disabled, bypass authentication entirely
47
+ const authEnabled = API_CONFIG.AUTH_ENABLED;
48
+
49
+ const [user, setUser] = useState<User | null>(authEnabled ? null : { id: 0, email: 'anonymous', display_name: 'Anonymous', is_owner: true });
50
+ const [isLoading, setIsLoading] = useState(authEnabled);
51
+ const [authMode, setAuthMode] = useState<'single' | 'multi'>('single');
52
+ const [canRegister, setCanRegister] = useState(false);
53
+ const [error, setError] = useState<string | null>(null);
54
+
55
+ const checkAuth = useCallback(async (retryCount = 0): Promise<void> => {
56
+ // Skip auth check if auth is disabled
57
+ if (!authEnabled) {
58
+ setIsLoading(false);
59
+ return;
60
+ }
61
+ const maxRetries = 5;
62
+ const baseDelay = 1000; // 1 second
63
+
64
+ try {
65
+ const response = await fetch(`${getApiBase()}/status`, {
66
+ credentials: 'include'
67
+ });
68
+ const data: AuthStatus = await response.json();
69
+
70
+ setAuthMode(data.auth_mode);
71
+ setCanRegister(data.can_register);
72
+
73
+ if (data.authenticated && data.user) {
74
+ setUser(data.user);
75
+ } else {
76
+ setUser(null);
77
+ }
78
+ setError(null);
79
+ setIsLoading(false);
80
+ } catch (err) {
81
+ console.error(`Failed to check auth status (attempt ${retryCount + 1}/${maxRetries + 1}):`, err);
82
+
83
+ // Retry with exponential backoff if server not ready
84
+ if (retryCount < maxRetries) {
85
+ const delay = baseDelay * Math.pow(2, retryCount);
86
+ console.log(`Retrying in ${delay}ms...`);
87
+ setTimeout(() => checkAuth(retryCount + 1), delay);
88
+ } else {
89
+ setUser(null);
90
+ setError('Failed to connect to server');
91
+ setIsLoading(false);
92
+ }
93
+ }
94
+ }, [authEnabled]);
95
+
96
+ // Check auth status on mount
97
+ useEffect(() => {
98
+ checkAuth();
99
+ }, [checkAuth]);
100
+
101
+ const login = useCallback(async (email: string, password: string): Promise<boolean> => {
102
+ setError(null);
103
+ setIsLoading(true);
104
+
105
+ try {
106
+ const response = await fetch(`${getApiBase()}/login`, {
107
+ method: 'POST',
108
+ headers: { 'Content-Type': 'application/json' },
109
+ credentials: 'include',
110
+ body: JSON.stringify({ email, password })
111
+ });
112
+
113
+ const data = await response.json();
114
+
115
+ if (!response.ok) {
116
+ setError(data.detail || 'Login failed');
117
+ setIsLoading(false);
118
+ return false;
119
+ }
120
+
121
+ if (data.success && data.user) {
122
+ setUser(data.user);
123
+ setIsLoading(false);
124
+ return true;
125
+ }
126
+
127
+ setError('Login failed');
128
+ setIsLoading(false);
129
+ return false;
130
+ } catch (err) {
131
+ console.error('Login error:', err);
132
+ setError('Failed to connect to server');
133
+ setIsLoading(false);
134
+ return false;
135
+ }
136
+ }, []);
137
+
138
+ const register = useCallback(async (
139
+ email: string,
140
+ password: string,
141
+ displayName: string
142
+ ): Promise<boolean> => {
143
+ setError(null);
144
+ setIsLoading(true);
145
+
146
+ try {
147
+ const response = await fetch(`${getApiBase()}/register`, {
148
+ method: 'POST',
149
+ headers: { 'Content-Type': 'application/json' },
150
+ credentials: 'include',
151
+ body: JSON.stringify({ email, password, display_name: displayName })
152
+ });
153
+
154
+ const data = await response.json();
155
+
156
+ if (!response.ok) {
157
+ setError(data.detail || 'Registration failed');
158
+ setIsLoading(false);
159
+ return false;
160
+ }
161
+
162
+ if (data.success && data.user) {
163
+ setUser(data.user);
164
+ setCanRegister(false); // After successful registration in single-owner mode
165
+ setIsLoading(false);
166
+ return true;
167
+ }
168
+
169
+ setError('Registration failed');
170
+ setIsLoading(false);
171
+ return false;
172
+ } catch (err) {
173
+ console.error('Register error:', err);
174
+ setError('Failed to connect to server');
175
+ setIsLoading(false);
176
+ return false;
177
+ }
178
+ }, []);
179
+
180
+ const logout = useCallback(async () => {
181
+ try {
182
+ await fetch(`${getApiBase()}/logout`, {
183
+ method: 'POST',
184
+ credentials: 'include'
185
+ });
186
+ } catch (err) {
187
+ console.error('Logout error:', err);
188
+ } finally {
189
+ setUser(null);
190
+ // Re-check auth status to update canRegister
191
+ await checkAuth();
192
+ }
193
+ }, [checkAuth]);
194
+
195
+ const value: AuthContextType = {
196
+ user,
197
+ isAuthenticated: user !== null,
198
+ isLoading,
199
+ authMode,
200
+ canRegister,
201
+ error,
202
+ login,
203
+ register,
204
+ logout,
205
+ checkAuth
206
+ };
207
+
208
+ return (
209
+ <AuthContext.Provider value={value}>
210
+ {children}
211
+ </AuthContext.Provider>
212
+ );
213
+ };
214
+
215
+ export const useAuth = (): AuthContextType => {
216
+ const context = useContext(AuthContext);
217
+ if (context === undefined) {
218
+ throw new Error('useAuth must be used within an AuthProvider');
219
+ }
220
+ return context;
221
+ };
@@ -0,0 +1,42 @@
1
+ import React, { createContext, useContext, useState, useEffect } from 'react';
2
+
3
+ interface ThemeContextType {
4
+ isDarkMode: boolean;
5
+ toggleTheme: () => void;
6
+ }
7
+
8
+ const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
9
+
10
+ export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
11
+ const [isDarkMode, setIsDarkMode] = useState(() => {
12
+ const saved = localStorage.getItem('darkMode');
13
+ return saved === null ? true : saved === 'true';
14
+ });
15
+
16
+ useEffect(() => {
17
+ localStorage.setItem('darkMode', isDarkMode.toString());
18
+ if (isDarkMode) {
19
+ document.documentElement.classList.add('dark');
20
+ } else {
21
+ document.documentElement.classList.remove('dark');
22
+ }
23
+ }, [isDarkMode]);
24
+
25
+ const toggleTheme = () => {
26
+ setIsDarkMode(prev => !prev);
27
+ };
28
+
29
+ return (
30
+ <ThemeContext.Provider value={{ isDarkMode, toggleTheme }}>
31
+ {children}
32
+ </ThemeContext.Provider>
33
+ );
34
+ };
35
+
36
+ export const useTheme = () => {
37
+ const context = useContext(ThemeContext);
38
+ if (context === undefined) {
39
+ throw new Error('useTheme must be used within a ThemeProvider');
40
+ }
41
+ return context;
42
+ };