crewly 1.20.195 → 1.20.197

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 (595) hide show
  1. package/config/constants.ts +68 -0
  2. package/config/hooks/agent-status/report.sh +31 -12
  3. package/config/hooks/subagent-guard/subagent.sh +25 -1
  4. package/config/roles/orchestrator/fragments/lifecycle.md +1 -1
  5. package/config/roles/orchestrator/prompt.md +3 -3
  6. package/config/skills/_common/lib.sh +28 -5
  7. package/config/skills/_common/lib.test.sh +32 -1
  8. package/config/skills/agent/core/create-intent-tasks/execute.sh +2 -0
  9. package/config/skills/agent/core/decompose-intent/execute.sh +2 -0
  10. package/config/skills/agent/core/experiment-card/SKILL.md +29 -1
  11. package/config/skills/agent/core/experiment-card/execute.sh +35 -1
  12. package/config/skills/agent/core/experiment-card/execute.test.sh +11 -0
  13. package/config/skills/agent/core/project-tickets/SKILL.md +35 -2
  14. package/config/skills/agent/core/project-tickets/execute.sh +59 -6
  15. package/config/skills/agent/core/project-tickets/execute.test.sh +24 -0
  16. package/config/skills/agent/core/send-message/execute.sh +16 -0
  17. package/config/skills/agent/core/send-message/execute.test.sh +10 -0
  18. package/config/skills/agent/core/trace-read/SKILL.md +117 -0
  19. package/config/skills/agent/core/trace-read/execute.sh +116 -0
  20. package/config/skills/agent/core/update-intent-task/execute.sh +2 -0
  21. package/config/skills/agent/marketing/submit-for-approval/execute.sh +3 -2
  22. package/config/skills/orchestrator/decompose-mission/execute.sh +2 -0
  23. package/config/skills/orchestrator/decompose-okr/execute.sh +1 -0
  24. package/config/skills/orchestrator/design-team/execute.sh +2 -0
  25. package/config/skills/orchestrator/measure-kr/execute.sh +2 -0
  26. package/config/skills/orchestrator/review-mission/execute.sh +2 -0
  27. package/config/skills/orchestrator/send-message/execute.sh +10 -2
  28. package/config/skills/orchestrator/send-message/execute.test.sh +9 -0
  29. package/config/skills/team-leader/design-checklist/execute.sh +2 -0
  30. package/dist/backend/backend/src/constants.d.ts +223 -5
  31. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  32. package/dist/backend/backend/src/constants.js +206 -6
  33. package/dist/backend/backend/src/constants.js.map +1 -1
  34. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.d.ts +9 -3
  35. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.d.ts.map +1 -1
  36. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js +38 -5
  37. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js.map +1 -1
  38. package/dist/backend/backend/src/controllers/approvals/approvals.controller.d.ts +4 -9
  39. package/dist/backend/backend/src/controllers/approvals/approvals.controller.d.ts.map +1 -1
  40. package/dist/backend/backend/src/controllers/approvals/approvals.controller.js +6 -14
  41. package/dist/backend/backend/src/controllers/approvals/approvals.controller.js.map +1 -1
  42. package/dist/backend/backend/src/controllers/auth/owner-session.controller.d.ts +64 -0
  43. package/dist/backend/backend/src/controllers/auth/owner-session.controller.d.ts.map +1 -0
  44. package/dist/backend/backend/src/controllers/auth/owner-session.controller.js +164 -0
  45. package/dist/backend/backend/src/controllers/auth/owner-session.controller.js.map +1 -0
  46. package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts.map +1 -1
  47. package/dist/backend/backend/src/controllers/browser/browser.controller.js +54 -8
  48. package/dist/backend/backend/src/controllers/browser/browser.controller.js.map +1 -1
  49. package/dist/backend/backend/src/controllers/browser/browser.routes.d.ts.map +1 -1
  50. package/dist/backend/backend/src/controllers/browser/browser.routes.js +18 -5
  51. package/dist/backend/backend/src/controllers/browser/browser.routes.js.map +1 -1
  52. package/dist/backend/backend/src/controllers/canva/canva.routes.d.ts.map +1 -1
  53. package/dist/backend/backend/src/controllers/canva/canva.routes.js +8 -1
  54. package/dist/backend/backend/src/controllers/canva/canva.routes.js.map +1 -1
  55. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  56. package/dist/backend/backend/src/controllers/chat/chat.controller.js +10 -1
  57. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  58. package/dist/backend/backend/src/controllers/cloud/cloud-device-pairing.controller.d.ts.map +1 -1
  59. package/dist/backend/backend/src/controllers/cloud/cloud-device-pairing.controller.js +3 -5
  60. package/dist/backend/backend/src/controllers/cloud/cloud-device-pairing.controller.js.map +1 -1
  61. package/dist/backend/backend/src/controllers/connector/connector.controller.d.ts +4 -2
  62. package/dist/backend/backend/src/controllers/connector/connector.controller.d.ts.map +1 -1
  63. package/dist/backend/backend/src/controllers/connector/connector.controller.js +17 -2
  64. package/dist/backend/backend/src/controllers/connector/connector.controller.js.map +1 -1
  65. package/dist/backend/backend/src/controllers/connector/grant-sharing.handler.d.ts.map +1 -1
  66. package/dist/backend/backend/src/controllers/connector/grant-sharing.handler.js +2 -3
  67. package/dist/backend/backend/src/controllers/connector/grant-sharing.handler.js.map +1 -1
  68. package/dist/backend/backend/src/controllers/decisions/decisions.controller.d.ts +4 -2
  69. package/dist/backend/backend/src/controllers/decisions/decisions.controller.d.ts.map +1 -1
  70. package/dist/backend/backend/src/controllers/decisions/decisions.controller.js +31 -20
  71. package/dist/backend/backend/src/controllers/decisions/decisions.controller.js.map +1 -1
  72. package/dist/backend/backend/src/controllers/desktop/desktop.controller.d.ts.map +1 -1
  73. package/dist/backend/backend/src/controllers/desktop/desktop.controller.js +16 -0
  74. package/dist/backend/backend/src/controllers/desktop/desktop.controller.js.map +1 -1
  75. package/dist/backend/backend/src/controllers/google/google.controller.d.ts.map +1 -1
  76. package/dist/backend/backend/src/controllers/google/google.controller.js +9 -5
  77. package/dist/backend/backend/src/controllers/google/google.controller.js.map +1 -1
  78. package/dist/backend/backend/src/controllers/google/google.routes.d.ts.map +1 -1
  79. package/dist/backend/backend/src/controllers/google/google.routes.js +16 -3
  80. package/dist/backend/backend/src/controllers/google/google.routes.js.map +1 -1
  81. package/dist/backend/backend/src/controllers/harness/harness.controller.d.ts.map +1 -1
  82. package/dist/backend/backend/src/controllers/harness/harness.controller.js +3 -5
  83. package/dist/backend/backend/src/controllers/harness/harness.controller.js.map +1 -1
  84. package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.routes.d.ts.map +1 -1
  85. package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.routes.js +8 -1
  86. package/dist/backend/backend/src/controllers/microsoft/microsoft-todo.routes.js.map +1 -1
  87. package/dist/backend/backend/src/controllers/mission/mission-policy.routes.js +1 -1
  88. package/dist/backend/backend/src/controllers/mission/mission-policy.routes.js.map +1 -1
  89. package/dist/backend/backend/src/controllers/owner-receipt/owner-receipt.controller.d.ts.map +1 -1
  90. package/dist/backend/backend/src/controllers/owner-receipt/owner-receipt.controller.js +3 -5
  91. package/dist/backend/backend/src/controllers/owner-receipt/owner-receipt.controller.js.map +1 -1
  92. package/dist/backend/backend/src/controllers/people/people.routes.d.ts.map +1 -1
  93. package/dist/backend/backend/src/controllers/people/people.routes.js +3 -5
  94. package/dist/backend/backend/src/controllers/people/people.routes.js.map +1 -1
  95. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts +35 -2
  96. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts.map +1 -1
  97. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js +138 -4
  98. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js.map +1 -1
  99. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.d.ts +2 -0
  100. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.d.ts.map +1 -1
  101. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.js +7 -1
  102. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.js.map +1 -1
  103. package/dist/backend/backend/src/controllers/request/open-items.controller.d.ts.map +1 -1
  104. package/dist/backend/backend/src/controllers/request/open-items.controller.js +2 -4
  105. package/dist/backend/backend/src/controllers/request/open-items.controller.js.map +1 -1
  106. package/dist/backend/backend/src/controllers/signal-digest/signal-digest.controller.js +1 -1
  107. package/dist/backend/backend/src/controllers/signal-digest/signal-digest.controller.js.map +1 -1
  108. package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
  109. package/dist/backend/backend/src/controllers/slack/slack.controller.js +9 -0
  110. package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
  111. package/dist/backend/backend/src/controllers/system/runtime-fallback.controller.d.ts.map +1 -1
  112. package/dist/backend/backend/src/controllers/system/runtime-fallback.controller.js +11 -0
  113. package/dist/backend/backend/src/controllers/system/runtime-fallback.controller.js.map +1 -1
  114. package/dist/backend/backend/src/controllers/system/system-control.controller.d.ts +6 -4
  115. package/dist/backend/backend/src/controllers/system/system-control.controller.d.ts.map +1 -1
  116. package/dist/backend/backend/src/controllers/system/system-control.controller.js +20 -13
  117. package/dist/backend/backend/src/controllers/system/system-control.controller.js.map +1 -1
  118. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  119. package/dist/backend/backend/src/controllers/team/team.controller.js +14 -7
  120. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  121. package/dist/backend/backend/src/controllers/tickets/tickets.controller.d.ts.map +1 -1
  122. package/dist/backend/backend/src/controllers/tickets/tickets.controller.js +5 -7
  123. package/dist/backend/backend/src/controllers/tickets/tickets.controller.js.map +1 -1
  124. package/dist/backend/backend/src/controllers/trace/trace.controller.d.ts +30 -4
  125. package/dist/backend/backend/src/controllers/trace/trace.controller.d.ts.map +1 -1
  126. package/dist/backend/backend/src/controllers/trace/trace.controller.js +278 -10
  127. package/dist/backend/backend/src/controllers/trace/trace.controller.js.map +1 -1
  128. package/dist/backend/backend/src/controllers/whatsapp/whatsapp-inbox.controller.d.ts +3 -3
  129. package/dist/backend/backend/src/controllers/whatsapp/whatsapp-inbox.controller.d.ts.map +1 -1
  130. package/dist/backend/backend/src/controllers/whatsapp/whatsapp-inbox.controller.js +4 -2
  131. package/dist/backend/backend/src/controllers/whatsapp/whatsapp-inbox.controller.js.map +1 -1
  132. package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.d.ts.map +1 -1
  133. package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.js +10 -2
  134. package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.js.map +1 -1
  135. package/dist/backend/backend/src/index.d.ts +34 -0
  136. package/dist/backend/backend/src/index.d.ts.map +1 -1
  137. package/dist/backend/backend/src/index.js +313 -42
  138. package/dist/backend/backend/src/index.js.map +1 -1
  139. package/dist/backend/backend/src/middleware/agent-origin-correction.d.ts +31 -0
  140. package/dist/backend/backend/src/middleware/agent-origin-correction.d.ts.map +1 -0
  141. package/dist/backend/backend/src/middleware/agent-origin-correction.js +31 -0
  142. package/dist/backend/backend/src/middleware/agent-origin-correction.js.map +1 -0
  143. package/dist/backend/backend/src/middleware/agent-origin.middleware.d.ts +6 -0
  144. package/dist/backend/backend/src/middleware/agent-origin.middleware.d.ts.map +1 -1
  145. package/dist/backend/backend/src/middleware/agent-origin.middleware.js +4 -1
  146. package/dist/backend/backend/src/middleware/agent-origin.middleware.js.map +1 -1
  147. package/dist/backend/backend/src/middleware/api-token.middleware.d.ts +20 -17
  148. package/dist/backend/backend/src/middleware/api-token.middleware.d.ts.map +1 -1
  149. package/dist/backend/backend/src/middleware/api-token.middleware.js +27 -37
  150. package/dist/backend/backend/src/middleware/api-token.middleware.js.map +1 -1
  151. package/dist/backend/backend/src/middleware/caller-identity.middleware.d.ts +213 -0
  152. package/dist/backend/backend/src/middleware/caller-identity.middleware.d.ts.map +1 -0
  153. package/dist/backend/backend/src/middleware/caller-identity.middleware.js +481 -0
  154. package/dist/backend/backend/src/middleware/caller-identity.middleware.js.map +1 -0
  155. package/dist/backend/backend/src/middleware/caller-identity.testing.d.ts +67 -0
  156. package/dist/backend/backend/src/middleware/caller-identity.testing.d.ts.map +1 -0
  157. package/dist/backend/backend/src/middleware/caller-identity.testing.js +108 -0
  158. package/dist/backend/backend/src/middleware/caller-identity.testing.js.map +1 -0
  159. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  160. package/dist/backend/backend/src/services/agent/agent-registration.service.js +12 -2
  161. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  162. package/dist/backend/backend/src/services/agent/control-plane-guard.service.d.ts +7 -5
  163. package/dist/backend/backend/src/services/agent/control-plane-guard.service.d.ts.map +1 -1
  164. package/dist/backend/backend/src/services/agent/control-plane-guard.service.js +19 -10
  165. package/dist/backend/backend/src/services/agent/control-plane-guard.service.js.map +1 -1
  166. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -1
  167. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +10 -1
  168. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -1
  169. package/dist/backend/backend/src/services/agent/restore-filter.d.ts +5 -2
  170. package/dist/backend/backend/src/services/agent/restore-filter.d.ts.map +1 -1
  171. package/dist/backend/backend/src/services/agent/restore-filter.js +5 -2
  172. package/dist/backend/backend/src/services/agent/restore-filter.js.map +1 -1
  173. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -1
  174. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js +4 -0
  175. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
  176. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts +29 -0
  177. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
  178. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js +77 -1
  179. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
  180. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
  181. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +1 -0
  182. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
  183. package/dist/backend/backend/src/services/browser/browser-session.service.d.ts +34 -1
  184. package/dist/backend/backend/src/services/browser/browser-session.service.d.ts.map +1 -1
  185. package/dist/backend/backend/src/services/browser/browser-session.service.js +38 -1
  186. package/dist/backend/backend/src/services/browser/browser-session.service.js.map +1 -1
  187. package/dist/backend/backend/src/services/browser/owner-browser-input.d.ts +98 -10
  188. package/dist/backend/backend/src/services/browser/owner-browser-input.d.ts.map +1 -1
  189. package/dist/backend/backend/src/services/browser/owner-browser-input.js +126 -11
  190. package/dist/backend/backend/src/services/browser/owner-browser-input.js.map +1 -1
  191. package/dist/backend/backend/src/services/chat/chat.service.d.ts +99 -2
  192. package/dist/backend/backend/src/services/chat/chat.service.d.ts.map +1 -1
  193. package/dist/backend/backend/src/services/chat/chat.service.js +265 -40
  194. package/dist/backend/backend/src/services/chat/chat.service.js.map +1 -1
  195. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +30 -5
  196. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  197. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +34 -4
  198. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  199. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.d.ts +18 -11
  200. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.d.ts.map +1 -1
  201. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.js +19 -25
  202. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.js.map +1 -1
  203. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts +7 -4
  204. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -1
  205. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js +8 -4
  206. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -1
  207. package/dist/backend/backend/src/services/chat-v2/types.d.ts +0 -1
  208. package/dist/backend/backend/src/services/chat-v2/types.d.ts.map +1 -1
  209. package/dist/backend/backend/src/services/chat-v2/types.js +0 -1
  210. package/dist/backend/backend/src/services/chat-v2/types.js.map +1 -1
  211. package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.d.ts.map +1 -1
  212. package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js +5 -0
  213. package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js.map +1 -1
  214. package/dist/backend/backend/src/services/core/api-token.service.d.ts +28 -0
  215. package/dist/backend/backend/src/services/core/api-token.service.d.ts.map +1 -1
  216. package/dist/backend/backend/src/services/core/api-token.service.js +46 -0
  217. package/dist/backend/backend/src/services/core/api-token.service.js.map +1 -1
  218. package/dist/backend/backend/src/services/core/dashboard-build.d.ts +49 -0
  219. package/dist/backend/backend/src/services/core/dashboard-build.d.ts.map +1 -0
  220. package/dist/backend/backend/src/services/core/dashboard-build.js +68 -0
  221. package/dist/backend/backend/src/services/core/dashboard-build.js.map +1 -0
  222. package/dist/backend/backend/src/services/core/owner-auth.service.d.ts +127 -0
  223. package/dist/backend/backend/src/services/core/owner-auth.service.d.ts.map +1 -0
  224. package/dist/backend/backend/src/services/core/owner-auth.service.js +205 -0
  225. package/dist/backend/backend/src/services/core/owner-auth.service.js.map +1 -0
  226. package/dist/backend/backend/src/services/core/peer-process.service.d.ts +168 -0
  227. package/dist/backend/backend/src/services/core/peer-process.service.d.ts.map +1 -0
  228. package/dist/backend/backend/src/services/core/peer-process.service.js +352 -0
  229. package/dist/backend/backend/src/services/core/peer-process.service.js.map +1 -0
  230. package/dist/backend/backend/src/services/experiments/experiment.service.d.ts +97 -1
  231. package/dist/backend/backend/src/services/experiments/experiment.service.d.ts.map +1 -1
  232. package/dist/backend/backend/src/services/experiments/experiment.service.js +372 -1
  233. package/dist/backend/backend/src/services/experiments/experiment.service.js.map +1 -1
  234. package/dist/backend/backend/src/services/experiments/experiment.wiring.d.ts.map +1 -1
  235. package/dist/backend/backend/src/services/experiments/experiment.wiring.js +19 -2
  236. package/dist/backend/backend/src/services/experiments/experiment.wiring.js.map +1 -1
  237. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.d.ts.map +1 -1
  238. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js +2 -1
  239. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js.map +1 -1
  240. package/dist/backend/backend/src/services/messaging/thread-status-queue.service.d.ts +0 -8
  241. package/dist/backend/backend/src/services/messaging/thread-status-queue.service.d.ts.map +1 -1
  242. package/dist/backend/backend/src/services/messaging/thread-status-queue.service.js +0 -18
  243. package/dist/backend/backend/src/services/messaging/thread-status-queue.service.js.map +1 -1
  244. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.d.ts +19 -0
  245. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.d.ts.map +1 -1
  246. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js +41 -5
  247. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
  248. package/dist/backend/backend/src/services/monitoring/agent-turn-state.d.ts +184 -0
  249. package/dist/backend/backend/src/services/monitoring/agent-turn-state.d.ts.map +1 -0
  250. package/dist/backend/backend/src/services/monitoring/agent-turn-state.js +391 -0
  251. package/dist/backend/backend/src/services/monitoring/agent-turn-state.js.map +1 -0
  252. package/dist/backend/backend/src/services/monitoring/claude-transcript-sync.service.d.ts +35 -1
  253. package/dist/backend/backend/src/services/monitoring/claude-transcript-sync.service.d.ts.map +1 -1
  254. package/dist/backend/backend/src/services/monitoring/claude-transcript-sync.service.js +138 -2
  255. package/dist/backend/backend/src/services/monitoring/claude-transcript-sync.service.js.map +1 -1
  256. package/dist/backend/backend/src/services/monitoring/claude-transcript-turn.d.ts +73 -0
  257. package/dist/backend/backend/src/services/monitoring/claude-transcript-turn.d.ts.map +1 -0
  258. package/dist/backend/backend/src/services/monitoring/claude-transcript-turn.js +258 -0
  259. package/dist/backend/backend/src/services/monitoring/claude-transcript-turn.js.map +1 -0
  260. package/dist/backend/backend/src/services/monitoring/deferred-idle-settle.d.ts +82 -0
  261. package/dist/backend/backend/src/services/monitoring/deferred-idle-settle.d.ts.map +1 -0
  262. package/dist/backend/backend/src/services/monitoring/deferred-idle-settle.js +141 -0
  263. package/dist/backend/backend/src/services/monitoring/deferred-idle-settle.js.map +1 -0
  264. package/dist/backend/backend/src/services/monitoring/system-resource-alert.service.d.ts +51 -1
  265. package/dist/backend/backend/src/services/monitoring/system-resource-alert.service.d.ts.map +1 -1
  266. package/dist/backend/backend/src/services/monitoring/system-resource-alert.service.js +118 -2
  267. package/dist/backend/backend/src/services/monitoring/system-resource-alert.service.js.map +1 -1
  268. package/dist/backend/backend/src/services/monitoring/transcript-cost-repair.d.ts +103 -0
  269. package/dist/backend/backend/src/services/monitoring/transcript-cost-repair.d.ts.map +1 -0
  270. package/dist/backend/backend/src/services/monitoring/transcript-cost-repair.js +86 -0
  271. package/dist/backend/backend/src/services/monitoring/transcript-cost-repair.js.map +1 -0
  272. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts +57 -0
  273. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
  274. package/dist/backend/backend/src/services/open-items/open-items.service.js +100 -4
  275. package/dist/backend/backend/src/services/open-items/open-items.service.js.map +1 -1
  276. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts.map +1 -1
  277. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js +13 -0
  278. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js.map +1 -1
  279. package/dist/backend/backend/src/services/project-tickets/project-ticket.service.d.ts +36 -0
  280. package/dist/backend/backend/src/services/project-tickets/project-ticket.service.d.ts.map +1 -1
  281. package/dist/backend/backend/src/services/project-tickets/project-ticket.service.js +42 -3
  282. package/dist/backend/backend/src/services/project-tickets/project-ticket.service.js.map +1 -1
  283. package/dist/backend/backend/src/services/project-tickets/ticket-assignee-waker.d.ts.map +1 -1
  284. package/dist/backend/backend/src/services/project-tickets/ticket-assignee-waker.js +2 -1
  285. package/dist/backend/backend/src/services/project-tickets/ticket-assignee-waker.js.map +1 -1
  286. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.d.ts.map +1 -1
  287. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.js +3 -0
  288. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.js.map +1 -1
  289. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-retro.d.ts +156 -0
  290. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-retro.d.ts.map +1 -0
  291. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-retro.js +308 -0
  292. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-retro.js.map +1 -0
  293. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-stats.d.ts +212 -0
  294. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-stats.d.ts.map +1 -0
  295. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-stats.js +515 -0
  296. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-stats.js.map +1 -0
  297. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-trace.d.ts +186 -0
  298. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-trace.d.ts.map +1 -0
  299. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-trace.js +341 -0
  300. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-trace.js.map +1 -0
  301. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts +309 -0
  302. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts.map +1 -1
  303. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js +726 -1
  304. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js.map +1 -1
  305. package/dist/backend/backend/src/services/restart/in-flight-turn-tracker.service.d.ts +34 -3
  306. package/dist/backend/backend/src/services/restart/in-flight-turn-tracker.service.d.ts.map +1 -1
  307. package/dist/backend/backend/src/services/restart/in-flight-turn-tracker.service.js +57 -2
  308. package/dist/backend/backend/src/services/restart/in-flight-turn-tracker.service.js.map +1 -1
  309. package/dist/backend/backend/src/services/restart/interrupted-turns.d.ts +61 -3
  310. package/dist/backend/backend/src/services/restart/interrupted-turns.d.ts.map +1 -1
  311. package/dist/backend/backend/src/services/restart/interrupted-turns.js +106 -9
  312. package/dist/backend/backend/src/services/restart/interrupted-turns.js.map +1 -1
  313. package/dist/backend/backend/src/services/restart/restart-drain.service.d.ts +22 -0
  314. package/dist/backend/backend/src/services/restart/restart-drain.service.d.ts.map +1 -1
  315. package/dist/backend/backend/src/services/restart/restart-drain.service.js +37 -5
  316. package/dist/backend/backend/src/services/restart/restart-drain.service.js.map +1 -1
  317. package/dist/backend/backend/src/services/restart/supervisor-stop-budget.d.ts +62 -0
  318. package/dist/backend/backend/src/services/restart/supervisor-stop-budget.d.ts.map +1 -0
  319. package/dist/backend/backend/src/services/restart/supervisor-stop-budget.js +126 -0
  320. package/dist/backend/backend/src/services/restart/supervisor-stop-budget.js.map +1 -0
  321. package/dist/backend/backend/src/services/restart/turn-probe.d.ts +17 -2
  322. package/dist/backend/backend/src/services/restart/turn-probe.d.ts.map +1 -1
  323. package/dist/backend/backend/src/services/restart/turn-probe.js +29 -4
  324. package/dist/backend/backend/src/services/restart/turn-probe.js.map +1 -1
  325. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.d.ts.map +1 -1
  326. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.js +4 -0
  327. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.service.js.map +1 -1
  328. package/dist/backend/backend/src/services/slack/slack-auto-working.service.d.ts +29 -0
  329. package/dist/backend/backend/src/services/slack/slack-auto-working.service.d.ts.map +1 -1
  330. package/dist/backend/backend/src/services/slack/slack-auto-working.service.js +66 -3
  331. package/dist/backend/backend/src/services/slack/slack-auto-working.service.js.map +1 -1
  332. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +79 -15
  333. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  334. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +200 -41
  335. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  336. package/dist/backend/backend/src/services/slack/slack.service.d.ts +18 -0
  337. package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
  338. package/dist/backend/backend/src/services/slack/slack.service.js +32 -0
  339. package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
  340. package/dist/backend/backend/src/services/trace/trace-analysis.service.d.ts +99 -0
  341. package/dist/backend/backend/src/services/trace/trace-analysis.service.d.ts.map +1 -0
  342. package/dist/backend/backend/src/services/trace/trace-analysis.service.js +148 -0
  343. package/dist/backend/backend/src/services/trace/trace-analysis.service.js.map +1 -0
  344. package/dist/backend/backend/src/services/trace/trace-context.service.d.ts +17 -0
  345. package/dist/backend/backend/src/services/trace/trace-context.service.d.ts.map +1 -1
  346. package/dist/backend/backend/src/services/trace/trace-context.service.js +58 -1
  347. package/dist/backend/backend/src/services/trace/trace-context.service.js.map +1 -1
  348. package/dist/backend/backend/src/services/trace/trace-http.middleware.d.ts +4 -0
  349. package/dist/backend/backend/src/services/trace/trace-http.middleware.d.ts.map +1 -1
  350. package/dist/backend/backend/src/services/trace/trace-http.middleware.js +32 -2
  351. package/dist/backend/backend/src/services/trace/trace-http.middleware.js.map +1 -1
  352. package/dist/backend/backend/src/services/trace/trace-metrics.d.ts +262 -0
  353. package/dist/backend/backend/src/services/trace/trace-metrics.d.ts.map +1 -0
  354. package/dist/backend/backend/src/services/trace/trace-metrics.js +810 -0
  355. package/dist/backend/backend/src/services/trace/trace-metrics.js.map +1 -0
  356. package/dist/backend/backend/src/services/trace/trace-recorder.d.ts +48 -0
  357. package/dist/backend/backend/src/services/trace/trace-recorder.d.ts.map +1 -1
  358. package/dist/backend/backend/src/services/trace/trace-recorder.js +121 -1
  359. package/dist/backend/backend/src/services/trace/trace-recorder.js.map +1 -1
  360. package/dist/backend/backend/src/services/trace/trace-store.d.ts +40 -1
  361. package/dist/backend/backend/src/services/trace/trace-store.d.ts.map +1 -1
  362. package/dist/backend/backend/src/services/trace/trace-store.js +126 -14
  363. package/dist/backend/backend/src/services/trace/trace-store.js.map +1 -1
  364. package/dist/backend/backend/src/services/trace/trace-summary.d.ts +77 -0
  365. package/dist/backend/backend/src/services/trace/trace-summary.d.ts.map +1 -0
  366. package/dist/backend/backend/src/services/trace/trace-summary.js +239 -0
  367. package/dist/backend/backend/src/services/trace/trace-summary.js.map +1 -0
  368. package/dist/backend/backend/src/services/trace/trace-timeline.d.ts +74 -0
  369. package/dist/backend/backend/src/services/trace/trace-timeline.d.ts.map +1 -0
  370. package/dist/backend/backend/src/services/trace/trace-timeline.js +162 -0
  371. package/dist/backend/backend/src/services/trace/trace-timeline.js.map +1 -0
  372. package/dist/backend/backend/src/services/trace/trace.types.d.ts +22 -3
  373. package/dist/backend/backend/src/services/trace/trace.types.d.ts.map +1 -1
  374. package/dist/backend/backend/src/services/trace/trace.types.js +20 -1
  375. package/dist/backend/backend/src/services/trace/trace.types.js.map +1 -1
  376. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt-format-ask.d.ts +80 -0
  377. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt-format-ask.d.ts.map +1 -0
  378. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt-format-ask.js +184 -0
  379. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt-format-ask.js.map +1 -0
  380. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.service.d.ts +7 -0
  381. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.service.d.ts.map +1 -1
  382. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.service.js +16 -0
  383. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.service.js.map +1 -1
  384. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.types.d.ts +16 -0
  385. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.types.d.ts.map +1 -1
  386. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.types.js.map +1 -1
  387. package/dist/backend/backend/src/services/v3/tl-auto-verify.service.d.ts.map +1 -1
  388. package/dist/backend/backend/src/services/v3/tl-auto-verify.service.js +2 -1
  389. package/dist/backend/backend/src/services/v3/tl-auto-verify.service.js.map +1 -1
  390. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts +8 -0
  391. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
  392. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +24 -2
  393. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
  394. package/dist/backend/backend/src/services/whatsapp/whatsapp-draft-gate.d.ts +4 -3
  395. package/dist/backend/backend/src/services/whatsapp/whatsapp-draft-gate.d.ts.map +1 -1
  396. package/dist/backend/backend/src/services/whatsapp/whatsapp-draft-gate.js +3 -2
  397. package/dist/backend/backend/src/services/whatsapp/whatsapp-draft-gate.js.map +1 -1
  398. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts +3 -1
  399. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -1
  400. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.js.map +1 -1
  401. package/dist/backend/backend/src/services/workflow/message-scheduler.service.d.ts.map +1 -1
  402. package/dist/backend/backend/src/services/workflow/message-scheduler.service.js +3 -0
  403. package/dist/backend/backend/src/services/workflow/message-scheduler.service.js.map +1 -1
  404. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
  405. package/dist/backend/backend/src/services/workflow/scheduler.service.js +3 -0
  406. package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
  407. package/dist/backend/backend/src/services/worktree/workitem-worktree.subscriber.d.ts.map +1 -1
  408. package/dist/backend/backend/src/services/worktree/workitem-worktree.subscriber.js +2 -1
  409. package/dist/backend/backend/src/services/worktree/workitem-worktree.subscriber.js.map +1 -1
  410. package/dist/backend/backend/src/types/decision.types.d.ts +3 -1
  411. package/dist/backend/backend/src/types/decision.types.d.ts.map +1 -1
  412. package/dist/backend/backend/src/types/experiment.types.d.ts +57 -0
  413. package/dist/backend/backend/src/types/experiment.types.d.ts.map +1 -1
  414. package/dist/backend/backend/src/types/experiment.types.js.map +1 -1
  415. package/dist/backend/backend/src/types/ticket-autopilot.types.d.ts +9 -0
  416. package/dist/backend/backend/src/types/ticket-autopilot.types.d.ts.map +1 -1
  417. package/dist/backend/backend/src/types/ticket-autopilot.types.js +14 -0
  418. package/dist/backend/backend/src/types/ticket-autopilot.types.js.map +1 -1
  419. package/dist/backend/backend/src/types/v2/open-item.types.d.ts +4 -0
  420. package/dist/backend/backend/src/types/v2/open-item.types.d.ts.map +1 -1
  421. package/dist/backend/backend/src/types/v2/work-item.types.d.ts +1 -1
  422. package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  423. package/dist/backend/backend/src/types/v2/work-item.types.js +1 -0
  424. package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
  425. package/dist/backend/backend/src/utils/agent-caller.utils.d.ts +44 -37
  426. package/dist/backend/backend/src/utils/agent-caller.utils.d.ts.map +1 -1
  427. package/dist/backend/backend/src/utils/agent-caller.utils.js +48 -42
  428. package/dist/backend/backend/src/utils/agent-caller.utils.js.map +1 -1
  429. package/dist/backend/backend/src/utils/secret-env.d.ts.map +1 -1
  430. package/dist/backend/backend/src/utils/secret-env.js +8 -1
  431. package/dist/backend/backend/src/utils/secret-env.js.map +1 -1
  432. package/dist/backend/build-info.json +2 -2
  433. package/dist/backend/config/constants.d.ts +67 -0
  434. package/dist/backend/config/constants.d.ts.map +1 -1
  435. package/dist/backend/config/constants.js +67 -0
  436. package/dist/backend/config/constants.js.map +1 -1
  437. package/dist/cli/backend/src/constants.d.ts +223 -5
  438. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  439. package/dist/cli/backend/src/constants.js +206 -6
  440. package/dist/cli/backend/src/constants.js.map +1 -1
  441. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  442. package/dist/cli/backend/src/services/agent/agent-registration.service.js +12 -2
  443. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
  444. package/dist/cli/backend/src/services/agent/control-plane-guard.service.d.ts +7 -5
  445. package/dist/cli/backend/src/services/agent/control-plane-guard.service.d.ts.map +1 -1
  446. package/dist/cli/backend/src/services/agent/control-plane-guard.service.js +19 -10
  447. package/dist/cli/backend/src/services/agent/control-plane-guard.service.js.map +1 -1
  448. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -1
  449. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +10 -1
  450. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -1
  451. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -1
  452. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.js +4 -0
  453. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
  454. package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.d.ts +29 -0
  455. package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
  456. package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.js +77 -1
  457. package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
  458. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
  459. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js +1 -0
  460. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
  461. package/dist/cli/backend/src/services/chat/chat.service.d.ts +99 -2
  462. package/dist/cli/backend/src/services/chat/chat.service.d.ts.map +1 -1
  463. package/dist/cli/backend/src/services/chat/chat.service.js +265 -40
  464. package/dist/cli/backend/src/services/chat/chat.service.js.map +1 -1
  465. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +30 -5
  466. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  467. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +34 -4
  468. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  469. package/dist/cli/backend/src/services/chat-v2/sqlite/channel.store.d.ts +18 -11
  470. package/dist/cli/backend/src/services/chat-v2/sqlite/channel.store.d.ts.map +1 -1
  471. package/dist/cli/backend/src/services/chat-v2/sqlite/channel.store.js +19 -25
  472. package/dist/cli/backend/src/services/chat-v2/sqlite/channel.store.js.map +1 -1
  473. package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.d.ts +7 -4
  474. package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -1
  475. package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.js +8 -4
  476. package/dist/cli/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -1
  477. package/dist/cli/backend/src/services/chat-v2/types.d.ts +0 -1
  478. package/dist/cli/backend/src/services/chat-v2/types.d.ts.map +1 -1
  479. package/dist/cli/backend/src/services/chat-v2/types.js +0 -1
  480. package/dist/cli/backend/src/services/chat-v2/types.js.map +1 -1
  481. package/dist/cli/backend/src/services/core/api-token.service.d.ts +28 -0
  482. package/dist/cli/backend/src/services/core/api-token.service.d.ts.map +1 -1
  483. package/dist/cli/backend/src/services/core/api-token.service.js +46 -0
  484. package/dist/cli/backend/src/services/core/api-token.service.js.map +1 -1
  485. package/dist/cli/backend/src/services/core/owner-auth.service.d.ts +127 -0
  486. package/dist/cli/backend/src/services/core/owner-auth.service.d.ts.map +1 -0
  487. package/dist/cli/backend/src/services/core/owner-auth.service.js +205 -0
  488. package/dist/cli/backend/src/services/core/owner-auth.service.js.map +1 -0
  489. package/dist/cli/backend/src/services/messaging/thread-status-queue.service.d.ts +0 -8
  490. package/dist/cli/backend/src/services/messaging/thread-status-queue.service.d.ts.map +1 -1
  491. package/dist/cli/backend/src/services/messaging/thread-status-queue.service.js +0 -18
  492. package/dist/cli/backend/src/services/messaging/thread-status-queue.service.js.map +1 -1
  493. package/dist/cli/backend/src/services/monitoring/activity-monitor.service.d.ts +19 -0
  494. package/dist/cli/backend/src/services/monitoring/activity-monitor.service.d.ts.map +1 -1
  495. package/dist/cli/backend/src/services/monitoring/activity-monitor.service.js +41 -5
  496. package/dist/cli/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
  497. package/dist/cli/backend/src/services/monitoring/agent-turn-state.d.ts +184 -0
  498. package/dist/cli/backend/src/services/monitoring/agent-turn-state.d.ts.map +1 -0
  499. package/dist/cli/backend/src/services/monitoring/agent-turn-state.js +391 -0
  500. package/dist/cli/backend/src/services/monitoring/agent-turn-state.js.map +1 -0
  501. package/dist/cli/backend/src/services/monitoring/claude-transcript-turn.d.ts +73 -0
  502. package/dist/cli/backend/src/services/monitoring/claude-transcript-turn.d.ts.map +1 -0
  503. package/dist/cli/backend/src/services/monitoring/claude-transcript-turn.js +258 -0
  504. package/dist/cli/backend/src/services/monitoring/claude-transcript-turn.js.map +1 -0
  505. package/dist/cli/backend/src/services/open-items/open-items.service.d.ts +57 -0
  506. package/dist/cli/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
  507. package/dist/cli/backend/src/services/open-items/open-items.service.js +100 -4
  508. package/dist/cli/backend/src/services/open-items/open-items.service.js.map +1 -1
  509. package/dist/cli/backend/src/services/project-tickets/project-ticket.service.d.ts +36 -0
  510. package/dist/cli/backend/src/services/project-tickets/project-ticket.service.d.ts.map +1 -1
  511. package/dist/cli/backend/src/services/project-tickets/project-ticket.service.js +42 -3
  512. package/dist/cli/backend/src/services/project-tickets/project-ticket.service.js.map +1 -1
  513. package/dist/cli/backend/src/services/restart/in-flight-turn-tracker.service.d.ts +34 -3
  514. package/dist/cli/backend/src/services/restart/in-flight-turn-tracker.service.d.ts.map +1 -1
  515. package/dist/cli/backend/src/services/restart/in-flight-turn-tracker.service.js +57 -2
  516. package/dist/cli/backend/src/services/restart/in-flight-turn-tracker.service.js.map +1 -1
  517. package/dist/cli/backend/src/services/restart/restart-drain.service.d.ts +22 -0
  518. package/dist/cli/backend/src/services/restart/restart-drain.service.d.ts.map +1 -1
  519. package/dist/cli/backend/src/services/restart/restart-drain.service.js +37 -5
  520. package/dist/cli/backend/src/services/restart/restart-drain.service.js.map +1 -1
  521. package/dist/cli/backend/src/services/slack/slack-auto-working.service.d.ts +29 -0
  522. package/dist/cli/backend/src/services/slack/slack-auto-working.service.d.ts.map +1 -1
  523. package/dist/cli/backend/src/services/slack/slack-auto-working.service.js +66 -3
  524. package/dist/cli/backend/src/services/slack/slack-auto-working.service.js.map +1 -1
  525. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +79 -15
  526. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  527. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +200 -41
  528. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  529. package/dist/cli/backend/src/services/slack/slack.service.d.ts +18 -0
  530. package/dist/cli/backend/src/services/slack/slack.service.d.ts.map +1 -1
  531. package/dist/cli/backend/src/services/slack/slack.service.js +32 -0
  532. package/dist/cli/backend/src/services/slack/slack.service.js.map +1 -1
  533. package/dist/cli/backend/src/services/trace/trace-context.service.d.ts +17 -0
  534. package/dist/cli/backend/src/services/trace/trace-context.service.d.ts.map +1 -1
  535. package/dist/cli/backend/src/services/trace/trace-context.service.js +58 -1
  536. package/dist/cli/backend/src/services/trace/trace-context.service.js.map +1 -1
  537. package/dist/cli/backend/src/services/trace/trace-recorder.d.ts +48 -0
  538. package/dist/cli/backend/src/services/trace/trace-recorder.d.ts.map +1 -1
  539. package/dist/cli/backend/src/services/trace/trace-recorder.js +121 -1
  540. package/dist/cli/backend/src/services/trace/trace-recorder.js.map +1 -1
  541. package/dist/cli/backend/src/services/trace/trace-store.d.ts +40 -1
  542. package/dist/cli/backend/src/services/trace/trace-store.d.ts.map +1 -1
  543. package/dist/cli/backend/src/services/trace/trace-store.js +126 -14
  544. package/dist/cli/backend/src/services/trace/trace-store.js.map +1 -1
  545. package/dist/cli/backend/src/services/trace/trace.types.d.ts +22 -3
  546. package/dist/cli/backend/src/services/trace/trace.types.d.ts.map +1 -1
  547. package/dist/cli/backend/src/services/trace/trace.types.js +20 -1
  548. package/dist/cli/backend/src/services/trace/trace.types.js.map +1 -1
  549. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.d.ts +3 -1
  550. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -1
  551. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.js.map +1 -1
  552. package/dist/cli/backend/src/types/decision.types.d.ts +3 -1
  553. package/dist/cli/backend/src/types/decision.types.d.ts.map +1 -1
  554. package/dist/cli/backend/src/types/ticket-autopilot.types.d.ts +9 -0
  555. package/dist/cli/backend/src/types/ticket-autopilot.types.d.ts.map +1 -1
  556. package/dist/cli/backend/src/types/ticket-autopilot.types.js +14 -0
  557. package/dist/cli/backend/src/types/ticket-autopilot.types.js.map +1 -1
  558. package/dist/cli/backend/src/types/v2/open-item.types.d.ts +4 -0
  559. package/dist/cli/backend/src/types/v2/open-item.types.d.ts.map +1 -1
  560. package/dist/cli/backend/src/types/v2/work-item.types.d.ts +1 -1
  561. package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  562. package/dist/cli/backend/src/types/v2/work-item.types.js +1 -0
  563. package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
  564. package/dist/cli/backend/src/utils/secret-env.d.ts.map +1 -1
  565. package/dist/cli/backend/src/utils/secret-env.js +8 -1
  566. package/dist/cli/backend/src/utils/secret-env.js.map +1 -1
  567. package/dist/cli/cli/src/commands/service.d.ts +12 -0
  568. package/dist/cli/cli/src/commands/service.d.ts.map +1 -1
  569. package/dist/cli/cli/src/commands/service.js +36 -2
  570. package/dist/cli/cli/src/commands/service.js.map +1 -1
  571. package/dist/cli/cli/src/index.js +4 -0
  572. package/dist/cli/cli/src/index.js.map +1 -1
  573. package/dist/cli/cli/src/utils/owner-token-fetch.d.ts +41 -0
  574. package/dist/cli/cli/src/utils/owner-token-fetch.d.ts.map +1 -0
  575. package/dist/cli/cli/src/utils/owner-token-fetch.js +83 -0
  576. package/dist/cli/cli/src/utils/owner-token-fetch.js.map +1 -0
  577. package/dist/cli/cli/src/utils/safe-shutdown.d.ts +13 -3
  578. package/dist/cli/cli/src/utils/safe-shutdown.d.ts.map +1 -1
  579. package/dist/cli/cli/src/utils/safe-shutdown.js +26 -4
  580. package/dist/cli/cli/src/utils/safe-shutdown.js.map +1 -1
  581. package/dist/cli/config/constants.d.ts +67 -0
  582. package/dist/cli/config/constants.d.ts.map +1 -1
  583. package/dist/cli/config/constants.js +67 -0
  584. package/dist/cli/config/constants.js.map +1 -1
  585. package/frontend/dist/assets/index-5cbcf45b.css +42 -0
  586. package/frontend/dist/assets/{index-800118ca.js → index-63a33dbf.js} +291 -291
  587. package/frontend/dist/index.html +2 -2
  588. package/package.json +1 -1
  589. package/packages/crewly-agent/src/runtime/api-client.test.ts +42 -0
  590. package/packages/crewly-agent/src/runtime/api-client.ts +6 -0
  591. package/dist/backend/backend/src/services/v3/request-notification.service.d.ts +0 -52
  592. package/dist/backend/backend/src/services/v3/request-notification.service.d.ts.map +0 -1
  593. package/dist/backend/backend/src/services/v3/request-notification.service.js +0 -161
  594. package/dist/backend/backend/src/services/v3/request-notification.service.js.map +0 -1
  595. package/frontend/dist/assets/index-5e967795.css +0 -42
