Language packs let the community add new UI languages to Jacky without touching the source code. A pack is a regular .jacky file (a ZIP archive) that Jacky can install via drag-and-drop.
Open the Manifest Builder
Recommended: Before starting your own translation, we highly encourage you to download a featured language package from the Workshop. This ensures you have access to a complete set of files and keys to use as a baseline!
Package Structure
A translation bundle must contain a manifest.json file at the root, and a subfolder named after the ISO 639-1 language code (e.g. es/ for Spanish, la/ for Latin). Inside that subfolder, you can define multiple translation files to fully localize Jacky:
manifest.json
The manifest details the type of package and language metadata:
{
"type": "lang",
"name": "Spanish",
"lang": {
"code": "es"
}
}type: Must be exactly"lang".name: The display name of the language pack.lang.code: ISO 639-1 code matching the inner folder.
Mappings Reference
Here is a detailed breakdown of all files that make up a translation bundle:
1. ui.json
Defines button, menu, settings panels, and header interface labels.
{
"ui": {
"menu_settings": "⚙️ Configuración",
"btn_yes": "✔ Sí",
"btn_cancel": "❌ Cancelar"
}
}2. dialogues.json
Defines spoken dialogue lines and general reactions. Organized under a "dialogues" key:
{
"meta": {
"name": "Español"
},
"dialogues": {
"greet": [
"¡Hola! ¿Cómo estás?",
"¡Qué tal, amigo!"
],
"idle": [
"Qué día tan tranquilo...",
"*mirando el cursor*"
]
}
}3. keywords.json
Maps intent triggers, actions, and custom words used by Jacky's parsing engine (e.g., system commands, confirmations, timer setup, easter eggs, application names, and TTS rules).
{
"interact_keywords": {
"navigate": ["ve a", "busca", "dirígete a"],
"click": ["presiona", "haz clic", "toca"],
"close": ["cierra", "quita", "borra"],
"minimize": ["minimiza", "esconde", "oculta"],
"type": ["escribe", "teclea", "pon"]
},
"confirm_words": {
"affirm": ["sí", "dale", "va", "ok"],
"deny": ["no", "nah", "cancela", "olvídalo"]
},
"easter_keywords": {
"barrel_roll": ["barrel roll", "da una vuelta"],
"dance": ["baila", "baila para mí"]
}
}4. collectibles.json
Translates names of collectibles and desktop sprites that spawn for the user to collect.
{
"sprite_names": {
"rubber_duck": "Pato de Hule",
"yo_yo": "Yo-Yo",
"pixel_heart": "Corazón Pixelado"
}
}5. prompts.json
Defines prompts sent to the LLM backend for reactions, battery/status alerts, vision tasks, and intent classifications.
Language Directives: Several prompts (like system instructions, chat reactions, and vision tasks) contain explicit directives telling the LLM which language to respond in (e.g., "SIEMPRE responde en español"). When translating prompts.json, make sure to update these instructions to your target language so the AI companion knows to reply in that language.
{
"llm_prompts": {
"sys_battery_low": "La batería de la laptop está baja ({pct}%). Reacciona preocupado.",
"sys_user_returned": "El usuario acaba de regresar después de estar ausente por un rato. Dale la bienvenida.",
"idle_selftalk": "Nadie te ha hablado en mucho rato. Estás solo y aburrido. Habla contigo mismo sobre algo random y absurdo."
}
}6. personalities.json
Configures custom companion personalities, their descriptions, system instructions, and maps them to external dialogue files.
{
"personalities": {
"nerdy": {
"name": "Nerdy",
"description": "Cerebrito. Sobreexplica todo y ama los datos curiosos de tecnología.",
"voice_id": "f2yUVfK5jdm78zlpcZ8C",
"system_prompt": "Eres un nerd y entusiasta de la tecnología. Hablas de manera técnica pero amigable...",
"dialogues": "dialogues_nerdy.json"
}
}
}7. Custom Dialogues (personalities/dialogues_<personality_id>.json)
When a personality maps its dialogues to a file (e.g., dialogues_nerdy.json), it is stored inside the personalities/ subfolder. This file contains character-specific dialogue lines that override the standard ones in dialogues.json when this personality is active.
Keep placeholders like {name}, {pct}, {time}, {label}, {duration}, {app}, and {peer_name} intact in your translations. They are used for runtime injection!