commandmate 0.47.2 → 0.49.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 (434) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +180 -180
  3. package/.next/app-path-routes-manifest.json +30 -30
  4. package/.next/build-manifest.json +2 -2
  5. package/.next/prerender-manifest.json +9 -9
  6. package/.next/required-server-files.json +1 -1
  7. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  8. package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
  9. package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
  10. package/.next/server/app/api/app/release-notes/route_client-reference-manifest.js +1 -1
  11. package/.next/server/app/api/app/update/route.js +3 -3
  12. package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
  13. package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
  14. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  15. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  16. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  17. package/.next/server/app/api/capabilities/route.js +1 -1
  18. package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
  19. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  20. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  21. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  22. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  23. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  24. package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
  25. package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
  26. package/.next/server/app/api/hooks/agent-event/route.js +2 -2
  27. package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
  28. package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
  29. package/.next/server/app/api/hooks/claude-done/route.js +2 -2
  30. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  31. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  32. package/.next/server/app/api/hooks/permission-request/route.js +1 -1
  33. package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
  34. package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/push/escalation/route.js +1 -1
  38. package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
  39. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  40. package/.next/server/app/api/push/vapid/route.js +1 -1
  41. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  42. package/.next/server/app/api/relays/[relayId]/cancel/route.js +1 -1
  43. package/.next/server/app/api/relays/[relayId]/cancel/route.js.nft.json +1 -1
  44. package/.next/server/app/api/relays/[relayId]/cancel/route_client-reference-manifest.js +1 -1
  45. package/.next/server/app/api/relays/route.js +1 -1
  46. package/.next/server/app/api/relays/route.js.nft.json +1 -1
  47. package/.next/server/app/api/relays/route_client-reference-manifest.js +1 -1
  48. package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
  49. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  50. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  51. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  52. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  53. package/.next/server/app/api/repositories/clone/route.js +1 -1
  54. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  55. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  56. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  57. package/.next/server/app/api/repositories/restore/route.js +1 -1
  58. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
  59. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  60. package/.next/server/app/api/repositories/route.js +1 -1
  61. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  62. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  63. package/.next/server/app/api/repositories/scan/route.js +1 -1
  64. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
  65. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  66. package/.next/server/app/api/repositories/sync/route.js +1 -1
  67. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
  68. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  69. package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
  70. package/.next/server/app/api/settings/default-agents/route.js +1 -1
  71. package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
  72. package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
  73. package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  75. package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
  76. package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
  78. package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
  79. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  80. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  81. package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  82. package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  83. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  84. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  85. package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
  86. package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
  87. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  88. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  89. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  90. package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
  91. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
  92. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  93. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
  94. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
  95. package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
  96. package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
  97. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  98. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  99. package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
  100. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  101. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/worktrees/[id]/direct-input/route.js +1 -1
  103. package/.next/server/app/api/worktrees/[id]/direct-input/route.js.nft.json +1 -1
  104. package/.next/server/app/api/worktrees/[id]/direct-input/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
  106. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  107. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  109. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  110. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  112. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  113. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  115. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  116. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  118. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  119. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  121. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  122. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  123. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  124. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  125. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  126. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  127. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  128. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  129. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  130. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  131. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  132. package/.next/server/app/api/worktrees/[id]/instances/notes/route_client-reference-manifest.js +1 -1
  133. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js +1 -1
  134. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
  135. package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
  136. package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
  137. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  138. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  139. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
  140. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  141. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  142. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  143. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  146. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  147. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  148. package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
  149. package/.next/server/app/api/worktrees/[id]/opencode/session/route.js +1 -1
  150. package/.next/server/app/api/worktrees/[id]/opencode/session/route.js.nft.json +1 -1
  151. package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
  152. package/.next/server/app/api/worktrees/[id]/opencode/share/route.js +1 -1
  153. package/.next/server/app/api/worktrees/[id]/opencode/share/route.js.nft.json +1 -1
  154. package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
  155. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  156. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  157. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  158. package/.next/server/app/api/worktrees/[id]/prompt-response/strict/route.js +1 -1
  159. package/.next/server/app/api/worktrees/[id]/prompt-response/strict/route.js.nft.json +1 -1
  160. package/.next/server/app/api/worktrees/[id]/prompt-response/strict/route_client-reference-manifest.js +1 -1
  161. package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  163. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  164. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  165. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  166. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  167. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  168. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  169. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  170. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  171. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  172. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
  173. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  174. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  175. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +3 -3
  176. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
  177. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
  178. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
  179. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
  180. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
  181. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
  182. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
  183. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
  184. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
  185. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  186. package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
  187. package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
  188. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  189. package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
  190. package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -103
  191. package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
  192. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  193. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  194. package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
  195. package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
  196. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  197. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  198. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  199. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  200. package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
  201. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
  202. package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
  203. package/.next/server/app/api/worktrees/[id]/verify/route.js +1 -1
  204. package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
  205. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route.js +1 -1
  206. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
  207. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
  208. package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
  209. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  210. package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
  211. package/.next/server/app/api/worktrees/route.js +1 -1
  212. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  213. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  214. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  215. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  216. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  217. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  218. package/.next/server/app/page_client-reference-manifest.js +1 -1
  219. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  220. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  221. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  222. package/.next/server/app/sessions/page.js +1 -1
  223. package/.next/server/app/sessions/page.js.nft.json +1 -1
  224. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  225. package/.next/server/app/skills/[skillId]/page.js +1 -1
  226. package/.next/server/app/skills/[skillId]/page.js.nft.json +1 -1
  227. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
  228. package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
  229. package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  230. package/.next/server/app/worktrees/[id]/files/[...path]/page.js +2 -2
  231. package/.next/server/app/worktrees/[id]/files/[...path]/page.js.nft.json +1 -1
  232. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  233. package/.next/server/app/worktrees/[id]/page.js +12 -12
  234. package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
  235. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  236. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  237. package/.next/server/app-paths-manifest.json +30 -30
  238. package/.next/server/chunks/1191.js +11 -4
  239. package/.next/server/chunks/1501.js +1 -1
  240. package/.next/server/chunks/1601.js +2 -2
  241. package/.next/server/chunks/1656.js +2 -2
  242. package/.next/server/chunks/1945.js +3 -3
  243. package/.next/server/chunks/1990.js +103 -0
  244. package/.next/server/chunks/2069.js +1 -0
  245. package/.next/server/chunks/2119.js +1 -1
  246. package/.next/server/chunks/2404.js +1 -1
  247. package/.next/server/chunks/2422.js +1 -1
  248. package/.next/server/chunks/2445.js +1 -1
  249. package/.next/server/chunks/2534.js +1 -1
  250. package/.next/server/chunks/255.js +1 -1
  251. package/.next/server/chunks/3241.js +1 -1
  252. package/.next/server/chunks/3505.js +2 -2
  253. package/.next/server/chunks/4243.js +1 -1
  254. package/.next/server/chunks/4248.js +1 -1
  255. package/.next/server/chunks/4280.js +1 -0
  256. package/.next/server/chunks/5209.js +1 -1
  257. package/.next/server/chunks/6119.js +1 -1
  258. package/.next/server/chunks/6130.js +1 -1
  259. package/.next/server/chunks/6401.js +1 -1
  260. package/.next/server/chunks/6486.js +9 -8
  261. package/.next/server/chunks/6781.js +1 -1
  262. package/.next/server/chunks/720.js +103 -0
  263. package/.next/server/chunks/7604.js +2 -0
  264. package/.next/server/chunks/7905.js +1 -1
  265. package/.next/server/chunks/8581.js +8 -8
  266. package/.next/server/chunks/8728.js +3 -3
  267. package/.next/server/chunks/8791.js +1 -1
  268. package/.next/server/chunks/8807.js +19 -18
  269. package/.next/server/chunks/8918.js +2 -104
  270. package/.next/server/chunks/936.js +1 -1
  271. package/.next/server/chunks/9390.js +1 -1
  272. package/.next/server/chunks/9540.js +1 -1
  273. package/.next/server/chunks/9627.js +5 -5
  274. package/.next/server/chunks/9731.js +2 -2
  275. package/.next/server/middleware-manifest.json +5 -5
  276. package/.next/server/pages/500.html +1 -1
  277. package/.next/server/server-reference-manifest.json +1 -1
  278. package/.next/static/chunks/1128-914c559913546bbc.js +1 -0
  279. package/.next/static/chunks/{2407-a6533805a86d05bd.js → 2407-ab92ae9837c39dce.js} +1 -1
  280. package/.next/static/chunks/{2863-6a07ec82fb52f4dd.js → 2863-7173dc305dffc4f6.js} +1 -1
  281. package/.next/static/chunks/6288-6fadbba6e84393b2.js +1 -0
  282. package/.next/static/chunks/7665-e9ef6e0a85b9fa49.js +1 -0
  283. package/.next/static/chunks/8407-35bbfc84793d7004.js +1 -0
  284. package/.next/static/chunks/9079-987939d231704218.js +1 -0
  285. package/.next/static/chunks/app/{layout-538d8d2746ad1588.js → layout-aa8e66164a4367af.js} +1 -1
  286. package/.next/static/chunks/app/sessions/page-cfd645305e25fd33.js +1 -0
  287. package/.next/static/chunks/app/skills/[skillId]/{page-52ba58712faf3378.js → page-cb6e74fd9a6a571d.js} +1 -1
  288. package/.next/static/chunks/app/worktrees/[id]/files/[...path]/page-704086656fb45699.js +1 -0
  289. package/.next/static/chunks/app/worktrees/[id]/page-a8d7886703ffc7b4.js +1 -0
  290. package/.next/static/css/{743f79ff19ab91e9.css → db8959555c3d9c96.css} +1 -1
  291. package/.next/trace +13 -13
  292. package/dist/cli/commands/auto-yes.d.ts +24 -0
  293. package/dist/cli/commands/auto-yes.d.ts.map +1 -1
  294. package/dist/cli/commands/auto-yes.js +76 -8
  295. package/dist/cli/commands/capture.d.ts.map +1 -1
  296. package/dist/cli/commands/capture.js +5 -0
  297. package/dist/cli/commands/instances.d.ts.map +1 -1
  298. package/dist/cli/commands/instances.js +10 -1
  299. package/dist/cli/commands/prompt.d.ts.map +1 -1
  300. package/dist/cli/commands/prompt.js +5 -3
  301. package/dist/cli/commands/send.d.ts.map +1 -1
  302. package/dist/cli/commands/send.js +19 -6
  303. package/dist/cli/commands/verify.d.ts.map +1 -1
  304. package/dist/cli/commands/verify.js +8 -1
  305. package/dist/cli/commands/wait.d.ts.map +1 -1
  306. package/dist/cli/commands/wait.js +101 -13
  307. package/dist/cli/config/duration-constants.d.ts +16 -13
  308. package/dist/cli/config/duration-constants.d.ts.map +1 -1
  309. package/dist/cli/config/duration-constants.js +21 -21
  310. package/dist/cli/docs/agent-operations.d.ts +2 -2
  311. package/dist/cli/docs/agent-operations.d.ts.map +1 -1
  312. package/dist/cli/docs/agent-operations.js +29 -1
  313. package/dist/cli/types/api-responses.d.ts +145 -3
  314. package/dist/cli/types/api-responses.d.ts.map +1 -1
  315. package/dist/cli/types/index.d.ts +4 -0
  316. package/dist/cli/types/index.d.ts.map +1 -1
  317. package/dist/cli/utils/resource-resolvers.d.ts +0 -18
  318. package/dist/cli/utils/resource-resolvers.d.ts.map +1 -1
  319. package/dist/cli/utils/resource-resolvers.js +1 -51
  320. package/dist/cli/utils/verify-runner.d.ts +24 -1
  321. package/dist/cli/utils/verify-runner.d.ts.map +1 -1
  322. package/dist/cli/utils/verify-runner.js +54 -1
  323. package/dist/config/auto-yes-duration.d.ts +56 -0
  324. package/dist/config/auto-yes-duration.d.ts.map +1 -0
  325. package/dist/config/auto-yes-duration.js +76 -0
  326. package/dist/lib/polling/auto-yes-suppression-reason.d.ts +54 -2
  327. package/dist/lib/polling/auto-yes-suppression-reason.d.ts.map +1 -1
  328. package/dist/lib/polling/auto-yes-suppression-reason.js +33 -2
  329. package/dist/lib/prompt-observation/types.d.ts +13 -0
  330. package/dist/lib/prompt-observation/types.d.ts.map +1 -1
  331. package/dist/server/locales/en/worktree.json +2 -1
  332. package/dist/server/locales/ja/worktree.json +2 -1
  333. package/dist/server/src/config/auto-yes-config.js +14 -19
  334. package/dist/server/src/config/auto-yes-duration.js +76 -0
  335. package/dist/server/src/lib/auto-yes-poller-answer-target.js +38 -0
  336. package/dist/server/src/lib/auto-yes-poller-keys.js +35 -0
  337. package/dist/server/src/lib/auto-yes-poller-session-presence.js +26 -0
  338. package/dist/server/src/lib/auto-yes-poller-tick.js +233 -0
  339. package/dist/server/src/lib/auto-yes-poller.js +337 -376
  340. package/dist/server/src/lib/auto-yes-state.js +59 -4
  341. package/dist/server/src/lib/cli-tools/submit-verified-sender.js +235 -19
  342. package/dist/server/src/lib/db/chat-db.js +5 -1
  343. package/dist/server/src/lib/db/verification-db.js +23 -2
  344. package/dist/server/src/lib/detection/composer-text.js +215 -11
  345. package/dist/server/src/lib/detection/option-recommendation.js +120 -0
  346. package/dist/server/src/lib/detection/prompt-detect-multiple-choice-approval-context.js +290 -0
  347. package/dist/server/src/lib/detection/prompt-detect-multiple-choice-chrome.js +193 -0
  348. package/dist/server/src/lib/detection/prompt-detect-multiple-choice.js +402 -539
  349. package/dist/server/src/lib/detection/prompt-detector.js +92 -21
  350. package/dist/server/src/lib/detection/prompt-screen-key.js +60 -0
  351. package/dist/server/src/lib/detection/tools/antigravity/dialog.js +158 -35
  352. package/dist/server/src/lib/detection/tools/claude/detect.js +111 -10
  353. package/dist/server/src/lib/detection/tools/command-code/dialog.js +67 -0
  354. package/dist/server/src/lib/detection/tools/dialog-block.js +16 -0
  355. package/dist/server/src/lib/detection/upstream-faults.js +19 -2
  356. package/dist/server/src/lib/detection/waiting-screen-reading.js +98 -0
  357. package/dist/server/src/lib/hooks/permission-decision-service.js +7 -0
  358. package/dist/server/src/lib/hooks/structured-decision-response.js +1 -1
  359. package/dist/server/src/lib/polling/auto-yes-confirm-page.js +2 -2
  360. package/dist/server/src/lib/polling/auto-yes-confirmation-ledger-types.js +3 -0
  361. package/dist/server/src/lib/polling/auto-yes-confirmation-ledger.js +34 -3
  362. package/dist/server/src/lib/polling/auto-yes-decision-state.js +195 -0
  363. package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +139 -10
  364. package/dist/server/src/lib/polling/auto-yes-enter-fallback.js +14 -0
  365. package/dist/server/src/lib/polling/auto-yes-manual-answer.js +124 -0
  366. package/dist/server/src/lib/polling/auto-yes-option-effect.js +157 -0
  367. package/dist/server/src/lib/polling/auto-yes-policy.js +11 -5
  368. package/dist/server/src/lib/polling/auto-yes-poller-capture.js +15 -2
  369. package/dist/server/src/lib/polling/auto-yes-poller-generation.js +42 -1
  370. package/dist/server/src/lib/polling/auto-yes-poller-receipt-log.js +42 -5
  371. package/dist/server/src/lib/polling/auto-yes-poller-state.js +147 -49
  372. package/dist/server/src/lib/polling/auto-yes-poller-steps.js +172 -2
  373. package/dist/server/src/lib/polling/auto-yes-prompt-suppression.js +2 -2
  374. package/dist/server/src/lib/polling/auto-yes-question-choice.js +57 -0
  375. package/dist/server/src/lib/polling/auto-yes-resolver.js +96 -21
  376. package/dist/server/src/lib/polling/auto-yes-suppression-reason.js +33 -2
  377. package/dist/server/src/lib/polling/auto-yes-suppression-state.js +25 -1
  378. package/dist/server/src/lib/polling/prompt-screen-reading.js +232 -0
  379. package/dist/server/src/lib/polling/response-checker-dialog-gate.js +39 -0
  380. package/dist/server/src/lib/polling/response-checker.js +145 -58
  381. package/dist/server/src/lib/prompt-answer-sender.js +104 -10
  382. package/dist/server/src/lib/push/notification-dedup.js +15 -2
  383. package/dist/server/src/lib/push/prompt-card-state.js +140 -19
  384. package/dist/server/src/lib/push/prompt-push-gate.js +158 -12
  385. package/dist/server/src/lib/push/push-sender.js +23 -3
  386. package/dist/server/src/lib/push/resolution-push-notifier.js +14 -0
  387. package/dist/server/src/lib/push/waiting-push-notifier.js +139 -17
  388. package/dist/server/src/lib/realtime/terminal-broadcast.js +16 -0
  389. package/dist/server/src/lib/session/agent-event-state.js +25 -5
  390. package/dist/server/src/lib/session/agent-event-turn.js +140 -46
  391. package/dist/server/src/lib/session/cli-session.js +21 -2
  392. package/dist/server/src/lib/session/composer-clear.js +56 -4
  393. package/dist/server/src/lib/session/current-output-builder.js +66 -12
  394. package/dist/server/src/lib/session/send-attempt-state.js +24 -7
  395. package/dist/server/src/lib/session/waiting-episode-binding-observation.js +289 -0
  396. package/dist/server/src/lib/session/waiting-episode-binding-resolve.js +38 -0
  397. package/dist/server/src/lib/session/waiting-episode-binding.js +276 -0
  398. package/dist/server/src/lib/session/waiting-episode-state-ops.js +152 -0
  399. package/dist/server/src/lib/session/waiting-episode-state-store.js +202 -0
  400. package/dist/server/src/lib/session/waiting-episode-state-types.js +6 -0
  401. package/dist/server/src/lib/session/waiting-episode-state.js +68 -91
  402. package/dist/server/src/lib/session/waiting-episode-verdict.js +174 -0
  403. package/dist/server/src/lib/tmux/tmux-capture-cache.js +76 -11
  404. package/dist/server/src/lib/tmux/tmux.js +79 -9
  405. package/dist/server/src/lib/verification/gate-runner.js +172 -16
  406. package/dist/server/src/lib/verification/machine-lock.js +5 -0
  407. package/dist/server/src/lib/ws-server.js +18 -3
  408. package/dist/server/src/types/auto-yes-answer-mode.js +38 -0
  409. package/dist/server/src/types/auto-yes-decision.js +61 -0
  410. package/dist/server/src/types/auto-yes.js +6 -0
  411. package/dist/server/src/types/prompt-reading.js +32 -0
  412. package/dist/types/auto-yes-answer-mode.d.ts +35 -0
  413. package/dist/types/auto-yes-answer-mode.d.ts.map +1 -0
  414. package/dist/types/auto-yes-answer-mode.js +38 -0
  415. package/docs/en/user-guide/webapp-guide.md +47 -13
  416. package/package.json +1 -1
  417. package/public/sw.js +76 -4
  418. package/release-notes/0.48.0.json +57 -0
  419. package/release-notes/0.49.0.json +45 -0
  420. package/.next/server/chunks/1559.js +0 -2
  421. package/.next/server/chunks/2460.js +0 -1
  422. package/.next/server/chunks/5595.js +0 -1
  423. package/.next/server/chunks/610.js +0 -1
  424. package/.next/server/chunks/6722.js +0 -1
  425. package/.next/static/chunks/5371-a549a0d2c2044d41.js +0 -1
  426. package/.next/static/chunks/602-1c1488959215e140.js +0 -1
  427. package/.next/static/chunks/6288-09feba367cc2c65e.js +0 -1
  428. package/.next/static/chunks/8407-155f84e5ba05f1d5.js +0 -1
  429. package/.next/static/chunks/9079-24f9fa549ed298f1.js +0 -1
  430. package/.next/static/chunks/app/sessions/page-e02f1adb1d1c1ccc.js +0 -1
  431. package/.next/static/chunks/app/worktrees/[id]/files/[...path]/page-9cf1ecc59e36a004.js +0 -1
  432. package/.next/static/chunks/app/worktrees/[id]/page-46aced20b2b1c010.js +0 -1
  433. /package/.next/static/{etorRtpxbQqqOzdUeXdw2 → 3_JtAZaKMJEDFIIfkHv4n}/_buildManifest.js +0 -0
  434. /package/.next/static/{etorRtpxbQqqOzdUeXdw2 → 3_JtAZaKMJEDFIIfkHv4n}/_ssgManifest.js +0 -0
