heyatlas 1.9.1 → 1.9.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 +65 -69
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -52475,15 +52475,67 @@ var SMITH_OPENCODE_JSONC = `{
52475
52475
  },
52476
52476
  },
52477
52477
  }`;
52478
+ var SMITH_UPLOAD_PLUGIN = [
52479
+ 'import { execSync } from "child_process";',
52480
+ 'import { existsSync, readFileSync, writeFileSync } from "fs";',
52481
+ 'import { basename, join } from "path";',
52482
+ "",
52483
+ 'const UPLOAD_EXTS = new Set(["docx","xlsx","pptx","pdf","html","csv","png","jpg","jpeg","gif","svg","zip","md","txt"]);',
52484
+ "const FILE_PATH_RE = /(?:\\/[\\w.${},-]+)+\\.(?:docx|xlsx|pptx|pdf|html|csv|png|jpg|jpeg|gif|svg|zip|md|txt)\\b/gi;",
52485
+ "",
52486
+ "export const UploadPlugin = async ({ directory }) => {",
52487
+ ' const agentsDir = join(directory, "agents");',
52488
+ ' const metaPath = join(agentsDir, "task-meta.json");',
52489
+ ' const outputsPath = join(agentsDir, "outputs.json");',
52490
+ " const trackedFiles = new Set();",
52491
+ " return {",
52492
+ ' "tool.execute.after": async (input, output) => {',
52493
+ ' const result = typeof output === "string" ? output : JSON.stringify(output);',
52494
+ " const matches = result.match(FILE_PATH_RE);",
52495
+ " if (matches) { for (const fp of matches) { if (existsSync(fp)) trackedFiles.add(fp); } }",
52496
+ " },",
52497
+ " event: async ({ event }) => {",
52498
+ ' if (event.type === "file.edited" && event.properties?.file) {',
52499
+ ' const ext = event.properties.file.split(".").pop()?.toLowerCase();',
52500
+ " if (ext && UPLOAD_EXTS.has(ext)) trackedFiles.add(event.properties.file);",
52501
+ " }",
52502
+ ' if (event.type === "session.idle" && trackedFiles.size > 0) {',
52503
+ " if (!existsSync(metaPath)) { trackedFiles.clear(); return; }",
52504
+ " try {",
52505
+ ' const meta = JSON.parse(readFileSync(metaPath, "utf-8"));',
52506
+ " if (!meta.publicUrl || !meta.bucket) return;",
52507
+ ' const dest = "r2:" + meta.bucket + "/" + meta.userId + "/" + meta.taskId;',
52508
+ ' const base = meta.publicUrl.replace(/\\/$/, "");',
52509
+ " const urls = [];",
52510
+ " for (const fp of trackedFiles) {",
52511
+ " if (!existsSync(fp)) continue;",
52512
+ " const name = basename(fp);",
52513
+ " try {",
52514
+ ' execSync("rclone copyto \\"" + fp + "\\" \\"" + dest + "/" + name + "\\"", { stdio: "pipe", timeout: 30000 });',
52515
+ ' urls.push({ url: base + "/" + meta.userId + "/" + meta.taskId + "/" + name, filename: name });',
52516
+ " } catch {}",
52517
+ " }",
52518
+ " if (urls.length > 0) writeFileSync(outputsPath, JSON.stringify(urls));",
52519
+ " trackedFiles.clear();",
52520
+ " } catch {}",
52521
+ " }",
52522
+ " },",
52523
+ " };",
52524
+ "};"
52525
+ ].join(`
52526
+ `);
52478
52527
  async function setupSmithWorkspace(cwd) {
52479
52528
  const targetAgentsDir = join2(cwd, ".opencode", "agents");
52529
+ const targetPluginsDir = join2(cwd, ".opencode", "plugins");
52480
52530
  mkdirSync2(targetAgentsDir, { recursive: true });
52531
+ mkdirSync2(targetPluginsDir, { recursive: true });
52481
52532
  for (const [filename, content] of Object.entries(SMITH_AGENTS)) {
52482
52533
  writeFileSync2(join2(targetAgentsDir, filename), content);
52483
52534
  }
52535
+ writeFileSync2(join2(targetPluginsDir, "upload.js"), SMITH_UPLOAD_PLUGIN);
52484
52536
  const config3 = SMITH_OPENCODE_JSONC.replace(/\$\{WORKING_DIRECTORY\}/g, cwd);
52485
52537
  writeFileSync2(join2(cwd, "opencode.jsonc"), config3);
52486
- console.log("[smith] Workspace configured with agents and opencode.jsonc");
52538
+ console.log("[smith] Workspace configured with agents, plugins, and opencode.jsonc");
52487
52539
  }
52488
52540
 
52489
52541
  class ACPProviderAgent {
@@ -52660,12 +52712,14 @@ async function handleTask(task, agent, tunnel) {
52660
52712
  { type: "ui_message", timestamp: Date.now(), data: { id: crypto.randomUUID(), role: "assistant", parts } }
52661
52713
  ]);
52662
52714
  }
52663
- const outputs = await uploadTaskOutputs(task.id);
52715
+ const outputs = readOutputsManifest();
52664
52716
  await tunnel.updateTask(task.id, {
52665
52717
  state: "completed",
52666
52718
  result: "end_turn",
52667
52719
  ...outputs.length > 0 ? { outputs } : {}
52668
52720
  });
52721
+ if (outputs.length > 0)
52722
+ console.log(`Uploaded ${outputs.length} file(s)`);
52669
52723
  console.log("Task completed");
52670
52724
  } catch (error87) {
52671
52725
  console.error(`Task failed: ${error87}`);
@@ -52792,77 +52846,19 @@ Please continue based on the above context.`;
52792
52846
  }
52793
52847
  return { prompt, latestUserMessage };
52794
52848
  }
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;
52849
+ function readOutputsManifest() {
52803
52850
  try {
52804
- meta3 = JSON.parse(fs.readFileSync(metaPath, "utf-8"));
52851
+ const fs = __require("fs");
52852
+ const path = __require("path");
52853
+ const manifestPath = path.join(process.cwd(), "agents", "outputs.json");
52854
+ if (!fs.existsSync(manifestPath))
52855
+ return [];
52856
+ const data = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
52857
+ fs.unlinkSync(manifestPath);
52858
+ return Array.isArray(data) ? data : [];
52805
52859
  } catch {
52806
52860
  return [];
52807
52861
  }
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("."))
52821
- continue;
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));
52835
- }
52836
- }
52837
- }
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;
52866
52862
  }
52867
52863
  function openBrowser(url3) {
52868
52864
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "heyatlas",
3
- "version": "1.9.1",
3
+ "version": "1.9.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",