Skip to content

feat(ui): one Settings home for the agent — rail, General, Guardrails, Storage, People, one restart banner (ent#887, #888, #890, #891, #353) - #3798

Merged
vybe merged 5 commits into
devfrom
feature/887-agent-settings-home
Oct 19, 2026
Merged

vybe merged 5 commits into
devfrom
feature/887-agent-settings-home

Conversation

@vybe

@vybe vybe commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

Summary

The agent page gets one configuration home: a Settings tab pinned at the end of the strip, with a left rail of panes (General · Guardrails · People · Channels · Integrations · Storage), a "Find a setting" box, and one restart banner that names every change waiting for a restart. The Info, Credentials, Access and Folders tabs are gone; the header is down to identity, state, the autonomy chip and the doors.

Implements (private tracker; closed manually at release):

What's in each pane

  • General — identity (label, id rename, avatar + next emotion, template description, tags), runtime / model / funding, execution timeout (1–120 min, named errors, agent_timeout_below_active_schedules → "Open Schedules"), parallel capacity (names the clamp when stored > ceiling), read-only mode, memory & CPU (with "Inherit default"; saved now, applied by the banner's restart — no longer restarts the agent on save), template technical details in a dialog, Danger zone (reset to main only when a repo is bound; delete).
  • Guardrails — rules (behind "Manage rules"), self-change permissions, approval-gated skills count → Skills, autonomy (read-only), cross-model validation (entitled), reliability.
  • People — AccessPanel embedded, unchanged.
  • Channels / Integrations — the Voice and MCP cards from the old Settings list, plus rows that open the tabs that still hold the rest.
  • Storage — repository binding, GitHub token, auto-sync, credentials, shared folders, file sharing.
  • Git tab keeps the operational half, and gains Pull / Push / Refresh (they lived only in the header).
  • Overview gains AgentLiveStrip (live CPU/memory, spend, created date) from the header.

Deep links keep working: ?tab=info|guardrails|credentials|folders|access resolve to their pane; the pane is in the URL (?section=), so Back steps between panes.

Decisions (confirmed with the operator)

  • Settings is owner-only; shared operators no longer see the Info/Credentials views (they keep Overview's description).
  • The system agent gets General (read-only identity/limits), Guardrails and Integrations.
  • People is shown without the user-management entitlement because it carries OSS sharing.
  • The description is read from the template until a shared editable one exists (abilityai/trinity-enterprise#584).

Restart banner

Rows report into stores/agentRestart.js; the banner lists them and offers Restart (or Start for a stopped agent). The list settles on the agent's real stopped → running status edge, not on the button: a start that fails keeps every entry listed, and a manual stop/start from the header settles it too.

Tests

Red first, then green:

  • tests/unit/agentSettingsHome.spec.js — strip, alias resolution, pane visibility, search, restart registry
  • tests/unit/agentSettingsHome.mount.spec.js — rail navigation through the URL, banner, timeout validation/save/conflict, inherit-default, ceiling note
  • tests/unit/agentSettingsRestart.mount.spec.js — failed start keeps the list; success and manual start settle it
  • tests/unit/fileSharingPanelAudience.spec.js — reports to the banner; agent switch never carries a wait over

Against dev: 13 assertions fail on the missing behaviour. On the branch: 379 files / 6,048 tests pass, check:tokens OK, raw-colour and loading-gate ratchets pass (AgentHeader 132 → 9 raw colour classes), build OK. Visual pass with Playwright in light/dark at 1440 and 390 on a running and a stopped (git-bound) agent: no console errors, no overflow.

Docs

docs/memory/feature-flows/agent-settings-home.md (new), requirements/core-agent.md §1.6–1.7, architecture/frontend.md, and the user docs that named the retired tabs.

🤖 Generated with Claude Code

vybe and others added 4 commits October 18, 2026 14:26
…, Storage, People, one restart banner

The agent page splits into a working strip and ONE Settings tab, pinned at
the end of the strip, with a rail of panes each answering one question
(decision on #966). The pane is in the URL
(?tab=settings&section=…); old ?tab=info|guardrails|credentials|folders|access
links land on their pane.

- General (Abilityai/trinity-enterprise#887): identity (label, id rename,
  avatar, description, tags), runtime/model/funding, execution timeout
  (Abilityai/trinity-enterprise#353 — named range error, #929 schedule
  conflict with an Open Schedules action), parallel capacity, read-only,
  memory/CPU, template details, Danger zone (reset to main only with a bound
  repo; delete). The header keeps identity, state, the autonomy chip and the
  doors; live usage and spend move to Overview; Pull/Push move to the Git tab.
- One restart banner: rows report to stores/agentRestart.js; memory/CPU is
  saved and applied on the next restart instead of restarting at once.
- Guardrails (Abilityai/trinity-enterprise#890): rules, self-change
  permissions (ent#756), gated-skill count, autonomy read-only until
  PR #2984 merges, cross-model validation, reliability.
- Storage (Abilityai/trinity-enterprise#888): repository, GitHub token,
  git sync, credentials, shared folders, file sharing. Credentials and
  Folders tabs removed; Sharing loses Distribution.
- People (Abilityai/trinity-enterprise#891): the Access tab, unchanged.
- Channels/Integrations hold the Voice / MCP cards from the old flat list and
  point at the tabs that still hold the rest.

Red before green: agentSettingsHome.spec.js (7 strip/alias cases) and the
file-sharing restart report fail against dev's agentTabs.js and
FileSharingPanel.vue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…settle the restart banner on the status edge (ent#887, ent#888)

A completeness audit against dev found five controls with no new home and
three defects in the one restart banner:

- Memory/CPU: the "Inherit default" choice is back, so a per-agent override
  can be cleared again; the editor seeds from the override, not the
  effective value, and saves an empty choice as null.
- Capacity: a stored value above the fleet ceiling says so, and names the
  value that applies.
- Git tab: the "Refresh status" button the header had; the Settings › Storage
  link is shown only to owners, who have that tab.
- General › Avatar: "Next emotion" for a prompt-generated avatar.
- Overview: a stopped agent's "Created" line.

- The banner's list is cleared on the agent's stopped → running edge, not by
  the button: a start that fails keeps every waiting change listed (the
  lifecycle composable reports and returns normally, so the old code read a
  failed start as success and lost the guardrails / GitHub-token entries),
  and a manual stop/start from the header settles the list too.
- FileSharingPanel resets on an in-place agent switch, so agent A's
  "restart required" is never announced for agent B.

Also: the two @Interactive e2e specs that deep-linked to ?tab=info now open
Settings › General → Technical details; user docs name Settings › Storage /
People instead of the retired Credentials / Access / Folders tabs.

Red first: agentSettingsRestart.mount.spec.js (failed start kept nothing,
manual start settled nothing), fileSharingPanelAudience.spec.js (switch
carried the wait over), agentSettingsHome.mount.spec.js (no inherit option,
no ceiling note) — 5 assertions red on the previous commit.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…al sources

The agent Settings home (ent#887) deletes components/settings/SettingsPanel.vue.
That component was the agent page's old Settings tab, never part of the platform
Settings view the screenshot shows, and screenshot-guard fails on a missing source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ls pane

The agent Settings home (ent#887) deletes components/settings/SettingsPanel.vue
and mounts ReliabilityPanel in agent-settings/GuardrailsPane.vue. The guard now
reads the pane and asserts the rendered tag, not just the name. Negative control:
removing the <ReliabilityPanel> tag turns it red.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dolho

dolho commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

/review — automated pre-landing review (at refs/pull/3798/head)

Branch: feature/887-agent-settings-home → dev (merge-base 93b57e43d)
Files Changed: 64 (+3076/−1559), frontend plus docs, no backend change
Scope: CLEAN. The diff stays on the Settings home, the retired tabs' redirects and the restart banner. The header slimming and the Git tab's Pull/Push are in the PR description.
Plan Completion: no plan file; the private-tracker issues were not fetched. The four listed panes (General, Guardrails, People, Storage) plus Channels/Integrations are all in the diff.

Execution coverage

changed symbol executed by live consumer verdict
agentRestart.js store, settleRestart, restartForPendingChanges (AgentDetail.vue) agentSettingsRestart.mount.spec.js mounts the real AgentDetail over a fake backend: failed start keeps the list, start clears it, header start settles it SettingsRestartBanner.vue, GitHubAuthRow.vue, GuardrailsPane.vue ✅ executed
agentSettings.js (resolveSettingsSection, filterSections), agentTabs.js aliases agentSettingsHome.spec.js + mount spec AgentSettingsHome.vue, AgentDetail.vue ✅ executed
executionTimeout.js, GeneralPane timeout row mount spec: range refusal, minutes→seconds, schedule conflict GeneralPane.vue ✅ executed
Memory/CPU row + saveResourceLimits mount spec covers "Inherit default" saving null GeneralPane.vue ✅ for the happy path. ❌ nothing drives a failed save or failed reload (see I2)
test_1712_circuit_breaker_honest_toggle.py reads GuardrailsPane.vue text for <ReliabilityPanel CI only 🛡 guard, but source text over a .vue (see appendix)

This is a feature PR, so the fix-mutation rule does not apply.

Critical findings

None.

Informational findings

[I1] Documentation staleness: three feature flows still describe deleted files (Confidence: 8/10)
Evidence: ResourceModal.vue and components/settings/SettingsPanel.vue no longer exist on the branch, yet:

  • docs/memory/feature-flows/agent-guardrails.md:40,160,190,193,323 describes SettingsPanel.vue as the tab container, with line numbers.
  • docs/memory/feature-flows/agent-mcp-key.md:25 says the key panel is "an additive section in settings/SettingsPanel.vue".
  • docs/memory/feature-flows/agent-resource-allocation.md:55,56 documents the ResourceModal import and usage.

Suggestion: run /sync-feature-flows over these three. agent-resource-allocation.md also needs the new behaviour: saving no longer restarts the agent, and the change joins the banner.

[I2] Memory/CPU row dead-ends on a load error (Confidence: 7/10)
File: src/frontend/src/components/agent-settings/GeneralPane.vue:256,262
Evidence: <span v-if="resourceLimits.error" …>Couldn't load the limits.</span> and v-if="canEdit && !resourceLimits.error && editing !== 'resources'" on Edit.
Issue: saveResourceLimits (AgentDetail.vue) always calls loadResourceLimits() after a save, including a failed one. If that reload fails, error is set, Edit disappears, and there is no retry. loadAll in the pane never re-reads limits, so only a page reload or a restart settle clears it. The Storage repository row, in the same PR, does offer "Try again".
Suggestion: add a "Try again" button on the error branch that calls the load, as the repository row does. Add a mount test for a failed save followed by a failed reload.

[I3] Stale comment points at a deleted component (Confidence: 8/10)
File: src/frontend/src/composables/useAgentSettings.js:93
Evidence: // The ResourceModal renders resourceLimits.error as a banner. The modal is deleted and nothing renders a banner now (see I2).
Suggestion: update the comment when fixing I2.

Clean categories

  • SQL / auth / credentials / enterprise disclosure: frontend and docs only. The Settings tab stays gated on agent.can_share, and the pane contents are rendered under v-if="activeTab === 'settings' && agent.can_share" (AgentDetail.vue). No credential values are logged or shown. The added docs name no private modules.
  • Deep links: the aliases info, credentials, folders and access all resolve through TAB_ALIASES + LEGACY_TAB_SECTIONS. The one remaining in-app emitter, OverviewPanel.vue:301, is now v-if="agent.can_share", so a shared operator gets no dead "Full details" link. No backend or MCP code builds ?tab=info|credentials|folders|access URLs (grepped src/backend, src/mcp-server).
  • Restart banner: the status-edge watcher guards name !== prevName and a falsy prevStatus, so loading an agent or switching agents does not settle. A failed start leaves every entry listed (mount spec).
  • Resources semantics: pending is computed against the container labels (agent_config.py current_memory/current_cpu), which are what check_resource_limits_match recreates on. Clearing an override reports no pending, matching the backend's db_limits.get(...) or current rule. The old modal had the same "Inherit default" behaviour, so this is not a regression.
  • Ratchets: raw-colour and loading-gate baselines only shrink (AgentHeader 132 → 9, plus the deleted ResourceModal/SettingsPanel/CapacityPanel entries).

Low confidence (appendix)

  • agentDetailTalkDoor.spec.js drops expect(HEADER_RAW).toContain('target="_blank"'). That line proved the "talk door has no _blank" check wasn't vacuous. The Git row it relied on moved out of the header, so the cross-check can no longer hold as written. Consider asserting the scoped slice is non-empty instead (4/10).
  • test_1712_… asserts "<ReliabilityPanel" in <GuardrailsPane.vue text>. It is the existing pattern, but a mount of GuardrailsPane would prove the panel renders (4/10).

Summary

  • Critical: 0, nothing blocks the merge.
  • Informational: 3 (I1 docs, I2 error dead-end, I3 stale comment).
  • Scope: clean.

I read the diff and the new panes and specs. I did not run the vitest suite or the UI.

Resolve two user-docs conflicts: keep dev's platform-side .credentials.enc
import wording, pointing the manual import at Settings › Storage (the
Credentials tab is retired by this PR).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

⚠️ Live-instance suite skipped — merge conflict against dev.

Resolve by merging dev locally and pushing the result; the next nightly re-tests.

@trinity-ability trinity-ability left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validated via /validate-pr: Lane B, Tier 1 green on 9720dde, dev green. /review informational findings (stale feature flows, GeneralPane resource-limits retry, stale comment) tracked as follow-up.

@vybe
vybe merged commit 52f2910 into dev Oct 19, 2026
26 checks passed
vybe pushed a commit that referenced this pull request Oct 20, 2026
…d Workspace doors out (Abilityai/trinity-enterprise#950) (#3823)

* feat(ui): agent header — repo, tags and a context chart back; Talk and Workspace doors out (Abilityai/trinity-enterprise#950)

Amends the ent#887 header (#3798) per product review:

- Repo line: the bound GitHub repo from the live git status (linked via
  utils/gitRemote.js — http(s)/ssh on a dotted host only, built from host +
  path), branch, "N changed" / "N ahead" / "N behind" or "in sync". Pull/Push
  stay on the Git tab.
- Tags: two BaseBadge chips + a counted "+N"; owners edit in a BaseModal
  around the existing TagsEditor, same update/add/remove-tag handlers.
- Context ring (AgentHeaderContext.vue) for a running agent, fed by
  stores/network.js contextStats through useAgentContextStats (15 s,
  visibility-gated, no stacked requests). Started/stopped in AgentDetail's
  start/stopAllPolling and status watcher, since the page is KeepAlive-cached.
  A 0 / offline reading shows "—", never a 0% ring.
- Talk and Workspace doors removed from the header; the call lives in the
  Workspace composer. armVoiceAutoStart now has no in-app caller (docs say so).
- AgentDetail clears gitStatus on agent switch and on stop, and useGitSync
  drops a git-status answer that lands for a previous agent or after a stop.
- The meta line reserves its height (two lines below sm) so late git/tag data
  never moves the tab strip.

Specs: header mount spec, gitRemote, useAgentContextStats, useGitSync stale
answer; door specs flipped to absence; e2e Talk-door spec split into a
hermetic agent-header spec (worst-case repo/tags at 375/768/1440) and
workspace-voice-query (the ?voice= one-shot cases). source-text baseline
lowered for portalVoiceMode (10 -> 9).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ui): agent header fits 375px and fetches context stats once per load (Abilityai/trinity-enterprise#950)

The first CI run of the new e2e specs caught two defects:

- agent-detail-request-dedupe: /api/agents/context-stats was fetched twice on
  one page load. AgentDetail starts its polls from onMounted, onActivated
  (both fire on a KeepAlive view's first mount) and the running-status
  watcher; useAgentContextStats.start() restarted and re-fetched for each.
  start() is now a no-op while the poll runs.
- agent-header @ 375px: the body scrolled 33px and the repo name was crushed
  to zero width — the header has ~184px of content width and the worded
  count badges alone need ~218px. The repo row now has two inner groups so the
  counts wrap under the name; below `sm` the branch hides and the counts read
  ±N / ↑N / ↓N (words at `sm` and in the tooltip); the name keeps a 4rem
  minimum. The e2e case now also asserts the name stays legible and every
  badge stays inside the header.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ui): Overview trends header wraps at 375px; agent-header e2e names the overflow offender (Abilityai/trinity-enterprise#950)

The second CI run of e2e/agent-header.spec.js measured the page 5px too wide
at 375px with the header itself fitting. The offender is OverviewPanel's
"Activity trends" title row — title + live running/queued counts + the
7d/14d/30d toggle on one rigid non-wrapping row (the #2197 class). It
predates this PR; this spec is the first CI check that measures Agent Detail
at phone width with a running agent. The row now wraps.

The overflow assertion now reports the widest unclipped element, as
body-horizontal-overflow.spec.js does, so the next failure names its cause.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: trinity-ability <309458136+trinity-ability@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
vybe pushed a commit that referenced this pull request Oct 20, 2026
…itcher, toggles, live sparklines, 7-day spend, GitHub line (Abilityai/trinity-enterprise#955)

Operator ruling on the release build: the header goes almost back to the way
it was before the Settings home (#3798). Four rows now:

  1  identity — the ent#955 in-place label pencil and avatar overlay stay;
     the badges regain the funding badge with the overlaid native subscription
     select (owners), which emits the same `change-subscription` the General
     pane does; right: Brain door, context ring, Start/Stop
  2  the Autonomy and Read-only toggles (`toggle-read-only` → the page's
     existing handler), the ent#950 tag chips (AgentHeaderMeta, tags only),
     and the live CPU / MEM / uptime sparklines against the configured limits
     (skeleton before the first sample, allocation when stopped) with a gear
     that opens Settings › General for memory / CPU (`open-resources`)
  3  the 7-day spend row (sparkline, today, trend vs avg, lifetime · runs)
  4  the GitHub line — repo, branch, last commit, changed / ahead / behind —
     only when the live status says a repository is connected, and WITHOUT
     Pull / Push / Refresh: the Git tab keeps the verbs (the one exclusion)

AgentHeaderMeta gains `show-repo` / `show-tags` so the header renders its two
halves in two rows, plus the last-commit sha the old git row showed.
AgentLiveStrip is deleted and Overview no longer shows a strip.

The identity spec pins the restored rows (funding select → change-subscription,
viewer gets no switcher, read-only + gear events, live stats running vs
stopped, spend row gated on a first run); the ent#950 spec pins the commit sha
and the absence of Pull / Push on the GitHub row, and stubs `matchMedia`
hoisted, which the sparklines' module-level theme read needs under jsdom.

The raw-colour baseline is re-frozen in the next commit, on its own.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
vybe pushed a commit that referenced this pull request Oct 20, 2026
…eader (Abilityai/trinity-enterprise#955)

Deliberate growth, named: AgentHeader.vue raw_gray 9 → 53 (the pre-#3798 rows
came back with their chrome ink: toggles divider, live-stats meta, spend row,
gear); AgentHeaderMeta.vue gets its first entry at raw_gray 19 (it was created
after the last freeze; adding the last-commit sha made it worth pinning). No
raw non-gray anywhere in either file; no hex.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
vybe pushed a commit that referenced this pull request Oct 20, 2026
…ing switcher, toggles, live sparklines, 7-day spend, GitHub line, capacity bars (Abilityai/trinity-enterprise#955) (#3826)

* feat(ui): edit the display name and change the avatar in place on the agent header again (Abilityai/trinity-enterprise#955)

ent#887 (#3798) moved the label edit and the avatar prompt into Settings ›
General and ent#950 (#3823) kept the header slim. The operator asked for the
quick path back: a pencil beside the name edits the display label inline
(editor inside the h1 so it inherits the heading's type and ink; pre-filled
with the label, never the slug; Enter/blur save, Esc cancels, empty clears),
and hovering — or focusing into — the avatar shows the camera (no avatar) or
change-prompt + next-emotion (avatar with an identity prompt). Owners only,
never a system agent — the same predicate the General pane uses.

The header emits the SAME three events the General pane's Identity rows emit
(`set-label`, `open-avatar-modal`, `cycle-emotion`), and AgentDetail wires them
to the handlers it already owned, so the two surfaces cannot drift. Settings ›
General keeps its rows; the id rename stays there only (it stops the agent and
re-keys ~20 tables, #1664).

No new raw palette classes: the header's gray count stays at its baseline (9),
the overlay's scrim and ink are `bg-black/40` / `text-white` on a photograph,
the pencil uses action-primary tokens, and the inline editor inherits the h1's
colour. Keyboard reaches the overlay via `group-focus-within`.

Tests: `tests/unit/agentHeaderIdentityEdit.mount.spec.js` mounts the header
(pencil visibility per principal, label-not-slug prefill, Enter/blur/Esc/
unchanged/empty, overlay per avatar state and principal) and shallow-mounts
the page (set-label reaches PUT /label and the heading follows; the modal
opens from the header; `hasAvatarPrompt` is passed). Full frontend unit suite
green (386 files, 6122 tests, ratchets included); `check:tokens` OK.

Docs: requirements core-agent (§ Settings home), feature flows
agent-settings-home + agent-avatars, architecture frontend.md, user-docs
managing-agents.

Closes Abilityai/trinity-enterprise#955

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(ui): the header's inline label editor gets a definite width and swallows its underline (Abilityai/trinity-enterprise#955)

Seen in the browser on the first build: the identity block is content-sized,
so the editor's `w-full` resolved against the input's intrinsic ~20ch and a
long name scrolled its first letters out on select-all; the 2px underline
also dropped the badge rows by 2px while editing. The block and the h1 take
`flex-1` only while editing (at rest nothing moves), and the input carries
`-mb-0.5`. Also drops a `font-inherit` class that is not a Tailwind utility —
preflight already gives the input the heading's font.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* feat(ui): the live strip — CPU/memory and the 7-day spend row — is back in the agent header (Abilityai/trinity-enterprise#955)

ent#887 moved the header's second and third rows (live CPU/memory, and the
7-day cost sparkline with today, trend and lifetime) to the top of Overview as
`AgentLiveStrip`. The operator wants them on the header, where they were.
The header gains a `strip` slot at the card's bottom; AgentDetail slots the
same `AgentLiveStrip` there with a new `embedded` prop (a top rule instead of
card chrome — mutually exclusive class arms, #2662) and no longer renders it on
Overview, so the strip stays one component with one data path and is shown
once. No new raw palette classes in either file.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* feat(ui): the agent header is the pre-#3798 header again — funding switcher, toggles, live sparklines, 7-day spend, GitHub line (Abilityai/trinity-enterprise#955)

Operator ruling on the release build: the header goes almost back to the way
it was before the Settings home (#3798). Four rows now:

  1  identity — the ent#955 in-place label pencil and avatar overlay stay;
     the badges regain the funding badge with the overlaid native subscription
     select (owners), which emits the same `change-subscription` the General
     pane does; right: Brain door, context ring, Start/Stop
  2  the Autonomy and Read-only toggles (`toggle-read-only` → the page's
     existing handler), the ent#950 tag chips (AgentHeaderMeta, tags only),
     and the live CPU / MEM / uptime sparklines against the configured limits
     (skeleton before the first sample, allocation when stopped) with a gear
     that opens Settings › General for memory / CPU (`open-resources`)
  3  the 7-day spend row (sparkline, today, trend vs avg, lifetime · runs)
  4  the GitHub line — repo, branch, last commit, changed / ahead / behind —
     only when the live status says a repository is connected, and WITHOUT
     Pull / Push / Refresh: the Git tab keeps the verbs (the one exclusion)

AgentHeaderMeta gains `show-repo` / `show-tags` so the header renders its two
halves in two rows, plus the last-commit sha the old git row showed.
AgentLiveStrip is deleted and Overview no longer shows a strip.

The identity spec pins the restored rows (funding select → change-subscription,
viewer gets no switcher, read-only + gear events, live stats running vs
stopped, spend row gated on a first run); the ent#950 spec pins the commit sha
and the absence of Pull / Push on the GitHub row, and stubs `matchMedia`
hoisted, which the sparklines' module-level theme read needs under jsdom.

The raw-colour baseline is re-frozen in the next commit, on its own.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* chore(ui): re-freeze the raw-colour baseline for the restored agent header (Abilityai/trinity-enterprise#955)

Deliberate growth, named: AgentHeader.vue raw_gray 9 → 53 (the pre-#3798 rows
came back with their chrome ink: toggles divider, live-stats meta, spend row,
gear); AgentHeaderMeta.vue gets its first entry at raw_gray 19 (it was created
after the last freeze; adding the last-commit sha made it worth pinning). No
raw non-gray anywhere in either file; no hex.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test(ui): stub the sparkline in the header identity spec — jsdom has no canvas 2D context, and its async clearRect failed the run as an unhandled error (Abilityai/trinity-enterprise#955)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(ui): the agent header keeps one footprint while its data lands (Abilityai/trinity-enterprise#955)

Measured on an in-app agent switch: the tab strip moved twice while the
header filled in. Now every late-arriving piece has a reserved home:
  - the slug / description line is always one line tall;
  - the funding badge shows a same-size skeleton until the auth status lands;
  - the 7-day spend row is always rendered — skeleton in flight, "No spend
    yet" after a first fetch that found no runs — at a fixed min-height;
  - the GitHub row is reserved up front for a `github:` template (skeleton
    while running and the status is in flight, a sentence while stopped) and
    otherwise appears only when the live status names a remote;
  - row 2's tag block and live-stats cluster have fixed widths from `sm` up,
    so whether the row wraps no longer depends on which data has arrived
    (the skeleton, the stopped allocation and the running cluster were three
    different widths — a 32px jump a beat after paint).

Pinned by the identity spec (reserved spend row, reserved GitHub row per
template, funding skeleton). Raw-colour baseline: header raw_gray 53 → 63 for
the three skeleton fills, named here rather than re-frozen apart since it is
the same change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(ui): no spinner above a still-rendered agent on an in-app switch (Abilityai/trinity-enterprise#955)

Agent Detail is KeepAlive-cached: on a switch the previous agent stays on
screen for the ~100ms the new one takes to land, and the page's loading
spinner stacked ABOVE it, pushing the header and the tab strip down 112px
and back. The spinner now renders only when there is no agent on screen at
all; a switch is stale-while-loading, like a refresh. Measured: header top,
header height and tab-strip top are constant across a round-trip switch.
Loading-gate baseline regenerated (the gate was narrowed, not added).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* feat(ui): one-line settings row, and an activity + capacity indicator on the agent header (Abilityai/trinity-enterprise#955)

Two operator notes on the restored header. (1) Row 2 broke into two lines:
the live cluster's fixed width was a hair under its running content, so
uptime and the gear dropped under CPU / MEM, and the tags block's fixed width
pushed the cluster itself to a second line. The cluster is now `flex-nowrap`
at a min-width that fits its widest state, and the tags block is `flex-1`
with truncating chips — one line wherever toggles + cluster fit, and the wrap
point no longer moves when data lands. (2) "Is something showing when the
agent is actively working?" — now yes, the dashboard's capacity meter with a
word: a `Working` badge on a pulsing green dot plus the slot bars and
`active/max`, or a quiet `Idle`, beside the context ring for running agents.
"Working" is the WS `workingState` first (instant), else the polled activity
state; the slot count never reads below it, so the bars and the word cannot
disagree. `useAgentContextStats` now also refreshes `fetchSlotStats` on its
15 s tick, so the header and the fleet tile read one map.

Pinned by the identity spec (Idle / Working / WS-before-poll / hidden when
stopped). Raw-colour baseline: header raw_gray 63 → 65 (the `active/max`
meta text), named here.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(ui): drop the uptime label and the gear from the header's live cluster (Abilityai/trinity-enterprise#955)

Operator: the CPU / MEM line carries the sparklines and their limits only.
The `open-resources` emit goes with the gear (memory / CPU are in Settings ›
General, one click away on the tab strip). Raw-colour baseline: header
raw_gray 65 → 59, named here.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(ui): the header's right cluster is Brain, capacity bars, Start/Stop — no Idle/Working word, no slot count, no context ring (Abilityai/trinity-enterprise#955)

Operator: just the capacity indicator. The dashboard's CapacityMeter stands
alone (its own tooltip names the slots); the Working / Idle badge, the
`active/max` text and the ent#950 context ring are gone, and
`AgentHeaderContext.vue` is deleted with its unit and e2e assertions. The
page no longer passes `contextStats` / `working` to the header; the
composable keeps the slot map fresh on its tick. Raw-colour baseline: header
raw_gray 59 → 57, named here.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test(ui): the context-stats composable spec's fake store gains the slot fetch the tick now makes (Abilityai/trinity-enterprise#955)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(ui): a short run lights the header's capacity bars at once (Abilityai/trinity-enterprise#955)

The bars read the slot map, refreshed every 15 s; a task or message that
finishes between two polls never reached them. The WS activity event lands
the moment an execution starts (`stores/network.js::workingState`), so the
composable now exposes it, the header fills one bar on it immediately (the
bars never read below the WS signal), and the slot map is re-read on that
event so the real count follows without waiting for the tick.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(ui): the agent page sees executions start — activity events reach the working map over the app-wide socket (Abilityai/trinity-enterprise#955)

Root cause of "a 10-second task never lights the capacity bars": the fleet
store's WS-driven `workingState` updated only through the store's OWN
socket, which the Dashboard opens on mount and closes on unmount — on the
agent page nothing fed it, so the header's instant signal was dead and the
bars waited for the 15 s slot poll, which a short run slips between. The
app-wide `/ws` (App.vue, `utils/websocket.js`) carries the same
`agent_activity` events; its handler now feeds the store's
`handleActivityStatusChange` for operator roles. The dashboard "working"
chip benefits the same way when the Dashboard is not the page that opened
the socket.

Pinned in websocketWorkspaceOnly.spec.js through the real connect path:
an operator's start/terminal events light and clear the state; a
Workspace-only member's do not touch it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(ui): the capacity bars clear as soon as the run ends (Abilityai/trinity-enterprise#955)

Measured on a 5 s turn: the start event lit the bar at once and re-read the
slot map, but the end event only cleared the WS flag — the map still said
one slot taken until the next 15 s tick, so the bar stayed lit for up to
15 s after the run. The map is now re-read on both edges; measured again:
lit within a second of the start, cleared half a second after the end.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(ui): the header's loading skeletons never widen a 375px page, and each AgentHeaderMeta half carries its own test id (Abilityai/trinity-enterprise#955)

The PR-side e2e run caught two things the mounted specs cannot see:

- At 375px the live cluster's "Loading live usage…" skeleton (`w-64`)
  pushed the page 25px wide. The cluster is now `min-w-0 max-w-full` and
  all three skeletons (live usage, spend, repository) are `max-w-full`,
  so a fixed-width placeholder is bounded by its row.
- `AgentHeaderMeta` is rendered twice (tags half in row 2, repo half in
  row 4) and both carried `data-testid="agent-header-meta"`: Playwright's
  strict mode refused the locator, and the 768px fit check measured the
  badges against the TAGS card's right edge. The repo half keeps
  `agent-header-meta`; the tags half is `agent-header-meta-tags`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: trinity-ability <309458136+trinity-ability@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
alex-furman pushed a commit to alex-furman/trinity that referenced this pull request Oct 27, 2026
…orage (Abilityai/trinity-enterprise#951)

Abilityai#3798 (ent#888) folded the Credentials tab into Settings › Storage, beside
repository, git sync and folders, and pointed ?tab=credentials at Storage.
Credentials answer a different question and are what an operator opens most
often after creating an agent, so they get their own pane again.

- utils/agentSettings.js: a `credentials` section directly after General
  ("What secrets it runs with"), the legacy ?tab=credentials alias lands on
  it, the credential search words move off Storage, and the system agent
  gets it back (it had the Credentials tab before Abilityai#3798).
- CredentialsPane.vue hosts CredentialsPanel embedded; StoragePane drops it.
- CredentialsPanel's file list stops reporting "Not present" for files it
  could not read: a stopped agent says so, a failed first read shows
  LoadFailed with a retry (a failed refresh keeps the data on screen), and an
  agent with no .env gets a next action (Quick Inject, or Add .env). Keyed on
  .env because every agent has a platform-written .mcp.json.
- Credential changes need no restart (.env is re-read at every spawn), so the
  pane reports nothing to the restart banner.

OSS-core by operator decision: a relocation of an existing OSS panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants