diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d1af86..1eb4486 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,31 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +## [2.1.1] - 2026-07-11 + +### Changed + +- Updated the verified runtime baseline to ZCode 3.3.4 (build 3.3.4.2877) and + CLI 0.15.2. Repinned all six macOS and Linux artifacts by exact filename, + byte size, SHA-512 digest, native architecture, package identity, bundle + identity, Developer ID team, and notarization evidence. +- Bumped the public build and `nddev-builder/core` component to 2.1.1 without + changing the product-contract or installed-stamp schema. + +### Fixed + +- Preserved `v2/tasks-index.sqlite` together with `cli/db/` during setup + installation and switching, preventing the desktop task index from becoming + detached from the restored CLI session database. +- Preserved legacy `v2/sessions/` snapshots when present so ZCode's supported + session-migration path remains available after setup changes. +- Preserved current and legacy bot definition state while continuing to omit + derived bot-model, coding-plan, telemetry, log, crash, rollout, and execution + caches from newly rendered setups. +- Refused apply-mode install, switch, remove, and restore operations while the + task/session databases are open or SQLite recovery sidecars are present, + preventing inconsistent cross-store snapshots of a running ZCode instance. + ## [2.1.0] - 2026-07-10 ### Added diff --git a/README.md b/README.md index 53f245b..b987031 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ changes. - **Author:** Danil Silantyev (github:rldyourmnd), CEO NDDev - **License:** AGPL-3.0-or-later -- **Build version:** 2.1.0 -- **Verified ZCode runtime:** app 3.3.3, CLI 0.15.0, model GLM-5.2 +- **Build version:** 2.1.1 +- **Verified ZCode runtime:** app 3.3.4, CLI 0.15.2, model GLM-5.2 ## What this repository contains @@ -49,6 +49,7 @@ cli-tools/scripts/install.sh bootstrap --apply cli-tools/scripts/install.sh list cli-tools/scripts/install.sh list --json cli-tools/scripts/install.sh install --setup nddev-builder --plan +# Quit the ZCode desktop app before apply-mode target changes. cli-tools/scripts/install.sh install --setup nddev-builder --apply cli-tools/scripts/install.sh status cli-tools/scripts/install.sh status --json @@ -57,8 +58,9 @@ cli-tools/scripts/install.sh status --json Plan mode performs no writes and does not invoke a locally installed `zcode` binary. It still parses and merges config, setting, provider, MCP, and hook inputs and rejects unresolved active placeholders in keys or values. Setup -installation in apply mode performs a bounded live runtime probe before it -changes the target. +installation in apply mode performs a bounded live runtime probe and rejects +open task/session databases or SQLite recovery sidecars before it changes the +target. See [docs/install.md](docs/install.md) for install, update, switch, backup, restore, remove, and custom-target usage. @@ -94,10 +96,12 @@ Apply operations rotate at most 10 backups under `~/.zcode-backups/`: --old.zcode N = 0..9 ``` -Credentials, certificates, sessions, databases, and runtime artifacts are -selectively restored during an update or switch. Logs, crash data, and plugin -caches are regenerated. Destructive restore/remove operations refuse targets -that are not marked by this installer with `BUILD-VERSION`. +Credentials, certificates, the desktop task index and legacy session snapshots, +bot definitions, CLI session databases, and runtime artifacts are selectively +restored during an update or switch. Logs, crash data, transient execution +data, model I/O rollouts, telemetry, and caches are regenerated. Destructive +restore/remove operations refuse targets that are not marked by this installer +with `BUILD-VERSION`. Install also refuses an existing unstamped target unless the user supplies both `--adopt-unmanaged` and an explicit existing `--target`. Adoption stores the diff --git a/VERSION b/VERSION index 7ec1d6d..3e3c2f1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1.0 +2.1.1 diff --git a/build/manifest.json b/build/manifest.json index 04adc1c..74b2c9b 100644 --- a/build/manifest.json +++ b/build/manifest.json @@ -1,6 +1,6 @@ { "name": "nddev-zcode-app", - "build_version": "2.1.0", + "build_version": "2.1.1", "source_root": "zcode_tools/marketplaces/", "installer": "cli-tools/scripts/install.sh install --setup ", "layout": { @@ -78,6 +78,7 @@ "path_boundaries": "canonical non-root target and backup roots must be disjoint absent-or-real-directory endpoints on one filesystem", "safe_tree": "managed inputs reject symlinks, special files, and multiply-linked regular files", "locking": "exclusive target lock and exclusive lock for the shared backup pool, acquired in deterministic order", + "runtime_quiescence": "apply-mode target mutations reject open task/session databases and SQLite recovery sidecars; ZCode must be quit cleanly before setup changes", "staging": "render, restore selected state, normalize permissions, verify, and fsync a same-filesystem sibling stage before live replacement", "commit": "identity-bind and hold an occupied backup slot, move the previous target into its backup, then atomically rename the verified stage without replacement", "rollback": "restore only identity-matched previous-target and held-slot state if commit, a handled signal, or pre-commit finalization fails; identity mismatch preserves foreign state, recovery paths, and locks; post-commit housekeeping failure is reported without discarding committed state", @@ -92,15 +93,26 @@ "always_restore": [ "v2/credentials.json", "v2/certs/", + "v2/tasks-index.sqlite", + "v2/sessions/", + "v2/bot-config.json", + "v2/bot-state.json", + "v2/bot-state.v2.json", "cli/agents/", "cli/db/", "cli/artifacts/" ], "never_restore": [ "cli/log/", + "cli/exec/", + "cli/rollout/", "v2/logs/", "v2/crash/", - "cli/plugins/cache/" + "cli/plugins/cache/", + "v2/bots-model-cache.json", + "v2/bots-model-cache.v2.json", + "v2/coding-plan-cache.json", + "v2/telemetry-state.json" ] }, "secrets": { diff --git a/build/version.json b/build/version.json index 0a08e6f..593c243 100644 --- a/build/version.json +++ b/build/version.json @@ -1,53 +1,53 @@ { - "build_version": "2.1.0", - "zcode_app_version": "3.3.3", - "zcode_cli_version": "0.15.0", + "build_version": "2.1.1", + "zcode_app_version": "3.3.4", + "zcode_cli_version": "0.15.2", "zcode_runtime": "GLM-5.2", "zcode_cdn_base": "https://cdn-zcode.z.ai/zcode/electron/releases", "zcode_download_artifacts": { "macos-arm64": { - "filename": "ZCode-3.3.3-mac-arm64.dmg", - "size_bytes": 161495574, - "sha512": "5434a525bc03adc274672ad2c9f83d6ebde67ec596ff55d1be0adc426c87731e657a0bf1db637000192491befee37fd34237eaa1b136f8c91b7da38b30fd7078", + "filename": "ZCode-3.3.4-mac-arm64.dmg", + "size_bytes": 161523919, + "sha512": "41d4d7bba64d7db8a12c5dbc8808cc44cefc67c43b84c8d7622d32a132bbbefac4af08724427223b807ad202f12863f3d310b01f1c2c12200ba6ff463db6513c", "team_id": "8A5X4JJ39T", "bundle_id": "dev.zcode.app", - "app_version": "3.3.3", - "bundle_version": "3.3.3.2657" + "app_version": "3.3.4", + "bundle_version": "3.3.4.2877" }, "macos-x64": { - "filename": "ZCode-3.3.3-mac-x64.dmg", - "size_bytes": 169792747, - "sha512": "22a179a23573fdcca08bc2a483ad4ab6df652d6e4af7b51a2ba79b101aad3f4e59aa894617c1bb9cd8a96cce0b93c0d123780400a6bd1d80126b99f83526846a", + "filename": "ZCode-3.3.4-mac-x64.dmg", + "size_bytes": 169797960, + "sha512": "8e20c7d9534ac34775a027252b492ef854b62a30ba83d63d677028476d76e07be4159ea3792e1fe2300384a32d0f500ef4d23955b1202cc661df41a03ac1fe96", "team_id": "8A5X4JJ39T", "bundle_id": "dev.zcode.app", - "app_version": "3.3.3", - "bundle_version": "3.3.3.2657" + "app_version": "3.3.4", + "bundle_version": "3.3.4.2877" }, "linux-x64-appimage": { - "filename": "ZCode-3.3.3-linux-x64.AppImage", - "size_bytes": 153884701, - "sha512": "be02e2f39c3cb1347c32e14ccc1888fc6e9937893d55f712ce95e44fdea077bda427a317ae12315c4043fa8a5d0af3e3c4c0263bcb6b8eae5b3a6acf02dfb870" + "filename": "ZCode-3.3.4-linux-x64.AppImage", + "size_bytes": 153909304, + "sha512": "5dcc5c0e948ca558f653410a3dfc1f08766b688cace98c671492690b0a7d9e1293900465ab0714ca73d6ea37cea56b05302191344679b95c1da49c322c9aeb31" }, "linux-x64-deb": { - "filename": "ZCode-3.3.3-linux-x64.deb", - "size_bytes": 113767364, - "sha512": "f71517c2af540cfe884f3417e2be8af72507f9a45cc75e5e3b10436606bba38510d838362721202d701c8cb00d33a2f8869d52d1d1c6097028de9f3843a9a407", + "filename": "ZCode-3.3.4-linux-x64.deb", + "size_bytes": 113797900, + "sha512": "5e26ded32c9f2fdc5da70805bd68f78588e48c6dcc785fec276a75d4f2a6a6b2423b93f880889eba36e2a6e60bd97e0c07039db230c769804b65ace09e6fe905", "package_name": "zcode", "package_arch": "amd64", - "package_version": "3.3.3-2657" + "package_version": "3.3.4-2877" }, "linux-arm64-appimage": { - "filename": "ZCode-3.3.3-linux-arm64.AppImage", - "size_bytes": 153820859, - "sha512": "ea60d899b88c56ec0740cca4af65317fbb0cdf9a12d12dd7bdf52c3ad2a5dd67aaf6f9299ee4ae90adc4541b9e669db014715054799150dd106f6c2b05cc6647" + "filename": "ZCode-3.3.4-linux-arm64.AppImage", + "size_bytes": 153841311, + "sha512": "a1c8c759cad74f0f0be5ce491ce234cdb6db03a476ebadc2a8ca1c6d72a5490603686e207fe2eb14930d6fadda3c4c1f311b62d0da6ad09265e86459c38c8734" }, "linux-arm64-deb": { - "filename": "ZCode-3.3.3-linux-arm64.deb", - "size_bytes": 107978832, - "sha512": "e36280ecb95edc71df69c5e84f109bacf2fb82aaaa0949666e2268206c7eb3b79af1c0e90afa633c050457326e578f679f4068809f92af307c724952f79bb045", + "filename": "ZCode-3.3.4-linux-arm64.deb", + "size_bytes": 108009364, + "sha512": "bab1fa5ab17dc58a6b386151c2ce7682ef06ffaa74723f8dc2a3987b15e3874da0643ee59b9fbe0986115f510962f9535f92e06232ae64ce51018e9d56e57954", "package_name": "zcode", "package_arch": "arm64", - "package_version": "3.3.3-2657" + "package_version": "3.3.4-2877" } }, "zcode_cli_launcher": { diff --git a/cli-tools/scripts/lib/build.sh b/cli-tools/scripts/lib/build.sh index b5989bb..7843526 100644 --- a/cli-tools/scripts/lib/build.sh +++ b/cli-tools/scripts/lib/build.sh @@ -1173,6 +1173,40 @@ nddev::build_clean() { nddev::render_env "$target" || return 1 } +nddev::assert_runtime_state_quiescent() { + local target=$1 database suffix inspector="" + if [ "${NDDEV_DRY_RUN:-1}" -eq 1 ] || [ ! -d "$target" ]; then + return 0 + fi + + if command -v lsof >/dev/null 2>&1; then + inspector="lsof" + elif command -v fuser >/dev/null 2>&1; then + inspector="fuser" + fi + + for database in "$target/v2/tasks-index.sqlite" "$target/cli/db/db.sqlite"; do + for suffix in -wal -shm -journal; do + if [ -e "${database}${suffix}" ] || [ -L "${database}${suffix}" ]; then + nddev::log "error" "runtime database has an active recovery sidecar: ${database}${suffix}" + nddev::log "error" "quit ZCode cleanly before changing the managed setup" + return 1 + fi + done + [ -f "$database" ] || continue + if [ "$inspector" = lsof ] && lsof -t -- "$database" >/dev/null 2>&1; then + nddev::log "error" "runtime database is open: $database" + nddev::log "error" "quit ZCode cleanly before changing the managed setup" + return 1 + fi + if [ "$inspector" = fuser ] && fuser "$database" >/dev/null 2>&1; then + nddev::log "error" "runtime database is open: $database" + nddev::log "error" "quit ZCode cleanly before changing the managed setup" + return 1 + fi + done +} + nddev::restore_runtime() { local source=$1 target=$2 managed=${3:-managed} if [ ! -d "$source" ]; then @@ -1291,6 +1325,9 @@ nddev::install_sequence() { fi fi + if [ "$had_target" -eq 1 ]; then + nddev::assert_runtime_state_quiescent "$ZCODE_HOME" || return + fi nddev::create_stage || return nddev::check_runtime_version || return nddev::build_clean "$NDDEV_STAGE_PATH" || return @@ -1324,6 +1361,7 @@ nddev::remove_managed_target() { nddev::log "error" "refusing to remove a managed tree containing unsafe filesystem entries" return 1 } + nddev::assert_runtime_state_quiescent "$ZCODE_HOME" || return NDDEV_ORIGINAL_TARGET_IDENTITY="$(nddev::path_identity "$ZCODE_HOME" directory)" || return 1 nddev::prepare_backup_destination "$current_version" || return if [ "${NDDEV_DRY_RUN:-1}" -eq 1 ]; then @@ -1396,6 +1434,7 @@ nddev::restore_backup_slot() { nddev::log "error" "refusing to replace a managed target containing unsafe filesystem entries" return 1 } + nddev::assert_runtime_state_quiescent "$ZCODE_HOME" || return NDDEV_ORIGINAL_TARGET_IDENTITY="$(nddev::path_identity "$ZCODE_HOME" directory)" || return 1 fi diff --git a/cli-tools/scripts/restore.sh b/cli-tools/scripts/restore.sh index 1aff647..52f0d61 100755 --- a/cli-tools/scripts/restore.sh +++ b/cli-tools/scripts/restore.sh @@ -54,6 +54,11 @@ fi RESTORE_PATHS=( "v2/credentials.json:v2/credentials.json:replace" "v2/certs:v2/certs:replace" + "v2/tasks-index.sqlite:v2/tasks-index.sqlite:replace" + "v2/sessions:v2/sessions:replace" + "v2/bot-config.json:v2/bot-config.json:replace" + "v2/bot-state.json:v2/bot-state.json:replace" + "v2/bot-state.v2.json:v2/bot-state.v2.json:replace" "cli/agents:cli/agents:replace" "cli/db:cli/db:merge" "cli/artifacts:cli/artifacts:replace" @@ -62,9 +67,15 @@ RESTORE_PATHS=( # Paths that are NEVER restored (pure runtime junk / regenerated by ZCode). NEVER_RESTORE=( "cli/log" + "cli/exec" + "cli/rollout" "v2/logs" "v2/crash" "cli/plugins/cache" + "v2/bots-model-cache.json" + "v2/bots-model-cache.v2.json" + "v2/coding-plan-cache.json" + "v2/telemetry-state.json" ) nddev::log "info" "backup: $BACKUP" diff --git a/docs/architecture.md b/docs/architecture.md index 531d3ad..a2205cc 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -54,7 +54,7 @@ prefix. tools come from the active workspace. All preference templates keep `modelProviderFamilyModes.zai` set to `oauth`, -which is the verified ZCode 3.3.3 account-authentication mode. The provider +which is the verified ZCode 3.3.4 account-authentication mode. The provider objects in `v2/config.json` are a separate explicit API-key contract: Z.ai uses `https://api.z.ai/api/anthropic`; BigModel uses `https://open.bigmodel.cn/api/anthropic`. Both API-key providers are disabled @@ -71,12 +71,15 @@ shared libraries and execute the same lifecycle: directory, 2. validate the selected marketplace and acquire an exclusive target lock plus an exclusive lock for the shared backup pool in deterministic order, -3. create a private same-filesystem sibling stage and check the live ZCode +3. reject open task/session databases or SQLite recovery sidecars in apply mode, + then create a private same-filesystem sibling stage and check the live ZCode runtime in apply mode through one canonical executable, a 3-second timeout, and a 64 KiB output cap, 4. copy source, structurally render JSON and MCP inputs, write a schema-2 `BUILD-VERSION` bound to the selected `setup_id`, - and selectively restore runtime state into the stage, + and selectively restore credentials, certificates, the desktop task index, + legacy session snapshots, bot definitions, CLI session databases, and + runtime artifacts into the stage, 5. reject unresolved placeholders in keys or values across active config/setting/provider/MCP/hook branches, symlinks, special files, and hardlink aliases; normalize private permissions, verify the complete staged diff --git a/docs/install.md b/docs/install.md index d9e6a0a..64202ee 100644 --- a/docs/install.md +++ b/docs/install.md @@ -111,6 +111,7 @@ cli-tools/scripts/install.sh list --json # Install — plan (dry-run) first, then apply: cli-tools/scripts/install.sh install --setup nddev-builder --plan +# Quit the ZCode desktop app before every apply-mode target mutation. cli-tools/scripts/install.sh install --setup nddev-builder --apply # Inspect the selected setup and validated installed-state stamp: @@ -226,7 +227,9 @@ original canonical target. 1. **Boundaries and locks** — target and backup roots are validated, then the installer acquires exclusive target and shared backup-pool locks. Concurrent - operations cannot race the same live tree or rotation pool. + operations cannot race the same live tree or rotation pool. Apply mode also + rejects open task/session databases and SQLite recovery sidecars; quit ZCode + cleanly before install, switch, remove, or restore. 2. **Stage** — a private sibling staging directory is created on the same filesystem. A clean target is rendered there from the selected marketplace: - `AGENTS.md` and user-scope `skills/`, `commands/`, and `agents/` are copied @@ -243,10 +246,14 @@ original canonical target. reported as unknown. 4. **Restore into stage** — selected runtime state is copied from the current target before any live replacement: - - **Always restored**: `v2/credentials.json`, `v2/certs/`, `cli/agents/` - (sessions), `cli/db/`, `cli/artifacts/`. + - **Always restored**: `v2/credentials.json`, `v2/certs/`, the desktop + `v2/tasks-index.sqlite`, legacy `v2/sessions/`, current and legacy bot + definition files, `cli/agents/`, `cli/db/`, and `cli/artifacts/`. The task + index and CLI session database are restored together so their cross-store + session references stay consistent. - **Never restored** (regenerated by ZCode): `cli/log/`, `v2/logs/`, - `v2/crash/`, `cli/plugins/cache/`. + `v2/crash/`, `cli/plugins/cache/`, transient `cli/exec/`, model I/O + `cli/rollout/`, telemetry, and model/plan caches. 5. **Verify** — managed stamp and JSON schemas, exact stamp/setup identity, marketplace presence, unresolved active config/setting/provider/MCP/hook placeholders in keys or values, diff --git a/docs/secrets.md b/docs/secrets.md index 6d6bc6e..39e2428 100644 --- a/docs/secrets.md +++ b/docs/secrets.md @@ -34,7 +34,7 @@ $EDITOR build/.env Z.ai account authentication and explicit provider API keys are separate: - `modelProviderFamilyModes.zai: oauth` in `v2/setting.json` is the verified - ZCode 3.3.3 default for account login. It does not require `ZAI_API_KEY`. + ZCode 3.3.4 default for account login. It does not require `ZAI_API_KEY`. - `ZAI_API_KEY` configures the explicit custom Z.ai provider at `https://api.z.ai/api/anthropic`. That provider is disabled by default; set its `enabled` field to `true` only after supplying the key. diff --git a/references/zcode-baseline.json b/references/zcode-baseline.json index 6fac9c5..e3c126c 100644 --- a/references/zcode-baseline.json +++ b/references/zcode-baseline.json @@ -1,11 +1,11 @@ { "baseline_version": 1, - "_comment": "ZCode runtime baseline for this build. The app and CLI versions are pinned in build/version.json and verified by the installer at install time. Account-mode Z.ai authentication uses the verified OAuth preference; explicit API-key providers are separate custom provider entries. Update verified_date and versions when the baseline changes.", + "_comment": "ZCode runtime baseline for this build. The app and CLI versions are pinned in build/version.json, compared during setup installation, and enforced as strict bootstrap postconditions. Account-mode Z.ai authentication uses the verified OAuth preference; explicit API-key providers are separate custom provider entries. Update verified_date and versions when the baseline changes.", "zcode": { - "app_version": "3.3.3", - "app_build": "3.3.3.2657", - "linux_deb_package_version": "3.3.3-2657", - "cli_version": "0.15.0", + "app_version": "3.3.4", + "app_build": "3.3.4.2877", + "linux_deb_package_version": "3.3.4-2877", + "cli_version": "0.15.2", "app_bundle_id": "dev.zcode.app", "macos_team_id": "8A5X4JJ39T", "runtime_model": "GLM-5.2", @@ -24,7 +24,11 @@ "hooks_enabled_flag_required": true, "mcp_config_key": "mcp.servers", "mcp_plugin_file": ".mcp.json", - "mcp_plugin_key": "mcpServers" + "mcp_plugin_key": "mcpServers", + "task_index_file": "~/.zcode/v2/tasks-index.sqlite", + "legacy_session_dir": "~/.zcode/v2/sessions/", + "cli_session_database": "~/.zcode/cli/db/db.sqlite", + "bot_state_file": "~/.zcode/v2/bot-state.v2.json" }, "evidence": { "official_install_documentation": "https://zcode.z.ai/en/docs/install", @@ -32,6 +36,6 @@ "official_distribution_base": "https://cdn-zcode.z.ai/zcode/electron/releases", "artifact_contract": "build/version.json:zcode_download_artifacts" }, - "verified_date": "2026-07-10", - "verified_against": "ZCode app 3.3.3 (build 3.3.3.2657) and CLI 0.15.0 runtime state" + "verified_date": "2026-07-11", + "verified_against": "ZCode app 3.3.4 (build 3.3.4.2877), CLI 0.15.2, all six native distribution artifacts, and the task/session storage layout" } diff --git a/zcode_tools/marketplaces/nddev-builder/marketplace.json b/zcode_tools/marketplaces/nddev-builder/marketplace.json index 3d0c05f..d9f6a10 100644 --- a/zcode_tools/marketplaces/nddev-builder/marketplace.json +++ b/zcode_tools/marketplaces/nddev-builder/marketplace.json @@ -10,7 +10,7 @@ "name": "core", "source": "./plugins/core", "description": "Reusable toolkit: skills, slash commands, and a reviewer subagent for building plugins, managing MCP servers and providers, authoring skills, and listing or removing components.", - "version": "2.1.0", + "version": "2.1.1", "author": { "name": "Danil Silantyev (github:rldyourmnd), CEO NDDev" }, diff --git a/zcode_tools/marketplaces/nddev-builder/plugins/core/.zcode-plugin/plugin.json b/zcode_tools/marketplaces/nddev-builder/plugins/core/.zcode-plugin/plugin.json index b04317c..7c545c3 100644 --- a/zcode_tools/marketplaces/nddev-builder/plugins/core/.zcode-plugin/plugin.json +++ b/zcode_tools/marketplaces/nddev-builder/plugins/core/.zcode-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "core", - "version": "2.1.0", + "version": "2.1.1", "description": "Reusable ZCode toolkit: skills, slash commands, and a reviewer subagent for building plugins, managing MCP servers and providers, authoring skills, and listing or removing components.", "author": { "name": "Danil Silantyev (github:rldyourmnd), CEO NDDev",