agent-tasks 1.5.0 → 1.6.1

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 (91) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +149 -42
  3. package/package.json +7 -1
  4. package/dist/context.d.ts +0 -17
  5. package/dist/context.d.ts.map +0 -1
  6. package/dist/context.js +0 -37
  7. package/dist/context.js.map +0 -1
  8. package/dist/db.d.ts +0 -10
  9. package/dist/db.d.ts.map +0 -1
  10. package/dist/db.js +0 -112
  11. package/dist/db.js.map +0 -1
  12. package/dist/domain/agent-bridge.d.ts +0 -13
  13. package/dist/domain/agent-bridge.d.ts.map +0 -1
  14. package/dist/domain/agent-bridge.js +0 -99
  15. package/dist/domain/agent-bridge.js.map +0 -1
  16. package/dist/domain/approvals.d.ts +0 -18
  17. package/dist/domain/approvals.d.ts.map +0 -1
  18. package/dist/domain/approvals.js +0 -89
  19. package/dist/domain/approvals.js.map +0 -1
  20. package/dist/domain/cleanup.d.ts +0 -28
  21. package/dist/domain/cleanup.d.ts.map +0 -1
  22. package/dist/domain/cleanup.js +0 -68
  23. package/dist/domain/cleanup.js.map +0 -1
  24. package/dist/domain/collaborators.d.ts +0 -14
  25. package/dist/domain/collaborators.d.ts.map +0 -1
  26. package/dist/domain/collaborators.js +0 -59
  27. package/dist/domain/collaborators.js.map +0 -1
  28. package/dist/domain/comments.d.ts +0 -14
  29. package/dist/domain/comments.d.ts.map +0 -1
  30. package/dist/domain/comments.js +0 -63
  31. package/dist/domain/comments.js.map +0 -1
  32. package/dist/domain/events.d.ts +0 -9
  33. package/dist/domain/events.d.ts.map +0 -1
  34. package/dist/domain/events.js +0 -52
  35. package/dist/domain/events.js.map +0 -1
  36. package/dist/domain/rules.d.ts +0 -2
  37. package/dist/domain/rules.d.ts.map +0 -1
  38. package/dist/domain/rules.js +0 -67
  39. package/dist/domain/rules.js.map +0 -1
  40. package/dist/domain/tasks.d.ts +0 -60
  41. package/dist/domain/tasks.d.ts.map +0 -1
  42. package/dist/domain/tasks.js +0 -616
  43. package/dist/domain/tasks.js.map +0 -1
  44. package/dist/domain/validate.d.ts +0 -14
  45. package/dist/domain/validate.d.ts.map +0 -1
  46. package/dist/domain/validate.js +0 -29
  47. package/dist/domain/validate.js.map +0 -1
  48. package/dist/event-bus.d.ts +0 -10
  49. package/dist/event-bus.d.ts.map +0 -1
  50. package/dist/event-bus.js +0 -38
  51. package/dist/event-bus.js.map +0 -1
  52. package/dist/index.d.ts +0 -3
  53. package/dist/index.d.ts.map +0 -1
  54. package/dist/index.js +0 -121
  55. package/dist/index.js.map +0 -1
  56. package/dist/server.d.ts +0 -10
  57. package/dist/server.d.ts.map +0 -1
  58. package/dist/server.js +0 -95
  59. package/dist/server.js.map +0 -1
  60. package/dist/session.d.ts +0 -7
  61. package/dist/session.d.ts.map +0 -1
  62. package/dist/session.js +0 -11
  63. package/dist/session.js.map +0 -1
  64. package/dist/storage/database.d.ts +0 -15
  65. package/dist/storage/database.d.ts.map +0 -1
  66. package/dist/storage/database.js +0 -215
  67. package/dist/storage/database.js.map +0 -1
  68. package/dist/tasks.d.ts +0 -32
  69. package/dist/tasks.d.ts.map +0 -1
  70. package/dist/tasks.js +0 -410
  71. package/dist/tasks.js.map +0 -1
  72. package/dist/transport/mcp.d.ts +0 -6
  73. package/dist/transport/mcp.d.ts.map +0 -1
  74. package/dist/transport/mcp.js +0 -573
  75. package/dist/transport/mcp.js.map +0 -1
  76. package/dist/transport/rest.d.ts +0 -4
  77. package/dist/transport/rest.d.ts.map +0 -1
  78. package/dist/transport/rest.js +0 -382
  79. package/dist/transport/rest.js.map +0 -1
  80. package/dist/transport/ws.d.ts +0 -10
  81. package/dist/transport/ws.d.ts.map +0 -1
  82. package/dist/transport/ws.js +0 -177
  83. package/dist/transport/ws.js.map +0 -1
  84. package/dist/types.d.ts +0 -146
  85. package/dist/types.d.ts.map +0 -1
  86. package/dist/types.js +0 -35
  87. package/dist/types.js.map +0 -1
  88. package/dist/ui/app.js +0 -648
  89. package/dist/ui/index.html +0 -82
  90. package/dist/ui/morphdom.min.js +0 -1
  91. package/dist/ui/styles.css +0 -805
