Compare commits
1 Commits
mimo/build
...
mimo/code/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
808d68cf62 |
88
app.js
88
app.js
@@ -55,11 +55,6 @@ let _clickStartX = 0, _clickStartY = 0; // Mnemosyne: click-vs-drag detection
|
|||||||
let loadProgress = 0;
|
let loadProgress = 0;
|
||||||
let performanceTier = 'high';
|
let performanceTier = 'high';
|
||||||
|
|
||||||
/** Escape HTML entities for safe innerHTML insertion. */
|
|
||||||
function escHtml(s) {
|
|
||||||
return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
|
|
||||||
}
|
|
||||||
|
|
||||||
// ═══ HERMES WS STATE ═══
|
// ═══ HERMES WS STATE ═══
|
||||||
let hermesWs = null;
|
let hermesWs = null;
|
||||||
let wsReconnectTimer = null;
|
let wsReconnectTimer = null;
|
||||||
@@ -70,8 +65,6 @@ let evenniaConnected = false;
|
|||||||
let evenniaStaleTimer = null;
|
let evenniaStaleTimer = null;
|
||||||
const EVENNIA_STALE_MS = 60000; // mark stale after 60s without update
|
const EVENNIA_STALE_MS = 60000; // mark stale after 60s without update
|
||||||
let recentToolOutputs = [];
|
let recentToolOutputs = [];
|
||||||
let actionStreamEntries = []; // Evennia command/result flow for action stream panel
|
|
||||||
let actionStreamRoom = ''; // Current room from movement events
|
|
||||||
let workshopPanelCtx = null;
|
let workshopPanelCtx = null;
|
||||||
let workshopPanelTexture = null;
|
let workshopPanelTexture = null;
|
||||||
let workshopPanelCanvas = null;
|
let workshopPanelCanvas = null;
|
||||||
@@ -2223,71 +2216,6 @@ function handleHermesMessage(data) {
|
|||||||
}
|
}
|
||||||
} else if (data.type && data.type.startsWith('evennia.')) {
|
} else if (data.type && data.type.startsWith('evennia.')) {
|
||||||
handleEvenniaEvent(data);
|
handleEvenniaEvent(data);
|
||||||
// Evennia event bridge — process command/result/room fields if present
|
|
||||||
handleEvenniaEvent(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════
|
|
||||||
// TIMMY ACTION STREAM — EVENNIA COMMAND FLOW
|
|
||||||
// ═══════════════════════════════════════════
|
|
||||||
|
|
||||||
const MAX_ACTION_STREAM = 8;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an entry to the action stream panel.
|
|
||||||
* @param {'cmd'|'result'|'room'} type
|
|
||||||
* @param {string} text
|
|
||||||
*/
|
|
||||||
function addActionStreamEntry(type, text) {
|
|
||||||
const entry = { type, text, ts: Date.now() };
|
|
||||||
actionStreamEntries.unshift(entry);
|
|
||||||
if (actionStreamEntries.length > MAX_ACTION_STREAM) actionStreamEntries.pop();
|
|
||||||
renderActionStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the current room display in the action stream.
|
|
||||||
* @param {string} room
|
|
||||||
*/
|
|
||||||
function setActionStreamRoom(room) {
|
|
||||||
actionStreamRoom = room;
|
|
||||||
const el = document.getElementById('action-stream-room');
|
|
||||||
if (el) el.textContent = room ? `◈ ${room}` : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render the action stream panel entries.
|
|
||||||
*/
|
|
||||||
function renderActionStream() {
|
|
||||||
const el = document.getElementById('action-stream-content');
|
|
||||||
if (!el) return;
|
|
||||||
el.innerHTML = actionStreamEntries.map(e => {
|
|
||||||
const ts = new Date(e.ts).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
|
||||||
const cls = e.type === 'cmd' ? 'as-cmd' : e.type === 'result' ? 'as-result' : 'as-room';
|
|
||||||
const prefix = e.type === 'cmd' ? '>' : e.type === 'result' ? '←' : '◈';
|
|
||||||
return `<div class="as-entry ${cls}"><span class="as-prefix">${prefix}</span> <span class="as-text">${escHtml(e.text)}</span> <span class="as-ts">${ts}</span></div>`;
|
|
||||||
}).join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process Evennia-specific fields from Hermes WS messages.
|
|
||||||
* Called from handleHermesMessage for any message carrying evennia metadata.
|
|
||||||
*/
|
|
||||||
function handleEvenniaEvent(data) {
|
|
||||||
if (data.evennia_command) {
|
|
||||||
addActionStreamEntry('cmd', data.evennia_command);
|
|
||||||
}
|
|
||||||
if (data.evennia_result) {
|
|
||||||
const excerpt = typeof data.evennia_result === 'string'
|
|
||||||
? data.evennia_result.substring(0, 120)
|
|
||||||
: JSON.stringify(data.evennia_result).substring(0, 120);
|
|
||||||
addActionStreamEntry('result', excerpt);
|
|
||||||
}
|
|
||||||
if (data.evennia_room) {
|
|
||||||
setActionStreamRoom(data.evennia_room);
|
|
||||||
addActionStreamEntry('room', `Moved to: ${data.evennia_room}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3119,6 +3047,8 @@ function populateAtlas() {
|
|||||||
let downloadedCount = 0;
|
let downloadedCount = 0;
|
||||||
let visibleCount = 0;
|
let visibleCount = 0;
|
||||||
|
|
||||||
|
let readyCount = 0;
|
||||||
|
|
||||||
portals.forEach(portal => {
|
portals.forEach(portal => {
|
||||||
const config = portal.config;
|
const config = portal.config;
|
||||||
if (config.status === 'online') onlineCount++;
|
if (config.status === 'online') onlineCount++;
|
||||||
@@ -3128,6 +3058,8 @@ function populateAtlas() {
|
|||||||
if (!matchesAtlasFilter(config) || !matchesAtlasSearch(config)) return;
|
if (!matchesAtlasFilter(config) || !matchesAtlasSearch(config)) return;
|
||||||
visibleCount++;
|
visibleCount++;
|
||||||
|
|
||||||
|
if (config.interaction_ready && config.status === 'online') readyCount++;
|
||||||
|
|
||||||
const card = document.createElement('div');
|
const card = document.createElement('div');
|
||||||
card.className = 'atlas-card';
|
card.className = 'atlas-card';
|
||||||
card.style.setProperty('--portal-color', config.color);
|
card.style.setProperty('--portal-color', config.color);
|
||||||
@@ -3153,6 +3085,13 @@ function populateAtlas() {
|
|||||||
// Action label
|
// Action label
|
||||||
const actionLabel = config.destination?.action_label
|
const actionLabel = config.destination?.action_label
|
||||||
|| (config.status === 'online' ? 'ENTER' : config.status === 'downloaded' ? 'LAUNCH' : 'VIEW');
|
|| (config.status === 'online' ? 'ENTER' : config.status === 'downloaded' ? 'LAUNCH' : 'VIEW');
|
||||||
|
const agents = config.agents_present || [];
|
||||||
|
const ready = config.interaction_ready && config.status === 'online';
|
||||||
|
const presenceLabel = agents.length > 0
|
||||||
|
? agents.map(a => a.toUpperCase()).join(', ')
|
||||||
|
: 'No agents present';
|
||||||
|
const readyLabel = ready ? 'INTERACTION READY' : 'UNAVAILABLE';
|
||||||
|
const readyClass = ready ? 'status-online' : 'status-offline';
|
||||||
|
|
||||||
card.innerHTML = `
|
card.innerHTML = `
|
||||||
<div class="atlas-card-header">
|
<div class="atlas-card-header">
|
||||||
@@ -3164,6 +3103,10 @@ function populateAtlas() {
|
|||||||
</div>
|
</div>
|
||||||
<div class="atlas-card-desc">${config.description}</div>
|
<div class="atlas-card-desc">${config.description}</div>
|
||||||
${readinessHTML}
|
${readinessHTML}
|
||||||
|
<div class="atlas-card-presence">
|
||||||
|
<div class="atlas-card-agents">${agents.length > 0 ? 'Agents: ' + presenceLabel : presenceLabel}</div>
|
||||||
|
<div class="atlas-card-ready ${readyClass}">${readyLabel}</div>
|
||||||
|
</div>
|
||||||
<div class="atlas-card-footer">
|
<div class="atlas-card-footer">
|
||||||
<div class="atlas-card-coord">X:${config.position.x} Z:${config.position.z}</div>
|
<div class="atlas-card-coord">X:${config.position.x} Z:${config.position.z}</div>
|
||||||
<div class="atlas-card-action">${actionLabel} →</div>
|
<div class="atlas-card-action">${actionLabel} →</div>
|
||||||
@@ -3194,6 +3137,7 @@ function populateAtlas() {
|
|||||||
document.getElementById('atlas-standby-count').textContent = standbyCount;
|
document.getElementById('atlas-standby-count').textContent = standbyCount;
|
||||||
document.getElementById('atlas-downloaded-count').textContent = downloadedCount;
|
document.getElementById('atlas-downloaded-count').textContent = downloadedCount;
|
||||||
document.getElementById('atlas-total-count').textContent = portals.length;
|
document.getElementById('atlas-total-count').textContent = portals.length;
|
||||||
|
document.getElementById('atlas-ready-count').textContent = readyCount;
|
||||||
|
|
||||||
// Update Bannerlord HUD status
|
// Update Bannerlord HUD status
|
||||||
const bannerlord = portals.find(p => p.config.id === 'bannerlord');
|
const bannerlord = portals.find(p => p.config.id === 'bannerlord');
|
||||||
|
|||||||
10
index.html
10
index.html
@@ -170,15 +170,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Timmy Action Stream (Evennia command/result flow) -->
|
|
||||||
<div id="action-stream" class="action-stream">
|
|
||||||
<div class="action-stream-header">
|
|
||||||
<span class="action-stream-icon">⚡</span> TIMMY ACTION STREAM
|
|
||||||
</div>
|
|
||||||
<div id="action-stream-room" class="action-stream-room"></div>
|
|
||||||
<div id="action-stream-content" class="action-stream-content"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Bottom: Chat Interface -->
|
<!-- Bottom: Chat Interface -->
|
||||||
<div id="chat-panel" class="chat-panel">
|
<div id="chat-panel" class="chat-panel">
|
||||||
<div class="chat-header">
|
<div class="chat-header">
|
||||||
@@ -334,6 +325,7 @@
|
|||||||
<span class="status-indicator downloaded"></span> <span id="atlas-downloaded-count">0</span> DOWNLOADED
|
<span class="status-indicator downloaded"></span> <span id="atlas-downloaded-count">0</span> DOWNLOADED
|
||||||
|
|
||||||
<span class="atlas-total">| <span id="atlas-total-count">0</span> WORLDS TOTAL</span>
|
<span class="atlas-total">| <span id="atlas-total-count">0</span> WORLDS TOTAL</span>
|
||||||
|
<span class="status-indicator online"></span> <span id="atlas-ready-count">0</span> INTERACTION READY
|
||||||
</div>
|
</div>
|
||||||
<div class="atlas-hint">Click a world to focus or enter</div>
|
<div class="atlas-hint">Click a world to focus or enter</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
142
portals.json
142
portals.json
@@ -24,12 +24,28 @@
|
|||||||
"owner": "Timmy",
|
"owner": "Timmy",
|
||||||
"app_id": 22320,
|
"app_id": 22320,
|
||||||
"window_title": "OpenMW",
|
"window_title": "OpenMW",
|
||||||
|
"position": {
|
||||||
|
"x": 15,
|
||||||
|
"y": 0,
|
||||||
|
"z": -10
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"y": -0.5
|
||||||
|
},
|
||||||
"destination": {
|
"destination": {
|
||||||
"url": null,
|
"url": null,
|
||||||
"type": "harness",
|
"type": "harness",
|
||||||
"action_label": "Enter Vvardenfell",
|
"action_label": "Enter Vvardenfell",
|
||||||
"params": { "world": "vvardenfell" }
|
"params": { "world": "vvardenfell" }
|
||||||
}
|
}
|
||||||
|
"params": {
|
||||||
|
"world": "vvardenfell"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"agents_present": [
|
||||||
|
"timmy"
|
||||||
|
],
|
||||||
|
"interaction_ready": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "bannerlord",
|
"id": "bannerlord",
|
||||||
@@ -40,16 +56,36 @@
|
|||||||
"role": "pilot",
|
"role": "pilot",
|
||||||
"position": { "x": -15, "y": 0, "z": -10 },
|
"position": { "x": -15, "y": 0, "z": -10 },
|
||||||
"rotation": { "y": 0.5 },
|
"rotation": { "y": 0.5 },
|
||||||
|
"position": {
|
||||||
|
"x": -15,
|
||||||
|
"y": 0,
|
||||||
|
"z": -10
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
"portal_type": "game-world",
|
"portal_type": "game-world",
|
||||||
"world_category": "strategy-rpg",
|
"world_category": "strategy-rpg",
|
||||||
"environment": "production",
|
"environment": "production",
|
||||||
"access_mode": "operator",
|
"access_mode": "operator",
|
||||||
"readiness_state": "downloaded",
|
"readiness_state": "downloaded",
|
||||||
"readiness_steps": {
|
"readiness_steps": {
|
||||||
"downloaded": { "label": "Downloaded", "done": true },
|
"downloaded": {
|
||||||
"runtime_ready": { "label": "Runtime Ready", "done": false },
|
"label": "Downloaded",
|
||||||
"launched": { "label": "Launched", "done": false },
|
"done": true
|
||||||
"harness_bridged": { "label": "Harness Bridged", "done": false }
|
},
|
||||||
|
"runtime_ready": {
|
||||||
|
"label": "Runtime Ready",
|
||||||
|
"done": false
|
||||||
|
},
|
||||||
|
"launched": {
|
||||||
|
"label": "Launched",
|
||||||
|
"done": false
|
||||||
|
},
|
||||||
|
"harness_bridged": {
|
||||||
|
"label": "Harness Bridged",
|
||||||
|
"done": false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"blocked_reason": null,
|
"blocked_reason": null,
|
||||||
"telemetry_source": "hermes-harness:bannerlord",
|
"telemetry_source": "hermes-harness:bannerlord",
|
||||||
@@ -60,8 +96,12 @@
|
|||||||
"url": null,
|
"url": null,
|
||||||
"type": "harness",
|
"type": "harness",
|
||||||
"action_label": "Enter Calradia",
|
"action_label": "Enter Calradia",
|
||||||
"params": { "world": "calradia" }
|
"params": {
|
||||||
}
|
"world": "calradia"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"agents_present": [],
|
||||||
|
"interaction_ready": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "workshop",
|
"id": "workshop",
|
||||||
@@ -72,11 +112,26 @@
|
|||||||
"role": "timmy",
|
"role": "timmy",
|
||||||
"position": { "x": 0, "y": 0, "z": -20 },
|
"position": { "x": 0, "y": 0, "z": -20 },
|
||||||
"rotation": { "y": 0 },
|
"rotation": { "y": 0 },
|
||||||
|
"position": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": -20
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
"destination": {
|
"destination": {
|
||||||
"url": "https://workshop.timmy.foundation",
|
"url": "https://workshop.timmy.foundation",
|
||||||
"type": "harness",
|
"type": "harness",
|
||||||
"params": { "mode": "creative" }
|
"params": {
|
||||||
}
|
"mode": "creative"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"agents_present": [
|
||||||
|
"timmy",
|
||||||
|
"kimi"
|
||||||
|
],
|
||||||
|
"interaction_ready": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "archive",
|
"id": "archive",
|
||||||
@@ -87,11 +142,25 @@
|
|||||||
"role": "timmy",
|
"role": "timmy",
|
||||||
"position": { "x": 25, "y": 0, "z": 0 },
|
"position": { "x": 25, "y": 0, "z": 0 },
|
||||||
"rotation": { "y": -1.57 },
|
"rotation": { "y": -1.57 },
|
||||||
|
"position": {
|
||||||
|
"x": 25,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"y": -1.57
|
||||||
|
},
|
||||||
"destination": {
|
"destination": {
|
||||||
"url": "https://archive.timmy.foundation",
|
"url": "https://archive.timmy.foundation",
|
||||||
"type": "harness",
|
"type": "harness",
|
||||||
"params": { "mode": "read" }
|
"params": {
|
||||||
}
|
"mode": "read"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"agents_present": [
|
||||||
|
"claude"
|
||||||
|
],
|
||||||
|
"interaction_ready": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "chapel",
|
"id": "chapel",
|
||||||
@@ -102,11 +171,23 @@
|
|||||||
"role": "timmy",
|
"role": "timmy",
|
||||||
"position": { "x": -25, "y": 0, "z": 0 },
|
"position": { "x": -25, "y": 0, "z": 0 },
|
||||||
"rotation": { "y": 1.57 },
|
"rotation": { "y": 1.57 },
|
||||||
|
"position": {
|
||||||
|
"x": -25,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"y": 1.57
|
||||||
|
},
|
||||||
"destination": {
|
"destination": {
|
||||||
"url": "https://chapel.timmy.foundation",
|
"url": "https://chapel.timmy.foundation",
|
||||||
"type": "harness",
|
"type": "harness",
|
||||||
"params": { "mode": "meditation" }
|
"params": {
|
||||||
}
|
"mode": "meditation"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"agents_present": [],
|
||||||
|
"interaction_ready": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "courtyard",
|
"id": "courtyard",
|
||||||
@@ -117,11 +198,26 @@
|
|||||||
"role": "reflex",
|
"role": "reflex",
|
||||||
"position": { "x": 15, "y": 0, "z": 10 },
|
"position": { "x": 15, "y": 0, "z": 10 },
|
||||||
"rotation": { "y": -2.5 },
|
"rotation": { "y": -2.5 },
|
||||||
|
"position": {
|
||||||
|
"x": 15,
|
||||||
|
"y": 0,
|
||||||
|
"z": 10
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"y": -2.5
|
||||||
|
},
|
||||||
"destination": {
|
"destination": {
|
||||||
"url": "https://courtyard.timmy.foundation",
|
"url": "https://courtyard.timmy.foundation",
|
||||||
"type": "harness",
|
"type": "harness",
|
||||||
"params": { "mode": "social" }
|
"params": {
|
||||||
}
|
"mode": "social"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"agents_present": [
|
||||||
|
"timmy",
|
||||||
|
"perplexity"
|
||||||
|
],
|
||||||
|
"interaction_ready": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "gate",
|
"id": "gate",
|
||||||
@@ -132,10 +228,22 @@
|
|||||||
"role": "reflex",
|
"role": "reflex",
|
||||||
"position": { "x": -15, "y": 0, "z": 10 },
|
"position": { "x": -15, "y": 0, "z": 10 },
|
||||||
"rotation": { "y": 2.5 },
|
"rotation": { "y": 2.5 },
|
||||||
|
"position": {
|
||||||
|
"x": -15,
|
||||||
|
"y": 0,
|
||||||
|
"z": 10
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"y": 2.5
|
||||||
|
},
|
||||||
"destination": {
|
"destination": {
|
||||||
"url": "https://gate.timmy.foundation",
|
"url": "https://gate.timmy.foundation",
|
||||||
"type": "harness",
|
"type": "harness",
|
||||||
"params": { "mode": "transit" }
|
"params": {
|
||||||
}
|
"mode": "transit"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"agents_present": [],
|
||||||
|
"interaction_ready": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
96
style.css
96
style.css
@@ -372,7 +372,33 @@ canvas#nexus-canvas {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: var(--color-text-muted);
|
color: var(--color-text-muted);
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.atlas-card-presence {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
background: rgba(0, 0, 0, 0.25);
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid rgba(160, 184, 208, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.atlas-card-agents {
|
||||||
|
font-size: 11px;
|
||||||
|
font-family: var(--font-body);
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.atlas-card-ready {
|
||||||
|
font-size: 9px;
|
||||||
|
font-family: var(--font-body);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.atlas-card-footer {
|
.atlas-card-footer {
|
||||||
@@ -849,70 +875,6 @@ canvas#nexus-canvas {
|
|||||||
color: var(--color-text-muted);
|
color: var(--color-text-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Timmy Action Stream (Evennia command/result flow) — issue #729 */
|
|
||||||
.action-stream {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 200px;
|
|
||||||
right: var(--space-3);
|
|
||||||
width: 320px;
|
|
||||||
max-height: 260px;
|
|
||||||
background: rgba(0, 0, 0, 0.65);
|
|
||||||
backdrop-filter: blur(8px);
|
|
||||||
border-left: 2px solid var(--color-gold);
|
|
||||||
padding: var(--space-3);
|
|
||||||
font-size: 10px;
|
|
||||||
font-family: var(--font-mono);
|
|
||||||
pointer-events: none;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.action-stream-header {
|
|
||||||
font-family: var(--font-display);
|
|
||||||
color: var(--color-gold);
|
|
||||||
letter-spacing: 0.1em;
|
|
||||||
font-size: 10px;
|
|
||||||
margin-bottom: var(--space-2);
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
.action-stream-icon {
|
|
||||||
margin-right: 4px;
|
|
||||||
}
|
|
||||||
.action-stream-room {
|
|
||||||
color: var(--color-primary);
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: 600;
|
|
||||||
margin-bottom: var(--space-1);
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
.action-stream-content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 3px;
|
|
||||||
overflow-y: auto;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.as-entry {
|
|
||||||
animation: log-fade-in 0.4s ease-out forwards;
|
|
||||||
opacity: 0;
|
|
||||||
line-height: 1.4;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
.as-cmd .as-prefix { color: var(--color-gold); font-weight: 700; }
|
|
||||||
.as-cmd .as-text { color: var(--color-gold); opacity: 0.85; }
|
|
||||||
.as-result .as-prefix { color: var(--color-primary); font-weight: 700; }
|
|
||||||
.as-result .as-text { color: var(--color-text-muted); }
|
|
||||||
.as-room .as-prefix { color: var(--color-secondary); font-weight: 700; }
|
|
||||||
.as-room .as-text { color: var(--color-secondary); opacity: 0.8; }
|
|
||||||
.as-ts {
|
|
||||||
color: var(--color-text-muted);
|
|
||||||
opacity: 0.4;
|
|
||||||
font-size: 9px;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Vision Hint */
|
/* Vision Hint */
|
||||||
.vision-hint {
|
.vision-hint {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -1316,10 +1278,6 @@ canvas#nexus-canvas {
|
|||||||
.hud-agent-log {
|
.hud-agent-log {
|
||||||
width: 220px;
|
width: 220px;
|
||||||
}
|
}
|
||||||
.action-stream {
|
|
||||||
width: 240px;
|
|
||||||
bottom: 180px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
|
|||||||
Reference in New Issue
Block a user