@humwick/server 0.130.1 → 0.130.2
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/README.md +5 -0
- package/docs/guides/tools-administration.md +4 -0
- package/docs/guides/tools-coordination.md +1 -0
- package/docs/guides/tools-tasks.md +8 -0
- package/docs/guides/workflows.md +58 -0
- package/docs/openapi.json +414 -1
- package/package.json +8 -17
- package/public/assets/{MessageBubble-BWpoBjl4.js → MessageBubble-BWLqMGKG.js} +2 -2
- package/public/assets/{PlanGraphPanel-C0auck3n.js → PlanGraphPanel-3TlIQpjk.js} +2 -2
- package/public/assets/{TraceView-DBnOx7AQ.js → TraceView-Wimm0Czv.js} +2 -2
- package/public/assets/{VaultDecisionCard-0kp2oNBC.js → VaultDecisionCard-Bau_vNax.js} +2 -2
- package/public/assets/{activity-yLztXEBt.js → activity-CrSurn-r.js} +2 -2
- package/public/assets/{agent-lineage-BbJDR1dW.js → agent-lineage-CknAJKcb.js} +2 -2
- package/public/assets/agent-liveness-CaNwK0Zf.js +2 -0
- package/public/assets/{agent-name-CTZBrSD9.js → agent-name-DKbiIhBo.js} +2 -2
- package/public/assets/agent-profiles-DwF6EQ4R.js +2 -0
- package/public/assets/{agent-project-badge-9TqzUUYE.js → agent-project-badge-Diz4Sjjb.js} +2 -2
- package/public/assets/{agent-tools-D4n40pn8.js → agent-tools-CRhpRQza.js} +2 -2
- package/public/assets/{agent-type-icon-D6FUarOf.js → agent-type-icon-LrUEU3lB.js} +2 -2
- package/public/assets/{agents-BYDslkJc.js → agents-B-v66C-4.js} +2 -2
- package/public/assets/{analytics-B-XSbEMC.js → analytics-BqCb-LKi.js} +2 -2
- package/public/assets/{artifact-viewer-DdWIfV6M.js → artifact-viewer-kf4pGuAR.js} +2 -2
- package/public/assets/{artifacts-oBOqks-2.js → artifacts-D32zyw4Y.js} +2 -2
- package/public/assets/{artifacts-DPN1q4pA.js → artifacts-DJevXcvg.js} +2 -2
- package/public/assets/{automation-4KcRFXEu.js → automation-BpRajx_5.js} +2 -2
- package/public/assets/{backlog-Cw9xPTCF.js → backlog-D_UjTdzX.js} +2 -2
- package/public/assets/{busy-health-CTu32MZt.js → busy-health-N3VEh4ao.js} +2 -2
- package/public/assets/{channels-BiXzg1G9.js → channels-9jopungq.js} +2 -2
- package/public/assets/{chat-Ctk2qwvA.js → chat-CSXrTB3C.js} +2 -2
- package/public/assets/{code-preview-Bm1wWqAp.js → code-preview-p1NnmqK0.js} +2 -2
- package/public/assets/{connectors-C36ax4Vw.js → connectors-CZdqlDNL.js} +2 -2
- package/public/assets/{cosmos-Jj9LK2Wf.js → cosmos-BgdsE4dG.js} +2 -2
- package/public/assets/{crate-agent-H6S7-B9T.js → crate-agent-30aXTKva.js} +2 -2
- package/public/assets/{dependency-graph-Cd1E23wa.js → dependency-graph-B_jvw2GE.js} +2 -2
- package/public/assets/{deploys-Bwfq146q.js → deploys-DoN6bAb5.js} +2 -2
- package/public/assets/{display-CfO7rTuF.js → display-BrKWFGJz.js} +2 -2
- package/public/assets/{files-DhhZI2Ih.js → files-D6XEu8Ng.js} +2 -2
- package/public/assets/{fleet-B_rFEbnL.js → fleet-C7jQWbw2.js} +2 -2
- package/public/assets/{fleet-metrics-BkHP-P3R.js → fleet-metrics-BiDs3MLx.js} +2 -2
- package/public/assets/{formatted-body-Cm1RrzmN.js → formatted-body-CQBwc1fb.js} +3 -3
- package/public/assets/{formatted-body-impl-DQiOuOD1.js → formatted-body-impl-DyG0WsQS.js} +2 -2
- package/public/assets/{host-providers-dialog-CHqwXTov.js → host-providers-dialog-DKaW31dN.js} +2 -2
- package/public/assets/index-CRHep3M9.js +15 -0
- package/public/assets/index-MYAIwYTX.css +2 -0
- package/public/assets/{insights-fH1EL-qZ.js → insights-CzrtkpOE.js} +2 -2
- package/public/assets/{integrations-C5Oix6ng.js → integrations-aVsUmigt.js} +2 -2
- package/public/assets/{issue-ref-chip-ODyondIa.js → issue-ref-chip-BnSlM_95.js} +2 -2
- package/public/assets/{log-viewer-Cvfy6PW7.js → log-viewer-qe7Ee47Z.js} +2 -2
- package/public/assets/{maintenance-D8CDH5wZ.js → maintenance-NfjqFZAk.js} +2 -2
- package/public/assets/{managed-agents-egllbpij.js → managed-agents-BiH0HgaE.js} +2 -2
- package/public/assets/{markdown-preview-CYSFgVgK.js → markdown-preview-BixaT3Xr.js} +3 -3
- package/public/assets/{markdown-preview-impl-BteVIjX4.js → markdown-preview-impl-DNGlWIS3.js} +2 -2
- package/public/assets/{memory-C8WmXsyr.js → memory-DNsCl6UX.js} +2 -2
- package/public/assets/{messages-BzQdqlO6.js → messages-DopU1L1X.js} +2 -2
- package/public/assets/{orchestrators-B1HxzkNw.js → orchestrators-Cq7ckLQT.js} +2 -2
- package/public/assets/{overview-DCUnI4Z7.js → overview-C1DCTzzV.js} +2 -2
- package/public/assets/{pairs-ftCd2XcD.js → pairs-DE_m6rrE.js} +2 -2
- package/public/assets/{profile-icon-B2zH8DMH.js → profile-icon-B3rfh77F.js} +2 -2
- package/public/assets/project-profile-instructions-DQWZE0kA.js +2 -0
- package/public/assets/projects-Br2Bd2h1.js +2 -0
- package/public/assets/{prompt-settings-Bftq9czX.js → prompt-settings-BKvFsvGD.js} +2 -2
- package/public/assets/provider-display-DsuWMvVL.js +2 -0
- package/public/assets/{registry-DWCU5c8q.js → registry-Cw38_6gW.js} +2 -2
- package/public/assets/run-card-CpKqRbhg.js +2 -0
- package/public/assets/scroll-text-BKXS1ahr.js +2 -0
- package/public/assets/{secrets-C7GIUATz.js → secrets-DxI-vzSq.js} +2 -2
- package/public/assets/{service-access-settings-C3aujqTG.js → service-access-settings-D9s_VJbd.js} +2 -2
- package/public/assets/{settings-C6sZ9eBa.js → settings-CKZTVGIx.js} +2 -2
- package/public/assets/{shipping-Bu8p1gEw.js → shipping-B9YtnwtG.js} +2 -2
- package/public/assets/{stats-V9Z-GxUd.js → stats-DyUBKyWI.js} +2 -2
- package/public/assets/{status-dot-CVv0iGHL.js → status-dot-DYqlEUhJ.js} +2 -2
- package/public/assets/{store-BvtFdlGX.js → store-DcClXLH0.js} +3 -3
- package/public/assets/{tasks-CXU75HRF.js → tasks-Bh7Chr4-.js} +2 -2
- package/public/assets/{teams-BPf976zb.js → teams-bowI7qVY.js} +2 -2
- package/public/assets/{terminal-viewer-DE9BOe-8.js → terminal-viewer-BgVLHdsU.js} +3 -3
- package/public/assets/{terminal-viewer-impl-D04pjmGh.js → terminal-viewer-impl-Dz22UPy6.js} +2 -2
- package/public/assets/token-estimate-Co-Jdphh.js +2 -0
- package/public/assets/{use-agent-terminal-B1yR456R.js → use-agent-terminal-DSQQ-iY7.js} +2 -2
- package/public/assets/{use-decisions-D-S4tpDf.js → use-decisions-samMQhQf.js} +2 -2
- package/public/assets/use-project-list-59LheVP7.js +2 -0
- package/public/assets/{use-selectors-CnrAk2YP.js → use-selectors-BZa25xEB.js} +2 -2
- package/public/assets/{user-avatar-nBFIcR4M.js → user-avatar-DHxlvUvV.js} +2 -2
- package/public/assets/versioned-prompt-editor-BmED5DnJ.js +8 -0
- package/public/assets/{work-queue-TCjJxeT-.js → work-queue-CSvpuNLz.js} +2 -2
- package/public/assets/{workflow-marker-Cf3Hf2fN.js → workflow-marker-DAZcj5qt.js} +2 -2
- package/public/assets/{workflows-CXQX20Qj.js → workflows-DdmxRSyg.js} +2 -2
- package/public/assets/{workspaces-qSYzKYMA.js → workspaces-BxeKfVuF.js} +2 -2
- package/public/cosmos.html +4 -4
- package/public/index.html +31 -29
- package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/runner/plugins/claude/hooks/gate-run-guard.provisioned.mjs +31 -1
- package/runner/src/adapters/claude-effort.ts +2 -4
- package/runner/src/adapters/codex-launch-config.ts +4 -5
- package/runner/src/adapters/codex.ts +1 -1
- package/runner/src/adapters/opencode-provider.ts +7 -22
- package/runner/src/adapters/opencode.ts +4 -4
- package/runner/src/agent-runner/credentials.ts +42 -12
- package/runner/src/agent-runner/inbox.ts +27 -0
- package/runner/src/agent-runner/lifecycle-milestones.ts +0 -2
- package/runner/src/bin/claude.ts +4 -0
- package/runner/src/bin/codex.ts +4 -0
- package/runner/src/bin/opencode.ts +4 -0
- package/runner/src/index.ts +5 -2
- package/runner/src/provider-setup.ts +34 -0
- package/runner/src/providers.ts +2 -1
- package/runner/src/runner-core.ts +18 -23
- package/runner/src/spawn-input.ts +2 -1
- package/runner/src/test-run-dedup.ts +59 -56
- package/scripts/cd-config.ts +8 -0
- package/scripts/gate-run-lease.ts +10 -7
- package/scripts/gate.sh +5 -1
- package/src/branch-land-notice.ts +93 -0
- package/src/branch-landed.ts +7 -76
- package/src/bus.ts +19 -20
- package/src/cd-deploy-notify.ts +30 -2
- package/src/cd-host-lag-notify.ts +7 -6
- package/src/ci/incidents.ts +2 -2
- package/src/ci/monitor.ts +5 -8
- package/src/ci/root-missing.ts +2 -7
- package/src/ci/transition-notify.ts +7 -39
- package/src/cli/cd-pauses.ts +19 -0
- package/src/cli/orchestrator.ts +1 -1
- package/src/cli/state.ts +2 -19
- package/src/cli/task-edit.ts +22 -0
- package/src/cli/task.ts +3 -1
- package/src/cli/workflow.ts +8 -2
- package/src/commands-db.ts +3 -3
- package/src/config-store-write.ts +13 -1
- package/src/config-store.ts +25 -14
- package/src/db/activity-async.ts +6 -1
- package/src/db/activity-write-ops.ts +12 -1
- package/src/db/activity.ts +1 -14
- package/src/db/agent-search.ts +1 -15
- package/src/db/agents-async.ts +52 -5
- package/src/db/agents-write-ops.ts +12 -3
- package/src/db/agents.ts +81 -54
- package/src/db/ci-incidents-async.ts +5 -5
- package/src/db/ci-incidents-write-ops.ts +2 -2
- package/src/db/command-row.ts +10 -2
- package/src/db/commands-list-query.ts +2 -0
- package/src/db/commands-spawn-read.ts +1 -1
- package/src/db/config-store-write-ops.ts +7 -2
- package/src/db/continuation-archives-async.ts +5 -0
- package/src/db/continuation-archives-write-ops.ts +7 -0
- package/src/db/continuations.ts +2 -2
- package/src/db/db-writer-worker.ts +8 -1
- package/src/db/deploy-events-async.ts +1 -0
- package/src/db/deploy-events-read-ops.ts +2 -1
- package/src/db/deploy-events.ts +35 -4
- package/src/db/hosts-registration.ts +10 -2
- package/src/db/hosts.ts +9 -6
- package/src/db/inbox.ts +0 -14
- package/src/db/index.ts +2 -0
- package/src/db/integrations-async.ts +8 -0
- package/src/db/integrations-ops.ts +15 -0
- package/src/db/integrations.ts +15 -21
- package/src/db/issue-lifecycle.ts +3 -4
- package/src/db/issue-refs-async.ts +20 -0
- package/src/db/issue-refs-write-ops.ts +29 -0
- package/src/db/issue-refs.ts +7 -8
- package/src/db/long-running-work.ts +2 -2
- package/src/db/main-connection-writes.ts +23 -2
- package/src/db/maintenance-job-reconcile.ts +61 -0
- package/src/db/maintenance-job-runs-async.ts +14 -0
- package/src/db/maintenance-job-write-ops.ts +9 -0
- package/src/db/mappers.ts +2 -14
- package/src/db/merge-lease.ts +1 -15
- package/src/db/migrations.ts +7 -15
- package/src/db/orchestrators.ts +4 -72
- package/src/db/pairs.ts +1 -13
- package/src/db/project-profile-instructions.ts +50 -0
- package/src/db/prompt-versions.ts +9 -2
- package/src/db/provider-config-history.ts +8 -3
- package/src/db/provider-model-seed.ts +34 -0
- package/src/db/read-op-marshaling-fixtures.ts +5 -0
- package/src/db/read-ops.ts +4 -0
- package/src/db/routing-policy.ts +2 -3
- package/src/db/schema.ts +9 -3
- package/src/db/spawn-delegation-state.ts +11 -4
- package/src/db/stats-async.ts +4 -3
- package/src/db/task-entity.ts +23 -2
- package/src/db/task-list.ts +3 -1
- package/src/db/tasks.ts +1 -17
- package/src/db/timer-ingress.ts +7 -1
- package/src/db/token-db-write-ops.ts +17 -0
- package/src/db/token-standing.ts +15 -11
- package/src/db/workflow-contact.ts +1 -1
- package/src/db/workflow-task-read-ops.ts +30 -0
- package/src/db/write-ops.ts +6 -0
- package/src/db/writer-gateway.ts +17 -11
- package/src/dispatch-availability.ts +10 -6
- package/src/ephemeral/{landing-ingress-proof-worker.ts → landing-ingress-proof.test-fixture.ts} +4 -2
- package/src/host/disk-alert.ts +121 -0
- package/src/lifecycle-manager.ts +3 -2
- package/src/maintenance/cd-watcher.ts +3 -3
- package/src/maintenance/critical-job-watchdog.ts +16 -17
- package/src/maintenance/index.ts +1 -0
- package/src/maintenance/jobs.ts +3 -2
- package/src/maintenance/scheduler.ts +84 -128
- package/src/maintenance/stalled-delivery-pager.ts +6 -5
- package/src/maintenance/workspaces.ts +1 -1
- package/src/managed-policy.ts +31 -27
- package/src/mcp/index.ts +5 -2
- package/src/mcp/output-descriptions.ts +8 -8
- package/src/mcp/presentation.ts +4 -4
- package/src/mcp/project-profile-instructions.ts +32 -0
- package/src/mcp/tool-groups.ts +1 -1
- package/src/mcp/tools-spawn.ts +4 -3
- package/src/mcp-agent-action.ts +1 -2
- package/src/mcp-issue-ref-tools.ts +12 -11
- package/src/mcp-maintenance-tools.ts +2 -2
- package/src/mcp-profile-trust-tools.ts +4 -4
- package/src/mcp-provider-catalog.ts +2 -2
- package/src/mcp-task-tools.ts +11 -5
- package/src/mcp-team-template-tools.ts +3 -3
- package/src/mcp-workflow-tools.ts +10 -3
- package/src/notification-types.ts +2 -1
- package/src/operator-alarm.ts +26 -11
- package/src/project-instructions.ts +4 -0
- package/src/project-profile-instruction-text.ts +6 -0
- package/src/project-profile-instructions.ts +20 -0
- package/src/provider-catalog-store.ts +3 -49
- package/src/provider-config-store.ts +12 -11
- package/src/provider-model-seed.ts +1 -18
- package/src/provider-quota-config-store.ts +5 -4
- package/src/provider-secrets.test-fixture.ts +3 -3
- package/src/recipe-runner.ts +2 -2
- package/src/repo-config-source.ts +10 -4
- package/src/routes/agent-profiles.ts +6 -6
- package/src/routes/agents-spawn.ts +1 -1
- package/src/routes/agents.ts +6 -6
- package/src/routes/commands-listing.ts +4 -0
- package/src/routes/commands.ts +2 -2
- package/src/routes/continuation-archives.ts +2 -2
- package/src/routes/index.ts +10 -1
- package/src/routes/integrations.ts +24 -50
- package/src/routes/issue-refs.ts +7 -7
- package/src/routes/orchestrator-bootstrap.ts +1 -1
- package/src/routes/orchestrator-host-registration.ts +2 -2
- package/src/routes/orchestrator-host-utilization.ts +3 -1
- package/src/routes/orchestrator-proxy.ts +2 -2
- package/src/routes/orchestrator.ts +2 -2
- package/src/routes/project-profile-instructions.ts +27 -0
- package/src/routes/project-trust.ts +2 -2
- package/src/routes/provider-config.ts +6 -6
- package/src/routes/provider-quota-config.ts +2 -2
- package/src/routes/settings.ts +5 -5
- package/src/routes/stats.ts +6 -6
- package/src/routes/task-http.ts +15 -1
- package/src/routes/task-issues.ts +11 -26
- package/src/routes/tasks.ts +22 -53
- package/src/routes/team-templates.ts +5 -5
- package/src/routes/teams-config.ts +2 -2
- package/src/routes/tokens.ts +12 -5
- package/src/routes/workflows.ts +20 -5
- package/src/routing-policy-normalize.ts +1 -2
- package/src/routing-step-defaults.ts +0 -2
- package/src/runner-token-mint-limit.ts +63 -0
- package/src/runtime-grant.ts +4 -2
- package/src/runtime-tokens.ts +39 -7
- package/src/security.ts +13 -20
- package/src/server-background.ts +1 -1
- package/src/server.ts +5 -2
- package/src/services/host-utilization.ts +23 -0
- package/src/services/idle-epics.ts +5 -6
- package/src/services/issue-lifecycle.ts +57 -61
- package/src/services/issue-refs.ts +9 -13
- package/src/services/kernel-timers-cutover-chaos-worker.ts +10 -7
- package/src/services/kernel-timers-ingress.ts +1 -1
- package/src/services/landed-ancestry.ts +19 -3
- package/src/services/memory-areas.ts +15 -51
- package/src/services/plan-ci-notice.ts +57 -0
- package/src/services/plan-ci-recovery.ts +2 -55
- package/src/services/plan-wake-digest.ts +1 -0
- package/src/services/profile-trust.ts +4 -3
- package/src/services/project-config-read.ts +70 -0
- package/src/services/project-profile-instructions.ts +54 -0
- package/src/services/provisioning-harness/budget-baseline.json +4 -4
- package/src/services/restart-spawn.ts +61 -49
- package/src/services/self-care-state.ts +2 -1
- package/src/services/self-effort.ts +5 -5
- package/src/services/send-message.ts +5 -1
- package/src/services/spawn-agent.ts +13 -2
- package/src/services/spawn-chain-inspector.ts +6 -13
- package/src/services/spawn-policy.ts +68 -0
- package/src/services/spawn-tree-cleanup.ts +2 -2
- package/src/services/task-dispatch.ts +3 -0
- package/src/services/task-state-reconcile.ts +6 -14
- package/src/services/team-templates.ts +9 -8
- package/src/services/transient-agent-reaper.ts +3 -1
- package/src/services/workflow-auto-start.ts +25 -13
- package/src/services/workflow-ci-main.ts +1 -1
- package/src/services/workflow-deferred-cleanup.ts +4 -2
- package/src/services/workflow-effect-driver.ts +2 -0
- package/src/services/workflow-effects.ts +18 -11
- package/src/services/workflow-land-notice.ts +10 -0
- package/src/services/workflow-pause-text.ts +43 -0
- package/src/services/workflow-reconcile.ts +13 -11
- package/src/services/workflow-run-view.ts +2 -0
- package/src/services/workflow-runs.ts +29 -13
- package/src/services/workflow-supervisor-state.ts +5 -0
- package/src/services/workflow-supervisor.ts +7 -3
- package/src/settings/registry.ts +1 -2
- package/src/spawn-command.ts +4 -4
- package/src/spawn-models.ts +10 -12
- package/src/spawn-placement.ts +1 -1
- package/src/spawn-targets.ts +1 -1
- package/src/startup-context-injection.ts +1 -0
- package/src/state-adoption/cd-cutover.ts +53 -7
- package/src/state-adoption/fleet-cutover.ts +35 -0
- package/src/state-adoption/fleet-plan.ts +36 -0
- package/src/state-adoption/index.ts +2 -2
- package/src/state-adoption/linux-plan.ts +2 -2
- package/src/state-adoption/linux.ts +2 -2
- package/src/state-adoption/macos-plan.ts +2 -2
- package/src/state-adoption/macos.ts +1 -1
- package/src/steward.ts +7 -6
- package/src/task-dispatch-live.ts +1 -1
- package/src/task-dispatcher.ts +1 -1
- package/src/teams-config-store.ts +4 -3
- package/src/token-db-write.ts +10 -0
- package/src/workspace-command-settle.ts +2 -1
- package/src/workspace-steward-wake.ts +2 -2
- package/node_modules/@humwick/kernel/LICENSE +0 -167
- package/node_modules/@humwick/kernel/async-entity-persistence.ts +0 -344
- package/node_modules/@humwick/kernel/async-event-log.ts +0 -107
- package/node_modules/@humwick/kernel/automations.pilot.ts +0 -147
- package/node_modules/@humwick/kernel/config.ts +0 -111
- package/node_modules/@humwick/kernel/contract.ts +0 -572
- package/node_modules/@humwick/kernel/control-authz.ts +0 -281
- package/node_modules/@humwick/kernel/control.ts +0 -645
- package/node_modules/@humwick/kernel/effects.ts +0 -493
- package/node_modules/@humwick/kernel/event-log.ts +0 -319
- package/node_modules/@humwick/kernel/http-transport.ts +0 -384
- package/node_modules/@humwick/kernel/identity-grammar.ts +0 -20
- package/node_modules/@humwick/kernel/identity.ts +0 -248
- package/node_modules/@humwick/kernel/index.ts +0 -28
- package/node_modules/@humwick/kernel/kernel-persistence.ts +0 -181
- package/node_modules/@humwick/kernel/landing-incident.ts +0 -306
- package/node_modules/@humwick/kernel/landing.ts +0 -953
- package/node_modules/@humwick/kernel/manifest-validation.ts +0 -460
- package/node_modules/@humwick/kernel/mcp-transport.ts +0 -109
- package/node_modules/@humwick/kernel/message-authority-chaos-worker.ts +0 -200
- package/node_modules/@humwick/kernel/message-authority.ts +0 -281
- package/node_modules/@humwick/kernel/module-host.ts +0 -722
- package/node_modules/@humwick/kernel/openapi-init.ts +0 -14
- package/node_modules/@humwick/kernel/package.json +0 -39
- package/node_modules/@humwick/kernel/persistence-schema.ts +0 -248
- package/node_modules/@humwick/kernel/persistence.ts +0 -510
- package/node_modules/@humwick/kernel/registry.ts +0 -60
- package/node_modules/@humwick/kernel/sqlite-kernel-persistence.ts +0 -499
- package/node_modules/@humwick/kernel/sqlite-module-host.ts +0 -87
- package/node_modules/@humwick/kernel/timers-chaos-worker.ts +0 -186
- package/node_modules/@humwick/kernel/timers.pilot.ts +0 -1411
- package/node_modules/@humwick/kernel/workflow-activation.ts +0 -25
- package/node_modules/@humwick/kernel/workflow-backstop.ts +0 -40
- package/node_modules/@humwick/kernel/workflow-cancel-tree.ts +0 -20
- package/node_modules/@humwick/kernel/workflow-chaos-worker.ts +0 -213
- package/node_modules/@humwick/kernel/workflow-composition.ts +0 -231
- package/node_modules/@humwick/kernel/workflow-container.ts +0 -72
- package/node_modules/@humwick/kernel/workflow-control.test-fixture.ts +0 -42
- package/node_modules/@humwick/kernel/workflow-control.ts +0 -178
- package/node_modules/@humwick/kernel/workflow-definition.ts +0 -507
- package/node_modules/@humwick/kernel/workflow-dispatch.ts +0 -60
- package/node_modules/@humwick/kernel/workflow-foreach.ts +0 -167
- package/node_modules/@humwick/kernel/workflow-journal-codec.ts +0 -339
- package/node_modules/@humwick/kernel/workflow-journal.ts +0 -922
- package/node_modules/@humwick/kernel/workflow-lane.ts +0 -48
- package/node_modules/@humwick/kernel/workflow-lease-owner.ts +0 -60
- package/node_modules/@humwick/kernel/workflow-recovery.test-fixture.ts +0 -19
- package/node_modules/@humwick/kernel/workflow-runtime.ts +0 -938
- package/node_modules/@humwick/kernel/workflow-script.ts +0 -11
- package/node_modules/@humwick/kernel/workflow-state.ts +0 -299
- package/node_modules/@humwick/kernel/workflow-step-commit.ts +0 -195
- package/node_modules/@humwick/kernel/workflow-transitions.ts +0 -317
- package/node_modules/@humwick/kernel/workflow-values.ts +0 -153
- package/node_modules/@humwick/kernel/workflow.pilot.ts +0 -376
- package/node_modules/@humwick/offload/LICENSE +0 -167
- package/node_modules/@humwick/offload/README.md +0 -57
- package/node_modules/@humwick/offload/dist/async-runner.d.ts +0 -18
- package/node_modules/@humwick/offload/dist/async-runner.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/async-runner.js +0 -158
- package/node_modules/@humwick/offload/dist/async-runner.js.map +0 -1
- package/node_modules/@humwick/offload/dist/envelope.d.ts +0 -25
- package/node_modules/@humwick/offload/dist/envelope.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/envelope.js +0 -80
- package/node_modules/@humwick/offload/dist/envelope.js.map +0 -1
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts +0 -10
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.js +0 -59
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.js.map +0 -1
- package/node_modules/@humwick/offload/dist/index.d.ts +0 -5
- package/node_modules/@humwick/offload/dist/index.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/index.js +0 -5
- package/node_modules/@humwick/offload/dist/index.js.map +0 -1
- package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts +0 -62
- package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/subprocess-runner.js +0 -295
- package/node_modules/@humwick/offload/dist/subprocess-runner.js.map +0 -1
- package/node_modules/@humwick/offload/dist/types.d.ts +0 -111
- package/node_modules/@humwick/offload/dist/types.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/types.js +0 -176
- package/node_modules/@humwick/offload/dist/types.js.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-pool.d.ts +0 -23
- package/node_modules/@humwick/offload/dist/worker-pool.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-pool.js +0 -435
- package/node_modules/@humwick/offload/dist/worker-pool.js.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-runtime.d.ts +0 -2
- package/node_modules/@humwick/offload/dist/worker-runtime.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-runtime.js +0 -27
- package/node_modules/@humwick/offload/dist/worker-runtime.js.map +0 -1
- package/node_modules/@humwick/offload/dist/worker.d.ts +0 -5
- package/node_modules/@humwick/offload/dist/worker.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/worker.js +0 -1
- package/node_modules/@humwick/offload/dist/worker.js.map +0 -1
- package/node_modules/@humwick/offload/package.json +0 -42
- package/node_modules/@humwick/offload/src/async-runner.ts +0 -170
- package/node_modules/@humwick/offload/src/envelope.ts +0 -92
- package/node_modules/@humwick/offload/src/fixtures/worker-task.ts +0 -49
- package/node_modules/@humwick/offload/src/index.ts +0 -4
- package/node_modules/@humwick/offload/src/subprocess-runner.ts +0 -334
- package/node_modules/@humwick/offload/src/types.ts +0 -235
- package/node_modules/@humwick/offload/src/worker-pool.ts +0 -463
- package/node_modules/@humwick/offload/src/worker-runtime.ts +0 -32
- package/node_modules/@humwick/offload/src/worker.ts +0 -5
- package/public/assets/agent-liveness-DyqxfB-t.js +0 -2
- package/public/assets/agent-profiles-BpI_jTxq.js +0 -2
- package/public/assets/index-B7ZerHLY.css +0 -2
- package/public/assets/index-BU3uWo2t.js +0 -15
- package/public/assets/projects-B_lmcqfO.js +0 -2
- package/public/assets/provider-display-DbLWpP3j.js +0 -2
- package/public/assets/run-card-CO_bguQf.js +0 -2
- package/public/assets/use-project-list-B-T2Bnnn.js +0 -2
- package/public/assets/versioned-prompt-editor-Diu8BIaM.js +0 -8
- package/runner/src/gate-run-lease-probe.ts +0 -38
- package/src/db/claude-catalog-reconcile.ts +0 -27
- package/src/routing-model-aliases.ts +0 -21
|
@@ -4,7 +4,8 @@ import { hostname } from "node:os";
|
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { ValidationError, listOrchestrators } from "./db";
|
|
6
6
|
import { isSecretEnvKey } from "./db/provider-config-secrets";
|
|
7
|
-
import { getConfig, listConfig
|
|
7
|
+
import { getConfig, listConfig } from "./config-store";
|
|
8
|
+
import { setConfigAsync } from "./config-store-write";
|
|
8
9
|
import { localOrchestratorIdFromEnv, providerConfigHomeFromEnv } from "./config";
|
|
9
10
|
import { cleanString, cleanStringArray, optionalEnum } from "./validation";
|
|
10
11
|
import { emitConfigChanged } from "./sse";
|
|
@@ -90,11 +91,11 @@ export function listProviderConfigEntries(host = defaultProviderConfigHost()): R
|
|
|
90
91
|
) as Record<SpawnProvider, ProviderConfigEntry>;
|
|
91
92
|
}
|
|
92
93
|
|
|
93
|
-
export function
|
|
94
|
+
export async function setProviderConfigAsync(
|
|
94
95
|
provider: string,
|
|
95
96
|
value: unknown,
|
|
96
97
|
opts: { host?: string; updatedBy?: string } = {},
|
|
97
|
-
): ProviderConfigEntry {
|
|
98
|
+
): Promise<ProviderConfigEntry> {
|
|
98
99
|
const cleanProvider = normalizeProviderConfigProvider(provider);
|
|
99
100
|
const host = normalizeProviderConfigHost(opts.host ?? defaultProviderConfigHost());
|
|
100
101
|
const normalized = cleanProviderConfig(cleanProvider, resolveMaskedEnvSentinels(value, host, cleanProvider));
|
|
@@ -102,7 +103,7 @@ export function setProviderConfig(
|
|
|
102
103
|
ensureProviderConfigDescriptors([key]);
|
|
103
104
|
const validation = validateSettingValue(PROVIDER_CONFIG_NAMESPACE, key, normalized);
|
|
104
105
|
if (!validation.valid) throw new ValidationError(validation.errors.join("; "));
|
|
105
|
-
return
|
|
106
|
+
return await setConfigAsync(PROVIDER_CONFIG_NAMESPACE, key, normalized, opts.updatedBy) as ProviderConfigEntry;
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
export function providerConfigPublic(entry: ProviderConfigEntry, opts: { maskEnv?: boolean } = {}): Record<string, unknown> {
|
|
@@ -138,11 +139,11 @@ export function providerConfigPublic(entry: ProviderConfigEntry, opts: { maskEnv
|
|
|
138
139
|
* This is the server-authority write path: callers are in-process (local migration
|
|
139
140
|
* or the orchestrator command-bus result handler), so no HTTP scope is required.
|
|
140
141
|
*/
|
|
141
|
-
export function
|
|
142
|
+
export async function seedProviderConfigsAsync(
|
|
142
143
|
host: string,
|
|
143
144
|
rawByProvider: Record<string, unknown>,
|
|
144
145
|
opts: { legacyHost?: string } = {},
|
|
145
|
-
): ProviderConfigEntry[] {
|
|
146
|
+
): Promise<ProviderConfigEntry[]> {
|
|
146
147
|
const seeded: ProviderConfigEntry[] = [];
|
|
147
148
|
const cleanHost = normalizeProviderConfigHost(host);
|
|
148
149
|
const legacyHost = opts.legacyHost ? normalizeProviderConfigHost(opts.legacyHost) : undefined;
|
|
@@ -159,7 +160,7 @@ export function seedProviderConfigs(
|
|
|
159
160
|
// still validates; the relay owns the schema, the reporter stays dumb.
|
|
160
161
|
const value = legacy?.value ?? { ...providerConfigDefaults(provider), ...(isRecord(raw) ? raw : {}) };
|
|
161
162
|
try {
|
|
162
|
-
const entry =
|
|
163
|
+
const entry = await setProviderConfigAsync(provider, value, { host: cleanHost, updatedBy: `migration:${cleanHost}` });
|
|
163
164
|
emitConfigChanged(entry.namespace, entry.key, entry.version);
|
|
164
165
|
seeded.push(entry);
|
|
165
166
|
} catch {
|
|
@@ -174,16 +175,16 @@ export function seedProviderConfigs(
|
|
|
174
175
|
* owns the stable-id/legacy-hostname resolution together so command routes do
|
|
175
176
|
* not re-parse or accidentally bypass the migration authority rules.
|
|
176
177
|
*/
|
|
177
|
-
export function
|
|
178
|
+
export async function seedMigratedProviderConfigsAsync(result: unknown): Promise<{ host: string; seeded: ProviderConfigEntry[] } | null> {
|
|
178
179
|
if (!isRecord(result)) return null;
|
|
179
180
|
const host = cleanString(result.host, "result.host", { max: 120 });
|
|
180
181
|
const hostname = cleanString(result.hostname, "result.hostname", { max: 120 });
|
|
181
182
|
const configs = isRecord(result.configs) ? result.configs : undefined;
|
|
182
183
|
if (!host || !configs) return null;
|
|
183
|
-
return { host, seeded:
|
|
184
|
+
return { host, seeded: await seedProviderConfigsAsync(host, configs, { legacyHost: hostname }) };
|
|
184
185
|
}
|
|
185
186
|
|
|
186
|
-
export function
|
|
187
|
+
export async function migrateLocalProviderConfigsAsync(home = humwickHome(), host = defaultProviderConfigHost()): Promise<ProviderConfigEntry[]> {
|
|
187
188
|
const dir = join(home, "providers");
|
|
188
189
|
if (!existsSync(dir)) return [];
|
|
189
190
|
const raw: Record<string, unknown> = {};
|
|
@@ -192,7 +193,7 @@ export function migrateLocalProviderConfigs(home = humwickHome(), host = default
|
|
|
192
193
|
if (!VALID_PROVIDER_CONFIGS.includes(provider as SpawnProvider)) continue;
|
|
193
194
|
raw[provider] = loadLocalProviderConfig(provider, home);
|
|
194
195
|
}
|
|
195
|
-
return
|
|
196
|
+
return seedProviderConfigsAsync(host, raw);
|
|
196
197
|
}
|
|
197
198
|
|
|
198
199
|
function normalizeProviderConfigHost(host: string): string {
|
|
@@ -1,18 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { seedProviderModelOverrides } from "./provider-catalog-store";
|
|
3
|
-
import { reconcileClaudeCatalogSeeds } from "./db/claude-catalog-reconcile";
|
|
4
|
-
import { VERSION } from "./config";
|
|
5
|
-
import { errMessage } from "@humwick/sdk";
|
|
6
|
-
|
|
7
|
-
// Stamp only after the transactional seed succeeds so a failure retries next boot.
|
|
8
|
-
export function reconcileProviderModelSeed(): void {
|
|
9
|
-
try {
|
|
10
|
-
reconcileClaudeCatalogSeeds();
|
|
11
|
-
const stamp = `seed:${VERSION}`;
|
|
12
|
-
if (getConfig<string>("system", "provider-model-seed-version")?.value === stamp) return;
|
|
13
|
-
seedProviderModelOverrides(stamp);
|
|
14
|
-
setConfig("system", "provider-model-seed-version", stamp, "server-startup");
|
|
15
|
-
} catch (err) {
|
|
16
|
-
console.warn(`[provider-model-seed] skipped: ${errMessage(err)}`);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
1
|
+
export { reconcileProviderModelSeed, seedProviderModelOverrides } from "./db/provider-model-seed";
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
// provider *spawn* config (provider-config-store.ts) by design — different scope,
|
|
10
10
|
// different cardinality.
|
|
11
11
|
import { ValidationError } from "./db";
|
|
12
|
-
import { getConfig, listConfig
|
|
12
|
+
import { getConfig, listConfig } from "./config-store";
|
|
13
|
+
import { setConfigAsync } from "./config-store-write";
|
|
13
14
|
import { emitConfigChanged } from "./sse";
|
|
14
15
|
import {
|
|
15
16
|
DEFAULT_PROVIDER_QUOTA_CONFIG,
|
|
@@ -47,14 +48,14 @@ export function listProviderQuotaConfigs(): ProviderQuotaConfigMap {
|
|
|
47
48
|
* clamped to 5m–15m, unset fields defaulted), so a partial body still validates.
|
|
48
49
|
* Emits `config.changed` so the orchestrator + dashboard pick it up live.
|
|
49
50
|
*/
|
|
50
|
-
export function
|
|
51
|
+
export async function setProviderQuotaConfigAsync(
|
|
51
52
|
provider: string,
|
|
52
53
|
value: unknown,
|
|
53
54
|
opts: { updatedBy?: string } = {},
|
|
54
|
-
): ProviderQuotaConfig {
|
|
55
|
+
): Promise<ProviderQuotaConfig> {
|
|
55
56
|
const clean = assertValidProvider(provider);
|
|
56
57
|
const normalized = normalizeProviderQuotaConfig(value);
|
|
57
|
-
const entry =
|
|
58
|
+
const entry = await setConfigAsync(PROVIDER_QUOTA_CONFIG_NAMESPACE, clean, normalized, opts.updatedBy);
|
|
58
59
|
emitConfigChanged(entry.namespace, entry.key, entry.version);
|
|
59
60
|
return normalized;
|
|
60
61
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getDb } from "./db";
|
|
2
|
-
import {
|
|
2
|
+
import { setProviderConfigAsync } from "./provider-config-store";
|
|
3
3
|
|
|
4
4
|
// #3402 — fake values under every key name the hub's central provider config holds, plus one no masking
|
|
5
5
|
// list knows, so a test proves masking follows the configured values rather than key names.
|
|
@@ -25,9 +25,9 @@ export function leakedProviderSecrets(text: string): string[] {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
/** Seeds the central provider config of `host` and returns its rows the way `sqlite3 ... select` prints them. */
|
|
28
|
-
export function seedProviderSecrets(host: string): string {
|
|
28
|
+
export async function seedProviderSecrets(host: string): Promise<string> {
|
|
29
29
|
for (const [provider, env] of Object.entries(PROVIDER_SECRET_ENV)) {
|
|
30
|
-
|
|
30
|
+
await setProviderConfigAsync(provider, { command: provider, env: { ...env, OPENCODE_CONFIG: "/srv/opencode.json" } }, { host });
|
|
31
31
|
}
|
|
32
32
|
return (getDb().query("SELECT namespace, key, value FROM config WHERE namespace = 'provider-config'").all() as Array<Record<string, string>>)
|
|
33
33
|
.map((row) => `${row.namespace}|${row.key}|${row.value}`).join("\n");
|
package/src/recipe-runner.ts
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
validateRecipeArtifactRefsAsync,
|
|
16
16
|
} from "./recipe-async";
|
|
17
17
|
import type { AttachmentRef, Command, RecipeInstance } from "./types";
|
|
18
|
-
import { SYSTEM_LAUNCH,
|
|
18
|
+
import { SYSTEM_LAUNCH, runnerRuntimeTokenEnvAsync } from "./runtime-tokens";
|
|
19
19
|
import { generateSpawnAgentId } from "./services/spawn-identity";
|
|
20
20
|
|
|
21
21
|
interface StartRecipeInput {
|
|
@@ -114,7 +114,7 @@ export async function startRecipe(input: StartRecipeInput): Promise<StartRecipeR
|
|
|
114
114
|
env: {
|
|
115
115
|
...(agent.env ?? {}),
|
|
116
116
|
...(attachments.length ? writeChildEnv({}, { AGENT_RELAY_RECIPE_ARTIFACTS: JSON.stringify(attachments) }) : {}),
|
|
117
|
-
...
|
|
117
|
+
...await runnerRuntimeTokenEnvAsync({ authority: SYSTEM_LAUNCH,
|
|
118
118
|
agentId,
|
|
119
119
|
orchestratorId: orchestrator.id,
|
|
120
120
|
cwd,
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
import { dirname, resolve } from "node:path";
|
|
7
7
|
import { isRecord, stringValue } from "@humwick/sdk";
|
|
8
8
|
import { isTrustedOrchestratorApiUrl, relayAuthHeaders } from "./config";
|
|
9
|
-
import { getConfig
|
|
9
|
+
import { getConfig } from "./config-store";
|
|
10
|
+
import { setConfigAsync } from "./config-store-write";
|
|
10
11
|
import { listOrchestrators, reportedRepoRootForCwd } from "./db";
|
|
11
12
|
import { hostIsRelayHost } from "./relay-host-locality";
|
|
12
13
|
import { normalizeHostToken, parseJson, sameHostIdentity } from "./utils";
|
|
@@ -70,11 +71,16 @@ export function hostRepoConfigSource<T>(spec: HostRepoConfigSpec<T>): HostRepoCo
|
|
|
70
71
|
return null;
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
/** #1870 S7: writes on the writer thread, and only when the answer changed. `at` is evidence, not a
|
|
75
|
+
* TTL, so re-stamping an identical answer on every read only bumped the version and history. */
|
|
76
|
+
async function writeCached(host: string, keys: readonly string[], found: RepoConfigSource<T> | null): Promise<void> {
|
|
74
77
|
const at = Date.now();
|
|
78
|
+
const answer = JSON.stringify(found);
|
|
75
79
|
for (const key of keys) {
|
|
76
80
|
try {
|
|
77
|
-
|
|
81
|
+
const current = getConfig<CachedRepoConfigSource<T>>(spec.cacheNamespace, cacheKey(host, key))?.value;
|
|
82
|
+
if (current?.at && JSON.stringify(current.found) === answer) continue;
|
|
83
|
+
await setConfigAsync<CachedRepoConfigSource<T>>(spec.cacheNamespace, cacheKey(host, key), { found, at }, spec.cacheNamespace);
|
|
78
84
|
} catch {
|
|
79
85
|
// The cache is an optimization for the sync paths; failing to record it must never fail a caller.
|
|
80
86
|
}
|
|
@@ -149,7 +155,7 @@ export function hostRepoConfigSource<T>(spec: HostRepoConfigSpec<T>): HostRepoCo
|
|
|
149
155
|
if (hostIsRelayHost(host)) return { known: true, found: await spec.findLocalAsync(cwd) };
|
|
150
156
|
const read = await readFromHost(cwd, host!);
|
|
151
157
|
if (read.known) {
|
|
152
|
-
writeCached(host!, cacheWriteKeys(cwd, read.found, opts.alsoCacheFor), read.found);
|
|
158
|
+
await writeCached(host!, cacheWriteKeys(cwd, read.found, opts.alsoCacheFor), read.found);
|
|
153
159
|
return read;
|
|
154
160
|
}
|
|
155
161
|
return cachedLookup(host!, cwd);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { PromptVersionConflictError } from "../prompt-version-errors";
|
|
2
2
|
import { versionedPromptsEnabled } from "../versioned-prompts";
|
|
3
3
|
import { promptActor } from "../services/prompt-version-writer";
|
|
4
|
-
import { setConfigAsync } from "../config-store-write";
|
|
4
|
+
import { deleteAgentProfileAsync, setAgentProfileAsync, setConfigAsync } from "../config-store-write";
|
|
5
5
|
import { memoryRetirementMessage } from "../memory-retirement";
|
|
6
6
|
// Auto-split from routes.ts (#299). Domain: agent-profiles.
|
|
7
7
|
import { ValidationError, withResolvedProvisioningAsync } from "../db";
|
|
8
8
|
import { cleanString, optionalEnum } from "../validation";
|
|
9
|
-
import {
|
|
9
|
+
import { getAgentProfile, listAgentProfiles, resolveAgentProfileKey, validateAgentProfile } from "../config-store";
|
|
10
10
|
import { RELAY_TOOL_GROUPS } from "../mcp";
|
|
11
11
|
import { emitConfigChanged } from "../sse";
|
|
12
12
|
import { error, isAdminRequest, json, normalizeConfigPathParam, parseBody, type Handler } from "./_shared";
|
|
@@ -140,8 +140,8 @@ export const putAgentProfileRoute: Handler = async (req, params) => {
|
|
|
140
140
|
return json(saved);
|
|
141
141
|
}
|
|
142
142
|
const profile = existing?.value.builtIn && isAdminRequest(req)
|
|
143
|
-
?
|
|
144
|
-
:
|
|
143
|
+
? await setAgentProfileAsync({ ...parsed.body, name } as AgentProfile, updatedBy, { overrideBuiltIn: true })
|
|
144
|
+
: await setAgentProfileAsync({ ...parsed.body, name } as AgentProfile, updatedBy);
|
|
145
145
|
emitConfigChanged(profile.namespace, profile.key, profile.version);
|
|
146
146
|
return json(profile, existing ? 200 : profile.version === 1 ? 201 : 200);
|
|
147
147
|
} catch (e) {
|
|
@@ -151,14 +151,14 @@ export const putAgentProfileRoute: Handler = async (req, params) => {
|
|
|
151
151
|
}
|
|
152
152
|
};
|
|
153
153
|
|
|
154
|
-
export const deleteAgentProfileRoute: Handler = (req, params) => {
|
|
154
|
+
export const deleteAgentProfileRoute: Handler = async (req, params) => {
|
|
155
155
|
try {
|
|
156
156
|
const name = normalizeConfigPathParam(params.name, "name");
|
|
157
157
|
const existing = getAgentProfile(name);
|
|
158
158
|
if (!existing) return error(memoryRetirementMessage(name) ?? "agent profile not found", 404);
|
|
159
159
|
const updatedBy = versionedPromptsEnabled() ? promptActor(req) : cleanString(new URL(req.url).searchParams.get("updatedBy") ?? undefined, "updatedBy", { max: 200 });
|
|
160
160
|
if (existing.value.builtIn && !isAdminRequest(req)) return error("built-in agent profiles are managed by Relay", 400);
|
|
161
|
-
|
|
161
|
+
await deleteAgentProfileAsync(name, updatedBy, { resetBuiltInOverride: existing.value.builtIn });
|
|
162
162
|
emitConfigChanged(existing.namespace, existing.key, existing.version + 1);
|
|
163
163
|
return json({ ok: true });
|
|
164
164
|
} catch (e) {
|
|
@@ -208,7 +208,7 @@ export const postAgentSpawn: Handler = async (req) => {
|
|
|
208
208
|
// strip the heavy inlined provisioning file contents from the echoed-back summary.
|
|
209
209
|
return json({
|
|
210
210
|
ok: true, spawnRequestId: result.spawnRequestId, harnessSubagents: result.harnessSubagents, orchestratorId: result.orchestratorId, placementReason: result.placementReason, provider: result.provider, command: summarizeSpawnCommandForCaller(result.command),
|
|
211
|
-
...(result.task ? { task: result.task } : {}), ...(result.warnings ? { warnings: result.warnings } : {}), ...(result.dispatchDecision ? { dispatchDecision: result.dispatchDecision } : {}), ...(workflow.reason ? { workflow: { started: false, reason: workflow.reason } } : {}),
|
|
211
|
+
...(result.task ? { task: result.task } : {}), ...(result.warnings ? { warnings: result.warnings } : {}), ...(result.spawnPolicy ? { spawnPolicy: result.spawnPolicy } : {}), ...(result.dispatchDecision ? { dispatchDecision: result.dispatchDecision } : {}), ...(workflow.reason ? { workflow: { started: false, reason: workflow.reason } } : {}),
|
|
212
212
|
}, 202);
|
|
213
213
|
} catch (e) {
|
|
214
214
|
if (e instanceof McpAuthError) return error(e.message, 403);
|
package/src/routes/agents.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { messageViewerForRequest, visibleMessages } from "./message-viewer";
|
|
3
3
|
import { attachPrincipal, attachPrincipals } from "../agent-principal";
|
|
4
4
|
import { VALID_AGENT_STATUSES, agentSessionStatus, auditEvent, canViewAgentRoute, error, json, normalizeAgentSessionGuard, parseBody, parseId, parseQueryInt, visibleAgentIdsForRequest, type Handler } from "./_shared";
|
|
5
|
-
import { ValidationError, deleteAgentAsync, getAgent, getAgentAsync, getAgentIdentityAsync, getAgentQuotaSnapshotsAsync, getAgentTimelineAsync, getCrashReport,
|
|
5
|
+
import { ValidationError, deleteAgentAsync, getAgent, getAgentAsync, getAgentIdentityAsync, getAgentQuotaSnapshotsAsync, getAgentTimelineAsync, getCrashReport, recordHeartbeatAsync, listAgentChatHistoryAsync, listAgents, listAgentsAsync, listArtifactsForEntityAsync, listContextSnapshotsAsync, listPendingReplyObligationsAsync, markReadyAsync, searchAgentsAsync, setLabelAsync, setStatusAsync, setTagsAsync, validateAgentSession } from "../db";
|
|
6
6
|
import { attachBranchState, attachBranchStates } from "../agent-branch-state";
|
|
7
7
|
import { redactAgentCardLaunchShape } from "../agent-launch-shape-redaction";
|
|
8
8
|
import { attachChannelBinding, attachChannelBindings } from "../agent-channel-binding";
|
|
@@ -258,8 +258,8 @@ function cleanAgentStatus(value: unknown): AgentStatusValue {
|
|
|
258
258
|
// #3606 — a reported status/readiness equal to the live card is a liveness tick, not a transition: no
|
|
259
259
|
// row write, no agent.status event. Presence still advances through the coalescing heartbeat buffer,
|
|
260
260
|
// except for a terminal row, which a beat would resurrect.
|
|
261
|
-
function noteUnchangedLifecycle(agentId: string, current: AgentCard, guard: AgentSessionGuard | undefined): void {
|
|
262
|
-
if (current.status !== "offline" && current.status !== "stale")
|
|
261
|
+
async function noteUnchangedLifecycle(agentId: string, current: AgentCard, guard: AgentSessionGuard | undefined): Promise<void> {
|
|
262
|
+
if (current.status !== "offline" && current.status !== "stale") await recordHeartbeatAsync(agentId, { guard });
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
async function applyAgentStatus(agentId: string, status: AgentStatusValue, guard: AgentSessionGuard | undefined, before: AgentCard | null): Promise<boolean> {
|
|
@@ -309,7 +309,7 @@ export const patchAgentStatus: Handler = async (req, params) => {
|
|
|
309
309
|
const session = validateAgentSession(params.id!, guard);
|
|
310
310
|
if (!session.ok) return error(session.error!, agentSessionStatus(session.error));
|
|
311
311
|
const before = getAgent(params.id!);
|
|
312
|
-
if (before?.status === status) noteUnchangedLifecycle(params.id!, before, guard);
|
|
312
|
+
if (before?.status === status) await noteUnchangedLifecycle(params.id!, before, guard);
|
|
313
313
|
else if (!(await applyAgentStatus(params.id!, status, guard, before))) return error("agent not found", 404);
|
|
314
314
|
} catch (e) {
|
|
315
315
|
if (e instanceof ValidationError) return error(e.message, 400);
|
|
@@ -349,7 +349,7 @@ export const postHeartbeat: Handler = async (req, params) => {
|
|
|
349
349
|
// A reported terminal status must not be undone by the beat's offline/stale resurrection.
|
|
350
350
|
if (status !== "offline" && status !== "stale") {
|
|
351
351
|
// #1468 — route the API heartbeat through the same coalescing buffer as the bus path.
|
|
352
|
-
if (!
|
|
352
|
+
if (!(await recordHeartbeatAsync(params.id!, { guard }))) return error("agent not found", 404);
|
|
353
353
|
}
|
|
354
354
|
if (wasUnavailable) {
|
|
355
355
|
const after = getAgent(params.id!);
|
|
@@ -429,7 +429,7 @@ export const patchAgentReady: Handler = async (req, params) => {
|
|
|
429
429
|
const session = validateAgentSession(params.id!, guard);
|
|
430
430
|
if (!session.ok) return error(session.error!, agentSessionStatus(session.error));
|
|
431
431
|
const before = getAgent(params.id!);
|
|
432
|
-
if (before?.ready === body.ready) noteUnchangedLifecycle(params.id!, before, guard);
|
|
432
|
+
if (before?.ready === body.ready) await noteUnchangedLifecycle(params.id!, before, guard);
|
|
433
433
|
else if (!(await applyAgentReady(params.id!, body.ready, guard, before))) return error("agent not found", 404);
|
|
434
434
|
} catch (e) {
|
|
435
435
|
if (e instanceof ValidationError) return error(e.message, 400);
|
|
@@ -32,6 +32,10 @@ export const getCommands: Handler = async (req) => {
|
|
|
32
32
|
limit: limitRaw ?? undefined,
|
|
33
33
|
dispatchableOnly,
|
|
34
34
|
oldestFirst: dispatchableOnly && status === "pending",
|
|
35
|
+
// #3391 — a listing omits each spawn's inline agentProfile (13.9 MB per 30 rows blocked the hub
|
|
36
|
+
// loop); `GET /api/commands/:id` returns the full row. The executor dispatch feed runs the rows it
|
|
37
|
+
// polls, so it keeps the profile.
|
|
38
|
+
slim: !dispatchableOnly,
|
|
35
39
|
});
|
|
36
40
|
return json(commands.map((command) => serializeCommandForRead(command, ctx)));
|
|
37
41
|
};
|
package/src/routes/commands.ts
CHANGED
|
@@ -29,7 +29,7 @@ import { KERNEL_CORRELATION_PREFIX, isReservedKernelCorrelationId } from "../ser
|
|
|
29
29
|
import { prepareScheduledCommandResultForStorage, settleScheduledCommandTimer } from "../services/scheduler-command";
|
|
30
30
|
import { ServiceAuthError } from "../services/errors";
|
|
31
31
|
import { applyIdleRefreshResult } from "../maintenance/workspaces";
|
|
32
|
-
import {
|
|
32
|
+
import { seedMigratedProviderConfigsAsync } from "../provider-config-store";
|
|
33
33
|
import { notifyAgentSpawnFailed } from "../agent-lifecycle-events";
|
|
34
34
|
import { scheduleRepoMerge } from "../workspace-auto-merge";
|
|
35
35
|
import { settleMemoryInjectionAfterContextCommand } from "../memory-injection";
|
|
@@ -559,7 +559,7 @@ export const patchCommand: Handler = async (req, params) => {
|
|
|
559
559
|
if (command.type === "orchestrator.migrate-provider-config" && command.status === "succeeded" && isRecord(result)) {
|
|
560
560
|
// Seed central rows from the reported host-local files with server authority (#465); idempotent, a
|
|
561
561
|
// stored row wins. Seeds from the request: the persisted result holds only fingerprints (#3403).
|
|
562
|
-
const migration =
|
|
562
|
+
const migration = await seedMigratedProviderConfigsAsync(result);
|
|
563
563
|
if (migration?.seeded.length) {
|
|
564
564
|
const { host, seeded } = migration;
|
|
565
565
|
await auditEvent({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Auto-split from routes.ts (#299). Domain: continuation archives.
|
|
2
2
|
import { isRecord } from "@humwick/sdk";
|
|
3
3
|
import { resolveCallerAgentId } from "../agent-ref";
|
|
4
|
-
import { archiveContinuationSegmentAsync,
|
|
4
|
+
import { archiveContinuationSegmentAsync, appendContinuationArchiveRefsAsync, getAgent, listAgents, ValidationError } from "../db";
|
|
5
5
|
import { getComponentAuth } from "../security";
|
|
6
6
|
import { cleanEpoch, cleanPositiveId, cleanString } from "../validation";
|
|
7
7
|
import { error, json, parseBody, type Handler } from "./_shared";
|
|
@@ -21,7 +21,7 @@ export const postContinuationArchiveRoute: Handler = async (req) => {
|
|
|
21
21
|
generation: cleanPositiveId(parsed.body.generation, "generation"),
|
|
22
22
|
now: cleanEpoch(parsed.body.occurredAt, "occurredAt"),
|
|
23
23
|
});
|
|
24
|
-
const envelope =
|
|
24
|
+
const envelope = await appendContinuationArchiveRefsAsync(agentId, [archive.ref]);
|
|
25
25
|
return json({ archive, envelope }, 201);
|
|
26
26
|
} catch (e) {
|
|
27
27
|
if (e instanceof ValidationError) return error(e.message, 400);
|
package/src/routes/index.ts
CHANGED
|
@@ -70,6 +70,7 @@ import { postIssueLifecycleReopenRoute } from "./issue-lifecycle";
|
|
|
70
70
|
import { deleteIssueRefRoute, getIssueRefRoute, listIssueRefsRoute, patchIssueRefRoute, postIssueRefRoute, resolveIssueRefRoute } from "./issue-refs";
|
|
71
71
|
import { deleteProjectEntryRoute, getProjectEntriesRoute, getProjectEntryRoute, getProjectInjectionPreviewRoute, getProjectResolveRoute, getProjectRoute, getProjectsRoute, patchProjectEntryRoute, postProjectEntryRoute } from "./projects";
|
|
72
72
|
import { getPromptHistoryRoute, postPromptRevisionRoute, getPromptTemplateRoute, getPromptTemplatesRoute, postPromptTemplateResetRoute, putPromptTemplateRoute } from "./prompt-templates";
|
|
73
|
+
import { projectProfileInstructionsRoute } from "./project-profile-instructions";
|
|
73
74
|
import { getRecipeByName, getRecipeInstanceArtifacts, getRecipeInstanceById, getRecipeInstances, getRecipes, postRecipeInstanceArtifacts, postRecipeStart, postRecipeStop } from "./recipes";
|
|
74
75
|
import { getSettingRoute, getSettingsNamespaceRoute, getSettingsRoute, putSettingRoute, putSettingsDefaultRoute } from "./settings";
|
|
75
76
|
import { postNotificationPreviewRoute } from "./notifications";
|
|
@@ -85,7 +86,7 @@ import { postMcp } from "../mcp";
|
|
|
85
86
|
import { postOrchestratorBootstrap, postOrchestratorBootstrapExchange } from "./orchestrator-bootstrap";
|
|
86
87
|
import { getDeploysRoute } from "./deploys";
|
|
87
88
|
import { getGateStatsRoute, getShippingBoardRoute, getShippingStatsRoute, postRedMainAbandonRoute } from "./shipping";
|
|
88
|
-
import { getWorkflowCatalogRoute, getWorkflowDefinitionsRoute, getWorkflowRunBudgetRoute, getWorkflowRunRoute, getWorkflowRunsRoute, getWorkflowStatsRoute, patchWorkflowRunBudgetRoute, postWorkflowRunCancelRoute, postWorkflowRunResumeRoute, postWorkflowRunStartRoute } from "./workflows";
|
|
89
|
+
import { getWorkflowCatalogRoute, getWorkflowDefinitionsRoute, getWorkflowRunBudgetRoute, getWorkflowRunRoute, getWorkflowRunsRoute, getWorkflowStatsRoute, patchWorkflowRunBudgetRoute, postWorkflowRunCancelRoute, postWorkflowRunPauseRoute, postWorkflowRunResumeRoute, postWorkflowRunStartRoute, postWorkflowRunUnpauseRoute } from "./workflows";
|
|
89
90
|
import { getRestartEpochRoute, postRestartEpochAbandonRoute } from "./restart-epochs";
|
|
90
91
|
import { getFleetConvergenceRoute } from "./fleet-convergence";
|
|
91
92
|
import { postTimerMessageOperator } from "./kernel-timers-operator";
|
|
@@ -318,6 +319,7 @@ const routes: Route[] = [
|
|
|
318
319
|
route("DELETE", "/api/commands/:id", deleteCommandById),
|
|
319
320
|
route("POST", "/api/system/timer-message-cutover/:verb", postTimerMessageOperator),
|
|
320
321
|
route("GET", "/api/agent-profiles", getAgentProfilesRoute),
|
|
322
|
+
route("GET", "/api/agent-profiles/:name/project-instructions", projectProfileInstructionsRoute),
|
|
321
323
|
route("GET", "/api/agent-profiles/tool-groups", getAgentProfileToolGroupsRoute),
|
|
322
324
|
route("POST", "/api/agent-profiles/preview", postAgentProfilePreviewRoute),
|
|
323
325
|
route("GET", "/api/agent-profiles/:name/resolved", getResolvedAgentProfileRoute),
|
|
@@ -546,6 +548,11 @@ const routes: Route[] = [
|
|
|
546
548
|
route("PATCH", "/api/issue-refs/:id", patchIssueRefRoute),
|
|
547
549
|
route("DELETE", "/api/issue-refs/:id", deleteIssueRefRoute),
|
|
548
550
|
route("GET", "/api/projects", getProjectsRoute),
|
|
551
|
+
route("GET", "/api/projects/:id/profile-instructions", projectProfileInstructionsRoute),
|
|
552
|
+
route("GET", "/api/projects/:id/profile-instructions/:profile", projectProfileInstructionsRoute),
|
|
553
|
+
route("PUT", "/api/projects/:id/profile-instructions/:profile", projectProfileInstructionsRoute),
|
|
554
|
+
route("GET", "/api/projects/:id/profile-instructions/:profile/history", projectProfileInstructionsRoute),
|
|
555
|
+
route("POST", "/api/projects/:id/profile-instructions/:profile/restore", projectProfileInstructionsRoute),
|
|
549
556
|
route("POST", "/api/projects", postProjectOnboardRoute),
|
|
550
557
|
route("POST", "/api/projects/:id/checkouts/bind", postProjectBindCheckoutRoute),
|
|
551
558
|
route("POST", "/api/projects/:id/checkouts/unbind", postProjectUnbindCheckoutRoute),
|
|
@@ -600,6 +607,8 @@ const routes: Route[] = [
|
|
|
600
607
|
route("GET", "/api/workflows/runs/:runId/budget", getWorkflowRunBudgetRoute),
|
|
601
608
|
route("PATCH", "/api/workflows/runs/:runId/budget", patchWorkflowRunBudgetRoute),
|
|
602
609
|
route("POST", "/api/workflows/runs/:runId/cancel", postWorkflowRunCancelRoute),
|
|
610
|
+
route("POST", "/api/workflows/runs/:runId/pause", postWorkflowRunPauseRoute),
|
|
611
|
+
route("POST", "/api/workflows/runs/:runId/unpause", postWorkflowRunUnpauseRoute),
|
|
603
612
|
route("POST", "/api/workflows/runs/:runId/resume", postWorkflowRunResumeRoute),
|
|
604
613
|
route("GET", "/api/workflows/stats", getWorkflowStatsRoute),
|
|
605
614
|
route("GET", "/api/workflows/definitions", getWorkflowDefinitionsRoute),
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import type { IntegrationRegistryInput } from "../db/integrations";
|
|
1
2
|
// Auto-split from routes.ts (#299). Domain: integrations.
|
|
2
3
|
import { INTEGRATION_RATE_LIMIT_PER_MINUTE, MAX_BODY_BYTES, getIntegrationTokens, type IntegrationTokenConfig } from "../config";
|
|
3
4
|
import { VALID_ARTIFACT_KINDS, VALID_ARTIFACT_ROLES, VALID_TASK_STATUSES, agentSessionStatus, authorizeRoute, cleanAttachmentRefs, dispatchTaskCallbacksInBackground, error, json, normalizeAgentSessionGuard, parseBody, reactionEmoji, sendReactionNotificationToAuthor, validateChannelAttachmentSourceRef, withPayloadAttachments, type Handler } from "./_shared";
|
|
4
|
-
import { ValidationError, evaluatePoolBindingsAsync, findMessageByTelegramSourceAsync, getAgent, getChannelAsync, getMessage, ingestIntegrationEvent, isIntegrationRegistryEnabled, listChannelBindingsAsync, listChannelsAsync,
|
|
5
|
+
import { ValidationError, evaluatePoolBindingsAsync, findMessageByTelegramSourceAsync, getAgent, getChannelAsync, getMessage, ingestIntegrationEvent, isIntegrationRegistryEnabled, listChannelBindingsAsync, listChannelsAsync, listIntegrationTaskStatsAsync, reconcileIntegrationRegistryAsync, resolveChannelRoutesAsync, sendMessageWithResult, setMessageReactionAsync, upsertChannelBindingAsync, upsertIntegrationRegistry, validateAgentSession } from "../db";
|
|
5
6
|
import { cleanMeta, cleanString, cleanStringArray, optionalEnum } from "../validation";
|
|
6
7
|
import { emitChannelActivity, emitMessageQueued, emitMessageReactionUpdated, emitNewMessage, emitTaskChanged } from "../sse";
|
|
7
8
|
import { getComponentAuth, getIntegrationAuth, hasIntegrationScope, isRequestAuthorizedFor } from "../security";
|
|
@@ -256,24 +257,7 @@ function normalizeIntegrationEvent(body: unknown): IntegrationEventInput {
|
|
|
256
257
|
};
|
|
257
258
|
}
|
|
258
259
|
|
|
259
|
-
function normalizeIntegrationRegistryInput(name: string, body: unknown): {
|
|
260
|
-
name: string;
|
|
261
|
-
displayName?: string;
|
|
262
|
-
description?: string;
|
|
263
|
-
enabled?: boolean;
|
|
264
|
-
scopes?: string[];
|
|
265
|
-
targets?: string[];
|
|
266
|
-
channels?: string[];
|
|
267
|
-
type?: string;
|
|
268
|
-
icon?: string;
|
|
269
|
-
accentColor?: string;
|
|
270
|
-
tags?: string[];
|
|
271
|
-
homepageUrl?: string;
|
|
272
|
-
repositoryUrl?: string;
|
|
273
|
-
docsUrl?: string;
|
|
274
|
-
manifest?: Record<string, unknown>;
|
|
275
|
-
source: "api";
|
|
276
|
-
} {
|
|
260
|
+
function normalizeIntegrationRegistryInput(name: string, body: unknown): IntegrationRegistryInput & { source: "api" } {
|
|
277
261
|
if (!isRecord(body)) throw new ValidationError("body must be an object");
|
|
278
262
|
if (body.enabled !== undefined && typeof body.enabled !== "boolean") throw new ValidationError("enabled must be a boolean");
|
|
279
263
|
return {
|
|
@@ -364,40 +348,30 @@ function safeCallbackHost(url: string | undefined): string | undefined {
|
|
|
364
348
|
}
|
|
365
349
|
}
|
|
366
350
|
|
|
367
|
-
function
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
for (const stats of observedStats.values()) {
|
|
388
|
-
upsertIntegrationRegistry({
|
|
389
|
-
name: stats.source,
|
|
390
|
-
enabled: true,
|
|
391
|
-
source: "observed",
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
return new Map(listIntegrationRegistry().map((integration) => [integration.name, integration]));
|
|
351
|
+
async function reconcileRegistry(configured: Map<string, IntegrationTokenConfig>, observedSources: string[]) {
|
|
352
|
+
const registry = await reconcileIntegrationRegistryAsync([...configured.values()].map((config) => ({
|
|
353
|
+
name: config.name,
|
|
354
|
+
displayName: config.displayName,
|
|
355
|
+
description: config.description,
|
|
356
|
+
scopes: config.scopes,
|
|
357
|
+
targets: config.targets,
|
|
358
|
+
channels: config.channels,
|
|
359
|
+
type: config.type,
|
|
360
|
+
icon: config.icon,
|
|
361
|
+
accentColor: config.accentColor,
|
|
362
|
+
tags: config.tags,
|
|
363
|
+
homepageUrl: config.homepageUrl,
|
|
364
|
+
repositoryUrl: config.repositoryUrl,
|
|
365
|
+
docsUrl: config.docsUrl,
|
|
366
|
+
manifest: config.manifest,
|
|
367
|
+
})), observedSources);
|
|
368
|
+
return new Map(registry.map((integration) => [integration.name, integration]));
|
|
395
369
|
}
|
|
396
370
|
|
|
397
|
-
export const getIntegrations: Handler = () => {
|
|
371
|
+
export const getIntegrations: Handler = async () => {
|
|
398
372
|
const configured = new Map(getIntegrationTokens().map((integration) => [integration.name, integration]));
|
|
399
|
-
const observedStats = new Map(
|
|
400
|
-
const registry =
|
|
373
|
+
const observedStats = new Map((await listIntegrationTaskStatsAsync()).map((stats) => [stats.source, stats]));
|
|
374
|
+
const registry = await reconcileRegistry(configured, [...observedStats.keys()]);
|
|
401
375
|
const names = [...new Set([...configured.keys(), ...observedStats.keys(), ...registry.keys()])].sort((a, b) => a.localeCompare(b));
|
|
402
376
|
const now = Date.now();
|
|
403
377
|
|
package/src/routes/issue-refs.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { deleteIssueRefMappingAsync, getIssueRef, listIssueRefs, patchIssueRefMappingAsync, resolveIssueRefMappingAsync, upsertIssueRefMappingAsync, type ListIssueRefsOptions } from "../services/issue-refs";
|
|
2
2
|
import { getIssueRefByExternalKey, issueRefClosedCompleted, issueRefForRefString } from "../db/issue-refs";
|
|
3
3
|
import { advanceTerminalPlanRefsAsync } from "../services/plan-terminal-refs";
|
|
4
4
|
import { cleanEnum, cleanString, optionalEnum } from "../validation";
|
|
@@ -76,7 +76,7 @@ export const postIssueRefRoute: Handler = async (req) => {
|
|
|
76
76
|
try {
|
|
77
77
|
const body = cleanUpsertBody(parsed.body);
|
|
78
78
|
const before = getIssueRefByExternalKey(body.provider, body.repo, body.externalKey);
|
|
79
|
-
const issueRef =
|
|
79
|
+
const issueRef = await upsertIssueRefMappingAsync(body);
|
|
80
80
|
// #2520 — a completed close cached here propagates to the plan nodes bound to this ref.
|
|
81
81
|
if (issueRefClosedCompleted(before, issueRef)) await advanceTerminalPlanRefsAsync({ issueRefId: issueRef.id });
|
|
82
82
|
return json({ issueRef });
|
|
@@ -98,7 +98,7 @@ export const resolveIssueRefRoute: Handler = async (req) => {
|
|
|
98
98
|
? issueRefForRefString(ref, cleanString(value.defaultRepo ?? value.repo, "defaultRepo", { max: 500 }))
|
|
99
99
|
: getIssueRefByExternalKey(cleanProvider(value.provider), cleanString(value.repo, "repo", { required: true, max: 500 })!, cleanString(value.externalKey, "externalKey", { required: true, max: 240 })!);
|
|
100
100
|
const issueRef = ref
|
|
101
|
-
?
|
|
101
|
+
? await resolveIssueRefMappingAsync({
|
|
102
102
|
ref,
|
|
103
103
|
defaultRepo: cleanString(value.defaultRepo ?? value.repo, "defaultRepo", { max: 500 }),
|
|
104
104
|
provider: optionalEnum(value.provider, "provider", ISSUE_PROVIDERS, "github") as IssueProvider,
|
|
@@ -107,7 +107,7 @@ export const resolveIssueRefRoute: Handler = async (req) => {
|
|
|
107
107
|
closeReason: cleanCloseReason(value.closeReason),
|
|
108
108
|
statusSyncedAt: cleanTimestamp(value.statusSyncedAt),
|
|
109
109
|
})
|
|
110
|
-
:
|
|
110
|
+
: await resolveIssueRefMappingAsync({
|
|
111
111
|
provider: cleanProvider(value.provider),
|
|
112
112
|
repo: cleanString(value.repo, "repo", { required: true, max: 500 })!,
|
|
113
113
|
externalKey: cleanString(value.externalKey, "externalKey", { required: true, max: 240 })!,
|
|
@@ -142,7 +142,7 @@ export const patchIssueRefRoute: Handler = async (req, params) => {
|
|
|
142
142
|
try {
|
|
143
143
|
const id = cleanString(params.id, "id", { required: true, max: 120 })!;
|
|
144
144
|
const before = getIssueRef(id);
|
|
145
|
-
const issueRef =
|
|
145
|
+
const issueRef = await patchIssueRefMappingAsync(id, cleanPatchBody(parsed.body));
|
|
146
146
|
if (!issueRef) return error("issue ref not found", 404);
|
|
147
147
|
// #2520 — a completed close cached here propagates to the plan nodes bound to this ref.
|
|
148
148
|
if (issueRefClosedCompleted(before, issueRef)) await advanceTerminalPlanRefsAsync({ issueRefId: issueRef.id });
|
|
@@ -152,9 +152,9 @@ export const patchIssueRefRoute: Handler = async (req, params) => {
|
|
|
152
152
|
}
|
|
153
153
|
};
|
|
154
154
|
|
|
155
|
-
export const deleteIssueRefRoute: Handler = (_req, params) => {
|
|
155
|
+
export const deleteIssueRefRoute: Handler = async (_req, params) => {
|
|
156
156
|
try {
|
|
157
|
-
const deleted =
|
|
157
|
+
const deleted = await deleteIssueRefMappingAsync(cleanString(params.id, "id", { required: true, max: 120 })!);
|
|
158
158
|
if (!deleted) return error("issue ref not found", 404);
|
|
159
159
|
return json({ deleted });
|
|
160
160
|
} catch (err) {
|
|
@@ -50,7 +50,7 @@ export const postOrchestratorBootstrap: Handler = async (req) => {
|
|
|
50
50
|
"--yes",
|
|
51
51
|
];
|
|
52
52
|
for (const entry of pathPrefix ?? []) args.push("--path-prefix", entry);
|
|
53
|
-
const command = ["bunx",
|
|
53
|
+
const command = ["bunx", `@humwick/server@${version}`, ...args].map(quoteInstallCommandArg).join(" ");
|
|
54
54
|
return json({
|
|
55
55
|
command,
|
|
56
56
|
relayUrl,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// upsert, and fanning the operator-facing events out as activity events — lives here.
|
|
5
5
|
import { isRecord } from "@humwick/sdk";
|
|
6
6
|
import type { HostHardware } from "@humwick/sdk";
|
|
7
|
-
import { upsertHostFromRegistrationAsync, type HostRegistrationEvent } from "../db";
|
|
7
|
+
import { conflictingHardwareFields, upsertHostFromRegistrationAsync, type HostRegistrationEvent } from "../db";
|
|
8
8
|
import { auditEvent, cleanSafeNumber } from "./_shared";
|
|
9
9
|
import { recordOrchestratorUtilization } from "./orchestrator-host-utilization";
|
|
10
10
|
import { cleanString } from "../validation";
|
|
@@ -55,7 +55,7 @@ async function emitHostRegistrationEvents(events: readonly HostRegistrationEvent
|
|
|
55
55
|
clientId: `host-identity-conflict-${ev.hostId}-${ev.orchestratorId}-${Date.now()}`,
|
|
56
56
|
kind: "state",
|
|
57
57
|
title: "Host identity conflict",
|
|
58
|
-
body: `${ev.hostname}: reported hardware differs from the stored fingerprint — bound anyway, kept first-seen (conflict:pending)`,
|
|
58
|
+
body: `${ev.hostname}: reported hardware differs from the stored fingerprint (${conflictingHardwareFields(ev.stored, ev.reported).join(", ")} changed) — bound anyway, kept first-seen (conflict:pending)`,
|
|
59
59
|
meta: ev.hostId,
|
|
60
60
|
icon: "ti-alert-triangle",
|
|
61
61
|
view: "orchestrators",
|
|
@@ -141,6 +141,7 @@ export function cleanHostUtilizationSample(value: unknown, now: number): HostUti
|
|
|
141
141
|
const swapUsedMb = nonNegative(value.swapUsedMb);
|
|
142
142
|
const diskTotalMb = nonNegative(value.diskTotalMb);
|
|
143
143
|
const diskFreeMb = nonNegative(value.diskFreeMb);
|
|
144
|
+
const diskPath = optionalString(value.diskPath, "utilization.diskPath", 200);
|
|
144
145
|
|
|
145
146
|
return {
|
|
146
147
|
at,
|
|
@@ -162,7 +163,7 @@ export function cleanHostUtilizationSample(value: unknown, now: number): HostUti
|
|
|
162
163
|
...(swapTotalMb !== undefined && swapUsedMb !== undefined && swapUsedMb <= swapTotalMb
|
|
163
164
|
? { swapTotalMb, swapUsedMb } : {}),
|
|
164
165
|
...(diskTotalMb !== undefined && diskFreeMb !== undefined && diskFreeMb <= diskTotalMb
|
|
165
|
-
? { diskTotalMb, diskFreeMb } : {}),
|
|
166
|
+
? { diskTotalMb, diskFreeMb, ...(diskPath ? { diskPath } : {}) } : {}),
|
|
166
167
|
memPressure,
|
|
167
168
|
agentCountThisDaemon,
|
|
168
169
|
queuedSpawnsThisDaemon,
|
|
@@ -207,6 +208,7 @@ export function toMachineSample(sample: HostUtilizationSample): HostMachineSampl
|
|
|
207
208
|
...(sample.swapTotalMb !== undefined ? { swapTotalMb: sample.swapTotalMb } : {}),
|
|
208
209
|
...(sample.diskFreeMb !== undefined ? { diskFreeMb: sample.diskFreeMb } : {}),
|
|
209
210
|
...(sample.diskTotalMb !== undefined ? { diskTotalMb: sample.diskTotalMb } : {}),
|
|
211
|
+
...(sample.diskPath ? { diskPath: sample.diskPath } : {}),
|
|
210
212
|
memPressure: sample.memPressure,
|
|
211
213
|
};
|
|
212
214
|
}
|