@agentuity/cli 1.0.24 → 1.0.26

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 (152) hide show
  1. package/dist/cache/index.d.ts +1 -0
  2. package/dist/cache/index.d.ts.map +1 -1
  3. package/dist/cache/index.js +1 -0
  4. package/dist/cache/index.js.map +1 -1
  5. package/dist/cache/user-cache.d.ts +20 -0
  6. package/dist/cache/user-cache.d.ts.map +1 -0
  7. package/dist/cache/user-cache.js +79 -0
  8. package/dist/cache/user-cache.js.map +1 -0
  9. package/dist/cmd/auth/logout.d.ts.map +1 -1
  10. package/dist/cmd/auth/logout.js +3 -1
  11. package/dist/cmd/auth/logout.js.map +1 -1
  12. package/dist/cmd/build/entry-generator.d.ts +4 -0
  13. package/dist/cmd/build/entry-generator.d.ts.map +1 -1
  14. package/dist/cmd/build/entry-generator.js +18 -3
  15. package/dist/cmd/build/entry-generator.js.map +1 -1
  16. package/dist/cmd/build/vite/bun-dev-server.d.ts +1 -0
  17. package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -1
  18. package/dist/cmd/build/vite/bun-dev-server.js +11 -9
  19. package/dist/cmd/build/vite/bun-dev-server.js.map +1 -1
  20. package/dist/cmd/cloud/db/stats.d.ts.map +1 -1
  21. package/dist/cmd/cloud/db/stats.js.map +1 -1
  22. package/dist/cmd/cloud/email/create.d.ts.map +1 -1
  23. package/dist/cmd/cloud/email/create.js +2 -7
  24. package/dist/cmd/cloud/email/create.js.map +1 -1
  25. package/dist/cmd/cloud/email/destination/delete.d.ts.map +1 -1
  26. package/dist/cmd/cloud/email/destination/delete.js +5 -1
  27. package/dist/cmd/cloud/email/destination/delete.js.map +1 -1
  28. package/dist/cmd/cloud/email/get.d.ts.map +1 -1
  29. package/dist/cmd/cloud/email/get.js +30 -7
  30. package/dist/cmd/cloud/email/get.js.map +1 -1
  31. package/dist/cmd/cloud/email/list.d.ts.map +1 -1
  32. package/dist/cmd/cloud/email/list.js +0 -6
  33. package/dist/cmd/cloud/email/list.js.map +1 -1
  34. package/dist/cmd/cloud/email/send.d.ts.map +1 -1
  35. package/dist/cmd/cloud/email/send.js +1 -5
  36. package/dist/cmd/cloud/email/send.js.map +1 -1
  37. package/dist/cmd/cloud/email/stats.d.ts.map +1 -1
  38. package/dist/cmd/cloud/email/stats.js.map +1 -1
  39. package/dist/cmd/cloud/email/util.d.ts +0 -1
  40. package/dist/cmd/cloud/email/util.d.ts.map +1 -1
  41. package/dist/cmd/cloud/email/util.js +1 -3
  42. package/dist/cmd/cloud/email/util.js.map +1 -1
  43. package/dist/cmd/cloud/sandbox/snapshot/build.d.ts.map +1 -1
  44. package/dist/cmd/cloud/sandbox/snapshot/build.js +4 -1
  45. package/dist/cmd/cloud/sandbox/snapshot/build.js.map +1 -1
  46. package/dist/cmd/cloud/sandbox/stats.d.ts.map +1 -1
  47. package/dist/cmd/cloud/sandbox/stats.js.map +1 -1
  48. package/dist/cmd/cloud/schedule/delete.d.ts.map +1 -1
  49. package/dist/cmd/cloud/schedule/delete.js +4 -1
  50. package/dist/cmd/cloud/schedule/delete.js.map +1 -1
  51. package/dist/cmd/cloud/schedule/delivery/list.d.ts.map +1 -1
  52. package/dist/cmd/cloud/schedule/delivery/list.js.map +1 -1
  53. package/dist/cmd/cloud/schedule/destination/create.d.ts.map +1 -1
  54. package/dist/cmd/cloud/schedule/destination/create.js +3 -1
  55. package/dist/cmd/cloud/schedule/destination/create.js.map +1 -1
  56. package/dist/cmd/cloud/schedule/destination/index.d.ts.map +1 -1
  57. package/dist/cmd/cloud/schedule/destination/index.js.map +1 -1
  58. package/dist/cmd/cloud/schedule/destination/list.d.ts.map +1 -1
  59. package/dist/cmd/cloud/schedule/destination/list.js.map +1 -1
  60. package/dist/cmd/cloud/schedule/get.d.ts.map +1 -1
  61. package/dist/cmd/cloud/schedule/get.js +4 -1
  62. package/dist/cmd/cloud/schedule/get.js.map +1 -1
  63. package/dist/cmd/cloud/schedule/index.d.ts.map +1 -1
  64. package/dist/cmd/cloud/schedule/index.js +4 -1
  65. package/dist/cmd/cloud/schedule/index.js.map +1 -1
  66. package/dist/cmd/cloud/schedule/list.d.ts.map +1 -1
  67. package/dist/cmd/cloud/schedule/list.js.map +1 -1
  68. package/dist/cmd/cloud/schedule/stats.d.ts.map +1 -1
  69. package/dist/cmd/cloud/schedule/stats.js.map +1 -1
  70. package/dist/cmd/cloud/schedule/util.d.ts.map +1 -1
  71. package/dist/cmd/cloud/schedule/util.js +1 -2
  72. package/dist/cmd/cloud/schedule/util.js.map +1 -1
  73. package/dist/cmd/cloud/services/stats.d.ts.map +1 -1
  74. package/dist/cmd/cloud/services/stats.js.map +1 -1
  75. package/dist/cmd/cloud/stream/index.d.ts.map +1 -1
  76. package/dist/cmd/cloud/stream/index.js +7 -1
  77. package/dist/cmd/cloud/stream/index.js.map +1 -1
  78. package/dist/cmd/cloud/stream/stats.d.ts.map +1 -1
  79. package/dist/cmd/cloud/stream/stats.js.map +1 -1
  80. package/dist/cmd/cloud/task/attachment.d.ts +2 -0
  81. package/dist/cmd/cloud/task/attachment.d.ts.map +1 -0
  82. package/dist/cmd/cloud/task/attachment.js +393 -0
  83. package/dist/cmd/cloud/task/attachment.js.map +1 -0
  84. package/dist/cmd/cloud/task/create.d.ts.map +1 -1
  85. package/dist/cmd/cloud/task/create.js +126 -5
  86. package/dist/cmd/cloud/task/create.js.map +1 -1
  87. package/dist/cmd/cloud/task/get.d.ts.map +1 -1
  88. package/dist/cmd/cloud/task/get.js +29 -11
  89. package/dist/cmd/cloud/task/get.js.map +1 -1
  90. package/dist/cmd/cloud/task/index.d.ts.map +1 -1
  91. package/dist/cmd/cloud/task/index.js +13 -1
  92. package/dist/cmd/cloud/task/index.js.map +1 -1
  93. package/dist/cmd/cloud/task/list.d.ts.map +1 -1
  94. package/dist/cmd/cloud/task/list.js +31 -15
  95. package/dist/cmd/cloud/task/list.js.map +1 -1
  96. package/dist/cmd/cloud/task/stats.js +2 -0
  97. package/dist/cmd/cloud/task/stats.js.map +1 -1
  98. package/dist/cmd/cloud/task/util.d.ts.map +1 -1
  99. package/dist/cmd/cloud/task/util.js +2 -4
  100. package/dist/cmd/cloud/task/util.js.map +1 -1
  101. package/dist/cmd/cloud/webhook/create.d.ts.map +1 -1
  102. package/dist/cmd/cloud/webhook/create.js +6 -1
  103. package/dist/cmd/cloud/webhook/create.js.map +1 -1
  104. package/dist/cmd/cloud/webhook/deliveries.d.ts.map +1 -1
  105. package/dist/cmd/cloud/webhook/deliveries.js +4 -1
  106. package/dist/cmd/cloud/webhook/deliveries.js.map +1 -1
  107. package/dist/cmd/cloud/webhook/destinations.d.ts.map +1 -1
  108. package/dist/cmd/cloud/webhook/destinations.js +4 -5
  109. package/dist/cmd/cloud/webhook/destinations.js.map +1 -1
  110. package/dist/cmd/dev/index.d.ts.map +1 -1
  111. package/dist/cmd/dev/index.js +80 -34
  112. package/dist/cmd/dev/index.js.map +1 -1
  113. package/package.json +6 -6
  114. package/src/cache/index.ts +2 -0
  115. package/src/cache/user-cache.ts +93 -0
  116. package/src/cmd/auth/logout.ts +3 -1
  117. package/src/cmd/build/entry-generator.ts +34 -4
  118. package/src/cmd/build/vite/bun-dev-server.ts +21 -9
  119. package/src/cmd/cloud/db/stats.ts +4 -12
  120. package/src/cmd/cloud/email/create.ts +2 -7
  121. package/src/cmd/cloud/email/destination/delete.ts +5 -1
  122. package/src/cmd/cloud/email/get.ts +42 -7
  123. package/src/cmd/cloud/email/list.ts +0 -6
  124. package/src/cmd/cloud/email/send.ts +1 -5
  125. package/src/cmd/cloud/email/stats.ts +2 -6
  126. package/src/cmd/cloud/email/util.ts +1 -3
  127. package/src/cmd/cloud/sandbox/snapshot/build.ts +25 -6
  128. package/src/cmd/cloud/sandbox/stats.ts +2 -6
  129. package/src/cmd/cloud/schedule/delete.ts +4 -1
  130. package/src/cmd/cloud/schedule/delivery/list.ts +15 -13
  131. package/src/cmd/cloud/schedule/destination/create.ts +11 -3
  132. package/src/cmd/cloud/schedule/destination/index.ts +3 -1
  133. package/src/cmd/cloud/schedule/destination/list.ts +19 -17
  134. package/src/cmd/cloud/schedule/get.ts +25 -20
  135. package/src/cmd/cloud/schedule/index.ts +4 -1
  136. package/src/cmd/cloud/schedule/list.ts +18 -16
  137. package/src/cmd/cloud/schedule/stats.ts +1 -3
  138. package/src/cmd/cloud/schedule/util.ts +1 -2
  139. package/src/cmd/cloud/services/stats.ts +13 -39
  140. package/src/cmd/cloud/stream/index.ts +7 -1
  141. package/src/cmd/cloud/stream/stats.ts +2 -6
  142. package/src/cmd/cloud/task/attachment.ts +432 -0
  143. package/src/cmd/cloud/task/create.ts +131 -5
  144. package/src/cmd/cloud/task/get.ts +30 -12
  145. package/src/cmd/cloud/task/index.ts +13 -1
  146. package/src/cmd/cloud/task/list.ts +31 -15
  147. package/src/cmd/cloud/task/stats.ts +3 -3
  148. package/src/cmd/cloud/task/util.ts +2 -4
  149. package/src/cmd/cloud/webhook/create.ts +6 -1
  150. package/src/cmd/cloud/webhook/deliveries.ts +4 -5
  151. package/src/cmd/cloud/webhook/destinations.ts +4 -5
  152. package/src/cmd/dev/index.ts +91 -48
