agkan 2.14.3 → 2.15.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 (179) hide show
  1. package/README.ja.md +13 -13
  2. package/README.md +13 -13
  3. package/dist/board/boardFavicon.d.ts +2 -0
  4. package/dist/board/boardFavicon.d.ts.map +1 -0
  5. package/dist/board/boardFavicon.js +5 -0
  6. package/dist/board/boardFavicon.js.map +1 -0
  7. package/dist/board/boardRenderer.d.ts +22 -6
  8. package/dist/board/boardRenderer.d.ts.map +1 -1
  9. package/dist/board/boardRenderer.js +40 -24
  10. package/dist/board/boardRenderer.js.map +1 -1
  11. package/dist/board/boardRoutes.d.ts +2 -2
  12. package/dist/board/boardRoutes.d.ts.map +1 -1
  13. package/dist/board/boardRoutes.js +18 -3
  14. package/dist/board/boardRoutes.js.map +1 -1
  15. package/dist/board/boardStyles.d.ts +1 -1
  16. package/dist/board/boardStyles.d.ts.map +1 -1
  17. package/dist/board/boardStyles.js +14 -6
  18. package/dist/board/boardStyles.js.map +1 -1
  19. package/dist/board/client/board.js +369 -13
  20. package/dist/board/server.d.ts +2 -2
  21. package/dist/board/server.d.ts.map +1 -1
  22. package/dist/board/server.js +5 -5
  23. package/dist/board/server.js.map +1 -1
  24. package/dist/cli/commands/agent-guide.d.ts.map +1 -1
  25. package/dist/cli/commands/agent-guide.js +6 -0
  26. package/dist/cli/commands/agent-guide.js.map +1 -1
  27. package/dist/cli/commands/board.d.ts.map +1 -1
  28. package/dist/cli/commands/board.js +202 -15
  29. package/dist/cli/commands/board.js.map +1 -1
  30. package/dist/cli/commands/ps.d.ts +7 -0
  31. package/dist/cli/commands/ps.d.ts.map +1 -0
  32. package/dist/cli/commands/ps.js +83 -0
  33. package/dist/cli/commands/ps.js.map +1 -0
  34. package/dist/cli/commands/task/add.js +1 -1
  35. package/dist/cli/commands/task/add.js.map +1 -1
  36. package/dist/cli/commands/task/copy.d.ts +6 -0
  37. package/dist/cli/commands/task/copy.d.ts.map +1 -0
  38. package/dist/cli/commands/task/copy.js +118 -0
  39. package/dist/cli/commands/task/copy.js.map +1 -0
  40. package/dist/cli/commands/task/list.d.ts.map +1 -1
  41. package/dist/cli/commands/task/list.js +37 -17
  42. package/dist/cli/commands/task/list.js.map +1 -1
  43. package/dist/cli/index.js +2 -0
  44. package/dist/cli/index.js.map +1 -1
  45. package/dist/cli/utils/board-daemon.d.ts +7 -0
  46. package/dist/cli/utils/board-daemon.d.ts.map +1 -0
  47. package/dist/cli/utils/board-daemon.js +77 -0
  48. package/dist/cli/utils/board-daemon.js.map +1 -0
  49. package/dist/db/adapters/sqlite-storage-backend.d.ts +26 -0
  50. package/dist/db/adapters/sqlite-storage-backend.d.ts.map +1 -0
  51. package/dist/db/adapters/sqlite-storage-backend.js +447 -0
  52. package/dist/db/adapters/sqlite-storage-backend.js.map +1 -0
  53. package/dist/db/connection.d.ts +14 -0
  54. package/dist/db/connection.d.ts.map +1 -1
  55. package/dist/db/connection.js +28 -2
  56. package/dist/db/connection.js.map +1 -1
  57. package/dist/db/migrations/20260328000000_initial_schema.d.ts +3 -0
  58. package/dist/db/migrations/20260328000000_initial_schema.d.ts.map +1 -0
  59. package/dist/db/migrations/20260328000000_initial_schema.js +218 -0
  60. package/dist/db/migrations/20260328000000_initial_schema.js.map +1 -0
  61. package/dist/db/migrations/20260329000000_add_session_id_to_task_run_logs.d.ts +3 -0
  62. package/dist/db/migrations/20260329000000_add_session_id_to_task_run_logs.d.ts.map +1 -0
  63. package/dist/db/migrations/20260329000000_add_session_id_to_task_run_logs.js +7 -0
  64. package/dist/db/migrations/20260329000000_add_session_id_to_task_run_logs.js.map +1 -0
  65. package/dist/db/migrations/index.d.ts +4 -0
  66. package/dist/db/migrations/index.d.ts.map +1 -0
  67. package/dist/db/migrations/index.js +18 -0
  68. package/dist/db/migrations/index.js.map +1 -0
  69. package/dist/db/migrations/types.d.ts +17 -0
  70. package/dist/db/migrations/types.d.ts.map +1 -0
  71. package/dist/{board/client → db/migrations}/types.js +0 -1
  72. package/dist/db/migrations/types.js.map +1 -0
  73. package/dist/db/reset.d.ts.map +1 -1
  74. package/dist/db/reset.js +8 -3
  75. package/dist/db/reset.js.map +1 -1
  76. package/dist/db/schema.d.ts +4 -4
  77. package/dist/db/schema.d.ts.map +1 -1
  78. package/dist/db/schema.js +22 -207
  79. package/dist/db/schema.js.map +1 -1
  80. package/dist/db/types/repository.d.ts +192 -0
  81. package/dist/db/types/repository.d.ts.map +1 -0
  82. package/dist/db/types/repository.js +15 -0
  83. package/dist/db/types/repository.js.map +1 -0
  84. package/dist/models/Attachment.d.ts +25 -0
  85. package/dist/models/Attachment.d.ts.map +1 -0
  86. package/dist/models/Attachment.js +7 -0
  87. package/dist/models/Attachment.js.map +1 -0
  88. package/dist/services/AttachmentService.d.ts +62 -0
  89. package/dist/services/AttachmentService.d.ts.map +1 -0
  90. package/dist/services/AttachmentService.js +95 -0
  91. package/dist/services/AttachmentService.js.map +1 -0
  92. package/dist/services/ClaudeProcessService.d.ts +100 -0
  93. package/dist/services/ClaudeProcessService.d.ts.map +1 -0
  94. package/dist/services/ClaudeProcessService.js +278 -0
  95. package/dist/services/ClaudeProcessService.js.map +1 -0
  96. package/dist/services/CommentService.d.ts +3 -3
  97. package/dist/services/CommentService.d.ts.map +1 -1
  98. package/dist/services/CommentService.js +10 -70
  99. package/dist/services/CommentService.js.map +1 -1
  100. package/dist/services/ExportImportService.d.ts +3 -3
  101. package/dist/services/ExportImportService.d.ts.map +1 -1
  102. package/dist/services/ExportImportService.js +12 -16
  103. package/dist/services/ExportImportService.js.map +1 -1
  104. package/dist/services/MetadataService.d.ts +3 -3
  105. package/dist/services/MetadataService.d.ts.map +1 -1
  106. package/dist/services/MetadataService.js +9 -69
  107. package/dist/services/MetadataService.js.map +1 -1
  108. package/dist/services/TagService.d.ts +3 -3
  109. package/dist/services/TagService.d.ts.map +1 -1
  110. package/dist/services/TagService.js +9 -35
  111. package/dist/services/TagService.js.map +1 -1
  112. package/dist/services/TaskBlockService.d.ts +3 -3
  113. package/dist/services/TaskBlockService.d.ts.map +1 -1
  114. package/dist/services/TaskBlockService.js +9 -36
  115. package/dist/services/TaskBlockService.js.map +1 -1
  116. package/dist/services/TaskService.d.ts +3 -23
  117. package/dist/services/TaskService.d.ts.map +1 -1
  118. package/dist/services/TaskService.js +34 -186
  119. package/dist/services/TaskService.js.map +1 -1
  120. package/dist/services/TaskTagService.d.ts +3 -3
  121. package/dist/services/TaskTagService.d.ts.map +1 -1
  122. package/dist/services/TaskTagService.js +19 -83
  123. package/dist/services/TaskTagService.js.map +1 -1
  124. package/dist/utils/logger.d.ts +7 -0
  125. package/dist/utils/logger.d.ts.map +1 -0
  126. package/dist/utils/logger.js +18 -0
  127. package/dist/utils/logger.js.map +1 -0
  128. package/package.json +12 -5
  129. package/dist/board/boardScript.d.ts +0 -2
  130. package/dist/board/boardScript.d.ts.map +0 -1
  131. package/dist/board/boardScript.js +0 -1202
  132. package/dist/board/boardScript.js.map +0 -1
  133. package/dist/board/client/addTaskModal.d.ts +0 -2
  134. package/dist/board/client/addTaskModal.d.ts.map +0 -1
  135. package/dist/board/client/addTaskModal.js +0 -64
  136. package/dist/board/client/addTaskModal.js.map +0 -1
  137. package/dist/board/client/autoScroll.d.ts +0 -4
  138. package/dist/board/client/autoScroll.d.ts.map +0 -1
  139. package/dist/board/client/autoScroll.js +0 -59
  140. package/dist/board/client/autoScroll.js.map +0 -1
  141. package/dist/board/client/boardPolling.d.ts +0 -15
  142. package/dist/board/client/boardPolling.d.ts.map +0 -1
  143. package/dist/board/client/boardPolling.js +0 -144
  144. package/dist/board/client/boardPolling.js.map +0 -1
  145. package/dist/board/client/burgerMenu.d.ts +0 -2
  146. package/dist/board/client/burgerMenu.d.ts.map +0 -1
  147. package/dist/board/client/burgerMenu.js +0 -80
  148. package/dist/board/client/burgerMenu.js.map +0 -1
  149. package/dist/board/client/contextMenu.d.ts +0 -2
  150. package/dist/board/client/contextMenu.d.ts.map +0 -1
  151. package/dist/board/client/contextMenu.js +0 -52
  152. package/dist/board/client/contextMenu.js.map +0 -1
  153. package/dist/board/client/detailPanel.d.ts +0 -8
  154. package/dist/board/client/detailPanel.d.ts.map +0 -1
  155. package/dist/board/client/detailPanel.js +0 -565
  156. package/dist/board/client/detailPanel.js.map +0 -1
  157. package/dist/board/client/dragDrop.d.ts +0 -6
  158. package/dist/board/client/dragDrop.d.ts.map +0 -1
  159. package/dist/board/client/dragDrop.js +0 -82
  160. package/dist/board/client/dragDrop.js.map +0 -1
  161. package/dist/board/client/filters.d.ts +0 -6
  162. package/dist/board/client/filters.d.ts.map +0 -1
  163. package/dist/board/client/filters.js +0 -167
  164. package/dist/board/client/filters.js.map +0 -1
  165. package/dist/board/client/main.d.ts +0 -2
  166. package/dist/board/client/main.d.ts.map +0 -1
  167. package/dist/board/client/main.js +0 -20
  168. package/dist/board/client/main.js.map +0 -1
  169. package/dist/board/client/tags.d.ts +0 -6
  170. package/dist/board/client/tags.d.ts.map +0 -1
  171. package/dist/board/client/tags.js +0 -198
  172. package/dist/board/client/tags.js.map +0 -1
  173. package/dist/board/client/types.d.ts +0 -48
  174. package/dist/board/client/types.d.ts.map +0 -1
  175. package/dist/board/client/types.js.map +0 -1
  176. package/dist/board/client/utils.d.ts +0 -4
  177. package/dist/board/client/utils.d.ts.map +0 -1
  178. package/dist/board/client/utils.js +0 -44
  179. package/dist/board/client/utils.js.map +0 -1
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.up = up;
4
+ function addColumnIfNotExists(db, alterSql) {
5
+ try {
6
+ db.exec(`SAVEPOINT add_column`);
7
+ db.exec(alterSql);
8
+ db.exec(`RELEASE SAVEPOINT add_column`);
9
+ }
10
+ catch {
11
+ db.exec(`ROLLBACK TO SAVEPOINT add_column`);
12
+ db.exec(`RELEASE SAVEPOINT add_column`);
13
+ }
14
+ }
15
+ function isStatusAllowed(db, status) {
16
+ try {
17
+ db.exec(`SAVEPOINT check_status`);
18
+ db.prepare(`INSERT INTO tasks (title, status, created_at, updated_at) VALUES ('__check__', ?, '', '')`).run(status);
19
+ db.exec(`ROLLBACK TO SAVEPOINT check_status`);
20
+ db.exec(`RELEASE SAVEPOINT check_status`);
21
+ return true;
22
+ }
23
+ catch {
24
+ db.exec(`ROLLBACK TO SAVEPOINT check_status`);
25
+ db.exec(`RELEASE SAVEPOINT check_status`);
26
+ return false;
27
+ }
28
+ }
29
+ function up(db) {
30
+ // Create tasks table
31
+ db.exec(`
32
+ CREATE TABLE IF NOT EXISTS tasks (
33
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
34
+ title TEXT NOT NULL,
35
+ body TEXT,
36
+ author TEXT,
37
+ status TEXT NOT NULL DEFAULT 'backlog' CHECK(status IN ('icebox', 'backlog', 'ready', 'in_progress', 'review', 'done', 'closed')),
38
+ created_at TEXT NOT NULL,
39
+ updated_at TEXT NOT NULL
40
+ );
41
+ `);
42
+ // Create index on tasks table
43
+ db.exec(`
44
+ CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
45
+ `);
46
+ db.exec(`
47
+ CREATE INDEX IF NOT EXISTS idx_tasks_author ON tasks(author);
48
+ `);
49
+ // Migrate tasks table to add 'review' status to CHECK constraint
50
+ if (!isStatusAllowed(db, 'review')) {
51
+ db.exec(`
52
+ CREATE TABLE tasks_new (
53
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
54
+ title TEXT NOT NULL,
55
+ body TEXT,
56
+ author TEXT,
57
+ status TEXT NOT NULL DEFAULT 'backlog' CHECK(status IN ('icebox', 'backlog', 'ready', 'in_progress', 'review', 'done', 'closed')),
58
+ created_at TEXT NOT NULL,
59
+ updated_at TEXT NOT NULL,
60
+ parent_id INTEGER DEFAULT NULL REFERENCES tasks_new(id) ON DELETE SET NULL
61
+ );
62
+ `);
63
+ db.exec(`INSERT INTO tasks_new SELECT id, title, body, author, status, created_at, updated_at, parent_id FROM tasks`);
64
+ db.exec(`DROP TABLE tasks`);
65
+ db.exec(`ALTER TABLE tasks_new RENAME TO tasks`);
66
+ db.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status)`);
67
+ db.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_author ON tasks(author)`);
68
+ db.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_parent_id ON tasks(parent_id)`);
69
+ }
70
+ // Migrate tasks table to add 'icebox' status to CHECK constraint
71
+ if (!isStatusAllowed(db, 'icebox')) {
72
+ db.exec(`
73
+ CREATE TABLE tasks_new (
74
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
75
+ title TEXT NOT NULL,
76
+ body TEXT,
77
+ author TEXT,
78
+ status TEXT NOT NULL DEFAULT 'backlog' CHECK(status IN ('icebox', 'backlog', 'ready', 'in_progress', 'review', 'done', 'closed')),
79
+ created_at TEXT NOT NULL,
80
+ updated_at TEXT NOT NULL,
81
+ parent_id INTEGER DEFAULT NULL REFERENCES tasks_new(id) ON DELETE SET NULL
82
+ );
83
+ `);
84
+ db.exec(`INSERT INTO tasks_new SELECT id, title, body, author, status, created_at, updated_at, parent_id FROM tasks`);
85
+ db.exec(`DROP TABLE tasks`);
86
+ db.exec(`ALTER TABLE tasks_new RENAME TO tasks`);
87
+ db.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status)`);
88
+ db.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_author ON tasks(author)`);
89
+ db.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_parent_id ON tasks(parent_id)`);
90
+ }
91
+ // Add parent_id column to tasks table (migration)
92
+ addColumnIfNotExists(db, `ALTER TABLE tasks ADD COLUMN parent_id INTEGER DEFAULT NULL REFERENCES tasks(id) ON DELETE SET NULL`);
93
+ db.exec(`
94
+ CREATE INDEX IF NOT EXISTS idx_tasks_parent_id ON tasks(parent_id)
95
+ `);
96
+ // Add assignees column to tasks table (migration)
97
+ addColumnIfNotExists(db, `ALTER TABLE tasks ADD COLUMN assignees TEXT DEFAULT NULL`);
98
+ // Create task_blocks table
99
+ db.exec(`
100
+ CREATE TABLE IF NOT EXISTS task_blocks (
101
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
102
+ blocker_task_id INTEGER NOT NULL,
103
+ blocked_task_id INTEGER NOT NULL,
104
+ created_at TEXT NOT NULL,
105
+ FOREIGN KEY (blocker_task_id) REFERENCES tasks(id) ON DELETE CASCADE,
106
+ FOREIGN KEY (blocked_task_id) REFERENCES tasks(id) ON DELETE CASCADE,
107
+ UNIQUE(blocker_task_id, blocked_task_id),
108
+ CHECK(blocker_task_id != blocked_task_id)
109
+ );
110
+ `);
111
+ // Create index on task_blocks table
112
+ db.exec(`
113
+ CREATE INDEX IF NOT EXISTS idx_task_blocks_blocker ON task_blocks(blocker_task_id);
114
+ `);
115
+ db.exec(`
116
+ CREATE INDEX IF NOT EXISTS idx_task_blocks_blocked ON task_blocks(blocked_task_id);
117
+ `);
118
+ // Create tags table
119
+ db.exec(`
120
+ CREATE TABLE IF NOT EXISTS tags (
121
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
122
+ name TEXT NOT NULL UNIQUE,
123
+ created_at TEXT NOT NULL
124
+ );
125
+ `);
126
+ // Create index on tags table
127
+ db.exec(`
128
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_tags_name ON tags(name);
129
+ `);
130
+ // Create task_tags table
131
+ db.exec(`
132
+ CREATE TABLE IF NOT EXISTS task_tags (
133
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
134
+ task_id INTEGER NOT NULL,
135
+ tag_id INTEGER NOT NULL,
136
+ created_at TEXT NOT NULL,
137
+ FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE,
138
+ FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE,
139
+ UNIQUE(task_id, tag_id)
140
+ );
141
+ `);
142
+ // Create index on task_tags table
143
+ db.exec(`
144
+ CREATE INDEX IF NOT EXISTS idx_task_tags_task_id ON task_tags(task_id);
145
+ `);
146
+ db.exec(`
147
+ CREATE INDEX IF NOT EXISTS idx_task_tags_tag_id ON task_tags(tag_id);
148
+ `);
149
+ // Create task_metadata table
150
+ db.exec(`
151
+ CREATE TABLE IF NOT EXISTS task_metadata (
152
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
153
+ task_id INTEGER NOT NULL,
154
+ key TEXT NOT NULL,
155
+ value TEXT NOT NULL,
156
+ created_at TEXT NOT NULL,
157
+ updated_at TEXT NOT NULL,
158
+ FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE,
159
+ UNIQUE(task_id, key)
160
+ );
161
+ `);
162
+ // Create index on task_metadata table
163
+ db.exec(`
164
+ CREATE INDEX IF NOT EXISTS idx_task_metadata_task_id ON task_metadata(task_id);
165
+ `);
166
+ // Create task_comments table
167
+ db.exec(`
168
+ CREATE TABLE IF NOT EXISTS task_comments (
169
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
170
+ task_id INTEGER NOT NULL,
171
+ author TEXT,
172
+ content TEXT NOT NULL,
173
+ created_at TEXT NOT NULL,
174
+ updated_at TEXT NOT NULL,
175
+ FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE
176
+ );
177
+ `);
178
+ // Create index on task_comments table
179
+ db.exec(`
180
+ CREATE INDEX IF NOT EXISTS idx_task_comments_task_id ON task_comments(task_id);
181
+ `);
182
+ db.exec(`
183
+ CREATE INDEX IF NOT EXISTS idx_task_comments_created_at ON task_comments(created_at);
184
+ `);
185
+ // Add priority column to tasks table (migration)
186
+ addColumnIfNotExists(db, `ALTER TABLE tasks ADD COLUMN priority TEXT DEFAULT NULL CHECK(priority IS NULL OR priority IN ('critical', 'high', 'medium', 'low'))`);
187
+ // Create task_run_logs table
188
+ db.exec(`
189
+ CREATE TABLE IF NOT EXISTS task_run_logs (
190
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
191
+ task_id INTEGER NOT NULL,
192
+ started_at TEXT NOT NULL,
193
+ finished_at TEXT,
194
+ exit_code INTEGER,
195
+ events TEXT NOT NULL,
196
+ FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE
197
+ );
198
+ `);
199
+ db.exec(`
200
+ CREATE INDEX IF NOT EXISTS idx_task_run_logs_task_id ON task_run_logs(task_id);
201
+ `);
202
+ // Migrate priority from task_metadata to tasks.priority
203
+ const priorityMetadata = db
204
+ .prepare(`SELECT task_id, value FROM task_metadata WHERE key = 'priority'`)
205
+ .all();
206
+ if (priorityMetadata.length > 0) {
207
+ const updateStmt = db.prepare(`UPDATE tasks SET priority = ? WHERE id = ? AND priority IS NULL`);
208
+ const deleteStmt = db.prepare(`DELETE FROM task_metadata WHERE task_id = ? AND key = 'priority'`);
209
+ for (const row of priorityMetadata) {
210
+ const validPriorities = ['critical', 'high', 'medium', 'low'];
211
+ if (validPriorities.includes(row.value)) {
212
+ updateStmt.run(row.value, row.task_id);
213
+ }
214
+ deleteStmt.run(row.task_id);
215
+ }
216
+ }
217
+ }
218
+ //# sourceMappingURL=20260328000000_initial_schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"20260328000000_initial_schema.js","sourceRoot":"","sources":["../../../src/db/migrations/20260328000000_initial_schema.ts"],"names":[],"mappings":";;AA2BA,gBA+NC;AAxPD,SAAS,oBAAoB,CAAC,EAAsB,EAAE,QAAgB;IACpE,IAAI,CAAC;QACH,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAChC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClB,EAAE,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,EAAE,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;QAC5C,EAAE,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,EAAsB,EAAE,MAAc;IAC7D,IAAI,CAAC;QACH,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAClC,EAAE,CAAC,OAAO,CAAC,2FAA2F,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpH,EAAE,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QAC9C,EAAE,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,EAAE,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QAC9C,EAAE,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAgB,EAAE,CAAC,EAAsB;IACvC,qBAAqB;IACrB,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;GAUP,CAAC,CAAC;IAEH,8BAA8B;IAC9B,EAAE,CAAC,IAAI,CAAC;;GAEP,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC;;GAEP,CAAC,CAAC;IAEH,iEAAiE;IACjE,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC;QACnC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;KAWP,CAAC,CAAC;QACH,EAAE,CAAC,IAAI,CACL,4GAA4G,CAC7G,CAAC;QACF,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC5B,EAAE,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QACjD,EAAE,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;QACxE,EAAE,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;QACxE,EAAE,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;IAChF,CAAC;IAED,iEAAiE;IACjE,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC;QACnC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;KAWP,CAAC,CAAC;QACH,EAAE,CAAC,IAAI,CACL,4GAA4G,CAC7G,CAAC;QACF,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC5B,EAAE,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QACjD,EAAE,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;QACxE,EAAE,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;QACxE,EAAE,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;IAChF,CAAC;IAED,kDAAkD;IAClD,oBAAoB,CAClB,EAAE,EACF,qGAAqG,CACtG,CAAC;IACF,EAAE,CAAC,IAAI,CAAC;;GAEP,CAAC,CAAC;IAEH,kDAAkD;IAClD,oBAAoB,CAAC,EAAE,EAAE,0DAA0D,CAAC,CAAC;IAErF,2BAA2B;IAC3B,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;GAWP,CAAC,CAAC;IAEH,oCAAoC;IACpC,EAAE,CAAC,IAAI,CAAC;;GAEP,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC;;GAEP,CAAC,CAAC;IAEH,oBAAoB;IACpB,EAAE,CAAC,IAAI,CAAC;;;;;;GAMP,CAAC,CAAC;IAEH,6BAA6B;IAC7B,EAAE,CAAC,IAAI,CAAC;;GAEP,CAAC,CAAC;IAEH,yBAAyB;IACzB,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;GAUP,CAAC,CAAC;IAEH,kCAAkC;IAClC,EAAE,CAAC,IAAI,CAAC;;GAEP,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC;;GAEP,CAAC,CAAC;IAEH,6BAA6B;IAC7B,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;GAWP,CAAC,CAAC;IAEH,sCAAsC;IACtC,EAAE,CAAC,IAAI,CAAC;;GAEP,CAAC,CAAC;IAEH,6BAA6B;IAC7B,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;GAUP,CAAC,CAAC;IAEH,sCAAsC;IACtC,EAAE,CAAC,IAAI,CAAC;;GAEP,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC;;GAEP,CAAC,CAAC;IAEH,iDAAiD;IACjD,oBAAoB,CAClB,EAAE,EACF,sIAAsI,CACvI,CAAC;IAEF,6BAA6B;IAC7B,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;GAUP,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC;;GAEP,CAAC,CAAC;IAEH,wDAAwD;IACxD,MAAM,gBAAgB,GAAG,EAAE;SACxB,OAAO,CAAC,iEAAiE,CAAC;SAC1E,GAAG,EAA+C,CAAC;IAEtD,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC,iEAAiE,CAAC,CAAC;QACjG,MAAM,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC,kEAAkE,CAAC,CAAC;QAElG,KAAK,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;YACnC,MAAM,eAAe,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC9D,IAAI,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YACzC,CAAC;YACD,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { MigratableDatabase } from './types';
2
+ export declare function up(db: MigratableDatabase): void;
3
+ //# sourceMappingURL=20260329000000_add_session_id_to_task_run_logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"20260329000000_add_session_id_to_task_run_logs.d.ts","sourceRoot":"","sources":["../../../src/db/migrations/20260329000000_add_session_id_to_task_run_logs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,wBAAgB,EAAE,CAAC,EAAE,EAAE,kBAAkB,GAAG,IAAI,CAE/C"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.up = up;
4
+ function up(db) {
5
+ db.exec(`ALTER TABLE task_run_logs ADD COLUMN session_id TEXT DEFAULT NULL`);
6
+ }
7
+ //# sourceMappingURL=20260329000000_add_session_id_to_task_run_logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"20260329000000_add_session_id_to_task_run_logs.js","sourceRoot":"","sources":["../../../src/db/migrations/20260329000000_add_session_id_to_task_run_logs.ts"],"names":[],"mappings":";;AAEA,gBAEC;AAFD,SAAgB,EAAE,CAAC,EAAsB;IACvC,EAAE,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;AAC/E,CAAC"}
@@ -0,0 +1,4 @@
1
+ export type { MigratableDatabase, Migration } from './types';
2
+ import type { Migration } from './types';
3
+ export declare const migrations: Migration[];
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/db/migrations/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAE7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAIzC,eAAO,MAAM,UAAU,EAAE,SAAS,EAWjC,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.migrations = void 0;
4
+ const _20260328000000_initial_schema_1 = require("./20260328000000_initial_schema");
5
+ const _20260329000000_add_session_id_to_task_run_logs_1 = require("./20260329000000_add_session_id_to_task_run_logs");
6
+ exports.migrations = [
7
+ {
8
+ version: '20260328000000',
9
+ description: 'initial_schema',
10
+ up: _20260328000000_initial_schema_1.up,
11
+ },
12
+ {
13
+ version: '20260329000000',
14
+ description: 'add_session_id_to_task_run_logs',
15
+ up: _20260329000000_add_session_id_to_task_run_logs_1.up,
16
+ },
17
+ ];
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/db/migrations/index.ts"],"names":[],"mappings":";;;AAGA,oFAAsE;AACtE,sHAAsF;AAEzE,QAAA,UAAU,GAAgB;IACrC;QACE,OAAO,EAAE,gBAAgB;QACzB,WAAW,EAAE,gBAAgB;QAC7B,EAAE,EAAE,mCAAa;KAClB;IACD;QACE,OAAO,EAAE,gBAAgB;QACzB,WAAW,EAAE,iCAAiC;QAC9C,EAAE,EAAE,oDAAY;KACjB;CACF,CAAC"}
@@ -0,0 +1,17 @@
1
+ type AnyStatement = {
2
+ get(...args: any[]): unknown;
3
+ run(...args: any[]): unknown;
4
+ all(...args: any[]): unknown[];
5
+ };
6
+ export interface MigratableDatabase {
7
+ exec(sql: string): unknown;
8
+ prepare(sql: string): AnyStatement;
9
+ transaction(fn: (...args: any[]) => any): (...args: any[]) => any;
10
+ }
11
+ export type Migration = {
12
+ version: string;
13
+ description: string;
14
+ up: (db: MigratableDatabase) => void;
15
+ };
16
+ export {};
17
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/db/migrations/types.ts"],"names":[],"mappings":"AACA,KAAK,YAAY,GAAG;IAAE,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IAAC,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IAAC,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,CAAA;CAAE,CAAC;AAEnH,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAAC;IAEnC,WAAW,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;CACnE;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,CAAC,EAAE,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACtC,CAAC"}
@@ -1,4 +1,3 @@
1
1
  "use strict";