@@ -22,6 +22,8 @@ const auto_yes_resolver_1 = require("./auto-yes-resolver");
22
22
  const auto_yes_policy_1 = require("./auto-yes-policy");
23
23
  const logger_1 = require("../../lib/logger");
24
24
  const global_state_1 = require("../global-state");
25
+ const prompt_screen_key_1 = require("../detection/prompt-screen-key");
26
+ const auto_yes_poller_state_1 = require("./auto-yes-poller-state");
25
27
  const auto_yes_suppression_reason_1 = require("./auto-yes-suppression-reason");
26
28
  const auto_yes_suppression_state_1 = require("./auto-yes-suppression-state");
27
29
  const logger = (0, logger_1.createLogger)('auto-yes-poller');
@@ -70,12 +72,20 @@ const WITHHELD_NO_RECEIPT_LOG_INTERVAL_MS = 60_000;
70
72
  * ungated reading this function already took, and the reason it recorded.
71
73
  *
72
74
  * @param compositeKey - The instance's key, for the once-a-minute limit
75
+ * Issue #3880: a person's send that may have left keys on the pane holds the
76
+ * dialog (`partial-answer`), but no tick inside the window published it — the
77
+ * manual hold kept them off it — so there is no record to re-stamp. Given that
78
+ * hold's screen, a dialog still up at it is withheld as `partial-answer` here,
79
+ * before the contract and the receipt (as on the tick, step 2.5).
80
+ *
73
81
  * @param readWithoutGate - The same frame read without `receiptScope`
