@qelos/aidev 1.2.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 (215) hide show
  1. package/.env.aidev.example +12 -1
  2. package/README.md +23 -6
  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 +1 -1
  22. package/dist/commands/run.d.ts.map +1 -1
  23. package/dist/commands/run.js +78 -63
  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/safeMode.d.ts +32 -0
  48. package/dist/safeMode.d.ts.map +1 -0
  49. package/dist/safeMode.js +192 -0
  50. package/dist/safeMode.js.map +1 -0
  51. package/dist/types.d.ts +3 -1
  52. package/dist/types.d.ts.map +1 -1
  53. package/package.json +2 -2
  54. package/ui/.output/nitro.json +1 -1
  55. package/ui/.output/public/_nuxt/6wLLp9Nc.js +1 -0
  56. package/ui/.output/public/_nuxt/BGkU0f28.js +1 -0
  57. package/ui/.output/public/_nuxt/BOIhDy_l.js +4 -0
  58. package/ui/.output/public/_nuxt/BWJzzHTi.js +1 -0
  59. package/ui/.output/public/_nuxt/{3LZdFtk_.js → By4xSvKt.js} +3 -3
  60. package/ui/.output/public/_nuxt/ByAMJ0xS.js +1 -0
  61. package/ui/.output/public/_nuxt/C1xk3ymy.js +1 -0
  62. package/ui/.output/public/_nuxt/CBV5GuL6.js +11 -0
  63. package/ui/.output/public/_nuxt/CTtW-0zG.js +1 -0
  64. package/ui/.output/public/_nuxt/CX0vIr0s.js +131 -0
  65. package/ui/.output/public/_nuxt/{LzHPbXPK.js → CYm8nRCj.js} +1 -1
  66. package/ui/.output/public/_nuxt/CdHqKVo4.js +1 -0
  67. package/ui/.output/public/_nuxt/CnXdKLRd.js +16 -0
  68. package/ui/.output/public/_nuxt/Cz9dogwK.js +1 -0
  69. package/ui/.output/public/_nuxt/DGHfexQZ.js +1 -0
  70. package/ui/.output/public/_nuxt/{CWjftssB.js → DOoocm0F.js} +1 -1
  71. package/ui/.output/public/_nuxt/{DZd8Jv5H.js → D_gcbXK2.js} +1 -1
  72. package/ui/.output/public/_nuxt/{CO4XMBYO.js → Dfhp6TEA.js} +11 -11
  73. package/ui/.output/public/_nuxt/{BtD1YBwM.js → G5BjvTWO.js} +1 -1
  74. package/ui/.output/public/_nuxt/H73b_QUy.js +1 -0
  75. package/ui/.output/public/_nuxt/{BMTHyzVP.js → LCoCV2KL.js} +1 -1
  76. package/ui/.output/public/_nuxt/Zrl3Utak.js +1 -0
  77. package/ui/.output/public/_nuxt/config.CaB_F_OT.css +1 -0
  78. package/ui/.output/public/_nuxt/default.D13_FS9T.css +1 -0
  79. package/ui/.output/public/_nuxt/hooks.B03-GWTh.css +1 -0
  80. package/ui/.output/public/_nuxt/kPPYUzXr.js +2 -0
  81. package/ui/.output/public/_nuxt/logs.DLMkvOEl.css +1 -0
  82. package/ui/.output/public/_nuxt/mHp9eItY.js +1 -0
  83. package/ui/.output/public/_nuxt/{BTfAgCfF.js → tyaD1vVi.js} +1 -1
  84. package/ui/.output/public/_nuxt/{BGlShnpS.js → ynXKxjpn.js} +1 -1
  85. package/ui/.output/public/_nuxt/{B8sr5ZW-.js → yqBy-NAR.js} +2 -2
  86. package/ui/.output/server/chunks/_/hooksTemplate.mjs +365 -0
  87. package/ui/.output/server/chunks/_/hooksTemplate.mjs.map +1 -0
  88. package/ui/.output/server/chunks/build/{Badge-YPOjmkfv.mjs → Badge-nNgbDd8N.mjs} +2 -2
  89. package/ui/.output/server/chunks/build/{Badge-YPOjmkfv.mjs.map → Badge-nNgbDd8N.mjs.map} +1 -1
  90. package/ui/.output/server/chunks/build/{Button-CZHl6fpI.mjs → Button-CQZG7w2L.mjs} +117 -3
  91. package/ui/.output/server/chunks/build/Button-CQZG7w2L.mjs.map +1 -0
  92. package/ui/.output/server/chunks/build/{Card--ibiHV_r.mjs → Card-DdEnDTQW.mjs} +2 -2
  93. package/ui/.output/server/chunks/build/{Card--ibiHV_r.mjs.map → Card-DdEnDTQW.mjs.map} +1 -1
  94. package/ui/.output/server/chunks/build/{FormGroup-CX5VmH8y.mjs → FormGroup-BfYiVGgN.mjs} +2 -2
  95. package/ui/.output/server/chunks/build/{FormGroup-CX5VmH8y.mjs.map → FormGroup-BfYiVGgN.mjs.map} +1 -1
  96. package/ui/.output/server/chunks/build/{Input-kmqS1oY_.mjs → Input-Cnk3P_aB.mjs} +5 -60
  97. package/ui/.output/server/chunks/build/Input-Cnk3P_aB.mjs.map +1 -0
  98. package/ui/.output/server/chunks/build/{Modal-DmZs0Ekg.mjs → Modal-DfVO6DJD.mjs} +10 -5
  99. package/ui/.output/server/chunks/build/Modal-DfVO6DJD.mjs.map +1 -0
  100. package/ui/.output/server/chunks/build/{Select-n4_YfXfk.mjs → Select-Dc9_TJIR.mjs} +3 -3
  101. package/ui/.output/server/chunks/build/{Select-n4_YfXfk.mjs.map → Select-Dc9_TJIR.mjs.map} +1 -1
  102. package/ui/.output/server/chunks/build/client.precomputed.mjs +1 -1
  103. package/ui/.output/server/chunks/build/client.precomputed.mjs.map +1 -1
  104. package/ui/.output/server/chunks/build/{config-Bkb2wy7R.mjs → config-BUokZPak.mjs} +78 -58
  105. package/ui/.output/server/chunks/build/config-BUokZPak.mjs.map +1 -0
  106. package/ui/.output/server/chunks/build/config-styles.irltMnuD.mjs +8 -0
  107. package/ui/.output/server/chunks/build/config-styles.irltMnuD.mjs.map +1 -0
  108. package/ui/.output/server/chunks/build/{default-DmD3qBXZ.mjs → default-6TcwTt3p.mjs} +10 -9
  109. package/ui/.output/server/chunks/build/default-6TcwTt3p.mjs.map +1 -0
  110. package/ui/.output/server/chunks/build/default-styles.BqL9zxh4.mjs +8 -0
  111. package/ui/.output/server/chunks/build/default-styles.BqL9zxh4.mjs.map +1 -0
  112. package/ui/.output/server/chunks/build/entry-styles.q-b4rEBh.mjs +11 -0
  113. package/ui/.output/server/chunks/build/entry-styles.q-b4rEBh.mjs.map +1 -0
  114. package/ui/.output/server/chunks/build/hooks-k2ZmlVpA.mjs +4181 -0
  115. package/ui/.output/server/chunks/build/hooks-k2ZmlVpA.mjs.map +1 -0
  116. package/ui/.output/server/chunks/build/hooks-styles.Ddk4F_Gj.mjs +8 -0
  117. package/ui/.output/server/chunks/build/hooks-styles.Ddk4F_Gj.mjs.map +1 -0
  118. package/ui/.output/server/chunks/build/{index-Dy4Tu7MB.mjs → index-DwMIJp2e.mjs} +7 -3
  119. package/ui/.output/server/chunks/build/index-DwMIJp2e.mjs.map +1 -0
  120. package/ui/.output/server/chunks/build/{index-BvfXQQ2n.mjs → index-JLPhao-C.mjs} +5 -5
  121. package/ui/.output/server/chunks/build/{index-BvfXQQ2n.mjs.map → index-JLPhao-C.mjs.map} +1 -1
  122. package/ui/.output/server/chunks/build/{interval-DHZqEf-n.mjs → interval-DPa3fpS0.mjs} +3 -3
  123. package/ui/.output/server/chunks/build/{interval-DHZqEf-n.mjs.map → interval-DPa3fpS0.mjs.map} +1 -1
  124. package/ui/.output/server/chunks/build/{login-B5YkLJCV.mjs → login-D9DpNq3o.mjs} +6 -5
  125. package/ui/.output/server/chunks/build/login-D9DpNq3o.mjs.map +1 -0
  126. package/ui/.output/server/chunks/build/{logs-BvD1Y3HI.mjs → logs-BVuWOSb6.mjs} +49 -31
  127. package/ui/.output/server/chunks/build/logs-BVuWOSb6.mjs.map +1 -0
  128. package/ui/.output/server/chunks/build/logs-styles.C2Mi0JvX.mjs +8 -0
  129. package/ui/.output/server/chunks/build/logs-styles.C2Mi0JvX.mjs.map +1 -0
  130. package/ui/.output/server/chunks/build/{run-BStPkbGg.mjs → run-BVQZSGcX.mjs} +5 -5
  131. package/ui/.output/server/chunks/build/{run-BStPkbGg.mjs.map → run-BVQZSGcX.mjs.map} +1 -1
  132. package/ui/.output/server/chunks/build/{schedule-B2UKsnRW.mjs → schedule-rRz2CwWh.mjs} +10 -9
  133. package/ui/.output/server/chunks/build/schedule-rRz2CwWh.mjs.map +1 -0
  134. package/ui/.output/server/chunks/build/server.mjs +14 -9
  135. package/ui/.output/server/chunks/build/server.mjs.map +1 -1
  136. package/ui/.output/server/chunks/build/styles.mjs +7 -6
  137. package/ui/.output/server/chunks/build/styles.mjs.map +1 -1
  138. package/ui/.output/server/chunks/build/{tasks-DBH3Z6lg.mjs → tasks-DJjZQWcq.mjs} +10 -9
  139. package/ui/.output/server/chunks/build/tasks-DJjZQWcq.mjs.map +1 -0
  140. package/ui/.output/server/chunks/build/{useApi-Bqajqsuz.mjs → useApi-Brbyp7hV.mjs} +3 -3
  141. package/ui/.output/server/chunks/build/useApi-Brbyp7hV.mjs.map +1 -0
  142. package/ui/.output/server/chunks/build/useFormGroup-DqE91r20.mjs +61 -0
  143. package/ui/.output/server/chunks/build/useFormGroup-DqE91r20.mjs.map +1 -0
  144. package/ui/.output/server/chunks/nitro/nitro.mjs +195 -157
  145. package/ui/.output/server/chunks/routes/api/config/test.post.mjs +1 -1
  146. package/ui/.output/server/chunks/routes/api/config/test.post.mjs.map +1 -1
  147. package/ui/.output/server/chunks/routes/api/hooks-execute.post.mjs +83 -0
  148. package/ui/.output/server/chunks/routes/api/hooks-execute.post.mjs.map +1 -0
  149. package/ui/.output/server/chunks/routes/api/hooks-regenerate.post.mjs +30 -0
  150. package/ui/.output/server/chunks/routes/api/hooks-regenerate.post.mjs.map +1 -0
  151. package/ui/.output/server/chunks/routes/api/hooks-update.post.mjs +31 -0
  152. package/ui/.output/server/chunks/routes/api/hooks-update.post.mjs.map +1 -0
  153. package/ui/.output/server/chunks/routes/api/hooks.get.mjs +28 -0
  154. package/ui/.output/server/chunks/routes/api/hooks.get.mjs.map +1 -0
  155. package/ui/.output/server/chunks/routes/api/hooks.put.mjs +32 -0
  156. package/ui/.output/server/chunks/routes/api/hooks.put.mjs.map +1 -0
  157. package/ui/.output/server/chunks/routes/api/logs.get.mjs +7 -2
  158. package/ui/.output/server/chunks/routes/api/logs.get.mjs.map +1 -1
  159. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/_virtual/_rollupPluginBabelHelpers.js +123 -0
  160. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/config/index.js +11 -0
  161. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/index.js +9 -0
  162. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/loader/index.js +175 -0
  163. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/utils/compose.js +16 -0
  164. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/utils/curry.js +20 -0
  165. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/utils/deepMerge.js +18 -0
  166. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/utils/isObject.js +9 -0
  167. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/utils/makeCancelable.js +25 -0
  168. package/ui/.output/server/node_modules/@monaco-editor/loader/lib/cjs/validators/index.js +49 -0
  169. package/ui/.output/server/node_modules/@monaco-editor/loader/package.json +51 -0
  170. package/ui/.output/server/node_modules/@tanstack/virtual-core/dist/esm/index.js +1197 -0
  171. package/ui/.output/server/node_modules/@tanstack/virtual-core/dist/esm/lazy-measurements.js +34 -0
  172. package/ui/.output/server/node_modules/@tanstack/virtual-core/dist/esm/utils.js +74 -0
  173. package/ui/.output/server/node_modules/@tanstack/virtual-core/package.json +56 -0
  174. package/ui/.output/server/node_modules/@tanstack/vue-virtual/dist/esm/index.js +66 -0
  175. package/ui/.output/server/node_modules/@tanstack/vue-virtual/package.json +68 -0
  176. package/ui/.output/server/node_modules/state-local/lib/cjs/state-local.js +195 -0
  177. package/ui/.output/server/node_modules/state-local/package.json +59 -0
  178. package/ui/.output/server/package.json +4 -0
  179. package/ui/package.json +1 -0
  180. package/ui/.output/public/_nuxt/B93YYUZf.js +0 -1
  181. package/ui/.output/public/_nuxt/BAs1isOw.js +0 -1
  182. package/ui/.output/public/_nuxt/BrZL2iQr.js +0 -1
  183. package/ui/.output/public/_nuxt/Bv6Ws9vz.js +0 -1
  184. package/ui/.output/public/_nuxt/C2WdrjFS.js +0 -1
  185. package/ui/.output/public/_nuxt/CVTgFccA.js +0 -2
  186. package/ui/.output/public/_nuxt/Ceb2855t.js +0 -1
  187. package/ui/.output/public/_nuxt/Cg55PjEy.js +0 -4
  188. package/ui/.output/public/_nuxt/D0ZgktSu.js +0 -1
  189. package/ui/.output/public/_nuxt/DZIUG6ZX.js +0 -1
  190. package/ui/.output/public/_nuxt/DihqGT4A.js +0 -1
  191. package/ui/.output/public/_nuxt/MzK2TZ-I.js +0 -16
  192. package/ui/.output/public/_nuxt/TJXLPQOj.js +0 -1
  193. package/ui/.output/public/_nuxt/VuiIFQtE.js +0 -1
  194. package/ui/.output/public/_nuxt/config.C19X1GwO.css +0 -1
  195. package/ui/.output/public/_nuxt/default.Dw-0Xw5D.css +0 -1
  196. package/ui/.output/public/_nuxt/logs.PK6CTQHM.css +0 -1
  197. package/ui/.output/server/chunks/build/Button-CZHl6fpI.mjs.map +0 -1
  198. package/ui/.output/server/chunks/build/Input-kmqS1oY_.mjs.map +0 -1
  199. package/ui/.output/server/chunks/build/Modal-DmZs0Ekg.mjs.map +0 -1
  200. package/ui/.output/server/chunks/build/config-Bkb2wy7R.mjs.map +0 -1
  201. package/ui/.output/server/chunks/build/config-styles.B4mTchgT.mjs +0 -8
  202. package/ui/.output/server/chunks/build/config-styles.B4mTchgT.mjs.map +0 -1
  203. package/ui/.output/server/chunks/build/default-DmD3qBXZ.mjs.map +0 -1
  204. package/ui/.output/server/chunks/build/default-styles.DmprFUrQ.mjs +0 -8
  205. package/ui/.output/server/chunks/build/default-styles.DmprFUrQ.mjs.map +0 -1
  206. package/ui/.output/server/chunks/build/entry-styles.Cg1Sndbr.mjs +0 -11
  207. package/ui/.output/server/chunks/build/entry-styles.Cg1Sndbr.mjs.map +0 -1
  208. package/ui/.output/server/chunks/build/index-Dy4Tu7MB.mjs.map +0 -1
  209. package/ui/.output/server/chunks/build/login-B5YkLJCV.mjs.map +0 -1
  210. package/ui/.output/server/chunks/build/logs-BvD1Y3HI.mjs.map +0 -1
  211. package/ui/.output/server/chunks/build/logs-styles.CU5b1wKf.mjs +0 -8
  212. package/ui/.output/server/chunks/build/logs-styles.CU5b1wKf.mjs.map +0 -1
  213. package/ui/.output/server/chunks/build/schedule-B2UKsnRW.mjs.map +0 -1
  214. package/ui/.output/server/chunks/build/tasks-DBH3Z6lg.mjs.map +0 -1
  215. package/ui/.output/server/chunks/build/useApi-Bqajqsuz.mjs.map +0 -1
