agent-tasks 1.7.0 → 1.9.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 (63) hide show
  1. package/README.md +17 -15
  2. package/dist/domain/agent-bridge.d.ts.map +1 -1
  3. package/dist/domain/agent-bridge.js +22 -2
  4. package/dist/domain/agent-bridge.js.map +1 -1
  5. package/dist/domain/approvals.d.ts.map +1 -1
  6. package/dist/domain/approvals.js +4 -1
  7. package/dist/domain/approvals.js.map +1 -1
  8. package/dist/domain/cleanup.d.ts.map +1 -1
  9. package/dist/domain/cleanup.js +8 -3
  10. package/dist/domain/cleanup.js.map +1 -1
  11. package/dist/domain/rules.js +11 -10
  12. package/dist/domain/rules.js.map +1 -1
  13. package/dist/domain/task-validator.d.ts +9 -0
  14. package/dist/domain/task-validator.d.ts.map +1 -0
  15. package/dist/domain/task-validator.js +70 -0
  16. package/dist/domain/task-validator.js.map +1 -0
  17. package/dist/domain/tasks.d.ts +14 -9
  18. package/dist/domain/tasks.d.ts.map +1 -1
  19. package/dist/domain/tasks.js +176 -109
  20. package/dist/domain/tasks.js.map +1 -1
  21. package/dist/index.js +4 -2
  22. package/dist/index.js.map +1 -1
  23. package/dist/storage/database.d.ts.map +1 -1
  24. package/dist/storage/database.js +4 -2
  25. package/dist/storage/database.js.map +1 -1
  26. package/dist/transport/mcp-handlers.d.ts +30 -0
  27. package/dist/transport/mcp-handlers.d.ts.map +1 -0
  28. package/dist/transport/mcp-handlers.js +408 -0
  29. package/dist/transport/mcp-handlers.js.map +1 -0
  30. package/dist/transport/mcp.d.ts.map +1 -1
  31. package/dist/transport/mcp.js +196 -656
  32. package/dist/transport/mcp.js.map +1 -1
  33. package/dist/transport/rest.d.ts.map +1 -1
  34. package/dist/transport/rest.js +8 -2
  35. package/dist/transport/rest.js.map +1 -1
  36. package/dist/transport/ws.d.ts.map +1 -1
  37. package/dist/transport/ws.js +7 -4
  38. package/dist/transport/ws.js.map +1 -1
  39. package/dist/ui/app.js +188 -1554
  40. package/dist/ui/board.js +401 -0
  41. package/dist/ui/drag.js +143 -0
  42. package/dist/ui/index.html +5 -0
  43. package/dist/ui/inline-edit.js +242 -0
  44. package/dist/ui/panel.js +574 -0
  45. package/dist/ui/styles.css +200 -0
  46. package/dist/ui/ui-utils.js +323 -0
  47. package/package.json +1 -1
  48. package/dist/db.d.ts +0 -10
  49. package/dist/db.d.ts.map +0 -1
  50. package/dist/db.js +0 -112
  51. package/dist/db.js.map +0 -1
  52. package/dist/event-bus.d.ts +0 -10
  53. package/dist/event-bus.d.ts.map +0 -1
  54. package/dist/event-bus.js +0 -38
  55. package/dist/event-bus.js.map +0 -1
  56. package/dist/session.d.ts +0 -7
  57. package/dist/session.d.ts.map +0 -1
  58. package/dist/session.js +0 -11
  59. package/dist/session.js.map +0 -1
  60. package/dist/tasks.d.ts +0 -32
  61. package/dist/tasks.d.ts.map +0 -1
  62. package/dist/tasks.js +0 -410
  63. package/dist/tasks.js.map +0 -1
@@ -690,6 +690,170 @@ header {
690
690
  color: var(--red);
691
691
  }
692
692
 
