@qelos/aidev 1.1.0 → 1.3.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 (239) hide show
  1. package/.env.aidev.example +12 -1
  2. package/README.md +65 -7
  3. package/dist/ai/devin.d.ts +7 -0
  4. package/dist/ai/devin.d.ts.map +1 -0
  5. package/dist/ai/devin.js +91 -0
  6. package/dist/ai/devin.js.map +1 -0
  7. package/dist/ai/index.js +2 -2
  8. package/dist/ai/index.js.map +1 -1
  9. package/dist/cli.js +31 -0
  10. package/dist/cli.js.map +1 -1
  11. package/dist/commands/help.js +1 -1
  12. package/dist/commands/help.js.map +1 -1
  13. package/dist/commands/hooks.d.ts +5 -0
  14. package/dist/commands/hooks.d.ts.map +1 -0
  15. package/dist/commands/hooks.js +86 -0
  16. package/dist/commands/hooks.js.map +1 -0
  17. package/dist/commands/init.d.ts +1 -0
  18. package/dist/commands/init.d.ts.map +1 -1
  19. package/dist/commands/init.js +18 -109
  20. package/dist/commands/init.js.map +1 -1
  21. package/dist/commands/run.d.ts +2 -1
  22. package/dist/commands/run.d.ts.map +1 -1
  23. package/dist/commands/run.js +105 -64
  24. package/dist/commands/run.js.map +1 -1
  25. package/dist/commands/schedule.js +2 -2
  26. package/dist/commands/schedule.js.map +1 -1
  27. package/dist/config.d.ts.map +1 -1
  28. package/dist/config.js +8 -1
  29. package/dist/config.js.map +1 -1
  30. package/dist/diagnostics.d.ts.map +1 -1
  31. package/dist/diagnostics.js +1 -2
  32. package/dist/diagnostics.js.map +1 -1
  33. package/dist/hooks.d.ts +18 -0
  34. package/dist/hooks.d.ts.map +1 -1
  35. package/dist/hooks.js +16 -0
  36. package/dist/hooks.js.map +1 -1
  37. package/dist/hooksTemplate.d.ts +14 -0
  38. package/dist/hooksTemplate.d.ts.map +1 -0
  39. package/dist/hooksTemplate.js +274 -0
  40. package/dist/hooksTemplate.js.map +1 -0
  41. package/dist/logger.d.ts +1 -0
  42. package/dist/logger.d.ts.map +1 -1
  43. package/dist/logger.js +32 -0
  44. package/dist/logger.js.map +1 -1
  45. package/dist/platform.d.ts +2 -2
  46. package/dist/platform.js +2 -2
  47. package/dist/providers/clickup.d.ts +8 -0
  48. package/dist/providers/clickup.d.ts.map +1 -1
  49. package/dist/providers/clickup.js +13 -1
  50. package/dist/providers/clickup.js.map +1 -1
  51. package/dist/providers/jira.d.ts +2 -0
  52. package/dist/providers/jira.d.ts.map +1 -1
  53. package/dist/providers/jira.js +51 -12
  54. package/dist/providers/jira.js.map +1 -1
  55. package/dist/providers/linear.d.ts +19 -0
  56. package/dist/providers/linear.d.ts.map +1 -1
  57. package/dist/providers/linear.js +65 -18
  58. package/dist/providers/linear.js.map +1 -1
  59. package/dist/providers/monday.d.ts +11 -0
  60. package/dist/providers/monday.d.ts.map +1 -1
  61. package/dist/providers/monday.js +74 -1
  62. package/dist/providers/monday.js.map +1 -1
  63. package/dist/providers/notion.d.ts +1 -0
  64. package/dist/providers/notion.d.ts.map +1 -1
  65. package/dist/providers/notion.js +44 -0
  66. package/dist/providers/notion.js.map +1 -1
  67. package/dist/providers/trello.d.ts +1 -0
  68. package/dist/providers/trello.d.ts.map +1 -1
  69. package/dist/providers/trello.js +53 -0
  70. package/dist/providers/trello.js.map +1 -1
  71. package/dist/safeMode.d.ts +32 -0
  72. package/dist/safeMode.d.ts.map +1 -0
  73. package/dist/safeMode.js +192 -0
  74. package/dist/safeMode.js.map +1 -0
  75. package/dist/types.d.ts +4 -1
  76. package/dist/types.d.ts.map +1 -1
  77. package/package.json +2 -2
  78. package/ui/.output/nitro.json +1 -1
  79. package/ui/.output/public/_nuxt/6wLLp9Nc.js +1 -0
  80. package/ui/.output/public/_nuxt/BGkU0f28.js +1 -0
  81. package/ui/.output/public/_nuxt/BOIhDy_l.js +4 -0
  82. package/ui/.output/public/_nuxt/BWJzzHTi.js +1 -0
  83. package/ui/.output/public/_nuxt/{3LZdFtk_.js → By4xSvKt.js} +3 -3
  84. package/ui/.output/public/_nuxt/ByAMJ0xS.js +1 -0
  85. package/ui/.output/public/_nuxt/C1xk3ymy.js +1 -0
  86. package/ui/.output/public/_nuxt/CBV5GuL6.js +11 -0
  87. package/ui/.output/public/_nuxt/CTtW-0zG.js +1 -0
  88. package/ui/.output/public/_nuxt/CX0vIr0s.js +131 -0
  89. package/ui/.output/public/_nuxt/{LzHPbXPK.js → CYm8nRCj.js} +1 -1
  90. package/ui/.output/public/_nuxt/CdHqKVo4.js +1 -0
  91. package/ui/.output/public/_nuxt/CnXdKLRd.js +16 -0
  92. package/ui/.output/public/_nuxt/Cz9dogwK.js +1 -0
  93. package/ui/.output/public/_nuxt/DGHfexQZ.js +1 -0
  94. package/ui/.output/public/_nuxt/{CWjftssB.js → DOoocm0F.js} +1 -1
  95. package/ui/.output/public/_nuxt/{DZd8Jv5H.js → D_gcbXK2.js} +1 -1
  96. package/ui/.output/public/_nuxt/{CO4XMBYO.js → Dfhp6TEA.js} +11 -11
  97. package/ui/.output/public/_nuxt/{BtD1YBwM.js → G5BjvTWO.js} +1 -1
  98. package/ui/.output/public/_nuxt/H73b_QUy.js +1 -0
  99. package/ui/.output/public/_nuxt/{BMTHyzVP.js → LCoCV2KL.js} +1 -1
  100. package/ui/.output/public/_nuxt/Zrl3Utak.js +1 -0
  101. package/ui/.output/public/_nuxt/config.CaB_F_OT.css +1 -0
  102. package/ui/.output/public/_nuxt/default.D13_FS9T.css +1 -0
  103. package/ui/.output/public/_nuxt/hooks.B03-GWTh.css +1 -0
  104. package/ui/.output/public/_nuxt/kPPYUzXr.js +2 -0
  105. package/ui/.output/public/_nuxt/logs.DLMkvOEl.css +1 -0
  106. package/ui/.output/public/_nuxt/mHp9eItY.js +1 -0
  107. package/ui/.output/public/_nuxt/{BTfAgCfF.js → tyaD1vVi.js} +1 -1
  108. package/ui/.output/public/_nuxt/{BGlShnpS.js → ynXKxjpn.js} +1 -1
  109. package/ui/.output/public/_nuxt/{B8sr5ZW-.js → yqBy-NAR.js} +2 -2
  110. package/ui/.output/server/chunks/_/hooksTemplate.mjs +365 -0
  111. package/ui/.output/server/chunks/_/hooksTemplate.mjs.map +1 -0
  112. package/ui/.output/server/chunks/build/{Badge-YPOjmkfv.mjs → Badge-nNgbDd8N.mjs} +2 -2
  113. package/ui/.output/server/chunks/build/{Badge-YPOjmkfv.mjs.map → Badge-nNgbDd8N.mjs.map} +1 -1
  114. package/ui/.output/server/chunks/build/{Button-CZHl6fpI.mjs → Button-CQZG7w2L.mjs} +117 -3
  115. package/ui/.output/server/chunks/build/Button-CQZG7w2L.mjs.map +1 -0
  116. package/ui/.output/server/chunks/build/{Card--ibiHV_r.mjs → Card-DdEnDTQW.mjs} +2 -2
  117. package/ui/.output/server/chunks/build/{Card--ibiHV_r.mjs.map → Card-DdEnDTQW.mjs.map} +1 -1
  118. package/ui/.output/server/chunks/build/{FormGroup-CX5VmH8y.mjs → FormGroup-BfYiVGgN.mjs} +2 -2
  119. package/ui/.output/server/chunks/build/{FormGroup-CX5VmH8y.mjs.map → FormGroup-BfYiVGgN.mjs.map} +1 -1
  120. package/ui/.output/server/chunks/build/{Input-kmqS1oY_.mjs → Input-Cnk3P_aB.mjs} +5 -60
  121. package/ui/.output/server/chunks/build/Input-Cnk3P_aB.mjs.map +1 -0
  122. package/ui/.output/server/chunks/build/{Modal-DmZs0Ekg.mjs → Modal-DfVO6DJD.mjs} +10 -5
  123. package/ui/.output/server/chunks/build/Modal-DfVO6DJD.mjs.map +1 -0
  124. package/ui/.output/server/chunks/build/{Select-n4_YfXfk.mjs → Select-Dc9_TJIR.mjs} +3 -3
  125. package/ui/.output/server/chunks/build/{Select-n4_YfXfk.mjs.map → Select-Dc9_TJIR.mjs.map} +1 -1
  126. package/ui/.output/server/chunks/build/client.precomputed.mjs +1 -1
  127. package/ui/.output/server/chunks/build/client.precomputed.mjs.map +1 -1
  128. package/ui/.output/server/chunks/build/{config-Bkb2wy7R.mjs → config-BUokZPak.mjs} +78 -58
  129. package/ui/.output/server/chunks/build/config-BUokZPak.mjs.map +1 -0
  130. package/ui/.output/server/chunks/build/config-styles.irltMnuD.mjs +8 -0
  131. package/ui/.output/server/chunks/build/config-styles.irltMnuD.mjs.map +1 -0
  132. package/ui/.output/server/chunks/build/{default-DmD3qBXZ.mjs → default-6TcwTt3p.mjs} +10 -9
  133. package/ui/.output/server/chunks/build/default-6TcwTt3p.mjs.map +1 -0
  134. package/ui/.output/server/chunks/build/default-styles.BqL9zxh4.mjs +8 -0
  135. package/ui/.output/server/chunks/build/default-styles.BqL9zxh4.mjs.map +1 -0
  136. package/ui/.output/server/chunks/build/entry-styles.q-b4rEBh.mjs +11 -0
  137. package/ui/.output/server/chunks/build/entry-styles.q-b4rEBh.mjs.map +1 -0
  138. package/ui/.output/server/chunks/build/hooks-k2ZmlVpA.mjs +4181 -0
  139. package/ui/.output/server/chunks/build/hooks-k2ZmlVpA.mjs.map +1 -0
  140. package/ui/.output/server/chunks/build/hooks-styles.Ddk4F_Gj.mjs +8 -0
  141. package/ui/.output/server/chunks/build/hooks-styles.Ddk4F_Gj.mjs.map +1 -0
  142. package/ui/.output/server/chunks/build/{index-Dy4Tu7MB.mjs → index-DwMIJp2e.mjs} +7 -3
  143. package/ui/.output/server/chunks/build/index-DwMIJp2e.mjs.map +1 -0
  144. package/ui/.output/server/chunks/build/{index-BvfXQQ2n.mjs → index-JLPhao-C.mjs} +5 -5
  145. package/ui/.output/server/chunks/build/{index-BvfXQQ2n.mjs.map → index-JLPhao-C.mjs.map} +1 -1
  146. package/ui/.output/server/chunks/build/{interval-DHZqEf-n.mjs → interval-DPa3fpS0.mjs} +3 -3
  147. package/ui/.output/server/chunks/build/{interval-DHZqEf-n.mjs.map → interval-DPa3fpS0.mjs.map} +1 -1
  148. package/ui/.output/server/chunks/build/{login-B5YkLJCV.mjs → login-D9DpNq3o.mjs} +6 -5
  149. package/ui/.output/server/chunks/build/login-D9DpNq3o.mjs.map +1 -0
  150. package/ui/.output/server/chunks/build/{logs-BvD1Y3HI.mjs → logs-BVuWOSb6.mjs} +49 -31
  151. package/ui/.output/server/chunks/build/logs-BVuWOSb6.mjs.map +1 -0
  152. package/ui/.output/server/chunks/build/logs-styles.C2Mi0JvX.mjs +8 -0
  153. package/ui/.output/server/chunks/build/logs-styles.C2Mi0JvX.mjs.map +1 -0
  154. package/ui/.output/server/chunks/build/{run-BStPkbGg.mjs → run-BVQZSGcX.mjs} +5 -5
  155. package/ui/.output/server/chunks/build/{run-BStPkbGg.mjs.map → run-BVQZSGcX.mjs.map} +1 -1
  156. package/ui/.output/server/chunks/build/{schedule-B2UKsnRW.mjs → schedule-rRz2CwWh.mjs} +10 -9
  157. package/ui/.output/server/chunks/build/schedule-rRz2CwWh.mjs.map +1 -0
  158. package/ui/.output/server/chunks/build/server.mjs +14 -9
  159. package/ui/.output/server/chunks/build/server.mjs.map +1 -1
  160. package/ui/.output/server/chunks/build/styles.mjs +8 -7
  161. package/ui/.output/server/chunks/build/styles.mjs.map +1 -1
  162. package/ui/.output/server/chunks/build/{tasks-DBH3Z6lg.mjs → tasks-DJjZQWcq.mjs} +10 -9
  163. package/ui/.output/server/chunks/build/tasks-DJjZQWcq.mjs.map +1 -0
  164. package/ui/.output/server/chunks/build/{useApi-Bqajqsuz.mjs → useApi-Brbyp7hV.mjs} +3 -3
  165. package/ui/.output/server/chunks/build/useApi-Brbyp7hV.mjs.map +1 -0
  166. package/ui/.output/server/chunks/build/useFormGroup-DqE91r20.mjs +61 -0
  167. package/ui/.output/server/chunks/build/useFormGroup-DqE91r20.mjs.map +1 -0
  168. package/ui/.output/server/chunks/nitro/nitro.mjs +202 -164
  169. package/ui/.output/server/chunks/routes/api/config/test.post.mjs +1 -1
  170. package/ui/.output/server/chunks/routes/api/config/test.post.mjs.map +1 -1
  171. package/ui/.output/server/chunks/routes/api/hooks-execute.post.mjs +83 -0
  172. package/ui/.output/server/chunks/routes/api/hooks-execute.post.mjs.map +1 -0
  173. package/ui/.output/server/chunks/routes/api/hooks-regenerate.post.mjs +30 -0
  174. package/ui/.output/server/chunks/routes/api/hooks-regenerate.post.mjs.map +1 -0
  175. package/ui/.output/server/chunks/routes/api/hooks-update.post.mjs +31 -0
  176. package/ui/.output/server/chunks/routes/api/hooks-update.post.mjs.map +1 -0
  177. package/ui/.output/server/chunks/routes/api/hooks.get.mjs +28 -0
  178. package/ui/.output/server/chunks/routes/api/hooks.get.mjs.map +1 -0
  179. package/ui/.output/server/chunks/routes/api/hooks.put.mjs +32 -0
  180. package/ui/.output/server/chunks/routes/api/hooks.put.mjs.map +1 -0
  181. package/ui/.output/server/chunks/routes/api/logs.get.mjs +7 -2
  182. package/ui/.output/server/chunks/routes/api/logs.get.mjs.map +1 -1
  183. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/_virtual/_rollupPluginBabelHelpers.js +123 -0
  184. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/config/index.js +11 -0
  185. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/index.js +9 -0
  186. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/loader/index.js +175 -0
  187. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/utils/compose.js +16 -0
  188. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/utils/curry.js +20 -0
  189. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/utils/deepMerge.js +18 -0
  190. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/utils/isObject.js +9 -0
  191. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/utils/makeCancelable.js +25 -0
  192. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/validators/index.js +49 -0
  193. package/ui/.output/server/node_modules/@monaco-editor/loader/package.json +51 -0
  194. package/ui/.output/server/node_modules/@tanstack/virtual-core/dist/esm/index.js +1197 -0
  195. package/ui/.output/server/node_modules/@tanstack/virtual-core/dist/esm/lazy-measurements.js +34 -0
  196. package/ui/.output/server/node_modules/@tanstack/virtual-core/dist/esm/utils.js +74 -0
  197. package/ui/.output/server/node_modules/@tanstack/virtual-core/package.json +56 -0
  198. package/ui/.output/server/node_modules/@tanstack/vue-virtual/dist/esm/index.js +66 -0
  199. package/ui/.output/server/node_modules/@tanstack/vue-virtual/package.json +68 -0
  200. package/ui/.output/server/node_modules/state-local/lib/cjs/state-local.js +195 -0
  201. package/ui/.output/server/node_modules/state-local/package.json +59 -0
  202. package/ui/.output/server/package.json +4 -0
  203. package/ui/package.json +1 -0
  204. package/ui/.output/public/_nuxt/B93YYUZf.js +0 -1
  205. package/ui/.output/public/_nuxt/BAs1isOw.js +0 -1
  206. package/ui/.output/public/_nuxt/BrZL2iQr.js +0 -1
  207. package/ui/.output/public/_nuxt/Bv6Ws9vz.js +0 -1
  208. package/ui/.output/public/_nuxt/C2WdrjFS.js +0 -1
  209. package/ui/.output/public/_nuxt/CVTgFccA.js +0 -2
  210. package/ui/.output/public/_nuxt/Ceb2855t.js +0 -1
  211. package/ui/.output/public/_nuxt/Cg55PjEy.js +0 -4
  212. package/ui/.output/public/_nuxt/D0ZgktSu.js +0 -1
  213. package/ui/.output/public/_nuxt/DZIUG6ZX.js +0 -1
  214. package/ui/.output/public/_nuxt/DihqGT4A.js +0 -1
  215. package/ui/.output/public/_nuxt/MzK2TZ-I.js +0 -16
  216. package/ui/.output/public/_nuxt/TJXLPQOj.js +0 -1
  217. package/ui/.output/public/_nuxt/VuiIFQtE.js +0 -1
  218. package/ui/.output/public/_nuxt/config.C19X1GwO.css +0 -1
  219. package/ui/.output/public/_nuxt/default.Dw-0Xw5D.css +0 -1
  220. package/ui/.output/public/_nuxt/logs.PK6CTQHM.css +0 -1
  221. package/ui/.output/server/chunks/build/Button-CZHl6fpI.mjs.map +0 -1
  222. package/ui/.output/server/chunks/build/Input-kmqS1oY_.mjs.map +0 -1
  223. package/ui/.output/server/chunks/build/Modal-DmZs0Ekg.mjs.map +0 -1
  224. package/ui/.output/server/chunks/build/config-Bkb2wy7R.mjs.map +0 -1
  225. package/ui/.output/server/chunks/build/config-styles.B4mTchgT.mjs +0 -8
  226. package/ui/.output/server/chunks/build/config-styles.B4mTchgT.mjs.map +0 -1
  227. package/ui/.output/server/chunks/build/default-DmD3qBXZ.mjs.map +0 -1
  228. package/ui/.output/server/chunks/build/default-styles.DmprFUrQ.mjs +0 -8
  229. package/ui/.output/server/chunks/build/default-styles.DmprFUrQ.mjs.map +0 -1
  230. package/ui/.output/server/chunks/build/entry-styles.Cg1Sndbr.mjs +0 -11
  231. package/ui/.output/server/chunks/build/entry-styles.Cg1Sndbr.mjs.map +0 -1
  232. package/ui/.output/server/chunks/build/index-Dy4Tu7MB.mjs.map +0 -1
  233. package/ui/.output/server/chunks/build/login-B5YkLJCV.mjs.map +0 -1
  234. package/ui/.output/server/chunks/build/logs-BvD1Y3HI.mjs.map +0 -1
  235. package/ui/.output/server/chunks/build/logs-styles.CU5b1wKf.mjs +0 -8
  236. package/ui/.output/server/chunks/build/logs-styles.CU5b1wKf.mjs.map +0 -1
  237. package/ui/.output/server/chunks/build/schedule-B2UKsnRW.mjs.map +0 -1
  238. package/ui/.output/server/chunks/build/tasks-DBH3Z6lg.mjs.map +0 -1
  239. package/ui/.output/server/chunks/build/useApi-Bqajqsuz.mjs.map +0 -1