@@ -1,9 +1,13 @@
1
+ import { basename, join } from 'path';
1
2
  import { z } from 'zod';
2
3
  import { createCommand } from '../../../types';
3
4
  import * as tui from '../../../tui';
4
5
  import { createStorageAdapter, parseMetadataFlag, cacheTaskId } from './util';
5
6
  import { getCommand } from '../../../command-prefix';
7
+ import { whoami } from '@agentuity/server';
6
8
  import type { TaskPriority, TaskStatus, TaskType } from '@agentuity/core';
9
+ import { getCachedUserInfo, setCachedUserInfo } from '../../../cache';
10
+ import { defaultProfileName } from '../../../config';
7
11
 
8
12
  const TaskCreateResponseSchema = z.object({
9
13
  success: z.boolean().describe('Whether the operation succeeded'),
@@ -15,6 +19,13 @@ const TaskCreateResponseSchema = z.object({
15
19
  priority: z.string().describe('Task priority'),
16
20
  created_at: z.string().describe('Creation timestamp'),
17
21
  }),
22
+ attachment: z
23
+ .object({
24
+ id: z.string().describe('Attachment ID'),
25
+ filename: z.string().describe('Attached filename'),
26
+ })
27
+ .optional()
28
+ .describe('Attached file info (when --file is used)'),
18
29
  durationMs: z.number().describe('Operation duration in milliseconds'),
19
30
  });
