synto 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- synto-0.1.0/.github/FUNDING.yml +6 -0
- synto-0.1.0/.github/workflows/benchmark.yml +41 -0
- synto-0.1.0/.github/workflows/ci.yml +38 -0
- synto-0.1.0/.github/workflows/release.yml +72 -0
- synto-0.1.0/.gitignore +32 -0
- synto-0.1.0/CLAUDE.md +83 -0
- synto-0.1.0/LICENSE +21 -0
- synto-0.1.0/PKG-INFO +190 -0
- synto-0.1.0/README.md +155 -0
- synto-0.1.0/RELEASE.md +38 -0
- synto-0.1.0/docs/img/setup.png +0 -0
- synto-0.1.0/docs/web-clipper-setup.md +76 -0
- synto-0.1.0/install.py +238 -0
- synto-0.1.0/pyproject.toml +71 -0
- synto-0.1.0/scripts/benchmark.sh +127 -0
- synto-0.1.0/scripts/compare_smoke.sh +356 -0
- synto-0.1.0/scripts/release.sh +44 -0
- synto-0.1.0/scripts/smoke_test.sh +1397 -0
- synto-0.1.0/src/synto/__init__.py +1 -0
- synto-0.1.0/src/synto/cli.py +2859 -0
- synto-0.1.0/src/synto/client_factory.py +70 -0
- synto-0.1.0/src/synto/compare/__init__.py +25 -0
- synto-0.1.0/src/synto/compare/metrics.py +215 -0
- synto-0.1.0/src/synto/compare/models.py +92 -0
- synto-0.1.0/src/synto/compare/report.py +180 -0
- synto-0.1.0/src/synto/compare/runner.py +510 -0
- synto-0.1.0/src/synto/config.py +301 -0
- synto-0.1.0/src/synto/engines.py +151 -0
- synto-0.1.0/src/synto/git_ops.py +115 -0
- synto-0.1.0/src/synto/global_config.py +86 -0
- synto-0.1.0/src/synto/indexer.py +272 -0
- synto-0.1.0/src/synto/markdown_math.py +110 -0
- synto-0.1.0/src/synto/metrics.py +193 -0
- synto-0.1.0/src/synto/models.py +409 -0
- synto-0.1.0/src/synto/ollama_client.py +179 -0
- synto-0.1.0/src/synto/openai_compat_client.py +482 -0
- synto-0.1.0/src/synto/pack_export.py +706 -0
- synto-0.1.0/src/synto/paths.py +61 -0
- synto-0.1.0/src/synto/pipeline/__init__.py +0 -0
- synto-0.1.0/src/synto/pipeline/compile.py +1526 -0
- synto-0.1.0/src/synto/pipeline/eval.py +241 -0
- synto-0.1.0/src/synto/pipeline/ingest.py +1172 -0
- synto-0.1.0/src/synto/pipeline/items.py +228 -0
- synto-0.1.0/src/synto/pipeline/lint.py +930 -0
- synto-0.1.0/src/synto/pipeline/lock.py +177 -0
- synto-0.1.0/src/synto/pipeline/maintain.py +359 -0
- synto-0.1.0/src/synto/pipeline/orchestrator.py +325 -0
- synto-0.1.0/src/synto/pipeline/query.py +786 -0
- synto-0.1.0/src/synto/pipeline/review.py +136 -0
- synto-0.1.0/src/synto/pricing.py +41 -0
- synto-0.1.0/src/synto/protocols.py +43 -0
- synto-0.1.0/src/synto/providers.py +79 -0
- synto-0.1.0/src/synto/readers.py +668 -0
- synto-0.1.0/src/synto/sanitize.py +45 -0
- synto-0.1.0/src/synto/schemas/index-v1.json +132 -0
- synto-0.1.0/src/synto/serve.py +231 -0
- synto-0.1.0/src/synto/state.py +2221 -0
- synto-0.1.0/src/synto/stats.py +293 -0
- synto-0.1.0/src/synto/structured_output.py +315 -0
- synto-0.1.0/src/synto/vault.py +332 -0
- synto-0.1.0/src/synto/watcher.py +131 -0
- synto-0.1.0/tests/compare_corpus/corpus.toml +100 -0
- synto-0.1.0/tests/compare_corpus/notes/ambiguous_entity.md +29 -0
- synto-0.1.0/tests/compare_corpus/notes/cross_reference.md +26 -0
- synto-0.1.0/tests/compare_corpus/notes/data_heavy_table.md +56 -0
- synto-0.1.0/tests/compare_corpus/notes/edge_empty_list.md +17 -0
- synto-0.1.0/tests/compare_corpus/notes/long_dense_technical.md +71 -0
- synto-0.1.0/tests/compare_corpus/notes/moderate_overlap.md +38 -0
- synto-0.1.0/tests/compare_corpus/notes/multi_concept_overlap.md +29 -0
- synto-0.1.0/tests/compare_corpus/notes/narrative_essay.md +19 -0
- synto-0.1.0/tests/compare_corpus/notes/noisy_low_quality.md +27 -0
- synto-0.1.0/tests/compare_corpus/notes/short_factual.md +11 -0
- synto-0.1.0/tests/compare_corpus/queries.toml +68 -0
- synto-0.1.0/tests/conftest.py +45 -0
- synto-0.1.0/tests/eval/__init__.py +1 -0
- synto-0.1.0/tests/eval/queries_default.toml +29 -0
- synto-0.1.0/tests/fixtures/analysis_valid.json +11 -0
- synto-0.1.0/tests/fixtures/compile_plan_valid.json +12 -0
- synto-0.1.0/tests/fixtures/single_article_valid.json +5 -0
- synto-0.1.0/tests/test_benchmarks.py +209 -0
- synto-0.1.0/tests/test_cli_compile.py +101 -0
- synto-0.1.0/tests/test_cli_messaging.py +99 -0
- synto-0.1.0/tests/test_cli_migrate_olw.py +328 -0
- synto-0.1.0/tests/test_cli_model_flags.py +47 -0
- synto-0.1.0/tests/test_cli_query.py +200 -0
- synto-0.1.0/tests/test_cli_reject.py +157 -0
- synto-0.1.0/tests/test_cli_status.py +56 -0
- synto-0.1.0/tests/test_cli_support.py +26 -0
- synto-0.1.0/tests/test_compare_cli.py +214 -0
- synto-0.1.0/tests/test_compare_metrics.py +167 -0
- synto-0.1.0/tests/test_compare_report.py +120 -0
- synto-0.1.0/tests/test_compare_runner.py +276 -0
- synto-0.1.0/tests/test_compare_safety.py +144 -0
- synto-0.1.0/tests/test_compile.py +573 -0
- synto-0.1.0/tests/test_compile_v2.py +1204 -0
- synto-0.1.0/tests/test_config.py +276 -0
- synto-0.1.0/tests/test_git_ops.py +105 -0
- synto-0.1.0/tests/test_indexer.py +94 -0
- synto-0.1.0/tests/test_ingest.py +1357 -0
- synto-0.1.0/tests/test_items.py +176 -0
- synto-0.1.0/tests/test_lint.py +926 -0
- synto-0.1.0/tests/test_lock.py +206 -0
- synto-0.1.0/tests/test_maintain.py +340 -0
- synto-0.1.0/tests/test_metrics.py +296 -0
- synto-0.1.0/tests/test_ollama_client.py +118 -0
- synto-0.1.0/tests/test_openai_compat_client.py +335 -0
- synto-0.1.0/tests/test_orchestrator.py +479 -0
- synto-0.1.0/tests/test_phase0_engines.py +62 -0
- synto-0.1.0/tests/test_phase0_migration_v8.py +307 -0
- synto-0.1.0/tests/test_phase0_readers.py +110 -0
- synto-0.1.0/tests/test_phase0_schemas.py +207 -0
- synto-0.1.0/tests/test_phase1a_capability_gating.py +158 -0
- synto-0.1.0/tests/test_phase1a_eval.py +254 -0
- synto-0.1.0/tests/test_phase1a_index_json.py +127 -0
- synto-0.1.0/tests/test_phase1a_metrics_cli.py +101 -0
- synto-0.1.0/tests/test_phase1a_metrics_persistence.py +142 -0
- synto-0.1.0/tests/test_phase1a_migration_v9.py +600 -0
- synto-0.1.0/tests/test_phase1a_pack_export.py +644 -0
- synto-0.1.0/tests/test_phase1a_pack_reader.py +207 -0
- synto-0.1.0/tests/test_phase1a_query_engine.py +130 -0
- synto-0.1.0/tests/test_phase1a_serve.py +232 -0
- synto-0.1.0/tests/test_phase1a_state.py +33 -0
- synto-0.1.0/tests/test_phase1a_stats.py +264 -0
- synto-0.1.0/tests/test_phase1a_vault_reader.py +431 -0
- synto-0.1.0/tests/test_pipeline_language.py +103 -0
- synto-0.1.0/tests/test_pipeline_reject_all.py +123 -0
- synto-0.1.0/tests/test_providers.py +756 -0
- synto-0.1.0/tests/test_query.py +317 -0
- synto-0.1.0/tests/test_query_git_behavior.py +79 -0
- synto-0.1.0/tests/test_query_synthesize.py +568 -0
- synto-0.1.0/tests/test_review.py +255 -0
- synto-0.1.0/tests/test_sanitize.py +117 -0
- synto-0.1.0/tests/test_setup.py +695 -0
- synto-0.1.0/tests/test_state.py +682 -0
- synto-0.1.0/tests/test_structured_output.py +300 -0
- synto-0.1.0/tests/test_vault.py +453 -0
- synto-0.1.0/tests/test_watcher.py +154 -0
- synto-0.1.0/uv.lock +1133 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: Benchmarks
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [master]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
benchmark:
|
|
11
|
+
name: Offline micro-benchmarks
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Install uv
|
|
18
|
+
uses: astral-sh/setup-uv@v4
|
|
19
|
+
with:
|
|
20
|
+
version: "latest"
|
|
21
|
+
|
|
22
|
+
- name: Set up Python
|
|
23
|
+
run: uv python install 3.12
|
|
24
|
+
|
|
25
|
+
- name: Install dependencies
|
|
26
|
+
run: uv sync --group dev
|
|
27
|
+
|
|
28
|
+
- name: Run benchmarks
|
|
29
|
+
run: |
|
|
30
|
+
uv run pytest tests/test_benchmarks.py \
|
|
31
|
+
--benchmark-only \
|
|
32
|
+
--benchmark-json=benchmark-results.json \
|
|
33
|
+
-v
|
|
34
|
+
|
|
35
|
+
- name: Upload benchmark results
|
|
36
|
+
uses: actions/upload-artifact@v4
|
|
37
|
+
with:
|
|
38
|
+
name: benchmark-results
|
|
39
|
+
path: benchmark-results.json
|
|
40
|
+
retention-days: 90
|
|
41
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master, main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [master, main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: pytest + ruff
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ["3.11", "3.12"]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Install uv
|
|
21
|
+
uses: astral-sh/setup-uv@v4
|
|
22
|
+
with:
|
|
23
|
+
version: "latest"
|
|
24
|
+
|
|
25
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
26
|
+
run: uv python install ${{ matrix.python-version }}
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: uv sync --group dev
|
|
30
|
+
|
|
31
|
+
- name: Lint (ruff)
|
|
32
|
+
run: uv run ruff check src/ tests/
|
|
33
|
+
|
|
34
|
+
- name: Format check (ruff)
|
|
35
|
+
run: uv run ruff format --check src/ tests/
|
|
36
|
+
|
|
37
|
+
- name: Run tests
|
|
38
|
+
run: uv run pytest --tb=short -q
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
name: Tests must pass
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Install uv
|
|
16
|
+
uses: astral-sh/setup-uv@v4
|
|
17
|
+
with:
|
|
18
|
+
version: "latest"
|
|
19
|
+
|
|
20
|
+
- name: Set up Python
|
|
21
|
+
run: uv python install 3.11
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: uv sync --group dev
|
|
25
|
+
|
|
26
|
+
- name: Lint
|
|
27
|
+
run: uv run ruff check src/ tests/
|
|
28
|
+
|
|
29
|
+
- name: Tests
|
|
30
|
+
run: uv run pytest --tb=short -q
|
|
31
|
+
|
|
32
|
+
release:
|
|
33
|
+
name: Create GitHub Release
|
|
34
|
+
needs: test
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
permissions:
|
|
37
|
+
contents: write
|
|
38
|
+
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@v4
|
|
41
|
+
with:
|
|
42
|
+
fetch-depth: 0
|
|
43
|
+
|
|
44
|
+
- name: Create release
|
|
45
|
+
uses: softprops/action-gh-release@v2
|
|
46
|
+
with:
|
|
47
|
+
generate_release_notes: true
|
|
48
|
+
make_latest: true
|
|
49
|
+
|
|
50
|
+
publish:
|
|
51
|
+
name: Publish to PyPI
|
|
52
|
+
needs: test
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
environment: pypi
|
|
55
|
+
permissions:
|
|
56
|
+
id-token: write # OIDC trusted publishing — no API token needed
|
|
57
|
+
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@v4
|
|
60
|
+
|
|
61
|
+
- name: Install uv
|
|
62
|
+
uses: astral-sh/setup-uv@v4
|
|
63
|
+
with:
|
|
64
|
+
version: "latest"
|
|
65
|
+
|
|
66
|
+
- name: Build package
|
|
67
|
+
run: uv build
|
|
68
|
+
|
|
69
|
+
- name: Publish to PyPI
|
|
70
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
71
|
+
with:
|
|
72
|
+
skip-existing: true
|
synto-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
.DS_Store
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
.venv/
|
|
8
|
+
.env
|
|
9
|
+
*.log
|
|
10
|
+
|
|
11
|
+
# Vault artifacts (not part of the tool itself)
|
|
12
|
+
.chroma/
|
|
13
|
+
*.db
|
|
14
|
+
.olw-compare/
|
|
15
|
+
|
|
16
|
+
# Test artifacts
|
|
17
|
+
.coverage
|
|
18
|
+
htmlcov/
|
|
19
|
+
.pytest_cache/
|
|
20
|
+
|
|
21
|
+
# Claude Code local settings (user-specific, never commit)
|
|
22
|
+
.claude/
|
|
23
|
+
|
|
24
|
+
# Ruff cache
|
|
25
|
+
.ruff_cache/
|
|
26
|
+
|
|
27
|
+
# Local planning/review artifacts
|
|
28
|
+
CONTEXT.md
|
|
29
|
+
REQUIREMENTS.md
|
|
30
|
+
IMPLEMENTATION_PLAN.md
|
|
31
|
+
IMPLEMENTAION_PLAN.md
|
|
32
|
+
REVIEW.md
|
synto-0.1.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install (editable, auto-detects uv/pip)
|
|
9
|
+
python install.py
|
|
10
|
+
|
|
11
|
+
# Dependencies
|
|
12
|
+
uv sync --group dev
|
|
13
|
+
|
|
14
|
+
# Tests (all offline, no Ollama required)
|
|
15
|
+
uv run pytest
|
|
16
|
+
uv run pytest tests/test_ingest.py::test_function_name -v # single test
|
|
17
|
+
uv run pytest --cov=src/synto # with coverage
|
|
18
|
+
|
|
19
|
+
# Lint & format
|
|
20
|
+
uv run ruff check src/ tests/
|
|
21
|
+
uv run ruff format --check src/ tests/
|
|
22
|
+
uv run ruff format src/ tests/ # auto-fix
|
|
23
|
+
|
|
24
|
+
# Smoke tests (user preference: run against LM Studio with gemma4:e4b)
|
|
25
|
+
# Requires LM Studio server at http://localhost:1234/v1 with gemma4:e4b loaded.
|
|
26
|
+
PROVIDER=lm_studio FAST_MODEL=gemma4:e4b HEAVY_MODEL=gemma4:e4b bash scripts/smoke_test.sh
|
|
27
|
+
PROVIDER=lm_studio FAST_MODEL=gemma4:e4b HEAVY_MODEL=gemma4:e4b bash scripts/compare_smoke.sh
|
|
28
|
+
# If LM Studio rejects the alias, use the exact loaded id it reports, e.g.
|
|
29
|
+
# PROVIDER=lm_studio FAST_MODEL=google/gemma-4-e4b HEAVY_MODEL=google/gemma-4-e4b bash scripts/smoke_test.sh
|
|
30
|
+
# The main smoke can take 15+ minutes with gemma4:e4b; use a long command timeout.
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Architecture
|
|
34
|
+
|
|
35
|
+
Three-stage local LLM pipeline turning Obsidian raw notes into a synthesized wiki via Ollama.
|
|
36
|
+
|
|
37
|
+
**Data flow:** `raw/*.md` → **ingest** (fast model → AnalysisResult) → **compile** (heavy model → SingleArticle drafts) → **approve** (publish to `wiki/`)
|
|
38
|
+
|
|
39
|
+
**Vault structure:** `raw/` (immutable user notes), `wiki/` (published articles), `wiki/.drafts/`, `wiki/sources/`, `wiki/queries/`, `wiki/synthesis/`, `.synto/state.db`
|
|
40
|
+
|
|
41
|
+
### Query synthesis
|
|
42
|
+
|
|
43
|
+
- `synto query --save` writes dated Q&A notes to `wiki/queries/`
|
|
44
|
+
- `synto query --synthesize` writes published synthesis articles to `wiki/synthesis/`
|
|
45
|
+
- synthesis rows are tracked in `wiki_articles` with `kind="synthesis"`, `question_hash`, `synthesis_sources`, and `synthesis_source_hashes`
|
|
46
|
+
- duplicate syntheses are keyed by normalized question hash
|
|
47
|
+
- `update_in_place` must respect manual-edit protection by comparing the on-disk body hash with the DB `content_hash`
|
|
48
|
+
- compare runs must not create or mutate active `wiki/synthesis/` content
|
|
49
|
+
|
|
50
|
+
### Key modules (`src/synto/`)
|
|
51
|
+
|
|
52
|
+
- `cli.py` — Click-based CLI entry point, all commands registered here
|
|
53
|
+
- `config.py` / `global_config.py` — Two-tier config: per-vault `synto.toml` + user-level `~/.config/synto/config.toml`
|
|
54
|
+
- `models.py` — Pydantic v2 schemas for LLM I/O (AnalysisResult, SingleArticle, PageSelection, QueryAnswer) and internal state (RawNoteRecord, WikiArticleRecord)
|
|
55
|
+
- `state.py` — SQLite state DB tracking note lifecycle (new → ingested → compiled → published/failed), concepts, and articles
|
|
56
|
+
- `ollama_client.py` — Thin httpx wrapper around Ollama HTTP API (no langchain)
|
|
57
|
+
- `structured_output.py` — 3-tier JSON extraction fallback: native `format=json` → regex extraction → retry with error feedback
|
|
58
|
+
- `vault.py` — Frontmatter parsing (python-frontmatter), wikilink extraction, atomic writes
|
|
59
|
+
- `indexer.py` — Generates `wiki/index.md` and append-only operation log
|
|
60
|
+
- `git_ops.py` — Auto-commit with `[synto]` prefix, safe undo via `git revert`
|
|
61
|
+
- `watcher.py` — Debounced file watcher (watchdog + threading.Timer)
|
|
62
|
+
|
|
63
|
+
### Pipeline stages (`pipeline/`)
|
|
64
|
+
|
|
65
|
+
- `ingest.py` — Fast model analyzes raw notes, extracts concepts, creates source summary pages
|
|
66
|
+
- `compile.py` — Default: concept-driven (one article per concept, incremental). Legacy: two-step LLM planning (`--legacy`). Manual-edit protection via content_hash comparison
|
|
67
|
+
- `query.py` — Index-based page routing (no embeddings), fast model selects pages, heavy model answers
|
|
68
|
+
- `lint.py` — Static health checks (orphans, broken links, stale articles, missing frontmatter)
|
|
69
|
+
|
|
70
|
+
## Conventions
|
|
71
|
+
|
|
72
|
+
- **Two LLM tiers:** fast model (gemma4:e4b, 8K ctx) for analysis/routing, heavy model (qwen2.5:14b, 16K ctx) for writing. For manual/smoke testing, use gemma4:e4b for both fast and heavy
|
|
73
|
+
- **Pydantic models for LLM output:** Keep schemas small and flat (no nested lists of objects) for 4B model reliability. JSON schema is injected into system prompts
|
|
74
|
+
- **Atomic writes:** `vault.atomic_write()` uses temp file + rename for crash safety
|
|
75
|
+
- **Content hashing:** SHA256 on note body (excluding frontmatter) for dedup and manual-edit detection
|
|
76
|
+
- **Concept normalization:** Case-insensitive matching against existing canonical names during ingest
|
|
77
|
+
- **Config loading order:** `--vault` flag → `SYNTO_VAULT` env var → global config default vault → error
|
|
78
|
+
- **Git safety:** All auto-operations use `[synto]`-prefixed commits; undo uses `git revert` (never destructive)
|
|
79
|
+
- **Error handling:** LLM failures log + mark note as "failed" + continue (no crash). Config loading returns None on failure (fail open)
|
|
80
|
+
- **Code comments:** Add comments only when the reason or invariant is non-obvious from the code itself. Prefer tests and commit messages for routine explanation; use comments for safeguards, provider quirks, heuristics, and tradeoffs that future agents or humans could otherwise misread.
|
|
81
|
+
- **Testing:** All 200 tests mock OllamaClient via MagicMock, use tmp_path vaults and in-memory SQLite. Fixtures in `tests/fixtures/`. Integration tests marked with `@pytest.mark.integration`
|
|
82
|
+
- **Python 3.11+:** Uses `tomllib` (stdlib), `from __future__ import annotations`, full type hints
|
|
83
|
+
- **Ruff config:** rules E, F, I, UP; line-length 100
|
synto-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 kytmanov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
synto-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: synto
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Turn private notes into local knowledge packs and synthesized wikis
|
|
5
|
+
Project-URL: Homepage, https://github.com/kytmanov/synto
|
|
6
|
+
Project-URL: Repository, https://github.com/kytmanov/synto
|
|
7
|
+
Project-URL: Issues, https://github.com/kytmanov/synto/issues
|
|
8
|
+
Author: kytmanov
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: knowledge-management,llm,local-ai,obsidian,ollama,wiki
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
21
|
+
Classifier: Topic :: Utilities
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Requires-Dist: click>=8.1
|
|
24
|
+
Requires-Dist: httpx>=0.27
|
|
25
|
+
Requires-Dist: jsonschema>=4.0
|
|
26
|
+
Requires-Dist: pydantic>=2.0
|
|
27
|
+
Requires-Dist: python-frontmatter>=1.1
|
|
28
|
+
Requires-Dist: python-ulid>=2.0
|
|
29
|
+
Requires-Dist: pyyaml>=6.0
|
|
30
|
+
Requires-Dist: rich>=13.0
|
|
31
|
+
Requires-Dist: watchdog>=4.0
|
|
32
|
+
Provides-Extra: mcp
|
|
33
|
+
Requires-Dist: mcp<2.0,>=1.0; extra == 'mcp'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
# Synto
|
|
37
|
+
|
|
38
|
+
<p align="center">
|
|
39
|
+
<a href="https://github.com/kytmanov/synto/commits/master"><img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/kytmanov/obsidian-llm-wiki-local?style=flat"></a>
|
|
40
|
+
<a href="https://github.com/kytmanov/synto/actions/workflows/ci.yml"><img alt="CI status" src="https://img.shields.io/github/actions/workflow/status/kytmanov/synto/ci.yml?style=flat&label=CI"></a>
|
|
41
|
+
<a href="https://pypi.org/project/synto/"><img alt="PyPI version" src="https://img.shields.io/pypi/v/synto?style=flat"></a>
|
|
42
|
+
</p>
|
|
43
|
+
|
|
44
|
+
**Turn your raw notes into a self-improving, interlinked wiki — powered by a local LLM.**
|
|
45
|
+
|
|
46
|
+
Synto is a knowledge compiler. Point it at any source of expertise and it produces a portable wiki pack any AI agent can install and query.
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
**Local-first, provider-flexible.** Runs 100% locally with Ollama or LM Studio. Switch to a cloud provider — Groq, OpenRouter, Mistral — when you need more power. Your notes and source material never leave your machine unless you choose.
|
|
50
|
+
|
|
51
|
+
Synto succeeds [obsidian-llm-wiki-local](https://github.com/kytmanov/obsidian-llm-wiki-local) (608 ★, 9k+ downloads) — same proven local pipeline, redesigned for distributable knowledge packs.
|
|
52
|
+
|
|
53
|
+
<p align=center>
|
|
54
|
+
<img width="341" height="463" alt="image" src="https://github.com/user-attachments/assets/b3e13203-bb4a-42a4-a16d-0d4d93404f71" />
|
|
55
|
+
</p>
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Why it exists
|
|
60
|
+
|
|
61
|
+
AI agents are only as good as the context you give them. A folder of notes or a raw PDF is not context — it's noise. Synto processes your source material through a local LLM pipeline, extracts concepts, writes cross-linked articles, and exports a structured directory: articles, an index, a concept graph, and agent-readable metadata. The pack installs like a package. Any agent gets a domain expert layer, not a file dump.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Use cases
|
|
66
|
+
|
|
67
|
+
**Architectural reference from a textbook**
|
|
68
|
+
|
|
69
|
+
[Dobryakov took Tanenbaum's *Distributed Systems*](https://www.facebook.com/dobryakov/posts/pfbid021pwPPJZ77KsyWMs3zTdMQEbgpmxgeE9wzoX1SDFE12y5vC3HtdFZV5i5HnS2dUAul), compiled it into a cross-linked wiki, and installed it into Claude/Cursor. Instead of generic suggestions, the AI started reasoning from established distributed systems principles — recommending consistent hashing and two-phase commit instead of "use a shared database." Any technical book, spec, or documentation set becomes a live context layer for your AI.
|
|
70
|
+
|
|
71
|
+
**Karpathy's LLM Wiki**
|
|
72
|
+
|
|
73
|
+
[Andrej Karpathy's](https://karpathy.ai) neural-network series is 20 hours of dense, high-quality material. Compile the transcripts and blog posts into a Synto pack and the content becomes queryable: any agent in your project can explain backpropagation, walk through the attention mechanism, or cite a specific lecture — from the source, not from model weights.
|
|
74
|
+
|
|
75
|
+
**Your own research notes**
|
|
76
|
+
|
|
77
|
+
Works today with Markdown. Drop notes in `raw/`, run `synto run`, and get a cross-linked wiki exported as an agent-ready pack. Expose it via `synto serve` as a local MCP server, or ship the pack directory for any file-aware agent to use.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## How it works
|
|
82
|
+
|
|
83
|
+
Three stages, two LLM tiers:
|
|
84
|
+
|
|
85
|
+
1. **Ingest** — fast model reads each source, extracts concepts and summaries
|
|
86
|
+
2. **Compile** — heavy model writes one cross-linked article per concept
|
|
87
|
+
3. **Export** — `synto pack export` produces an agent-ready directory
|
|
88
|
+
|
|
89
|
+
The fast model handles analysis (4B parameters is enough). The heavy model handles writing (14B+ recommended locally, or any cloud model). Both tiers are configurable independently.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Install
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
pip install synto
|
|
97
|
+
# or
|
|
98
|
+
uv tool install synto
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
For MCP server support:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
pip install "synto[mcp]"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Quick start
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
synto setup # configure LLM provider
|
|
113
|
+
synto init ~/my-vault # create vault
|
|
114
|
+
|
|
115
|
+
# add Markdown notes to ~/my-vault/raw/
|
|
116
|
+
synto run --vault ~/my-vault # ingest + compile into wiki/.drafts/
|
|
117
|
+
synto review --vault ~/my-vault # inspect drafts interactively
|
|
118
|
+
# or: synto approve --all --vault ~/my-vault
|
|
119
|
+
|
|
120
|
+
synto pack export --target agents --vault ~/my-vault
|
|
121
|
+
synto serve --vault ~/my-vault # expose as MCP server (requires [mcp])
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
If you want a one-command flow, use `synto run --auto-approve --vault ~/my-vault`.
|
|
125
|
+
That skips draft review and publishes directly into `wiki/`.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## What's in a pack
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
pack/
|
|
133
|
+
articles/ one Markdown file per concept
|
|
134
|
+
index/INDEX.json machine-readable index with stable article IDs
|
|
135
|
+
agent/
|
|
136
|
+
manifest.json capabilities, pack metadata
|
|
137
|
+
concepts.json concept registry
|
|
138
|
+
sources.json source provenance
|
|
139
|
+
AGENTS.md agent-readable entrypoint
|
|
140
|
+
CLAUDE.md Claude Code context file
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Any file-aware agent can read the articles directly. `INDEX.json` enables fast concept lookup without a database. `synto serve` exposes `list_articles`, `read_article`, and `find_concept` as MCP tools.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## What ships now
|
|
148
|
+
|
|
149
|
+
- Full ingest → compile → approve pipeline; currently supports Markdown notes and Obsidian vaults
|
|
150
|
+
- `synto pack export --target agents` — portable knowledge pack with INDEX.json and agent metadata
|
|
151
|
+
- `synto serve` — read-only MCP server (`list_articles`, `read_article`, `find_concept`)
|
|
152
|
+
- `synto query` — index-routed Q&A with optional synthesis to `wiki/synthesis/`
|
|
153
|
+
- `synto review` — interactive draft review: approve, reject, edit, or diff before publishing
|
|
154
|
+
- `synto watch` — file watcher: auto-ingest and compile on every save
|
|
155
|
+
- `synto maintain` — wiki health check, stub creation, orphan cleanup
|
|
156
|
+
- `synto eval` — offline structural evaluation (coverage, citation support, link resolution)
|
|
157
|
+
- `synto compare` — A/B model comparison without touching your vault
|
|
158
|
+
- Multi-language: notes are ingested and compiled in their source language
|
|
159
|
+
- 20+ LLM providers supported via OpenAI-compatible API
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Data & Privacy
|
|
164
|
+
|
|
165
|
+
- **Local by default.** Ollama and LM Studio process all content on your machine — notes never leave it.
|
|
166
|
+
- **Cloud providers.** If you configure an OpenAI-compatible cloud provider, note content and wiki text are sent to that service. Review their privacy policy before use.
|
|
167
|
+
- **No remote analytics.** Synto does not send usage analytics anywhere. Local runtime and cost metrics stay in your vault database.
|
|
168
|
+
- **Pack exports.** Exported packs include raw notes, sources, wiki articles, queries, and synthesis by default. Review your vault before sharing a pack.
|
|
169
|
+
- **API keys.** Stored in `~/.config/synto/config.toml` (user-owned, not inside the vault). Never commit that file.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Requirements
|
|
174
|
+
|
|
175
|
+
- Python 3.11+
|
|
176
|
+
- An LLM provider: Ollama (local), LM Studio, or any OpenAI-compatible endpoint
|
|
177
|
+
|
|
178
|
+
Recommended local setup: a 4B model for ingest (e.g. Gemma 4), a 14B+ model for compilation (e.g. Qwen 2.5 14B). Works entirely offline.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Migrate from obsidian-llm-wiki-local
|
|
183
|
+
|
|
184
|
+
**Existing obsidian-llm-wiki-local vaults must be migrated first.** Run `migrate-olw` to copy `wiki.toml` and `.olw/` into the current Synto layout before using normal commands.
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
synto migrate-olw --vault ~/my-old-vault
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Copies `wiki.toml` → `synto.toml` and `.olw/` → `.synto/`. Notes and articles are untouched. Old files are preserved — delete them once you've verified everything works.
|
synto-0.1.0/README.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Synto
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://github.com/kytmanov/synto/commits/master"><img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/kytmanov/obsidian-llm-wiki-local?style=flat"></a>
|
|
5
|
+
<a href="https://github.com/kytmanov/synto/actions/workflows/ci.yml"><img alt="CI status" src="https://img.shields.io/github/actions/workflow/status/kytmanov/synto/ci.yml?style=flat&label=CI"></a>
|
|
6
|
+
<a href="https://pypi.org/project/synto/"><img alt="PyPI version" src="https://img.shields.io/pypi/v/synto?style=flat"></a>
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
**Turn your raw notes into a self-improving, interlinked wiki — powered by a local LLM.**
|
|
10
|
+
|
|
11
|
+
Synto is a knowledge compiler. Point it at any source of expertise and it produces a portable wiki pack any AI agent can install and query.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
**Local-first, provider-flexible.** Runs 100% locally with Ollama or LM Studio. Switch to a cloud provider — Groq, OpenRouter, Mistral — when you need more power. Your notes and source material never leave your machine unless you choose.
|
|
15
|
+
|
|
16
|
+
Synto succeeds [obsidian-llm-wiki-local](https://github.com/kytmanov/obsidian-llm-wiki-local) (608 ★, 9k+ downloads) — same proven local pipeline, redesigned for distributable knowledge packs.
|
|
17
|
+
|
|
18
|
+
<p align=center>
|
|
19
|
+
<img width="341" height="463" alt="image" src="https://github.com/user-attachments/assets/b3e13203-bb4a-42a4-a16d-0d4d93404f71" />
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Why it exists
|
|
25
|
+
|
|
26
|
+
AI agents are only as good as the context you give them. A folder of notes or a raw PDF is not context — it's noise. Synto processes your source material through a local LLM pipeline, extracts concepts, writes cross-linked articles, and exports a structured directory: articles, an index, a concept graph, and agent-readable metadata. The pack installs like a package. Any agent gets a domain expert layer, not a file dump.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Use cases
|
|
31
|
+
|
|
32
|
+
**Architectural reference from a textbook**
|
|
33
|
+
|
|
34
|
+
[Dobryakov took Tanenbaum's *Distributed Systems*](https://www.facebook.com/dobryakov/posts/pfbid021pwPPJZ77KsyWMs3zTdMQEbgpmxgeE9wzoX1SDFE12y5vC3HtdFZV5i5HnS2dUAul), compiled it into a cross-linked wiki, and installed it into Claude/Cursor. Instead of generic suggestions, the AI started reasoning from established distributed systems principles — recommending consistent hashing and two-phase commit instead of "use a shared database." Any technical book, spec, or documentation set becomes a live context layer for your AI.
|
|
35
|
+
|
|
36
|
+
**Karpathy's LLM Wiki**
|
|
37
|
+
|
|
38
|
+
[Andrej Karpathy's](https://karpathy.ai) neural-network series is 20 hours of dense, high-quality material. Compile the transcripts and blog posts into a Synto pack and the content becomes queryable: any agent in your project can explain backpropagation, walk through the attention mechanism, or cite a specific lecture — from the source, not from model weights.
|
|
39
|
+
|
|
40
|
+
**Your own research notes**
|
|
41
|
+
|
|
42
|
+
Works today with Markdown. Drop notes in `raw/`, run `synto run`, and get a cross-linked wiki exported as an agent-ready pack. Expose it via `synto serve` as a local MCP server, or ship the pack directory for any file-aware agent to use.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## How it works
|
|
47
|
+
|
|
48
|
+
Three stages, two LLM tiers:
|
|
49
|
+
|
|
50
|
+
1. **Ingest** — fast model reads each source, extracts concepts and summaries
|
|
51
|
+
2. **Compile** — heavy model writes one cross-linked article per concept
|
|
52
|
+
3. **Export** — `synto pack export` produces an agent-ready directory
|
|
53
|
+
|
|
54
|
+
The fast model handles analysis (4B parameters is enough). The heavy model handles writing (14B+ recommended locally, or any cloud model). Both tiers are configurable independently.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Install
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install synto
|
|
62
|
+
# or
|
|
63
|
+
uv tool install synto
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
For MCP server support:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pip install "synto[mcp]"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Quick start
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
synto setup # configure LLM provider
|
|
78
|
+
synto init ~/my-vault # create vault
|
|
79
|
+
|
|
80
|
+
# add Markdown notes to ~/my-vault/raw/
|
|
81
|
+
synto run --vault ~/my-vault # ingest + compile into wiki/.drafts/
|
|
82
|
+
synto review --vault ~/my-vault # inspect drafts interactively
|
|
83
|
+
# or: synto approve --all --vault ~/my-vault
|
|
84
|
+
|
|
85
|
+
synto pack export --target agents --vault ~/my-vault
|
|
86
|
+
synto serve --vault ~/my-vault # expose as MCP server (requires [mcp])
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
If you want a one-command flow, use `synto run --auto-approve --vault ~/my-vault`.
|
|
90
|
+
That skips draft review and publishes directly into `wiki/`.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## What's in a pack
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
pack/
|
|
98
|
+
articles/ one Markdown file per concept
|
|
99
|
+
index/INDEX.json machine-readable index with stable article IDs
|
|
100
|
+
agent/
|
|
101
|
+
manifest.json capabilities, pack metadata
|
|
102
|
+
concepts.json concept registry
|
|
103
|
+
sources.json source provenance
|
|
104
|
+
AGENTS.md agent-readable entrypoint
|
|
105
|
+
CLAUDE.md Claude Code context file
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Any file-aware agent can read the articles directly. `INDEX.json` enables fast concept lookup without a database. `synto serve` exposes `list_articles`, `read_article`, and `find_concept` as MCP tools.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## What ships now
|
|
113
|
+
|
|
114
|
+
- Full ingest → compile → approve pipeline; currently supports Markdown notes and Obsidian vaults
|
|
115
|
+
- `synto pack export --target agents` — portable knowledge pack with INDEX.json and agent metadata
|
|
116
|
+
- `synto serve` — read-only MCP server (`list_articles`, `read_article`, `find_concept`)
|
|
117
|
+
- `synto query` — index-routed Q&A with optional synthesis to `wiki/synthesis/`
|
|
118
|
+
- `synto review` — interactive draft review: approve, reject, edit, or diff before publishing
|
|
119
|
+
- `synto watch` — file watcher: auto-ingest and compile on every save
|
|
120
|
+
- `synto maintain` — wiki health check, stub creation, orphan cleanup
|
|
121
|
+
- `synto eval` — offline structural evaluation (coverage, citation support, link resolution)
|
|
122
|
+
- `synto compare` — A/B model comparison without touching your vault
|
|
123
|
+
- Multi-language: notes are ingested and compiled in their source language
|
|
124
|
+
- 20+ LLM providers supported via OpenAI-compatible API
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Data & Privacy
|
|
129
|
+
|
|
130
|
+
- **Local by default.** Ollama and LM Studio process all content on your machine — notes never leave it.
|
|
131
|
+
- **Cloud providers.** If you configure an OpenAI-compatible cloud provider, note content and wiki text are sent to that service. Review their privacy policy before use.
|
|
132
|
+
- **No remote analytics.** Synto does not send usage analytics anywhere. Local runtime and cost metrics stay in your vault database.
|
|
133
|
+
- **Pack exports.** Exported packs include raw notes, sources, wiki articles, queries, and synthesis by default. Review your vault before sharing a pack.
|
|
134
|
+
- **API keys.** Stored in `~/.config/synto/config.toml` (user-owned, not inside the vault). Never commit that file.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Requirements
|
|
139
|
+
|
|
140
|
+
- Python 3.11+
|
|
141
|
+
- An LLM provider: Ollama (local), LM Studio, or any OpenAI-compatible endpoint
|
|
142
|
+
|
|
143
|
+
Recommended local setup: a 4B model for ingest (e.g. Gemma 4), a 14B+ model for compilation (e.g. Qwen 2.5 14B). Works entirely offline.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Migrate from obsidian-llm-wiki-local
|
|
148
|
+
|
|
149
|
+
**Existing obsidian-llm-wiki-local vaults must be migrated first.** Run `migrate-olw` to copy `wiki.toml` and `.olw/` into the current Synto layout before using normal commands.
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
synto migrate-olw --vault ~/my-old-vault
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Copies `wiki.toml` → `synto.toml` and `.olw/` → `.synto/`. Notes and articles are untouched. Old files are preserved — delete them once you've verified everything works.
|