@@ -39,6 +39,7 @@ exports.getOpenStatus = getOpenStatus;
39
39
  exports.getInReviewStatus = getInReviewStatus;
40
40
  exports.getInProgressStatus = getInProgressStatus;
41
41
  exports.getRunSkipReason = getRunSkipReason;
42
+ exports.getBlockedBySkipReason = getBlockedBySkipReason;
42
43
  exports.isThinkingTask = isThinkingTask;
43
44
  exports.isPlanningTask = isPlanningTask;
44
45
  exports.buildPlanningAnalysisPrompt = buildPlanningAnalysisPrompt;
@@ -88,7 +89,15 @@ const activeTask_1 = require("../activeTask");
88
89
  const hooks_1 = require("../hooks");
89
90
  const sessions_1 = require("../sessions");
90
91
  const accepted_1 = require("./accepted");
91
- const SKIP_STATUSES = new Set(['closed', 'done', 'cancelled', 'complete']);
92
+ const safeMode_1 = require("../safeMode");
93
+ function applySafeMode(task, context, config) {
94
+ if (!config.safeMode)
95
+ return { task, context };
96
+ const secrets = (0, safeMode_1.collectSecrets)();
97
+ const sanitized = (0, safeMode_1.sanitizeTaskForSafeMode)(task, context, secrets);
98
+ return { task: { ...task, ...sanitized.task }, context: sanitized.context };
99
+ }
100
+ const SKIP_STATUSES = new Set(['closed', 'done', 'cancelled', 'complete', 'resolved', 'completed']);
92
101
  const NO_PRIORITY = Number.MAX_SAFE_INTEGER;
