Skip to content

Commit 9924422

Browse files
authored
Merge branch 'develop' into fix/fast-first-action-ack-21igvnc1lvzji
2 parents dfb0f72 + 9abaa6d commit 9924422

25 files changed

Lines changed: 899 additions & 98 deletions
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@roomote/cloud-agents": patch
3+
---
4+
5+
Include authorized Settings skills in Fast mode's unscoped skill inventory.

‎apps/docs/skills.mdx‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ a packaged or Settings skill. Roomote resolves Settings skills only from
1515
environments you can use. If different environments define different versions
1616
with the same name, Roomote asks which environment you mean.
1717

18+
When you ask Fast which skills are available, its unscoped inventory includes
19+
packaged skills and Settings skills from every environment you can use.
20+
Repository-defined skills remain scoped to a specific environment or
21+
repository.
22+
1823
Use Skills when the same guidance keeps showing up across tasks in an
1924
environment: a framework-specific review checklist, a release process, a
2025
design-system rule, a data workflow, or a repeatable debugging path.

‎apps/web/src/app/(authenticated)/sessions/SessionCard.client.test.tsx‎

Lines changed: 57 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎apps/web/src/app/(authenticated)/sessions/SessionCard.tsx‎

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@ import Link from 'next/link';
22
import { formatDistanceToNow } from 'date-fns';
33

44
import { formatInferenceCost, getUserDisplayName } from '@/lib';
5+
import { formatAutomationLabel } from '@/lib/task-creator-filter';
56
import { Avatar, Spinner } from '@/components/system';
7+
import { PullRequestBadge } from '@/components/sandbox';
68
import { SessionStatusBadge } from '@/components/sessions/SessionStatusBadge';
79
import { SessionSearchSnippet } from '@/components/sessions/SessionSearchSnippet';
810
import { getSessionSurfaceLabel } from '@/components/sessions/session-surfaces';
911

