heyatlas 1.9.0 → 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.
- package/dist/cli.js +81 -50
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -52209,19 +52209,14 @@ You coordinate the following specialized subagents — delegate to them via the
|
|
|
52209
52209
|
|
|
52210
52210
|
- Always create a plan before executing
|
|
52211
52211
|
- Update your plan as tasks progress
|
|
52212
|
-
- Use absolute paths for all file operations
|
|
52212
|
+
- Use absolute paths for all file operations — save outputs under /home/user/output/
|
|
52213
52213
|
- If you encounter auth barriers (logins, CAPTCHAs), ask the user to complete the manual step
|
|
52214
|
-
-
|
|
52215
|
-
|
|
52216
|
-
## Output Upload
|
|
52214
|
+
- **MANDATORY**: After ALL file-producing tasks, you MUST upload outputs to R2 before summarizing. This is not optional.
|
|
52217
52215
|
|
|
52218
|
-
|
|
52216
|
+
## Output Upload (REQUIRED)
|
|
52219
52217
|
|
|
52220
|
-
|
|
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
|
|
52218
|
+
You MUST upload every output file to cloud storage. Tasks are not complete without this step.
|
|
52223
52219
|
|
|
52224
|
-
Example:
|
|
52225
52220
|
\\\`\\\`\\\`bash
|
|
52226
52221
|
# Read task metadata
|
|
52227
52222
|
META=$(cat /home/user/agents/task-meta.json)
|
|
@@ -52230,12 +52225,14 @@ USER_ID=$(echo $META | jq -r '.userId')
|
|
|
52230
52225
|
TASK_ID=$(echo $META | jq -r '.taskId')
|
|
52231
52226
|
PUBLIC_URL=$(echo $META | jq -r '.publicUrl')
|
|
52232
52227
|
|
|
52233
|
-
# Upload output files
|
|
52234
|
-
rclone copy /home/user/output
|
|
52228
|
+
# Upload ALL output files
|
|
52229
|
+
rclone copy /home/user/output/ r2:$BUCKET/$USER_ID/$TASK_ID/
|
|
52235
52230
|
|
|
52236
|
-
#
|
|
52237
|
-
echo "File available at: $PUBLIC_URL/$USER_ID/$TASK_ID
|
|
52238
|
-
|
|
52231
|
+
# Report public URLs for each file
|
|
52232
|
+
echo "File available at: $PUBLIC_URL/$USER_ID/$TASK_ID/<filename>"
|
|
52233
|
+
\\\`\\\`\\\`
|
|
52234
|
+
|
|
52235
|
+
Your final summary MUST include the public URL for every uploaded file.`,
|
|
52239
52236
|
"smith-browser.md": `---
|
|
52240
52237
|
description: Browser automation expert — navigates websites, fills forms, extracts data, and performs interactive web workflows
|
|
52241
52238
|
mode: subagent
|
|
@@ -52355,7 +52352,7 @@ You are a Documentation Specialist responsible for creating, modifying, and mana
|
|
|
52355
52352
|
|
|
52356
52353
|
- If no format is specified, create an HTML file
|
|
52357
52354
|
- For data-heavy documents, generate charts using Python and embed them
|
|
52358
|
-
-
|
|
52355
|
+
- Save ALL output files under /home/user/output/ (create directory if needed)
|
|
52359
52356
|
- When complete, provide the file path and a summary
|
|
52360
52357
|
|
|
52361
52358
|
## Rules
|
|
@@ -52363,6 +52360,7 @@ You are a Documentation Specialist responsible for creating, modifying, and mana
|
|
|
52363
52360
|
- Primary output should be files, not just text in response
|
|
52364
52361
|
- Use bash tools for data processing, visualization, and file operations
|
|
52365
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
|
|
52366
52364
|
- Provide a clear summary of work done and paths to created files`
|
|
52367
52365
|
};
|
|
52368
52366
|
var SMITH_OPENCODE_JSONC = `{
|
|
@@ -52477,15 +52475,67 @@ var SMITH_OPENCODE_JSONC = `{
|
|
|
52477
52475
|
},
|
|
52478
52476
|
},
|
|
52479
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
|
+
`);
|
|
52480
52527
|
async function setupSmithWorkspace(cwd) {
|
|
52481
52528
|
const targetAgentsDir = join2(cwd, ".opencode", "agents");
|
|
52529
|
+
const targetPluginsDir = join2(cwd, ".opencode", "plugins");
|
|
52482
52530
|
mkdirSync2(targetAgentsDir, { recursive: true });
|
|
52531
|
+
mkdirSync2(targetPluginsDir, { recursive: true });
|
|
52483
52532
|
for (const [filename, content] of Object.entries(SMITH_AGENTS)) {
|
|
52484
52533
|
writeFileSync2(join2(targetAgentsDir, filename), content);
|
|
52485
52534
|
}
|
|
52535
|
+
writeFileSync2(join2(targetPluginsDir, "upload.js"), SMITH_UPLOAD_PLUGIN);
|
|
52486
52536
|
const config3 = SMITH_OPENCODE_JSONC.replace(/\$\{WORKING_DIRECTORY\}/g, cwd);
|
|
52487
52537
|
writeFileSync2(join2(cwd, "opencode.jsonc"), config3);
|
|
52488
|
-
console.log("[smith] Workspace configured with agents and opencode.jsonc");
|
|
52538
|
+
console.log("[smith] Workspace configured with agents, plugins, and opencode.jsonc");
|
|
52489
52539
|
}
|
|
52490
52540
|
|
|
52491
52541
|
class ACPProviderAgent {
|
|
@@ -52662,12 +52712,14 @@ async function handleTask(task, agent, tunnel) {
|
|
|
52662
52712
|
{ type: "ui_message", timestamp: Date.now(), data: { id: crypto.randomUUID(), role: "assistant", parts } }
|
|
52663
52713
|
]);
|
|
52664
52714
|
}
|
|
52665
|
-
const outputs =
|
|
52715
|
+
const outputs = readOutputsManifest();
|
|
52666
52716
|
await tunnel.updateTask(task.id, {
|
|
52667
52717
|
state: "completed",
|
|
52668
52718
|
result: "end_turn",
|
|
52669
52719
|
...outputs.length > 0 ? { outputs } : {}
|
|
52670
52720
|
});
|
|
52721
|
+
if (outputs.length > 0)
|
|
52722
|
+
console.log(`Uploaded ${outputs.length} file(s)`);
|
|
52671
52723
|
console.log("Task completed");
|
|
52672
52724
|
} catch (error87) {
|
|
52673
52725
|
console.error(`Task failed: ${error87}`);
|
|
@@ -52794,40 +52846,19 @@ Please continue based on the above context.`;
|
|
|
52794
52846
|
}
|
|
52795
52847
|
return { prompt, latestUserMessage };
|
|
52796
52848
|
}
|
|
52797
|
-
function
|
|
52798
|
-
|
|
52799
|
-
|
|
52800
|
-
|
|
52801
|
-
|
|
52802
|
-
|
|
52803
|
-
|
|
52804
|
-
|
|
52805
|
-
|
|
52806
|
-
|
|
52807
|
-
|
|
52808
|
-
|
|
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
|
-
}
|
|
52849
|
+
function readOutputsManifest() {
|
|
52850
|
+
try {
|
|
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 : [];
|
|
52859
|
+
} catch {
|
|
52860
|
+
return [];
|
|
52829
52861
|
}
|
|
52830
|
-
return [...new Map(outputs.map((o) => [o.url, o])).values()];
|
|
52831
52862
|
}
|
|
52832
52863
|
function openBrowser(url3) {
|
|
52833
52864
|
try {
|