heyatlas 1.8.0 → 1.8.2

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.
Files changed (2) hide show
  1. package/dist/cli.js +96 -9
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -52195,7 +52195,31 @@ You coordinate the following specialized subagents — delegate to them via the
52195
52195
  - Update your plan as tasks progress
52196
52196
  - Use absolute paths for all file operations
52197
52197
  - If you encounter auth barriers (logins, CAPTCHAs), ask the user to complete the manual step
52198
- - Provide a comprehensive summary when done`,
52198
+ - Provide a comprehensive summary when done
52199
+
52200
+ ## Output Upload
52201
+
52202
+ After completing a task that produces files, upload them to cloud storage using rclone:
52203
+
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
+ \\\`\\\`\\\`bash
52210
+ # Read task metadata
52211
+ META=$(cat /home/user/agents/task-meta.json)
52212
+ BUCKET=$(echo $META | jq -r '.bucket')
52213
+ USER_ID=$(echo $META | jq -r '.userId')
52214
+ TASK_ID=$(echo $META | jq -r '.taskId')
52215
+ PUBLIC_URL=$(echo $META | jq -r '.publicUrl')
52216
+
52217
+ # Upload output files
52218
+ rclone copy /home/user/output.docx r2:$BUCKET/$USER_ID/$TASK_ID/
52219
+
52220
+ # Share the public URL
52221
+ echo "File available at: $PUBLIC_URL/$USER_ID/$TASK_ID/output.docx"
52222
+ \\\`\\\`\\\``,
52199
52223
  "smith-browser.md": `---
52200
52224
  description: Browser automation expert — navigates websites, fills forms, extracts data, and performs interactive web workflows
52201
52225
  mode: subagent
@@ -52545,6 +52569,25 @@ async function connect(agentType, options = {}) {
52545
52569
  interactive: true,
52546
52570
  agentType: options.agentType || "local"
52547
52571
  });
52572
+ if (options.taskFile) {
52573
+ const fs = await import("fs");
52574
+ const taskData = JSON.parse(fs.readFileSync(options.taskFile, "utf-8"));
52575
+ console.log(`Task: ${taskData.description.slice(0, 80)}...`);
52576
+ await tunnel.connect(credentials.userId, agent.name);
52577
+ console.log("Tunnel established");
52578
+ try {
52579
+ await handleTask(taskData, agent, tunnel);
52580
+ console.log(`
52581
+ Task complete. Disconnecting...`);
52582
+ } catch (error87) {
52583
+ console.error(`Task failed: ${error87}`);
52584
+ } finally {
52585
+ agent.cleanup();
52586
+ await tunnel.disconnect();
52587
+ process.exit(0);
52588
+ }
52589
+ return;
52590
+ }
52548
52591
  tunnel.onNewTask(async (task) => {
52549
52592
  await handleTask(task, agent, tunnel);
52550
52593
  });
@@ -52602,7 +52645,12 @@ async function handleTask(task, agent, tunnel) {
52602
52645
  { type: "ui_message", timestamp: Date.now(), data: { id: crypto.randomUUID(), role: "assistant", parts } }
52603
52646
  ]);
52604
52647
  }
52605
- await tunnel.updateTask(task.id, { state: "completed", result: "end_turn" });
52648
+ const outputs = extractOutputUrls(parts);
52649
+ await tunnel.updateTask(task.id, {
52650
+ state: "completed",
52651
+ result: "end_turn",
52652
+ ...outputs.length > 0 ? { outputs } : {}
52653
+ });
52606
52654
  console.log("Task completed");
52607
52655
  } catch (error87) {
52608
52656
  console.error(`Task failed: ${error87}`);
@@ -52729,6 +52777,41 @@ Please continue based on the above context.`;
52729
52777
  }
52730
52778
  return { prompt, latestUserMessage };
52731
52779
  }
52780
+ function extractOutputUrls(parts) {
52781
+ const outputs = [];
52782
+ const urlPattern = /https?:\/\/[^\s"'<>]+/g;
52783
+ for (const part of parts) {
52784
+ if (part.type === "text" && typeof part.text === "string") {
52785
+ const matches = part.text.match(urlPattern);
52786
+ if (!matches)
52787
+ continue;
52788
+ for (const url3 of matches) {
52789
+ const filename = url3.split("/").pop() || "";
52790
+ const ext = filename.includes(".") ? filename.split(".").pop()?.toLowerCase() : null;
52791
+ if (!ext)
52792
+ continue;
52793
+ const typeMap = {
52794
+ pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
52795
+ docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
52796
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
52797
+ pdf: "application/pdf",
52798
+ html: "text/html",
52799
+ png: "image/png",
52800
+ jpg: "image/jpeg",
52801
+ jpeg: "image/jpeg",
52802
+ csv: "text/csv",
52803
+ json: "application/json"
52804
+ };
52805
+ outputs.push({
52806
+ url: url3,
52807
+ filename: decodeURIComponent(filename),
52808
+ type: typeMap[ext] || undefined
52809
+ });
52810
+ }
52811
+ }
52812
+ }
52813
+ return [...new Map(outputs.map((o) => [o.url, o])).values()];
52814
+ }
52732
52815
  function openBrowser(url3) {
52733
52816
  try {
52734
52817
  const { execSync } = __require("child_process");
@@ -52758,7 +52841,8 @@ var { positionals, values } = parseArgs({
52758
52841
  options: {
52759
52842
  help: { type: "boolean", short: "h" },
52760
52843
  version: { type: "boolean", short: "v" },
52761
- "no-browser": { type: "boolean" }
52844
+ "no-browser": { type: "boolean" },
52845
+ "task-file": { type: "string" }
52762
52846
  },
52763
52847
  allowPositionals: true
52764
52848
  });
@@ -52773,13 +52857,15 @@ Supported Agents:
52773
52857
  ${SUPPORTED_AGENTS.join(", ")}
52774
52858
 
52775
52859
  Options:
52776
- -h, --help Show this help message
52777
- -v, --version Show version
52778
- --no-browser Don't open browser automatically
52860
+ -h, --help Show this help message
52861
+ -v, --version Show version
52862
+ --no-browser Don't open browser automatically
52863
+ --task-file <path> Run a single task from a JSON file and exit
52779
52864
 
52780
52865
  Examples:
52781
- heyatlas connect opencode Connect OpenCode via ACP
52782
- heyatlas connect smith Connect Smith via OpenCode
52866
+ heyatlas connect opencode Connect OpenCode via ACP
52867
+ heyatlas connect smith Connect Smith via OpenCode
52868
+ heyatlas connect smith --task-file task.json Run a single task and exit
52783
52869
  `);
52784
52870
  }
52785
52871
  async function main() {
@@ -52806,7 +52892,8 @@ async function main() {
52806
52892
  process.exit(1);
52807
52893
  }
52808
52894
  await connect(agent, {
52809
- openBrowser: !values["no-browser"]
52895
+ openBrowser: !values["no-browser"],
52896
+ taskFile: values["task-file"]
52810
52897
  });
52811
52898
  } else {
52812
52899
  console.error(`Unknown command: ${command}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "heyatlas",
3
- "version": "1.8.0",
3
+ "version": "1.8.2",
4
4
  "description": "Tunnel local AI agents to the cloud for voice-powered interactions",
5
5
  "author": "Bishwendu Kundu <bishwenduk029@gmail.com>",
6
6
  "license": "MIT",