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:
+51
@@ -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
|
||||
Reference in New Issue
Block a user