Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 12 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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.

Expand Down Expand Up @@ -94,10 +96,12 @@ Apply operations rotate at most 10 backups under `~/.zcode-backups/`:
<N>-<VERSION>-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
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.1.0
2.1.1
16 changes: 14 additions & 2 deletions build/manifest.json
Original file line number Diff line number Diff line change
@@ -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 <id>",
"layout": {
Expand Down Expand Up @@ -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",
Expand All @@ -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": {
Expand Down
54 changes: 27 additions & 27 deletions build/version.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
39 changes: 39 additions & 0 deletions cli-tools/scripts/lib/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
11 changes: 11 additions & 0 deletions cli-tools/scripts/restore.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down
9 changes: 6 additions & 3 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
15 changes: 11 additions & 4 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion docs/secrets.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading
Loading