@ran-sh/dsh-crew 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,9 +17,13 @@ dsh-crew integrate
17
17
  dsh-crew status
18
18
  ```
19
19
 
20
- Open <http://127.0.0.1:3080> for the daily console. On Windows, installation
21
- also registers login startup for the 3080 console; its official bridge starts
22
- and owns the isolated 3210 Harness backend.
20
+ Open <http://127.0.0.1:3080> for the daily console. On Windows, installation
21
+ also registers login startup for the 3080 console; its official bridge starts
22
+ and owns the isolated 3210 Harness backend.
23
+
24
+ Fresh installs contain only the built-in DeepSeek route. Add your own provider
25
+ credentials, model priorities, and optional integrations in the local Settings;
26
+ they are never bundled into this package.
23
27
 
24
28
  | Surface | Purpose |
25
29
  | --- | --- |
@@ -42,26 +46,26 @@ silently falling back.
42
46
  ## Useful commands
43
47
 
44
48
  ```bash
45
- dsh-crew inspect # live capabilities and readiness
46
- dsh-crew jobs list # jobs and Result Contracts
47
- dsh-crew providers list # 3210 Harness provider inventory (secret-free)
48
- dsh-crew providers probe <provider-id>
49
- curl http://127.0.0.1:3210/_dsh/dsh-crew/credential-references # references/orphans only
50
- dsh-crew credentials list # secret-free reference inventory
51
- dsh-crew credentials purge-plan env:NAME
52
- dsh-crew credentials purge env:NAME --plan <plan-id> --expected-revision <sha256> --confirm
53
- dsh-crew providers delete-plan <provider-id> --replacement-default <provider-id>
54
- dsh-crew providers delete <provider-id> --plan <plan-id> --expected-revision <sha256> --confirm
55
- dsh-crew releases list # retained validated payloads
56
- dsh-crew rollback <version> # switch payload and verify the 3210 runtime
57
- dsh-crew update # update and repair enabled integrations
49
+ dsh-crew inspect # live capabilities and readiness
50
+ dsh-crew jobs list # jobs and Result Contracts
51
+ dsh-crew providers list # 3210 Harness provider inventory (secret-free)
52
+ dsh-crew providers probe <provider-id>
53
+ curl http://127.0.0.1:3210/_dsh/dsh-crew/credential-references # references/orphans only
54
+ dsh-crew credentials list # secret-free reference inventory
55
+ dsh-crew credentials purge-plan env:NAME
56
+ dsh-crew credentials purge env:NAME --plan <plan-id> --expected-revision <sha256> --confirm
57
+ dsh-crew providers delete-plan <provider-id> --replacement-default <provider-id>
58
+ dsh-crew providers delete <provider-id> --plan <plan-id> --expected-revision <sha256> --confirm
59
+ dsh-crew releases list # retained validated payloads
60
+ dsh-crew rollback <version> # switch payload and verify the 3210 runtime
61
+ dsh-crew update # update and repair enabled integrations
58
62
  dsh-crew uninstall # remove managed files, keep backups/config
59
63
  ```
60
64
 
61
- The runtime is isolated under `~/.config/dsh-crew/harness` with `profile: dsh-crew`;
62
- the official `web` profile receives only the 3080 bridge.
63
- All production Worker/Reviewer model calls are executed by the isolated 3210
64
- Crew Harness; 3080 is a control-plane bridge only.
65
+ The runtime is isolated under `~/.config/dsh-crew/harness` with `profile: dsh-crew`;
66
+ the official `web` profile receives only the 3080 bridge.
67
+ All production Worker/Reviewer model calls are executed by the isolated 3210
68
+ Crew Harness; 3080 is a control-plane bridge only.
65
69
 
66
70
  ## Legacy launcher migration
67
71
 
package/README.zh.md CHANGED
@@ -16,8 +16,11 @@ dsh-crew integrate
16
16
  dsh-crew status
17
17
  ```
18
18
 
