* fix: honor the three documented repeater cookie semantics
Logseq's documented repeater semantics (per docs.logseq.com and
`logseq/docs` `Tasks.md`) define three org-mode-style cookies for
recurring tasks:
`.+`: repeats from the last completion date
`++`: advances from scheduled, skipping in whole intervals to future
`+`: advances from scheduled by the declared interval (can stack)
The scheduler in `worker/commands.cljs` has been ignoring the cookie
entirely and applying a single, `++`-like semantic for every
recurring task. A user who wrote `.+1w` in markdown — expecting "a
week from when I actually finished" — silently got `++1w` behavior
("a week from the original scheduled date, skipped to future"),
which for a weekly task scheduled 2026-04-01 and completed on
2026-04-05 returns the next occurrence on 2026-04-08 rather than
the documented 2026-04-12.
This change:
* Adds a closed-values `:logseq.property.repeat/repeat-type` property
with values `:dotted-plus` / `:plus` / `:double-plus`. Default is
`:double-plus` so existing recurring tasks see no behavior change
on upgrade.
* Rewrites the scheduler to branch on repeat-type and implement each
semantic: `.+` anchors on now; `+` advances from original once (can
stack overdue, per org-mode); `++` iterates in whole intervals
until strictly after now. The `++` path is mathematically
equivalent to the previous scheduler, so default-path behavior is
preserved.
* Guards against frequency <= 0 — the old code would silently produce
nonsense and, under the new `++` loop, would spin forever. The
guard short-circuits to `nil`.
* Extracts `resolve-recur-frequency` and fixes the previous
`(or [A B] [C D])` pattern in `compute-reschedule-property-tx` —
any 2-vector is truthy in Clojure, so the default-value branch
was unreachable and entities without an explicit
`:recur-frequency` silently fell through to `frequency = nil`.
`if-let` makes both branches reachable so default-to-1 actually
works at migration time.
* Restores the cookie-type selector that was removed from the
date-time popover in `0a5b88467` (Nov 2020) — in-code support for
all three cookies has been present but not user-pickable for the
last ~5.5 years.
* Adds `docs/recurring-tasks.md` — a technical spec for contributors
and users that restates and augments the upstream `Tasks.md` text,
adds decision guidance, and documents the implementation surface.
* Extends the file-graph → DB-graph migration (built on top of
`44d6bd49c4` "fix: preserve repeated schedule import") to also
carry the cookie kind via a new `repeat-types` map in
`graph-parser/exporter.cljs`, so an imported `.+1w` task lands in
the DB-graph with `:repeat-type.dotted-plus` rather than picking
up the `:double-plus` default. Test updated to assert this.
* Adds deftests covering each cookie's distinctive behavior plus
boundary cases (non-positive frequency, unknown unit, frequency > 1
variants, `++` at month/year units, and both branches of
`resolve-recur-frequency`).
The preexisting `get-next-time-test` passes unchanged under the
`:double-plus` default, preserving the existing regression contract.
Tests pin `t/now` via `with-redefs` for determinism.
Refs #7731, #11260, #6715, #8531. Folds in the small remaining delta
from #12532 (now closed as superseded by `44d6bd49c4`).
* fix: harden recurring task repeat type
* fix: contain repeat type selector
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* fix: handle clamped monthly repeats
---------
Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* fix(lint): make worker/frontend separation lint work on Windows
* chore: update cljs:electron-watch script to include test flag
* chore: remove dead root dependencies
* chore(deps): converge better-sqlite3 to 12.6.2 across deps packages
* chore(deps): converge fs-extra to ^11.3.0 across package roots
* fix(test): correct parameters for create-if-not-exists function
* chore(deps): converge cljs-bean to 1.9.0 across deps roots
* fix(tests): escape regex in cljs:run-test script
* chore: pin root packageManager to yarn 1.22.22
* chore(build): replace del with fs.rmSync in gulp clean
* chore(build): replace npm-run-all with npm-run-all2
* chore(security): upgrade dompurify and unify sanitizer path
* chore(observability): upgrade web sentry to 8.x
* chore: remove unused react-draggable dependencies
* chore(ci): fix windows release artifact collection
* fix(build): create static dir before gulp clean scans it
* fix: update nbb-logseq dependency to version feat-db-v33
* fix(test): move start-time initialization after clone repo
* fix(deps): update nbb dependencies and adjust test script paths to compatible with windows path delimiter
* chore(deps): remove dead meander dependency
---------
Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
When new built-in properties are supported in exporter, all-built-in-names
and file-built-in-property-names should be updated. No need
to handle block/properties-order and block/properties-text-values
as those are ignored
Template blocks were being copied instead of updated in place. Would
feel buggy to user as Template blocks would show up twice in search and
would not be where they had defined them
* Fix import Zotero not recognized as asset
* Fix the inconsistency between imported Zotero label and actual filename
* Import support for zotero linked file like using zotfile
* Fix zotero highlighting block error after importing from file
* compatible with old configuration
* fix zotero picture highlight block does not consider as asset after importing
* Reconstructed to meet bb requirements
* empty datascript to avoid Conflicting upsert error after importing file to db graph
* use external-file-name instead of adding new property
* fix zotero link file can't open in asset page
* compatible with commit 33db791
* compatible with windows path & support zotero path can be relative for ci testing
* add zotero importing test
* remove prn log
* remove useless line
* Revert commit 45ebb9e
Future imports will be performed in the worker, will no longer encounter these issues
* refactor: update today page check to use async block retrieval
* Revert "refactor: update today page check to use async block retrieval"
This reverts commit 6750333df1.
* fix multiline block containing attributes will be truncated and lose data after importing
* fix the issues with block attribute name contains "/" after importing
* standardize eol, all files except .bat files use lf
* compatible with windows path
* fix multiple line importing issues
Also remove the following related file schema
attributes and their dependent code:
:block/marker, :block/priority, :block/scheduled,
:block/deadline,:block/repeated?, :block/pre-block?,
:block/properties-order, :block/properties-text-values, :block/macros,
:block/invalid-properties
Also update validation in DB scripts:
* replace alternative validate-db impl with standard CLI one
* Add validation to import script
* Choose to decouple other DB scripts from validate-db as it may go away
later