@cluesmith/codev 2.0.0-rc.26 → 2.0.0-rc.27

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": "@cluesmith/codev",
3
- "version": "2.0.0-rc.26",
3
+ "version": "2.0.0-rc.27",
4
4
  "description": "Codev CLI - AI-assisted software development framework",
5
5
  "type": "module",
6
6
  "bin": {
@@ -4,15 +4,15 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>AF: {{PROJECT_NAME}}</title>
7
- <!-- CSS files loaded in dependency order -->
8
- <link rel="stylesheet" href="/dashboard/css/variables.css">
9
- <link rel="stylesheet" href="/dashboard/css/layout.css">
10
- <link rel="stylesheet" href="/dashboard/css/tabs.css">
11
- <link rel="stylesheet" href="/dashboard/css/statusbar.css">
12
- <link rel="stylesheet" href="/dashboard/css/dialogs.css">
13
- <link rel="stylesheet" href="/dashboard/css/projects.css">
14
- <link rel="stylesheet" href="/dashboard/css/files.css">
15
- <link rel="stylesheet" href="/dashboard/css/utilities.css">
7
+ <!-- CSS files loaded in dependency order (relative paths for proxy compatibility) -->
8
+ <link rel="stylesheet" href="dashboard/css/variables.css">
9
+ <link rel="stylesheet" href="dashboard/css/layout.css">
10
+ <link rel="stylesheet" href="dashboard/css/tabs.css">
11
+ <link rel="stylesheet" href="dashboard/css/statusbar.css">
12
+ <link rel="stylesheet" href="dashboard/css/dialogs.css">
13
+ <link rel="stylesheet" href="dashboard/css/projects.css">
14
+ <link rel="stylesheet" href="dashboard/css/files.css">
15
+ <link rel="stylesheet" href="dashboard/css/utilities.css">
16
16
  </head>
17
17
  <body>
18
18
  <header class="header">
@@ -137,12 +137,13 @@
137
137
  </script>
138
138
 
139
139
  <!-- JavaScript files loaded in dependency order -->
140
- <script src="/dashboard/js/state.js"></script>
141
- <script src="/dashboard/js/utils.js"></script>
142
- <script src="/dashboard/js/tabs.js"></script>
143
- <script src="/dashboard/js/dialogs.js"></script>
144
- <script src="/dashboard/js/projects.js"></script>
145
- <script src="/dashboard/js/files.js"></script>
146
- <script src="/dashboard/js/main.js"></script>
140
+ <!-- JS files (relative paths for proxy compatibility) -->
141
+ <script src="dashboard/js/state.js"></script>
142
+ <script src="dashboard/js/utils.js"></script>
143
+ <script src="dashboard/js/tabs.js"></script>
144
+ <script src="dashboard/js/dialogs.js"></script>
145
+ <script src="dashboard/js/projects.js"></script>
146
+ <script src="dashboard/js/files.js"></script>
147
+ <script src="dashboard/js/main.js"></script>
147
148
  </body>
148
149
  </html>
@@ -1535,18 +1535,31 @@
1535
1535
  }
1536
1536
 
1537
1537
  // Share dialog functions (QR code for mobile access)
1538
+ let tunnelAbortController = null;
1539
+
1538
1540
  async function showShareDialog() {
1539
1541
  const dialog = document.getElementById('share-dialog');
1540
1542
  const content = document.getElementById('share-content');
1541
1543
  const stopBtn = document.getElementById('stop-tunnel-btn');
1542
1544
 
1543
1545
  dialog.style.display = 'flex';
1544
- content.innerHTML = '<div class="loading"><div class="spinner"></div><p>Starting tunnel...</p></div>';
1545
1546
  stopBtn.style.display = 'none';
1546
1547
 
1548
+ // Create abort controller for cancellation
1549
+ tunnelAbortController = new AbortController();
1550
+
1551
+ content.innerHTML = `
1552
+ <div class="loading">
1553
+ <div class="spinner"></div>
1554
+ <p>Starting tunnel...</p>
1555
+ <p style="font-size: 12px; color: var(--muted); margin-top: 8px;">This may take up to 30 seconds</p>
1556
+ <button class="btn" style="margin-top: 16px;" onclick="cancelTunnelStart()">Cancel</button>
1557
+ </div>
1558
+ `;
1559
+
1547
1560
  try {
1548
1561
  // Check if tunnel is already running
1549
- const statusRes = await fetch('/api/tunnel/status');
1562
+ const statusRes = await fetch('/api/tunnel/status', { signal: tunnelAbortController.signal });
1550
1563
  const status = await statusRes.json();
1551
1564
 
1552
1565
  if (status.running && status.url) {
@@ -1555,7 +1568,7 @@
1555
1568
  }
1556
1569
 
1557
1570
  // Start tunnel
1558
- const res = await fetch('/api/tunnel/start', { method: 'POST' });
1571
+ const res = await fetch('/api/tunnel/start', { method: 'POST', signal: tunnelAbortController.signal });
1559
1572
  const result = await res.json();
1560
1573
 
1561
1574
  if (result.success && result.url) {
@@ -1564,8 +1577,22 @@
1564
1577
  content.innerHTML = `<p style="color: var(--danger);">Failed to start tunnel: ${result.error || 'Unknown error'}</p>`;
1565
1578
  }
1566
1579
  } catch (e) {
1567
- content.innerHTML = `<p style="color: var(--danger);">Error: ${e.message}</p>`;
1580
+ if (e.name === 'AbortError') {
1581
+ content.innerHTML = '<p>Tunnel start cancelled.</p>';
1582
+ } else {
1583
+ content.innerHTML = `<p style="color: var(--danger);">Error: ${e.message}</p>`;
1584
+ }
1585
+ } finally {
1586
+ tunnelAbortController = null;
1587
+ }
1588
+ }
1589
+
1590
+ function cancelTunnelStart() {
1591
+ if (tunnelAbortController) {
1592
+ tunnelAbortController.abort();
1568
1593
  }
1594
+ // Also stop any tunnel that might have started
1595
+ fetch('/api/tunnel/stop', { method: 'POST' }).catch(() => {});
1569
1596
  }
1570
1597
 
1571
1598
  function showQRCode(tunnelUrl) {