@humwick/server 0.130.1 → 0.130.3
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/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-administration.md +4 -0
- package/docs/guides/tools-coordination.md +2 -0
- package/docs/guides/tools-tasks.md +8 -0
- package/docs/guides/workflows.md +74 -0
- package/docs/openapi.json +486 -4
- package/package.json +10 -18
- package/public/assets/{MessageBubble-BWpoBjl4.js → MessageBubble-Bq9kr21N.js} +2 -2
- package/public/assets/{PlanGraphPanel-C0auck3n.js → PlanGraphPanel-Dqiroy06.js} +2 -2
- package/public/assets/{TraceView-DBnOx7AQ.js → TraceView-DYU962-H.js} +2 -2
- package/public/assets/{VaultDecisionCard-0kp2oNBC.js → VaultDecisionCard-DhPfzioE.js} +2 -2
- package/public/assets/{activity-yLztXEBt.js → activity-DzCcQTee.js} +2 -2
- package/public/assets/{agent-lineage-BbJDR1dW.js → agent-lineage-SgDt9i3T.js} +2 -2
- package/public/assets/agent-liveness-Bq-s73jW.js +2 -0
- package/public/assets/{agent-name-CTZBrSD9.js → agent-name-CcY3Aijy.js} +2 -2
- package/public/assets/agent-profiles-cxtRBn6O.js +2 -0
- package/public/assets/{agent-project-badge-9TqzUUYE.js → agent-project-badge-DGYbIhaI.js} +2 -2
- package/public/assets/{agent-tools-D4n40pn8.js → agent-tools-DHbftV0N.js} +2 -2
- package/public/assets/{agent-type-icon-D6FUarOf.js → agent-type-icon-CY113sp-.js} +2 -2
- package/public/assets/{agents-BYDslkJc.js → agents-BPzY7IlQ.js} +2 -2
- package/public/assets/{analytics-B-XSbEMC.js → analytics-DENFPv_a.js} +2 -2
- package/public/assets/{artifact-viewer-DdWIfV6M.js → artifact-viewer-KRvSc7sl.js} +2 -2
- package/public/assets/{artifacts-DPN1q4pA.js → artifacts-C9gSmL3s.js} +2 -2
- package/public/assets/{artifacts-oBOqks-2.js → artifacts-DT-HkI5O.js} +2 -2
- package/public/assets/{automation-4KcRFXEu.js → automation-BsmjQhKD.js} +2 -2
- package/public/assets/{backlog-Cw9xPTCF.js → backlog-8NYH_62t.js} +2 -2
- package/public/assets/{busy-health-CTu32MZt.js → busy-health-D3hwvYb4.js} +2 -2
- package/public/assets/{channels-BiXzg1G9.js → channels-DCJ5WL7O.js} +2 -2
- package/public/assets/{chat-Ctk2qwvA.js → chat-DAIl357U.js} +3 -3
- package/public/assets/{code-preview-Bm1wWqAp.js → code-preview-CzrZfr9U.js} +2 -2
- package/public/assets/{connectors-C36ax4Vw.js → connectors-xTxtlyou.js} +2 -2
- package/public/assets/{cosmos-Jj9LK2Wf.js → cosmos-BpebFLK2.js} +2 -2
- package/public/assets/{crate-agent-H6S7-B9T.js → crate-agent-BHvI5wXC.js} +2 -2
- package/public/assets/{dependency-graph-Cd1E23wa.js → dependency-graph-DGT0o3wJ.js} +2 -2
- package/public/assets/{deploys-Bwfq146q.js → deploys-hqWOHSHE.js} +2 -2
- package/public/assets/{display-CfO7rTuF.js → display-CDeH4I8T.js} +2 -2
- package/public/assets/{files-DhhZI2Ih.js → files-BTeGVmTg.js} +2 -2
- package/public/assets/{fleet-B_rFEbnL.js → fleet-DgXtNgCa.js} +2 -2
- package/public/assets/{fleet-metrics-BkHP-P3R.js → fleet-metrics-BHEt5yc_.js} +2 -2
- package/public/assets/{formatted-body-Cm1RrzmN.js → formatted-body-MLtodyPp.js} +3 -3
- package/public/assets/{formatted-body-impl-DQiOuOD1.js → formatted-body-impl-CAe664Z8.js} +2 -2
- package/public/assets/{host-providers-dialog-CHqwXTov.js → host-providers-dialog-mapF4Fj9.js} +2 -2
- package/public/assets/index-CqqgOI5R.js +15 -0
- package/public/assets/index-MYAIwYTX.css +2 -0
- package/public/assets/{insights-fH1EL-qZ.js → insights-DNyf7IzF.js} +2 -2
- package/public/assets/{integrations-C5Oix6ng.js → integrations-DlYOHq7T.js} +2 -2
- package/public/assets/{issue-ref-chip-ODyondIa.js → issue-ref-chip-CeWBNWn7.js} +2 -2
- package/public/assets/{log-viewer-Cvfy6PW7.js → log-viewer-Cib8nqdE.js} +2 -2
- package/public/assets/{maintenance-D8CDH5wZ.js → maintenance-DSn1cPm7.js} +2 -2
- package/public/assets/{managed-agents-egllbpij.js → managed-agents-C3CkM81m.js} +2 -2
- package/public/assets/{markdown-preview-CYSFgVgK.js → markdown-preview-W4VQQPAv.js} +3 -3
- package/public/assets/{markdown-preview-impl-BteVIjX4.js → markdown-preview-impl-CMsTdhjq.js} +2 -2
- package/public/assets/{memory-C8WmXsyr.js → memory-BV17qtO4.js} +2 -2
- package/public/assets/{messages-BzQdqlO6.js → messages-Bm_1AqSA.js} +2 -2
- package/public/assets/{orchestrators-B1HxzkNw.js → orchestrators-Dg-vfP09.js} +2 -2
- package/public/assets/{overview-DCUnI4Z7.js → overview-DcYCrvlr.js} +2 -2
- package/public/assets/{pairs-ftCd2XcD.js → pairs-8o9nuG3V.js} +2 -2
- package/public/assets/{profile-icon-B2zH8DMH.js → profile-icon-BsRyBMea.js} +2 -2
- package/public/assets/project-profile-instructions-DETKFn_E.js +2 -0
- package/public/assets/projects-M_m6AHws.js +2 -0
- package/public/assets/{prompt-settings-Bftq9czX.js → prompt-settings-C_mNCgeL.js} +2 -2
- package/public/assets/provider-display-BEeLXC_D.js +2 -0
- package/public/assets/{registry-DWCU5c8q.js → registry-DDHHHE5N.js} +2 -2
- package/public/assets/run-card-Dt4I4jaP.js +2 -0
- package/public/assets/scroll-text-BKXS1ahr.js +2 -0
- package/public/assets/{secrets-C7GIUATz.js → secrets-BkVwxI5O.js} +2 -2
- package/public/assets/{service-access-settings-C3aujqTG.js → service-access-settings-Crq-6a-B.js} +2 -2
- package/public/assets/{settings-C6sZ9eBa.js → settings-CYcavMFu.js} +2 -2
- package/public/assets/shipping-H6gzEeZB.js +2 -0
- package/public/assets/{stats-V9Z-GxUd.js → stats-BJVeWkpV.js} +2 -2
- package/public/assets/{status-dot-CVv0iGHL.js → status-dot-BcHyw1Vw.js} +2 -2
- package/public/assets/store-DKPDIZBe.js +9 -0
- package/public/assets/{tasks-CXU75HRF.js → tasks-qJjlQPpx.js} +2 -2
- package/public/assets/{teams-BPf976zb.js → teams-Cd5Sk1uX.js} +2 -2
- package/public/assets/{terminal-viewer-DE9BOe-8.js → terminal-viewer-CpY5_m7W.js} +3 -3
- package/public/assets/{terminal-viewer-impl-D04pjmGh.js → terminal-viewer-impl-DI_2llFR.js} +2 -2
- package/public/assets/token-estimate-Co-Jdphh.js +2 -0
- package/public/assets/{use-agent-terminal-B1yR456R.js → use-agent-terminal-0yJA_buM.js} +2 -2
- package/public/assets/{use-decisions-D-S4tpDf.js → use-decisions-uJXHf34W.js} +2 -2
- package/public/assets/use-project-list-CpWl6eHQ.js +2 -0
- package/public/assets/{use-selectors-CnrAk2YP.js → use-selectors-BdxBW8mL.js} +2 -2
- package/public/assets/{user-avatar-nBFIcR4M.js → user-avatar-3IndfpOc.js} +2 -2
- package/public/assets/versioned-prompt-editor-CIVg7XB1.js +8 -0
- package/public/assets/{work-queue-TCjJxeT-.js → work-queue-B9rnLwHZ.js} +2 -2
- package/public/assets/{workflow-marker-Cf3Hf2fN.js → workflow-marker-X8wxyhzC.js} +2 -2
- package/public/assets/{workflows-CXQX20Qj.js → workflows-o5YyMFW7.js} +2 -2
- package/public/assets/{workspaces-qSYzKYMA.js → workspaces-CzEGoAng.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/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/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/adapters/provider-quota-harvest.ts +20 -71
- 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 +2 -4
- package/runner/src/agent-runner/liveness-exchange.ts +104 -0
- 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/claude-system-prompt.ts +49 -0
- package/runner/src/index.ts +5 -2
- 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 +35 -0
- package/runner/src/providers.ts +2 -1
- package/runner/src/runner-core.ts +32 -38
- package/runner/src/runner-helpers.ts +0 -8
- package/runner/src/session-scratch.ts +6 -2
- package/runner/src/spawn-input.ts +2 -1
- package/runner/src/test-run-dedup.ts +59 -56
- package/runner/test-support/provisioning-context.ts +4 -2
- package/runner/test-support/runner-harness.ts +2 -1
- package/scripts/cd-config.ts +8 -0
- package/scripts/gate-run-lease.ts +10 -7
- package/scripts/gate.sh +5 -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/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 +93 -0
- package/src/branch-landed.ts +31 -98
- package/src/bus.ts +40 -39
- package/src/cd-deploy-notify.ts +32 -4
- 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/notifications.ts +4 -4
- package/src/ci/root-missing.ts +4 -9
- package/src/ci/transition-notify.ts +12 -44
- package/src/claude-app/oauth-http.ts +3 -3
- 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 +19 -4
- package/src/commands-db.ts +7 -7
- package/src/commands-write.ts +8 -0
- package/src/compaction-watch.ts +10 -8
- package/src/config-store-write.ts +13 -1
- package/src/config-store.ts +25 -14
- package/src/config.ts +4 -11
- package/src/connectors.ts +10 -8
- package/src/context-advisory.ts +22 -21
- 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-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/agent-search.ts +1 -15
- package/src/db/agents-async.ts +59 -9
- package/src/db/agents-write-ops.ts +12 -3
- package/src/db/agents.ts +95 -65
- 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/ci-incidents-async.ts +5 -5
- package/src/db/ci-incidents-write-ops.ts +2 -2
- 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/command-row.ts +10 -2
- package/src/db/commands-list-query.ts +2 -0
- package/src/db/commands-planner-stats.test-fixture.ts +8 -0
- package/src/db/commands-read-ops.ts +16 -0
- package/src/db/commands-spawn-read.ts +1 -1
- package/src/db/config-store-write-ops.ts +7 -2
- package/src/db/connection.ts +1 -182
- package/src/db/context-carry-write.ts +74 -0
- package/src/db/continuation-archives-async.ts +5 -0
- package/src/db/continuation-archives-write-ops.ts +7 -0
- package/src/db/continuations.ts +6 -6
- package/src/db/db-error-registry.ts +12 -0
- 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/gateway.ts +26 -133
- package/src/db/history-retention-ops.ts +13 -0
- package/src/db/hosts-registration.ts +10 -2
- package/src/db/hosts.ts +9 -6
- package/src/db/inbox-async.ts +2 -2
- package/src/db/inbox-read-ops.ts +1 -1
- package/src/db/inbox.ts +9 -17
- 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-associations.ts +2 -2
- package/src/db/issue-lifecycle.ts +3 -4
- package/src/db/issue-refs-async.ts +23 -0
- package/src/db/issue-refs-read-ops.ts +6 -0
- package/src/db/issue-refs-write-ops.ts +29 -0
- package/src/db/issue-refs.ts +15 -16
- 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/long-running-work.ts +2 -2
- package/src/db/main-connection-mode.ts +11 -0
- package/src/db/main-connection-writes.ts +41 -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/maintenance-pauses.ts +2 -2
- package/src/db/mappers.ts +2 -14
- package/src/db/merge-lease.ts +1 -15
- package/src/db/message-send.ts +4 -0
- package/src/db/messages.ts +31 -25
- package/src/db/migrations.ts +25 -16
- package/src/db/notification-write-ops.ts +19 -0
- package/src/db/operator-answer-write.ts +19 -0
- package/src/db/orchestrators.ts +14 -76
- package/src/db/pairs-async.ts +22 -1
- package/src/db/pairs-write-ops.ts +8 -3
- package/src/db/pairs.ts +42 -61
- 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-profile-instructions.ts +50 -0
- package/src/db/project-trust-approvals.ts +2 -2
- package/src/db/prompt-templates.ts +4 -4
- 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 +23 -0
- package/src/db/read-ops.ts +8 -0
- package/src/db/retention.ts +13 -2
- package/src/db/review-publish-write.ts +8 -0
- package/src/db/routing-policy.ts +2 -3
- 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 +13 -4
- package/src/db/spawn-budget.ts +5 -0
- package/src/db/spawn-delegation-state.ts +11 -4
- package/src/db/spawn-delegation.ts +1 -11
- package/src/db/sql-audit-indexes.ts +3 -0
- package/src/db/stats-async.ts +9 -6
- package/src/db/task-entity.ts +28 -6
- package/src/db/task-list.ts +3 -1
- package/src/db/tasks.ts +1 -17
- 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/timer-ingress.ts +7 -1
- package/src/db/token-db-write-ops.ts +19 -0
- package/src/db/token-standing-async.ts +12 -0
- package/src/db/token-standing.ts +21 -20
- 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-contact.ts +1 -1
- package/src/db/workflow-task-read-ops.ts +30 -0
- package/src/db/workspaces.ts +8 -5
- package/src/db/write-ops.ts +37 -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 +58 -56
- package/src/dev.ts +8 -3
- 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/event-loop-lag.ts +4 -2
- package/src/event-loop-yield.ts +2 -2
- package/src/events.ts +10 -8
- package/src/host/disk-alert.ts +121 -0
- 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/injection-sweep-pacing.ts +6 -8
- 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 +107 -100
- package/src/maintenance/breaker.ts +18 -16
- package/src/maintenance/cd-watcher.ts +3 -3
- package/src/maintenance/checkout-refresh.ts +18 -1
- package/src/maintenance/critical-job-watchdog.ts +19 -20
- package/src/maintenance/events.ts +3 -3
- package/src/maintenance/history-retention-job.ts +30 -0
- package/src/maintenance/index.ts +1 -0
- package/src/maintenance/jobs.ts +32 -69
- 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 +98 -137
- package/src/maintenance/stalled-delivery-pager.ts +10 -9
- package/src/maintenance/teams.ts +19 -30
- package/src/maintenance/workspaces.ts +18 -28
- package/src/managed-policy-escalation.ts +7 -7
- package/src/managed-policy.ts +32 -28
- package/src/managed-provider-gate.ts +5 -4
- package/src/managed-spawn-reservation.ts +5 -4
- package/src/mcp/index.ts +12 -9
- package/src/mcp/output-descriptions.ts +8 -8
- package/src/mcp/presentation.ts +6 -5
- package/src/mcp/project-profile-instructions.ts +32 -0
- 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 +4 -3
- package/src/mcp/tool-roles.ts +81 -0
- package/src/mcp/tools-spawn.ts +4 -3
- package/src/mcp/tools-workspace.ts +1 -1
- package/src/mcp-agent-action.ts +1 -2
- 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 +13 -12
- package/src/mcp-maintenance-tools.ts +2 -2
- 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 +5 -5
- package/src/mcp-project-journal-tools.ts +4 -12
- package/src/mcp-project-tools.ts +17 -18
- package/src/mcp-provider-catalog.ts +2 -2
- package/src/mcp-routing-policy-tools.ts +3 -2
- package/src/mcp-task-tools.ts +11 -5
- package/src/mcp-team-template-tools.ts +3 -3
- package/src/mcp-team-tools.ts +6 -6
- package/src/mcp-workflow-tools.ts +13 -4
- 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/notification-types.ts +2 -1
- package/src/notify.ts +5 -5
- package/src/observed-reset-refresh.ts +4 -4
- package/src/operator-alarm.ts +23 -11
- package/src/project-ingest.ts +6 -6
- package/src/project-instructions.ts +12 -1
- package/src/project-profile-instruction-text.ts +6 -0
- package/src/project-profile-instructions.ts +20 -0
- package/src/project-trust.ts +12 -11
- package/src/prompt-resolver.ts +3 -3
- 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-async.ts +5 -7
- package/src/provider-quota-config-store.ts +5 -4
- package/src/provider-secrets.test-fixture.ts +3 -3
- package/src/provider-timeline-event.ts +4 -7
- package/src/quota-band-delivery.ts +2 -2
- package/src/recipe-runner.ts +6 -5
- package/src/repo-config-source.ts +10 -4
- 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-profiles.ts +6 -6
- 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 +2 -2
- package/src/routes/agents.ts +19 -121
- package/src/routes/auth.ts +14 -15
- 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 +5 -1
- package/src/routes/commands.ts +31 -29
- package/src/routes/context-resets.ts +2 -2
- package/src/routes/continuation-archives.ts +2 -2
- package/src/routes/coordinator-teams.ts +1 -1
- package/src/routes/decisions.ts +2 -2
- 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 +12 -2
- package/src/routes/integrations.ts +32 -56
- package/src/routes/issue-activity.ts +2 -2
- package/src/routes/issue-associations.ts +4 -4
- package/src/routes/issue-refs.ts +9 -9
- 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 +2 -2
- package/src/routes/orchestrator-host-registration.ts +4 -2
- package/src/routes/orchestrator-host-utilization.ts +5 -3
- package/src/routes/orchestrator-proxy.ts +4 -4
- package/src/routes/orchestrator.ts +28 -19
- package/src/routes/pairs.ts +8 -8
- package/src/routes/project-profile-instructions.ts +27 -0
- package/src/routes/project-trust.ts +3 -3
- package/src/routes/projects.ts +16 -16
- package/src/routes/prompt-templates.ts +12 -12
- package/src/routes/provider-config.ts +6 -6
- package/src/routes/provider-quota-config.ts +2 -2
- package/src/routes/provider-quotas.ts +10 -10
- package/src/routes/run-command.ts +1 -1
- package/src/routes/secrets-backup.ts +2 -2
- package/src/routes/secrets-import.ts +1 -1
- package/src/routes/secrets-vault.ts +7 -7
- package/src/routes/settings.ts +6 -6
- 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/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 +12 -12
- package/src/routes/teams-config.ts +2 -2
- package/src/routes/teams.ts +10 -10
- package/src/routes/tokens.ts +30 -22
- 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 +22 -7
- package/src/routes/workspaces.ts +17 -16
- package/src/routing-policy-normalize.ts +1 -2
- package/src/routing-policy-push.ts +6 -6
- package/src/routing-step-defaults.ts +0 -2
- package/src/runner-token-mint-limit.ts +63 -0
- package/src/runtime-grant.ts +21 -13
- package/src/runtime-tokens.ts +59 -35
- package/src/secrets-broker/config.ts +1 -1
- package/src/secrets-broker/service.ts +2 -2
- package/src/security.ts +16 -21
- 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 +2 -2
- package/src/server.ts +26 -24
- 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/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 +27 -4
- package/src/services/idle-agent-digest.ts +17 -12
- package/src/services/idle-epics.ts +9 -10
- 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 +69 -72
- package/src/services/issue-refs.ts +10 -15
- package/src/services/kernel-timers-cutover-chaos-worker.ts +11 -8
- package/src/services/kernel-timers-ingress-chaos-worker.ts +6 -1
- package/src/services/kernel-timers-ingress.ts +4 -4
- 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 +25 -8
- 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 +17 -53
- 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 +57 -0
- package/src/services/plan-ci-recovery.ts +2 -55
- 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 +9 -3
- package/src/services/profile-trust.ts +6 -5
- package/src/services/project-config-read.ts +70 -0
- package/src/services/project-profile-instructions.ts +54 -0
- package/src/services/project.ts +11 -10
- package/src/services/prompt-templates.ts +6 -5
- 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/budget-baseline.json +4 -4
- 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 +74 -61
- 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-care-state.ts +2 -1
- package/src/services/self-effort-grant.ts +5 -25
- package/src/services/self-effort.ts +5 -5
- package/src/services/send-message.ts +21 -34
- package/src/services/shutdown-agent.ts +17 -14
- package/src/services/spawn-agent.ts +25 -43
- package/src/services/spawn-chain-inspector.ts +7 -14
- 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-policy.ts +68 -0
- 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 +8 -9
- 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-dispatch.ts +3 -0
- 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 +8 -17
- package/src/services/task-validation.ts +2 -2
- package/src/services/team-templates.ts +12 -11
- 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 +25 -20
- 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 +26 -13
- package/src/services/workflow-caller.ts +61 -4
- package/src/services/workflow-child-proof-worker.ts +1 -1
- package/src/services/workflow-ci-main.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 +5 -3
- package/src/services/workflow-effect-driver.ts +42 -17
- package/src/services/workflow-effects.ts +58 -37
- package/src/services/workflow-land-notice.ts +10 -0
- package/src/services/workflow-pause-text.ts +43 -0
- package/src/services/workflow-pins.ts +7 -4
- package/src/services/workflow-reconcile.ts +14 -11
- 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 +6 -3
- package/src/services/workflow-run.test-fixture.ts +1 -1
- package/src/services/workflow-runs.ts +61 -33
- package/src/services/workflow-supervisor-state.ts +26 -1
- package/src/services/workflow-supervisor.ts +11 -6
- package/src/services/workspace-recovery.ts +4 -3
- package/src/settings/registry.ts +1 -2
- package/src/spawn-admission.ts +10 -2
- package/src/spawn-command.ts +4 -4
- package/src/spawn-models.ts +10 -12
- package/src/spawn-placement.ts +28 -10
- package/src/spawn-targets.ts +9 -9
- package/src/sse-agent-status.ts +15 -6
- package/src/sse.ts +49 -24
- package/src/startup-context-injection.ts +62 -57
- 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-handoff.ts +4 -3
- package/src/steward-policy-cleanup.ts +9 -8
- package/src/steward.ts +9 -8
- package/src/task-dispatch-live.ts +6 -3
- package/src/task-dispatcher.ts +3 -3
- package/src/teams-config-store.ts +4 -3
- package/src/token-db-write.ts +10 -0
- 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/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 +26 -17
- 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 +4 -4
- 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/shipping-Bu8p1gEw.js +0 -2
- package/public/assets/store-BvtFdlGX.js +0 -9
- package/public/assets/use-project-list-B-T2Bnnn.js +0 -2
- package/public/assets/versioned-prompt-editor-Diu8BIaM.js +0 -8
- package/runner/src/agent-runner/http-liveness.ts +0 -85
- package/runner/src/gate-run-lease-probe.ts +0 -38
- package/src/db/claude-catalog-reconcile.ts +0 -27
- package/src/db/on-loop-write-transaction.ts +0 -34
- package/src/routing-model-aliases.ts +0 -21
|
@@ -11,8 +11,8 @@ import { projectSettingSourcesOn } from "./profile-home";
|
|
|
11
11
|
// the Claude re-injection channel and lists both names the cwd may carry.
|
|
12
12
|
const REPO_INSTRUCTION_FILES = ["CLAUDE.md", "AGENTS.md"] as const;
|
|
13
13
|
|
|
14
|
-
// Bound each re-injected file so a pathological repo doc
|
|
15
|
-
//
|
|
14
|
+
// Bound each re-injected file so a pathological repo doc cannot balloon the context.
|
|
15
|
+
// The composed append travels by private file (#3830). Mirrors Codex's
|
|
16
16
|
// project_doc_max_bytes default; oversized content is truncated with a loud marker
|
|
17
17
|
// rather than silently dropped.
|
|
18
18
|
const REPO_INSTRUCTIONS_MAX_BYTES = 64 * 1024;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { basename } from "node:path";
|
|
2
|
+
import { logger } from "./logger";
|
|
3
|
+
|
|
4
|
+
const warned = new Set<string>();
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The ONE place a provider's launch command is resolved. The launch and the pre-spawn login check
|
|
8
|
+
* both call it, so the check can never probe a different binary than the launch runs.
|
|
9
|
+
* A stored `claude-rig` command (the retired wrapper) is treated as plain `claude`, with one warning.
|
|
10
|
+
*/
|
|
11
|
+
export function resolveLaunchCommand(command: string): string {
|
|
12
|
+
if (basename(command) !== "claude-rig") return command;
|
|
13
|
+
if (!warned.has(command)) {
|
|
14
|
+
warned.add(command);
|
|
15
|
+
logger.warn("provider-command", `stored provider command "${command}" is the retired claude-rig wrapper; launching plain "claude" instead. Set the provider command to "claude" in the dashboard.`);
|
|
16
|
+
}
|
|
17
|
+
return "claude";
|
|
18
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { errMessage } from "@humwick/sdk";
|
|
2
|
+
import { checkProviderAuth } from "@humwick/sdk/provider-probe";
|
|
3
|
+
import { selectProviderConfigEnv } from "@humwick/sdk/child-env";
|
|
4
|
+
import type { ProviderAdapter, ProviderStatusEvent } from "./adapter";
|
|
5
|
+
import { logger } from "./logger";
|
|
6
|
+
import { hostSourcesFor } from "./host-asset-plan";
|
|
7
|
+
import { resolveLaunchCommand } from "./provider-command";
|
|
8
|
+
|
|
9
|
+
/** All real adapters share the managed-spawn login check, including replacements (#3751). */
|
|
10
|
+
export function withProviderSetup(adapter: ProviderAdapter): ProviderAdapter {
|
|
11
|
+
const spawn = adapter.spawn.bind(adapter);
|
|
12
|
+
adapter.spawn = async (config) => {
|
|
13
|
+
const env = selectProviderConfigEnv(config.providerConfig.env, hostSourcesFor(config).settings);
|
|
14
|
+
const auth = await checkProviderAuth(config.provider, undefined, env, resolveLaunchCommand(config.providerConfig.command));
|
|
15
|
+
if (!auth.ok) throw new Error(auth.reason);
|
|
16
|
+
return spawn(config);
|
|
17
|
+
};
|
|
18
|
+
return adapter;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function providerStartupFailure(error: unknown): ProviderStatusEvent {
|
|
22
|
+
const message = `Provider startup failed: ${errMessage(error)}`;
|
|
23
|
+
return { status: "error", reason: "provider-turn", providerState: {
|
|
24
|
+
state: "blocked", terminal: true, reason: "providerSetupRequired", label: "Provider setup required", message,
|
|
25
|
+
recommendedAction: "Complete the provider login and first-run setup on this host, then restart the runner.",
|
|
26
|
+
} };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function attemptProviderStartup(start: () => Promise<void>, failed: (status: ProviderStatusEvent) => void): Promise<void> {
|
|
30
|
+
try { await start(); }
|
|
31
|
+
catch (error) {
|
|
32
|
+
logger.error("startup", errMessage(error));
|
|
33
|
+
failed(providerStartupFailure(error));
|
|
34
|
+
}
|
|
35
|
+
}
|
package/runner/src/providers.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { withProviderSetup } from "./provider-setup";
|
|
1
2
|
import { ClaudeApiAdapter } from "./adapters/claude-api";
|
|
2
3
|
import type { LaunchMode, SpawnProvider } from "@humwick/sdk";
|
|
3
4
|
import { getAllManifests, supportedLaunchModesForProvider } from "@humwick/providers";
|
|
@@ -31,5 +32,5 @@ export function createProviderAdapter(provider: SpawnProvider, providerArgs: str
|
|
|
31
32
|
if (launchMode && !supportedLaunchModesForProvider(provider).includes(launchMode)) {
|
|
32
33
|
throw new Error(`${provider} does not support launchMode=${launchMode}`);
|
|
33
34
|
}
|
|
34
|
-
return registration.createAdapter(providerArgs, launchMode);
|
|
35
|
+
return withProviderSetup(registration.createAdapter(providerArgs, launchMode));
|
|
35
36
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { attemptProviderStartup } from "./provider-setup";
|
|
2
|
+
import { bootstrapUnreadMessages, reportUnavailableMessages } from "./agent-runner/inbox";
|
|
1
3
|
import { writeChildEnv } from "@humwick/sdk/env";
|
|
2
4
|
import { normalizeDeliverResult } from "./delivery-result";
|
|
3
5
|
import { TokenUsageReportCoverage } from "./agent-runner/token-usage-coverage";
|
|
@@ -9,7 +11,7 @@ import { PromptCommands, promptOrigin } from "./agent-runner/commands/prompt";
|
|
|
9
11
|
import type { NativeSelfResumeHandoff } from "./native-self-resume";
|
|
10
12
|
import { LifecyclePhase } from "./agent-runner/lifecycle-phase";
|
|
11
13
|
import { startRunnerMcpProxy, runnerWebToolLog, runnerWebSearch, runnerMcpHiddenTools } from "./runner-mcp-proxy";
|
|
12
|
-
import {
|
|
14
|
+
import { LivenessExchange } from "./agent-runner/liveness-exchange";
|
|
13
15
|
import { TaskClaims } from "./agent-runner/task-claims";
|
|
14
16
|
import { TurnReport } from "./agent-runner/turn-report";
|
|
15
17
|
import { SessionMirror } from "./agent-runner/session-mirror";
|
|
@@ -20,7 +22,7 @@ import { hostname } from "node:os";
|
|
|
20
22
|
import { resolveEnvLayers, selectProviderConfigEnv } from "@humwick/sdk/child-env";
|
|
21
23
|
import { createHash } from "node:crypto";
|
|
22
24
|
import { join } from "node:path";
|
|
23
|
-
import { type ContextState, type Message, type ProviderState, HELD_FOR_PAYLOAD_KEY, PROVIDER_SUBMIT_UNCONFIRMED, PROXY_AUTH_HOLD_KIND, errMessage, frameSuppressedFromTurn, stringValue } from "@humwick/sdk";
|
|
25
|
+
import { type ContextState, type Message, type ProviderState, HELD_FOR_PAYLOAD_KEY, PROVIDER_SUBMIT_UNCONFIRMED, PROXY_AUTH_HOLD_KIND, errMessage, frameSuppressedFromTurn, relayBusUrl, stringValue } from "@humwick/sdk";
|
|
24
26
|
import { exitRunner } from "./runner-exit";
|
|
25
27
|
import { isResumeWake, ProviderHoldEpisodes } from "./provider-hold";
|
|
26
28
|
import { contextStateFromProbeMetrics, quotaStateFromProbeMetrics } from "@humwick/sdk/context-probe";
|
|
@@ -34,7 +36,6 @@ import { AttachmentCacheSweep } from "./attachment-cache-sweep";
|
|
|
34
36
|
import { resolveTestRunRootPid, TEST_RUN_DEDUP_SWEEP_MS, TestRunDedupSweep } from "./test-run-dedup";
|
|
35
37
|
import { cachedGateRunCommandsForCwd } from "./gate-run-config";
|
|
36
38
|
import { AreaMemoryTracker } from "./area-memory";
|
|
37
|
-
import { GateRunLeaseProbe } from "./gate-run-lease-probe";
|
|
38
39
|
import { ClaimTracker } from "./claim-tracker";
|
|
39
40
|
import { ProviderQuotaHarvest } from "./adapters/provider-quota-harvest";
|
|
40
41
|
import { agentShellLaunchEnv } from "./adapters/project-shell";
|
|
@@ -87,7 +88,6 @@ import {
|
|
|
87
88
|
providerMonitorUnavailableMessage,
|
|
88
89
|
providerStateFromActiveWork,
|
|
89
90
|
registerWithinDeadline,
|
|
90
|
-
relayBusUrl,
|
|
91
91
|
runnerAgentStatus,
|
|
92
92
|
runnerBusErrorAction,
|
|
93
93
|
runnerMessageMatches,
|
|
@@ -217,14 +217,13 @@ export class AgentRunner {
|
|
|
217
217
|
private terminalProviderExit?: Record<string, unknown>;
|
|
218
218
|
private nativeSelfResume = new NativeSelfResumeTracker();
|
|
219
219
|
private readonly registration: Registration;
|
|
220
|
-
private readonly
|
|
220
|
+
private readonly liveness: LivenessExchange;
|
|
221
221
|
private readonly taskClaims: TaskClaims;
|
|
222
222
|
private delivering = false;
|
|
223
223
|
private drainTimer?: Timer;
|
|
224
224
|
private livenessReconcileTimer?: Timer;
|
|
225
225
|
private readonly attachmentCacheSweep: AttachmentCacheSweep;
|
|
226
226
|
private readonly testRunDedupSweep: TestRunDedupSweep;
|
|
227
|
-
private readonly gateRunLeaseProbe: GateRunLeaseProbe;
|
|
228
227
|
private processStartedAt = 0;
|
|
229
228
|
private providerSessionId = crypto.randomUUID();
|
|
230
229
|
// Last transcript path seen this session — used by end-of-session Insights (#184)
|
|
@@ -363,11 +362,11 @@ export class AgentRunner {
|
|
|
363
362
|
});
|
|
364
363
|
this.lifecycleMilestones = new LifecycleMilestones({
|
|
365
364
|
options: this.options, agentId: this.agentId, process: () => this.process,
|
|
366
|
-
stopAttachmentCacheSweep: () => this.attachmentCacheSweep.stop(), stopTestRunDedupSweep: () => this.testRunDedupSweep.stop(),
|
|
365
|
+
stopAttachmentCacheSweep: () => this.attachmentCacheSweep.stop(), stopTestRunDedupSweep: () => this.testRunDedupSweep.stop(),
|
|
367
366
|
disposeEmptyTurns: () => this.emptyTurns.dispose(), resetEmptyTurns: () => this.emptyTurns.reset(), resetLateClearRecovery: () => { this.lateClearRecovery.reset(); this.continuationFence.reset(); },
|
|
368
367
|
clearLifecycleAction: () => this.lifecycle.setLifecycleAction(undefined), setOffline: () => this.claims.setTerminalStatus("offline"), publishStatus: () => this.publishStatus(),
|
|
369
368
|
stopDrainTimer: () => { if (this.drainTimer) clearTimeout(this.drainTimer); this.drainTimer = undefined; }, stopSubmitRecoveryPoll: () => this.stopSubmitRecoveryPoll(),
|
|
370
|
-
stopTaskClaims: () => this.taskClaims.stop(),
|
|
369
|
+
stopTaskClaims: () => this.taskClaims.stop(), stopLiveness: () => this.liveness.stop(), stopCredentials: () => this.credentials.stop(),
|
|
371
370
|
disarmBusyLivenessReconcile: () => this.disarmBusyLivenessReconcile(), disarmBusyReconciler: () => this.busyReconciler.disarm(),
|
|
372
371
|
disposeProviderInput: () => this.providerInput.dispose(), disposeParkPosts: () => this.parkPosts.dispose(),
|
|
373
372
|
stopReasoningTail: () => this.sessionMirror.stopReasoningTail(), clearNativeSessionCapture: () => this.sessionMirror.clearNativeSessionCapture(), stopObligationCache: () => this.obligationCache.stop(),
|
|
@@ -409,14 +408,12 @@ export class AgentRunner {
|
|
|
409
408
|
const sessionProviderPid = () => resolveTestRunRootPid(this.process, (managedProcess) => this.options.adapter.resolveBusyPid?.(managedProcess));
|
|
410
409
|
// #2461 — ancestry alone made this sweep a no-op for `relay_run` gate runs (a disjoint tree
|
|
411
410
|
// under the orchestrator). It now also owns anything env-tagged with this agent's id, classifies
|
|
412
|
-
// against the repo's CONFIGURED gate commands, and
|
|
411
|
+
// against the repo's CONFIGURED gate commands, and reads live leases during each sweep. The
|
|
413
412
|
// config read is cached for the session — it is a repo file, so re-reading it every 15s for the
|
|
414
|
-
// agent's whole life buys nothing.
|
|
415
|
-
this.gateRunLeaseProbe = new GateRunLeaseProbe(this.agentId, TEST_RUN_DEDUP_SWEEP_MS);
|
|
413
|
+
// agent's whole life buys nothing.
|
|
416
414
|
this.testRunDedupSweep = new TestRunDedupSweep({
|
|
417
415
|
rootPid: sessionProviderPid, agentId: () => this.agentId,
|
|
418
416
|
gateCommands: () => cachedGateRunCommandsForCwd(this.options.cwd),
|
|
419
|
-
leaseHolderPid: () => this.gateRunLeaseProbe.pid(),
|
|
420
417
|
protectedPids: () => [process.pid], log: (message) => this.logRunnerDiagnostic(message),
|
|
421
418
|
});
|
|
422
419
|
this.context.configureLogger();
|
|
@@ -435,11 +432,11 @@ export class AgentRunner {
|
|
|
435
432
|
void this.proxy?.refreshTools().catch(() => {});
|
|
436
433
|
},
|
|
437
434
|
resumeLivenessAndPublishRotation: (status, jti) => {
|
|
438
|
-
this.
|
|
435
|
+
this.liveness.resetAuthFailure();
|
|
439
436
|
// An earlier auth failure may have stopped the liveness loop; restart it so the
|
|
440
|
-
// agent reports live again on the fresh token.
|
|
437
|
+
// agent reports live again on the fresh token. startLiveness clears any
|
|
441
438
|
// existing timer first, so this is safe on the normal (proactive) renew path too.
|
|
442
|
-
this.
|
|
439
|
+
this.startLiveness();
|
|
443
440
|
this.pendingTimelineEvent = { status, id: jti, timestamp: Date.now() };
|
|
444
441
|
this.bus.reconnectTransport(status === "runtime-token-reminted" ? "runtime token re-minted" : "runtime token renewed");
|
|
445
442
|
this.publishStatus();
|
|
@@ -450,6 +447,7 @@ export class AgentRunner {
|
|
|
450
447
|
},
|
|
451
448
|
logRunnerDiagnostic: (message) => this.logRunnerDiagnostic(message),
|
|
452
449
|
reportBackgroundRejection: (scope, status, title, error) => this.reportBackgroundRejection(scope, status, title, error),
|
|
450
|
+
onTerminalAuthFailure: (reason) => { logger.error("runner", `exiting: ${reason}`); this.options.onProviderExit?.(1, reason); },
|
|
453
451
|
});
|
|
454
452
|
const token = this.credentials.current();
|
|
455
453
|
if (token) publishRuntimeTokenForCli(token, this.credentials.expiresAt, (message) => this.logRunnerDiagnostic(message));
|
|
@@ -470,14 +468,14 @@ export class AgentRunner {
|
|
|
470
468
|
// #2514 — the per-provider config env carries a dedicated-home provider's (claude-b's) own
|
|
471
469
|
// credential, which the quota harvest needs to key its reports under the B subscription.
|
|
472
470
|
providerConfigEnv: () => this.options.providerConfig.env,
|
|
473
|
-
http: () => this.http,
|
|
474
471
|
});
|
|
475
|
-
this.
|
|
476
|
-
http: this.http, agentId: this.agentId, instanceId: options.instanceId, logIntervalMs: HTTP_LIVENESS_LOG_INTERVAL_MS,
|
|
472
|
+
this.liveness = new LivenessExchange({
|
|
473
|
+
http: this.http, bus: () => this.bus, agentId: this.agentId, instanceId: options.instanceId, logIntervalMs: HTTP_LIVENESS_LOG_INTERVAL_MS,
|
|
477
474
|
isStopped: () => this.lifecycle.stopped, isTerminalStatusLatched: () => this.lifecycle.terminalStatusLatched,
|
|
478
475
|
currentStatus: () => this.claims.currentStatus(),
|
|
479
|
-
|
|
480
|
-
|
|
476
|
+
sampleQuota: () => this.providerQuotaHarvest.sample(),
|
|
477
|
+
acceptQuota: (report, result) => this.providerQuotaHarvest.accept(report, result),
|
|
478
|
+
enqueueMessage: (message) => this.enqueueMessage(message), triggerEffort: () => this.effort.trigger(),
|
|
481
479
|
recoverRuntimeTokenAfterAuthFailure: (source) => this.credentials.recoverRuntimeTokenAfterAuthFailure(source),
|
|
482
480
|
logRunnerDiagnostic: (message) => this.logRunnerDiagnostic(message),
|
|
483
481
|
});
|
|
@@ -733,16 +731,17 @@ export class AgentRunner {
|
|
|
733
731
|
this.ensureScratch();
|
|
734
732
|
void sweepRunnerStaleScratch({ listAgents: () => this.http.listAgents(), agentId: this.agentId, cwd: this.options.cwd, fallbackBaseDir: orchestratorBaseDirFromEnv(), log: (message) => this.logRunnerDiagnostic(message) });
|
|
735
733
|
this.scheduleAttachmentCacheSweep();
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
734
|
+
await attemptProviderStartup(async () => {
|
|
735
|
+
this.adoptProcess(await this.spawnProvider());
|
|
736
|
+
this.registration.writeRunnerInfoFile();
|
|
737
|
+
await this.promptCommands.startLaunchSeededTurn();
|
|
738
|
+
this.publishStatus();
|
|
739
|
+
await this.promptCommands.deliverInitialPrompt();
|
|
740
|
+
}, (status) => this.setProviderStatus(status));
|
|
741
741
|
await this.bootstrapUnreadMessages();
|
|
742
742
|
this.taskClaims.start();
|
|
743
|
-
this.
|
|
743
|
+
this.startLiveness();
|
|
744
744
|
this.testRunDedupSweep.start();
|
|
745
|
-
this.gateRunLeaseProbe.start();
|
|
746
745
|
this.credentials.scheduleRuntimeTokenRenewal();
|
|
747
746
|
this.scheduleDrain();
|
|
748
747
|
}
|
|
@@ -790,6 +789,7 @@ export class AgentRunner {
|
|
|
790
789
|
}
|
|
791
790
|
|
|
792
791
|
private handleBusRegistered(): void {
|
|
792
|
+
if (this.process) this.publishStatus();
|
|
793
793
|
void this.nativeSelfResume.reconcile((id) => this.http.request("GET", `/api/commands/${encodeURIComponent(id)}`)).catch((error) => this.sessionLog(`compact settlement reconcile: ${errMessage(error)}`));
|
|
794
794
|
// #2973 — a re-register follows a relay restart (a deploy): re-list so changed tools reach the agent.
|
|
795
795
|
void this.proxy?.refreshTools().catch(() => {}); this.effort.trigger();
|
|
@@ -941,14 +941,7 @@ export class AgentRunner {
|
|
|
941
941
|
this.scheduleDrain();
|
|
942
942
|
}
|
|
943
943
|
|
|
944
|
-
private
|
|
945
|
-
try {
|
|
946
|
-
const messages = await this.http.pollMessages({ for: this.agentId, unread: true, limit: 100, turnDelivery: true });
|
|
947
|
-
for (const message of messages) this.enqueueMessage(message);
|
|
948
|
-
} catch (error) {
|
|
949
|
-
logger.error("runner", `inbox bootstrap failed: ${error}`);
|
|
950
|
-
}
|
|
951
|
-
}
|
|
944
|
+
private bootstrapUnreadMessages = () => bootstrapUnreadMessages(this.http, this.agentId, (message) => this.enqueueMessage(message));
|
|
952
945
|
|
|
953
946
|
private scheduleDrain(delayMs = 0): void {
|
|
954
947
|
if (this.lifecycle.stopped || this.drainTimer || this.deliverySubmitHold || this.submitResendInFlight) return;
|
|
@@ -1363,7 +1356,8 @@ export class AgentRunner {
|
|
|
1363
1356
|
private async drainMessages(): Promise<void> {
|
|
1364
1357
|
if (this.lifecycle.stopped || this.delivering || this.deliverySubmitHold || this.submitResendInFlight || this.pendingMessages.size === 0) return;
|
|
1365
1358
|
if (!this.process) {
|
|
1366
|
-
this.
|
|
1359
|
+
if (this.terminalFailure) await reportUnavailableMessages(this.http, this.agentId, this.pendingMessages, this.settledMessageIds, this.terminalFailure.message);
|
|
1360
|
+
if (this.pendingMessages.size) this.scheduleDrain(500);
|
|
1367
1361
|
return;
|
|
1368
1362
|
}
|
|
1369
1363
|
this.delivering = true;
|
|
@@ -2822,7 +2816,7 @@ export class AgentRunner {
|
|
|
2822
2816
|
?? (activeWork.length === 0 ? this.emptyTurns.providerState() ?? null : null);
|
|
2823
2817
|
const published = this.publishRunnerStatus({
|
|
2824
2818
|
agentStatus,
|
|
2825
|
-
ready: agentStatus !== "offline" && !this.lifecycle.stopped && !teardownLifecycle && !this.startupPaneDialog && !this.deliverySubmitHold,
|
|
2819
|
+
ready: Boolean(this.process) && agentStatus !== "offline" && !this.lifecycle.stopped && !teardownLifecycle && !this.startupPaneDialog && !this.deliverySubmitHold,
|
|
2826
2820
|
meta: {
|
|
2827
2821
|
...runnerIdentityMeta(this.options, { tmuxSession: providerTerminalSession(this.process), tmuxSocket: providerTerminalSocket(this.process), auth: { profileId: this.credentials.profileId, jti: this.credentials.jti, expiresAt: this.credentials.expiresAt } }, "status"),
|
|
2828
2822
|
lifecycleAction: this.lifecycle.lifecycleAction ?? null,
|
|
@@ -2866,7 +2860,7 @@ export class AgentRunner {
|
|
|
2866
2860
|
if (published && this.pendingTimelineEvent === timelineEvent) this.pendingTimelineEvent = undefined;
|
|
2867
2861
|
}
|
|
2868
2862
|
|
|
2869
|
-
private
|
|
2863
|
+
private startLiveness(): void { this.liveness.start(); }
|
|
2870
2864
|
|
|
2871
2865
|
private logRunnerDiagnostic(message: string): void { this.context.logRunnerDiagnostic(message); }
|
|
2872
2866
|
private sessionLog(message: string): void { this.context.sessionLog(message); }
|
|
@@ -133,14 +133,6 @@ export function csvTags(raw: string | undefined): string[] {
|
|
|
133
133
|
return (raw || "").split(",").map((tag) => tag.trim()).filter(Boolean);
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
export function relayBusUrl(relayUrl: string): string {
|
|
137
|
-
const url = new URL(relayUrl);
|
|
138
|
-
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
|
|
139
|
-
url.pathname = `${url.pathname.replace(/\/+$/, "")}/bus`;
|
|
140
|
-
url.search = "";
|
|
141
|
-
return url.toString();
|
|
142
|
-
}
|
|
143
|
-
|
|
144
136
|
export function runnerAgentStatus(status: "idle" | "busy" | "offline" | "error"): "idle" | "busy" | "offline" {
|
|
145
137
|
return status === "error" ? "offline" : status;
|
|
146
138
|
}
|
|
@@ -194,9 +194,13 @@ export function reapSessionScratch(target: SessionScratchTarget): void {
|
|
|
194
194
|
// scratch dir reap to avoid leaking one file per spawn.
|
|
195
195
|
export function reapSessionLauncher(target: SessionLauncherTarget): string[] {
|
|
196
196
|
const removed: string[] = [];
|
|
197
|
-
|
|
197
|
+
const launchers = dedupePaths([
|
|
198
198
|
target.launcherScript,
|
|
199
199
|
target.tmuxSession ? launcherScriptPathForSession(target.tmuxSession, target.launcherDir) : undefined,
|
|
200
|
+
]);
|
|
201
|
+
for (const path of dedupePaths([
|
|
202
|
+
...launchers,
|
|
203
|
+
...launchers.flatMap(path => [`${path}.exit-code`, `${path}.exit-code.stderr`]),
|
|
200
204
|
target.tmuxSession ? launcherGatePathForSession(target.tmuxSession, target.launcherDir) : undefined,
|
|
201
205
|
])) {
|
|
202
206
|
try {
|
|
@@ -286,7 +290,7 @@ export async function sweepStaleLaunchersAsync(opts: LauncherSweepOptions): Prom
|
|
|
286
290
|
try {
|
|
287
291
|
const current = await stat(scriptPath);
|
|
288
292
|
if (!current.isFile() || opts.now - current.mtimeMs < minAge) continue;
|
|
289
|
-
const agentId = await launcherAgentId(scriptPath);
|
|
293
|
+
const agentId = await launcherAgentId(scriptPath.replace(/\.exit-code(?:\.stderr)?$/, ""));
|
|
290
294
|
if (agentId && opts.keepAgentIds.has(agentId)) continue;
|
|
291
295
|
await rm(scriptPath, { force: true });
|
|
292
296
|
removed.push(scriptPath);
|
|
@@ -105,6 +105,7 @@ export function parseRunnerCliArgs(
|
|
|
105
105
|
else if (arg === "--model-record-provider-model" && ownArgs[i + 1]) modelRecordRaw.providerModel = ownArgs[++i];
|
|
106
106
|
else if (arg === "--model-record-qualified" && ownArgs[i + 1]) modelRecordRaw.qualifiedModel = ownArgs[++i];
|
|
107
107
|
else if (arg === "--model-record-effort" && ownArgs[i + 1]) modelRecordRaw.effort = ownArgs[++i];
|
|
108
|
+
else if (arg === "--model-record-efforts" && ownArgs[i + 1]) { try { modelRecordRaw.efforts = JSON.parse(ownArgs[++i]!); } catch {} }
|
|
108
109
|
else if (arg === "--model-record-window" && ownArgs[i + 1]) {
|
|
109
110
|
const parsed = Number(ownArgs[++i]);
|
|
110
111
|
if (Number.isSafeInteger(parsed) && parsed > 0) modelRecordRaw.contextWindowTokens = parsed;
|
|
@@ -143,5 +144,5 @@ export function parseRunnerCliArgs(
|
|
|
143
144
|
}
|
|
144
145
|
|
|
145
146
|
export function runnerHelp(provider: string): string {
|
|
146
|
-
return `${provider}-
|
|
147
|
+
return `${provider}-humwick [--headless] [--launch-mode interactive|headless] [--model ALIAS] [--effort LEVEL] [--context-window-tokens N] [--model-record-alias A --model-record-provider-model M --model-record-qualified Q --model-record-effort E --model-record-window N --model-record-max-output N --model-record-threshold JSON] [--rig NAME] [--profile NAME] [--cwd PATH] [--relay-url URL] [--approval MODE] [--label NAME] [--agent-id ID] [--prompt TEXT] [--system-prompt-append TEXT] [--tags a,b] [--caps x,y] [-- provider-args...]`;
|
|
147
148
|
}
|
|
@@ -1,41 +1,14 @@
|
|
|
1
1
|
import { relayEnv } from "@humwick/sdk/env";
|
|
2
|
-
// #
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// broad, a single run takes 10-15 minutes — and the agent starts the NEXT run long before the
|
|
6
|
-
// previous one finishes. The stacked runs saturate the host: each one holds a gate slot, forks
|
|
7
|
-
// its own shard processes, and the oldest run's result is thrown away the moment it lands.
|
|
8
|
-
// Instructions don't fix this (an agent rationalizes around them), so the bound has to be
|
|
9
|
-
// structural and live BELOW the agent: the runner watches its own session's process tree and,
|
|
10
|
-
// whenever it sees more than one independent test run, kills every run except the newest.
|
|
11
|
-
//
|
|
12
|
-
// Scoping is per-agent BY CONSTRUCTION: the sweep only ever looks at processes it can PROVE belong
|
|
13
|
-
// to this agent — descendants of this session's provider process (the tmux pane pid / direct child
|
|
14
|
-
// pid the adapter already resolves for busy-liveness), plus processes carrying this agent's
|
|
15
|
-
// AGENT_RELAY_ID in their environment. A sibling agent's runs satisfy neither test, so this can
|
|
16
|
-
// never fratricide the fleet the way a host-wide `pkill -f` would (#753). It is also
|
|
17
|
-
// provider-agnostic — nothing here knows whether the tree belongs to Claude or Codex.
|
|
18
|
-
//
|
|
19
|
-
// #2461 — the env-tag half of that ownership test is new, and it is why this file exists at all
|
|
20
|
-
// after the lease landed. Ancestry ALONE made this a no-op for the case the issue reports: a
|
|
21
|
-
// `relay_run` gate run executes under the ORCHESTRATOR daemon, a tree that shares no ancestor with
|
|
22
|
-
// the provider pane, so a descendant-scoped sweep could never see it. The orchestrator now stamps
|
|
23
|
-
// AGENT_RELAY_ID onto those children, which is what makes them attributable here.
|
|
24
|
-
//
|
|
25
|
-
// This sweep is now the BACKSTOP, not the primary mechanism. Kill-replace happens at LAUNCH, in
|
|
26
|
-
// sdk/src/gate-run-lease.ts, entered from `scripts/gate-slot` and the orchestrator. What is left
|
|
27
|
-
// for the sweep is the residual shape neither front door sees: a gate run started straight from the
|
|
28
|
-
// provider shell in a repo that does not route through `gate.sh`. It is 15s-late by construction —
|
|
29
|
-
// that is the documented coverage gap, tracked for a launch-exact PATH shim in the follow-up issue.
|
|
30
|
-
// When a live lease holder exists it is AUTHORITATIVE: the sweep keeps it and kills the rest, so
|
|
31
|
-
// the two mechanisms can never disagree about which run survives.
|
|
2
|
+
// #3754 — the lease owns launch-time replacement. The sweep only deduplicates
|
|
3
|
+
// unleased runs with the same captured checkout/revision; ancestry proves ownership,
|
|
4
|
+
// but cannot prove two commands tested the same tree. Live leases protect whole runs.
|
|
32
5
|
import { execFile } from "node:child_process";
|
|
33
6
|
import { readFileSync, readdirSync } from "node:fs";
|
|
34
7
|
import { promisify } from "node:util";
|
|
35
8
|
import { errMessage } from "@humwick/sdk";
|
|
36
9
|
import { killPid, waitForPidsExit } from "@humwick/sdk/process-utils";
|
|
37
10
|
import { classifyGateRun, isTestRunCommand, type GateRunCommands } from "@humwick/sdk/gate-run-classify";
|
|
38
|
-
import { GATE_RUN_AGENT_ENV } from "@humwick/sdk/gate-run-lease";
|
|
11
|
+
import { GATE_RUN_AGENT_ENV, GATE_RUN_CONTEXT_ENV, GATE_RUN_HELD_ENV, readLiveGateRunHolderPids } from "@humwick/sdk/gate-run-lease";
|
|
39
12
|
import type { ManagedProcess } from "./adapter";
|
|
40
13
|
|
|
41
14
|
// Re-exported so the sweep and both lease front doors share ONE definition of "is this a test run".
|
|
@@ -215,6 +188,9 @@ export interface TestRunDedupScope {
|
|
|
215
188
|
/** Classifier override. Defaults to the argv-shape heuristic; the sweep passes a classifier bound
|
|
216
189
|
* to the repo's CONFIGURED gate commands so a foreign runner (`pnpm tier:run …`) is matched too. */
|
|
217
190
|
isGateRun?: (args: string) => boolean;
|
|
191
|
+
/** Launch-time checkout/revision identity. Missing identity cannot prove a duplicate. */
|
|
192
|
+
contextByPid?: ReadonlyMap<number, string>;
|
|
193
|
+
leasedPids?: readonly number[];
|
|
218
194
|
}
|
|
219
195
|
|
|
220
196
|
export function planTestRunDedup(
|
|
@@ -278,29 +254,34 @@ export function planTestRunDedup(
|
|
|
278
254
|
}
|
|
279
255
|
if (runRoots.length < 2) return EMPTY_PLAN;
|
|
280
256
|
|
|
281
|
-
//
|
|
282
|
-
//
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
257
|
+
// A lease may belong to a child of the outer shell. Spare the WHOLE run, including
|
|
258
|
+
// ancestors and descendants, rather than signalling its owner indirectly (#3754).
|
|
259
|
+
const leased = new Set(scope.leasedPids ?? []);
|
|
260
|
+
const groups = new Map<string, number[]>();
|
|
261
|
+
const leasedRoots = new Set<number>();
|
|
262
|
+
for (const pid of runRoots) {
|
|
263
|
+
if (subtree(pid).some((child) => leased.has(child))) leasedRoots.add(pid);
|
|
264
|
+
const context = scope.contextByPid ? scope.contextByPid.get(pid) : "legacy";
|
|
265
|
+
if (!context) continue;
|
|
266
|
+
const group = groups.get(context) ?? [];
|
|
267
|
+
group.push(pid);
|
|
268
|
+
groups.set(context, group);
|
|
269
|
+
}
|
|
270
|
+
const staleRoots: number[] = [];
|
|
271
|
+
let keptPid: number | undefined;
|
|
272
|
+
for (const group of groups.values()) {
|
|
273
|
+
if (group.length < 2) continue;
|
|
274
|
+
const leaseKeep = scope.keepPid !== undefined && group.includes(scope.keepPid) ? scope.keepPid : undefined;
|
|
275
|
+
const newest = group.find((pid) => leasedRoots.has(pid)) ?? leaseKeep ?? group.reduce((current, pid) => {
|
|
276
|
+
const candidate = byPid.get(pid)!;
|
|
277
|
+
const prior = byPid.get(current)!;
|
|
278
|
+
return candidate.elapsedSeconds < prior.elapsedSeconds
|
|
279
|
+
|| (candidate.elapsedSeconds === prior.elapsedSeconds && pid > current) ? pid : current;
|
|
280
|
+
});
|
|
281
|
+
keptPid = newest;
|
|
282
|
+
staleRoots.push(...group.filter((pid) => pid !== newest && !leasedRoots.has(pid)));
|
|
283
|
+
}
|
|
284
|
+
staleRoots.sort((a, b) => a - b);
|
|
304
285
|
if (staleRoots.length === 0) return EMPTY_PLAN;
|
|
305
286
|
|
|
306
287
|
const protectedSet = new Set([rootPid, ...protectedPids]);
|
|
@@ -334,6 +315,17 @@ export async function readProcessTable(timeoutMs: number = PROCESS_TABLE_TIMEOUT
|
|
|
334
315
|
return stdout;
|
|
335
316
|
}
|
|
336
317
|
|
|
318
|
+
/** Only launch-time metadata can distinguish revisions; today's HEAD cannot (#3754). */
|
|
319
|
+
export function readTestRunContext(pid: number): { context?: string; leased?: boolean } {
|
|
320
|
+
try {
|
|
321
|
+
const env = Object.fromEntries(readFileSync(`/proc/${pid}/environ`, "utf8").split("\0").map((entry) => {
|
|
322
|
+
const equals = entry.indexOf("=");
|
|
323
|
+
return [entry.slice(0, equals), entry.slice(equals + 1)];
|
|
324
|
+
}));
|
|
325
|
+
return { context: relayEnv(env, GATE_RUN_CONTEXT_ENV), leased: !!relayEnv(env, GATE_RUN_HELD_ENV) };
|
|
326
|
+
} catch { return {}; }
|
|
327
|
+
}
|
|
328
|
+
|
|
337
329
|
export interface TestRunDedupDeps {
|
|
338
330
|
/** Resolve this session's provider pid. undefined ⇒ ancestry proves nothing; the env tag may. */
|
|
339
331
|
rootPid: () => number | undefined;
|
|
@@ -344,6 +336,8 @@ export interface TestRunDedupDeps {
|
|
|
344
336
|
gateCommands?: () => GateRunCommands;
|
|
345
337
|
/** The live lease holder pid, when one exists — authoritative over newest-wins. */
|
|
346
338
|
leaseHolderPid?: () => number | undefined;
|
|
339
|
+
readRunContext?: (pid: number) => { context?: string; leased?: boolean };
|
|
340
|
+
liveLeasePids?: () => Promise<number[]>;
|
|
347
341
|
collectOwnedPids?: (agentId: string) => Promise<number[]>;
|
|
348
342
|
readProcessTable?: () => Promise<string>;
|
|
349
343
|
kill?: (pid: number, signal: "SIGTERM" | "SIGKILL") => void;
|
|
@@ -374,8 +368,17 @@ export async function runTestRunDedupSweep(deps: TestRunDedupDeps): Promise<numb
|
|
|
374
368
|
}
|
|
375
369
|
|
|
376
370
|
const gateCommands = deps.gateCommands?.() ?? {};
|
|
377
|
-
const
|
|
378
|
-
|
|
371
|
+
const rows = parseProcessTable(table);
|
|
372
|
+
const contextByPid = new Map<number, string>();
|
|
373
|
+
const leasedPids = await (deps.liveLeasePids ?? (() => agentId ? readLiveGateRunHolderPids(agentId) : Promise.resolve([])))();
|
|
374
|
+
for (const row of rows) {
|
|
375
|
+
if (classifyGateRun(row.args, gateCommands) === null) continue;
|
|
376
|
+
const context = (deps.readRunContext ?? readTestRunContext)(row.pid);
|
|
377
|
+
if (context.context) contextByPid.set(row.pid, context.context);
|
|
378
|
+
if (context.leased) leasedPids.push(row.pid);
|
|
379
|
+
}
|
|
380
|
+
const plan = planTestRunDedup(rows, rootPid, deps.protectedPids?.() ?? [], {
|
|
381
|
+
ownedPids, contextByPid, leasedPids,
|
|
379
382
|
keepPid: deps.leaseHolderPid?.(),
|
|
380
383
|
isGateRun: (args) => classifyGateRun(args, gateCommands) !== null,
|
|
381
384
|
});
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { getManifest } from "@humwick/providers";
|
|
1
3
|
import type { SpawnProvider } from "@humwick/sdk";
|
|
2
4
|
import type { RunnerSpawnConfig, SpawnArgs } from "../src/adapter";
|
|
3
5
|
import { codexLaunchContext } from "../src/adapters/codex";
|
|
@@ -16,8 +18,8 @@ export function systemPromptAppendFromSpawnArgs(
|
|
|
16
18
|
spawnArgs: Pick<SpawnArgs, "args">,
|
|
17
19
|
runnerConfig: RunnerSpawnConfig,
|
|
18
20
|
): string {
|
|
19
|
-
return provider === "claude"
|
|
20
|
-
? flagValue(spawnArgs.args, "--append-system-prompt")
|
|
21
|
+
return getManifest(provider)?.shim?.kind === "claude-relay"
|
|
22
|
+
? readFileSync(flagValue(spawnArgs.args, "--append-system-prompt-file")!, "utf8")
|
|
21
23
|
: codexLaunchContext({ meta: { config: runnerConfig } }) ?? "";
|
|
22
24
|
}
|
|
23
25
|
|
|
@@ -91,7 +91,8 @@ export class RunnerHttp {
|
|
|
91
91
|
});
|
|
92
92
|
for (const method of ["listPromptTemplates", "listReplyObligations", "listAgents", "pollMessages"] as const) this.when(method, async () => []);
|
|
93
93
|
this.when("getProviderQuotaConfig", async () => ({}));
|
|
94
|
-
|
|
94
|
+
this.when("heartbeat", async () => ({ ok: true, messages: [] }));
|
|
95
|
+
for (const method of ["setStatus", "setReady", "markRead"] as const) this.when(method, async () => {});
|
|
95
96
|
this.when("recordMessageDeliveryAttempt", async () => ({}) as Awaited<ReturnType<HumwickHttpClient["recordMessageDeliveryAttempt"]>>);
|
|
96
97
|
this.when("claimMessageResult", async () => ({ ok: true, claimExpiresAt: Date.now() + 60_000 }));
|
|
97
98
|
this.when("updateTaskStatus", async () => ({}) as Awaited<ReturnType<HumwickHttpClient["updateTaskStatus"]>>);
|
package/scripts/cd-config.ts
CHANGED
|
@@ -172,6 +172,14 @@ export function claimCanonicalDeployLease(input: { commitSha: string; version: s
|
|
|
172
172
|
return tryBeginDeployEvent(input);
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
/** A scoped release step borrows its parent's lease, including when deploying a rollback SHA (#3470). */
|
|
176
|
+
export function attachCutoverDeployLease(id: string): DeployEvent {
|
|
177
|
+
openCanonicalDeployLedger();
|
|
178
|
+
const event = getDeployEvent(id);
|
|
179
|
+
if (!event || event.status !== "pending" || !event.initiatedBy.startsWith("humwick-cutover:")) throw new Error(`Not a pending cutover lease: ${id}`);
|
|
180
|
+
return event;
|
|
181
|
+
}
|
|
182
|
+
|
|
175
183
|
/**
|
|
176
184
|
* #2105 — stamp THIS driver process onto the lease it just claimed, so cd-watcher's reconcile can
|
|
177
185
|
* reclaim a stranded row on executor liveness (minutes) instead of the 2h lease TTL. Best-effort by
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import { relayEnv } from "@humwick/sdk/env";
|
|
2
|
+
import { relayEnv, writeChildEnv } from "@humwick/sdk/env";
|
|
3
3
|
/**
|
|
4
4
|
* #2461 — the gate-run lease CLI. ONE implementation of the per-agent single-run invariant.
|
|
5
5
|
*
|
|
@@ -49,6 +49,8 @@ import { readFileSync } from "node:fs";
|
|
|
49
49
|
import { join } from "node:path";
|
|
50
50
|
import {
|
|
51
51
|
claimGateRunLease,
|
|
52
|
+
gateRunContext,
|
|
53
|
+
GATE_RUN_CONTEXT_ENV,
|
|
52
54
|
gateRunLeaseDir,
|
|
53
55
|
gateRunLeaseEnabled,
|
|
54
56
|
gateRunWasSuperseded,
|
|
@@ -136,17 +138,18 @@ export async function claim(options: {
|
|
|
136
138
|
// here, which is one read and therefore no disagreement.
|
|
137
139
|
const category = carried ?? classifyGateRun(options.command, gateCommandsForCwd(options.cwd));
|
|
138
140
|
if (!category) return { state: "skip", dir: "", epoch: "" };
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
// Preflight captured HEAD. Reuse that identity even if the checkout moves before claim (#3754).
|
|
142
|
+
const carriedContext = options.dir?.split("/").at(-1);
|
|
143
|
+
const context = options.dir ? (/^[a-f0-9]{64}$/.test(carriedContext ?? "") ? carriedContext : undefined) : gateRunContext(options.cwd);
|
|
144
|
+
const scopedEnv = writeChildEnv({ ...env }, { [GATE_RUN_CONTEXT_ENV]: context });
|
|
145
|
+
if (options.dir && options.dir !== gateRunLeaseDir(agentId, scopedEnv)) return { state: "skip", dir: "", epoch: "" };
|
|
143
146
|
|
|
144
147
|
const handle = await claimGateRunLease({
|
|
145
148
|
agentId,
|
|
146
149
|
category,
|
|
147
150
|
command: options.command,
|
|
148
151
|
selfPid: options.pid,
|
|
149
|
-
env,
|
|
152
|
+
env: scopedEnv,
|
|
150
153
|
...(options.epoch ? { epoch: options.epoch } : {}),
|
|
151
154
|
...clampedLockWait(env),
|
|
152
155
|
...(options.log ? { log: options.log } : {}),
|
|
@@ -190,7 +193,7 @@ export function preflight(options: { cwd: string; command: string; env?: Record<
|
|
|
190
193
|
if ((relayEnv(env, GATE_RUN_HELD_ENV) ?? "").trim()) return { state: "nested", dir: gateRunLeaseDir(agentId, env), category: "" };
|
|
191
194
|
const category = classifyGateRun(options.command, gateCommandsForCwd(options.cwd));
|
|
192
195
|
if (!category) return { state: "skip", dir: "", category: "" };
|
|
193
|
-
return { state: "claim", dir: gateRunLeaseDir(agentId, env), category };
|
|
196
|
+
return { state: "claim", dir: gateRunLeaseDir(agentId, env, options.cwd), category };
|
|
194
197
|
}
|
|
195
198
|
|
|
196
199
|
/** A carried category is honoured only if it is one this protocol actually has. Anything else is
|
package/scripts/gate.sh
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env sh
|
|
2
2
|
# Explicit override, managed native delegate, then the bundled compatibility launcher.
|
|
3
|
+
# CI runs this checkout's own launcher: the managed delegate execs the host's DEPLOYED runtime,
|
|
4
|
+
# so a broken deploy would turn every CI run red (T7319). Both share the host admission ledger.
|
|
3
5
|
GS="${GATE_SLOT_BIN:-}"
|
|
6
|
+
BUNDLED="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)/gate-slot"
|
|
7
|
+
[ -x "$GS" ] || { [ "${GITHUB_ACTIONS:-}" = true ] && GS="$BUNDLED"; }
|
|
4
8
|
[ -x "$GS" ] || GS="$HOME/.local/bin/gate-slot"
|
|
5
|
-
[ -x "$GS" ] || GS="$
|
|
9
|
+
[ -x "$GS" ] || GS="$BUNDLED"
|
|
6
10
|
exec "$GS" "$@"
|