Watch
0
0
Fork
You've already forked hyperhive
0

Compare commits

..
5 changed files with 52 additions and 3 deletions

View file

@ -82,7 +82,8 @@ agent is stale.
Things blocked on operator decision — the approval queue.
**P3NDING APPR0VALS** — the queue (see "Approval card" below). A
**P3NDING APPR0VALS** — the queue (see "Approval card" below).
The R3QU3ST SP4WN form lives at the top of this section. A
`pending · N` / `history · N` tab pair switches between the live
queue and the last 30 resolved approvals (see "Approval card" for
the history row shape).
@ -135,7 +136,8 @@ page — see below.)
**K3PT ST4T3** — two sub-sections on one pane:
*Tombstones*: agents with kept state and **no container** (size + age +
claude-creds badge). One action: `PURG3` (wipes state + applied
claude-creds badge). Two actions: `⊕ R3V1V3` (queues a Spawn
approval; existing state is reused), `PURG3` (wipes state + applied
dirs; `POST /api/purge-tombstone/{name}`).
⚠️ **Not only *destroyed* agents.** Nothing records a destroy: every

View file

@ -159,8 +159,33 @@ export function renderApprovals() {
// no-op elsewhere — `approval_added` / `approval_resolved` SSE
// events route through here on every page that loads the bundle.
if (!root) return;
// Save spawn form input + focus state before the DOM wipe so a live
// approval_added/resolved event doesn't erase a partially-typed name
// or steal focus from the operator.
const savedSpawnName = root.querySelector('.spawnform input[name="name"]')?.value ?? '';
const spawnHadFocus = document.activeElement === root.querySelector('.spawnform input[name="name"]');
root.replaceChildren();
// Spawn request form: submitting it queues a Spawn approval that
// lands in this same list, so the form belongs here rather than on
// the containers list (the agent doesn't exist yet).
const spawnNameInput = el('input', {
name: 'name',
placeholder: 'new agent name (≤9 chars)',
maxlength: '9', required: '', autocomplete: 'off',
});
if (savedSpawnName) spawnNameInput.value = savedSpawnName;
if (spawnHadFocus) spawnNameInput.focus();
const spawn = el('form', {
method: 'POST', action: '/api/request-spawn',
class: 'spawnform', 'data-async': '', 'data-no-refresh': '',
});
spawn.append(
spawnNameInput,
el('button', { type: 'submit', class: 'btn btn-spawn' }, '◆ R3QU3ST SP4WN'),
);
root.append(spawn);
const pending = approvalsState.pending;
const history = approvalsState.history;
const active = localStorage.getItem(APPROVAL_TAB_KEY) || 'pending';

View file

@ -33,7 +33,7 @@
<main class="core-main">
<!-- K3PT ST4T3: tombstoned-agent kept state + stale permission entries.
tombstones-section shows destroyed agents (purge button).
tombstones-section shows destroyed agents (revive / purge buttons).
tombstones-stale-perms is lazy-loaded on tab activation and shows
agents with explicit capability/tool-group entries but no live
container (typically renamed/deleted agents whose JSON entries

View file

@ -74,6 +74,16 @@ function renderTombstones(s) {
li.append(head);
const actions = el('div', { class: 'actions' });
const respawn = el('form', {
method: 'POST', action: '/api/request-spawn',
class: 'inline', 'data-async': '',
'data-confirm': 'queue spawn approval for ' + t.name + '? state will be reused.',
});
respawn.append(
el('input', { type: 'hidden', name: 'name', value: t.name }),
el('button', { type: 'submit', class: 'btn btn-start' }, '⊕ R3V1V3'),
);
actions.append(respawn);
actions.append(form(
'/api/purge-tombstone/' + t.name, 'btn-destroy', 'PURG3',
'PURGE ' + t.name + '? config history, claude creds, '

View file

@ -610,6 +610,18 @@ hive-agent-menu {
}
ul form.inline { display: inline-block; }
.spawnform { display: flex; gap: 0.6em; align-items: stretch; margin: 0.5em 0; }
.spawnform input {
font-family: inherit;
font-size: 1em;
background: var(--bg-elev);
color: var(--fg);
border: 1px solid var(--border);
padding: 0.4em 0.6em;
flex: 1;
}
.spawnform input::placeholder { color: var(--muted); }
.spawnform input:focus { outline: 1px solid var(--purple); }
.role-pending { color: var(--amber); border-color: var(--amber); }
.btn-inline {
font-family: inherit;