Skip to content

Commit 960262b

Browse files
committed
feat(web): workbench room is the child tenant's mail thread; legacy chat client deleted (CL-8435)
A workbench is a child tenant, so /w/:tenantId now renders that tenant's mailbox: participants are its principals, the timeline is its mail threads with native in-reply-to chains as sub-threads, and a message is addressed to every agent in the room through one send seam. Creating a workbench is a stock tenant create plus a stock member invite per agent, Myra always included. The chat client for the deleted /chat/workbenches routes is gone, along with every module that only existed to serve it.
1 parent 3d8072a commit 960262b

94 files changed

Lines changed: 815 additions & 17617 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎apps/web/src/agent-chat-launch.test.ts‎

Lines changed: 0 additions & 78 deletions
This file was deleted.

‎apps/web/src/agent-chat-launch.ts‎

Lines changed: 0 additions & 26 deletions
This file was deleted.

‎apps/web/src/agent-dm-launch.test.ts‎

Lines changed: 0 additions & 72 deletions
This file was deleted.

‎apps/web/src/agent-dm-launch.ts‎

Lines changed: 0 additions & 21 deletions
This file was deleted.

‎apps/web/src/agents-api.ts‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,3 +460,18 @@ export function useAgentDirectory(tenantId: string | undefined): APIQuery<AgentD
460460
});
461461
return toAPIQuery(result);
462462
}
463+
464+
// The guided capability-add surface: only what this tenant actually has.
465+
const CapabilityInventoryWire = type({
466+
toolPackages: type({ name: "string" }).array(),
467+
skills: type({ name: "string" }).array(),
468+
models: type({ canonicalName: "string" }).array(),
469+
});
470+
export type CapabilityInventory = typeof CapabilityInventoryWire.infer;
471+
472+
export function listCapabilityInventory(tenantId: string): Promise<CapabilityInventory> {
473+
return getJSON(
474+
`/api/tenants/${tenantId}/agent-definitions/capabilities/inventory`,
475+
CapabilityInventoryWire,
476+
);
477+
}

‎apps/web/src/app.css‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3860,3 +3860,58 @@ button.mission-control-jump-row:hover {
38603860
.chat-composer > textarea {
38613861
width: 100%;
38623862
}
3863+
3864+
/* A workbench room: timeline in the stage, sub-thread replies beside it. */
3865+
.room-layout {
3866+
display: flex;
3867+
min-height: 0;
3868+
flex: 1;
3869+
}
3870+
.room-participants {
3871+
display: flex;
3872+
flex-wrap: wrap;
3873+
gap: 0.5rem;
3874+
margin: 0 0 1rem;
3875+
padding: 0;
3876+
list-style: none;
3877+
font-size: 0.82rem;
3878+
color: var(--muted-foreground);
3879+
}
3880+
.room-participants > li {
3881+
display: flex;
3882+
align-items: center;
3883+
gap: 0.35rem;
3884+
}
3885+
.room-replies-link {
3886+
display: block;
3887+
margin-top: 0.35rem;
3888+
padding: 0;
3889+
border: 0;
3890+
background: none;
3891+
font-size: 0.78rem;
3892+
color: var(--muted-foreground);
3893+
cursor: pointer;
3894+
}
3895+
.room-replies-link:hover {
3896+
color: var(--foreground);
3897+
}
3898+
.room-subthread {
3899+
display: flex;
3900+
flex-direction: column;
3901+
width: 22rem;
3902+
min-height: 0;
3903+
overflow-y: auto;
3904+
padding: 1rem;
3905+
border-left: 1px solid var(--border);
3906+
}
3907+
.room-subthread-head {
3908+
display: flex;
3909+
align-items: center;
3910+
justify-content: space-between;
3911+
margin-bottom: 0.75rem;
3912+
}
3913+
.room-subthread-head > h2 {
3914+
margin: 0;
3915+
font-size: 0.95rem;
3916+
font-weight: 600;
3917+
}

‎apps/web/src/chat-path.ts‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ export const chatKeys = {
1212
childTenants: (tenantId: string) => ["tenant", tenantId, "child-tenants"] as const,
1313
};
1414

15+
/** One key factory per room (a workbench child tenant), so a send
16+
* invalidates the room's timeline and roster together. */
17+
export const roomKeys = {
18+
scope: (tenantId: string) => ["room", tenantId] as const,
19+
tenant: (tenantId: string) => ["room", tenantId, "tenant"] as const,
20+
participants: (tenantId: string) => ["room", tenantId, "participants"] as const,
21+
timeline: (tenantId: string) => ["room", tenantId, "timeline"] as const,
22+
};
23+
1524
export const CHATS_PATH_PREFIX = "/chats";
1625
export const NEW_CHAT_PATH = `${CHATS_PATH_PREFIX}/new`;
1726

‎apps/web/src/chat/agent-display-names.test.ts‎

Lines changed: 0 additions & 38 deletions
This file was deleted.

‎apps/web/src/chat/agent-display-names.ts‎

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)