sqlew 3.5.3 → 3.6.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 (227) hide show
  1. package/CHANGELOG.md +247 -1772
  2. package/README.md +70 -304
  3. package/assets/config.example.toml +97 -0
  4. package/dist/adapters/index.d.ts +11 -0
  5. package/dist/adapters/index.d.ts.map +1 -0
  6. package/dist/adapters/index.js +21 -0
  7. package/dist/adapters/index.js.map +1 -0
  8. package/dist/adapters/mysql-adapter.d.ts +31 -0
  9. package/dist/adapters/mysql-adapter.d.ts.map +1 -0
  10. package/dist/adapters/mysql-adapter.js +63 -0
  11. package/dist/adapters/mysql-adapter.js.map +1 -0
  12. package/dist/adapters/postgresql-adapter.d.ts +31 -0
  13. package/dist/adapters/postgresql-adapter.d.ts.map +1 -0
  14. package/dist/adapters/postgresql-adapter.js +63 -0
  15. package/dist/adapters/postgresql-adapter.js.map +1 -0
  16. package/dist/adapters/sqlite-adapter.d.ts +37 -0
  17. package/dist/adapters/sqlite-adapter.d.ts.map +1 -0
  18. package/dist/adapters/sqlite-adapter.js +129 -0
  19. package/dist/adapters/sqlite-adapter.js.map +1 -0
  20. package/dist/adapters/types.d.ts +33 -0
  21. package/dist/adapters/types.d.ts.map +1 -0
  22. package/dist/adapters/types.js +2 -0
  23. package/dist/adapters/types.js.map +1 -0
  24. package/dist/cli.js +55 -54
  25. package/dist/cli.js.map +1 -1
  26. package/dist/config/example-generator.d.ts +11 -0
  27. package/dist/config/example-generator.d.ts.map +1 -0
  28. package/dist/config/example-generator.js +48 -0
  29. package/dist/config/example-generator.js.map +1 -0
  30. package/dist/config/loader.d.ts.map +1 -1
  31. package/dist/config/loader.js +4 -0
  32. package/dist/config/loader.js.map +1 -1
  33. package/dist/config/types.d.ts +9 -0
  34. package/dist/config/types.d.ts.map +1 -1
  35. package/dist/config/types.js.map +1 -1
  36. package/dist/database.d.ts +44 -122
  37. package/dist/database.d.ts.map +1 -1
  38. package/dist/database.js +145 -416
  39. package/dist/database.js.map +1 -1
  40. package/dist/index.js +215 -185
  41. package/dist/index.js.map +1 -1
  42. package/dist/knexfile.d.ts +6 -0
  43. package/dist/knexfile.d.ts.map +1 -0
  44. package/dist/knexfile.js +85 -0
  45. package/dist/knexfile.js.map +1 -0
  46. package/dist/migrations/add-help-system-tables.d.ts +35 -0
  47. package/dist/migrations/add-help-system-tables.d.ts.map +1 -0
  48. package/dist/migrations/add-help-system-tables.js +206 -0
  49. package/dist/migrations/add-help-system-tables.js.map +1 -0
  50. package/dist/migrations/add-token-tracking.d.ts +28 -0
  51. package/dist/migrations/add-token-tracking.d.ts.map +1 -0
  52. package/dist/migrations/add-token-tracking.js +108 -0
  53. package/dist/migrations/add-token-tracking.js.map +1 -0
  54. package/dist/migrations/index.d.ts +25 -12
  55. package/dist/migrations/index.d.ts.map +1 -1
  56. package/dist/migrations/index.js +147 -20
  57. package/dist/migrations/index.js.map +1 -1
  58. package/dist/migrations/knex/20251025020452_create_master_tables.d.ts +4 -0
  59. package/dist/migrations/knex/20251025020452_create_master_tables.d.ts.map +1 -0
  60. package/dist/migrations/knex/20251025020452_create_master_tables.js +65 -0
  61. package/dist/migrations/knex/20251025020452_create_master_tables.js.map +1 -0
  62. package/dist/migrations/knex/20251025021152_create_transaction_tables.d.ts +4 -0
  63. package/dist/migrations/knex/20251025021152_create_transaction_tables.d.ts.map +1 -0
  64. package/dist/migrations/knex/20251025021152_create_transaction_tables.js +235 -0
  65. package/dist/migrations/knex/20251025021152_create_transaction_tables.js.map +1 -0
  66. package/dist/migrations/knex/20251025021351_create_indexes.d.ts +4 -0
  67. package/dist/migrations/knex/20251025021351_create_indexes.d.ts.map +1 -0
  68. package/dist/migrations/knex/20251025021351_create_indexes.js +62 -0
  69. package/dist/migrations/knex/20251025021351_create_indexes.js.map +1 -0
  70. package/dist/migrations/knex/20251025021416_seed_master_data.d.ts +4 -0
  71. package/dist/migrations/knex/20251025021416_seed_master_data.d.ts.map +1 -0
  72. package/dist/migrations/knex/20251025021416_seed_master_data.js +58 -0
  73. package/dist/migrations/knex/20251025021416_seed_master_data.js.map +1 -0
  74. package/dist/migrations/knex/20251025070349_create_views.d.ts +4 -0
  75. package/dist/migrations/knex/20251025070349_create_views.d.ts.map +1 -0
  76. package/dist/migrations/knex/20251025070349_create_views.js +143 -0
  77. package/dist/migrations/knex/20251025070349_create_views.js.map +1 -0
  78. package/dist/migrations/knex/20251025081221_add_link_type_to_task_decision_links.d.ts +4 -0
  79. package/dist/migrations/knex/20251025081221_add_link_type_to_task_decision_links.d.ts.map +1 -0
  80. package/dist/migrations/knex/20251025081221_add_link_type_to_task_decision_links.js +15 -0
  81. package/dist/migrations/knex/20251025081221_add_link_type_to_task_decision_links.js.map +1 -0
  82. package/dist/migrations/knex/20251025082220_fix_task_dependencies_columns.d.ts +8 -0
  83. package/dist/migrations/knex/20251025082220_fix_task_dependencies_columns.d.ts.map +1 -0
  84. package/dist/migrations/knex/20251025082220_fix_task_dependencies_columns.js +12 -0
  85. package/dist/migrations/knex/20251025082220_fix_task_dependencies_columns.js.map +1 -0
  86. package/dist/migrations/knex/20251025090000_create_help_system_tables.d.ts +19 -0
  87. package/dist/migrations/knex/20251025090000_create_help_system_tables.d.ts.map +1 -0
  88. package/dist/migrations/knex/20251025090000_create_help_system_tables.js +115 -0
  89. package/dist/migrations/knex/20251025090000_create_help_system_tables.js.map +1 -0
  90. package/dist/migrations/knex/20251025090100_seed_help_categories_and_use_cases.d.ts +13 -0
  91. package/dist/migrations/knex/20251025090100_seed_help_categories_and_use_cases.d.ts.map +1 -0
  92. package/dist/migrations/knex/20251025090100_seed_help_categories_and_use_cases.js +377 -0
  93. package/dist/migrations/knex/20251025090100_seed_help_categories_and_use_cases.js.map +1 -0
  94. package/dist/migrations/knex/20251025100000_seed_help_metadata.d.ts +15 -0
  95. package/dist/migrations/knex/20251025100000_seed_help_metadata.d.ts.map +1 -0
  96. package/dist/migrations/knex/20251025100000_seed_help_metadata.js +253 -0
  97. package/dist/migrations/knex/20251025100000_seed_help_metadata.js.map +1 -0
  98. package/dist/migrations/knex/20251025100100_seed_remaining_use_cases.d.ts +16 -0
  99. package/dist/migrations/knex/20251025100100_seed_remaining_use_cases.d.ts.map +1 -0
  100. package/dist/migrations/knex/20251025100100_seed_remaining_use_cases.js +276 -0
  101. package/dist/migrations/knex/20251025100100_seed_remaining_use_cases.js.map +1 -0
  102. package/dist/migrations/knex/20251025120000_add_cascade_to_task_dependencies.d.ts +8 -0
  103. package/dist/migrations/knex/20251025120000_add_cascade_to_task_dependencies.d.ts.map +1 -0
  104. package/dist/migrations/knex/20251025120000_add_cascade_to_task_dependencies.js +64 -0
  105. package/dist/migrations/knex/20251025120000_add_cascade_to_task_dependencies.js.map +1 -0
  106. package/dist/migrations/seed-help-data.d.ts +48 -0
  107. package/dist/migrations/seed-help-data.d.ts.map +1 -0
  108. package/dist/migrations/seed-help-data.js +1466 -0
  109. package/dist/migrations/seed-help-data.js.map +1 -0
  110. package/dist/migrations/seed-tool-metadata.d.ts +24 -0
  111. package/dist/migrations/seed-tool-metadata.d.ts.map +1 -0
  112. package/dist/migrations/seed-tool-metadata.js +392 -0
  113. package/dist/migrations/seed-tool-metadata.js.map +1 -0
  114. package/dist/migrations/v3.6.0-help-system-refactor.d.ts +46 -0
  115. package/dist/migrations/v3.6.0-help-system-refactor.d.ts.map +1 -0
  116. package/dist/migrations/v3.6.0-help-system-refactor.js +223 -0
  117. package/dist/migrations/v3.6.0-help-system-refactor.js.map +1 -0
  118. package/dist/schema.d.ts.map +1 -1
  119. package/dist/schema.js +2 -0
  120. package/dist/schema.js.map +1 -1
  121. package/dist/tests/git-aware-completion.test.js +89 -70
  122. package/dist/tests/git-aware-completion.test.js.map +1 -1
  123. package/dist/tests/help-system.test.d.ts +23 -0
  124. package/dist/tests/help-system.test.d.ts.map +1 -0
  125. package/dist/tests/help-system.test.js +374 -0
  126. package/dist/tests/help-system.test.js.map +1 -0
  127. package/dist/tests/tasks.auto-pruning-decision-link.test.js +92 -78
  128. package/dist/tests/tasks.auto-pruning-decision-link.test.js.map +1 -1
  129. package/dist/tests/tasks.auto-pruning-partial.test.js +106 -95
  130. package/dist/tests/tasks.auto-pruning-partial.test.js.map +1 -1
  131. package/dist/tests/tasks.auto-pruning-persistence.test.js +115 -97
  132. package/dist/tests/tasks.auto-pruning-persistence.test.js.map +1 -1
  133. package/dist/tests/tasks.auto-pruning-safety.test.js +124 -103
  134. package/dist/tests/tasks.auto-pruning-safety.test.js.map +1 -1
  135. package/dist/tests/tasks.dependencies.test.js +338 -307
  136. package/dist/tests/tasks.dependencies.test.js.map +1 -1
  137. package/dist/tests/tasks.link-file-backward-compat.test.js +116 -104
  138. package/dist/tests/tasks.link-file-backward-compat.test.js.map +1 -1
  139. package/dist/tests/tasks.watch-files-action.test.js +122 -101
  140. package/dist/tests/tasks.watch-files-action.test.js.map +1 -1
  141. package/dist/tests/tasks.watch-files-parameter.test.js +105 -94
  142. package/dist/tests/tasks.watch-files-parameter.test.js.map +1 -1
  143. package/dist/tests/two-step-git-completion.test.js +176 -133
  144. package/dist/tests/two-step-git-completion.test.js.map +1 -1
  145. package/dist/tests/vcs-staging.test.js +1 -1
  146. package/dist/tests/vcs-staging.test.js.map +1 -1
  147. package/dist/tools/config.d.ts +9 -6
  148. package/dist/tools/config.d.ts.map +1 -1
  149. package/dist/tools/config.js +16 -14
  150. package/dist/tools/config.js.map +1 -1
  151. package/dist/tools/constraints.d.ts +10 -7
  152. package/dist/tools/constraints.d.ts.map +1 -1
  153. package/dist/tools/constraints.js +66 -48
  154. package/dist/tools/constraints.js.map +1 -1
  155. package/dist/tools/context.d.ts +36 -33
  156. package/dist/tools/context.d.ts.map +1 -1
  157. package/dist/tools/context.js +374 -330
  158. package/dist/tools/context.js.map +1 -1
  159. package/dist/tools/files.d.ts +12 -9
  160. package/dist/tools/files.d.ts.map +1 -1
  161. package/dist/tools/files.js +173 -95
  162. package/dist/tools/files.js.map +1 -1
  163. package/dist/tools/help-queries.d.ts +130 -0
  164. package/dist/tools/help-queries.d.ts.map +1 -0
  165. package/dist/tools/help-queries.js +393 -0
  166. package/dist/tools/help-queries.js.map +1 -0
  167. package/dist/tools/messaging.d.ts +14 -11
  168. package/dist/tools/messaging.d.ts.map +1 -1
  169. package/dist/tools/messaging.js +217 -133
  170. package/dist/tools/messaging.js.map +1 -1
  171. package/dist/tools/tasks.d.ts +18 -16
  172. package/dist/tools/tasks.d.ts.map +1 -1
  173. package/dist/tools/tasks.js +513 -439
  174. package/dist/tools/tasks.js.map +1 -1
  175. package/dist/tools/utils.d.ts +14 -11
  176. package/dist/tools/utils.d.ts.map +1 -1
  177. package/dist/tools/utils.js +86 -121
  178. package/dist/tools/utils.js.map +1 -1
  179. package/dist/utils/activity-logging.d.ts +114 -0
  180. package/dist/utils/activity-logging.d.ts.map +1 -0
  181. package/dist/utils/activity-logging.js +162 -0
  182. package/dist/utils/activity-logging.js.map +1 -0
  183. package/dist/utils/batch.d.ts +2 -2
  184. package/dist/utils/batch.d.ts.map +1 -1
  185. package/dist/utils/batch.js +8 -8
  186. package/dist/utils/batch.js.map +1 -1
  187. package/dist/utils/cleanup.d.ts +21 -13
  188. package/dist/utils/cleanup.d.ts.map +1 -1
  189. package/dist/utils/cleanup.js +31 -24
  190. package/dist/utils/cleanup.js.map +1 -1
  191. package/dist/utils/debug-logger.d.ts +44 -0
  192. package/dist/utils/debug-logger.d.ts.map +1 -0
  193. package/dist/utils/debug-logger.js +116 -0
  194. package/dist/utils/debug-logger.js.map +1 -0
  195. package/dist/utils/help-tracking.d.ts +55 -0
  196. package/dist/utils/help-tracking.d.ts.map +1 -0
  197. package/dist/utils/help-tracking.js +88 -0
  198. package/dist/utils/help-tracking.js.map +1 -0
  199. package/dist/utils/retention.d.ts +7 -7
  200. package/dist/utils/retention.d.ts.map +1 -1
  201. package/dist/utils/retention.js +12 -12
  202. package/dist/utils/retention.js.map +1 -1
  203. package/dist/utils/task-stale-detection.d.ts +15 -13
  204. package/dist/utils/task-stale-detection.d.ts.map +1 -1
  205. package/dist/utils/task-stale-detection.js +100 -302
  206. package/dist/utils/task-stale-detection.js.map +1 -1
  207. package/dist/utils/token-estimation.d.ts +72 -0
  208. package/dist/utils/token-estimation.d.ts.map +1 -0
  209. package/dist/utils/token-estimation.js +71 -0
  210. package/dist/utils/token-estimation.js.map +1 -0
  211. package/dist/utils/token-logging.d.ts +48 -0
  212. package/dist/utils/token-logging.d.ts.map +1 -0
  213. package/dist/utils/token-logging.js +112 -0
  214. package/dist/utils/token-logging.js.map +1 -0
  215. package/dist/utils/view-queries.d.ts +34 -0
  216. package/dist/utils/view-queries.d.ts.map +1 -0
  217. package/dist/utils/view-queries.js +192 -0
  218. package/dist/utils/view-queries.js.map +1 -0
  219. package/dist/watcher/file-watcher.d.ts.map +1 -1
  220. package/dist/watcher/file-watcher.js +25 -11
  221. package/dist/watcher/file-watcher.js.map +1 -1
  222. package/docs/BEST_PRACTICES.md +56 -448
  223. package/docs/MIGRATION_v3.6.0.md +170 -0
  224. package/docs/SHARED_CONCEPTS.md +63 -208
  225. package/docs/TASK_OVERVIEW.md +2 -2
  226. package/docs/TOOL_SELECTION.md +41 -248
  227. package/package.json +16 -4
