chore: bump version to 9.6.3
This commit is contained in:
Generated
+1
-1
@@ -790,7 +790,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pi-natives"
|
||||
version = "9.6.2"
|
||||
version = "9.6.3"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"globset",
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ members = ["crates/*"]
|
||||
resolver = "3"
|
||||
|
||||
[workspace.package]
|
||||
version = "9.6.2"
|
||||
version = "9.6.3"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = ["Can Boluk"]
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
},
|
||||
"packages/agent": {
|
||||
"name": "@oh-my-pi/pi-agent-core",
|
||||
"version": "9.6.2",
|
||||
"version": "9.6.3",
|
||||
"dependencies": {
|
||||
"@oh-my-pi/pi-ai": "workspace:*",
|
||||
"@oh-my-pi/pi-tui": "workspace:*",
|
||||
@@ -35,7 +35,7 @@
|
||||
},
|
||||
"packages/ai": {
|
||||
"name": "@oh-my-pi/pi-ai",
|
||||
"version": "9.6.2",
|
||||
"version": "9.6.3",
|
||||
"bin": {
|
||||
"pi-ai": "./src/cli.ts",
|
||||
},
|
||||
@@ -65,7 +65,7 @@
|
||||
},
|
||||
"packages/coding-agent": {
|
||||
"name": "@oh-my-pi/pi-coding-agent",
|
||||
"version": "9.6.2",
|
||||
"version": "9.6.3",
|
||||
"bin": {
|
||||
"omp": "src/cli.ts",
|
||||
},
|
||||
@@ -100,7 +100,7 @@
|
||||
},
|
||||
"packages/natives": {
|
||||
"name": "@oh-my-pi/pi-natives",
|
||||
"version": "9.6.2",
|
||||
"version": "9.6.3",
|
||||
"dependencies": {
|
||||
"@oh-my-pi/pi-utils": "workspace:*",
|
||||
},
|
||||
@@ -128,7 +128,7 @@
|
||||
},
|
||||
"packages/stats": {
|
||||
"name": "@oh-my-pi/omp-stats",
|
||||
"version": "9.6.2",
|
||||
"version": "9.6.3",
|
||||
"bin": {
|
||||
"omp-stats": "./src/index.ts",
|
||||
},
|
||||
@@ -148,7 +148,7 @@
|
||||
},
|
||||
"packages/tui": {
|
||||
"name": "@oh-my-pi/pi-tui",
|
||||
"version": "9.6.2",
|
||||
"version": "9.6.3",
|
||||
"dependencies": {
|
||||
"@oh-my-pi/pi-natives": "workspace:*",
|
||||
"@types/mime-types": "^3.0.1",
|
||||
@@ -163,7 +163,7 @@
|
||||
},
|
||||
"packages/utils": {
|
||||
"name": "@oh-my-pi/pi-utils",
|
||||
"version": "9.6.2",
|
||||
"version": "9.6.3",
|
||||
"dependencies": {
|
||||
"winston": "^3.19.0",
|
||||
"winston-daily-rotate-file": "^5.0.0",
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
//! - Ellipsis decoded lazily
|
||||
//! - truncateToWidth returns the original `JsString` when possible
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
||||
use napi::{JsString, bindgen_prelude::*};
|
||||
use napi_derive::napi;
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
@@ -293,7 +295,7 @@ fn ansi_seq_len_u16(data: &[u16], pos: usize) -> Option<usize> {
|
||||
// '[' CSI
|
||||
for (i, b) in data[pos + 2..].iter().enumerate() {
|
||||
if (0x40..=0x7e).contains(b) {
|
||||
return Some(i + 1 - pos);
|
||||
return Some(i + 3);
|
||||
}
|
||||
}
|
||||
None
|
||||
@@ -302,10 +304,10 @@ fn ansi_seq_len_u16(data: &[u16], pos: usize) -> Option<usize> {
|
||||
// ']' OSC
|
||||
for (i, &b) in data[pos + 2..].iter().enumerate() {
|
||||
if b == 0x07 {
|
||||
return Some(i + 1 - pos);
|
||||
return Some(i + 3);
|
||||
}
|
||||
if b == ESC && data.get(i + 1) == Some(&0x5c) {
|
||||
return Some(i + 2 - pos);
|
||||
if b == ESC && data.get(pos + 2 + i + 1) == Some(&0x5c) {
|
||||
return Some(i + 4);
|
||||
}
|
||||
}
|
||||
None
|
||||
@@ -353,13 +355,17 @@ fn grapheme_width_str(g: &str) -> usize {
|
||||
UnicodeWidthStr::width(g)
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static SCRATCH: RefCell<String> = const { RefCell::new(String::new()) };
|
||||
}
|
||||
|
||||
/// Iterate graphemes in a UTF-16 segment with:
|
||||
/// - ASCII fast path (no UTF-8 conversion)
|
||||
/// - non-ASCII slow path using a reused scratch String
|
||||
///
|
||||
/// Callback returns `true` to continue, `false` to stop early.
|
||||
#[inline]
|
||||
fn for_each_grapheme_u16<F>(segment: &[u16], scratch: &mut String, mut f: F) -> bool
|
||||
fn for_each_grapheme_u16<F>(segment: &[u16], mut f: F) -> bool
|
||||
where
|
||||
F: FnMut(&[u16], usize) -> bool,
|
||||
{
|
||||
@@ -378,31 +384,33 @@ where
|
||||
}
|
||||
|
||||
// Slow path: decode into scratch once, reuse allocation
|
||||
scratch.clear();
|
||||
scratch.reserve(segment.len());
|
||||
SCRATCH.with_borrow_mut(|scratch| {
|
||||
scratch.clear();
|
||||
scratch.reserve(segment.len());
|
||||
|
||||
for r in std::char::decode_utf16(segment.iter().copied()) {
|
||||
scratch.push(r.unwrap_or('\u{FFFD}'));
|
||||
}
|
||||
|
||||
let mut utf16_pos = 0usize;
|
||||
for g in scratch.graphemes(true) {
|
||||
let w = grapheme_width_str(g);
|
||||
|
||||
let g_u16_len: usize = g.chars().map(|c| c.len_utf16()).sum();
|
||||
let u16_slice = &segment[utf16_pos..utf16_pos + g_u16_len];
|
||||
utf16_pos += g_u16_len;
|
||||
|
||||
if !f(u16_slice, w) {
|
||||
return false;
|
||||
for r in std::char::decode_utf16(segment.iter().copied()) {
|
||||
scratch.push(r.unwrap_or('\u{FFFD}'));
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
let mut utf16_pos = 0usize;
|
||||
for g in scratch.graphemes(true) {
|
||||
let w = grapheme_width_str(g);
|
||||
|
||||
let g_u16_len: usize = g.chars().map(|c| c.len_utf16()).sum();
|
||||
let u16_slice = &segment[utf16_pos..utf16_pos + g_u16_len];
|
||||
utf16_pos += g_u16_len;
|
||||
|
||||
if !f(u16_slice, w) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
})
|
||||
}
|
||||
|
||||
/// Visible width, with early-exit if width exceeds `limit`.
|
||||
fn visible_width_u16_up_to(data: &[u16], limit: usize, scratch: &mut String) -> (usize, bool) {
|
||||
fn visible_width_u16_up_to(data: &[u16], limit: usize) -> (usize, bool) {
|
||||
let mut width = 0usize;
|
||||
let mut i = 0usize;
|
||||
|
||||
@@ -424,7 +432,7 @@ fn visible_width_u16_up_to(data: &[u16], limit: usize, scratch: &mut String) ->
|
||||
}
|
||||
let seg = &data[start..i];
|
||||
|
||||
let ok = for_each_grapheme_u16(seg, scratch, |_, w| {
|
||||
let ok = for_each_grapheme_u16(seg, |_, w| {
|
||||
width += w;
|
||||
width <= limit
|
||||
});
|
||||
@@ -436,8 +444,8 @@ fn visible_width_u16_up_to(data: &[u16], limit: usize, scratch: &mut String) ->
|
||||
(width, width > limit)
|
||||
}
|
||||
|
||||
fn visible_width_u16(data: &[u16], scratch: &mut String) -> usize {
|
||||
visible_width_u16_up_to(data, usize::MAX, scratch).0
|
||||
fn visible_width_u16(data: &[u16]) -> usize {
|
||||
visible_width_u16_up_to(data, usize::MAX).0
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
@@ -462,10 +470,8 @@ pub fn truncate_to_width(
|
||||
let text_u16 = text.into_utf16()?;
|
||||
let text = text_u16.as_slice();
|
||||
|
||||
let mut scratch = String::new();
|
||||
|
||||
// Fast path: early-exit width check
|
||||
let (text_w, exceeded) = visible_width_u16_up_to(text, max_width, &mut scratch);
|
||||
let (text_w, exceeded) = visible_width_u16_up_to(text, max_width);
|
||||
if !exceeded {
|
||||
if !pad {
|
||||
// Return original JsString handle: zero output allocation.
|
||||
@@ -501,7 +507,7 @@ pub fn truncate_to_width(
|
||||
if target_w == 0 {
|
||||
let mut out = Vec::with_capacity(ellipsis.len().min(max_width * 2));
|
||||
let mut w = 0usize;
|
||||
let _ = for_each_grapheme_u16(ellipsis, &mut scratch, |gu16, gw| {
|
||||
let _ = for_each_grapheme_u16(ellipsis, |gu16, gw| {
|
||||
if w + gw > max_width {
|
||||
return false;
|
||||
}
|
||||
@@ -543,7 +549,7 @@ pub fn truncate_to_width(
|
||||
}
|
||||
let seg = &text[start..i];
|
||||
|
||||
let keep_going = for_each_grapheme_u16(seg, &mut scratch, |gu16, gw| {
|
||||
let keep_going = for_each_grapheme_u16(seg, |gu16, gw| {
|
||||
if w + gw > target_w {
|
||||
return false;
|
||||
}
|
||||
@@ -594,8 +600,6 @@ fn slice_with_width_impl(
|
||||
// store pending ANSI ranges (pos,len) to avoid copying until needed
|
||||
let mut pending_ansi: Vec<(usize, usize)> = Vec::new();
|
||||
|
||||
let mut scratch = String::new();
|
||||
|
||||
while i < line.len() && current_col < end_col {
|
||||
if line[i] == ESC {
|
||||
if let Some(len) = ansi_seq_len_u16(line, i) {
|
||||
@@ -621,7 +625,7 @@ fn slice_with_width_impl(
|
||||
}
|
||||
let seg = &line[start..i];
|
||||
|
||||
let _ = for_each_grapheme_u16(seg, &mut scratch, |gu16, gw| {
|
||||
let _ = for_each_grapheme_u16(seg, |gu16, gw| {
|
||||
if current_col >= end_col {
|
||||
return false;
|
||||
}
|
||||
@@ -704,8 +708,6 @@ fn extract_segments_impl(
|
||||
let mut after_started = false;
|
||||
let mut state = AnsiState::new();
|
||||
|
||||
let mut scratch = String::new();
|
||||
|
||||
while i < line.len() {
|
||||
let done = if after_len == 0 {
|
||||
current_col >= before_end
|
||||
@@ -750,7 +752,7 @@ fn extract_segments_impl(
|
||||
}
|
||||
let seg = &line[start..i];
|
||||
|
||||
let _ = for_each_grapheme_u16(seg, &mut scratch, |gu16, gw| {
|
||||
let _ = for_each_grapheme_u16(seg, |gu16, gw| {
|
||||
let done_inner = if after_len == 0 {
|
||||
current_col >= before_end
|
||||
} else {
|
||||
@@ -825,8 +827,7 @@ pub fn extract_segments(
|
||||
#[napi(js_name = "visibleWidth")]
|
||||
pub fn visible_width_napi(text: JsString) -> Result<u32> {
|
||||
let text_u16 = text.into_utf16()?;
|
||||
let mut scratch = String::new();
|
||||
Ok(clamp_u32(visible_width_u16(text_u16.as_slice(), &mut scratch)))
|
||||
Ok(clamp_u32(visible_width_u16(text_u16.as_slice())))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -839,11 +840,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_visible_width() {
|
||||
let mut scratch = String::new();
|
||||
assert_eq!(visible_width_u16(&to_u16("hello"), &mut scratch), 5);
|
||||
assert_eq!(visible_width_u16(&to_u16("\x1b[31mhello\x1b[0m"), &mut scratch), 5);
|
||||
assert_eq!(visible_width_u16(&to_u16("\x1b[38;5;196mred\x1b[0m"), &mut scratch), 3);
|
||||
assert_eq!(visible_width_u16(&to_u16("a\tb"), &mut scratch), 1 + TAB_WIDTH + 1);
|
||||
assert_eq!(visible_width_u16(&to_u16("hello")), 5);
|
||||
assert_eq!(visible_width_u16(&to_u16("\x1b[31mhello\x1b[0m")), 5);
|
||||
assert_eq!(visible_width_u16(&to_u16("\x1b[38;5;196mred\x1b[0m")), 3);
|
||||
assert_eq!(visible_width_u16(&to_u16("a\tb")), 1 + TAB_WIDTH + 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -881,8 +881,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_early_exit() {
|
||||
let data = to_u16(&"a]b".repeat(1000));
|
||||
let mut scratch = String::new();
|
||||
let (w, exceeded) = visible_width_u16_up_to(&data, 10, &mut scratch);
|
||||
let (w, exceeded) = visible_width_u16_up_to(&data, 10);
|
||||
assert!(exceeded);
|
||||
assert!(w > 10);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oh-my-pi/pi-agent-core",
|
||||
"version": "9.6.2",
|
||||
"version": "9.6.3",
|
||||
"description": "General-purpose agent with transport abstraction, state management, and attachment support",
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oh-my-pi/pi-ai",
|
||||
"version": "9.6.2",
|
||||
"version": "9.6.3",
|
||||
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oh-my-pi/pi-coding-agent",
|
||||
"version": "9.6.2",
|
||||
"version": "9.6.3",
|
||||
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
||||
"type": "module",
|
||||
"ompConfig": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oh-my-pi/pi-natives",
|
||||
"version": "9.6.2",
|
||||
"version": "9.6.3",
|
||||
"description": "Native Rust functionality via N-API",
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oh-my-pi/omp-stats",
|
||||
"version": "9.6.2",
|
||||
"version": "9.6.3",
|
||||
"description": "Local observability dashboard for pi AI usage statistics",
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
|
||||
@@ -57,10 +57,6 @@ function bunStringWidth(str: string): number {
|
||||
if (str.includes("\t")) {
|
||||
clean = clean.replace(/\t/g, " ");
|
||||
}
|
||||
if (clean.includes("\x1b")) {
|
||||
clean = clean.replace(/\x1b\[[0-9;]*[mGKHJ]/g, "");
|
||||
clean = clean.replace(/\x1b\]8;;[^\x07]*\x07/g, "");
|
||||
}
|
||||
return Bun.stringWidth(clean);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oh-my-pi/pi-tui",
|
||||
"version": "9.6.2",
|
||||
"version": "9.6.3",
|
||||
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
|
||||
@@ -25,8 +25,8 @@ export function getSegmenter(): Intl.Segmenter {
|
||||
}
|
||||
|
||||
// Cache for non-ASCII strings
|
||||
const WIDTH_CACHE_SIZE = 512;
|
||||
const widthCache = new Map<string, number>();
|
||||
//const WIDTH_CACHE_SIZE = 512;
|
||||
//const widthCache = new Map<string, number>();
|
||||
|
||||
/**
|
||||
* Calculate the visible width of a string in terminal columns.
|
||||
@@ -60,7 +60,11 @@ export function visibleWidth(str: string): number {
|
||||
if (str.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
return visibleWidthRaw(str);
|
||||
|
||||
// === Disabled cache ===
|
||||
|
||||
/*
|
||||
// Check cache
|
||||
const cached = widthCache.get(str);
|
||||
if (cached !== undefined) {
|
||||
@@ -77,6 +81,7 @@ export function visibleWidth(str: string): number {
|
||||
widthCache.set(str, width);
|
||||
|
||||
return width;
|
||||
*/
|
||||
}
|
||||
|
||||
const WRAP_OPTIONS = { wordWrap: true, hard: true, trim: false } as const;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oh-my-pi/pi-utils",
|
||||
"version": "9.6.2",
|
||||
"version": "9.6.3",
|
||||
"description": "Shared utilities for pi packages",
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
|
||||
Reference in New Issue
Block a user