heyatlas 1.8.0 → 1.9.0
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 +113 -9
- 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;
|
|
@@ -52195,7 +52211,31 @@ You coordinate the following specialized subagents — delegate to them via the
|
|
|
52195
52211
|
- Update your plan as tasks progress
|
|
52196
52212
|
- Use absolute paths for all file operations
|
|
52197
52213
|
- If you encounter auth barriers (logins, CAPTCHAs), ask the user to complete the manual step
|
|
52198
|
-
- Provide a comprehensive summary when done
|
|
52214
|
+
- Provide a comprehensive summary when done
|
|
52215
|
+
|
|
52216
|
+
## Output Upload
|
|
52217
|
+
|
|
52218
|
+
After completing a task that produces files, upload them to cloud storage using rclone:
|
|
52219
|
+
|
|
52220
|
+
1. Read \\\`/home/user/agents/task-meta.json\\\` to get the bucket name, userId, and taskId
|
|
52221
|
+
2. Upload all output files using: \\\`rclone copy <file-or-dir> r2:<bucket>/<userId>/<taskId>/\\\`
|
|
52222
|
+
3. Include the uploaded file paths in your summary
|
|
52223
|
+
|
|
52224
|
+
Example:
|
|
52225
|
+
\\\`\\\`\\\`bash
|
|
52226
|
+
# Read task metadata
|
|
52227
|
+
META=$(cat /home/user/agents/task-meta.json)
|
|
52228
|
+
BUCKET=$(echo $META | jq -r '.bucket')
|
|
52229
|
+
USER_ID=$(echo $META | jq -r '.userId')
|
|
52230
|
+
TASK_ID=$(echo $META | jq -r '.taskId')
|
|
52231
|
+
PUBLIC_URL=$(echo $META | jq -r '.publicUrl')
|
|
52232
|
+
|
|
52233
|
+
# Upload output files
|
|
52234
|
+
rclone copy /home/user/output.docx r2:$BUCKET/$USER_ID/$TASK_ID/
|
|
52235
|
+
|
|
52236
|
+
# Share the public URL
|
|
52237
|
+
echo "File available at: $PUBLIC_URL/$USER_ID/$TASK_ID/output.docx"
|
|
52238
|
+
\\\`\\\`\\\``,
|
|
52199
52239
|
"smith-browser.md": `---
|
|
52200
52240
|
description: Browser automation expert — navigates websites, fills forms, extracts data, and performs interactive web workflows
|
|
52201
52241
|
mode: subagent
|
|
@@ -52545,6 +52585,26 @@ async function connect(agentType, options = {}) {
|
|
|
52545
52585
|
interactive: true,
|
|
52546
52586
|
agentType: options.agentType || "local"
|
|
52547
52587
|
});
|
|
52588
|
+
if (options.taskFile) {
|
|
52589
|
+
const fs = await import("fs");
|
|
52590
|
+
const taskData = JSON.parse(fs.readFileSync(options.taskFile, "utf-8"));
|
|
52591
|
+
console.log(`Task: ${taskData.description.slice(0, 80)}...`);
|
|
52592
|
+
await tunnel.connect(credentials.userId, agent.name);
|
|
52593
|
+
await tunnel.waitForState();
|
|
52594
|
+
console.log("Tunnel established");
|
|
52595
|
+
try {
|
|
52596
|
+
await handleTask(taskData, agent, tunnel);
|
|
52597
|
+
console.log(`
|
|
52598
|
+
Task complete. Disconnecting...`);
|
|
52599
|
+
} catch (error87) {
|
|
52600
|
+
console.error(`Task failed: ${error87}`);
|
|
52601
|
+
} finally {
|
|
52602
|
+
agent.cleanup();
|
|
52603
|
+
await tunnel.disconnect();
|
|
52604
|
+
process.exit(0);
|
|
52605
|
+
}
|
|
52606
|
+
return;
|
|
52607
|
+
}
|
|
52548
52608
|
tunnel.onNewTask(async (task) => {
|
|
52549
52609
|
await handleTask(task, agent, tunnel);
|
|
52550
52610
|
});
|
|
@@ -52602,7 +52662,12 @@ async function handleTask(task, agent, tunnel) {
|
|
|
52602
52662
|
{ type: "ui_message", timestamp: Date.now(), data: { id: crypto.randomUUID(), role: "assistant", parts } }
|
|
52603
52663
|
]);
|
|
52604
52664
|
}
|
|
52605
|
-
|
|
52665
|
+
const outputs = extractOutputUrls(parts);
|
|
52666
|
+
await tunnel.updateTask(task.id, {
|
|
52667
|
+
state: "completed",
|
|
52668
|
+
result: "end_turn",
|
|
52669
|
+
...outputs.length > 0 ? { outputs } : {}
|
|
52670
|
+
});
|
|
52606
52671
|
console.log("Task completed");
|
|
52607
52672
|
} catch (error87) {
|
|
52608
52673
|
console.error(`Task failed: ${error87}`);
|
|
@@ -52729,6 +52794,41 @@ Please continue based on the above context.`;
|
|
|
52729
52794
|
}
|
|
52730
52795
|
return { prompt, latestUserMessage };
|
|
52731
52796
|
}
|
|
52797
|
+
function extractOutputUrls(parts) {
|
|
52798
|
+
const outputs = [];
|
|
52799
|
+
const urlPattern = /https?:\/\/[^\s"'<>]+/g;
|
|
52800
|
+
for (const part of parts) {
|
|
52801
|
+
if (part.type === "text" && typeof part.text === "string") {
|
|
52802
|
+
const matches = part.text.match(urlPattern);
|
|
52803
|
+
if (!matches)
|
|
52804
|
+
continue;
|
|
52805
|
+
for (const url3 of matches) {
|
|
52806
|
+
const filename = url3.split("/").pop() || "";
|
|
52807
|
+
const ext = filename.includes(".") ? filename.split(".").pop()?.toLowerCase() : null;
|
|
52808
|
+
if (!ext)
|
|
52809
|
+
continue;
|
|
52810
|
+
const typeMap = {
|
|
52811
|
+
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
52812
|
+
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
52813
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
52814
|
+
pdf: "application/pdf",
|
|
52815
|
+
html: "text/html",
|
|
52816
|
+
png: "image/png",
|
|
52817
|
+
jpg: "image/jpeg",
|
|
52818
|
+
jpeg: "image/jpeg",
|
|
52819
|
+
csv: "text/csv",
|
|
52820
|
+
json: "application/json"
|
|
52821
|
+
};
|
|
52822
|
+
outputs.push({
|
|
52823
|
+
url: url3,
|
|
52824
|
+
filename: decodeURIComponent(filename),
|
|
52825
|
+
type: typeMap[ext] || undefined
|
|
52826
|
+
});
|
|
52827
|
+
}
|
|
52828
|
+
}
|
|
52829
|
+
}
|
|
52830
|
+
return [...new Map(outputs.map((o) => [o.url, o])).values()];
|
|
52831
|
+
}
|
|
52732
52832
|
function openBrowser(url3) {
|
|
52733
52833
|
try {
|
|
52734
52834
|
const { execSync } = __require("child_process");
|
|
@@ -52758,7 +52858,8 @@ var { positionals, values } = parseArgs({
|
|
|
52758
52858
|
options: {
|
|
52759
52859
|
help: { type: "boolean", short: "h" },
|
|
52760
52860
|
version: { type: "boolean", short: "v" },
|
|
52761
|
-
"no-browser": { type: "boolean" }
|
|
52861
|
+
"no-browser": { type: "boolean" },
|
|
52862
|
+
"task-file": { type: "string" }
|
|
52762
52863
|
},
|
|
52763
52864
|
allowPositionals: true
|
|
52764
52865
|
});
|
|
@@ -52773,13 +52874,15 @@ Supported Agents:
|
|
|
52773
52874
|
${SUPPORTED_AGENTS.join(", ")}
|
|
52774
52875
|
|
|
52775
52876
|
Options:
|
|
52776
|
-
-h, --help
|
|
52777
|
-
-v, --version
|
|
52778
|
-
--no-browser
|
|
52877
|
+
-h, --help Show this help message
|
|
52878
|
+
-v, --version Show version
|
|
52879
|
+
--no-browser Don't open browser automatically
|
|
52880
|
+
--task-file <path> Run a single task from a JSON file and exit
|
|
52779
52881
|
|
|
52780
52882
|
Examples:
|
|
52781
|
-
heyatlas connect opencode
|
|
52782
|
-
heyatlas connect smith
|
|
52883
|
+
heyatlas connect opencode Connect OpenCode via ACP
|
|
52884
|
+
heyatlas connect smith Connect Smith via OpenCode
|
|
52885
|
+
heyatlas connect smith --task-file task.json Run a single task and exit
|
|
52783
52886
|
`);
|
|
52784
52887
|
}
|
|
52785
52888
|
async function main() {
|
|
@@ -52806,7 +52909,8 @@ async function main() {
|
|
|
52806
52909
|
process.exit(1);
|
|
52807
52910
|
}
|
|
52808
52911
|
await connect(agent, {
|
|
52809
|
-
openBrowser: !values["no-browser"]
|
|
52912
|
+
openBrowser: !values["no-browser"],
|
|
52913
|
+
taskFile: values["task-file"]
|
|
52810
52914
|
});
|
|
52811
52915
|
} else {
|
|
52812
52916
|
console.error(`Unknown command: ${command}`);
|