1012
type SessionCardData = {
1113
id: string;
1214
title: string;
15+
ownerKind: 'user' | 'automation' | 'system';
16+
ownerAutomation: string | null;
1317
ownerName: string | null;
1418
ownerEmail: string | null;
1519
ownerImageUrl: string | null;
@@ -21,6 +25,11 @@ type SessionCardData = {
2125
inferenceCostMicroUsd: number;
2226
unread: boolean;
2327
searchSnippet?: string | null;
28+
pullRequests: Array<{
29+
repository: string;
30+
number: number;
31+
url: string;
32+
}>;
2433
tasks: Array<{
2534
taskId: string;
2635
workflow: string;
@@ -37,25 +46,30 @@ export function SessionCard({
3746
viewerUserId: string;
3847
query?: string;
3948
}) {
40-
const owner =
41-
getUserDisplayName({
42-
name: session.ownerName,
43-
email: session.ownerEmail,
44-
}) ?? 'Roomote';
49+
const actorName =
50+
session.ownerKind === 'automation' && session.ownerAutomation
51+
? formatAutomationLabel(session.ownerAutomation)
52+
: (getUserDisplayName({
53+
name: session.ownerName,
54+
email: session.ownerEmail,
55+
}) ?? 'Roomote');
4556
const status = session.cachedStatus ?? 'ready';
4657

4758
return (
48-
<Link
49-
href={`/sessions/${session.id}`}
50-
className="ph-no-capture group flex w-full items-start gap-3 p-4 transition-colors hover:bg-accent-foreground/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
51-
>
52-
<div className="relative mt-1 shrink-0">
59+
<div className="ph-no-capture group relative flex w-full items-start gap-3 p-4 transition-colors hover:bg-accent-foreground/10">
60+
<Link
61+
href={`/sessions/${session.id}`}
62+
className="absolute inset-0 z-0 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
63+
>
64+
<span className="sr-only">{session.title}</span>
65+
</Link>
66+
<div className="pointer-events-none relative z-10 mt-1 shrink-0">
5367
<Avatar
5468
imageUrl={session.ownerImageUrl}
55-
name={owner}
69+
name={actorName}
5670
email={session.ownerEmail ?? undefined}
5771
size="md"
58-
alt={owner}
72+
alt={actorName}
5973
/>
6074
{session.unread && session.ownerUserId === viewerUserId ? (
6175
<span
@@ -64,17 +78,21 @@ export function SessionCard({
6478
/>
6579
) : null}
6680
</div>
67-
<div className="min-w-0 flex-1 space-y-2">
68-
<div className="flex flex-wrap items-center justify-between gap-2">
69-
<p className="line-clamp-2 text-base font-medium group-hover:underline">
70-
{session.title}
71-
</p>
81+
<div className="pointer-events-none relative z-10 min-w-0 flex-1">
82+
<div className="flex items-start justify-between gap-2 text-xs text-muted-foreground/75 md:items-center">
83+
<div className="flex flex-wrap items-center gap-1 text-nowrap">
84+
<span>{actorName}</span>
85+
<span>started a session</span>
86+
</div>
7287
<span className="shrink-0 text-xs text-muted-foreground">
7388
{formatDistanceToNow(new Date(session.activityAt * 1000), {
7489
addSuffix: true,
7590
})}
7691
</span>
7792
</div>
93+
<p className="mt-1 mb-2 line-clamp-2 text-base font-medium group-hover:underline">
94+
{session.title}
95+
</p>
7896
<SessionSearchSnippet
7997
snippet={session.searchSnippet}
8098
query={query}
@@ -90,11 +108,21 @@ export function SessionCard({
90108
<SessionStatusBadge status={status} className="capitalize" />
91109
)}
92110
<span>{getSessionSurfaceLabel(session.sourceSurface)}</span>
111+
{session.pullRequests.map((pullRequest) => (
112+
<PullRequestBadge
113+
key={`${pullRequest.repository}:${pullRequest.number}`}
114+
repo={pullRequest.repository}
115+
prNumber={pullRequest.number}
116+
url={pullRequest.url}
117+
className="pointer-events-auto"
118+
iconClassName="size-3"
119+
/>
120+
))}
93121
{session.inferenceCostMicroUsd > 0 ? (
94122
<span>${formatInferenceCost(session.inferenceCostMicroUsd)}</span>
95123
) : null}
96124
</div>
97125
</div>
98-
</Link>
126+
</div>
99127
);
100128
}

‎apps/web/src/app/(authenticated)/sessions/SessionsFilters.client.test.tsx‎

Lines changed: 51 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎apps/web/src/app/(authenticated)/sessions/SessionsFilters.tsx‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ const ADVANCED_FILTERS_STORAGE_KEY =
3737
'roomote-sessions-advanced-filters-visible';
3838
const SESSIONS_VIEW_STORAGE_KEY = 'roomote-sessions-view';
3939
const ADVANCED_FILTER_PARAMS = [
40-
'user',
4140
'repository',
4241
'pullRequest',
4342
'model',
@@ -244,12 +243,14 @@ export function SessionsFilters({
244243
}
245244
/>
246245
<TaskFilters
247-
userId="all"
246+
userId={userId ?? 'all'}
248247
repositoryName={null}
249248
pullRequest={null}
250249
model={null}
251250
timePeriod={timePeriod}
252-
onUserChange={() => undefined}
251+
onUserChange={(value) =>
252+
updateNullableParam('user', value && value !== 'all' ? value : null)
253+
}
253254
onRepositoryChange={() => undefined}
254255
onPullRequestChange={() => undefined}
255256
onModelChange={() => undefined}
@@ -259,7 +260,6 @@ export function SessionsFilters({
259260
else params.set('period', String(period));
260261
})
261262
}
262-
showUser={false}
263263
showRepository={false}
264264
showPullRequest={false}
265265
showModel={false}
@@ -288,6 +288,7 @@ export function SessionsFilters({
288288
}
289289
onModelChange={(value) => updateNullableParam('model', value)}
290290
onTimePeriodChange={() => undefined}
291+
showUser={false}
291292
showTimePeriod={false}
292293
showTaskType={false}
293294
/>

0 commit comments

Comments
 (0)