agent page: link to the agent's forge profile
Add a '⬡ forge ↗' link to the per-agent page's meta row, next to the stats + screen links. It opens the agent's Forgejo profile (http://<host>:3000/<label> — the per-agent forge user is named after the agent) in a new tab. - web_ui.rs: StateSnapshot gains forge_present, true when the agent's forge-token file exists in the state dir (same signal that tells the agent it has a forge account). - index.html / app.js: hidden link, shown + href-filled when forge_present, mirroring the existing gui_enabled/screen-link pattern. Host comes from window.location so it works off whatever host the page is served from. closes #185
This commit is contained in:
parent
310fd0b481
commit
6ab667901d
4 changed files with 24 additions and 0 deletions
|
|
@ -358,6 +358,10 @@ Layout, top to bottom:
|
||||||
|
|
||||||
- Banner (gradient shimmer while state=thinking).
|
- Banner (gradient shimmer while state=thinking).
|
||||||
- Title with `↑ DASHB04RD` back-link (new tab) + `↻ R3BU1LD`.
|
- Title with `↑ DASHB04RD` back-link (new tab) + `↻ R3BU1LD`.
|
||||||
|
- Meta links row: `📊 stats →`, `🖥 screen →` (shown when
|
||||||
|
`gui_enabled`), and `⬡ forge ↗` (shown when `forge_present` —
|
||||||
|
links to the agent's Forgejo profile at `<host>:3000/<label>`,
|
||||||
|
new tab).
|
||||||
- Status section: empty when online (alive-badge in the state
|
- Status section: empty when online (alive-badge in the state
|
||||||
row carries the signal), populated with the login form /
|
row carries the signal), populated with the login form /
|
||||||
OAuth URL when `status` is `needs_login_*`.
|
OAuth URL when `status` is `needs_login_*`.
|
||||||
|
|
|
||||||
|
|
@ -677,6 +677,17 @@
|
||||||
// Show the screen link when the weston VNC compositor is enabled.
|
// Show the screen link when the weston VNC compositor is enabled.
|
||||||
const screenLink = $('screen-link');
|
const screenLink = $('screen-link');
|
||||||
if (screenLink) screenLink.style.display = s.gui_enabled ? '' : 'none';
|
if (screenLink) screenLink.style.display = s.gui_enabled ? '' : 'none';
|
||||||
|
// Show the forge profile link when this agent has a forge account.
|
||||||
|
// The forge runs on :3000 of the same host; the user is the label.
|
||||||
|
const forgeLink = $('forge-link');
|
||||||
|
if (forgeLink) {
|
||||||
|
if (s.forge_present) {
|
||||||
|
forgeLink.href = `http://${window.location.hostname}:3000/${s.label}`;
|
||||||
|
forgeLink.style.display = '';
|
||||||
|
} else {
|
||||||
|
forgeLink.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
renderTermInput(s.label, s.status === 'online');
|
renderTermInput(s.label, s.status === 'online');
|
||||||
renderInbox(s.inbox || []);
|
renderInbox(s.inbox || []);
|
||||||
// Authoritative state comes from the harness via /api/state.
|
// Authoritative state comes from the harness via /api/state.
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,9 @@
|
||||||
<a href="/stats" style="color: var(--cyan); text-decoration: none;">📊 stats →</a>
|
<a href="/stats" style="color: var(--cyan); text-decoration: none;">📊 stats →</a>
|
||||||
<a id="screen-link" href="/screen" target="_blank" rel="noopener"
|
<a id="screen-link" href="/screen" target="_blank" rel="noopener"
|
||||||
style="display:none; color: var(--cyan); text-decoration: none; margin-left: 1em;">🖥 screen →</a>
|
style="display:none; color: var(--cyan); text-decoration: none; margin-left: 1em;">🖥 screen →</a>
|
||||||
|
<a id="forge-link" href="#" target="_blank" rel="noopener"
|
||||||
|
title="this agent's profile on the hive forge"
|
||||||
|
style="display:none; color: var(--cyan); text-decoration: none; margin-left: 1em;">⬡ forge ↗</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div id="status">
|
<div id="status">
|
||||||
|
|
|
||||||
|
|
@ -383,6 +383,11 @@ struct StateSnapshot {
|
||||||
/// (i.e. `/etc/hyperhive/gui.json` was present at harness startup).
|
/// (i.e. `/etc/hyperhive/gui.json` was present at harness startup).
|
||||||
/// When true, the UI may render a `🖥 screen` link to `/screen`.
|
/// When true, the UI may render a `🖥 screen` link to `/screen`.
|
||||||
gui_enabled: bool,
|
gui_enabled: bool,
|
||||||
|
/// Whether this agent has a Forgejo account wired — its
|
||||||
|
/// `forge-token` file exists in the state dir. When true the UI
|
||||||
|
/// links to the agent's forge profile at `<host>:3000/<label>`
|
||||||
|
/// (the per-agent forge user is named after the agent).
|
||||||
|
forge_present: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
|
@ -485,6 +490,7 @@ async fn api_state(State(state): State<AppState>) -> axum::Json<StateSnapshot> {
|
||||||
ctx_usage,
|
ctx_usage,
|
||||||
cost_usage,
|
cost_usage,
|
||||||
gui_enabled: state.gui_vnc_port.is_some(),
|
gui_enabled: state.gui_vnc_port.is_some(),
|
||||||
|
forge_present: crate::paths::state_dir().join("forge-token").is_file(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue