groove-dev 0.27.29 → 0.27.32

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 (30) 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/api.js +4 -1
  5. package/node_modules/@groove-dev/daemon/src/providers/local.js +4 -2
  6. package/node_modules/@groove-dev/daemon/src/providers/ollama.js +35 -3
  7. package/node_modules/@groove-dev/gui/dist/assets/{index-CjjmUhoW.css → index-BwNjgBny.css} +1 -1
  8. package/node_modules/@groove-dev/gui/dist/assets/{index-CNsQ3n1t.js → index-PxWmJjcJ.js} +9 -9
  9. package/node_modules/@groove-dev/gui/dist/index.html +2 -2
  10. package/node_modules/@groove-dev/gui/package.json +1 -1
  11. package/node_modules/@groove-dev/gui/src/app.css +10 -0
  12. package/node_modules/@groove-dev/gui/src/components/agents/spawn-wizard.jsx +4 -4
  13. package/node_modules/@groove-dev/gui/src/components/editor/terminal.jsx +21 -13
  14. package/node_modules/@groove-dev/gui/src/components/layout/terminal-panel.jsx +1 -1
  15. package/node_modules/@groove-dev/gui/src/views/settings.jsx +2 -2
  16. package/package.json +1 -1
  17. package/packages/cli/package.json +1 -1
  18. package/packages/daemon/package.json +1 -1
  19. package/packages/daemon/src/api.js +4 -1
  20. package/packages/daemon/src/providers/local.js +4 -2
  21. package/packages/daemon/src/providers/ollama.js +35 -3
  22. package/packages/gui/dist/assets/{index-CjjmUhoW.css → index-BwNjgBny.css} +1 -1
  23. package/packages/gui/dist/assets/{index-CNsQ3n1t.js → index-PxWmJjcJ.js} +9 -9
  24. package/packages/gui/dist/index.html +2 -2
  25. package/packages/gui/package.json +1 -1
  26. package/packages/gui/src/app.css +10 -0
  27. package/packages/gui/src/components/agents/spawn-wizard.jsx +4 -4
  28. package/packages/gui/src/components/editor/terminal.jsx +21 -13
  29. package/packages/gui/src/components/layout/terminal-panel.jsx +1 -1
  30. package/packages/gui/src/views/settings.jsx +2 -2
@@ -6,12 +6,12 @@
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <link rel="icon" type="image/png" href="/favicon.png" />
8
8
  <title>Groove GUI</title>
9
- <script type="module" crossorigin src="/assets/index-CNsQ3n1t.js"></script>
9
+ <script type="module" crossorigin src="/assets/index-PxWmJjcJ.js"></script>
10
10
  <link rel="modulepreload" crossorigin href="/assets/vendor-C0HXlhrU.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/reactflow-BQPfi37R.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/codemirror-BBL3i_JW.js">
13
13
  <link rel="modulepreload" crossorigin href="/assets/xterm--7_ns2zW.js">
14
- <link rel="stylesheet" crossorigin href="/assets/index-CjjmUhoW.css">
14
+ <link rel="stylesheet" crossorigin href="/assets/index-BwNjgBny.css">
15
15
  </head>
16
16
  <body>
17
17
  <div id="root"></div>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groove-dev/gui",
3
- "version": "0.27.29",
3
+ "version": "0.27.32",
4
4
  "description": "GROOVE GUI — visual agent control plane",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",
