crewly 1.20.193 → 1.20.195

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 (407) hide show
  1. package/config/roles/auditor/prompt.md +2 -2
  2. package/config/roles/orchestrator/fragments/communication.md +1 -1
  3. package/config/roles/orchestrator/prompt.md +15 -505
  4. package/config/skills/agent/computer-use/SKILL.md +6 -0
  5. package/config/skills/agent/core/experiment-card/SKILL.md +101 -0
  6. package/config/skills/agent/core/experiment-card/execute.sh +149 -0
  7. package/config/skills/agent/core/experiment-card/execute.test.sh +97 -0
  8. package/config/skills/agent/desktop-app-control/execute.sh +5 -2
  9. package/config/skills/orchestrator/send-message/execute.sh +19 -2
  10. package/config/skills/orchestrator/send-message/execute.test.sh +80 -0
  11. package/config/skills/registry.json +7 -5
  12. package/config/skills/team-leader/signal-digest/SKILL.md +110 -0
  13. package/config/skills/team-leader/signal-digest/execute.sh +173 -0
  14. package/config/skills/team-leader/signal-digest/execute.test.sh +123 -0
  15. package/config/skills/team-leader/signal-digest/signal-digest.config.example.json +23 -0
  16. package/config/skills/team-leader/signal-digest/signal_digest.py +572 -0
  17. package/config/skills/team-leader/signal-digest/signal_digest.test.py +319 -0
  18. package/dist/backend/backend/src/constants.d.ts +191 -1
  19. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  20. package/dist/backend/backend/src/constants.js +194 -1
  21. package/dist/backend/backend/src/constants.js.map +1 -1
  22. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  23. package/dist/backend/backend/src/controllers/chat/chat.controller.js +6 -0
  24. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  25. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -1
  26. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +3 -1
  27. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -1
  28. package/dist/backend/backend/src/controllers/experiments/experiments.routes.d.ts +27 -0
  29. package/dist/backend/backend/src/controllers/experiments/experiments.routes.d.ts.map +1 -0
  30. package/dist/backend/backend/src/controllers/experiments/experiments.routes.js +96 -0
  31. package/dist/backend/backend/src/controllers/experiments/experiments.routes.js.map +1 -0
  32. package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.d.ts +1 -0
  33. package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.d.ts.map +1 -1
  34. package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.js +1 -0
  35. package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.js.map +1 -1
  36. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
  37. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +5 -2
  38. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
  39. package/dist/backend/backend/src/controllers/request/request.controller.d.ts.map +1 -1
  40. package/dist/backend/backend/src/controllers/request/request.controller.js +5 -1
  41. package/dist/backend/backend/src/controllers/request/request.controller.js.map +1 -1
  42. package/dist/backend/backend/src/controllers/settings/settings.controller.d.ts.map +1 -1
  43. package/dist/backend/backend/src/controllers/settings/settings.controller.js +18 -2
  44. package/dist/backend/backend/src/controllers/settings/settings.controller.js.map +1 -1
  45. package/dist/backend/backend/src/controllers/signal-digest/signal-digest.controller.d.ts +26 -0
  46. package/dist/backend/backend/src/controllers/signal-digest/signal-digest.controller.d.ts.map +1 -0
  47. package/dist/backend/backend/src/controllers/signal-digest/signal-digest.controller.js +100 -0
  48. package/dist/backend/backend/src/controllers/signal-digest/signal-digest.controller.js.map +1 -0
  49. package/dist/backend/backend/src/controllers/trace/trace.controller.d.ts +47 -0
  50. package/dist/backend/backend/src/controllers/trace/trace.controller.d.ts.map +1 -0
  51. package/dist/backend/backend/src/controllers/trace/trace.controller.js +169 -0
  52. package/dist/backend/backend/src/controllers/trace/trace.controller.js.map +1 -0
  53. package/dist/backend/backend/src/index.d.ts.map +1 -1
  54. package/dist/backend/backend/src/index.js +66 -20
  55. package/dist/backend/backend/src/index.js.map +1 -1
  56. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  57. package/dist/backend/backend/src/routes/api.routes.js +14 -0
  58. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  59. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  60. package/dist/backend/backend/src/services/agent/agent-registration.service.js +6 -1
  61. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  62. package/dist/backend/backend/src/services/agent/auditor-scheduler.service.d.ts.map +1 -1
  63. package/dist/backend/backend/src/services/agent/auditor-scheduler.service.js +3 -0
  64. package/dist/backend/backend/src/services/agent/auditor-scheduler.service.js.map +1 -1
  65. package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +1 -1
  66. package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
  67. package/dist/backend/backend/src/services/agent/runtime-session-recovery.d.ts +4 -2
  68. package/dist/backend/backend/src/services/agent/runtime-session-recovery.d.ts.map +1 -1
  69. package/dist/backend/backend/src/services/agent/runtime-session-recovery.js +22 -6
  70. package/dist/backend/backend/src/services/agent/runtime-session-recovery.js.map +1 -1
  71. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js +2 -2
  72. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js.map +1 -1
  73. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
  74. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +1 -0
  75. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
  76. package/dist/backend/backend/src/services/backup/backup-archive.service.d.ts +6 -0
  77. package/dist/backend/backend/src/services/backup/backup-archive.service.d.ts.map +1 -1
  78. package/dist/backend/backend/src/services/backup/backup-archive.service.js +7 -1
  79. package/dist/backend/backend/src/services/backup/backup-archive.service.js.map +1 -1
  80. package/dist/backend/backend/src/services/boot/boot-announce.service.d.ts +1 -1
  81. package/dist/backend/backend/src/services/boot/boot-announce.service.d.ts.map +1 -1
  82. package/dist/backend/backend/src/services/canva/canva-token.service.d.ts.map +1 -1
  83. package/dist/backend/backend/src/services/canva/canva-token.service.js +5 -0
  84. package/dist/backend/backend/src/services/canva/canva-token.service.js.map +1 -1
  85. package/dist/backend/backend/src/services/chat/chat.service.d.ts +78 -2
  86. package/dist/backend/backend/src/services/chat/chat.service.d.ts.map +1 -1
  87. package/dist/backend/backend/src/services/chat/chat.service.js +210 -26
  88. package/dist/backend/backend/src/services/chat/chat.service.js.map +1 -1
  89. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +14 -3
  90. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  91. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +28 -4
  92. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  93. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts +4 -3
  94. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -1
  95. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js +7 -4
  96. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js.map +1 -1
  97. package/dist/backend/backend/src/services/decisions/decision-store.d.ts.map +1 -1
  98. package/dist/backend/backend/src/services/decisions/decision-store.js +5 -1
  99. package/dist/backend/backend/src/services/decisions/decision-store.js.map +1 -1
  100. package/dist/backend/backend/src/services/decisions/decision.wiring.d.ts +10 -1
  101. package/dist/backend/backend/src/services/decisions/decision.wiring.d.ts.map +1 -1
  102. package/dist/backend/backend/src/services/decisions/decision.wiring.js +20 -9
  103. package/dist/backend/backend/src/services/decisions/decision.wiring.js.map +1 -1
  104. package/dist/backend/backend/src/services/experiments/experiment-verdict.d.ts +88 -0
  105. package/dist/backend/backend/src/services/experiments/experiment-verdict.d.ts.map +1 -0
  106. package/dist/backend/backend/src/services/experiments/experiment-verdict.js +226 -0
  107. package/dist/backend/backend/src/services/experiments/experiment-verdict.js.map +1 -0
  108. package/dist/backend/backend/src/services/experiments/experiment.service.d.ts +350 -0
  109. package/dist/backend/backend/src/services/experiments/experiment.service.d.ts.map +1 -0
  110. package/dist/backend/backend/src/services/experiments/experiment.service.js +908 -0
  111. package/dist/backend/backend/src/services/experiments/experiment.service.js.map +1 -0
  112. package/dist/backend/backend/src/services/experiments/experiment.wiring.d.ts +88 -0
  113. package/dist/backend/backend/src/services/experiments/experiment.wiring.d.ts.map +1 -0
  114. package/dist/backend/backend/src/services/experiments/experiment.wiring.js +162 -0
  115. package/dist/backend/backend/src/services/experiments/experiment.wiring.js.map +1 -0
  116. package/dist/backend/backend/src/services/experiments/seo-ops-metric.fetcher.d.ts +67 -0
  117. package/dist/backend/backend/src/services/experiments/seo-ops-metric.fetcher.d.ts.map +1 -0
  118. package/dist/backend/backend/src/services/experiments/seo-ops-metric.fetcher.js +133 -0
  119. package/dist/backend/backend/src/services/experiments/seo-ops-metric.fetcher.js.map +1 -0
  120. package/dist/backend/backend/src/services/google/google-workspace-token.service.d.ts.map +1 -1
  121. package/dist/backend/backend/src/services/google/google-workspace-token.service.js +5 -0
  122. package/dist/backend/backend/src/services/google/google-workspace-token.service.js.map +1 -1
  123. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -1
  124. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js +7 -0
  125. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -1
  126. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts +11 -3
  127. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  128. package/dist/backend/backend/src/services/messaging/queue-processor.service.js +24 -7
  129. package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  130. package/dist/backend/backend/src/services/microsoft/microsoft-token.service.d.ts.map +1 -1
  131. package/dist/backend/backend/src/services/microsoft/microsoft-token.service.js +5 -0
  132. package/dist/backend/backend/src/services/microsoft/microsoft-token.service.js.map +1 -1
  133. package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts +7 -0
  134. package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
  135. package/dist/backend/backend/src/services/monitoring/token-usage.service.js +4 -0
  136. package/dist/backend/backend/src/services/monitoring/token-usage.service.js.map +1 -1
  137. package/dist/backend/backend/src/services/orc/orc-status-router.service.d.ts.map +1 -1
  138. package/dist/backend/backend/src/services/orc/orc-status-router.service.js +12 -3
  139. package/dist/backend/backend/src/services/orc/orc-status-router.service.js.map +1 -1
  140. package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts.map +1 -1
  141. package/dist/backend/backend/src/services/orc/reply-destination.wiring.js +16 -0
  142. package/dist/backend/backend/src/services/orc/reply-destination.wiring.js.map +1 -1
  143. package/dist/backend/backend/src/services/people/acting-for.service.d.ts +42 -5
  144. package/dist/backend/backend/src/services/people/acting-for.service.d.ts.map +1 -1
  145. package/dist/backend/backend/src/services/people/acting-for.service.js +80 -5
  146. package/dist/backend/backend/src/services/people/acting-for.service.js.map +1 -1
  147. package/dist/backend/backend/src/services/people/grant-sharing.d.ts +5 -4
  148. package/dist/backend/backend/src/services/people/grant-sharing.d.ts.map +1 -1
  149. package/dist/backend/backend/src/services/people/grant-sharing.js +12 -4
  150. package/dist/backend/backend/src/services/people/grant-sharing.js.map +1 -1
  151. package/dist/backend/backend/src/services/people/people-directory.service.d.ts +71 -13
  152. package/dist/backend/backend/src/services/people/people-directory.service.d.ts.map +1 -1
  153. package/dist/backend/backend/src/services/people/people-directory.service.js +164 -27
  154. package/dist/backend/backend/src/services/people/people-directory.service.js.map +1 -1
  155. package/dist/backend/backend/src/services/project-tickets/project-ticket.service.d.ts.map +1 -1
  156. package/dist/backend/backend/src/services/project-tickets/project-ticket.service.js +2 -0
  157. package/dist/backend/backend/src/services/project-tickets/project-ticket.service.js.map +1 -1
  158. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
  159. package/dist/backend/backend/src/services/reconciler/reconciler.service.js +15 -0
  160. package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
  161. package/dist/backend/backend/src/services/session/session-handoff.service.d.ts.map +1 -1
  162. package/dist/backend/backend/src/services/session/session-handoff.service.js +8 -5
  163. package/dist/backend/backend/src/services/session/session-handoff.service.js.map +1 -1
  164. package/dist/backend/backend/src/services/signal-digest/signal-digest-card.d.ts +75 -0
  165. package/dist/backend/backend/src/services/signal-digest/signal-digest-card.d.ts.map +1 -0
  166. package/dist/backend/backend/src/services/signal-digest/signal-digest-card.js +187 -0
  167. package/dist/backend/backend/src/services/signal-digest/signal-digest-card.js.map +1 -0
  168. package/dist/backend/backend/src/services/signal-digest/signal-digest-contract.d.ts +86 -0
  169. package/dist/backend/backend/src/services/signal-digest/signal-digest-contract.d.ts.map +1 -0
  170. package/dist/backend/backend/src/services/signal-digest/signal-digest-contract.js +307 -0
  171. package/dist/backend/backend/src/services/signal-digest/signal-digest-contract.js.map +1 -0
  172. package/dist/backend/backend/src/services/signal-digest/signal-digest-store.d.ts +85 -0
  173. package/dist/backend/backend/src/services/signal-digest/signal-digest-store.d.ts.map +1 -0
  174. package/dist/backend/backend/src/services/signal-digest/signal-digest-store.js +185 -0
  175. package/dist/backend/backend/src/services/signal-digest/signal-digest-store.js.map +1 -0
  176. package/dist/backend/backend/src/services/signal-digest/signal-digest.service.d.ts +272 -0
  177. package/dist/backend/backend/src/services/signal-digest/signal-digest.service.d.ts.map +1 -0
  178. package/dist/backend/backend/src/services/signal-digest/signal-digest.service.js +570 -0
  179. package/dist/backend/backend/src/services/signal-digest/signal-digest.service.js.map +1 -0
  180. package/dist/backend/backend/src/services/signal-digest/signal-digest.wiring.d.ts +51 -0
  181. package/dist/backend/backend/src/services/signal-digest/signal-digest.wiring.d.ts.map +1 -0
  182. package/dist/backend/backend/src/services/signal-digest/signal-digest.wiring.js +116 -0
  183. package/dist/backend/backend/src/services/signal-digest/signal-digest.wiring.js.map +1 -0
  184. package/dist/backend/backend/src/services/slack/notify-reconciliation.service.d.ts +5 -1
  185. package/dist/backend/backend/src/services/slack/notify-reconciliation.service.d.ts.map +1 -1
  186. package/dist/backend/backend/src/services/slack/notify-reconciliation.service.js +6 -2
  187. package/dist/backend/backend/src/services/slack/notify-reconciliation.service.js.map +1 -1
  188. package/dist/backend/backend/src/services/slack/slack-bot-ids.d.ts +33 -0
  189. package/dist/backend/backend/src/services/slack/slack-bot-ids.d.ts.map +1 -0
  190. package/dist/backend/backend/src/services/slack/slack-bot-ids.js +56 -0
  191. package/dist/backend/backend/src/services/slack/slack-bot-ids.js.map +1 -0
  192. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +14 -1
  193. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  194. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +30 -10
  195. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  196. package/dist/backend/backend/src/services/slack/slack-relogin-dm.service.d.ts +1 -1
  197. package/dist/backend/backend/src/services/slack/slack-relogin-dm.service.d.ts.map +1 -1
  198. package/dist/backend/backend/src/services/slack/slack.service.d.ts +31 -1
  199. package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
  200. package/dist/backend/backend/src/services/slack/slack.service.js +52 -7
  201. package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
  202. package/dist/backend/backend/src/services/system/auto-update.service.d.ts +2 -2
  203. package/dist/backend/backend/src/services/system/auto-update.service.d.ts.map +1 -1
  204. package/dist/backend/backend/src/services/task-pool/pool-storage.d.ts.map +1 -1
  205. package/dist/backend/backend/src/services/task-pool/pool-storage.js +4 -0
  206. package/dist/backend/backend/src/services/task-pool/pool-storage.js.map +1 -1
  207. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  208. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +2 -0
  209. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  210. package/dist/backend/backend/src/services/trace/trace-context.service.d.ts +195 -0
  211. package/dist/backend/backend/src/services/trace/trace-context.service.d.ts.map +1 -0
  212. package/dist/backend/backend/src/services/trace/trace-context.service.js +432 -0
  213. package/dist/backend/backend/src/services/trace/trace-context.service.js.map +1 -0
  214. package/dist/backend/backend/src/services/trace/trace-http.middleware.d.ts +42 -0
  215. package/dist/backend/backend/src/services/trace/trace-http.middleware.d.ts.map +1 -0
  216. package/dist/backend/backend/src/services/trace/trace-http.middleware.js +146 -0
  217. package/dist/backend/backend/src/services/trace/trace-http.middleware.js.map +1 -0
  218. package/dist/backend/backend/src/services/trace/trace-markers.d.ts +93 -0
  219. package/dist/backend/backend/src/services/trace/trace-markers.d.ts.map +1 -0
  220. package/dist/backend/backend/src/services/trace/trace-markers.js +162 -0
  221. package/dist/backend/backend/src/services/trace/trace-markers.js.map +1 -0
  222. package/dist/backend/backend/src/services/trace/trace-recorder.d.ts +290 -0
  223. package/dist/backend/backend/src/services/trace/trace-recorder.d.ts.map +1 -0
  224. package/dist/backend/backend/src/services/trace/trace-recorder.js +669 -0
  225. package/dist/backend/backend/src/services/trace/trace-recorder.js.map +1 -0
  226. package/dist/backend/backend/src/services/trace/trace-store.d.ts +269 -0
  227. package/dist/backend/backend/src/services/trace/trace-store.d.ts.map +1 -0
  228. package/dist/backend/backend/src/services/trace/trace-store.js +602 -0
  229. package/dist/backend/backend/src/services/trace/trace-store.js.map +1 -0
  230. package/dist/backend/backend/src/services/trace/trace.types.d.ts +118 -0
  231. package/dist/backend/backend/src/services/trace/trace.types.d.ts.map +1 -0
  232. package/dist/backend/backend/src/services/trace/trace.types.js +85 -0
  233. package/dist/backend/backend/src/services/trace/trace.types.js.map +1 -0
  234. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.boot.d.ts +1 -1
  235. package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.boot.d.ts.map +1 -1
  236. package/dist/backend/backend/src/services/v3/request.service.d.ts.map +1 -1
  237. package/dist/backend/backend/src/services/v3/request.service.js +4 -0
  238. package/dist/backend/backend/src/services/v3/request.service.js.map +1 -1
  239. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
  240. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +22 -2
  241. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
  242. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts +3 -1
  243. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -1
  244. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.js.map +1 -1
  245. package/dist/backend/backend/src/services/workflow/message-scheduler.service.d.ts.map +1 -1
  246. package/dist/backend/backend/src/services/workflow/message-scheduler.service.js +3 -0
  247. package/dist/backend/backend/src/services/workflow/message-scheduler.service.js.map +1 -1
  248. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
  249. package/dist/backend/backend/src/services/workflow/scheduler.service.js +3 -0
  250. package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
  251. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.d.ts +3 -0
  252. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.d.ts.map +1 -1
  253. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.js +7 -0
  254. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.js.map +1 -1
  255. package/dist/backend/backend/src/types/experiment.types.d.ts +155 -0
  256. package/dist/backend/backend/src/types/experiment.types.d.ts.map +1 -0
  257. package/dist/backend/backend/src/types/experiment.types.js +32 -0
  258. package/dist/backend/backend/src/types/experiment.types.js.map +1 -0
  259. package/dist/backend/backend/src/types/messaging.types.d.ts +6 -0
  260. package/dist/backend/backend/src/types/messaging.types.d.ts.map +1 -1
  261. package/dist/backend/backend/src/types/messaging.types.js.map +1 -1
  262. package/dist/backend/backend/src/types/signal-digest.types.d.ts +185 -0
  263. package/dist/backend/backend/src/types/signal-digest.types.d.ts.map +1 -0
  264. package/dist/backend/backend/src/types/signal-digest.types.js +21 -0
  265. package/dist/backend/backend/src/types/signal-digest.types.js.map +1 -0
  266. package/dist/backend/backend/src/types/v2/request.types.d.ts +4 -0
  267. package/dist/backend/backend/src/types/v2/request.types.d.ts.map +1 -1
  268. package/dist/backend/backend/src/types/v2/request.types.js.map +1 -1
  269. package/dist/backend/backend/src/types/v2/work-item.types.d.ts +4 -0
  270. package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  271. package/dist/backend/backend/src/types/v2/work-item.types.js +1 -0
  272. package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
  273. package/dist/backend/backend/src/utils/security.d.ts +2 -0
  274. package/dist/backend/backend/src/utils/security.d.ts.map +1 -1
  275. package/dist/backend/backend/src/utils/security.js +3 -1
  276. package/dist/backend/backend/src/utils/security.js.map +1 -1
  277. package/dist/backend/backend/src/websocket/chat.gateway.d.ts +9 -0
  278. package/dist/backend/backend/src/websocket/chat.gateway.d.ts.map +1 -1
  279. package/dist/backend/backend/src/websocket/chat.gateway.js +26 -0
  280. package/dist/backend/backend/src/websocket/chat.gateway.js.map +1 -1
  281. package/dist/backend/build-info.json +2 -2
  282. package/dist/cli/backend/src/constants.d.ts +191 -1
  283. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  284. package/dist/cli/backend/src/constants.js +194 -1
  285. package/dist/cli/backend/src/constants.js.map +1 -1
  286. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  287. package/dist/cli/backend/src/services/agent/agent-registration.service.js +6 -1
  288. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
  289. package/dist/cli/backend/src/services/agent/auditor-scheduler.service.d.ts.map +1 -1
  290. package/dist/cli/backend/src/services/agent/auditor-scheduler.service.js +3 -0
  291. package/dist/cli/backend/src/services/agent/auditor-scheduler.service.js.map +1 -1
  292. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +1 -1
  293. package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
  294. package/dist/cli/backend/src/services/agent/runtime-session-recovery.d.ts +4 -2
  295. package/dist/cli/backend/src/services/agent/runtime-session-recovery.d.ts.map +1 -1
  296. package/dist/cli/backend/src/services/agent/runtime-session-recovery.js +22 -6
  297. package/dist/cli/backend/src/services/agent/runtime-session-recovery.js.map +1 -1
  298. package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.js +2 -2
  299. package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.js.map +1 -1
  300. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
  301. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js +1 -0
  302. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
  303. package/dist/cli/backend/src/services/backup/backup-archive.service.d.ts +6 -0
  304. package/dist/cli/backend/src/services/backup/backup-archive.service.d.ts.map +1 -1
  305. package/dist/cli/backend/src/services/backup/backup-archive.service.js +7 -1
  306. package/dist/cli/backend/src/services/backup/backup-archive.service.js.map +1 -1
  307. package/dist/cli/backend/src/services/chat/chat.service.d.ts +185 -0
  308. package/dist/cli/backend/src/services/chat/chat.service.d.ts.map +1 -0
  309. package/dist/cli/backend/src/services/chat/chat.service.js +558 -0
  310. package/dist/cli/backend/src/services/chat/chat.service.js.map +1 -0
  311. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +14 -3
  312. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  313. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +28 -4
  314. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  315. package/dist/cli/backend/src/services/chat-v2/chat-v2.service.d.ts +4 -3
  316. package/dist/cli/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -1
  317. package/dist/cli/backend/src/services/chat-v2/chat-v2.service.js +7 -4
  318. package/dist/cli/backend/src/services/chat-v2/chat-v2.service.js.map +1 -1
  319. package/dist/cli/backend/src/services/decisions/decision-store.d.ts.map +1 -1
  320. package/dist/cli/backend/src/services/decisions/decision-store.js +5 -1
  321. package/dist/cli/backend/src/services/decisions/decision-store.js.map +1 -1
  322. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -1
  323. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js +7 -0
  324. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -1
  325. package/dist/cli/backend/src/services/messaging/queue-processor.service.d.ts +11 -3
  326. package/dist/cli/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  327. package/dist/cli/backend/src/services/messaging/queue-processor.service.js +24 -7
  328. package/dist/cli/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  329. package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts +7 -0
  330. package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
  331. package/dist/cli/backend/src/services/monitoring/token-usage.service.js +4 -0
  332. package/dist/cli/backend/src/services/monitoring/token-usage.service.js.map +1 -1
  333. package/dist/cli/backend/src/services/people/acting-for.service.d.ts +42 -5
  334. package/dist/cli/backend/src/services/people/acting-for.service.d.ts.map +1 -1
  335. package/dist/cli/backend/src/services/people/acting-for.service.js +80 -5
  336. package/dist/cli/backend/src/services/people/acting-for.service.js.map +1 -1
  337. package/dist/cli/backend/src/services/people/people-directory.service.d.ts +71 -13
  338. package/dist/cli/backend/src/services/people/people-directory.service.d.ts.map +1 -1
  339. package/dist/cli/backend/src/services/people/people-directory.service.js +164 -27
  340. package/dist/cli/backend/src/services/people/people-directory.service.js.map +1 -1
  341. package/dist/cli/backend/src/services/project-tickets/project-ticket.service.d.ts.map +1 -1
  342. package/dist/cli/backend/src/services/project-tickets/project-ticket.service.js +2 -0
  343. package/dist/cli/backend/src/services/project-tickets/project-ticket.service.js.map +1 -1
  344. package/dist/cli/backend/src/services/session/session-handoff.service.d.ts.map +1 -1
  345. package/dist/cli/backend/src/services/session/session-handoff.service.js +8 -5
  346. package/dist/cli/backend/src/services/session/session-handoff.service.js.map +1 -1
  347. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts +14 -1
  348. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  349. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js +30 -10
  350. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  351. package/dist/cli/backend/src/services/slack/slack.service.d.ts +31 -1
  352. package/dist/cli/backend/src/services/slack/slack.service.d.ts.map +1 -1
  353. package/dist/cli/backend/src/services/slack/slack.service.js +52 -7
  354. package/dist/cli/backend/src/services/slack/slack.service.js.map +1 -1
  355. package/dist/cli/backend/src/services/task-pool/pool-storage.d.ts.map +1 -1
  356. package/dist/cli/backend/src/services/task-pool/pool-storage.js +4 -0
  357. package/dist/cli/backend/src/services/task-pool/pool-storage.js.map +1 -1
  358. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  359. package/dist/cli/backend/src/services/task-pool/task-pool.service.js +2 -0
  360. package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  361. package/dist/cli/backend/src/services/trace/trace-context.service.d.ts +195 -0
  362. package/dist/cli/backend/src/services/trace/trace-context.service.d.ts.map +1 -0
  363. package/dist/cli/backend/src/services/trace/trace-context.service.js +432 -0
  364. package/dist/cli/backend/src/services/trace/trace-context.service.js.map +1 -0
  365. package/dist/cli/backend/src/services/trace/trace-markers.d.ts +93 -0
  366. package/dist/cli/backend/src/services/trace/trace-markers.d.ts.map +1 -0
  367. package/dist/cli/backend/src/services/trace/trace-markers.js +162 -0
  368. package/dist/cli/backend/src/services/trace/trace-markers.js.map +1 -0
  369. package/dist/cli/backend/src/services/trace/trace-recorder.d.ts +290 -0
  370. package/dist/cli/backend/src/services/trace/trace-recorder.d.ts.map +1 -0
  371. package/dist/cli/backend/src/services/trace/trace-recorder.js +669 -0
  372. package/dist/cli/backend/src/services/trace/trace-recorder.js.map +1 -0
  373. package/dist/cli/backend/src/services/trace/trace-store.d.ts +269 -0
  374. package/dist/cli/backend/src/services/trace/trace-store.d.ts.map +1 -0
  375. package/dist/cli/backend/src/services/trace/trace-store.js +602 -0
  376. package/dist/cli/backend/src/services/trace/trace-store.js.map +1 -0
  377. package/dist/cli/backend/src/services/trace/trace.types.d.ts +118 -0
  378. package/dist/cli/backend/src/services/trace/trace.types.d.ts.map +1 -0
  379. package/dist/cli/backend/src/services/trace/trace.types.js +85 -0
  380. package/dist/cli/backend/src/services/trace/trace.types.js.map +1 -0
  381. package/dist/cli/backend/src/services/v3/request.service.d.ts.map +1 -1
  382. package/dist/cli/backend/src/services/v3/request.service.js +4 -0
  383. package/dist/cli/backend/src/services/v3/request.service.js.map +1 -1
  384. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.d.ts +3 -1
  385. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -1
  386. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.js.map +1 -1
  387. package/dist/cli/backend/src/types/messaging.types.d.ts +6 -0
  388. package/dist/cli/backend/src/types/messaging.types.d.ts.map +1 -1
  389. package/dist/cli/backend/src/types/messaging.types.js.map +1 -1
  390. package/dist/cli/backend/src/types/v2/request.types.d.ts +4 -0
  391. package/dist/cli/backend/src/types/v2/request.types.d.ts.map +1 -1
  392. package/dist/cli/backend/src/types/v2/request.types.js.map +1 -1
  393. package/dist/cli/backend/src/types/v2/work-item.types.d.ts +4 -0
  394. package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  395. package/dist/cli/backend/src/types/v2/work-item.types.js +1 -0
  396. package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
  397. package/dist/cli/backend/src/utils/security.d.ts +196 -0
  398. package/dist/cli/backend/src/utils/security.d.ts.map +1 -0
  399. package/dist/cli/backend/src/utils/security.js +538 -0
  400. package/dist/cli/backend/src/utils/security.js.map +1 -0
  401. package/dist/cli/backend/src/websocket/chat.gateway.d.ts +9 -0
  402. package/dist/cli/backend/src/websocket/chat.gateway.d.ts.map +1 -1
  403. package/dist/cli/backend/src/websocket/chat.gateway.js +26 -0
  404. package/dist/cli/backend/src/websocket/chat.gateway.js.map +1 -1
  405. package/frontend/dist/assets/{index-465d1f8f.js → index-800118ca.js} +274 -274
  406. package/frontend/dist/index.html +1 -1
  407. package/package.json +1 -1
