docs(demo): tighten 1-min script to a scannable half-page

This commit is contained in:
Ramis
2026-06-28 11:28:13 -07:00
parent 70b41104ad
commit 28f3236d76
5 changed files with 319 additions and 127 deletions
+89
View File
@@ -7,6 +7,37 @@ each engineer is doing, remembers which interventions helped, and nudges the
team before duplicated work, merge collisions, or missed handoffs slow everyone team before duplicated work, merge collisions, or missed handoffs slow everyone
down. down.
<p align="center">
<a href="https://podman.live/">
<img
alt="Try PodMan live in production"
src="https://img.shields.io/badge/TRY%20PODMAN%20LIVE-https%3A%2F%2Fpodman.live-1f6feb?style=for-the-badge"
/>
</a>
</p>
<h2 align="center">
<a href="https://podman.live/">Open the live production app: https://podman.live/</a>
</h2>
<p align="center">
PodMan is already deployed. Click the link above and try the production app.
</p>
<h2 align="center">
<a href="https://youtu.be/bWJIsIWTgr0">Watch the demo video</a>
</h2>
<p align="center">
<a href="https://youtu.be/bWJIsIWTgr0">
<img
src="https://img.youtube.com/vi/bWJIsIWTgr0/maxresdefault.jpg"
alt="PodMan demo video thumbnail"
width="760"
/>
</a>
</p>
[LiveKit](https://livekit.io/) · [MongoDB](https://www.mongodb.com/) · [LiveKit](https://livekit.io/) · [MongoDB](https://www.mongodb.com/) ·
[Gemini](https://ai.google.dev/) · [Hermes](https://hermes-agent.nousresearch.com/) · [Gemini](https://ai.google.dev/) · [Hermes](https://hermes-agent.nousresearch.com/) ·
[Modular MAX](https://www.modular.com/max) · [Modular MAX](https://www.modular.com/max) ·
@@ -38,6 +69,64 @@ Source image: `~/pic.jpg`, committed as
| Start local development | API, vision agent, and frontend commands are in [Local Development](#local-development) | | Start local development | API, vision agent, and frontend commands are in [Local Development](#local-development) |
| Debug production | Public checks first, then systemd services in [Production Operations](#production-operations) | | Debug production | Public checks first, then systemd services in [Production Operations](#production-operations) |
## Hackathon Fit
PodMan is built for the **2026 AI Engineer World's Fair Hackathon** theme:
**Continual Learning**.
It is not a wrapper chatbot or static dashboard. It is a production-running
agentic coordination system that gets better from real use: every observation,
collision, intervention, accept, dismiss, suppression, and conversation note
feeds MongoDB-backed memory so future interventions become sharper and less
annoying.
| Hackathon target | How PodMan addresses it |
| ---------------------- | ---------------------------------------------------------------------------------------- |
| Continual Learning | Learns from real team behavior and accepted/dismissed interventions. |
| Self-Improvement Stack | Uses memory stats, Hermes jobs, production watchdogs, and deployment checks. |
| Recursive Intelligence | Gives agents operational memory and feedback loops for improving future coordination. |
| Live Demo | Already deployed at [`https://podman.live/`](https://podman.live/). |
| Technicality | Combines realtime media, vision, vector recall, graph traversal, memory, and ops agents. |
| Creativity | Solves the coordination cost around AI-assisted engineering teams. |
### Sponsor Tech Used
| Sponsor / tech | Usage in PodMan |
| -------------- | -------------------------------------------------------------------------------- |
| DigitalOcean | Hosts the production app, API, workers, Caddy, and systemd-supervised services. |
| LiveKit | Realtime room layer for screen share, audio, data messages, and agent presence. |
| Gemini | Screen understanding, live room conversation, urgent TTS, embeddings, and music. |
| MongoDB Atlas | Durable memory, `$vectorSearch`, `$graphLookup`, user learning, and job logs. |
| Modular MAX | Serves `gemma-4-31B-it` as the long-context reasoning model. |
### What To Try
```mermaid
flowchart LR
A["Open podman.live"] --> B["Join a pod"]
B --> C["Share screen via LiveKit"]
C --> D["Gemini extracts work context"]
D --> E["MongoDB recalls prior outcomes"]
E --> F["PodMan nudges only when useful"]
F --> G["Accept or dismiss"]
G --> H["Memory improves next run"]
classDef action fill:#e8f1ff,stroke:#3366cc,color:#0b1f44;
classDef ai fill:#f4edff,stroke:#805ad5,color:#2d1857;
classDef memory fill:#fff6df,stroke:#c47f00,color:#3d2b00;
class A,B,C,F,G action;
class D ai;
class E,H memory;
```
1. Open [`https://podman.live/`](https://podman.live/).
2. Create or join a pod.
3. Add teammates and share screens.
4. Watch PodMan build live context, detect overlap, and surface intervention
cards.
5. Accept or dismiss a card; that feedback becomes memory for the next similar
event.
--- ---
## Current Live System ## Current Live System
+63 -83
View File
@@ -5,7 +5,7 @@
**4-minute script** for the complete story. Practice the 4-min to land at 3:45. **4-minute script** for the complete story. Practice the 4-min to land at 3:45.
**The thesis (say this first, in either script):** AI is collapsing the cost of **The thesis (say this first, in either script):** AI is collapsing the cost of
_writing_ code. More and more of every codebase is authored with AI assist — and *writing* code. More and more of every codebase is authored with AI assist — and
increasingly by **autonomous agents**. So the bottleneck of software engineering increasingly by **autonomous agents**. So the bottleneck of software engineering
is shifting away from engineering itself toward **organization, management, and is shifting away from engineering itself toward **organization, management, and
project coordination**. Pair a team with hundreds of agents all committing to the project coordination**. Pair a team with hundreds of agents all committing to the
@@ -13,8 +13,8 @@ same repo at once and it becomes **physically impossible for a human to track
progress or avoid stepping on someone else's work.** Code generation scaled; progress or avoid stepping on someone else's work.** Code generation scaled;
human coordination did not. That gap is the new bottleneck. human coordination did not. That gap is the new bottleneck.
**The one-line story:** writing code isn't the bottleneck anymore — _coordinating **The one-line story:** writing code isn't the bottleneck anymore — *coordinating
who (and what) is writing what_ is. PodMan is a pair programmer for the whole who (and what) is writing what* is. PodMan is a pair programmer for the whole
team — humans **and** agents: it watches every actor's work in real time, gives team — humans **and** agents: it watches every actor's work in real time, gives
everyone live status without anyone having to interrupt anyone, catches collisions everyone live status without anyone having to interrupt anyone, catches collisions
before they land, and learns your team's dynamics so it nudges less and helps more before they land, and learns your team's dynamics so it nudges less and helps more
@@ -28,85 +28,52 @@ every actor, every day, is the value.
--- ---
## 1-Minute Live Script (you + teammates — real-time interventions) ## 1-Minute Live Script (you + teammates — real-time interventions)
**Goal:** in 60 seconds, prove the unprecedented loop — real-time multimodal **Hard limit 1:00.** Hits the tracks: real-time multimodal, on-device Gemma,
perception → live collision intervention spoken by an **on-device Gemma model** Continual Learning, Self-Improvement, Recursive Intelligence.
→ a **self-improving** coordination layer. Hits four judging tracks: Continual
Learning, the Self-Improvement Stack, Recursive Intelligence, and on-device
Gemma. **Hard limit:** 1:00.
**Pre-flight (do NOT skip — these are the win conditions):** **Pre-flight:** pod open on `podman.live`, all joined, screen share + **sound on**;
git watchers running; everyone has `README.md` open. On-device **Gemma** must be
up as Hermes's voice (else Gemini TTS auto-falls-back — just drop the "on-device"
word).
- **On-device Gemma must be committed and running** as Hermes's voice/reasoning **0:000:12 — Thesis**
layer before showtime. Verify it speaks once in rehearsal. If it isn't up, > "Code is almost free to write now — humans with AI, soon swarms of agents, all
PodMan **automatically falls back to Gemini TTS** — the demo still works, you > on one repo. No human can track that. The bottleneck is coordination — and it
just drop the "on-device" line. Never debug Gemma on stage. > has to fix itself, live. Watch."
- Pod open on the shared screen (`podman.live`), all teammates joined, screen
share on, **sound on** — voice is live for _every_ intervention now.
- Each teammate's git watcher running so local unpushed edits report in.
- Everyone has `README.md` open, ready to type. Pre-pick the first colliding
pair (you + a teammate).
### 0:000:12The thesis (one breath) **0:120:35Collision caught live (money shot)**
- You + a teammate both edit `README.md`, save (unpushed).
- Card appears on every screen + voice fires: _"<you> and <teammate> are both
editing README.md. Sync before pushing."_
- Say: "Gemini Vision reads our screens, fused with local git, in real time —
and the alert is **spoken by a Gemma model on-device**. Neither of us asked."
> "Code is almost free to write now — humans with AI today, swarms of autonomous **0:350:52 — Self-improving (narrate)**
> agents tomorrow, all committing to one repo. No human can track that. The - Third teammate edits too → **new** card + voice for the new pair (never goes
> bottleneck stopped being engineering and became coordination — and it has to silent).
> fix itself, on its own, in real time. Watch." - Say: "Every trace lands in **Atlas**; vector search recalls past collisions,
repeats come back tagged **'Seen before'** and escalate — no retraining. It
tunes its own coordination from its own outcomes."
_On screen:_ pod view, teammate tiles live, activity stream moving. **0:521:00 — Close**
> "Real-time awareness, on-device voice, a coordination layer that improves
> itself — for humans and agents, zero interruptions."
### 0:120:32 — Real-time perception → live intervention (the money shot) _Fallback:_ Gemma down → drop the on-device line. Voice silent → read it, point
at the card. No card → switch the pair to a fresh file and re-save.
- On cue, **you and one teammate both edit `README.md`** and save (unpushed).
- A **conflict card appears on everyone's screen** within a cycle: _"Conflict:
<you> + <teammate> both on README.md (unpushed)."_
- The voice fires out loud over LiveKit: _"<you> and <teammate> are both editing
README.md. Please sync before pushing."_
- Land both the perception and the on-device beat: "PodMan is reading our actual
screens with **Gemini Vision** and fusing local git truth in real time — then
that alert is reasoned and **spoken by a Gemma model running on-device**, no
round-trip to a frontier API. Real-time multimodal in, on-device voice out.
Neither of us asked. Neither of us was watching."
### 0:320:48 — Self-improving coordination (narrate the stack)
- Have a **third teammate** edit the same file (or a second one). A **new** card
+ voice fires for the new pair — _it never goes silent on later collisions._
- Narrate the self-improvement architecture (no trigger needed — it's running):
"Every intervention and every accept/dismiss is a trace in **MongoDB Atlas**.
PodMan recalls similar past collisions with **vector search**, an
outcome-conditioned policy adapts who to nudge and how, and repeats come back
tagged **'Seen before'** and escalate automatically. That's the
self-improvement stack — it gets sharper the more the team uses it, with no
retraining and almost no human input. The recursive part: it's tuning its own
coordination behavior from its own logged outcomes."
### 0:481:00 — Close
> "Real-time multimodal awareness, on-device voice, and a coordination layer that
> improves itself from every interaction — for a whole team of humans and agents,
> with zero interruptions. That's the layer code generation never had."
**Track callouts (say at least the bolded word in each):**
| Track | Spoken moment |
| ----------------------- | -------------------------------------------------------- |
| Real-time multimodal | "reading our screens with **Gemini Vision** … real time" |
| **On-device Gemma** | "spoken by a **Gemma** model running **on-device**" |
| Continual Learning | "recalls past collisions … **'Seen before'** … no retraining" |
| Self-Improvement Stack | "every trace in **Atlas** … outcome-conditioned policy" |
| Recursive Intelligence | "tuning its **own** coordination behavior from its outcomes" |
_Fallbacks:_ Gemma down → drop the on-device line, Gemini TTS covers it. Voice
silent → read the line aloud, point at the card (cards are the default path).
Card won't trigger → switch the colliding pair to a fresh file and re-save.
--- ---
## The script (4:00) ## The script (4:00)
### 0:000:30 — The problem + hook ### 0:000:30 — The problem + hook
> "AI made writing code almost free — humans with AI today, swarms of autonomous > "AI made writing code almost free — humans with AI today, swarms of autonomous
@@ -119,7 +86,7 @@ Card won't trigger → switch the colliding pair to a fresh file and re-save.
> interrupting them, catches collisions before they land, and learns your team as > interrupting them, catches collisions before they land, and learns your team as
> it goes." > it goes."
_On screen:_ the pod view, two teammates joined, screen-share tiles live. *On screen:* the pod view, two teammates joined, screen-share tiles live.
### 0:301:05 — Real-time team awareness (LiveKit + Gemini Vision) ### 0:301:05 — Real-time team awareness (LiveKit + Gemini Vision)
@@ -129,10 +96,10 @@ _On screen:_ the pod view, two teammates joined, screen-share tiles live.
symbol, activity — not a chatbot, a perception layer." symbol, activity — not a chatbot, a perception layer."
- Show the live activity stream filling in (Signals vs Reasoning sections). - Show the live activity stream filling in (Signals vs Reasoning sections).
- Land the value: "This is the part that replaces 'what are you working on?' — - Land the value: "This is the part that replaces 'what are you working on?' —
every teammate's current work is just _visible_, in real time. Nobody had to every teammate's current work is just *visible*, in real time. Nobody had to
ask." ask."
_Built-by-us callout:_ `backend/src/vision/gemini.ts`, the LiveKit agent worker. *Built-by-us callout:* `backend/src/vision/gemini.ts`, the LiveKit agent worker.
### 1:051:40 — The catch (detection + first intervention) ### 1:051:40 — The catch (detection + first intervention)
@@ -140,27 +107,27 @@ _Built-by-us callout:_ `backend/src/vision/gemini.ts`, the LiveKit agent worker.
- "Normally nobody notices until merge time. GitHub can't see this — nothing's - "Normally nobody notices until merge time. GitHub can't see this — nothing's
pushed. Our detector fuses live screen context with **local git truth** from a pushed. Our detector fuses live screen context with **local git truth** from a
watcher on each laptop." watcher on each laptop."
- A collision card appears: _"alice + bob both on detector.ts (unpushed)."_ - A collision card appears: *"alice + bob both on detector.ts (unpushed)."*
- Let the **Gemini TTS** urgent voice fire once over LiveKit: _"alice and bob are - Let the **Gemini TTS** urgent voice fire once over LiveKit: *"alice and bob are
both editing detector.ts. Please sync before pushing."_ both editing detector.ts. Please sync before pushing."*
- Land the value: "That's a merge conflict and a wasted afternoon caught before it - Land the value: "That's a merge conflict and a wasted afternoon caught before it
happened — and neither of them had to be tracking the other." happened — and neither of them had to be tracking the other."
_Built-by-us callout:_ `collision/detector.ts`, `action/hermes.ts`, *Built-by-us callout:* `collision/detector.ts`, `action/hermes.ts`,
`voice/live.ts`. `voice/live.ts`.
### 1:402:10 — Cross-channel overlap (research + code) ### 1:402:10 — Cross-channel overlap (research + code)
- Keep alice editing `livekit.py`. - Keep alice editing `livekit.py`.
- Have bob share a browser tab on LiveKit docs/SDK pages. - Have bob share a browser tab on LiveKit docs/SDK pages.
- A collaboration nudge appears: _"🤝 bob is researching LiveKit agents - A collaboration nudge appears: *"🤝 bob is researching LiveKit agents
(docs.livekit.io) while alice edits livekit.py — sync up before duplicating (docs.livekit.io) while alice edits livekit.py — sync up before duplicating
effort."_ effort."*
- Land the value: "This is not a merge conflict. PodMan caught duplicated effort - Land the value: "This is not a merge conflict. PodMan caught duplicated effort
across channels — code on one screen, research on another — and nudged the team across channels — code on one screen, research on another — and nudged the team
before two people solved the same problem twice." before two people solved the same problem twice."
_Built-by-us callout:_ `vision/gemini.ts`, `collision/research.ts`, *Built-by-us callout:* `vision/gemini.ts`, `collision/research.ts`,
`memory/vectors.ts`. `memory/vectors.ts`.
### 2:102:50 — Continual learning (the theme — the money shot) ### 2:102:50 — Continual learning (the theme — the money shot)
@@ -179,15 +146,15 @@ This is the differentiator. Two beats, both from pre-seeded memory:
that adapts on the recalled outcome." that adapts on the recalled outcome."
- Optional: show `/api/memory/stats` counts climbing — accumulated experience. - Optional: show `/api/memory/stats` counts climbing — accumulated experience.
_Built-by-us callout:_ `memory/vectors.ts` ($vectorSearch), `memory/policy.ts` *Built-by-us callout:* `memory/vectors.ts` ($vectorSearch), `memory/policy.ts`
(outcome-conditioned gate), `memory/store.ts`. (outcome-conditioned gate), `memory/store.ts`.
### 2:503:30 — The five-minute meeting, killed (Gemini Live API) ### 2:503:30 — The five-minute meeting, killed (Gemini Live API)
- Frame it: "Instead of breaking a teammate's focus to ask what they're up to, - Frame it: "Instead of breaking a teammate's focus to ask what they're up to,
you ask PodMan." you ask PodMan."
- Open the live voice conversation. Ask out loud: _"PodMan, what is everyone - Open the live voice conversation. Ask out loud: *"PodMan, what is everyone
working on, and where is the collision detector implemented?"_ working on, and where is the collision detector implemented?"*
- It answers with **real tool calls**`search_repo`, git history, current - It answers with **real tool calls**`search_repo`, git history, current
collisions — not guesses. collisions — not guesses.
- "This is the **Gemini Live API**, streaming speech-to-speech over LiveKit, with - "This is the **Gemini Live API**, streaming speech-to-speech over LiveKit, with
@@ -195,7 +162,7 @@ _Built-by-us callout:_ `memory/vectors.ts` ($vectorSearch), `memory/policy.ts`
and live state. That's the status sync, answered in seconds, with zero recovery and live state. That's the status sync, answered in seconds, with zero recovery
tax on anyone else." tax on anyone else."
_Built-by-us callout:_ `agents/podman-live-conversation/agent.py`. *Built-by-us callout:* `agents/podman-live-conversation/agent.py`.
### 3:303:50 — Stack + close ### 3:303:50 — Stack + close
@@ -209,12 +176,17 @@ _Built-by-us callout:_ `agents/podman-live-conversation/agent.py`.
helps more over time. Saved focus, multiplied across every actor. That's helps more over time. Saved focus, multiplied across every actor. That's
continual learning, shipped." continual learning, shipped."
### 3:504:00 — Buffer / Q&A handoff ### 3:504:00 — Buffer / Q&A handoff
--- ---
## Sponsor-prize coverage (say each at least once) ## Sponsor-prize coverage (say each at least once)
| Prize | Spoken moment | Segment | | Prize | Spoken moment | Segment |
| ---------------- | -------------------------------------------------------------------------------- | ---------------------- | | ---------------- | -------------------------------------------------------------------------------- | ---------------------- |
| **Gemini** | Vision perception, Live API agent w/ tools, TTS voice, Lyria score | 0:30, 1:05, 2:50, 3:30 | | **Gemini** | Vision perception, Live API agent w/ tools, TTS voice, Lyria score | 0:30, 1:05, 2:50, 3:30 |
@@ -222,10 +194,14 @@ _Built-by-us callout:_ `agents/podman-live-conversation/agent.py`.
| **MongoDB** | "Atlas vector search recalling past events" | 1:50 | | **MongoDB** | "Atlas vector search recalling past events" | 1:50 |
| **DigitalOcean** | "all on DigitalOcean, systemd-supervised workers" | 3:30 | | **DigitalOcean** | "all on DigitalOcean, systemd-supervised workers" | 3:30 |
--- ---
## If something breaks (live recovery) ## If something breaks (live recovery)
| Failure | Recovery | | Failure | Recovery |
| ----------------------- | ----------------------------------------------------------------------- | | ----------------------- | ----------------------------------------------------------------------- |
| Voice doesn't fire | Cut to the card; say the line aloud; cards are the default path anyway. | | Voice doesn't fire | Cut to the card; say the line aloud; cards are the default path anyway. |
@@ -233,12 +209,16 @@ _Built-by-us callout:_ `agents/podman-live-conversation/agent.py`.
| Collision won't trigger | Use the backup recording for that beat; keep narrating. | | Collision won't trigger | Use the backup recording for that beat; keep narrating. |
| Agent flapping | Pre-checked — but if so, `systemctl restart podman-platform-agent`. | | Agent flapping | Pre-checked — but if so, `systemctl restart podman-platform-agent`. |
**Rule:** never debug on stage. Narrate, fall back to recording, keep moving. **Rule:** never debug on stage. Narrate, fall back to recording, keep moving.
--- ---
## Tight timing summary ## Tight timing summary
| Time | Beat | | Time | Beat |
| ---- | ---------------------------------------------------------- | | ---- | ---------------------------------------------------------- |
| 0:00 | Problem (coordination cost) + hook + original-work line | | 0:00 | Problem (coordination cost) + hook + original-work line |
+63 -6
View File
@@ -1,7 +1,64 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"> <svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
<rect width="32" height="32" rx="7" fill="#0b0f17" /> <title id="title">PodMan Logo Mark</title>
<circle cx="25" cy="6.6" r="2.4" fill="#34d399" /> <desc id="desc">A minimal rounded robot head with glowing eyes and a blue-violet antenna orb, optimized for white backgrounds.</desc>
<text x="14.5" y="24.5" text-anchor="middle" <defs>
font-family="ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" <filter id="softShadow" x="44" y="90" width="424" height="360" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
font-weight="700" font-size="24" fill="#34d399">P</text> <feDropShadow dx="0" dy="14" stdDeviation="20" flood-color="#94A3B8" flood-opacity="0.22"/>
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="#C7D2FE" flood-opacity="0.20"/>
</filter>
<filter id="eyeGlow" x="138" y="234" width="236" height="96" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="6" result="blur"/>
<feColorMatrix in="blur" type="matrix" values="0 0 0 0 0.27 0 0 0 0 0.42 0 0 0 0 1 0 0 0 0.78 0" result="glow"/>
<feMerge>
<feMergeNode in="glow"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<linearGradient id="shell" x1="122" y1="144" x2="390" y2="420" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#FFFFFF"/>
<stop offset="0.56" stop-color="#F7FAFF"/>
<stop offset="1" stop-color="#EDF3FF"/>
</linearGradient>
<linearGradient id="face" x1="154" y1="220" x2="358" y2="334" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#050A1F"/>
<stop offset="0.48" stop-color="#081038"/>
<stop offset="1" stop-color="#10237A"/>
</linearGradient>
<linearGradient id="orb" x1="218" y1="38" x2="292" y2="113" gradientUnits="userSpaceOnUse">
<stop stop-color="#65D5FF"/>
<stop offset="0.46" stop-color="#6A65FF"/>
<stop offset="1" stop-color="#9A5CFF"/>
</linearGradient>
<radialGradient id="eye" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(256 280) rotate(90) scale(18)">
<stop offset="0" stop-color="#FFFFFF"/>
<stop offset="0.55" stop-color="#F6FBFF"/>
<stop offset="1" stop-color="#C8DDFF"/>
</radialGradient>
<linearGradient id="antenna" x1="256" y1="86" x2="256" y2="158" gradientUnits="userSpaceOnUse">
<stop stop-color="#4F63FF"/>
<stop offset="1" stop-color="#1E3A8A"/>
</linearGradient>
</defs>
<!-- transparent background; tuned to read clearly on white surfaces -->
<!-- Antenna -->
<rect x="250" y="87" width="12" height="82" rx="6" fill="url(#antenna)"/>
<circle cx="256" cy="70" r="31" fill="url(#orb)"/>
<circle cx="244" cy="56" r="9" fill="white" opacity="0.38"/>
<!-- Head shell -->
<g filter="url(#softShadow)">
<rect x="96" y="146" width="320" height="260" rx="92" fill="url(#shell)" stroke="#DDE6F3" stroke-width="2"/>
<rect x="104" y="154" width="304" height="244" rx="84" stroke="white" stroke-opacity="0.84" stroke-width="12"/>
</g>
<!-- Face visor -->
<g filter="url(#eyeGlow)">
<rect x="146" y="226" width="220" height="104" rx="46" fill="url(#face)"/>
<circle cx="202" cy="278" r="18" fill="url(#eye)"/>
<circle cx="310" cy="278" r="18" fill="url(#eye)"/>
<circle cx="202" cy="278" r="8" fill="white" opacity="0.96"/>
<circle cx="310" cy="278" r="8" fill="white" opacity="0.96"/>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 416 B

After

Width:  |  Height:  |  Size: 3.3 KiB

+64
View File
@@ -0,0 +1,64 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
<title id="title">PodMan Logo Mark</title>
<desc id="desc">A minimal rounded robot head with glowing eyes and a blue-violet antenna orb, optimized for white backgrounds.</desc>
<defs>
<filter id="softShadow" x="44" y="90" width="424" height="360" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feDropShadow dx="0" dy="14" stdDeviation="20" flood-color="#94A3B8" flood-opacity="0.22"/>
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="#C7D2FE" flood-opacity="0.20"/>
</filter>
<filter id="eyeGlow" x="138" y="234" width="236" height="96" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="6" result="blur"/>
<feColorMatrix in="blur" type="matrix" values="0 0 0 0 0.27 0 0 0 0 0.42 0 0 0 0 1 0 0 0 0.78 0" result="glow"/>
<feMerge>
<feMergeNode in="glow"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<linearGradient id="shell" x1="122" y1="144" x2="390" y2="420" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#FFFFFF"/>
<stop offset="0.56" stop-color="#F7FAFF"/>
<stop offset="1" stop-color="#EDF3FF"/>
</linearGradient>
<linearGradient id="face" x1="154" y1="220" x2="358" y2="334" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#050A1F"/>
<stop offset="0.48" stop-color="#081038"/>
<stop offset="1" stop-color="#10237A"/>
</linearGradient>
<linearGradient id="orb" x1="218" y1="38" x2="292" y2="113" gradientUnits="userSpaceOnUse">
<stop stop-color="#65D5FF"/>
<stop offset="0.46" stop-color="#6A65FF"/>
<stop offset="1" stop-color="#9A5CFF"/>
</linearGradient>
<radialGradient id="eye" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(256 280) rotate(90) scale(18)">
<stop offset="0" stop-color="#FFFFFF"/>
<stop offset="0.55" stop-color="#F6FBFF"/>
<stop offset="1" stop-color="#C8DDFF"/>
</radialGradient>
<linearGradient id="antenna" x1="256" y1="86" x2="256" y2="158" gradientUnits="userSpaceOnUse">
<stop stop-color="#4F63FF"/>
<stop offset="1" stop-color="#1E3A8A"/>
</linearGradient>
</defs>
<!-- transparent background; tuned to read clearly on white surfaces -->
<!-- Antenna -->
<rect x="250" y="87" width="12" height="82" rx="6" fill="url(#antenna)"/>
<circle cx="256" cy="70" r="31" fill="url(#orb)"/>
<circle cx="244" cy="56" r="9" fill="white" opacity="0.38"/>
<!-- Head shell -->
<g filter="url(#softShadow)">
<rect x="96" y="146" width="320" height="260" rx="92" fill="url(#shell)" stroke="#DDE6F3" stroke-width="2"/>
<rect x="104" y="154" width="304" height="244" rx="84" stroke="white" stroke-opacity="0.84" stroke-width="12"/>
</g>
<!-- Face visor -->
<g filter="url(#eyeGlow)">
<rect x="146" y="226" width="220" height="104" rx="46" fill="url(#face)"/>
<circle cx="202" cy="278" r="18" fill="url(#eye)"/>
<circle cx="310" cy="278" r="18" fill="url(#eye)"/>
<circle cx="202" cy="278" r="8" fill="white" opacity="0.96"/>
<circle cx="310" cy="278" r="8" fill="white" opacity="0.96"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

+15 -13
View File
@@ -9,11 +9,7 @@ import {
useUser, useUser,
} from '@clerk/react'; } from '@clerk/react';
import type { Room } from 'livekit-client'; import type { Room } from 'livekit-client';
import { import { AlertCircleIcon, RefreshCwIcon, SparklesIcon } from 'lucide-react';
AlertCircleIcon,
RefreshCwIcon,
SparklesIcon,
} from 'lucide-react';
import type { Pod, PodInput } from '@podman/shared'; import type { Pod, PodInput } from '@podman/shared';
import { joinPod } from './lib/pod.js'; import { joinPod } from './lib/pod.js';
import * as api from './lib/api.js'; import * as api from './lib/api.js';
@@ -342,9 +338,12 @@ export default function App() {
<header className="sticky top-0 z-10 -mx-4 border-b bg-background/86 px-4 pb-4 pt-2 backdrop-blur-xl sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8"> <header className="sticky top-0 z-10 -mx-4 border-b bg-background/86 px-4 pb-4 pt-2 backdrop-blur-xl sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
<div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between"> <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
<div className="flex min-w-0 items-center gap-3"> <div className="flex min-w-0 items-center gap-3">
<div className="grid size-10 place-items-center rounded-lg bg-primary text-sm font-semibold text-primary-foreground shadow-sm"> <img
PM src="/podman-logo.svg"
</div> alt=""
className="size-11 shrink-0 rounded-lg"
aria-hidden="true"
/>
<div className="min-w-0"> <div className="min-w-0">
<h1 className="text-[1.95rem] font-semibold leading-none tracking-tight">PodMan</h1> <h1 className="text-[1.95rem] font-semibold leading-none tracking-tight">PodMan</h1>
</div> </div>
@@ -468,9 +467,12 @@ function AuthGate() {
<div className="mx-auto flex min-h-screen w-full max-w-[1120px] flex-col px-4 py-4 sm:px-6 lg:px-8"> <div className="mx-auto flex min-h-screen w-full max-w-[1120px] flex-col px-4 py-4 sm:px-6 lg:px-8">
<header className="flex items-center justify-between border-b pb-4 pt-2"> <header className="flex items-center justify-between border-b pb-4 pt-2">
<div className="flex min-w-0 items-center gap-3"> <div className="flex min-w-0 items-center gap-3">
<div className="grid size-10 place-items-center rounded-lg bg-primary text-sm font-semibold text-primary-foreground shadow-sm"> <img
PM src="/podman-logo.svg"
</div> alt=""
className="size-11 shrink-0 rounded-lg"
aria-hidden="true"
/>
<h1 className="text-[1.95rem] font-semibold leading-none tracking-tight">PodMan</h1> <h1 className="text-[1.95rem] font-semibold leading-none tracking-tight">PodMan</h1>
</div> </div>
<SignInButton mode="modal"> <SignInButton mode="modal">
@@ -485,8 +487,8 @@ function AuthGate() {
Create your account to enter PodMan Create your account to enter PodMan
</h2> </h2>
<p className="mt-3 text-base text-muted-foreground"> <p className="mt-3 text-base text-muted-foreground">
PodMan saves your context across pods so agents can learn from your work in every PodMan saves your context across pods so agents can learn from your work in every room
room you join. you join.
</p> </p>
</section> </section>