diff --git a/.gitattributes b/.gitattributes index 912c11ef0..d6fdb7f2d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,7 @@ -scripts/** text eol=lf +*.sh text eol=lf .githooks/** text eol=lf .github/workflows/*.yml text eol=lf +migrations/postgres/*.sql text eol=lf # Custom merge driver for tracked generated inventory docs (#4724 slice B). # These two files are generated wholesale; line-count churn makes concurrent PRs @@ -26,3 +27,7 @@ docs/generated/worker-inventory.md merge=regen-inventory # and crash on them. `-text` additionally keeps EOL conversion away from files # whose exact bytes are the assertion. tests/fixtures/relay_obligation/*.jsonl -diff -text +# `.expected` is the same corpus's third-party golden output. Without `-text`, +# a Windows checkout rewrites LF to CRLF and the Python/Rust byte-equal gate +# fails even though both implementations still emit LF. +tests/fixtures/relay_obligation/*.expected -diff -text diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 474b34505..56bcb2547 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -7,10 +7,12 @@ ## Queue Hygiene & Merge-Readiness checklist -- [ ] **Duplicate PR guard:** I have checked for overlapping open PRs before creating this PR (especially for generated refresh work). -- [ ] **No-change verification:** If this PR claims no change, I have verified it modifies zero files using `gh pr view --json files`. (If an unavoidable no-change PR is opened, its body lists the exact overlapping PR numbers and branches). -- [ ] **Stale branch cleanup:** I am not salvaging a stale broad branch in-place. Instead, I am closing stale branches and recreating clean branches from main. -- [ ] **Scratch file cleanup:** I have run `git status` or a changed-file audit to ensure no ad-hoc scratch files (e.g. `plan.md`, `pr-body.md`) or unrelated test scripts (e.g. `.sh`, `.sql`) are included in this PR. +- [ ] **Duplicate PR guard:** I have checked for overlapping open PRs before creating this PR (especially for generated refresh work). If overlap is found, I have ended the run with a no-change report rather than opening an empty PR. I re-checked overlap immediately before opening or updating this PR. +- [ ] **No-change verification:** If this PR claims no change, I have verified it modifies zero files using `gh pr view --json files`. A no-change result should not become a PR unless it explicitly changes a queue-hygiene artifact. (If an unavoidable no-change PR is opened, its body lists the exact overlapping PR numbers and branches). +- [ ] **Stale branch cleanup:** I am not salvaging a stale broad branch in-place. Instead, I am closing stale branches and recreating clean branches from main. I ran a final changed-file audit and abandoned any contaminated branches. +- [ ] **Scratch file cleanup:** I have run `git status` or a changed-file audit to ensure no ad-hoc scratch files (e.g. `plan.md`, `pr-body.md`, `patch.diff`, `prs.json`) or unrelated test scripts (e.g. `.sh`, `.sql`) are included in this PR. +- [ ] **Mergeability status:** I am not claiming merge-ready from partial check status. Pending or UNKNOWN mergeability is explicitly called out. +- [ ] **Verification Grounding:** I am not claiming PostgreSQL, Discord, tmux, provider runtime, browser, or CI verification unless it was actually executed. If a required check cannot run in the environment, I have stated the exact reason and the residual risk. ## Dashboard / UI checklist - [ ] **시안에 없는 기존 기능을 임의로 삭제하지 않았다.** Reference 시안(redesign reference)에서 빠진 위젯·필터·탭이라도 기존 dashboard에 있던 기능은 사용자 명시 제거 요청 없이 삭제하지 않는다. 시안의 톤·간격·타이포에 맞춰 확장하거나 별도 sub-issue로 분리한다. (관련 결정: #1254 audit, 2026-04-15 결정 기록) @@ -26,10 +28,13 @@ - Agent: - Boundary: - Primary files: -- Verification commands and results: +- Public API impact: +- Docs impact: +- Verification commands and results: - Skipped checks with reasons: - Risk: - Rollback notes: - Queue hygiene invariant: - Related PRs/issues checked: +- Duplicate/overlap check: - Why this is non-overlapping: diff --git a/.github/workflows/ci-macos-trusted.yml b/.github/workflows/ci-macos-trusted.yml index 8d4774df3..2afd69eee 100644 --- a/.github/workflows/ci-macos-trusted.yml +++ b/.github/workflows/ci-macos-trusted.yml @@ -110,10 +110,10 @@ jobs: echo "SCCACHE_GHA_ENABLED=" } >> "$GITHUB_ENV" - - name: Install Opus on macOS + - name: Install native dependencies on macOS shell: bash run: | - brew install opus pkg-config + brew install opus pkg-config tmux echo "PKG_CONFIG_PATH=$(brew --prefix opus)/lib/pkgconfig:${PKG_CONFIG_PATH:-}" >> "$GITHUB_ENV" - name: Cache Cargo dependencies @@ -237,10 +237,10 @@ jobs: } >> "$GITHUB_ENV" fi - - name: Install Opus on macOS + - name: Install native dependencies on macOS shell: bash run: | - brew install opus pkg-config + brew install opus pkg-config tmux echo "PKG_CONFIG_PATH=$(brew --prefix opus)/lib/pkgconfig:${PKG_CONFIG_PATH:-}" >> "$GITHUB_ENV" # Do not attach GitHub cache actions to the persistent self-hosted path: diff --git a/.github/workflows/ci-main.yml b/.github/workflows/ci-main.yml index 47743107c..0dd714666 100644 --- a/.github/workflows/ci-main.yml +++ b/.github/workflows/ci-main.yml @@ -124,7 +124,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: "22" + node-version-file: ".nvmrc" - name: Policy JS unit tests run: npm run test:policies @@ -212,7 +212,11 @@ jobs: resource_sample > "$RUNNER_TEMP/pg-resource-samples.log" 2>&1 & - name: just test-postgres - timeout-minutes: 20 + # Exact-head #1710 ran 796 selected tests successfully in 1189.32s + # before the recipe reached its explicit no-marker modules. The old 20m + # bound therefore terminated a green suite with no cleanup headroom. + # Keep the push lane aligned with the measured PR/nightly budget. + timeout-minutes: 30 run: just test-postgres env: # #4245: see Full tests lane — keep test debuginfo off so the build diff --git a/.github/workflows/ci-nightly.yml b/.github/workflows/ci-nightly.yml index 3a860a1ea..991d30a27 100644 --- a/.github/workflows/ci-nightly.yml +++ b/.github/workflows/ci-nightly.yml @@ -27,7 +27,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: "22" + node-version-file: ".nvmrc" cache: npm cache-dependency-path: dashboard/package-lock.json @@ -48,7 +48,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: "22" + node-version-file: ".nvmrc" cache: npm cache-dependency-path: dashboard/package-lock.json @@ -97,9 +97,9 @@ jobs: echo "SCCACHE_GHA_ENABLED=" } >> "$GITHUB_ENV" - - name: Install Opus on macOS + - name: Install native dependencies on macOS run: | - brew install opus pkg-config + brew install opus pkg-config tmux echo "PKG_CONFIG_PATH=$(brew --prefix opus)/lib/pkgconfig:${PKG_CONFIG_PATH:-}" >> "$GITHUB_ENV" - name: Setup sccache @@ -256,7 +256,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v4 with: - node-version: "22" + node-version-file: ".nvmrc" - name: Setup sccache uses: mozilla-actions/sccache-action@v0.0.10 diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index 43c1fefa1..8cb5e3ff5 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -162,6 +162,11 @@ jobs: - 'src/services/auto_queue/**' - 'src/services/automation_candidate_materializer/**' - 'src/services/dispatches/**' + - 'src/services/scheduled_messages.rs' + - 'src/services/scheduled_messages/**' + - 'src/services/external_share_outbox.rs' + - 'src/services/external_share_outbox/**' + - 'src/services/discord/outbound/source_registry.rs' - 'src/services/queue.rs' - 'src/services/session_forwarding.rs' - 'src/services/session_forwarding/**' @@ -377,7 +382,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: "22" + node-version-file: ".nvmrc" cache: npm cache-dependency-path: dashboard/package-lock.json @@ -434,7 +439,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: "22" + node-version-file: ".nvmrc" - name: Policy JS unit tests run: npm run test:policies @@ -740,7 +745,11 @@ jobs: env -u AGENTDESK_ROOT_DIR cargo test --lib identity_guarded_save_rejects_stale_write_against_newer_turn - name: just test-postgres - timeout-minutes: 20 + # Exact-head #1710 ran 796 selected tests successfully in 1189.32s + # before the recipe reached its explicit no-marker modules. The old 20m + # bound therefore terminated a green suite with no cleanup headroom. + # Match the measured nightly budget and retain 50% runtime headroom. + timeout-minutes: 30 shell: bash env: BASH_ENV: /dev/null @@ -1328,14 +1337,14 @@ jobs: set -euo pipefail limit=$((10 * 1024 * 1024)) failed=0 - while IFS= read -r path; do + while IFS= read -r -d '' path; do [ -f "$path" ] || continue size=$(git cat-file -s "HEAD:$path") if [ "$size" -gt "$limit" ]; then printf 'ERROR: tracked file exceeds 10 MiB: %s (%s bytes)\n' "$path" "$size" failed=1 fi - done < <(git ls-files) + done < <(git ls-files -z) exit "$failed" - name: Install shellcheck @@ -1418,7 +1427,7 @@ jobs: exit 1 fi gate_path=scripts/check-ci-runner-hardening.sh - expected=e32217629c135d5cbd16c8bb81eb58fe53e07cea0def203a5ce6380191f80263 + expected=7a34eb0354c620e0396d7c82bf7b783158b3e96ad9d1cc43f1b0e68aca36dfa1 actual="$(sha256sum "$gate_path" | cut -d ' ' -f 1)" if [ "$actual" != "$expected" ]; then echo "::error file=$gate_path::content hash mismatch: expected $expected, found $actual; review the gate and update both #5321 gate pins together" @@ -1525,7 +1534,7 @@ jobs: exit 1 fi gate_path=scripts/check-ci-runner-hardening.sh - expected=e32217629c135d5cbd16c8bb81eb58fe53e07cea0def203a5ce6380191f80263 + expected=7a34eb0354c620e0396d7c82bf7b783158b3e96ad9d1cc43f1b0e68aca36dfa1 actual="$(sha256sum "$gate_path" | cut -d ' ' -f 1)" if [ "$actual" != "$expected" ]; then echo "::error file=$gate_path::content hash mismatch: expected $expected, found $actual; review the gate and update both #5321 gate pins together" diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index d19d3f8c4..270f29b7c 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -59,6 +59,8 @@ src/ │ ├── legacy_db_paths.rs │ ├── legacy_tmp_paths.rs │ └── mod.rs +├── config/ +│ └── agent_channels.rs ├── db/ │ ├── auto_queue/ │ │ ├── entries/ @@ -115,6 +117,8 @@ src/ │ │ └── tests.rs │ ├── scheduled_messages/ │ │ ├── agent.rs +│ │ ├── discord_mentions.rs +│ │ ├── external_delivery.rs │ │ ├── outbox.rs │ │ ├── postgres_tests.rs │ │ └── writes.rs @@ -244,7 +248,8 @@ src/ │ │ │ │ ├── part_07.rs │ │ │ │ ├── part_08.rs │ │ │ │ ├── part_09.rs -│ │ │ │ └── part_10.rs +│ │ │ │ ├── part_10.rs +│ │ │ │ └── part_11.rs │ │ │ ├── guides.rs │ │ │ ├── inventory.rs │ │ │ └── taxonomy.rs @@ -253,12 +258,14 @@ src/ │ │ │ ├── admin.rs │ │ │ ├── agents.rs │ │ │ ├── analytics.rs +│ │ │ ├── cluster.rs │ │ │ ├── integrations.rs │ │ │ ├── kanban.rs │ │ │ ├── mod.rs │ │ │ ├── onboarding.rs │ │ │ ├── ops.rs -│ │ │ └── reviews.rs +│ │ │ ├── reviews.rs +│ │ │ └── routines.rs │ │ ├── review_verdict/ │ │ │ ├── decision_route.rs │ │ │ ├── mod.rs @@ -271,6 +278,7 @@ src/ │ │ │ └── responses.rs │ │ ├── scheduled_messages/ │ │ │ ├── postgres_tests.rs +│ │ │ ├── provider_targets.rs │ │ │ └── snapshot_capture.rs │ │ ├── tests/ │ │ │ ├── preflight_harness/ @@ -302,6 +310,7 @@ src/ │ │ ├── home_metrics.rs │ │ ├── hooks.rs │ │ ├── idle_recap.rs +│ │ ├── kakao.rs │ │ ├── kanban.rs │ │ ├── kanban_repos.rs │ │ ├── maintenance.rs @@ -317,6 +326,7 @@ src/ │ │ ├── pr_summary.rs │ │ ├── prompt_manifest_retention.rs │ │ ├── provider_cli_api.rs +│ │ ├── providers_api.rs │ │ ├── queue_api.rs │ │ ├── receipt.rs │ │ ├── resume.rs @@ -607,7 +617,8 @@ src/ │ │ │ │ └── rebind_adoption.rs │ │ │ ├── stall_recovery_tests/ │ │ │ │ ├── flake_isolation_4361.rs -│ │ │ │ └── flake_isolation_4422.rs +│ │ │ │ ├── flake_isolation_4422.rs +│ │ │ │ └── generation_fence_5462.rs │ │ │ ├── anchor_repost.rs │ │ │ ├── budget.rs │ │ │ ├── destructive_commit.rs @@ -642,6 +653,7 @@ src/ │ │ │ ├── delivery.rs │ │ │ ├── delivery_frontier_probe.rs │ │ │ ├── delivery_record.rs +│ │ │ ├── image_attachment.rs │ │ │ ├── manual_delivery.rs │ │ │ ├── message.rs │ │ │ ├── mod.rs @@ -1306,6 +1318,8 @@ src/ │ │ ├── routing_constraint.rs │ │ ├── thread_reuse.rs │ │ └── wait_queue.rs +│ ├── external_share_outbox/ +│ │ └── postgres_tests.rs │ ├── git/ │ │ ├── branch_resolver.rs │ │ ├── commit_resolver.rs @@ -1331,6 +1345,8 @@ src/ │ │ ├── memento_throttle.rs │ │ ├── mod.rs │ │ └── runtime_state.rs +│ ├── message_outbox/ +│ │ └── identity.rs │ ├── observability/ │ │ ├── emit.rs │ │ ├── events.rs @@ -1366,7 +1382,9 @@ src/ │ │ ├── cancel_token_claude_interrupt.rs │ │ ├── cancel_token_cleanup.rs │ │ ├── cancel_watchdog.rs -│ │ └── provider_conformance_invariant_tests.rs +│ │ ├── catalog.rs +│ │ ├── provider_conformance_invariant_tests.rs +│ │ └── registry.rs │ ├── provider_cli/ │ │ ├── canary.rs │ │ ├── context.rs @@ -1409,7 +1427,9 @@ src/ │ ├── scheduled_messages/ │ │ ├── context_snapshot.rs │ │ ├── evidence.rs +│ │ ├── external_delivery.rs │ │ ├── postgres_tests.rs +│ │ ├── push_handoff.rs │ │ └── timing.rs │ ├── session_backend/ │ │ ├── stream_line.rs @@ -1422,6 +1442,17 @@ src/ │ │ └── mod.rs │ ├── stale_turn_reconciler/ │ │ └── test_barriers.rs +│ ├── stream_json_cli/ +│ │ ├── dialects/ +│ │ │ ├── agy.rs +│ │ │ ├── grok.rs +│ │ │ └── mod.rs +│ │ ├── codec.rs +│ │ ├── mod.rs +│ │ ├── policy.rs +│ │ ├── request.rs +│ │ ├── runner.rs +│ │ └── session.rs │ ├── tui_prompt_dedupe/ │ │ ├── extract.rs │ │ ├── observation.rs @@ -1465,12 +1496,16 @@ src/ │ ├── dispatched_sessions.rs │ ├── dispatches_followup.rs │ ├── escalation_settings.rs +│ ├── external_share.rs +│ ├── external_share_outbox.rs │ ├── gemini.rs │ ├── github_issue_creation.rs │ ├── hang_forensics.rs │ ├── health_active_session_audit.rs │ ├── health_diagnostics.rs │ ├── issue_announcements.rs +│ ├── kakao.rs +│ ├── kakao_message.rs │ ├── kanban.rs │ ├── kanban_cards.rs │ ├── long_turn_watchdog.rs @@ -1483,6 +1518,7 @@ src/ │ ├── message_outbox_recovery_tests.rs │ ├── mod.rs │ ├── monitoring_store.rs +│ ├── oauth_connection.rs │ ├── opencode.rs │ ├── operator_connectors.rs │ ├── pane_readiness.rs @@ -1610,6 +1646,7 @@ This table is generated from the current `src/` root and fails CI when a new top | --- | --- | | `src/cli/` | Operator-facing CLI commands, direct API shims, migrations, and Discord send helpers. | | `src/compat/` | Centralised home for compatibility/legacy/fallback shims (#1076). Each public item carries a `REMOVE_WHEN` comment so retirement is grep-driven. | +| `src/config/` | Config newtypes extracted from the `config.rs` facade, including the provider-keyed AgentChannels map. | | `src/db/` | PostgreSQL access layer, migration helpers, and schema authority. | | `src/dispatch/` | Dispatch context construction, review metadata, and worktree targeting. | | `src/engine/` | QuickJS policy runtime, hook wiring, transition logic, and Rust-JS bridge ops. | diff --git a/Cargo.lock b/Cargo.lock index 057455395..6787013c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,6 +52,7 @@ dependencies = [ "axum", "base64", "blake3", + "chacha20poly1305", "chrono", "chrono-tz", "clap", @@ -67,6 +68,7 @@ dependencies = [ "json5", "libc", "notify", + "oauth2", "poise", "pulldown-cmark", "rand 0.8.5", @@ -97,6 +99,7 @@ dependencies = [ "url", "uuid", "which 8.0.2", + "zeroize", ] [[package]] @@ -475,6 +478,17 @@ dependencies = [ "cpufeatures 0.2.17", ] +[[package]] +name = "chacha20" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.1", +] + [[package]] name = "chacha20poly1305" version = "0.10.1" @@ -482,7 +496,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ "aead", - "chacha20", + "chacha20 0.9.1", "cipher", "poly1305", "zeroize", @@ -726,9 +740,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" dependencies = [ "crossbeam-utils", ] @@ -1525,11 +1539,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", "rand_core 0.10.1", "wasip2", "wasip3", + "wasm-bindgen", ] [[package]] @@ -2783,6 +2799,26 @@ dependencies = [ "libc", ] +[[package]] +name = "oauth2" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51e219e79014df21a225b1860a479e2dcd7cbd9130f4defd4bd0e191ea31d67d" +dependencies = [ + "base64", + "chrono", + "getrandom 0.2.17", + "http", + "rand 0.8.5", + "reqwest", + "serde", + "serde_json", + "serde_path_to_error", + "sha2", + "thiserror 1.0.69", + "url", +] + [[package]] name = "once_cell" version = "1.21.4" @@ -3376,14 +3412,15 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.14" +version = "0.11.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560" dependencies = [ "bytes", - "getrandom 0.3.4", + "getrandom 0.4.2", "lru-slab", - "rand 0.9.2", + "rand 0.10.1", + "rand_pcg", "ring", "rustc-hash 2.1.1", "rustls 0.23.37", @@ -3457,6 +3494,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" dependencies = [ + "chacha20 0.10.1", "getrandom 0.4.2", "rand_core 0.10.1", ] @@ -3515,6 +3553,15 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" +[[package]] +name = "rand_pcg" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core 0.10.1", +] + [[package]] name = "rayon" version = "1.12.0" @@ -5625,6 +5672,7 @@ checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" dependencies = [ "getrandom 0.4.2", "js-sys", + "serde_core", "sha1_smol", "wasm-bindgen", ] diff --git a/Cargo.toml b/Cargo.toml index 49c4ffdf7..5f4289382 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,7 +75,7 @@ json5 = "0.4" futures = "0.3" ureq = { version = "2", features = ["json"] } url = "2" -uuid = { version = "1", features = ["v4", "v5"] } +uuid = { version = "1", features = ["v4", "v5", "serde"] } chrono = { version = "0.4", default-features = false, features = ["std", "clock", "serde"] } chrono-tz = "0.10" notify = "7" @@ -98,12 +98,15 @@ icu_properties = "=2.1.2" # From RCC — crypto/encoding base64 = "0.22" blake3 = "1" +chacha20poly1305 = "0.10" +zeroize = { version = "1", features = ["derive"] } # From RCC — concurrency dashmap = "6" # From RCC — HTTP client reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "json", "stream"] } +oauth2 = { version = "5.0.0", default-features = false, features = ["reqwest", "rustls-tls"] } # From RCC — crypto sha2 = "0.10" diff --git a/README.md b/README.md index 9d454fe38..a26cbcaaf 100644 --- a/README.md +++ b/README.md @@ -646,6 +646,7 @@ agentdesk discord-sendfile --channel --key agentdesk discord-sendmessage --channel --message agentdesk discord-senddm --user --message agentdesk send --target channel: --content [--bot announce|notify|] +agentdesk send-to-agent --from --to --message --expect-reply true|false agentdesk discord read [--limit ] [--before ] [--after ] agentdesk monitoring start --channel --key --description agentdesk monitoring stop --channel --key @@ -654,6 +655,7 @@ agentdesk monitoring stop --channel --key agentdesk review-verdict --dispatch --verdict pass|improve|rework|reject|approved agentdesk review-decision --card --decision approve|rework|escalate|accept|dispute|dismiss|requeue|resume agentdesk docs [CATEGORY] [--flat] +agentdesk show session-name --channel [--provider ] agentdesk force-kill --session-key [--retry] # Kanban / dispatch / auto-queue @@ -675,6 +677,9 @@ agentdesk auto-queue config --max-concurrent [--run ] [--repo ] agentdesk cherry-merge [--close-issue] agentdesk status # Runtime health summary +agentdesk health # Consolidated node health snapshot +agentdesk machine-compare # Multinode release/dev state comparison +agentdesk activity --since