BareGit
# Translator for SillyTavern Cards

This is a pure front-end web app to translate (e.g. from English to
Chinese) SillyTavern character cards.

## Tech stack

- Use preact.js. The app should be written in a way that doesn’t
  require a build process. The user should be able to simply host the
  files as static files in an HTTP server and use it.
- No style-related external libraries (e.g. bootstrap).

## The translation process

A SillyTavern character card is basically just a piece of JSON code.
The process of tranlate such a character card is the following:

1. Parse the JSON into JavaScript object
2. Iterate over all the “leaf” values in this object. If the value is
   a string, it should be translated.
3. For each “leaf” string value, the app should use an
   OpenAI-compatible LLM API to translate it, and replace the value
   with the translated value. These requests should be managed by a
   task queue to handle concurrency and prevent overloading the API
   or the browser.
4. After all “leaf” string values are translated, provide the JSON as
   a string to the user.

## Details

- The app should have an option dialog.

- The options should include the LLM prompt.

- The endpoint URL of the LLM API, the model name, and the API key are
  also configurable in the option dialog.

- There should be a list of “ignored keys”, which is a list of regular
  expressions. In the process of iterating over the “leaf” values, if
  the any of patterns in the ignored keys is found in the key, all the
  values under the key should not be translated. Note that the key
  does not have to be the key of the “leaf” value; it could be a key
  in an intermediate layer. The ignored keys should be configurable in
  the option dialog.

- The number of concurrent translations in the task queue should also
  be configurable in the option dialog.

- The options are saved in the browser’s local storage.

- After the translation is done. There should be an interface that
  layout the JSON as a tree on the UI. Each string value will be
  accompanied by three buttons: translate, revert, or retry. This
  interface will allow the user to finetune the translation result.

  * If the user clicks the “translate” button, and the value was not
    translated at that point (maybe because it was ignored by an
    ignored key), the app should translate the value. If the value is
    already translated, the “translate” button does nothing.

  * If the user clicks the “revert” button, and the value was
    translated, it should revert the value to the original value. If
    that value was not translated, this button does nothing.

  * If the user clicks the “retry” button, and the value was
    translated, the app should redo the translation on that value. If
    the value was not translated, this button does nothing.

- Because of this interface, it is recommended to create an
  intermediate type (maybe a JavaScript class), which stores both the
  original value, and the translated value. In the beginning of the
  translation process, the string values in the JSON should be
  replaced by an object of this type.