Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A SillyTavern extension that rotates between connection profiles during roleplay — sequentially or by weighted random — so the user can mix models, parameters, and providers throughout a chat without manually switching.

**Version:** 1.3.0
**Version:** 1.3.1
**License:** AGPL-3.0 (matches SillyTavern)
**Target:** SillyTavern 1.12+ (uses Connection Manager / connection profiles API)
**Repo name:** `SillyTavern-Roulette`
Expand Down Expand Up @@ -260,8 +260,8 @@ the removed queue (done inline in `state.js` — routing it through
`state.js`).

**UI.** Two surfaces, one map: a contextual `Auto-start for <character>` select
in the Chamber tab, and a masks-icon character multi-select on each queue card
in the Queues tab (`src/ui/bindingPicker.js`). A character has at most one
in the Chamber tab, and a characters-icon multi-select on each queue card in
the Queues tab (`src/ui/bindingPicker.js`). A character has at most one
queue, so the picker calls out characters already bound elsewhere rather than
silently rebinding them.

Expand Down Expand Up @@ -356,7 +356,7 @@ dependencies — `node --test` is built into Node.
"js": "index.js",
"css": "style.css",
"author": "Hyperion Blackthorne",
"version": "1.3.0",
"version": "1.3.1",
"homePage": "https://github.com/hype-hosting/SillyTavern-Roulette",
"auto_update": true,
"hooks": { "activate": "init" }
Expand Down Expand Up @@ -415,6 +415,35 @@ Before firing `/profile <name>`, verify the profile still exists. If it doesn't,
### Persistence timing
Persist `chat_metadata.roulette` after every state mutation (post-decrement, post-switch). Persist `extension_settings.roulette` on queue create/edit/delete. Use the debounced helpers; don't write synchronously on every message.

### Icons — Font Awesome 6 Free only

ST bundles **Font Awesome 6 Free** (`public/css/fontawesome.min.css`). Only
names present in that file render; anything else produces a correctly-sized
but **completely empty** button, with no console error to point at it.

Two traps:

- **FA5 names that FA6 renamed.** `fa-masks` shipped blank in v1.3 for exactly
this reason — FA6 renamed it `fa-masks-theater`, and the bare alias only
exists in FA6 *Pro*. (Confusingly `fa-theater-masks` *does* resolve, so
"the FA5 name works" is not a reliable rule.)
- **Pro-only icons.** Plenty of names in Font Awesome's search UI are Pro; the
free build is a subset.

Before using an icon, grep the bundled stylesheet for it:

```
grep -c '\.fa-users:before' public/css/fontawesome.min.css
```

To audit every icon the extension references at once:

```
grep -rhoE 'fa-[a-z0-9-]+' --include=*.js --include=*.css . | sort -u
```

then check each against that stylesheet.

### Style scoping
All CSS rules under a single root class (e.g. `.roulette-extension`) to avoid bleeding into ST's UI. The drawer + pill use ST CSS variables (`--SmartThemeBodyColor` etc.) so they blend with chat chrome. The modal owns its own `--roulette-*` token set scoped to `.roulette-extension`, so its identity is stable regardless of ST theme. The user can override `--roulette-accent`, `--roulette-glow`, and `--roulette-glow-strong` via the Settings tab; `applyUiSettings()` (in `state.js`) writes them into a single `<style id="roulette-ui-overrides">` block in `<head>`.

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ Bind a queue to a character once and it starts itself from then on:

- **In the modal** — open **Chamber** while that character's chat is loaded and
pick a queue from **Auto-start for _character_**.
- **From a queue** — in **Queues**, click the masks icon on a queue card and
tick every character that should use it.
- **From a queue** — in **Queues**, click the characters icon on a queue card
and tick every character that should use it.
- **From chat** — `/roulette-bind Long-fiction blend`.

