swarm-tickets 1.0.0 → 2.0.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/LICENSE.txt +0 -0
- package/README.md +307 -61
- package/SKILL.md +222 -46
- package/backup-tickets.sh +0 -0
- package/bug-report-widget.js +536 -0
- package/lib/storage/base-adapter.js +200 -0
- package/lib/storage/index.js +87 -0
- package/lib/storage/json-adapter.js +293 -0
- package/lib/storage/sqlite-adapter.js +552 -0
- package/lib/storage/supabase-adapter.js +614 -0
- package/package.json +21 -12
- package/setup.js +9 -11
- package/ticket-cli.js +0 -0
- package/ticket-server.js +425 -269
- package/ticket-tracker.html +459 -132
- package/tickets.example.json +0 -0
package/SKILL.md
CHANGED
|
@@ -9,34 +9,61 @@ This skill enables you to track and manage bug tickets in the project.
|
|
|
9
9
|
|
|
10
10
|
## Overview
|
|
11
11
|
|
|
12
|
-
The project uses `swarm-tickets` for bug tracking. Tickets
|
|
12
|
+
The project uses `swarm-tickets` for bug tracking. Tickets can be stored in multiple backends:
|
|
13
|
+
- **JSON** (default): `./tickets.json` at the project root
|
|
14
|
+
- **SQLite**: `./tickets.db` local database
|
|
15
|
+
- **Supabase**: Cloud PostgreSQL database
|
|
16
|
+
|
|
17
|
+
## Storage Configuration
|
|
18
|
+
|
|
19
|
+
Set the storage backend via environment variable:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# JSON (default)
|
|
23
|
+
export SWARM_TICKETS_STORAGE=json
|
|
24
|
+
|
|
25
|
+
# SQLite
|
|
26
|
+
export SWARM_TICKETS_STORAGE=sqlite
|
|
27
|
+
export SWARM_TICKETS_SQLITE_PATH=./tickets.db
|
|
28
|
+
|
|
29
|
+
# Supabase
|
|
30
|
+
export SWARM_TICKETS_STORAGE=supabase
|
|
31
|
+
export SUPABASE_URL=https://your-project.supabase.co
|
|
32
|
+
export SUPABASE_ANON_KEY=your-anon-key
|
|
33
|
+
```
|
|
13
34
|
|
|
14
35
|
## Ticket Structure
|
|
15
36
|
|
|
16
37
|
```json
|
|
17
38
|
{
|
|
18
|
-
"
|
|
39
|
+
"id": "TKT-1234567890",
|
|
40
|
+
"route": "/dashboard/users",
|
|
41
|
+
"f12Errors": "Browser console errors",
|
|
42
|
+
"serverErrors": "Server-side errors",
|
|
43
|
+
"description": "Additional context",
|
|
44
|
+
"status": "open|in-progress|fixed|closed",
|
|
45
|
+
"priority": "critical|high|medium|low",
|
|
46
|
+
"relatedTickets": ["TKT-xxx"],
|
|
47
|
+
"swarmActions": [
|
|
19
48
|
{
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"serverErrors": "Server-side errors",
|
|
24
|
-
"description": "Additional context",
|
|
25
|
-
"status": "open|in-progress|fixed|closed",
|
|
26
|
-
"priority": "critical|high|medium|low",
|
|
27
|
-
"relatedTickets": ["TKT-xxx"],
|
|
28
|
-
"swarmActions": [
|
|
29
|
-
{
|
|
30
|
-
"timestamp": "ISO timestamp",
|
|
31
|
-
"action": "What you did",
|
|
32
|
-
"result": "What happened"
|
|
33
|
-
}
|
|
34
|
-
],
|
|
35
|
-
"namespace": "where/fixes/applied",
|
|
36
|
-
"createdAt": "ISO timestamp",
|
|
37
|
-
"updatedAt": "ISO timestamp"
|
|
49
|
+
"timestamp": "ISO timestamp",
|
|
50
|
+
"action": "What you did",
|
|
51
|
+
"result": "What happened"
|
|
38
52
|
}
|
|
39
|
-
]
|
|
53
|
+
],
|
|
54
|
+
"comments": [
|
|
55
|
+
{
|
|
56
|
+
"id": "CMT-xxx",
|
|
57
|
+
"timestamp": "ISO timestamp",
|
|
58
|
+
"type": "human|ai",
|
|
59
|
+
"author": "username",
|
|
60
|
+
"content": "Comment text",
|
|
61
|
+
"metadata": {}
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"namespace": "where/fixes/applied",
|
|
65
|
+
"createdAt": "ISO timestamp",
|
|
66
|
+
"updatedAt": "ISO timestamp"
|
|
40
67
|
}
|
|
41
68
|
```
|
|
42
69
|
|
|
@@ -44,14 +71,121 @@ The project uses `swarm-tickets` for bug tracking. Tickets are stored in `./tick
|
|
|
44
71
|
|
|
45
72
|
### Before You Start
|
|
46
73
|
|
|
47
|
-
Always create a backup before modifying tickets
|
|
74
|
+
Always create a backup before modifying tickets directly:
|
|
48
75
|
|
|
49
76
|
```javascript
|
|
50
77
|
const fs = require('fs').promises;
|
|
51
78
|
await fs.copyFile('tickets.json', `tickets.backup.${Date.now()}.json`);
|
|
52
79
|
```
|
|
53
80
|
|
|
54
|
-
###
|
|
81
|
+
### Using the API (Recommended)
|
|
82
|
+
|
|
83
|
+
```javascript
|
|
84
|
+
// Base URL for local server
|
|
85
|
+
const API = 'http://localhost:3456/api';
|
|
86
|
+
|
|
87
|
+
// Get all tickets
|
|
88
|
+
const response = await fetch(`${API}/tickets`);
|
|
89
|
+
const tickets = await response.json();
|
|
90
|
+
|
|
91
|
+
// Filter tickets
|
|
92
|
+
const openTickets = await fetch(`${API}/tickets?status=open`);
|
|
93
|
+
const criticalTickets = await fetch(`${API}/tickets?priority=critical`);
|
|
94
|
+
|
|
95
|
+
// Get single ticket
|
|
96
|
+
const ticket = await fetch(`${API}/tickets/TKT-123`).then(r => r.json());
|
|
97
|
+
|
|
98
|
+
// Create ticket
|
|
99
|
+
const newTicket = await fetch(`${API}/tickets`, {
|
|
100
|
+
method: 'POST',
|
|
101
|
+
headers: { 'Content-Type': 'application/json' },
|
|
102
|
+
body: JSON.stringify({
|
|
103
|
+
route: '/dashboard',
|
|
104
|
+
description: 'Something is broken',
|
|
105
|
+
f12Errors: 'TypeError: ...',
|
|
106
|
+
serverErrors: ''
|
|
107
|
+
})
|
|
108
|
+
}).then(r => r.json());
|
|
109
|
+
|
|
110
|
+
// Update ticket
|
|
111
|
+
await fetch(`${API}/tickets/${ticketId}`, {
|
|
112
|
+
method: 'PATCH',
|
|
113
|
+
headers: { 'Content-Type': 'application/json' },
|
|
114
|
+
body: JSON.stringify({
|
|
115
|
+
status: 'in-progress',
|
|
116
|
+
priority: 'high'
|
|
117
|
+
})
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Close ticket
|
|
121
|
+
await fetch(`${API}/tickets/${ticketId}/close`, {
|
|
122
|
+
method: 'POST',
|
|
123
|
+
headers: { 'Content-Type': 'application/json' },
|
|
124
|
+
body: JSON.stringify({ reason: 'Fixed in commit abc123' })
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Reopen ticket
|
|
128
|
+
await fetch(`${API}/tickets/${ticketId}/reopen`, { method: 'POST' });
|
|
129
|
+
|
|
130
|
+
// Add swarm action
|
|
131
|
+
await fetch(`${API}/tickets/${ticketId}/swarm-action`, {
|
|
132
|
+
method: 'POST',
|
|
133
|
+
headers: { 'Content-Type': 'application/json' },
|
|
134
|
+
body: JSON.stringify({
|
|
135
|
+
action: 'Investigating database connection',
|
|
136
|
+
result: 'Found connection pool misconfiguration'
|
|
137
|
+
})
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Working with Comments
|
|
142
|
+
|
|
143
|
+
```javascript
|
|
144
|
+
// Add a human comment
|
|
145
|
+
await fetch(`${API}/tickets/${ticketId}/comments`, {
|
|
146
|
+
method: 'POST',
|
|
147
|
+
headers: { 'Content-Type': 'application/json' },
|
|
148
|
+
body: JSON.stringify({
|
|
149
|
+
type: 'human',
|
|
150
|
+
author: 'developer-name',
|
|
151
|
+
content: 'I think this is related to the auth refactor'
|
|
152
|
+
})
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// Add an AI comment
|
|
156
|
+
await fetch(`${API}/tickets/${ticketId}/comments`, {
|
|
157
|
+
method: 'POST',
|
|
158
|
+
headers: { 'Content-Type': 'application/json' },
|
|
159
|
+
body: JSON.stringify({
|
|
160
|
+
type: 'ai',
|
|
161
|
+
author: 'claude',
|
|
162
|
+
content: 'After analyzing the stack trace, this appears to be a null reference issue in UserList.jsx:45',
|
|
163
|
+
metadata: {
|
|
164
|
+
analysisType: 'stack-trace',
|
|
165
|
+
confidence: 'high'
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Get all comments for a ticket
|
|
171
|
+
const comments = await fetch(`${API}/tickets/${ticketId}/comments`).then(r => r.json());
|
|
172
|
+
|
|
173
|
+
// Update a comment
|
|
174
|
+
await fetch(`${API}/tickets/${ticketId}/comments/${commentId}`, {
|
|
175
|
+
method: 'PATCH',
|
|
176
|
+
headers: { 'Content-Type': 'application/json' },
|
|
177
|
+
body: JSON.stringify({
|
|
178
|
+
content: 'Updated comment text'
|
|
179
|
+
})
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// Delete a comment
|
|
183
|
+
await fetch(`${API}/tickets/${ticketId}/comments/${commentId}`, {
|
|
184
|
+
method: 'DELETE'
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Reading Tickets (Direct File Access - JSON only)
|
|
55
189
|
|
|
56
190
|
```javascript
|
|
57
191
|
const fs = require('fs').promises;
|
|
@@ -68,7 +202,7 @@ const highPriority = tickets.filter(t => t.priority === 'high' || t.priority ===
|
|
|
68
202
|
const routeTickets = tickets.filter(t => t.route.includes('/dashboard'));
|
|
69
203
|
```
|
|
70
204
|
|
|
71
|
-
### Updating Tickets
|
|
205
|
+
### Updating Tickets (Direct File Access - JSON only)
|
|
72
206
|
|
|
73
207
|
When working on a ticket:
|
|
74
208
|
|
|
@@ -129,21 +263,6 @@ if (!ticket.priority) {
|
|
|
129
263
|
}
|
|
130
264
|
```
|
|
131
265
|
|
|
132
|
-
### Linking Related Tickets
|
|
133
|
-
|
|
134
|
-
Find and link related tickets:
|
|
135
|
-
|
|
136
|
-
```javascript
|
|
137
|
-
// Find tickets on the same route
|
|
138
|
-
const related = tickets
|
|
139
|
-
.filter(t => t.id !== ticket.id && t.route === ticket.route)
|
|
140
|
-
.map(t => t.id);
|
|
141
|
-
|
|
142
|
-
if (related.length > 0) {
|
|
143
|
-
ticket.relatedTickets = related;
|
|
144
|
-
}
|
|
145
|
-
```
|
|
146
|
-
|
|
147
266
|
### Setting Namespace
|
|
148
267
|
|
|
149
268
|
Document where fixes were applied:
|
|
@@ -161,10 +280,11 @@ ticket.namespace = 'api/users';
|
|
|
161
280
|
1. **Always backup before modifying** - Copy tickets.json before changes
|
|
162
281
|
2. **Update timestamps** - Set `updatedAt` when changing tickets
|
|
163
282
|
3. **Log your actions** - Add entries to `swarmActions` for everything you do
|
|
164
|
-
4. **
|
|
165
|
-
5. **
|
|
166
|
-
6. **
|
|
167
|
-
7. **
|
|
283
|
+
4. **Add comments** - Use the comments system for discussion and notes
|
|
284
|
+
5. **Set priorities** - Help triage by assigning priority levels
|
|
285
|
+
6. **Link related tickets** - Connect tickets that affect the same area
|
|
286
|
+
7. **Document namespaces** - Record where fixes were applied
|
|
287
|
+
8. **Be specific** - In swarm actions, explain what you did and why
|
|
168
288
|
|
|
169
289
|
## Workflow Example
|
|
170
290
|
|
|
@@ -214,6 +334,27 @@ ticket.updatedAt = new Date().toISOString();
|
|
|
214
334
|
await fs.writeFile('tickets.json', JSON.stringify(data, null, 2));
|
|
215
335
|
```
|
|
216
336
|
|
|
337
|
+
## API Endpoints Reference
|
|
338
|
+
|
|
339
|
+
| Method | Endpoint | Description |
|
|
340
|
+
|--------|----------|-------------|
|
|
341
|
+
| GET | `/api/tickets` | List all tickets (supports `?status=`, `?priority=`, `?route=`) |
|
|
342
|
+
| POST | `/api/tickets` | Create new ticket |
|
|
343
|
+
| GET | `/api/tickets/:id` | Get single ticket |
|
|
344
|
+
| PATCH | `/api/tickets/:id` | Update ticket |
|
|
345
|
+
| DELETE | `/api/tickets/:id` | Delete ticket |
|
|
346
|
+
| POST | `/api/tickets/:id/close` | Close ticket (with optional reason) |
|
|
347
|
+
| POST | `/api/tickets/:id/reopen` | Reopen ticket |
|
|
348
|
+
| POST | `/api/tickets/:id/analyze` | Auto-analyze and set priority |
|
|
349
|
+
| POST | `/api/tickets/:id/swarm-action` | Add swarm action |
|
|
350
|
+
| GET | `/api/tickets/:id/comments` | Get ticket comments |
|
|
351
|
+
| POST | `/api/tickets/:id/comments` | Add comment |
|
|
352
|
+
| PATCH | `/api/tickets/:id/comments/:commentId` | Update comment |
|
|
353
|
+
| DELETE | `/api/tickets/:id/comments/:commentId` | Delete comment |
|
|
354
|
+
| GET | `/api/stats` | Get ticket statistics |
|
|
355
|
+
| POST | `/api/bug-report` | Submit bug report (rate limited) |
|
|
356
|
+
| GET | `/api/health` | Health check |
|
|
357
|
+
|
|
217
358
|
## UI Access
|
|
218
359
|
|
|
219
360
|
Users can view and create tickets via the web UI:
|
|
@@ -225,11 +366,46 @@ The UI allows users to:
|
|
|
225
366
|
- Create new tickets with F12 and server errors
|
|
226
367
|
- View all tickets with filtering and search
|
|
227
368
|
- See ticket status, priority, and swarm actions
|
|
369
|
+
- Add comments to tickets
|
|
370
|
+
- Close/reopen tickets
|
|
371
|
+
|
|
372
|
+
## Bug Report Widget
|
|
373
|
+
|
|
374
|
+
For end-user bug reporting, embed the widget in your application. The widget is served automatically by the swarm-tickets server.
|
|
375
|
+
|
|
376
|
+
```html
|
|
377
|
+
<!-- Local development -->
|
|
378
|
+
<script src="http://localhost:3456/bug-report-widget.js"
|
|
379
|
+
data-endpoint="http://localhost:3456/api/bug-report"
|
|
380
|
+
data-position="bottom-right"
|
|
381
|
+
data-theme="dark">
|
|
382
|
+
</script>
|
|
383
|
+
|
|
384
|
+
<!-- Production (use your actual server URL) -->
|
|
385
|
+
<script src="https://your-server.com/bug-report-widget.js"
|
|
386
|
+
data-endpoint="https://your-server.com/api/bug-report"
|
|
387
|
+
data-api-key="stk_your_api_key"
|
|
388
|
+
data-position="bottom-right"
|
|
389
|
+
data-theme="dark">
|
|
390
|
+
</script>
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### Widget Options
|
|
394
|
+
|
|
395
|
+
| Option | Default | Description |
|
|
396
|
+
|--------|---------|-------------|
|
|
397
|
+
| `data-endpoint` | `/api/bug-report` | API endpoint URL |
|
|
398
|
+
| `data-api-key` | none | API key for authentication |
|
|
399
|
+
| `data-position` | `bottom-right` | `bottom-right`, `bottom-left`, `top-right`, `top-left` |
|
|
400
|
+
| `data-theme` | `dark` | `dark` or `light` |
|
|
401
|
+
|
|
402
|
+
See the main README.md for complete widget configuration and API key management.
|
|
228
403
|
|
|
229
404
|
## Notes
|
|
230
405
|
|
|
231
|
-
- Tickets persist
|
|
232
|
-
- The server auto-backs up to `ticket-backups/` before writes (
|
|
406
|
+
- Tickets persist based on configured storage (JSON, SQLite, or Supabase)
|
|
407
|
+
- The server auto-backs up to `ticket-backups/` before writes (JSON mode)
|
|
233
408
|
- Manual backups recommended: Copy tickets.json before major changes
|
|
234
409
|
- Recovery: Restore from `ticket-backups/` folder (keeps last 10)
|
|
235
|
-
- The UI and the swarm both work with the same
|
|
410
|
+
- The UI and the swarm both work with the same ticket storage
|
|
411
|
+
- Comments support both human and AI authors for collaborative debugging
|
package/backup-tickets.sh
CHANGED
|
File without changes
|