@dxos/shell 0.3.11-main.8a2cfe6 → 0.3.11-main.8a9dd1e

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 (99) hide show
  1. package/dist/bundle/shell.mjs +36674 -0
  2. package/dist/bundle/shell.mjs.map +1 -0
  3. package/dist/bundle/shell.umd.js +210 -0
  4. package/dist/bundle/shell.umd.js.map +1 -0
  5. package/dist/bundle/style.css +1 -0
  6. package/dist/lib/browser/meta.json +1 -1
  7. package/dist/lib/browser/react.mjs +702 -397
  8. package/dist/lib/browser/react.mjs.map +4 -4
  9. package/dist/lib/browser/testing/index.mjs.map +1 -1
  10. package/dist/types/src/components/IdentityList/DeviceList.d.ts.map +1 -1
  11. package/dist/types/src/components/IdentityList/DeviceList.js +5 -3
  12. package/dist/types/src/components/IdentityList/DeviceList.js.map +1 -1
  13. package/dist/types/src/components/Panel/Action.js +1 -1
  14. package/dist/types/src/components/Panel/Action.js.map +1 -1
  15. package/dist/types/src/composites/Shell/Shell.d.ts.map +1 -1
  16. package/dist/types/src/composites/Shell/Shell.js +15 -5
  17. package/dist/types/src/composites/Shell/Shell.js.map +1 -1
  18. package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts.map +1 -1
  19. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js +23 -6
  20. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js.map +1 -1
  21. package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.d.ts +6 -0
  22. package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.d.ts.map +1 -1
  23. package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.js +26 -3
  24. package/dist/types/src/panels/IdentityPanel/IdentityPanel.stories.js.map +1 -1
  25. package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.d.ts +19 -8
  26. package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.d.ts.map +1 -1
  27. package/dist/types/src/panels/IdentityPanel/identityMachine.d.ts +1 -1
  28. package/dist/types/src/panels/IdentityPanel/identityMachine.d.ts.map +1 -1
  29. package/dist/types/src/panels/IdentityPanel/identityMachine.js +12 -3
  30. package/dist/types/src/panels/IdentityPanel/identityMachine.js.map +1 -1
  31. package/dist/types/src/panels/IdentityPanel/steps/AgentForm.d.ts +3 -0
  32. package/dist/types/src/panels/IdentityPanel/steps/AgentForm.d.ts.map +1 -0
  33. package/dist/types/src/panels/IdentityPanel/steps/AgentForm.js +26 -0
  34. package/dist/types/src/panels/IdentityPanel/steps/AgentForm.js.map +1 -0
  35. package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.d.ts +10 -0
  36. package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.d.ts.map +1 -0
  37. package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.js +23 -0
  38. package/dist/types/src/panels/IdentityPanel/steps/DeviceManager.js.map +1 -0
  39. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.d.ts.map +1 -1
  40. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js +9 -1
  41. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js.map +1 -1
  42. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.d.ts +0 -1
  43. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.d.ts.map +1 -1
  44. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js +2 -3
  45. package/dist/types/src/panels/IdentityPanel/steps/ProfileForm.js.map +1 -1
  46. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.d.ts +16 -0
  47. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.d.ts.map +1 -0
  48. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.js +40 -0
  49. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.js.map +1 -0
  50. package/dist/types/src/panels/IdentityPanel/steps/index.d.ts +3 -0
  51. package/dist/types/src/panels/IdentityPanel/steps/index.d.ts.map +1 -1
  52. package/dist/types/src/panels/IdentityPanel/steps/index.js +3 -0
  53. package/dist/types/src/panels/IdentityPanel/steps/index.js.map +1 -1
  54. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.d.ts +15 -0
  55. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.d.ts.map +1 -0
  56. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.js +78 -0
  57. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.js.map +1 -0
  58. package/dist/types/src/panels/JoinPanel/JoinPanel.js +4 -3
  59. package/dist/types/src/panels/JoinPanel/JoinPanel.js.map +1 -1
  60. package/dist/types/src/panels/JoinPanel/joinMachine.js +1 -1
  61. package/dist/types/src/panels/JoinPanel/joinMachine.js.map +1 -1
  62. package/dist/types/src/panels/SpacePanel/SpacePanel.d.ts.map +1 -1
  63. package/dist/types/src/panels/SpacePanel/SpacePanel.js +5 -3
  64. package/dist/types/src/panels/SpacePanel/SpacePanel.js.map +1 -1
  65. package/dist/types/src/panels/SpacePanel/SpacePanel.stories.d.ts.map +1 -1
  66. package/dist/types/src/panels/SpacePanel/SpacePanel.stories.js +2 -2
  67. package/dist/types/src/panels/SpacePanel/SpacePanel.stories.js.map +1 -1
  68. package/dist/types/src/panels/SpacePanel/SpacePanelProps.d.ts +1 -0
  69. package/dist/types/src/panels/SpacePanel/SpacePanelProps.d.ts.map +1 -1
  70. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.d.ts +1 -0
  71. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.d.ts.map +1 -1
  72. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.js +3 -1
  73. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.js.map +1 -1
  74. package/dist/types/src/translations/locales/en-US.d.ts +6 -0
  75. package/dist/types/src/translations/locales/en-US.d.ts.map +1 -1
  76. package/dist/types/src/translations/locales/en-US.js +7 -1
  77. package/dist/types/src/translations/locales/en-US.js.map +1 -1
  78. package/package.json +20 -19
  79. package/src/components/IdentityList/DeviceList.tsx +7 -5
  80. package/src/components/Panel/Action.tsx +1 -1
  81. package/src/composites/Shell/Shell.tsx +16 -3
  82. package/src/panels/IdentityPanel/IdentityPanel.stories.tsx +44 -2
  83. package/src/panels/IdentityPanel/IdentityPanel.tsx +34 -7
  84. package/src/panels/IdentityPanel/IdentityPanelProps.ts +27 -8
  85. package/src/panels/IdentityPanel/identityMachine.ts +13 -4
  86. package/src/panels/IdentityPanel/steps/AgentForm.tsx +61 -0
  87. package/src/panels/IdentityPanel/steps/DeviceManager.tsx +41 -0
  88. package/src/panels/IdentityPanel/steps/IdentityActionChooser.tsx +12 -7
  89. package/src/panels/IdentityPanel/steps/ProfileForm.tsx +1 -1
  90. package/src/panels/IdentityPanel/steps/SignOutChooser.tsx +82 -0
  91. package/src/panels/IdentityPanel/steps/index.ts +3 -0
  92. package/src/panels/IdentityPanel/useAgentHandlers.ts +88 -0
  93. package/src/panels/JoinPanel/JoinPanel.tsx +2 -2
  94. package/src/panels/JoinPanel/joinMachine.ts +1 -1
  95. package/src/panels/SpacePanel/SpacePanel.stories.tsx +2 -1
  96. package/src/panels/SpacePanel/SpacePanel.tsx +4 -1
  97. package/src/panels/SpacePanel/SpacePanelProps.ts +1 -0
  98. package/src/panels/SpacePanel/steps/SpaceManager.tsx +4 -1
  99. package/src/translations/locales/en-US.ts +7 -1