19
- 打开 <http://127.0.0.1:3080> 进入日常控制台。Windows 安装会注册当前用户的
20
- 登录启动项,先启动 3080 控制台,再由官方桥接启动并监管隔离的 3210 Harness。
19
+ 打开 <http://127.0.0.1:3080> 进入日常控制台。Windows 安装会注册当前用户的
20
+ 登录启动项,先启动 3080 控制台,再由官方桥接启动并监管隔离的 3210 Harness。
21
+
22
+ 全新安装只包含内置 DeepSeek 路由。其他 Provider 凭据、模型优先级和可选集成需要
23
+ 在本机设置中自行配置,绝不会打包进发布版本。
21
24
 
22
25
  | 界面 | 用途 |
23
26
  | --- | --- |
@@ -38,25 +41,25 @@ dsh-crew status
38
41
  ## 常用命令
39
42
 
40
43
  ```bash
41
- dsh-crew inspect # 实时能力与就绪度
42
- dsh-crew jobs list # 任务与 Result Contract
43
- dsh-crew providers list # 3210 Harness Provider 清单(不含密钥)
44
- dsh-crew providers probe <provider-id>
45
- curl http://127.0.0.1:3210/_dsh/dsh-crew/credential-references # 仅查看引用/孤儿报告
46
- dsh-crew credentials list # 不含密钥值的引用清单
47
- dsh-crew credentials purge-plan env:NAME
48
- dsh-crew credentials purge env:NAME --plan <plan-id> --expected-revision <sha256> --confirm
49
- dsh-crew providers delete-plan <provider-id> --replacement-default <provider-id>
50
- dsh-crew providers delete <provider-id> --plan <plan-id> --expected-revision <sha256> --confirm
51
- dsh-crew releases list # 查看保留且已验证的版本
52
- dsh-crew rollback <version> # 切换版本并验证 3210 runtime
53
- dsh-crew update # 更新并修复已启用集成
44
+ dsh-crew inspect # 实时能力与就绪度
45
+ dsh-crew jobs list # 任务与 Result Contract
46
+ dsh-crew providers list # 3210 Harness Provider 清单(不含密钥)
47
+ dsh-crew providers probe <provider-id>
48
+ curl http://127.0.0.1:3210/_dsh/dsh-crew/credential-references # 仅查看引用/孤儿报告
49
+ dsh-crew credentials list # 不含密钥值的引用清单
50
+ dsh-crew credentials purge-plan env:NAME
51
+ dsh-crew credentials purge env:NAME --plan <plan-id> --expected-revision <sha256> --confirm
52
+ dsh-crew providers delete-plan <provider-id> --replacement-default <provider-id>
53
+ dsh-crew providers delete <provider-id> --plan <plan-id> --expected-revision <sha256> --confirm
54
+ dsh-crew releases list # 查看保留且已验证的版本
55
+ dsh-crew rollback <version> # 切换版本并验证 3210 runtime
56
+ dsh-crew update # 更新并修复已启用集成
54
57
  dsh-crew uninstall # 移除受管文件,保留配置/备份
55
58
  ```
56
59
 
57
- 运行时隔离在 `~/.config/dsh-crew/harness`,使用 `profile: dsh-crew`;官方 `web` profile
58
- 只接收 3080 轻量桥接。
59
- 生产 Worker/Reviewer 的模型调用全部由隔离的 3210 Crew Harness 执行,3080 仅作为控制面桥接。
60
+ 运行时隔离在 `~/.config/dsh-crew/harness`,使用 `profile: dsh-crew`;官方 `web` profile
61
+ 只接收 3080 轻量桥接。
62
+ 生产 Worker/Reviewer 的模型调用全部由隔离的 3210 Crew Harness 执行,3080 仅作为控制面桥接。
60
63
 
61
64
  ## 旧启动器迁移
62
65
 
