@dxos/shell 0.3.11-main.4eab977 → 0.3.11-main.4faaf44

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 (110) hide show
  1. package/dist/bundle/shell.mjs +36766 -0
  2. package/dist/bundle/shell.mjs.map +1 -0
  3. package/dist/bundle/shell.umd.js +210 -0
  4. package/dist/bundle/shell.umd.js.map +1 -0
  5. package/dist/bundle/style.css +1 -0
  6. package/dist/lib/browser/meta.json +1 -1
  7. package/dist/lib/browser/react.mjs +712 -446
  8. package/dist/lib/browser/react.mjs.map +4 -4
  9. package/dist/lib/browser/testing/index.mjs +35 -14
  10. package/dist/lib/browser/testing/index.mjs.map +3 -3
  11. package/dist/types/src/components/IdentityList/SpaceMemberList.js +1 -1
  12. package/dist/types/src/components/IdentityList/SpaceMemberList.js.map +1 -1
  13. package/dist/types/src/components/Panel/Action.d.ts.map +1 -1
  14. package/dist/types/src/components/Panel/Action.js +3 -18
  15. package/dist/types/src/components/Panel/Action.js.map +1 -1
  16. package/dist/types/src/composites/Shell/Shell.d.ts.map +1 -1
  17. package/dist/types/src/composites/Shell/Shell.js +15 -5
  18. package/dist/types/src/composites/Shell/Shell.js.map +1 -1
  19. package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts.map +1 -1
  20. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js +17 -9
  21. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js.map +1 -1
  22. package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.d.ts +12 -2
  23. package/dist/types/src/panels/IdentityPanel/IdentityPanelProps.d.ts.map +1 -1
  24. package/dist/types/src/panels/IdentityPanel/identityMachine.d.ts +1 -1
  25. package/dist/types/src/panels/IdentityPanel/identityMachine.d.ts.map +1 -1
  26. package/dist/types/src/panels/IdentityPanel/identityMachine.js +10 -2
  27. package/dist/types/src/panels/IdentityPanel/identityMachine.js.map +1 -1
  28. package/dist/types/src/panels/IdentityPanel/steps/AgentForm.d.ts +3 -0
  29. package/dist/types/src/panels/IdentityPanel/steps/AgentForm.d.ts.map +1 -0
  30. package/dist/types/src/panels/IdentityPanel/steps/AgentForm.js +26 -0
  31. package/dist/types/src/panels/IdentityPanel/steps/AgentForm.js.map +1 -0
  32. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.d.ts.map +1 -1
  33. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js +5 -1
  34. package/dist/types/src/panels/IdentityPanel/steps/IdentityActionChooser.js.map +1 -1
  35. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.d.ts +16 -0
  36. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.d.ts.map +1 -0
  37. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.js +40 -0
  38. package/dist/types/src/panels/IdentityPanel/steps/SignOutChooser.js.map +1 -0
  39. package/dist/types/src/panels/IdentityPanel/steps/index.d.ts +2 -0
  40. package/dist/types/src/panels/IdentityPanel/steps/index.d.ts.map +1 -1
  41. package/dist/types/src/panels/IdentityPanel/steps/index.js +2 -0
  42. package/dist/types/src/panels/IdentityPanel/steps/index.js.map +1 -1
  43. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.d.ts +15 -0
  44. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.d.ts.map +1 -0
  45. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.js +78 -0
  46. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.js.map +1 -0
  47. package/dist/types/src/panels/JoinPanel/JoinPanel.js +4 -3
  48. package/dist/types/src/panels/JoinPanel/JoinPanel.js.map +1 -1
  49. package/dist/types/src/panels/JoinPanel/joinMachine.d.ts +1 -1
  50. package/dist/types/src/panels/JoinPanel/joinMachine.d.ts.map +1 -1
  51. package/dist/types/src/panels/JoinPanel/joinMachine.js +15 -18
  52. package/dist/types/src/panels/JoinPanel/joinMachine.js.map +1 -1
  53. package/dist/types/src/panels/JoinPanel/steps/AdditionMethodChooser.js +3 -3
  54. package/dist/types/src/panels/JoinPanel/steps/AdditionMethodChooser.js.map +1 -1
  55. package/dist/types/src/panels/JoinPanel/steps/InvitationInput.d.ts.map +1 -1
  56. package/dist/types/src/panels/JoinPanel/steps/InvitationInput.js +13 -6
  57. package/dist/types/src/panels/JoinPanel/steps/InvitationInput.js.map +1 -1
  58. package/dist/types/src/panels/JoinPanel/steps/ResetIdentity.js +1 -1
  59. package/dist/types/src/panels/JoinPanel/steps/ResetIdentity.js.map +1 -1
  60. package/dist/types/src/panels/SpacePanel/SpacePanel.d.ts.map +1 -1
  61. package/dist/types/src/panels/SpacePanel/SpacePanel.js +5 -3
  62. package/dist/types/src/panels/SpacePanel/SpacePanel.js.map +1 -1
  63. package/dist/types/src/panels/SpacePanel/SpacePanel.stories.d.ts.map +1 -1
  64. package/dist/types/src/panels/SpacePanel/SpacePanel.stories.js +2 -2
  65. package/dist/types/src/panels/SpacePanel/SpacePanel.stories.js.map +1 -1
  66. package/dist/types/src/panels/SpacePanel/SpacePanelProps.d.ts +1 -0
  67. package/dist/types/src/panels/SpacePanel/SpacePanelProps.d.ts.map +1 -1
  68. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.d.ts +1 -0
  69. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.d.ts.map +1 -1
  70. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.js +3 -1
  71. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.js.map +1 -1
  72. package/dist/types/src/playwright/invitations-manager.d.ts +1 -0
  73. package/dist/types/src/playwright/invitations-manager.d.ts.map +1 -1
  74. package/dist/types/src/playwright/invitations-manager.js +4 -1
  75. package/dist/types/src/playwright/invitations-manager.js.map +1 -1
  76. package/dist/types/src/playwright/invitations.spec.js +15 -0
  77. package/dist/types/src/playwright/invitations.spec.js.map +1 -1
  78. package/dist/types/src/testing/shell-manager.d.ts +5 -4
  79. package/dist/types/src/testing/shell-manager.d.ts.map +1 -1
  80. package/dist/types/src/testing/shell-manager.js +36 -12
  81. package/dist/types/src/testing/shell-manager.js.map +1 -1
  82. package/dist/types/src/translations/locales/en-US.d.ts +5 -0
  83. package/dist/types/src/translations/locales/en-US.d.ts.map +1 -1
  84. package/dist/types/src/translations/locales/en-US.js +5 -0
  85. package/dist/types/src/translations/locales/en-US.js.map +1 -1
  86. package/package.json +21 -20
  87. package/src/components/IdentityList/SpaceMemberList.tsx +1 -1
  88. package/src/components/Panel/Action.tsx +4 -19
  89. package/src/composites/Shell/Shell.tsx +16 -3
  90. package/src/panels/IdentityPanel/IdentityPanel.tsx +27 -11
  91. package/src/panels/IdentityPanel/IdentityPanelProps.ts +20 -2
  92. package/src/panels/IdentityPanel/identityMachine.ts +11 -3
  93. package/src/panels/IdentityPanel/steps/AgentForm.tsx +61 -0
  94. package/src/panels/IdentityPanel/steps/IdentityActionChooser.tsx +8 -4
  95. package/src/panels/IdentityPanel/steps/SignOutChooser.tsx +84 -0
  96. package/src/panels/IdentityPanel/steps/index.ts +2 -0
  97. package/src/panels/IdentityPanel/useAgentHandlers.ts +88 -0
  98. package/src/panels/JoinPanel/JoinPanel.tsx +2 -2
  99. package/src/panels/JoinPanel/joinMachine.ts +16 -19
  100. package/src/panels/JoinPanel/steps/AdditionMethodChooser.tsx +3 -3
  101. package/src/panels/JoinPanel/steps/InvitationInput.tsx +7 -1
  102. package/src/panels/JoinPanel/steps/ResetIdentity.tsx +1 -1
  103. package/src/panels/SpacePanel/SpacePanel.stories.tsx +2 -1
  104. package/src/panels/SpacePanel/SpacePanel.tsx +4 -1
  105. package/src/panels/SpacePanel/SpacePanelProps.ts +1 -0
  106. package/src/panels/SpacePanel/steps/SpaceManager.tsx +4 -1
  107. package/src/playwright/invitations-manager.ts +5 -1
  108. package/src/playwright/invitations.spec.ts +19 -0
  109. package/src/testing/shell-manager.ts +40 -13
  110. package/src/translations/locales/en-US.ts +5 -0
