@mndrk/agx 1.4.20 → 1.4.22
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/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/BUILD_ID +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/app-build-manifest.json +29 -29
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/app-path-routes-manifest.json +4 -4
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/build-manifest.json +2 -2
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/prerender-manifest.json +22 -22
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/_not-found.html +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/_not-found.rsc +2 -2
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/audit/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/[...nextauth]/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/daemon-secret/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/device/code/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/device/token/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/refresh/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/learnings/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/logs/stream/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/orchestrator/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/orchestrator/tasks/[taskId]/signal/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/orchestrator/tasks/[taskId]/start/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/orchestrator/tasks/[taskId]/status/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/projects/[id]/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/providers/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/queue/complete/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/queue/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/stage-prompts/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/comments/[commentId]/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/comments/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/heartbeat/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/history/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/logs/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/[id]/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/tasks/stream/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/user-settings/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/workflows/[id]/nodes/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/workflows/[id]/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/auth/callback/route_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/auth/device/page.js +5 -5
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/auth/device/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/auth/device.html +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/auth/device.rsc +3 -3
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/dashboard/page.js +8 -3
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/dashboard/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/dashboard.html +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/dashboard.rsc +3 -3
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/index.html +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/index.rsc +2 -2
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/login.html +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/login.rsc +2 -2
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/page.js +4 -4
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/tasks/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/[slug]/workflow/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects.html +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/projects.rsc +3 -3
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/settings.html +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app/settings.rsc +2 -2
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/app-paths-manifest.json +4 -4
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/chunks/3009.js +5 -6
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/chunks/6125.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/middleware-manifest.json +5 -5
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/pages/404.html +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/pages/500.html +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/server-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/server/server-reference-manifest.json +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/{9337-5d3c6b1828da8ec3.js → 9337-09000d8a6c85f40c.js} +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/9719-0fda94fde411f574.js +1 -0
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/auth/device/page-e2c2560ec12b421d.js +1 -0
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/dashboard/page-7437499eb05d5ce8.js +1 -0
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/projects/[slug]/page-253ca8286e8f1d68.js +1 -0
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/css/72371329e4c91108.css +1 -0
- package/index.js +212 -63
- package/lib/cli/cloud/aggregate.js +162 -0
- package/lib/cli/cloud/command.js +230 -0
- package/lib/cli/cloud/executeVerifySingle.js +293 -0
- package/lib/cli/cloud/executeVerifySwarm.js +302 -0
- package/lib/cli/cloud/index.js +68 -0
- package/lib/cli/cloud/iterations.js +155 -0
- package/lib/cli/cloud/persist.js +123 -0
- package/lib/cli/cloud/prompts.js +229 -0
- package/lib/cli/cloud/simpleLoops.js +203 -0
- package/lib/cli/cloud/taskLogger.js +159 -0
- package/lib/cli/cloudArtifacts.js +478 -0
- package/lib/cli/onboarding.js +23 -4
- package/lib/cli/runCli.js +205 -2200
- package/lib/cli/util.js +68 -1
- package/lib/cloud/client.js +3 -30
- package/lib/config/cloudConfig.js +110 -6
- package/lib/config/paths.js +1 -1
- package/package.json +1 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/9719-1d7bdd112db709cc.js +0 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/auth/device/page-1191b5d80fb53701.js +0 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/dashboard/page-2403721dcf6fac4f.js +0 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/chunks/app/projects/[slug]/page-e5b42f6a38ee1959.js +0 -1
- package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/css/97623b2fc4a523a7.css +0 -1
- /package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/{_UEH0bf2vZJdfFbGlB9rM → M4AQWpnhTFqFD3HFlSHd9}/_buildManifest.js +0 -0
- /package/cloud-runtime/standalone/Projects/Agents/agx-cloud/.next/static/{_UEH0bf2vZJdfFbGlB9rM → M4AQWpnhTFqFD3HFlSHd9}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const crypto = require('crypto');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const os = require('os');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
function isLocalArtifactsEnabled() {
|
|
10
|
+
// Single cutover: always on, no opt-out.
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function mapCloudStageToLocalStage(stage) {
|
|
15
|
+
const raw = String(stage || '').toLowerCase().trim();
|
|
16
|
+
if (raw === 'plan' || raw === 'execute' || raw === 'verify' || raw === 'resume') return raw;
|
|
17
|
+
if (raw === 'ideation' || raw === 'planning') return 'plan';
|
|
18
|
+
if (raw === 'verification') return 'verify';
|
|
19
|
+
return 'execute';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function shortStableHex(value, len = 6) {
|
|
23
|
+
const v = String(value || '');
|
|
24
|
+
if (!v) return crypto.randomBytes(Math.max(2, Math.ceil(len / 2))).toString('hex').slice(0, len);
|
|
25
|
+
return crypto.createHash('sha1').update(v).digest('hex').slice(0, len);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function extractCloudProjectIdentity(task) {
|
|
29
|
+
const projectObj = task?.project && typeof task.project === 'object' ? task.project : null;
|
|
30
|
+
const projectId =
|
|
31
|
+
task?.project_id ||
|
|
32
|
+
task?.projectId ||
|
|
33
|
+
projectObj?.id ||
|
|
34
|
+
projectObj?.project_id ||
|
|
35
|
+
null;
|
|
36
|
+
|
|
37
|
+
const projectSlug =
|
|
38
|
+
task?.project_slug ||
|
|
39
|
+
projectObj?.slug ||
|
|
40
|
+
projectObj?.project_slug ||
|
|
41
|
+
(typeof task?.project === 'string' ? task.project : null) ||
|
|
42
|
+
null;
|
|
43
|
+
|
|
44
|
+
const projectName =
|
|
45
|
+
task?.project_name ||
|
|
46
|
+
projectObj?.name ||
|
|
47
|
+
projectObj?.project_name ||
|
|
48
|
+
null;
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
projectId: projectId ? String(projectId) : null,
|
|
52
|
+
projectSlug: projectSlug ? String(projectSlug) : null,
|
|
53
|
+
projectName: projectName ? String(projectName) : null
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function extractCloudTaskIdentity(task) {
|
|
58
|
+
const taskId = task?.id ? String(task.id).trim() : '';
|
|
59
|
+
const taskSlug = task?.slug ? String(task.slug).trim() : '';
|
|
60
|
+
return { taskId, taskSlug };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function resolveLocalProjectSlugForCloudTask(storage, task) {
|
|
64
|
+
const { projectId, projectSlug, projectName } = extractCloudProjectIdentity(task);
|
|
65
|
+
const label = projectSlug || projectName || 'cloud';
|
|
66
|
+
const base = storage.slugify(label, { maxLength: 64 });
|
|
67
|
+
const baseState = await storage.readProjectState(base);
|
|
68
|
+
|
|
69
|
+
if (!baseState) {
|
|
70
|
+
return base;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const baseCloudId = baseState?.cloud?.project_id ? String(baseState.cloud.project_id) : null;
|
|
74
|
+
if (!baseCloudId && projectId) {
|
|
75
|
+
return base;
|
|
76
|
+
}
|
|
77
|
+
if (baseCloudId && projectId && baseCloudId === projectId) {
|
|
78
|
+
return base;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const suffix = projectId ? shortStableHex(projectId, 6) : shortStableHex(`${label}:${process.cwd()}:${Date.now()}`, 6);
|
|
82
|
+
const trimmedBase = storage.slugify(label, { maxLength: 64 - (1 + suffix.length) });
|
|
83
|
+
let candidate = `${trimmedBase}-${suffix}`;
|
|
84
|
+
|
|
85
|
+
for (let i = 0; i < 200; i += 1) {
|
|
86
|
+
const s = await storage.readProjectState(candidate);
|
|
87
|
+
if (!s) return candidate;
|
|
88
|
+
const cid = s?.cloud?.project_id ? String(s.cloud.project_id) : null;
|
|
89
|
+
if (projectId && cid === projectId) return candidate;
|
|
90
|
+
candidate = `${trimmedBase}-${suffix}-${i + 1}`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return `${trimmedBase}-${suffix}-${crypto.randomBytes(2).toString('hex')}`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function resolveLocalTaskSlugForCloudTask(storage, projectSlug, task) {
|
|
97
|
+
const { taskId, taskSlug: cloudTaskSlug } = extractCloudTaskIdentity(task);
|
|
98
|
+
const label = cloudTaskSlug || taskId;
|
|
99
|
+
const desired = storage.slugify(label, { maxLength: 64 });
|
|
100
|
+
|
|
101
|
+
const existing = await storage.readTaskState(projectSlug, desired);
|
|
102
|
+
if (!existing) return desired;
|
|
103
|
+
|
|
104
|
+
const existingCloudTaskId = existing?.cloud?.task_id ? String(existing.cloud.task_id) : null;
|
|
105
|
+
if (!existingCloudTaskId && taskId) return desired;
|
|
106
|
+
if (existingCloudTaskId && taskId && existingCloudTaskId === taskId) return desired;
|
|
107
|
+
|
|
108
|
+
const suffix = taskId ? shortStableHex(taskId, 6) : shortStableHex(`${label}:${Date.now()}`, 6);
|
|
109
|
+
const trimmedBase = storage.slugify(label, { maxLength: 64 - (1 + suffix.length) });
|
|
110
|
+
let candidate = `${trimmedBase}-${suffix}`;
|
|
111
|
+
|
|
112
|
+
for (let i = 0; i < 200; i += 1) {
|
|
113
|
+
const st = await storage.readTaskState(projectSlug, candidate);
|
|
114
|
+
if (!st) return candidate;
|
|
115
|
+
const cid = st?.cloud?.task_id ? String(st.cloud.task_id) : null;
|
|
116
|
+
if (taskId && cid === taskId) return candidate;
|
|
117
|
+
candidate = `${trimmedBase}-${suffix}-${i + 1}`;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return `${trimmedBase}-${suffix}-${crypto.randomBytes(2).toString('hex')}`;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function renderWorkingSetMarkdownFromCloudTask(task) {
|
|
124
|
+
const currentPlan = typeof task?.current_plan === 'string' ? task.current_plan.trim() : '';
|
|
125
|
+
const openBlockers = Array.isArray(task?.open_blockers) ? task.open_blockers.filter(Boolean).map(String) : [];
|
|
126
|
+
const nextAction = typeof task?.next_action === 'string' ? task.next_action.trim() : '';
|
|
127
|
+
|
|
128
|
+
if (!currentPlan && openBlockers.length === 0 && !nextAction) return '';
|
|
129
|
+
|
|
130
|
+
const lines = ['# Working Set', ''];
|
|
131
|
+
if (currentPlan) {
|
|
132
|
+
lines.push('## Current Plan', '', currentPlan.trim(), '');
|
|
133
|
+
}
|
|
134
|
+
if (openBlockers.length > 0) {
|
|
135
|
+
lines.push('## Open Blockers', '');
|
|
136
|
+
for (const blocker of openBlockers) lines.push(`- ${blocker}`);
|
|
137
|
+
lines.push('');
|
|
138
|
+
}
|
|
139
|
+
if (nextAction) {
|
|
140
|
+
lines.push('## Next Action', '', nextAction.trim(), '');
|
|
141
|
+
}
|
|
142
|
+
return lines.join('\n').trim() + '\n';
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function createDaemonArtifactsRecorder({ storage, run, taskId }) {
|
|
146
|
+
const promptParts = [];
|
|
147
|
+
const outputParts = [];
|
|
148
|
+
|
|
149
|
+
const pushSection = (arr, title, text) => {
|
|
150
|
+
if (!text) return;
|
|
151
|
+
arr.push(`# ${title}`.trim(), '');
|
|
152
|
+
arr.push(String(text).trim(), '');
|
|
153
|
+
arr.push('---', '');
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
get runPath() {
|
|
158
|
+
return run?.paths?.root || null;
|
|
159
|
+
},
|
|
160
|
+
recordPrompt(title, text) {
|
|
161
|
+
pushSection(promptParts, title, text);
|
|
162
|
+
},
|
|
163
|
+
recordOutput(title, text) {
|
|
164
|
+
pushSection(outputParts, title, text);
|
|
165
|
+
},
|
|
166
|
+
async recordEngineTrace(meta, traceEvent) {
|
|
167
|
+
if (!storage || !run?.paths?.events || !traceEvent) return;
|
|
168
|
+
const safeMeta = meta && typeof meta === 'object' ? meta : {};
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
if (traceEvent.phase === 'start') {
|
|
172
|
+
await storage.appendEvent(
|
|
173
|
+
run.paths.events,
|
|
174
|
+
storage.engineCallStartedEvent({
|
|
175
|
+
trace_id: traceEvent.id,
|
|
176
|
+
label: traceEvent.label,
|
|
177
|
+
provider: safeMeta.provider || null,
|
|
178
|
+
model: safeMeta.model || null,
|
|
179
|
+
role: safeMeta.role || null,
|
|
180
|
+
pid: traceEvent.pid ?? null,
|
|
181
|
+
args: traceEvent.args,
|
|
182
|
+
timeout_ms: traceEvent.timeout_ms,
|
|
183
|
+
started_at: traceEvent.started_at,
|
|
184
|
+
})
|
|
185
|
+
);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (traceEvent.phase === 'exit' || traceEvent.phase === 'error' || traceEvent.phase === 'timeout') {
|
|
190
|
+
await storage.appendEvent(
|
|
191
|
+
run.paths.events,
|
|
192
|
+
storage.engineCallCompletedEvent({
|
|
193
|
+
trace_id: traceEvent.id,
|
|
194
|
+
label: traceEvent.label,
|
|
195
|
+
provider: safeMeta.provider || null,
|
|
196
|
+
model: safeMeta.model || null,
|
|
197
|
+
role: safeMeta.role || null,
|
|
198
|
+
phase: traceEvent.phase,
|
|
199
|
+
exit_code: traceEvent.exit_code ?? null,
|
|
200
|
+
duration_ms: traceEvent.duration_ms,
|
|
201
|
+
finished_at: traceEvent.finished_at,
|
|
202
|
+
stdout_tail: traceEvent.stdout_tail,
|
|
203
|
+
stderr_tail: traceEvent.stderr_tail,
|
|
204
|
+
error: traceEvent.error,
|
|
205
|
+
})
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
} catch {
|
|
209
|
+
// Never let trace/event writing break daemon execution.
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
async flush() {
|
|
213
|
+
const promptText = promptParts.join('\n').trim() + '\n';
|
|
214
|
+
const outputText = outputParts.join('\n').trim() + '\n';
|
|
215
|
+
|
|
216
|
+
if (promptText.trim()) {
|
|
217
|
+
const totalBytes = Buffer.byteLength(promptText, 'utf8');
|
|
218
|
+
const event = storage.promptBuiltEvent({ sections: { daemon: totalBytes }, total_bytes: totalBytes });
|
|
219
|
+
await storage.writePrompt(run, promptText, event);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (outputText.trim()) {
|
|
223
|
+
await storage.writeOutput(run, outputText);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
await storage.appendEvent(run.paths.events, { t: 'DAEMON_ARTIFACTS_FLUSHED', task_id: taskId });
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function localArtifactKey(filePath) {
|
|
232
|
+
const host = os.hostname();
|
|
233
|
+
const p = String(filePath || '');
|
|
234
|
+
if (!p) return `local://${host}/`;
|
|
235
|
+
return `local://${host}${p.startsWith('/') ? '' : '/'}${p}`;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async function buildLocalRunIndexEntry(storage, run, status) {
|
|
239
|
+
if (!storage || !run?.paths?.root) return null;
|
|
240
|
+
|
|
241
|
+
const maxShaBytes = Number(process.env.AGX_LOCAL_ARTIFACT_SHA_MAX_BYTES || 5 * 1024 * 1024);
|
|
242
|
+
const shaMax = Number.isFinite(maxShaBytes) && maxShaBytes > 0 ? maxShaBytes : 5 * 1024 * 1024;
|
|
243
|
+
|
|
244
|
+
const sha256File = async (filePath) => {
|
|
245
|
+
const stat = await fs.promises.stat(filePath);
|
|
246
|
+
if (stat.size > shaMax) {
|
|
247
|
+
return { bytes: stat.size, sha256: undefined };
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return new Promise((resolve, reject) => {
|
|
251
|
+
const hash = crypto.createHash('sha256');
|
|
252
|
+
const stream = fs.createReadStream(filePath);
|
|
253
|
+
stream.on('data', (chunk) => hash.update(chunk));
|
|
254
|
+
stream.on('error', reject);
|
|
255
|
+
stream.on('end', () => resolve({ bytes: stat.size, sha256: hash.digest('hex') }));
|
|
256
|
+
});
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
const tryRef = async (kind, filePath) => {
|
|
260
|
+
try {
|
|
261
|
+
const { bytes, sha256 } = await sha256File(filePath);
|
|
262
|
+
return { kind, key: localArtifactKey(filePath), bytes, sha256 };
|
|
263
|
+
} catch {
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const meta = await storage.readJsonSafe(run.paths.meta);
|
|
269
|
+
const createdAt = meta?.created_at || new Date().toISOString();
|
|
270
|
+
|
|
271
|
+
const manifest = [];
|
|
272
|
+
manifest.push({ kind: 'artifact', key: localArtifactKey(run.paths.root) });
|
|
273
|
+
|
|
274
|
+
const promptRef = await tryRef('prompt', run.paths.prompt);
|
|
275
|
+
if (promptRef) manifest.push(promptRef);
|
|
276
|
+
|
|
277
|
+
const outputRef = await tryRef('output', run.paths.output);
|
|
278
|
+
if (outputRef) manifest.push(outputRef);
|
|
279
|
+
|
|
280
|
+
const eventsRef = await tryRef('events', run.paths.events);
|
|
281
|
+
if (eventsRef) manifest.push(eventsRef);
|
|
282
|
+
|
|
283
|
+
const decisionRef = await tryRef('artifact', run.paths.decision);
|
|
284
|
+
if (decisionRef) manifest.push({ ...decisionRef, kind: 'artifact' });
|
|
285
|
+
|
|
286
|
+
return {
|
|
287
|
+
run_id: run.run_id,
|
|
288
|
+
stage: run.stage,
|
|
289
|
+
engine: meta?.engine || meta?.provider || meta?.engine_name || run.engine || 'unknown',
|
|
290
|
+
model: meta?.model || null,
|
|
291
|
+
status: String(status || 'unknown'),
|
|
292
|
+
created_at: createdAt,
|
|
293
|
+
artifact_manifest: manifest,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function saveAugmentedPrompt(content, debug = false) {
|
|
298
|
+
if (!content) return;
|
|
299
|
+
const CONFIG_DIR = path.join(process.env.HOME || process.env.USERPROFILE, '.agx');
|
|
300
|
+
const AUGMENTED_PROMPT_FILE = path.join(CONFIG_DIR, 'augmented-prompt.txt');
|
|
301
|
+
try {
|
|
302
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
303
|
+
fs.writeFileSync(AUGMENTED_PROMPT_FILE, `${content}\n`, 'utf8');
|
|
304
|
+
} catch (err) {
|
|
305
|
+
if (debug) {
|
|
306
|
+
console.error(`Failed to write augmented prompt to ${AUGMENTED_PROMPT_FILE}:`, err?.message || err);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function extractSection(markdown, heading) {
|
|
312
|
+
if (!markdown) return '';
|
|
313
|
+
const pattern = new RegExp(`^##\\s+${heading}\\s*$`, 'im');
|
|
314
|
+
const match = pattern.exec(markdown);
|
|
315
|
+
if (!match) return '';
|
|
316
|
+
const start = match.index + match[0].length;
|
|
317
|
+
const rest = markdown.slice(start);
|
|
318
|
+
const next = rest.search(/^##\s+/im);
|
|
319
|
+
const section = next === -1 ? rest : rest.slice(0, next);
|
|
320
|
+
return section.trim();
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function buildFullDaemonPromptContext(task, options = {}) {
|
|
324
|
+
const comments = Array.isArray(options.comments) ? options.comments : [];
|
|
325
|
+
const provider = options.provider || task?.engine || task?.provider || 'unknown';
|
|
326
|
+
const model = options.model || task?.model || null;
|
|
327
|
+
const iterationPrompt = options.iterationPrompt || '';
|
|
328
|
+
|
|
329
|
+
const plan = extractSection(task?.content, 'Plan');
|
|
330
|
+
const todo = extractSection(task?.content, 'Todo') || extractSection(task?.content, 'TODO');
|
|
331
|
+
const checkpoints = extractSection(task?.content, 'Checkpoints');
|
|
332
|
+
const learnings = extractSection(task?.content, 'Learnings');
|
|
333
|
+
|
|
334
|
+
const stageKey = task?.stage || 'unknown';
|
|
335
|
+
const stagePrompt = typeof options.resolveStageObjective === 'function'
|
|
336
|
+
? options.resolveStageObjective(task, stageKey, '')
|
|
337
|
+
: '';
|
|
338
|
+
const stageRequirement = typeof options.buildStageRequirementPrompt === 'function'
|
|
339
|
+
? options.buildStageRequirementPrompt({ stage: stageKey, stagePrompt })
|
|
340
|
+
: '';
|
|
341
|
+
|
|
342
|
+
const commentsSection = comments.length > 0
|
|
343
|
+
? comments.map((c) => `${c.author || 'user'}: ${c.content || ''}`).join('\n')
|
|
344
|
+
: '(no comments yet)';
|
|
345
|
+
|
|
346
|
+
let prompt = `## Cloud Task Context
|
|
347
|
+
|
|
348
|
+
You are continuing a cloud task. Here is the current state:
|
|
349
|
+
|
|
350
|
+
Task ID: ${task?.id || 'unknown'}
|
|
351
|
+
Title: ${task?.title || 'Untitled'}
|
|
352
|
+
Stage: ${task?.stage || 'ideation'}
|
|
353
|
+
Stage Objective: ${stagePrompt}
|
|
354
|
+
Stage Completion Requirement (guidance): ${stageRequirement}
|
|
355
|
+
Provider: ${provider}${model ? `/${model}` : ''}
|
|
356
|
+
|
|
357
|
+
User Request:
|
|
358
|
+
"""
|
|
359
|
+
${task?.title || ''}
|
|
360
|
+
${task?.content || ''}
|
|
361
|
+
---
|
|
362
|
+
Task Thread:
|
|
363
|
+
${commentsSection}
|
|
364
|
+
"""
|
|
365
|
+
|
|
366
|
+
## Extracted State
|
|
367
|
+
|
|
368
|
+
Goal: ${task?.title || 'Untitled'}
|
|
369
|
+
Plan: ${plan || '(none)'}
|
|
370
|
+
Todo: ${todo || '(none)'}
|
|
371
|
+
Checkpoints: ${checkpoints || '(none)'}
|
|
372
|
+
Learnings: ${learnings || '(none)'}
|
|
373
|
+
|
|
374
|
+
## Instructions
|
|
375
|
+
|
|
376
|
+
Continue working on this task. Use the cloud API to sync progress.
|
|
377
|
+
Respect the Stage Completion Requirement before using [complete] or [done].
|
|
378
|
+
|
|
379
|
+
To update the task:
|
|
380
|
+
- [done] - Mark task complete
|
|
381
|
+
- [complete: message] - Complete current stage
|
|
382
|
+
- [log: message] - Add a log entry
|
|
383
|
+
- [checkpoint: message] - Save progress checkpoint
|
|
384
|
+
- [learn: insight] - Record a learning
|
|
385
|
+
- [plan: text] - Update plan
|
|
386
|
+
- [todo: text] - Update todo list
|
|
387
|
+
`;
|
|
388
|
+
|
|
389
|
+
if (iterationPrompt) {
|
|
390
|
+
prompt += `\nYour specific task for this iteration: ${iterationPrompt}\n`;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
return prompt;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function parseFrontmatterFromContent(content) {
|
|
397
|
+
if (!content) return {};
|
|
398
|
+
const match = content.match(/^---\n([\s\S]*?)\n---\n/);
|
|
399
|
+
if (!match) return {};
|
|
400
|
+
const frontmatter = {};
|
|
401
|
+
const lines = match[1].split('\n');
|
|
402
|
+
for (const line of lines) {
|
|
403
|
+
const colonIndex = line.indexOf(':');
|
|
404
|
+
if (colonIndex > 0) {
|
|
405
|
+
const key = line.slice(0, colonIndex).trim();
|
|
406
|
+
const value = line.slice(colonIndex + 1).trim();
|
|
407
|
+
if (key) frontmatter[key] = value;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return frontmatter;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
function normalizeTicketType(value) {
|
|
414
|
+
if (typeof value !== 'string') return 'task';
|
|
415
|
+
const normalized = value.trim().toLowerCase();
|
|
416
|
+
if (!normalized) return 'task';
|
|
417
|
+
if (normalized === 'spike' || normalized === 'spikes') return 'spike';
|
|
418
|
+
return 'task';
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function resolveTaskTicketType(task) {
|
|
422
|
+
const frontmatter = parseFrontmatterFromContent(task?.content || '');
|
|
423
|
+
const candidates = [
|
|
424
|
+
task?.ticket_type,
|
|
425
|
+
task?.type,
|
|
426
|
+
task?.issue_type,
|
|
427
|
+
task?.kind,
|
|
428
|
+
frontmatter.ticket_type,
|
|
429
|
+
frontmatter.type,
|
|
430
|
+
frontmatter.issue_type,
|
|
431
|
+
frontmatter.kind,
|
|
432
|
+
];
|
|
433
|
+
for (const candidate of candidates) {
|
|
434
|
+
const resolved = normalizeTicketType(candidate);
|
|
435
|
+
if (resolved === 'spike') return 'spike';
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
const title = String(task?.title || '').trim().toLowerCase();
|
|
439
|
+
if (title.startsWith('spike:') || title.startsWith('[spike]')) {
|
|
440
|
+
return 'spike';
|
|
441
|
+
}
|
|
442
|
+
return 'task';
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
function parseList(value) {
|
|
446
|
+
if (!value || typeof value !== 'string') return [];
|
|
447
|
+
const trimmed = value.trim();
|
|
448
|
+
if (!trimmed) return [];
|
|
449
|
+
if (trimmed.startsWith('[') && trimmed.endsWith(']')) {
|
|
450
|
+
try {
|
|
451
|
+
const parsed = JSON.parse(trimmed);
|
|
452
|
+
if (Array.isArray(parsed)) {
|
|
453
|
+
return parsed.map((v) => String(v).trim()).filter(Boolean);
|
|
454
|
+
}
|
|
455
|
+
} catch { }
|
|
456
|
+
}
|
|
457
|
+
return trimmed
|
|
458
|
+
.split(',')
|
|
459
|
+
.map((v) => v.trim())
|
|
460
|
+
.filter(Boolean);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
module.exports = {
|
|
464
|
+
isLocalArtifactsEnabled,
|
|
465
|
+
mapCloudStageToLocalStage,
|
|
466
|
+
extractCloudProjectIdentity,
|
|
467
|
+
extractCloudTaskIdentity,
|
|
468
|
+
resolveLocalProjectSlugForCloudTask,
|
|
469
|
+
resolveLocalTaskSlugForCloudTask,
|
|
470
|
+
renderWorkingSetMarkdownFromCloudTask,
|
|
471
|
+
createDaemonArtifactsRecorder,
|
|
472
|
+
buildLocalRunIndexEntry,
|
|
473
|
+
saveAugmentedPrompt,
|
|
474
|
+
buildFullDaemonPromptContext,
|
|
475
|
+
resolveTaskTicketType,
|
|
476
|
+
parseList,
|
|
477
|
+
};
|
|
478
|
+
|
package/lib/cli/onboarding.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
const { c } = require('../ui/colors');
|
|
5
5
|
const { loadConfig, saveConfig, prompt } = require('./configStore');
|
|
6
|
+
const { loadCloudConfigFile, saveCloudConfigFile, DEFAULT_API_URL } = require('../config/cloudConfig');
|
|
6
7
|
const {
|
|
7
8
|
PROVIDERS,
|
|
8
9
|
detectProviders,
|
|
@@ -177,6 +178,9 @@ async function showConfigStatus() {
|
|
|
177
178
|
if (config?.settingsMeta?.changedAt) {
|
|
178
179
|
console.log(` Settings changed: ${c.dim}${config.settingsMeta.changedAt}${c.reset} (${config.settingsMeta.provenance || 'unknown'})`);
|
|
179
180
|
}
|
|
181
|
+
const cloudConfig = loadCloudConfigFile();
|
|
182
|
+
const cloudUrl = cloudConfig?.apiUrl || DEFAULT_API_URL;
|
|
183
|
+
console.log(` Backend URL: ${c.cyan}${cloudUrl}${c.reset}`);
|
|
180
184
|
} else {
|
|
181
185
|
console.log(` ${c.yellow}Not configured${c.reset} - run ${c.cyan}agx init${c.reset}`);
|
|
182
186
|
}
|
|
@@ -195,8 +199,9 @@ async function runConfigMenu() {
|
|
|
195
199
|
console.log(` ${c.cyan}1${c.reset}) Install a new provider`);
|
|
196
200
|
console.log(` ${c.cyan}2${c.reset}) Login to a provider`);
|
|
197
201
|
console.log(` ${c.cyan}3${c.reset}) Change default provider`);
|
|
198
|
-
console.log(` ${c.cyan}4${c.reset})
|
|
199
|
-
console.log(` ${c.cyan}5${c.reset})
|
|
202
|
+
console.log(` ${c.cyan}4${c.reset}) Set backend URL`);
|
|
203
|
+
console.log(` ${c.cyan}5${c.reset}) Show status`);
|
|
204
|
+
console.log(` ${c.cyan}6${c.reset}) Run full setup wizard`);
|
|
200
205
|
console.log(` ${c.cyan}q${c.reset}) Quit`);
|
|
201
206
|
|
|
202
207
|
const choice = await prompt('\nChoice: ');
|
|
@@ -256,10 +261,24 @@ async function runConfigMenu() {
|
|
|
256
261
|
}
|
|
257
262
|
break;
|
|
258
263
|
}
|
|
259
|
-
case '4':
|
|
260
|
-
|
|
264
|
+
case '4': {
|
|
265
|
+
const cloudConfig = loadCloudConfigFile();
|
|
266
|
+
const currentUrl = cloudConfig?.apiUrl || DEFAULT_API_URL;
|
|
267
|
+
console.log(`\n Current backend URL: ${c.cyan}${currentUrl}${c.reset}`);
|
|
268
|
+
const newUrl = await prompt(`\n New URL [${c.dim}${currentUrl}${c.reset}]: `);
|
|
269
|
+
if (newUrl && newUrl.trim()) {
|
|
270
|
+
const updated = { ...(cloudConfig || {}), apiUrl: newUrl.trim() };
|
|
271
|
+
saveCloudConfigFile(updated);
|
|
272
|
+
console.log(`\n${c.green}✓${c.reset} Backend URL set to ${c.cyan}${newUrl.trim()}${c.reset}`);
|
|
273
|
+
} else {
|
|
274
|
+
console.log(`\n${c.dim}Keeping current URL${c.reset}`);
|
|
275
|
+
}
|
|
261
276
|
break;
|
|
277
|
+
}
|
|
262
278
|
case '5':
|
|
279
|
+
await showConfigStatus();
|
|
280
|
+
break;
|
|
281
|
+
case '6':
|
|
263
282
|
await runOnboarding();
|
|
264
283
|
break;
|
|
265
284
|
case 'q':
|