replicas-cli 0.2.301 → 0.2.303

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 (2) hide show
  1. package/dist/index.mjs +71 -67
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -9345,7 +9345,7 @@ var HOOK_EXEC_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
9345
9345
  var REPLICAS_CONFIG_FILENAMES = ["replicas.json", "replicas.yaml", "replicas.yml"];
9346
9346
 
9347
9347
  // ../shared/src/cli-version.ts
9348
- var CLI_VERSION = "0.2.301";
9348
+ var CLI_VERSION = "0.2.303";
9349
9349
 
9350
9350
  // ../shared/src/engine/environment.ts
9351
9351
  var DESKTOP_NOVNC_PORT = 6080;
@@ -9477,6 +9477,10 @@ function normalizeCodexAspTranscriptStatus(status, failed = false) {
9477
9477
  }
9478
9478
 
9479
9479
  // ../shared/src/routes/workspaces.ts
9480
+ var WORKSPACE_STATUSES = ["active", "sleeping", "archived", "preparing", "error"];
9481
+ function isWorkspaceSuspendedStatus(status) {
9482
+ return status === "sleeping" || status === "archived";
9483
+ }
9480
9484
  var VALID_LIFECYCLE_POLICIES = ["default", "delete_when_done", "delete_after_inactivity"];
9481
9485
  function workspaceConfigWithCapabilities(config2, capabilities = {}) {
9482
9486
  const mergedCapabilities = {
@@ -9497,7 +9501,7 @@ function workspaceConfigWithPrFollowups(config2, prFollowups = config2?.capabili
9497
9501
  var WORKSPACE_FILE_UPLOAD_MAX_SIZE_BYTES = 20 * 1024 * 1024;
9498
9502
  var WORKSPACE_FILE_CONTENT_MAX_SIZE_BYTES = 1 * 1024 * 1024;
9499
9503
  var WORKSPACE_SIDEBAR_VIEWS = ["owned", "shared", "team", "automated"];
9500
- var WORKSPACE_STATUS_FILTERS = ["active", "sleeping", "preparing", "failed"];
9504
+ var WORKSPACE_STATUS_FILTERS = WORKSPACE_STATUSES.map((status) => status === "error" ? "failed" : status);
9501
9505
  var DEFAULT_STATUS_FILTERS = [...WORKSPACE_STATUS_FILTERS];
9502
9506
  var DEFAULT_WORKSPACE_FILTERS = {
9503
9507
  statuses: [...DEFAULT_STATUS_FILTERS],
@@ -12023,9 +12027,9 @@ Found ${response.workspaces.length} workspaces matching "${workspaceName}":`));
12023
12027
  console.log(chalk4.green(`
12024
12028
  \u2713 Selected workspace: ${selectedWorkspace.name}`));
12025
12029
  console.log(chalk4.gray(` Status: ${selectedWorkspace.status || "unknown"}`));
12026
- if (selectedWorkspace.status === "sleeping") {
12030
+ if (isWorkspaceSuspendedStatus(selectedWorkspace.status)) {
12027
12031
  throw new Error(
12028
- "Workspace is currently sleeping. Wake it using `replicas interact` (press w on a sleeping workspace) or visit https://tryreplicas.com"
12032
+ `Workspace is currently ${selectedWorkspace.status}. Wake it using \`replicas interact\` (press w on a suspended workspace) or visit https://tryreplicas.com`
12029
12033
  );
12030
12034
  }
12031
12035
  console.log(chalk4.blue("\nRequesting SSH access token..."));
@@ -12899,14 +12903,9 @@ function formatDate(dateString) {
12899
12903
  return new Date(dateString).toLocaleString();
12900
12904
  }
12901
12905
  function formatStatus(status) {
12902
- switch (status) {
12903
- case "active":
12904
- return chalk15.green(status);
12905
- case "sleeping":
12906
- return chalk15.gray(status);
12907
- default:
12908
- return status;
12909
- }
12906
+ if (status === "active") return chalk15.green(status);
12907
+ if (isWorkspaceSuspendedStatus(status)) return chalk15.gray(status);
12908
+ return status;
12910
12909
  }
12911
12910
  function truncate(text, maxLength) {
12912
12911
  if (text.length <= maxLength) return text;
@@ -14855,20 +14854,29 @@ function useWaitForWorkspaceActive() {
14855
14854
  }
14856
14855
  }, [auth, orgFetch, orgId]);
14857
14856
  }
