@cohortapp/agent-sdk 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (731) hide show
  1. package/.claude/commands/init-agent.md +104 -0
  2. package/.claude/commands/init-maestro.md +1187 -0
  3. package/.claude/settings.json +161 -0
  4. package/.env.example +216 -0
  5. package/README.md +632 -0
  6. package/agents/browser-operator/agent.md +52 -0
  7. package/agents/calendar-ops/agent.md +50 -0
  8. package/agents/communications/agent.md +96 -0
  9. package/agents/decision-log/agent.md +65 -0
  10. package/agents/desktop-operator/agent.md +59 -0
  11. package/agents/gmail-operator/agent.md +62 -0
  12. package/agents/inbound-dispatcher/agent.md +66 -0
  13. package/agents/inbox-processor/agent.md +39 -0
  14. package/agents/pmo-execution/agent.md +60 -0
  15. package/agents/session-spawner/agent.md +64 -0
  16. package/agents/slack-operator/agent.md +60 -0
  17. package/agents/whatsapp-operator/agent.md +60 -0
  18. package/agents/workflow-automation/agent.md +61 -0
  19. package/archetypes/altitudes/c-suite.yaml +58 -0
  20. package/archetypes/altitudes/founder.yaml +68 -0
  21. package/archetypes/altitudes/senior-manager.yaml +63 -0
  22. package/archetypes/altitudes/svp.yaml +60 -0
  23. package/archetypes/altitudes/vp.yaml +50 -0
  24. package/archetypes/archetype.schema.json +77 -0
  25. package/archetypes/base.yaml +47 -0
  26. package/archetypes/capabilities/commercial-leader.yaml +159 -0
  27. package/archetypes/capabilities/compliance-officer.yaml +159 -0
  28. package/archetypes/capabilities/executive-operator.yaml +169 -0
  29. package/archetypes/capabilities/finance-leader.yaml +162 -0
  30. package/archetypes/capabilities/operations-leader.yaml +154 -0
  31. package/archetypes/capabilities/product-leader.yaml +148 -0
  32. package/archetypes/capabilities/technical-leader.yaml +146 -0
  33. package/archetypes/functions/commercial-leader.yaml +62 -0
  34. package/archetypes/functions/compliance-officer.yaml +64 -0
  35. package/archetypes/functions/executive-operator.yaml +70 -0
  36. package/archetypes/functions/finance-leader.yaml +70 -0
  37. package/archetypes/functions/operations-leader.yaml +62 -0
  38. package/archetypes/functions/product-leader.yaml +61 -0
  39. package/archetypes/functions/technical-leader.yaml +57 -0
  40. package/bin/cohort-mcp.mjs +81 -0
  41. package/bin/maestro.mjs +3516 -0
  42. package/bin/maestro.test.mjs +1015 -0
  43. package/desktop-control/README.md +56 -0
  44. package/desktop-control/app-profiles/gmail.yaml +120 -0
  45. package/desktop-control/app-profiles/slack.yaml +315 -0
  46. package/desktop-control/app-profiles/whatsapp.yaml +107 -0
  47. package/docs/architecture/agent-topology.md +2239 -0
  48. package/docs/architecture/archetype-agent-factory.md +110 -0
  49. package/docs/architecture/collective-memory-and-org-mesh.md +115 -0
  50. package/docs/architecture/continuous-monitoring.md +221 -0
  51. package/docs/architecture/mcp-capability-map.md +585 -0
  52. package/docs/architecture/system-architecture.md +1272 -0
  53. package/docs/company-context/README.md +40 -0
  54. package/docs/guides/agent-persona-setup.md +600 -0
  55. package/docs/guides/agents-observe-setup.md +64 -0
  56. package/docs/guides/billing-console-keys.md +88 -0
  57. package/docs/guides/ccxray-diagnostics.md +65 -0
  58. package/docs/guides/channel-bus.md +127 -0
  59. package/docs/guides/claude-mem-setup.md +79 -0
  60. package/docs/guides/claude-pace-setup.md +56 -0
  61. package/docs/guides/claudraband-sessions.md +98 -0
  62. package/docs/guides/clawteam-swarm.md +116 -0
  63. package/docs/guides/code-review-graph-setup.md +86 -0
  64. package/docs/guides/email-setup.md +431 -0
  65. package/docs/guides/mac-mini.md +119 -0
  66. package/docs/guides/media-generation-setup.md +349 -0
  67. package/docs/guides/model-routing.md +162 -0
  68. package/docs/guides/observability-otel.md +265 -0
  69. package/docs/guides/org-onboarding.md +132 -0
  70. package/docs/guides/outbound-governance-setup.md +437 -0
  71. package/docs/guides/pdf-generation-setup.md +315 -0
  72. package/docs/guides/poller-daemon-setup.md +563 -0
  73. package/docs/guides/rag-context-setup.md +459 -0
  74. package/docs/guides/self-optimization-pattern.md +82 -0
  75. package/docs/guides/setup-wizard.md +178 -0
  76. package/docs/guides/slack-setup.md +350 -0
  77. package/docs/guides/telegram-setup.md +227 -0
  78. package/docs/guides/twilio-subaccounts-setup.md +223 -0
  79. package/docs/guides/verification.md +128 -0
  80. package/docs/guides/voice-mode.md +188 -0
  81. package/docs/guides/voice-sms-setup.md +698 -0
  82. package/docs/guides/webhook-relay-setup.md +349 -0
  83. package/docs/guides/whatsapp-setup.md +288 -0
  84. package/docs/prompts/board-pack-cover-template.md +36 -0
  85. package/docs/prompts/decision-recommendation-template.md +88 -0
  86. package/docs/prompts/followup-message-template.md +141 -0
  87. package/docs/prompts/investor-letter-template.md +52 -0
  88. package/docs/prompts/morning-brief-template.md +82 -0
  89. package/docs/prompts/presentation-template.md +58 -0
  90. package/docs/prompts/weekly-strategic-memo-template.md +104 -0
  91. package/docs/research/hallucinated-tool-output-investigation.md +151 -0
  92. package/docs/runbooks/backup-restore.md +205 -0
  93. package/docs/runbooks/cohort-cutover.md +129 -0
  94. package/docs/runbooks/fleet-operations.md +200 -0
  95. package/docs/runbooks/incident-response.md +226 -0
  96. package/docs/runbooks/mac-mini-bootstrap.md +431 -0
  97. package/docs/runbooks/perpetual-operations.md +509 -0
  98. package/docs/runbooks/recovery-and-failover.md +260 -0
  99. package/framework-features.json +267 -0
  100. package/ingest/README.md +87 -0
  101. package/lib/action-executor.js +689 -0
  102. package/lib/action-executor.test.mjs +871 -0
  103. package/lib/agent-root.mjs +37 -0
  104. package/lib/archetype.mjs +236 -0
  105. package/lib/archetype.test.mjs +132 -0
  106. package/lib/autonomy.mjs +114 -0
  107. package/lib/autonomy.test.mjs +66 -0
  108. package/lib/backlog.mjs +358 -0
  109. package/lib/backlog.test.mjs +266 -0
  110. package/lib/budget-guard.mjs +279 -0
  111. package/lib/budget-guard.test.mjs +291 -0
  112. package/lib/cadence-bus-schedule.test.mjs +194 -0
  113. package/lib/cadence-bus.mjs +1120 -0
  114. package/lib/cadence-bus.test.mjs +720 -0
  115. package/lib/cadences.mjs +205 -0
  116. package/lib/cadences.test.mjs +125 -0
  117. package/lib/capability.mjs +154 -0
  118. package/lib/capability.test.mjs +78 -0
  119. package/lib/channels/base-adapter.mjs +719 -0
  120. package/lib/channels/base-adapter.test.mjs +590 -0
  121. package/lib/channels/channel.mjs +128 -0
  122. package/lib/channels/channels.test.mjs +371 -0
  123. package/lib/channels/contract.mjs +215 -0
  124. package/lib/channels/contract.test.mjs +137 -0
  125. package/lib/channels/conversation-resolver.mjs +95 -0
  126. package/lib/channels/gmail/adapter.mjs +87 -0
  127. package/lib/channels/inbox-item.mjs +255 -0
  128. package/lib/channels/inbox-item.test.mjs +335 -0
  129. package/lib/channels/index.mjs +94 -0
  130. package/lib/channels/orgmail/adapter.mjs +353 -0
  131. package/lib/channels/orgmail/adapter.test.mjs +311 -0
  132. package/lib/channels/pairing.mjs +363 -0
  133. package/lib/channels/pairing.test.mjs +270 -0
  134. package/lib/channels/registry.mjs +164 -0
  135. package/lib/channels/slack/adapter.mjs +317 -0
  136. package/lib/channels/slack-adapter.test.mjs +212 -0
  137. package/lib/channels/sms/adapter.mjs +43 -0
  138. package/lib/channels/telegram/adapter.mjs +432 -0
  139. package/lib/channels/telegram-adapter.test.mjs +306 -0
  140. package/lib/channels/voice/adapter.mjs +301 -0
  141. package/lib/channels/voice/adapter.test.mjs +278 -0
  142. package/lib/channels/whatsapp/adapter-baileys.mjs +587 -0
  143. package/lib/channels/whatsapp/adapter-baileys.test.mjs +359 -0
  144. package/lib/channels/whatsapp/adapter-twilio.mjs +65 -0
  145. package/lib/channels/whatsapp/baileys-typing.test.mjs +154 -0
  146. package/lib/charter.mjs +256 -0
  147. package/lib/charter.test.mjs +89 -0
  148. package/lib/claude-bin.mjs +134 -0
  149. package/lib/claude-bin.test.mjs +75 -0
  150. package/lib/collective/capture.mjs +185 -0
  151. package/lib/collective/capture.test.mjs +121 -0
  152. package/lib/collective/cards.mjs +201 -0
  153. package/lib/collective/cards.test.mjs +114 -0
  154. package/lib/collective/config.mjs +186 -0
  155. package/lib/collective/config.test.mjs +123 -0
  156. package/lib/collective/global-config.mjs +113 -0
  157. package/lib/collective/global-config.test.mjs +75 -0
  158. package/lib/collective/presence.mjs +201 -0
  159. package/lib/collective/presence.test.mjs +95 -0
  160. package/lib/collective/recall.mjs +215 -0
  161. package/lib/collective/recall.test.mjs +116 -0
  162. package/lib/comms/send-gate.mjs +554 -0
  163. package/lib/comms/send-gate.test.mjs +577 -0
  164. package/lib/comms.mjs +67 -0
  165. package/lib/comms.test.mjs +41 -0
  166. package/lib/diagnostics/alerts.mjs +424 -0
  167. package/lib/diagnostics/alerts.test.mjs +318 -0
  168. package/lib/diagnostics/backup-freshness.mjs +188 -0
  169. package/lib/diagnostics/backup-freshness.test.mjs +185 -0
  170. package/lib/diagnostics/counters.mjs +269 -0
  171. package/lib/diagnostics/counters.test.mjs +206 -0
  172. package/lib/diagnostics/events.mjs +188 -0
  173. package/lib/diagnostics/events.test.mjs +290 -0
  174. package/lib/diagnostics/otel.mjs +237 -0
  175. package/lib/diagnostics/otel.test.mjs +196 -0
  176. package/lib/diagnostics/trace.mjs +216 -0
  177. package/lib/diagnostics/trace.test.mjs +251 -0
  178. package/lib/env-compat.mjs +74 -0
  179. package/lib/env-compat.test.mjs +104 -0
  180. package/lib/feature-init.mjs +331 -0
  181. package/lib/fs-atomic.mjs +112 -0
  182. package/lib/fs-atomic.test.mjs +72 -0
  183. package/lib/fs-ownership.mjs +111 -0
  184. package/lib/fs-ownership.test.mjs +158 -0
  185. package/lib/hooks/bus.mjs +347 -0
  186. package/lib/hooks/bus.test.mjs +387 -0
  187. package/lib/index.js +16 -0
  188. package/lib/learning/config.mjs +106 -0
  189. package/lib/learning/config.test.mjs +75 -0
  190. package/lib/learning/counters.mjs +156 -0
  191. package/lib/learning/counters.test.mjs +69 -0
  192. package/lib/learning/curator-consolidate.test.mjs +238 -0
  193. package/lib/learning/curator.mjs +453 -0
  194. package/lib/learning/curator.test.mjs +106 -0
  195. package/lib/learning/log.mjs +40 -0
  196. package/lib/learning/reflect.mjs +534 -0
  197. package/lib/learning/reflect.test.mjs +0 -0
  198. package/lib/learning/session-index.mjs +352 -0
  199. package/lib/learning/session-index.test.mjs +125 -0
  200. package/lib/learning/skill-writer.mjs +474 -0
  201. package/lib/learning/skill-writer.test.mjs +210 -0
  202. package/lib/mcp/server.mjs +328 -0
  203. package/lib/mcp/server.test.mjs +400 -0
  204. package/lib/model-router/auth-profiles.mjs +758 -0
  205. package/lib/model-router/auth-profiles.test.mjs +580 -0
  206. package/lib/model-router/catalog/anthropic.yaml +153 -0
  207. package/lib/model-router/catalog/deepseek.yaml +86 -0
  208. package/lib/model-router/catalog/moonshot.yaml +81 -0
  209. package/lib/model-router/catalog/qwen.yaml +114 -0
  210. package/lib/model-router/catalog.mjs +925 -0
  211. package/lib/model-router/catalog.test.mjs +385 -0
  212. package/lib/model-router/economics.mjs +564 -0
  213. package/lib/model-router/economics.test.mjs +344 -0
  214. package/lib/model-router/failover.mjs +298 -0
  215. package/lib/model-router/failover.test.mjs +439 -0
  216. package/lib/model-router/health.mjs +453 -0
  217. package/lib/model-router/health.test.mjs +338 -0
  218. package/lib/model-router/integration-coverage.test.mjs +829 -0
  219. package/lib/model-router/integration.test.mjs +564 -0
  220. package/lib/model-router/ledger.mjs +402 -0
  221. package/lib/model-router/ledger.test.mjs +382 -0
  222. package/lib/model-router/llm-task.mjs +515 -0
  223. package/lib/model-router/llm-task.test.mjs +392 -0
  224. package/lib/model-router/org-credentials.mjs +260 -0
  225. package/lib/model-router/org-credentials.test.mjs +265 -0
  226. package/lib/model-router/pricing-refresh.mjs +463 -0
  227. package/lib/model-router/pricing-refresh.test.mjs +286 -0
  228. package/lib/model-router/reconcile.mjs +429 -0
  229. package/lib/model-router/reconcile.test.mjs +316 -0
  230. package/lib/model-router/repair.mjs +471 -0
  231. package/lib/model-router/repair.test.mjs +180 -0
  232. package/lib/model-router/resolve.mjs +1206 -0
  233. package/lib/model-router/spawn.mjs +497 -0
  234. package/lib/model-router/spawn.test.mjs +425 -0
  235. package/lib/model-router/taxonomy.mjs +893 -0
  236. package/lib/model-router/taxonomy.test.mjs +410 -0
  237. package/lib/model-router.mjs +677 -0
  238. package/lib/model-router.test.mjs +907 -0
  239. package/lib/org/activity.mjs +211 -0
  240. package/lib/org/activity.test.mjs +134 -0
  241. package/lib/org/approvals.mjs +448 -0
  242. package/lib/org/approvals.test.mjs +216 -0
  243. package/lib/org/awareness.mjs +222 -0
  244. package/lib/org/awareness.test.mjs +159 -0
  245. package/lib/org/board.mjs +229 -0
  246. package/lib/org/board.test.mjs +177 -0
  247. package/lib/org/bootstrap-context.mjs +169 -0
  248. package/lib/org/bootstrap-context.test.mjs +153 -0
  249. package/lib/org/client.mjs +1628 -0
  250. package/lib/org/client.test.mjs +1107 -0
  251. package/lib/org/cohort-client.mjs +67 -0
  252. package/lib/org/cohort-client.test.mjs +126 -0
  253. package/lib/org/cost-sync.mjs +227 -0
  254. package/lib/org/cost-sync.test.mjs +153 -0
  255. package/lib/org/doctor.mjs +212 -0
  256. package/lib/org/doctor.test.mjs +212 -0
  257. package/lib/org/handoff.mjs +293 -0
  258. package/lib/org/handoff.test.mjs +269 -0
  259. package/lib/org/integration-tools.mjs +182 -0
  260. package/lib/org/integration-tools.test.mjs +160 -0
  261. package/lib/org/keys.mjs +131 -0
  262. package/lib/org/keys.test.mjs +92 -0
  263. package/lib/org/knowledge.mjs +463 -0
  264. package/lib/org/knowledge.test.mjs +319 -0
  265. package/lib/org/leases.mjs +335 -0
  266. package/lib/org/leases.test.mjs +235 -0
  267. package/lib/org/mesh-integration.test.mjs +127 -0
  268. package/lib/org/mesh.mjs +459 -0
  269. package/lib/org/mesh.test.mjs +345 -0
  270. package/lib/org/messaging.mjs +503 -0
  271. package/lib/org/messaging.test.mjs +238 -0
  272. package/lib/org/policy.mjs +345 -0
  273. package/lib/org/policy.test.mjs +237 -0
  274. package/lib/org/protocol.checksum +1 -0
  275. package/lib/org/protocol.checksum.test.mjs +90 -0
  276. package/lib/org/protocol.mjs +967 -0
  277. package/lib/org/protocol.test.mjs +264 -0
  278. package/lib/org/registry.mjs +194 -0
  279. package/lib/org/registry.test.mjs +100 -0
  280. package/lib/org/tool-surface-integration.test.mjs +120 -0
  281. package/lib/org/tool-surface.mjs +2535 -0
  282. package/lib/org/tool-surface.test.mjs +589 -0
  283. package/lib/org/ui-parity.mjs +3236 -0
  284. package/lib/org/ui-parity.test.mjs +348 -0
  285. package/lib/org/verify.mjs +176 -0
  286. package/lib/org/verify.test.mjs +194 -0
  287. package/lib/rag/embed.mjs +188 -0
  288. package/lib/rag/indexer.mjs +425 -0
  289. package/lib/rag/rag.test.mjs +505 -0
  290. package/lib/rag/search.mjs +475 -0
  291. package/lib/rate-guard.mjs +246 -0
  292. package/lib/rate-guard.test.mjs +201 -0
  293. package/lib/render.mjs +112 -0
  294. package/lib/render.test.mjs +68 -0
  295. package/lib/resource-governor.mjs +297 -0
  296. package/lib/resource-governor.test.mjs +262 -0
  297. package/lib/scheduling/dynamic-jobs.mjs +675 -0
  298. package/lib/scheduling/dynamic-jobs.test.mjs +344 -0
  299. package/lib/scheduling/jitter.mjs +0 -0
  300. package/lib/scheduling/jitter.test.mjs +140 -0
  301. package/lib/secrets/broker.mjs +315 -0
  302. package/lib/secrets/broker.test.mjs +280 -0
  303. package/lib/secrets/providers.mjs +461 -0
  304. package/lib/secrets/providers.test.mjs +274 -0
  305. package/lib/security/audit-engine.mjs +684 -0
  306. package/lib/security/audit-engine.test.mjs +389 -0
  307. package/lib/security/coerce-args.mjs +552 -0
  308. package/lib/security/coerce-args.test.mjs +281 -0
  309. package/lib/security/dangerous-tools.mjs +97 -0
  310. package/lib/security/dangerous-tools.test.mjs +68 -0
  311. package/lib/security/external-content.mjs +145 -0
  312. package/lib/security/external-content.test.mjs +67 -0
  313. package/lib/security/redact.mjs +592 -0
  314. package/lib/security/redact.test.mjs +441 -0
  315. package/lib/security/secret-equal.mjs +73 -0
  316. package/lib/security/secret-equal.test.mjs +55 -0
  317. package/lib/session-permissions.mjs +101 -0
  318. package/lib/session-permissions.test.mjs +100 -0
  319. package/lib/setup/claude-probe.mjs +74 -0
  320. package/lib/setup/completeness.mjs +175 -0
  321. package/lib/setup/completeness.test.mjs +110 -0
  322. package/lib/setup/context-pack.mjs +173 -0
  323. package/lib/setup/context-pack.test.mjs +89 -0
  324. package/lib/setup/enrich.mjs +277 -0
  325. package/lib/setup/enrich.test.mjs +115 -0
  326. package/lib/setup/enroll-from-cohort.mjs +441 -0
  327. package/lib/setup/enroll-from-cohort.test.mjs +233 -0
  328. package/lib/setup/integration.test.mjs +162 -0
  329. package/lib/setup/io.mjs +360 -0
  330. package/lib/setup/io.test.mjs +77 -0
  331. package/lib/setup/run-generator.mjs +81 -0
  332. package/lib/setup/runner.mjs +244 -0
  333. package/lib/setup/runner.test.mjs +132 -0
  334. package/lib/setup/sections/comms.mjs +173 -0
  335. package/lib/setup/sections/company.mjs +120 -0
  336. package/lib/setup/sections/enrich.mjs +138 -0
  337. package/lib/setup/sections/identity.mjs +182 -0
  338. package/lib/setup/sections/identity.test.mjs +140 -0
  339. package/lib/setup/sections/learning.mjs +153 -0
  340. package/lib/setup/sections/learning.test.mjs +81 -0
  341. package/lib/setup/sections/messaging.mjs +219 -0
  342. package/lib/setup/sections/messaging.test.mjs +127 -0
  343. package/lib/setup/sections/model.mjs +102 -0
  344. package/lib/setup/sections/operating-model.mjs +78 -0
  345. package/lib/setup/sections/org.mjs +475 -0
  346. package/lib/setup/sections/org.test.mjs +313 -0
  347. package/lib/setup/sections/orgmail.mjs +173 -0
  348. package/lib/setup/sections/orgmail.test.mjs +118 -0
  349. package/lib/setup/sections/recovery.mjs +159 -0
  350. package/lib/setup/sections/recovery.test.mjs +98 -0
  351. package/lib/setup/sections/tools.mjs +132 -0
  352. package/lib/setup/sections/verify.mjs +97 -0
  353. package/lib/setup/sot.mjs +205 -0
  354. package/lib/setup/sot.test.mjs +81 -0
  355. package/lib/setup/state.mjs +151 -0
  356. package/lib/setup/state.test.mjs +92 -0
  357. package/lib/singleton.js +229 -0
  358. package/lib/singleton.test.mjs +135 -0
  359. package/lib/telemetry/alerts.mjs +216 -0
  360. package/lib/telemetry/alerts.test.mjs +109 -0
  361. package/lib/telemetry/collect.mjs +512 -0
  362. package/lib/telemetry/collect.test.mjs +202 -0
  363. package/lib/tool-definitions-integration.test.mjs +83 -0
  364. package/lib/tool-definitions.js +738 -0
  365. package/lib/tool-definitions.test.mjs +437 -0
  366. package/lib/util/fetch-timeout.mjs +136 -0
  367. package/lib/util/fetch-timeout.test.mjs +202 -0
  368. package/lib/util/reconnect.mjs +343 -0
  369. package/lib/util/reconnect.test.mjs +369 -0
  370. package/lib/util/unhandled.mjs +205 -0
  371. package/lib/util/unhandled.test.mjs +216 -0
  372. package/lib/voice/context-loader.mjs +466 -0
  373. package/lib/voice/index.mjs +100 -0
  374. package/lib/voice/openai-realtime.mjs +510 -0
  375. package/lib/voice/outbound.mjs +542 -0
  376. package/lib/voice/outbound.test.mjs +69 -0
  377. package/lib/voice/post-call-brief.mjs +428 -0
  378. package/lib/voice/provider.mjs +52 -0
  379. package/lib/voice/session-rotation.mjs +257 -0
  380. package/lib/voice/stt.mjs +161 -0
  381. package/lib/voice/stt.test.mjs +226 -0
  382. package/lib/voice/tool-bridge.mjs +370 -0
  383. package/lib/voice/tts.mjs +104 -0
  384. package/lib/voice/twilio-sip-bridge.mjs +288 -0
  385. package/lib/voice/voice.test.mjs +990 -0
  386. package/mcp/README.md +80 -0
  387. package/package.json +151 -0
  388. package/plugins/maestro-skills/plugin.json +139 -0
  389. package/plugins/maestro-skills/skills/agents-observe.md +110 -0
  390. package/plugins/maestro-skills/skills/board-deck.md +68 -0
  391. package/plugins/maestro-skills/skills/books-close.md +77 -0
  392. package/plugins/maestro-skills/skills/brand-steward.md +121 -0
  393. package/plugins/maestro-skills/skills/calendar-plan.md +57 -0
  394. package/plugins/maestro-skills/skills/call-working-sessions.md +124 -0
  395. package/plugins/maestro-skills/skills/ccxray-diagnostics.md +91 -0
  396. package/plugins/maestro-skills/skills/claude-pace.md +61 -0
  397. package/plugins/maestro-skills/skills/code-review-graph.md +99 -0
  398. package/plugins/maestro-skills/skills/crm-pipeline.md +65 -0
  399. package/plugins/maestro-skills/skills/decision-brief.md +89 -0
  400. package/plugins/maestro-skills/skills/directory-hygiene.md +125 -0
  401. package/plugins/maestro-skills/skills/draft-comms.md +84 -0
  402. package/plugins/maestro-skills/skills/evening-wrap.md +53 -0
  403. package/plugins/maestro-skills/skills/files-find.md +65 -0
  404. package/plugins/maestro-skills/skills/generative-ui.md +228 -0
  405. package/plugins/maestro-skills/skills/hiring-triage.md +74 -0
  406. package/plugins/maestro-skills/skills/inbox-triage.md +61 -0
  407. package/plugins/maestro-skills/skills/mail-triage.md +86 -0
  408. package/plugins/maestro-skills/skills/morning-brief.md +54 -0
  409. package/plugins/maestro-skills/skills/native-artifacts.md +157 -0
  410. package/plugins/maestro-skills/skills/org-board.md +133 -0
  411. package/plugins/maestro-skills/skills/org-credential.md +68 -0
  412. package/plugins/maestro-skills/skills/org-recall.md +81 -0
  413. package/plugins/maestro-skills/skills/pipeline-review.md +76 -0
  414. package/plugins/maestro-skills/skills/regulatory-status.md +81 -0
  415. package/plugins/maestro-skills/skills/router-why.md +78 -0
  416. package/plugins/maestro-skills/skills/schedule-meeting.md +91 -0
  417. package/plugins/maestro-skills/skills/session-search.md +71 -0
  418. package/plugins/maestro-skills/skills/set-reminder.md +93 -0
  419. package/plugins/maestro-skills/skills/slack-followup.md +64 -0
  420. package/plugins/maestro-skills/skills/team-activity.md +86 -0
  421. package/plugins/maestro-skills/skills/weekly-memo.md +70 -0
  422. package/policies/action-classification.yaml +114 -0
  423. package/policies/ai-disclosure.yaml +294 -0
  424. package/policies/communication-style.md +139 -0
  425. package/policies/information-barriers.yaml +118 -0
  426. package/policies/prompt-injection-defence.yaml +138 -0
  427. package/public/assets/icon-dark.png +0 -0
  428. package/public/assets/icon-dark.svg +9 -0
  429. package/public/assets/icon-light.svg +9 -0
  430. package/public/assets/logo-dark.svg +15 -0
  431. package/public/assets/logo-light.svg +15 -0
  432. package/scaffold/.mcp.json +7 -0
  433. package/scaffold/CLAUDE.md +368 -0
  434. package/scaffold/config/agent.json +55 -0
  435. package/scaffold/config/agent.ts +76 -0
  436. package/scaffold/config/agent.ts.example +89 -0
  437. package/scaffold/config/alerts.yaml +23 -0
  438. package/scaffold/config/allowlist.yaml.example +25 -0
  439. package/scaffold/config/caller-id-map.yaml +46 -0
  440. package/scaffold/config/collective.yaml +49 -0
  441. package/scaffold/config/company.json +20 -0
  442. package/scaffold/config/known-agents.json +6 -0
  443. package/scaffold/config/learning.yaml +55 -0
  444. package/scaffold/config/model-routing.yaml.example +104 -0
  445. package/scaffold/config/org.yaml +25 -0
  446. package/scaffold/config/orgmail.yaml.example +19 -0
  447. package/scaffold/config/recovery.yaml +72 -0
  448. package/scaffold/config/secrets.yaml +27 -0
  449. package/scaffold/config/slack.yaml.example +35 -0
  450. package/scaffold/config/telegram.yaml.example +38 -0
  451. package/scaffold/config/voice.yaml.example +89 -0
  452. package/scaffold/config/whatsapp.yaml.example +39 -0
  453. package/schedules/README.md +49 -0
  454. package/schedules/triggers/backlog-executor.md +102 -0
  455. package/schedules/triggers/brand-steward.md +72 -0
  456. package/schedules/triggers/daily-evening-wrap.md +159 -0
  457. package/schedules/triggers/daily-midday-sweep.md +58 -0
  458. package/schedules/triggers/daily-morning-brief.md +55 -0
  459. package/schedules/triggers/directory-hygiene.md +81 -0
  460. package/schedules/triggers/dynamic-jobs.md +40 -0
  461. package/schedules/triggers/inbox-processor.md +115 -0
  462. package/schedules/triggers/meeting-action-capture.md +60 -0
  463. package/schedules/triggers/meeting-prep.md +69 -0
  464. package/schedules/triggers/messaging-inbound.md +50 -0
  465. package/schedules/triggers/org-pulse.md +24 -0
  466. package/schedules/triggers/quarterly-self-assessment.md +54 -0
  467. package/schedules/triggers/weekly-engineering-health.md +37 -0
  468. package/schedules/triggers/weekly-execution.md +65 -0
  469. package/schedules/triggers/weekly-hiring.md +53 -0
  470. package/schedules/triggers/weekly-priorities.md +38 -0
  471. package/schedules/triggers/weekly-strategic-memo.md +124 -0
  472. package/scripts/archive-email.sh +55 -0
  473. package/scripts/cadence/cadence-status.mjs +36 -0
  474. package/scripts/cadence/enqueue-cadence-tick.mjs +174 -0
  475. package/scripts/cadence/enqueue-cadence-tick.test.mjs +187 -0
  476. package/scripts/cadence/launchd-cadence-wrapper.sh +85 -0
  477. package/scripts/cadence/launchd-cloud-relay-wrapper.sh +95 -0
  478. package/scripts/cadence/launchd-socket-mode-wrapper.sh +95 -0
  479. package/scripts/ci/check-docs-accuracy.mjs +493 -0
  480. package/scripts/ci/check-docs-accuracy.test.mjs +409 -0
  481. package/scripts/ci/check-exports-exist.mjs +140 -0
  482. package/scripts/ci/check-files-exist.mjs +107 -0
  483. package/scripts/ci/check-no-build-artifacts.mjs +111 -0
  484. package/scripts/ci/check-no-build-artifacts.test.mjs +71 -0
  485. package/scripts/ci/check-no-confidential.mjs +198 -0
  486. package/scripts/ci/check-no-conflict-markers.mjs +169 -0
  487. package/scripts/ci/check-no-residual-identity.mjs +163 -0
  488. package/scripts/ci/check-no-residual-identity.test.mjs +89 -0
  489. package/scripts/ci/check-tarball-fidelity.mjs +205 -0
  490. package/scripts/ci/check-unresolved-tokens.mjs +83 -0
  491. package/scripts/ci/check.mjs +109 -0
  492. package/scripts/ci/check.test.mjs +194 -0
  493. package/scripts/ci/run-coverage.mjs +82 -0
  494. package/scripts/ci/run-tests.mjs +71 -0
  495. package/scripts/cloud-relay/README.md +59 -0
  496. package/scripts/cloud-relay/index.mjs +233 -0
  497. package/scripts/cloud-relay/package.json +15 -0
  498. package/scripts/cloud-relay/railway.json +13 -0
  499. package/scripts/cloud-relay/voice/README.md +94 -0
  500. package/scripts/cloud-relay/voice/package-lock.json +39 -0
  501. package/scripts/cloud-relay/voice/package.json +16 -0
  502. package/scripts/cloud-relay/voice/railway.json +13 -0
  503. package/scripts/cloud-relay/voice/server.mjs +532 -0
  504. package/scripts/collective/hook-runner.mjs +211 -0
  505. package/scripts/collective/hook-runner.test.mjs +90 -0
  506. package/scripts/collective/org-pulse.mjs +72 -0
  507. package/scripts/collective/org-sync.mjs +61 -0
  508. package/scripts/collective/recall.mjs +45 -0
  509. package/scripts/collective/who.mjs +30 -0
  510. package/scripts/comms-monitor.sh +288 -0
  511. package/scripts/configure-whatsapp-sandbox.sh +201 -0
  512. package/scripts/continuous-monitor.sh +91 -0
  513. package/scripts/cost/fleet-digest.mjs +407 -0
  514. package/scripts/cost/fleet-digest.test.mjs +207 -0
  515. package/scripts/cost/track-claude-usage.mjs +169 -0
  516. package/scripts/daemon/agent-daemon.mjs +989 -0
  517. package/scripts/daemon/agent-daemon.test.mjs +525 -0
  518. package/scripts/daemon/cadence-consumer-governance.test.mjs +220 -0
  519. package/scripts/daemon/cadence-consumer.mjs +1080 -0
  520. package/scripts/daemon/cadence-consumer.test.mjs +770 -0
  521. package/scripts/daemon/cadence-handlers.mjs +1121 -0
  522. package/scripts/daemon/cadence-handlers.test.mjs +617 -0
  523. package/scripts/daemon/classifier.mjs +704 -0
  524. package/scripts/daemon/classifier.test.mjs +238 -0
  525. package/scripts/daemon/classify-kind.mjs +54 -0
  526. package/scripts/daemon/classify-kind.test.mjs +40 -0
  527. package/scripts/daemon/context-compiler.mjs +605 -0
  528. package/scripts/daemon/context-compiler.test.mjs +300 -0
  529. package/scripts/daemon/dispatcher-cooldown.test.mjs +122 -0
  530. package/scripts/daemon/dispatcher-governance.test.mjs +886 -0
  531. package/scripts/daemon/dispatcher.mjs +1516 -0
  532. package/scripts/daemon/health.mjs +72 -0
  533. package/scripts/daemon/inbox-deferral.mjs +210 -0
  534. package/scripts/daemon/inbox-deferral.test.mjs +242 -0
  535. package/scripts/daemon/integration.test.mjs +149 -0
  536. package/scripts/daemon/launchd-wrapper-generic.sh +96 -0
  537. package/scripts/daemon/launchd-wrapper-slack-events.sh +37 -0
  538. package/scripts/daemon/launchd-wrapper.sh +91 -0
  539. package/scripts/daemon/lib/session-router.mjs +274 -0
  540. package/scripts/daemon/lib/session-router.test.mjs +295 -0
  541. package/scripts/daemon/maestro-daemon.mjs +275 -0
  542. package/scripts/daemon/prompt-builder.mjs +685 -0
  543. package/scripts/daemon/prompt-builder.test.mjs +213 -0
  544. package/scripts/daemon/responder.mjs +854 -0
  545. package/scripts/daemon/session-lock.mjs +721 -0
  546. package/scripts/daemon/session-lock.test.mjs +252 -0
  547. package/scripts/daemon/session-outcomes.mjs +640 -0
  548. package/scripts/daemon/session-outcomes.test.mjs +533 -0
  549. package/scripts/daemon/typing-registry.mjs +90 -0
  550. package/scripts/daemon/typing-registry.test.mjs +77 -0
  551. package/scripts/daemon/voice-webhook-server.mjs +804 -0
  552. package/scripts/decisions/capture-decision.mjs +116 -0
  553. package/scripts/disclosure_assessment.py +873 -0
  554. package/scripts/disclosure_boundaries.py +562 -0
  555. package/scripts/email-signature-principal.html +52 -0
  556. package/scripts/email-signature.html +60 -0
  557. package/scripts/email_quote_thread.py +167 -0
  558. package/scripts/email_thread_dedup.py +362 -0
  559. package/scripts/emergency-stop.sh +81 -0
  560. package/scripts/healthcheck.sh +116 -0
  561. package/scripts/hooks/block-mcp-cohort-send.sh +15 -0
  562. package/scripts/hooks/block-mcp-slack-send.sh +7 -0
  563. package/scripts/hooks/post-action-log.sh +126 -0
  564. package/scripts/hooks/pre-send-audit.sh +174 -0
  565. package/scripts/hooks/pre-send-audit.test.mjs +215 -0
  566. package/scripts/hooks/session-end-log.sh +27 -0
  567. package/scripts/hooks/session-start-banner.sh +115 -0
  568. package/scripts/huddle/audio-bridge.mjs +664 -0
  569. package/scripts/huddle/boot-slack-cdp.sh +102 -0
  570. package/scripts/huddle/huddle-controller.mjs +942 -0
  571. package/scripts/huddle/huddle-server.mjs +1229 -0
  572. package/scripts/huddle/launch-slack.sh +232 -0
  573. package/scripts/huddle/openai-realtime-bridge.mjs +462 -0
  574. package/scripts/huddle/package-lock.json +62 -0
  575. package/scripts/huddle/package.json +22 -0
  576. package/scripts/huddle/setup-audio.sh +239 -0
  577. package/scripts/huddle/start-call.mjs +318 -0
  578. package/scripts/huddle/test-pipeline.mjs +263 -0
  579. package/scripts/learning/consolidate-skills.mjs +72 -0
  580. package/scripts/learning/session-search.mjs +125 -0
  581. package/scripts/llm_email_dedup.py +442 -0
  582. package/scripts/local-triggers/generate-plists.sh +432 -0
  583. package/scripts/local-triggers/generate-plists.test.mjs +413 -0
  584. package/scripts/local-triggers/install-all.sh +49 -0
  585. package/scripts/local-triggers/plists/.gitkeep +0 -0
  586. package/scripts/local-triggers/run-trigger.sh +63 -0
  587. package/scripts/local-triggers/templates/rag-reindex.plist.template +47 -0
  588. package/scripts/local-triggers/templates/voice-relay-poller.plist.template +54 -0
  589. package/scripts/local-triggers/templates/voice-tunnel.plist.template +55 -0
  590. package/scripts/local-triggers/templates/voice-webhook.plist.template +51 -0
  591. package/scripts/maintenance/backup-to-cloud.sh +124 -0
  592. package/scripts/maintenance/health-check.sh +377 -0
  593. package/scripts/media-generation/README.md +105 -0
  594. package/scripts/media-generation/gemini-image-client.mjs +173 -0
  595. package/scripts/media-generation/generate-assets.mjs +289 -0
  596. package/scripts/media-generation/veo-video-client.mjs +219 -0
  597. package/scripts/org/send-orgmail.mjs +227 -0
  598. package/scripts/outbound-dedup-cleanup.sh +43 -0
  599. package/scripts/outbound-dedup.sh +477 -0
  600. package/scripts/outbound_dedup.py +115 -0
  601. package/scripts/parse-voice-transcript.mjs +481 -0
  602. package/scripts/pdf-generation/README.md +63 -0
  603. package/scripts/pdf-generation/build-document.mjs +247 -0
  604. package/scripts/pdf-generation/templates/board-pack.latex +136 -0
  605. package/scripts/pdf-generation/templates/corporate-letter.latex +126 -0
  606. package/scripts/pdf-generation/templates/memo.latex +114 -0
  607. package/scripts/poll-slack-events.sh +35 -0
  608. package/scripts/poller/calendar-poller.mjs +12 -0
  609. package/scripts/poller/gmail-poller.mjs +192 -0
  610. package/scripts/poller/imap-client.mjs +289 -0
  611. package/scripts/poller/inbox-scan-poller.mjs +156 -0
  612. package/scripts/poller/inbox-scan-poller.test.mjs +231 -0
  613. package/scripts/poller/index.mjs +73 -0
  614. package/scripts/poller/intra-session-check.mjs +285 -0
  615. package/scripts/poller/lib/cloud-relay-dedup.mjs +88 -0
  616. package/scripts/poller/lib/cloud-relay-dedup.test.mjs +133 -0
  617. package/scripts/poller/lib/slash-command-handlers.mjs +177 -0
  618. package/scripts/poller/secondary-gmail-poller.mjs +132 -0
  619. package/scripts/poller/slack-cloud-relay-client.mjs +368 -0
  620. package/scripts/poller/slack-poller.mjs +854 -0
  621. package/scripts/poller/slack-socket-mode.mjs +917 -0
  622. package/scripts/poller/slack-socket-mode.test.mjs +753 -0
  623. package/scripts/poller/trigger.mjs +75 -0
  624. package/scripts/poller/utils.mjs +371 -0
  625. package/scripts/poller/voice-cloud-relay-client.mjs +179 -0
  626. package/scripts/poller/voice-poller.mjs +236 -0
  627. package/scripts/poller-launchd/install.sh +66 -0
  628. package/scripts/poller-launchd/poller.plist.template +40 -0
  629. package/scripts/poller-launchd/whatsapp-handler.plist.template +39 -0
  630. package/scripts/post-interaction-indexer.py +1598 -0
  631. package/scripts/pre-draft-context.py +994 -0
  632. package/scripts/pre_draft_lookup.py +258 -0
  633. package/scripts/rag/build-index.mjs +47 -0
  634. package/scripts/rag/ingest.mjs +111 -0
  635. package/scripts/rag/search.mjs +119 -0
  636. package/scripts/rag-indexer.py +629 -0
  637. package/scripts/restore-from-backup.sh +248 -0
  638. package/scripts/restore-from-backup.test.mjs +178 -0
  639. package/scripts/resume-operations.sh +80 -0
  640. package/scripts/search-secondary-inbox.py +181 -0
  641. package/scripts/secondary-inbox-poller.py +437 -0
  642. package/scripts/self-optimization/compute-metrics.py +398 -0
  643. package/scripts/send-email-as-principal.py +369 -0
  644. package/scripts/send-email-threaded.py +392 -0
  645. package/scripts/send-email-with-attachment.py +377 -0
  646. package/scripts/send-email.sh +131 -0
  647. package/scripts/send-sms.sh +175 -0
  648. package/scripts/send-whatsapp.sh +292 -0
  649. package/scripts/session-start.sh +106 -0
  650. package/scripts/setup/boot-claude-session.sh +94 -0
  651. package/scripts/setup/configure-macos.sh +674 -0
  652. package/scripts/setup/configure-twilio-sip-trunk.mjs +207 -0
  653. package/scripts/setup/configure-voice-tunnel.mjs +182 -0
  654. package/scripts/setup/generate-agent-env.mjs +92 -0
  655. package/scripts/setup/generate-agent-package-json.mjs +222 -0
  656. package/scripts/setup/generate-agent-package-json.test.mjs +143 -0
  657. package/scripts/setup/generate-autonomy.mjs +60 -0
  658. package/scripts/setup/generate-backlog.mjs +101 -0
  659. package/scripts/setup/generate-cadences.mjs +92 -0
  660. package/scripts/setup/generate-capability.mjs +162 -0
  661. package/scripts/setup/generate-charter.mjs +76 -0
  662. package/scripts/setup/generate-comms.mjs +59 -0
  663. package/scripts/setup/generate-company.mjs +92 -0
  664. package/scripts/setup/init-agent.sh +547 -0
  665. package/scripts/setup/init-agent.test.mjs +151 -0
  666. package/scripts/setup/init-archetype.mjs +74 -0
  667. package/scripts/setup/init-backup.mjs +54 -0
  668. package/scripts/setup/init-cadence-bus.mjs +60 -0
  669. package/scripts/setup/init-channel-bus.mjs +46 -0
  670. package/scripts/setup/init-cost-tracking.mjs +45 -0
  671. package/scripts/setup/init-decision-capture.mjs +66 -0
  672. package/scripts/setup/init-known-agents.mjs +57 -0
  673. package/scripts/setup/init-learning.mjs +70 -0
  674. package/scripts/setup/init-memory-executive.mjs +45 -0
  675. package/scripts/setup/init-model-router.mjs +124 -0
  676. package/scripts/setup/init-rag.mjs +174 -0
  677. package/scripts/setup/init-session-router.mjs +38 -0
  678. package/scripts/setup/init-slack-socket-mode.mjs +260 -0
  679. package/scripts/setup/init-telegram.mjs +165 -0
  680. package/scripts/setup/init-voice-realtime.mjs +204 -0
  681. package/scripts/setup/init-whatsapp-baileys.mjs +77 -0
  682. package/scripts/setup/install-dev-tools.sh +150 -0
  683. package/scripts/setup/lib/install-plist.mjs +95 -0
  684. package/scripts/setup/migrate-agent-to-sot.mjs +192 -0
  685. package/scripts/setup/render-environment-yaml.mjs +133 -0
  686. package/scripts/slack-events-ctl.sh +177 -0
  687. package/scripts/slack-events-server.mjs +1045 -0
  688. package/scripts/slack-react.mjs +89 -0
  689. package/scripts/slack-responded.sh +232 -0
  690. package/scripts/slack-send.sh +287 -0
  691. package/scripts/slack-typing.mjs +196 -0
  692. package/scripts/slack-upload-v2.py +95 -0
  693. package/scripts/sms-handler.mjs +450 -0
  694. package/scripts/spawn-session.sh +120 -0
  695. package/scripts/sync-protocol.mjs +217 -0
  696. package/scripts/system-verify.sh +184 -0
  697. package/scripts/test-email-thread-dedup.py +239 -0
  698. package/scripts/test-information-barriers.py +484 -0
  699. package/scripts/test-llm-email-dedup.py +251 -0
  700. package/scripts/test-pre-draft-integration.py +203 -0
  701. package/scripts/test-rag-phase2.sh +442 -0
  702. package/scripts/test-rag-search.sh +251 -0
  703. package/scripts/test-voice-parser.mjs +316 -0
  704. package/scripts/user-context-search.py +659 -0
  705. package/scripts/validate_outbound.py +1504 -0
  706. package/scripts/watchdog/ai.maestro.memory-watchdog.plist +41 -0
  707. package/scripts/watchdog/force-reboot.sh +157 -0
  708. package/scripts/watchdog/memory-watchdog.sh +473 -0
  709. package/scripts/whatsapp-handler.mjs +538 -0
  710. package/teams/desktop-operations.yaml +34 -0
  711. package/teams/executive-office.yaml +27 -0
  712. package/teams/legal-and-regulatory.yaml +24 -0
  713. package/teams/platform-and-engineering.yaml +23 -0
  714. package/teams/strategy-and-growth.yaml +29 -0
  715. package/workflows/continuous/backlog-executor.yaml +141 -0
  716. package/workflows/continuous/inbound-monitor.yaml +168 -0
  717. package/workflows/daily/applicant-triage.yaml +197 -0
  718. package/workflows/daily/comms-triage.yaml +80 -0
  719. package/workflows/daily/evening-wrap.yaml +105 -0
  720. package/workflows/daily/morning-brief.yaml +164 -0
  721. package/workflows/daily/slack-followup-sweep.yaml +87 -0
  722. package/workflows/event-driven/README.md +50 -0
  723. package/workflows/event-driven/agent-failure-investigation.yaml +137 -0
  724. package/workflows/event-driven/pr-review.yaml +107 -0
  725. package/workflows/monthly/board-readiness.yaml +76 -0
  726. package/workflows/quarterly/strategic-scenario-analysis.yaml +85 -0
  727. package/workflows/session-protocol.md +171 -0
  728. package/workflows/weekly/engineering-health.yaml +154 -0
  729. package/workflows/weekly/hiring-review.yaml +169 -0
  730. package/workflows/weekly/rollup-pipeline-review.yaml +76 -0
  731. package/workflows/weekly/strategic-memo.yaml +79 -0
