@agentuity/core 1.0.29 → 1.0.30

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.
@@ -1,245 +1,1249 @@
1
1
  import { FetchAdapter } from './adapter.ts';
2
+ /**
3
+ * Priority level for a task, from highest (`'high'`) to no priority (`'none'`).
4
+ */
2
5
  export type TaskPriority = 'high' | 'medium' | 'low' | 'none';
6
+ /**
7
+ * The classification of a task.
8
+ *
9
+ * - `'epic'` — Large initiatives that span multiple features or tasks.
10
+ * - `'feature'` — New capabilities to be built.
11
+ * - `'enhancement'` — Improvements to existing features.
12
+ * - `'bug'` — Defects to be fixed.
13
+ * - `'task'` — General work items.
14
+ */
3
15
  export type TaskType = 'epic' | 'feature' | 'enhancement' | 'bug' | 'task';
16
+ /**
17
+ * The lifecycle status of a task.
18
+ *
19
+ * - `'open'` — Created, not yet started.
20
+ * - `'in_progress'` — Actively being worked on.
21
+ * - `'done'` — Work completed.
22
+ * - `'closed'` — Resolved and closed.
23
+ * - `'cancelled'` — Abandoned.
24
+ */
4
25
  export type TaskStatus = 'open' | 'in_progress' | 'closed' | 'done' | 'cancelled';
26
+ /**
27
+ * A lightweight reference to a user or project entity, containing just the ID
28
+ * and display name. Used for creator, assignee, closer, and project associations.
29
+ */
5
30
  export interface EntityRef {
31
+ /** Unique identifier of the referenced entity. */
6
32
  id: string;
33
+ /** Human-readable display name of the entity. */
7
34
  name: string;
8
35
  }
36
+ /**
37
+ * A work item in the task management system.
38
+ *
39
+ * Tasks can represent epics, features, bugs, enhancements, or generic tasks.
40
+ * They support hierarchical organization via {@link Task.parent_id | parent_id},
41
+ * assignment tracking, and lifecycle management through status transitions.
42
+ *
43
+ * @remarks
44
+ * Status transitions are tracked automatically — when a task moves to a new status,
45
+ * the corresponding date field (e.g., {@link Task.open_date | open_date},
46
+ * {@link Task.in_progress_date | in_progress_date}) is set by the server.
47
+ */
9
48
  export interface Task {
49
+ /** Unique identifier for the task. */
10
50
  id: string;
51
+ /** ISO 8601 timestamp when the task was created. */
11
52
  created_at: string;
53
+ /** ISO 8601 timestamp when the task was last modified. */
12
54
  updated_at: string;
55
+ /**
56
+ * The task title.
57
+ *
58
+ * @remarks Must be non-empty and at most 1024 characters.
59
+ */
13
60
  title: string;
61
+ /**
62
+ * Detailed description of the task.
63
+ *
64
+ * @remarks Maximum 65,536 characters.
65
+ */
14
66
  description?: string;
67
+ /**
68
+ * Arbitrary key-value metadata attached to the task.
69
+ * Can be used for custom fields, integrations, or filtering.
70
+ */
15
71
  metadata?: Record<string, unknown>;
72
+ /** The priority level of the task. */
16
73
  priority: TaskPriority;
74
+ /**
75
+ * ID of the parent task, enabling hierarchical task organization
76
+ * (e.g., an epic containing features).
77
+ */
17
78
  parent_id?: string;
79
+ /** The classification of this task. */
18
80
  type: TaskType;
81
+ /** The current lifecycle status of the task. */
19
82
  status: TaskStatus;
83
+ /** ISO 8601 timestamp when the task was moved to `'open'` status. */
20
84
  open_date?: string;
85
+ /** ISO 8601 timestamp when the task was moved to `'in_progress'` status. */
21
86
  in_progress_date?: string;
87
+ /** ISO 8601 timestamp when the task was closed. */
22
88
  closed_date?: string;
89
+ /**
90
+ * ID of the user who created the task.
91
+ *
92
+ * @remarks Legacy field; prefer {@link Task.creator | creator}.
93
+ */
23
94
  created_id: string;
95
+ /**
96
+ * ID of the user the task is assigned to.
97
+ *
98
+ * @remarks Legacy field; prefer {@link Task.assignee | assignee}.
99
+ */
24
100
  assigned_id?: string;
101
+ /**
102
+ * ID of the user who closed the task.
103
+ *
104
+ * @remarks Legacy field; prefer {@link Task.closer | closer}.
105
+ */
25
106
  closed_id?: string;
107
+ /** Reference to the user who created the task. */
26
108
  creator?: EntityRef;
109
+ /** Reference to the user the task is assigned to. */
27
110
  assignee?: EntityRef;
111
+ /** Reference to the user who closed the task. */
28
112
  closer?: EntityRef;
113
+ /** Reference to the project this task belongs to. */
29
114
  project?: EntityRef;
115
+ /** ISO 8601 timestamp when the task was cancelled. */
30
116
  cancelled_date?: string;
31
- deleted: boolean;
117
+ /** Array of tags associated with this task. */
32
118
  tags?: Tag[];
119
+ /** Array of comments on this task. */
33
120
  comments?: Comment[];
34
121
  }
122
+ /**
123
+ * A comment on a task, supporting threaded discussion.
124
+ */
35
125
  export interface Comment {
126
+ /** Unique identifier for the comment. */
36
127
  id: string;
128
+ /** ISO 8601 timestamp when the comment was created. */
37
129
  created_at: string;
130
+ /** ISO 8601 timestamp when the comment was last edited. */
38
131
  updated_at: string;
132
+ /** ID of the task this comment belongs to. */
39
133
  task_id: string;
134
+ /** ID of the user who authored the comment. */
40
135
  user_id: string;
136
+ /** Reference to the comment author with display name. */
41
137
  author?: EntityRef;
138
+ /**
139
+ * The comment text content.
140
+ *
141
+ * @remarks Must be non-empty.
142
+ */
42
143
  body: string;
43
144
  }
