groove-dev 0.27.26 → 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 (49) hide show
  1. package/.groove-staging/state.json +3 -0
  2. package/.groove-staging/timeline.json +13 -0
  3. package/CLAUDE.md +0 -10
  4. package/DECENTRALIZED_NET_WP_V1.md +871 -0
  5. package/README.md +28 -0
  6. package/SECURITY_SWEEP.md +228 -0
  7. package/decentralized-net/ACTION_PLAN.md +422 -0
  8. package/node_modules/@groove-dev/cli/package.json +1 -1
  9. package/node_modules/@groove-dev/daemon/package.json +1 -1
  10. package/node_modules/@groove-dev/daemon/src/api.js +99 -0
  11. package/node_modules/@groove-dev/daemon/src/introducer.js +7 -7
  12. package/node_modules/@groove-dev/daemon/src/journalist.js +36 -6
  13. package/node_modules/@groove-dev/daemon/src/memory.js +29 -10
  14. package/node_modules/@groove-dev/daemon/src/process.js +29 -12
  15. package/node_modules/@groove-dev/daemon/src/providers/claude-code.js +26 -1
  16. package/node_modules/@groove-dev/daemon/src/providers/codex.js +34 -11
  17. package/node_modules/@groove-dev/daemon/src/rotator.js +24 -1
  18. package/node_modules/@groove-dev/daemon/test/introducer.test.js +63 -0
  19. package/node_modules/@groove-dev/daemon/test/journalist.test.js +106 -0
  20. package/node_modules/@groove-dev/daemon/test/memory.test.js +49 -0
  21. package/node_modules/@groove-dev/daemon/test/rotator.test.js +99 -0
  22. package/node_modules/@groove-dev/gui/dist/assets/{index-DieCV-v1.js → index-Ch1N9G4Z.js} +1728 -1728
  23. package/node_modules/@groove-dev/gui/dist/index.html +1 -1
  24. package/node_modules/@groove-dev/gui/package.json +1 -1
  25. package/node_modules/@groove-dev/gui/src/components/agents/agent-config.jsx +147 -21
  26. package/node_modules/@groove-dev/gui/src/components/agents/spawn-wizard.jsx +206 -44
  27. package/node_modules/@groove-dev/gui/src/components/marketplace/integration-wizard.jsx +11 -24
  28. package/node_modules/@groove-dev/gui/src/components/marketplace/marketplace-card.jsx +1 -36
  29. package/node_modules/@groove-dev/gui/src/lib/integration-logos.js +39 -0
  30. package/package.json +1 -1
  31. package/packages/cli/package.json +1 -1
  32. package/packages/daemon/package.json +1 -1
  33. package/packages/daemon/src/api.js +99 -0
  34. package/packages/daemon/src/introducer.js +7 -7
  35. package/packages/daemon/src/journalist.js +36 -6
  36. package/packages/daemon/src/memory.js +29 -10
  37. package/packages/daemon/src/process.js +29 -12
  38. package/packages/daemon/src/providers/claude-code.js +26 -1
  39. package/packages/daemon/src/providers/codex.js +34 -11
  40. package/packages/daemon/src/rotator.js +24 -1
  41. package/packages/gui/dist/assets/{index-DieCV-v1.js → index-Ch1N9G4Z.js} +1728 -1728
  42. package/packages/gui/dist/index.html +1 -1
  43. package/packages/gui/package.json +1 -1
  44. package/packages/gui/src/components/agents/agent-config.jsx +147 -21
  45. package/packages/gui/src/components/agents/spawn-wizard.jsx +206 -44
  46. package/packages/gui/src/components/marketplace/integration-wizard.jsx +11 -24
  47. package/packages/gui/src/components/marketplace/marketplace-card.jsx +1 -36
  48. package/packages/gui/src/lib/integration-logos.js +39 -0
  49. package/MUST_FIX_ISSUES.md +0 -305
@@ -335,6 +335,61 @@ describe('Rotator', () => {
335
335
  assert.equal(tokenCeilingRotations.length, 0);
336
336
  });
337
337
 
