sqlew 3.6.10 → 3.7.1

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 (372) hide show
  1. package/CHANGELOG.md +346 -0
  2. package/README.md +54 -39
  3. package/assets/config.example.toml +93 -0
  4. package/assets/kanban-visualizer.png +0 -0
  5. package/assets/sample-agents/sqlew-architect.md +32 -13
  6. package/assets/sample-agents/sqlew-researcher.md +70 -17
  7. package/assets/sample-agents/sqlew-scrum-master.md +60 -25
  8. package/assets/schema.sql +2 -2
  9. package/dist/adapters/auth/auth-factory.d.ts +86 -0
  10. package/dist/adapters/auth/auth-factory.d.ts.map +1 -0
  11. package/dist/adapters/auth/auth-factory.js +103 -0
  12. package/dist/adapters/auth/auth-factory.js.map +1 -0
  13. package/dist/adapters/auth/auth-types.d.ts +30 -0
  14. package/dist/adapters/auth/auth-types.d.ts.map +1 -0
  15. package/dist/adapters/auth/auth-types.js +30 -0
  16. package/dist/adapters/auth/auth-types.js.map +1 -0
  17. package/dist/adapters/auth/base-auth-provider.d.ts +327 -0
  18. package/dist/adapters/auth/base-auth-provider.d.ts.map +1 -0
  19. package/dist/adapters/auth/base-auth-provider.js +111 -0
  20. package/dist/adapters/auth/base-auth-provider.js.map +1 -0
  21. package/dist/adapters/auth/direct-auth-provider.d.ts +356 -0
  22. package/dist/adapters/auth/direct-auth-provider.d.ts.map +1 -0
  23. package/dist/adapters/auth/direct-auth-provider.js +406 -0
  24. package/dist/adapters/auth/direct-auth-provider.js.map +1 -0
  25. package/dist/adapters/base-adapter.d.ts +638 -0
  26. package/dist/adapters/base-adapter.d.ts.map +1 -0
  27. package/dist/adapters/base-adapter.js +557 -0
  28. package/dist/adapters/base-adapter.js.map +1 -0
  29. package/dist/adapters/index.d.ts +13 -2
  30. package/dist/adapters/index.d.ts.map +1 -1
  31. package/dist/adapters/index.js +27 -5
  32. package/dist/adapters/index.js.map +1 -1
  33. package/dist/adapters/mysql-adapter.d.ts +547 -6
  34. package/dist/adapters/mysql-adapter.d.ts.map +1 -1
  35. package/dist/adapters/mysql-adapter.js +651 -32
  36. package/dist/adapters/mysql-adapter.js.map +1 -1
  37. package/dist/adapters/postgresql-adapter.d.ts +15 -4
  38. package/dist/adapters/postgresql-adapter.d.ts.map +1 -1
  39. package/dist/adapters/postgresql-adapter.js +19 -2
  40. package/dist/adapters/postgresql-adapter.js.map +1 -1
  41. package/dist/adapters/sqlite-adapter.d.ts +35 -5
  42. package/dist/adapters/sqlite-adapter.d.ts.map +1 -1
  43. package/dist/adapters/sqlite-adapter.js +57 -18
  44. package/dist/adapters/sqlite-adapter.js.map +1 -1
  45. package/dist/cli/db-dump.d.ts +32 -0
  46. package/dist/cli/db-dump.d.ts.map +1 -0
  47. package/dist/cli/db-dump.js +409 -0
  48. package/dist/cli/db-dump.js.map +1 -0
  49. package/dist/cli.js +24 -14
  50. package/dist/cli.js.map +1 -1
  51. package/dist/config/knex/bootstrap/20251025020452_create_master_tables.d.ts.map +1 -0
  52. package/dist/{migrations → config}/knex/bootstrap/20251025020452_create_master_tables.js +7 -2
  53. package/dist/config/knex/bootstrap/20251025020452_create_master_tables.js.map +1 -0
  54. package/dist/config/knex/bootstrap/20251025021152_create_transaction_tables.d.ts.map +1 -0
  55. package/dist/{migrations → config}/knex/bootstrap/20251025021152_create_transaction_tables.js +49 -50
  56. package/dist/config/knex/bootstrap/20251025021152_create_transaction_tables.js.map +1 -0
  57. package/dist/config/knex/bootstrap/20251025021351_create_indexes.d.ts.map +1 -0
  58. package/dist/config/knex/bootstrap/20251025021351_create_indexes.js.map +1 -0
  59. package/dist/config/knex/bootstrap/20251025021416_seed_master_data.d.ts.map +1 -0
  60. package/dist/{migrations → config}/knex/bootstrap/20251025021416_seed_master_data.js +11 -6
  61. package/dist/config/knex/bootstrap/20251025021416_seed_master_data.js.map +1 -0
  62. package/dist/config/knex/bootstrap/20251025070349_create_views.d.ts.map +1 -0
  63. package/dist/{migrations → config}/knex/bootstrap/20251025070349_create_views.js +66 -14
  64. package/dist/config/knex/bootstrap/20251025070349_create_views.js.map +1 -0
  65. package/dist/config/knex/enhancements/20251025081221_add_link_type_to_task_decision_links.d.ts.map +1 -0
  66. package/dist/config/knex/enhancements/20251025081221_add_link_type_to_task_decision_links.js +22 -0
  67. package/dist/config/knex/enhancements/20251025081221_add_link_type_to_task_decision_links.js.map +1 -0
  68. package/dist/config/knex/enhancements/20251025082220_fix_task_dependencies_columns.d.ts.map +1 -0
  69. package/dist/config/knex/enhancements/20251025082220_fix_task_dependencies_columns.js.map +1 -0
  70. package/dist/config/knex/enhancements/20251025090000_create_help_system_tables.d.ts.map +1 -0
  71. package/dist/{migrations → config}/knex/enhancements/20251025090000_create_help_system_tables.js +6 -0
  72. package/dist/config/knex/enhancements/20251025090000_create_help_system_tables.js.map +1 -0
  73. package/dist/config/knex/enhancements/20251025090100_seed_help_categories_and_use_cases.d.ts.map +1 -0
  74. package/dist/{migrations → config}/knex/enhancements/20251025090100_seed_help_categories_and_use_cases.js +6 -0
  75. package/dist/config/knex/enhancements/20251025090100_seed_help_categories_and_use_cases.js.map +1 -0
  76. package/dist/config/knex/enhancements/20251025100000_seed_help_metadata.d.ts.map +1 -0
  77. package/dist/{migrations → config}/knex/enhancements/20251025100000_seed_help_metadata.js +6 -0
  78. package/dist/config/knex/enhancements/20251025100000_seed_help_metadata.js.map +1 -0
  79. package/dist/config/knex/enhancements/20251025100100_seed_remaining_use_cases.d.ts.map +1 -0
  80. package/dist/config/knex/enhancements/20251025100100_seed_remaining_use_cases.js.map +1 -0
  81. package/dist/config/knex/enhancements/20251025120000_add_cascade_to_task_dependencies.d.ts.map +1 -0
  82. package/dist/{migrations → config}/knex/enhancements/20251025120000_add_cascade_to_task_dependencies.js +7 -0
  83. package/dist/config/knex/enhancements/20251025120000_add_cascade_to_task_dependencies.js.map +1 -0
  84. package/dist/config/knex/enhancements/20251027000000_add_agent_reuse_system.d.ts.map +1 -0
  85. package/dist/config/knex/enhancements/20251027000000_add_agent_reuse_system.js +62 -0
  86. package/dist/config/knex/enhancements/20251027000000_add_agent_reuse_system.js.map +1 -0
  87. package/dist/config/knex/enhancements/20251027010000_add_task_constraint_to_decision_context.d.ts.map +1 -0
  88. package/dist/config/knex/enhancements/20251027010000_add_task_constraint_to_decision_context.js.map +1 -0
  89. package/dist/config/knex/enhancements/20251027020000_update_agent_reusability.d.ts.map +1 -0
  90. package/dist/{migrations → config}/knex/enhancements/20251027020000_update_agent_reusability.js +6 -0
  91. package/dist/config/knex/enhancements/20251027020000_update_agent_reusability.js.map +1 -0
  92. package/dist/config/knex/enhancements/20251028000000_simplify_agent_system.d.ts.map +1 -0
  93. package/dist/{migrations → config}/knex/enhancements/20251028000000_simplify_agent_system.js +6 -0
  94. package/dist/config/knex/enhancements/20251028000000_simplify_agent_system.js.map +1 -0
  95. package/dist/config/knex/enhancements/20251031000000_drop_orphaned_message_view.d.ts +13 -0
  96. package/dist/config/knex/enhancements/20251031000000_drop_orphaned_message_view.d.ts.map +1 -0
  97. package/dist/config/knex/enhancements/20251031000000_drop_orphaned_message_view.js +48 -0
  98. package/dist/config/knex/enhancements/20251031000000_drop_orphaned_message_view.js.map +1 -0
  99. package/dist/config/knex/enhancements/20251104000003_rename_constraints_created_by_to_agent_id.d.ts +24 -0
  100. package/dist/config/knex/enhancements/20251104000003_rename_constraints_created_by_to_agent_id.d.ts.map +1 -0
  101. package/dist/config/knex/enhancements/20251104000003_rename_constraints_created_by_to_agent_id.js +189 -0
  102. package/dist/config/knex/enhancements/20251104000003_rename_constraints_created_by_to_agent_id.js.map +1 -0
  103. package/dist/config/knex/enhancements/20251105000000_add_token_usage_table.d.ts +16 -0
  104. package/dist/config/knex/enhancements/20251105000000_add_token_usage_table.d.ts.map +1 -0
  105. package/dist/config/knex/enhancements/20251105000000_add_token_usage_table.js +65 -0
  106. package/dist/config/knex/enhancements/20251105000000_add_token_usage_table.js.map +1 -0
  107. package/dist/config/knex/enhancements/20251105000001_rename_decision_context_decided_by_to_agent_id.d.ts +23 -0
  108. package/dist/config/knex/enhancements/20251105000001_rename_decision_context_decided_by_to_agent_id.d.ts.map +1 -0
  109. package/dist/config/knex/enhancements/20251105000001_rename_decision_context_decided_by_to_agent_id.js +118 -0
  110. package/dist/config/knex/enhancements/20251105000001_rename_decision_context_decided_by_to_agent_id.js.map +1 -0
  111. package/dist/config/knex/upgrades/20251024010000_upgrade_v1_0_to_v1_1.d.ts.map +1 -0
  112. package/dist/config/knex/upgrades/20251024010000_upgrade_v1_0_to_v1_1.js.map +1 -0
  113. package/dist/config/knex/upgrades/20251024020000_upgrade_v2_0_to_v2_1.d.ts.map +1 -0
  114. package/dist/config/knex/upgrades/20251024020000_upgrade_v2_0_to_v2_1.js.map +1 -0
  115. package/dist/config/knex/upgrades/20251024030000_upgrade_v2_1_to_v3_0.d.ts.map +1 -0
  116. package/dist/config/knex/upgrades/20251024030000_upgrade_v2_1_to_v3_0.js.map +1 -0
  117. package/dist/config/knex/upgrades/20251024040000_upgrade_v3_0_to_v3_2.d.ts.map +1 -0
  118. package/dist/config/knex/upgrades/20251024040000_upgrade_v3_0_to_v3_2.js.map +1 -0
  119. package/dist/config/knex/upgrades/20251024050000_upgrade_v3_2_0_to_v3_2_2.d.ts.map +1 -0
  120. package/dist/config/knex/upgrades/20251024050000_upgrade_v3_2_0_to_v3_2_2.js.map +1 -0
  121. package/dist/config/knex/upgrades/20251024060000_upgrade_v3_4_to_v3_5.d.ts.map +1 -0
  122. package/dist/config/knex/upgrades/20251024060000_upgrade_v3_4_to_v3_5.js.map +1 -0
  123. package/dist/config/knex/upgrades/20251024070000_upgrade_v3_5_to_v3_6.d.ts.map +1 -0
  124. package/dist/config/knex/upgrades/20251024070000_upgrade_v3_5_to_v3_6.js.map +1 -0
  125. package/dist/config/knex/upgrades/20251104000000_add_multi_project_v3_7_0.d.ts +49 -0
  126. package/dist/config/knex/upgrades/20251104000000_add_multi_project_v3_7_0.d.ts.map +1 -0
  127. package/dist/config/knex/upgrades/20251104000000_add_multi_project_v3_7_0.js +864 -0
  128. package/dist/config/knex/upgrades/20251104000000_add_multi_project_v3_7_0.js.map +1 -0
  129. package/dist/config/loader.d.ts +19 -1
  130. package/dist/config/loader.d.ts.map +1 -1
  131. package/dist/config/loader.js +149 -4
  132. package/dist/config/loader.js.map +1 -1
  133. package/dist/config/types.d.ts +261 -2
  134. package/dist/config/types.d.ts.map +1 -1
  135. package/dist/config/types.js.map +1 -1
  136. package/dist/config/writer.d.ts +65 -0
  137. package/dist/config/writer.d.ts.map +1 -0
  138. package/dist/config/writer.js +139 -0
  139. package/dist/config/writer.js.map +1 -0
  140. package/dist/database.d.ts +11 -2
  141. package/dist/database.d.ts.map +1 -1
  142. package/dist/database.js +62 -6
  143. package/dist/database.js.map +1 -1
  144. package/dist/index.js +173 -39
  145. package/dist/index.js.map +1 -1
  146. package/dist/knexfile.d.ts.map +1 -1
  147. package/dist/knexfile.js +88 -12
  148. package/dist/knexfile.js.map +1 -1
  149. package/dist/tests/all-features.test.js +15 -3
  150. package/dist/tests/all-features.test.js.map +1 -1
  151. package/dist/tests/config-loader.test.d.ts +6 -0
  152. package/dist/tests/config-loader.test.d.ts.map +1 -0
  153. package/dist/tests/config-loader.test.js +201 -0
  154. package/dist/tests/config-loader.test.js.map +1 -0
  155. package/dist/tests/connection-manager-integration.test.d.ts +2 -0
  156. package/dist/tests/connection-manager-integration.test.d.ts.map +1 -0
  157. package/dist/tests/connection-manager-integration.test.js +431 -0
  158. package/dist/tests/connection-manager-integration.test.js.map +1 -0
  159. package/dist/tests/connection-manager.test.d.ts +2 -0
  160. package/dist/tests/connection-manager.test.d.ts.map +1 -0
  161. package/dist/tests/connection-manager.test.js +361 -0
  162. package/dist/tests/connection-manager.test.js.map +1 -0
  163. package/dist/tests/dump-import.test.d.ts +15 -0
  164. package/dist/tests/dump-import.test.d.ts.map +1 -0
  165. package/dist/tests/dump-import.test.js +430 -0
  166. package/dist/tests/dump-import.test.js.map +1 -0
  167. package/dist/tests/migration-idempotency.test.d.ts +2 -0
  168. package/dist/tests/migration-idempotency.test.d.ts.map +1 -0
  169. package/dist/tests/migration-idempotency.test.js +330 -0
  170. package/dist/tests/migration-idempotency.test.js.map +1 -0
  171. package/dist/tests/migration-upgrade-paths.test.d.ts +2 -0
  172. package/dist/tests/migration-upgrade-paths.test.d.ts.map +1 -0
  173. package/dist/tests/migration-upgrade-paths.test.js +248 -0
  174. package/dist/tests/migration-upgrade-paths.test.js.map +1 -0
  175. package/dist/tests/migrations/test-all-versions-real.js +3 -0
  176. package/dist/tests/migrations/test-all-versions-real.js.map +1 -1
  177. package/dist/tests/multi-project-migration.test.d.ts +17 -0
  178. package/dist/tests/multi-project-migration.test.d.ts.map +1 -0
  179. package/dist/tests/multi-project-migration.test.js +399 -0
  180. package/dist/tests/multi-project-migration.test.js.map +1 -0
  181. package/dist/tests/multi-project.test.d.ts +5 -0
  182. package/dist/tests/multi-project.test.d.ts.map +1 -0
  183. package/dist/tests/multi-project.test.js +238 -0
  184. package/dist/tests/multi-project.test.js.map +1 -0
  185. package/dist/tests/schema-migration.test.d.ts +8 -0
  186. package/dist/tests/schema-migration.test.d.ts.map +1 -0
  187. package/dist/tests/schema-migration.test.js +108 -0
  188. package/dist/tests/schema-migration.test.js.map +1 -0
  189. package/dist/tests/sql-dump-converters.test.d.ts +7 -0
  190. package/dist/tests/sql-dump-converters.test.d.ts.map +1 -0
  191. package/dist/tests/sql-dump-converters.test.js +314 -0
  192. package/dist/tests/sql-dump-converters.test.js.map +1 -0
  193. package/dist/tests/sql-dump-cross-database.test.d.ts +21 -0
  194. package/dist/tests/sql-dump-cross-database.test.d.ts.map +1 -0
  195. package/dist/tests/sql-dump-cross-database.test.js +314 -0
  196. package/dist/tests/sql-dump-cross-database.test.js.map +1 -0
  197. package/dist/tests/sql-dump-default-conversions.test.d.ts +8 -0
  198. package/dist/tests/sql-dump-default-conversions.test.d.ts.map +1 -0
  199. package/dist/tests/sql-dump-default-conversions.test.js +141 -0
  200. package/dist/tests/sql-dump-default-conversions.test.js.map +1 -0
  201. package/dist/tests/sql-dump-fk-constraints.test.d.ts +13 -0
  202. package/dist/tests/sql-dump-fk-constraints.test.d.ts.map +1 -0
  203. package/dist/tests/sql-dump-fk-constraints.test.js +381 -0
  204. package/dist/tests/sql-dump-fk-constraints.test.js.map +1 -0
  205. package/dist/tests/sql-dump-indexes.test.d.ts +12 -0
  206. package/dist/tests/sql-dump-indexes.test.d.ts.map +1 -0
  207. package/dist/tests/sql-dump-indexes.test.js +269 -0
  208. package/dist/tests/sql-dump-indexes.test.js.map +1 -0
  209. package/dist/tests/sql-dump-integration.test.d.ts +16 -0
  210. package/dist/tests/sql-dump-integration.test.d.ts.map +1 -0
  211. package/dist/tests/sql-dump-integration.test.js +342 -0
  212. package/dist/tests/sql-dump-integration.test.js.map +1 -0
  213. package/dist/tests/sql-dump-table-ordering.test.d.ts +8 -0
  214. package/dist/tests/sql-dump-table-ordering.test.d.ts.map +1 -0
  215. package/dist/tests/sql-dump-table-ordering.test.js +253 -0
  216. package/dist/tests/sql-dump-table-ordering.test.js.map +1 -0
  217. package/dist/tests/tasks.link-file-backward-compat.test.js +11 -1
  218. package/dist/tests/tasks.link-file-backward-compat.test.js.map +1 -1
  219. package/dist/tests/tasks.watch-files-action.test.js +11 -1
  220. package/dist/tests/tasks.watch-files-action.test.js.map +1 -1
  221. package/dist/tests/type-conversion.test.d.ts +8 -0
  222. package/dist/tests/type-conversion.test.d.ts.map +1 -0
  223. package/dist/tests/type-conversion.test.js +312 -0
  224. package/dist/tests/type-conversion.test.js.map +1 -0
  225. package/dist/tests/utils/test-helpers.d.ts +93 -0
  226. package/dist/tests/utils/test-helpers.d.ts.map +1 -0
  227. package/dist/tests/utils/test-helpers.js +407 -0
  228. package/dist/tests/utils/test-helpers.js.map +1 -0
  229. package/dist/tools/config.d.ts +58 -0
  230. package/dist/tools/config.d.ts.map +1 -0
  231. package/dist/tools/config.js +281 -0
  232. package/dist/tools/config.js.map +1 -0
  233. package/dist/tools/constraints.d.ts.map +1 -1
  234. package/dist/tools/constraints.js +138 -122
  235. package/dist/tools/constraints.js.map +1 -1
  236. package/dist/tools/context.d.ts.map +1 -1
  237. package/dist/tools/context.js +216 -109
  238. package/dist/tools/context.js.map +1 -1
  239. package/dist/tools/files.d.ts.map +1 -1
  240. package/dist/tools/files.js +123 -102
  241. package/dist/tools/files.js.map +1 -1
  242. package/dist/tools/tasks.d.ts.map +1 -1
  243. package/dist/tools/tasks.js +593 -518
  244. package/dist/tools/tasks.js.map +1 -1
  245. package/dist/tools/utils.d.ts +5 -0
  246. package/dist/tools/utils.d.ts.map +1 -1
  247. package/dist/tools/utils.js +176 -122
  248. package/dist/tools/utils.js.map +1 -1
  249. package/dist/types.d.ts +9 -26
  250. package/dist/types.d.ts.map +1 -1
  251. package/dist/utils/cleanup.d.ts +3 -0
  252. package/dist/utils/cleanup.d.ts.map +1 -1
  253. package/dist/utils/cleanup.js +14 -2
  254. package/dist/utils/cleanup.js.map +1 -1
  255. package/dist/utils/connection-manager.d.ts +59 -0
  256. package/dist/utils/connection-manager.d.ts.map +1 -0
  257. package/dist/utils/connection-manager.js +178 -0
  258. package/dist/utils/connection-manager.js.map +1 -0
  259. package/dist/utils/debug-logger.d.ts +8 -4
  260. package/dist/utils/debug-logger.d.ts.map +1 -1
  261. package/dist/utils/debug-logger.js +27 -7
  262. package/dist/utils/debug-logger.js.map +1 -1
  263. package/dist/utils/error-handler.d.ts +6 -4
  264. package/dist/utils/error-handler.d.ts.map +1 -1
  265. package/dist/utils/error-handler.js +34 -9
  266. package/dist/utils/error-handler.js.map +1 -1
  267. package/dist/utils/parameter-validator.d.ts.map +1 -1
  268. package/dist/utils/parameter-validator.js +50 -16
  269. package/dist/utils/parameter-validator.js.map +1 -1
  270. package/dist/utils/project-context.d.ts +111 -0
  271. package/dist/utils/project-context.d.ts.map +1 -0
  272. package/dist/utils/project-context.js +187 -0
  273. package/dist/utils/project-context.js.map +1 -0
  274. package/dist/utils/sql-dump-converters.d.ts +188 -0
  275. package/dist/utils/sql-dump-converters.d.ts.map +1 -0
  276. package/dist/utils/sql-dump-converters.js +311 -0
  277. package/dist/utils/sql-dump-converters.js.map +1 -0
  278. package/dist/utils/sql-dump.d.ts +102 -0
  279. package/dist/utils/sql-dump.d.ts.map +1 -0
  280. package/dist/utils/sql-dump.js +1550 -0
  281. package/dist/utils/sql-dump.js.map +1 -0
  282. package/dist/utils/vcs-adapter.d.ts +42 -0
  283. package/dist/utils/vcs-adapter.d.ts.map +1 -1
  284. package/dist/utils/vcs-adapter.js +154 -0
  285. package/dist/utils/vcs-adapter.js.map +1 -1
  286. package/docs/BASEADAPTER_IMPLEMENTATION.md +399 -0
  287. package/docs/DATABASE_AUTH.md +445 -0
  288. package/docs/DATABASE_MIGRATION.md +247 -0
  289. package/docs/MULTI_PROJECT_ARCHITECTURE.md +497 -0
  290. package/package.json +12 -4
  291. package/dist/migrations/knex/bootstrap/20251025020452_create_master_tables.d.ts.map +0 -1
  292. package/dist/migrations/knex/bootstrap/20251025020452_create_master_tables.js.map +0 -1
  293. package/dist/migrations/knex/bootstrap/20251025021152_create_transaction_tables.d.ts.map +0 -1
  294. package/dist/migrations/knex/bootstrap/20251025021152_create_transaction_tables.js.map +0 -1
  295. package/dist/migrations/knex/bootstrap/20251025021351_create_indexes.d.ts.map +0 -1
  296. package/dist/migrations/knex/bootstrap/20251025021351_create_indexes.js.map +0 -1
  297. package/dist/migrations/knex/bootstrap/20251025021416_seed_master_data.d.ts.map +0 -1
  298. package/dist/migrations/knex/bootstrap/20251025021416_seed_master_data.js.map +0 -1
  299. package/dist/migrations/knex/bootstrap/20251025070349_create_views.d.ts.map +0 -1
  300. package/dist/migrations/knex/bootstrap/20251025070349_create_views.js.map +0 -1
  301. package/dist/migrations/knex/enhancements/20251025081221_add_link_type_to_task_decision_links.d.ts.map +0 -1
  302. package/dist/migrations/knex/enhancements/20251025081221_add_link_type_to_task_decision_links.js +0 -15
  303. package/dist/migrations/knex/enhancements/20251025081221_add_link_type_to_task_decision_links.js.map +0 -1
  304. package/dist/migrations/knex/enhancements/20251025082220_fix_task_dependencies_columns.d.ts.map +0 -1
  305. package/dist/migrations/knex/enhancements/20251025082220_fix_task_dependencies_columns.js.map +0 -1
  306. package/dist/migrations/knex/enhancements/20251025090000_create_help_system_tables.d.ts.map +0 -1
  307. package/dist/migrations/knex/enhancements/20251025090000_create_help_system_tables.js.map +0 -1
  308. package/dist/migrations/knex/enhancements/20251025090100_seed_help_categories_and_use_cases.d.ts.map +0 -1
  309. package/dist/migrations/knex/enhancements/20251025090100_seed_help_categories_and_use_cases.js.map +0 -1
  310. package/dist/migrations/knex/enhancements/20251025100000_seed_help_metadata.d.ts.map +0 -1
  311. package/dist/migrations/knex/enhancements/20251025100000_seed_help_metadata.js.map +0 -1
  312. package/dist/migrations/knex/enhancements/20251025100100_seed_remaining_use_cases.d.ts.map +0 -1
  313. package/dist/migrations/knex/enhancements/20251025100100_seed_remaining_use_cases.js.map +0 -1
  314. package/dist/migrations/knex/enhancements/20251025120000_add_cascade_to_task_dependencies.d.ts.map +0 -1
  315. package/dist/migrations/knex/enhancements/20251025120000_add_cascade_to_task_dependencies.js.map +0 -1
  316. package/dist/migrations/knex/enhancements/20251027000000_add_agent_reuse_system.d.ts.map +0 -1
  317. package/dist/migrations/knex/enhancements/20251027000000_add_agent_reuse_system.js +0 -34
  318. package/dist/migrations/knex/enhancements/20251027000000_add_agent_reuse_system.js.map +0 -1
  319. package/dist/migrations/knex/enhancements/20251027010000_add_task_constraint_to_decision_context.d.ts.map +0 -1
  320. package/dist/migrations/knex/enhancements/20251027010000_add_task_constraint_to_decision_context.js.map +0 -1
  321. package/dist/migrations/knex/enhancements/20251027020000_update_agent_reusability.d.ts.map +0 -1
  322. package/dist/migrations/knex/enhancements/20251027020000_update_agent_reusability.js.map +0 -1
  323. package/dist/migrations/knex/enhancements/20251028000000_simplify_agent_system.d.ts.map +0 -1
  324. package/dist/migrations/knex/enhancements/20251028000000_simplify_agent_system.js.map +0 -1
  325. package/dist/migrations/knex/upgrades/20251024010000_upgrade_v1_0_to_v1_1.d.ts.map +0 -1
  326. package/dist/migrations/knex/upgrades/20251024010000_upgrade_v1_0_to_v1_1.js.map +0 -1
  327. package/dist/migrations/knex/upgrades/20251024020000_upgrade_v2_0_to_v2_1.d.ts.map +0 -1
  328. package/dist/migrations/knex/upgrades/20251024020000_upgrade_v2_0_to_v2_1.js.map +0 -1
  329. package/dist/migrations/knex/upgrades/20251024030000_upgrade_v2_1_to_v3_0.d.ts.map +0 -1
  330. package/dist/migrations/knex/upgrades/20251024030000_upgrade_v2_1_to_v3_0.js.map +0 -1
  331. package/dist/migrations/knex/upgrades/20251024040000_upgrade_v3_0_to_v3_2.d.ts.map +0 -1
  332. package/dist/migrations/knex/upgrades/20251024040000_upgrade_v3_0_to_v3_2.js.map +0 -1
  333. package/dist/migrations/knex/upgrades/20251024050000_upgrade_v3_2_0_to_v3_2_2.d.ts.map +0 -1
  334. package/dist/migrations/knex/upgrades/20251024050000_upgrade_v3_2_0_to_v3_2_2.js.map +0 -1
  335. package/dist/migrations/knex/upgrades/20251024060000_upgrade_v3_4_to_v3_5.d.ts.map +0 -1
  336. package/dist/migrations/knex/upgrades/20251024060000_upgrade_v3_4_to_v3_5.js.map +0 -1
  337. package/dist/migrations/knex/upgrades/20251024070000_upgrade_v3_5_to_v3_6.d.ts.map +0 -1
  338. package/dist/migrations/knex/upgrades/20251024070000_upgrade_v3_5_to_v3_6.js.map +0 -1
  339. /package/dist/{migrations → config}/knex/bootstrap/20251025020452_create_master_tables.d.ts +0 -0
  340. /package/dist/{migrations → config}/knex/bootstrap/20251025021152_create_transaction_tables.d.ts +0 -0
  341. /package/dist/{migrations → config}/knex/bootstrap/20251025021351_create_indexes.d.ts +0 -0
  342. /package/dist/{migrations → config}/knex/bootstrap/20251025021351_create_indexes.js +0 -0
  343. /package/dist/{migrations → config}/knex/bootstrap/20251025021416_seed_master_data.d.ts +0 -0
  344. /package/dist/{migrations → config}/knex/bootstrap/20251025070349_create_views.d.ts +0 -0
  345. /package/dist/{migrations → config}/knex/enhancements/20251025081221_add_link_type_to_task_decision_links.d.ts +0 -0
  346. /package/dist/{migrations → config}/knex/enhancements/20251025082220_fix_task_dependencies_columns.d.ts +0 -0
  347. /package/dist/{migrations → config}/knex/enhancements/20251025082220_fix_task_dependencies_columns.js +0 -0
  348. /package/dist/{migrations → config}/knex/enhancements/20251025090000_create_help_system_tables.d.ts +0 -0
  349. /package/dist/{migrations → config}/knex/enhancements/20251025090100_seed_help_categories_and_use_cases.d.ts +0 -0
  350. /package/dist/{migrations → config}/knex/enhancements/20251025100000_seed_help_metadata.d.ts +0 -0
  351. /package/dist/{migrations → config}/knex/enhancements/20251025100100_seed_remaining_use_cases.d.ts +0 -0
  352. /package/dist/{migrations → config}/knex/enhancements/20251025100100_seed_remaining_use_cases.js +0 -0
  353. /package/dist/{migrations → config}/knex/enhancements/20251025120000_add_cascade_to_task_dependencies.d.ts +0 -0
  354. /package/dist/{migrations → config}/knex/enhancements/20251027000000_add_agent_reuse_system.d.ts +0 -0
  355. /package/dist/{migrations → config}/knex/enhancements/20251027010000_add_task_constraint_to_decision_context.d.ts +0 -0
  356. /package/dist/{migrations → config}/knex/enhancements/20251027010000_add_task_constraint_to_decision_context.js +0 -0
  357. /package/dist/{migrations → config}/knex/enhancements/20251027020000_update_agent_reusability.d.ts +0 -0
  358. /package/dist/{migrations → config}/knex/enhancements/20251028000000_simplify_agent_system.d.ts +0 -0
  359. /package/dist/{migrations → config}/knex/upgrades/20251024010000_upgrade_v1_0_to_v1_1.d.ts +0 -0
  360. /package/dist/{migrations → config}/knex/upgrades/20251024010000_upgrade_v1_0_to_v1_1.js +0 -0
  361. /package/dist/{migrations → config}/knex/upgrades/20251024020000_upgrade_v2_0_to_v2_1.d.ts +0 -0
  362. /package/dist/{migrations → config}/knex/upgrades/20251024020000_upgrade_v2_0_to_v2_1.js +0 -0
  363. /package/dist/{migrations → config}/knex/upgrades/20251024030000_upgrade_v2_1_to_v3_0.d.ts +0 -0
  364. /package/dist/{migrations → config}/knex/upgrades/20251024030000_upgrade_v2_1_to_v3_0.js +0 -0
  365. /package/dist/{migrations → config}/knex/upgrades/20251024040000_upgrade_v3_0_to_v3_2.d.ts +0 -0
  366. /package/dist/{migrations → config}/knex/upgrades/20251024040000_upgrade_v3_0_to_v3_2.js +0 -0
  367. /package/dist/{migrations → config}/knex/upgrades/20251024050000_upgrade_v3_2_0_to_v3_2_2.d.ts +0 -0
  368. /package/dist/{migrations → config}/knex/upgrades/20251024050000_upgrade_v3_2_0_to_v3_2_2.js +0 -0
  369. /package/dist/{migrations → config}/knex/upgrades/20251024060000_upgrade_v3_4_to_v3_5.d.ts +0 -0
  370. /package/dist/{migrations → config}/knex/upgrades/20251024060000_upgrade_v3_4_to_v3_5.js +0 -0
  371. /package/dist/{migrations → config}/knex/upgrades/20251024070000_upgrade_v3_5_to_v3_6.d.ts +0 -0
  372. /package/dist/{migrations → config}/knex/upgrades/20251024070000_upgrade_v3_5_to_v3_6.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"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"}