145
+ /**
146
+ * A label that can be applied to tasks for categorization and filtering.
147
+ */
44
148
  export interface Tag {
149
+ /** Unique identifier for the tag. */
45
150
  id: string;
151
+ /** ISO 8601 timestamp when the tag was created. */
46
152
  created_at: string;
153
+ /** Display name of the tag. */
47
154
  name: string;
155
+ /**
156
+ * Optional hex color code for the tag.
157
+ *
158
+ * @example '#ff0000'
159
+ */
48
160
  color?: string;
49
161
  }
162
+ /**
163
+ * A record of a single field change on a task, providing an audit trail.
164
+ */
50
165
  export interface TaskChangelogEntry {
166
+ /** Unique identifier for the changelog entry. */
51
167
  id: string;
168
+ /** ISO 8601 timestamp when the change occurred. */
52
169
  created_at: string;
170
+ /** ID of the task that was changed. */
53
171
  task_id: string;
172
+ /**
173
+ * Name of the field that was changed.
174
+ *
175
+ * @example 'status'
176
+ * @example 'priority'
177
+ * @example 'assigned_id'
178
+ */
54
179
  field: string;
180
+ /** The previous value of the field (as a string), or `undefined` if the field was newly set. */
55
181
  old_value?: string;
182
+ /** The new value of the field (as a string), or `undefined` if the field was cleared. */
56
183
  new_value?: string;
57
184
  }
185
+ /**
186
+ * Parameters for creating a new task.
187
+ */
58
188
  export interface CreateTaskParams {
189
+ /**
190
+ * The task title (required).
191
+ *
192
+ * @remarks Must be non-empty and at most 1024 characters.
193
+ */
59
194
  title: string;
195
+ /**
196
+ * Detailed description of the task.
197
+ *
198
+ * @remarks Maximum 65,536 characters.
199
+ */
60
200
  description?: string;
201
+ /** Arbitrary key-value metadata. */
61
202
  metadata?: Record<string, unknown>;
203
+ /**
204
+ * Priority level. Defaults to `'none'` if not provided.
205
+ *
206
+ * @default 'none'
207
+ */
62
208
  priority?: TaskPriority;
209
+ /** ID of the parent task for hierarchical organization. */
63
210
  parent_id?: string;
211
+ /** The task classification (required). */
64
212
  type: TaskType;
213
+ /**
214
+ * Initial status. Defaults to `'open'` if not provided.
215
+ *
216
+ * @default 'open'
217
+ */
65
218
  status?: TaskStatus;
219
+ /**
220
+ * ID of the creator.
221
+ *
222
+ * @remarks Legacy field; prefer {@link CreateTaskParams.creator | creator}.
223
+ */
66
224
  created_id: string;
225
+ /**
226
+ * ID of the assigned user.
227
+ *
228
+ * @remarks Legacy field; prefer {@link CreateTaskParams.assignee | assignee}.
229
+ */
67
230
  assigned_id?: string;
231
+ /** Reference to the user creating the task (id and name). */
68
232
  creator?: EntityRef;
233
+ /** Reference to the user being assigned the task. */
69
234
  assignee?: EntityRef;
235
+ /** Reference to the project this task belongs to. */
70
236
  project?: EntityRef;
237
+ /** Array of tag IDs to associate with the task at creation. */
71
238
  tag_ids?: string[];
72
239
  }
240
+ /**
241
+ * Parameters for partially updating an existing task.
242
+ *
243
+ * @remarks Only provided fields are modified; omitted fields remain unchanged.
244
+ */
73
245
  export interface UpdateTaskParams {
246
+ /**
247
+ * Updated task title.
248
+ *
249
+ * @remarks Must be non-empty and at most 1024 characters if provided.
250
+ */
74
251
  title?: string;
252
+ /**
253
+ * Updated description.
254
+ *
255
+ * @remarks Maximum 65,536 characters.
256
+ */
75
257
  description?: string;
258
+ /** Updated key-value metadata. */
76
259
  metadata?: Record<string, unknown>;
260
+ /** Updated priority level. */
77
261
  priority?: TaskPriority;
262
+ /** Updated parent task ID. */
78
263
  parent_id?: string;
264
+ /** Updated task classification. */
79
265
  type?: TaskType;
266
+ /** Updated lifecycle status. */
80
267
  status?: TaskStatus;
268
+ /**
269
+ * Updated assigned user ID.
270
+ *
271
+ * @remarks Legacy field; prefer {@link UpdateTaskParams.assignee | assignee}.
272
+ */
81
273
  assigned_id?: string;
274
+ /**
275
+ * ID of the user closing the task.
276
+ *
277
+ * @remarks Legacy field; prefer {@link UpdateTaskParams.closer | closer}.
278
+ */
82
279
  closed_id?: string;
280
+ /** Reference to the user being assigned the task. */
83
281
  assignee?: EntityRef;
282
+ /** Reference to the user closing the task. */
84
283
  closer?: EntityRef;
284
+ /** Reference to the project this task belongs to. */
85
285
  project?: EntityRef;
86
286
  }
287
+ /**
288
+ * Parameters for filtering and paginating the task list.
289
+ */
87
290
  export interface ListTasksParams {
291
+ /** Filter by task status. */
88
292
  status?: TaskStatus;
293
+ /** Filter by task type. */
89
294
  type?: TaskType;
295
+ /** Filter by priority level. */
90
296
  priority?: TaskPriority;
297
+ /** Filter by assigned user ID. */
91
298
  assigned_id?: string;
299
+ /** Filter by parent task ID (get subtasks). */
92
300
  parent_id?: string;
301
+ /** Filter by project ID. */
93
302
  project_id?: string;
303
+ /** Filter by tag ID. */
94
304
  tag_id?: string;
305
+ /**
306
+ * Filter for soft-deleted tasks.
307
+ *
308
+ * @default false
309
+ */
95
310
  deleted?: boolean;
311
+ /**
312
+ * Sort field. Prefix with `-` for descending order.
313
+ *
314
+ * @remarks Supported values: `'created_at'`, `'updated_at'`, `'priority'`.
315
+ * Prefix with `-` for descending (e.g., `'-created_at'`).
316
+ */
96
317
  sort?: string;
318
+ /** Sort direction: `'asc'` or `'desc'`. */
97
319
  order?: 'asc' | 'desc';
320
+ /** Maximum number of results to return. */
98
321
  limit?: number;
322
+ /** Number of results to skip for pagination. */
99
323
  offset?: number;
100
324
  }