@@ -0,0 +1,432 @@
1
+ #!/bin/bash
2
+ # =============================================================================
3
+ # generate-plists.sh — Generate launchd plist files from templates
4
+ # =============================================================================
5
+ #
6
+ # Reads config/agent.ts to extract the agent's first name and generates
7
+ # properly configured plist files for all scheduled triggers and the daemon.
8
+ #
9
+ # Architecture marker:
10
+ # MAESTRO_PLIST_ARCH=cadence-bus
11
+ #
12
+ # This generator emits the *cadence-bus* plist architecture (introduced in
13
+ # maestro 1.8). Scheduled cadence ticks invoke a lightweight Node enqueue
14
+ # script (scripts/cadence/enqueue-cadence-tick.mjs) that drops an event onto
15
+ # state/cadence-bus/. The persistent maestro-daemon.mjs consumes the bus and
16
+ # decides — per cadence — whether to handle the tick inline or escalate to a
17
+ # managed sub-session. Launchd NEVER spawns a fresh Claude Code session for
18
+ # routine cadence ticks anymore.
19
+ #
20
+ # Doctor verifies the `MAESTRO_PLIST_ARCH=cadence-bus` marker is present in
21
+ # installed plists, and flags any plist that still runs run-trigger.sh
22
+ # directly as the legacy spawn-per-tick pattern.
23
+ #
24
+ # Usage:
25
+ # ./scripts/local-triggers/generate-plists.sh
26
+ #
27
+ # Called by: init-agent.sh (Step 5) and by `maestro upgrade` migration.
28
+ # =============================================================================
29
+
30
+ set -e
31
+
32
+ # Plist architecture marker — embedded as a comment in every generated plist.
33
+ MAESTRO_PLIST_ARCH="cadence-bus"
34
+ MAESTRO_PLIST_ARCH_VERSION="1"
35
+
36
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
37
+ AGENT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
38
+ PLIST_DIR="$SCRIPT_DIR/plists"
39
+
40
+ # Resolve the agent's first name. Order of preference:
41
+ # 1. config/agent.json — single source of truth (SOT) introduced when
42
+ # maestro split identity out of TypeScript into JSON. Use jq if
43
+ # available, otherwise a small awk fallback.
44
+ # 2. config/agent.ts — legacy path; only works if firstName is
45
+ # defined inline (string literal), not as a type-only declaration
46
+ # like `firstName: string;`.
47
+ # 3. Directory name — last-resort fallback (e.g. ~/ravi-ai → ravi).
48
+ AGENT_JSON="$AGENT_DIR/config/agent.json"
49
+ AGENT_TS="$AGENT_DIR/config/agent.ts"
50
+ AGENT_FIRST=""
51
+
52
+ if [ -z "$AGENT_FIRST" ] && [ -f "$AGENT_JSON" ]; then
53
+ if command -v jq >/dev/null 2>&1; then
54
+ AGENT_FIRST=$(jq -r '.firstName // empty' "$AGENT_JSON" 2>/dev/null | tr '[:upper:]' '[:lower:]')
55
+ else
56
+ # Awk fallback — handle "firstName": "value" with optional whitespace
57
+ AGENT_FIRST=$(awk -F'"' '/"firstName"[[:space:]]*:/ { print tolower($4); exit }' "$AGENT_JSON")
58
+ fi
59
+ fi
60
+
61
+ if [ -z "$AGENT_FIRST" ] && [ -f "$AGENT_TS" ]; then
62
+ # Only accept a quoted inline value — `firstName: string;` (type
63
+ # declaration) must not match. The grep requires a quote on the line.
64
+ AGENT_FIRST=$(grep "firstName:[[:space:]]*['\"]" "$AGENT_TS" \
65
+ | head -1 \
66
+ | sed "s/.*firstName:[[:space:]]*['\"]//; s/['\"].*//" \
67
+ | tr '[:upper:]' '[:lower:]')
68
+ fi
69
+
70
+ # Fall back to directory name if config not set or UNCONFIGURED.
71
+ if [ -z "$AGENT_FIRST" ] || [ "$AGENT_FIRST" = "unconfigured" ]; then
72
+ AGENT_FIRST=$(basename "$AGENT_DIR" | sed 's/-ai$//')
73
+ fi
74
+
75
+ AGENT_UPPER=$(echo "$AGENT_FIRST" | tr '[:lower:]' '[:upper:]')
76
+ AGENT_USER=$(whoami)
77
+ NODE_PATH=$(which node 2>/dev/null || echo "/opt/homebrew/bin/node")
78
+
79
+ echo "[generate-plists] Agent: $AGENT_FIRST"
80
+ echo "[generate-plists] Directory: $AGENT_DIR"
81
+ echo "[generate-plists] User: $AGENT_USER"
82
+
83
+ mkdir -p "$PLIST_DIR"
84
+
85
+ # Clear old plists before generating — prevents stale plists from a previous
86
+ # agent identity (e.g. an old AGENT_LAUNCHD_PREFIX) from being installed
87
+ # alongside new ones
88
+ rm -f "$PLIST_DIR"/*.plist 2>/dev/null
89
+
90
+ # ── Helper: generate a single plist ──────────────────────────────────────────
91
+
92
+ generate_plist() {
93
+ local LABEL="$1"
94
+ local PROGRAM_ARGS="$2" # The command to run (array elements separated by |)
95
+ local SCHEDULE="$3" # Optional: StartCalendarInterval dict content
96
+ local INTERVAL="$4" # Optional: StartInterval in seconds
97
+ local KEEP_ALIVE="$5" # Optional: true for daemon-style
98
+
99
+ local FILE="$PLIST_DIR/$LABEL.plist"
100
+
101
+ cat > "$FILE" << PLIST_HEADER
102
+ <?xml version="1.0" encoding="UTF-8"?>
103
+ <!-- maestro-plist-arch: $MAESTRO_PLIST_ARCH v$MAESTRO_PLIST_ARCH_VERSION -->
104
+ <!-- generated-by: scripts/local-triggers/generate-plists.sh -->
105
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
106
+ <plist version="1.0">
107
+ <dict>
108
+ <key>Label</key>
109
+ <string>$LABEL</string>
110
+
111
+ <key>ProgramArguments</key>
112
+ <array>
113
+ PLIST_HEADER
114
+
115
+ # Split program args by |
116
+ IFS='|' read -ra ARGS <<< "$PROGRAM_ARGS"
117
+ for arg in "${ARGS[@]}"; do
118
+ echo " <string>$arg</string>" >> "$FILE"
119
+ done
120
+
121
+ cat >> "$FILE" << PLIST_MID
122
+ </array>
123
+
124
+ <key>WorkingDirectory</key>
125
+ <string>$AGENT_DIR</string>
126
+ PLIST_MID
127
+
128
+ if [ "$KEEP_ALIVE" = "true" ]; then
129
+ cat >> "$FILE" << 'PLIST_KEEPALIVE'
130
+
131
+ <key>KeepAlive</key>
132
+ <dict>
133
+ <key>SuccessfulExit</key>
134
+ <false/>
135
+ <key>Crashed</key>
136
+ <true/>
137
+ </dict>
138
+
139
+ <key>RunAtLoad</key>
140
+ <true/>
141
+
142
+ <key>ThrottleInterval</key>
143
+ <integer>30</integer>
144
+ PLIST_KEEPALIVE
145
+ fi
146
+
147
+ if [ -n "$SCHEDULE" ]; then
148
+ cat >> "$FILE" << PLIST_SCHED
149
+
150
+ <key>StartCalendarInterval</key>
151
+ <dict>
152
+ $SCHEDULE
153
+ </dict>
154
+ PLIST_SCHED
155
+ fi
156
+
157
+ if [ -n "$INTERVAL" ]; then
158
+ cat >> "$FILE" << PLIST_INTERVAL
159
+
160
+ <key>StartInterval</key>
161
+ <integer>$INTERVAL</integer>
162
+ PLIST_INTERVAL
163
+ fi
164
+
165
+ # ── EnvironmentVariables block ──────────────────────────────────────────
166
+ # Exports for every spawned process:
167
+ # PATH — homebrew + standard paths so node/python/etc are findable
168
+ # CLAUDE_CODE_TMPDIR — redirect Claude Code per-cwd temp to external SSD if mounted
169
+ # AGENT_ROOT — used by maestro's singleton lock and other helpers
170
+ cat >> "$FILE" << PLIST_ENV
171
+
172
+ <key>EnvironmentVariables</key>
173
+ <dict>
174
+ <key>PATH</key>
175
+ <string>/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
176
+ <key>HOME</key>
177
+ <string>$HOME</string>
178
+ <key>USER</key>
179
+ <string>$AGENT_USER</string>
180
+ <key>AGENT_ROOT</key>
181
+ <string>$AGENT_DIR</string>
182
+ PLIST_ENV
183
+
184
+ if [ -d "/Volumes/4TB-SSD" ]; then
185
+ cat >> "$FILE" << PLIST_SSD
186
+ <key>CLAUDE_CODE_TMPDIR</key>
187
+ <string>/Volumes/4TB-SSD/maestro/${AGENT_FIRST}/claude-tmp</string>
188
+ PLIST_SSD
189
+ fi
190
+
191
+ cat >> "$FILE" << 'PLIST_ENV_END'
192
+ </dict>
193
+ PLIST_ENV_END
194
+
195
+ # Resolve symlinked log path to a real path so launchd can write to it.
196
+ # If logs/ is a symlink (e.g. when redirected to an external SSD), launchd's
197
+ # StandardErrorPath/StandardOutPath sometimes fail with EX_CONFIG (78).
198
+ LOG_REAL=$(cd -P "$AGENT_DIR/logs/daemon" 2>/dev/null && pwd -P || echo "$AGENT_DIR/logs/daemon")
199
+
200
+ cat >> "$FILE" << PLIST_FOOTER
201
+
202
+ <key>StandardOutPath</key>
203
+ <string>$LOG_REAL/launchd-stdout.log</string>
204
+
205
+ <key>StandardErrorPath</key>
206
+ <string>$LOG_REAL/launchd-stderr.log</string>
207
+ </dict>
208
+ </plist>
209
+ PLIST_FOOTER
210
+
211
+ echo " Generated: $LABEL"
212
+ }
213
+
214
+ # ── Helper: trigger plist (enqueues a cadence tick) ──────────────────────────
215
+ #
216
+ # Cadence-bus architecture: launchd invokes the lightweight Node enqueue
217
+ # script (scripts/cadence/enqueue-cadence-tick.mjs) which drops a JSON event
218
+ # onto state/cadence-bus/inbox/. The persistent maestro-daemon.mjs consumes
219
+ # the bus and either handles the tick inline or escalates to a managed
220
+ # sub-session.
221
+ #
222
+ # This deliberately does NOT spawn Claude Code per tick anymore. The legacy
223
+ # run-trigger.sh is preserved for manual one-shot invocations only.
224
+
225
+ generate_trigger_plist() {
226
+ local TRIGGER_NAME="$1"
227
+ local SCHEDULE="$2"
228
+ local INTERVAL="$3"
229
+ local CATCHUP_SECONDS="$4" # Optional: catch-up interval (seconds) for
230
+ # calendar-scheduled cadences that have no
231
+ # StartInterval. Used by the bus's at-most-once
232
+ # gate (WS4) for stale fast-forward after an
233
+ # outage. For StartInterval cadences the
234
+ # interval is taken from $INTERVAL directly.
235
+
236
+ local LABEL="ai.maestro.${AGENT_FIRST}-${TRIGGER_NAME}"
237
+ local ENQUEUE="$AGENT_DIR/scripts/cadence/enqueue-cadence-tick.mjs"
238
+ local WRAPPER="$AGENT_DIR/scripts/cadence/launchd-cadence-wrapper.sh"
239
+
240
+ # The cadence interval (seconds) handed to the enqueue script so the bus can
241
+ # enforce at-most-once delivery + stale fast-forward. Prefer the explicit
242
+ # StartInterval; otherwise the caller-supplied calendar catch-up interval.
243
+ local TICK_INTERVAL="$INTERVAL"
244
+ [ -z "$TICK_INTERVAL" ] && TICK_INTERVAL="$CATCHUP_SECONDS"
245
+
246
+ local ENQUEUE_ARGS="$WRAPPER|$ENQUEUE|$TRIGGER_NAME|--source=launchd|--quiet"
247
+ if [ -n "$TICK_INTERVAL" ]; then
248
+ ENQUEUE_ARGS="$ENQUEUE_ARGS|--interval=$TICK_INTERVAL"
249
+ fi
250
+
251
+ generate_plist "$LABEL" \
252
+ "$ENQUEUE_ARGS" \
253
+ "$SCHEDULE" \
254
+ "$INTERVAL" \
255
+ ""
256
+ }
257
+
258
+ # ── Generate all plists ─────────────────────────────────────────────────────
259
+
260
+ echo ""
261
+ echo "Generating launchd plist files..."
262
+
263
+ # 1. Main daemon (KeepAlive) — uses wrapper to bootstrap env (HOME, PATH, etc).
264
+ # Wrapper is at scripts/daemon/launchd-wrapper.sh. This avoids passing
265
+ # EnvironmentVariables in the plist, which has been observed to cause
266
+ # EX_CONFIG (78) failures on macOS when the agent's logs/state dirs are
267
+ # symlinked to an external SSD.
268
+ generate_plist "ai.maestro.${AGENT_FIRST}-daemon" \
269
+ "${AGENT_DIR}/scripts/daemon/launchd-wrapper.sh" \
270
+ "" "" "true"
271
+
272
+ # 2. Slack events relay polling job (every 5 sec).
273
+ # The local Mac mini polls the Railway-hosted webhook relay for buffered
274
+ # Slack events. This replaces the older local slack-events-server.mjs which
275
+ # needed an inbound tunnel from the Mac. See docs/guides/webhook-relay-setup.md.
276
+ # Routed through the generic wrapper so its output goes to the SSD.
277
+ generate_plist "ai.maestro.${AGENT_FIRST}-poll-relay" \
278
+ "${AGENT_DIR}/scripts/daemon/launchd-wrapper-generic.sh|${AGENT_DIR}/scripts/poll-slack-events.sh" \
279
+ "" "5" ""
280
+
281
+ # 2b. Slack Socket Mode listener (persistent WebSocket — KeepAlive).
282
+ # Replaces the 60s slack-poller cycle for DMs + @mentions with a
283
+ # realtime WSS connection to Slack. Requires SLACK_APP_LEVEL_TOKEN
284
+ # in .env (the operator generates this via api.slack.com → App-Level
285
+ # Tokens with connections:write scope). The wrapper at
286
+ # scripts/cadence/launchd-socket-mode-wrapper.sh bootstraps env +
287
+ # execs scripts/poller/slack-socket-mode.mjs.
288
+ #
289
+ # KeepAlive uses the same SuccessfulExit:false / Crashed:true semantics
290
+ # as the daemon plist so .emergency-stop (clean exit 0) refuses to
291
+ # restart, but unexpected crashes do trigger a restart treadmill.
292
+ generate_plist "ai.maestro.${AGENT_FIRST}-slack-socket" \
293
+ "${AGENT_DIR}/scripts/cadence/launchd-socket-mode-wrapper.sh" \
294
+ "" "" "true"
295
+
296
+ # 3. Standard cadence triggers — derived from the canonical STANDARD_CADENCES
297
+ # in lib/cadences.mjs (the single source of truth), NOT a second hardcoded
298
+ # list. Previously these were hand-maintained here and drifted from the SoT
299
+ # (e.g. org-pulse was declared standard but never got a plist). The node
300
+ # emitter prints one pipe-delimited line per cadence:
301
+ # <id>|<interval-or-empty>|<base64(StartCalendarInterval-xml)-or-empty>|<catchup-seconds-or-empty>
302
+ # consumed by the same generate_trigger_plist used for archetype cadences.
303
+ #
304
+ # Resolution order for the cadences module: the agent's own lib/ (framework
305
+ # checkout), then the installed @cohortapp/agent-sdk package. If neither resolves
306
+ # (e.g. a stripped-down repo) we FALL BACK to the legacy hardcoded standard
307
+ # set so the generator never breaks.
308
+ CADENCES_MJS=""
309
+ for cand in \
310
+ "$AGENT_DIR/lib/cadences.mjs" \
311
+ "$AGENT_DIR/node_modules/@cohortapp/agent-sdk/lib/cadences.mjs" \
312
+ "${MAESTRO_ROOT:-}/lib/cadences.mjs"; do
313
+ if [ -n "$cand" ] && [ -f "$cand" ]; then CADENCES_MJS="$cand"; break; fi
314
+ done
315
+
316
+ STD_CADENCE_LINES=""
317
+ if [ -n "$CADENCES_MJS" ]; then
318
+ STD_CADENCE_LINES=$(node --input-type=module -e "
319
+ import { STANDARD_CADENCES } from '$CADENCES_MJS';
320
+ // StartCalendarInterval dict-content XML, mirroring generate-cadences.mjs.
321
+ function xml(cal) {
322
+ let x = '';
323
+ if (cal.weekday != null) x += ' <key>Weekday</key>\n <integer>' + cal.weekday + '</integer>\n';
324
+ if (cal.day != null) x += ' <key>Day</key>\n <integer>' + cal.day + '</integer>\n';
325
+ x += ' <key>Hour</key>\n <integer>' + (cal.hour ?? 9) + '</integer>\n <key>Minute</key>\n <integer>' + (cal.minute ?? 0) + '</integer>';
326
+ return x;
327
+ }
328
+ const DAILY = 86400, MONTHLY = 2592000;
329
+ for (const c of STANDARD_CADENCES) {
330
+ if (typeof c.interval === 'number') {
331
+ // StartInterval cadence: interval is both schedule and catch-up.
332
+ process.stdout.write(c.id + '|' + c.interval + '||\n');
333
+ } else if (c.calendar) {
334
+ // Calendar cadence: monthly catch-up if it's pinned to a Day, else daily.
335
+ const catchup = c.calendar.day != null ? MONTHLY : DAILY;
336
+ const b64 = Buffer.from(xml(c.calendar), 'utf-8').toString('base64');
337
+ process.stdout.write(c.id + '||' + b64 + '|' + catchup + '\n');
338
+ }
339
+ // Cadences with neither interval nor calendar (none today) are skipped — they
340
+ // have no launchd trigger.
341
+ }
342
+ " 2>/dev/null) || STD_CADENCE_LINES=""
343
+ fi
344
+
345
+ if [ -n "$STD_CADENCE_LINES" ]; then
346
+ while IFS='|' read -r CID CINT CSCHED64 CCATCHUP; do
347
+ [ -z "$CID" ] && continue
348
+ if [ -n "$CINT" ]; then
349
+ generate_trigger_plist "$CID" "" "$CINT"
350
+ else
351
+ CSCHED=$(printf '%s' "$CSCHED64" | base64 -D 2>/dev/null || printf '%s' "$CSCHED64" | base64 -d 2>/dev/null)
352
+ generate_trigger_plist "$CID" "$CSCHED" "" "$CCATCHUP"
353
+ fi
354
+ done <<< "$STD_CADENCE_LINES"
355
+ echo "[generate-plists] emitted standard cadences from lib/cadences.mjs (SoT)"
356
+ else
357
+ # ── Legacy fallback: hardcoded standard set (used only when lib/cadences.mjs
358
+ # cannot be resolved). Kept in sync with STANDARD_CADENCES. ──
359
+ echo "[generate-plists] WARN: lib/cadences.mjs not resolvable; using hardcoded standard set"
360
+ generate_trigger_plist "inbox-processor" "" "300"
361
+ generate_trigger_plist "backlog-executor" "" "600"
362
+ generate_trigger_plist "meeting-prep" "" "900"
363
+ generate_trigger_plist "meeting-action-capture" "" "1800"
364
+ generate_trigger_plist "daily-morning-brief" \
365
+ " <key>Hour</key>
366
+ <integer>6</integer>
367
+ <key>Minute</key>
368
+ <integer>30</integer>" \
369
+ "" "86400"
370
+ generate_trigger_plist "daily-midday-sweep" \
371
+ " <key>Hour</key>
372
+ <integer>12</integer>
373
+ <key>Minute</key>
374
+ <integer>0</integer>" \
375
+ "" "86400"
376
+ generate_trigger_plist "daily-evening-wrap" \
377
+ " <key>Hour</key>
378
+ <integer>18</integer>
379
+ <key>Minute</key>
380
+ <integer>0</integer>" \
381
+ "" "86400"
382
+ generate_trigger_plist "org-pulse" \
383
+ " <key>Hour</key>
384
+ <integer>7</integer>
385
+ <key>Minute</key>
386
+ <integer>30</integer>" \
387
+ "" "86400"
388
+ generate_trigger_plist "quarterly-self-assessment" \
389
+ " <key>Day</key>
390
+ <integer>1</integer>
391
+ <key>Hour</key>
392
+ <integer>9</integer>
393
+ <key>Minute</key>
394
+ <integer>0</integer>" \
395
+ "" "2592000"
396
+ generate_trigger_plist "skill-curator" \
397
+ " <key>Hour</key>
398
+ <integer>4</integer>
399
+ <key>Minute</key>
400
+ <integer>0</integer>" \
401
+ "" "86400"
402
+ fi
403
+
404
+ # NOTE: Weekly/monthly archetype cadences (legacy weekly-hiring/priorities/
405
+ # execution/engineering-health/strategic-memo, plus function-specific ones) are
406
+ # ARCHETYPE-DRIVEN. They come from config/.cadence-plists.tsv, written by
407
+ # scripts/setup/generate-cadences.mjs from the agent's function × altitude, and
408
+ # are emitted by the loop further below — so a compliance officer and a founder
409
+ # get different schedules instead of one hardcoded exec-office rhythm.
410
+
411
+ # ── Archetype-specific cadences (function + altitude) ────────────────────────
412
+ # Emitted from config/.cadence-plists.tsv (written by generate-cadences.mjs).
413
+ # Each line is pipe-delimited: <cadence-id>|<interval-seconds-or-empty>|<base64(StartCalendarInterval-xml)-or-empty>.
414
+ # Pipe (not tab) so bash preserves the empty middle field; base64/ids never contain '|'.
415
+ # Reuses generate_trigger_plist so these get the identical cadence-bus plist
416
+ # structure as the standard set. No-op when the file is absent (legacy / framework).
417
+ CADENCE_TSV="$AGENT_DIR/config/.cadence-plists.tsv"
418
+ if [ -f "$CADENCE_TSV" ]; then
419
+ while IFS='|' read -r CID CINT CSCHED64; do
420
+ [ -z "$CID" ] && continue
421
+ if [ -n "$CINT" ]; then
422
+ generate_trigger_plist "$CID" "" "$CINT"
423
+ else
424
+ CSCHED=$(printf '%s' "$CSCHED64" | base64 -D 2>/dev/null || printf '%s' "$CSCHED64" | base64 -d 2>/dev/null)
425
+ generate_trigger_plist "$CID" "$CSCHED" ""
426
+ fi
427
+ done < "$CADENCE_TSV"
428
+ echo "[generate-plists] emitted archetype cadences from config/.cadence-plists.tsv"
429
+ fi
430
+
431
+ echo ""
432
+ echo "Generated $(ls "$PLIST_DIR"/*.plist 2>/dev/null | wc -l | tr -d ' ') plist files in $PLIST_DIR"