Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/release-plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ jobs:
with:
subject-path: |
dist/main.js
dist/manifest.json
dist/styles.css

- name: Create release
Expand Down
3 changes: 2 additions & 1 deletion .oxlintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@
"eslint/radix": "off",
"unicorn/import-style": "off",
"unicorn/no-process-exit": "off",
"eslint/one-var": ["warn", "never"]
"eslint/one-var": ["warn", "never"],
"unicorn/max-nested-calls": ["warn", { "max": 5 }]
},
"env": {
"builtin": true,
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ This is the monorepo for an extensible Obsidian syncing plugin to sync vault fil
- Excluding main plugin, shared utils and documentation site, all packages are Sync Engine modules, they use the SDK and follow unified module structure.
- `null` forbidden, use `undefined` consistently.
- Lint warnings must be cleared, except time-bounded ones (TODO with date, deprecated API for compat)
- SDK types (`**/*.d.ts` in `packages/plugin/dist/`) are committed to satisfy Obsidian automated linting. You must not touch these types.
- SDK types (`**/*.d.ts` in `packages/plugin/dist/`) are committed to satisfy Obsidian automated linting. Never edit, delete, restore, clean, or otherwise alter these files, even when builds or checks create uncommitted changes. Leave their existing worktree state unchanged.

## Documentation

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ If not all your devices have WebDAV Sync updated to 2.5.12 or later, you can go

Sync Engine is a revolutionary solution for vault syncing. Its not only a syncing plugin, it is a modular platform that everyone can build upon.

The core ships the infrastructure, and all backends (WebDAV, S3, GDrive) and features (i18n, optimization, sync strategy) come from composable modules. You and your AI agents can build your own modules via convenient SDK, extend the plugin, contribute to community, all without modifying the source code.
The core ships the infrastructure, and all backends (WebDAV, S3, GDrive) and features (i18n, optimization, sync strategy) come from composable modules. You can build your own modules via convenient SDK, extend the plugin, contribute to community, all without modifying the source code.

Access Sync Engine documentation at [`sync.consensia.cc`](https://sync.consensia.cc), which contains usage guides, existing modules, permission claims, benchmarking, and documentation on how to build a module.

Expand Down Expand Up @@ -104,7 +104,7 @@ Sync Engine fits the gap: you want to choose your own storage, you want the plug
## Usage

1. Download and enable `Sync Engine` from Obsidian plugin store.
2. Open "Module management" panel, install needed translations, backends and optional features.
2. Open "Module management" setting, install needed translations, backends and optional features.
3. Fill the necessary information about your cloud service in the settings interface.
4. Start your first sync from command palette or ribbon button.
5. Review the sync tasks that will be performed.
Expand Down
4 changes: 2 additions & 2 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ const localeConfig = configGenerator<ThemeConfig>((t) => {
items: [
{ link: `${deepDive}/file-tree`, text: t('fileTree') },
{
link: `${deepDive}/module-management-panel`,
text: t('moduleManagementPanel'),
link: `${deepDive}/module-management-page`,
text: t('moduleManagementPage'),
},
],
text: t('userInterface'),
Expand Down
2 changes: 1 addition & 1 deletion docs/.vitepress/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const en = {
'All content licensed under the <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a> License.',
migrateFromV2: 'Migrate from V2',
miscellaneous: 'Miscellaneous',
moduleManagementPanel: 'Module Management Panel',
moduleManagementPage: 'Module Management Page',
modules: 'Modules',
nativeName: 'English',
permissions: 'Permissions',
Expand Down
2 changes: 1 addition & 1 deletion docs/src/pages/en/deep-dive/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ The dependency direction is intentionally visible in the constructors. For examp

External modules extend this same context at runtime. `Extensibility` verifies and imports an approved constructor, adds it to SynthKernel, merges its `moduleSettings`, and adds it to `allModules` so it participates in startup and disposal. Unloading invokes `dispose()`, removes the constructor, and dispatches `moduleUnloaded`.

The module loader is also a security boundary because modules are executable code. Trust, integrity verification, enablement, storage, and runtime privileges are specified in the [Extensibility Contract](./extensibility); module-management UI behavior is covered in [Module Management UI](./module-management-panel).
The module loader is also a security boundary because modules are executable code. Trust, integrity verification, enablement, storage, and runtime privileges are specified in the [Extensibility Contract](./extensibility); module-management UI behavior is covered in [Module Management UI](./module-management-page).

## Registration Pattern

Expand Down
4 changes: 2 additions & 2 deletions docs/src/pages/en/deep-dive/extensibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ The loader guards against:

Module source URLs are stored in `settings.moduleSources`. The default source is `https://sync.consensia.cc/modules.json`, this is the official source hosted on GitHub pages, fully transparent.

Sync Engine officially hosts an alternative source `https://github.com/hesprs/sync-engine/raw/refs/heads/gh-pages/modules-alternative.json`. This source is identical to the main source except replaced all `sync.consensia.cc` to `hesprs.github.io/sync-engine`. Use this source when your firewall flags `sync.consensia.cc` as unsafe.
Sync Engine officially hosts an alternative source `https://raw.githubusercontent.com/hesprs/sync-engine/refs/heads/gh-pages/modules-alternative.json`. This source is identical to the main source except replaced all `sync.consensia.cc` to `hesprs.github.io/sync-engine`. Use this source when your firewall flags `sync.consensia.cc` as unsafe.

::: warning

Please avoid using two sources simultaneously, if you have decided to use `https://github.com/hesprs/sync-engine/raw/refs/heads/gh-pages/modules-alternative.json`, delete `https://sync.consensia.cc/modules.json` in the sources list.
Please avoid using two sources simultaneously, if you have decided to use `https://raw.githubusercontent.com/hesprs/sync-engine/refs/heads/gh-pages/modules-alternative.json`, delete `https://sync.consensia.cc/modules.json` in the sources list.

:::

Expand Down
2 changes: 1 addition & 1 deletion docs/src/pages/en/development/develop-a-module.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ So simply run `bun dev`, and your module will be rebuilt inside the right folder

After rebuilding, you need to reload the module in module management UI to apply latest changes. Or you can use the [Hot Reload](https://github.com/pjeby/hot-reload) plugin to reload Sync Engine on each build, so your module will also be reloaded.

To reliably reload Sync Engine modules without triggering its integrity protection, you need to manually disable integrity verification in the module editor interface in [module management panel](../deep-dive/module-management-panel). Make sure you only disable the verification of the module you are developing, see [Security](../usage/security) for security implications.
To reliably reload Sync Engine modules without triggering its integrity protection, you need to manually disable integrity verification in the module editor interface in [module management page](../deep-dive/module-management-page). Make sure you only disable the verification of the module you are developing, see [Security](../usage/security) for security implications.

## Load CSS in a Module

Expand Down
2 changes: 1 addition & 1 deletion docs/src/pages/en/usage/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ If you need a more transparent migration process to see what is going on around
1. Go into Obsidian, use WebDAV Sync to sync all your devices to ensure they have aligned copies of your data. If it shows the migration prompt, choose "cancel" directly.
2. Disable and delete WebDAV Sync on every devices.
3. Install Sync Engine from Obsidian plugin store.
4. Install the `WebDAV` module from the module management panel in Sync Engine settings, configure your account on every devices.
4. Install the `WebDAV` module from the module management page in Sync Engine settings, configure your account on every devices.
5. If you previously **enabled encryption**, please download the Encryption module and configure the encryption password. The manually delete the remote base directory on your WebDAV management UI. Choose one of your devices with better internet connection to sync your encrypted full vault to the remote.
6. If you are not using encryption previously, **go to Sync Engine settings and disable "Asymmetric storage", you do not need to delete any data anywhere.**
7. Perform sync on all other devices, Sync Engine should scan the remote folder and picks up the aligned state, populates its internal records only and shows "Already synced".
2 changes: 1 addition & 1 deletion docs/src/pages/en/usage/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ import ModuleCards from '@/components/ModuleCards.vue';

Below shows all currently available modules, the recommended way is to download them in the plugin module management UI. You can also download the JavaScript binaries here.

The official module source is `https://sync.consensia.cc/modules.json`. If your machine fails to fetch this module source (often due to aggressive firewall), you can try adding `https://github.com/hesprs/sync-engine/raw/refs/heads/gh-pages/modules-alternative.json` (and delete the original one) to your module sources. This source is the official alternative using GitHub's domain.
The official module source is `https://sync.consensia.cc/modules.json`. If your machine fails to fetch this module source (often due to aggressive firewall), you can try adding `https://raw.githubusercontent.com/hesprs/sync-engine/refs/heads/gh-pages/modules-alternative.json` (and delete the original one) to your module sources. This source is the official alternative using GitHub's domain.

<ModuleCards />
2 changes: 1 addition & 1 deletion docs/src/pages/en/usage/permissions.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Sync Engine only makes network requests for the two purposes below:

Requests made for syncing purpose only happen during sync runs.

Module sources are fetched only when automatic module update starts or user opens the module management panel. Sync Engine only fetches module sources defined in the "Module sources" setting. Modules are only downloaded when the user manually downloads a module or during module auto update.
Module sources are fetched only when automatic module update starts or user opens the module management page. Sync Engine only fetches module sources defined in the "Module sources" setting. Modules are only downloaded when the user manually downloads a module or during module auto update.

The only default module source is `https://sync.consensia.cc/modules.json`, `sync.consensia.cc` is hosted on GitHub pages, whose source code is 100% transparent and verifiable in Sync Engine GitHub repository.

Expand Down
4 changes: 2 additions & 2 deletions docs/src/pages/en/usage/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ Choose the installed module that connects Sync Engine to your storage service. T

### Module Management

Open the module management panel. From there, you can install, update, enable, disable, remove, or edit modules, and manage their update sources. Modules provide storage backends and extra sync strategies. Review [Security](./security) before installing modules from sources you do not control.
Open the module management page. From there, you can install, update, enable, disable, remove, or edit modules, and manage their update sources. Modules provide storage backends and extra sync strategies. Review [Security](./security) before installing modules from sources you do not control.

The [module management panel](../deep-dive/module-management-panel) consists of a top bar and the module card list. You can select to show installed only and edit module sources at the hamburger button beside the search bar.
The [module management page](../deep-dive/module-management-page) consists of a top bar and the module card list. You can select to show installed only and edit module sources at the hamburger button beside the search bar.

### Auto-Update Modules

Expand Down
2 changes: 1 addition & 1 deletion docs/src/pages/en/usage/why-sync-engine.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Sync Engine core offers necessary features to ensure the extensibility and perfo
It is simple to start using Sync Engine:

1. Download and enable `Sync Engine` from Obsidian plugin store.
2. Open "Module management" panel, install needed translations, backends and optional features.
2. Open "Module management" page, install needed translations, backends and optional features.
3. Fill the necessary information about your cloud service in the settings interface.
4. Start your first sync from command palette or ribbon button.
5. Review the sync tasks that will be performed.
Expand Down
4 changes: 2 additions & 2 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"id": "sync-engine",
"name": "Sync Engine",
"version": "3.0.6",
"minAppVersion": "1.12.3",
"version": "3.1.0",
"minAppVersion": "1.13.0",
"authorUrl": "https://hesprs.github.io",
"description": "The next-generation syncing plugin: Fast · Free · Extend with Modules. Supports WebDAV and S3.",
"author": "Hēsperus",
Expand Down
8 changes: 4 additions & 4 deletions modules.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"description": "WebDAV backend support.",
"icon": "server",
"main": "https://sync.consensia.cc/modules/webdav.js",
"minPluginVersion": "3.0.0"
"minPluginVersion": "3.1.0"
},
{
"id": "s3",
Expand All @@ -15,7 +15,7 @@
"description": "S3 and S3-compatible backend support.",
"icon": "server",
"main": "https://sync.consensia.cc/modules/s3.js",
"minPluginVersion": "3.0.0"
"minPluginVersion": "3.1.0"
},
{
"id": "encryption",
Expand All @@ -24,7 +24,7 @@
"description": "Client-side encrypt vault files before uploading to backend.",
"icon": "key-round",
"main": "https://sync.consensia.cc/modules/encryption.js",
"minPluginVersion": "3.0.0"
"minPluginVersion": "3.1.0"
},
{
"id": "i18n-zh",
Expand Down Expand Up @@ -60,6 +60,6 @@
"description": "Smart merge conflict resolution strategy that applies recursive three-way merge.",
"icon": "combine",
"main": "https://sync.consensia.cc/modules/smart-merge.js",
"minPluginVersion": "3.0.0"
"minPluginVersion": "3.1.0"
}
]
2 changes: 1 addition & 1 deletion packages/encryption/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default class Encryption {
priority: 7919,
}),
registerSetting({
apply: (el) => encryptionSetting(el, this.ctx as Context, this.moduleSettings),
apply: encryptionSetting(this.ctx as Context, this.moduleSettings),
priority: 1355,
}),
);
Expand Down
66 changes: 41 additions & 25 deletions packages/encryption/src/setting.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import type { EncryptionSettings } from '@';
import type { Context, Fragment, MaybePromise, Translate } from '@hesprs/sync-engine-sdk';
import type {
CallableOrObjectTree,
Context,
Fragment,
MaybePromise,
Translate,
} from '@hesprs/sync-engine-sdk';
import type { App } from 'obsidian';
import { setNeedMigration } from '@hesprs/sync-engine-sdk';
import { SecretComponent, Setting } from 'obsidian';
import { s, setNeedMigration } from '@hesprs/sync-engine-sdk';
import { SecretComponent } from 'obsidian';

export type EncryptionTranslations = {
encryption: string;
Expand All @@ -11,35 +17,45 @@ export type EncryptionTranslations = {
};

export default function encryptionSetting(
el: HTMLElement,
ctx: {
translate: Translate<EncryptionTranslations>;
app: App;
saveSettings: () => Promise<void>;
recordStoreExists: () => MaybePromise<boolean>;
},
settings: EncryptionSettings,
) {
): CallableOrObjectTree {
const { translate, app, saveSettings, recordStoreExists } = ctx;

new Setting(el)
.setName(translate('encryption'))
.setDesc(translate('encryptionDescription'))
.addComponent((element) =>
new SecretComponent(app, element).setValue(settings.password).onChange((value) => {
settings.password = value;
void saveSettings();
}),
)
.addToggle((toggle) =>
setNeedMigration(ctx as Context, {
apply: (value) => {
settings.enabled = value;
void saveSettings();
return {
1000: {
6037: s(() => ({
desc: translate('encryptionDescription'),
name: translate('encryption'),
render: (setting) => {
setting
.setClass('sync-engine-togglable-value')
.addComponent((element) =>
new SecretComponent(app, element)
.setValue(settings.password)
.onChange((value) => {
settings.password = value;
void saveSettings();
}),
)
.addToggle((toggle) =>
setNeedMigration(ctx as Context, {
apply: (value) => {
settings.enabled = value;
void saveSettings();
},
content: (value) =>
translate('encryptionMigration', value ? 'enable' : 'disable'),
needMigration: recordStoreExists,
toggle: toggle.setValue(settings.enabled),
}),
);
},
content: (value) => translate('encryptionMigration', value ? 'enable' : 'disable'),
needMigration: recordStoreExists,
toggle: toggle.setValue(settings.enabled),
}),
);
})),
},
};
}
8 changes: 6 additions & 2 deletions packages/i18n/src/ru/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ const ru: Translations = {
'Sync Engine записывает состояния синхронизации для разрешения операций между локальными и удалёнными файлами. Эта опция позволяет выборочно очищать записи. Внимание: это действие может привести к потере данных.',
completed: 'Завершено',
completedNoop: 'Уже синхронизировано',
configurations: 'Конфигурации',
configure: 'Настроить',
confirm: 'Подтвердить',
confirmDeleteDescription:
Expand Down Expand Up @@ -220,6 +219,9 @@ const ru: Translations = {
moduleManagementDescription:
'Управление модулями в специальной панели. Вы можете устанавливать, удалять, обновлять, включать, отключать и редактировать модули, а также их источники.',
moduleSourcePlaceholder: 'https://example.com/modules.json',
moduleSources: 'Источники модулей',
moduleSourcesDescription:
'Редактируйте источники модулей, из которых формируется каталог. Это позволяет устанавливать сторонние модули Sync Engine.',
moveLocal: 'Переместить локальный файл',
moveRemote: 'Переместить удалённый файл',
name: 'Название',
Expand All @@ -233,7 +235,6 @@ const ru: Translations = {
'Отображать всплывающее уведомление на мобильных устройствах во время синхронизации. Заменяет строку состояния, используемую на ПК.',
official: 'Официальный',
omittedInvalidEntry: 'Пропущено недействительных записей: {{count}}.',
openPanel: 'Открыть панель',
realtimeSync: 'Синхронизация в реальном времени',
realtimeSyncDescription:
'Запускать синхронизацию автоматически сразу после изменения файлов. Измените задержку между изменением файла и запуском синхронизации в поле ниже.',
Expand All @@ -259,6 +260,8 @@ const ru: Translations = {
showInstalledOnly: 'Только установленные',
showProgress: 'Показывать прогресс',
skip: 'Пропустить',
someModulesHidden:
'Некоторые модули скрыты, поскольку плагин Sync Engine устарел. Обновите его, чтобы просмотреть полный каталог модулей.',
sourcesDescription:
'Добавьте URL-адреса источников модулей. Пустые и недействительные строки будут пропущены при сохранении.',
startMigration: 'Начать миграцию',
Expand Down Expand Up @@ -321,6 +324,7 @@ const ru: Translations = {
updateSourcePlaceholder: 'https://example.com/modules.json',
upload: 'Загрузить',
walkingRemote: 'Сканирование удалённых файлов',
xEnabled: 'Включено модулей: {{x}}',
};

export default ru;
Loading
Loading