@@ -23,7 +23,8 @@
23
23
  * @module services/experiments/experiment.service
24
24
  */
25
25
  import { type ComponentLogger } from '../core/logger.service.js';
26
- import { type Experiment, type ExperimentMetric, type ExperimentStatus, type ExperimentTicketLink } from '../../types/experiment.types.js';
26
+ import { type Experiment, type ExperimentAutopilotScope, type ExperimentProcessSummary, type ExperimentMetric, type ExperimentStatus, type ExperimentTicketLink } from '../../types/experiment.types.js';
27
+ import { type DateRange } from './experiment-verdict.js';
27
28
  import type { MetricFetcher } from './seo-ops-metric.fetcher.js';
28
29
  /** A notice for the owner (same shape as the ticket autopilot's). */
29
30
  export interface ExperimentOwnerNotice {
@@ -48,6 +49,16 @@ export type TicketShipState = {
48
49
  done: true;
49
50
  at: string | null;
50
51
  };
52
+ /** The ticket autopilot as an experiment sees it (specs/2026-10-03-autopilot-experiments.md §3). */
53
+ export interface ExperimentAutopilotSource {
54
+ /** A project by id / name / path; throws when unknown */
55
+ resolveProject(ref: string): Promise<{
56
+ id: string;
57
+ name: string;
58
+ }>;
59
+ /** The autopilot's process numbers over a window (local days, inclusive) */
60
+ process(projectId: string, label: string | null, range: DateRange): Promise<ExperimentProcessSummary>;
61
+ }
51
62
  /** Dependencies. */
52
63
  export interface ExperimentServiceDeps {
53
64
  /** JSON store */
@@ -65,6 +76,8 @@ export interface ExperimentServiceDeps {
65
76
  notifyOwner?: (notice: ExperimentOwnerNotice) => Promise<boolean>;
66
77
  /** Does a file exist (the seo-ops config) */
67
78
  fileExists?: (file: string) => Promise<boolean>;
79
+ /** Ticket autopilot stats (autopilot-scoped cards); absent = such cards are refused */
80
+ autopilot?: ExperimentAutopilotSource;
68
81
  now?: () => Date;
69
82
  logger?: ComponentLogger;
70
83
  }
@@ -80,6 +93,12 @@ export interface CreateExperimentInput {
80
93
  confidence?: unknown;
81
94
  /** When the change went live (ISO). Required when the linked ticket is already done with no recorded done time. */
82
95
  shippedAt?: unknown;
96
+ /** Autopilot scope `{ project, label? }`: the card measures a period of autopilot work */
97
+ autopilot?: unknown;
98
+ /** Extra outcome metrics (autopilot scope), each like `metric`; `config` defaults to the primary's */
99
+ metrics?: unknown;
100
+ /** Autopilot scope: when the period starts (ISO, not in the future; default: now) */
101
+ startedAt?: unknown;
83
102
  }
84
103
  /** An error with an HTTP status. */
85
104
  export declare class ExperimentError extends Error {
@@ -90,6 +109,27 @@ export declare class ExperimentError extends Error {
90
109
  */
91
110
  constructor(status: number, message: string);
92
111
  }
112
+ /**
113
+ * A local calendar day (the autopilot's days; the budget resets at local midnight).
114
+ *
115
+ * @param d - Time
116
+ * @returns YYYY-MM-DD
117
+ */
118
+ export declare function localDay(d: Date): string;
119
+ /**
120
+ * The process windows of an autopilot card, in local days: the observation
121
+ * window starts ON the start day (the autopilot works that day too), the
122
+ * baseline is the equal window right before it.
123
+ *
124
+ * @param startedAt - When the card started (ISO)
125
+ * @param windowDays - Days per window
126
+ * @returns Baseline, observation, and when the observation window is over
127
+ */
128
+ export declare function processWindows(startedAt: string, windowDays: number): {
129
+ baseline: DateRange;
130
+ observation: DateRange;
131
+ dueAtMs: number;
132
+ };
93
133
  /**
94
134
  * A GA4 landing-page filter as a path: GA4 reports landing pages as paths, so
95
135
  * a full URL is reduced to its path and any query string / fragment dropped
@@ -137,6 +177,20 @@ export declare function metricLabel(m: ExperimentMetric): string;
137
177
  * @returns Markdown
138
178
  */
139
179
  export declare function resultSummary(e: Experiment): string;
180
+ /**
181
+ * The process numbers as one line.
182
+ *
183
+ * @param p - Process summary
184
+ * @returns e.g. "9 tickets shipped · 1.2 owner touches per ticket · stalls 3h 10m · $2.10 per shipped ticket"
185
+ */
186
+ export declare function processLine(p: ExperimentProcessSummary): string;
187
+ /**
188
+ * The autopilot part of a result: the other outcome metrics and the process.
189
+ *
190
+ * @param a - Scope
191
+ * @returns Lines
192
+ */
193
+ export declare function autopilotSummaryLines(a: ExperimentAutopilotScope): string[];
140
194
  /**
141
195
  * Experiment cards: store, lifecycle and the measuring tick.
142
196
  */
@@ -149,6 +203,8 @@ export declare class ExperimentService {
149
203
  private timer;
150
204
  /** A tick is running (fetches can be slow; ticks never overlap) */
151
205
  private ticking;
206
+ /** Check-ins whose reads / send keep failing: next try and failures so far */
207
+ private readonly checkInRetry;
152
208
  /** Experiments being measured right now (a measureNow racing a tick fetches once) */
153
209
  private readonly measuring;
154
210
  /**
@@ -237,6 +293,46 @@ export declare class ExperimentService {
237
293
  * @throws ExperimentError(400) on invalid input
238
294
  */
239
295
  create(input: CreateExperimentInput, caller: string): Promise<Experiment>;
296
+ /**
297
+ * The autopilot scope of a new card, validated.
298
+ *
299
+ * @param input - Create input
300
+ * @param primary - The primary metric (its config is the default of the extra metrics)
301
+ * @returns Scope, or undefined for an ordinary card
302
+ * @throws ExperimentError(400)
303
+ */
304
+ private parseAutopilotScope;
305
+ /**
306
+ * Autopilot cards: fetch the extra outcome metrics' baselines and the
307
+ * process baseline that are still missing (retried by the tick).
308
+ *
309
+ * @param id - EXP-n
310
+ */
311
+ private captureAutopilotBaseline;
312
+ /**
313
+ * Autopilot cards: the process baseline (as soon as the card starts) and
314
+ * the process result (once the observation window's last local day is
315
+ * over), each recorded once, independent of the outcome metrics. A failed
316
+ * read is retried by the next tick; a window with no autopilot traces is
317
+ * stored as no-data, never as zeros.
318
+ *
319
+ * @param id - EXP-n
320
+ */
321
+ private captureProcess;
322
+ /**
323
+ * Autopilot cards whose outcome fetch keeps failing: remind the owner at
324
+ * most once a week (the first notice is {@link fetchFailed}'s).
325
+ *
326
+ * @param id - EXP-n
327
+ */
328
+ private remindStuck;
329
+ /**
330
+ * Autopilot cards: one short owner note per week while running.
331
+ *
332
+ * @param id - EXP-n
333
+ * @returns True when a check-in went out
334
+ */
335
+ private checkIn;
240
336
  /**
241
337
  * Mark an experiment shipped: fix its windows, record the prediction and
242
338
  * capture the baseline.
@@ -1 +1 @@
1
- {"version":3,"file":"experiment.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/experiments/experiment.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,EAGL,KAAK,UAAU,EAGf,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EAErB,KAAK,oBAAoB,EAE1B,MAAM,iCAAiC,CAAC;AAGzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,qEAAqE;AACrE,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,uFAAuF;AACvF,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzG,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5F;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAElF,oBAAoB;AACpB,MAAM,WAAW,qBAAqB;IACpC,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,WAAW,EAAE,aAAa,CAAC;IAC3B,4FAA4F;IAC5F,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IAC3E,sDAAsD;IACtD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,iFAAiF;IACjF,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvE,6DAA6D;IAC7D,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE,6CAA6C;IAC7C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED,iDAAiD;AACjD,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mHAAmH;IACnH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,oCAAoC;AACpC,qBAAa,eAAgB,SAAQ,KAAK;aAKZ,MAAM,EAAE,MAAM;IAJ1C;;;OAGG;gBACyB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAI5D;AAuCD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAYhD;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAqC7D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB,GAAG,SAAS,CAajF;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,oBAAoB,GAAG,MAAM,CAE9D;AAYD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAMvD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAcnD;AAED;;GAEG;AACH,qBAAa,iBAAiB;IAchB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAbjC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkC;IACzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,KAAK,CAAuC;IACpD,OAAO,CAAC,KAAK,CAA+C;IAC5D,mEAAmE;IACnE,OAAO,CAAC,OAAO,CAAS;IACxB,qFAAqF;IACrF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAE/C;;OAEG;gBAC0B,IAAI,EAAE,qBAAqB;IAKxD;;;;OAIG;IACH,MAAM,CAAC,WAAW,IAAI,iBAAiB,GAAG,IAAI;IAI9C;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI;IAQ3D;;;;OAIG;IACH,KAAK,CAAC,UAAU,GAAE,MAA8C,GAAG,IAAI;IAWvE,qBAAqB;IACrB,IAAI,IAAI,IAAI;IASZ;;;;;OAKG;IACH,OAAO,CAAC,MAAM;IAMd;;;;OAIG;YACW,IAAI;IAUlB;;;;OAIG;YACW,IAAI;IAOlB;;;;;;;OAOG;YACW,MAAM;IAYpB;;;;;;OAMG;IACH,OAAO,CAAC,MAAM;IAUd;;;;;OAKG;IACG,IAAI,CAAC,MAAM,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAQpF;;;;;OAKG;IACG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IASjD;;;;;;;OAOG;IACG,MAAM,CAAC,KAAK,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAmG/E;;;;;;;;;OASG;IACG,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAkB/E;;;;;;;;OAQG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAQ9E;;;;;;OAMG;IACG,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAiBjD;;;;;OAKG;IACG,IAAI,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAU5D;;;;OAIG;YACW,OAAO;IA0CrB;;;;;;;;OAQG;IACH,OAAO,CAAC,UAAU;IAKlB;;;;;;OAMG;YACW,eAAe;IAqB7B;;;;OAIG;YACW,gBAAgB;IAc9B;;;;;;OAMG;YACW,WAAW;IA0BzB;;;;OAIG;YACW,eAAe;IAuB7B;;;;OAIG;YACW,OAAO;IAUrB;;;;OAIG;YACW,WAAW;IA4BzB;;;;;OAKG;YACW,QAAQ;CAwDvB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,GAAG,SAAS,CAErE"}
1
+ {"version":3,"file":"experiment.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/experiments/experiment.service.ts"],"names":[],"mappings":"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"}
@@ -67,6 +67,34 @@ function parseShipTime(raw, now) {
67
67
  function errText(err) {
68
68
  return err instanceof Error ? err.message : String(err);
69
69
  }
70
+ /**
71
+ * A local calendar day (the autopilot's days; the budget resets at local midnight).
72
+ *
73
+ * @param d - Time
74
+ * @returns YYYY-MM-DD
75
+ */
76
+ export function localDay(d) {
77
+ const pad = (n) => String(n).padStart(2, '0');
78
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
79
+ }
80
+ /**
81
+ * The process windows of an autopilot card, in local days: the observation
82
+ * window starts ON the start day (the autopilot works that day too), the
83
+ * baseline is the equal window right before it.
84
+ *
85
+ * @param startedAt - When the card started (ISO)
86
+ * @param windowDays - Days per window
87
+ * @returns Baseline, observation, and when the observation window is over
88
+ */
89
+ export function processWindows(startedAt, windowDays) {
90
+ const t = new Date(startedAt);
91
+ const at = (delta) => new Date(t.getFullYear(), t.getMonth(), t.getDate() + delta, 12);
92
+ return {
93
+ baseline: { start: localDay(at(-windowDays)), end: localDay(at(-1)) },
94
+ observation: { start: localDay(at(0)), end: localDay(at(windowDays - 1)) },
95
+ dueAtMs: new Date(t.getFullYear(), t.getMonth(), t.getDate() + windowDays, 0, 0, 0, 0).getTime(),
96
+ };
97
+ }
70
98
  /**
71
99
  * Trimmed, length-capped string, or undefined.
72
100
  *
@@ -238,10 +266,62 @@ export function resultSummary(e) {
238
266
  }
239
267
  if (e.baseline && e.result)
240
268
  lines.push(`Baseline ${e.baseline.start}..${e.baseline.end} · Result ${e.result.start}..${e.result.end}`);
269
+ if (e.autopilot)
270
+ lines.push(...autopilotSummaryLines(e.autopilot));
241
271
  if (e.ticket)
242
272
  lines.push(`Ticket: ${ticketLabel(e.ticket)}`);
243
273
  return lines.join('\n');
244
274
  }
275
+ /**
276
+ * Duration in words.
277
+ *
278
+ * @param ms - Milliseconds
279
+ * @returns "3h 10m" / "45m"
280
+ */
281
+ function durationText(ms) {
282
+ const m = Math.round(ms / 60_000);
283
+ if (m < 60)
284
+ return `${m}m`;
285
+ const h = Math.floor(m / 60);
286
+ return m % 60 ? `${h}h ${m % 60}m` : `${h}h`;
287
+ }
288
+ /**
289
+ * The process numbers as one line.
290
+ *
291
+ * @param p - Process summary
292
+ * @returns e.g. "9 tickets shipped · 1.2 owner touches per ticket · stalls 3h 10m · $2.10 per shipped ticket"
293
+ */
294
+ export function processLine(p) {
295
+ return [
296
+ `${p.ticketsShipped} ticket${p.ticketsShipped === 1 ? '' : 's'} shipped (${p.ticketsStarted} started)`,
297
+ `${p.ownerTouchesPerTicket === null ? `${p.ownerTouches} owner touches` : `${p.ownerTouchesPerTicket} owner touches per ticket`}`,
298
+ `stalls ${p.stalls === 0 ? 'none' : `${p.stalls} (${durationText(p.stallMs)})`}`,
299
+ p.costPerShippedTicket === null ? `$${p.costUsd.toFixed(2)} spent` : `$${p.costPerShippedTicket.toFixed(2)} per shipped ticket`,
300
+ ].join(' · ');
301
+ }
302
+ /**
303
+ * The autopilot part of a result: the other outcome metrics and the process.
304
+ *
305
+ * @param a - Scope
306
+ * @returns Lines
307
+ */
308
+ export function autopilotSummaryLines(a) {
309
+ const lines = [];
310
+ if (a.outcomes.length > 0) {
311
+ lines.push('Other metrics:');
312
+ for (const o of a.outcomes) {
313
+ const word = o.verdict === 'worked' ? 'worked' : o.verdict === 'didnt' ? "didn't work" : o.verdict ? 'inconclusive' : 'not measured';
314
+ lines.push(`- ${metricLabel(o.metric)}: ${o.verdictReason ?? (o.lastError ? `fetch failed (${o.lastError.slice(0, 120)})` : 'n/a')} — ${word}`);
315
+ }
316
+ }
317
+ const scope = `autopilot of ${a.projectName}${a.label ? `, label ${a.label}` : ''}`;
318
+ if (a.processResult)
319
+ lines.push(`Process (${scope}): ${a.processResult.noData ? 'no autopilot work recorded' : processLine(a.processResult)}`);
320
+ // A baseline window without autopilot traces is no data, not zeros: left out.
321
+ if (a.processBaseline && !a.processBaseline.noData)
322
+ lines.push(`Process before: ${processLine(a.processBaseline)}`);
323
+ return lines;
324
+ }
245
325
  /**
246
326
  * Experiment cards: store, lifecycle and the measuring tick.
247
327
  */
@@ -254,6 +334,8 @@ export class ExperimentService {
254
334
  timer = null;
255
335
  /** A tick is running (fetches can be slow; ticks never overlap) */
256
336
  ticking = false;
337
+ /** Check-ins whose reads / send keep failing: next try and failures so far */
338
+ checkInRetry = new Map();
257
339
  /** Experiments being measured right now (a measureNow racing a tick fetches once) */
258
340
  measuring = new Set();
259
341
  /**
@@ -458,7 +540,15 @@ export class ExperimentService {
458
540
  }
459
541
  const ticket = validateTicketLink(input.ticket);
460
542
  const title = text(input.title) ?? hypothesis.slice(0, 80);
461
- const explicitShip = input.shippedAt === undefined || input.shippedAt === null || input.shippedAt === '' ? undefined : parseShipTime(String(input.shippedAt), this.now());
543
+ const scope = await this.parseAutopilotScope(input, metric);
544
+ const startedAt = input.startedAt === undefined || input.startedAt === null || input.startedAt === '' ? undefined : parseShipTime(String(input.startedAt), this.now());
545
+ // An autopilot card starts at its creation (or startedAt): the baseline is
546
+ // the equal window before it (specs/2026-10-03-autopilot-experiments.md §3).
547
+ const explicitShip = scope
548
+ ? (startedAt ?? (input.shippedAt ? parseShipTime(String(input.shippedAt), this.now()) : this.now().toISOString()))
549
+ : input.shippedAt === undefined || input.shippedAt === null || input.shippedAt === ''
550
+ ? undefined
551
+ : parseShipTime(String(input.shippedAt), this.now());
462
552
  // A ticket that is already done ships the card right away. Its done
463
553
  // transition dates the ship; with no recorded done time the caller must
464
554
  // say when the change went live (guessing would skew the baseline).
@@ -497,9 +587,13 @@ export class ExperimentService {
497
587
  status: 'planned',
498
588
  createdAt: at,
499
589
  updatedAt: at,
590
+ ...(scope ? { autopilot: scope } : {}),
500
591
  timeline: [],
501
592
  };
502
593
  this.record(e, 'created', `by ${caller}${ticket ? ` on ${ticketLabel(ticket)}` : ''}`);
594
+ if (scope) {
595
+ this.record(e, 'autopilot_scope', `autopilot of ${scope.projectName}${scope.label ? `, label ${scope.label}` : ''}; outcome metrics: ${[metricLabel(metric), ...scope.outcomes.map((o) => metricLabel(o.metric))].join('; ')}`);
596
+ }
503
597
  data.experiments.push(e);
504
598
  await this.save(data);
505
599
  return e;
@@ -514,6 +608,225 @@ export class ExperimentService {
514
608
  return this.ship(created.id, `ticket ${ticketLabel(ticket)} done`, ticketDoneAt);
515
609
  return created;
516
610
  }
611
+ /**
612
+ * The autopilot scope of a new card, validated.
613
+ *
614
+ * @param input - Create input
615
+ * @param primary - The primary metric (its config is the default of the extra metrics)
616
+ * @returns Scope, or undefined for an ordinary card
617
+ * @throws ExperimentError(400)
618
+ */
619
+ async parseAutopilotScope(input, primary) {
620
+ if (input.autopilot === undefined || input.autopilot === null || input.autopilot === '' || input.autopilot === false) {
621
+ if (input.metrics !== undefined && input.metrics !== null)
622
+ throw new ExperimentError(400, 'metrics (extra outcome metrics) are for autopilot cards: add autopilot: {project}');
623
+ return undefined;
624
+ }
625
+ if (!this.deps.autopilot)
626
+ throw new ExperimentError(400, 'Autopilot experiments are not available (the ticket autopilot is not running)');
627
+ const raw = (typeof input.autopilot === 'object' ? input.autopilot : {});
628
+ const ref = text(raw.project) ?? text(raw.projectId);
629
+ if (!ref)
630
+ throw new ExperimentError(400, 'autopilot.project is required (project id, name or path)');
631
+ let project;
632
+ try {
633
+ project = await this.deps.autopilot.resolveProject(ref);
634
+ }
635
+ catch (err) {
636
+ throw new ExperimentError(400, `autopilot.project: ${errText(err)}`);
637
+ }
638
+ const label = text(raw.label);
639
+ const list = input.metrics === undefined || input.metrics === null ? [] : input.metrics;
640
+ if (!Array.isArray(list))
641
+ throw new ExperimentError(400, 'metrics must be a list of metric definitions');
642
+ if (list.length > EXPERIMENT_CONSTANTS.MAX_EXTRA_METRICS)
643
+ throw new ExperimentError(400, `at most ${EXPERIMENT_CONSTANTS.MAX_EXTRA_METRICS} extra metrics`);
644
+ const outcomes = [];
645
+ for (const [i, m] of list.entries()) {
646
+ const withConfig = m && typeof m === 'object' ? { config: primary.config, ...m } : m;
647
+ try {
648
+ const metric = validateMetric(withConfig);
649
+ if (metric.config !== primary.config && this.deps.fileExists && !(await this.deps.fileExists(metric.config))) {
650
+ throw new ExperimentError(400, `seo-ops config not found: ${metric.config}`);
651
+ }
652
+ outcomes.push({ metric });
653
+ }
654
+ catch (err) {
655
+ throw new ExperimentError(400, `metrics[${i}]: ${errText(err)}`);
656
+ }
657
+ }
658
+ return { projectId: project.id, projectName: project.name, ...(label ? { label } : {}), outcomes, checkIns: 0 };
659
+ }
660
+ /**
661
+ * Autopilot cards: fetch the extra outcome metrics' baselines and the
662
+ * process baseline that are still missing (retried by the tick).
663
+ *
664
+ * @param id - EXP-n
665
+ */
666
+ async captureAutopilotBaseline(id) {
667
+ const e = await this.get(id);
668
+ if (!e || e.status !== 'running' || !e.autopilot || !e.shippedAt)
669
+ return;
670
+ const fetched = [];
671
+ for (const [index, o] of e.autopilot.outcomes.entries()) {
672
+ if (o.baseline)
673
+ continue;
674
+ const ow = experimentWindows(e.shippedAt, e.windowDays, o.metric.source);
675
+ try {
676
+ fetched.push({ index, m: await this.deps.fetchMetric(o.metric, ow.baseline) });
677
+ }
678
+ catch (err) {
679
+ fetched.push({ index, error: errText(err).slice(0, 500) });
680
+ }
681
+ }
682
+ if (fetched.length === 0)
683
+ return;
684
+ await this.mutate(id, (x) => {
685
+ if (!x.autopilot)
686
+ return;
687
+ for (const f of fetched) {
688
+ const o = x.autopilot.outcomes[f.index];
689
+ if (!o || o.baseline)
690
+ continue;
691
+ if (f.m) {
692
+ o.baseline = f.m;
693
+ delete o.lastError;
694
+ this.record(x, 'outcome_baseline', `${metricLabel(o.metric)}: ${formatValue(f.m.total, o.metric.measure)} over ${f.m.start}..${f.m.end}`);
695
+ }
696
+ else if (o.lastError !== f.error) {
697
+ o.lastError = f.error;
698
+ this.record(x, 'fetch_failed', `baseline of ${metricLabel(o.metric)}: ${f.error}`);
699
+ }
700
+ }
701
+ });
702
+ }
703
+ /**
704
+ * Autopilot cards: the process baseline (as soon as the card starts) and
705
+ * the process result (once the observation window's last local day is
706
+ * over), each recorded once, independent of the outcome metrics. A failed
707
+ * read is retried by the next tick; a window with no autopilot traces is
708
+ * stored as no-data, never as zeros.
709
+ *
710
+ * @param id - EXP-n
711
+ */
712
+ async captureProcess(id) {
713
+ const e = await this.get(id);
714
+ if (!e || e.status !== 'running' || !e.autopilot || !e.shippedAt || !this.deps.autopilot)
715
+ return;
716
+ const w = processWindows(e.shippedAt, e.windowDays);
717
+ const label = e.autopilot.label ?? null;
718
+ const read = async (range, what) => this.deps.autopilot?.process(e.autopilot.projectId, label, range).catch((err) => {
719
+ this.logger.debug(`Could not read the autopilot process ${what}`, { id, error: errText(err) });
720
+ return undefined;
721
+ });
722
+ const base = e.autopilot.processBaseline ? undefined : await read(w.baseline, 'baseline');
723
+ const result = !e.autopilot.processResult && this.now().getTime() >= w.dueAtMs ? await read(w.observation, 'result') : undefined;
724
+ if (!base && !result)
725
+ return;
726
+ await this.mutate(id, (x) => {
727
+ if (!x.autopilot)
728
+ return;
729
+ if (base && !x.autopilot.processBaseline) {
730
+ x.autopilot.processBaseline = base;
731
+ this.record(x, 'process_baseline', base.noData ? `no autopilot work in ${w.baseline.start}..${w.baseline.end}` : processLine(base));
732
+ }
733
+ if (result && !x.autopilot.processResult) {
734
+ x.autopilot.processResult = result;
735
+ this.record(x, 'process_result', result.noData ? `no autopilot work in ${w.observation.start}..${w.observation.end}` : processLine(result));
736
+ }
737
+ });
738
+ }
739
+ /**
740
+ * Autopilot cards whose outcome fetch keeps failing: remind the owner at
741
+ * most once a week (the first notice is {@link fetchFailed}'s).
742
+ *
743
+ * @param id - EXP-n
744
+ */
745
+ async remindStuck(id) {
746
+ const e = await this.get(id);
747
+ if (!e || !e.autopilot || !e.stuckReported || !this.deps.notifyOwner)
748
+ return;
749
+ const last = Date.parse(e.stuckNoticeAt ?? '') || 0;
750
+ if (this.now().getTime() - last < EXPERIMENT_CONSTANTS.CHECK_IN_INTERVAL_MS)
751
+ return;
752
+ const process = e.autopilot.processResult && !e.autopilot.processResult.noData ? `\nProcess so far: ${processLine(e.autopilot.processResult)}` : '';
753
+ const sent = await this.deps
754
+ .notifyOwner({
755
+ title: `Experiment ${e.id} still can't fetch its metric`,
756
+ message: `${e.title}\nMetric: ${metricLabel(e.metric)}\nStill failing: ${e.lastError ?? 'unknown error'}\nFix the seo-ops config or credentials (${e.metric.config}).${process}`,
757
+ urgent: false,
758
+ })
759
+ .catch(() => false);
760
+ if (sent)
761
+ await this.mutate(id, (x) => {
762
+ x.stuckNoticeAt = this.now().toISOString();
763
+ this.record(x, 'stuck_reminder', x.lastError ?? '');
764
+ });
765
+ }
766
+ /**
767
+ * Autopilot cards: one short owner note per week while running.
768
+ *
769
+ * @param id - EXP-n
770
+ * @returns True when a check-in went out
771
+ */
772
+ async checkIn(id) {
773
+ const e = await this.get(id);
774
+ if (!e || e.status !== 'running' || !e.autopilot || !e.shippedAt || !this.deps.autopilot)
775
+ return false;
776
+ const nowMs = this.now().getTime();
777
+ if (e.dueAt && Date.parse(e.dueAt) <= nowMs)
778
+ return false;
779
+ const week = Math.floor((nowMs - Date.parse(e.shippedAt)) / EXPERIMENT_CONSTANTS.CHECK_IN_INTERVAL_MS);
780
+ if (week < 1 || week <= e.autopilot.checkIns)
781
+ return false;
782
+ const retry = this.checkInRetry.get(id);
783
+ if (retry && nowMs < retry.at)
784
+ return false;
785
+ const backOff = () => {
786
+ const failures = (retry?.failures ?? 0) + 1;
787
+ const C = EXPERIMENT_CONSTANTS;
788
+ this.checkInRetry.set(id, { failures, at: nowMs + Math.min(C.CHECK_IN_RETRY_MAX_MS, C.CHECK_IN_RETRY_MIN_MS * 2 ** (failures - 1)) });
789
+ return false;
790
+ };
791
+ const w = experimentWindows(e.shippedAt, e.windowDays, e.metric.source);
792
+ // Process numbers in local days, start day included (the autopilot's days).
793
+ const pw = processWindows(e.shippedAt, e.windowDays);
794
+ const today = localDay(this.now());
795
+ const soFar = { start: pw.observation.start, end: today < pw.observation.end ? today : pw.observation.end };
796
+ const process = await this.deps.autopilot.process(e.autopilot.projectId, e.autopilot.label ?? null, soFar).catch(() => null);
797
+ // No process numbers: no note (it would say nothing); retry with a backoff.
798
+ if (!process)
799
+ return backOff();
800
+ // The primary metric so far: only days that have settled.
801
+ const lag = EXPERIMENT_CONSTANTS.SOURCE_LAG_DAYS[e.metric.source] ?? 0;
802
+ const settled = new Date(nowMs - (lag + 1) * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
803
+ const metricEnd = settled < w.observation.end ? settled : w.observation.end;
804
+ let metricSoFar = null;
805
+ if (metricEnd >= w.observation.start) {
806
+ metricSoFar = await this.deps.fetchMetric(e.metric, { start: w.observation.start, end: metricEnd }).catch(() => null);
807
+ }
808
+ const lines = [`${e.id} week ${week}: ${e.title}`];
809
+ lines.push(process.noData ? 'No autopilot work recorded yet.' : processLine(process));
810
+ if (metricSoFar) {
811
+ const days = Math.round((Date.parse(`${metricEnd}T00:00:00Z`) - Date.parse(`${w.observation.start}T00:00:00Z`)) / (24 * 60 * 60 * 1000)) + 1;
812
+ const base = e.baseline ? ` (baseline ${formatValue(e.baseline.total, e.metric.measure)} over ${e.windowDays} days)` : '';
813
+ lines.push(`${metricLabel(e.metric)}: ${formatValue(metricSoFar.total, e.metric.measure)} over the first ${days} day${days === 1 ? '' : 's'}${base}`);
814
+ }
815
+ lines.push(`Result due ${e.dueAt?.slice(0, 10) ?? 'later'}.`);
816
+ const message = lines.join('\n');
817
+ const sent = this.deps.notifyOwner ? await this.deps.notifyOwner({ title: `Experiment ${e.id}: week ${week}`, message, urgent: false }).catch(() => false) : true;
818
+ if (!sent)
819
+ return backOff();
820
+ this.checkInRetry.delete(id);
821
+ await this.mutate(id, (x) => {
822
+ if (!x.autopilot)
823
+ return;
824
+ x.autopilot.checkIns = week;
825
+ x.autopilot.lastCheckInAt = this.now().toISOString();
826
+ this.record(x, 'check_in', `week ${week}: ${process.noData ? 'no autopilot work yet' : processLine(process)}${metricSoFar ? `; ${metricLabel(e.metric)} so far ${formatValue(metricSoFar.total, e.metric.measure)}` : ''}`);
827
+ });
828
+ return true;
829
+ }
517
830
  /**
518
831
  * Mark an experiment shipped: fix its windows, record the prediction and
519
832
  * capture the baseline.
@@ -540,6 +853,8 @@ export class ExperimentService {
540
853
  });
541
854
  await this.recordPrediction(id);
542
855
  await this.captureBaseline(id);
856
+ // Autopilot cards: the process baseline does not wait for the outcome fetch.
857
+ await this.captureProcess(id);
543
858
  return (await this.get(id));
544
859
  }
545
860
  /**
@@ -626,11 +941,20 @@ export class ExperimentService {
626
941
  continue;
627
942
  }
628
943
  if (e.status === 'running') {
944
+ // Autopilot process numbers and check-ins run on their own schedule:
945
+ // a failing outcome fetch (e.g. missing credentials) never holds them.
946
+ if (e.autopilot) {
947
+ await this.captureProcess(e.id);
948
+ await this.checkIn(e.id);
949
+ await this.remindStuck(e.id);
950
+ }
629
951
  // After MAX_FETCH_ATTEMPTS failures in a row, retry once a day.
630
952
  if (this.backingOff(e, nowMs))
631
953
  continue;
632
954
  if (!e.baseline)
633
955
  await this.captureBaseline(e.id);
956
+ if (e.autopilot)
957
+ await this.captureAutopilotBaseline(e.id);
634
958
  if (e.dueAt && Date.parse(e.dueAt) <= nowMs) {
635
959
  const after = await this.get(e.id);
636
960
  if (after?.baseline) {
@@ -731,6 +1055,7 @@ export class ExperimentService {
731
1055
  this.record(e, 'fetch_failed', `${step}: ${e.lastError}`);
732
1056
  if (e.fetchAttempts >= EXPERIMENT_CONSTANTS.MAX_FETCH_ATTEMPTS && !e.stuckReported) {
733
1057
  e.stuckReported = true;
1058
+ e.stuckNoticeAt = this.now().toISOString();
734
1059
  tell = { ...e };
735
1060
  }
736
1061
  });
@@ -777,6 +1102,10 @@ export class ExperimentService {
777
1102
  delete x.lastFetchAt;
778
1103
  this.record(x, 'baseline_captured', `${formatValue(m.total, x.metric.measure)} over ${m.start}..${m.end} (volume ${m.volume})`);
779
1104
  });
1105
+ if (e.autopilot) {
1106
+ await this.captureAutopilotBaseline(id);
1107
+ await this.captureProcess(id);
1108
+ }
780
1109
  }
781
1110
  /**
782
1111
  * Fetch the observation window and label the result.
@@ -812,6 +1141,23 @@ export class ExperimentService {
812
1141
  await this.fetchFailed(id, 'result', err);
813
1142
  return;
814
1143
  }
1144
+ // Autopilot cards: the extra outcome metrics and the process numbers of
1145
+ // the same window (a failed extra fetch never blocks the result).
1146
+ const extras = [];
1147
+ let process = null;
1148
+ if (e.autopilot) {
1149
+ for (const o of e.autopilot.outcomes) {
1150
+ try {
1151
+ extras.push({ m: await this.deps.fetchMetric(o.metric, experimentWindows(e.shippedAt, e.windowDays, o.metric.source).observation) });
1152
+ }
1153
+ catch (err) {
1154
+ extras.push({ error: errText(err).slice(0, 500) });
1155
+ }
1156
+ }
1157
+ if (this.deps.autopilot && !e.autopilot.processResult) {
1158
+ process = await this.deps.autopilot.process(e.autopilot.projectId, e.autopilot.label ?? null, processWindows(e.shippedAt, e.windowDays).observation).catch(() => null);
1159
+ }
1160
+ }
815
1161
  await this.mutate(id, (x) => {
816
1162
  // Re-checked under the store lock: a racing measureNow / tick may
817
1163
  // have measured it already.
@@ -826,6 +1172,31 @@ export class ExperimentService {
826
1172
  delete x.lastError;
827
1173
  delete x.lastFetchAt;
828
1174
  this.record(x, 'measured', `${v.verdict}: ${v.reason}`);
1175
+ if (x.autopilot) {
1176
+ for (const [i, o] of x.autopilot.outcomes.entries()) {
1177
+ const got = extras[i];
1178
+ if (!got)
1179
+ continue;
1180
+ if (got.m) {
1181
+ o.result = got.m;
1182
+ delete o.lastError;
1183
+ if (o.baseline) {
1184
+ const ov = decideVerdict(o.metric.measure, defaultDirection(o.metric.measure), o.baseline, got.m);
1185
+ o.verdict = ov.verdict;
1186
+ o.verdictReason = ov.reason;
1187
+ }
1188
+ this.record(x, 'outcome_result', `${metricLabel(o.metric)}: ${o.verdictReason ?? `${formatValue(got.m.total, o.metric.measure)} (no baseline)`}`);
1189
+ }
1190
+ else {
1191
+ o.lastError = got.error;
1192
+ this.record(x, 'fetch_failed', `result of ${metricLabel(o.metric)}: ${got.error}`);
1193
+ }
1194
+ }
1195
+ if (process && !x.autopilot.processResult) {
1196
+ x.autopilot.processResult = process;
1197
+ this.record(x, 'process_result', process.noData ? 'no autopilot work in the window' : processLine(process));
1198
+ }
1199
+ }
829
1200
  });
830
1201
  this.logger.info('Experiment measured', { id });
831
1202
  }