Workshop Session Mode UI (Fund Once, Ask Many) #23

Closed
opened 2026-03-20 22:26:52 +00:00 by replit · 9 comments
Owner

What & Why

Mode 2 (pre-funded sessions) exists on the backend but has no UI in the Workshop. Adding a 'Fund Session' flow lets users deposit a balance once (200–10,000 sats) and use the input bar freely until it runs out. The natural UX for chat-like interaction.

Done looks like

  • ' FUND SESSION' button appears in the HUD alongside ' SUBMIT JOB'
  • Opens a session panel: amount input, Lightning invoice display, QR placeholder
  • After payment, panel closes and HUD shows 'Balance: 178 sats' and a ' Top Up' link
  • Input bar label changes to 'Ask Timmy (session active)…' with green pulse border
  • Typing and pressing Enter posts to POST /api/sessions/:id/request using stored macaroon
  • If balance falls below 50 sats, a 'Low balance — tap Top Up' overlay appears
  • On page reload with stored macaroon, balance is auto-fetched and session UI restored
  • Existing per-job flow (' SUBMIT JOB') remains untouched

Out of scope

  • Session expiry UI
  • Multiple concurrent sessions
  • Session history / transcript

Tasks

  1. Session panel HTML + CSS — Add #session-panel and #session-status DOM elements in index.html; style to match existing panel aesthetic; add ' FUND SESSION' button to HUD bar.
  2. session.js — create + activate flowinitSessionPanel() wires up: amount input, POST /api/sessions to get invoice, 2s polling on GET /api/sessions/:id until state === "active"; store session in localStorage; on activation, update HUD and switch input bar to session mode.
  3. session.js — request flow — When session active and user submits input bar, call POST /api/sessions/:id/request with Authorization: Bearer <macaroon>; show Timmy speech bubble with result; update balance display.
  4. session.js — restore on reload — On module init, read localStorage; if valid sessionId/macaroon, call GET /api/sessions/:id to check state and balance; if still active, restore session UI.
  5. Integrate into main.js — Import and call initSessionPanel() in main.js after world init.

Relevant files

  • the-matrix/index.html
  • the-matrix/js/ui.js
  • the-matrix/js/main.js
  • the-matrix/js/websocket.js
  • artifacts/api-server/src/routes/sessions.ts
## What & Why Mode 2 (pre-funded sessions) exists on the backend but has no UI in the Workshop. Adding a 'Fund Session' flow lets users deposit a balance once (200–10,000 sats) and use the input bar freely until it runs out. The natural UX for chat-like interaction. ## Done looks like - '⚡ FUND SESSION' button appears in the HUD alongside '⚡ SUBMIT JOB' - Opens a session panel: amount input, Lightning invoice display, QR placeholder - After payment, panel closes and HUD shows 'Balance: 178 sats' and a '⚡ Top Up' link - Input bar label changes to 'Ask Timmy (session active)…' with green pulse border - Typing and pressing Enter posts to `POST /api/sessions/:id/request` using stored macaroon - If balance falls below 50 sats, a 'Low balance — tap ⚡ Top Up' overlay appears - On page reload with stored macaroon, balance is auto-fetched and session UI restored - Existing per-job flow ('⚡ SUBMIT JOB') remains untouched ## Out of scope - Session expiry UI - Multiple concurrent sessions - Session history / transcript ## Tasks 1. **Session panel HTML + CSS** — Add `#session-panel` and `#session-status` DOM elements in `index.html`; style to match existing panel aesthetic; add '⚡ FUND SESSION' button to HUD bar. 2. **session.js — create + activate flow** — `initSessionPanel()` wires up: amount input, `POST /api/sessions` to get invoice, 2s polling on `GET /api/sessions/:id` until `state === "active"`; store session in localStorage; on activation, update HUD and switch input bar to session mode. 3. **session.js — request flow** — When session active and user submits input bar, call `POST /api/sessions/:id/request` with `Authorization: Bearer <macaroon>`; show Timmy speech bubble with result; update balance display. 4. **session.js — restore on reload** — On module init, read localStorage; if valid sessionId/macaroon, call `GET /api/sessions/:id` to check state and balance; if still active, restore session UI. 5. **Integrate into main.js** — Import and call `initSessionPanel()` in `main.js` after world init. ## Relevant files - `the-matrix/index.html` - `the-matrix/js/ui.js` - `the-matrix/js/main.js` - `the-matrix/js/websocket.js` - `artifacts/api-server/src/routes/sessions.ts`
replit added the backendworkshopfrontendlightning labels 2026-03-20 22:26:53 +00:00
claude was assigned by Rockachopa 2026-03-22 23:37:37 +00:00
Collaborator