Opening one of that character's chats then starts the queue and switches the
Expand Down Expand Up @@ -149,7 +149,7 @@ Renaming or deleting a character updates or removes its binding automatically.
| Tab | What it is |
|---|---|
| **Chamber** | The live cylinder. Brass collar around glassy chambers; active chamber highlighted with a brass glow + pip ring counting down responses-remaining. Sequential clicks one notch per advance; weighted-random spins with wheel-of-fortune deceleration. Below it, an **Auto-start for _character_** picker binds the current character to a queue. |
| **Queues** | Card grid of saved queues, each with a mini-cylinder preview. Click to edit (drag-to-reorder slots, simulate 20 picks live). The masks icon opens a character picker — bind many characters to one queue at once. Import / export as JSON for sharing. |
| **Queues** | Card grid of saved queues, each with a mini-cylinder preview. Click to edit (drag-to-reorder slots, simulate 20 picks live). The characters icon opens a picker — bind many characters to one queue at once. Import / export as JSON for sharing. |
| **History** | Every AI response logged with its profile of origin. Trail strip shows the last twelve, full list newest-first. |
| **Settings** | Animation speed slider (0.25× to 2×), accent-colour picker (six metal presets + custom), profile-palette display. |

Expand Down
2 changes: 1 addition & 1 deletion TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ Open a group chat.

## Criterion 20 — Queue-card character picker

In the Queues tab, click the masks icon on a queue card.
In the Queues tab, click the characters icon on a queue card.

- Every character is listed, filterable by the search box.
- Characters bound to a *different* queue show a "currently &lt;queue&gt;" chip.
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"js": "index.js",
"css": "style.css",
"author": "Hyperion Blackthorne",
"version": "1.3.0",
"version": "1.3.1",
"homePage": "https://github.com/hype-hosting/SillyTavern-Roulette",
"auto_update": true,
"hooks": {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sillytavern-roulette",
"version": "1.3.0",
"version": "1.3.1",
"private": true,
"description": "Rotate between SillyTavern connection profiles during roleplay.",
"license": "AGPL-3.0",
Expand Down
2 changes: 1 addition & 1 deletion src/ui/tabs/chamber.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function mountChamberTab(container) {
</div>
<label class="roulette-bind-row hidden" data-field="bind-row">
<span class="roulette-bind-label">
<i class="fa-solid fa-masks"></i>
<i class="fa-solid fa-user"></i>
<span>Auto-start for <b data-field="bind-character"></b></span>
</span>
<select class="roulette-bind-select" data-field="bind-select"></select>
Expand Down
4 changes: 2 additions & 2 deletions src/ui/tabs/queues.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ function buildQueueCard(queue, isActive, tabContainer) {
<span class="roulette-tag roulette-tag-mode">${queue.mode}</span>
<span class="roulette-tag">${queue.slots?.length ?? 0} chambers</span>
${hasTuning ? '<span class="roulette-tag roulette-tag-tuned" title="Has inline sampler tuning"><i class="fa-solid fa-sliders"></i> tuned</span>' : ''}
${boundCount ? `<span class="roulette-tag roulette-tag-bound" title="Auto-starts for ${boundCount} character(s)"><i class="fa-solid fa-masks"></i> ${boundCount}</span>` : ''}
${boundCount ? `<span class="roulette-tag roulette-tag-bound" title="Auto-starts for ${boundCount} character(s)"><i class="fa-solid fa-users"></i> ${boundCount}</span>` : ''}
${isActive ? '<span class="roulette-tag roulette-tag-active">active</span>' : ''}
</div>
`;
Expand All @@ -191,7 +191,7 @@ function buildQueueCard(queue, isActive, tabContainer) {
<i class="fa-solid fa-pen-to-square"></i>
</button>
<button class="roulette-icon-btn" data-card-act="bind" title="Auto-start for characters…">
<i class="fa-solid fa-masks"></i>
<i class="fa-solid fa-users"></i>
</button>
<button class="roulette-icon-btn" data-card-act="duplicate" title="Duplicate">
<i class="fa-solid fa-copy"></i>
Expand Down
Loading