@ran-sh/dsh-crew 0.5.6 → 1.0.0

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.
Files changed (47) hide show
  1. package/README.md +20 -7
  2. package/README.zh.md +18 -7
  3. package/docs/installation.md +1 -1
  4. package/docs/ui-surfaces.md +65 -46
  5. package/lib/client.js +565 -28
  6. package/official-web-bridge/lib/client.js +565 -28
  7. package/package.json +1 -1
  8. package/src/client/collapsible-sections.mjs +3 -2
  9. package/src/client/host-readiness.mjs +16 -3
  10. package/src/client/index.tsx +331 -54
  11. package/src/config-readiness.mjs +66 -5
  12. package/src/credential-lifecycle.mjs +73 -0
  13. package/src/credential-purge-adapters.mjs +127 -0
  14. package/src/credential-purge-state.mjs +59 -0
  15. package/src/credential-reference-inventory.mjs +78 -0
  16. package/src/dsh-cli-runtime.mjs +36 -9
  17. package/src/extension-contract.mjs +16 -10
  18. package/src/hub/index.mjs +1004 -438
  19. package/src/hub-client.mjs +25 -5
  20. package/src/hub-compatibility.mjs +23 -7
  21. package/src/install/install.mjs +4 -4
  22. package/src/install/npx-lifecycle.mjs +495 -134
  23. package/src/job-contracts.mjs +27 -6
  24. package/src/jobs.mjs +2 -4
  25. package/src/local-request-guard.mjs +60 -0
  26. package/src/mcp-runtime.mjs +7 -5
  27. package/src/model-routing.mjs +141 -49
  28. package/src/multimodal.mjs +0 -0
  29. package/src/official-web-bridge.mjs +248 -95
  30. package/src/policy.mjs +62 -31
  31. package/src/provider-config-scrub.mjs +71 -0
  32. package/src/provider-delete-adapters.mjs +451 -0
  33. package/src/provider-desired-state.mjs +37 -0
  34. package/src/provider-health.mjs +124 -0
  35. package/src/provider-inventory.mjs +132 -0
  36. package/src/provider-lifecycle-state.mjs +95 -0
  37. package/src/provider-lifecycle.mjs +214 -0
  38. package/src/provider-profile-store.mjs +171 -0
  39. package/src/readiness-matrix.mjs +11 -5
  40. package/src/removable-waiter.mjs +29 -0
  41. package/src/runtime-identity.mjs +66 -21
  42. package/src/runtime-readiness-snapshot.mjs +87 -0
  43. package/src/server.mjs +64 -21
  44. package/src/status-shard.mjs +13 -2
  45. package/src/workflow-runtime.mjs +44 -10
  46. package/windows/start-dsh-crew.cmd +3 -3
  47. package/windows/start-dsh-crew.ps1 +49 -5
@@ -90,7 +90,7 @@ export async function hubStatus({ force = false } = {}) {
90
90
  endpoint: 'runtime',
91
91
  });
92
92
  }
93
- return cacheStatus(evaluateHubHandshake(runtime.body));
93
+ return cacheStatus(evaluateHubHandshake(runtime.body, { strictProduction: true }));
94
94
  } catch {
95
95
  return cacheStatus(EMPTY_STATUS);
96
96
  }
@@ -113,8 +113,26 @@ export function hubRequestError(body, status) {
113
113
  return err;
114
114
  }
115
115
 
116
- async function call(path, init) {
117
- const res = await fetch(`${API}${path}`, init);
116
+ // Transport deadlines: every Hub call is bounded so a wedged local HTTP
117
+ // exchange can never outlive the workflow timeout contract. Long polls get
118
+ // their requested wait plus grace; spawn gets a wider bound because worktree
119
+ // creation can clone sizeable repositories. The env override exists for
120
+ // deterministic deadline tests; production defaults stay at 10s.
121
+ const ENV_TIMEOUT_MS = Number(process.env.DSH_CREW_HUB_TIMEOUT_MS);
122
+ const DEFAULT_TIMEOUT_MS = Number.isInteger(ENV_TIMEOUT_MS) && ENV_TIMEOUT_MS > 0 ? ENV_TIMEOUT_MS : 10_000;
123
+ const SPAWN_TIMEOUT_MS = Math.max(DEFAULT_TIMEOUT_MS, 60_000);
124
+ const LONG_POLL_GRACE_MS = 5_000;
125
+
126
+ async function call(path, init, { timeoutMs = DEFAULT_TIMEOUT_MS } = {}) {
127
+ let res;
128
+ try {
129
+ res = await fetch(`${API}${path}`, { ...init, signal: AbortSignal.timeout(timeoutMs) });
130
+ } catch (err) {
131
+ if (err?.name === 'TimeoutError' || err?.name === 'AbortError') {
132
+ throw hubRequestError({ error: `hub request timed out after ${timeoutMs}ms` }, 0);
133
+ }
134
+ throw err;
135
+ }
118
136
  const body = await res.json();
119
137
  if (!res.ok || body.ok === false) throw hubRequestError(body, res.status);
120
138
  return body;
@@ -125,8 +143,10 @@ export const hub = {
125
143
  method: 'POST',
126
144
  headers: { 'content-type': 'application/json' },
127
145
  body: JSON.stringify(spec),
128
- }).then((b) => b.job),
146
+ }, { timeoutMs: SPAWN_TIMEOUT_MS }).then((b) => b.job),
129
147
  list: () => call('/jobs').then((b) => b.jobs),