2
- // Shared types for client-side board code
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
4
3
  //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/db/migrations/types.ts"],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"reset.d.ts","sourceRoot":"","sources":["../../src/db/reset.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAsBpC"}
1
+ {"version":3,"file":"reset.d.ts","sourceRoot":"","sources":["../../src/db/reset.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,IAAI,CA2BpC"}
package/dist/db/reset.js CHANGED
@@ -23,9 +23,14 @@ function resetDatabase() {
23
23
  connection_1.DatabaseConnection.close();
24
24
  // Database file path
25
25
  const dbPath = (0, config_1.resolveDatabasePath)();
26
- // Delete database file if it exists
27
- if (fs_1.default.existsSync(dbPath)) {
28
- fs_1.default.unlinkSync(dbPath);
26
+ // Delete database file and auxiliary SQLite files (journal, WAL, SHM).
27
+ // Orphaned auxiliary files from a previous interrupted write can cause
28
+ // SQLite to attempt journal recovery on the newly-created file, leading
29
+ // to "attempt to write a readonly database" or "disk I/O error".
30
+ for (const path of [dbPath, `${dbPath}-journal`, `${dbPath}-wal`, `${dbPath}-shm`]) {
31
+ if (fs_1.default.existsSync(path)) {
32
+ fs_1.default.unlinkSync(path);
33
+ }
29
34
  }
30
35
  // Initialize new database connection (schema is automatically created)
31
36
  connection_1.DatabaseConnection.getInstance();
@@ -1 +1 @@
1
- {"version":3,"file":"reset.js","sourceRoot":"","sources":["../../src/db/reset.ts"],"names":[],"mappings":";;;;;AAUA,sCAsBC;AAhCD,4CAAoB;AACpB,qCAA2D;AAC3D,6CAAkD;AAElD;;;;;GAKG;AACH,SAAgB,aAAa;IAC3B,uDAAuD;IACvD,IAAI,CAAC,IAAA,mBAAU,GAAE,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,oEAAoE;YAClE,wEAAwE,CAC3E,CAAC;IACJ,CAAC;IAED,4BAA4B;IAC5B,+BAAkB,CAAC,KAAK,EAAE,CAAC;IAE3B,qBAAqB;IACrB,MAAM,MAAM,GAAG,IAAA,4BAAmB,GAAE,CAAC;IAErC,oCAAoC;IACpC,IAAI,YAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,YAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IAED,uEAAuE;IACvE,+BAAkB,CAAC,WAAW,EAAE,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"reset.js","sourceRoot":"","sources":["../../src/db/reset.ts"],"names":[],"mappings":";;;;;AAUA,sCA2BC;AArCD,4CAAoB;AACpB,qCAA2D;AAC3D,6CAAkD;AAElD;;;;;GAKG;AACH,SAAgB,aAAa;IAC3B,uDAAuD;IACvD,IAAI,CAAC,IAAA,mBAAU,GAAE,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,oEAAoE;YAClE,wEAAwE,CAC3E,CAAC;IACJ,CAAC;IAED,4BAA4B;IAC5B,+BAAkB,CAAC,KAAK,EAAE,CAAC;IAE3B,qBAAqB;IACrB,MAAM,MAAM,GAAG,IAAA,4BAAmB,GAAE,CAAC;IAErC,uEAAuE;IACvE,uEAAuE;IACvE,wEAAwE;IACxE,iEAAiE;IACjE,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,GAAG,MAAM,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC;QACnF,IAAI,YAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,YAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,+BAAkB,CAAC,WAAW,EAAE,CAAC;AACnC,CAAC"}
@@ -1,9 +1,9 @@
1
- import Database from 'better-sqlite3';
1
+ import type { MigratableDatabase } from './migrations/types';
2
2
  /**
3
3
  * Create database schema and run migrations
4
4
  *
5
- * Note: This function receives a raw better-sqlite3 Database instance
6
- * because it needs to execute migrations before the StorageProvider is created.
5
+ * Note: This function receives a database instance that satisfies MigratableDatabase.
6
+ * It is called before the StorageProvider is created.
7
7
  */
8
- export declare function runMigrations(db: Database.Database): void;
8
+ export declare function runMigrations(db: MigratableDatabase): void;
9
9
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAyPzD"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAG7D;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,kBAAkB,GAAG,IAAI,CA4B1D"}
package/dist/db/schema.js CHANGED
@@ -1,219 +1,34 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.runMigrations = runMigrations;
4
+ const index_1 = require("./migrations/index");
4
5
  /**
5
6
  * Create database schema and run migrations
6
7
  *
7
- * Note: This function receives a raw better-sqlite3 Database instance
8
- * because it needs to execute migrations before the StorageProvider is created.
8
+ * Note: This function receives a database instance that satisfies MigratableDatabase.
9
+ * It is called before the StorageProvider is created.
9
10
  */
10
11
  function runMigrations(db) {
11
- // Create tasks table
12
12
  db.exec(`
13
- CREATE TABLE IF NOT EXISTS tasks (
14
- id INTEGER PRIMARY KEY AUTOINCREMENT,
15
- title TEXT NOT NULL,
16
- body TEXT,
17
- author TEXT,
18
- status TEXT NOT NULL DEFAULT 'backlog' CHECK(status IN ('icebox', 'backlog', 'ready', 'in_progress', 'review', 'done', 'closed')),
19
- created_at TEXT NOT NULL,
20
- updated_at TEXT NOT NULL
21
- );
22
- `);
23
- // Create index on tasks table
24
- db.exec(`
25
- CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
26
- `);
27
- db.exec(`
28
- CREATE INDEX IF NOT EXISTS idx_tasks_author ON tasks(author);
29
- `);
30
- // Migrate tasks table to add 'review' status to CHECK constraint
31
- const taskTableDef = db.prepare(`SELECT sql FROM sqlite_master WHERE type='table' AND name='tasks'`).get();
32
- if (taskTableDef && !taskTableDef.sql.includes("'review'")) {
33
- db.exec(`
34
- CREATE TABLE tasks_new (
35
- id INTEGER PRIMARY KEY AUTOINCREMENT,
36
- title TEXT NOT NULL,
37
- body TEXT,
38
- author TEXT,
39
- status TEXT NOT NULL DEFAULT 'backlog' CHECK(status IN ('icebox', 'backlog', 'ready', 'in_progress', 'review', 'done', 'closed')),
40
- created_at TEXT NOT NULL,
41
- updated_at TEXT NOT NULL,
42
- parent_id INTEGER DEFAULT NULL REFERENCES tasks_new(id) ON DELETE SET NULL
43
- );
44
- `);
45
- db.exec(`INSERT INTO tasks_new SELECT id, title, body, author, status, created_at, updated_at, parent_id FROM tasks`);
46
- db.exec(`DROP TABLE tasks`);
47
- db.exec(`ALTER TABLE tasks_new RENAME TO tasks`);
48
- db.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status)`);
49
- db.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_author ON tasks(author)`);
50
- db.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_parent_id ON tasks(parent_id)`);
51
- }
52
- // Migrate tasks table to add 'icebox' status to CHECK constraint
53
- const taskTableDefForIcebox = db
54
- .prepare(`SELECT sql FROM sqlite_master WHERE type='table' AND name='tasks'`)
55
- .get();
56
- if (taskTableDefForIcebox && !taskTableDefForIcebox.sql.includes("'icebox'")) {
57
- db.exec(`
58
- CREATE TABLE tasks_new (
59
- id INTEGER PRIMARY KEY AUTOINCREMENT,
60
- title TEXT NOT NULL,
61
- body TEXT,
62
- author TEXT,
63
- status TEXT NOT NULL DEFAULT 'backlog' CHECK(status IN ('icebox', 'backlog', 'ready', 'in_progress', 'review', 'done', 'closed')),
64
- created_at TEXT NOT NULL,
65
- updated_at TEXT NOT NULL,
66
- parent_id INTEGER DEFAULT NULL REFERENCES tasks_new(id) ON DELETE SET NULL
67
- );
68
- `);
69
- db.exec(`INSERT INTO tasks_new SELECT id, title, body, author, status, created_at, updated_at, parent_id FROM tasks`);
70
- db.exec(`DROP TABLE tasks`);
71
- db.exec(`ALTER TABLE tasks_new RENAME TO tasks`);
72
- db.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status)`);
73
- db.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_author ON tasks(author)`);
74
- db.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_parent_id ON tasks(parent_id)`);
75
- }
76
- // Add parent_id column to tasks table (migration)
77
- const columnExists = db
78
- .prepare(`
79
- SELECT COUNT(*) as count FROM pragma_table_info('tasks')
80
- WHERE name = 'parent_id'
81
- `)
82
- .get();
83
- if (columnExists.count === 0) {
84
- db.exec(`
85
- ALTER TABLE tasks ADD COLUMN parent_id INTEGER DEFAULT NULL
86
- REFERENCES tasks(id) ON DELETE SET NULL
87
- `);
88
- db.exec(`
89
- CREATE INDEX IF NOT EXISTS idx_tasks_parent_id ON tasks(parent_id)
90
- `);
91
- }
92
- // Add assignees column to tasks table (migration)
93
- const assigneesColumnExists = db
94
- .prepare(`
95
- SELECT COUNT(*) as count FROM pragma_table_info('tasks')
96
- WHERE name = 'assignees'
97
- `)
98
- .get();
99
- if (assigneesColumnExists.count === 0) {
100
- db.exec(`
101
- ALTER TABLE tasks ADD COLUMN assignees TEXT DEFAULT NULL
102
- `);
103
- }
104
- // Create task_blocks table
105
- db.exec(`
106
- CREATE TABLE IF NOT EXISTS task_blocks (
107
- id INTEGER PRIMARY KEY AUTOINCREMENT,
108
- blocker_task_id INTEGER NOT NULL,
109
- blocked_task_id INTEGER NOT NULL,
110
- created_at TEXT NOT NULL,
111
- FOREIGN KEY (blocker_task_id) REFERENCES tasks(id) ON DELETE CASCADE,
112
- FOREIGN KEY (blocked_task_id) REFERENCES tasks(id) ON DELETE CASCADE,
113
- UNIQUE(blocker_task_id, blocked_task_id),
114
- CHECK(blocker_task_id != blocked_task_id)
115
- );
116
- `);
117
- // Create index on task_blocks table
118
- db.exec(`
119
- CREATE INDEX IF NOT EXISTS idx_task_blocks_blocker ON task_blocks(blocker_task_id);
120
- `);
121
- db.exec(`
122
- CREATE INDEX IF NOT EXISTS idx_task_blocks_blocked ON task_blocks(blocked_task_id);
123
- `);
124
- // Create tags table
125
- db.exec(`
126
- CREATE TABLE IF NOT EXISTS tags (
127
- id INTEGER PRIMARY KEY AUTOINCREMENT,
128
- name TEXT NOT NULL UNIQUE,
129
- created_at TEXT NOT NULL
130
- );
131
- `);
132
- // Create index on tags table
133
- db.exec(`
134
- CREATE UNIQUE INDEX IF NOT EXISTS idx_tags_name ON tags(name);
135
- `);
136
- // Create task_tags table
137
- db.exec(`
138
- CREATE TABLE IF NOT EXISTS task_tags (
139
- id INTEGER PRIMARY KEY AUTOINCREMENT,
140
- task_id INTEGER NOT NULL,
141
- tag_id INTEGER NOT NULL,
142
- created_at TEXT NOT NULL,
143
- FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE,
144
- FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE,
145
- UNIQUE(task_id, tag_id)
146
- );
147
- `);
148
- // Create index on task_tags table
149
- db.exec(`
150
- CREATE INDEX IF NOT EXISTS idx_task_tags_task_id ON task_tags(task_id);
151
- `);
152
- db.exec(`
153
- CREATE INDEX IF NOT EXISTS idx_task_tags_tag_id ON task_tags(tag_id);
154
- `);
155
- // Create task_metadata table
156
- db.exec(`
157
- CREATE TABLE IF NOT EXISTS task_metadata (
158
- id INTEGER PRIMARY KEY AUTOINCREMENT,
159
- task_id INTEGER NOT NULL,
160
- key TEXT NOT NULL,
161
- value TEXT NOT NULL,
162
- created_at TEXT NOT NULL,
163
- updated_at TEXT NOT NULL,
164
- FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE,
165
- UNIQUE(task_id, key)
166
- );
167
- `);
168
- // Create index on task_metadata table
169
- db.exec(`
170
- CREATE INDEX IF NOT EXISTS idx_task_metadata_task_id ON task_metadata(task_id);
171
- `);
172
- // Create task_comments table
173
- db.exec(`
174
- CREATE TABLE IF NOT EXISTS task_comments (
175
- id INTEGER PRIMARY KEY AUTOINCREMENT,
176
- task_id INTEGER NOT NULL,
177
- author TEXT,
178
- content TEXT NOT NULL,
179
- created_at TEXT NOT NULL,
180
- updated_at TEXT NOT NULL,
181
- FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE
182
- );
183
- `);
184
- // Create index on task_comments table
185
- db.exec(`
186
- CREATE INDEX IF NOT EXISTS idx_task_comments_task_id ON task_comments(task_id);
187
- `);
188
- db.exec(`
189
- CREATE INDEX IF NOT EXISTS idx_task_comments_created_at ON task_comments(created_at);
190
- `);
191
- // Add priority column to tasks table (migration)
192
- const priorityColumnExists = db
193
- .prepare(`
194
- SELECT COUNT(*) as count FROM pragma_table_info('tasks')
195
- WHERE name = 'priority'
196
- `)
197
- .get();
198
- if (priorityColumnExists.count === 0) {
199
- db.exec(`
200
- ALTER TABLE tasks ADD COLUMN priority TEXT DEFAULT NULL
201
- CHECK(priority IS NULL OR priority IN ('critical', 'high', 'medium', 'low'))
202
- `);
203
- }
204
- // Migrate priority from task_metadata to tasks.priority
205
- const priorityMetadata = db
206
- .prepare(`SELECT task_id, value FROM task_metadata WHERE key = 'priority'`)
207
- .all();
208
- if (priorityMetadata.length > 0) {
209
- const updateStmt = db.prepare(`UPDATE tasks SET priority = ? WHERE id = ? AND priority IS NULL`);
210
- const deleteStmt = db.prepare(`DELETE FROM task_metadata WHERE task_id = ? AND key = 'priority'`);
211
- for (const row of priorityMetadata) {
212
- const validPriorities = ['critical', 'high', 'medium', 'low'];
213
- if (validPriorities.includes(row.value)) {
214
- updateStmt.run(row.value, row.task_id);
215
- }
216
- deleteStmt.run(row.task_id);
13
+ CREATE TABLE IF NOT EXISTS schema_migrations (
14
+ version TEXT PRIMARY KEY,
15
+ applied_at TEXT NOT NULL
16
+ )
17
+ `);
18
+ const appliedRows = db.prepare(`SELECT version FROM schema_migrations`).all();
19
+ const appliedSet = new Set(appliedRows.map((r) => r.version));
20
+ const pending = index_1.migrations
21
+ .filter((m) => !appliedSet.has(m.version))
22
+ .sort((a, b) => a.version.localeCompare(b.version));
23
+ for (const migration of pending) {
24
+ try {
25
+ db.transaction(() => {
26
+ migration.up(db);
27
+ db.prepare(`INSERT INTO schema_migrations (version, applied_at) VALUES (?, ?)`).run(migration.version, new Date().toISOString());
28
+ })();
29
+ }
30
+ catch (err) {
31
+ throw new Error(`Migration ${migration.version} failed: ${err instanceof Error ? err.message : String(err)}`);
217
32
  }
218
33
  }
219
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":";;AASA,sCA4BC;AApCD,8CAAgD;AAEhD;;;;;GAKG;AACH,SAAgB,aAAa,CAAC,EAAsB;IAClD,EAAE,CAAC,IAAI,CAAC;;;;;GAKP,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,EAAE,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC,GAAG,EAAgC,CAAC;IAC5G,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAE9D,MAAM,OAAO,GAAG,kBAAU;SACvB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;SACzC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAEtD,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;gBAClB,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBACjB,EAAE,CAAC,OAAO,CAAC,mEAAmE,CAAC,CAAC,GAAG,CACjF,SAAS,CAAC,OAAO,EACjB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CACzB,CAAC;YACJ,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,aAAa,SAAS,CAAC,OAAO,YAAY,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChH,CAAC;IACH,CAAC;AACH,CAAC"}