@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,538 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Agent WhatsApp Handler — Twilio Inbound WhatsApp Webhook
4
+ *
5
+ * Receives inbound WhatsApp messages via Twilio webhook, maps senders to known
6
+ * contacts, writes messages to the inbox for the inbox processor, and logs everything.
7
+ *
8
+ * WhatsApp messages arrive at Twilio via the same Messages webhook as SMS, but
9
+ * with "whatsapp:" prefix on the From/To fields. This handler listens on a
10
+ * separate port so it can be configured as the WhatsApp-specific webhook in Twilio.
11
+ *
12
+ * Endpoints:
13
+ * POST /whatsapp — Twilio WhatsApp webhook (returns TwiML)
14
+ * POST /whatsapp/status — Delivery status callback
15
+ * GET /health — Health check
16
+ *
17
+ * Environment:
18
+ * TWILIO_ACCOUNT_SID — For request validation
19
+ * TWILIO_AUTH_TOKEN — For request validation
20
+ * WHATSAPP_PORT — Port to listen on (default: 3002)
21
+ *
22
+ * Usage:
23
+ * node scripts/whatsapp-handler.mjs
24
+ *
25
+ * Configure in Twilio Console:
26
+ * WhatsApp Sandbox (or WABA) → "When a message comes in" → POST → <url>/whatsapp
27
+ * Status callback → POST → <url>/whatsapp/status
28
+ */
29
+
30
+ import fs from "node:fs";
31
+ import path from "node:path";
32
+ import http from "node:http";
33
+ import { URL } from "node:url";
34
+
35
+ // ---------------------------------------------------------------------------
36
+ // Configuration
37
+ // ---------------------------------------------------------------------------
38
+
39
+ const PORT = parseInt(process.env.WHATSAPP_PORT || "3002", 10);
40
+ const AGENT_REPO_DIR =
41
+ process.env.AGENT_DIR ||
42
+ process.env.AGENT_REPO_DIR ||
43
+ path.resolve(path.dirname(new URL(import.meta.url).pathname), "..");
44
+
45
+ let _agent = null;
46
+ function loadAgent() {
47
+ if (_agent) return _agent;
48
+ try {
49
+ _agent = JSON.parse(fs.readFileSync(path.join(AGENT_REPO_DIR, "config/agent.json"), "utf-8"));
50
+ } catch {
51
+ _agent = { firstName: "Agent", phone: "" };
52
+ }
53
+ return _agent;
54
+ }
55
+
56
+ const INBOX_DIR = path.join(AGENT_REPO_DIR, "state", "inbox", "whatsapp");
57
+ const LOG_DIR = path.join(AGENT_REPO_DIR, "logs", "whatsapp");
58
+ const CALLER_ID_MAP_PATH = path.join(AGENT_REPO_DIR, "config", "caller-id-map.yaml");
59
+ const AGENT_NUMBER = loadAgent().phone || "";
60
+
61
+ // ---------------------------------------------------------------------------
62
+ // Utilities
63
+ // ---------------------------------------------------------------------------
64
+
65
+ function ensureDir(dir) {
66
+ try {
67
+ fs.mkdirSync(dir, { recursive: true });
68
+ } catch {
69
+ // Already exists or inaccessible
70
+ }
71
+ }
72
+
73
+ function today() {
74
+ return new Date().toISOString().split("T")[0];
75
+ }
76
+
77
+ function timestamp() {
78
+ return new Date().toISOString().replace(/[:.]/g, "-");
79
+ }
80
+
81
+ /**
82
+ * Strip the "whatsapp:" prefix from phone numbers.
83
+ * Twilio sends WhatsApp numbers as "whatsapp:+1234567890".
84
+ */
85
+ function stripWhatsAppPrefix(number) {
86
+ if (typeof number === "string" && number.startsWith("whatsapp:")) {
87
+ return number.substring(9);
88
+ }
89
+ return number || "";
90
+ }
91
+
92
+ /**
93
+ * Load caller-id-map.yaml and build a phone-to-user lookup.
94
+ * Simple YAML parsing — avoids external dependency.
95
+ */
96
+ function loadCallerIdMap() {
97
+ const map = new Map();
98
+ try {
99
+ const content = fs.readFileSync(CALLER_ID_MAP_PATH, "utf-8");
100
+ const userBlocks = content.split(/^\s{2}\w+:/gm);
101
+ const userKeys = content.match(/^\s{2}(\w+):/gm) || [];
102
+
103
+ for (let i = 0; i < userKeys.length; i++) {
104
+ const key = userKeys[i].trim().replace(":", "");
105
+ const block = userBlocks[i + 1] || "";
106
+
107
+ const nameMatch = block.match(/name:\s*"([^"]+)"/);
108
+ const name = nameMatch ? nameMatch[1] : key;
109
+
110
+ const accessMatch = block.match(/access_level:\s*(\w+)/);
111
+ const accessLevel = accessMatch ? accessMatch[1] : "default";
112
+
113
+ const emailMatch = block.match(/email:\s*"([^"]+)"/);
114
+ const email = emailMatch ? emailMatch[1] : "";
115
+
116
+ // Extract phone numbers
117
+ const phoneMatch = block.match(/phone:\s*\[([^\]]*)\]/);
118
+ if (phoneMatch) {
119
+ const phones = phoneMatch[1].match(/"([^"]+)"/g) || [];
120
+ for (const phoneStr of phones) {
121
+ const phone = phoneStr.replace(/"/g, "");
122
+ map.set(phone, { id: key, name, accessLevel, email });
123
+ }
124
+ }
125
+
126
+ // Also check for whatsapp-specific numbers
127
+ const waMatch = block.match(/whatsapp:\s*\[([^\]]*)\]/);
128
+ if (waMatch) {
129
+ const waNumbers = waMatch[1].match(/"([^"]+)"/g) || [];
130
+ for (const waStr of waNumbers) {
131
+ const waNum = waStr.replace(/"/g, "");
132
+ map.set(waNum, { id: key, name, accessLevel, email });
133
+ }
134
+ }
135
+ }
136
+ } catch (err) {
137
+ console.error(`[CALLER-MAP] Failed to load: ${err.message}`);
138
+ }
139
+ return map;
140
+ }
141
+
142
+ // Load on startup; reload periodically
143
+ let callerMap = loadCallerIdMap();
144
+ setInterval(() => {
145
+ callerMap = loadCallerIdMap();
146
+ }, 60_000);
147
+
148
+ /**
149
+ * Look up a phone number in the caller ID map.
150
+ */
151
+ function lookupSender(phoneNumber) {
152
+ const clean = stripWhatsAppPrefix(phoneNumber);
153
+ if (callerMap.has(clean)) {
154
+ return callerMap.get(clean);
155
+ }
156
+ const stripped = clean.replace(/^\+/, "");
157
+ for (const [key, value] of callerMap) {
158
+ if (key.replace(/^\+/, "") === stripped) {
159
+ return value;
160
+ }
161
+ }
162
+ return null;
163
+ }
164
+
165
+ /**
166
+ * Parse URL-encoded form body (application/x-www-form-urlencoded).
167
+ */
168
+ function parseFormBody(body) {
169
+ const params = new URLSearchParams(body);
170
+ const result = {};
171
+ for (const [key, value] of params) {
172
+ result[key] = value;
173
+ }
174
+ return result;
175
+ }
176
+
177
+ // ---------------------------------------------------------------------------
178
+ // Logging
179
+ // ---------------------------------------------------------------------------
180
+
181
+ function logWhatsApp(entry) {
182
+ const dir = path.join(LOG_DIR, today());
183
+ ensureDir(dir);
184
+
185
+ const logFile = path.join(dir, `${today()}-whatsapp.jsonl`);
186
+ const line = JSON.stringify({
187
+ ...entry,
188
+ logged_at: new Date().toISOString(),
189
+ });
190
+
191
+ try {
192
+ fs.appendFileSync(logFile, line + "\n");
193
+ } catch (err) {
194
+ console.error(`[LOG] Failed to write: ${err.message}`);
195
+ }
196
+
197
+ console.log(
198
+ `[WA] ${entry.direction || "inbound"} ${entry.from} -> ${entry.to}: ${(entry.body || "").substring(0, 100)}`,
199
+ );
200
+ }
201
+
202
+ /**
203
+ * Log to the main audit trail.
204
+ */
205
+ function logAudit(action, details) {
206
+ const auditDir = path.join(AGENT_REPO_DIR, "logs", "audit");
207
+ ensureDir(auditDir);
208
+
209
+ const auditFile = path.join(auditDir, `${today()}-actions.jsonl`);
210
+ const entry = {
211
+ timestamp: new Date().toISOString(),
212
+ agent: "whatsapp-handler",
213
+ action,
214
+ ...details,
215
+ };
216
+
217
+ try {
218
+ fs.appendFileSync(auditFile, JSON.stringify(entry) + "\n");
219
+ } catch (err) {
220
+ console.error(`[AUDIT] Failed to write: ${err.message}`);
221
+ }
222
+ }
223
+
224
+ // ---------------------------------------------------------------------------
225
+ // Inbox Writer
226
+ // ---------------------------------------------------------------------------
227
+
228
+ /**
229
+ * Write an inbound WhatsApp message to the inbox as a YAML file.
230
+ * Follows the same schema as SMS/Slack/Gmail inbox items.
231
+ */
232
+ function writeToInbox(msgData) {
233
+ ensureDir(INBOX_DIR);
234
+
235
+ const ts = timestamp();
236
+ const messageSid = msgData.MessageSid || msgData.SmsSid || "unknown";
237
+ const filename = `${ts}-${messageSid}.yaml`;
238
+ const filePath = path.join(INBOX_DIR, filename);
239
+
240
+ const rawFrom = stripWhatsAppPrefix(msgData.From || "");
241
+ const sender = lookupSender(rawFrom);
242
+ const senderName = sender ? sender.name : rawFrom || "unknown";
243
+ const senderId = sender ? sender.id : "unknown";
244
+ const senderPrivilege = sender ? sender.accessLevel : "unknown";
245
+
246
+ // Check for media
247
+ const numMedia = parseInt(msgData.NumMedia || "0", 10);
248
+ const mediaUrls = [];
249
+ for (let i = 0; i < numMedia; i++) {
250
+ const url = msgData[`MediaUrl${i}`];
251
+ const contentType = msgData[`MediaContentType${i}`];
252
+ if (url) {
253
+ mediaUrls.push({ url, content_type: contentType || "unknown" });
254
+ }
255
+ }
256
+
257
+ // Detect message type hints
258
+ const body = msgData.Body || "";
259
+ const profileName = msgData.ProfileName || "";
260
+ const forwarded = msgData.Forwarded === "true";
261
+ const frequentlyForwarded = msgData.FrequentlyForwarded === "true";
262
+
263
+ const yaml = [
264
+ `id: "${messageSid}"`,
265
+ `service: "whatsapp"`,
266
+ `channel: "whatsapp/${senderId}"`,
267
+ `sender: "${senderName}"`,
268
+ `sender_phone: "${rawFrom}"`,
269
+ `sender_privilege: "${senderPrivilege}"`,
270
+ `sender_profile_name: "${profileName}"`,
271
+ `timestamp: "${new Date().toISOString()}"`,
272
+ `subject: "WhatsApp from ${senderName}"`,
273
+ `content: |`,
274
+ ` ${body.replace(/\n/g, "\n ")}`,
275
+ `to: "${stripWhatsAppPrefix(msgData.To || "")}"`,
276
+ `is_reply: false`,
277
+ `is_forwarded: ${forwarded}`,
278
+ `is_frequently_forwarded: ${frequentlyForwarded}`,
279
+ `priority_signals:`,
280
+ ` from_ceo: ${senderPrivilege === "ceo"}`,
281
+ ` tagged_urgent: ${body.toLowerCase().includes("urgent")}`,
282
+ ` contains_deadline: false`,
283
+ ` mentions_agent: ${body.toLowerCase().includes((loadAgent().firstName || "agent").toLowerCase())}`,
284
+ ];
285
+
286
+ if (mediaUrls.length > 0) {
287
+ yaml.push(`media:`);
288
+ for (const m of mediaUrls) {
289
+ yaml.push(` - url: "${m.url}"`);
290
+ yaml.push(` content_type: "${m.content_type}"`);
291
+ }
292
+ }
293
+
294
+ yaml.push(`raw_ref: "whatsapp:${messageSid}"`);
295
+
296
+ try {
297
+ fs.writeFileSync(filePath, yaml.join("\n") + "\n");
298
+ console.log(`[INBOX] Written: ${filename}`);
299
+ return filePath;
300
+ } catch (err) {
301
+ console.error(`[INBOX] Failed to write: ${err.message}`);
302
+ return null;
303
+ }
304
+ }
305
+
306
+ // ---------------------------------------------------------------------------
307
+ // TwiML Response
308
+ // ---------------------------------------------------------------------------
309
+
310
+ function twimlAck() {
311
+ return '<?xml version="1.0" encoding="UTF-8"?>\n<Response></Response>';
312
+ }
313
+
314
+ // ---------------------------------------------------------------------------
315
+ // HTTP Server
316
+ // ---------------------------------------------------------------------------
317
+
318
+ const server = http.createServer(async (req, res) => {
319
+ const url = new URL(req.url, `http://localhost:${PORT}`);
320
+
321
+ // Health check
322
+ if (req.method === "GET" && url.pathname === "/health") {
323
+ res.writeHead(200, { "Content-Type": "application/json" });
324
+ res.end(
325
+ JSON.stringify({
326
+ status: "ok",
327
+ service: "agent-whatsapp-handler",
328
+ uptime: process.uptime(),
329
+ timestamp: new Date().toISOString(),
330
+ knownContacts: callerMap.size,
331
+ }),
332
+ );
333
+ return;
334
+ }
335
+
336
+ // Root info
337
+ if (req.method === "GET" && url.pathname === "/") {
338
+ res.writeHead(200, { "Content-Type": "application/json" });
339
+ res.end(
340
+ JSON.stringify({
341
+ service: "Agent WhatsApp Handler",
342
+ description: "Twilio inbound WhatsApp webhook for the agent's inbox",
343
+ endpoints: {
344
+ health: "/health",
345
+ whatsapp: "/whatsapp (POST)",
346
+ status: "/whatsapp/status (POST)",
347
+ },
348
+ }),
349
+ );
350
+ return;
351
+ }
352
+
353
+ // WhatsApp message webhook
354
+ if (req.method === "POST" && url.pathname === "/whatsapp") {
355
+ let body = "";
356
+ req.on("data", (chunk) => {
357
+ body += chunk.toString();
358
+ });
359
+ req.on("end", () => {
360
+ try {
361
+ const msgData = parseFormBody(body);
362
+
363
+ const rawFrom = msgData.From || "unknown";
364
+ const rawTo = msgData.To || "";
365
+ const from = stripWhatsAppPrefix(rawFrom);
366
+ const to = stripWhatsAppPrefix(rawTo);
367
+ const messageBody = msgData.Body || "";
368
+ const messageSid = msgData.MessageSid || msgData.SmsSid || "unknown";
369
+ const numMedia = parseInt(msgData.NumMedia || "0", 10);
370
+ const profileName = msgData.ProfileName || "";
371
+
372
+ // Log the inbound WhatsApp message
373
+ logWhatsApp({
374
+ direction: "inbound",
375
+ messageSid,
376
+ from,
377
+ to,
378
+ body: messageBody,
379
+ numMedia,
380
+ profileName,
381
+ timestamp: new Date().toISOString(),
382
+ });
383
+
384
+ // Write to inbox for processing
385
+ const inboxPath = writeToInbox(msgData);
386
+
387
+ // Log to audit trail
388
+ logAudit("whatsapp_received", {
389
+ from,
390
+ to,
391
+ messageSid,
392
+ profileName,
393
+ body_preview: messageBody.substring(0, 100),
394
+ inbox_path: inboxPath,
395
+ sender_identified: !!lookupSender(from),
396
+ num_media: numMedia,
397
+ });
398
+
399
+ // Check if from CEO — log as priority
400
+ const sender = lookupSender(from);
401
+ if (sender && sender.accessLevel === "ceo") {
402
+ console.log(
403
+ `[PRIORITY] WhatsApp from CEO (${sender.name}): ${messageBody.substring(0, 100)}`,
404
+ );
405
+
406
+ // Write priority trigger
407
+ const priorityFile = path.join(
408
+ INBOX_DIR,
409
+ `priority-${Date.now()}.yaml`,
410
+ );
411
+ const priorityYaml =
412
+ [
413
+ `type: priority_trigger`,
414
+ `reason: "WhatsApp from CEO"`,
415
+ `source_item: "whatsapp:${messageSid}"`,
416
+ `timestamp: "${new Date().toISOString()}"`,
417
+ `sender: "${sender.name}"`,
418
+ `channel: "whatsapp/${sender.id}"`,
419
+ `content: |`,
420
+ ` ${messageBody.replace(/\n/g, "\n ")}`,
421
+ ].join("\n") + "\n";
422
+
423
+ try {
424
+ fs.writeFileSync(priorityFile, priorityYaml);
425
+ console.log(`[PRIORITY] Priority trigger written`);
426
+ } catch (err) {
427
+ console.error(`[PRIORITY] Failed: ${err.message}`);
428
+ }
429
+ }
430
+
431
+ // Return TwiML acknowledgement (no auto-reply)
432
+ res.writeHead(200, { "Content-Type": "text/xml" });
433
+ res.end(twimlAck());
434
+ } catch (err) {
435
+ console.error(`[WA] Error processing webhook: ${err.message}`);
436
+ res.writeHead(200, { "Content-Type": "text/xml" });
437
+ res.end(twimlAck());
438
+ }
439
+ });
440
+ return;
441
+ }
442
+
443
+ // Delivery status callback
444
+ if (req.method === "POST" && url.pathname === "/whatsapp/status") {
445
+ let body = "";
446
+ req.on("data", (chunk) => {
447
+ body += chunk.toString();
448
+ });
449
+ req.on("end", () => {
450
+ try {
451
+ const statusData = parseFormBody(body);
452
+
453
+ const messageSid = statusData.MessageSid || "unknown";
454
+ const messageStatus = statusData.MessageStatus || "unknown";
455
+ const to = stripWhatsAppPrefix(statusData.To || "");
456
+ const from = stripWhatsAppPrefix(statusData.From || "");
457
+ const errorCode = statusData.ErrorCode || "";
458
+ const errorMessage = statusData.ErrorMessage || "";
459
+
460
+ logWhatsApp({
461
+ direction: "status",
462
+ messageSid,
463
+ from,
464
+ to,
465
+ status: messageStatus,
466
+ errorCode,
467
+ errorMessage,
468
+ timestamp: new Date().toISOString(),
469
+ });
470
+
471
+ // Log failures to audit
472
+ if (
473
+ messageStatus === "failed" ||
474
+ messageStatus === "undelivered" ||
475
+ errorCode
476
+ ) {
477
+ logAudit("whatsapp_delivery_failure", {
478
+ messageSid,
479
+ to,
480
+ from,
481
+ status: messageStatus,
482
+ errorCode,
483
+ errorMessage,
484
+ });
485
+ console.error(
486
+ `[WA-STATUS] DELIVERY FAILURE: ${messageSid} to ${to} — ${messageStatus} (${errorCode}: ${errorMessage})`,
487
+ );
488
+ } else {
489
+ console.log(
490
+ `[WA-STATUS] ${messageSid}: ${messageStatus}`,
491
+ );
492
+ }
493
+
494
+ res.writeHead(200, { "Content-Type": "text/xml" });
495
+ res.end(twimlAck());
496
+ } catch (err) {
497
+ console.error(`[WA-STATUS] Error: ${err.message}`);
498
+ res.writeHead(200, { "Content-Type": "text/xml" });
499
+ res.end(twimlAck());
500
+ }
501
+ });
502
+ return;
503
+ }
504
+
505
+ // 404 for everything else
506
+ res.writeHead(404, { "Content-Type": "application/json" });
507
+ res.end(JSON.stringify({ error: "Not found" }));
508
+ });
509
+
510
+ // ---------------------------------------------------------------------------
511
+ // Start
512
+ // ---------------------------------------------------------------------------
513
+
514
+ ensureDir(INBOX_DIR);
515
+ ensureDir(LOG_DIR);
516
+
517
+ server.listen(PORT, "0.0.0.0", () => {
518
+ console.log(`\n========================================`);
519
+ console.log(` Agent WhatsApp Handler`);
520
+ console.log(` Port: ${PORT}`);
521
+ console.log(` Health: http://0.0.0.0:${PORT}/health`);
522
+ console.log(` Webhook: POST /whatsapp`);
523
+ console.log(` Status: POST /whatsapp/status`);
524
+ console.log(` Known contacts: ${callerMap.size}`);
525
+ console.log(` Inbox: ${INBOX_DIR}`);
526
+ console.log(` Logs: ${LOG_DIR}`);
527
+ console.log(`========================================\n`);
528
+ });
529
+
530
+ // Graceful shutdown
531
+ process.on("SIGTERM", () => {
532
+ console.log("[WA] Shutting down...");
533
+ server.close(() => process.exit(0));
534
+ });
535
+ process.on("SIGINT", () => {
536
+ console.log("[WA] Shutting down...");
537
+ server.close(() => process.exit(0));
538
+ });
@@ -0,0 +1,34 @@
1
+ # Desktop Operations Team
2
+ # Controls real macOS applications on the Mac mini
3
+
4
+ name: desktop-operations
5
+ lead: desktop-operator
6
+ description: >
7
+ Manages all desktop application control on the Mac mini.
8
+ The "hands" of the CEO Brain — executing Slack, email, WhatsApp,
9
+ and browser operations under strict governance.
10
+
11
+ members:
12
+ - desktop-operator # Central desktop control coordinator
13
+ - slack-operator # Slack app control
14
+ - gmail-operator # Gmail browser control
15
+ - whatsapp-operator # WhatsApp Desktop control
16
+ - browser-operator # General browser operations
17
+ - calendar-ops # Calendar management (shared with executive-office)
18
+
19
+ responsibilities:
20
+ - Application monitoring and observation
21
+ - Message drafting and sending (with approval)
22
+ - Channel and inbox triage
23
+ - Follow-up execution
24
+ - Screenshot capture and state verification
25
+ - Action logging and audit trail
26
+
27
+ governance:
28
+ - All send operations require appropriate approval level
29
+ - All actions are logged with before/after state capture
30
+ - Rate limits enforced per application
31
+ - Emergency stop halts all desktop operations
32
+ - Forbidden actions are never executed regardless of instruction
33
+
34
+ escalation: chief-of-staff
@@ -0,0 +1,27 @@
1
+ # Executive Office Team
2
+ # The core team that produces executive outputs and manages CEO operations
3
+
4
+ name: executive-office
5
+ lead: chief-of-staff
6
+ description: >
7
+ The primary operating team. Produces all executive outputs, manages the
8
+ CEO's operational cadence, and coordinates across all domain teams.
9
+
10
+ members:
11
+ - chief-of-staff # Team lead and orchestrator
12
+ - ceo-briefing # Brief and memo production
13
+ - communications # Outbound communications governance
14
+ - pmo-execution # Project tracking and follow-through
15
+ - calendar-ops # Calendar and scheduling
16
+ - decision-log # Decision recording
17
+ - workflow-automation # Scheduled workflow management
18
+
19
+ responsibilities:
20
+ - Morning and evening briefs
21
+ - Communications triage and drafting
22
+ - Follow-up management
23
+ - Decision tracking
24
+ - Calendar management
25
+ - Executive cadence execution
26
+
27
+ escalation: principal # Escalates to CEO
@@ -0,0 +1,24 @@
1
+ # Legal & Regulatory Team
2
+ # Handles all legal, regulatory, and compliance matters
3
+
4
+ name: legal-and-regulatory
5
+ lead: regulatory-compliance
6
+ description: >
7
+ Manages regulatory submission, legal structuring,
8
+ fund operations compliance, and risk management.
9
+
10
+ members:
11
+ - regulatory-compliance # regulatory compliance
12
+ - legal-structuring # Legal entity and contract work
13
+ - fund-ops # Fund administration and investor reporting
14
+ - risk-register # Risk identification and tracking
15
+
16
+ responsibilities:
17
+ - Regulatory gap remediation tracking
18
+ - Regulatory submission preparation
19
+ - Legal structuring for M&A
20
+ - Fund compliance and reporting
21
+ - Risk register maintenance
22
+ - Monthly risk refresh
23
+
24
+ escalation: chief-of-staff
@@ -0,0 +1,23 @@
1
+ # Platform & Engineering Team
2
+ # Handles technical architecture, engineering coordination, and product strategy
3
+
4
+ name: platform-and-engineering
5
+ lead: product-strategy
6
+ description: >
7
+ Manages the company's platform development, engineering coordination,
8
+ and technical architecture decisions.
9
+
10
+ members:
11
+ - product-strategy # Product roadmap and prioritisation
12
+ - platform-architecture # Technical architecture
13
+ - engineering-coordination # Cross-repo engineering health
14
+
15
+ responsibilities:
16
+ - Platform maturity tracking
17
+ - Engineering health monitoring
18
+ - Architecture decision support
19
+ - Technical debt management
20
+ - Build and test status
21
+ - Production readiness assessment
22
+
23
+ escalation: chief-of-staff
@@ -0,0 +1,29 @@
1
+ # Strategy & Growth Team
2
+ # Handles strategic analysis, corporate development, and capital markets
3
+
4
+ name: strategy-and-growth
5
+ lead: strategic-planning
6
+ description: >
7
+ Manages all strategic analysis, M&A execution, capital raising,
8
+ and competitive positioning for the company.
9
+
10
+ members:
11
+ - strategic-planning # Strategic analysis and scenarios
12
+ - corporate-development # M&A and rollup execution
13
+ - rollup-target-sourcing # Acquisition target pipeline
14
+ - capital-raising # LP relationships and fundraising
15
+ - competitive-intelligence # Competitor monitoring
16
+ - market-research # Market and sector analysis
17
+ - partnerships # Strategic partnerships
18
+ - board-prep # Board materials and governance
19
+
20
+ responsibilities:
21
+ - Weekly strategic memo
22
+ - Rollup pipeline management
23
+ - Deal preparation and execution
24
+ - Capital raising support
25
+ - Competitive intelligence
26
+ - Board pack preparation
27
+ - Quarterly scenario analysis
28
+
29
+ escalation: chief-of-staff