crewly 1.20.355 → 1.20.358

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 (393) hide show
  1. package/config/constants.ts +11 -0
  2. package/config/roles/team-leader/prompt.md +1 -1
  3. package/config/roles/team-leader/tl-addon.md +1 -1
  4. package/config/skills/team-leader/delegate-task/SKILL.md +23 -1
  5. package/config/skills/team-leader/delegate-task/execute.sh +44 -1
  6. package/config/skills/team-leader/delegate-task/execute.test.sh +95 -1
  7. package/dist/backend/backend/src/constants.d.ts +319 -17
  8. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  9. package/dist/backend/backend/src/constants.js +322 -17
  10. package/dist/backend/backend/src/constants.js.map +1 -1
  11. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.d.ts.map +1 -1
  12. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js +10 -0
  13. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js.map +1 -1
  14. package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.d.ts.map +1 -1
  15. package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.js +7 -0
  16. package/dist/backend/backend/src/controllers/orchestrator/orchestrator.controller.js.map +1 -1
  17. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  18. package/dist/backend/backend/src/controllers/team/team.controller.js +5 -0
  19. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  20. package/dist/backend/backend/src/index.d.ts +15 -0
  21. package/dist/backend/backend/src/index.d.ts.map +1 -1
  22. package/dist/backend/backend/src/index.js +138 -15
  23. package/dist/backend/backend/src/index.js.map +1 -1
  24. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +21 -2
  25. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  26. package/dist/backend/backend/src/services/agent/agent-registration.service.js +100 -3
  27. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  28. package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.d.ts +34 -1
  29. package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.d.ts.map +1 -1
  30. package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.js +69 -13
  31. package/dist/backend/backend/src/services/agent/fresh-task-conversation.service.js.map +1 -1
  32. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts +8 -0
  33. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts.map +1 -1
  34. package/dist/backend/backend/src/services/agent/idle-detection.service.js +26 -2
  35. package/dist/backend/backend/src/services/agent/idle-detection.service.js.map +1 -1
  36. package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +9 -1
  37. package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
  38. package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js +60 -4
  39. package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -1
  40. package/dist/backend/backend/src/services/agent/resource-mode-protection.d.ts +22 -0
  41. package/dist/backend/backend/src/services/agent/resource-mode-protection.d.ts.map +1 -1
  42. package/dist/backend/backend/src/services/agent/resource-mode-protection.js +33 -0
  43. package/dist/backend/backend/src/services/agent/resource-mode-protection.js.map +1 -1
  44. package/dist/backend/backend/src/services/agent/resource-mode.service.d.ts +59 -3
  45. package/dist/backend/backend/src/services/agent/resource-mode.service.d.ts.map +1 -1
  46. package/dist/backend/backend/src/services/agent/resource-mode.service.js +108 -10
  47. package/dist/backend/backend/src/services/agent/resource-mode.service.js.map +1 -1
  48. package/dist/backend/backend/src/services/agent/runtime-session-recovery.d.ts +44 -3
  49. package/dist/backend/backend/src/services/agent/runtime-session-recovery.d.ts.map +1 -1
  50. package/dist/backend/backend/src/services/agent/runtime-session-recovery.js +126 -11
  51. package/dist/backend/backend/src/services/agent/runtime-session-recovery.js.map +1 -1
  52. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +2 -0
  53. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  54. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +9 -1
  55. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  56. package/dist/backend/backend/src/services/harness/harness-relogin.service.d.ts +23 -0
  57. package/dist/backend/backend/src/services/harness/harness-relogin.service.d.ts.map +1 -1
  58. package/dist/backend/backend/src/services/harness/harness-relogin.service.js +47 -6
  59. package/dist/backend/backend/src/services/harness/harness-relogin.service.js.map +1 -1
  60. package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.d.ts +150 -0
  61. package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.d.ts.map +1 -0
  62. package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.js +319 -0
  63. package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.js.map +1 -0
  64. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts +9 -7
  65. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts.map +1 -1
  66. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js +19 -17
  67. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js.map +1 -1
  68. package/dist/backend/backend/src/services/memory/memory.service.d.ts.map +1 -1
  69. package/dist/backend/backend/src/services/memory/memory.service.js +11 -0
  70. package/dist/backend/backend/src/services/memory/memory.service.js.map +1 -1
  71. package/dist/backend/backend/src/services/memory/startup-briefing.service.d.ts +104 -0
  72. package/dist/backend/backend/src/services/memory/startup-briefing.service.d.ts.map +1 -0
  73. package/dist/backend/backend/src/services/memory/startup-briefing.service.js +302 -0
  74. package/dist/backend/backend/src/services/memory/startup-briefing.service.js.map +1 -0
  75. package/dist/backend/backend/src/services/messaging/deferred-start-retry.d.ts +14 -2
  76. package/dist/backend/backend/src/services/messaging/deferred-start-retry.d.ts.map +1 -1
  77. package/dist/backend/backend/src/services/messaging/deferred-start-retry.js +21 -4
  78. package/dist/backend/backend/src/services/messaging/deferred-start-retry.js.map +1 -1
  79. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.d.ts +33 -1
  80. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.d.ts.map +1 -1
  81. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.js +69 -4
  82. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.js.map +1 -1
  83. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.wiring.d.ts +24 -1
  84. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.wiring.d.ts.map +1 -1
  85. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.wiring.js +54 -3
  86. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.wiring.js.map +1 -1
  87. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  88. package/dist/backend/backend/src/services/messaging/queue-processor.service.js +10 -1
  89. package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  90. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts +8 -0
  91. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
  92. package/dist/backend/backend/src/services/open-items/open-items.service.js +33 -0
  93. package/dist/backend/backend/src/services/open-items/open-items.service.js.map +1 -1
  94. package/dist/backend/backend/src/services/open-items/open-items.wiring.js +2 -2
  95. package/dist/backend/backend/src/services/open-items/open-items.wiring.js.map +1 -1
  96. package/dist/backend/backend/src/services/open-items/question-card-gate.d.ts +49 -0
  97. package/dist/backend/backend/src/services/open-items/question-card-gate.d.ts.map +1 -0
  98. package/dist/backend/backend/src/services/open-items/question-card-gate.js +77 -0
  99. package/dist/backend/backend/src/services/open-items/question-card-gate.js.map +1 -0
  100. package/dist/backend/backend/src/services/orc/owner-completion-report.service.d.ts +9 -0
  101. package/dist/backend/backend/src/services/orc/owner-completion-report.service.d.ts.map +1 -1
  102. package/dist/backend/backend/src/services/orc/owner-completion-report.service.js +16 -2
  103. package/dist/backend/backend/src/services/orc/owner-completion-report.service.js.map +1 -1
  104. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.d.ts.map +1 -1
  105. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js +10 -0
  106. package/dist/backend/backend/src/services/orchestrator/orchestrator-heartbeat-monitor.service.js.map +1 -1
  107. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.d.ts +2 -0
  108. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.d.ts.map +1 -1
  109. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.js +17 -0
  110. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.js.map +1 -1
  111. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.d.ts +7 -0
  112. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.d.ts.map +1 -1
  113. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js +22 -10
  114. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js.map +1 -1
  115. package/dist/backend/backend/src/services/project-tickets/ticket-prefixes.d.ts +30 -0
  116. package/dist/backend/backend/src/services/project-tickets/ticket-prefixes.d.ts.map +1 -0
  117. package/dist/backend/backend/src/services/project-tickets/ticket-prefixes.js +48 -0
  118. package/dist/backend/backend/src/services/project-tickets/ticket-prefixes.js.map +1 -0
  119. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts +8 -0
  120. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
  121. package/dist/backend/backend/src/services/reconciler/reconciler.service.js +29 -8
  122. package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
  123. package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.d.ts +16 -0
  124. package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.d.ts.map +1 -1
  125. package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.js +23 -0
  126. package/dist/backend/backend/src/services/runtime-fallback/effective-runtime.js.map +1 -1
  127. package/dist/backend/backend/src/services/runtime-fallback/reset-time.d.ts +2 -1
  128. package/dist/backend/backend/src/services/runtime-fallback/reset-time.d.ts.map +1 -1
  129. package/dist/backend/backend/src/services/runtime-fallback/reset-time.js +3 -2
  130. package/dist/backend/backend/src/services/runtime-fallback/reset-time.js.map +1 -1
  131. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.d.ts +128 -5
  132. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.d.ts.map +1 -1
  133. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.js +320 -38
  134. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.js.map +1 -1
  135. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.d.ts +23 -0
  136. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.d.ts.map +1 -1
  137. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.js +48 -3
  138. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.js.map +1 -1
  139. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-rules.d.ts +78 -0
  140. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-rules.d.ts.map +1 -1
  141. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-rules.js +159 -1
  142. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-rules.js.map +1 -1
  143. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-screen.d.ts +63 -0
  144. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-screen.d.ts.map +1 -0
  145. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-screen.js +104 -0
  146. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-screen.js.map +1 -0
  147. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-state.d.ts +166 -0
  148. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-state.d.ts.map +1 -0
  149. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-state.js +207 -0
  150. package/dist/backend/backend/src/services/runtime-fallback/usage-limit-state.js.map +1 -0
  151. package/dist/backend/backend/src/services/slack/agent-coordination.d.ts +119 -0
  152. package/dist/backend/backend/src/services/slack/agent-coordination.d.ts.map +1 -0
  153. package/dist/backend/backend/src/services/slack/agent-coordination.js +174 -0
  154. package/dist/backend/backend/src/services/slack/agent-coordination.js.map +1 -0
  155. package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
  156. package/dist/backend/backend/src/services/slack/slack-initializer.js +7 -0
  157. package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
  158. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +167 -0
  159. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  160. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +619 -9
  161. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  162. package/dist/backend/backend/src/services/slack/slack-thread-context.service.d.ts +22 -0
  163. package/dist/backend/backend/src/services/slack/slack-thread-context.service.d.ts.map +1 -1
  164. package/dist/backend/backend/src/services/slack/slack-thread-context.service.js +49 -12
  165. package/dist/backend/backend/src/services/slack/slack-thread-context.service.js.map +1 -1
  166. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts +7 -0
  167. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
  168. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js +25 -4
  169. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
  170. package/dist/backend/backend/src/services/team-move/team-move-chat.d.ts +21 -1
  171. package/dist/backend/backend/src/services/team-move/team-move-chat.d.ts.map +1 -1
  172. package/dist/backend/backend/src/services/team-move/team-move-chat.js +54 -2
  173. package/dist/backend/backend/src/services/team-move/team-move-chat.js.map +1 -1
  174. package/dist/backend/backend/src/services/team-move/team-move-exporter.d.ts +9 -4
  175. package/dist/backend/backend/src/services/team-move/team-move-exporter.d.ts.map +1 -1
  176. package/dist/backend/backend/src/services/team-move/team-move-exporter.js +32 -10
  177. package/dist/backend/backend/src/services/team-move/team-move-exporter.js.map +1 -1
  178. package/dist/backend/backend/src/services/team-move/team-move-importer.d.ts +19 -0
  179. package/dist/backend/backend/src/services/team-move/team-move-importer.d.ts.map +1 -1
  180. package/dist/backend/backend/src/services/team-move/team-move-importer.js +78 -3
  181. package/dist/backend/backend/src/services/team-move/team-move-importer.js.map +1 -1
  182. package/dist/backend/backend/src/services/team-move/team-move-runtime.d.ts.map +1 -1
  183. package/dist/backend/backend/src/services/team-move/team-move-runtime.js +8 -0
  184. package/dist/backend/backend/src/services/team-move/team-move-runtime.js.map +1 -1
  185. package/dist/backend/backend/src/services/team-move/team-move-transcripts.d.ts +106 -0
  186. package/dist/backend/backend/src/services/team-move/team-move-transcripts.d.ts.map +1 -0
  187. package/dist/backend/backend/src/services/team-move/team-move-transcripts.js +212 -0
  188. package/dist/backend/backend/src/services/team-move/team-move-transcripts.js.map +1 -0
  189. package/dist/backend/backend/src/services/team-move/team-move.types.d.ts +20 -0
  190. package/dist/backend/backend/src/services/team-move/team-move.types.d.ts.map +1 -1
  191. package/dist/backend/backend/src/services/team-move/team-move.types.js.map +1 -1
  192. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.d.ts +2 -2
  193. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.d.ts.map +1 -1
  194. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js +11 -4
  195. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js.map +1 -1
  196. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
  197. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +13 -0
  198. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
  199. package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.d.ts.map +1 -1
  200. package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.js +3 -0
  201. package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.js.map +1 -1
  202. package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.d.ts.map +1 -1
  203. package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.js +4 -1
  204. package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.js.map +1 -1
  205. package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.d.ts.map +1 -1
  206. package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.js +4 -0
  207. package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.js.map +1 -1
  208. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts +33 -4
  209. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -1
  210. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.js +75 -7
  211. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.js.map +1 -1
  212. package/dist/backend/backend/src/services/wiki/wiki-lint.service.d.ts.map +1 -1
  213. package/dist/backend/backend/src/services/wiki/wiki-lint.service.js +3 -1
  214. package/dist/backend/backend/src/services/wiki/wiki-lint.service.js.map +1 -1
  215. package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.d.ts +116 -0
  216. package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.d.ts.map +1 -0
  217. package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.js +227 -0
  218. package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.js.map +1 -0
  219. package/dist/backend/backend/src/services/wiki/wiki-log-entries.d.ts +142 -0
  220. package/dist/backend/backend/src/services/wiki/wiki-log-entries.d.ts.map +1 -0
  221. package/dist/backend/backend/src/services/wiki/wiki-log-entries.js +222 -0
  222. package/dist/backend/backend/src/services/wiki/wiki-log-entries.js.map +1 -0
  223. package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.d.ts +93 -0
  224. package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.d.ts.map +1 -0
  225. package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.js +142 -0
  226. package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.js.map +1 -0
  227. package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.d.ts +104 -0
  228. package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.d.ts.map +1 -0
  229. package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.js +192 -0
  230. package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.js.map +1 -0
  231. package/dist/backend/backend/src/services/wiki/wiki-query.service.d.ts +3 -2
  232. package/dist/backend/backend/src/services/wiki/wiki-query.service.d.ts.map +1 -1
  233. package/dist/backend/backend/src/services/wiki/wiki-query.service.js +23 -39
  234. package/dist/backend/backend/src/services/wiki/wiki-query.service.js.map +1 -1
  235. package/dist/backend/backend/src/services/wiki/wiki-queue-drain.service.d.ts +105 -0
  236. package/dist/backend/backend/src/services/wiki/wiki-queue-drain.service.d.ts.map +1 -0
  237. package/dist/backend/backend/src/services/wiki/wiki-queue-drain.service.js +195 -0
  238. package/dist/backend/backend/src/services/wiki/wiki-queue-drain.service.js.map +1 -0
  239. package/dist/backend/backend/src/services/wiki/wiki-recent.service.d.ts.map +1 -1
  240. package/dist/backend/backend/src/services/wiki/wiki-recent.service.js +3 -0
  241. package/dist/backend/backend/src/services/wiki/wiki-recent.service.js.map +1 -1
  242. package/dist/backend/backend/src/services/wiki/wiki-search.service.d.ts +28 -5
  243. package/dist/backend/backend/src/services/wiki/wiki-search.service.d.ts.map +1 -1
  244. package/dist/backend/backend/src/services/wiki/wiki-search.service.js +96 -25
  245. package/dist/backend/backend/src/services/wiki/wiki-search.service.js.map +1 -1
  246. package/dist/backend/backend/src/services/wiki/wiki-vault-walk.d.ts +11 -0
  247. package/dist/backend/backend/src/services/wiki/wiki-vault-walk.d.ts.map +1 -1
  248. package/dist/backend/backend/src/services/wiki/wiki-vault-walk.js +17 -1
  249. package/dist/backend/backend/src/services/wiki/wiki-vault-walk.js.map +1 -1
  250. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts +22 -0
  251. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
  252. package/dist/backend/backend/src/services/workflow/scheduler.service.js +35 -1
  253. package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
  254. package/dist/backend/backend/src/types/index.d.ts +12 -0
  255. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  256. package/dist/backend/backend/src/types/index.js.map +1 -1
  257. package/dist/backend/backend/src/types/team-template.types.d.ts +1 -0
  258. package/dist/backend/backend/src/types/team-template.types.d.ts.map +1 -1
  259. package/dist/backend/backend/src/types/team-template.types.js.map +1 -1
  260. package/dist/backend/build-info.json +2 -2
  261. package/dist/backend/config/constants.d.ts +11 -0
  262. package/dist/backend/config/constants.d.ts.map +1 -1
  263. package/dist/backend/config/constants.js +11 -0
  264. package/dist/backend/config/constants.js.map +1 -1
  265. package/dist/cli/backend/src/constants.d.ts +319 -17
  266. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  267. package/dist/cli/backend/src/constants.js +322 -17
  268. package/dist/cli/backend/src/constants.js.map +1 -1
  269. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts +21 -2
  270. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  271. package/dist/cli/backend/src/services/agent/agent-registration.service.js +100 -3
  272. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
  273. package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.d.ts +34 -1
  274. package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.d.ts.map +1 -1
  275. package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.js +69 -13
  276. package/dist/cli/backend/src/services/agent/fresh-task-conversation.service.js.map +1 -1
  277. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +9 -1
  278. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
  279. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js +60 -4
  280. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -1
  281. package/dist/cli/backend/src/services/agent/resource-mode.service.d.ts +59 -3
  282. package/dist/cli/backend/src/services/agent/resource-mode.service.d.ts.map +1 -1
  283. package/dist/cli/backend/src/services/agent/resource-mode.service.js +108 -10
  284. package/dist/cli/backend/src/services/agent/resource-mode.service.js.map +1 -1
  285. package/dist/cli/backend/src/services/agent/runtime-session-recovery.d.ts +44 -3
  286. package/dist/cli/backend/src/services/agent/runtime-session-recovery.d.ts.map +1 -1
  287. package/dist/cli/backend/src/services/agent/runtime-session-recovery.js +126 -11
  288. package/dist/cli/backend/src/services/agent/runtime-session-recovery.js.map +1 -1
  289. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +2 -0
  290. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  291. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +9 -1
  292. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  293. package/dist/cli/backend/src/services/harness/harness-relogin.service.d.ts +23 -0
  294. package/dist/cli/backend/src/services/harness/harness-relogin.service.d.ts.map +1 -1
  295. package/dist/cli/backend/src/services/harness/harness-relogin.service.js +47 -6
  296. package/dist/cli/backend/src/services/harness/harness-relogin.service.js.map +1 -1
  297. package/dist/cli/backend/src/services/memory/memory.service.d.ts.map +1 -1
  298. package/dist/cli/backend/src/services/memory/memory.service.js +11 -0
  299. package/dist/cli/backend/src/services/memory/memory.service.js.map +1 -1
  300. package/dist/cli/backend/src/services/memory/startup-briefing.service.d.ts +104 -0
  301. package/dist/cli/backend/src/services/memory/startup-briefing.service.d.ts.map +1 -0
  302. package/dist/cli/backend/src/services/memory/startup-briefing.service.js +302 -0
  303. package/dist/cli/backend/src/services/memory/startup-briefing.service.js.map +1 -0
  304. package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.d.ts +33 -1
  305. package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.d.ts.map +1 -1
  306. package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.js +69 -4
  307. package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.js.map +1 -1
  308. package/dist/cli/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  309. package/dist/cli/backend/src/services/messaging/queue-processor.service.js +10 -1
  310. package/dist/cli/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  311. package/dist/cli/backend/src/services/open-items/open-items.service.d.ts +8 -0
  312. package/dist/cli/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
  313. package/dist/cli/backend/src/services/open-items/open-items.service.js +33 -0
  314. package/dist/cli/backend/src/services/open-items/open-items.service.js.map +1 -1
  315. package/dist/cli/backend/src/services/open-items/question-card-gate.d.ts +49 -0
  316. package/dist/cli/backend/src/services/open-items/question-card-gate.d.ts.map +1 -0
  317. package/dist/cli/backend/src/services/open-items/question-card-gate.js +77 -0
  318. package/dist/cli/backend/src/services/open-items/question-card-gate.js.map +1 -0
  319. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.d.ts +2 -0
  320. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.d.ts.map +1 -1
  321. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.js +17 -0
  322. package/dist/cli/backend/src/services/orchestrator/orchestrator-restart.service.js.map +1 -1
  323. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.d.ts +7 -0
  324. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.d.ts.map +1 -1
  325. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.js +22 -10
  326. package/dist/cli/backend/src/services/orchestrator/orchestrator-status.service.js.map +1 -1
  327. package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.d.ts +16 -0
  328. package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.d.ts.map +1 -1
  329. package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.js +23 -0
  330. package/dist/cli/backend/src/services/runtime-fallback/effective-runtime.js.map +1 -1
  331. package/dist/cli/backend/src/services/runtime-fallback/reset-time.d.ts +2 -1
  332. package/dist/cli/backend/src/services/runtime-fallback/reset-time.d.ts.map +1 -1
  333. package/dist/cli/backend/src/services/runtime-fallback/reset-time.js +3 -2
  334. package/dist/cli/backend/src/services/runtime-fallback/reset-time.js.map +1 -1
  335. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.d.ts +78 -0
  336. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.d.ts.map +1 -1
  337. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.js +159 -1
  338. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-rules.js.map +1 -1
  339. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-screen.d.ts +63 -0
  340. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-screen.d.ts.map +1 -0
  341. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-screen.js +104 -0
  342. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-screen.js.map +1 -0
  343. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-state.d.ts +166 -0
  344. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-state.d.ts.map +1 -0
  345. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-state.js +207 -0
  346. package/dist/cli/backend/src/services/runtime-fallback/usage-limit-state.js.map +1 -0
  347. package/dist/cli/backend/src/services/slack/agent-coordination.d.ts +119 -0
  348. package/dist/cli/backend/src/services/slack/agent-coordination.d.ts.map +1 -0
  349. package/dist/cli/backend/src/services/slack/agent-coordination.js +174 -0
  350. package/dist/cli/backend/src/services/slack/agent-coordination.js.map +1 -0
  351. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +167 -0
  352. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  353. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +619 -9
  354. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  355. package/dist/cli/backend/src/services/slack/slack-thread-context.service.d.ts +22 -0
  356. package/dist/cli/backend/src/services/slack/slack-thread-context.service.d.ts.map +1 -1
  357. package/dist/cli/backend/src/services/slack/slack-thread-context.service.js +49 -12
  358. package/dist/cli/backend/src/services/slack/slack-thread-context.service.js.map +1 -1
  359. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts +7 -0
  360. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
  361. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js +25 -4
  362. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
  363. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.d.ts +33 -4
  364. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -1
  365. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.js +75 -7
  366. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.js.map +1 -1
  367. package/dist/cli/backend/src/services/wiki/wiki-log-entries.d.ts +142 -0
  368. package/dist/cli/backend/src/services/wiki/wiki-log-entries.d.ts.map +1 -0
  369. package/dist/cli/backend/src/services/wiki/wiki-log-entries.js +222 -0
  370. package/dist/cli/backend/src/services/wiki/wiki-log-entries.js.map +1 -0
  371. package/dist/cli/backend/src/services/wiki/wiki-recent.service.d.ts +51 -0
  372. package/dist/cli/backend/src/services/wiki/wiki-recent.service.d.ts.map +1 -0
  373. package/dist/cli/backend/src/services/wiki/wiki-recent.service.js +105 -0
  374. package/dist/cli/backend/src/services/wiki/wiki-recent.service.js.map +1 -0
  375. package/dist/cli/backend/src/services/wiki/wiki-search.service.d.ts +28 -5
  376. package/dist/cli/backend/src/services/wiki/wiki-search.service.d.ts.map +1 -1
  377. package/dist/cli/backend/src/services/wiki/wiki-search.service.js +96 -25
  378. package/dist/cli/backend/src/services/wiki/wiki-search.service.js.map +1 -1
  379. package/dist/cli/backend/src/services/wiki/wiki-vault-walk.d.ts +11 -0
  380. package/dist/cli/backend/src/services/wiki/wiki-vault-walk.d.ts.map +1 -1
  381. package/dist/cli/backend/src/services/wiki/wiki-vault-walk.js +17 -1
  382. package/dist/cli/backend/src/services/wiki/wiki-vault-walk.js.map +1 -1
  383. package/dist/cli/backend/src/types/index.d.ts +12 -0
  384. package/dist/cli/backend/src/types/index.d.ts.map +1 -1
  385. package/dist/cli/backend/src/types/index.js.map +1 -1
  386. package/dist/cli/backend/src/types/team-template.types.d.ts +1 -0
  387. package/dist/cli/backend/src/types/team-template.types.d.ts.map +1 -1
  388. package/dist/cli/backend/src/types/team-template.types.js.map +1 -1
  389. package/dist/cli/config/constants.d.ts +11 -0
  390. package/dist/cli/config/constants.d.ts.map +1 -1
  391. package/dist/cli/config/constants.js +11 -0
  392. package/dist/cli/config/constants.js.map +1 -1
  393. package/package.json +1 -1