93
102
  const SLEEPING_MARKER = 'machine appears to be asleep';
94
103
  exports.DEFAULT_TRIGGER_WORD = 'aidev-continue';
@@ -155,6 +164,26 @@ function getRunSkipReason(status, filter, pendingStatus, openStatus = 'open') {
155
164
  }
156
165
  return null;
157
166
  }
167
+ async function getBlockedBySkipReason(task, provider) {
168
+ if (!task.blockedBy || task.blockedBy.length === 0)
169
+ return null;
170
+ if (!provider.fetchTaskById) {
171
+ logger_1.logger.debug(`[${task.id}] provider does not support fetchTaskById — skipping blocked-by check`);
172
+ return null;
173
+ }
174
+ for (const blockerId of task.blockedBy) {
175
+ const blocker = await provider.fetchTaskById(blockerId);
176
+ if (blocker === null) {
177
+ logger_1.logger.debug(`[${task.id}] blocker ${blockerId} not found — treating as non-blocking`);
178
+ continue;
179
+ }
180
+ if (!SKIP_STATUSES.has(blocker.status.toLowerCase())) {
181
+ return `blocked by task ${blockerId} (status: ${blocker.status})`;
182
+ }
183
+ logger_1.logger.debug(`[${task.id}] blocker ${blockerId} is closed (status: ${blocker.status}) — not blocking`);
184
+ }
185
+ return null;
186
+ }
158
187
  function isThinkingTask(task, config) {
159
188
  if (!config.thinkingTag)
160
189
  return false;
@@ -521,6 +550,11 @@ async function processTask(task, filter, config, provider, runners, screenAvaila
521
550
  logger_1.logger.info(`[${task.id}] "${task.name}" skipped — ${skipReason}`);
522
551
  return 'skipped';
523
552
  }
553
+ const blockedReason = await getBlockedBySkipReason(task, provider);
554
+ if (blockedReason) {
555
+ logger_1.logger.info(`[${task.id}] "${task.name}" skipped — ${blockedReason}`);
556
+ return 'skipped';
557
+ }
524
558
  const branchName = `${task.id}/${git.slugify(task.name)}`;
525
559
  const branchExists = git.remoteBranchExists(config.gitRemote, branchName);
526
560
  if (isPending || branchExists) {
@@ -544,18 +578,18 @@ async function processTask(task, filter, config, provider, runners, screenAvaila
544
578
  logger_1.logger.info(`Trigger word "${config.triggerWord}" found — re-processing task`);
545
579
  }
546
580
  if (!screenAvailable) {
547
- await notifySleeping(task, provider, config.commentPrefix);
581
+ await notifySleeping(task, provider, config, hooks, vm);
548
582
  return 'skipped';
549
583
  }
550
584
  }
551
585
  else {
552
586
  if (!screenAvailable) {
553
- await notifySleeping(task, provider, config.commentPrefix);
587
+ await notifySleeping(task, provider, config, hooks, vm);
554
588
  return 'skipped';
555
589
  }
556
590
  const clarification = await checkNeedsClarification(task, config, provider, runners);
557
591
  if (clarification) {
558
- await provider.postComment(task.id, `${config.commentPrefix} ${clarification}`);
592
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} ${clarification}`, config, provider, hooks, vm);
559
593
  await provider.updateStatus(task.id, getPendingStatus(config));
560
594
  logger_1.logger.info(`Posted clarification question, set status to ${getPendingStatus(config)}`);
561
595
  return 'skipped';
@@ -621,7 +655,7 @@ function hasTriggerWord(comments, triggerWord) {
621
655
  return true;
622
656
  return false;
623
657
  }
624
- async function notifySleeping(task, provider, commentPrefix) {
658
+ async function notifySleeping(task, provider, config, hooks, vm) {
625
659
  try {
626
660
  const comments = await provider.getComments(task.id);
627
661
  const lastComment = comments.length > 0 ? comments[comments.length - 1] : null;
@@ -634,8 +668,8 @@ async function notifySleeping(task, provider, commentPrefix) {
634
668
  // If we can't check comments, still attempt to post
635
669
  }
636
670
  try {
637
- await provider.postComment(task.id, `${commentPrefix} Cannot work on this task — the ${SLEEPING_MARKER} or the screen is locked. ` +
638
- 'AI agents require an active display session to operate. Please wake the machine and unlock the screen so I can continue.');
671
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Cannot work on this task — the ${SLEEPING_MARKER} or the screen is locked. ` +
672
+ 'AI agents require an active display session to operate. Please wake the machine and unlock the screen so I can continue.', config, provider, hooks, vm);
639
673
  logger_1.logger.info(`[${task.id}] Posted sleep notification`);
640
674
  }
