@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.
- package/.claude/commands/init-agent.md +104 -0
- package/.claude/commands/init-maestro.md +1187 -0
- package/.claude/settings.json +161 -0
- package/.env.example +216 -0
- package/README.md +632 -0
- package/agents/browser-operator/agent.md +52 -0
- package/agents/calendar-ops/agent.md +50 -0
- package/agents/communications/agent.md +96 -0
- package/agents/decision-log/agent.md +65 -0
- package/agents/desktop-operator/agent.md +59 -0
- package/agents/gmail-operator/agent.md +62 -0
- package/agents/inbound-dispatcher/agent.md +66 -0
- package/agents/inbox-processor/agent.md +39 -0
- package/agents/pmo-execution/agent.md +60 -0
- package/agents/session-spawner/agent.md +64 -0
- package/agents/slack-operator/agent.md +60 -0
- package/agents/whatsapp-operator/agent.md +60 -0
- package/agents/workflow-automation/agent.md +61 -0
- package/archetypes/altitudes/c-suite.yaml +58 -0
- package/archetypes/altitudes/founder.yaml +68 -0
- package/archetypes/altitudes/senior-manager.yaml +63 -0
- package/archetypes/altitudes/svp.yaml +60 -0
- package/archetypes/altitudes/vp.yaml +50 -0
- package/archetypes/archetype.schema.json +77 -0
- package/archetypes/base.yaml +47 -0
- package/archetypes/capabilities/commercial-leader.yaml +159 -0
- package/archetypes/capabilities/compliance-officer.yaml +159 -0
- package/archetypes/capabilities/executive-operator.yaml +169 -0
- package/archetypes/capabilities/finance-leader.yaml +162 -0
- package/archetypes/capabilities/operations-leader.yaml +154 -0
- package/archetypes/capabilities/product-leader.yaml +148 -0
- package/archetypes/capabilities/technical-leader.yaml +146 -0
- package/archetypes/functions/commercial-leader.yaml +62 -0
- package/archetypes/functions/compliance-officer.yaml +64 -0
- package/archetypes/functions/executive-operator.yaml +70 -0
- package/archetypes/functions/finance-leader.yaml +70 -0
- package/archetypes/functions/operations-leader.yaml +62 -0
- package/archetypes/functions/product-leader.yaml +61 -0
- package/archetypes/functions/technical-leader.yaml +57 -0
- package/bin/cohort-mcp.mjs +81 -0
- package/bin/maestro.mjs +3516 -0
- package/bin/maestro.test.mjs +1015 -0
- package/desktop-control/README.md +56 -0
- package/desktop-control/app-profiles/gmail.yaml +120 -0
- package/desktop-control/app-profiles/slack.yaml +315 -0
- package/desktop-control/app-profiles/whatsapp.yaml +107 -0
- package/docs/architecture/agent-topology.md +2239 -0
- package/docs/architecture/archetype-agent-factory.md +110 -0
- package/docs/architecture/collective-memory-and-org-mesh.md +115 -0
- package/docs/architecture/continuous-monitoring.md +221 -0
- package/docs/architecture/mcp-capability-map.md +585 -0
- package/docs/architecture/system-architecture.md +1272 -0
- package/docs/company-context/README.md +40 -0
- package/docs/guides/agent-persona-setup.md +600 -0
- package/docs/guides/agents-observe-setup.md +64 -0
- package/docs/guides/billing-console-keys.md +88 -0
- package/docs/guides/ccxray-diagnostics.md +65 -0
- package/docs/guides/channel-bus.md +127 -0
- package/docs/guides/claude-mem-setup.md +79 -0
- package/docs/guides/claude-pace-setup.md +56 -0
- package/docs/guides/claudraband-sessions.md +98 -0
- package/docs/guides/clawteam-swarm.md +116 -0
- package/docs/guides/code-review-graph-setup.md +86 -0
- package/docs/guides/email-setup.md +431 -0
- package/docs/guides/mac-mini.md +119 -0
- package/docs/guides/media-generation-setup.md +349 -0
- package/docs/guides/model-routing.md +162 -0
- package/docs/guides/observability-otel.md +265 -0
- package/docs/guides/org-onboarding.md +132 -0
- package/docs/guides/outbound-governance-setup.md +437 -0
- package/docs/guides/pdf-generation-setup.md +315 -0
- package/docs/guides/poller-daemon-setup.md +563 -0
- package/docs/guides/rag-context-setup.md +459 -0
- package/docs/guides/self-optimization-pattern.md +82 -0
- package/docs/guides/setup-wizard.md +178 -0
- package/docs/guides/slack-setup.md +350 -0
- package/docs/guides/telegram-setup.md +227 -0
- package/docs/guides/twilio-subaccounts-setup.md +223 -0
- package/docs/guides/verification.md +128 -0
- package/docs/guides/voice-mode.md +188 -0
- package/docs/guides/voice-sms-setup.md +698 -0
- package/docs/guides/webhook-relay-setup.md +349 -0
- package/docs/guides/whatsapp-setup.md +288 -0
- package/docs/prompts/board-pack-cover-template.md +36 -0
- package/docs/prompts/decision-recommendation-template.md +88 -0
- package/docs/prompts/followup-message-template.md +141 -0
- package/docs/prompts/investor-letter-template.md +52 -0
- package/docs/prompts/morning-brief-template.md +82 -0
- package/docs/prompts/presentation-template.md +58 -0
- package/docs/prompts/weekly-strategic-memo-template.md +104 -0
- package/docs/research/hallucinated-tool-output-investigation.md +151 -0
- package/docs/runbooks/backup-restore.md +205 -0
- package/docs/runbooks/cohort-cutover.md +129 -0
- package/docs/runbooks/fleet-operations.md +200 -0
- package/docs/runbooks/incident-response.md +226 -0
- package/docs/runbooks/mac-mini-bootstrap.md +431 -0
- package/docs/runbooks/perpetual-operations.md +509 -0
- package/docs/runbooks/recovery-and-failover.md +260 -0
- package/framework-features.json +267 -0
- package/ingest/README.md +87 -0
- package/lib/action-executor.js +689 -0
- package/lib/action-executor.test.mjs +871 -0
- package/lib/agent-root.mjs +37 -0
- package/lib/archetype.mjs +236 -0
- package/lib/archetype.test.mjs +132 -0
- package/lib/autonomy.mjs +114 -0
- package/lib/autonomy.test.mjs +66 -0
- package/lib/backlog.mjs +358 -0
- package/lib/backlog.test.mjs +266 -0
- package/lib/budget-guard.mjs +279 -0
- package/lib/budget-guard.test.mjs +291 -0
- package/lib/cadence-bus-schedule.test.mjs +194 -0
- package/lib/cadence-bus.mjs +1120 -0
- package/lib/cadence-bus.test.mjs +720 -0
- package/lib/cadences.mjs +205 -0
- package/lib/cadences.test.mjs +125 -0
- package/lib/capability.mjs +154 -0
- package/lib/capability.test.mjs +78 -0
- package/lib/channels/base-adapter.mjs +719 -0
- package/lib/channels/base-adapter.test.mjs +590 -0
- package/lib/channels/channel.mjs +128 -0
- package/lib/channels/channels.test.mjs +371 -0
- package/lib/channels/contract.mjs +215 -0
- package/lib/channels/contract.test.mjs +137 -0
- package/lib/channels/conversation-resolver.mjs +95 -0
- package/lib/channels/gmail/adapter.mjs +87 -0
- package/lib/channels/inbox-item.mjs +255 -0
- package/lib/channels/inbox-item.test.mjs +335 -0
- package/lib/channels/index.mjs +94 -0
- package/lib/channels/orgmail/adapter.mjs +353 -0
- package/lib/channels/orgmail/adapter.test.mjs +311 -0
- package/lib/channels/pairing.mjs +363 -0
- package/lib/channels/pairing.test.mjs +270 -0
- package/lib/channels/registry.mjs +164 -0
- package/lib/channels/slack/adapter.mjs +317 -0
- package/lib/channels/slack-adapter.test.mjs +212 -0
- package/lib/channels/sms/adapter.mjs +43 -0
- package/lib/channels/telegram/adapter.mjs +432 -0
- package/lib/channels/telegram-adapter.test.mjs +306 -0
- package/lib/channels/voice/adapter.mjs +301 -0
- package/lib/channels/voice/adapter.test.mjs +278 -0
- package/lib/channels/whatsapp/adapter-baileys.mjs +587 -0
- package/lib/channels/whatsapp/adapter-baileys.test.mjs +359 -0
- package/lib/channels/whatsapp/adapter-twilio.mjs +65 -0
- package/lib/channels/whatsapp/baileys-typing.test.mjs +154 -0
- package/lib/charter.mjs +256 -0
- package/lib/charter.test.mjs +89 -0
- package/lib/claude-bin.mjs +134 -0
- package/lib/claude-bin.test.mjs +75 -0
- package/lib/collective/capture.mjs +185 -0
- package/lib/collective/capture.test.mjs +121 -0
- package/lib/collective/cards.mjs +201 -0
- package/lib/collective/cards.test.mjs +114 -0
- package/lib/collective/config.mjs +186 -0
- package/lib/collective/config.test.mjs +123 -0
- package/lib/collective/global-config.mjs +113 -0
- package/lib/collective/global-config.test.mjs +75 -0
- package/lib/collective/presence.mjs +201 -0
- package/lib/collective/presence.test.mjs +95 -0
- package/lib/collective/recall.mjs +215 -0
- package/lib/collective/recall.test.mjs +116 -0
- package/lib/comms/send-gate.mjs +554 -0
- package/lib/comms/send-gate.test.mjs +577 -0
- package/lib/comms.mjs +67 -0
- package/lib/comms.test.mjs +41 -0
- package/lib/diagnostics/alerts.mjs +424 -0
- package/lib/diagnostics/alerts.test.mjs +318 -0
- package/lib/diagnostics/backup-freshness.mjs +188 -0
- package/lib/diagnostics/backup-freshness.test.mjs +185 -0
- package/lib/diagnostics/counters.mjs +269 -0
- package/lib/diagnostics/counters.test.mjs +206 -0
- package/lib/diagnostics/events.mjs +188 -0
- package/lib/diagnostics/events.test.mjs +290 -0
- package/lib/diagnostics/otel.mjs +237 -0
- package/lib/diagnostics/otel.test.mjs +196 -0
- package/lib/diagnostics/trace.mjs +216 -0
- package/lib/diagnostics/trace.test.mjs +251 -0
- package/lib/env-compat.mjs +74 -0
- package/lib/env-compat.test.mjs +104 -0
- package/lib/feature-init.mjs +331 -0
- package/lib/fs-atomic.mjs +112 -0
- package/lib/fs-atomic.test.mjs +72 -0
- package/lib/fs-ownership.mjs +111 -0
- package/lib/fs-ownership.test.mjs +158 -0
- package/lib/hooks/bus.mjs +347 -0
- package/lib/hooks/bus.test.mjs +387 -0
- package/lib/index.js +16 -0
- package/lib/learning/config.mjs +106 -0
- package/lib/learning/config.test.mjs +75 -0
- package/lib/learning/counters.mjs +156 -0
- package/lib/learning/counters.test.mjs +69 -0
- package/lib/learning/curator-consolidate.test.mjs +238 -0
- package/lib/learning/curator.mjs +453 -0
- package/lib/learning/curator.test.mjs +106 -0
- package/lib/learning/log.mjs +40 -0
- package/lib/learning/reflect.mjs +534 -0
- package/lib/learning/reflect.test.mjs +0 -0
- package/lib/learning/session-index.mjs +352 -0
- package/lib/learning/session-index.test.mjs +125 -0
- package/lib/learning/skill-writer.mjs +474 -0
- package/lib/learning/skill-writer.test.mjs +210 -0
- package/lib/mcp/server.mjs +328 -0
- package/lib/mcp/server.test.mjs +400 -0
- package/lib/model-router/auth-profiles.mjs +758 -0
- package/lib/model-router/auth-profiles.test.mjs +580 -0
- package/lib/model-router/catalog/anthropic.yaml +153 -0
- package/lib/model-router/catalog/deepseek.yaml +86 -0
- package/lib/model-router/catalog/moonshot.yaml +81 -0
- package/lib/model-router/catalog/qwen.yaml +114 -0
- package/lib/model-router/catalog.mjs +925 -0
- package/lib/model-router/catalog.test.mjs +385 -0
- package/lib/model-router/economics.mjs +564 -0
- package/lib/model-router/economics.test.mjs +344 -0
- package/lib/model-router/failover.mjs +298 -0
- package/lib/model-router/failover.test.mjs +439 -0
- package/lib/model-router/health.mjs +453 -0
- package/lib/model-router/health.test.mjs +338 -0
- package/lib/model-router/integration-coverage.test.mjs +829 -0
- package/lib/model-router/integration.test.mjs +564 -0
- package/lib/model-router/ledger.mjs +402 -0
- package/lib/model-router/ledger.test.mjs +382 -0
- package/lib/model-router/llm-task.mjs +515 -0
- package/lib/model-router/llm-task.test.mjs +392 -0
- package/lib/model-router/org-credentials.mjs +260 -0
- package/lib/model-router/org-credentials.test.mjs +265 -0
- package/lib/model-router/pricing-refresh.mjs +463 -0
- package/lib/model-router/pricing-refresh.test.mjs +286 -0
- package/lib/model-router/reconcile.mjs +429 -0
- package/lib/model-router/reconcile.test.mjs +316 -0
- package/lib/model-router/repair.mjs +471 -0
- package/lib/model-router/repair.test.mjs +180 -0
- package/lib/model-router/resolve.mjs +1206 -0
- package/lib/model-router/spawn.mjs +497 -0
- package/lib/model-router/spawn.test.mjs +425 -0
- package/lib/model-router/taxonomy.mjs +893 -0
- package/lib/model-router/taxonomy.test.mjs +410 -0
- package/lib/model-router.mjs +677 -0
- package/lib/model-router.test.mjs +907 -0
- package/lib/org/activity.mjs +211 -0
- package/lib/org/activity.test.mjs +134 -0
- package/lib/org/approvals.mjs +448 -0
- package/lib/org/approvals.test.mjs +216 -0
- package/lib/org/awareness.mjs +222 -0
- package/lib/org/awareness.test.mjs +159 -0
- package/lib/org/board.mjs +229 -0
- package/lib/org/board.test.mjs +177 -0
- package/lib/org/bootstrap-context.mjs +169 -0
- package/lib/org/bootstrap-context.test.mjs +153 -0
- package/lib/org/client.mjs +1628 -0
- package/lib/org/client.test.mjs +1107 -0
- package/lib/org/cohort-client.mjs +67 -0
- package/lib/org/cohort-client.test.mjs +126 -0
- package/lib/org/cost-sync.mjs +227 -0
- package/lib/org/cost-sync.test.mjs +153 -0
- package/lib/org/doctor.mjs +212 -0
- package/lib/org/doctor.test.mjs +212 -0
- package/lib/org/handoff.mjs +293 -0
- package/lib/org/handoff.test.mjs +269 -0
- package/lib/org/integration-tools.mjs +182 -0
- package/lib/org/integration-tools.test.mjs +160 -0
- package/lib/org/keys.mjs +131 -0
- package/lib/org/keys.test.mjs +92 -0
- package/lib/org/knowledge.mjs +463 -0
- package/lib/org/knowledge.test.mjs +319 -0
- package/lib/org/leases.mjs +335 -0
- package/lib/org/leases.test.mjs +235 -0
- package/lib/org/mesh-integration.test.mjs +127 -0
- package/lib/org/mesh.mjs +459 -0
- package/lib/org/mesh.test.mjs +345 -0
- package/lib/org/messaging.mjs +503 -0
- package/lib/org/messaging.test.mjs +238 -0
- package/lib/org/policy.mjs +345 -0
- package/lib/org/policy.test.mjs +237 -0
- package/lib/org/protocol.checksum +1 -0
- package/lib/org/protocol.checksum.test.mjs +90 -0
- package/lib/org/protocol.mjs +967 -0
- package/lib/org/protocol.test.mjs +264 -0
- package/lib/org/registry.mjs +194 -0
- package/lib/org/registry.test.mjs +100 -0
- package/lib/org/tool-surface-integration.test.mjs +120 -0
- package/lib/org/tool-surface.mjs +2535 -0
- package/lib/org/tool-surface.test.mjs +589 -0
- package/lib/org/ui-parity.mjs +3236 -0
- package/lib/org/ui-parity.test.mjs +348 -0
- package/lib/org/verify.mjs +176 -0
- package/lib/org/verify.test.mjs +194 -0
- package/lib/rag/embed.mjs +188 -0
- package/lib/rag/indexer.mjs +425 -0
- package/lib/rag/rag.test.mjs +505 -0
- package/lib/rag/search.mjs +475 -0
- package/lib/rate-guard.mjs +246 -0
- package/lib/rate-guard.test.mjs +201 -0
- package/lib/render.mjs +112 -0
- package/lib/render.test.mjs +68 -0
- package/lib/resource-governor.mjs +297 -0
- package/lib/resource-governor.test.mjs +262 -0
- package/lib/scheduling/dynamic-jobs.mjs +675 -0
- package/lib/scheduling/dynamic-jobs.test.mjs +344 -0
- package/lib/scheduling/jitter.mjs +0 -0
- package/lib/scheduling/jitter.test.mjs +140 -0
- package/lib/secrets/broker.mjs +315 -0
- package/lib/secrets/broker.test.mjs +280 -0
- package/lib/secrets/providers.mjs +461 -0
- package/lib/secrets/providers.test.mjs +274 -0
- package/lib/security/audit-engine.mjs +684 -0
- package/lib/security/audit-engine.test.mjs +389 -0
- package/lib/security/coerce-args.mjs +552 -0
- package/lib/security/coerce-args.test.mjs +281 -0
- package/lib/security/dangerous-tools.mjs +97 -0
- package/lib/security/dangerous-tools.test.mjs +68 -0
- package/lib/security/external-content.mjs +145 -0
- package/lib/security/external-content.test.mjs +67 -0
- package/lib/security/redact.mjs +592 -0
- package/lib/security/redact.test.mjs +441 -0
- package/lib/security/secret-equal.mjs +73 -0
- package/lib/security/secret-equal.test.mjs +55 -0
- package/lib/session-permissions.mjs +101 -0
- package/lib/session-permissions.test.mjs +100 -0
- package/lib/setup/claude-probe.mjs +74 -0
- package/lib/setup/completeness.mjs +175 -0
- package/lib/setup/completeness.test.mjs +110 -0
- package/lib/setup/context-pack.mjs +173 -0
- package/lib/setup/context-pack.test.mjs +89 -0
- package/lib/setup/enrich.mjs +277 -0
- package/lib/setup/enrich.test.mjs +115 -0
- package/lib/setup/enroll-from-cohort.mjs +441 -0
- package/lib/setup/enroll-from-cohort.test.mjs +233 -0
- package/lib/setup/integration.test.mjs +162 -0
- package/lib/setup/io.mjs +360 -0
- package/lib/setup/io.test.mjs +77 -0
- package/lib/setup/run-generator.mjs +81 -0
- package/lib/setup/runner.mjs +244 -0
- package/lib/setup/runner.test.mjs +132 -0
- package/lib/setup/sections/comms.mjs +173 -0
- package/lib/setup/sections/company.mjs +120 -0
- package/lib/setup/sections/enrich.mjs +138 -0
- package/lib/setup/sections/identity.mjs +182 -0
- package/lib/setup/sections/identity.test.mjs +140 -0
- package/lib/setup/sections/learning.mjs +153 -0
- package/lib/setup/sections/learning.test.mjs +81 -0
- package/lib/setup/sections/messaging.mjs +219 -0
- package/lib/setup/sections/messaging.test.mjs +127 -0
- package/lib/setup/sections/model.mjs +102 -0
- package/lib/setup/sections/operating-model.mjs +78 -0
- package/lib/setup/sections/org.mjs +475 -0
- package/lib/setup/sections/org.test.mjs +313 -0
- package/lib/setup/sections/orgmail.mjs +173 -0
- package/lib/setup/sections/orgmail.test.mjs +118 -0
- package/lib/setup/sections/recovery.mjs +159 -0
- package/lib/setup/sections/recovery.test.mjs +98 -0
- package/lib/setup/sections/tools.mjs +132 -0
- package/lib/setup/sections/verify.mjs +97 -0
- package/lib/setup/sot.mjs +205 -0
- package/lib/setup/sot.test.mjs +81 -0
- package/lib/setup/state.mjs +151 -0
- package/lib/setup/state.test.mjs +92 -0
- package/lib/singleton.js +229 -0
- package/lib/singleton.test.mjs +135 -0
- package/lib/telemetry/alerts.mjs +216 -0
- package/lib/telemetry/alerts.test.mjs +109 -0
- package/lib/telemetry/collect.mjs +512 -0
- package/lib/telemetry/collect.test.mjs +202 -0
- package/lib/tool-definitions-integration.test.mjs +83 -0
- package/lib/tool-definitions.js +738 -0
- package/lib/tool-definitions.test.mjs +437 -0
- package/lib/util/fetch-timeout.mjs +136 -0
- package/lib/util/fetch-timeout.test.mjs +202 -0
- package/lib/util/reconnect.mjs +343 -0
- package/lib/util/reconnect.test.mjs +369 -0
- package/lib/util/unhandled.mjs +205 -0
- package/lib/util/unhandled.test.mjs +216 -0
- package/lib/voice/context-loader.mjs +466 -0
- package/lib/voice/index.mjs +100 -0
- package/lib/voice/openai-realtime.mjs +510 -0
- package/lib/voice/outbound.mjs +542 -0
- package/lib/voice/outbound.test.mjs +69 -0
- package/lib/voice/post-call-brief.mjs +428 -0
- package/lib/voice/provider.mjs +52 -0
- package/lib/voice/session-rotation.mjs +257 -0
- package/lib/voice/stt.mjs +161 -0
- package/lib/voice/stt.test.mjs +226 -0
- package/lib/voice/tool-bridge.mjs +370 -0
- package/lib/voice/tts.mjs +104 -0
- package/lib/voice/twilio-sip-bridge.mjs +288 -0
- package/lib/voice/voice.test.mjs +990 -0
- package/mcp/README.md +80 -0
- package/package.json +151 -0
- package/plugins/maestro-skills/plugin.json +139 -0
- package/plugins/maestro-skills/skills/agents-observe.md +110 -0
- package/plugins/maestro-skills/skills/board-deck.md +68 -0
- package/plugins/maestro-skills/skills/books-close.md +77 -0
- package/plugins/maestro-skills/skills/brand-steward.md +121 -0
- package/plugins/maestro-skills/skills/calendar-plan.md +57 -0
- package/plugins/maestro-skills/skills/call-working-sessions.md +124 -0
- package/plugins/maestro-skills/skills/ccxray-diagnostics.md +91 -0
- package/plugins/maestro-skills/skills/claude-pace.md +61 -0
- package/plugins/maestro-skills/skills/code-review-graph.md +99 -0
- package/plugins/maestro-skills/skills/crm-pipeline.md +65 -0
- package/plugins/maestro-skills/skills/decision-brief.md +89 -0
- package/plugins/maestro-skills/skills/directory-hygiene.md +125 -0
- package/plugins/maestro-skills/skills/draft-comms.md +84 -0
- package/plugins/maestro-skills/skills/evening-wrap.md +53 -0
- package/plugins/maestro-skills/skills/files-find.md +65 -0
- package/plugins/maestro-skills/skills/generative-ui.md +228 -0
- package/plugins/maestro-skills/skills/hiring-triage.md +74 -0
- package/plugins/maestro-skills/skills/inbox-triage.md +61 -0
- package/plugins/maestro-skills/skills/mail-triage.md +86 -0
- package/plugins/maestro-skills/skills/morning-brief.md +54 -0
- package/plugins/maestro-skills/skills/native-artifacts.md +157 -0
- package/plugins/maestro-skills/skills/org-board.md +133 -0
- package/plugins/maestro-skills/skills/org-credential.md +68 -0
- package/plugins/maestro-skills/skills/org-recall.md +81 -0
- package/plugins/maestro-skills/skills/pipeline-review.md +76 -0
- package/plugins/maestro-skills/skills/regulatory-status.md +81 -0
- package/plugins/maestro-skills/skills/router-why.md +78 -0
- package/plugins/maestro-skills/skills/schedule-meeting.md +91 -0
- package/plugins/maestro-skills/skills/session-search.md +71 -0
- package/plugins/maestro-skills/skills/set-reminder.md +93 -0
- package/plugins/maestro-skills/skills/slack-followup.md +64 -0
- package/plugins/maestro-skills/skills/team-activity.md +86 -0
- package/plugins/maestro-skills/skills/weekly-memo.md +70 -0
- package/policies/action-classification.yaml +114 -0
- package/policies/ai-disclosure.yaml +294 -0
- package/policies/communication-style.md +139 -0
- package/policies/information-barriers.yaml +118 -0
- package/policies/prompt-injection-defence.yaml +138 -0
- package/public/assets/icon-dark.png +0 -0
- package/public/assets/icon-dark.svg +9 -0
- package/public/assets/icon-light.svg +9 -0
- package/public/assets/logo-dark.svg +15 -0
- package/public/assets/logo-light.svg +15 -0
- package/scaffold/.mcp.json +7 -0
- package/scaffold/CLAUDE.md +368 -0
- package/scaffold/config/agent.json +55 -0
- package/scaffold/config/agent.ts +76 -0
- package/scaffold/config/agent.ts.example +89 -0
- package/scaffold/config/alerts.yaml +23 -0
- package/scaffold/config/allowlist.yaml.example +25 -0
- package/scaffold/config/caller-id-map.yaml +46 -0
- package/scaffold/config/collective.yaml +49 -0
- package/scaffold/config/company.json +20 -0
- package/scaffold/config/known-agents.json +6 -0
- package/scaffold/config/learning.yaml +55 -0
- package/scaffold/config/model-routing.yaml.example +104 -0
- package/scaffold/config/org.yaml +25 -0
- package/scaffold/config/orgmail.yaml.example +19 -0
- package/scaffold/config/recovery.yaml +72 -0
- package/scaffold/config/secrets.yaml +27 -0
- package/scaffold/config/slack.yaml.example +35 -0
- package/scaffold/config/telegram.yaml.example +38 -0
- package/scaffold/config/voice.yaml.example +89 -0
- package/scaffold/config/whatsapp.yaml.example +39 -0
- package/schedules/README.md +49 -0
- package/schedules/triggers/backlog-executor.md +102 -0
- package/schedules/triggers/brand-steward.md +72 -0
- package/schedules/triggers/daily-evening-wrap.md +159 -0
- package/schedules/triggers/daily-midday-sweep.md +58 -0
- package/schedules/triggers/daily-morning-brief.md +55 -0
- package/schedules/triggers/directory-hygiene.md +81 -0
- package/schedules/triggers/dynamic-jobs.md +40 -0
- package/schedules/triggers/inbox-processor.md +115 -0
- package/schedules/triggers/meeting-action-capture.md +60 -0
- package/schedules/triggers/meeting-prep.md +69 -0
- package/schedules/triggers/messaging-inbound.md +50 -0
- package/schedules/triggers/org-pulse.md +24 -0
- package/schedules/triggers/quarterly-self-assessment.md +54 -0
- package/schedules/triggers/weekly-engineering-health.md +37 -0
- package/schedules/triggers/weekly-execution.md +65 -0
- package/schedules/triggers/weekly-hiring.md +53 -0
- package/schedules/triggers/weekly-priorities.md +38 -0
- package/schedules/triggers/weekly-strategic-memo.md +124 -0
- package/scripts/archive-email.sh +55 -0
- package/scripts/cadence/cadence-status.mjs +36 -0
- package/scripts/cadence/enqueue-cadence-tick.mjs +174 -0
- package/scripts/cadence/enqueue-cadence-tick.test.mjs +187 -0
- package/scripts/cadence/launchd-cadence-wrapper.sh +85 -0
- package/scripts/cadence/launchd-cloud-relay-wrapper.sh +95 -0
- package/scripts/cadence/launchd-socket-mode-wrapper.sh +95 -0
- package/scripts/ci/check-docs-accuracy.mjs +493 -0
- package/scripts/ci/check-docs-accuracy.test.mjs +409 -0
- package/scripts/ci/check-exports-exist.mjs +140 -0
- package/scripts/ci/check-files-exist.mjs +107 -0
- package/scripts/ci/check-no-build-artifacts.mjs +111 -0
- package/scripts/ci/check-no-build-artifacts.test.mjs +71 -0
- package/scripts/ci/check-no-confidential.mjs +198 -0
- package/scripts/ci/check-no-conflict-markers.mjs +169 -0
- package/scripts/ci/check-no-residual-identity.mjs +163 -0
- package/scripts/ci/check-no-residual-identity.test.mjs +89 -0
- package/scripts/ci/check-tarball-fidelity.mjs +205 -0
- package/scripts/ci/check-unresolved-tokens.mjs +83 -0
- package/scripts/ci/check.mjs +109 -0
- package/scripts/ci/check.test.mjs +194 -0
- package/scripts/ci/run-coverage.mjs +82 -0
- package/scripts/ci/run-tests.mjs +71 -0
- package/scripts/cloud-relay/README.md +59 -0
- package/scripts/cloud-relay/index.mjs +233 -0
- package/scripts/cloud-relay/package.json +15 -0
- package/scripts/cloud-relay/railway.json +13 -0
- package/scripts/cloud-relay/voice/README.md +94 -0
- package/scripts/cloud-relay/voice/package-lock.json +39 -0
- package/scripts/cloud-relay/voice/package.json +16 -0
- package/scripts/cloud-relay/voice/railway.json +13 -0
- package/scripts/cloud-relay/voice/server.mjs +532 -0
- package/scripts/collective/hook-runner.mjs +211 -0
- package/scripts/collective/hook-runner.test.mjs +90 -0
- package/scripts/collective/org-pulse.mjs +72 -0
- package/scripts/collective/org-sync.mjs +61 -0
- package/scripts/collective/recall.mjs +45 -0
- package/scripts/collective/who.mjs +30 -0
- package/scripts/comms-monitor.sh +288 -0
- package/scripts/configure-whatsapp-sandbox.sh +201 -0
- package/scripts/continuous-monitor.sh +91 -0
- package/scripts/cost/fleet-digest.mjs +407 -0
- package/scripts/cost/fleet-digest.test.mjs +207 -0
- package/scripts/cost/track-claude-usage.mjs +169 -0
- package/scripts/daemon/agent-daemon.mjs +989 -0
- package/scripts/daemon/agent-daemon.test.mjs +525 -0
- package/scripts/daemon/cadence-consumer-governance.test.mjs +220 -0
- package/scripts/daemon/cadence-consumer.mjs +1080 -0
- package/scripts/daemon/cadence-consumer.test.mjs +770 -0
- package/scripts/daemon/cadence-handlers.mjs +1121 -0
- package/scripts/daemon/cadence-handlers.test.mjs +617 -0
- package/scripts/daemon/classifier.mjs +704 -0
- package/scripts/daemon/classifier.test.mjs +238 -0
- package/scripts/daemon/classify-kind.mjs +54 -0
- package/scripts/daemon/classify-kind.test.mjs +40 -0
- package/scripts/daemon/context-compiler.mjs +605 -0
- package/scripts/daemon/context-compiler.test.mjs +300 -0
- package/scripts/daemon/dispatcher-cooldown.test.mjs +122 -0
- package/scripts/daemon/dispatcher-governance.test.mjs +886 -0
- package/scripts/daemon/dispatcher.mjs +1516 -0
- package/scripts/daemon/health.mjs +72 -0
- package/scripts/daemon/inbox-deferral.mjs +210 -0
- package/scripts/daemon/inbox-deferral.test.mjs +242 -0
- package/scripts/daemon/integration.test.mjs +149 -0
- package/scripts/daemon/launchd-wrapper-generic.sh +96 -0
- package/scripts/daemon/launchd-wrapper-slack-events.sh +37 -0
- package/scripts/daemon/launchd-wrapper.sh +91 -0
- package/scripts/daemon/lib/session-router.mjs +274 -0
- package/scripts/daemon/lib/session-router.test.mjs +295 -0
- package/scripts/daemon/maestro-daemon.mjs +275 -0
- package/scripts/daemon/prompt-builder.mjs +685 -0
- package/scripts/daemon/prompt-builder.test.mjs +213 -0
- package/scripts/daemon/responder.mjs +854 -0
- package/scripts/daemon/session-lock.mjs +721 -0
- package/scripts/daemon/session-lock.test.mjs +252 -0
- package/scripts/daemon/session-outcomes.mjs +640 -0
- package/scripts/daemon/session-outcomes.test.mjs +533 -0
- package/scripts/daemon/typing-registry.mjs +90 -0
- package/scripts/daemon/typing-registry.test.mjs +77 -0
- package/scripts/daemon/voice-webhook-server.mjs +804 -0
- package/scripts/decisions/capture-decision.mjs +116 -0
- package/scripts/disclosure_assessment.py +873 -0
- package/scripts/disclosure_boundaries.py +562 -0
- package/scripts/email-signature-principal.html +52 -0
- package/scripts/email-signature.html +60 -0
- package/scripts/email_quote_thread.py +167 -0
- package/scripts/email_thread_dedup.py +362 -0
- package/scripts/emergency-stop.sh +81 -0
- package/scripts/healthcheck.sh +116 -0
- package/scripts/hooks/block-mcp-cohort-send.sh +15 -0
- package/scripts/hooks/block-mcp-slack-send.sh +7 -0
- package/scripts/hooks/post-action-log.sh +126 -0
- package/scripts/hooks/pre-send-audit.sh +174 -0
- package/scripts/hooks/pre-send-audit.test.mjs +215 -0
- package/scripts/hooks/session-end-log.sh +27 -0
- package/scripts/hooks/session-start-banner.sh +115 -0
- package/scripts/huddle/audio-bridge.mjs +664 -0
- package/scripts/huddle/boot-slack-cdp.sh +102 -0
- package/scripts/huddle/huddle-controller.mjs +942 -0
- package/scripts/huddle/huddle-server.mjs +1229 -0
- package/scripts/huddle/launch-slack.sh +232 -0
- package/scripts/huddle/openai-realtime-bridge.mjs +462 -0
- package/scripts/huddle/package-lock.json +62 -0
- package/scripts/huddle/package.json +22 -0
- package/scripts/huddle/setup-audio.sh +239 -0
- package/scripts/huddle/start-call.mjs +318 -0
- package/scripts/huddle/test-pipeline.mjs +263 -0
- package/scripts/learning/consolidate-skills.mjs +72 -0
- package/scripts/learning/session-search.mjs +125 -0
- package/scripts/llm_email_dedup.py +442 -0
- package/scripts/local-triggers/generate-plists.sh +432 -0
- package/scripts/local-triggers/generate-plists.test.mjs +413 -0
- package/scripts/local-triggers/install-all.sh +49 -0
- package/scripts/local-triggers/plists/.gitkeep +0 -0
- package/scripts/local-triggers/run-trigger.sh +63 -0
- package/scripts/local-triggers/templates/rag-reindex.plist.template +47 -0
- package/scripts/local-triggers/templates/voice-relay-poller.plist.template +54 -0
- package/scripts/local-triggers/templates/voice-tunnel.plist.template +55 -0
- package/scripts/local-triggers/templates/voice-webhook.plist.template +51 -0
- package/scripts/maintenance/backup-to-cloud.sh +124 -0
- package/scripts/maintenance/health-check.sh +377 -0
- package/scripts/media-generation/README.md +105 -0
- package/scripts/media-generation/gemini-image-client.mjs +173 -0
- package/scripts/media-generation/generate-assets.mjs +289 -0
- package/scripts/media-generation/veo-video-client.mjs +219 -0
- package/scripts/org/send-orgmail.mjs +227 -0
- package/scripts/outbound-dedup-cleanup.sh +43 -0
- package/scripts/outbound-dedup.sh +477 -0
- package/scripts/outbound_dedup.py +115 -0
- package/scripts/parse-voice-transcript.mjs +481 -0
- package/scripts/pdf-generation/README.md +63 -0
- package/scripts/pdf-generation/build-document.mjs +247 -0
- package/scripts/pdf-generation/templates/board-pack.latex +136 -0
- package/scripts/pdf-generation/templates/corporate-letter.latex +126 -0
- package/scripts/pdf-generation/templates/memo.latex +114 -0
- package/scripts/poll-slack-events.sh +35 -0
- package/scripts/poller/calendar-poller.mjs +12 -0
- package/scripts/poller/gmail-poller.mjs +192 -0
- package/scripts/poller/imap-client.mjs +289 -0
- package/scripts/poller/inbox-scan-poller.mjs +156 -0
- package/scripts/poller/inbox-scan-poller.test.mjs +231 -0
- package/scripts/poller/index.mjs +73 -0
- package/scripts/poller/intra-session-check.mjs +285 -0
- package/scripts/poller/lib/cloud-relay-dedup.mjs +88 -0
- package/scripts/poller/lib/cloud-relay-dedup.test.mjs +133 -0
- package/scripts/poller/lib/slash-command-handlers.mjs +177 -0
- package/scripts/poller/secondary-gmail-poller.mjs +132 -0
- package/scripts/poller/slack-cloud-relay-client.mjs +368 -0
- package/scripts/poller/slack-poller.mjs +854 -0
- package/scripts/poller/slack-socket-mode.mjs +917 -0
- package/scripts/poller/slack-socket-mode.test.mjs +753 -0
- package/scripts/poller/trigger.mjs +75 -0
- package/scripts/poller/utils.mjs +371 -0
- package/scripts/poller/voice-cloud-relay-client.mjs +179 -0
- package/scripts/poller/voice-poller.mjs +236 -0
- package/scripts/poller-launchd/install.sh +66 -0
- package/scripts/poller-launchd/poller.plist.template +40 -0
- package/scripts/poller-launchd/whatsapp-handler.plist.template +39 -0
- package/scripts/post-interaction-indexer.py +1598 -0
- package/scripts/pre-draft-context.py +994 -0
- package/scripts/pre_draft_lookup.py +258 -0
- package/scripts/rag/build-index.mjs +47 -0
- package/scripts/rag/ingest.mjs +111 -0
- package/scripts/rag/search.mjs +119 -0
- package/scripts/rag-indexer.py +629 -0
- package/scripts/restore-from-backup.sh +248 -0
- package/scripts/restore-from-backup.test.mjs +178 -0
- package/scripts/resume-operations.sh +80 -0
- package/scripts/search-secondary-inbox.py +181 -0
- package/scripts/secondary-inbox-poller.py +437 -0
- package/scripts/self-optimization/compute-metrics.py +398 -0
- package/scripts/send-email-as-principal.py +369 -0
- package/scripts/send-email-threaded.py +392 -0
- package/scripts/send-email-with-attachment.py +377 -0
- package/scripts/send-email.sh +131 -0
- package/scripts/send-sms.sh +175 -0
- package/scripts/send-whatsapp.sh +292 -0
- package/scripts/session-start.sh +106 -0
- package/scripts/setup/boot-claude-session.sh +94 -0
- package/scripts/setup/configure-macos.sh +674 -0
- package/scripts/setup/configure-twilio-sip-trunk.mjs +207 -0
- package/scripts/setup/configure-voice-tunnel.mjs +182 -0
- package/scripts/setup/generate-agent-env.mjs +92 -0
- package/scripts/setup/generate-agent-package-json.mjs +222 -0
- package/scripts/setup/generate-agent-package-json.test.mjs +143 -0
- package/scripts/setup/generate-autonomy.mjs +60 -0
- package/scripts/setup/generate-backlog.mjs +101 -0
- package/scripts/setup/generate-cadences.mjs +92 -0
- package/scripts/setup/generate-capability.mjs +162 -0
- package/scripts/setup/generate-charter.mjs +76 -0
- package/scripts/setup/generate-comms.mjs +59 -0
- package/scripts/setup/generate-company.mjs +92 -0
- package/scripts/setup/init-agent.sh +547 -0
- package/scripts/setup/init-agent.test.mjs +151 -0
- package/scripts/setup/init-archetype.mjs +74 -0
- package/scripts/setup/init-backup.mjs +54 -0
- package/scripts/setup/init-cadence-bus.mjs +60 -0
- package/scripts/setup/init-channel-bus.mjs +46 -0
- package/scripts/setup/init-cost-tracking.mjs +45 -0
- package/scripts/setup/init-decision-capture.mjs +66 -0
- package/scripts/setup/init-known-agents.mjs +57 -0
- package/scripts/setup/init-learning.mjs +70 -0
- package/scripts/setup/init-memory-executive.mjs +45 -0
- package/scripts/setup/init-model-router.mjs +124 -0
- package/scripts/setup/init-rag.mjs +174 -0
- package/scripts/setup/init-session-router.mjs +38 -0
- package/scripts/setup/init-slack-socket-mode.mjs +260 -0
- package/scripts/setup/init-telegram.mjs +165 -0
- package/scripts/setup/init-voice-realtime.mjs +204 -0
- package/scripts/setup/init-whatsapp-baileys.mjs +77 -0
- package/scripts/setup/install-dev-tools.sh +150 -0
- package/scripts/setup/lib/install-plist.mjs +95 -0
- package/scripts/setup/migrate-agent-to-sot.mjs +192 -0
- package/scripts/setup/render-environment-yaml.mjs +133 -0
- package/scripts/slack-events-ctl.sh +177 -0
- package/scripts/slack-events-server.mjs +1045 -0
- package/scripts/slack-react.mjs +89 -0
- package/scripts/slack-responded.sh +232 -0
- package/scripts/slack-send.sh +287 -0
- package/scripts/slack-typing.mjs +196 -0
- package/scripts/slack-upload-v2.py +95 -0
- package/scripts/sms-handler.mjs +450 -0
- package/scripts/spawn-session.sh +120 -0
- package/scripts/sync-protocol.mjs +217 -0
- package/scripts/system-verify.sh +184 -0
- package/scripts/test-email-thread-dedup.py +239 -0
- package/scripts/test-information-barriers.py +484 -0
- package/scripts/test-llm-email-dedup.py +251 -0
- package/scripts/test-pre-draft-integration.py +203 -0
- package/scripts/test-rag-phase2.sh +442 -0
- package/scripts/test-rag-search.sh +251 -0
- package/scripts/test-voice-parser.mjs +316 -0
- package/scripts/user-context-search.py +659 -0
- package/scripts/validate_outbound.py +1504 -0
- package/scripts/watchdog/ai.maestro.memory-watchdog.plist +41 -0
- package/scripts/watchdog/force-reboot.sh +157 -0
- package/scripts/watchdog/memory-watchdog.sh +473 -0
- package/scripts/whatsapp-handler.mjs +538 -0
- package/teams/desktop-operations.yaml +34 -0
- package/teams/executive-office.yaml +27 -0
- package/teams/legal-and-regulatory.yaml +24 -0
- package/teams/platform-and-engineering.yaml +23 -0
- package/teams/strategy-and-growth.yaml +29 -0
- package/workflows/continuous/backlog-executor.yaml +141 -0
- package/workflows/continuous/inbound-monitor.yaml +168 -0
- package/workflows/daily/applicant-triage.yaml +197 -0
- package/workflows/daily/comms-triage.yaml +80 -0
- package/workflows/daily/evening-wrap.yaml +105 -0
- package/workflows/daily/morning-brief.yaml +164 -0
- package/workflows/daily/slack-followup-sweep.yaml +87 -0
- package/workflows/event-driven/README.md +50 -0
- package/workflows/event-driven/agent-failure-investigation.yaml +137 -0
- package/workflows/event-driven/pr-review.yaml +107 -0
- package/workflows/monthly/board-readiness.yaml +76 -0
- package/workflows/quarterly/strategic-scenario-analysis.yaml +85 -0
- package/workflows/session-protocol.md +171 -0
- package/workflows/weekly/engineering-health.yaml +154 -0
- package/workflows/weekly/hiring-review.yaml +169 -0
- package/workflows/weekly/rollup-pipeline-review.yaml +76 -0
- package/workflows/weekly/strategic-memo.yaml +79 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# ClawTeam Swarm Orchestration Guide
|
|
2
|
+
|
|
3
|
+
ClawTeam is a CLI-native swarm orchestrator that uses git worktrees, tmux, and filesystem-based messaging to run multiple coding agents in parallel. It implements a leader/worker pattern where a leader agent manages task creation, dependency chains, spawning, monitoring, and merge.
|
|
4
|
+
|
|
5
|
+
## Why It Matters
|
|
6
|
+
|
|
7
|
+
When a coding task involves 2+ independent workstreams (e.g., frontend + backend, or multiple microservices), running agents sequentially is slow and wasteful. ClawTeam gives each agent its own git worktree — isolated branch, files, staging area, and process space — eliminating conflicts, corruption, and dependency collisions.
|
|
8
|
+
|
|
9
|
+
## Key Capabilities
|
|
10
|
+
|
|
11
|
+
- **Leader/worker pattern**: Leader agent manages task graph; workers execute independently
|
|
12
|
+
- **Git worktree isolation**: Each worker gets its own worktree branch
|
|
13
|
+
- **Filesystem messaging**: Point-to-point and broadcast messaging between agents
|
|
14
|
+
- **Task dependencies**: Auto-unblocking when upstream tasks complete
|
|
15
|
+
- **Kanban board**: Terminal and web dashboard for monitoring
|
|
16
|
+
- **Multi-agent support**: Claude Code, Codex, Hermes, nanobot, OpenClaw
|
|
17
|
+
|
|
18
|
+
## Technical Details
|
|
19
|
+
|
|
20
|
+
- CLI-native and fully automatable (no GUI required)
|
|
21
|
+
- tmux-based worker management
|
|
22
|
+
- MIT licensed
|
|
23
|
+
- Known gaps: task status sync can lag (needs leader-side verification), requires explicit model pinning
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
### Via init-agent
|
|
28
|
+
|
|
29
|
+
If you ran `scripts/setup/init-agent.sh` with `MAESTRO_ENABLE_SWARM=1`, ClawTeam was cloned and configured. Verify:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Check ClawTeam is available
|
|
33
|
+
which clawteam || ls ~/ClawTeam-OpenClaw/clawteam
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Manual
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Clone the repository
|
|
40
|
+
git clone https://github.com/win4r/ClawTeam-OpenClaw.git ~/ClawTeam-OpenClaw
|
|
41
|
+
|
|
42
|
+
# Ensure tmux is installed
|
|
43
|
+
brew install tmux # macOS
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
48
|
+
### Basic swarm launch
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
cd ~/your-repo
|
|
52
|
+
clawteam start --leader claude --workers 3 --task "Implement user authentication"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### With task dependencies
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
clawteam start \
|
|
59
|
+
--leader claude \
|
|
60
|
+
--task-file tasks.yaml \
|
|
61
|
+
--workers 4 \
|
|
62
|
+
--model claude-opus-4-6
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Monitoring
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Terminal kanban
|
|
69
|
+
clawteam board
|
|
70
|
+
|
|
71
|
+
# Web dashboard
|
|
72
|
+
clawteam dashboard --port 8080
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Filesystem messaging
|
|
76
|
+
|
|
77
|
+
Workers communicate via an inbox system in the worktree root:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Leader sends to worker-2
|
|
81
|
+
echo "Priority change: focus on API endpoints first" > .clawteam/inbox/worker-2/msg-001.txt
|
|
82
|
+
|
|
83
|
+
# Worker reads inbox
|
|
84
|
+
cat .clawteam/inbox/self/*.txt
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Repository
|
|
88
|
+
|
|
89
|
+
- GitHub: https://github.com/win4r/ClawTeam-OpenClaw
|
|
90
|
+
- License: MIT
|
|
91
|
+
|
|
92
|
+
## Integration with Maestro
|
|
93
|
+
|
|
94
|
+
ClawTeam is an optional module for coding-heavy agents. It is not required for operational agents (Chief of Staff, Legal, Communications) but is valuable for:
|
|
95
|
+
|
|
96
|
+
- **Engineering coordination agents** running parallel coding tasks
|
|
97
|
+
- **Platform architecture agents** implementing across multiple packages
|
|
98
|
+
- **Any agent** where a backlog item involves 2+ independent code changes
|
|
99
|
+
|
|
100
|
+
### Routing rules
|
|
101
|
+
|
|
102
|
+
The backlog executor can route items to ClawTeam when:
|
|
103
|
+
1. The task involves code changes to 2+ independent files/packages
|
|
104
|
+
2. The task is explicitly tagged as `swarm-eligible` in the queue
|
|
105
|
+
3. The agent's config has `MAESTRO_ENABLE_SWARM=1`
|
|
106
|
+
|
|
107
|
+
### Post-merge workflow
|
|
108
|
+
|
|
109
|
+
After ClawTeam workers complete, the leader agent:
|
|
110
|
+
1. Reviews all worker diffs
|
|
111
|
+
2. Runs tests on each worktree branch
|
|
112
|
+
3. Merges clean branches to the integration branch
|
|
113
|
+
4. Produces a structured summary of changes
|
|
114
|
+
5. Cleans up worktrees
|
|
115
|
+
|
|
116
|
+
This maps naturally to Maestro's session output pattern (`outputs/sessions/{id}/output.md`).
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Code-Review-Graph — Structural Knowledge Graph for Codebases
|
|
2
|
+
|
|
3
|
+
Tree-sitter-based knowledge graph mapping functions, classes, imports, and call relationships. Provides MCP tools for blast-radius analysis, review context, architecture overview, and refactor planning.
|
|
4
|
+
|
|
5
|
+
## Why It Matters
|
|
6
|
+
|
|
7
|
+
When agents review PRs, plan refactors, or assess engineering health, they need structural understanding of the codebase — not just text search. Code-review-graph builds a persistent knowledge graph that auto-updates on file changes, providing:
|
|
8
|
+
|
|
9
|
+
- **Blast-radius analysis** — What breaks if this function changes?
|
|
10
|
+
- **Review context** — What other code depends on this change?
|
|
11
|
+
- **Architecture overview** — How do modules connect?
|
|
12
|
+
- **Semantic search** — Find related functions by call graph, not just name
|
|
13
|
+
- **Refactor planning** — Map dependencies before restructuring
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
### Via install-dev-tools (recommended)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
./scripts/setup/install-dev-tools.sh --tool code-review-graph
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Manual
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Global install
|
|
27
|
+
npm install -g code-review-graph
|
|
28
|
+
|
|
29
|
+
# Or via npx (zero-install)
|
|
30
|
+
npx code-review-graph
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## MCP Server Configuration
|
|
34
|
+
|
|
35
|
+
Add to your Claude Code MCP settings (`.claude/settings.json` or project-level):
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"mcpServers": {
|
|
40
|
+
"code-review-graph": {
|
|
41
|
+
"command": "npx",
|
|
42
|
+
"args": ["code-review-graph", "serve", "--port", "3848"],
|
|
43
|
+
"env": {
|
|
44
|
+
"CRG_REPO_PATH": "/path/to/your/repo"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Usage
|
|
52
|
+
|
|
53
|
+
### Build the graph for a repo
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npx code-review-graph index /path/to/repo
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Query via MCP tools (from Claude Code)
|
|
60
|
+
|
|
61
|
+
Once configured as an MCP server, Claude Code gains these tools:
|
|
62
|
+
- `blast_radius(file, function)` — Trace all callers and dependents
|
|
63
|
+
- `review_context(diff)` — Generate review context from a diff
|
|
64
|
+
- `architecture_overview()` — High-level module map
|
|
65
|
+
- `semantic_search(query)` — Find related code by structural relationships
|
|
66
|
+
|
|
67
|
+
### Standalone CLI
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npx code-review-graph blast-radius --file src/lib/executor.js --function executeAction
|
|
71
|
+
npx code-review-graph overview --repo ~/maestro
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Integration with Maestro
|
|
75
|
+
|
|
76
|
+
Recommended for coding-oriented agents and workflows:
|
|
77
|
+
- **Engineering health checks** — Use architecture overview to assess repo structure
|
|
78
|
+
- **PR review agents** — Enrich review context with dependency information
|
|
79
|
+
- **Refactoring tasks** — Plan changes with blast-radius awareness
|
|
80
|
+
|
|
81
|
+
Optional for non-coding agents (operational, hiring, comms). Enable per-repo as needed.
|
|
82
|
+
|
|
83
|
+
## Repository
|
|
84
|
+
|
|
85
|
+
- License: Open source
|
|
86
|
+
- Requires: Tree-sitter (bundled)
|
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
# Email Setup Guide
|
|
2
|
+
|
|
3
|
+
Two email lanes coexist, deliberately — pick yours first:
|
|
4
|
+
|
|
5
|
+
| Your mailbox | Lane | Where |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| **Workspace mailbox** — a Cohort-hosted address at your org's verified domain (`<member-slug>@<domain>`, assigned in Cohort → Settings → Email) | **`orgmail` channel adapter** — inbound + replies ride org RPC (no IMAP, no app passwords, no provider creds on the mini) | [Workspace email (orgmail)](#workspace-email-orgmail) below |
|
|
8
|
+
| **Personal Gmail** — the agent's mailbox is a plain Google account | **Legacy Gmail lane** — IMAP polling + SMTP scripts (`GMAIL_APP_PASSWORD`) | the rest of this guide |
|
|
9
|
+
|
|
10
|
+
## Workspace email (orgmail)
|
|
11
|
+
|
|
12
|
+
The Cohort workspace mailbox turns the agent's org enrollment into a full email identity:
|
|
13
|
+
|
|
14
|
+
1. **Admin (once per org):** Cohort → Settings → Email — provision + verify the sending/receiving domain (copy the DNS records verbatim), then assign this agent a mailbox (`astra@agents.example`).
|
|
15
|
+
2. **Agent repo:** enable the channel — `cohort setup --only orgmail` (wizard order 77), or copy the gate file by hand:
|
|
16
|
+
```bash
|
|
17
|
+
cp scaffold/config/orgmail.yaml.example config/orgmail.yaml
|
|
18
|
+
```
|
|
19
|
+
Credentials come from `config/org.yaml` (`org.cohort.{base,orgId,token}` — the enrollment SoT); there is nothing else to configure.
|
|
20
|
+
3. **Restart the daemon.** Inbound mail flows `email.inbox` → `email.message` → `state/inbox/orgmail/*.yaml` → classifier → session, on a 45s poll (`poll_seconds`, env override `MAESTRO_ORGMAIL_POLL_MS`). `mark_read: true` advances the SERVER-side read cursor after each clean handoff — there is no local cursor file; an unmarked item simply re-delivers (at-least-once, deduped downstream by item id).
|
|
21
|
+
4. **Replies** go through the sanctioned CLI (never raw curl, never the MCP `email_send` tool — the PreToolUse hooks block it):
|
|
22
|
+
```bash
|
|
23
|
+
node scripts/org/send-orgmail.mjs --thread "<thread_id>" --body-file reply.md
|
|
24
|
+
```
|
|
25
|
+
Recipients + subject derive from the thread server-side. A **first-contact** recipient (an address this mailbox has never corresponded with) returns `approval_required` — re-run with `--request-approval --wait` and a human approves it in Cohort (/decisions).
|
|
26
|
+
5. **Verify:** `cohort doctor` runs the mailbox probe; the setup wizard's verify step does one `email.inbox {limit:1}` round-trip (it WARNS — not fails — until the admin has verified a domain and assigned the mailbox).
|
|
27
|
+
6. **Kill switch:** delete/rename `config/orgmail.yaml` and restart — the daemon's gate-file loop skips the platform. Server-side, an admin can flip the mailbox to Disabled in Settings → Email.
|
|
28
|
+
|
|
29
|
+
> Hand-adding `.mcp.json` (the `cohort` MCP server) to a pre-2.0 repo? Add the three PreToolUse matchers (`mcp__cohort__messaging_send`, `mcp__cohort__email_send`, `mcp__cohort__org_rpc` → `scripts/hooks/block-mcp-cohort-send.sh`) alongside it — `cohort upgrade` rewrites neither file. Fresh `cohort create` repos ship both together.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
# Legacy lane: personal Gmail
|
|
34
|
+
|
|
35
|
+
How to enable Gmail-based email for a Maestro agent: IMAP polling (reading inbound mail), SMTP sending (plain, threaded, with attachments, as principal), email thread deduplication, signature management, and email archival.
|
|
36
|
+
|
|
37
|
+
**Prerequisites**: Complete the [Mac Mini Bootstrap](../runbooks/mac-mini-bootstrap.md) and have the agent's `.env` file created.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Architecture Overview
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
┌──────────────────────────────────────────────────────────────────────┐
|
|
45
|
+
│ INBOUND │
|
|
46
|
+
│ Gmail IMAP ──▶ gmail-poller.mjs ──▶ state/inbox/gmail/*.yaml │
|
|
47
|
+
│ (every 60s) imap-client.mjs (inbox processor routes) │
|
|
48
|
+
│ │
|
|
49
|
+
│ Optional: secondary inbox (e.g. CEO inbox) │
|
|
50
|
+
│ Gmail IMAP ──▶ secondary-gmail-poller.mjs ──▶ state/inbox/gmail/*.yaml │
|
|
51
|
+
├──────────────────────────────────────────────────────────────────────┤
|
|
52
|
+
│ OUTBOUND │
|
|
53
|
+
│ │
|
|
54
|
+
│ ┌─────────────────┐ ┌───────────────────────┐ ┌───────────────┐ │
|
|
55
|
+
│ │ send-email.sh │ │ send-email-threaded.py │ │ send-email- │ │
|
|
56
|
+
│ │ (simple HTML) │ │ (thread-aware + dedup) │ │ with-attach.py│ │
|
|
57
|
+
│ └───────┬─────────┘ └──────────┬────────────┘ └──────┬────────┘ │
|
|
58
|
+
│ │ │ │ │
|
|
59
|
+
│ ▼ ▼ ▼ │
|
|
60
|
+
│ ┌────────────────────────────────────────────────────────────────┐ │
|
|
61
|
+
│ │ Pre-send pipeline: │ │
|
|
62
|
+
│ │ 1. validate_outbound.py (factual checks — blocks if issues) │ │
|
|
63
|
+
│ │ 2. llm_email_dedup.py (LLM asks: already addressed?) │ │
|
|
64
|
+
│ │ 3. outbound_dedup.py (content-hash dedup) │ │
|
|
65
|
+
│ │ 4. pre_draft_lookup.py (context enrichment — advisory) │ │
|
|
66
|
+
│ │ 5. email_quote_thread.py (include quoted original in reply) │ │
|
|
67
|
+
│ └────────────────────────────────────────────────────────────────┘ │
|
|
68
|
+
│ │ │
|
|
69
|
+
│ ▼ │
|
|
70
|
+
│ msmtp / Gmail SMTP ──▶ recipient │
|
|
71
|
+
│ (with branded HTML signature auto-appended) │
|
|
72
|
+
├──────────────────────────────────────────────────────────────────────┤
|
|
73
|
+
│ DEDUP & THREADING │
|
|
74
|
+
│ email_thread_dedup.py — Hash-based thread dedup │
|
|
75
|
+
│ llm_email_dedup.py — LLM semantic dedup (Claude Haiku) │
|
|
76
|
+
│ email_quote_thread.py — Fetch and format quoted reply chain │
|
|
77
|
+
├──────────────────────────────────────────────────────────────────────┤
|
|
78
|
+
│ SEARCH │
|
|
79
|
+
│ search-secondary-inbox.py — Search CEO inbox via IMAP │
|
|
80
|
+
└──────────────────────────────────────────────────────────────────────┘
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 1. Gmail Account & App Password
|
|
86
|
+
|
|
87
|
+
Maestro uses IMAP for reading email and SMTP for sending. Both use Gmail app passwords (not OAuth) for simplicity and reliability on headless Mac minis.
|
|
88
|
+
|
|
89
|
+
### 1.1 Enable 2-Factor Authentication
|
|
90
|
+
|
|
91
|
+
App passwords require 2FA:
|
|
92
|
+
|
|
93
|
+
1. Go to https://myaccount.google.com/security
|
|
94
|
+
2. Enable 2-Step Verification if not already active
|
|
95
|
+
|
|
96
|
+
### 1.2 Generate an App Password
|
|
97
|
+
|
|
98
|
+
1. Go to https://myaccount.google.com/apppasswords
|
|
99
|
+
2. Select app: "Mail", device: "Mac"
|
|
100
|
+
3. Click "Generate"
|
|
101
|
+
4. Copy the 16-character password (no spaces)
|
|
102
|
+
|
|
103
|
+
### 1.3 Configure Environment Variables
|
|
104
|
+
|
|
105
|
+
Add to `.env`:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Agent's Gmail account
|
|
109
|
+
GMAIL_APP_PASSWORD=xxxxxxxxxxxxxxxx
|
|
110
|
+
|
|
111
|
+
# Optional: secondary inbox (e.g. CEO email) for monitoring
|
|
112
|
+
SECONDARY_GMAIL_APP_PASSWORD=xxxxxxxxxxxxxxxx
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 1.4 Configure msmtp (SMTP Client)
|
|
116
|
+
|
|
117
|
+
The `send-email.sh` script uses `msmtp` to send email via Gmail SMTP:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Install msmtp
|
|
121
|
+
brew install msmtp
|
|
122
|
+
|
|
123
|
+
# Create configuration
|
|
124
|
+
cat > ~/.msmtprc << 'EOF'
|
|
125
|
+
defaults
|
|
126
|
+
auth on
|
|
127
|
+
tls on
|
|
128
|
+
tls_trust_file /etc/ssl/cert.pem
|
|
129
|
+
logfile ~/maestro/logs/msmtp.log
|
|
130
|
+
|
|
131
|
+
account agent
|
|
132
|
+
host smtp.gmail.com
|
|
133
|
+
port 587
|
|
134
|
+
from agent@example.com
|
|
135
|
+
user agent@example.com
|
|
136
|
+
password YOUR_GMAIL_APP_PASSWORD
|
|
137
|
+
EOF
|
|
138
|
+
|
|
139
|
+
chmod 600 ~/.msmtprc
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Replace `agent@example.com` and the password with your agent's credentials.
|
|
143
|
+
|
|
144
|
+
**Alternative**: The Python send scripts (`send-email-threaded.py`, `send-email-with-attachment.py`) use `smtplib` directly with Gmail SMTP, so they don't need msmtp. Only the shell `send-email.sh` requires msmtp.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## 2. Inbound Email — IMAP Polling
|
|
149
|
+
|
|
150
|
+
The poller checks Gmail via IMAP on every polling cycle (default: 60 seconds) and writes new messages to the inbox.
|
|
151
|
+
|
|
152
|
+
### 2.1 How It Works
|
|
153
|
+
|
|
154
|
+
1. `scripts/poller/gmail-poller.mjs` connects via `scripts/poller/imap-client.mjs`
|
|
155
|
+
2. Searches for UNSEEN messages in INBOX
|
|
156
|
+
3. Parses each message: sender, subject, body, attachments, threading headers
|
|
157
|
+
4. Writes a YAML file to `state/inbox/gmail/` for the inbox processor
|
|
158
|
+
5. Marks messages as SEEN to avoid reprocessing
|
|
159
|
+
|
|
160
|
+
### 2.2 IMAP Configuration
|
|
161
|
+
|
|
162
|
+
The poller reads credentials from `.env`:
|
|
163
|
+
|
|
164
|
+
| Variable | Purpose |
|
|
165
|
+
|---|---|
|
|
166
|
+
| `GMAIL_APP_PASSWORD` | Agent's own inbox |
|
|
167
|
+
| `SECONDARY_GMAIL_APP_PASSWORD` | CEO/secondary inbox |
|
|
168
|
+
|
|
169
|
+
IMAP server settings are hardcoded to Gmail defaults (`imap.gmail.com:993` with SSL).
|
|
170
|
+
|
|
171
|
+
### 2.3 Secondary Inbox Monitoring
|
|
172
|
+
|
|
173
|
+
If the agent monitors a second inbox (e.g. the CEO's email for triage):
|
|
174
|
+
|
|
175
|
+
- `scripts/poller/secondary-gmail-poller.mjs` handles the secondary inbox
|
|
176
|
+
- Uses `SECONDARY_GMAIL_APP_PASSWORD`
|
|
177
|
+
- Writes to the same `state/inbox/gmail/` directory with source annotation
|
|
178
|
+
|
|
179
|
+
### 2.4 Verify IMAP Access
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Test IMAP connectivity (uses Python imaplib)
|
|
183
|
+
python3 -c "
|
|
184
|
+
import imaplib
|
|
185
|
+
m = imaplib.IMAP4_SSL('imap.gmail.com')
|
|
186
|
+
m.login('agent@example.com', 'YOUR_APP_PASSWORD')
|
|
187
|
+
m.select('INBOX')
|
|
188
|
+
_, msgs = m.search(None, 'UNSEEN')
|
|
189
|
+
print(f'Connected OK. {len(msgs[0].split())} unread messages.')
|
|
190
|
+
m.logout()
|
|
191
|
+
"
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## 3. Outbound Email — Sending
|
|
197
|
+
|
|
198
|
+
Three send scripts handle different use cases:
|
|
199
|
+
|
|
200
|
+
### 3.1 Simple HTML Email (`send-email.sh`)
|
|
201
|
+
|
|
202
|
+
Sends a one-shot HTML email with branded signature via `msmtp`.
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
./scripts/send-email.sh "recipient@example.com" "Subject line" "Body text here"
|
|
206
|
+
|
|
207
|
+
# With CC and threading headers:
|
|
208
|
+
./scripts/send-email.sh "to@example.com" "Re: Subject" "Reply body" "cc@example.com" "<message-id>" "<references>"
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Features**:
|
|
212
|
+
- HTML signature with name, title, logo, phone, address auto-appended
|
|
213
|
+
- Content-hash dedup via `outbound-dedup.sh`
|
|
214
|
+
- Markdown-to-HTML conversion for body
|
|
215
|
+
|
|
216
|
+
### 3.2 Threaded Email (`send-email-threaded.py`)
|
|
217
|
+
|
|
218
|
+
The primary send script for production use. Thread-aware with full dedup pipeline.
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
python3 scripts/send-email-threaded.py "to@example.com" "Subject" "Body" \
|
|
222
|
+
--reply-to-subject "Original thread subject" \
|
|
223
|
+
--attachment /path/to/file.pdf
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**Features**:
|
|
227
|
+
- IMAP lookup for real Message-IDs (proper Gmail threading)
|
|
228
|
+
- 3-layer dedup: LLM semantic check → Gmail Sent folder check → content-hash
|
|
229
|
+
- Pre-draft context enrichment (advisory — looks up recipient before sending)
|
|
230
|
+
- Factual validation (blocks if critical issues found)
|
|
231
|
+
- Quoted reply chain inclusion (`email_quote_thread.py`)
|
|
232
|
+
- Branded HTML signature auto-appended
|
|
233
|
+
- `--force` flag to bypass dedup in exceptional cases
|
|
234
|
+
|
|
235
|
+
### 3.3 Email with Attachments (`send-email-with-attachment.py`)
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
python3 scripts/send-email-with-attachment.py "to@example.com" "Subject" "Body" \
|
|
239
|
+
--attachment /path/to/file.pdf \
|
|
240
|
+
--attachment /path/to/image.png \
|
|
241
|
+
--cc "cc@example.com" \
|
|
242
|
+
--reply-to-subject "Thread subject"
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Features**:
|
|
246
|
+
- MIME multipart with proper content-type detection
|
|
247
|
+
- Supports multiple attachments
|
|
248
|
+
- Full dedup pipeline (LLM + content-hash)
|
|
249
|
+
- Pre-draft context enrichment
|
|
250
|
+
- Same branded signature
|
|
251
|
+
|
|
252
|
+
### 3.4 Sending as Principal (`send-email-as-principal.py`)
|
|
253
|
+
|
|
254
|
+
Sends email in the CEO/principal's voice from their email account:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
python3 scripts/send-email-as-principal.py "to@example.com" "Subject" "Body" \
|
|
258
|
+
--cc "cc@example.com"
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
This uses the secondary Gmail credentials and the principal's signature block.
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## 4. Email Signatures
|
|
266
|
+
|
|
267
|
+
### 4.1 Signature Files
|
|
268
|
+
|
|
269
|
+
Two HTML signature templates live in `scripts/`:
|
|
270
|
+
|
|
271
|
+
| File | Used By | Identity |
|
|
272
|
+
|---|---|---|
|
|
273
|
+
| `email-signature.html` | Agent's own emails | Agent name, title, logo, phone, address |
|
|
274
|
+
| `email-signature-principal.html` | Principal's emails | CEO name, title, logo, phone, address |
|
|
275
|
+
|
|
276
|
+
### 4.2 Signature Behaviour
|
|
277
|
+
|
|
278
|
+
- **All send scripts auto-append the HTML signature** — do not include a text sign-off in the email body
|
|
279
|
+
- The signature includes: name, title, your company logo (hosted on Google), phone number, office address, confidentiality disclaimer
|
|
280
|
+
- Logo URL points to a Google-hosted image (no local file dependency)
|
|
281
|
+
|
|
282
|
+
### 4.3 Customising for a New Agent
|
|
283
|
+
|
|
284
|
+
Update `email-signature.html`:
|
|
285
|
+
- Replace the agent name, title, and phone number
|
|
286
|
+
- Keep the logo URL, address, and disclaimer structure
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## 5. Email Thread Deduplication
|
|
291
|
+
|
|
292
|
+
Email dedup prevents the agent from sending duplicate replies to the same thread. Three layers work together:
|
|
293
|
+
|
|
294
|
+
### 5.1 Layer 1 — LLM Semantic Dedup (`llm_email_dedup.py`)
|
|
295
|
+
|
|
296
|
+
Uses Claude Haiku to check if a topic has already been addressed in recent conversation history with the recipient.
|
|
297
|
+
|
|
298
|
+
- Reads recent sent emails to the same recipient via IMAP
|
|
299
|
+
- Asks Claude: "Has this topic already been addressed?"
|
|
300
|
+
- Returns `DEDUP_SKIP` if the LLM determines it's a duplicate
|
|
301
|
+
- Replaced the old subject+recipient hash lock (removed per CEO directive — was causing false positives on follow-up emails with the same subject)
|
|
302
|
+
|
|
303
|
+
### 5.2 Layer 2 — Gmail Sent Folder Check
|
|
304
|
+
|
|
305
|
+
Checks the actual Gmail Sent folder via IMAP to see if a similar email was recently sent.
|
|
306
|
+
|
|
307
|
+
### 5.3 Layer 3 — Content-Hash Dedup (`outbound_dedup.py`)
|
|
308
|
+
|
|
309
|
+
Atomic mkdir-based locking using SHA-256 hash of `to + subject + first 100 chars of body`. Prevents concurrent sessions from sending identical emails.
|
|
310
|
+
|
|
311
|
+
- Lock TTL: 12 hours
|
|
312
|
+
- Fail-open: if the lock system errors, the email sends anyway
|
|
313
|
+
|
|
314
|
+
### 5.4 Email Quote Threading (`email_quote_thread.py`)
|
|
315
|
+
|
|
316
|
+
When replying to an existing thread:
|
|
317
|
+
1. Fetches the original email chain via IMAP
|
|
318
|
+
2. Formats quoted HTML with attribution headers ("On [date], [sender] wrote:")
|
|
319
|
+
3. Appends quoted chain below the new reply
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## 6. Email Search
|
|
324
|
+
|
|
325
|
+
### 6.1 Inbox Search (`search-secondary-inbox.py`)
|
|
326
|
+
|
|
327
|
+
Searches the CEO's (or agent's) Gmail via IMAP for context retrieval:
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
python3 scripts/search-secondary-inbox.py --query "Q3 budget" --limit 5
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
Used by the pre-draft context system to find relevant email history before composing messages.
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## 7. Email Archival
|
|
338
|
+
|
|
339
|
+
### 7.1 Archive Script (`archive-email.sh`)
|
|
340
|
+
|
|
341
|
+
Archives processed emails:
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
./scripts/archive-email.sh
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Moves processed emails from active inbox directories to date-partitioned archive directories.
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
## 8. Testing
|
|
352
|
+
|
|
353
|
+
| # | Test | How to Verify |
|
|
354
|
+
|---|---|---|
|
|
355
|
+
| 1 | IMAP connectivity | Run the Python IMAP test from section 2.4 |
|
|
356
|
+
| 2 | msmtp configuration | `echo "test" \| msmtp -a agent your@email.com` |
|
|
357
|
+
| 3 | Simple send | `./scripts/send-email.sh "your@email.com" "Test" "Body"` |
|
|
358
|
+
| 4 | Threaded send | Send a reply with `--reply-to-subject` and verify Gmail threads it |
|
|
359
|
+
| 5 | Attachment send | Send with `--attachment` and verify file arrives |
|
|
360
|
+
| 6 | Dedup working | Send identical email twice; second should show `DEDUP_SKIP` |
|
|
361
|
+
| 7 | LLM dedup | Send two different emails about same topic; second should warn |
|
|
362
|
+
| 8 | Signature rendering | Check received email has branded HTML signature |
|
|
363
|
+
| 9 | Poller picking up mail | Send email to agent, check `state/inbox/gmail/` |
|
|
364
|
+
| 10 | Audit logging | Check `logs/audit/YYYY-MM-DD-actions.jsonl` for send entries |
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## 9. Troubleshooting
|
|
369
|
+
|
|
370
|
+
### IMAP connection refused
|
|
371
|
+
|
|
372
|
+
1. Verify 2FA is enabled on the Google account
|
|
373
|
+
2. Verify the app password is correct (no spaces)
|
|
374
|
+
3. Check that IMAP is enabled: Gmail Settings → Forwarding and POP/IMAP → Enable IMAP
|
|
375
|
+
4. Check firewall allows outbound connections to `imap.gmail.com:993`
|
|
376
|
+
|
|
377
|
+
### msmtp authentication failure
|
|
378
|
+
|
|
379
|
+
1. Verify `~/.msmtprc` has correct username and app password
|
|
380
|
+
2. Verify file permissions: `chmod 600 ~/.msmtprc`
|
|
381
|
+
3. Test: `echo "test" | msmtp -a agent --debug your@email.com`
|
|
382
|
+
4. Check `logs/msmtp.log` for detailed error
|
|
383
|
+
|
|
384
|
+
### Emails not threading in Gmail
|
|
385
|
+
|
|
386
|
+
1. Verify `In-Reply-To` and `References` headers are set correctly
|
|
387
|
+
2. Use `send-email-threaded.py` (not `send-email.sh`) for replies — it does IMAP lookup for real Message-IDs
|
|
388
|
+
3. Gmail threads by `In-Reply-To` + matching `References` + same subject (with `Re:` prefix)
|
|
389
|
+
|
|
390
|
+
### LLM dedup false positives
|
|
391
|
+
|
|
392
|
+
1. If legitimate follow-ups are being blocked, use `--force` flag
|
|
393
|
+
2. Review the LLM dedup logic in `llm_email_dedup.py` — it uses Claude Haiku for semantic comparison
|
|
394
|
+
3. The LLM checks recent sent emails only (last 48 hours) — old conversations won't trigger
|
|
395
|
+
|
|
396
|
+
### Duplicate emails being sent
|
|
397
|
+
|
|
398
|
+
1. Verify `outbound-dedup.sh` is executable: `chmod +x scripts/outbound-dedup.sh`
|
|
399
|
+
2. Check lock directory exists: `ls state/locks/outbound/email/`
|
|
400
|
+
3. Verify lock TTL hasn't been set too low (default: 720 minutes / 12 hours)
|
|
401
|
+
4. Run cleanup: `./scripts/outbound-dedup-cleanup.sh`
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## Key Files
|
|
406
|
+
|
|
407
|
+
| File | Purpose |
|
|
408
|
+
|---|---|
|
|
409
|
+
| `scripts/send-email.sh` | Simple HTML email via msmtp |
|
|
410
|
+
| `scripts/send-email-threaded.py` | Thread-aware email with full dedup pipeline |
|
|
411
|
+
| `scripts/send-email-with-attachment.py` | MIME email with file attachments |
|
|
412
|
+
| `scripts/send-email-as-principal.py` | Send as principal (CEO voice) |
|
|
413
|
+
| `scripts/email_thread_dedup.py` | Hash-based email thread deduplication |
|
|
414
|
+
| `scripts/llm_email_dedup.py` | LLM semantic deduplication (Claude Haiku) |
|
|
415
|
+
| `scripts/email_quote_thread.py` | Fetch and format quoted reply chains |
|
|
416
|
+
| `scripts/archive-email.sh` | Email archival workflow |
|
|
417
|
+
| `scripts/email-signature.html` | Agent's branded HTML signature |
|
|
418
|
+
| `scripts/email-signature-principal.html` | Principal's branded HTML signature |
|
|
419
|
+
| `scripts/search-secondary-inbox.py` | IMAP email search for context retrieval |
|
|
420
|
+
| `scripts/poller/gmail-poller.mjs` | Inbound email polling (IMAP) |
|
|
421
|
+
| `scripts/poller/imap-client.mjs` | IMAP client wrapper |
|
|
422
|
+
| `scripts/poller/secondary-gmail-poller.mjs` | Secondary inbox polling |
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## Related Documents
|
|
427
|
+
|
|
428
|
+
- [Voice & SMS Setup](voice-sms-setup.md) — Phone and SMS capabilities
|
|
429
|
+
- [Outbound Governance Setup](outbound-governance-setup.md) — Dedup, validation, information barriers
|
|
430
|
+
- [Poller & Daemon Setup](poller-daemon-setup.md) — How email polling integrates with the event loop
|
|
431
|
+
- [Agent Persona Setup](agent-persona-setup.md) — Configuring agent identity for email signature
|