@@ -5,12 +5,14 @@
5
5
  * CONVERTED: Using Knex.js with DatabaseAdapter (async/await)
6
6
  */
7
7
  import { getAdapter, getOrCreateAgent, getOrCreateContextKey, getOrCreateTag, getOrCreateScope, getLayerId, addDecisionContext as dbAddDecisionContext, getDecisionWithContext as dbGetDecisionWithContext, listDecisionContexts as dbListDecisionContexts } from '../database.js';
8
+ import { getProjectContext } from '../utils/project-context.js';
8
9
  import { STRING_TO_STATUS, DEFAULT_VERSION, DEFAULT_STATUS } from '../constants.js';
9
10
  import { validateRequired, validateStatus } from '../utils/validators.js';
10
11
  import { logDecisionSet, logDecisionUpdate, recordDecisionHistory } from '../utils/activity-logging.js';
11
12
  import { parseStringArray } from '../utils/param-parser.js';
12
13
  import { validateActionParams, validateBatchParams } from '../utils/parameter-validator.js';
13
- import { debugLogFunctionEntry, debugLogFunctionExit, debugLogTransaction, debugLogCriticalError } from '../utils/debug-logger.js';
14
+ import connectionManager from '../utils/connection-manager.js';
15
+ import { debugLog, debugLogFunctionEntry, debugLogFunctionExit, debugLogTransaction, debugLogCriticalError } from '../utils/debug-logger.js';
14
16
  /**
15
17
  * Internal helper: Set decision without wrapping in transaction
16
18
  * Used by setDecision (with transaction) and setDecisionBatch (manages its own transaction)
@@ -22,6 +24,8 @@ import { debugLogFunctionEntry, debugLogFunctionExit, debugLogTransaction, debug
22
24
  */
