Skip to content

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 28 Sep 06:47
· 394 commits to main since this release
262b163

Warning

English: v0.7.0 removes custom workflows. A migration tool preserves
definitions and triggers for review and can convert exact preset matches,
but it cannot guarantee a complete reproduction of your workflows. If you
use custom workflows, back up config/ before upgrading.

**简体中文:**v0.7.0 移除了自定义工作流。迁移工具会保留定义和触发器供检查,
并可转换与内置预设完全匹配的工作流,但不能保证完整复现原有工作流。
如果使用了自定义工作流,请在升级前备份 config/。

**繁體中文:**v0.7.0 移除了自訂工作流程。遷移工具會保留定義與觸發器供檢查,
並可轉換與內建預設完全相符的工作流程,但無法保證完整重現原有工作流程。
如果使用了自訂工作流程,請在升級前備份 config/。

**日本語:**v0.7.0 ではカスタムワークフローを削除しました。移行ツールは定義と
トリガーを確認用に保存し、組み込みプリセットと完全に一致するものは変換できますが、
元のワークフローを完全に再現できる保証はありません。カスタムワークフローを
使用している場合は、アップグレード前に config/ をバックアップしてください。

한국어: v0.7.0에서 사용자 지정 워크플로를 제거했습니다. 마이그레이션 도구는
정의와 트리거를 검토할 수 있도록 보존하고 기본 프리셋과 정확히 일치하는 항목을
변환할 수 있지만, 기존 워크플로의 완전한 재현은 보장하지 않습니다. 사용자 지정
워크플로를 사용 중이라면 업그레이드 전에 config/를 백업하세요.

Important

Upgrade notes. Back up config/ before upgrading. Keep the existing
data/ mount; the version upgrade does not require copying it.
Existing v0.6.1 databases advance from schema 034 through numbered migrations
035–044; fresh installs use baseline/044_v0.7.0.sql. Do not replace an
existing database with a fresh-install baseline.

Migration 035 removes user-authored workflow definitions and triggers. The
upgrade hook preserves them for review before applying that migration, but
instances that already passed 035 need a pre-035 database backup to recover
definitions removed by an earlier build. Run history remains in Activity.

Migration 038 adds a derived card-summary cache for
metadata snapshots and queues every existing snapshot. The server fills it in
small background batches after startup; lists stay correct while it drains.

Migration 039 disables every Follow a circle, Follow a series, and Follow a
voice actor trigger, because their options changed (Track, Fetch, the new
works switch, and the metadata refresh choice were removed). Each disabled
trigger shows that it needs reconfiguring: open it, check its Run options,
save it, and turn it on again. Manual runs are unaffected.

Migration 041 adds the creator lookup expression indexes and the missing
foreign-key child indexes used by cleanup cascades.

By default KIKOTO_ROOT_PASSWORD no longer sets the administrator password on
every start. Existing accounts keep their current passwords, so the root
account still signs in with the last applied value and can now change it in
Settings. Remove KIKOTO_ROOT_PASSWORD from .env; Kikoto logs a warning
while it is set. To keep the previous behavior, set
KIKOTO_ROOT_ACCOUNT_MODE=environment instead. Update docker-compose.yml
either way, because the previous file neither passes the new variables nor
starts without KIKOTO_ROOT_PASSWORD.

Migration 040 signs everyone out once, in browsers and in the Android app,
because sessions are now stored as digests and the existing plaintext
sessions are deleted. Sign in again after upgrading.

Migration 042 keeps only the two latest stored snapshots of each circle,
which may make the database noticeably smaller after the next Compact
database. The first start after upgrading re-derives voice credits and
circles from every work's metadata once in the background; later starts and
metadata syncs only process works whose metadata changed.

Migration 043 adds durable account-owned listening history without inferring
duration for old play events. Migration 044 stores preserved workflow review
data and resumable library-layout migration state.

Kikoto v0.7.0 replaces custom workflow editing with built-in presets and
adds library storage pools, first-run setup, database backups, personal data
transfer, and persistent listening history. It also improves Fetch recovery,
search, playback, and startup performance.

Custom Workflow Migration

  • The custom workflow canvas, user-authored definitions and triggers, slash
    commands, and definition run dialog are removed. Built-in workflows remain
    available for manual runs and automation.
  • During an upgrade from a pre-035 database, Kikoto saves user-authored
    definitions and triggers for review before migration 035 deletes the active
    copies. Exact preset matches can be converted into disabled triggers for
    reconfiguration; other definitions can be exported. Run history remains
    readable in Activity. Conversion does not promise equivalent behavior.

