groove-dev 0.27.110 → 0.27.112

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 (43) hide show
  1. package/EMBEDDING_SERVICE_BUILD_PLAN.md +200 -0
  2. package/TRAINING_DATA_v2.md +9 -0
  3. package/moe-training/client/consent.js +47 -55
  4. package/moe-training/client/domain-tagger.js +3 -1
  5. package/moe-training/client/trajectory-capture.js +3 -2
  6. package/moe-training/shared/constants.js +1 -0
  7. package/moe-training/test/client/consent.test.js +23 -20
  8. package/moe-training/test/client/domain-tagger.test.js +6 -4
  9. package/node_modules/@groove-dev/cli/package.json +1 -1
  10. package/node_modules/@groove-dev/daemon/package.json +1 -1
  11. package/node_modules/@groove-dev/daemon/src/api.js +24 -42
  12. package/node_modules/@groove-dev/daemon/src/index.js +8 -10
  13. package/node_modules/@groove-dev/gui/dist/assets/{index-B8JomvGM.js → index-CHu5w3i3.js} +1 -1
  14. package/node_modules/@groove-dev/gui/dist/index.html +1 -1
  15. package/node_modules/@groove-dev/gui/package.json +1 -1
  16. package/node_modules/@groove-dev/gui/src/stores/groove.js +1 -1
  17. package/node_modules/moe-training/client/consent.js +47 -55
  18. package/node_modules/moe-training/client/domain-tagger.js +3 -1
  19. package/node_modules/moe-training/client/trajectory-capture.js +3 -2
  20. package/node_modules/moe-training/shared/constants.js +1 -0
  21. package/node_modules/moe-training/test/client/consent.test.js +23 -20
  22. package/node_modules/moe-training/test/client/domain-tagger.test.js +6 -4
  23. package/package.json +1 -1
  24. package/packages/cli/package.json +1 -1
  25. package/packages/daemon/package.json +1 -1
  26. package/packages/daemon/src/api.js +24 -42
  27. package/packages/daemon/src/index.js +8 -10
  28. package/packages/gui/dist/assets/{index-B8JomvGM.js → index-CHu5w3i3.js} +1 -1
  29. package/packages/gui/dist/index.html +1 -1
  30. package/packages/gui/package.json +1 -1
  31. package/packages/gui/src/stores/groove.js +1 -1
  32. package/TRAINING_DATA.md +0 -12
  33. package/codex/browser-racing-game/README.md +0 -45
  34. package/codex/browser-racing-game/dist/assets/index-D-sGTraQ.js +0 -47
  35. package/codex/browser-racing-game/dist/assets/index-S75nJv69.css +0 -1
  36. package/codex/browser-racing-game/dist/index.html +0 -14
  37. package/codex/browser-racing-game/index.html +0 -13
  38. package/codex/browser-racing-game/package-lock.json +0 -841
  39. package/codex/browser-racing-game/package.json +0 -15
  40. package/codex/browser-racing-game/src/app.css +0 -359
  41. package/codex/browser-racing-game/src/main.ts +0 -913
  42. package/codex/browser-racing-game/tsconfig.json +0 -20
  43. package/codex/browser-racing-game/vite.config.ts +0 -12
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groove-dev/daemon",
3
- "version": "0.27.110",
3
+ "version": "0.27.112",
4
4
  "description": "GROOVE daemon — agent orchestration engine",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",
@@ -112,7 +112,7 @@ export function createApi(app, daemon) {
112
112
  res.setHeader('Content-Security-Policy', "default-src * 'unsafe-inline' 'unsafe-eval' data: blob:; frame-ancestors 'self'");
113
113
  } else {
114
114
  res.setHeader('X-Frame-Options', 'DENY');
115
- res.setHeader('Content-Security-Policy', "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; connect-src 'self' ws://localhost:* ws://127.0.0.1:* http://localhost:* http://127.0.0.1:*; font-src 'self' data:; object-src 'none'; base-uri 'self'; frame-src 'self'; frame-ancestors 'none'");
115
+ res.setHeader('Content-Security-Policy', "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; connect-src 'self' ws://localhost:* ws://127.0.0.1:* http://localhost:* http://127.0.0.1:*; font-src 'self' data:; object-src 'none'; base-uri 'self'; frame-src 'self' http://127.0.0.1:* http://localhost:*; frame-ancestors 'none'");
116
116
  }
117
117
  next();
118
118
  });
@@ -4855,9 +4855,13 @@ Keep responses concise. Help them think, don't lecture them about the system the
4855
4855
 
