diff --git a/README.md b/README.md index 6de7baf12..4dff0bcb3 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ **English** · [简体中文](./README.zh-CN.md) -[![Version](https://img.shields.io/badge/version-v0.0.48-8b5cf6)](./docs/CHANGELOG.md#0048---2026-10-07) +[![Version](https://img.shields.io/badge/version-v0.0.49-8b5cf6)](./docs/CHANGELOG.md#0049---2026-10-09) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) [![Stage](https://img.shields.io/badge/stage-early--access-orange)](./docs/CHANGELOG.md) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/ackness/covel) @@ -13,7 +13,7 @@ Covel is an AI RPG framework and playable studio where NPC relationships, lore, quests, inventory, memory, stage direction, and media can evolve between turns. Its architecture has three clear layers: the **kernel provides primitives and orchestration**, **plugins provide behavior**, and **world packs provide settings, resources, and a default plugin composition**. -> **Source version: v0.0.48**, early access. APIs, world data, and plugin manifests may change between versions. Current binaries target macOS Apple Silicon and Windows x64 and are unsigned; macOS builds are not notarized. Read the [v0.0.48 upgrade notes](./docs/CHANGELOG.md#breaking-changes-and-upgrade-notes-for-v0048) before upgrading: v0.0.48 does not read the data of an earlier version, and sessions saved before it are lost. Versions before v0.0.42 also require the [v0.0.42 upgrade guide](./docs/guide/upgrade-0.0.42.en.md). Existing development data is not automatically migrated; back up affected storage before recreating it. +> **Source version: v0.0.49**, early access. APIs, world data, and plugin manifests may change between versions. Current binaries target macOS Apple Silicon and Windows x64 and are unsigned; macOS builds are not notarized. Read the [v0.0.49 upgrade notes](./docs/CHANGELOG.md#upgrade-notes-for-v0049) before upgrading. Existing v0.0.48 SQLite databases remain readable without deleting data. Upgrades from earlier versions still follow the [v0.0.48 breaking-change notes](./docs/CHANGELOG.md#breaking-changes-and-upgrade-notes-for-v0048); versions before v0.0.42 also require the [v0.0.42 upgrade guide](./docs/guide/upgrade-0.0.42.en.md). Back up affected storage before upgrading; development data is not automatically migrated. ## Highlights diff --git a/README.zh-CN.md b/README.zh-CN.md index e5604e22d..4451d63eb 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -4,7 +4,7 @@ [English](./README.md) · **简体中文** -[![Version](https://img.shields.io/badge/version-v0.0.48-8b5cf6)](./docs/CHANGELOG.md#0048---2026-10-07) +[![Version](https://img.shields.io/badge/version-v0.0.49-8b5cf6)](./docs/CHANGELOG.md#0049---2026-10-09) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) [![Stage](https://img.shields.io/badge/stage-early--access-orange)](./docs/CHANGELOG.md) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/ackness/covel) @@ -13,7 +13,7 @@ Covel 是一套 AI RPG 框架,也是一间可以直接游玩的工作室:NPC 关系、世界典籍、任务、行囊、记忆、舞台调度和媒体都会随回合演化。它有三层清晰分工:**内核提供原语与编排**,**插件提供行为**,**世界包提供设定、资源与默认插件组合**。 -> **当前源码版本:v0.0.48**,早期阶段。API、世界数据和插件 manifest 可能随版本变化。当前二进制面向 macOS Apple Silicon 与 Windows x64,尚未签名,macOS 构建也未公证;升级前请阅读 [v0.0.48 升级说明](./docs/CHANGELOG.md#breaking-changes-and-upgrade-notes-for-v0048):v0.0.48 不读取早期版本的数据,此前保存的会话无法继续。从 v0.0.42 之前的版本升级还需遵循 [v0.0.42 升级指南](./docs/guide/upgrade-0.0.42.md)。已有开发数据不会自动迁移,请在重建受影响的存储前保留完整备份。 +> **当前源码版本:v0.0.49**,早期阶段。API、世界数据和插件 manifest 可能随版本变化。当前二进制面向 macOS Apple Silicon 与 Windows x64,尚未签名,macOS 构建也未公证。升级前请阅读 [v0.0.49 升级说明](./docs/CHANGELOG.md#upgrade-notes-for-v0049)。v0.0.48 的 SQLite 数据库可以继续读取,无需删除数据。更早版本仍需遵循 [v0.0.48 破坏性变更说明](./docs/CHANGELOG.md#breaking-changes-and-upgrade-notes-for-v0048);从 v0.0.42 之前的版本升级还需遵循 [v0.0.42 升级指南](./docs/guide/upgrade-0.0.42.md)。升级前请保留完整备份,开发数据不会自动迁移。 ## 亮点 diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 41ba541ac..7f2116989 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@covel/desktop", - "version": "0.0.48", + "version": "0.0.49", "private": true, "type": "module", "main": "dist/main.mjs", diff --git a/apps/server/package.json b/apps/server/package.json index ed634258c..41692a9a3 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -1,6 +1,6 @@ { "name": "@covel/server", - "version": "0.0.48", + "version": "0.0.49", "private": true, "type": "module", "files": [ diff --git a/apps/web/package.json b/apps/web/package.json index 07a619af1..eaacfe6c1 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@covel/web", - "version": "0.0.48", + "version": "0.0.49", "private": true, "deprecated": false, "type": "module", diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 2d96baffd..8e243c23e 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. Follows [Ke ## [Unreleased] +## [0.0.49] - 2026-10-09 + +This release fixes session recovery, background-task status, streaming retries, plugin and storage boundaries, and desktop layout issues. SQLite now uses Node's built-in driver while retaining the existing database format. macOS Apple Silicon and Windows x64 binaries are unsigned; the macOS build is not notarized. Read the [upgrade notes](#upgrade-notes-for-v0049) before installing. + ### Added - **Recorded scripted sessions replay in one command, on any machine.** `pnpm e2e:replay` plays each session under `tests/llm-replay/` against its recording: it starts the replay proxy, a test server with a new database, its own home directory, the session's random seed and UTC, then `scripts/e2e-plugin-verify.ts`, and stops them. The server reads nothing from `.env`, `~/.covel` or the shell's `COVEL_*` variables, so another checkout sends the same requests; any request missing from the recording fails the run. Recordings are committed, one answer per request named after its digest. `--record --upstream ` records a session again: answers already recorded are reused, only new requests reach the model, and answers the session no longer asks for are removed. `pnpm llm:replay` stays for ad-hoc recordings under `debugs/`. The `lantern-barrow` session is defined but not recorded yet: record it with `pnpm e2e:replay --record --upstream https://api.deepseek.com lantern-barrow`. Verified with a fake model on a session that stopped at character creation (8 requests, all answered in a copy of the repository at another path, with another `HOME`, time zone and `LANG`); not yet verified on a recorded three-turn session. See `docs/guide/e2e-plugin-verify.md`. @@ -21,9 +25,7 @@ All notable changes to this project will be documented in this file. Follows [Ke ### Fixed - **A filled opening form no longer repeats a full stop supplied by both the field and its template.** Narrative interpolation omits a template `.` or `。` immediately after a value already ending with that character. Stored player input and punctuation within the value remain unchanged. - - **Completed background tasks no longer accumulate as failed turns below the story.** Restoring a worker's model reasoning created a separate foreground task that was then marked interrupted, even when its durable job had committed successfully. The timeline now joins worker traces to the job's source turn using `backgroundTurnId`, preserves the durable outcome, and deduplicates reasoning across refreshes and either hydration order. Actual job failures remain visible under their source task. - - **A suspension can be resumed again after the server stopped in the middle of resuming it.** The claim a resume takes was never released when the process ended first, so every later resume answered 409 and the player could only abandon it. The claim is now released at the next server start (SQLite) or after one hour (PostgreSQL). `DataStore` gains `releaseStaleSuspensionClaims`. - **A settled tabletop check reaches the narrative without row IDs.** The check text the narrators read carried the form submission ID and the turn ID of the stored receipt. It now carries the check only: action, attribute, modifier, die, difficulty, total and outcome. - **A media download drops a redirect's body unread.** `ctx.media.ingestUrl` read the whole body of each 3xx response, which `maxBytes` did not limit. @@ -80,6 +82,13 @@ All notable changes to this project will be documented in this file. Follows [Ke - **`pnpm e2e:verify` runs without `.env` and `.env.llm`.** It required both files although the harness reads no provider key (the server does), so it could not start where the keys are environment variables. It now loads each file only when present, like `pnpm i18n`. The plugin-testing guide's example passed `--plugins`, which the harness rejects; it now passes `--plugin`. - **A missing user worlds directory takes one line in the server log.** On a fresh install `$COVEL_HOME/worlds` does not exist until the first world is installed, and the seeder and the file watcher each printed an `ENOENT` stack trace for it. The directory still counts as an unscanned source, so stale worlds are still kept until a complete scan. +### Upgrade notes for v0.0.49 + +- **Upgrading from v0.0.48 does not require deleting SQLite data.** Existing `covel.db` files remain readable after the switch to `node:sqlite`; this release adds no data migration. Keep a backup before upgrading. Upgrades from versions before v0.0.48 still need the [v0.0.48 breaking-change notes](#breaking-changes-and-upgrade-notes-for-v0048), and versions before v0.0.42 also need the [v0.0.42 guide](./guide/upgrade-0.0.42.en.md). +- **Custom storage backends must implement `DataStore.releaseStaleSuspensionClaims(olderThanIso): Promise`.** Built-in backends already release abandoned resume claims according to their startup and expiry policy. +- **Plugin host ranges are enforced at startup and reload.** A plugin whose declared `covel` range excludes `0.0.49` will not run; authors should test the package and update its range when supported. Plugins without a range keep their existing behavior. +- **Desktop downloads are unsigned.** macOS builds are also not notarized, so the operating system may require first-launch confirmation. There is no signing or notarization claim for these artifacts. + ## [0.0.48] - 2026-10-07 This release lays out the prompt so that a provider's prefix cache reaches the history, keeps IDs and timestamps out of what a model reads, settles more of the slips for which a tool refused a model's call, adds sessions that replay from recorded model calls, and fixes the findings of a whole-codebase audit. **It does not read the data of an earlier version**: read the [upgrade notes](#breaking-changes-and-upgrade-notes-for-v0048) before installing it. diff --git a/package.json b/package.json index 3b7f3fe97..549d63b54 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "covel", - "version": "0.0.48", + "version": "0.0.49", "private": true, "type": "module", "scripts": { diff --git a/packages/ai-provider/package.json b/packages/ai-provider/package.json index 7a0a7e670..f524827af 100644 --- a/packages/ai-provider/package.json +++ b/packages/ai-provider/package.json @@ -1,6 +1,6 @@ { "name": "@covel/ai-provider", - "version": "0.0.48", + "version": "0.0.49", "private": true, "type": "module", "exports": { diff --git a/packages/approval/package.json b/packages/approval/package.json index 37b06b466..f9bf3a3af 100644 --- a/packages/approval/package.json +++ b/packages/approval/package.json @@ -1,6 +1,6 @@ { "name": "@covel/approval", - "version": "0.0.48", + "version": "0.0.49", "private": true, "type": "module", "exports": { diff --git a/packages/context/package.json b/packages/context/package.json index 485306f1b..6bffde792 100644 --- a/packages/context/package.json +++ b/packages/context/package.json @@ -1,6 +1,6 @@ { "name": "@covel/context", - "version": "0.0.48", + "version": "0.0.49", "private": true, "type": "module", "exports": { diff --git a/packages/create/package.json b/packages/create/package.json index 3fa2d2540..e9700fddd 100644 --- a/packages/create/package.json +++ b/packages/create/package.json @@ -1,6 +1,6 @@ { "name": "@covel/create", - "version": "0.0.48", + "version": "0.0.49", "private": true, "type": "module", "exports": { diff --git a/packages/events/package.json b/packages/events/package.json index c5e7d590e..b11ab29c4 100644 --- a/packages/events/package.json +++ b/packages/events/package.json @@ -1,6 +1,6 @@ { "name": "@covel/events", - "version": "0.0.48", + "version": "0.0.49", "private": true, "type": "module", "exports": { diff --git a/packages/memory/package.json b/packages/memory/package.json index 84825050a..97a3e9404 100644 --- a/packages/memory/package.json +++ b/packages/memory/package.json @@ -1,6 +1,6 @@ { "name": "@covel/memory", - "version": "0.0.48", + "version": "0.0.49", "private": true, "type": "module", "exports": { diff --git a/packages/plugin-handlers-utils/package.json b/packages/plugin-handlers-utils/package.json index 02af78789..793a810dc 100644 --- a/packages/plugin-handlers-utils/package.json +++ b/packages/plugin-handlers-utils/package.json @@ -1,6 +1,6 @@ { "name": "@covel/plugin-handlers-utils", - "version": "0.0.48", + "version": "0.0.49", "type": "module", "exports": { ".": { diff --git a/packages/plugin-loader/package.json b/packages/plugin-loader/package.json index bd5244e0d..be5d2b721 100644 --- a/packages/plugin-loader/package.json +++ b/packages/plugin-loader/package.json @@ -1,6 +1,6 @@ { "name": "@covel/plugin-loader", - "version": "0.0.48", + "version": "0.0.49", "private": true, "type": "module", "exports": { diff --git a/packages/plugin-test-utils/package.json b/packages/plugin-test-utils/package.json index c863312e4..d32f49e71 100644 --- a/packages/plugin-test-utils/package.json +++ b/packages/plugin-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@covel/plugin-test-utils", - "version": "0.0.48", + "version": "0.0.49", "private": true, "type": "module", "exports": { diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 3d0350ff5..b8866330e 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,6 +1,6 @@ { "name": "@covel/runtime", - "version": "0.0.48", + "version": "0.0.49", "private": true, "type": "module", "exports": { diff --git a/packages/settings/package.json b/packages/settings/package.json index 57f2c261c..5ca038259 100644 --- a/packages/settings/package.json +++ b/packages/settings/package.json @@ -1,6 +1,6 @@ { "name": "@covel/settings", - "version": "0.0.48", + "version": "0.0.49", "private": true, "type": "module", "exports": { diff --git a/packages/shared/package.json b/packages/shared/package.json index 1ecc2a5cc..d72abfe88 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@covel/shared", - "version": "0.0.48", + "version": "0.0.49", "private": true, "type": "module", "exports": { diff --git a/packages/store/package.json b/packages/store/package.json index 53f0d75a1..ba5def9ec 100644 --- a/packages/store/package.json +++ b/packages/store/package.json @@ -1,6 +1,6 @@ { "name": "@covel/store", - "version": "0.0.48", + "version": "0.0.49", "type": "module", "private": true, "exports": { diff --git a/packages/test-runtime/package.json b/packages/test-runtime/package.json index e896e784a..03ca2d37f 100644 --- a/packages/test-runtime/package.json +++ b/packages/test-runtime/package.json @@ -1,6 +1,6 @@ { "name": "@covel/test-runtime", - "version": "0.0.48", + "version": "0.0.49", "private": true, "type": "module", "bin": { diff --git a/packages/tools/package.json b/packages/tools/package.json index 2f10d230d..dce77b971 100644 --- a/packages/tools/package.json +++ b/packages/tools/package.json @@ -1,6 +1,6 @@ { "name": "@covel/tools", - "version": "0.0.48", + "version": "0.0.49", "private": true, "type": "module", "exports": {