@@ -24,6 +24,17 @@
24
24
  * most every BILLING_PROBE_INTERVAL_MS. A switch-back that fails (the limit
25
25
  * comes straight back) doubles the next probe interval.
26
26
  * 7. **Tell the owner once** per event, and once when it is over.
27
+ * 8. **Prefer the better target.** While the configured runtime is still out,
28
+ * an agent on a fallback moves (at an idle boundary, or when it is next
29
+ * started) to the earliest available entry of its chain when that is
30
+ * earlier than the one it is on — orc on `claude-code@work` goes back to
31
+ * `claude-code` once the default login has usage, even though its own
32
+ * runtime (DeepSeek, out of credit) is not back.
33
+ * 9. **Stale marks are cleared** when the reset time passes and a probe
34
+ * answers, when the owner signs that login in again
35
+ * ({@link RuntimeFallbackService.onRuntimeLogin} /
36
+ * {@link RuntimeFallbackService.onAccountLogin}), or when another session
37
+ * on that target is seen working ({@link RuntimeFallbackService.reportWorking}).
27
38
  *
28
39
  * A chain entry may be one of the owner's other Claude Code accounts
29
40
  * (`claude-code@work`, issue #942): it is a runtime target of its own — out
@@ -41,6 +52,7 @@
41
52
  */
42
53
  import { ORCHESTRATOR_SESSION_NAME, RUNTIME_FALLBACK_CONSTANTS, RUNTIME_TYPES } from '../../constants.js';
43
54
  import { detectUsageLimit } from './usage-limit-rules.js';
55
+ import { clearUsageLimit } from './usage-limit-state.js';
44
56
  import { traceRuntimeBlocked } from '../trace/trace-recorder.js';
45
57
  import { accountOf, baseRuntimeOf, parseRuntimeTarget, runtimeTarget } from '../harness/claude-accounts.js';
46
58
  import { applySettingsPatch, runtimeLabel, runtimeShortLabel, } from './runtime-fallback.types.js';
@@ -76,6 +88,8 @@ export class RuntimeFallbackService {
76
88
  noticeDue = new Map();
77
89
  /** Kickoff notes waiting for a session's next launch */
78
90
  kickoffNotes = new Map();
91
+ /** Last working-evidence look per session (throttle) */
92
+ workingSeen = new Map();
79
93
  /** Last switch-back per runtime, to recognise one that failed */
80
94
  recentRecoveries = new Map();
81
95
  availability = null;
@@ -179,7 +193,7 @@ export class RuntimeFallbackService {
179
193
  this.availability = null;
180
194
  const target = runtimeTarget(RUNTIME_TYPES.CLAUDE_CODE, account);
181
195
  try {
182
- await this.recoverSignedOutAccount(target);
196
+ await this.recheckAfterLogin(target);
183
197
  }
184
198
  finally {
185
199
  // The owner is away: a freshly signed-in account must be usable at once,
@@ -254,27 +268,94 @@ export class RuntimeFallbackService {
254
268
  }
255
269
  }
256
270
  /**
257
- * If the account was marked signed out, probe it and bring it back.
271
+ * The owner signed a harness's default login in again (the re-login flow
272
+ * finished for it). A mark on that runtime — signed out, or out of usage:
273
+ * the new login may be another account, or the same one with usage bought
274
+ * — is probed now instead of at its reset time, and cleared when the
275
+ * probe answers.
258
276
  *
259
- * @param target - `claude-code@<account>`
277
+ * @param runtime - Runtime id (`claude-code`, `codex-cli`, …; the harness id)
278
+ * @returns Resolves when done; never rejects
279
+ *
280
+ * @example
281
+ * ```ts
282
+ * relogin.setHarnessLoginHandler((harnessId) => service.onRuntimeLogin(harnessId));
283
+ * ```
260
284
  */
261
- async recoverSignedOutAccount(target) {
285
+ async onRuntimeLogin(runtime) {
286
+ this.availability = null;
287
+ try {
288
+ await this.recheckAfterLogin(runtime);
289
+ }
290
+ catch (err) {
291
+ this.logger.warn('Re-checking a runtime after a sign-in failed', { runtime, error: err instanceof Error ? err.message : String(err) });
292
+ }
293
+ }
294
+ /**
295
+ * A login of a runtime target was signed in again: if it is marked (signed
296
+ * out or out of usage), probe it and bring it back when it answers.
297
+ *
298
+ * @param target - Runtime target (`claude-code`, `claude-code@<account>`)
299
+ */
300
+ async recheckAfterLogin(target) {
262
301
  const entry = this.state.exhausted[target];
263
- if (!entry || entry.kind !== 'login')
302
+ if (!entry)
264
303
  return;
265
304
  const result = await this.deps.probe(target).catch(() => 'unknown');
266
305
  entry.lastProbeAt = new Date(this.now()).toISOString();
267
306
  if (result === 'available') {
307
+ this.logger.info('Signed in again and the probe answers — clearing the out-of-usage mark', { runtime: target, kind: entry.kind ?? 'usage_limit' });
268
308
  await this.recover(target);
269
309
  return;
270
310
  }
271
- if (result === 'limited') {
311
+ if (result === 'limited' && entry.kind === 'login') {
272
312
  // Signed in again, but that account is out of usage too.
273
313
  entry.kind = 'usage_limit';
274
314
  entry.ruleId = 'probe_limited';
275
315
  }
276
316
  this.save();
277
317
  }
318
+ /**
319
+ * A session's model just answered with a tool call (Claude Code
320
+ * PreToolUse hook). A model cannot do that while its account is out of
321
+ * usage, so a mark on the target the session runs on is stale: it is
322
+ * cleared (agents moved off it come back at their idle boundary). Marks
323
+ * newer than WORKING_EVIDENCE_GRACE_MS are kept (a turn already streaming
324
+ * when the limit hit proves nothing). Looked at most once a minute per
325
+ * session, and only while a Claude Code target is marked.
326
+ *
327
+ * @param sessionName - Session the hook came from
328
+ */
329
+ reportWorking(sessionName) {
330
+ if (!this.state.settings.enabled || this.isExempt(sessionName))
331
+ return;
332
+ if (!Object.keys(this.state.exhausted).some((r) => baseRuntimeOf(r) === RUNTIME_TYPES.CLAUDE_CODE))
333
+ return;
334
+ if (this.switching.has(sessionName))
335
+ return;
336
+ const now = this.now();
337
+ if (now - (this.workingSeen.get(sessionName) ?? Number.NEGATIVE_INFINITY) < C.WORKING_EVIDENCE_THROTTLE_MS)
338
+ return;
339
+ this.workingSeen.set(sessionName, now);
340
+ void this.onWorking(sessionName).catch((err) => this.logger.warn('Runtime fallback could not use a working signal', { sessionName, error: err instanceof Error ? err.message : String(err) }));
341
+ }
342
+ /**
343
+ * Clear the mark on the target a working session runs on.
344
+ *
345
+ * @param sessionName - Session
346
+ */
347
+ async onWorking(sessionName) {
348
+ const target = this.state.overrides[sessionName]?.runtime ?? (await this.deps.getAgent(sessionName).catch(() => null))?.primary;
349
+ if (!target || baseRuntimeOf(target) !== RUNTIME_TYPES.CLAUDE_CODE)
350
+ return;
351
+ const entry = this.state.exhausted[target];
352
+ if (!entry)
353
+ return;
354
+ if (this.now() - Date.parse(entry.since) < C.WORKING_EVIDENCE_GRACE_MS)
355
+ return;
356
+ this.logger.info('A session is working on a runtime marked out of usage — clearing the mark', { runtime: target, sessionName, since: entry.since });
357
+ await this.recover(target);
358
+ }
278
359
  /**
279
360
  * Take the note for a session's next kickoff.
280
361
  *
@@ -356,10 +437,23 @@ export class RuntimeFallbackService {
356
437
  }
357
438
  else if (existing.revertPending && !this.state.exhausted[existing.primary]) {
358
439
  // A stopped agent being started after its runtime came back.
359
- this.finishRevertOffline(input.sessionName, existing);
440
+ await this.finishRevertOffline(input.sessionName, existing);
360
441
  return configured;
361
442
  }
443
+ else if (!this.state.exhausted[existing.primary]) {
444
+ // Its runtime is back but not yet marked for revert: the next tick reverts it.
445
+ return this.decision(existing.runtime);
446
+ }
362
447
  else {
448
+ // Starting anyway: on the best target of its chain, not on one that ran
449
+ // out meanwhile or below one that came back.
450
+ const agent = await this.launchAgent(input);
451
+ const better = await this.betterTarget(agent, existing.runtime, true);
452
+ if (better) {
453
+ await this.recordSwitch(agent, existing.runtime, better, null, this.state.exhausted[existing.runtime] ? 'switch' : 'upgrade');
454
+ this.logger.info('Starting an agent on a better fallback runtime', { sessionName: input.sessionName, from: existing.runtime, runtime: better });
455
+ return this.decision(better);
456
+ }
363
457
  return this.decision(existing.runtime);
364
458
  }
365
459
  }
@@ -373,14 +467,7 @@ export class RuntimeFallbackService {
373
467
  }
374
468
  if (input.isOrchestrator && !this.state.settings.orcFollows)
375
469
  return configured;
376
- const agent = (await this.deps.getAgent(input.sessionName).catch(() => null)) ?? {
377
- sessionName: input.sessionName,
378
- name: input.sessionName,
379
- primary: input.configured,
380
- memberId: input.memberId,
381
- teamId: input.teamId,
382
- isOrchestrator: input.isOrchestrator,
383
- };
470
+ const agent = await this.launchAgent(input);
384
471
  const target = await this.pickFallback(agent, input.configured);
385
472
  if (!target) {
386
473
  this.markNoFallback(input.configured);
@@ -394,6 +481,22 @@ export class RuntimeFallbackService {
394
481
  });
395
482
  return this.decision(target);
396
483
  }
484
+ /**
485
+ * The agent behind a launch (from the launch input when it is not known).
486
+ *
487
+ * @param input - Launch input
488
+ * @returns Agent
489
+ */
490
+ async launchAgent(input) {
491
+ return ((await this.deps.getAgent(input.sessionName).catch(() => null)) ?? {
492
+ sessionName: input.sessionName,
493
+ name: input.sessionName,
494
+ primary: input.configured,
495
+ memberId: input.memberId,
496
+ teamId: input.teamId,
497
+ isOrchestrator: input.isOrchestrator,
498
+ });
499
+ }
397
500
  /**
398
501
  * The configured runtime of a launching agent is not installed / not signed
399
502
  * in on this machine: record it like a signed-out account so the agent starts
@@ -510,8 +613,11 @@ export class RuntimeFallbackService {
510
613
  }
511
614
  else {
512
615
  const confirmed = await this.confirm(runtime);
513
- if (!confirmed)
616
+ if (!confirmed) {
617
+ // The probe answered normally: the session is not out of usage either.
618
+ clearUsageLimit(sessionName);
514
619
  return;
620
+ }
515
621
  if (!this.state.exhausted[runtime]) {
516
622
  // The limit came straight back after a switch-back: back off the
517
623
  // next probe, and do not tell the owner a second time.
@@ -590,6 +696,10 @@ export class RuntimeFallbackService {
590
696
  }
591
697
  finally {
592
698
  this.switching.delete(sessionName);
699
+ // On another runtime now (or back on one that has usage again): the
700
+ // session's own usage-limit state no longer holds.
701
+ if (outcome === 'switched' || outcome === 'reverted')
702
+ clearUsageLimit(sessionName);
593
703
  await this.afterSwitch(sessionName, outcome, opts.flushAfter);
594
704
  }
595
705
  }
@@ -653,18 +763,26 @@ export class RuntimeFallbackService {
653
763
  * @param from - Runtime it leaves (out of usage)
654
764
  * @param target - Runtime it goes to
655
765
  * @param handover - Handover file, when written
766
+ * @param direction - `switch` (`from` ran out) or `upgrade` (`target` ranks higher in the chain)
656
767
  */
657
- async recordSwitch(agent, from, target, handover = null) {
768
+ async recordSwitch(agent, from, target, handover = null, direction = 'switch') {
658
769
  const sessionName = agent.sessionName;
659
770
  const existing = this.state.overrides[sessionName];
660
771
  const exhausted = this.state.exhausted[from];
661
- // The primary's conversation is kept for the switch back; the fallback
662
- // runtime starts fresh.
663
- const primarySessionId = existing?.primarySessionId ?? (from === agent.primary ? this.deps.conversation.get(sessionName) : undefined);
772
+ const currentId = this.deps.conversation.get(sessionName);
773
+ // The primary's conversation is kept for the switch back. Between two
774
+ // Claude Code targets (the default login and another account) the
775
+ // conversation itself travels: its transcript is copied into the target
776
+ // account's config dir and resumed there (crewly#1344). Any other hop
777
+ // starts fresh with the handover.
778
+ const primarySessionId = existing?.primarySessionId ?? (from === agent.primary ? currentId : undefined);
779
+ const carried = currentId ? await this.carryConversation(sessionName, from, target, currentId) : false;
664
780
  this.deps.conversation.clear(sessionName);
781
+ if (carried)
782
+ this.deps.conversation.set(sessionName, currentId);
665
783
  if (target === agent.primary) {
666
784
  delete this.state.overrides[sessionName];
667
- if (primarySessionId)
785
+ if (!carried && primarySessionId)
668
786
  this.deps.conversation.set(sessionName, primarySessionId);
669
787
  }
670
788
  else {
@@ -685,9 +803,37 @@ export class RuntimeFallbackService {
685
803
  }
686
804
  this.save();
687
805
  const workItem = await this.deps.getActiveWorkItem(sessionName).catch(() => null);
688
- this.kickoffNotes.set(sessionName, this.switchNote(from, target, exhausted?.until, handover, workItem));
806
+ this.kickoffNotes.set(sessionName, direction === 'upgrade'
807
+ ? this.upgradeNote(agent.primary, from, target, handover, workItem, carried)
808
+ : this.switchNote(from, target, exhausted?.until, handover, workItem, carried));
809
+ if (carried)
810
+ this.logger.info('Conversation carried to the target Claude Code account', { sessionName, from, to: target, conversationId: currentId });
689
811
  this.scheduleNotice(from);
690
812
  }
813
+ /**
814
+ * Whether the conversation can continue on the target: both targets run
815
+ * Claude Code (different accounts or the default login) and the wiring
816
+ * copied its transcript there. Never throws.
817
+ *
818
+ * @param sessionName - Session
819
+ * @param from - Target it leaves
820
+ * @param to - Target it goes to
821
+ * @param conversationId - Its conversation on `from`
822
+ * @returns True when `--resume <conversationId>` works on `to`
823
+ */
824
+ async carryConversation(sessionName, from, to, conversationId) {
825
+ if (!this.deps.carryConversation)
826
+ return false;
827
+ if (baseRuntimeOf(from) !== RUNTIME_TYPES.CLAUDE_CODE || baseRuntimeOf(to) !== RUNTIME_TYPES.CLAUDE_CODE)
828
+ return false;
829
+ try {
830
+ return await this.deps.carryConversation({ sessionName, from, to, conversationId });
831
+ }
832
+ catch (err) {
833
+ this.logger.warn('Could not carry the conversation to the target account; it starts fresh with the handover', { sessionName, from, to, error: err instanceof Error ? err.message : String(err) });
834
+ return false;
835
+ }
836
+ }
691
837
  /**
692
838
  * Wait until the agent is not mid-turn (bounded: a usage limit ends the turn anyway).
693
839
  *
@@ -731,6 +877,33 @@ export class RuntimeFallbackService {
731
877
  const own = agent.memberId ? this.state.settings.memberChains[agent.memberId] : undefined;
732
878
  return own && own.length > 0 ? own : this.state.settings.chain;
733
879
  }
880
+ /**
881
+ * Where an agent whose configured runtime is out should be instead of
882
+ * `current`: the earliest available entry of its chain (never its
883
+ * configured runtime, never one marked out of usage), when that ranks
884
+ * before `current` — or, with `orAnyWhenCurrentOut`, any available entry
885
+ * when `current` itself is marked out.
886
+ *
887
+ * @param agent - Agent (its configured runtime is out)
888
+ * @param current - Runtime target it is on
889
+ * @param orAnyWhenCurrentOut - Also move off a `current` that ran out to a lower-ranked entry
890
+ * @returns Better target, or null to stay
891
+ */
892
+ async betterTarget(agent, current, orAnyWhenCurrentOut) {
893
+ const best = await this.pickFallback(agent, agent.primary);
894
+ if (!best || best === current)
895
+ return null;
896
+ const chain = this.chainFor(agent);
897
+ const rank = (r) => {
898
+ const i = chain.indexOf(r);
899
+ return i < 0 ? Number.POSITIVE_INFINITY : i;
900
+ };
901
+ if (rank(best) < rank(current))
902
+ return best;
903
+ if (orAnyWhenCurrentOut && this.state.exhausted[current])
904
+ return best;
905
+ return null;
906
+ }
734
907
  /**
735
908
  * Whether some runtime could take over (synchronous; uses the cached
736
909
  * availability, optimistic when nothing is cached yet).
@@ -894,11 +1067,17 @@ export class RuntimeFallbackService {
894
1067
  }
895
1068
  await this.revertIdle();
896
1069
  }
897
- /** Revert every pending override whose agent is idle (or not running). */
1070
+ /**
1071
+ * Revert every pending override whose agent is idle (or not running), and
1072
+ * move an idle agent whose configured runtime is still out to a better
1073
+ * entry of its chain ({@link betterTarget}).
1074
+ */
898
1075
  async revertIdle() {
899
1076
  for (const [sessionName, override] of Object.entries(this.state.overrides)) {
900
- if (this.state.exhausted[override.primary])
1077
+ if (this.state.exhausted[override.primary]) {
1078
+ await this.upgradeIfBetter(sessionName, override);
901
1079
  continue;
1080
+ }
902
1081
  if (!override.revertPending) {
903
1082
  // State from before a restart whose primary is no longer marked out of usage.
904
1083
  override.revertPending = true;
@@ -907,7 +1086,7 @@ export class RuntimeFallbackService {
907
1086
  if (this.switching.has(sessionName))
908
1087
  continue;
909
1088
  if (!this.deps.isLive(sessionName)) {
910
- this.finishRevertOffline(sessionName, override);
1089
+ await this.finishRevertOffline(sessionName, override);
911
1090
  continue;
912
1091
  }
913
1092
  if (await this.deps.isBusy(sessionName).catch(() => true))
@@ -915,20 +1094,100 @@ export class RuntimeFallbackService {
915
1094
  await this.revertSession(sessionName);
916
1095
  }
917
1096
  }
1097
+ /**
1098
+ * Move an idle, running agent to a better entry of its chain. A stopped
1099
+ * agent is left alone: its next start picks the best target.
1100
+ *
1101
+ * @param sessionName - Session
1102
+ * @param override - Its override (the configured runtime is out)
1103
+ */
1104
+ async upgradeIfBetter(sessionName, override) {
1105
+ if (this.switching.has(sessionName) || this.isExempt(sessionName) || !this.deps.isLive(sessionName))
1106
+ return;
1107
+ // Cheap filter before reading the agent: some other chain entry must be open.
1108
+ const { chain, memberChains } = this.state.settings;
1109
+ const open = [...chain, ...Object.values(memberChains).flat()].some((r) => r !== override.runtime && r !== override.primary && !this.state.exhausted[r]);
1110
+ if (!open)
1111
+ return;
1112
+ const agent = await this.deps.getAgent(sessionName).catch(() => null);
1113
+ if (!agent || agent.primary !== override.primary)
1114
+ return;
1115
+ if (agent.isOrchestrator && !this.state.settings.orcFollows)
1116
+ return;
1117
+ const better = await this.betterTarget(agent, override.runtime, false);
1118
+ if (!better)
1119
+ return;
1120
+ if (await this.deps.isBusy(sessionName).catch(() => true))
1121
+ return;
1122
+ if (this.switching.has(sessionName))
1123
+ return;
1124
+ this.switching.add(sessionName);
1125
+ let outcome = 'skipped';
1126
+ try {
1127
+ outcome = await this.doUpgrade(agent, override.runtime, better);
1128
+ }
1129
+ catch (err) {
1130
+ this.logger.warn('Moving an agent to a better fallback runtime failed', { sessionName, error: err instanceof Error ? err.message : String(err) });
1131
+ outcome = 'failed';
1132
+ }
1133
+ finally {
1134
+ this.switching.delete(sessionName);
1135
+ await this.afterSwitch(sessionName, outcome, false);
1136
+ }
1137
+ }
1138
+ /**
1139
+ * Hand over and relaunch an idle agent on a better target.
1140
+ *
1141
+ * @param agent - Agent
1142
+ * @param from - Target it is on
1143
+ * @param target - Better target
1144
+ * @returns Outcome
1145
+ */
1146
+ async doUpgrade(agent, from, target) {
1147
+ const sessionName = agent.sessionName;
1148
+ // Last look right before: anything that started since means "not now".
1149
+ if (await this.deps.isBusy(sessionName).catch(() => true))
1150
+ return 'skipped';
1151
+ const handover = await this.deps
1152
+ .writeHandover({
1153
+ sessionName,
1154
+ from,
1155
+ to: target,
1156
+ direction: 'upgrade',
1157
+ conversationId: this.deps.conversation.get(sessionName) ?? null,
1158
+ workItem: await this.deps.getActiveWorkItem(sessionName).catch(() => null),
1159
+ })
1160
+ .catch(() => null);
1161
+ await this.recordSwitch(agent, from, target, handover, 'upgrade');
1162
+ this.logger.info('Moving an idle agent to a better fallback runtime (its own runtime is still out)', { sessionName, from, to: target, primary: agent.primary });
1163
+ const ok = await this.deps.relaunch(agent).catch(() => false);
1164
+ if (!ok) {
1165
+ this.logger.warn('Relaunch on the better fallback runtime failed (the override stays; the next start uses it)', { sessionName, runtime: target });
1166
+ return 'failed';
1167
+ }
1168
+ return 'switched';
1169
+ }
918
1170
  /**
919
1171
  * Clear the override of an agent that is not running.
920
1172
  *
921
1173
  * @param sessionName - Session
922
1174
  * @param override - Its override
923
1175
  */
924
- finishRevertOffline(sessionName, override) {
1176
+ async finishRevertOffline(sessionName, override) {
925
1177
  delete this.state.overrides[sessionName];
926
- if (override.primarySessionId)
1178
+ const currentId = this.deps.conversation.get(sessionName);
1179
+ // The conversation that went on on the fallback account comes back with
1180
+ // the agent when both sides are Claude Code (crewly#1344); otherwise the
1181
+ // primary's own conversation from before the switch is resumed.
1182
+ const carried = currentId ? await this.carryConversation(sessionName, override.runtime, override.primary, currentId) : false;
1183
+ if (carried)
1184
+ this.deps.conversation.set(sessionName, currentId);
1185
+ else if (override.primarySessionId)
927
1186
  this.deps.conversation.set(sessionName, override.primarySessionId);
928
1187
  else
929
1188
  this.deps.conversation.clear(sessionName);
930
1189
  this.save();
931
- this.logger.info('Fallback ended for a stopped agent (its next start uses its own runtime)', { sessionName, runtime: override.primary });
1190
+ this.logger.info('Fallback ended for a stopped agent (its next start uses its own runtime)', { sessionName, runtime: override.primary, carried });
932
1191
  }
933
1192
  /**
934
1193
  * Move an idle agent back to its configured runtime.
@@ -973,12 +1232,18 @@ export class RuntimeFallbackService {
973
1232
  })
974
1233
  .catch(() => null);
975
1234
  delete this.state.overrides[sessionName];
976
- if (override.primarySessionId)
1235
+ const currentId = this.deps.conversation.get(sessionName);
1236
+ // Both sides Claude Code: the conversation that went on while on the
1237
+ // fallback account comes back with the agent (crewly#1344).
1238
+ const carried = currentId ? await this.carryConversation(sessionName, override.runtime, override.primary, currentId) : false;
1239
+ if (carried)
1240
+ this.deps.conversation.set(sessionName, currentId);
1241
+ else if (override.primarySessionId)
977
1242
  this.deps.conversation.set(sessionName, override.primarySessionId);
978
1243
  else
979
1244
  this.deps.conversation.clear(sessionName);
980
1245
  this.save();
981
- this.kickoffNotes.set(sessionName, this.revertNote(override, handover, workItem));
1246
+ this.kickoffNotes.set(sessionName, this.revertNote(override, handover, workItem, carried));
982
1247
  this.logger.info('Switching agent back to its own runtime at an idle boundary', { sessionName, from: override.runtime, to: override.primary });
983
1248
  const ok = await this.deps.relaunch(agent).catch(() => false);
984
1249
  if (!ok) {
@@ -1137,7 +1402,15 @@ export class RuntimeFallbackService {
1137
1402
  ...(tz ? { timeZone: tz } : {}),
1138
1403
  }).format(new Date(epochMs));
1139
1404
  }
1140
- switchNote(from, to, until, handover, workItem) {
1405
+ /** The second sentence of a kickoff note: whether the conversation came along. */
1406
+ continuity(handover, carried) {
1407
+ if (carried)
1408
+ return 'Your conversation came with you — carry on where you were; nothing was lost.';
1409
+ return handover
1410
+ ? `This is a fresh conversation: after registering, read ${handover} once — it holds the end of your previous conversation.`
1411
+ : 'This is a fresh conversation: your tasks, teams and wiki are all still in Crewly.';
1412
+ }
1413
+ switchNote(from, to, until, handover, workItem, carried = false) {
1141
1414
  const reset = until ? ` (it resets ~${this.formatTime(Date.parse(until))})` : '';
1142
1415
  const kind = this.state.exhausted[from]?.kind;
1143
1416
  const parts = [
@@ -1148,20 +1421,29 @@ export class RuntimeFallbackService {
1148
1421
  : kind === 'login'
1149
1422
  ? `Crewly moved you from ${this.label(from)} to ${this.label(to)} because the ${this.label(from)} login expired.`
1150
1423
  : `Crewly moved you from ${this.label(from)} to ${this.label(to)} because ${this.label(from)} hit its usage limit${reset}; you will be moved back when it resets.`,
1151
- handover
1152
- ? `This is a fresh conversation: after registering, read ${handover} once — it holds the end of your previous conversation.`
1153
- : 'This is a fresh conversation: your tasks, teams and wiki are all still in Crewly.',
1424
+ this.continuity(handover, carried),
1425
+ ];
1426
+ if (workItem)
1427
+ parts.push(`Then continue WorkItem ${workItem.id} ("${workItem.title}") where you left off.`);
1428
+ return parts.join(' ');
1429
+ }
1430
+ upgradeNote(primary, from, to, handover, workItem, carried = false) {
1431
+ const parts = [
1432
+ `${this.label(to)} has usage again, so Crewly moved you there from ${this.label(from)}; ${this.label(primary)} is still unavailable and you will be moved back to it once it is.`,
1433
+ this.continuity(handover, carried),
1154
1434
  ];
1155
1435
  if (workItem)
1156
1436
  parts.push(`Then continue WorkItem ${workItem.id} ("${workItem.title}") where you left off.`);
1157
1437
  return parts.join(' ');
1158
1438
  }
1159
- revertNote(override, handover, workItem) {
1439
+ revertNote(override, handover, workItem, carried = false) {
1160
1440
  const parts = [
1161
1441
  `${this.label(override.primary)} is available again, so Crewly moved you back from ${this.label(override.runtime)}.`,
1162
- handover
1163
- ? `Work went on while you were away: read ${handover} once for what happened since.`
1164
- : 'Work went on while you were away: check your WorkItems and wiki for what happened since.',
1442
+ carried
1443
+ ? 'Your conversation came back with you — carry on where you were.'
1444
+ : handover
1445
+ ? `Work went on while you were away: read ${handover} once for what happened since.`
1446
+ : 'Work went on while you were away: check your WorkItems and wiki for what happened since.',
1165
1447
  ];
1166
1448
  if (workItem)
1167
1449
  parts.push(`Then continue WorkItem ${workItem.id} ("${workItem.title}").`);