@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.
- package/dist/cache/index.d.ts +1 -0
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +1 -0
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/user-cache.d.ts +20 -0
- package/dist/cache/user-cache.d.ts.map +1 -0
- package/dist/cache/user-cache.js +79 -0
- package/dist/cache/user-cache.js.map +1 -0
- package/dist/cmd/auth/logout.d.ts.map +1 -1
- package/dist/cmd/auth/logout.js +3 -1
- package/dist/cmd/auth/logout.js.map +1 -1
- package/dist/cmd/build/entry-generator.d.ts +4 -0
- package/dist/cmd/build/entry-generator.d.ts.map +1 -1
- package/dist/cmd/build/entry-generator.js +18 -3
- package/dist/cmd/build/entry-generator.js.map +1 -1
- package/dist/cmd/build/vite/bun-dev-server.d.ts +1 -0
- package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -1
- package/dist/cmd/build/vite/bun-dev-server.js +11 -9
- package/dist/cmd/build/vite/bun-dev-server.js.map +1 -1
- package/dist/cmd/cloud/db/stats.d.ts.map +1 -1
- package/dist/cmd/cloud/db/stats.js.map +1 -1
- package/dist/cmd/cloud/email/create.d.ts.map +1 -1
- package/dist/cmd/cloud/email/create.js +2 -7
- package/dist/cmd/cloud/email/create.js.map +1 -1
- package/dist/cmd/cloud/email/destination/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/email/destination/delete.js +5 -1
- package/dist/cmd/cloud/email/destination/delete.js.map +1 -1
- package/dist/cmd/cloud/email/get.d.ts.map +1 -1
- package/dist/cmd/cloud/email/get.js +30 -7
- package/dist/cmd/cloud/email/get.js.map +1 -1
- package/dist/cmd/cloud/email/list.d.ts.map +1 -1
- package/dist/cmd/cloud/email/list.js +0 -6
- package/dist/cmd/cloud/email/list.js.map +1 -1
- package/dist/cmd/cloud/email/send.d.ts.map +1 -1
- package/dist/cmd/cloud/email/send.js +1 -5
- package/dist/cmd/cloud/email/send.js.map +1 -1
- package/dist/cmd/cloud/email/stats.d.ts.map +1 -1
- package/dist/cmd/cloud/email/stats.js.map +1 -1
- package/dist/cmd/cloud/email/util.d.ts +0 -1
- package/dist/cmd/cloud/email/util.d.ts.map +1 -1
- package/dist/cmd/cloud/email/util.js +1 -3
- package/dist/cmd/cloud/email/util.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/build.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/build.js +4 -1
- package/dist/cmd/cloud/sandbox/snapshot/build.js.map +1 -1
- package/dist/cmd/cloud/sandbox/stats.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/stats.js.map +1 -1
- package/dist/cmd/cloud/schedule/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/schedule/delete.js +4 -1
- package/dist/cmd/cloud/schedule/delete.js.map +1 -1
- package/dist/cmd/cloud/schedule/delivery/list.d.ts.map +1 -1
- package/dist/cmd/cloud/schedule/delivery/list.js.map +1 -1
- package/dist/cmd/cloud/schedule/destination/create.d.ts.map +1 -1
- package/dist/cmd/cloud/schedule/destination/create.js +3 -1
- package/dist/cmd/cloud/schedule/destination/create.js.map +1 -1
- package/dist/cmd/cloud/schedule/destination/index.d.ts.map +1 -1
- package/dist/cmd/cloud/schedule/destination/index.js.map +1 -1
- package/dist/cmd/cloud/schedule/destination/list.d.ts.map +1 -1
- package/dist/cmd/cloud/schedule/destination/list.js.map +1 -1
- package/dist/cmd/cloud/schedule/get.d.ts.map +1 -1
- package/dist/cmd/cloud/schedule/get.js +4 -1
- package/dist/cmd/cloud/schedule/get.js.map +1 -1
- package/dist/cmd/cloud/schedule/index.d.ts.map +1 -1
- package/dist/cmd/cloud/schedule/index.js +4 -1
- package/dist/cmd/cloud/schedule/index.js.map +1 -1
- package/dist/cmd/cloud/schedule/list.d.ts.map +1 -1
- package/dist/cmd/cloud/schedule/list.js.map +1 -1
- package/dist/cmd/cloud/schedule/stats.d.ts.map +1 -1
- package/dist/cmd/cloud/schedule/stats.js.map +1 -1
- package/dist/cmd/cloud/schedule/util.d.ts.map +1 -1
- package/dist/cmd/cloud/schedule/util.js +1 -2
- package/dist/cmd/cloud/schedule/util.js.map +1 -1
- package/dist/cmd/cloud/services/stats.d.ts.map +1 -1
- package/dist/cmd/cloud/services/stats.js.map +1 -1
- package/dist/cmd/cloud/stream/index.d.ts.map +1 -1
- package/dist/cmd/cloud/stream/index.js +7 -1
- package/dist/cmd/cloud/stream/index.js.map +1 -1
- package/dist/cmd/cloud/stream/stats.d.ts.map +1 -1
- package/dist/cmd/cloud/stream/stats.js.map +1 -1
- package/dist/cmd/cloud/task/attachment.d.ts +2 -0
- package/dist/cmd/cloud/task/attachment.d.ts.map +1 -0
- package/dist/cmd/cloud/task/attachment.js +393 -0
- package/dist/cmd/cloud/task/attachment.js.map +1 -0
- package/dist/cmd/cloud/task/create.d.ts.map +1 -1
- package/dist/cmd/cloud/task/create.js +126 -5
- package/dist/cmd/cloud/task/create.js.map +1 -1
- package/dist/cmd/cloud/task/get.d.ts.map +1 -1
- package/dist/cmd/cloud/task/get.js +29 -11
- package/dist/cmd/cloud/task/get.js.map +1 -1
- package/dist/cmd/cloud/task/index.d.ts.map +1 -1
- package/dist/cmd/cloud/task/index.js +13 -1
- package/dist/cmd/cloud/task/index.js.map +1 -1
- package/dist/cmd/cloud/task/list.d.ts.map +1 -1
- package/dist/cmd/cloud/task/list.js +31 -15
- package/dist/cmd/cloud/task/list.js.map +1 -1
- package/dist/cmd/cloud/task/stats.js +2 -0
- package/dist/cmd/cloud/task/stats.js.map +1 -1
- package/dist/cmd/cloud/task/util.d.ts.map +1 -1
- package/dist/cmd/cloud/task/util.js +2 -4
- package/dist/cmd/cloud/task/util.js.map +1 -1
- package/dist/cmd/cloud/webhook/create.d.ts.map +1 -1
- package/dist/cmd/cloud/webhook/create.js +6 -1
- package/dist/cmd/cloud/webhook/create.js.map +1 -1
- package/dist/cmd/cloud/webhook/deliveries.d.ts.map +1 -1
- package/dist/cmd/cloud/webhook/deliveries.js +4 -1
- package/dist/cmd/cloud/webhook/deliveries.js.map +1 -1
- package/dist/cmd/cloud/webhook/destinations.d.ts.map +1 -1
- package/dist/cmd/cloud/webhook/destinations.js +4 -5
- package/dist/cmd/cloud/webhook/destinations.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +80 -34
- package/dist/cmd/dev/index.js.map +1 -1
- package/package.json +6 -6
- package/src/cache/index.ts +2 -0
- package/src/cache/user-cache.ts +93 -0
- package/src/cmd/auth/logout.ts +3 -1
- package/src/cmd/build/entry-generator.ts +34 -4
- package/src/cmd/build/vite/bun-dev-server.ts +21 -9
- package/src/cmd/cloud/db/stats.ts +4 -12
- package/src/cmd/cloud/email/create.ts +2 -7
- package/src/cmd/cloud/email/destination/delete.ts +5 -1
- package/src/cmd/cloud/email/get.ts +42 -7
- package/src/cmd/cloud/email/list.ts +0 -6
- package/src/cmd/cloud/email/send.ts +1 -5
- package/src/cmd/cloud/email/stats.ts +2 -6
- package/src/cmd/cloud/email/util.ts +1 -3
- package/src/cmd/cloud/sandbox/snapshot/build.ts +25 -6
- package/src/cmd/cloud/sandbox/stats.ts +2 -6
- package/src/cmd/cloud/schedule/delete.ts +4 -1
- package/src/cmd/cloud/schedule/delivery/list.ts +15 -13
- package/src/cmd/cloud/schedule/destination/create.ts +11 -3
- package/src/cmd/cloud/schedule/destination/index.ts +3 -1
- package/src/cmd/cloud/schedule/destination/list.ts +19 -17
- package/src/cmd/cloud/schedule/get.ts +25 -20
- package/src/cmd/cloud/schedule/index.ts +4 -1
- package/src/cmd/cloud/schedule/list.ts +18 -16
- package/src/cmd/cloud/schedule/stats.ts +1 -3
- package/src/cmd/cloud/schedule/util.ts +1 -2
- package/src/cmd/cloud/services/stats.ts +13 -39
- package/src/cmd/cloud/stream/index.ts +7 -1
- package/src/cmd/cloud/stream/stats.ts +2 -6
- package/src/cmd/cloud/task/attachment.ts +432 -0
- package/src/cmd/cloud/task/create.ts +131 -5
- package/src/cmd/cloud/task/get.ts +30 -12
- package/src/cmd/cloud/task/index.ts +13 -1
- package/src/cmd/cloud/task/list.ts +31 -15
- package/src/cmd/cloud/task/stats.ts +3 -3
- package/src/cmd/cloud/task/util.ts +2 -4
- package/src/cmd/cloud/webhook/create.ts +6 -1
- package/src/cmd/cloud/webhook/deliveries.ts +4 -5
- package/src/cmd/cloud/webhook/destinations.ts +4 -5
- 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
|
|
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:
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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.
|
|
90
|
-
tableData['Closed By'] = task.
|
|
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
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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({
|
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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 &&
|
|
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}`);
|