swarm-tickets 2.0.0 → 2.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swarm-tickets",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "Lightweight ticket tracking system for AI-powered bug fixing with Claude-flow/Claude Code. Supports JSON, SQLite, and Supabase storage.",
5
5
  "main": "ticket-server.js",
6
6
  "bin": {
package/setup.js CHANGED
@@ -24,16 +24,15 @@ try {
24
24
  console.log('✅ Installed swarm skill');
25
25
  }
26
26
 
27
- // Copy ticket-tracker.html to project root
27
+ // Copy ticket-tracker.html to project root (always update to get latest features)
28
28
  const htmlSource = path.join(__dirname, 'ticket-tracker.html');
29
29
  const htmlDest = path.join(projectRoot, 'ticket-tracker.html');
30
-
31
- if (!fs.existsSync(htmlDest)) {
32
- fs.copyFileSync(htmlSource, htmlDest);
33
- console.log('✅ Copied ticket-tracker.html to project root');
34
- } else {
35
- console.log('⚠️ ticket-tracker.html already exists, skipping');
36
- }
30
+
31
+ const htmlExists = fs.existsSync(htmlDest);
32
+ fs.copyFileSync(htmlSource, htmlDest);
33
+ console.log(htmlExists
34
+ ? '✅ Updated ticket-tracker.html to latest version'
35
+ : '✅ Copied ticket-tracker.html to project root');
37
36
 
38
37
  // Create tickets.json if it doesn't exist
39
38
  const ticketsFile = path.join(projectRoot, 'tickets.json');
@@ -560,6 +560,47 @@
560
560
  </div>
561
561
  </div>
562
562
 
563
+ <!-- Edit Ticket Modal -->
564
+ <div id="edit-modal" class="modal">
565
+ <div class="modal-content" style="max-width: 600px;">
566
+ <div class="modal-header">
567
+ <h3>✏️ Edit Ticket</h3>
568
+ <button class="modal-close" onclick="closeEditModal()">&times;</button>
569
+ </div>
570
+ <form id="edit-form">
571
+ <input type="hidden" id="edit-ticket-id">
572
+ <div class="form-group">
573
+ <label for="edit-status">Status</label>
574
+ <select id="edit-status">
575
+ <option value="open">Open</option>
576
+ <option value="in-progress">In Progress</option>
577
+ <option value="fixed">Fixed</option>
578
+ <option value="closed">Closed</option>
579
+ </select>
580
+ </div>
581
+ <div class="form-group">
582
+ <label for="edit-priority">Priority</label>
583
+ <select id="edit-priority">
584
+ <option value="">Not Set</option>
585
+ <option value="critical">Critical</option>
586
+ <option value="high">High</option>
587
+ <option value="medium">Medium</option>
588
+ <option value="low">Low</option>
589
+ </select>
590
+ </div>
591
+ <div class="form-group">
592
+ <label for="edit-description">Description</label>
593
+ <textarea id="edit-description" rows="3" placeholder="Description..."></textarea>
594
+ </div>
595
+ <div class="form-group">
596
+ <label for="edit-namespace">Namespace (where fix applied)</label>
597
+ <input type="text" id="edit-namespace" placeholder="e.g., auth/login, database/connection">
598
+ </div>
599
+ <button type="submit">Save Changes</button>
600
+ </form>
601
+ </div>
602
+ </div>
603
+
563
604
  <script>
564
605
  let tickets = [];
565
606
  let useServer = false;
@@ -798,6 +839,63 @@
798
839
  document.getElementById('comment-modal').classList.remove('open');
799
840
  }
800
841
 
