heyatlas 1.7.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 +98 -10
  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
@@ -52443,7 +52467,8 @@ async function setupSmithWorkspace(cwd) {
52443
52467
  for (const [filename, content] of Object.entries(SMITH_AGENTS)) {
52444
52468
  writeFileSync2(join2(targetAgentsDir, filename), content);
52445
52469
  }
52446
- writeFileSync2(join2(cwd, "opencode.jsonc"), SMITH_OPENCODE_JSONC);
52470
+ const config3 = SMITH_OPENCODE_JSONC.replace(/\$\{WORKING_DIRECTORY\}/g, cwd);
52471
+ writeFileSync2(join2(cwd, "opencode.jsonc"), config3);
52447
52472
  console.log("[smith] Workspace configured with agents and opencode.jsonc");
52448
52473
  }
52449
52474
 
@@ -52544,6 +52569,25 @@ async function connect(agentType, options = {}) {
52544
52569
  interactive: true,
52545
52570
  agentType: options.agentType || "local"
52546
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
+ }
52547
52591
  tunnel.onNewTask(async (task) => {
52548
52592
  await handleTask(task, agent, tunnel);
52549
52593
  });
@@ -52601,7 +52645,12 @@ async function handleTask(task, agent, tunnel) {
52601
52645
  { type: "ui_message", timestamp: Date.now(), data: { id: crypto.randomUUID(), role: "assistant", parts } }
52602
52646
  ]);
52603
52647
  }
52604
- 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
+ });
52605
52654
  console.log("Task completed");
52606
52655
  } catch (error87) {
52607
52656
  console.error(`Task failed: ${error87}`);
@@ -52728,6 +52777,41 @@ Please continue based on the above context.`;
52728
52777
  }
52729
52778
  return { prompt, latestUserMessage };
52730
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
+ }
52731
52815
  function openBrowser(url3) {
52732
52816
  try {
52733
52817
  const { execSync } = __require("child_process");
@@ -52757,7 +52841,8 @@ var { positionals, values } = parseArgs({
52757
52841
  options: {
52758
52842
  help: { type: "boolean", short: "h" },
52759
52843
  version: { type: "boolean", short: "v" },
52760
- "no-browser": { type: "boolean" }
52844
+ "no-browser": { type: "boolean" },
52845
+ "task-file": { type: "string" }
52761
52846
  },
52762
52847
  allowPositionals: true
52763
52848
  });
@@ -52772,13 +52857,15 @@ Supported Agents:
52772
52857
  ${SUPPORTED_AGENTS.join(", ")}
52773
52858
 
52774
52859
  Options:
52775
- -h, --help Show this help message
52776
- -v, --version Show version
52777
- --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
52778
52864
 
52779
52865
  Examples:
52780
- heyatlas connect opencode Connect OpenCode via ACP
52781
- 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
52782
52869
  `);
52783
52870
  }
52784
52871
  async function main() {
@@ -52805,7 +52892,8 @@ async function main() {
52805
52892
  process.exit(1);
52806
52893
  }
52807
52894
  await connect(agent, {
52808
- openBrowser: !values["no-browser"]
52895
+ openBrowser: !values["no-browser"],
52896
+ taskFile: values["task-file"]
52809
52897
  });
52810
52898
  } else {
52811
52899
  console.error(`Unknown command: ${command}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "heyatlas",
3
- "version": "1.7.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",