diff --git a/.claude/scheduled_tasks.lock b/.claude/scheduled_tasks.lock new file mode 100644 index 0000000..93b69b8 --- /dev/null +++ b/.claude/scheduled_tasks.lock @@ -0,0 +1 @@ +{"sessionId":"17e654e8-7dd5-4856-85c5-0cfeb7ab736b","pid":3488121,"procStart":"252909119","acquiredAt":1781038486936} \ No newline at end of file diff --git a/index.html b/index.html index 7999d81..9b4c12c 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,7 @@ name="description" content="amerc is an agent mercenary layer for embedding, bringing, and hosting agents across vertical software boundaries." /> - + diff --git a/package.json b/package.json index d980a02..46cc777 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "amerc-site", - "version": "0.26.0-mansion", + "version": "0.27.0-vivid", "private": true, "type": "module", "scripts": { diff --git a/src/AgentPlatform.jsx b/src/AgentPlatform.jsx index 8f91b32..52cbfaf 100644 --- a/src/AgentPlatform.jsx +++ b/src/AgentPlatform.jsx @@ -2,6 +2,9 @@ import React, { useCallback, useEffect, useState } from 'react'; import { api } from './api.js'; const STATUS_COLOR = { online: '#36f0b0', pending: '#f2b85f', lost: '#ff9f5a', down: '#ff7a8c' }; +const TAG_EMOJI = { backend: '๐Ÿ› ๏ธ', model: '๐Ÿง ', frontend: '๐ŸŽจ', ui: '๐Ÿ–Œ๏ธ', web: '๐ŸŒ', data: '๐Ÿ“Š', devops: 'โš™๏ธ', ml: '๐Ÿค–', security: '๐Ÿ”', api: '๐Ÿ”Œ', bot: '๐Ÿค–', chat: '๐Ÿ’ฌ', test: '๐Ÿงช', docs: '๐Ÿ“„', design: 'โœ๏ธ', ops: '๐Ÿšฆ', research: '๐Ÿ”ฌ' }; +const classEmoji = (c) => { for (const t of (c.tags || [])) if (TAG_EMOJI[t]) return TAG_EMOJI[t]; return '๐Ÿ—ก๏ธ'; }; +function avatarStyle(name) { let h = 0; for (const ch of String(name)) h = (h * 31 + ch.charCodeAt(0)) >>> 0; const a = h % 360, b = (a + 70 + h % 90) % 360; return { background: `linear-gradient(135deg, hsl(${a} 68% 46%), hsl(${b} 64% 32%))` }; } // ---- Browse Agents: all public classes, filter by tag -------------------- export function AgentBrowse({ auth, setRoute }) { @@ -38,16 +41,29 @@ export function AgentBrowse({ auth, setRoute }) {
{classes.map((c) => ( ))} - {!classes.length &&

No agent classes yet. Open My Booth to publish one.

} + {!classes.length && ( +
+

No agents here yet โ€” be the first.

+
    +
  1. Publish a class in โ€” name it, tag it (e.g. backend, model).
  2. +
  3. Run an instance โ€” your broker connects and it goes online.
  4. +
  5. Use it โ€” embed it as a chatbox or drive it through a web terminal.
  6. +
+ +
+ )}
{open && { setOpen(null); load(); }} />} diff --git a/src/Scene2D.jsx b/src/Scene2D.jsx index 073ea1e..462e38e 100644 --- a/src/Scene2D.jsx +++ b/src/Scene2D.jsx @@ -6,7 +6,7 @@ import Mansion from './Mansion.jsx'; import TavernGame from './TavernGame.jsx'; import { api } from './api.js'; -const RELEASE = '0.26.0-mansion'; +const RELEASE = '0.27.0-vivid'; const NAV = [ { id: 'home', label: 'Tavern' }, diff --git a/src/styles.css b/src/styles.css index 14d4072..208180d 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1073,3 +1073,17 @@ button { .mn-created p { margin: 0 0 8px; font-size: 13px; color: #d8c4a0; } .mn-created code { background: #07060c; padding: 1px 5px; border-radius: 4px; color: #7fe9ff; } .mn-row { display: flex; align-items: center; gap: 10px; padding: 9px 0; border-bottom: 1px solid #241a36; font-size: 13px; } .mn-row a { color: #27d8ff; } .mn-row span { color: #8a7aa8; margin-left: auto; } + +/* agent card avatars + online pulse + onboarding (0.27 vividness) */ +.ap-card-head2 { display: flex; align-items: center; gap: 11px; } +.ap-avatar { width: 40px; height: 40px; border-radius: 11px; display: flex; align-items: center; justify-content: center; font-size: 20px; flex: none; box-shadow: 0 3px 10px rgba(0,0,0,0.45), inset 0 0 0 1px rgba(255,255,255,0.12); } +.ap-card-titles { display: flex; flex-direction: column; gap: 3px; min-width: 0; } +.ap-card-titles strong { font-size: 15px; color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } +.ap-online i.pulse { box-shadow: 0 0 0 0 rgba(54,240,176,0.7); animation: ap-pulse 1.8s infinite; } +@keyframes ap-pulse { 0% { box-shadow: 0 0 0 0 rgba(54,240,176,0.6); } 70% { box-shadow: 0 0 0 6px rgba(54,240,176,0); } 100% { box-shadow: 0 0 0 0 rgba(54,240,176,0); } } +.ap-empty-start { grid-column: 1 / -1; max-width: 560px; margin: 10px auto; padding: 26px 28px; text-align: left; background: linear-gradient(160deg, #16102a, #0e0a18); border: 1px solid #2a1f3e; border-radius: 16px; box-shadow: 0 14px 40px rgba(0,0,0,0.5); } +.ap-empty-start h3 { margin: 0 0 14px; color: #fff; font-size: 18px; font-family: Georgia, serif; } +.ap-empty-start ol { margin: 0 0 18px; padding-left: 20px; display: flex; flex-direction: column; gap: 10px; } +.ap-empty-start li { color: #c9b8e6; font-size: 13px; line-height: 1.6; } +.ap-empty-start code { background: #07060c; color: #7fe9ff; padding: 1px 6px; border-radius: 4px; } +.ap-link { background: none; color: #27d8ff; cursor: pointer; text-decoration: underline; font: inherit; padding: 0; }