botmux 3.18.6 → 3.18.7
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/dist/.runtime-build-id +1 -1
- package/dist/adapters/backend/riff-backend.d.ts +158 -0
- package/dist/adapters/backend/riff-backend.d.ts.map +1 -1
- package/dist/adapters/backend/riff-backend.js +330 -7
- package/dist/adapters/backend/riff-backend.js.map +1 -1
- package/dist/adapters/backend/sandbox.d.ts +42 -0
- package/dist/adapters/backend/sandbox.d.ts.map +1 -1
- package/dist/adapters/backend/sandbox.js +95 -5
- package/dist/adapters/backend/sandbox.js.map +1 -1
- package/dist/adapters/cli/codex-app.d.ts.map +1 -1
- package/dist/adapters/cli/codex-app.js +2 -1
- package/dist/adapters/cli/codex-app.js.map +1 -1
- package/dist/adapters/cli/dsh.d.ts.map +1 -1
- package/dist/adapters/cli/dsh.js +2 -1
- package/dist/adapters/cli/dsh.js.map +1 -1
- package/dist/adapters/cli/mir.d.ts.map +1 -1
- package/dist/adapters/cli/mir.js +2 -1
- package/dist/adapters/cli/mir.js.map +1 -1
- package/dist/adapters/cli/mira.d.ts.map +1 -1
- package/dist/adapters/cli/mira.js +2 -1
- package/dist/adapters/cli/mira.js.map +1 -1
- package/dist/adapters/hook-command.d.ts +3 -5
- package/dist/adapters/hook-command.d.ts.map +1 -1
- package/dist/adapters/hook-command.js +59 -13
- package/dist/adapters/hook-command.js.map +1 -1
- package/dist/autostart.d.ts +76 -0
- package/dist/autostart.d.ts.map +1 -1
- package/dist/autostart.js +105 -28
- package/dist/autostart.js.map +1 -1
- package/dist/bot-registry.d.ts +12 -0
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +43 -3
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli/dashboard-command.d.ts +142 -0
- package/dist/cli/dashboard-command.d.ts.map +1 -1
- package/dist/cli/dashboard-command.js +160 -0
- package/dist/cli/dashboard-command.js.map +1 -1
- package/dist/cli/dashboard-endpoint.d.ts +66 -0
- package/dist/cli/dashboard-endpoint.d.ts.map +1 -1
- package/dist/cli/dashboard-endpoint.js +144 -30
- package/dist/cli/dashboard-endpoint.js.map +1 -1
- package/dist/cli/send-dispatch.d.ts +2 -0
- package/dist/cli/send-dispatch.d.ts.map +1 -1
- package/dist/cli/send-dispatch.js +8 -2
- package/dist/cli/send-dispatch.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +270 -38
- package/dist/cli.js.map +1 -1
- package/dist/core/binary-self-update.d.ts +7 -0
- package/dist/core/binary-self-update.d.ts.map +1 -1
- package/dist/core/binary-self-update.js +17 -0
- package/dist/core/binary-self-update.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +52 -1
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/cost-calculator.d.ts +9 -1
- package/dist/core/cost-calculator.d.ts.map +1 -1
- package/dist/core/cost-calculator.js +5 -0
- package/dist/core/cost-calculator.js.map +1 -1
- package/dist/core/passthrough-commands.d.ts.map +1 -1
- package/dist/core/passthrough-commands.js +1 -1
- package/dist/core/passthrough-commands.js.map +1 -1
- package/dist/core/self-spawn.d.ts +46 -1
- package/dist/core/self-spawn.d.ts.map +1 -1
- package/dist/core/self-spawn.js +57 -0
- package/dist/core/self-spawn.js.map +1 -1
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +81 -5
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +93 -0
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/autostart-api.d.ts.map +1 -1
- package/dist/dashboard/autostart-api.js +16 -3
- package/dist/dashboard/autostart-api.js.map +1 -1
- package/dist/dashboard/bot-onboarding.d.ts +2 -1
- package/dist/dashboard/bot-onboarding.d.ts.map +1 -1
- package/dist/dashboard/bot-onboarding.js +22 -6
- package/dist/dashboard/bot-onboarding.js.map +1 -1
- package/dist/dashboard/bot-payload.d.ts +1 -0
- package/dist/dashboard/bot-payload.d.ts.map +1 -1
- package/dist/dashboard/bot-payload.js +3 -0
- package/dist/dashboard/bot-payload.js.map +1 -1
- package/dist/dashboard/connector-api.d.ts.map +1 -1
- package/dist/dashboard/connector-api.js +28 -0
- package/dist/dashboard/connector-api.js.map +1 -1
- package/dist/dashboard/trigger-api.d.ts.map +1 -1
- package/dist/dashboard/trigger-api.js +33 -21
- package/dist/dashboard/trigger-api.js.map +1 -1
- package/dist/dashboard/web/bot-defaults-page.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults-page.js +12 -2
- package/dist/dashboard/web/bot-defaults-page.js.map +1 -1
- package/dist/dashboard/web/bot-defaults.d.ts +2 -0
- package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults.js.map +1 -1
- package/dist/dashboard/web/bot-onboarding.d.ts +40 -1
- package/dist/dashboard/web/bot-onboarding.d.ts.map +1 -1
- package/dist/dashboard/web/bot-onboarding.js +52 -2
- package/dist/dashboard/web/bot-onboarding.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +2 -0
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/webhook-routes.d.ts.map +1 -1
- package/dist/dashboard/webhook-routes.js +272 -30
- package/dist/dashboard/webhook-routes.js.map +1 -1
- package/dist/dashboard-web/app.js +1 -1
- package/dist/dashboard-web/chunks/{agent-workbench-dock-page-XHJUYFGN.js → agent-workbench-dock-page-6LC422N6.js} +1 -1
- package/dist/dashboard-web/chunks/{agent-workbench-page-FLKTLIRM.js → agent-workbench-page-RSAWY7O2.js} +1 -1
- package/dist/dashboard-web/chunks/{bot-defaults-page-XMGLZZ2E.js → bot-defaults-page-67RAWCSQ.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-TLG45URB.js → chunk-IA5KMD5O.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-BU3Q6XC6.js → chunk-K232GT3M.js} +2 -2
- package/dist/dashboard-web/chunks/chunk-MMLTCXHP.js +10 -0
- package/dist/dashboard-web/chunks/{chunk-ECFC7UG2.js → chunk-R3LJUCEO.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-Z67OSM5P.js → chunk-YJA3KY3J.js} +1 -1
- package/dist/dashboard-web/chunks/{connectors-page-WDM4CEAU.js → connectors-page-DJCTHSFB.js} +1 -1
- package/dist/dashboard-web/chunks/{feedback-page-GMJ4FLJ4.js → feedback-page-O7SZRKNM.js} +1 -1
- package/dist/dashboard-web/chunks/{groups-page-L4ZJNWVR.js → groups-page-7PONUYHE.js} +1 -1
- package/dist/dashboard-web/chunks/{insights-page-7LUJU2CX.js → insights-page-J6DAAJ6D.js} +1 -1
- package/dist/dashboard-web/chunks/{monitor-room-7LZUJQPF.js → monitor-room-F3QNEW7N.js} +1 -1
- package/dist/dashboard-web/chunks/{monitoring-page-AUSXMPYO.js → monitoring-page-JHDD2VS2.js} +1 -1
- package/dist/dashboard-web/chunks/{office-page-6ZU6MAZN.js → office-page-MMTN4IKD.js} +1 -1
- package/dist/dashboard-web/chunks/{overview-page-QBC5CIYH.js → overview-page-IQ2UJAJP.js} +1 -1
- package/dist/dashboard-web/chunks/{roles-page-QO3YCA7D.js → roles-page-FNI4MGX6.js} +1 -1
- package/dist/dashboard-web/chunks/{schedules-page-YNGSKDQW.js → schedules-page-6PUU63KS.js} +1 -1
- package/dist/dashboard-web/chunks/{sessions-page-BWR4UB6X.js → sessions-page-O4N72EXT.js} +4 -4
- package/dist/dashboard-web/chunks/{settings-page-2IRIS3FP.js → settings-page-G7B3STUF.js} +1 -1
- package/dist/dashboard-web/chunks/{skills-page-5RZPM6HJ.js → skills-page-CEWKQOIG.js} +1 -1
- package/dist/dashboard-web/chunks/{team-federation-page-KERG6LKC.js → team-federation-page-NUP4VK4H.js} +1 -1
- package/dist/dashboard-web/chunks/{v3-page-766CBD7H.js → v3-page-M4XF6D5Z.js} +1 -1
- package/dist/dashboard-web/chunks/{whiteboards-page-2M6XZD5C.js → whiteboards-page-L755NZX6.js} +1 -1
- package/dist/dashboard-web/style.css +13 -0
- package/dist/dashboard.js +3 -0
- package/dist/dashboard.js.map +1 -1
- package/dist/global-config.d.ts +3 -0
- package/dist/global-config.d.ts.map +1 -1
- package/dist/global-config.js +10 -3
- package/dist/global-config.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +19 -1
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +19 -1
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/api-gate.d.ts +53 -0
- package/dist/im/lark/api-gate.d.ts.map +1 -0
- package/dist/im/lark/api-gate.js +322 -0
- package/dist/im/lark/api-gate.js.map +1 -0
- package/dist/im/lark/audio-transcribe.d.ts +23 -0
- package/dist/im/lark/audio-transcribe.d.ts.map +1 -0
- package/dist/im/lark/audio-transcribe.js +126 -0
- package/dist/im/lark/audio-transcribe.js.map +1 -0
- package/dist/im/lark/card-builder.d.ts +6 -0
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +53 -1
- package/dist/im/lark/card-builder.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts +10 -0
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +68 -1
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +247 -224
- package/dist/im/lark/client.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +34 -3
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/message-parser.d.ts +16 -0
- package/dist/im/lark/message-parser.d.ts.map +1 -1
- package/dist/im/lark/message-parser.js +31 -0
- package/dist/im/lark/message-parser.js.map +1 -1
- package/dist/services/budget-tracker.d.ts +61 -0
- package/dist/services/budget-tracker.d.ts.map +1 -0
- package/dist/services/budget-tracker.js +306 -0
- package/dist/services/budget-tracker.js.map +1 -0
- package/dist/services/connector-store.d.ts +16 -0
- package/dist/services/connector-store.d.ts.map +1 -1
- package/dist/services/connector-store.js.map +1 -1
- package/dist/services/failed-turn-retry.d.ts +43 -0
- package/dist/services/failed-turn-retry.d.ts.map +1 -0
- package/dist/services/failed-turn-retry.js +50 -0
- package/dist/services/failed-turn-retry.js.map +1 -0
- package/dist/services/model-pricing.d.ts +80 -0
- package/dist/services/model-pricing.d.ts.map +1 -0
- package/dist/services/model-pricing.js +182 -0
- package/dist/services/model-pricing.js.map +1 -0
- package/dist/services/session-store.d.ts.map +1 -1
- package/dist/services/session-store.js +13 -3
- package/dist/services/session-store.js.map +1 -1
- package/dist/services/trigger-types.d.ts +10 -0
- package/dist/services/trigger-types.d.ts.map +1 -1
- package/dist/services/trigger-types.js.map +1 -1
- package/dist/services/usage-ledger.d.ts +10 -0
- package/dist/services/usage-ledger.d.ts.map +1 -1
- package/dist/services/usage-ledger.js +36 -0
- package/dist/services/usage-ledger.js.map +1 -1
- package/dist/services/voice/asr.d.ts +17 -0
- package/dist/services/voice/asr.d.ts.map +1 -0
- package/dist/services/voice/asr.js +64 -0
- package/dist/services/voice/asr.js.map +1 -0
- package/dist/services/voice/index.d.ts +17 -2
- package/dist/services/voice/index.d.ts.map +1 -1
- package/dist/services/voice/index.js +43 -0
- package/dist/services/voice/index.js.map +1 -1
- package/dist/services/voice/types.d.ts +15 -0
- package/dist/services/voice/types.d.ts.map +1 -1
- package/dist/services/webhook-idempotency.d.ts +134 -0
- package/dist/services/webhook-idempotency.d.ts.map +1 -0
- package/dist/services/webhook-idempotency.js +265 -0
- package/dist/services/webhook-idempotency.js.map +1 -0
- package/dist/setup/app-name.d.ts +1 -0
- package/dist/setup/app-name.d.ts.map +1 -1
- package/dist/setup/app-name.js +7 -0
- package/dist/setup/app-name.js.map +1 -1
- package/dist/setup/bot-config-editor.d.ts +28 -0
- package/dist/setup/bot-config-editor.d.ts.map +1 -1
- package/dist/setup/bot-config-editor.js +73 -0
- package/dist/setup/bot-config-editor.js.map +1 -1
- package/dist/setup/open-platform-automation.d.ts +26 -0
- package/dist/setup/open-platform-automation.d.ts.map +1 -1
- package/dist/setup/open-platform-automation.js +90 -1
- package/dist/setup/open-platform-automation.js.map +1 -1
- package/dist/setup/open-platform-outcome.d.ts.map +1 -1
- package/dist/setup/open-platform-outcome.js +8 -2
- package/dist/setup/open-platform-outcome.js.map +1 -1
- package/dist/types.d.ts +20 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/usage-limit-tracker.d.ts +29 -9
- package/dist/utils/usage-limit-tracker.d.ts.map +1 -1
- package/dist/utils/usage-limit-tracker.js +122 -14
- package/dist/utils/usage-limit-tracker.js.map +1 -1
- package/dist/worker.js +27 -6
- package/dist/worker.js.map +1 -1
- package/dist/workflows/definition.d.ts +56 -56
- package/dist/workflows/events/payloads.d.ts +2 -2
- package/dist/workflows/events/schema.d.ts +430 -430
- package/dist/workflows/migration/v2-run-archive-schema.d.ts +2 -2
- package/dist/workflows/v3/run-envelope.d.ts +56 -56
- package/package.json +9 -8
- package/scripts/postinstall-bin.mjs +25 -0
- package/dist/dashboard-web/chunks/chunk-NJCJR3U2.js +0 -10
|
@@ -33,6 +33,145 @@ export function formatDashboardSuccessLines(result) {
|
|
|
33
33
|
lines.push(`本地直连(平台异常时可用): ${result.localUrl}`);
|
|
34
34
|
return lines;
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* How long `start`/`restart` should keep waiting for the dashboard to answer, and
|
|
38
|
+
* what to tell an operator who asks for the link while it is still coming up.
|
|
39
|
+
*
|
|
40
|
+
* SIZED FROM A REAL FLEET, not from how long a boot "should" take. The budget was
|
|
41
|
+
* 6s; MEASURED on a 13-member fleet the dashboard needed ~45s from supervisor
|
|
42
|
+
* start to answering (supervisor up at 14:23:04, `.dashboard-port` written at
|
|
43
|
+
* 14:23:49). So every `restart` there ended in the "still booting" fallback, and
|
|
44
|
+
* the operator's natural next step — `botmux dashboard` — printed
|
|
45
|
+
* "not reachable ... `botmux restart` will start it": advice that would restart a
|
|
46
|
+
* daemon which was in fact coming up fine, throwing away the boot about to
|
|
47
|
+
* succeed.
|
|
48
|
+
*/
|
|
49
|
+
export const DASHBOARD_READY_WAIT_MS = 90_000;
|
|
50
|
+
/**
|
|
51
|
+
* How long to keep polling before the liveness gate may end the wait.
|
|
52
|
+
*
|
|
53
|
+
* A just-started supervisor has not written its dashboard row yet, so the very
|
|
54
|
+
* first observation can legitimately be "cannot tell" — which must not be read as
|
|
55
|
+
* "nothing is coming up". This is the old whole-budget value, so the previous
|
|
56
|
+
* behaviour is preserved for that initial stretch and the gate only starts cutting
|
|
57
|
+
* waits short once the state file has had time to appear.
|
|
58
|
+
*/
|
|
59
|
+
export const DASHBOARD_LIVENESS_GRACE_MS = 6_000;
|
|
60
|
+
/**
|
|
61
|
+
* Failure reasons that prove we REACHED the dashboard, so waiting cannot change
|
|
62
|
+
* them. This is the "did we get an answer from the dashboard itself" question —
|
|
63
|
+
* NOT "is this backed by a file", which is the distinction an earlier version got
|
|
64
|
+
* wrong in both directions:
|
|
65
|
+
*
|
|
66
|
+
* • `no-secret` looks file-backed and permanent, but `.dashboard-secret` is
|
|
67
|
+
* created BY the dashboard during its own boot (`loadOrCreateSecret()`, called
|
|
68
|
+
* at module scope in dashboard.ts). On a fresh install the supervisor has a live
|
|
69
|
+
* dashboard pid well before that line runs, so the first poll legitimately sees
|
|
70
|
+
* `no-secret` and it resolves on its own moments later.
|
|
71
|
+
* • `wrong-service` is not permanent either: another service can hold the recorded
|
|
72
|
+
* port while the dashboard has not bound its own yet, which makes discovery fail
|
|
73
|
+
* now and succeed once it binds.
|
|
74
|
+
*
|
|
75
|
+
* Treating either as terminal ended the poll early and then told the operator to
|
|
76
|
+
* restart a dashboard that was coming up fine — the same misdiagnosis this module
|
|
77
|
+
* fixes for `unreachable`.
|
|
78
|
+
*
|
|
79
|
+
* Terminal is therefore "we got an answer FROM the dashboard": `no-active-token`
|
|
80
|
+
* (it is up, it just has no token yet) and `http-error`. The latter is exactly how
|
|
81
|
+
* `dashboard-endpoint.ts:reachedDashboard()` classifies it — a 500 or a malformed
|
|
82
|
+
* body means the dashboard replied, so waiting changes nothing, and leaving it out
|
|
83
|
+
* would spend the full 90s budget on a live dashboard that answers 500 forever.
|
|
84
|
+
*/
|
|
85
|
+
export function dashboardFailureIsTerminal(failure) {
|
|
86
|
+
return failure.reason === 'no-active-token' || failure.reason === 'http-error';
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Map an observed fleet state to "is a dashboard coming up?" — the OBSERVATION
|
|
90
|
+
* half of the readiness decision, kept pure so it is testable.
|
|
91
|
+
*
|
|
92
|
+
* This used to live inline in `cli.ts` where nothing could reach it, and the
|
|
93
|
+
* `launching` branch in particular is the whole point of the fix: the supervisor
|
|
94
|
+
* records `status='launching', pid=0` while a crashed member is in restart
|
|
95
|
+
* backoff, so a pid-based check called that "not live", ended the poll, and then
|
|
96
|
+
* advised restarting a dashboard the supervisor was already bringing back.
|
|
97
|
+
*
|
|
98
|
+
* Tri-state on purpose — `null` is "cannot tell yet", NOT "no":
|
|
99
|
+
* • no state file, or the dashboard row not written yet → null
|
|
100
|
+
* • no live supervisor → false (nobody left to start anything)
|
|
101
|
+
* • stopped / errored → false (the supervisor has given up)
|
|
102
|
+
* • launching → true (pid is 0 BY DESIGN here; never pid-check this state)
|
|
103
|
+
* • online → only true if the pid is actually alive
|
|
104
|
+
*
|
|
105
|
+
* @param state parsed fleet state, or null when absent/unreadable
|
|
106
|
+
* @param pidAlive liveness probe, injected so tests need no real processes
|
|
107
|
+
*/
|
|
108
|
+
export function dashboardComingUpFromState(state, dashboardProcessName, pidAlive) {
|
|
109
|
+
if (!state)
|
|
110
|
+
return null;
|
|
111
|
+
const sup = state.supervisorPid;
|
|
112
|
+
const supervisorAlive = Number.isSafeInteger(sup) && sup > 1 && pidAlive(sup);
|
|
113
|
+
if (!supervisorAlive)
|
|
114
|
+
return false;
|
|
115
|
+
const proc = state.procs?.find((p) => p.name === dashboardProcessName);
|
|
116
|
+
if (!proc)
|
|
117
|
+
return null;
|
|
118
|
+
if (proc.status === 'stopped' || proc.status === 'errored')
|
|
119
|
+
return false;
|
|
120
|
+
if (proc.status === 'launching')
|
|
121
|
+
return true;
|
|
122
|
+
if (!Number.isSafeInteger(proc.pid) || proc.pid <= 1)
|
|
123
|
+
return false;
|
|
124
|
+
return pidAlive(proc.pid);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Should the readiness poll take another turn?
|
|
128
|
+
*
|
|
129
|
+
* Three independent bounds, and all of them matter:
|
|
130
|
+
* • the clock — liveness alone would spin forever on a member that is up but
|
|
131
|
+
* never binds its port;
|
|
132
|
+
* • whether the failure is terminal — no point polling an answer that will not
|
|
133
|
+
* change;
|
|
134
|
+
* • whether a dashboard is coming up — the clock alone would spend the (now much
|
|
135
|
+
* larger) budget in full on a fleet that has no dashboard member, or whose
|
|
136
|
+
* dashboard the supervisor has given up on.
|
|
137
|
+
*
|
|
138
|
+
* `comingUp` is deliberately TRI-STATE. `null` means "cannot tell yet" (no state
|
|
139
|
+
* file, or the supervisor has not written the dashboard row), which is normal in
|
|
140
|
+
* the first moments and must not end the wait; before
|
|
141
|
+
* DASHBOARD_LIVENESS_GRACE_MS it keeps waiting, after it stops rather than hold
|
|
142
|
+
* the full budget on a fleet whose state never appears.
|
|
143
|
+
*/
|
|
144
|
+
export function shouldKeepWaitingForDashboard(input) {
|
|
145
|
+
if (input.elapsedMs >= (input.budgetMs ?? DASHBOARD_READY_WAIT_MS))
|
|
146
|
+
return false;
|
|
147
|
+
if (dashboardFailureIsTerminal(input.failure))
|
|
148
|
+
return false;
|
|
149
|
+
if (input.comingUp === null) {
|
|
150
|
+
return input.elapsedMs < (input.graceMs ?? DASHBOARD_LIVENESS_GRACE_MS);
|
|
151
|
+
}
|
|
152
|
+
return input.comingUp;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* The message for a failure that may just mean "not up yet" — the one an operator
|
|
156
|
+
* sees from `botmux dashboard`.
|
|
157
|
+
*
|
|
158
|
+
* "Run restart" is right ONLY when nothing is coming up. With a live dashboard
|
|
159
|
+
* member, nothing is broken and a restart would throw away a boot that is about to
|
|
160
|
+
* succeed, so say "wait" instead. Covers every non-terminal shape, because they
|
|
161
|
+
* are all reachable while the dashboard is still booting: the port not listening
|
|
162
|
+
* yet (`unreachable`), the secret not written yet (`no-secret` — the dashboard
|
|
163
|
+
* creates it itself), and the port not bound yet so discovery finds someone else
|
|
164
|
+
* on the recorded one (`wrong-service`). See DASHBOARD_READY_WAIT_MS.
|
|
165
|
+
*/
|
|
166
|
+
export function formatDashboardUnreachable(port, comingUp) {
|
|
167
|
+
// `null` ("cannot tell yet") is treated as coming up: the honest advice when we
|
|
168
|
+
// do not know is "wait and retry", never "restart".
|
|
169
|
+
if (comingUp !== false) {
|
|
170
|
+
return `dashboard 正在启动中,还没开始在 127.0.0.1:${port} 上应答(大 fleet 可能要几十秒)。`
|
|
171
|
+
+ '稍等几秒后重新运行 `botmux dashboard` 即可,不需要 restart。';
|
|
172
|
+
}
|
|
173
|
+
return `dashboard process not reachable on 127.0.0.1:${port} — \`botmux restart\` will start it`;
|
|
174
|
+
}
|
|
36
175
|
export function formatDashboardFallbackFailure(action, failure) {
|
|
37
176
|
const operation = action === 'current' ? 'Dashboard lookup' : 'Rotation';
|
|
38
177
|
return `${operation} failed: ${failure.detail ?? failure.reason}`;
|
|
@@ -80,4 +219,25 @@ export async function executeDashboardCommand(args, callEndpoint) {
|
|
|
80
219
|
}
|
|
81
220
|
return { kind: 'endpoint', action, result: ensured };
|
|
82
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* `botmux dashboard`'s execution path, as ONE importable unit.
|
|
224
|
+
*
|
|
225
|
+
* Why this exists rather than inline wiring in `cli.ts`: the opt-in below is the
|
|
226
|
+
* whole fix for a dead `.dashboard-port`, and `cli.ts` exports nothing testable,
|
|
227
|
+
* so the only way to check it was a source-text assertion. Two such assertions
|
|
228
|
+
* were written and both were wrong — the first false-RED on a legitimate
|
|
229
|
+
* extract-to-local refactor, the second stayed GREEN when the flag-carrying call
|
|
230
|
+
* was fully disconnected from the caller actually passed down (flag present,
|
|
231
|
+
* command executed, wiring severed). A regex over nested callbacks cannot express
|
|
232
|
+
* "this options object reaches that caller"; a function can.
|
|
233
|
+
*
|
|
234
|
+
* `rescanWhenUnreachable: true` is correct HERE and only here: this is a one-shot
|
|
235
|
+
* human command, so at worst it scans the probe range once per invocation. The
|
|
236
|
+
* 500ms readiness poll must keep the default (false) or it would scan every tick.
|
|
237
|
+
*
|
|
238
|
+
* @param callEndpoint the raw endpoint caller; this wrapper is what adds the opt-in
|
|
239
|
+
*/
|
|
240
|
+
export async function executeDashboardCliCommand(args, callEndpoint) {
|
|
241
|
+
return executeDashboardCommand(args, (path) => callEndpoint(path, { rescanWhenUnreachable: true }));
|
|
242
|
+
}
|
|
83
243
|
//# sourceMappingURL=dashboard-command.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-command.js","sourceRoot":"","sources":["../../src/cli/dashboard-command.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dashboard-command.js","sourceRoot":"","sources":["../../src/cli/dashboard-command.ts"],"names":[],"mappings":"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"}
|
|
@@ -56,7 +56,45 @@ export declare function requestDashboardAt(opts: {
|
|
|
56
56
|
path: DashboardEndpoint;
|
|
57
57
|
secret: string;
|
|
58
58
|
fetchImpl?: FetchImpl;
|
|
59
|
+
/**
|
|
60
|
+
* Abort the request after this long. REQUIRED for discovery: a local service
|
|
61
|
+
* that accepts the TCP connection but never sends HTTP headers would otherwise
|
|
62
|
+
* hang the whole serial probe loop forever (`loopbackFetch` sets no request
|
|
63
|
+
* timeout of its own), so a single stalled port could permanently wedge
|
|
64
|
+
* `botmux dashboard` before it ever reaches the real dashboard.
|
|
65
|
+
*/
|
|
66
|
+
timeoutMs?: number;
|
|
59
67
|
}): Promise<DashboardResult>;
|
|
68
|
+
/**
|
|
69
|
+
* Should a failure on the recorded port trigger a probe-range rescan?
|
|
70
|
+
*
|
|
71
|
+
* `wrong-service` / `auth-failed` mean SOMETHING answered but is not our
|
|
72
|
+
* dashboard, so the recorded port is provably wrong and scanning is safe.
|
|
73
|
+
*
|
|
74
|
+
* `unreachable` is ambiguous — it is BOTH "dashboard still booting" (retry the
|
|
75
|
+
* same port; scanning would be wasted work every tick) AND "the recorded port is
|
|
76
|
+
* a dead value nobody listens on" (retrying can never succeed, so without a scan
|
|
77
|
+
* the port file stays wrong forever). MEASURED on a box where `.dashboard-port`
|
|
78
|
+
* held 7893 while the live dashboard was on 7891 with 0 processes on 7893: every
|
|
79
|
+
* `botmux dashboard` failed, and the existing self-heal never ran because it is
|
|
80
|
+
* gated on someone answering.
|
|
81
|
+
*
|
|
82
|
+
* `allowUnreachableRescan` is how the caller separates the two: a one-shot human
|
|
83
|
+
* command passes true (at worst one scan per invocation); the 500ms readiness poll
|
|
84
|
+
* leaves it false. It is deliberately NOT derived from "is the dashboard coming
|
|
85
|
+
* up?" — that answers `true` for `online` + live pid too, which is exactly the
|
|
86
|
+
* measured failure, so such a gate would never fire on the real bug.
|
|
87
|
+
*/
|
|
88
|
+
/**
|
|
89
|
+
* Per-probe cap. Loopback only, so a healthy dashboard answers in milliseconds;
|
|
90
|
+
* this exists purely to survive a port that accepts TCP and never replies.
|
|
91
|
+
*/
|
|
92
|
+
export declare const DISCOVERY_PROBE_TIMEOUT_MS = 2000;
|
|
93
|
+
/**
|
|
94
|
+
* Cap for the WHOLE serial scan. Without it, `probeSpan × probeTimeout`
|
|
95
|
+
* (21 × 2s) would be the worst case on a host full of stalled loopback services.
|
|
96
|
+
*/
|
|
97
|
+
export declare const DISCOVERY_TOTAL_BUDGET_MS = 8000;
|
|
60
98
|
/**
|
|
61
99
|
* Resolve the dashboard URL for `path`, trying the recorded port first and
|
|
62
100
|
* self-healing the port file when it points at the wrong service or a loopback
|
|
@@ -71,6 +109,34 @@ export declare function callDashboard(opts: {
|
|
|
71
109
|
persistPort?: boolean;
|
|
72
110
|
path: DashboardEndpoint;
|
|
73
111
|
fetchImpl?: FetchImpl;
|
|
112
|
+
/**
|
|
113
|
+
* Allow a rescan when the recorded port is simply not listening.
|
|
114
|
+
*
|
|
115
|
+
* Pass true for a ONE-SHOT human command (`botmux dashboard`), which is what
|
|
116
|
+
* `executeDashboardCliCommand` does. Leave it false for the 500ms readiness
|
|
117
|
+
* poll, where `unreachable` is the normal booting state and scanning the range
|
|
118
|
+
* every tick would be pure waste.
|
|
119
|
+
*
|
|
120
|
+
* NOT gated on "the dashboard is not coming up": that observation is `true` for
|
|
121
|
+
* both `launching` AND `online` + live pid, and the measured failure was the
|
|
122
|
+
* latter (dashboard healthy on another port), so such a gate would never fire
|
|
123
|
+
* on the bug this exists for.
|
|
124
|
+
*/
|
|
125
|
+
rescanWhenUnreachable?: boolean;
|
|
126
|
+
/** Override the per-probe timeout (default DISCOVERY_PROBE_TIMEOUT_MS). */
|
|
127
|
+
probeTimeoutMs?: number;
|
|
128
|
+
/**
|
|
129
|
+
* Bound the FIRST (recorded-port) request even without opting into a rescan.
|
|
130
|
+
*
|
|
131
|
+
* The readiness poll needs this: its 90s budget is only consulted AFTER
|
|
132
|
+
* `await callDashboard(...)` returns, so a recorded port that accepts the
|
|
133
|
+
* connection and never answers makes the first await hang forever — the outer
|
|
134
|
+
* budget and the retry loop are both unreachable. Bounding the request is the
|
|
135
|
+
* only thing that can interrupt it.
|
|
136
|
+
*/
|
|
137
|
+
requestTimeoutMs?: number;
|
|
138
|
+
/** Override the whole-scan budget (default DISCOVERY_TOTAL_BUDGET_MS). */
|
|
139
|
+
discoveryBudgetMs?: number;
|
|
74
140
|
}): Promise<DashboardResult>;
|
|
75
141
|
export {};
|
|
76
142
|
//# sourceMappingURL=dashboard-endpoint.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-endpoint.d.ts","sourceRoot":"","sources":["../../src/cli/dashboard-endpoint.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,MAAM,iBAAiB,GAAG,eAAe,GAAG,eAAe,GAAG,gBAAgB,GAAG,uBAAuB,CAAC;AAE/G,MAAM,MAAM,mBAAmB,GAC3B,WAAW,GACX,aAAa,GACb,aAAa,GACb,YAAY,GACZ,iBAAiB,GACjB,eAAe,CAAC;AAEpB,MAAM,MAAM,eAAe,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE,KAAK,SAAS,GAAG,OAAO,KAAK,CAAC;AAE9B;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,CAY/F;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAiBtE;AAED,gEAAgE;AAChE,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,iBAAiB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"dashboard-endpoint.d.ts","sourceRoot":"","sources":["../../src/cli/dashboard-endpoint.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,MAAM,iBAAiB,GAAG,eAAe,GAAG,eAAe,GAAG,gBAAgB,GAAG,uBAAuB,CAAC;AAE/G,MAAM,MAAM,mBAAmB,GAC3B,WAAW,GACX,aAAa,GACb,aAAa,GACb,YAAY,GACZ,iBAAiB,GACjB,eAAe,CAAC;AAEpB,MAAM,MAAM,eAAe,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE,KAAK,SAAS,GAAG,OAAO,KAAK,CAAC;AAE9B;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,CAY/F;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAiBtE;AAED,gEAAgE;AAChE,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,iBAAiB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,eAAe,CAAC,CA+D3B;AAOD;;;;;;;;;;;;;;;;;;;GAmBG;AACH;;;GAGG;AACH,eAAO,MAAM,0BAA0B,OAAQ,CAAC;AAChD;;;GAGG;AACH,eAAO,MAAM,yBAAyB,OAAQ,CAAC;AAQ/C;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;;;;;;;;OAYG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,2EAA2E;IAC3E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG,OAAO,CAAC,eAAe,CAAC,CAiG3B"}
|
|
@@ -63,43 +63,111 @@ export async function requestDashboardAt(opts) {
|
|
|
63
63
|
// the verifier reconstructs the bind from the port IT bound, so any forward
|
|
64
64
|
// mismatches the signature (and the attacker can't re-sign without the secret).
|
|
65
65
|
const { ts, nonce, sig } = signCliAuth(secret, cliAuthBind('POST', path, port));
|
|
66
|
-
|
|
66
|
+
const ac = opts.timeoutMs === undefined ? null : new AbortController();
|
|
67
|
+
const timer = ac ? setTimeout(() => ac.abort(), opts.timeoutMs) : null;
|
|
67
68
|
try {
|
|
68
|
-
|
|
69
|
+
// The timeout must span the WHOLE exchange, not just the headers: a fetch
|
|
70
|
+
// resolves its Response as soon as headers arrive, so a server that sends
|
|
71
|
+
// `200 application/json` and then stalls mid-body would hang forever in
|
|
72
|
+
// `.text()`/`.json()` below. MEASURED: with the timer cleared right after the
|
|
73
|
+
// fetch, exactly that shape wedged the CLI (outer timeout, rc=124).
|
|
74
|
+
const res = await fetchImpl(`http://${host}:${port}${path}`, {
|
|
69
75
|
method: 'POST',
|
|
70
76
|
headers: {
|
|
71
77
|
'X-Botmux-Cli-Ts': ts,
|
|
72
78
|
'X-Botmux-Cli-Nonce': nonce,
|
|
73
79
|
'X-Botmux-Cli-Auth': sig,
|
|
74
80
|
},
|
|
81
|
+
...(ac ? { signal: ac.signal } : {}),
|
|
75
82
|
});
|
|
83
|
+
// Read the body ONCE, and never swallow a failed read. Every status branch used
|
|
84
|
+
// to do `.text().catch(() => '')`, which turns an ABORTED body into a normal
|
|
85
|
+
// empty body — so a server answering `500 headers` + a body that never
|
|
86
|
+
// completes was classified `http-error`. That matters beyond the label:
|
|
87
|
+
// `reachedDashboard(http-error)` is true, so rediscovery STOPS and the stale
|
|
88
|
+
// port file is kept, letting one stalled service permanently block self-heal.
|
|
89
|
+
// MEASURED: recorded port returning `500` + partial body → `http-error` in
|
|
90
|
+
// 305ms, port file unchanged, real dashboard never probed.
|
|
91
|
+
//
|
|
92
|
+
// A COMPLETE body still classifies normally even when malformed; only an
|
|
93
|
+
// aborted/failed read escapes to the catch below as `unreachable`.
|
|
94
|
+
const raw = await res.text();
|
|
95
|
+
if (res.status === 404)
|
|
96
|
+
return classifyDashboard404(path, raw);
|
|
97
|
+
if (res.status === 401)
|
|
98
|
+
return classifyDashboard401(raw);
|
|
99
|
+
if (!res.ok) {
|
|
100
|
+
return { ok: false, reason: 'http-error', detail: `${res.status} ${raw}` };
|
|
101
|
+
}
|
|
102
|
+
// reload-binding 不返回 url,200 即成功(仅用于「捅一下 daemon 重连」)
|
|
103
|
+
if (path === '/__cli/reload-binding')
|
|
104
|
+
return { ok: true, url: '' };
|
|
105
|
+
let body = {};
|
|
106
|
+
try {
|
|
107
|
+
body = JSON.parse(raw);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
body = {};
|
|
111
|
+
}
|
|
112
|
+
if (!body.url)
|
|
113
|
+
return { ok: false, reason: 'http-error', detail: 'malformed response (no url)' };
|
|
114
|
+
// localUrl is present only when the dashboard link routes through the central
|
|
115
|
+
// platform — a direct host:port fallback for when the platform is down.
|
|
116
|
+
return { ok: true, url: body.url, localUrl: body.localUrl };
|
|
76
117
|
}
|
|
77
118
|
catch {
|
|
119
|
+
// Includes the abort and a body that never completes: for our purposes a
|
|
120
|
+
// stalled port is indistinguishable from a dead one, and both must let the
|
|
121
|
+
// probe loop move on. A malformed-but-COMPLETE body never lands here — it is
|
|
122
|
+
// classified above, because only the `.text()` read itself can reject.
|
|
78
123
|
return { ok: false, reason: 'unreachable' };
|
|
79
124
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (!res.ok) {
|
|
85
|
-
return { ok: false, reason: 'http-error', detail: `${res.status} ${await res.text().catch(() => '')}` };
|
|
125
|
+
finally {
|
|
126
|
+
// Always clear it — a live timer would keep the CLI's event loop alive.
|
|
127
|
+
if (timer)
|
|
128
|
+
clearTimeout(timer);
|
|
86
129
|
}
|
|
87
|
-
// reload-binding 不返回 url,200 即成功(仅用于「捅一下 daemon 重连」)
|
|
88
|
-
if (path === '/__cli/reload-binding')
|
|
89
|
-
return { ok: true, url: '' };
|
|
90
|
-
const body = await res.json().catch(() => ({}));
|
|
91
|
-
if (!body.url)
|
|
92
|
-
return { ok: false, reason: 'http-error', detail: 'malformed response (no url)' };
|
|
93
|
-
// localUrl is present only when the dashboard link routes through the central
|
|
94
|
-
// platform — a direct host:port fallback for when the platform is down.
|
|
95
|
-
return { ok: true, url: body.url, localUrl: body.localUrl };
|
|
96
130
|
}
|
|
97
131
|
/** A result that proves we actually reached the dashboard (vs. wrong port). */
|
|
98
132
|
function reachedDashboard(r) {
|
|
99
133
|
return r.ok || (!r.ok && (r.reason === 'no-active-token' || r.reason === 'http-error'));
|
|
100
134
|
}
|
|
101
|
-
|
|
102
|
-
|
|
135
|
+
/**
|
|
136
|
+
* Should a failure on the recorded port trigger a probe-range rescan?
|
|
137
|
+
*
|
|
138
|
+
* `wrong-service` / `auth-failed` mean SOMETHING answered but is not our
|
|
139
|
+
* dashboard, so the recorded port is provably wrong and scanning is safe.
|
|
140
|
+
*
|
|
141
|
+
* `unreachable` is ambiguous — it is BOTH "dashboard still booting" (retry the
|
|
142
|
+
* same port; scanning would be wasted work every tick) AND "the recorded port is
|
|
143
|
+
* a dead value nobody listens on" (retrying can never succeed, so without a scan
|
|
144
|
+
* the port file stays wrong forever). MEASURED on a box where `.dashboard-port`
|
|
145
|
+
* held 7893 while the live dashboard was on 7891 with 0 processes on 7893: every
|
|
146
|
+
* `botmux dashboard` failed, and the existing self-heal never ran because it is
|
|
147
|
+
* gated on someone answering.
|
|
148
|
+
*
|
|
149
|
+
* `allowUnreachableRescan` is how the caller separates the two: a one-shot human
|
|
150
|
+
* command passes true (at worst one scan per invocation); the 500ms readiness poll
|
|
151
|
+
* leaves it false. It is deliberately NOT derived from "is the dashboard coming
|
|
152
|
+
* up?" — that answers `true` for `online` + live pid too, which is exactly the
|
|
153
|
+
* measured failure, so such a gate would never fire on the real bug.
|
|
154
|
+
*/
|
|
155
|
+
/**
|
|
156
|
+
* Per-probe cap. Loopback only, so a healthy dashboard answers in milliseconds;
|
|
157
|
+
* this exists purely to survive a port that accepts TCP and never replies.
|
|
158
|
+
*/
|
|
159
|
+
export const DISCOVERY_PROBE_TIMEOUT_MS = 2_000;
|
|
160
|
+
/**
|
|
161
|
+
* Cap for the WHOLE serial scan. Without it, `probeSpan × probeTimeout`
|
|
162
|
+
* (21 × 2s) would be the worst case on a host full of stalled loopback services.
|
|
163
|
+
*/
|
|
164
|
+
export const DISCOVERY_TOTAL_BUDGET_MS = 8_000;
|
|
165
|
+
function shouldRediscover(r, allowUnreachableRescan = false) {
|
|
166
|
+
if (r.ok)
|
|
167
|
+
return false;
|
|
168
|
+
if (r.reason === 'wrong-service' || r.reason === 'auth-failed')
|
|
169
|
+
return true;
|
|
170
|
+
return allowUnreachableRescan && r.reason === 'unreachable';
|
|
103
171
|
}
|
|
104
172
|
/**
|
|
105
173
|
* Resolve the dashboard URL for `path`, trying the recorded port first and
|
|
@@ -127,26 +195,67 @@ export async function callDashboard(opts) {
|
|
|
127
195
|
|| opts.envPort
|
|
128
196
|
|| String(opts.defaultPort);
|
|
129
197
|
const candidate = Number(recorded);
|
|
198
|
+
const probeTimeoutMs = opts.probeTimeoutMs ?? DISCOVERY_PROBE_TIMEOUT_MS;
|
|
130
199
|
// 1. Try the recorded port. A success — or any state that proves we reached
|
|
131
200
|
// the dashboard (no-active-token / http-error) — is returned as-is.
|
|
132
|
-
|
|
201
|
+
//
|
|
202
|
+
// This hop must be bounded whenever the caller can't otherwise interrupt it.
|
|
203
|
+
// An opted-in one-shot command gets `probeTimeoutMs`; the readiness poll
|
|
204
|
+
// passes `requestTimeoutMs` explicitly, because its own 90s budget is only
|
|
205
|
+
// checked AFTER this await returns — so a recorded port that accepts and never
|
|
206
|
+
// answers would hang the first iteration forever, with the outer budget and
|
|
207
|
+
// the retry loop both unreachable. Callers that pass neither stay unbounded.
|
|
208
|
+
const firstTimeoutMs = opts.requestTimeoutMs
|
|
209
|
+
?? (opts.rescanWhenUnreachable ? probeTimeoutMs : undefined);
|
|
210
|
+
const first = await requestDashboardAt({
|
|
211
|
+
host, port: candidate, path: opts.path, secret, fetchImpl,
|
|
212
|
+
...(firstTimeoutMs === undefined ? {} : { timeoutMs: firstTimeoutMs }),
|
|
213
|
+
});
|
|
133
214
|
if (reachedDashboard(first))
|
|
134
215
|
return first;
|
|
135
|
-
// 2. Rediscover
|
|
136
|
-
// but failed
|
|
137
|
-
// sig_mismatch
|
|
138
|
-
//
|
|
139
|
-
// the
|
|
140
|
-
if (!shouldRediscover(first))
|
|
216
|
+
// 2. Rediscover when the recorded port provably cannot be the dashboard:
|
|
217
|
+
// something answered but failed identity checks (wrong-service 404 /
|
|
218
|
+
// sig_mismatch), or — when the caller opted in, i.e. a one-shot human
|
|
219
|
+
// command — nothing is listening there at all (a dead recorded port, which
|
|
220
|
+
// retrying the same port can never fix).
|
|
221
|
+
if (!shouldRediscover(first, opts.rescanWhenUnreachable))
|
|
141
222
|
return first;
|
|
142
223
|
const base = Number(opts.envPort || opts.defaultPort);
|
|
224
|
+
// TWO bounds, and both are needed. Per-probe alone degrades to
|
|
225
|
+
// `probeSpan × timeout` (21 × 2s ≈ 42s) because the loop is serial; a total
|
|
226
|
+
// deadline alone would let one stalled port consume the entire budget before
|
|
227
|
+
// any other candidate is tried. MEASURED without either: a local service that
|
|
228
|
+
// accepts TCP and never answers made `callDashboard` hang forever.
|
|
229
|
+
const deadline = Date.now() + (opts.discoveryBudgetMs ?? DISCOVERY_TOTAL_BUDGET_MS);
|
|
143
230
|
for (let p = base; p <= base + probeSpan; p++) {
|
|
144
231
|
if (p === candidate)
|
|
145
232
|
continue;
|
|
233
|
+
// Out of budget: stop and report the ORIGINAL failure. Never invent a reason,
|
|
234
|
+
// and never rewrite the port file on the way out.
|
|
235
|
+
//
|
|
236
|
+
// This `break` and the `Math.min` clamp below have DISTINCT jobs:
|
|
237
|
+
// • the break stops ISSUING probes once the budget is gone — after the
|
|
238
|
+
// deadline no further connection or HMAC probe may be attempted at all;
|
|
239
|
+
// • the clamp bounds the DURATION of a probe that is still allowed to start,
|
|
240
|
+
// so the last one cannot overrun the budget by a full probeTimeoutMs.
|
|
241
|
+
// Wall-clock alone cannot tell them apart (deleting either leaves a 900ms
|
|
242
|
+
// budget at ~910ms, because a negative `remaining` clamps to a ~0ms timeout and
|
|
243
|
+
// probes then fail instantly). Each is pinned by its own test with a criterion
|
|
244
|
+
// that DOES discriminate: call-count for the break, and `budget <
|
|
245
|
+
// probeTimeoutMs` for the clamp. See dashboard-endpoint.test.ts.
|
|
246
|
+
const remaining = deadline - Date.now();
|
|
247
|
+
if (remaining <= 0)
|
|
248
|
+
break;
|
|
146
249
|
// Probe read-only (`/__cli/current`) so discovery never mints a token on a
|
|
147
250
|
// server we're merely identifying. Only the real dashboard can answer the
|
|
148
251
|
// HMAC-gated route as `ok` or `no-active-token`.
|
|
149
|
-
|
|
252
|
+
// Clamp to what is LEFT, or the last probe could overrun the budget by a full
|
|
253
|
+
// probeTimeoutMs (checking the deadline before the probe bounds when we start,
|
|
254
|
+
// not when we finish) — making the "total budget" a soft target rather than a cap.
|
|
255
|
+
const probe = await requestDashboardAt({
|
|
256
|
+
host, port: p, path: '/__cli/current', secret, fetchImpl,
|
|
257
|
+
timeoutMs: Math.min(probeTimeoutMs, remaining),
|
|
258
|
+
});
|
|
150
259
|
if (probe.ok || (!probe.ok && probe.reason === 'no-active-token')) {
|
|
151
260
|
if (persistPort) {
|
|
152
261
|
try {
|
|
@@ -154,11 +263,16 @@ export async function callDashboard(opts) {
|
|
|
154
263
|
}
|
|
155
264
|
catch { /* best-effort self-heal */ }
|
|
156
265
|
}
|
|
157
|
-
// Found the dashboard — perform the actually-requested op on its port.
|
|
158
|
-
|
|
266
|
+
// Found the dashboard — perform the actually-requested op on its port. The
|
|
267
|
+
// real request gets its own fresh timeout: it is not discovery, and it must
|
|
268
|
+
// not inherit whatever the scan already spent.
|
|
269
|
+
return requestDashboardAt({
|
|
270
|
+
host, port: p, path: opts.path, secret, fetchImpl, timeoutMs: probeTimeoutMs,
|
|
271
|
+
});
|
|
159
272
|
}
|
|
160
273
|
}
|
|
161
|
-
// No dashboard found in the probe range; surface the original
|
|
274
|
+
// No dashboard found in the probe range; surface the original failure
|
|
275
|
+
// (wrong-service, auth-failed, or unreachable) rather than inventing one.
|
|
162
276
|
return first;
|
|
163
277
|
}
|
|
164
278
|
//# sourceMappingURL=dashboard-endpoint.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-endpoint.js","sourceRoot":"","sources":["../../src/cli/dashboard-endpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AA4C9D;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAuB,EAAE,QAAgB;IAC5E,IAAI,IAAI,GAAY,IAAI,CAAC;IACzB,IAAI,CAAC;QAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,mCAAmC,CAAC,CAAC;IAClF,MAAM,GAAG,GAAG,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAE,IAA4B,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IACjG,IAAI,IAAI,KAAK,gBAAgB,IAAI,GAAG,KAAK,iBAAiB,EAAE,CAAC;QAC3D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAClD,CAAC;IACD,OAAO;QACL,EAAE,EAAE,KAAK;QACT,MAAM,EAAE,eAAe;QACvB,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK;KAC3D,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACnD,IAAI,IAAI,GAAY,IAAI,CAAC;IACzB,IAAI,CAAC;QAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;IACjE,MAAM,GAAG,GAAG,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAE,IAA4B,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IACjG,MAAM,UAAU,GAAG,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAE,IAA6B,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1G,IAAI,GAAG,KAAK,cAAc,IAAI,UAAU,KAAK,cAAc,EAAE,CAAC;QAC5D,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,aAAa;YACrB,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB;SACxE,CAAC;IACJ,CAAC;IACD,OAAO;QACL,EAAE,EAAE,KAAK;QACT,MAAM,EAAE,YAAY;QACpB,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK;KAC3D,CAAC;AACJ,CAAC;AAED,gEAAgE;AAChE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,
|
|
1
|
+
{"version":3,"file":"dashboard-endpoint.js","sourceRoot":"","sources":["../../src/cli/dashboard-endpoint.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,6 +13,8 @@ export type DispatchPrimaryDeps = {
|
|
|
13
13
|
sendMessage: SendMessageFn;
|
|
14
14
|
replyMessage: ReplyMessageFn;
|
|
15
15
|
};
|
|
16
|
+
/** Keep provider details visible without leaking Axios config or headers. */
|
|
17
|
+
export declare function describeSendFailure(err: unknown): string;
|
|
16
18
|
/** First attachment path that aliases stdin, or null if none do. */
|
|
17
19
|
export declare function findStdinAliasAttachment(paths: readonly string[]): string | null;
|
|
18
20
|
export type SlashSendValidation = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send-dispatch.d.ts","sourceRoot":"","sources":["../../src/cli/send-dispatch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"send-dispatch.d.ts","sourceRoot":"","sources":["../../src/cli/send-dispatch.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { extname } from 'node:path';
|
|
2
|
+
import { formatLarkError } from '../bot-registry.js';
|
|
3
|
+
/** Keep provider details visible without leaking Axios config or headers. */
|
|
4
|
+
export function describeSendFailure(err) {
|
|
5
|
+
return formatLarkError(err)
|
|
6
|
+
?? (err instanceof Error && err.message ? err.message : String(err));
|
|
7
|
+
}
|
|
2
8
|
/**
|
|
3
9
|
* Paths that resolve to the process's own stdin. `botmux send` reads stdin for
|
|
4
10
|
* the message body (the documented `echo "msg" | botmux send` form), so passing
|
|
@@ -66,7 +72,7 @@ export async function sendFileAttachments(deps, appId, files) {
|
|
|
66
72
|
sent.push(await deps.dispatch(JSON.stringify({ file_key: fileKey }), 'file'));
|
|
67
73
|
}
|
|
68
74
|
catch (err) {
|
|
69
|
-
failed.push({ path: fp, error:
|
|
75
|
+
failed.push({ path: fp, error: describeSendFailure(err) });
|
|
70
76
|
}
|
|
71
77
|
}
|
|
72
78
|
return { sent, failed };
|
|
@@ -308,7 +314,7 @@ export async function sendVideoAttachments(deps, appId, videos) {
|
|
|
308
314
|
failed.push({
|
|
309
315
|
path: video.videoPath,
|
|
310
316
|
coverPath: video.coverPath,
|
|
311
|
-
error:
|
|
317
|
+
error: describeSendFailure(err),
|
|
312
318
|
});
|
|
313
319
|
}
|
|
314
320
|
}
|