325
+ /**
326
+ * Paginated list of tasks with total count.
327
+ */
101
328
  export interface ListTasksResult {
329
+ /** Array of tasks matching the query. */
102
330
  tasks: Task[];
331
+ /** Total number of tasks matching the filters (before pagination). */
103
332
  total: number;
333
+ /** The limit that was applied. */
104
334
  limit: number;
335
+ /** The offset that was applied. */
105
336
  offset: number;
106
337
  }
338
+ /**
339
+ * Paginated list of changelog entries for a task.
340
+ */
107
341
  export interface TaskChangelogResult {
342
+ /** Array of change records. */
108
343
  changelog: TaskChangelogEntry[];
344
+ /** Total number of changelog entries. */
109
345
  total: number;
346
+ /** Applied limit. */
110
347
  limit: number;
348
+ /** Applied offset. */
111
349
  offset: number;
112
350
  }
351
+ /**
352
+ * Paginated list of comments on a task.
353
+ */
113
354
  export interface ListCommentsResult {
355
+ /** Array of comments. */
114
356
  comments: Comment[];
357
+ /** Total number of comments. */
115
358
  total: number;
359
+ /** Applied limit. */
116
360
  limit: number;
361
+ /** Applied offset. */
117
362
  offset: number;
118
363
  }
364
+ /**
365
+ * List of all tags in the organization.
366
+ */
119
367
  export interface ListTagsResult {
368
+ /** Array of tags. */
120
369
  tags: Tag[];
121
370
  }
371
+ /**
372
+ * A file attachment on a task. Attachments are stored in S3 and accessed via presigned URLs.
373
+ */
122
374
  export interface Attachment {
375
+ /** Unique identifier for the attachment. */
123
376
  id: string;
377
+ /** ISO 8601 timestamp when the attachment was uploaded. */
124
378
  created_at: string;
379
+ /** ID of the task this attachment belongs to. */
125
380
  task_id: string;
381
+ /** ID of the user who uploaded the attachment. */
126
382
  user_id: string;
383
+ /** Reference to the uploader with display name. */
127
384
  author?: EntityRef;
385
+ /** Original filename of the uploaded file. */
128
386
  filename: string;
387
+ /**
388
+ * MIME type of the file.
389
+ *
390
+ * @example 'application/pdf'
391
+ */
129
392
  content_type?: string;
393
+ /** File size in bytes. */
130
394
  size?: number;
131
395
  }
396
+ /**
397
+ * Parameters for initiating a file upload to a task.
398
+ */
132
399
  export interface CreateAttachmentParams {
400
+ /** The filename for the attachment (required). */
133
401
  filename: string;
402
+ /** MIME type of the file. */
134
403
  content_type?: string;
404
+ /** File size in bytes. */
135
405
  size?: number;
136
406
  }
407
+ /**
408
+ * Response from initiating an attachment upload. Contains a presigned S3 URL for direct upload.
409
+ */
137
410
  export interface PresignUploadResponse {
411
+ /** The created attachment record. */
138
412
  attachment: Attachment;
413
+ /** A presigned S3 URL to upload the file content via HTTP PUT. */
139
414
  presigned_url: string;
415
+ /** Number of seconds until the presigned URL expires. */
140
416
  expiry_seconds: number;
141
417
  }
418
+ /**
419
+ * Response containing a presigned S3 URL for downloading an attachment.
420
+ */
142
421
  export interface PresignDownloadResponse {
422
+ /** A presigned S3 URL to download the file via HTTP GET. */
143
423
  presigned_url: string;
424
+ /** Number of seconds until the presigned URL expires. */
144
425
  expiry_seconds: number;
145
426
  }
427
+ /**
428
+ * List of attachments on a task.
429
+ */
146
430
  export interface ListAttachmentsResult {
431
+ /** Array of attachment records. */
147
432
  attachments: Attachment[];
433
+ /** Total number of attachments. */
148
434
  total: number;
149
435
  }
436
+ /**
437
+ * List of all users who have been referenced in tasks (as creators, assignees, or closers).
438
+ */
150
439
  export interface ListUsersResult {
440
+ /** Array of user entity references. */
151
441
  users: EntityRef[];
152
442
  }
443
+ /**
444
+ * List of all projects that have been referenced in tasks.
445
+ */
153
446
  export interface ListProjectsResult {
447
+ /** Array of project entity references. */
154
448
  projects: EntityRef[];
155
449
  }
450
+ /**
451
+ * Parameters for querying task activity time-series data.
452
+ */
156
453
  export interface TaskActivityParams {
454
+ /**
455
+ * Number of days of activity to retrieve.
456
+ *
457
+ * @remarks Minimum 7, maximum 365.
458
+ * @default 90
459
+ */
157
460
  days?: number;
158
461
  }
462
+ /**
463
+ * A single day's snapshot of task counts by status.
464
+ */
159
465
  export interface TaskActivityDataPoint {
466
+ /**
467
+ * The date in `YYYY-MM-DD` format.
468
+ *
469
+ * @example '2026-02-28'
470
+ */
160
471
  date: string;
472
+ /** Number of tasks in `'open'` status on this date. */
161
473
  open: number;
474
+ /** Number of tasks in `'in_progress'` status on this date. */
162
475
  inProgress: number;
476
+ /** Number of tasks in `'done'` status on this date. */
163
477
  done: number;
478
+ /** Number of tasks in `'closed'` status on this date. */
164
479
  closed: number;
480
+ /** Number of tasks in `'cancelled'` status on this date. */
165
481
  cancelled: number;
166
482
  }
483
+ /**
484
+ * Task activity time-series data.
485
+ */
167
486
  export interface TaskActivityResult {
487
+ /** Array of daily activity snapshots, ordered chronologically. */
168
488
  activity: TaskActivityDataPoint[];
489
+ /** The number of days of data returned. */
169
490
  days: number;
170
491
  }