130
- get: (id, waitSeconds = 0) => call(`/jobs/${id}?wait=${waitSeconds}`).then((b) => b.job),
148
+ get: (id, waitSeconds = 0) => call(`/jobs/${id}?wait=${waitSeconds}`, undefined, {
149
+ timeoutMs: waitSeconds > 0 ? (waitSeconds * 1000) + LONG_POLL_GRACE_MS : DEFAULT_TIMEOUT_MS,
150
+ }).then((b) => b.job),
131
151
  cancel: (id) => call(`/jobs/${id}/cancel`, { method: 'POST' }).then((b) => b.job),
132
152
  };
@@ -13,9 +13,16 @@ export function hubCompatibilityMessage(status = {}) {
13
13
  return `DSH workers hub is reachable but incompatible (${code}${detail}). Update/restart the Hub plugin before using Hub execution.`;
14
14
  }
15
15
 
16
- export function resolveHubExecutionMode(requestedMode = 'auto', status = {}) {
17
- if (requestedMode === 'standalone') {
18
- return { ok: true, mode: 'standalone', reason: 'explicit-standalone' };
16
+ export function resolveHubExecutionMode(requestedMode = 'auto', status = {}, { productionOnly = false } = {}) {
17
+ if (requestedMode === 'standalone') {
18
+ if (productionOnly) {
19
+ return {
20
+ ok: false,
21
+ code: 'STANDALONE_EXECUTION_DISABLED',
22
+ error: 'Standalone execution is disabled for the production 3210 Crew transport.',
23
+ };
24
+ }
25
+ return { ok: true, mode: 'standalone', reason: 'explicit-standalone' };
19
26
  }
20
27
 
21
28
  if (status.compatible === true) {
@@ -31,16 +38,25 @@ export function resolveHubExecutionMode(requestedMode = 'auto', status = {}) {
31
38
  };
32
39
  }
33
40
 
34
- if (requestedMode === 'hub') {
41
+ if (requestedMode === 'hub') {
35
42
  return {
36
43
  ok: false,
37
44
  code: status.code ?? HUB_COMPATIBILITY_CODES.UNREACHABLE,
38
45
  error: 'Session mode is "hub" but the DSH workers hub is not reachable.',
39
46
  hub: status,
40
47
  };
41
- }
42
-
43
- return {
48
+ }
49
+
50
+ if (productionOnly) {
51
+ return {
52
+ ok: false,
53
+ code: status.code ?? HUB_COMPATIBILITY_CODES.UNREACHABLE,
54
+ error: `Production 3210 Crew transport is unavailable (${status.code ?? HUB_COMPATIBILITY_CODES.UNREACHABLE}).`,
55
+ hub: status,
56
+ };
57
+ }
58
+
59
+ return {
44
60
  ok: true,
45
61
  mode: 'standalone',
46
62
  reason: 'hub-unreachable-fallback',
@@ -93,12 +93,12 @@ function legacySnapshotFrom(config = {}) {
93
93
  };
94
94
  }
95
95
 
96
- function attachReadMetadata(config, { version, canonical }) {
97
- return {
96
+ function attachReadMetadata(config, { version, canonical }) {
97
+ return {
98
98
  ...config,
99
99
  config_schema_version: version,
100
- config_authority: canonical ? 'canonical' : 'legacy-import',
101
- config_migration_required: !canonical,
100
+ config_authority: canonical ? 'canonical' : 'legacy-import',
101
+ config_migration_required: !canonical || version < CONFIG_SCHEMA_VERSION,
102
102
  config_activation: runtimeActivationMetadata(),
103
103
  };
104
104
  }