diff --git a/server/sessionManager.js b/server/sessionManager.js index 0060325..a08b84c 100644 --- a/server/sessionManager.js +++ b/server/sessionManager.js @@ -26,27 +26,13 @@ function buildRoutedPrompt(prompt, lastDirectedMember = null) { if (!targetMember) { return { targetMember: null, - routedPrompt: [ - "[YONLENDIRME NOTU - CEVAPTA TEKRAR ETME]", - "Bu mesaj genel bir gorev veya genel konusmadir.", - "Cevabi once Mazlum baslatsin.", - "Konusan herkes ad etiketi kullansin.", - "[KULLANICI MESAJI]", - prompt - ].join("\n") + routedPrompt: `Not: Bu genel mesajdir. Once Mazlum cevap versin ve konusan herkes ad etiketi kullansin. Kullanici mesaji: ${prompt}` }; } return { targetMember, - routedPrompt: [ - "[YONLENDIRME NOTU - CEVAPTA TEKRAR ETME]", - `Bu mesaj ${targetMember.name} icindir.`, - `Yalnizca ${targetMember.name} cevap versin.`, - `Cevap \`${targetMember.name}:\` ile baslasin.`, - "[KULLANICI MESAJI]", - prompt - ].join("\n") + routedPrompt: `Not: Bu mesaj ${targetMember.name} icindir. Yalnizca ${targetMember.name} cevap versin ve cevap \`${targetMember.name}:\` ile baslasin. Kullanici mesaji: ${prompt}` }; } diff --git a/web/src/App.jsx b/web/src/App.jsx index f7fc3e5..2341512 100644 --- a/web/src/App.jsx +++ b/web/src/App.jsx @@ -1,6 +1,5 @@ import { useState } from "react"; import ShellFrame from "./components/ShellFrame.jsx"; -import StatusStrip from "./components/StatusStrip.jsx"; import SessionToolbar from "./components/SessionToolbar.jsx"; import ChatStream from "./components/ChatStream.jsx"; import PromptComposer from "./components/PromptComposer.jsx"; @@ -32,35 +31,40 @@ export default function App() {

Retro Claude Team Console

- LIVE STREAM - TEAM COMMS - PIXEL MODE + LINK: {connected ? "ONLINE" : "OFFLINE"} + SESSION: {String(session.status || "idle").toUpperCase()} + TEAM: {session.teamActivated ? "ACTIVE" : "STANDBY"} + MODEL: {session.runtime?.anthropicModel || "N/A"} + KEY: {String(session.runtime?.activeKey || "pro").toUpperCase()}
- - runAction(startSession)} - onActivate={() => runAction(activateTeam)} - onStop={() => runAction(stopSession)} - /> - {error ?
{error}
: null}
+
+ +
- + runAction(startSession)} + onActivate={() => runAction(activateTeam)} + onStop={() => runAction(stopSession)} + /> + } + /> runAction(() => sendPrompt(prompt))} />
-
- -
diff --git a/web/src/components/ChatStream.jsx b/web/src/components/ChatStream.jsx index 580b300..94f270d 100644 --- a/web/src/components/ChatStream.jsx +++ b/web/src/components/ChatStream.jsx @@ -1,7 +1,7 @@ import { useEffect, useRef } from "react"; import PanelFrame from "./PanelFrame.jsx"; -export default function ChatStream({ chat, session }) { +export default function ChatStream({ chat, session, headerExtra = null }) { const scrollerRef = useRef(null); useEffect(() => { @@ -16,7 +16,12 @@ export default function ChatStream({ chat, session }) { const isEmpty = !chat.trim(); return ( - +
{isEmpty ? (
diff --git a/web/src/components/PanelFrame.jsx b/web/src/components/PanelFrame.jsx index 9f8e39c..cac1e69 100644 --- a/web/src/components/PanelFrame.jsx +++ b/web/src/components/PanelFrame.jsx @@ -1,4 +1,4 @@ -export default function PanelFrame({ title, eyebrow, children, className = "" }) { +export default function PanelFrame({ title, eyebrow, children, className = "", headerExtra = null }) { return (
@@ -6,6 +6,7 @@ export default function PanelFrame({ title, eyebrow, children, className = "" })

{eyebrow}

{title}

+ {headerExtra ?
{headerExtra}
: null}
{children}
diff --git a/web/src/components/SessionToolbar.jsx b/web/src/components/SessionToolbar.jsx index ced0306..563e242 100644 --- a/web/src/components/SessionToolbar.jsx +++ b/web/src/components/SessionToolbar.jsx @@ -5,7 +5,7 @@ export default function SessionToolbar({ session, busy, onStart, onActivate, onS const isStarting = session.status === "starting"; return ( -
+
Start Session diff --git a/web/src/lib/teamFeed.js b/web/src/lib/teamFeed.js index 879e319..6b9e6ec 100644 --- a/web/src/lib/teamFeed.js +++ b/web/src/lib/teamFeed.js @@ -81,6 +81,8 @@ function isContinuationLine(line) { } return [ + /^[•\-]\s+/.test(trimmed), + /^[0-9]+\.\s+/.test(trimmed), /^[A-Za-zÀ-ÿ0-9ÇĞİÖŞÜçğıöşü"'`(]/.test(trimmed), /^[.!?…]/.test(trimmed), /^💪|^😊|^🚀|^☕|^🎨|^📱/.test(trimmed) @@ -115,7 +117,9 @@ export function parseTeamFeed(chat) { if (speakerMatch) { const member = memberMap.get(normalizeSpeaker(speakerMatch[1])); if (!member) { - currentEntry = null; + if (currentEntry && isContinuationLine(line)) { + currentEntry.text = currentEntry.text ? `${currentEntry.text}\n${line}` : line; + } continue; } diff --git a/web/src/styles/app.css b/web/src/styles/app.css index 07307c3..1bf2121 100644 --- a/web/src/styles/app.css +++ b/web/src/styles/app.css @@ -7,8 +7,8 @@ display: flex; justify-content: space-between; gap: 24px; - align-items: end; - margin-bottom: 24px; + align-items: start; + margin-bottom: 18px; } .app-shell__eyebrow, @@ -39,14 +39,15 @@ display: flex; gap: 10px; flex-wrap: wrap; + justify-content: flex-end; } .app-shell__meta span { - padding: 8px 12px; - border: 2px solid var(--border-mid); - background: rgba(15, 22, 17, 0.8); + padding: 6px 10px; + border: 1px solid rgba(70, 121, 84, 0.45); + background: rgba(15, 22, 17, 0.56); color: var(--text-dim); - font-size: 0.75rem; + font-size: 0.7rem; } .shell-frame { @@ -80,14 +81,6 @@ z-index: 1; } -.status-strip { - display: grid; - grid-template-columns: repeat(5, minmax(0, 1fr)); - gap: 10px; - margin-bottom: 14px; -} - -.status-strip__cell, .panel-frame, .prompt-composer, .error-banner { @@ -96,15 +89,6 @@ background: linear-gradient(180deg, rgba(26, 34, 29, 0.95) 0%, rgba(14, 19, 16, 0.95) 100%); } -.status-strip__cell { - padding: 12px; -} - -.status-strip__cell strong { - font-size: 0.95rem; - letter-spacing: 0.08em; -} - .is-green { color: var(--accent-green); } @@ -125,7 +109,11 @@ display: flex; gap: 12px; flex-wrap: wrap; - margin-bottom: 16px; +} + +.session-toolbar--inline { + justify-content: flex-end; + margin-bottom: 0; } .pixel-button { @@ -191,6 +179,7 @@ display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(320px, 0.9fr); gap: 16px; + align-items: start; } .console-grid__main, @@ -201,14 +190,30 @@ min-width: 0; } +.console-grid__side { + min-width: 0; +} + +.console-grid__main { + min-width: 0; +} + .panel-frame__header { padding: 14px 16px 0; + display: flex; + justify-content: space-between; + gap: 14px; + align-items: start; } .panel-frame__body { padding: 14px 16px 16px; } +.panel-frame__extra { + flex-shrink: 0; +} + .chat-stream, .team-card__body { min-height: 420px; @@ -281,13 +286,16 @@ .team-board { display: grid; - gap: 12px; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 14px; + align-items: start; } .team-card { border: 2px solid var(--border-mid); background: linear-gradient(180deg, rgba(10, 16, 11, 0.92), rgba(8, 12, 9, 0.96)); box-shadow: inset 0 0 0 1px rgba(114, 255, 132, 0.08); + min-height: 348px; } .team-card__header { @@ -342,8 +350,8 @@ } .team-card__body { - min-height: 124px; - max-height: 190px; + min-height: 276px; + max-height: 276px; } .team-message { @@ -373,11 +381,11 @@ } @media (max-width: 1024px) { - .status-strip { - grid-template-columns: repeat(2, minmax(0, 1fr)); + .console-grid { + grid-template-columns: 1fr; } - .console-grid { + .team-board { grid-template-columns: 1fr; } } @@ -393,12 +401,17 @@ align-items: stretch; } - .status-strip { - grid-template-columns: 1fr; - } - .shell-frame__screen { min-height: auto; padding: 12px; } + + .panel-frame__header { + flex-direction: column; + align-items: stretch; + } + + .session-toolbar--inline { + justify-content: stretch; + } }