From c15adec726980bee0ad3ea6f238fe8d2ed4d6f0b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 7 Sep 2026 23:36:01 +0000 Subject: [PATCH 1/8] chore: bump version to 0.1.10 --- Cargo.toml | 2 +- VERSION_CLI | 2 +- src/cortex-cli/VERSION | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 63b99dd3..c9af51a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -104,7 +104,7 @@ members = [ [workspace.package] # CLI version - kept in sync with VERSION_CLI and src/cortex-cli/VERSION # Run `scripts/check-cli-version.sh` to verify consistency -version = "0.1.9" +version = "0.1.10" edition = "2024" rust-version = "1.98" authors = ["Cortex Team "] diff --git a/VERSION_CLI b/VERSION_CLI index 1a030947..9767cc98 100644 --- a/VERSION_CLI +++ b/VERSION_CLI @@ -1 +1 @@ -0.1.9 +0.1.10 diff --git a/src/cortex-cli/VERSION b/src/cortex-cli/VERSION index 1a030947..9767cc98 100755 --- a/src/cortex-cli/VERSION +++ b/src/cortex-cli/VERSION @@ -1 +1 @@ -0.1.9 +0.1.10 From 014f746dca23bd49b9b0daf1f45ca8b22af899ff Mon Sep 17 00:00:00 2001 From: Mathis Date: Mon, 7 Sep 2026 23:38:59 +0000 Subject: [PATCH 2/8] chore: sync Cargo.lock for 0.1.10 workspace version --- Cargo.lock | 94 +++++++++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 86cf85b7..03786f32 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -955,7 +955,7 @@ dependencies = [ [[package]] name = "cortex-app-server" -version = "0.1.9" +version = "0.1.10" dependencies = [ "anyhow", "async-channel", @@ -995,7 +995,7 @@ dependencies = [ [[package]] name = "cortex-apply-patch" -version = "0.1.9" +version = "0.1.10" dependencies = [ "anyhow", "serde", @@ -1021,7 +1021,7 @@ dependencies = [ [[package]] name = "cortex-cli" -version = "0.1.9" +version = "0.1.10" dependencies = [ "anyhow", "base64", @@ -1071,7 +1071,7 @@ dependencies = [ [[package]] name = "cortex-collab" -version = "0.1.9" +version = "0.1.10" dependencies = [ "serde", "thiserror 2.0.20", @@ -1081,7 +1081,7 @@ dependencies = [ [[package]] name = "cortex-commands" -version = "0.1.9" +version = "0.1.10" dependencies = [ "chrono", "dirs 6.0.0", @@ -1096,7 +1096,7 @@ dependencies = [ [[package]] name = "cortex-common" -version = "0.1.9" +version = "0.1.10" dependencies = [ "clap", "cortex-protocol", @@ -1130,7 +1130,7 @@ dependencies = [ [[package]] name = "cortex-core" -version = "0.1.9" +version = "0.1.10" dependencies = [ "ahash", "anyhow", @@ -1153,7 +1153,7 @@ dependencies = [ [[package]] name = "cortex-engine" -version = "0.1.9" +version = "0.1.10" dependencies = [ "aes-gcm", "anyhow", @@ -1225,7 +1225,7 @@ dependencies = [ [[package]] name = "cortex-exec" -version = "0.1.9" +version = "0.1.10" dependencies = [ "cortex-engine", "cortex-protocol", @@ -1237,7 +1237,7 @@ dependencies = [ [[package]] name = "cortex-execpolicy" -version = "0.1.9" +version = "0.1.10" dependencies = [ "serde", "serde_json", @@ -1256,7 +1256,7 @@ dependencies = [ [[package]] name = "cortex-feedback" -version = "0.1.9" +version = "0.1.10" dependencies = [ "anyhow", "chrono", @@ -1269,7 +1269,7 @@ dependencies = [ [[package]] name = "cortex-file-search" -version = "0.1.9" +version = "0.1.10" dependencies = [ "anyhow", "ignore", @@ -1311,7 +1311,7 @@ dependencies = [ [[package]] name = "cortex-keyring-store" -version = "0.1.9" +version = "0.1.10" dependencies = [ "keyring", "thiserror 2.0.20", @@ -1335,7 +1335,7 @@ dependencies = [ [[package]] name = "cortex-lmstudio" -version = "0.1.9" +version = "0.1.10" dependencies = [ "reqwest", "serde", @@ -1349,7 +1349,7 @@ dependencies = [ [[package]] name = "cortex-login" -version = "0.1.9" +version = "0.1.10" dependencies = [ "aes-gcm", "anyhow", @@ -1397,7 +1397,7 @@ dependencies = [ [[package]] name = "cortex-mcp-client" -version = "0.1.9" +version = "0.1.10" dependencies = [ "anyhow", "async-trait", @@ -1413,7 +1413,7 @@ dependencies = [ [[package]] name = "cortex-mcp-server" -version = "0.1.9" +version = "0.1.10" dependencies = [ "anyhow", "async-trait", @@ -1426,7 +1426,7 @@ dependencies = [ [[package]] name = "cortex-mcp-types" -version = "0.1.9" +version = "0.1.10" dependencies = [ "schemars", "serde", @@ -1443,7 +1443,7 @@ dependencies = [ [[package]] name = "cortex-network-proxy" -version = "0.1.9" +version = "0.1.10" dependencies = [ "serde", "serde_json", @@ -1453,7 +1453,7 @@ dependencies = [ [[package]] name = "cortex-otel" -version = "0.1.9" +version = "0.1.10" dependencies = [ "cortex-common", "opentelemetry", @@ -1467,7 +1467,7 @@ dependencies = [ [[package]] name = "cortex-plugins" -version = "0.1.9" +version = "0.1.10" dependencies = [ "async-trait", "chrono", @@ -1493,14 +1493,14 @@ dependencies = [ [[package]] name = "cortex-process-hardening" -version = "0.1.9" +version = "0.1.10" dependencies = [ "libc", ] [[package]] name = "cortex-prompt-harness" -version = "0.1.9" +version = "0.1.10" dependencies = [ "chrono", "indexmap", @@ -1511,7 +1511,7 @@ dependencies = [ [[package]] name = "cortex-protocol" -version = "0.1.9" +version = "0.1.10" dependencies = [ "base64", "chrono", @@ -1556,7 +1556,7 @@ dependencies = [ [[package]] name = "cortex-sandbox" -version = "0.1.9" +version = "0.1.10" dependencies = [ "dirs 6.0.0", "landlock", @@ -1583,7 +1583,7 @@ dependencies = [ [[package]] name = "cortex-shell-snapshot" -version = "0.1.9" +version = "0.1.10" dependencies = [ "chrono", "dirs 6.0.0", @@ -1597,7 +1597,7 @@ dependencies = [ [[package]] name = "cortex-skills" -version = "0.1.9" +version = "0.1.10" dependencies = [ "chrono", "dashmap", @@ -1616,7 +1616,7 @@ dependencies = [ [[package]] name = "cortex-slack" -version = "0.1.9" +version = "0.1.10" dependencies = [ "async-trait", "axum", @@ -1666,7 +1666,7 @@ dependencies = [ [[package]] name = "cortex-tui" -version = "0.1.9" +version = "0.1.10" dependencies = [ "anyhow", "arboard", @@ -1711,7 +1711,7 @@ dependencies = [ [[package]] name = "cortex-tui-buffer" -version = "0.1.9" +version = "0.1.10" dependencies = [ "cortex-tui-core", "smallvec", @@ -1719,7 +1719,7 @@ dependencies = [ [[package]] name = "cortex-tui-capture" -version = "0.1.9" +version = "0.1.10" dependencies = [ "anyhow", "chrono", @@ -1739,7 +1739,7 @@ dependencies = [ [[package]] name = "cortex-tui-components" -version = "0.1.9" +version = "0.1.10" dependencies = [ "cortex-core", "crossterm", @@ -1749,7 +1749,7 @@ dependencies = [ [[package]] name = "cortex-tui-core" -version = "0.1.9" +version = "0.1.10" dependencies = [ "bitflags 2.13.1", "smallvec", @@ -1758,7 +1758,7 @@ dependencies = [ [[package]] name = "cortex-tui-framework" -version = "0.1.9" +version = "0.1.10" dependencies = [ "cortex-tui-buffer", "cortex-tui-core", @@ -1772,7 +1772,7 @@ dependencies = [ [[package]] name = "cortex-tui-input" -version = "0.1.9" +version = "0.1.10" dependencies = [ "bitflags 2.13.1", "crossterm", @@ -1781,7 +1781,7 @@ dependencies = [ [[package]] name = "cortex-tui-layout" -version = "0.1.9" +version = "0.1.10" dependencies = [ "cortex-tui-buffer", "slotmap", @@ -1790,7 +1790,7 @@ dependencies = [ [[package]] name = "cortex-tui-syntax" -version = "0.1.9" +version = "0.1.10" dependencies = [ "ahash", "cortex-tui-text", @@ -1803,7 +1803,7 @@ dependencies = [ [[package]] name = "cortex-tui-terminal" -version = "0.1.9" +version = "0.1.10" dependencies = [ "cortex-tui-buffer", "cortex-tui-core", @@ -1813,7 +1813,7 @@ dependencies = [ [[package]] name = "cortex-tui-text" -version = "0.1.9" +version = "0.1.10" dependencies = [ "smallvec", "unicode-segmentation", @@ -1822,7 +1822,7 @@ dependencies = [ [[package]] name = "cortex-tui-widgets" -version = "0.1.9" +version = "0.1.10" dependencies = [ "cortex-tui-buffer", "cortex-tui-core", @@ -1833,7 +1833,7 @@ dependencies = [ [[package]] name = "cortex-update" -version = "0.1.9" +version = "0.1.10" dependencies = [ "chrono", "cortex-common", @@ -1860,11 +1860,11 @@ dependencies = [ [[package]] name = "cortex-utils-cache" -version = "0.1.9" +version = "0.1.10" [[package]] name = "cortex-utils-file-safety" -version = "0.1.9" +version = "0.1.10" dependencies = [ "tempfile", "thiserror 2.0.20", @@ -1872,11 +1872,11 @@ dependencies = [ [[package]] name = "cortex-utils-git" -version = "0.1.9" +version = "0.1.10" [[package]] name = "cortex-utils-image" -version = "0.1.9" +version = "0.1.10" dependencies = [ "anyhow", "base64", @@ -1884,7 +1884,7 @@ dependencies = [ [[package]] name = "cortex-utils-pty" -version = "0.1.9" +version = "0.1.10" dependencies = [ "anyhow", "portable-pty", @@ -1892,7 +1892,7 @@ dependencies = [ [[package]] name = "cortex-utils-string" -version = "0.1.9" +version = "0.1.10" dependencies = [ "unicode-width", ] From eaa89da21b5f0ed233663a210279aac72eb2ff85 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 7 Sep 2026 23:50:08 +0000 Subject: [PATCH 3/8] fix(release): sync sdk 0.1.10 and splash chrome width Keep @cortexlm/sdk on VERSION_CLI and use the full 40-col budget so v0.1.10 still shows the mid splash hints. Co-authored-by: Mathis --- packages/sdk/package.json | 2 +- scripts/bump-version.sh | 26 ++++++++++++++++++++++++++ scripts/check-cli-version.sh | 12 ++++++++++++ src/cortex-tui/src/lock_boards.rs | 30 +++++++++++++++++++----------- src/cortex-tui/src/lock_proof.rs | 25 ++++++++++++++++++++++++- 5 files changed, 82 insertions(+), 13 deletions(-) diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 0d48215b..2ba5a4a1 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@cortexlm/sdk", - "version": "0.1.9", + "version": "0.1.10", "description": "Typed, local Cortex CLI subprocess client", "license": "Apache-2.0", "private": true, diff --git a/scripts/bump-version.sh b/scripts/bump-version.sh index 5b6e1094..e0c93a5b 100755 --- a/scripts/bump-version.sh +++ b/scripts/bump-version.sh @@ -248,6 +248,32 @@ else echo -e " ${GREEN}✓ Updated Cargo.toml${NC}" fi +# Keep the private SDK package version on VERSION_CLI (packages/sdk tests require it). +SDK_PKG="$REPO_ROOT/packages/sdk/package.json" +echo -e "${BLUE}Updating packages/sdk/package.json...${NC}" +if [ "$DRY_RUN" = true ]; then + echo " Would update version to \"$NEW_VERSION\" in $SDK_PKG" +elif [ -f "$SDK_PKG" ]; then + SDK_PKG_TMP=$(mktemp "${SDK_PKG}.tmp.XXXXXX") + awk -v new_ver="$NEW_VERSION" ' + BEGIN { done = 0 } + !done && /"version"[[:space:]]*:/ { + sub(/"[0-9][^"]*"/, "\"" new_ver "\"") + done = 1 + } + { print } + ' "$SDK_PKG" > "$SDK_PKG_TMP" + if ! grep -q "\"version\": \"$NEW_VERSION\"" "$SDK_PKG_TMP"; then + rm -f "$SDK_PKG_TMP" + echo -e "${RED}ERROR: Failed to update version in packages/sdk/package.json${NC}" + exit 1 + fi + mv "$SDK_PKG_TMP" "$SDK_PKG" + echo -e " ${GREEN}✓ Updated packages/sdk/package.json${NC}" +else + echo -e " ${YELLOW}⚠ packages/sdk/package.json not found — skipped${NC}" +fi + echo "" # Verify consistency diff --git a/scripts/check-cli-version.sh b/scripts/check-cli-version.sh index ad053764..41db465b 100755 --- a/scripts/check-cli-version.sh +++ b/scripts/check-cli-version.sh @@ -94,6 +94,18 @@ elif [ -n "$CLI_FILE_VERSION" ]; then echo -e "${GREEN}✓ VERSION_CLI matches src/cortex-cli/VERSION${NC}" fi +SDK_PKG="$REPO_ROOT/packages/sdk/package.json" +if [ -f "$SDK_PKG" ]; then + SDK_VERSION=$(grep -m1 '"version"' "$SDK_PKG" | sed 's/.*"\([^"]*\)".*/\1/') + echo "packages/sdk/package.json: $SDK_VERSION" + if [ "$VERSION_CLI" != "$SDK_VERSION" ]; then + echo -e "${RED}ERROR: VERSION_CLI ($VERSION_CLI) does not match packages/sdk/package.json ($SDK_VERSION)${NC}" + ERRORS=$((ERRORS + 1)) + else + echo -e "${GREEN}✓ VERSION_CLI matches packages/sdk/package.json${NC}" + fi +fi + # Check against release version if provided (used in CI) if [ -n "$CLI_RELEASE_VERSION" ]; then echo "" diff --git a/src/cortex-tui/src/lock_boards.rs b/src/cortex-tui/src/lock_boards.rs index 1135fdbe..ccddf62c 100644 --- a/src/cortex-tui/src/lock_boards.rs +++ b/src/cortex-tui/src/lock_boards.rs @@ -785,10 +785,27 @@ fn bar(filled: u16, total: u16) -> String { s } +/// Splash hint row: full, 40-col, or short — picked by character budget. +/// Uses the full area width (not [`inner_width`]) so `v0.1.10` still fits +/// the 40-column mid form `v{version} · / commands · @ files · ! shell`. +pub(crate) fn splash_legend(version: &str, width: usize) -> String { + let full_h = format!("v{version} · {LAUNCH_HINTS}"); + let mid_h = format!("v{version} · {LAUNCH_HINTS_NARROW}"); + if full_h.chars().count() <= width { + full_h + } else if mid_h.chars().count() <= width { + mid_h + } else { + format!("v{version} · / commands") + } +} + /// Launch header: `Welcome to Cortex, the coding agent CLI` then /// `v{version} · / commands · …`. No fake `> cortex` or painted cwd. fn paint_launch_header(area: Rect, buf: &mut Buffer, full: bool) -> u16 { - let w = inner_width(area); + // Full terminal width: the 40-col lock is exactly the mid hint budget + // once the package version is seven characters (`v0.1.10`). + let w = area.width.max(1) as usize; let mut y = area.y; let dim = Style::default().fg(TEXT_DIM); let bold = Style::default().fg(TEXT).add_modifier(Modifier::BOLD); @@ -797,16 +814,7 @@ fn paint_launch_header(area: Rect, buf: &mut Buffer, full: bool) -> u16 { buf.set_string(area.x + 17, y, ", the coding agent CLI", dim); y += 1; if full { - let version = env!("CARGO_PKG_VERSION"); - let full_h = format!("v{version} · {LAUNCH_HINTS}"); - let mid_h = format!("v{version} · {LAUNCH_HINTS_NARROW}"); - let hints = if full_h.chars().count() <= w { - full_h - } else if mid_h.chars().count() <= w { - mid_h - } else { - format!("v{version} · / commands") - }; + let hints = splash_legend(env!("CARGO_PKG_VERSION"), w); buf.set_string( area.x, y, diff --git a/src/cortex-tui/src/lock_proof.rs b/src/cortex-tui/src/lock_proof.rs index 1778fc0f..eda29d42 100644 --- a/src/cortex-tui/src/lock_proof.rs +++ b/src/cortex-tui/src/lock_proof.rs @@ -2337,14 +2337,30 @@ mod tests { ); } + #[test] + fn splash_legend_keeps_mid_hints_at_40_for_package_version() { + let version = env!("CARGO_PKG_VERSION"); + let legend = crate::lock_boards::splash_legend(version, 40); + assert!( + legend.contains("/ commands · @ files · ! shell"), + "40-col splash must keep mid hints for v{version}: {legend}" + ); + assert!( + !legend.contains("& cloud"), + "40-col splash shortens before & cloud: {legend}" + ); + } + #[test] fn splash_has_session_chrome() { + let version = env!("CARGO_PKG_VERSION"); + let mid = format!("v{version} · / commands · @ files · ! shell"); for size in SIZES { let frame = render_lock_scene("splash", size.0, size.1).expect("splash"); for needle in [ "Welcome to", "the coding agent CLI", - "/ commands · @ files · ! shell", + "/ commands", "Plan, search, build anything", "Cortex Mini 1", ] { @@ -2354,6 +2370,13 @@ mod tests { frame.plain ); } + if mid.chars().count() <= size.0 as usize { + assert!( + frame.plain.contains(&mid), + "splash missing mid chrome `{mid}` at {size:?}:\n{}", + frame.plain + ); + } assert!(!frame.plain.contains("▄█▀▀▀▀█▄"), "{}", frame.plain); assert!( !frame.plain.contains("> cortex"), From 582ff4bcd16e73a777e4d6abb05a15f51428183b Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 7 Sep 2026 23:50:47 +0000 Subject: [PATCH 4/8] chore(release): mention sdk in version-check fix hints Co-authored-by: Mathis --- scripts/check-cli-version.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/check-cli-version.sh b/scripts/check-cli-version.sh index 41db465b..08c051e4 100755 --- a/scripts/check-cli-version.sh +++ b/scripts/check-cli-version.sh @@ -128,6 +128,7 @@ if [ $ERRORS -gt 0 ]; then echo "1. Update VERSION_CLI with the correct version" echo "2. Update [workspace.package] version in Cargo.toml to match" echo "3. Ensure cortex-cli/Cargo.toml uses 'version.workspace = true'" + echo "4. Update packages/sdk/package.json to the same version" exit 1 fi From 5876d8d1ff6f286c519661955e95f60cb41d6228 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 7 Sep 2026 23:53:44 +0000 Subject: [PATCH 5/8] fix(tui): keep splash legend when version is longer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ellipsize v{version} instead of dropping @ files · ! shell so 40x12 chrome stays complete for v0.1.10 and later. Co-authored-by: Mathis --- src/cortex-tui/src/lock_boards.rs | 51 +++++++++++++++++++++++-------- src/cortex-tui/src/lock_proof.rs | 34 ++++++++------------- 2 files changed, 51 insertions(+), 34 deletions(-) diff --git a/src/cortex-tui/src/lock_boards.rs b/src/cortex-tui/src/lock_boards.rs index ccddf62c..d90d287f 100644 --- a/src/cortex-tui/src/lock_boards.rs +++ b/src/cortex-tui/src/lock_boards.rs @@ -785,26 +785,51 @@ fn bar(filled: u16, total: u16) -> String { s } -/// Splash hint row: full, 40-col, or short — picked by character budget. -/// Uses the full area width (not [`inner_width`]) so `v0.1.10` still fits -/// the 40-column mid form `v{version} · / commands · @ files · ! shell`. +/// Join `v{version}` to a hint legend, ellipsizing the version — never the +/// legend — when the pair is wider than `width`. pub(crate) fn splash_legend(version: &str, width: usize) -> String { - let full_h = format!("v{version} · {LAUNCH_HINTS}"); - let mid_h = format!("v{version} · {LAUNCH_HINTS_NARROW}"); - if full_h.chars().count() <= width { - full_h - } else if mid_h.chars().count() <= width { - mid_h - } else { - format!("v{version} · / commands") + let ver = format!("v{version}"); + for legend in [LAUNCH_HINTS, LAUNCH_HINTS_NARROW] { + let line = format!("{ver} · {legend}"); + if line.chars().count() <= width { + return line; + } + } + // Keep `/ commands · @ files · ! shell` (and `& cloud` when it fits). + // A longer package version is shortened; the keystroke legend is not. + for legend in [LAUNCH_HINTS, LAUNCH_HINTS_NARROW] { + let suffix = format!(" · {legend}"); + let suffix_len = suffix.chars().count(); + if suffix_len >= width { + continue; + } + let shown = ellipsis_prefix(&ver, width - suffix_len); + if shown.is_empty() { + continue; + } + return format!("{shown}{suffix}"); + } + LAUNCH_HINTS_NARROW.to_string() +} + +fn ellipsis_prefix(text: &str, budget: usize) -> String { + if text.chars().count() <= budget { + return text.to_string(); + } + if budget == 0 { + return String::new(); + } + if budget == 1 { + return "…".to_string(); } + format!("{}…", text.chars().take(budget - 1).collect::()) } /// Launch header: `Welcome to Cortex, the coding agent CLI` then /// `v{version} · / commands · …`. No fake `> cortex` or painted cwd. fn paint_launch_header(area: Rect, buf: &mut Buffer, full: bool) -> u16 { - // Full terminal width: the 40-col lock is exactly the mid hint budget - // once the package version is seven characters (`v0.1.10`). + // Full terminal width so the 40-col lock can hold the mid legend; a + // longer version is ellipsized instead of dropping `@ files · ! shell`. let w = area.width.max(1) as usize; let mut y = area.y; let dim = Style::default().fg(TEXT_DIM); diff --git a/src/cortex-tui/src/lock_proof.rs b/src/cortex-tui/src/lock_proof.rs index eda29d42..524e62bc 100644 --- a/src/cortex-tui/src/lock_proof.rs +++ b/src/cortex-tui/src/lock_proof.rs @@ -2338,29 +2338,28 @@ mod tests { } #[test] - fn splash_legend_keeps_mid_hints_at_40_for_package_version() { - let version = env!("CARGO_PKG_VERSION"); - let legend = crate::lock_boards::splash_legend(version, 40); - assert!( - legend.contains("/ commands · @ files · ! shell"), - "40-col splash must keep mid hints for v{version}: {legend}" - ); - assert!( - !legend.contains("& cloud"), - "40-col splash shortens before & cloud: {legend}" - ); + fn splash_legend_keeps_mid_hints_when_version_grows() { + for version in [env!("CARGO_PKG_VERSION"), "0.1.10", "10.20.30-rc.1"] { + let legend = crate::lock_boards::splash_legend(version, 40); + assert!( + legend.contains("/ commands · @ files · ! shell"), + "40-col splash must keep mid hints for v{version}: {legend}" + ); + assert!( + !legend.contains("& cloud"), + "40-col splash shortens before & cloud: {legend}" + ); + } } #[test] fn splash_has_session_chrome() { - let version = env!("CARGO_PKG_VERSION"); - let mid = format!("v{version} · / commands · @ files · ! shell"); for size in SIZES { let frame = render_lock_scene("splash", size.0, size.1).expect("splash"); for needle in [ "Welcome to", "the coding agent CLI", - "/ commands", + "/ commands · @ files · ! shell", "Plan, search, build anything", "Cortex Mini 1", ] { @@ -2370,13 +2369,6 @@ mod tests { frame.plain ); } - if mid.chars().count() <= size.0 as usize { - assert!( - frame.plain.contains(&mid), - "splash missing mid chrome `{mid}` at {size:?}:\n{}", - frame.plain - ); - } assert!(!frame.plain.contains("▄█▀▀▀▀█▄"), "{}", frame.plain); assert!( !frame.plain.contains("> cortex"), From ba931ffa8ae25fef261ca283beefe0939fca0a44 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 7 Sep 2026 23:59:39 +0000 Subject: [PATCH 6/8] fix(tui): extract splash legend to satisfy line-count gate Move version-width splash helpers into splash_chrome.rs so lock_boards.rs and lock_proof.rs stay at or below the QUALITY_BASE sizes. Co-authored-by: Mathis --- src/cortex-tui/src/lib.rs | 1 + src/cortex-tui/src/lock_boards.rs | 44 +------------- src/cortex-tui/src/lock_proof.rs | 15 ----- src/cortex-tui/src/splash_chrome.rs | 91 +++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 58 deletions(-) create mode 100644 src/cortex-tui/src/splash_chrome.rs diff --git a/src/cortex-tui/src/lib.rs b/src/cortex-tui/src/lib.rs index 39d979f0..073b00e3 100644 --- a/src/cortex-tui/src/lib.rs +++ b/src/cortex-tui/src/lib.rs @@ -105,6 +105,7 @@ pub mod lock_proof; pub mod lock_v2; pub mod readme_hero; pub mod readme_hero_boards; +pub mod splash_chrome; // Backtracking system for conversation history navigation pub mod backtrack; diff --git a/src/cortex-tui/src/lock_boards.rs b/src/cortex-tui/src/lock_boards.rs index d90d287f..04567e09 100644 --- a/src/cortex-tui/src/lock_boards.rs +++ b/src/cortex-tui/src/lock_boards.rs @@ -17,6 +17,7 @@ use ratatui::style::{Color, Modifier, Style}; use ratatui::text::{Line, Span}; use ratatui::widgets::{Paragraph, Widget}; +use crate::splash_chrome::splash_legend; use crate::ui::text_utils::{ first_fitting_line, fit_line, trim_dangling_separator, wrap_keep_indent, wrap_or_drop, }; @@ -36,9 +37,6 @@ const GHOST_RUNNING: &str = crate::views::minimal_session::PLACEHOLDER_RUNNING; /// Right-hand footer hint, and its narrow form — the live footer's copy. const FOOTER_HINT: &str = crate::widgets::key_hints::FOOTER_HINT_IDLE; const FOOTER_HINT_SHORT: &str = "shift+tab modes"; -/// Keystroke hints under the splash, and the form that fits 40 columns. -const LAUNCH_HINTS: &str = crate::views::minimal_session::EMPTY_SESSION_HINTS; -const LAUNCH_HINTS_NARROW: &str = "/ commands · @ files · ! shell"; /// Rows the composer takes: hairline, prompt, hairline. const COMPOSER_ROWS: u16 = crate::views::minimal_session::COMPOSER_ROWS; @@ -785,46 +783,6 @@ fn bar(filled: u16, total: u16) -> String { s } -/// Join `v{version}` to a hint legend, ellipsizing the version — never the -/// legend — when the pair is wider than `width`. -pub(crate) fn splash_legend(version: &str, width: usize) -> String { - let ver = format!("v{version}"); - for legend in [LAUNCH_HINTS, LAUNCH_HINTS_NARROW] { - let line = format!("{ver} · {legend}"); - if line.chars().count() <= width { - return line; - } - } - // Keep `/ commands · @ files · ! shell` (and `& cloud` when it fits). - // A longer package version is shortened; the keystroke legend is not. - for legend in [LAUNCH_HINTS, LAUNCH_HINTS_NARROW] { - let suffix = format!(" · {legend}"); - let suffix_len = suffix.chars().count(); - if suffix_len >= width { - continue; - } - let shown = ellipsis_prefix(&ver, width - suffix_len); - if shown.is_empty() { - continue; - } - return format!("{shown}{suffix}"); - } - LAUNCH_HINTS_NARROW.to_string() -} - -fn ellipsis_prefix(text: &str, budget: usize) -> String { - if text.chars().count() <= budget { - return text.to_string(); - } - if budget == 0 { - return String::new(); - } - if budget == 1 { - return "…".to_string(); - } - format!("{}…", text.chars().take(budget - 1).collect::()) -} - /// Launch header: `Welcome to Cortex, the coding agent CLI` then /// `v{version} · / commands · …`. No fake `> cortex` or painted cwd. fn paint_launch_header(area: Rect, buf: &mut Buffer, full: bool) -> u16 { diff --git a/src/cortex-tui/src/lock_proof.rs b/src/cortex-tui/src/lock_proof.rs index 524e62bc..1778fc0f 100644 --- a/src/cortex-tui/src/lock_proof.rs +++ b/src/cortex-tui/src/lock_proof.rs @@ -2337,21 +2337,6 @@ mod tests { ); } - #[test] - fn splash_legend_keeps_mid_hints_when_version_grows() { - for version in [env!("CARGO_PKG_VERSION"), "0.1.10", "10.20.30-rc.1"] { - let legend = crate::lock_boards::splash_legend(version, 40); - assert!( - legend.contains("/ commands · @ files · ! shell"), - "40-col splash must keep mid hints for v{version}: {legend}" - ); - assert!( - !legend.contains("& cloud"), - "40-col splash shortens before & cloud: {legend}" - ); - } - } - #[test] fn splash_has_session_chrome() { for size in SIZES { diff --git a/src/cortex-tui/src/splash_chrome.rs b/src/cortex-tui/src/splash_chrome.rs new file mode 100644 index 00000000..38d1ab84 --- /dev/null +++ b/src/cortex-tui/src/splash_chrome.rs @@ -0,0 +1,91 @@ +//! Splash legend + version-width helpers. +//! +//! Split out of [`crate::lock_boards`] so a longer package version can +//! ellipsis without growing that file past the source-policy line-count +//! gate. At 40 columns the mid keystroke legend is kept; `& cloud` is +//! added when it fits. The version shortens — the legend does not. + +/// Full empty-session hints, including the cloud slot when width allows. +const LAUNCH_HINTS: &str = crate::views::minimal_session::EMPTY_SESSION_HINTS; +/// Form that fits a 40-column lock (`& cloud` dropped). +const LAUNCH_HINTS_NARROW: &str = "/ commands · @ files · ! shell"; + +/// Join `v{version}` to a hint legend, ellipsizing the version — never the +/// legend — when the pair is wider than `width`. +pub(crate) fn splash_legend(version: &str, width: usize) -> String { + let ver = format!("v{version}"); + for legend in [LAUNCH_HINTS, LAUNCH_HINTS_NARROW] { + let line = format!("{ver} · {legend}"); + if line.chars().count() <= width { + return line; + } + } + // Keep `/ commands · @ files · ! shell` (and `& cloud` when it fits). + // A longer package version is shortened; the keystroke legend is not. + for legend in [LAUNCH_HINTS, LAUNCH_HINTS_NARROW] { + let suffix = format!(" · {legend}"); + let suffix_len = suffix.chars().count(); + if suffix_len >= width { + continue; + } + let shown = ellipsis_prefix(&ver, width - suffix_len); + if shown.is_empty() { + continue; + } + return format!("{shown}{suffix}"); + } + LAUNCH_HINTS_NARROW.to_string() +} + +fn ellipsis_prefix(text: &str, budget: usize) -> String { + if text.chars().count() <= budget { + return text.to_string(); + } + if budget == 0 { + return String::new(); + } + if budget == 1 { + return "…".to_string(); + } + format!("{}…", text.chars().take(budget - 1).collect::()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn splash_legend_keeps_mid_hints_when_version_grows() { + for version in [env!("CARGO_PKG_VERSION"), "0.1.10", "10.20.30-rc.1"] { + let legend = splash_legend(version, 40); + assert!( + legend.contains("/ commands · @ files · ! shell"), + "40-col splash must keep mid hints for v{version}: {legend}" + ); + assert!( + !legend.contains("& cloud"), + "40-col splash shortens before & cloud: {legend}" + ); + } + } + + #[test] + fn splash_legend_adds_cloud_when_width_allows() { + let legend = splash_legend("0.1.10", 120); + assert!( + legend.contains("/ commands · @ files · ! shell · & cloud"), + "wide splash keeps the cloud slot: {legend}" + ); + assert!( + legend.starts_with("v0.1.10 · "), + "wide splash keeps the full version: {legend}" + ); + } + + #[test] + fn splash_legend_ellipsizes_version_not_legend() { + let legend = splash_legend("0.1.10", 40); + assert_eq!(legend, "v0.1.… · / commands · @ files · ! shell"); + assert_eq!(legend.chars().count(), 40); + } +} From fa130ebef087860198d3197b08a955f5db578575 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 8 Sep 2026 00:03:37 +0000 Subject: [PATCH 7/8] test(tui): assert 40-col splash version fits before ellipsis v0.1.10 plus the mid legend is exactly 40 columns; only a longer version is shortened. Co-authored-by: Mathis --- src/cortex-tui/src/splash_chrome.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/cortex-tui/src/splash_chrome.rs b/src/cortex-tui/src/splash_chrome.rs index 38d1ab84..1e6c9eac 100644 --- a/src/cortex-tui/src/splash_chrome.rs +++ b/src/cortex-tui/src/splash_chrome.rs @@ -84,8 +84,19 @@ mod tests { #[test] fn splash_legend_ellipsizes_version_not_legend() { - let legend = splash_legend("0.1.10", 40); - assert_eq!(legend, "v0.1.… · / commands · @ files · ! shell"); - assert_eq!(legend.chars().count(), 40); + let exact = splash_legend("0.1.10", 40); + assert_eq!(exact, "v0.1.10 · / commands · @ files · ! shell"); + assert_eq!(exact.chars().count(), 40); + + let overflow = splash_legend("10.20.30-rc.1", 40); + assert!( + overflow.contains("/ commands · @ files · ! shell"), + "overflow must keep the mid legend: {overflow}" + ); + assert!( + overflow.contains('…'), + "a longer version ellipsizes: {overflow}" + ); + assert!(overflow.chars().count() <= 40, "{overflow}"); } } From 823a50b1b5890a048bd1e887776ded44bb70e8eb Mon Sep 17 00:00:00 2001 From: Mathis Date: Tue, 8 Sep 2026 00:15:54 +0000 Subject: [PATCH 8/8] chore: refresh app-server OpenAPI version to 0.1.10 --- docs/reference/app-server.openapi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/app-server.openapi.json b/docs/reference/app-server.openapi.json index 4ef31a60..f2f670b6 100644 --- a/docs/reference/app-server.openapi.json +++ b/docs/reference/app-server.openapi.json @@ -270,7 +270,7 @@ "info": { "description": "Supported local session/health contract. Message POST stores a message; it does not generate a model response. Other development endpoints are not part of this stable contract.", "title": "Cortex local session API", - "version": "0.1.9" + "version": "0.1.10" }, "openapi": "3.1.0", "paths": {