thrust-cli 1.0.13 → 1.0.14

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/utils/daemon.js +72 -58
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thrust-cli",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "The local agent for Thrust AI Director",
5
5
  "type": "module",
6
6
  "homepage": "https://thrust.web.app",
package/utils/daemon.js CHANGED
@@ -20,7 +20,7 @@ const API_URL = GATEWAY_URL.replace('ws://', 'http://').replace('wss://', 'https
20
20
  const AUTH_PROXY_URL = "https://everydaycats-thrust-auth-server.hf.space";
21
21
 
22
22
  // --- DEBOUNCE & POLLING TIMERS ---
23
- const INACTIVITY_DELAY_MS = 15 * 1000; // Wait for 15 seconds of silence across ALL inputs before sending
23
+ const INACTIVITY_DELAY_MS = 15 * 1000; // Wait for 15 seconds of silence before syncing
24
24
  const MCP_POLL_INTERVAL_MS = 18 * 1000; // Poll external tools every 18 seconds
25
25
 
26
26
  let currentWatcher = null;
@@ -486,7 +486,6 @@ async function pollExternalMCPServers() {
486
486
  }
487
487
 
488
488
  if (hasNewData) {
489
- // Add to buffer and reset the 15-second countdown
490
489
  triggerDebouncedSync();
491
490
  }
492
491
  }
@@ -504,7 +503,12 @@ async function startWatching(projectPath) {
504
503
  mcpPollTimer = setInterval(pollExternalMCPServers, MCP_POLL_INTERVAL_MS);
505
504
 
506
505
  currentWatcher = chokidar.watch(projectPath, {
507
- ignored: [/(^|[\/\\])\../, '**/node_modules/**', '**/dist/**', '**/build/**'],
506
+ ignored: [
507
+ /(^|[\/\\])\../,
508
+ '**/node_modules/**', '**/dist/**', '**/build/**',
509
+ // Ignore noisy Unity cache & build folders to prevent infinite debounce loops
510
+ '**/Library/**', '**/Temp/**', '**/Logs/**', '**/obj/**', '**/ProjectSettings/**'
511
+ ],
508
512
  persistent: true,
509
513
  ignoreInitial: true
510
514
  });
@@ -514,7 +518,6 @@ async function startWatching(projectPath) {
514
518
  fileActivityBuffer += `[${new Date().toLocaleTimeString()}] ${event.toUpperCase()}: ${relativePath}\n`;
515
519
  broadcastLocalLog('watch', `[${event.toUpperCase()}] ${relativePath}`);
516
520
 
517
- // Reset the 15-second countdown
518
521
  triggerDebouncedSync();
519
522
  });
520
523
  } catch (err) {}
@@ -561,66 +564,77 @@ function connectWebSocket() {
561
564
  }
562
565
 