23
25
  async function setDecisionInternal(params, adapter, trx) {
24
26
  const knex = trx || adapter.getKnex();
27
+ // Validate project context (Constraint #29 - fail-fast before mutations)
28
+ const projectId = getProjectContext().getProjectId();
25
29
  // Validate required parameters
26
30
  const trimmedKey = validateRequired(params.key, 'key');
27
31
  if (params.value === undefined || params.value === null) {
@@ -57,12 +61,13 @@ async function setDecisionInternal(params, adapter, trx) {
57
61
  const ts = Math.floor(Date.now() / 1000);
58
62
  // Check if decision already exists for activity logging
59
63
  const existingDecision = await knex(isNumeric ? 't_decisions_numeric' : 't_decisions')
60
- .where({ key_id: keyId })
64
+ .where({ key_id: keyId, project_id: projectId })
61
65
  .first();
62
66
  // Insert or update decision based on value type
63
67
  const tableName = isNumeric ? 't_decisions_numeric' : 't_decisions';
64
68
  const decisionData = {
65
69
  key_id: keyId,
70
+ project_id: projectId,
66
71
  value: isNumeric ? value : String(value),
67
72
  agent_id: agentId,
68
73
  layer_id: layerId,
@@ -71,7 +76,7 @@ async function setDecisionInternal(params, adapter, trx) {
71
76
  ts: ts
72
77
  };
73
78
  // Use transaction-aware upsert instead of adapter.upsert to avoid connection pool timeout
74
- const conflictColumns = ['key_id'];
79
+ const conflictColumns = ['key_id', 'project_id'];
75
80
  const updateColumns = Object.keys(decisionData).filter(key => !conflictColumns.includes(key));
76
81
  const updateData = updateColumns.reduce((acc, col) => {
77
82
  acc[col] = decisionData[col];
@@ -116,24 +121,36 @@ async function setDecisionInternal(params, adapter, trx) {
116
121
  if (params.tags && params.tags.length > 0) {
117
122
  // Parse tags (handles both arrays and JSON strings from MCP)
118
123
  const tags = parseStringArray(params.tags);
119
- // Clear existing tags
120
- await knex('t_decision_tags').where({ decision_key_id: keyId }).delete();
124
+ // Clear existing tags for this project
125
+ await knex('t_decision_tags')
126
+ .where({ decision_key_id: keyId, project_id: projectId })
127
+ .delete();
121
128
  // Insert new tags
122
129
  for (const tagName of tags) {
123
130
  const tagId = await getOrCreateTag(adapter, tagName, trx);
124
- await knex('t_decision_tags').insert({ decision_key_id: keyId, tag_id: tagId });
131
+ await knex('t_decision_tags').insert({
132
+ decision_key_id: keyId,
133
+ tag_id: tagId,
134
+ project_id: projectId
135
+ });
125
136
  }
126
137
  }
127
138
  // Handle m_scopes (many-to-many)
128
139
  if (params.scopes && params.scopes.length > 0) {
129
140
  // Parse scopes (handles both arrays and JSON strings from MCP)
130
141
  const scopes = parseStringArray(params.scopes);
131
- // Clear existing scopes
132
- await knex('t_decision_scopes').where({ decision_key_id: keyId }).delete();
142
+ // Clear existing scopes for this project
143
+ await knex('t_decision_scopes')
144
+ .where({ decision_key_id: keyId, project_id: projectId })
145
+ .delete();
133
146
  // Insert new scopes
134
147
  for (const scopeName of scopes) {
135
148
  const scopeId = await getOrCreateScope(adapter, scopeName, trx);
136
- await knex('t_decision_scopes').insert({ decision_key_id: keyId, scope_id: scopeId });
149
+ await knex('t_decision_scopes').insert({
150
+ decision_key_id: keyId,
151
+ scope_id: scopeId,
152
+ project_id: projectId
153
+ });
137
154
  }
138
155
  }
139
156
  return {
@@ -165,12 +182,14 @@ export async function setDecision(params, adapter) {
165
182
  const actualAdapter = adapter ?? getAdapter();
166
183
  try {
167
184
  debugLogTransaction('START', 'setDecision');
168
- // Use transaction for atomicity
169
- const result = await actualAdapter.transaction(async (trx) => {
170
- debugLogTransaction('COMMIT', 'setDecision-transaction-begin');
171
- const internalResult = await setDecisionInternal(params, actualAdapter, trx);
172
- debugLogTransaction('COMMIT', 'setDecision-transaction-end');
173
- return internalResult;
185
+ // Use transaction for atomicity with connection retry
186
+ const result = await connectionManager.executeWithRetry(async () => {
187
+ return await actualAdapter.transaction(async (trx) => {
188
+ debugLogTransaction('COMMIT', 'setDecision-transaction-begin');
189
+ const internalResult = await setDecisionInternal(params, actualAdapter, trx);
190
+ debugLogTransaction('COMMIT', 'setDecision-transaction-end');
191
+ return internalResult;
192
+ });
174
193
  });
175
194
  debugLogFunctionExit('setDecision', true, result);
176
195
  return result;
@@ -205,9 +224,31 @@ export async function getContext(params = {}, adapter) {
205
224
  }
206
225
  const actualAdapter = adapter ?? getAdapter();
207
226
  const knex = actualAdapter.getKnex();
227
+ // Determine which project to query (current or referenced)
228
+ let projectId;
229
+ if (params._reference_project) {
230
+ // Cross-project query: look up the referenced project
231
+ const refProject = await knex('m_projects')
232
+ .where({ name: params._reference_project })
233
+ .first();
234
+ if (!refProject) {
235
+ throw new Error(`Referenced project "${params._reference_project}" not found`);
236
+ }
237
+ projectId = refProject.id;
238
+ debugLog('INFO', 'Cross-project query', {
239
+ currentProject: getProjectContext().getProjectName(),
240
+ referencedProject: params._reference_project,
241
+ projectId
242
+ });
243
+ }
244
+ else {
245
+ // Normal query: use current project
246
+ projectId = getProjectContext().getProjectId();
247
+ }
208
248
  try {
209
249
  // Build query dynamically based on filters
210
- let query = knex('v_tagged_decisions');
250
+ // NOTE: v_tagged_decisions view will be updated to include project_id filtering
251
+ let query = knex('v_tagged_decisions').where('project_id', projectId);
211
252
  // Filter by status
212
253
  if (params.status) {
213
254
  if (!STRING_TO_STATUS[params.status]) {
@@ -275,6 +316,8 @@ export async function getDecision(params, adapter) {
275
316
  }
276
317
  const actualAdapter = adapter ?? getAdapter();
277
318
  const knex = actualAdapter.getKnex();
319
+ // Validate project context
320
+ const projectId = getProjectContext().getProjectId();
278
321
  // Validate parameter
279
322
  if (!params.key || params.key.trim() === '') {
280
323
  throw new Error('Parameter "key" is required and cannot be empty');
@@ -282,6 +325,7 @@ export async function getDecision(params, adapter) {
282
325
  try {
283
326
  // If include_context is true, use the context-aware function
284
327
  if (params.include_context) {
328
+ // TODO: Update dbGetDecisionWithContext to accept projectId parameter
285
329
  const result = await dbGetDecisionWithContext(actualAdapter, params.key);
286
330
  if (!result) {
287
331
  return {
@@ -311,7 +355,7 @@ export async function getDecision(params, adapter) {
311
355
  }
312
356
  // Standard query without context (backward compatible)
313
357
  const row = await knex('v_tagged_decisions')
314
- .where({ key: params.key })
358
+ .where({ key: params.key, project_id: projectId })
315
359
  .first();
316
360
  if (!row) {
317
361
  return {
@@ -346,6 +390,8 @@ export async function searchByTags(params, adapter) {
346
390
  }
347
391
  const actualAdapter = adapter ?? getAdapter();
348
392
  const knex = actualAdapter.getKnex();
393
+ // Validate project context
394
+ const projectId = getProjectContext().getProjectId();
349
395
  // Validate required parameters
350
396
  if (!params.tags || params.tags.length === 0) {
351
397
  throw new Error('Parameter "tags" is required and must contain at least one tag');
@@ -354,7 +400,7 @@ export async function searchByTags(params, adapter) {
354
400
  // Parse tags (handles both arrays and JSON strings from MCP)
355
401
  const tags = parseStringArray(params.tags);
356
402
  const matchMode = params.match_mode || 'OR';
357
- let query = knex('v_tagged_decisions');
403
+ let query = knex('v_tagged_decisions').where('project_id', projectId);
358
404
  // Apply tag filtering based on match mode
359
405
  if (matchMode === 'AND') {
360
406
  // All tags must be present
@@ -421,6 +467,8 @@ export async function getVersions(params, adapter) {
421
467
  }
422
468
  const actualAdapter = adapter ?? getAdapter();
423
469
  const knex = actualAdapter.getKnex();
470
+ // Validate project context
471
+ const projectId = getProjectContext().getProjectId();
424
472
  // Validate required parameter
425
473
  if (!params.key || params.key.trim() === '') {
426
474
  throw new Error('Parameter "key" is required and cannot be empty');
@@ -442,7 +490,7 @@ export async function getVersions(params, adapter) {
442
490
  // Query t_decision_history with agent join
443
491
  const rows = await knex('t_decision_history as dh')
444
492
  .leftJoin('m_agents as a', 'dh.agent_id', 'a.id')
445
- .where('dh.key_id', keyId)
493
+ .where({ 'dh.key_id': keyId, 'dh.project_id': projectId })
446
494
  .select('dh.version', 'dh.value', 'a.name as agent_name', knex.raw(`datetime(dh.ts, 'unixepoch') as timestamp`))
447
495
  .orderBy('dh.ts', 'desc');
448
496
  // Transform to response format
@@ -481,6 +529,27 @@ export async function searchByLayer(params, adapter) {
481
529
  }
482
530
  const actualAdapter = adapter ?? getAdapter();
483
531
  const knex = actualAdapter.getKnex();
532
+ // Determine which project to query (current or referenced)
533
+ let projectId;
534
+ if (params._reference_project) {
535
+ // Cross-project query: look up the referenced project
536
+ const refProject = await knex('m_projects')
537
+ .where({ name: params._reference_project })
538
+ .first();
539
+ if (!refProject) {
540
+ throw new Error(`Referenced project "${params._reference_project}" not found`);
541
+ }
542
+ projectId = refProject.id;
543
+ debugLog('INFO', 'Cross-project searchByLayer', {
544
+ currentProject: getProjectContext().getProjectName(),
545
+ referencedProject: params._reference_project,
546
+ projectId
547
+ });
548
+ }
549
+ else {
550
+ // Normal query: use current project
551
+ projectId = getProjectContext().getProjectId();
552
+ }
484
553
  // Validate required parameter
485
554
  if (!params.layer || params.layer.trim() === '') {
486
555
  throw new Error('Parameter "layer" is required and cannot be empty');
@@ -502,7 +571,7 @@ export async function searchByLayer(params, adapter) {
502
571
  if (includeTagsValue) {
503
572
  // Use v_tagged_decisions view for full metadata
504
573
  rows = await knex('v_tagged_decisions')
505
- .where({ layer: params.layer, status: statusValue })
574
+ .where({ layer: params.layer, status: statusValue, project_id: projectId })
506
575
  .orderBy('updated', 'desc')
507
576
  .select('*');
508
577
  }
@@ -515,6 +584,7 @@ export async function searchByLayer(params, adapter) {
515
584
  .leftJoin('m_agents as a', 'd.agent_id', 'a.id')
516
585
  .where('l.name', params.layer)
517
586
  .where('d.status', statusInt)
587
+ .where('d.project_id', projectId)
518
588
  .select('ck.key', 'd.value', 'd.version', knex.raw(`CASE d.status WHEN 1 THEN 'active' WHEN 2 THEN 'deprecated' WHEN 3 THEN 'draft' END as status`), 'l.name as layer', knex.raw('NULL as tags'), knex.raw('NULL as scopes'), 'a.name as decided_by', knex.raw(`datetime(d.ts, 'unixepoch') as updated`));
519
589
  const numericDecisions = knex('t_decisions_numeric as dn')
520
590
  .innerJoin('m_context_keys as ck', 'dn.key_id', 'ck.id')
@@ -522,6 +592,7 @@ export async function searchByLayer(params, adapter) {
522
592
  .leftJoin('m_agents as a', 'dn.agent_id', 'a.id')
523
593
  .where('l.name', params.layer)
524
594
  .where('dn.status', statusInt)
595
+ .where('dn.project_id', projectId)
525
596
  .select('ck.key', knex.raw('CAST(dn.value AS TEXT) as value'), 'dn.version', knex.raw(`CASE dn.status WHEN 1 THEN 'active' WHEN 2 THEN 'deprecated' WHEN 3 THEN 'draft' END as status`), 'l.name as layer', knex.raw('NULL as tags'), knex.raw('NULL as scopes'), 'a.name as decided_by', knex.raw(`datetime(dn.ts, 'unixepoch') as updated`));
526
597
  // Union both queries
527
598
  rows = await stringDecisions.union([numericDecisions]).orderBy('updated', 'desc');
@@ -672,6 +743,8 @@ export async function searchAdvanced(params = {}, adapter) {
672
743
  validateActionParams('decision', 'search_advanced', params);
673
744
  const actualAdapter = adapter ?? getAdapter();
674
745
  const knex = actualAdapter.getKnex();
746
+ // Validate project context
747
+ const projectId = getProjectContext().getProjectId();
675
748
  try {
676
749
  // Parse relative time to Unix timestamp
677
750
  const parseRelativeTime = (relativeTime) => {
@@ -695,7 +768,7 @@ export async function searchAdvanced(params = {}, adapter) {
695
768
  }
696
769
  };
697
770
  // Build base query using v_tagged_decisions view
698
- let query = knex('v_tagged_decisions');
771
+ let query = knex('v_tagged_decisions').where('project_id', projectId);
699
772
  // Filter by layers (OR relationship)
700
773
  if (params.layers && params.layers.length > 0) {
701
774
  query = query.whereIn('layer', params.layers);
@@ -853,25 +926,27 @@ export async function setDecisionBatch(params, adapter) {
853
926
  try {
854
927
  if (atomic) {
855
928
  // Atomic mode: All or nothing
856
- const results = await actualAdapter.transaction(async (trx) => {
857
- const processedResults = [];
858
- for (const decision of params.decisions) {
859
- try {
860
- const result = await setDecisionInternal(decision, actualAdapter, trx);
861
- processedResults.push({
862
- key: decision.key,
863
- key_id: result.key_id,
864
- version: result.version,
865
- success: true,
866
- error: undefined
867
- });
868
- }
869
- catch (error) {
870
- const message = error instanceof Error ? error.message : String(error);
871
- throw new Error(`Batch failed at decision "${decision.key}": ${message}`);
929
+ const results = await connectionManager.executeWithRetry(async () => {
930
+ return await actualAdapter.transaction(async (trx) => {
931
+ const processedResults = [];
932
+ for (const decision of params.decisions) {
933
+ try {
934
+ const result = await setDecisionInternal(decision, actualAdapter, trx);
935
+ processedResults.push({
936
+ key: decision.key,
937
+ key_id: result.key_id,
938
+ version: result.version,
939
+ success: true,
940
+ error: undefined
941
+ });
942
+ }
943
+ catch (error) {
944
+ const message = error instanceof Error ? error.message : String(error);
945
+ throw new Error(`Batch failed at decision "${decision.key}": ${message}`);
946
+ }
872
947
  }
873
- }
874
- return processedResults;
948
+ return processedResults;
949
+ });
875
950
  });
876
951
  return {
877
952
  success: true,
@@ -887,8 +962,10 @@ export async function setDecisionBatch(params, adapter) {
887
962
  let failed = 0;
888
963
  for (const decision of params.decisions) {
889
964
  try {
890
- const result = await actualAdapter.transaction(async (trx) => {
891
- return await setDecisionInternal(decision, actualAdapter, trx);
965
+ const result = await connectionManager.executeWithRetry(async () => {
966
+ return await actualAdapter.transaction(async (trx) => {
967
+ return await setDecisionInternal(decision, actualAdapter, trx);
968
+ });
892
969
  });
893
970
  results.push({
894
971
  key: decision.key,
@@ -938,6 +1015,8 @@ export async function hasUpdates(params, adapter) {
938
1015
  validateActionParams('decision', 'has_updates', params);
939
1016
  const actualAdapter = adapter ?? getAdapter();
940
1017
  const knex = actualAdapter.getKnex();
1018
+ // Validate project context
1019
+ const projectId = getProjectContext().getProjectId();
941
1020
  try {
942
1021
  // Parse ISO timestamp to Unix epoch
943
1022
  const sinceDate = new Date(params.since_timestamp);
@@ -947,10 +1026,12 @@ export async function hasUpdates(params, adapter) {
947
1026
  const sinceTs = Math.floor(sinceDate.getTime() / 1000);
948
1027
  // Count decisions updated since timestamp (both string and numeric tables)
949
1028
  const decisionCount1 = await knex('t_decisions')
1029
+ .where({ project_id: projectId })
950
1030
  .where('ts', '>', sinceTs)
951
1031
  .count('* as count')
952
1032
  .first();
953
1033
  const decisionCount2 = await knex('t_decisions_numeric')
1034
+ .where({ project_id: projectId })
954
1035
  .where('ts', '>', sinceTs)
955
1036
  .count('* as count')
956
1037
  .first();
@@ -973,8 +1054,9 @@ export async function hasUpdates(params, adapter) {
973
1054
  .first();
974
1055
  messagesCount = messageResult?.count || 0;
975
1056
  }
976
- // Count file changes since timestamp
1057
+ // Count file changes since timestamp (project-scoped)
977
1058
  const fileResult = await knex('t_file_changes')
1059
+ .where({ project_id: projectId })
978
1060
  .where('ts', '>', sinceTs)
979
1061
  .count('* as count')
980
1062
  .first();
@@ -1009,10 +1091,12 @@ export async function setFromTemplate(params, adapter) {
1009
1091
  validateActionParams('decision', 'set_from_template', params);
1010
1092
  const actualAdapter = adapter ?? getAdapter();
1011
1093
  const knex = actualAdapter.getKnex();
1094
+ // Validate project context
1095
+ const projectId = getProjectContext().getProjectId();
1012
1096
  try {
1013
- // Get template
1097
+ // Get template (templates are project-scoped)
1014
1098
  const templateRow = await knex('t_decision_templates')
1015
- .where({ name: params.template })
1099
+ .where({ name: params.template, project_id: projectId })
1016
1100
  .first();
1017
1101
  if (!templateRow) {
1018
1102
  throw new Error(`Template not found: ${params.template}`);
@@ -1081,40 +1165,45 @@ export async function createTemplate(params, adapter) {
1081
1165
  validateActionParams('decision', 'create_template', params);
1082
1166
  const actualAdapter = adapter ?? getAdapter();
1083
1167
  const knex = actualAdapter.getKnex();
1168
+ // Validate project context (Constraint #29 - fail-fast before mutations)
1169
+ const projectId = getProjectContext().getProjectId();
1084
1170
  try {
1085
- return await actualAdapter.transaction(async (trx) => {
1086
- // Validate layer if provided in defaults
1087
- if (params.defaults.layer) {
1088
- const layerId = await getLayerId(actualAdapter, params.defaults.layer, trx);
1089
- if (layerId === null) {
1090
- throw new Error(`Invalid layer in defaults: ${params.defaults.layer}. Must be one of: presentation, business, data, infrastructure, cross-cutting`);
1171
+ return await connectionManager.executeWithRetry(async () => {
1172
+ return await actualAdapter.transaction(async (trx) => {
1173
+ // Validate layer if provided in defaults
1174
+ if (params.defaults.layer) {
1175
+ const layerId = await getLayerId(actualAdapter, params.defaults.layer, trx);
1176
+ if (layerId === null) {
1177
+ throw new Error(`Invalid layer in defaults: ${params.defaults.layer}. Must be one of: presentation, business, data, infrastructure, cross-cutting`);
1178
+ }
1091
1179
  }
1092
- }
1093
- // Validate status if provided in defaults
1094
- if (params.defaults.status && !STRING_TO_STATUS[params.defaults.status]) {
1095
- throw new Error(`Invalid status in defaults: ${params.defaults.status}. Must be 'active', 'deprecated', or 'draft'`);
1096
- }
1097
- // Get or create agent if creator specified
1098
- let createdById = null;
1099
- if (params.created_by) {
1100
- createdById = await getOrCreateAgent(actualAdapter, params.created_by, trx);
1101
- }
1102
- // Serialize defaults and required fields
1103
- const defaultsJson = JSON.stringify(params.defaults);
1104
- const requiredFieldsJson = params.required_fields ? JSON.stringify(params.required_fields) : null;
1105
- // Insert template
1106
- const [id] = await trx('t_decision_templates').insert({
1107
- name: params.name,
1108
- defaults: defaultsJson,
1109
- required_fields: requiredFieldsJson,
1110
- created_by: createdById
1180
+ // Validate status if provided in defaults
1181
+ if (params.defaults.status && !STRING_TO_STATUS[params.defaults.status]) {
1182
+ throw new Error(`Invalid status in defaults: ${params.defaults.status}. Must be 'active', 'deprecated', or 'draft'`);
1183
+ }
1184
+ // Get or create agent if creator specified
1185
+ let createdById = null;
1186
+ if (params.created_by) {
1187
+ createdById = await getOrCreateAgent(actualAdapter, params.created_by, trx);
1188
+ }
1189
+ // Serialize defaults and required fields
1190
+ const defaultsJson = JSON.stringify(params.defaults);
1191
+ const requiredFieldsJson = params.required_fields ? JSON.stringify(params.required_fields) : null;
1192
+ // Insert template
1193
+ const [id] = await trx('t_decision_templates').insert({
1194
+ name: params.name,
1195
+ project_id: projectId,
1196
+ defaults: defaultsJson,
1197
+ required_fields: requiredFieldsJson,
1198
+ created_by: createdById
1199
+ });
1200
+ return {
1201
+ success: true,
1202
+ template_id: id,
1203
+ template_name: params.name,
1204
+ message: `Template "${params.name}" created successfully`
1205
+ };
1111
1206
  });
1112
- return {
1113
- success: true,
1114
- template_id: id,
1115
- template_name: params.name,
1116
- message: `Template "${params.name}" created successfully`
1117
- };
1118
1207
  });
1119
1208
  }
1120
1209
  catch (error) {
@@ -1135,9 +1224,12 @@ export async function listTemplates(params = {}, adapter) {
1135
1224
  validateActionParams('decision', 'list_templates', params);
1136
1225
  const actualAdapter = adapter ?? getAdapter();
1137
1226
  const knex = actualAdapter.getKnex();
1227
+ // Validate project context
1228
+ const projectId = getProjectContext().getProjectId();
1138
1229
  try {
1139
1230
  const rows = await knex('t_decision_templates as t')
1140
1231
  .leftJoin('m_agents as a', 't.created_by', 'a.id')
1232
+ .where('t.project_id', projectId)
1141
1233
  .select('t.id', 't.name', 't.defaults', 't.required_fields', 'a.name as created_by', knex.raw(`datetime(t.ts, 'unixepoch') as created_at`))
1142
1234
  .orderBy('t.name', 'asc');
1143
1235
  // Parse JSON fields
@@ -1180,45 +1272,60 @@ export async function hardDeleteDecision(params, adapter) {
1180
1272
  validateActionParams('decision', 'hard_delete', params);
1181
1273
  const actualAdapter = adapter ?? getAdapter();
1182
1274
  const knex = actualAdapter.getKnex();
1275
+ // Validate project context (fail-fast)
1276
+ const projectId = getProjectContext().getProjectId();
1183
1277
  try {
1184
- return await actualAdapter.transaction(async (trx) => {
1185
- // Get key_id
1186
- const keyResult = await trx('m_context_keys')
1187
- .where({ key: params.key })
1188
- .first('id');
1189
- if (!keyResult) {
1190
- // Key doesn't exist - still return success (idempotent)
1191
- return {
1192
- success: true,
1193
- key: params.key,
1194
- message: `Decision "${params.key}" not found (already deleted or never existed)`
1195
- };
1196
- }
1197
- const keyId = keyResult.id;
1198
- // Delete from t_decisions (if exists)
1199
- const deletedString = await trx('t_decisions').where({ key_id: keyId }).delete();
1200
- // Delete from t_decisions_numeric (if exists)
1201
- const deletedNumeric = await trx('t_decisions_numeric').where({ key_id: keyId }).delete();
1202
- // Delete from t_decision_history (CASCADE should handle this, but explicit for clarity)
1203
- const deletedHistory = await trx('t_decision_history').where({ key_id: keyId }).delete();
1204
- // Delete from t_decision_tags (CASCADE should handle this)
1205
- const deletedTags = await trx('t_decision_tags').where({ decision_key_id: keyId }).delete();
1206
- // Delete from t_decision_scopes (CASCADE should handle this)
1207
- const deletedScopes = await trx('t_decision_scopes').where({ decision_key_id: keyId }).delete();
1208
- // Calculate total deleted records
1209
- const totalDeleted = deletedString + deletedNumeric + deletedHistory + deletedTags + deletedScopes;
1210
- if (totalDeleted === 0) {
1278
+ return await connectionManager.executeWithRetry(async () => {
1279
+ return await actualAdapter.transaction(async (trx) => {
1280
+ // Get key_id
1281
+ const keyResult = await trx('m_context_keys')
1282
+ .where({ key: params.key })
1283
+ .first('id');
1284
+ if (!keyResult) {
1285
+ // Key doesn't exist - still return success (idempotent)
1286
+ return {
1287
+ success: true,
1288
+ key: params.key,
1289
+ message: `Decision "${params.key}" not found (already deleted or never existed)`
1290
+ };
1291
+ }
1292
+ const keyId = keyResult.id;
1293
+ // SECURITY: All deletes MUST filter by project_id to prevent cross-project deletion
1294
+ // Delete from t_decisions (if exists in this project)
1295
+ const deletedString = await trx('t_decisions')
1296
+ .where({ key_id: keyId, project_id: projectId })
1297
+ .delete();
1298
+ // Delete from t_decisions_numeric (if exists in this project)
1299
+ const deletedNumeric = await trx('t_decisions_numeric')
1300
+ .where({ key_id: keyId, project_id: projectId })
1301
+ .delete();
1302
+ // Delete from t_decision_history (for this project only)
1303
+ const deletedHistory = await trx('t_decision_history')
1304
+ .where({ key_id: keyId, project_id: projectId })
1305
+ .delete();
1306
+ // Delete from t_decision_tags (for this project only)
1307
+ const deletedTags = await trx('t_decision_tags')
1308
+ .where({ decision_key_id: keyId, project_id: projectId })
1309
+ .delete();
1310
+ // Delete from t_decision_scopes (for this project only)
1311
+ const deletedScopes = await trx('t_decision_scopes')
1312
+ .where({ decision_key_id: keyId, project_id: projectId })
1313
+ .delete();
1314
+ // Calculate total deleted records
1315
+ const totalDeleted = deletedString + deletedNumeric + deletedHistory + deletedTags + deletedScopes;
1316
+ if (totalDeleted === 0) {
1317
+ return {
1318
+ success: true,
1319
+ key: params.key,
1320
+ message: `Decision "${params.key}" not found (already deleted or never existed)`
1321
+ };
1322
+ }
1211
1323
  return {
1212
1324
  success: true,
1213
1325
  key: params.key,
1214
- message: `Decision "${params.key}" not found (already deleted or never existed)`
1326
+ message: `Decision "${params.key}" permanently deleted (${totalDeleted} record${totalDeleted === 1 ? '' : 's'})`
1215
1327
  };
1216
- }
1217
- return {
1218
- success: true,
1219
- key: params.key,
1220
- message: `Decision "${params.key}" permanently deleted (${totalDeleted} record${totalDeleted === 1 ? '' : 's'})`
1221
- };
1328
+ });
1222
1329
  });
1223
1330
  }
1224
1331
  catch (error) {