thrust-cli 1.0.16 → 1.0.17
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/build/AuthPage.jsx +0 -0
- package/build/asset-manifest.json +13 -0
- package/build/favicon.ico +0 -0
- package/build/index.html +1 -0
- package/build/logo192.png +0 -0
- package/build/logo512.png +0 -0
- package/build/manifest.json +25 -0
- package/build/robots.txt +3 -0
- package/build/static/css/main.ebf0e7c6.css +4 -0
- package/build/static/css/main.ebf0e7c6.css.map +1 -0
- package/build/static/js/main.80b95b75.js +3 -0
- package/build/static/js/main.80b95b75.js.LICENSE.txt +56 -0
- package/build/static/js/main.80b95b75.js.map +1 -0
- package/build/thrust_black.jpg +0 -0
- package/build/thrust_equal_black.png +0 -0
- package/build/thrust_equal_white.png +0 -0
- package/build/thrust_tracing_black.png +0 -0
- package/build/thrust_tracing_white.png +0 -0
- package/build/thrust_white.jpg +0 -0
- package/package.json +1 -1
- package/utils/daemon.js +41 -13
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
package/utils/daemon.js
CHANGED
|
@@ -21,8 +21,8 @@ const API_URL = GATEWAY_URL.replace('ws://', 'http://').replace('wss://', 'https
|
|
|
21
21
|
const AUTH_PROXY_URL = "https://everydaycats-thrust-auth-server.hf.space";
|
|
22
22
|
|
|
23
23
|
// --- DEBOUNCE & POLLING TIMERS ---
|
|
24
|
-
const INACTIVITY_DELAY_MS = 15 * 1000;
|
|
25
|
-
const MCP_POLL_INTERVAL_MS = 18 * 1000;
|
|
24
|
+
const INACTIVITY_DELAY_MS = 15 * 1000;
|
|
25
|
+
const MCP_POLL_INTERVAL_MS = 18 * 1000;
|
|
26
26
|
|
|
27
27
|
let currentWatcher = null;
|
|
28
28
|
let inactivityTimer = null;
|
|
@@ -127,7 +127,7 @@ export async function startDaemon(preferredPort) {
|
|
|
127
127
|
app.use(cors(corsOptionsDelegate));
|
|
128
128
|
app.use(express.json());
|
|
129
129
|
|
|
130
|
-
const frontendPath = path.join(__dirname, '..', '
|
|
130
|
+
const frontendPath = path.join(__dirname, '..', 'build');
|
|
131
131
|
|
|
132
132
|
// ==========================================
|
|
133
133
|
// MCP SERVER ENDPOINTS (FEED-IN PUSH)
|
|
@@ -138,7 +138,6 @@ export async function startDaemon(preferredPort) {
|
|
|
138
138
|
const token = config.auth?.token;
|
|
139
139
|
const projectId = config.activeLeadId;
|
|
140
140
|
|
|
141
|
-
// Extract optional parameters, default to true
|
|
142
141
|
const prd = req.query.prd || 'true';
|
|
143
142
|
const thrust = req.query.thrust || 'true';
|
|
144
143
|
const timeline = req.query.timeline || 'true';
|
|
@@ -148,7 +147,6 @@ export async function startDaemon(preferredPort) {
|
|
|
148
147
|
}
|
|
149
148
|
|
|
150
149
|
try {
|
|
151
|
-
// Forward parameters to new combined gateway endpoint
|
|
152
150
|
const response = await fetch(`${API_URL}/api/projects/${projectId}/mcp-context?prd=${prd}&thrust=${thrust}&timeline=${timeline}`, {
|
|
153
151
|
headers: { 'Authorization': `Bearer ${token}` }
|
|
154
152
|
});
|
|
@@ -200,7 +198,7 @@ export async function startDaemon(preferredPort) {
|
|
|
200
198
|
saveConfig(config);
|
|
201
199
|
|
|
202
200
|
pollExternalMCPServers();
|
|
203
|
-
fetchInitialMCPContext({ name, url, type: 'http' });
|
|
201
|
+
fetchInitialMCPContext({ name, url, type: 'http' });
|
|
204
202
|
res.json({ success: true });
|
|
205
203
|
});
|
|
206
204
|
|
|
@@ -306,7 +304,8 @@ export async function startDaemon(preferredPort) {
|
|
|
306
304
|
}
|
|
307
305
|
});
|
|
308
306
|
|
|
309
|
-
|
|
307
|
+
|
|
308
|
+
app.post('/api/tasks/complete', async (req, res) => {
|
|
310
309
|
const { taskId, taskTitle } = req.body;
|
|
311
310
|
const config = getConfig();
|
|
312
311
|
const token = config.auth?.token;
|
|
@@ -327,6 +326,10 @@ export async function startDaemon(preferredPort) {
|
|
|
327
326
|
const data = await response.json();
|
|
328
327
|
if (!response.ok) throw new Error(data.error);
|
|
329
328
|
|
|
329
|
+
// 👉 NEW: Force the buffer to have content so syncContext doesn't abort!
|
|
330
|
+
// This tells the AI exactly what you just checked off manually.
|
|
331
|
+
fileActivityBuffer += `\n[${new Date().toLocaleTimeString()}] [USER ACTION] Manually marked task as complete: "${taskTitle}"\n`;
|
|
332
|
+
|
|
330
333
|
if (config.leads[projectId]?.path) {
|
|
331
334
|
if (inactivityTimer) clearTimeout(inactivityTimer);
|
|
332
335
|
syncContext(config.leads[projectId].path);
|
|
@@ -535,13 +538,11 @@ async function startWatching(projectPath) {
|
|
|
535
538
|
|
|
536
539
|
fileActivityBuffer = "";
|
|
537
540
|
|
|
538
|
-
// Fetch initial MCP states immediately upon watching a project
|
|
539
541
|
const config = getConfig();
|
|
540
542
|
if (config.mcpServers && config.mcpServers.length > 0) {
|
|
541
543
|
config.mcpServers.forEach(server => fetchInitialMCPContext(server));
|
|
542
544
|
}
|
|
543
545
|
|
|
544
|
-
// Start the active polling loop for external services
|
|
545
546
|
if (mcpPollTimer) clearInterval(mcpPollTimer);
|
|
546
547
|
mcpPollTimer = setInterval(pollExternalMCPServers, MCP_POLL_INTERVAL_MS);
|
|
547
548
|
|
|
@@ -549,11 +550,37 @@ async function startWatching(projectPath) {
|
|
|
549
550
|
ignored:[
|
|
550
551
|
/(^|[\/\\])\../,
|
|
551
552
|
'**/node_modules/**', '**/dist/**', '**/build/**',
|
|
552
|
-
// Ignore noisy Unity cache & build folders
|
|
553
553
|
'**/Library/**', '**/Temp/**', '**/Logs/**', '**/obj/**', '**/ProjectSettings/**'
|
|
554
554
|
],
|
|
555
555
|
persistent: true,
|
|
556
|
-
ignoreInitial: true
|
|
556
|
+
ignoreInitial: true,
|
|
557
|
+
ignorePermissionErrors: true // NEW: Ignores restricted Android/Termux subfolders safely
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
// NEW: FATAL ERROR HANDLER
|
|
561
|
+
// Catches EACCES constraints before Node.js crashes and forces a UI unlink
|
|
562
|
+
currentWatcher.on('error', async (error) => {
|
|
563
|
+
const isPermissionError = error.code === 'EACCES' || error.code === 'EPERM';
|
|
564
|
+
const msg = isPermissionError
|
|
565
|
+
? `Permission Denied: Cannot watch folder. Access Denied by OS.`
|
|
566
|
+
: `Watcher Error: ${error.message}`;
|
|
567
|
+
|
|
568
|
+
broadcastLocalLog('error', msg);
|
|
569
|
+
|
|
570
|
+
// Force unlink the bad folder
|
|
571
|
+
const cfg = getConfig();
|
|
572
|
+
cfg.activeLeadId = null;
|
|
573
|
+
saveConfig(cfg);
|
|
574
|
+
|
|
575
|
+
if (inactivityTimer) { clearTimeout(inactivityTimer); inactivityTimer = null; }
|
|
576
|
+
if (mcpPollTimer) { clearInterval(mcpPollTimer); mcpPollTimer = null; }
|
|
577
|
+
if (currentWatcher) {
|
|
578
|
+
await currentWatcher.close().catch(() => {});
|
|
579
|
+
currentWatcher = null;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// Signal the frontend to drop the user back to the setup wizard
|
|
583
|
+
broadcastLocalLog('force_unlink', 'Folder access denied. Project unlinked safely.');
|
|
557
584
|
});
|
|
558
585
|
|
|
559
586
|
currentWatcher.on('all', (event, filePath) => {
|
|
@@ -563,7 +590,9 @@ async function startWatching(projectPath) {
|
|
|
563
590
|
|
|
564
591
|
triggerDebouncedSync();
|
|
565
592
|
});
|
|
566
|
-
} catch (err) {
|
|
593
|
+
} catch (err) {
|
|
594
|
+
broadcastLocalLog('error', `Failed to initialize watcher: ${err.message}`);
|
|
595
|
+
}
|
|
567
596
|
}
|
|
568
597
|
|
|
569
598
|
function connectWebSocket() {
|
|
@@ -589,7 +618,6 @@ function connectWebSocket() {
|
|
|
589
618
|
try {
|
|
590
619
|
const msg = JSON.parse(data.toString());
|
|
591
620
|
|
|
592
|
-
// NEW: Handle dynamic MCP Queries pushed from the AI Director
|
|
593
621
|
if (msg.type === 'mcp_query' && msg.payload) {
|
|
594
622
|
const { serverName, toolName, targetArg } = msg.payload;
|
|
595
623
|
const targetServer = getConfig().mcpServers?.find(s => s.name.toLowerCase() === serverName.toLowerCase());
|