641
675
  catch (err) {
@@ -735,12 +769,13 @@ async function resolveConflictsWithAI(task, config, provider, runners, context,
735
769
  logger_1.logger.warn(`Branch has conflicts with ${config.githubBaseBranch} in ${check.conflictFiles.length} file(s): ` +
736
770
  check.conflictFiles.join(', '));
737
771
  try {
738
- await provider.postComment(task.id, `${config.commentPrefix} Branch \`${branchName}\` has merge conflicts with \`${config.githubBaseBranch}\` ` +
739
- `in ${check.conflictFiles.length} file(s). Attempting automatic resolution...`);
772
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Branch \`${branchName}\` has merge conflicts with \`${config.githubBaseBranch}\` ` +
773
+ `in ${check.conflictFiles.length} file(s). Attempting automatic resolution...`, config, provider, hooks, vm);
740
774
  }
741
775
  catch { /* ignore */ }
742
776
  if (!git.mergeBaseBranch(config.gitRemote, config.githubBaseBranch)) {
743
- let prompt = buildConflictResolutionPrompt(task, check.conflictFiles, context);
777
+ const { task: safeTask, context: safeContext } = applySafeMode(task, context, config);
778
+ let prompt = buildConflictResolutionPrompt(safeTask, check.conflictFiles, safeContext);
744
779
  // beforeResolveConflicts hook
745
780
  if (vm) {
746
781
  const conflictCtx = { task, config, branchName, conflictFiles: check.conflictFiles, prompt };
@@ -785,7 +820,7 @@ async function resolveConflictsWithAI(task, config, provider, runners, context,
785
820
  git.abortMerge();
786
821
  }
787
822
  try {
788
- await provider.postComment(task.id, `${config.commentPrefix} Failed to automatically resolve merge conflicts. Manual intervention needed to rebase/merge the branch.`);
823
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Failed to automatically resolve merge conflicts. Manual intervention needed to rebase/merge the branch.`, config, provider, hooks, vm);
789
824
  }
790
825
  catch { /* ignore */ }
791
826
  return false;
@@ -807,7 +842,7 @@ async function resolveConflictsWithAI(task, config, provider, runners, context,
807
842
  await (0, hooks_1.executeHook)(hooks, 'afterResolveConflicts', afterCtx, vm);
808
843
  }
809
844
  try {
810
- await provider.postComment(task.id, `${config.commentPrefix} Merge conflicts resolved automatically.`);
845
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Merge conflicts resolved automatically.`, config, provider, hooks, vm);
811
846
  }
812
847
  catch { /* ignore */ }
813
848
  }
@@ -861,7 +896,7 @@ async function implementTask(task, branchName, branchExists, config, provider, r
861
896
  try {
862
897
  await provider.updateStatus(task.id, 'in progress');
863
898
  const verb = branchExists ? 'Continuing' : 'Starting';
864
- await provider.postComment(task.id, `${config.commentPrefix} ${verb} implementation on branch \`${branchName}\``);
899
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} ${verb} implementation on branch \`${branchName}\``, config, provider, hooks, vm);
865
900
  }
