replicas-cli 0.2.302 → 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.
- package/dist/index.mjs +71 -67
- 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.
|
|
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 =
|
|
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
|
|
12030
|
+
if (isWorkspaceSuspendedStatus(selectedWorkspace.status)) {
|
|
12027
12031
|
throw new Error(
|
|
12028
|
-
|
|
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
|
-
|
|
12903
|
-
|
|
12904
|
-
|
|
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
|
|
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: "
|
|
14862
|
+
mutationFn: (workspaceId) => orgFetch(`/v1/workspaces/${workspaceId}/archive`, {
|
|
14863
|
+
method: "POST"
|
|
14865
14864
|
}),
|
|
14866
|
-
onSuccess: (_data,
|
|
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.
|
|
14869
|
-
auth.queryClient.
|
|
14870
|
-
auth.queryClient.
|
|
14871
|
-
auth.queryClient.
|
|
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
|
-
|
|
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 [
|
|
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
|
|
15334
|
+
const handleArchive = useCallback4(() => {
|
|
15327
15335
|
const item = items[cursorIndex];
|
|
15328
15336
|
if (!item || item.type !== "workspace") return;
|
|
15329
|
-
if (
|
|
15330
|
-
|
|
15331
|
-
|
|
15337
|
+
if (confirmArchive === item.workspaceId) {
|
|
15338
|
+
onArchiveWorkspace(item.workspaceId);
|
|
15339
|
+
setConfirmArchive(null);
|
|
15332
15340
|
} else {
|
|
15333
|
-
|
|
15341
|
+
setConfirmArchive(item.workspaceId);
|
|
15334
15342
|
}
|
|
15335
|
-
}, [items, cursorIndex,
|
|
15343
|
+
}, [items, cursorIndex, confirmArchive, onArchiveWorkspace]);
|
|
15336
15344
|
const moveCursorAndClearConfirm = useCallback4(
|
|
15337
15345
|
(next) => {
|
|
15338
|
-
|
|
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 (
|
|
15353
|
+
if (confirmArchive) {
|
|
15346
15354
|
if (key.name === "y") {
|
|
15347
|
-
|
|
15348
|
-
|
|
15355
|
+
onArchiveWorkspace(confirmArchive);
|
|
15356
|
+
setConfirmArchive(null);
|
|
15349
15357
|
return;
|
|
15350
15358
|
}
|
|
15351
15359
|
if (key.name === "n" || key.name === "escape") {
|
|
15352
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
15421
|
+
const handleArchiveClick = useCallback4(
|
|
15414
15422
|
(workspaceId, e) => {
|
|
15415
15423
|
e?.preventDefault?.();
|
|
15416
|
-
if (
|
|
15417
|
-
|
|
15418
|
-
|
|
15424
|
+
if (confirmArchive === workspaceId) {
|
|
15425
|
+
onArchiveWorkspace(workspaceId);
|
|
15426
|
+
setConfirmArchive(null);
|
|
15419
15427
|
} else {
|
|
15420
|
-
|
|
15428
|
+
setConfirmArchive(workspaceId);
|
|
15421
15429
|
}
|
|
15422
15430
|
},
|
|
15423
|
-
[
|
|
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 =
|
|
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: "#
|
|
15492
|
-
/* @__PURE__ */ jsx2("text", { children: /* @__PURE__ */ jsx2("span", { fg: "#
|
|
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
|
-
|
|
15495
|
-
|
|
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: () =>
|
|
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) =>
|
|
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
|
|
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
|
|
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
|
|
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
|
|
17556
|
+
const handleArchiveWorkspace = useCallback8(
|
|
17549
17557
|
async (workspaceId) => {
|
|
17550
17558
|
try {
|
|
17551
|
-
await
|
|
17552
|
-
|
|
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
|
-
[
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
17747
|
+
" This workspace is ",
|
|
17748
|
+
statusData.status
|
|
17745
17749
|
] }),
|
|
17746
17750
|
/* @__PURE__ */ jsxs9("text", { fg: "#555555", children: [
|
|
17747
17751
|
"Press ",
|