Merge branch 'main' into feat/llm-tool-improvement

This commit is contained in:
Jon Fuller 2025-06-26 14:15:08 -07:00 committed by GitHub
commit 755b1ed42f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
142 changed files with 3250 additions and 771 deletions

1
.env Normal file
View File

@ -0,0 +1 @@
NODE_OPTIONS=--max_old_space_size=4096

View File

@ -85,7 +85,7 @@ runs:
APPLE_ID: ${{ env.APPLE_ID }}
APPLE_ID_PASSWORD: ${{ env.APPLE_ID_PASSWORD }}
WINDOWS_SIGN_EXECUTABLE: ${{ env.WINDOWS_SIGN_EXECUTABLE }}
TRILIUM_ARTIFACT_NAME_HINT: TriliumNextNotes-${{ github.ref_name }}-${{ inputs.os }}-${{ inputs.arch }}
TRILIUM_ARTIFACT_NAME_HINT: TriliumNotes-${{ github.ref_name }}-${{ inputs.os }}-${{ inputs.arch }}
run: pnpm nx --project=desktop electron-forge:make -- --arch=${{ inputs.arch }} --platform=${{ inputs.forge_platform }}
# Add DMG signing step

View File

@ -30,4 +30,4 @@ runs:
mkdir -p upload
file=$(find ./apps/server/out -name '*.tar.xz' -print -quit)
name=${{ github.ref_name }}
cp "$file" "upload/TriliumNextNotes-Server-${name//\//-}-${{ inputs.os }}-${{ inputs.arch }}.tar.xz"
cp "$file" "upload/TriliumNotes-Server-${name//\//-}-${{ inputs.os }}-${{ inputs.arch }}.tar.xz"

View File

@ -13,9 +13,9 @@ name: "CodeQL Advanced"
on:
push:
branches: [ "develop" ]
branches: [ "main" ]
pull_request:
branches: [ "develop" ]
branches: [ "main" ]
schedule:
- cron: '20 7 * * 0'

View File

@ -1,9 +1,9 @@
name: Dev
on:
push:
branches: [ develop ]
branches: [ main ]
pull_request:
branches: [ develop ]
branches: [ main ]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@ -12,8 +12,8 @@ concurrency:
env:
GHCR_REGISTRY: ghcr.io
DOCKERHUB_REGISTRY: docker.io
IMAGE_NAME: ${{ github.repository_owner }}/notes
TEST_TAG: ${{ github.repository_owner }}/notes:test
IMAGE_NAME: ${{ github.repository}}
TEST_TAG: ${{ github.repository}}:test
permissions:
pull-requests: write # for PR comments
@ -77,6 +77,7 @@ jobs:
- name: Trigger client build
run: pnpm nx run client:build
- name: Send client bundle stats to RelativeCI
if: false
uses: relative-ci/agent-action@v3
with:
webpackStatsFile: ./apps/client/dist/webpack-stats.json

View File

@ -1,7 +1,7 @@
on:
push:
branches:
- "develop"
- "main"
- "feature/update**"
- "feature/server_esm**"
paths-ignore:
@ -14,8 +14,8 @@ on:
env:
GHCR_REGISTRY: ghcr.io
DOCKERHUB_REGISTRY: docker.io
IMAGE_NAME: ${{ github.repository_owner }}/notes
TEST_TAG: ${{ github.repository_owner }}/notes:test
IMAGE_NAME: ${{ github.repository}}
TEST_TAG: ${{ github.repository}}:test
permissions:
contents: read
@ -83,6 +83,14 @@ jobs:
- name: Run Playwright tests
run: TRILIUM_DOCKER=1 TRILIUM_PORT=8082 pnpm exec nx run server-e2e:e2e
- name: Upload Playwright trace
if: failure()
uses: actions/upload-artifact@v4
with:
name: Playwright trace (${{ matrix.dockerfile }})
path: test-output/playwright/output
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:

View File

@ -92,7 +92,7 @@ jobs:
uses: actions/upload-artifact@v4
if: ${{ github.event_name == 'pull_request' }}
with:
name: TriliumNextNotes ${{ matrix.os.name }} ${{ matrix.arch }}
name: TriliumNotes ${{ matrix.os.name }} ${{ matrix.arch }}
path: apps/desktop/upload
nightly-server:

View File

@ -3,7 +3,7 @@ name: playwright
on:
push:
branches:
- master
- main
pull_request:
permissions:
@ -40,4 +40,4 @@ jobs:
# - run: npx nx-cloud record -- echo Hello World
# Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected
# When you enable task distribution, run the e2e-ci task instead of e2e
- run: pnpm exec nx affected -t e2e
- run: pnpm exec nx affected -t e2e --exclude desktop-e2e

View File

@ -23,7 +23,7 @@ jobs:
shell: bash
forge_platform: darwin
- name: linux
image: ubuntu-latest
image: ubuntu-22.04
shell: bash
forge_platform: linux
- name: windows

2
.nvmrc
View File

@ -1 +1 @@
22.16.0
22.17.0

View File