@@ -220,7 +220,8 @@ var SpaceMemberListImpl = ({ members, onSelect }) => {
220
220
  const { t } = useTranslation3("os");
221
221
  const visibleMembers = members.filter((member) => member.identity);
222
222
  return visibleMembers.length > 0 ? /* @__PURE__ */ React6.createElement(List2, {
223
- classNames: "flex flex-col gap-2"
223
+ classNames: "flex flex-col gap-2",
224
+ "data-testid": "space-members-list"
224
225
  }, visibleMembers.map((member) => {
225
226
  return /* @__PURE__ */ React6.createElement(IdentityListItem, {
226
227
  key: member.identity.identityKey.toHex(),
@@ -521,12 +522,6 @@ import { useControllableState } from "@radix-ui/react-use-controllable-state";
521
522
  import React11, { forwardRef as forwardRef2 } from "react";
522
523
  import { Button as Button3, DropdownMenu, useTranslation as useTranslation5 } from "@dxos/react-ui";
523
524
  import { descriptionText as descriptionText4, getSize as getSize3, mx as mx9 } from "@dxos/react-ui-theme";
524
- var buttonColorFragment = (props) => {
525
- const resolvedVariant = props.variant ?? "default";
526
- return [
527
- !props.disabled ? resolvedVariant === "default" ? "bg-neutral-25 hover:bg-white hover:text-primary-500 active:bg-neutral-25 dark:active:bg-neutral-800" : resolvedVariant === "ghost" ? "active:bg-neutral-125 dark:active:bg-neutral-800" : resolvedVariant === "primary" ? "active:bg-primary-700 dark:active:bg-primary-500" : "" : ""
528
- ];
529
- };
530
525
  var defaultActions = {
531
526
  noopAction: {
532
527
  label: "No-op",
@@ -552,8 +547,7 @@ var BifurcatedAction = /* @__PURE__ */ forwardRef2((props, forwardedRef) => {
552
547
  ...rest,
553
548
  classNames: [
554
549
  "bs-11 flex-1 min-is-0 flex gap-2 rounded-ie-none",
555
- classNames,
556
- ...buttonColorFragment(props)
550
+ classNames
557
551
  ],
558
552
  ref: forwardedRef,
559
553
  variant,
@@ -563,8 +557,7 @@ var BifurcatedAction = /* @__PURE__ */ forwardRef2((props, forwardedRef) => {
563
557
  }, /* @__PURE__ */ React11.createElement(Button3, {
564
558
  classNames: [
565
559
  "bs-11 flex-none rounded-is-none",
566
- classNames,
567
- ...buttonColorFragment(props)
560
+ classNames
568
561
  ]
569
562
  }, /* @__PURE__ */ React11.createElement("span", {
570
563
  className: "sr-only"
@@ -598,8 +591,7 @@ var Action = /* @__PURE__ */ forwardRef2((props, forwardedRef) => {
598
591
  classNames: [
599
592
  isFull && "is-full",
600
593
  "bs-11 flex gap-2 mbs-2",
601
- classNames,
602
- ...buttonColorFragment(props)
594
+ classNames
603
595
  ],
604
596
  ref: forwardedRef,
605
597
  variant
@@ -813,17 +805,17 @@ var SpaceListItem = /* @__PURE__ */ forwardRef7(({ space, onClick }, ref) => {
813
805
  });
814
806
 
815
807
  // packages/sdk/shell/src/composites/IdentityDialog/IdentityDialog.tsx
816
- import React38 from "react";
808
+ import React40 from "react";
817
809
  import { Dialog, useId as useId9 } from "@dxos/react-ui";
818
810
 
819
811
  // packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx
820
- import React25, { useEffect as useEffect2, useMemo as useMemo3 } from "react";
812
+ import React27, { useEffect as useEffect3, useMemo as useMemo3 } from "react";
821
813
  import { generateName as generateName2 } from "@dxos/display-name";
822
814
  import { log as log3 } from "@dxos/log";
823
815
  import { useClient as useClient3 } from "@dxos/react-client";
824
- import { useIdentity, useDevices } from "@dxos/react-client/halo";
816
+ import { useIdentity, useDevices, useHaloInvitations as useHaloInvitations2 } from "@dxos/react-client/halo";
825
817
  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 useTranslation11 } from "@dxos/react-ui";
818
+ import { Avatar as Avatar4, DensityProvider as DensityProvider2, useId as useId5, useJdenticonHref as useJdenticonHref3, useTranslation as useTranslation13 } from "@dxos/react-ui";
827
819
 
828
820
  // packages/sdk/shell/src/panels/IdentityPanel/identityMachine.ts
829
821
  import { useMachine } from "@xstate/react";
@@ -844,6 +836,13 @@ var identityMachine = createMachine({
844
836
  states: {
845
837
  choosingAction: {},
846
838
  managingDeviceInvitation: {},
839
+ managingAgent: {
840
+ initial: "idle",
841
+ states: {
842
+ idle: {},
843
+ pending: {}
844
+ }
845
+ },
847
846
  managingDevices: {},
848
847
  managingProfile: {
849
848
  initial: "idle",
@@ -864,7 +863,8 @@ var identityMachine = createMachine({
864
863
  actions: "log"
865
864
  }
866
865
  }
867
- }
866
+ },
867
+ signingOut: {}
868
868
  },
869
869
  on: {
870
870
  unchooseAction: {
@@ -895,6 +895,14 @@ var identityMachine = createMachine({
895
895
  chooseProfile: {
896
896
  target: ".managingProfile",
897
897
  actions: "log"
898
+ },
899
+ chooseSignOut: {
900
+ target: ".signingOut",
901
+ actions: "log"
902
+ },
903
+ chooseAgent: {
904
+ target: ".managingAgent",
905
+ actions: "log"
898
906
  }
899
907
  }
900
908
  }, {
@@ -914,7 +922,7 @@ var identityMachine = createMachine({
914
922
  context
915
923
  }, {
916
924
  F: __dxlog_file,
917
- L: 96,
925
+ L: 104,
918
926
  S: void 0,
919
927
  C: (f, a) => f(...a)
920
928
  });
@@ -935,18 +943,51 @@ var useIdentityMachine = (client, options) => {
935
943
  });
936
944
  };
937
945
 
938
- // packages/sdk/shell/src/panels/IdentityPanel/steps/DeviceManager.tsx
946
+ // packages/sdk/shell/src/panels/IdentityPanel/steps/AgentForm.tsx
939
947
  import React21 from "react";
940
948
  import { useTranslation as useTranslation7 } from "@dxos/react-ui";
941
- var DeviceManager = ({ devices, active, send }) => {
942
- const { t } = useTranslation7("os");
949
+ var AgentForm = (props) => {
950
+ const { active, onAgentCreate, onAgentDestroy, send, validationMessage, agentStatus, agentActive, agentProviderDisabled } = props;
943
951
  const disabled = !active;
952
+ const { t } = useTranslation7("os");
944
953
  return /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("div", {
954
+ role: "none",
955
+ className: "grow flex flex-col justify-center"
956
+ }, /* @__PURE__ */ React21.createElement(Input, {
957
+ validationMessage,
958
+ label: /* @__PURE__ */ React21.createElement(StepHeading, null, "Agent Status"),
959
+ disabled,
960
+ "data-testid": "agent-status",
961
+ value: agentStatus
962
+ })), /* @__PURE__ */ React21.createElement(Actions, null, /* @__PURE__ */ React21.createElement(Action, {
963
+ disabled: agentActive || agentProviderDisabled,
964
+ onClick: () => onAgentCreate?.(),
965
+ "data-testid": "create-agent"
966
+ }, "Create Agent"), /* @__PURE__ */ React21.createElement(Action, {
967
+ disabled: !agentActive || agentProviderDisabled,
968
+ onClick: () => onAgentDestroy?.(),
969
+ "data-testid": "destroy-agent"
970
+ }, "Destroy Agent"), /* @__PURE__ */ React21.createElement(Action, {
971
+ disabled,
972
+ onClick: () => send?.({
973
+ type: "unchooseAction"
974
+ }),
975
+ "data-testid": "update-profile-form-back"
976
+ }, t("back label"))));
977
+ };
978
+
979
+ // packages/sdk/shell/src/panels/IdentityPanel/steps/DeviceManager.tsx
980
+ import React22 from "react";
981
+ import { useTranslation as useTranslation8 } from "@dxos/react-ui";
982
+ var DeviceManager = ({ devices, active, send }) => {
983
+ const { t } = useTranslation8("os");
984
+ const disabled = !active;
985
+ return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("div", {
945
986
  role: "none",
946
987
  className: "grow"
947
- }, /* @__PURE__ */ React21.createElement(DeviceList, {
988
+ }, /* @__PURE__ */ React22.createElement(DeviceList, {
948
989
  devices
949
- })), /* @__PURE__ */ React21.createElement(Actions, null, /* @__PURE__ */ React21.createElement(Action, {
990
+ })), /* @__PURE__ */ React22.createElement(Actions, null, /* @__PURE__ */ React22.createElement(Action, {
950
991
  variant: "ghost",
951
992
  disabled,
952
993
  onClick: () => send?.({
@@ -957,12 +998,12 @@ var DeviceManager = ({ devices, active, send }) => {
957
998
  };
958
999
 
959
1000
  // packages/sdk/shell/src/panels/IdentityPanel/steps/IdentityActionChooser.tsx
960
- import { CaretRight, Devices, Plus, Power, UserGear } from "@phosphor-icons/react";
961
- import React22, { useCallback as useCallback4 } from "react";
1001
+ import { CaretRight, Devices, Plus, Power, UserGear, HardDrive } from "@phosphor-icons/react";
1002
+ import React23, { useCallback as useCallback4 } from "react";
962
1003
  import { useClient as useClient2 } from "@dxos/react-client";
963
1004
  import { useHaloInvitations } from "@dxos/react-client/halo";
964
1005
  import { Invitation as Invitation3, InvitationEncoder } from "@dxos/react-client/invitations";
965
- import { DensityProvider, useTranslation as useTranslation8 } from "@dxos/react-ui";
1006
+ import { DensityProvider, useTranslation as useTranslation9 } from "@dxos/react-ui";
966
1007
  import { getSize as getSize6 } from "@dxos/react-ui-theme";
967
1008
  var IdentityActionChooser = (props) => {
968
1009
  const { send } = props;
@@ -992,82 +1033,95 @@ var IdentityActionChooser = (props) => {
992
1033
  invitation
993
1034
  });
994
1035
  };
995
- return /* @__PURE__ */ React22.createElement(IdentityActionChooserImpl, {
1036
+ return /* @__PURE__ */ React23.createElement(IdentityActionChooserImpl, {
996
1037
  ...props,
997
1038
  onCreateInvitationClick: (e) => createInvitation(e)
998
1039
  });
999
1040
  };
1000
1041
  var IdentityActionChooserImpl = ({ onCreateInvitationClick, active, send, onDone, doneActionParent }) => {
1001
- const { t } = useTranslation8("os");
1002
- return /* @__PURE__ */ React22.createElement("div", {
1042
+ const { t } = useTranslation9("os");
1043
+ return /* @__PURE__ */ React23.createElement("div", {
1003
1044
  role: "none",
1004
1045
  className: "grow flex flex-col gap-1"
1005
- }, /* @__PURE__ */ React22.createElement(DensityProvider, {
1046
+ }, /* @__PURE__ */ React23.createElement(DensityProvider, {
1006
1047
  density: "coarse"
1007
- }, /* @__PURE__ */ React22.createElement("div", {
1048
+ }, /* @__PURE__ */ React23.createElement("div", {
1008
1049
  className: "grow justify-center flex flex-col gap-1"
1009
- }, /* @__PURE__ */ React22.createElement(Action, {
1050
+ }, /* @__PURE__ */ React23.createElement(Action, {
1051
+ "data-testid": "manage-agent",
1052
+ onClick: () => send?.({
1053
+ type: "chooseAgent"
1054
+ }),
1055
+ classNames: "plb-4"
1056
+ }, /* @__PURE__ */ React23.createElement(HardDrive, {
1057
+ className: getSize6(6)
1058
+ }), /* @__PURE__ */ React23.createElement("span", {
1059
+ className: "grow mli-3"
1060
+ }, "Manage Agent"), /* @__PURE__ */ React23.createElement(CaretRight, {
1061
+ weight: "bold",
1062
+ className: getSize6(4)
1063
+ })), /* @__PURE__ */ React23.createElement(Action, {
1010
1064
  disabled: !active,
1011
1065
  "data-testid": "devices-panel.create-invitation",
1012
1066
  onClick: onCreateInvitationClick,
1013
1067
  classNames: "plb-4"
1014
- }, /* @__PURE__ */ React22.createElement(Plus, {
1068
+ }, /* @__PURE__ */ React23.createElement(Plus, {
1015
1069
  className: getSize6(6)
1016
- }), /* @__PURE__ */ React22.createElement("span", {
1070
+ }), /* @__PURE__ */ React23.createElement("span", {
1017
1071
  className: "grow mli-3"
1018
- }, t("choose add device label")), /* @__PURE__ */ React22.createElement(CaretRight, {
1072
+ }, t("choose add device label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1019
1073
  weight: "bold",
1020
1074
  className: getSize6(4)
1021
- })), /* @__PURE__ */ React22.createElement(Action, {
1075
+ })), /* @__PURE__ */ React23.createElement(Action, {
1022
1076
  "data-testid": "manage-devices",
1023
1077
  onClick: () => send?.({
1024
1078
  type: "chooseDevices"
1025
1079
  }),
1026
1080
  classNames: "plb-4"
1027
- }, /* @__PURE__ */ React22.createElement(Devices, {
1081
+ }, /* @__PURE__ */ React23.createElement(Devices, {
1028
1082
  className: getSize6(6)
1029
- }), /* @__PURE__ */ React22.createElement("span", {
1083
+ }), /* @__PURE__ */ React23.createElement("span", {
1030
1084
  className: "grow mli-3"
1031
- }, t("choose devices label")), /* @__PURE__ */ React22.createElement(CaretRight, {
1085
+ }, t("choose devices label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1032
1086
  weight: "bold",
1033
1087
  className: getSize6(4)
1034
- })), /* @__PURE__ */ React22.createElement(Action, {
1088
+ })), /* @__PURE__ */ React23.createElement(Action, {
1035
1089
  "data-testid": "manage-profile",
1036
1090
  onClick: () => send?.({
1037
1091
  type: "chooseProfile"
1038
1092
  }),
1039
1093
  classNames: "plb-4"
1040
- }, /* @__PURE__ */ React22.createElement(UserGear, {
1094
+ }, /* @__PURE__ */ React23.createElement(UserGear, {
1041
1095
  className: getSize6(6)
1042
- }), /* @__PURE__ */ React22.createElement("span", {
1096
+ }), /* @__PURE__ */ React23.createElement("span", {
1043
1097
  className: "grow mli-3"
1044
- }, t("choose profile label")), /* @__PURE__ */ React22.createElement(CaretRight, {
1098
+ }, t("choose profile label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1045
1099
  weight: "bold",
1046
1100
  className: getSize6(4)
1047
- })), /* @__PURE__ */ React22.createElement(Action, {
1048
- disabled: true,
1049
- "data-testid": "sign-out",
1050
- onClick: () => {
1051
- },
1101
+ })), /* @__PURE__ */ React23.createElement(Action, {
1102
+ "data-testid": "devices-panel.sign-out",
1103
+ onClick: () => send?.({
1104
+ type: "chooseSignOut"
1105
+ }),
1052
1106
  classNames: "plb-4"
1053
- }, /* @__PURE__ */ React22.createElement(Power, {
1107
+ }, /* @__PURE__ */ React23.createElement(Power, {
1054
1108
  className: getSize6(6)
1055
- }), /* @__PURE__ */ React22.createElement("span", {
1109
+ }), /* @__PURE__ */ React23.createElement("span", {
1056
1110
  className: "grow mli-3"
1057
- }, t("choose sign out label")), /* @__PURE__ */ React22.createElement(CaretRight, {
1111
+ }, t("choose sign out label")), /* @__PURE__ */ React23.createElement(CaretRight, {
1058
1112
  weight: "bold",
1059
1113
  className: getSize6(4)
1060
1114
  })))));
1061
1115
  };
1062
1116
 
1063
1117
  // packages/sdk/shell/src/panels/IdentityPanel/steps/ProfileForm.tsx
1064
- import React23, { useState as useState3 } from "react";
1118
+ import React24, { useState as useState3 } from "react";
1065
1119
  import { log as log2 } from "@dxos/log";
1066
- import { useTranslation as useTranslation9 } from "@dxos/react-ui";
1120
+ import { useTranslation as useTranslation10 } from "@dxos/react-ui";
1067
1121
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/steps/ProfileForm.tsx";
1068
1122
  var ProfileForm = (props) => {
1069
1123
  const { onUpdateProfile } = props;
1070
- const { t } = useTranslation9("os");
1124
+ const { t } = useTranslation10("os");
1071
1125
  const [validationMessage, setValidationMessage] = useState3("");
1072
1126
  const handleUpdateProfile = async (profile) => {
1073
1127
  await onUpdateProfile?.(profile).catch((error) => {
@@ -1080,7 +1134,7 @@ var ProfileForm = (props) => {
1080
1134
  setValidationMessage(t("failed to update profile message"));
1081
1135
  });
1082
1136
  };
1083
- return /* @__PURE__ */ React23.createElement(ProfileFormImpl, {
1137
+ return /* @__PURE__ */ React24.createElement(ProfileFormImpl, {
1084
1138
  ...props,
1085
1139
  onUpdateProfile: handleUpdateProfile,
1086
1140
  validationMessage
@@ -1089,14 +1143,14 @@ var ProfileForm = (props) => {
1089
1143
  var ProfileFormImpl = (props) => {
1090
1144
  const { active, profile, send, onUpdateProfile, validationMessage } = props;
1091
1145
  const disabled = !active;
1092
- const { t } = useTranslation9("os");
1146
+ const { t } = useTranslation10("os");
1093
1147
  const [inputValue, setInputValue] = useState3(profile?.displayName ?? "");
1094
- return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement("div", {
1148
+ return /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement("div", {
1095
1149
  role: "none",
1096
1150
  className: "grow flex flex-col justify-center"
1097
- }, /* @__PURE__ */ React23.createElement(Input, {
1151
+ }, /* @__PURE__ */ React24.createElement(Input, {
1098
1152
  validationMessage,
1099
- label: /* @__PURE__ */ React23.createElement(StepHeading, null, t("display name input label")),
1153
+ label: /* @__PURE__ */ React24.createElement(StepHeading, null, t("display name input label")),
1100
1154
  disabled,
1101
1155
  "data-testid": "display-name-input",
1102
1156
  placeholder: t("display name input placeholder"),
@@ -1105,14 +1159,14 @@ var ProfileFormImpl = (props) => {
1105
1159
  onKeyDown: ({ key }) => key === "Enter" && onUpdateProfile?.({
1106
1160
  displayName: inputValue
1107
1161
  })
1108
- })), /* @__PURE__ */ React23.createElement(Actions, null, /* @__PURE__ */ React23.createElement(Action, {
1162
+ })), /* @__PURE__ */ React24.createElement(Actions, null, /* @__PURE__ */ React24.createElement(Action, {
1109
1163
  variant: "ghost",
1110
1164
  disabled,
1111
1165
  onClick: () => send?.({
1112
1166
  type: "unchooseAction"
1113
1167
  }),
1114
1168
  "data-testid": "update-profile-form-back"
1115
- }, t("back label")), /* @__PURE__ */ React23.createElement(Action, {
1169
+ }, t("back label")), /* @__PURE__ */ React24.createElement(Action, {
1116
1170
  variant: "primary",
1117
1171
  disabled,
1118
1172
  onClick: () => onUpdateProfile?.({
@@ -1122,23 +1176,164 @@ var ProfileFormImpl = (props) => {
1122
1176
  }, t("done label"))));
1123
1177
  };
1124
1178
 
1179
+ // packages/sdk/shell/src/panels/IdentityPanel/steps/SignOutChooser.tsx
1180
+ import { Warning } from "@phosphor-icons/react";
1181
+ import React25 from "react";
1182
+ import { Message, useTranslation as useTranslation11 } from "@dxos/react-ui";
1183
+ import { getSize as getSize7, mx as mx18 } from "@dxos/react-ui-theme";
1184
+ var SignOutChooser = (props) => {
1185
+ const { t } = useTranslation11("os");
1186
+ const onResetDevice = () => {
1187
+ if (window.confirm(t("reset device confirm message"))) {
1188
+ void props.onResetDevice?.();
1189
+ }
1190
+ };
1191
+ return /* @__PURE__ */ React25.createElement(SignOutChooserImpl, {
1192
+ disabled: !props.active,
1193
+ onBack: () => props.send?.({
1194
+ type: "unchooseAction"
1195
+ }),
1196
+ onResetDevice,
1197
+ onJoinNewIdentity: props.onJoinNewIdentity
1198
+ });
1199
+ };
1200
+ var SignOutChooserImpl = ({ disabled, onResetDevice, onJoinNewIdentity, onBack }) => {
1201
+ const { t } = useTranslation11("os");
1202
+ return /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement("div", {
1203
+ role: "none",
1204
+ className: "grow flex flex-col justify-center"
1205
+ }, /* @__PURE__ */ React25.createElement(Message.Root, {
1206
+ valence: "error"
1207
+ }, /* @__PURE__ */ React25.createElement(Message.Title, null, /* @__PURE__ */ React25.createElement(Warning, {
1208
+ className: mx18(getSize7(6), "inline mie-2")
1209
+ }), 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, {
1210
+ disabled,
1211
+ onClick: onBack
1212
+ }, t("back label")), /* @__PURE__ */ React25.createElement(Action, {
1213
+ variant: "primary",
1214
+ "data-testid": "sign-out.join-new-identity",
1215
+ classNames: "!bg-error-500 hover:!bg-error-550",
1216
+ disabled,
1217
+ onClick: onJoinNewIdentity
1218
+ }, t("join new identity label")), /* @__PURE__ */ React25.createElement(Action, {
1219
+ variant: "primary",
1220
+ "data-testid": "sign-out.reset-device",
1221
+ classNames: "!bg-error-500 hover:!bg-error-550",
1222
+ disabled,
1223
+ onClick: onResetDevice
1224
+ }, t("reset device label"))));
1225
+ };
1226
+
1227
+ // packages/sdk/shell/src/panels/IdentityPanel/useAgentHandlers.ts
1228
+ import { useCallback as useCallback5, useEffect as useEffect2, useState as useState4 } from "react";
1229
+ import { invariant } from "@dxos/invariant";
1230
+ import { useAgentHostingProviderClient } from "@dxos/react-client";
1231
+ import { Invitation as Invitation4, InvitationEncoder as InvitationEncoder2 } from "@dxos/react-client/invitations";
1232
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/useAgentHandlers.ts";
1233
+ var useAgentHandlers = ({ client, invitations, identity }) => {
1234
+ const [validationMessage, setValidationMessage] = useState4("");
1235
+ const [agentStatus, setAgentStatus] = useState4("");
1236
+ const [agentActive, setAgentActive] = useState4(false);
1237
+ const agentHostingProviderClient = useAgentHostingProviderClient(client.config);
1238
+ useEffect2(() => {
1239
+ const fetchAgentStatus = async () => {
1240
+ if (agentHostingProviderClient) {
1241
+ const agentStatus2 = await agentHostingProviderClient?.getAgent(identity?.identityKey.truncate() ?? "foo");
1242
+ if (agentStatus2) {
1243
+ setAgentActive(true);
1244
+ setAgentStatus(agentStatus2);
1245
+ } else {
1246
+ setAgentActive(false);
1247
+ setValidationMessage("No agent deployed via provider.");
1248
+ }
1249
+ } else {
1250
+ setValidationMessage("No agent provider configured.");
1251
+ }
1252
+ };
1253
+ void fetchAgentStatus();
1254
+ }, []);
1255
+ const handleAgentCreate = useCallback5(async (invitation) => {
1256
+ const invitationCode = InvitationEncoder2.encode(invitation);
1257
+ if (invitation.state === Invitation4.State.CONNECTING) {
1258
+ console.log(JSON.stringify({
1259
+ invitationCode,
1260
+ authCode: invitation.authCode
1261
+ }));
1262
+ invariant(identity, "Identity not found", {
1263
+ F: __dxlog_file3,
1264
+ L: 50,
1265
+ S: void 0,
1266
+ A: [
1267
+ "identity",
1268
+ "'Identity not found'"
1269
+ ]
1270
+ });
1271
+ if (agentHostingProviderClient) {
1272
+ try {
1273
+ const res = await agentHostingProviderClient?.createAgent(invitationCode, identity.identityKey.truncate());
1274
+ setAgentStatus(res);
1275
+ setAgentActive(true);
1276
+ setValidationMessage("");
1277
+ } catch (err) {
1278
+ setValidationMessage(`error creating agent: ${err.message}`);
1279
+ }
1280
+ }
1281
+ }
1282
+ }, []);
1283
+ const onAgentCreate = async () => {
1284
+ invitations.forEach((invitation2) => invitation2.cancel());
1285
+ const invitation = client.halo.share({
1286
+ type: Invitation4.Type.MULTIUSE,
1287
+ authMethod: Invitation4.AuthMethod.NONE
1288
+ });
1289
+ invitation.subscribe(handleAgentCreate);
1290
+ };
1291
+ const onAgentDestroy = async () => {
1292
+ const identity2 = client.halo.identity.get();
1293
+ invariant(identity2, "Identity not found", {
1294
+ F: __dxlog_file3,
1295
+ L: 76,
1296
+ S: void 0,
1297
+ A: [
1298
+ "identity",
1299
+ "'Identity not found'"
1300
+ ]
1301
+ });
1302
+ try {
1303
+ await agentHostingProviderClient?.destroyAgent(identity2.identityKey.truncate());
1304
+ setValidationMessage("No agent deployed via provider.");
1305
+ setAgentStatus("");
1306
+ setAgentActive(false);
1307
+ } catch (err) {
1308
+ setValidationMessage(`error destroying agent: ${err.message}`);
1309
+ }
1310
+ };
1311
+ return {
1312
+ onAgentCreate,
1313
+ onAgentDestroy,
1314
+ validationMessage,
1315
+ agentStatus,
1316
+ agentActive
1317
+ };
1318
+ };
1319
+
1125
1320
  // packages/sdk/shell/src/steps/InvitationManager.tsx
1126
1321
  import { Check as Check3, X as X3 } from "@phosphor-icons/react";
1127
- import React24, { useMemo as useMemo2 } from "react";
1322
+ import React26, { useMemo as useMemo2 } from "react";
1128
1323
  import { QR } from "react-qr-rounded";
1129
- import { Invitation as Invitation4 } from "@dxos/react-client/invitations";
1130
- import { useId as useId4, useTranslation as useTranslation10 } from "@dxos/react-ui";
1131
- import { descriptionText as descriptionText7, getSize as getSize7, mx as mx18 } from "@dxos/react-ui-theme";
1324
+ import { Invitation as Invitation5 } from "@dxos/react-client/invitations";
1325
+ import { useId as useId4, useTranslation as useTranslation12 } from "@dxos/react-ui";
1326
+ import { descriptionText as descriptionText7, getSize as getSize8, mx as mx19 } from "@dxos/react-ui-theme";
1132
1327
  var InvitationManagerView = ({ children, ...props }) => {
1133
- return /* @__PURE__ */ React24.createElement(Viewport.View, {
1328
+ return /* @__PURE__ */ React26.createElement(Viewport.View, {
1134
1329
  ...props,
1135
1330
  classNames: "grow flex flex-col justify-around items-center"
1136
1331
  }, children);
1137
1332
  };
1138
1333
  var InvitationManager = ({ invitationUrl, active, send, status, type, authCode, id }) => {
1139
- const { t } = useTranslation10("os");
1334
+ const { t } = useTranslation12("os");
1140
1335
  const qrLabel = useId4("invitation-manager__qr-code");
1141
- const statusValue = type === Invitation4.Type.MULTIUSE ? 0 : invitationStatusValue.get(status) ?? 0;
1336
+ const statusValue = type === Invitation5.Type.MULTIUSE ? 0 : invitationStatusValue.get(status) ?? 0;
1142
1337
  const showAuthCode = statusValue === 3;
1143
1338
  const emoji2 = toEmoji(id ?? "");
1144
1339
  const activeView = useMemo2(() => {
@@ -1154,50 +1349,50 @@ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode,
1154
1349
  }, [
1155
1350
  statusValue
1156
1351
  ]);
1157
- return /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(Viewport.Root, {
1352
+ return /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(Viewport.Root, {
1158
1353
  activeView,
1159
1354
  classNames: "grow plb-1"
1160
- }, /* @__PURE__ */ React24.createElement(Viewport.Views, null, /* @__PURE__ */ React24.createElement(InvitationManagerView, {
1355
+ }, /* @__PURE__ */ React26.createElement(Viewport.Views, null, /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1161
1356
  id: "showing qr",
1162
1357
  emoji: emoji2
1163
- }, /* @__PURE__ */ React24.createElement("p", {
1358
+ }, /* @__PURE__ */ React26.createElement("p", {
1164
1359
  className: "text-sm mlb-1 font-normal text-center"
1165
- }, t(type === Invitation4.Type.MULTIUSE ? "invite many qr label" : "invite one qr label")), /* @__PURE__ */ React24.createElement("div", {
1360
+ }, t(type === Invitation5.Type.MULTIUSE ? "invite many qr label" : "invite one qr label")), /* @__PURE__ */ React26.createElement("div", {
1166
1361
  role: "none",
1167
- className: mx18(descriptionText7, "is-full max-is-[14rem] relative")
1168
- }, /* @__PURE__ */ React24.createElement(QR, {
1362
+ className: mx19(descriptionText7, "is-full max-is-[14rem] relative")
1363
+ }, /* @__PURE__ */ React26.createElement(QR, {
1169
1364
  rounding: 100,
1170
1365
  backgroundColor: "transparent",
1171
1366
  color: "currentColor",
1172
- className: mx18("is-full bs-full p-2", showAuthCode && "invisible"),
1367
+ className: mx19("is-full bs-full p-2", showAuthCode && "invisible"),
1173
1368
  "aria-labelledby": qrLabel,
1174
1369
  errorCorrectionLevel: "Q",
1175
1370
  cutout: true
1176
- }, invitationUrl ?? "never"), /* @__PURE__ */ React24.createElement(Centered, null, /* @__PURE__ */ React24.createElement(Emoji, {
1371
+ }, invitationUrl ?? "never"), /* @__PURE__ */ React26.createElement(Centered, null, /* @__PURE__ */ React26.createElement(Emoji, {
1177
1372
  text: emoji2
1178
- }))), /* @__PURE__ */ React24.createElement("span", {
1373
+ }))), /* @__PURE__ */ React26.createElement("span", {
1179
1374
  id: qrLabel,
1180
1375
  className: "sr-only"
1181
- }, t("qr label")), /* @__PURE__ */ React24.createElement(CopyButton, {
1376
+ }, t("qr label")), /* @__PURE__ */ React26.createElement(CopyButton, {
1182
1377
  variant: "ghost",
1183
1378
  value: invitationUrl ?? "never"
1184
- })), /* @__PURE__ */ React24.createElement(InvitationManagerView, {
1379
+ })), /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1185
1380
  id: "showing auth code"
1186
- }, /* @__PURE__ */ React24.createElement(Label, null, t("auth code message")), /* @__PURE__ */ React24.createElement(AuthCode, {
1381
+ }, /* @__PURE__ */ React26.createElement(Label, null, t("auth code message")), /* @__PURE__ */ React26.createElement(AuthCode, {
1187
1382
  code: authCode,
1188
1383
  large: true,
1189
1384
  classNames: "text-black dark:text-white"
1190
- }), /* @__PURE__ */ React24.createElement(Label, null, "Be sure the other device is showing this symbol:"), emoji2 && /* @__PURE__ */ React24.createElement(Emoji, {
1385
+ }), /* @__PURE__ */ React26.createElement(Label, null, "Be sure the other device is showing this symbol:"), emoji2 && /* @__PURE__ */ React26.createElement(Emoji, {
1191
1386
  text: emoji2
1192
- })), /* @__PURE__ */ React24.createElement(InvitationManagerView, {
1387
+ })), /* @__PURE__ */ React26.createElement(InvitationManagerView, {
1193
1388
  id: "showing final"
1194
- }, statusValue > 0 ? /* @__PURE__ */ React24.createElement(Check3, {
1195
- className: mx18("m-1.5", getSize7(6))
1196
- }) : /* @__PURE__ */ React24.createElement(X3, {
1197
- className: mx18("m-1.5", getSize7(6))
1198
- })))), /* @__PURE__ */ React24.createElement(Actions, {
1389
+ }, statusValue > 0 ? /* @__PURE__ */ React26.createElement(Check3, {
1390
+ className: mx19("m-1.5", getSize8(6))
1391
+ }) : /* @__PURE__ */ React26.createElement(X3, {
1392
+ className: mx19("m-1.5", getSize8(6))
1393
+ })))), /* @__PURE__ */ React26.createElement(Actions, {
1199
1394
  classNames: "mbs-4"
1200
- }, /* @__PURE__ */ React24.createElement(Action, {
1395
+ }, /* @__PURE__ */ React26.createElement(Action, {
1201
1396
  disabled: !active,
1202
1397
  onClick: () => send?.({
1203
1398
  type: "deselectInvitation"
@@ -1206,35 +1401,36 @@ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode,
1206
1401
  };
1207
1402
 
1208
1403
  // packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx
1209
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx";
1404
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/IdentityPanel/IdentityPanel.tsx";
1210
1405
  var viewStyles = "pbs-1 pbe-3 pli-3";
1211
1406
  var IdentityHeading = ({ titleId, title, identity, onDone }) => {
1212
1407
  const fallbackHref = useJdenticonHref3(identity.identityKey.toHex(), 12);
1213
- return /* @__PURE__ */ React25.createElement(Heading, {
1408
+ return /* @__PURE__ */ React27.createElement(Heading, {
1214
1409
  titleId,
1215
1410
  title,
1216
- corner: /* @__PURE__ */ React25.createElement(CloseButton, {
1411
+ corner: /* @__PURE__ */ React27.createElement(CloseButton, {
1217
1412
  onDone
1218
1413
  })
1219
- }, /* @__PURE__ */ React25.createElement(Avatar4.Root, {
1414
+ }, /* @__PURE__ */ React27.createElement(Avatar4.Root, {
1220
1415
  size: 12,
1221
1416
  variant: "circle",
1222
1417
  status: "active"
1223
- }, /* @__PURE__ */ React25.createElement(Avatar4.Frame, {
1418
+ }, /* @__PURE__ */ React27.createElement(Avatar4.Frame, {
1224
1419
  classNames: "block mbs-4 mbe-2 mli-auto chromatic-ignore"
1225
- }, /* @__PURE__ */ React25.createElement(Avatar4.Fallback, {
1420
+ }, /* @__PURE__ */ React27.createElement(Avatar4.Fallback, {
1226
1421
  href: fallbackHref
1227
- })), /* @__PURE__ */ React25.createElement(Avatar4.Label, {
1228
- classNames: "block text-center font-light text-xl"
1422
+ })), /* @__PURE__ */ React27.createElement(Avatar4.Label, {
1423
+ classNames: "block text-center font-light text-xl",
1424
+ "data-testid": "identityHeading.displayName"
1229
1425
  }, identity.profile?.displayName ?? generateName2(identity.identityKey.toHex()))));
1230
1426
  };
1231
1427
  var IdentityPanelImpl = (props) => {
1232
- const { identity, titleId, activeView, onUpdateProfile, IdentityActionChooser: IdentityActionChooserComponent = IdentityActionChooser, InvitationManager: InvitationManagerComponent = InvitationManager, onDone, ...rest } = props;
1233
- const { t } = useTranslation11("os");
1428
+ const { identity, titleId, activeView, onUpdateProfile, onResetDevice, onJoinNewIdentity, IdentityActionChooser: IdentityActionChooserComponent = IdentityActionChooser, InvitationManager: InvitationManagerComponent = InvitationManager, onDone, ...rest } = props;
1429
+ const { t } = useTranslation13("os");
1234
1430
  const title = useMemo3(() => {
1235
1431
  switch (activeView) {
1236
- case "device manager":
1237
- return t("choose devices label");
1432
+ case "agent manager":
1433
+ return "Manage Agent";
1238
1434
  case "device invitation manager":
1239
1435
  return t("choose add device label");
1240
1436
  default:
@@ -1244,50 +1440,62 @@ var IdentityPanelImpl = (props) => {
1244
1440
  activeView,
1245
1441
  t
1246
1442
  ]);
1247
- console.log("[IdentityPanelImpl]", {
1248
- activeView
1249
- });
1250
- return /* @__PURE__ */ React25.createElement(DensityProvider2, {
1443
+ return /* @__PURE__ */ React27.createElement(DensityProvider2, {
1251
1444
  density: "fine"
1252
- }, /* @__PURE__ */ React25.createElement(IdentityHeading, {
1445
+ }, /* @__PURE__ */ React27.createElement(IdentityHeading, {
1253
1446
  identity,
1254
1447
  titleId,
1255
1448
  title,
1256
1449
  onDone
1257
- }), /* @__PURE__ */ React25.createElement(Viewport.Root, {
1450
+ }), /* @__PURE__ */ React27.createElement(Viewport.Root, {
1258
1451
  activeView
1259
- }, /* @__PURE__ */ React25.createElement(Viewport.Views, null, /* @__PURE__ */ React25.createElement(Viewport.View, {
1452
+ }, /* @__PURE__ */ React27.createElement(Viewport.Views, null, /* @__PURE__ */ React27.createElement(Viewport.View, {
1260
1453
  id: "identity action chooser",
1261
1454
  classNames: viewStyles
1262
- }, /* @__PURE__ */ React25.createElement(IdentityActionChooserComponent, {
1455
+ }, /* @__PURE__ */ React27.createElement(IdentityActionChooserComponent, {
1263
1456
  active: activeView === "identity action chooser",
1264
1457
  ...rest
1265
- })), /* @__PURE__ */ React25.createElement(Viewport.View, {
1458
+ })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1266
1459
  id: "device invitation manager",
1267
1460
  classNames: viewStyles
1268
- }, /* @__PURE__ */ React25.createElement(InvitationManagerComponent, {
1461
+ }, /* @__PURE__ */ React27.createElement(InvitationManagerComponent, {
1269
1462
  active: activeView === "device invitation manager",
1270
1463
  ...rest,
1271
1464
  invitationUrl: rest.createInvitationUrl(rest.invitationCode)
1272
- })), /* @__PURE__ */ React25.createElement(Viewport.View, {
1465
+ })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1273
1466
  id: "device manager",
1274
1467
  classNames: viewStyles
1275
- }, /* @__PURE__ */ React25.createElement(DeviceManager, {
1468
+ }, /* @__PURE__ */ React27.createElement(DeviceManager, {
1276
1469
  active: activeView === "device manager",
1277
1470
  ...rest
1278
- })), /* @__PURE__ */ React25.createElement(Viewport.View, {
1471
+ })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1279
1472
  classNames: viewStyles,
1280
1473
  id: "update profile form"
1281
- }, /* @__PURE__ */ React25.createElement(ProfileForm, {
1474
+ }, /* @__PURE__ */ React27.createElement(ProfileForm, {
1282
1475
  send: rest.send,
1283
1476
  active: activeView === "update profile form",
1284
1477
  profile: identity.profile,
1285
1478
  onUpdateProfile
1479
+ })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1480
+ classNames: viewStyles,
1481
+ id: "signing out"
1482
+ }, /* @__PURE__ */ React27.createElement(SignOutChooser, {
1483
+ send: rest.send,
1484
+ active: activeView === "signing out",
1485
+ onResetDevice,
1486
+ onJoinNewIdentity
1487
+ })), /* @__PURE__ */ React27.createElement(Viewport.View, {
1488
+ classNames: viewStyles,
1489
+ id: "agent manager"
1490
+ }, /* @__PURE__ */ React27.createElement(AgentForm, {
1491
+ send: rest.send,
1492
+ active: activeView === "agent manager",
1493
+ ...rest
1286
1494
  })))));
1287
1495
  };
1288
1496
  var IdentityPanelWithInvitationImpl = ({ invitation, ...props }) => {
1289
1497
  const invitationStatus = useInvitationStatus2(invitation);
1290
- return /* @__PURE__ */ React25.createElement(IdentityPanelImpl, {
1498
+ return /* @__PURE__ */ React27.createElement(IdentityPanelImpl, {
1291
1499
  ...props,
1292
1500
  ...invitationStatus
1293
1501
  });
@@ -1297,16 +1505,22 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1297
1505
  const client = useClient3();
1298
1506
  const devices = useDevices();
1299
1507
  const identity = useIdentity();
1508
+ const invitations = useHaloInvitations2();
1509
+ const agentProps = useAgentHandlers({
1510
+ client,
1511
+ identity,
1512
+ invitations
1513
+ });
1300
1514
  if (!identity) {
1301
1515
  console.error("IdentityPanel rendered with no active identity.");
1302
1516
  return null;
1303
1517
  }
1304
1518
  const [identityState, identitySend, identityService] = useIdentityMachine(client);
1305
- useEffect2(() => {
1519
+ useEffect3(() => {
1306
1520
  const subscription = identityService.subscribe((state) => {
1307
1521
  log3("[state]", state, {
1308
- F: __dxlog_file3,
1309
- L: 123,
1522
+ F: __dxlog_file4,
1523
+ L: 138,
1310
1524
  S: void 0,
1311
1525
  C: (f, a) => f(...a)
1312
1526
  });
@@ -1332,16 +1546,23 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1332
1546
  }
1333
1547
  ].some(identityState.matches):
1334
1548
  return "update profile form";
1549
+ case identityState.matches("signingOut"):
1550
+ return "signing out";
1551
+ case [
1552
+ {
1553
+ managingAgent: "idle"
1554
+ },
1555
+ {
1556
+ managingAgent: "pending"
1557
+ }
1558
+ ].some(identityState.matches):
1559
+ return "agent manager";
1335
1560
  default:
1336
1561
  return "identity action chooser";
1337
1562
  }
1338
1563
  }, [
1339
1564
  identityState
1340
1565
  ]);
1341
- console.log({
1342
- activeView,
1343
- identityState
1344
- });
1345
1566
  const onUpdateProfile = async (profile) => {
1346
1567
  identitySend({
1347
1568
  type: "updateProfile"
@@ -1356,16 +1577,17 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1356
1577
  send: identitySend,
1357
1578
  titleId,
1358
1579
  createInvitationUrl,
1359
- onUpdateProfile
1580
+ onUpdateProfile,
1581
+ ...agentProps
1360
1582
  };
1361
- return identityState.context.invitation ? /* @__PURE__ */ React25.createElement(IdentityPanelWithInvitationImpl, {
1583
+ return identityState.context.invitation ? /* @__PURE__ */ React27.createElement(IdentityPanelWithInvitationImpl, {
1362
1584
  ...implProps,
1363
1585
  invitation: identityState.context.invitation
1364
- }) : /* @__PURE__ */ React25.createElement(IdentityPanelImpl, implProps);
1586
+ }) : /* @__PURE__ */ React27.createElement(IdentityPanelImpl, implProps);
1365
1587
  };
1366
1588
 
1367
1589
  // packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx
1368
- import React35, { useCallback as useCallback6, useEffect as useEffect4, useMemo as useMemo4 } from "react";
1590
+ import React37, { useCallback as useCallback7, useEffect as useEffect5, useMemo as useMemo4 } from "react";
1369
1591
  import { log as log8 } from "@dxos/log";
1370
1592
  import { useClient as useClient6, useMulticastObservable } from "@dxos/react-client";
1371
1593
  import { useIdentity as useIdentity2 } from "@dxos/react-client/halo";
@@ -1373,25 +1595,25 @@ import { DensityProvider as DensityProvider3, useId as useId7, useThemeContext a
1373
1595
 
1374
1596
  // packages/sdk/shell/src/panels/JoinPanel/JoinHeading.tsx
1375
1597
  import { X as X4 } from "@phosphor-icons/react";
1376
- import React26, { cloneElement, forwardRef as forwardRef8 } from "react";
1377
- import { Button as Button5, useTranslation as useTranslation12 } from "@dxos/react-ui";
1378
- import { descriptionText as descriptionText8, getSize as getSize8, mx as mx19 } from "@dxos/react-ui-theme";
1598
+ import React28, { cloneElement, forwardRef as forwardRef8 } from "react";
1599
+ import { Button as Button5, useTranslation as useTranslation14 } from "@dxos/react-ui";
1600
+ import { descriptionText as descriptionText8, getSize as getSize9, mx as mx20 } from "@dxos/react-ui-theme";
1379
1601
  var JoinHeading = /* @__PURE__ */ forwardRef8(({ mode, titleId, onExit, exitActionParent }, forwardedRef) => {
1380
- const { t } = useTranslation12("os");
1381
- const exitButton = /* @__PURE__ */ React26.createElement(Button5, {
1602
+ const { t } = useTranslation14("os");
1603
+ const exitButton = /* @__PURE__ */ React28.createElement(Button5, {
1382
1604
  variant: "ghost",
1383
1605
  ...onExit && {
1384
1606
  onClick: onExit
1385
1607
  },
1386
- classNames: mx19(descriptionText8, "plb-0 pli-2 absolute block-start-0 inline-end-0 z-[1]"),
1608
+ classNames: mx20(descriptionText8, "plb-0 pli-2 absolute block-start-0 inline-end-0 z-[1]"),
1387
1609
  "data-testid": "join-exit"
1388
- }, /* @__PURE__ */ React26.createElement(X4, {
1610
+ }, /* @__PURE__ */ React28.createElement(X4, {
1389
1611
  weight: "bold",
1390
- className: getSize8(4)
1391
- }), /* @__PURE__ */ React26.createElement("span", {
1612
+ className: getSize9(4)
1613
+ }), /* @__PURE__ */ React28.createElement("span", {
1392
1614
  className: "sr-only"
1393
1615
  }, t("exit label")));
1394
- return /* @__PURE__ */ React26.createElement(Heading, {
1616
+ return /* @__PURE__ */ React28.createElement(Heading, {
1395
1617
  ref: forwardedRef,
1396
1618
  titleId,
1397
1619
  title: t(mode === "halo-only" ? "selecting identity heading" : "joining space heading"),
@@ -1406,14 +1628,15 @@ var JoinHeading = /* @__PURE__ */ forwardRef8(({ mode, titleId, onExit, exitActi
1406
1628
 
1407
1629
  // packages/sdk/shell/src/panels/JoinPanel/joinMachine.ts
1408
1630
  import { useMachine as useMachine2 } from "@xstate/react";
1409
- import { useCallback as useCallback5 } from "react";
1631
+ import { useCallback as useCallback6 } from "react";
1410
1632
  import { assign as assign2, createMachine as createMachine2 } from "xstate";
1411
1633
  import { log as log4 } from "@dxos/log";
1412
- import { Invitation as Invitation5, InvitationEncoder as InvitationEncoder2 } from "@dxos/react-client/invitations";
1413
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/joinMachine.ts";
1634
+ import { AlreadyJoinedError } from "@dxos/react-client";
1635
+ import { Invitation as Invitation6, InvitationEncoder as InvitationEncoder3 } from "@dxos/react-client/invitations";
1636
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/joinMachine.ts";
1414
1637
  var getInvitationSubscribable = (Kind, invitation) => {
1415
1638
  log4("[subscribing to invitation]", invitation, {
1416
- F: __dxlog_file4,
1639
+ F: __dxlog_file5,
1417
1640
  L: 88,
1418
1641
  S: void 0,
1419
1642
  C: (f, a) => f(...a)
@@ -1421,12 +1644,12 @@ var getInvitationSubscribable = (Kind, invitation) => {
1421
1644
  return {
1422
1645
  subscribe: (next, onError, complete) => invitation.subscribe((invitation2) => {
1423
1646
  switch (invitation2.state) {
1424
- case Invitation5.State.CONNECTING: {
1647
+ case Invitation6.State.CONNECTING: {
1425
1648
  log4("[invitation connecting]", {
1426
1649
  Kind,
1427
1650
  invitation: invitation2
1428
1651
  }, {
1429
- F: __dxlog_file4,
1652
+ F: __dxlog_file5,
1430
1653
  L: 99,
1431
1654
  S: void 0,
1432
1655
  C: (f, a) => f(...a)
@@ -1436,12 +1659,12 @@ var getInvitationSubscribable = (Kind, invitation) => {
1436
1659
  invitation: invitation2
1437
1660
  });
1438
1661
  }
1439
- case Invitation5.State.CONNECTED: {
1662
+ case Invitation6.State.CONNECTED: {
1440
1663
  log4("[invitation connected]", {
1441
1664
  Kind,
1442
1665
  invitation: invitation2
1443
1666
  }, {
1444
- F: __dxlog_file4,
1667
+ F: __dxlog_file5,
1445
1668
  L: 104,
1446
1669
  S: void 0,
1447
1670
  C: (f, a) => f(...a)
@@ -1451,12 +1674,12 @@ var getInvitationSubscribable = (Kind, invitation) => {
1451
1674
  invitation: invitation2
1452
1675
  });
1453
1676
  }
1454
- case Invitation5.State.READY_FOR_AUTHENTICATION: {
1677
+ case Invitation6.State.READY_FOR_AUTHENTICATION: {
1455
1678
  log4("[invitation ready for authentication]", {
1456
1679
  Kind,
1457
1680
  invitation: invitation2
1458
1681
  }, {
1459
- F: __dxlog_file4,
1682
+ F: __dxlog_file5,
1460
1683
  L: 109,
1461
1684
  S: void 0,
1462
1685
  C: (f, a) => f(...a)
@@ -1466,12 +1689,12 @@ var getInvitationSubscribable = (Kind, invitation) => {
1466
1689
  invitation: invitation2
1467
1690
  });
1468
1691
  }
1469
- case Invitation5.State.AUTHENTICATING: {
1692
+ case Invitation6.State.AUTHENTICATING: {
1470
1693
  log4("[invitation authenticating]", {
1471
1694
  Kind,
1472
1695
  invitation: invitation2
1473
1696
  }, {
1474
- F: __dxlog_file4,
1697
+ F: __dxlog_file5,
1475
1698
  L: 114,
1476
1699
  S: void 0,
1477
1700
  C: (f, a) => f(...a)
@@ -1481,12 +1704,12 @@ var getInvitationSubscribable = (Kind, invitation) => {
1481
1704
  invitation: invitation2
1482
1705
  });
1483
1706
  }
1484
- case Invitation5.State.SUCCESS: {
1707
+ case Invitation6.State.SUCCESS: {
1485
1708
  log4("[invitation success]", {
1486
1709
  Kind,
1487
1710
  invitation: invitation2
1488
1711
  }, {
1489
- F: __dxlog_file4,
1712
+ F: __dxlog_file5,
1490
1713
  L: 119,
1491
1714
  S: void 0,
1492
1715
  C: (f, a) => f(...a)
@@ -1497,11 +1720,11 @@ var getInvitationSubscribable = (Kind, invitation) => {
1497
1720
  });
1498
1721
  return complete?.();
1499
1722
  }
1500
- case Invitation5.State.CANCELLED: {
1723
+ case Invitation6.State.CANCELLED: {
1501
1724
  log4.warn("[invitation cancelled]", {
1502
1725
  Kind
1503
1726
  }, {
1504
- F: __dxlog_file4,
1727
+ F: __dxlog_file5,
1505
1728
  L: 125,
1506
1729
  S: void 0,
1507
1730
  C: (f, a) => f(...a)
@@ -1511,11 +1734,11 @@ var getInvitationSubscribable = (Kind, invitation) => {
1511
1734
  reason: "cancelled"
1512
1735
  });
1513
1736
  }
1514
- case Invitation5.State.TIMEOUT: {
1737
+ case Invitation6.State.TIMEOUT: {
1515
1738
  log4.error("[invitation timeout]", {
1516
1739
  Kind
1517
1740
  }, {
1518
- F: __dxlog_file4,
1741
+ F: __dxlog_file5,
1519
1742
  L: 130,
1520
1743
  S: void 0,
1521
1744
  C: (f, a) => f(...a)
@@ -1527,12 +1750,28 @@ var getInvitationSubscribable = (Kind, invitation) => {
1527
1750
  }
1528
1751
  }
1529
1752
  }, (error) => {
1753
+ if (error instanceof AlreadyJoinedError) {
1754
+ log4("[already joined]", {
1755
+ Kind,
1756
+ error
1757
+ }, {
1758
+ F: __dxlog_file5,
1759
+ L: 137,
1760
+ S: void 0,
1761
+ C: (f, a) => f(...a)
1762
+ });
1763
+ next({
1764
+ type: `success${Kind}Invitation`,
1765
+ invitation: invitation.get()
1766
+ });
1767
+ return complete?.();
1768
+ }
1530
1769
  log4.error("[invitation errored]", {
1531
1770
  Kind,
1532
1771
  error
1533
1772
  }, {
1534
- F: __dxlog_file4,
1535
- L: 136,
1773
+ F: __dxlog_file5,
1774
+ L: 142,
1536
1775
  S: void 0,
1537
1776
  C: (f, a) => f(...a)
1538
1777
  });
@@ -1594,7 +1833,7 @@ var acceptingInvitationTemplate = (Kind, successTarget) => {
1594
1833
  {
1595
1834
  cond: (context) => {
1596
1835
  const invitation = context[Kind.toLowerCase()].invitation;
1597
- return !invitation || invitation?.state === Invitation5.State.CONNECTING;
1836
+ return !invitation || invitation?.state === Invitation6.State.CONNECTING;
1598
1837
  },
1599
1838
  target: `connecting${Kind}Invitation`,
1600
1839
  actions: "log"
@@ -1851,13 +2090,13 @@ var joinMachine = createMachine2({
1851
2090
  } : context.space
1852
2091
  }),
1853
2092
  log: (context, event) => {
1854
- log4.info("[transition]", {
2093
+ log4("[transition]", {
1855
2094
  event,
1856
2095
  haloInvitation: context.halo.invitation,
1857
2096
  spaceInvitation: context.space.invitation
1858
2097
  }, {
1859
- F: __dxlog_file4,
1860
- L: 400,
2098
+ F: __dxlog_file5,
2099
+ L: 406,
1861
2100
  S: void 0,
1862
2101
  C: (f, a) => f(...a)
1863
2102
  });
@@ -1870,8 +2109,8 @@ var defaultCodeFromUrl = (invitationType, text) => {
1870
2109
  return searchParams.get(`${invitationType}InvitationCode`) ?? searchParams.get(`${invitationType}Invitation`) ?? searchParams.get("invitationCode") ?? searchParams.get("invitation") ?? text;
1871
2110
  } catch (err) {
1872
2111
  log4.catch(err, void 0, {
1873
- F: __dxlog_file4,
1874
- L: 427,
2112
+ F: __dxlog_file5,
2113
+ L: 433,
1875
2114
  S: void 0,
1876
2115
  C: (f, a) => f(...a)
1877
2116
  });
@@ -1879,10 +2118,11 @@ var defaultCodeFromUrl = (invitationType, text) => {
1879
2118
  }
1880
2119
  };
1881
2120
  var useJoinMachine = (client, options) => {
1882
- const redeemHaloInvitationCode = useCallback5(({ halo }) => {
2121
+ const redeemHaloInvitationCode = useCallback6(({ halo }) => {
1883
2122
  if (halo.unredeemedCode) {
1884
2123
  try {
1885
- const invitationObservable = client.halo.join(InvitationEncoder2.decode(defaultCodeFromUrl("halo", halo.unredeemedCode)));
2124
+ const invitation = InvitationEncoder3.decode(defaultCodeFromUrl("halo", halo.unredeemedCode));
2125
+ const invitationObservable = client.halo.join(invitation);
1886
2126
  return {
1887
2127
  ...halo,
1888
2128
  invitationObservable,
@@ -1890,8 +2130,8 @@ var useJoinMachine = (client, options) => {
1890
2130
  };
1891
2131
  } catch (err) {
1892
2132
  log4.error("Could not redeem device invitation code", err, {
1893
- F: __dxlog_file4,
1894
- L: 449,
2133
+ F: __dxlog_file5,
2134
+ L: 454,
1895
2135
  S: void 0,
1896
2136
  C: (f, a) => f(...a)
1897
2137
  });
@@ -1903,27 +2143,20 @@ var useJoinMachine = (client, options) => {
1903
2143
  }, [
1904
2144
  client
1905
2145
  ]);
1906
- const redeemSpaceInvitationCode = useCallback5(({ space }) => {
2146
+ const redeemSpaceInvitationCode = useCallback6(({ space }) => {
1907
2147
  if (space.unredeemedCode) {
1908
2148
  try {
1909
- const invitation = InvitationEncoder2.decode(defaultCodeFromUrl("space", space.unredeemedCode));
1910
- if (space.succeededKeys?.has(invitation.spaceKey?.toHex() ?? "never")) {
1911
- return {
1912
- ...space,
1913
- invitation
1914
- };
1915
- } else {
1916
- const invitationObservable = client.spaces.join(invitation);
1917
- return {
1918
- ...space,
1919
- invitationObservable,
1920
- invitationSubscribable: getInvitationSubscribable("Space", invitationObservable)
1921
- };
1922
- }
2149
+ const invitation = InvitationEncoder3.decode(defaultCodeFromUrl("space", space.unredeemedCode));
2150
+ const invitationObservable = client.spaces.join(invitation);
2151
+ return {
2152
+ ...space,
2153
+ invitationObservable,
2154
+ invitationSubscribable: getInvitationSubscribable("Space", invitationObservable)
2155
+ };
1923
2156
  } catch (err) {
1924
2157
  log4.error("Could not redeem space invitation code", err, {
1925
- F: __dxlog_file4,
1926
- L: 479,
2158
+ F: __dxlog_file5,
2159
+ L: 476,
1927
2160
  S: void 0,
1928
2161
  C: (f, a) => f(...a)
1929
2162
  });
@@ -1935,7 +2168,7 @@ var useJoinMachine = (client, options) => {
1935
2168
  }, [
1936
2169
  client
1937
2170
  ]);
1938
- const invalidateHaloInvitationCode = useCallback5(({ halo }) => {
2171
+ const invalidateHaloInvitationCode = useCallback6(({ halo }) => {
1939
2172
  if (halo.unredeemedCode) {
1940
2173
  options?.onInvalidateInvitationCode?.(halo.unredeemedCode);
1941
2174
  return {
@@ -1948,7 +2181,7 @@ var useJoinMachine = (client, options) => {
1948
2181
  }, [
1949
2182
  options?.onInvalidateInvitationCode
1950
2183
  ]);
1951
- const invalidateSpaceInvitationCode = useCallback5(({ space }) => {
2184
+ const invalidateSpaceInvitationCode = useCallback6(({ space }) => {
1952
2185
  if (space.unredeemedCode) {
1953
2186
  options?.onInvalidateInvitationCode?.(space.unredeemedCode);
1954
2187
  return {
@@ -1983,17 +2216,17 @@ var useJoinMachine = (client, options) => {
1983
2216
 
1984
2217
  // packages/sdk/shell/src/panels/JoinPanel/steps/AdditionMethodChooser.tsx
1985
2218
  import { CaretRight as CaretRight2, Plus as Plus2, QrCode, Textbox } from "@phosphor-icons/react";
1986
- import React27 from "react";
1987
- import { useTranslation as useTranslation13 } from "@dxos/react-ui";
1988
- import { getSize as getSize9 } from "@dxos/react-ui-theme";
2219
+ import React29 from "react";
2220
+ import { useTranslation as useTranslation15 } from "@dxos/react-ui";
2221
+ import { getSize as getSize10 } from "@dxos/react-ui-theme";
1989
2222
  var AdditionMethodChooser = (viewStateProps) => {
1990
2223
  const disabled = !viewStateProps.active;
1991
2224
  const { send } = viewStateProps;
1992
- const { t } = useTranslation13("os");
2225
+ const { t } = useTranslation15("os");
1993
2226
  const sharedButtonProps = {
1994
2227
  disabled,
1995
- after: /* @__PURE__ */ React27.createElement(CaretRight2, {
1996
- className: getSize9(4),
2228
+ after: /* @__PURE__ */ React29.createElement(CaretRight2, {
2229
+ className: getSize10(4),
1997
2230
  weight: "bold"
1998
2231
  }),
1999
2232
  slots: {
@@ -2002,77 +2235,77 @@ var AdditionMethodChooser = (viewStateProps) => {
2002
2235
  }
2003
2236
  }
2004
2237
  };
2005
- return /* @__PURE__ */ React27.createElement(React27.Fragment, null, /* @__PURE__ */ React27.createElement(StepHeading, null, t("addition method chooser title")), /* @__PURE__ */ React27.createElement("div", {
2238
+ return /* @__PURE__ */ React29.createElement(React29.Fragment, null, /* @__PURE__ */ React29.createElement(StepHeading, null, t("addition method chooser title")), /* @__PURE__ */ React29.createElement("div", {
2006
2239
  role: "none",
2007
2240
  className: "flex flex-col gap-1 grow"
2008
- }, /* @__PURE__ */ React27.createElement(CompoundButton, {
2241
+ }, /* @__PURE__ */ React29.createElement(CompoundButton, {
2009
2242
  ...sharedButtonProps,
2010
2243
  description: t("create identity description"),
2011
- before: /* @__PURE__ */ React27.createElement(Plus2, {
2012
- className: getSize9(6)
2244
+ before: /* @__PURE__ */ React29.createElement(Plus2, {
2245
+ className: getSize10(6)
2013
2246
  }),
2014
2247
  onClick: () => send({
2015
2248
  type: "createIdentity"
2016
2249
  }),
2017
2250
  "data-autofocus": "choosingAuthMethod",
2018
- "data-testid": "create-identity"
2019
- }, t("create identity label")), /* @__PURE__ */ React27.createElement(CompoundButton, {
2251
+ "data-testid": "identity-chooser.create-identity"
2252
+ }, t("create identity label")), /* @__PURE__ */ React29.createElement(CompoundButton, {
2020
2253
  ...sharedButtonProps,
2021
2254
  description: t("join identity description"),
2022
- before: /* @__PURE__ */ React27.createElement(QrCode, {
2023
- className: getSize9(6)
2255
+ before: /* @__PURE__ */ React29.createElement(QrCode, {
2256
+ className: getSize10(6)
2024
2257
  }),
2025
2258
  onClick: () => send({
2026
2259
  type: "acceptHaloInvitation"
2027
2260
  }),
2028
- "data-testid": "join-identity"
2029
- }, t("join identity label")), /* @__PURE__ */ React27.createElement(CompoundButton, {
2261
+ "data-testid": "identity-chooser.join-identity"
2262
+ }, t("join identity label")), /* @__PURE__ */ React29.createElement(CompoundButton, {
2030
2263
  ...sharedButtonProps,
2031
2264
  // TODO(mykola): Implement recover.
2032
2265
  disabled: true,
2033
2266
  description: t("recover identity description"),
2034
- before: /* @__PURE__ */ React27.createElement(Textbox, {
2035
- className: getSize9(6)
2267
+ before: /* @__PURE__ */ React29.createElement(Textbox, {
2268
+ className: getSize10(6)
2036
2269
  }),
2037
2270
  onClick: () => send({
2038
2271
  type: "recoverIdentity"
2039
2272
  }),
2040
- "data-testid": "recover-identity"
2273
+ "data-testid": "identity-chooser.recover-identity"
2041
2274
  }, t("recover identity label"))));
2042
2275
  };
2043
2276
 
2044
2277
  // packages/sdk/shell/src/panels/JoinPanel/steps/IdentityAdded.tsx
2045
- import React28, { cloneElement as cloneElement2 } from "react";
2278
+ import React30, { cloneElement as cloneElement2 } from "react";
2046
2279
  import { generateName as generateName3 } from "@dxos/display-name";
2047
- import { Avatar as Avatar5, useId as useId6, useJdenticonHref as useJdenticonHref4, useTranslation as useTranslation14 } from "@dxos/react-ui";
2048
- import { mx as mx20 } from "@dxos/react-ui-theme";
2280
+ import { Avatar as Avatar5, useId as useId6, useJdenticonHref as useJdenticonHref4, useTranslation as useTranslation16 } from "@dxos/react-ui";
2281
+ import { mx as mx21 } from "@dxos/react-ui-theme";
2049
2282
  var IdentityAdded = (props) => {
2050
2283
  const { mode, addedIdentity, active, send, onDone, doneActionParent } = props;
2051
2284
  const disabled = !active;
2052
- const { t } = useTranslation14("os");
2285
+ const { t } = useTranslation16("os");
2053
2286
  const fallbackValue = addedIdentity?.identityKey.toHex();
2054
2287
  const labelId = useId6("identityListItem__label");
2055
2288
  const jdenticon = useJdenticonHref4(fallbackValue ?? "", 12);
2056
2289
  const displayName = addedIdentity?.profile?.displayName ?? (addedIdentity && generateName3(addedIdentity?.identityKey.toHex()));
2057
- const doneAction = /* @__PURE__ */ React28.createElement(Action, {
2290
+ const doneAction = /* @__PURE__ */ React30.createElement(Action, {
2058
2291
  ...onDone && {
2059
2292
  onClick: () => onDone(null)
2060
2293
  },
2061
2294
  disabled,
2062
2295
  "data-autofocus": "confirmingAddedIdentity",
2063
2296
  "data-testid": "identity-added-done"
2064
- }, /* @__PURE__ */ React28.createElement("span", null, t("done label")));
2065
- return /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(StepHeading, null, t("identity added label")), /* @__PURE__ */ React28.createElement("div", {
2297
+ }, /* @__PURE__ */ React30.createElement("span", null, t("done label")));
2298
+ return /* @__PURE__ */ React30.createElement(React30.Fragment, null, /* @__PURE__ */ React30.createElement(StepHeading, null, t("identity added label")), /* @__PURE__ */ React30.createElement("div", {
2066
2299
  role: "none",
2067
2300
  className: "grow flex flex-col items-center justify-center text-center gap-2"
2068
- }, /* @__PURE__ */ React28.createElement(Avatar5.Root, {
2301
+ }, /* @__PURE__ */ React30.createElement(Avatar5.Root, {
2069
2302
  status: "active",
2070
2303
  labelId
2071
- }, /* @__PURE__ */ React28.createElement(Avatar5.Frame, null, /* @__PURE__ */ React28.createElement(Avatar5.Fallback, {
2304
+ }, /* @__PURE__ */ React30.createElement(Avatar5.Frame, null, /* @__PURE__ */ React30.createElement(Avatar5.Fallback, {
2072
2305
  href: jdenticon
2073
- })), /* @__PURE__ */ React28.createElement(Avatar5.Label, {
2074
- classNames: mx20("text-lg truncate", !addedIdentity?.profile?.displayName && "font-mono")
2075
- }, displayName))), /* @__PURE__ */ React28.createElement(Actions, null, mode === "halo-only" ? doneActionParent ? /* @__PURE__ */ cloneElement2(doneActionParent, {}, doneAction) : doneAction : /* @__PURE__ */ React28.createElement(Action, {
2306
+ })), /* @__PURE__ */ React30.createElement(Avatar5.Label, {
2307
+ classNames: mx21("text-lg truncate", !addedIdentity?.profile?.displayName && "font-mono")
2308
+ }, displayName))), /* @__PURE__ */ React30.createElement(Actions, null, mode === "halo-only" ? doneActionParent ? /* @__PURE__ */ cloneElement2(doneActionParent, {}, doneAction) : doneAction : /* @__PURE__ */ React30.createElement(Action, {
2076
2309
  variant: "primary",
2077
2310
  disabled: disabled || !addedIdentity,
2078
2311
  onClick: () => addedIdentity && send({
@@ -2084,17 +2317,17 @@ var IdentityAdded = (props) => {
2084
2317
  };
2085
2318
 
2086
2319
  // packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx
2087
- import React29, { useState as useState4 } from "react";
2320
+ import React31, { useState as useState5 } from "react";
2088
2321
  import { log as log5 } from "@dxos/log";
2089
2322
  import { useClient as useClient4 } from "@dxos/react-client";
2090
- import { useTranslation as useTranslation15 } from "@dxos/react-ui";
2091
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx";
2323
+ import { useTranslation as useTranslation17 } from "@dxos/react-ui";
2324
+ var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/IdentityInput.tsx";
2092
2325
  var IdentityInput = (props) => {
2093
2326
  const { send, method } = props;
2094
2327
  const isRecover = method === "recover identity";
2095
2328
  const client = useClient4();
2096
- const { t } = useTranslation15("os");
2097
- const [validationMessage, setValidationMessage] = useState4("");
2329
+ const { t } = useTranslation17("os");
2330
+ const [validationMessage, setValidationMessage] = useState5("");
2098
2331
  const createIdentity = (displayName) => {
2099
2332
  void client.halo.createIdentity({
2100
2333
  [isRecover ? "seedphrase" : "displayName"]: displayName
@@ -2105,7 +2338,7 @@ var IdentityInput = (props) => {
2105
2338
  });
2106
2339
  }, (error) => {
2107
2340
  log5.catch(error, void 0, {
2108
- F: __dxlog_file5,
2341
+ F: __dxlog_file6,
2109
2342
  L: 37,
2110
2343
  S: void 0,
2111
2344
  C: (f, a) => f(...a)
@@ -2113,7 +2346,7 @@ var IdentityInput = (props) => {
2113
2346
  setValidationMessage(t(isRecover ? "failed to recover identity message" : "failed to create identity message"));
2114
2347
  });
2115
2348
  };
2116
- return /* @__PURE__ */ React29.createElement(IdentityInputImpl, {
2349
+ return /* @__PURE__ */ React31.createElement(IdentityInputImpl, {
2117
2350
  ...props,
2118
2351
  onDisplayNameConfirm: createIdentity,
2119
2352
  validationMessage
@@ -2122,27 +2355,27 @@ var IdentityInput = (props) => {
2122
2355
  var IdentityInputImpl = (props) => {
2123
2356
  const { method, send, active, onDisplayNameConfirm, validationMessage } = props;
2124
2357
  const disabled = !active;
2125
- const { t } = useTranslation15("os");
2126
- const [inputValue, setInputValue] = useState4("");
2358
+ const { t } = useTranslation17("os");
2359
+ const [inputValue, setInputValue] = useState5("");
2127
2360
  const isRecover = method === "recover identity";
2128
- return /* @__PURE__ */ React29.createElement(React29.Fragment, null, /* @__PURE__ */ React29.createElement("div", {
2361
+ return /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement("div", {
2129
2362
  role: "none",
2130
2363
  className: "grow flex flex-col justify-center"
2131
- }, /* @__PURE__ */ React29.createElement(Input, {
2364
+ }, /* @__PURE__ */ React31.createElement(Input, {
2132
2365
  validationMessage,
2133
- label: /* @__PURE__ */ React29.createElement(StepHeading, null, t(isRecover ? "recover identity input label" : "new identity input label")),
2366
+ label: /* @__PURE__ */ React31.createElement(StepHeading, null, t(isRecover ? "recover identity input label" : "new identity input label")),
2134
2367
  disabled,
2135
2368
  "data-testid": "identity-input",
2136
2369
  placeholder: isRecover ? "Type your recovery phrase" : "Type a display name",
2137
2370
  onChange: ({ target: { value } }) => setInputValue(value)
2138
- })), /* @__PURE__ */ React29.createElement(Actions, null, /* @__PURE__ */ React29.createElement(Action, {
2371
+ })), /* @__PURE__ */ React31.createElement(Actions, null, /* @__PURE__ */ React31.createElement(Action, {
2139
2372
  variant: "ghost",
2140
2373
  disabled,
2141
2374
  onClick: () => send?.({
2142
2375
  type: "deselectAuthMethod"
2143
2376
  }),
2144
2377
  "data-testid": `${method === "recover identity" ? "recover" : "create"}-identity-input-back`
2145
- }, t("back label")), /* @__PURE__ */ React29.createElement(Action, {
2378
+ }, t("back label")), /* @__PURE__ */ React31.createElement(Action, {
2146
2379
  variant: "primary",
2147
2380
  disabled,
2148
2381
  onClick: () => onDisplayNameConfirm?.(inputValue),
@@ -2151,32 +2384,32 @@ var IdentityInputImpl = (props) => {
2151
2384
  };
2152
2385
 
2153
2386
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationAccepted.tsx
2154
- import React30, { cloneElement as cloneElement3 } from "react";
2155
- import { useTranslation as useTranslation16 } from "@dxos/react-ui";
2387
+ import React32, { cloneElement as cloneElement3 } from "react";
2388
+ import { useTranslation as useTranslation18 } from "@dxos/react-ui";
2156
2389
  var InvitationAccepted = (props) => {
2157
2390
  const { active, Kind, doneActionParent, onDone } = props;
2158
2391
  const disabled = !active;
2159
- const { t } = useTranslation16("os");
2160
- const doneAction = /* @__PURE__ */ React30.createElement(Action, {
2392
+ const { t } = useTranslation18("os");
2393
+ const doneAction = /* @__PURE__ */ React32.createElement(Action, {
2161
2394
  variant: "primary",
2162
2395
  onClick: onDone,
2163
2396
  disabled,
2164
2397
  "data-autofocus": `success${Kind}Invitation finishingJoining${Kind}`,
2165
2398
  "data-testid": `${Kind.toLowerCase()}-invitation-accepted-done`
2166
2399
  }, t("done label"));
2167
- return /* @__PURE__ */ React30.createElement(React30.Fragment, null, /* @__PURE__ */ React30.createElement("div", {
2400
+ return /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement("div", {
2168
2401
  role: "none",
2169
2402
  className: "grow flex flex-col justify-center"
2170
- }, /* @__PURE__ */ React30.createElement("p", {
2403
+ }, /* @__PURE__ */ React32.createElement("p", {
2171
2404
  className: "text-center text-sm font-normal"
2172
- }, t("welcome message"))), /* @__PURE__ */ React30.createElement(Actions, null, doneActionParent ? /* @__PURE__ */ cloneElement3(doneActionParent, {}, doneAction) : doneAction));
2405
+ }, t("welcome message"))), /* @__PURE__ */ React32.createElement(Actions, null, doneActionParent ? /* @__PURE__ */ cloneElement3(doneActionParent, {}, doneAction) : doneAction));
2173
2406
  };
2174
2407
 
2175
2408
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx
2176
- import React31, { useState as useState5, useEffect as useEffect3, cloneElement as cloneElement4 } from "react";
2409
+ import React33, { useState as useState6, useEffect as useEffect4, cloneElement as cloneElement4 } from "react";
2177
2410
  import { log as log6 } from "@dxos/log";
2178
- import { useTranslation as useTranslation17 } from "@dxos/react-ui";
2179
- var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx";
2411
+ import { useTranslation as useTranslation19 } from "@dxos/react-ui";
2412
+ var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/InvitationInput.tsx";
2180
2413
  var invitationCodeFromUrl = (text) => {
2181
2414
  try {
2182
2415
  const searchParams = new URLSearchParams(text.substring(text.lastIndexOf("?")));
@@ -2184,7 +2417,7 @@ var invitationCodeFromUrl = (text) => {
2184
2417
  return invitation ?? text;
2185
2418
  } catch (err) {
2186
2419
  log6.catch(err, void 0, {
2187
- F: __dxlog_file6,
2420
+ F: __dxlog_file7,
2188
2421
  L: 25,
2189
2422
  S: void 0,
2190
2423
  C: (f, a) => f(...a)
@@ -2195,21 +2428,26 @@ var invitationCodeFromUrl = (text) => {
2195
2428
  var InvitationInput = (props) => {
2196
2429
  const { Kind, active, send, unredeemedCode, onExit, exitActionParent, onDone, doneActionParent, succeededKeys } = props;
2197
2430
  const disabled = !active;
2198
- const { t } = useTranslation17("os");
2199
- const [inputValue, setInputValue] = useState5(unredeemedCode ?? "");
2200
- useEffect3(() => {
2431
+ const { t } = useTranslation19("os");
2432
+ const [inputValue, setInputValue] = useState6(unredeemedCode ?? "");
2433
+ useEffect4(() => {
2201
2434
  unredeemedCode && setInputValue(unredeemedCode ?? "");
2202
2435
  }, [
2203
2436
  unredeemedCode
2204
2437
  ]);
2205
- const handleNext = () => send({
2206
- type: `set${Kind}InvitationCode`,
2207
- code: invitationCodeFromUrl(inputValue),
2208
- ...Kind === "Space" && {
2209
- succeededKeys
2438
+ const handleNext = () => {
2439
+ if (inputValue.trim().length === 0) {
2440
+ return;
2210
2441
  }
2211
- });
2212
- const exitAction = /* @__PURE__ */ React31.createElement(Action, {
2442
+ send({
2443
+ type: `set${Kind}InvitationCode`,
2444
+ code: invitationCodeFromUrl(inputValue),
2445
+ ...Kind === "Space" && {
2446
+ succeededKeys
2447
+ }
2448
+ });
2449
+ };
2450
+ const exitAction = /* @__PURE__ */ React33.createElement(Action, {
2213
2451
  variant: "ghost",
2214
2452
  disabled,
2215
2453
  ...onExit ? {
@@ -2219,11 +2457,12 @@ var InvitationInput = (props) => {
2219
2457
  },
2220
2458
  "data-testid": "join-exit"
2221
2459
  }, t("cancel label"));
2222
- return /* @__PURE__ */ React31.createElement(React31.Fragment, null, /* @__PURE__ */ React31.createElement("div", {
2460
+ return /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement("div", {
2223
2461
  role: "none",
2224
2462
  className: "grow flex flex-col justify-center"
2225
- }, /* @__PURE__ */ React31.createElement(Input, {
2226
- label: /* @__PURE__ */ React31.createElement(StepHeading, null, t("invitation input label")),
2463
+ }, /* @__PURE__ */ React33.createElement(Input, {
2464
+ label: /* @__PURE__ */ React33.createElement(StepHeading, null, t("invitation input label")),
2465
+ // TODO(burdon): Translation.
2227
2466
  placeholder: "Type an invitation code",
2228
2467
  disabled,
2229
2468
  value: inputValue,
@@ -2231,14 +2470,14 @@ var InvitationInput = (props) => {
2231
2470
  "data-autofocus": `inputting${Kind}InvitationCode`,
2232
2471
  "data-testid": `${Kind.toLowerCase()}-invitation-input`,
2233
2472
  onKeyUp: ({ key }) => key === "Enter" && handleNext()
2234
- })), /* @__PURE__ */ React31.createElement(Actions, null, Kind === "Halo" ? /* @__PURE__ */ React31.createElement(Action, {
2473
+ })), /* @__PURE__ */ React33.createElement(Actions, null, Kind === "Halo" ? /* @__PURE__ */ React33.createElement(Action, {
2235
2474
  variant: "ghost",
2236
2475
  disabled,
2237
2476
  onClick: () => send({
2238
2477
  type: "deselectAuthMethod"
2239
2478
  }),
2240
2479
  "data-testid": `${Kind.toLowerCase()}-invitation-input-back`
2241
- }, t("back label")) : exitActionParent ? /* @__PURE__ */ cloneElement4(exitActionParent, {}, exitAction) : doneActionParent ? /* @__PURE__ */ cloneElement4(doneActionParent, {}, exitAction) : exitAction, /* @__PURE__ */ React31.createElement(Action, {
2480
+ }, t("back label")) : exitActionParent ? /* @__PURE__ */ cloneElement4(exitActionParent, {}, exitAction) : doneActionParent ? /* @__PURE__ */ cloneElement4(doneActionParent, {}, exitAction) : exitAction, /* @__PURE__ */ React33.createElement(Action, {
2242
2481
  variant: "primary",
2243
2482
  disabled,
2244
2483
  onClick: handleNext,
@@ -2247,8 +2486,8 @@ var InvitationInput = (props) => {
2247
2486
  };
2248
2487
 
2249
2488
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationRescuer.tsx
2250
- import React32 from "react";
2251
- import { useTranslation as useTranslation18 } from "@dxos/react-ui";
2489
+ import React34 from "react";
2490
+ import { useTranslation as useTranslation20 } from "@dxos/react-ui";
2252
2491
  import { descriptionText as descriptionText9 } from "@dxos/react-ui-theme";
2253
2492
  var InvitationActions = ({
2254
2493
  // `invitationState` does report correct state, but here we evaluate whether `failReason` is a better source of truth
@@ -2260,14 +2499,14 @@ var InvitationActions = ({
2260
2499
  Kind,
2261
2500
  failReason
2262
2501
  }) => {
2263
- const { t } = useTranslation18("os");
2502
+ const { t } = useTranslation20("os");
2264
2503
  if (failReason) {
2265
- return /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement(StepHeading, {
2504
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement(StepHeading, {
2266
2505
  className: descriptionText9
2267
- }, t(failReason === "timeout" ? "timeout status label" : failReason === "cancelled" ? "cancelled status label" : "error status label")), /* @__PURE__ */ React32.createElement("div", {
2506
+ }, t(failReason === "timeout" ? "timeout status label" : failReason === "cancelled" ? "cancelled status label" : "error status label")), /* @__PURE__ */ React34.createElement("div", {
2268
2507
  role: "none",
2269
2508
  className: "grow"
2270
- }), /* @__PURE__ */ React32.createElement(Actions, null, /* @__PURE__ */ React32.createElement(Action, {
2509
+ }), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2271
2510
  disabled: !active,
2272
2511
  onClick: () => send({
2273
2512
  type: `reset${Kind}Invitation`
@@ -2275,16 +2514,16 @@ var InvitationActions = ({
2275
2514
  "data-testid": "invitation-rescuer-reset"
2276
2515
  }, t("reset label"))));
2277
2516
  } else {
2278
- return /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement(StepHeading, {
2517
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement(StepHeading, {
2279
2518
  className: descriptionText9
2280
- }, t("connecting status label")), /* @__PURE__ */ React32.createElement("div", {
2519
+ }, t("connecting status label")), /* @__PURE__ */ React34.createElement("div", {
2281
2520
  role: "none",
2282
2521
  className: "grow"
2283
- }), /* @__PURE__ */ React32.createElement(Actions, null, /* @__PURE__ */ React32.createElement(Action, {
2522
+ }), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2284
2523
  disabled: true,
2285
2524
  classNames: "order-2",
2286
2525
  "data-testid": "next"
2287
- }, t("next label")), /* @__PURE__ */ React32.createElement(Action, {
2526
+ }, t("next label")), /* @__PURE__ */ React34.createElement(Action, {
2288
2527
  disabled: !active,
2289
2528
  onClick: onInvitationCancel,
2290
2529
  "data-testid": "invitation-rescuer-cancel"
@@ -2293,46 +2532,46 @@ var InvitationActions = ({
2293
2532
  };
2294
2533
  var InvitationRescuer = (props) => {
2295
2534
  const { Kind, invitationState, active, send } = props;
2296
- const { t } = useTranslation18("os");
2297
- return /* @__PURE__ */ React32.createElement(React32.Fragment, null, typeof invitationState === "undefined" ? /* @__PURE__ */ React32.createElement(React32.Fragment, null, /* @__PURE__ */ React32.createElement("div", {
2535
+ const { t } = useTranslation20("os");
2536
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, typeof invitationState === "undefined" ? /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement("div", {
2298
2537
  role: "none",
2299
2538
  className: "grow flex flex-col justify-center"
2300
- }, /* @__PURE__ */ React32.createElement(StepHeading, {
2539
+ }, /* @__PURE__ */ React34.createElement(StepHeading, {
2301
2540
  className: descriptionText9
2302
- }, "There was a problem joining the space")), /* @__PURE__ */ React32.createElement(Actions, null, /* @__PURE__ */ React32.createElement(Action, {
2541
+ }, "There was a problem joining the space")), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2303
2542
  disabled: !active,
2304
2543
  "data-testid": "invitation-rescuer-blank-reset",
2305
2544
  onClick: () => send({
2306
2545
  type: `reset${Kind}Invitation`
2307
2546
  })
2308
- }, t("reset label")))) : /* @__PURE__ */ React32.createElement(InvitationActions, props));
2547
+ }, t("reset label")))) : /* @__PURE__ */ React34.createElement(InvitationActions, props));
2309
2548
  };
2310
2549
 
2311
2550
  // packages/sdk/shell/src/panels/JoinPanel/steps/InvitationAuthenticator.tsx
2312
- import React33, { useState as useState6 } from "react";
2313
- import { Input as Input2, useTranslation as useTranslation19 } from "@dxos/react-ui";
2551
+ import React35, { useState as useState7 } from "react";
2552
+ import { Input as Input2, useTranslation as useTranslation21 } from "@dxos/react-ui";
2314
2553
  var pinLength = 6;
2315
2554
  var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, onInvitationAuthenticate, onInvitationCancel }) => {
2316
2555
  const disabled = !active || pending;
2317
- const { t } = useTranslation19("os");
2556
+ const { t } = useTranslation21("os");
2318
2557
  const invitationType = Kind.toLowerCase();
2319
- const [authCode, setAuthCode] = useState6("");
2558
+ const [authCode, setAuthCode] = useState7("");
2320
2559
  const onChange = ({ target: { value } }) => {
2321
2560
  setAuthCode(value);
2322
2561
  if (value.length === pinLength) {
2323
2562
  document.querySelector(`[data-autofocus-pinlength="${invitationType}"]`)?.focus();
2324
2563
  }
2325
2564
  };
2326
- return /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement("div", {
2565
+ return /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement("div", {
2327
2566
  role: "none",
2328
2567
  className: "grow flex flex-col justify-center"
2329
- }, invitationId && /* @__PURE__ */ React33.createElement(Emoji, {
2568
+ }, invitationId && /* @__PURE__ */ React35.createElement(Emoji, {
2330
2569
  text: toEmoji(invitationId)
2331
- }), /* @__PURE__ */ React33.createElement(Input2.Root, failed && {
2570
+ }), /* @__PURE__ */ React35.createElement(Input2.Root, failed && {
2332
2571
  validationValence: "error"
2333
- }, /* @__PURE__ */ React33.createElement(Input2.Label, {
2572
+ }, /* @__PURE__ */ React35.createElement(Input2.Label, {
2334
2573
  asChild: true
2335
- }, /* @__PURE__ */ React33.createElement(StepHeading, null, t("auth code input label"))), /* @__PURE__ */ React33.createElement(Input2.PinInput, {
2574
+ }, /* @__PURE__ */ React35.createElement(StepHeading, null, t("auth code input label"))), /* @__PURE__ */ React35.createElement(Input2.PinInput, {
2336
2575
  disabled,
2337
2576
  length: pinLength,
2338
2577
  onChange,
@@ -2343,14 +2582,14 @@ var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, on
2343
2582
  "data-prevent-ios-autofocus": true,
2344
2583
  "data-testid": `${invitationType}-auth-code-input`,
2345
2584
  "data-1p-ignore": true
2346
- }), failed && /* @__PURE__ */ React33.createElement(Input2.DescriptionAndValidation, {
2585
+ }), failed && /* @__PURE__ */ React35.createElement(Input2.DescriptionAndValidation, {
2347
2586
  classNames: "text-center"
2348
- }, /* @__PURE__ */ React33.createElement(Input2.Validation, null, t("failed to authenticate message"))))), /* @__PURE__ */ React33.createElement(Actions, null, /* @__PURE__ */ React33.createElement(Action, {
2587
+ }, /* @__PURE__ */ React35.createElement(Input2.Validation, null, t("failed to authenticate message"))))), /* @__PURE__ */ React35.createElement(Actions, null, /* @__PURE__ */ React35.createElement(Action, {
2349
2588
  variant: "ghost",
2350
2589
  disabled,
2351
2590
  onClick: () => onInvitationCancel?.(),
2352
2591
  "data-testid": `${invitationType}-invitation-authenticator-cancel`
2353
- }, t("cancel label")), /* @__PURE__ */ React33.createElement(Action, {
2592
+ }, t("cancel label")), /* @__PURE__ */ React35.createElement(Action, {
2354
2593
  variant: "primary",
2355
2594
  disabled,
2356
2595
  onClick: () => onInvitationAuthenticate?.(authCode),
@@ -2360,21 +2599,21 @@ var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, on
2360
2599
  };
2361
2600
 
2362
2601
  // packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx
2363
- import React34, { useState as useState7 } from "react";
2602
+ import React36, { useState as useState8 } from "react";
2364
2603
  import { log as log7 } from "@dxos/log";
2365
2604
  import { useClient as useClient5 } from "@dxos/react-client";
2366
- import { useTranslation as useTranslation20 } from "@dxos/react-ui";
2367
- var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx";
2605
+ import { useTranslation as useTranslation22 } from "@dxos/react-ui";
2606
+ var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/steps/ResetIdentity.tsx";
2368
2607
  var ResetIdentity = ({ send, active }) => {
2369
2608
  const client = useClient5();
2370
- const { t } = useTranslation20("os");
2371
- const [validationMessage, setValidationMessage] = useState7("");
2609
+ const { t } = useTranslation22("os");
2610
+ const [validationMessage, setValidationMessage] = useState8("");
2372
2611
  const resetIdentity = () => {
2373
2612
  void client.reset().then(() => send?.({
2374
2613
  type: "resetIdentity"
2375
2614
  }), (error) => {
2376
2615
  log7.catch(error, void 0, {
2377
- F: __dxlog_file7,
2616
+ F: __dxlog_file8,
2378
2617
  L: 32,
2379
2618
  S: void 0,
2380
2619
  C: (f, a) => f(...a)
@@ -2382,29 +2621,29 @@ var ResetIdentity = ({ send, active }) => {
2382
2621
  setValidationMessage(t("failed to reset identity message"));
2383
2622
  });
2384
2623
  };
2385
- return /* @__PURE__ */ React34.createElement(ResetIdentityImpl, {
2624
+ return /* @__PURE__ */ React36.createElement(ResetIdentityImpl, {
2386
2625
  disabled: !active,
2387
2626
  validationMessage,
2388
2627
  onConfirm: () => resetIdentity()
2389
2628
  });
2390
2629
  };
2391
2630
  var ResetIdentityImpl = ({ disabled, validationMessage, onConfirm }) => {
2392
- const { t } = useTranslation20("os");
2631
+ const { t } = useTranslation22("os");
2393
2632
  const confirmationValue = t("confirmation value");
2394
- const [inputValue, setInputValue] = useState7("");
2395
- return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement("div", {
2633
+ const [inputValue, setInputValue] = useState8("");
2634
+ return /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement("div", {
2396
2635
  role: "none",
2397
2636
  className: "grow flex flex-col justify-center"
2398
- }, /* @__PURE__ */ React34.createElement(Input, {
2637
+ }, /* @__PURE__ */ React36.createElement(Input, {
2399
2638
  validationMessage,
2400
- label: /* @__PURE__ */ React34.createElement(StepHeading, null, t("reset identity input label", {
2639
+ label: /* @__PURE__ */ React36.createElement(StepHeading, null, t("reset identity input label", {
2401
2640
  confirmationValue
2402
2641
  })),
2403
2642
  disabled,
2404
- "data-testid": "identity-input",
2643
+ "data-testid": "reset-identity-input",
2405
2644
  placeholder: confirmationValue,
2406
2645
  onChange: ({ target: { value } }) => setInputValue(value)
2407
- })), /* @__PURE__ */ React34.createElement(Actions, null, /* @__PURE__ */ React34.createElement(Action, {
2646
+ })), /* @__PURE__ */ React36.createElement(Actions, null, /* @__PURE__ */ React36.createElement(Action, {
2408
2647
  // TODO(wittjosiah): Probably make this red?
2409
2648
  variant: "primary",
2410
2649
  disabled: disabled || inputValue !== confirmationValue,
@@ -2417,7 +2656,7 @@ var ResetIdentityImpl = ({ disabled, validationMessage, onConfirm }) => {
2417
2656
  var stepStyles = "pbs-1 pbe-3 pli-3";
2418
2657
 
2419
2658
  // packages/sdk/shell/src/styles/invitationStatusStyles.ts
2420
- import { Invitation as Invitation6 } from "@dxos/react-client/invitations";
2659
+ import { Invitation as Invitation7 } from "@dxos/react-client/invitations";
2421
2660
  var inactiveBgColor = "bg-neutral-100 dark:bg-neutral-600";
2422
2661
  var activeBgColor = "bg-primary-500 dark:bg-primary-400";
2423
2662
  var successBgColor = "bg-success-500 dark:bg-success-400";
@@ -2433,55 +2672,55 @@ var activeStrokeColor = "stroke-primary-400 dark:stroke-primary-150";
2433
2672
  var successStrokeColor = "stroke-success-300 dark:stroke-primary-400";
2434
2673
  var errorStrokeColor = "stroke-error-300 dark:stroke-error-500";
2435
2674
  var cancelledStrokeColor = "stroke-warning-300 dark:stroke-warning-500";
2436
- var resolvedStrokeColor = (status) => status === Invitation6.State.ERROR ? errorStrokeColor : status === Invitation6.State.CANCELLED || status === Invitation6.State.TIMEOUT ? cancelledStrokeColor : successStrokeColor;
2437
- var resolvedBgColor = (status) => status === Invitation6.State.ERROR ? errorBgColor : status === Invitation6.State.CANCELLED || status === Invitation6.State.TIMEOUT ? cancelledBgColor : successBgColor;
2438
- var resolvedTextColor = (status) => status === Invitation6.State.ERROR ? errorTextColor : status === Invitation6.State.CANCELLED || status === Invitation6.State.TIMEOUT ? cancelledTextColor : successTextColor;
2675
+ var resolvedStrokeColor = (status) => status === Invitation7.State.ERROR ? errorStrokeColor : status === Invitation7.State.CANCELLED || status === Invitation7.State.TIMEOUT ? cancelledStrokeColor : successStrokeColor;
2676
+ var resolvedBgColor = (status) => status === Invitation7.State.ERROR ? errorBgColor : status === Invitation7.State.CANCELLED || status === Invitation7.State.TIMEOUT ? cancelledBgColor : successBgColor;
2677
+ var resolvedTextColor = (status) => status === Invitation7.State.ERROR ? errorTextColor : status === Invitation7.State.CANCELLED || status === Invitation7.State.TIMEOUT ? cancelledTextColor : successTextColor;
2439
2678
 
2440
2679
  // packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx
2441
- var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx";
2680
+ var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx";
2442
2681
  var JoinPanelImpl = (props) => {
2443
2682
  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;
2444
- return /* @__PURE__ */ React35.createElement(DensityProvider3, {
2683
+ return /* @__PURE__ */ React37.createElement(DensityProvider3, {
2445
2684
  density: "fine"
2446
- }, mode !== "halo-only" && /* @__PURE__ */ React35.createElement(JoinHeading, {
2685
+ }, mode !== "halo-only" && /* @__PURE__ */ React37.createElement(JoinHeading, {
2447
2686
  titleId,
2448
2687
  mode,
2449
2688
  onExit,
2450
2689
  exitActionParent
2451
- }), /* @__PURE__ */ React35.createElement(Viewport.Root, {
2690
+ }), /* @__PURE__ */ React37.createElement(Viewport.Root, {
2452
2691
  focusManaged: true,
2453
2692
  activeView
2454
- }, /* @__PURE__ */ React35.createElement(Viewport.Views, null, /* @__PURE__ */ React35.createElement(Viewport.View, {
2693
+ }, /* @__PURE__ */ React37.createElement(Viewport.Views, null, /* @__PURE__ */ React37.createElement(Viewport.View, {
2455
2694
  classNames: stepStyles,
2456
2695
  id: "addition method chooser"
2457
- }, /* @__PURE__ */ React35.createElement(AdditionMethodChooser, {
2696
+ }, /* @__PURE__ */ React37.createElement(AdditionMethodChooser, {
2458
2697
  send,
2459
2698
  active: activeView === "addition method chooser"
2460
- })), /* @__PURE__ */ React35.createElement(Viewport.View, {
2699
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2461
2700
  classNames: stepStyles,
2462
2701
  id: "reset identity confirmation"
2463
- }, /* @__PURE__ */ React35.createElement(ResetIdentityComponent, {
2702
+ }, /* @__PURE__ */ React37.createElement(ResetIdentityComponent, {
2464
2703
  send,
2465
2704
  method: "reset identity",
2466
2705
  active: activeView === "reset identity confirmation"
2467
- })), /* @__PURE__ */ React35.createElement(Viewport.View, {
2706
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2468
2707
  classNames: stepStyles,
2469
2708
  id: "create identity input"
2470
- }, /* @__PURE__ */ React35.createElement(IdentityInputComponent, {
2709
+ }, /* @__PURE__ */ React37.createElement(IdentityInputComponent, {
2471
2710
  send,
2472
2711
  method: "create identity",
2473
2712
  active: activeView === "create identity input"
2474
- })), /* @__PURE__ */ React35.createElement(Viewport.View, {
2713
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2475
2714
  classNames: stepStyles,
2476
2715
  id: "recover identity input"
2477
- }, /* @__PURE__ */ React35.createElement(IdentityInputComponent, {
2716
+ }, /* @__PURE__ */ React37.createElement(IdentityInputComponent, {
2478
2717
  send,
2479
2718
  method: "recover identity",
2480
2719
  active: activeView === "recover identity input"
2481
- })), /* @__PURE__ */ React35.createElement(Viewport.View, {
2720
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2482
2721
  classNames: stepStyles,
2483
2722
  id: "halo invitation input"
2484
- }, /* @__PURE__ */ React35.createElement(InvitationInput, {
2723
+ }, /* @__PURE__ */ React37.createElement(InvitationInput, {
2485
2724
  send,
2486
2725
  Kind: "Halo",
2487
2726
  active: activeView === "halo invitation input",
@@ -2491,20 +2730,20 @@ var JoinPanelImpl = (props) => {
2491
2730
  ...succeededKeys?.Halo && {
2492
2731
  succeededKeys: succeededKeys.Halo
2493
2732
  }
2494
- })), /* @__PURE__ */ React35.createElement(Viewport.View, {
2733
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2495
2734
  classNames: stepStyles,
2496
2735
  id: "halo invitation rescuer"
2497
- }, /* @__PURE__ */ React35.createElement(InvitationRescuer, {
2736
+ }, /* @__PURE__ */ React37.createElement(InvitationRescuer, {
2498
2737
  send,
2499
2738
  Kind: "Halo",
2500
2739
  active: activeView === "halo invitation rescuer",
2501
2740
  invitationState: invitationStates?.Halo,
2502
2741
  onInvitationCancel: onHaloInvitationCancel,
2503
2742
  failReason: failReasons?.Halo
2504
- })), /* @__PURE__ */ React35.createElement(Viewport.View, {
2743
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2505
2744
  classNames: stepStyles,
2506
2745
  id: "halo invitation authenticator"
2507
- }, /* @__PURE__ */ React35.createElement(InvitationAuthenticator, {
2746
+ }, /* @__PURE__ */ React37.createElement(InvitationAuthenticator, {
2508
2747
  send,
2509
2748
  Kind: "Halo",
2510
2749
  active: activeView === "halo invitation authenticator",
@@ -2513,28 +2752,28 @@ var JoinPanelImpl = (props) => {
2513
2752
  ...failed.has("Halo") && {
2514
2753
  failed: true
2515
2754
  }
2516
- })), /* @__PURE__ */ React35.createElement(Viewport.View, {
2755
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2517
2756
  classNames: stepStyles,
2518
2757
  id: "halo invitation accepted"
2519
- }, /* @__PURE__ */ React35.createElement(InvitationAccepted, {
2758
+ }, /* @__PURE__ */ React37.createElement(InvitationAccepted, {
2520
2759
  send,
2521
2760
  Kind: "Halo",
2522
2761
  active: activeView === "halo invitation accepted",
2523
2762
  doneActionParent,
2524
2763
  onDone: onHaloDone
2525
- })), /* @__PURE__ */ React35.createElement(Viewport.View, {
2764
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2526
2765
  classNames: stepStyles,
2527
2766
  id: "identity added"
2528
- }, /* @__PURE__ */ React35.createElement(IdentityAdded, {
2767
+ }, /* @__PURE__ */ React37.createElement(IdentityAdded, {
2529
2768
  send,
2530
2769
  mode,
2531
2770
  active: activeView === "identity added",
2532
2771
  doneActionParent,
2533
2772
  onDone: onHaloDone
2534
- })), /* @__PURE__ */ React35.createElement(Viewport.View, {
2773
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2535
2774
  classNames: stepStyles,
2536
2775
  id: "space invitation input"
2537
- }, /* @__PURE__ */ React35.createElement(InvitationInput, {
2776
+ }, /* @__PURE__ */ React37.createElement(InvitationInput, {
2538
2777
  send,
2539
2778
  Kind: "Space",
2540
2779
  active: activeView === "space invitation input",
@@ -2546,20 +2785,20 @@ var JoinPanelImpl = (props) => {
2546
2785
  },
2547
2786
  onExit,
2548
2787
  exitActionParent
2549
- })), /* @__PURE__ */ React35.createElement(Viewport.View, {
2788
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2550
2789
  classNames: stepStyles,
2551
2790
  id: "space invitation rescuer"
2552
- }, /* @__PURE__ */ React35.createElement(InvitationRescuer, {
2791
+ }, /* @__PURE__ */ React37.createElement(InvitationRescuer, {
2553
2792
  send,
2554
2793
  Kind: "Space",
2555
2794
  active: activeView === "space invitation rescuer",
2556
2795
  invitationState: invitationStates?.Space,
2557
2796
  onInvitationCancel: onSpaceInvitationCancel,
2558
2797
  failReason: failReasons?.Space
2559
- })), /* @__PURE__ */ React35.createElement(Viewport.View, {
2798
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2560
2799
  classNames: stepStyles,
2561
2800
  id: "space invitation authenticator"
2562
- }, /* @__PURE__ */ React35.createElement(InvitationAuthenticator, {
2801
+ }, /* @__PURE__ */ React37.createElement(InvitationAuthenticator, {
2563
2802
  send,
2564
2803
  Kind: "Space",
2565
2804
  active: activeView === "space invitation authenticator",
@@ -2568,10 +2807,10 @@ var JoinPanelImpl = (props) => {
2568
2807
  ...failed.has("Space") && {
2569
2808
  failed: true
2570
2809
  }
2571
- })), /* @__PURE__ */ React35.createElement(Viewport.View, {
2810
+ })), /* @__PURE__ */ React37.createElement(Viewport.View, {
2572
2811
  classNames: stepStyles,
2573
2812
  id: "space invitation accepted"
2574
- }, /* @__PURE__ */ React35.createElement(InvitationAccepted, {
2813
+ }, /* @__PURE__ */ React37.createElement(InvitationAccepted, {
2575
2814
  send,
2576
2815
  Kind: "Space",
2577
2816
  active: activeView === "space invitation accepted",
@@ -2595,12 +2834,11 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
2595
2834
  }
2596
2835
  }
2597
2836
  });
2598
- console.log("[joinState]", joinState);
2599
- useEffect4(() => {
2837
+ useEffect5(() => {
2600
2838
  const subscription = joinService.subscribe((state) => {
2601
2839
  log8("[state]", state, {
2602
- F: __dxlog_file8,
2603
- L: 200,
2840
+ F: __dxlog_file9,
2841
+ L: 198,
2604
2842
  S: void 0,
2605
2843
  C: (f, a) => f(...a)
2606
2844
  });
@@ -2609,7 +2847,7 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
2609
2847
  }, [
2610
2848
  joinService
2611
2849
  ]);
2612
- useEffect4(() => {
2850
+ useEffect5(() => {
2613
2851
  const stateStack = joinState.configuration[0].id.split(".");
2614
2852
  const innermostState = stateStack[stateStack.length - 1];
2615
2853
  const autoFocusValue = innermostState === "finishingJoining" ? "successSpaceInvitation" : innermostState;
@@ -2790,27 +3028,29 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
2790
3028
  }), [
2791
3029
  joinState
2792
3030
  ]);
2793
- const onHaloDone = useCallback6(() => {
3031
+ const onHaloDone = useCallback7(() => {
2794
3032
  propsOnDone?.({
2795
3033
  identityKey: joinState.context.halo.invitation?.identityKey ?? null,
2796
3034
  swarmKey: joinState.context.halo.invitation?.swarmKey ?? null,
2797
- spaceKey: joinState.context.halo.invitation?.spaceKey ?? null
3035
+ spaceKey: joinState.context.halo.invitation?.spaceKey ?? null,
3036
+ target: joinState.context.halo.invitation?.target ?? null
2798
3037
  });
2799
3038
  }, [
2800
3039
  joinState,
2801
3040
  propsOnDone
2802
3041
  ]);
2803
- const onSpaceDone = useCallback6(() => {
3042
+ const onSpaceDone = useCallback7(() => {
2804
3043
  propsOnDone?.({
2805
3044
  identityKey: joinState.context.space.invitation?.identityKey ?? null,
2806
3045
  swarmKey: joinState.context.space.invitation?.swarmKey ?? null,
2807
- spaceKey: joinState.context.space.invitation?.spaceKey ?? null
3046
+ spaceKey: joinState.context.space.invitation?.spaceKey ?? null,
3047
+ target: joinState.context.space.invitation?.target ?? null
2808
3048
  });
2809
3049
  }, [
2810
3050
  joinState,
2811
3051
  propsOnDone
2812
3052
  ]);
2813
- return /* @__PURE__ */ React35.createElement(JoinPanelImpl, {
3053
+ return /* @__PURE__ */ React37.createElement(JoinPanelImpl, {
2814
3054
  titleId,
2815
3055
  mode,
2816
3056
  send: joinSend,
@@ -2849,16 +3089,16 @@ var JoinPanel = ({ titleId: propsTitleId, mode = "default", initialInvitationCod
2849
3089
 
2850
3090
  // packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx
2851
3091
  import { Planet } from "@phosphor-icons/react";
2852
- import React37, { useEffect as useEffect5, useMemo as useMemo5 } from "react";
3092
+ import React39, { useEffect as useEffect6, useMemo as useMemo5 } from "react";
2853
3093
  import { log as log10 } from "@dxos/log";
2854
3094
  import { useInvitationStatus as useInvitationStatus3 } from "@dxos/react-client/invitations";
2855
- import { DensityProvider as DensityProvider4, useId as useId8, useTranslation as useTranslation22 } from "@dxos/react-ui";
3095
+ import { DensityProvider as DensityProvider4, useId as useId8, useTranslation as useTranslation24 } from "@dxos/react-ui";
2856
3096
 
2857
3097
  // packages/sdk/shell/src/panels/SpacePanel/spaceMachine.ts
2858
3098
  import { useMachine as useMachine3 } from "@xstate/react";
2859
3099
  import { assign as assign3, createMachine as createMachine3 } from "xstate";
2860
3100
  import { log as log9 } from "@dxos/log";
2861
- var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/spaceMachine.ts";
3101
+ var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/spaceMachine.ts";
2862
3102
  var spaceMachine = createMachine3({
2863
3103
  id: "space",
2864
3104
  predictableActionArguments: true,
@@ -2899,7 +3139,7 @@ var spaceMachine = createMachine3({
2899
3139
  event,
2900
3140
  context
2901
3141
  }, {
2902
- F: __dxlog_file9,
3142
+ F: __dxlog_file10,
2903
3143
  L: 53,
2904
3144
  S: void 0,
2905
3145
  C: (f, a) => f(...a)
@@ -2918,21 +3158,21 @@ var useSpaceMachine = (options) => {
2918
3158
 
2919
3159
  // packages/sdk/shell/src/panels/SpacePanel/steps/SpaceManager.tsx
2920
3160
  import { Placeholder as Placeholder2, UserPlus, UsersThree } from "@phosphor-icons/react";
2921
- import React36, { useCallback as useCallback7, useState as useState8 } from "react";
3161
+ import React38, { useCallback as useCallback8, useState as useState9 } from "react";
2922
3162
  import { useConfig } from "@dxos/react-client";
2923
3163
  import { useSpaceInvitations as useSpaceInvitations2 } from "@dxos/react-client/echo";
2924
- import { Invitation as Invitation7, InvitationEncoder as InvitationEncoder3 } from "@dxos/react-client/invitations";
2925
- import { ScrollArea, useTranslation as useTranslation21 } from "@dxos/react-ui";
2926
- import { descriptionText as descriptionText10, mx as mx21 } from "@dxos/react-ui-theme";
3164
+ import { Invitation as Invitation8, InvitationEncoder as InvitationEncoder4 } from "@dxos/react-client/invitations";
3165
+ import { ScrollArea, useTranslation as useTranslation23 } from "@dxos/react-ui";
3166
+ import { descriptionText as descriptionText10, mx as mx22 } from "@dxos/react-ui-theme";
2927
3167
  var activeActionKey = "dxos:react-shell/space-manager/active-action";
2928
3168
  var SpaceManager = (props) => {
2929
- const { space } = props;
2930
- const { t } = useTranslation21("os");
3169
+ const { space, target } = props;
3170
+ const { t } = useTranslation23("os");
2931
3171
  const config = useConfig();
2932
3172
  const invitations = useSpaceInvitations2(space?.key);
2933
- const onInvitationEvent = useCallback7((invitation) => {
2934
- const invitationCode = InvitationEncoder3.encode(invitation);
2935
- if (invitation.state === Invitation7.State.CONNECTING) {
3173
+ const onInvitationEvent = useCallback8((invitation) => {
3174
+ const invitationCode = InvitationEncoder4.encode(invitation);
3175
+ if (invitation.state === Invitation8.State.CONNECTING) {
2936
3176
  console.log(JSON.stringify({
2937
3177
  invitationCode,
2938
3178
  authCode: invitation.authCode
@@ -2944,10 +3184,11 @@ var SpaceManager = (props) => {
2944
3184
  label: t("invite one label"),
2945
3185
  description: t("invite one description"),
2946
3186
  icon: UserPlus,
2947
- onClick: useCallback7(() => {
3187
+ onClick: useCallback8(() => {
2948
3188
  const invitation = space.share?.({
2949
- type: Invitation7.Type.INTERACTIVE,
2950
- authMethod: Invitation7.AuthMethod.SHARED_SECRET
3189
+ type: Invitation8.Type.INTERACTIVE,
3190
+ authMethod: Invitation8.AuthMethod.SHARED_SECRET,
3191
+ target
2951
3192
  });
2952
3193
  if (invitation && config.values.runtime?.app?.env?.DX_ENVIRONMENT !== "production") {
2953
3194
  invitation.subscribe(onInvitationEvent);
@@ -2960,10 +3201,11 @@ var SpaceManager = (props) => {
2960
3201
  label: t("invite many label"),
2961
3202
  description: t("invite many description"),
2962
3203
  icon: UsersThree,
2963
- onClick: useCallback7(() => {
3204
+ onClick: useCallback8(() => {
2964
3205
  const invitation = space.share?.({
2965
- type: Invitation7.Type.MULTIUSE,
2966
- authMethod: Invitation7.AuthMethod.NONE
3206
+ type: Invitation8.Type.MULTIUSE,
3207
+ authMethod: Invitation8.AuthMethod.NONE,
3208
+ target
2967
3209
  });
2968
3210
  if (invitation && config.values.runtime?.app?.env?.DX_ENVIRONMENT !== "production") {
2969
3211
  invitation.subscribe(onInvitationEvent);
@@ -2973,7 +3215,7 @@ var SpaceManager = (props) => {
2973
3215
  ])
2974
3216
  }
2975
3217
  };
2976
- return /* @__PURE__ */ React36.createElement(SpaceManagerImpl, {
3218
+ return /* @__PURE__ */ React38.createElement(SpaceManagerImpl, {
2977
3219
  ...props,
2978
3220
  invitations,
2979
3221
  inviteActions
@@ -2982,7 +3224,7 @@ var SpaceManager = (props) => {
2982
3224
  var headingFragment = "pis-3 pie-1 plb-1 mbe-1 font-medium";
2983
3225
  var SpaceManagerImpl = (props) => {
2984
3226
  const { active, space, createInvitationUrl, send, inviteActions: propsInviteActions, invitations, showInactiveInvitations, SpaceMemberList: SpaceMemberListComponent = SpaceMemberList, InvitationList: InvitationListComponent = InvitationList } = props;
2985
- const { t } = useTranslation21("os");
3227
+ const { t } = useTranslation23("os");
2986
3228
  const inviteActions = propsInviteActions ?? {
2987
3229
  noopInvite: {
2988
3230
  label: t("create space invitation label"),
@@ -2992,34 +3234,34 @@ var SpaceManagerImpl = (props) => {
2992
3234
  }
2993
3235
  }
2994
3236
  };
2995
- const [activeAction, setInternalActiveAction] = useState8(localStorage.getItem(activeActionKey) ?? "inviteOne");
3237
+ const [activeAction, setInternalActiveAction] = useState9(localStorage.getItem(activeActionKey) ?? "inviteOne");
2996
3238
  const setActiveAction = (nextAction) => {
2997
3239
  setInternalActiveAction(nextAction);
2998
3240
  localStorage.setItem(activeActionKey, nextAction);
2999
3241
  };
3000
3242
  const visibleInvitations = showInactiveInvitations ? invitations : invitations?.filter((invitation) => ![
3001
- Invitation7.State.CANCELLED
3243
+ Invitation8.State.CANCELLED
3002
3244
  ].includes(invitation.get().state));
3003
- return /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement(ScrollArea.Root, {
3245
+ return /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement(ScrollArea.Root, {
3004
3246
  classNames: "grow shrink basis-28 -mli-2"
3005
- }, /* @__PURE__ */ React36.createElement(ScrollArea.Viewport, {
3247
+ }, /* @__PURE__ */ React38.createElement(ScrollArea.Viewport, {
3006
3248
  classNames: "is-full pie-2"
3007
- }, !!visibleInvitations?.length && /* @__PURE__ */ React36.createElement(React36.Fragment, null, /* @__PURE__ */ React36.createElement("h3", {
3008
- className: mx21(headingFragment, descriptionText10)
3009
- }, t("invitation list heading")), /* @__PURE__ */ React36.createElement(InvitationListComponent, {
3249
+ }, !!visibleInvitations?.length && /* @__PURE__ */ React38.createElement(React38.Fragment, null, /* @__PURE__ */ React38.createElement("h3", {
3250
+ className: mx22(headingFragment, descriptionText10)
3251
+ }, t("invitation list heading")), /* @__PURE__ */ React38.createElement(InvitationListComponent, {
3010
3252
  className: "mb-2",
3011
3253
  send,
3012
3254
  invitations: visibleInvitations ?? [],
3013
3255
  onClickRemove: (invitation) => invitation.cancel(),
3014
3256
  createInvitationUrl
3015
- }), /* @__PURE__ */ React36.createElement("h3", {
3016
- className: mx21(headingFragment, descriptionText10, "mbs-2")
3017
- }, t("space member list heading"))), /* @__PURE__ */ React36.createElement(SpaceMemberListComponent, {
3257
+ }), /* @__PURE__ */ React38.createElement("h3", {
3258
+ className: mx22(headingFragment, descriptionText10, "mbs-2")
3259
+ }, t("space member list heading"))), /* @__PURE__ */ React38.createElement(SpaceMemberListComponent, {
3018
3260
  spaceKey: space.key,
3019
3261
  includeSelf: true
3020
- })), /* @__PURE__ */ React36.createElement(ScrollArea.Scrollbar, {
3262
+ })), /* @__PURE__ */ React38.createElement(ScrollArea.Scrollbar, {
3021
3263
  orientation: "vertical"
3022
- }, /* @__PURE__ */ React36.createElement(ScrollArea.Thumb, null))), /* @__PURE__ */ React36.createElement(Actions, null, /* @__PURE__ */ React36.createElement(BifurcatedAction, {
3264
+ }, /* @__PURE__ */ React38.createElement(ScrollArea.Thumb, null))), /* @__PURE__ */ React38.createElement(Actions, null, /* @__PURE__ */ React38.createElement(BifurcatedAction, {
3023
3265
  disabled: !active,
3024
3266
  actions: inviteActions,
3025
3267
  activeAction,
@@ -3029,47 +3271,48 @@ var SpaceManagerImpl = (props) => {
3029
3271
  };
3030
3272
 
3031
3273
  // packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx
3032
- var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx";
3274
+ var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/SpacePanel.tsx";
3033
3275
  var SpacePanelHeading = ({ titleId, space, onDone }) => {
3034
- const { t } = useTranslation22("os");
3276
+ const { t } = useTranslation24("os");
3035
3277
  const name = space.properties.name;
3036
- return /* @__PURE__ */ React37.createElement(Heading, {
3278
+ return /* @__PURE__ */ React39.createElement(Heading, {
3037
3279
  titleId,
3038
3280
  title: t("space panel heading"),
3039
- corner: /* @__PURE__ */ React37.createElement(CloseButton, {
3281
+ corner: /* @__PURE__ */ React39.createElement(CloseButton, {
3040
3282
  "data-testid": "identity-panel-done",
3041
3283
  onDone
3042
3284
  })
3043
- }, /* @__PURE__ */ React37.createElement("div", {
3285
+ }, /* @__PURE__ */ React39.createElement("div", {
3044
3286
  role: "none",
3045
3287
  className: "flex gap-4 items-center justify-center mlb-4"
3046
- }, /* @__PURE__ */ React37.createElement(Planet, {
3288
+ }, /* @__PURE__ */ React39.createElement(Planet, {
3047
3289
  size: 32
3048
- }), /* @__PURE__ */ React37.createElement("div", {
3290
+ }), /* @__PURE__ */ React39.createElement("div", {
3049
3291
  className: "block text-start font-light text-xl"
3050
3292
  }, name ?? space.key.truncate())));
3051
3293
  };
3052
3294
  var SpacePanelImpl = (props) => {
3053
- const { titleId, activeView, space, SpaceManager: SpaceManagerComponent = SpaceManager, InvitationManager: InvitationManagerComponent = InvitationManager, ...rest } = props;
3054
- return /* @__PURE__ */ React37.createElement(DensityProvider4, {
3295
+ const { titleId, activeView, space, target, SpaceManager: SpaceManagerComponent = SpaceManager, InvitationManager: InvitationManagerComponent = InvitationManager, ...rest } = props;
3296
+ return /* @__PURE__ */ React39.createElement(DensityProvider4, {
3055
3297
  density: "fine"
3056
- }, /* @__PURE__ */ React37.createElement(SpacePanelHeading, {
3298
+ }, /* @__PURE__ */ React39.createElement(SpacePanelHeading, {
3057
3299
  ...rest,
3058
3300
  titleId,
3059
3301
  space
3060
- }), /* @__PURE__ */ React37.createElement(Viewport.Root, {
3302
+ }), /* @__PURE__ */ React39.createElement(Viewport.Root, {
3061
3303
  activeView
3062
- }, /* @__PURE__ */ React37.createElement(Viewport.Views, null, /* @__PURE__ */ React37.createElement(Viewport.View, {
3304
+ }, /* @__PURE__ */ React39.createElement(Viewport.Views, null, /* @__PURE__ */ React39.createElement(Viewport.View, {
3063
3305
  id: "space manager",
3064
3306
  classNames: stepStyles
3065
- }, /* @__PURE__ */ React37.createElement(SpaceManagerComponent, {
3307
+ }, /* @__PURE__ */ React39.createElement(SpaceManagerComponent, {
3066
3308
  active: activeView === "space manager",
3067
3309
  space,
3310
+ target,
3068
3311
  ...rest
3069
- })), /* @__PURE__ */ React37.createElement(Viewport.View, {
3312
+ })), /* @__PURE__ */ React39.createElement(Viewport.View, {
3070
3313
  id: "space invitation manager",
3071
3314
  classNames: stepStyles
3072
- }, /* @__PURE__ */ React37.createElement(InvitationManagerComponent, {
3315
+ }, /* @__PURE__ */ React39.createElement(InvitationManagerComponent, {
3073
3316
  active: activeView === "space invitation manager",
3074
3317
  ...rest,
3075
3318
  invitationUrl: props.invitationUrl
@@ -3077,7 +3320,7 @@ var SpacePanelImpl = (props) => {
3077
3320
  };
3078
3321
  var SpacePanelWithInvitationImpl = ({ invitation, ...props }) => {
3079
3322
  const invitationStatus = useInvitationStatus3(invitation);
3080
- return /* @__PURE__ */ React37.createElement(SpacePanelImpl, {
3323
+ return /* @__PURE__ */ React39.createElement(SpacePanelImpl, {
3081
3324
  ...props,
3082
3325
  ...invitationStatus,
3083
3326
  invitationUrl: props.createInvitationUrl(invitationStatus.invitationCode)
@@ -3090,11 +3333,11 @@ var SpacePanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => code,
3090
3333
  space: props.space
3091
3334
  }
3092
3335
  });
3093
- useEffect5(() => {
3336
+ useEffect6(() => {
3094
3337
  const subscription = spaceService.subscribe((state) => {
3095
3338
  log10("[state]", state, {
3096
- F: __dxlog_file10,
3097
- L: 92,
3339
+ F: __dxlog_file11,
3340
+ L: 94,
3098
3341
  S: void 0,
3099
3342
  C: (f, a) => f(...a)
3100
3343
  });
@@ -3122,62 +3365,65 @@ var SpacePanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => code,
3122
3365
  titleId,
3123
3366
  createInvitationUrl
3124
3367
  };
3125
- return spaceState.context.invitation ? /* @__PURE__ */ React37.createElement(SpacePanelWithInvitationImpl, {
3126
- ...implProps,
3127
- invitation: spaceState.context.invitation
3128
- }) : /* @__PURE__ */ React37.createElement(SpacePanelImpl, implProps);
3368
+ return spaceState.context.invitation ? (
3369
+ // TODO(wittjosiah): Unused? Remove?
3370
+ /* @__PURE__ */ React39.createElement(SpacePanelWithInvitationImpl, {
3371
+ ...implProps,
3372
+ invitation: spaceState.context.invitation
3373
+ })
3374
+ ) : /* @__PURE__ */ React39.createElement(SpacePanelImpl, implProps);
3129
3375
  };
3130
3376
 
3131
3377
  // packages/sdk/shell/src/composites/IdentityDialog/IdentityDialog.tsx
3132
3378
  var IdentityDialog = (props) => {
3133
3379
  const titleId = useId9("spaceDialog__title");
3134
- return /* @__PURE__ */ React38.createElement(Dialog.Root, {
3380
+ return /* @__PURE__ */ React40.createElement(Dialog.Root, {
3135
3381
  defaultOpen: true,
3136
3382
  onOpenChange: (open) => open || props.onDone?.()
3137
- }, /* @__PURE__ */ React38.createElement(Dialog.Portal, null, /* @__PURE__ */ React38.createElement(Dialog.Overlay, null, /* @__PURE__ */ React38.createElement(Dialog.Content, {
3383
+ }, /* @__PURE__ */ React40.createElement(Dialog.Portal, null, /* @__PURE__ */ React40.createElement(Dialog.Overlay, null, /* @__PURE__ */ React40.createElement(Dialog.Content, {
3138
3384
  "aria-labelledby": titleId,
3139
3385
  onOpenAutoFocus: (e) => e.preventDefault()
3140
- }, /* @__PURE__ */ React38.createElement(ClipboardProvider, null, /* @__PURE__ */ React38.createElement(IdentityPanel, {
3386
+ }, /* @__PURE__ */ React40.createElement(ClipboardProvider, null, /* @__PURE__ */ React40.createElement(IdentityPanel, {
3141
3387
  ...props,
3142
3388
  titleId,
3143
- doneActionParent: /* @__PURE__ */ React38.createElement(Dialog.Close, {
3389
+ doneActionParent: /* @__PURE__ */ React40.createElement(Dialog.Close, {
3144
3390
  asChild: true
3145
3391
  })
3146
3392
  }))))));
3147
3393
  };
3148
3394
 
3149
3395
  // packages/sdk/shell/src/composites/JoinDialog/JoinDialog.tsx
3150
- import React39 from "react";
3396
+ import React41 from "react";
3151
3397
  import { AlertDialog, useId as useId10, useVisualViewport } from "@dxos/react-ui";
3152
3398
  var JoinDialog = (joinPanelProps) => {
3153
3399
  const titleId = useId10("joinDialog__title");
3154
3400
  const { height } = useVisualViewport();
3155
- return /* @__PURE__ */ React39.createElement(AlertDialog.Root, {
3401
+ return /* @__PURE__ */ React41.createElement(AlertDialog.Root, {
3156
3402
  defaultOpen: true,
3157
3403
  onOpenChange: (open) => open || (joinPanelProps.onExit ? joinPanelProps.onExit() : joinPanelProps.onDone?.(null))
3158
- }, /* @__PURE__ */ React39.createElement(AlertDialog.Portal, null, /* @__PURE__ */ React39.createElement(AlertDialog.Overlay, {
3404
+ }, /* @__PURE__ */ React41.createElement(AlertDialog.Portal, null, /* @__PURE__ */ React41.createElement(AlertDialog.Overlay, {
3159
3405
  classNames: "backdrop-blur",
3160
3406
  ...height && {
3161
3407
  style: {
3162
3408
  blockSize: `${height}px`
3163
3409
  }
3164
3410
  }
3165
- }, /* @__PURE__ */ React39.createElement(AlertDialog.Content, {
3411
+ }, /* @__PURE__ */ React41.createElement(AlertDialog.Content, {
3166
3412
  "aria-labelledby": titleId
3167
- }, /* @__PURE__ */ React39.createElement(JoinPanel, {
3413
+ }, /* @__PURE__ */ React41.createElement(JoinPanel, {
3168
3414
  ...joinPanelProps,
3169
3415
  titleId,
3170
- exitActionParent: /* @__PURE__ */ React39.createElement(AlertDialog.Cancel, {
3416
+ exitActionParent: /* @__PURE__ */ React41.createElement(AlertDialog.Cancel, {
3171
3417
  asChild: true
3172
3418
  }),
3173
- doneActionParent: /* @__PURE__ */ React39.createElement(AlertDialog.Action, {
3419
+ doneActionParent: /* @__PURE__ */ React41.createElement(AlertDialog.Action, {
3174
3420
  asChild: true
3175
3421
  })
3176
3422
  })))));
3177
3423
  };
3178
3424
 
3179
3425
  // packages/sdk/shell/src/composites/Shell/run-shell.tsx
3180
- import React42, { StrictMode } from "react";
3426
+ import React44, { StrictMode } from "react";
3181
3427
  import { createRoot } from "react-dom/client";
3182
3428
  import { DEFAULT_CLIENT_CHANNEL, DEFAULT_SHELL_CHANNEL } from "@dxos/client-protocol";
3183
3429
  import { ShellRuntimeImpl } from "@dxos/client-services";
@@ -3187,49 +3433,51 @@ import { defaultTx } from "@dxos/react-ui-theme";
3187
3433
  import { createIFramePort } from "@dxos/rpc-tunnel";
3188
3434
 
3189
3435
  // packages/sdk/shell/src/composites/Shell/Shell.tsx
3190
- import React41, { useEffect as useEffect6, useState as useState9 } from "react";
3436
+ import React43, { useEffect as useEffect7, useState as useState10 } from "react";
3191
3437
  import { log as log11 } from "@dxos/log";
3192
- import { ShellDisplay, ShellLayout } from "@dxos/react-client";
3438
+ import { ShellDisplay, ShellLayout, useClient as useClient7 } from "@dxos/react-client";
3193
3439
  import { useSpace as useSpace2 } from "@dxos/react-client/echo";
3194
3440
 
3195
3441
  // packages/sdk/shell/src/composites/SpaceDialog/SpaceDialog.tsx
3196
- import React40 from "react";
3442
+ import React42 from "react";
3197
3443
  import { Dialog as Dialog2, useId as useId11 } from "@dxos/react-ui";
3198
3444
  var SpaceDialog = (spacePanelProps) => {
3199
3445
  const titleId = useId11("spaceDialog__title");
3200
- return /* @__PURE__ */ React40.createElement(Dialog2.Root, {
3446
+ return /* @__PURE__ */ React42.createElement(Dialog2.Root, {
3201
3447
  defaultOpen: true,
3202
3448
  onOpenChange: (open) => open || spacePanelProps.onDone?.()
3203
- }, /* @__PURE__ */ React40.createElement(Dialog2.Portal, null, /* @__PURE__ */ React40.createElement(Dialog2.Overlay, null, /* @__PURE__ */ React40.createElement(Dialog2.Content, {
3449
+ }, /* @__PURE__ */ React42.createElement(Dialog2.Portal, null, /* @__PURE__ */ React42.createElement(Dialog2.Overlay, null, /* @__PURE__ */ React42.createElement(Dialog2.Content, {
3204
3450
  "aria-labelledby": titleId
3205
- }, /* @__PURE__ */ React40.createElement(ClipboardProvider, null, /* @__PURE__ */ React40.createElement(SpacePanel, {
3451
+ }, /* @__PURE__ */ React42.createElement(ClipboardProvider, null, /* @__PURE__ */ React42.createElement(SpacePanel, {
3206
3452
  ...spacePanelProps,
3207
3453
  titleId,
3208
- doneActionParent: /* @__PURE__ */ React40.createElement(Dialog2.Close, {
3454
+ doneActionParent: /* @__PURE__ */ React42.createElement(Dialog2.Close, {
3209
3455
  asChild: true
3210
3456
  })
3211
3457
  }))))));
3212
3458
  };
3213
3459
 
3214
3460
  // packages/sdk/shell/src/composites/Shell/Shell.tsx
3215
- var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/composites/Shell/Shell.tsx";
3461
+ var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/composites/Shell/Shell.tsx";
3216
3462
  var Shell = ({ runtime, origin }) => {
3217
- const [{ layout, invitationCode, spaceKey }, setLayout] = useState9({
3463
+ const [{ layout, invitationCode, spaceKey, target }, setLayout] = useState10({
3218
3464
  layout: runtime.layout,
3219
3465
  invitationCode: runtime.invitationCode,
3220
- spaceKey: runtime.spaceKey
3466
+ spaceKey: runtime.spaceKey,
3467
+ target: runtime.target
3221
3468
  });
3469
+ const client = useClient7();
3222
3470
  const space = useSpace2(spaceKey);
3223
- useEffect6(() => {
3471
+ useEffect7(() => {
3224
3472
  return runtime.layoutUpdate.on((request) => setLayout(request));
3225
3473
  }, [
3226
3474
  runtime
3227
3475
  ]);
3228
- useEffect6(() => {
3476
+ useEffect7(() => {
3229
3477
  if (layout === ShellLayout.SPACE && !space) {
3230
3478
  log11.warn("No space found for shell space invitations.", void 0, {
3231
- F: __dxlog_file11,
3232
- L: 30,
3479
+ F: __dxlog_file12,
3480
+ L: 32,
3233
3481
  S: void 0,
3234
3482
  C: (f, a) => f(...a)
3235
3483
  });
@@ -3250,7 +3498,7 @@ var Shell = ({ runtime, origin }) => {
3250
3498
  ]);
3251
3499
  switch (layout) {
3252
3500
  case ShellLayout.INITIALIZE_IDENTITY:
3253
- return /* @__PURE__ */ React41.createElement(JoinDialog, {
3501
+ return /* @__PURE__ */ React43.createElement(JoinDialog, {
3254
3502
  mode: "halo-only",
3255
3503
  initialInvitationCode: invitationCode,
3256
3504
  onDone: () => {
@@ -3265,8 +3513,18 @@ var Shell = ({ runtime, origin }) => {
3265
3513
  case ShellLayout.IDENTITY:
3266
3514
  case ShellLayout.SHARE_IDENTITY:
3267
3515
  case ShellLayout.EDIT_PROFILE:
3268
- return /* @__PURE__ */ React41.createElement(IdentityDialog, {
3516
+ return /* @__PURE__ */ React43.createElement(IdentityDialog, {
3269
3517
  createInvitationUrl: (invitationCode2) => `${origin}?deviceInvitationCode=${invitationCode2}`,
3518
+ onResetDevice: async () => {
3519
+ await client.reset();
3520
+ await runtime.setAppContext({
3521
+ display: ShellDisplay.NONE,
3522
+ reload: true
3523
+ });
3524
+ },
3525
+ onJoinNewIdentity: () => runtime.setLayout({
3526
+ layout: ShellLayout.INITIALIZE_IDENTITY
3527
+ }),
3270
3528
  onDone: async () => {
3271
3529
  await runtime.setAppContext({
3272
3530
  display: ShellDisplay.NONE
@@ -3277,8 +3535,9 @@ var Shell = ({ runtime, origin }) => {
3277
3535
  }
3278
3536
  });
3279
3537
  case ShellLayout.SPACE:
3280
- return space ? /* @__PURE__ */ React41.createElement(SpaceDialog, {
3538
+ return space ? /* @__PURE__ */ React43.createElement(SpaceDialog, {
3281
3539
  space,
3540
+ target,
3282
3541
  createInvitationUrl: (invitationCode2) => `${origin}?spaceInvitationCode=${invitationCode2}`,
3283
3542
  onDone: async () => {
3284
3543
  await runtime.setAppContext({
@@ -3290,12 +3549,14 @@ var Shell = ({ runtime, origin }) => {
3290
3549
  }
3291
3550
  }) : null;
3292
3551
  case ShellLayout.JOIN_SPACE:
3293
- return /* @__PURE__ */ React41.createElement(JoinDialog, {
3552
+ return /* @__PURE__ */ React43.createElement(JoinDialog, {
3294
3553
  initialInvitationCode: invitationCode,
3295
3554
  onDone: async (result) => {
3555
+ const target2 = result?.target ?? void 0;
3296
3556
  await runtime.setAppContext({
3297
3557
  display: ShellDisplay.NONE,
3298
- spaceKey: result?.spaceKey ?? void 0
3558
+ spaceKey: result?.spaceKey ?? void 0,
3559
+ target: target2
3299
3560
  });
3300
3561
  runtime.setLayout({
3301
3562
  layout: ShellLayout.DEFAULT
@@ -3415,7 +3676,12 @@ var os = {
3415
3676
  "confirm label": "Confirm",
3416
3677
  "reset identity input label": "This will clear this device and all associated data. Type {{confirmationValue}} and confirm to continue.",
3417
3678
  "failed to reset identity message": "Failed to reset identity.",
3418
- "confirmation value": "CONFIRM"
3679
+ "confirmation value": "CONFIRM",
3680
+ "sign out chooser title": "DANGER ZONE",
3681
+ "sign out chooser message": "Proceeding with either action below will erase all data on this device.",
3682
+ "join new identity label": "Join a new identity",
3683
+ "reset device label": "Reset device",
3684
+ "reset device confirm message": "Are you sure you want to reset your device? All data will be lost."
3419
3685
  };
3420
3686
 
3421
3687
  // packages/sdk/shell/src/translations/index.ts
@@ -3439,27 +3705,27 @@ var runShell = async (config = new Config()) => {
3439
3705
  runtime.open(),
3440
3706
  client.initialize()
3441
3707
  ]);
3442
- createRoot(document.getElementById("root")).render(/* @__PURE__ */ React42.createElement(StrictMode, null, /* @__PURE__ */ React42.createElement(ThemeProvider, {
3708
+ createRoot(document.getElementById("root")).render(/* @__PURE__ */ React44.createElement(StrictMode, null, /* @__PURE__ */ React44.createElement(ThemeProvider, {
3443
3709
  tx: defaultTx,
3444
3710
  resourceExtensions: [
3445
3711
  osTranslations
3446
3712
  ]
3447
- }, /* @__PURE__ */ React42.createElement(ClientContext.Provider, {
3713
+ }, /* @__PURE__ */ React44.createElement(ClientContext.Provider, {
3448
3714
  value: {
3449
3715
  client,
3450
3716
  status: SystemStatus.ACTIVE
3451
3717
  }
3452
- }, /* @__PURE__ */ React42.createElement(ClipboardProvider, null, /* @__PURE__ */ React42.createElement(Tooltip3.Provider, null, /* @__PURE__ */ React42.createElement(Shell, {
3718
+ }, /* @__PURE__ */ React44.createElement(ClipboardProvider, null, /* @__PURE__ */ React44.createElement(Tooltip3.Provider, null, /* @__PURE__ */ React44.createElement(Shell, {
3453
3719
  runtime,
3454
3720
  origin: location.origin
3455
3721
  })))))));
3456
3722
  };
3457
3723
 
3458
3724
  // packages/sdk/shell/src/composites/Shell/ShellContext.tsx
3459
- import React43, { createContext as createContext2, useCallback as useCallback8, useContext as useContext2, useEffect as useEffect7, useMemo as useMemo6, useState as useState10 } from "react";
3460
- import { ShellDisplay as ShellDisplay2, ShellLayout as ShellLayout3, useClient as useClient7 } from "@dxos/react-client";
3725
+ import React45, { createContext as createContext2, useCallback as useCallback9, useContext as useContext2, useEffect as useEffect8, useMemo as useMemo6, useState as useState11 } from "react";
3726
+ import { ShellDisplay as ShellDisplay2, ShellLayout as ShellLayout3, useClient as useClient8 } from "@dxos/react-client";
3461
3727
  import { useIdentity as useIdentity3 } from "@dxos/react-client/halo";
3462
- import { mx as mx22 } from "@dxos/react-ui-theme";
3728
+ import { mx as mx23 } from "@dxos/react-ui-theme";
3463
3729
 
3464
3730
  // packages/sdk/shell/src/composites/Shell/memory-shell-runtime.ts
3465
3731
  import { Event } from "@dxos/async";
@@ -3495,7 +3761,7 @@ var MemoryShellRuntime = class {
3495
3761
  // packages/sdk/shell/src/composites/Shell/ShellContext.tsx
3496
3762
  var ShellContext = /* @__PURE__ */ createContext2({});
3497
3763
  var useShell = () => {
3498
- const client = useClient7();
3764
+ const client = useClient8();
3499
3765
  const { runtime, setDisplay } = useContext2(ShellContext);
3500
3766
  const setLayout = async (layout, options) => {
3501
3767
  if (runtime) {
@@ -3516,9 +3782,9 @@ var useShell = () => {
3516
3782
  };
3517
3783
  };
3518
3784
  var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoinedSpace, children }) => {
3519
- const client = useClient7();
3785
+ const client = useClient8();
3520
3786
  const identity = useIdentity3();
3521
- const [display, setDisplay] = useState10(!identity || spaceInvitationCode || deviceInvitationCode ? ShellDisplay2.FULLSCREEN : ShellDisplay2.NONE);
3787
+ const [display, setDisplay] = useState11(!identity || spaceInvitationCode || deviceInvitationCode ? ShellDisplay2.FULLSCREEN : ShellDisplay2.NONE);
3522
3788
  const shellRuntime = useMemo6(() => {
3523
3789
  if (client.config.get("runtime.app.env.DX_VAULT") !== "false") {
3524
3790
  return;
@@ -3544,7 +3810,7 @@ var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoine
3544
3810
  spaceInvitationCode,
3545
3811
  deviceInvitationCode
3546
3812
  ]);
3547
- const handleKeyDown = useCallback8((event) => {
3813
+ const handleKeyDown = useCallback9((event) => {
3548
3814
  if (!space || !shellRuntime) {
3549
3815
  return;
3550
3816
  }
@@ -3565,7 +3831,7 @@ var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoine
3565
3831
  space,
3566
3832
  shellRuntime
3567
3833
  ]);
3568
- useEffect7(() => {
3834
+ useEffect8(() => {
3569
3835
  if (!shellRuntime) {
3570
3836
  return;
3571
3837
  }
@@ -3575,7 +3841,7 @@ var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoine
3575
3841
  shellRuntime,
3576
3842
  handleKeyDown
3577
3843
  ]);
3578
- useEffect7(() => {
3844
+ useEffect8(() => {
3579
3845
  if (!shellRuntime) {
3580
3846
  return;
3581
3847
  }
@@ -3588,12 +3854,12 @@ var ShellProvider = ({ space, deviceInvitationCode, spaceInvitationCode, onJoine
3588
3854
  }, [
3589
3855
  shellRuntime
3590
3856
  ]);
3591
- return /* @__PURE__ */ React43.createElement(React43.Fragment, null, shellRuntime && /* @__PURE__ */ React43.createElement("div", {
3592
- className: mx22(display === ShellDisplay2.NONE ? "hidden" : "")
3593
- }, /* @__PURE__ */ React43.createElement(Shell, {
3857
+ return /* @__PURE__ */ React45.createElement(React45.Fragment, null, shellRuntime && /* @__PURE__ */ React45.createElement("div", {
3858
+ className: mx23(display === ShellDisplay2.NONE ? "hidden" : "")
3859
+ }, /* @__PURE__ */ React45.createElement(Shell, {
3594
3860
  runtime: shellRuntime,
3595
3861
  origin: window.location.origin
3596
- })), /* @__PURE__ */ React43.createElement(ShellContext.Provider, {
3862
+ })), /* @__PURE__ */ React45.createElement(ShellContext.Provider, {
3597
3863
  value: {
3598
3864
  runtime: shellRuntime,
3599
3865
  setDisplay