@@ -80,6 +80,16 @@ html {
80
80
  ::-webkit-scrollbar-thumb:hover { background: var(--color-surface-6); }
81
81
  ::selection { background: rgba(51, 175, 188, 0.25); }
82
82
 
83
+ /* ── Terminal (xterm) ────────────────────────────────────── */
84
+
85
+ .xterm-viewport::-webkit-scrollbar { width: 6px; }
86
+ .xterm-viewport::-webkit-scrollbar-track { background: transparent; }
87
+ .xterm-viewport::-webkit-scrollbar-thumb { background: var(--color-surface-5); border-radius: 3px; }
88
+ .xterm-viewport::-webkit-scrollbar-thumb:hover { background: var(--color-surface-6); }
89
+ .xterm-viewport { scrollbar-width: thin; scrollbar-color: var(--color-surface-5) transparent; }
90
+ .xterm { padding: 0; }
91
+ .xterm-screen { width: 100% !important; }
92
+
83
93
  /* ── Animations ───────────────────────────────────────────── */
84
94
 
85
95
  @keyframes pulse {
@@ -90,14 +90,14 @@ export function SpawnWizard() {
90
90
  const selectedRole = role || customRole;
91
91
  const selectedProvider = providers.find((p) => p.id === provider);
92
92
  const availableModels = selectedProvider?.models || [];
93
- const installedProviders = providers.filter((p) => p.installed);
93
+ const installedProviders = providers.filter((p) => p.authType === 'api-key' ? (p.installed && p.hasKey) : p.installed);
94
94
 
95
95
  useEffect(() => {
96
96
  if (open) {
97
97
  fetchProviders().then((data) => {
98
98
  const list = Array.isArray(data) ? data : data.providers || [];
99
99
  setProviders(list);
100
- const installed = list.filter((p) => p.installed);
100
+ const installed = list.filter((p) => p.authType === 'api-key' ? (p.installed && p.hasKey) : p.installed);
101
101
  if (installed.length > 0 && !provider) {
102
102
  const priority = ['claude-code', 'gemini', 'codex', 'ollama'];
103
103
  const best = priority.find((pid) => installed.some((p) => p.id === pid)) || installed[0].id;
@@ -408,8 +408,8 @@ export function SpawnWizard() {
408
408
  >
409
409
  <option value="">Auto</option>
410
410
  {providers.map((p) => (
411
- <option key={p.id} value={p.id} disabled={!p.installed}>
412
- {p.name}{!p.installed ? ' (not installed)' : ''}
411
+ <option key={p.id} value={p.id} disabled={p.authType === 'api-key' ? !(p.installed && p.hasKey) : !p.installed}>
412
+ {p.name}{!p.installed ? ' (Not installed)' : (p.authType === 'api-key' && !p.hasKey) ? ' (No API key)' : ''}
413
413
  </option>
414
414
  ))}
415
415
  </select>
@@ -8,14 +8,15 @@ import { TerminalPanel } from '../layout/terminal-panel';
8
8
 
9
9
  const THEME = {
10
10
  background: '#1a1e25',
11
- foreground: '#bcc2cd',
11
+ foreground: '#c8ccd4',
12
12
  cursor: '#33afbc',
13
13
  cursorAccent: '#1a1e25',
14
- selectionBackground: 'rgba(51, 175, 188, 0.25)',
14
+ selectionBackground: 'rgba(51, 175, 188, 0.3)',
15
+ selectionForeground: '#ffffff',
15
16
  black: '#1a1e25', red: '#e06c75', green: '#4ae168', yellow: '#e5c07b',
16
- blue: '#61afef', magenta: '#c678dd', cyan: '#33afbc', white: '#bcc2cd',
17
- brightBlack: '#505862', brightRed: '#e06c75', brightGreen: '#4ae168', brightYellow: '#e5c07b',
18
- brightBlue: '#61afef', brightMagenta: '#c678dd', brightCyan: '#33afbc', brightWhite: '#e6e6e6',
17
+ blue: '#61afef', magenta: '#c678dd', cyan: '#33afbc', white: '#abb2bf',
18
+ brightBlack: '#5c6370', brightRed: '#f07178', brightGreen: '#4ae168', brightYellow: '#e5c07b',
19
+ brightBlue: '#61afef', brightMagenta: '#c678dd', brightCyan: '#56b6c2', brightWhite: '#ffffff',
19
20
  };
20
21
 
21
22
  let tabCounter = 0;
@@ -35,12 +36,19 @@ function TerminalInstance({ tabId, visible }) {
35
36
  const term = new XTerm({
36
37
  theme: THEME,
37
38
  fontFamily: "'JetBrains Mono Variable', 'SF Mono', monospace",
38
- fontSize: 13,
39
- lineHeight: 1.4,
39
+ fontSize: 12,
40
+ lineHeight: 1.1,
41
+ letterSpacing: 0,
40
42
  cursorBlink: true,
41
43
  cursorStyle: 'bar',
42
- scrollback: 5000,
44
+ cursorWidth: 1,
45
+ scrollback: 10000,
43
46
  allowProposedApi: true,
47
+ minimumContrastRatio: 1,
48
+ drawBoldTextInBrightColors: true,
49
+ fontWeight: '400',
50
+ fontWeightBold: '600',
51
+ overviewRulerWidth: 0,
44
52
  });
45
53
 
46
54
  const fitAddon = new FitAddon();
@@ -50,10 +58,6 @@ function TerminalInstance({ tabId, visible }) {
50
58
  termRef.current = term;
51
59
  fitRef.current = fitAddon;
52
60
 
53
- requestAnimationFrame(() => {
54
- try { fitAddon.fit(); } catch {}
55
- });
56
-
57
61
  let spawnAttempts = 0;
58
62
  function trySpawn() {
59
63
  spawnAttempts++;
@@ -97,7 +101,11 @@ function TerminalInstance({ tabId, visible }) {
97
101
  });
98
102
  }
99
103
 
100
- trySpawn();
104
+ // Fit first, then spawn — ensures PTY gets correct column count
105
+ requestAnimationFrame(() => {
106
+ try { fitAddon.fit(); } catch {}
107
+ trySpawn();
108
+ });
101
109
 
102
110
  const observer = new ResizeObserver(() => {
103
111
  requestAnimationFrame(() => { try { fitAddon.fit(); } catch {} });
@@ -122,7 +122,7 @@ export function TerminalPanel({
122
122
  </div>
123
123
 
124
124
  {/* Terminal content */}
125
- <div className="flex-1 min-h-0 p-2">
125
+ <div className="flex-1 min-h-0 pl-2 pt-1">
126
126
  {children}
127
127
  </div>
128
128
  </div>
@@ -999,7 +999,7 @@ export default function SettingsView() {
999
999
  const connectedCount = providers.filter((p) => {
1000
1000
  if (p.authType === 'local') return p.installed;
1001
1001
  if (p.authType === 'subscription') return p.installed;
1002
- return p.hasKey;
1002
+ return p.installed && p.hasKey;
1003
1003
  }).length;
1004
1004
 
1005
1005
  // Rotation threshold display: 0 = auto, otherwise show as percentage
@@ -1074,7 +1074,7 @@ export default function SettingsView() {
1074
1074
  onChange={(e) => updateConfig('defaultProvider', e.target.value)}
1075
1075
  className="w-full h-8 px-2.5 text-xs bg-surface-0 border border-border-subtle rounded-md text-text-0 font-mono focus:outline-none focus:ring-1 focus:ring-accent cursor-pointer"
1076
1076
  >
1077
- {providers.filter((p) => p.installed || p.hasKey).map((p) => (
1077
+ {providers.filter((p) => p.installed && (p.authType === 'local' || p.authType === 'subscription' || p.hasKey)).map((p) => (
1078
1078
  <option key={p.id} value={p.id}>{p.name}</option>
1079
1079
  ))}
1080
1080
  </select>