338
+ it('should trigger estimated_context_ceiling when contextUsage is stale', async () => {
339
+ // Simulates a Codex agent that never reports contextUsage updates.
340
+ // The agent has consumed 200K tokens (100% of maxContext) but contextUsage stayed at 0.
341
+ const agent = {
342
+ id: 'cx1', name: 'codex-stale', role: 'backend', status: 'running',
343
+ provider: 'codex', scope: [], model: 'gpt-5.4',
344
+ tokensUsed: 200_000, contextUsage: 0, workingDir: '/tmp',
345
+ lastActivity: new Date(Date.now() - 30_000).toISOString(),
346
+ spawnedAt: new Date(Date.now() - 300_000).toISOString(),
347
+ };
348
+ mockDaemon.registry.agents = [agent];
349
+
350
+ // First check — records the initial contextUsage state
351
+ await rotator.check();
352
+ assert.equal(rotator.getHistory().length, 0); // No rotation yet
353
+
354
+ // Simulate 120+ seconds of stale contextUsage by backdating the timestamp
355
+ const state = rotator._lastContextState.get('cx1');
356
+ state.timestamp = Date.now() - 130_000; // 130s ago
357
+
358
+ // Second check — stale context + high tokens should trigger estimated_context_ceiling
359
+ await rotator.check();
360
+
361
+ const history = rotator.getHistory();
362
+ assert.equal(history.length, 1);
363
+ assert.equal(history[0].reason, 'estimated_context_ceiling');
364
+ });
365
+
366
+ it('should NOT trigger estimated_context_ceiling when tokens are below HARD_CEILING', async () => {
367
+ const agent = {
368
+ id: 'cx2', name: 'codex-low', role: 'backend', status: 'running',
369
+ provider: 'codex', scope: [], model: 'gpt-5.4',
370
+ tokensUsed: 50_000, contextUsage: 0, workingDir: '/tmp',
371
+ lastActivity: new Date(Date.now() - 30_000).toISOString(),
372
+ spawnedAt: new Date(Date.now() - 300_000).toISOString(),
373
+ };
374
+ mockDaemon.registry.agents = [agent];
375
+
376
+ // First check to record state
377
+ await rotator.check();
378
+ const state = rotator._lastContextState.get('cx2');
379
+ state.timestamp = Date.now() - 130_000;
380
+
381
+ // Second check — 50K/200K = 25%, below 80% ceiling
382
+ await rotator.check();
383
+
384
+ const history = rotator.getHistory();
385
+ assert.equal(history.length, 0);
386
+ });
387
+
388
+ it('should include estimatedCeilingRotations in stats', () => {
389
+ const stats = rotator.getStats();
390
+ assert.equal(stats.estimatedCeilingRotations, 0);
391
+ });
392
+
338
393
  it('should record lastRotationTime after successful rotation', async () => {
339
394
  const agent = {
340
395
  id: 'a3', name: 'backend-3', role: 'backend',
@@ -352,4 +407,48 @@ describe('Rotator', () => {
352
407
  const elapsed = Date.now() - rotator.lastRotationTime.get(newAgent.id);
353
408
  assert.ok(elapsed < 1000); // Should be very recent
354
409
  });
410
+
411
+ it('should pass isRotation flag through spawn config', async () => {
412
+ let spawnConfig = null;
413
+ mockDaemon.processes.spawn = async (config) => {
414
+ spawnConfig = config;
415
+ return { id: 'new-' + config.role, name: config.name, ...config };
416
+ };
417
+
418
+ const agent = {
419
+ id: 'a4', name: 'backend-4', role: 'backend',
420
+ provider: 'claude-code', scope: [], model: null,
421
+ tokensUsed: 3000, contextUsage: 0.9, workingDir: '/tmp',
422
+ teamId: 'team-1',
423
+ };
424
+ mockDaemon.registry.agents = [agent];
425
+
426
+ await rotator.rotate('a4');
427
+
428
+ assert.ok(spawnConfig, 'spawn should have been called');
429
+ assert.equal(spawnConfig.isRotation, true, 'isRotation must be true for rotation spawns');
430
+ assert.equal(spawnConfig.teamId, 'team-1', 'teamId must be passed through');
431
+ });
432
+
433
+ it('should pass teamId to appendHandoffBrief', async () => {
434
+ let appendArgs = null;
435
+ mockDaemon.memory.appendHandoffBrief = (role, entry, workingDir, teamId) => {
436
+ appendArgs = { role, workingDir, teamId };
437
+ return true;
438
+ };
439
+
440
+ const agent = {
441
+ id: 'a5', name: 'backend-5', role: 'backend',
442
+ provider: 'claude-code', scope: [], model: null,
443
+ tokensUsed: 3000, contextUsage: 0.9, workingDir: '/tmp',
444
+ teamId: 'team-alpha',
445
+ };
446
+ mockDaemon.registry.agents = [agent];
447
+
448
+ await rotator.rotate('a5');
449
+
450
+ assert.ok(appendArgs, 'appendHandoffBrief should have been called');
451
+ assert.equal(appendArgs.teamId, 'team-alpha');
452
+ assert.equal(appendArgs.role, 'backend');
453
+ });
355
454
  });