Personal listening and data

  • Android pauses when headphones disconnect, including in the background, and
    does not automatically resume on reconnection.
  • Sleep timers can rewind 0–120 minutes within the current track after pausing,
    including finish-current-track, and preserve the rewound cursor.
  • Personal tag management supports rename, merge, delete and unused-tag cleanup for work,
    circle and voice tags. New workflow defaults reuse tags without a date;
    existing saved templates keep their behavior.
  • Listening history persists independently of 90-day recommendation cleanup.
    Only measured listening contributes duration; remaining legacy play events
    are preserved without inferred time.
  • Data transfer previews and imports versioned personal JSON and Kikoeru review
    state, matching existing work codes and offering keep/overwrite choices.
    Export contains personal work state, playlists and custom tags.

Accounts

  • Sign-in attempts are throttled, and Argon2id memory use is bounded during
    password verification.

  • A new production instance no longer needs a password in .env. The web app
    shows Set up Kikoto, and the first administrator is created with a
    one-time setup token from the service log or config/setup-token, so a
    client that can only reach the port cannot claim the instance.

  • docker compose exec kikoto /app/kikoto admin reset-password resets a
    forgotten administrator password from the host while Kikoto runs. It prints
    a new password, restores the account as an enabled super administrator, and
    signs it out everywhere.

  • A reset targets the initial administrator by default. When it no longer
    exists, the account must be named with --username or
    KIKOTO_ROOT_USERNAME; the error lists the super administrators. A named
    account must exist, except root, which is created so an instance with no
    usable administrator can still be recovered.

  • Without shell access, KIKOTO_ROOT_PASSWORD_RESET=true applies
    KIKOTO_ROOT_PASSWORD once at startup. Restarting with the same values does
    not undo a password changed later in Settings.

  • KIKOTO_ROOT_ACCOUNT_MODE=environment keeps the root account defined by
    KIKOTO_ROOT_USERNAME and KIKOTO_ROOT_PASSWORD on every start, as before,
    and locks its password, role, enabled state, and deletion in the app. The
    password reset switch and the reset command do not apply to that account.

  • In the default setup mode the initial administrator is managed like any
    other super administrator: it can change its own password, and another super
    administrator can change its role or delete it.

  • New passwords must have at least 8 characters and must not be a value that
    appeared in the documentation.

  • The database and its backups store only a SHA-256 digest of each session
    token, so a copied database or backup can no longer be used to sign in.

  • The Android app is excluded from Android cloud backup and device-to-device
    transfer, so its stored session no longer leaves the device in a backup. A
    restored or transferred app asks for the server and sign-in again.

Workflows

  • Follow a circle, Follow a series, and Follow a voice actor are organized as
    Input, Filter, and Actions. Input is the target and the catalog refresh
    (Incremental or Full). Filter holds a release date range and a work limit,
    both off by default. Actions are Sync metadata for catalog works that lack it,
    the tag, and for circles Check remote sources.
  • Without a filter, a follow syncs every catalog work that lacks metadata. The
    trigger popover warns before saving an automated follow without a filter and
    recommends turning one on.
  • Track and Fetch are no longer follow actions, and a follow no longer refreshes
    the metadata of works that already have it.
  • Metadata sync can refresh all works, one circle's works, or one voice actor's
    works, either only missing or outdated metadata or all of it. Scheduled
    metadata sync triggers keep their previous behavior until edited.
  • The release date filter now uses the catalog's release date for works not yet
    in the library, so a release range no longer filters out every new circle or
    series work.
  • Circle and voice actor detail refreshes keep their behavior.
  • A trigger popover that stays open while you select another workflow tab now
    saves to the workflow it was opened for. Before, a new trigger could be
    created on the other workflow, or an edited one moved there with options in
    the wrong shape.
  • Recover stale workflow runs no longer disturbs a job that is still running:
    it could return that job to the queue so it ran a second time, and it failed
    queued jobs that could not resume, such as a database optimization. It now
    requeues or fails only jobs with no running executor.
  • A job whose heartbeat is delayed, for example by a busy database, is no
    longer returned to the queue while it is still running.
  • A job whose executor stopped without recording a result, including after a
    transient source error, is now marked failed or retried instead of staying
    running and blocking every other job until a restart.
  • The new Refresh local work files workflow, second after Scan local library,
    indexes the media files inside discovered local work folders ahead of time.
    Incremental covers folders that were never indexed and Full re-indexes every
    local work. It runs manually or from a Startup or interval trigger.
  • Editing a trigger while its remote sources are still loading no longer loses
    the action, limit, or tag template you changed; the loaded sources only fill
    an empty source choice.

