groove-dev 0.27.6 → 0.27.7

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.27.7 — Revert classifier broadcast — was eating stdout events (2026-04-12)
4
+
5
+ Planner was producing complete plans (confirmed in stream-json log: full result event, 1.9min, 10 turns, stop_reason end_turn), but the GUI wasn't rendering the final message. Last visible chat was an early exploration message; the plan and subsequent updates never reached the chat UI.
6
+
7
+ **Root cause.** v0.27.5 added `classifier:update` broadcasts inside `classifier.addEvent()` — which runs synchronously on EVERY stdout event in `process.js` stdout handler, BEFORE the `agent:output` broadcast that actually delivers messages to the chat. Any throw in the added code path (classify iteration, broadcast JSON.stringify on large event contents) would kill the stdout handler for that chunk. The `agent:output` broadcast at line 644 never fires. The plan is silently lost mid-transit.
8
+
9
+ The v0.26.39 classifier didn't broadcast — it just recorded events. That's why it worked. Shipping the revert.
10
+
11
+ **Reverted**
12
+ - `classifier.js` — full restore to v0.26.39. No `daemon` constructor arg, no `broadcast()` call, no `_lastBroadcastCount` throttle.
13
+ - `index.js` — `new TaskClassifier()` (back to no-arg constructor).
14
+
15
+ **Consequence**
16
+ - GUI no longer gets mid-session `classifier:update` events. The downshift suggestion API (`GET /api/agents/:id/routing/suggestion`) still works, just won't push real-time updates. This was a Phase 5 enhancement that wasn't worth breaking message delivery for.
17
+
3
18
  ## v0.27.6 — Revert rotator safety triggers — kill switch was killing planners (2026-04-12)
4
19
 
5
20
  User noticed rotations happening at 25-35% context window — way below the 75% threshold. Root cause: quality-based rotation was firing during planner thinking phases. Chain:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groove-dev/cli",
3
- "version": "0.27.6",
3
+ "version": "0.27.7",
4
4
  "description": "GROOVE CLI \u2014 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.6",
3
+ "version": "0.27.7",
4
4
  "description": "GROOVE daemon — agent orchestration engine",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",
@@ -35,11 +35,9 @@ const LIGHT_SIGNALS = [
35
35
  ];
36
36
 
37
37
  export class TaskClassifier {
38
- constructor(daemon = null) {
38
+ constructor() {
39
39
  this.windowSize = 200; // Large enough for quality signal extraction across tool calls
40
40
  this.agentWindows = {}; // for degradation detection and adaptive scoring
41
- this.daemon = daemon; // optional — enables broadcast of classification updates
42
- this._lastBroadcastCount = {}; // per-agent throttle
43
41
  }
44
42
 
45
43
  addEvent(agentId, event) {
@@ -77,23 +75,6 @@ export class TaskClassifier {
77
75
  window.push({ ...event, timestamp: event.timestamp || Date.now() });
78
76
  }
79
77
  while (window.length > this.windowSize) window.shift();
80
-
81
- // Broadcast classification updates periodically. Enables GUI to surface
82
- // downshift suggestions ("agent's been doing light work — switch to Haiku?").
83
- // Requires 40+ events before any broadcast; throttles to every 20 events.
84
- if (this.daemon?.broadcast && window.length >= 40) {
85
- const lastBroadcast = this._lastBroadcastCount[agentId] || 0;
86
- if (window.length - lastBroadcast >= 20) {
87
- this._lastBroadcastCount[agentId] = window.length;
88
- const tier = this.classify(agentId);
89
- this.daemon.broadcast({
90
- type: 'classifier:update',
91
- agentId,
92
- tier,
93
- eventCount: window.length,
94
- });
95
- }
96
- }
97
78
  }
98
79
 
99
80
  // Classify current activity for an agent
@@ -122,7 +122,7 @@ export class Daemon {
122
122
  this.adaptive = new AdaptiveThresholds(this.grooveDir);
123
123
  this.teams = new Teams(this);
124
124
  this.credentials = new CredentialStore(this.grooveDir);
125
- this.classifier = new TaskClassifier(this);
125
+ this.classifier = new TaskClassifier();
126
126
  this.router = new ModelRouter(this);
127
127
  this.pm = new ProjectManager(this);
128
128
  this.indexer = new CodebaseIndexer(this);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groove-dev/gui",
3
- "version": "0.27.6",
3
+ "version": "0.27.7",
4
4
  "description": "GROOVE GUI — visual agent control plane",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "groove-dev",
3
- "version": "0.27.6",
3
+ "version": "0.27.7",
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.6",
3
+ "version": "0.27.7",
4
4
  "description": "GROOVE CLI \u2014 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.6",
3
+ "version": "0.27.7",
4
4
  "description": "GROOVE daemon — agent orchestration engine",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",
@@ -35,11 +35,9 @@ const LIGHT_SIGNALS = [
35
35
  ];
36
36
 
37
37
  export class TaskClassifier {
38
- constructor(daemon = null) {
38
+ constructor() {
39
39
  this.windowSize = 200; // Large enough for quality signal extraction across tool calls
40
40
  this.agentWindows = {}; // for degradation detection and adaptive scoring
41
- this.daemon = daemon; // optional — enables broadcast of classification updates
42
- this._lastBroadcastCount = {}; // per-agent throttle
43
41
  }
44
42
 
45
43
  addEvent(agentId, event) {
@@ -77,23 +75,6 @@ export class TaskClassifier {
77
75
  window.push({ ...event, timestamp: event.timestamp || Date.now() });
78
76
  }
79
77
  while (window.length > this.windowSize) window.shift();
80
-
81
- // Broadcast classification updates periodically. Enables GUI to surface
82
- // downshift suggestions ("agent's been doing light work — switch to Haiku?").
83
- // Requires 40+ events before any broadcast; throttles to every 20 events.
84
- if (this.daemon?.broadcast && window.length >= 40) {
85
- const lastBroadcast = this._lastBroadcastCount[agentId] || 0;
86
- if (window.length - lastBroadcast >= 20) {
87
- this._lastBroadcastCount[agentId] = window.length;
88
- const tier = this.classify(agentId);
89
- this.daemon.broadcast({
90
- type: 'classifier:update',
91
- agentId,
92
- tier,
93
- eventCount: window.length,
94
- });
95
- }
96
- }
97
78
  }
98
79
 
99
80
  // Classify current activity for an agent
@@ -122,7 +122,7 @@ export class Daemon {
122
122
  this.adaptive = new AdaptiveThresholds(this.grooveDir);
123
123
  this.teams = new Teams(this);
124
124
  this.credentials = new CredentialStore(this.grooveDir);
125
- this.classifier = new TaskClassifier(this);
125
+ this.classifier = new TaskClassifier();
126
126
  this.router = new ModelRouter(this);
127
127
  this.pm = new ProjectManager(this);
128
128
  this.indexer = new CodebaseIndexer(this);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groove-dev/gui",
3
- "version": "0.27.6",
3
+ "version": "0.27.7",
4
4
  "description": "GROOVE GUI — visual agent control plane",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",