492
+ /**
493
+ * Interface defining the contract for task storage operations.
494
+ *
495
+ * Implemented by {@link TaskStorageService}.
496
+ */
171
497
  export interface TaskStorage {
498
+ /**
499
+ * Create a new task.
500
+ *
501
+ * @param params - The task creation parameters
502
+ * @returns The newly created task
503
+ */
172
504
  create(params: CreateTaskParams): Promise<Task>;
505
+ /**
506
+ * Get a task by its ID.
507
+ *
508
+ * @param id - The unique task identifier
509
+ * @returns The task if found, or `null` if not found
510
+ */
173
511
  get(id: string): Promise<Task | null>;
512
+ /**
513
+ * List tasks with optional filtering and pagination.
514
+ *
515
+ * @param params - Optional filter and pagination parameters
516
+ * @returns Paginated list of matching tasks
517
+ */
174
518
  list(params?: ListTasksParams): Promise<ListTasksResult>;
519
+ /**
520
+ * Partially update an existing task.
521
+ *
522
+ * @param id - The unique task identifier
523
+ * @param params - Fields to update (only provided fields are changed)
524
+ * @returns The updated task
525
+ */
175
526
  update(id: string, params: UpdateTaskParams): Promise<Task>;
527
+ /**
528
+ * Close a task by setting its status to closed.
529
+ *
530
+ * @param id - The unique task identifier
531
+ * @returns The closed task
532
+ */
176
533
  close(id: string): Promise<Task>;
534
+ /**
535
+ * Soft-delete a task, marking it as deleted without permanent removal.
536
+ *
537
+ * @param id - The unique task identifier
538
+ * @returns The soft-deleted task
539
+ */
177
540
  softDelete(id: string): Promise<Task>;
541
+ /**
542
+ * Get the changelog (audit trail) for a task.
543
+ *
544
+ * @param id - The unique task identifier
545
+ * @param params - Optional pagination parameters
546
+ * @returns Paginated list of changelog entries
547
+ */
178
548
  changelog(id: string, params?: {
179
549
  limit?: number;
180
550
  offset?: number;
181
551
  }): Promise<TaskChangelogResult>;
552
+ /**
553
+ * Create a comment on a task.
554
+ *
555
+ * @param taskId - The ID of the task to comment on
556
+ * @param body - The comment text content
557
+ * @param userId - The ID of the user authoring the comment
558
+ * @param author - Optional entity reference with display name
559
+ * @returns The newly created comment
560
+ */
182
561
  createComment(taskId: string, body: string, userId: string, author?: EntityRef): Promise<Comment>;
562
+ /**
563
+ * Get a comment by its ID.
564
+ *
565
+ * @param commentId - The unique comment identifier
566
+ * @returns The comment
567
+ */
183
568
  getComment(commentId: string): Promise<Comment>;
569
+ /**
570
+ * Update a comment's body text.
571
+ *
572
+ * @param commentId - The unique comment identifier
573
+ * @param body - The new comment text
574
+ * @returns The updated comment
575
+ */
184
576
  updateComment(commentId: string, body: string): Promise<Comment>;
577
+ /**
578
+ * Delete a comment.
579
+ *
580
+ * @param commentId - The unique comment identifier
581
+ */
185
582
  deleteComment(commentId: string): Promise<void>;
583
+ /**
584
+ * List comments on a task with optional pagination.
585
+ *
586
+ * @param taskId - The ID of the task
587
+ * @param params - Optional pagination parameters
588
+ * @returns Paginated list of comments
589
+ */
186
590
  listComments(taskId: string, params?: {
187
591
  limit?: number;
188
592
  offset?: number;
189
593
  }): Promise<ListCommentsResult>;
594
+ /**
595
+ * Create a new tag.
596
+ *
597
+ * @param name - The tag display name
598
+ * @param color - Optional hex color code (e.g., `'#ff0000'`)
599
+ * @returns The newly created tag
600
+ */
190
601
  createTag(name: string, color?: string): Promise<Tag>;
602
+ /**
603
+ * Get a tag by its ID.
604
+ *
605
+ * @param tagId - The unique tag identifier
606
+ * @returns The tag
607
+ */
191
608
  getTag(tagId: string): Promise<Tag>;
609
+ /**
610
+ * Update a tag's name and optionally its color.
611
+ *
612
+ * @param tagId - The unique tag identifier
613
+ * @param name - The new tag name
614
+ * @param color - Optional new hex color code
615
+ * @returns The updated tag
616
+ */
192
617
  updateTag(tagId: string, name: string, color?: string): Promise<Tag>;
618
+ /**
619
+ * Delete a tag.
620
+ *
621
+ * @param tagId - The unique tag identifier
622
+ */
193
623
  deleteTag(tagId: string): Promise<void>;
624
+ /**
625
+ * List all tags in the organization.
626
+ *
627
+ * @returns List of all tags
628
+ */
194
629
  listTags(): Promise<ListTagsResult>;
630
+ /**
631
+ * Associate a tag with a task.
632
+ *
633
+ * @param taskId - The ID of the task
634
+ * @param tagId - The ID of the tag to add
635
+ */
195
636
  addTagToTask(taskId: string, tagId: string): Promise<void>;
637
+ /**
638
+ * Remove a tag association from a task.
639
+ *
640
+ * @param taskId - The ID of the task
641
+ * @param tagId - The ID of the tag to remove
642
+ */
196
643
  removeTagFromTask(taskId: string, tagId: string): Promise<void>;
644
+ /**
645
+ * List all tags associated with a specific task.
646
+ *
647
+ * @param taskId - The ID of the task
648
+ * @returns Array of tags on the task
649
+ */
197
650
  listTagsForTask(taskId: string): Promise<Tag[]>;
651
+ /**
652
+ * Initiate a file upload to a task. Returns a presigned S3 URL for direct upload.
653
+ *
654
+ * @param taskId - The ID of the task to attach the file to
655
+ * @param params - Attachment metadata (filename, content type, size)
656
+ * @returns The attachment record and a presigned upload URL
657
+ */
198
658
  uploadAttachment(taskId: string, params: CreateAttachmentParams): Promise<PresignUploadResponse>;
659
+ /**
660
+ * Confirm that a file upload has completed successfully.
661
+ *
662
+ * @param attachmentId - The unique attachment identifier
663
+ * @returns The confirmed attachment record
664
+ */
199
665
  confirmAttachment(attachmentId: string): Promise<Attachment>;
666
+ /**
667
+ * Get a presigned S3 URL for downloading an attachment.
668
+ *
669
+ * @param attachmentId - The unique attachment identifier
670
+ * @returns A presigned download URL
671
+ */
200
672
  downloadAttachment(attachmentId: string): Promise<PresignDownloadResponse>;
673
+ /**
674
+ * List all attachments on a task.
675
+ *
676
+ * @param taskId - The ID of the task
677
+ * @returns List of attachments with total count
678
+ */
201
679
  listAttachments(taskId: string): Promise<ListAttachmentsResult>;
680
+ /**
681
+ * Delete an attachment.
682
+ *
683
+ * @param attachmentId - The unique attachment identifier
684
+ */
202
685
  deleteAttachment(attachmentId: string): Promise<void>;
686
+ /**
687
+ * List all users who have been referenced in tasks.
688
+ *
689
+ * @returns List of user entity references
690
+ */
203
691
  listUsers(): Promise<ListUsersResult>;
692
+ /**
693
+ * List all projects that have been referenced in tasks.
694
+ *
695
+ * @returns List of project entity references
696
+ */
204
697
  listProjects(): Promise<ListProjectsResult>;
698
+ /**
699
+ * Get task activity time-series data showing daily status counts.
700
+ *
701
+ * @param params - Optional parameters controlling the number of days to retrieve
702
+ * @returns Time-series activity data
703
+ */
205
704
  getActivity(params?: TaskActivityParams): Promise<TaskActivityResult>;
206
705
  }