866
901
  catch (err) {
867
902
  logger_1.logger.warn(`Could not update task status: ${err}`);
@@ -869,7 +904,7 @@ async function implementTask(task, branchName, branchExists, config, provider, r
869
904
  if (branchExists) {
870
905
  if (!git.fetchAndCheckoutBranch(config.gitRemote, branchName)) {
871
906
  logger_1.logger.error(`Failed to checkout existing branch ${branchName}`);
872
- await provider.postComment(task.id, `${config.commentPrefix} Failed to checkout existing branch. Manual intervention needed.`);
907
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Failed to checkout existing branch. Manual intervention needed.`, config, provider, hooks, vm);
873
908
  return;
874
909
  }
875
910
  logger_1.logger.info(`Continuing on existing branch: ${branchName}`);
@@ -877,7 +912,7 @@ async function implementTask(task, branchName, branchExists, config, provider, r
877
912
  else {
878
913
  if (!git.createBranchFromRemote(config.gitRemote, config.githubBaseBranch, branchName)) {
879
914
  logger_1.logger.error(`Failed to create branch ${branchName} from ${config.gitRemote}/${config.githubBaseBranch}`);
880
- await provider.postComment(task.id, `${config.commentPrefix} Failed to prepare git branch. Manual intervention needed.`);
915
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Failed to prepare git branch. Manual intervention needed.`, config, provider, hooks, vm);
881
916
  return;
882
917
  }
883
918
  }
@@ -904,10 +939,11 @@ async function implementTask(task, branchName, branchExists, config, provider, r
904
939
  logger_1.logger.info(`Found ${reviewThreads.length} unresolved review comment(s) to address`);
905
940
  context += formatReviewComments(reviewThreads);
906
941
  }
907
- let implementPrompt = buildImplementPrompt(task, context);
942
+ const { task: safeTask, context: safeContext } = applySafeMode(task, context, config);
943
+ let implementPrompt = buildImplementPrompt(safeTask, safeContext);
908
944
  // beforeEachTask hook — may modify context (e.g. improve the prompt)
909
945
  if (vm) {
910
- const taskCtx = { task, config, branchName, prompt: implementPrompt };
946
+ const taskCtx = { task: safeTask, config, branchName, prompt: implementPrompt };
911
947
  const modified = await (0, hooks_1.executeHook)(hooks, 'beforeEachTask', taskCtx, vm);
912
948
  implementPrompt = modified.prompt;
913
949
  }
@@ -942,7 +978,7 @@ async function implementTask(task, branchName, branchExists, config, provider, r
942
978
  if (!implemented) {
943
979
  logger_1.logger.error('All AI runners failed or produced no changes');
944
980
  const diagnostics = (0, diagnostics_1.collectAndLogDiagnostics)();
945
- await provider.postComment(task.id, `${config.commentPrefix} All AI runners failed. Manual implementation needed.\n\n${diagnostics}`);
981
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} All AI runners failed. Manual implementation needed.\n\n${diagnostics}`, config, provider, hooks, vm);
946
982
  if (!branchExists) {
947
983
  git.deleteBranch(branchName);
948
984
  }
@@ -966,7 +1002,7 @@ async function implementTask(task, branchName, branchExists, config, provider, r
966
1002
  try {
967
1003
  const prUrl = tryCreatePR(config, branchName, task);
968
1004
  const comment = buildCompletionComment(branchName, prUrl, config);
969
- await provider.postComment(task.id, comment);
1005
+ await (0, hooks_1.postCommentWithHooks)(task, comment, config, provider, hooks, vm);
970
1006
  await provider.updateStatus(task.id, getInReviewStatus(config));
971
1007
  }
972
1008
  catch (err) {
@@ -1183,7 +1219,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1183
1219
  try {
1184
1220
  await provider.updateStatus(task.id, 'in progress');
1185
1221
  const verb = branchExists ? 'Continuing' : 'Starting';
1186
- await provider.postComment(task.id, `${config.commentPrefix} ${verb} implementation on branch \`${branchName}\` (thinking mode — will analyze and break into sub-tasks)`);
1222
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} ${verb} implementation on branch \`${branchName}\` (thinking mode — will analyze and break into sub-tasks)`, config, provider, hooks, vm);
1187
1223
  }
1188
1224
  catch (err) {
1189
1225
  logger_1.logger.warn(`Could not update task status: ${err}`);
@@ -1191,7 +1227,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1191
1227
  if (branchExists) {
1192
1228
  if (!git.fetchAndCheckoutBranch(config.gitRemote, branchName)) {
1193
1229
  logger_1.logger.error(`Failed to checkout existing branch ${branchName}`);
1194
- await provider.postComment(task.id, `${config.commentPrefix} Failed to checkout existing branch. Manual intervention needed.`);
1230
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Failed to checkout existing branch. Manual intervention needed.`, config, provider, hooks, vm);
1195
1231
  return;
1196
1232
  }
1197
1233
  logger_1.logger.info(`Continuing on existing branch: ${branchName}`);
@@ -1199,7 +1235,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1199
1235
  else {
1200
1236
  if (!git.createBranchFromRemote(config.gitRemote, config.githubBaseBranch, branchName)) {
1201
1237
  logger_1.logger.error(`Failed to create branch ${branchName} from ${config.gitRemote}/${config.githubBaseBranch}`);
1202
- await provider.postComment(task.id, `${config.commentPrefix} Failed to prepare git branch. Manual intervention needed.`);
1238
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Failed to prepare git branch. Manual intervention needed.`, config, provider, hooks, vm);
1203
1239
  return;
1204
1240
  }
1205
1241
  }
@@ -1228,16 +1264,17 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1228
1264
  logger_1.logger.info(`Found ${reviewThreads.length} unresolved review comment(s) to address`);
1229
1265
  context += reviewContext;
1230
1266
  }
1267
+ const { task: safeTask, context: safeContext } = applySafeMode(task, context, config);
1231
1268
  // Check for an existing plan (resume scenario)
1232
1269
  let plan = readTaskPlan(task.id);
1233
1270
  if (plan) {
1234
1271
  logger_1.logger.info(`Found existing task plan with ${plan.subtasks.length} sub-tasks — resuming`);
1235
1272
  }
1236
1273
  else {
1237
- plan = await analyzeAndPlan(task, context, runners);
1274
+ plan = await analyzeAndPlan(safeTask, safeContext, runners);
1238
1275
  if (!plan) {
1239
1276
  logger_1.logger.error('Failed to create implementation plan');
1240
- await provider.postComment(task.id, `${config.commentPrefix} Failed to analyze and break down the task. Manual implementation needed.`);
1277
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Failed to analyze and break down the task. Manual implementation needed.`, config, provider, hooks, vm);
1241
1278
  cleanupThinkingFiles(task.id);
1242
1279
  if (!branchExists)
1243
1280
  git.deleteBranch(branchName);
@@ -1245,7 +1282,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1245
1282
  }
1246
1283
  logger_1.logger.info(`Task broken into ${plan.subtasks.length} sub-tasks`);
1247
1284
  try {
1248
- await provider.postComment(task.id, `${config.commentPrefix} Task analyzed and broken into ${plan.subtasks.length} sub-tasks:\n\n${formatSubtaskList(plan)}`);
1285
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Task analyzed and broken into ${plan.subtasks.length} sub-tasks:\n\n${formatSubtaskList(plan)}`, config, provider, hooks, vm);
1249
1286
  }