693
+ /* ---- Gate indicators ---- */
694
+
695
+ .gate-indicator {
696
+ display: flex;
697
+ align-items: center;
698
+ gap: 4px;
699
+ padding: 3px 8px;
700
+ font-size: 10px;
701
+ color: var(--text-dim);
702
+ border-bottom: 1px solid var(--border);
703
+ flex-wrap: wrap;
704
+ }
705
+
706
+ .gate-indicator .material-symbols-outlined {
707
+ font-size: 12px;
708
+ color: var(--orange);
709
+ }
710
+
711
+ .gate-req {
712
+ background: var(--orange-dim);
713
+ color: var(--orange);
714
+ padding: 1px 5px;
715
+ border-radius: 3px;
716
+ font-weight: 500;
717
+ font-size: 10px;
718
+ }
719
+
720
+ /* ---- Decision cards ---- */
721
+
722
+ .panel-decision {
723
+ border: 1px solid var(--border);
724
+ border-left: 3px solid var(--accent);
725
+ border-radius: var(--radius);
726
+ margin-bottom: 8px;
727
+ overflow: hidden;
728
+ }
729
+
730
+ .decision-header {
731
+ display: flex;
732
+ align-items: center;
733
+ gap: 6px;
734
+ padding: 8px 12px;
735
+ font-weight: 600;
736
+ font-size: 13px;
737
+ background: var(--bg-hover);
738
+ border-bottom: 1px solid var(--border);
739
+ }
740
+
741
+ .decision-header .material-symbols-outlined {
742
+ font-size: 16px;
743
+ color: var(--accent);
744
+ }
745
+
746
+ .decision-body {
747
+ padding: 8px 12px;
748
+ }
749
+
750
+ .decision-row {
751
+ display: flex;
752
+ gap: 8px;
753
+ padding: 4px 0;
754
+ font-size: 13px;
755
+ line-height: 1.4;
756
+ }
757
+
758
+ .decision-row + .decision-row {
759
+ border-top: 1px solid var(--border-light, var(--border));
760
+ }
761
+
762
+ .decision-label {
763
+ font-weight: 600;
764
+ min-width: 60px;
765
+ color: var(--text-muted);
766
+ font-size: 11px;
767
+ text-transform: uppercase;
768
+ letter-spacing: 0.3px;
769
+ padding-top: 1px;
770
+ }
771
+
772
+ .decision-chose {
773
+ color: var(--green, #2d8659);
774
+ }
775
+
776
+ .decision-over {
777
+ color: var(--text-dim);
778
+ }
779
+
780
+ .decision-because {
781
+ color: var(--text);
782
+ }
783
+
784
+ /* --------------------------------------------------------------------------
785
+ Learnings (side panel)
786
+ -------------------------------------------------------------------------- */
787
+
788
+ .panel-learning {
789
+ border: 1px solid var(--border);
790
+ border-left: 3px solid var(--amber, #9a6700);
791
+ border-radius: var(--radius);
792
+ margin-bottom: 8px;
793
+ overflow: hidden;
794
+ }
795
+
796
+ .learning-header {
797
+ display: flex;
798
+ align-items: center;
799
+ gap: 6px;
800
+ padding: 8px 12px;
801
+ font-weight: 600;
802
+ font-size: 13px;
803
+ background: var(--amber-dim, rgba(154, 103, 0, 0.12));
804
+ border-bottom: 1px solid var(--border);
805
+ }
806
+
807
+ .learning-icon {
808
+ font-size: 16px;
809
+ color: var(--amber, #9a6700);
810
+ }
811
+
812
+ .learning-category {
813
+ font-size: 11px;
814
+ text-transform: uppercase;
815
+ letter-spacing: 0.3px;
816
+ color: var(--amber, #9a6700);
817
+ background: var(--amber-dim, rgba(154, 103, 0, 0.12));
818
+ padding: 1px 6px;
819
+ border-radius: 4px;
820
+ font-weight: 500;
821
+ }
822
+
823
+ .learning-source {
824
+ font-size: 11px;
825
+ color: var(--text-dim);
826
+ font-weight: 400;
827
+ font-style: italic;
828
+ }
829
+
830
+ .learning-body {
831
+ padding: 8px 12px;
832
+ font-size: 13px;
833
+ line-height: 1.5;
834
+ }
835
+
836
+ .learning-body .rendered-md {
837
+ font-size: 13px;
838
+ }
839
+
840
+ /* --------------------------------------------------------------------------
841
+ Affinity indicator (task cards)
842
+ -------------------------------------------------------------------------- */
843
+
844
+ .task-card-affinity {
845
+ display: inline-flex;
846
+ align-items: center;
847
+ gap: 2px;
848
+ font-size: 11px;
849
+ color: var(--indigo, #5856d6);
850
+ margin-left: auto;
851
+ }
852
+
853
+ .task-card-affinity .material-symbols-outlined {
854
+ font-size: 14px;
855
+ }
856
+
693
857
  .column-body {
694
858
  padding: 6px 8px;
695
859
  overflow-y: auto;
@@ -1209,6 +1373,42 @@ header {
1209
1373
  outline-offset: 2px;
1210
1374
  }
1211
1375
 
1376
+ /* --------------------------------------------------------------------------
1377
+ Show More Button
1378
+ -------------------------------------------------------------------------- */
1379
+
1380
+ .column-show-more-btn {
1381
+ display: flex;
1382
+ align-items: center;
1383
+ justify-content: center;
1384
+ gap: 4px;
1385
+ padding: 8px;
1386
+ margin: 2px 8px 4px;
1387
+ border: none;
1388
+ border-radius: var(--radius-sm);
1389
+ background: var(--bg-elevated);
1390
+ color: var(--text-dim);
1391
+ font-size: 12px;
1392
+ font-weight: 500;
1393
+ font-family: var(--font-sans);
1394
+ cursor: pointer;
1395
+ transition: all var(--transition-fast);
1396
+ width: calc(100% - 16px);
1397
+ }
1398
+
1399
+ .column-show-more-btn:hover {
1400
+ color: var(--accent);
1401
+ background: var(--accent-dim);
1402
+ }
1403
+
1404
+ .column-show-more-btn .material-symbols-outlined {
1405
+ font-size: 16px;
1406
+ }
1407
+
1408
+ .kanban-column.collapsed .column-show-more-btn {
1409
+ display: none;
1410
+ }
1411
+
1212
1412
  /* --------------------------------------------------------------------------
1213
1413
  Inline Task Creation
1214
1414
  -------------------------------------------------------------------------- */
@@ -0,0 +1,323 @@
1
+ // =============================================================================
2
+ // agent-tasks — UI Utilities
3
+ //
4
+ // Avatar rendering, markdown, escaping, relative time, morphdom wrapper,
5
+ // syntax highlighting, diff detection/rendering.
6
+ // =============================================================================
7
+
8
+ window.TaskBoard = window.TaskBoard || {};
9
+
10
+ // ---- HTML Escaping ----
11
+
12
+ function esc(str) {
13
+ if (!str) return '';
14
+ return String(str)
15
+ .replace(/&/g, '&')
16
+ .replace(/</g, '&lt;')
17
+ .replace(/>/g, '&gt;')
18
+ .replace(/"/g, '&quot;');
19
+ }
20
+
21
+ function formatDate(iso) {
22
+ if (!iso) return '\u2014';
23
+ try {
24
+ const d = new Date(iso + 'Z');
25
+ return d.toLocaleString(undefined, {
26
+ month: 'short',
27
+ day: 'numeric',
28
+ hour: '2-digit',
29
+ minute: '2-digit',
30
+ });
31
+ } catch {
32
+ return iso;
33
+ }
34
+ }
35
+
36
+ // ---- DOM morphing (morphdom) ----
37
+
38
+ function morph(el, newInnerHTML) {
39
+ const wrap = document.createElement(el.tagName);
40
+ wrap.innerHTML = newInnerHTML;
41
+ morphdom(el, wrap, {
42
+ childrenOnly: true,
43
+ getNodeKey(node) {
44
+ if (node.id) return node.id;
45
+ if (
46
+ node.dataset &&
47
+ node.dataset.stage &&
48
+ node.classList &&
49
+ node.classList.contains('kanban-column')
50
+ )
51
+ return 'col-' + node.dataset.stage;
52
+ return null;
53
+ },
54
+ onBeforeElUpdated(fromEl, toEl) {
55
+ if (fromEl.classList && fromEl.classList.contains('task-card')) {
56
+ toEl.classList.add('no-anim');
57
+ }
58
+ return true;
59
+ },
60
+ });
61
+ }
62
+
63
+ // ---- Relative time ----
64
+
65
+ function relativeTime(iso) {
66
+ if (!iso) return '';
67
+ try {
68
+ const d = new Date(iso + 'Z');
69
+ const now = Date.now();
70
+ const diff = now - d.getTime();
71
+ if (diff < 0) return 'just now';
72
+ const secs = Math.floor(diff / 1000);
73
+ if (secs < 60) return 'just now';
74
+ const mins = Math.floor(secs / 60);
75
+ if (mins < 60) return `${mins}m ago`;
76
+ const hrs = Math.floor(mins / 60);
77
+ if (hrs < 24) return `${hrs}h ago`;
78
+ const days = Math.floor(hrs / 24);
79
+ if (days < 30) return `${days}d ago`;
80
+ const months = Math.floor(days / 30);
81
+ if (months < 12) return `${months}mo ago`;
82
+ return `${Math.floor(months / 12)}y ago`;
83
+ } catch {
84
+ return '';
85
+ }
86
+ }
87
+
88
+ // ---- Avatar ----
89
+
90
+ var AVATAR_COLORS = [
91
+ '#5d8da8',
92
+ '#6f42c1',
93
+ '#28a745',
94
+ '#fd7e14',
95
+ '#dc3545',
96
+ '#007bff',
97
+ '#5856d6',
98
+ '#f59e0b',
99
+ '#e83e8c',
100
+ '#20c997',
101
+ ];
102
+
103
+ function avatarColor(name) {
104
+ let hash = 0;
105
+ for (let i = 0; i < name.length; i++) {
106
+ hash = name.charCodeAt(i) + ((hash << 5) - hash);
107
+ }
108
+ return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length];
109
+ }
110
+
111
+ function avatarInitials(name) {
112
+ if (!name) return '?';
113
+ const parts = name
114
+ .replace(/[^a-zA-Z0-9\s-]/g, '')
115
+ .split(/[\s-]+/)
116
+ .filter(Boolean);
117
+ if (parts.length >= 2) return (parts[0][0] + parts[1][0]).toUpperCase();
118
+ return name.substring(0, 2).toUpperCase();
119
+ }
120
+
121
+ function renderAvatar(name, sizeClass) {
122
+ if (!name) return '';
123
+ const color = avatarColor(name);
124
+ const initials = avatarInitials(name);
125
+ const cls = sizeClass ? `avatar-circle ${sizeClass}` : 'avatar-circle';
126
+ return `<div class="${cls}" style="background:${color}" title="${esc(name)}">${esc(initials)}</div>`;
127
+ }
128
+
129
+ // ---- Markdown Rendering ----
130
+
131
+ function renderMarkdown(text) {
132
+ if (!text) return '';
133
+ if (typeof marked !== 'undefined' && typeof DOMPurify !== 'undefined') {
134
+ try {
135
+ const html = DOMPurify.sanitize(marked.parse(text, { breaks: true, gfm: true }));
136
+ return '<div class="rendered-md prose">' + html + '</div>';
137
+ } catch (e) {
138
+ return '<div class="rendered-md">' + esc(text) + '</div>';
139
+ }
140
+ }
141
+ return '<div class="rendered-md">' + esc(text).replace(/\n/g, '<br>') + '</div>';
142
+ }
143
+
144
+ // ---- Syntax Highlighting (via highlight.js CDN) ----
145
+
146
+ function highlightCode(code, langHint) {
147
+ if (!code) return esc(code);
148
+ if (typeof hljs !== 'undefined') {
149
+ try {
150
+ if (langHint) {
151
+ const result = hljs.highlight(code, { language: langHint, ignoreIllegals: true });
152
+ return result.value;
153
+ }
154
+ const result = hljs.highlightAuto(code);
155
+ return result.value;
156
+ } catch (e) {
157
+ return esc(code);
158
+ }
159
+ }
160
+ return esc(code);
161
+ }
162
+
163
+ function highlightSyntax(code, langHint) {
164
+ return highlightCode(code, langHint);
165
+ }
166
+
167
+ function detectLanguage(name) {
168
+ if (!name) return '';
169
+ const n = name.toLowerCase();
170
+ if (/\.(js|ts|jsx|tsx)/.test(n) || /javascript|typescript/.test(n)) return 'javascript';
171
+ if (/\.(py)/.test(n) || /python/.test(n)) return 'python';
172
+ if (/\.(sh|bash)/.test(n) || /shell|bash/.test(n)) return 'bash';
173
+ if (/\.json/.test(n)) return 'json';
174
+ if (/\.(css|scss)/.test(n)) return 'css';
175
+ if (/\.(html|xml)/.test(n)) return 'xml';
176
+ if (/\.sql/.test(n)) return 'sql';
177
+ if (/\.ya?ml/.test(n)) return 'yaml';
178
+ if (/\.rs/.test(n) || /rust/.test(n)) return 'rust';
179
+ if (/\.go/.test(n)) return 'go';
180
+ return '';
181
+ }
182
+
183
+ // ---- Diff Detection & Rendering ----
184
+
185
+ function isDiff(content) {
186
+ if (!content) return false;
187
+ const dLines = content.split('\n').slice(0, 30);
188
+ let hasHunkHeader = false;
189
+ let hasMinusFile = false;
190
+ let hasPlusFile = false;
191
+ let hasDiffCmd = false;
192
+ for (const line of dLines) {
193
+ if (/^@@\s/.test(line)) hasHunkHeader = true;
194
+ if (/^--- [ab\/]/.test(line)) hasMinusFile = true;
195
+ if (/^\+\+\+ [ab\/]/.test(line)) hasPlusFile = true;
196
+ if (/^diff --git/.test(line)) hasDiffCmd = true;
197
+ }
198
+ return hasHunkHeader || (hasMinusFile && hasPlusFile) || hasDiffCmd;
199
+ }
200
+
201
+ function renderDiff(content) {
202
+ const dLines = content.split('\n');
203
+ const leftRows = [];
204
+ const rightRows = [];
205
+ let leftLn = 0;
206
+ let rightLn = 0;
207
+
208
+ for (const line of dLines) {
209
+ if (/^(---|\+\+\+|diff |index )/.test(line)) {
210
+ continue;
211
+ } else if (/^@@/.test(line)) {
212
+ const m = line.match(/@@ -(\d+)(?:,\d+)? \+(\d+)/);
213
+ if (m) {
214
+ leftLn = parseInt(m[1], 10) - 1;
215
+ rightLn = parseInt(m[2], 10) - 1;
216
+ }
217
+ const escaped = esc(line);
218
+ leftRows.push('<tr class="diff-section-header"><td colspan="2">' + escaped + '</td></tr>');
219
+ rightRows.push('<tr class="diff-section-header"><td colspan="2">' + escaped + '</td></tr>');
220
+ } else if (/^\+/.test(line)) {
221
+ rightLn++;
222
+ const escaped = esc(line.slice(1));
223
+ leftRows.push(
224
+ '<tr class="diff-add"><td class="diff-ln"></td><td class="diff-code"></td></tr>',
225
+ );
226
+ rightRows.push(
227
+ '<tr class="diff-add"><td class="diff-ln">' +
228
+ rightLn +
229
+ '</td><td class="diff-code">' +
230
+ escaped +
231
+ '</td></tr>',
232
+ );
233
+ } else if (/^-/.test(line)) {
234
+ leftLn++;
235
+ const escaped = esc(line.slice(1));
236
+ leftRows.push(
237
+ '<tr class="diff-del"><td class="diff-ln">' +
238
+ leftLn +
239
+ '</td><td class="diff-code">' +
240
+ escaped +
241
+ '</td></tr>',
242
+ );
243
+ rightRows.push(
244
+ '<tr class="diff-del"><td class="diff-ln"></td><td class="diff-code"></td></tr>',
245
+ );
246
+ } else {
247
+ leftLn++;
248
+ rightLn++;
249
+ const text = line.startsWith(' ') ? line.slice(1) : line;
250
+ const escaped = esc(text);
251
+ leftRows.push(
252
+ '<tr class="diff-context"><td class="diff-ln">' +
253
+ leftLn +
254
+ '</td><td class="diff-code">' +
255
+ escaped +
256
+ '</td></tr>',
257
+ );
258
+ rightRows.push(
259
+ '<tr class="diff-context"><td class="diff-ln">' +
260
+ rightLn +
261
+ '</td><td class="diff-code">' +
262
+ escaped +
263
+ '</td></tr>',
264
+ );
265
+ }
266
+ }
267
+
268
+ return (
269
+ '<div class="diff-viewer">' +
270
+ '<div class="diff-side diff-left"><div class="diff-header">Original</div>' +
271
+ '<table class="diff-table">' +
272
+ leftRows.join('') +
273
+ '</table></div>' +
274
+ '<div class="diff-side diff-right"><div class="diff-header">Modified</div>' +
275
+ '<table class="diff-table">' +
276
+ rightRows.join('') +
277
+ '</table></div>' +
278
+ '</div>'
279
+ );
280
+ }
281
+
282
+ // ---- Toast ----
283
+
284
+ function showToast(title, body, type) {
285
+ const container = document.getElementById('toast-container');
286
+ const el = document.createElement('div');
287
+ el.className = 'toast';
288
+
289
+ const isError =
290
+ type === 'error' ||
291
+ title.toLowerCase().includes('fail') ||
292
+ title.toLowerCase().includes('error');
293
+ const iconName = isError ? 'error' : 'check_circle';
294
+ const iconClass = isError ? 'toast-icon-error' : 'toast-icon-success';
295
+
296
+ el.innerHTML =
297
+ `<span class="material-symbols-outlined toast-icon ${iconClass}" aria-hidden="true">${iconName}</span>` +
298
+ `<div class="toast-content"><div class="toast-title">${esc(title)}</div><div class="toast-body">${esc(body)}</div></div>`;
299
+ container.appendChild(el);
300
+
301
+ setTimeout(() => {
302
+ el.classList.add('fade-out');
303
+ el.addEventListener('animationend', () => el.remove(), { once: true });
304
+ setTimeout(() => el.remove(), 400);
305
+ }, 4000);
306
+ }
307
+
308
+ // ---- Register on namespace ----
309
+
310
+ TaskBoard.esc = esc;
311
+ TaskBoard.formatDate = formatDate;
312
+ TaskBoard.morph = morph;
313
+ TaskBoard.relativeTime = relativeTime;
314
+ TaskBoard.avatarColor = avatarColor;
315
+ TaskBoard.avatarInitials = avatarInitials;
316
+ TaskBoard.renderAvatar = renderAvatar;
317
+ TaskBoard.renderMarkdown = renderMarkdown;
318
+ TaskBoard.highlightCode = highlightCode;
319
+ TaskBoard.highlightSyntax = highlightSyntax;
320
+ TaskBoard.detectLanguage = detectLanguage;
321
+ TaskBoard.isDiff = isDiff;
322
+ TaskBoard.renderDiff = renderDiff;
323
+ TaskBoard.showToast = showToast;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-tasks",
3
- "version": "1.7.0",
3
+ "version": "1.9.0",
4
4
  "description": "Pipeline-driven task management for AI coding agents — stages, dependencies, artifacts, and multi-agent claiming",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/dist/db.d.ts DELETED
@@ -1,10 +0,0 @@
1
- import Database from 'better-sqlite3';
2
- export declare function log(level: string, msg: string): void;
3
- export declare function initDb(): Promise<Database.Database>;
4
- export declare function getDb(): Database.Database;
5
- export declare function transaction<T>(fn: () => T): T;
6
- export declare function queryAll<T>(sql: string, params?: unknown[]): T[];
7
- export declare function queryOne<T>(sql: string, params?: unknown[]): T | null;
8
- export declare function run(sql: string, params?: unknown[]): Database.RunResult;
9
- export declare function closeDb(): void;
10
- //# sourceMappingURL=db.d.ts.map
package/dist/db.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAOtC,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED,wBAAsB,MAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAqBzD;AAED,wBAAgB,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAGzC;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAG7C;AAuDD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,CAIhE;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,GAAG,IAAI,CAKrE;AAED,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC,SAAS,CAIvE;AAED,wBAAgB,OAAO,IAAI,IAAI,CAS9B"}
package/dist/db.js DELETED
@@ -1,112 +0,0 @@
1
- import Database from 'better-sqlite3';
2
- import { homedir } from 'os';
3
- import { join } from 'path';
4
- import { mkdirSync } from 'fs';
5
- let db = null;
6
- export function log(level, msg) {
7
- process.stderr.write(`[agent-tasks:${level}] ${new Date().toISOString()} ${msg}\n`);
8
- }
9
- export async function initDb() {
10
- if (db)
11
- return db;
12
- const inMemory = !!process.env.AGENT_TASKS_TEST;
13
- if (inMemory) {
14
- db = new Database(':memory:');
15
- }
16
- else {
17
- const dir = join(homedir(), '.claude');
18
- mkdirSync(dir, { recursive: true });
19
- const dbPath = process.env.AGENT_TASKS_DB || join(dir, 'agent-tasks.db');
20
- db = new Database(dbPath);
21
- }
22
- db.pragma('journal_mode = WAL');
23
- db.pragma('busy_timeout = 5000');
24
- db.pragma('synchronous = NORMAL');
25
- db.pragma('foreign_keys = ON');
26
- initSchema(db);
27
- return db;
28
- }
29
- export function getDb() {
30
- if (!db)
31
- throw new Error('Database not initialized. Call initDb() first.');
32
- return db;
33
- }
34
- export function transaction(fn) {
35
- const database = getDb();
36
- return database.transaction(fn)();
37
- }
38
- function initSchema(database) {
39
- database.exec(`
40
- CREATE TABLE IF NOT EXISTS tasks (
41
- id INTEGER PRIMARY KEY AUTOINCREMENT,
42
- title TEXT NOT NULL,
43
- description TEXT,
44
- created_by TEXT NOT NULL,
45
- assigned_to TEXT,
46
- status TEXT NOT NULL DEFAULT 'pending',
47
- stage TEXT NOT NULL DEFAULT 'backlog',
48
- priority INTEGER NOT NULL DEFAULT 0,
49
- project TEXT,
50
- tags TEXT,
51
- result TEXT,
52
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
53
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
54
- )
55
- `);
56
- database.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_assigned ON tasks(assigned_to, status)`);
57
- database.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_stage ON tasks(stage, priority)`);
58
- database.exec(`
59
- CREATE TABLE IF NOT EXISTS task_dependencies (
60
- task_id INTEGER NOT NULL,
61
- depends_on INTEGER NOT NULL,
62
- PRIMARY KEY (task_id, depends_on)
63
- )
64
- `);
65
- database.exec(`
66
- CREATE TABLE IF NOT EXISTS task_artifacts (
67
- id INTEGER PRIMARY KEY AUTOINCREMENT,
68
- task_id INTEGER NOT NULL,
69
- stage TEXT NOT NULL,
70
- name TEXT NOT NULL,
71
- content TEXT NOT NULL,
72
- created_by TEXT NOT NULL,
73
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
74
- )
75
- `);
76
- database.exec(`CREATE INDEX IF NOT EXISTS idx_task_artifacts_task ON task_artifacts(task_id, stage)`);
77
- database.exec(`
78
- CREATE TABLE IF NOT EXISTS pipeline_config (
79
- project TEXT PRIMARY KEY,
80
- stages TEXT NOT NULL DEFAULT '["backlog","spec","plan","implement","test","review","done","cancelled"]',
81
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
82
- )
83
- `);
84
- }
85
- export function queryAll(sql, params) {
86
- const database = getDb();
87
- const stmt = database.prepare(sql);
88
- return (params?.length ? stmt.all(...params) : stmt.all());
89
- }
90
- export function queryOne(sql, params) {
91
- const database = getDb();
92
- const stmt = database.prepare(sql);
93
- const row = params?.length ? stmt.get(...params) : stmt.get();
94
- return row ?? null;
95
- }
96
- export function run(sql, params) {
97
- const database = getDb();
98
- const stmt = database.prepare(sql);
99
- return params?.length ? stmt.run(...params) : stmt.run();
100
- }
101
- export function closeDb() {
102
- if (db) {
103
- try {
104
- db.close();
105
- }
106
- catch (e) {
107
- log('warn', `Error closing db: ${e}`);
108
- }
109
- db = null;
110
- }
111
- }
112
- //# sourceMappingURL=db.js.map
package/dist/db.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
@@ -1,10 +0,0 @@
1
- export type EventType = 'task:create' | 'task:update' | 'task:delete' | 'pipeline:config';
2
- type Handler = (data: unknown) => void;
3
- declare class EventBus {
4
- private listeners;
5
- emit(type: EventType, data?: unknown): void;
6
- on(type: EventType | '*', handler: Handler): () => void;
7
- }
8
- export declare const eventBus: EventBus;
9
- export {};
10
- //# sourceMappingURL=event-bus.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../src/event-bus.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,aAAa,GAAG,aAAa,GAAG,iBAAiB,CAAC;AAE1F,KAAK,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;AAEvC,cAAM,QAAQ;IACZ,OAAO,CAAC,SAAS,CAA4C;IAE7D,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAqB3C,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,GAAG,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,IAAI;CAWxD;AAED,eAAO,MAAM,QAAQ,UAAiB,CAAC"}