sqlew 3.2.5 → 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 (291) hide show
  1. package/CHANGELOG.md +288 -1011
  2. package/README.md +80 -263
  3. package/assets/config.example.toml +97 -0
  4. package/assets/schema.sql +6 -1
  5. package/dist/adapters/index.d.ts +11 -0
  6. package/dist/adapters/index.d.ts.map +1 -0
  7. package/dist/adapters/index.js +21 -0
  8. package/dist/adapters/index.js.map +1 -0
  9. package/dist/adapters/mysql-adapter.d.ts +31 -0
  10. package/dist/adapters/mysql-adapter.d.ts.map +1 -0
  11. package/dist/adapters/mysql-adapter.js +63 -0
  12. package/dist/adapters/mysql-adapter.js.map +1 -0
  13. package/dist/adapters/postgresql-adapter.d.ts +31 -0
  14. package/dist/adapters/postgresql-adapter.d.ts.map +1 -0
  15. package/dist/adapters/postgresql-adapter.js +63 -0
  16. package/dist/adapters/postgresql-adapter.js.map +1 -0
  17. package/dist/adapters/sqlite-adapter.d.ts +37 -0
  18. package/dist/adapters/sqlite-adapter.d.ts.map +1 -0
  19. package/dist/adapters/sqlite-adapter.js +129 -0
  20. package/dist/adapters/sqlite-adapter.js.map +1 -0
  21. package/dist/adapters/types.d.ts +33 -0
  22. package/dist/adapters/types.d.ts.map +1 -0
  23. package/dist/adapters/types.js +2 -0
  24. package/dist/adapters/types.js.map +1 -0
  25. package/dist/cli.js +55 -54
  26. package/dist/cli.js.map +1 -1
  27. package/dist/config/example-generator.d.ts +11 -0
  28. package/dist/config/example-generator.d.ts.map +1 -0
  29. package/dist/config/example-generator.js +48 -0
  30. package/dist/config/example-generator.js.map +1 -0
  31. package/dist/config/loader.d.ts +46 -0
  32. package/dist/config/loader.d.ts.map +1 -0
  33. package/dist/config/loader.js +155 -0
  34. package/dist/config/loader.js.map +1 -0
  35. package/dist/config/types.d.ts +86 -0
  36. package/dist/config/types.d.ts.map +1 -0
  37. package/dist/config/types.js +28 -0
  38. package/dist/config/types.js.map +1 -0
  39. package/dist/constants.d.ts +9 -0
  40. package/dist/constants.d.ts.map +1 -1
  41. package/dist/constants.js +10 -0
  42. package/dist/constants.js.map +1 -1
  43. package/dist/database.d.ts +44 -122
  44. package/dist/database.d.ts.map +1 -1
  45. package/dist/database.js +145 -349
  46. package/dist/database.js.map +1 -1
  47. package/dist/index.js +223 -175
  48. package/dist/index.js.map +1 -1
  49. package/dist/knexfile.d.ts +6 -0
  50. package/dist/knexfile.d.ts.map +1 -0
  51. package/dist/knexfile.js +85 -0
  52. package/dist/knexfile.js.map +1 -0
  53. package/dist/migrations/add-help-system-tables.d.ts +35 -0
  54. package/dist/migrations/add-help-system-tables.d.ts.map +1 -0
  55. package/dist/migrations/add-help-system-tables.js +206 -0
  56. package/dist/migrations/add-help-system-tables.js.map +1 -0
  57. package/dist/migrations/add-token-tracking.d.ts +28 -0
  58. package/dist/migrations/add-token-tracking.d.ts.map +1 -0
  59. package/dist/migrations/add-token-tracking.js +108 -0
  60. package/dist/migrations/add-token-tracking.js.map +1 -0
  61. package/dist/migrations/add-v3.5.0-pruned-files.d.ts +26 -0
  62. package/dist/migrations/add-v3.5.0-pruned-files.d.ts.map +1 -0
  63. package/dist/migrations/add-v3.5.0-pruned-files.js +107 -0
  64. package/dist/migrations/add-v3.5.0-pruned-files.js.map +1 -0
  65. package/dist/migrations/index.d.ts +26 -12
  66. package/dist/migrations/index.d.ts.map +1 -1
  67. package/dist/migrations/index.js +162 -20
  68. package/dist/migrations/index.js.map +1 -1
  69. package/dist/migrations/knex/20251025020452_create_master_tables.d.ts +4 -0
  70. package/dist/migrations/knex/20251025020452_create_master_tables.d.ts.map +1 -0
  71. package/dist/migrations/knex/20251025020452_create_master_tables.js +65 -0
  72. package/dist/migrations/knex/20251025020452_create_master_tables.js.map +1 -0
  73. package/dist/migrations/knex/20251025021152_create_transaction_tables.d.ts +4 -0
  74. package/dist/migrations/knex/20251025021152_create_transaction_tables.d.ts.map +1 -0
  75. package/dist/migrations/knex/20251025021152_create_transaction_tables.js +235 -0
  76. package/dist/migrations/knex/20251025021152_create_transaction_tables.js.map +1 -0
  77. package/dist/migrations/knex/20251025021351_create_indexes.d.ts +4 -0
  78. package/dist/migrations/knex/20251025021351_create_indexes.d.ts.map +1 -0
  79. package/dist/migrations/knex/20251025021351_create_indexes.js +62 -0
  80. package/dist/migrations/knex/20251025021351_create_indexes.js.map +1 -0
  81. package/dist/migrations/knex/20251025021416_seed_master_data.d.ts +4 -0
  82. package/dist/migrations/knex/20251025021416_seed_master_data.d.ts.map +1 -0
  83. package/dist/migrations/knex/20251025021416_seed_master_data.js +58 -0
  84. package/dist/migrations/knex/20251025021416_seed_master_data.js.map +1 -0
  85. package/dist/migrations/knex/20251025070349_create_views.d.ts +4 -0
  86. package/dist/migrations/knex/20251025070349_create_views.d.ts.map +1 -0
  87. package/dist/migrations/knex/20251025070349_create_views.js +143 -0
  88. package/dist/migrations/knex/20251025070349_create_views.js.map +1 -0
  89. package/dist/migrations/knex/20251025081221_add_link_type_to_task_decision_links.d.ts +4 -0
  90. package/dist/migrations/knex/20251025081221_add_link_type_to_task_decision_links.d.ts.map +1 -0
  91. package/dist/migrations/knex/20251025081221_add_link_type_to_task_decision_links.js +15 -0
  92. package/dist/migrations/knex/20251025081221_add_link_type_to_task_decision_links.js.map +1 -0
  93. package/dist/migrations/knex/20251025082220_fix_task_dependencies_columns.d.ts +8 -0
  94. package/dist/migrations/knex/20251025082220_fix_task_dependencies_columns.d.ts.map +1 -0
  95. package/dist/migrations/knex/20251025082220_fix_task_dependencies_columns.js +12 -0
  96. package/dist/migrations/knex/20251025082220_fix_task_dependencies_columns.js.map +1 -0
  97. package/dist/migrations/knex/20251025090000_create_help_system_tables.d.ts +19 -0
  98. package/dist/migrations/knex/20251025090000_create_help_system_tables.d.ts.map +1 -0
  99. package/dist/migrations/knex/20251025090000_create_help_system_tables.js +115 -0
  100. package/dist/migrations/knex/20251025090000_create_help_system_tables.js.map +1 -0
  101. package/dist/migrations/knex/20251025090100_seed_help_categories_and_use_cases.d.ts +13 -0
  102. package/dist/migrations/knex/20251025090100_seed_help_categories_and_use_cases.d.ts.map +1 -0
  103. package/dist/migrations/knex/20251025090100_seed_help_categories_and_use_cases.js +377 -0
  104. package/dist/migrations/knex/20251025090100_seed_help_categories_and_use_cases.js.map +1 -0
  105. package/dist/migrations/knex/20251025100000_seed_help_metadata.d.ts +15 -0
  106. package/dist/migrations/knex/20251025100000_seed_help_metadata.d.ts.map +1 -0
  107. package/dist/migrations/knex/20251025100000_seed_help_metadata.js +253 -0
  108. package/dist/migrations/knex/20251025100000_seed_help_metadata.js.map +1 -0
  109. package/dist/migrations/knex/20251025100100_seed_remaining_use_cases.d.ts +16 -0
  110. package/dist/migrations/knex/20251025100100_seed_remaining_use_cases.d.ts.map +1 -0
  111. package/dist/migrations/knex/20251025100100_seed_remaining_use_cases.js +276 -0
  112. package/dist/migrations/knex/20251025100100_seed_remaining_use_cases.js.map +1 -0
  113. package/dist/migrations/knex/20251025120000_add_cascade_to_task_dependencies.d.ts +8 -0
  114. package/dist/migrations/knex/20251025120000_add_cascade_to_task_dependencies.d.ts.map +1 -0
  115. package/dist/migrations/knex/20251025120000_add_cascade_to_task_dependencies.js +64 -0
  116. package/dist/migrations/knex/20251025120000_add_cascade_to_task_dependencies.js.map +1 -0
  117. package/dist/migrations/seed-help-data.d.ts +48 -0
  118. package/dist/migrations/seed-help-data.d.ts.map +1 -0
  119. package/dist/migrations/seed-help-data.js +1466 -0
  120. package/dist/migrations/seed-help-data.js.map +1 -0
  121. package/dist/migrations/seed-tool-metadata.d.ts +24 -0
  122. package/dist/migrations/seed-tool-metadata.d.ts.map +1 -0
  123. package/dist/migrations/seed-tool-metadata.js +392 -0
  124. package/dist/migrations/seed-tool-metadata.js.map +1 -0
  125. package/dist/migrations/v3.6.0-help-system-refactor.d.ts +46 -0
  126. package/dist/migrations/v3.6.0-help-system-refactor.d.ts.map +1 -0
  127. package/dist/migrations/v3.6.0-help-system-refactor.js +223 -0
  128. package/dist/migrations/v3.6.0-help-system-refactor.js.map +1 -0
  129. package/dist/schema.d.ts.map +1 -1
  130. package/dist/schema.js +2 -0
  131. package/dist/schema.js.map +1 -1
  132. package/dist/tests/git-aware-completion.test.d.ts +6 -0
  133. package/dist/tests/git-aware-completion.test.d.ts.map +1 -0
  134. package/dist/tests/git-aware-completion.test.js +160 -0
  135. package/dist/tests/git-aware-completion.test.js.map +1 -0
  136. package/dist/tests/help-system.test.d.ts +23 -0
  137. package/dist/tests/help-system.test.d.ts.map +1 -0
  138. package/dist/tests/help-system.test.js +374 -0
  139. package/dist/tests/help-system.test.js.map +1 -0
  140. package/dist/tests/tasks.auto-pruning-decision-link.test.d.ts +6 -0
  141. package/dist/tests/tasks.auto-pruning-decision-link.test.d.ts.map +1 -0
  142. package/dist/tests/tasks.auto-pruning-decision-link.test.js +264 -0
  143. package/dist/tests/tasks.auto-pruning-decision-link.test.js.map +1 -0
  144. package/dist/tests/tasks.auto-pruning-partial.test.d.ts +6 -0
  145. package/dist/tests/tasks.auto-pruning-partial.test.d.ts.map +1 -0
  146. package/dist/tests/tasks.auto-pruning-partial.test.js +285 -0
  147. package/dist/tests/tasks.auto-pruning-partial.test.js.map +1 -0
  148. package/dist/tests/tasks.auto-pruning-persistence.test.d.ts +6 -0
  149. package/dist/tests/tasks.auto-pruning-persistence.test.d.ts.map +1 -0
  150. package/dist/tests/tasks.auto-pruning-persistence.test.js +250 -0
  151. package/dist/tests/tasks.auto-pruning-persistence.test.js.map +1 -0
  152. package/dist/tests/tasks.auto-pruning-safety.test.d.ts +12 -0
  153. package/dist/tests/tasks.auto-pruning-safety.test.d.ts.map +1 -0
  154. package/dist/tests/tasks.auto-pruning-safety.test.js +217 -0
  155. package/dist/tests/tasks.auto-pruning-safety.test.js.map +1 -0
  156. package/dist/tests/tasks.dependencies.test.js +338 -307
  157. package/dist/tests/tasks.dependencies.test.js.map +1 -1
  158. package/dist/tests/tasks.link-file-backward-compat.test.d.ts +6 -0
  159. package/dist/tests/tasks.link-file-backward-compat.test.d.ts.map +1 -0
  160. package/dist/tests/tasks.link-file-backward-compat.test.js +247 -0
  161. package/dist/tests/tasks.link-file-backward-compat.test.js.map +1 -0
  162. package/dist/tests/tasks.watch-files-action.test.d.ts +6 -0
  163. package/dist/tests/tasks.watch-files-action.test.d.ts.map +1 -0
  164. package/dist/tests/tasks.watch-files-action.test.js +372 -0
  165. package/dist/tests/tasks.watch-files-action.test.js.map +1 -0
  166. package/dist/tests/tasks.watch-files-parameter.test.d.ts +6 -0
  167. package/dist/tests/tasks.watch-files-parameter.test.d.ts.map +1 -0
  168. package/dist/tests/tasks.watch-files-parameter.test.js +260 -0
  169. package/dist/tests/tasks.watch-files-parameter.test.js.map +1 -0
  170. package/dist/tests/two-step-git-completion.test.d.ts +6 -0
  171. package/dist/tests/two-step-git-completion.test.d.ts.map +1 -0
  172. package/dist/tests/two-step-git-completion.test.js +326 -0
  173. package/dist/tests/two-step-git-completion.test.js.map +1 -0
  174. package/dist/tests/vcs-staging.test.d.ts +6 -0
  175. package/dist/tests/vcs-staging.test.d.ts.map +1 -0
  176. package/dist/tests/vcs-staging.test.js +137 -0
  177. package/dist/tests/vcs-staging.test.js.map +1 -0
  178. package/dist/tools/config.d.ts +9 -4
  179. package/dist/tools/config.d.ts.map +1 -1
  180. package/dist/tools/config.js +16 -12
  181. package/dist/tools/config.js.map +1 -1
  182. package/dist/tools/constraints.d.ts +9 -3
  183. package/dist/tools/constraints.d.ts.map +1 -1
  184. package/dist/tools/constraints.js +66 -45
  185. package/dist/tools/constraints.js.map +1 -1
  186. package/dist/tools/context.d.ts +35 -16
  187. package/dist/tools/context.d.ts.map +1 -1
  188. package/dist/tools/context.js +374 -314
  189. package/dist/tools/context.js.map +1 -1
  190. package/dist/tools/files.d.ts +11 -4
  191. package/dist/tools/files.d.ts.map +1 -1
  192. package/dist/tools/files.js +173 -91
  193. package/dist/tools/files.js.map +1 -1
  194. package/dist/tools/help-queries.d.ts +130 -0
  195. package/dist/tools/help-queries.d.ts.map +1 -0
  196. package/dist/tools/help-queries.js +393 -0
  197. package/dist/tools/help-queries.js.map +1 -0
  198. package/dist/tools/messaging.d.ts +13 -6
  199. package/dist/tools/messaging.d.ts.map +1 -1
  200. package/dist/tools/messaging.js +217 -129
  201. package/dist/tools/messaging.js.map +1 -1
  202. package/dist/tools/tasks.d.ts +42 -12
  203. package/dist/tools/tasks.d.ts.map +1 -1
  204. package/dist/tools/tasks.js +809 -347
  205. package/dist/tools/tasks.js.map +1 -1
  206. package/dist/tools/utils.d.ts +13 -5
  207. package/dist/tools/utils.d.ts.map +1 -1
  208. package/dist/tools/utils.js +92 -115
  209. package/dist/tools/utils.js.map +1 -1
  210. package/dist/types.d.ts +4 -0
  211. package/dist/types.d.ts.map +1 -1
  212. package/dist/utils/activity-logging.d.ts +114 -0
  213. package/dist/utils/activity-logging.d.ts.map +1 -0
  214. package/dist/utils/activity-logging.js +162 -0
  215. package/dist/utils/activity-logging.js.map +1 -0
  216. package/dist/utils/batch.d.ts +2 -2
  217. package/dist/utils/batch.d.ts.map +1 -1
  218. package/dist/utils/batch.js +8 -8
  219. package/dist/utils/batch.js.map +1 -1
  220. package/dist/utils/cleanup.d.ts +21 -13
  221. package/dist/utils/cleanup.d.ts.map +1 -1
  222. package/dist/utils/cleanup.js +31 -24
  223. package/dist/utils/cleanup.js.map +1 -1
  224. package/dist/utils/debug-logger.d.ts +44 -0
  225. package/dist/utils/debug-logger.d.ts.map +1 -0
  226. package/dist/utils/debug-logger.js +116 -0
  227. package/dist/utils/debug-logger.js.map +1 -0
  228. package/dist/utils/file-pruning.d.ts +69 -0
  229. package/dist/utils/file-pruning.d.ts.map +1 -0
  230. package/dist/utils/file-pruning.js +185 -0
  231. package/dist/utils/file-pruning.js.map +1 -0
  232. package/dist/utils/help-tracking.d.ts +55 -0
  233. package/dist/utils/help-tracking.d.ts.map +1 -0
  234. package/dist/utils/help-tracking.js +88 -0
  235. package/dist/utils/help-tracking.js.map +1 -0
  236. package/dist/utils/quality-checks.d.ts +60 -0
  237. package/dist/utils/quality-checks.d.ts.map +1 -0
  238. package/dist/utils/quality-checks.js +228 -0
  239. package/dist/utils/quality-checks.js.map +1 -0
  240. package/dist/utils/retention.d.ts +13 -5
  241. package/dist/utils/retention.d.ts.map +1 -1
  242. package/dist/utils/retention.js +20 -8
  243. package/dist/utils/retention.js.map +1 -1
  244. package/dist/utils/task-stale-detection.d.ts +77 -7
  245. package/dist/utils/task-stale-detection.d.ts.map +1 -1
  246. package/dist/utils/task-stale-detection.js +309 -34
  247. package/dist/utils/task-stale-detection.js.map +1 -1
  248. package/dist/utils/token-estimation.d.ts +72 -0
  249. package/dist/utils/token-estimation.d.ts.map +1 -0
  250. package/dist/utils/token-estimation.js +71 -0
  251. package/dist/utils/token-estimation.js.map +1 -0
  252. package/dist/utils/token-logging.d.ts +48 -0
  253. package/dist/utils/token-logging.d.ts.map +1 -0
  254. package/dist/utils/token-logging.js +112 -0
  255. package/dist/utils/token-logging.js.map +1 -0
  256. package/dist/utils/vcs-adapter.d.ts +68 -0
  257. package/dist/utils/vcs-adapter.d.ts.map +1 -0
  258. package/dist/utils/vcs-adapter.js +187 -0
  259. package/dist/utils/vcs-adapter.js.map +1 -0
  260. package/dist/utils/view-queries.d.ts +34 -0
  261. package/dist/utils/view-queries.d.ts.map +1 -0
  262. package/dist/utils/view-queries.js +192 -0
  263. package/dist/utils/view-queries.js.map +1 -0
  264. package/dist/watcher/file-watcher.d.ts +54 -4
  265. package/dist/watcher/file-watcher.d.ts.map +1 -1
  266. package/dist/watcher/file-watcher.js +329 -33
  267. package/dist/watcher/file-watcher.js.map +1 -1
  268. package/dist/watcher/gitignore-parser.d.ts +70 -0
  269. package/dist/watcher/gitignore-parser.d.ts.map +1 -0
  270. package/dist/watcher/gitignore-parser.js +191 -0
  271. package/dist/watcher/gitignore-parser.js.map +1 -0
  272. package/dist/watcher/index.d.ts +1 -0
  273. package/dist/watcher/index.d.ts.map +1 -1
  274. package/dist/watcher/index.js +1 -0
  275. package/dist/watcher/index.js.map +1 -1
  276. package/docs/AI_AGENT_GUIDE.md +1 -1
  277. package/docs/ARCHITECTURE.md +12 -0
  278. package/docs/AUTO_FILE_TRACKING.md +486 -82
  279. package/docs/BEST_PRACTICES.md +56 -448
  280. package/docs/CONFIGURATION.md +908 -0
  281. package/docs/GIT_AWARE_AUTO_COMPLETE.md +645 -0
  282. package/docs/MIGRATION_v3.3.md +602 -0
  283. package/docs/MIGRATION_v3.6.0.md +170 -0
  284. package/docs/SHARED_CONCEPTS.md +65 -209
  285. package/docs/TASK_ACTIONS.md +12 -0
  286. package/docs/TASK_OVERVIEW.md +125 -24
  287. package/docs/TASK_PRUNING.md +589 -0
  288. package/docs/TASK_SYSTEM.md +83 -13
  289. package/docs/TOOL_REFERENCE.md +94 -6
  290. package/docs/TOOL_SELECTION.md +41 -248
  291. package/package.json +21 -7
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Integration tests for v3.5.0 Auto-Pruning Safety Check
3
+ * Tests that the system blocks task transition when ALL watched files are non-existent
4
+ *
5
+ * Test Scenario: Zero Work Done Protection
6
+ * - Create task with 3 watched files
7
+ * - Make ALL 3 files non-existent
8
+ * - Trigger detectAndTransitionToReview()
9
+ * - Expected: Error thrown, task status unchanged, transaction rolled back
10
+ */
11
+ import { describe, it, beforeEach, afterEach } from 'node:test';
12
+ import * as assert from 'node:assert/strict';
13
+ import { initializeDatabase, closeDatabase } from '../database.js';
14
+ import { detectAndTransitionToReview } from '../utils/task-stale-detection.js';
15
+ describe('Auto-pruning: Safety check when all files pruned', () => {
16
+ let db;
17
+ beforeEach(async () => {
18
+ db = await initializeDatabase({
19
+ databaseType: 'sqlite',
20
+ connection: { filename: ':memory:' }
21
+ });
22
+ });
23
+ afterEach(async () => {
24
+ await closeDatabase();
25
+ });
26
+ it('should block transition when all watched files are non-existent', async () => {
27
+ const knex = db.getKnex();
28
+ // 1. Create test task in 'in_progress' status
29
+ const taskId = await createTestTask(db);
30
+ // 2. Add 3 non-existent files to watch list
31
+ // Using paths that will never exist in the test environment
32
+ const nonExistentFiles = [
33
+ '/tmp/never-created-file-1.ts',
34
+ '/tmp/never-created-file-2.ts',
35
+ '/tmp/never-created-file-3.ts'
36
+ ];
37
+ await addWatchedFiles(db, taskId, nonExistentFiles);
38
+ // 3. Make task appear "stale" by backdating its updated_ts
39
+ // Set updated_ts to 10 minutes ago (older than default 3-minute idle threshold)
40
+ const tenMinutesAgo = Math.floor(Date.now() / 1000) - (10 * 60);
41
+ await knex('t_tasks')
42
+ .where({ id: taskId })
43
+ .update({ updated_ts: tenMinutesAgo });
44
+ // 4. Verify task is in 'in_progress' before attempt
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();
50
+ assert.strictEqual(beforeStatus.name, 'in_progress', 'Task should start in in_progress');
51
+ // 5. Verify watch list has all 3 files before attempt
52
+ const beforeWatchCount = await knex('t_task_file_links')
53
+ .where({ task_id: taskId })
54
+ .count('* as count')
55
+ .first();
56
+ assert.strictEqual(beforeWatchCount.count, 3, 'Watch list should have 3 files before pruning attempt');
57
+ // 6. Attempt transition - should NOT throw at top level
58
+ // The error should be caught internally and logged
59
+ // Task should remain in in_progress without transitioning
60
+ const transitioned = await detectAndTransitionToReview(db);
61
+ // 7. Verify zero tasks were transitioned
62
+ assert.strictEqual(transitioned, 0, 'No tasks should have been transitioned');
63
+ // 8. Verify task status unchanged (remains in in_progress)
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();
69
+ assert.strictEqual(afterStatus.name, 'in_progress', 'Task should remain in in_progress after safety check');
70
+ // 9. Verify NO audit records created (transaction rollback)
71
+ const prunedCount = await knex('t_task_pruned_files')
72
+ .where({ task_id: taskId })
73
+ .count('* as count')
74
+ .first();
75
+ assert.strictEqual(prunedCount.count, 0, 'Should have no pruned file records due to rollback');
76
+ // 10. Verify watch list is NOT empty (transaction rolled back)
77
+ const afterWatchCount = await knex('t_task_file_links')
78
+ .where({ task_id: taskId })
79
+ .count('* as count')
80
+ .first();
81
+ assert.strictEqual(afterWatchCount.count, 3, 'Watch list should still have all 3 files after rollback');
82
+ });
83
+ it('should prune SOME non-existent files and continue (partial prune)', async () => {
84
+ const knex = db.getKnex();
85
+ // Create task
86
+ const taskId = await createTestTask(db);
87
+ // Add mix of existent and non-existent files
88
+ // Use package.json as a file that definitely exists in the project root
89
+ const mixedFiles = [
90
+ 'package.json', // exists
91
+ '/tmp/never-created-file-1.ts', // does not exist
92
+ '/tmp/never-created-file-2.ts' // does not exist
93
+ ];
94
+ await addWatchedFiles(db, taskId, mixedFiles);
95
+ // Make task appear stale
96
+ const tenMinutesAgo = Math.floor(Date.now() / 1000) - (10 * 60);
97
+ await knex('t_tasks')
98
+ .where({ id: taskId })
99
+ .update({ updated_ts: tenMinutesAgo });
100
+ // Verify initial watch count
101
+ const beforeWatchCount = await knex('t_task_file_links')
102
+ .where({ task_id: taskId })
103
+ .count('* as count')
104
+ .first();
105
+ assert.strictEqual(beforeWatchCount.count, 3, 'Watch list should start with 3 files');
106
+ // Attempt transition - should proceed with partial pruning
107
+ await detectAndTransitionToReview(db);
108
+ // Verify some files were pruned
109
+ const prunedCount = await knex('t_task_pruned_files')
110
+ .where({ task_id: taskId })
111
+ .count('* as count')
112
+ .first();
113
+ assert.strictEqual(prunedCount.count, 2, 'Should have 2 pruned file records (the non-existent ones)');
114
+ // Verify watch list now has only 1 file (the existing one)
115
+ const afterWatchCount = await knex('t_task_file_links')
116
+ .where({ task_id: taskId })
117
+ .count('* as count')
118
+ .first();
119
+ assert.strictEqual(afterWatchCount.count, 1, 'Watch list should have 1 remaining file after partial prune');
120
+ // Verify remaining file is package.json
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();
126
+ assert.strictEqual(remainingFile.path, 'package.json', 'Remaining file should be package.json');
127
+ });
128
+ it('should handle task with no watched files gracefully', async () => {
129
+ const knex = db.getKnex();
130
+ // Create task without any watched files
131
+ const taskId = await createTestTask(db);
132
+ // Make task appear stale
133
+ const tenMinutesAgo = Math.floor(Date.now() / 1000) - (10 * 60);
134
+ await knex('t_tasks')
135
+ .where({ id: taskId })
136
+ .update({ updated_ts: tenMinutesAgo });
137
+ // Attempt transition - should skip this task
138
+ const transitioned = await detectAndTransitionToReview(db);
139
+ assert.strictEqual(transitioned, 0, 'Should not transition task with no watched files');
140
+ // Verify task status unchanged
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();
146
+ assert.strictEqual(status.name, 'in_progress', 'Task should remain in in_progress');
147
+ });
148
+ console.log('\n✅ All auto-pruning safety check tests passed!\n');
149
+ });
150
+ /**
151
+ * Helper: Create a test task in 'in_progress' status
152
+ */
153
+ async function createTestTask(db) {
154
+ const knex = db.getKnex();
155
+ // Create 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
+ }
173
+ // Get 'in_progress' status ID
174
+ const statusRow = await knex('m_task_statuses')
175
+ .where({ name: 'in_progress' })
176
+ .select('id')
177
+ .first();
178
+ // Create task with updated_ts set to now (will be backdated in tests)
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;
192
+ }
193
+ /**
194
+ * Helper: Add watched files to a task
195
+ */
196
+ async function addWatchedFiles(db, taskId, filePaths) {
197
+ const knex = db.getKnex();
198
+ for (const filePath of filePaths) {
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
+ });
215
+ }
216
+ }
217
+ //# sourceMappingURL=tasks.auto-pruning-safety.test.js.map
@@ -0,0 +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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"}