563
566
  async function syncContext(projectPath) {
564
- if (!globalWs || globalWs.readyState !== WebSocket.OPEN) return;
567
+ if (!globalWs || globalWs.readyState !== WebSocket.OPEN) {
568
+ broadcastLocalLog('error', `⚠️ Cannot sync: Not connected to Cloud.`);
569
+ return;
570
+ }
565
571
 
566
- const git = simpleGit(projectPath);
567
- const isRepo = await git.checkIsRepo().catch(() => false);
568
- if (!isRepo) return;
572
+ broadcastLocalLog('system', `⏳ 15s silence reached. Preparing sync...`);
573
+
574
+ let diff = "";
575
+ let newFilesData = "";
576
+ let imagesData = [];
569
577
 
570
578
  try {
571
- const status = await git.status();
572
- const diff = await git.diff();
573
-
574
- if (!fileActivityBuffer.trim() && !diff) return;
575
-
576
- let newFilesData = "";
577
- let imagesData = [];
578
-
579
- const binaryExts =[
580
- '.png', '.jpg', '.jpeg', '.webp', '.gif', '.svg', '.ico',
581
- '.pdf', '.zip', '.tar', '.gz', '.mp4', '.mp3', '.wav',
582
- '.exe', '.dll', '.so', '.dylib',
583
- '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.bin'
584
- ];
585
-
586
- for (const file of status.not_added) {
587
- const ext = path.extname(file).toLowerCase();
588
- const fullPath = path.join(projectPath, file);
589
- if (!fs.existsSync(fullPath)) continue;
590
-
591
- const stat = fs.statSync(fullPath);
592
- if (stat.isDirectory() || stat.size > 5 * 1024 * 1024) continue;
593
-
594
- const fileData = fs.readFileSync(fullPath);
595
- const isBinary = binaryExts.includes(ext) || isBinaryData(fileData);
596
-
597
- if (isBinary) {
598
- const base64 = fileData.toString('base64');
599
- const mime = ['.png','.jpg','.jpeg','.webp','.gif'].includes(ext)
600
- ? `image/${ext.replace('.','')}`
601
- : 'application/octet-stream';
602
- imagesData.push(`data:${mime};base64,${base64}`);
603
- } else {
604
- const content = fileData.toString('utf8');
605
- newFilesData += `\n--- NEW FILE: ${file} (Scraped at ${new Date().toLocaleTimeString()}) ---\n${content.substring(0, 10000)}\n`;
579
+ const git = simpleGit(projectPath);
580
+ const isRepo = await git.checkIsRepo().catch(() => false);
581
+
582
+ if (isRepo) {
583
+ const status = await git.status();
584
+ diff = await git.diff();
585
+
586
+ const binaryExts =[
587
+ '.png', '.jpg', '.jpeg', '.webp', '.gif', '.svg', '.ico',
588
+ '.pdf', '.zip', '.tar', '.gz', '.mp4', '.mp3', '.wav',
589
+ '.exe', '.dll', '.so', '.dylib',
590
+ '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.bin'
591
+ ];
592
+
593
+ for (const file of status.not_added) {
594
+ const ext = path.extname(file).toLowerCase();
595
+ const fullPath = path.join(projectPath, file);
596
+ if (!fs.existsSync(fullPath)) continue;
597
+
598
+ const stat = fs.statSync(fullPath);
599
+ if (stat.isDirectory() || stat.size > 5 * 1024 * 1024) continue;
600
+
601
+ const fileData = fs.readFileSync(fullPath);
602
+ const isBinary = binaryExts.includes(ext) || isBinaryData(fileData);
603
+
604
+ if (isBinary) {
605
+ const base64 = fileData.toString('base64');
606
+ const mime = ['.png','.jpg','.jpeg','.webp','.gif'].includes(ext)
607
+ ? `image/${ext.replace('.','')}`
608
+ : 'application/octet-stream';
609
+ imagesData.push(`data:${mime};base64,${base64}`);
610
+ } else {
611
+ const content = fileData.toString('utf8');
612
+ newFilesData += `\n--- NEW FILE: ${file} (Scraped at ${new Date().toLocaleTimeString()}) ---\n${content.substring(0, 10000)}\n`;
613
+ }
606
614
  }
615
+ } else {
616
+ broadcastLocalLog('system', `ℹ️ Folder is not a Git repo. Syncing MCP/Activity logs only.`);
607
617
  }
618
+ } catch (e) {
619
+ console.error("Git/Sync processing error:", e);
620
+ }
608
621
 
609
- globalWs.send(JSON.stringify({
610
- type: "context_sync",
611
- projectId: getActiveProject().id,
612
- data: {
613
- buffer: fileActivityBuffer,
614
- diffs: diff,
615
- new_files: newFilesData,
616
- images: imagesData
617
- }
618
- }));
622
+ if (!fileActivityBuffer.trim() && !diff && !newFilesData) {
623
+ broadcastLocalLog('system', `ℹ️ Buffer empty. Nothing to sync.`);
624
+ return;
625
+ }
619
626
 
620
- broadcastLocalLog('sync', `✅ Context Batch synced to AI.`);
621
- fileActivityBuffer = "";
627
+ globalWs.send(JSON.stringify({
628
+ type: "context_sync",
629
+ projectId: getActiveProject().id,
630
+ data: {
631
+ buffer: fileActivityBuffer,
632
+ diffs: diff,
633
+ new_files: newFilesData,
634
+ images: imagesData
635
+ }
636
+ }));
622
637
 
623
- } catch (e) {
624
- console.error("Sync error:", e);
625
- }
638
+ broadcastLocalLog('sync', `✅ Context Batch synced to AI.`);
639
+ fileActivityBuffer = "";
626
640
  }