1250
1287
  catch (err) {
1251
1288
  logger_1.logger.warn(`Failed to post breakdown comment: ${err}`);
@@ -1254,7 +1291,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1254
1291
  // beforeThinkingTask hook — may adjust subtask titles/descriptions before execution
1255
1292
  if (vm) {
1256
1293
  const thinkCtx = {
1257
- task,
1294
+ task: safeTask,
1258
1295
  config,
1259
1296
  branchName,
1260
1297
  subtasks: plan.subtasks.map((s) => ({
@@ -1302,7 +1339,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1302
1339
  const newIds = newSubtasks.map((s) => s.id).join(', ');
1303
1340
  logger_1.logger.info(` Step ${failedId} was split into ${newIds}`);
1304
1341
  try {
1305
- await provider.postComment(task.id, `${config.commentPrefix} Step ${failedId} was split into ${newIds}:\n\n${formatSubtaskList(plan)}`);
1342
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Step ${failedId} was split into ${newIds}:\n\n${formatSubtaskList(plan)}`, config, provider, hooks, vm);
1306
1343
  }
1307
1344
  catch { /* ignore */ }
1308
1345
  i--; // re-process this index — it now points at the first new sub-task
@@ -1310,14 +1347,14 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1310
1347
  }
1311
1348
  logger_1.logger.warn(` Could not split failed step ${failedId} — falling back to plain retry`);
1312
1349
  try {
1313
- await provider.postComment(task.id, `${config.commentPrefix} Failed to automatically split step ${failedId}. Retrying as-is.`);
1350
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Failed to automatically split step ${failedId}. Retrying as-is.`, config, provider, hooks, vm);
1314
1351
  }
1315
1352
  catch { /* ignore */ }
1316
1353
  }
1317
1354
  else if (!isGitFailure && attempts >= 2 && depth >= 2) {
1318
1355
  logger_1.logger.warn(` Step ${subtask.id} has reached the split-depth cap — manual intervention may be needed`);
1319
1356
  try {
1320
- await provider.postComment(task.id, `${config.commentPrefix} Step ${subtask.id} has already been split twice and is still failing. Retrying as-is — please consider manual intervention.`);
1357
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Step ${subtask.id} has already been split twice and is still failing. Retrying as-is — please consider manual intervention.`, config, provider, hooks, vm);
1321
1358
  }
1322
1359
  catch { /* ignore */ }
1323
1360
  }
@@ -1327,7 +1364,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1327
1364
  subtask.attempts = (subtask.attempts ?? 0) + 1;
1328
1365
  writeTaskPlan(plan);
1329
1366
  logger_1.logger.info(` Starting step ${subtask.id}: ${subtask.title} (attempt ${subtask.attempts})`);
1330
- const success = await executeSubTask(subtask, task, plan, config, runners, reviewContext, previousError, ticketConversationContext.trim().length > 0);
1367
+ const success = await executeSubTask(subtask, safeTask, plan, config, runners, reviewContext, previousError, ticketConversationContext.trim().length > 0);
1331
1368
  if (!success) {
1332
1369
  const diagnostics = (0, diagnostics_1.collectAndLogDiagnostics)();
1333
1370
  subtask.status = 'failed';
@@ -1336,7 +1373,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1336
1373
  allSucceeded = false;
1337
1374
  logger_1.logger.error(` Step ${subtask.id} failed: ${subtask.title}`);
1338
1375
  try {
1339
- await provider.postComment(task.id, `${config.commentPrefix} Step ${subtask.id} failed: ${subtask.title}\n\n${formatSubtaskList(plan)}\n\n${diagnostics}`);
1376
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Step ${subtask.id} failed: ${subtask.title}\n\n${formatSubtaskList(plan)}\n\n${diagnostics}`, config, provider, hooks, vm);
1340
1377
  }
1341
1378
  catch { /* ignore */ }
1342
1379
  break;
@@ -1361,7 +1398,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1361
1398
  writeTaskPlan(plan);
1362
1399
  logger_1.logger.success(` Step ${subtask.id} complete: ${subtask.title}`);
1363
1400
  try {
1364
- await provider.postComment(task.id, `${config.commentPrefix} Step ${subtask.id} complete: ${subtask.title}\n\n${formatSubtaskList(plan)}`);
1401
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Step ${subtask.id} complete: ${subtask.title}\n\n${formatSubtaskList(plan)}`, config, provider, hooks, vm);
1365
1402
  }
1366
1403
  catch { /* ignore */ }
1367
1404
  }
@@ -1369,7 +1406,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1369
1406
  logger_1.logger.error('Thinking task did not complete all sub-tasks');
1370
1407
  try {
1371
1408
  const diagnostics = (0, diagnostics_1.collectAndLogDiagnostics)();
1372
- await provider.postComment(task.id, `${config.commentPrefix} Thinking task did not complete all sub-tasks. Manual intervention needed.\n\n${diagnostics}`);
1409
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Thinking task did not complete all sub-tasks. Manual intervention needed.\n\n${diagnostics}`, config, provider, hooks, vm);
1373
1410
  }
1374
1411
  catch { /* ignore */ }
1375
1412
  return;
@@ -1381,7 +1418,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1381
1418
  try {
1382
1419
  const prUrl = tryCreatePR(config, branchName, task);
1383
1420
  const comment = buildCompletionComment(branchName, prUrl, config);
1384
- await provider.postComment(task.id, comment);
1421
+ await (0, hooks_1.postCommentWithHooks)(task, comment, config, provider, hooks, vm);
1385
1422
  await provider.updateStatus(task.id, getInReviewStatus(config));
1386
1423
  if (config.thinkingTag && provider.removeTag) {
1387
1424
  try {
@@ -1404,11 +1441,11 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1404
1441
  }
1405
1442
  logger_1.logger.success(`Thinking task implemented: branch ${branchName} pushed`);
1406
1443
  }
1407
- async function implementPlanningTask(task, config, provider, runners, _hooks = {}, _vm) {
1444
+ async function implementPlanningTask(task, config, provider, runners, hooks = {}, vm) {
1408
1445
  logger_1.logger.info(`Implementing planning task: ${task.name}`);
1409
1446
  try {
1410
1447
  await provider.updateStatus(task.id, 'in progress');
1411
- await provider.postComment(task.id, `${config.commentPrefix} Starting planning mode — analyzing task and drafting sub-tickets`);
1448
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Starting planning mode — analyzing task and drafting sub-tickets`, config, provider, hooks, vm);
1412
1449
  }
1413
1450
  catch (err) {
1414
1451
  logger_1.logger.warn(`Could not update task status: ${err}`);
@@ -1421,7 +1458,8 @@ async function implementPlanningTask(task, config, provider, runners, _hooks = {
1421
1458
  catch {
1422
1459
  // ignore
1423
1460
  }
1424
- const prompt = buildPlanningAnalysisPrompt(task, context);
1461
+ const { task: safeTask, context: safeContext } = applySafeMode(task, context, config);
1462
+ const prompt = buildPlanningAnalysisPrompt(safeTask, safeContext);
1425
1463
  let parsed = null;
1426
1464
  let previousNotes = '';
1427
1465
  for (const runner of runners) {
@@ -1443,14 +1481,14 @@ async function implementPlanningTask(task, config, provider, runners, _hooks = {
1443
1481
  if (!parsed) {
1444
1482
  logger_1.logger.error('Planning produced no sub-tasks');
1445
1483
  try {
1446
- await provider.postComment(task.id, `${config.commentPrefix} Planning produced no sub-tasks`);
1484
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Planning produced no sub-tasks`, config, provider, hooks, vm);
1447
1485
  }
1448
1486
  catch { /* ignore */ }
1449
1487
  return;
1450
1488
  }
1451
1489
  if (parsed.clarification) {
1452
1490
  try {
1453
- await provider.postComment(task.id, `${config.commentPrefix} ${parsed.clarification}`);
1491
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} ${parsed.clarification}`, config, provider, hooks, vm);
1454
1492
  await provider.updateStatus(task.id, getPendingStatus(config));
1455
1493
  logger_1.logger.info(`Posted planning clarification, set status to ${getPendingStatus(config)}`);
1456
1494
  }
@@ -1462,7 +1500,7 @@ async function implementPlanningTask(task, config, provider, runners, _hooks = {
1462
1500
  if (parsed.subtasks.length === 0) {
1463
1501
  logger_1.logger.error('Planning produced no sub-tasks');
1464
1502
  try {
1465
- await provider.postComment(task.id, `${config.commentPrefix} Planning produced no sub-tasks`);
1503
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Planning produced no sub-tasks`, config, provider, hooks, vm);
1466
1504
  }
1467
1505
  catch { /* ignore */ }
1468
1506
  return;
@@ -1507,7 +1545,7 @@ async function implementPlanningTask(task, config, provider, runners, _hooks = {
1507
1545
  }
1508
1546
  }
1509
1547
  try {
1510
- await provider.postComment(task.id, summaryLines.join('\n'));
1548
+ await (0, hooks_1.postCommentWithHooks)(task, summaryLines.join('\n'), config, provider, hooks, vm);
1511
1549
  }
1512
1550
  catch (err) {
1513
1551
  logger_1.logger.warn(`Failed to post planning summary: ${err instanceof Error ? err.message : err}`);
@@ -1685,18 +1723,18 @@ async function processNonCodeTask(task, filter, config, provider, runners, scree
1685
1723
  : 'Human follow-up comment found — processing non-code task');
1686
1724
  }
1687
1725
  if (!screenAvailable) {
1688
- await notifySleeping(task, provider, config.commentPrefix);
1726
+ await notifySleeping(task, provider, config, hooks, vm);
1689
1727
  return 'skipped';
1690
1728
  }
1691
1729
  }
1692
1730
  else {
1693
1731
  if (!screenAvailable) {
1694
- await notifySleeping(task, provider, config.commentPrefix);
1732
+ await notifySleeping(task, provider, config, hooks, vm);
1695
1733
  return 'skipped';
1696
1734
  }
1697
1735
  const clarification = await checkNeedsClarification(task, config, provider, runners);
1698
1736
  if (clarification) {
1699
- await provider.postComment(task.id, `${config.commentPrefix} ${clarification}`);
1737
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} ${clarification}`, config, provider, hooks, vm);
1700
1738
  await provider.updateStatus(task.id, getPendingStatus(config));
1701
1739
  logger_1.logger.info(`Posted clarification question, set status to ${getPendingStatus(config)}`);
1702
1740
  return 'skipped';
@@ -1723,7 +1761,7 @@ async function implementNonCodeTask(task, config, provider, runners, hooks = {},
1723
1761
  logger_1.logger.info(`Implementing non-code task: ${task.name}`);
1724
1762
  try {
1725
1763
  await provider.updateStatus(task.id, 'in progress');
1726
- await provider.postComment(task.id, `${config.commentPrefix} Starting non-code task execution`);
1764
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Starting non-code task execution`, config, provider, hooks, vm);
1727
1765
  }
1728
1766
  catch (err) {
1729
1767
  logger_1.logger.warn(`Could not update task status: ${err}`);
@@ -1736,10 +1774,11 @@ async function implementNonCodeTask(task, config, provider, runners, hooks = {},
1736
1774
  catch {
1737
1775
  // ignore
1738
1776
  }
1739
- let nonCodePrompt = buildNonCodePrompt(task, context);
1777
+ const { task: safeTask, context: safeContext } = applySafeMode(task, context, config);
1778
+ let nonCodePrompt = buildNonCodePrompt(safeTask, safeContext);
1740
1779
  // beforeNonCodeTask hook
1741
1780
  if (vm) {
1742
- const ncCtx = { task, config, prompt: nonCodePrompt };
1781
+ const ncCtx = { task: safeTask, config, prompt: nonCodePrompt };
1743
1782
  const modified = await (0, hooks_1.executeHook)(hooks, 'beforeNonCodeTask', ncCtx, vm);
1744
1783
  nonCodePrompt = modified.prompt;
1745
1784
  }
@@ -1764,12 +1803,12 @@ async function implementNonCodeTask(task, config, provider, runners, hooks = {},
1764
1803
  if (!implemented) {
1765
1804
  logger_1.logger.error('All AI runners failed');
1766
1805
  const diagnostics = (0, diagnostics_1.collectAndLogDiagnostics)();
1767
- await provider.postComment(task.id, `${config.commentPrefix} All AI runners failed. Manual intervention needed.\n\n${diagnostics}`);
1806
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} All AI runners failed. Manual intervention needed.\n\n${diagnostics}`, config, provider, hooks, vm);
1768
1807
  return;
1769
1808
  }
1770
1809
  try {
1771
1810
  const comment = buildNonCodeCompletionComment(config, agentOutput);
1772
- await provider.postComment(task.id, comment);
1811
+ await (0, hooks_1.postCommentWithHooks)(task, comment, config, provider, hooks, vm);
1773
1812
  await provider.updateStatus(task.id, getInReviewStatus(config));
1774
1813
  }
1775
1814
  catch (err) {
@@ -1778,7 +1817,7 @@ async function implementNonCodeTask(task, config, provider, runners, hooks = {},
1778
1817
  // afterNonCodeTask hook
1779
1818
  if (vm) {
1780
1819
  const afterCtx = {
1781
- task, config, prompt: nonCodePrompt, success: true, output: agentOutput,
1820
+ task: safeTask, config, prompt: nonCodePrompt, success: true, output: agentOutput,
1782
1821
  };
1783
1822
  await (0, hooks_1.executeHook)(hooks, 'afterNonCodeTask', afterCtx, vm);
1784
1823
  }
@@ -1894,7 +1933,7 @@ async function implementNonCodeThinkingTask(task, config, provider, runners, hoo
1894
1933
  logger_1.logger.info(`Implementing non-code thinking task: ${task.name}`);
1895
1934
  try {
1896
1935
  await provider.updateStatus(task.id, 'in progress');
1897
- await provider.postComment(task.id, `${config.commentPrefix} Starting non-code task execution (thinking mode — will analyze and break into sub-tasks)`);
1936
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Starting non-code task execution (thinking mode — will analyze and break into sub-tasks)`, config, provider, hooks, vm);
1898
1937
  }
1899
1938
  catch (err) {
1900
1939
  logger_1.logger.warn(`Could not update task status: ${err}`);
@@ -1907,15 +1946,16 @@ async function implementNonCodeThinkingTask(task, config, provider, runners, hoo
1907
1946
  catch {
1908
1947
  // ignore
1909
1948
  }
1910
- const plan = await analyzeAndPlanNonCode(task, context, runners);
1949
+ const { task: safeTask, context: safeContext } = applySafeMode(task, context, config);
1950
+ const plan = await analyzeAndPlanNonCode(safeTask, safeContext, runners);
1911
1951
  if (!plan) {
1912
1952
  logger_1.logger.error('Failed to create non-code task plan');
1913
- await provider.postComment(task.id, `${config.commentPrefix} Failed to analyze and break down the non-code task. Manual intervention needed.`);
1953
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Failed to analyze and break down the non-code task. Manual intervention needed.`, config, provider, hooks, vm);
1914
1954
  return;
1915
1955
  }
1916
1956
  logger_1.logger.info(`Non-code task broken into ${plan.subtasks.length} sub-tasks`);
1917
1957
  try {
1918
- await provider.postComment(task.id, `${config.commentPrefix} Task analyzed and broken into ${plan.subtasks.length} sub-tasks:\n\n${formatSubtaskList(plan)}`);
1958
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Task analyzed and broken into ${plan.subtasks.length} sub-tasks:\n\n${formatSubtaskList(plan)}`, config, provider, hooks, vm);
1919
1959
  }
1920
1960
  catch (err) {
1921
1961
  logger_1.logger.warn(`Failed to post non-code breakdown comment: ${err}`);
@@ -1924,7 +1964,7 @@ async function implementNonCodeThinkingTask(task, config, provider, runners, hoo
1924
1964
  // branchName is empty because non-code tasks don't create a branch.
1925
1965
  if (vm) {
1926
1966
  const thinkCtx = {
1927
- task,
1967
+ task: safeTask,
1928
1968
  config,
1929
1969
  branchName: '',
1930
1970
  subtasks: plan.subtasks.map((s) => ({
@@ -1983,7 +2023,7 @@ async function implementNonCodeThinkingTask(task, config, provider, runners, hoo
1983
2023
  allSucceeded = false;
1984
2024
  logger_1.logger.error(` Non-code step ${formatSubtaskId(subtask.id)} failed: ${subtask.title}`);
1985
2025
  try {
1986
- await provider.postComment(task.id, `${config.commentPrefix} Step ${formatSubtaskId(subtask.id)} failed: ${subtask.title}\n\n${formatSubtaskList(plan)}`);
2026
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Step ${formatSubtaskId(subtask.id)} failed: ${subtask.title}\n\n${formatSubtaskList(plan)}`, config, provider, hooks, vm);
1987
2027
  }
1988
2028
  catch { /* ignore */ }
1989
2029
  break;
@@ -1991,7 +2031,7 @@ async function implementNonCodeThinkingTask(task, config, provider, runners, hoo
1991
2031
  // Post the sub-task summary BEFORE marking it done — per the task spec, the
1992
2032
  // comment is posted, then the sub-task is announced as complete.
1993
2033
  try {
1994
- await provider.postComment(task.id, `${config.commentPrefix} Step ${formatSubtaskId(subtask.id)}: ${subtask.title}\n\n---\n\n${summary}`);
2034
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Step ${formatSubtaskId(subtask.id)}: ${subtask.title}\n\n---\n\n${summary}`, config, provider, hooks, vm);
1995
2035
  }
1996
2036
  catch (err) {
1997
2037
  logger_1.logger.warn(`Failed to post summary for step ${formatSubtaskId(subtask.id)}: ${err}`);
@@ -2000,20 +2040,20 @@ async function implementNonCodeThinkingTask(task, config, provider, runners, hoo
2000
2040
  subtask.status = 'done';
2001
2041
  logger_1.logger.success(` Non-code step ${formatSubtaskId(subtask.id)} complete: ${subtask.title}`);
2002
2042
  try {
2003
- await provider.postComment(task.id, `${config.commentPrefix} Step ${formatSubtaskId(subtask.id)} complete: ${subtask.title}\n\n${formatSubtaskList(plan)}`);
2043
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Step ${formatSubtaskId(subtask.id)} complete: ${subtask.title}\n\n${formatSubtaskList(plan)}`, config, provider, hooks, vm);
2004
2044
  }
2005
2045
  catch { /* ignore */ }
2006
2046
  }
2007
2047
  if (!allSucceeded) {
2008
2048
  logger_1.logger.error('Non-code thinking task did not complete all sub-tasks');
2009
2049
  try {
2010
- await provider.postComment(task.id, `${config.commentPrefix} Non-code thinking task did not complete all sub-tasks. Manual intervention needed.`);
2050
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Non-code thinking task did not complete all sub-tasks. Manual intervention needed.`, config, provider, hooks, vm);
2011
2051
  }
2012
2052
  catch { /* ignore */ }
2013
2053
  return;
2014
2054
  }
2015
2055
  try {
2016
- await provider.postComment(task.id, buildNonCodeThinkingCompletionComment(config));
2056
+ await (0, hooks_1.postCommentWithHooks)(task, buildNonCodeThinkingCompletionComment(config), config, provider, hooks, vm);
2017
2057
  await provider.updateStatus(task.id, getInReviewStatus(config));
2018
2058
  if (config.thinkingTag && provider.removeTag) {
2019
2059
  try {
@@ -2083,7 +2123,7 @@ async function processReviewTask(task, config, provider, runners, screenAvailabl
2083
2123
  return 'skipped';
2084
2124
  }
2085
2125
  if (!screenAvailable) {
2086
- await notifySleeping(task, provider, config.commentPrefix);
2126
+ await notifySleeping(task, provider, config, hooks, vm);
2087
2127
  return 'skipped';
2088
2128
  }
2089
2129
  logger_1.logger.info(`[${task.id}] Found ${actionableThreads.length} actionable review thread(s) — resolving`);
@@ -2096,7 +2136,8 @@ async function implementReviewTask(task, branchName, config, provider, runners,
2096
2136
  logger_1.logger.error(`[${task.id}] Failed to checkout branch ${branchName}`);
2097
2137
  return;
2098
2138
  }
2099
- let reviewPrompt = buildReviewPrompt(task, threads);
2139
+ const { task: safeTask } = applySafeMode(task, '', config);
2140
+ let reviewPrompt = buildReviewPrompt(safeTask, threads);
2100
2141
  // beforeReviewTask hook
2101
2142
  if (vm) {
2102
2143
  const reviewCtx = { task, config, branchName, threads, prompt: reviewPrompt };
@@ -2123,7 +2164,7 @@ async function implementReviewTask(task, branchName, config, provider, runners,
2123
2164
  logger_1.logger.error(`[${task.id}] All AI runners failed to address review comments`);
2124
2165
  const diagnostics = (0, diagnostics_1.collectAndLogDiagnostics)();
2125
2166
  try {
2126
- await provider.postComment(task.id, `${config.commentPrefix} Failed to address code review comments automatically.\n\n${diagnostics}`);
2167
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} Failed to address code review comments automatically.\n\n${diagnostics}`, config, provider, hooks, vm);
2127
2168
  }
2128
2169
  catch { /* ignore */ }
2129
2170
  // afterReviewTask hook — failure
@@ -2169,7 +2210,7 @@ async function implementReviewTask(task, branchName, config, provider, runners,
2169
2210
  if (resolvedCount > 0 || repliedCount > 0) {
2170
2211
  try {
2171
2212
  const comment = buildReviewCompletionComment(config, resolvedCount, repliedCount);
2172
- await provider.postComment(task.id, comment);
2213
+ await (0, hooks_1.postCommentWithHooks)(task, comment, config, provider, hooks, vm);
2173
2214
  }
2174
2215
  catch { /* ignore */ }
2175
2216
  }