@@ -0,0 +1,173 @@
1
+ #!/bin/bash
2
+ # =============================================================================
3
+ # signal-digest — a site's daily signals → 3–5 actions → one owner card (#987)
4
+ #
5
+ # collect GA4 + Search Console + the site inbox + broken pages / JS errors,
6
+ # minus what was already tried; prints JSON with draft actions.
7
+ # Reports each source's status to Crewly, which tells the owner
8
+ # once when a source starts or stops failing.
9
+ # propose send 3–5 actions; the owner gets one Slack card with Do / Skip
10
+ # per action (Do opens an experiment ticket in the site's project).
11
+ # schedule print the daily cron task for the orchestrator to create.
12
+ #
13
+ # Usage:
14
+ # bash execute.sh collect --config site.signal.json [--days 7]
15
+ # bash execute.sh propose --config site.signal.json --actions actions.json
16
+ # bash execute.sh schedule --config site.signal.json [--cron "0 8 * * *"] [--timezone America/New_York]
17
+ # bash execute.sh '{"command":"collect","config":"site.signal.json"}'
18
+ # =============================================================================
19
+ set -euo pipefail
20
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
21
+ source "${SCRIPT_DIR}/../_common/lib.sh"
22
+
23
+ DEFAULT_CRON="0 8 * * *"
24
+ DEFAULT_TIMEZONE="America/New_York"
25
+
26
+ print_usage() {
27
+ cat <<'EOF_USAGE'
28
+ Usage:
29
+ bash execute.sh collect --config site.signal.json [--days 7]
30
+ bash execute.sh propose --config site.signal.json --actions actions.json (file, or inline JSON)
31
+ bash execute.sh schedule --config site.signal.json [--cron "0 8 * * *"] [--timezone America/New_York]
32
+ bash execute.sh '{"command":"collect","config":"site.signal.json"}'
33
+
34
+ The config is the site's seo-ops config plus a "signalDigest" section
35
+ (see signal-digest.config.example.json).
36
+ EOF_USAGE
37
+ }
38
+
39
+ COMMAND=""; CONFIG=""; DAYS=""; ACTIONS=""; CRON=""; TIMEZONE=""
40
+ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
41
+ INPUT=$(read_json_input "$1")
42
+ shift || true
43
+ COMMAND=$(printf '%s' "$INPUT" | jq -r '.command // empty')
44
+ CONFIG=$(printf '%s' "$INPUT" | jq -r '.config // empty')
45
+ DAYS=$(printf '%s' "$INPUT" | jq -r '.days // empty')
46
+ ACTIONS=$(printf '%s' "$INPUT" | jq -r 'if .actions == null then empty elif (.actions | type) == "string" then .actions else (.actions | tojson) end')
47
+ CRON=$(printf '%s' "$INPUT" | jq -r '.cron // empty')
48
+ TIMEZONE=$(printf '%s' "$INPUT" | jq -r '.timezone // empty')
49
+ elif [[ $# -gt 0 && ${1:0:1} != '-' ]]; then
50
+ COMMAND="$1"
51
+ shift
52
+ fi
53
+ while [[ $# -gt 0 ]]; do
54
+ case "$1" in
55
+ --config|-c) [ $# -ge 2 ] || error_exit "--config requires a value"; CONFIG="$2"; shift 2 ;;
56
+ --days) [ $# -ge 2 ] || error_exit "--days requires a value"; DAYS="$2"; shift 2 ;;
57
+ --actions) [ $# -ge 2 ] || error_exit "--actions requires a value"; ACTIONS="$2"; shift 2 ;;
58
+ --cron) [ $# -ge 2 ] || error_exit "--cron requires a value"; CRON="$2"; shift 2 ;;
59
+ --timezone) [ $# -ge 2 ] || error_exit "--timezone requires a value"; TIMEZONE="$2"; shift 2 ;;
60
+ --help|-h) print_usage; exit 0 ;;
61
+ *) error_exit "Unknown option: $1" ;;
62
+ esac
63
+ done
64
+ [ -n "$COMMAND" ] || { print_usage; exit 1; }
65
+ require_param "config (--config)" "$CONFIG"
66
+ [ -f "$CONFIG" ] || error_exit "Config file not found: $CONFIG"
67
+ jq -e 'type == "object"' "$CONFIG" >/dev/null 2>&1 || error_exit "Config file $CONFIG is not a JSON object"
68
+
69
+ # The site name: signalDigest.site, else the host of siteUrl.
70
+ SITE=$(jq -r '.signalDigest.site // ((.siteUrl // "") | sub("^[a-zA-Z]+://"; "") | sub("/.*$"; ""))' "$CONFIG")
71
+ [ -n "$SITE" ] || error_exit "Config needs signalDigest.site (or siteUrl) to name the site"
72
+ PROJECT=$(jq -r '.signalDigest.project // empty' "$CONFIG")
73
+ uri() { jq -rn --arg v "$1" '$v|@uri'; }
74
+
75
+ # api_call may print a one-line warning to stderr; the answer is the last line.
76
+ call() {
77
+ local out
78
+ out=$(api_call "$@" 2>&1) || { printf '%s\n' "$out" | tail -n 1; return 1; }
79
+ printf '%s\n' "$out" | tail -n 1
80
+ }
81
+
82
+ case "$COMMAND" in
83
+ collect)
84
+ command -v python3 >/dev/null 2>&1 || error_exit "python3 (>= 3.8) is required"
85
+ WORK=$(mktemp -d)
86
+ trap 'rm -rf "$WORK"' EXIT
87
+ ARGS=(collect --config "$CONFIG")
88
+ [ -n "$DAYS" ] && ARGS+=(--days "$DAYS")
89
+ # History: what the owner already chose Do / Skip on for this site.
90
+ if HISTORY=$(call GET "/signal-digests/history?site=$(uri "$SITE")"); then
91
+ printf '%s' "$HISTORY" > "$WORK/history.json"
92
+ ARGS+=(--history "$WORK/history.json")
93
+ else
94
+ echo "{\"warning\":\"could not read the site history from Crewly; already-decided actions are not filtered out\"}" >&2
95
+ fi
96
+ # Experiment cards (#986): drafts their query / page already covers are dropped.
97
+ if EXPERIMENTS=$(call GET "/experiments"); then
98
+ printf '%s' "$EXPERIMENTS" > "$WORK/experiments.json"
99
+ ARGS+=(--experiments "$WORK/experiments.json")
100
+ else
101
+ echo "{\"warning\":\"could not read the experiment cards from Crewly; drafts they cover are not filtered out\"}" >&2
102
+ fi
103
+ # Inbox: the site's inbound requests (signalDigest.inbox.query), via Gmail.
104
+ INBOX_QUERY=$(jq -r '.signalDigest.inbox.query // empty' "$CONFIG")
105
+ if [ -n "$INBOX_QUERY" ]; then
106
+ INBOX_ACCOUNT=$(jq -r '.signalDigest.inbox.account // empty' "$CONFIG")
107
+ INBOX_MAX=$(jq -r '.signalDigest.inbox.max // 20' "$CONFIG")
108
+ [ -n "$INBOX_ACCOUNT" ] && export CREWLY_GOOGLE_ACCOUNT="$INBOX_ACCOUNT"
109
+ if INBOX=$(call GET "/google/gmail/search?q=$(uri "$INBOX_QUERY")&max=$(uri "$INBOX_MAX")"); then
110
+ printf '%s' "$INBOX" | jq -c '{query: .data.query, count: .data.count, messages: [.data.messages[]? | {from, subject, date, snippet}]}' > "$WORK/inbox.json"
111
+ else
112
+ printf '%s' "$INBOX" | jq -c '{success: false, reason: (.details.error // .error // "unknown"), message: (.details.message // .message // "")}' > "$WORK/inbox.json" 2>/dev/null \
113
+ || jq -n '{success: false, reason: "unreadable answer"}' > "$WORK/inbox.json"
114
+ fi
115
+ ARGS+=(--inbox "$WORK/inbox.json")
116
+ fi
117
+ set +e
118
+ RESULT=$(python3 "$SCRIPT_DIR/signal_digest.py" "${ARGS[@]}")
119
+ CODE=$?
120
+ set -e
121
+ [ -n "$RESULT" ] || exit "$CODE"
122
+ # Source status → Crewly. The owner hears once when a source starts or
123
+ # stops failing; nothing is posted on the days nothing changes.
124
+ REPORT='{"sent":false}'
125
+ SOURCES=$(printf '%s' "$RESULT" | jq -c '.sources // empty' 2>/dev/null || true)
126
+ if [ -n "$SOURCES" ]; then
127
+ BODY=$(jq -cn --arg site "$SITE" --argjson sources "$SOURCES" '{site: $site, sources: $sources}')
128
+ if ANSWER=$(call POST "/signal-digests/sources" "$BODY"); then
129
+ REPORT=$(printf '%s' "$ANSWER" | jq -c '{sent: true, started: (.data.started // []), stopped: (.data.stopped // []), ownerTold: (.data.notified // false)}' 2>/dev/null || echo '{"sent":true}')
130
+ else
131
+ echo "{\"warning\":\"could not report the source status to Crewly; the owner is not told about source failures\"}" >&2
132
+ fi
133
+ fi
134
+ printf '%s' "$RESULT" | jq --argjson report "$REPORT" '. + {sourceReport: $report}' 2>/dev/null || printf '%s\n' "$RESULT"
135
+ exit "$CODE"
136
+ ;;
137
+
138
+ propose)
139
+ require_param "actions (--actions)" "$ACTIONS"
140
+ if [ -f "$ACTIONS" ]; then ACTIONS_JSON=$(cat "$ACTIONS"); else ACTIONS_JSON="$ACTIONS"; fi
141
+ ITEMS=$(printf '%s' "$ACTIONS_JSON" | jq -c 'if type == "array" then . elif type == "object" and (.items | type) == "array" then .items elif type == "object" and (.actions | type) == "array" then .actions else error("expected an array of actions") end' 2>/dev/null) \
142
+ || error_exit "--actions must be a JSON array of actions (or {\"items\": [...]}), as a file or inline"
143
+ # The absolute config lets a Do create the action's experiment card (#986).
144
+ CONFIG_ABS="$(cd "$(dirname "$CONFIG")" && pwd)/$(basename "$CONFIG")"
145
+ BODY=$(jq -cn --arg site "$SITE" --arg project "$PROJECT" --arg config "$CONFIG_ABS" --argjson items "$ITEMS" \
146
+ '{site: $site, config: $config, items: [$items[] | {key, source, signal, proposal, expectedEffect, effort}
147
+ + (if .metric then {metric} else {} end) + (if .experiment then {experiment} else {} end)]}
148
+ + (if $project != "" then {project: $project} else {} end)')
149
+ if ! RESPONSE=$(call POST "/signal-digests" "$BODY"); then
150
+ printf '%s' "$RESPONSE" | jq -c '{success: false, error: (.details.error // .error // .details // "unknown")}' 2>/dev/null || jq -n --arg r "$RESPONSE" '{success: false, error: $r}'
151
+ exit 1
152
+ fi
153
+ printf '%s' "$RESPONSE" | jq -c '{success: true, digestId: .data.id, site: .data.site, actions: (.data.items | length)}
154
+ + (if .data.card then {card: "posted"} else {card: "not posted", postError: .data.postError} end)'
155
+ ;;
156
+
157
+ schedule)
158
+ # Cron tasks are created by the orchestrator (or the owner), not by a lead:
159
+ # print the exact create-cron call to hand over.
160
+ [ -n "${CREWLY_SESSION_NAME:-}" ] || error_exit "CREWLY_SESSION_NAME is not set: run this from your agent session"
161
+ TEAM_ID=$(resolve_team_id) || error_exit "Could not find the team of ${CREWLY_SESSION_NAME}"
162
+ CONFIG_ABS="$(cd "$(dirname "$CONFIG")" && pwd)/$(basename "$CONFIG")"
163
+ TASK="Daily signal digest for ${SITE}: run \`bash ${SCRIPT_DIR}/execute.sh collect --config ${CONFIG_ABS}\`, pick the 3-5 actions most worth the owner's tap (rewrite the drafts as needed), then run \`bash ${SCRIPT_DIR}/execute.sh propose --config ${CONFIG_ABS} --actions <file>\`. If no source could be examined, stop there: the owner is told once when a source starts or stops failing, so post nothing about it."
164
+ CRON_JSON=$(jq -cn --arg cron "${CRON:-$DEFAULT_CRON}" --arg tz "${TIMEZONE:-$DEFAULT_TIMEZONE}" --arg agent "$CREWLY_SESSION_NAME" --arg team "$TEAM_ID" --arg task "$TASK" \
165
+ '{cronExpression: $cron, timezone: $tz, targetAgent: $agent, targetTeamId: $team, taskDescription: $task}')
166
+ jq -cn --argjson cron "$CRON_JSON" '{success: true, createCron: $cron,
167
+ next: "Cron tasks are created by the orchestrator: send it this createCron object and ask it to run create-cron with it (or the owner can add it under Schedules)."}'
168
+ ;;
169
+
170
+ *)
171
+ error_exit "Unknown command: ${COMMAND} (collect | propose | schedule)"
172
+ ;;
173
+ esac
@@ -0,0 +1,123 @@
1
+ #!/bin/bash
2
+ # Tests for signal-digest — run with: bash execute.test.sh
3
+ # Python HTTP stub as the backend; asserts the requests the skill sends and
4
+ # the JSON it prints. Google is never called (no GSC / GA4 in the configs).
5
+ set -u
6
+ HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
+ EXEC="$HERE/execute.sh"
8
+ PASS=0; FAIL=0
9
+ check() {
10
+ local name="$1"; local got="$2"; local want="$3"
11
+ if [ "$got" = "$want" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $name"; echo " want: $want"; echo " got: $got"; fi
12
+ }
13
+
14
+ PORT=18841
15
+ TMP="$(mktemp -d)"
16
+ STUB_LOG="$TMP/requests.jsonl"; : > "$STUB_LOG"; export STUB_LOG; export STUB_PORT="$PORT"
17
+ python3 -u <<'PY' >/dev/null 2>&1 &
18
+ from http.server import BaseHTTPRequestHandler, HTTPServer
19
+ import json, os
20
+ LOG = os.environ['STUB_LOG']; PORT = int(os.environ['STUB_PORT'])
21
+ class H(BaseHTTPRequestHandler):
22
+ def _reply(self, method, data=None):
23
+ with open(LOG, 'a') as f:
24
+ f.write(json.dumps({'method': method, 'path': self.path, 'body': data, 'account': self.headers.get('X-Google-Account')}) + '\n')
25
+ path = self.path.split('?')[0]
26
+ status, out = 200, {}
27
+ if path == '/api/signal-digests/history':
28
+ out = {'site': 'visa.careerengine.us', 'entries': [{'key': 'errors:broken:/gone', 'status': 'skip', 'at': '2026-10-01T00:00:00Z', 'digestId': 'SD-1'}]}
29
+ elif path == '/api/experiments':
30
+ out = [{'id': 'EXP-1', 'status': 'running', 'metric': {'query': 'opt extension'}, 'updatedAt': '2026-10-01T00:00:00Z'}]
31
+ elif path == '/api/signal-digests/sources':
32
+ out = {'site': data['site'], 'sources': [], 'started': [k for k, v in data['sources'].items() if v.startswith('error')], 'stopped': [], 'notified': True}
33
+ elif path == '/api/google/gmail/search':
34
+ out = {'query': 'to:visa', 'count': 1, 'messages': [{'id': 'm1', 'from': 'a@b.c', 'subject': 'H1B fee?', 'date': 'd', 'snippet': 'how much'}]}
35
+ elif path == '/api/signal-digests' and method == 'POST':
36
+ if any(i.get('key') == 'tried' for i in (data or {}).get('items', [])):
37
+ status = 409
38
+ body = {'success': False, 'error': 'These actions were already decided: "tried"'}
39
+ self.send_response(status); self.send_header('Content-Type', 'application/json'); self.end_headers()
40
+ self.wfile.write(json.dumps(body).encode()); return
41
+ out = {'id': 'SD-7', 'site': data['site'], 'items': data['items'], 'card': {'slackChannelId': 'C1', 'messageTs': '1.0'}}
42
+ status = 201
43
+ self.send_response(status); self.send_header('Content-Type', 'application/json'); self.end_headers()
44
+ self.wfile.write(json.dumps({'success': True, 'data': out}).encode())
45
+ def _body(self):
46
+ n = int(self.headers.get('content-length', '0')); body = self.rfile.read(n).decode() if n else ''
47
+ return json.loads(body or '{}')
48
+ def do_GET(self): self._reply('GET')
49
+ def do_POST(self): self._reply('POST', self._body())
50
+ def log_message(self, *a, **k): pass
51
+ HTTPServer(('127.0.0.1', PORT), H).serve_forever()
52
+ PY
53
+ STUB_PID=$!
54
+ disown "$STUB_PID" 2>/dev/null || true
55
+ trap 'kill "$STUB_PID" >/dev/null 2>&1; rm -rf "$TMP"' EXIT
56
+ for i in $(seq 1 30); do curl -s -o /dev/null -m 0.2 "http://127.0.0.1:${PORT}/" 2>/dev/null && break; sleep 0.1; done
57
+
58
+ CFG="$TMP/ce.signal.json"
59
+ cat > "$CFG" <<'EOF'
60
+ {"siteUrl":"https://visa.careerengine.us","signalDigest":{"project":"CE site","inbox":{"query":"to:visa@careerengine.us newer_than:1d","account":"site@careerengine.us","max":5},"errors":{"checkSitemap":false}}}
61
+ EOF
62
+ BARE="$TMP/bare.json"
63
+ echo '{"siteUrl":"https://example.com","signalDigest":{"errors":{"checkSitemap":false}}}' > "$BARE"
64
+
65
+ run() { CREWLY_SESSION_NAME=tl-owen CREWLY_API_URL="http://127.0.0.1:${PORT}" HOME="$TMP" bash "$EXEC" "$@" 2>/dev/null; }
66
+ run_err() { CREWLY_SESSION_NAME=tl-owen CREWLY_API_URL="http://127.0.0.1:${PORT}" HOME="$TMP" bash "$EXEC" "$@" 2>&1 >/dev/null; }
67
+ # Skills fire a background POST /api/heartbeat on start: ignore it everywhere.
68
+ calls() { jq -c 'select(.path != "/api/heartbeat")' "$STUB_LOG"; }
69
+ last() { calls | tail -n 1 | jq -c "$1"; }
70
+ req() { calls | jq -c "select(.path | startswith(\"$1\")) | $2" | tail -n 1; }
71
+
72
+ # --- collect: history + inbox fetched, passed to the Python side
73
+ OUT=$(run collect --config "$CFG")
74
+ check "collect: exit 0 with the inbox as a source" "$(printf '%s' "$OUT" | jq -c '.sources')" '{"ga4":"not configured","gsc":"not configured","inbox":"ok","errors":"not configured"}'
75
+ check "collect: site and project from config" "$(printf '%s' "$OUT" | jq -c '[.site,.project]')" '["visa.careerengine.us","CE site"]'
76
+ check "collect: inbox messages" "$(printf '%s' "$OUT" | jq -c '.inbox.messages')" '[{"from":"a@b.c","subject":"H1B fee?","date":"d","snippet":"how much"}]'
77
+ check "collect: history asked for this site" "$(req /api/signal-digests/history '.path')" '"/api/signal-digests/history?site=visa.careerengine.us"'
78
+ check "collect: experiment cards asked for" "$(req /api/experiments '.path')" '"/api/experiments"'
79
+ check "collect: gmail query, max and account" "$(req /api/google/gmail/search '[.path,.account]')" '["/api/google/gmail/search?q=to%3Avisa%40careerengine.us%20newer_than%3A1d&max=5","site@careerengine.us"]'
80
+ check "collect: source status reported for the site" "$(req /api/signal-digests/sources '.body')" '{"site":"visa.careerengine.us","sources":{"ga4":"not configured","gsc":"not configured","inbox":"ok","errors":"not configured"}}'
81
+ check "collect: source report in the output" "$(printf '%s' "$OUT" | jq -c '.sourceReport')" '{"sent":true,"started":[],"stopped":[],"ownerTold":true}'
82
+
83
+ : > "$STUB_LOG"
84
+ run collect --config "$BARE" >/dev/null; CODE=$?
85
+ check "collect: nothing examinable exits 1" "$CODE" "1"
86
+ check "collect: still reports the source status" "$(req /api/signal-digests/sources '.body.site')" '"example.com"'
87
+ check "collect: no inbox query, no gmail call" "$(req /api/google '.path')" ''
88
+
89
+ # --- propose
90
+ cat > "$TMP/actions.json" <<'EOF'
91
+ [{"key":"gsc:low-ctr:a","source":"gsc","signal":"s1","proposal":"p1","expectedEffect":"e1","effort":"S","metric":"m1","score":99,"experiment":{"source":"gsc","measure":"ctr","query":"a"}},
92
+ {"key":"errors:broken:/x","source":"errors","signal":"s2","proposal":"p2","expectedEffect":"e2","effort":"S"},
93
+ {"key":"ga4:drop","source":"ga4","signal":"s3","proposal":"p3","expectedEffect":"e3","effort":"M"}]
94
+ EOF
95
+ OUT=$(run propose --config "$CFG" --actions "$TMP/actions.json")
96
+ check "propose: output" "$OUT" '{"success":true,"digestId":"SD-7","site":"visa.careerengine.us","actions":3,"card":"posted"}'
97
+ check "propose: body (site, project, no score, experiment kept)" "$(last '.body | [.site, .project, (.items|length), .items[0]]')" '["visa.careerengine.us","CE site",3,{"key":"gsc:low-ctr:a","source":"gsc","signal":"s1","proposal":"p1","expectedEffect":"e1","effort":"S","metric":"m1","experiment":{"source":"gsc","measure":"ctr","query":"a"}}]'
98
+ check "propose: absolute config path" "$(last '.body.config')" "\"$CFG\""
99
+ check "propose: no metric key when absent" "$(last '.body.items[1] | has("metric")')" 'false'
100
+ run propose --config "$BARE" --actions '{"items":[{"key":"k1","source":"gsc","signal":"s","proposal":"p","expectedEffect":"e","effort":"S"},{"key":"k2","source":"gsc","signal":"s","proposal":"p","expectedEffect":"e","effort":"S"},{"key":"k3","source":"gsc","signal":"s","proposal":"p","expectedEffect":"e","effort":"S"}]}' >/dev/null
101
+ check "propose: inline {items}, no project, site from siteUrl" "$(last '.body | [.site, has("project"), (.items|length)]')" '["example.com",false,3]'
102
+ OUT=$(run propose --config "$CFG" --actions '[{"key":"tried","source":"gsc","signal":"s","proposal":"p","expectedEffect":"e","effort":"S"}]' || true)
103
+ check "propose: a 409 is passed on" "$(printf '%s' "$OUT" | jq -r '.success')" "false"
104
+ check "propose: bad actions" "$(run_err propose --config "$CFG" --actions '{"nope":1}' | jq -r .error | cut -c1-25)" "--actions must be a JSON "
105
+
106
+ # --- schedule: prints the create-cron object (it never creates the cron itself)
107
+ mkdir -p "$TMP/.crewly/teams/team-ce"
108
+ echo '{"members":[{"sessionName":"tl-owen"}]}' > "$TMP/.crewly/teams/team-ce/config.json"
109
+ : > "$STUB_LOG"
110
+ OUT=$(run schedule --config "$CFG" --cron "30 7 * * 1-5")
111
+ check "schedule: cron object" "$(printf '%s' "$OUT" | jq -c '.createCron | [.cronExpression,.timezone,.targetAgent,.targetTeamId]')" '["30 7 * * 1-5","America/New_York","tl-owen","team-ce"]'
112
+ check "schedule: task names the site and both steps" "$(printf '%s' "$OUT" | jq -r '.createCron.taskDescription | test("visa.careerengine.us") and test("collect --config /") and test("propose --config")')" "true"
113
+ check "schedule: no API call" "$(calls | wc -l | tr -d ' ')" "0"
114
+ check "schedule: no daily team-channel post about failing sources" "$(printf '%s' "$OUT" | jq -r '.createCron.taskDescription | test("team channel")')" "false"
115
+
116
+ # --- argument errors
117
+ check "config required" "$(run_err collect | jq -r .error)" "Missing required parameter: config (--config)"
118
+ check "unknown command" "$(run_err frobnicate --config "$CFG" | jq -r .error)" "Unknown command: frobnicate (collect | propose | schedule)"
119
+ OUT=$(run '{"command":"propose","config":"'"$CFG"'","actions":[{"key":"k1","source":"gsc","signal":"s","proposal":"p","expectedEffect":"e","effort":"S"},{"key":"k2","source":"gsc","signal":"s","proposal":"p","expectedEffect":"e","effort":"S"},{"key":"k3","source":"gsc","signal":"s","proposal":"p","expectedEffect":"e","effort":"S"}]}')
120
+ check "json input: actions as an array" "$(printf '%s' "$OUT" | jq -r .digestId)" "SD-7"
121
+
122
+ echo "signal-digest: $PASS passed, $FAIL failed"
123
+ [ "$FAIL" -eq 0 ]
@@ -0,0 +1,23 @@
1
+ {
2
+ "siteUrl": "https://visa.careerengine.us",
3
+ "gscProperty": "sc-domain:visa.careerengine.us",
4
+ "ga4PropertyId": "123456789",
5
+ "ga4HostName": "visa.careerengine.us",
6
+ "credentialsPath": "SEO_OPS_GOOGLE_CREDENTIALS",
7
+ "sitemapUrl": "https://visa.careerengine.us/sitemap.xml",
8
+ "exclusions": {
9
+ "queries": ["^site:", "careerengine"],
10
+ "pages": ["/admin"]
11
+ },
12
+ "urlNormalize": { "stripScheme": true, "localePrefixes": ["en", "zh"] },
13
+ "signalDigest": {
14
+ "site": "visa.careerengine.us",
15
+ "project": "CE site",
16
+ "days": 7,
17
+ "ga4": { "conversionEvents": ["generate_lead", "form_submit"] },
18
+ "inbox": { "query": "to:visa@careerengine.us newer_than:1d", "max": 20 },
19
+ "errors": { "checkSitemap": true, "maxUrls": 60, "url": "https://visa.careerengine.us/api/client-errors?days=1" },
20
+ "experimentLog": "~/.crewly/wiki/ce-site/experiment-log.md",
21
+ "thresholds": { "ga4DropPct": 20, "ga4MinPrevSessions": 50, "ga4MinPrevKeyEvents": 5 }
22
+ }
23
+ }