heyatlas 1.8.2 → 1.9.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/dist/cli.js +98 -46
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -5559,6 +5559,22 @@ class AtlasTunnel {
|
|
|
5559
5559
|
};
|
|
5560
5560
|
});
|
|
5561
5561
|
}
|
|
5562
|
+
async waitForState(timeoutMs = 1e4) {
|
|
5563
|
+
if (this.currentState)
|
|
5564
|
+
return;
|
|
5565
|
+
return new Promise((resolve, reject) => {
|
|
5566
|
+
const timeout = setTimeout(() => reject(new Error("Timed out waiting for state")), timeoutMs);
|
|
5567
|
+
const check = () => {
|
|
5568
|
+
if (this.currentState) {
|
|
5569
|
+
clearTimeout(timeout);
|
|
5570
|
+
resolve();
|
|
5571
|
+
} else {
|
|
5572
|
+
setTimeout(check, 100);
|
|
5573
|
+
}
|
|
5574
|
+
};
|
|
5575
|
+
check();
|
|
5576
|
+
});
|
|
5577
|
+
}
|
|
5562
5578
|
handleStateUpdate(state, source) {
|
|
5563
5579
|
if (source === "server") {
|
|
5564
5580
|
this.currentState = state;
|
|
@@ -52193,19 +52209,14 @@ You coordinate the following specialized subagents — delegate to them via the
|
|
|
52193
52209
|
|
|
52194
52210
|
- Always create a plan before executing
|
|
52195
52211
|
- Update your plan as tasks progress
|
|
52196
|
-
- Use absolute paths for all file operations
|
|
52212
|
+
- Use absolute paths for all file operations — save outputs under /home/user/output/
|
|
52197
52213
|
- If you encounter auth barriers (logins, CAPTCHAs), ask the user to complete the manual step
|
|
52198
|
-
-
|
|
52214
|
+
- **MANDATORY**: After ALL file-producing tasks, you MUST upload outputs to R2 before summarizing. This is not optional.
|
|
52199
52215
|
|
|
52200
|
-
## Output Upload
|
|
52216
|
+
## Output Upload (REQUIRED)
|
|
52201
52217
|
|
|
52202
|
-
|
|
52218
|
+
You MUST upload every output file to cloud storage. Tasks are not complete without this step.
|
|
52203
52219
|
|
|
52204
|
-
1. Read \\\`/home/user/agents/task-meta.json\\\` to get the bucket name, userId, and taskId
|
|
52205
|
-
2. Upload all output files using: \\\`rclone copy <file-or-dir> r2:<bucket>/<userId>/<taskId>/\\\`
|
|
52206
|
-
3. Include the uploaded file paths in your summary
|
|
52207
|
-
|
|
52208
|
-
Example:
|
|
52209
52220
|
\\\`\\\`\\\`bash
|
|
52210
52221
|
# Read task metadata
|
|
52211
52222
|
META=$(cat /home/user/agents/task-meta.json)
|
|
@@ -52214,12 +52225,14 @@ USER_ID=$(echo $META | jq -r '.userId')
|
|
|
52214
52225
|
TASK_ID=$(echo $META | jq -r '.taskId')
|
|
52215
52226
|
PUBLIC_URL=$(echo $META | jq -r '.publicUrl')
|
|
52216
52227
|
|
|
52217
|
-
# Upload output files
|
|
52218
|
-
rclone copy /home/user/output
|
|
52228
|
+
# Upload ALL output files
|
|
52229
|
+
rclone copy /home/user/output/ r2:$BUCKET/$USER_ID/$TASK_ID/
|
|
52230
|
+
|
|
52231
|
+
# Report public URLs for each file
|
|
52232
|
+
echo "File available at: $PUBLIC_URL/$USER_ID/$TASK_ID/<filename>"
|
|
52233
|
+
\\\`\\\`\\\`
|
|
52219
52234
|
|
|
52220
|
-
|
|
52221
|
-
echo "File available at: $PUBLIC_URL/$USER_ID/$TASK_ID/output.docx"
|
|
52222
|
-
\\\`\\\`\\\``,
|
|
52235
|
+
Your final summary MUST include the public URL for every uploaded file.`,
|
|
52223
52236
|
"smith-browser.md": `---
|
|
52224
52237
|
description: Browser automation expert — navigates websites, fills forms, extracts data, and performs interactive web workflows
|
|
52225
52238
|
mode: subagent
|
|
@@ -52339,7 +52352,7 @@ You are a Documentation Specialist responsible for creating, modifying, and mana
|
|
|
52339
52352
|
|
|
52340
52353
|
- If no format is specified, create an HTML file
|
|
52341
52354
|
- For data-heavy documents, generate charts using Python and embed them
|
|
52342
|
-
-
|
|
52355
|
+
- Save ALL output files under /home/user/output/ (create directory if needed)
|
|
52343
52356
|
- When complete, provide the file path and a summary
|
|
52344
52357
|
|
|
52345
52358
|
## Rules
|
|
@@ -52347,6 +52360,7 @@ You are a Documentation Specialist responsible for creating, modifying, and mana
|
|
|
52347
52360
|
- Primary output should be files, not just text in response
|
|
52348
52361
|
- Use bash tools for data processing, visualization, and file operations
|
|
52349
52362
|
- For charts: write a Python script using plotly/matplotlib, execute it, save output as image
|
|
52363
|
+
- **ALWAYS save files to /home/user/output/** — this is required for upload to work
|
|
52350
52364
|
- Provide a clear summary of work done and paths to created files`
|
|
52351
52365
|
};
|
|
52352
52366
|
var SMITH_OPENCODE_JSONC = `{
|
|
@@ -52574,6 +52588,7 @@ async function connect(agentType, options = {}) {
|
|
|
52574
52588
|
const taskData = JSON.parse(fs.readFileSync(options.taskFile, "utf-8"));
|
|
52575
52589
|
console.log(`Task: ${taskData.description.slice(0, 80)}...`);
|
|
52576
52590
|
await tunnel.connect(credentials.userId, agent.name);
|
|
52591
|
+
await tunnel.waitForState();
|
|
52577
52592
|
console.log("Tunnel established");
|
|
52578
52593
|
try {
|
|
52579
52594
|
await handleTask(taskData, agent, tunnel);
|
|
@@ -52645,7 +52660,7 @@ async function handleTask(task, agent, tunnel) {
|
|
|
52645
52660
|
{ type: "ui_message", timestamp: Date.now(), data: { id: crypto.randomUUID(), role: "assistant", parts } }
|
|
52646
52661
|
]);
|
|
52647
52662
|
}
|
|
52648
|
-
const outputs =
|
|
52663
|
+
const outputs = await uploadTaskOutputs(task.id);
|
|
52649
52664
|
await tunnel.updateTask(task.id, {
|
|
52650
52665
|
state: "completed",
|
|
52651
52666
|
result: "end_turn",
|
|
@@ -52777,40 +52792,77 @@ Please continue based on the above context.`;
|
|
|
52777
52792
|
}
|
|
52778
52793
|
return { prompt, latestUserMessage };
|
|
52779
52794
|
}
|
|
52780
|
-
function
|
|
52781
|
-
const
|
|
52782
|
-
const
|
|
52783
|
-
|
|
52784
|
-
|
|
52785
|
-
|
|
52786
|
-
|
|
52787
|
-
|
|
52788
|
-
|
|
52789
|
-
|
|
52790
|
-
|
|
52791
|
-
|
|
52795
|
+
async function uploadTaskOutputs(taskId) {
|
|
52796
|
+
const fs = await import("fs");
|
|
52797
|
+
const path = await import("path");
|
|
52798
|
+
const { execSync } = await import("child_process");
|
|
52799
|
+
const metaPath = "/home/user/agents/task-meta.json";
|
|
52800
|
+
if (!fs.existsSync(metaPath))
|
|
52801
|
+
return [];
|
|
52802
|
+
let meta3;
|
|
52803
|
+
try {
|
|
52804
|
+
meta3 = JSON.parse(fs.readFileSync(metaPath, "utf-8"));
|
|
52805
|
+
} catch {
|
|
52806
|
+
return [];
|
|
52807
|
+
}
|
|
52808
|
+
if (!meta3.publicUrl || !meta3.bucket)
|
|
52809
|
+
return [];
|
|
52810
|
+
const outputFiles = [];
|
|
52811
|
+
const scanDirs = ["/home/user/output", "/home/user"];
|
|
52812
|
+
const skipDirs = new Set(["agents", ".opencode", ".heyatlas", ".config", ".npm", ".local", ".cache", "node_modules"]);
|
|
52813
|
+
const outputExts = new Set(["docx", "xlsx", "pptx", "pdf", "html", "csv", "json", "png", "jpg", "jpeg", "gif", "svg", "zip", "tar", "md", "txt"]);
|
|
52814
|
+
for (const dir of scanDirs) {
|
|
52815
|
+
if (!fs.existsSync(dir))
|
|
52816
|
+
continue;
|
|
52817
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
52818
|
+
for (const entry of entries) {
|
|
52819
|
+
if (entry.isDirectory() && dir === "/home/user") {
|
|
52820
|
+
if (skipDirs.has(entry.name) || entry.name.startsWith("."))
|
|
52792
52821
|
continue;
|
|
52793
|
-
const
|
|
52794
|
-
|
|
52795
|
-
|
|
52796
|
-
|
|
52797
|
-
|
|
52798
|
-
|
|
52799
|
-
|
|
52800
|
-
|
|
52801
|
-
|
|
52802
|
-
|
|
52803
|
-
|
|
52804
|
-
|
|
52805
|
-
|
|
52806
|
-
url: url3,
|
|
52807
|
-
filename: decodeURIComponent(filename),
|
|
52808
|
-
type: typeMap[ext] || undefined
|
|
52809
|
-
});
|
|
52822
|
+
const subDir = path.join(dir, entry.name);
|
|
52823
|
+
const subEntries = fs.readdirSync(subDir, { withFileTypes: true });
|
|
52824
|
+
for (const sub of subEntries) {
|
|
52825
|
+
if (sub.isFile()) {
|
|
52826
|
+
const ext = sub.name.split(".").pop()?.toLowerCase();
|
|
52827
|
+
if (ext && outputExts.has(ext))
|
|
52828
|
+
outputFiles.push(path.join(subDir, sub.name));
|
|
52829
|
+
}
|
|
52830
|
+
}
|
|
52831
|
+
} else if (entry.isFile()) {
|
|
52832
|
+
const ext = entry.name.split(".").pop()?.toLowerCase();
|
|
52833
|
+
if (ext && outputExts.has(ext))
|
|
52834
|
+
outputFiles.push(path.join(dir, entry.name));
|
|
52810
52835
|
}
|
|
52811
52836
|
}
|
|
52812
52837
|
}
|
|
52813
|
-
|
|
52838
|
+
if (outputFiles.length === 0)
|
|
52839
|
+
return [];
|
|
52840
|
+
const r2Dest = `r2:${meta3.bucket}/${meta3.userId}/${meta3.taskId}`;
|
|
52841
|
+
const outputs = [];
|
|
52842
|
+
const typeMap = {
|
|
52843
|
+
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
52844
|
+
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
52845
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
52846
|
+
pdf: "application/pdf",
|
|
52847
|
+
html: "text/html",
|
|
52848
|
+
png: "image/png",
|
|
52849
|
+
jpg: "image/jpeg",
|
|
52850
|
+
jpeg: "image/jpeg",
|
|
52851
|
+
csv: "text/csv"
|
|
52852
|
+
};
|
|
52853
|
+
for (const filePath of outputFiles) {
|
|
52854
|
+
const filename = path.basename(filePath);
|
|
52855
|
+
try {
|
|
52856
|
+
execSync(`rclone copyto "${filePath}" "${r2Dest}/${filename}"`, { stdio: "pipe", timeout: 30000 });
|
|
52857
|
+
const ext = filename.split(".").pop()?.toLowerCase() || "";
|
|
52858
|
+
const publicUrl = `${meta3.publicUrl.replace(/\/$/, "")}/${meta3.userId}/${meta3.taskId}/${filename}`;
|
|
52859
|
+
outputs.push({ url: publicUrl, filename, type: typeMap[ext] });
|
|
52860
|
+
console.log(`Uploaded: ${filename}`);
|
|
52861
|
+
} catch (e) {
|
|
52862
|
+
console.error(`Failed to upload ${filename}:`, e instanceof Error ? e.message : e);
|
|
52863
|
+
}
|
|
52864
|
+
}
|
|
52865
|
+
return outputs;
|
|
52814
52866
|
}
|
|
52815
52867
|
function openBrowser(url3) {
|
|
52816
52868
|
try {
|