14858
- function useDeleteWorkspace() {
14857
+ function useArchiveWorkspace() {
14859
14858
  const auth = useReplicasAuth();
14860
14859
  const orgFetch = useOrgFetch();
14861
14860
  const orgId = auth.getOrganizationId();
14862
14861
  return useMutation({
14863
- mutationFn: (workspaceId) => orgFetch(`/v1/workspaces/${workspaceId}`, {
14864
- method: "DELETE"
14862
+ mutationFn: (workspaceId) => orgFetch(`/v1/workspaces/${workspaceId}/archive`, {
14863
+ method: "POST"
14865
14864
  }),
14866
- onSuccess: (_data, deletedWorkspaceId) => {
14865
+ onSuccess: (_data, archivedWorkspaceId) => {
14866
+ auth.queryClient.setQueriesData(
14867
+ { queryKey: ["workspaces", orgId] },
14868
+ (current) => current ? {
14869
+ ...current,
14870
+ workspaces: current.workspaces.map(
14871
+ (workspace) => workspace.id === archivedWorkspaceId ? { ...workspace, status: "archived" } : workspace
14872
+ )
14873
+ } : current
14874
+ );
14867
14875
  auth.queryClient.invalidateQueries({ queryKey: ["workspaces", orgId] });
14868
- auth.queryClient.removeQueries({ queryKey: ["workspace-status", deletedWorkspaceId] });
14869
- auth.queryClient.removeQueries({ queryKey: ["workspace-chats", deletedWorkspaceId] });
14870
- auth.queryClient.removeQueries({ queryKey: ["chat-history", deletedWorkspaceId] });
14871
- auth.queryClient.removeQueries({ queryKey: ["workspace-previews", deletedWorkspaceId] });
14876
+ auth.queryClient.invalidateQueries({ queryKey: ["workspace-status", archivedWorkspaceId] });
14877
+ auth.queryClient.invalidateQueries({ queryKey: ["workspace-chats", archivedWorkspaceId] });
14878
+ auth.queryClient.invalidateQueries({ queryKey: ["chat-history", archivedWorkspaceId] });
14879
+ auth.queryClient.invalidateQueries({ queryKey: ["workspace-previews", archivedWorkspaceId] });
14872
14880
  }
14873
14881
  }, auth.queryClient);
14874
14882
  }
@@ -15264,7 +15272,7 @@ function WorkspaceSidebar({
15264
15272
  selectedWorkspaceId,
15265
15273
  onSelectWorkspace,
15266
15274
  onCreateWorkspace,
15267
- onDeleteWorkspace,
15275
+ onArchiveWorkspace,
15268
15276
  onWakeWorkspace,
15269
15277
  wakingWorkspaceId,
15270
15278
  focused,
@@ -15274,7 +15282,7 @@ function WorkspaceSidebar({
15274
15282
  const [collapsedGroups, setCollapsedGroups] = useState2(/* @__PURE__ */ new Set());
15275
15283
  const [cursorIndex, setCursorIndex] = useState2(0);
15276
15284
  const [scrollOffset, setScrollOffset] = useState2(0);
15277
- const [confirmDelete, setConfirmDelete] = useState2(null);
15285
+ const [confirmArchive, setConfirmArchive] = useState2(null);
15278
15286
  const items = useMemo2(() => flattenGroups(groups, collapsedGroups), [groups, collapsedGroups]);
15279
15287
  const clampedCursor = Math.min(cursorIndex, Math.max(0, items.length - 1));
15280
15288
  if (clampedCursor !== cursorIndex) {
@@ -15323,33 +15331,33 @@ function WorkspaceSidebar({
15323
15331
  },
15324
15332
  [onSelectWorkspace, onCreateWorkspace]
15325
15333
  );
15326
- const handleDelete = useCallback4(() => {
15334
+ const handleArchive = useCallback4(() => {
15327
15335
  const item = items[cursorIndex];
15328
15336
  if (!item || item.type !== "workspace") return;
15329
- if (confirmDelete === item.workspaceId) {
15330
- onDeleteWorkspace(item.workspaceId);
15331
- setConfirmDelete(null);
15337
+ if (confirmArchive === item.workspaceId) {
15338
+ onArchiveWorkspace(item.workspaceId);
15339
+ setConfirmArchive(null);
15332
15340
  } else {
15333
- setConfirmDelete(item.workspaceId);
15341
+ setConfirmArchive(item.workspaceId);
15334
15342
  }
15335
- }, [items, cursorIndex, confirmDelete, onDeleteWorkspace]);
15343
+ }, [items, cursorIndex, confirmArchive, onArchiveWorkspace]);
15336
15344
  const moveCursorAndClearConfirm = useCallback4(
15337
15345
  (next) => {
15338
- setConfirmDelete(null);
15346
+ setConfirmArchive(null);
15339
15347
  moveCursor(next);
15340
15348
  },
15341
15349
  [moveCursor]
15342
15350
  );
15343
15351
  useKeyboard((key) => {
15344
15352
  if (!focused) return;
15345
- if (confirmDelete) {
15353
+ if (confirmArchive) {
15346
15354
  if (key.name === "y") {
15347
- onDeleteWorkspace(confirmDelete);
15348
- setConfirmDelete(null);
15355
+ onArchiveWorkspace(confirmArchive);
15356
+ setConfirmArchive(null);
15349
15357
  return;
15350
15358
  }
15351
15359
  if (key.name === "n" || key.name === "escape") {
15352
- setConfirmDelete(null);
15360
+ setConfirmArchive(null);
15353
15361
  return;
15354
15362
  }
15355
15363
  return;
@@ -15383,7 +15391,7 @@ function WorkspaceSidebar({
15383
15391
  return;
15384
15392
  }
15385
15393
  if (key.name === "d" || key.name === "x" || key.name === "delete") {
15386
- handleDelete();
15394
+ handleArchive();
15387
15395
  return;
15388
15396
  }
15389
15397
  if (key.name === "a") {
@@ -15395,7 +15403,7 @@ function WorkspaceSidebar({
15395
15403
  }
15396
15404
  if (key.name === "w") {
15397
15405
  const item = items[cursorIndex];
15398
- if (item?.type === "workspace" && item.status === "sleeping" && wakingWorkspaceId !== item.workspaceId) {
15406
+ if (item?.type === "workspace" && isWorkspaceSuspendedStatus(item.status) && wakingWorkspaceId !== item.workspaceId) {
15399
15407
  onWakeWorkspace(item.workspaceId);
15400
15408
  }
15401
15409
  return;
@@ -15403,24 +15411,24 @@ function WorkspaceSidebar({
15403
15411
  });
15404
15412
  const handleItemClick = useCallback4(
15405
15413
  (globalIndex) => {
15406
- setConfirmDelete(null);
15414
+ setConfirmArchive(null);
15407
15415
  setCursorIndex(globalIndex);
15408
15416
  const item = items[globalIndex];
15409
15417
  if (item) handleAction(item);
15410
15418
  },
15411
15419
  [items, handleAction]
15412
15420
  );
15413
- const handleDeleteClick = useCallback4(
15421
+ const handleArchiveClick = useCallback4(
15414
15422
  (workspaceId, e) => {
15415
15423
  e?.preventDefault?.();
15416
- if (confirmDelete === workspaceId) {
15417
- onDeleteWorkspace(workspaceId);
15418
- setConfirmDelete(null);
15424
+ if (confirmArchive === workspaceId) {
15425
+ onArchiveWorkspace(workspaceId);
15426
+ setConfirmArchive(null);
15419
15427
  } else {
15420
- setConfirmDelete(workspaceId);
15428
+ setConfirmArchive(workspaceId);
15421
15429
  }
15422
15430
  },
15423
- [confirmDelete, onDeleteWorkspace]
15431
+ [confirmArchive, onArchiveWorkspace]
15424
15432
  );
15425
15433
  const visibleItems = items.slice(scrollOffset, scrollOffset + visibleHeight);
15426
15434
  if (loading) {
@@ -15482,19 +15490,19 @@ function WorkspaceSidebar({
15482
15490
  }
15483
15491
  if (item.type === "workspace") {
15484
15492
  const isSelected = item.workspaceId === selectedWorkspaceId;
15485
- const isConfirming = confirmDelete === item.workspaceId;
15493
+ const isConfirming = confirmArchive === item.workspaceId;
15486
15494
  const dot = item.status === "active" ? "\u25CF" : item.status === "preparing" ? "\u25CC" : "\u25CB";
15487
15495
  const dotColor = item.status === "active" ? "#3eeba3" : item.status === "preparing" ? "#ffaa00" : "#666666";
15488
15496
  const nameColor = isSelected ? "#3eeba3" : "#cccccc";
15489
15497
  const itemBg = isConfirming ? "#331111" : isCursor ? "#1a1a1a" : isSelected ? "#0a1a0a" : "#0a0a0a";
15490
15498
  if (isConfirming) {
15491
- return /* @__PURE__ */ jsxs2("box", { height: 1, backgroundColor: "#331111", paddingX: 1, flexDirection: "row", gap: 1, children: [
15492
- /* @__PURE__ */ jsx2("text", { children: /* @__PURE__ */ jsx2("span", { fg: "#ff4444", children: "Delete?" }) }),
15499
+ return /* @__PURE__ */ jsxs2("box", { height: 1, backgroundColor: "#172414", paddingX: 1, flexDirection: "row", gap: 1, children: [
15500
+ /* @__PURE__ */ jsx2("text", { children: /* @__PURE__ */ jsx2("span", { fg: "#3eeba3", children: "Archive?" }) }),
15493
15501
  /* @__PURE__ */ jsx2("box", { onMouseDown: () => {
15494
- onDeleteWorkspace(item.workspaceId);
15495
- setConfirmDelete(null);
15502
+ onArchiveWorkspace(item.workspaceId);
15503
+ setConfirmArchive(null);
15496
15504
  }, children: /* @__PURE__ */ jsx2("text", { children: /* @__PURE__ */ jsx2("span", { fg: "#3eeba3", children: "[y]" }) }) }),
15497
- /* @__PURE__ */ jsx2("box", { onMouseDown: () => setConfirmDelete(null), children: /* @__PURE__ */ jsx2("text", { children: /* @__PURE__ */ jsx2("span", { fg: "#ff4444", children: "[n]" }) }) })
15505
+ /* @__PURE__ */ jsx2("box", { onMouseDown: () => setConfirmArchive(null), children: /* @__PURE__ */ jsx2("text", { children: /* @__PURE__ */ jsx2("span", { fg: "#ff4444", children: "[n]" }) }) })
15498
15506
  ] }, `w-${item.workspaceId}`);
15499
15507
  }
15500
15508
  return /* @__PURE__ */ jsxs2(
@@ -15515,7 +15523,7 @@ function WorkspaceSidebar({
15515
15523
  ] }),
15516
15524
  /* @__PURE__ */ jsx2("span", { fg: nameColor, children: truncate3(item.name, 17) })
15517
15525
  ] }),
15518
- /* @__PURE__ */ jsx2("box", { onMouseDown: (e) => handleDeleteClick(item.workspaceId, e), children: /* @__PURE__ */ jsx2("text", { children: /* @__PURE__ */ jsx2("span", { fg: isCursor ? "#ff4444" : "#222222", children: "\u2717" }) }) })
15526
+ /* @__PURE__ */ jsx2("box", { onMouseDown: (e) => handleArchiveClick(item.workspaceId, e), children: /* @__PURE__ */ jsx2("text", { children: /* @__PURE__ */ jsx2("span", { fg: isCursor ? "#3eeba3" : "#222222", children: "A" }) }) })
15519
15527
  ]
15520
15528
  },
15521
15529
  `w-${item.workspaceId}`
@@ -16736,7 +16744,7 @@ function buildInteractiveItems(workspaceId, status, previews, wakingWorkspaceId)
16736
16744
  if (workspaceId) {
16737
16745
  items.push({ type: "dashboard", workspaceId });
16738
16746
  }
16739
- if (workspaceId && status.status === "sleeping" && wakingWorkspaceId !== workspaceId) {
16747
+ if (workspaceId && isWorkspaceSuspendedStatus(status.status) && wakingWorkspaceId !== workspaceId) {
16740
16748
  items.push({ type: "wake", workspaceId });
16741
16749
  }
16742
16750
  const repoDiffs = [];
@@ -17053,7 +17061,7 @@ function WorkspaceInfo({ status, workspaceName, workspaceId, focused, loading, a
17053
17061
  }
17054
17062
  );
17055
17063
  }
17056
- const statusColor = status.status === "active" ? "#3eeba3" : status.status === "sleeping" ? "#ffaa00" : "#ff4444";
17064
+ const statusColor = status.status === "active" ? "#3eeba3" : isWorkspaceSuspendedStatus(status.status) ? "#ffaa00" : "#ff4444";
17057
17065
  const rawEnv = status.environmentDetails;
17058
17066
  const env = rawEnv && agentAvailability ? {
17059
17067
  ...rawEnv,
@@ -17461,7 +17469,7 @@ function AppInner() {
17461
17469
  );
17462
17470
  const { data: agentAvailability } = useAgentAvailability(isMockSelected ? null : selectedWorkspaceId);
17463
17471
  const createWorkspaceMutation = useCreateWorkspace();
17464
- const deleteWorkspaceMutation = useDeleteWorkspace();
17472
+ const archiveWorkspaceMutation = useArchiveWorkspace();
17465
17473
  const wakeWorkspaceMutation = useWakeWorkspace();
17466
17474
  const generateNameMutation = useGenerateWorkspaceName();
17467
17475
  const [wakingWorkspaceId, setWakingWorkspaceId] = useState8(null);
@@ -17545,21 +17553,16 @@ function AppInner() {
17545
17553
  },
17546
17554
  [createWorkspaceMutation, toast]
17547
17555
  );
17548
- const handleDeleteWorkspace = useCallback8(
17556
+ const handleArchiveWorkspace = useCallback8(
17549
17557
  async (workspaceId) => {
17550
17558
  try {
17551
- await deleteWorkspaceMutation.mutateAsync(workspaceId);
17552
- if (selectedWorkspaceId === workspaceId) {
17553
- setSelectedWorkspaceId(null);
17554
- setViewingDiff(null);
17555
- setLastViewedDiff(null);
17556
- }
17557
- toast.show({ message: "Workspace deleted", variant: "info" });
17559
+ await archiveWorkspaceMutation.mutateAsync(workspaceId);
17560
+ toast.show({ message: "Workspace archived", variant: "info" });
17558
17561
  } catch (err) {
17559
17562
  toast.error(err);
17560
17563
  }
17561
17564
  },
17562
- [selectedWorkspaceId, deleteWorkspaceMutation]
17565
+ [archiveWorkspaceMutation]
17563
17566
  );
17564
17567
  const handleWakeWorkspace = useCallback8(
17565
17568
  async (workspaceId) => {
@@ -17597,7 +17600,7 @@ function AppInner() {
17597
17600
  setFocusPanel((current) => {
17598
17601
  const availablePanels = FOCUS_ORDER.filter((p) => {
17599
17602
  if (p === "sidebar" && !showWorkspacePanel) return false;
17600
- if ((p === "chat-tabs" || p === "chat-history" || p === "chat-input") && (!selectedWorkspaceId || statusData?.status === "sleeping")) return false;
17603
+ if ((p === "chat-tabs" || p === "chat-history" || p === "chat-input") && (!selectedWorkspaceId || isWorkspaceSuspendedStatus(statusData?.status))) return false;
17601
17604
  if (viewingDiff && (p === "chat-tabs" || p === "chat-input")) return false;
17602
17605
  if (p === "chat-tabs" && chats.length <= 1) return false;
17603
17606
  if (p === "info" && !showInfoPanel) return false;
@@ -17626,7 +17629,7 @@ function AppInner() {
17626
17629
  return;
17627
17630
  }
17628
17631
  if (key.name === "w" && focusPanel !== "sidebar" && focusPanel !== "info" && selectedWorkspaceId) {
17629
- if (statusData?.status === "sleeping" && !wakingWorkspaceId) {
17632
+ if (isWorkspaceSuspendedStatus(statusData?.status) && !wakingWorkspaceId) {
17630
17633
  handleWakeWorkspace(selectedWorkspaceId);
17631
17634
  }
17632
17635
  return;
@@ -17689,7 +17692,7 @@ function AppInner() {
17689
17692
  selectedWorkspaceId,
17690
17693
  onSelectWorkspace: handleSelectWorkspace,
17691
17694
  onCreateWorkspace: handleCreateWorkspace,
17692
- onDeleteWorkspace: handleDeleteWorkspace,
17695
+ onArchiveWorkspace: handleArchiveWorkspace,
17693
17696
  onWakeWorkspace: handleWakeWorkspace,
17694
17697
  wakingWorkspaceId,
17695
17698
  focused: focusPanel === "sidebar",
@@ -17709,7 +17712,7 @@ function AppInner() {
17709
17712
  titleAlignment: "center",
17710
17713
  children: /* @__PURE__ */ jsx11(DiffViewer, { diff: viewingDiff.diff, repoName: viewingDiff.repoName, focused: focusPanel !== "sidebar" && focusPanel !== "info" })
17711
17714
  }
17712
- ) : selectedWorkspaceId && statusData?.status !== "sleeping" ? /* @__PURE__ */ jsx11(
17715
+ ) : selectedWorkspaceId && !isWorkspaceSuspendedStatus(statusData?.status) ? /* @__PURE__ */ jsx11(
17713
17716
  ChatArea,
17714
17717
  {
17715
17718
  chats,
@@ -17726,7 +17729,7 @@ function AppInner() {
17726
17729
  agentLabel,
17727
17730
  agentConnectHelp
17728
17731
  }
17729
- ) : selectedWorkspaceId && statusData?.status === "sleeping" ? /* @__PURE__ */ jsxs9(
17732
+ ) : selectedWorkspaceId && isWorkspaceSuspendedStatus(statusData?.status) ? /* @__PURE__ */ jsxs9(
17730
17733
  "box",
17731
17734
  {
17732
17735
  flexGrow: 1,
@@ -17741,7 +17744,8 @@ function AppInner() {
17741
17744
  children: [
17742
17745
  /* @__PURE__ */ jsxs9("text", { fg: "#888888", children: [
17743
17746
  "\u263E",
17744
- " This workspace is sleeping"
17747
+ " This workspace is ",
17748
+ statusData.status
17745
17749
  ] }),
17746
17750
  /* @__PURE__ */ jsxs9("text", { fg: "#555555", children: [
17747
17751
  "Press ",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-cli",
3
- "version": "0.2.301",
3
+ "version": "0.2.303",
4
4
  "description": "CLI for managing Replicas workspaces - SSH into cloud dev environments with automatic port forwarding",
5
5
  "main": "dist/index.mjs",
6
6
  "bin": {