706
+ /**
707
+ * Client for the Agentuity Task management service.
708
+ *
709
+ * Provides a full-featured project management API including task CRUD, hierarchical
710
+ * organization (epics → features → tasks), comments, tags, file attachments via
711
+ * presigned S3 URLs, changelog tracking, and activity analytics.
712
+ *
713
+ * Tasks support lifecycle management through status transitions (`open` → `in_progress`
714
+ * → `done`/`closed`/`cancelled`) with automatic date tracking for each transition.
715
+ *
716
+ * All methods validate inputs client-side and throw structured errors for invalid
717
+ * parameters. API errors throw {@link ServiceException}.
718
+ *
719
+ * @example
720
+ * ```typescript
721
+ * const tasks = new TaskStorageService(baseUrl, adapter);
722
+ *
723
+ * // Create a task
724
+ * const task = await tasks.create({
725
+ * title: 'Implement login flow',
726
+ * type: 'feature',
727
+ * created_id: 'user_123',
728
+ * creator: { id: 'user_123', name: 'Alice' },
729
+ * priority: 'high',
730
+ * });
731
+ *
732
+ * // Add a comment
733
+ * await tasks.createComment(task.id, 'Started working on this', 'user_123');
734
+ *
735
+ * // List open tasks
736
+ * const { tasks: openTasks } = await tasks.list({ status: 'open' });
737
+ * ```
738
+ */
207
739
  export declare class TaskStorageService implements TaskStorage {
208
740
  #private;
741
+ /**
742
+ * Creates a new TaskStorageService instance.
743
+ *
744
+ * @param baseUrl - The base URL of the task management API
745
+ * @param adapter - The HTTP fetch adapter used for making API requests
746
+ */
209
747
  constructor(baseUrl: string, adapter: FetchAdapter);
748
+ /**
749
+ * Create a new task.
750
+ *
751
+ * @param params - The task creation parameters including title, type, and optional fields
752
+ * @returns The newly created task
753
+ * @throws {@link TaskTitleRequiredError} if the title is empty or not a string
754
+ * @throws {@link ServiceException} if the API request fails
755
+ *
756
+ * @example
757
+ * ```typescript
758
+ * const task = await tasks.create({
759
+ * title: 'Fix login bug',
760
+ * type: 'bug',
761
+ * created_id: 'user_123',
762
+ * priority: 'high',
763
+ * creator: { id: 'user_123', name: 'Alice' },
764
+ * project: { id: 'proj_456', name: 'Auth Service' },
765
+ * });
766
+ * console.log('Created:', task.id);
767
+ * ```
768
+ */
210
769
  create(params: CreateTaskParams): Promise<Task>;
770
+ /**
771
+ * Get a task by its ID.
772
+ *
773
+ * @param id - The unique task identifier
774
+ * @returns The task if found, or `null` if the task does not exist
775
+ * @throws {@link TaskIdRequiredError} if the ID is empty or not a string
776
+ * @throws {@link ServiceException} if the API request fails
777
+ *
778
+ * @example
779
+ * ```typescript
780
+ * const task = await tasks.get('task_abc123');
781
+ * if (task) {
782
+ * console.log(task.title, task.status);
783
+ * } else {
784
+ * console.log('Task not found');
785
+ * }
786
+ * ```
787
+ */
211
788
  get(id: string): Promise<Task | null>;
789
+ /**
790
+ * List tasks with optional filtering and pagination.
791
+ *
792
+ * @param params - Optional filter and pagination parameters
793
+ * @returns Paginated list of tasks matching the filters
794
+ * @throws {@link ServiceException} if the API request fails
795
+ *
796
+ * @example
797
+ * ```typescript
798
+ * // List all open high-priority bugs
799
+ * const result = await tasks.list({
800
+ * status: 'open',
801
+ * type: 'bug',
802
+ * priority: 'high',
803
+ * sort: '-created_at',
804
+ * limit: 20,
805
+ * });
806
+ * console.log(`Found ${result.total} bugs, showing ${result.tasks.length}`);
807
+ * ```
808
+ */
212
809
  list(params?: ListTasksParams): Promise<ListTasksResult>;
810
+ /**
811
+ * Partially update an existing task.
812
+ *
813
+ * @param id - The unique task identifier
814
+ * @param params - Fields to update; only provided fields are changed
815
+ * @returns The updated task
816
+ * @throws {@link TaskIdRequiredError} if the ID is empty or not a string
817
+ * @throws {@link TaskTitleRequiredError} if a title is provided but is empty
818
+ * @throws {@link ServiceException} if the API request fails
819
+ *
820
+ * @example
821
+ * ```typescript
822
+ * const updated = await tasks.update('task_abc123', {
823
+ * status: 'in_progress',
824
+ * priority: 'high',
825
+ * assignee: { id: 'user_456', name: 'Bob' },
826
+ * });
827
+ * console.log('Updated status:', updated.status);
828
+ * ```
829
+ */
213
830
  update(id: string, params: UpdateTaskParams): Promise<Task>;
831
+ /**
832
+ * Close a task by setting its status to closed.
833
+ *
834
+ * @param id - The unique task identifier
835
+ * @returns The closed task with updated `closed_date`
836
+ * @throws {@link TaskIdRequiredError} if the ID is empty or not a string
837
+ * @throws {@link ServiceException} if the API request fails
838
+ *
839
+ * @example
840
+ * ```typescript
841
+ * const closed = await tasks.close('task_abc123');
842
+ * console.log('Closed at:', closed.closed_date);
843
+ * ```
844
+ */
214
845
  close(id: string): Promise<Task>;
846
+ /**
847
+ * Get the changelog (audit trail) for a task, showing all field changes over time.
848
+ *
849
+ * @param id - The unique task identifier
850
+ * @param params - Optional pagination parameters
851
+ * @returns Paginated list of changelog entries ordered by most recent first
852
+ * @throws {@link TaskIdRequiredError} if the ID is empty or not a string
853
+ * @throws {@link ServiceException} if the API request fails
854
+ *
855
+ * @example
856
+ * ```typescript
857
+ * const { changelog, total } = await tasks.changelog('task_abc123', {
858
+ * limit: 10,
859
+ * offset: 0,
860
+ * });
861
+ * for (const entry of changelog) {
862
+ * console.log(`${entry.field}: ${entry.old_value} → ${entry.new_value}`);
863
+ * }
864
+ * ```
865
+ */
215
866
  changelog(id: string, params?: {
216
867
  limit?: number;
217
868
  offset?: number;
218
869
  }): Promise<TaskChangelogResult>;
870
+ /**
871
+ * Soft-delete a task, marking it as deleted without permanent removal.
872
+ *
873
+ * @param id - The unique task identifier
874
+ * @returns The soft-deleted task
875
+ * @throws {@link TaskIdRequiredError} if the ID is empty or not a string
876
+ * @throws {@link ServiceException} if the API request fails
877
+ *
878
+ * @example
879
+ * ```typescript
880
+ * const deleted = await tasks.softDelete('task_abc123');
881
+ * console.log('Soft-deleted task:', deleted.id);
882
+ * ```
883
+ */
219
884
  softDelete(id: string): Promise<Task>;
885
+ /**
886
+ * Create a comment on a task.
887
+ *
888
+ * @param taskId - The ID of the task to comment on
889
+ * @param body - The comment text content (must be non-empty)
890
+ * @param userId - The ID of the user authoring the comment
891
+ * @param author - Optional entity reference with the author's display name
892
+ * @returns The newly created comment
893
+ * @throws {@link TaskIdRequiredError} if the task ID is empty or not a string
894
+ * @throws {@link CommentBodyRequiredError} if the body is empty or not a string
895
+ * @throws {@link UserIdRequiredError} if the user ID is empty or not a string
896
+ * @throws {@link ServiceException} if the API request fails
897
+ *
898
+ * @example
899
+ * ```typescript
900
+ * const comment = await tasks.createComment(
901
+ * 'task_abc123',
902
+ * 'This is ready for review.',
903
+ * 'user_456',
904
+ * { id: 'user_456', name: 'Bob' },
905
+ * );
906
+ * console.log('Comment created:', comment.id);
907
+ * ```
908
+ */
220
909
  createComment(taskId: string, body: string, userId: string, author?: EntityRef): Promise<Comment>;
910
+ /**
911
+ * Get a comment by its ID.
912
+ *
913
+ * @param commentId - The unique comment identifier
914
+ * @returns The comment
915
+ * @throws {@link CommentIdRequiredError} if the comment ID is empty or not a string
916
+ * @throws {@link ServiceException} if the API request fails
917
+ *
918
+ * @example
919
+ * ```typescript
920
+ * const comment = await tasks.getComment('comment_xyz789');
921
+ * console.log(`${comment.author?.name}: ${comment.body}`);
922
+ * ```
923
+ */
221
924
  getComment(commentId: string): Promise<Comment>;
925
+ /**
926
+ * Update a comment's body text.
927
+ *
928
+ * @param commentId - The unique comment identifier
929
+ * @param body - The new comment text (must be non-empty)
930
+ * @returns The updated comment
931
+ * @throws {@link CommentIdRequiredError} if the comment ID is empty or not a string
932
+ * @throws {@link CommentBodyRequiredError} if the body is empty or not a string
933
+ * @throws {@link ServiceException} if the API request fails
934
+ *
935
+ * @example
936
+ * ```typescript
937
+ * const updated = await tasks.updateComment(
938
+ * 'comment_xyz789',
939
+ * 'Updated: This is now ready for final review.',
940
+ * );
941
+ * console.log('Updated at:', updated.updated_at);
942
+ * ```
943
+ */
222
944
  updateComment(commentId: string, body: string): Promise<Comment>;
945
+ /**
946
+ * Delete a comment permanently.
947
+ *
948
+ * @param commentId - The unique comment identifier
949
+ * @throws {@link CommentIdRequiredError} if the comment ID is empty or not a string
950
+ * @throws {@link ServiceException} if the API request fails
951
+ *
952
+ * @example
953
+ * ```typescript
954
+ * await tasks.deleteComment('comment_xyz789');
955
+ * console.log('Comment deleted');
956
+ * ```
957
+ */
223
958
  deleteComment(commentId: string): Promise<void>;
959
+ /**
960
+ * List comments on a task with optional pagination.
961
+ *
962
+ * @param taskId - The ID of the task whose comments to list
963
+ * @param params - Optional pagination parameters
964
+ * @returns Paginated list of comments
965
+ * @throws {@link TaskIdRequiredError} if the task ID is empty or not a string
966
+ * @throws {@link ServiceException} if the API request fails
967
+ *
968
+ * @example
969
+ * ```typescript
970
+ * const { comments, total } = await tasks.listComments('task_abc123', {
971
+ * limit: 25,
972
+ * offset: 0,
973
+ * });
974
+ * for (const c of comments) {
975
+ * console.log(`${c.author?.name}: ${c.body}`);
976
+ * }
977
+ * ```
978
+ */
224
979
  listComments(taskId: string, params?: {
225
980
  limit?: number;
226
981
  offset?: number;
227
982
  }): Promise<ListCommentsResult>;
983
+ /**
984
+ * Create a new tag for categorizing tasks.
985
+ *
986
+ * @param name - The tag display name (must be non-empty)
987
+ * @param color - Optional hex color code (e.g., `'#ff0000'`)
988
+ * @returns The newly created tag
989
+ * @throws {@link TagNameRequiredError} if the name is empty or not a string
990
+ * @throws {@link ServiceException} if the API request fails
991
+ *
992
+ * @example
993
+ * ```typescript
994
+ * const tag = await tasks.createTag('urgent', '#ff0000');
995
+ * console.log('Created tag:', tag.id, tag.name);
996
+ * ```
997
+ */
228
998
  createTag(name: string, color?: string): Promise<Tag>;
999
+ /**
1000
+ * Get a tag by its ID.
1001
+ *
1002
+ * @param tagId - The unique tag identifier
1003
+ * @returns The tag
1004
+ * @throws {@link TagIdRequiredError} if the tag ID is empty or not a string
1005
+ * @throws {@link ServiceException} if the API request fails
1006
+ *
1007
+ * @example
1008
+ * ```typescript
1009
+ * const tag = await tasks.getTag('tag_def456');
1010
+ * console.log(`${tag.name} (${tag.color})`);
1011
+ * ```
1012
+ */
229
1013
  getTag(tagId: string): Promise<Tag>;
1014
+ /**
1015
+ * Update a tag's name and optionally its color.
1016
+ *
1017
+ * @param tagId - The unique tag identifier
1018
+ * @param name - The new tag name (must be non-empty)
1019
+ * @param color - Optional new hex color code
1020
+ * @returns The updated tag
1021
+ * @throws {@link TagIdRequiredError} if the tag ID is empty or not a string
1022
+ * @throws {@link TagNameRequiredError} if the name is empty or not a string
1023
+ * @throws {@link ServiceException} if the API request fails
1024
+ *
1025
+ * @example
1026
+ * ```typescript
1027
+ * const updated = await tasks.updateTag('tag_def456', 'critical', '#cc0000');
1028
+ * console.log('Updated:', updated.name);
1029
+ * ```
1030
+ */
230
1031
  updateTag(tagId: string, name: string, color?: string): Promise<Tag>;
1032
+ /**
1033
+ * Delete a tag permanently.
1034
+ *
1035
+ * @param tagId - The unique tag identifier
1036
+ * @throws {@link TagIdRequiredError} if the tag ID is empty or not a string
1037
+ * @throws {@link ServiceException} if the API request fails
1038
+ *
1039
+ * @example
1040
+ * ```typescript
1041
+ * await tasks.deleteTag('tag_def456');
1042
+ * console.log('Tag deleted');
1043
+ * ```
1044
+ */
231
1045
  deleteTag(tagId: string): Promise<void>;
1046
+ /**
1047
+ * List all tags in the organization.
1048
+ *
1049
+ * @returns List of all tags
1050
+ * @throws {@link ServiceException} if the API request fails
1051
+ *
1052
+ * @example
1053
+ * ```typescript
1054
+ * const { tags } = await tasks.listTags();
1055
+ * for (const tag of tags) {
1056
+ * console.log(`${tag.name} (${tag.color ?? 'no color'})`);
1057
+ * }
1058
+ * ```
1059
+ */
232
1060
  listTags(): Promise<ListTagsResult>;
1061
+ /**
1062
+ * Associate a tag with a task.
1063
+ *
1064
+ * @param taskId - The ID of the task
1065
+ * @param tagId - The ID of the tag to add
1066
+ * @throws {@link TaskIdRequiredError} if the task ID is empty or not a string
1067
+ * @throws {@link TagIdRequiredError} if the tag ID is empty or not a string
1068
+ * @throws {@link ServiceException} if the API request fails
1069
+ *
1070
+ * @example
1071
+ * ```typescript
1072
+ * await tasks.addTagToTask('task_abc123', 'tag_def456');
1073
+ * console.log('Tag added to task');
1074
+ * ```
1075
+ */
233
1076
  addTagToTask(taskId: string, tagId: string): Promise<void>;
1077
+ /**
1078
+ * Remove a tag association from a task.
1079
+ *
1080
+ * @param taskId - The ID of the task
1081
+ * @param tagId - The ID of the tag to remove
1082
+ * @throws {@link TaskIdRequiredError} if the task ID is empty or not a string
1083
+ * @throws {@link TagIdRequiredError} if the tag ID is empty or not a string
1084
+ * @throws {@link ServiceException} if the API request fails
1085
+ *
1086
+ * @example
1087
+ * ```typescript
1088
+ * await tasks.removeTagFromTask('task_abc123', 'tag_def456');
1089
+ * console.log('Tag removed from task');
1090
+ * ```
1091
+ */
234
1092
  removeTagFromTask(taskId: string, tagId: string): Promise<void>;
1093
+ /**
1094
+ * List all tags associated with a specific task.
1095
+ *
1096
+ * @param taskId - The ID of the task
1097
+ * @returns Array of tags on the task
1098
+ * @throws {@link TaskIdRequiredError} if the task ID is empty or not a string
1099
+ * @throws {@link ServiceException} if the API request fails
1100
+ *
1101
+ * @example
1102
+ * ```typescript
1103
+ * const tags = await tasks.listTagsForTask('task_abc123');
1104
+ * console.log('Tags:', tags.map((t) => t.name).join(', '));
1105
+ * ```
1106
+ */
235
1107
  listTagsForTask(taskId: string): Promise<Tag[]>;
1108
+ /**
1109
+ * Initiate a file upload to a task. Returns a presigned S3 URL for direct upload.
1110
+ *
1111
+ * @remarks
1112
+ * After receiving the presigned URL, upload the file content via HTTP PUT to that URL.
1113
+ * Then call {@link TaskStorageService.confirmAttachment | confirmAttachment} to finalize.
1114
+ *
1115
+ * @param taskId - The ID of the task to attach the file to
1116
+ * @param params - Attachment metadata including filename, content type, and size
1117
+ * @returns The created attachment record and a presigned upload URL
1118
+ * @throws {@link TaskIdRequiredError} if the task ID is empty or not a string
1119
+ * @throws {@link ServiceException} if the API request fails
1120
+ *
1121
+ * @example
1122
+ * ```typescript
1123
+ * const { attachment, presigned_url } = await tasks.uploadAttachment(
1124
+ * 'task_abc123',
1125
+ * { filename: 'report.pdf', content_type: 'application/pdf', size: 102400 },
1126
+ * );
1127
+ *
1128
+ * // Upload the file to S3
1129
+ * await fetch(presigned_url, { method: 'PUT', body: fileContent });
1130
+ *
1131
+ * // Confirm the upload
1132
+ * await tasks.confirmAttachment(attachment.id);
1133
+ * ```
1134
+ */
236
1135
  uploadAttachment(taskId: string, params: CreateAttachmentParams): Promise<PresignUploadResponse>;
1136
+ /**
1137
+ * Confirm that a file upload has completed successfully.
1138
+ *
1139
+ * @remarks
1140
+ * Call this after successfully uploading the file to the presigned URL
1141
+ * returned by {@link TaskStorageService.uploadAttachment | uploadAttachment}.
1142
+ *
1143
+ * @param attachmentId - The unique attachment identifier
1144
+ * @returns The confirmed attachment record
1145
+ * @throws {@link AttachmentIdRequiredError} if the attachment ID is empty or not a string
1146
+ * @throws {@link ServiceException} if the API request fails
1147
+ *
1148
+ * @example
1149
+ * ```typescript
1150
+ * const confirmed = await tasks.confirmAttachment('att_ghi789');
1151
+ * console.log('Confirmed:', confirmed.filename);
1152
+ * ```
1153
+ */
237
1154
  confirmAttachment(attachmentId: string): Promise<Attachment>;
1155
+ /**
1156
+ * Get a presigned S3 URL for downloading an attachment.
1157
+ *
1158
+ * @param attachmentId - The unique attachment identifier
1159
+ * @returns A presigned download URL with expiry information
1160
+ * @throws {@link AttachmentIdRequiredError} if the attachment ID is empty or not a string
1161
+ * @throws {@link ServiceException} if the API request fails
1162
+ *
1163
+ * @example
1164
+ * ```typescript
1165
+ * const { presigned_url, expiry_seconds } = await tasks.downloadAttachment('att_ghi789');
1166
+ * console.log(`Download URL (expires in ${expiry_seconds}s):`, presigned_url);
1167
+ * ```
1168
+ */
238
1169
  downloadAttachment(attachmentId: string): Promise<PresignDownloadResponse>;
1170
+ /**
1171
+ * List all attachments on a task.
1172
+ *
1173
+ * @param taskId - The ID of the task
1174
+ * @returns List of attachments with total count
1175
+ * @throws {@link TaskIdRequiredError} if the task ID is empty or not a string
1176
+ * @throws {@link ServiceException} if the API request fails
1177
+ *
1178
+ * @example
1179
+ * ```typescript
1180
+ * const { attachments, total } = await tasks.listAttachments('task_abc123');
1181
+ * for (const att of attachments) {
1182
+ * console.log(`${att.filename} (${att.content_type}, ${att.size} bytes)`);
1183
+ * }
1184
+ * ```
1185
+ */
239
1186
  listAttachments(taskId: string): Promise<ListAttachmentsResult>;
1187
+ /**
1188
+ * Delete an attachment permanently.
1189
+ *
1190
+ * @param attachmentId - The unique attachment identifier
1191
+ * @throws {@link AttachmentIdRequiredError} if the attachment ID is empty or not a string
1192
+ * @throws {@link ServiceException} if the API request fails
1193
+ *
1194
+ * @example
1195
+ * ```typescript
1196
+ * await tasks.deleteAttachment('att_ghi789');
1197
+ * console.log('Attachment deleted');
1198
+ * ```
1199
+ */
240
1200
  deleteAttachment(attachmentId: string): Promise<void>;
1201
+ /**
1202
+ * List all users who have been referenced in tasks (as creators, assignees, or closers).
1203
+ *
1204
+ * @returns List of user entity references
1205
+ * @throws {@link ServiceException} if the API request fails
1206
+ *
1207
+ * @example
1208
+ * ```typescript
1209
+ * const { users } = await tasks.listUsers();
1210
+ * for (const user of users) {
1211
+ * console.log(`${user.name} (${user.id})`);
1212
+ * }
1213
+ * ```
1214
+ */
241
1215
  listUsers(): Promise<ListUsersResult>;
1216
+ /**
1217
+ * List all projects that have been referenced in tasks.
1218
+ *
1219
+ * @returns List of project entity references
1220
+ * @throws {@link ServiceException} if the API request fails
1221
+ *
1222
+ * @example
1223
+ * ```typescript
1224
+ * const { projects } = await tasks.listProjects();
1225
+ * for (const project of projects) {
1226
+ * console.log(`${project.name} (${project.id})`);
1227
+ * }
1228
+ * ```
1229
+ */
242
1230
  listProjects(): Promise<ListProjectsResult>;
1231
+ /**
1232
+ * Get task activity time-series data showing daily task counts by status.
1233
+ *
1234
+ * @param params - Optional parameters controlling the number of days to retrieve
1235
+ * @returns Time-series activity data with daily snapshots
1236
+ * @throws {@link ServiceException} if the API request fails
1237
+ *
1238
+ * @example
1239
+ * ```typescript
1240
+ * const { activity, days } = await tasks.getActivity({ days: 30 });
1241
+ * console.log(`Activity over ${days} days:`);
1242
+ * for (const point of activity) {
1243
+ * console.log(`${point.date}: ${point.open} open, ${point.inProgress} in progress`);
1244
+ * }
1245
+ * ```
1246
+ */
243
1247
  getActivity(params?: TaskActivityParams): Promise<TaskActivityResult>;
244
1248
  }
245
1249
  //# sourceMappingURL=task.d.ts.map