Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions console/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,16 @@
</div>
<div class="drilldown-resizer" id="drilldown-resizer" title="Drag to resize"></div>
<div class="drilldown-side" id="drilldown-side">
<section id="identity" class="identity-wrap"></section>
<!-- Identity (who's managing this cluster) and Remote (the live ACP
connection that powers Agent chat below) read as one unit — both
are supporting status for the same persistent chat, just two
different failure modes (bad credentials vs. no connection) —
so they're visually one box (`.mgmt-combo`) though still two
independently-rendered/tested sections. -->
<div class="mgmt-combo">
<section id="identity" class="identity-wrap"></section>
<section id="remote" class="remote-wrap"></section>
</div>
<section id="chat" class="chat-wrap">
<div class="chat-head">
<span class="chat-title">Agent chat</span>
Expand Down Expand Up @@ -175,7 +184,6 @@
<div id="cfg-editor-mount" class="cfg-editor-mount"></div>
<div class="cfg-editor-error" id="cfg-editor-error" hidden></div>
</section>
<section id="remote" class="remote-wrap"></section>
<!-- Compose (agent-deployment-templates.md: author library → preview →
deploy_provision) is the one surface Part C didn't fully relocate —
`[+ New fleet]`/`[+ Add instance]` (slice 5) reach the same engine as
Expand Down
43 changes: 31 additions & 12 deletions console/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,13 +298,14 @@ async function refreshRemote(): Promise<void> {
// `activeFleet === null` shows the Fleets screen (the `#config` list); a
// selected fleet shows Fleet detail (breadcrumb header + the members roster,
// with each member drilling further into its Agent console — slice 3) instead.
// Remote (management-connection setup) and Compose (template/bundle authoring)
// are Fleets-screen concerns — not relevant once drilled into a fleet/agent, so
// they hide alongside it.
// Compose (template/bundle authoring) is a Fleets-screen concern — not
// relevant once drilled into a fleet/agent, so it hides alongside it. Remote
// now lives in the persistent side column (`.mgmt-combo`, next to Identity) —
// it stays visible at every depth, same as Identity and Agent chat, since
// it's the connection status backing that same persistent chat.
function updateScreen(): void {
if (configEl) configEl.hidden = activeFleet !== null;
if (fleetDetailEl) fleetDetailEl.hidden = activeFleet === null;
if (remoteEl) remoteEl.hidden = activeFleet !== null;
if (composeStandaloneEl) composeStandaloneEl.hidden = activeFleet !== null;
if (activeFleet && fdHeaderEl) renderFleetDetailHeader(fdHeaderEl, activeFleet);
}
Expand Down Expand Up @@ -720,22 +721,40 @@ async function scale(
// already-tested path via a synthetic click rather than duplicating the
// open/dial/teardown logic here. Tries the service-name form first, then the
// short name — the same precedence `filterByMembers` uses for fleet members.
function openAgentForRow(svc: string, alt: string): void {
// `source` is the roster row button that was clicked — every "can't open"
// path flashes feedback on it, since `note()` alone only reaches the (closed)
// Debug drawer's Activity tab and a click that does nothing there reads as
// the roster row simply not working.
function openAgentForRow(svc: string, alt: string, source: HTMLButtonElement): void {
const btn =
document.querySelector<HTMLButtonElement>(
`#agent-list [data-agent="${CSS.escape(svc)}"]`,
) ??
document.querySelector<HTMLButtonElement>(
`#agent-list [data-agent="${CSS.escape(alt)}"]`,
);
if (btn) {
if (btn && !btn.disabled) {
btn.click();
} else {
note(
"info",
`agents: no agent console registered for "${svc}" — add it to agents.toml to open one`,
);
return;
}
const reason = btn
? "registered in agents.toml but not configured (no url/token)"
: "no matching agents.toml entry — or it's the management agent, whose console is already open above";
note("info", `agents: "${alt}" ${reason} — nothing opened`);
flashRowFeedback(source, btn ? "not configured" : "no console");
}

// Briefly relabel the clicked roster button so a click that can't open a
// console still visibly does *something*, instead of looking identical to a
// dead button.
function flashRowFeedback(btn: HTMLButtonElement, label: string): void {
const original = btn.textContent;
btn.disabled = true;
btn.textContent = label;
setTimeout(() => {
btn.textContent = original;
btn.disabled = false;
}, 1800);
}

// One delegated listener on the roster. Start executes on click; Stop is
Expand All @@ -749,7 +768,7 @@ if (roster) {
const openBtn = target.closest<HTMLButtonElement>("button.row-open");
if (openBtn) {
const { openAgent, openAgentAlt } = openBtn.dataset;
if (openAgent) openAgentForRow(openAgent, openAgentAlt ?? openAgent);
if (openAgent) openAgentForRow(openAgent, openAgentAlt ?? openAgent, openBtn);
return;
}
const btn = target.closest<HTMLButtonElement>("button.act");
Expand Down
18 changes: 15 additions & 3 deletions console/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,18 @@ body {
flex-direction: column;
gap: 12px;
}
.drilldown-side > .identity-wrap {
.drilldown-side > .mgmt-combo {
margin: 0;
}
/* Identity + Remote render as two independent sections (still separately
testable pure functions) but share one border/background so they read as
one status box — see the HTML comment above `.mgmt-combo`. */
.mgmt-combo {
display: flex;
flex-direction: column;
}
.mgmt-combo .identity-wrap,
.mgmt-combo .remote-wrap {
margin: 0;
}
.drilldown-side > .chat-wrap {
Expand Down Expand Up @@ -572,7 +583,8 @@ button.act:disabled {
.identity {
border: 1px solid var(--border);
border-left: 3px solid var(--s-running);
border-radius: 6px;
border-bottom: none;
border-radius: 6px 6px 0 0;
background: var(--panel);
padding: 10px 12px;
font-size: 13px;
Expand Down Expand Up @@ -894,7 +906,7 @@ button.act:disabled {
}
.remote {
border: 1px solid var(--border);
border-radius: 6px;
border-radius: 0 0 6px 6px;
background: var(--panel);
padding: 10px 12px;
font-size: 13px;
Expand Down
Loading