@pixelbyte-software/pixcode 1.35.0 → 1.35.1
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/LICENSE +718 -718
- package/README.de.md +248 -248
- package/README.ja.md +240 -240
- package/README.ko.md +240 -240
- package/README.md +303 -303
- package/README.ru.md +248 -248
- package/README.tr.md +250 -250
- package/README.zh-CN.md +240 -240
- package/dist/api-docs.html +548 -548
- package/dist/assets/{index-Djuh0wHV.js → index-CBdsvGSR.js} +133 -133
- package/dist/clear-cache.html +85 -85
- package/dist/convert-icons.md +52 -52
- package/dist/generate-icons.js +48 -48
- package/dist/icons/codex-white.svg +3 -3
- package/dist/icons/codex.svg +3 -3
- package/dist/icons/cursor-white.svg +11 -11
- package/dist/icons/qwen-logo.svg +14 -14
- package/dist/index.html +58 -58
- package/dist/manifest.json +60 -60
- package/dist/openapi.yaml +1693 -1693
- package/dist/sw.js +124 -124
- package/dist-server/server/cli.js +96 -96
- package/dist-server/server/daemon/manager.js +33 -33
- package/dist-server/server/daemon-manager.js +64 -64
- package/dist-server/server/modules/orchestration/preview/preview-proxy.js +3 -3
- package/dist-server/server/modules/orchestration/preview/preview-proxy.js.map +1 -1
- package/dist-server/server/routes/commands.js +25 -25
- package/dist-server/server/routes/git.js +17 -17
- package/dist-server/server/routes/taskmaster.js +419 -419
- package/package.json +180 -180
- package/scripts/fix-node-pty.js +67 -67
- package/scripts/smoke/a2a-roundtrip.mjs +167 -167
- package/scripts/smoke/orchestration-api.mjs +172 -172
- package/scripts/smoke/orchestration-live-run.mjs +176 -176
- package/server/claude-sdk.js +898 -898
- package/server/cli.js +935 -935
- package/server/constants/config.js +4 -4
- package/server/cursor-cli.js +342 -342
- package/server/daemon/manager.js +564 -564
- package/server/daemon-manager.js +959 -959
- package/server/database/json-store.js +197 -197
- package/server/gemini-cli.js +535 -535
- package/server/gemini-response-handler.js +79 -79
- package/server/index.js +3135 -3135
- package/server/load-env.js +34 -34
- package/server/middleware/auth.js +173 -173
- package/server/modules/orchestration/a2a/adapter-registry.ts +108 -108
- package/server/modules/orchestration/a2a/adapters/abstract-a2a.adapter.ts +55 -55
- package/server/modules/orchestration/a2a/adapters/claude-code.adapter.ts +284 -284
- package/server/modules/orchestration/a2a/adapters/codex.adapter.ts +244 -244
- package/server/modules/orchestration/a2a/adapters/cursor.adapter.ts +249 -249
- package/server/modules/orchestration/a2a/adapters/gemini.adapter.ts +248 -248
- package/server/modules/orchestration/a2a/adapters/opencode.adapter.ts +248 -248
- package/server/modules/orchestration/a2a/adapters/qwen.adapter.ts +248 -248
- package/server/modules/orchestration/a2a/agent-card.ts +55 -55
- package/server/modules/orchestration/a2a/auth.middleware.ts +29 -29
- package/server/modules/orchestration/a2a/bus.ts +46 -46
- package/server/modules/orchestration/a2a/routes.ts +577 -577
- package/server/modules/orchestration/a2a/task-store.ts +178 -178
- package/server/modules/orchestration/a2a/types.ts +125 -125
- package/server/modules/orchestration/a2a/validator.ts +113 -113
- package/server/modules/orchestration/index.ts +66 -66
- package/server/modules/orchestration/preview/port-watcher.ts +112 -112
- package/server/modules/orchestration/preview/preview-proxy.ts +60 -60
- package/server/modules/orchestration/preview/types.ts +19 -19
- package/server/modules/orchestration/tasks/orchestration-task-store.ts +45 -45
- package/server/modules/orchestration/tasks/orchestration-task.routes.ts +73 -73
- package/server/modules/orchestration/tasks/orchestration-task.service.ts +145 -145
- package/server/modules/orchestration/tasks/orchestration-task.types.ts +29 -29
- package/server/modules/orchestration/workflows/built-in-workflows.ts +127 -127
- package/server/modules/orchestration/workflows/workflow-runner.ts +1206 -1206
- package/server/modules/orchestration/workflows/workflow-store.ts +97 -97
- package/server/modules/orchestration/workflows/workflow.routes.ts +169 -169
- package/server/modules/orchestration/workflows/workflow.types.ts +70 -70
- package/server/modules/orchestration/workflows/workspace-target.ts +120 -120
- package/server/modules/orchestration/workspace/docker-workspace.ts +135 -135
- package/server/modules/orchestration/workspace/path-safety.ts +55 -55
- package/server/modules/orchestration/workspace/types.ts +52 -52
- package/server/modules/orchestration/workspace/workspace-manager.ts +97 -97
- package/server/modules/orchestration/workspace/worktree-workspace.ts +125 -125
- package/server/modules/providers/index.ts +2 -2
- package/server/modules/providers/list/claude/claude-auth.provider.ts +145 -145
- package/server/modules/providers/list/claude/claude-mcp.provider.ts +135 -135
- package/server/modules/providers/list/claude/claude-sessions.provider.ts +306 -306
- package/server/modules/providers/list/claude/claude.provider.ts +15 -15
- package/server/modules/providers/list/codex/codex-auth.provider.ts +115 -115
- package/server/modules/providers/list/codex/codex-mcp.provider.ts +135 -135
- package/server/modules/providers/list/codex/codex-sessions.provider.ts +319 -319
- package/server/modules/providers/list/codex/codex.provider.ts +15 -15
- package/server/modules/providers/list/cursor/cursor-auth.provider.ts +143 -143
- package/server/modules/providers/list/cursor/cursor-mcp.provider.ts +108 -108
- package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +421 -421
- package/server/modules/providers/list/cursor/cursor.provider.ts +15 -15
- package/server/modules/providers/list/gemini/gemini-auth.provider.ts +163 -163
- package/server/modules/providers/list/gemini/gemini-mcp.provider.ts +110 -110
- package/server/modules/providers/list/gemini/gemini-sessions.provider.ts +227 -227
- package/server/modules/providers/list/gemini/gemini.provider.ts +15 -15
- package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +232 -232
- package/server/modules/providers/list/qwen/qwen-sessions.provider.ts +265 -265
- package/server/modules/providers/provider.registry.ts +40 -40
- package/server/modules/providers/provider.routes.ts +819 -819
- package/server/modules/providers/services/mcp.service.ts +86 -86
- package/server/modules/providers/services/provider-auth.service.ts +26 -26
- package/server/modules/providers/services/sessions.service.ts +45 -45
- package/server/modules/providers/shared/base/abstract.provider.ts +20 -20
- package/server/modules/providers/shared/mcp/mcp.provider.ts +151 -151
- package/server/modules/providers/tests/mcp.test.ts +293 -293
- package/server/openai-codex.js +462 -462
- package/server/opencode-cli.js +459 -459
- package/server/opencode-response-handler.js +107 -107
- package/server/projects.js +3105 -3105
- package/server/routes/agent.js +1365 -1365
- package/server/routes/auth.js +138 -138
- package/server/routes/codex.js +19 -19
- package/server/routes/commands.js +554 -554
- package/server/routes/cursor.js +52 -52
- package/server/routes/gemini.js +24 -24
- package/server/routes/git.js +1488 -1488
- package/server/routes/mcp-utils.js +31 -31
- package/server/routes/messages.js +61 -61
- package/server/routes/network.js +120 -120
- package/server/routes/plugins.js +318 -318
- package/server/routes/projects.js +915 -915
- package/server/routes/settings.js +286 -286
- package/server/routes/taskmaster.js +1496 -1496
- package/server/routes/telegram.js +125 -125
- package/server/routes/user.js +123 -123
- package/server/services/install-jobs.js +571 -571
- package/server/services/notification-orchestrator.js +242 -242
- package/server/services/provider-credentials.js +189 -189
- package/server/services/telegram/bot.js +279 -279
- package/server/services/telegram/translations.js +170 -170
- package/server/sessionManager.js +225 -225
- package/server/shared/interfaces.ts +54 -54
- package/server/shared/types.ts +172 -172
- package/server/shared/utils.ts +193 -193
- package/server/tsconfig.json +36 -36
- package/server/utils/colors.js +21 -21
- package/server/utils/commandParser.js +303 -303
- package/server/utils/frontmatter.js +18 -18
- package/server/utils/gitConfig.js +34 -34
- package/server/utils/mcp-detector.js +147 -147
- package/server/utils/plugin-loader.js +457 -457
- package/server/utils/plugin-process-manager.js +184 -184
- package/server/utils/runtime-paths.js +37 -37
- package/server/utils/taskmaster-websocket.js +128 -128
- package/server/utils/url-detection.js +71 -71
- package/server/vite-daemon.js +78 -78
- package/shared/modelConstants.js +162 -162
- package/shared/networkHosts.js +22 -22
|
@@ -1,176 +1,176 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const baseUrl = process.env.PIXCODE_BASE_URL || 'http://127.0.0.1:3001';
|
|
4
|
-
const apiKey = process.env.PIXCODE_API_KEY;
|
|
5
|
-
const goal = process.env.PIXCODE_LIVE_GOAL;
|
|
6
|
-
const timeoutMs = Number.parseInt(process.env.PIXCODE_LIVE_TIMEOUT_MS || '1200000', 10);
|
|
7
|
-
const minAgentOutputs = Number.parseInt(process.env.PIXCODE_LIVE_MIN_AGENT_OUTPUTS || '2', 10);
|
|
8
|
-
const workflowId = process.env.PIXCODE_LIVE_WORKFLOW_ID || 'agent_team';
|
|
9
|
-
|
|
10
|
-
if (!apiKey) {
|
|
11
|
-
console.error('PIXCODE_API_KEY is required.');
|
|
12
|
-
process.exit(1);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
if (!goal) {
|
|
16
|
-
console.error('PIXCODE_LIVE_GOAL is required.');
|
|
17
|
-
process.exit(1);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function parseJsonEnv(name) {
|
|
21
|
-
const raw = process.env[name];
|
|
22
|
-
if (!raw) {
|
|
23
|
-
throw new Error(`${name} is required.`);
|
|
24
|
-
}
|
|
25
|
-
try {
|
|
26
|
-
return JSON.parse(raw);
|
|
27
|
-
} catch (error) {
|
|
28
|
-
throw new Error(`${name} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function assert(condition, message) {
|
|
33
|
-
if (!condition) throw new Error(message);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function headers(extra = {}) {
|
|
37
|
-
return {
|
|
38
|
-
authorization: `Bearer ${apiKey}`,
|
|
39
|
-
'content-type': 'application/json',
|
|
40
|
-
...extra,
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async function request(path, options = {}) {
|
|
45
|
-
const response = await fetch(`${baseUrl}${path}`, {
|
|
46
|
-
...options,
|
|
47
|
-
headers: headers(options.headers || {}),
|
|
48
|
-
});
|
|
49
|
-
const text = await response.text();
|
|
50
|
-
const body = text ? JSON.parse(text) : null;
|
|
51
|
-
if (!response.ok) {
|
|
52
|
-
throw new Error(`${options.method || 'GET'} ${path} failed: ${response.status} ${text}`);
|
|
53
|
-
}
|
|
54
|
-
return body;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function terminal(status) {
|
|
58
|
-
return status === 'completed' || status === 'failed' || status === 'canceled';
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function agentTextCount(run) {
|
|
62
|
-
return (run.nodeRuns || []).filter((node) =>
|
|
63
|
-
(node.messages || []).some((message) => message.role !== 'user' && message.text?.trim()) ||
|
|
64
|
-
Boolean(node.outputText?.trim()),
|
|
65
|
-
).length;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function compactNodes(run) {
|
|
69
|
-
return (run.nodeRuns || []).map((node) => ({
|
|
70
|
-
nodeId: node.nodeId,
|
|
71
|
-
label: node.agentLabel,
|
|
72
|
-
status: node.status,
|
|
73
|
-
taskId: node.a2aTaskId,
|
|
74
|
-
messageCount: (node.messages || []).filter((message) => message.role !== 'user').length,
|
|
75
|
-
hasOutput: Boolean(node.outputText?.trim()),
|
|
76
|
-
error: node.error,
|
|
77
|
-
}));
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
async function cancelRun(runId) {
|
|
81
|
-
try {
|
|
82
|
-
await request(`/api/orchestration/workflows/runs/${encodeURIComponent(runId)}/cancel`, {
|
|
83
|
-
method: 'POST',
|
|
84
|
-
body: '{}',
|
|
85
|
-
});
|
|
86
|
-
} catch {
|
|
87
|
-
// Best-effort cleanup only.
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
async function main() {
|
|
92
|
-
const agents = parseJsonEnv('PIXCODE_LIVE_AGENTS_JSON');
|
|
93
|
-
assert(Array.isArray(agents) && agents.length > 0, 'PIXCODE_LIVE_AGENTS_JSON must be a non-empty array.');
|
|
94
|
-
|
|
95
|
-
const settings = process.env.PIXCODE_LIVE_SETTINGS_JSON
|
|
96
|
-
? JSON.parse(process.env.PIXCODE_LIVE_SETTINGS_JSON)
|
|
97
|
-
: {};
|
|
98
|
-
const metadata = {
|
|
99
|
-
agents,
|
|
100
|
-
projectPath: process.env.PIXCODE_LIVE_PROJECT_PATH,
|
|
101
|
-
projectId: process.env.PIXCODE_LIVE_PROJECT_ID,
|
|
102
|
-
settings: {
|
|
103
|
-
maxParallelAgents: Number.parseInt(process.env.PIXCODE_LIVE_MAX_PARALLEL || '3', 10),
|
|
104
|
-
isolation: process.env.PIXCODE_LIVE_ISOLATION || 'host',
|
|
105
|
-
keepWorkspace: process.env.PIXCODE_LIVE_KEEP_WORKSPACE !== 'false',
|
|
106
|
-
...settings,
|
|
107
|
-
},
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const preview = await request(`/api/orchestration/workflows/${encodeURIComponent(workflowId)}/preview`, {
|
|
111
|
-
method: 'POST',
|
|
112
|
-
body: JSON.stringify({ metadata }),
|
|
113
|
-
});
|
|
114
|
-
assert(preview.nodeCount >= agents.length + 1, 'Preview did not expand enough nodes for the requested agents.');
|
|
115
|
-
console.log(JSON.stringify({ event: 'preview', nodeIds: preview.nodes.map((node) => node.id) }));
|
|
116
|
-
|
|
117
|
-
const started = await request(`/api/orchestration/workflows/${encodeURIComponent(workflowId)}/runs`, {
|
|
118
|
-
method: 'POST',
|
|
119
|
-
body: JSON.stringify({ input: goal, metadata }),
|
|
120
|
-
});
|
|
121
|
-
const runId = started.id;
|
|
122
|
-
assert(runId, 'Run id missing from start response.');
|
|
123
|
-
console.log(JSON.stringify({ event: 'started', runId, contextId: started.contextId }));
|
|
124
|
-
|
|
125
|
-
const deadline = Date.now() + timeoutMs;
|
|
126
|
-
let lastSignature = '';
|
|
127
|
-
let latest = started;
|
|
128
|
-
while (!terminal(latest.status) && Date.now() < deadline) {
|
|
129
|
-
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
130
|
-
latest = await request(`/api/orchestration/workflows/runs/${encodeURIComponent(runId)}`);
|
|
131
|
-
const nodes = compactNodes(latest);
|
|
132
|
-
const signature = JSON.stringify(nodes.map((node) => [
|
|
133
|
-
node.nodeId,
|
|
134
|
-
node.status,
|
|
135
|
-
node.messageCount,
|
|
136
|
-
node.hasOutput,
|
|
137
|
-
node.error,
|
|
138
|
-
]));
|
|
139
|
-
if (signature !== lastSignature) {
|
|
140
|
-
lastSignature = signature;
|
|
141
|
-
console.log(JSON.stringify({
|
|
142
|
-
event: 'progress',
|
|
143
|
-
status: latest.status,
|
|
144
|
-
agentOutputs: agentTextCount(latest),
|
|
145
|
-
nodes,
|
|
146
|
-
}));
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (!terminal(latest.status)) {
|
|
151
|
-
await cancelRun(runId);
|
|
152
|
-
throw new Error(`Run ${runId} did not finish before ${timeoutMs}ms; canceled.`);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const outputCount = agentTextCount(latest);
|
|
156
|
-
if (outputCount < minAgentOutputs) {
|
|
157
|
-
throw new Error(`Expected at least ${minAgentOutputs} nodes with agent output; got ${outputCount}.`);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (latest.status !== 'completed') {
|
|
161
|
-
throw new Error(`Run ended with ${latest.status}: ${JSON.stringify(compactNodes(latest))}`);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
console.log(JSON.stringify({
|
|
165
|
-
event: 'completed',
|
|
166
|
-
runId,
|
|
167
|
-
contextId: latest.contextId,
|
|
168
|
-
outputCount,
|
|
169
|
-
nodes: compactNodes(latest),
|
|
170
|
-
}, null, 2));
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
main().catch((error) => {
|
|
174
|
-
console.error(error instanceof Error ? error.message : String(error));
|
|
175
|
-
process.exit(1);
|
|
176
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const baseUrl = process.env.PIXCODE_BASE_URL || 'http://127.0.0.1:3001';
|
|
4
|
+
const apiKey = process.env.PIXCODE_API_KEY;
|
|
5
|
+
const goal = process.env.PIXCODE_LIVE_GOAL;
|
|
6
|
+
const timeoutMs = Number.parseInt(process.env.PIXCODE_LIVE_TIMEOUT_MS || '1200000', 10);
|
|
7
|
+
const minAgentOutputs = Number.parseInt(process.env.PIXCODE_LIVE_MIN_AGENT_OUTPUTS || '2', 10);
|
|
8
|
+
const workflowId = process.env.PIXCODE_LIVE_WORKFLOW_ID || 'agent_team';
|
|
9
|
+
|
|
10
|
+
if (!apiKey) {
|
|
11
|
+
console.error('PIXCODE_API_KEY is required.');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (!goal) {
|
|
16
|
+
console.error('PIXCODE_LIVE_GOAL is required.');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function parseJsonEnv(name) {
|
|
21
|
+
const raw = process.env[name];
|
|
22
|
+
if (!raw) {
|
|
23
|
+
throw new Error(`${name} is required.`);
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
return JSON.parse(raw);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
throw new Error(`${name} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function assert(condition, message) {
|
|
33
|
+
if (!condition) throw new Error(message);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function headers(extra = {}) {
|
|
37
|
+
return {
|
|
38
|
+
authorization: `Bearer ${apiKey}`,
|
|
39
|
+
'content-type': 'application/json',
|
|
40
|
+
...extra,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function request(path, options = {}) {
|
|
45
|
+
const response = await fetch(`${baseUrl}${path}`, {
|
|
46
|
+
...options,
|
|
47
|
+
headers: headers(options.headers || {}),
|
|
48
|
+
});
|
|
49
|
+
const text = await response.text();
|
|
50
|
+
const body = text ? JSON.parse(text) : null;
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
throw new Error(`${options.method || 'GET'} ${path} failed: ${response.status} ${text}`);
|
|
53
|
+
}
|
|
54
|
+
return body;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function terminal(status) {
|
|
58
|
+
return status === 'completed' || status === 'failed' || status === 'canceled';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function agentTextCount(run) {
|
|
62
|
+
return (run.nodeRuns || []).filter((node) =>
|
|
63
|
+
(node.messages || []).some((message) => message.role !== 'user' && message.text?.trim()) ||
|
|
64
|
+
Boolean(node.outputText?.trim()),
|
|
65
|
+
).length;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function compactNodes(run) {
|
|
69
|
+
return (run.nodeRuns || []).map((node) => ({
|
|
70
|
+
nodeId: node.nodeId,
|
|
71
|
+
label: node.agentLabel,
|
|
72
|
+
status: node.status,
|
|
73
|
+
taskId: node.a2aTaskId,
|
|
74
|
+
messageCount: (node.messages || []).filter((message) => message.role !== 'user').length,
|
|
75
|
+
hasOutput: Boolean(node.outputText?.trim()),
|
|
76
|
+
error: node.error,
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function cancelRun(runId) {
|
|
81
|
+
try {
|
|
82
|
+
await request(`/api/orchestration/workflows/runs/${encodeURIComponent(runId)}/cancel`, {
|
|
83
|
+
method: 'POST',
|
|
84
|
+
body: '{}',
|
|
85
|
+
});
|
|
86
|
+
} catch {
|
|
87
|
+
// Best-effort cleanup only.
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function main() {
|
|
92
|
+
const agents = parseJsonEnv('PIXCODE_LIVE_AGENTS_JSON');
|
|
93
|
+
assert(Array.isArray(agents) && agents.length > 0, 'PIXCODE_LIVE_AGENTS_JSON must be a non-empty array.');
|
|
94
|
+
|
|
95
|
+
const settings = process.env.PIXCODE_LIVE_SETTINGS_JSON
|
|
96
|
+
? JSON.parse(process.env.PIXCODE_LIVE_SETTINGS_JSON)
|
|
97
|
+
: {};
|
|
98
|
+
const metadata = {
|
|
99
|
+
agents,
|
|
100
|
+
projectPath: process.env.PIXCODE_LIVE_PROJECT_PATH,
|
|
101
|
+
projectId: process.env.PIXCODE_LIVE_PROJECT_ID,
|
|
102
|
+
settings: {
|
|
103
|
+
maxParallelAgents: Number.parseInt(process.env.PIXCODE_LIVE_MAX_PARALLEL || '3', 10),
|
|
104
|
+
isolation: process.env.PIXCODE_LIVE_ISOLATION || 'host',
|
|
105
|
+
keepWorkspace: process.env.PIXCODE_LIVE_KEEP_WORKSPACE !== 'false',
|
|
106
|
+
...settings,
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const preview = await request(`/api/orchestration/workflows/${encodeURIComponent(workflowId)}/preview`, {
|
|
111
|
+
method: 'POST',
|
|
112
|
+
body: JSON.stringify({ metadata }),
|
|
113
|
+
});
|
|
114
|
+
assert(preview.nodeCount >= agents.length + 1, 'Preview did not expand enough nodes for the requested agents.');
|
|
115
|
+
console.log(JSON.stringify({ event: 'preview', nodeIds: preview.nodes.map((node) => node.id) }));
|
|
116
|
+
|
|
117
|
+
const started = await request(`/api/orchestration/workflows/${encodeURIComponent(workflowId)}/runs`, {
|
|
118
|
+
method: 'POST',
|
|
119
|
+
body: JSON.stringify({ input: goal, metadata }),
|
|
120
|
+
});
|
|
121
|
+
const runId = started.id;
|
|
122
|
+
assert(runId, 'Run id missing from start response.');
|
|
123
|
+
console.log(JSON.stringify({ event: 'started', runId, contextId: started.contextId }));
|
|
124
|
+
|
|
125
|
+
const deadline = Date.now() + timeoutMs;
|
|
126
|
+
let lastSignature = '';
|
|
127
|
+
let latest = started;
|
|
128
|
+
while (!terminal(latest.status) && Date.now() < deadline) {
|
|
129
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
130
|
+
latest = await request(`/api/orchestration/workflows/runs/${encodeURIComponent(runId)}`);
|
|
131
|
+
const nodes = compactNodes(latest);
|
|
132
|
+
const signature = JSON.stringify(nodes.map((node) => [
|
|
133
|
+
node.nodeId,
|
|
134
|
+
node.status,
|
|
135
|
+
node.messageCount,
|
|
136
|
+
node.hasOutput,
|
|
137
|
+
node.error,
|
|
138
|
+
]));
|
|
139
|
+
if (signature !== lastSignature) {
|
|
140
|
+
lastSignature = signature;
|
|
141
|
+
console.log(JSON.stringify({
|
|
142
|
+
event: 'progress',
|
|
143
|
+
status: latest.status,
|
|
144
|
+
agentOutputs: agentTextCount(latest),
|
|
145
|
+
nodes,
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (!terminal(latest.status)) {
|
|
151
|
+
await cancelRun(runId);
|
|
152
|
+
throw new Error(`Run ${runId} did not finish before ${timeoutMs}ms; canceled.`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const outputCount = agentTextCount(latest);
|
|
156
|
+
if (outputCount < minAgentOutputs) {
|
|
157
|
+
throw new Error(`Expected at least ${minAgentOutputs} nodes with agent output; got ${outputCount}.`);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (latest.status !== 'completed') {
|
|
161
|
+
throw new Error(`Run ended with ${latest.status}: ${JSON.stringify(compactNodes(latest))}`);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
console.log(JSON.stringify({
|
|
165
|
+
event: 'completed',
|
|
166
|
+
runId,
|
|
167
|
+
contextId: latest.contextId,
|
|
168
|
+
outputCount,
|
|
169
|
+
nodes: compactNodes(latest),
|
|
170
|
+
}, null, 2));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
main().catch((error) => {
|
|
174
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
175
|
+
process.exit(1);
|
|
176
|
+
});
|