@ran-sh/dsh-crew 1.0.3 → 1.1.1
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/codex/AGENTS.md +101 -92
- package/docs/ui-surfaces.md +48 -21
- package/lib/client.js +68 -44
- package/official-web-bridge/lib/client.js +368 -4709
- package/official-web-bridge/package.json +1 -2
- package/package.json +130 -67
- package/scripts/build-client.mjs +30 -15
- package/scripts/remove-legacy-official-bridge.ps1 +89 -0
- package/scripts/setup.mjs +152 -140
- package/scripts/verify-npm-install.mjs +311 -310
- package/scripts/verify-official-bridge-e2e.mjs +12 -1
- package/src/client/host-readiness.mjs +62 -59
- package/src/client/index.tsx +35 -30
- package/src/client/quick-entry.tsx +10 -0
- package/src/client/quick-panel.tsx +295 -0
- package/src/client/surface-detection.mjs +43 -30
- package/src/dsh-cli-runtime.mjs +500 -40
- package/src/dsh-cohort.mjs +20 -0
- package/src/hub/index.mjs +1602 -1485
- package/src/install/npx-lifecycle.mjs +1568 -111
- package/src/install/official-web.mjs +36 -73
- package/src/jobs.mjs +20 -24
- package/src/official-web-bridge.mjs +329 -249
- package/src/provider-profile-store.mjs +12 -0
- package/src/provider-settings-store.mjs +347 -5
- package/src/runtime-identity.mjs +23 -1
- package/src/supervisor/restart-request.mjs +202 -0
- package/windows/start-dsh-crew.ps1 +792 -370
- package/worker.cordis.yml +32 -46
- package/zcode/AGENTS.md +35 -26
package/codex/AGENTS.md
CHANGED
|
@@ -1,92 +1,101 @@
|
|
|
1
|
-
# Global capability-aware delegation policy
|
|
2
|
-
|
|
3
|
-
The main Codex agent owns the user's task from planning through final delivery.
|
|
4
|
-
DSH Crew is an execution and review capability that Codex may use after
|
|
5
|
-
discovering what the current environment actually supports.
|
|
6
|
-
|
|
7
|
-
## Discover capabilities before delegation
|
|
8
|
-
|
|
9
|
-
- Before delegating substantial work, query DSH Crew's authoritative live
|
|
10
|
-
configuration, capability, and readiness surfaces.
|
|
11
|
-
- Discover capabilities dynamically from the returned contracts. Do not rely
|
|
12
|
-
on a hard-coded list of roles, models, providers, tools, modes, or optional
|
|
13
|
-
features; newly added capabilities should be considered automatically.
|
|
14
|
-
- For every relevant capability, respect its reported availability, activation
|
|
15
|
-
state, invocation mode, constraints, dependencies, and readiness evidence.
|
|
16
|
-
- Treat installed, configured, enabled, and callable as different states. Use a
|
|
17
|
-
capability only when the complete live execution path is ready.
|
|
18
|
-
- Keep the capability snapshot for the current plan, and refresh it after a
|
|
19
|
-
relevant configuration change or an availability, routing, credential,
|
|
20
|
-
compatibility, or activation failure.
|
|
21
|
-
- If discovery is unavailable or evidence is incomplete, fail closed: do not
|
|
22
|
-
invent capabilities or repeatedly dispatch blind retries. If DSH Crew was
|
|
23
|
-
selected for the task, apply the operator decision gate below.
|
|
24
|
-
|
|
25
|
-
## Operator decision gate when DSH Crew is unavailable
|
|
26
|
-
|
|
27
|
-
- Once Codex has selected DSH Crew for any work unit, any condition that makes
|
|
28
|
-
the required Crew capability unavailable or non-callable is a mandatory
|
|
29
|
-
pause point, regardless of cause.
|
|
30
|
-
- At this pause point, do not continue implementation, silently fall back,
|
|
31
|
-
choose another execution path, or repair/reconfigure DSH Crew without new
|
|
32
|
-
operator direction. Perform only the read-only diagnosis needed to report
|
|
33
|
-
the blocker accurately.
|
|
34
|
-
- Report the unavailable capability, bounded reason and evidence, and completed
|
|
35
|
-
work. Then wait for the operator to choose one direction:
|
|
36
|
-
1. Repair or restore DSH Crew, then continue through DSH Crew.
|
|
37
|
-
2. Do not repair DSH Crew; continue with the main Codex agent.
|
|
38
|
-
- Resume only after the operator gives a new instruction. If repair is chosen,
|
|
39
|
-
verify live capability again before dispatch. If local execution is chosen,
|
|
40
|
-
state that the affected work is no longer independently delegated.
|
|
41
|
-
- This gate applies only after DSH Crew has been selected or explicitly
|
|
42
|
-
requested. It does not force a pause when initial planning decides DSH Crew
|
|
43
|
-
provides no benefit and the task should remain with the main agent.
|
|
44
|
-
|
|
45
|
-
## Decide what to delegate
|
|
46
|
-
|
|
47
|
-
- Decompose the request into bounded work units before choosing an executor.
|
|
48
|
-
- Match each unit against discovered capabilities. Use DSH Crew only where it
|
|
49
|
-
provides a clear execution, isolation, parallelism, specialization, or
|
|
50
|
-
independent-review benefit.
|
|
51
|
-
- Delegate the smallest coherent unit that can be completed and verified
|
|
52
|
-
independently. Do not delegate an entire request merely because it is large.
|
|
53
|
-
- Keep ambiguity, dependency ordering, cross-cutting decisions, conflict
|
|
54
|
-
resolution, external side effects, final integration, and user communication
|
|
55
|
-
in the main Codex agent.
|
|
56
|
-
- Respect reported concurrency and isolation limits. Parallelize only
|
|
57
|
-
independent units with explicit, non-overlapping ownership.
|
|
58
|
-
- Simple questions, explanations, small read-only inspections, and genuinely
|
|
59
|
-
trivial edits should normally remain in the main agent.
|
|
60
|
-
- Explicit user instructions override default routing, but never safety or
|
|
61
|
-
capability boundaries.
|
|
62
|
-
|
|
63
|
-
## Execute and verify
|
|
64
|
-
|
|
65
|
-
- Give each delegated unit a concrete objective, owned scope, workspace
|
|
66
|
-
context, constraints, and required validation evidence.
|
|
67
|
-
- Prefer isolated execution for code changes when supported. Review work must
|
|
68
|
-
remain read-only.
|
|
69
|
-
- Consume compact structured results and canonical events. Do not move
|
|
70
|
-
unbounded transcripts, raw provider payloads, credentials, or unnecessary
|
|
71
|
-
patch content between agents.
|
|
72
|
-
- The main agent must validate results, tests, changed scope, unresolved risks,
|
|
73
|
-
and completion state before accepting delegated work.
|
|
74
|
-
|
|
75
|
-
## Review policy
|
|
76
|
-
|
|
77
|
-
- Use available independent review for non-trivial code changes when its live
|
|
78
|
-
invocation policy permits automatic use or the user requests manual use.
|
|
79
|
-
- Never bypass a manual, disabled, unavailable, or restricted review boundary.
|
|
80
|
-
- Treat requested changes, incomplete structured results, or missing direct
|
|
81
|
-
evidence as not approved.
|
|
82
|
-
- If selected DSH Crew review cannot run, apply the operator decision gate. The
|
|
83
|
-
main agent may review locally only after the operator selects that path.
|
|
84
|
-
|
|
85
|
-
## Authority and completion
|
|
86
|
-
|
|
87
|
-
- Delegation does not broaden authority. Publishing, pushing, messaging,
|
|
88
|
-
credential changes, account actions, destructive operations, and other
|
|
89
|
-
external effects still require authority from the user's request.
|
|
90
|
-
- Do not present delegated work as complete until validation passes, structured
|
|
91
|
-
results are complete, integration is checked, and permitted review
|
|
92
|
-
requirements are satisfied or transparently reported as unavailable.
|
|
1
|
+
# Global capability-aware delegation policy
|
|
2
|
+
|
|
3
|
+
The main Codex agent owns the user's task from planning through final delivery.
|
|
4
|
+
DSH Crew is an execution and review capability that Codex may use after
|
|
5
|
+
discovering what the current environment actually supports.
|
|
6
|
+
|
|
7
|
+
## Discover capabilities before delegation
|
|
8
|
+
|
|
9
|
+
- Before delegating substantial work, query DSH Crew's authoritative live
|
|
10
|
+
configuration, capability, and readiness surfaces.
|
|
11
|
+
- Discover capabilities dynamically from the returned contracts. Do not rely
|
|
12
|
+
on a hard-coded list of roles, models, providers, tools, modes, or optional
|
|
13
|
+
features; newly added capabilities should be considered automatically.
|
|
14
|
+
- For every relevant capability, respect its reported availability, activation
|
|
15
|
+
state, invocation mode, constraints, dependencies, and readiness evidence.
|
|
16
|
+
- Treat installed, configured, enabled, and callable as different states. Use a
|
|
17
|
+
capability only when the complete live execution path is ready.
|
|
18
|
+
- Keep the capability snapshot for the current plan, and refresh it after a
|
|
19
|
+
relevant configuration change or an availability, routing, credential,
|
|
20
|
+
compatibility, or activation failure.
|
|
21
|
+
- If discovery is unavailable or evidence is incomplete, fail closed: do not
|
|
22
|
+
invent capabilities or repeatedly dispatch blind retries. If DSH Crew was
|
|
23
|
+
selected for the task, apply the operator decision gate below.
|
|
24
|
+
|
|
25
|
+
## Operator decision gate when DSH Crew is unavailable
|
|
26
|
+
|
|
27
|
+
- Once Codex has selected DSH Crew for any work unit, any condition that makes
|
|
28
|
+
the required Crew capability unavailable or non-callable is a mandatory
|
|
29
|
+
pause point, regardless of cause.
|
|
30
|
+
- At this pause point, do not continue implementation, silently fall back,
|
|
31
|
+
choose another execution path, or repair/reconfigure DSH Crew without new
|
|
32
|
+
operator direction. Perform only the read-only diagnosis needed to report
|
|
33
|
+
the blocker accurately.
|
|
34
|
+
- Report the unavailable capability, bounded reason and evidence, and completed
|
|
35
|
+
work. Then wait for the operator to choose one direction:
|
|
36
|
+
1. Repair or restore DSH Crew, then continue through DSH Crew.
|
|
37
|
+
2. Do not repair DSH Crew; continue with the main Codex agent.
|
|
38
|
+
- Resume only after the operator gives a new instruction. If repair is chosen,
|
|
39
|
+
verify live capability again before dispatch. If local execution is chosen,
|
|
40
|
+
state that the affected work is no longer independently delegated.
|
|
41
|
+
- This gate applies only after DSH Crew has been selected or explicitly
|
|
42
|
+
requested. It does not force a pause when initial planning decides DSH Crew
|
|
43
|
+
provides no benefit and the task should remain with the main agent.
|
|
44
|
+
|
|
45
|
+
## Decide what to delegate
|
|
46
|
+
|
|
47
|
+
- Decompose the request into bounded work units before choosing an executor.
|
|
48
|
+
- Match each unit against discovered capabilities. Use DSH Crew only where it
|
|
49
|
+
provides a clear execution, isolation, parallelism, specialization, or
|
|
50
|
+
independent-review benefit.
|
|
51
|
+
- Delegate the smallest coherent unit that can be completed and verified
|
|
52
|
+
independently. Do not delegate an entire request merely because it is large.
|
|
53
|
+
- Keep ambiguity, dependency ordering, cross-cutting decisions, conflict
|
|
54
|
+
resolution, external side effects, final integration, and user communication
|
|
55
|
+
in the main Codex agent.
|
|
56
|
+
- Respect reported concurrency and isolation limits. Parallelize only
|
|
57
|
+
independent units with explicit, non-overlapping ownership.
|
|
58
|
+
- Simple questions, explanations, small read-only inspections, and genuinely
|
|
59
|
+
trivial edits should normally remain in the main agent.
|
|
60
|
+
- Explicit user instructions override default routing, but never safety or
|
|
61
|
+
capability boundaries.
|
|
62
|
+
|
|
63
|
+
## Execute and verify
|
|
64
|
+
|
|
65
|
+
- Give each delegated unit a concrete objective, owned scope, workspace
|
|
66
|
+
context, constraints, and required validation evidence.
|
|
67
|
+
- Prefer isolated execution for code changes when supported. Review work must
|
|
68
|
+
remain read-only.
|
|
69
|
+
- Consume compact structured results and canonical events. Do not move
|
|
70
|
+
unbounded transcripts, raw provider payloads, credentials, or unnecessary
|
|
71
|
+
patch content between agents.
|
|
72
|
+
- The main agent must validate results, tests, changed scope, unresolved risks,
|
|
73
|
+
and completion state before accepting delegated work.
|
|
74
|
+
|
|
75
|
+
## Review policy
|
|
76
|
+
|
|
77
|
+
- Use available independent review for non-trivial code changes when its live
|
|
78
|
+
invocation policy permits automatic use or the user requests manual use.
|
|
79
|
+
- Never bypass a manual, disabled, unavailable, or restricted review boundary.
|
|
80
|
+
- Treat requested changes, incomplete structured results, or missing direct
|
|
81
|
+
evidence as not approved.
|
|
82
|
+
- If selected DSH Crew review cannot run, apply the operator decision gate. The
|
|
83
|
+
main agent may review locally only after the operator selects that path.
|
|
84
|
+
|
|
85
|
+
## Authority and completion
|
|
86
|
+
|
|
87
|
+
- Delegation does not broaden authority. Publishing, pushing, messaging,
|
|
88
|
+
credential changes, account actions, destructive operations, and other
|
|
89
|
+
external effects still require authority from the user's request.
|
|
90
|
+
- Do not present delegated work as complete until validation passes, structured
|
|
91
|
+
results are complete, integration is checked, and permitted review
|
|
92
|
+
requirements are satisfied or transparently reported as unavailable.
|
|
93
|
+
|
|
94
|
+
## Harness upgrade redlines
|
|
95
|
+
|
|
96
|
+
- Never install, update, register, unlink, repair, or mutate anything under ~/.dsh.
|
|
97
|
+
- DSH Crew runtime upgrades must go through the Crew-owned installer and DSH_HOME.
|
|
98
|
+
- Never use direct pnpm/npm/dsh plugin operations against the official web profile.
|
|
99
|
+
- Preparing a Harness upgrade must not restart 3080 or 3210.
|
|
100
|
+
- Standalone workers launch through the official DSH SDK profile contract; dsh-sdk-jsonrpc-demo is obsolete.
|
|
101
|
+
- Legacy 3080 bridge must never be used for 3210 lifecycle/restart/rollback.
|
package/docs/ui-surfaces.md
CHANGED
|
@@ -1,46 +1,66 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 3210 and 3080 UI responsibilities
|
|
2
2
|
|
|
3
|
-
DSH Crew
|
|
4
|
-
client
|
|
3
|
+
DSH Crew presents two different user experiences from two independently built
|
|
4
|
+
client bundles. The native 3210 page is the canonical full control plane;
|
|
5
|
+
the official 3080 page is an optional narrow quick-controls panel.
|
|
5
6
|
|
|
6
|
-
##
|
|
7
|
+
## 3210: canonical full control plane
|
|
7
8
|
|
|
8
|
-
The
|
|
9
|
-
management:
|
|
9
|
+
The Crew-owned `dsh-crew` profile on `127.0.0.1:3210` owns day-to-day Crew
|
|
10
|
+
management AND model execution:
|
|
10
11
|
|
|
11
12
|
- Crew workflow and global enablement
|
|
12
13
|
- Worker and Reviewer policy
|
|
13
14
|
- model priority, fallback, review, and adaptive routing
|
|
14
|
-
-
|
|
15
|
-
-
|
|
15
|
+
- multimodal (vision/imagegen) capability switches
|
|
16
|
+
- providers lifecycle (migrate/delete/rollback/quarantine)
|
|
17
|
+
- credential references lifecycle
|
|
18
|
+
- workspaces, presets, jobs
|
|
19
|
+
- installation integrations (Codex, Claude, ZCode)
|
|
16
20
|
- task status and bounded model-invocation summaries
|
|
17
|
-
- the link to the underlying 3210 Crew Harness
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
Bundle: `lib/client.js` (module `@ran-sh/dsh-crew`), built from
|
|
23
|
+
`src/client/entry.tsx`.
|
|
21
24
|
|
|
22
|
-
##
|
|
25
|
+
## 3080: optional quick-controls surface
|
|
23
26
|
|
|
24
|
-
The
|
|
25
|
-
|
|
26
|
-
Providers, Harness Models, Agent presets, and native runtime settings.
|
|
27
|
+
The official Harness `web` profile on `127.0.0.1:3080` may host a NARROW
|
|
28
|
+
quick-controls card — and nothing else:
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
- master switch (`subagents_enabled`)
|
|
31
|
+
- Flash / Pro model priority lists (add/remove/reorder only)
|
|
32
|
+
- vision / imagegen toggles + providers (restart-pending flow)
|
|
33
|
+
- deep link to the 3210 full control plane (`http://127.0.0.1:3210/`)
|
|
34
|
+
|
|
35
|
+
Bundle: `official-web-bridge/lib/client.js` (module
|
|
36
|
+
`@ran-sh/dsh-crew-web-bridge`), built from `src/client/quick-entry.tsx`.
|
|
37
|
+
It physically contains none of the full control-plane code (no credential
|
|
38
|
+
purge, no provider delete/migration, no install integration).
|
|
39
|
+
|
|
40
|
+
The 3080 bridge proxies ONLY four exact endpoints to 3210:
|
|
41
|
+
`quick-config`, `quick-status`, `runtime/restart-request`,
|
|
42
|
+
`runtime/restart-status`. Everything else on the Crew namespace is 404 on
|
|
43
|
+
3080, and `/supervisor/restart` returns 410 Gone pointing at 3210.
|
|
44
|
+
|
|
45
|
+
The official `~/.dsh` tree is strictly read-only for Crew; the 3080 quick
|
|
46
|
+
surface itself is optional — Crew works fully with 3080 closed.
|
|
47
|
+
|
|
48
|
+
## UNKNOWN: diagnostics only
|
|
49
|
+
|
|
50
|
+
Unknown surfaces render diagnostics and never gain write authority.
|
|
31
51
|
|
|
32
52
|
## Surface detection and failure behavior
|
|
33
53
|
|
|
34
54
|
The client does not infer responsibility from a hard-coded browser port. It
|
|
35
55
|
uses two same-origin, structured signals:
|
|
36
56
|
|
|
37
|
-
1. `/_dsh/dsh-crew/bridge-status` identifies the official bridge
|
|
57
|
+
1. `/_dsh/dsh-crew/bridge-status` identifies the official quick bridge.
|
|
38
58
|
2. `/_dsh/dsh-crew/runtime` identifies the native Crew-owned runtime.
|
|
39
59
|
|
|
40
60
|
The bridge signal wins on 3080 because the proxied runtime response correctly
|
|
41
61
|
describes the 3210 backend. If neither contract can be verified, the client
|
|
42
|
-
fails closed to the
|
|
43
|
-
|
|
62
|
+
fails closed to the diagnostics view. Missing evidence never enables the
|
|
63
|
+
full control plane and never becomes `READY`.
|
|
44
64
|
|
|
45
65
|
The split changes presentation only. Crew state, credentials, routing policy,
|
|
46
66
|
and model execution remain isolated under the Crew-owned home and profile.
|
|
@@ -63,3 +83,10 @@ they do not authenticate local users. If a deployment ever needs to separate
|
|
|
63
83
|
local principals, add a per-install random token to state-changing calls and
|
|
64
84
|
inject it server-side in the bridge — do not use browser `Origin` as
|
|
65
85
|
authentication.
|
|
86
|
+
|
|
87
|
+
## Process ownership
|
|
88
|
+
|
|
89
|
+
The Windows launcher supervisor (`windows/start-dsh-crew.ps1` watch mode) is
|
|
90
|
+
the ONLY process authority for 3210. The 3080 bridge never spawns, owns, or
|
|
91
|
+
kills 3210. Restart and maintenance go through durable request files the hub
|
|
92
|
+
writes and the launcher executes (`supervisor/restart-request.mjs`).
|
package/lib/client.js
CHANGED
|
@@ -195,7 +195,7 @@ function runtimeState(runtime, readinessSnapshot) {
|
|
|
195
195
|
}
|
|
196
196
|
function bridgeState(surface) {
|
|
197
197
|
if (surface === "official-bridge") return READINESS_STATES.READY;
|
|
198
|
-
if (surface === "native-crew-harness") return READINESS_STATES.
|
|
198
|
+
if (surface === "native-crew-harness") return READINESS_STATES.UNKNOWN;
|
|
199
199
|
return READINESS_STATES.UNKNOWN;
|
|
200
200
|
}
|
|
201
201
|
/** Project only structured, non-secret installer/runtime evidence. */
|
|
@@ -265,12 +265,31 @@ function classifyCrewSurface({ bridgeStatus, runtime } = {}) {
|
|
|
265
265
|
if (runtime?.ok === true && runtime.service === "dsh-crew-hub" && (runtime.surface === CREW_UI_SURFACES.NATIVE || runtime.surface === void 0)) return CREW_UI_SURFACES.NATIVE;
|
|
266
266
|
return CREW_UI_SURFACES.UNKNOWN;
|
|
267
267
|
}
|
|
268
|
+
/**
|
|
269
|
+
* Surface capability model. The NATIVE 3210 Crew harness is the single full
|
|
270
|
+
* control plane; the OFFICIAL 3080 surface is a narrow quick-controls panel
|
|
271
|
+
* (total switch, flash/pro model priority, vision/imagegen toggles) plus a
|
|
272
|
+
* deep link back to 3210. Unknown surfaces get diagnostics only — never write
|
|
273
|
+
* authority. This replaces the old binary full-vs-minimal assumption.
|
|
274
|
+
*/
|
|
268
275
|
function surfaceResponsibilities(surface) {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
276
|
+
switch (surface) {
|
|
277
|
+
case CREW_UI_SURFACES.NATIVE: return {
|
|
278
|
+
fullControlPlane: true,
|
|
279
|
+
quickControlPlane: true,
|
|
280
|
+
diagnostics: true
|
|
281
|
+
};
|
|
282
|
+
case CREW_UI_SURFACES.OFFICIAL: return {
|
|
283
|
+
fullControlPlane: false,
|
|
284
|
+
quickControlPlane: true,
|
|
285
|
+
diagnostics: true
|
|
286
|
+
};
|
|
287
|
+
default: return {
|
|
288
|
+
fullControlPlane: false,
|
|
289
|
+
quickControlPlane: false,
|
|
290
|
+
diagnostics: true
|
|
291
|
+
};
|
|
292
|
+
}
|
|
274
293
|
}
|
|
275
294
|
//#endregion
|
|
276
295
|
//#region src/client/task-telemetry.mjs
|
|
@@ -1591,7 +1610,7 @@ function WorkersPanel({ ctx }) {
|
|
|
1591
1610
|
} catch {}
|
|
1592
1611
|
}, [get]);
|
|
1593
1612
|
(0, react.useEffect)(() => {
|
|
1594
|
-
if (surface
|
|
1613
|
+
if (!surfaceResponsibilities(surface).fullControlPlane) return void 0;
|
|
1595
1614
|
refreshAll();
|
|
1596
1615
|
const timer = setInterval(() => {
|
|
1597
1616
|
Promise.all([get("/jobs"), get("/provider-health").catch(() => null)]).then(([j, health]) => {
|
|
@@ -1675,10 +1694,10 @@ function WorkersPanel({ ctx }) {
|
|
|
1675
1694
|
withLang
|
|
1676
1695
|
]);
|
|
1677
1696
|
(0, react.useEffect)(() => {
|
|
1678
|
-
if (surface
|
|
1697
|
+
if (surfaceResponsibilities(surface).fullControlPlane) refreshHarnessModels();
|
|
1679
1698
|
}, [surface, refreshHarnessModels]);
|
|
1680
1699
|
(0, react.useEffect)(() => {
|
|
1681
|
-
if (surface
|
|
1700
|
+
if (surfaceResponsibilities(surface).fullControlPlane) refreshProviderInventory();
|
|
1682
1701
|
}, [surface, refreshProviderInventory]);
|
|
1683
1702
|
const act = (0, react.useCallback)(async (target, confirmName) => {
|
|
1684
1703
|
if (confirmName && !window.confirm(copy.confirmRestore(confirmName))) return;
|
|
@@ -1721,6 +1740,34 @@ function WorkersPanel({ ctx }) {
|
|
|
1721
1740
|
get,
|
|
1722
1741
|
copy
|
|
1723
1742
|
]);
|
|
1743
|
+
/** Request a Crew 3210 restart through the durable supervisor channel
|
|
1744
|
+
* (hub writes the request; the Windows watcher executes it). Polls until
|
|
1745
|
+
* VERIFIED or a terminal failure. Same-origin against the 3210 API — the
|
|
1746
|
+
* legacy 3080 supervisor endpoint is retired. */
|
|
1747
|
+
const requestRestart = (0, react.useCallback)(async (reason) => {
|
|
1748
|
+
const created = await post("/runtime/restart-request", {
|
|
1749
|
+
confirm: true,
|
|
1750
|
+
reason: reason ?? "configuration change"
|
|
1751
|
+
});
|
|
1752
|
+
if (!created.ok) throw new Error(created.code ?? created.error ?? copy.providerLifecycleError);
|
|
1753
|
+
const requestId = created.request_id;
|
|
1754
|
+
const deadline = Date.now() + 9e4;
|
|
1755
|
+
for (;;) {
|
|
1756
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
1757
|
+
if (Date.now() > deadline) throw new Error("Crew restart timed out");
|
|
1758
|
+
const status = await get(`/runtime/restart-status?id=${encodeURIComponent(requestId)}`);
|
|
1759
|
+
if (!status.ok) continue;
|
|
1760
|
+
if (status.state === "VERIFIED") return {
|
|
1761
|
+
ok: true,
|
|
1762
|
+
...status
|
|
1763
|
+
};
|
|
1764
|
+
if (status.state !== "RESTART_REQUESTED") throw new Error(status.state ?? "Crew restart failed");
|
|
1765
|
+
}
|
|
1766
|
+
}, [
|
|
1767
|
+
post,
|
|
1768
|
+
get,
|
|
1769
|
+
copy
|
|
1770
|
+
]);
|
|
1724
1771
|
/** Selects & checkboxes: apply immediately. */
|
|
1725
1772
|
const field = (key, value) => {
|
|
1726
1773
|
setConfig((c) => ({
|
|
@@ -2020,13 +2067,7 @@ function WorkersPanel({ ctx }) {
|
|
|
2020
2067
|
}), path);
|
|
2021
2068
|
if (!result.ok) throw new Error(result.code ?? result.error ?? copy.providerLifecycleError);
|
|
2022
2069
|
if (result.restart_required === true && result.result?.state === "RESTART_PENDING") {
|
|
2023
|
-
|
|
2024
|
-
const restarted = await readJson(await fetch(restartPath, {
|
|
2025
|
-
method: "POST",
|
|
2026
|
-
headers: { "content-type": "application/json" },
|
|
2027
|
-
body: JSON.stringify({ confirm: true })
|
|
2028
|
-
}), restartPath);
|
|
2029
|
-
if (!restarted.ok) throw new Error(restarted.code ?? restarted.error ?? copy.providerLifecycleError);
|
|
2070
|
+
await requestRestart("provider delete");
|
|
2030
2071
|
const verified = await post(`/providers/${encoded}/verify-delete`, {
|
|
2031
2072
|
transaction_id: planned.plan.plan_id,
|
|
2032
2073
|
confirm: true
|
|
@@ -2065,13 +2106,7 @@ function WorkersPanel({ ctx }) {
|
|
|
2065
2106
|
});
|
|
2066
2107
|
if (!result.ok) throw new Error(result.code ?? result.error ?? copy.providerLifecycleError);
|
|
2067
2108
|
if (result.restart_required === true && result.result?.state === "RESTART_PENDING") {
|
|
2068
|
-
|
|
2069
|
-
const restarted = await readJson(await fetch(restartPath, {
|
|
2070
|
-
method: "POST",
|
|
2071
|
-
headers: { "content-type": "application/json" },
|
|
2072
|
-
body: JSON.stringify({ confirm: true })
|
|
2073
|
-
}), restartPath);
|
|
2074
|
-
if (!restarted.ok) throw new Error(restarted.code ?? restarted.error ?? copy.providerLifecycleError);
|
|
2109
|
+
await requestRestart("provider migrate");
|
|
2075
2110
|
const verified = await post(`/providers/${encoded}/verify-migration`, {
|
|
2076
2111
|
transaction_id: planned.plan.plan_id,
|
|
2077
2112
|
confirm: true
|
|
@@ -2100,15 +2135,7 @@ function WorkersPanel({ ctx }) {
|
|
|
2100
2135
|
confirm: true
|
|
2101
2136
|
});
|
|
2102
2137
|
if (!result.ok) throw new Error(result.code ?? result.error ?? copy.providerLifecycleError);
|
|
2103
|
-
if (result.restart_required === true)
|
|
2104
|
-
const restartPath = "http://127.0.0.1:3080/_dsh/dsh-crew/supervisor/restart";
|
|
2105
|
-
const restarted = await readJson(await fetch(restartPath, {
|
|
2106
|
-
method: "POST",
|
|
2107
|
-
headers: { "content-type": "application/json" },
|
|
2108
|
-
body: JSON.stringify({ confirm: true })
|
|
2109
|
-
}), restartPath);
|
|
2110
|
-
if (!restarted.ok) throw new Error(restarted.code ?? restarted.error ?? copy.providerLifecycleError);
|
|
2111
|
-
}
|
|
2138
|
+
if (result.restart_required === true) await requestRestart("provider migrate");
|
|
2112
2139
|
setNotice(copy.saved);
|
|
2113
2140
|
await refreshProviderInventory();
|
|
2114
2141
|
} catch (error) {
|
|
@@ -2153,13 +2180,7 @@ function WorkersPanel({ ctx }) {
|
|
|
2153
2180
|
});
|
|
2154
2181
|
if (!result.ok) throw new Error(result.code ?? result.error ?? copy.providerLifecycleError);
|
|
2155
2182
|
if (result.restart_required === true && result.state === "ROLLBACK_PENDING") {
|
|
2156
|
-
|
|
2157
|
-
const restarted = await readJson(await fetch(restartPath, {
|
|
2158
|
-
method: "POST",
|
|
2159
|
-
headers: { "content-type": "application/json" },
|
|
2160
|
-
body: JSON.stringify({ confirm: true })
|
|
2161
|
-
}), restartPath);
|
|
2162
|
-
if (!restarted.ok) throw new Error(restarted.code ?? restarted.error ?? copy.providerLifecycleError);
|
|
2183
|
+
await requestRestart("provider migrate");
|
|
2163
2184
|
const verified = await post(`/providers/${encoded}/verify-rollback`, {
|
|
2164
2185
|
transaction_id: transactionId,
|
|
2165
2186
|
confirm: true
|
|
@@ -4754,7 +4775,7 @@ function WorkersPanel({ ctx }) {
|
|
|
4754
4775
|
}
|
|
4755
4776
|
function apply$1(ctx) {
|
|
4756
4777
|
let runningCount = 0;
|
|
4757
|
-
let
|
|
4778
|
+
let badgeSurface = null;
|
|
4758
4779
|
ctx.slots.inject("settings.section", () => {
|
|
4759
4780
|
let dispose = register();
|
|
4760
4781
|
function register() {
|
|
@@ -4783,11 +4804,14 @@ function apply$1(ctx) {
|
|
|
4783
4804
|
const poll = async () => {
|
|
4784
4805
|
if (document.visibilityState !== "visible") return;
|
|
4785
4806
|
try {
|
|
4786
|
-
if (
|
|
4787
|
-
const
|
|
4788
|
-
|
|
4807
|
+
if (badgeSurface === null) {
|
|
4808
|
+
const [bridgeStatus, runtime] = await Promise.all([fetch(`${API}/bridge-status`, { cache: "no-store" }).then((r) => r.ok ? r.json() : null).catch(() => null), fetch(`${API}/runtime`, { cache: "no-store" }).then((r) => r.ok ? r.json() : null).catch(() => null)]);
|
|
4809
|
+
badgeSurface = surfaceResponsibilities(classifyCrewSurface({
|
|
4810
|
+
bridgeStatus,
|
|
4811
|
+
runtime
|
|
4812
|
+
})).fullControlPlane;
|
|
4789
4813
|
}
|
|
4790
|
-
if (!
|
|
4814
|
+
if (!badgeSurface) return;
|
|
4791
4815
|
const r = await (await fetch(`${API}/jobs`, { cache: "no-store" })).json();
|
|
4792
4816
|
const n = r.ok ? (r.jobs ?? []).filter((j) => j.status === "running").length : 0;
|
|
4793
4817
|
if (n !== runningCount) {
|