82
+ * @param personHoldScreenKey - The screen of a person's hold the tick had
83
+ * (`PartialAutoYesAnswer.byPerson`), else null
74
84
  * @returns The prompt the ungated reading saw, with the reason this call
75
85
  * recorded or kept for it (null when none: a dialog the gate accepted and is
76
86
  * waiting to be answered); null when no dialog was read past the gate
77
87
  */
78
- function logIfWithheldForWantOfReceipt(worktreeId, instanceId, compositeKey, readWithoutGate) {
88
+ function logIfWithheldForWantOfReceipt(worktreeId, instanceId, compositeKey, readWithoutGate, personHoldScreenKey = null) {
79
89
  // Issue #3767: the gate's own verdict for this tick's candidate. Null means it
80
90
  // never saw one (no dialog), `ok` that it let the frame through.
81
91
  let verdict = (0, antigravity_receipt_episodes_1.getAntigravityReceiptVerdict)(worktreeId, instanceId);
@@ -91,6 +101,14 @@ function logIfWithheldForWantOfReceipt(worktreeId, instanceId, compositeKey, rea
91
101
  verdict ??= (0, antigravity_receipt_episodes_1.judgeAntigravityPermissionReceipt)(worktreeId, instanceId, now);
92
102
  if (verdict.ok)
93
103
  return null;
104
+ if (personHoldScreenKey !== null && (0, auto_yes_poller_state_1.partialAnswerCovers)(personHoldScreenKey, (0, prompt_screen_key_1.promptScreenKey)(promptData))) {
105
+ (0, auto_yes_suppression_state_1.recordPolicySuppression)(worktreeId, 'antigravity', instanceId, {
106
+ reason: auto_yes_suppression_reason_1.PARTIAL_ANSWER_SUPPRESSION_REASON,
107
+ mode: null,
108
+ promptType: promptData.type,
109
+ });
110
+ return { promptData, reason: auto_yes_suppression_reason_1.PARTIAL_ANSWER_SUPPRESSION_REASON, keptPersonHold: true };
111
+ }
94
112
  // Issue #3724: a contract that withholds the answer makes the server reply
95
113
  // `ask`, so the dialog stays up past the receipt window. The cause is then the
96
114
  // contract, not a hooks.json that points elsewhere. Judged exactly as the tick
@@ -102,7 +120,7 @@ function logIfWithheldForWantOfReceipt(worktreeId, instanceId, compositeKey, rea
102
120
  // dropping the `policy-lookup-failed` record the tick made.
103
121
  const { policy, taskId } = (0, auto_yes_policy_1.getSessionAutoYesPolicyLookupEntry)(worktreeId, 'antigravity', instanceId);
104
122
  const mode = (0, auto_yes_resolver_1.policyLookupMode)(policy);
105
- const resolution = (0, auto_yes_resolver_1.resolveAutoAnswerWithPolicy)(ungated.promptData, policy);
123
+ const resolution = (0, auto_yes_resolver_1.resolveAutoAnswerWithPolicy)(ungated.promptData, policy, 'antigravity');
106
124
  // Issue #3767: `answered` is the dialog the gate already let through on this
107
125
  // receipt, still up past the window. Unless the contract withheld it, that is
108
126
  // not a missing receipt: neither recorded nor logged, nor counted for the limit.
@@ -149,9 +167,7 @@ function logIfWithheldForWantOfReceipt(worktreeId, instanceId, compositeKey, rea
149
167
  reason: resolution.suppressedBy,
150
168
  mode,
151
169
  taskId,
152
- hint: resolution.suppressedBy === auto_yes_suppression_reason_1.POLICY_LOOKUP_FAILED_SUPPRESSION_REASON
153
- ? '契約の照会に失敗したので答えていない。サーバーログの policy-lookup-failed を確認'
154
- : '契約の autoYes が答えを止めている。契約の autoYes を確認',
170
+ hint: withheldHint(resolution.suppressedBy),
155
171
  });
156
172
  return seen(contractReason ?? null);
157
173
  }
@@ -172,6 +188,24 @@ function logIfWithheldForWantOfReceipt(worktreeId, instanceId, compositeKey, rea
172
188
  });
173
189
  return seen(auto_yes_suppression_reason_1.NO_HOOK_RECEIPT_SUPPRESSION_REASON);
174
190
  }
