SillyTavern world artifacts, versioned in place

Tracked inside SillyTavern's live data directory rather than symlinked out of
it. data/ is a bind mount into the container, so a symlink to a host path
outside that mount resolves inside the container where the target does not
exist -- broken to SillyTavern while looking correct on the host.

The .gitignore is an allowlist, denying everything and re-including named paths,
because this is live application data rather than a curated export. secrets.json
is the reason: empty today because API keys go through LiteLLM with a
placeholder, and it arms itself the moment a key is typed into the UI. This repo
is public. A denylist protects only the paths someone remembered.

Two of the four artifact types are not diffable as stored. Character cards are
PNGs with the card JSON in a tEXt chunk, and personas live inside a 48 KB
settings.json that SillyTavern rewrites on any change. st-export.py extracts
both into _text/ so the reviewable artifact is text, one-way on purpose --
re-embedding JSON into a PNG is where a mistake corrupts authored content.

Stock content is excluded: Seraphina's expression pack is 3.6 MiB of PNG the app
regenerates on startup. The stock lorebook Eldoria.json stays -- 8 KB of
readable JSON is a useful worked example of the format.
This commit is contained in:
Mikkeli
2026-08-12 20:59:32 +09:00
commit 00f5e2fa72
9 changed files with 731 additions and 0 deletions
+51
View File
@@ -0,0 +1,51 @@
# ⚠ ALLOWLIST, NOT A DENYLIST — deny everything, then re-include what is ours.
#
# This directory is SillyTavern's live user data, not a curated export. It holds
# chat logs, an empty-but-arming `secrets.json`, caches, thumbnails and whatever
# a future version decides to write here. A denylist protects only the files
# someone remembered; an allowlist means a new file is invisible until a human
# names it.
#
# ⚠ THE ONE THAT MATTERS: `secrets.json` is currently EMPTY, because API keys go
# through LiteLLM with a placeholder. It arms itself the moment any key is typed
# into the UI, and this repo is public. It must never become trackable by
# accident, which under a denylist it eventually would.
# 1. deny everything
/*
# 2. re-include the artifacts worth versioning
!.gitignore
!README.md
!st-export.py
!/worlds/
!/characters/
!/QuickReplies/
!/OpenAI Settings/
!/User Avatars/
!/_text/
# 3. drop SillyTavern's STOCK content — it is regenerated on startup
# ⚠ Seraphina's expression pack alone is 3.6 MiB of PNG, and none of it is
# world-building. The stock lorebook `worlds/Eldoria.json` is KEPT on purpose:
# 8 KB of readable JSON is a useful worked example of lorebook structure.
/characters/default_*
/characters/Seraphina/
# 4. inside those, still keep the junk out
# ⚠ Backup files, including ones left by operational fixes — `Default.json.bak-squashfix`
# was created while debugging the heretic 400 and was staged on the first pass.
**/*.bak-*
**/*.bak
**/.DS_Store
**/Thumbs.db
# ⚠ NOT TRACKED, DELIBERATELY:
# secrets.json API keys — see above
# settings.json every UI preference, rewritten on any change; personas
# are extracted from it into _text/personas.json instead
# chats/, group chats/ the sessions themselves — personal, and churn hard
# backups/, thumbnails/, vectors/, stats.json, content.log, image-metadata.json
# themes/, movingUI/, reasoning/, extensions/, assets/, backgrounds/
# instruct/, context/, sysprompt/ 85 stock templates that ship with the app,
# and are INERT in Chat Completion mode anyway