rename: the server is Inkwell — package, env vars, image, compose, export marker
CI & Build / Python lint (push) Successful in 2s
CI & Build / Build now, or wait for Android? (push) Successful in 2s
Android / Build, or is the channel already serving this? (push) Successful in 3s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 2s
CI & Build / TypeScript typecheck (push) Successful in 7s
CI & Build / Python tests (push) Successful in 15s
CI & Build / integration (push) Successful in 45s
CI & Build / Build & push image (push) Skipped
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 4m17s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 7m33s
Desktop (Tauri) / Update manifest (push) Successful in 7s
Android / Kotlin + Rust (APK) (push) Successful in 11m25s

Step 2 of milestone 481. The operator chose a full rename (Scribe note 5071), so
this goes past the display strings into the identities:

- src/thoughtsync → src/inkwell; every import, the Dockerfile and both compose
  commands, alembic env, pyproject
- THOUGHTSYNC_* → INKWELL_* (database URL, secret key, log level, tag/port/bind)
- container data dir /var/thoughtsync → /var/inkwell
- image git.fabledsword.com/bvandeusen/inkwell; Postgres user/db default inkwell;
  CI's integration service follows
- the files the image serves are inkwell.*. fetch-clients.sh still fetches the
  thoughtsync-named release assets, because the lanes that publish them are
  renamed in steps 3 and 4
- exports are written with app "inkwell"

Two deliberate exceptions, both because data rides on them:

- compose volumes are now named explicitly and overridable (INKWELL_DB_VOLUME,
  INKWELL_DATA_VOLUME), so a deployment installed as ThoughtSync points at the
  volumes and DB identity it already has. .env.example says exactly what to set
- import still accepts app "thoughtsync", because exports written before the
  rename are backups. Tested both ways

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-06 14:18:49 -04:00
co-authored by Claude Opus 5.5
parent f806e35d41
commit a706644455
78 changed files with 231 additions and 168 deletions
+35 -8
View File
@@ -1,12 +1,15 @@
import io
import json
import zipfile
from datetime import datetime, timezone
import pytest
from thoughtsync.app import create_app
from thoughtsync.common import coerce_bool, parse_dt
from thoughtsync.colors import NOTE_COLORS
from thoughtsync.models.note import Note
from thoughtsync.notes.checklist import (
from inkwell.app import create_app
from inkwell.common import coerce_bool, parse_dt
from inkwell.colors import NOTE_COLORS
from inkwell.models.note import Note
from inkwell.notes.checklist import (
append_item,
parse_items,
remove_item,
@@ -14,13 +17,15 @@ from thoughtsync.notes.checklist import (
set_item_text,
strip_marker,
)
from thoughtsync.unfurl_queue import detect_urls
from thoughtsync.notes import (
from inkwell.unfurl_queue import detect_urls
from inkwell.notes import (
_ImportBudget,
_attachment_ext,
_header_filename,
_keep_spec,
_native_spec,
_note_markdown,
_read_import_specs,
_safe_filename,
_slugify,
_usec_to_dt,
@@ -32,7 +37,8 @@ from thoughtsync.notes import (
parse_list_items,
parse_tags,
)
from thoughtsync.notes.tags import split_body_tags
from inkwell.notes.import_export import NATIVE_APP_MARKERS
from inkwell.notes.tags import split_body_tags
@pytest.fixture
@@ -672,3 +678,24 @@ def test_native_spec_of_a_pre_m304_export_still_carries_its_items():
# items at all.
old = {"body": "shopping", "items": [{"text": "milk", "checked": True}]}
assert _native_spec(old)["items"] == [{"text": "milk", "checked": True}]
def _export_zip(app_marker: str) -> zipfile.ZipFile:
buf = io.BytesIO()
with zipfile.ZipFile(buf, "w") as zf:
zf.writestr("notes.json", json.dumps({"app": app_marker, "notes": [{"body": "kept"}]}))
return zipfile.ZipFile(io.BytesIO(buf.getvalue()))
@pytest.mark.parametrize("marker", ["inkwell", "thoughtsync"])
def test_an_export_imports_under_either_name(marker):
# "thoughtsync" is what every export written before the rename to Inkwell says.
# Those zips are backups, so they have to keep restoring as native exports rather
# than falling through to the Keep importer, which would find nothing in them.
specs, source = _read_import_specs(_export_zip(marker), _ImportBudget())
assert source == "inkwell"
assert [s["body"] for s in specs] == ["kept"]
def test_new_exports_are_written_as_inkwell():
assert NATIVE_APP_MARKERS[0] == "inkwell"