agent-tasks 1.1.0

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 -0
  2. package/README.md +74 -0
  3. package/dist/context.d.ts +17 -0
  4. package/dist/context.d.ts.map +1 -0
  5. package/dist/context.js +37 -0
  6. package/dist/context.js.map +1 -0
  7. package/dist/db.d.ts +10 -0
  8. package/dist/db.d.ts.map +1 -0
  9. package/dist/db.js +112 -0
  10. package/dist/db.js.map +1 -0
  11. package/dist/domain/agent-bridge.d.ts +13 -0
  12. package/dist/domain/agent-bridge.d.ts.map +1 -0
  13. package/dist/domain/agent-bridge.js +99 -0
  14. package/dist/domain/agent-bridge.js.map +1 -0
  15. package/dist/domain/approvals.d.ts +18 -0
  16. package/dist/domain/approvals.d.ts.map +1 -0
  17. package/dist/domain/approvals.js +89 -0
  18. package/dist/domain/approvals.js.map +1 -0
  19. package/dist/domain/cleanup.d.ts +28 -0
  20. package/dist/domain/cleanup.d.ts.map +1 -0
  21. package/dist/domain/cleanup.js +68 -0
  22. package/dist/domain/cleanup.js.map +1 -0
  23. package/dist/domain/collaborators.d.ts +14 -0
  24. package/dist/domain/collaborators.d.ts.map +1 -0
  25. package/dist/domain/collaborators.js +59 -0
  26. package/dist/domain/collaborators.js.map +1 -0
  27. package/dist/domain/comments.d.ts +14 -0
  28. package/dist/domain/comments.d.ts.map +1 -0
  29. package/dist/domain/comments.js +63 -0
  30. package/dist/domain/comments.js.map +1 -0
  31. package/dist/domain/events.d.ts +9 -0
  32. package/dist/domain/events.d.ts.map +1 -0
  33. package/dist/domain/events.js +52 -0
  34. package/dist/domain/events.js.map +1 -0
  35. package/dist/domain/rules.d.ts +2 -0
  36. package/dist/domain/rules.d.ts.map +1 -0
  37. package/dist/domain/rules.js +67 -0
  38. package/dist/domain/rules.js.map +1 -0
  39. package/dist/domain/tasks.d.ts +60 -0
  40. package/dist/domain/tasks.d.ts.map +1 -0
  41. package/dist/domain/tasks.js +616 -0
  42. package/dist/domain/tasks.js.map +1 -0
  43. package/dist/domain/validate.d.ts +14 -0
  44. package/dist/domain/validate.d.ts.map +1 -0
  45. package/dist/domain/validate.js +29 -0
  46. package/dist/domain/validate.js.map +1 -0
  47. package/dist/event-bus.d.ts +10 -0
  48. package/dist/event-bus.d.ts.map +1 -0
  49. package/dist/event-bus.js +38 -0
  50. package/dist/event-bus.js.map +1 -0
  51. package/dist/index.d.ts +3 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +121 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/server.d.ts +10 -0
  56. package/dist/server.d.ts.map +1 -0
  57. package/dist/server.js +95 -0
  58. package/dist/server.js.map +1 -0
  59. package/dist/session.d.ts +7 -0
  60. package/dist/session.d.ts.map +1 -0
  61. package/dist/session.js +11 -0
  62. package/dist/session.js.map +1 -0
  63. package/dist/storage/database.d.ts +15 -0
  64. package/dist/storage/database.d.ts.map +1 -0
  65. package/dist/storage/database.js +215 -0
  66. package/dist/storage/database.js.map +1 -0
  67. package/dist/tasks.d.ts +32 -0
  68. package/dist/tasks.d.ts.map +1 -0
  69. package/dist/tasks.js +410 -0
  70. package/dist/tasks.js.map +1 -0
  71. package/dist/transport/mcp.d.ts +6 -0
  72. package/dist/transport/mcp.d.ts.map +1 -0
  73. package/dist/transport/mcp.js +573 -0
  74. package/dist/transport/mcp.js.map +1 -0
  75. package/dist/transport/rest.d.ts +4 -0
  76. package/dist/transport/rest.d.ts.map +1 -0
  77. package/dist/transport/rest.js +382 -0
  78. package/dist/transport/rest.js.map +1 -0
  79. package/dist/transport/ws.d.ts +10 -0
  80. package/dist/transport/ws.d.ts.map +1 -0
  81. package/dist/transport/ws.js +177 -0
  82. package/dist/transport/ws.js.map +1 -0
  83. package/dist/types.d.ts +146 -0
  84. package/dist/types.d.ts.map +1 -0
  85. package/dist/types.js +35 -0
  86. package/dist/types.js.map +1 -0
  87. package/dist/ui/app.js +648 -0
  88. package/dist/ui/index.html +82 -0
  89. package/dist/ui/morphdom.min.js +1 -0
  90. package/dist/ui/styles.css +805 -0
  91. package/package.json +78 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../../src/domain/cleanup.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,cAAc;IAIN;IACA;IAJX,KAAK,GAA0C,IAAI,CAAC;IAE5D,YACmB,EAAM,EACN,gBAAwB,EAAE;QAD1B,OAAE,GAAF,EAAE,CAAI;QACN,kBAAa,GAAb,aAAa,CAAa;IAC1C,CAAC;IAEJ,KAAK;QACH,yBAAyB;QACzB,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC3D,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,kCAAkC;QAClC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;IAC/C,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;IACH,CAAC;IAED,GAAG;QAMD,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;aAC3E,WAAW,EAAE;aACb,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC;aACjB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAEhB,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CACvB,iFAAiF,EACjF,CAAC,MAAM,CAAC,CACT,CAAC;QAEF,oFAAoF;QACpF,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAC1B,uEAAuE,CACxE,CAAC;QAEF,8DAA8D;QAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAC3B,wEAAwE,CACzE,CAAC;QAEF,0CAA0C;QAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAC3B,0EAA0E,EAC1E,CAAC,MAAM,CAAC,CACT,CAAC;QAEF,OAAO;YACL,WAAW,EAAE,KAAK,CAAC,OAAO;YAC1B,cAAc,EAAE,QAAQ,CAAC,OAAO;YAChC,eAAe,EAAE,SAAS,CAAC,OAAO;YAClC,eAAe,EAAE,SAAS,CAAC,OAAO;SACnC,CAAC;IACJ,CAAC;IAED,QAAQ;QAMN,uEAAuE;QACvE,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CACvB,gGAAgG,CACjG,CAAC;QACF,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAC1B,uEAAuE,CACxE,CAAC;QACF,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAC3B,wEAAwE,CACzE,CAAC;QACF,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;QACtF,OAAO;YACL,WAAW,EAAE,KAAK,CAAC,OAAO;YAC1B,cAAc,EAAE,QAAQ,CAAC,OAAO;YAChC,eAAe,EAAE,SAAS,CAAC,OAAO;YAClC,eAAe,EAAE,SAAS,CAAC,OAAO;SACnC,CAAC;IACJ,CAAC;IAED,eAAe;QAMb,+DAA+D;QAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC5D,OAAO;YACL,WAAW,EAAE,KAAK,CAAC,OAAO;YAC1B,cAAc,EAAE,QAAQ,CAAC,OAAO;YAChC,eAAe,EAAE,SAAS,CAAC,OAAO;YAClC,eAAe,EAAE,SAAS,CAAC,OAAO;SACnC,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,14 @@
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
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,59 @@
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collaborators.js","sourceRoot":"","sources":["../../src/domain/collaborators.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
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
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,63 @@
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/domain/comments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
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
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,52 @@
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
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,2 @@
1
+ export declare function generateRules(format: 'mdc' | 'claude_md', stages: string[], project?: string): string;
2
+ //# sourceMappingURL=rules.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,67 @@
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
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,60 @@
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/domain/tasks.ts"],"names":[],"mappings":"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"}