groove-dev 0.26.38 → 0.27.0
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 +59 -0
- package/CLAUDE.md +24 -19
- package/node_modules/@groove-dev/cli/bin/groove.js +2 -0
- package/node_modules/@groove-dev/cli/package.json +1 -1
- package/node_modules/@groove-dev/cli/src/commands/nuke.js +16 -4
- package/node_modules/@groove-dev/cli/src/commands/stop.js +17 -2
- package/node_modules/@groove-dev/daemon/integrations-registry.json +681 -75
- package/node_modules/@groove-dev/daemon/package.json +1 -1
- package/node_modules/@groove-dev/daemon/src/adaptive.js +23 -25
- package/node_modules/@groove-dev/daemon/src/api.js +346 -22
- package/node_modules/@groove-dev/daemon/src/classifier.js +53 -6
- package/node_modules/@groove-dev/daemon/src/firstrun.js +14 -1
- package/node_modules/@groove-dev/daemon/src/gateways/manager.js +2 -2
- package/node_modules/@groove-dev/daemon/src/index.js +28 -4
- package/node_modules/@groove-dev/daemon/src/integrations.js +215 -14
- package/node_modules/@groove-dev/daemon/src/introducer.js +84 -11
- package/node_modules/@groove-dev/daemon/src/journalist.js +43 -1
- package/node_modules/@groove-dev/daemon/src/lockmanager.js +60 -0
- package/node_modules/@groove-dev/daemon/src/mcp-manager.js +270 -0
- package/node_modules/@groove-dev/daemon/src/memory.js +370 -0
- package/node_modules/@groove-dev/daemon/src/pm.js +1 -1
- package/node_modules/@groove-dev/daemon/src/process.js +141 -9
- package/node_modules/@groove-dev/daemon/src/registry.js +1 -1
- package/node_modules/@groove-dev/daemon/src/rotator.js +334 -31
- package/node_modules/@groove-dev/daemon/src/router.js +43 -0
- package/node_modules/@groove-dev/daemon/src/tokentracker.js +70 -18
- package/node_modules/@groove-dev/daemon/src/validate.js +5 -13
- package/node_modules/@groove-dev/daemon/templates/groove-slides.cjs +306 -0
- package/node_modules/@groove-dev/daemon/test/classifier.test.js +3 -5
- package/node_modules/@groove-dev/daemon/test/lockmanager.test.js +64 -0
- package/node_modules/@groove-dev/daemon/test/memory.test.js +252 -0
- package/node_modules/@groove-dev/daemon/test/rotator.test.js +108 -0
- package/node_modules/@groove-dev/daemon/test/router.test.js +64 -0
- package/node_modules/@groove-dev/daemon/test/slides-engine.test.js +230 -0
- package/node_modules/@groove-dev/daemon/test/tokentracker.test.js +78 -0
- package/node_modules/@groove-dev/gui/dist/assets/index-DjORRpF0.css +1 -0
- package/node_modules/@groove-dev/gui/dist/assets/index-eCrVowF0.js +652 -0
- package/node_modules/@groove-dev/gui/dist/index.html +2 -2
- package/node_modules/@groove-dev/gui/package.json +1 -4
- package/node_modules/@groove-dev/gui/src/components/agents/agent-chat.jsx +26 -17
- package/node_modules/@groove-dev/gui/src/components/agents/agent-config.jsx +22 -1
- package/node_modules/@groove-dev/gui/src/components/agents/agent-feed.jsx +53 -21
- package/node_modules/@groove-dev/gui/src/components/agents/agent-node.jsx +132 -90
- package/node_modules/@groove-dev/gui/src/components/agents/spawn-wizard.jsx +212 -1
- package/node_modules/@groove-dev/gui/src/components/dashboard/cache-ring.jsx +6 -2
- package/node_modules/@groove-dev/gui/src/components/dashboard/intel-panel.jsx +495 -174
- package/node_modules/@groove-dev/gui/src/components/dashboard/kpi-card.jsx +12 -2
- package/node_modules/@groove-dev/gui/src/components/dashboard/team-burn-panel.jsx +55 -0
- package/node_modules/@groove-dev/gui/src/components/layout/activity-bar.jsx +3 -3
- package/node_modules/@groove-dev/gui/src/components/layout/app-shell.jsx +24 -19
- package/node_modules/@groove-dev/gui/src/components/layout/command-palette.jsx +2 -2
- package/node_modules/@groove-dev/gui/src/components/marketplace/integration-wizard.jsx +391 -61
- package/node_modules/@groove-dev/gui/src/components/marketplace/marketplace-card.jsx +29 -7
- package/node_modules/@groove-dev/gui/src/lib/format.js +0 -6
- package/node_modules/@groove-dev/gui/src/lib/hooks/use-dashboard.js +23 -5
- package/node_modules/@groove-dev/gui/src/stores/groove.js +59 -9
- package/node_modules/@groove-dev/gui/src/views/agents.jsx +84 -10
- package/node_modules/@groove-dev/gui/src/views/dashboard.jsx +24 -21
- package/node_modules/@groove-dev/gui/src/views/marketplace.jsx +153 -85
- package/package.json +2 -8
- package/packages/cli/bin/groove.js +2 -0
- package/packages/cli/package.json +1 -1
- package/packages/cli/src/commands/nuke.js +16 -4
- package/packages/cli/src/commands/stop.js +17 -2
- package/packages/daemon/integrations-registry.json +681 -75
- package/packages/daemon/package.json +1 -1
- package/packages/daemon/src/adaptive.js +23 -25
- package/packages/daemon/src/api.js +346 -22
- package/packages/daemon/src/classifier.js +53 -6
- package/packages/daemon/src/firstrun.js +14 -1
- package/packages/daemon/src/gateways/manager.js +2 -2
- package/packages/daemon/src/index.js +28 -4
- package/packages/daemon/src/integrations.js +215 -14
- package/packages/daemon/src/introducer.js +84 -11
- package/packages/daemon/src/journalist.js +43 -1
- package/packages/daemon/src/lockmanager.js +60 -0
- package/packages/daemon/src/mcp-manager.js +270 -0
- package/packages/daemon/src/memory.js +370 -0
- package/packages/daemon/src/pm.js +1 -1
- package/packages/daemon/src/process.js +141 -9
- package/packages/daemon/src/registry.js +1 -1
- package/packages/daemon/src/rotator.js +334 -31
- package/packages/daemon/src/router.js +43 -0
- package/packages/daemon/src/tokentracker.js +70 -18
- package/packages/daemon/src/validate.js +5 -13
- package/packages/daemon/templates/groove-slides.cjs +306 -0
- package/packages/gui/dist/assets/index-DjORRpF0.css +1 -0
- package/packages/gui/dist/assets/index-eCrVowF0.js +652 -0
- package/packages/gui/dist/index.html +2 -2
- package/packages/gui/package.json +1 -4
- package/packages/gui/src/components/agents/agent-chat.jsx +26 -17
- package/packages/gui/src/components/agents/agent-config.jsx +22 -1
- package/packages/gui/src/components/agents/agent-feed.jsx +53 -21
- package/packages/gui/src/components/agents/agent-node.jsx +132 -90
- package/packages/gui/src/components/agents/spawn-wizard.jsx +212 -1
- package/packages/gui/src/components/dashboard/cache-ring.jsx +6 -2
- package/packages/gui/src/components/dashboard/intel-panel.jsx +495 -174
- package/packages/gui/src/components/dashboard/kpi-card.jsx +12 -2
- package/packages/gui/src/components/dashboard/team-burn-panel.jsx +55 -0
- package/packages/gui/src/components/layout/activity-bar.jsx +3 -3
- package/packages/gui/src/components/layout/app-shell.jsx +24 -19
- package/packages/gui/src/components/layout/command-palette.jsx +2 -2
- package/packages/gui/src/components/marketplace/integration-wizard.jsx +391 -61
- package/packages/gui/src/components/marketplace/marketplace-card.jsx +29 -7
- package/packages/gui/src/lib/format.js +0 -6
- package/packages/gui/src/lib/hooks/use-dashboard.js +23 -5
- package/packages/gui/src/stores/groove.js +59 -9
- package/packages/gui/src/views/agents.jsx +84 -10
- package/packages/gui/src/views/dashboard.jsx +24 -21
- package/packages/gui/src/views/marketplace.jsx +153 -85
- package/node_modules/@groove-dev/gui/dist/assets/index-CEFKgLGB.css +0 -1
- package/node_modules/@groove-dev/gui/dist/assets/index-CaKBNWcK.js +0 -638
- package/node_modules/@groove-dev/gui/dist/groove-logo-short.png +0 -0
- package/node_modules/@groove-dev/gui/dist/groove-logo.png +0 -0
- package/node_modules/@groove-dev/gui/public/groove-logo-short.png +0 -0
- package/node_modules/@groove-dev/gui/public/groove-logo.png +0 -0
- package/node_modules/@groove-dev/gui/src/components/ui/dropdown-menu.jsx +0 -60
- package/node_modules/@groove-dev/gui/src/lib/hooks/use-media-query.js +0 -18
- package/node_modules/@radix-ui/react-dropdown-menu/LICENSE +0 -21
- package/node_modules/@radix-ui/react-dropdown-menu/README.md +0 -3
- package/node_modules/@radix-ui/react-dropdown-menu/dist/index.d.mts +0 -97
- package/node_modules/@radix-ui/react-dropdown-menu/dist/index.d.ts +0 -97
- package/node_modules/@radix-ui/react-dropdown-menu/dist/index.js +0 -337
- package/node_modules/@radix-ui/react-dropdown-menu/dist/index.js.map +0 -7
- package/node_modules/@radix-ui/react-dropdown-menu/dist/index.mjs +0 -305
- package/node_modules/@radix-ui/react-dropdown-menu/dist/index.mjs.map +0 -7
- package/node_modules/@radix-ui/react-dropdown-menu/package.json +0 -75
- package/node_modules/@radix-ui/react-popover/LICENSE +0 -21
- package/node_modules/@radix-ui/react-popover/README.md +0 -3
- package/node_modules/@radix-ui/react-popover/dist/index.d.mts +0 -85
- package/node_modules/@radix-ui/react-popover/dist/index.d.ts +0 -85
- package/node_modules/@radix-ui/react-popover/dist/index.js +0 -352
- package/node_modules/@radix-ui/react-popover/dist/index.js.map +0 -7
- package/node_modules/@radix-ui/react-popover/dist/index.mjs +0 -320
- package/node_modules/@radix-ui/react-popover/dist/index.mjs.map +0 -7
- package/node_modules/@radix-ui/react-popover/package.json +0 -82
- package/node_modules/@radix-ui/react-separator/LICENSE +0 -21
- package/node_modules/@radix-ui/react-separator/README.md +0 -3
- package/node_modules/@radix-ui/react-separator/dist/index.d.mts +0 -21
- package/node_modules/@radix-ui/react-separator/dist/index.d.ts +0 -21
- package/node_modules/@radix-ui/react-separator/dist/index.js +0 -65
- package/node_modules/@radix-ui/react-separator/dist/index.js.map +0 -7
- package/node_modules/@radix-ui/react-separator/dist/index.mjs +0 -32
- package/node_modules/@radix-ui/react-separator/dist/index.mjs.map +0 -7
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive/LICENSE +0 -21
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive/README.md +0 -3
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive/dist/index.d.mts +0 -52
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive/dist/index.d.ts +0 -52
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive/dist/index.js +0 -80
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive/dist/index.js.map +0 -7
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive/dist/index.mjs +0 -47
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive/dist/index.mjs.map +0 -7
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive/package.json +0 -69
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-slot/LICENSE +0 -21
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-slot/README.md +0 -3
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-slot/dist/index.d.mts +0 -22
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-slot/dist/index.d.ts +0 -22
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-slot/dist/index.js +0 -152
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-slot/dist/index.js.map +0 -7
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-slot/dist/index.mjs +0 -119
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-slot/dist/index.mjs.map +0 -7
- package/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-slot/package.json +0 -64
- package/node_modules/@radix-ui/react-separator/package.json +0 -69
- package/packages/gui/dist/assets/index-CEFKgLGB.css +0 -1
- package/packages/gui/dist/assets/index-CaKBNWcK.js +0 -638
- package/packages/gui/dist/groove-logo-short.png +0 -0
- package/packages/gui/dist/groove-logo.png +0 -0
- package/packages/gui/public/groove-logo-short.png +0 -0
- package/packages/gui/public/groove-logo.png +0 -0
- package/packages/gui/src/components/ui/dropdown-menu.jsx +0 -60
- package/packages/gui/src/lib/hooks/use-media-query.js +0 -18
|
@@ -2,12 +2,19 @@
|
|
|
2
2
|
// FSL-1.1-Apache-2.0 — see LICENSE
|
|
3
3
|
|
|
4
4
|
import { spawn as cpSpawn } from 'child_process';
|
|
5
|
-
import { createWriteStream, mkdirSync, chmodSync, existsSync, readFileSync, unlinkSync, readdirSync } from 'fs';
|
|
6
|
-
import { resolve } from 'path';
|
|
5
|
+
import { createWriteStream, mkdirSync, chmodSync, existsSync, readFileSync, unlinkSync, readdirSync, copyFileSync } from 'fs';
|
|
6
|
+
import { resolve, dirname } from 'path';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
7
8
|
import { getProvider, getInstalledProviders } from './providers/index.js';
|
|
8
9
|
import { AgentLoop } from './agent-loop.js';
|
|
9
10
|
import { validateAgentConfig } from './validate.js';
|
|
10
11
|
|
|
12
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const SLIDES_ENGINE_SRC = resolve(__dirname, '../templates/groove-slides.cjs');
|
|
14
|
+
|
|
15
|
+
const COMPACTION_DROP_THRESHOLD = 0.25; // 25% drop from peak = natural compaction
|
|
16
|
+
const COMPACTION_MIN_PEAK = 0.15; // Ignore compaction if peak was below 15%
|
|
17
|
+
|
|
11
18
|
// Role-specific prompt prefixes — applied during spawn regardless of entry point
|
|
12
19
|
// (SpawnPanel, chat continue, CLI, API) for consistency
|
|
13
20
|
const ROLE_PROMPTS = {
|
|
@@ -84,7 +91,14 @@ When making visual changes, always read app.css for the color palette and existi
|
|
|
84
91
|
- Running tests (npm test) and builds (npm run build) to catch regressions
|
|
85
92
|
- Auditing changes from other agents for correctness and consistency
|
|
86
93
|
- Fixing integration issues that span the daemon/GUI boundary
|
|
87
|
-
|
|
94
|
+
|
|
95
|
+
CRITICAL — NEVER DO THESE:
|
|
96
|
+
- NEVER restart the Groove daemon. No "groove stop", "groove start", "groove nuke", "groove restart".
|
|
97
|
+
- NEVER kill the daemon process. No "kill <pid>", "pkill groove", "killall node", etc.
|
|
98
|
+
- NEVER run "./promote.sh", "./promote-local.sh", or any publish/deploy script.
|
|
99
|
+
- NEVER start long-running dev servers (vite dev, npm start, next dev, etc.).
|
|
100
|
+
|
|
101
|
+
Restarting the daemon destroys ALL other agents currently running in other teams. Verification is done via "npm run build" and "npm test", which exit cleanly. If code changes require a daemon restart to take effect, report that in your output so the user can restart manually — do NOT do it yourself.
|
|
88
102
|
|
|
89
103
|
`,
|
|
90
104
|
testing: `You are a Testing agent. You write and maintain test suites, improve coverage, and verify quality. Focus on:
|
|
@@ -127,12 +141,36 @@ IMPORTANT: Do NOT start long-running dev servers (vite dev, npm start, next dev,
|
|
|
127
141
|
- Writing database-related tests and verifying migration safety
|
|
128
142
|
|
|
129
143
|
`,
|
|
130
|
-
slides: `You are a Slide Deck agent. You build presentation decks as HTML slides (Reveal.js) with
|
|
144
|
+
slides: `You are a Slide Deck agent. You build presentation decks as HTML slides (Reveal.js) with a matching PPTX export. Focus on:
|
|
131
145
|
- Creating clean, professional slide layouts with strong visual hierarchy
|
|
132
|
-
- Structuring content into clear sections with concise
|
|
146
|
+
- Structuring content into clear sections with concise, editorial copy
|
|
133
147
|
- Building responsive HTML slides that look polished in the browser
|
|
134
|
-
- Generating a slides.json data file alongside HTML
|
|
135
|
-
|
|
148
|
+
- Generating a slides.json data file alongside HTML so PPTX export stays in sync
|
|
149
|
+
|
|
150
|
+
MANDATORY PPTX LAYOUT ENGINE — baked into Groove, not optional
|
|
151
|
+
|
|
152
|
+
A file called groove-slides.cjs has been written into your working directory. It is the layout engine — it does NOT define any theme or style. You MUST use it in your convert-slides.js (which must also be CommonJS — use require, not import). Do not re-implement its functions. Do not copy its contents into your own code.
|
|
153
|
+
|
|
154
|
+
const {
|
|
155
|
+
LAYOUT, estimateTextHeight, fitFontSize,
|
|
156
|
+
hardGate, tracker,
|
|
157
|
+
} = require('./groove-slides.cjs');
|
|
158
|
+
|
|
159
|
+
What the engine gives you:
|
|
160
|
+
- LAYOUT constants — SLIDE_W (10), SLIDE_H (5.625), SAFE_X (0.6), SAFE_W (8.8), SAFE_BOT (5.125), CONTENT_START (0.65), plus standard gaps. Any element whose y + h exceeds SAFE_BOT (5.125) is clipped off the slide — treat that as a build failure.
|
|
161
|
+
- estimateTextHeight(text, fontSize, boxW, {bold}) — returns the height the text will actually need.
|
|
162
|
+
- fitFontSize(text, maxSize, minSize, boxW, boxH, {bold}) — returns the largest integer font size that fits the text in the box. Use this for every headline, hero number, price, or any text that could wrap. It replaces shrinkText.
|
|
163
|
+
- tracker() — returns { track, placed }. Wrap EVERY slide.addText / slide.addShape call's options with track('element-name', {x, y, w, h, text, fontSize, bold, ...}) so the gate can inspect it.
|
|
164
|
+
- hardGate(pairs) — runs collision, bounds, and wrap checks over every slide. Calls process.exit(1) on any issue. Call it once, before pres.writeFile(), with allSlides.map(s => [s.name, s.elements]).
|
|
165
|
+
|
|
166
|
+
Non-negotiable rules:
|
|
167
|
+
1. Do NOT use shrinkText: true. PowerPoint honors it; Google Slides and LibreOffice PDF export largely do not — the text renders at its declared size and overflows. Compute a real font size with fitFontSize() instead.
|
|
168
|
+
2. Do NOT invent skipCollision, skipBounds, skipWrap, or any other opt-out flag on tracked elements. The engine rejects them with an error. If a design element legitimately extends past the safe area (e.g., an orb bleeding off-slide as atmosphere), call slide.addImage directly WITHOUT tracking it — the gate only validates elements you declare placed.
|
|
169
|
+
3. Y advances come from estimateTextHeight() or an explicit box budget (const titleBoxH = 1.2). Never write a hardcoded magic number like Y += 0.95.
|
|
170
|
+
4. Do NOT wrap hardGate() in try/catch. Do NOT run pres.writeFile() after a failing gate. If the gate fails, the deck is not shippable — fix the slide generator.
|
|
171
|
+
5. Track the brand watermark and category label you draw on every slide. If they are not in placed[], the gate cannot detect a title bleeding into them.
|
|
172
|
+
|
|
173
|
+
A marketplace skill (e.g., modern-pitch-deck) layers theme on top — color palette, typography choices, gradient backgrounds, visual components (orbs, charts, heatmaps), slide archetype patterns. Skills must NOT redefine the engine functions, reset LAYOUT constants, or introduce their own gate. If you see a skill doing any of those, ignore that part and keep using the engine as documented here.
|
|
136
174
|
|
|
137
175
|
`,
|
|
138
176
|
home: `You are a Smart Home automation agent. You have MCP integrations for Home Assistant. Focus on:
|
|
@@ -225,6 +263,7 @@ export class ProcessManager {
|
|
|
225
263
|
constructor(daemon) {
|
|
226
264
|
this.daemon = daemon;
|
|
227
265
|
this.handles = new Map(); // agentId -> { proc, logStream }
|
|
266
|
+
this.peakContextUsage = new Map(); // agentId -> highest contextUsage seen
|
|
228
267
|
}
|
|
229
268
|
|
|
230
269
|
async spawn(config) {
|
|
@@ -298,6 +337,20 @@ export class ProcessManager {
|
|
|
298
337
|
locks.register(agent.id, agent.scope);
|
|
299
338
|
}
|
|
300
339
|
|
|
340
|
+
// For slides-role agents, write the baked-in layout engine into the working
|
|
341
|
+
// directory. The agent imports it as `./groove-slides.cjs`. Core layout rules
|
|
342
|
+
// (Y-cursor, fitFontSize, collision/bounds/wrap gates) ship with Groove so
|
|
343
|
+
// they apply without a skill attached — skills only provide theme/style.
|
|
344
|
+
if (config.role === 'slides') {
|
|
345
|
+
try {
|
|
346
|
+
const dest = resolve(agent.workingDir || this.daemon.projectDir, 'groove-slides.cjs');
|
|
347
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
348
|
+
copyFileSync(SLIDES_ENGINE_SRC, dest);
|
|
349
|
+
} catch (err) {
|
|
350
|
+
console.log(`[Groove:Spawn] Failed to write groove-slides.cjs: ${err.message}`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
301
354
|
// Pre-spawn task negotiation — if same-role agents are running,
|
|
302
355
|
// query them about current work so the new agent gets a clear assignment
|
|
303
356
|
const sameRole = registry.getAll().filter(
|
|
@@ -469,9 +522,12 @@ For normal file edits within your scope, proceed without review.
|
|
|
469
522
|
|
|
470
523
|
// Write MCP config for agent integrations (command/args only, no secrets)
|
|
471
524
|
// Credentials are injected via process environment below
|
|
525
|
+
// Only write .mcp.json for claude-code — other providers use GROOVE's exec API
|
|
472
526
|
let integrationEnv = {};
|
|
473
527
|
if (config.integrations?.length > 0 && this.daemon.integrations) {
|
|
474
|
-
|
|
528
|
+
if (agent.provider === 'claude-code') {
|
|
529
|
+
this.daemon.integrations.writeMcpJson(config.integrations);
|
|
530
|
+
}
|
|
475
531
|
integrationEnv = this.daemon.integrations.getSpawnEnv(config.integrations);
|
|
476
532
|
}
|
|
477
533
|
|
|
@@ -571,6 +627,17 @@ For normal file edits within your scope, proceed without review.
|
|
|
571
627
|
}
|
|
572
628
|
if (output.contextUsage !== undefined) {
|
|
573
629
|
updates.contextUsage = output.contextUsage;
|
|
630
|
+
|
|
631
|
+
const peak = this.peakContextUsage.get(agent.id) || 0;
|
|
632
|
+
if (output.contextUsage > peak) {
|
|
633
|
+
this.peakContextUsage.set(agent.id, output.contextUsage);
|
|
634
|
+
} else if (peak >= COMPACTION_MIN_PEAK) {
|
|
635
|
+
const drop = peak - output.contextUsage;
|
|
636
|
+
if (drop >= COMPACTION_DROP_THRESHOLD * peak) {
|
|
637
|
+
this.daemon.rotator.recordNaturalCompaction(agent, peak, output.contextUsage);
|
|
638
|
+
this.peakContextUsage.set(agent.id, output.contextUsage);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
574
641
|
}
|
|
575
642
|
registry.update(agent.id, updates);
|
|
576
643
|
|
|
@@ -652,6 +719,25 @@ For normal file edits within your scope, proceed without review.
|
|
|
652
719
|
// Process cross-scope handoff requests from this agent
|
|
653
720
|
this._processHandoffs(agent);
|
|
654
721
|
}
|
|
722
|
+
|
|
723
|
+
// Update Layer 7 specialization profile for this agent's session
|
|
724
|
+
if (this.daemon.memory && (finalStatus === 'completed' || finalStatus === 'crashed')) {
|
|
725
|
+
try {
|
|
726
|
+
const events = this.daemon.classifier?.agentWindows?.[agent.id] || [];
|
|
727
|
+
const signals = events.length >= 6
|
|
728
|
+
? this.daemon.adaptive.extractSignals(events, agent.scope)
|
|
729
|
+
: null;
|
|
730
|
+
const score = signals ? this.daemon.adaptive.scoreSession(signals) : null;
|
|
731
|
+
const files = this.daemon.journalist?.getAgentFiles(agent) || [];
|
|
732
|
+
this.daemon.memory.updateSpecialization(agent.id, {
|
|
733
|
+
role: agent.role,
|
|
734
|
+
qualityScore: score,
|
|
735
|
+
filesTouched: files,
|
|
736
|
+
signals,
|
|
737
|
+
threshold: this.daemon.adaptive?.getThreshold(agent.provider, agent.role),
|
|
738
|
+
});
|
|
739
|
+
} catch { /* best-effort */ }
|
|
740
|
+
}
|
|
655
741
|
});
|
|
656
742
|
|
|
657
743
|
proc.on('error', (err) => {
|
|
@@ -716,6 +802,17 @@ For normal file edits within your scope, proceed without review.
|
|
|
716
802
|
// Context window usage (0-1 scale) — drives rotation threshold
|
|
717
803
|
if (output.contextUsage !== undefined) {
|
|
718
804
|
updates.contextUsage = output.contextUsage;
|
|
805
|
+
|
|
806
|
+
const peak = this.peakContextUsage.get(agentId) || 0;
|
|
807
|
+
if (output.contextUsage > peak) {
|
|
808
|
+
this.peakContextUsage.set(agentId, output.contextUsage);
|
|
809
|
+
} else if (peak >= COMPACTION_MIN_PEAK) {
|
|
810
|
+
const drop = peak - output.contextUsage;
|
|
811
|
+
if (drop >= COMPACTION_DROP_THRESHOLD * peak) {
|
|
812
|
+
this.daemon.rotator.recordNaturalCompaction(agent, peak, output.contextUsage);
|
|
813
|
+
this.peakContextUsage.set(agentId, output.contextUsage);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
719
816
|
}
|
|
720
817
|
|
|
721
818
|
// Session ID for resume support
|
|
@@ -1042,7 +1139,42 @@ For normal file edits within your scope, proceed without review.
|
|
|
1042
1139
|
return newAgent;
|
|
1043
1140
|
}
|
|
1044
1141
|
|
|
1142
|
+
/**
|
|
1143
|
+
* Stop the agent's current work without killing the agent.
|
|
1144
|
+
* The process is terminated but the agent stays in the registry with its
|
|
1145
|
+
* sessionId intact, so you can resume it later with a new message.
|
|
1146
|
+
*/
|
|
1147
|
+
async stop(agentId) {
|
|
1148
|
+
const handle = this.handles.get(agentId);
|
|
1149
|
+
if (!handle) return;
|
|
1150
|
+
|
|
1151
|
+
const { proc, loop } = handle;
|
|
1152
|
+
|
|
1153
|
+
if (loop) {
|
|
1154
|
+
await loop.stop();
|
|
1155
|
+
this.handles.delete(agentId);
|
|
1156
|
+
this.daemon.registry.update(agentId, { status: 'stopped', pid: null });
|
|
1157
|
+
return;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
return new Promise((resolveStop) => {
|
|
1161
|
+
const forceTimer = setTimeout(() => {
|
|
1162
|
+
try { proc.kill('SIGKILL'); } catch {}
|
|
1163
|
+
}, 5000);
|
|
1164
|
+
|
|
1165
|
+
proc.on('exit', () => {
|
|
1166
|
+
clearTimeout(forceTimer);
|
|
1167
|
+
this.handles.delete(agentId);
|
|
1168
|
+
this.daemon.registry.update(agentId, { status: 'stopped', pid: null });
|
|
1169
|
+
resolveStop();
|
|
1170
|
+
});
|
|
1171
|
+
|
|
1172
|
+
try { proc.kill('SIGTERM'); } catch { resolveStop(); }
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1045
1176
|
async kill(agentId) {
|
|
1177
|
+
this.peakContextUsage.delete(agentId);
|
|
1046
1178
|
const handle = this.handles.get(agentId);
|
|
1047
1179
|
|
|
1048
1180
|
if (!handle) {
|
|
@@ -1165,7 +1297,7 @@ For normal file edits within your scope, proceed without review.
|
|
|
1165
1297
|
].join('\n');
|
|
1166
1298
|
|
|
1167
1299
|
try {
|
|
1168
|
-
const response = await journalist.callHeadless(prompt);
|
|
1300
|
+
const response = await journalist.callHeadless(prompt, { trackAs: '__negotiator__' });
|
|
1169
1301
|
return response;
|
|
1170
1302
|
} catch {
|
|
1171
1303
|
// Fallback: return raw data for the agent to interpret
|
|
@@ -51,7 +51,7 @@ export class Registry extends EventEmitter {
|
|
|
51
51
|
if (!agent) return null;
|
|
52
52
|
|
|
53
53
|
// Only allow known fields to prevent prototype pollution
|
|
54
|
-
const SAFE_FIELDS = ['status', 'pid', 'tokensUsed', 'contextUsage', 'lastActivity', 'model', 'provider', 'name', 'routingMode', 'routingReason', 'sessionId', 'skills', 'integrations', 'workingDir', 'effort', 'costUsd', 'durationMs', 'turns', 'inputTokens', 'outputTokens', 'teamId', 'permission', 'scope'];
|
|
54
|
+
const SAFE_FIELDS = ['status', 'pid', 'tokensUsed', 'contextUsage', 'lastActivity', 'model', 'provider', 'name', 'routingMode', 'routingReason', 'sessionId', 'skills', 'integrations', 'workingDir', 'effort', 'costUsd', 'durationMs', 'turns', 'inputTokens', 'outputTokens', 'teamId', 'permission', 'scope', 'integrationApproval'];
|
|
55
55
|
for (const key of Object.keys(updates)) {
|
|
56
56
|
if (SAFE_FIELDS.includes(key)) {
|
|
57
57
|
agent[key] = updates[key];
|