groove-dev 0.27.182 → 0.27.183

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 (48) hide show
  1. package/CLAUDE.md +0 -7
  2. package/node_modules/@groove-dev/cli/package.json +1 -1
  3. package/node_modules/@groove-dev/daemon/package.json +1 -1
  4. package/node_modules/@groove-dev/daemon/src/deliver.js +130 -0
  5. package/node_modules/@groove-dev/daemon/src/index.js +7 -3
  6. package/node_modules/@groove-dev/daemon/src/innerchat.js +213 -62
  7. package/node_modules/@groove-dev/daemon/src/process.js +1 -1
  8. package/node_modules/@groove-dev/daemon/src/registry.js +5 -1
  9. package/node_modules/@groove-dev/daemon/src/rename.js +72 -0
  10. package/node_modules/@groove-dev/daemon/src/routes/agents.js +22 -100
  11. package/node_modules/@groove-dev/daemon/src/routes/innerchat.js +12 -9
  12. package/node_modules/@groove-dev/daemon/src/teams.js +7 -1
  13. package/node_modules/@groove-dev/daemon/test/innerchat.test.js +197 -111
  14. package/node_modules/@groove-dev/daemon/test/rename.test.js +108 -0
  15. package/node_modules/@groove-dev/gui/dist/assets/{index-DTFtRtkx.css → index-CiOy7wVS.css} +1 -1
  16. package/node_modules/@groove-dev/gui/dist/assets/{index-CTer01Vg.js → index-DPjGBQ5X.js} +225 -225
  17. package/node_modules/@groove-dev/gui/dist/index.html +2 -2
  18. package/node_modules/@groove-dev/gui/package.json +1 -1
  19. package/node_modules/@groove-dev/gui/src/components/agents/agent-panel.jsx +3 -68
  20. package/node_modules/@groove-dev/gui/src/components/agents/innerchat-relay.jsx +145 -0
  21. package/node_modules/@groove-dev/gui/src/components/chat/chat-messages.jsx +3 -1
  22. package/node_modules/@groove-dev/gui/src/components/fleet/fleet-pane.jsx +15 -1
  23. package/node_modules/@groove-dev/gui/src/components/fleet/fleet-sidebar.jsx +33 -1
  24. package/node_modules/@groove-dev/gui/src/stores/groove.js +29 -44
  25. package/node_modules/@groove-dev/gui/src/stores/slices/agents-slice.js +27 -4
  26. package/package.json +1 -1
  27. package/packages/cli/package.json +1 -1
  28. package/packages/daemon/package.json +1 -1
  29. package/packages/daemon/src/deliver.js +130 -0
  30. package/packages/daemon/src/index.js +7 -3
  31. package/packages/daemon/src/innerchat.js +213 -62
  32. package/packages/daemon/src/process.js +1 -1
  33. package/packages/daemon/src/registry.js +5 -1
  34. package/packages/daemon/src/rename.js +72 -0
  35. package/packages/daemon/src/routes/agents.js +22 -100
  36. package/packages/daemon/src/routes/innerchat.js +12 -9
  37. package/packages/daemon/src/teams.js +7 -1
  38. package/packages/gui/dist/assets/{index-DTFtRtkx.css → index-CiOy7wVS.css} +1 -1
  39. package/packages/gui/dist/assets/{index-CTer01Vg.js → index-DPjGBQ5X.js} +225 -225
  40. package/packages/gui/dist/index.html +2 -2
  41. package/packages/gui/package.json +1 -1
  42. package/packages/gui/src/components/agents/agent-panel.jsx +3 -68
  43. package/packages/gui/src/components/agents/innerchat-relay.jsx +145 -0
  44. package/packages/gui/src/components/chat/chat-messages.jsx +3 -1
  45. package/packages/gui/src/components/fleet/fleet-pane.jsx +15 -1
  46. package/packages/gui/src/components/fleet/fleet-sidebar.jsx +33 -1
  47. package/packages/gui/src/stores/groove.js +29 -44
  48. package/packages/gui/src/stores/slices/agents-slice.js +27 -4
