@siftd/connect-agent 0.2.25 → 0.2.27
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/orchestrator.d.ts +11 -1
- package/dist/orchestrator.js +61 -23
- package/dist/workers/manager.d.ts +0 -1
- package/dist/workers/manager.js +49 -29
- package/package.json +1 -1
package/dist/orchestrator.d.ts
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
* It does NOT do the work itself. Claude Code CLI workers do the work.
|
|
6
6
|
*/
|
|
7
7
|
import type { MessageParam } from '@anthropic-ai/sdk/resources/messages';
|
|
8
|
-
import { WorkerAsset } from './core/file-tracker.js';
|
|
9
8
|
export type MessageSender = (message: string) => Promise<void>;
|
|
10
9
|
export interface WorkerStatus {
|
|
11
10
|
id: string;
|
|
@@ -16,6 +15,17 @@ export interface WorkerStatus {
|
|
|
16
15
|
estimated: number;
|
|
17
16
|
}
|
|
18
17
|
export type WorkerStatusCallback = (workers: WorkerStatus[]) => void;
|
|
18
|
+
export interface WorkerAsset {
|
|
19
|
+
path: string;
|
|
20
|
+
name: string;
|
|
21
|
+
type: 'new' | 'modified' | 'unchanged';
|
|
22
|
+
fileType: 'code' | 'image' | 'pdf' | 'text' | 'other';
|
|
23
|
+
preview?: string;
|
|
24
|
+
diff?: Array<{
|
|
25
|
+
type: 'context' | 'add' | 'remove';
|
|
26
|
+
content: string;
|
|
27
|
+
}>;
|
|
28
|
+
}
|
|
19
29
|
export interface GalleryWorker {
|
|
20
30
|
id: string;
|
|
21
31
|
task: string;
|
package/dist/orchestrator.js
CHANGED
|
@@ -17,7 +17,49 @@ import { WorkerTools } from './tools/worker.js';
|
|
|
17
17
|
import { SharedState } from './workers/shared-state.js';
|
|
18
18
|
import { getKnowledgeForPrompt } from './genesis/index.js';
|
|
19
19
|
import { loadHubContext, formatHubContext, logAction } from './core/hub.js';
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Extract file paths from worker output
|
|
22
|
+
* Workers naturally mention files they create: "Created /tmp/foo.html", "Saved to /path/file"
|
|
23
|
+
*/
|
|
24
|
+
function extractFilesFromOutput(output) {
|
|
25
|
+
const assets = [];
|
|
26
|
+
const seen = new Set();
|
|
27
|
+
// Common patterns for file creation/modification in worker output
|
|
28
|
+
const patterns = [
|
|
29
|
+
/(?:created|wrote|saved|generated|writing|creating)\s+(?:file\s+)?[`"']?([\/~][^\s`"']+\.[a-z0-9]+)[`"']?/gi,
|
|
30
|
+
/(?:output|file|saved)\s*(?:to|:)\s*[`"']?([\/~][^\s`"']+\.[a-z0-9]+)[`"']?/gi,
|
|
31
|
+
/[`"']([\/~][^\s`"']+\.[a-z0-9]+)[`"']\s*(?:created|saved|written)/gi,
|
|
32
|
+
/(?:^|\n)\s*[✓✅]\s*[`"']?([\/~][^\s`"']+\.[a-z0-9]+)[`"']?/gm,
|
|
33
|
+
];
|
|
34
|
+
for (const pattern of patterns) {
|
|
35
|
+
let match;
|
|
36
|
+
while ((match = pattern.exec(output)) !== null) {
|
|
37
|
+
const filePath = match[1].replace(/^~/, process.env.HOME || '/tmp');
|
|
38
|
+
if (!seen.has(filePath)) {
|
|
39
|
+
seen.add(filePath);
|
|
40
|
+
assets.push({
|
|
41
|
+
path: filePath,
|
|
42
|
+
name: filePath.split('/').pop() || filePath,
|
|
43
|
+
type: 'new',
|
|
44
|
+
fileType: getFileType(filePath)
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return assets;
|
|
50
|
+
}
|
|
51
|
+
function getFileType(path) {
|
|
52
|
+
const ext = path.split('.').pop()?.toLowerCase() || '';
|
|
53
|
+
if (['js', 'ts', 'jsx', 'tsx', 'py', 'html', 'css', 'json', 'md', 'sh'].includes(ext))
|
|
54
|
+
return 'code';
|
|
55
|
+
if (['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp'].includes(ext))
|
|
56
|
+
return 'image';
|
|
57
|
+
if (ext === 'pdf')
|
|
58
|
+
return 'pdf';
|
|
59
|
+
if (['txt', 'log', 'csv'].includes(ext))
|
|
60
|
+
return 'text';
|
|
61
|
+
return 'other';
|
|
62
|
+
}
|
|
21
63
|
const SYSTEM_PROMPT = `You are a MASTER ORCHESTRATOR - NOT a worker. You delegate ALL file/code work to Claude Code CLI workers.
|
|
22
64
|
|
|
23
65
|
CRITICAL IDENTITY:
|
|
@@ -919,19 +961,10 @@ Be specific about what you want done.`,
|
|
|
919
961
|
prompt = `Context: ${context}\n\nTask: ${task}`;
|
|
920
962
|
}
|
|
921
963
|
// Add brief instruction
|
|
922
|
-
prompt += `\n\nBe concise. Output results directly.`;
|
|
964
|
+
prompt += `\n\nBe concise. Output results directly. Do NOT open browsers or start servers - just create files and report paths.`;
|
|
923
965
|
console.log(`[ORCHESTRATOR] Worker ${id} starting: ${task.slice(0, 80)}...`);
|
|
924
966
|
// Estimate task duration
|
|
925
967
|
const estimatedTime = this.estimateTaskDuration(task);
|
|
926
|
-
// Take snapshot of files before worker starts (for asset tracking)
|
|
927
|
-
let beforeSnapshot;
|
|
928
|
-
try {
|
|
929
|
-
beforeSnapshot = takeSnapshot(cwd);
|
|
930
|
-
console.log(`[ORCHESTRATOR] Snapshot: ${beforeSnapshot.files.size} files in ${cwd}`);
|
|
931
|
-
}
|
|
932
|
-
catch (err) {
|
|
933
|
-
console.log(`[ORCHESTRATOR] Could not take snapshot: ${err}`);
|
|
934
|
-
}
|
|
935
968
|
const job = {
|
|
936
969
|
id,
|
|
937
970
|
task: task.slice(0, 200),
|
|
@@ -939,8 +972,7 @@ Be specific about what you want done.`,
|
|
|
939
972
|
startTime: Date.now(),
|
|
940
973
|
output: '',
|
|
941
974
|
estimatedTime,
|
|
942
|
-
workingDir: cwd
|
|
943
|
-
beforeSnapshot
|
|
975
|
+
workingDir: cwd
|
|
944
976
|
};
|
|
945
977
|
// Escape single quotes in prompt for shell safety
|
|
946
978
|
const escapedPrompt = prompt.replace(/'/g, "'\\''");
|
|
@@ -982,21 +1014,27 @@ Be specific about what you want done.`,
|
|
|
982
1014
|
job.endTime = Date.now();
|
|
983
1015
|
const duration = Math.round((job.endTime - job.startTime) / 1000);
|
|
984
1016
|
console.log(`[ORCHESTRATOR] Worker ${id} done in ${duration}s`);
|
|
985
|
-
|
|
986
|
-
|
|
1017
|
+
const result = job.output.trim() || '(No output)';
|
|
1018
|
+
// Extract files from worker output (workers naturally mention what they created)
|
|
1019
|
+
const assets = extractFilesFromOutput(result);
|
|
1020
|
+
job.assets = assets;
|
|
1021
|
+
if (assets.length > 0) {
|
|
1022
|
+
console.log(`[ORCHESTRATOR] Worker ${id} created ${assets.length} files: ${assets.map(a => a.name).join(', ')}`);
|
|
1023
|
+
// Store in memory for gallery queries
|
|
987
1024
|
try {
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
1025
|
+
await this.memory.remember(`Worker ${id} completed task "${job.task}" and created files: ${assets.map(a => a.path).join(', ')}`, {
|
|
1026
|
+
type: 'episodic',
|
|
1027
|
+
source: 'worker_output',
|
|
1028
|
+
tags: ['worker', 'files', id],
|
|
1029
|
+
importance: 0.7
|
|
1030
|
+
});
|
|
994
1031
|
}
|
|
995
1032
|
catch (err) {
|
|
996
|
-
console.log(`[ORCHESTRATOR] Could not
|
|
1033
|
+
console.log(`[ORCHESTRATOR] Could not store worker output in memory: ${err}`);
|
|
997
1034
|
}
|
|
1035
|
+
// Broadcast gallery update
|
|
1036
|
+
this.broadcastGalleryUpdate();
|
|
998
1037
|
}
|
|
999
|
-
const result = job.output.trim() || '(No output)';
|
|
1000
1038
|
// Notify via callback (sends to user via WebSocket)
|
|
1001
1039
|
if (this.workerResultCallback) {
|
|
1002
1040
|
this.workerResultCallback(id, result);
|
|
@@ -13,7 +13,6 @@ export type GalleryCallback = (workers: GalleryWorker[]) => void;
|
|
|
13
13
|
export declare class WorkerManager {
|
|
14
14
|
private config;
|
|
15
15
|
private activeWorkers;
|
|
16
|
-
private fileSnapshots;
|
|
17
16
|
private galleryCallback;
|
|
18
17
|
constructor(workspaceDir: string, configOverrides?: Partial<WorkerConfig>);
|
|
19
18
|
/**
|
package/dist/workers/manager.js
CHANGED
|
@@ -6,11 +6,51 @@ 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
|
-
|
|
9
|
+
// Removed file-tracker - now extract files from worker output
|
|
10
|
+
/**
|
|
11
|
+
* Extract file paths from worker output
|
|
12
|
+
*/
|
|
13
|
+
function extractFilesFromOutput(output) {
|
|
14
|
+
const assets = [];
|
|
15
|
+
const seen = new Set();
|
|
16
|
+
const patterns = [
|
|
17
|
+
/(?:created|wrote|saved|generated|writing|creating)\s+(?:file\s+)?[`"']?([\/~][^\s`"']+\.[a-z0-9]+)[`"']?/gi,
|
|
18
|
+
/(?:output|file|saved)\s*(?:to|:)\s*[`"']?([\/~][^\s`"']+\.[a-z0-9]+)[`"']?/gi,
|
|
19
|
+
/[`"']([\/~][^\s`"']+\.[a-z0-9]+)[`"']\s*(?:created|saved|written)/gi,
|
|
20
|
+
/(?:^|\n)\s*[✓✅]\s*[`"']?([\/~][^\s`"']+\.[a-z0-9]+)[`"']?/gm,
|
|
21
|
+
];
|
|
22
|
+
for (const pattern of patterns) {
|
|
23
|
+
let match;
|
|
24
|
+
while ((match = pattern.exec(output)) !== null) {
|
|
25
|
+
const filePath = match[1].replace(/^~/, process.env.HOME || '/tmp');
|
|
26
|
+
if (!seen.has(filePath)) {
|
|
27
|
+
seen.add(filePath);
|
|
28
|
+
const ext = filePath.split('.').pop()?.toLowerCase() || '';
|
|
29
|
+
assets.push({
|
|
30
|
+
path: filePath,
|
|
31
|
+
name: filePath.split('/').pop() || filePath,
|
|
32
|
+
type: 'new',
|
|
33
|
+
fileType: getFileType(ext)
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return assets;
|
|
39
|
+
}
|
|
40
|
+
function getFileType(ext) {
|
|
41
|
+
if (['js', 'ts', 'jsx', 'tsx', 'py', 'html', 'css', 'json', 'md', 'sh'].includes(ext))
|
|
42
|
+
return 'code';
|
|
43
|
+
if (['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp'].includes(ext))
|
|
44
|
+
return 'image';
|
|
45
|
+
if (ext === 'pdf')
|
|
46
|
+
return 'pdf';
|
|
47
|
+
if (['txt', 'log', 'csv'].includes(ext))
|
|
48
|
+
return 'text';
|
|
49
|
+
return 'other';
|
|
50
|
+
}
|
|
10
51
|
export class WorkerManager {
|
|
11
52
|
config;
|
|
12
53
|
activeWorkers = new Map();
|
|
13
|
-
fileSnapshots = new Map(); // Before-snapshots per job
|
|
14
54
|
galleryCallback = null;
|
|
15
55
|
constructor(workspaceDir, configOverrides) {
|
|
16
56
|
this.config = {
|
|
@@ -94,15 +134,6 @@ export class WorkerManager {
|
|
|
94
134
|
// Validate timeout
|
|
95
135
|
const effectiveTimeout = Math.min(timeout, this.config.maxTimeout);
|
|
96
136
|
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
|
-
}
|
|
106
137
|
const job = {
|
|
107
138
|
id: jobId,
|
|
108
139
|
task,
|
|
@@ -123,6 +154,7 @@ IMPORTANT - Progress & Logging:
|
|
|
123
154
|
- Output findings as you go, don't wait until the end
|
|
124
155
|
- Print discoveries and insights immediately as you find them
|
|
125
156
|
- Report on each file/step before moving to the next
|
|
157
|
+
- Do NOT open browsers or start servers - just create files and report paths
|
|
126
158
|
|
|
127
159
|
REQUIRED - Log Export:
|
|
128
160
|
At the END of your work, create a final log file at: ${logFile}
|
|
@@ -200,24 +232,12 @@ This ensures nothing is lost even if your output gets truncated.`;
|
|
|
200
232
|
if (stderr && code !== 0) {
|
|
201
233
|
currentJob.error = stderr.trim();
|
|
202
234
|
}
|
|
203
|
-
//
|
|
204
|
-
const
|
|
205
|
-
if (
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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
|
-
}
|
|
235
|
+
// Extract files from worker output (workers mention what they created)
|
|
236
|
+
const assets = extractFilesFromOutput(finalResult);
|
|
237
|
+
if (assets.length > 0) {
|
|
238
|
+
currentJob.assets = assets;
|
|
239
|
+
console.log(`[WORKER] ${jobId} created ${assets.length} files: ${assets.map(a => a.name).join(', ')}`);
|
|
240
|
+
this.broadcastGalleryUpdate();
|
|
221
241
|
}
|
|
222
242
|
this.saveJob(currentJob);
|
|
223
243
|
}
|