4856
4856
  app.get('/api/training/status', (req, res) => {
4857
4857
  let userId = null;
4858
- try { userId = ConsentManager.isCaptureEnabled() ? ConsentManager.getOrCreateUserId() : null; } catch (e) { /* no db yet */ }
4858
+ let optedIn = false;
4859
+ try {
4860
+ userId = ConsentManager.getOrCreateUserId();
4861
+ optedIn = ConsentManager.isCaptureEnabled();
4862
+ } catch (e) { /* */ }
4859
4863
  res.json({
4860
- optedIn: !!daemon.config.training_opt_in,
4864
+ optedIn,
4861
4865
  userId: userId ? userId.substring(0, 8) + '...' : null,
4862
4866
  captureActive: !!daemon.trajectoryCapture,
4863
4867
  sessionsCaptured: daemon.state.get('training_sessions_captured') || 0,
@@ -4869,39 +4873,23 @@ Keep responses concise. Help them think, don't lecture them about the system the
4869
4873
  const { enabled } = req.body;
4870
4874
  if (typeof enabled !== 'boolean') return res.status(400).json({ error: 'enabled must be boolean' });
4871
4875
 
4872
- daemon.config.training_opt_in = enabled;
4873
- const { saveConfig } = await import('./firstrun.js');
4874
- saveConfig(daemon.grooveDir, daemon.config);
4875
-
4876
- if (enabled) {
4877
- try {
4878
- const userId = ConsentManager.getOrCreateUserId();
4879
- const consent = new ConsentManager();
4880
- try {
4881
- consent.recordConsent(userId, true, '1.0');
4882
- } finally {
4883
- consent.close();
4884
- }
4876
+ try {
4877
+ const userId = ConsentManager.getOrCreateUserId();
4878
+ const consent = new ConsentManager();
4879
+ if (enabled) {
4880
+ consent.recordConsent(userId, true, '1.0');
4885
4881
  await daemon._initTrajectoryCapture();
4886
4882
  daemon.state.set('training_enrolled_at', new Date().toISOString());
4887
- } catch (e) {
4888
- daemon.config.training_opt_in = false;
4889
- return res.status(500).json({ error: 'Failed to enable data sharing', detail: e.message });
4890
- }
4891
- } else {
4892
- if (daemon.trajectoryCapture) {
4893
- try { await daemon.trajectoryCapture.shutdown(); } catch (e) { /* */ }
4894
- daemon.trajectoryCapture = null;
4895
- }
4896
- try {
4897
- const userId = ConsentManager.getOrCreateUserId();
4898
- const consent = new ConsentManager();
4899
- try {
4900
- consent.revokeConsent(userId);
4901
- } finally {
4902
- consent.close();
4883
+ } else {
4884
+ consent.revokeConsent(userId);
4885
+ if (daemon.trajectoryCapture) {
4886
+ try { await daemon.trajectoryCapture.shutdown(); } catch (e) { /* */ }
4887
+ daemon.trajectoryCapture = null;
4903
4888
  }
4904
- } catch (e) { /* no user_id yet */ }
4889
+ }
4890
+ } catch (e) {
4891
+ console.error('[training/opt-in] Failed to update data sharing:', e);
4892
+ return res.status(500).json({ error: 'Failed to update data sharing', detail: e.message });
4905
4893
  }
4906
4894
 
4907
4895
  daemon.broadcast({ type: 'training:status', data: { optedIn: enabled, captureActive: !!daemon.trajectoryCapture } });
@@ -4911,18 +4899,13 @@ Keep responses concise. Help them think, don't lecture them about the system the
4911
4899
 
4912
4900
  app.post('/api/training/opt-in/delete', async (req, res) => {
4913
4901
  try {
4914
- daemon.config.training_opt_in = false;
4915
- const { saveConfig } = await import('./firstrun.js');
4916
- saveConfig(daemon.grooveDir, daemon.config);
4902
+ const userId = ConsentManager.getOrCreateUserId();
4903
+ const consent = new ConsentManager();
4904
+ consent.revokeConsent(userId);
4917
4905
  if (daemon.trajectoryCapture) {
4918
4906
  try { await daemon.trajectoryCapture.shutdown(); } catch (e) { /* */ }
4919
4907
  daemon.trajectoryCapture = null;
4920
4908
  }
4921
- try {
4922
- const userId = ConsentManager.getOrCreateUserId();
4923
- const consent = new ConsentManager();
4924
- try { consent.revokeConsent(userId); } finally { consent.close(); }
4925
- } catch (e) { /* */ }
4926
4909
  daemon.broadcast({ type: 'training:status', data: { optedIn: false, captureActive: false } });
4927
4910
  if (daemon.audit) daemon.audit.log('training.delete', {});
4928
4911
  res.json({ ok: true, deleted: true });
@@ -4948,7 +4931,6 @@ Keep responses concise. Help them think, don't lecture them about the system the
4948
4931
  'port', 'journalistInterval', 'rotationThreshold', 'autoRotation',
4949
4932
  'qcThreshold', 'maxAgents', 'defaultProvider', 'defaultWorkingDir',
4950
4933
  'onboardingDismissed', 'defaultModel', 'defaultChatProvider', 'defaultChatModel',
4951
- 'training_opt_in',
4952
4934
  ];
4953
4935
  for (const key of Object.keys(req.body)) {
4954
4936
  if (!ALLOWED_KEYS.includes(key)) {
@@ -666,17 +666,15 @@ export class Daemon {
666
666
  }
667
667
 
668
668
  async _initTrajectoryCapture() {
669
- if (!this.config.training_opt_in) return;
670
669
  try {
671
- if (ConsentManager.isCaptureEnabled()) {
672
- const pkgPath = new URL('../package.json', import.meta.url);
673
- const version = JSON.parse(readFileSync(pkgPath, 'utf8')).version;
674
- this.trajectoryCapture = new TrajectoryCapture({
675
- centralCommandUrl: process.env.GROOVE_CENTRAL_URL || 'https://api.groovedev.ai',
676
- grooveVersion: version,
677
- });
678
- this.trajectoryCapture.init();
679
- }
670
+ if (!ConsentManager.isCaptureEnabled()) return;
671
+ const pkgPath = new URL('../package.json', import.meta.url);
672
+ const version = JSON.parse(readFileSync(pkgPath, 'utf8')).version;
673
+ this.trajectoryCapture = new TrajectoryCapture({
674
+ centralCommandUrl: process.env.GROOVE_CENTRAL_URL || 'https://api.groovedev.ai',
675
+ grooveVersion: version,
676
+ });
677
+ this.trajectoryCapture.init();
680
678
  } catch (e) {
681
679
  // Training capture is never critical
682
680
  }