Added
- Added a read-only synchronized-graph verifier that compares the actual Markdown and Org file bytes across devices, including nested and nonstandard layouts, without requiring shell or ADB access.
Changed
-
A fault one core test injects can no longer fail an unrelated test beside
it. The shared-provider "this filesystem has norenameat2flags" fault was
armed process-wide, so under a threadedcargo testthe injected errno was
visible to every other test renaming a provider file at that moment; the
whole-suite failure set differed on every run. The fault is now scoped to the
thread under test and handed explicitly to the sync actor for the one request
that needs it, so the corpus reports the same result twice in a row (GH #350). -
Queries and search are much faster on Managed Storage. Every managed
query used to re-read, re-parse, and structurally cross-check every candidate
page, every time -- so a page full of{{query}}re-parsed the graph on each
open, and search re-parsed it on each keystroke. Unchanged pages now reuse
their complete parsed application view after their exact file bytes and
stored page state are checked; an external edit or accepted actor change is
re-read immediately. Searching for a literal phrase also consults the stored
text index first instead of reading every page, and a result-limited search
now does its work only for the results it keeps.
Fixed
-
Task markers mean the same thing everywhere. The editor, carry-forward,
the sheet state/priority writers, and the rendered checkbox now share one
leading-marker recognizer that is byte-faithful to the parser: a task written
asTODO<tab>xno longer counts as open for carry-forward while rendering
without a checkbox, cycling or setting state on an indented task replaces its
marker instead of prepending a second one, and a bareTODOfollowed by
continuation lines is no longer treated as a task the renderer cannot see. -
key:: valueproperty lines are recognized the same way by every tool.
Logbook insertion, managed template/content checks, rename, conflict handling
and the read index now share the parser's exact property-line rule, so a
dotted key likelogseq.order-list-type:: numberis treated as a block
property everywhere (a logbook entry could previously be inserted above it),
leading whitespace and Unicode keys behave identically, andkey::value
without a space is (as the parser already said) not a property. -
Page-link gestures are the same everywhere. Middle-click now opens a
background tab from every page reference and page title — unlinked-reference
page headers, namespace macro and hierarchy links, the zoom breadcrumb,
right-sidebar item titles, query search-result rows, and the page title's
Ctrl/Cmd+click all behaved differently (plain-click only, or autoscroll on
Windows). Shift+click still opens the sidebar and plain click still navigates
(GH #207). -
A split pane's only tab keeps its close button. The tab strip hid the ✕
whenever a pane held a single tab, so after one split neither pane could be
closed without first dragging a tab across. The ✕ now shows whenever closing
actually works: any multi-tab strip, or a lone non-feed tab whose pane can
close (GH #207). -
Search and conflict handling now use one contract across runtimes. Page
and block search agree on Unicode whitespace, bare Unicode tags, and the
common linear-time regex subset; query-workspace saves and Direct conflict
resolution classify bounded failure codes instead of matching error prose.
The browser mock now also announces the graph rebind caused by changing the
default home page. -
Managed Storage and Direct Files answer the same query the same way. The
two storage modes evaluated block queries through separate copies of the same
logic, and the copies had drifted: a byte-budgeted block-referrers panel
admitted a different number of rows, and kept a different set of them, on the
two modes for identical content. Both now use one evaluator and one
result-budget rule. -
Journal recency respects the configured title format. On graphs with a
custom:journal/page-title-format,(sort-by modified)ranked every
journal last on three of the four query paths (they parsed titles with the
default format only). All producers now share one recency axis that honours
the graph's configured formats. -
Backlink filter truncation is reported consistently. A page-property
root entry that hit its text/facet budget marked the context truncated on
Managed Storage but not on Direct Files; the two now agree. -
Managed rename works for every page name. The managed rename planner
keyed its index lookups with a different Unicode fold than the index itself
(the two disagree on Greek final sigma), so renaming such a page reported
success while doing nothing. Rename lookups now use the index's own fold. -
config.edn settings can no longer clobber a nested map. Every setting
writer now edits only the root map's direct entries; a same-named keyword
nested inside another map (e.g. under:default-templates) survives
byte-for-byte instead of being spliced over. -
Write-durability errors are reported, not swallowed. The workspaces
registry, backup restore, and Linux window-identity writers follow the save
path's directory-fsync policy (tolerate "unsupported here", report real
errors), the window-identity writer uses unique create-only temp files, and
the file watcher recognizes backup-restore temp files directly. -
One spelling of a page is one favorite. Starring a page under one
spelling (different case, an alias, NFC/NFD accents, boundary slashes) now
fills the star and toggles off under every other spelling instead of
appending a duplicate; the sidebar arrangement, membership, page delete, and
rename all use the same kind-scoped identity, so deleting a page no longer
silently drops a journal favorite that merely shares its name. Backlink
filter chips key by the same identity, so two spellings of one co-referenced
page no longer produce two chips that miss each other's filters.
Added
-
Batch copy/export for references (GH #348). Linked References and
Unlinked References each have an explicit export affordance: every entry is
pre-selected for copy-all, uncheck for a subset, and the familiar Copy /
export modal (Text, OPML, HTML, with the usual content/indent/depth/cleanup
options) produces the selected blocks grouped by their source page. The two
sections act independently, Linked honors its active filters, and normal page
export is unchanged — references are never included unless you ask. -
Favorites nest to any depth (GH #102). A group can hold groups, and a
favorite can hold favorites; drag a row to the right to nest it, to the left
to lift it out. Depth is measured from where the drag started, so a plain
vertical drag never nests by accident, and the insertion line is drawn at the
depth the drop will land. Deleting a group still keeps everything it held —
now one level up rather than at the top. The arrangement page round-trips
every bullet at every depth, so hand-written nesting survives. -
Editing the Favorites page updates the sidebar (GH #102). The arrangement
lives in an ordinary page, so editing it — in Tine or outside — is now
reflected immediately instead of at the next graph open. A page edit is a
membership statement: removing a[[link]]bullet unfavorites that page and
adding one favorites it. This also gives favorites reordering a keyboard
route, since the arrangement is a page like any other. -
logseq/config.ednis re-read while Tine runs. A settings change made in
Logseq, in a text editor, or delivered by Syncthing is now picked up during
the session rather than being ignored until the next graph open — and
therefore no longer computed against a stale copy. Favorites, shortcuts,
macros, the home page, journal formats, hidden properties and the rest all
follow. Tine only pays for the reload when the file's bytes actually differ
from those it is serving, so its own settings writes and repeated identical
deliveries cost nothing. -
Privacy-safe diagnostic reports (GH #343). Every production build now
retains a bounded current-and-previous-run flight recorder of fixed operation
names, outcomes, timings and counts. Settings → Diagnostics previews the JSON
before the user chooses to copy or save it; nothing is uploaded automatically,
and graph content, paths, page titles, queries, URLs and credentials are
excluded by the recorder API. Release CI also retains exact-commit native
symbols and hidden frontend source maps outside the shipped packages. -
Experimental 32-bit Windows packages (GH #275). Releases now produce an
i686-pc-windows-msvcinstaller and portable ZIP for older Windows 10 tablets.
The pilot is deliberately excluded from automatic updates until it has been
exercised on a reporter's real 32-bit device. -
Favorites can be arranged into named groups. One level, plain-text group
names, collapsible, with drag between groups as well as within one. Deleting a
group never unfavorites anything — its pages move back to the ungrouped list.
The arrangement lives in an ordinary page in your graph, so it syncs and
merges like everything else rather than as an opaque settings blob, and
because its entries are real links a page rename follows them automatically.
config.edn :favoritesstays exactly what it was — the flat list Logseq
reads — so Logseq keeps working. Nothing is created until you actually make a
group: if you never group anything, nothing about Favorites changes (GH #102).
Changed
-
Typing in the Linked References search box now also narrows the reference
chips below it. The reference list already shrank as you typed; the chips —
the pages and tags you pick from — were computed over every backlink, so they
and their counts never moved. They now follow what you type, which is what
Logseq's equivalent field does and what the list is for. A chip you have
already selected stays visible even when your text filters its last backlink
away, at count zero, so a filter can never become unreachable (GH #173). -
A journal day with more than one file is now resolved on the day itself.
These days — usually a leftover of changing the journal date format, which
never overwrites the old file — used to reach you only as a sticky notice at
startup pointing at Settings. They now join the conflict badge, the dock and
the walk like every other conflict, and the day page offers the same
side-by-side review: keep a line from either file, or keep both. Keeping both
is what "Merge" did in Settings, so nothing was lost by moving it here; the
other file goes to the recoverable trash once you apply. Opening, renaming and
trashing an individual file are still offered, on the day and in Settings.
Two files in different formats (a.mdand an.orgfor one day) can't be
folded together and say so instead of offering a choice that could not be
applied. The startup notice is gone. -
Copy / export names its two content choices after what you actually get.
The explicit Content option in "Copy / export as…" now reads Plain text
(cleaned, as displayed) and Markdown — or Org on an Org page —
(preserved source syntax: bold, highlighting, links, properties and
structure). The preserve choice was always implemented but shipped under
the internal label "Source"; users looking for the Markdown-preserving
option could not find it (GH #352).
Fixed
-
Future iOS/TestFlight builds now use Tine's application icon. The generated
Xcode project previously retained Tauri's template icon even though Tine's
complete iOS icon set was tracked in the repository. Project preparation now
installs that set before Xcode compiles the asset catalog, and the signed-IPA
contract compares the packaged primary icon's pixels with Tine's source. The
already-submitted0.6.95.8beta is unchanged. -
Dragging a favourite in the sidebar no longer selects its title. The
reorder drag is a pointer gesture, not a text gesture, but nothing suppressed
selection, so the label smeared under the cursor. Applies to both reorderable
sidebar lists. -
The Linked References filter no longer claims to have filtered a list it has
not. While the descendant index is still loading the panel deliberately
shows every reference — the local text it has is only a subset, so hiding a
reference could hide a real match — but the summary still read "N of N
references". It now says indexing is in progress and that the filter applies
when it finishes (GH #173). -
Deleting an open page on Android no longer passes through an unexplained
black frame. Tine still waits for pending edits and the native trash
operation to become durable before navigating anywhere, but it now retires
the deleted page's pane routes in that same durable continuation, before the
loaded page is purged. Debug mode also times confirmation, saving, native
deletion, fallback loading and first paint separately so remaining
device/storage latency can be diagnosed without logging note names or paths
(GH #376). -
Creating a journal no longer makes the next Direct Files page fail to save
on Windows. Windows may report severalCreate,Modify, and rename events
for Tine's own atomic page publication. Those exact self echoes now validate
the published path, bytes, and physical file identity under the same write
lock instead of raising the external-change frontier while the watcher waits
to reconcile them. A changed external file, an identical-byte replacement
inode from a sync service or second Tine, ambiguous events, and portable
case/NFC collisions remain fail-closed (GH #374, follow-up to GH #366). -
Block zoom keeps pointing at the intended block after siblings are inserted
or reordered. Tine now keeps its deterministic, UUID-shaped runtime
locators separate from authoredid::/ Org:id:identity, resolves the
unique authored claimant first, and refuses ambiguous duplicate authored IDs
instead of guessing. Existing graphs are not rewritten (GH #373). -
Windows self-update now follows the system proxy route and shows one update
offer at a time. The native updater already used the Windows trust store,
but its reduced feature set omitted Reqwest's separate Windows system-proxy
integration, so it could fail to fetchlatest.jsoneven while WebView2 and
the browser reached GitHub. Startup and manual checks also now replace the
same release offer instead of stacking duplicate install prompts (GH #241). -
Selecting text on Android no longer stacks Tine's formatting controls under
the system Cut/Copy/Paste menu. Tine's Bold, link, code, highlight and other
formatting actions now dock above the existing mobile keyboard toolbar, while
Android keeps the selection-adjacent region for its native actions and handles.
The compact formatting overflow opens upward, away from the keyboard (GH #375). -
Fitting split panes no longer keep a scrollbar merely for blank editing
space. The first GH #369 correction fixed short panes but still made an
otherwise fitting page scroll whenever it occupied 60–100% of its pane. An
idle pane now has zero blank scroll range at every fitting height; the 40%
pane-relative breathing room returns while a block is actively edited, so a
long page's tail remains comfortably reachable. -
The full Rust core corpus now finishes and the release gate no longer hides
passing tests. Five obsolete shared-join test barriers now pause at current,
finite clean-runtime concurrency cuts. An honest unfiltered run completed all
2,116 selected-or-ignored tests without a hang or timeout, and 47 stale or
passing names were removed from the release exclusion. The remaining 45
known-red legacy-oracle tests are listed exactly and classified by behavior
family, so a newly passing, renamed, or omitted test fails the contract
instead of silently drifting outside the gate (GH #350). -
Managed Storage can reopen retained edits and moves of blocks carrying a
Logseqid::UUID. Projection recovery now consults the same bounded
baseline identity candidates as planning and commit validation, instead of
refusing the accepted block as unauthorized when the UUID originated in the
activation baseline (GH #370). -
Android startup and page navigation no longer look like an unexplained black
or blank screen while work is pending. The native window now has light and
night Tine backing colors before the WebView paints, startup immediately shows
a matching readiness surface, and an in-app page load has a small visible
indicator. Actual load failures still replace it with their error, and plugin
revocation checks still finish before community code can activate (GH #299). -
Clicking a block bullet no longer reports a false same-name file conflict.
A block zoom now keeps using the exact page already open in Direct Files
instead of racing the durable block-ID save with a second read of the page's
older bytes. Restored zoom tabs still load missing owners from disk, and
genuinely different same-name physical files remain fail-closed (GH #354). -
Page action control labels no longer join dragged text selections. The
journal carry-over buttons ("Carry unfinished tasks → today" and friends),
the tag-table toggle, the guide copy button, and the ⋯ page-actions trigger
are page chrome, not content: selecting across the page no longer copies
their label text, while the buttons stay fully clickable and keyboard-
focusable. -
Joining a synced graph no longer gets stuck on an older local managed-storage
marker. If Direct Files is active but a previous activation left private
managed state behind, Tine now archives that complete predecessor unchanged
before bootstrapping the other device's shared identity, instead of trying to
open the old marker as the new graph and reporting that it names a different
catalog document. -
A provider deletion can no longer erase a local edit that arrived in the
same sync pass. Managed sync now captures a pending Markdown or Org watcher
epoch before applying provider projection, then drains the complete visible
provider cut before classifying the resulting race. The local edit therefore
enters immutable history and the normal edit-versus-delete rule settles it,
even when the filesystem and oplog notifications arrive together. -
Direct Files delete, rename, trash, and conflict-copy moves no longer read
every document in the graph. These exact no-clobber moves now validate the
source and destination through retained metadata and portable path checks;
document contents remain untouched and unrelated files are never opened. -
A crash inside a Direct Files save can no longer leave a page invisible
under hidden recovery names. On the next checked open, one unambiguous
stranded copy is restored without clobbering a live file. Ambiguous or
superseded copies are retained or moved intact to recoverable conflict trash;
lookalikes and files whose physical identity cannot be proved are untouched. -
Changed Direct Files saves perform one fewer full-file read. The atomic
retirement already detaches and byte-checks the exact expected inode before
publishing, so Tine no longer rereads the same live name immediately before
that stronger proof. External edits still win or become an explicit conflict,
and managed-storage projection behavior is unchanged. -
Page lists stay fast after Direct Files file lifecycle changes. With a
warm graph, creates, deletes, watcher additions/removals, and renames now
update the exact in-memory page inventory instead of making the next page
lookup reopen and reparse the whole graph. Rename transactions reparse only
documents whose retained final bytes they already changed; explicit titles,
parse failures, physical paths, and watcher invalidation remain authoritative.
Download an installer for your platform below. Windows and Linux ship both x64 and ARM64 builds (match your CPU). Windows users who prefer no installer can grab the portable Tine_*-portable.zip for their architecture. macOS and Windows builds are currently unsigned, so their operating systems may show a warning on first launch. On macOS, if Tine repeatedly asks to access Documents, see the workaround in the README.