@alook/cli 0.0.45 → 0.0.47

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 CHANGED
@@ -14836,6 +14836,7 @@ var CalendarEventApiSchema = exports_external.object({
14836
14836
  description: exports_external.string().nullable(),
14837
14837
  scheduled_at: exports_external.string(),
14838
14838
  occurrence_at: exports_external.string(),
14839
+ collapsed_count: exports_external.number().nullable().optional(),
14839
14840
  repeat_interval: exports_external.string().nullable(),
14840
14841
  repeat_stop_at: exports_external.string().nullable(),
14841
14842
  last_triggered_at: exports_external.string().nullable(),
@@ -14861,9 +14862,18 @@ var UpdateIssueRequestSchema = exports_external.object({
14861
14862
  description: exports_external.string().max(20000).optional(),
14862
14863
  status: IssueStatusSchema.optional()
14863
14864
  }).refine((v) => v.title !== undefined || v.description !== undefined || v.status !== undefined, { message: "at least one field is required" });
14864
- var CreateIssueCommentRequestSchema = exports_external.object({
14865
+ var CreateIssueCommentBodySchema = exports_external.object({
14865
14866
  content: exports_external.string().min(1, "content is required").max(20000)
14866
14867
  });
14868
+ var IssueCommentApiSchema = exports_external.object({
14869
+ id: exports_external.string(),
14870
+ issue_id: exports_external.string(),
14871
+ workspace_id: exports_external.string(),
14872
+ author_type: exports_external.enum(["user", "agent"]),
14873
+ author_id: exports_external.string(),
14874
+ content: exports_external.string(),
14875
+ created_at: exports_external.string()
14876
+ });
14867
14877
  var IssueApiSchema = exports_external.object({
14868
14878
  id: exports_external.string(),
14869
14879
  workspace_id: exports_external.string(),
@@ -15044,6 +15054,21 @@ var WorkspaceFileReportSchema = exports_external.object({
15044
15054
  error: exports_external.string().optional(),
15045
15055
  path: exports_external.string()
15046
15056
  });
15057
+ var StudioMemberSchema = exports_external.object({
15058
+ name: exports_external.string().optional(),
15059
+ role: exports_external.enum(["leader", "researcher", "engineer", "assistant"]),
15060
+ runtime_id: exports_external.string().min(1, "runtime_id is required"),
15061
+ runtime_config: exports_external.object({ model: exports_external.string().max(100).optional() }).passthrough().optional(),
15062
+ description: exports_external.string().optional().default(""),
15063
+ instructions: exports_external.string().optional().default(""),
15064
+ avatar_url: exports_external.string().max(2000).nullable().optional(),
15065
+ email_handle: exports_external.string().max(30).optional()
15066
+ });
15067
+ var CreateStudioRequestSchema = exports_external.object({
15068
+ name: exports_external.string().max(100).optional(),
15069
+ scenario: exports_external.string().max(50).optional(),
15070
+ members: exports_external.array(StudioMemberSchema).min(1).max(4)
15071
+ }).refine((v) => v.members.some((m) => m.role === "leader"), { message: "at least one member must have the leader role" });
15047
15072
  // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260504.1_@opentelemetry+api@1.9.1_bun-types@1.3.13_kysely@0.28.16/node_modules/drizzle-orm/entity.js
15048
15073
  var entityKind = Symbol.for("drizzle:entityKind");
15049
15074
  var hasOwnEntityKind = Symbol.for("drizzle:hasOwnEntityKind");
@@ -16438,7 +16463,7 @@ var session = sqliteTable("session", {
16438
16463
  userAgent: text("userAgent"),
16439
16464
  createdAt: text("createdAt").notNull().$defaultFn(() => new Date().toISOString()),
16440
16465
  updatedAt: text("updatedAt").notNull().$defaultFn(() => new Date().toISOString())
16441
- });
16466
+ }, (t) => [index("idx_session_token_expires").on(t.token, t.expiresAt)]);
16442
16467
  var account = sqliteTable("account", {
16443
16468
  id: text("id").primaryKey().$defaultFn(() => nanoid3()),
16444
16469
  userId: text("userId").notNull().references(() => user.id, { onDelete: "cascade" }),
@@ -16685,6 +16710,18 @@ var issue2 = sqliteTable("issue", {
16685
16710
  foreignColumns: [agent.id, agent.workspaceId]
16686
16711
  }).onDelete("cascade")
16687
16712
  ]);
16713
+ var issueComment = sqliteTable("issue_comment", {
16714
+ id: text("id").primaryKey().$defaultFn(() => "ic_" + nanoid3()),
16715
+ issueId: text("issue_id").notNull().references(() => issue2.id, { onDelete: "cascade" }),
16716
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
16717
+ authorType: text("author_type").notNull().default("user"),
16718
+ authorId: text("author_id").notNull(),
16719
+ content: text("content").notNull(),
16720
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
16721
+ }, (t) => [
16722
+ index("idx_issue_comment_issue").on(t.issueId, t.createdAt),
16723
+ index("idx_issue_comment_workspace").on(t.workspaceId, t.issueId)
16724
+ ]);
16688
16725
  var taskMessage = sqliteTable("task_message", {
16689
16726
  id: text("id").primaryKey().$defaultFn(() => nanoid3()),
16690
16727
  taskId: text("task_id").notNull().references(() => agentTaskQueue.id, { onDelete: "cascade" }),
@@ -16696,7 +16733,10 @@ var taskMessage = sqliteTable("task_message", {
16696
16733
  input: text("input", { mode: "json" }),
16697
16734
  output: text("output").notNull().default(""),
16698
16735
  createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
16699
- }, (t) => [index("idx_task_message_task_seq").on(t.taskId, t.seq)]);
16736
+ }, (t) => [
16737
+ index("idx_task_message_task_seq").on(t.taskId, t.seq),
16738
+ index("idx_task_message_task_created").on(t.taskId, t.createdAt)
16739
+ ]);
16700
16740
  var emails = sqliteTable("emails", {
16701
16741
  id: text("id").primaryKey().$defaultFn(() => nanoid3()),
16702
16742
  agentId: text("agent_id").notNull(),
@@ -16719,7 +16759,12 @@ var emails = sqliteTable("emails", {
16719
16759
  foreignKey({
16720
16760
  columns: [t.agentId, t.workspaceId],
16721
16761
  foreignColumns: [agent.id, agent.workspaceId]
16722
- }).onDelete("cascade")
16762
+ }).onDelete("cascade"),
16763
+ index("idx_emails_agent_ws_status").on(t.agentId, t.workspaceId, t.status),
16764
+ index("idx_emails_to_direction").on(t.toEmail, t.direction),
16765
+ index("idx_emails_from_direction").on(t.fromEmail, t.direction),
16766
+ index("idx_emails_message_id").on(t.messageId),
16767
+ index("idx_emails_created_at").on(t.createdAt)
16723
16768
  ]);
16724
16769
  var calendarEvent = sqliteTable("calendar_event", {
16725
16770
  id: text("id").primaryKey().$defaultFn(() => "ce_" + nanoid3()),
@@ -16883,6 +16928,9 @@ var workspaceFileRequest = sqliteTable("workspace_file_request", {
16883
16928
  // ../shared/src/db/queries/task.ts
16884
16929
  var DEFAULT_STALE_SECONDS = Number(process.env.ALOOK_STALE_DISPATCH_TIMEOUT_S) || 20;
16885
16930
  var DEFAULT_STALE_RUNNING_SECONDS = Number(process.env.ALOOK_STALE_RUNNING_TIMEOUT_S) || 3600;
16931
+ // ../shared/src/db/queries/task-message.ts
16932
+ var HIDDEN_STEP_TYPES = ["status", "log", "tool-result", "text"];
16933
+ var FIXED_PARAMS = 1 + HIDDEN_STEP_TYPES.length;
16886
16934
  // ../shared/src/utils/email.ts
16887
16935
  var DOMAIN = `@${process.env.ALOOK_DOMAIN || "alook.ai"}`;
16888
16936
  var RESERVED_HANDLES = new Set([
@@ -19103,7 +19151,7 @@ function calendarCommand() {
19103
19151
  return;
19104
19152
  }
19105
19153
  for (const ev of events) {
19106
- const repeatBadge = ev.repeat_interval ? ` [every ${ev.repeat_interval}${ev.repeat_stop_at ? ` until ${formatLocalDatetime(ev.repeat_stop_at)}` : ""}]` : "";
19154
+ const repeatBadge = ev.repeat_interval ? ` [every ${ev.repeat_interval}${ev.collapsed_count ? ` · ${ev.collapsed_count} occurrences` : ""}${ev.repeat_stop_at ? ` until ${formatLocalDatetime(ev.repeat_stop_at)}` : ""}]` : "";
19107
19155
  const descBadge = ev.description ? " [has description]" : "";
19108
19156
  console.log(`${ev.id} ${formatLocalDatetime(ev.scheduled_at)} ${ev.title}${repeatBadge}${descBadge}`);
19109
19157
  }
@@ -19240,7 +19288,7 @@ function readBody(opts) {
19240
19288
  function printIssue(issue3) {
19241
19289
  console.log(`${issue3.id} ${issue3.status.padEnd(11)} ${issue3.title}`);
19242
19290
  }
19243
- function printIssueDetail(issue3, messages) {
19291
+ function printIssueDetail(issue3, messages, comments) {
19244
19292
  console.log(`id: ${issue3.id}`);
19245
19293
  console.log(`agent_id: ${issue3.agent_id}`);
19246
19294
  console.log(`status: ${issue3.status}`);
@@ -19250,11 +19298,19 @@ function printIssueDetail(issue3, messages) {
19250
19298
  console.log(`title: ${issue3.title}`);
19251
19299
  console.log("description:");
19252
19300
  console.log(issue3.description || "(no description)");
19253
- if (messages && messages.length > 0) {
19301
+ const events = messages?.filter((m) => m.role === "event") ?? [];
19302
+ if (events.length > 0) {
19254
19303
  console.log(`
19255
- conversation:`);
19256
- for (const m of messages) {
19257
- console.log(`[${m.role}] ${m.content}`);
19304
+ events:`);
19305
+ for (const m of events) {
19306
+ console.log(` [${m.created_at}] ${m.content}`);
19307
+ }
19308
+ }
19309
+ if (comments && comments.length > 0) {
19310
+ console.log(`
19311
+ comments:`);
19312
+ for (const c of comments) {
19313
+ console.log(` [${c.created_at}] (${c.author_type}) ${c.content}`);
19258
19314
  }
19259
19315
  }
19260
19316
  }
@@ -19305,24 +19361,6 @@ function issueCommand() {
19305
19361
  process.exit(1);
19306
19362
  }
19307
19363
  });
19308
- cmd.command("pull").description("Show the next active issue for an agent").requiredOption("--agent_id <id>", "Agent ID").option("--json", "Output as JSON").action(async (opts, command) => {
19309
- const { serverUrl, token, workspaceId } = resolveClientOpts3(command, opts.agent_id);
19310
- const client = new APIClient(serverUrl, token, workspaceId);
19311
- try {
19312
- const issues = await client.getJSON(`/api/issues?agentId=${encodeURIComponent(opts.agent_id)}&terminal=false`);
19313
- const issue3 = issues[0] ?? null;
19314
- if (opts.json)
19315
- return printJSON(issue3);
19316
- if (!issue3) {
19317
- console.log("No active issues.");
19318
- return;
19319
- }
19320
- printIssueDetail(issue3);
19321
- } catch (err) {
19322
- console.error(`Error: ${err instanceof Error ? err.message : err}`);
19323
- process.exit(1);
19324
- }
19325
- });
19326
19364
  cmd.command("show").description("Show issue details and conversation").requiredOption("--agent_id <id>", "Agent ID").requiredOption("--issue_id <id>", "Issue ID").option("--json", "Output as JSON").action(async (opts, command) => {
19327
19365
  const { serverUrl, token, workspaceId } = resolveClientOpts3(command, opts.agent_id);
19328
19366
  const client = new APIClient(serverUrl, token, workspaceId);
@@ -19334,7 +19372,7 @@ function issueCommand() {
19334
19372
  }
19335
19373
  if (opts.json)
19336
19374
  return printJSON(res);
19337
- printIssueDetail(res.issue, res.messages);
19375
+ printIssueDetail(res.issue, res.messages, res.comments);
19338
19376
  } catch (err) {
19339
19377
  console.error(`Error: ${err instanceof Error ? err.message : err}`);
19340
19378
  process.exit(1);
@@ -19378,7 +19416,7 @@ function issueCommand() {
19378
19416
  const { serverUrl, token, workspaceId } = resolveClientOpts3(command, opts.agent_id);
19379
19417
  const client = new APIClient(serverUrl, token, workspaceId);
19380
19418
  try {
19381
- const res = await client.postJSON(`/api/issues/${opts.issue_id}?agentId=${encodeURIComponent(opts.agent_id)}`, { content });
19419
+ const res = await client.postJSON(`/api/issues/${opts.issue_id}/comments?agentId=${encodeURIComponent(opts.agent_id)}`, { content });
19382
19420
  if (opts.json)
19383
19421
  return printJSON(res);
19384
19422
  console.log(`Commented on ${opts.issue_id}`);
@@ -14553,6 +14553,7 @@ var CalendarEventApiSchema = exports_external.object({
14553
14553
  description: exports_external.string().nullable(),
14554
14554
  scheduled_at: exports_external.string(),
14555
14555
  occurrence_at: exports_external.string(),
14556
+ collapsed_count: exports_external.number().nullable().optional(),
14556
14557
  repeat_interval: exports_external.string().nullable(),
14557
14558
  repeat_stop_at: exports_external.string().nullable(),
14558
14559
  last_triggered_at: exports_external.string().nullable(),
@@ -14578,9 +14579,18 @@ var UpdateIssueRequestSchema = exports_external.object({
14578
14579
  description: exports_external.string().max(20000).optional(),
14579
14580
  status: IssueStatusSchema.optional()
14580
14581
  }).refine((v) => v.title !== undefined || v.description !== undefined || v.status !== undefined, { message: "at least one field is required" });
14581
- var CreateIssueCommentRequestSchema = exports_external.object({
14582
+ var CreateIssueCommentBodySchema = exports_external.object({
14582
14583
  content: exports_external.string().min(1, "content is required").max(20000)
14583
14584
  });
14585
+ var IssueCommentApiSchema = exports_external.object({
14586
+ id: exports_external.string(),
14587
+ issue_id: exports_external.string(),
14588
+ workspace_id: exports_external.string(),
14589
+ author_type: exports_external.enum(["user", "agent"]),
14590
+ author_id: exports_external.string(),
14591
+ content: exports_external.string(),
14592
+ created_at: exports_external.string()
14593
+ });
14584
14594
  var IssueApiSchema = exports_external.object({
14585
14595
  id: exports_external.string(),
14586
14596
  workspace_id: exports_external.string(),
@@ -14761,6 +14771,21 @@ var WorkspaceFileReportSchema = exports_external.object({
14761
14771
  error: exports_external.string().optional(),
14762
14772
  path: exports_external.string()
14763
14773
  });
14774
+ var StudioMemberSchema = exports_external.object({
14775
+ name: exports_external.string().optional(),
14776
+ role: exports_external.enum(["leader", "researcher", "engineer", "assistant"]),
14777
+ runtime_id: exports_external.string().min(1, "runtime_id is required"),
14778
+ runtime_config: exports_external.object({ model: exports_external.string().max(100).optional() }).passthrough().optional(),
14779
+ description: exports_external.string().optional().default(""),
14780
+ instructions: exports_external.string().optional().default(""),
14781
+ avatar_url: exports_external.string().max(2000).nullable().optional(),
14782
+ email_handle: exports_external.string().max(30).optional()
14783
+ });
14784
+ var CreateStudioRequestSchema = exports_external.object({
14785
+ name: exports_external.string().max(100).optional(),
14786
+ scenario: exports_external.string().max(50).optional(),
14787
+ members: exports_external.array(StudioMemberSchema).min(1).max(4)
14788
+ }).refine((v) => v.members.some((m) => m.role === "leader"), { message: "at least one member must have the leader role" });
14764
14789
  // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260504.1_@opentelemetry+api@1.9.1_bun-types@1.3.13_kysely@0.28.16/node_modules/drizzle-orm/entity.js
14765
14790
  var entityKind = Symbol.for("drizzle:entityKind");
14766
14791
  var hasOwnEntityKind = Symbol.for("drizzle:hasOwnEntityKind");
@@ -16155,7 +16180,7 @@ var session = sqliteTable("session", {
16155
16180
  userAgent: text("userAgent"),
16156
16181
  createdAt: text("createdAt").notNull().$defaultFn(() => new Date().toISOString()),
16157
16182
  updatedAt: text("updatedAt").notNull().$defaultFn(() => new Date().toISOString())
16158
- });
16183
+ }, (t) => [index("idx_session_token_expires").on(t.token, t.expiresAt)]);
16159
16184
  var account = sqliteTable("account", {
16160
16185
  id: text("id").primaryKey().$defaultFn(() => nanoid3()),
16161
16186
  userId: text("userId").notNull().references(() => user.id, { onDelete: "cascade" }),
@@ -16402,6 +16427,18 @@ var issue2 = sqliteTable("issue", {
16402
16427
  foreignColumns: [agent.id, agent.workspaceId]
16403
16428
  }).onDelete("cascade")
16404
16429
  ]);
16430
+ var issueComment = sqliteTable("issue_comment", {
16431
+ id: text("id").primaryKey().$defaultFn(() => "ic_" + nanoid3()),
16432
+ issueId: text("issue_id").notNull().references(() => issue2.id, { onDelete: "cascade" }),
16433
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
16434
+ authorType: text("author_type").notNull().default("user"),
16435
+ authorId: text("author_id").notNull(),
16436
+ content: text("content").notNull(),
16437
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
16438
+ }, (t) => [
16439
+ index("idx_issue_comment_issue").on(t.issueId, t.createdAt),
16440
+ index("idx_issue_comment_workspace").on(t.workspaceId, t.issueId)
16441
+ ]);
16405
16442
  var taskMessage = sqliteTable("task_message", {
16406
16443
  id: text("id").primaryKey().$defaultFn(() => nanoid3()),
16407
16444
  taskId: text("task_id").notNull().references(() => agentTaskQueue.id, { onDelete: "cascade" }),
@@ -16413,7 +16450,10 @@ var taskMessage = sqliteTable("task_message", {
16413
16450
  input: text("input", { mode: "json" }),
16414
16451
  output: text("output").notNull().default(""),
16415
16452
  createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
16416
- }, (t) => [index("idx_task_message_task_seq").on(t.taskId, t.seq)]);
16453
+ }, (t) => [
16454
+ index("idx_task_message_task_seq").on(t.taskId, t.seq),
16455
+ index("idx_task_message_task_created").on(t.taskId, t.createdAt)
16456
+ ]);
16417
16457
  var emails = sqliteTable("emails", {
16418
16458
  id: text("id").primaryKey().$defaultFn(() => nanoid3()),
16419
16459
  agentId: text("agent_id").notNull(),
@@ -16436,7 +16476,12 @@ var emails = sqliteTable("emails", {
16436
16476
  foreignKey({
16437
16477
  columns: [t.agentId, t.workspaceId],
16438
16478
  foreignColumns: [agent.id, agent.workspaceId]
16439
- }).onDelete("cascade")
16479
+ }).onDelete("cascade"),
16480
+ index("idx_emails_agent_ws_status").on(t.agentId, t.workspaceId, t.status),
16481
+ index("idx_emails_to_direction").on(t.toEmail, t.direction),
16482
+ index("idx_emails_from_direction").on(t.fromEmail, t.direction),
16483
+ index("idx_emails_message_id").on(t.messageId),
16484
+ index("idx_emails_created_at").on(t.createdAt)
16440
16485
  ]);
16441
16486
  var calendarEvent = sqliteTable("calendar_event", {
16442
16487
  id: text("id").primaryKey().$defaultFn(() => "ce_" + nanoid3()),
@@ -16600,6 +16645,9 @@ var workspaceFileRequest = sqliteTable("workspace_file_request", {
16600
16645
  // ../shared/src/db/queries/task.ts
16601
16646
  var DEFAULT_STALE_SECONDS = Number(process.env.ALOOK_STALE_DISPATCH_TIMEOUT_S) || 20;
16602
16647
  var DEFAULT_STALE_RUNNING_SECONDS = Number(process.env.ALOOK_STALE_RUNNING_TIMEOUT_S) || 3600;
16648
+ // ../shared/src/db/queries/task-message.ts
16649
+ var HIDDEN_STEP_TYPES = ["status", "log", "tool-result", "text"];
16650
+ var FIXED_PARAMS = 1 + HIDDEN_STEP_TYPES.length;
16603
16651
  // ../shared/src/utils/email.ts
16604
16652
  var DOMAIN = `@${process.env.ALOOK_DOMAIN || "alook.ai"}`;
16605
16653
  var RESERVED_HANDLES = new Set([
@@ -18332,7 +18380,7 @@ function clearKillIntent(baseDir, taskId) {
18332
18380
  // daemon/prompt.ts
18333
18381
  var DM_RESPONSE_NOTICE = "IMPORTANT: Only your final text response is visible to the user." + " Tool calls, intermediate reasoning, and mid-process outputs are NOT displayed." + " Put all key information, answers, and conclusions in your final response — that is the only thing the user will read.";
18334
18382
  var EMAIL_NOTICE = "This task was triggered automatically by an incoming email. There is no human in this session." + " If you need to communicate with a human, you MUST send an email using the email sending tool." + " If you need more information or confirmation from the human, send them an email asking for it and then exit." + " Do not wait — when the human replies, a new task will be triggered automatically and you will be woken up with their response.";
18335
- var ISSUE_NOTICE = "This task was triggered by an assigned issue. Use `alook issue show`, `alook issue update`, and `alook issue comment` to inspect and update the issue as you work." + " Move the issue to in_progress when you begin, then to review, done, closed, canceled, or failed when appropriate.";
18383
+ var ISSUE_NOTICE = "This task was triggered by an assigned issue. The issue_id is provided in this message." + " Use `alook issue show --agent_id <your_agent_id> --issue_id <issue_id>` to read full context." + " Use `alook issue update --agent_id <your_agent_id> --issue_id <issue_id> --status <status>` to change status." + " Use `alook issue comment --agent_id <your_agent_id> --issue_id <issue_id> --body <text>` to leave a comment." + " You are responsible for setting the issue status: move to in_progress when working, review when awaiting user feedback, done/closed when finished." + " Always leave a comment summarizing what you did before changing status.";
18336
18384
  function buildDmNotice(name, email3) {
18337
18385
  return `This task was triggered by an incoming email on a conversation with ${name} (${email3}).` + ` ${name} is present in this session — reply to them directly.` + ` If you need to communicate with anyone else, use the email sending tool.`;
18338
18386
  }
@@ -18352,6 +18400,10 @@ function buildPrompt(task, attachments) {
18352
18400
  }
18353
18401
  if (task.type === "issue_event") {
18354
18402
  obj.notice = ISSUE_NOTICE;
18403
+ const ctx = task.context;
18404
+ if (ctx?.issue_id) {
18405
+ obj.issue_id = ctx.issue_id;
18406
+ }
18355
18407
  }
18356
18408
  if (task.sender) {
18357
18409
  obj.sender = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alook/cli",
3
- "version": "0.0.45",
3
+ "version": "0.0.47",
4
4
  "description": "Alook CLI — Enable Your Person Colleague",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/alookai/alook#readme",