@humwick/server 0.130.2 → 0.130.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/bundled/prompts/manifest.json +1 -0
- package/bundled/prompts/task.hydration.md +1 -1
- package/bundled/roles/builder.md +1 -1
- package/docs/guides/sub-coordinators.md +12 -5
- package/docs/guides/tools-coordination.md +1 -0
- package/docs/guides/workflows.md +16 -0
- package/docs/openapi.json +175 -4
- package/package.json +8 -7
- package/public/assets/{MessageBubble-BWLqMGKG.js → MessageBubble-BOkmEvgZ.js} +2 -2
- package/public/assets/{PlanGraphPanel-3TlIQpjk.js → PlanGraphPanel-BkaDJp0r.js} +2 -2
- package/public/assets/{TraceView-Wimm0Czv.js → TraceView-B99Uu2yT.js} +2 -2
- package/public/assets/{VaultDecisionCard-Bau_vNax.js → VaultDecisionCard-DUIfTTFF.js} +2 -2
- package/public/assets/{activity-CrSurn-r.js → activity-ZIX0N1El.js} +2 -2
- package/public/assets/{agent-lineage-CknAJKcb.js → agent-lineage-kq9TPYFw.js} +2 -2
- package/public/assets/agent-liveness-DSQY1Aa_.js +2 -0
- package/public/assets/{agent-name-DKbiIhBo.js → agent-name-C_7F4DFR.js} +2 -2
- package/public/assets/{agent-profiles-DwF6EQ4R.js → agent-profiles-BNOcrGcY.js} +2 -2
- package/public/assets/{agent-project-badge-Diz4Sjjb.js → agent-project-badge-B6yAh70a.js} +2 -2
- package/public/assets/{agent-tools-CRhpRQza.js → agent-tools-CcrhmOzF.js} +2 -2
- package/public/assets/{agent-type-icon-LrUEU3lB.js → agent-type-icon-CXSLrKiq.js} +2 -2
- package/public/assets/{agents-B-v66C-4.js → agents-DIZG97_X.js} +2 -2
- package/public/assets/{analytics-BqCb-LKi.js → analytics-rasmoPjR.js} +2 -2
- package/public/assets/{artifact-viewer-kf4pGuAR.js → artifact-viewer-tBpTrEPb.js} +2 -2
- package/public/assets/{artifacts-DJevXcvg.js → artifacts-BNkrynP1.js} +2 -2
- package/public/assets/{artifacts-D32zyw4Y.js → artifacts-Bjq-ZyBA.js} +2 -2
- package/public/assets/{automation-BpRajx_5.js → automation-Cx422L3L.js} +2 -2
- package/public/assets/{backlog-D_UjTdzX.js → backlog-RuFQ8PUu.js} +2 -2
- package/public/assets/{busy-health-N3VEh4ao.js → busy-health-BvNQ9g5x.js} +2 -2
- package/public/assets/{channels-9jopungq.js → channels-DNbKAS0I.js} +2 -2
- package/public/assets/{chat-CSXrTB3C.js → chat-Bp3Fx73h.js} +3 -3
- package/public/assets/{code-preview-p1NnmqK0.js → code-preview-KIRZA6cz.js} +2 -2
- package/public/assets/{connectors-CZdqlDNL.js → connectors-k7vO4vvc.js} +2 -2
- package/public/assets/{cosmos-BgdsE4dG.js → cosmos-BuVoq1aw.js} +2 -2
- package/public/assets/{crate-agent-30aXTKva.js → crate-agent-irqlt4NH.js} +2 -2
- package/public/assets/{dependency-graph-B_jvw2GE.js → dependency-graph-D_rurNBz.js} +2 -2
- package/public/assets/{deploys-DoN6bAb5.js → deploys-yzZqIpxE.js} +2 -2
- package/public/assets/{display-BrKWFGJz.js → display-BemJG1f_.js} +2 -2
- package/public/assets/{files-D6XEu8Ng.js → files-DXWcrxOz.js} +2 -2
- package/public/assets/{fleet-C7jQWbw2.js → fleet-TEuOCZXE.js} +2 -2
- package/public/assets/{fleet-metrics-BiDs3MLx.js → fleet-metrics-BGoDAFI-.js} +2 -2
- package/public/assets/{formatted-body-impl-DyG0WsQS.js → formatted-body-impl-BB9eq9nN.js} +2 -2
- package/public/assets/{formatted-body-CQBwc1fb.js → formatted-body-qy2nTD_1.js} +3 -3
- package/public/assets/{host-providers-dialog-DKaW31dN.js → host-providers-dialog-BGPHxuwT.js} +2 -2
- package/public/assets/{index-CRHep3M9.js → index-BC5XZc0z.js} +5 -5
- package/public/assets/{index-MYAIwYTX.css → index-D8Rp9pz2.css} +1 -1
- package/public/assets/{insights-CzrtkpOE.js → insights-C-KQG0h-.js} +2 -2
- package/public/assets/{integrations-aVsUmigt.js → integrations-ClPRPyKU.js} +2 -2
- package/public/assets/{issue-ref-chip-BnSlM_95.js → issue-ref-chip-DbH8J9Ak.js} +2 -2
- package/public/assets/{log-viewer-qe7Ee47Z.js → log-viewer-PH4zVn24.js} +2 -2
- package/public/assets/{maintenance-NfjqFZAk.js → maintenance-5lV43uTL.js} +2 -2
- package/public/assets/{managed-agents-BiH0HgaE.js → managed-agents-BdgU35aX.js} +2 -2
- package/public/assets/{markdown-preview-BixaT3Xr.js → markdown-preview-DNT4OUwQ.js} +3 -3
- package/public/assets/{markdown-preview-impl-DNGlWIS3.js → markdown-preview-impl-CnCcPy0A.js} +2 -2
- package/public/assets/{memory-DNsCl6UX.js → memory--GgWH1gH.js} +2 -2
- package/public/assets/{messages-DopU1L1X.js → messages-CzFl_97O.js} +2 -2
- package/public/assets/{orchestrators-Cq7ckLQT.js → orchestrators-CVvJVkzv.js} +2 -2
- package/public/assets/overview-DsrZvE86.js +2 -0
- package/public/assets/{pairs-DE_m6rrE.js → pairs-D2d0d2py.js} +2 -2
- package/public/assets/{profile-icon-B3rfh77F.js → profile-icon-_SMuSbYF.js} +2 -2
- package/public/assets/{project-profile-instructions-DQWZE0kA.js → project-profile-instructions-Apn15y43.js} +2 -2
- package/public/assets/{projects-Br2Bd2h1.js → projects-D3B6kto5.js} +2 -2
- package/public/assets/{prompt-settings-BKvFsvGD.js → prompt-settings-DnPB6Ez6.js} +2 -2
- package/public/assets/provider-display-bWwiuedV.js +2 -0
- package/public/assets/{registry-Cw38_6gW.js → registry-D790cIhN.js} +2 -2
- package/public/assets/run-card-BCro-Odj.js +2 -0
- package/public/assets/{secrets-DxI-vzSq.js → secrets-CVXvfvbU.js} +2 -2
- package/public/assets/{service-access-settings-D9s_VJbd.js → service-access-settings-D3Xxqb9w.js} +2 -2
- package/public/assets/{settings-CKZTVGIx.js → settings-CoUC7Jci.js} +2 -2
- package/public/assets/shipping-D_Lp9n_J.js +2 -0
- package/public/assets/{stats-DyUBKyWI.js → stats-CXiNjB9S.js} +2 -2
- package/public/assets/{status-dot-DYqlEUhJ.js → status-dot-C703YIy1.js} +2 -2
- package/public/assets/store-BgDALGIX.js +9 -0
- package/public/assets/{tasks-Bh7Chr4-.js → tasks-DO0WpJCx.js} +2 -2
- package/public/assets/{teams-bowI7qVY.js → teams-FGkdi_tL.js} +2 -2
- package/public/assets/{terminal-viewer-BgVLHdsU.js → terminal-viewer-Dh8dSC7e.js} +3 -3
- package/public/assets/{terminal-viewer-impl-Dz22UPy6.js → terminal-viewer-impl-B5Zriip3.js} +2 -2
- package/public/assets/{use-agent-terminal-DSQQ-iY7.js → use-agent-terminal-CRUVDvLC.js} +2 -2
- package/public/assets/{use-decisions-samMQhQf.js → use-decisions-CoaqRh4l.js} +2 -2
- package/public/assets/{use-project-list-59LheVP7.js → use-project-list-X-BgT53X.js} +2 -2
- package/public/assets/{use-selectors-BZa25xEB.js → use-selectors-0X_UZkk-.js} +2 -2
- package/public/assets/{user-avatar-DHxlvUvV.js → user-avatar-CkLhVBGu.js} +2 -2
- package/public/assets/{versioned-prompt-editor-BmED5DnJ.js → versioned-prompt-editor-BkTi7eim.js} +2 -2
- package/public/assets/{work-queue-CSvpuNLz.js → work-queue-DDOLEyKo.js} +2 -2
- package/public/assets/{workflow-marker-DAZcj5qt.js → workflow-marker-CzOsB8BM.js} +2 -2
- package/public/assets/{workflows-DdmxRSyg.js → workflows-DJilvmRM.js} +2 -2
- package/public/assets/{workspaces-BxeKfVuF.js → workspaces-CHcfbLR3.js} +2 -2
- package/public/cosmos.html +4 -4
- package/public/index.html +29 -29
- package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/runner/src/adapters/claude-api.ts +1 -1
- package/runner/src/adapters/claude-headless.ts +1 -1
- package/runner/src/adapters/claude-launch-exit.ts +26 -0
- package/runner/src/adapters/claude-session-probe.ts +1 -1
- package/runner/src/adapters/claude-tmux.ts +38 -10
- package/runner/src/adapters/claude.ts +28 -75
- package/runner/src/adapters/provider-quota-harvest.ts +20 -71
- package/runner/src/agent-runner/lifecycle-milestones.ts +2 -2
- package/runner/src/agent-runner/liveness-exchange.ts +104 -0
- package/runner/src/claude-system-prompt.ts +49 -0
- package/runner/src/launch-assembly.ts +14 -10
- package/runner/src/profile-home.ts +1 -1
- package/runner/src/project-instructions.ts +2 -2
- package/runner/src/provider-command.ts +18 -0
- package/runner/src/provider-setup.ts +3 -2
- package/runner/src/runner-core.ts +14 -15
- package/runner/src/runner-helpers.ts +0 -8
- package/runner/src/session-scratch.ts +6 -2
- package/runner/test-support/provisioning-context.ts +4 -2
- package/runner/test-support/runner-harness.ts +2 -1
- package/scripts/steward-policy-cleanup.ts +2 -2
- package/src/agent-authz.ts +2 -2
- package/src/agent-drive-arbiter.ts +3 -8
- package/src/agent-exit-cleanup-async.ts +2 -2
- package/src/agent-exit-cleanup.ts +23 -19
- package/src/agent-lifecycle-events.ts +112 -85
- package/src/agent-ref.ts +3 -2
- package/src/agent-status-events.ts +43 -14
- package/src/auth/login-link.ts +35 -0
- package/src/auth/password.ts +4 -3
- package/src/auth/session-refresh.ts +1 -1
- package/src/auth/session.test-fixture.ts +2 -2
- package/src/auth/session.ts +7 -7
- package/src/automations/crud.ts +8 -81
- package/src/automations/dispatch.ts +33 -58
- package/src/automations/index.ts +1 -1
- package/src/automations/persistence.ts +65 -0
- package/src/automations/precheck.ts +18 -16
- package/src/automations/read-async.ts +11 -0
- package/src/automations/reconcile.ts +30 -39
- package/src/automations/storage.ts +33 -10
- package/src/automations/write-async.ts +33 -0
- package/src/branch-land-notice.ts +3 -3
- package/src/branch-landed.ts +25 -23
- package/src/bus.ts +21 -19
- package/src/cd-deploy-notify.ts +2 -2
- package/src/ci/notifications.ts +4 -4
- package/src/ci/root-missing.ts +3 -3
- package/src/ci/transition-notify.ts +5 -5
- package/src/claude-app/oauth-http.ts +3 -3
- package/src/cli/index.ts +7 -1
- package/src/cli/init.ts +53 -0
- package/src/cli/orchestrator.ts +1 -7
- package/src/cli/setup.ts +6 -4
- package/src/cli/workflow.ts +12 -3
- package/src/commands-db.ts +4 -4
- package/src/commands-write.ts +8 -0
- package/src/compaction-watch.ts +10 -8
- package/src/config-store-write.ts +2 -2
- package/src/config.ts +4 -11
- package/src/connectors.ts +10 -8
- package/src/context-advisory.ts +22 -21
- package/src/db/agent-action-write.ts +36 -0
- package/src/db/agent-control-async.ts +9 -0
- package/src/db/agent-control-write.ts +49 -0
- package/src/db/agent-effort-observe.ts +22 -0
- package/src/db/agent-meta.ts +14 -3
- package/src/db/agents-async.ts +8 -5
- package/src/db/agents.ts +15 -12
- package/src/db/auth-identities.ts +2 -2
- package/src/db/automation-read-ops.ts +11 -0
- package/src/db/automation-write-ops.ts +46 -0
- package/src/db/blackboard.ts +2 -2
- package/src/db/browser-session-write.ts +32 -0
- package/src/db/bus-outbox-write-ops.ts +3 -1
- package/src/db/checkout-refresh-schema.ts +47 -0
- package/src/db/checkout-refresh.ts +5 -5
- package/src/db/command-agent-profile-backfill.ts +39 -0
- package/src/db/command-agent-profiles.ts +5 -1
- package/src/db/command-retention.ts +126 -0
- package/src/db/commands-planner-stats.test-fixture.ts +8 -0
- package/src/db/commands-read-ops.ts +16 -0
- package/src/db/connection.ts +1 -182
- package/src/db/context-carry-write.ts +74 -0
- package/src/db/continuations.ts +4 -4
- package/src/db/db-error-registry.ts +12 -0
- package/src/db/gateway.ts +26 -133
- package/src/db/history-retention-ops.ts +13 -0
- package/src/db/inbox-async.ts +2 -2
- package/src/db/inbox-read-ops.ts +1 -1
- package/src/db/inbox.ts +9 -3
- package/src/db/issue-associations.ts +2 -2
- package/src/db/issue-refs-async.ts +4 -1
- package/src/db/issue-refs-read-ops.ts +6 -0
- package/src/db/issue-refs.ts +8 -8
- package/src/db/kernel-event-log-schema.ts +2 -0
- package/src/db/land-boundaries.ts +51 -5
- package/src/db/land-gate-attestations.ts +2 -2
- package/src/db/landing-receipts.ts +2 -2
- package/src/db/lifecycle-context-write.ts +5 -0
- package/src/db/lifecycle-tail-async.ts +76 -0
- package/src/db/lifecycle-tail-write-ops.ts +62 -0
- package/src/db/lifecycle-write-window.ts +2 -1
- package/src/db/lineage-pair-dedupe-sql.ts +3 -3
- package/src/db/main-connection-mode.ts +11 -0
- package/src/db/main-connection-writes.ts +20 -2
- package/src/db/maintenance-job-runs-async.ts +2 -2
- package/src/db/maintenance-job-write-ops.ts +1 -1
- package/src/db/maintenance-pauses.ts +2 -2
- package/src/db/message-send.ts +4 -0
- package/src/db/messages.ts +31 -25
- package/src/db/migrations.ts +18 -1
- package/src/db/notification-write-ops.ts +19 -0
- package/src/db/operator-answer-write.ts +19 -0
- package/src/db/orchestrators.ts +10 -4
- package/src/db/pairs-async.ts +22 -1
- package/src/db/pairs-write-ops.ts +8 -3
- package/src/db/pairs.ts +41 -48
- package/src/db/plan-dispatch-schema.ts +5 -1
- package/src/db/plan-ready-notices.ts +43 -0
- package/src/db/plan-tools-include-migration.ts +36 -0
- package/src/db/plans-write-ops.ts +2 -0
- package/src/db/presence-buffer.ts +5 -0
- package/src/db/presence-loop.ts +18 -23
- package/src/db/presence-write.ts +0 -6
- package/src/db/project-entries-async.ts +14 -0
- package/src/db/project-entries-read-ops.ts +5 -1
- package/src/db/project-entries-write-ops.ts +8 -0
- package/src/db/project-entries.ts +15 -12
- package/src/db/project-journal.ts +2 -2
- package/src/db/project-trust-approvals.ts +2 -2
- package/src/db/prompt-templates.ts +4 -4
- package/src/db/read-op-marshaling-fixtures.ts +18 -0
- package/src/db/read-ops.ts +4 -0
- package/src/db/retention.ts +13 -2
- package/src/db/review-publish-write.ts +8 -0
- package/src/db/runtime-admin-async.ts +19 -0
- package/src/db/runtime-admin-write-ops.ts +36 -0
- package/src/db/runtime-tail-async.ts +288 -0
- package/src/db/runtime-tail-write-ops.ts +97 -0
- package/src/db/schema.ts +4 -1
- package/src/db/spawn-budget.ts +5 -0
- package/src/db/spawn-delegation.ts +3 -12
- package/src/db/sql-audit-indexes.ts +3 -0
- package/src/db/stats-async.ts +5 -3
- package/src/db/task-entity.ts +5 -4
- package/src/db/team-claim-policy.ts +60 -0
- package/src/db/teams-async.ts +4 -0
- package/src/db/teams-write-ops.ts +4 -0
- package/src/db/terminal-events.ts +15 -0
- package/src/db/timer-cutover-bodies.ts +292 -0
- package/src/db/timer-cutover-core.ts +37 -278
- package/src/db/timer-cutover-state.ts +40 -0
- package/src/db/timer-cutover-write-ops.ts +1 -40
- package/src/db/token-db-write-ops.ts +2 -0
- package/src/db/token-standing-async.ts +12 -0
- package/src/db/token-standing.ts +6 -9
- package/src/db/token-usage-retention.ts +33 -0
- package/src/db/token-usage-write-ops.ts +1 -1
- package/src/db/token-usage.ts +4 -1
- package/src/db/user-invites-async.ts +13 -0
- package/src/db/user-invites.ts +3 -3
- package/src/db/users.ts +14 -6
- package/src/db/workflow-execution.ts +3 -3
- package/src/db/workspaces.ts +8 -5
- package/src/db/write-ops.ts +31 -12
- package/src/db/writer-fault-seam.ts +2 -9
- package/src/db/writer-fault-test-ops.ts +18 -0
- package/src/db/writer-gateway.ts +42 -46
- package/src/dev.ts +12 -16
- package/src/event-loop-lag.ts +4 -2
- package/src/event-loop-yield.ts +2 -2
- package/src/events.ts +10 -8
- package/src/host-provider-store.ts +5 -4
- package/src/hub-metrics-report.ts +5 -1
- package/src/hub-metrics.ts +38 -18
- package/src/init.ts +299 -0
- package/src/injection-sweep-pacing.ts +6 -8
- package/src/invite-link.ts +16 -9
- package/src/land-gate-notifications.ts +11 -10
- package/src/land-gate-queue-progress.ts +3 -3
- package/src/land-settle-dispatch.ts +52 -92
- package/src/lifecycle-context-pressure.ts +11 -10
- package/src/lifecycle-manager.ts +104 -98
- package/src/maintenance/breaker.ts +18 -16
- package/src/maintenance/checkout-refresh.ts +18 -1
- package/src/maintenance/critical-job-watchdog.ts +3 -3
- package/src/maintenance/events.ts +3 -3
- package/src/maintenance/history-retention-job.ts +30 -0
- package/src/maintenance/jobs.ts +29 -67
- package/src/maintenance/long-running-work.ts +3 -1
- package/src/maintenance/offline-agent-prune-job.ts +28 -0
- package/src/maintenance/orphaned-sessions.ts +5 -4
- package/src/maintenance/pauses.ts +4 -10
- package/src/maintenance/plan-ready-notice-job.ts +71 -0
- package/src/maintenance/scheduler.ts +18 -13
- package/src/maintenance/stalled-delivery-pager.ts +4 -4
- package/src/maintenance/teams.ts +19 -30
- package/src/maintenance/workspaces.ts +17 -27
- package/src/managed-policy-escalation.ts +7 -7
- package/src/managed-policy.ts +3 -3
- package/src/managed-provider-gate.ts +5 -4
- package/src/managed-spawn-reservation.ts +5 -4
- package/src/mcp/index.ts +8 -8
- package/src/mcp/output-descriptions.ts +1 -1
- package/src/mcp/presentation.ts +2 -1
- package/src/mcp/runtime-output.ts +6 -1
- package/src/mcp/self-care-visibility.ts +2 -2
- package/src/mcp/spawn-targets-matrix.ts +10 -1
- package/src/mcp/tool-groups.ts +3 -2
- package/src/mcp/tool-roles.ts +81 -0
- package/src/mcp/tools-workspace.ts +1 -1
- package/src/mcp-blackboard-tools.ts +6 -5
- package/src/mcp-decision-tools.ts +7 -7
- package/src/mcp-egress-tools.ts +10 -9
- package/src/mcp-issue-activity-tools.ts +2 -2
- package/src/mcp-issue-association-tools.ts +4 -4
- package/src/mcp-issue-ref-tools.ts +3 -3
- package/src/mcp-merge-tools.ts +5 -5
- package/src/mcp-notification-subscription-tools.ts +14 -15
- package/src/mcp-output-levels.test-fixture.ts +1 -1
- package/src/mcp-profile-trust-tools.ts +1 -1
- package/src/mcp-project-journal-tools.ts +4 -12
- package/src/mcp-project-tools.ts +17 -18
- package/src/mcp-routing-policy-tools.ts +3 -2
- package/src/mcp-team-tools.ts +6 -6
- package/src/mcp-workflow-tools.ts +5 -3
- package/src/memory-area-injection.ts +13 -12
- package/src/memory-boundary-capture.ts +6 -6
- package/src/memory-injection.ts +45 -43
- package/src/merge-pause-maintenance.ts +5 -4
- package/src/notification-router.ts +44 -17
- package/src/notify.ts +5 -5
- package/src/observed-reset-refresh.ts +4 -4
- package/src/operator-alarm.ts +2 -5
- package/src/project-ingest.ts +6 -6
- package/src/project-instructions.ts +8 -1
- package/src/project-trust.ts +12 -11
- package/src/prompt-resolver.ts +3 -3
- package/src/provider-quota-async.ts +5 -7
- package/src/provider-timeline-event.ts +4 -7
- package/src/quota-band-delivery.ts +2 -2
- package/src/recipe-runner.ts +4 -3
- package/src/retention-config-store.ts +4 -3
- package/src/reviewer-pipeline.ts +11 -10
- package/src/routes/_route.ts +4 -4
- package/src/routes/_shared.ts +13 -12
- package/src/routes/agent-effort.ts +5 -5
- package/src/routes/agent-heartbeat-quota.ts +23 -0
- package/src/routes/agent-keep.ts +1 -1
- package/src/routes/agent-reporting.ts +1 -1
- package/src/routes/agent-self-effort.ts +5 -5
- package/src/routes/agent-sessions.ts +24 -24
- package/src/routes/agents-spawn.ts +1 -1
- package/src/routes/agents.ts +17 -119
- package/src/routes/auth.ts +44 -17
- package/src/routes/authority-audit.ts +2 -2
- package/src/routes/automations.ts +6 -5
- package/src/routes/channel-binding-delete.ts +1 -1
- package/src/routes/channel-output.ts +3 -3
- package/src/routes/claude-api-budget.ts +5 -5
- package/src/routes/commands-listing.ts +1 -1
- package/src/routes/commands.ts +29 -27
- package/src/routes/context-resets.ts +2 -2
- package/src/routes/coordinator-teams.ts +1 -1
- package/src/routes/decisions.ts +2 -2
- package/src/routes/host-providers.ts +18 -0
- package/src/routes/host-secret-files.ts +1 -1
- package/src/routes/hosts.ts +11 -11
- package/src/routes/inbox.ts +3 -2
- package/src/routes/index.ts +7 -3
- package/src/routes/integrations.ts +9 -7
- package/src/routes/issue-activity.ts +2 -2
- package/src/routes/issue-associations.ts +4 -4
- package/src/routes/issue-refs.ts +3 -3
- package/src/routes/kernel-timers-operator.ts +1 -1
- package/src/routes/memory.ts +1 -1
- package/src/routes/merges.ts +11 -11
- package/src/routes/messages.ts +23 -17
- package/src/routes/orchestrator-bootstrap.ts +3 -1
- package/src/routes/orchestrator-host-registration.ts +2 -0
- package/src/routes/orchestrator-host-utilization.ts +2 -2
- package/src/routes/orchestrator-proxy.ts +2 -2
- package/src/routes/orchestrator.ts +27 -18
- package/src/routes/pairs.ts +8 -8
- package/src/routes/project-profile-instructions.ts +1 -1
- package/src/routes/project-trust.ts +1 -1
- package/src/routes/projects.ts +16 -16
- package/src/routes/prompt-templates.ts +12 -12
- package/src/routes/provider-quotas.ts +10 -10
- package/src/routes/run-command.ts +1 -1
- package/src/routes/secrets-backup.ts +4 -5
- package/src/routes/secrets-import.ts +3 -4
- package/src/routes/secrets-vault.ts +12 -14
- package/src/routes/settings.ts +1 -1
- package/src/routes/shipping.ts +9 -1
- package/src/routes/spawn-policy.ts +8 -7
- package/src/routes/sse.ts +2 -2
- package/src/routes/team-templates.ts +7 -7
- package/src/routes/teams.ts +10 -10
- package/src/routes/tokens.ts +18 -17
- package/src/routes/users.ts +24 -24
- package/src/routes/viewer-read.ts +3 -3
- package/src/routes/web-tool-calls.ts +4 -4
- package/src/routes/workflows.ts +2 -2
- package/src/routes/workspaces.ts +17 -16
- package/src/routing-policy-push.ts +6 -6
- package/src/runtime-grant.ts +17 -11
- package/src/runtime-install.ts +30 -0
- package/src/runtime-tokens.ts +20 -28
- package/src/secrets-broker/config.ts +1 -1
- package/src/secrets-broker/service.ts +2 -2
- package/src/security.ts +3 -1
- package/src/self-resume-carry.ts +21 -110
- package/src/self-resume-supersede.ts +4 -3
- package/src/self-resume.ts +54 -66
- package/src/server-background.ts +1 -1
- package/src/server.ts +25 -26
- package/src/services/agent-action.ts +12 -31
- package/src/services/agent-effort.ts +7 -32
- package/src/services/agent-hang-watchdog-job.ts +2 -2
- package/src/services/agent-heartbeat.ts +166 -0
- package/src/services/agent-reporting.ts +1 -1
- package/src/services/auth-context.ts +6 -0
- package/src/services/browser-inventory.ts +3 -3
- package/src/services/browser-session-state.ts +3 -2
- package/src/services/browser-session.ts +21 -27
- package/src/services/bus-command-update.ts +9 -9
- package/src/services/checkout-refresh-state.ts +1 -0
- package/src/services/checkout-refresh.test-fixture.ts +3 -2
- package/src/services/command-host.ts +7 -2
- package/src/services/coordinator-digest.ts +3 -2
- package/src/services/dispatch-command.ts +12 -13
- package/src/services/effective-launch-driver.ts +14 -9
- package/src/services/host-changed-paths.test-fixture.ts +5 -6
- package/src/services/host-project-readiness.ts +2 -2
- package/src/services/host-providers.ts +1 -1
- package/src/services/host-utilization.ts +9 -9
- package/src/services/idle-agent-digest.ts +17 -12
- package/src/services/idle-epics.ts +4 -4
- package/src/services/interrupt-agent.ts +12 -9
- package/src/services/issue-activity.ts +3 -3
- package/src/services/issue-associations.ts +15 -18
- package/src/services/issue-lifecycle-comments.ts +3 -2
- package/src/services/issue-lifecycle.ts +14 -13
- package/src/services/issue-refs.ts +4 -5
- package/src/services/kernel-timers-cutover-chaos-worker.ts +1 -1
- package/src/services/kernel-timers-ingress-chaos-worker.ts +6 -1
- package/src/services/kernel-timers-ingress.ts +3 -3
- package/src/services/kernel-timers-message-authority-chaos-worker.ts +3 -10
- package/src/services/kernel-timers-operator-chaos-worker.ts +3 -2
- package/src/services/kernel-timers-outbox.ts +1 -1
- package/src/services/kernel-timers-stage10-operator.ts +1 -1
- package/src/services/kernel-timers.ts +4 -3
- package/src/services/land-gate-placement.ts +11 -2
- package/src/services/land-issue-relations.ts +5 -4
- package/src/services/land-restart-retry.ts +7 -6
- package/src/services/landed-ancestry.ts +6 -5
- package/src/services/legacy-landing-host.ts +4 -1
- package/src/services/legacy-landing-recovery.ts +8 -6
- package/src/services/managed-running.ts +17 -17
- package/src/services/memory-areas.ts +3 -3
- package/src/services/merge-pause.ts +9 -15
- package/src/services/operator-decisions.ts +37 -41
- package/src/services/orchestrator-registration-recovery.ts +6 -2
- package/src/services/orchestrator-upgrade.ts +14 -12
- package/src/services/permission-decision.ts +4 -3
- package/src/services/plan-ci-notice.ts +1 -1
- package/src/services/plan-conformance.ts +4 -4
- package/src/services/plan-dispatch-policy.ts +10 -3
- package/src/services/plan-dispatch.ts +35 -14
- package/src/services/plan-graph.ts +39 -261
- package/src/services/plan-import.ts +1 -1
- package/src/services/plan-live-bindings.ts +8 -37
- package/src/services/plan-task-create.ts +1 -1
- package/src/services/plan-terminal-refs.ts +2 -12
- package/src/services/plan-wake-digest.ts +8 -3
- package/src/services/profile-trust.ts +2 -2
- package/src/services/project.ts +11 -10
- package/src/services/prompt-templates.ts +6 -5
- package/src/services/provider-api-key.ts +73 -0
- package/src/services/provider-hold-nudge.ts +9 -9
- package/src/services/provider-hold-record.ts +13 -12
- package/src/services/provider-state-audit.ts +19 -18
- package/src/services/provisioning-harness/driver.ts +1 -1
- package/src/services/provisioning-harness/fixture-matrix.ts +3 -3
- package/src/services/provisioning-harness/lifecycle.ts +24 -22
- package/src/services/provisioning-harness/prepare.ts +16 -17
- package/src/services/rate-limit-resume.ts +10 -9
- package/src/services/red-main-auto-revert.ts +7 -5
- package/src/services/red-main-controller-deps.ts +20 -3
- package/src/services/red-main-incident.ts +3 -1
- package/src/services/red-main-quarantine.ts +2 -3
- package/src/services/register-agent.ts +22 -22
- package/src/services/restart-project-role.ts +1 -1
- package/src/services/restart-spawn.ts +17 -16
- package/src/services/review-publish.ts +7 -24
- package/src/services/review-ref-reconcile.ts +29 -38
- package/src/services/runtime-dependency-alert.ts +27 -0
- package/src/services/scheduler-command.ts +11 -9
- package/src/services/scheduler.ts +5 -5
- package/src/services/self-effort-grant.ts +5 -25
- package/src/services/send-message.ts +16 -33
- package/src/services/shutdown-agent.ts +17 -14
- package/src/services/spawn-agent.ts +12 -41
- package/src/services/spawn-chain-inspector.ts +1 -1
- package/src/services/spawn-cwd-placement.ts +21 -5
- package/src/services/spawn-issue-activity.ts +8 -6
- package/src/services/spawn-launch.ts +17 -1
- package/src/services/spawn-loss-escalation.ts +1 -1
- package/src/services/spawn-registration-watchdog.ts +2 -2
- package/src/services/spawn-repo-probe.ts +7 -5
- package/src/services/spawn-tree-cleanup.ts +7 -8
- package/src/services/steward-reaper.ts +4 -4
- package/src/services/task-context-hydration.ts +25 -1
- package/src/services/task-delivery.ts +20 -34
- package/src/services/task-entity.ts +40 -203
- package/src/services/task-issue-link.ts +13 -20
- package/src/services/task-issue-weave.ts +12 -11
- package/src/services/task-lifecycle.ts +27 -31
- package/src/services/task-repo-cwd.ts +37 -0
- package/src/services/task-review-hold.ts +4 -17
- package/src/services/task-semantic-events.ts +13 -11
- package/src/services/task-state-reconcile.ts +3 -4
- package/src/services/task-validation.ts +2 -2
- package/src/services/team-templates.ts +5 -5
- package/src/services/team.ts +31 -98
- package/src/services/terminal-provider-exit.ts +6 -5
- package/src/services/timer-message-fire-chaos-worker.ts +7 -3
- package/src/services/timer-message-fire-outbox.ts +1 -1
- package/src/services/transient-agent-reaper.ts +22 -19
- package/src/services/turn-reconcile-audit.ts +9 -9
- package/src/services/user-onboarding.ts +8 -6
- package/src/services/user-profile.ts +6 -9
- package/src/services/work-finality.ts +16 -4
- package/src/services/workflow-auto-start.ts +2 -1
- package/src/services/workflow-caller.ts +61 -4
- package/src/services/workflow-child-proof-worker.ts +1 -1
- package/src/services/workflow-control-proof-worker.ts +1 -1
- package/src/services/workflow-coordinator.ts +8 -2
- package/src/services/workflow-decisions.ts +5 -5
- package/src/services/workflow-deferred-cleanup.ts +1 -1
- package/src/services/workflow-effect-driver.ts +42 -19
- package/src/services/workflow-effects.ts +41 -27
- package/src/services/workflow-pins.ts +7 -4
- package/src/services/workflow-reconcile.ts +1 -0
- package/src/services/workflow-resume-pins.ts +3 -3
- package/src/services/workflow-routing-defaults.ts +18 -0
- package/src/services/workflow-run-view.ts +4 -3
- package/src/services/workflow-run.test-fixture.ts +1 -1
- package/src/services/workflow-runs.ts +34 -22
- package/src/services/workflow-supervisor-state.ts +21 -1
- package/src/services/workflow-supervisor.ts +4 -3
- package/src/services/workspace-recovery.ts +4 -3
- package/src/setup.ts +47 -8
- package/src/spawn-admission.ts +10 -2
- package/src/spawn-placement.ts +27 -9
- package/src/spawn-targets.ts +8 -8
- package/src/sse-agent-status.ts +15 -6
- package/src/sse.ts +49 -24
- package/src/startup-context-injection.ts +61 -57
- package/src/steward-handoff.ts +4 -3
- package/src/steward-policy-cleanup.ts +9 -8
- package/src/steward.ts +2 -2
- package/src/task-dispatch-live.ts +5 -2
- package/src/task-dispatcher.ts +2 -2
- package/src/token-db.ts +2 -2
- package/src/token-usage-async.ts +2 -4
- package/src/user-awaiting-reply.ts +5 -5
- package/src/utils.ts +7 -0
- package/src/workspace-actions.ts +24 -29
- package/src/workspace-auto-merge.ts +14 -12
- package/src/workspace-changed-paths-client.ts +16 -5
- package/src/workspace-cleanup-stale.ts +30 -7
- package/src/workspace-command-settle.ts +24 -16
- package/src/workspace-config.ts +1 -1
- package/src/workspace-conflict-resolver.ts +9 -7
- package/src/workspace-dead-owner-recovery.ts +5 -4
- package/src/workspace-escalation.ts +12 -11
- package/src/workspace-human-escalation.ts +3 -3
- package/src/workspace-land-gate-watchdog.ts +3 -3
- package/src/workspace-land-refusal.ts +20 -0
- package/src/workspace-land-stopped.ts +1 -0
- package/src/workspace-merge.ts +10 -26
- package/src/workspace-nothing-to-land-notice.ts +2 -2
- package/src/workspace-orphans.ts +18 -37
- package/src/workspace-pr-completion.ts +10 -8
- package/src/workspace-rekey.ts +3 -3
- package/src/workspace-steward-failure.ts +2 -2
- package/src/workspace-steward-wake.ts +2 -2
- package/public/assets/agent-liveness-CaNwK0Zf.js +0 -2
- package/public/assets/overview-C1DCTzzV.js +0 -2
- package/public/assets/provider-display-DsuWMvVL.js +0 -2
- package/public/assets/run-card-CpKqRbhg.js +0 -2
- package/public/assets/shipping-B9YtnwtG.js +0 -2
- package/public/assets/store-DcClXLH0.js +0 -9
- package/runner/src/agent-runner/http-liveness.ts +0 -85
- package/src/db/on-loop-write-transaction.ts +0 -34
package/src/cd-deploy-notify.ts
CHANGED
|
@@ -41,7 +41,7 @@ export async function notifyCdDeployLive(input: CdDeployLiveInput = {}): Promise
|
|
|
41
41
|
const version = input.version ?? VERSION;
|
|
42
42
|
const gitSha = input.gitSha ?? reportedGitSha();
|
|
43
43
|
if (!gitSha) {
|
|
44
|
-
routeNotification({ type: "cd.deploy_live", scope: {}, recipients: [], message: {
|
|
44
|
+
await routeNotification({ type: "cd.deploy_live", scope: {}, recipients: [], message: {
|
|
45
45
|
body: `Humwick v${version} is now running.`, payload: { kind: "cd.deploy-live", version },
|
|
46
46
|
idempotencyKey: `release-deploy-live:${version}`, replyExpected: false,
|
|
47
47
|
} });
|
|
@@ -50,7 +50,7 @@ export async function notifyCdDeployLive(input: CdDeployLiveInput = {}): Promise
|
|
|
50
50
|
const shortSha = gitSha.slice(0, 12);
|
|
51
51
|
const contents = await deployNoticeContents(gitSha, input.repoRoot ?? resolve(import.meta.dir, ".."));
|
|
52
52
|
|
|
53
|
-
routeNotification({
|
|
53
|
+
await routeNotification({
|
|
54
54
|
type: "cd.deploy_live",
|
|
55
55
|
scope: {},
|
|
56
56
|
ttlMs: null,
|
package/src/ci/notifications.ts
CHANGED
|
@@ -120,13 +120,13 @@ export interface RouteCiIncidentNotificationResult {
|
|
|
120
120
|
* through routeNotification so its TTL, idempotency, routing explanation, and
|
|
121
121
|
* Activity audit behavior stay identical to every other Relay notification.
|
|
122
122
|
*/
|
|
123
|
-
export function routeCiIncidentNotification(input: RouteCiIncidentNotificationInput): RouteCiIncidentNotificationResult {
|
|
123
|
+
export async function routeCiIncidentNotification(input: RouteCiIncidentNotificationInput): Promise<RouteCiIncidentNotificationResult> {
|
|
124
124
|
const { payload } = input;
|
|
125
125
|
const subject = input.subject ?? defaultSubject(input.type, payload.repository, payload.branch);
|
|
126
126
|
const body = input.body ?? defaultBody(input);
|
|
127
127
|
const recipients = input.recipients ?? [payload.coordinatorAgentId];
|
|
128
128
|
const idempotencyKey = input.idempotencyKey ?? defaultIdempotencyKey(input);
|
|
129
|
-
const messages = routeNotification({
|
|
129
|
+
const messages = await routeNotification({
|
|
130
130
|
type: input.type,
|
|
131
131
|
scope: {
|
|
132
132
|
repoRoot: payload.repoRoot ?? payload.repository,
|
|
@@ -148,14 +148,14 @@ export function routeCiIncidentNotification(input: RouteCiIncidentNotificationIn
|
|
|
148
148
|
});
|
|
149
149
|
|
|
150
150
|
if (!input.alertHuman) return { messages };
|
|
151
|
-
const humanFallback = notifyWorkspaceHumanEscalation({
|
|
151
|
+
const humanFallback = (await notifyWorkspaceHumanEscalation({
|
|
152
152
|
subject,
|
|
153
153
|
body,
|
|
154
154
|
payload: { kind: input.type, ...payload },
|
|
155
155
|
priority: humanAlertPriority(input.type),
|
|
156
156
|
tags: ["agent-relay", "ci", humanAlertTag(input.type)],
|
|
157
157
|
source: "ci-incident",
|
|
158
|
-
});
|
|
158
|
+
}));
|
|
159
159
|
return { messages, humanFallback };
|
|
160
160
|
}
|
|
161
161
|
|
package/src/ci/root-missing.ts
CHANGED
|
@@ -11,11 +11,11 @@ export interface CiRootMissing {
|
|
|
11
11
|
|
|
12
12
|
type Deps = Pick<CiTransitionNotifyDeps, "resolveCoordinator" | "route" | "now">;
|
|
13
13
|
|
|
14
|
-
function notify(input: CiRootMissing, deps: Deps, fired: boolean): boolean {
|
|
14
|
+
async function notify(input: CiRootMissing, deps: Deps, fired: boolean): Promise<boolean> {
|
|
15
15
|
if (!fired) return false;
|
|
16
16
|
const route = deps.route ?? routeCiIncidentNotification;
|
|
17
17
|
const observedAt = deps.now ?? Date.now();
|
|
18
|
-
route({
|
|
18
|
+
await route({
|
|
19
19
|
type: "ci.root_missing",
|
|
20
20
|
payload: { provider: "github-actions", repository: input.repository, repoRoot: input.rootPath, branch: "*", coordinatorAgentId: resolveCoordinator(deps), observedAt },
|
|
21
21
|
alertHuman: true,
|
|
@@ -26,5 +26,5 @@ function notify(input: CiRootMissing, deps: Deps, fired: boolean): boolean {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export async function notifyCiRootMissing(input: CiRootMissing, deps: Deps = {}): Promise<boolean> {
|
|
29
|
-
return notify(input, deps, await markCiRootMissingNotifiedAsync(input.repository, deps.now));
|
|
29
|
+
return await notify(input, deps, await markCiRootMissingNotifiedAsync(input.repository, deps.now));
|
|
30
30
|
}
|
|
@@ -42,7 +42,7 @@ export const CI_MAIN_WATCH_COORDINATOR = "cd-watcher";
|
|
|
42
42
|
|
|
43
43
|
export interface CiTransitionNotifyDeps {
|
|
44
44
|
ingest?: (observation: CiObservation, now?: number) => CiIncidentIngestResult | Promise<CiIncidentIngestResult>;
|
|
45
|
-
route?: (input: Parameters<typeof routeCiIncidentNotification>[0]) => RouteCiIncidentNotificationResult
|
|
45
|
+
route?: (input: Parameters<typeof routeCiIncidentNotification>[0]) => RouteCiIncidentNotificationResult | Promise<RouteCiIncidentNotificationResult>;
|
|
46
46
|
/** Resolve the coordinator/owner agent the relay message addresses. Defaults to the configured
|
|
47
47
|
* steward fallback, then the system watch actor. */
|
|
48
48
|
resolveCoordinator?: () => string | undefined;
|
|
@@ -93,7 +93,7 @@ export async function notifyCiTransition(
|
|
|
93
93
|
failingRunIds: observation.failingRuns.map((run) => run.id),
|
|
94
94
|
failingJobNames: failingJobNames(observation),
|
|
95
95
|
};
|
|
96
|
-
const routed = route({
|
|
96
|
+
const routed = await route({
|
|
97
97
|
type: "ci.failed",
|
|
98
98
|
payload,
|
|
99
99
|
alertHuman: true,
|
|
@@ -117,7 +117,7 @@ export async function notifyCiTransition(
|
|
|
117
117
|
greenHeadSha: observation.headSha,
|
|
118
118
|
...(result.incident.resolution ? { resolution: result.incident.resolution } : {}),
|
|
119
119
|
};
|
|
120
|
-
const routed = route({
|
|
120
|
+
const routed = await route({
|
|
121
121
|
type: "ci.recovered",
|
|
122
122
|
payload,
|
|
123
123
|
alertHuman: true,
|
|
@@ -138,7 +138,7 @@ export async function notifyCiTransition(
|
|
|
138
138
|
firstSeenAt: result.firstSeenAt,
|
|
139
139
|
observedAt: observation.observedAt,
|
|
140
140
|
};
|
|
141
|
-
const routed = route({
|
|
141
|
+
const routed = await route({
|
|
142
142
|
type: "ci.never_matched",
|
|
143
143
|
payload,
|
|
144
144
|
alertHuman: true,
|
|
@@ -149,7 +149,7 @@ export async function notifyCiTransition(
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
if (result.kind === "config_mismatch") {
|
|
152
|
-
const routed = route(configMismatchRoute(observation, resolveCoordinator(deps), result.unmatchedJobs));
|
|
152
|
+
const routed = await route(configMismatchRoute(observation, resolveCoordinator(deps), result.unmatchedJobs));
|
|
153
153
|
return { transition: "config_mismatch", notified: true, messages: routed.messages.length, ...(routed.humanFallback ? { humanFallback: routed.humanFallback } : {}) };
|
|
154
154
|
}
|
|
155
155
|
|
|
@@ -68,12 +68,12 @@ async function getRuntime(): Promise<Runtime> {
|
|
|
68
68
|
removeShutdownHook = onShutdown("claude-app-oauth", stopClaudeAppOAuth);
|
|
69
69
|
outcome = { status: "ok", detail: "OAuth available" };
|
|
70
70
|
return { provider, server, base: `http://127.0.0.1:${address.port}` };
|
|
71
|
-
})().catch(error => withRelayEventDrain(() => {
|
|
71
|
+
})().catch(error => withRelayEventDrain(async () => {
|
|
72
72
|
runtime = undefined;
|
|
73
73
|
const detail = `OAuth unavailable: ${errMessage(error)}`;
|
|
74
74
|
outcome = { status: "error", detail };
|
|
75
|
-
raiseOperatorAlarm({ clientId: `claude-app-oauth:${detail}`, source: "claude-app-oauth",
|
|
76
|
-
subject: "Claude app OAuth unavailable", detail, view: "overview", dedupeEvent: true });
|
|
75
|
+
(await raiseOperatorAlarm({ clientId: `claude-app-oauth:${detail}`, source: "claude-app-oauth",
|
|
76
|
+
subject: "Claude app OAuth unavailable", detail, view: "overview", dedupeEvent: true }));
|
|
77
77
|
throw error;
|
|
78
78
|
}));
|
|
79
79
|
}
|
package/src/cli/index.ts
CHANGED
|
@@ -22,6 +22,7 @@ import { handleUpgradeCommand } from "./upgrade";
|
|
|
22
22
|
import { handleProviderCommand } from "./provider";
|
|
23
23
|
import { handleContextProbeCommand } from "./context-probe";
|
|
24
24
|
import { handleSetupCommand } from "./setup";
|
|
25
|
+
import { handleInitCommand } from "./init";
|
|
25
26
|
import { handleDaemonCommand } from "./daemon";
|
|
26
27
|
import { handleOrchestratorCommand } from "./orchestrator";
|
|
27
28
|
import { handleDevCommand } from "./dev";
|
|
@@ -68,6 +69,7 @@ Usage:
|
|
|
68
69
|
humwick run --status <runId>
|
|
69
70
|
${CHANNEL_OUTPUT_USAGE}
|
|
70
71
|
humwick [start]
|
|
72
|
+
humwick init [--yes] [--json] [--tarball-dir DIR] [--env-file PATH] [--runtime-prefix DIR] [--host HOST] [--port PORT] [--db-path PATH] (install or repair the server as a user service)
|
|
71
73
|
humwick setup [--yes] [--dry-run] [--force] [--env-file PATH] [--runtime-prefix DIR] [--host HOST] [--port PORT] [--db-path PATH] [--token TOKEN|--no-token]
|
|
72
74
|
humwick upgrade [--dry-run] [--version VERSION] [--runtime-prefix DIR] [--providers auto|all|codex|claude|opencode|orchestrator] [--no-restart] [--yes]
|
|
73
75
|
humwick upgrade --host ID [--host ID2 ...] [--version VERSION] [--providers ...] (upgrade remote orchestrator hosts over the relay)
|
|
@@ -281,10 +283,14 @@ export async function handleCli(args: string[]): Promise<"start" | "handled"> {
|
|
|
281
283
|
await handleUpgradeCommand(command === "setup" ? args.slice(2) : args.slice(1));
|
|
282
284
|
return "handled";
|
|
283
285
|
}
|
|
284
|
-
if (command === "setup"
|
|
286
|
+
if (command === "setup") {
|
|
285
287
|
await handleSetupCommand(args.slice(1));
|
|
286
288
|
return "handled";
|
|
287
289
|
}
|
|
290
|
+
if (command === "init") {
|
|
291
|
+
await handleInitCommand(args.slice(1));
|
|
292
|
+
return "handled";
|
|
293
|
+
}
|
|
288
294
|
if (command === "channels-host") {
|
|
289
295
|
const { handleChannelsHostCommand } = await import("./channels-host");
|
|
290
296
|
await handleChannelsHostCommand(args.slice(1));
|
package/src/cli/init.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// `humwick init` (#2680): install or repair a persistent server; the same code serves --yes/--json.
|
|
2
|
+
import { InitStepError, runInit, type InitOptions } from "../init";
|
|
3
|
+
import { errMessage } from "@humwick/sdk";
|
|
4
|
+
import { confirm } from "./_shared";
|
|
5
|
+
|
|
6
|
+
export async function handleInitCommand(args: string[]): Promise<void> {
|
|
7
|
+
const options: InitOptions = {};
|
|
8
|
+
let yes = false;
|
|
9
|
+
let json = false;
|
|
10
|
+
for (let i = 0; i < args.length; i++) {
|
|
11
|
+
const arg = args[i];
|
|
12
|
+
const value = () => {
|
|
13
|
+
const next = args[++i];
|
|
14
|
+
if (!next) throw new Error(`${arg} needs a value`);
|
|
15
|
+
return next;
|
|
16
|
+
};
|
|
17
|
+
if (arg === "--tarball-dir") options.tarballDir = value();
|
|
18
|
+
else if (arg === "--runtime-prefix") options.runtimePrefix = value();
|
|
19
|
+
else if (arg === "--env-file") options.envFile = value();
|
|
20
|
+
else if (arg === "--host") options.host = value();
|
|
21
|
+
else if (arg === "--port") options.port = parseInt(value(), 10);
|
|
22
|
+
else if (arg === "--db-path") options.dbPath = value();
|
|
23
|
+
else if (arg === "--yes" || arg === "-y") yes = true;
|
|
24
|
+
else if (arg === "--json") json = true;
|
|
25
|
+
else throw new Error(`Unknown init option "${arg}"`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!yes && !json && !(await confirm("Install the Humwick server as a user service on this machine?"))) {
|
|
29
|
+
console.log("Init cancelled.");
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
// With --json, stdout carries only the result object; progress goes to stderr.
|
|
33
|
+
const log = (line: string) => (json ? console.error : console.log)(`✓ ${line}`);
|
|
34
|
+
try {
|
|
35
|
+
const result = await runInit(options, log);
|
|
36
|
+
if (json) {
|
|
37
|
+
console.log(JSON.stringify(result, null, 2));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
for (const warning of result.warnings) console.log(`! ${warning}`);
|
|
41
|
+
console.log(`\nHumwick ${result.version} is running as ${result.service.unit}.`);
|
|
42
|
+
console.log(`Dashboard: ${result.dashboardUrl}`);
|
|
43
|
+
console.log(`Login link: ${result.loginUrl}`);
|
|
44
|
+
console.log("\nNext:");
|
|
45
|
+
for (const step of result.next) console.log(`- ${step}`);
|
|
46
|
+
} catch (e) {
|
|
47
|
+
const step = e instanceof InitStepError ? e.step : "init";
|
|
48
|
+
const repair = e instanceof InitStepError ? e.repair : "Rerun init; it resumes where it stopped.";
|
|
49
|
+
if (json) console.log(JSON.stringify({ ok: false, step, error: errMessage(e), repair }, null, 2));
|
|
50
|
+
else console.error(`init failed at ${step}: ${errMessage(e)}\nRepair: ${repair}`);
|
|
51
|
+
process.exitCode = 1;
|
|
52
|
+
}
|
|
53
|
+
}
|
package/src/cli/orchestrator.ts
CHANGED
|
@@ -20,7 +20,7 @@ import { createUserPathPlan, executeUserPathPlan, purgeUserPath } from "../user-
|
|
|
20
20
|
import { VERSION } from "../config";
|
|
21
21
|
import { shellQuote } from "@humwick/sdk/shell-utils";
|
|
22
22
|
import { RELAY_TOKEN_HEADER } from "@humwick/sdk";
|
|
23
|
-
import { expandTilde } from "../utils";
|
|
23
|
+
import { expandTilde, sanitizeOrchestratorId } from "../utils";
|
|
24
24
|
import { confirm } from "./_shared";
|
|
25
25
|
|
|
26
26
|
const ORCHESTRATOR_USAGE =
|
|
@@ -310,12 +310,6 @@ async function exchangeOrchestratorBootstrapToken(relayUrl: string, bootstrapTok
|
|
|
310
310
|
return payload.token;
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
function sanitizeOrchestratorId(value: string): string {
|
|
314
|
-
const clean = value.trim().replace(/\./g, "-").replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
315
|
-
if (!clean) throw new Error("--id must contain at least one letter or number");
|
|
316
|
-
return clean.slice(0, 120);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
313
|
function detectProviderPathPrefixes(providers: string[]): string[] {
|
|
320
314
|
const prefixes: string[] = [];
|
|
321
315
|
for (const provider of providers) {
|
package/src/cli/setup.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Setup command — auto-split from cli.ts (#294). Generates the relay env file.
|
|
2
|
-
import {
|
|
2
|
+
import { executeSetupPlan, formatSetupPlan, pathExists, redactSetupPlan, resolveSetupPlan } from "../setup";
|
|
3
3
|
import { confirm } from "./_shared";
|
|
4
4
|
|
|
5
5
|
export async function handleSetupCommand(args: string[]): Promise<void> {
|
|
@@ -32,7 +32,7 @@ export async function handleSetupCommand(args: string[]): Promise<void> {
|
|
|
32
32
|
else throw new Error(`Unknown setup option "${arg}"`);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
const plan =
|
|
35
|
+
const plan = await resolveSetupPlan({
|
|
36
36
|
...(envFile ? { envFile } : {}),
|
|
37
37
|
...(host ? { host } : {}),
|
|
38
38
|
...(port !== undefined ? { port } : {}),
|
|
@@ -43,7 +43,8 @@ export async function handleSetupCommand(args: string[]): Promise<void> {
|
|
|
43
43
|
force,
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
// A managed env file is reused (same token), so only a foreign file needs consent.
|
|
47
|
+
if (!dryRun && !yes && !plan.reused && await pathExists(plan.envFile)) {
|
|
47
48
|
const ok = await confirm(`Overwrite ${plan.envFile}?`);
|
|
48
49
|
if (!ok) {
|
|
49
50
|
console.log("Setup cancelled.");
|
|
@@ -52,6 +53,7 @@ export async function handleSetupCommand(args: string[]): Promise<void> {
|
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
const result = await executeSetupPlan(plan, { dryRun, force });
|
|
55
|
-
|
|
56
|
+
// The admin token never goes to stdout; it stays in the 0600 env file (#2680).
|
|
57
|
+
if (json) console.log(JSON.stringify({ plan: redactSetupPlan(plan), output: result }, null, 2));
|
|
56
58
|
else console.log(dryRun ? formatSetupPlan(plan) : result);
|
|
57
59
|
}
|
package/src/cli/workflow.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { apiRequest } from "./_shared";
|
|
2
2
|
import { probeWorkflowDeployment } from "../../scripts/wait-for-deploy";
|
|
3
3
|
|
|
4
|
-
export const WORKFLOW_USAGE = "Usage: humwick workflow start <workflow> <taskId> [--json] | workflow get <runId> [--verbose] [--include-held] [--results-ref <id>] [--results-cursor <cursor>] [--json] | workflow resume <runId> [--activation <id>] | workflow pause <runId> --reason <text> | workflow unpause <runId>";
|
|
4
|
+
export const WORKFLOW_USAGE = "Usage: humwick workflow start <workflow> <taskId> [--json] | workflow get <runId> [--verbose] [--include-held] [--results-ref <id>] [--results-cursor <cursor>] [--json] | workflow resume <runId> [--activation <id>] [--step <step>] [--pins <json>] [--note <text>] | workflow pause <runId> --reason <text> | workflow unpause <runId>";
|
|
5
5
|
|
|
6
6
|
export async function handleWorkflowCommand(args: string[]): Promise<void> {
|
|
7
7
|
const [command, runId, ...flags] = args;
|
|
@@ -33,8 +33,17 @@ export async function handleWorkflowCommand(args: string[]): Promise<void> {
|
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
35
|
if (command === "resume") {
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
const body: Record<string, unknown> = {};
|
|
37
|
+
const fields: Record<string, string> = { "--activation": "activationId", "--step": "step", "--pins": "pins", "--note": "note" };
|
|
38
|
+
for (let index = 0; index < flags.length; index++) {
|
|
39
|
+
const flag = flags[index]!;
|
|
40
|
+
if (flag === "--json") continue;
|
|
41
|
+
const field = fields[flag];
|
|
42
|
+
const value = flags[++index];
|
|
43
|
+
if (!field || !value || value.startsWith("--")) throw new Error(WORKFLOW_USAGE);
|
|
44
|
+
body[field] = field === "pins" ? JSON.parse(value) : value;
|
|
45
|
+
}
|
|
46
|
+
console.log(JSON.stringify(await apiRequest("POST", `/api/workflows/runs/${encodeURIComponent(runId)}/resume`, body), null, 2));
|
|
38
47
|
return;
|
|
39
48
|
}
|
|
40
49
|
const query = new URLSearchParams();
|
package/src/commands-db.ts
CHANGED
|
@@ -834,13 +834,13 @@ export function deleteCommand(id: string): boolean {
|
|
|
834
834
|
|
|
835
835
|
// Race the host claim on the same pending row; only the winning cancellation records stop intent.
|
|
836
836
|
// Legacy landing cancellation stays confined to its unfenced rows.
|
|
837
|
-
export function cancelPendingCommand(id: string, expectedType: string, reason = "canceled before dispatch"): boolean {
|
|
837
|
+
export function cancelPendingCommand(id: string, expectedType: string, reason = "canceled before dispatch", submittedAt: number = Date.now()): boolean {
|
|
838
838
|
if (expectedType === "workspace.merge") {
|
|
839
839
|
const existing = getCommand(id);
|
|
840
840
|
if (!existing || !isLegacyUnfencedWorkspaceMerge(existing)) return false;
|
|
841
841
|
}
|
|
842
842
|
return inWriteTransaction(() => {
|
|
843
|
-
const now =
|
|
843
|
+
const now = submittedAt;
|
|
844
844
|
const changes = getDb()
|
|
845
845
|
.query(`UPDATE commands SET status = 'canceled', result = ${canceledSpawnResultSql()}, error = ?, updated_at = ? WHERE id = ? AND status = 'pending' AND type = ?`)
|
|
846
846
|
.run(reason, now, id, expectedType).changes;
|
|
@@ -978,7 +978,7 @@ export const EXPIRED_PENDING_COMMANDS_SQL = `SELECT * FROM commands WHERE (type
|
|
|
978
978
|
|
|
979
979
|
export function expireCommands(
|
|
980
980
|
now: number = Date.now(),
|
|
981
|
-
opts: { isTargetGone?: (command: Command) => boolean } = {},
|
|
981
|
+
opts: { isTargetGone?: (command: Command) => boolean; update?: typeof updateCommand } = {},
|
|
982
982
|
): Command[] {
|
|
983
983
|
const activeRows = getDb().query(EXPIRED_CLAIMED_COMMANDS_SQL).all(now, ...CLAIMED_ACTIVE_STATUSES) as CommandRow[];
|
|
984
984
|
const pendingCandidates = getDb().query(EXPIRED_PENDING_COMMANDS_SQL).all(now) as CommandRow[];
|
|
@@ -998,7 +998,7 @@ export function expireCommands(
|
|
|
998
998
|
// #1452 round-13 — the TTL sweep is an AUTHORIZED terminalizer of a claimed publish (executor:true):
|
|
999
999
|
// it is the fail-closed path that lets the reconciler clean a host-death-after-claim, and timed_out is
|
|
1000
1000
|
// ambiguous (ref retained), never a ref-drop. External surfaces get no such flag (see updateCommand).
|
|
1001
|
-
updateCommand(row.id, {
|
|
1001
|
+
(opts.update ?? updateCommand)(row.id, {
|
|
1002
1002
|
status: "timed_out",
|
|
1003
1003
|
error: row.status === "pending"
|
|
1004
1004
|
? ((row.type === "agent.spawn" || row.type === "agent.restart") && hostSpawnsDrained(row.target) ? "host draining: spawns disabled; expired before dispatch" : "command target gone; expired before dispatch")
|
package/src/commands-write.ts
CHANGED
|
@@ -49,6 +49,10 @@ export async function createCommandAsync(
|
|
|
49
49
|
vaultProjectId?: string,
|
|
50
50
|
): Promise<Command> {
|
|
51
51
|
const args = await prepareCommandWriteAsync(input, options, vaultActor, vaultProjectId);
|
|
52
|
+
return submitPreparedCommandAsync(args);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function submitPreparedCommandAsync(args: CreateCommandWriteArgs): Promise<Command> {
|
|
52
56
|
return getGateway().coalesce(
|
|
53
57
|
"commands.create",
|
|
54
58
|
args,
|
|
@@ -82,6 +86,10 @@ export function getCommandAsync(id: string): Promise<Command | null> {
|
|
|
82
86
|
return getGateway().read("commands.get", { id }) as unknown as Promise<Command | null>;
|
|
83
87
|
}
|
|
84
88
|
|
|
89
|
+
export function findLatestCommandByCorrelationAsync(type: string, correlationId: string): Promise<Command | null> {
|
|
90
|
+
return getGateway().read("commands.latestByCorrelation", { type, correlationId }) as unknown as Promise<Command | null>;
|
|
91
|
+
}
|
|
92
|
+
|
|
85
93
|
/** #2969 — an agent's confirmed effort changes within a chat window's time range, read off-loop. */
|
|
86
94
|
export function listEffortChangesAsync(agentId: string, from: number, to: number, after?: EffortChangeCursor): Promise<{ changes: EffortChange[]; next?: EffortChangeCursor }> {
|
|
87
95
|
return getGateway().read("commands.effortChanges", { agentId, from, to, ...(after ? { after } : {}) }) as unknown as Promise<{ changes: EffortChange[]; next?: EffortChangeCursor }>;
|
package/src/compaction-watch.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { framed } from "./hub-metrics";
|
|
2
|
+
import { createActivityEventAsync } from "./db/activity-async";
|
|
1
3
|
import { timePostBindPhase } from "./post-bind-startup";
|
|
2
4
|
import { guardedInterval, isRecord } from "@humwick/sdk";
|
|
3
|
-
import { getAgent
|
|
5
|
+
import { getAgent } from "./db";
|
|
4
6
|
import { emitRelayEvent } from "./events";
|
|
5
7
|
import { isContinuationSelfResumeCommand } from "./self-resume-command";
|
|
6
8
|
import type { AgentCard, Command } from "./types";
|
|
@@ -74,7 +76,7 @@ export class CompactionWatch {
|
|
|
74
76
|
start(): void {
|
|
75
77
|
if (this.timer) return;
|
|
76
78
|
// #3643 — the tick writes an activity event; a BUSY from a bare timer would exit the hub.
|
|
77
|
-
this.timer = guardedInterval("[compaction-watch] tick", this.tickMs, () => timePostBindPhase("compaction-watch.tick", () => this.tick()));
|
|
79
|
+
this.timer = guardedInterval("[compaction-watch] tick", this.tickMs, framed("timer compaction-watch", () => timePostBindPhase("compaction-watch.tick", async () => (await this.tick()))));
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
stop(): void {
|
|
@@ -116,7 +118,7 @@ export class CompactionWatch {
|
|
|
116
118
|
this.pending.delete(agentId);
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
tick(): void {
|
|
121
|
+
async tick(): Promise<void> {
|
|
120
122
|
const now = this.now();
|
|
121
123
|
for (const [agentId, watch] of this.pending) {
|
|
122
124
|
if (watch.deadline > now) continue;
|
|
@@ -138,15 +140,15 @@ export class CompactionWatch {
|
|
|
138
140
|
continue;
|
|
139
141
|
}
|
|
140
142
|
this.pending.delete(agentId);
|
|
141
|
-
this.emitStalled(watch, true);
|
|
143
|
+
(await this.emitStalled(watch, true));
|
|
142
144
|
continue;
|
|
143
145
|
}
|
|
144
146
|
this.pending.delete(agentId);
|
|
145
|
-
this.emitStalled(watch);
|
|
147
|
+
(await this.emitStalled(watch));
|
|
146
148
|
}
|
|
147
149
|
}
|
|
148
150
|
|
|
149
|
-
private emitStalled(watch: PendingWatch, busyCapped = false): void {
|
|
151
|
+
private async emitStalled(watch: PendingWatch, busyCapped = false): Promise<void> {
|
|
150
152
|
const verb = watch.kind === "compact" ? "Compaction" : "Context clear";
|
|
151
153
|
// #2043 F3 — the busy-capped variant means the agent is STILL taking turns (not stuck at a menu)
|
|
152
154
|
// yet the compaction never started after a bounded wait — the runaway shape from #2043.
|
|
@@ -159,7 +161,7 @@ export class CompactionWatch {
|
|
|
159
161
|
subject: watch.agentId,
|
|
160
162
|
data: { agentId: watch.agentId, commandId: watch.commandId, kind: watch.kind, detail, busyCapped },
|
|
161
163
|
});
|
|
162
|
-
|
|
164
|
+
(await createActivityEventAsync({
|
|
163
165
|
clientId: `command-stalled-${watch.commandId}-${this.now()}-${++this.seq}`,
|
|
164
166
|
kind: "state",
|
|
165
167
|
title: `${verb} stalled: ${watch.agentId}`,
|
|
@@ -168,7 +170,7 @@ export class CompactionWatch {
|
|
|
168
170
|
view: "agents",
|
|
169
171
|
agentId: watch.agentId,
|
|
170
172
|
metadata: { source: "compaction-watch", commandId: watch.commandId, kind: watch.kind, stalled: true, detail, busyCapped },
|
|
171
|
-
});
|
|
173
|
+
}));
|
|
172
174
|
}
|
|
173
175
|
}
|
|
174
176
|
|
|
@@ -45,7 +45,7 @@ export async function setAgentProfileAsync(profile: AgentProfile, updatedBy?: st
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/** `deleteAgentProfile` on the writer thread (#1870 S7). */
|
|
48
|
-
export function deleteAgentProfileAsync(name: string, updatedBy?: string, opts: { resetBuiltInOverride?: boolean } = {}): Promise<boolean> {
|
|
48
|
+
export async function deleteAgentProfileAsync(name: string, updatedBy?: string, opts: { resetBuiltInOverride?: boolean } = {}): Promise<boolean> {
|
|
49
49
|
const target = agentProfileDeleteTarget(name, opts);
|
|
50
|
-
return deleteConfigAsync(target.namespace, target.key, updatedBy);
|
|
50
|
+
return (await deleteConfigAsync(target.namespace, target.key, updatedBy));
|
|
51
51
|
}
|
package/src/config.ts
CHANGED
|
@@ -637,21 +637,14 @@ export const DB_READER_JOB_TIMEOUT_MS = envPositiveInt("AGENT_RELAY_DB_READER_JO
|
|
|
637
637
|
export const DB_READER_MARSHAL_IN_PROCESS =
|
|
638
638
|
process.env.NODE_ENV === "test" || relayEnv(process.env, "AGENT_RELAY_DB_MARSHAL") === "1";
|
|
639
639
|
|
|
640
|
-
/**
|
|
641
|
-
* Phase-R rollout gate (#1960 T2 — ADR 0001 §7 Phase 1) for the gateway's READER half only. The
|
|
642
|
-
* writer stays in-process unconditionally: Phase W (a worker writer taking the sole RW connection) is
|
|
643
|
-
* a separate, much larger burn-down (#1870) and is deliberately NOT wired here. Any value other than
|
|
644
|
-
* the literal `"worker"` — unset included — resolves to `"in-process"`, so this is behavior-preserving
|
|
645
|
-
* by default; an operator opts in explicitly per the same string-literal convention as
|
|
646
|
-
* `parseKernelTimersMode`.
|
|
647
|
-
*/
|
|
640
|
+
/** Explicit reader placement override. Otherwise file databases use workers (#3339). */
|
|
648
641
|
export type GatewayReaderBackendMode = "in-process" | "worker";
|
|
649
642
|
|
|
650
|
-
export function parseGatewayReaderBackend(value: string | undefined): GatewayReaderBackendMode {
|
|
651
|
-
return value === "worker"
|
|
643
|
+
export function parseGatewayReaderBackend(value: string | undefined): GatewayReaderBackendMode | undefined {
|
|
644
|
+
return value === "worker" || value === "in-process" ? value : undefined;
|
|
652
645
|
}
|
|
653
646
|
|
|
654
|
-
export function gatewayReaderBackendFromEnv(): GatewayReaderBackendMode {
|
|
647
|
+
export function gatewayReaderBackendFromEnv(): GatewayReaderBackendMode | undefined {
|
|
655
648
|
return parseGatewayReaderBackend(relayEnv(process.env, "AGENT_RELAY_GATEWAY_READER_BACKEND"));
|
|
656
649
|
}
|
|
657
650
|
|
package/src/connectors.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { framed } from "./hub-metrics";
|
|
2
|
+
import { upsertAgentAsync } from "./db/agents-async";
|
|
1
3
|
import { writeChildEnv } from "@humwick/sdk/env";
|
|
2
4
|
import { timePostBindPhase } from "./post-bind-startup";
|
|
3
5
|
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
6
|
import { homedir } from "node:os";
|
|
5
7
|
import { dirname, join, resolve } from "node:path";
|
|
6
8
|
import type { ConnectorAction, ConnectorActionResult, ConnectorManifest, ConnectorSummary } from "./types";
|
|
7
|
-
import {
|
|
9
|
+
import { ValidationError } from "./db";
|
|
8
10
|
import { CHANNELS_HOST_SECRETS } from "@humwick/sdk/channels-host-service";
|
|
9
11
|
import { fireAndForget, guardedInterval, isRecord } from "@humwick/sdk";
|
|
10
12
|
import { registerConnectorConfigSetting, validateConnectorConfig } from "./settings/modules";
|
|
@@ -274,11 +276,11 @@ export function startConnectorStatusPoller(): void {
|
|
|
274
276
|
// deploy that took down the relay/orchestrator tree) BEFORE the first status
|
|
275
277
|
// poll overwrites their persisted "running" flag with the now-dead reality.
|
|
276
278
|
void fireAndForget("[connectors] boot reconcile", async () => {
|
|
277
|
-
await fireAndForget("[connectors] ensure channels host", () => timePostBindPhase("connectors.ensureChannelsHostConnector", () => ensureChannelsHostOnBoot()));
|
|
279
|
+
await fireAndForget("[connectors] ensure channels host", () => timePostBindPhase("connectors.ensureChannelsHostConnector", async () => (await ensureChannelsHostOnBoot())));
|
|
278
280
|
await fireAndForget("[connectors] reconcile on boot", () => timePostBindPhase("connectors.reconcileConnectorsOnBoot", reconcileConnectorsOnBoot));
|
|
279
281
|
await timePostBindPhase("connectors.refreshAllConnectorStatuses", refreshAllConnectorStatuses);
|
|
280
282
|
});
|
|
281
|
-
guardedInterval("[connectors] status poll", STATUS_POLL_INTERVAL_MS, () => timePostBindPhase("connectors.refreshAllConnectorStatuses", refreshAllConnectorStatuses));
|
|
283
|
+
guardedInterval("[connectors] status poll", STATUS_POLL_INTERVAL_MS, framed("timer connector-status", () => timePostBindPhase("connectors.refreshAllConnectorStatuses", refreshAllConnectorStatuses)));
|
|
282
284
|
}
|
|
283
285
|
|
|
284
286
|
const CHANNELS_HOST_ID = "channels-host";
|
|
@@ -386,14 +388,14 @@ function configuredNtfyTopic(): string | null {
|
|
|
386
388
|
* adapter's own gate — an unconfigured relay genuinely has no escalation target and must
|
|
387
389
|
* still warn. Returns true when the row was (re)registered.
|
|
388
390
|
*/
|
|
389
|
-
export function ensureEscalationChannelRegistered(): boolean {
|
|
391
|
+
export async function ensureEscalationChannelRegistered(): Promise<boolean> {
|
|
390
392
|
if (isEphemeralMode()) return false;
|
|
391
393
|
const topic = configuredNtfyTopic();
|
|
392
394
|
if (!topic) return false;
|
|
393
395
|
// Shape matches the channels-host adapter's registration (channels-host/src/relay.ts
|
|
394
396
|
// registerChannel + adapters/ntfy.ts channels()), so its later re-registration updates
|
|
395
397
|
// the same row in place rather than churning it.
|
|
396
|
-
|
|
398
|
+
(await upsertAgentAsync({
|
|
397
399
|
id: ESCALATION_NTFY_CHANNEL_ID,
|
|
398
400
|
name: "ntfy",
|
|
399
401
|
kind: "channel",
|
|
@@ -411,7 +413,7 @@ export function ensureEscalationChannelRegistered(): boolean {
|
|
|
411
413
|
displayName: "ntfy",
|
|
412
414
|
topicChannels: [topic],
|
|
413
415
|
},
|
|
414
|
-
});
|
|
416
|
+
}));
|
|
415
417
|
return true;
|
|
416
418
|
}
|
|
417
419
|
|
|
@@ -429,7 +431,7 @@ export async function ensureChannelsHostConnector(entry = resolveChannelsHostEnt
|
|
|
429
431
|
// Register the escalation channel row now that config (incl. any legacy-migrated topic)
|
|
430
432
|
// is persisted, so the escalation-target check passes without waiting for the async
|
|
431
433
|
// channels-host SSE connect (#1510).
|
|
432
|
-
ensureEscalationChannelRegistered();
|
|
434
|
+
(await ensureEscalationChannelRegistered());
|
|
433
435
|
|
|
434
436
|
|
|
435
437
|
}
|
|
@@ -437,7 +439,7 @@ export async function ensureChannelsHostConnector(entry = resolveChannelsHostEnt
|
|
|
437
439
|
/** Boot wrapper: a failed bring-up is logged with its stack and raised to /api/health, never swallowed (#3393). */
|
|
438
440
|
export async function ensureChannelsHostOnBoot(entry?: string | null): Promise<void> {
|
|
439
441
|
try {
|
|
440
|
-
await (entry === undefined ? ensureChannelsHostConnector() : ensureChannelsHostConnector(entry));
|
|
442
|
+
await (entry === undefined ? (await ensureChannelsHostConnector()) : (await ensureChannelsHostConnector(entry)));
|
|
441
443
|
clearChannelsHostEnsureFailure();
|
|
442
444
|
} catch (error) {
|
|
443
445
|
console.error("[connectors] ensureChannelsHostConnector failed:", error instanceof Error ? (error.stack ?? error.message) : error);
|