Skip to content

Commit 5f0cd76

Browse files
author
Shaw
committed
chore: preserve cloud route worktree
2 parents ff95e7a + 01eabe8 commit 5f0cd76

35 files changed

Lines changed: 729 additions & 221 deletions

apps/app-lifeops/src/api/client-lifeops.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -716,9 +716,7 @@ declare module "@elizaos/app-core/api/client-base" {
716716
sendWhatsAppConnectorMessage(
717717
data: SendLifeOpsWhatsAppMessageRequest,
718718
): Promise<{ ok: true; messageId: string }>;
719-
getWhatsAppConnectorMessages(options?: {
720-
limit?: number;
721-
}): Promise<{
719+
getWhatsAppConnectorMessages(options?: { limit?: number }): Promise<{
722720
count: number;
723721
messages: Array<{
724722
id: string;

apps/app-lifeops/src/components/EventEditorDrawer.test.tsx

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,9 @@ const calendars: LifeOpsCalendarSummary[] = [
182182
},
183183
];
184184

185-
function event(overrides: Partial<LifeOpsCalendarEvent> = {}): LifeOpsCalendarEvent {
185+
function event(
186+
overrides: Partial<LifeOpsCalendarEvent> = {},
187+
): LifeOpsCalendarEvent {
186188
return {
187189
id: "event-1",
188190
externalId: "google-event-1",
@@ -232,12 +234,7 @@ describe("EventEditorDrawer", () => {
232234
clientMock.updateLifeOpsCalendarEvent.mockResolvedValue({ event: updated });
233235

234236
render(
235-
<EventEditorDrawer
236-
open
237-
mode="edit"
238-
event={event()}
239-
onClose={vi.fn()}
240-
/>,
237+
<EventEditorDrawer open mode="edit" event={event()} onClose={vi.fn()} />,
241238
);
242239

243240
expect(screen.queryByText("Repeat")).toBeNull();
@@ -263,12 +260,12 @@ describe("EventEditorDrawer", () => {
263260
attendees: [],
264261
}),
265262
);
266-
expect(clientMock.updateLifeOpsCalendarEvent.mock.calls[0]?.[1]).not.toHaveProperty(
267-
"recurrence",
268-
);
269-
expect(clientMock.updateLifeOpsCalendarEvent.mock.calls[0]?.[1]).not.toHaveProperty(
270-
"reminders",
271-
);
263+
expect(
264+
clientMock.updateLifeOpsCalendarEvent.mock.calls[0]?.[1],
265+
).not.toHaveProperty("recurrence");
266+
expect(
267+
clientMock.updateLifeOpsCalendarEvent.mock.calls[0]?.[1],
268+
).not.toHaveProperty("reminders");
272269
});
273270

274271
it("uses grantId plus calendarId when selecting among duplicate primary calendars", async () => {

apps/app-lifeops/src/components/EventEditorDrawer.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,9 @@ export function EventEditorDrawer({
220220
const [error, setError] = useState<string | null>(null);
221221

222222
const isCreate = mode === "create";
223+
const calendarRequestSide = isCreate
224+
? (createDefaults?.side ?? "owner")
225+
: (event?.side ?? "owner");
223226

224227
// Seed form when the event changes (edit) or drawer opens in create mode.
225228
useEffect(() => {
@@ -241,7 +244,7 @@ export function EventEditorDrawer({
241244
setCalendarsLoading(true);
242245
setCalendarsError(null);
243246
void client
244-
.getLifeOpsCalendars({ side: "owner" })
247+
.getLifeOpsCalendars({ side: calendarRequestSide })
245248
.then((response) => {
246249
if (cancelled) return;
247250
setCalendars(response.calendars);
@@ -286,7 +289,7 @@ export function EventEditorDrawer({
286289
return () => {
287290
cancelled = true;
288291
};
289-
}, [open]);
292+
}, [open, calendarRequestSide]);
290293

291294
const calendarOptions = useMemo(() => {
292295
if (calendars.length > 0) return calendars;
@@ -316,12 +319,12 @@ export function EventEditorDrawer({
316319
] satisfies LifeOpsCalendarSummary[];
317320
}, [calendars, form.calendarId, form.grantId, form.side]);
318321

319-
const updateForm = useCallback(<K extends keyof FormState>(
320-
key: K,
321-
value: FormState[K],
322-
) => {
323-
setForm((prev) => ({ ...prev, [key]: value }));
324-
}, []);
322+
const updateForm = useCallback(
323+
<K extends keyof FormState>(key: K, value: FormState[K]) => {
324+
setForm((prev) => ({ ...prev, [key]: value }));
325+
},
326+
[],
327+
);
325328

326329
const handleSave = useCallback(
327330
async (options: { keepOpen?: boolean } = {}) => {

apps/app-lifeops/src/components/LifeOpsSettingsSection.tsx

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import {
2-
Button,
3-
SegmentedControl,
4-
useApp,
5-
} from "@elizaos/app-core";
1+
import { Button, SegmentedControl, useApp } from "@elizaos/app-core";
62
import { client } from "@elizaos/app-core/api";
73
import type { ModelOption } from "@elizaos/shared/contracts/onboarding";
84
import type {
@@ -562,7 +558,8 @@ function GoogleConnectorSideCard({
562558

563559
const toggleCalendar = useCallback(
564560
async (calendar: LifeOpsCalendarSummary) => {
565-
setCalendarPendingId(calendar.calendarId);
561+
const pendingId = `${calendar.side}:${calendar.grantId}:${calendar.calendarId}`;
562+
setCalendarPendingId(pendingId);
566563
setCalendarError(null);
567564
try {
568565
const response = await client.setLifeOpsCalendarIncluded({
@@ -822,12 +819,12 @@ function GoogleConnectorSideCard({
822819
) : calendars.length > 0 ? (
823820
<div className="grid gap-2">
824821
{calendars.map((calendar) => {
822+
const calendarIdentity = `${calendar.side}:${calendar.grantId}:${calendar.calendarId}`;
825823
const disabled =
826-
controlDisabled ||
827-
calendarPendingId === calendar.calendarId;
824+
controlDisabled || calendarPendingId === calendarIdentity;
828825
return (
829826
<label
830-
key={`${calendar.grantId}:${calendar.calendarId}`}
827+
key={calendarIdentity}
831828
className="flex cursor-pointer items-start gap-3 rounded-xl bg-card/18 px-3 py-2 text-xs"
832829
>
833830
<input
@@ -885,13 +882,15 @@ function GoogleConnectorSideCard({
885882
}
886883

887884
function flattenModelOptions(
888-
models: {
889-
nano?: ModelOption[];
890-
small?: ModelOption[];
891-
medium?: ModelOption[];
892-
large?: ModelOption[];
893-
mega?: ModelOption[];
894-
} | undefined,
885+
models:
886+
| {
887+
nano?: ModelOption[];
888+
small?: ModelOption[];
889+
medium?: ModelOption[];
890+
large?: ModelOption[];
891+
mega?: ModelOption[];
892+
}
893+
| undefined,
895894
): ModelOption[] {
896895
if (!models) return [];
897896
const seen = new Set<string>();

apps/app-lifeops/src/hooks/useGoogleLifeOpsConnector.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ describe("useGoogleLifeOpsConnector - pendingAuthUrl state", () => {
178178
clientMock.startGoogleLifeOpsConnector.mock.calls[0] ?? [];
179179
expect(request?.capabilities).toContain("google.gmail.triage");
180180
expect(request?.capabilities).not.toContain("google.gmail.manage");
181+
expect(request?.createNewGrant).toBe(true);
181182
});
182183

183184
it("connectAdditional() requests inbox tracking without Gmail manage scopes", async () => {

apps/app-lifeops/src/hooks/useGoogleLifeOpsConnector.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { APP_RESUME_EVENT } from "@elizaos/app-core/events";
44
import { useApp } from "@elizaos/app-core/state";
55
import { openExternalUrl } from "@elizaos/app-core/utils";
66
import type {
7-
DisconnectLifeOpsGoogleConnectorRequest,
87
LifeOpsConnectorMode,
98
LifeOpsConnectorSide,
109
LifeOpsGoogleCapability,
@@ -574,7 +573,7 @@ export function useGoogleLifeOpsConnector(
574573
side,
575574
mode: selectedModeRef.current ?? status?.mode,
576575
grantId,
577-
} as DisconnectLifeOpsGoogleConnectorRequest & { grantId: string });
576+
});
578577
await refresh({ mode: selectedModeRef.current });
579578
dispatchLifeOpsGoogleConnectorRefresh({
580579
origin: instanceIdRef.current,
@@ -606,9 +605,10 @@ export function useGoogleLifeOpsConnector(
606605
connectMode === "cloud_managed"
607606
? resolveSuccessRedirectUrl(side)
608607
: undefined,
609-
side,
610-
mode: connectMode,
611-
});
608+
side,
609+
mode: connectMode,
610+
createNewGrant: true,
611+
});
612612
await openExternalUrl(result.authUrl);
613613
setError(null);
614614
} catch (cause) {

apps/app-lifeops/src/lifeops/google-calendar.test.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,11 @@ describe("fetchGoogleCalendarEvents", () => {
2929
JSON.stringify(
3030
pageToken === "page-2"
3131
? {
32-
items: [
33-
googleEvent("event-2", "2026-04-23T16:00:00.000Z"),
34-
],
32+
items: [googleEvent("event-2", "2026-04-23T16:00:00.000Z")],
3533
}
3634
: {
3735
nextPageToken: "page-2",
38-
items: [
39-
googleEvent("event-1", "2026-04-23T15:00:00.000Z"),
40-
],
36+
items: [googleEvent("event-1", "2026-04-23T15:00:00.000Z")],
4137
},
4238
),
4339
{

apps/app-lifeops/src/lifeops/google-calendar.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,10 @@ interface GoogleCalendarCreateRequestBody {
119119
}>;
120120
}
121121

122-
export interface SyncedGoogleCalendarEvent
123-
extends Omit<
124-
LifeOpsCalendarEvent,
125-
"id" | "agentId" | "provider" | "side" | "syncedAt" | "updatedAt"
126-
> {}
122+
export interface SyncedGoogleCalendarEvent extends Omit<
123+
LifeOpsCalendarEvent,
124+
"id" | "agentId" | "provider" | "side" | "syncedAt" | "updatedAt"
125+
> {}
127126

128127
function readGoogleEventInstant(
129128
value: GoogleCalendarEventDate | undefined,
@@ -340,9 +339,8 @@ export async function listGoogleCalendars(args: {
340339
if (item.deleted || item.hidden) continue;
341340
const calendarId = item.id?.trim();
342341
if (!calendarId) continue;
343-
const summary = (item.summaryOverride?.trim() ||
344-
item.summary?.trim() ||
345-
calendarId);
342+
const summary =
343+
item.summaryOverride?.trim() || item.summary?.trim() || calendarId;
346344
entries.push({
347345
calendarId,
348346
summary,

0 commit comments

Comments
 (0)