@dxos/shell 0.3.11-main.4feb9c9 → 0.3.11-main.5960564

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/bundle/shell.mjs +4715 -4670
  2. package/dist/bundle/shell.mjs.map +1 -1
  3. package/dist/bundle/shell.umd.js +51 -51
  4. package/dist/bundle/shell.umd.js.map +1 -1
  5. package/dist/bundle/style.css +1 -1
  6. package/dist/lib/browser/meta.json +1 -1
  7. package/dist/lib/browser/react.mjs +513 -443
  8. package/dist/lib/browser/react.mjs.map +4 -4
  9. package/dist/types/src/components/Panel/Action.js +1 -1
  10. package/dist/types/src/components/Panel/Action.js.map +1 -1
  11. package/dist/types/src/composites/Shell/Shell.d.ts.map +1 -1
  12. package/dist/types/src/composites/Shell/Shell.js +5 -1
  13. package/dist/types/src/composites/Shell/Shell.js.map +1 -1
  14. package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts.map +1 -1
  15. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js +5 -5
  16. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js.map +1 -1
  17. package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.d.ts +3 -1
  18. package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.d.ts.map +1 -1
  19. package/dist/types/src/panels/IdentityPanel/identityMachine.d.ts +1 -1
  20. package/dist/types/src/panels/IdentityPanel/identityMachine.d.ts.map +1 -1
  21. package/dist/types/src/panels/IdentityPanel/identityMachine.js +2 -2
  22. package/dist/types/src/panels/IdentityPanel/identityMachine.js.map +1 -1
  23. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.d.ts.map +1 -1
  24. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js +1 -1
  25. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js.map +1 -1
  26. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.d.ts +16 -0
  27. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.d.ts.map +1 -0
  28. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.js +40 -0
  29. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.js.map +1 -0
  30. package/dist/types/src/panels/IdentityPanel/steps/index.d.ts +2 -1
  31. package/dist/types/src/panels/IdentityPanel/steps/index.d.ts.map +1 -1
  32. package/dist/types/src/panels/IdentityPanel/steps/index.js +2 -1
  33. package/dist/types/src/panels/IdentityPanel/steps/index.js.map +1 -1
  34. package/dist/types/src/translations/locales/en-US.d.ts +5 -0
  35. package/dist/types/src/translations/locales/en-US.d.ts.map +1 -1
  36. package/dist/types/src/translations/locales/en-US.js +5 -0
  37. package/dist/types/src/translations/locales/en-US.js.map +1 -1
  38. package/package.json +18 -18
  39. package/src/components/Panel/Action.tsx +1 -1
  40. package/src/composites/Shell/Shell.tsx +7 -1
  41. package/src/panels/IdentityPanel/IdentityPanel.tsx +14 -7
  42. package/src/panels/IdentityPanel/IdentityPanelProps.ts +4 -1
  43. package/src/panels/IdentityPanel/identityMachine.ts +3 -3
  44. package/src/panels/IdentityPanel/steps/IdentityActionChooser.tsx +1 -6
  45. package/src/panels/IdentityPanel/steps/SignOutChooser.tsx +82 -0
  46. package/src/panels/IdentityPanel/steps/index.ts +2 -1
  47. package/src/translations/locales/en-US.ts +5 -0
@@ -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 React39 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 React26, { useEffect as useEffect3, 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 useClient4 } from "@dxos/react-client";
824
824
  import { useIdentity, useDevices } 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 useTranslation12 } 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";
@@ -871,7 +871,8 @@ var identityMachine = createMachine({
871
871
  actions: "log"
872
872
  }
873
873
  }
874
- }
874
+ },
875
+ signingOut: {}
875
876
  },