@@ -9,25 +9,24 @@
9
9
  * - Expected: Error thrown, task status unchanged, transaction rolled back
10
10
  */
11
11
  import { describe, it, beforeEach, afterEach } from 'node:test';
12
- import assert from 'node:assert/strict';
13
- import Database from 'better-sqlite3';
14
- import { initializeSchema } from '../schema.js';
15
- import { runAllMigrations } from '../migrations/index.js';
12
+ import * as assert from 'node:assert/strict';
13
+ import { initializeDatabase, closeDatabase } from '../database.js';
16
14
  import { detectAndTransitionToReview } from '../utils/task-stale-detection.js';
17
15
  describe('Auto-pruning: Safety check when all files pruned', () => {
18
16
  let db;
19
- beforeEach(() => {
20
- db = new Database(':memory:');
21
- db.pragma('foreign_keys = ON');
22
- initializeSchema(db);
23
- runAllMigrations(db);
17
+ beforeEach(async () => {
18
+ db = await initializeDatabase({
19
+ databaseType: 'sqlite',
20
+ connection: { filename: ':memory:' }
21
+ });
24
22
  });
25
- afterEach(() => {
26
- db.close();
23
+ afterEach(async () => {
24
+ await closeDatabase();
27
25
  });
28
26
  it('should block transition when all watched files are non-existent', async () => {
27
+ const knex = db.getKnex();
29
28
  // 1. Create test task in 'in_progress' status
30
- const taskId = createTestTask(db);
29
+ const taskId = await createTestTask(db);
31
30
  // 2. Add 3 non-existent files to watch list
32
31
  // Using paths that will never exist in the test environment
33
32
  const nonExistentFiles = [
@@ -35,27 +34,25 @@ describe('Auto-pruning: Safety check when all files pruned', () => {
35
34
  '/tmp/never-created-file-2.ts',
36
35
  '/tmp/never-created-file-3.ts'
37
36
  ];
38
- addWatchedFiles(db, taskId, nonExistentFiles);
37
+ await addWatchedFiles(db, taskId, nonExistentFiles);
39
38
  // 3. Make task appear "stale" by backdating its updated_ts
40
39
  // Set updated_ts to 10 minutes ago (older than default 3-minute idle threshold)
41
40
  const tenMinutesAgo = Math.floor(Date.now() / 1000) - (10 * 60);
42
- db.prepare(`
43
- UPDATE t_tasks
44
- SET updated_ts = ?
45
- WHERE id = ?
46
- `).run(tenMinutesAgo, taskId);
41
+ await knex('t_tasks')
42
+ .where({ id: taskId })
43
+ .update({ updated_ts: tenMinutesAgo });
47
44
  // 4. Verify task is in 'in_progress' before attempt
48
- const beforeStatus = db.prepare(`
49
- SELECT s.name
50
- FROM t_tasks t
51
- JOIN m_task_statuses s ON t.status_id = s.id
52
- WHERE t.id = ?
53
- `).get(taskId);
45
+ const beforeStatus = await knex('t_tasks as t')
46
+ .join('m_task_statuses as s', 't.status_id', 's.id')
47
+ .where('t.id', taskId)
48
+ .select('s.name')
49
+ .first();
54
50
  assert.strictEqual(beforeStatus.name, 'in_progress', 'Task should start in in_progress');
55
51
  // 5. Verify watch list has all 3 files before attempt
56
- const beforeWatchCount = db.prepare(`
57
- SELECT COUNT(*) as count FROM t_task_file_links WHERE task_id = ?
58
- `).get(taskId);
52
+ const beforeWatchCount = await knex('t_task_file_links')
53
+ .where({ task_id: taskId })
54
+ .count('* as count')
55
+ .first();
59
56
  assert.strictEqual(beforeWatchCount.count, 3, 'Watch list should have 3 files before pruning attempt');
60
57
  // 6. Attempt transition - should NOT throw at top level
61
58
  // The error should be caught internally and logged
@@ -64,27 +61,29 @@ describe('Auto-pruning: Safety check when all files pruned', () => {
64
61
  // 7. Verify zero tasks were transitioned
65
62
  assert.strictEqual(transitioned, 0, 'No tasks should have been transitioned');
66
63
  // 8. Verify task status unchanged (remains in in_progress)
67
- const afterStatus = db.prepare(`
68
- SELECT s.name
69
- FROM t_tasks t
70
- JOIN m_task_statuses s ON t.status_id = s.id
71
- WHERE t.id = ?
72
- `).get(taskId);
64
+ const afterStatus = await knex('t_tasks as t')
65
+ .join('m_task_statuses as s', 't.status_id', 's.id')
66
+ .where('t.id', taskId)
67
+ .select('s.name')
68
+ .first();
73
69
  assert.strictEqual(afterStatus.name, 'in_progress', 'Task should remain in in_progress after safety check');
74
70
  // 9. Verify NO audit records created (transaction rollback)
75
- const prunedCount = db.prepare(`
76
- SELECT COUNT(*) as count FROM t_task_pruned_files WHERE task_id = ?
77
- `).get(taskId);
71
+ const prunedCount = await knex('t_task_pruned_files')
72
+ .where({ task_id: taskId })
73
+ .count('* as count')
74
+ .first();
78
75
  assert.strictEqual(prunedCount.count, 0, 'Should have no pruned file records due to rollback');
79
76
  // 10. Verify watch list is NOT empty (transaction rolled back)
80
- const afterWatchCount = db.prepare(`
81
- SELECT COUNT(*) as count FROM t_task_file_links WHERE task_id = ?
82
- `).get(taskId);
77
+ const afterWatchCount = await knex('t_task_file_links')
78
+ .where({ task_id: taskId })
79
+ .count('* as count')
80
+ .first();
83
81
  assert.strictEqual(afterWatchCount.count, 3, 'Watch list should still have all 3 files after rollback');
84
82
  });
85
83
  it('should prune SOME non-existent files and continue (partial prune)', async () => {
84
+ const knex = db.getKnex();
86
85
  // Create task
87
- const taskId = createTestTask(db);
86
+ const taskId = await createTestTask(db);
88
87
  // Add mix of existent and non-existent files
89
88
  // Use package.json as a file that definitely exists in the project root
90
89
  const mixedFiles = [
@@ -92,60 +91,58 @@ describe('Auto-pruning: Safety check when all files pruned', () => {
92
91
  '/tmp/never-created-file-1.ts', // does not exist
93
92
  '/tmp/never-created-file-2.ts' // does not exist
94
93
  ];
95
- addWatchedFiles(db, taskId, mixedFiles);
94
+ await addWatchedFiles(db, taskId, mixedFiles);
96
95
  // Make task appear stale
97
96
  const tenMinutesAgo = Math.floor(Date.now() / 1000) - (10 * 60);
98
- db.prepare(`
99
- UPDATE t_tasks
100
- SET updated_ts = ?
101
- WHERE id = ?
102
- `).run(tenMinutesAgo, taskId);
97
+ await knex('t_tasks')
98
+ .where({ id: taskId })
99
+ .update({ updated_ts: tenMinutesAgo });
103
100
  // Verify initial watch count
104
- const beforeWatchCount = db.prepare(`
105
- SELECT COUNT(*) as count FROM t_task_file_links WHERE task_id = ?
106
- `).get(taskId);
101
+ const beforeWatchCount = await knex('t_task_file_links')
102
+ .where({ task_id: taskId })
103
+ .count('* as count')
104
+ .first();
107
105
  assert.strictEqual(beforeWatchCount.count, 3, 'Watch list should start with 3 files');
108
106
  // Attempt transition - should proceed with partial pruning
109
107
  await detectAndTransitionToReview(db);
110
108
  // Verify some files were pruned
111
- const prunedCount = db.prepare(`
112
- SELECT COUNT(*) as count FROM t_task_pruned_files WHERE task_id = ?
113
- `).get(taskId);
109
+ const prunedCount = await knex('t_task_pruned_files')
110
+ .where({ task_id: taskId })
111
+ .count('* as count')
112
+ .first();
114
113
  assert.strictEqual(prunedCount.count, 2, 'Should have 2 pruned file records (the non-existent ones)');
115
114
  // Verify watch list now has only 1 file (the existing one)
116
- const afterWatchCount = db.prepare(`
117
- SELECT COUNT(*) as count FROM t_task_file_links WHERE task_id = ?
118
- `).get(taskId);
115
+ const afterWatchCount = await knex('t_task_file_links')
116
+ .where({ task_id: taskId })
117
+ .count('* as count')
118
+ .first();
119
119
  assert.strictEqual(afterWatchCount.count, 1, 'Watch list should have 1 remaining file after partial prune');
120
120
  // Verify remaining file is package.json
121
- const remainingFile = db.prepare(`
122
- SELECT f.path
123
- FROM t_task_file_links tfl
124
- JOIN m_files f ON tfl.file_id = f.id
125
- WHERE tfl.task_id = ?
126
- `).get(taskId);
121
+ const remainingFile = await knex('t_task_file_links as tfl')
122
+ .join('m_files as f', 'tfl.file_id', 'f.id')
123
+ .where('tfl.task_id', taskId)
124
+ .select('f.path')
125
+ .first();
127
126
  assert.strictEqual(remainingFile.path, 'package.json', 'Remaining file should be package.json');
128
127
  });
129
128
  it('should handle task with no watched files gracefully', async () => {
129
+ const knex = db.getKnex();
130
130
  // Create task without any watched files
131
- const taskId = createTestTask(db);
131
+ const taskId = await createTestTask(db);
132
132
  // Make task appear stale
133
133
  const tenMinutesAgo = Math.floor(Date.now() / 1000) - (10 * 60);
134
- db.prepare(`
135
- UPDATE t_tasks
136
- SET updated_ts = ?
137
- WHERE id = ?
138
- `).run(tenMinutesAgo, taskId);
134
+ await knex('t_tasks')
135
+ .where({ id: taskId })
136
+ .update({ updated_ts: tenMinutesAgo });
139
137
  // Attempt transition - should skip this task
140
138
  const transitioned = await detectAndTransitionToReview(db);
141
139
  assert.strictEqual(transitioned, 0, 'Should not transition task with no watched files');
142
140
  // Verify task status unchanged
143
- const status = db.prepare(`
144
- SELECT s.name
145
- FROM t_tasks t
146
- JOIN m_task_statuses s ON t.status_id = s.id
147
- WHERE t.id = ?
148
- `).get(taskId);
141
+ const status = await knex('t_tasks as t')
142
+ .join('m_task_statuses as s', 't.status_id', 's.id')
143
+ .where('t.id', taskId)
144
+ .select('s.name')
145
+ .first();
149
146
  assert.strictEqual(status.name, 'in_progress', 'Task should remain in in_progress');
150
147
  });
151
148
  console.log('\n✅ All auto-pruning safety check tests passed!\n');
@@ -153,44 +150,68 @@ describe('Auto-pruning: Safety check when all files pruned', () => {
153
150
  /**
154
151
  * Helper: Create a test task in 'in_progress' status
155
152
  */
156
- function createTestTask(db) {
153
+ async function createTestTask(db) {
154
+ const knex = db.getKnex();
157
155
  // Create test agent
158
- const agentId = db.prepare(`
159
- INSERT INTO m_agents (name) VALUES (?) RETURNING id
160
- `).get('test-agent');
156
+ const [agentId] = await knex('m_agents')
157
+ .insert({ name: 'test-agent' })
158
+ .onConflict('name')
159
+ .ignore()
160
+ .returning('id');
161
+ // If insert was ignored, get the existing agent
162
+ let actualAgentId;
163
+ if (agentId) {
164
+ actualAgentId = agentId.id || agentId;
165
+ }
166
+ else {
167
+ const agent = await knex('m_agents')
168
+ .where({ name: 'test-agent' })
169
+ .select('id')
170
+ .first();
171
+ actualAgentId = agent.id;
172
+ }
161
173
  // Get 'in_progress' status ID
162
- const statusId = db.prepare(`
163
- SELECT id FROM m_task_statuses WHERE name = 'in_progress'
164
- `).get();
174
+ const statusRow = await knex('m_task_statuses')
175
+ .where({ name: 'in_progress' })
176
+ .select('id')
177
+ .first();
165
178
  // Create task with updated_ts set to now (will be backdated in tests)
166
- const taskId = db.prepare(`
167
- INSERT INTO t_tasks (
168
- title,
169
- status_id,
170
- priority,
171
- assigned_agent_id,
172
- created_by_agent_id,
173
- created_ts,
174
- updated_ts
175
- )
176
- VALUES (?, ?, 2, ?, ?, unixepoch(), unixepoch())
177
- RETURNING id
178
- `).get('Test task for auto-pruning', statusId.id, agentId.id, agentId.id);
179
- return taskId.id;
179
+ const currentTs = Math.floor(Date.now() / 1000);
180
+ const [taskId] = await knex('t_tasks')
181
+ .insert({
182
+ title: 'Test task for auto-pruning',
183
+ status_id: statusRow.id,
184
+ priority: 2,
185
+ assigned_agent_id: actualAgentId,
186
+ created_by_agent_id: actualAgentId,
187
+ created_ts: currentTs,
188
+ updated_ts: currentTs
189
+ })
190
+ .returning('id');
191
+ return taskId.id || taskId;
180
192
  }
181
193
  /**
182
194
  * Helper: Add watched files to a task
183
195
  */
184
- function addWatchedFiles(db, taskId, filePaths) {
185
- const insertFile = db.prepare(`
186
- INSERT OR IGNORE INTO m_files (path) VALUES (?) RETURNING id
187
- `);
188
- const linkFile = db.prepare(`
189
- INSERT INTO t_task_file_links (task_id, file_id) VALUES (?, ?)
190
- `);
196
+ async function addWatchedFiles(db, taskId, filePaths) {
197
+ const knex = db.getKnex();
191
198
  for (const filePath of filePaths) {
192
- const fileResult = insertFile.get(filePath);
193
- linkFile.run(taskId, fileResult.id);
199
+ // Insert file (ignore if exists)
200
+ await knex('m_files')
201
+ .insert({ path: filePath })
202
+ .onConflict('path')
203
+ .ignore();
204
+ // Get file ID
205
+ const fileRow = await knex('m_files')
206
+ .where({ path: filePath })
207
+ .select('id')
208
+ .first();
209
+ // Link file to task
210
+ await knex('t_task_file_links')
211
+ .insert({
212
+ task_id: taskId,
213
+ file_id: fileRow.id
214
+ });
194
215
  }
195
216
  }
196
217
  //# sourceMappingURL=tasks.auto-pruning-safety.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.auto-pruning-safety.test.js","sourceRoot":"","sources":["../../src/tests/tasks.auto-pruning-safety.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tasks.auto-pruning-safety.test.js","sourceRoot":"","sources":["../../src/tests/tasks.auto-pruning-safety.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E,QAAQ,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAChE,IAAI,EAAmB,CAAC;IAExB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,EAAE,GAAG,MAAM,kBAAkB,CAAC;YAC5B,YAAY,EAAE,QAAQ;YACtB,UAAU,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE;SACrC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,aAAa,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;QAE1B,8CAA8C;QAC9C,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,CAAC,CAAC;QAExC,4CAA4C;QAC5C,4DAA4D;QAC5D,MAAM,gBAAgB,GAAG;YACvB,8BAA8B;YAC9B,8BAA8B;YAC9B,8BAA8B;SAC/B,CAAC;QACF,MAAM,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC;QAEpD,2DAA2D;QAC3D,gFAAgF;QAChF,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAChE,MAAM,IAAI,CAAC,SAAS,CAAC;aAClB,KAAK,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;aACrB,MAAM,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC;QAEzC,oDAAoD;QACpD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC;aAC5C,IAAI,CAAC,sBAAsB,EAAE,aAAa,EAAE,MAAM,CAAC;aACnD,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;aACrB,MAAM,CAAC,QAAQ,CAAC;aAChB,KAAK,EAAsB,CAAC;QAE/B,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,EAAE,aAAa,EAAE,kCAAkC,CAAC,CAAC;QAEzF,sDAAsD;QACtD,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC;aACrD,KAAK,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAC1B,KAAK,CAAC,YAAY,CAAC;aACnB,KAAK,EAAuB,CAAC;QAEhC,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC,EAAE,uDAAuD,CAAC,CAAC;QAEvG,wDAAwD;QACxD,mDAAmD;QACnD,0DAA0D;QAC1D,MAAM,YAAY,GAAG,MAAM,2BAA2B,CAAC,EAAE,CAAC,CAAC;QAE3D,yCAAyC;QACzC,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,EAAE,wCAAwC,CAAC,CAAC;QAE9E,2DAA2D;QAC3D,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC;aAC3C,IAAI,CAAC,sBAAsB,EAAE,aAAa,EAAE,MAAM,CAAC;aACnD,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;aACrB,MAAM,CAAC,QAAQ,CAAC;aAChB,KAAK,EAAsB,CAAC;QAE/B,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,IAAI,EAAE,aAAa,EAAE,sDAAsD,CAAC,CAAC;QAE5G,4DAA4D;QAC5D,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC;aAClD,KAAK,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAC1B,KAAK,CAAC,YAAY,CAAC;aACnB,KAAK,EAAuB,CAAC;QAEhC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,oDAAoD,CAAC,CAAC;QAE/F,+DAA+D;QAC/D,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC;aACpD,KAAK,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAC1B,KAAK,CAAC,YAAY,CAAC;aACnB,KAAK,EAAuB,CAAC;QAEhC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC,EAAE,yDAAyD,CAAC,CAAC;IAC1G,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;QAE1B,cAAc;QACd,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,CAAC,CAAC;QAExC,6CAA6C;QAC7C,wEAAwE;QACxE,MAAM,UAAU,GAAG;YACjB,cAAc,EAAE,SAAS;YACzB,8BAA8B,EAAE,iBAAiB;YACjD,8BAA8B,CAAE,iBAAiB;SAClD,CAAC;QACF,MAAM,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAE9C,yBAAyB;QACzB,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAChE,MAAM,IAAI,CAAC,SAAS,CAAC;aAClB,KAAK,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;aACrB,MAAM,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC;QAEzC,6BAA6B;QAC7B,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC;aACrD,KAAK,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAC1B,KAAK,CAAC,YAAY,CAAC;aACnB,KAAK,EAAuB,CAAC;QAEhC,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC,EAAE,sCAAsC,CAAC,CAAC;QAEtF,2DAA2D;QAC3D,MAAM,2BAA2B,CAAC,EAAE,CAAC,CAAC;QAEtC,gCAAgC;QAChC,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC;aAClD,KAAK,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAC1B,KAAK,CAAC,YAAY,CAAC;aACnB,KAAK,EAAuB,CAAC;QAEhC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,2DAA2D,CAAC,CAAC;QAEtG,2DAA2D;QAC3D,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC;aACpD,KAAK,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAC1B,KAAK,CAAC,YAAY,CAAC;aACnB,KAAK,EAAuB,CAAC;QAEhC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC,EAAE,6DAA6D,CAAC,CAAC;QAE5G,wCAAwC;QACxC,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,0BAA0B,CAAC;aACzD,IAAI,CAAC,cAAc,EAAE,aAAa,EAAE,MAAM,CAAC;aAC3C,KAAK,CAAC,aAAa,EAAE,MAAM,CAAC;aAC5B,MAAM,CAAC,QAAQ,CAAC;aAChB,KAAK,EAAsB,CAAC;QAE/B,MAAM,CAAC,WAAW,CAAC,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,uCAAuC,CAAC,CAAC;IAClG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;QAE1B,wCAAwC;QACxC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,CAAC,CAAC;QAExC,yBAAyB;QACzB,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAChE,MAAM,IAAI,CAAC,SAAS,CAAC;aAClB,KAAK,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;aACrB,MAAM,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC;QAEzC,6CAA6C;QAC7C,MAAM,YAAY,GAAG,MAAM,2BAA2B,CAAC,EAAE,CAAC,CAAC;QAE3D,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,EAAE,kDAAkD,CAAC,CAAC;QAExF,+BAA+B;QAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC;aACtC,IAAI,CAAC,sBAAsB,EAAE,aAAa,EAAE,MAAM,CAAC;aACnD,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;aACrB,MAAM,CAAC,QAAQ,CAAC;aAChB,KAAK,EAAsB,CAAC;QAE/B,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,mCAAmC,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;AACnE,CAAC,CAAC,CAAC;AAEH;;GAEG;AACH,KAAK,UAAU,cAAc,CAAC,EAAmB;IAC/C,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAE1B,oBAAoB;IACpB,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC;SACrC,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;SAC9B,UAAU,CAAC,MAAM,CAAC;SAClB,MAAM,EAAE;SACR,SAAS,CAAC,IAAI,CAAC,CAAC;IAEnB,gDAAgD;IAChD,IAAI,aAAqB,CAAC;IAC1B,IAAI,OAAO,EAAE,CAAC;QACZ,aAAa,GAAG,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC;IACxC,CAAC;SAAM,CAAC;QACN,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC;aACjC,KAAK,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;aAC7B,MAAM,CAAC,IAAI,CAAC;aACZ,KAAK,EAAoB,CAAC;QAC7B,aAAa,GAAG,KAAK,CAAC,EAAE,CAAC;IAC3B,CAAC;IAED,8BAA8B;IAC9B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC;SAC5C,KAAK,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;SAC9B,MAAM,CAAC,IAAI,CAAC;SACZ,KAAK,EAAoB,CAAC;IAE7B,sEAAsE;IACtE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAChD,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC;SACnC,MAAM,CAAC;QACN,KAAK,EAAE,4BAA4B;QACnC,SAAS,EAAE,SAAS,CAAC,EAAE;QACvB,QAAQ,EAAE,CAAC;QACX,iBAAiB,EAAE,aAAa;QAChC,mBAAmB,EAAE,aAAa;QAClC,UAAU,EAAE,SAAS;QACrB,UAAU,EAAE,SAAS;KACtB,CAAC;SACD,SAAS,CAAC,IAAI,CAAC,CAAC;IAEnB,OAAO,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,eAAe,CAAC,EAAmB,EAAE,MAAc,EAAE,SAAmB;IACrF,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAE1B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,iCAAiC;QACjC,MAAM,IAAI,CAAC,SAAS,CAAC;aAClB,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;aAC1B,UAAU,CAAC,MAAM,CAAC;aAClB,MAAM,EAAE,CAAC;QAEZ,cAAc;QACd,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC;aAClC,KAAK,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;aACzB,MAAM,CAAC,IAAI,CAAC;aACZ,KAAK,EAAoB,CAAC;QAE7B,oBAAoB;QACpB,MAAM,IAAI,CAAC,mBAAmB,CAAC;aAC5B,MAAM,CAAC;YACN,OAAO,EAAE,MAAM;YACf,OAAO,EAAE,OAAO,CAAC,EAAE;SACpB,CAAC,CAAC;IACP,CAAC;AACH,CAAC"}