package/lib/client.js CHANGED
@@ -509,6 +509,8 @@ const COPY = {
509
509
  providerState: (state) => `状态:${state}`,
510
510
  providerModels: (count) => `${count} 个模型`,
511
511
  providerJobs: (count) => `${count} 个运行任务`,
512
+ providerOfficialBuiltin: "· 官方内置(不可删除)",
513
+ providerSourceUnresolved: "· 来源未解析(安全锁定)",
512
514
  providerDeletePlan: "生成删除计划",
513
515
  providerDelete: "确认删除",
514
516
  providerPlanReady: "计划已生成;再次确认后才会修改 3210 配置。",
@@ -519,6 +521,12 @@ const COPY = {
519
521
  providerDeleteConfirm: "确认按计划删除这个 Harness Provider?会清理路由引用并重启 3210。",
520
522
  providerDeleteBlocked: "当前 Provider 不能删除(内置、在用、已删除或缺少可用替换)。",
521
523
  providerLifecycleError: "Provider 生命周期操作失败",
524
+ providerDeletePending: "配置可能已变更,事务仍待重启/验证;请刷新状态后选择回滚。",
525
+ providerRollbackContinue: "继续回滚验证",
526
+ recoveryUnresolved: "发现不可自动恢复的事务",
527
+ recoveryStorage: "存储项",
528
+ recoveryQuarantine: "隔离",
529
+ recoveryQuarantineConfirm: "该事务清单无法安全恢复。将其移入隔离区并阻止自动使用,继续?",
522
530
  providerNoInventory: "暂时无法读取 3210 Provider inventory。",
523
531
  credentialReferences: "Credential 引用",
524
532
  credentialReferenceHint: "仅显示引用名、归属和孤儿状态;不会读取或删除密钥。",
@@ -832,6 +840,8 @@ const COPY = {
832
840
  providerState: (state) => `State: ${state}`,
833
841
  providerModels: (count) => `${count} models`,
834
842
  providerJobs: (count) => `${count} running jobs`,
843
+ providerOfficialBuiltin: "· official built-in (immutable)",
844
+ providerSourceUnresolved: "· source unresolved (locked)",
835
845
  providerDeletePlan: "Plan deletion",
836
846
  providerDelete: "Confirm delete",
837
847
  providerPlanReady: "Plan ready; a second confirmation is required before changing 3210 config.",
@@ -842,6 +852,12 @@ const COPY = {
842
852
  providerDeleteConfirm: "Delete this Harness Provider per the plan? Routing refs will be scrubbed and 3210 restarted.",
843
853
  providerDeleteBlocked: "This Provider cannot be deleted (built-in, in use, already absent, or missing a valid replacement).",
844
854
  providerLifecycleError: "Provider lifecycle operation failed",
855
+ providerDeletePending: "Configuration may already be changed; the transaction still needs restart/verification. Refresh status and use rollback if needed.",
856
+ providerRollbackContinue: "Continue rollback verification",
857
+ recoveryUnresolved: "An unrecoverable recovery transaction is blocking deletion",
858
+ recoveryStorage: "storage entry",
859
+ recoveryQuarantine: "Quarantine",
860
+ recoveryQuarantineConfirm: "This recovery manifest cannot be safely reopened. Move it into the quarantine area and keep it out of automatic recovery?",
845
861
  providerNoInventory: "3210 Provider inventory is temporarily unavailable.",
846
862
  credentialReferences: "Credential references",
847
863
  credentialReferenceHint: "Names, ownership, and orphan status only; values are never read or deleted.",
@@ -1959,13 +1975,13 @@ function WorkersPanel({ ctx }) {
1959
1975
  applyPatch(patch);
1960
1976
  };
1961
1977
  const deleteHarnessProvider = async (record) => {
1962
- if (!record || record.ownership === "harness" || record.desired_state === "absent" || Number(record.references?.active_jobs ?? 0) > 0) {
1978
+ if (!record || record.delete_capability !== "supported" || record.desired_state === "absent" || Number(record.references?.active_jobs ?? 0) > 0) {
1963
1979
  setNotice(copy.providerDeleteBlocked);
1964
1980
  return;
1965
1981
  }
1966
1982
  let replacementDefault;
1967
1983
  if (record.references?.harness_default === true) {
1968
- const candidate = (providerInventory?.records ?? []).find((item) => item.id !== record.id && item.desired_state !== "absent" && item.ownership !== "harness" && (item.models?.length ?? 0) > 0)?.id ?? "";
1984
+ const candidate = (providerInventory?.records ?? []).find((item) => item.id === "deepseek-official" && item.id !== record.id && item.desired_state !== "absent" && (item.models?.length ?? 0) > 0)?.id ?? (providerInventory?.records ?? []).find((item) => item.id !== record.id && item.desired_state !== "absent" && item.delete_capability !== "source-unresolved" && (item.models?.length ?? 0) > 0)?.id ?? "";
1969
1985
  const entered = window.prompt(copy.providerReplacement, candidate);
1970
1986
  if (!entered?.trim()) return;
1971
1987
  replacementDefault = entered.trim();
@@ -2006,13 +2022,29 @@ function WorkersPanel({ ctx }) {
2006
2022
  setNotice(copy.saved);
2007
2023
  await refreshProviderInventory();
2008
2024
  } catch (error) {
2009
- setNotice(String(error?.message ?? error));
2025
+ try {
2026
+ await refreshProviderInventory();
2027
+ } catch {}
2028
+ setNotice(`${String(error?.message ?? error)} · ${copy.providerDeletePending}`);
2010
2029
  } finally {
2011
2030
  setProviderLifecycleBusy(null);
2012
2031
  }
2013
2032
  };
2014
- const rollbackHarnessProvider = async (record, transactionId) => {
2015
- if (!record || !transactionId || record.desired_state !== "absent") {
2033
+ const rollbackHarnessProvider = async (record, transactionId, transactionState = "VERIFIED") => {
2034
+ const continuing = ["ROLLBACK_PENDING", "ROLLBACK_RESTART_PENDING"].includes(transactionState);
2035
+ const recoverable = [
2036
+ "PLANNED",
2037
+ "TOMBSTONE_APPLYING",
2038
+ "TOMBSTONE_APPLIED",
2039
+ "REFERENCES_APPLYING",
2040
+ "REFERENCES_APPLIED",
2041
+ "DECLARATIONS_APPLYING",
2042
+ "DECLARATIONS_APPLIED",
2043
+ "DELETE_RESTART_PENDING",
2044
+ "ROLLBACK_APPLYING",
2045
+ "ROLLBACK_RESTORED"
2046
+ ].includes(transactionState);
2047
+ if (!record || !transactionId || !continuing && !recoverable && record.desired_state !== "absent") {
2016
2048
  setNotice(copy.providerRollbackUnavailable);
2017
2049
  return;
2018
2050
  }
@@ -2021,7 +2053,11 @@ function WorkersPanel({ ctx }) {
2021
2053
  setNotice(copy.working);
2022
2054
  try {
2023
2055
  const encoded = encodeURIComponent(record.id);
2024
- const result = await post(`/providers/${encoded}/rollback`, {
2056
+ const result = continuing ? {
2057
+ ok: true,
2058
+ restart_required: true,
2059
+ state: "ROLLBACK_PENDING"
2060
+ } : await post(`/providers/${encoded}/rollback`, {
2025
2061
  transaction_id: transactionId,
2026
2062
  confirm: true
2027
2063
  });
@@ -2043,6 +2079,32 @@ function WorkersPanel({ ctx }) {
2043
2079
  setNotice(copy.saved);
2044
2080
  await refreshProviderInventory();
2045
2081
  } catch (error) {
2082
+ try {
2083
+ await refreshProviderInventory();
2084
+ } catch {}
2085
+ setNotice(`${String(error?.message ?? error)} · ${copy.providerDeletePending}`);
2086
+ } finally {
2087
+ setProviderLifecycleBusy(null);
2088
+ }
2089
+ };
2090
+ const quarantineRecoveryTransaction = async (entry) => {
2091
+ const actionId = typeof entry?.action_id === "string" ? entry.action_id : "";
2092
+ if (!actionId || entry?.recoverable === true) return;
2093
+ if (!window.confirm(copy.recoveryQuarantineConfirm)) return;
2094
+ setProviderLifecycleBusy(`quarantine:${actionId}`);
2095
+ setNotice(copy.working);
2096
+ try {
2097
+ const result = await post("/providers/_recovery/quarantine", {
2098
+ action_id: actionId,
2099
+ confirm: true
2100
+ });
2101
+ if (!result.ok) throw new Error(result.code ?? result.error ?? copy.providerLifecycleError);
2102
+ setNotice(copy.saved);
2103
+ await refreshProviderInventory();
2104
+ } catch (error) {
2105
+ try {
2106
+ await refreshProviderInventory();
2107
+ } catch {}
2046
2108
  setNotice(String(error?.message ?? error));
2047
2109
  } finally {
2048
2110
  setProviderLifecycleBusy(null);
@@ -3040,7 +3102,7 @@ function WorkersPanel({ ctx }) {
3040
3102
  style: S.fieldLabel,
3041
3103
  children: copy.workerProvider
3042
3104
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CustomSelect, {
3043
- value: config.worker_provider_mode ?? "follow-dsh",
3105
+ value: config.worker_provider_mode ?? "deepseek-official",
3044
3106
  onChange: (v) => field("worker_provider_mode", v),
3045
3107
  options: ["follow-dsh", "deepseek-official"].map((m) => ({
3046
3108
  value: m,
@@ -3588,9 +3650,31 @@ function WorkersPanel({ ctx }) {
3588
3650
  children: copy.providerNoInventory
3589
3651
  }),
3590
3652
  (providerInventory?.records ?? []).map((record) => {
3591
- const blocked = record.ownership === "harness" || record.desired_state === "absent" || Number(record.references?.active_jobs ?? 0) > 0;
3653
+ const immutable = record.delete_capability === "immutable-builtin";
3654
+ const unresolved = record.delete_capability === "source-unresolved";
3655
+ const blocked = immutable || unresolved || record.desired_state === "absent" || Number(record.references?.active_jobs ?? 0) > 0;
3592
3656
  const lifecycle = record.desired_state === "absent" ? "absent" : record.lifecycle?.enabled === false ? "disabled" : record.lifecycle?.catalogued ? "catalogued" : "configured";
3593
- const rollbackTransaction = (providerInventory?.lifecycle_transactions ?? []).find((entry) => entry.provider_id === record.id && ["VERIFIED", "RESTART_PENDING"].includes(entry.state));
3657
+ const lifecycleTransactions = providerInventory?.lifecycle_transactions ?? [];
3658
+ const recoveryTransactions = (providerInventory?.recovery_transactions ?? []).map((entry) => ({
3659
+ ...entry,
3660
+ state: entry.phase
3661
+ }));
3662
+ const rollbackTransaction = [...lifecycleTransactions, ...recoveryTransactions].filter((entry) => entry.provider_id === record.id && [
3663
+ "VERIFIED",
3664
+ "RESTART_PENDING",
3665
+ "ROLLBACK_PENDING",
3666
+ "PLANNED",
3667
+ "TOMBSTONE_APPLYING",
3668
+ "TOMBSTONE_APPLIED",
3669
+ "REFERENCES_APPLYING",
3670
+ "REFERENCES_APPLIED",
3671
+ "DECLARATIONS_APPLYING",
3672
+ "DECLARATIONS_APPLIED",
3673
+ "DELETE_RESTART_PENDING",
3674
+ "ROLLBACK_RESTART_PENDING",
3675
+ "ROLLBACK_RESTORED",
3676
+ "ROLLBACK_APPLYING"
3677
+ ].includes(entry.state)).sort((a, b) => String(a.updated_at ?? "").localeCompare(String(b.updated_at ?? ""))).at(-1);
3594
3678
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3595
3679
  style: {
3596
3680
  display: "flex",
@@ -3619,12 +3703,20 @@ function WorkersPanel({ ctx }) {
3619
3703
  style: { opacity: .65 },
3620
3704
  children: copy.providerModels(record.models?.length ?? 0)
3621
3705
  }),
3706
+ immutable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3707
+ style: { opacity: .65 },
3708
+ children: copy.providerOfficialBuiltin
3709
+ }),
3710
+ unresolved && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3711
+ style: { color: "#c98735" },
3712
+ children: copy.providerSourceUnresolved
3713
+ }),
3622
3714
  Number(record.references?.active_jobs ?? 0) > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3623
3715
  style: { color: "#c98735" },
3624
3716
  children: copy.providerJobs(record.references.active_jobs)
3625
3717
  }),
3626
3718
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: { flex: 1 } }),
3627
- record.ownership !== "harness" && record.desired_state !== "absent" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3719
+ record.delete_capability === "supported" && record.desired_state !== "absent" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3628
3720
  type: "button",
3629
3721
  style: {
3630
3722
  ...S.btn,
@@ -3636,7 +3728,20 @@ function WorkersPanel({ ctx }) {
3636
3728
  },
3637
3729
  children: providerLifecycleBusy === record.id ? copy.working : copy.providerDeletePlan
3638
3730
  }),
3639
- record.desired_state === "absent" && rollbackTransaction && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3731
+ (record.desired_state === "absent" || [
3732
+ "PLANNED",
3733
+ "TOMBSTONE_APPLYING",
3734
+ "TOMBSTONE_APPLIED",
3735
+ "REFERENCES_APPLYING",
3736
+ "REFERENCES_APPLIED",
3737
+ "DECLARATIONS_APPLYING",
3738
+ "DECLARATIONS_APPLIED",
3739
+ "DELETE_RESTART_PENDING",
3740
+ "ROLLBACK_PENDING",
3741
+ "ROLLBACK_RESTART_PENDING",
3742
+ "ROLLBACK_RESTORED",
3743
+ "ROLLBACK_APPLYING"
3744
+ ].includes(rollbackTransaction?.state)) && rollbackTransaction && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3640
3745
  type: "button",
3641
3746
  style: {
3642
3747
  ...S.btn,
@@ -3644,13 +3749,51 @@ function WorkersPanel({ ctx }) {
3644
3749
  },
3645
3750
  disabled: providerLifecycleBusy !== null,
3646
3751
  onClick: () => {
3647
- rollbackHarnessProvider(record, rollbackTransaction.transaction_id);
3752
+ rollbackHarnessProvider(record, rollbackTransaction.transaction_id, rollbackTransaction.state);
3648
3753
  },
3649
- children: providerLifecycleBusy === `rollback:${record.id}` ? copy.working : copy.providerRollback
3754
+ children: providerLifecycleBusy === `rollback:${record.id}` ? copy.working : rollbackTransaction.state === "ROLLBACK_PENDING" ? copy.providerRollbackContinue : copy.providerRollback
3650
3755
  })
3651
3756
  ]
3652
3757
  }, record.id);
3653
3758
  }),
3759
+ (providerInventory?.recovery_transactions ?? []).filter((entry) => entry?.unresolved === true || !entry?.provider_id).map((entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3760
+ style: {
3761
+ display: "flex",
3762
+ alignItems: "center",
3763
+ gap: 8,
3764
+ fontSize: 12,
3765
+ flexWrap: "wrap",
3766
+ color: "#c98735",
3767
+ marginTop: 6
3768
+ },
3769
+ children: [
3770
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3771
+ style: { fontWeight: 600 },
3772
+ children: copy.recoveryUnresolved
3773
+ }),
3774
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3775
+ style: S.mono,
3776
+ children: entry.storage_id ?? entry.transaction_id ?? "unknown"
3777
+ }),
3778
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3779
+ style: { opacity: .7 },
3780
+ children: entry.phase
3781
+ }),
3782
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: { flex: 1 } }),
3783
+ entry.action_id && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3784
+ type: "button",
3785
+ style: {
3786
+ ...S.btn,
3787
+ padding: "2px 8px"
3788
+ },
3789
+ disabled: providerLifecycleBusy !== null,
3790
+ onClick: () => {
3791
+ quarantineRecoveryTransaction(entry);
3792
+ },
3793
+ children: providerLifecycleBusy === `quarantine:${entry.action_id}` ? copy.working : copy.recoveryQuarantine
3794
+ })
3795
+ ]
3796
+ }, `recovery:${entry.storage_id ?? entry.transaction_id ?? "unknown"}`)),
3654
3797
  (credentialRefs.length > 0 || credentialUnverified.length > 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3655
3798
  style: {
3656
3799
  marginTop: 10,