@@ -89,6 +89,14 @@ const activeTask_1 = require("../activeTask");
89
89
  const hooks_1 = require("../hooks");
90
90
  const sessions_1 = require("../sessions");
91
91
  const accepted_1 = require("./accepted");
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
+ }
92
100
  const SKIP_STATUSES = new Set(['closed', 'done', 'cancelled', 'complete', 'resolved', 'completed']);
93
101
  const NO_PRIORITY = Number.MAX_SAFE_INTEGER;
94
102
  const SLEEPING_MARKER = 'machine appears to be asleep';
@@ -570,18 +578,18 @@ async function processTask(task, filter, config, provider, runners, screenAvaila
570
578
  logger_1.logger.info(`Trigger word "${config.triggerWord}" found — re-processing task`);
571
579
  }
572
580
  if (!screenAvailable) {
573
- await notifySleeping(task, provider, config.commentPrefix);
581
+ await notifySleeping(task, provider, config, hooks, vm);
574
582
  return 'skipped';
575
583
  }
576
584
  }
577
585
  else {
578
586
  if (!screenAvailable) {
579
- await notifySleeping(task, provider, config.commentPrefix);
587
+ await notifySleeping(task, provider, config, hooks, vm);
580
588
  return 'skipped';
581
589
  }
582
590
  const clarification = await checkNeedsClarification(task, config, provider, runners);
583
591
  if (clarification) {
584
- await provider.postComment(task.id, `${config.commentPrefix} ${clarification}`);
592
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} ${clarification}`, config, provider, hooks, vm);
585
593
  await provider.updateStatus(task.id, getPendingStatus(config));
586
594
  logger_1.logger.info(`Posted clarification question, set status to ${getPendingStatus(config)}`);
587
595
  return 'skipped';
@@ -647,7 +655,7 @@ function hasTriggerWord(comments, triggerWord) {
647
655
  return true;
648
656
  return false;
649
657
  }
650
- async function notifySleeping(task, provider, commentPrefix) {
658
+ async function notifySleeping(task, provider, config, hooks, vm) {
651
659
  try {
652
660
  const comments = await provider.getComments(task.id);
653
661
  const lastComment = comments.length > 0 ? comments[comments.length - 1] : null;
@@ -660,8 +668,8 @@ async function notifySleeping(task, provider, commentPrefix) {
660
668
  // If we can't check comments, still attempt to post
661
669
  }
662
670
  try {
663
- await provider.postComment(task.id, `${commentPrefix} Cannot work on this task — the ${SLEEPING_MARKER} or the screen is locked. ` +
664
- '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);
665
673
  logger_1.logger.info(`[${task.id}] Posted sleep notification`);
666
674
  }
667
675
  catch (err) {
@@ -761,12 +769,13 @@ async function resolveConflictsWithAI(task, config, provider, runners, context,
761
769
  logger_1.logger.warn(`Branch has conflicts with ${config.githubBaseBranch} in ${check.conflictFiles.length} file(s): ` +
762
770
  check.conflictFiles.join(', '));
763
771
  try {
764
- await provider.postComment(task.id, `${config.commentPrefix} Branch \`${branchName}\` has merge conflicts with \`${config.githubBaseBranch}\` ` +
765
- `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);
766
774
  }
767
775
  catch { /* ignore */ }
768
776
  if (!git.mergeBaseBranch(config.gitRemote, config.githubBaseBranch)) {
769
- 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);
770
779
  // beforeResolveConflicts hook
771
780
  if (vm) {
772
781
  const conflictCtx = { task, config, branchName, conflictFiles: check.conflictFiles, prompt };
@@ -811,7 +820,7 @@ async function resolveConflictsWithAI(task, config, provider, runners, context,
811
820
  git.abortMerge();
812
821
  }
813
822
  try {
814
- 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);
815
824
  }
816
825
  catch { /* ignore */ }
817
826
  return false;
@@ -833,7 +842,7 @@ async function resolveConflictsWithAI(task, config, provider, runners, context,
833
842
  await (0, hooks_1.executeHook)(hooks, 'afterResolveConflicts', afterCtx, vm);
834
843
  }
835
844
  try {
836
- 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);
837
846
  }
838
847
  catch { /* ignore */ }
839
848
  }
@@ -887,7 +896,7 @@ async function implementTask(task, branchName, branchExists, config, provider, r
887
896
  try {
888
897
  await provider.updateStatus(task.id, 'in progress');
889
898
  const verb = branchExists ? 'Continuing' : 'Starting';
890
- 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);
891
900
  }
892
901
  catch (err) {
893
902
  logger_1.logger.warn(`Could not update task status: ${err}`);
@@ -895,7 +904,7 @@ async function implementTask(task, branchName, branchExists, config, provider, r
895
904
  if (branchExists) {
896
905
  if (!git.fetchAndCheckoutBranch(config.gitRemote, branchName)) {
897
906
  logger_1.logger.error(`Failed to checkout existing branch ${branchName}`);
898
- 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);
899
908
  return;
900
909
  }
901
910
  logger_1.logger.info(`Continuing on existing branch: ${branchName}`);
@@ -903,7 +912,7 @@ async function implementTask(task, branchName, branchExists, config, provider, r
903
912
  else {
904
913
  if (!git.createBranchFromRemote(config.gitRemote, config.githubBaseBranch, branchName)) {
905
914
  logger_1.logger.error(`Failed to create branch ${branchName} from ${config.gitRemote}/${config.githubBaseBranch}`);
906
- 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);
907
916
  return;
908
917
  }
909
918
  }
@@ -930,10 +939,11 @@ async function implementTask(task, branchName, branchExists, config, provider, r
930
939
  logger_1.logger.info(`Found ${reviewThreads.length} unresolved review comment(s) to address`);
931
940
  context += formatReviewComments(reviewThreads);
932
941
  }
933
- let implementPrompt = buildImplementPrompt(task, context);
942
+ const { task: safeTask, context: safeContext } = applySafeMode(task, context, config);
943
+ let implementPrompt = buildImplementPrompt(safeTask, safeContext);
934
944
  // beforeEachTask hook — may modify context (e.g. improve the prompt)
935
945
  if (vm) {
936
- const taskCtx = { task, config, branchName, prompt: implementPrompt };
946
+ const taskCtx = { task: safeTask, config, branchName, prompt: implementPrompt };
937
947
  const modified = await (0, hooks_1.executeHook)(hooks, 'beforeEachTask', taskCtx, vm);
938
948
  implementPrompt = modified.prompt;
939
949
  }
@@ -968,7 +978,7 @@ async function implementTask(task, branchName, branchExists, config, provider, r
968
978
  if (!implemented) {
969
979
  logger_1.logger.error('All AI runners failed or produced no changes');
970
980
  const diagnostics = (0, diagnostics_1.collectAndLogDiagnostics)();
971
- 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);
972
982
  if (!branchExists) {
973
983
  git.deleteBranch(branchName);
974
984
  }
@@ -992,7 +1002,7 @@ async function implementTask(task, branchName, branchExists, config, provider, r
992
1002
  try {
993
1003
  const prUrl = tryCreatePR(config, branchName, task);
994
1004
  const comment = buildCompletionComment(branchName, prUrl, config);
995
- await provider.postComment(task.id, comment);
1005
+ await (0, hooks_1.postCommentWithHooks)(task, comment, config, provider, hooks, vm);
996
1006
  await provider.updateStatus(task.id, getInReviewStatus(config));
997
1007
  }
998
1008
  catch (err) {
@@ -1209,7 +1219,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1209
1219
  try {
1210
1220
  await provider.updateStatus(task.id, 'in progress');
1211
1221
  const verb = branchExists ? 'Continuing' : 'Starting';
1212
- 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);
1213
1223
  }
1214
1224
  catch (err) {
1215
1225
  logger_1.logger.warn(`Could not update task status: ${err}`);
@@ -1217,7 +1227,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1217
1227
  if (branchExists) {
1218
1228
  if (!git.fetchAndCheckoutBranch(config.gitRemote, branchName)) {
1219
1229
  logger_1.logger.error(`Failed to checkout existing branch ${branchName}`);
1220
- 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);
1221
1231
  return;
1222
1232
  }
1223
1233
  logger_1.logger.info(`Continuing on existing branch: ${branchName}`);
@@ -1225,7 +1235,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1225
1235
  else {
1226
1236
  if (!git.createBranchFromRemote(config.gitRemote, config.githubBaseBranch, branchName)) {
1227
1237
  logger_1.logger.error(`Failed to create branch ${branchName} from ${config.gitRemote}/${config.githubBaseBranch}`);
1228
- 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);
1229
1239
  return;
1230
1240
  }
1231
1241
  }
@@ -1254,16 +1264,17 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1254
1264
  logger_1.logger.info(`Found ${reviewThreads.length} unresolved review comment(s) to address`);
1255
1265
  context += reviewContext;
1256
1266
  }
1267
+ const { task: safeTask, context: safeContext } = applySafeMode(task, context, config);
1257
1268
  // Check for an existing plan (resume scenario)
1258
1269
  let plan = readTaskPlan(task.id);
1259
1270
  if (plan) {
1260
1271
  logger_1.logger.info(`Found existing task plan with ${plan.subtasks.length} sub-tasks — resuming`);
1261
1272
  }
1262
1273
  else {
1263
- plan = await analyzeAndPlan(task, context, runners);
1274
+ plan = await analyzeAndPlan(safeTask, safeContext, runners);
1264
1275
  if (!plan) {
1265
1276
  logger_1.logger.error('Failed to create implementation plan');
1266
- 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);
1267
1278
  cleanupThinkingFiles(task.id);
1268
1279
  if (!branchExists)
1269
1280
  git.deleteBranch(branchName);
@@ -1271,7 +1282,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1271
1282
  }
1272
1283
  logger_1.logger.info(`Task broken into ${plan.subtasks.length} sub-tasks`);
1273
1284
  try {
1274
- 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);
1275
1286
  }
1276
1287
  catch (err) {
1277
1288
  logger_1.logger.warn(`Failed to post breakdown comment: ${err}`);
@@ -1280,7 +1291,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1280
1291
  // beforeThinkingTask hook — may adjust subtask titles/descriptions before execution
1281
1292
  if (vm) {
1282
1293
  const thinkCtx = {
1283
- task,
1294
+ task: safeTask,
1284
1295
  config,
1285
1296
  branchName,
1286
1297
  subtasks: plan.subtasks.map((s) => ({
@@ -1328,7 +1339,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1328
1339
  const newIds = newSubtasks.map((s) => s.id).join(', ');
1329
1340
  logger_1.logger.info(` Step ${failedId} was split into ${newIds}`);
1330
1341
  try {
1331
- 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);
1332
1343
  }
1333
1344
  catch { /* ignore */ }
1334
1345
  i--; // re-process this index — it now points at the first new sub-task
@@ -1336,14 +1347,14 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1336
1347
  }
1337
1348
  logger_1.logger.warn(` Could not split failed step ${failedId} — falling back to plain retry`);
1338
1349
  try {
1339
- 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);
1340
1351
  }
1341
1352
  catch { /* ignore */ }
1342
1353
  }
1343
1354
  else if (!isGitFailure && attempts >= 2 && depth >= 2) {
1344
1355
  logger_1.logger.warn(` Step ${subtask.id} has reached the split-depth cap — manual intervention may be needed`);
1345
1356
  try {
1346
- 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);
1347
1358
  }
1348
1359
  catch { /* ignore */ }
1349
1360
  }
@@ -1353,7 +1364,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1353
1364
  subtask.attempts = (subtask.attempts ?? 0) + 1;
1354
1365
  writeTaskPlan(plan);
1355
1366
  logger_1.logger.info(` Starting step ${subtask.id}: ${subtask.title} (attempt ${subtask.attempts})`);
1356
- 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);
1357
1368
  if (!success) {
1358
1369
  const diagnostics = (0, diagnostics_1.collectAndLogDiagnostics)();
1359
1370
  subtask.status = 'failed';
@@ -1362,7 +1373,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1362
1373
  allSucceeded = false;
1363
1374
  logger_1.logger.error(` Step ${subtask.id} failed: ${subtask.title}`);
1364
1375
  try {
1365
- 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);
1366
1377
  }
1367
1378
  catch { /* ignore */ }
1368
1379
  break;
@@ -1387,7 +1398,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1387
1398
  writeTaskPlan(plan);
1388
1399
  logger_1.logger.success(` Step ${subtask.id} complete: ${subtask.title}`);
1389
1400
  try {
1390
- 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);
1391
1402
  }
1392
1403
  catch { /* ignore */ }
1393
1404
  }
@@ -1395,7 +1406,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1395
1406
  logger_1.logger.error('Thinking task did not complete all sub-tasks');
1396
1407
  try {
1397
1408
  const diagnostics = (0, diagnostics_1.collectAndLogDiagnostics)();
1398
- 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);
1399
1410
  }
1400
1411
  catch { /* ignore */ }
1401
1412
  return;
@@ -1407,7 +1418,7 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1407
1418
  try {
1408
1419
  const prUrl = tryCreatePR(config, branchName, task);
1409
1420
  const comment = buildCompletionComment(branchName, prUrl, config);
1410
- await provider.postComment(task.id, comment);
1421
+ await (0, hooks_1.postCommentWithHooks)(task, comment, config, provider, hooks, vm);
1411
1422
  await provider.updateStatus(task.id, getInReviewStatus(config));
1412
1423
  if (config.thinkingTag && provider.removeTag) {
1413
1424
  try {
@@ -1430,11 +1441,11 @@ async function implementThinkingTask(task, branchName, branchExists, config, pro
1430
1441
  }
1431
1442
  logger_1.logger.success(`Thinking task implemented: branch ${branchName} pushed`);
1432
1443
  }
1433
- async function implementPlanningTask(task, config, provider, runners, _hooks = {}, _vm) {
1444
+ async function implementPlanningTask(task, config, provider, runners, hooks = {}, vm) {
1434
1445
  logger_1.logger.info(`Implementing planning task: ${task.name}`);
1435
1446
  try {
1436
1447
  await provider.updateStatus(task.id, 'in progress');
1437
- 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);
1438
1449
  }
1439
1450
  catch (err) {
1440
1451
  logger_1.logger.warn(`Could not update task status: ${err}`);
@@ -1447,7 +1458,8 @@ async function implementPlanningTask(task, config, provider, runners, _hooks = {
1447
1458
  catch {
1448
1459
  // ignore
1449
1460
  }
1450
- const prompt = buildPlanningAnalysisPrompt(task, context);
1461
+ const { task: safeTask, context: safeContext } = applySafeMode(task, context, config);
1462
+ const prompt = buildPlanningAnalysisPrompt(safeTask, safeContext);
1451
1463
  let parsed = null;
1452
1464
  let previousNotes = '';
1453
1465
  for (const runner of runners) {
@@ -1469,14 +1481,14 @@ async function implementPlanningTask(task, config, provider, runners, _hooks = {
1469
1481
  if (!parsed) {
1470
1482
  logger_1.logger.error('Planning produced no sub-tasks');
1471
1483
  try {
1472
- 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);
1473
1485
  }
1474
1486
  catch { /* ignore */ }
1475
1487
  return;
1476
1488
  }
1477
1489
  if (parsed.clarification) {
1478
1490
  try {
1479
- await provider.postComment(task.id, `${config.commentPrefix} ${parsed.clarification}`);
1491
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} ${parsed.clarification}`, config, provider, hooks, vm);
1480
1492
  await provider.updateStatus(task.id, getPendingStatus(config));
