@cluesmith/codev 2.0.0-rc.28 → 2.0.0-rc.29
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
|
@@ -20,7 +20,7 @@ async function closeTab(tabId, event) {
|
|
|
20
20
|
// Check if process is still running before showing confirmation (Bugfix #132)
|
|
21
21
|
// If the shell/builder already exited, close immediately without confirmation
|
|
22
22
|
try {
|
|
23
|
-
const response = await fetch(
|
|
23
|
+
const response = await fetch(apiUrl(`api/tabs/${encodeURIComponent(tabId)}/running`));
|
|
24
24
|
if (response.ok) {
|
|
25
25
|
const { running } = await response.json();
|
|
26
26
|
if (!running) {
|
|
@@ -56,7 +56,7 @@ async function doCloseTab(tabId) {
|
|
|
56
56
|
if (!tab) return;
|
|
57
57
|
|
|
58
58
|
try {
|
|
59
|
-
await fetch(
|
|
59
|
+
await fetch(apiUrl(`api/tabs/${encodeURIComponent(tabId)}`), { method: 'DELETE' });
|
|
60
60
|
|
|
61
61
|
tabs = tabs.filter(t => t.id !== tabId);
|
|
62
62
|
|
|
@@ -224,7 +224,7 @@ async function createFile() {
|
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
try {
|
|
227
|
-
const response = await fetch('
|
|
227
|
+
const response = await fetch(apiUrl('api/files'), {
|
|
228
228
|
method: 'POST',
|
|
229
229
|
headers: { 'Content-Type': 'application/json' },
|
|
230
230
|
body: JSON.stringify({ path: filePath, content: '' })
|
|
@@ -251,7 +251,7 @@ async function createFile() {
|
|
|
251
251
|
// Spawn worktree builder
|
|
252
252
|
async function spawnBuilder() {
|
|
253
253
|
try {
|
|
254
|
-
const response = await fetch('
|
|
254
|
+
const response = await fetch(apiUrl('api/tabs/builder'), {
|
|
255
255
|
method: 'POST',
|
|
256
256
|
headers: { 'Content-Type': 'application/json' },
|
|
257
257
|
body: JSON.stringify({})
|
|
@@ -283,7 +283,7 @@ async function spawnBuilder() {
|
|
|
283
283
|
// Spawn shell
|
|
284
284
|
async function spawnShell() {
|
|
285
285
|
try {
|
|
286
|
-
const response = await fetch('
|
|
286
|
+
const response = await fetch(apiUrl('api/tabs/shell'), {
|
|
287
287
|
method: 'POST',
|
|
288
288
|
headers: { 'Content-Type': 'application/json' },
|
|
289
289
|
body: JSON.stringify({})
|
|
@@ -325,7 +325,7 @@ async function spawnShell() {
|
|
|
325
325
|
// Create new utility shell (quick action button)
|
|
326
326
|
async function createNewShell() {
|
|
327
327
|
try {
|
|
328
|
-
const response = await fetch('
|
|
328
|
+
const response = await fetch(apiUrl('api/tabs/shell'), { method: 'POST' });
|
|
329
329
|
const data = await response.json();
|
|
330
330
|
if (!data.success && data.error) {
|
|
331
331
|
showToast(data.error || 'Failed to create shell', 'error');
|
|
@@ -347,7 +347,7 @@ async function createNewWorktreeShell() {
|
|
|
347
347
|
if (branch === null) return;
|
|
348
348
|
|
|
349
349
|
try {
|
|
350
|
-
const response = await fetch('
|
|
350
|
+
const response = await fetch(apiUrl('api/tabs/shell'), {
|
|
351
351
|
method: 'POST',
|
|
352
352
|
headers: { 'Content-Type': 'application/json' },
|
|
353
353
|
body: JSON.stringify({ worktree: true, branch: branch || undefined })
|
|
@@ -22,7 +22,7 @@ function stopFilesPolling() {
|
|
|
22
22
|
// Check if files have changed and refresh if needed
|
|
23
23
|
async function checkFilesForChanges() {
|
|
24
24
|
try {
|
|
25
|
-
const response = await fetch(
|
|
25
|
+
const response = await fetch(apiUrl(`api/files/hash?t=${Date.now()}`));
|
|
26
26
|
if (!response.ok) return;
|
|
27
27
|
|
|
28
28
|
const data = await response.json();
|
|
@@ -42,7 +42,7 @@ async function checkFilesForChanges() {
|
|
|
42
42
|
async function loadFilesTree() {
|
|
43
43
|
try {
|
|
44
44
|
// Add cache-busting param to ensure fresh data
|
|
45
|
-
const response = await fetch(
|
|
45
|
+
const response = await fetch(apiUrl(`api/files?t=${Date.now()}`));
|
|
46
46
|
if (!response.ok) {
|
|
47
47
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
48
48
|
}
|
|
@@ -34,7 +34,7 @@ async function openFileFromMessage(filePath, lineNumber) {
|
|
|
34
34
|
// Refresh state from API
|
|
35
35
|
async function refresh() {
|
|
36
36
|
try {
|
|
37
|
-
const response = await fetch('
|
|
37
|
+
const response = await fetch(apiUrl('api/state'));
|
|
38
38
|
if (!response.ok) throw new Error('Failed to fetch state');
|
|
39
39
|
|
|
40
40
|
const newState = await response.json();
|
|
@@ -65,7 +65,7 @@ function stopPolling() {
|
|
|
65
65
|
// Poll for projectlist.md creation when in starter mode
|
|
66
66
|
async function pollForProjectlistCreation() {
|
|
67
67
|
try {
|
|
68
|
-
const response = await fetch('
|
|
68
|
+
const response = await fetch(apiUrl('api/projectlist-exists'));
|
|
69
69
|
if (!response.ok) return;
|
|
70
70
|
|
|
71
71
|
const { exists } = await response.json();
|
|
@@ -420,7 +420,7 @@ async function pollHotReload() {
|
|
|
420
420
|
if (!hotReloadEnabled) return;
|
|
421
421
|
|
|
422
422
|
try {
|
|
423
|
-
const response = await fetch('
|
|
423
|
+
const response = await fetch(apiUrl('api/hot-reload'));
|
|
424
424
|
if (!response.ok) return;
|
|
425
425
|
|
|
426
426
|
const data = await response.json();
|
|
@@ -140,7 +140,7 @@ function parseProjectlist(content) {
|
|
|
140
140
|
// Load projectlist.md from disk
|
|
141
141
|
async function loadProjectlist() {
|
|
142
142
|
try {
|
|
143
|
-
const response = await fetch('
|
|
143
|
+
const response = await fetch(apiUrl('file?path=codev/projectlist.md'));
|
|
144
144
|
|
|
145
145
|
if (!response.ok) {
|
|
146
146
|
if (response.status === 404) {
|
|
@@ -181,7 +181,7 @@ async function pollProjectlist() {
|
|
|
181
181
|
if (activeTabId !== 'dashboard') return;
|
|
182
182
|
|
|
183
183
|
try {
|
|
184
|
-
const response = await fetch('
|
|
184
|
+
const response = await fetch(apiUrl('file?path=codev/projectlist.md'));
|
|
185
185
|
if (!response.ok) return;
|
|
186
186
|
|
|
187
187
|
const text = await response.text();
|
|
@@ -300,7 +300,7 @@ function renderStageCell(project, stage) {
|
|
|
300
300
|
// Open a project file in a new annotation tab
|
|
301
301
|
async function openProjectFile(path) {
|
|
302
302
|
try {
|
|
303
|
-
const response = await fetch('
|
|
303
|
+
const response = await fetch(apiUrl('api/tabs/file'), {
|
|
304
304
|
method: 'POST',
|
|
305
305
|
headers: { 'Content-Type': 'application/json' },
|
|
306
306
|
body: JSON.stringify({ path })
|
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
// Dashboard Utility Functions
|
|
2
2
|
|
|
3
|
+
// Get the base path for API calls (handles tower proxy context)
|
|
4
|
+
// When accessed via tower proxy at /project/<encoded>/, API calls need to go through the proxy
|
|
5
|
+
// When accessed directly at /, API calls go to root
|
|
6
|
+
function getApiBase() {
|
|
7
|
+
const path = window.location.pathname;
|
|
8
|
+
// Check if we're in tower proxy context: /project/<encoded>/
|
|
9
|
+
const match = path.match(/^(\/project\/[^/]+\/)/);
|
|
10
|
+
if (match) {
|
|
11
|
+
return match[1]; // Returns /project/<encoded>/
|
|
12
|
+
}
|
|
13
|
+
return '/'; // Direct access
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Build API URL that works both directly and through tower proxy
|
|
17
|
+
function apiUrl(endpoint) {
|
|
18
|
+
const base = getApiBase();
|
|
19
|
+
// Remove leading slash from endpoint if present
|
|
20
|
+
const cleanEndpoint = endpoint.startsWith('/') ? endpoint.slice(1) : endpoint;
|
|
21
|
+
return base + cleanEndpoint;
|
|
22
|
+
}
|
|
23
|
+
|
|
3
24
|
// Escape HTML special characters to prevent XSS
|
|
4
25
|
function escapeHtml(text) {
|
|
5
26
|
return String(text)
|
|
@@ -87,7 +108,7 @@ async function openFileTab(filePath, options = {}) {
|
|
|
87
108
|
}
|
|
88
109
|
|
|
89
110
|
// Create new tab
|
|
90
|
-
const response = await fetch('
|
|
111
|
+
const response = await fetch(apiUrl('api/tabs/file'), {
|
|
91
112
|
method: 'POST',
|
|
92
113
|
headers: { 'Content-Type': 'application/json' },
|
|
93
114
|
body: JSON.stringify({ path: filePath })
|