191
+ /**
192
+ * The hint of `antigravity-autoyes-withheld-by-policy` for `reason`. Issue
193
+ * #3822: the base rules' withholding (`allow-once-unidentified`) is not the
194
+ * contract's, so the line does not send the operator to the contract for it.
195
+ */
196
+ function withheldHint(reason) {
197
+ if (reason === auto_yes_suppression_reason_1.POLICY_LOOKUP_FAILED_SUPPRESSION_REASON) {
198
+ return '契約の照会に失敗したので答えていない。サーバーログの policy-lookup-failed を確認';
199
+ }
200
+ // Issue #3863: the other base-rule withholding, over a question's recommended option.
201
+ if (reason === auto_yes_suppression_reason_1.RECOMMENDED_OPTION_UNIDENTIFIED_SUPPRESSION_REASON) {
202
+ return '質問の推奨の選択肢を 1 つに特定できないので答えていない(基本の判定。契約の判定ではない)。画面で答える';
203
+ }
204
+ if ((0, auto_yes_suppression_reason_1.isBaseRuleSuppressionReason)(reason)) {
205
+ return '今回だけ許可の選択肢を 1 つに特定できないので答えていない(基本の判定。契約の判定ではない)。画面で答える';
206
+ }
207
+ return '契約の autoYes が答えを止めている。契約の autoYes を確認';
208
+ }
175
209
  /**
176
210
  * Whether a withheld line for `compositeKey` is due at `now` under the
177
211
  * once-a-minute limit; when it is, entries past the interval are pruned and
@@ -218,6 +252,9 @@ function refreshEpisodeSuppression(worktreeId, instanceId, verdict, resolution)
218
252
  // up (same episode, accepted on the same receipt). Not `getPartialAnswer`:
219
253
  // the tick forgets it as soon as the gated reading stops seeing the prompt,
220
254
  // which past the window is every tick.
255
+ // Issue #3798: re-stamped under the waiting episode it was recorded for
256
+ // (`episodeId` is carried over), not whichever is open now — the keys went
257
+ // to that wait's dialog.
221
258
  const { at: _recordedAt, ...suppression } = own;
222
259
  (0, auto_yes_suppression_state_1.recordPolicySuppression)(worktreeId, 'antigravity', instanceId, suppression);
223
260
  return true;
@@ -6,15 +6,24 @@
6
6
  * `AutoYesPollerState`. Must not import auto-yes-poller.ts (cycle).
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.partialAnswerScreenKey = exports.UNIDENTIFIED_SCREEN_KEY = void 0;
10
+ exports.getAutoYesLastAnswer = getAutoYesLastAnswer;
9
11
  exports.promptFrameKey = promptFrameKey;
10
12
  exports.warnOncePerFrame = warnOncePerFrame;
11
- exports.partialAnswerScreenKey = partialAnswerScreenKey;
13
+ exports.partialAnswerCovers = partialAnswerCovers;
12
14
  exports.ledgerScreenKey = ledgerScreenKey;
15
+ exports.approvalTargetWithoutCursor = approvalTargetWithoutCursor;
13
16
  exports.getPartialAnswer = getPartialAnswer;
14
17
  exports.forgetPartialAnswer = forgetPartialAnswer;
18
+ exports.personSendsInFlight = personSendsInFlight;
15
19
  exports.forgetPartialAnswersByWorktree = forgetPartialAnswersByWorktree;
20
+ exports.releasePartialAnswerToHuman = releasePartialAnswerToHuman;
21
+ exports.identifyPartialAnswerScreen = identifyPartialAnswerScreen;
22
+ exports.keepPartialAnswerByPerson = keepPartialAnswerByPerson;
23
+ exports.nextSendOrder = nextSendOrder;
16
24
  exports.clearPartialAnswers = clearPartialAnswers;
17
25
  exports.beginSendAttempt = beginSendAttempt;
26
+ exports.beginManualSendAttempt = beginManualSendAttempt;
18
27
  exports.settleSendAttempt = settleSendAttempt;
19
28
  exports.hasMovedSendInFlight = hasMovedSendInFlight;
20
29
  exports.movePartialAnswers = movePartialAnswers;
@@ -24,7 +33,17 @@ const auto_yes_state_1 = require("../auto-yes-state");
24
33
  const global_state_1 = require("../global-state");
25
34
  const auto_yes_enter_fallback_state_1 = require("./auto-yes-enter-fallback-state");
26
35
  const appearance_1 = require("../prompt-observation/appearance");
36
+ const prompt_screen_key_1 = require("../detection/prompt-screen-key");
27
37
  const logger = (0, logger_1.createLogger)('auto-yes-poller');
38
+ /**
39
+ * The Auto-Yes poller's last answer for one instance (Issue #3798), for the
40
+ * other observers of the same waiting episode (the response poller). Read off
41
+ * `globalThis` (`__autoYesPollerStates`) as the push gate reads the poller's
42
+ * answer time, so a reader need not import the poller.
43
+ */
44
+ function getAutoYesLastAnswer(compositeKey) {
45
+ return globalThis.__autoYesPollerStates?.get(compositeKey)?.lastAnswer ?? null;
46
+ }
28
47
  /**
29
48
  * Issue #2995: what makes two ticks "the same prompt" for `warnOncePerFrame`.
30
49
  *
@@ -65,41 +84,21 @@ function warnOncePerFrame(pollerState, frameKey, event, fields) {
65
84
  logger.warn(event, fields);
66
85
  }
67
86
  /**
68
- * Which prompt a stopped answer is about (Issue #3706): the type, the question,
69
- * the option labels and `approvalTarget` — what {@link promptFrameKey} tells
70
- * apart — but NOT where the cursor is. The keys that were sent may have moved
71
- * the cursor themselves (a `Down` whose Enter was withheld), and that must not
72
- * make the same list read as a new one; a different list or a different command
73
- * under the same question is a new prompt and is answered.
74
- */
75
- function partialAnswerScreenKey(promptData) {
76
- const options = promptData.type === 'multiple_choice'
77
- ? promptData.options.map((o) => `${o.number}.${o.label}`).join('\n')
78
- : promptData.options.join('\n');
79
- return [(0, prompt_key_1.generatePromptKey)(promptData), options, withoutCursorMarks(promptData)].join('\u0000');
80
- }
81
- /**
82
- * `approvalTarget` with the cursor taken out: the generic parser copies the
83
- * option panel into it, `❯` row included, so a moved cursor would otherwise
84
- * read as another prompt.
85
- *
86
- * [Issue #3817] Only the rows the block reader adopted as the options are
87
- * aligned (`approvalTargetWithOptionRowsAligned`, the reading #3812 gives the
88
- * strict respond), so two commands whose bodies differ by an indent or a `>`
89
- * are two screens. A label the block reader read may run longer than the
90
- * prompt's — it folds wrapped rows and the footer in — so it only has to start
91
- * with it. A yes/no prompt has no cursor and is read as it is. A list whose
92
- * rows cannot be told that way keeps the old reading below: two bodies then
93
- * read as one screen, which holds the prompt for a human rather than typing
94
- * the answer twice.
87
+ * The screen key of a person's send made with no prompt read off the screen
88
+ * (Issue #3880: the capture before it failed). A hold at it covers whatever
89
+ * confirmation the next tick reads, and takes that confirmation's key there
90
+ * ({@link identifyPartialAnswerScreen}); from then on it is released like any
91
+ * other — the screen changing, the session relaunched, a person's answer going
92
+ * through — and before then by a frame with no prompt on it.
95
93
  */