@@ -0,0 +1,108 @@
1
+ // GROOVE — Agent Rename Migration Tests
2
+ // FSL-1.1-Apache-2.0 — see LICENSE
3
+
4
+ import { describe, it, beforeEach, afterEach } from 'node:test';
5
+ import assert from 'node:assert/strict';
6
+ import { mkdtempSync, mkdirSync, writeFileSync, existsSync, readFileSync, rmSync } from 'fs';
7
+ import { resolve } from 'path';
8
+ import { tmpdir } from 'os';
9
+ import { renameAgent } from '../src/rename.js';
10
+ import { Registry } from '../src/registry.js';
11
+
12
+ describe('renameAgent', () => {
13
+ let root, daemon, agent;
14
+
15
+ beforeEach(() => {
16
+ root = mkdtempSync(resolve(tmpdir(), 'groove-rename-'));
17
+ const grooveDir = resolve(root, '.groove');
18
+ mkdirSync(resolve(grooveDir, 'logs'), { recursive: true });
19
+ mkdirSync(resolve(grooveDir, 'personalities'), { recursive: true });
20
+ mkdirSync(resolve(root, 'agent-files'), { recursive: true });
21
+
22
+ const registry = new Registry({ save() {}, load() { return null; } });
23
+ daemon = {
24
+ registry,
25
+ grooveDir,
26
+ projectDir: root,
27
+ audit: { log() {} },
28
+ };
29
+ agent = registry.add({ role: 'fullstack', name: 'fullstack-1' });
30
+
31
+ writeFileSync(resolve(grooveDir, 'logs', 'fullstack-1.log'), 'session history');
32
+ writeFileSync(resolve(grooveDir, 'personalities', 'fullstack-1.md'), 'be terse');
33
+ mkdirSync(resolve(root, 'agent-files', 'fullstack-1'));
34
+ writeFileSync(resolve(root, 'agent-files', 'fullstack-1', 'notes.md'), 'notes');
35
+ });
36
+
37
+ afterEach(() => rmSync(root, { recursive: true, force: true }));
38
+
39
+ const p = {
40
+ log: (n) => resolve(root, '.groove', 'logs', `${n}.log`),
41
+ personality: (n) => resolve(root, '.groove', 'personalities', `${n}.md`),
42
+ files: (n) => resolve(root, 'agent-files', n),
43
+ };
44
+
45
+ it('migrates the log, personality and agent-files', () => {
46
+ renameAgent(daemon, agent.id, 'senior-dev');
47
+
48
+ assert.equal(daemon.registry.get(agent.id).name, 'senior-dev');
49
+
50
+ assert.ok(!existsSync(p.log('fullstack-1')), 'old log removed');
51
+ assert.equal(readFileSync(p.log('senior-dev'), 'utf8'), 'session history');
52
+
53
+ assert.ok(!existsSync(p.personality('fullstack-1')));
54
+ assert.equal(readFileSync(p.personality('senior-dev'), 'utf8'), 'be terse');
55
+
56
+ assert.ok(!existsSync(p.files('fullstack-1')));
57
+ assert.equal(readFileSync(resolve(p.files('senior-dev'), 'notes.md'), 'utf8'), 'notes');
58
+ });
59
+
60
+ it('rejects a name already taken by another agent', () => {
61
+ daemon.registry.add({ role: 'fullstack', name: 'fullstack-2' });
62
+ assert.throws(() => renameAgent(daemon, agent.id, 'fullstack-2'), /already exists/);
63
+
64
+ // Nothing moved — the original log must survive a rejected rename.
65
+ assert.equal(daemon.registry.get(agent.id).name, 'fullstack-1');
66
+ assert.equal(readFileSync(p.log('fullstack-1'), 'utf8'), 'session history');
67
+ });
68
+
69
+ it('rejects an empty name and no-ops an unchanged one', () => {
70
+ assert.throws(() => renameAgent(daemon, agent.id, ' '), /name is required/);
71
+ const same = renameAgent(daemon, agent.id, 'fullstack-1');
72
+ assert.equal(same.name, 'fullstack-1');
73
+ assert.equal(readFileSync(p.log('fullstack-1'), 'utf8'), 'session history');
74
+ });
75
+
76
+ it('throws for an unknown agent', () => {
77
+ assert.throws(() => renameAgent(daemon, 'nope', 'whatever'), /Agent not found/);
78
+ });
79
+
80
+ it('tolerates missing artifacts', () => {
81
+ rmSync(p.personality('fullstack-1'));
82
+ rmSync(p.files('fullstack-1'), { recursive: true });
83
+
84
+ renameAgent(daemon, agent.id, 'solo');
85
+ assert.equal(readFileSync(p.log('solo'), 'utf8'), 'session history');
86
+ assert.ok(!existsSync(p.personality('solo')));
87
+ });
88
+
89
+ it('rejects names that would escape their directory', () => {
90
+ // These become path segments (agent-files/<name>), so a separator or a
91
+ // dot-segment would write outside the intended directory.
92
+ for (const bad of ['front end/dev', '../escape', '..', 'a/../../b', 'has space']) {
93
+ assert.throws(() => renameAgent(daemon, agent.id, bad), /name may only contain|name must be/);
94
+ }
95
+ assert.equal(daemon.registry.get(agent.id).name, 'fullstack-1');
96
+ assert.ok(existsSync(p.log('fullstack-1')));
97
+ });
98
+
99
+ it('rejects an over-long name', () => {
100
+ assert.throws(() => renameAgent(daemon, agent.id, 'x'.repeat(65)), /64 characters/);
101
+ });
102
+
103
+ it('blocks a bare registry.update from renaming without migration', () => {
104
+ daemon.registry.update(agent.id, { name: 'sneaky' });
105
+ assert.equal(daemon.registry.get(agent.id).name, 'fullstack-1');
106
+ assert.ok(existsSync(p.log('fullstack-1')), 'log was never orphaned');
107
+ });
108
+ });