@@ -1,89 +0,0 @@
1
- // =============================================================================
2
- // agent-tasks — Approval domain service
3
- //
4
- // Stage-gated approvals for pipeline advancement.
5
- // =============================================================================
6
- import { NotFoundError, ConflictError, ValidationError } from '../types.js';
7
- import { rejectNullBytes } from './validate.js';
8
- export class ApprovalService {
9
- db;
10
- events;
11
- constructor(db, events) {
12
- this.db = db;
13
- this.events = events;
14
- }
15
- request(taskId, stage, reviewer) {
16
- const task = this.db.queryOne('SELECT id, project FROM tasks WHERE id = ?', [taskId]);
17
- if (!task)
18
- throw new NotFoundError('Task', taskId);
19
- const existing = this.db.queryOne(`SELECT * FROM task_approvals WHERE task_id = ? AND stage = ? AND status = 'pending'`, [taskId, stage]);
20
- if (existing)
21
- throw new ConflictError(`Pending approval already exists for task ${taskId} at stage ${stage}.`);
22
- const result = this.db.run(`INSERT INTO task_approvals (task_id, stage, reviewer) VALUES (?, ?, ?)`, [taskId, stage, reviewer ?? null]);
23
- const approval = this.db.queryOne('SELECT * FROM task_approvals WHERE id = ?', [
24
- Number(result.lastInsertRowid),
25
- ]);
26
- this.events.emit('approval:requested', { approval });
27
- return approval;
28
- }
29
- approve(approvalId, reviewer, comment) {
30
- rejectNullBytes(reviewer, 'reviewer');
31
- return this.resolve(approvalId, 'approved', reviewer, comment);
32
- }
33
- reject(approvalId, reviewer, comment) {
34
- rejectNullBytes(reviewer, 'reviewer');
35
- if (!comment?.trim())
36
- throw new ValidationError('Rejection requires a comment.');
37
- return this.resolve(approvalId, 'rejected', reviewer, comment);
38
- }
39
- getPending(reviewer) {
40
- if (reviewer) {
41
- return this.db.queryAll(`SELECT * FROM task_approvals WHERE status = 'pending' AND (reviewer = ? OR reviewer IS NULL) ORDER BY requested_at ASC`, [reviewer]);
42
- }
43
- return this.db.queryAll(`SELECT * FROM task_approvals WHERE status = 'pending' ORDER BY requested_at ASC`);
44
- }
45
- getForTask(taskId) {
46
- return this.db.queryAll('SELECT * FROM task_approvals WHERE task_id = ? ORDER BY requested_at DESC', [taskId]);
47
- }
48
- isApprovalRequired(stage, project) {
49
- if (!project)
50
- return false;
51
- const config = this.db.queryOne('SELECT * FROM pipeline_config WHERE project = ?', [project]);
52
- if (!config?.approval_config)
53
- return false;
54
- try {
55
- const approvalConfig = JSON.parse(config.approval_config);
56
- return !!approvalConfig[stage]?.required;
57
- }
58
- catch {
59
- return false;
60
- }
61
- }
62
- hasPendingApproval(taskId, stage) {
63
- const pending = this.db.queryOne(`SELECT id FROM task_approvals WHERE task_id = ? AND stage = ? AND status = 'pending'`, [taskId, stage]);
64
- return !!pending;
65
- }
66
- isApproved(taskId, stage) {
67
- const approved = this.db.queryOne(`SELECT id FROM task_approvals WHERE task_id = ? AND stage = ? AND status = 'approved'`, [taskId, stage]);
68
- return !!approved;
69
- }
70
- resolve(approvalId, status, reviewer, comment) {
71
- const approval = this.db.queryOne('SELECT * FROM task_approvals WHERE id = ?', [
72
- approvalId,
73
- ]);
74
- if (!approval)
75
- throw new NotFoundError('Approval', approvalId);
76
- if (approval.status !== 'pending') {
77
- throw new ConflictError(`Approval ${approvalId} is already ${approval.status}.`);
78
- }
79
- this.db.run(`UPDATE task_approvals SET status = ?, reviewer = ?, resolved_at = datetime('now'), comment = ? WHERE id = ?`, [status, reviewer, comment ?? null, approvalId]);
80
- const resolved = this.db.queryOne('SELECT * FROM task_approvals WHERE id = ?', [
81
- approvalId,
82
- ]);
83
- this.events.emit(status === 'approved' ? 'approval:approved' : 'approval:rejected', {
84
- approval: resolved,
85
- });
86
- return resolved;
87
- }
88
- }
89
- //# sourceMappingURL=approvals.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"approvals.js","sourceRoot":"","sources":["../../src/domain/approvals.ts"],"names":[],"mappings":"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"}
@@ -1,28 +0,0 @@
1
- import type { Db } from '../storage/database.js';
2
- export declare class CleanupService {
3
- private readonly db;
4
- private readonly retentionDays;
5
- private timer;
6
- constructor(db: Db, retentionDays?: number);
7
- start(): void;
8
- stop(): void;
9
- run(): {
10
- purgedTasks: number;
11
- purgedComments: number;
12
- purgedArtifacts: number;
13
- purgedApprovals: number;
14
- };
15
- purgeAll(): {
16
- purgedTasks: number;
17
- purgedComments: number;
18
- purgedArtifacts: number;
19
- purgedApprovals: number;
20
- };
21
- purgeEverything(): {
22
- purgedTasks: number;
23
- purgedComments: number;
24
- purgedArtifacts: number;
25
- purgedApprovals: number;
26
- };
27
- }
28
- //# sourceMappingURL=cleanup.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../../src/domain/cleanup.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAC;AAEjD,qBAAa,cAAc;IAIvB,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAJhC,OAAO,CAAC,KAAK,CAA+C;gBAGzC,EAAE,EAAE,EAAE,EACN,aAAa,GAAE,MAAW;IAG7C,KAAK,IAAI,IAAI;IAQb,IAAI,IAAI,IAAI;IAOZ,GAAG,IAAI;QACL,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,MAAM,CAAC;KACzB;IAmCD,QAAQ,IAAI;QACV,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,MAAM,CAAC;KACzB;IAoBD,eAAe,IAAI;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,MAAM,CAAC;KACzB;CAaF"}
@@ -1,68 +0,0 @@
1
- export class CleanupService {
2
- db;
3
- retentionDays;
4
- timer = null;
5
- constructor(db, retentionDays = 30) {
6
- this.db = db;
7
- this.retentionDays = retentionDays;
8
- }
9
- start() {
10
- // Run cleanup every hour
11
- this.timer = setInterval(() => this.run(), 60 * 60 * 1000);
12
- this.timer.unref();
13
- // Run once on start (delayed 10s)
14
- setTimeout(() => this.run(), 10_000).unref();
15
- }
16
- stop() {
17
- if (this.timer) {
18
- clearInterval(this.timer);
19
- this.timer = null;
20
- }
21
- }
22
- run() {
23
- const cutoff = new Date(Date.now() - this.retentionDays * 24 * 60 * 60 * 1000)
24
- .toISOString()
25
- .replace('T', ' ')
26
- .slice(0, 19);
27
- const tasks = this.db.run(`DELETE FROM tasks WHERE status IN ('completed', 'cancelled') AND updated_at < ?`, [cutoff]);
28
- // Orphaned comments (task deleted via CASCADE should handle this, but just in case)
29
- const comments = this.db.run(`DELETE FROM task_comments WHERE task_id NOT IN (SELECT id FROM tasks)`);
30
- // Orphaned artifacts (defensive — CASCADE should handle this)
31
- const artifacts = this.db.run(`DELETE FROM task_artifacts WHERE task_id NOT IN (SELECT id FROM tasks)`);
32
- // Resolved approvals older than retention
33
- const approvals = this.db.run(`DELETE FROM task_approvals WHERE status != 'pending' AND resolved_at < ?`, [cutoff]);
34
- return {
35
- purgedTasks: tasks.changes,
36
- purgedComments: comments.changes,
37
- purgedArtifacts: artifacts.changes,
38
- purgedApprovals: approvals.changes,
39
- };
40
- }
41
- purgeAll() {
42
- // Purge completed/cancelled by status OR tasks in done/cancelled stage
43
- const tasks = this.db.run(`DELETE FROM tasks WHERE status IN ('completed', 'cancelled') OR stage IN ('done', 'cancelled')`);
44
- const comments = this.db.run(`DELETE FROM task_comments WHERE task_id NOT IN (SELECT id FROM tasks)`);
45
- const artifacts = this.db.run(`DELETE FROM task_artifacts WHERE task_id NOT IN (SELECT id FROM tasks)`);
46
- const approvals = this.db.run(`DELETE FROM task_approvals WHERE status != 'pending'`);
47
- return {
48
- purgedTasks: tasks.changes,
49
- purgedComments: comments.changes,
50
- purgedArtifacts: artifacts.changes,
51
- purgedApprovals: approvals.changes,
52
- };
53
- }
54
- purgeEverything() {
55
- // Nuclear option — delete ALL tasks regardless of status/stage
56
- const tasks = this.db.run(`DELETE FROM tasks`);
57
- const comments = this.db.run(`DELETE FROM task_comments`);
58
- const artifacts = this.db.run(`DELETE FROM task_artifacts`);
59
- const approvals = this.db.run(`DELETE FROM task_approvals`);
60
- return {
61
- purgedTasks: tasks.changes,
62
- purgedComments: comments.changes,
63
- purgedArtifacts: artifacts.changes,
64
- purgedApprovals: approvals.changes,
65
- };
66
- }
67
- }
68
- //# sourceMappingURL=cleanup.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../../src/domain/cleanup.ts"],"names":[],"mappings":"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"}
@@ -1,14 +0,0 @@
1
- import type { Db } from '../storage/database.js';
2
- import type { EventBus } from './events.js';
3
- import type { CollaboratorRole, TaskCollaborator } from '../types.js';
4
- export declare class CollaboratorService {
5
- private readonly db;
6
- private readonly events;
7
- constructor(db: Db, events: EventBus);
8
- add(taskId: number, agentId: string, role?: CollaboratorRole): TaskCollaborator;
9
- remove(taskId: number, agentId: string): void;
10
- list(taskId: number): TaskCollaborator[];
11
- getTasksForAgent(agentId: string): number[];
12
- private validateAgent;
13
- }
14
- //# sourceMappingURL=collaborators.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"collaborators.d.ts","sourceRoot":"","sources":["../../src/domain/collaborators.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAMtE,qBAAa,mBAAmB;IAE5B,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,EAAE,EAAE,EAAE,EACN,MAAM,EAAE,QAAQ;IAGnC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAiC,GAAG,gBAAgB;IA4B/F,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAW7C,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,EAAE;IAOxC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE;IAQ3C,OAAO,CAAC,aAAa;CAKtB"}
@@ -1,59 +0,0 @@
1
- // =============================================================================
2
- // agent-tasks — Collaborator domain service
3
- //
4
- // Multiple agents can collaborate on a single task with defined roles.
5
- // =============================================================================
6
- import { NotFoundError, ValidationError, ConflictError } from '../types.js';
7
- import { rejectNullBytes, rejectControlChars } from './validate.js';
8
- const VALID_ROLES = ['collaborator', 'reviewer', 'watcher'];
9
- export class CollaboratorService {
10
- db;
11
- events;
12
- constructor(db, events) {
13
- this.db = db;
14
- this.events = events;
15
- }
16
- add(taskId, agentId, role = 'collaborator') {
17
- this.validateAgent(agentId);
18
- if (!VALID_ROLES.includes(role)) {
19
- throw new ValidationError(`Invalid role: ${role}. Valid: ${VALID_ROLES.join(', ')}`);
20
- }
21
- const task = this.db.queryOne('SELECT id FROM tasks WHERE id = ?', [taskId]);
22
- if (!task)
23
- throw new NotFoundError('Task', taskId);
24
- try {
25
- this.db.run(`INSERT INTO task_collaborators (task_id, agent_id, role) VALUES (?, ?, ?)`, [
26
- taskId,
27
- agentId,
28
- role,
29
- ]);
30
- }
31
- catch {
32
- throw new ConflictError(`Agent ${agentId} is already a collaborator on task ${taskId}.`);
33
- }
34
- const collab = this.db.queryOne('SELECT * FROM task_collaborators WHERE task_id = ? AND agent_id = ?', [taskId, agentId]);
35
- this.events.emit('collaborator:added', { task_id: taskId, agent_id: agentId, role });
36
- return collab;
37
- }
38
- remove(taskId, agentId) {
39
- const result = this.db.run('DELETE FROM task_collaborators WHERE task_id = ? AND agent_id = ?', [taskId, agentId]);
40
- if (result.changes === 0) {
41
- throw new NotFoundError('Collaborator', `${agentId} on task ${taskId}`);
42
- }
43
- this.events.emit('collaborator:removed', { task_id: taskId, agent_id: agentId });
44
- }
45
- list(taskId) {
46
- return this.db.queryAll('SELECT * FROM task_collaborators WHERE task_id = ? ORDER BY added_at ASC', [taskId]);
47
- }
48
- getTasksForAgent(agentId) {
49
- const rows = this.db.queryAll('SELECT task_id FROM task_collaborators WHERE agent_id = ?', [agentId]);
50
- return rows.map((r) => r.task_id);
51
- }
52
- validateAgent(agentId) {
53
- rejectNullBytes(agentId, 'agent_id');
54
- rejectControlChars(agentId, 'agent_id');
55
- if (!agentId.trim())
56
- throw new ValidationError('Agent ID must not be empty.');
57
- }
58
- }
59
- //# sourceMappingURL=collaborators.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"collaborators.js","sourceRoot":"","sources":["../../src/domain/collaborators.ts"],"names":[],"mappings":"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"}
@@ -1,14 +0,0 @@
1
- import type { Db } from '../storage/database.js';
2
- import type { EventBus } from './events.js';
3
- import type { TaskComment } from '../types.js';
4
- export declare class CommentService {
5
- private readonly db;
6
- private readonly events;
7
- constructor(db: Db, events: EventBus);
8
- add(taskId: number, agentId: string, content: string, parentCommentId?: number): TaskComment;
9
- list(taskId: number, limit?: number, offset?: number): TaskComment[];
10
- thread(commentId: number): TaskComment[];
11
- countByTask(): Record<number, number>;
12
- private validateContent;
13
- }
14
- //# sourceMappingURL=comments.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/domain/comments.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,EAAE,EAAE,EAAE,EACN,MAAM,EAAE,QAAQ;IAGnC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,WAAW;IA6B5F,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAM,EAAE,MAAM,SAAI,GAAG,WAAW,EAAE;IAO5D,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE;IAaxC,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IASrC,OAAO,CAAC,eAAe;CAQxB"}
@@ -1,63 +0,0 @@
1
- // =============================================================================
2
- // agent-tasks — Comment domain service
3
- //
4
- // Threaded comments on tasks for async multi-agent discussion.
5
- // =============================================================================
6
- import { NotFoundError, ValidationError } from '../types.js';
7
- import { MAX_DESCRIPTION_LENGTH, rejectNullBytes, rejectControlChars } from './validate.js';
8
- export class CommentService {
9
- db;
10
- events;
11
- constructor(db, events) {
12
- this.db = db;
13
- this.events = events;
14
- }
15
- add(taskId, agentId, content, parentCommentId) {
16
- this.validateContent(content);
17
- rejectNullBytes(agentId, 'agent_id');
18
- rejectControlChars(agentId, 'agent_id');
19
- const task = this.db.queryOne('SELECT id FROM tasks WHERE id = ?', [taskId]);
20
- if (!task)
21
- throw new NotFoundError('Task', taskId);
22
- if (parentCommentId !== undefined) {
23
- const parent = this.db.queryOne('SELECT * FROM task_comments WHERE id = ? AND task_id = ?', [parentCommentId, taskId]);
24
- if (!parent)
25
- throw new NotFoundError('Parent comment', parentCommentId);
26
- }
27
- const result = this.db.run(`INSERT INTO task_comments (task_id, agent_id, content, parent_comment_id) VALUES (?, ?, ?, ?)`, [taskId, agentId, content.trim(), parentCommentId ?? null]);
28
- const comment = this.db.queryOne('SELECT * FROM task_comments WHERE id = ?', [
29
- Number(result.lastInsertRowid),
30
- ]);
31
- this.events.emit('comment:created', { comment });
32
- return comment;
33
- }
34
- list(taskId, limit = 100, offset = 0) {
35
- return this.db.queryAll('SELECT * FROM task_comments WHERE task_id = ? ORDER BY created_at ASC LIMIT ? OFFSET ?', [taskId, Math.min(limit, 500), offset]);
36
- }
37
- thread(commentId) {
38
- const root = this.db.queryOne('SELECT * FROM task_comments WHERE id = ?', [
39
- commentId,
40
- ]);
41
- if (!root)
42
- throw new NotFoundError('Comment', commentId);
43
- const rootId = root.parent_comment_id ?? root.id;
44
- return this.db.queryAll('SELECT * FROM task_comments WHERE id = ? OR parent_comment_id = ? ORDER BY created_at ASC', [rootId, rootId]);
45
- }
46
- countByTask() {
47
- const rows = this.db.queryAll('SELECT task_id, COUNT(*) as cnt FROM task_comments GROUP BY task_id');
48
- const counts = {};
49
- for (const r of rows)
50
- counts[r.task_id] = r.cnt;
51
- return counts;
52
- }
53
- validateContent(content) {
54
- rejectNullBytes(content, 'comment content');
55
- const trimmed = content.trim();
56
- if (!trimmed)
57
- throw new ValidationError('Comment content must not be empty.');
58
- if (trimmed.length > MAX_DESCRIPTION_LENGTH) {
59
- throw new ValidationError(`Comment too long (max ${MAX_DESCRIPTION_LENGTH} chars).`);
60
- }
61
- }
62
- }
63
- //# sourceMappingURL=comments.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/domain/comments.ts"],"names":[],"mappings":"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"}
@@ -1,9 +0,0 @@
1
- import type { EventType, TasksEvent } from '../types.js';
2
- export type EventHandler = (event: TasksEvent) => void;
3
- export declare class EventBus {
4
- private readonly listeners;
5
- emit(type: EventType, data?: Record<string, unknown>): void;
6
- on(type: EventType | '*', handler: EventHandler): () => void;
7
- removeAll(): void;
8
- }
9
- //# sourceMappingURL=events.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/domain/events.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzD,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;AAEvD,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiD;IAE3E,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI;IA8B/D,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,GAAG,EAAE,OAAO,EAAE,YAAY,GAAG,MAAM,IAAI;IAY5D,SAAS,IAAI,IAAI;CAGlB"}
@@ -1,52 +0,0 @@
1
- // =============================================================================
2
- // agent-tasks — Event bus
3
- //
4
- // Simple in-process pub/sub for domain events.
5
- // =============================================================================
6
- export class EventBus {
7
- listeners = new Map();
8
- emit(type, data = {}) {
9
- const event = {
10
- type,
11
- timestamp: new Date().toISOString(),
12
- data,
13
- };
14
- const specific = this.listeners.get(type);
15
- if (specific) {
16
- for (const h of specific) {
17
- try {
18
- h(event);
19
- }
20
- catch {
21
- /* fail-safe */
22
- }
23
- }
24
- }
25
- const wildcards = this.listeners.get('*');
26
- if (wildcards) {
27
- for (const h of wildcards) {
28
- try {
29
- h(event);
30
- }
31
- catch {
32
- /* fail-safe */
33
- }
34
- }
35
- }
36
- }
37
- on(type, handler) {
38
- let set = this.listeners.get(type);
39
- if (!set) {
40
- set = new Set();
41
- this.listeners.set(type, set);
42
- }
43
- set.add(handler);
44
- return () => {
45
- set.delete(handler);
46
- };
47
- }
48
- removeAll() {
49
- this.listeners.clear();
50
- }
51
- }
52
- //# sourceMappingURL=events.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/domain/events.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,0BAA0B;AAC1B,EAAE;AACF,+CAA+C;AAC/C,gFAAgF;AAMhF,MAAM,OAAO,QAAQ;IACF,SAAS,GAAG,IAAI,GAAG,EAAsC,CAAC;IAE3E,IAAI,CAAC,IAAe,EAAE,OAAgC,EAAE;QACtD,MAAM,KAAK,GAAe;YACxB,IAAI;YACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,IAAI;SACL,CAAC;QAEF,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACzB,IAAI,CAAC;oBACH,CAAC,CAAC,KAAK,CAAC,CAAC;gBACX,CAAC;gBAAC,MAAM,CAAC;oBACP,eAAe;gBACjB,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;gBAC1B,IAAI,CAAC;oBACH,CAAC,CAAC,KAAK,CAAC,CAAC;gBACX,CAAC;gBAAC,MAAM,CAAC;oBACP,eAAe;gBACjB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,EAAE,CAAC,IAAqB,EAAE,OAAqB;QAC7C,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;YAChB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAChC,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACjB,OAAO,GAAG,EAAE;YACV,GAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC,CAAC;IACJ,CAAC;IAED,SAAS;QACP,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;CACF"}
@@ -1,2 +0,0 @@
1
- export declare function generateRules(format: 'mdc' | 'claude_md', stages: string[], project?: string): string;
2
- //# sourceMappingURL=rules.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/domain/rules.ts"],"names":[],"mappings":"AAOA,wBAAgB,aAAa,CAC3B,MAAM,EAAE,KAAK,GAAG,WAAW,EAC3B,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAKR"}
@@ -1,67 +0,0 @@
1
- // =============================================================================
2
- // agent-tasks — IDE rule generation
3
- //
4
- // Generates project-specific rule files for Cursor (.mdc) and Claude Code
5
- // (CLAUDE.md snippets) that instruct agents to use the pipeline.
6
- // =============================================================================
7
- export function generateRules(format, stages, project) {
8
- if (format === 'mdc') {
9
- return generateMdc(stages, project);
10
- }
11
- return generateClaudeMd(stages, project);
12
- }
13
- function generateMdc(stages, project) {
14
- const projectLine = project ? `\nProject: ${project}` : '';
15
- return `---
16
- description: Pipeline task management workflow for AI agents
17
- alwaysApply: true
18
- ---
19
-
20
- # Pipeline Workflow${projectLine}
21
-
22
- ## Task Lifecycle
23
-
24
- Tasks flow through stages: ${stages.filter((s) => s !== 'cancelled').join(' → ')}
25
-
26
- ## Rules
27
-
28
- 1. **Always check for work first**: Call \`task_next\` to find available tasks
29
- 2. **Claim before working**: Call \`task_claim\` before starting implementation
30
- 3. **Advance through stages**: Use \`task_advance\` — never skip stages
31
- 4. **Attach artifacts**: Use \`task_add_artifact\` at each stage (specs, plans, test results, review notes)
32
- 5. **Comment on decisions**: Use \`task_comment\` to record reasoning and tradeoffs
33
- 6. **Complete with results**: Use \`task_complete\` with a summary of what was done
34
- 7. **Create subtasks**: Break large tasks into subtasks with \`task_create\` using \`parent_id\`
35
-
36
- ## Available Tools
37
-
38
- - \`task_create\` — Create a task (title, description, priority, project, tags, parent_id)
39
- - \`task_list\` — List tasks (filter by status, stage, project, assignee)
40
- - \`task_claim\` — Claim and start working on a task
41
- - \`task_advance\` — Move to next stage (checks dependencies)
42
- - \`task_complete\` — Mark done with result
43
- - \`task_add_artifact\` — Attach spec/plan/test results/review notes
44
- - \`task_comment\` — Add discussion comment
45
- - \`task_search\` — Full-text search across tasks
46
- - \`task_next\` — Get highest-priority unblocked task
47
- - \`task_review_cycle\` — Approve or reject during review
48
- `;
49
- }
50
- function generateClaudeMd(stages, project) {
51
- const projectLine = project ? ` for project "${project}"` : '';
52
- return `## Pipeline Tasks${projectLine}
53
-
54
- Tasks flow through: ${stages.filter((s) => s !== 'cancelled').join(' → ')}
55
-
56
- ### Workflow
57
- 1. Check \`task_next\` for available work
58
- 2. \`task_claim\` before starting
59
- 3. \`task_advance\` through stages — attach artifacts at each stage
60
- 4. \`task_comment\` to record decisions
61
- 5. \`task_complete\` with summary
62
-
63
- ### Key Tools
64
- \`task_create\`, \`task_list\`, \`task_claim\`, \`task_advance\`, \`task_complete\`, \`task_add_artifact\`, \`task_comment\`, \`task_search\`, \`task_next\`, \`task_review_cycle\`
65
- `;
66
- }
67
- //# sourceMappingURL=rules.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/domain/rules.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,oCAAoC;AACpC,EAAE;AACF,0EAA0E;AAC1E,iEAAiE;AACjE,gFAAgF;AAEhF,MAAM,UAAU,aAAa,CAC3B,MAA2B,EAC3B,MAAgB,EAChB,OAAgB;IAEhB,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,OAAO,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,WAAW,CAAC,MAAgB,EAAE,OAAgB;IACrD,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,OAAO;;;;;qBAKY,WAAW;;;;6BAIH,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;CAwB/E,CAAC;AACF,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAgB,EAAE,OAAgB;IAC1D,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,iBAAiB,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/D,OAAO,oBAAoB,WAAW;;sBAElB,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;CAWxE,CAAC;AACF,CAAC"}
@@ -1,60 +0,0 @@
1
- import type { Db } from '../storage/database.js';
2
- import type { EventBus } from './events.js';
3
- import type { Task, TaskArtifact, TaskCreateInput, TaskDependency, TaskListFilter, TaskUpdateInput, PipelineConfig, SearchResult } from '../types.js';
4
- export declare const DEFAULT_STAGES: string[];
5
- export declare class TaskService {
6
- private readonly db;
7
- private readonly events;
8
- constructor(db: Db, events: EventBus);
9
- getPipelineStages(project?: string): string[];
10
- setPipelineConfig(project: string, stages: string[]): PipelineConfig;
11
- create(input: TaskCreateInput, createdBy: string): Task;
12
- update(taskId: number, updates: TaskUpdateInput): Task;
13
- list(filter?: TaskListFilter): Task[];
14
- getById(id: number): Task | null;
15
- claim(taskId: number, claimerName: string): Task;
16
- complete(taskId: number, result: string): Task;
17
- fail(taskId: number, result: string): Task;
18
- cancel(taskId: number, reason: string): Task;
19
- advance(taskId: number, toStage?: string): Task;
20
- regress(taskId: number, toStage: string, reason?: string): Task;
21
- next(project?: string, stage?: string): Task | null;
22
- addDependency(taskId: number, dependsOn: number): void;
23
- removeDependency(taskId: number, dependsOn: number): void;
24
- getDependencies(taskId: number): {
25
- blockers: Task[];
26
- blocking: Task[];
27
- };
28
- getAllDependencies(): TaskDependency[];
29
- addArtifact(taskId: number, name: string, content: string, createdBy: string, stage?: string): TaskArtifact;
30
- getArtifacts(taskId: number, stage?: string): TaskArtifact[];
31
- getArtifactCounts(): Record<number, number>;
32
- getSubtasks(taskId: number): Task[];
33
- getSubtaskProgress(taskId: number): {
34
- total: number;
35
- done: number;
36
- };
37
- getAllSubtaskProgress(): Record<number, {
38
- total: number;
39
- done: number;
40
- }>;
41
- search(query: string, options?: {
42
- project?: string;
43
- limit?: number;
44
- }): SearchResult[];
45
- private sanitizeFtsQuery;
46
- delete(taskId: number): void;
47
- private requireTask;
48
- private validateStage;
49
- private validateTitle;
50
- private validateDescription;
51
- private validateResult;
52
- private validateProjectName;
53
- private validateAssignee;
54
- private validateTags;
55
- private validateArtifactName;
56
- private validateArtifactContent;
57
- private checkDependencies;
58
- private wouldCreateCycle;
59
- }
60
- //# sourceMappingURL=tasks.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/domain/tasks.ts"],"names":[],"mappings":"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"}