1481
1493
  logger_1.logger.info(`Posted planning clarification, set status to ${getPendingStatus(config)}`);
1482
1494
  }
@@ -1488,7 +1500,7 @@ async function implementPlanningTask(task, config, provider, runners, _hooks = {
1488
1500
  if (parsed.subtasks.length === 0) {
1489
1501
  logger_1.logger.error('Planning produced no sub-tasks');
1490
1502
  try {
1491
- 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);
1492
1504
  }
1493
1505
  catch { /* ignore */ }
1494
1506
  return;
@@ -1533,7 +1545,7 @@ async function implementPlanningTask(task, config, provider, runners, _hooks = {
1533
1545
  }
1534
1546
  }
1535
1547
  try {
1536
- await provider.postComment(task.id, summaryLines.join('\n'));
1548
+ await (0, hooks_1.postCommentWithHooks)(task, summaryLines.join('\n'), config, provider, hooks, vm);
1537
1549
  }
1538
1550
  catch (err) {
1539
1551
  logger_1.logger.warn(`Failed to post planning summary: ${err instanceof Error ? err.message : err}`);
@@ -1711,18 +1723,18 @@ async function processNonCodeTask(task, filter, config, provider, runners, scree
1711
1723
  : 'Human follow-up comment found — processing non-code task');
1712
1724
  }
1713
1725
  if (!screenAvailable) {
1714
- await notifySleeping(task, provider, config.commentPrefix);
1726
+ await notifySleeping(task, provider, config, hooks, vm);
1715
1727
  return 'skipped';
1716
1728
  }
1717
1729
  }
1718
1730
  else {
1719
1731
  if (!screenAvailable) {
1720
- await notifySleeping(task, provider, config.commentPrefix);
1732
+ await notifySleeping(task, provider, config, hooks, vm);
1721
1733
  return 'skipped';
1722
1734
  }
1723
1735
  const clarification = await checkNeedsClarification(task, config, provider, runners);
1724
1736
  if (clarification) {
1725
- await provider.postComment(task.id, `${config.commentPrefix} ${clarification}`);
1737
+ await (0, hooks_1.postCommentWithHooks)(task, `${config.commentPrefix} ${clarification}`, config, provider, hooks, vm);
1726
1738
  await provider.updateStatus(task.id, getPendingStatus(config));
1727
1739
  logger_1.logger.info(`Posted clarification question, set status to ${getPendingStatus(config)}`);
1728
1740
  return 'skipped';
@@ -1749,7 +1761,7 @@ async function implementNonCodeTask(task, config, provider, runners, hooks = {},
1749
1761
  logger_1.logger.info(`Implementing non-code task: ${task.name}`);
1750
1762
  try {
1751
1763
  await provider.updateStatus(task.id, 'in progress');
1752
- 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);
1753
1765
  }
1754
1766
  catch (err) {
1755
1767
  logger_1.logger.warn(`Could not update task status: ${err}`);
@@ -1762,10 +1774,11 @@ async function implementNonCodeTask(task, config, provider, runners, hooks = {},
1762
1774
  catch {
1763
1775
  // ignore
1764
1776
  }
1765
- let nonCodePrompt = buildNonCodePrompt(task, context);
1777
+ const { task: safeTask, context: safeContext } = applySafeMode(task, context, config);
1778
+ let nonCodePrompt = buildNonCodePrompt(safeTask, safeContext);
1766
1779
  // beforeNonCodeTask hook
1767
1780
  if (vm) {
1768
- const ncCtx = { task, config, prompt: nonCodePrompt };
1781
+ const ncCtx = { task: safeTask, config, prompt: nonCodePrompt };
1769
1782
  const modified = await (0, hooks_1.executeHook)(hooks, 'beforeNonCodeTask', ncCtx, vm);
1770
1783
  nonCodePrompt = modified.prompt;
1771
1784
  }
@@ -1790,12 +1803,12 @@ async function implementNonCodeTask(task, config, provider, runners, hooks = {},
1790
1803
  if (!implemented) {
1791
1804
  logger_1.logger.error('All AI runners failed');
1792
1805
  const diagnostics = (0, diagnostics_1.collectAndLogDiagnostics)();
1793
- 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);
1794
1807
  return;
1795
1808
  }
1796
1809
  try {
1797
1810
  const comment = buildNonCodeCompletionComment(config, agentOutput);
1798
- await provider.postComment(task.id, comment);
1811
+ await (0, hooks_1.postCommentWithHooks)(task, comment, config, provider, hooks, vm);
1799
1812
  await provider.updateStatus(task.id, getInReviewStatus(config));
1800
1813
  }
1801
1814
  catch (err) {
@@ -1804,7 +1817,7 @@ async function implementNonCodeTask(task, config, provider, runners, hooks = {},
1804
1817
  // afterNonCodeTask hook
1805
1818
  if (vm) {
1806
1819
  const afterCtx = {
1807
- task, config, prompt: nonCodePrompt, success: true, output: agentOutput,
1820
+ task: safeTask, config, prompt: nonCodePrompt, success: true, output: agentOutput,
1808
1821
  };
1809
1822
  await (0, hooks_1.executeHook)(hooks, 'afterNonCodeTask', afterCtx, vm);
1810
1823
  }
@@ -1920,7 +1933,7 @@ async function implementNonCodeThinkingTask(task, config, provider, runners, hoo
1920
1933
  logger_1.logger.info(`Implementing non-code thinking task: ${task.name}`);
1921
1934
  try {
1922
1935
  await provider.updateStatus(task.id, 'in progress');
1923
- 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);
1924
1937
  }
1925
1938
  catch (err) {
1926
1939
  logger_1.logger.warn(`Could not update task status: ${err}`);
@@ -1933,15 +1946,16 @@ async function implementNonCodeThinkingTask(task, config, provider, runners, hoo
1933
1946
  catch {
1934
1947
  // ignore
1935
1948
  }
1936
- 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);
1937
1951
  if (!plan) {
1938
1952
  logger_1.logger.error('Failed to create non-code task plan');
1939
- 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);
1940
1954
  return;
1941
1955
  }
1942
1956
  logger_1.logger.info(`Non-code task broken into ${plan.subtasks.length} sub-tasks`);
1943
1957
  try {
1944
- 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);
1945
1959
  }
1946
1960
  catch (err) {
1947
1961
  logger_1.logger.warn(`Failed to post non-code breakdown comment: ${err}`);
@@ -1950,7 +1964,7 @@ async function implementNonCodeThinkingTask(task, config, provider, runners, hoo
1950
1964
  // branchName is empty because non-code tasks don't create a branch.
1951
1965
  if (vm) {
1952
1966
  const thinkCtx = {
1953
- task,
1967
+ task: safeTask,
1954
1968
  config,
1955
1969
  branchName: '',
1956
1970
  subtasks: plan.subtasks.map((s) => ({
@@ -2009,7 +2023,7 @@ async function implementNonCodeThinkingTask(task, config, provider, runners, hoo
2009
2023
  allSucceeded = false;
2010
2024
  logger_1.logger.error(` Non-code step ${formatSubtaskId(subtask.id)} failed: ${subtask.title}`);
2011
2025
  try {
2012
- 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);
2013
2027
  }
2014
2028
  catch { /* ignore */ }
2015
2029
  break;
@@ -2017,7 +2031,7 @@ async function implementNonCodeThinkingTask(task, config, provider, runners, hoo
2017
2031
  // Post the sub-task summary BEFORE marking it done — per the task spec, the
2018
2032
  // comment is posted, then the sub-task is announced as complete.
2019
2033
  try {
2020
- 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);
2021
2035
  }
2022
2036
  catch (err) {
2023
2037
  logger_1.logger.warn(`Failed to post summary for step ${formatSubtaskId(subtask.id)}: ${err}`);
@@ -2026,20 +2040,20 @@ async function implementNonCodeThinkingTask(task, config, provider, runners, hoo
2026
2040
  subtask.status = 'done';
2027
2041
  logger_1.logger.success(` Non-code step ${formatSubtaskId(subtask.id)} complete: ${subtask.title}`);
2028
2042
  try {
2029
- 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);
2030
2044
  }
2031
2045
  catch { /* ignore */ }
2032
2046
  }
2033
2047
  if (!allSucceeded) {
2034
2048
  logger_1.logger.error('Non-code thinking task did not complete all sub-tasks');
2035
2049
  try {
2036
- 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);
2037
2051
  }
2038
2052
  catch { /* ignore */ }
2039
2053
  return;
2040
2054
  }
2041
2055
  try {
2042
- await provider.postComment(task.id, buildNonCodeThinkingCompletionComment(config));
2056
+ await (0, hooks_1.postCommentWithHooks)(task, buildNonCodeThinkingCompletionComment(config), config, provider, hooks, vm);
2043
2057
  await provider.updateStatus(task.id, getInReviewStatus(config));
2044
2058
  if (config.thinkingTag && provider.removeTag) {
2045
2059
  try {
@@ -2109,7 +2123,7 @@ async function processReviewTask(task, config, provider, runners, screenAvailabl
2109
2123
  return 'skipped';
2110
2124
  }
2111
2125
  if (!screenAvailable) {
2112
- await notifySleeping(task, provider, config.commentPrefix);
2126
+ await notifySleeping(task, provider, config, hooks, vm);
2113
2127
  return 'skipped';
2114
2128
  }
2115
2129
  logger_1.logger.info(`[${task.id}] Found ${actionableThreads.length} actionable review thread(s) — resolving`);
@@ -2122,7 +2136,8 @@ async function implementReviewTask(task, branchName, config, provider, runners,
2122
2136
  logger_1.logger.error(`[${task.id}] Failed to checkout branch ${branchName}`);
2123
2137
  return;
2124
2138
  }
2125
- let reviewPrompt = buildReviewPrompt(task, threads);
2139
+ const { task: safeTask } = applySafeMode(task, '', config);
2140
+ let reviewPrompt = buildReviewPrompt(safeTask, threads);
2126
2141
  // beforeReviewTask hook
2127
2142
  if (vm) {
2128
2143
  const reviewCtx = { task, config, branchName, threads, prompt: reviewPrompt };
@@ -2149,7 +2164,7 @@ async function implementReviewTask(task, branchName, config, provider, runners,
2149
2164
  logger_1.logger.error(`[${task.id}] All AI runners failed to address review comments`);
2150
2165
  const diagnostics = (0, diagnostics_1.collectAndLogDiagnostics)();
2151
2166
  try {
2152
- 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);
2153
2168
  }
2154
2169
  catch { /* ignore */ }
2155
2170
  // afterReviewTask hook — failure
@@ -2195,7 +2210,7 @@ async function implementReviewTask(task, branchName, config, provider, runners,
2195
2210
  if (resolvedCount > 0 || repliedCount > 0) {
2196
2211
  try {
2197
2212
  const comment = buildReviewCompletionComment(config, resolvedCount, repliedCount);
2198
- await provider.postComment(task.id, comment);
2213
+ await (0, hooks_1.postCommentWithHooks)(task, comment, config, provider, hooks, vm);
2199
2214
  }
2200
2215
  catch { /* ignore */ }
2201
2216
  }