groove-dev 0.27.143 → 0.27.145

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 (251) hide show
  1. package/CLAUDE.md +0 -7
  2. package/node_modules/@groove-dev/cli/package.json +1 -1
  3. package/node_modules/@groove-dev/daemon/package.json +1 -1
  4. package/node_modules/@groove-dev/daemon/src/api.js +1086 -6532
  5. package/node_modules/@groove-dev/daemon/src/conversations.js +18 -48
  6. package/node_modules/@groove-dev/daemon/src/gateways/manager.js +35 -1
  7. package/node_modules/@groove-dev/daemon/src/index.js +3 -0
  8. package/node_modules/@groove-dev/daemon/src/journalist.js +23 -13
  9. package/node_modules/@groove-dev/daemon/src/mlx-server.js +365 -0
  10. package/node_modules/@groove-dev/daemon/src/model-lab.js +308 -12
  11. package/node_modules/@groove-dev/daemon/src/pm.js +1 -1
  12. package/node_modules/@groove-dev/daemon/src/process.js +2 -2
  13. package/node_modules/@groove-dev/daemon/src/providers/local.js +36 -8
  14. package/node_modules/@groove-dev/daemon/src/registry.js +21 -5
  15. package/node_modules/@groove-dev/daemon/src/routes/agents.js +812 -0
  16. package/node_modules/@groove-dev/daemon/src/routes/coordination.js +318 -0
  17. package/node_modules/@groove-dev/daemon/src/routes/files.js +751 -0
  18. package/node_modules/@groove-dev/daemon/src/routes/integrations.js +485 -0
  19. package/node_modules/@groove-dev/daemon/src/routes/network.js +1784 -0
  20. package/node_modules/@groove-dev/daemon/src/routes/providers.js +755 -0
  21. package/node_modules/@groove-dev/daemon/src/routes/schedules.js +110 -0
  22. package/node_modules/@groove-dev/daemon/src/routes/teams.js +650 -0
  23. package/node_modules/@groove-dev/daemon/src/scheduler.js +456 -24
  24. package/node_modules/@groove-dev/daemon/src/teams.js +1 -1
  25. package/node_modules/@groove-dev/daemon/src/validate.js +38 -1
  26. package/node_modules/@groove-dev/daemon/templates/mlx-setup.json +12 -0
  27. package/node_modules/@groove-dev/daemon/templates/tgi-setup.json +1 -1
  28. package/node_modules/@groove-dev/daemon/templates/vllm-setup.json +1 -1
  29. package/node_modules/@groove-dev/daemon/test/introducer.test.js +3 -3
  30. package/node_modules/@groove-dev/daemon/test/journalist.test.js +7 -10
  31. package/node_modules/@groove-dev/daemon/test/registry.test.js +38 -0
  32. package/node_modules/@groove-dev/gui/dist/assets/index-Bxc0gU06.js +1006 -0
  33. package/node_modules/@groove-dev/gui/dist/assets/index-C0pztKBn.css +1 -0
  34. package/node_modules/@groove-dev/gui/dist/index.html +2 -2
  35. package/node_modules/@groove-dev/gui/package.json +1 -1
  36. package/node_modules/@groove-dev/gui/src/{app.jsx → App.jsx} +0 -2
  37. package/node_modules/@groove-dev/gui/src/app.css +35 -0
  38. package/node_modules/@groove-dev/gui/src/components/agents/agent-config.jsx +1 -128
  39. package/node_modules/@groove-dev/gui/src/components/agents/agent-feed.jsx +210 -112
  40. package/node_modules/@groove-dev/gui/src/components/agents/agent-node.jsx +8 -13
  41. package/node_modules/@groove-dev/gui/src/components/agents/agent-panel.jsx +2 -70
  42. package/node_modules/@groove-dev/gui/src/components/agents/code-review.jsx +159 -122
  43. package/node_modules/@groove-dev/gui/src/components/agents/diff-viewer.jsx +23 -23
  44. package/node_modules/@groove-dev/gui/src/components/agents/journalist-panel.jsx +1 -1
  45. package/node_modules/@groove-dev/gui/src/components/agents/spawn-wizard.jsx +2 -135
  46. package/node_modules/@groove-dev/gui/src/components/automations/automation-card.jsx +274 -0
  47. package/node_modules/@groove-dev/gui/src/components/automations/automation-wizard.jsx +1136 -0
  48. package/node_modules/@groove-dev/gui/src/components/chat/chat-header.jsx +2 -0
  49. package/node_modules/@groove-dev/gui/src/components/chat/chat-input.jsx +68 -66
  50. package/node_modules/@groove-dev/gui/src/components/chat/chat-view.jsx +4 -8
  51. package/node_modules/@groove-dev/gui/src/components/dashboard/activity-feed.jsx +3 -3
  52. package/node_modules/@groove-dev/gui/src/components/dashboard/cache-ring.jsx +5 -5
  53. package/node_modules/@groove-dev/gui/src/components/dashboard/context-gauges.jsx +6 -8
  54. package/node_modules/@groove-dev/gui/src/components/dashboard/fleet-panel.jsx +8 -14
  55. package/node_modules/@groove-dev/gui/src/components/dashboard/intel-panel.jsx +238 -656
  56. package/node_modules/@groove-dev/gui/src/components/dashboard/kpi-card.jsx +3 -3
  57. package/node_modules/@groove-dev/gui/src/components/dashboard/routing-chart.jsx +3 -3
  58. package/node_modules/@groove-dev/gui/src/components/dashboard/team-burn-panel.jsx +1 -1
  59. package/node_modules/@groove-dev/gui/src/components/dashboard/token-chart.jsx +4 -4
  60. package/node_modules/@groove-dev/gui/src/components/lab/chat-playground.jsx +39 -31
  61. package/node_modules/@groove-dev/gui/src/components/lab/lab-assistant.jsx +316 -82
  62. package/node_modules/@groove-dev/gui/src/components/lab/metrics-panel.jsx +187 -32
  63. package/node_modules/@groove-dev/gui/src/components/lab/parameter-panel.jsx +200 -18
  64. package/node_modules/@groove-dev/gui/src/components/lab/preset-manager.jsx +17 -14
  65. package/node_modules/@groove-dev/gui/src/components/lab/runtime-config.jsx +335 -152
  66. package/node_modules/@groove-dev/gui/src/components/lab/system-prompt-editor.jsx +10 -8
  67. package/node_modules/@groove-dev/gui/src/components/layout/activity-bar.jsx +2 -4
  68. package/node_modules/@groove-dev/gui/src/components/layout/terminal-panel.jsx +4 -2
  69. package/node_modules/@groove-dev/gui/src/components/layout/welcome-splash.jsx +137 -108
  70. package/node_modules/@groove-dev/gui/src/components/network/network-health.jsx +2 -2
  71. package/node_modules/@groove-dev/gui/src/components/network/performance-dashboard.jsx +4 -4
  72. package/node_modules/@groove-dev/gui/src/components/settings/ssh-wizard.jsx +81 -99
  73. package/node_modules/@groove-dev/gui/src/components/ui/sheet.jsx +5 -2
  74. package/node_modules/@groove-dev/gui/src/components/ui/slider.jsx +8 -8
  75. package/node_modules/@groove-dev/gui/src/lib/cron.js +64 -0
  76. package/node_modules/@groove-dev/gui/src/lib/status.js +25 -24
  77. package/node_modules/@groove-dev/gui/src/lib/theme-hex.js +1 -0
  78. package/node_modules/@groove-dev/gui/src/stores/groove.js +51 -3144
  79. package/node_modules/@groove-dev/gui/src/stores/helpers.js +10 -0
  80. package/node_modules/@groove-dev/gui/src/stores/slices/agents-slice.js +459 -0
  81. package/node_modules/@groove-dev/gui/src/stores/slices/automations-slice.js +96 -0
  82. package/node_modules/@groove-dev/gui/src/stores/slices/chat-slice.js +226 -0
  83. package/node_modules/@groove-dev/gui/src/stores/slices/editor-slice.js +285 -0
  84. package/node_modules/@groove-dev/gui/src/stores/slices/marketplace-slice.js +461 -0
  85. package/node_modules/@groove-dev/gui/src/stores/slices/network-slice.js +361 -0
  86. package/node_modules/@groove-dev/gui/src/stores/slices/preview-slice.js +109 -0
  87. package/node_modules/@groove-dev/gui/src/stores/slices/providers-slice.js +897 -0
  88. package/node_modules/@groove-dev/gui/src/stores/slices/teams-slice.js +413 -0
  89. package/node_modules/@groove-dev/gui/src/stores/slices/ui-slice.js +98 -0
  90. package/node_modules/@groove-dev/gui/src/views/agents.jsx +5 -5
  91. package/node_modules/@groove-dev/gui/src/views/dashboard.jsx +12 -13
  92. package/node_modules/@groove-dev/gui/src/views/marketplace.jsx +191 -3
  93. package/node_modules/@groove-dev/gui/src/views/model-lab.jsx +54 -12
  94. package/node_modules/@groove-dev/gui/src/views/models.jsx +419 -496
  95. package/node_modules/@groove-dev/gui/src/views/network.jsx +3 -3
  96. package/node_modules/@groove-dev/gui/src/views/settings.jsx +81 -94
  97. package/node_modules/@groove-dev/gui/src/views/teams.jsx +40 -483
  98. package/node_modules/axios/CHANGELOG.md +260 -0
  99. package/node_modules/axios/README.md +595 -223
  100. package/node_modules/axios/dist/axios.js +1460 -1090
  101. package/node_modules/axios/dist/axios.js.map +1 -1
  102. package/node_modules/axios/dist/axios.min.js +3 -3
  103. package/node_modules/axios/dist/axios.min.js.map +1 -1
  104. package/node_modules/axios/dist/browser/axios.cjs +1560 -1132
  105. package/node_modules/axios/dist/browser/axios.cjs.map +1 -1
  106. package/node_modules/axios/dist/esm/axios.js +1557 -1128
  107. package/node_modules/axios/dist/esm/axios.js.map +1 -1
  108. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  109. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  110. package/node_modules/axios/dist/node/axios.cjs +1594 -1057
  111. package/node_modules/axios/dist/node/axios.cjs.map +1 -1
  112. package/node_modules/axios/index.d.cts +40 -41
  113. package/node_modules/axios/index.d.ts +151 -227
  114. package/node_modules/axios/index.js +2 -0
  115. package/node_modules/axios/lib/adapters/adapters.js +4 -2
  116. package/node_modules/axios/lib/adapters/fetch.js +147 -16
  117. package/node_modules/axios/lib/adapters/http.js +306 -58
  118. package/node_modules/axios/lib/adapters/xhr.js +6 -2
  119. package/node_modules/axios/lib/core/Axios.js +7 -3
  120. package/node_modules/axios/lib/core/AxiosError.js +120 -34
  121. package/node_modules/axios/lib/core/AxiosHeaders.js +27 -25
  122. package/node_modules/axios/lib/core/buildFullPath.js +1 -1
  123. package/node_modules/axios/lib/core/dispatchRequest.js +19 -7
  124. package/node_modules/axios/lib/core/mergeConfig.js +21 -4
  125. package/node_modules/axios/lib/core/settle.js +7 -11
  126. package/node_modules/axios/lib/defaults/index.js +14 -9
  127. package/node_modules/axios/lib/env/data.js +1 -1
  128. package/node_modules/axios/lib/helpers/AxiosURLSearchParams.js +1 -2
  129. package/node_modules/axios/lib/helpers/buildURL.js +1 -1
  130. package/node_modules/axios/lib/helpers/cookies.js +14 -2
  131. package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +28 -1
  132. package/node_modules/axios/lib/helpers/formDataToJSON.js +3 -1
  133. package/node_modules/axios/lib/helpers/formDataToStream.js +3 -2
  134. package/node_modules/axios/lib/helpers/parseProtocol.js +1 -1
  135. package/node_modules/axios/lib/helpers/progressEventReducer.js +5 -5
  136. package/node_modules/axios/lib/helpers/resolveConfig.js +54 -18
  137. package/node_modules/axios/lib/helpers/shouldBypassProxy.js +74 -2
  138. package/node_modules/axios/lib/helpers/toFormData.js +10 -2
  139. package/node_modules/axios/lib/helpers/validator.js +3 -1
  140. package/node_modules/axios/lib/utils.js +33 -21
  141. package/node_modules/axios/package.json +17 -24
  142. package/node_modules/follow-redirects/README.md +7 -5
  143. package/node_modules/follow-redirects/index.js +24 -1
  144. package/node_modules/follow-redirects/package.json +1 -1
  145. package/package.json +1 -1
  146. package/packages/cli/package.json +1 -1
  147. package/packages/daemon/package.json +1 -1
  148. package/packages/daemon/src/api.js +1086 -6532
  149. package/packages/daemon/src/conversations.js +18 -48
  150. package/packages/daemon/src/gateways/manager.js +35 -1
  151. package/packages/daemon/src/index.js +3 -0
  152. package/packages/daemon/src/journalist.js +23 -13
  153. package/packages/daemon/src/mlx-server.js +365 -0
  154. package/packages/daemon/src/model-lab.js +308 -12
  155. package/packages/daemon/src/pm.js +1 -1
  156. package/packages/daemon/src/process.js +2 -2
  157. package/packages/daemon/src/providers/local.js +36 -8
  158. package/packages/daemon/src/registry.js +21 -5
  159. package/packages/daemon/src/routes/agents.js +812 -0
  160. package/packages/daemon/src/routes/coordination.js +318 -0
  161. package/packages/daemon/src/routes/files.js +751 -0
  162. package/packages/daemon/src/routes/integrations.js +485 -0
  163. package/packages/daemon/src/routes/network.js +1784 -0
  164. package/packages/daemon/src/routes/providers.js +755 -0
  165. package/packages/daemon/src/routes/schedules.js +110 -0
  166. package/packages/daemon/src/routes/teams.js +650 -0
  167. package/packages/daemon/src/scheduler.js +456 -24
  168. package/packages/daemon/src/teams.js +1 -1
  169. package/packages/daemon/src/validate.js +38 -1
  170. package/packages/daemon/templates/mlx-setup.json +12 -0
  171. package/packages/daemon/templates/tgi-setup.json +1 -1
  172. package/packages/daemon/templates/vllm-setup.json +1 -1
  173. package/packages/gui/dist/assets/index-Bxc0gU06.js +1006 -0
  174. package/packages/gui/dist/assets/index-C0pztKBn.css +1 -0
  175. package/packages/gui/dist/index.html +2 -2
  176. package/packages/gui/package.json +1 -1
  177. package/packages/gui/src/{app.jsx → App.jsx} +0 -2
  178. package/packages/gui/src/app.css +35 -0
  179. package/packages/gui/src/components/agents/agent-config.jsx +1 -128
  180. package/packages/gui/src/components/agents/agent-feed.jsx +210 -112
  181. package/packages/gui/src/components/agents/agent-node.jsx +8 -13
  182. package/packages/gui/src/components/agents/agent-panel.jsx +2 -70
  183. package/packages/gui/src/components/agents/code-review.jsx +159 -122
  184. package/packages/gui/src/components/agents/diff-viewer.jsx +23 -23
  185. package/packages/gui/src/components/agents/journalist-panel.jsx +1 -1
  186. package/packages/gui/src/components/agents/spawn-wizard.jsx +2 -135
  187. package/packages/gui/src/components/automations/automation-card.jsx +274 -0
  188. package/packages/gui/src/components/automations/automation-wizard.jsx +1136 -0
  189. package/packages/gui/src/components/chat/chat-header.jsx +2 -0
  190. package/packages/gui/src/components/chat/chat-input.jsx +68 -66
  191. package/packages/gui/src/components/chat/chat-view.jsx +4 -8
  192. package/packages/gui/src/components/dashboard/activity-feed.jsx +3 -3
  193. package/packages/gui/src/components/dashboard/cache-ring.jsx +5 -5
  194. package/packages/gui/src/components/dashboard/context-gauges.jsx +6 -8
  195. package/packages/gui/src/components/dashboard/fleet-panel.jsx +8 -14
  196. package/packages/gui/src/components/dashboard/intel-panel.jsx +238 -656
  197. package/packages/gui/src/components/dashboard/kpi-card.jsx +3 -3
  198. package/packages/gui/src/components/dashboard/routing-chart.jsx +3 -3
  199. package/packages/gui/src/components/dashboard/team-burn-panel.jsx +1 -1
  200. package/packages/gui/src/components/dashboard/token-chart.jsx +4 -4
  201. package/packages/gui/src/components/lab/chat-playground.jsx +39 -31
  202. package/packages/gui/src/components/lab/lab-assistant.jsx +316 -82
  203. package/packages/gui/src/components/lab/metrics-panel.jsx +187 -32
  204. package/packages/gui/src/components/lab/parameter-panel.jsx +200 -18
  205. package/packages/gui/src/components/lab/preset-manager.jsx +17 -14
  206. package/packages/gui/src/components/lab/runtime-config.jsx +335 -152
  207. package/packages/gui/src/components/lab/system-prompt-editor.jsx +10 -8
  208. package/packages/gui/src/components/layout/activity-bar.jsx +2 -4
  209. package/packages/gui/src/components/layout/terminal-panel.jsx +4 -2
  210. package/packages/gui/src/components/layout/welcome-splash.jsx +137 -108
  211. package/packages/gui/src/components/network/network-health.jsx +2 -2
  212. package/packages/gui/src/components/network/performance-dashboard.jsx +4 -4
  213. package/packages/gui/src/components/settings/ssh-wizard.jsx +81 -99
  214. package/packages/gui/src/components/ui/sheet.jsx +5 -2
  215. package/packages/gui/src/components/ui/slider.jsx +8 -8
  216. package/packages/gui/src/lib/cron.js +64 -0
  217. package/packages/gui/src/lib/status.js +25 -24
  218. package/packages/gui/src/lib/theme-hex.js +1 -0
  219. package/packages/gui/src/stores/groove.js +51 -3144
  220. package/packages/gui/src/stores/helpers.js +10 -0
  221. package/packages/gui/src/stores/slices/agents-slice.js +459 -0
  222. package/packages/gui/src/stores/slices/automations-slice.js +96 -0
  223. package/packages/gui/src/stores/slices/chat-slice.js +226 -0
  224. package/packages/gui/src/stores/slices/editor-slice.js +285 -0
  225. package/packages/gui/src/stores/slices/marketplace-slice.js +461 -0
  226. package/packages/gui/src/stores/slices/network-slice.js +361 -0
  227. package/packages/gui/src/stores/slices/preview-slice.js +109 -0
  228. package/packages/gui/src/stores/slices/providers-slice.js +897 -0
  229. package/packages/gui/src/stores/slices/teams-slice.js +413 -0
  230. package/packages/gui/src/stores/slices/ui-slice.js +98 -0
  231. package/packages/gui/src/views/agents.jsx +5 -5
  232. package/packages/gui/src/views/dashboard.jsx +12 -13
  233. package/packages/gui/src/views/marketplace.jsx +191 -3
  234. package/packages/gui/src/views/model-lab.jsx +54 -12
  235. package/packages/gui/src/views/models.jsx +419 -496
  236. package/packages/gui/src/views/network.jsx +3 -3
  237. package/packages/gui/src/views/settings.jsx +81 -94
  238. package/packages/gui/src/views/teams.jsx +40 -483
  239. package/SECURITY_SWEEP.md +0 -228
  240. package/TRAINING_DATA_v4.md +0 -6
  241. package/node_modules/@groove-dev/gui/dist/assets/index-CCVvAoQn.css +0 -1
  242. package/node_modules/@groove-dev/gui/dist/assets/index-DGIv_TRm.js +0 -984
  243. package/node_modules/@groove-dev/gui/src/components/agents/agent-chat.jsx +0 -379
  244. package/node_modules/@groove-dev/gui/src/views/preview.jsx +0 -6
  245. package/node_modules/@groove-dev/gui/src/views/subscription-panel.jsx +0 -327
  246. package/packages/gui/dist/assets/index-CCVvAoQn.css +0 -1
  247. package/packages/gui/dist/assets/index-DGIv_TRm.js +0 -984
  248. package/packages/gui/src/components/agents/agent-chat.jsx +0 -379
  249. package/packages/gui/src/views/preview.jsx +0 -6
  250. package/packages/gui/src/views/subscription-panel.jsx +0 -327
  251. package/test.py +0 -571