876
877
  on: {
877
878
  unchooseAction: {
@@ -903,6 +904,10 @@ var identityMachine = createMachine({
903
904
  target: ".managingProfile",
904
905
  actions: "log"
905
906
  },
907
+ chooseSignOut: {
908
+ target: ".signingOut",
909
+ actions: "log"
910
+ },
906
911
  chooseAgent: {
907
912
  target: ".managingAgent",
908
913
  actions: "log"
@@ -946,18 +951,147 @@ var useIdentityMachine = (client, options) => {
946
951
  });
947
952
  };
948
953
 
949
- // packages/sdk/shell/src/panels/IdentityPanel/steps/DeviceManager.tsx
950
- import React21 from "react";
954
+ // packages/sdk/shell/src/panels/IdentityPanel/steps/AgentPanel.tsx
955
+ import React21, { useState as useState3, useCallback as useCallback4, useEffect as useEffect2 } from "react";
956
+ import { invariant } from "@dxos/invariant";
957
+ import { useClient as useClient2, useAgentHostingProviderClient } from "@dxos/react-client";
958
+ import { useHaloInvitations } from "@dxos/react-client/halo";
959
+ import { Invitation as Invitation3, InvitationEncoder } from "@dxos/react-client/invitations";
951
960
  import { useTranslation as useTranslation7 } from "@dxos/react-ui";
952
- var DeviceManager = ({ devices, active, send }) => {
953
- const { t } = useTranslation7("os");
961
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/steps/AgentPanel.tsx";
962
+ var AgentForm = (props) => {
963
+ const { identity } = props;
964
+ const [validationMessage, setValidationMessage] = useState3("");
965
+ const [agentStatus, setAgentStatus] = useState3("");
966
+ const [agentActive, setAgentActive] = useState3(false);
967
+ const client = useClient2();
968
+ const invitations = useHaloInvitations();
969
+ const agentHostingProviderClient = useAgentHostingProviderClient(client.config);
970
+ useEffect2(() => {
971
+ const fetchAgentStatus = async () => {
972
+ if (agentHostingProviderClient) {
973
+ const agentStatus2 = await agentHostingProviderClient?.getAgent(identity?.identityKey.truncate() ?? "foo");
974
+ if (agentStatus2) {
975
+ setAgentActive(true);
976
+ setAgentStatus(agentStatus2);
977
+ } else {
978
+ setAgentActive(false);
979
+ setValidationMessage("No agent deployed via provider.");
980
+ }
981
+ } else {
982
+ setValidationMessage("No agent provider configured.");
983
+ }
984
+ };
985
+ void fetchAgentStatus();
986
+ }, []);
987
+ const onAgentCreateEvent = useCallback4(async (invitation) => {
988
+ const invitationCode = InvitationEncoder.encode(invitation);
989
+ if (invitation.state === Invitation3.State.CONNECTING) {
990
+ console.log(JSON.stringify({
991
+ invitationCode,
992
+ authCode: invitation.authCode
993
+ }));
994
+ invariant(identity, "Identity not found", {
995
+ F: __dxlog_file2,
996
+ L: 65,
997
+ S: void 0,
998
+ A: [
999
+ "identity",
1000
+ "'Identity not found'"
1001
+ ]
1002
+ });
1003
+ if (agentHostingProviderClient) {
1004
+ try {
1005
+ const res = await agentHostingProviderClient?.createAgent(invitationCode, identity.identityKey.truncate());
1006
+ setAgentStatus(res);
1007
+ setAgentActive(true);
1008
+ setValidationMessage("");
1009
+ } catch (err) {
1010
+ setValidationMessage(`error creating agent: ${err.message}`);
1011
+ }
1012
+ }
1013
+ }
1014
+ }, []);
1015
+ const handleAgentCreate = async () => {
1016
+ invitations.forEach((invitation2) => invitation2.cancel());
1017
+ const invitation = client.halo.share({
1018
+ type: Invitation3.Type.MULTIUSE,
1019
+ authMethod: Invitation3.AuthMethod.NONE
1020
+ });
1021
+ invitation.subscribe(onAgentCreateEvent);
1022
+ };
1023
+ const handleAgentDestroy = async () => {
1024
+ const identity2 = client.halo.identity.get();
1025
+ invariant(identity2, "Identity not found", {
1026
+ F: __dxlog_file2,
1027
+ L: 91,
1028
+ S: void 0,
1029
+ A: [
1030
+ "identity",
1031
+ "'Identity not found'"
1032
+ ]
1033
+ });
1034
+ try {
1035
+ await agentHostingProviderClient?.destroyAgent(identity2.identityKey.truncate());
1036
+ setValidationMessage("No agent deployed via provider.");
1037
+ setAgentStatus("");
1038
+ setAgentActive(false);
1039
+ } catch (err) {
1040
+ setValidationMessage(`error destroying agent: ${err.message}`);
1041
+ }
1042
+ };
1043
+ return /* @__PURE__ */ React21.createElement(AgentFormImpl, {
1044
+ ...props,
1045
+ onAgentCreate: handleAgentCreate,
1046
+ onAgentDestroy: handleAgentDestroy,
1047
+ validationMessage,
1048
+ agentStatus,
1049
+ agentActive,
1050
+ agentProviderDisabled: !agentHostingProviderClient
1051
+ });
1052
+ };
1053
+ var AgentFormImpl = (props) => {
1054
+ const { active, onAgentCreate, onAgentDestroy, send, validationMessage, agentStatus, agentActive, agentProviderDisabled } = props;
954
1055
  const disabled = !active;
1056
+ const { t } = useTranslation7("os");
955
1057
  return /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("div", {
1058
+ role: "none",
1059
+ className: "grow flex flex-col justify-center"
1060
+ }, /* @__PURE__ */ React21.createElement(Input, {
1061
+ validationMessage,
1062
+ label: /* @__PURE__ */ React21.createElement(StepHeading, null, "Agent Status"),
1063
+ disabled,
1064
+ "data-testid": "agent-status",
1065
+ value: agentStatus
1066
+ })), /* @__PURE__ */ React21.createElement(Actions, null, /* @__PURE__ */ React21.createElement(Action, {
1067
+ disabled: agentActive || agentProviderDisabled,
1068
+ onClick: () => onAgentCreate?.(),
1069
+ "data-testid": "create-agent"
1070
+ }, "Create Agent"), /* @__PURE__ */ React21.createElement(Action, {
1071
+ disabled: !agentActive || agentProviderDisabled,
1072
+ onClick: () => onAgentDestroy?.(),
1073
+ "data-testid": "destroy-agent"
1074
+ }, "Destroy Agent"), /* @__PURE__ */ React21.createElement(Action, {
1075
+ disabled,
1076
+ onClick: () => send?.({
1077
+ type: "unchooseAction"
1078
+ }),
1079
+ "data-testid": "update-profile-form-back"
1080
+ }, t("back label"))));
1081
+ };
1082
+
1083
+ // packages/sdk/shell/src/panels/IdentityPanel/steps/DeviceManager.tsx
1084
+ import React22 from "react";
1085
+ import { useTranslation as useTranslation8 } from "@dxos/react-ui";
1086
+ var DeviceManager = ({ devices, active, send }) => {
1087
+ const { t } = useTranslation8("os");
1088
+ const disabled = !active;
1089
+ return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("div", {
956
1090
  role: "none",
957
1091
  className: "grow"
958
- }, /* @__PURE__ */ React21.createElement(DeviceList, {
1092
+ }, /* @__PURE__ */ React22.createElement(DeviceList, {
959
1093
  devices
960
- })), /* @__PURE__ */ React21.createElement(Actions, null, /* @__PURE__ */ React21.createElement(Action, {
1094
+ })), /* @__PURE__ */ React22.createElement(Actions, null, /* @__PURE__ */ React22.createElement(Action, {
961
1095
  variant: "ghost",
962
1096
  disabled,
963
1097
  onClick: () => send?.({
@@ -969,19 +1103,19 @@ var DeviceManager = ({ devices, active, send }) => {
969
1103
 
970
1104
  // packages/sdk/shell/src/panels/IdentityPanel/steps/IdentityActionChooser.tsx
971
1105
  import { CaretRight, Devices, Plus, Power, UserGear, HardDrive } from "@phosphor-icons/react";
972
- import React22, { useCallback as useCallback4 } from "react";
973
- import { useClient as useClient2 } from "@dxos/react-client";
974
- import { useHaloInvitations } from "@dxos/react-client/halo";
975
- import { Invitation as Invitation3, InvitationEncoder } from "@dxos/react-client/invitations";
976
- import { DensityProvider, useTranslation as useTranslation8 } from "@dxos/react-ui";
1106
+ import React23, { useCallback as useCallback5 } from "react";
1107
+ import { useClient as useClient3 } from "@dxos/react-client";
1108
+ import { useHaloInvitations as useHaloInvitations2 } from "@dxos/react-client/halo";
1109
+ import { Invitation as Invitation4, InvitationEncoder as InvitationEncoder2 } from "@dxos/react-client/invitations";
1110
+ import { DensityProvider, useTranslation as useTranslation9 } from "@dxos/react-ui";
977
1111
  import { getSize as getSize6 } from "@dxos/react-ui-theme";
978
1112
  var IdentityActionChooser = (props) => {
979
1113
  const { send } = props;
980
- const client = useClient2();
981
- const invitations = useHaloInvitations();
982
- const onInvitationEvent = useCallback4((invitation) => {
983
- const invitationCode = InvitationEncoder.encode(invitation);
984
- if (invitation.state === Invitation3.State.CONNECTING) {
1114
+ const client = useClient3();
1115
+ const invitations = useHaloInvitations2();
1116
+ const onInvitationEvent = useCallback5((invitation) => {
1117
+ const invitationCode = InvitationEncoder2.encode(invitation);
1118
+ if (invitation.state === Invitation4.State.CONNECTING) {
985
1119
  console.log(JSON.stringify({
986
1120
  invitationCode,
987
1121
  authCode: invitation.authCode
@@ -992,8 +1126,8 @@ var IdentityActionChooser = (props) => {
992
1126
  const testing = e.altKey && e.shiftKey;
993
1127
  invitations.forEach((invitation2) => invitation2.cancel());
994
1128
  const invitation = client.halo.share(testing ? {
995
- type: Invitation3.Type.MULTIUSE,
996
- authMethod: Invitation3.AuthMethod.NONE
1129
+ type: Invitation4.Type.MULTIUSE,
1130
+ authMethod: Invitation4.AuthMethod.NONE
997
1131
  } : void 0);
998
1132
  if (true) {
999
1133
  invitation.subscribe(onInvitationEvent);
@@ -1003,100 +1137,100 @@ var IdentityActionChooser = (props) => {
1003
1137
  invitation
1004
1138
  });
1005
1139
  };
1006
- return /* @__PURE__ */ React22.createElement(IdentityActionChooserImpl, {
1140
+ return /* @__PURE__ */ React23.createElement(IdentityActionChooserImpl, {
1007
1141
  ...props,
1008
1142
  onCreateInvitationClick: (e) => createInvitation(e)
1009
1143
  });
1010
1144
  };
1011
1145
  var IdentityActionChooserImpl = ({ onCreateInvitationClick, active, send, onDone, doneActionParent }) => {
1012
- const { t } = useTranslation8("os");
1013
- return /* @__PURE__ */ React22.createElement("div", {
1146
+ const { t } = useTranslation9("os");
1147
+ return /* @__PURE__ */ React23.createElement("div", {
1014
1148
  role: "none",
1015
1149
  className: "grow flex flex-col gap-1"
1016
- }, /* @__PURE__ */ React22.createElement(DensityProvider, {
1150
+ }, /* @__PURE__ */ React23.createElement(DensityProvider, {
1017
1151
  density: "coarse"
1018
- }, /* @__PURE__ */ React22.createElement("div", {
1152
+ }, /* @__PURE__ */ React23.createElement("div", {
1019
1153
  className: "grow justify-center flex flex-col gap-1"
1020
- }, /* @__PURE__ */ React22.createElement(Action, {
1154
+ }, /* @__PURE__ */ React23.createElement(Action, {
1021
1155
  "data-testid": "manage-agent",
1022
1156
  onClick: () => send?.({
1023
1157
  type: "chooseAgent"
1024
1158
  }),
1025
1159
  classNames: "plb-4"
1026
- }, /* @__PURE__ */ React22.createElement(HardDrive, {
1160
+ }, /* @__PURE__ */ React23.createElement(HardDrive, {
1027
1161
  className: getSize6(6)
1028
- }), /* @__PURE__ */ React22.createElement("span", {
1162
+ }), /* @__PURE__ */ React23.createElement("span", {
1029
1163
  className: "grow mli-3"
1030
- }, "Manage Agent"), /* @__PURE__ */ React22.createElement(CaretRight, {
1164
+ }, "Manage Agent"), /* @__PURE__ */ React23.createElement(CaretRight, {
1031
1165
  weight: "bold",
1032
1166
  className: getSize6(4)
1033
- })), /* @__PURE__ */ React22.createElement(Action, {
1167
+ })), /* @__PURE__ */ React23.createElement(Action, {
1034
1168
  disabled: !active,
1035
1169
  "data-testid": "devices-panel.create-invitation",
1036
1170
  onClick: onCreateInvitationClick,
1037
1171
  classNames: "plb-4"
1038
- }, /* @__PURE__ */ React22.createElement(Plus, {
1172
+ }, /* @__PURE__ */ React23.createElement(Plus, {
1039
1173
  className: getSize6(6)
1040
- }), /* @__PURE__ */ React22.createElement("span", {
1174
+ }), /* @__PURE__ */ React23.createElement("span", {
1041
1175
  className: "grow mli-3"
1042
- }, t("choose add device label")), /* @__PURE__ */ React22.createElement(CaretRight, {
1176
+ }, t("choose add device label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1043
1177
  weight: "bold",
1044
1178
  className: getSize6(4)
1045
- })), /* @__PURE__ */ React22.createElement(Action, {
1179
+ })), /* @__PURE__ */ React23.createElement(Action, {
1046
1180
  "data-testid": "manage-devices",
1047
1181
  onClick: () => send?.({
1048
1182
  type: "chooseDevices"
1049
1183
  }),
1050
1184
  classNames: "plb-4"
1051
- }, /* @__PURE__ */ React22.createElement(Devices, {
1185
+ }, /* @__PURE__ */ React23.createElement(Devices, {
1052
1186
  className: getSize6(6)
1053
- }), /* @__PURE__ */ React22.createElement("span", {
1187
+ }), /* @__PURE__ */ React23.createElement("span", {
1054
1188
  className: "grow mli-3"
1055
- }, t("choose devices label")), /* @__PURE__ */ React22.createElement(CaretRight, {
1189
+ }, t("choose devices label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1056
1190
  weight: "bold",
1057
1191
  className: getSize6(4)
1058
- })), /* @__PURE__ */ React22.createElement(Action, {
1192
+ })), /* @__PURE__ */ React23.createElement(Action, {
1059
1193
  "data-testid": "manage-profile",
1060
1194
  onClick: () => send?.({
1061
1195
  type: "chooseProfile"
1062
1196
  }),
1063
1197
  classNames: "plb-4"
1064
- }, /* @__PURE__ */ React22.createElement(UserGear, {
1198
+ }, /* @__PURE__ */ React23.createElement(UserGear, {
1065
1199
  className: getSize6(6)
1066
- }), /* @__PURE__ */ React22.createElement("span", {
1200
+ }), /* @__PURE__ */ React23.createElement("span", {
1067
1201
  className: "grow mli-3"
1068
- }, t("choose profile label")), /* @__PURE__ */ React22.createElement(CaretRight, {
1202
+ }, t("choose profile label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1069
1203
  weight: "bold",
1070
1204
  className: getSize6(4)
1071
- })), /* @__PURE__ */ React22.createElement(Action, {
1072
- disabled: true,
1205
+ })), /* @__PURE__ */ React23.createElement(Action, {
1073
1206
  "data-testid": "sign-out",
1074
- onClick: () => {
1075
- },
1207
+ onClick: () => send?.({
1208
+ type: "chooseSignOut"
1209
+ }),
1076
1210
  classNames: "plb-4"
1077
- }, /* @__PURE__ */ React22.createElement(Power, {
1211
+ }, /* @__PURE__ */ React23.createElement(Power, {
1078
1212
  className: getSize6(6)
1079
- }), /* @__PURE__ */ React22.createElement("span", {
1213
+ }), /* @__PURE__ */ React23.createElement("span", {
1080
1214
  className: "grow mli-3"
1081
- }, t("choose sign out label")), /* @__PURE__ */ React22.createElement(CaretRight, {
1215
+ }, t("choose sign out label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1082
1216
  weight: "bold",
1083
1217
  className: getSize6(4)
1084
1218
  })))));
1085
1219
  };
1086
1220
 
1087
1221
  // packages/sdk/shell/src/panels/IdentityPanel/steps/ProfileForm.tsx
1088
- import React23, { useState as useState3 } from "react";
1222
+ import React24, { useState as useState4 } from "react";
1089
1223
  import { log as log2 } from "@dxos/log";
1090
- import { useTranslation as useTranslation9 } from "@dxos/react-ui";
1091
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/steps/ProfileForm.tsx";
1224
+ import { useTranslation as useTranslation10 } from "@dxos/react-ui";
1225
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/steps/ProfileForm.tsx";
1092
1226
  var ProfileForm = (props) => {
1093
1227
  const { onUpdateProfile } = props;
1094
- const { t } = useTranslation9("os");
1095
- const [validationMessage, setValidationMessage] = useState3("");
1228
+ const { t } = useTranslation10("os");
1229
+ const [validationMessage, setValidationMessage] = useState4("");
1096
1230
  const handleUpdateProfile = async (profile) => {
1097
1231
  await onUpdateProfile?.(profile).catch((error) => {
1098
1232
  log2.catch(error, void 0, {
1099
- F: __dxlog_file2,
1233
+ F: __dxlog_file3,
1100
1234
  L: 32,
1101
1235
  S: void 0,
1102
1236
  C: (f, a) => f(...a)
@@ -1104,7 +1238,7 @@ var ProfileForm = (props) => {
1104
1238
  setValidationMessage(t("failed to update profile message"));
1105
1239
  });
1106
1240
  };
1107
- return /* @__PURE__ */ React23.createElement(ProfileFormImpl, {
1241
+ return /* @__PURE__ */ React24.createElement(ProfileFormImpl, {
1108
1242
  ...props,
1109
1243
  onUpdateProfile: handleUpdateProfile,
1110
1244
  validationMessage
@@ -1113,14 +1247,14 @@ var ProfileForm = (props) => {
1113
1247
  var ProfileFormImpl = (props) => {
1114
1248
  const { active, profile, send, onUpdateProfile, validationMessage } = props;
1115
1249
  const disabled = !active;
1116
- const { t } = useTranslation9("os");
1117
- const [inputValue, setInputValue] = useState3(profile?.displayName ?? "");
1118
- return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement("div", {
1250
+ const { t } = useTranslation10("os");
1251
+ const [inputValue, setInputValue] = useState4(profile?.displayName ?? "");
1252
+ return /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement("div", {
1119
1253
  role: "none",
1120
1254
  className: "grow flex flex-col justify-center"
1121
- }, /* @__PURE__ */ React23.createElement(Input, {
1255
+ }, /* @__PURE__ */ React24.createElement(Input, {
1122
1256
  validationMessage,
1123
- label: /* @__PURE__ */ React23.createElement(StepHeading, null, t("display name input label")),
1257
+ label: /* @__PURE__ */ React24.createElement(StepHeading, null, t("display name input label")),
1124
1258
  disabled,
1125
1259
  "data-testid": "display-name-input",
1126
1260
  placeholder: t("display name input placeholder"),
@@ -1129,14 +1263,14 @@ var ProfileFormImpl = (props) => {
1129
1263
  onKeyDown: ({ key }) => key === "Enter" && onUpdateProfile?.({
1130
1264
  displayName: inputValue
1131
1265
  })
1132
- })), /* @__PURE__ */ React23.createElement(Actions, null, /* @__PURE__ */ React23.createElement(Action, {
1266
+ })), /* @__PURE__ */ React24.createElement(Actions, null, /* @__PURE__ */ React24.createElement(Action, {
1133
1267
  variant: "ghost",
1134
1268
  disabled,
1135
1269
  onClick: () => send?.({
1136
1270
  type: "unchooseAction"
1137
1271
  }),
1138
1272
  "data-testid": "update-profile-form-back"
1139
- }, t("back label")), /* @__PURE__ */ React23.createElement(Action, {
1273
+ }, t("back label")), /* @__PURE__ */ React24.createElement(Action, {
1140
1274
  variant: "primary",
1141
1275
  disabled,
1142
1276
  onClick: () => onUpdateProfile?.({
@@ -1146,150 +1280,67 @@ var ProfileFormImpl = (props) => {
1146
1280
  }, t("done label"))));
1147
1281
  };
1148
1282
 
1149
- // packages/sdk/shell/src/panels/IdentityPanel/steps/AgentPanel.tsx
1150
- import React24, { useState as useState4, useCallback as useCallback5, useEffect as useEffect2 } from "react";
1151
- import { invariant } from "@dxos/invariant";
1152
- import { useClient as useClient3, useAgentHostingProviderClient } from "@dxos/react-client";
1153
- import { useHaloInvitations as useHaloInvitations2 } from "@dxos/react-client/halo";
1154
- import { Invitation as Invitation4, InvitationEncoder as InvitationEncoder2 } from "@dxos/react-client/invitations";
1155
- import { useTranslation as useTranslation10 } from "@dxos/react-ui";
1156
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/steps/AgentPanel.tsx";
1157
- var AgentForm = (props) => {
1158
- const { identity } = props;
1159
- const [validationMessage, setValidationMessage] = useState4("");
1160
- const [agentStatus, setAgentStatus] = useState4("");
1161
- const [agentActive, setAgentActive] = useState4(false);
1162
- const client = useClient3();
1163
- const invitations = useHaloInvitations2();
1164
- const agentHostingProviderClient = useAgentHostingProviderClient(client.config);
1165
- useEffect2(() => {
1166
- const fetchAgentStatus = async () => {
1167
- if (agentHostingProviderClient) {
1168
- const agentStatus2 = await agentHostingProviderClient?.getAgent(identity?.identityKey.truncate() ?? "foo");
1169
- if (agentStatus2) {
1170
- setAgentActive(true);
1171
- setAgentStatus(agentStatus2);
1172
- } else {
1173
- setAgentActive(false);
1174
- setValidationMessage("No agent deployed via provider.");
1175
- }
1176
- } else {
1177
- setValidationMessage("No agent provider configured.");
1178
- }
1179
- };
1180
- void fetchAgentStatus();
1181
- }, []);
1182
- const onAgentCreateEvent = useCallback5(async (invitation) => {
1183
- const invitationCode = InvitationEncoder2.encode(invitation);
1184
- if (invitation.state === Invitation4.State.CONNECTING) {
1185
- console.log(JSON.stringify({
1186
- invitationCode,
1187
- authCode: invitation.authCode
1188
- }));
1189
- invariant(identity, "Identity not found", {
1190
- F: __dxlog_file3,
1191
- L: 65,
1192
- S: void 0,
1193
- A: [
1194
- "identity",
1195
- "'Identity not found'"
1196
- ]
1197
- });
1198
- if (agentHostingProviderClient) {
1199
- try {
1200
- const res = await agentHostingProviderClient?.createAgent(invitationCode, identity.identityKey.truncate());
1201
- setAgentStatus(res);
1202
- setAgentActive(true);
1203
- setValidationMessage("");
1204
- } catch (err) {
1205
- setValidationMessage(`error creating agent: ${err.message}`);
1206
- }
1207
- }
1208
- }
1209
- }, []);
1210
- const handleAgentCreate = async () => {
1211
- invitations.forEach((invitation2) => invitation2.cancel());
1212
- const invitation = client.halo.share({
1213
- type: Invitation4.Type.MULTIUSE,
1214
- authMethod: Invitation4.AuthMethod.NONE
1215
- });
1216
- invitation.subscribe(onAgentCreateEvent);
1217
- };
1218
- const handleAgentDestroy = async () => {
1219
- const identity2 = client.halo.identity.get();
1220
- invariant(identity2, "Identity not found", {
1221
- F: __dxlog_file3,
1222
- L: 91,
1223
- S: void 0,
1224
- A: [
1225
- "identity",
1226
- "'Identity not found'"
1227
- ]
1228
- });
1229
- try {
1230
- await agentHostingProviderClient?.destroyAgent(identity2.identityKey.truncate());
1231
- setValidationMessage("No agent deployed via provider.");
1232
- setAgentStatus("");
1233
- setAgentActive(false);
1234
- } catch (err) {
1235
- setValidationMessage(`error destroying agent: ${err.message}`);
1283
+ // packages/sdk/shell/src/panels/IdentityPanel/steps/SignOutChooser.tsx
1284
+ import { Warning } from "@phosphor-icons/react";
1285
+ import React25 from "react";
1286
+ import { Message, useTranslation as useTranslation11 } from "@dxos/react-ui";
1287
+ import { getSize as getSize7, mx as mx18 } from "@dxos/react-ui-theme";
1288
+ var SignOutChooser = (props) => {
1289
+ const { t } = useTranslation11("os");
1290
+ const onResetDevice = () => {
1291
+ if (window.confirm(t("reset device confirm message"))) {
1292
+ void props.onResetDevice?.();
1236
1293
  }
1237
1294
  };
1238
- return /* @__PURE__ */ React24.createElement(AgentFormImpl, {
1239
- ...props,
1240
- onAgentCreate: handleAgentCreate,
1241
- onAgentDestroy: handleAgentDestroy,
1242
- validationMessage,
1243
- agentStatus,
1244
- agentActive,
1245
- agentProviderDisabled: !agentHostingProviderClient
1295
+ return /* @__PURE__ */ React25.createElement(SignOutChooserImpl, {
1296
+ disabled: !props.active,
1297
+ onBack: () => props.send?.({
1298
+ type: "unchooseAction"
1299
+ }),
1300
+ onResetDevice,
1301
+ onJoinNewIdentity: props.onJoinNewIdentity
1246
1302
  });
1247
1303
  };
1248
- var AgentFormImpl = (props) => {
1249
- const { active, onAgentCreate, onAgentDestroy, send, validationMessage, agentStatus, agentActive, agentProviderDisabled } = props;
1250
- const disabled = !active;
1251
- const { t } = useTranslation10("os");
1252
- return /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement("div", {
1304
+ var SignOutChooserImpl = ({ disabled, onResetDevice, onJoinNewIdentity, onBack }) => {
1305
+ const { t } = useTranslation11("os");
1306
+ return /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement("div", {
1253
1307
  role: "none",
1254
1308
  className: "grow flex flex-col justify-center"
1255
- }, /* @__PURE__ */ React24.createElement(Input, {
1256
- validationMessage,
1257
- label: /* @__PURE__ */ React24.createElement(StepHeading, null, "Agent Status"),
1309
+ }, /* @__PURE__ */ React25.createElement(Message.Root, {
1310
+ valence: "error"
1311
+ }, /* @__PURE__ */ React25.createElement(Message.Title, null, /* @__PURE__ */ React25.createElement(Warning, {
1312
+ className: mx18(getSize7(6), "inline mie-2")
1313
+ }), 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, {
1258
1314
  disabled,
1259
- "data-testid": "agent-status",
1260
- value: agentStatus
1261
- })), /* @__PURE__ */ React24.createElement(Actions, null, /* @__PURE__ */ React24.createElement(Action, {
1262
- disabled: agentActive || agentProviderDisabled,
1263
- onClick: () => onAgentCreate?.(),
1264
- "data-testid": "create-agent"
1265
- }, "Create Agent"), /* @__PURE__ */ React24.createElement(Action, {
1266
- disabled: !agentActive || agentProviderDisabled,
1267
- onClick: () => onAgentDestroy?.(),
1268
- "data-testid": "destroy-agent"
1269
- }, "Destroy Agent"), /* @__PURE__ */ React24.createElement(Action, {
1315
+ onClick: onBack
1316
+ }, t("back label")), /* @__PURE__ */ React25.createElement(Action, {
1317
+ variant: "primary",
1318
+ classNames: "!bg-error-500 hover:!bg-error-550",
1270
1319
  disabled,
1271
- onClick: () => send?.({
1272
- type: "unchooseAction"
1273
- }),
1274
- "data-testid": "update-profile-form-back"
1275
- }, t("back label"))));
1320
+ onClick: onJoinNewIdentity
1321
+ }, t("join new identity label")), /* @__PURE__ */ React25.createElement(Action, {
1322
+ variant: "primary",
1323
+ classNames: "!bg-error-500 hover:!bg-error-550",
1324
+ disabled,
1325
+ onClick: onResetDevice
1326
+ }, t("reset device label"))));
1276
1327
  };
1277
1328
 
1278
1329
  // packages/sdk/shell/src/steps/InvitationManager.tsx
1279
1330
  import { Check as Check3, X as X3 } from "@phosphor-icons/react";
1280
- import React25, { useMemo as useMemo2 } from "react";
1331
+ import React26, { useMemo as useMemo2 } from "react";
1281
1332
  import { QR } from "react-qr-rounded";
1282
1333
  import { Invitation as Invitation5 } from "@dxos/react-client/invitations";
1283
- import { useId as useId4, useTranslation as useTranslation11 } from "@dxos/react-ui";
1284
- import { descriptionText as descriptionText7, getSize as getSize7, mx as mx18 } from "@dxos/react-ui-theme";
1334
+ import { useId as useId4, useTranslation as useTranslation12 } from "@dxos/react-ui";
1335
+ import { descriptionText as descriptionText7, getSize as getSize8, mx as mx19 } from "@dxos/react-ui-theme";
1285
1336
  var InvitationManagerView = ({ children, ...props }) => {
1286
- return /* @__PURE__ */ React25.createElement(Viewport.View, {
1337
+ return /* @__PURE__ */ React26.createElement(Viewport.View, {
1287
1338
  ...props,
1288
1339
  classNames: "grow flex flex-col justify-around items-center"
1289
1340
  }, children);
1290
1341
  };
1291
1342
  var InvitationManager = ({ invitationUrl, active, send, status, type, authCode, id }) => {
1292
- const { t } = useTranslation11("os");
1343
+ const { t } = useTranslation12("os");
1293
1344
  const qrLabel = useId4("invitation-manager__qr-code");
1294
1345
  const statusValue = type === Invitation5.Type.MULTIUSE ? 0 : invitationStatusValue.get(status) ?? 0;
1295
1346
  const showAuthCode = statusValue === 3;
@@ -1307,50 +1358,50 @@ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode,
1307
1358
  }, [
1308
1359
  statusValue
1309
1360
  ]);
1310
- return /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement(Viewport.Root, {
1361
+ return /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(Viewport.Root, {
1311
1362
  activeView,
1312
1363
  classNames: "grow plb-1"
1313
- }, /* @__PURE__ */ React25.createElement(Viewport.Views, null, /* @__PURE__ */ React25.createElement(InvitationManagerView, {
1364
+ }, /* @__PURE__ */ React26.createElement(Viewport.Views, null, /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1314
1365
  id: "showing qr",
1315
1366
  emoji: emoji2
1316
- }, /* @__PURE__ */ React25.createElement("p", {
1367
+ }, /* @__PURE__ */ React26.createElement("p", {
1317
1368
  className: "text-sm mlb-1 font-normal text-center"
1318
- }, t(type === Invitation5.Type.MULTIUSE ? "invite many qr label" : "invite one qr label")), /* @__PURE__ */ React25.createElement("div", {
1369
+ }, t(type === Invitation5.Type.MULTIUSE ? "invite many qr label" : "invite one qr label")), /* @__PURE__ */ React26.createElement("div", {
1319
1370
  role: "none",
1320
- className: mx18(descriptionText7, "is-full max-is-[14rem] relative")
1321
- }, /* @__PURE__ */ React25.createElement(QR, {
1371
+ className: mx19(descriptionText7, "is-full max-is-[14rem] relative")
1372
+ }, /* @__PURE__ */ React26.createElement(QR, {
1322
1373
  rounding: 100,
1323
1374
  backgroundColor: "transparent",
1324
1375
  color: "currentColor",
1325
- className: mx18("is-full bs-full p-2", showAuthCode && "invisible"),
1376
+ className: mx19("is-full bs-full p-2", showAuthCode && "invisible"),
1326
1377
  "aria-labelledby": qrLabel,
1327
1378
  errorCorrectionLevel: "Q",
1328
1379
  cutout: true
1329
- }, invitationUrl ?? "never"), /* @__PURE__ */ React25.createElement(Centered, null, /* @__PURE__ */ React25.createElement(Emoji, {
1380
+ }, invitationUrl ?? "never"), /* @__PURE__ */ React26.createElement(Centered, null, /* @__PURE__ */ React26.createElement(Emoji, {
1330
1381
  text: emoji2
1331
- }))), /* @__PURE__ */ React25.createElement("span", {
1382
+ }))), /* @__PURE__ */ React26.createElement("span", {
1332
1383
  id: qrLabel,
1333
1384
  className: "sr-only"
1334
- }, t("qr label")), /* @__PURE__ */ React25.createElement(CopyButton, {
1385
+ }, t("qr label")), /* @__PURE__ */ React26.createElement(CopyButton, {
1335
1386
  variant: "ghost",
1336
1387
  value: invitationUrl ?? "never"
1337
- })), /* @__PURE__ */ React25.createElement(InvitationManagerView, {
1388
+ })), /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1338
1389
  id: "showing auth code"
1339
- }, /* @__PURE__ */ React25.createElement(Label, null, t("auth code message")), /* @__PURE__ */ React25.createElement(AuthCode, {
1390
+ }, /* @__PURE__ */ React26.createElement(Label, null, t("auth code message")), /* @__PURE__ */ React26.createElement(AuthCode, {
1340
1391
  code: authCode,
1341
1392
  large: true,
1342
1393
  classNames: "text-black dark:text-white"
1343
- }), /* @__PURE__ */ React25.createElement(Label, null, "Be sure the other device is showing this symbol:"), emoji2 && /* @__PURE__ */ React25.createElement(Emoji, {
1394
+ }), /* @__PURE__ */ React26.createElement(Label, null, "Be sure the other device is showing this symbol:"), emoji2 && /* @__PURE__ */ React26.createElement(Emoji, {
1344
1395
  text: emoji2
1345
- })), /* @__PURE__ */ React25.createElement(InvitationManagerView, {
1396
+ })), /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1346
1397
  id: "showing final"
1347
- }, statusValue > 0 ? /* @__PURE__ */ React25.createElement(Check3, {
1348
- className: mx18("m-1.5", getSize7(6))
1349
- }) : /* @__PURE__ */ React25.createElement(X3, {
1350
- className: mx18("m-1.5", getSize7(6))
1351
- })))), /* @__PURE__ */ React25.createElement(Actions, {
1398
+ }, statusValue > 0 ? /* @__PURE__ */ React26.createElement(Check3, {
1399
+ className: mx19("m-1.5", getSize8(6))
1400
+ }) : /* @__PURE__ */ React26.createElement(X3, {
1401
+ className: mx19("m-1.5", getSize8(6))
1402
+ })))), /* @__PURE__ */ React26.createElement(Actions, {
1352
1403
  classNames: "mbs-4"
1353
- }, /* @__PURE__ */ React25.createElement(Action, {
1404
+ }, /* @__PURE__ */ React26.createElement(Action, {
1354
1405
  disabled: !active,
1355
1406
  onClick: () => send?.({
1356
1407
  type: "deselectInvitation"
@@ -1363,27 +1414,27 @@ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/I
1363
1414
  var viewStyles = "pbs-1 pbe-3 pli-3";
1364
1415
  var IdentityHeading = ({ titleId, title, identity, onDone }) => {
1365
1416
  const fallbackHref = useJdenticonHref3(identity.identityKey.toHex(), 12);
1366
- return /* @__PURE__ */ React26.createElement(Heading, {
1417
+ return /* @__PURE__ */ React27.createElement(Heading, {
1367
1418
  titleId,
1368
1419
  title,
1369
- corner: /* @__PURE__ */ React26.createElement(CloseButton, {
1420
+ corner: /* @__PURE__ */ React27.createElement(CloseButton, {
1370
1421
  onDone
1371
1422
  })
1372
- }, /* @__PURE__ */ React26.createElement(Avatar4.Root, {
1423
+ }, /* @__PURE__ */ React27.createElement(Avatar4.Root, {
1373
1424
  size: 12,
1374
1425
  variant: "circle",
1375
1426
  status: "active"
1376
- }, /* @__PURE__ */ React26.createElement(Avatar4.Frame, {
1427
+ }, /* @__PURE__ */ React27.createElement(Avatar4.Frame, {
1377
1428
  classNames: "block mbs-4 mbe-2 mli-auto chromatic-ignore"
1378
- }, /* @__PURE__ */ React26.createElement(Avatar4.Fallback, {
1429
+ }, /* @__PURE__ */ React27.createElement(Avatar4.Fallback, {
1379
1430
  href: fallbackHref
1380
- })), /* @__PURE__ */ React26.createElement(Avatar4.Label, {
1431
+ })), /* @__PURE__ */ React27.createElement(Avatar4.Label, {
1381
1432
  classNames: "block text-center font-light text-xl"
1382
1433
  }, identity.profile?.displayName ?? generateName2(identity.identityKey.toHex()))));
1383
1434
  };
1384
1435
  var IdentityPanelImpl = (props) => {
1385
- const { identity, titleId, activeView, onUpdateProfile, IdentityActionChooser: IdentityActionChooserComponent = IdentityActionChooser, InvitationManager: InvitationManagerComponent = InvitationManager, onDone, ...rest } = props;
1386
- const { t } = useTranslation12("os");
1436
+ const { identity, titleId, activeView, onUpdateProfile, onResetDevice, onJoinNewIdentity, IdentityActionChooser: IdentityActionChooserComponent = IdentityActionChooser, InvitationManager: InvitationManagerComponent = InvitationManager, onDone, ...rest } = props;
1437
+ const { t } = useTranslation13("os");
1387
1438
  const title = useMemo3(() => {
1388
1439
  switch (activeView) {
1389
1440
  case "agent manager":
@@ -1397,49 +1448,54 @@ var IdentityPanelImpl = (props) => {
1397
1448
  activeView,
1398
1449
  t
1399
1450
  ]);
1400
- console.log("[IdentityPanelImpl]", {
1401
- activeView
1402
- });
1403
- return /* @__PURE__ */ React26.createElement(DensityProvider2, {
1451
+ return /* @__PURE__ */ React27.createElement(DensityProvider2, {
1404
1452
  density: "fine"
1405
- }, /* @__PURE__ */ React26.createElement(IdentityHeading, {
1453
+ }, /* @__PURE__ */ React27.createElement(IdentityHeading, {
1406
1454
  identity,
1407
1455
  titleId,
1408
1456
  title,
1409
1457
  onDone
1410
- }), /* @__PURE__ */ React26.createElement(Viewport.Root, {
1458
+ }), /* @__PURE__ */ React27.createElement(Viewport.Root, {
1411
1459
  activeView
1412
- }, /* @__PURE__ */ React26.createElement(Viewport.Views, null, /* @__PURE__ */ React26.createElement(Viewport.View, {
1460
+ }, /* @__PURE__ */ React27.createElement(Viewport.Views, null, /* @__PURE__ */ React27.createElement(Viewport.View, {
1413
1461
  id: "identity action chooser",
1414
1462
  classNames: viewStyles
1415
- }, /* @__PURE__ */ React26.createElement(IdentityActionChooserComponent, {
1463
+ }, /* @__PURE__ */ React27.createElement(IdentityActionChooserComponent, {
1416
1464
  active: activeView === "identity action chooser",
1417
1465
  ...rest
1418
- })), /* @__PURE__ */ React26.createElement(Viewport.View, {
1466
+ })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1419
1467
  id: "device invitation manager",
1420
1468
  classNames: viewStyles
1421
- }, /* @__PURE__ */ React26.createElement(InvitationManagerComponent, {
1469
+ }, /* @__PURE__ */ React27.createElement(InvitationManagerComponent, {
1422
1470
  active: activeView === "device invitation manager",
1423
1471
  ...rest,
1424
1472
  invitationUrl: rest.createInvitationUrl(rest.invitationCode)
1425
- })), /* @__PURE__ */ React26.createElement(Viewport.View, {
1473
+ })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1426
1474
  id: "device manager",
1427
1475
  classNames: viewStyles
1428
- }, /* @__PURE__ */ React26.createElement(DeviceManager, {
1476
+ }, /* @__PURE__ */ React27.createElement(DeviceManager, {
1429
1477
  active: activeView === "device manager",
1430
1478
  ...rest
1431
- })), /* @__PURE__ */ React26.createElement(Viewport.View, {
1479
+ })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1432
1480
  classNames: viewStyles,
1433
1481
  id: "update profile form"
1434
- }, /* @__PURE__ */ React26.createElement(ProfileForm, {
1482
+ }, /* @__PURE__ */ React27.createElement(ProfileForm, {
1435
1483
  send: rest.send,
1436
1484
  active: activeView === "update profile form",
1437
1485
  profile: identity.profile,
1438
1486
  onUpdateProfile
1439
- })), /* @__PURE__ */ React26.createElement(Viewport.View, {
1487
+ })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1488
+ classNames: viewStyles,
1489
+ id: "signing out"
1490
+ }, /* @__PURE__ */ React27.createElement(SignOutChooser, {
1491
+ send: rest.send,
1492
+ active: activeView === "signing out",
1493
+ onResetDevice,
1494
+ onJoinNewIdentity
1495
+ })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1440
1496
  classNames: viewStyles,
1441
1497
  id: "agent manager"
1442
- }, /* @__PURE__ */ React26.createElement(AgentForm, {
1498
+ }, /* @__PURE__ */ React27.createElement(AgentForm, {
1443
1499
  send: rest.send,
1444
1500
  active: activeView === "agent manager",
1445
1501
  identity
@@ -1447,7 +1503,7 @@ var IdentityPanelImpl = (props) => {
1447
1503
  };
1448
1504
  var IdentityPanelWithInvitationImpl = ({ invitation, ...props }) => {
1449
1505
  const invitationStatus = useInvitationStatus2(invitation);
1450
- return /* @__PURE__ */ React26.createElement(IdentityPanelImpl, {
1506
+ return /* @__PURE__ */ React27.createElement(IdentityPanelImpl, {
1451
1507
  ...props,
1452
1508
  ...invitationStatus
1453
1509
  });
@@ -1466,7 +1522,7 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1466
1522
  const subscription = identityService.subscribe((state) => {
1467
1523
  log3("[state]", state, {
1468
1524
  F: __dxlog_file4,
1469
- L: 126,
1525
+ L: 135,
1470
1526
  S: void 0,
1471
1527
  C: (f, a) => f(...a)
1472
1528
  });
@@ -1492,6 +1548,8 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1492
1548
  }
1493
1549
  ].some(identityState.matches):
1494
1550
  return "update profile form";
1551
+ case identityState.matches("signingOut"):
1552
+ return "signing out";
1495
1553
  case [
1496
1554
  {
1497
1555
  managingAgent: "idle"
@@ -1507,10 +1565,6 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1507
1565
  }, [
1508
1566
  identityState
1509
1567
  ]);
1510
- console.log({
1511
- activeView,
1512
- identityState
1513
- });
1514
1568
  const onUpdateProfile = async (profile) => {
1515
1569
  identitySend({
1516
1570
  type: "updateProfile"
@@ -1527,14 +1581,14 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1527
1581
  createInvitationUrl,
1528
1582
  onUpdateProfile
1529
1583
  };
1530
- return identityState.context.invitation ? /* @__PURE__ */ React26.createElement(IdentityPanelWithInvitationImpl, {
1584
+ return identityState.context.invitation ? /* @__PURE__ */ React27.createElement(IdentityPanelWithInvitationImpl, {
1531
1585
  ...implProps,
1532
1586
  invitation: identityState.context.invitation
1533
- }) : /* @__PURE__ */ React26.createElement(IdentityPanelImpl, implProps);
1587
+ }) : /* @__PURE__ */ React27.createElement(IdentityPanelImpl, implProps);
1534
1588
  };
1535
1589
 
1536
1590
  // packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx
1537
- import React36, { useCallback as useCallback7, useEffect as useEffect5, useMemo as useMemo4 } from "react";
1591
+ import React37, { useCallback as useCallback7, useEffect as useEffect5, useMemo as useMemo4 } from "react";
1538
1592
  import { log as log8 } from "@dxos/log";
1539
1593
  import { useClient as useClient7, useMulticastObservable } from "@dxos/react-client";
1540
1594
  import { useIdentity as useIdentity2 } from "@dxos/react-client/halo";
@@ -1542,25 +1596,25 @@ import { DensityProvider as DensityProvider3, useId as useId7, useThemeContext a
1542
1596
 
1543
1597
  // packages/sdk/shell/src/panels/JoinPanel/JoinHeading.tsx
1544
1598
  import { X as X4 } from "@phosphor-icons/react";
1545
- import React27, { cloneElement, forwardRef as forwardRef8 } from "react";
1546
- import { Button as Button5, useTranslation as useTranslation13 } from "@dxos/react-ui";
1547
- import { descriptionText as descriptionText8, getSize as getSize8, mx as mx19 } from "@dxos/react-ui-theme";
1599
+ import React28, { cloneElement, forwardRef as forwardRef8 } from "react";
1600
+ import { Button as Button5, useTranslation as useTranslation14 } from "@dxos/react-ui";
1601
+ import { descriptionText as descriptionText8, getSize as getSize9, mx as mx20 } from "@dxos/react-ui-theme";
1548
1602
  var JoinHeading = /* @__PURE__ */ forwardRef8(({ mode, titleId, onExit, exitActionParent }, forwardedRef) => {
1549
- const { t } = useTranslation13("os");
1550
- const exitButton = /* @__PURE__ */ React27.createElement(Button5, {
1603
+ const { t } = useTranslation14("os");
1604
+ const exitButton = /* @__PURE__ */ React28.createElement(Button5, {
1551
1605
  variant: "ghost",
1552
1606
  ...onExit && {
1553
1607
  onClick: onExit
1554
1608
  },
1555
- classNames: mx19(descriptionText8, "plb-0 pli-2 absolute block-start-0 inline-end-0 z-[1]"),
1609
+ classNames: mx20(descriptionText8, "plb-0 pli-2 absolute block-start-0 inline-end-0 z-[1]"),
1556
1610
  "data-testid": "join-exit"
1557
- }, /* @__PURE__ */ React27.createElement(X4, {
1611
+ }, /* @__PURE__ */ React28.createElement(X4, {
1558
1612
  weight: "bold",
1559
- className: getSize8(4)
1560
- }), /* @__PURE__ */ React27.createElement("span", {
1613
+ className: getSize9(4)
1614
+ }), /* @__PURE__ */ React28.createElement("span", {
1561
1615
  className: "sr-only"
1562
1616
  }, t("exit label")));
1563
- return /* @__PURE__ */ React27.createElement(Heading, {
1617
+ return /* @__PURE__ */ React28.createElement(Heading, {
1564
1618
  ref: forwardedRef,
1565
1619
  titleId,
1566
1620
  title: t(mode === "halo-only" ? "selecting identity heading" : "joining space heading"),
@@ -2152,17 +2206,17 @@ var useJoinMachine = (client, options) => {
2152
2206
 
2153
2207
  // packages/sdk/shell/src/panels/JoinPanel/steps/AdditionMethodChooser.tsx
2154
2208
  import { CaretRight as CaretRight2, Plus as Plus2, QrCode, Textbox } from "@phosphor-icons/react";
2155
- import React28 from "react";
2156
- import { useTranslation as useTranslation14 } from "@dxos/react-ui";
2157
- import { getSize as getSize9 } from "@dxos/react-ui-theme";
2209
+ import React29 from "react";
2210
+ import { useTranslation as useTranslation15 } from "@dxos/react-ui";
2211
+ import { getSize as getSize10 } from "@dxos/react-ui-theme";
2158
2212
  var AdditionMethodChooser = (viewStateProps) => {
2159
2213
  const disabled = !viewStateProps.active;
2160
2214
  const { send } = viewStateProps;
2161
- const { t } = useTranslation14("os");
2215
+ const { t } = useTranslation15("os");
2162
2216
  const sharedButtonProps = {
2163
2217
  disabled,
2164
- after: /* @__PURE__ */ React28.createElement(CaretRight2, {
2165
- className: getSize9(4),
2218
+ after: /* @__PURE__ */ React29.createElement(CaretRight2, {
2219
+ className: getSize10(4),
2166
2220
  weight: "bold"
2167
2221
  }),
2168
2222
  slots: {
@@ -2171,37 +2225,37 @@ var AdditionMethodChooser = (viewStateProps) => {
2171
2225
  }
2172
2226
  }
2173
2227
  };
2174
- return /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(StepHeading, null, t("addition method chooser title")), /* @__PURE__ */ React28.createElement("div", {
2228
+ return /* @__PURE__ */ React29.createElement(React29.Fragment, null, /* @__PURE__ */ React29.createElement(StepHeading, null, t("addition method chooser title")), /* @__PURE__ */ React29.createElement("div", {
2175
2229
  role: "none",
2176
2230
  className: "flex flex-col gap-1 grow"
2177
- }, /* @__PURE__ */ React28.createElement(CompoundButton, {
2231
+ }, /* @__PURE__ */ React29.createElement(CompoundButton, {
2178
2232
  ...sharedButtonProps,
2179
2233
  description: t("create identity description"),
2180
- before: /* @__PURE__ */ React28.createElement(Plus2, {
2181
- className: getSize9(6)
2234
+ before: /* @__PURE__ */ React29.createElement(Plus2, {
2235
+ className: getSize10(6)
2182
2236
  }),
2183
2237
  onClick: () => send({
2184
2238
  type: "createIdentity"
2185
2239
  }),
2186
2240
  "data-autofocus": "choosingAuthMethod",
2187
2241
  "data-testid": "create-identity"
2188
- }, t("create identity label")), /* @__PURE__ */ React28.createElement(CompoundButton, {
2242
+ }, t("create identity label")), /* @__PURE__ */ React29.createElement(CompoundButton, {
2189
2243
  ...sharedButtonProps,
2190
2244
  description: t("join identity description"),
2191
- before: /* @__PURE__ */ React28.createElement(QrCode, {
2192
- className: getSize9(6)
2245
+ before: /* @__PURE__ */ React29.createElement(QrCode, {
2246
+ className: getSize10(6)
2193
2247
  }),
2194
2248
  onClick: () => send({
2195
2249
  type: "acceptHaloInvitation"
2196
2250
  }),
2197
2251
  "data-testid": "join-identity"
2198
- }, t("join identity label")), /* @__PURE__ */ React28.createElement(CompoundButton, {
2252
+ }, t("join identity label")), /* @__PURE__ */ React29.createElement(CompoundButton, {
2199
2253
  ...sharedButtonProps,
2200
2254
  // TODO(mykola): Implement recover.
2201
2255
  disabled: true,
2202
2256
  description: t("recover identity description"),
2203
- before: /* @__PURE__ */ React28.createElement(Textbox, {
2204
- className: getSize9(6)
2257
+ before: /* @__PURE__ */ React29.createElement(Textbox, {
2258
+ className: getSize10(6)
2205
2259
  }),
2206
2260
  onClick: () => send({
2207
2261
  type: "recoverIdentity"
@@ -2211,37 +2265,37 @@ var AdditionMethodChooser = (viewStateProps) => {
2211
2265
  };
2212
2266
 
2213
2267
  // packages/sdk/shell/src/panels/JoinPanel/steps/IdentityAdded.tsx
2214
- import React29, { cloneElement as cloneElement2 } from "react";
2268
+ import React30, { cloneElement as cloneElement2 } from "react";
2215
2269
  import { generateName as generateName3 } from "@dxos/display-name";
2216
- import { Avatar as Avatar5, useId as useId6, useJdenticonHref as useJdenticonHref4, useTranslation as useTranslation15 } from "@dxos/react-ui";
2217
- import { mx as mx20 } from "@dxos/react-ui-theme";
2270
+ import { Avatar as Avatar5, useId as useId6, useJdenticonHref as useJdenticonHref4, useTranslation as useTranslation16 } from "@dxos/react-ui";
2271
+ import { mx as mx21 } from "@dxos/react-ui-theme";
2218
2272
  var IdentityAdded = (props) => {
2219
2273
  const { mode, addedIdentity, active, send, onDone, doneActionParent } = props;
2220
2274
  const disabled = !active;
2221
- const { t } = useTranslation15("os");
2275
+ const { t } = useTranslation16("os");
2222
2276
  const fallbackValue = addedIdentity?.identityKey.toHex();
2223
2277
  const labelId = useId6("identityListItem__label");
2224
2278
  const jdenticon = useJdenticonHref4(fallbackValue ?? "", 12);
2225
2279
  const displayName = addedIdentity?.profile?.displayName ?? (addedIdentity && generateName3(addedIdentity?.identityKey.toHex()));
2226
- const doneAction = /* @__PURE__ */ React29.createElement(Action, {
2280
+ const doneAction = /* @__PURE__ */ React30.createElement(Action, {
2227
2281
  ...onDone && {
2228
2282
  onClick: () => onDone(null)
2229
2283
  },
2230
2284
  disabled,
2231
2285
  "data-autofocus": "confirmingAddedIdentity",
2232
2286
  "data-testid": "identity-added-done"
2233
- }, /* @__PURE__ */ React29.createElement("span", null, t("done label")));
2234
- return /* @__PURE__ */ React29.createElement(React29.Fragment, null, /* @__PURE__ */ React29.createElement(StepHeading, null, t("identity added label")), /* @__PURE__ */ React29.createElement("div", {
2287
+ }, /* @__PURE__ */ React30.createElement("span", null, t("done label")));
2288
+ return /* @__PURE__ */ React30.createElement(React30.Fragment, null, /* @__PURE__ */ React30.createElement(StepHeading, null, t("identity added label")), /* @__PURE__ */ React30.createElement("div", {
2235
2289
  role: "none",
2236
2290
  className: "grow flex flex-col items-center justify-center text-center gap-2"
2237
- }, /* @__PURE__ */ React29.createElement(Avatar5.Root, {
2291
+ }, /* @__PURE__ */ React30.createElement(Avatar5.Root, {
2238
2292
  status: "active",
2239
2293
  labelId
2240
- }, /* @__PURE__ */ React29.createElement(Avatar5.Frame, null, /* @__PURE__ */ React29.createElement(Avatar5.Fallback, {
2294
+ }, /* @__PURE__ */ React30.createElement(Avatar5.Frame, null, /* @__PURE__ */ React30.createElement(Avatar5.Fallback, {
2241
2295
  href: jdenticon
2242
- })), /* @__PURE__ */ React29.createElement(Avatar5.Label, {
2243
- classNames: mx20("text-lg truncate", !addedIdentity?.profile?.displayName && "font-mono")
2244
- }, displayName))), /* @__PURE__ */ React29.createElement(Actions, null, mode === "halo-only" ? doneActionParent ? /* @__PURE__ */ cloneElement2(doneActionParent, {}, doneAction) : doneAction : /* @__PURE__ */ React29.createElement(Action, {
2296
+ })), /* @__PURE__ */ React30.createElement(Avatar5.Label, {
2297
+ classNames: mx21("text-lg truncate", !addedIdentity?.profile?.displayName && "font-mono")
2298
+ }, displayName))), /* @__PURE__ */ React30.createElement(Actions, null, mode === "halo-only" ? doneActionParent ? /* @__PURE__ */ cloneElement2(doneActionParent, {}, doneAction) : doneAction : /* @__PURE__ */ React30.createElement(Action, {
2245
2299
  variant: "primary",
2246
2300
  disabled: disabled || !addedIdentity,
2247
2301
  onClick: () => addedIdentity && send({
@@ -2253,16 +2307,16 @@ var IdentityAdded = (props) => {
2253
2307
  };
2254
2308
 
2255
2309
  // packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx
2256
- import React30, { useState as useState5 } from "react";
2310
+ import React31, { useState as useState5 } from "react";
2257
2311
  import { log as log5 } from "@dxos/log";
2258
2312
  import { useClient as useClient5 } from "@dxos/react-client";
2259
- import { useTranslation as useTranslation16 } from "@dxos/react-ui";
2313
+ import { useTranslation as useTranslation17 } from "@dxos/react-ui";
2260
2314
  var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx";
2261
2315
  var IdentityInput = (props) => {
2262
2316
  const { send, method } = props;
2263
2317
  const isRecover = method === "recover identity";
2264
2318
  const client = useClient5();
2265
- const { t } = useTranslation16("os");
2319
+ const { t } = useTranslation17("os");
2266
2320
  const [validationMessage, setValidationMessage] = useState5("");
2267
2321
  const createIdentity = (displayName) => {
2268
2322
  void client.halo.createIdentity({
@@ -2282,7 +2336,7 @@ var IdentityInput = (props) => {
2282
2336
  setValidationMessage(t(isRecover ? "failed to recover identity message" : "failed to create identity message"));
2283
2337
  });
2284
2338
  };
2285
- return /* @__PURE__ */ React30.createElement(IdentityInputImpl, {
2339
+ return /* @__PURE__ */ React31.createElement(IdentityInputImpl, {
2286
2340
  ...props,
2287
2341
  onDisplayNameConfirm: createIdentity,
2288
2342
  validationMessage
@@ -2291,27 +2345,27 @@ var IdentityInput = (props) => {
2291
2345
  var IdentityInputImpl = (props) => {
2292
2346
  const { method, send, active, onDisplayNameConfirm, validationMessage } = props;
2293
2347
  const disabled = !active;
2294
- const { t } = useTranslation16("os");
2348
+ const { t } = useTranslation17("os");
2295
2349
  const [inputValue, setInputValue] = useState5("");
2296
2350
  const isRecover = method === "recover identity";
2297
- return /* @__PURE__ */ React30.createElement(React30.Fragment, null, /* @__PURE__ */ React30.createElement("div", {
2351
+ return /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement("div", {
2298
2352
  role: "none",
2299
2353
  className: "grow flex flex-col justify-center"
2300
- }, /* @__PURE__ */ React30.createElement(Input, {
2354
+ }, /* @__PURE__ */ React31.createElement(Input, {
2301
2355
  validationMessage,
2302
- label: /* @__PURE__ */ React30.createElement(StepHeading, null, t(isRecover ? "recover identity input label" : "new identity input label")),
2356
+ label: /* @__PURE__ */ React31.createElement(StepHeading, null, t(isRecover ? "recover identity input label" : "new identity input label")),
2303
2357
  disabled,
2304
2358
  "data-testid": "identity-input",
2305
2359
  placeholder: isRecover ? "Type your recovery phrase" : "Type a display name",
2306
2360
  onChange: ({ target: { value } }) => setInputValue(value)
2307
- })), /* @__PURE__ */ React30.createElement(Actions, null, /* @__PURE__ */ React30.createElement(Action, {
2361
+ })), /* @__PURE__ */ React31.createElement(Actions, null, /* @__PURE__ */ React31.createElement(Action, {
2308
2362
  variant: "ghost",
2309
2363
  disabled,
2310
2364
  onClick: () => send?.({
2311
2365
  type: "deselectAuthMethod"
2312
2366
  }),
2313
2367
  "data-testid": `${method === "recover identity" ? "recover" : "create"}-identity-input-back`
2314
- }, t("back label")), /* @__PURE__ */ React30.createElement(Action, {
2368
+ }, t("back label")), /* @__PURE__ */ React31.createElement(Action, {
2315
2369
  variant: "primary",
2316
2370
  disabled,
2317
2371
  onClick: () => onDisplayNameConfirm?.(inputValue),
@@ -2320,31 +2374,31 @@ var IdentityInputImpl = (props) => {
2320
2374
  };
2321
2375
 
2322
2376
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationAccepted.tsx
2323
- import React31, { cloneElement as cloneElement3 } from "react";
2324
- import { useTranslation as useTranslation17 } from "@dxos/react-ui";
2377
+ import React32, { cloneElement as cloneElement3 } from "react";
2378
+ import { useTranslation as useTranslation18 } from "@dxos/react-ui";
2325
2379
  var InvitationAccepted = (props) => {
2326
2380
  const { active, Kind, doneActionParent, onDone } = props;
2327
2381
  const disabled = !active;
2328
- const { t } = useTranslation17("os");
2329
- const doneAction = /* @__PURE__ */ React31.createElement(Action, {
2382
+ const { t } = useTranslation18("os");
2383
+ const doneAction = /* @__PURE__ */ React32.createElement(Action, {
2330
2384
  variant: "primary",
2331
2385
  onClick: onDone,
2332
2386
  disabled,
2333
2387
  "data-autofocus": `success${Kind}Invitation finishingJoining${Kind}`,
2334
2388
  "data-testid": `${Kind.toLowerCase()}-invitation-accepted-done`
2335
2389
  }, t("done label"));
2336
- return /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement("div", {
2390
+ return /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement("div", {
2337
2391
  role: "none",
2338
2392
  className: "grow flex flex-col justify-center"
2339
- }, /* @__PURE__ */ React31.createElement("p", {
2393
+ }, /* @__PURE__ */ React32.createElement("p", {
2340
2394
  className: "text-center text-sm font-normal"
2341
- }, t("welcome message"))), /* @__PURE__ */ React31.createElement(Actions, null, doneActionParent ? /* @__PURE__ */ cloneElement3(doneActionParent, {}, doneAction) : doneAction));
2395
+ }, t("welcome message"))), /* @__PURE__ */ React32.createElement(Actions, null, doneActionParent ? /* @__PURE__ */ cloneElement3(doneActionParent, {}, doneAction) : doneAction));
2342
2396
  };
2343
2397
 
2344
2398
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx
2345
- import React32, { useState as useState6, useEffect as useEffect4, cloneElement as cloneElement4 } from "react";
2399
+ import React33, { useState as useState6, useEffect as useEffect4, cloneElement as cloneElement4 } from "react";
2346
2400
  import { log as log6 } from "@dxos/log";
2347
- import { useTranslation as useTranslation18 } from "@dxos/react-ui";
2401
+ import { useTranslation as useTranslation19 } from "@dxos/react-ui";
2348
2402
  var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx";
2349
2403
  var invitationCodeFromUrl = (text) => {
2350
2404
  try {
@@ -2364,7 +2418,7 @@ var invitationCodeFromUrl = (text) => {
2364
2418
  var InvitationInput = (props) => {
2365
2419
  const { Kind, active, send, unredeemedCode, onExit, exitActionParent, onDone, doneActionParent, succeededKeys } = props;
2366
2420
  const disabled = !active;
2367
- const { t } = useTranslation18("os");
2421
+ const { t } = useTranslation19("os");
2368
2422
  const [inputValue, setInputValue] = useState6(unredeemedCode ?? "");
2369
2423
  useEffect4(() => {
2370
2424
  unredeemedCode && setInputValue(unredeemedCode ?? "");
@@ -2378,7 +2432,7 @@ var InvitationInput = (props) => {
2378
2432
  succeededKeys
2379
2433
  }
2380
2434
  });
2381
- const exitAction = /* @__PURE__ */ React32.createElement(Action, {
2435
+ const exitAction = /* @__PURE__ */ React33.createElement(Action, {
2382
2436
  variant: "ghost",
2383
2437
  disabled,
2384
2438
  ...onExit ? {
@@ -2388,11 +2442,11 @@ var InvitationInput = (props) => {
2388
2442
  },
2389
2443
  "data-testid": "join-exit"
2390
2444
  }, t("cancel label"));
2391
- return /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement("div", {
2445
+ return /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement("div", {
2392
2446
  role: "none",
2393
2447
  className: "grow flex flex-col justify-center"
2394
- }, /* @__PURE__ */ React32.createElement(Input, {
2395
- label: /* @__PURE__ */ React32.createElement(StepHeading, null, t("invitation input label")),
2448
+ }, /* @__PURE__ */ React33.createElement(Input, {
2449
+ label: /* @__PURE__ */ React33.createElement(StepHeading, null, t("invitation input label")),
2396
2450
  placeholder: "Type an invitation code",
2397
2451
  disabled,
2398
2452
  value: inputValue,
@@ -2400,14 +2454,14 @@ var InvitationInput = (props) => {
2400
2454
  "data-autofocus": `inputting${Kind}InvitationCode`,
2401
2455
  "data-testid": `${Kind.toLowerCase()}-invitation-input`,
2402
2456
  onKeyUp: ({ key }) => key === "Enter" && handleNext()
2403
- })), /* @__PURE__ */ React32.createElement(Actions, null, Kind === "Halo" ? /* @__PURE__ */ React32.createElement(Action, {
2457
+ })), /* @__PURE__ */ React33.createElement(Actions, null, Kind === "Halo" ? /* @__PURE__ */ React33.createElement(Action, {
2404
2458
  variant: "ghost",
2405
2459
  disabled,
2406
2460
  onClick: () => send({
2407
2461
  type: "deselectAuthMethod"
2408
2462
  }),
2409
2463
  "data-testid": `${Kind.toLowerCase()}-invitation-input-back`
2410
- }, t("back label")) : exitActionParent ? /* @__PURE__ */ cloneElement4(exitActionParent, {}, exitAction) : doneActionParent ? /* @__PURE__ */ cloneElement4(doneActionParent, {}, exitAction) : exitAction, /* @__PURE__ */ React32.createElement(Action, {
2464
+ }, t("back label")) : exitActionParent ? /* @__PURE__ */ cloneElement4(exitActionParent, {}, exitAction) : doneActionParent ? /* @__PURE__ */ cloneElement4(doneActionParent, {}, exitAction) : exitAction, /* @__PURE__ */ React33.createElement(Action, {
2411
2465
  variant: "primary",
2412
2466
  disabled,
2413
2467
  onClick: handleNext,
@@ -2416,8 +2470,8 @@ var InvitationInput = (props) => {
2416
2470
  };
2417
2471
 
2418
2472
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationRescuer.tsx
2419
- import React33 from "react";
2420
- import { useTranslation as useTranslation19 } from "@dxos/react-ui";
2473
+ import React34 from "react";
2474
+ import { useTranslation as useTranslation20 } from "@dxos/react-ui";
2421
2475
  import { descriptionText as descriptionText9 } from "@dxos/react-ui-theme";
2422
2476
  var InvitationActions = ({
2423
2477
  // `invitationState` does report correct state, but here we evaluate whether `failReason` is a better source of truth
@@ -2429,14 +2483,14 @@ var InvitationActions = ({
2429
2483
  Kind,
2430
2484
  failReason
2431
2485
  }) => {
2432
- const { t } = useTranslation19("os");
2486
+ const { t } = useTranslation20("os");
2433
2487
  if (failReason) {
2434
- return /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement(StepHeading, {
2488
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement(StepHeading, {
2435
2489
  className: descriptionText9
2436
- }, t(failReason === "timeout" ? "timeout status label" : failReason === "cancelled" ? "cancelled status label" : "error status label")), /* @__PURE__ */ React33.createElement("div", {
2490
+ }, t(failReason === "timeout" ? "timeout status label" : failReason === "cancelled" ? "cancelled status label" : "error status label")), /* @__PURE__ */ React34.createElement("div", {
2437
2491
  role: "none",
2438
2492
  className: "grow"
2439
- }), /* @__PURE__ */ React33.createElement(Actions, null, /* @__PURE__ */ React33.createElement(Action, {
2493
+ }), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2440
2494
  disabled: !active,
2441
2495
  onClick: () => send({
2442
2496
  type: `reset${Kind}Invitation`
@@ -2444,16 +2498,16 @@ var InvitationActions = ({
2444
2498
  "data-testid": "invitation-rescuer-reset"
2445
2499
  }, t("reset label"))));
2446
2500
  } else {
2447
- return /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement(StepHeading, {
2501
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement(StepHeading, {
2448
2502
  className: descriptionText9
2449
- }, t("connecting status label")), /* @__PURE__ */ React33.createElement("div", {
2503
+ }, t("connecting status label")), /* @__PURE__ */ React34.createElement("div", {
2450
2504
  role: "none",
2451
2505
  className: "grow"
2452
- }), /* @__PURE__ */ React33.createElement(Actions, null, /* @__PURE__ */ React33.createElement(Action, {
2506
+ }), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2453
2507
  disabled: true,
2454
2508
  classNames: "order-2",
2455
2509
  "data-testid": "next"
2456
- }, t("next label")), /* @__PURE__ */ React33.createElement(Action, {
2510
+ }, t("next label")), /* @__PURE__ */ React34.createElement(Action, {
2457
2511
  disabled: !active,
2458
2512
  onClick: onInvitationCancel,
2459
2513
  "data-testid": "invitation-rescuer-cancel"
@@ -2462,28 +2516,28 @@ var InvitationActions = ({
2462
2516
  };
2463
2517
  var InvitationRescuer = (props) => {
2464
2518
  const { Kind, invitationState, active, send } = props;
2465
- const { t } = useTranslation19("os");
2466
- return /* @__PURE__ */ React33.createElement(React33.Fragment, null, typeof invitationState === "undefined" ? /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement("div", {
2519
+ const { t } = useTranslation20("os");
2520
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, typeof invitationState === "undefined" ? /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement("div", {
2467
2521
  role: "none",
2468
2522
  className: "grow flex flex-col justify-center"
2469
- }, /* @__PURE__ */ React33.createElement(StepHeading, {
2523
+ }, /* @__PURE__ */ React34.createElement(StepHeading, {
2470
2524
  className: descriptionText9
2471
- }, "There was a problem joining the space")), /* @__PURE__ */ React33.createElement(Actions, null, /* @__PURE__ */ React33.createElement(Action, {
2525
+ }, "There was a problem joining the space")), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2472
2526
  disabled: !active,
2473
2527
  "data-testid": "invitation-rescuer-blank-reset",
2474
2528
  onClick: () => send({
2475
2529
  type: `reset${Kind}Invitation`
2476
2530
  })
2477
- }, t("reset label")))) : /* @__PURE__ */ React33.createElement(InvitationActions, props));
2531
+ }, t("reset label")))) : /* @__PURE__ */ React34.createElement(InvitationActions, props));
2478
2532
  };
2479
2533
 
2480
2534
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationAuthenticator.tsx
2481
- import React34, { useState as useState7 } from "react";
2482
- import { Input as Input2, useTranslation as useTranslation20 } from "@dxos/react-ui";
2535
+ import React35, { useState as useState7 } from "react";
2536
+ import { Input as Input2, useTranslation as useTranslation21 } from "@dxos/react-ui";
2483
2537
  var pinLength = 6;
2484
2538
  var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, onInvitationAuthenticate, onInvitationCancel }) => {
2485
2539
  const disabled = !active || pending;
2486
- const { t } = useTranslation20("os");
2540
+ const { t } = useTranslation21("os");
2487
2541
  const invitationType = Kind.toLowerCase();
2488
2542
  const [authCode, setAuthCode] = useState7("");
2489
2543
  const onChange = ({ target: { value } }) => {
@@ -2492,16 +2546,16 @@ var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, on
2492
2546
  document.querySelector(`[data-autofocus-pinlength="${invitationType}"]`)?.focus();
2493
2547
  }
2494
2548
  };
2495
- return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement("div", {
2549
+ return /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement("div", {
2496
2550
  role: "none",
2497
2551
  className: "grow flex flex-col justify-center"
2498
- }, invitationId && /* @__PURE__ */ React34.createElement(Emoji, {
2552
+ }, invitationId && /* @__PURE__ */ React35.createElement(Emoji, {
2499
2553
  text: toEmoji(invitationId)
2500
- }), /* @__PURE__ */ React34.createElement(Input2.Root, failed && {
2554
+ }), /* @__PURE__ */ React35.createElement(Input2.Root, failed && {
2501
2555
  validationValence: "error"
2502
- }, /* @__PURE__ */ React34.createElement(Input2.Label, {
2556
+ }, /* @__PURE__ */ React35.createElement(Input2.Label, {
2503
2557
  asChild: true
2504
- }, /* @__PURE__ */ React34.createElement(StepHeading, null, t("auth code input label"))), /* @__PURE__ */ React34.createElement(Input2.PinInput, {
2558
+ }, /* @__PURE__ */ React35.createElement(StepHeading, null, t("auth code input label"))), /* @__PURE__ */ React35.createElement(Input2.PinInput, {
2505
2559
  disabled,
2506
2560
  length: pinLength,
2507
2561
  onChange,
@@ -2512,14 +2566,14 @@ var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, on
2512
2566
  "data-prevent-ios-autofocus": true,
2513
2567
  "data-testid": `${invitationType}-auth-code-input`,
2514
2568
  "data-1p-ignore": true
2515
- }), failed && /* @__PURE__ */ React34.createElement(Input2.DescriptionAndValidation, {
2569
+ }), failed && /* @__PURE__ */ React35.createElement(Input2.DescriptionAndValidation, {
2516
2570
  classNames: "text-center"
2517
- }, /* @__PURE__ */ React34.createElement(Input2.Validation, null, t("failed to authenticate message"))))), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2571
+ }, /* @__PURE__ */ React35.createElement(Input2.Validation, null, t("failed to authenticate message"))))), /* @__PURE__ */ React35.createElement(Actions, null, /* @__PURE__ */ React35.createElement(Action, {
2518
2572
  variant: "ghost",
2519
2573
  disabled,
2520
2574
  onClick: () => onInvitationCancel?.(),
2521
2575
  "data-testid": `${invitationType}-invitation-authenticator-cancel`
2522
- }, t("cancel label")), /* @__PURE__ */ React34.createElement(Action, {
2576
+ }, t("cancel label")), /* @__PURE__ */ React35.createElement(Action, {
2523
2577
  variant: "primary",
2524
2578
  disabled,
2525
2579
  onClick: () => onInvitationAuthenticate?.(authCode),
@@ -2529,14 +2583,14 @@ var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, on
2529
2583
  };
2530
2584
 
2531
2585
  // packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx
2532
- import React35, { useState as useState8 } from "react";
2586
+ import React36, { useState as useState8 } from "react";
2533
2587
  import { log as log7 } from "@dxos/log";
2534
2588
  import { useClient as useClient6 } from "@dxos/react-client";
2535
- import { useTranslation as useTranslation21 } from "@dxos/react-ui";
2589
+ import { useTranslation as useTranslation22 } from "@dxos/react-ui";
2536
2590
  var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx";
2537
2591
  var ResetIdentity = ({ send, active }) => {
2538
2592
  const client = useClient6();
2539
- const { t } = useTranslation21("os");
2593
+ const { t } = useTranslation22("os");
2540
2594
  const [validationMessage, setValidationMessage] = useState8("");
2541
2595
  const resetIdentity = () => {
2542
2596
  void client.reset().then(() => send?.({
@@ -2551,29 +2605,29 @@ var ResetIdentity = ({ send, active }) => {
2551
2605
  setValidationMessage(t("failed to reset identity message"));
2552
2606
  });
2553
2607
  };
2554
- return /* @__PURE__ */ React35.createElement(ResetIdentityImpl, {
2608
+ return /* @__PURE__ */ React36.createElement(ResetIdentityImpl, {
2555
2609
  disabled: !active,
2556
2610
  validationMessage,
2557
2611
  onConfirm: () => resetIdentity()
2558
2612
  });
2559
2613
  };
2560
2614
  var ResetIdentityImpl = ({ disabled, validationMessage, onConfirm }) => {
2561
- const { t } = useTranslation21("os");
2615
+ const { t } = useTranslation22("os");
2562
2616
  const confirmationValue = t("confirmation value");
2563
2617
  const [inputValue, setInputValue] = useState8("");
2564
- return /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement("div", {
2618
+ return /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement("div", {
2565
2619
  role: "none",
2566
2620
  className: "grow flex flex-col justify-center"
2567
- }, /* @__PURE__ */ React35.createElement(Input, {
2621
+ }, /* @__PURE__ */ React36.createElement(Input, {
2568
2622
  validationMessage,
2569
- label: /* @__PURE__ */ React35.createElement(StepHeading, null, t("reset identity input label", {
2623
+ label: /* @__PURE__ */ React36.createElement(StepHeading, null, t("reset identity input label", {
2570
2624
  confirmationValue
2571
2625
  })),
2572
2626
  disabled,
2573
2627
  "data-testid": "identity-input",
2574
2628
  placeholder: confirmationValue,
2575
2629
  onChange: ({ target: { value } }) => setInputValue(value)
2576
- })), /* @__PURE__ */ React35.createElement(Actions, null, /* @__PURE__ */ React35.createElement(Action, {
2630
+ })), /* @__PURE__ */ React36.createElement(Actions, null, /* @__PURE__ */ React36.createElement(Action, {
2577
2631
  // TODO(wittjosiah): Probably make this red?
2578
2632
  variant: "primary",
2579
2633
  disabled: disabled || inputValue !== confirmationValue,
@@ -2610,47 +2664,47 @@ var resolvedTextColor = (status) => status === Invitation7.State.ERROR ? errorTe
2610
2664
  var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx";
2611
2665
  var JoinPanelImpl = (props) => {
2612
2666
  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;
2613
- return /* @__PURE__ */ React36.createElement(DensityProvider3, {
2667
+ return /* @__PURE__ */ React37.createElement(DensityProvider3, {
2614
2668
  density: "fine"
2615
- }, mode !== "halo-only" && /* @__PURE__ */ React36.createElement(JoinHeading, {
2669
+ }, mode !== "halo-only" && /* @__PURE__ */ React37.createElement(JoinHeading, {
2616
2670
  titleId,
2617
2671
  mode,
2618
2672
  onExit,
2619
2673
  exitActionParent
2620
- }), /* @__PURE__ */ React36.createElement(Viewport.Root, {
2674
+ }), /* @__PURE__ */ React37.createElement(Viewport.Root, {
2621
2675
  focusManaged: true,
2622
2676
  activeView
2623
- }, /* @__PURE__ */ React36.createElement(Viewport.Views, null, /* @__PURE__ */ React36.createElement(Viewport.View, {
2677
+ }, /* @__PURE__ */ React37.createElement(Viewport.Views, null, /* @__PURE__ */ React37.createElement(Viewport.View, {
2624
2678
  classNames: stepStyles,
2625
2679
  id: "addition method chooser"
2626
- }, /* @__PURE__ */ React36.createElement(AdditionMethodChooser, {
2680
+ }, /* @__PURE__ */ React37.createElement(AdditionMethodChooser, {
2627
2681
  send,
2628
2682
  active: activeView === "addition method chooser"
2629
- })), /* @__PURE__ */ React36.createElement(Viewport.View, {
2683
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2630
2684
  classNames: stepStyles,
2631
2685
  id: "reset identity confirmation"
2632
- }, /* @__PURE__ */ React36.createElement(ResetIdentityComponent, {
2686
+ }, /* @__PURE__ */ React37.createElement(ResetIdentityComponent, {
2633
2687
  send,
2634
2688
  method: "reset identity",
2635
2689
  active: activeView === "reset identity confirmation"
2636
- })), /* @__PURE__ */ React36.createElement(Viewport.View, {
2690
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2637
2691
  classNames: stepStyles,
2638
2692
  id: "create identity input"
2639
- }, /* @__PURE__ */ React36.createElement(IdentityInputComponent, {
2693
+ }, /* @__PURE__ */ React37.createElement(IdentityInputComponent, {
2640
2694
  send,
2641
2695
  method: "create identity",
2642
2696
  active: activeView === "create identity input"
2643
- })), /* @__PURE__ */ React36.createElement(Viewport.View, {
2697
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2644
2698
  classNames: stepStyles,
2645
2699
  id: "recover identity input"
2646
- }, /* @__PURE__ */ React36.createElement(IdentityInputComponent, {
2700
+ }, /* @__PURE__ */ React37.createElement(IdentityInputComponent, {
2647
2701
  send,
2648
2702
  method: "recover identity",
2649
2703
  active: activeView === "recover identity input"
2650
- })), /* @__PURE__ */ React36.createElement(Viewport.View, {
2704
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2651
2705
  classNames: stepStyles,
2652
2706
  id: "halo invitation input"
2653
- }, /* @__PURE__ */ React36.createElement(InvitationInput, {
2707
+ }, /* @__PURE__ */ React37.createElement(InvitationInput, {
2654
2708
  send,
2655
2709
  Kind: "Halo",
2656
2710
  active: activeView === "halo invitation input",
@@ -2660,20 +2714,20 @@ var JoinPanelImpl = (props) => {
2660
2714
  ...succeededKeys?.Halo && {
2661
2715
  succeededKeys: succeededKeys.Halo
2662
2716
  }
2663
- })), /* @__PURE__ */ React36.createElement(Viewport.View, {
2717
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2664
2718
  classNames: stepStyles,
2665
2719
  id: "halo invitation rescuer"
2666
- }, /* @__PURE__ */ React36.createElement(InvitationRescuer, {
2720
+ }, /* @__PURE__ */ React37.createElement(InvitationRescuer, {
2667
2721
  send,
2668
2722
  Kind: "Halo",
2669
2723
  active: activeView === "halo invitation rescuer",
2670
2724
  invitationState: invitationStates?.Halo,
2671
2725
  onInvitationCancel: onHaloInvitationCancel,
2672
2726
  failReason: failReasons?.Halo
2673
- })), /* @__PURE__ */ React36.createElement(Viewport.View, {
2727
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2674
2728
  classNames: stepStyles,
2675
2729
  id: "halo invitation authenticator"
2676
- }, /* @__PURE__ */ React36.createElement(InvitationAuthenticator, {
2730
+ }, /* @__PURE__ */ React37.createElement(InvitationAuthenticator, {
2677
2731
  send,
2678
2732
  Kind: "Halo",
2679
2733
  active: activeView === "halo invitation authenticator",
@@ -2682,28 +2736,28 @@ var JoinPanelImpl = (props) => {
2682
2736
  ...failed.has("Halo") && {
2683
2737
  failed: true
2684
2738
  }
2685
- })), /* @__PURE__ */ React36.createElement(Viewport.View, {
2739
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2686
2740
  classNames: stepStyles,
2687
2741
  id: "halo invitation accepted"
2688
- }, /* @__PURE__ */ React36.createElement(InvitationAccepted, {
2742
+ }, /* @__PURE__ */ React37.createElement(InvitationAccepted, {
2689
2743
  send,
2690
2744
  Kind: "Halo",
2691
2745
  active: activeView === "halo invitation accepted",
2692
2746
  doneActionParent,
2693
2747
  onDone: onHaloDone
2694
- })), /* @__PURE__ */ React36.createElement(Viewport.View, {
2748
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2695
2749
  classNames: stepStyles,
2696
2750
  id: "identity added"
2697
- }, /* @__PURE__ */ React36.createElement(IdentityAdded, {
2751
+ }, /* @__PURE__ */ React37.createElement(IdentityAdded, {
2698
2752
  send,
2699
2753
  mode,
2700
2754
  active: activeView === "identity added",
2701
2755
  doneActionParent,
2702
2756
  onDone: onHaloDone
2703
- })), /* @__PURE__ */ React36.createElement(Viewport.View, {
2757
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2704
2758
  classNames: stepStyles,
2705
2759
  id: "space invitation input"
2706
- }, /* @__PURE__ */ React36.createElement(InvitationInput, {
2760
+ }, /* @__PURE__ */ React37.createElement(InvitationInput, {
2707
2761
  send,
2708
2762
  Kind: "Space",
2709
2763
  active: activeView === "space invitation input",
@@ -2715,20 +2769,20 @@ var JoinPanelImpl = (props) => {
2715
2769
  },
2716
2770
  onExit,
2717
2771
  exitActionParent
2718
- })), /* @__PURE__ */ React36.createElement(Viewport.View, {
2772
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2719
2773
  classNames: stepStyles,
2720
2774
  id: "space invitation rescuer"
2721
- }, /* @__PURE__ */ React36.createElement(InvitationRescuer, {
2775
+ }, /* @__PURE__ */ React37.createElement(InvitationRescuer, {
2722
2776
  send,
2723
2777
  Kind: "Space",
2724
2778
  active: activeView === "space invitation rescuer",
2725
2779
  invitationState: invitationStates?.Space,
2726
2780
  onInvitationCancel: onSpaceInvitationCancel,
2727
2781
  failReason: failReasons?.Space
2728
- })), /* @__PURE__ */ React36.createElement(Viewport.View, {
2782
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2729
2783
  classNames: stepStyles,
2730
2784
  id: "space invitation authenticator"
2731
- }, /* @__PURE__ */ React36.createElement(InvitationAuthenticator, {
2785
+ }, /* @__PURE__ */ React37.createElement(InvitationAuthenticator, {
2732
2786
  send,
2733
2787
  Kind: "Space",
2734
2788
  active: activeView === "space invitation authenticator",
@@ -2737,10 +2791,10 @@ var JoinPanelImpl = (props) => {
2737
2791
  ...failed.has("Space") && {
2738
2792
  failed: true
2739
2793
  }
2740
- })), /* @__PURE__ */ React36.createElement(Viewport.View, {
2794
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2741
2795
  classNames: stepStyles,
2742
2796
  id: "space invitation accepted"
2743
- }, /* @__PURE__ */ React36.createElement(InvitationAccepted, {
2797
+ }, /* @__PURE__ */ React37.createElement(InvitationAccepted, {
2744
2798
  send,
2745
2799
  Kind: "Space",
2746
2800
  active: activeView === "space invitation accepted",
@@ -2980,7 +3034,7 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
2980
3034
  joinState,
2981
3035
  propsOnDone
2982
3036
  ]);
2983
- return /* @__PURE__ */ React36.createElement(JoinPanelImpl, {
3037
+ return /* @__PURE__ */ React37.createElement(JoinPanelImpl, {
2984
3038
  titleId,
2985
3039
  mode,
2986
3040
  send: joinSend,
@@ -3019,10 +3073,10 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
3019
3073
 
3020
3074
  // packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx
3021
3075
  import { Planet } from "@phosphor-icons/react";
3022
- import React38, { useEffect as useEffect6, useMemo as useMemo5 } from "react";
3076
+ import React39, { useEffect as useEffect6, useMemo as useMemo5 } from "react";
3023
3077
  import { log as log10 } from "@dxos/log";
3024
3078
  import { useInvitationStatus as useInvitationStatus3 } from "@dxos/react-client/invitations";
3025
- import { DensityProvider as DensityProvider4, useId as useId8, useTranslation as useTranslation23 } from "@dxos/react-ui";
3079
+ import { DensityProvider as DensityProvider4, useId as useId8, useTranslation as useTranslation24 } from "@dxos/react-ui";
3026
3080
 
3027
3081
  // packages/sdk/shell/src/panels/SpacePanel/spaceMachine.ts
3028
3082
  import { useMachine as useMachine3 } from "@xstate/react";
@@ -3088,16 +3142,16 @@ var useSpaceMachine = (options) => {
3088
3142
 
3089
3143
  // packages/sdk/shell/src/panels/SpacePanel/steps/SpaceManager.tsx
3090
3144
  import { Placeholder as Placeholder2, UserPlus, UsersThree } from "@phosphor-icons/react";
3091
- import React37, { useCallback as useCallback8, useState as useState9 } from "react";
3145
+ import React38, { useCallback as useCallback8, useState as useState9 } from "react";
3092
3146
  import { useConfig } from "@dxos/react-client";
3093
3147
  import { useSpaceInvitations as useSpaceInvitations2 } from "@dxos/react-client/echo";
3094
3148
  import { Invitation as Invitation8, InvitationEncoder as InvitationEncoder4 } from "@dxos/react-client/invitations";
3095
- import { ScrollArea, useTranslation as useTranslation22 } from "@dxos/react-ui";
3096
- import { descriptionText as descriptionText10, mx as mx21 } from "@dxos/react-ui-theme";
3149
+ import { ScrollArea, useTranslation as useTranslation23 } from "@dxos/react-ui";
3150
+ import { descriptionText as descriptionText10, mx as mx22 } from "@dxos/react-ui-theme";
3097
3151
  var activeActionKey = "dxos:react-shell/space-manager/active-action";
3098
3152
  var SpaceManager = (props) => {
3099
3153
  const { space, target } = props;
3100
- const { t } = useTranslation22("os");
3154
+ const { t } = useTranslation23("os");
3101
3155
  const config = useConfig();
3102
3156
  const invitations = useSpaceInvitations2(space?.key);
3103
3157
  const onInvitationEvent = useCallback8((invitation) => {
@@ -3145,7 +3199,7 @@ var SpaceManager = (props) => {
3145
3199
  ])
3146
3200
  }
3147
3201
  };
3148
- return /* @__PURE__ */ React37.createElement(SpaceManagerImpl, {
3202
+ return /* @__PURE__ */ React38.createElement(SpaceManagerImpl, {
3149
3203
  ...props,
3150
3204
  invitations,
3151
3205
  inviteActions
@@ -3154,7 +3208,7 @@ var SpaceManager = (props) => {
3154
3208
  var headingFragment = "pis-3 pie-1 plb-1 mbe-1 font-medium";
3155
3209
  var SpaceManagerImpl = (props) => {
3156
3210
  const { active, space, createInvitationUrl, send, inviteActions: propsInviteActions, invitations, showInactiveInvitations, SpaceMemberList: SpaceMemberListComponent = SpaceMemberList, InvitationList: InvitationListComponent = InvitationList } = props;
3157
- const { t } = useTranslation22("os");
3211
+ const { t } = useTranslation23("os");
3158
3212
  const inviteActions = propsInviteActions ?? {
3159
3213
  noopInvite: {
3160
3214
  label: t("create space invitation label"),
@@ -3172,26 +3226,26 @@ var SpaceManagerImpl = (props) => {
3172
3226
  const visibleInvitations = showInactiveInvitations ? invitations : invitations?.filter((invitation) => ![
3173
3227
  Invitation8.State.CANCELLED
3174
3228
  ].includes(invitation.get().state));
3175
- return /* @__PURE__ */ React37.createElement(React37.Fragment, null, /* @__PURE__ */ React37.createElement(ScrollArea.Root, {
3229
+ return /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement(ScrollArea.Root, {
3176
3230
  classNames: "grow shrink basis-28 -mli-2"
3177
- }, /* @__PURE__ */ React37.createElement(ScrollArea.Viewport, {
3231
+ }, /* @__PURE__ */ React38.createElement(ScrollArea.Viewport, {
3178
3232
  classNames: "is-full pie-2"
3179
- }, !!visibleInvitations?.length && /* @__PURE__ */ React37.createElement(React37.Fragment, null, /* @__PURE__ */ React37.createElement("h3", {
3180
- className: mx21(headingFragment, descriptionText10)
3181
- }, t("invitation list heading")), /* @__PURE__ */ React37.createElement(InvitationListComponent, {
3233
+ }, !!visibleInvitations?.length && /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement("h3", {
3234
+ className: mx22(headingFragment, descriptionText10)
3235
+ }, t("invitation list heading")), /* @__PURE__ */ React38.createElement(InvitationListComponent, {
3182
3236
  className: "mb-2",
3183
3237
  send,
3184
3238
  invitations: visibleInvitations ?? [],
3185
3239
  onClickRemove: (invitation) => invitation.cancel(),
3186
3240
  createInvitationUrl
3187
- }), /* @__PURE__ */ React37.createElement("h3", {
3188
- className: mx21(headingFragment, descriptionText10, "mbs-2")
3189
- }, t("space member list heading"))), /* @__PURE__ */ React37.createElement(SpaceMemberListComponent, {
3241
+ }), /* @__PURE__ */ React38.createElement("h3", {
3242
+ className: mx22(headingFragment, descriptionText10, "mbs-2")
3243
+ }, t("space member list heading"))), /* @__PURE__ */ React38.createElement(SpaceMemberListComponent, {
3190
3244
  spaceKey: space.key,
3191
3245
  includeSelf: true
3192
- })), /* @__PURE__ */ React37.createElement(ScrollArea.Scrollbar, {
3246
+ })), /* @__PURE__ */ React38.createElement(ScrollArea.Scrollbar, {
3193
3247
  orientation: "vertical"
3194
- }, /* @__PURE__ */ React37.createElement(ScrollArea.Thumb, null))), /* @__PURE__ */ React37.createElement(Actions, null, /* @__PURE__ */ React37.createElement(BifurcatedAction, {
3248
+ }, /* @__PURE__ */ React38.createElement(ScrollArea.Thumb, null))), /* @__PURE__ */ React38.createElement(Actions, null, /* @__PURE__ */ React38.createElement(BifurcatedAction, {
3195
3249
  disabled: !active,
3196
3250
  actions: inviteActions,
3197
3251
  activeAction,
@@ -3203,46 +3257,46 @@ var SpaceManagerImpl = (props) => {
3203
3257
  // packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx
3204
3258
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx";
3205
3259
  var SpacePanelHeading = ({ titleId, space, onDone }) => {
3206
- const { t } = useTranslation23("os");
3260
+ const { t } = useTranslation24("os");
3207
3261
  const name = space.properties.name;
3208
- return /* @__PURE__ */ React38.createElement(Heading, {
3262
+ return /* @__PURE__ */ React39.createElement(Heading, {
3209
3263
  titleId,
3210
3264
  title: t("space panel heading"),
3211
- corner: /* @__PURE__ */ React38.createElement(CloseButton, {
3265
+ corner: /* @__PURE__ */ React39.createElement(CloseButton, {
3212
3266
  "data-testid": "identity-panel-done",
3213
3267
  onDone
3214
3268
  })
3215
- }, /* @__PURE__ */ React38.createElement("div", {
3269
+ }, /* @__PURE__ */ React39.createElement("div", {
3216
3270
  role: "none",
3217
3271
  className: "flex gap-4 items-center justify-center mlb-4"
3218
- }, /* @__PURE__ */ React38.createElement(Planet, {
3272
+ }, /* @__PURE__ */ React39.createElement(Planet, {
3219
3273
  size: 32
3220
- }), /* @__PURE__ */ React38.createElement("div", {
3274
+ }), /* @__PURE__ */ React39.createElement("div", {
3221
3275
  className: "block text-start font-light text-xl"
3222
3276
  }, name ?? space.key.truncate())));
3223
3277
  };
3224
3278
  var SpacePanelImpl = (props) => {
3225
3279
  const { titleId, activeView, space, target, SpaceManager: SpaceManagerComponent = SpaceManager, InvitationManager: InvitationManagerComponent = InvitationManager, ...rest } = props;
3226
- return /* @__PURE__ */ React38.createElement(DensityProvider4, {
3280
+ return /* @__PURE__ */ React39.createElement(DensityProvider4, {
3227
3281
  density: "fine"
3228
- }, /* @__PURE__ */ React38.createElement(SpacePanelHeading, {
3282
+ }, /* @__PURE__ */ React39.createElement(SpacePanelHeading, {
3229
3283
  ...rest,
3230
3284
  titleId,
3231
3285
  space
3232
- }), /* @__PURE__ */ React38.createElement(Viewport.Root, {
3286
+ }), /* @__PURE__ */ React39.createElement(Viewport.Root, {
3233
3287
  activeView
3234
- }, /* @__PURE__ */ React38.createElement(Viewport.Views, null, /* @__PURE__ */ React38.createElement(Viewport.View, {
3288
+ }, /* @__PURE__ */ React39.createElement(Viewport.Views, null, /* @__PURE__ */ React39.createElement(Viewport.View, {
3235
3289
  id: "space manager",
3236
3290
  classNames: stepStyles
3237
- }, /* @__PURE__ */ React38.createElement(SpaceManagerComponent, {
3291
+ }, /* @__PURE__ */ React39.createElement(SpaceManagerComponent, {
3238
3292
  active: activeView === "space manager",
3239
3293
  space,
3240
3294
  target,
3241
3295
  ...rest
3242
- })), /* @__PURE__ */ React38.createElement(Viewport.View, {
3296
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
3243
3297
  id: "space invitation manager",
3244
3298
  classNames: stepStyles
3245
- }, /* @__PURE__ */ React38.createElement(InvitationManagerComponent, {
3299
+ }, /* @__PURE__ */ React39.createElement(InvitationManagerComponent, {
3246
3300
  active: activeView === "space invitation manager",
3247
3301
  ...rest,
3248
3302
  invitationUrl: props.invitationUrl
@@ -3250,7 +3304,7 @@ var SpacePanelImpl = (props) => {
3250
3304
  };
3251
3305
  var SpacePanelWithInvitationImpl = ({ invitation, ...props }) => {
3252
3306
  const invitationStatus = useInvitationStatus3(invitation);
3253
- return /* @__PURE__ */ React38.createElement(SpacePanelImpl, {
3307
+ return /* @__PURE__ */ React39.createElement(SpacePanelImpl, {
3254
3308
  ...props,
3255
3309
  ...invitationStatus,
3256
3310
  invitationUrl: props.createInvitationUrl(invitationStatus.invitationCode)
@@ -3297,63 +3351,63 @@ var SpacePanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => code,
3297
3351
  };
3298
3352
  return spaceState.context.invitation ? (
3299
3353
  // TODO(wittjosiah): Unused? Remove?
3300
- /* @__PURE__ */ React38.createElement(SpacePanelWithInvitationImpl, {
3354
+ /* @__PURE__ */ React39.createElement(SpacePanelWithInvitationImpl, {
3301
3355
  ...implProps,
3302
3356
  invitation: spaceState.context.invitation
3303
3357
  })
3304
- ) : /* @__PURE__ */ React38.createElement(SpacePanelImpl, implProps);
3358
+ ) : /* @__PURE__ */ React39.createElement(SpacePanelImpl, implProps);
3305
3359
  };
3306
3360
 
3307
3361
  // packages/sdk/shell/src/composites/IdentityDialog/IdentityDialog.tsx
3308
3362
  var IdentityDialog = (props) => {
3309
3363
  const titleId = useId9("spaceDialog__title");
3310
- return /* @__PURE__ */ React39.createElement(Dialog.Root, {
3364
+ return /* @__PURE__ */ React40.createElement(Dialog.Root, {
3311
3365
  defaultOpen: true,
3312
3366
  onOpenChange: (open) => open || props.onDone?.()
3313
- }, /* @__PURE__ */ React39.createElement(Dialog.Portal, null, /* @__PURE__ */ React39.createElement(Dialog.Overlay, null, /* @__PURE__ */ React39.createElement(Dialog.Content, {
3367
+ }, /* @__PURE__ */ React40.createElement(Dialog.Portal, null, /* @__PURE__ */ React40.createElement(Dialog.Overlay, null, /* @__PURE__ */ React40.createElement(Dialog.Content, {
3314
3368
  "aria-labelledby": titleId,
3315
3369
  onOpenAutoFocus: (e) => e.preventDefault()
3316
- }, /* @__PURE__ */ React39.createElement(ClipboardProvider, null, /* @__PURE__ */ React39.createElement(IdentityPanel, {
3370
+ }, /* @__PURE__ */ React40.createElement(ClipboardProvider, null, /* @__PURE__ */ React40.createElement(IdentityPanel, {
3317
3371
  ...props,
3318
3372
  titleId,
3319
- doneActionParent: /* @__PURE__ */ React39.createElement(Dialog.Close, {
3373
+ doneActionParent: /* @__PURE__ */ React40.createElement(Dialog.Close, {
3320
3374
  asChild: true
3321
3375
  })
3322
3376
  }))))));
3323
3377
  };
3324
3378
 
3325
3379
  // packages/sdk/shell/src/composites/JoinDialog/JoinDialog.tsx
3326
- import React40 from "react";
3380
+ import React41 from "react";
3327
3381
  import { AlertDialog, useId as useId10, useVisualViewport } from "@dxos/react-ui";
3328
3382
  var JoinDialog = (joinPanelProps) => {
3329
3383
  const titleId = useId10("joinDialog__title");
3330
3384
  const { height } = useVisualViewport();
3331
- return /* @__PURE__ */ React40.createElement(AlertDialog.Root, {
3385
+ return /* @__PURE__ */ React41.createElement(AlertDialog.Root, {
3332
3386
  defaultOpen: true,
3333
3387
  onOpenChange: (open) => open || (joinPanelProps.onExit ? joinPanelProps.onExit() : joinPanelProps.onDone?.(null))
3334
- }, /* @__PURE__ */ React40.createElement(AlertDialog.Portal, null, /* @__PURE__ */ React40.createElement(AlertDialog.Overlay, {
3388
+ }, /* @__PURE__ */ React41.createElement(AlertDialog.Portal, null, /* @__PURE__ */ React41.createElement(AlertDialog.Overlay, {
3335
3389
  classNames: "backdrop-blur",
3336
3390
  ...height && {
3337
3391
  style: {
3338
3392
  blockSize: `${height}px`
3339
3393
  }
3340
3394
  }
3341
- }, /* @__PURE__ */ React40.createElement(AlertDialog.Content, {
3395
+ }, /* @__PURE__ */ React41.createElement(AlertDialog.Content, {
3342
3396
  "aria-labelledby": titleId
3343
- }, /* @__PURE__ */ React40.createElement(JoinPanel, {
3397
+ }, /* @__PURE__ */ React41.createElement(JoinPanel, {
3344
3398
  ...joinPanelProps,
3345
3399
  titleId,
3346
- exitActionParent: /* @__PURE__ */ React40.createElement(AlertDialog.Cancel, {
3400
+ exitActionParent: /* @__PURE__ */ React41.createElement(AlertDialog.Cancel, {
3347
3401
  asChild: true
3348
3402
  }),
3349
- doneActionParent: /* @__PURE__ */ React40.createElement(AlertDialog.Action, {
3403
+ doneActionParent: /* @__PURE__ */ React41.createElement(AlertDialog.Action, {
3350
3404
  asChild: true
3351
3405
  })
3352
3406
  })))));
3353
3407
  };
3354
3408
 
3355
3409
  // packages/sdk/shell/src/composites/Shell/run-shell.tsx
3356
- import React43, { StrictMode } from "react";
3410
+ import React44, { StrictMode } from "react";
3357
3411
  import { createRoot } from "react-dom/client";
3358
3412
  import { DEFAULT_CLIENT_CHANNEL, DEFAULT_SHELL_CHANNEL } from "@dxos/client-protocol";
3359
3413
  import { ShellRuntimeImpl } from "@dxos/client-services";
@@ -3363,25 +3417,25 @@ import { defaultTx } from "@dxos/react-ui-theme";
3363
3417
  import { createIFramePort } from "@dxos/rpc-tunnel";
3364
3418
 
3365
3419
  // packages/sdk/shell/src/composites/Shell/Shell.tsx
3366
- import React42, { useEffect as useEffect7, useState as useState10 } from "react";
3420
+ import React43, { useEffect as useEffect7, useState as useState10 } from "react";
3367
3421
  import { log as log11 } from "@dxos/log";
3368
- import { ShellDisplay, ShellLayout } from "@dxos/react-client";
3422
+ import { ShellDisplay, ShellLayout, useClient as useClient8 } from "@dxos/react-client";
3369
3423
  import { useSpace as useSpace2 } from "@dxos/react-client/echo";
3370
3424
 
3371
3425
  // packages/sdk/shell/src/composites/SpaceDialog/SpaceDialog.tsx
3372
- import React41 from "react";
3426
+ import React42 from "react";
3373
3427
  import { Dialog as Dialog2, useId as useId11 } from "@dxos/react-ui";
3374
3428
  var SpaceDialog = (spacePanelProps) => {
3375
3429
  const titleId = useId11("spaceDialog__title");
3376
- return /* @__PURE__ */ React41.createElement(Dialog2.Root, {
3430
+ return /* @__PURE__ */ React42.createElement(Dialog2.Root, {
3377
3431
  defaultOpen: true,
3378
3432
  onOpenChange: (open) => open || spacePanelProps.onDone?.()
3379
- }, /* @__PURE__ */ React41.createElement(Dialog2.Portal, null, /* @__PURE__ */ React41.createElement(Dialog2.Overlay, null, /* @__PURE__ */ React41.createElement(Dialog2.Content, {
3433
+ }, /* @__PURE__ */ React42.createElement(Dialog2.Portal, null, /* @__PURE__ */ React42.createElement(Dialog2.Overlay, null, /* @__PURE__ */ React42.createElement(Dialog2.Content, {
3380
3434
  "aria-labelledby": titleId
3381
- }, /* @__PURE__ */ React41.createElement(ClipboardProvider, null, /* @__PURE__ */ React41.createElement(SpacePanel, {
3435
+ }, /* @__PURE__ */ React42.createElement(ClipboardProvider, null, /* @__PURE__ */ React42.createElement(SpacePanel, {
3382
3436
  ...spacePanelProps,
3383
3437
  titleId,
3384
- doneActionParent: /* @__PURE__ */ React41.createElement(Dialog2.Close, {
3438
+ doneActionParent: /* @__PURE__ */ React42.createElement(Dialog2.Close, {
3385
3439
  asChild: true
3386
3440
  })
3387
3441
  }))))));
@@ -3396,6 +3450,7 @@ var Shell = ({ runtime, origin }) => {
3396
3450
  spaceKey: runtime.spaceKey,
3397
3451
  target: runtime.target
3398
3452
  });
3453
+ const client = useClient8();
3399
3454
  const space = useSpace2(spaceKey);
3400
3455
  useEffect7(() => {
3401
3456
  return runtime.layoutUpdate.on((request) => setLayout(request));
@@ -3406,7 +3461,7 @@ var Shell = ({ runtime, origin }) => {
3406
3461
  if (layout === ShellLayout.SPACE && !space) {
3407
3462
  log11.warn("No space found for shell space invitations.", void 0, {
3408
3463
  F: __dxlog_file12,
3409
- L: 31,
3464
+ L: 32,
3410
3465
  S: void 0,
3411
3466
  C: (f, a) => f(...a)
3412
3467
  });
@@ -3427,7 +3482,7 @@ var Shell = ({ runtime, origin }) => {
3427
3482
  ]);
3428
3483
  switch (layout) {
3429
3484
  case ShellLayout.INITIALIZE_IDENTITY:
3430
- return /* @__PURE__ */ React42.createElement(JoinDialog, {
3485
+ return /* @__PURE__ */ React43.createElement(JoinDialog, {
3431
3486
  mode: "halo-only",
3432
3487
  initialInvitationCode: invitationCode,
3433
3488
  onDone: () => {
@@ -3442,8 +3497,18 @@ var Shell = ({ runtime, origin }) => {
3442
3497
  case ShellLayout.IDENTITY:
3443
3498
  case ShellLayout.SHARE_IDENTITY:
3444
3499
  case ShellLayout.EDIT_PROFILE:
3445
- return /* @__PURE__ */ React42.createElement(IdentityDialog, {
3500
+ return /* @__PURE__ */ React43.createElement(IdentityDialog, {
3446
3501
  createInvitationUrl: (invitationCode2) => `${origin}?deviceInvitationCode=${invitationCode2}`,
3502
+ onResetDevice: async () => {
3503
+ await client.reset();
3504
+ await runtime.setAppContext({
3505
+ display: ShellDisplay.NONE,
3506
+ reload: true
3507
+ });
3508
+ },
3509
+ onJoinNewIdentity: () => runtime.setLayout({
3510
+ layout: ShellLayout.INITIALIZE_IDENTITY
3511
+ }),
3447
3512
  onDone: async () => {
3448
3513
  await runtime.setAppContext({
3449
3514
  display: ShellDisplay.NONE
@@ -3454,7 +3519,7 @@ var Shell = ({ runtime, origin }) => {
3454
3519
  }
3455
3520
  });
3456
3521
  case ShellLayout.SPACE:
3457
- return space ? /* @__PURE__ */ React42.createElement(SpaceDialog, {
3522
+ return space ? /* @__PURE__ */ React43.createElement(SpaceDialog, {
3458
3523
  space,
3459
3524
  target,
3460
3525
  createInvitationUrl: (invitationCode2) => `${origin}?spaceInvitationCode=${invitationCode2}`,
@@ -3468,7 +3533,7 @@ var Shell = ({ runtime, origin }) => {
3468
3533
  }
3469
3534
  }) : null;
3470
3535
  case ShellLayout.JOIN_SPACE:
3471
- return /* @__PURE__ */ React42.createElement(JoinDialog, {
3536
+ return /* @__PURE__ */ React43.createElement(JoinDialog, {
3472
3537
  initialInvitationCode: invitationCode,
3473
3538
  onDone: async (result) => {
3474
3539
  const target2 = result?.target ?? void 0;
@@ -3595,7 +3660,12 @@ var os = {
3595
3660
  "confirm label": "Confirm",
3596
3661
  "reset identity input label": "This will clear this device and all associated data. Type {{confirmationValue}} and confirm to continue.",
3597
3662
  "failed to reset identity message": "Failed to reset identity.",
3598
- "confirmation value": "CONFIRM"
3663
+ "confirmation value": "CONFIRM",
3664
+ "sign out chooser title": "DANGER ZONE",
3665
+ "sign out chooser message": "Proceeding with either action below will erase all data on this device.",
3666
+ "join new identity label": "Join a new identity",
3667
+ "reset device label": "Reset device",
3668
+ "reset device confirm message": "Are you sure you want to reset your device? All data will be lost."
3599
3669
  };
3600
3670
 
3601
3671
  // packages/sdk/shell/src/translations/index.ts
@@ -3619,27 +3689,27 @@ var runShell = async (config = new Config()) => {
3619
3689
  runtime.open(),
3620
3690
  client.initialize()
3621
3691
  ]);
3622
- createRoot(document.getElementById("root")).render(/* @__PURE__ */ React43.createElement(StrictMode, null, /* @__PURE__ */ React43.createElement(ThemeProvider, {
3692
+ createRoot(document.getElementById("root")).render(/* @__PURE__ */ React44.createElement(StrictMode, null, /* @__PURE__ */ React44.createElement(ThemeProvider, {
3623
3693
  tx: defaultTx,
3624
3694
  resourceExtensions: [
3625
3695
  osTranslations
3626
3696
  ]
3627
- }, /* @__PURE__ */ React43.createElement(ClientContext.Provider, {
3697
+ }, /* @__PURE__ */ React44.createElement(ClientContext.Provider, {
3628
3698
  value: {
3629
3699
  client,
3630
3700
  status: SystemStatus.ACTIVE
3631
3701
  }
3632
- }, /* @__PURE__ */ React43.createElement(ClipboardProvider, null, /* @__PURE__ */ React43.createElement(Tooltip3.Provider, null, /* @__PURE__ */ React43.createElement(Shell, {
3702
+ }, /* @__PURE__ */ React44.createElement(ClipboardProvider, null, /* @__PURE__ */ React44.createElement(Tooltip3.Provider, null, /* @__PURE__ */ React44.createElement(Shell, {
3633
3703
  runtime,
3634
3704
  origin: location.origin
3635
3705
  })))))));
3636
3706
  };
3637
3707
 
3638
3708
  // packages/sdk/shell/src/composites/Shell/ShellContext.tsx
3639
- import React44, { createContext as createContext2, useCallback as useCallback9, useContext as useContext2, useEffect as useEffect8, useMemo as useMemo6, useState as useState11 } from "react";
3640
- import { ShellDisplay as ShellDisplay2, ShellLayout as ShellLayout3, useClient as useClient8 } from "@dxos/react-client";
3709
+ import React45, { createContext as createContext2, useCallback as useCallback9, useContext as useContext2, useEffect as useEffect8, useMemo as useMemo6, useState as useState11 } from "react";
3710
+ import { ShellDisplay as ShellDisplay2, ShellLayout as ShellLayout3, useClient as useClient9 } from "@dxos/react-client";
3641
3711
  import { useIdentity as useIdentity3 } from "@dxos/react-client/halo";
3642
- import { mx as mx22 } from "@dxos/react-ui-theme";
3712
+ import { mx as mx23 } from "@dxos/react-ui-theme";
3643
3713
 
3644
3714
  // packages/sdk/shell/src/composites/Shell/memory-shell-runtime.ts
3645
3715
  import { Event } from "@dxos/async";
@@ -3675,7 +3745,7 @@ var MemoryShellRuntime = class {
3675
3745
  // packages/sdk/shell/src/composites/Shell/ShellContext.tsx
3676
3746
  var ShellContext = /* @__PURE__ */ createContext2({});
3677
3747
  var useShell = () => {
3678
- const client = useClient8();
3748
+ const client = useClient9();
3679
3749
  const { runtime, setDisplay } = useContext2(ShellContext);
3680
3750
  const setLayout = async (layout, options) => {
3681
3751
  if (runtime) {
@@ -3696,7 +3766,7 @@ var useShell = () => {
3696
3766
  };
3697
3767
  };
3698
3768
  var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoinedSpace, children }) => {
3699
- const client = useClient8();
3769
+ const client = useClient9();
3700
3770
  const identity = useIdentity3();
3701
3771
  const [display, setDisplay] = useState11(!identity || spaceInvitationCode || deviceInvitationCode ? ShellDisplay2.FULLSCREEN : ShellDisplay2.NONE);
3702
3772
  const shellRuntime = useMemo6(() => {
@@ -3768,12 +3838,12 @@ var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoine
3768
3838
  }, [
3769
3839
  shellRuntime
3770
3840
  ]);
3771
- return /* @__PURE__ */ React44.createElement(React44.Fragment, null, shellRuntime && /* @__PURE__ */ React44.createElement("div", {
3772
- className: mx22(display === ShellDisplay2.NONE ? "hidden" : "")
3773
- }, /* @__PURE__ */ React44.createElement(Shell, {
3841
+ return /* @__PURE__ */ React45.createElement(React45.Fragment, null, shellRuntime && /* @__PURE__ */ React45.createElement("div", {
3842
+ className: mx23(display === ShellDisplay2.NONE ? "hidden" : "")
3843
+ }, /* @__PURE__ */ React45.createElement(Shell, {
3774
3844
  runtime: shellRuntime,
3775
3845
  origin: window.location.origin
3776
- })), /* @__PURE__ */ React44.createElement(ShellContext.Provider, {
3846
+ })), /* @__PURE__ */ React45.createElement(ShellContext.Provider, {
3777
3847
  value: {
3778
3848
  runtime: shellRuntime,
3779
3849
  setDisplay