groove-dev 0.27.27 → 0.27.28

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 (32) hide show
  1. package/.groove-staging/state.json +3 -0
  2. package/.groove-staging/timeline.json +13 -0
  3. package/DECENTRALIZED_NET_WP_V1.md +871 -0
  4. package/README.md +28 -0
  5. package/decentralized-net/ACTION_PLAN.md +422 -0
  6. package/node_modules/@groove-dev/cli/package.json +1 -1
  7. package/node_modules/@groove-dev/daemon/package.json +1 -1
  8. package/node_modules/@groove-dev/daemon/src/api.js +99 -0
  9. package/node_modules/@groove-dev/daemon/src/process.js +12 -0
  10. package/node_modules/@groove-dev/daemon/src/providers/claude-code.js +26 -1
  11. package/node_modules/@groove-dev/gui/dist/assets/{index-DieCV-v1.js → index-Ch1N9G4Z.js} +1728 -1728
  12. package/node_modules/@groove-dev/gui/dist/index.html +1 -1
  13. package/node_modules/@groove-dev/gui/package.json +1 -1
  14. package/node_modules/@groove-dev/gui/src/components/agents/agent-config.jsx +147 -21
  15. package/node_modules/@groove-dev/gui/src/components/agents/spawn-wizard.jsx +206 -44
  16. package/node_modules/@groove-dev/gui/src/components/marketplace/integration-wizard.jsx +11 -24
  17. package/node_modules/@groove-dev/gui/src/components/marketplace/marketplace-card.jsx +1 -36
  18. package/node_modules/@groove-dev/gui/src/lib/integration-logos.js +39 -0
  19. package/package.json +1 -1
  20. package/packages/cli/package.json +1 -1
  21. package/packages/daemon/package.json +1 -1
  22. package/packages/daemon/src/api.js +99 -0
  23. package/packages/daemon/src/process.js +12 -0
  24. package/packages/daemon/src/providers/claude-code.js +26 -1
  25. package/packages/gui/dist/assets/{index-DieCV-v1.js → index-Ch1N9G4Z.js} +1728 -1728
  26. package/packages/gui/dist/index.html +1 -1
  27. package/packages/gui/package.json +1 -1
  28. package/packages/gui/src/components/agents/agent-config.jsx +147 -21
  29. package/packages/gui/src/components/agents/spawn-wizard.jsx +206 -44
  30. package/packages/gui/src/components/marketplace/integration-wizard.jsx +11 -24
  31. package/packages/gui/src/components/marketplace/marketplace-card.jsx +1 -36
  32. package/packages/gui/src/lib/integration-logos.js +39 -0
@@ -4,42 +4,7 @@ import { cn } from '../../lib/cn';
4
4
  import { Badge } from '../ui/badge';
5
5
  import { fmtNum } from '../../lib/format';
6
6
 
7
- // Well-known integration logos via CDN (simple-icons on cdn.simpleicons.org)
8
- export const INTEGRATION_LOGOS = {
9
- 'google-workspace': 'https://cdn.simpleicons.org/google/white',
10
- github: 'https://cdn.simpleicons.org/github/white',
11
- stripe: 'https://cdn.simpleicons.org/stripe/635BFF',
12
- gmail: 'https://cdn.simpleicons.org/gmail/EA4335',
13
- 'google-calendar': 'https://cdn.simpleicons.org/googlecalendar/4285F4',
14
- 'google-drive': 'https://cdn.simpleicons.org/googledrive/4285F4',
15
- 'google-docs': 'https://cdn.simpleicons.org/googledocs/4285F4',
16
- 'google-sheets': 'https://cdn.simpleicons.org/googlesheets/34A853',
17
- 'google-slides': 'https://cdn.simpleicons.org/googleslides/FBBC04',
18
- 'google-maps': 'https://cdn.simpleicons.org/googlemaps/4285F4',
19
- postgres: 'https://cdn.simpleicons.org/postgresql/4169E1',
20
- notion: 'https://cdn.simpleicons.org/notion/white',
21
- linear: 'https://cdn.simpleicons.org/linear/5E6AD2',
22
- 'brave-search': 'https://cdn.simpleicons.org/brave/FB542B',
23
- 'home-assistant': 'https://cdn.simpleicons.org/homeassistant/18BCF2',
24
- sentry: 'https://cdn.simpleicons.org/sentry/362D59',
25
- elevenlabs: 'https://cdn.simpleicons.org/elevenlabs/white',
26
- hubspot: 'https://cdn.simpleicons.org/hubspot/FF7A59',
27
- jira: 'https://cdn.simpleicons.org/jira/0052CC',
28
- sendgrid: 'https://cdn.simpleicons.org/sendgrid/1A82E2',
29
- resend: 'https://cdn.simpleicons.org/resend/white',
30
- replicate: 'https://cdn.simpleicons.org/replicate/white',
31
- vercel: 'https://cdn.simpleicons.org/vercel/white',
32
- supabase: 'https://cdn.simpleicons.org/supabase/3FCF8E',
33
- mixpanel: 'https://cdn.simpleicons.org/mixpanel/7856FF',
34
- datadog: 'https://cdn.simpleicons.org/datadog/632CA6',
35
- airtable: 'https://cdn.simpleicons.org/airtable/18BFFF',
36
- zendesk: 'https://cdn.simpleicons.org/zendesk/03363D',
37
- intercom: 'https://cdn.simpleicons.org/intercom/6AFDEF',
38
- twilio: 'https://cdn.simpleicons.org/twilio/F22F46',
39
- telnyx: 'https://cdn.simpleicons.org/telnyx/00C08B',
40
- aws: 'https://cdn.simpleicons.org/amazonaws/FF9900',
41
- plaid: 'https://cdn.simpleicons.org/plaid/white',
42
- };
7
+ import { INTEGRATION_LOGOS } from '../../lib/integration-logos';
43
8
 