Fetch

  • A queued or running Fetch is shared per canonical work, so repeated requests
    reuse its run instead of downloading the same work twice.

  • Retrying a Fetch whose files were already published, but whose result could
    not be recorded, no longer replaces the work folder with only the newly
    selected files. The retry recognizes the published folder and continues from
    it.

  • Fetch never deletes an existing publication backup. If one is still present,
    publishing stops and asks for review instead.

  • A Fetch interrupted while registering its published files now completes at
    the next startup, including Fetches left in that state by earlier versions.
    A Fetch that still cannot be recovered is reported in Activity and no longer
    stops the server from starting.

  • Activity names each Fetch after its work, such as Fetch RJ00000001, finds
    it by work code, and records whether it was queued by Availability Watch, a
    bulk action, a popular collection, or a preset workflow. Workflows lists Fetch
    as a read-only tab with its history.

  • When Fetch cannot write into the library, it says what to configure and links
    to Settings -> Library instead of failing the plan.

  • A Fetch run's detail lists its files: the file being downloaded stays on top
    with its own progress bar, and the expanded list shows which files are done,
    waiting, or where the run failed or paused.

  • While a dialog is open, the page behind it no longer scrolls, whether the
    wheel is over a list that reached its end, the dialog header, or the
    backdrop. The page keeps its position and width.

  • Retrying or resuming a Fetch no longer counts the files it already cached or
    staged against free space, so a retry after a partial run is not refused for
    space it already holds.

  • A Fetch that fails while assembling or verifying its staged files marks that
    step as failed; Publish no longer reports the error while Assemble still
    shows as running.

  • Fetch stages files in bounded chunks instead of one whole-file copy call, and
    database writes wait up to 30 seconds for a competing writer instead of 5.
    On hosts where writing large files briefly stalls the database, such as
    Docker Desktop bind mounts, a Fetch no longer fails with "database is locked"
    while it assembles its staging directory.

  • When a Track finishes, Library refreshes the page, filters, and sort you are
    viewing. Before, after changing page or filter it could reload the results
    from when the list was first opened.

Library Storage

  • Viewers can choose which available source types appear in the Library source
    bar. Bulk work selection now uses a shared toolbar with a tri-state checkbox
    and reviewed Fork and Fetch actions.

  • A new instance opens Set up your library after the administrator is
    created: choose the Standard layout or Storage pools, scan, optionally sync
    metadata, and decide whether scans run on startup or when folders change.
    Both scan triggers now start off on a new install. Upgraded instances keep
    the Standard layout and their triggers, and skip the setup.

  • Storage pool mode treats selected first-level folders of the data directory
    as separate disks or cloud drives. Fetch saves new works to the chosen Fetch
    pool and keeps its staging, backup, and trash inside the target's pool, so
    publication stays a rename on one disk.

  • An unmounted data directory or offline pool no longer makes a scan report the
    whole library missing. Kikoto marks each pool root with .kikoto-pool; an
    empty, unmarked root of a library with works fails the scan without changes,
    and an offline pool is skipped and named in a partial run.

  • Scans always reach the level where Fetch saves works, and Settings rejects a
    shallower scan depth, so a shallow depth no longer reports Fetched works
    missing.

Tags

  • Works, circles, and voice actors edit personal tags in a searchable picker
    instead of a comma-separated field: a popover on desktop and a bottom sheet
    on mobile. Type to filter your existing tags for that kind of item, press
    Enter to create one, and check or uncheck a tag to add or remove it. Each
    change saves immediately, and a tag you uncheck stays listed until the picker
    closes so it can be checked again.

Circles And Voice Actors

  • Opening a circle that is not in the database no longer adds it.
    Administrators are offered Follow a circle with the circle ID filled in;
    other users are asked to contact an administrator. When a first fetch fails,
    the circle it started is removed, so a mistyped circle ID no longer stays in
    the circle list.
  • A Follow run form opened from a circle or voice actor page notes which
    target it filled in.
  • A voice actor page that does not exist explains that syncing the metadata of
    any of their works creates it, or asks you to contact an administrator.
  • Opening a work's circle, series, or voice actor link fetches missing
    metadata from DLsite only for users who can sync metadata. Other users open
    links the site already stores and are otherwise asked to contact an
    administrator.
  • The circle and voice actor lists no longer fail in a library with more than
    about 32,000 circles or voice actors.

Playback

  • Reloading or restarting the app no longer resets Resume progress to 0:00. A
    restored track saves progress only after it starts playing or you seek in it,
    so hiding the page, locking the device, or switching tracks before that no
    longer overwrites the saved cursor.
  • A reloaded queue continues its current track from the saved cursor when that
    cursor points at the same track and is unfinished.
  • A Resume or reload start position that is still loading carries over when
    playback falls back to another source, instead of restarting at 0:00.
  • In loop mode, Next from the system media controls or the Android
    notification on the last track wraps to the first track, and those controls
    always act on the current queue and mode.