96
- function withoutCursorMarks(promptData) {
97
- const target = promptData.approvalTarget ?? '';
98
- if (promptData.type !== 'multiple_choice')
99
- return target;
100
- const aligned = (0, appearance_1.approvalTargetWithOptionRowsAligned)(target, promptData.options.map((o) => o.label), (read, named) => read.startsWith(named));
101
- return aligned ?? withoutLeadingMarks(target);
94
+ exports.UNIDENTIFIED_SCREEN_KEY = '\u0000unidentified-screen';
95
+ /** Whether a hold (or a send) at `heldScreenKey` covers the confirmation at `screenKey`. */
96
+ function partialAnswerCovers(heldScreenKey, screenKey) {
97
+ return heldScreenKey === screenKey || heldScreenKey === exports.UNIDENTIFIED_SCREEN_KEY;
102
98
  }
99
+ /** Issue #3798: moved to `detection/prompt-screen-key`, where the waiting episodes read it too. */
100
+ var prompt_screen_key_2 = require("../detection/prompt-screen-key");
101
+ Object.defineProperty(exports, "partialAnswerScreenKey", { enumerable: true, get: function () { return prompt_screen_key_2.promptScreenKey; } });
103
102
  /**
104
103
  * Which confirmation the ledger counts a prompt as (Issue #3820): the
105
104
  * {@link partialAnswerScreenKey} reading where the option rows can be told,
@@ -115,14 +114,32 @@ function withoutCursorMarks(promptData) {
115
114
  */
116
115
  function ledgerScreenKey(promptData) {
117
116
  if (promptData.type !== 'multiple_choice')
118
- return partialAnswerScreenKey(promptData);
117
+ return (0, prompt_screen_key_1.promptScreenKey)(promptData);
119
118
  const target = promptData.approvalTarget ?? '';
120
119
  const aligned = (0, appearance_1.approvalTargetWithOptionRowsAligned)(target, promptData.options.map((o) => o.label), (read, named) => read.startsWith(named));
121
120
  if (aligned !== null)
122
- return partialAnswerScreenKey(promptData);
121
+ return (0, prompt_screen_key_1.promptScreenKey)(promptData);
123
122
  const options = promptData.options.map((o) => `${o.number}.${o.label}`).join('\n');
124
123
  return [(0, prompt_key_1.generatePromptKey)(promptData), options, withOptionRowGuttersAligned(target, promptData.options)].join('\u0000');
125
124
  }
125
+ /**
126
+ * `approvalTarget` with only the cursor taken out of its option rows, or null
127
+ * when the prompt has none (Issue #3821, the identity of the confirmation an
128
+ * Auto-Yes decision is about). The reading {@link ledgerScreenKey} keeps: the
129
+ * rows the block reader adopted as the options are aligned
130
+ * (`approvalTargetWithOptionRowsAligned`), else only the rows that ARE the
131
+ * prompt's options lose their gutter; the body — its indent, a `>`, a blank
132
+ * row — stays byte for byte, so two commands that differ there are two
133
+ * confirmations (#3817), and a moved cursor is the same one.
134
+ */
135
+ function approvalTargetWithoutCursor(promptData) {
136
+ const target = promptData.approvalTarget;
137
+ if (typeof target !== 'string')
138
+ return null;
139
+ if (promptData.type !== 'multiple_choice')
140
+ return target;
141
+ return ((0, appearance_1.approvalTargetWithOptionRowsAligned)(target, promptData.options.map((o) => o.label), (read, named) => read.startsWith(named)) ?? withOptionRowGuttersAligned(target, promptData.options));
142
+ }
126
143
  /** A row's leading cursor marks and indentation. */
127
144
  const LEADING_MARKS_PATTERN = /^[\s\u276F\u203A>\u25B6\u25BA\u25CF\u25CB\u25C9\u2192]+/u;
128
145
  /** A row's option number and the text after its separator (`1.`, `1)` or `1`, then spaces). */
@@ -145,13 +162,6 @@ function withOptionRowGuttersAligned(text, options) {
145
162
  })
146
163
  .join('\n');
147
164
  }
148
- /** Every row's leading marks and indentation taken out (the reading before #3817). */
149
- function withoutLeadingMarks(text) {
150
- return text
151
- .split('\n')
152
- .map((line) => line.replace(/^[\s\u276F\u203A>\u25B6\u25BA\u25CF\u25CB\u25C9\u2192]+/u, ''))
153
- .join('\n');
154
- }
155
165
  /** compositeKey -> the answer stopped part-way. globalThis for hot reload (#153). */
156
166
  const partialAnswers = (0, global_state_1.getOrInitGlobal)('__autoYesPartialAnswers', () => new Map());