@@ -0,0 +1,361 @@
1
+ // FSL-1.1-Apache-2.0 — see LICENSE
2
+
3
+ import { api } from '../../lib/api';
4
+
5
+ export const createNetworkSlice = (set, get) => ({
6
+ // ── Network (Early Access) ────────────────────────────────
7
+ networkUnlocked: false,
8
+ networkInstalled: false,
9
+ networkInstallProgress: { installing: false, step: null, message: null, percent: 0, error: null },
10
+ networkNode: { active: false, status: 'disconnected', nodeId: null, layers: null, model: null, sessions: 0, hardware: null },
11
+ networkStatus: { nodes: [], coverage: 0, totalLayers: 0, models: [], activeSessions: 0 },
12
+ networkStatusReachable: false,
13
+ networkEvents: [],
14
+ networkVersion: { installed: null, latest: null, updateAvailable: false },
15
+ networkUpdateProgress: { updating: false, step: null, message: null, percent: 0, error: null },
16
+ networkCompute: { totalRamMb: 0, totalVramMb: 0, totalCpuCores: 0, totalBandwidthMbps: 0, activeNodes: 0, totalNodes: 0, avgLoad: 0 },
17
+ networkSnapshots: [],
18
+ networkTokenTiming: null,
19
+ networkBenchmarks: [],
20
+ networkTraces: [],
21
+ networkPerfSnapshots: [],
22
+ networkNodeTelemetry: {},
23
+ networkWallet: { connected: false, address: null, balance: '0.00', token: 'GROOVE', chain: 'base-l2' },
24
+ networkEarnings: { today: 0, thisWeek: 0, allTime: 0, history: [] },
25
+
26
+ // ── Federation ────────────────────────────────────────────
27
+ federation: {
28
+ peers: [],
29
+ whitelist: [],
30
+ connections: [],
31
+ pouchLog: [],
32
+ ambassadors: [],
33
+ selectedPeerId: null,
34
+ },
35
+
36
+ // ── Network Actions ───────────────────────────────────────
37
+
38
+ async fetchBetaStatus() {
39
+ try {
40
+ const data = await api.get('/beta/status');
41
+ set({ networkUnlocked: !!data?.unlocked });
42
+ } catch { /* endpoint may not exist yet */ }
43
+ },
44
+
45
+ async activateBeta(code) {
46
+ const data = await api.post('/beta/activate', { code });
47
+ if (!data?.unlocked) {
48
+ throw new Error(data?.message || 'Invalid invite code');
49
+ }
50
+ set({ networkUnlocked: true });
51
+ return data;
52
+ },
53
+
54
+ async deactivateBeta() {
55
+ try {
56
+ await api.post('/beta/deactivate');
57
+ set({
58
+ networkUnlocked: false,
59
+ activeView: get().activeView === 'network' ? 'agents' : get().activeView,
60
+ });
61
+ } catch (err) {
62
+ get().addToast('error', 'Deactivate failed', err.message);
63
+ throw err;
64
+ }
65
+ },
66
+
67
+ async fetchNetworkNodeStatus() {
68
+ try {
69
+ const data = await api.get('/network/node/status');
70
+ const update = { networkNode: { ...get().networkNode, ...(data || {}) } };
71
+ if (data && typeof data.installed === 'boolean') {
72
+ update.networkInstalled = data.installed;
73
+ }
74
+ set(update);
75
+ return data;
76
+ } catch { return null; }
77
+ },
78
+
79
+ async fetchNetworkInstallStatus() {
80
+ try {
81
+ const data = await api.get('/network/install/status');
82
+ if (data && typeof data.installed === 'boolean') {
83
+ set({ networkInstalled: data.installed });
84
+ }
85
+ return data;
86
+ } catch { return null; }
87
+ },
88
+
89
+ async installNetworkPackage() {
90
+ set({
91
+ networkInstallProgress: {
92
+ installing: true,
93
+ step: 'starting',
94
+ message: 'Starting install…',
95
+ percent: 0,
96
+ error: null,
97
+ },
98
+ });
99
+ try {
100
+ await api.post('/network/install');
101
+ } catch (err) {
102
+ set({
103
+ networkInstallProgress: {
104
+ installing: false,
105
+ step: 'error',
106
+ message: err.message,
107
+ percent: 0,
108
+ error: err.message,
109
+ },
110
+ });
111
+ get().addToast('error', 'Install failed', err.message);
112
+ }
113
+ },
114
+
115
+ async uninstallNetworkPackage() {
116
+ try {
117
+ await api.post('/network/uninstall');
118
+ set({
119
+ networkInstalled: false,
120
+ networkNode: { active: false, status: 'disconnected', nodeId: null, layers: null, model: null, sessions: 0, hardware: null },
121
+ networkInstallProgress: { installing: false, step: null, message: null, percent: 0, error: null },
122
+ });
123
+ get().addToast('success', 'Network package uninstalled');
124
+ } catch (err) {
125
+ get().addToast('error', 'Uninstall failed', err.message);
126
+ throw err;
127
+ }
128
+ },
129
+
130
+ async fetchNetworkStatus() {
131
+ try {
132
+ const data = await api.get('/network/status');
133
+ const update = {
134
+ networkStatus: { ...get().networkStatus, ...(data || {}) },
135
+ networkStatusReachable: true,
136
+ };
137
+ if (data?.compute) {
138
+ const c = data.compute;
139
+ update.networkCompute = {
140
+ totalRamMb: c.totalRamMb ?? c.total_ram_mb ?? 0,
141
+ totalVramMb: c.totalVramMb ?? c.total_vram_mb ?? 0,
142
+ totalCpuCores: c.totalCpuCores ?? c.total_cpu_cores ?? 0,
143
+ totalBandwidthMbps: c.totalBandwidthMbps ?? c.total_bandwidth_mbps ?? 0,
144
+ activeNodes: c.activeNodes ?? c.active_nodes ?? 0,
145
+ totalNodes: c.totalNodes ?? c.total_nodes ?? 0,
146
+ avgLoad: c.avgLoad ?? c.avg_load ?? 0,
147
+ };
148
+ } else if (Array.isArray(data?.nodes) && data.nodes.length > 0) {
149
+ const nodes = data.nodes;
150
+ const active = nodes.filter((n) => n.status === 'active');
151
+ update.networkCompute = {
152
+ totalRamMb: nodes.reduce((s, n) => s + (n.ram_mb || 0), 0),
153
+ totalVramMb: nodes.reduce((s, n) => s + (n.vram_mb || 0), 0),
154
+ totalCpuCores: nodes.reduce((s, n) => s + (n.cpu_cores || 0), 0),
155
+ totalBandwidthMbps: nodes.reduce((s, n) => s + (n.bandwidth_mbps || 0), 0),
156
+ activeNodes: active.length,
157
+ totalNodes: nodes.length,
158
+ avgLoad: active.length > 0 ? active.reduce((s, n) => s + (n.load || 0), 0) / active.length : 0,
159
+ };
160
+ }
161
+ set(update);
162
+
163
+ if (data) {
164
+ const ownId = get().networkNode.nodeId;
165
+ const nodes = data.nodes || [];
166
+ const ownNode = ownId ? nodes.find((n) => (n.node_id || n.nodeId) === ownId) : null;
167
+ const activeNodes = nodes.filter((n) => n.status === 'active');
168
+ const snap = {
169
+ t: Date.now(),
170
+ globalSessions: data.activeSessions || 0,
171
+ mySessions: ownNode?.active_sessions ?? ownNode?.sessions ?? 0,
172
+ nodeCount: activeNodes.length,
173
+ avgLoad: activeNodes.length > 0 ? activeNodes.reduce((s, n) => s + (n.load || 0), 0) / activeNodes.length : 0,
174
+ myLoad: ownNode?.load ?? 0,
175
+ totalVramMb: nodes.reduce((s, n) => s + (n.vram_mb || 0), 0),
176
+ totalRamMb: nodes.reduce((s, n) => s + (n.ram_mb || 0), 0),
177
+ };
178
+ let snapshots = [...get().networkSnapshots, snap];
179
+ if (snapshots.length > 100) snapshots = snapshots.slice(-100);
180
+ set({ networkSnapshots: snapshots });
181
+ }
182
+
183
+ return data;
184
+ } catch {
185
+ set({ networkStatusReachable: false });
186
+ return null;
187
+ }
188
+ },
189
+
190
+ async checkNetworkUpdate() {
191
+ try {
192
+ const data = await api.get('/network/update/check');
193
+ if (!data) return null;
194
+ set({
195
+ networkVersion: {
196
+ installed: data.installed ?? null,
197
+ latest: data.latest ?? null,
198
+ updateAvailable: !!data.updateAvailable,
199
+ },
200
+ });
201
+ return data;
202
+ } catch { return null; }
203
+ },
204
+
205
+ async updateNetworkPackage() {
206
+ set({
207
+ networkUpdateProgress: {
208
+ updating: true,
209
+ step: 'starting',
210
+ message: 'Starting update…',
211
+ percent: 0,
212
+ error: null,
213
+ },
214
+ });
215
+ try {
216
+ await api.post('/network/update');
217
+ } catch (err) {
218
+ set({
219
+ networkUpdateProgress: {
220
+ updating: false,
221
+ step: 'error',
222
+ message: err.message,
223
+ percent: 0,
224
+ error: err.message,
225
+ },
226
+ });
227
+ get().addToast('error', 'Update failed', err.message);
228
+ }
229
+ },
230
+
231
+ async startNetworkNode() {
232
+ set({ networkNode: { ...get().networkNode, status: 'connecting' } });
233
+ try {
234
+ const data = await api.post('/network/node/start');
235
+ set({ networkNode: { ...get().networkNode, active: true, ...(data || {}) } });
236
+ get().addToast('success', 'Node started', 'Connecting to the Groove network');
237
+ return data;
238
+ } catch (err) {
239
+ set({ networkNode: { ...get().networkNode, status: 'disconnected', active: false } });
240
+ get().addToast('error', 'Node start failed', err.message);
241
+ throw err;
242
+ }
243
+ },
244
+
245
+ async stopNetworkNode() {
246
+ try {
247
+ await api.post('/network/node/stop');
248
+ set({ networkNode: { ...get().networkNode, active: false, status: 'disconnected' } });
249
+ get().addToast('info', 'Node stopped');
250
+ } catch (err) {
251
+ get().addToast('error', 'Node stop failed', err.message);
252
+ throw err;
253
+ }
254
+ },
255
+
256
+ async fetchNetworkWallet() {
257
+ return get().networkWallet;
258
+ },
259
+ async fetchNetworkEarnings() {
260
+ return get().networkEarnings;
261
+ },
262
+
263
+ async fetchNetworkBenchmarks() {
264
+ try {
265
+ const data = await api.get('/network/benchmarks');
266
+ if (Array.isArray(data)) set({ networkBenchmarks: data.slice(-100) });
267
+ return data;
268
+ } catch { return null; }
269
+ },
270
+
271
+ async fetchNetworkTraces() {
272
+ try {
273
+ const data = await api.get('/network/traces');
274
+ if (Array.isArray(data)) set({ networkTraces: data });
275
+ return data;
276
+ } catch { return null; }
277
+ },
278
+
279
+ async fetchNetworkTrace(filename) {
280
+ try {
281
+ return await api.get(`/network/traces/${encodeURIComponent(filename)}`);
282
+ } catch { return null; }
283
+ },
284
+
285
+ async fetchLiveTrace(offset = 0) {
286
+ try {
287
+ return await api.get(`/network/traces/live?offset=${offset}`);
288
+ } catch { return null; }
289
+ },
290
+
291
+ // ── Federation ────────────────────────────────────────────
292
+
293
+ async fetchFederationStatus() {
294
+ try {
295
+ const data = await api.get('/federation');
296
+ set((s) => ({
297
+ federation: {
298
+ ...s.federation,
299
+ peers: data.peers || [],
300
+ whitelist: data.whitelist || [],
301
+ connections: data.connections || [],
302
+ ambassadors: data.ambassadors?.ambassadors || data.ambassadors || [],
303
+ },
304
+ }));
305
+ return data;
306
+ } catch { return null; }
307
+ },
308
+
309
+ async addToWhitelist(ip, port = 31415, name) {
310
+ try {
311
+ await api.post('/federation/whitelist', { ip, port, ...(name && { name }) });
312
+ get().addToast('success', `Added ${ip} to whitelist`);
313
+ get().fetchFederationStatus();
314
+ } catch (err) {
315
+ get().addToast('error', 'Whitelist failed', err.message);
316
+ throw err;
317
+ }
318
+ },
319
+
320
+ async removeFromWhitelist(ip) {
321
+ try {
322
+ await api.delete(`/federation/whitelist/${encodeURIComponent(ip)}`);
323
+ get().addToast('info', `Removed ${ip}`);
324
+ get().fetchFederationStatus();
325
+ } catch (err) {
326
+ get().addToast('error', 'Remove failed', err.message);
327
+ }
328
+ },
329
+
330
+ setSelectedPeer(peerId) {
331
+ set((s) => ({ federation: { ...s.federation, selectedPeerId: peerId } }));
332
+ },
333
+
334
+ async fetchPouchLog(peerId) {
335
+ try {
336
+ const data = await api.get(`/federation/pouch/log${peerId ? `?peerId=${encodeURIComponent(peerId)}` : ''}`);
337
+ set((s) => ({ federation: { ...s.federation, pouchLog: data || [] } }));
338
+ } catch { /* ignore */ }
339
+ },
340
+
341
+ async sendPouch(peerId, contract) {
342
+ try {
343
+ const result = await api.post('/federation/pouch/send', { peerId, contract });
344
+ get().addToast('success', 'Pouch sent');
345
+ return result;
346
+ } catch (err) {
347
+ get().addToast('error', 'Pouch send failed', err.message);
348
+ throw err;
349
+ }
350
+ },
351
+
352
+ async disconnectPeer(peerId) {
353
+ try {
354
+ await api.delete(`/federation/peers/${encodeURIComponent(peerId)}`);
355
+ get().addToast('info', 'Peer disconnected');
356
+ get().fetchFederationStatus();
357
+ } catch (err) {
358
+ get().addToast('error', 'Disconnect failed', err.message);
359
+ }
360
+ },
361
+ });
@@ -0,0 +1,109 @@
1
+ // FSL-1.1-Apache-2.0 — see LICENSE
2
+
3
+ import { api } from '../../lib/api';
4
+
5
+ export const createPreviewSlice = (set, get) => ({
6
+ // ── Preview ───────────────────────────────────────────────
7
+ previewState: { url: null, teamId: null, kind: null, deviceSize: 'desktop', screenshotMode: false },
8
+ showPreviewInAgents: false,
9
+ previewChat: [],
10
+ previewIterating: false,
11
+ teamPreviews: {},
12
+
13
+ // ── Preview Actions ───────────────────────────────────────
14
+
15
+ async fetchActivePreviews() {
16
+ try {
17
+ const data = await api.get('/preview');
18
+ const previews = data.previews || [];
19
+ if (previews.length > 0) {
20
+ const updates = {};
21
+ for (const p of previews) {
22
+ updates[p.teamId] = { url: `/api/preview/${p.teamId}/proxy/`, kind: p.kind, active: true };
23
+ }
24
+ const most = previews.sort((a, b) => (b.startedAt || 0) - (a.startedAt || 0))[0];
25
+ set((s) => ({
26
+ teamPreviews: { ...s.teamPreviews, ...updates },
27
+ previewState: { url: `/api/preview/${most.teamId}/proxy/`, teamId: most.teamId, kind: most.kind, deviceSize: 'desktop', screenshotMode: false },
28
+ showPreviewInAgents: true,
29
+ }));
30
+ }
31
+ } catch {}
32
+ },
33
+
34
+ openPreview(url, teamId, kind) {
35
+ set((s) => ({
36
+ previewState: { url, teamId, kind, deviceSize: 'desktop', screenshotMode: false },
37
+ teamPreviews: { ...s.teamPreviews, [teamId]: { url, kind, active: true } },
38
+ previewChat: [],
39
+ showPreviewInAgents: true,
40
+ }));
41
+ },
42
+ closePreview() {
43
+ set({ showPreviewInAgents: false });
44
+ },
45
+ stopPreview() {
46
+ const { previewState } = get();
47
+ if (previewState.teamId) {
48
+ api.delete(`/preview/${previewState.teamId}`).catch(() => {});
49
+ set((s) => ({
50
+ teamPreviews: {
51
+ ...s.teamPreviews,
52
+ [previewState.teamId]: { ...s.teamPreviews[previewState.teamId], active: false },
53
+ },
54
+ showPreviewInAgents: false,
55
+ }));
56
+ }
57
+ },
58
+ async relaunchPreview(teamId) {
59
+ try {
60
+ const result = await api.post(`/preview/${teamId}/launch`);
61
+ if (result.launched) {
62
+ const proxyUrl = `/api/preview/${teamId}/proxy/`;
63
+ set((s) => ({
64
+ previewState: { url: proxyUrl, teamId, kind: result.kind, deviceSize: 'desktop', screenshotMode: false },
65
+ teamPreviews: { ...s.teamPreviews, [teamId]: { url: proxyUrl, kind: result.kind, active: true } },
66
+ showPreviewInAgents: true,
67
+ }));
68
+ } else {
69
+ get().addToast('warning', 'Preview could not launch', result.reason ? String(result.reason).slice(0, 200) : 'Build or server failed');
70
+ }
71
+ } catch (err) {
72
+ get().addToast('error', 'Failed to launch preview', err.message);
73
+ }
74
+ },
75
+ togglePreviewInAgents() {
76
+ set((s) => ({ showPreviewInAgents: !s.showPreviewInAgents }));
77
+ },
78
+ setPreviewDevice(size) {
79
+ set((s) => ({ previewState: { ...s.previewState, deviceSize: size } }));
80
+ },
81
+ toggleScreenshotMode() {
82
+ set((s) => ({ previewState: { ...s.previewState, screenshotMode: !s.previewState.screenshotMode } }));
83
+ },
84
+ async iteratePreview(message, screenshotBase64) {
85
+ const { previewState } = get();
86
+ if (!previewState.teamId) return;
87
+
88
+ const userMsg = { role: 'user', content: message, screenshot: screenshotBase64 || null, timestamp: Date.now() };
89
+ set((s) => ({ previewChat: [...s.previewChat, userMsg], previewIterating: true }));
90
+
91
+ try {
92
+ const body = { message };
93
+ if (screenshotBase64) body.screenshot = screenshotBase64;
94
+ const res = await api.post(`/preview/${previewState.teamId}/iterate`, body);
95
+ const assistantMsg = { role: 'assistant', content: res.response || res.message || 'Changes routed to planner.', timestamp: Date.now() };
96
+ set((s) => ({ previewChat: [...s.previewChat, assistantMsg], previewIterating: false }));
97
+ } catch (err) {
98
+ const errMsg = { role: 'assistant', content: `Failed to iterate: ${err.message}`, timestamp: Date.now() };
99
+ set((s) => ({ previewChat: [...s.previewChat, errMsg], previewIterating: false }));
100
+ }
101
+ },
102
+ addPreviewChatMessage(role, content, screenshot) {
103
+ const msg = { role, content, screenshot: screenshot || null, timestamp: Date.now() };
104
+ set((s) => ({ previewChat: [...s.previewChat, msg] }));
105
+ },
106
+ clearPreviewChat() {
107
+ set({ previewChat: [] });
108
+ },
109
+ });