@siftd/connect-agent 0.2.3 → 0.2.5

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/dist/heartbeat.js CHANGED
@@ -10,7 +10,7 @@ import { hostname } from 'os';
10
10
  import { createHash } from 'crypto';
11
11
  import { getServerUrl, getAgentToken, getUserId, isCloudMode } from './config.js';
12
12
  const HEARTBEAT_INTERVAL = 10000; // 10 seconds
13
- const VERSION = '0.2.3'; // Should match package.json
13
+ const VERSION = '0.2.5'; // Should match package.json
14
14
  const state = {
15
15
  intervalId: null,
16
16
  runnerId: null,
@@ -690,12 +690,24 @@ Be specific about what you want done.`,
690
690
  const maxRetries = 2;
691
691
  const id = `worker_${Date.now()}_${++this.jobCounter}`;
692
692
  const cwd = workingDir || this.workspaceDir;
693
- // Build prompt for worker
693
+ // Build prompt for worker with checkpoint instructions
694
694
  let prompt = task;
695
695
  if (context) {
696
696
  prompt = `Context: ${context}\n\nTask: ${task}`;
697
697
  }
698
- prompt += '\n\nKeep your response concise and focused on results.';
698
+ // Add checkpoint and logging instructions to prevent data loss
699
+ const logFile = `/tmp/worker-${id}-log.txt`;
700
+ prompt += `
701
+
702
+ IMPORTANT - Progress & Logging:
703
+ - Output findings as you go, don't wait until the end
704
+ - Print discoveries, file paths, and insights immediately as you find them
705
+ - Report on each file/step before moving to the next
706
+
707
+ REQUIRED - Log Export:
708
+ At the END of your work, create a final log file at: ${logFile}
709
+ Include: job_id=${id}, timestamp, summary of work done, files modified, key findings.
710
+ This ensures nothing is lost even if your output gets truncated.`;
699
711
  console.log(`[ORCHESTRATOR] Delegating to worker ${id}: ${task.slice(0, 80)}...`);
700
712
  return new Promise((resolve) => {
701
713
  const job = {
@@ -722,10 +734,20 @@ Be specific about what you want done.`,
722
734
  if (job.status === 'running') {
723
735
  job.status = 'timeout';
724
736
  job.endTime = Date.now();
725
- child.kill('SIGTERM');
737
+ // Send SIGINT first to allow graceful shutdown and output flush
738
+ child.kill('SIGINT');
739
+ // Give 5 seconds for graceful shutdown before SIGTERM
740
+ setTimeout(() => {
741
+ if (!child.killed) {
742
+ child.kill('SIGTERM');
743
+ }
744
+ }, 5000);
745
+ const partialOutput = job.output.trim();
726
746
  resolve({
727
747
  success: false,
728
- output: `Worker timed out after 5 minutes.\nPartial output:\n${job.output.slice(-1000)}`
748
+ output: partialOutput
749
+ ? `Worker timed out after 5 minutes. Partial findings:\n${partialOutput.slice(-2000)}`
750
+ : 'Worker timed out after 5 minutes with no output. The task may be too complex - try breaking it into smaller steps.'
729
751
  });
730
752
  }
731
753
  }, 5 * 60 * 1000);
@@ -70,8 +70,21 @@ export class WorkerManager {
70
70
  this.saveJob(job);
71
71
  // Spawn Claude CLI process
72
72
  try {
73
+ // Add checkpoint and logging instructions to prevent data loss
74
+ const logFile = `/tmp/worker-${jobId}-log.txt`;
75
+ const enhancedTask = `${task}
76
+
77
+ IMPORTANT - Progress & Logging:
78
+ - Output findings as you go, don't wait until the end
79
+ - Print discoveries and insights immediately as you find them
80
+ - Report on each file/step before moving to the next
81
+
82
+ REQUIRED - Log Export:
83
+ At the END of your work, create a final log file at: ${logFile}
84
+ Include: job_id=${jobId}, timestamp, summary of work done, files modified, key findings.
85
+ This ensures nothing is lost even if your output gets truncated.`;
73
86
  // Escape single quotes in task for shell safety
74
- const escapedTask = task.replace(/'/g, "'\\''");
87
+ const escapedTask = enhancedTask.replace(/'/g, "'\\''");
75
88
  // Spawn using bash -l -c to ensure proper PATH resolution (NVM, etc.)
76
89
  // This is more reliable than shell: true which has quote escaping issues
77
90
  const child = spawn('bash', ['-l', '-c', `claude -p '${escapedTask}' --output-format text --dangerously-skip-permissions`], {
@@ -101,11 +114,18 @@ export class WorkerManager {
101
114
  // Set up timeout
102
115
  const timeoutHandle = setTimeout(() => {
103
116
  if (child.pid && !child.killed) {
104
- child.kill('SIGTERM');
117
+ // Send SIGINT first to allow graceful shutdown and output flush
118
+ child.kill('SIGINT');
119
+ // Give 5 seconds for graceful shutdown before SIGTERM
120
+ setTimeout(() => {
121
+ if (!child.killed) {
122
+ child.kill('SIGTERM');
123
+ }
124
+ }, 5000);
105
125
  job.status = 'timeout';
106
126
  job.error = `Job timed out after ${effectiveTimeout}ms`;
107
127
  job.completed = new Date().toISOString();
108
- job.result = stdout || stderr;
128
+ job.result = stdout.trim() || stderr.trim() || 'No output captured before timeout';
109
129
  this.saveJob(job);
110
130
  this.activeWorkers.delete(jobId);
111
131
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@siftd/connect-agent",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "Master orchestrator agent - control Claude Code remotely via web",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",