From b141900ad76a2946c3a789c60969b52c783d7d05 Mon Sep 17 00:00:00 2001 From: Philip Date: Tue, 4 Aug 2026 13:33:48 -0500 Subject: [PATCH] Office: company switcher tabs + active objective line Tabs render only when more than one active company exists; objective line shows the newest in-progress objective above the canvas. Co-Authored-By: Claude Fable 5 --- engine/static/office.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/engine/static/office.html b/engine/static/office.html index 85718c4..80af465 100644 --- a/engine/static/office.html +++ b/engine/static/office.html @@ -17,6 +17,8 @@

🏠 FarmHouse Office ← dashboard

+
+
…
at desk = building · research room = researching · conference room = blocked, waiting on your answer · water cooler = idle
…
@@ -177,6 +179,9 @@ async function poll() { const co = companies.find(c=>c.slug===want) ?? companies[0]; if (!co) return; companyName = co.name; + document.getElementById('tabs').innerHTML = companies.length > 1 + ? companies.map(c => `${c.name}`).join('') + : ''; const [detail, items, events] = await Promise.all([ fetch(`/companies/${co.slug}`).then(r=>r.json()), fetch(`/companies/${co.slug}/work-items`).then(r=>r.json()), @@ -195,6 +200,9 @@ async function poll() { a.status = e.status; a.taskType = taskType; route(a, targetFor(a, i)); } }); + const activeObj = items.find(w => w.type === 'objective' && w.status === 'in_progress'); + document.getElementById('objline').textContent = + activeObj ? `Objective: ${activeObj.title.slice(0,110)}` : 'No active objective'; const ev = events[0]; if (ev) document.getElementById('ticker').textContent = `${new Date(ev.created_at).toLocaleTimeString()} — ${ev.event_type}: ${JSON.stringify(ev.payload??{}).slice(0,120)}`;