groove-dev 0.17.8 → 0.18.2
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/node_modules/@groove-dev/cli/package.json +4 -3
- package/node_modules/@groove-dev/daemon/google-oauth.json +5 -0
- package/node_modules/@groove-dev/daemon/integrations-registry.json +0 -40
- package/node_modules/@groove-dev/daemon/package.json +4 -3
- package/node_modules/@groove-dev/daemon/src/api.js +212 -21
- package/node_modules/@groove-dev/daemon/src/index.js +68 -1
- package/node_modules/@groove-dev/daemon/src/integrations.js +59 -20
- package/node_modules/@groove-dev/daemon/src/process.js +83 -11
- package/node_modules/@groove-dev/daemon/src/providers/claude-code.js +4 -0
- package/node_modules/@groove-dev/daemon/src/registry.js +1 -1
- package/node_modules/@groove-dev/gui/.groove/audit.log +1 -0
- package/node_modules/@groove-dev/gui/.groove/codebase-index.json +64 -0
- package/node_modules/@groove-dev/gui/.groove/config.json +10 -0
- package/node_modules/@groove-dev/gui/.groove/coordination.md +5 -0
- package/node_modules/@groove-dev/gui/.groove/credentials.json +6 -0
- package/node_modules/@groove-dev/gui/.groove/daemon.port +1 -0
- package/node_modules/@groove-dev/gui/.groove/federation/identity.key +3 -0
- package/node_modules/@groove-dev/gui/.groove/federation/identity.pub +3 -0
- package/node_modules/@groove-dev/gui/.groove/integrations/package.json +6 -0
- package/node_modules/@groove-dev/gui/.groove/state.json +3 -0
- package/node_modules/@groove-dev/gui/dist/assets/index-x5suAiK7.js +182 -0
- package/node_modules/@groove-dev/gui/dist/index.html +1 -1
- package/node_modules/@groove-dev/gui/package.json +5 -4
- package/node_modules/@groove-dev/gui/src/App.jsx +149 -76
- package/node_modules/@groove-dev/gui/src/components/AgentActions.jsx +130 -1
- package/node_modules/@groove-dev/gui/src/components/AgentChat.jsx +47 -7
- package/node_modules/@groove-dev/gui/src/components/AgentNode.jsx +13 -83
- package/node_modules/@groove-dev/gui/src/components/SpawnPanel.jsx +918 -580
- package/node_modules/@groove-dev/gui/src/stores/groove.js +31 -2
- package/node_modules/@groove-dev/gui/src/views/AgentTree.jsx +133 -67
- package/node_modules/@groove-dev/gui/src/views/FileEditor.jsx +85 -1
- package/node_modules/@groove-dev/gui/src/views/IntegrationsStore.jsx +121 -44
- package/package.json +1 -2
- package/packages/cli/package.json +4 -3
- package/packages/daemon/integrations-registry.json +0 -40
- package/packages/daemon/package.json +4 -3
- package/packages/daemon/src/api.js +212 -21
- package/packages/daemon/src/index.js +68 -1
- package/packages/daemon/src/integrations.js +59 -20
- package/packages/daemon/src/process.js +83 -11
- package/packages/daemon/src/providers/claude-code.js +4 -0
- package/packages/daemon/src/registry.js +1 -1
- package/packages/gui/dist/assets/index-x5suAiK7.js +182 -0
- package/packages/gui/dist/index.html +1 -1
- package/packages/gui/node_modules/.vite/deps/@codemirror_autocomplete.js +68 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_autocomplete.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_commands.js +1420 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_commands.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_lang-css.js +17 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_lang-css.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_lang-html.js +22 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_lang-html.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_lang-javascript.js +34 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_lang-javascript.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_lang-json.js +101 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_lang-json.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_lang-markdown.js +2534 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_lang-markdown.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_lang-python.js +789 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_lang-python.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_language.js +115 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_language.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_search.js +1136 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_search.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_state.js +63 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_state.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_theme-one-dark.js +179 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_theme-one-dark.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_view.js +104 -0
- package/packages/gui/node_modules/.vite/deps/@codemirror_view.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/@xterm_addon-fit.js +46 -0
- package/packages/gui/node_modules/.vite/deps/@xterm_addon-fit.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/@xterm_addon-web-links.js +121 -0
- package/packages/gui/node_modules/.vite/deps/@xterm_addon-web-links.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/@xterm_xterm.js +9237 -0
- package/packages/gui/node_modules/.vite/deps/@xterm_xterm.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/@xyflow_react.js +9934 -0
- package/packages/gui/node_modules/.vite/deps/@xyflow_react.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/_metadata.json +184 -0
- package/packages/gui/node_modules/.vite/deps/chunk-3EE34IFC.js +5169 -0
- package/packages/gui/node_modules/.vite/deps/chunk-3EE34IFC.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/chunk-3IB5EUP7.js +2000 -0
- package/packages/gui/node_modules/.vite/deps/chunk-3IB5EUP7.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/chunk-3LBP22MX.js +1115 -0
- package/packages/gui/node_modules/.vite/deps/chunk-3LBP22MX.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/chunk-3Q7HT7ZF.js +701 -0
- package/packages/gui/node_modules/.vite/deps/chunk-3Q7HT7ZF.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/chunk-44CLUOQE.js +1776 -0
- package/packages/gui/node_modules/.vite/deps/chunk-44CLUOQE.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/chunk-5RZAEUNX.js +280 -0
- package/packages/gui/node_modules/.vite/deps/chunk-5RZAEUNX.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/chunk-5WRI5ZAA.js +30 -0
- package/packages/gui/node_modules/.vite/deps/chunk-5WRI5ZAA.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/chunk-7FYDPZIO.js +1004 -0
- package/packages/gui/node_modules/.vite/deps/chunk-7FYDPZIO.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/chunk-BX6POZPY.js +292 -0
- package/packages/gui/node_modules/.vite/deps/chunk-BX6POZPY.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/chunk-HVFOBSCQ.js +1062 -0
- package/packages/gui/node_modules/.vite/deps/chunk-HVFOBSCQ.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/chunk-RE2FU7ZU.js +10985 -0
- package/packages/gui/node_modules/.vite/deps/chunk-RE2FU7ZU.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/chunk-YYJMNVCJ.js +3459 -0
- package/packages/gui/node_modules/.vite/deps/chunk-YYJMNVCJ.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/package.json +3 -0
- package/packages/gui/node_modules/.vite/deps/react-dom.js +6 -0
- package/packages/gui/node_modules/.vite/deps/react-dom.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/react-dom_client.js +20217 -0
- package/packages/gui/node_modules/.vite/deps/react-dom_client.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/react.js +5 -0
- package/packages/gui/node_modules/.vite/deps/react.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/react_jsx-dev-runtime.js +278 -0
- package/packages/gui/node_modules/.vite/deps/react_jsx-dev-runtime.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/react_jsx-runtime.js +6 -0
- package/packages/gui/node_modules/.vite/deps/react_jsx-runtime.js.map +7 -0
- package/packages/gui/node_modules/.vite/deps/zustand.js +56 -0
- package/packages/gui/node_modules/.vite/deps/zustand.js.map +7 -0
- package/packages/gui/package.json +5 -4
- package/packages/gui/src/App.jsx +149 -76
- package/packages/gui/src/components/AgentActions.jsx +130 -1
- package/packages/gui/src/components/AgentChat.jsx +47 -7
- package/packages/gui/src/components/AgentNode.jsx +13 -83
- package/packages/gui/src/components/SpawnPanel.jsx +918 -580
- package/packages/gui/src/stores/groove.js +31 -2
- package/packages/gui/src/views/AgentTree.jsx +133 -67
- package/packages/gui/src/views/FileEditor.jsx +85 -1
- package/packages/gui/src/views/IntegrationsStore.jsx +121 -44
- package/docs/FILE-EDITOR-PLAN.md +0 -253
- package/docs/GUI_DESIGN_SPEC.md +0 -402
- package/docs/SKILLS-API-SPEC.md +0 -277
- package/node_modules/@groove-dev/gui/dist/assets/index-D5dtDQf0.js +0 -156
- package/packages/gui/dist/assets/index-D5dtDQf0.js +0 -156
package/docs/GUI_DESIGN_SPEC.md
DELETED
|
@@ -1,402 +0,0 @@
|
|
|
1
|
-
# Groove AI — GUI Design Specification
|
|
2
|
-
### Terminal-Native Visual Control Plane
|
|
3
|
-
|
|
4
|
-
> The GUI should feel like a terminal that happens to have graphics in it — not a website pretending to be a terminal.
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Philosophy
|
|
9
|
-
|
|
10
|
-
This is a TUI-meets-browser hybrid. It runs at `localhost:3141` and is designed to sit inside a terminal multiplexer pane (cmux) alongside real terminal sessions. It should look like it belongs there. No rounded corners on containers, no card shadows, no hover animations, no gradient backgrounds. Think: htop with a React Flow node graph in the center.
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
## Color Palette
|
|
15
|
-
|
|
16
|
-
Based on One Dark Pro. Every color has a purpose.
|
|
17
|
-
|
|
18
|
-
### Backgrounds
|
|
19
|
-
| Token | Hex | Usage |
|
|
20
|
-
|---|---|---|
|
|
21
|
-
| `--bg-base` | `#24282f` | Main content area / node graph background |
|
|
22
|
-
| `--bg-chrome` | `#282c34` | Sidebar, header bar, panels |
|
|
23
|
-
| `--bg-surface` | `#2c313a` | Buttons, input fields, card surfaces |
|
|
24
|
-
| `--bg-hover` | `#333842` | Button/row hover state |
|
|
25
|
-
| `--bg-active` | `#3a3f4b` | Active/selected button or tab |
|
|
26
|
-
|
|
27
|
-
### Text
|
|
28
|
-
| Token | Hex | Usage |
|
|
29
|
-
|---|---|---|
|
|
30
|
-
| `--text-primary` | `#abb2bf` | Default body text, labels |
|
|
31
|
-
| `--text-bright` | `#e6e6e6` | Headings, active items, emphasis |
|
|
32
|
-
| `--text-dim` | `#5c6370` | Secondary info, timestamps, hints |
|
|
33
|
-
| `--text-muted` | `#3e4451` | Disabled text, decorative borders |
|
|
34
|
-
|
|
35
|
-
### Accent / Status
|
|
36
|
-
| Token | Hex | Usage |
|
|
37
|
-
|---|---|---|
|
|
38
|
-
| `--accent` | `#33afbc` | Brand accent — active nav item, selected node border, primary action |
|
|
39
|
-
| `--green` | `#98c379` | Agent active, success states, healthy status |
|
|
40
|
-
| `--amber` | `#e5c07b` | Agent idle, warning, pending approval |
|
|
41
|
-
| `--red` | `#e06c75` | Agent blocked/error, kill actions, conflicts |
|
|
42
|
-
| `--purple` | `#c678dd` | Journalist activity, context rotation events |
|
|
43
|
-
| `--blue` | `#61afef` | Info badges, links, secondary accent |
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## Typography
|
|
48
|
-
|
|
49
|
-
One font. Everywhere. No exceptions.
|
|
50
|
-
|
|
51
|
-
```
|
|
52
|
-
font-family: 'JetBrains Mono', 'SF Mono', 'Fira Code', 'Cascadia Code', Consolas, monospace;
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
| Element | Size | Weight | Color |
|
|
56
|
-
|---|---|---|---|
|
|
57
|
-
| Header bar title | 13px | 600 | `--text-bright` |
|
|
58
|
-
| Nav buttons | 12px | 500 | `--text-primary` (inactive), `--text-bright` (active) |
|
|
59
|
-
| Node labels | 12px | 600 | `--text-bright` |
|
|
60
|
-
| Node metadata | 11px | 400 | `--text-dim` |
|
|
61
|
-
| Panel headings | 11px | 600 | `--text-dim`, uppercase, letter-spacing 1.5px |
|
|
62
|
-
| Panel body text | 12px | 400 | `--text-primary` |
|
|
63
|
-
| Timestamps | 10px | 400 | `--text-dim` |
|
|
64
|
-
| Status badges | 10px | 600 | Status color, uppercase |
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
## Layout
|
|
69
|
-
|
|
70
|
-
```
|
|
71
|
-
┌──────────────────────────────────────────────────────┐
|
|
72
|
-
│ HEADER BAR (--bg-chrome, 40px height) │
|
|
73
|
-
│ [logo] [Agents] [Tokens] [Teams] [Permissions] │
|
|
74
|
-
├────────────────────────────────────┬─────────────────┤
|
|
75
|
-
│ │ │
|
|
76
|
-
│ NODE GRAPH │ DETAIL PANEL │
|
|
77
|
-
│ (--bg-base) │ (--bg-chrome) │
|
|
78
|
-
│ │ │
|
|
79
|
-
│ React Flow canvas with │ Context for │
|
|
80
|
-
│ agent nodes and edges │ selected node │
|
|
81
|
-
│ │ │
|
|
82
|
-
│ │ │
|
|
83
|
-
└────────────────────────────────────┴─────────────────┘
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### Header Bar
|
|
87
|
-
- Height: 40px
|
|
88
|
-
- Background: `--bg-chrome`
|
|
89
|
-
- Bottom border: 1px `--text-muted`
|
|
90
|
-
- Logo: Groove infinity icon (16px), left side
|
|
91
|
-
- Nav buttons: right-aligned, evenly spaced
|
|
92
|
-
|
|
93
|
-
### Node Graph Area
|
|
94
|
-
- Background: `--bg-base`
|
|
95
|
-
- Takes remaining viewport width/height
|
|
96
|
-
- Subtle dot grid pattern: `--text-muted` dots, 20px spacing, 1px size
|
|
97
|
-
- No border, no padding — edge to edge
|
|
98
|
-
|
|
99
|
-
### Detail Panel (right sidebar)
|
|
100
|
-
- Width: 320px, collapsible
|
|
101
|
-
- Background: `--bg-chrome`
|
|
102
|
-
- Left border: 1px `--text-muted`
|
|
103
|
-
- Shows detail for whatever is selected in the graph
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
## Components
|
|
108
|
-
|
|
109
|
-
### Nav Buttons (Header)
|
|
110
|
-
|
|
111
|
-
The four main views: **Agents**, **Tokens**, **Teams**, **Permissions**
|
|
112
|
-
|
|
113
|
-
```
|
|
114
|
-
Inactive:
|
|
115
|
-
background: transparent
|
|
116
|
-
color: --text-primary
|
|
117
|
-
padding: 6px 14px
|
|
118
|
-
border: none
|
|
119
|
-
|
|
120
|
-
Hover:
|
|
121
|
-
background: --bg-hover
|
|
122
|
-
color: --text-bright
|
|
123
|
-
|
|
124
|
-
Active:
|
|
125
|
-
background: --bg-active
|
|
126
|
-
color: --text-bright
|
|
127
|
-
border-bottom: 2px --accent (or underline indicator)
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
No border-radius. These are terminal tabs, not web buttons.
|
|
131
|
-
|
|
132
|
-
### Agent Nodes (React Flow)
|
|
133
|
-
|
|
134
|
-
Each node represents one running agent.
|
|
135
|
-
|
|
136
|
-
```
|
|
137
|
-
┌─────────────────────────┐
|
|
138
|
-
│ ● backend-1 │ ← status dot + agent name
|
|
139
|
-
│ src/api/** │ ← file scope
|
|
140
|
-
│ claude-code · 45% │ ← provider + context usage
|
|
141
|
-
└─────────────────────────┘
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
| Property | Value |
|
|
145
|
-
|---|---|
|
|
146
|
-
| Background | `--bg-surface` |
|
|
147
|
-
| Border | 1px `--text-muted` |
|
|
148
|
-
| Border (selected) | 1px `--accent` |
|
|
149
|
-
| Border-radius | 2px (barely rounded — terminal feel) |
|
|
150
|
-
| Padding | 10px 12px |
|
|
151
|
-
| Width | 200px |
|
|
152
|
-
| Font | 12px for name, 11px for metadata |
|
|
153
|
-
|
|
154
|
-
**Status dot** (6px circle, left of agent name):
|
|
155
|
-
- `--green` = active
|
|
156
|
-
- `--amber` = idle / waiting
|
|
157
|
-
- `--red` = blocked / error
|
|
158
|
-
- `--purple` = rotating context
|
|
159
|
-
|
|
160
|
-
**Context usage bar** (optional, bottom of node):
|
|
161
|
-
- Height: 2px
|
|
162
|
-
- Background: `--text-muted`
|
|
163
|
-
- Fill: `--green` (0-60%), `--amber` (60-80%), `--red` (80-100%)
|
|
164
|
-
|
|
165
|
-
### Edges (connections between nodes)
|
|
166
|
-
|
|
167
|
-
- Stroke: `--text-muted`
|
|
168
|
-
- Stroke width: 1px
|
|
169
|
-
- Style: straight or step (not bezier — too soft)
|
|
170
|
-
- Animated dash when data is flowing (introduction events, journalist updates)
|
|
171
|
-
|
|
172
|
-
### QC Supervisor Node (special)
|
|
173
|
-
|
|
174
|
-
Same structure as agent node but:
|
|
175
|
-
- Border: 1px `--purple`
|
|
176
|
-
- Label prefix: `[QC]`
|
|
177
|
-
- Always positioned at root/top of the tree
|
|
178
|
-
|
|
179
|
-
### Status Badges
|
|
180
|
-
|
|
181
|
-
Small inline badges for agent states.
|
|
182
|
-
|
|
183
|
-
```
|
|
184
|
-
background: rgba(color, 0.12)
|
|
185
|
-
color: status color
|
|
186
|
-
padding: 2px 6px
|
|
187
|
-
font-size: 10px
|
|
188
|
-
font-weight: 600
|
|
189
|
-
text-transform: uppercase
|
|
190
|
-
letter-spacing: 0.5px
|
|
191
|
-
border-radius: 2px
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
Examples:
|
|
195
|
-
- `ACTIVE` — green bg tint, green text
|
|
196
|
-
- `IDLE` — amber bg tint, amber text
|
|
197
|
-
- `BLOCKED` — red bg tint, red text
|
|
198
|
-
- `ROTATING` — purple bg tint, purple text
|
|
199
|
-
|
|
200
|
-
### Token Usage View
|
|
201
|
-
|
|
202
|
-
Replaces the node graph when "Tokens" tab is active.
|
|
203
|
-
|
|
204
|
-
```
|
|
205
|
-
┌──────────────────────────────────┐
|
|
206
|
-
│ TOKEN USAGE this session│
|
|
207
|
-
│ │
|
|
208
|
-
│ Total 1,247,893 │
|
|
209
|
-
│ Saved (routing) 412,500 (33%) │
|
|
210
|
-
│ Saved (rotation) 289,100 (23%) │
|
|
211
|
-
│ │
|
|
212
|
-
│ AGENT BREAKDOWN │
|
|
213
|
-
│ ─────────────────────────────── │
|
|
214
|
-
│ backend-1 482,100 38.6% │
|
|
215
|
-
│ ████████████████░░░░░░ │
|
|
216
|
-
│ frontend-1 391,200 31.3% │
|
|
217
|
-
│ ██████████████░░░░░░░░ │
|
|
218
|
-
│ database-1 374,593 30.0% │
|
|
219
|
-
│ █████████████░░░░░░░░░ │
|
|
220
|
-
└──────────────────────────────────┘
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
Bar charts use block characters or thin divs:
|
|
224
|
-
- Fill: `--accent`
|
|
225
|
-
- Track: `--text-muted`
|
|
226
|
-
- Height: 3px
|
|
227
|
-
|
|
228
|
-
Numbers right-aligned, monospace tabular. This should look like a terminal stats output, not a web dashboard.
|
|
229
|
-
|
|
230
|
-
### Teams View
|
|
231
|
-
|
|
232
|
-
List of saved team configurations.
|
|
233
|
-
|
|
234
|
-
```
|
|
235
|
-
┌──────────────────────────────────┐
|
|
236
|
-
│ SAVED TEAMS │
|
|
237
|
-
│ │
|
|
238
|
-
│ > fullstack 4 agents │
|
|
239
|
-
│ backend, frontend, db, qc │
|
|
240
|
-
│ saved 2026-04-05 │
|
|
241
|
-
│ │
|
|
242
|
-
│ > api-only 2 agents │
|
|
243
|
-
│ backend, database │
|
|
244
|
-
│ saved 2026-04-04 │
|
|
245
|
-
└──────────────────────────────────┘
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
- `>` prefix for each team (terminal-style list marker)
|
|
249
|
-
- Selected team: `--text-bright` text, `--bg-hover` background
|
|
250
|
-
- Load button: inline, right side, `--accent` text
|
|
251
|
-
|
|
252
|
-
### Permissions / Approvals View
|
|
253
|
-
|
|
254
|
-
Pending agent actions requiring human approval.
|
|
255
|
-
|
|
256
|
-
```
|
|
257
|
-
┌──────────────────────────────────┐
|
|
258
|
-
│ PENDING APPROVALS 2 │
|
|
259
|
-
│ │
|
|
260
|
-
│ backend-1 wants to: │
|
|
261
|
-
│ Edit src/middleware/auth.js │
|
|
262
|
-
│ "Refactoring auth to use JWT" │
|
|
263
|
-
│ [APPROVE] [REJECT] 2m ago │
|
|
264
|
-
│ │
|
|
265
|
-
│ frontend-1 wants to: │
|
|
266
|
-
│ Create src/components/Modal.jsx │
|
|
267
|
-
│ "Adding confirmation dialog" │
|
|
268
|
-
│ [APPROVE] [REJECT] 45s ago │
|
|
269
|
-
└──────────────────────────────────┘
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
Action buttons:
|
|
273
|
-
```
|
|
274
|
-
[APPROVE]:
|
|
275
|
-
background: rgba(--green, 0.12)
|
|
276
|
-
color: --green
|
|
277
|
-
border: 1px rgba(--green, 0.2)
|
|
278
|
-
padding: 4px 10px
|
|
279
|
-
font-size: 11px
|
|
280
|
-
|
|
281
|
-
[REJECT]:
|
|
282
|
-
background: rgba(--red, 0.12)
|
|
283
|
-
color: --red
|
|
284
|
-
border: 1px rgba(--red, 0.2)
|
|
285
|
-
padding: 4px 10px
|
|
286
|
-
font-size: 11px
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
---
|
|
290
|
-
|
|
291
|
-
## Detail Panel (Right Sidebar)
|
|
292
|
-
|
|
293
|
-
Shows context for selected agent node.
|
|
294
|
-
|
|
295
|
-
```
|
|
296
|
-
┌─────────────────────┐
|
|
297
|
-
│ AGENT DETAIL │
|
|
298
|
-
│ │
|
|
299
|
-
│ backend-1 │
|
|
300
|
-
│ Status: ACTIVE │
|
|
301
|
-
│ Provider: claude │
|
|
302
|
-
│ Context: 45% │
|
|
303
|
-
│ ████████░░░░░░░░░░ │
|
|
304
|
-
│ Tokens: 482,100 │
|
|
305
|
-
│ Scope: │
|
|
306
|
-
│ src/api/** │
|
|
307
|
-
│ src/middleware/** │
|
|
308
|
-
│ Spawned: 14:20 │
|
|
309
|
-
│ Peers: frontend-1, │
|
|
310
|
-
│ database-1 │
|
|
311
|
-
│ │
|
|
312
|
-
│ RECENT ACTIVITY │
|
|
313
|
-
│ ───────────────── │
|
|
314
|
-
│ 14:32 editing │
|
|
315
|
-
│ auth.js │
|
|
316
|
-
│ 14:28 introduced to │
|
|
317
|
-
│ frontend-1 │
|
|
318
|
-
│ 14:20 spawned │
|
|
319
|
-
└─────────────────────┘
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
- Section headers: `--text-dim`, 11px, uppercase, 1.5px letter-spacing
|
|
323
|
-
- Dividers: single line of `─` chars or 1px `--text-muted` border
|
|
324
|
-
- Key labels: `--text-dim`
|
|
325
|
-
- Values: `--text-primary`
|
|
326
|
-
- Agent name: `--text-bright`, 14px, 600 weight
|
|
327
|
-
|
|
328
|
-
---
|
|
329
|
-
|
|
330
|
-
## Interaction States
|
|
331
|
-
|
|
332
|
-
| State | Treatment |
|
|
333
|
-
|---|---|
|
|
334
|
-
| Default | `--bg-surface` background, `--text-primary` text |
|
|
335
|
-
| Hover | `--bg-hover` background, `--text-bright` text |
|
|
336
|
-
| Active/Selected | `--bg-active` background, `--text-bright` text |
|
|
337
|
-
| Focused | 1px `--accent` outline (no glow, no shadow) |
|
|
338
|
-
| Disabled | `--text-muted` text, no hover change |
|
|
339
|
-
|
|
340
|
-
No transitions longer than 100ms. No easing curves. Instant or near-instant state changes — like a terminal.
|
|
341
|
-
|
|
342
|
-
---
|
|
343
|
-
|
|
344
|
-
## What NOT To Do
|
|
345
|
-
|
|
346
|
-
- No border-radius > 2px anywhere
|
|
347
|
-
- No box-shadow anywhere
|
|
348
|
-
- No gradients anywhere
|
|
349
|
-
- No opacity transitions on hover
|
|
350
|
-
- No font-size larger than 14px (exception: token counter numbers)
|
|
351
|
-
- No sans-serif fonts
|
|
352
|
-
- No rounded buttons
|
|
353
|
-
- No icons — use text labels and ASCII where possible (`●`, `>`, `─`, `█`, `░`)
|
|
354
|
-
- No loading spinners — use text like `loading...` or `syncing...`
|
|
355
|
-
- No toast notifications — use inline status text
|
|
356
|
-
- No modals — use the detail panel or inline expansion
|
|
357
|
-
|
|
358
|
-
---
|
|
359
|
-
|
|
360
|
-
## CSS Variables (copy-paste ready)
|
|
361
|
-
|
|
362
|
-
```css
|
|
363
|
-
:root {
|
|
364
|
-
/* Backgrounds */
|
|
365
|
-
--bg-base: #24282f;
|
|
366
|
-
--bg-chrome: #282c34;
|
|
367
|
-
--bg-surface: #2c313a;
|
|
368
|
-
--bg-hover: #333842;
|
|
369
|
-
--bg-active: #3a3f4b;
|
|
370
|
-
|
|
371
|
-
/* Text */
|
|
372
|
-
--text-primary: #abb2bf;
|
|
373
|
-
--text-bright: #e6e6e6;
|
|
374
|
-
--text-dim: #5c6370;
|
|
375
|
-
--text-muted: #3e4451;
|
|
376
|
-
|
|
377
|
-
/* Status */
|
|
378
|
-
--accent: #33afbc;
|
|
379
|
-
--green: #98c379;
|
|
380
|
-
--amber: #e5c07b;
|
|
381
|
-
--red: #e06c75;
|
|
382
|
-
--purple: #c678dd;
|
|
383
|
-
--blue: #61afef;
|
|
384
|
-
|
|
385
|
-
/* Typography */
|
|
386
|
-
--font: 'JetBrains Mono', 'SF Mono', 'Fira Code', 'Cascadia Code', Consolas, monospace;
|
|
387
|
-
}
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
---
|
|
391
|
-
|
|
392
|
-
## File Reference
|
|
393
|
-
|
|
394
|
-
- Logo (full): `/groove-logo.png` (800x254, cyan on transparent)
|
|
395
|
-
- Logo (icon): `/favicon.png` (500x500, infinity symbol)
|
|
396
|
-
- Brand accent: `#33afbc`
|
|
397
|
-
- Site: https://grooveai.dev
|
|
398
|
-
- Docs: https://docs.grooveai.dev
|
|
399
|
-
|
|
400
|
-
---
|
|
401
|
-
|
|
402
|
-
*This spec is the single source of truth for GUI visual design. If it's not in here, don't add it. If it contradicts a mockup, this document wins.*
|
package/docs/SKILLS-API-SPEC.md
DELETED
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
# Skills Marketplace API — Build Spec
|
|
2
|
-
|
|
3
|
-
> Instructions for building the server-side Skills API that powers the GROOVE Skills Store.
|
|
4
|
-
> This API is hosted on the docs/retail site (docs.groovedev.ai).
|
|
5
|
-
|
|
6
|
-
## Context
|
|
7
|
-
|
|
8
|
-
GROOVE is an agent orchestration tool. Its GUI has a Skills Store (app-store style) that currently reads from a static `registry.json` file. We need a real API so users can **submit, edit, and sell** their own skills. The GROOVE daemon will fetch from this API instead of the static file.
|
|
9
|
-
|
|
10
|
-
### What exists today (static files):
|
|
11
|
-
- `https://docs.groovedev.ai/skills/registry.json` — JSON array of all skill metadata
|
|
12
|
-
- `https://docs.groovedev.ai/skills/content/<id>.md` — individual SKILL.md files
|
|
13
|
-
|
|
14
|
-
### What we're building:
|
|
15
|
-
A REST API that replaces the static files and adds CRUD + author management.
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## Data Model
|
|
20
|
-
|
|
21
|
-
### Skill
|
|
22
|
-
|
|
23
|
-
```json
|
|
24
|
-
{
|
|
25
|
-
"id": "frontend-design",
|
|
26
|
-
"name": "Frontend Design",
|
|
27
|
-
"description": "Create distinctive, production-grade frontend interfaces...",
|
|
28
|
-
"author": "Anthropic",
|
|
29
|
-
"authorId": "user_abc123",
|
|
30
|
-
"authorProfile": {
|
|
31
|
-
"avatar": "https://...",
|
|
32
|
-
"website": "https://anthropic.com",
|
|
33
|
-
"github": "anthropics",
|
|
34
|
-
"twitter": "AnthropicAI",
|
|
35
|
-
"bio": "Building reliable AI systems"
|
|
36
|
-
},
|
|
37
|
-
"category": "design",
|
|
38
|
-
"tags": ["frontend", "ui", "css", "react"],
|
|
39
|
-
"roles": ["frontend", "fullstack"],
|
|
40
|
-
"source": "claude-official",
|
|
41
|
-
"icon": "P",
|
|
42
|
-
"contentUrl": "https://docs.groovedev.ai/skills/content/frontend-design.md",
|
|
43
|
-
"content": "--- (full SKILL.md content) ---",
|
|
44
|
-
"downloads": 1840,
|
|
45
|
-
"rating": 4.8,
|
|
46
|
-
"ratingCount": 124,
|
|
47
|
-
"price": 0,
|
|
48
|
-
"featured": false,
|
|
49
|
-
"status": "published",
|
|
50
|
-
"version": "1.0.0",
|
|
51
|
-
"createdAt": "2026-04-01T00:00:00Z",
|
|
52
|
-
"updatedAt": "2026-04-06T00:00:00Z"
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
**Categories** (enum): `design`, `quality`, `devtools`, `workflow`, `security`, `specialized`
|
|
57
|
-
|
|
58
|
-
**Status** (enum): `draft`, `review`, `published`, `rejected`, `unlisted`
|
|
59
|
-
|
|
60
|
-
**Source**: `claude-official` for Anthropic skills, `community` for user-submitted
|
|
61
|
-
|
|
62
|
-
### Author / User
|
|
63
|
-
|
|
64
|
-
```json
|
|
65
|
-
{
|
|
66
|
-
"id": "user_abc123",
|
|
67
|
-
"githubId": "12345",
|
|
68
|
-
"username": "johndoe",
|
|
69
|
-
"displayName": "John Doe",
|
|
70
|
-
"avatar": "https://avatars.githubusercontent.com/u/12345",
|
|
71
|
-
"bio": "Senior UI designer, 10 years experience",
|
|
72
|
-
"website": "https://johndoe.dev",
|
|
73
|
-
"github": "johndoe",
|
|
74
|
-
"twitter": "johndoe",
|
|
75
|
-
"portfolio": "https://dribbble.com/johndoe",
|
|
76
|
-
"createdAt": "2026-04-01T00:00:00Z",
|
|
77
|
-
"skillCount": 3,
|
|
78
|
-
"totalDownloads": 5200
|
|
79
|
-
}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
## API Endpoints
|
|
85
|
-
|
|
86
|
-
Base URL: `https://docs.groovedev.ai/api/v1`
|
|
87
|
-
|
|
88
|
-
### Public (no auth)
|
|
89
|
-
|
|
90
|
-
#### `GET /skills`
|
|
91
|
-
Returns the full skill registry. This is what the GROOVE daemon fetches on startup.
|
|
92
|
-
|
|
93
|
-
Query params:
|
|
94
|
-
- `search` — text search on name, description, tags
|
|
95
|
-
- `category` — filter by category
|
|
96
|
-
- `sort` — `popular` (default), `rating`, `newest`, `name`
|
|
97
|
-
- `status` — defaults to `published` only
|
|
98
|
-
- `author` — filter by authorId
|
|
99
|
-
- `limit` — pagination (default 50)
|
|
100
|
-
- `offset` — pagination offset
|
|
101
|
-
|
|
102
|
-
Response:
|
|
103
|
-
```json
|
|
104
|
-
{
|
|
105
|
-
"skills": [ ... ],
|
|
106
|
-
"total": 21,
|
|
107
|
-
"categories": [
|
|
108
|
-
{ "id": "devtools", "count": 9 },
|
|
109
|
-
{ "id": "quality", "count": 3 }
|
|
110
|
-
]
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
**Important:** The response shape must match what the GROOVE daemon expects. The `skills` array uses the same schema as `registry.json` today. The `content` field should NOT be included in list responses (it's large). Only metadata.
|
|
115
|
-
|
|
116
|
-
#### `GET /skills/:id`
|
|
117
|
-
Returns a single skill with full metadata.
|
|
118
|
-
|
|
119
|
-
Response: single skill object (without `content` field)
|
|
120
|
-
|
|
121
|
-
#### `GET /skills/:id/content`
|
|
122
|
-
Returns the full SKILL.md content for a skill.
|
|
123
|
-
|
|
124
|
-
Response:
|
|
125
|
-
```json
|
|
126
|
-
{
|
|
127
|
-
"id": "frontend-design",
|
|
128
|
-
"content": "---\nname: Frontend Design\n---\n\n..."
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
#### `GET /skills/registry.json`
|
|
133
|
-
**Backwards compatibility.** Returns the same format as the current static file so older GROOVE versions still work. Just the skills array, no wrapper object.
|
|
134
|
-
|
|
135
|
-
#### `GET /authors/:id`
|
|
136
|
-
Public author profile.
|
|
137
|
-
|
|
138
|
-
Response: author object + their published skills
|
|
139
|
-
|
|
140
|
-
---
|
|
141
|
-
|
|
142
|
-
### Authenticated (requires GitHub OAuth token)
|
|
143
|
-
|
|
144
|
-
#### Auth Flow
|
|
145
|
-
- GitHub OAuth (standard web flow)
|
|
146
|
-
- User authorizes, we get GitHub profile
|
|
147
|
-
- Create or update user record
|
|
148
|
-
- Return JWT for subsequent API calls
|
|
149
|
-
- GROOVE daemon does NOT handle auth — this is for the web portal / submission flow
|
|
150
|
-
|
|
151
|
-
#### `POST /skills`
|
|
152
|
-
Submit a new skill.
|
|
153
|
-
|
|
154
|
-
Body:
|
|
155
|
-
```json
|
|
156
|
-
{
|
|
157
|
-
"name": "My Awesome Skill",
|
|
158
|
-
"description": "Does amazing things...",
|
|
159
|
-
"category": "design",
|
|
160
|
-
"tags": ["ui", "css"],
|
|
161
|
-
"roles": ["frontend"],
|
|
162
|
-
"icon": "A",
|
|
163
|
-
"content": "---\nname: My Awesome Skill\n---\n\nFull SKILL.md content here...",
|
|
164
|
-
"price": 0,
|
|
165
|
-
"version": "1.0.0"
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
- `id` is auto-generated from slugified `name`
|
|
170
|
-
- `author`, `authorId`, `authorProfile` populated from authenticated user
|
|
171
|
-
- `source` set to `community`
|
|
172
|
-
- `status` set to `draft` initially
|
|
173
|
-
- `downloads`, `rating`, `ratingCount` initialized to 0
|
|
174
|
-
|
|
175
|
-
Response: created skill object
|
|
176
|
-
|
|
177
|
-
#### `PUT /skills/:id`
|
|
178
|
-
Edit an existing skill. Author-only.
|
|
179
|
-
|
|
180
|
-
Body: partial skill object (only changed fields)
|
|
181
|
-
|
|
182
|
-
Restrictions:
|
|
183
|
-
- Can only edit your own skills
|
|
184
|
-
- Cannot change `id`, `authorId`, `source`, `downloads`, `rating`, `ratingCount`
|
|
185
|
-
- Changing `content` bumps `updatedAt`
|
|
186
|
-
|
|
187
|
-
#### `DELETE /skills/:id`
|
|
188
|
-
Remove a skill. Author-only. Sets status to `unlisted` (soft delete).
|
|
189
|
-
|
|
190
|
-
#### `POST /skills/:id/publish`
|
|
191
|
-
Submit a skill for review / publish it.
|
|
192
|
-
- If `price === 0`: auto-publish (set status to `published`)
|
|
193
|
-
- If `price > 0`: set status to `review` (manual review before listing)
|
|
194
|
-
|
|
195
|
-
#### `PUT /authors/me`
|
|
196
|
-
Update your own author profile.
|
|
197
|
-
|
|
198
|
-
Body:
|
|
199
|
-
```json
|
|
200
|
-
{
|
|
201
|
-
"displayName": "John Doe",
|
|
202
|
-
"bio": "Senior UI designer",
|
|
203
|
-
"website": "https://...",
|
|
204
|
-
"twitter": "johndoe",
|
|
205
|
-
"portfolio": "https://..."
|
|
206
|
-
}
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
---
|
|
210
|
-
|
|
211
|
-
### Future (Payments — don't build yet, but design schema for it)
|
|
212
|
-
|
|
213
|
-
- `POST /skills/:id/purchase` — record a purchase
|
|
214
|
-
- `GET /authors/me/earnings` — seller dashboard
|
|
215
|
-
- Stripe Connect for payouts
|
|
216
|
-
- 80/20 revenue share (creator/platform)
|
|
217
|
-
- Price field already in the skill model, just not enforced yet
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
## Key Design Decisions
|
|
222
|
-
|
|
223
|
-
1. **Backwards compatible** — `/skills/registry.json` must keep working as a plain JSON array. The GROOVE daemon currently fetches this on startup. Newer daemon versions will switch to `/api/v1/skills`.
|
|
224
|
-
|
|
225
|
-
2. **Content separate from metadata** — The `content` (full SKILL.md) is large. Never include it in list/registry responses. Only serve it via `/skills/:id/content`.
|
|
226
|
-
|
|
227
|
-
3. **Soft deletes** — Never hard-delete skills. Set status to `unlisted`.
|
|
228
|
-
|
|
229
|
-
4. **Download counting** — Increment on install. The GROOVE daemon will POST to `/skills/:id/install` to record an install (new endpoint, unauthenticated, rate-limited by IP).
|
|
230
|
-
|
|
231
|
-
5. **Rating** — Not building the rating/review system yet, but the fields are in the schema. We'll add `POST /skills/:id/rate` later.
|
|
232
|
-
|
|
233
|
-
6. **The 21 Anthropic skills** — Seed the database with these. They have `source: "claude-official"` and `author: "Anthropic"`. They should not be editable via the API.
|
|
234
|
-
|
|
235
|
-
7. **Validation:**
|
|
236
|
-
- `name`: 3-100 chars
|
|
237
|
-
- `description`: 10-500 chars
|
|
238
|
-
- `content`: must be valid markdown, max 50KB
|
|
239
|
-
- `category`: must be one of the enum values
|
|
240
|
-
- `tags`: max 10, each 2-30 chars
|
|
241
|
-
- `icon`: single character
|
|
242
|
-
- `price`: >= 0, max 99.99
|
|
243
|
-
|
|
244
|
-
---
|
|
245
|
-
|
|
246
|
-
## Tech Recommendations
|
|
247
|
-
|
|
248
|
-
- Whatever fits the existing docs site stack
|
|
249
|
-
- If starting fresh: Node.js + Express or Hono, SQLite or Postgres
|
|
250
|
-
- GitHub OAuth for auth
|
|
251
|
-
- JWT for session tokens
|
|
252
|
-
- Rate limiting on public endpoints (60/min per IP)
|
|
253
|
-
- CORS: allow `localhost:*` (for GROOVE daemon) + `groovedev.ai` origins
|
|
254
|
-
|
|
255
|
-
---
|
|
256
|
-
|
|
257
|
-
## Install Tracking Endpoint
|
|
258
|
-
|
|
259
|
-
Add this for download counting (the GROOVE daemon calls this when a user installs a skill):
|
|
260
|
-
|
|
261
|
-
#### `POST /skills/:id/install`
|
|
262
|
-
Unauthenticated. Rate-limited (1 per skill per IP per hour).
|
|
263
|
-
|
|
264
|
-
Increments the `downloads` counter.
|
|
265
|
-
|
|
266
|
-
Response: `{ "downloads": 1841 }`
|
|
267
|
-
|
|
268
|
-
This replaces the current flow where the daemon downloads from `contentUrl` directly. New flow:
|
|
269
|
-
1. Daemon calls `POST /api/v1/skills/:id/install` to record the install
|
|
270
|
-
2. Daemon calls `GET /api/v1/skills/:id/content` to get the SKILL.md
|
|
271
|
-
3. Daemon saves locally
|
|
272
|
-
|
|
273
|
-
---
|
|
274
|
-
|
|
275
|
-
## Seed Data
|
|
276
|
-
|
|
277
|
-
The current `skills-registry.json` in the GROOVE repo has all 21 Anthropic skills with full metadata including downloads, ratings, prices, author profiles, and featured flags. Use this to seed the database.
|