@alook/cli 0.0.13 → 0.0.14
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/index.js +11 -5
- package/dist/session-runner.js +11 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14118,6 +14118,9 @@ var TestEmailConnectionSchema = exports_external.object({
|
|
|
14118
14118
|
smtpPassword: exports_external.string().min(1),
|
|
14119
14119
|
smtpTls: exports_external.number().int().min(0).max(2).default(1)
|
|
14120
14120
|
});
|
|
14121
|
+
var UpdateMemberRequestSchema = exports_external.object({
|
|
14122
|
+
global_instruction: exports_external.string().max(50000).trim()
|
|
14123
|
+
});
|
|
14121
14124
|
var CreateWorkspaceRequestSchema = exports_external.object({
|
|
14122
14125
|
name: exports_external.string().min(1, "name is required"),
|
|
14123
14126
|
slug: exports_external.string().min(1, "slug is required")
|
|
@@ -15550,6 +15553,7 @@ var member = sqliteTable("member", {
|
|
|
15550
15553
|
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
15551
15554
|
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
15552
15555
|
role: text("role").notNull().default("member"),
|
|
15556
|
+
globalInstruction: text("global_instruction").notNull().default(""),
|
|
15553
15557
|
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
15554
15558
|
}, (t) => [unique("member_workspace_user").on(t.workspaceId, t.userId)]);
|
|
15555
15559
|
var machine = sqliteTable("machine", {
|
|
@@ -15655,6 +15659,7 @@ var agentTaskQueue = sqliteTable("agent_task_queue", {
|
|
|
15655
15659
|
error: text("error")
|
|
15656
15660
|
}, (t) => [
|
|
15657
15661
|
index("idx_task_queue_pending").on(t.agentId, t.status).where(sql`status IN ('queued', 'dispatched')`),
|
|
15662
|
+
index("idx_task_queue_workspace_active").on(t.workspaceId, t.status, t.agentId).where(sql`status IN ('queued', 'dispatched', 'running')`),
|
|
15658
15663
|
foreignKey({
|
|
15659
15664
|
columns: [t.agentId, t.workspaceId],
|
|
15660
15665
|
foreignColumns: [agent.id, agent.workspaceId]
|
|
@@ -16751,7 +16756,7 @@ import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, readFileSync
|
|
|
16751
16756
|
import { basename, join as join5 } from "path";
|
|
16752
16757
|
import PostalMime from "postal-mime";
|
|
16753
16758
|
var VALID_STATUSES = ["unread", "read", "archived"];
|
|
16754
|
-
var
|
|
16759
|
+
var EMAIL_BASE = "/tmp/alook-emails";
|
|
16755
16760
|
var MIME_BY_EXT = {
|
|
16756
16761
|
".pdf": "application/pdf",
|
|
16757
16762
|
".png": "image/png",
|
|
@@ -16801,13 +16806,14 @@ function resolveClientOpts(command, opts) {
|
|
|
16801
16806
|
}
|
|
16802
16807
|
function emailCommand() {
|
|
16803
16808
|
const cmd = new Command5("email").description("Manage agent emails");
|
|
16804
|
-
cmd.command("pull").description("Download and parse emails to /tmp/alook-emails/").requiredOption("--agent_id <id>", "Agent ID").option("--status <status>", "Filter by status (unread, read, archived)").option("--workspace <id>", "Workspace ID").option("--json", "Output as JSON instead of files").action(async (opts, command) => {
|
|
16809
|
+
cmd.command("pull").description("Download and parse emails to /tmp/alook-emails/{workspaceId}/{agentId}/").requiredOption("--agent_id <id>", "Agent ID").option("--status <status>", "Filter by status (unread, read, archived)").option("--workspace <id>", "Workspace ID").option("--json", "Output as JSON instead of files").action(async (opts, command) => {
|
|
16805
16810
|
const { serverUrl, token, workspaceId } = resolveClientOpts(command, { workspace: opts.workspace, agentId: opts.agent_id });
|
|
16806
16811
|
const client = new APIClient(serverUrl, token, workspaceId);
|
|
16807
16812
|
if (opts.status && !VALID_STATUSES.includes(opts.status)) {
|
|
16808
16813
|
console.error(`Error: invalid status "${opts.status}", must be one of: ${VALID_STATUSES.join(", ")}`);
|
|
16809
16814
|
process.exit(1);
|
|
16810
16815
|
}
|
|
16816
|
+
const emailDir_base = join5(EMAIL_BASE, workspaceId, opts.agent_id);
|
|
16811
16817
|
try {
|
|
16812
16818
|
let query = `/api/email?agentId=${opts.agent_id}`;
|
|
16813
16819
|
if (opts.status)
|
|
@@ -16821,10 +16827,10 @@ function emailCommand() {
|
|
|
16821
16827
|
printJSON(emails2);
|
|
16822
16828
|
return;
|
|
16823
16829
|
}
|
|
16824
|
-
mkdirSync5(
|
|
16830
|
+
mkdirSync5(emailDir_base, { recursive: true });
|
|
16825
16831
|
const downloadedPaths = [];
|
|
16826
16832
|
for (const email3 of emails2) {
|
|
16827
|
-
const emailDir = join5(
|
|
16833
|
+
const emailDir = join5(emailDir_base, email3.id);
|
|
16828
16834
|
mkdirSync5(emailDir, { recursive: true });
|
|
16829
16835
|
const metadata = {
|
|
16830
16836
|
id: email3.id,
|
|
@@ -16888,7 +16894,7 @@ function emailCommand() {
|
|
|
16888
16894
|
}
|
|
16889
16895
|
}
|
|
16890
16896
|
}
|
|
16891
|
-
console.log(`Downloaded ${emails2.length} email${emails2.length === 1 ? "" : "s"} to ${
|
|
16897
|
+
console.log(`Downloaded ${emails2.length} email${emails2.length === 1 ? "" : "s"} to ${emailDir_base}/`);
|
|
16892
16898
|
for (const p of downloadedPaths) {
|
|
16893
16899
|
console.log(` ${p}`);
|
|
16894
16900
|
}
|
package/dist/session-runner.js
CHANGED
|
@@ -13835,6 +13835,9 @@ var TestEmailConnectionSchema = exports_external.object({
|
|
|
13835
13835
|
smtpPassword: exports_external.string().min(1),
|
|
13836
13836
|
smtpTls: exports_external.number().int().min(0).max(2).default(1)
|
|
13837
13837
|
});
|
|
13838
|
+
var UpdateMemberRequestSchema = exports_external.object({
|
|
13839
|
+
global_instruction: exports_external.string().max(50000).trim()
|
|
13840
|
+
});
|
|
13838
13841
|
var CreateWorkspaceRequestSchema = exports_external.object({
|
|
13839
13842
|
name: exports_external.string().min(1, "name is required"),
|
|
13840
13843
|
slug: exports_external.string().min(1, "slug is required")
|
|
@@ -15267,6 +15270,7 @@ var member = sqliteTable("member", {
|
|
|
15267
15270
|
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
15268
15271
|
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
15269
15272
|
role: text("role").notNull().default("member"),
|
|
15273
|
+
globalInstruction: text("global_instruction").notNull().default(""),
|
|
15270
15274
|
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
15271
15275
|
}, (t) => [unique("member_workspace_user").on(t.workspaceId, t.userId)]);
|
|
15272
15276
|
var machine = sqliteTable("machine", {
|
|
@@ -15372,6 +15376,7 @@ var agentTaskQueue = sqliteTable("agent_task_queue", {
|
|
|
15372
15376
|
error: text("error")
|
|
15373
15377
|
}, (t) => [
|
|
15374
15378
|
index("idx_task_queue_pending").on(t.agentId, t.status).where(sql`status IN ('queued', 'dispatched')`),
|
|
15379
|
+
index("idx_task_queue_workspace_active").on(t.workspaceId, t.status, t.agentId).where(sql`status IN ('queued', 'dispatched', 'running')`),
|
|
15375
15380
|
foreignKey({
|
|
15376
15381
|
columns: [t.agentId, t.workspaceId],
|
|
15377
15382
|
foreignColumns: [agent.id, agent.workspaceId]
|
|
@@ -16595,30 +16600,30 @@ ${task.agent?.userEmail ? `Your owner's email address is '${task.agent.userEmail
|
|
|
16595
16600
|
|
|
16596
16601
|
### Emails
|
|
16597
16602
|
---
|
|
16598
|
-
Run 'npx @alook/cli email pull --agent_id ${task.agentId} --status unread' to download unread emails to '/tmp/alook-emails/'.
|
|
16599
|
-
Each email is saved to '/tmp/alook-emails/<emailId>/' with:
|
|
16603
|
+
Run 'npx @alook/cli email pull --agent_id ${task.agentId} --workspace ${task.workspaceId} --status unread' to download unread emails to '/tmp/alook-emails/${task.workspaceId}/${task.agentId}/'.
|
|
16604
|
+
Each email is saved to '/tmp/alook-emails/${task.workspaceId}/${task.agentId}/<emailId>/' with:
|
|
16600
16605
|
- 'metadata.json' — sender, recipient, subject, date, status, message_id, in_reply_to, references
|
|
16601
16606
|
- 'body.txt' — plain text body
|
|
16602
16607
|
- 'body.html' — HTML body (if available)
|
|
16603
16608
|
- 'attachments/' — extracted attachment files (if any)
|
|
16604
16609
|
---
|
|
16605
16610
|
Before starting to process an email, mark it as read:
|
|
16606
|
-
- Run 'npx @alook/cli email set --agent_id ${task.agentId} --email_id <EMAIL_ID> --status read'
|
|
16611
|
+
- Run 'npx @alook/cli email set --agent_id ${task.agentId} --workspace ${task.workspaceId} --email_id <EMAIL_ID> --status read'
|
|
16607
16612
|
---
|
|
16608
16613
|
|
|
16609
16614
|
#### Sending a new email
|
|
16610
16615
|
Write the HTML body to a file first, then send it. The body is forwarded as-is (HTML).
|
|
16611
|
-
- Run 'npx @alook/cli email send --agent_id ${task.agentId} --to <ADDRESS> --subject "<SUBJECT>" --body-file <PATH_TO_HTML>'
|
|
16616
|
+
- Run 'npx @alook/cli email send --agent_id ${task.agentId} --workspace ${task.workspaceId} --to <ADDRESS> --subject "<SUBJECT>" --body-file <PATH_TO_HTML>'
|
|
16612
16617
|
- To send from a specific mailbox, add '--from <YOUR_EMAIL_ADDRESS>'. Without '--from', the default Alook address is used.
|
|
16613
16618
|
- Attach files with '--attachment <PATH>' — repeat the flag for multiple attachments. Each file is uploaded before sending.
|
|
16614
|
-
- Example: 'npx @alook/cli email send --agent_id ${task.agentId} --to foo@bar.com --subject "Weekly report" --body-file /tmp/body.html --from alice@company.com --attachment /tmp/report.pdf'
|
|
16619
|
+
- Example: 'npx @alook/cli email send --agent_id ${task.agentId} --workspace ${task.workspaceId} --to foo@bar.com --subject "Weekly report" --body-file /tmp/body.html --from alice@company.com --attachment /tmp/report.pdf'
|
|
16615
16620
|
|
|
16616
16621
|
#### Replying to an email
|
|
16617
16622
|
To reply to an email, add '--in-reply-to <EMAIL_ID>' to the send command. This sets the correct email threading headers so the recipient's email client groups the reply into the same conversation thread.
|
|
16618
16623
|
- Use 'Re: <original subject>' as the subject.
|
|
16619
16624
|
- Quote the original email body in your reply (wrap it in a blockquote).
|
|
16620
16625
|
- The <EMAIL_ID> is the Alook email id from metadata.json (not the message_id header).
|
|
16621
|
-
- Example: 'npx @alook/cli email send --agent_id ${task.agentId} --to sender@example.com --subject "Re: Bug report" --body-file /tmp/reply.html --in-reply-to <EMAIL_ID>'
|
|
16626
|
+
- Example: 'npx @alook/cli email send --agent_id ${task.agentId} --workspace ${task.workspaceId} --to sender@example.com --subject "Re: Bug report" --body-file /tmp/reply.html --in-reply-to <EMAIL_ID>'
|
|
16622
16627
|
---
|
|
16623
16628
|
`;
|
|
16624
16629
|
}
|