@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,738 @@
1
+ /**
2
+ * Maestro — Comprehensive Tool Definitions
3
+ *
4
+ * Reusable tool schemas for Claude API tool_use, scoped by access level.
5
+ * Covers all operational capabilities an autonomous agent in an
6
+ * organisation might need.
7
+ *
8
+ * Categories:
9
+ * 1. Communication — Slack, Email, WhatsApp, SMS
10
+ * 2. Search / RAG — Email, Calendar, Files, Meetings, Slack, Web
11
+ * 3. Knowledge — Decisions, People, Regulatory, Strategy
12
+ * 4. Operations — Queues, Action Items, Scheduling
13
+ * 5. Analysis — Financial, Pipeline, Engineering Health
14
+ * 6. Document Generation — Memos, Briefs, Reports
15
+ * 7. Org (Cohort) — the curated org operating surface, generated from
16
+ * lib/org/tool-surface.mjs (ONE table shared with the cohort-mcp server
17
+ * so the two planes cannot drift). Reads land in every level's lookup
18
+ * set; writes in leadership+; the org_rpc/org_read escape hatches are
19
+ * CEO-only (server-side scopes still gate regardless). The additive
20
+ * families appear automatically once the vendored protocol carries them:
21
+ * email tools, artifact tools, and the agent desks (mail app / files /
22
+ * calendar / crm / books / meetings.recapFile).
23
+ *
24
+ * Usage:
25
+ * import { getToolsForAccessLevel } from "@cohortapp/agent-sdk/lib/tool-definitions.js";
26
+ * const tools = getToolsForAccessLevel("ceo");
27
+ * // Pass to Claude API: { tools }
28
+ *
29
+ * @module tool-definitions
30
+ */
31
+
32
+ import { getOrgTools, loadIntegrationToolsFromDisk } from "./org/tool-surface.mjs";
33
+
34
+ // ============================================================================
35
+ // 1. COMMUNICATION TOOLS
36
+ // ============================================================================
37
+
38
+ const slackSend = {
39
+ name: "slack_send",
40
+ description:
41
+ "Send a Slack message to a team member or channel. Confirm recipient and content before invoking.",
42
+ input_schema: {
43
+ type: "object",
44
+ properties: {
45
+ recipient: { type: "string", description: "Person or channel (e.g. 'Alex', '#engineering')" },
46
+ message: { type: "string", description: "Message content" },
47
+ thread_ts: { type: "string", description: "Thread timestamp to reply in-thread (optional)" },
48
+ urgent: { type: "boolean", description: "Whether urgent (affects formatting)" },
49
+ },
50
+ required: ["recipient", "message"],
51
+ },
52
+ };
53
+
54
+ const draftEmail = {
55
+ name: "draft_email",
56
+ description:
57
+ "Draft or send an email. Drafts are saved for review; set urgency to 'immediate' to send now.",
58
+ input_schema: {
59
+ type: "object",
60
+ properties: {
61
+ to: { type: "string", description: "Recipient name or email" },
62
+ subject: { type: "string", description: "Subject line" },
63
+ body: { type: "string", description: "Email body" },
64
+ cc: { type: "string", description: "CC recipients (comma-separated)" },
65
+ voice: { type: "string", enum: ["agent", "principal"], description: "Whose voice (default: agent)" },
66
+ urgency: { type: "string", enum: ["routine", "urgent", "immediate"], description: "Urgency level" },
67
+ },
68
+ required: ["to", "subject", "body"],
69
+ },
70
+ };
71
+
72
+ const whatsappSend = {
73
+ name: "whatsapp_send",
74
+ description: "Send a WhatsApp message to a registered contact.",
75
+ input_schema: {
76
+ type: "object",
77
+ properties: {
78
+ recipient: { type: "string", description: "Person name" },
79
+ message: { type: "string", description: "Message content" },
80
+ },
81
+ required: ["recipient", "message"],
82
+ },
83
+ };
84
+
85
+ const smsSend = {
86
+ name: "sms_send",
87
+ description: "Send an SMS text message via Twilio.",
88
+ input_schema: {
89
+ type: "object",
90
+ properties: {
91
+ recipient: { type: "string", description: "Person name or phone number (E.164)" },
92
+ message: { type: "string", description: "Message content (160 char limit for single SMS)" },
93
+ },
94
+ required: ["recipient", "message"],
95
+ },
96
+ };
97
+
98
+ const sendVoiceMessage = {
99
+ name: "send_voice_message",
100
+ description:
101
+ "Synthesize speech from text (OpenAI TTS) and deliver as a voice note. " +
102
+ "Auto-routes the transport: a Slack channel/DM id (C/D/G prefix) → audio file upload, " +
103
+ "an E.164 phone with WhatsApp configured → inline voice note (PTT), " +
104
+ "an E.164 phone without WhatsApp → Twilio outbound call that speaks the message. " +
105
+ "Use this when prose-via-voice is more appropriate than text (warm follow-ups, " +
106
+ "longer briefings someone will listen to in transit, content the recipient should " +
107
+ "hear in your agent voice).",
108
+ input_schema: {
109
+ type: "object",
110
+ properties: {
111
+ to: {
112
+ type: "string",
113
+ description:
114
+ "Destination: Slack channel id (C…/D…/G…), WhatsApp JID (…@s.whatsapp.net), or E.164 phone (+…)",
115
+ },
116
+ text: {
117
+ type: "string",
118
+ description: "Spoken content (max 4096 chars). Keep < 60s of audio for conversational feel.",
119
+ },
120
+ transport: {
121
+ type: "string",
122
+ enum: ["whatsapp", "slack", "pstn"],
123
+ description: "Force a specific transport (default: auto-routed based on `to`).",
124
+ },
125
+ voice: {
126
+ type: "string",
127
+ enum: ["alloy", "ash", "ballad", "coral", "echo", "sage", "shimmer", "verse"],
128
+ description: "TTS voice (default: from config/voice.yaml, falls back to alloy).",
129
+ },
130
+ },
131
+ required: ["to", "text"],
132
+ },
133
+ };
134
+
135
+ const ragSearch = {
136
+ name: "rag_search",
137
+ description:
138
+ "Semantic / keyword search across the agent's own corpus (memory, knowledge, " +
139
+ "decisions, queues, agent definitions, workflows, briefs, policies). Use this " +
140
+ "when you need a specific fact or quote from the agent's institutional memory " +
141
+ "and the answer isn't already in your pre-loaded context. Each call is fast " +
142
+ "(<50ms, no network) but adds ~1s of conversational silence so prefer it for " +
143
+ "specific lookups, not exploratory browsing. " +
144
+ "Top result is always shown; ask for more by raising top_n.",
145
+ input_schema: {
146
+ type: "object",
147
+ properties: {
148
+ query: {
149
+ type: "string",
150
+ description: "Free-text query. Specific names, project IDs, and dates work best.",
151
+ },
152
+ top_n: { type: "number", description: "Max hits to return (default: 5, max: 20)" },
153
+ kind: {
154
+ type: "string",
155
+ enum: [
156
+ "memory", "knowledge", "queue", "dashboard", "config",
157
+ "agent_def", "workflow", "brief", "memo", "policy",
158
+ ],
159
+ description:
160
+ "Filter to a single content kind. Useful when you know the answer must " +
161
+ "be in (say) decisions vs. briefs.",
162
+ },
163
+ },
164
+ required: ["query"],
165
+ },
166
+ };
167
+
168
+ const placeVoiceCall = {
169
+ name: "place_voice_call",
170
+ description:
171
+ "Place a live conversational outbound phone call. Bridges Twilio outbound → " +
172
+ "OpenAI Realtime so the agent voice (gpt-realtime-2) talks with the peer in " +
173
+ "real time, with the same tool bridge as inbound calls. Use only when a " +
174
+ "synchronous voice conversation is genuinely needed; one-shot voice messages " +
175
+ "should use send_voice_message instead (much cheaper, no real-time pressure).",
176
+ input_schema: {
177
+ type: "object",
178
+ properties: {
179
+ to: { type: "string", description: "E.164 phone number to call" },
180
+ brief: {
181
+ type: "string",
182
+ description:
183
+ "What the agent should accomplish on the call. Becomes the model's session " +
184
+ "instructions. Be specific: 'Confirm with the principal that they received the board " +
185
+ "resolution and answer any questions about clause 4.2.'",
186
+ },
187
+ voice: {
188
+ type: "string",
189
+ enum: ["cedar", "marin", "alloy", "ash", "ballad", "coral", "echo", "sage", "shimmer", "verse"],
190
+ description: "Realtime voice (default: cedar)",
191
+ },
192
+ },
193
+ required: ["to", "brief"],
194
+ },
195
+ };
196
+
197
+ // ============================================================================
198
+ // 2. SEARCH / RAG TOOLS
199
+ // ============================================================================
200
+
201
+ const searchEmail = {
202
+ name: "search_email",
203
+ description:
204
+ "Search Gmail for emails. Use for finding correspondence, checking what someone sent, recalling email threads.",
205
+ input_schema: {
206
+ type: "object",
207
+ properties: {
208
+ query: { type: "string", description: "Natural language or Gmail search syntax (e.g. 'from:alex budget this week')" },
209
+ max_results: { type: "number", description: "Max results (default: 5)" },
210
+ },
211
+ required: ["query"],
212
+ },
213
+ };
214
+
215
+ const searchCalendar = {
216
+ name: "search_calendar",
217
+ description:
218
+ "Look up calendar events — meetings, availability, schedule. Returns titles, times, attendees.",
219
+ input_schema: {
220
+ type: "object",
221
+ properties: {
222
+ query: { type: "string", description: "What to find (e.g. 'meetings tomorrow', 'next call with Shayan', 'free time Thursday')" },
223
+ time_range: { type: "string", description: "'today', 'tomorrow', 'this week', 'next week', or specific date" },
224
+ },
225
+ required: ["query"],
226
+ },
227
+ };
228
+
229
+ const searchFiles = {
230
+ name: "search_files",
231
+ description:
232
+ "Search the agent's knowledge base, documents, and operational files. Covers knowledge/, config/, state/, docs/, outputs/.",
233
+ input_schema: {
234
+ type: "object",
235
+ properties: {
236
+ query: { type: "string", description: "What to search for (e.g. 'regulatory submission status', 'rollup targets')" },
237
+ scope: { type: "string", enum: ["all", "knowledge", "config", "state", "docs", "outputs"], description: "Scope (default: all)" },
238
+ },
239
+ required: ["query"],
240
+ },
241
+ };
242
+
243
+ const searchMeetings = {
244
+ name: "search_meetings",
245
+ description:
246
+ "Search past meeting notes and transcripts. Use for recalling discussions, decisions, and action items from meetings.",
247
+ input_schema: {
248
+ type: "object",
249
+ properties: {
250
+ query: { type: "string", description: "What to find in meeting notes (e.g. 'board meeting decisions', 'hiring discussion')" },
251
+ date_range: { type: "string", description: "Date range (e.g. 'last week', 'March 2026')" },
252
+ },
253
+ required: ["query"],
254
+ },
255
+ };
256
+
257
+ const searchSlack = {
258
+ name: "search_slack",
259
+ description:
260
+ "Search Slack message history across channels. Find conversations, decisions made in Slack, mentions.",
261
+ input_schema: {
262
+ type: "object",
263
+ properties: {
264
+ query: { type: "string", description: "Search query (e.g. 'Q3 deployment', 'compliance in #legal')" },
265
+ channel: { type: "string", description: "Limit to channel (optional)" },
266
+ },
267
+ required: ["query"],
268
+ },
269
+ };
270
+
271
+ const searchWeb = {
272
+ name: "search_web",
273
+ description:
274
+ "Search the web for current information. Use for market data, competitor intel, regulatory updates, news.",
275
+ input_schema: {
276
+ type: "object",
277
+ properties: {
278
+ query: { type: "string", description: "Web search query" },
279
+ max_results: { type: "number", description: "Max results (default: 5)" },
280
+ },
281
+ required: ["query"],
282
+ },
283
+ };
284
+
285
+ const searchDocuments = {
286
+ name: "search_documents",
287
+ description:
288
+ "Search shared documents in Google Drive, Confluence, or other document stores. Find reports, proposals, specs.",
289
+ input_schema: {
290
+ type: "object",
291
+ properties: {
292
+ query: { type: "string", description: "What to find (e.g. 'investor deck Q1', 'board pack March')" },
293
+ doc_type: { type: "string", enum: ["all", "docs", "sheets", "slides", "pdf"], description: "Filter by type" },
294
+ },
295
+ required: ["query"],
296
+ },
297
+ };
298
+
299
+ // ============================================================================
300
+ // 3. KNOWLEDGE / INSTITUTIONAL MEMORY TOOLS
301
+ // ============================================================================
302
+
303
+ const searchDecisions = {
304
+ name: "search_decisions",
305
+ description:
306
+ "Search the decision archive — past decisions, their rationale, who made them, and outcomes.",
307
+ input_schema: {
308
+ type: "object",
309
+ properties: {
310
+ query: { type: "string", description: "What decision to find (e.g. 'hiring freeze rationale', 'Singapore entity structure')" },
311
+ },
312
+ required: ["query"],
313
+ },
314
+ };
315
+
316
+ const lookupPerson = {
317
+ name: "lookup_person",
318
+ description:
319
+ "Look up information about a person — role, contact details, reporting line, recent activity, communication preferences.",
320
+ input_schema: {
321
+ type: "object",
322
+ properties: {
323
+ name: { type: "string", description: "Person's name" },
324
+ info_type: { type: "string", enum: ["all", "contact", "role", "activity", "preferences"], description: "What to look up" },
325
+ },
326
+ required: ["name"],
327
+ },
328
+ };
329
+
330
+ const searchRegulatory = {
331
+ name: "search_regulatory",
332
+ description:
333
+ "Search regulatory and compliance information — licence status, submission deadlines, compliance requirements, legal obligations.",
334
+ input_schema: {
335
+ type: "object",
336
+ properties: {
337
+ query: { type: "string", description: "Regulatory query (e.g. 'licence gaps', 'submission deadline', 'regulatory requirements')" },
338
+ jurisdiction: { type: "string", description: "Jurisdiction filter (e.g. 'DIFC', 'Cayman', 'UK')" },
339
+ },
340
+ required: ["query"],
341
+ },
342
+ };
343
+
344
+ const searchStrategy = {
345
+ name: "search_strategy",
346
+ description:
347
+ "Search strategic context — priorities, OKRs, initiative status, strategic memos, competitive intelligence.",
348
+ input_schema: {
349
+ type: "object",
350
+ properties: {
351
+ query: { type: "string", description: "Strategic query (e.g. 'strategic initiative status', 'Q2 priorities', 'competitive landscape')" },
352
+ },
353
+ required: ["query"],
354
+ },
355
+ };
356
+
357
+ const searchPrecedents = {
358
+ name: "search_precedents",
359
+ description:
360
+ "Search operational precedents — how similar situations were handled before, templates, playbooks.",
361
+ input_schema: {
362
+ type: "object",
363
+ properties: {
364
+ query: { type: "string", description: "Situation to find precedent for (e.g. 'investor objection handling', 'candidate rejection template')" },
365
+ },
366
+ required: ["query"],
367
+ },
368
+ };
369
+
370
+ // ============================================================================
371
+ // 4. OPERATIONS TOOLS
372
+ // ============================================================================
373
+
374
+ const queueUpdate = {
375
+ name: "queue_update",
376
+ description:
377
+ "Update status or priority of an item in operational queues (action-stack, follow-ups, decision-queue).",
378
+ input_schema: {
379
+ type: "object",
380
+ properties: {
381
+ search_term: { type: "string", description: "Text to search in item titles (fuzzy match)" },
382
+ new_status: { type: "string", enum: ["open", "in_progress", "blocked", "resolved", "closed"] },
383
+ new_priority: { type: "string", enum: ["critical", "high", "medium", "low"] },
384
+ note: { type: "string", description: "Note to add to the item's history" },
385
+ },
386
+ required: ["search_term", "new_status"],
387
+ },
388
+ };
389
+
390
+ const createActionItem = {
391
+ name: "create_action_item",
392
+ description:
393
+ "Create a new action item, follow-up, or decision in the operational queues.",
394
+ input_schema: {
395
+ type: "object",
396
+ properties: {
397
+ title: { type: "string", description: "Brief title" },
398
+ queue: { type: "string", enum: ["action-stack", "follow-ups", "decision-queue", "tech-debt"], description: "Queue (default: action-stack)" },
399
+ priority: { type: "string", enum: ["critical", "high", "medium", "low"] },
400
+ due_date: { type: "string", description: "Due date YYYY-MM-DD" },
401
+ owner: { type: "string", description: "Responsible person (default: agent)" },
402
+ context: { type: "string", description: "Background context" },
403
+ blocked_by: { type: "string", description: "What blocks this item" },
404
+ },
405
+ required: ["title"],
406
+ },
407
+ };
408
+
409
+ const scheduleMeeting = {
410
+ name: "schedule_meeting",
411
+ description:
412
+ "Schedule a meeting on Google Calendar. Checks availability and sends invites.",
413
+ input_schema: {
414
+ type: "object",
415
+ properties: {
416
+ title: { type: "string", description: "Meeting title" },
417
+ attendees: { type: "string", description: "Attendee names or emails (comma-separated)" },
418
+ date: { type: "string", description: "Date (YYYY-MM-DD or 'tomorrow', 'next Monday')" },
419
+ time: { type: "string", description: "Time (HH:MM in agent timezone, or 'morning', 'afternoon')" },
420
+ duration: { type: "string", description: "Duration (e.g. '30m', '1h', default: 30m)" },
421
+ description: { type: "string", description: "Meeting description/agenda" },
422
+ location: { type: "string", description: "Location or video link" },
423
+ },
424
+ required: ["title", "attendees", "date"],
425
+ },
426
+ };
427
+
428
+ const createReminder = {
429
+ name: "create_reminder",
430
+ description:
431
+ "Set a reminder for the agent or principal. Fires via Slack DM at the specified time.",
432
+ input_schema: {
433
+ type: "object",
434
+ properties: {
435
+ message: { type: "string", description: "Reminder message" },
436
+ when: { type: "string", description: "When to remind (e.g. 'in 2 hours', 'tomorrow 9am', '2026-04-10 14:00')" },
437
+ for_whom: { type: "string", description: "Who to remind (default: principal)" },
438
+ },
439
+ required: ["message", "when"],
440
+ },
441
+ };
442
+
443
+ // ============================================================================
444
+ // 5. ANALYSIS TOOLS
445
+ // ============================================================================
446
+
447
+ const searchFinancial = {
448
+ name: "search_financial",
449
+ description:
450
+ "Look up financial data — runway, burn rate, capital readiness, fundraising pipeline, AUM figures.",
451
+ input_schema: {
452
+ type: "object",
453
+ properties: {
454
+ query: { type: "string", description: "Financial query (e.g. 'current runway', 'fundraising status', 'AUM pipeline')" },
455
+ },
456
+ required: ["query"],
457
+ },
458
+ };
459
+
460
+ const searchPipeline = {
461
+ name: "search_pipeline",
462
+ description:
463
+ "Search the commercial/relationship pipeline — deal stages, partner status, investor conversations.",
464
+ input_schema: {
465
+ type: "object",
466
+ properties: {
467
+ query: { type: "string", description: "Pipeline query (e.g. 'acquisition targets status', 'investor conversations this month')" },
468
+ stage: { type: "string", enum: ["all", "prospecting", "engaged", "diligence", "closing", "closed"], description: "Filter by stage" },
469
+ },
470
+ required: ["query"],
471
+ },
472
+ };
473
+
474
+ const searchEngineering = {
475
+ name: "search_engineering",
476
+ description:
477
+ "Search engineering health data — repo activity, PR status, delivery confidence, tech debt, deployment status.",
478
+ input_schema: {
479
+ type: "object",
480
+ properties: {
481
+ query: { type: "string", description: "Engineering query (e.g. 'adaptic-engine PR status', 'deployment blockers', 'tech debt priority')" },
482
+ repo: { type: "string", description: "Specific repository name (optional)" },
483
+ },
484
+ required: ["query"],
485
+ },
486
+ };
487
+
488
+ const searchHiring = {
489
+ name: "search_hiring",
490
+ description:
491
+ "Search hiring pipeline — open roles, candidate status, interview pipeline, offer tracking.",
492
+ input_schema: {
493
+ type: "object",
494
+ properties: {
495
+ query: { type: "string", description: "Hiring query (e.g. 'open engineering roles', 'candidates for CFO', 'offers pending')" },
496
+ status: { type: "string", enum: ["all", "open", "screening", "interviewing", "offer", "filled"], description: "Filter by status" },
497
+ },
498
+ required: ["query"],
499
+ },
500
+ };
501
+
502
+ const searchRisk = {
503
+ name: "search_risk",
504
+ description:
505
+ "Search the enterprise risk register — active risks, mitigations, severity, ownership.",
506
+ input_schema: {
507
+ type: "object",
508
+ properties: {
509
+ query: { type: "string", description: "Risk query (e.g. 'critical risks', 'regulatory risks', 'unmitigated risks')" },
510
+ severity: { type: "string", enum: ["all", "critical", "high", "medium", "low"], description: "Filter by severity" },
511
+ },
512
+ required: ["query"],
513
+ },
514
+ };
515
+
516
+ // ============================================================================
517
+ // 6. DOCUMENT GENERATION TOOLS
518
+ // ============================================================================
519
+
520
+ const generateMemo = {
521
+ name: "generate_memo",
522
+ description:
523
+ "Generate a branded PDF memo or brief. Saved to outputs/drafts/ and optionally shared via Slack.",
524
+ input_schema: {
525
+ type: "object",
526
+ properties: {
527
+ title: { type: "string", description: "Document title" },
528
+ content: { type: "string", description: "Memo content (markdown)" },
529
+ type: { type: "string", enum: ["memo", "brief", "board-pack", "letter", "investor"], description: "Document type" },
530
+ share_to: { type: "string", description: "Slack channel or person to share with (optional)" },
531
+ },
532
+ required: ["title", "content"],
533
+ },
534
+ };
535
+
536
+ const generateReport = {
537
+ name: "generate_report",
538
+ description:
539
+ "Generate an analytical report by aggregating data from dashboards, queues, and operational state.",
540
+ input_schema: {
541
+ type: "object",
542
+ properties: {
543
+ report_type: {
544
+ type: "string",
545
+ enum: ["executive-summary", "engineering-health", "hiring-pipeline", "strategy-scorecard", "leadership-accountability", "risk-register", "custom"],
546
+ description: "Report type",
547
+ },
548
+ custom_query: { type: "string", description: "For custom reports — what to analyse" },
549
+ time_range: { type: "string", description: "Time range (default: current)" },
550
+ },
551
+ required: ["report_type"],
552
+ },
553
+ };
554
+
555
+ // ============================================================================
556
+ // 7. ORG (COHORT) TOOLS — generated from lib/org/tool-surface.mjs
557
+ // ============================================================================
558
+ //
559
+ // ONE curated table serves both the cohort-mcp server and this native
560
+ // function-call path. The schemas in the table are already Claude
561
+ // `tool_use`-shaped, so the projection below is a plain field pick — the two
562
+ // planes cannot drift. The additive families gate on the vendored protocol
563
+ // (tool-surface: emailFamilyAvailable / artifactFamilyAvailable /
564
+ // deskFamilyAvailable) — email tools, artifact tools, and the agent-desk tools
565
+ // (mail app / files / calendar / crm / books / meetings) register only when
566
+ // their family is vendored.
567
+
568
+ // The CURATED org tools are import-time stable (family gating is fixed per the
569
+ // vendored protocol), so a one-time snapshot is fine here. The integration tools
570
+ // getOrgTools now appends are EXCLUDED from this frozen list (`!t.integration`)
571
+ // and added fresh per getToolsForAccessLevel call, below — so the native plane
572
+ // hot-refreshes them without a restart and they're never double-counted (SP5).
573
+ const ORG_TOOL_DEFS = getOrgTools({}).filter((t) => !t.integration);
574
+ const asClaudeTool = ({ name, description, input_schema }) => ({ name, description, input_schema });
575
+ const orgTools = ORG_TOOL_DEFS.map(asClaudeTool);
576
+ const orgToolsByAccess = (access) =>
577
+ ORG_TOOL_DEFS.filter((t) => t.access === access).map(asClaudeTool);
578
+
579
+ /**
580
+ * The workspace's GRANTED integration tools (SP5), read FRESH from the shared
581
+ * disk cache (state/org/toolset.json) on each call so the native plane reflects a
582
+ * newly-granted tool WITHOUT a daemon/session restart — the curated tools above
583
+ * are the only import-time-frozen part; the integration set is the sole runtime-
584
+ * mutable part. They are access "write", so they ride the write tiers (ceo +
585
+ * leadership) exactly like orgWriteTools. Fail-open to [].
586
+ * @returns {Array<{name:string,description:string,input_schema:object}>}
587
+ */
588
+ function currentOrgIntegrationTools() {
589
+ try {
590
+ return loadIntegrationToolsFromDisk().map(asClaudeTool);
591
+ } catch {
592
+ return [];
593
+ }
594
+ }
595
+
596
+ // Reads → every level's lookup set; writes → leadership+; the escape hatches
597
+ // (org_rpc / org_read, access "admin") → CEO only. hq's server-side scope gate
598
+ // applies regardless — the native clamp only narrows, never grants.
599
+ const orgReadTools = orgToolsByAccess("read");
600
+ const orgWriteTools = orgToolsByAccess("write");
601
+ const orgAdminTools = orgToolsByAccess("admin");
602
+
603
+ // Voice curation: conversation-sized org actions only.
604
+ const ORG_VOICE_NAMES = new Set(["org_whoami", "messaging_history", "messaging_send", "board_ready"]);
605
+ const orgVoiceTools = orgTools.filter((t) => ORG_VOICE_NAMES.has(t.name));
606
+
607
+ // ============================================================================
608
+ // ACCESS LEVEL SCOPING
609
+ // ============================================================================
610
+
611
+ // All lookup/search tools (read-only, safe for any authorised user)
612
+ const lookupTools = [
613
+ searchEmail, searchCalendar, searchFiles, searchMeetings, searchSlack,
614
+ searchWeb, searchDocuments, searchDecisions, lookupPerson, searchRegulatory,
615
+ searchStrategy, searchPrecedents, searchFinancial, searchPipeline,
616
+ searchEngineering, searchHiring, searchRisk,
617
+ ...orgReadTools,
618
+ ];
619
+
620
+ // Write tools (require higher access)
621
+ const writeToolsCeo = [
622
+ slackSend, draftEmail, whatsappSend, smsSend,
623
+ sendVoiceMessage, placeVoiceCall,
624
+ queueUpdate, createActionItem, scheduleMeeting, createReminder,
625
+ generateMemo, generateReport,
626
+ ...orgWriteTools,
627
+ // Escape hatches are deliberately withheld from lower native access levels.
628
+ ...orgAdminTools,
629
+ ];
630
+
631
+ const writeToolsLeadership = [
632
+ slackSend, draftEmail,
633
+ sendVoiceMessage,
634
+ queueUpdate, createActionItem, scheduleMeeting, createReminder,
635
+ ...orgWriteTools,
636
+ ];
637
+
638
+ // Voice-specific tool surface — exposed to Realtime sessions via tool-bridge.
639
+ // rag_search lands here too: voice sessions benefit massively from being
640
+ // able to retrieve specific snippets from the agent's corpus mid-call.
641
+ const voiceTools = [
642
+ slackSend, draftEmail, whatsappSend, smsSend,
643
+ sendVoiceMessage,
644
+ ragSearch,
645
+ queueUpdate, createActionItem, scheduleMeeting,
646
+ ...[searchEmail, searchCalendar, searchSlack, searchDecisions, lookupPerson, searchFinancial, searchPipeline],
647
+ ...orgVoiceTools,
648
+ ];
649
+
650
+ // Known access-level keys. "default" is the least-privilege fallback.
651
+ export const KNOWN_ACCESS_LEVELS = ["ceo", "leadership", "voice", "default"];
652
+
653
+ /**
654
+ * Normalise an access-level key to a known, safe value.
655
+ *
656
+ * Access-level lookups used to be case-sensitive and silently returned an EMPTY
657
+ * tool set for any unrecognised key — so "CEO" (instead of "ceo") yielded zero
658
+ * tools, a silent UNDER-privilege footgun. This normaliser:
659
+ * - lowercases/trims the input so "CEO", " ceo ", etc. all map to "ceo"
660
+ * - coerces any truly-unknown / invalid level to the least-privilege
661
+ * "default" (NEVER empty, NEVER throws), logging a warning so the
662
+ * misconfiguration is visible
663
+ *
664
+ * Known levels (ceo / leadership / voice / default) are returned unchanged.
665
+ *
666
+ * @param {string} accessLevel - Raw access-level key (any casing/whitespace).
667
+ * @returns {string} A guaranteed-known access-level key.
668
+ */
669
+ export function normalizeAccessLevel(accessLevel) {
670
+ const key =
671
+ typeof accessLevel === "string" ? accessLevel.trim().toLowerCase() : "";
672
+ if (KNOWN_ACCESS_LEVELS.includes(key)) {
673
+ return key;
674
+ }
675
+ // Unknown / empty / non-string: fall back to least privilege.
676
+ console.warn(
677
+ `[tool-definitions] Unknown access level ${JSON.stringify(
678
+ accessLevel,
679
+ )}; coercing to least-privilege "default".`,
680
+ );
681
+ return "default";
682
+ }
683
+
684
+ /**
685
+ * Get tools available for a caller's access level.
686
+ *
687
+ * The level is normalised first (case/whitespace-insensitive); an unknown level
688
+ * coerces to the least-privilege "default" surface rather than an empty set.
689
+ *
690
+ * @param {string} accessLevel - "ceo", "leadership", "voice", or "default"
691
+ * @returns {Array<object>} Claude API tool schemas
692
+ */
693
+ export function getToolsForAccessLevel(accessLevel) {
694
+ // Granted integration tools (write tier) are read fresh from the disk cache
695
+ // on every call so a newly-granted tool appears without a restart (SP5).
696
+ const integrationTools = currentOrgIntegrationTools();
697
+ switch (normalizeAccessLevel(accessLevel)) {
698
+ case "ceo":
699
+ return [...writeToolsCeo, ...integrationTools, ...lookupTools];
700
+ case "leadership":
701
+ return [...writeToolsLeadership, ...integrationTools, ...lookupTools];
702
+ case "voice":
703
+ // Curated set for Realtime voice sessions — communication +
704
+ // common lookups, no document-generation (long-form artefacts
705
+ // don't fit conversational voice flow).
706
+ return [...voiceTools];
707
+ case "default":
708
+ default:
709
+ // normalizeAccessLevel guarantees a known key, so "default" is the only
710
+ // path here — read-only search and lookup tools.
711
+ return [...lookupTools];
712
+ }
713
+ }
714
+
715
+ /**
716
+ * Get tool names for an access level.
717
+ * @param {string} accessLevel
718
+ * @returns {string[]}
719
+ */
720
+ export function getToolNamesForAccessLevel(accessLevel) {
721
+ return getToolsForAccessLevel(accessLevel).map((t) => t.name);
722
+ }
723
+
724
+ /**
725
+ * Get all tool definitions (for documentation / init-maestro generation).
726
+ * @returns {{ communication: object[], search: object[], knowledge: object[], operations: object[], analysis: object[], documents: object[], org: object[] }}
727
+ */
728
+ export function getAllToolsByCategory() {
729
+ return {
730
+ communication: [slackSend, draftEmail, whatsappSend, smsSend, sendVoiceMessage, placeVoiceCall],
731
+ search: [searchEmail, searchCalendar, searchFiles, searchMeetings, searchSlack, searchWeb, searchDocuments, ragSearch],
732
+ knowledge: [searchDecisions, lookupPerson, searchRegulatory, searchStrategy, searchPrecedents],
733
+ operations: [queueUpdate, createActionItem, scheduleMeeting, createReminder],
734
+ analysis: [searchFinancial, searchPipeline, searchEngineering, searchHiring, searchRisk],
735
+ documents: [generateMemo, generateReport],
736
+ org: [...orgTools],
737
+ };
738
+ }