842
+ // Open edit modal
843
+ function openEditModal(ticketId) {
844
+ const ticket = tickets.find(t => t.id === ticketId);
845
+ if (!ticket) return;
846
+
847
+ document.getElementById('edit-ticket-id').value = ticketId;
848
+ document.getElementById('edit-status').value = ticket.status || 'open';
849
+ document.getElementById('edit-priority').value = ticket.priority || '';
850
+ document.getElementById('edit-description').value = ticket.description || '';
851
+ document.getElementById('edit-namespace').value = ticket.namespace || '';
852
+ document.getElementById('edit-modal').classList.add('open');
853
+ }
854
+
855
+ // Close edit modal
856
+ function closeEditModal() {
857
+ document.getElementById('edit-modal').classList.remove('open');
858
+ }
859
+
860
+ // Handle edit form
861
+ document.getElementById('edit-form').addEventListener('submit', async function(e) {
862
+ e.preventDefault();
863
+ const ticketId = document.getElementById('edit-ticket-id').value;
864
+ const updates = {
865
+ status: document.getElementById('edit-status').value,
866
+ priority: document.getElementById('edit-priority').value || null,
867
+ description: document.getElementById('edit-description').value,
868
+ namespace: document.getElementById('edit-namespace').value || null
869
+ };
870
+
871
+ if (useServer) {
872
+ try {
873
+ await fetch(`${API_BASE}/tickets/${ticketId}`, {
874
+ method: 'PATCH',
875
+ headers: { 'Content-Type': 'application/json' },
876
+ body: JSON.stringify(updates)
877
+ });
878
+ await loadTickets();
879
+ renderTickets();
880
+ renderStats();
881
+ closeEditModal();
882
+ } catch (error) {
883
+ alert('Failed to update ticket');
884
+ }
885
+ } else {
886
+ // Update in localStorage
887
+ const ticket = tickets.find(t => t.id === ticketId);
888
+ if (ticket) {
889
+ Object.assign(ticket, updates);
890
+ ticket.updatedAt = new Date().toISOString();
891
+ localStorage.setItem('claudeflow-tickets', JSON.stringify(tickets));
892
+ renderTickets();
893
+ renderStats();
894
+ closeEditModal();
895
+ }
896
+ }
897
+ });
898
+
801
899
  // Add comment
802
900
  async function addComment(ticketId, author, content) {
803
901
  if (useServer) {
@@ -1004,8 +1102,11 @@
1004
1102
  <button class="quick-prompt-btn btn-small" onclick="copyQuickPrompt('${ticket.id}')">
1005
1103
  📋 Quick Prompt
1006
1104
  </button>
1105
+ <button class="btn-small" onclick="openEditModal('${ticket.id}')" style="background: #3498db;">
1106
+ ✏️ Edit
1107
+ </button>
1007
1108
  <button class="btn-secondary btn-small" onclick="openCommentModal('${ticket.id}')">
1008
- 💬 Add Comment
1109
+ 💬 Comment
1009
1110
  </button>
1010
1111
  ${ticket.status !== 'closed' ? `
1011
1112
  <button class="btn-danger btn-small" onclick="closeTicket('${ticket.id}')">
@@ -1058,20 +1159,27 @@
1058
1159
  renderTickets(filtered);
1059
1160
  }
1060
1161
 
1061
- // Close modal on escape
1162
+ // Close modals on escape
1062
1163
  document.addEventListener('keydown', (e) => {
1063
1164
  if (e.key === 'Escape') {
1064
1165
  closeCommentModal();
1166
+ closeEditModal();
1065
1167
  }
1066
1168
  });
1067
1169
 
1068
- // Close modal on overlay click
1170
+ // Close modals on overlay click
1069
1171
  document.getElementById('comment-modal').addEventListener('click', (e) => {
1070
1172
  if (e.target.classList.contains('modal')) {
1071
1173
  closeCommentModal();
1072
1174
  }
1073
1175
  });
1074
1176
 
1177
+ document.getElementById('edit-modal').addEventListener('click', (e) => {
1178
+ if (e.target.classList.contains('modal')) {
1179
+ closeEditModal();
1180
+ }
1181
+ });
1182
+
1075
1183
  // Initialize
1076
1184
  updateProjectName();
1077
1185
  updateFormLabels();