@siftd/connect-agent 0.2.23 → 0.2.25
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 +18 -1
- package/dist/orchestrator.js +20 -0
- package/dist/tools/worker.d.ts +10 -0
- package/dist/tools/worker.js +12 -0
- package/dist/workers/manager.d.ts +22 -1
- package/dist/workers/manager.js +64 -0
- package/dist/workers/types.d.ts +12 -0
- package/package.json +1 -1
package/dist/heartbeat.js
CHANGED
|
@@ -8,9 +8,26 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { hostname } from 'os';
|
|
10
10
|
import { createHash } from 'crypto';
|
|
11
|
+
import { readFileSync } from 'fs';
|
|
12
|
+
import { fileURLToPath } from 'url';
|
|
13
|
+
import { dirname, join } from 'path';
|
|
11
14
|
import { getServerUrl, getAgentToken, getUserId, isCloudMode } from './config.js';
|
|
12
15
|
const HEARTBEAT_INTERVAL = 10000; // 10 seconds
|
|
13
|
-
|
|
16
|
+
// Read version from package.json dynamically
|
|
17
|
+
function getVersion() {
|
|
18
|
+
try {
|
|
19
|
+
// Try to find package.json relative to this file
|
|
20
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
21
|
+
const __dirname = dirname(__filename);
|
|
22
|
+
const pkgPath = join(__dirname, '..', 'package.json');
|
|
23
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
24
|
+
return pkg.version || '0.0.0';
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return '0.0.0';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const VERSION = getVersion();
|
|
14
31
|
const state = {
|
|
15
32
|
intervalId: null,
|
|
16
33
|
runnerId: null,
|
package/dist/orchestrator.js
CHANGED
|
@@ -174,12 +174,19 @@ export class MasterOrchestrator {
|
|
|
174
174
|
*/
|
|
175
175
|
setGalleryCallback(callback) {
|
|
176
176
|
this.galleryCallback = callback;
|
|
177
|
+
// Also set on workerTools for spawn_worker jobs
|
|
178
|
+
this.workerTools.setGalleryCallback(callback ? (workers) => {
|
|
179
|
+
// Merge with delegate_to_worker jobs and broadcast
|
|
180
|
+
this.broadcastGalleryUpdate();
|
|
181
|
+
} : null);
|
|
177
182
|
}
|
|
178
183
|
/**
|
|
179
184
|
* Get gallery workers with their assets
|
|
180
185
|
*/
|
|
181
186
|
getGalleryWorkers() {
|
|
182
187
|
const workers = [];
|
|
188
|
+
const seenIds = new Set();
|
|
189
|
+
// Include jobs from delegateToWorker (this.jobs)
|
|
183
190
|
for (const [id, job] of this.jobs) {
|
|
184
191
|
// Only include jobs with assets or that are running
|
|
185
192
|
if (job.assets || job.status === 'running') {
|
|
@@ -189,8 +196,21 @@ export class MasterOrchestrator {
|
|
|
189
196
|
status: job.status === 'timeout' ? 'failed' : job.status,
|
|
190
197
|
assets: job.assets || []
|
|
191
198
|
});
|
|
199
|
+
seenIds.add(id);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Include jobs from workerTools (spawn_worker)
|
|
203
|
+
try {
|
|
204
|
+
const spawnedWorkers = this.workerTools.getGalleryWorkers();
|
|
205
|
+
for (const worker of spawnedWorkers) {
|
|
206
|
+
if (!seenIds.has(worker.id)) {
|
|
207
|
+
workers.push(worker);
|
|
208
|
+
}
|
|
192
209
|
}
|
|
193
210
|
}
|
|
211
|
+
catch {
|
|
212
|
+
// WorkerTools not available
|
|
213
|
+
}
|
|
194
214
|
return workers;
|
|
195
215
|
}
|
|
196
216
|
/**
|
package/dist/tools/worker.d.ts
CHANGED
|
@@ -2,10 +2,20 @@
|
|
|
2
2
|
* Worker Tools
|
|
3
3
|
* Tools for spawning and managing Claude Code workers
|
|
4
4
|
*/
|
|
5
|
+
import { GalleryCallback, GalleryWorker } from '../workers/manager.js';
|
|
5
6
|
import type { ToolResult } from './bash.js';
|
|
7
|
+
export { GalleryCallback, GalleryWorker };
|
|
6
8
|
export declare class WorkerTools {
|
|
7
9
|
private manager;
|
|
8
10
|
constructor(workspaceDir: string);
|
|
11
|
+
/**
|
|
12
|
+
* Set callback for gallery updates (worker assets for UI)
|
|
13
|
+
*/
|
|
14
|
+
setGalleryCallback(callback: GalleryCallback | null): void;
|
|
15
|
+
/**
|
|
16
|
+
* Get gallery workers with assets
|
|
17
|
+
*/
|
|
18
|
+
getGalleryWorkers(): GalleryWorker[];
|
|
9
19
|
/**
|
|
10
20
|
* Spawn a new Claude Code worker
|
|
11
21
|
*/
|
package/dist/tools/worker.js
CHANGED
|
@@ -8,6 +8,18 @@ export class WorkerTools {
|
|
|
8
8
|
constructor(workspaceDir) {
|
|
9
9
|
this.manager = new WorkerManager(workspaceDir);
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Set callback for gallery updates (worker assets for UI)
|
|
13
|
+
*/
|
|
14
|
+
setGalleryCallback(callback) {
|
|
15
|
+
this.manager.setGalleryCallback(callback);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get gallery workers with assets
|
|
19
|
+
*/
|
|
20
|
+
getGalleryWorkers() {
|
|
21
|
+
return this.manager.getGalleryWorkers();
|
|
22
|
+
}
|
|
11
23
|
/**
|
|
12
24
|
* Spawn a new Claude Code worker
|
|
13
25
|
*/
|
|
@@ -2,11 +2,32 @@
|
|
|
2
2
|
* Claude Code Worker Manager
|
|
3
3
|
* Spawns and manages Claude Code CLI instances for parallel task execution
|
|
4
4
|
*/
|
|
5
|
-
import { WorkerJob, SpawnOptions, WorkerConfig } from './types.js';
|
|
5
|
+
import { WorkerJob, SpawnOptions, WorkerConfig, WorkerAsset } from './types.js';
|
|
6
|
+
export interface GalleryWorker {
|
|
7
|
+
id: string;
|
|
8
|
+
task: string;
|
|
9
|
+
status: 'running' | 'completed' | 'failed';
|
|
10
|
+
assets: WorkerAsset[];
|
|
11
|
+
}
|
|
12
|
+
export type GalleryCallback = (workers: GalleryWorker[]) => void;
|
|
6
13
|
export declare class WorkerManager {
|
|
7
14
|
private config;
|
|
8
15
|
private activeWorkers;
|
|
16
|
+
private fileSnapshots;
|
|
17
|
+
private galleryCallback;
|
|
9
18
|
constructor(workspaceDir: string, configOverrides?: Partial<WorkerConfig>);
|
|
19
|
+
/**
|
|
20
|
+
* Set callback for gallery updates (worker assets for UI)
|
|
21
|
+
*/
|
|
22
|
+
setGalleryCallback(callback: GalleryCallback | null): void;
|
|
23
|
+
/**
|
|
24
|
+
* Get gallery workers with assets for UI
|
|
25
|
+
*/
|
|
26
|
+
getGalleryWorkers(): GalleryWorker[];
|
|
27
|
+
/**
|
|
28
|
+
* Broadcast gallery update
|
|
29
|
+
*/
|
|
30
|
+
private broadcastGalleryUpdate;
|
|
10
31
|
/**
|
|
11
32
|
* Generate a unique job ID
|
|
12
33
|
*/
|
package/dist/workers/manager.js
CHANGED
|
@@ -6,9 +6,12 @@ import { spawn } from 'child_process';
|
|
|
6
6
|
import * as fs from 'fs';
|
|
7
7
|
import * as path from 'path';
|
|
8
8
|
import { DEFAULT_WORKER_CONFIG } from './types.js';
|
|
9
|
+
import { takeSnapshot, compareSnapshots } from '../core/file-tracker.js';
|
|
9
10
|
export class WorkerManager {
|
|
10
11
|
config;
|
|
11
12
|
activeWorkers = new Map();
|
|
13
|
+
fileSnapshots = new Map(); // Before-snapshots per job
|
|
14
|
+
galleryCallback = null;
|
|
12
15
|
constructor(workspaceDir, configOverrides) {
|
|
13
16
|
this.config = {
|
|
14
17
|
...DEFAULT_WORKER_CONFIG,
|
|
@@ -20,6 +23,39 @@ export class WorkerManager {
|
|
|
20
23
|
fs.mkdirSync(this.config.jobsDir, { recursive: true });
|
|
21
24
|
}
|
|
22
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Set callback for gallery updates (worker assets for UI)
|
|
28
|
+
*/
|
|
29
|
+
setGalleryCallback(callback) {
|
|
30
|
+
this.galleryCallback = callback;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get gallery workers with assets for UI
|
|
34
|
+
*/
|
|
35
|
+
getGalleryWorkers() {
|
|
36
|
+
const jobs = this.list();
|
|
37
|
+
return jobs
|
|
38
|
+
.filter(job => job.assets && job.assets.length > 0 || job.status === 'running')
|
|
39
|
+
.slice(0, 20) // Limit for UI
|
|
40
|
+
.map(job => ({
|
|
41
|
+
id: job.id,
|
|
42
|
+
task: job.task.slice(0, 60),
|
|
43
|
+
status: (job.status === 'timeout' || job.status === 'cancelled') ? 'failed' :
|
|
44
|
+
(job.status === 'pending' ? 'running' : job.status),
|
|
45
|
+
assets: job.assets || []
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Broadcast gallery update
|
|
50
|
+
*/
|
|
51
|
+
broadcastGalleryUpdate() {
|
|
52
|
+
if (!this.galleryCallback)
|
|
53
|
+
return;
|
|
54
|
+
const workers = this.getGalleryWorkers();
|
|
55
|
+
if (workers.length > 0) {
|
|
56
|
+
this.galleryCallback(workers);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
23
59
|
/**
|
|
24
60
|
* Generate a unique job ID
|
|
25
61
|
*/
|
|
@@ -58,6 +94,15 @@ export class WorkerManager {
|
|
|
58
94
|
// Validate timeout
|
|
59
95
|
const effectiveTimeout = Math.min(timeout, this.config.maxTimeout);
|
|
60
96
|
const jobId = this.generateJobId();
|
|
97
|
+
// Take snapshot before spawning (for asset tracking)
|
|
98
|
+
try {
|
|
99
|
+
const beforeSnapshot = takeSnapshot(workspace);
|
|
100
|
+
this.fileSnapshots.set(jobId, beforeSnapshot);
|
|
101
|
+
console.log(`[WORKER] Snapshot for ${jobId}: ${beforeSnapshot.files.size} files`);
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
console.log(`[WORKER] Could not take snapshot for ${jobId}: ${err}`);
|
|
105
|
+
}
|
|
61
106
|
const job = {
|
|
62
107
|
id: jobId,
|
|
63
108
|
task,
|
|
@@ -155,6 +200,25 @@ This ensures nothing is lost even if your output gets truncated.`;
|
|
|
155
200
|
if (stderr && code !== 0) {
|
|
156
201
|
currentJob.error = stderr.trim();
|
|
157
202
|
}
|
|
203
|
+
// Track file changes (for gallery)
|
|
204
|
+
const beforeSnapshot = this.fileSnapshots.get(jobId);
|
|
205
|
+
if (beforeSnapshot) {
|
|
206
|
+
try {
|
|
207
|
+
const afterSnapshot = takeSnapshot(currentJob.workspace);
|
|
208
|
+
const assets = compareSnapshots(beforeSnapshot, afterSnapshot);
|
|
209
|
+
currentJob.assets = assets;
|
|
210
|
+
const newCount = assets.filter(a => a.type === 'new').length;
|
|
211
|
+
const modCount = assets.filter(a => a.type === 'modified').length;
|
|
212
|
+
console.log(`[WORKER] ${jobId} assets: ${assets.length} files (${newCount} new, ${modCount} modified)`);
|
|
213
|
+
// Clean up snapshot
|
|
214
|
+
this.fileSnapshots.delete(jobId);
|
|
215
|
+
// Broadcast gallery update
|
|
216
|
+
this.broadcastGalleryUpdate();
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
console.log(`[WORKER] Could not track assets for ${jobId}: ${err}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
158
222
|
this.saveJob(currentJob);
|
|
159
223
|
}
|
|
160
224
|
});
|
package/dist/workers/types.d.ts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Worker System Types
|
|
3
3
|
*/
|
|
4
|
+
export interface WorkerAsset {
|
|
5
|
+
path: string;
|
|
6
|
+
name: string;
|
|
7
|
+
type: 'new' | 'modified' | 'unchanged';
|
|
8
|
+
fileType: 'code' | 'image' | 'pdf' | 'text' | 'other';
|
|
9
|
+
preview?: string;
|
|
10
|
+
diff?: Array<{
|
|
11
|
+
type: 'context' | 'add' | 'remove';
|
|
12
|
+
content: string;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
4
15
|
export interface WorkerJob {
|
|
5
16
|
id: string;
|
|
6
17
|
task: string;
|
|
@@ -15,6 +26,7 @@ export interface WorkerJob {
|
|
|
15
26
|
pid?: number;
|
|
16
27
|
timeout: number;
|
|
17
28
|
exitCode?: number;
|
|
29
|
+
assets?: WorkerAsset[];
|
|
18
30
|
}
|
|
19
31
|
export interface SpawnOptions {
|
|
20
32
|
workspace?: string;
|