@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,62 @@
1
+ {
2
+ "name": "maestro-huddle",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "maestro-huddle",
9
+ "version": "1.0.0",
10
+ "dependencies": {
11
+ "@anthropic-ai/sdk": "^0.52.0",
12
+ "dotenv": "^16.5.0",
13
+ "ws": "^8.18.0"
14
+ },
15
+ "engines": {
16
+ "node": ">=20.0.0"
17
+ }
18
+ },
19
+ "node_modules/@anthropic-ai/sdk": {
20
+ "version": "0.52.0",
21
+ "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.52.0.tgz",
22
+ "integrity": "sha512-d4c+fg+xy9e46c8+YnrrgIQR45CZlAi7PwdzIfDXDM6ACxEZli1/fxhURsq30ZpMZy6LvSkr41jGq5aF5TD7rQ==",
23
+ "license": "MIT",
24
+ "bin": {
25
+ "anthropic-ai-sdk": "bin/cli"
26
+ }
27
+ },
28
+ "node_modules/dotenv": {
29
+ "version": "16.6.1",
30
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
31
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
32
+ "license": "BSD-2-Clause",
33
+ "engines": {
34
+ "node": ">=12"
35
+ },
36
+ "funding": {
37
+ "url": "https://dotenvx.com"
38
+ }
39
+ },
40
+ "node_modules/ws": {
41
+ "version": "8.20.0",
42
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz",
43
+ "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==",
44
+ "license": "MIT",
45
+ "engines": {
46
+ "node": ">=10.0.0"
47
+ },
48
+ "peerDependencies": {
49
+ "bufferutil": "^4.0.1",
50
+ "utf-8-validate": ">=5.0.2"
51
+ },
52
+ "peerDependenciesMeta": {
53
+ "bufferutil": {
54
+ "optional": true
55
+ },
56
+ "utf-8-validate": {
57
+ "optional": true
58
+ }
59
+ }
60
+ }
61
+ }
62
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "maestro-huddle",
3
+ "version": "1.0.0",
4
+ "description": "Maestro — Slack huddle voice participation (agent-neutral)",
5
+ "main": "huddle-server.mjs",
6
+ "type": "module",
7
+ "scripts": {
8
+ "start": "node huddle-server.mjs",
9
+ "setup": "./setup-audio.sh",
10
+ "launch-slack": "./launch-slack.sh",
11
+ "join": "node huddle-server.mjs --join",
12
+ "call": "node huddle-server.mjs --call"
13
+ },
14
+ "engines": {
15
+ "node": ">=20.0.0"
16
+ },
17
+ "dependencies": {
18
+ "@anthropic-ai/sdk": "^0.52.0",
19
+ "dotenv": "^16.5.0",
20
+ "ws": "^8.18.0"
21
+ }
22
+ }
@@ -0,0 +1,239 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # ---------------------------------------------------------------------------
5
+ # Maestro Huddle — Audio Setup
6
+ #
7
+ # Installs and configures BlackHole virtual audio devices for Slack huddle
8
+ # participation. Two separate virtual devices prevent feedback loops:
9
+ #
10
+ # BlackHole 2ch → Slack's Speaker output (captures what others say)
11
+ # BlackHole 16ch → Slack's Mic input (carries the agent's synthesized voice)
12
+ #
13
+ # Usage:
14
+ # ./setup-audio.sh # Full install + verify
15
+ # ./setup-audio.sh --check # Verify existing setup only
16
+ # ---------------------------------------------------------------------------
17
+
18
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
19
+ LOG_FILE="${SCRIPT_DIR}/../../logs/huddle/setup-audio.log"
20
+
21
+ mkdir -p "$(dirname "$LOG_FILE")"
22
+
23
+ log() { echo "[$(date '+%H:%M:%S')] $*" | tee -a "$LOG_FILE"; }
24
+ err() { echo "[$(date '+%H:%M:%S')] ERROR: $*" | tee -a "$LOG_FILE" >&2; }
25
+ ok() { echo "[$(date '+%H:%M:%S')] ✓ $*" | tee -a "$LOG_FILE"; }
26
+
27
+ # ---------------------------------------------------------------------------
28
+ # Pre-flight checks
29
+ # ---------------------------------------------------------------------------
30
+
31
+ check_homebrew() {
32
+ if ! command -v brew &>/dev/null; then
33
+ err "Homebrew not installed. Install from https://brew.sh"
34
+ exit 1
35
+ fi
36
+ ok "Homebrew available"
37
+ }
38
+
39
+ check_switchaudio() {
40
+ if ! command -v SwitchAudioSource &>/dev/null; then
41
+ log "Installing switchaudio-osx..."
42
+ brew install switchaudio-osx
43
+ fi
44
+ ok "SwitchAudioSource available"
45
+ }
46
+
47
+ check_sox() {
48
+ if ! command -v sox &>/dev/null; then
49
+ log "Installing sox (audio capture/playback)..."
50
+ brew install sox
51
+ fi
52
+ ok "sox available"
53
+ }
54
+
55
+ # ---------------------------------------------------------------------------
56
+ # BlackHole installation
57
+ # ---------------------------------------------------------------------------
58
+
59
+ install_blackhole_2ch() {
60
+ if SwitchAudioSource -a 2>/dev/null | grep -q "BlackHole 2ch"; then
61
+ ok "BlackHole 2ch already installed"
62
+ return 0
63
+ fi
64
+
65
+ log "Installing BlackHole 2ch (huddle output capture)..."
66
+ brew install blackhole-2ch
67
+
68
+ # Verify installation
69
+ sleep 2
70
+ if SwitchAudioSource -a 2>/dev/null | grep -q "BlackHole 2ch"; then
71
+ ok "BlackHole 2ch installed successfully"
72
+ else
73
+ err "BlackHole 2ch installation failed — may need restart"
74
+ return 1
75
+ fi
76
+ }
77
+
78
+ install_blackhole_16ch() {
79
+ if SwitchAudioSource -a 2>/dev/null | grep -q "BlackHole 16ch"; then
80
+ ok "BlackHole 16ch already installed"
81
+ return 0
82
+ fi
83
+
84
+ log "Installing BlackHole 16ch (agent mic input)..."
85
+ brew install blackhole-16ch
86
+
87
+ sleep 2
88
+ if SwitchAudioSource -a 2>/dev/null | grep -q "BlackHole 16ch"; then
89
+ ok "BlackHole 16ch installed successfully"
90
+ else
91
+ err "BlackHole 16ch installation failed — may need restart"
92
+ return 1
93
+ fi
94
+ }
95
+
96
+ # ---------------------------------------------------------------------------
97
+ # Verification
98
+ # ---------------------------------------------------------------------------
99
+
100
+ verify_audio_devices() {
101
+ log ""
102
+ log "=== Audio Device Verification ==="
103
+ log ""
104
+
105
+ local all_devices
106
+ all_devices=$(SwitchAudioSource -a 2>/dev/null)
107
+
108
+ log "All audio devices:"
109
+ echo "$all_devices" | while read -r line; do
110
+ log " $line"
111
+ done
112
+
113
+ local pass=true
114
+
115
+ if echo "$all_devices" | grep -q "BlackHole 2ch"; then
116
+ ok "BlackHole 2ch present (Slack speaker → capture)"
117
+ else
118
+ err "BlackHole 2ch NOT found"
119
+ pass=false
120
+ fi
121
+
122
+ if echo "$all_devices" | grep -q "BlackHole 16ch"; then
123
+ ok "BlackHole 16ch present (TTS → Slack mic)"
124
+ else
125
+ err "BlackHole 16ch NOT found"
126
+ pass=false
127
+ fi
128
+
129
+ if command -v sox &>/dev/null; then
130
+ ok "sox available for audio capture/playback"
131
+ else
132
+ err "sox NOT found"
133
+ pass=false
134
+ fi
135
+
136
+ log ""
137
+
138
+ if [ "$pass" = true ]; then
139
+ ok "Audio setup verified — all devices present"
140
+ log ""
141
+ log "=== Slack Configuration Required ==="
142
+ log ""
143
+ log "Open Slack → Preferences → Audio & Video:"
144
+ log " Speaker: BlackHole 2ch"
145
+ log " Microphone: BlackHole 16ch"
146
+ log ""
147
+ log "This routes huddle audio through the agent's capture pipeline."
148
+ log "System audio remains on built-in devices (no disruption)."
149
+ return 0
150
+ else
151
+ err "Audio setup incomplete — see errors above"
152
+ return 1
153
+ fi
154
+ }
155
+
156
+ # ---------------------------------------------------------------------------
157
+ # Audio routing test
158
+ # ---------------------------------------------------------------------------
159
+
160
+ test_audio_capture() {
161
+ log ""
162
+ log "=== Audio Capture Test ==="
163
+ log ""
164
+ log "Recording 3 seconds from BlackHole 2ch..."
165
+
166
+ local test_file="/tmp/agent-audio-test-$(date +%s).wav"
167
+
168
+ # Record 3 seconds from BlackHole 2ch
169
+ if sox -t coreaudio "BlackHole 2ch" -r 16000 -c 1 -b 16 "$test_file" trim 0 3 2>/dev/null; then
170
+ local file_size
171
+ file_size=$(stat -f%z "$test_file" 2>/dev/null || echo "0")
172
+ ok "Captured ${file_size} bytes to ${test_file}"
173
+
174
+ if [ "$file_size" -gt 1000 ]; then
175
+ ok "Audio capture working (got data)"
176
+ else
177
+ log "Captured silence (expected if nothing is playing through BlackHole 2ch)"
178
+ fi
179
+
180
+ rm -f "$test_file"
181
+ else
182
+ err "Audio capture failed — BlackHole 2ch may not be accessible"
183
+ return 1
184
+ fi
185
+ }
186
+
187
+ test_audio_playback() {
188
+ log ""
189
+ log "=== Audio Playback Test ==="
190
+ log ""
191
+ log "Generating 1-second test tone on BlackHole 16ch..."
192
+
193
+ # Generate a 440Hz sine wave and play to BlackHole 16ch
194
+ if sox -n -t coreaudio "BlackHole 16ch" synth 1 sine 440 2>/dev/null; then
195
+ ok "Playback to BlackHole 16ch succeeded"
196
+ log "If Slack mic is set to BlackHole 16ch, this tone would be heard in a huddle"
197
+ else
198
+ err "Playback to BlackHole 16ch failed"
199
+ return 1
200
+ fi
201
+ }
202
+
203
+ # ---------------------------------------------------------------------------
204
+ # Main
205
+ # ---------------------------------------------------------------------------
206
+
207
+ main() {
208
+ log ""
209
+ log "=========================================="
210
+ log " Maestro Huddle — Audio Setup"
211
+ log " $(date)"
212
+ log "=========================================="
213
+ log ""
214
+
215
+ if [ "${1:-}" = "--check" ]; then
216
+ check_switchaudio
217
+ verify_audio_devices
218
+ exit $?
219
+ fi
220
+
221
+ if [ "${1:-}" = "--test" ]; then
222
+ test_audio_capture
223
+ test_audio_playback
224
+ exit $?
225
+ fi
226
+
227
+ # Full installation
228
+ check_homebrew
229
+ check_switchaudio
230
+ check_sox
231
+ install_blackhole_2ch
232
+ install_blackhole_16ch
233
+ verify_audio_devices
234
+
235
+ log ""
236
+ log "Run './setup-audio.sh --test' after configuring Slack audio to verify the pipeline."
237
+ }
238
+
239
+ main "$@"
@@ -0,0 +1,318 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Start a Slack huddle call with someone and then launch the huddle server.
4
+ *
5
+ * This script handles the two-step huddle flow:
6
+ * 1. Click huddle button in main window (opens preview)
7
+ * 2. Click "Start huddle" in preview window (starts WebRTC)
8
+ * 3. Launch the huddle server to connect audio bridge
9
+ *
10
+ * Usage:
11
+ * node start-call.mjs principal
12
+ * node start-call.mjs alex
13
+ */
14
+
15
+ import { WebSocket } from "ws";
16
+ import { execFileSync, execFile, spawn } from "node:child_process";
17
+ import { promisify } from "node:util";
18
+ import { dirname, join } from "node:path";
19
+ import { fileURLToPath } from "node:url";
20
+ import dotenv from "dotenv";
21
+
22
+ const __dirname = dirname(fileURLToPath(import.meta.url));
23
+ dotenv.config({ path: join(__dirname, "../..", ".env") });
24
+
25
+ const execFileAsync = promisify(execFile);
26
+ const CDP_URL = "http://localhost:9222";
27
+ const target = process.argv[2] || "principal";
28
+
29
+ // ---------------------------------------------------------------------------
30
+ // Helper: send CDP command
31
+ // ---------------------------------------------------------------------------
32
+
33
+ function cdpEval(wsUrl, expression, timeout = 5000) {
34
+ return new Promise((resolve, reject) => {
35
+ const ws = new WebSocket(wsUrl);
36
+ const timer = setTimeout(() => { ws.close(); reject(new Error("timeout")); }, timeout);
37
+ ws.on("error", (err) => { clearTimeout(timer); reject(err); });
38
+ ws.on("open", () => {
39
+ ws.send(JSON.stringify({
40
+ id: 1,
41
+ method: "Runtime.evaluate",
42
+ params: { expression, returnByValue: true, awaitPromise: true },
43
+ }));
44
+ });
45
+ ws.on("message", (raw) => {
46
+ const msg = JSON.parse(raw.toString());
47
+ if (msg.id === 1) {
48
+ clearTimeout(timer);
49
+ ws.close();
50
+ resolve(msg.result?.result?.value);
51
+ }
52
+ });
53
+ });
54
+ }
55
+
56
+ async function fetchTargets() {
57
+ const resp = await fetch(`${CDP_URL}/json`);
58
+ return resp.json();
59
+ }
60
+
61
+ function sleep(ms) {
62
+ return new Promise((r) => setTimeout(r, ms));
63
+ }
64
+
65
+ // ---------------------------------------------------------------------------
66
+ // Main
67
+ // ---------------------------------------------------------------------------
68
+
69
+ async function main() {
70
+ console.log(`\n=== Starting huddle call with: ${target} ===\n`);
71
+
72
+ // Step 0: Find main Slack target
73
+ const targets = await fetchTargets();
74
+ const mainTarget = targets.find(
75
+ (t) => t.type === "page" && t.url?.includes("app.slack.com/client")
76
+ );
77
+ if (!mainTarget) {
78
+ console.error("ERROR: No Slack page target found. Is Slack running with CDP?");
79
+ process.exit(1);
80
+ }
81
+ const mainWs = mainTarget.webSocketDebuggerUrl;
82
+ console.log("[OK] Found Slack target:", mainTarget.title.substring(0, 50));
83
+
84
+ // Step 1: Initialize microphone access and set audio preferences.
85
+ // After a Slack restart, input devices aren't enumerable until
86
+ // getUserMedia() or askForMediaAccess() is called. We ensure both
87
+ // permission and device enumeration are ready before proceeding.
88
+ await cdpEval(
89
+ mainWs,
90
+ `(async () => {
91
+ const calls = window.desktop?.calls;
92
+ if (calls?.askForMediaAccess) await calls.askForMediaAccess('microphone');
93
+ try {
94
+ const s = await navigator.mediaDevices.getUserMedia({audio: true});
95
+ s.getTracks().forEach(t => t.stop());
96
+ } catch {}
97
+ })()`,
98
+ 10000
99
+ );
100
+ console.log("[OK] Microphone access initialized");
101
+
102
+ const inputId = "9f391a3f2efb9f50f9dc8dea1534700bcc5d4e0478b56438930a2071401b25bb";
103
+ const outputId = "a930ae0eb95e3c597c4722e8bc232890be7f94ef6c9b864c4170a58ba28b5b6b";
104
+ await cdpEval(
105
+ mainWs,
106
+ `localStorage.setItem('preferred-media-devices', JSON.stringify({audioinput: '${inputId}', audiooutput: '${outputId}'}))`
107
+ );
108
+ console.log("[OK] Audio preferences set (BlackHole 16ch in, 2ch out)");
109
+
110
+ // Step 2: Navigate to target's DM (Cmd+K → type name → Enter)
111
+ console.log(`[..] Navigating to ${target}'s DM...`);
112
+ await execFileAsync("osascript", [
113
+ "-e",
114
+ `tell application "Slack" to activate
115
+ delay 0.5
116
+ tell application "System Events"
117
+ keystroke "k" using {command down}
118
+ end tell`,
119
+ ]);
120
+ await sleep(800);
121
+ await execFileAsync("osascript", [
122
+ "-e",
123
+ `tell application "System Events" to keystroke "${target}"`,
124
+ ]);
125
+ await sleep(1200);
126
+ await execFileAsync("osascript", [
127
+ "-e",
128
+ `tell application "System Events" to key code 36`,
129
+ ]);
130
+ await sleep(2000);
131
+ console.log("[OK] Navigated to DM");
132
+
133
+ // Step 3: Click huddle button via React props
134
+ console.log("[..] Opening huddle preview...");
135
+ const clickResult = await cdpEval(
136
+ mainWs,
137
+ `(() => {
138
+ const btn = document.querySelector('[data-qa="huddle_channel_header_button__start_button"]');
139
+ if (!btn) return 'no-button';
140
+ const pk = Object.keys(btn).find(k => k.startsWith('__reactProps'));
141
+ if (pk && btn[pk]?.onClick) {
142
+ btn[pk].onClick({
143
+ target: btn, currentTarget: btn,
144
+ nativeEvent: new MouseEvent('click', {bubbles: true}),
145
+ type: 'click', preventDefault: () => {}, stopPropagation: () => {}, persist: () => {}
146
+ });
147
+ return 'clicked';
148
+ }
149
+ return 'no-handler';
150
+ })()`
151
+ );
152
+ if (clickResult !== "clicked") {
153
+ console.error(`ERROR: Huddle button click failed: ${clickResult}`);
154
+ process.exit(1);
155
+ }
156
+ console.log("[OK] Huddle button clicked — waiting for preview...");
157
+
158
+ // Step 4: Wait for preview window to appear and get its position
159
+ let previewPos = null;
160
+ for (let attempt = 0; attempt < 10; attempt++) {
161
+ await sleep(1000);
162
+ try {
163
+ const { stdout } = await execFileAsync("osascript", [
164
+ "-e",
165
+ `tell application "System Events"
166
+ tell process "Slack"
167
+ repeat with i from 1 to (count of windows)
168
+ if name of window i contains "Huddle" then
169
+ set p to position of window i
170
+ set s to size of window i
171
+ return (item 1 of p as text) & "," & (item 2 of p as text) & "|" & (item 1 of s as text) & "x" & (item 2 of s as text)
172
+ end if
173
+ end repeat
174
+ return "waiting"
175
+ end tell
176
+ end tell`,
177
+ ]);
178
+ const result = stdout.trim();
179
+ if (result !== "waiting") {
180
+ const [posStr, sizeStr] = result.split("|");
181
+ const [wx, wy] = posStr.split(",").map(Number);
182
+ const [ww, wh] = sizeStr.split("x").map(Number);
183
+ previewPos = { x: wx, y: wy, w: ww, h: wh };
184
+ console.log(
185
+ `[OK] Preview window found at (${wx},${wy}), size ${ww}x${wh}`
186
+ );
187
+
188
+ // Move window up if Start button would be behind dock
189
+ if (wy + wh > 1000) {
190
+ await execFileAsync("osascript", [
191
+ "-e",
192
+ `tell application "System Events"
193
+ tell process "Slack"
194
+ repeat with i from 1 to (count of windows)
195
+ if name of window i contains "Huddle" then
196
+ set position of window i to {${wx}, 0}
197
+ end if
198
+ end repeat
199
+ end tell
200
+ end tell`,
201
+ ]);
202
+ previewPos.y = 0;
203
+ console.log("[OK] Moved preview window up to avoid dock");
204
+ }
205
+ break;
206
+ }
207
+ } catch {
208
+ // Window not ready yet
209
+ }
210
+ }
211
+
212
+ if (!previewPos) {
213
+ console.error("ERROR: Preview window never appeared");
214
+ process.exit(1);
215
+ }
216
+
217
+ // Step 5: Find Start button in preview CDP target
218
+ await sleep(1000);
219
+ const updatedTargets = await fetchTargets();
220
+ const previewTarget = updatedTargets.find(
221
+ (t) => t.type === "page" && t.title?.includes("Huddle")
222
+ );
223
+
224
+ let btnX = 316,
225
+ btnY = previewPos.h - 70; // Default: center-bottom
226
+
227
+ if (previewTarget) {
228
+ try {
229
+ const btnPosStr = await cdpEval(
230
+ previewTarget.webSocketDebuggerUrl,
231
+ `(() => {
232
+ const btn = document.querySelector('[data-qa="huddle_invite_window_with_preview_content_join_button"]')
233
+ || Array.from(document.querySelectorAll('button')).find(b => b.getAttribute('aria-label') === 'Start huddle');
234
+ if (!btn) return null;
235
+ const r = btn.getBoundingClientRect();
236
+ return JSON.stringify({x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)});
237
+ })()`
238
+ );
239
+ if (btnPosStr) {
240
+ const pos = JSON.parse(btnPosStr);
241
+ btnX = pos.x;
242
+ btnY = pos.y;
243
+ console.log(`[OK] Start button at viewport (${btnX}, ${btnY})`);
244
+ }
245
+ } catch (err) {
246
+ console.log(`[..] CDP button lookup failed (${err.message}), using default position`);
247
+ }
248
+ }
249
+
250
+ // Step 6: Click Start huddle via cliclick
251
+ const screenX = previewPos.x + btnX;
252
+ const screenY = previewPos.y + btnY;
253
+ console.log(`[..] Clicking Start huddle at screen (${screenX}, ${screenY})...`);
254
+
255
+ // Raise the preview window first
256
+ await execFileAsync("osascript", [
257
+ "-e",
258
+ `tell application "System Events"
259
+ tell process "Slack"
260
+ repeat with i from 1 to (count of windows)
261
+ if name of window i contains "Huddle" then
262
+ perform action "AXRaise" of window i
263
+ end if
264
+ end repeat
265
+ end tell
266
+ end tell`,
267
+ ]);
268
+ await sleep(500);
269
+
270
+ execFileSync("cliclick", [`c:${screenX},${screenY}`]);
271
+ console.log("[OK] Start button clicked");
272
+
273
+ // Step 7: Wait for huddle to connect
274
+ console.log("[..] Waiting for huddle to connect...");
275
+ await sleep(6000);
276
+
277
+ // Verify huddle is active
278
+ const updatedTargets2 = await fetchTargets();
279
+ const huddleActive = updatedTargets2.some(
280
+ (t) => t.title?.includes("Huddle:") || t.title?.includes("🎤")
281
+ );
282
+
283
+ if (huddleActive) {
284
+ console.log("[OK] Huddle is ACTIVE!\n");
285
+ } else {
286
+ // Check main window
287
+ const state = await cdpEval(
288
+ mainWs,
289
+ `JSON.stringify({
290
+ title: document.title,
291
+ activeAudio: [...document.querySelectorAll('audio')].filter(a => !a.paused).length,
292
+ huddleChildren: (document.querySelector('div.p-huddle_workspace[role="dialog"]')?.children.length || 0)
293
+ })`
294
+ );
295
+ console.log("[??] Huddle state:", state);
296
+ }
297
+
298
+ // Step 8: Launch huddle server to connect audio bridge
299
+ console.log("[..] Launching huddle server for audio bridge...\n");
300
+ const server = spawn("node", [join(__dirname, "huddle-server.mjs")], {
301
+ stdio: "inherit",
302
+ env: { ...process.env },
303
+ });
304
+
305
+ server.on("exit", (code) => {
306
+ console.log(`\n[EXIT] Huddle server exited with code ${code}`);
307
+ process.exit(code || 0);
308
+ });
309
+
310
+ // Forward signals to the server
311
+ process.on("SIGINT", () => server.kill("SIGINT"));
312
+ process.on("SIGTERM", () => server.kill("SIGTERM"));
313
+ }
314
+
315
+ main().catch((err) => {
316
+ console.error(`[FATAL] ${err.message}`);
317
+ process.exit(1);
318
+ });