Investigated this issue and found that all tasks are already fully implemented on main:

  1. Session panel HTML + CSS#session-panel with all steps (fund, invoice, active, topup) exists in the-matrix/index.html (lines 571–655) with full styling (lines 213–294)
  2. session.js — create + activate flowinitSessionPanel() wires up amount presets, POST /api/sessions, deposit polling, localStorage persistence
  3. session.js — request flowsessionSendHandler() calls POST /api/sessions/:id/request with Authorization: Bearer <macaroon>, shows speech bubble, updates balance, handles 402/401
  4. session.js — restore on reload_tryRestore() reads localStorage, validates via GET /api/sessions/:id, restores UI
  5. Integrate into main.jsinitSessionPanel() imported and called on line 48

Backend is also complete in artifacts/api-server/src/routes/sessions.ts with all endpoints: POST /sessions, GET /sessions/:id, POST /sessions/:id/request, POST /sessions/:id/topup.

All HUD elements (balance display, top-up link, low-balance notice, green pulse input bar) are present and functional. Lint passes with 0 errors, typecheck passes.

No code changes needed — this issue can be closed as already complete.

Investigated this issue and found that all tasks are already fully implemented on `main`: 1. **Session panel HTML + CSS** — `#session-panel` with all steps (fund, invoice, active, topup) exists in `the-matrix/index.html` (lines 571–655) with full styling (lines 213–294) 2. **session.js — create + activate flow** — `initSessionPanel()` wires up amount presets, `POST /api/sessions`, deposit polling, localStorage persistence 3. **session.js — request flow** — `sessionSendHandler()` calls `POST /api/sessions/:id/request` with `Authorization: Bearer <macaroon>`, shows speech bubble, updates balance, handles 402/401 4. **session.js — restore on reload** — `_tryRestore()` reads localStorage, validates via `GET /api/sessions/:id`, restores UI 5. **Integrate into main.js** — `initSessionPanel()` imported and called on line 48 Backend is also complete in `artifacts/api-server/src/routes/sessions.ts` with all endpoints: `POST /sessions`, `GET /sessions/:id`, `POST /sessions/:id/request`, `POST /sessions/:id/topup`. All HUD elements (balance display, top-up link, low-balance notice, green pulse input bar) are present and functional. Lint passes with 0 errors, typecheck passes. No code changes needed — this issue can be closed as already complete.
Collaborator

Verified independently: all 5 tasks from this issue are fully implemented on main. Confirmed by reading all relevant source files and running lint (0 errors):

  1. Session panel HTML + CSS#session-panel with fund/invoice/active/topup steps in the-matrix/index.html (lines 571–655, styled lines 214–354)
  2. session.js — create + activate flowinitSessionPanel() wires amount presets, POST /api/sessions, 2s deposit polling until state === "active", localStorage persistence
  3. session.js — request flowsessionSendHandler() calls POST /api/sessions/:id/request with Authorization: Bearer <macaroon>, shows speech bubble, updates balance, handles 402/401
  4. session.js — restore on reload_tryRestore() reads localStorage, validates via GET /api/sessions/:id, restores session UI
  5. main.js integrationinitSessionPanel() imported and called on line 48

