ui(sessions): simplify delegation copy and labels across sessions page and routes

This commit is contained in:
Tyler Gillispie 2026-08-25 09:59:27 -07:00
parent e9a9fb500f
commit 22bcd889c3
3 changed files with 27 additions and 26 deletions

View File

@ -224,9 +224,9 @@ Deno.test("Event Cockpit & Master Kill Switch", async (t) => {
`deno test server/main.test.ts --filter "Event Cockpit"` Expected: FAIL `deno test server/main.test.ts --filter "Event Cockpit"` Expected: FAIL
- [x] **Step 3: Implement `POST /api/events/:id/end` and - [x] **Step 3: Implement `POST /api/events/:id/end` and
`POST /api/events/:id/extend` in `server/routes/events.ts`** Fetch all session IDs `POST /api/events/:id/extend` in `server/routes/events.ts`** Fetch all
created under the event pass, delete them from Valkey and PostgreSQL, session IDs created under the event pass, delete them from Valkey and
record in audit ledger, and mark event `is_active = false`. PostgreSQL, record in audit ledger, and mark event `is_active = false`.
- [x] **Step 4: Update `ui/components/SessionsPage.tsx` with Event Cockpit - [x] **Step 4: Update `ui/components/SessionsPage.tsx` with Event Cockpit
Deck** Display active events with live progress bar Deck** Display active events with live progress bar

View File

@ -41,7 +41,7 @@ sessionRoutes.post("/api/sessions/delegate", async (c) => {
const cleanLabel = (label && typeof label === "string" && label.trim()) const cleanLabel = (label && typeof label === "string" && label.trim())
? label.trim() ? label.trim()
: "AI Agent Session"; : "Delegated Session";
const hours = Math.min(Math.max(Number(lifespanHours) || 1, 1), 720); // Max 30 days const hours = Math.min(Math.max(Number(lifespanHours) || 1, 1), 720); // Max 30 days
const expiresAt = new Date(Date.now() + hours * 3600 * 1000); const expiresAt = new Date(Date.now() + hours * 3600 * 1000);

View File

@ -139,14 +139,13 @@ export const SessionsPage = ({
Active Sessions & Delegations Active Sessions & Delegations
</h1> </h1>
<p style="color: var(--text-secondary); margin: 0; font-size: 0.95rem;"> <p style="color: var(--text-secondary); margin: 0; font-size: 0.95rem;">
Manage browser logins and spawn isolated sessions for AI agents and Manage browser logins and mint isolated, scoped sessions for 1-click
CLI tools. passes, team members, CLI tools, or AI agents.
</p> </p>
</div> </div>
<button <button
type="button" type="button"
id="openDelegateBtn"
class="btn-primary" class="btn-primary"
style="min-height: 42px; box-shadow: var(--shadow-sm); display: inline-flex; align-items: center; gap: 0.4rem;" style="min-height: 42px; box-shadow: var(--shadow-sm); display: inline-flex; align-items: center; gap: 0.4rem;"
onclick="openDelegateDrawer()" onclick="openDelegateDrawer()"
@ -161,11 +160,11 @@ export const SessionsPage = ({
> >
<path d="M12 5v14M5 12h14"></path> <path d="M12 5v14M5 12h14"></path>
</svg> </svg>
<span>Delegate Agent Session</span> <span>Delegate Session</span>
</button> </button>
</div> </div>
{/* Delegate Agent Session Drawer */} {/* Delegate Session Drawer */}
<div <div
id="delegateDrawer" id="delegateDrawer"
class="card" class="card"
@ -174,11 +173,12 @@ export const SessionsPage = ({
<div style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 0.5rem;"> <div style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 0.5rem;">
<div> <div>
<h3 style="margin: 0 0 0.25rem 0; color: var(--text-primary);"> <h3 style="margin: 0 0 0.25rem 0; color: var(--text-primary);">
Spawn Delegated Agent Session Delegate New Session
</h3> </h3>
<p style="color: var(--text-secondary); font-size: 0.9rem; margin: 0;"> <p style="color: var(--text-secondary); font-size: 0.9rem; margin: 0;">
Mint an isolated child session for an AI assistant, daemon, or CLI Mint an isolated, scoped child session for 1-click magic links,
without exposing your primary browser credentials. CLI tools, team members, or AI assistants without exposing your
primary passkeys.
</p> </p>
</div> </div>
<button <button
@ -198,12 +198,12 @@ export const SessionsPage = ({
{/* Label Input */} {/* Label Input */}
<div style="margin-bottom: 1.25rem;"> <div style="margin-bottom: 1.25rem;">
<label style="display: block; font-weight: 600; margin-bottom: 0.35rem; font-size: 0.875rem; color: var(--text-secondary);"> <label style="display: block; font-weight: 600; margin-bottom: 0.35rem; font-size: 0.875rem; color: var(--text-secondary);">
Agent Label / Purpose * Session Label / Purpose *
</label> </label>
<input <input
type="text" type="text"
id="delegateLabel" id="delegateLabel"
placeholder="e.g. Antigravity Coding Assistant, Jules Auto-Refactor, Sync Script" placeholder="e.g. Workshop Guest Pass, Antigravity Assistant, CI/CD Runner, Terminal CLI"
required required
style="width: 100%;" style="width: 100%;"
/> />
@ -306,7 +306,7 @@ export const SessionsPage = ({
<div style="margin-top: 0.75rem; display: flex; flex-direction: column; gap: 0.5rem;"> <div style="margin-top: 0.75rem; display: flex; flex-direction: column; gap: 0.5rem;">
<p style="margin: 0 0 0.5rem 0; font-size: 0.8rem; color: var(--text-secondary);"> <p style="margin: 0 0 0.5rem 0; font-size: 0.8rem; color: var(--text-secondary);">
Select which subsidiary microservices and IAM capabilities this Select which subsidiary microservices and IAM capabilities this
agent token is permitted to access: delegated token is permitted to access:
</p> </p>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 0.5rem;"> <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 0.5rem;">
@ -381,17 +381,18 @@ export const SessionsPage = ({
> >
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem;"> <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem;">
<div style="display: flex; align-items: center; gap: 0.5rem;"> <div style="display: flex; align-items: center; gap: 0.5rem;">
<span style="font-size: 1.2rem;">🤖</span> <span style="font-size: 1.2rem;">🔑</span>
<strong style="color: var(--text-primary); font-size: 1rem;"> <strong style="color: var(--text-primary); font-size: 1rem;">
Agent Session Delegated Successfully! Session Delegated Successfully!
</strong> </strong>
</div> </div>
<span class="badge badge-success">Active Now</span> <span class="badge badge-success">Active Now</span>
</div> </div>
<p style="font-size: 0.85rem; color: var(--text-secondary); margin: 0 0 1rem 0;"> <p style="font-size: 0.85rem; color: var(--text-secondary); margin: 0 0 1rem 0;">
Copy this token or ready-to-run CLI string. You can revoke or extend Copy this token, 1-click magic link, or CLI export string. You can
this token anytime from the active session cards below. revoke or extend this session anytime from the active session cards
below.
</p> </p>
<div style="display: flex; flex-direction: column; gap: 0.75rem; margin-bottom: 1rem;"> <div style="display: flex; flex-direction: column; gap: 0.75rem; margin-bottom: 1rem;">
@ -595,7 +596,7 @@ export const SessionsPage = ({
<td> <td>
<div style="display: flex; align-items: center; gap: 0.5rem;"> <div style="display: flex; align-items: center; gap: 0.5rem;">
<span style="font-size: 1.1rem;"> <span style="font-size: 1.1rem;">
{isAgent ? "🤖" : isCurrent ? "📱" : "💻"} {isAgent ? "🔑" : isCurrent ? "📱" : "💻"}
</span> </span>
<div> <div>
<strong style="color: var(--text-primary);"> <strong style="color: var(--text-primary);">
@ -614,7 +615,7 @@ export const SessionsPage = ({
<span class="badge badge-info"> <span class="badge badge-info">
{scopes.length > 0 {scopes.length > 0
? `${scopes.length} Scopes` ? `${scopes.length} Scopes`
: "Full Access"} : "Delegated"}
</span> </span>
) )
: ( : (
@ -666,7 +667,7 @@ export const SessionsPage = ({
class="btn-outline" class="btn-outline"
style="padding: 0.25rem 0.5rem; font-size: 0.75rem; min-height: 30px;" style="padding: 0.25rem 0.5rem; font-size: 0.75rem; min-height: 30px;"
onclick={`openEditScopesModal('${session.id}', '${ onclick={`openEditScopesModal('${session.id}', '${
session.label || "Agent" session.label || "Delegated"
}', ${ }', ${
JSON.stringify(JSON.stringify(scopes)) JSON.stringify(JSON.stringify(scopes))
})`} })`}
@ -723,7 +724,7 @@ export const SessionsPage = ({
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem;"> <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem;">
<div style="display: flex; align-items: center; gap: 0.65rem;"> <div style="display: flex; align-items: center; gap: 0.65rem;">
<div style="display: flex; align-items: center; justify-content: center; width: 38px; height: 38px; background: var(--surface-muted); border-radius: var(--radius-md); font-size: 1.2rem;"> <div style="display: flex; align-items: center; justify-content: center; width: 38px; height: 38px; background: var(--surface-muted); border-radius: var(--radius-md); font-size: 1.2rem;">
{isAgent ? "🤖" : isCurrent ? "📱" : "💻"} {isAgent ? "🔑" : isCurrent ? "📱" : "💻"}
</div> </div>
<div> <div>
<div style="font-weight: 700; font-size: 0.95rem; color: var(--text-primary);"> <div style="font-weight: 700; font-size: 0.95rem; color: var(--text-primary);">
@ -737,7 +738,7 @@ export const SessionsPage = ({
</div> </div>
{isAgent {isAgent
? <span class="badge badge-info">Agent Token</span> ? <span class="badge badge-info">Delegated</span>
: isCurrent : isCurrent
? <span class="badge badge-success">Active Now</span> ? <span class="badge badge-success">Active Now</span>
: <span class="badge badge-secondary">Active</span>} : <span class="badge badge-secondary">Active</span>}
@ -747,7 +748,7 @@ export const SessionsPage = ({
{isAgent && ( {isAgent && (
<div style="margin-bottom: 0.25rem;"> <div style="margin-bottom: 0.25rem;">
<strong>Scopes:</strong>{" "} <strong>Scopes:</strong>{" "}
{scopes.length > 0 ? scopes.join(", ") : "Full Access"} {scopes.length > 0 ? scopes.join(", ") : "Delegated"}
</div> </div>
)} )}
<div> <div>
@ -780,7 +781,7 @@ export const SessionsPage = ({
class="btn-outline" class="btn-outline"
style="flex: 1; justify-content: center; min-height: 38px; font-size: 0.8rem;" style="flex: 1; justify-content: center; min-height: 38px; font-size: 0.8rem;"
onclick={`openEditScopesModal('${session.id}', '${ onclick={`openEditScopesModal('${session.id}', '${
session.label || "Agent" session.label || "Delegated"
}', ${JSON.stringify(JSON.stringify(scopes))})`} }', ${JSON.stringify(JSON.stringify(scopes))})`}
> >
Scopes Scopes