44
9
  function ItemIcon({ item, size = 40 }) {
45
10
  const logoUrl = INTEGRATION_LOGOS[item.id];
@@ -0,0 +1,39 @@
1
+ // FSL-1.1-Apache-2.0 — see LICENSE
2
+
3
+ export const INTEGRATION_LOGOS = {
4
+ 'google-workspace': 'https://cdn.simpleicons.org/google/white',
5
+ slack: 'https://cdn.simpleicons.org/slack/E01E5A',
6
+ discord: 'https://cdn.simpleicons.org/discord/5865F2',
7
+ github: 'https://cdn.simpleicons.org/github/white',
8
+ stripe: 'https://cdn.simpleicons.org/stripe/635BFF',
9
+ gmail: 'https://cdn.simpleicons.org/gmail/EA4335',
10
+ 'google-calendar': 'https://cdn.simpleicons.org/googlecalendar/4285F4',
11
+ 'google-drive': 'https://cdn.simpleicons.org/googledrive/4285F4',
12
+ 'google-docs': 'https://cdn.simpleicons.org/googledocs/4285F4',
13
+ 'google-sheets': 'https://cdn.simpleicons.org/googlesheets/34A853',
14
+ 'google-slides': 'https://cdn.simpleicons.org/googleslides/FBBC04',
15
+ 'google-maps': 'https://cdn.simpleicons.org/googlemaps/4285F4',
16
+ postgres: 'https://cdn.simpleicons.org/postgresql/4169E1',
17
+ notion: 'https://cdn.simpleicons.org/notion/white',
18
+ linear: 'https://cdn.simpleicons.org/linear/5E6AD2',
19
+ 'brave-search': 'https://cdn.simpleicons.org/brave/FB542B',
20
+ 'home-assistant': 'https://cdn.simpleicons.org/homeassistant/18BCF2',
21
+ sentry: 'https://cdn.simpleicons.org/sentry/362D59',
22
+ elevenlabs: 'https://cdn.simpleicons.org/elevenlabs/white',
23
+ hubspot: 'https://cdn.simpleicons.org/hubspot/FF7A59',
24
+ jira: 'https://cdn.simpleicons.org/jira/0052CC',
25
+ sendgrid: 'https://cdn.simpleicons.org/sendgrid/1A82E2',
26
+ resend: 'https://cdn.simpleicons.org/resend/white',
27
+ replicate: 'https://cdn.simpleicons.org/replicate/white',
28
+ vercel: 'https://cdn.simpleicons.org/vercel/white',
29
+ supabase: 'https://cdn.simpleicons.org/supabase/3FCF8E',
30
+ mixpanel: 'https://cdn.simpleicons.org/mixpanel/7856FF',
31
+ datadog: 'https://cdn.simpleicons.org/datadog/632CA6',
32
+ airtable: 'https://cdn.simpleicons.org/airtable/18BFFF',
33
+ zendesk: 'https://cdn.simpleicons.org/zendesk/03363D',
34
+ intercom: 'https://cdn.simpleicons.org/intercom/6AFDEF',
35
+ twilio: 'https://cdn.simpleicons.org/twilio/F22F46',
36
+ telnyx: 'https://cdn.simpleicons.org/telnyx/00C08B',
37
+ aws: 'https://cdn.simpleicons.org/amazonaws/FF9900',
38
+ plaid: 'https://cdn.simpleicons.org/plaid/white',
39
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "groove-dev",
3
- "version": "0.27.27",
3
+ "version": "0.27.28",
4
4
  "description": "Open-source agent orchestration layer — the AI company OS. Local model agent engine (GGUF/Ollama/llama-server), HuggingFace model browser, MCP integrations (Slack, Gmail, Stripe, 15+), agent scheduling (cron), business roles (CMO, CFO, EA). GUI dashboard, multi-agent coordination, zero cold-start, infinite sessions. Works with Claude Code, Codex, Gemini CLI, Ollama, any local model.",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "author": "Groove Dev <hello@groovedev.ai> (https://groovedev.ai)",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groove-dev/cli",
3
- "version": "0.27.27",
3
+ "version": "0.27.28",
4
4
  "description": "GROOVE CLI — manage AI coding agents from your terminal",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groove-dev/daemon",
3
- "version": "0.27.27",
3
+ "version": "0.27.28",
4
4
  "description": "GROOVE daemon — agent orchestration engine",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",
@@ -9,7 +9,9 @@ import { spawn, execFile } from 'child_process';
9
9
  import { lookup as mimeLookup } from './mimetypes.js';
10
10
  import { listProviders, getProvider } from './providers/index.js';
11
11
  import { OllamaProvider } from './providers/ollama.js';
12
+ import { ClaudeCodeProvider } from './providers/claude-code.js';
12
13
  import { validateAgentConfig } from './validate.js';
14
+ import { ROLE_INTEGRATIONS } from './process.js';
13
15
 
14
16
  const __dirname = dirname(fileURLToPath(import.meta.url));
15
17
  const pkgVersion = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version;
@@ -179,6 +181,88 @@ export function createApi(app, daemon) {
179
181
  res.json({ ok: true });
180
182
  });
181
183
 
184
+ // --- Role-to-Integration Mapping ---
185
+
186
+ app.get('/api/roles/integrations', (req, res) => {
187
+ const roleFilter = req.query.role;
188
+ const entries = roleFilter ? { [roleFilter]: ROLE_INTEGRATIONS[roleFilter] || [] } : ROLE_INTEGRATIONS;
189
+ const result = {};
190
+ for (const [role, ids] of Object.entries(entries)) {
191
+ result[role] = (ids || []).map((id) => {
192
+ const status = daemon.integrations.getStatus(id);
193
+ const entry = daemon.integrations.registry.find((r) => r.id === id);
194
+ return {
195
+ id,
196
+ name: entry?.name || id,
197
+ installed: status?.installed || false,
198
+ configured: status?.configured || false,
199
+ authenticated: status?.authenticated || false,
200
+ };
201
+ });
202
+ }
203
+ if (roleFilter) return res.json(result[roleFilter] || []);
204
+ res.json(result);
205
+ });
206
+
207
+ app.post('/api/agents/preflight', (req, res) => {
208
+ const { role, integrations } = req.body || {};
209
+ if (!role || !Array.isArray(integrations)) {
210
+ return res.status(400).json({ error: 'role and integrations[] required' });
211
+ }
212
+ const issues = [];
213
+ for (const id of integrations) {
214
+ const status = daemon.integrations.getStatus(id);
215
+ const entry = daemon.integrations.registry.find((r) => r.id === id);
216
+ const name = entry?.name || id;
217
+ if (!status || !status.installed) {
218
+ issues.push({ integrationId: id, name, problem: 'not_installed' });
219
+ } else if (!status.configured) {
220
+ issues.push({ integrationId: id, name, problem: 'not_configured' });
221
+ } else if (!status.authenticated) {
222
+ issues.push({ integrationId: id, name, problem: 'not_authenticated' });
223
+ }
224
+ }
225
+ res.json({ ready: issues.length === 0, issues });
226
+ });
227
+
228
+ // --- Agent Integration Attach/Detach ---
229
+
230
+ app.post('/api/agents/:id/integrations/:integrationId', (req, res) => {
231
+ const agent = daemon.registry.get(req.params.id);
232
+ if (!agent) return res.status(404).json({ error: 'Agent not found' });
233
+
234
+ const integrationId = req.params.integrationId;
235
+ const status = daemon.integrations.getStatus(integrationId);
236
+ if (!status || !status.installed) {
237
+ return res.status(400).json({ error: `Integration not installed: ${integrationId}` });
238
+ }
239
+
240
+ const integrations = new Set(agent.integrations || []);
241
+ integrations.add(integrationId);
242
+ const updated = Array.from(integrations);
243
+
244
+ daemon.registry.update(req.params.id, { integrations: updated });
245
+ daemon.integrations.writeMcpJson(daemon.integrations.getActiveIntegrations());
246
+ daemon.integrations.refreshMcpJson();
247
+ daemon.audit.log('agent.integration.attach', { agentId: req.params.id, integrationId });
248
+ daemon.broadcast({ type: 'agent:integration:attach', agentId: req.params.id, integrationId });
249
+ res.json({ ok: true, integrations: updated });
250
+ });
251
+
252
+ app.delete('/api/agents/:id/integrations/:integrationId', (req, res) => {
253
+ const agent = daemon.registry.get(req.params.id);
254
+ if (!agent) return res.status(404).json({ error: 'Agent not found' });
255
+
256
+ const integrationId = req.params.integrationId;
257
+ const integrations = (agent.integrations || []).filter((id) => id !== integrationId);
258
+
259
+ daemon.registry.update(req.params.id, { integrations });
260
+ daemon.integrations.refreshMcpJson();
261
+ daemon.audit.log('agent.integration.detach', { agentId: req.params.id, integrationId });
262
+ daemon.broadcast({ type: 'agent:integration:detach', agentId: req.params.id, integrationId });
263
+ res.json({ ok: true, integrations });
264
+ });
265
+
182
266
  // Lock management
183
267
  app.get('/api/locks', (req, res) => {
184
268
  res.json(daemon.locks.getAll());
@@ -307,10 +391,25 @@ export function createApi(app, daemon) {
307
391
  // Enrich with credential status
308
392
  for (const p of providers) {
309
393
  p.hasKey = daemon.credentials.hasKey(p.id);
394
+ if (p.id === 'claude-code') {
395
+ p.authStatus = ClaudeCodeProvider.getAuthStatus();
396
+ }
310
397
  }
311
398
  res.json(providers);
312
399
  });
313
400
 
401
+ // --- Claude Code Auth ---
402
+
403
+ app.get('/api/providers/claude-code/auth', (req, res) => {
404
+ res.json(ClaudeCodeProvider.getAuthStatus());
405
+ });
406
+
407
+ app.post('/api/providers/claude-code/login', (req, res) => {
408
+ ClaudeCodeProvider.triggerLogin();
409
+ daemon.audit.log('claude-code.login.started', {});
410
+ res.json({ ok: true });
411
+ });
412
+
314
413
  // --- Ollama ---
315
414
 
316
415
  app.get('/api/providers/ollama/hardware', (req, res) => {
@@ -266,6 +266,18 @@ IMPORTANT: Do not use markdown formatting like ** or ### in your output. Write i
266
266
  `,
267
267
  };
268
268
 
269
+ // Role-to-integration mapping — recommended integrations per role for onboarding preflight
270
+ export const ROLE_INTEGRATIONS = {
271
+ ea: ['gmail', 'google-calendar'],
272
+ cmo: ['gmail', 'slack', 'hubspot'],
273
+ cfo: ['stripe', 'google-sheets'],
274
+ support: ['gmail', 'slack', 'zendesk'],
275
+ analyst: ['google-sheets', 'postgres', 'mixpanel'],
276
+ home: ['home-assistant'],
277
+ slides: ['google-slides'],
278
+ creative: ['google-docs'],
279
+ };
280
+
269
281
  // Permission-level prompt instructions
270
282
  // "auto" = PM reviews risky ops via API. "full" = no reviews, max speed.
271
283
  const PERMISSION_PROMPTS = {
@@ -1,7 +1,7 @@
1
1
  // GROOVE — Claude Code Provider
2
2
  // FSL-1.1-Apache-2.0 — see LICENSE
3
3
 
4
- import { execSync } from 'child_process';
4
+ import { execSync, spawn as cpSpawn } from 'child_process';
5
5
  import { writeFileSync, readFileSync, existsSync } from 'fs';
6
6
  import { resolve } from 'path';
7
7
  import { homedir } from 'os';
@@ -223,4 +223,29 @@ export class ClaudeCodeProvider extends Provider {
223
223
 
224
224
  return merged;
225
225
  }
226
+
227
+ static getAuthStatus() {
228
+ try {
229
+ const out = execSync('claude auth status --json', { encoding: 'utf8', timeout: 10_000, stdio: ['pipe', 'pipe', 'pipe'] });
230
+ const data = JSON.parse(out);
231
+ return {
232
+ authenticated: true,
233
+ authMethod: data.authMethod || data.auth_method || 'unknown',
234
+ email: data.email || null,
235
+ subscriptionType: data.subscriptionType || data.subscription_type || null,
236
+ orgName: data.orgName || data.org_name || null,
237
+ };
238
+ } catch (err) {
239
+ return { authenticated: false, error: err.message };
240
+ }
241
+ }
242
+
243
+ static triggerLogin() {
244
+ const child = cpSpawn('claude', ['auth', 'login', '--claudeai'], {
245
+ detached: true,
246
+ stdio: 'ignore',
247
+ });
248
+ child.unref();
249
+ return { pid: child.pid };
250
+ }
226
251
  }