157
167
  /**
@@ -168,6 +178,7 @@ function getPartialAnswer(compositeKey, epoch) {
168
178
  }
169
179
  return partial;
170
180
  }
181
+ const NO_ATTEMPTS = new Set();
171
182
  /**
172
183
  * Forget it: the prompt left the screen, another prompt came up, or the session ended.
173
184
  *
@@ -179,6 +190,8 @@ function getPartialAnswer(compositeKey, epoch) {
179
190
  * and records as before. Expiring is the mark: it drops the attempt from the
180
191
  * registry, so no per-key "forgotten up to seq" state has to outlive it.
181
192
  *
193
+ * @param spare - Issue #3880: sends that are not expired (a person's, at agy's
194
+ * dialog the ungated reading still shows)
182
195
  * @param screenKey - Given when the memory is dropped because ANOTHER prompt is
183
196
  * on screen (re-instruction 3): only the sends at the forgotten memory's
184
197
  * screen are expired. A send at the screen now shown (Y, carried here by a
@@ -186,16 +199,27 @@ function getPartialAnswer(compositeKey, epoch) {
186
199
  * stop is still remembered when it comes back. Omitted (the prompt left the
187
200
  * screen), every send under the key is expired.
188
201
  */
189
- function forgetPartialAnswer(compositeKey, screenKey) {
202
+ function forgetPartialAnswer(compositeKey, screenKey, spare = NO_ATTEMPTS) {
190
203
  partialAnswers.delete(compositeKey);
191
204
  for (const attempt of [...sendAttempts]) {
192
205
  if (attempt.recordKey !== compositeKey)
193
206
  continue;
194
207
  if (screenKey !== undefined && attempt.screenKey !== screenKey)
195
208
  continue;
209
+ if (spare.has(attempt))
210
+ continue;
196
211
  expireSendAttempt(attempt);
197
212
  }
198
213
  }
214
+ /**
215
+ * A person's sends still in flight under this key, to this session epoch
216
+ * (Issue #3880): agy's gated reading seeing no prompt does not say the screen
217
+ * they type at is gone, so the tick checks the ungated reading before it
218
+ * expires them ({@link forgetPartialAnswer}'s `spare`).
219
+ */
220
+ function personSendsInFlight(compositeKey, epoch) {
221
+ return [...sendAttempts].filter((attempt) => attempt.byPerson === true && attempt.recordKey === compositeKey && attempt.recordEpoch === epoch);
222
+ }
199
223
  /**
200
224
  * {@link forgetPartialAnswer} for every instance of a worktree, and the sends
201
225
  * still in flight there are expired (Issue #3713): a slow tick that comes back
@@ -213,6 +237,53 @@ function forgetPartialAnswersByWorktree(worktreeId) {
213
237
  expireSendAttempt(attempt);
214
238
  }
215
239
  }
240
+ /**
241
+ * A person's answer went through, or was refused before any key (Issue #3880):
242
+ * the answer Auto-Yes held at that confirmation is theirs now, so the hold is
243
+ * dropped — only one recorded before the person's answer began (`before`, its
244
+ * {@link nextSendOrder}). A hold recorded since, by a send begun after theirs
245
+ * (another person's from another screen, a tick's), is about what that send
246
+ * did and stays. Only the record: a send still in flight records what it did
247
+ * when it comes back. Not called when a person's own send may have left keys
248
+ * on the pane, nor at the START of their answer.
249
+ */
250
+ function releasePartialAnswerToHuman(compositeKey, before) {
251
+ const recorded = partialAnswers.get(compositeKey);
252
+ if (recorded !== undefined && recorded.seq < before)
253
+ partialAnswers.delete(compositeKey);
254
+ }
255
+ /**
256
+ * The hold's screen, now that a tick read the confirmation on screen (Issue
257
+ * #3880): a hold at {@link UNIDENTIFIED_SCREEN_KEY} takes `screenKey`.
258
+ */
259
+ function identifyPartialAnswerScreen(compositeKey, screenKey) {
260
+ const recorded = partialAnswers.get(compositeKey);
261
+ if (recorded?.screenKey === exports.UNIDENTIFIED_SCREEN_KEY)
262
+ partialAnswers.set(compositeKey, { ...recorded, screenKey });
263
+ }
264
+ /**
265
+ * Put back a person's hold the tick dropped because its gated reading saw no
266
+ * prompt, while agy's dialog it is about is still up past the receipt window
267
+ * (Issue #3880). Only into the same session, and over nothing newer.
268
+ */
269
+ function keepPartialAnswerByPerson(compositeKey, partial, screenKey) {
270
+ if ((0, auto_yes_enter_fallback_state_1.getEnterFallbackSessionEpoch)(compositeKey) !== partial.epoch)
271
+ return;
272
+ const recorded = partialAnswers.get(compositeKey);
273
+ if (recorded !== undefined && recorded.seq > partial.seq)
274
+ return;
275
+ partialAnswers.set(compositeKey, { ...partial, screenKey });
276
+ }
277
+ /**
278
+ * A place in the order sends are registered in (Issue #3880): a person's
279
+ * answer takes one as it begins, so the hold it releases when it ends is only
280
+ * one recorded by a send registered before it began. What its own send
281
+ * records is ordered by that send's registration instead
282
+ * ({@link beginManualSendAttempt}).
283
+ */
284
+ function nextSendOrder() {
285
+ return ++sendAttemptSeq.last;
286
+ }
216
287
  /** Forget every one, and expire every send in flight: server shutdown, and a test seam. */
217
288
  function clearPartialAnswers() {
218
289
  partialAnswers.clear();
@@ -240,12 +311,38 @@ function beginSendAttempt(compositeKey, screenKey, epoch, ledger = null) {
240
311
  sendAttempts.add(attempt);
241
312
  return attempt;
242
313
  }
314
+ /**
315
+ * Register a person's send about to start (Issue #3880): the screen it types
316
+ * at and the session epoch it goes to, fixed now, and its place among the
317
+ * sends taken now too, as Auto-Yes's own is — not when the answer began: an
318
+ * answer that waited before its first key (the re-verification of the screen)
319
+ * may send after one begun later, and then its keys are the newer ones.
320
+ * Settled with {@link settleSendAttempt} like Auto-Yes's own, so it records a
321
+ * hold only for the session the keys went to, never over a hold of a send
322
+ * registered after it, and not at all once the screen it typed at was seen gone.
323
+ */
324
+ function beginManualSendAttempt(compositeKey, screenKey) {
325
+ const attempt = {
326
+ seq: ++sendAttemptSeq.last,
327
+ screenKey,
328
+ recordKey: compositeKey,
329
+ recordEpoch: (0, auto_yes_enter_fallback_state_1.getEnterFallbackSessionEpoch)(compositeKey),
330
+ moved: false,
331
+ state: 'pending',
332
+ byPerson: true,
333
+ ledger: null,
334
+ };
335
+ sendAttempts.add(attempt);
336
+ return attempt;
337
+ }
243
338
  /**
244
339
  * The send came back. `keysSent` — it was stopped with keys already on the
245
- * pane — records the partial answer under the attempt's key as it is now, when
246
- * that key's session is still the one the keys went to; otherwise (sent in
247
- * full, stopped before any key, or failed) only the attempt itself is removed.
248
- * A second call, or a call on an expired attempt, does nothing.
340
+ * pane, or (Issue #3880) a tmux call of it ended without an exit status and
341
+ * its keys may be there — records the partial answer under the attempt's key
342
+ * as it is now, when that key's session is still the one the keys went to;
343
+ * otherwise (sent in full, stopped before any key, or failed with nothing
344
+ * sent) only the attempt itself is removed. A second call, or a call on an
345
+ * expired attempt, does nothing.
249
346
  */
250
347
  function settleSendAttempt(attempt, keysSent, at = Date.now()) {
251
348
  if (attempt.state !== 'pending')
@@ -267,6 +364,7 @@ function settleSendAttempt(attempt, keysSent, at = Date.now()) {
267
364
  epoch: attempt.recordEpoch,
268
365
  at,
269
366
  seq: attempt.seq,
367
+ ...(attempt.byPerson ? { byPerson: true } : {}),
270
368
  });
271
369
  }
272
370
  function expireSendAttempt(attempt) {
@@ -286,7 +384,7 @@ function hasMovedSendInFlight(compositeKey, epoch, screenKey) {
286
384
  if (attempt.moved &&
287
385
  attempt.recordKey === compositeKey &&
288
386
  attempt.recordEpoch === epoch &&
289
- attempt.screenKey === screenKey) {
387
+ partialAnswerCovers(attempt.screenKey, screenKey)) {
290
388
  return true;
291
389
  }
292
390
  }
@@ -12,11 +12,18 @@
12
12
  */
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.withheldForEarlierSend = withheldForEarlierSend;
15
+ exports.answerModeOfTick = answerModeOfTick;
16
+ exports.questionAnsweringOf = questionAnsweringOf;
17
+ exports.withheldAsQuestion = withheldAsQuestion;
18
+ exports.withheldAtSend = withheldAtSend;
15
19
  exports.resolveAnswerUnderPolicy = resolveAnswerUnderPolicy;
16
20
  exports.skippedForUnownedSession = skippedForUnownedSession;
17
21
  const auto_yes_resolver_1 = require("./auto-yes-resolver");
18
22
  const auto_yes_policy_1 = require("./auto-yes-policy");
19
23
  const auto_yes_suppression_reason_1 = require("./auto-yes-suppression-reason");
24
+ const auto_yes_state_1 = require("../auto-yes-state");
25
+ const auto_yes_dialog_gate_1 = require("./auto-yes-dialog-gate");
26
+ const auto_yes_answer_mode_1 = require("../../types/auto-yes-answer-mode");
20
27
  const auto_yes_poller_state_1 = require("./auto-yes-poller-state");
21
28
  const auto_yes_prompt_suppression_1 = require("./auto-yes-prompt-suppression");
22
29
  const auto_yes_confirmation_ledger_1 = require("./auto-yes-confirmation-ledger");
@@ -30,7 +37,10 @@ function withheldForEarlierSend(judged, screenKey, epoch) {
30
37
  const { worktreeId, cliToolId, instanceId, compositeKey, pollerState, promptData, frameKey } = judged;
31
38
  const partial = (0, auto_yes_poller_state_1.getPartialAnswer)(compositeKey, epoch);
32
39
  if (partial !== null) {
33
- if (partial.screenKey === screenKey) {
40
+ if ((0, auto_yes_poller_state_1.partialAnswerCovers)(partial.screenKey, screenKey)) {
41
+ // Issue #3880: a person's send made with no prompt read (the capture
42
+ // failed) holds the first confirmation read after it, as that one.
43
+ (0, auto_yes_poller_state_1.identifyPartialAnswerScreen)(compositeKey, screenKey);
34
44
  (0, auto_yes_prompt_suppression_1.suppressAndWarnOnce)(judged, {
35
45
  reason: auto_yes_suppression_reason_1.PARTIAL_ANSWER_SUPPRESSION_REASON,
36
46
  mode: null,
@@ -54,6 +64,165 @@ function withheldForEarlierSend(judged, screenKey, epoch) {
54
64
  }
55
65
  return false;
56
66
  }
67
+ /**
68
+ * The answer mode a tick acts under (Issue #3863): the grant the tick read
69
+ * (its generation's, #3706), or — for a direct caller with no generation —
70
+ * the instance's grant as it stands, if it is on. Neither: the default,
71
+ * `recommended`. A grant that cannot be read is `careful`, the mode that
72
+ * answers less.
73
+ */
74
+ function answerModeOfTick(worktreeId, cliToolId, instanceId, grant) {
75
+ if (grant !== undefined)
76
+ return (0, auto_yes_state_1.autoYesAnswerModeOf)(grant);
77
+ try {
78
+ const state = (0, auto_yes_state_1.getAutoYesState)(worktreeId, cliToolId, instanceId);
79
+ return state?.enabled ? (0, auto_yes_state_1.autoYesAnswerModeOf)(state) : auto_yes_answer_mode_1.DEFAULT_AUTO_YES_ANSWER_MODE;
80
+ }
81
+ catch {
82
+ return 'careful';
83
+ }
84
+ }
85
+ /**
86
+ * Issue #3863: what the resolver needs to answer the prompt as a question
87
+ * under `answerMode`, or undefined when it is not answered as one — not a
88
+ * question reader's picker, or the mode is `careful` (which never answers it).
89
+ */
90
+ function questionAnsweringOf(judged, answerMode) {
91
+ // Issue #3881 (review N3): the shared table, which the observation reads too.
92
+ const kind = (0, auto_yes_dialog_gate_1.classifyAutoYesQuestion)(judged.promptData, judged.dialogGate, judged.cliToolId);
93
+ if ((0, auto_yes_dialog_gate_1.autoYesQuestionTreatment)(kind, answerMode) !== 'recommended-choice')
94
+ return undefined;
95
+ return { optionRecommendations: judged.optionRecommendations };
96
+ }
97
+ /**
98
+ * Step 3.7 of `detectAndRespondToPrompt` (Issue #3822): a question to the
99
+ * operator is left to the human when Auto-Yes's answer mode says so.
100
+ *
101
+ * Issue #3863: which questions, by {@link classifyAutoYesQuestion}:
102
+ *
103
+ * - a question reader's picker (Claude's AskUserQuestion, Command Code's
104
+ * question screen) — left to a human under the `careful` answer mode; under
105
+ * `recommended` it goes on to step 4, which answers it with its recommended
106
+ * option (`auto-yes-question-choice`). Judged without the dialog gate, so a
107
+ * `legacy` tool and the `CM_AUTOYES_DIALOG_GATE` kill switch change nothing
108
+ * here;
109
+ * - OpenCode V2's question form — left to a human under either mode;
110
+ * - Issue #3881: a copilot / codex numbered list nothing marks as a question
111
+ * or as a permission (`'unidentified'`) — left to a human under `careful`;
112
+ * under `recommended` it goes on to step 4 and is answered as before.
113
+ *
114
+ * Not a contract verdict, so `allowPromptTypes` cannot bring it back: an
115
+ * `allow-listed` contract naming `multiple_choice` delegates permission
116
+ * dialogs, not the operator's questions.
117
+ *
118
+ * Recorded as `question-left-to-human` — a question in general, not the
119
+ * `Submit` / `Cancel` confirm page that follows one (`question-confirm-page`,
120
+ * #3748, recorded at step 3.3 before this step is reached).
121
+ *
122
+ * @returns true when the prompt is withheld (the caller returns `no_answer`)
123
+ */
124
+ function withheldAsQuestion(judged) {
125
+ const { promptData, dialogGate, cliToolId } = judged;
126
+ const kind = (0, auto_yes_dialog_gate_1.classifyAutoYesQuestion)(promptData, dialogGate, cliToolId);
127
+ if (kind === null)
128
+ return false;
129
+ const answerMode = judged.answerMode ?? auto_yes_answer_mode_1.DEFAULT_AUTO_YES_ANSWER_MODE;
130
+ if ((0, auto_yes_dialog_gate_1.autoYesQuestionTreatment)(kind, answerMode) !== 'left-to-human')
131
+ return false;
132
+ withholdQuestion(judged, answerMode, false, kind);
133
+ return true;
134
+ }
135
+ /** Record a question left to a human (`question-left-to-human`), warning once per frame. */
136
+ function withholdQuestion(judged, answerMode, atSend, kind) {
137
+ const { promptData, frameKey, dialogGate } = judged;
138
+ (0, auto_yes_prompt_suppression_1.suppressAndWarnOnce)(judged, { reason: auto_yes_suppression_reason_1.QUESTION_LEFT_TO_HUMAN_SUPPRESSION_REASON, mode: null, promptType: promptData.type }, `${frameKey}\u0000question`, 'poller:auto-yes-skipped-question', {
139
+ reason: auto_yes_suppression_reason_1.QUESTION_LEFT_TO_HUMAN_SUPPRESSION_REASON,
140
+ promptType: promptData.type,
141
+ dialogKind: dialogGate?.dialog?.kind ?? null,
142
+ // Issue #3881: `unidentified` — not known to be a question, nor not one.
143
+ questionKind: kind,
144
+ question: (0, auto_yes_prompt_suppression_1.truncateForLog)(promptData.question),
145
+ answerMode,
146
+ ...(atSend ? { atSend: true } : {}),
147
+ });
148
+ }
149
+ /**
150
+ * The last look before a key (Issue #3822): is the answer still Auto-Yes's to
151
+ * send? Asked after the last wait before the send (the ownership check), so
152
+ * nothing it reads can change before the first key goes out.
153
+ *
154
+ * - With a `generation` (a poller tick), Auto-Yes must still be on and inside
155
+ * its window. `getAutoYesState` disables an expired grant on read, the
156
+ * boundary the hook and the next tick see. Without one (direct callers,
157
+ * tests) the grant is not checked, as the tick checks nothing then (#3706).
158
+ * - The contract is read again past the policy cache, so a switched contract,
159
+ * an `off`, or a deny pattern added since the tick's lookup withholds the
160
+ * key. A read that fails is "contract unknown" (`policy-lookup-failed`), as
161
+ * in step 4, and so is a grant that cannot be read.
162
+ * - Issue #3863: the answer mode is read off that grant again. A question the
163
+ * `careful` mode leaves to a human gets no key, whatever the tick began
164
+ * under; the question's answer is resolved again under the mode as it is.
165
+ * (A mode change replaces the grant, so a tick that began under the old one
166
+ * has usually stopped at its last generation check already.)
167
+ *
168
+ * The `PermissionRequest` hook is not asked this: its `allow` IS the answer,
169
+ * decided against the grant and the contract when the hook is answered, and
170
+ * nothing is typed afterwards for a later look to stop.
171
+ *
172
+ * @param checkGrant - Whether the grant is checked (a tick with a generation)
173
+ * @returns true when the key is withheld (the caller returns `no_answer`)
174
+ */
175
+ function withheldAtSend(judged, checkGrant) {
176
+ const { worktreeId, cliToolId, instanceId, pollerState, promptData, frameKey } = judged;
177
+ let answerMode = judged.answerMode ?? auto_yes_answer_mode_1.DEFAULT_AUTO_YES_ANSWER_MODE;
178
+ if (checkGrant) {
179
+ let grant;
180
+ try {
181
+ grant = (0, auto_yes_state_1.getAutoYesState)(worktreeId, cliToolId, instanceId);
182
+ }
183
+ catch {
184
+ return withholdAsUnknown(judged);
185
+ }
186
+ if (!grant?.enabled) {
187
+ // Auto-Yes is off: nothing is recorded as withheld (the poller stops on
188
+ // its next tick and the state says why), only that the key was not sent.
189
+ (0, auto_yes_poller_state_1.warnOncePerFrame)(pollerState, `${frameKey}\u0000at-send-disabled`, 'poller:auto-yes-withheld-at-send', {
190
+ worktreeId,
191
+ cliToolId,
192
+ instanceId,
193
+ reason: grant?.stopReason === 'expired' ? 'expired' : 'auto-yes-disabled',
194
+ promptType: promptData.type,
195
+ });
196
+ return true;
197
+ }
198
+ answerMode = (0, auto_yes_state_1.autoYesAnswerModeOf)(grant);
199
+ const questionKind = (0, auto_yes_dialog_gate_1.classifyAutoYesQuestion)(promptData, judged.dialogGate, cliToolId);
200
+ if (answerMode === 'careful' && questionKind !== null
201
+ && (0, auto_yes_dialog_gate_1.autoYesQuestionTreatment)(questionKind, answerMode) === 'left-to-human') {
202
+ withholdQuestion(judged, answerMode, true, questionKind);
203
+ return true;
204
+ }
205
+ }
206
+ const policy = (0, auto_yes_policy_1.getSessionAutoYesPolicy)(worktreeId, cliToolId, instanceId, { fresh: true });
207
+ const resolution = (0, auto_yes_resolver_1.resolveAutoAnswerWithPolicy)(promptData, policy, cliToolId, questionAnsweringOf(judged, answerMode));
208
+ if (resolution.suppressedBy) {
209
+ const mode = (0, auto_yes_resolver_1.policyLookupMode)(policy);
210
+ (0, auto_yes_prompt_suppression_1.suppressAndWarnOnce)(judged, { reason: resolution.suppressedBy, mode, promptType: promptData.type, pattern: resolution.pattern }, `${frameKey}\u0000${resolution.suppressedBy}\u0000${mode ?? ''}\u0000${resolution.pattern ?? ''}`, 'poller:auto-yes-suppressed-by-policy', {
211
+ reason: resolution.suppressedBy,
212
+ mode,
213
+ pattern: resolution.pattern,
214
+ promptType: promptData.type,
215
+ atSend: true,
216
+ });
217
+ return true;
218
+ }
219
+ return false;
220
+ }
221
+ function withholdAsUnknown(judged) {
222
+ const { promptData, frameKey } = judged;
223
+ (0, auto_yes_prompt_suppression_1.suppressAndWarnOnce)(judged, { reason: auto_yes_suppression_reason_1.POLICY_LOOKUP_FAILED_SUPPRESSION_REASON, mode: null, promptType: promptData.type }, `${frameKey}\u0000${auto_yes_suppression_reason_1.POLICY_LOOKUP_FAILED_SUPPRESSION_REASON}\u0000at-send`, 'poller:auto-yes-suppressed-by-policy', { reason: auto_yes_suppression_reason_1.POLICY_LOOKUP_FAILED_SUPPRESSION_REASON, mode: null, promptType: promptData.type, atSend: true });
224
+ return true;
225
+ }
57
226
  /**
58
227
  * Step 4 of `detectAndRespondToPrompt`: the auto answer under the execution
59
228
  * contract's policy, recording the suppression when the policy withholds it.
@@ -64,7 +233,8 @@ function resolveAnswerUnderPolicy(judged) {
64
233
  const { worktreeId, cliToolId, instanceId, promptData, frameKey } = judged;
65
234
  // Issue #3822: a failed lookup reaches the resolver as unknown and withholds.
66
235
  const policy = (0, auto_yes_policy_1.getSessionAutoYesPolicy)(worktreeId, cliToolId, instanceId);
67
- const resolution = (0, auto_yes_resolver_1.resolveAutoAnswerWithPolicy)(promptData, policy);
236
+ // Issue #3863: a question the `recommended` mode answers takes its recommended option.
237
+ const resolution = (0, auto_yes_resolver_1.resolveAutoAnswerWithPolicy)(promptData, policy, cliToolId, questionAnsweringOf(judged, judged.answerMode ?? auto_yes_answer_mode_1.DEFAULT_AUTO_YES_ANSWER_MODE));
68
238
  if (resolution.suppressedBy) {
69
239
  const mode = (0, auto_yes_resolver_1.policyLookupMode)(policy);
70
240
  // Issue #1684: the log line alone leaves a CLI-driven pipeline blind to
@@ -247,8 +247,8 @@ function suppressIfNotOursToAnswer(prompt, frame) {
247
247
  //
248
248
  // Issue #3748: Claude's confirmation page (`Ready to submit your answers?` /
249
249
  // `❯ 1. Submit answers` / `2. Cancel`) is the same page and is declined the
250
- // same way. Judged by `isAutoYesDeclinedConfirmPage`, which the browser's
251
- // fallback (`useAutoYes`) asks too, and recorded with a reason of its own,
250
+ // same way. Judged by `isAutoYesDeclinedConfirmPage` (the browser's fallback,
251
+ // `useAutoYes`, read the same page by its options until #3821 retired it), and recorded with a reason of its own,
252
252
  // `question-confirm-page`, which `cmate wait` names as such (it reused
253
253
  // `unclassified-frame`, whose wording says no detector recognised the frame).
254
254
  if ((0, auto_yes_confirm_page_1.isAutoYesDeclinedConfirmPage)(cliToolId, frame)) {