@ -1,4 +1,4 @@
# TriliumNext Notes
# Trilium Notes
![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran?style=flat-square)
![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/notes?style=flat-square)
@ -7,7 +7,7 @@
[English](./README.md) | [Chinese](./docs/README-ZH_CN.md) | [Russian](./docs/README.ru.md) | [Japanese](./docs/README.ja.md) | [Italian](./docs/README.it.md) | [Spanish](./docs/README.es.md)
TriliumNext Notes is a free and open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases.
Trilium Notes is a free and open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases.
See [screenshots](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) for quick overview:
@ -153,7 +153,7 @@ Please view the [documentation guide](./docs/Developer%20Guide/Developer%20Guide
## 👏 Shoutouts
* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - best WYSIWYG editor on the market, very interactive and listening team
* [FancyTree](https://github.com/mar10/fancytree) - very feature rich tree library without real competition. TriliumNext Notes would not be the same without it.
* [FancyTree](https://github.com/mar10/fancytree) - very feature rich tree library without real competition. Trilium Notes would not be the same without it.
* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with support for huge amount of languages
* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library without competition. Used in [relation maps](https://triliumnext.github.io/Docs/Wiki/relation-map.html) and [link maps](https://triliumnext.github.io/Docs/Wiki/note-map.html#link-map)

View File

@ -24,7 +24,7 @@ if ! git diff-index --quiet HEAD --; then
exit 1
fi
BASE_BRANCH=master
BASE_BRANCH=main
if [[ "$VERSION" == *"beta"* ]]; then
BASE_BRANCH=beta

View File

@ -47,11 +47,3 @@ echo "Tagging commit with $TAG"
git tag $TAG
git push origin $TAG
echo "Updating master"
git fetch
git checkout master
git reset --hard origin/master
git merge origin/develop
git push

View File

@ -26,8 +26,9 @@ stats() {
s=$(number_of_keys "${paths[0]}/en/server.json")
c=$(number_of_keys "${paths[1]}/en/translation.json")
echo "| locale | server strings | client strings |"
echo "|--------|---------------|---------------|"
echo "|--------|----------------|----------------|"
echo "| en | ${s} | ${c} |"
echo "|--------|----------------|----------------|"
for locale in "${locales[@]}"; do
s=$(number_of_keys "${paths[0]}/${locale}/server.json")
c=$(number_of_keys "${paths[1]}/${locale}/translation.json")
@ -78,7 +79,10 @@ file_path="$(
cd -- "$(dirname "${0}")" >/dev/null 2>&1 || exit
pwd -P
)"
paths=("${file_path}/../translations/" "${file_path}/../src/public/translations/")
paths=(
"${file_path}/../../apps/server/src/assets/translations/"
"${file_path}/../../apps/client/src/translations/"
)
locales=(cn de es fr pt_br ro tw)
if [ $# -eq 1 ]; then

View File

@ -36,9 +36,9 @@
},
"devDependencies": {
"@playwright/test": "1.53.1",
"@stylistic/eslint-plugin": "4.4.1",
"@stylistic/eslint-plugin": "5.0.0",
"@types/express": "5.0.3",
"@types/node": "22.15.32",
"@types/node": "22.15.33",
"@types/yargs": "17.0.33",
"@vitest/coverage-v8": "3.2.4",
"eslint": "9.29.0",

View File

@ -5,7 +5,7 @@
"private": true,
"license": "AGPL-3.0-only",
"author": {
"name": "TriliumNext Notes Team",
"name": "Trilium Notes Team",
"email": "contact@eliandoran.me",
"url": "https://github.com/TriliumNext/Notes"
},
@ -18,7 +18,7 @@
"@fullcalendar/list": "6.1.17",
"@fullcalendar/multimonth": "6.1.17",
"@fullcalendar/timegrid": "6.1.17",
"@mermaid-js/layout-elk": "0.1.7",
"@mermaid-js/layout-elk": "0.1.8",
"@mind-elixir/node-menu": "1.0.5",
"@popperjs/core": "2.11.8",
"@triliumnext/ckeditor5": "workspace:*",
@ -47,7 +47,7 @@
"leaflet-gpx": "2.2.0",
"mark.js": "8.11.1",
"marked": "15.0.12",
"mermaid": "11.6.0",
"mermaid": "11.7.0",
"mind-elixir": "4.6.1",
"normalize.css": "8.0.1",
"panzoom": "9.4.3",
@ -60,13 +60,13 @@
"@ckeditor/ckeditor5-inspector": "4.1.0",
"@types/bootstrap": "5.2.10",
"@types/jquery": "3.5.32",
"@types/leaflet": "1.9.18",
"@types/leaflet": "1.9.19",
"@types/leaflet-gpx": "1.3.7",
"@types/mark.js": "8.11.12",
"copy-webpack-plugin": "13.0.0",
"happy-dom": "18.0.1",
"script-loader": "0.7.2",
"vite-plugin-static-copy": "3.0.2"
"vite-plugin-static-copy": "3.1.0"
},
"nx": {
"name": "client",

View File

@ -688,7 +688,7 @@ export default class TabManager extends Component {
const titleFragments = [
// it helps to navigate in history if note title is included in the title
await activeNoteContext.getNavigationTitle(),
"TriliumNext Notes"
"Trilium Notes"
].filter(Boolean);
document.title = titleFragments.join(" - ");

View File

@ -1,6 +1,6 @@
{
"about": {
"title": "关于 TriliumNext Notes",
"title": "关于 Trilium Notes",
"close": "关闭",
"homepage": "项目主页:",
"app_version": "应用版本:",

View File

@ -1,6 +1,6 @@
{
"about": {
"title": "Über TriliumNext Notes",
"title": "Über Trilium Notes",
"close": "Schließen",
"homepage": "Startseite:",
"app_version": "App-Version:",
@ -639,7 +639,7 @@
"reload_frontend": "Frontend neu laden",
"show_hidden_subtree": "Versteckten Teilbaum anzeigen",
"show_help": "Hilfe anzeigen",
"about": "Über TriliumNext Notes",
"about": "Über Trilium Notes",
"logout": "Abmelden",
"show-cheatsheet": "Cheatsheet anzeigen",
"toggle-zen-mode": "Zen Modus"

View File

@ -1,6 +1,6 @@
{
"about": {
"title": "About TriliumNext Notes",
"title": "About Trilium Notes",
"close": "Close",
"homepage": "Homepage:",
"app_version": "App version:",
@ -643,7 +643,7 @@
"reload_frontend": "Reload Frontend",
"show_hidden_subtree": "Show Hidden Subtree",
"show_help": "Show Help",
"about": "About TriliumNext Notes",
"about": "About Trilium Notes",
"logout": "Logout",
"show-cheatsheet": "Show Cheatsheet",
"toggle-zen-mode": "Zen Mode"
@ -1197,7 +1197,6 @@
"restore_provider": "Restore provider to search",
"similarity_threshold": "Similarity Threshold",
"similarity_threshold_description": "Minimum similarity score (0-1) for notes to be included in context for LLM queries",
"reprocess_index": "Rebuild Search Index",
"reprocessing_index": "Rebuilding...",
"reprocess_index_started": "Search index optimization started in the background",
@ -1929,5 +1928,10 @@
"download_link": "Download Native Version",
"continue_anyway": "Continue Anyway",
"dont_show_again": "Don't show this warning again"
},
"editorfeatures": {
"title": "Features",
"emoji_completion_enabled": "Enable Emoji auto-completion",
"note_completion_enabled": "Enable note auto-completion"
}
}

View File

@ -1,6 +1,6 @@
{
"about": {
"title": "Acerca de TriliumNext Notes",
"title": "Acerca de Trilium Notes",
"close": "Cerrar",
"homepage": "Página principal:",
"app_version": "Versión de la aplicación:",
@ -16,7 +16,7 @@
"message": "Ha ocurrido un error crítico que previene que el cliente de la aplicación inicie:\n\n{{message}}\n\nMuy probablemente es causado por un script que falla de forma inesperada. Intente iniciar la aplicación en modo seguro y atienda el error."
},
"widget-error": {
"title": "No se pudo inicializar un widget",
"title": "Hubo un fallo al inicializar un widget",
"message-custom": "El widget personalizado de la nota con ID \"{{id}}\", titulada \"{{title}}\" no pudo ser inicializado debido a:\n\n{{message}}",
"message-unknown": "Un widget no pudo ser inicializado debido a:\n\n{{message}}"
},
@ -127,6 +127,7 @@
"collapseSubTree": "colapsar subárbol",
"tabShortcuts": "Atajos de pestañas",
"newTabNoteLink": "<kbd>CTRL+clic</kbd> - (o clic central del mouse) en el enlace de la nota abre la nota en una nueva pestaña",
"newTabWithActivationNoteLink": "<kbd>Ctrl+Shift+clic</kbd> - (o <kbd>Shift+clic de rueda de ratón</kbd>) en el enlace de la nota abre y activa la nota en una nueva pestaña",
"onlyInDesktop": "Solo en escritorio (compilación con Electron)",
"openEmptyTab": "abrir pestaña vacía",
"closeActiveTab": "cerrar pestaña activa",
@ -232,6 +233,8 @@
"move_success_message": "Las notas seleccionadas se han movido a "
},
"note_type_chooser": {
"change_path_prompt": "Cambiar donde se creará la nueva nota:",
"search_placeholder": "ruta de búsqueda por nombre (por defecto si está vacío)",
"modal_title": "Elija el tipo de nota",
"close": "Cerrar",
"modal_body": "Elija el tipo de nota/plantilla de la nueva nota:",
@ -274,9 +277,9 @@
"revision_last_edited": "Esta revisión se editó por última vez en {{date}}",
"confirm_delete_all": "¿Quiere eliminar todas las revisiones de esta nota?",
"no_revisions": "Aún no hay revisiones para esta nota...",
"restore_button": "",
"restore_button": "Restaurar",
"confirm_restore": "¿Quiere restaurar esta revisión? Esto sobrescribirá el título actual y el contenido de la nota con esta revisión.",
"delete_button": "",
"delete_button": "Eliminar",
"confirm_delete": "¿Quieres eliminar esta revisión?",
"revisions_deleted": "Se han eliminado las revisiones de nota.",
"revision_restored": "Se ha restaurado la revisión de nota.",
@ -588,6 +591,7 @@
"sat": "Sáb",
"sun": "Dom",
"cannot_find_day_note": "No se puede encontrar la nota del día",
"cannot_find_week_note": "No se puede encontrar la nota de la semana",
"january": "Enero",
"febuary": "Febrero",
"march": "Marzo",
@ -639,7 +643,7 @@
"reload_frontend": "Recargar interfaz",
"show_hidden_subtree": "Mostrar subárbol oculto",
"show_help": "Mostrar ayuda",
"about": "Acerca de TriliumNext Notes",
"about": "Acerca de Trilium Notes",
"logout": "Cerrar sesión",
"show-cheatsheet": "Mostrar hoja de trucos",
"toggle-zen-mode": "Modo Zen"
@ -1121,6 +1125,148 @@
"layout-vertical-description": "la barra del lanzador está en la izquierda (por defecto)",
"layout-horizontal-description": "la barra de lanzamiento está debajo de la barra de pestañas, la barra de pestañas ahora tiene ancho completo."
},
"ai_llm": {
"not_started": "No iniciado",
"title": "IA y ajustes de embeddings",
"processed_notes": "Notas procesadas",
"total_notes": "Notas totales",
"progress": "Progreso",
"queued_notes": "Notas en fila",
"failed_notes": "Notas fallidas",
"last_processed": "Última procesada",
"refresh_stats": "Recargar estadísticas",
"enable_ai_features": "Habilitar características IA/LLM",
"enable_ai_description": "Habilitar características de IA como resumen de notas, generación de contenido y otras capacidades LLM",
"openai_tab": "OpenAI",
"anthropic_tab": "Anthropic",
"voyage_tab": "Voyage AI",
"ollama_tab": "Ollama",
"enable_ai": "Habilitar características IA/LLM",
"enable_ai_desc": "Habilitar características de IA como resumen de notas, generación de contenido y otras capacidades LLM",
"provider_configuration": "Configuración de proveedor de IA",
"provider_precedence": "Precedencia de proveedor",
"provider_precedence_description": "Lista de proveedores en orden de precedencia separada por comas (p.e., 'openai,anthropic,ollama')",
"temperature": "Temperatura",
"temperature_description": "Controla la aleatoriedad de las respuestas (0 = determinista, 2 = aleatoriedad máxima)",
"system_prompt": "Mensaje de sistema",
"system_prompt_description": "Mensaje de sistema predeterminado utilizado para todas las interacciones de IA",
"openai_configuration": "Configuración de OpenAI",
"openai_settings": "Ajustes de OpenAI",
"api_key": "Clave API",
"url": "URL base",
"model": "Modelo",
"openai_api_key_description": "Tu clave API de OpenAI para acceder a sus servicios de IA",
"anthropic_api_key_description": "Tu clave API de Anthropic para acceder a los modelos Claude",
"default_model": "Modelo por defecto",
"openai_model_description": "Ejemplos: gpt-4o, gpt-4-turbo, gpt-3.5-turbo",
"base_url": "URL base",
"openai_url_description": "Por defecto: https://api.openai.com/v1",
"anthropic_settings": "Ajustes de Anthropic",
"anthropic_url_description": "URL base para la API de Anthropic (por defecto: https://api.anthropic.com)",
"anthropic_model_description": "Modelos Claude de Anthropic para el completado de chat",
"voyage_settings": "Ajustes de Voyage AI",
"ollama_settings": "Ajustes de Ollama",
"ollama_url_description": "URL para la API de Ollama (por defecto: http://localhost:11434)",
"ollama_model_description": "Modelo de Ollama a usar para el completado de chat",
"anthropic_configuration": "Configuración de Anthropic",
"voyage_configuration": "Configuración de Voyage AI",
"voyage_url_description": "Por defecto: https://api.voyageai.com/v1",
"ollama_configuration": "Configuración de Ollama",
"enable_ollama": "Habilitar Ollama",
"enable_ollama_description": "Habilitar Ollama para uso de modelo de IA local",
"ollama_url": "URL de Ollama",
"ollama_model": "Modelo de Ollama",
"refresh_models": "Refrescar modelos",
"refreshing_models": "Refrescando...",
"enable_automatic_indexing": "Habilitar indexado automático",
"rebuild_index": "Recrear índice",
"rebuild_index_error": "Error al comenzar la reconstrucción del índice. Consulte los registros para más detalles.",
"note_title": "Título de nota",
"error": "Error",
"last_attempt": "Último intento",
"actions": "Acciones",
"retry": "Reintentar",
"partial": "{{ percentage }}% completado",
"retry_queued": "Nota en la cola para reintento",
"retry_failed": "Hubo un fallo al poner en la cola a la nota para reintento",
"max_notes_per_llm_query": "Máximo de notas por consulta",
"max_notes_per_llm_query_description": "Número máximo de notas similares a incluir en el contexto IA",
"active_providers": "Proveedores activos",
"disabled_providers": "Proveedores deshabilitados",
"remove_provider": "Eliminar proveedor de la búsqueda",
"restore_provider": "Restaurar proveedor a la búsqueda",
"similarity_threshold": "Bias de similaridad",
"similarity_threshold_description": "Puntuación de similaridad mínima (0-1) para incluir notas en el contexto para consultas LLM",
"reprocess_index": "Reconstruir el índice de búsqueda",
"reprocessing_index": "Reconstruyendo...",
"reprocess_index_started": "La optimización de índice de búsqueda comenzó en segundo plano",
"reprocess_index_error": "Error al reconstruir el índice de búsqueda",
"index_rebuild_progress": "Progreso de reconstrucción de índice",
"index_rebuilding": "Optimizando índice ({{percentage}}%)",
"index_rebuild_complete": "Optimización de índice completa",
"index_rebuild_status_error": "Error al comprobar el estado de reconstrucción del índice",
"never": "Nunca",
"processing": "Procesando ({{percentage}}%)",
"incomplete": "Incompleto ({{percentage}}%)",
"complete": "Completo (100%)",
"refreshing": "Refrescando...",
"auto_refresh_notice": "Refrescar automáticamente cada {{seconds}} segundos",
"note_queued_for_retry": "Nota en la cola para reintento",
"failed_to_retry_note": "Hubo un fallo al reintentar nota",
"all_notes_queued_for_retry": "Todas las notas con fallo agregadas a la cola para reintento",
"failed_to_retry_all": "Hubo un fallo al reintentar notas",
"ai_settings": "Ajustes de IA",
"api_key_tooltip": "Clave API para acceder al servicio",
"empty_key_warning": {
"anthropic": "La clave API de Anthropic está vacía. Por favor, ingrese una clave API válida.",
"openai": "La clave API de OpenAI está vacía. Por favor, ingrese una clave API válida.",
"voyage": "La clave API de Voyage está vacía. Por favor, ingrese una clave API válida.",
"ollama": "La clave API de Ollama está vacía. Por favor, ingrese una clave API válida."
},
"agent": {
"processing": "Procesando...",
"thinking": "Pensando...",
"loading": "Cargando...",
"generating": "Generando..."
},
"name": "IA",
"openai": "OpenAI",
"use_enhanced_context": "Utilizar contexto mejorado",
"enhanced_context_description": "Provee a la IA con más contexto de la nota y sus notas relacionadas para obtener mejores respuestas",
"show_thinking": "Mostrar pensamiento",
"show_thinking_description": "Mostrar la cadena del proceso de pensamiento de la IA",
"enter_message": "Ingrese su mensaje...",
"error_contacting_provider": "Error al contactar con su proveedor de IA. Por favor compruebe sus ajustes y conexión a internet.",
"error_generating_response": "Error al generar respuesta de IA",
"index_all_notes": "Indexar todas las notas",
"index_status": "Estado de índice",
"indexed_notes": "Notas indexadas",
"indexing_stopped": "Indexado detenido",
"indexing_in_progress": "Indexado en progreso...",
"last_indexed": "Último indexado",
"n_notes_queued": "{{ count }} nota agregada a la cola para indexado",
"n_notes_queued_plural": "{{ count }} notas agregadas a la cola para indexado",
"note_chat": "Chat de nota",
"notes_indexed": "{{ count }} nota indexada",
"notes_indexed_plural": "{{ count }} notas indexadas",
"sources": "Fuentes",
"start_indexing": "Comenzar indexado",
"use_advanced_context": "Usar contexto avanzado",
"ollama_no_url": "Ollama no está configurado. Por favor ingrese una URL válida.",
"chat": {
"root_note_title": "Chats de IA",
"root_note_content": "Esta nota contiene tus conversaciones de chat de IA guardadas.",
"new_chat_title": "Nuevo chat",
"create_new_ai_chat": "Crear nuevo chat de IA"
},
"create_new_ai_chat": "Crear nuevo chat de IA",
"configuration_warnings": "Hay algunos problemas con su configuración de IA. Por favor compruebe sus ajustes.",
"experimental_warning": "La característica de LLM aún es experimental - ha sido advertido.",
"selected_provider": "Proveedor seleccionado",
"selected_provider_description": "Elija el proveedor de IA para el chat y características de completado",
"select_model": "Seleccionar modelo...",
"select_provider": "Seleccionar proveedor..."
},
"zoom_factor": {
"title": "Factor de zoom (solo versión de escritorio)",
"description": "El zoom también se puede controlar con los atajos CTRL+- y CTRL+=."
@ -1236,12 +1382,26 @@
"label": "Tamaño para modo de solo lectura automático (notas de texto)",
"unit": "caracteres"
},
"custom_date_time_format": {
"title": "Formato de fecha/hora personalizada",
"description": "Personalizar el formado de fecha y la hora insertada vía <kbd></kbd> o la barra de herramientas. Véa la <a href=\"https://day.js.org/docs/en/display/format\" target=\"_blank\" rel=\"noopener noreferrer\">documentación de Day.js</a> para más tokens de formato disponibles.",
"format_string": "Cadena de formato:",
"formatted_time": "Fecha/hora personalizada:"
},
"i18n": {
"title": "Localización",
"language": "Idioma",
"first-day-of-the-week": "Primer día de la semana",
"sunday": "Domingo",
"monday": "Lunes"
"monday": "Lunes",
"first-week-of-the-year": "Primer semana del año",
"first-week-contains-first-day": "Primer semana que contiene al primer día del año",
"first-week-contains-first-thursday": "Primer semana que contiene al primer jueves del año",
"first-week-has-minimum-days": "Primer semana que contiene un mínimo de días",
"min-days-in-first-week": "Días mínimos en la primer semana",
"first-week-info": "Primer semana que contiene al primer jueves del año está basado en el estándar<a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a>.",
"first-week-warning": "Cambiar las opciones de primer semana puede causar duplicados con las Notas Semanales existentes y las Notas Semanales existentes no serán actualizadas respectivamente.",
"formatting-locale": "Fecha y formato de número"
},
"backup": {
"automatic_backup": "Copia de seguridad automática",
@ -1308,6 +1468,39 @@
"password_mismatch": "Las nuevas contraseñas no son las mismas.",
"password_changed_success": "La contraseña ha sido cambiada. Trilium se recargará después de presionar Aceptar."
},
"multi_factor_authentication": {
"title": "Autenticación Multi-Factor",
"description": "La autenticación multifactor (MFA) agrega una capa adicional de seguridad a su cuenta. En lugar de solo ingresar una contraseña para iniciar sesión, MFA requiere que proporcione una o más pruebas adicionales para verificar su identidad. De esta manera, incluso si alguien se apodera de su contraseña, aún no puede acceder a su cuenta sin la segunda pieza de información. Es como agregar una cerradura adicional a su puerta, lo que hace que sea mucho más difícil para cualquier otra persona entrar.<br><br>Por favor siga las instrucciones a continuación para habilitar MFA. Si no lo configura correctamente, el inicio de sesión volverá a solo contraseña.",
"mfa_enabled": "Habilitar la autenticación multifactor",
"mfa_method": "Método MFA",
"electron_disabled": "Actualmente la autenticación multifactor no está soportada en la compilación de escritorio.",
"totp_title": "Contraseña de un solo uso basada en el tiempo (TOTP)",
"totp_description": "TOTP (contraseña de un solo uso basada en el tiempo) es una característica de seguridad que genera un código temporal único que cambia cada 30 segundos. Utiliza este código, junto con su contraseña para iniciar sesión en su cuenta, lo que hace que sea mucho más difícil para cualquier otra persona acceder a ella.",
"totp_secret_title": "Generar secreto TOTP",
"totp_secret_generate": "Generar secreto TOTP",
"totp_secret_regenerate": "Regenerar secreto TOTP",
"no_totp_secret_warning": "Para habilitar TOTP, primero debe de generar un secreto TOTP.",
"totp_secret_description_warning": "Después de generar un nuevo secreto TOTP, le será requerido que inicie sesión otra vez con el nuevo secreto TOTP.",
"totp_secret_generated": "Secreto TOTP generado",
"totp_secret_warning": "Por favor guarde el secreto generado en una ubicación segura. No será mostrado de nuevo.",
"totp_secret_regenerate_confirm": "¿Está seguro que desea regenerar el secreto TOTP? Esto va a invalidar el secreto TOTP previo y todos los códigos de recuperación existentes.",
"recovery_keys_title": "Claves de recuperación para un solo inicio de sesión",
"recovery_keys_description": "Las claves de recuperación para un solo inicio de sesión son usadas para iniciar sesión incluso cuando no puede acceder a los códigos de su autentificador.",
"recovery_keys_description_warning": "Las claves de recuperación no son mostrada de nuevo después de dejar esta página, manténgalas en un lugar seguro.<br>Después de que una clave de recuperación es utilizada ya no puede utilizarse de nuevo.",
"recovery_keys_error": "Error al generar códigos de recuperación",
"recovery_keys_no_key_set": "No hay códigos de recuperación establecidos",
"recovery_keys_generate": "Generar códigos de recuperación",
"recovery_keys_regenerate": "Regenerar códigos de recuperación",
"recovery_keys_used": "Usado: {{date}}",
"recovery_keys_unused": "El código de recuperación {{index}} está sin usar",
"oauth_title": "OAuth/OpenID",
"oauth_description": "OpenID es una forma estandarizada de permitirle iniciar sesión en sitios web utilizando una cuenta de otro servicio, como Google, para verificar su identidad. Siga estas <a href = \"https://developers.google.com/identity/openid-connect/openid-connect\">instrucciones</a> para configurar un servicio OpenID a través de Google.",
"oauth_description_warning": "Para habilitar OAuth/OpenID, necesita establecer la URL base de OAuth/OpenID, ID de cliente y secreto de cliente en el archivo config.ini y reiniciar la aplicación. Si desea establecerlas desde variables de ambiente, por favor establezca TRILIUM_OAUTH_BASE_URL, TRILIUM_OAUTH_CLIENT_ID y TRILIUM_OAUTH_CLIENT_SECRET.",
"oauth_missing_vars": "Ajustes faltantes: {{variables}}",
"oauth_user_account": "Cuenta de usuario: ",
"oauth_user_email": "Correo electrónico de usuario: ",
"oauth_user_not_logged_in": "¡No ha iniciado sesión!"
},
"shortcuts": {
"keyboard_shortcuts": "Atajos de teclado",
"multiple_shortcuts": "Varios atajos para la misma acción se pueden separar mediante comas.",
@ -1431,7 +1624,9 @@
"widget": "Widget",
"confirm-change": "No es recomendado cambiar el tipo de nota cuando el contenido de la nota no está vacío. ¿Desea continuar de cualquier manera?",
"geo-map": "Mapa Geo",
"beta-feature": "Beta"
"beta-feature": "Beta",
"ai-chat": "Chat de IA",
"task-list": "Lista de tareas"
},
"protect_note": {
"toggle-on": "Proteger la nota",
@ -1541,7 +1736,9 @@
},
"clipboard": {
"cut": "La(s) notas(s) han sido cortadas al portapapeles.",
"copied": "La(s) notas(s) han sido copiadas al portapapeles."
"copied": "La(s) notas(s) han sido copiadas al portapapeles.",
"copy_failed": "No se puede copiar al portapapeles debido a problemas de permisos.",
"copy_success": "Copiado al portapapeles."
},
"entrypoints": {
"note-revision-created": "Una revisión de nota ha sido creada.",
@ -1584,7 +1781,7 @@
"auto-detect-language": "Detectado automáticamente"
},
"highlighting": {
"title": "",
"title": "Bloques de código",
"description": "Controla el resaltado de sintaxis para bloques de código dentro de las notas de texto, las notas de código no serán afectadas.",
"color-scheme": "Esquema de color"
},
@ -1592,7 +1789,8 @@
"word_wrapping": "Ajuste de palabras",
"theme_none": "Sin resaltado de sintaxis",
"theme_group_light": "Temas claros",
"theme_group_dark": "Temas oscuros"
"theme_group_dark": "Temas oscuros",
"copy_title": "Copiar al portapapeles"
},
"classic_editor_toolbar": {
"title": "Formato"
@ -1713,5 +1911,22 @@
},
"png_export_button": {
"button_title": "Exportar diagrama como PNG"
},
"svg": {
"export_to_png": "El diagrama no pudo ser exportado a PNG."
},
"code_theme": {
"title": "Apariencia",
"word_wrapping": "Ajuste de palabras",
"color-scheme": "Esquema de color"
},
"cpu_arch_warning": {
"title": "Por favor descargue la versión ARM64",
"message_macos": "TriliumNext está siendo ejecutado bajo traducción Rosetta 2, lo que significa que está usando la versión Intel (x64) en Apple Silicon Mac. Esto impactará significativamente en el rendimiento y la vida de la batería.",
"message_windows": "TriliumNext está siendo ejecutado bajo emulación, lo que significa que está usando la version Intel (x64) en Windows en un dispositivo ARM. Esto impactará significativamente en el rendimiento y la vida de la batería.",
"recommendation": "Para la mejor experiencia, por favor descargue la versión nativa ARM64 de TriliumNext desde nuestra página de lanzamientos.",
"download_link": "Descargar versión nativa",
"continue_anyway": "Continuar de todas maneras",
"dont_show_again": "No mostrar esta advertencia otra vez"
}
}

View File

@ -1,6 +1,6 @@
{
"about": {
"title": "À propos de TriliumNext Notes",
"title": "À propos de Trilium Notes",
"close": "Fermer",
"homepage": "Page d'accueil :",
"app_version": "Version de l'application :",
@ -639,7 +639,7 @@
"reload_frontend": "Recharger l'interface",
"show_hidden_subtree": "Afficher le Sous-arbre caché",
"show_help": "Afficher l'aide",
"about": "À propos de TriliumNext Notes",
"about": "À propos de Trilium Notes",
"logout": "Déconnexion",
"show-cheatsheet": "Afficher l'aide rapide",
"toggle-zen-mode": "Zen Mode"

View File

@ -1,6 +1,6 @@
{
"about": {
"title": "Despre TriliumNext Notes",
"title": "Despre Trilium Notes",
"homepage": "Site web:",
"app_version": "Versiune aplicație:",
"db_version": "Versiune bază de date:",
@ -572,7 +572,7 @@
"system-default": "Fontul predefinit al sistemului"
},
"global_menu": {
"about": "Despre TriliumNext Notes",
"about": "Despre Trilium Notes",
"advanced": "Opțiuni avansate",
"configure_launchbar": "Configurează bara de lansare",
"logout": "Deautentificare",

View File

@ -1,6 +1,6 @@
{
"about": {
"title": "關於 TriliumNext Notes",
"title": "關於 Trilium Notes",
"homepage": "項目主頁:",
"app_version": "軟件版本:",
"db_version": "資料庫版本:",

View File

@ -1,13 +1,12 @@
import { ALLOWED_PROTOCOLS } from "../../../services/link.js";
import { MIME_TYPE_AUTO } from "@triliumnext/commons";
import { buildExtraCommands, type EditorConfig } from "@triliumnext/ckeditor5";
import { buildExtraCommands, type EditorConfig, PREMIUM_PLUGINS } from "@triliumnext/ckeditor5";
import { getHighlightJsNameForMime } from "../../../services/mime_types.js";
import options from "../../../services/options.js";
import { ensureMimeTypesForHighlighting, isSyntaxHighlightEnabled } from "../../../services/syntax_highlight.js";
import emojiDefinitionsUrl from "@triliumnext/ckeditor5/emoji_definitions/en.json?url";
import { copyTextWithToast } from "../../../services/clipboard_ext.js";
import getTemplates from "./snippets.js";
import { PREMIUM_PLUGINS } from "../../../../../../packages/ckeditor5/src/plugins.js";
import { t } from "../../../services/i18n.js";
import { getMermaidConfig } from "../../../services/mermaid.js";
import noteAutocompleteService, { type Suggestion } from "../../../services/note_autocomplete.js";
@ -30,22 +29,6 @@ export async function buildConfig(opts: BuildEditorOptions): Promise<EditorConfi
const config: EditorConfig = {
licenseKey,
placeholder: t("editable_text.placeholder"),
mention: {
feeds: [
{
marker: "@",
feed: (queryText: string) => noteAutocompleteService.autocompleteSourceForCKEditor(queryText),
itemRenderer: (item) => {
const itemElement = document.createElement("button");
itemElement.innerHTML = `${(item as Suggestion).highlightedNotePathTitle} `;
return itemElement;
},
minimumCharacters: 0
}
],
},
codeBlock: {
languages: buildListOfLanguages()
},
@ -180,7 +163,8 @@ export async function buildConfig(opts: BuildEditorOptions): Promise<EditorConfi
allow: JSON.parse(options.get("allowedHtmlTags"))
},
// This value must be kept in sync with the language defined in webpack.config.js.
language: "en"
language: "en",
removePlugins: getDisabledPlugins()
};
// Set up content language.
@ -192,6 +176,26 @@ export async function buildConfig(opts: BuildEditorOptions): Promise<EditorConfi
}
}
// Mention customisation.
if (options.get("textNoteCompletionEnabled") === "true") {
config.mention = {
feeds: [
{
marker: "@",
feed: (queryText: string) => noteAutocompleteService.autocompleteSourceForCKEditor(queryText),
itemRenderer: (item) => {
const itemElement = document.createElement("button");
itemElement.innerHTML = `${(item as Suggestion).highlightedNotePathTitle} `;
return itemElement;
},
minimumCharacters: 0
}
],
};
}
// Enable premium plugins.
if (hasPremiumLicense) {
config.extraPlugins = [
@ -232,3 +236,13 @@ function getLicenseKey() {
return premiumLicenseKey;
}
function getDisabledPlugins() {
let disabledPlugins: string[] = [];
if (options.get("textNoteEmojiCompletionEnabled") !== "true") {
disabledPlugins.push("EmojiMention");
}
return disabledPlugins;
}

View File

@ -46,6 +46,7 @@ import LanguageOptions from "./options/i18n/language.js";
import type BasicWidget from "../basic_widget.js";
import CodeTheme from "./options/code_notes/code_theme.js";
import RelatedSettings from "./options/appearance/related_settings.js";
import EditorFeaturesOptions from "./options/text_notes/features.js";
const TPL = /*html*/`<div class="note-detail-content-widget note-detail-printable">
<style>
@ -85,6 +86,7 @@ const CONTENT_WIDGETS: Record<OptionPages | "_backendLog", (typeof NoteContextAw
],
_optionsTextNotes: [
EditorOptions,
EditorFeaturesOptions,
HeadingStyleOptions,
CodeBlockOptions,
TableOfContentsOptions,

View File

@ -0,0 +1,45 @@
import { OptionMap } from "@triliumnext/commons";
import OptionsWidget from "../options_widget";
import { t } from "../../../../services/i18n";
const TPL = /*html*/`
<div class="options-section">
<h4>${t("editorfeatures.title")}</h4>
<div>
<label class="tn-checkbox">
<input type="checkbox" name="emoji-completion-enabled" />
${t("editorfeatures.emoji_completion_enabled")}
</label>
</div>
<div>
<label class="tn-checkbox">
<input type="checkbox" name="note-completion-enabled" />
${t("editorfeatures.note_completion_enabled")}
</label>
</div>
</div>
`;
export default class EditorFeaturesOptions extends OptionsWidget {
private $emojiCompletionEnabledCheckbox!: JQuery<HTMLElement>;
private $noteCompletionEnabledCheckbox!: JQuery<HTMLElement>;
doRender() {
this.$widget = $(TPL);
this.$emojiCompletionEnabledCheckbox = this.$widget.find(`input[name="emoji-completion-enabled"]`);
this.$emojiCompletionEnabledCheckbox.on("change", () => this.updateCheckboxOption("textNoteEmojiCompletionEnabled", this.$emojiCompletionEnabledCheckbox))
this.$noteCompletionEnabledCheckbox = this.$widget.find(`input[name="note-completion-enabled"]`);
this.$noteCompletionEnabledCheckbox.on("change", () => this.updateCheckboxOption("textNoteCompletionEnabled", this.$noteCompletionEnabledCheckbox))
}
optionsLoaded(options: OptionMap) {
this.setCheckboxState(this.$emojiCompletionEnabledCheckbox, options.textNoteEmojiCompletionEnabled);
this.setCheckboxState(this.$noteCompletionEnabledCheckbox, options.textNoteCompletionEnabled);
}
}

3
apps/desktop-e2e/.env Normal file
View File

@ -0,0 +1,3 @@
TRILIUM_INTEGRATION_TEST=memory-no-store
TRILIUM_PORT=8082
TRILIUM_DATA_DIR=data

View File

@ -0,0 +1,15 @@
import playwright from "eslint-plugin-playwright";
import baseConfig from "../../eslint.config.mjs";
export default [
playwright.configs["flat/recommended"],
...baseConfig,
{
files: [
"**/*.ts",
"**/*.js"
],
// Override or add rules here
rules: {}
}
];

View File

@ -0,0 +1,24 @@
{
"name": "@triliumnext/desktop-e2e",
"version": "0.0.1",
"private": true,
"nx": {
"name": "desktop-e2e",
"implicitDependencies": [
"client",
"desktop"
],
"targets": {
"e2e": {
"dependsOn": [
"desktop:build",
"desktop:rebuild-deps"
]
}
}
},
"devDependencies": {
"dotenv": "16.5.0",
"electron": "36.5.0"
}
}

View File

@ -0,0 +1,23 @@
import { defineConfig, devices } from '@playwright/test';
require('dotenv').config({
path: __dirname + "/" + ".env"
});
/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
},
projects: [
{
name: "chromium",
use: { ...devices["Desktop Chrome"] },
}
],
});

View File

@ -0,0 +1,66 @@
import { test, expect, _electron as electron, type ElectronApplication, request } from '@playwright/test';
import { join } from 'path';
import App from './support';
let app: ElectronApplication;
test.beforeAll(async () => {
const distPath = join(__dirname, '../../desktop/dist/main.cjs');
console.log("Dir", join(__dirname, 'traces'));
app = await electron.launch({
args: [ distPath ]
});
});
test.afterAll(async () => {
try {
const pid = app.process().pid;
if (pid) {
// Double-check process is dead
try {
process.kill(pid, 0); // throws if process doesn't exist
process.kill(pid, 'SIGKILL'); // force kill if still alive
} catch (e) {
// Process already dead
}
}
} catch (err) {
console.warn('Failed to close Electron app cleanly:', err);
}
await app.close();
});
test('First setup', async () => {
// Get the main window
const setupWindow = await app.firstWindow();
await expect(setupWindow).toHaveTitle("Setup");
await expect(setupWindow.locator('h1')).toHaveText("Trilium Notes setup");
await setupWindow.locator(`input[type="radio"]`).first().click();
// Wait for the finish.
const newWindowPromise = app.waitForEvent('window');
await setupWindow.locator(`button[type="submit"]`, { hasText: "Next" }).click();
const mainWindow = await newWindowPromise;
await expect(mainWindow).toHaveTitle("Trilium Notes");
const support = new App(mainWindow);
await support.selectNoteInNoteTree("Trilium Demo");
await support.setNoteShared(true);
const sharedInfoWidget = support.currentNoteSplit.locator(".shared-info-widget");
await expect(sharedInfoWidget).toBeVisible();
const sharedInfoLink = sharedInfoWidget.locator("a.shared-link");
const linkUrl = await sharedInfoLink.getAttribute("href");
expect(linkUrl).toBeDefined();
// Verify the shared link is valid
const requestContext = await request.newContext();
const response = await requestContext.get(linkUrl!);
expect(response).toBeOK();
await mainWindow.waitForTimeout(5000);
});

View File

@ -0,0 +1,53 @@
import { expect, Locator, Page } from "@playwright/test";
export default class App {
readonly noteTree: Locator;
readonly currentNoteSplit: Locator;
readonly currentNoteSplitTitle: Locator;
readonly currentNoteSplitRibbon: Locator;
readonly currentNoteSplitContent: Locator;
page: Page;
constructor(page: Page) {
this.page = page;
this.noteTree = page.locator(".tree-wrapper");
this.currentNoteSplit = page.locator(".note-split:not(.hidden-ext)");
this.currentNoteSplitTitle = this.currentNoteSplit.locator(".note-title");
this.currentNoteSplitRibbon = this.currentNoteSplit.locator(".ribbon-container");
this.currentNoteSplitContent = this.currentNoteSplit.locator(".note-detail-printable.visible");
}
async selectNoteInNoteTree(noteTitle: string) {
const item = this.noteTree.locator(`span.fancytree-node`, { hasText: noteTitle });
await item.click();
await expect(this.currentNoteSplitTitle).toHaveValue(noteTitle);
}
async goToRibbonTab(tabName: string) {
await this.currentNoteSplitRibbon.locator(`.ribbon-tab-title`, { hasText: tabName }).click();
}
async setNoteShared(shared: boolean) {
await this.goToRibbonTab("Basic Properties");
// Ensure the initial state.
const switchButton = this.currentNoteSplitRibbon.locator(`.shared-switch-container .switch-button`);
if (shared) {
await expect(switchButton.locator("input")).not.toBeChecked();
} else {
await expect(switchButton.locator("input")).toBeChecked();
}
// Click the switch to change the state.
await switchButton.click();
// Verify the state after clicking.
if (shared) {
await expect(switchButton.locator("input")).toBeChecked();
} else {
await expect(switchButton.locator("input")).not.toBeChecked();
}
}
}

View File

@ -0,0 +1,25 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"outDir": "out-tsc/playwright",
"sourceMap": false
},
"include": [
"**/*.ts",
"**/*.js",
"playwright.config.ts",
"src/**/*.spec.ts",
"src/**/*.spec.js",
"src/**/*.test.ts",
"src/**/*.test.js",
"src/**/*.d.ts"
],
"exclude": [
"out-tsc",
"test-output",
"eslint.config.js",
"eslint.config.mjs",
"eslint.config.cjs"
]
}

View File

@ -2,6 +2,7 @@ import path from "path";
import fs from "fs-extra";
import { LOCALES } from "@triliumnext/commons";
import { PRODUCT_NAME } from "../src/app-info.js";
import type { ForgeConfig } from "@electron-forge/shared-types";
const ELECTRON_FORGE_DIR = __dirname;
@ -23,13 +24,13 @@ const windowsSignConfiguration = process.env.WINDOWS_SIGN_EXECUTABLE ? {
const macosSignConfiguration = process.env.APPLE_ID ? {
osxSign: {},
osxNotarize: {
appleId: process.env.APPLE_ID,
appleIdPassword: process.env.APPLE_ID_PASSWORD,
teamId: process.env.APPLE_TEAM_ID
appleId: process.env.APPLE_ID!,
appleIdPassword: process.env.APPLE_ID_PASSWORD!,
teamId: process.env.APPLE_TEAM_ID!
}
} : undefined;
module.exports = {
const config: ForgeConfig = {
outDir: "out",
// Documentation of `packagerConfig` options: https://electron.github.io/packager/main/interfaces/Options.html
packagerConfig: {
@ -143,7 +144,7 @@ module.exports = {
],
hooks: {
// Remove unused locales from the packaged app to save some space.
postPackage(_, packageResult) {
async postPackage(_, packageResult) {
const isMac = (process.platform === "darwin");
let localesToKeep = LOCALES
.filter(locale => !locale.contentOnly)
@ -159,8 +160,8 @@ module.exports = {
for (const outputPath of packageResult.outputPaths) {
const localeDirs = isMac
? [
path.join(outputPath, "TriliumNext Notes.app/Contents/Resources"),
path.join(outputPath, "TriliumNext Notes.app/Contents/Frameworks/Electron Framework.framework/Resources")
path.join(outputPath, `${PRODUCT_NAME}.app/Contents/Resources`),
path.join(outputPath, `${PRODUCT_NAME}.app/Contents/Frameworks/Electron Framework.framework/Resources`)
]
: [ path.join(outputPath, 'locales') ];
@ -212,7 +213,7 @@ module.exports = {
}
},
// Gather all the artifacts produced by the makers and copy them to a common upload directory.
postMake(_, makeResults) {
async postMake(_, makeResults) {
const outputDir = path.join(__dirname, "..", "upload");
fs.mkdirpSync(outputDir);
for (const makeResult of makeResults) {
@ -261,3 +262,5 @@ function getExtraResourcesForPlatform() {
return resources;
}
export default config;

View File

@ -1,12 +1,12 @@
{
"name": "@triliumnext/desktop",
"version": "0.95.0",
"description": "Build your personal knowledge base with TriliumNext Notes",
"description": "Build your personal knowledge base with Trilium Notes",
"private": true,
"main": "main.cjs",
"dependencies": {
"@electron/remote": "2.1.2",
"better-sqlite3": "^11.9.1",
"better-sqlite3": "^12.0.0",
"electron-debug": "4.1.0",
"electron-dl": "4.0.0",
"electron-squirrel-startup": "1.0.1",
@ -36,7 +36,7 @@
},
"license": "AGPL-3.0-only",
"author": {
"name": "TriliumNext Notes Team",
"name": "Trilium Notes Team",
"email": "contact@eliandoran.me",
"url": "https://github.com/TriliumNext/Notes"
},
@ -98,6 +98,11 @@
"input": "apps/server/dist/assets",
"output": "assets"
},
{
"glob": "**/*",
"input": "packages/share-theme/src/templates",
"output": "share-theme/templates"
},
{
"glob": "**/*",
"input": "apps/desktop/src/assets",

View File

@ -0,0 +1,46 @@
import { globSync } from "fs";
import { join } from "path";
import { it, describe, expect } from "vitest";
describe("Check artifacts are present", () => {
const distPath = join(__dirname, "../../dist");
it("has the necessary node modules", async () => {
const paths = [
"node_modules/better-sqlite3",
"node_modules/bindings",
"node_modules/file-uri-to-path"
];
ensurePathsExist(paths);
});
it("includes the client", async () => {
const paths = [
"public/assets",
"public/fonts",
"public/node_modules",
"public/src",
"public/stylesheets",
"public/translations"
];
ensurePathsExist(paths);
});
it("includes necessary assets", async () => {
const paths = [
"assets",
"share-theme"
];
ensurePathsExist(paths);
});
function ensurePathsExist(paths: string[]) {
for (const path of paths) {
const result = globSync(join(distPath, path, "**"));
expect(result, path).not.toHaveLength(0);
}
}
});

View File

@ -1,4 +1,4 @@
/**
* The Electron product name (can be used for the window WMClass or passed down to the Electron packager).
*/
export const PRODUCT_NAME = "TriliumNext Notes";
export const PRODUCT_NAME = "Trilium Notes";

View File

@ -0,0 +1,18 @@
/// <reference types='vitest' />
import { defineConfig } from 'vite';
export default defineConfig(() => ({
root: __dirname,
cacheDir: '../../node_modules/.vite/apps/server',
plugins: [],
test: {
watch: false,
globals: true,
setupFiles: ["./spec/setup.ts"],
environment: "node",
include: ['spec/build-checks/**'],
reporters: [
"verbose"
]
},
}));

View File

@ -4,7 +4,7 @@
"description": "Standalone tool to dump contents of Trilium document.db file into a directory tree of notes",
"private": true,
"dependencies": {
"better-sqlite3": "^11.1.2",
"better-sqlite3": "^12.0.0",
"mime-types": "^3.0.0",
"sanitize-filename": "^1.6.3",
"tsx": "^4.19.3",

View File

@ -17,7 +17,7 @@
<img style="aspect-ratio:150/150;" src="Trilium Demo_icon-color.svg" width="150"
height="150">
</figure>
<p><strong>Welcome to TriliumNext Notes!</strong>
<p><strong>Welcome to Trilium Notes!</strong>
</p>
<p>This is initial "demo" document provided by TriliumNext by default to

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg enable-background="new 0 0 256 256" version="1.1" viewBox="0 0 256 256" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<title>TriliumNext Notes</title>
<title>Trilium Notes</title>
<style type="text/css">
.st0{fill:#95C980;}
.st1{fill:#72B755;}

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -5,7 +5,7 @@
"description": "Desktop version of Trilium which imports the demo database (presented to new users at start-up) or the user guide and other documentation and saves the modifications for committing.",
"dependencies": {
"archiver": "7.0.1",
"better-sqlite3": "^11.9.1"
"better-sqlite3": "^12.0.0"
},
"devDependencies": {
"@triliumnext/client": "workspace:*",

View File

@ -1,4 +1,4 @@
FROM node:22.16.0-bullseye-slim AS builder
FROM node:22.17.0-bullseye-slim AS builder
RUN corepack enable
# Install native dependencies since we might be building cross-platform.
@ -7,7 +7,7 @@ COPY ./docker/package.json ./docker/pnpm-workspace.yaml /usr/src/app/
# We have to use --no-frozen-lockfile due to CKEditor patches
RUN pnpm install --no-frozen-lockfile --prod && pnpm rebuild
FROM node:22.16.0-bullseye-slim
FROM node:22.17.0-bullseye-slim
# Install only runtime dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends \

View File

@ -1,4 +1,4 @@
FROM node:22.16.0-alpine AS builder
FROM node:22.17.0-alpine AS builder
RUN corepack enable
# Install native dependencies since we might be building cross-platform.
@ -7,7 +7,7 @@ COPY ./docker/package.json ./docker/pnpm-workspace.yaml /usr/src/app/
# We have to use --no-frozen-lockfile due to CKEditor patches
RUN pnpm install --no-frozen-lockfile --prod && pnpm rebuild
FROM node:22.16.0-alpine
FROM node:22.17.0-alpine
# Install runtime dependencies
RUN apk add --no-cache su-exec shadow

View File

@ -1,4 +1,4 @@
FROM node:22.16.0-alpine AS builder
FROM node:22.17.0-alpine AS builder
RUN corepack enable
# Install native dependencies since we might be building cross-platform.
@ -7,7 +7,7 @@ COPY ./docker/package.json ./docker/pnpm-workspace.yaml /usr/src/app/
# We have to use --no-frozen-lockfile due to CKEditor patches
RUN pnpm install --no-frozen-lockfile --prod && pnpm rebuild
FROM node:22.16.0-alpine
FROM node:22.17.0-alpine
# Create a non-root user with configurable UID/GID
ARG USER=trilium
ARG UID=1001

View File

@ -1,4 +1,4 @@
FROM node:22.16.0-bullseye-slim AS builder
FROM node:22.17.0-bullseye-slim AS builder
RUN corepack enable
# Install native dependencies since we might be building cross-platform.
@ -7,7 +7,7 @@ COPY ./docker/package.json ./docker/pnpm-workspace.yaml /usr/src/app/
# We have to use --no-frozen-lockfile due to CKEditor patches
RUN pnpm install --no-frozen-lockfile --prod && pnpm rebuild
FROM node:22.16.0-bullseye-slim
FROM node:22.17.0-bullseye-slim
# Create a non-root user with configurable UID/GID
ARG USER=trilium
ARG UID=1001

View File

@ -1,5 +1,5 @@
{
"dependencies": {
"better-sqlite3": "11.10.0"
"better-sqlite3": "12.1.1"
}
}

View File

@ -4,7 +4,7 @@
"description": "The server-side component of TriliumNext, which exposes the client via the web, allows for sync and provides a REST API for both internal and external use.",
"private": true,
"dependencies": {
"better-sqlite3": "11.10.0"
"better-sqlite3": "12.1.1"
},
"devDependencies": {
"@electron/remote": "2.1.2",
@ -39,7 +39,7 @@
"@types/ws": "8.18.1",
"@types/xml2js": "0.4.14",
"express-http-proxy": "2.1.1",
"@anthropic-ai/sdk": "0.54.0",
"@anthropic-ai/sdk": "0.55.0",
"@braintree/sanitize-url": "7.1.1",
"@triliumnext/commons": "workspace:*",
"@triliumnext/express-partial-content": "workspace:*",
@ -65,7 +65,7 @@
"escape-html": "1.0.3",
"express": "5.1.0",
"express-openid-connect": "^2.17.1",
"express-rate-limit": "7.5.0",
"express-rate-limit": "7.5.1",
"express-session": "1.18.1",
"file-uri-to-path": "2.0.0",
"fs-extra": "11.3.0",
@ -88,7 +88,7 @@
"multer": "2.0.1",
"normalize-strings": "1.1.1",
"ollama": "0.5.16",
"openai": "5.5.1",
"openai": "5.7.0",
"rand-token": "1.0.1",
"safe-compare": "1.1.4",
"sanitize-filename": "1.6.3",

View File

@ -48,7 +48,7 @@ chmod 755 $BUILD_DIR/trilium.sh
VERSION=`jq -r ".version" package.json`
ARCHIVE_NAME="TriliumNextNotes-Server-${VERSION}-linux-${ARCH}"
ARCHIVE_NAME="TriliumNotes-Server-${VERSION}-linux-${ARCH}"
echo "Creating Archive $ARCHIVE_NAME..."
mkdir $DIST_DIR

File diff suppressed because one or more lines are too long

View File

@ -42,19 +42,5 @@
This will export the notes in an unencrypted form, so if you reimport into
Trilium, make sure to re-protect these notes.</p>
<h2>Supported syntax</h2>
<ul>
<li><a href="https://github.github.com/gfm/">GitHub-Flavored Markdown</a> is
the main syntax that Trilium is following.</li>
<li>Images are supported. When exporting, images are usually kept in the basic
Markdown syntax but will use the HTML syntax if the image has a custom
width. Figures are always embedded as HTML.</li>
<li>Tables are supported with the Markdown syntax. If the table is too complex
or contains elements that would render as HTML, the table is also rendered
as HTML.</li>
<li><a class="reference-link" href="#root/_help_NwBbFdNZ9h7O">Admonitions</a>&nbsp;are
supported using GitHub's format.</li>
<li>Links are supported. “Reference links” (internal links that mirror a note's
title and display its icon) are embedded as HTML in order to preserve the
information on import.</li>
<li>Math equations are supported using <code>$</code> and <code>$$</code> syntaxes.</li>
</ul>
<p>See the dedicated page:&nbsp;<a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/mHbBMPDPkVV5/Oau6X9rCuegd/_help_rJ9grSgoExl9">Supported syntax</a>
</p>

View File

@ -0,0 +1,54 @@
<p><a href="https://github.github.com/gfm/">GitHub-Flavored Markdown</a> is
the main syntax that Trilium is following.</p>
<h2>Images</h2>
<p>When exporting, images are usually kept in the basic Markdown syntax but
will use the HTML syntax if the image has a custom width. Figures are always
embedded as HTML.</p>
<h2>Tables</h2>
<p>Simple tables are supported with the Markdown syntax. If the table is
too complex or contains elements that would render as HTML, the table is
also rendered as HTML.</p>
<h2>Links</h2>
<p>Standard Markdown links are supported.</p>
<p>Trilium internal links (that mirror a note's title and display its icon)
are embedded as HTML in order to preserve the information on import.</p>
<h2>Math equations</h2>
<p>Both inline and display equations are supported, using the <code>$</code> and <code>$$</code> syntaxes.</p>
<h2>Admonitions</h2>
<p>The Markdown syntax for admonitions as supported by Trilium is the one
that GitHub uses, which is as follows:</p><pre><code class="language-text-x-trilium-auto">&gt; [!NOTE]
&gt; This is a note.
&gt; [!TIP]
&gt; This is a tip.
&gt; [!IMPORTANT]
&gt; This is a very important information.
&gt; [!CAUTION]
&gt; This is a caution.</code></pre>
<p>There are currently no plans of supporting alternative admonition syntaxes
such as <code>!!! note</code>.</p>
<h2>Wikilinks</h2>
<p>Basic support for wikilinks has been added in v0.96.0:</p>
<ul>
<li><code>[[foo/bar]]</code> will look for the <code>bar.md</code> file in the <code>foo</code> directory
and turn it into an internal link.</li>
<li><code>![[foo/baz.png]]</code> will look for the <code>baz.png</code> file
in the <code>foo</code> directory and turn it into an image.</li>
</ul>
<p>This feature is import-only, which means that it will turn wikilinks into
Trilium-compatible syntax, but it will not export Trilium Notes into Markdown
files with this syntax.</p>
<aside class="admonition important">
<p>The path to pages in wikilinks is resolved relatively to the <em>import root </em>and
not the current directory of the note. This is to be inline with other
platforms that use wikilinks such as SilverBullet.</p>
<p>The root path of the import is determined as follows:</p>
<ul>
<li>If there is a single directory within the archive at root level, then
that directory is considered the root.</li>
<li>If there are multiple files &amp; directories at root level, then the
archive root (containing all of these items) is considered the root.</li>
</ul>
</aside>

View File

@ -20,7 +20,7 @@
<h2>Installation</h2>
<h3>Download</h3>
<p>You can either download source code zip/tar from <a href="https://github.com/TriliumNext/Notes/releases/latest">https://github.com/TriliumNext/Notes/releases/latest</a>.</p>
<p>For the latest version including betas, clone Git repository <strong>from</strong> <code>master</code> <strong>branch</strong> with:</p><pre><code class="language-text-x-trilium-auto">git clone -b master https://github.com/triliumnext/notes.git</code></pre>
<p>For the latest version including betas, clone Git repository <strong>from</strong> <code>main</code> <strong>branch</strong> with:</p><pre><code class="language-text-x-trilium-auto">git clone -b main https://github.com/triliumnext/notes.git</code></pre>
<h2>Installation</h2><pre><code class="language-text-x-trilium-auto">cd trilium
# download all node dependencies

View File

@ -3,10 +3,10 @@
<h2>Steps</h2>
<ul>
<li>SSH into your server</li>
<li>use <code>wget</code> (or <code>curl</code>) to download latest <code>TriliumNextNotes-Server-[VERSION]-linux-x64.tar.xz</code> (copy
<li>use <code>wget</code> (or <code>curl</code>) to download latest <code>TriliumNotes-Server-[VERSION]-linux-x64.tar.xz</code> (copy
link from <a href="https://github.com/TriliumNext/Notes/releases">release page</a>,
notice <code>-Server</code> suffix) on your server.</li>
<li>unpack the archive, e.g. using <code>tar -xf -d TriliumNextNotes-Server-[VERSION]-linux-x64.tar.xz</code>
<li>unpack the archive, e.g. using <code>tar -xf -d TriliumNotes-Server-[VERSION]-linux-x64.tar.xz</code>
</li>
<li><code>cd trilium-linux-x64-server</code>
</li>
@ -27,7 +27,7 @@
<h2>Configure Trilium to auto-run on boot with systemd</h2>
<ul>
<li>After downloading, extract and move Trilium:</li>
</ul><pre><code class="language-text-x-trilium-auto">tar -xvf TriliumNextNotes-Server-[VERSION]-linux-x64.tar.xz
</ul><pre><code class="language-text-x-trilium-auto">tar -xvf TriliumNotes-Server-[VERSION]-linux-x64.tar.xz
sudo mv trilium-linux-x64-server /opt/trilium</code></pre>
<ul>
<li>Create the service:</li>

View File

@ -153,13 +153,13 @@ class="table">
</td>
</tr>
<tr>
<td><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/iPIMuisry3hd/_help_gLt3vA97tMcp">Premium features</a>
<td><a class="reference-link" href="#root/_help_gLt3vA97tMcp">Premium features</a>
</td>
<td>
<ul>
<li><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/iPIMuisry3hd/gLt3vA97tMcp/_help_ZlN4nump6EbW">Slash Commands</a>
<li><a class="reference-link" href="#root/_help_ZlN4nump6EbW">Slash Commands</a>
</li>
<li><a class="reference-link" href="#root/pOsGYCXsbNQG/tC7s2alapj8V/_help_KC1HB96bqqHX">Templates</a>
<li><a class="reference-link" href="#root/_help_KC1HB96bqqHX">Templates</a>
</li>
</ul>
</td>
@ -167,6 +167,7 @@ class="table">
</tbody>
</table>
</figure>
<h2>Read-Only vs. Editing Mode</h2>
<p>Text notes are usually opened in edit mode. However, they may open in
read-only mode if the note is too big or the note is explicitly marked

View File

@ -62,17 +62,4 @@ class="image image-style-align-center">
are currently no plans for adjusting it or allowing the user to customize
them.</p>
<h3>Markdown support</h3>
<p>The Markdown syntax for admonitions as supported by Trilium is the one
that GitHub uses, which is as follows:</p><pre><code class="language-text-x-trilium-auto">&gt; [!NOTE]
&gt; This is a note.
&gt; [!TIP]
&gt; This is a tip.
&gt; [!IMPORTANT]
&gt; This is a very important information.
&gt; [!CAUTION]
&gt; This is a caution.</code></pre>
<p>There are currently no plans of supporting alternative admonition syntaxes
such as <code>!!! note</code>.</p>
<p>See&nbsp;<a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/mHbBMPDPkVV5/Oau6X9rCuegd/_help_rJ9grSgoExl9">Supported syntax</a>.</p>

View File

@ -1,4 +1,4 @@
<p>The text editor we are using for <a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_iPIMuisry3hd">Text</a> notes
<p>The text editor we are using for&nbsp;<a class="reference-link" href="#root/_help_iPIMuisry3hd">Text</a>&nbsp;notes
is called CKEditor and it's a commercial product. The core components are
open-source, however they <a href="https://ckeditor.com/docs/trial/latest/index.html">offer quite a few features</a> that
require a commercial license in order to be used.</p>
@ -6,12 +6,13 @@
in order to have some of these extra features and they have agreed, based
on a signed agreement.</p>
<h2>How the license works</h2>
<p>The license key is stored in the application and it enables the use of
the previously described premium features. The license key has an expiration
date which means that the features can become disabled if using an older
version of the application for extended periods of time.</p>
<h2>Can I opt out of these features?</h2>
<p>At this moment there is no way to disable this features, apart from manually
modifying the source code. If this is a problem, <a href="#root/pOsGYCXsbNQG/BgmBlOIl72jZ/_help_wy8So3yZZlH9">let us know</a>.</p>
<p>At this moment there is no way to disable these features, apart from manually
modifying the source code. If this is a problem, <a href="#root/_help_wy8So3yZZlH9">let us know</a>.</p>
<p>If you have the possibility of rebuilding the source code (e.g. if a package
maintainer), then modify <code>VITE_CKEDITOR_KEY</code> in <code>apps/client/.env</code> to
be <code>GPL</code>.</p>

View File

@ -1,18 +1,18 @@
<figure class="image image-style-align-right">
<img style="aspect-ratio:419/571" src="Slash Commands_image.png" width="419"
height="571" />
<img style="aspect-ratio:419/571;" src="Slash Commands_image.png" width="419"
height="571">
</figure>
<aside class="admonition note">
<p>This is a premium feature of the editor we are using (CKEditor) and we
benefit from it thanks to an written agreement with the team. See  <a class="reference-link"
href="#root/_help_gLt3vA97tMcp">Premium features</a> for more information.</p>
benefit from it thanks to an written agreement with the team. See&nbsp;
<a
class="reference-link" href="#root/_help_gLt3vA97tMcp">Premium features</a>&nbsp;for more information.</p>
</aside>
<p>Slash commands is a feature of <a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_iPIMuisry3hd">Text</a> notes
<p>Slash commands is a feature of&nbsp;<a class="reference-link" href="#root/_help_iPIMuisry3hd">Text</a>&nbsp;notes
which allows easily accessing commonly used commands simply by using the
keyboard, without having to remember dedicated <a class="reference-link"
href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/_help_A9Oc6YKKc65v">Keyboard Shortcuts</a>.</p>
keyboard, without having to remember dedicated&nbsp;<a class="reference-link"
href="#root/_help_A9Oc6YKKc65v">Keyboard Shortcuts</a>.</p>
<h2>Interaction</h2>
<ul>
<li>As the name suggests, to trigger the slash commands simply press the <kbd>/</kbd> key
to trigger it. Note that this can be anywhere in a paragraph as long as
@ -24,12 +24,11 @@
<li>To trigger an action, press the <kbd>Enter</kbd> key.</li>
</ul>
<h2>Integration with other features</h2>
<p>Apart from the common set of commands, some features are specially integrated
with the slash commands:</p>
<ul>
<li>For <a href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/iPIMuisry3hd/_help_NwBbFdNZ9h7O">admonitions</a>,
each admonition type (e.g. note, tip) will be individually displayed.</li>
<li>Every <a class="reference-link" href="#root/_help_pwc194wlRzcH">Text Snippets</a> will
<li>For <a href="#root/_help_NwBbFdNZ9h7O">admonitions</a>, each admonition
type (e.g. note, tip) will be individually displayed.</li>
<li>Every&nbsp;<a class="reference-link" href="#root/_help_pwc194wlRzcH">Text Snippets</a>&nbsp;will
also appear individually, making it easy to insert them.</li>
</ul>

View File

@ -1,18 +1,18 @@
<figure class="image image-style-align-right">
<img style="aspect-ratio:265/108" src="Text Snippets_image.png" width="265"
height="108" />
<img style="aspect-ratio:265/108;" src="Text Snippets_image.png" width="265"
height="108">
</figure>
<aside class="admonition note">
<p>This is a premium feature of the editor we are using (CKEditor) and we
benefit from it thanks to an written agreement with the team. See  <a class="reference-link"
href="#root/_help_gLt3vA97tMcp">Premium features</a> for more information.</p>
benefit from it thanks to an written agreement with the team. See&nbsp;
<a
class="reference-link" href="#root/_help_gLt3vA97tMcp">Premium features</a>&nbsp;for more information.</p>
</aside>
<p>Text Snippets are closely related to <a class="reference-link" href="#root/pOsGYCXsbNQG/tC7s2alapj8V/_help_KC1HB96bqqHX">Templates</a>,
<p>Text Snippets are closely related to&nbsp;<a class="reference-link" href="#root/_help_KC1HB96bqqHX">Templates</a>,
but instead of defining the content of an entire note, text snippets are
pieces of formatted text that can easily be inserted in a text note.</p>
<h2>Creating a text snippet</h2>
<p>In the <a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/Vc8PjrjAGuOp/_help_oPVyFC7WL2Lp">Note Tree</a>:</p>
<p>In the&nbsp;<a class="reference-link" href="#root/_help_oPVyFC7WL2Lp">Note Tree</a>:</p>
<ol>
<li>Right click a note where to place the text snippet.</li>
<li>Select <em>Insert child note</em>.</li>
@ -21,16 +21,14 @@
<p>Afterwards, simply type in the content of the note the desired text. The
text can be formatted in the same manner as a normal text note.</p>
<p>The title of the note will become the title of the template. Optionally,
a description can be added in the <a class="reference-link" href="#root/pOsGYCXsbNQG/tC7s2alapj8V/zEY4DaJG4YT5/_help_OFXdgB2nNk1F">Promoted Attributes</a> section.</p>
a description can be added in the&nbsp;<a class="reference-link" href="#root/_help_OFXdgB2nNk1F">Promoted Attributes</a>&nbsp;section.</p>
<h2>Inserting a snippet</h2>
<p>Once a snippet is created, there are two options to insert it:</p>
<ol>
<li>From the <a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/iPIMuisry3hd/_help_nRhnJkTT8cPs">Formatting toolbar</a>,
<li>From the&nbsp;<a class="reference-link" href="#root/_help_nRhnJkTT8cPs">Formatting toolbar</a>,
by looking for the
<img src="1_Text Snippets_image.png" width="19" height="19"
/>button.</li>
<li>Using <a class="reference-link" href="#root/_help_ZlN4nump6EbW">Slash Commands</a>:
<img src="1_Text Snippets_image.png" width="19" height="19">button.</li>
<li>Using&nbsp;<a class="reference-link" href="#root/_help_ZlN4nump6EbW">Slash Commands</a>:
<ol>
<li>To look for a specific template, start typing the name of the template
(its title).</li>
@ -41,16 +39,15 @@
<aside class="admonition tip">
<p>A newly created snippet doesn't appear? Generally it takes up to a few
seconds to refresh the list of templates once you make a change.</p>
<p>If this doesn't happen, <a href="#root/pOsGYCXsbNQG/BgmBlOIl72jZ/_help_s8alTXmpFR61">reload the application</a> and
<p>If this doesn't happen, <a href="#root/_help_s8alTXmpFR61">reload the application</a> and
<a
href="#root/pOsGYCXsbNQG/BgmBlOIl72jZ/_help_wy8So3yZZlH9">report the issue</a>to us. </p>
href="#root/_help_wy8So3yZZlH9">report the issue</a>to us.&nbsp;</p>
</aside>
<h2>Limitations</h2>
<ul>
<li>Whenever a snippet is created, deleted or its title/description are modified,
all the open text notes will need to be refreshed. This causes a slight
flash for usually under a second, but it can cause some discomfort.</li>
<li>Unlike <a class="reference-link" href="#root/pOsGYCXsbNQG/tC7s2alapj8V/_help_KC1HB96bqqHX">Templates</a>,
the snippets cannot be limited to a particular <a href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/wArbEsdSae6g/_help_9sRHySam5fXb">workspace</a>.</li>
<li>Unlike&nbsp;<a class="reference-link" href="#root/_help_KC1HB96bqqHX">Templates</a>,
the snippets cannot be limited to a particular <a href="#root/_help_9sRHySam5fXb">workspace</a>.</li>
</ul>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg enable-background="new 0 0 256 256" version="1.1" viewBox="0 0 256 256" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<title>TriliumNext Notes</title>
<title>Trilium Notes</title>
<path fill="black" d="m232.6 27.598c-17.706 0.092041-40.298 3.7127-58.258 10.104-1.7959 0.63909-3.5465 1.3043-5.2402 1.998-3.1 1.2-6.0988 2.6016-8.7988 4.1016-2.2 1.2-4.3016 2.4988-6.1016 3.7988-21.6 15.5-27.9 44.2-28.6 65.4l14.9-10.5 14.301-10 51.199-35.9-49.1 39.301-14.1 11.299-14.801 11.801c20.4 6.5 52.4 9.7992 74.9-6.3008 3.1886-2.319 6.4708-5.1162 9.7559-8.459 0.14708-0.08175 0.29689-0.1571 0.44336-0.24023 2.3386-2.3386 4.7705-4.8714 7.0215-7.5898 0.02928-0.033868 0.05864-0.065681 0.08789-0.099609 0.0964-0.038723 0.1948-0.072111 0.29102-0.11133 14.544-16.737 27.833-39.152 32.252-55.658 0.67979-2.5395 1.1487-4.9387 1.3809-7.1562 0.11607-1.1088 0.17422-2.173 0.16797-3.1855-1.0438-0.3625-2.1849-0.68557-3.4121-0.9707-1.2272-0.28513-2.542-0.53096-3.9336-0.74024s-2.8595-0.38069-4.3965-0.51562c-3.0739-0.26987-6.4198-0.39341-9.9609-0.375zm-202.79 20.252c-11.737-0.05-22.113 1.4004-28.312 4.6504 0.9 5.6625 4.3309 13.419 9.3125 21.77v0.001953c3.3209 5.5664 7.332 11.395 11.74 17.043v0.001953c6.6127 8.4716 14.122 16.534 21.547 22.684 2.3 1.9 4.5008 3.5996 6.8008 5.0996 0.048555 0.0124 0.097907 0.019 0.14648 0.03125 1.7845 1.2837 3.569 2.2777 5.3535 3.1699 20.8 10.4 45.5 3.7984 62.1-4.1016l-14.301-7.2988-13.6-6.9004-48.127-24.607 49.928 21.707 14.5 6.3008 15.199 6.5996c-3.4-18.3-14.099-44-35.799-54.9-3.3-1.6-6.9004-3.1004-10.9-4.4004-2.9-0.9-5.8996-1.7-9.0996-2.5-11.65-2.75-24.751-4.2996-36.488-4.3496zm97.488 73.85 3.6992 13.9 3.5996 13.201 12.801 47.6-15.9-47-4.5-13.4-4.8008-14.199c-10.3 13.4-21.3 36.199-15.5 57.199 0.8747 3.11 2.1333 6.3182 3.6719 9.709 0.01066 0.06374 0.01836 0.12769 0.0293 0.19141 1.1 2.5 2.3988 5.0992 3.7988 7.6992 10.4 18.8 27.701 38.501 39.701 42.801 0.00763-0.00936 0.01581-0.01991 0.02344-0.0293 0.02502 0.00909 0.05119 0.02035 0.07617 0.0293 8.8-10.8 16.8-42.601 15.9-65.701-0.1-2.7-0.30117-5.2992-0.70117-7.6992-0.3-1.9-0.69922-3.8-1.1992-5.5-5.6-20.2-25.199-32.601-40.699-38.801z"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg enable-background="new 0 0 256 256" version="1.1" viewBox="0 0 256 256" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<title>TriliumNext Notes</title>
<title>Trilium Notes</title>
<style type="text/css">
.st0{fill:#95C980;}
.st1{fill:#72B755;}

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg enable-background="new 0 0 256 256" version="1.1" viewBox="0 0 256 256" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<title>TriliumNext Notes</title>
<title>Trilium Notes</title>
<g>
<path d="m202.9 112.7c-22.5 16.1-54.5 12.8-74.9 6.3l14.8-11.8 14.1-11.3 49.1-39.3-51.2 35.9-14.3 10-14.9 10.5c0.7-21.2 7-49.9 28.6-65.4 1.8-1.3 3.9-2.6 6.1-3.8 2.7-1.5 5.7-2.9 8.8-4.1 27.1-11.1 68.5-15.3 85.2-9.5 0.1 16.2-15.9 45.4-33.9 65.9-2.4 2.8-4.9 5.4-7.4 7.8-3.4 3.5-6.8 6.4-10.1 8.8z" fill="#ab60e3"/>
<path d="m213.1 104c-22.2 12.6-51.4 9.3-70.3 3.2l14.1-11.3 49.1-39.3-51.2 35.9-14.3 10c0.5-18.1 4.9-42.1 19.7-58.6 2.7-1.5 5.7-2.9 8.8-4.1 27.1-11.1 68.5-15.3 85.2-9.5 0.1 16.2-15.9 45.4-33.9 65.9-2.3 2.8-4.8 5.4-7.2 7.8z" fill="#8038b8"/>

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg enable-background="new 0 0 256 256" version="1.1" viewBox="0 0 256 256" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<title>TriliumNext Notes</title>
<title>Trilium Notes</title>
<path fill="white" d="m232.6 27.598c-17.706 0.092041-40.298 3.7127-58.258 10.104-1.7959 0.63909-3.5465 1.3043-5.2402 1.998-3.1 1.2-6.0988 2.6016-8.7988 4.1016-2.2 1.2-4.3016 2.4988-6.1016 3.7988-21.6 15.5-27.9 44.2-28.6 65.4l14.9-10.5 14.301-10 51.199-35.9-49.1 39.301-14.1 11.299-14.801 11.801c20.4 6.5 52.4 9.7992 74.9-6.3008 3.1886-2.319 6.4708-5.1162 9.7559-8.459 0.14708-0.08175 0.29689-0.1571 0.44336-0.24023 2.3386-2.3386 4.7705-4.8714 7.0215-7.5898 0.02928-0.033868 0.05864-0.065681 0.08789-0.099609 0.0964-0.038723 0.1948-0.072111 0.29102-0.11133 14.544-16.737 27.833-39.152 32.252-55.658 0.67979-2.5395 1.1487-4.9387 1.3809-7.1562 0.11607-1.1088 0.17422-2.173 0.16797-3.1855-1.0438-0.3625-2.1849-0.68557-3.4121-0.9707-1.2272-0.28513-2.542-0.53096-3.9336-0.74024s-2.8595-0.38069-4.3965-0.51562c-3.0739-0.26987-6.4198-0.39341-9.9609-0.375zm-202.79 20.252c-11.737-0.05-22.113 1.4004-28.312 4.6504 0.9 5.6625 4.3309 13.419 9.3125 21.77v0.001953c3.3209 5.5664 7.332 11.395 11.74 17.043v0.001953c6.6127 8.4716 14.122 16.534 21.547 22.684 2.3 1.9 4.5008 3.5996 6.8008 5.0996 0.048555 0.0124 0.097907 0.019 0.14648 0.03125 1.7845 1.2837 3.569 2.2777 5.3535 3.1699 20.8 10.4 45.5 3.7984 62.1-4.1016l-14.301-7.2988-13.6-6.9004-48.127-24.607 49.928 21.707 14.5 6.3008 15.199 6.5996c-3.4-18.3-14.099-44-35.799-54.9-3.3-1.6-6.9004-3.1004-10.9-4.4004-2.9-0.9-5.8996-1.7-9.0996-2.5-11.65-2.75-24.751-4.2996-36.488-4.3496zm97.488 73.85 3.6992 13.9 3.5996 13.201 12.801 47.6-15.9-47-4.5-13.4-4.8008-14.199c-10.3 13.4-21.3 36.199-15.5 57.199 0.8747 3.11 2.1333 6.3182 3.6719 9.709 0.01066 0.06374 0.01836 0.12769 0.0293 0.19141 1.1 2.5 2.3988 5.0992 3.7988 7.6992 10.4 18.8 27.701 38.501 39.701 42.801 0.00763-0.00936 0.01581-0.01991 0.02344-0.0293 0.02502 0.00909 0.05119 0.02035 0.07617 0.0293 8.8-10.8 16.8-42.601 15.9-65.701-0.1-2.7-0.30117-5.2992-0.70117-7.6992-0.3-1.9-0.69922-3.8-1.1992-5.5-5.6-20.2-25.199-32.601-40.699-38.801z"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,6 +1,6 @@
# TriliumNext Base System Prompt
# Trilium Base System Prompt
You are an AI assistant integrated into TriliumNext Notes, a powerful note-taking application that helps users build personal knowledge bases with features like:
You are an AI assistant integrated into Trilium Notes, a powerful note-taking application that helps users build personal knowledge bases with features like:
- Hierarchical note organization with support for placing notes in multiple locations
- Rich text editing with WYSIWYG and Markdown support
- Code notes with syntax highlighting
@ -10,9 +10,9 @@ You are an AI assistant integrated into TriliumNext Notes, a powerful note-takin
- Relation maps for visualizing connections between notes
- Synchronization between devices
Your primary goal is to help users find information in their notes, answer questions based on their knowledge base, and provide assistance with using TriliumNext Notes features. Be sure to summarize the notes and include the title of the notes when providing a summary.
Your primary goal is to help users find information in their notes, answer questions based on their knowledge base, and provide assistance with using Trilium Notes features. Be sure to summarize the notes and include the title of the notes when providing a summary.
IMPORTANT: When working with notes in TriliumNext:
IMPORTANT: When working with notes in Trilium:
- Each note has a unique system ID (e.g., "abc123def456") which is different from its title
- When tools require a noteId parameter, always use the system ID, not the title
- Always use search tools first to find notes and get their IDs before performing operations on them

View File

@ -1,5 +1,5 @@
```
In this environment you have access to a set of tools that help you interact with TriliumNext Notes, a hierarchical note-taking application for building personal knowledge bases. You can use these tools to search notes, navigate the note hierarchy, analyze queries, and provide thoughtful responses based on the user's knowledge base.
In this environment you have access to a set of tools that help you interact with Trilium Notes, a hierarchical note-taking application for building personal knowledge bases. You can use these tools to search notes, navigate the note hierarchy, analyze queries, and provide thoughtful responses based on the user's knowledge base.
You can invoke tools by writing an "<function_calls>" block like the following as part of your reply to the user:
<function_calls>
@ -16,7 +16,7 @@ String and scalar parameters should be specified as is, while lists and objects
[TOOL_DEFINITIONS]
You are an AI assistant integrated into TriliumNext Notes, a powerful note-taking application that helps users build personal knowledge bases with features like:
You are an AI assistant integrated into Trilium Notes, a powerful note-taking application that helps users build personal knowledge bases with features like:
- Hierarchical note organization with support for placing notes in multiple locations
- Rich text editing with WYSIWYG and Markdown support
- Code notes with syntax highlighting
@ -26,7 +26,7 @@ You are an AI assistant integrated into TriliumNext Notes, a powerful note-takin
- Relation maps for visualizing connections between notes
- Synchronization between devices
Your primary goal is to help users find information in their notes, answer questions based on their knowledge base, and provide assistance with using TriliumNext Notes features.
Your primary goal is to help users find information in their notes, answer questions based on their knowledge base, and provide assistance with using Trilium Notes features.
When responding to queries:
1. For complex queries, decompose them into simpler parts and address each one

View File

@ -1,5 +1,5 @@
```
In this environment you have access to a set of tools that help you interact with TriliumNext Notes, a hierarchical note-taking application for building personal knowledge bases. You can use these tools to search notes, navigate the note hierarchy, analyze queries, and provide thoughtful responses based on the user's knowledge base.
In this environment you have access to a set of tools that help you interact with Trilium Notes, a hierarchical note-taking application for building personal knowledge bases. You can use these tools to search notes, navigate the note hierarchy, analyze queries, and provide thoughtful responses based on the user's knowledge base.
You can invoke tools by writing a JSON object with the following format:
{
@ -12,7 +12,7 @@ You can invoke tools by writing a JSON object with the following format:
[TOOL_DEFINITIONS]
You are an AI assistant integrated into TriliumNext Notes, a powerful note-taking application that helps users build personal knowledge bases with features like:
You are an AI assistant integrated into Trilium Notes, a powerful note-taking application that helps users build personal knowledge bases with features like:
- Hierarchical note organization with support for placing notes in multiple locations
- Rich text editing with WYSIWYG and Markdown support
- Code notes with syntax highlighting
@ -22,7 +22,7 @@ You are an AI assistant integrated into TriliumNext Notes, a powerful note-takin
- Relation maps for visualizing connections between notes
- Synchronization between devices
Your primary goal is to help users find information in their notes, answer questions based on their knowledge base, and provide assistance with using TriliumNext Notes features.
Your primary goal is to help users find information in their notes, answer questions based on their knowledge base, and provide assistance with using Trilium Notes features.
When responding to queries:
1. For complex queries, decompose them into simpler parts and address each one

View File

@ -1,5 +1,5 @@
```
In this environment you have access to a set of tools that help you interact with TriliumNext Notes, a hierarchical note-taking application for building personal knowledge bases. You can use these tools to search notes, navigate the note hierarchy, analyze queries, and provide thoughtful responses based on the user's knowledge base.
In this environment you have access to a set of tools that help you interact with Trilium Notes, a hierarchical note-taking application for building personal knowledge bases. You can use these tools to search notes, navigate the note hierarchy, analyze queries, and provide thoughtful responses based on the user's knowledge base.
You can invoke tools by writing an "<tool_calls>" block like the following as part of your reply to the user:
<tool_calls>
@ -20,7 +20,7 @@ String and scalar parameters should be specified as is, while lists and objects
[TOOL_DEFINITIONS]
You are an AI assistant integrated into TriliumNext Notes, a powerful note-taking application that helps users build personal knowledge bases with features like:
You are an AI assistant integrated into Trilium Notes, a powerful note-taking application that helps users build personal knowledge bases with features like:
- Hierarchical note organization with support for placing notes in multiple locations
- Rich text editing with WYSIWYG and Markdown support
- Code notes with syntax highlighting
@ -30,7 +30,7 @@ You are an AI assistant integrated into TriliumNext Notes, a powerful note-takin
- Relation maps for visualizing connections between notes
- Synchronization between devices
Your primary goal is to help users find information in their notes, answer questions based on their knowledge base, and provide assistance with using TriliumNext Notes features.
Your primary goal is to help users find information in their notes, answer questions based on their knowledge base, and provide assistance with using Trilium Notes features.
When responding to queries:
1. For complex queries, decompose them into simpler parts and address each one

File diff suppressed because one or more lines are too long

View File

@ -109,7 +109,7 @@
},
"javascript-required": "Trilium erfordert, dass JavaScript aktiviert ist.",
"setup": {
"heading": "TriliumNext Notes Setup",
"heading": "Trilium Notes Setup",
"new-document": "Ich bin ein neuer Benutzer und möchte ein neues Trilium-Dokument für meine Notizen erstellen",
"sync-from-desktop": "Ich habe bereits eine Desktop-Instanz und möchte die Synchronisierung damit einrichten",
"sync-from-server": "Ich habe bereits eine Server-Instanz und möchte die Synchronisierung damit einrichten",
@ -121,7 +121,7 @@
"setup_sync-from-desktop": {
"heading": "Synchronisation vom Desktop",
"description": "Dieses Setup muss von der Desktop-Instanz aus initiiert werden:",
"step1": "Öffne deine TriliumNext Notes Desktop-Instanz.",
"step1": "Öffne deine Trilium Notes Desktop-Instanz.",
"step2": "Klicke im Trilium-Menü auf Optionen.",
"step3": "Klicke auf die Kategorie Synchronisation.",
"step4": "Ändere die Server-Instanzadresse auf: {{- host}} und klicke auf Speichern.",
@ -256,7 +256,7 @@
"unable-to-save-message": "Die ausgewählte Datei konnte nicht beschrieben werden. Erneut versuchen oder ein anderes Ziel auswählen."
},
"tray": {
"tooltip": "TriliumNext Notes",
"tooltip": "Trilium Notes",
"close": "Trilium schließen",
"recents": "Kürzliche Notizen",
"bookmarks": "Lesezeichen",

View File

@ -124,7 +124,7 @@
},
"javascript-required": "Trilium requires JavaScript to be enabled.",
"setup": {
"heading": "TriliumNext Notes setup",
"heading": "Trilium Notes setup",
"new-document": "I'm a new user, and I want to create a new Trilium document for my notes",
"sync-from-desktop": "I have a desktop instance already, and I want to set up sync with it",
"sync-from-server": "I have a server instance already, and I want to set up sync with it",
@ -136,7 +136,7 @@
"setup_sync-from-desktop": {
"heading": "Sync from Desktop",
"description": "This setup needs to be initiated from the desktop instance:",
"step1": "Open your desktop instance of TriliumNext Notes.",
"step1": "Open your desktop instance of Trilium Notes.",
"step2": "From the Trilium Menu, click Options.",
"step3": "Click on Sync category.",
"step4": "Change server instance address to: {{- host}} and click Save.",
@ -278,7 +278,7 @@
"unable-to-save-message": "The selected file could not be written to. Try again or select another destination."
},
"tray": {
"tooltip": "TriliumNext Notes",
"tooltip": "Trilium Notes",
"close": "Quit Trilium",
"recents": "Recent notes",
"bookmarks": "Bookmarks",

View File

@ -1,12 +1,18 @@
{
"keyboard_actions": {
"back-in-note-history": "Navegar a la nota previa en el historial",
"forward-in-note-history": "Navegar a la nota siguiente en el historial",
"open-jump-to-note-dialog": "Abrir cuadro de diálogo \"Saltar a nota\"",
"scroll-to-active-note": "Desplazarse a la nota activa en el árbol de notas",
"quick-search": "Activar barra de búisqueda rápida",
"search-in-subtree": "Buscar notas en el subárbol de la nota activa",
"expand-subtree": "Expandir el subárbol de la nota actual",
"collapse-tree": "Colapsa el árbol de notas completo",
"collapse-subtree": "Colapsa el subárbol de la nota actual",
"sort-child-notes": "Ordenar subnotas",
"creating-and-moving-notes": "Creando y moviendo notas",
"create-note-after": "Crear nota después de la nota activa",
"create-note-into": "Crear nota como subnota de la nota activa",
"create-note-into-inbox": "Crear una nota en la bandeja de entrada (si está definida) o nota del día",
"delete-note": "Eliminar nota",
"move-note-up": "Mover nota hacia arriba",
@ -15,6 +21,8 @@
"move-note-down-in-hierarchy": "Mover nota hacia abajo en la jerarquía",
"edit-note-title": "Saltar del árbol al detalle de la nota y editar el título",
"edit-branch-prefix": "Mostrar cuadro de diálogo Editar prefijo de rama",
"cloneNotesTo": "Clonar notas seleccionadas",
"moveNotesTo": "Mover notas seleccionadas",
"note-clipboard": "Portapapeles de notas",
"copy-notes-to-clipboard": "Copiar las notas seleccionadas al portapapeles",
"paste-notes-from-clipboard": "Pegar las notas del portapapeles en una nota activa",
@ -48,6 +56,8 @@
"show-recent-changes": "Muestra el cuadro de diálogo Cambios recientes",
"show-sql-console": "Muestra el cuadro de diálogo Consola SQL",
"show-backend-log": "Muestra el cuadro de diálogo Registro de backend",
"show-help": "Muestra ayuda/hoja de referencia integrada",
"show-cheatsheet": "Muestra un modal con operaciones de teclado comunes",
"text-note-operations": "Operaciones de notas de texto",
"add-link-to-text": "Abrir cuadro de diálogo para agregar un enlace al texto",
"follow-link-under-cursor": "Seguir el enlace dentro del cual se coloca el cursor",
@ -80,6 +90,7 @@
"unhoist": "Bajar desde cualquier lugar",
"reload-frontend-app": "Recargar frontend de la aplicación",
"open-dev-tools": "Abrir herramientas de desarrollo",
"find-in-text": "Alternar panel de búsqueda",
"toggle-left-note-tree-panel": "Alternar panel izquierdo (árbol de notas)",
"toggle-full-screen": "Alternar pantalla completa",
"zoom-out": "Alejar",
@ -88,20 +99,20 @@
"reset-zoom-level": "Restablecer nivel de zoom",
"copy-without-formatting": "Copiar el texto seleccionado sin formatear",
"force-save-revision": "Forzar la creación/guardado de una nueva revisión de nota de la nota activa",
"show-help": "Muestra ayuda/hoja de referencia integrada",
"toggle-book-properties": "Alternar propiedades del libro",
"toggle-classic-editor-toolbar": "Alternar la pestaña de formato por el editor con barra de herramientas fija",
"export-as-pdf": "Exporta la nota actual como un PDF",
"show-cheatsheet": "Muestra un modal con operaciones de teclado comunes",
"toggle-zen-mode": "Habilita/Deshabilita el modo Zen (IU mínima para edición sin distracciones)"
},
"login": {
"title": "Iniciar sesión",
"heading": "Iniciar sesión en Trilium",
"incorrect-totp": "El TOTP es incorrecto. Por favor, intente de nuevo.",
"incorrect-password": "La contraseña es incorrecta. Por favor inténtalo de nuevo.",
"password": "Contraseña",
"remember-me": "Recordarme",
"button": "Iniciar sesión"
"button": "Iniciar sesión",
"sign_in_with_sso": "Iniciar sesión con {{ ssoIssuerName }}"
},
"set_password": {
"title": "Establecer contraseña",
@ -113,7 +124,7 @@
},
"javascript-required": "Trilium requiere que JavaScript esté habilitado.",
"setup": {
"heading": "Configuración de TriliumNext Notes",
"heading": "Configuración de Trilium Notes",
"new-document": "Soy un usuario nuevo y quiero crear un nuevo documento de Trilium para mis notas",
"sync-from-desktop": "Ya tengo una instancia de escritorio y quiero configurar la sincronización con ella",
"sync-from-server": "Ya tengo una instancia de servidor y quiero configurar la sincronización con ella",
@ -125,7 +136,7 @@
"setup_sync-from-desktop": {
"heading": "Sincronizar desde el escritorio",
"description": "Esta configuración debe iniciarse desde la instancia de escritorio:",
"step1": "Abra su instancia de escritorio de TriliumNext Notes.",
"step1": "Abra su instancia de escritorio de Trilium Notes.",
"step2": "En el menú Trilium, dé clic en Opciones.",
"step3": "Dé clic en la categoría Sincronizar.",
"step4": "Cambie la dirección de la instancia del servidor a: {{- host}} y dé clic en Guardar.",
@ -172,6 +183,7 @@
"saturday": "Sábado",
"sunday": "Domingo"
},
"weekdayNumber": "Semana {weekNumber}",
"months": {
"january": "Enero",
"february": "Febrero",
@ -186,6 +198,7 @@
"november": "Noviembre",
"december": "Diciembre"
},
"quarterNumber": "Cuarto {quarterNumber}",
"special_notes": {
"search_prefix": "Buscar:"
},
@ -225,6 +238,7 @@
"protected-session-title": "Sesión protegida",
"sync-status-title": "Sincronizar estado",
"settings-title": "Ajustes",
"llm-chat-title": "Chat con notas",
"options-title": "Opciones",
"appearance-title": "Apariencia",
"shortcuts-title": "Atajos",
@ -233,14 +247,17 @@
"images-title": "Imágenes",
"spellcheck-title": "Corrección ortográfica",
"password-title": "Contraseña",
"multi-factor-authentication-title": "MFA",
"etapi-title": "ETAPI",
"backup-title": "Respaldo",
"sync-title": "Sincronizar",
"ai-llm-title": "IA/LLM",
"other": "Otros",
"advanced-title": "Avanzado",
"visible-launchers-title": "Lanzadores visibles",
"user-guide": "Guía de Usuario",
"localization": "Idioma y Región"
"localization": "Idioma y Región",
"inbox-title": "Bandeja"
},
"notes": {
"new-note": "Nueva nota",
@ -261,13 +278,14 @@
"unable-to-save-message": "No se pudo escribir en el archivo seleccionado. Intente de nuevo o seleccione otro destino."
},
"tray": {
"tooltip": "TriliumNext Notes",
"tooltip": "Trilium Notes",
"close": "Cerrar Trilium",
"recents": "Notas recientes",
"bookmarks": "Marcadores",
"today": "Abrir nota del diario de hoy",
"new-note": "Nueva nota",
"show-windows": "Mostrar ventanas"
"show-windows": "Mostrar ventanas",
"open_new_window": "Abrir nueva ventana"
},
"migration": {
"old_version": "La migración directa desde tu versión actual no está soportada. Por favor actualice a v0.60.4 primero y solo después a esta versión.",
@ -276,5 +294,14 @@
},
"modals": {
"error_title": "Error"
},
"share_theme": {
"site-theme": "Tema de sitio",
"search_placeholder": "Búsqueda...",
"image_alt": "Imagen de artículo",
"last-updated": "Última actualización en {{-date}}",
"subpages": "Subpáginas:",
"on-this-page": "En esta página",
"expand": "Expandir"
}
}

View File

@ -113,7 +113,7 @@
},
"javascript-required": "Trilium nécessite que JavaScript soit activé.",
"setup": {
"heading": "Configuration de TriliumNext Notes",
"heading": "Configuration de Trilium Notes",
"new-document": "Je suis un nouvel utilisateur et je souhaite créer un nouveau document Trilium pour mes notes",
"sync-from-desktop": "J'ai déjà l'application de bureau et je souhaite configurer la synchronisation avec celle-ci",
"sync-from-server": "J'ai déjà un serveur et je souhaite configurer la synchronisation avec celui-ci",
@ -125,7 +125,7 @@
"setup_sync-from-desktop": {
"heading": "Synchroniser depuis une application de bureau",
"description": "Cette procédure doit être réalisée depuis l'application de bureau installée sur votre ordinateur:",
"step1": "Ouvrez l'application TriliumNext Notes.",
"step1": "Ouvrez l'application Trilium Notes.",
"step2": "Dans le menu Trilium, cliquez sur Options.",
"step3": "Cliquez sur la catégorie Synchroniser.",
"step4": "Remplacez l'adresse de l'instance de serveur par : {{- host}} et cliquez sur Enregistrer.",
@ -260,7 +260,7 @@
"unable-to-save-message": "Le fichier sélectionné n'a pas pu être écrit. Réessayez ou sélectionnez une autre destination."
},
"tray": {
"tooltip": "TriliumNext Notes",
"tooltip": "Trilium Notes",
"close": "Quitter Trilium",
"recents": "Notes récentes",
"bookmarks": "Signets",

View File

@ -110,7 +110,7 @@
},
"javascript-required": "Trilium precisa que JavaScript esteja habilitado.",
"setup": {
"heading": "TriliumNext Notes setup",
"heading": "Trilium Notes setup",
"new-document": "Sou um novo usuário e quero criar um novo documento Trilium para minhas notas",
"sync-from-desktop": "Já tenho uma instância no desktop e quero configurar a sincronização com ela",
"sync-from-server": "Já tenho uma instância no servidor e quero configurar a sincronização com ela",
@ -122,7 +122,7 @@
"setup_sync-from-desktop": {
"heading": "Sincronizar com Desktop",
"description": "Esta configuração deve ser iniciada a partir da instância do desktop:",
"step1": "Abra sua instância do TriliumNext Notes no desktop.",
"step1": "Abra sua instância do Trilium Notes no desktop.",
"step2": "No menu do Trilium, clique em Opções.",
"step3": "Clique na categoria Sincronização.",
"step4": "Altere o endereço da instância do servidor para: {{- host}} e clique em Salvar.",

View File

@ -113,7 +113,7 @@
},
"javascript-required": "Trilium necesită JavaScript să fie activat pentru a putea funcționa.",
"setup": {
"heading": "Instalarea TriliumNext Notes",
"heading": "Instalarea Trilium Notes",
"init-in-progress": "Se inițializează documentul",
"new-document": "Sunt un utilizator nou și doresc să creez un document Trilium pentru notițele mele",
"next": "Mai departe",
@ -125,7 +125,7 @@
"setup_sync-from-desktop": {
"description": "Acești pași trebuie urmați de pe aplicația de desktop:",
"heading": "Sincronizare cu aplicația desktop",
"step1": "Deschideți aplicația TriliumNext Notes pentru desktop.",
"step1": "Deschideți aplicația Trilium Notes pentru desktop.",
"step2": "Din meniul Trilium, dați clic pe Opțiuni.",
"step3": "Clic pe categoria „Sincronizare”.",
"step4": "Schimbați adresa server-ului către: {{- host}} și apăsați „Salvează”.",
@ -266,7 +266,7 @@
"new-note": "Notiță nouă",
"recents": "Notițe recente",
"today": "Mergi la notița de astăzi",
"tooltip": "TriliumNext Notes",
"tooltip": "Trilium Notes",
"show-windows": "Afișează ferestrele"
},
"migration": {

View File

@ -7,7 +7,7 @@
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover" />
<link rel="manifest" crossorigin="use-credentials" href="manifest.webmanifest">
<title>TriliumNext Notes</title>
<title>Trilium Notes</title>
</head>
<body class="desktop heading-style-<%= headingStyle %> layout-<%= layoutOrientation %> platform-<%= platform %> <%= isElectron ? 'electron' : '' %> <%= hasNativeTitleBar ? 'native-titlebar' : '' %> <%= hasBackgroundEffects ? 'background-effects' : '' %>">
<noscript><%= t("javascript-required") %></noscript>

View File

@ -7,7 +7,7 @@
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, interactive-widget=resizes-content" />
<meta name="theme-color" content="#fff">
<title>TriliumNext Notes</title>
<title>Trilium Notes</title>
<link rel="manifest" crossorigin="use-credentials" href="manifest.webmanifest">
<style>

View File

@ -85,6 +85,8 @@ const ALLOWED_OPTIONS = new Set<OptionNames>([
"languages",
"textNoteEditorType",
"textNoteEditorMultilineToolbar",
"textNoteEmojiCompletionEnabled",
"textNoteCompletionEnabled",
"layoutOrientation",
"backgroundEffects",
"allowedHtmlTags",

View File

@ -36,6 +36,17 @@ import type Becca from "../becca/becca-interface.js";
import type { NoteParams } from "./note-interface.js";
import type { ApiParams } from "./backend_script_api_interface.js";
// Dayjs plugins
import isSameOrBefore from "dayjs/plugin/isSameOrBefore";
import isSameOrAfter from "dayjs/plugin/isSameOrAfter";
import isBetween from "dayjs/plugin/isBetween";
import advancedFormat from "dayjs/plugin/advancedFormat.js";
dayjs.extend(isSameOrBefore);
dayjs.extend(isSameOrAfter);
dayjs.extend(isBetween);
dayjs.extend(advancedFormat);
/**
* A whole number
* @typedef {number} int

View File

@ -283,7 +283,19 @@ $$`;
it("supports wikilink with root-relative path", () => {
const input = `oh no my banana I bought on [[journal/monday]] has gone off! Im taking it back to the [[other/shop]] for a refund`;
const expected = `<p>oh no my banana I bought on <a class="reference-link" href="journal/monday">journal/monday</a> has gone off! Im taking it back to the <a class="reference-link" href="other/shop">other/shop</a> for a refund</p>`;
const expected = `<p>oh no my banana I bought on <a class="reference-link" href="/journal/monday">journal/monday</a> has gone off! Im taking it back to the <a class="reference-link" href="/other/shop">other/shop</a> for a refund</p>`;
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
});
it("supports wikilink in lists", () => {
const input = `- oh no my banana I bought on [[journal/monday]] has gone off! Im taking it back to the [[other/shop]] for a refund`;
const expected = `<ul><li>oh no my banana I bought on <a class="reference-link" href="/journal/monday">journal/monday</a> has gone off! Im taking it back to the <a class="reference-link" href="/other/shop">other/shop</a> for a refund</li></ul>`;
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
});
it("supports wikilink with image (transclusion)", () => {
const input = `heres the handsome boy ![[assets/2025-06-20_14-05-20.jpeg]]`;
const expected = `<p>heres the handsome boy <img src="/assets/2025-06-20_14-05-20.jpeg"></p>`;
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
});

View File

@ -1,12 +1,14 @@
"use strict";
import { parse, Renderer, type Tokens } from "marked";
import { parse, Renderer, use, type Tokens } from "marked";
import htmlSanitizer from "../html_sanitizer.js";
import importUtils from "./utils.js";
import { getMimeTypeFromMarkdownName, MIME_TYPE_AUTO } from "@triliumnext/commons";
import { ADMONITION_TYPE_MAPPINGS } from "../export/markdown.js";
import utils from "../utils.js";
import { normalizeMimeTypeForCKEditor } from "@triliumnext/commons";
import wikiLinkTransclusion from "./markdown/wikilink_transclusion.js";
import wikiLinkInternalLink from "./markdown/wikilink_internal_link.js";
/**
* Keep renderer code up to date with https://github.com/markedjs/marked/blob/master/src/Renderer.ts.
@ -23,9 +25,7 @@ class CustomMarkdownRenderer extends Renderer {
}
override paragraph(data: Tokens.Paragraph): string {
let text = super.paragraph(data).trimEnd();
text = processWikiLinks(text);
return text;
return super.paragraph(data).trimEnd();
}
override code({ text, lang }: Tokens.Code): string {
@ -126,6 +126,14 @@ function renderToHtml(content: string, title: string) {
// Extract formulas and replace them with placeholders to prevent interference from Markdown rendering
const { processedText, placeholderMap: formulaMap } = extractFormulas(content);
use({
// Order is important, especially for wikilinks.
extensions: [
wikiLinkTransclusion,
wikiLinkInternalLink
]
});
let html = parse(processedText, {
async: false,
renderer: renderer
@ -214,11 +222,6 @@ function restoreFromMap(text: string, map: Map<string, string>): string {
return text.replace(new RegExp(pattern, 'g'), match => map.get(match) ?? match);
}
function processWikiLinks(paragraph: string) {
paragraph = paragraph.replaceAll(/\[\[([^\[\]]+)\]\]/g, `<a class="reference-link" href="$1">$1</a>`);
return paragraph;
}
const renderer = new CustomMarkdownRenderer({ async: false });
export default {

View File

@ -0,0 +1,29 @@
import { TokenizerAndRendererExtension } from "marked";
const wikiLinkInternalLink: TokenizerAndRendererExtension = {
name: "wikilinkInternalLink",
level: "inline",
start(src: string) {
return src.indexOf('[[');
},
tokenizer(src) {
const match = /^\[\[([^\]]+?)\]\]/.exec(src);
if (match) {
return {
type: 'wikilinkInternalLink',
raw: match[0],
text: match[1].trim(), // what shows as link text
href: match[1].trim()
};
}
},
renderer(token) {
return `<a class="reference-link" href="/${token.href}">${token.text}</a>`;
}
}
export default wikiLinkInternalLink;

View File

@ -0,0 +1,30 @@
import type { TokenizerAndRendererExtension } from "marked";
/**
* The terminology is inspired by https://silverbullet.md/Transclusions.
*/
const wikiLinkTransclusion: TokenizerAndRendererExtension = {
name: "wikiLinkTransclusion",
level: "inline",
start(src: string) {
return src.match(/!\[\[/)?.index;
},
tokenizer(src) {
const match = /^!\[\[([^\]]+?)\]\]/.exec(src);
if (match) {
return {
type: "wikiLinkTransclusion",
raw: match[0],
href: match[1].trim(),
};
}
},
renderer(token) {
return `<img src="/${token.href}">`;
}
};
export default wikiLinkTransclusion;

View File

@ -60,7 +60,28 @@ describe("processNoteContent", () => {
const htmlNote = rootNote.children.find((ch) => ch.title === "IREN Reports Q2 FY25 Results");
expect(htmlNote?.getContent().toString().substring(0, 4)).toEqual("<div");
});
it("can import from Silverbullet", async () => {
const { importedNote } = await testImport("silverbullet.zip");
const bananaNote = getNoteByTitlePath(importedNote, "assets", "banana.jpeg");
const mondayNote = getNoteByTitlePath(importedNote, "journal", "monday");
const shopNote = getNoteByTitlePath(importedNote, "other", "shop");
const content = mondayNote?.getContent();
expect(content).toContain(`<a class="reference-link" href="#root/${shopNote.noteId}`);
expect(content).toContain(`<img src="api/images/${bananaNote!.noteId}/banana.jpeg`);
});
});
function getNoteByTitlePath(parentNote: BNote, ...titlePath: string[]) {
let cursor = parentNote;
for (const title of titlePath) {
const childNote = cursor.getChildNotes().find(n => n.title === title);
expect(childNote).toBeTruthy();
cursor = childNote!;
}
return cursor;
}
describe("removeTriliumTags", () => {
it("removes <h1> tags from HTML", () => {

View File

@ -41,6 +41,7 @@ async function importZip(taskContext: TaskContext, fileBuffer: Buffer, importRoo
const createdPaths: Record<string, string> = { "/": importRootNote.noteId, "\\": importRootNote.noteId };
let metaFile: MetaFile | null = null;
let firstNote: BNote | null = null;
let topLevelPath = "";
const createdNoteIds = new Set<string>();
function getNewNoteId(origNoteId: string) {
@ -257,16 +258,17 @@ async function importZip(taskContext: TaskContext, fileBuffer: Buffer, importRoo
saveAttributes(note, noteMeta);
firstNote = firstNote || note;
return noteId;
}
function getEntityIdFromRelativeUrl(url: string, filePath: string) {
let absUrl: string;
if (!url.startsWith("/")) {
while (url.startsWith("./")) {
url = url.substr(2);
}
let absUrl = path.dirname(filePath);
absUrl = path.dirname(filePath);
while (url.startsWith("../")) {
absUrl = path.dirname(absUrl);
@ -279,6 +281,11 @@ async function importZip(taskContext: TaskContext, fileBuffer: Buffer, importRoo
}
absUrl += `${absUrl.length > 0 ? "/" : ""}${url}`;
} else {
absUrl = topLevelPath + url;
}
console.log(url, "-->", absUrl);
const { noteMeta, attachmentMeta } = getMeta(absUrl);
@ -330,7 +337,7 @@ async function importZip(taskContext: TaskContext, fileBuffer: Buffer, importRoo
return `src="${url}"`;
}
if (isUrlAbsolute(url) || url.startsWith("/")) {
if (isUrlAbsolute(url)) {
return match;
}
@ -527,20 +534,28 @@ async function importZip(taskContext: TaskContext, fileBuffer: Buffer, importRoo
}
}
// we're running two passes to make sure that the meta file is loaded before the rest of the files is processed.
// we're running two passes in order to obtain critical information first (meta file and root)
const topLevelItems = new Set<string>();
await readZipFile(fileBuffer, async (zipfile: yauzl.ZipFile, entry: yauzl.Entry) => {
const filePath = normalizeFilePath(entry.fileName);
// make sure that the meta file is loaded before the rest of the files is processed.
if (filePath === "!!!meta.json") {
const content = await readContent(zipfile, entry);
metaFile = JSON.parse(content.toString("utf-8"));
}
// determine the root of the .zip (i.e. if it has only one top-level folder then the root is that folder, or the root of the archive if there are multiple top-level folders).
const firstSlash = filePath.indexOf("/");
const topLevelPath = (firstSlash !== -1 ? filePath.substring(0, firstSlash) : filePath);
topLevelItems.add(topLevelPath);
zipfile.readEntry();
});
topLevelPath = (topLevelItems.size > 1 ? "" : topLevelItems.values().next().value ?? "");
await readZipFile(fileBuffer, async (zipfile: yauzl.ZipFile, entry: yauzl.Entry) => {
const filePath = normalizeFilePath(entry.fileName);

View File

@ -21,7 +21,7 @@ const loadSystemPrompt = (): string => {
} catch (error) {
console.error('Failed to load system prompt from file:', error);
// Return fallback prompt if file can't be loaded
return "You are a helpful assistant embedded in the TriliumNext Notes application. " +
return "You are a helpful assistant embedded in the Trilium Notes application. " +
"You can help users with their notes, answer questions, and provide information. " +
"Keep your responses concise and helpful. " +
"You're currently chatting with the user about their notes.";
@ -57,7 +57,7 @@ export const SYSTEM_PROMPTS = {
export const CONTEXT_PROMPTS = {
// Query enhancer prompt for generating better search terms
QUERY_ENHANCER:
`You are an AI assistant that decides what information needs to be retrieved from a user's knowledge base called TriliumNext Notes to answer the user's question.
`You are an AI assistant that decides what information needs to be retrieved from a user's knowledge base called Trilium Notes to answer the user's question.
Given the user's question, generate 3-5 specific search queries that would help find relevant information.
Each query should be focused on a different aspect of the question.
Avoid generating queries that are too broad, vague, or about a user's entire Note database, and make sure they are relevant to the user's question.
@ -210,7 +210,7 @@ When using tools to search for information, follow these requirements:
// OpenAI-specific prompt formatting
SYSTEM_WITH_CONTEXT: (context: string) =>
`<system_prompt>
You are an AI assistant integrated into TriliumNext Notes.
You are an AI assistant integrated into Trilium Notes.
Use the following information from the user's notes to answer their questions:
<user_notes>
@ -264,7 +264,7 @@ CRITICAL INSTRUCTIONS FOR TOOL USAGE:
// Common prompts across providers
COMMON: {
DEFAULT_ASSISTANT_INTRO: "<assistant_role>You are an AI assistant integrated into TriliumNext Notes. Focus on helping users find information in their notes and answering questions based on their knowledge base. Be concise, informative, and direct when responding to queries.</assistant_role>"
DEFAULT_ASSISTANT_INTRO: "<assistant_role>You are an AI assistant integrated into Trilium Notes. Focus on helping users find information in their notes and answering questions based on their knowledge base. Be concise, informative, and direct when responding to queries.</assistant_role>"
}
};

View File

@ -66,7 +66,7 @@ export class QueryProcessor {
// Check cache first
const cached = cacheManager.getQueryResults(`searchQueries:${userQuestion}`);
const PROMPT = `You are an AI assistant that decides what information needs to be retrieved from a user's knowledge base called TriliumNext Notes to answer the user's question.
const PROMPT = `You are an AI assistant that decides what information needs to be retrieved from a user's knowledge base called Trilium Notes to answer the user's question.
Given the user's question, generate 3-5 specific search queries that would help find relevant information.
Each query should be focused on a different aspect of the question.
Avoid generating queries that are too broad, vague, or about a user's entire Note database, and make sure they are relevant to the user's question.
@ -308,7 +308,7 @@ Example: ["exact topic mentioned", "related concept 1", "related concept 2"]`
): Promise<SubQuery[]> {
try {
// Use the proven prompt format that was working before
const prompt = `You are an AI assistant that decides what information needs to be retrieved from a user's knowledge base called TriliumNext Notes to answer the user's question.
const prompt = `You are an AI assistant that decides what information needs to be retrieved from a user's knowledge base called Trilium Notes to answer the user's question.
Given the user's question, generate 3-5 specific search queries that would help find relevant information.
Each query should be focused on a different aspect of the question.
Avoid generating queries that are too broad, vague, or about a user's entire Note database, and make sure they are relevant to the user's question.

View File

@ -178,6 +178,8 @@ const defaultOptions: DefaultOption[] = [
// Text note configuration
{ name: "textNoteEditorType", value: "ckeditor-balloon", isSynced: true },
{ name: "textNoteEditorMultilineToolbar", value: "false", isSynced: true },
{ name: "textNoteEmojiCompletionEnabled", value: "true", isSynced: true },
{ name: "textNoteCompletionEnabled", value: "true", isSynced: true },
// HTML import configuration
{ name: "layoutOrientation", value: "vertical", isSynced: false },

View File

@ -0,0 +1,114 @@
import becca from "../becca/becca.js";
import { note, NoteBuilder } from "../test/becca_mocking.js";
import cls from "./cls.js";
import { executeBundle, getScriptBundle } from "./script.js";
import BBranch from "../becca/entities/bbranch.js";
import BNote from "../becca/entities/bnote.js";
describe("Script", () => {
let rootNote!: NoteBuilder;
beforeEach(() => {
becca.reset();
rootNote = new NoteBuilder(
new BNote({
noteId: "root",
title: "root",
type: "text"
})
);
new BBranch({
branchId: "none_root",
noteId: "root",
parentNoteId: "none",
notePosition: 10
});
vi.mock("./sql.js", () => {
return {
default: {
transactional: (cb: Function) => {
cb();
},
execute: () => {},
replace: () => {},
getMap: () => {}
}
};
});
vi.mock("./sql_init.js", () => {
return {
dbReady: () => {
console.log("Hello world");
}
};
});
});
it("returns result from script", () => {
cls.init(() => {
const result = executeBundle({
script: `return "world";`,
html: "",
});
expect(result).toBe("world");
});
});
describe("dayjs", () => {
const scriptNote = note("dayjs", {
type: "code",
mime: "application/javascript;env=backend",
});
it("dayjs is available", () => {
cls.init(() => {
const bundle = getScriptBundle(scriptNote.note, true, "backend", [], `return api.dayjs().format("YYYY-MM-DD");`);
expect(bundle).toBeDefined();
const result = executeBundle(bundle!);
expect(result).toMatch(/^\d{4}-\d{2}-\d{2}$/);
});
});
it("dayjs is-same-or-before", () => {
cls.init(() => {
const bundle = getScriptBundle(scriptNote.note, true, "backend", [], `return api.dayjs("2023-10-01").isSameOrBefore(api.dayjs("2023-10-02"));`);
expect(bundle).toBeDefined();
const result = executeBundle(bundle!);
expect(result).toBe(true);
});
});
it("dayjs is-same-or-after", () => {
cls.init(() => {
const bundle = getScriptBundle(scriptNote.note, true, "backend", [], `return api.dayjs("2023-10-02").isSameOrAfter(api.dayjs("2023-10-01"));`);
expect(bundle).toBeDefined();
const result = executeBundle(bundle!);
expect(result).toBe(true);
});
});
it("dayjs is-between", () => {
cls.init(() => {
const bundle = getScriptBundle(scriptNote.note, true, "backend", [], `return api.dayjs("2023-10-02").isBetween(api.dayjs("2023-10-01"), api.dayjs("2023-10-03"));`);
expect(bundle).toBeDefined();
const result = executeBundle(bundle!);
expect(result).toBe(true);
});
});
// advanced format
it("dayjs advanced format", () => {
cls.init(() => {
const bundle = getScriptBundle(scriptNote.note, true, "backend", [], `return api.dayjs("2023-10-01").format("Q");`);
expect(bundle).toBeDefined();
const result = executeBundle(bundle!);
expect(result).not.toBe("Q");
});
});
});
});

View File

@ -39,7 +39,7 @@ function executeNoteNoException(note: BNote, apiParams: ApiParams) {
}
}
function executeBundle(bundle: Bundle, apiParams: ApiParams = {}) {
export function executeBundle(bundle: Bundle, apiParams: ApiParams = {}) {
if (!apiParams.startNote) {
// this is the default case, the only exception is when we want to preserve frontend startNote
apiParams.startNote = bundle.note;
@ -140,7 +140,7 @@ function getScriptBundleForFrontend(note: BNote, script?: string, params?: Scrip
return bundle;
}
function getScriptBundle(note: BNote, root: boolean = true, scriptEnv: string | null = null, includedNoteIds: string[] = [], overrideContent: string | null = null): Bundle | undefined {
export function getScriptBundle(note: BNote, root: boolean = true, scriptEnv: string | null = null, includedNoteIds: string[] = [], overrideContent: string | null = null): Bundle | undefined {
if (!note.isContentAvailable()) {
return;
}

View File

@ -45,7 +45,7 @@ async function createExtraWindow(extraWindowHash: string) {
const win = new BrowserWindow({
width: 1000,
height: 800,
title: "TriliumNext Notes",
title: "Trilium Notes",
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
@ -155,7 +155,7 @@ async function createMainWindow(app: App) {
height: mainWindowState.height,
minWidth: 500,
minHeight: 400,
title: "TriliumNext Notes",
title: "Trilium Notes",
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
@ -268,7 +268,7 @@ async function createSetupWindow() {
width,
height,
resizable: false,
title: "TriliumNext Notes Setup",
title: "Trilium Notes Setup",
icon: getIcon(),
webPreferences: {
// necessary for e.g. utils.isElectron()

View File

@ -117,11 +117,11 @@ export const downloadMatrix: DownloadMatrix = {
},
tarX64: {
name: "x86 (.tar.xz)",
url: `https://github.com/TriliumNext/Notes/releases/download/v${version}/TriliumNextNotes-Server-v${version}-linux-x64.tar.xz`
url: `https://github.com/TriliumNext/Notes/releases/download/v${version}/TriliumNotes-Server-v${version}-linux-x64.tar.xz`
},
tarArm64: {
name: "ARM (.tar.xz)",
url: `https://github.com/TriliumNext/Notes/releases/download/v${version}/TriliumNextNotes-Server-v${version}-linux-arm64.tar.xz`
url: `https://github.com/TriliumNext/Notes/releases/download/v${version}/TriliumNotes-Server-v${version}-linux-arm64.tar.xz`
},
nixos: {
name: "NixOS module",
@ -150,7 +150,7 @@ export const downloadMatrix: DownloadMatrix = {
export function buildDownloadUrl(app: App, platform: Platform, format: string, architecture: Architecture): string {
if (app === "desktop") {
return downloadMatrix.desktop[platform]?.downloads[format].url ??
`https://github.com/TriliumNext/Notes/releases/download/v${version}/TriliumNextNotes-v${version}-${platform}-${architecture}.${format}`;
`https://github.com/TriliumNext/Notes/releases/download/v${version}/TriliumNotes-v${version}-${platform}-${architecture}.${format}`;
} else if (app === "server") {
return downloadMatrix.server[platform]?.downloads[format].url ?? "#";
} else {

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg enable-background="new 0 0 256 256" version="1.1" viewBox="0 0 256 256" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<title>TriliumNext Notes</title>
<title>Trilium Notes</title>
<style type="text/css">
.st0{fill:#95C980;}
.st1{fill:#72B755;}

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -18,7 +18,7 @@ The key-based approach allows a hierarchical structure. For example, a key of `a
```json
{
"about": {
"title": "About TriliumNext Notes"
"title": "About Trilium Notes"
}
}
```

View File

@ -4,7 +4,7 @@ On Ubuntu:
```
#!/usr/bin/env bash
name=TriliumNextNotes-linux-x64-nightly.deb
name=TriliumNotes-linux-x64-nightly.deb
rm -f $name*
wget https://github.com/TriliumNext/Notes/releases/download/nightly/$name
sudo apt-get install ./$name

View File

@ -1,8 +1,8 @@
# TriliumNext Notes
# Trilium Notes
[English](../README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md)
TriliumNext Notes 是一个层次化的笔记应用程序,专注于建立大型个人知识库。请参阅[屏幕截图](https://triliumnext.github.io/Docs/Wiki/screenshot-tour)以快速了解:
Trilium Notes 是一个层次化的笔记应用程序,专注于建立大型个人知识库。请参阅[屏幕截图](https://triliumnext.github.io/Docs/Wiki/screenshot-tour)以快速了解:
<a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="./app.png" alt="Trilium Screenshot" width="1000"></a>

6
docs/README.es.md vendored
View File

@ -1,8 +1,8 @@
# TriliumNext Notes
# Trilium Notes
[English](../README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md)
TriliumNext Notes es una aplicación de toma de notas jerárquicas multi-plataforma y de código libre con un enfoque en la construcción de grandes bases de conocimiento personal.
Trilium Notes es una aplicación de toma de notas jerárquicas multi-plataforma y de código libre con un enfoque en la construcción de grandes bases de conocimiento personal.
Vea estas [capturas de pantalla](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) para un vistazo rápido:
@ -92,7 +92,7 @@ npm run server:start
## 👏 Reconocimientos
- [CKEditor 5](https://github.com/ckeditor/ckeditor5) - el mejor editor WYSIWYG en el mercado, equipo muy interactivo y atento
- [FancyTree](https://github.com/mar10/fancytree) - biblioteca de árbol muy rica en funciones sin competencia real. TriliumNext Notes no sería lo mismo sin esta.
- [FancyTree](https://github.com/mar10/fancytree) - biblioteca de árbol muy rica en funciones sin competencia real. Trilium Notes no sería lo mismo sin esta.
- [CodeMirror](https://github.com/codemirror/CodeMirror) - editor de código con soporte para una gran cantidad de lenguajes
- [jsPlumb](https://github.com/jsplumb/jsplumb) - biblioteca de conectividad visual sin competencia. Usado en [mapas de relación](https://triliumnext.github.io/Docs/Wiki/Relation-map) y [mapas de enlace](https://triliumnext.github.io/Docs/Wiki/Link-map)

4
docs/README.it.md vendored
View File

@ -1,8 +1,8 @@
# TriliumNext Notes
# Trilium Notes
[English](../README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md)
TriliumNext Notes è un'applicazione per appunti ad organizzazione gerarchica, studiata per la costruzione di archivi di conoscenza personali di grandi dimensioni.
Trilium Notes è un'applicazione per appunti ad organizzazione gerarchica, studiata per la costruzione di archivi di conoscenza personali di grandi dimensioni.
Vedi [fotografie](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) per una panoramica veloce:

2
docs/README.ja.md vendored
View File

@ -1,4 +1,4 @@
# TriliumNext Notes
# Trilium Notes
[English](../README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md)

Some files were not shown because too many files have changed in this diff Show More