@@ -182,9 +182,9 @@ var DeviceList = ({ devices, onSelect }) => {
182
182
  }, devices.map((device) => {
183
183
  const identity = {
184
184
  identityKey: device.deviceKey,
185
- profile: {
185
+ profile: device.profile ? {
186
186
  displayName: `${device.profile?.platform} (${device.profile?.platformVersion}) on ${device.profile?.os} (${device.profile?.osVersion}) ${device.profile?.architecture ?? "Unknown"}-bit`
187
- }
187
+ } : void 0
188
188
  };
189
189
  return /* @__PURE__ */ React5.createElement(IdentityListItem, {
190
190
  key: device.deviceKey.toHex(),
@@ -598,8 +598,8 @@ var Action = /* @__PURE__ */ forwardRef2((props, forwardedRef) => {
598
598
  classNames: [
599
599
  isFull && "is-full",
600
600
  "bs-11 flex gap-2 mbs-2",
601
- classNames,
602
- ...buttonColorFragment(props)
601
+ ...buttonColorFragment(props),
602
+ classNames
603
603
  ],
604
604
  ref: forwardedRef,
605
605
  variant
@@ -813,17 +813,17 @@ var SpaceListItem = /* @__PURE__ */ forwardRef7(({ space, onClick }, ref) => {
813
813
  });
814
814
 
815
815
  // packages/sdk/shell/src/composites/IdentityDialog/IdentityDialog.tsx
816
- import React37 from "react";
816
+ import React40 from "react";
817
817
  import { Dialog, useId as useId9 } from "@dxos/react-ui";
818
818
 
819
819
  // packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx
820
- import React24, { useEffect as useEffect2, useMemo as useMemo3 } from "react";
820
+ import React27, { useEffect as useEffect3, useMemo as useMemo3 } from "react";
821
821
  import { generateName as generateName2 } from "@dxos/display-name";
822
822
  import { log as log3 } from "@dxos/log";
823
823
  import { useClient as useClient3 } from "@dxos/react-client";
824
- import { useIdentity } from "@dxos/react-client/halo";
824
+ import { useIdentity, useDevices, useHaloInvitations as useHaloInvitations2 } from "@dxos/react-client/halo";
825
825
  import { useInvitationStatus as useInvitationStatus2 } from "@dxos/react-client/invitations";
826
- import { Avatar as Avatar4, DensityProvider as DensityProvider2, useId as useId5, useJdenticonHref as useJdenticonHref3, useTranslation as useTranslation10 } from "@dxos/react-ui";
826
+ import { Avatar as Avatar4, DensityProvider as DensityProvider2, useId as useId5, useJdenticonHref as useJdenticonHref3, useTranslation as useTranslation13 } from "@dxos/react-ui";
827
827
 
828
828
  // packages/sdk/shell/src/panels/IdentityPanel/identityMachine.ts
829
829
  import { useMachine } from "@xstate/react";
@@ -844,6 +844,14 @@ var identityMachine = createMachine({
844
844
  states: {
845
845
  choosingAction: {},
846
846
  managingDeviceInvitation: {},
847
+ managingAgent: {
848
+ initial: "idle",
849
+ states: {
850
+ idle: {},
851
+ pending: {}
852
+ }
853
+ },
854
+ managingDevices: {},
847
855
  managingProfile: {
848
856
  initial: "idle",
849
857
  states: {
@@ -863,7 +871,8 @@ var identityMachine = createMachine({
863
871
  actions: "log"
864
872
  }
865
873
  }
866
- }
874
+ },
875
+ signingOut: {}
867
876
  },
868
877
  on: {
869
878
  unchooseAction: {
@@ -873,13 +882,6 @@ var identityMachine = createMachine({
873
882
  "log"
874
883
  ]
875
884
  },
876
- chooseDevices: {
877
- target: ".managingDeviceInvitation",
878
- actions: [
879
- "unsetInvitation",
880
- "log"
881
- ]
882
- },
883
885
  deselectInvitation: {
884
886
  target: ".choosingAction",
885
887
  actions: [
@@ -894,9 +896,21 @@ var identityMachine = createMachine({
894
896
  "log"
895
897
  ]
896
898
  },
899
+ chooseDevices: {
900
+ target: ".managingDevices",
901
+ actions: "log"
902
+ },
897
903
  chooseProfile: {
898
904
  target: ".managingProfile",
899
905
  actions: "log"
906
+ },
907
+ chooseSignOut: {
908
+ target: ".signingOut",
909
+ actions: "log"
910
+ },
911
+ chooseAgent: {
912
+ target: ".managingAgent",
913
+ actions: "log"
900
914
  }
901
915
  }
902
916
  }, {
@@ -916,7 +930,7 @@ var identityMachine = createMachine({
916
930
  context
917
931
  }, {
918
932
  F: __dxlog_file,
919
- L: 95,
933
+ L: 104,
920
934
  S: void 0,
921
935
  C: (f, a) => f(...a)
922
936
  });
@@ -937,13 +951,67 @@ var useIdentityMachine = (client, options) => {
937
951
  });
938
952
  };
939
953
 
954
+ // packages/sdk/shell/src/panels/IdentityPanel/steps/AgentForm.tsx
955
+ import React21 from "react";
956
+ import { useTranslation as useTranslation7 } from "@dxos/react-ui";
957
+ var AgentForm = (props) => {
958
+ const { active, onAgentCreate, onAgentDestroy, send, validationMessage, agentStatus, agentActive, agentProviderDisabled } = props;
959
+ const disabled = !active;
960
+ const { t } = useTranslation7("os");
961
+ return /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("div", {
962
+ role: "none",
963
+ className: "grow flex flex-col justify-center"
964
+ }, /* @__PURE__ */ React21.createElement(Input, {
965
+ validationMessage,
966
+ label: /* @__PURE__ */ React21.createElement(StepHeading, null, "Agent Status"),
967
+ disabled,
968
+ "data-testid": "agent-status",
969
+ value: agentStatus
970
+ })), /* @__PURE__ */ React21.createElement(Actions, null, /* @__PURE__ */ React21.createElement(Action, {
971
+ disabled: agentActive || agentProviderDisabled,
972
+ onClick: () => onAgentCreate?.(),
973
+ "data-testid": "create-agent"
974
+ }, "Create Agent"), /* @__PURE__ */ React21.createElement(Action, {
975
+ disabled: !agentActive || agentProviderDisabled,
976
+ onClick: () => onAgentDestroy?.(),
977
+ "data-testid": "destroy-agent"
978
+ }, "Destroy Agent"), /* @__PURE__ */ React21.createElement(Action, {
979
+ disabled,
980
+ onClick: () => send?.({
981
+ type: "unchooseAction"
982
+ }),
983
+ "data-testid": "update-profile-form-back"
984
+ }, t("back label"))));
985
+ };
986
+
987
+ // packages/sdk/shell/src/panels/IdentityPanel/steps/DeviceManager.tsx
988
+ import React22 from "react";
989
+ import { useTranslation as useTranslation8 } from "@dxos/react-ui";
990
+ var DeviceManager = ({ devices, active, send }) => {
991
+ const { t } = useTranslation8("os");
992
+ const disabled = !active;
993
+ return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("div", {
994
+ role: "none",
995
+ className: "grow"
996
+ }, /* @__PURE__ */ React22.createElement(DeviceList, {
997
+ devices
998
+ })), /* @__PURE__ */ React22.createElement(Actions, null, /* @__PURE__ */ React22.createElement(Action, {
999
+ variant: "ghost",
1000
+ disabled,
1001
+ onClick: () => send?.({
1002
+ type: "unchooseAction"
1003
+ }),
1004
+ "data-testid": "manage-devices-back"
1005
+ }, t("back label"))));
1006
+ };
1007
+
940
1008
  // packages/sdk/shell/src/panels/IdentityPanel/steps/IdentityActionChooser.tsx
941
- import { CaretRight, Plus, Power, UserGear } from "@phosphor-icons/react";
942
- import React21, { useCallback as useCallback4 } from "react";
1009
+ import { CaretRight, Devices, Plus, Power, UserGear, HardDrive } from "@phosphor-icons/react";
1010
+ import React23, { useCallback as useCallback4 } from "react";
943
1011
  import { useClient as useClient2 } from "@dxos/react-client";
944
1012
  import { useHaloInvitations } from "@dxos/react-client/halo";
945
1013
  import { Invitation as Invitation3, InvitationEncoder } from "@dxos/react-client/invitations";
946
- import { DensityProvider, useTranslation as useTranslation7 } from "@dxos/react-ui";
1014
+ import { DensityProvider, useTranslation as useTranslation9 } from "@dxos/react-ui";
947
1015
  import { getSize as getSize6 } from "@dxos/react-ui-theme";
948
1016
  var IdentityActionChooser = (props) => {
949
1017
  const { send } = props;
@@ -973,69 +1041,95 @@ var IdentityActionChooser = (props) => {
973
1041
  invitation
974
1042
  });
975
1043
  };
976
- return /* @__PURE__ */ React21.createElement(IdentityActionChooserImpl, {
1044
+ return /* @__PURE__ */ React23.createElement(IdentityActionChooserImpl, {
977
1045
  ...props,
978
1046
  onCreateInvitationClick: (e) => createInvitation(e)
979
1047
  });
980
1048
  };
981
1049
  var IdentityActionChooserImpl = ({ onCreateInvitationClick, active, send, onDone, doneActionParent }) => {
982
- const { t } = useTranslation7("os");
983
- return /* @__PURE__ */ React21.createElement("div", {
1050
+ const { t } = useTranslation9("os");
1051
+ return /* @__PURE__ */ React23.createElement("div", {
984
1052
  role: "none",
985
1053
  className: "grow flex flex-col gap-1"
986
- }, /* @__PURE__ */ React21.createElement(DensityProvider, {
1054
+ }, /* @__PURE__ */ React23.createElement(DensityProvider, {
987
1055
  density: "coarse"
988
- }, /* @__PURE__ */ React21.createElement("div", {
1056
+ }, /* @__PURE__ */ React23.createElement("div", {
989
1057
  className: "grow justify-center flex flex-col gap-1"
990
- }, /* @__PURE__ */ React21.createElement(Action, {
1058
+ }, /* @__PURE__ */ React23.createElement(Action, {
1059
+ "data-testid": "manage-agent",
1060
+ onClick: () => send?.({
1061
+ type: "chooseAgent"
1062
+ }),
1063
+ classNames: "plb-4"
1064
+ }, /* @__PURE__ */ React23.createElement(HardDrive, {
1065
+ className: getSize6(6)
1066
+ }), /* @__PURE__ */ React23.createElement("span", {
1067
+ className: "grow mli-3"
1068
+ }, "Manage Agent"), /* @__PURE__ */ React23.createElement(CaretRight, {
1069
+ weight: "bold",
1070
+ className: getSize6(4)
1071
+ })), /* @__PURE__ */ React23.createElement(Action, {
991
1072
  disabled: !active,
992
1073
  "data-testid": "devices-panel.create-invitation",
993
1074
  onClick: onCreateInvitationClick,
994
1075
  classNames: "plb-4"
995
- }, /* @__PURE__ */ React21.createElement(Plus, {
1076
+ }, /* @__PURE__ */ React23.createElement(Plus, {
996
1077
  className: getSize6(6)
997
- }), /* @__PURE__ */ React21.createElement("span", {
1078
+ }), /* @__PURE__ */ React23.createElement("span", {
998
1079
  className: "grow mli-3"
999
- }, t("choose devices label")), /* @__PURE__ */ React21.createElement(CaretRight, {
1080
+ }, t("choose add device label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1000
1081
  weight: "bold",
1001
1082
  className: getSize6(4)
1002
- })), /* @__PURE__ */ React21.createElement(Action, {
1083
+ })), /* @__PURE__ */ React23.createElement(Action, {
1084
+ "data-testid": "manage-devices",
1085
+ onClick: () => send?.({
1086
+ type: "chooseDevices"
1087
+ }),
1088
+ classNames: "plb-4"
1089
+ }, /* @__PURE__ */ React23.createElement(Devices, {
1090
+ className: getSize6(6)
1091
+ }), /* @__PURE__ */ React23.createElement("span", {
1092
+ className: "grow mli-3"
1093
+ }, t("choose devices label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1094
+ weight: "bold",
1095
+ className: getSize6(4)
1096
+ })), /* @__PURE__ */ React23.createElement(Action, {
1003
1097
  "data-testid": "manage-profile",
1004
1098
  onClick: () => send?.({
1005
1099
  type: "chooseProfile"
1006
1100
  }),
1007
1101
  classNames: "plb-4"
1008
- }, /* @__PURE__ */ React21.createElement(UserGear, {
1102
+ }, /* @__PURE__ */ React23.createElement(UserGear, {
1009
1103
  className: getSize6(6)
1010
- }), /* @__PURE__ */ React21.createElement("span", {
1104
+ }), /* @__PURE__ */ React23.createElement("span", {
1011
1105
  className: "grow mli-3"
1012
- }, t("choose profile label")), /* @__PURE__ */ React21.createElement(CaretRight, {
1106
+ }, t("choose profile label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1013
1107
  weight: "bold",
1014
1108
  className: getSize6(4)
1015
- })), /* @__PURE__ */ React21.createElement(Action, {
1016
- disabled: true,
1109
+ })), /* @__PURE__ */ React23.createElement(Action, {
1017
1110
  "data-testid": "sign-out",
1018
- onClick: () => {
1019
- },
1111
+ onClick: () => send?.({
1112
+ type: "chooseSignOut"
1113
+ }),
1020
1114
  classNames: "plb-4"
1021
- }, /* @__PURE__ */ React21.createElement(Power, {
1115
+ }, /* @__PURE__ */ React23.createElement(Power, {
1022
1116
  className: getSize6(6)
1023
- }), /* @__PURE__ */ React21.createElement("span", {
1117
+ }), /* @__PURE__ */ React23.createElement("span", {
1024
1118
  className: "grow mli-3"
1025
- }, t("choose sign out label")), /* @__PURE__ */ React21.createElement(CaretRight, {
1119
+ }, t("choose sign out label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1026
1120
  weight: "bold",
1027
1121
  className: getSize6(4)
1028
1122
  })))));
1029
1123
  };
1030
1124
 
1031
1125
  // packages/sdk/shell/src/panels/IdentityPanel/steps/ProfileForm.tsx
1032
- import React22, { useState as useState3 } from "react";
1126
+ import React24, { useState as useState3 } from "react";
1033
1127
  import { log as log2 } from "@dxos/log";
1034
- import { useTranslation as useTranslation8 } from "@dxos/react-ui";
1128
+ import { useTranslation as useTranslation10 } from "@dxos/react-ui";
1035
1129
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/steps/ProfileForm.tsx";
1036
1130
  var ProfileForm = (props) => {
1037
1131
  const { onUpdateProfile } = props;
1038
- const { t } = useTranslation8("os");
1132
+ const { t } = useTranslation10("os");
1039
1133
  const [validationMessage, setValidationMessage] = useState3("");
1040
1134
  const handleUpdateProfile = async (profile) => {
1041
1135
  await onUpdateProfile?.(profile).catch((error) => {
@@ -1048,7 +1142,7 @@ var ProfileForm = (props) => {
1048
1142
  setValidationMessage(t("failed to update profile message"));
1049
1143
  });
1050
1144
  };
1051
- return /* @__PURE__ */ React22.createElement(ProfileFormImpl, {
1145
+ return /* @__PURE__ */ React24.createElement(ProfileFormImpl, {
1052
1146
  ...props,
1053
1147
  onUpdateProfile: handleUpdateProfile,
1054
1148
  validationMessage
@@ -1057,14 +1151,14 @@ var ProfileForm = (props) => {
1057
1151
  var ProfileFormImpl = (props) => {
1058
1152
  const { active, profile, send, onUpdateProfile, validationMessage } = props;
1059
1153
  const disabled = !active;
1060
- const { t } = useTranslation8("os");
1154
+ const { t } = useTranslation10("os");
1061
1155
  const [inputValue, setInputValue] = useState3(profile?.displayName ?? "");
1062
- return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("div", {
1156
+ return /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement("div", {
1063
1157
  role: "none",
1064
1158
  className: "grow flex flex-col justify-center"
1065
- }, /* @__PURE__ */ React22.createElement(Input, {
1159
+ }, /* @__PURE__ */ React24.createElement(Input, {
1066
1160
  validationMessage,
1067
- label: /* @__PURE__ */ React22.createElement(StepHeading, null, t("display name input label")),
1161
+ label: /* @__PURE__ */ React24.createElement(StepHeading, null, t("display name input label")),
1068
1162
  disabled,
1069
1163
  "data-testid": "display-name-input",
1070
1164
  placeholder: t("display name input placeholder"),
@@ -1073,14 +1167,14 @@ var ProfileFormImpl = (props) => {
1073
1167
  onKeyDown: ({ key }) => key === "Enter" && onUpdateProfile?.({
1074
1168
  displayName: inputValue
1075
1169
  })
1076
- })), /* @__PURE__ */ React22.createElement(Actions, null, /* @__PURE__ */ React22.createElement(Action, {
1170
+ })), /* @__PURE__ */ React24.createElement(Actions, null, /* @__PURE__ */ React24.createElement(Action, {
1077
1171
  variant: "ghost",
1078
1172
  disabled,
1079
1173
  onClick: () => send?.({
1080
1174
  type: "unchooseAction"
1081
1175
  }),
1082
1176
  "data-testid": "update-profile-form-back"
1083
- }, t("back label")), /* @__PURE__ */ React22.createElement(Action, {
1177
+ }, t("back label")), /* @__PURE__ */ React24.createElement(Action, {
1084
1178
  variant: "primary",
1085
1179
  disabled,
1086
1180
  onClick: () => onUpdateProfile?.({
@@ -1090,23 +1184,162 @@ var ProfileFormImpl = (props) => {
1090
1184
  }, t("done label"))));
1091
1185
  };
1092
1186
 
1187
+ // packages/sdk/shell/src/panels/IdentityPanel/steps/SignOutChooser.tsx
1188
+ import { Warning } from "@phosphor-icons/react";
1189
+ import React25 from "react";
1190
+ import { Message, useTranslation as useTranslation11 } from "@dxos/react-ui";
1191
+ import { getSize as getSize7, mx as mx18 } from "@dxos/react-ui-theme";
1192
+ var SignOutChooser = (props) => {
1193
+ const { t } = useTranslation11("os");
1194
+ const onResetDevice = () => {
1195
+ if (window.confirm(t("reset device confirm message"))) {
1196
+ void props.onResetDevice?.();
1197
+ }
1198
+ };
1199
+ return /* @__PURE__ */ React25.createElement(SignOutChooserImpl, {
1200
+ disabled: !props.active,
1201
+ onBack: () => props.send?.({
1202
+ type: "unchooseAction"
1203
+ }),
1204
+ onResetDevice,
1205
+ onJoinNewIdentity: props.onJoinNewIdentity
1206
+ });
1207
+ };
1208
+ var SignOutChooserImpl = ({ disabled, onResetDevice, onJoinNewIdentity, onBack }) => {
1209
+ const { t } = useTranslation11("os");
1210
+ return /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement("div", {
1211
+ role: "none",
1212
+ className: "grow flex flex-col justify-center"
1213
+ }, /* @__PURE__ */ React25.createElement(Message.Root, {
1214
+ valence: "error"
1215
+ }, /* @__PURE__ */ React25.createElement(Message.Title, null, /* @__PURE__ */ React25.createElement(Warning, {
1216
+ className: mx18(getSize7(6), "inline mie-2")
1217
+ }), t("sign out chooser title")), /* @__PURE__ */ React25.createElement(Message.Body, null, t("sign out chooser message")))), /* @__PURE__ */ React25.createElement(Actions, null, /* @__PURE__ */ React25.createElement(Action, {
1218
+ disabled,
1219
+ onClick: onBack
1220
+ }, t("back label")), /* @__PURE__ */ React25.createElement(Action, {
1221
+ variant: "primary",
1222
+ classNames: "!bg-error-500 hover:!bg-error-550",
1223
+ disabled,
1224
+ onClick: onJoinNewIdentity
1225
+ }, t("join new identity label")), /* @__PURE__ */ React25.createElement(Action, {
1226
+ variant: "primary",
1227
+ classNames: "!bg-error-500 hover:!bg-error-550",
1228
+ disabled,
1229
+ onClick: onResetDevice
1230
+ }, t("reset device label"))));
1231
+ };
1232
+
1233
+ // packages/sdk/shell/src/panels/IdentityPanel/useAgentHandlers.ts
1234
+ import { useCallback as useCallback5, useEffect as useEffect2, useState as useState4 } from "react";
1235
+ import { invariant } from "@dxos/invariant";
1236
+ import { useAgentHostingProviderClient } from "@dxos/react-client";
1237
+ import { Invitation as Invitation4, InvitationEncoder as InvitationEncoder2 } from "@dxos/react-client/invitations";
1238
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/useAgentHandlers.ts";
1239
+ var useAgentHandlers = ({ client, invitations, identity }) => {
1240
+ const [validationMessage, setValidationMessage] = useState4("");
1241
+ const [agentStatus, setAgentStatus] = useState4("");
1242
+ const [agentActive, setAgentActive] = useState4(false);
1243
+ const agentHostingProviderClient = useAgentHostingProviderClient(client.config);
1244
+ useEffect2(() => {
1245
+ const fetchAgentStatus = async () => {
1246
+ if (agentHostingProviderClient) {
1247
+ const agentStatus2 = await agentHostingProviderClient?.getAgent(identity?.identityKey.truncate() ?? "foo");
1248
+ if (agentStatus2) {
1249
+ setAgentActive(true);
1250
+ setAgentStatus(agentStatus2);
1251
+ } else {
1252
+ setAgentActive(false);
1253
+ setValidationMessage("No agent deployed via provider.");
1254
+ }
1255
+ } else {
1256
+ setValidationMessage("No agent provider configured.");
1257
+ }
1258
+ };
1259
+ void fetchAgentStatus();
1260
+ }, []);
1261
+ const handleAgentCreate = useCallback5(async (invitation) => {
1262
+ const invitationCode = InvitationEncoder2.encode(invitation);
1263
+ if (invitation.state === Invitation4.State.CONNECTING) {
1264
+ console.log(JSON.stringify({
1265
+ invitationCode,
1266
+ authCode: invitation.authCode
1267
+ }));
1268
+ invariant(identity, "Identity not found", {
1269
+ F: __dxlog_file3,
1270
+ L: 50,
1271
+ S: void 0,
1272
+ A: [
1273
+ "identity",
1274
+ "'Identity not found'"
1275
+ ]
1276
+ });
1277
+ if (agentHostingProviderClient) {
1278
+ try {
1279
+ const res = await agentHostingProviderClient?.createAgent(invitationCode, identity.identityKey.truncate());
1280
+ setAgentStatus(res);
1281
+ setAgentActive(true);
1282
+ setValidationMessage("");
1283
+ } catch (err) {
1284
+ setValidationMessage(`error creating agent: ${err.message}`);
1285
+ }
1286
+ }
1287
+ }
1288
+ }, []);
1289
+ const onAgentCreate = async () => {
1290
+ invitations.forEach((invitation2) => invitation2.cancel());
1291
+ const invitation = client.halo.share({
1292
+ type: Invitation4.Type.MULTIUSE,
1293
+ authMethod: Invitation4.AuthMethod.NONE
1294
+ });
1295
+ invitation.subscribe(handleAgentCreate);
1296
+ };
1297
+ const onAgentDestroy = async () => {
1298
+ const identity2 = client.halo.identity.get();
1299
+ invariant(identity2, "Identity not found", {
1300
+ F: __dxlog_file3,
1301
+ L: 76,
1302
+ S: void 0,
1303
+ A: [
1304
+ "identity",
1305
+ "'Identity not found'"
1306
+ ]
1307
+ });
1308
+ try {
1309
+ await agentHostingProviderClient?.destroyAgent(identity2.identityKey.truncate());
1310
+ setValidationMessage("No agent deployed via provider.");
1311
+ setAgentStatus("");
1312
+ setAgentActive(false);
1313
+ } catch (err) {
1314
+ setValidationMessage(`error destroying agent: ${err.message}`);
1315
+ }
1316
+ };
1317
+ return {
1318
+ onAgentCreate,
1319
+ onAgentDestroy,
1320
+ validationMessage,
1321
+ agentStatus,
1322
+ agentActive
1323
+ };
1324
+ };
1325
+
1093
1326
  // packages/sdk/shell/src/steps/InvitationManager.tsx
1094
1327
  import { Check as Check3, X as X3 } from "@phosphor-icons/react";
1095
- import React23, { useMemo as useMemo2 } from "react";
1328
+ import React26, { useMemo as useMemo2 } from "react";
1096
1329
  import { QR } from "react-qr-rounded";
1097
- import { Invitation as Invitation4 } from "@dxos/react-client/invitations";
1098
- import { useId as useId4, useTranslation as useTranslation9 } from "@dxos/react-ui";
1099
- import { descriptionText as descriptionText7, getSize as getSize7, mx as mx18 } from "@dxos/react-ui-theme";
1330
+ import { Invitation as Invitation5 } from "@dxos/react-client/invitations";
1331
+ import { useId as useId4, useTranslation as useTranslation12 } from "@dxos/react-ui";
1332
+ import { descriptionText as descriptionText7, getSize as getSize8, mx as mx19 } from "@dxos/react-ui-theme";
1100
1333
  var InvitationManagerView = ({ children, ...props }) => {
1101
- return /* @__PURE__ */ React23.createElement(Viewport.View, {
1334
+ return /* @__PURE__ */ React26.createElement(Viewport.View, {
1102
1335
  ...props,
1103
1336
  classNames: "grow flex flex-col justify-around items-center"
1104
1337
  }, children);
1105
1338
  };
1106
1339
  var InvitationManager = ({ invitationUrl, active, send, status, type, authCode, id }) => {
1107
- const { t } = useTranslation9("os");
1340
+ const { t } = useTranslation12("os");
1108
1341
  const qrLabel = useId4("invitation-manager__qr-code");
1109
- const statusValue = type === Invitation4.Type.MULTIUSE ? 0 : invitationStatusValue.get(status) ?? 0;
1342
+ const statusValue = type === Invitation5.Type.MULTIUSE ? 0 : invitationStatusValue.get(status) ?? 0;
1110
1343
  const showAuthCode = statusValue === 3;
1111
1344
  const emoji2 = toEmoji(id ?? "");
1112
1345
  const activeView = useMemo2(() => {
@@ -1122,50 +1355,50 @@ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode,
1122
1355
  }, [
1123
1356
  statusValue
1124
1357
  ]);
1125
- return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement(Viewport.Root, {
1358
+ return /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(Viewport.Root, {
1126
1359
  activeView,
1127
1360
  classNames: "grow plb-1"
1128
- }, /* @__PURE__ */ React23.createElement(Viewport.Views, null, /* @__PURE__ */ React23.createElement(InvitationManagerView, {
1361
+ }, /* @__PURE__ */ React26.createElement(Viewport.Views, null, /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1129
1362
  id: "showing qr",
1130
1363
  emoji: emoji2
1131
- }, /* @__PURE__ */ React23.createElement("p", {
1364
+ }, /* @__PURE__ */ React26.createElement("p", {
1132
1365
  className: "text-sm mlb-1 font-normal text-center"
1133
- }, t(type === Invitation4.Type.MULTIUSE ? "invite many qr label" : "invite one qr label")), /* @__PURE__ */ React23.createElement("div", {
1366
+ }, t(type === Invitation5.Type.MULTIUSE ? "invite many qr label" : "invite one qr label")), /* @__PURE__ */ React26.createElement("div", {
1134
1367
  role: "none",
1135
- className: mx18(descriptionText7, "is-full max-is-[14rem] relative")
1136
- }, /* @__PURE__ */ React23.createElement(QR, {
1368
+ className: mx19(descriptionText7, "is-full max-is-[14rem] relative")
1369
+ }, /* @__PURE__ */ React26.createElement(QR, {
1137
1370
  rounding: 100,
1138
1371
  backgroundColor: "transparent",
1139
1372
  color: "currentColor",
1140
- className: mx18("is-full bs-full p-2", showAuthCode && "invisible"),
1373
+ className: mx19("is-full bs-full p-2", showAuthCode && "invisible"),
1141
1374
  "aria-labelledby": qrLabel,
1142
1375
  errorCorrectionLevel: "Q",
1143
1376
  cutout: true
1144
- }, invitationUrl ?? "never"), /* @__PURE__ */ React23.createElement(Centered, null, /* @__PURE__ */ React23.createElement(Emoji, {
1377
+ }, invitationUrl ?? "never"), /* @__PURE__ */ React26.createElement(Centered, null, /* @__PURE__ */ React26.createElement(Emoji, {
1145
1378
  text: emoji2
1146
- }))), /* @__PURE__ */ React23.createElement("span", {
1379
+ }))), /* @__PURE__ */ React26.createElement("span", {
1147
1380
  id: qrLabel,
1148
1381
  className: "sr-only"
1149
- }, t("qr label")), /* @__PURE__ */ React23.createElement(CopyButton, {
1382
+ }, t("qr label")), /* @__PURE__ */ React26.createElement(CopyButton, {
1150
1383
  variant: "ghost",
1151
1384
  value: invitationUrl ?? "never"
1152
- })), /* @__PURE__ */ React23.createElement(InvitationManagerView, {
1385
+ })), /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1153
1386
  id: "showing auth code"
1154
- }, /* @__PURE__ */ React23.createElement(Label, null, t("auth code message")), /* @__PURE__ */ React23.createElement(AuthCode, {
1387
+ }, /* @__PURE__ */ React26.createElement(Label, null, t("auth code message")), /* @__PURE__ */ React26.createElement(AuthCode, {
1155
1388
  code: authCode,
1156
1389
  large: true,
1157
1390
  classNames: "text-black dark:text-white"
1158
- }), /* @__PURE__ */ React23.createElement(Label, null, "Be sure the other device is showing this symbol:"), emoji2 && /* @__PURE__ */ React23.createElement(Emoji, {
1391
+ }), /* @__PURE__ */ React26.createElement(Label, null, "Be sure the other device is showing this symbol:"), emoji2 && /* @__PURE__ */ React26.createElement(Emoji, {
1159
1392
  text: emoji2
1160
- })), /* @__PURE__ */ React23.createElement(InvitationManagerView, {
1393
+ })), /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1161
1394
  id: "showing final"
1162
- }, statusValue > 0 ? /* @__PURE__ */ React23.createElement(Check3, {
1163
- className: mx18("m-1.5", getSize7(6))
1164
- }) : /* @__PURE__ */ React23.createElement(X3, {
1165
- className: mx18("m-1.5", getSize7(6))
1166
- })))), /* @__PURE__ */ React23.createElement(Actions, {
1395
+ }, statusValue > 0 ? /* @__PURE__ */ React26.createElement(Check3, {
1396
+ className: mx19("m-1.5", getSize8(6))
1397
+ }) : /* @__PURE__ */ React26.createElement(X3, {
1398
+ className: mx19("m-1.5", getSize8(6))
1399
+ })))), /* @__PURE__ */ React26.createElement(Actions, {
1167
1400
  classNames: "mbs-4"
1168
- }, /* @__PURE__ */ React23.createElement(Action, {
1401
+ }, /* @__PURE__ */ React26.createElement(Action, {
1169
1402
  disabled: !active,
1170
1403
  onClick: () => send?.({
1171
1404
  type: "deselectInvitation"
@@ -1174,36 +1407,37 @@ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode,
1174
1407
  };
1175
1408
 
1176
1409
  // packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx
1177
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx";
1410
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx";
1178
1411
  var viewStyles = "pbs-1 pbe-3 pli-3";
1179
1412
  var IdentityHeading = ({ titleId, title, identity, onDone }) => {
1180
1413
  const fallbackHref = useJdenticonHref3(identity.identityKey.toHex(), 12);
1181
- return /* @__PURE__ */ React24.createElement(Heading, {
1414
+ return /* @__PURE__ */ React27.createElement(Heading, {
1182
1415
  titleId,
1183
1416
  title,
1184
- corner: /* @__PURE__ */ React24.createElement(CloseButton, {
1417
+ corner: /* @__PURE__ */ React27.createElement(CloseButton, {
1185
1418
  onDone
1186
1419
  })
1187
- }, /* @__PURE__ */ React24.createElement(Avatar4.Root, {
1420
+ }, /* @__PURE__ */ React27.createElement(Avatar4.Root, {
1188
1421
  size: 12,
1189
1422
  variant: "circle",
1190
1423
  status: "active"
1191
- }, /* @__PURE__ */ React24.createElement(Avatar4.Frame, {
1424
+ }, /* @__PURE__ */ React27.createElement(Avatar4.Frame, {
1192
1425
  classNames: "block mbs-4 mbe-2 mli-auto chromatic-ignore"
1193
- }, /* @__PURE__ */ React24.createElement(Avatar4.Fallback, {
1426
+ }, /* @__PURE__ */ React27.createElement(Avatar4.Fallback, {
1194
1427
  href: fallbackHref
1195
- })), /* @__PURE__ */ React24.createElement(Avatar4.Label, {
1428
+ })), /* @__PURE__ */ React27.createElement(Avatar4.Label, {
1196
1429
  classNames: "block text-center font-light text-xl"
1197
1430
  }, identity.profile?.displayName ?? generateName2(identity.identityKey.toHex()))));
1198
1431
  };
1199
1432
  var IdentityPanelImpl = (props) => {
1200
- const { identity, titleId, activeView, onUpdateProfile, IdentityActionChooser: IdentityActionChooserComponent = IdentityActionChooser, InvitationManager: InvitationManagerComponent = InvitationManager, onDone, ...rest } = props;
1201
- const { t } = useTranslation10("os");
1433
+ const { identity, titleId, activeView, onUpdateProfile, onResetDevice, onJoinNewIdentity, IdentityActionChooser: IdentityActionChooserComponent = IdentityActionChooser, InvitationManager: InvitationManagerComponent = InvitationManager, onDone, ...rest } = props;
1434
+ const { t } = useTranslation13("os");
1202
1435
  const title = useMemo3(() => {
1203
1436
  switch (activeView) {
1204
- case "device manager":
1437
+ case "agent manager":
1438
+ return "Manage Agent";
1205
1439
  case "device invitation manager":
1206
- return t("choose devices label");
1440
+ return t("choose add device label");
1207
1441
  default:
1208
1442
  return t("identity heading");
1209
1443
  }
@@ -1211,41 +1445,62 @@ var IdentityPanelImpl = (props) => {
1211
1445
  activeView,
1212
1446
  t
1213
1447
  ]);
1214
- return /* @__PURE__ */ React24.createElement(DensityProvider2, {
1448
+ return /* @__PURE__ */ React27.createElement(DensityProvider2, {
1215
1449
  density: "fine"
1216
- }, /* @__PURE__ */ React24.createElement(IdentityHeading, {
1450
+ }, /* @__PURE__ */ React27.createElement(IdentityHeading, {
1217
1451
  identity,
1218
1452
  titleId,
1219
1453
  title,
1220
1454
  onDone
1221
- }), /* @__PURE__ */ React24.createElement(Viewport.Root, {
1455
+ }), /* @__PURE__ */ React27.createElement(Viewport.Root, {
1222
1456
  activeView
1223
- }, /* @__PURE__ */ React24.createElement(Viewport.Views, null, /* @__PURE__ */ React24.createElement(Viewport.View, {
1457
+ }, /* @__PURE__ */ React27.createElement(Viewport.Views, null, /* @__PURE__ */ React27.createElement(Viewport.View, {
1224
1458
  id: "identity action chooser",
1225
1459
  classNames: viewStyles
1226
- }, /* @__PURE__ */ React24.createElement(IdentityActionChooserComponent, {
1460
+ }, /* @__PURE__ */ React27.createElement(IdentityActionChooserComponent, {
1227
1461
  active: activeView === "identity action chooser",
1228
1462
  ...rest
1229
- })), /* @__PURE__ */ React24.createElement(Viewport.View, {
1463
+ })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1230
1464
  id: "device invitation manager",
1231
1465
  classNames: viewStyles
1232
- }, /* @__PURE__ */ React24.createElement(InvitationManagerComponent, {
1466
+ }, /* @__PURE__ */ React27.createElement(InvitationManagerComponent, {
1233
1467
  active: activeView === "device invitation manager",
1234
1468
  ...rest,
1235
1469
  invitationUrl: rest.createInvitationUrl(rest.invitationCode)
1236
- })), /* @__PURE__ */ React24.createElement(Viewport.View, {
1470
+ })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1471
+ id: "device manager",
1472
+ classNames: viewStyles
1473
+ }, /* @__PURE__ */ React27.createElement(DeviceManager, {
1474
+ active: activeView === "device manager",
1475
+ ...rest
1476
+ })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1237
1477
  classNames: viewStyles,
1238
1478
  id: "update profile form"
1239
- }, /* @__PURE__ */ React24.createElement(ProfileForm, {
1479
+ }, /* @__PURE__ */ React27.createElement(ProfileForm, {
1240
1480
  send: rest.send,
1241
1481
  active: activeView === "update profile form",
1242
1482
  profile: identity.profile,
1243
1483
  onUpdateProfile
1484
+ })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1485
+ classNames: viewStyles,
1486
+ id: "signing out"
1487
+ }, /* @__PURE__ */ React27.createElement(SignOutChooser, {
1488
+ send: rest.send,
1489
+ active: activeView === "signing out",
1490
+ onResetDevice,
1491
+ onJoinNewIdentity
1492
+ })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1493
+ classNames: viewStyles,
1494
+ id: "agent manager"
1495
+ }, /* @__PURE__ */ React27.createElement(AgentForm, {
1496
+ send: rest.send,
1497
+ active: activeView === "agent manager",
1498
+ ...rest
1244
1499
  })))));
1245
1500
  };
1246
1501
  var IdentityPanelWithInvitationImpl = ({ invitation, ...props }) => {
1247
1502
  const invitationStatus = useInvitationStatus2(invitation);
1248
- return /* @__PURE__ */ React24.createElement(IdentityPanelImpl, {
1503
+ return /* @__PURE__ */ React27.createElement(IdentityPanelImpl, {
1249
1504
  ...props,
1250
1505
  ...invitationStatus
1251
1506
  });
@@ -1253,17 +1508,24 @@ var IdentityPanelWithInvitationImpl = ({ invitation, ...props }) => {
1253
1508
  var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => code, ...props }) => {
1254
1509
  const titleId = useId5("identityPanel__heading", propsTitleId);
1255
1510
  const client = useClient3();
1511
+ const devices = useDevices();
1256
1512
  const identity = useIdentity();
1513
+ const invitations = useHaloInvitations2();
1514
+ const agentProps = useAgentHandlers({
1515
+ client,
1516
+ identity,
1517
+ invitations
1518
+ });
1257
1519
  if (!identity) {
1258
1520
  console.error("IdentityPanel rendered with no active identity.");
1259
1521
  return null;
1260
1522
  }
1261
1523
  const [identityState, identitySend, identityService] = useIdentityMachine(client);
1262
- useEffect2(() => {
1524
+ useEffect3(() => {
1263
1525
  const subscription = identityService.subscribe((state) => {
1264
1526
  log3("[state]", state, {
1265
- F: __dxlog_file3,
1266
- L: 117,
1527
+ F: __dxlog_file4,
1528
+ L: 138,
1267
1529
  S: void 0,
1268
1530
  C: (f, a) => f(...a)
1269
1531
  });
@@ -1278,6 +1540,8 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1278
1540
  return "identity action chooser";
1279
1541
  case identityState.matches("managingDeviceInvitation"):
1280
1542
  return "device invitation manager";
1543
+ case identityState.matches("managingDevices"):
1544
+ return "device manager";
1281
1545
  case [
1282
1546
  {
1283
1547
  managingProfile: "idle"
@@ -1287,6 +1551,17 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1287
1551
  }
1288
1552
  ].some(identityState.matches):
1289
1553
  return "update profile form";
1554
+ case identityState.matches("signingOut"):
1555
+ return "signing out";
1556
+ case [
1557
+ {
1558
+ managingAgent: "idle"
1559
+ },
1560
+ {
1561
+ managingAgent: "pending"
1562
+ }
1563
+ ].some(identityState.matches):
1564
+ return "agent manager";
1290
1565
  default:
1291
1566
  return "identity action chooser";
1292
1567
  }
@@ -1302,20 +1577,22 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1302
1577
  const implProps = {
1303
1578
  ...props,
1304
1579
  identity,
1580
+ devices,
1305
1581
  activeView,
1306
1582
  send: identitySend,
1307
1583
  titleId,
1308
1584
  createInvitationUrl,
1309
- onUpdateProfile
1585
+ onUpdateProfile,
1586
+ ...agentProps
1310
1587
  };
1311
- return identityState.context.invitation ? /* @__PURE__ */ React24.createElement(IdentityPanelWithInvitationImpl, {
1588
+ return identityState.context.invitation ? /* @__PURE__ */ React27.createElement(IdentityPanelWithInvitationImpl, {
1312
1589
  ...implProps,
1313
1590
  invitation: identityState.context.invitation
1314
- }) : /* @__PURE__ */ React24.createElement(IdentityPanelImpl, implProps);
1591
+ }) : /* @__PURE__ */ React27.createElement(IdentityPanelImpl, implProps);
1315
1592
  };
1316
1593
 
1317
1594
  // packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx
1318
- import React34, { useCallback as useCallback6, useEffect as useEffect4, useMemo as useMemo4 } from "react";
1595
+ import React37, { useCallback as useCallback7, useEffect as useEffect5, useMemo as useMemo4 } from "react";
1319
1596
  import { log as log8 } from "@dxos/log";
1320
1597
  import { useClient as useClient6, useMulticastObservable } from "@dxos/react-client";
1321
1598
  import { useIdentity as useIdentity2 } from "@dxos/react-client/halo";
@@ -1323,25 +1600,25 @@ import { DensityProvider as DensityProvider3, useId as useId7, useThemeContext a
1323
1600
 
1324
1601
  // packages/sdk/shell/src/panels/JoinPanel/JoinHeading.tsx
1325
1602
  import { X as X4 } from "@phosphor-icons/react";
1326
- import React25, { cloneElement, forwardRef as forwardRef8 } from "react";
1327
- import { Button as Button5, useTranslation as useTranslation11 } from "@dxos/react-ui";
1328
- import { descriptionText as descriptionText8, getSize as getSize8, mx as mx19 } from "@dxos/react-ui-theme";
1603
+ import React28, { cloneElement, forwardRef as forwardRef8 } from "react";
1604
+ import { Button as Button5, useTranslation as useTranslation14 } from "@dxos/react-ui";
1605
+ import { descriptionText as descriptionText8, getSize as getSize9, mx as mx20 } from "@dxos/react-ui-theme";
1329
1606
  var JoinHeading = /* @__PURE__ */ forwardRef8(({ mode, titleId, onExit, exitActionParent }, forwardedRef) => {
1330
- const { t } = useTranslation11("os");
1331
- const exitButton = /* @__PURE__ */ React25.createElement(Button5, {
1607
+ const { t } = useTranslation14("os");
1608
+ const exitButton = /* @__PURE__ */ React28.createElement(Button5, {
1332
1609
  variant: "ghost",
1333
1610
  ...onExit && {
1334
1611
  onClick: onExit
1335
1612
  },
1336
- classNames: mx19(descriptionText8, "plb-0 pli-2 absolute block-start-0 inline-end-0 z-[1]"),
1613
+ classNames: mx20(descriptionText8, "plb-0 pli-2 absolute block-start-0 inline-end-0 z-[1]"),
1337
1614
  "data-testid": "join-exit"
1338
- }, /* @__PURE__ */ React25.createElement(X4, {
1615
+ }, /* @__PURE__ */ React28.createElement(X4, {
1339
1616
  weight: "bold",
1340
- className: getSize8(4)
1341
- }), /* @__PURE__ */ React25.createElement("span", {
1617
+ className: getSize9(4)
1618
+ }), /* @__PURE__ */ React28.createElement("span", {
1342
1619
  className: "sr-only"
1343
1620
  }, t("exit label")));
1344
- return /* @__PURE__ */ React25.createElement(Heading, {
1621
+ return /* @__PURE__ */ React28.createElement(Heading, {
1345
1622
  ref: forwardedRef,
1346
1623
  titleId,
1347
1624
  title: t(mode === "halo-only" ? "selecting identity heading" : "joining space heading"),
@@ -1356,14 +1633,14 @@ var JoinHeading = /* @__PURE__ */ forwardRef8(({ mode, titleId, onExit, exitActi
1356
1633
 
1357
1634
  // packages/sdk/shell/src/panels/JoinPanel/joinMachine.ts
1358
1635
  import { useMachine as useMachine2 } from "@xstate/react";
1359
- import { useCallback as useCallback5 } from "react";
1636
+ import { useCallback as useCallback6 } from "react";
1360
1637
  import { assign as assign2, createMachine as createMachine2 } from "xstate";
1361
1638
  import { log as log4 } from "@dxos/log";
1362
- import { Invitation as Invitation5, InvitationEncoder as InvitationEncoder2 } from "@dxos/react-client/invitations";
1363
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/joinMachine.ts";
1639
+ import { Invitation as Invitation6, InvitationEncoder as InvitationEncoder3 } from "@dxos/react-client/invitations";
1640
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/joinMachine.ts";
1364
1641
  var getInvitationSubscribable = (Kind, invitation) => {
1365
1642
  log4("[subscribing to invitation]", invitation, {
1366
- F: __dxlog_file4,
1643
+ F: __dxlog_file5,
1367
1644
  L: 88,
1368
1645
  S: void 0,
1369
1646
  C: (f, a) => f(...a)
@@ -1371,12 +1648,12 @@ var getInvitationSubscribable = (Kind, invitation) => {
1371
1648
  return {
1372
1649
  subscribe: (next, onError, complete) => invitation.subscribe((invitation2) => {
1373
1650
  switch (invitation2.state) {
1374
- case Invitation5.State.CONNECTING: {
1651
+ case Invitation6.State.CONNECTING: {
1375
1652
  log4("[invitation connecting]", {
1376
1653
  Kind,
1377
1654
  invitation: invitation2
1378
1655
  }, {
1379
- F: __dxlog_file4,
1656
+ F: __dxlog_file5,
1380
1657
  L: 99,
1381
1658
  S: void 0,
1382
1659
  C: (f, a) => f(...a)
@@ -1386,12 +1663,12 @@ var getInvitationSubscribable = (Kind, invitation) => {
1386
1663
  invitation: invitation2
1387
1664
  });
1388
1665
  }
1389
- case Invitation5.State.CONNECTED: {
1666
+ case Invitation6.State.CONNECTED: {
1390
1667
  log4("[invitation connected]", {
1391
1668
  Kind,
1392
1669
  invitation: invitation2
1393
1670
  }, {
1394
- F: __dxlog_file4,
1671
+ F: __dxlog_file5,
1395
1672
  L: 104,
1396
1673
  S: void 0,
1397
1674
  C: (f, a) => f(...a)
@@ -1401,12 +1678,12 @@ var getInvitationSubscribable = (Kind, invitation) => {
1401
1678
  invitation: invitation2
1402
1679
  });
1403
1680
  }
1404
- case Invitation5.State.READY_FOR_AUTHENTICATION: {
1681
+ case Invitation6.State.READY_FOR_AUTHENTICATION: {
1405
1682
  log4("[invitation ready for authentication]", {
1406
1683
  Kind,
1407
1684
  invitation: invitation2
1408
1685
  }, {
1409
- F: __dxlog_file4,
1686
+ F: __dxlog_file5,
1410
1687
  L: 109,
1411
1688
  S: void 0,
1412
1689
  C: (f, a) => f(...a)
@@ -1416,12 +1693,12 @@ var getInvitationSubscribable = (Kind, invitation) => {
1416
1693
  invitation: invitation2
1417
1694
  });
1418
1695
  }
1419
- case Invitation5.State.AUTHENTICATING: {
1696
+ case Invitation6.State.AUTHENTICATING: {
1420
1697
  log4("[invitation authenticating]", {
1421
1698
  Kind,
1422
1699
  invitation: invitation2
1423
1700
  }, {
1424
- F: __dxlog_file4,
1701
+ F: __dxlog_file5,
1425
1702
  L: 114,
1426
1703
  S: void 0,
1427
1704
  C: (f, a) => f(...a)
@@ -1431,12 +1708,12 @@ var getInvitationSubscribable = (Kind, invitation) => {
1431
1708
  invitation: invitation2
1432
1709
  });
1433
1710
  }
1434
- case Invitation5.State.SUCCESS: {
1711
+ case Invitation6.State.SUCCESS: {
1435
1712
  log4("[invitation success]", {
1436
1713
  Kind,
1437
1714
  invitation: invitation2
1438
1715
  }, {
1439
- F: __dxlog_file4,
1716
+ F: __dxlog_file5,
1440
1717
  L: 119,
1441
1718
  S: void 0,
1442
1719
  C: (f, a) => f(...a)
@@ -1447,11 +1724,11 @@ var getInvitationSubscribable = (Kind, invitation) => {
1447
1724
  });
1448
1725
  return complete?.();
1449
1726
  }
1450
- case Invitation5.State.CANCELLED: {
1727
+ case Invitation6.State.CANCELLED: {
1451
1728
  log4.warn("[invitation cancelled]", {
1452
1729
  Kind
1453
1730
  }, {
1454
- F: __dxlog_file4,
1731
+ F: __dxlog_file5,
1455
1732
  L: 125,
1456
1733
  S: void 0,
1457
1734
  C: (f, a) => f(...a)
@@ -1461,11 +1738,11 @@ var getInvitationSubscribable = (Kind, invitation) => {
1461
1738
  reason: "cancelled"
1462
1739
  });
1463
1740
  }
1464
- case Invitation5.State.TIMEOUT: {
1741
+ case Invitation6.State.TIMEOUT: {
1465
1742
  log4.error("[invitation timeout]", {
1466
1743
  Kind
1467
1744
  }, {
1468
- F: __dxlog_file4,
1745
+ F: __dxlog_file5,
1469
1746
  L: 130,
1470
1747
  S: void 0,
1471
1748
  C: (f, a) => f(...a)
@@ -1481,7 +1758,7 @@ var getInvitationSubscribable = (Kind, invitation) => {
1481
1758
  Kind,
1482
1759
  error
1483
1760
  }, {
1484
- F: __dxlog_file4,
1761
+ F: __dxlog_file5,
1485
1762
  L: 136,
1486
1763
  S: void 0,
1487
1764
  C: (f, a) => f(...a)
@@ -1544,7 +1821,7 @@ var acceptingInvitationTemplate = (Kind, successTarget) => {
1544
1821
  {
1545
1822
  cond: (context) => {
1546
1823
  const invitation = context[Kind.toLowerCase()].invitation;
1547
- return !invitation || invitation?.state === Invitation5.State.CONNECTING;
1824
+ return !invitation || invitation?.state === Invitation6.State.CONNECTING;
1548
1825
  },
1549
1826
  target: `connecting${Kind}Invitation`,
1550
1827
  actions: "log"
@@ -1801,12 +2078,12 @@ var joinMachine = createMachine2({
1801
2078
  } : context.space
1802
2079
  }),
1803
2080
  log: (context, event) => {
1804
- log4.info("[transition]", {
2081
+ log4("[transition]", {
1805
2082
  event,
1806
2083
  haloInvitation: context.halo.invitation,
1807
2084
  spaceInvitation: context.space.invitation
1808
2085
  }, {
1809
- F: __dxlog_file4,
2086
+ F: __dxlog_file5,
1810
2087
  L: 400,
1811
2088
  S: void 0,
1812
2089
  C: (f, a) => f(...a)
@@ -1820,7 +2097,7 @@ var defaultCodeFromUrl = (invitationType, text) => {
1820
2097
  return searchParams.get(`${invitationType}InvitationCode`) ?? searchParams.get(`${invitationType}Invitation`) ?? searchParams.get("invitationCode") ?? searchParams.get("invitation") ?? text;
1821
2098
  } catch (err) {
1822
2099
  log4.catch(err, void 0, {
1823
- F: __dxlog_file4,
2100
+ F: __dxlog_file5,
1824
2101
  L: 427,
1825
2102
  S: void 0,
1826
2103
  C: (f, a) => f(...a)
@@ -1829,10 +2106,10 @@ var defaultCodeFromUrl = (invitationType, text) => {
1829
2106
  }
1830
2107
  };
1831
2108
  var useJoinMachine = (client, options) => {
1832
- const redeemHaloInvitationCode = useCallback5(({ halo }) => {
2109
+ const redeemHaloInvitationCode = useCallback6(({ halo }) => {
1833
2110
  if (halo.unredeemedCode) {
1834
2111
  try {
1835
- const invitationObservable = client.halo.join(InvitationEncoder2.decode(defaultCodeFromUrl("halo", halo.unredeemedCode)));
2112
+ const invitationObservable = client.halo.join(InvitationEncoder3.decode(defaultCodeFromUrl("halo", halo.unredeemedCode)));
1836
2113
  return {
1837
2114
  ...halo,
1838
2115
  invitationObservable,
@@ -1840,7 +2117,7 @@ var useJoinMachine = (client, options) => {
1840
2117
  };
1841
2118
  } catch (err) {
1842
2119
  log4.error("Could not redeem device invitation code", err, {
1843
- F: __dxlog_file4,
2120
+ F: __dxlog_file5,
1844
2121
  L: 449,
1845
2122
  S: void 0,
1846
2123
  C: (f, a) => f(...a)
@@ -1853,10 +2130,10 @@ var useJoinMachine = (client, options) => {
1853
2130
  }, [
1854
2131
  client
1855
2132
  ]);
1856
- const redeemSpaceInvitationCode = useCallback5(({ space }) => {
2133
+ const redeemSpaceInvitationCode = useCallback6(({ space }) => {
1857
2134
  if (space.unredeemedCode) {
1858
2135
  try {
1859
- const invitation = InvitationEncoder2.decode(defaultCodeFromUrl("space", space.unredeemedCode));
2136
+ const invitation = InvitationEncoder3.decode(defaultCodeFromUrl("space", space.unredeemedCode));
1860
2137
  if (space.succeededKeys?.has(invitation.spaceKey?.toHex() ?? "never")) {
1861
2138
  return {
1862
2139
  ...space,
@@ -1872,7 +2149,7 @@ var useJoinMachine = (client, options) => {
1872
2149
  }
1873
2150
  } catch (err) {
1874
2151
  log4.error("Could not redeem space invitation code", err, {
1875
- F: __dxlog_file4,
2152
+ F: __dxlog_file5,
1876
2153
  L: 479,
1877
2154
  S: void 0,
1878
2155
  C: (f, a) => f(...a)
@@ -1885,7 +2162,7 @@ var useJoinMachine = (client, options) => {
1885
2162
  }, [
1886
2163
  client
1887
2164
  ]);
1888
- const invalidateHaloInvitationCode = useCallback5(({ halo }) => {
2165
+ const invalidateHaloInvitationCode = useCallback6(({ halo }) => {
1889
2166
  if (halo.unredeemedCode) {
1890
2167
  options?.onInvalidateInvitationCode?.(halo.unredeemedCode);
1891
2168
  return {
@@ -1898,7 +2175,7 @@ var useJoinMachine = (client, options) => {
1898
2175
  }, [
1899
2176
  options?.onInvalidateInvitationCode
1900
2177
  ]);
1901
- const invalidateSpaceInvitationCode = useCallback5(({ space }) => {
2178
+ const invalidateSpaceInvitationCode = useCallback6(({ space }) => {
1902
2179
  if (space.unredeemedCode) {
1903
2180
  options?.onInvalidateInvitationCode?.(space.unredeemedCode);
1904
2181
  return {
@@ -1933,17 +2210,17 @@ var useJoinMachine = (client, options) => {
1933
2210
 
1934
2211
  // packages/sdk/shell/src/panels/JoinPanel/steps/AdditionMethodChooser.tsx
1935
2212
  import { CaretRight as CaretRight2, Plus as Plus2, QrCode, Textbox } from "@phosphor-icons/react";
1936
- import React26 from "react";
1937
- import { useTranslation as useTranslation12 } from "@dxos/react-ui";
1938
- import { getSize as getSize9 } from "@dxos/react-ui-theme";
2213
+ import React29 from "react";
2214
+ import { useTranslation as useTranslation15 } from "@dxos/react-ui";
2215
+ import { getSize as getSize10 } from "@dxos/react-ui-theme";
1939
2216
  var AdditionMethodChooser = (viewStateProps) => {
1940
2217
  const disabled = !viewStateProps.active;
1941
2218
  const { send } = viewStateProps;
1942
- const { t } = useTranslation12("os");
2219
+ const { t } = useTranslation15("os");
1943
2220
  const sharedButtonProps = {
1944
2221
  disabled,
1945
- after: /* @__PURE__ */ React26.createElement(CaretRight2, {
1946
- className: getSize9(4),
2222
+ after: /* @__PURE__ */ React29.createElement(CaretRight2, {
2223
+ className: getSize10(4),
1947
2224
  weight: "bold"
1948
2225
  }),
1949
2226
  slots: {
@@ -1952,37 +2229,37 @@ var AdditionMethodChooser = (viewStateProps) => {
1952
2229
  }
1953
2230
  }
1954
2231
  };
1955
- return /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(StepHeading, null, t("addition method chooser title")), /* @__PURE__ */ React26.createElement("div", {
2232
+ return /* @__PURE__ */ React29.createElement(React29.Fragment, null, /* @__PURE__ */ React29.createElement(StepHeading, null, t("addition method chooser title")), /* @__PURE__ */ React29.createElement("div", {
1956
2233
  role: "none",
1957
2234
  className: "flex flex-col gap-1 grow"
1958
- }, /* @__PURE__ */ React26.createElement(CompoundButton, {
2235
+ }, /* @__PURE__ */ React29.createElement(CompoundButton, {
1959
2236
  ...sharedButtonProps,
1960
2237
  description: t("create identity description"),
1961
- before: /* @__PURE__ */ React26.createElement(Plus2, {
1962
- className: getSize9(6)
2238
+ before: /* @__PURE__ */ React29.createElement(Plus2, {
2239
+ className: getSize10(6)
1963
2240
  }),
1964
2241
  onClick: () => send({
1965
2242
  type: "createIdentity"
1966
2243
  }),
1967
2244
  "data-autofocus": "choosingAuthMethod",
1968
2245
  "data-testid": "create-identity"
1969
- }, t("create identity label")), /* @__PURE__ */ React26.createElement(CompoundButton, {
2246
+ }, t("create identity label")), /* @__PURE__ */ React29.createElement(CompoundButton, {
1970
2247
  ...sharedButtonProps,
1971
2248
  description: t("join identity description"),
1972
- before: /* @__PURE__ */ React26.createElement(QrCode, {
1973
- className: getSize9(6)
2249
+ before: /* @__PURE__ */ React29.createElement(QrCode, {
2250
+ className: getSize10(6)
1974
2251
  }),
1975
2252
  onClick: () => send({
1976
2253
  type: "acceptHaloInvitation"
1977
2254
  }),
1978
2255
  "data-testid": "join-identity"
1979
- }, t("join identity label")), /* @__PURE__ */ React26.createElement(CompoundButton, {
2256
+ }, t("join identity label")), /* @__PURE__ */ React29.createElement(CompoundButton, {
1980
2257
  ...sharedButtonProps,
1981
2258
  // TODO(mykola): Implement recover.
1982
2259
  disabled: true,
1983
2260
  description: t("recover identity description"),
1984
- before: /* @__PURE__ */ React26.createElement(Textbox, {
1985
- className: getSize9(6)
2261
+ before: /* @__PURE__ */ React29.createElement(Textbox, {
2262
+ className: getSize10(6)
1986
2263
  }),
1987
2264
  onClick: () => send({
1988
2265
  type: "recoverIdentity"
@@ -1992,37 +2269,37 @@ var AdditionMethodChooser = (viewStateProps) => {
1992
2269
  };
1993
2270
 
1994
2271
  // packages/sdk/shell/src/panels/JoinPanel/steps/IdentityAdded.tsx
1995
- import React27, { cloneElement as cloneElement2 } from "react";
2272
+ import React30, { cloneElement as cloneElement2 } from "react";
1996
2273
  import { generateName as generateName3 } from "@dxos/display-name";
1997
- import { Avatar as Avatar5, useId as useId6, useJdenticonHref as useJdenticonHref4, useTranslation as useTranslation13 } from "@dxos/react-ui";
1998
- import { mx as mx20 } from "@dxos/react-ui-theme";
2274
+ import { Avatar as Avatar5, useId as useId6, useJdenticonHref as useJdenticonHref4, useTranslation as useTranslation16 } from "@dxos/react-ui";
2275
+ import { mx as mx21 } from "@dxos/react-ui-theme";
1999
2276
  var IdentityAdded = (props) => {
2000
2277
  const { mode, addedIdentity, active, send, onDone, doneActionParent } = props;
2001
2278
  const disabled = !active;
2002
- const { t } = useTranslation13("os");
2279
+ const { t } = useTranslation16("os");
2003
2280
  const fallbackValue = addedIdentity?.identityKey.toHex();
2004
2281
  const labelId = useId6("identityListItem__label");
2005
2282
  const jdenticon = useJdenticonHref4(fallbackValue ?? "", 12);
2006
2283
  const displayName = addedIdentity?.profile?.displayName ?? (addedIdentity && generateName3(addedIdentity?.identityKey.toHex()));
2007
- const doneAction = /* @__PURE__ */ React27.createElement(Action, {
2284
+ const doneAction = /* @__PURE__ */ React30.createElement(Action, {
2008
2285
  ...onDone && {
2009
2286
  onClick: () => onDone(null)
2010
2287
  },
2011
2288
  disabled,
2012
2289
  "data-autofocus": "confirmingAddedIdentity",
2013
2290
  "data-testid": "identity-added-done"
2014
- }, /* @__PURE__ */ React27.createElement("span", null, t("done label")));
2015
- return /* @__PURE__ */ React27.createElement(React27.Fragment, null, /* @__PURE__ */ React27.createElement(StepHeading, null, t("identity added label")), /* @__PURE__ */ React27.createElement("div", {
2291
+ }, /* @__PURE__ */ React30.createElement("span", null, t("done label")));
2292
+ return /* @__PURE__ */ React30.createElement(React30.Fragment, null, /* @__PURE__ */ React30.createElement(StepHeading, null, t("identity added label")), /* @__PURE__ */ React30.createElement("div", {
2016
2293
  role: "none",
2017
2294
  className: "grow flex flex-col items-center justify-center text-center gap-2"
2018
- }, /* @__PURE__ */ React27.createElement(Avatar5.Root, {
2295
+ }, /* @__PURE__ */ React30.createElement(Avatar5.Root, {
2019
2296
  status: "active",
2020
2297
  labelId
2021
- }, /* @__PURE__ */ React27.createElement(Avatar5.Frame, null, /* @__PURE__ */ React27.createElement(Avatar5.Fallback, {
2298
+ }, /* @__PURE__ */ React30.createElement(Avatar5.Frame, null, /* @__PURE__ */ React30.createElement(Avatar5.Fallback, {
2022
2299
  href: jdenticon
2023
- })), /* @__PURE__ */ React27.createElement(Avatar5.Label, {
2024
- classNames: mx20("text-lg truncate", !addedIdentity?.profile?.displayName && "font-mono")
2025
- }, displayName))), /* @__PURE__ */ React27.createElement(Actions, null, mode === "halo-only" ? doneActionParent ? /* @__PURE__ */ cloneElement2(doneActionParent, {}, doneAction) : doneAction : /* @__PURE__ */ React27.createElement(Action, {
2300
+ })), /* @__PURE__ */ React30.createElement(Avatar5.Label, {
2301
+ classNames: mx21("text-lg truncate", !addedIdentity?.profile?.displayName && "font-mono")
2302
+ }, displayName))), /* @__PURE__ */ React30.createElement(Actions, null, mode === "halo-only" ? doneActionParent ? /* @__PURE__ */ cloneElement2(doneActionParent, {}, doneAction) : doneAction : /* @__PURE__ */ React30.createElement(Action, {
2026
2303
  variant: "primary",
2027
2304
  disabled: disabled || !addedIdentity,
2028
2305
  onClick: () => addedIdentity && send({
@@ -2034,17 +2311,17 @@ var IdentityAdded = (props) => {
2034
2311
  };
2035
2312
 
2036
2313
  // packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx
2037
- import React28, { useState as useState4 } from "react";
2314
+ import React31, { useState as useState5 } from "react";
2038
2315
  import { log as log5 } from "@dxos/log";
2039
2316
  import { useClient as useClient4 } from "@dxos/react-client";
2040
- import { useTranslation as useTranslation14 } from "@dxos/react-ui";
2041
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx";
2317
+ import { useTranslation as useTranslation17 } from "@dxos/react-ui";
2318
+ var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx";
2042
2319
  var IdentityInput = (props) => {
2043
2320
  const { send, method } = props;
2044
2321
  const isRecover = method === "recover identity";
2045
2322
  const client = useClient4();
2046
- const { t } = useTranslation14("os");
2047
- const [validationMessage, setValidationMessage] = useState4("");
2323
+ const { t } = useTranslation17("os");
2324
+ const [validationMessage, setValidationMessage] = useState5("");
2048
2325
  const createIdentity = (displayName) => {
2049
2326
  void client.halo.createIdentity({
2050
2327
  [isRecover ? "seedphrase" : "displayName"]: displayName
@@ -2055,7 +2332,7 @@ var IdentityInput = (props) => {
2055
2332
  });
2056
2333
  }, (error) => {
2057
2334
  log5.catch(error, void 0, {
2058
- F: __dxlog_file5,
2335
+ F: __dxlog_file6,
2059
2336
  L: 37,
2060
2337
  S: void 0,
2061
2338
  C: (f, a) => f(...a)
@@ -2063,7 +2340,7 @@ var IdentityInput = (props) => {
2063
2340
  setValidationMessage(t(isRecover ? "failed to recover identity message" : "failed to create identity message"));
2064
2341
  });
2065
2342
  };
2066
- return /* @__PURE__ */ React28.createElement(IdentityInputImpl, {
2343
+ return /* @__PURE__ */ React31.createElement(IdentityInputImpl, {
2067
2344
  ...props,
2068
2345
  onDisplayNameConfirm: createIdentity,
2069
2346
  validationMessage
@@ -2072,27 +2349,27 @@ var IdentityInput = (props) => {
2072
2349
  var IdentityInputImpl = (props) => {
2073
2350
  const { method, send, active, onDisplayNameConfirm, validationMessage } = props;
2074
2351
  const disabled = !active;
2075
- const { t } = useTranslation14("os");
2076
- const [inputValue, setInputValue] = useState4("");
2352
+ const { t } = useTranslation17("os");
2353
+ const [inputValue, setInputValue] = useState5("");
2077
2354
  const isRecover = method === "recover identity";
2078
- return /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement("div", {
2355
+ return /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement("div", {
2079
2356
  role: "none",
2080
2357
  className: "grow flex flex-col justify-center"
2081
- }, /* @__PURE__ */ React28.createElement(Input, {
2358
+ }, /* @__PURE__ */ React31.createElement(Input, {
2082
2359
  validationMessage,
2083
- label: /* @__PURE__ */ React28.createElement(StepHeading, null, t(isRecover ? "recover identity input label" : "new identity input label")),
2360
+ label: /* @__PURE__ */ React31.createElement(StepHeading, null, t(isRecover ? "recover identity input label" : "new identity input label")),
2084
2361
  disabled,
2085
2362
  "data-testid": "identity-input",
2086
2363
  placeholder: isRecover ? "Type your recovery phrase" : "Type a display name",
2087
2364
  onChange: ({ target: { value } }) => setInputValue(value)
2088
- })), /* @__PURE__ */ React28.createElement(Actions, null, /* @__PURE__ */ React28.createElement(Action, {
2365
+ })), /* @__PURE__ */ React31.createElement(Actions, null, /* @__PURE__ */ React31.createElement(Action, {
2089
2366
  variant: "ghost",
2090
2367
  disabled,
2091
2368
  onClick: () => send?.({
2092
2369
  type: "deselectAuthMethod"
2093
2370
  }),
2094
2371
  "data-testid": `${method === "recover identity" ? "recover" : "create"}-identity-input-back`
2095
- }, t("back label")), /* @__PURE__ */ React28.createElement(Action, {
2372
+ }, t("back label")), /* @__PURE__ */ React31.createElement(Action, {
2096
2373
  variant: "primary",
2097
2374
  disabled,
2098
2375
  onClick: () => onDisplayNameConfirm?.(inputValue),
@@ -2101,32 +2378,32 @@ var IdentityInputImpl = (props) => {
2101
2378
  };
2102
2379
 
2103
2380
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationAccepted.tsx
2104
- import React29, { cloneElement as cloneElement3 } from "react";
2105
- import { useTranslation as useTranslation15 } from "@dxos/react-ui";
2381
+ import React32, { cloneElement as cloneElement3 } from "react";
2382
+ import { useTranslation as useTranslation18 } from "@dxos/react-ui";
2106
2383
  var InvitationAccepted = (props) => {
2107
2384
  const { active, Kind, doneActionParent, onDone } = props;
2108
2385
  const disabled = !active;
2109
- const { t } = useTranslation15("os");
2110
- const doneAction = /* @__PURE__ */ React29.createElement(Action, {
2386
+ const { t } = useTranslation18("os");
2387
+ const doneAction = /* @__PURE__ */ React32.createElement(Action, {
2111
2388
  variant: "primary",
2112
2389
  onClick: onDone,
2113
2390
  disabled,
2114
2391
  "data-autofocus": `success${Kind}Invitation finishingJoining${Kind}`,
2115
2392
  "data-testid": `${Kind.toLowerCase()}-invitation-accepted-done`
2116
2393
  }, t("done label"));
2117
- return /* @__PURE__ */ React29.createElement(React29.Fragment, null, /* @__PURE__ */ React29.createElement("div", {
2394
+ return /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement("div", {
2118
2395
  role: "none",
2119
2396
  className: "grow flex flex-col justify-center"
2120
- }, /* @__PURE__ */ React29.createElement("p", {
2397
+ }, /* @__PURE__ */ React32.createElement("p", {
2121
2398
  className: "text-center text-sm font-normal"
2122
- }, t("welcome message"))), /* @__PURE__ */ React29.createElement(Actions, null, doneActionParent ? /* @__PURE__ */ cloneElement3(doneActionParent, {}, doneAction) : doneAction));
2399
+ }, t("welcome message"))), /* @__PURE__ */ React32.createElement(Actions, null, doneActionParent ? /* @__PURE__ */ cloneElement3(doneActionParent, {}, doneAction) : doneAction));
2123
2400
  };
2124
2401
 
2125
2402
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx
2126
- import React30, { useState as useState5, useEffect as useEffect3, cloneElement as cloneElement4 } from "react";
2403
+ import React33, { useState as useState6, useEffect as useEffect4, cloneElement as cloneElement4 } from "react";
2127
2404
  import { log as log6 } from "@dxos/log";
2128
- import { useTranslation as useTranslation16 } from "@dxos/react-ui";
2129
- var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx";
2405
+ import { useTranslation as useTranslation19 } from "@dxos/react-ui";
2406
+ var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx";
2130
2407
  var invitationCodeFromUrl = (text) => {
2131
2408
  try {
2132
2409
  const searchParams = new URLSearchParams(text.substring(text.lastIndexOf("?")));
@@ -2134,7 +2411,7 @@ var invitationCodeFromUrl = (text) => {
2134
2411
  return invitation ?? text;
2135
2412
  } catch (err) {
2136
2413
  log6.catch(err, void 0, {
2137
- F: __dxlog_file6,
2414
+ F: __dxlog_file7,
2138
2415
  L: 25,
2139
2416
  S: void 0,
2140
2417
  C: (f, a) => f(...a)
@@ -2145,9 +2422,9 @@ var invitationCodeFromUrl = (text) => {
2145
2422
  var InvitationInput = (props) => {
2146
2423
  const { Kind, active, send, unredeemedCode, onExit, exitActionParent, onDone, doneActionParent, succeededKeys } = props;
2147
2424
  const disabled = !active;
2148
- const { t } = useTranslation16("os");
2149
- const [inputValue, setInputValue] = useState5(unredeemedCode ?? "");
2150
- useEffect3(() => {
2425
+ const { t } = useTranslation19("os");
2426
+ const [inputValue, setInputValue] = useState6(unredeemedCode ?? "");
2427
+ useEffect4(() => {
2151
2428
  unredeemedCode && setInputValue(unredeemedCode ?? "");
2152
2429
  }, [
2153
2430
  unredeemedCode
@@ -2159,7 +2436,7 @@ var InvitationInput = (props) => {
2159
2436
  succeededKeys
2160
2437
  }
2161
2438
  });
2162
- const exitAction = /* @__PURE__ */ React30.createElement(Action, {
2439
+ const exitAction = /* @__PURE__ */ React33.createElement(Action, {
2163
2440
  variant: "ghost",
2164
2441
  disabled,
2165
2442
  ...onExit ? {
@@ -2169,11 +2446,11 @@ var InvitationInput = (props) => {
2169
2446
  },
2170
2447
  "data-testid": "join-exit"
2171
2448
  }, t("cancel label"));
2172
- return /* @__PURE__ */ React30.createElement(React30.Fragment, null, /* @__PURE__ */ React30.createElement("div", {
2449
+ return /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement("div", {
2173
2450
  role: "none",
2174
2451
  className: "grow flex flex-col justify-center"
2175
- }, /* @__PURE__ */ React30.createElement(Input, {
2176
- label: /* @__PURE__ */ React30.createElement(StepHeading, null, t("invitation input label")),
2452
+ }, /* @__PURE__ */ React33.createElement(Input, {
2453
+ label: /* @__PURE__ */ React33.createElement(StepHeading, null, t("invitation input label")),
2177
2454
  placeholder: "Type an invitation code",
2178
2455
  disabled,
2179
2456
  value: inputValue,
@@ -2181,14 +2458,14 @@ var InvitationInput = (props) => {
2181
2458
  "data-autofocus": `inputting${Kind}InvitationCode`,
2182
2459
  "data-testid": `${Kind.toLowerCase()}-invitation-input`,
2183
2460
  onKeyUp: ({ key }) => key === "Enter" && handleNext()
2184
- })), /* @__PURE__ */ React30.createElement(Actions, null, Kind === "Halo" ? /* @__PURE__ */ React30.createElement(Action, {
2461
+ })), /* @__PURE__ */ React33.createElement(Actions, null, Kind === "Halo" ? /* @__PURE__ */ React33.createElement(Action, {
2185
2462
  variant: "ghost",
2186
2463
  disabled,
2187
2464
  onClick: () => send({
2188
2465
  type: "deselectAuthMethod"
2189
2466
  }),
2190
2467
  "data-testid": `${Kind.toLowerCase()}-invitation-input-back`
2191
- }, t("back label")) : exitActionParent ? /* @__PURE__ */ cloneElement4(exitActionParent, {}, exitAction) : doneActionParent ? /* @__PURE__ */ cloneElement4(doneActionParent, {}, exitAction) : exitAction, /* @__PURE__ */ React30.createElement(Action, {
2468
+ }, t("back label")) : exitActionParent ? /* @__PURE__ */ cloneElement4(exitActionParent, {}, exitAction) : doneActionParent ? /* @__PURE__ */ cloneElement4(doneActionParent, {}, exitAction) : exitAction, /* @__PURE__ */ React33.createElement(Action, {
2192
2469
  variant: "primary",
2193
2470
  disabled,
2194
2471
  onClick: handleNext,
@@ -2197,8 +2474,8 @@ var InvitationInput = (props) => {
2197
2474
  };
2198
2475
 
2199
2476
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationRescuer.tsx
2200
- import React31 from "react";
2201
- import { useTranslation as useTranslation17 } from "@dxos/react-ui";
2477
+ import React34 from "react";
2478
+ import { useTranslation as useTranslation20 } from "@dxos/react-ui";
2202
2479
  import { descriptionText as descriptionText9 } from "@dxos/react-ui-theme";
2203
2480
  var InvitationActions = ({
2204
2481
  // `invitationState` does report correct state, but here we evaluate whether `failReason` is a better source of truth
@@ -2210,14 +2487,14 @@ var InvitationActions = ({
2210
2487
  Kind,
2211
2488
  failReason
2212
2489
  }) => {
2213
- const { t } = useTranslation17("os");
2490
+ const { t } = useTranslation20("os");
2214
2491
  if (failReason) {
2215
- return /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement(StepHeading, {
2492
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement(StepHeading, {
2216
2493
  className: descriptionText9
2217
- }, t(failReason === "timeout" ? "timeout status label" : failReason === "cancelled" ? "cancelled status label" : "error status label")), /* @__PURE__ */ React31.createElement("div", {
2494
+ }, t(failReason === "timeout" ? "timeout status label" : failReason === "cancelled" ? "cancelled status label" : "error status label")), /* @__PURE__ */ React34.createElement("div", {
2218
2495
  role: "none",
2219
2496
  className: "grow"
2220
- }), /* @__PURE__ */ React31.createElement(Actions, null, /* @__PURE__ */ React31.createElement(Action, {
2497
+ }), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2221
2498
  disabled: !active,
2222
2499
  onClick: () => send({
2223
2500
  type: `reset${Kind}Invitation`
@@ -2225,16 +2502,16 @@ var InvitationActions = ({
2225
2502
  "data-testid": "invitation-rescuer-reset"
2226
2503
  }, t("reset label"))));
2227
2504
  } else {
2228
- return /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement(StepHeading, {
2505
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement(StepHeading, {
2229
2506
  className: descriptionText9
2230
- }, t("connecting status label")), /* @__PURE__ */ React31.createElement("div", {
2507
+ }, t("connecting status label")), /* @__PURE__ */ React34.createElement("div", {
2231
2508
  role: "none",
2232
2509
  className: "grow"
2233
- }), /* @__PURE__ */ React31.createElement(Actions, null, /* @__PURE__ */ React31.createElement(Action, {
2510
+ }), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2234
2511
  disabled: true,
2235
2512
  classNames: "order-2",
2236
2513
  "data-testid": "next"
2237
- }, t("next label")), /* @__PURE__ */ React31.createElement(Action, {
2514
+ }, t("next label")), /* @__PURE__ */ React34.createElement(Action, {
2238
2515
  disabled: !active,
2239
2516
  onClick: onInvitationCancel,
2240
2517
  "data-testid": "invitation-rescuer-cancel"
@@ -2243,46 +2520,46 @@ var InvitationActions = ({
2243
2520
  };
2244
2521
  var InvitationRescuer = (props) => {
2245
2522
  const { Kind, invitationState, active, send } = props;
2246
- const { t } = useTranslation17("os");
2247
- return /* @__PURE__ */ React31.createElement(React31.Fragment, null, typeof invitationState === "undefined" ? /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement("div", {
2523
+ const { t } = useTranslation20("os");
2524
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, typeof invitationState === "undefined" ? /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement("div", {
2248
2525
  role: "none",
2249
2526
  className: "grow flex flex-col justify-center"
2250
- }, /* @__PURE__ */ React31.createElement(StepHeading, {
2527
+ }, /* @__PURE__ */ React34.createElement(StepHeading, {
2251
2528
  className: descriptionText9
2252
- }, "There was a problem joining the space")), /* @__PURE__ */ React31.createElement(Actions, null, /* @__PURE__ */ React31.createElement(Action, {
2529
+ }, "There was a problem joining the space")), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2253
2530
  disabled: !active,
2254
2531
  "data-testid": "invitation-rescuer-blank-reset",
2255
2532
  onClick: () => send({
2256
2533
  type: `reset${Kind}Invitation`
2257
2534
  })
2258
- }, t("reset label")))) : /* @__PURE__ */ React31.createElement(InvitationActions, props));
2535
+ }, t("reset label")))) : /* @__PURE__ */ React34.createElement(InvitationActions, props));
2259
2536
  };
2260
2537
 
2261
2538
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationAuthenticator.tsx
2262
- import React32, { useState as useState6 } from "react";
2263
- import { Input as Input2, useTranslation as useTranslation18 } from "@dxos/react-ui";
2539
+ import React35, { useState as useState7 } from "react";
2540
+ import { Input as Input2, useTranslation as useTranslation21 } from "@dxos/react-ui";
2264
2541
  var pinLength = 6;
2265
2542
  var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, onInvitationAuthenticate, onInvitationCancel }) => {
2266
2543
  const disabled = !active || pending;
2267
- const { t } = useTranslation18("os");
2544
+ const { t } = useTranslation21("os");
2268
2545
  const invitationType = Kind.toLowerCase();
2269
- const [authCode, setAuthCode] = useState6("");
2546
+ const [authCode, setAuthCode] = useState7("");
2270
2547
  const onChange = ({ target: { value } }) => {
2271
2548
  setAuthCode(value);
2272
2549
  if (value.length === pinLength) {
2273
2550
  document.querySelector(`[data-autofocus-pinlength="${invitationType}"]`)?.focus();
2274
2551
  }
2275
2552
  };
2276
- return /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement("div", {
2553
+ return /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement("div", {
2277
2554
  role: "none",
2278
2555
  className: "grow flex flex-col justify-center"
2279
- }, invitationId && /* @__PURE__ */ React32.createElement(Emoji, {
2556
+ }, invitationId && /* @__PURE__ */ React35.createElement(Emoji, {
2280
2557
  text: toEmoji(invitationId)
2281
- }), /* @__PURE__ */ React32.createElement(Input2.Root, failed && {
2558
+ }), /* @__PURE__ */ React35.createElement(Input2.Root, failed && {
2282
2559
  validationValence: "error"
2283
- }, /* @__PURE__ */ React32.createElement(Input2.Label, {
2560
+ }, /* @__PURE__ */ React35.createElement(Input2.Label, {
2284
2561
  asChild: true
2285
- }, /* @__PURE__ */ React32.createElement(StepHeading, null, t("auth code input label"))), /* @__PURE__ */ React32.createElement(Input2.PinInput, {
2562
+ }, /* @__PURE__ */ React35.createElement(StepHeading, null, t("auth code input label"))), /* @__PURE__ */ React35.createElement(Input2.PinInput, {
2286
2563
  disabled,
2287
2564
  length: pinLength,
2288
2565
  onChange,
@@ -2293,14 +2570,14 @@ var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, on
2293
2570
  "data-prevent-ios-autofocus": true,
2294
2571
  "data-testid": `${invitationType}-auth-code-input`,
2295
2572
  "data-1p-ignore": true
2296
- }), failed && /* @__PURE__ */ React32.createElement(Input2.DescriptionAndValidation, {
2573
+ }), failed && /* @__PURE__ */ React35.createElement(Input2.DescriptionAndValidation, {
2297
2574
  classNames: "text-center"
2298
- }, /* @__PURE__ */ React32.createElement(Input2.Validation, null, t("failed to authenticate message"))))), /* @__PURE__ */ React32.createElement(Actions, null, /* @__PURE__ */ React32.createElement(Action, {
2575
+ }, /* @__PURE__ */ React35.createElement(Input2.Validation, null, t("failed to authenticate message"))))), /* @__PURE__ */ React35.createElement(Actions, null, /* @__PURE__ */ React35.createElement(Action, {
2299
2576
  variant: "ghost",
2300
2577
  disabled,
2301
2578
  onClick: () => onInvitationCancel?.(),
2302
2579
  "data-testid": `${invitationType}-invitation-authenticator-cancel`
2303
- }, t("cancel label")), /* @__PURE__ */ React32.createElement(Action, {
2580
+ }, t("cancel label")), /* @__PURE__ */ React35.createElement(Action, {
2304
2581
  variant: "primary",
2305
2582
  disabled,
2306
2583
  onClick: () => onInvitationAuthenticate?.(authCode),
@@ -2310,21 +2587,21 @@ var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, on
2310
2587
  };
2311
2588
 
2312
2589
  // packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx
2313
- import React33, { useState as useState7 } from "react";
2590
+ import React36, { useState as useState8 } from "react";
2314
2591
  import { log as log7 } from "@dxos/log";
2315
2592
  import { useClient as useClient5 } from "@dxos/react-client";
2316
- import { useTranslation as useTranslation19 } from "@dxos/react-ui";
2317
- var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx";
2593
+ import { useTranslation as useTranslation22 } from "@dxos/react-ui";
2594
+ var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx";
2318
2595
  var ResetIdentity = ({ send, active }) => {
2319
2596
  const client = useClient5();
2320
- const { t } = useTranslation19("os");
2321
- const [validationMessage, setValidationMessage] = useState7("");
2597
+ const { t } = useTranslation22("os");
2598
+ const [validationMessage, setValidationMessage] = useState8("");
2322
2599
  const resetIdentity = () => {
2323
2600
  void client.reset().then(() => send?.({
2324
2601
  type: "resetIdentity"
2325
2602
  }), (error) => {
2326
2603
  log7.catch(error, void 0, {
2327
- F: __dxlog_file7,
2604
+ F: __dxlog_file8,
2328
2605
  L: 32,
2329
2606
  S: void 0,
2330
2607
  C: (f, a) => f(...a)
@@ -2332,29 +2609,29 @@ var ResetIdentity = ({ send, active }) => {
2332
2609
  setValidationMessage(t("failed to reset identity message"));
2333
2610
  });
2334
2611
  };
2335
- return /* @__PURE__ */ React33.createElement(ResetIdentityImpl, {
2612
+ return /* @__PURE__ */ React36.createElement(ResetIdentityImpl, {
2336
2613
  disabled: !active,
2337
2614
  validationMessage,
2338
2615
  onConfirm: () => resetIdentity()
2339
2616
  });
2340
2617
  };
2341
2618
  var ResetIdentityImpl = ({ disabled, validationMessage, onConfirm }) => {
2342
- const { t } = useTranslation19("os");
2619
+ const { t } = useTranslation22("os");
2343
2620
  const confirmationValue = t("confirmation value");
2344
- const [inputValue, setInputValue] = useState7("");
2345
- return /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement("div", {
2621
+ const [inputValue, setInputValue] = useState8("");
2622
+ return /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement("div", {
2346
2623
  role: "none",
2347
2624
  className: "grow flex flex-col justify-center"
2348
- }, /* @__PURE__ */ React33.createElement(Input, {
2625
+ }, /* @__PURE__ */ React36.createElement(Input, {
2349
2626
  validationMessage,
2350
- label: /* @__PURE__ */ React33.createElement(StepHeading, null, t("reset identity input label", {
2627
+ label: /* @__PURE__ */ React36.createElement(StepHeading, null, t("reset identity input label", {
2351
2628
  confirmationValue
2352
2629
  })),
2353
2630
  disabled,
2354
2631
  "data-testid": "identity-input",
2355
2632
  placeholder: confirmationValue,
2356
2633
  onChange: ({ target: { value } }) => setInputValue(value)
2357
- })), /* @__PURE__ */ React33.createElement(Actions, null, /* @__PURE__ */ React33.createElement(Action, {
2634
+ })), /* @__PURE__ */ React36.createElement(Actions, null, /* @__PURE__ */ React36.createElement(Action, {
2358
2635
  // TODO(wittjosiah): Probably make this red?
2359
2636
  variant: "primary",
2360
2637
  disabled: disabled || inputValue !== confirmationValue,
@@ -2367,7 +2644,7 @@ var ResetIdentityImpl = ({ disabled, validationMessage, onConfirm }) => {
2367
2644
  var stepStyles = "pbs-1 pbe-3 pli-3";
2368
2645
 
2369
2646
  // packages/sdk/shell/src/styles/invitationStatusStyles.ts
2370
- import { Invitation as Invitation6 } from "@dxos/react-client/invitations";
2647
+ import { Invitation as Invitation7 } from "@dxos/react-client/invitations";
2371
2648
  var inactiveBgColor = "bg-neutral-100 dark:bg-neutral-600";
2372
2649
  var activeBgColor = "bg-primary-500 dark:bg-primary-400";
2373
2650
  var successBgColor = "bg-success-500 dark:bg-success-400";
@@ -2383,55 +2660,55 @@ var activeStrokeColor = "stroke-primary-400 dark:stroke-primary-150";
2383
2660
  var successStrokeColor = "stroke-success-300 dark:stroke-primary-400";
2384
2661
  var errorStrokeColor = "stroke-error-300 dark:stroke-error-500";
2385
2662
  var cancelledStrokeColor = "stroke-warning-300 dark:stroke-warning-500";
2386
- var resolvedStrokeColor = (status) => status === Invitation6.State.ERROR ? errorStrokeColor : status === Invitation6.State.CANCELLED || status === Invitation6.State.TIMEOUT ? cancelledStrokeColor : successStrokeColor;
2387
- var resolvedBgColor = (status) => status === Invitation6.State.ERROR ? errorBgColor : status === Invitation6.State.CANCELLED || status === Invitation6.State.TIMEOUT ? cancelledBgColor : successBgColor;
2388
- var resolvedTextColor = (status) => status === Invitation6.State.ERROR ? errorTextColor : status === Invitation6.State.CANCELLED || status === Invitation6.State.TIMEOUT ? cancelledTextColor : successTextColor;
2663
+ var resolvedStrokeColor = (status) => status === Invitation7.State.ERROR ? errorStrokeColor : status === Invitation7.State.CANCELLED || status === Invitation7.State.TIMEOUT ? cancelledStrokeColor : successStrokeColor;
2664
+ var resolvedBgColor = (status) => status === Invitation7.State.ERROR ? errorBgColor : status === Invitation7.State.CANCELLED || status === Invitation7.State.TIMEOUT ? cancelledBgColor : successBgColor;
2665
+ var resolvedTextColor = (status) => status === Invitation7.State.ERROR ? errorTextColor : status === Invitation7.State.CANCELLED || status === Invitation7.State.TIMEOUT ? cancelledTextColor : successTextColor;
2389
2666
 
2390
2667
  // packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx
2391
- var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx";
2668
+ var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx";
2392
2669
  var JoinPanelImpl = (props) => {
2393
2670
  const { titleId, send, activeView, failed, mode, unredeemedCodes, invitationStates, succeededKeys, failReasons, onExit, onHaloDone, onSpaceDone, exitActionParent, doneActionParent, onHaloInvitationCancel, onSpaceInvitationCancel, onHaloInvitationAuthenticate, onSpaceInvitationAuthenticate, IdentityInput: IdentityInputComponent = IdentityInput, ResetIdentity: ResetIdentityComponent = ResetIdentity } = props;
2394
- return /* @__PURE__ */ React34.createElement(DensityProvider3, {
2671
+ return /* @__PURE__ */ React37.createElement(DensityProvider3, {
2395
2672
  density: "fine"
2396
- }, mode !== "halo-only" && /* @__PURE__ */ React34.createElement(JoinHeading, {
2673
+ }, mode !== "halo-only" && /* @__PURE__ */ React37.createElement(JoinHeading, {
2397
2674
  titleId,
2398
2675
  mode,
2399
2676
  onExit,
2400
2677
  exitActionParent
2401
- }), /* @__PURE__ */ React34.createElement(Viewport.Root, {
2678
+ }), /* @__PURE__ */ React37.createElement(Viewport.Root, {
2402
2679
  focusManaged: true,
2403
2680
  activeView
2404
- }, /* @__PURE__ */ React34.createElement(Viewport.Views, null, /* @__PURE__ */ React34.createElement(Viewport.View, {
2681
+ }, /* @__PURE__ */ React37.createElement(Viewport.Views, null, /* @__PURE__ */ React37.createElement(Viewport.View, {
2405
2682
  classNames: stepStyles,
2406
2683
  id: "addition method chooser"
2407
- }, /* @__PURE__ */ React34.createElement(AdditionMethodChooser, {
2684
+ }, /* @__PURE__ */ React37.createElement(AdditionMethodChooser, {
2408
2685
  send,
2409
2686
  active: activeView === "addition method chooser"
2410
- })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2687
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2411
2688
  classNames: stepStyles,
2412
2689
  id: "reset identity confirmation"
2413
- }, /* @__PURE__ */ React34.createElement(ResetIdentityComponent, {
2690
+ }, /* @__PURE__ */ React37.createElement(ResetIdentityComponent, {
2414
2691
  send,
2415
2692
  method: "reset identity",
2416
2693
  active: activeView === "reset identity confirmation"
2417
- })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2694
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2418
2695
  classNames: stepStyles,
2419
2696
  id: "create identity input"
2420
- }, /* @__PURE__ */ React34.createElement(IdentityInputComponent, {
2697
+ }, /* @__PURE__ */ React37.createElement(IdentityInputComponent, {
2421
2698
  send,
2422
2699
  method: "create identity",
2423
2700
  active: activeView === "create identity input"
2424
- })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2701
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2425
2702
  classNames: stepStyles,
2426
2703
  id: "recover identity input"
2427
- }, /* @__PURE__ */ React34.createElement(IdentityInputComponent, {
2704
+ }, /* @__PURE__ */ React37.createElement(IdentityInputComponent, {
2428
2705
  send,
2429
2706
  method: "recover identity",
2430
2707
  active: activeView === "recover identity input"
2431
- })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2708
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2432
2709
  classNames: stepStyles,
2433
2710
  id: "halo invitation input"
2434
- }, /* @__PURE__ */ React34.createElement(InvitationInput, {
2711
+ }, /* @__PURE__ */ React37.createElement(InvitationInput, {
2435
2712
  send,
2436
2713
  Kind: "Halo",
2437
2714
  active: activeView === "halo invitation input",
@@ -2441,20 +2718,20 @@ var JoinPanelImpl = (props) => {
2441
2718
  ...succeededKeys?.Halo && {
2442
2719
  succeededKeys: succeededKeys.Halo
2443
2720
  }
2444
- })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2721
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2445
2722
  classNames: stepStyles,
2446
2723
  id: "halo invitation rescuer"
2447
- }, /* @__PURE__ */ React34.createElement(InvitationRescuer, {
2724
+ }, /* @__PURE__ */ React37.createElement(InvitationRescuer, {
2448
2725
  send,
2449
2726
  Kind: "Halo",
2450
2727
  active: activeView === "halo invitation rescuer",
2451
2728
  invitationState: invitationStates?.Halo,
2452
2729
  onInvitationCancel: onHaloInvitationCancel,
2453
2730
  failReason: failReasons?.Halo
2454
- })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2731
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2455
2732
  classNames: stepStyles,
2456
2733
  id: "halo invitation authenticator"
2457
- }, /* @__PURE__ */ React34.createElement(InvitationAuthenticator, {
2734
+ }, /* @__PURE__ */ React37.createElement(InvitationAuthenticator, {
2458
2735
  send,
2459
2736
  Kind: "Halo",
2460
2737
  active: activeView === "halo invitation authenticator",
@@ -2463,28 +2740,28 @@ var JoinPanelImpl = (props) => {
2463
2740
  ...failed.has("Halo") && {
2464
2741
  failed: true
2465
2742
  }
2466
- })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2743
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2467
2744
  classNames: stepStyles,
2468
2745
  id: "halo invitation accepted"
2469
- }, /* @__PURE__ */ React34.createElement(InvitationAccepted, {
2746
+ }, /* @__PURE__ */ React37.createElement(InvitationAccepted, {
2470
2747
  send,
2471
2748
  Kind: "Halo",
2472
2749
  active: activeView === "halo invitation accepted",
2473
2750
  doneActionParent,
2474
2751
  onDone: onHaloDone
2475
- })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2752
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2476
2753
  classNames: stepStyles,
2477
2754
  id: "identity added"
2478
- }, /* @__PURE__ */ React34.createElement(IdentityAdded, {
2755
+ }, /* @__PURE__ */ React37.createElement(IdentityAdded, {
2479
2756
  send,
2480
2757
  mode,
2481
2758
  active: activeView === "identity added",
2482
2759
  doneActionParent,
2483
2760
  onDone: onHaloDone
2484
- })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2761
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2485
2762
  classNames: stepStyles,
2486
2763
  id: "space invitation input"
2487
- }, /* @__PURE__ */ React34.createElement(InvitationInput, {
2764
+ }, /* @__PURE__ */ React37.createElement(InvitationInput, {
2488
2765
  send,
2489
2766
  Kind: "Space",
2490
2767
  active: activeView === "space invitation input",
@@ -2496,20 +2773,20 @@ var JoinPanelImpl = (props) => {
2496
2773
  },
2497
2774
  onExit,
2498
2775
  exitActionParent
2499
- })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2776
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2500
2777
  classNames: stepStyles,
2501
2778
  id: "space invitation rescuer"
2502
- }, /* @__PURE__ */ React34.createElement(InvitationRescuer, {
2779
+ }, /* @__PURE__ */ React37.createElement(InvitationRescuer, {
2503
2780
  send,
2504
2781
  Kind: "Space",
2505
2782
  active: activeView === "space invitation rescuer",
2506
2783
  invitationState: invitationStates?.Space,
2507
2784
  onInvitationCancel: onSpaceInvitationCancel,
2508
2785
  failReason: failReasons?.Space
2509
- })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2786
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2510
2787
  classNames: stepStyles,
2511
2788
  id: "space invitation authenticator"
2512
- }, /* @__PURE__ */ React34.createElement(InvitationAuthenticator, {
2789
+ }, /* @__PURE__ */ React37.createElement(InvitationAuthenticator, {
2513
2790
  send,
2514
2791
  Kind: "Space",
2515
2792
  active: activeView === "space invitation authenticator",
@@ -2518,10 +2795,10 @@ var JoinPanelImpl = (props) => {
2518
2795
  ...failed.has("Space") && {
2519
2796
  failed: true
2520
2797
  }
2521
- })), /* @__PURE__ */ React34.createElement(Viewport.View, {
2798
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2522
2799
  classNames: stepStyles,
2523
2800
  id: "space invitation accepted"
2524
- }, /* @__PURE__ */ React34.createElement(InvitationAccepted, {
2801
+ }, /* @__PURE__ */ React37.createElement(InvitationAccepted, {
2525
2802
  send,
2526
2803
  Kind: "Space",
2527
2804
  active: activeView === "space invitation accepted",
@@ -2545,12 +2822,11 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
2545
2822
  }
2546
2823
  }
2547
2824
  });
2548
- console.log("[joinState]", joinState);
2549
- useEffect4(() => {
2825
+ useEffect5(() => {
2550
2826
  const subscription = joinService.subscribe((state) => {
2551
2827
  log8("[state]", state, {
2552
- F: __dxlog_file8,
2553
- L: 200,
2828
+ F: __dxlog_file9,
2829
+ L: 198,
2554
2830
  S: void 0,
2555
2831
  C: (f, a) => f(...a)
2556
2832
  });
@@ -2559,7 +2835,7 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
2559
2835
  }, [
2560
2836
  joinService
2561
2837
  ]);
2562
- useEffect4(() => {
2838
+ useEffect5(() => {
2563
2839
  const stateStack = joinState.configuration[0].id.split(".");
2564
2840
  const innermostState = stateStack[stateStack.length - 1];
2565
2841
  const autoFocusValue = innermostState === "finishingJoining" ? "successSpaceInvitation" : innermostState;
@@ -2740,27 +3016,29 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
2740
3016
  }), [
2741
3017
  joinState
2742
3018
  ]);
2743
- const onHaloDone = useCallback6(() => {
3019
+ const onHaloDone = useCallback7(() => {
2744
3020
  propsOnDone?.({
2745
3021
  identityKey: joinState.context.halo.invitation?.identityKey ?? null,
2746
3022
  swarmKey: joinState.context.halo.invitation?.swarmKey ?? null,
2747
- spaceKey: joinState.context.halo.invitation?.spaceKey ?? null
3023
+ spaceKey: joinState.context.halo.invitation?.spaceKey ?? null,
3024
+ target: joinState.context.halo.invitation?.target ?? null
2748
3025
  });
2749
3026
  }, [
2750
3027
  joinState,
2751
3028
  propsOnDone
2752
3029
  ]);
2753
- const onSpaceDone = useCallback6(() => {
3030
+ const onSpaceDone = useCallback7(() => {
2754
3031
  propsOnDone?.({
2755
3032
  identityKey: joinState.context.space.invitation?.identityKey ?? null,
2756
3033
  swarmKey: joinState.context.space.invitation?.swarmKey ?? null,
2757
- spaceKey: joinState.context.space.invitation?.spaceKey ?? null
3034
+ spaceKey: joinState.context.space.invitation?.spaceKey ?? null,
3035
+ target: joinState.context.space.invitation?.target ?? null
2758
3036
  });
2759
3037
  }, [
2760
3038
  joinState,
2761
3039
  propsOnDone
2762
3040
  ]);
2763
- return /* @__PURE__ */ React34.createElement(JoinPanelImpl, {
3041
+ return /* @__PURE__ */ React37.createElement(JoinPanelImpl, {
2764
3042
  titleId,
2765
3043
  mode,
2766
3044
  send: joinSend,
@@ -2799,16 +3077,16 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
2799
3077
 
2800
3078
  // packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx
2801
3079
  import { Planet } from "@phosphor-icons/react";
2802
- import React36, { useEffect as useEffect5, useMemo as useMemo5 } from "react";
3080
+ import React39, { useEffect as useEffect6, useMemo as useMemo5 } from "react";
2803
3081
  import { log as log10 } from "@dxos/log";
2804
3082
  import { useInvitationStatus as useInvitationStatus3 } from "@dxos/react-client/invitations";
2805
- import { DensityProvider as DensityProvider4, useId as useId8, useTranslation as useTranslation21 } from "@dxos/react-ui";
3083
+ import { DensityProvider as DensityProvider4, useId as useId8, useTranslation as useTranslation24 } from "@dxos/react-ui";
2806
3084
 
2807
3085
  // packages/sdk/shell/src/panels/SpacePanel/spaceMachine.ts
2808
3086
  import { useMachine as useMachine3 } from "@xstate/react";
2809
3087
  import { assign as assign3, createMachine as createMachine3 } from "xstate";
2810
3088
  import { log as log9 } from "@dxos/log";
2811
- var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/spaceMachine.ts";
3089
+ var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/spaceMachine.ts";
2812
3090
  var spaceMachine = createMachine3({
2813
3091
  id: "space",
2814
3092
  predictableActionArguments: true,
@@ -2849,7 +3127,7 @@ var spaceMachine = createMachine3({
2849
3127
  event,
2850
3128
  context
2851
3129
  }, {
2852
- F: __dxlog_file9,
3130
+ F: __dxlog_file10,
2853
3131
  L: 53,
2854
3132
  S: void 0,
2855
3133
  C: (f, a) => f(...a)
@@ -2868,21 +3146,21 @@ var useSpaceMachine = (options) => {
2868
3146
 
2869
3147
  // packages/sdk/shell/src/panels/SpacePanel/steps/SpaceManager.tsx
2870
3148
  import { Placeholder as Placeholder2, UserPlus, UsersThree } from "@phosphor-icons/react";
2871
- import React35, { useCallback as useCallback7, useState as useState8 } from "react";
3149
+ import React38, { useCallback as useCallback8, useState as useState9 } from "react";
2872
3150
  import { useConfig } from "@dxos/react-client";
2873
3151
  import { useSpaceInvitations as useSpaceInvitations2 } from "@dxos/react-client/echo";
2874
- import { Invitation as Invitation7, InvitationEncoder as InvitationEncoder3 } from "@dxos/react-client/invitations";
2875
- import { ScrollArea, useTranslation as useTranslation20 } from "@dxos/react-ui";
2876
- import { descriptionText as descriptionText10, mx as mx21 } from "@dxos/react-ui-theme";
3152
+ import { Invitation as Invitation8, InvitationEncoder as InvitationEncoder4 } from "@dxos/react-client/invitations";
3153
+ import { ScrollArea, useTranslation as useTranslation23 } from "@dxos/react-ui";
3154
+ import { descriptionText as descriptionText10, mx as mx22 } from "@dxos/react-ui-theme";
2877
3155
  var activeActionKey = "dxos:react-shell/space-manager/active-action";
2878
3156
  var SpaceManager = (props) => {
2879
- const { space } = props;
2880
- const { t } = useTranslation20("os");
3157
+ const { space, target } = props;
3158
+ const { t } = useTranslation23("os");
2881
3159
  const config = useConfig();
2882
3160
  const invitations = useSpaceInvitations2(space?.key);
2883
- const onInvitationEvent = useCallback7((invitation) => {
2884
- const invitationCode = InvitationEncoder3.encode(invitation);
2885
- if (invitation.state === Invitation7.State.CONNECTING) {
3161
+ const onInvitationEvent = useCallback8((invitation) => {
3162
+ const invitationCode = InvitationEncoder4.encode(invitation);
3163
+ if (invitation.state === Invitation8.State.CONNECTING) {
2886
3164
  console.log(JSON.stringify({
2887
3165
  invitationCode,
2888
3166
  authCode: invitation.authCode
@@ -2894,10 +3172,11 @@ var SpaceManager = (props) => {
2894
3172
  label: t("invite one label"),
2895
3173
  description: t("invite one description"),
2896
3174
  icon: UserPlus,
2897
- onClick: useCallback7(() => {
3175
+ onClick: useCallback8(() => {
2898
3176
  const invitation = space.share?.({
2899
- type: Invitation7.Type.INTERACTIVE,
2900
- authMethod: Invitation7.AuthMethod.SHARED_SECRET
3177
+ type: Invitation8.Type.INTERACTIVE,
3178
+ authMethod: Invitation8.AuthMethod.SHARED_SECRET,
3179
+ target
2901
3180
  });
2902
3181
  if (invitation && config.values.runtime?.app?.env?.DX_ENVIRONMENT !== "production") {
2903
3182
  invitation.subscribe(onInvitationEvent);
@@ -2910,10 +3189,11 @@ var SpaceManager = (props) => {
2910
3189
  label: t("invite many label"),
2911
3190
  description: t("invite many description"),
2912
3191
  icon: UsersThree,
2913
- onClick: useCallback7(() => {
3192
+ onClick: useCallback8(() => {
2914
3193
  const invitation = space.share?.({
2915
- type: Invitation7.Type.MULTIUSE,
2916
- authMethod: Invitation7.AuthMethod.NONE
3194
+ type: Invitation8.Type.MULTIUSE,
3195
+ authMethod: Invitation8.AuthMethod.NONE,
3196
+ target
2917
3197
  });
2918
3198
  if (invitation && config.values.runtime?.app?.env?.DX_ENVIRONMENT !== "production") {
2919
3199
  invitation.subscribe(onInvitationEvent);
@@ -2923,7 +3203,7 @@ var SpaceManager = (props) => {
2923
3203
  ])
2924
3204
  }
2925
3205
  };
2926
- return /* @__PURE__ */ React35.createElement(SpaceManagerImpl, {
3206
+ return /* @__PURE__ */ React38.createElement(SpaceManagerImpl, {
2927
3207
  ...props,
2928
3208
  invitations,
2929
3209
  inviteActions
@@ -2932,7 +3212,7 @@ var SpaceManager = (props) => {
2932
3212
  var headingFragment = "pis-3 pie-1 plb-1 mbe-1 font-medium";
2933
3213
  var SpaceManagerImpl = (props) => {
2934
3214
  const { active, space, createInvitationUrl, send, inviteActions: propsInviteActions, invitations, showInactiveInvitations, SpaceMemberList: SpaceMemberListComponent = SpaceMemberList, InvitationList: InvitationListComponent = InvitationList } = props;
2935
- const { t } = useTranslation20("os");
3215
+ const { t } = useTranslation23("os");
2936
3216
  const inviteActions = propsInviteActions ?? {
2937
3217
  noopInvite: {
2938
3218
  label: t("create space invitation label"),
@@ -2942,34 +3222,34 @@ var SpaceManagerImpl = (props) => {
2942
3222
  }
2943
3223
  }
2944
3224
  };
2945
- const [activeAction, setInternalActiveAction] = useState8(localStorage.getItem(activeActionKey) ?? "inviteOne");
3225
+ const [activeAction, setInternalActiveAction] = useState9(localStorage.getItem(activeActionKey) ?? "inviteOne");
2946
3226
  const setActiveAction = (nextAction) => {
2947
3227
  setInternalActiveAction(nextAction);
2948
3228
  localStorage.setItem(activeActionKey, nextAction);
2949
3229
  };
2950
3230
  const visibleInvitations = showInactiveInvitations ? invitations : invitations?.filter((invitation) => ![
2951
- Invitation7.State.CANCELLED
3231
+ Invitation8.State.CANCELLED
2952
3232
  ].includes(invitation.get().state));
2953
- return /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement(ScrollArea.Root, {
3233
+ return /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement(ScrollArea.Root, {
2954
3234
  classNames: "grow shrink basis-28 -mli-2"
2955
- }, /* @__PURE__ */ React35.createElement(ScrollArea.Viewport, {
3235
+ }, /* @__PURE__ */ React38.createElement(ScrollArea.Viewport, {
2956
3236
  classNames: "is-full pie-2"
2957
- }, !!visibleInvitations?.length && /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement("h3", {
2958
- className: mx21(headingFragment, descriptionText10)
2959
- }, t("invitation list heading")), /* @__PURE__ */ React35.createElement(InvitationListComponent, {
3237
+ }, !!visibleInvitations?.length && /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement("h3", {
3238
+ className: mx22(headingFragment, descriptionText10)
3239
+ }, t("invitation list heading")), /* @__PURE__ */ React38.createElement(InvitationListComponent, {
2960
3240
  className: "mb-2",
2961
3241
  send,
2962
3242
  invitations: visibleInvitations ?? [],
2963
3243
  onClickRemove: (invitation) => invitation.cancel(),
2964
3244
  createInvitationUrl
2965
- }), /* @__PURE__ */ React35.createElement("h3", {
2966
- className: mx21(headingFragment, descriptionText10, "mbs-2")
2967
- }, t("space member list heading"))), /* @__PURE__ */ React35.createElement(SpaceMemberListComponent, {
3245
+ }), /* @__PURE__ */ React38.createElement("h3", {
3246
+ className: mx22(headingFragment, descriptionText10, "mbs-2")
3247
+ }, t("space member list heading"))), /* @__PURE__ */ React38.createElement(SpaceMemberListComponent, {
2968
3248
  spaceKey: space.key,
2969
3249
  includeSelf: true
2970
- })), /* @__PURE__ */ React35.createElement(ScrollArea.Scrollbar, {
3250
+ })), /* @__PURE__ */ React38.createElement(ScrollArea.Scrollbar, {
2971
3251
  orientation: "vertical"
2972
- }, /* @__PURE__ */ React35.createElement(ScrollArea.Thumb, null))), /* @__PURE__ */ React35.createElement(Actions, null, /* @__PURE__ */ React35.createElement(BifurcatedAction, {
3252
+ }, /* @__PURE__ */ React38.createElement(ScrollArea.Thumb, null))), /* @__PURE__ */ React38.createElement(Actions, null, /* @__PURE__ */ React38.createElement(BifurcatedAction, {
2973
3253
  disabled: !active,
2974
3254
  actions: inviteActions,
2975
3255
  activeAction,
@@ -2979,47 +3259,48 @@ var SpaceManagerImpl = (props) => {
2979
3259
  };
2980
3260
 
2981
3261
  // packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx
2982
- var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx";
3262
+ var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx";
2983
3263
  var SpacePanelHeading = ({ titleId, space, onDone }) => {
2984
- const { t } = useTranslation21("os");
3264
+ const { t } = useTranslation24("os");
2985
3265
  const name = space.properties.name;
2986
- return /* @__PURE__ */ React36.createElement(Heading, {
3266
+ return /* @__PURE__ */ React39.createElement(Heading, {
2987
3267
  titleId,
2988
3268
  title: t("space panel heading"),
2989
- corner: /* @__PURE__ */ React36.createElement(CloseButton, {
3269
+ corner: /* @__PURE__ */ React39.createElement(CloseButton, {
2990
3270
  "data-testid": "identity-panel-done",
2991
3271
  onDone
2992
3272
  })
2993
- }, /* @__PURE__ */ React36.createElement("div", {
3273
+ }, /* @__PURE__ */ React39.createElement("div", {
2994
3274
  role: "none",
2995
3275
  className: "flex gap-4 items-center justify-center mlb-4"
2996
- }, /* @__PURE__ */ React36.createElement(Planet, {
3276
+ }, /* @__PURE__ */ React39.createElement(Planet, {
2997
3277
  size: 32
2998
- }), /* @__PURE__ */ React36.createElement("div", {
3278
+ }), /* @__PURE__ */ React39.createElement("div", {
2999
3279
  className: "block text-start font-light text-xl"
3000
3280
  }, name ?? space.key.truncate())));
3001
3281
  };
3002
3282
  var SpacePanelImpl = (props) => {
3003
- const { titleId, activeView, space, SpaceManager: SpaceManagerComponent = SpaceManager, InvitationManager: InvitationManagerComponent = InvitationManager, ...rest } = props;
3004
- return /* @__PURE__ */ React36.createElement(DensityProvider4, {
3283
+ const { titleId, activeView, space, target, SpaceManager: SpaceManagerComponent = SpaceManager, InvitationManager: InvitationManagerComponent = InvitationManager, ...rest } = props;
3284
+ return /* @__PURE__ */ React39.createElement(DensityProvider4, {
3005
3285
  density: "fine"
3006
- }, /* @__PURE__ */ React36.createElement(SpacePanelHeading, {
3286
+ }, /* @__PURE__ */ React39.createElement(SpacePanelHeading, {
3007
3287
  ...rest,
3008
3288
  titleId,
3009
3289
  space
3010
- }), /* @__PURE__ */ React36.createElement(Viewport.Root, {
3290
+ }), /* @__PURE__ */ React39.createElement(Viewport.Root, {
3011
3291
  activeView
3012
- }, /* @__PURE__ */ React36.createElement(Viewport.Views, null, /* @__PURE__ */ React36.createElement(Viewport.View, {
3292
+ }, /* @__PURE__ */ React39.createElement(Viewport.Views, null, /* @__PURE__ */ React39.createElement(Viewport.View, {
3013
3293
  id: "space manager",
3014
3294
  classNames: stepStyles
3015
- }, /* @__PURE__ */ React36.createElement(SpaceManagerComponent, {
3295
+ }, /* @__PURE__ */ React39.createElement(SpaceManagerComponent, {
3016
3296
  active: activeView === "space manager",
3017
3297
  space,
3298
+ target,
3018
3299
  ...rest
3019
- })), /* @__PURE__ */ React36.createElement(Viewport.View, {
3300
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
3020
3301
  id: "space invitation manager",
3021
3302
  classNames: stepStyles
3022
- }, /* @__PURE__ */ React36.createElement(InvitationManagerComponent, {
3303
+ }, /* @__PURE__ */ React39.createElement(InvitationManagerComponent, {
3023
3304
  active: activeView === "space invitation manager",
3024
3305
  ...rest,
3025
3306
  invitationUrl: props.invitationUrl
@@ -3027,7 +3308,7 @@ var SpacePanelImpl = (props) => {
3027
3308
  };
3028
3309
  var SpacePanelWithInvitationImpl = ({ invitation, ...props }) => {
3029
3310
  const invitationStatus = useInvitationStatus3(invitation);
3030
- return /* @__PURE__ */ React36.createElement(SpacePanelImpl, {
3311
+ return /* @__PURE__ */ React39.createElement(SpacePanelImpl, {
3031
3312
  ...props,
3032
3313
  ...invitationStatus,
3033
3314
  invitationUrl: props.createInvitationUrl(invitationStatus.invitationCode)
@@ -3040,11 +3321,11 @@ var SpacePanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => code,
3040
3321
  space: props.space
3041
3322
  }
3042
3323
  });
3043
- useEffect5(() => {
3324
+ useEffect6(() => {
3044
3325
  const subscription = spaceService.subscribe((state) => {
3045
3326
  log10("[state]", state, {
3046
- F: __dxlog_file10,
3047
- L: 92,
3327
+ F: __dxlog_file11,
3328
+ L: 94,
3048
3329
  S: void 0,
3049
3330
  C: (f, a) => f(...a)
3050
3331
  });
@@ -3072,62 +3353,65 @@ var SpacePanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => code,
3072
3353
  titleId,
3073
3354
  createInvitationUrl
3074
3355
  };
3075
- return spaceState.context.invitation ? /* @__PURE__ */ React36.createElement(SpacePanelWithInvitationImpl, {
3076
- ...implProps,
3077
- invitation: spaceState.context.invitation
3078
- }) : /* @__PURE__ */ React36.createElement(SpacePanelImpl, implProps);
3356
+ return spaceState.context.invitation ? (
3357
+ // TODO(wittjosiah): Unused? Remove?
3358
+ /* @__PURE__ */ React39.createElement(SpacePanelWithInvitationImpl, {
3359
+ ...implProps,
3360
+ invitation: spaceState.context.invitation
3361
+ })
3362
+ ) : /* @__PURE__ */ React39.createElement(SpacePanelImpl, implProps);
3079
3363
  };
3080
3364
 
3081
3365
  // packages/sdk/shell/src/composites/IdentityDialog/IdentityDialog.tsx
3082
3366
  var IdentityDialog = (props) => {
3083
3367
  const titleId = useId9("spaceDialog__title");
3084
- return /* @__PURE__ */ React37.createElement(Dialog.Root, {
3368
+ return /* @__PURE__ */ React40.createElement(Dialog.Root, {
3085
3369
  defaultOpen: true,
3086
3370
  onOpenChange: (open) => open || props.onDone?.()
3087
- }, /* @__PURE__ */ React37.createElement(Dialog.Portal, null, /* @__PURE__ */ React37.createElement(Dialog.Overlay, null, /* @__PURE__ */ React37.createElement(Dialog.Content, {
3371
+ }, /* @__PURE__ */ React40.createElement(Dialog.Portal, null, /* @__PURE__ */ React40.createElement(Dialog.Overlay, null, /* @__PURE__ */ React40.createElement(Dialog.Content, {
3088
3372
  "aria-labelledby": titleId,
3089
3373
  onOpenAutoFocus: (e) => e.preventDefault()
3090
- }, /* @__PURE__ */ React37.createElement(ClipboardProvider, null, /* @__PURE__ */ React37.createElement(IdentityPanel, {
3374
+ }, /* @__PURE__ */ React40.createElement(ClipboardProvider, null, /* @__PURE__ */ React40.createElement(IdentityPanel, {
3091
3375
  ...props,
3092
3376
  titleId,
3093
- doneActionParent: /* @__PURE__ */ React37.createElement(Dialog.Close, {
3377
+ doneActionParent: /* @__PURE__ */ React40.createElement(Dialog.Close, {
3094
3378
  asChild: true
3095
3379
  })
3096
3380
  }))))));
3097
3381
  };
3098
3382
 
3099
3383
  // packages/sdk/shell/src/composites/JoinDialog/JoinDialog.tsx
3100
- import React38 from "react";
3384
+ import React41 from "react";
3101
3385
  import { AlertDialog, useId as useId10, useVisualViewport } from "@dxos/react-ui";
3102
3386
  var JoinDialog = (joinPanelProps) => {
3103
3387
  const titleId = useId10("joinDialog__title");
3104
3388
  const { height } = useVisualViewport();
3105
- return /* @__PURE__ */ React38.createElement(AlertDialog.Root, {
3389
+ return /* @__PURE__ */ React41.createElement(AlertDialog.Root, {
3106
3390
  defaultOpen: true,
3107
3391
  onOpenChange: (open) => open || (joinPanelProps.onExit ? joinPanelProps.onExit() : joinPanelProps.onDone?.(null))
3108
- }, /* @__PURE__ */ React38.createElement(AlertDialog.Portal, null, /* @__PURE__ */ React38.createElement(AlertDialog.Overlay, {
3392
+ }, /* @__PURE__ */ React41.createElement(AlertDialog.Portal, null, /* @__PURE__ */ React41.createElement(AlertDialog.Overlay, {
3109
3393
  classNames: "backdrop-blur",
3110
3394
  ...height && {
3111
3395
  style: {
3112
3396
  blockSize: `${height}px`
3113
3397
  }
3114
3398
  }
3115
- }, /* @__PURE__ */ React38.createElement(AlertDialog.Content, {
3399
+ }, /* @__PURE__ */ React41.createElement(AlertDialog.Content, {
3116
3400
  "aria-labelledby": titleId
3117
- }, /* @__PURE__ */ React38.createElement(JoinPanel, {
3401
+ }, /* @__PURE__ */ React41.createElement(JoinPanel, {
3118
3402
  ...joinPanelProps,
3119
3403
  titleId,
3120
- exitActionParent: /* @__PURE__ */ React38.createElement(AlertDialog.Cancel, {
3404
+ exitActionParent: /* @__PURE__ */ React41.createElement(AlertDialog.Cancel, {
3121
3405
  asChild: true
3122
3406
  }),
3123
- doneActionParent: /* @__PURE__ */ React38.createElement(AlertDialog.Action, {
3407
+ doneActionParent: /* @__PURE__ */ React41.createElement(AlertDialog.Action, {
3124
3408
  asChild: true
3125
3409
  })
3126
3410
  })))));
3127
3411
  };
3128
3412
 
3129
3413
  // packages/sdk/shell/src/composites/Shell/run-shell.tsx
3130
- import React41, { StrictMode } from "react";
3414
+ import React44, { StrictMode } from "react";
3131
3415
  import { createRoot } from "react-dom/client";
3132
3416
  import { DEFAULT_CLIENT_CHANNEL, DEFAULT_SHELL_CHANNEL } from "@dxos/client-protocol";
3133
3417
  import { ShellRuntimeImpl } from "@dxos/client-services";
@@ -3137,49 +3421,51 @@ import { defaultTx } from "@dxos/react-ui-theme";
3137
3421
  import { createIFramePort } from "@dxos/rpc-tunnel";
3138
3422
 
3139
3423
  // packages/sdk/shell/src/composites/Shell/Shell.tsx
3140
- import React40, { useEffect as useEffect6, useState as useState9 } from "react";
3424
+ import React43, { useEffect as useEffect7, useState as useState10 } from "react";
3141
3425
  import { log as log11 } from "@dxos/log";
3142
- import { ShellDisplay, ShellLayout } from "@dxos/react-client";
3426
+ import { ShellDisplay, ShellLayout, useClient as useClient7 } from "@dxos/react-client";
3143
3427
  import { useSpace as useSpace2 } from "@dxos/react-client/echo";
3144
3428
 
3145
3429
  // packages/sdk/shell/src/composites/SpaceDialog/SpaceDialog.tsx
3146
- import React39 from "react";
3430
+ import React42 from "react";
3147
3431
  import { Dialog as Dialog2, useId as useId11 } from "@dxos/react-ui";
3148
3432
  var SpaceDialog = (spacePanelProps) => {
3149
3433
  const titleId = useId11("spaceDialog__title");
3150
- return /* @__PURE__ */ React39.createElement(Dialog2.Root, {
3434
+ return /* @__PURE__ */ React42.createElement(Dialog2.Root, {
3151
3435
  defaultOpen: true,
3152
3436
  onOpenChange: (open) => open || spacePanelProps.onDone?.()
3153
- }, /* @__PURE__ */ React39.createElement(Dialog2.Portal, null, /* @__PURE__ */ React39.createElement(Dialog2.Overlay, null, /* @__PURE__ */ React39.createElement(Dialog2.Content, {
3437
+ }, /* @__PURE__ */ React42.createElement(Dialog2.Portal, null, /* @__PURE__ */ React42.createElement(Dialog2.Overlay, null, /* @__PURE__ */ React42.createElement(Dialog2.Content, {
3154
3438
  "aria-labelledby": titleId
3155
- }, /* @__PURE__ */ React39.createElement(ClipboardProvider, null, /* @__PURE__ */ React39.createElement(SpacePanel, {
3439
+ }, /* @__PURE__ */ React42.createElement(ClipboardProvider, null, /* @__PURE__ */ React42.createElement(SpacePanel, {
3156
3440
  ...spacePanelProps,
3157
3441
  titleId,
3158
- doneActionParent: /* @__PURE__ */ React39.createElement(Dialog2.Close, {
3442
+ doneActionParent: /* @__PURE__ */ React42.createElement(Dialog2.Close, {
3159
3443
  asChild: true
3160
3444
  })
3161
3445
  }))))));
3162
3446
  };
3163
3447
 
3164
3448
  // packages/sdk/shell/src/composites/Shell/Shell.tsx
3165
- var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/composites/Shell/Shell.tsx";
3449
+ var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/composites/Shell/Shell.tsx";
3166
3450
  var Shell = ({ runtime, origin }) => {
3167
- const [{ layout, invitationCode, spaceKey }, setLayout] = useState9({
3451
+ const [{ layout, invitationCode, spaceKey, target }, setLayout] = useState10({
3168
3452
  layout: runtime.layout,
3169
3453
  invitationCode: runtime.invitationCode,
3170
- spaceKey: runtime.spaceKey
3454
+ spaceKey: runtime.spaceKey,
3455
+ target: runtime.target
3171
3456
  });
3457
+ const client = useClient7();
3172
3458
  const space = useSpace2(spaceKey);
3173
- useEffect6(() => {
3459
+ useEffect7(() => {
3174
3460
  return runtime.layoutUpdate.on((request) => setLayout(request));
3175
3461
  }, [
3176
3462
  runtime
3177
3463
  ]);
3178
- useEffect6(() => {
3464
+ useEffect7(() => {
3179
3465
  if (layout === ShellLayout.SPACE && !space) {
3180
3466
  log11.warn("No space found for shell space invitations.", void 0, {
3181
- F: __dxlog_file11,
3182
- L: 30,
3467
+ F: __dxlog_file12,
3468
+ L: 32,
3183
3469
  S: void 0,
3184
3470
  C: (f, a) => f(...a)
3185
3471
  });
@@ -3200,7 +3486,7 @@ var Shell = ({ runtime, origin }) => {
3200
3486
  ]);
3201
3487
  switch (layout) {
3202
3488
  case ShellLayout.INITIALIZE_IDENTITY:
3203
- return /* @__PURE__ */ React40.createElement(JoinDialog, {
3489
+ return /* @__PURE__ */ React43.createElement(JoinDialog, {
3204
3490
  mode: "halo-only",
3205
3491
  initialInvitationCode: invitationCode,
3206
3492
  onDone: () => {
@@ -3215,8 +3501,18 @@ var Shell = ({ runtime, origin }) => {
3215
3501
  case ShellLayout.IDENTITY:
3216
3502
  case ShellLayout.SHARE_IDENTITY:
3217
3503
  case ShellLayout.EDIT_PROFILE:
3218
- return /* @__PURE__ */ React40.createElement(IdentityDialog, {
3504
+ return /* @__PURE__ */ React43.createElement(IdentityDialog, {
3219
3505
  createInvitationUrl: (invitationCode2) => `${origin}?deviceInvitationCode=${invitationCode2}`,
3506
+ onResetDevice: async () => {
3507
+ await client.reset();
3508
+ await runtime.setAppContext({
3509
+ display: ShellDisplay.NONE,
3510
+ reload: true
3511
+ });
3512
+ },
3513
+ onJoinNewIdentity: () => runtime.setLayout({
3514
+ layout: ShellLayout.INITIALIZE_IDENTITY
3515
+ }),
3220
3516
  onDone: async () => {
3221
3517
  await runtime.setAppContext({
3222
3518
  display: ShellDisplay.NONE
@@ -3227,8 +3523,9 @@ var Shell = ({ runtime, origin }) => {
3227
3523
  }
3228
3524
  });
3229
3525
  case ShellLayout.SPACE:
3230
- return space ? /* @__PURE__ */ React40.createElement(SpaceDialog, {
3526
+ return space ? /* @__PURE__ */ React43.createElement(SpaceDialog, {
3231
3527
  space,
3528
+ target,
3232
3529
  createInvitationUrl: (invitationCode2) => `${origin}?spaceInvitationCode=${invitationCode2}`,
3233
3530
  onDone: async () => {
3234
3531
  await runtime.setAppContext({
@@ -3240,12 +3537,14 @@ var Shell = ({ runtime, origin }) => {
3240
3537
  }
3241
3538
  }) : null;
3242
3539
  case ShellLayout.JOIN_SPACE:
3243
- return /* @__PURE__ */ React40.createElement(JoinDialog, {
3540
+ return /* @__PURE__ */ React43.createElement(JoinDialog, {
3244
3541
  initialInvitationCode: invitationCode,
3245
3542
  onDone: async (result) => {
3543
+ const target2 = result?.target ?? void 0;
3246
3544
  await runtime.setAppContext({
3247
3545
  display: ShellDisplay.NONE,
3248
- spaceKey: result?.spaceKey ?? void 0
3546
+ spaceKey: result?.spaceKey ?? void 0,
3547
+ target: target2
3249
3548
  });
3250
3549
  runtime.setLayout({
3251
3550
  layout: ShellLayout.DEFAULT
@@ -3337,7 +3636,8 @@ var os = {
3337
3636
  "selecting identity heading": "Selecting identity",
3338
3637
  "devices heading": "Devices",
3339
3638
  "identity heading": "Profile settings",
3340
- "choose devices label": "Add device",
3639
+ "choose add device label": "Add device",
3640
+ "choose devices label": "Manage devices",
3341
3641
  "choose profile label": "Edit profile",
3342
3642
  "choose sign out label": "Sign out",
3343
3643
  "empty space members message": "There is nobody in this space yet.",
@@ -3364,7 +3664,12 @@ var os = {
3364
3664
  "confirm label": "Confirm",
3365
3665
  "reset identity input label": "This will clear this device and all associated data. Type {{confirmationValue}} and confirm to continue.",
3366
3666
  "failed to reset identity message": "Failed to reset identity.",
3367
- "confirmation value": "CONFIRM"
3667
+ "confirmation value": "CONFIRM",
3668
+ "sign out chooser title": "DANGER ZONE",
3669
+ "sign out chooser message": "Proceeding with either action below will erase all data on this device.",
3670
+ "join new identity label": "Join a new identity",
3671
+ "reset device label": "Reset device",
3672
+ "reset device confirm message": "Are you sure you want to reset your device? All data will be lost."
3368
3673
  };
3369
3674
 
3370
3675
  // packages/sdk/shell/src/translations/index.ts
@@ -3388,27 +3693,27 @@ var runShell = async (config = new Config()) => {
3388
3693
  runtime.open(),
3389
3694
  client.initialize()
3390
3695
  ]);
3391
- createRoot(document.getElementById("root")).render(/* @__PURE__ */ React41.createElement(StrictMode, null, /* @__PURE__ */ React41.createElement(ThemeProvider, {
3696
+ createRoot(document.getElementById("root")).render(/* @__PURE__ */ React44.createElement(StrictMode, null, /* @__PURE__ */ React44.createElement(ThemeProvider, {
3392
3697
  tx: defaultTx,
3393
3698
  resourceExtensions: [
3394
3699
  osTranslations
3395
3700
  ]
3396
- }, /* @__PURE__ */ React41.createElement(ClientContext.Provider, {
3701
+ }, /* @__PURE__ */ React44.createElement(ClientContext.Provider, {
3397
3702
  value: {
3398
3703
  client,
3399
3704
  status: SystemStatus.ACTIVE
3400
3705
  }
3401
- }, /* @__PURE__ */ React41.createElement(ClipboardProvider, null, /* @__PURE__ */ React41.createElement(Tooltip3.Provider, null, /* @__PURE__ */ React41.createElement(Shell, {
3706
+ }, /* @__PURE__ */ React44.createElement(ClipboardProvider, null, /* @__PURE__ */ React44.createElement(Tooltip3.Provider, null, /* @__PURE__ */ React44.createElement(Shell, {
3402
3707
  runtime,
3403
3708
  origin: location.origin
3404
3709
  })))))));
3405
3710
  };
3406
3711
 
3407
3712
  // packages/sdk/shell/src/composites/Shell/ShellContext.tsx
3408
- import React42, { createContext as createContext2, useCallback as useCallback8, useContext as useContext2, useEffect as useEffect7, useMemo as useMemo6, useState as useState10 } from "react";
3409
- import { ShellDisplay as ShellDisplay2, ShellLayout as ShellLayout3, useClient as useClient7 } from "@dxos/react-client";
3713
+ import React45, { createContext as createContext2, useCallback as useCallback9, useContext as useContext2, useEffect as useEffect8, useMemo as useMemo6, useState as useState11 } from "react";
3714
+ import { ShellDisplay as ShellDisplay2, ShellLayout as ShellLayout3, useClient as useClient8 } from "@dxos/react-client";
3410
3715
  import { useIdentity as useIdentity3 } from "@dxos/react-client/halo";
3411
- import { mx as mx22 } from "@dxos/react-ui-theme";
3716
+ import { mx as mx23 } from "@dxos/react-ui-theme";
3412
3717
 
3413
3718
  // packages/sdk/shell/src/composites/Shell/memory-shell-runtime.ts
3414
3719
  import { Event } from "@dxos/async";
@@ -3444,7 +3749,7 @@ var MemoryShellRuntime = class {
3444
3749
  // packages/sdk/shell/src/composites/Shell/ShellContext.tsx
3445
3750
  var ShellContext = /* @__PURE__ */ createContext2({});
3446
3751
  var useShell = () => {
3447
- const client = useClient7();
3752
+ const client = useClient8();
3448
3753
  const { runtime, setDisplay } = useContext2(ShellContext);
3449
3754
  const setLayout = async (layout, options) => {
3450
3755
  if (runtime) {
@@ -3465,9 +3770,9 @@ var useShell = () => {
3465
3770
  };
3466
3771
  };
3467
3772
  var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoinedSpace, children }) => {
3468
- const client = useClient7();
3773
+ const client = useClient8();
3469
3774
  const identity = useIdentity3();
3470
- const [display, setDisplay] = useState10(!identity || spaceInvitationCode || deviceInvitationCode ? ShellDisplay2.FULLSCREEN : ShellDisplay2.NONE);
3775
+ const [display, setDisplay] = useState11(!identity || spaceInvitationCode || deviceInvitationCode ? ShellDisplay2.FULLSCREEN : ShellDisplay2.NONE);
3471
3776
  const shellRuntime = useMemo6(() => {
3472
3777
  if (client.config.get("runtime.app.env.DX_VAULT") !== "false") {
3473
3778
  return;
@@ -3493,7 +3798,7 @@ var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoine
3493
3798
  spaceInvitationCode,
3494
3799
  deviceInvitationCode
3495
3800
  ]);
3496
- const handleKeyDown = useCallback8((event) => {
3801
+ const handleKeyDown = useCallback9((event) => {
3497
3802
  if (!space || !shellRuntime) {
3498
3803
  return;
3499
3804
  }
@@ -3514,7 +3819,7 @@ var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoine
3514
3819
  space,
3515
3820
  shellRuntime
3516
3821
  ]);
3517
- useEffect7(() => {
3822
+ useEffect8(() => {
3518
3823
  if (!shellRuntime) {
3519
3824
  return;
3520
3825
  }
@@ -3524,7 +3829,7 @@ var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoine
3524
3829
  shellRuntime,
3525
3830
  handleKeyDown
3526
3831
  ]);
3527
- useEffect7(() => {
3832
+ useEffect8(() => {
3528
3833
  if (!shellRuntime) {
3529
3834
  return;
3530
3835
  }
@@ -3537,12 +3842,12 @@ var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoine
3537
3842
  }, [
3538
3843
  shellRuntime
3539
3844
  ]);
3540
- return /* @__PURE__ */ React42.createElement(React42.Fragment, null, shellRuntime && /* @__PURE__ */ React42.createElement("div", {
3541
- className: mx22(display === ShellDisplay2.NONE ? "hidden" : "")
3542
- }, /* @__PURE__ */ React42.createElement(Shell, {
3845
+ return /* @__PURE__ */ React45.createElement(React45.Fragment, null, shellRuntime && /* @__PURE__ */ React45.createElement("div", {
3846
+ className: mx23(display === ShellDisplay2.NONE ? "hidden" : "")
3847
+ }, /* @__PURE__ */ React45.createElement(Shell, {
3543
3848
  runtime: shellRuntime,
3544
3849
  origin: window.location.origin
3545
- })), /* @__PURE__ */ React42.createElement(ShellContext.Provider, {
3850
+ })), /* @__PURE__ */ React45.createElement(ShellContext.Provider, {
3546
3851
  value: {
3547
3852
  runtime: shellRuntime,
3548
3853
  setDisplay