Favorites

  • Changing lists for selected works no longer replaces each work's existing
    list membership. The list picker shows whether all, some, or none of the
    selected works are in each list, and saves only the lists you change, in one
    transaction.

Performance

  • Library search uses a folded FTS5 trigram index for more responsive
    matching. Large index backlogs now drain in the background.

  • The player dock has a redesigned compact and full view, queue reordering,
    and next-track preload. The frontend now uses React 19 and keeps mobile
    browsing tabs mounted for faster switching.

  • Library and voice lists read a compact per-snapshot card summary instead of
    decoding every work's full DLsite snapshot.

  • SQLite connections use synchronous=NORMAL, a 16 MiB page cache, and a
    256 MiB memory map per connection.

  • The bundled frontend's hashed assets are cached as immutable, while the app
    shell, service worker, and manifest are revalidated. JSON and text responses
    are gzip-compressed for clients that accept it; media, Range, event-stream,
    and authentication responses are unchanged. The split-deployment nginx
    configuration gets matching compression and asset caching.

  • Concurrent requests for the same work detail share one request.

  • The player's playback clock is published separately, so only progress,
    lyrics, and sleep-timer displays re-render during playback.

  • Circle and voice actor details, voice alias search, the voice remote
    catalog, and remote Fetch source options no longer query the database while
    still holding a connection for their own results. A few of these requests at
    once could take every database connection and stall the whole site,
    including sign-in and background jobs.

  • An API request that has not started responding within 60 seconds is
    cancelled with a retryable "service unavailable" error instead of waiting
    forever for a database connection. Media transcodes, remote-source
    operations, and filesystem maintenance keep their longer running time, and
    streams are unaffected once they start. The server log reports a database
    connection pool that stays exhausted, and when it recovers.

  • The web app's framework libraries load from a separate chunk that stays
    cached across releases, and the circle, voice actor, and work detail pages
    load the Fetch dialog only when it opens.

  • The header logo uses a small icon instead of the 512-pixel app icon.

  • Each web app build uses its own offline cache, and installing a new build
    removes the previous build's cached files instead of keeping them forever.

  • Query planner statistics are refreshed at startup, daily, and after each full
    scan and metadata sync, not only by Compact database. A new install's
    Library no longer stays slow until the database is compacted.

  • A full library scan commits every 250 folders instead of holding the
    database for the whole library, so saving playback progress during a large
    scan no longer fails as busy. Folders that did not change are not rewritten.

  • Startup and metadata sync no longer re-derive voice credits and circles for
    the whole library. Only works whose metadata changed are processed, and a
    change that leaves voice actors and circles as they were, such as a new
    sales count, does not rebuild everyone's recommendations.

  • Circle refreshes no longer store a new circle snapshot every time; each
    circle keeps its two latest.

  • Searching no longer waits while a large backlog of changed works is
    re-indexed, such as after a bulk metadata sync. The index catches up in the
    background, and a small number of changes is still searchable immediately.

Maintenance

  • Demo mode can showcase tracked works and workflow Activity while keeping
    administration surfaces read-only.

  • Kikoto now backs up its database. Before upgrading an existing database it
    writes a verified snapshot to config/backups and stops the upgrade if the
    snapshot fails. It also keeps a daily automatic backup, and Settings ->
    Cleanup can back up on demand and shows the latest backup. See
    Database backups for retention and
    restore steps.

  • Compact database runs in the background as a workflow shown in Activity.
    Only one can be queued or running at a time, and the result is still recorded
    in the audit log.

  • Expired sessions and old workflow runs are cleaned up automatically shortly
    after startup and then daily, with the same retention rules as manual
    cleanup.

  • Stopping or upgrading the container now shuts down gracefully: in-flight
    requests finish, and a running workflow job returns to the queue without
    spending a retry, instead of being recovered as if the service had crashed.
    The drain is bounded by the new KIKOTO_SHUTDOWN_TIMEOUT_SECONDS (default
    20). The bundled Compose files set stop_grace_period: 30s; add the same to
    a custom Compose file, because Docker's default 10 seconds can kill the drain.

  • The update check now reports only published GitHub Releases, so a version
    is no longer announced while its image and APK are still being published.

  • A release pushes the Docker image, including latest, only after the
    Android APK has also built, and publishes the GitHub Release last.

  • The Docker image now installs the current Debian security updates for
    ffmpeg and ca-certificates each time it is built, instead of fixed
    package versions that had stopped receiving fixes.

Accessibility And Translation

  • Dialogs keep keyboard focus inside the top-most dialog.
  • The player seek bar and cache usage meter announce readable values.
  • Translate the Workflows page strings that previously fell back to English in
    Japanese, Korean, and both Chinese locales.