20
31
 
@@ -23,7 +34,8 @@ export const createSubcommand = createCommand({
23
34
  aliases: ['new', 'add'],
24
35
  description: 'Create a new task',
25
36
  tags: ['mutating', 'slow', 'requires-auth'],
26
- requires: { auth: true },
37
+ requires: { auth: true, apiClient: true },
38
+ optional: { project: true },
27
39
  examples: [
28
40
  {
29
41
  command: getCommand('cloud task create "Fix login bug" --type bug --created-id agent_001'),
@@ -48,19 +60,34 @@ export const createSubcommand = createCommand({
48
60
  }),
49
61
  options: z.object({
50
62
  type: z.enum(['epic', 'feature', 'enhancement', 'bug', 'task']).describe('the task type'),
51
- createdId: z.string().min(1).describe('the ID of the creator (agent or user)'),
63
+ createdId: z
64
+ .string()
65
+ .min(1)
66
+ .optional()
67
+ .describe('the ID of the creator (agent or user, defaults to authenticated user)'),
68
+ createdName: z
69
+ .string()
70
+ .min(1)
71
+ .optional()
72
+ .describe('the display name of the creator (used with --created-id)'),
73
+ projectId: z.string().optional().describe('project ID to associate with the task'),
74
+ projectName: z
75
+ .string()
76
+ .optional()
77
+ .describe('project display name (used with --project-id)'),
52
78
  description: z.string().optional().describe('task description'),
53
79
  priority: z
54
80
  .enum(['high', 'medium', 'low', 'none'])
55
81
  .optional()
56
82
  .describe('task priority (default: none)'),
57
83
  status: z
58
- .enum(['open', 'in_progress', 'closed'])
84
+ .enum(['open', 'in_progress', 'closed', 'done', 'cancelled'])
59
85
  .optional()
60
86
  .describe('initial task status (default: open)'),
61
87
  parentId: z.string().optional().describe('parent task ID for subtasks'),
62
88
  assignedId: z.string().optional().describe('ID of the assigned agent or user'),
63
89
  metadata: z.string().optional().describe('JSON metadata object'),
90
+ file: z.string().optional().describe('file path to attach to the task'),
64
91
  }),
65
92
  response: TaskCreateResponseSchema,
66
93
  },
@@ -72,10 +99,65 @@ export const createSubcommand = createCommand({
72
99
 
73
100
  const metadata = parseMetadataFlag(opts.metadata);
74
101
 
102
+ // Resolve creator info
103
+ const createdId = opts.createdId ?? ctx.auth.userId;
104
+ let creator: { id: string; name: string } | undefined;
105
+ if (opts.createdId && opts.createdName) {
106
+ // Explicit creator with name
107
+ creator = { id: opts.createdId, name: opts.createdName };
108
+ } else if (!opts.createdId) {
109
+ // Using auth userId — check cache first, then fall back to whoami API call
110
+ const profileName = ctx.config?.name ?? defaultProfileName;
111
+ const cached = getCachedUserInfo(profileName);
112
+ if (cached) {
113
+ const name = [cached.firstName, cached.lastName].filter(Boolean).join(' ');
114
+ if (name) {
115
+ creator = { id: createdId, name };
116
+ }
117
+ } else {
118
+ // Fetch from API and cache
119
+ try {
120
+ const user = await whoami(ctx.apiClient);
121
+ const name = [user.firstName, user.lastName].filter(Boolean).join(' ');
122
+ if (name) {
123
+ creator = { id: createdId, name };
124
+ }
125
+ setCachedUserInfo(profileName, createdId, user.firstName, user.lastName);
126
+ } catch {
127
+ // Fall back to no creator EntityRef — task DB will use id as name
128
+ }
129
+ }
130
+ }
131
+
132
+ // Resolve project info
133
+ let project: { id: string; name: string } | undefined;
134
+ if (opts.projectId) {
135
+ // Explicit project via flags
136
+ project = { id: opts.projectId, name: opts.projectName ?? opts.projectId };
137
+ } else if (ctx.project?.projectId) {
138
+ // Auto-detect from project context — read name from package.json
139
+ let projectName = ctx.project.projectId;
140
+ try {
141
+ const pkgPath = join(ctx.projectDir, 'package.json');
142
+ const pkgFile = Bun.file(pkgPath);
143
+ if (await pkgFile.exists()) {
144
+ const pkg = await pkgFile.json();
145
+ if (pkg.name) {
146
+ projectName = pkg.name;
147
+ }
148
+ }
149
+ } catch {
150
+ // Fall back to projectId as name
151
+ }
152
+ project = { id: ctx.project.projectId, name: projectName };
153
+ }
154
+
75
155
  const task = await storage.create({
76
156
  title: args.title,
77
157
  type: opts.type as TaskType,
78
- created_id: opts.createdId,
158
+ created_id: createdId,
159
+ creator,
160
+ project,
79
161
  description: opts.description,
80
162
  priority: opts.priority as TaskPriority,
81
163
  status: opts.status as TaskStatus,
@@ -84,9 +166,44 @@ export const createSubcommand = createCommand({
84
166
  metadata,
85
167
  });
86
168
 
87
- const durationMs = Date.now() - started;
88
169
  await cacheTaskId(ctx, task.id);
89
170
 
171
+ // Handle --file attachment
172
+ let attachmentInfo: { id: string; filename: string } | undefined;
173
+ if (opts.file) {
174
+ const file = Bun.file(opts.file);
175
+ if (!(await file.exists())) {
176
+ tui.fatal(`File not found: ${opts.file}`);
177
+ }
178
+
179
+ const filename = basename(opts.file);
180
+ const contentType = file.type || 'application/octet-stream';
181
+ const size = file.size;
182
+
183
+ const presign = await storage.uploadAttachment(task.id, {
184
+ filename,
185
+ content_type: contentType,
186
+ size,
187
+ });
188
+
189
+ const uploadResponse = await fetch(presign.presigned_url, {
190
+ method: 'PUT',
191
+ body: file.stream(),
192
+ headers: {
193
+ 'Content-Type': contentType,
194
+ },
195
+ duplex: 'half',
196
+ });
197
+ if (!uploadResponse.ok) {
198
+ tui.fatal(`Attachment upload failed: ${uploadResponse.statusText}`);
199
+ }
200
+
201
+ const attachment = await storage.confirmAttachment(presign.attachment.id);
202
+ attachmentInfo = { id: attachment.id, filename: attachment.filename };
203
+ }
204
+
205
+ const durationMs = Date.now() - started;
206
+
90
207
  if (!options.json) {
91
208
  tui.success(`Task created: ${tui.bold(task.id)}`);
92
209
 
@@ -102,6 +219,14 @@ export const createSubcommand = createCommand({
102
219
  tableData['Description'] = task.description;
103
220
  }
104
221
 
222
+ if (project) {
223
+ tableData['Project'] = project.name;
224
+ }
225
+
226
+ if (attachmentInfo) {
227
+ tableData['Attachment'] = `${attachmentInfo.filename} (${attachmentInfo.id})`;
228
+ }
229
+
105
230
  tui.table([tableData], Object.keys(tableData), { layout: 'vertical', padStart: ' ' });
106
231
  }
107
232
 
@@ -115,6 +240,7 @@ export const createSubcommand = createCommand({
115
240
  priority: task.priority,
116
241
  created_at: task.created_at,
117
242
  },
243
+ ...(attachmentInfo ? { attachment: attachmentInfo } : {}),
118
244
  durationMs,
119
245
  };
120
246
  },
@@ -4,6 +4,13 @@ import * as tui from '../../../tui';
4
4
  import { createStorageAdapter, cacheTaskId } from './util';
5
5
  import { getCommand } from '../../../command-prefix';
6
6
 
7
+ const EntityRefSchema = z
8
+ .object({
9
+ id: z.string(),
10
+ name: z.string(),
11
+ })
12
+ .optional();
13
+
7
14
  const TaskGetResponseSchema = z.object({
8
15
  success: z.boolean().describe('Whether the operation succeeded'),
9
16
  task: z.object({
@@ -14,15 +21,17 @@ const TaskGetResponseSchema = z.object({
14
21
  status: z.string().describe('Task status'),
15
22
  priority: z.string().describe('Task priority'),
16
23
  parent_id: z.string().optional().describe('Parent task ID'),
17
- assigned_id: z.string().optional().describe('Assigned agent or user ID'),
18
- created_id: z.string().describe('Creator ID'),
19
- closed_id: z.string().optional().describe('Closer ID'),
24
+ creator: EntityRefSchema.describe('Creator'),
25
+ assignee: EntityRefSchema.describe('Assignee'),
26
+ closer: EntityRefSchema.describe('Closer'),
27
+ project: EntityRefSchema.describe('Project'),
20
28
  metadata: z.record(z.string(), z.unknown()).optional().describe('Task metadata'),
21
29
  created_at: z.string().describe('Creation timestamp'),
22
30
  updated_at: z.string().describe('Last update timestamp'),
23
31
  open_date: z.string().optional().describe('Date task was opened'),
24
32
  in_progress_date: z.string().optional().describe('Date task moved to in-progress'),
25
33
  closed_date: z.string().optional().describe('Date task was closed'),
34
+ cancelled_date: z.string().optional().describe('Date task was cancelled'),
26
35
  }),
27
36
  durationMs: z.number().describe('Operation duration in milliseconds'),
28
37
  });
@@ -78,16 +87,20 @@ export const getSubcommand = createCommand({
78
87
  tableData['Description'] = task.description;
79
88
  }
80
89
 
81
- tableData['Creator'] = task.created_id;
82
-
83
- if (task.assigned_id) {
84
- tableData['Assigned'] = task.assigned_id;
90
+ if (task.creator) {
91
+ tableData['Creator'] = `${task.creator.name} (${task.creator.id})`;
92
+ }
93
+ if (task.assignee) {
94
+ tableData['Assigned'] = `${task.assignee.name} (${task.assignee.id})`;
95
+ }
96
+ if (task.project) {
97
+ tableData['Project'] = `${task.project.name} (${task.project.id})`;
85
98
  }
86
99
  if (task.parent_id) {
87
100
  tableData['Parent'] = task.parent_id;
88
101
  }
89
- if (task.closed_id) {
90
- tableData['Closed By'] = task.closed_id;
102
+ if (task.closer) {
103
+ tableData['Closed By'] = `${task.closer.name} (${task.closer.id})`;
91
104
  }
92
105
 
93
106
  tableData['Created'] = new Date(task.created_at).toLocaleString();
@@ -102,6 +115,9 @@ export const getSubcommand = createCommand({
102
115
  if (task.closed_date) {
103
116
  tableData['Closed'] = new Date(task.closed_date).toLocaleString();
104
117
  }
118
+ if (task.cancelled_date) {
119
+ tableData['Cancelled'] = new Date(task.cancelled_date).toLocaleString();
120
+ }
105
121
  tui.table([tableData], Object.keys(tableData), { layout: 'vertical', padStart: ' ' });
106
122
 
107
123
  if (task.metadata && Object.keys(task.metadata).length > 0) {
@@ -121,15 +137,17 @@ export const getSubcommand = createCommand({
121
137
  status: task.status,
122
138
  priority: task.priority,
123
139
  parent_id: task.parent_id,
124
- assigned_id: task.assigned_id,
125
- created_id: task.created_id,
126
- closed_id: task.closed_id,
140
+ creator: task.creator,
141
+ assignee: task.assignee,
142
+ closer: task.closer,
143
+ project: task.project,
127
144
  metadata: task.metadata,
128
145
  created_at: task.created_at,
129
146
  updated_at: task.updated_at,
130
147
  open_date: task.open_date,
131
148
  in_progress_date: task.in_progress_date,
132
149
  closed_date: task.closed_date,
150
+ cancelled_date: task.cancelled_date,
133
151
  },
134
152
  durationMs,
135
153
  };
@@ -4,6 +4,7 @@ import { createSubcommand } from './create';
4
4
  import { updateSubcommand } from './update';
5
5
  import { listSubcommand } from './list';
6
6
  import { statsSubcommand } from './stats';
7
+ import { attachmentSubcommand } from './attachment';
7
8
  import { getCommand } from '../../../command-prefix';
8
9
 
9
10
  export const taskCommand = createCommand({
@@ -27,8 +28,19 @@ export const taskCommand = createCommand({
27
28
  command: getCommand('cloud task update task_abc123 --status in_progress'),
28
29
  description: 'Update task status',
29
30
  },
31
+ {
32
+ command: getCommand('cloud task attachment upload task_abc123 ./report.pdf'),
33
+ description: 'Upload a file attachment to a task',
34
+ },
35
+ ],
36
+ subcommands: [
37
+ getSubcommand,
38
+ createSubcommand,
39
+ updateSubcommand,
40
+ listSubcommand,
41
+ statsSubcommand,
42
+ attachmentSubcommand,
30
43
  ],
31
- subcommands: [getSubcommand, createSubcommand, updateSubcommand, listSubcommand, statsSubcommand],
32
44
  requires: { auth: true },
33
45
  });
34
46
 
@@ -14,7 +14,24 @@ const TaskListResponseSchema = z.object({
14
14
  type: z.string(),
15
15
  status: z.string(),
16
16
  priority: z.string(),
17
- assigned_id: z.string().optional(),
17
+ creator: z
18
+ .object({
19
+ id: z.string(),
20
+ name: z.string(),
21
+ })
22
+ .optional(),
23
+ assignee: z
24
+ .object({
25
+ id: z.string(),
26
+ name: z.string(),
27
+ })
28
+ .optional(),
29
+ project: z
30
+ .object({
31
+ id: z.string(),
32
+ name: z.string(),
33
+ })
34
+ .optional(),
18
35
  created_at: z.string(),
19
36
  updated_at: z.string(),
20
37
  })
@@ -35,7 +52,9 @@ const PRIORITY_COLORS: Record<string, (s: string) => string> = {
35
52
  const STATUS_COLORS: Record<string, (s: string) => string> = {
36
53
  open: tui.colorSuccess,
37
54
  in_progress: tui.colorWarning,
55
+ done: tui.colorInfo,
38
56
  closed: tui.muted,
57
+ cancelled: tui.muted,
39
58
  };
40
59
 
41
60
  function formatPriority(p: string): string {
@@ -86,7 +105,10 @@ export const listSubcommand = createCommand({
86
105
  ],
87
106
  schema: {
88
107
  options: z.object({
89
- status: z.enum(['open', 'in_progress', 'closed']).optional().describe('filter by status'),
108
+ status: z
109
+ .enum(['open', 'in_progress', 'done', 'closed', 'cancelled'])
110
+ .optional()
111
+ .describe('filter by status'),
90
112
  type: z
91
113
  .enum(['epic', 'feature', 'enhancement', 'bug', 'task'])
92
114
  .optional()
@@ -98,17 +120,7 @@ export const listSubcommand = createCommand({
98
120
  assignedId: z.string().optional().describe('filter by assigned agent or user ID'),
99
121
  parentId: z.string().optional().describe('filter by parent task ID'),
100
122
  sort: z
101
- .enum([
102
- 'created_at',
103
- 'updated_at',
104
- 'priority',
105
- 'status',
106
- 'title',
107
- 'type',
108
- 'open_date',
109
- 'in_progress_date',
110
- 'closed_date',
111
- ])
123
+ .enum(['created_at', 'updated_at', 'priority'])
112
124
  .optional()
113
125
  .describe('field to sort by (default: created_at)'),
114
126
  order: z.enum(['asc', 'desc']).optional().describe('sort order (default: desc)'),
@@ -147,7 +159,8 @@ export const listSubcommand = createCommand({
147
159
  Type: task.type,
148
160
  Status: formatStatus(task.status),
149
161
  Priority: formatPriority(task.priority),
150
- Assigned: task.assigned_id ?? tui.muted('—'),
162
+ Creator: task.creator?.name ? truncate(task.creator.name, 20) : tui.muted('—'),
163
+ Assigned: task.assignee?.name ? truncate(task.assignee.name, 20) : tui.muted('—'),
151
164
  Updated: new Date(task.updated_at).toLocaleDateString(),
152
165
  }));
153
166
 
@@ -157,6 +170,7 @@ export const listSubcommand = createCommand({
157
170
  { name: 'Type', alignment: 'left' },
158
171
  { name: 'Status', alignment: 'left' },
159
172
  { name: 'Priority', alignment: 'left' },
173
+ { name: 'Creator', alignment: 'left' },
160
174
  { name: 'Assigned', alignment: 'left' },
161
175
  { name: 'Updated', alignment: 'left' },
162
176
  ]);
@@ -175,7 +189,9 @@ export const listSubcommand = createCommand({
175
189
  type: task.type,
176
190
  status: task.status,
177
191
  priority: task.priority,
178
- assigned_id: task.assigned_id,
192
+ creator: task.creator,
193
+ assignee: task.assignee,
194
+ project: task.project,
179
195
  created_at: task.created_at,
180
196
  updated_at: task.updated_at,
181
197
  })),
@@ -21,10 +21,10 @@ function displayStats(data: ServiceStatsData): void {
21
21
  tui.newline();
22
22
  console.log(` ${tui.muted('Total:')} ${formatNumber(svc.total)}`);
23
23
  console.log(` ${tui.muted('Open:')} ${formatNumber(svc.open)}`);
24
- console.log(
25
- ` ${tui.muted('In Progress:')} ${formatNumber(svc.inProgress)}`
26
- );
24
+ console.log(` ${tui.muted('In Progress:')} ${formatNumber(svc.inProgress)}`);
25
+ console.log(` ${tui.muted('Done:')} ${formatNumber(svc.done)}`);
27
26
  console.log(` ${tui.muted('Closed:')} ${formatNumber(svc.closed)}`);
27
+ console.log(` ${tui.muted('Cancelled:')} ${formatNumber(svc.cancelled)}`);
28
28
  }
29
29
 
30
30
  export const statsSubcommand = createCommand({
@@ -15,8 +15,7 @@ export interface TaskContext {
15
15
 
16
16
  export async function createStorageAdapter(ctx: TaskContext) {
17
17
  const orgId =
18
- ctx.options.orgId ??
19
- (process.env.AGENTUITY_CLOUD_ORG_ID || ctx.config?.preferences?.orgId);
18
+ ctx.options.orgId ?? (process.env.AGENTUITY_CLOUD_ORG_ID || ctx.config?.preferences?.orgId);
20
19
  if (!orgId) {
21
20
  tui.fatal('Organization ID is required. Use --org-id flag or set AGENTUITY_CLOUD_ORG_ID.');
22
21
  }
@@ -47,8 +46,7 @@ export async function cacheTaskId(
47
46
  const profileName = ctx.config?.name ?? defaultProfileName;
48
47
  const region = await getDefaultRegion(profileName, ctx.config);
49
48
  const orgId =
50
- ctx.options.orgId ??
51
- (process.env.AGENTUITY_CLOUD_ORG_ID || ctx.config?.preferences?.orgId);
49
+ ctx.options.orgId ?? (process.env.AGENTUITY_CLOUD_ORG_ID || ctx.config?.preferences?.orgId);
52
50
  await setResourceInfo('task', profileName, taskId, region, orgId);
53
51
  }
54
52
 
@@ -5,7 +5,12 @@ import { createWebhookAPIClient, getWebhookApiOptions } from './util';
5
5
  import { getCommand } from '../../../command-prefix';
6
6
  import { createWebhook, WebhookSchema } from '@agentuity/server';
7
7
 
8
- const WebhookCreateResponseSchema = WebhookSchema.pick({ id: true, name: true, url: true, created_at: true });
8
+ const WebhookCreateResponseSchema = WebhookSchema.pick({
9
+ id: true,
10
+ name: true,
11
+ url: true,
12
+ created_at: true,
13
+ });
9
14
 
10
15
  export const createSubcommand = createCommand({
11
16
  name: 'create',
@@ -130,11 +130,10 @@ const retryDeliverySubcommand = createSubcommand({
130
130
 
131
131
  if (!options.json) {
132
132
  tui.success(`Retried delivery: ${tui.bold(delivery.id)}`);
133
- tui.table(
134
- [{ ID: delivery.id, Status: delivery.status }],
135
- ['ID', 'Status'],
136
- { layout: 'vertical', padStart: ' ' }
137
- );
133
+ tui.table([{ ID: delivery.id, Status: delivery.status }], ['ID', 'Status'], {
134
+ layout: 'vertical',
135
+ padStart: ' ',
136
+ });
138
137
  }
139
138
 
140
139
  return delivery;
@@ -59,10 +59,7 @@ const listDestinationsSubcommand = createSubcommand({
59
59
  } else {
60
60
  const tableData = destinations.map((d: WebhookDestination) => {
61
61
  const config =
62
- d.type === 'url' &&
63
- d.config &&
64
- typeof d.config === 'object' &&
65
- 'url' in d.config
62
+ d.type === 'url' && d.config && typeof d.config === 'object' && 'url' in d.config
66
63
  ? String((d.config as Record<string, unknown>).url)
67
64
  : JSON.stringify(d.config);
68
65
  return {
@@ -192,7 +189,9 @@ const updateDestinationSubcommand = createSubcommand({
192
189
  if (!options.json) {
193
190
  tui.success(`Updated destination: ${destination.id}`);
194
191
  const url =
195
- destination.config && typeof destination.config === 'object' && 'url' in destination.config
192
+ destination.config &&
193
+ typeof destination.config === 'object' &&
194
+ 'url' in destination.config
196
195
  ? (destination.config as Record<string, unknown>).url
197
196
  : JSON.stringify(destination.config);
198
197
  console.log(` URL: ${url}`);