@cohortapp/agent-sdk 2.16.0 → 2.18.4
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/settings.json +18 -0
- package/.env.example +23 -7
- package/README.md +1 -0
- package/bin/maestro.mjs +62 -0
- package/docs/guides/billing-console-keys.md +60 -0
- package/docs/guides/front-door-session.md +54 -9
- package/docs/guides/mac-mini.md +20 -25
- package/docs/guides/poller-daemon-setup.md +4 -1
- package/docs/guides/setup-wizard.md +1 -1
- package/docs/runbooks/fleet-rollout.md +156 -0
- package/docs/runbooks/mac-mini-bootstrap.md +12 -14
- package/lib/action-executor.js +19 -3
- package/lib/budget-guard.mjs +279 -3
- package/lib/channels/base-adapter.mjs +3 -1
- package/lib/channels/contract.mjs +2 -1
- package/lib/channels/inbox-item.mjs +8 -0
- package/lib/claude-bin.mjs +5 -6
- package/lib/cli/doctor-checks.mjs +141 -10
- package/lib/cli/global-setup-extras.mjs +5 -1
- package/lib/cli/inbox.mjs +100 -15
- package/lib/cli/seat-auth.mjs +463 -0
- package/lib/cli/session.mjs +80 -12
- package/lib/collective/capture.mjs +8 -6
- package/lib/collective/global-config.mjs +63 -1
- package/lib/collective/presence.mjs +142 -5
- package/lib/comms/send-gate.mjs +559 -1
- package/lib/context/budget.mjs +327 -0
- package/lib/context/history-scope.mjs +138 -0
- package/lib/diagnostics/alerts.mjs +49 -0
- package/lib/diagnostics/cadence-output-freshness.mjs +288 -0
- package/lib/engine/agents/definitions.mjs +343 -0
- package/lib/engine/agents/persist.mjs +275 -0
- package/lib/engine/agents/runtime.mjs +748 -0
- package/lib/engine/agents/usage.mjs +95 -0
- package/lib/engine/auth-status.mjs +139 -0
- package/lib/engine/budget.mjs +194 -0
- package/lib/engine/cli.mjs +1204 -0
- package/lib/engine/commands/index.mjs +269 -0
- package/lib/engine/context/budget.mjs +219 -0
- package/lib/engine/context/cache.mjs +125 -0
- package/lib/engine/context/child-env.mjs +215 -0
- package/lib/engine/context/compaction.mjs +342 -0
- package/lib/engine/context/images.mjs +90 -0
- package/lib/engine/context/instructions.mjs +327 -0
- package/lib/engine/context/lazy-instructions.mjs +169 -0
- package/lib/engine/context/manager.mjs +182 -0
- package/lib/engine/context/real-path.mjs +91 -0
- package/lib/engine/context/secret-values.mjs +163 -0
- package/lib/engine/context/settings.mjs +274 -0
- package/lib/engine/context/stream-input.mjs +159 -0
- package/lib/engine/guard.mjs +152 -0
- package/lib/engine/hooks.mjs +713 -0
- package/lib/engine/loop.mjs +560 -0
- package/lib/engine/mcp/client.mjs +254 -0
- package/lib/engine/mcp/config.mjs +301 -0
- package/lib/engine/mcp/http.mjs +201 -0
- package/lib/engine/mcp/index.mjs +146 -0
- package/lib/engine/mcp/jsonrpc.mjs +147 -0
- package/lib/engine/mcp/naming.mjs +66 -0
- package/lib/engine/mcp/resources.mjs +89 -0
- package/lib/engine/mcp/results.mjs +133 -0
- package/lib/engine/mcp/stdio.mjs +137 -0
- package/lib/engine/mcp/supervisor.mjs +116 -0
- package/lib/engine/messages.mjs +104 -0
- package/lib/engine/output/json.mjs +164 -0
- package/lib/engine/output/stream-json.mjs +266 -0
- package/lib/engine/permissions.mjs +845 -0
- package/lib/engine/process-identity.mjs +164 -0
- package/lib/engine/process-tree.mjs +551 -0
- package/lib/engine/prompt.mjs +60 -0
- package/lib/engine/session/store.mjs +299 -0
- package/lib/engine/session-runtime/args.mjs +97 -0
- package/lib/engine/session-runtime/host.mjs +143 -0
- package/lib/engine/session-runtime/inbox.mjs +122 -0
- package/lib/engine/session-runtime/notifications.mjs +129 -0
- package/lib/engine/session-runtime/registry.mjs +328 -0
- package/lib/engine/session-runtime/runner.mjs +344 -0
- package/lib/engine/session-runtime/socket.mjs +212 -0
- package/lib/engine/session-runtime/wakeup.mjs +115 -0
- package/lib/engine/skills/index.mjs +321 -0
- package/lib/engine/tools/bash-background.mjs +533 -0
- package/lib/engine/tools/bash.mjs +216 -0
- package/lib/engine/tools/edit.mjs +97 -0
- package/lib/engine/tools/glob.mjs +81 -0
- package/lib/engine/tools/grep.mjs +224 -0
- package/lib/engine/tools/index.mjs +84 -0
- package/lib/engine/tools/list-agents.mjs +32 -0
- package/lib/engine/tools/ls.mjs +127 -0
- package/lib/engine/tools/monitor.mjs +82 -0
- package/lib/engine/tools/notebook-edit.mjs +218 -0
- package/lib/engine/tools/read.mjs +103 -0
- package/lib/engine/tools/schedule-wakeup.mjs +45 -0
- package/lib/engine/tools/schema.mjs +144 -0
- package/lib/engine/tools/send-message.mjs +77 -0
- package/lib/engine/tools/session.mjs +70 -0
- package/lib/engine/tools/todo.mjs +144 -0
- package/lib/engine/tools/toolsearch.mjs +217 -0
- package/lib/engine/tools/walk.mjs +193 -0
- package/lib/engine/tools/web-switch.mjs +31 -0
- package/lib/engine/tools/webfetch-html.mjs +387 -0
- package/lib/engine/tools/webfetch-net.mjs +340 -0
- package/lib/engine/tools/webfetch.mjs +198 -0
- package/lib/engine/tools/websearch.mjs +91 -0
- package/lib/engine/tools/workflow.mjs +95 -0
- package/lib/engine/tools/write.mjs +76 -0
- package/lib/engine/tui/line-editor.mjs +137 -0
- package/lib/engine/tui/render.mjs +86 -0
- package/lib/engine/tui/tui.mjs +274 -0
- package/lib/engine/wire/anthropic-messages.mjs +263 -0
- package/lib/engine/wire/effort.mjs +36 -0
- package/lib/engine/wire/errors.mjs +496 -0
- package/lib/engine/wire/http.mjs +441 -0
- package/lib/engine/wire/index.mjs +76 -0
- package/lib/engine/wire/openai-chat.mjs +332 -0
- package/lib/engine/wire/prompt-cache.mjs +79 -0
- package/lib/engine/wire/search.mjs +140 -0
- package/lib/engine/wire/sse.mjs +114 -0
- package/lib/engine/wire/stall.mjs +349 -0
- package/lib/engine/wire/token-provider.mjs +175 -0
- package/lib/engine/wire/usage.mjs +192 -0
- package/lib/engine/workflow/host.mjs +524 -0
- package/lib/engine/workflow/journal.mjs +188 -0
- package/lib/engine/workflow/json-schema.mjs +171 -0
- package/lib/engine/workflow/meta.mjs +329 -0
- package/lib/engine/workflow/notifications.mjs +52 -0
- package/lib/engine/workflow/runtime.mjs +447 -0
- package/lib/engine/workflow/sandbox.mjs +534 -0
- package/lib/engine/workflow/worker.mjs +141 -0
- package/lib/engine/workflow/worktree.mjs +74 -0
- package/lib/execution/disposition.mjs +1 -1
- package/lib/execution/intake.mjs +10 -0
- package/lib/execution/surface-policy.mjs +15 -0
- package/lib/learning/curator.mjs +8 -6
- package/lib/learning/reflect.mjs +8 -6
- package/lib/model-router/catalog/cohort.yaml +137 -0
- package/lib/model-router/catalog.mjs +118 -1
- package/lib/model-router/economics.mjs +9 -0
- package/lib/model-router/failover.mjs +67 -16
- package/lib/model-router/llm-task.mjs +39 -3
- package/lib/model-router/resolve.mjs +95 -3
- package/lib/model-router/spawn.mjs +46 -47
- package/lib/model-router/taxonomy.mjs +126 -4
- package/lib/org/cost-sync.mjs +141 -11
- package/lib/org/inbound/broadcast.mjs +289 -0
- package/lib/org/inbound/collective.mjs +375 -0
- package/lib/org/inbound/directedness.mjs +96 -8
- package/lib/org/inbound/facts.mjs +82 -4
- package/lib/org/inbound/hydrate.mjs +555 -51
- package/lib/org/inbound/project.mjs +22 -0
- package/lib/org/inbound/surfaces.mjs +14 -0
- package/lib/org/llm-token.mjs +879 -0
- package/lib/org/mesh.mjs +61 -0
- package/lib/org/messaging.mjs +3 -1
- package/lib/org/protocol.checksum +1 -1
- package/lib/org/protocol.mjs +15 -0
- package/lib/org/quota.mjs +520 -0
- package/lib/org/tool-surface.mjs +104 -16
- package/lib/org/ui-parity.mjs +16 -1
- package/lib/org/work-ledger.mjs +37 -6
- package/lib/rate-guard.mjs +114 -1
- package/lib/resource-governor.mjs +41 -6
- package/lib/runtime/adapter.mjs +823 -0
- package/lib/runtime/child-env.mjs +191 -0
- package/lib/runtime/legacy-shell-guard.mjs +97 -0
- package/lib/runtime/seat-engine.mjs +162 -0
- package/lib/session/ask-ledger.mjs +271 -0
- package/lib/session/current-work.mjs +676 -0
- package/lib/session/feed-core.mjs +40 -3
- package/lib/session/launch-args.mjs +56 -4
- package/lib/session/status-summary.mjs +26 -9
- package/lib/session/upgrade-notice.mjs +42 -0
- package/lib/setup/claude-probe.mjs +117 -13
- package/lib/setup/enrich.mjs +13 -10
- package/lib/setup/sections/model.mjs +39 -13
- package/lib/telemetry/collect.mjs +208 -9
- package/lib/upgrade/ignored-drift.mjs +105 -0
- package/lib/voice/post-call-brief.mjs +30 -17
- package/package.json +15 -3
- package/plugins/maestro-skills/skills/board-work.md +5 -0
- package/plugins/maestro-skills/skills/inbound-triage.md +56 -15
- package/plugins/maestro-skills/skills/main-session.md +18 -7
- package/scripts/ci/check-tarball-fidelity.mjs +126 -2
- package/scripts/ci/run-tests.mjs +47 -19
- package/scripts/cohort-llm/api-key-helper.mjs +92 -0
- package/scripts/collective/hook-runner.mjs +29 -2
- package/scripts/continuous-monitor.sh +13 -0
- package/scripts/cost/track-claude-usage.mjs +15 -0
- package/scripts/daemon/agent-daemon.mjs +408 -20
- package/scripts/daemon/assurance.mjs +48 -12
- package/scripts/daemon/cadence-consumer.mjs +218 -68
- package/scripts/daemon/cadence-handlers.mjs +73 -4
- package/scripts/daemon/classifier.mjs +75 -26
- package/scripts/daemon/context-compiler.mjs +104 -59
- package/scripts/daemon/deliver.mjs +30 -1
- package/scripts/daemon/dispatcher.mjs +804 -157
- package/scripts/daemon/health.mjs +14 -1
- package/scripts/daemon/lib/session-router.mjs +310 -42
- package/scripts/daemon/maestro-daemon.mjs +11 -0
- package/scripts/daemon/prompt-builder.mjs +121 -12
- package/scripts/daemon/responder.mjs +315 -146
- package/scripts/daemon/sdk-version.mjs +98 -16
- package/scripts/eval/probe-gateway.mjs +635 -0
- package/scripts/eval/replay/extract.mjs +270 -0
- package/scripts/eval/replay/grade.mjs +260 -0
- package/scripts/eval/replay/lib/config.mjs +50 -0
- package/scripts/eval/replay/lib/effects.mjs +65 -0
- package/scripts/eval/replay/lib/fixture.mjs +188 -0
- package/scripts/eval/replay/lib/judge.mjs +72 -0
- package/scripts/eval/replay/lib/redact.mjs +136 -0
- package/scripts/eval/replay/lib/sandbox.mjs +170 -0
- package/scripts/eval/replay/lib/schema-check.mjs +63 -0
- package/scripts/eval/replay/lib/transcript.mjs +76 -0
- package/scripts/eval/replay/mcp-replay-stub.mjs +101 -0
- package/scripts/eval/replay/report.mjs +185 -0
- package/scripts/eval/replay/run.mjs +404 -0
- package/scripts/fleet/rollout.mjs +1094 -0
- package/scripts/hooks/pre-send-audit.sh +36 -245
- package/scripts/hooks/pre-write-yaml-validate.mjs +275 -0
- package/scripts/hooks/validate-state-yaml.sh +190 -0
- package/scripts/huddle/huddle-llm.mjs +361 -0
- package/scripts/huddle/huddle-server.mjs +46 -121
- package/scripts/local-triggers/autoupdate.sh +448 -78
- package/scripts/local-triggers/run-trigger.sh +13 -0
- package/scripts/maintenance/pin-integrity.mjs +364 -0
- package/scripts/poll-slack-events.sh +41 -9
- package/scripts/poller/slack-socket-mode.mjs +28 -3
- package/scripts/session/supervisor.mjs +80 -13
- package/scripts/spawn-session.sh +13 -0
- package/bin/maestro.test.mjs +0 -1574
- package/lib/action-executor.test.mjs +0 -871
- package/lib/archetype.test.mjs +0 -132
- package/lib/assurance/plan-note.test.mjs +0 -234
- package/lib/assurance/room-budget.test.mjs +0 -486
- package/lib/assurance/tier.test.mjs +0 -174
- package/lib/autonomy.test.mjs +0 -66
- package/lib/backlog.test.mjs +0 -302
- package/lib/backup/policy.test.mjs +0 -305
- package/lib/budget-escalate.test.mjs +0 -232
- package/lib/budget-guard.envelope.test.mjs +0 -476
- package/lib/budget-guard.test.mjs +0 -427
- package/lib/cadence-bus-requeue.test.mjs +0 -83
- package/lib/cadence-bus-schedule.test.mjs +0 -194
- package/lib/cadence-bus.test.mjs +0 -720
- package/lib/cadences.test.mjs +0 -230
- package/lib/capability/inventory.test.mjs +0 -232
- package/lib/capability.test.mjs +0 -78
- package/lib/channels/base-adapter.test.mjs +0 -590
- package/lib/channels/channels.test.mjs +0 -371
- package/lib/channels/contract.test.mjs +0 -162
- package/lib/channels/inbox-item.test.mjs +0 -368
- package/lib/channels/orgmail/adapter.test.mjs +0 -448
- package/lib/channels/pairing.test.mjs +0 -270
- package/lib/channels/repeat-suppressor.test.mjs +0 -134
- package/lib/channels/slack-adapter.test.mjs +0 -212
- package/lib/channels/telegram-adapter.test.mjs +0 -306
- package/lib/channels/voice/adapter.test.mjs +0 -278
- package/lib/channels/whatsapp/adapter-baileys.test.mjs +0 -359
- package/lib/channels/whatsapp/baileys-typing.test.mjs +0 -154
- package/lib/charter.test.mjs +0 -89
- package/lib/claude-bin.test.mjs +0 -131
- package/lib/cli/board.test.mjs +0 -227
- package/lib/cli/design.test.mjs +0 -270
- package/lib/cli/doctor-checks.test.mjs +0 -336
- package/lib/cli/global-setup-extras.test.mjs +0 -462
- package/lib/cli/inbox.test.mjs +0 -230
- package/lib/cli/session-ack.test.mjs +0 -63
- package/lib/cli/session.test.mjs +0 -613
- package/lib/collective/capture.test.mjs +0 -121
- package/lib/collective/cards.test.mjs +0 -114
- package/lib/collective/config.test.mjs +0 -123
- package/lib/collective/global-config.test.mjs +0 -220
- package/lib/collective/global-skills.test.mjs +0 -126
- package/lib/collective/presence.test.mjs +0 -95
- package/lib/collective/recall.test.mjs +0 -116
- package/lib/collective/vendor-skills.test.mjs +0 -306
- package/lib/comms/send-gate.test.mjs +0 -770
- package/lib/comms.test.mjs +0 -41
- package/lib/cost/ledger-row.test.mjs +0 -183
- package/lib/design/design-md.test.mjs +0 -318
- package/lib/design/fixtures/DESIGN.golden.md +0 -238
- package/lib/design/fixtures/PRODUCT.golden.md +0 -67
- package/lib/design/fixtures/foundation.json +0 -133
- package/lib/design/refresh-gate.test.mjs +0 -144
- package/lib/design/write.test.mjs +0 -241
- package/lib/diagnostics/alerts.test.mjs +0 -318
- package/lib/diagnostics/backup-freshness.test.mjs +0 -185
- package/lib/diagnostics/counters.test.mjs +0 -206
- package/lib/diagnostics/events.test.mjs +0 -290
- package/lib/diagnostics/otel.test.mjs +0 -196
- package/lib/diagnostics/trace.test.mjs +0 -251
- package/lib/env-compat.test.mjs +0 -104
- package/lib/execution/disposition.test.mjs +0 -553
- package/lib/execution/drive.test.mjs +0 -270
- package/lib/execution/effects.test.mjs +0 -344
- package/lib/execution/intake.test.mjs +0 -389
- package/lib/execution/journal.test.mjs +0 -261
- package/lib/execution/match.test.mjs +0 -235
- package/lib/execution/pipeline.test.mjs +0 -392
- package/lib/execution/route.test.mjs +0 -186
- package/lib/execution/surface-policy.test.mjs +0 -162
- package/lib/fs-atomic.test.mjs +0 -72
- package/lib/fs-ownership.test.mjs +0 -158
- package/lib/goals/admission.test.mjs +0 -164
- package/lib/goals/classify.test.mjs +0 -167
- package/lib/goals/collaborate.test.mjs +0 -336
- package/lib/goals/gaps.test.mjs +0 -284
- package/lib/goals/loop.test.mjs +0 -845
- package/lib/hooks/bus.test.mjs +0 -387
- package/lib/identity/persona.test.mjs +0 -142
- package/lib/kpi-sensors.test.mjs +0 -278
- package/lib/kpi.test.mjs +0 -244
- package/lib/learning/config.test.mjs +0 -75
- package/lib/learning/counters.test.mjs +0 -69
- package/lib/learning/curator-consolidate.test.mjs +0 -238
- package/lib/learning/curator.test.mjs +0 -106
- package/lib/learning/reflect.test.mjs +0 -0
- package/lib/learning/session-index.test.mjs +0 -125
- package/lib/learning/skill-writer.test.mjs +0 -210
- package/lib/mandate/audit.test.mjs +0 -195
- package/lib/mandate/contract.test.mjs +0 -185
- package/lib/mandate/derive.test.mjs +0 -274
- package/lib/mandate/model.test.mjs +0 -164
- package/lib/mandate/refresh.test.mjs +0 -389
- package/lib/mcp/server.test.mjs +0 -426
- package/lib/model-router/auth-profiles.test.mjs +0 -580
- package/lib/model-router/catalog.test.mjs +0 -385
- package/lib/model-router/economics.test.mjs +0 -438
- package/lib/model-router/failover.test.mjs +0 -439
- package/lib/model-router/health.test.mjs +0 -338
- package/lib/model-router/integration-coverage.test.mjs +0 -831
- package/lib/model-router/integration.test.mjs +0 -564
- package/lib/model-router/ledger.test.mjs +0 -415
- package/lib/model-router/llm-task.test.mjs +0 -392
- package/lib/model-router/org-credentials.test.mjs +0 -265
- package/lib/model-router/pricing-refresh.test.mjs +0 -286
- package/lib/model-router/reconcile.test.mjs +0 -316
- package/lib/model-router/repair.test.mjs +0 -180
- package/lib/model-router/spawn.test.mjs +0 -446
- package/lib/model-router/taxonomy.test.mjs +0 -410
- package/lib/model-router.test.mjs +0 -1207
- package/lib/org/activity.test.mjs +0 -134
- package/lib/org/approvals.test.mjs +0 -216
- package/lib/org/awareness.test.mjs +0 -159
- package/lib/org/board-mine-cache.test.mjs +0 -53
- package/lib/org/board.test.mjs +0 -187
- package/lib/org/bootstrap-context.test.mjs +0 -153
- package/lib/org/client.test.mjs +0 -1206
- package/lib/org/cohort-client.test.mjs +0 -126
- package/lib/org/cost-sync.test.mjs +0 -153
- package/lib/org/doctor.test.mjs +0 -346
- package/lib/org/engagement-ledger.test.mjs +0 -112
- package/lib/org/engagement.test.mjs +0 -739
- package/lib/org/handoff.test.mjs +0 -269
- package/lib/org/inbound/directedness.test.mjs +0 -668
- package/lib/org/inbound/facts.test.mjs +0 -471
- package/lib/org/inbound/hydrate.test.mjs +0 -453
- package/lib/org/inbound/index.test.mjs +0 -429
- package/lib/org/inbound/project.test.mjs +0 -287
- package/lib/org/integration-tools.test.mjs +0 -160
- package/lib/org/keys.test.mjs +0 -92
- package/lib/org/knowledge.test.mjs +0 -326
- package/lib/org/leases.test.mjs +0 -235
- package/lib/org/mesh-directives.test.mjs +0 -110
- package/lib/org/mesh-integration.test.mjs +0 -127
- package/lib/org/mesh.test.mjs +0 -400
- package/lib/org/messaging.test.mjs +0 -471
- package/lib/org/param-contract.test.mjs +0 -477
- package/lib/org/policy.test.mjs +0 -237
- package/lib/org/protocol.checksum.test.mjs +0 -90
- package/lib/org/protocol.test.mjs +0 -323
- package/lib/org/push.test.mjs +0 -792
- package/lib/org/registry.test.mjs +0 -100
- package/lib/org/resource-tools.test.mjs +0 -361
- package/lib/org/tool-access.test.mjs +0 -144
- package/lib/org/tool-surface-integration.test.mjs +0 -120
- package/lib/org/tool-surface.test.mjs +0 -1268
- package/lib/org/typing.test.mjs +0 -291
- package/lib/org/ui-parity.test.mjs +0 -560
- package/lib/org/verify.test.mjs +0 -194
- package/lib/org/work-ledger.test.mjs +0 -273
- package/lib/plan/adoption-e2e.test.mjs +0 -366
- package/lib/plan/budget-enforcement.test.mjs +0 -400
- package/lib/plan/compile.test.mjs +0 -382
- package/lib/plan/emit.test.mjs +0 -269
- package/lib/plan/explain.test.mjs +0 -188
- package/lib/prompts/parallelism.test.mjs +0 -177
- package/lib/rag/rag.test.mjs +0 -505
- package/lib/rate-guard.test.mjs +0 -272
- package/lib/reactive-gate.test.mjs +0 -57
- package/lib/render.test.mjs +0 -68
- package/lib/resource-governor.test.mjs +0 -488
- package/lib/scheduling/dynamic-jobs.test.mjs +0 -344
- package/lib/scheduling/jitter.test.mjs +0 -140
- package/lib/secrets/broker.test.mjs +0 -280
- package/lib/secrets/providers.test.mjs +0 -274
- package/lib/security/audit-engine.test.mjs +0 -424
- package/lib/security/coerce-args.test.mjs +0 -281
- package/lib/security/dangerous-tools.test.mjs +0 -68
- package/lib/security/external-content.test.mjs +0 -84
- package/lib/security/redact.test.mjs +0 -441
- package/lib/security/secret-equal.test.mjs +0 -55
- package/lib/session/config.test.mjs +0 -92
- package/lib/session/feed-core.test.mjs +0 -198
- package/lib/session/first-run.test.mjs +0 -121
- package/lib/session/frontdoor.test.mjs +0 -205
- package/lib/session/handoffs.test.mjs +0 -183
- package/lib/session/identity.test.mjs +0 -180
- package/lib/session/inbox-claims.test.mjs +0 -286
- package/lib/session/launch-args.test.mjs +0 -157
- package/lib/session/liveness.test.mjs +0 -100
- package/lib/session/status-summary.test.mjs +0 -118
- package/lib/session-permissions.test.mjs +0 -120
- package/lib/setup/claude-probe.test.mjs +0 -187
- package/lib/setup/completeness.test.mjs +0 -110
- package/lib/setup/context-pack.test.mjs +0 -89
- package/lib/setup/enrich.test.mjs +0 -115
- package/lib/setup/enroll-from-cohort.test.mjs +0 -300
- package/lib/setup/integration.test.mjs +0 -162
- package/lib/setup/io.test.mjs +0 -77
- package/lib/setup/runner.test.mjs +0 -132
- package/lib/setup/sections/identity.test.mjs +0 -234
- package/lib/setup/sections/inventory.test.mjs +0 -198
- package/lib/setup/sections/learning.test.mjs +0 -81
- package/lib/setup/sections/mandate.test.mjs +0 -388
- package/lib/setup/sections/messaging.test.mjs +0 -127
- package/lib/setup/sections/model.test.mjs +0 -240
- package/lib/setup/sections/org.test.mjs +0 -346
- package/lib/setup/sections/orgmail.test.mjs +0 -118
- package/lib/setup/sections/recovery.test.mjs +0 -98
- package/lib/setup/sections/subagents.test.mjs +0 -429
- package/lib/setup/sections/verify.test.mjs +0 -175
- package/lib/setup/sot.test.mjs +0 -81
- package/lib/setup/state.test.mjs +0 -115
- package/lib/singleton.test.mjs +0 -151
- package/lib/subagents/cli.test.mjs +0 -389
- package/lib/subagents/client.test.mjs +0 -309
- package/lib/subagents/gap.test.mjs +0 -234
- package/lib/subagents/lock.test.mjs +0 -248
- package/lib/subagents/manifest.test.mjs +0 -175
- package/lib/subagents/refs.test.mjs +0 -204
- package/lib/subagents/resolve.test.mjs +0 -422
- package/lib/subagents/schema.test.mjs +0 -328
- package/lib/telemetry/alerts.test.mjs +0 -109
- package/lib/telemetry/collect.test.mjs +0 -1274
- package/lib/tool-definitions-integration.test.mjs +0 -83
- package/lib/tool-definitions.test.mjs +0 -437
- package/lib/upgrade/global-refresh.test.mjs +0 -65
- package/lib/upgrade/launchd-reconcile.test.mjs +0 -272
- package/lib/upgrade/post-steps.test.mjs +0 -200
- package/lib/upgrade/verify.test.mjs +0 -164
- package/lib/util/fetch-timeout.test.mjs +0 -202
- package/lib/util/reconnect.test.mjs +0 -369
- package/lib/util/unhandled.test.mjs +0 -216
- package/lib/voice/outbound.test.mjs +0 -69
- package/lib/voice/session-rotation.test.mjs +0 -114
- package/lib/voice/stt.test.mjs +0 -226
- package/lib/voice/voice.test.mjs +0 -990
- package/scripts/cadence/enqueue-cadence-tick.test.mjs +0 -187
- package/scripts/ci/check-docs-accuracy.test.mjs +0 -409
- package/scripts/ci/check-durable-write-seam.test.mjs +0 -90
- package/scripts/ci/check-no-build-artifacts.test.mjs +0 -71
- package/scripts/ci/check-no-residual-identity.test.mjs +0 -202
- package/scripts/ci/check-skill-packs.test.mjs +0 -495
- package/scripts/ci/check-subagent-frontmatter.test.mjs +0 -124
- package/scripts/ci/check.test.mjs +0 -194
- package/scripts/ci/conformance-org-api.test.mjs +0 -425
- package/scripts/cloud-relay/voice/relay-identity.test.mjs +0 -96
- package/scripts/collective/hook-runner.test.mjs +0 -173
- package/scripts/cost/fleet-digest.test.mjs +0 -207
- package/scripts/cost/track-claude-usage-pricing.test.mjs +0 -183
- package/scripts/cost/track-claude-usage.test.mjs +0 -148
- package/scripts/daemon/agent-daemon-board-mine.test.mjs +0 -96
- package/scripts/daemon/agent-daemon-design.test.mjs +0 -238
- package/scripts/daemon/agent-daemon-frontdoor.test.mjs +0 -60
- package/scripts/daemon/agent-daemon.test.mjs +0 -995
- package/scripts/daemon/assurance-e2e.test.mjs +0 -613
- package/scripts/daemon/assurance.test.mjs +0 -1791
- package/scripts/daemon/board-mirror.test.mjs +0 -165
- package/scripts/daemon/cadence-consumer-frontdoor.test.mjs +0 -393
- package/scripts/daemon/cadence-consumer-governance.test.mjs +0 -276
- package/scripts/daemon/cadence-consumer.test.mjs +0 -776
- package/scripts/daemon/cadence-handlers.test.mjs +0 -837
- package/scripts/daemon/classifier-identity.test.mjs +0 -137
- package/scripts/daemon/classifier.test.mjs +0 -266
- package/scripts/daemon/classify-kind.test.mjs +0 -40
- package/scripts/daemon/context-compiler.test.mjs +0 -300
- package/scripts/daemon/deliver.test.mjs +0 -564
- package/scripts/daemon/dispatcher-cooldown.test.mjs +0 -122
- package/scripts/daemon/dispatcher-governance.test.mjs +0 -1013
- package/scripts/daemon/dispatcher-resume.test.mjs +0 -166
- package/scripts/daemon/execution-ladder.test.mjs +0 -470
- package/scripts/daemon/goal-steward-cadence.test.mjs +0 -312
- package/scripts/daemon/inbox-deferral-session.test.mjs +0 -49
- package/scripts/daemon/inbox-deferral.test.mjs +0 -336
- package/scripts/daemon/inbox-wake.test.mjs +0 -199
- package/scripts/daemon/integration.test.mjs +0 -149
- package/scripts/daemon/lib/self-echo.test.mjs +0 -153
- package/scripts/daemon/lib/session-router.test.mjs +0 -295
- package/scripts/daemon/prompt-builder-preamble.test.mjs +0 -210
- package/scripts/daemon/prompt-builder.test.mjs +0 -344
- package/scripts/daemon/responder-cost.test.mjs +0 -68
- package/scripts/daemon/responder-history.test.mjs +0 -185
- package/scripts/daemon/sdk-version.test.mjs +0 -31
- package/scripts/daemon/session-lock.test.mjs +0 -252
- package/scripts/daemon/session-outcomes.test.mjs +0 -533
- package/scripts/daemon/typing-registry.test.mjs +0 -102
- package/scripts/hooks/pre-send-audit.test.mjs +0 -354
- package/scripts/huddle/huddle-prompt.test.mjs +0 -176
- package/scripts/local-triggers/autoupdate.test.mjs +0 -518
- package/scripts/local-triggers/generate-plists.test.mjs +0 -456
- package/scripts/media-generation/brand-clause.test.mjs +0 -135
- package/scripts/org/send-orgmail.first-contact.test.mjs +0 -102
- package/scripts/poller/inbox-privilege-injection.test.mjs +0 -167
- package/scripts/poller/inbox-scan-poller.test.mjs +0 -295
- package/scripts/poller/lib/cloud-relay-dedup.test.mjs +0 -133
- package/scripts/poller/slack-socket-mode.test.mjs +0 -805
- package/scripts/poller-launchd/install.test.mjs +0 -243
- package/scripts/restore-from-backup.test.mjs +0 -181
- package/scripts/session/feed.test.mjs +0 -196
- package/scripts/session/supervisor-sh.test.mjs +0 -218
- package/scripts/session/supervisor.test.mjs +0 -482
- package/scripts/setup/configure-macos.test.mjs +0 -306
- package/scripts/setup/gen-subagent-manifest.test.mjs +0 -124
- package/scripts/setup/generate-agent-package-json.test.mjs +0 -143
- package/scripts/setup/generate-capability.test.mjs +0 -134
- package/scripts/setup/init-agent.test.mjs +0 -370
- package/scripts/setup/init-skill-marketplace.test.mjs +0 -193
- package/scripts/vendor/sync-skill-packs.test.mjs +0 -103
- package/scripts/watchdog/memory-watchdog.test.mjs +0 -64
package/.claude/settings.json
CHANGED
|
@@ -122,6 +122,15 @@
|
|
|
122
122
|
"command": "./scripts/hooks/block-mcp-cohort-send.sh"
|
|
123
123
|
}
|
|
124
124
|
]
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"matcher": "Write|Edit",
|
|
128
|
+
"hooks": [
|
|
129
|
+
{
|
|
130
|
+
"type": "command",
|
|
131
|
+
"command": "node ./scripts/hooks/pre-write-yaml-validate.mjs"
|
|
132
|
+
}
|
|
133
|
+
]
|
|
125
134
|
}
|
|
126
135
|
],
|
|
127
136
|
"PostToolUse": [
|
|
@@ -133,6 +142,15 @@
|
|
|
133
142
|
"command": "./scripts/hooks/post-action-log.sh"
|
|
134
143
|
}
|
|
135
144
|
]
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"matcher": "Bash|Write|Edit",
|
|
148
|
+
"hooks": [
|
|
149
|
+
{
|
|
150
|
+
"type": "command",
|
|
151
|
+
"command": "./scripts/hooks/validate-state-yaml.sh"
|
|
152
|
+
}
|
|
153
|
+
]
|
|
136
154
|
}
|
|
137
155
|
],
|
|
138
156
|
"Stop": [
|
package/.env.example
CHANGED
|
@@ -63,7 +63,7 @@ COHORT_AGENT_EMAIL=
|
|
|
63
63
|
# is in effect and what `claude auth status` reports (presence of a credential,
|
|
64
64
|
# not its validity — a bad token surfaces on the first real spawn).
|
|
65
65
|
#
|
|
66
|
-
# Option A — subscription OAuth token
|
|
66
|
+
# Option A — subscription OAuth token (NOT the fleet posture — see Option C)
|
|
67
67
|
# On ANY machine where you are logged in to Claude Code, run
|
|
68
68
|
# claude setup-token
|
|
69
69
|
# and paste the long-lived token below, together with
|
|
@@ -72,25 +72,38 @@ COHORT_AGENT_EMAIL=
|
|
|
72
72
|
# keychain login is NOT relied on because it expires headlessly. The token is
|
|
73
73
|
# per seat; mint a fresh one with the same command when it is rejected.
|
|
74
74
|
# Headless setup reads it from the environment: CLAUDE_CODE_OAUTH_TOKEN=… maestro setup --headless
|
|
75
|
+
# It still RUNS, but it has no per-agent ceiling and no central spend
|
|
76
|
+
# visibility: do NOT provision a new agent seat on it (gate G4).
|
|
75
77
|
CLAUDE_CODE_OAUTH_TOKEN=
|
|
76
78
|
|
|
77
79
|
# Option B — keychain login on this machine (interactive / dev boxes only)
|
|
78
80
|
# `claude login` here, leave CLAUDE_CODE_OAUTH_TOKEN and ANTHROPIC_API_KEY
|
|
79
81
|
# empty, set MAESTRO_PREFER_SUBSCRIPTION_AUTH=1. Doctor warns: the login
|
|
80
|
-
# expires headlessly and
|
|
82
|
+
# expires headlessly and an agent seat belongs on Option C.
|
|
81
83
|
#
|
|
82
84
|
# Set to 1 for Option A and Option B: every claude spawn strips
|
|
83
85
|
# ANTHROPIC_API_KEY from its env so claude rides the subscription (token or
|
|
84
86
|
# keychain) — routine cadence ticks then cost zero API credits.
|
|
85
87
|
MAESTRO_PREFER_SUBSCRIPTION_AUTH=
|
|
86
88
|
|
|
87
|
-
# Option C — API key (pay-per-token)
|
|
88
|
-
# Set ANTHROPIC_API_KEY to a valid sk-ant-api03-... key
|
|
89
|
-
#
|
|
89
|
+
# Option C — API key (pay-per-token) ← THE FLEET POSTURE (agent seats)
|
|
90
|
+
# Set ANTHROPIC_API_KEY to a valid sk-ant-api03-... key created INSIDE a
|
|
91
|
+
# Console workspace with a monthly spend cap, one workspace per agent, and
|
|
92
|
+
# leave the two above empty. Get one:
|
|
93
|
+
# https://console.anthropic.com/settings/keys
|
|
90
94
|
# Doctor validates it against api.anthropic.com on every run; an invalid
|
|
91
95
|
# key cascades 401s through every sub-session spawn.
|
|
96
|
+
# Runbook: docs/guides/billing-console-keys.md
|
|
92
97
|
ANTHROPIC_API_KEY=
|
|
93
98
|
|
|
99
|
+
# OPTIONAL — Arm the G4 guard. `maestro doctor` and `maestro seat-auth` WARN on
|
|
100
|
+
# a seat still using subscription OAuth (and on a seat carrying both rails,
|
|
101
|
+
# which is ambiguous about where its spend lands). Set this to 1 and those
|
|
102
|
+
# warnings become failures — do that once the fleet has migrated, so a seat that
|
|
103
|
+
# regresses to a subscription token announces itself. Never fails an
|
|
104
|
+
# engine=cohort seat that holds no Anthropic credential: that is its posture.
|
|
105
|
+
MAESTRO_REQUIRE_CONSOLE_KEY=
|
|
106
|
+
|
|
94
107
|
# OPTIONAL — Supplemental model access (GPT-4, embeddings)
|
|
95
108
|
# Get your key: https://platform.openai.com/api-keys
|
|
96
109
|
# Subscription: OpenAI API plan (pay-per-token)
|
|
@@ -226,6 +239,9 @@ GREPTILE_API_KEY=
|
|
|
226
239
|
# Flags that control system behaviour. These are not secrets.
|
|
227
240
|
#
|
|
228
241
|
|
|
229
|
-
#
|
|
230
|
-
#
|
|
242
|
+
# The session context compiler: pre-compile context before each Claude Code
|
|
243
|
+
# session. ON BY DEFAULT in code as well as here — the two used to disagree
|
|
244
|
+
# (code read `=== "1"`, this file shipped `=1`), so which of two materially
|
|
245
|
+
# different context paths ran depended on whether the operator had copied this
|
|
246
|
+
# file. Set to 0 only to fall back to the legacy path in a hurry.
|
|
231
247
|
DAEMON_CONTEXT_COMPILER=1
|
package/README.md
CHANGED
|
@@ -161,6 +161,7 @@ Verifies the agent installation end-to-end. Checks include:
|
|
|
161
161
|
- **Config:** `config/environment.yaml`, `config/contacts.yaml`, `config/priorities.yaml`, `config/sla-defaults.yaml`.
|
|
162
162
|
- **State:** `state/dashboards/executive-summary.yaml`, `state/queues/action-stack.yaml`, `knowledge/decisions/decision-schema.yaml`.
|
|
163
163
|
- **Environment:** `.env` file with `ANTHROPIC_API_KEY` (required), `SLACK_USER_TOKEN`, `GMAIL_APP_PASSWORD` (optional).
|
|
164
|
+
- **Billing rail (G4):** which Claude rail this seat is on — `api-key` (the fleet posture: a per-agent Console key in a capped workspace), `subscription`, `both` (ambiguous, flagged loudly) or `neither`. Variable **names** only; no credential value is ever printed. A warning today; `MAESTRO_REQUIRE_CONSOLE_KEY=1` turns it into a failure once the fleet has migrated. `maestro seat-auth --row` prints the paste-able inventory row and `maestro seat-auth --fleet` the template it pastes into — see [billing: Console API keys](docs/guides/billing-console-keys.md).
|
|
164
165
|
- **Dependencies:** `node_modules` installed, Claude CLI available, jq available, emergency-stop script present.
|
|
165
166
|
|
|
166
167
|
Doctor exits non-zero when issues are found and prints actionable remediation (most commonly: `npx @cohortapp/agent-sdk upgrade`). Doctor also verifies the collective-memory wiring (see below).
|
package/bin/maestro.mjs
CHANGED
|
@@ -37,6 +37,7 @@ import { runAudit, applyFixes, buildAttestation } from "../lib/security/audit-en
|
|
|
37
37
|
import { selectProvider } from "../lib/secrets/providers.mjs";
|
|
38
38
|
import { syncSecrets, rotateSecret, makeBroker, auditLogPath } from "../lib/secrets/broker.mjs";
|
|
39
39
|
import { applyBrandEnvCompat } from "../lib/env-compat.mjs";
|
|
40
|
+
import { buildIgnoredDriftReport, formatIgnoredLine, IGNORED_DRIFT_REL } from "../lib/upgrade/ignored-drift.mjs";
|
|
40
41
|
|
|
41
42
|
// Fleet back-compat FIRST: bridge NEOLITH_* ⇄ COHORT_* env names before any
|
|
42
43
|
// env-first resolution below — installed hosts still export the legacy names.
|
|
@@ -1249,6 +1250,8 @@ Per-file behaviour:
|
|
|
1249
1250
|
const counts = { added: 0, updated: 0, same: 0, ignored: 0, preserved: 0, mergeKept: 0, forced: 0, pruned: 0, pruneKept: 0 };
|
|
1250
1251
|
const preservedFiles = [];
|
|
1251
1252
|
const ignoredFiles = [];
|
|
1253
|
+
// repoRel → the upstream file the protection kept out (null when upstream ships nothing there): the drift report's input.
|
|
1254
|
+
const ignoredSources = new Map();
|
|
1252
1255
|
const prunedFiles = [];
|
|
1253
1256
|
const pruneKeptFiles = [];
|
|
1254
1257
|
// What upstream ships right now — becomes this machine's provenance record.
|
|
@@ -1276,6 +1279,7 @@ Per-file behaviour:
|
|
|
1276
1279
|
if (isIgnored) {
|
|
1277
1280
|
counts.ignored++;
|
|
1278
1281
|
ignoredFiles.push(repoRel);
|
|
1282
|
+
ignoredSources.set(repoRel, srcFile);
|
|
1279
1283
|
if (flags.verbose) console.log(` · ${repoRel} (ignored via .maestroignore)`);
|
|
1280
1284
|
continue;
|
|
1281
1285
|
}
|
|
@@ -1414,6 +1418,7 @@ Per-file behaviour:
|
|
|
1414
1418
|
if (matchesIgnore(repoRel, ignorePatterns)) {
|
|
1415
1419
|
counts.ignored++;
|
|
1416
1420
|
ignoredFiles.push(repoRel);
|
|
1421
|
+
ignoredSources.set(repoRel, null);
|
|
1417
1422
|
if (flags.verbose) console.log(` · ${repoRel} (orphan, ignored via .maestroignore)`);
|
|
1418
1423
|
continue;
|
|
1419
1424
|
}
|
|
@@ -1504,6 +1509,7 @@ Per-file behaviour:
|
|
|
1504
1509
|
if (matchesIgnore(repoRel, ignorePatterns)) {
|
|
1505
1510
|
counts.ignored++;
|
|
1506
1511
|
ignoredFiles.push(repoRel);
|
|
1512
|
+
ignoredSources.set(repoRel, src);
|
|
1507
1513
|
if (flags.verbose) console.log(` · ${repoRel} (ignored via .maestroignore)`);
|
|
1508
1514
|
continue;
|
|
1509
1515
|
}
|
|
@@ -1596,6 +1602,26 @@ Per-file behaviour:
|
|
|
1596
1602
|
if (counts.updated) ok(`${counts.updated} updated (vendored, no local edits)`);
|
|
1597
1603
|
if (counts.same) console.log(` = ${counts.same} already up-to-date`);
|
|
1598
1604
|
if (counts.ignored) console.log(` · ${counts.ignored} ignored (.maestroignore protected)`);
|
|
1605
|
+
// A protected file is a fork the operator owns; "N ignored" hid how far
|
|
1606
|
+
// upstream had moved under each one. Say it per file, and keep the answer
|
|
1607
|
+
// in .maestro/ignored-drift.json for doctor and the next reader.
|
|
1608
|
+
let ignoredDrift = null;
|
|
1609
|
+
if (ignoredFiles.length) {
|
|
1610
|
+
const readOrNull = (p) => { try { return p && existsSync(p) ? readFileSync(p, "utf8") : null; } catch { return null; } };
|
|
1611
|
+
ignoredDrift = buildIgnoredDriftReport(
|
|
1612
|
+
[...new Set(ignoredFiles)].sort().map((repoRel) => ({ path: repoRel, local: readOrNull(join(cwd, repoRel)), upstream: readOrNull(ignoredSources.get(repoRel)) })),
|
|
1613
|
+
{ sdkVersion: readFrameworkVersion(), at: new Date().toISOString() },
|
|
1614
|
+
);
|
|
1615
|
+
for (const f of ignoredDrift.files) console.log(formatIgnoredLine(f));
|
|
1616
|
+
if (ignoredDrift.counts.drifts) warn(`${ignoredDrift.counts.drifts} protected file(s) drift from upstream — every upstream fix to those paths stops here until you port it (diff each against node_modules/@cohortapp/agent-sdk/<path>)`);
|
|
1617
|
+
if (!flags.dryRun) {
|
|
1618
|
+
try {
|
|
1619
|
+
const out = join(cwd, IGNORED_DRIFT_REL);
|
|
1620
|
+
mkdirSync(dirname(out), { recursive: true });
|
|
1621
|
+
writeFileSync(out, JSON.stringify(ignoredDrift, null, 2) + "\n");
|
|
1622
|
+
} catch (e) { warn(`could not write ${IGNORED_DRIFT_REL}: ${e && e.message ? e.message : e}`); }
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1599
1625
|
if (counts.mergeKept) console.log(` ~ ${counts.mergeKept} merge-mode kept (agents/ custom files preserved)`);
|
|
1600
1626
|
if (counts.preserved) warn(`${counts.preserved} preserved (local edits — kept your version)`);
|
|
1601
1627
|
if (counts.forced) warn(`${counts.forced} force-overwritten (backups in .maestro/backup/)`);
|
|
@@ -3341,6 +3367,38 @@ async function globalSetup(args = []) {
|
|
|
3341
3367
|
ok("global hooks already present (no change)");
|
|
3342
3368
|
}
|
|
3343
3369
|
|
|
3370
|
+
// 1b) Per-seat .claude/settings.json: the state-YAML gate hooks (PreToolUse on
|
|
3371
|
+
// Write|Edit, PostToolUse on Bash|Write|Edit). These belong in the SEAT file,
|
|
3372
|
+
// not ~/.claude — their commands are seat-relative and only mean anything
|
|
3373
|
+
// inside an agent repo. A hand edit there does not survive a fresh checkout
|
|
3374
|
+
// or an upgrade, which is why the scaffold copy carries them for new seats
|
|
3375
|
+
// and this merge carries them onto existing ones (upgrade runs global-setup
|
|
3376
|
+
// as a post-step). Deep-merged, idempotent, backed up before write.
|
|
3377
|
+
{
|
|
3378
|
+
const seatSettingsPath = join(cwd, ".claude", "settings.json");
|
|
3379
|
+
let seat = {};
|
|
3380
|
+
if (existsSync(seatSettingsPath)) {
|
|
3381
|
+
try { seat = JSON.parse(readFileSync(seatSettingsPath, "utf-8")); } catch { seat = null; }
|
|
3382
|
+
}
|
|
3383
|
+
if (seat === null) {
|
|
3384
|
+
warn(`${seatSettingsPath} is not valid JSON — state-YAML gate hooks not merged (repair it, then re-run global-setup)`);
|
|
3385
|
+
} else {
|
|
3386
|
+
const merged = gc.mergeStateYamlGateHooks(seat);
|
|
3387
|
+
if (merged.added.length > 0) {
|
|
3388
|
+
if (!dryRun) {
|
|
3389
|
+
mkdirSync(dirname(seatSettingsPath), { recursive: true });
|
|
3390
|
+
if (existsSync(seatSettingsPath)) {
|
|
3391
|
+
try { copyFileSync(seatSettingsPath, `${seatSettingsPath}.backup.${tsStamp()}`); } catch { /* */ }
|
|
3392
|
+
}
|
|
3393
|
+
writeFileSync(seatSettingsPath, JSON.stringify(merged.settings, null, 2) + "\n");
|
|
3394
|
+
}
|
|
3395
|
+
ok(`${dryRun ? "[dry-run] " : ""}seat hooks added to .claude/settings.json: ${merged.added.join(", ")}`);
|
|
3396
|
+
} else {
|
|
3397
|
+
ok("seat state-YAML gate hooks already present (no change)");
|
|
3398
|
+
}
|
|
3399
|
+
}
|
|
3400
|
+
}
|
|
3401
|
+
|
|
3344
3402
|
// 2) global CLAUDE.md directive (only our delimited block is touched).
|
|
3345
3403
|
let mdContent = "";
|
|
3346
3404
|
if (existsSync(claudeMdPath)) { try { mdContent = readFileSync(claudeMdPath, "utf-8"); } catch { /* */ } }
|
|
@@ -3806,9 +3864,11 @@ switch (command) {
|
|
|
3806
3864
|
case "who-owns": case "who": await whoOwnsCmd(args); break;
|
|
3807
3865
|
case "inbox": process.exitCode = await (await import("../lib/cli/inbox.mjs")).runInbox(args); break;
|
|
3808
3866
|
case "session-ack": process.exitCode = await (await import("../lib/cli/session-ack.mjs")).runSessionAck(args); break;
|
|
3867
|
+
case "seat-auth": process.exitCode = await (await import("../lib/cli/seat-auth.mjs")).runSeatAuth(args); break;
|
|
3809
3868
|
case "session": { const r = await (await import("../lib/cli/session.mjs")).run(args); process.exitCode = r.code; break; }
|
|
3810
3869
|
case "board": await (await import("../lib/cli/board.mjs")).boardCmd(args); break;
|
|
3811
3870
|
case "design": await (await import("../lib/cli/design.mjs")).designCmd(args); break;
|
|
3871
|
+
case "run": process.exitCode = await (await import("../lib/engine/cli.mjs")).runFromProcess(args); break;
|
|
3812
3872
|
case "init":
|
|
3813
3873
|
case "update-init":
|
|
3814
3874
|
case "init-update":
|
|
@@ -3836,9 +3896,11 @@ Usage:
|
|
|
3836
3896
|
npx @cohortapp/agent-sdk who-owns <scope> Who owns a scope / escalate-to / reports (org context, zero-LLM)
|
|
3837
3897
|
npx @cohortapp/agent-sdk inbox list|show|claim|reply|done|defer The main session's inbox (JSON; shares the daemon's markers)
|
|
3838
3898
|
npx @cohortapp/agent-sdk session-ack <tickId> Ack a cadence tick handed to the main session
|
|
3899
|
+
npx @cohortapp/agent-sdk seat-auth [--row|--fleet] Which Claude billing rail this seat is on (G4) — variable NAMES only, never a value
|
|
3839
3900
|
npx @cohortapp/agent-sdk session <cmd> Front-door session: status|attach|start|stop|restart|spawn|peers|handoffs|ack
|
|
3840
3901
|
npx @cohortapp/agent-sdk board mine|track|claim|complete Your work across every board (maestro board --help)
|
|
3841
3902
|
npx @cohortapp/agent-sdk design sync [--out <dir>] Pull the brand foundation → DESIGN.md + PRODUCT.md
|
|
3903
|
+
npx @cohortapp/agent-sdk run -p "<prompt>" [flags] Cohort Engine, headless (cohort run --help)
|
|
3842
3904
|
|
|
3843
3905
|
Upgrade flags:
|
|
3844
3906
|
--dry-run, -n Preview changes without writing
|
|
@@ -65,6 +65,7 @@ make per-agent spend attribution and revocation possible).
|
|
|
65
65
|
|
|
66
66
|
```sh
|
|
67
67
|
maestro doctor # validates ANTHROPIC_API_KEY against api.anthropic.com
|
|
68
|
+
maestro seat-auth # which rail this seat is on, by variable NAME (see below)
|
|
68
69
|
```
|
|
69
70
|
|
|
70
71
|
After the cost-telemetry work (roadmap item 0.3) lands, `maestro doctor` also
|
|
@@ -72,6 +73,65 @@ turns RED when sessions have run but recorded spend is $0, and a nightly digest
|
|
|
72
73
|
reconciles the local ledger against the Admin Cost API. Until then, confirm spend
|
|
73
74
|
is accruing in the Console workspace view for a canary agent.
|
|
74
75
|
|
|
76
|
+
## The tooling: `maestro seat-auth` (G4)
|
|
77
|
+
|
|
78
|
+
A seat can state, about itself, which rail it is on — and the answer is a
|
|
79
|
+
**verdict over variable names**, never a value. Nothing here prints, logs or
|
|
80
|
+
stores a credential, not even truncated.
|
|
81
|
+
|
|
82
|
+
| Verdict | Meaning | Doctor level |
|
|
83
|
+
| -------------- | ---------------------------------------------------------------------- | -------------------------------- |
|
|
84
|
+
| `api-key` | `ANTHROPIC_API_KEY` only — the fleet posture | ok |
|
|
85
|
+
| `subscription` | `MAESTRO_PREFER_SUBSCRIPTION_AUTH` and/or `CLAUDE_CODE_OAUTH_TOKEN` | warn (fail when armed, below) |
|
|
86
|
+
| `both` | a Console key **and** a subscription credential on the same seat | warn (fail when armed) — loud |
|
|
87
|
+
| `neither` | no Claude credential at all | fail — except on an engine-cohort seat, where it is expected |
|
|
88
|
+
|
|
89
|
+
**`both` is its own verdict and is worth flagging loudly.** It is not "half
|
|
90
|
+
migrated": it is ambiguous. The runtime adapter blanks `ANTHROPIC_API_KEY` on a
|
|
91
|
+
seat that `subscriptionAuth()` calls true (`lib/runtime/adapter.mjs`), so the
|
|
92
|
+
subscription rail wins the lanes that go through the adapter while a lane that
|
|
93
|
+
passes the environment straight through may use the key. Spend then lands in
|
|
94
|
+
two places and neither is authoritative. Migrate, do not stack.
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
maestro seat-auth # the verdict, the names present, the remediation
|
|
98
|
+
maestro seat-auth --json # the same, machine-readable
|
|
99
|
+
maestro seat-auth --row # ONE markdown row to paste into the fleet inventory
|
|
100
|
+
maestro seat-auth --fleet # the inventory template, one row per org member
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The same verdict appears as a row in `maestro doctor`, so an operator who runs
|
|
104
|
+
only doctor still sees it.
|
|
105
|
+
|
|
106
|
+
### The fleet inventory
|
|
107
|
+
|
|
108
|
+
A seat's environment lives on the seat's own machine. There is no remote
|
|
109
|
+
inventory mechanism and this tooling does not invent one. So the fleet report is
|
|
110
|
+
a **template plus paste-able rows**: run `maestro seat-auth --fleet` once (it
|
|
111
|
+
pre-fills one row per member from the org directory), then on each machine run
|
|
112
|
+
`maestro seat-auth --row` and paste the line over that seat's row. The measured
|
|
113
|
+
columns — seat, agent id, machine, verdict, which variable names are present,
|
|
114
|
+
when it was checked — fill themselves; the Console-side columns (account,
|
|
115
|
+
workspace, cap, key id last 4, revocation date) stay blank, because only a human
|
|
116
|
+
with Console access knows them and a tool that guessed them would teach people
|
|
117
|
+
to trust a guess.
|
|
118
|
+
|
|
119
|
+
### Arming the guard
|
|
120
|
+
|
|
121
|
+
The check **warns** by default, deliberately: seats are live, and a check that
|
|
122
|
+
failed on the day it shipped would break the seats it exists to move. Once every
|
|
123
|
+
row of the inventory reads `api-key`, set
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
MAESTRO_REQUIRE_CONSOLE_KEY=1
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
in each seat's `.env` (or the fleet's environment). `subscription` and `both`
|
|
130
|
+
then FAIL `maestro doctor` and exit 1 from `maestro seat-auth`, so a seat that
|
|
131
|
+
regresses to a subscription token announces itself instead of quietly billing a
|
|
132
|
+
personal plan. Record the date it was set fleet-wide — that, plus the last token
|
|
133
|
+
revocation, is what closes this gate.
|
|
134
|
+
|
|
75
135
|
## What is automated vs human
|
|
76
136
|
|
|
77
137
|
maestro cannot create Console workspaces or keys for you — that requires a human
|
|
@@ -177,15 +177,60 @@ summary and in `.maestro/upgrade-result.json` `{from, to, at, steps}`:
|
|
|
177
177
|
| `globalInstall` | `npm i -g @cohortapp/agent-sdk@<this version>` so `maestro` / `cohort` / `cohort-mcp` on PATH match the agent dir (`MAESTRO_SKIP_GLOBAL_INSTALL=1` skips) |
|
|
178
178
|
| `verify` | the `maestro upgrade --verify` report, below |
|
|
179
179
|
|
|
180
|
-
autoupdate then kickstarts the daemon and health-gates it
|
|
181
|
-
|
|
182
|
-
line, and
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
180
|
+
autoupdate then kickstarts the daemon and health-gates it. **The gate means
|
|
181
|
+
health, not "running"** — it used to be "pid alive + a fresh `org-mesh
|
|
182
|
+
connected` line", and a crash-looping daemon satisfies both (launchd respawns
|
|
183
|
+
it, and every respawn prints the line again): one seat logged `up to date
|
|
184
|
+
(2.17.0)` hourly for six days, 2026-09-15..21, while its daemon died ~25 s
|
|
185
|
+
after every start, and the org saw no presence beat from it for ten days. The
|
|
186
|
+
daemon now has to answer all of:
|
|
187
|
+
|
|
188
|
+
- **pid stability** — the daemon pid set is unchanged across two samples 90 s
|
|
189
|
+
apart and every pid's `ps etime` is ≥ 90 s (3× the observed crash
|
|
190
|
+
interval, well inside the hourly cadence; `MAESTRO_AUTOUPDATE_STABLE_S`);
|
|
191
|
+
- **no fatal line** in its own log since the restart (`[DAEMON]
|
|
192
|
+
uncaughtException:`, `[daemon] Fatal:`, `[wrapper] FATAL:`,
|
|
193
|
+
`ERR_MODULE_NOT_FOUND`) — the log has no per-line timestamps and the
|
|
194
|
+
wrapper names the file for the day the process started, so "since the
|
|
195
|
+
restart" is a line offset taken before the kickstart;
|
|
196
|
+
- **an org-acknowledged beat** — `state/org/last-beat.json` `{at, ok, code?}`,
|
|
197
|
+
which `lib/org/mesh.mjs` overwrites on every presence beat (`ok:true` only
|
|
198
|
+
when the org answered 2xx), must say `ok:true`, post-date the daemon's start
|
|
199
|
+
and be younger than 5 min (`MAESTRO_AUTOUPDATE_BEAT_FRESH_S`, the same bar
|
|
200
|
+
after which hq's presence view calls a seat offline). Skipped only for a
|
|
201
|
+
seat `config/org.yaml` does not enrol.
|
|
202
|
+
|
|
203
|
+
When a `-session` plist was generated, the session label must also be loaded
|
|
204
|
+
with a live supervisor process; a missing session is logged as
|
|
205
|
+
`reconcile-failed` and does **not** roll back (the daemon's `--print` lane is
|
|
206
|
+
the front door meanwhile; doctor says what to do). Every launchd and `pgrep`
|
|
207
|
+
question is scoped to *this* agent (`ai.maestro.<first>-*` and its own agent
|
|
208
|
+
dir), so two seats on one Mac never gate on — or restart — each other.
|
|
209
|
+
|
|
210
|
+
**Being up to date is not an exemption.** When the installed version is
|
|
211
|
+
already `@latest` the run still runs the same gate on the current version.
|
|
212
|
+
An unhealthy daemon is logged loudly, recorded in `state/autoupdate/last.json`
|
|
213
|
+
as `{ok:false, healthy:false, reason:"unhealthy-current: …"}` (the beat
|
|
214
|
+
carries it as `machine.upgrade`), and announced once per episode through
|
|
215
|
+
`state/session/upgrade-notice.json` `{from:CUR, to:CUR, healthy:false,
|
|
216
|
+
reason}` so the front-door session's feed surfaces it as a `daemon-unhealthy`
|
|
217
|
+
directive — a distinct action from `upgrade-available`, so no session restarts
|
|
218
|
+
on a health report. Nothing is rolled back (there is no upgrade to undo), an
|
|
219
|
+
`unhealthy-current` entry never holds a later release, and a recovery restores
|
|
220
|
+
`last.json`.
|
|
221
|
+
|
|
222
|
+
**A stale daemon is reconciled on the same path.** A hand-run `maestro
|
|
223
|
+
upgrade` installs the package and reconciles the seat but never restarts the
|
|
224
|
+
daemon (its verify row says the new version "takes effect when autoupdate
|
|
225
|
+
kickstarts it"). When `state/dashboards/daemon-health.yaml` shows the live
|
|
226
|
+
daemon started on a different `sdk_version` than the installed one, the hourly
|
|
227
|
+
run kickstarts it, waits, and runs the gate exactly as after an automatic
|
|
228
|
+
install — a healthy outcome writes the same `{from:<old>, to:<new>}` notice, so
|
|
229
|
+
the session restarts itself onto the new code when idle. The fatal scan starts
|
|
230
|
+
at the running daemon's own boot marker (`[DAEMON] boot pid=<pid>`, the first
|
|
231
|
+
line `maestro-daemon.mjs` prints), never at the top of the shared start-day
|
|
232
|
+
log, so a one-off crash earlier the same day that launchd already recovered
|
|
233
|
+
from is history, not health.
|
|
189
234
|
|
|
190
235
|
An unhealthy daemon **rolls back**: the previous SDK is reinstalled into the
|
|
191
236
|
agent dir and *that* package's `upgrade` runs, the global install is put back
|
package/docs/guides/mac-mini.md
CHANGED
|
@@ -32,20 +32,17 @@ npm i -g @cohortapp/agent-sdk # GLOBAL on purpose: every Claude Code sess
|
|
|
32
32
|
# this seat needs `maestro` + `cohort-mcp` on PATH
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
## 3. The Claude
|
|
35
|
+
## 3. The Claude credential — one Console API key per seat
|
|
36
36
|
|
|
37
37
|
Every `claude` the seat runs (the daemon's `--print` lane, the main session,
|
|
38
|
-
cadence sub-sessions) authenticates with
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
cadence sub-sessions) authenticates with an **Anthropic Console API key**
|
|
39
|
+
created for this agent, in a Console workspace with its own spend limit. Do
|
|
40
|
+
not use a Claude subscription on an agent seat: neither a `claude setup-token`
|
|
41
|
+
token nor the keychain login (which also expires headlessly). Creating the
|
|
42
|
+
workspace and the key: [billing-console-keys.md](billing-console-keys.md).
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Keep it in your clipboard / password manager for step 5. It is per seat: mint
|
|
48
|
-
a fresh one whenever `cohort doctor` reports the token as rejected.
|
|
44
|
+
Keep the key in your password manager for step 5. It is per seat: rotate it in
|
|
45
|
+
the Console whenever `cohort doctor` reports it as rejected.
|
|
49
46
|
|
|
50
47
|
## 4. Create the agent repo
|
|
51
48
|
|
|
@@ -59,7 +56,7 @@ including `.mcp.json`, which exposes the `cohort-mcp` org tool surface to
|
|
|
59
56
|
interactive Claude sessions, and the PreToolUse hooks that keep its outbound
|
|
60
57
|
writes on the CLI lane).
|
|
61
58
|
|
|
62
|
-
## 5. Enroll against `https://os.cohortapp.com` — and paste the
|
|
59
|
+
## 5. Enroll against `https://os.cohortapp.com` — and paste the API key
|
|
63
60
|
|
|
64
61
|
Two lanes — pick one:
|
|
65
62
|
|
|
@@ -68,13 +65,13 @@ Two lanes — pick one:
|
|
|
68
65
|
|
|
69
66
|
```bash
|
|
70
67
|
export COHORT_API_KEY=nlk_… COHORT_ORG_ID=<org-ID> COHORT_AGENT_ID=<member-slug>
|
|
71
|
-
cohort setup # the model section (order 30) asks for the
|
|
72
|
-
# headless / one-paste bootstrap: the
|
|
73
|
-
|
|
68
|
+
cohort setup # the model section (order 30) asks for the API key from step 3
|
|
69
|
+
# headless / one-paste bootstrap: the key comes from the environment instead of a prompt
|
|
70
|
+
ANTHROPIC_API_KEY=<key> cohort setup --headless
|
|
74
71
|
```
|
|
75
72
|
|
|
76
|
-
Either way `.env` ends up with `
|
|
77
|
-
`
|
|
73
|
+
Either way `.env` ends up with `ANTHROPIC_API_KEY`, mode 600, and no
|
|
74
|
+
`CLAUDE_CODE_OAUTH_TOKEN` or `MAESTRO_PREFER_SUBSCRIPTION_AUTH`.
|
|
78
75
|
|
|
79
76
|
> **`COHORT_ORG_ID` is the org's ID, not its slug** — this line said
|
|
80
77
|
> `<org-slug>` and that would 401 every call. The value rides as `x-org-id`
|
|
@@ -98,7 +95,7 @@ Two lanes — pick one:
|
|
|
98
95
|
|
|
99
96
|
| Order | Section | What it does |
|
|
100
97
|
| --- | --- | --- |
|
|
101
|
-
| 30 | `model` | Claude auth — **`
|
|
98
|
+
| 30 | `model` | Claude auth — **`api-key` by default**: paste the agent's Console API key; writes `ANTHROPIC_API_KEY`, chmods `.env` 600 |
|
|
102
99
|
| 75 | `org` | endpoint + token (the enrollment SoT) |
|
|
103
100
|
| 76 | `messaging` | messaging.read/write + calling.write scopes, home channels |
|
|
104
101
|
| 77 | `orgmail` | **workspace mailbox** — writes `config/orgmail.yaml` |
|
|
@@ -144,13 +141,11 @@ cohort doctor
|
|
|
144
141
|
|
|
145
142
|
All green includes, in this order:
|
|
146
143
|
|
|
147
|
-
- **Claude auth** — the mode in effect (`
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
cheap way to prove it. "keychain login"
|
|
153
|
-
or "nothing configured" means step 3/5 was skipped.
|
|
144
|
+
- **Claude auth** — the mode in effect (`ANTHROPIC_API_KEY` is the expected
|
|
145
|
+
line for an agent seat). In API-key mode the probe makes a real call, so a
|
|
146
|
+
rejected key shows here. A subscription line (OAuth token or keychain login)
|
|
147
|
+
on an agent seat means it is still on the pre-migration setup — see step 3.
|
|
148
|
+
"nothing configured" means step 3/5 was skipped.
|
|
154
149
|
- **Cohort sources** — for each of `base` / `orgId` / `token` / `agentId`,
|
|
155
150
|
which file won (`config/org.yaml` beats the environment beats `.env`) and
|
|
156
151
|
every value that lost. If you edited `.env` and nothing changed, this line
|
|
@@ -279,7 +279,10 @@ Pre-compiles session context to reduce prompt size:
|
|
|
279
279
|
|
|
280
280
|
- Reads recent interactions, queue state, and active items
|
|
281
281
|
- Compresses context to fit within token limits
|
|
282
|
-
-
|
|
282
|
+
- **On by default.** Set `DAEMON_CONTEXT_COMPILER=0` in `.env` to fall back to
|
|
283
|
+
the legacy per-prompt history path. The code used to default this OFF while
|
|
284
|
+
`.env.example` shipped `=1`, so which path ran depended on whether the
|
|
285
|
+
operator had copied the example env; both now agree.
|
|
283
286
|
|
|
284
287
|
---
|
|
285
288
|
|
|
@@ -52,7 +52,7 @@ core runner.
|
|
|
52
52
|
|---------|-------|-------------|
|
|
53
53
|
| `identity` | 10 | Agent name and title, the **function × altitude** archetype, and the principal. Writes `config/agent.json`. |
|
|
54
54
|
| `company` | 20 | Company-context interview — name, website, industry, one-line + detailed overview, stage/size, footprint, regulation, top priorities, and key people. Writes `config/company.json`. |
|
|
55
|
-
| `model` | 30 | Claude auth. Three modes, **`
|
|
55
|
+
| `model` | 30 | Claude auth. Three modes, **`api-key` the default**: paste an Anthropic Console API key created for this agent in a Console workspace with a spend limit (headless: `ANTHROPIC_API_KEY` in the environment) → `.env` gets `ANTHROPIC_API_KEY`. Setup runbook: [billing-console-keys.md](billing-console-keys.md). The other two modes — a `claude setup-token` subscription token, or this machine's keychain login — are for a person's own development machine, not an agent seat. Chmods `.env` 600. |
|
|
56
56
|
| `comms` | 45 | Wires each messaging channel — Slack, Gmail, SMS, WhatsApp, Telegram, voice — into `.env`/gate files and verifies inbound. |
|
|
57
57
|
| `tools` | 50 | Selects which channels and MCP servers the agent should run. |
|
|
58
58
|
| `operating-model` | 60 | Deterministically generates the operating charter, a seeded WBS backlog (≥5 open items), 40–60 sub-agents + skills + workflows + MCP servers + event-routing, archetype cadences, the autonomy policy, the communication profile, and the launchd plists. |
|