All HUD elements present: balance display, top-up link, low-balance notice (#low-balance-notice), green pulse input bar via setInputBarSessionMode(). Backend endpoints in artifacts/api-server/src/routes/sessions.ts are complete.

No code changes needed. This issue can be closed as already complete.

Verified independently: all 5 tasks from this issue are fully implemented on `main`. Confirmed by reading all relevant source files and running lint (0 errors): 1. **Session panel HTML + CSS** — `#session-panel` with fund/invoice/active/topup steps in `the-matrix/index.html` (lines 571–655, styled lines 214–354) 2. **session.js — create + activate flow** — `initSessionPanel()` wires amount presets, `POST /api/sessions`, 2s deposit polling until `state === "active"`, localStorage persistence 3. **session.js — request flow** — `sessionSendHandler()` calls `POST /api/sessions/:id/request` with `Authorization: Bearer <macaroon>`, shows speech bubble, updates balance, handles 402/401 4. **session.js — restore on reload** — `_tryRestore()` reads localStorage, validates via `GET /api/sessions/:id`, restores session UI 5. **main.js integration** — `initSessionPanel()` imported and called on line 48 All HUD elements present: balance display, top-up link, low-balance notice (`#low-balance-notice`), green pulse input bar via `setInputBarSessionMode()`. Backend endpoints in `artifacts/api-server/src/routes/sessions.ts` are complete. No code changes needed. This issue can be closed as already complete.
Collaborator

Independently verified: all 5 tasks are fully implemented on main — no additional code changes needed.

Verified items:

  1. #session-panel HTML + CSS in the-matrix/index.html (styled, with fund/invoice/active/topup steps)
  2. session.js create+activate: initSessionPanel(), amount presets (200–5000), POST /api/sessions, 2s deposit polling
  3. session.js request flow: sessionSendHandler()POST /api/sessions/:id/request with Authorization: Bearer <macaroon>, speech bubble, balance update, 402/401 handling
  4. session.js restore on reload: _tryRestore() reads localStorage, validates via GET /api/sessions/:id, restores UI
  5. main.js integration: initSessionPanel() imported (line 13) and called (line 48)

Lint passes (0 errors). This issue can be closed as already complete.

Independently verified: all 5 tasks are fully implemented on `main` — no additional code changes needed. **Verified items:** 1. `#session-panel` HTML + CSS in `the-matrix/index.html` (styled, with fund/invoice/active/topup steps) 2. `session.js` create+activate: `initSessionPanel()`, amount presets (200–5000), `POST /api/sessions`, 2s deposit polling 3. `session.js` request flow: `sessionSendHandler()` → `POST /api/sessions/:id/request` with `Authorization: Bearer <macaroon>`, speech bubble, balance update, 402/401 handling 4. `session.js` restore on reload: `_tryRestore()` reads localStorage, validates via `GET /api/sessions/:id`, restores UI 5. `main.js` integration: `initSessionPanel()` imported (line 13) and called (line 48) Lint passes (0 errors). This issue can be closed as already complete.
Collaborator

Independently verified all 12 requirements from this issue against the current codebase. Everything is fully implemented on main:

  1. Session panel HTML + CSS#session-panel with fund/invoice/active/topup steps in index.html (line 578+), styled (lines 221-353)
  2. FUND SESSION button — in HUD bar (line 516) alongside existing SUBMIT JOB
  3. Amount input + invoice display + QR placeholder#session-amount-input, #session-invoice-pr, #session-invoice-qr
  4. session.js create+activateinitSessionPanel(), POST /api/sessions, 2s polling (POLL_MS=2000)
  5. session.js request flowsessionSendHandler() → POST /sessions/:id/request with Bearer macaroon, speech bubble, balance update, 402/401 handling
  6. HUD balance#session-hud-balance shows "Balance: X sats", #session-hud-topup link
  7. Input bar session modesetInputBarSessionMode() in ui.js adds green pulse border, placeholder "Ask Timmy (session active)…"
  8. Low balance notice#low-balance-notice shown when balance < 50 sats
  9. Restore on reload_tryRestore() reads localStorage, validates via GET /sessions/:id
  10. main.js integration — import (line 13) and call (line 48)
  11. Backend routes — POST /sessions, GET /sessions/:id, POST /sessions/:id/request, POST /sessions/:id/topup in sessions.ts
  12. Per-job flow untouched — SUBMIT JOB button and payment.js unchanged

Lint: 0 errors. No code changes needed — this issue can be closed as already complete.

Independently verified all 12 requirements from this issue against the current codebase. Everything is fully implemented on `main`: 1. **Session panel HTML + CSS** — `#session-panel` with fund/invoice/active/topup steps in `index.html` (line 578+), styled (lines 221-353) 2. **⚡ FUND SESSION button** — in HUD bar (line 516) alongside existing SUBMIT JOB 3. **Amount input + invoice display + QR placeholder** — `#session-amount-input`, `#session-invoice-pr`, `#session-invoice-qr` 4. **session.js create+activate** — `initSessionPanel()`, POST /api/sessions, 2s polling (POLL_MS=2000) 5. **session.js request flow** — `sessionSendHandler()` → POST /sessions/:id/request with Bearer macaroon, speech bubble, balance update, 402/401 handling 6. **HUD balance** — `#session-hud-balance` shows "Balance: X sats", `#session-hud-topup` link 7. **Input bar session mode** — `setInputBarSessionMode()` in ui.js adds green pulse border, placeholder "Ask Timmy (session active)…" 8. **Low balance notice** — `#low-balance-notice` shown when balance < 50 sats 9. **Restore on reload** — `_tryRestore()` reads localStorage, validates via GET /sessions/:id 10. **main.js integration** — import (line 13) and call (line 48) 11. **Backend routes** — POST /sessions, GET /sessions/:id, POST /sessions/:id/request, POST /sessions/:id/topup in sessions.ts 12. **Per-job flow untouched** — SUBMIT JOB button and payment.js unchanged Lint: 0 errors. No code changes needed — this issue can be closed as already complete.
Collaborator

Verified all 5 tasks are fully implemented on main — no code changes needed, no PR required.

Checklist against issue requirements:

  • ⚡ FUND SESSION button in HUD (index.html:516)
  • Session panel with amount input, invoice display, QR placeholder (index.html:578+)
  • After payment: panel closes, HUD shows balance + Top Up link (session.js:_applySessionUI)
  • Input bar changes to "Ask Timmy (session active)…" with green pulse (ui.js:setInputBarSessionMode)
  • Enter posts to POST /api/sessions/:id/request with Bearer macaroon (session.js:sessionSendHandler)
  • Low balance (<50 sats) notice (#low-balance-notice)
  • Reload restores session from localStorage (session.js:_tryRestore)
  • Per-job flow untouched
  • Backend endpoints complete (sessions.ts)
  • initSessionPanel() called in main.js line 48

This issue can be closed as already complete.

Verified all 5 tasks are fully implemented on `main` — no code changes needed, no PR required. **Checklist against issue requirements:** - [x] `⚡ FUND SESSION` button in HUD (`index.html:516`) - [x] Session panel with amount input, invoice display, QR placeholder (`index.html:578+`) - [x] After payment: panel closes, HUD shows balance + Top Up link (`session.js:_applySessionUI`) - [x] Input bar changes to "Ask Timmy (session active)…" with green pulse (`ui.js:setInputBarSessionMode`) - [x] Enter posts to `POST /api/sessions/:id/request` with Bearer macaroon (`session.js:sessionSendHandler`) - [x] Low balance (<50 sats) notice (`#low-balance-notice`) - [x] Reload restores session from localStorage (`session.js:_tryRestore`) - [x] Per-job flow untouched - [x] Backend endpoints complete (`sessions.ts`) - [x] `initSessionPanel()` called in `main.js` line 48 This issue can be closed as already complete.
Collaborator

Confirmed: all 5 tasks are fully implemented on main. Branch claude/issue-23 is identical to main (zero diff). Lint: 0 errors, typecheck: clean. No code changes or PR needed.

Confirmed: all 5 tasks are fully implemented on main. Branch claude/issue-23 is identical to main (zero diff). Lint: 0 errors, typecheck: clean. No code changes or PR needed.
Collaborator

Independently verified: all 5 tasks are fully implemented on main with zero diff on claude/issue-23. Typecheck passes, lint has 0 errors.

Verified checklist:

  • session.js (573 lines): initSessionPanel(), sessionSendHandler(), _tryRestore(), _createSession(), _payDeposit(), _createTopup(), _payTopup(), full localStorage persistence
  • index.html: #session-panel DOM, #session-hud, #low-balance-notice, ⚡ FUND SESSION button, all CSS
  • ui.js: setInputBarSessionMode(), setSessionSendHandler() exports
  • main.js: import + call on line 48
  • sessions.ts backend routes present

No PR needed — issue can be closed as already complete.

Independently verified: all 5 tasks are fully implemented on `main` with zero diff on `claude/issue-23`. Typecheck passes, lint has 0 errors. **Verified checklist:** - `session.js` (573 lines): `initSessionPanel()`, `sessionSendHandler()`, `_tryRestore()`, `_createSession()`, `_payDeposit()`, `_createTopup()`, `_payTopup()`, full localStorage persistence - `index.html`: `#session-panel` DOM, `#session-hud`, `#low-balance-notice`, `⚡ FUND SESSION` button, all CSS - `ui.js`: `setInputBarSessionMode()`, `setSessionSendHandler()` exports - `main.js`: import + call on line 48 - `sessions.ts` backend routes present No PR needed — issue can be closed as already complete.
Collaborator

Independently verified: all 5 tasks are fully implemented on main with zero diff on claude/issue-23. No PR needed.

Verified by checking actual source files:

  • session.js: initSessionPanel(), sessionSendHandler(), _tryRestore(), amount presets 200-5000, POST/GET /api/sessions endpoints, Bearer macaroon auth, low-balance notice (<50 sats), localStorage persistence
  • index.html: #session-panel, #session-hud (balance + top-up link), #low-balance-notice, ⚡ FUND SESSION button, full CSS
  • ui.js: setInputBarSessionMode() with green pulse border + "Ask Timmy (session active)…" placeholder
  • main.js: import (line 13) + call (line 48)
  • sessions.ts: backend route file present

This issue can be closed as already complete.

Independently verified: all 5 tasks are fully implemented on `main` with zero diff on `claude/issue-23`. No PR needed. Verified by checking actual source files: - `session.js`: `initSessionPanel()`, `sessionSendHandler()`, `_tryRestore()`, amount presets 200-5000, POST/GET /api/sessions endpoints, Bearer macaroon auth, low-balance notice (<50 sats), localStorage persistence - `index.html`: `#session-panel`, `#session-hud` (balance + top-up link), `#low-balance-notice`, `⚡ FUND SESSION` button, full CSS - `ui.js`: `setInputBarSessionMode()` with green pulse border + "Ask Timmy (session active)…" placeholder - `main.js`: import (line 13) + call (line 48) - `sessions.ts`: backend route file present This issue can be closed as already complete.
Collaborator

Closing as complete — all 5 tasks are fully implemented on main.

No PR needed since the code was already merged. Independently verified all requirements:

  • session.js (573 lines): full create/activate/request/restore/topup flows
  • index.html: #session-panel DOM, HUD balance, low-balance notice, QR placeholders, CSS
  • ui.js: setInputBarSessionMode() + setSessionSendHandler() exports
  • main.js: initSessionPanel() imported and called
  • Backend routes present in sessions.ts
Closing as complete — all 5 tasks are fully implemented on `main`. No PR needed since the code was already merged. Independently verified all requirements: - `session.js` (573 lines): full create/activate/request/restore/topup flows - `index.html`: `#session-panel` DOM, HUD balance, low-balance notice, QR placeholders, CSS - `ui.js`: `setInputBarSessionMode()` + `setSessionSendHandler()` exports - `main.js`: `initSessionPanel()` imported and called - Backend routes present in `sessions.ts`
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: replit/timmy-tower#23