diff --git a/Cargo.lock b/Cargo.lock index 3711a6493..8277a7bc2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4716,7 +4716,7 @@ dependencies = [ [[package]] name = "pi-ast" -version = "17.1.1" +version = "17.1.2" dependencies = [ "anyhow", "ast-grep-core", @@ -4785,7 +4785,7 @@ dependencies = [ [[package]] name = "pi-iso" -version = "17.1.1" +version = "17.1.2" dependencies = [ "async-trait", "libc", @@ -4797,7 +4797,7 @@ dependencies = [ [[package]] name = "pi-natives" -version = "17.1.1" +version = "17.1.2" dependencies = [ "anyhow", "arboard", @@ -4860,7 +4860,7 @@ dependencies = [ [[package]] name = "pi-shell" -version = "17.1.1" +version = "17.1.2" dependencies = [ "anyhow", "brush-builtins", @@ -4874,6 +4874,7 @@ dependencies = [ "jaq", "jiff", "libc", + "memchr", "os_pipe", "parking_lot", "pi-uutils-ctx", @@ -4946,7 +4947,7 @@ dependencies = [ [[package]] name = "pi-walker" -version = "17.1.1" +version = "17.1.2" dependencies = [ "dashmap", "globset", diff --git a/Cargo.toml b/Cargo.toml index 373d9d6ec..16a25b2f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ exclude = ["crates/vendor/brush-core", "crates/vendor/brush-builtins"] resolver = "3" [workspace.package] -version = "17.1.1" +version = "17.1.2" edition = "2024" license = "MIT" authors = ["Can Boluk"] diff --git a/bun.lock b/bun.lock index dfdfae976..e08bea85a 100644 --- a/bun.lock +++ b/bun.lock @@ -21,7 +21,7 @@ }, "packages/agent": { "name": "@oh-my-pi/pi-agent-core", - "version": "17.1.1", + "version": "17.1.2", "dependencies": { "@oh-my-pi/pi-ai": "catalog:", "@oh-my-pi/pi-catalog": "catalog:", @@ -39,7 +39,7 @@ }, "packages/ai": { "name": "@oh-my-pi/pi-ai", - "version": "17.1.1", + "version": "17.1.2", "dependencies": { "@bufbuild/protobuf": "catalog:", "@oh-my-pi/pi-catalog": "catalog:", @@ -55,7 +55,7 @@ }, "packages/catalog": { "name": "@oh-my-pi/pi-catalog", - "version": "17.1.1", + "version": "17.1.2", "dependencies": { "@bufbuild/protobuf": "catalog:", "@oh-my-pi/pi-utils": "catalog:", @@ -69,7 +69,7 @@ }, "packages/coding-agent": { "name": "@oh-my-pi/pi-coding-agent", - "version": "17.1.1", + "version": "17.1.2", "bin": { "omp": "src/cli.ts", }, @@ -144,7 +144,7 @@ }, "packages/hashline": { "name": "@oh-my-pi/hashline", - "version": "17.1.1", + "version": "17.1.2", "dependencies": { "@oh-my-pi/pi-natives": "catalog:", "lru-cache": "catalog:", @@ -188,7 +188,7 @@ }, "packages/mnemopi": { "name": "@oh-my-pi/pi-mnemopi", - "version": "17.1.1", + "version": "17.1.2", "bin": { "mnemopi": "src/cli.ts", }, @@ -215,7 +215,7 @@ }, "packages/natives": { "name": "@oh-my-pi/pi-natives", - "version": "17.1.1", + "version": "17.1.2", "devDependencies": { "@napi-rs/cli": "catalog:", "@types/bun": "catalog:", @@ -223,7 +223,7 @@ }, "packages/snapcompact": { "name": "@oh-my-pi/snapcompact", - "version": "17.1.1", + "version": "17.1.2", "dependencies": { "@oh-my-pi/pi-ai": "catalog:", "@oh-my-pi/pi-natives": "catalog:", @@ -236,7 +236,7 @@ }, "packages/stats": { "name": "@oh-my-pi/omp-stats", - "version": "17.1.1", + "version": "17.1.2", "bin": { "omp-stats": "./src/index.ts", }, @@ -263,7 +263,7 @@ }, "packages/swarm-extension": { "name": "@oh-my-pi/swarm-extension", - "version": "17.1.1", + "version": "17.1.2", "bin": { "omp-swarm": "src/cli.ts", }, @@ -279,7 +279,7 @@ }, "packages/tui": { "name": "@oh-my-pi/pi-tui", - "version": "17.1.1", + "version": "17.1.2", "dependencies": { "@oh-my-pi/pi-natives": "catalog:", "@oh-my-pi/pi-utils": "catalog:", @@ -318,7 +318,7 @@ }, "packages/utils": { "name": "@oh-my-pi/pi-utils", - "version": "17.1.1", + "version": "17.1.2", "dependencies": { "@oh-my-pi/pi-natives": "catalog:", "handlebars": "catalog:", @@ -331,7 +331,7 @@ }, "packages/wire": { "name": "@oh-my-pi/pi-wire", - "version": "17.1.1", + "version": "17.1.2", "devDependencies": { "@types/bun": "catalog:", }, @@ -372,18 +372,18 @@ "@huggingface/transformers": "^4.2.0", "@mozilla/readability": "^0.6.0", "@napi-rs/cli": "3.7.2", - "@oh-my-pi/hashline": "17.1.1", - "@oh-my-pi/omp-stats": "17.1.1", - "@oh-my-pi/pi-agent-core": "17.1.1", - "@oh-my-pi/pi-ai": "17.1.1", - "@oh-my-pi/pi-catalog": "17.1.1", - "@oh-my-pi/pi-coding-agent": "17.1.1", - "@oh-my-pi/pi-mnemopi": "17.1.1", - "@oh-my-pi/pi-natives": "17.1.1", - "@oh-my-pi/pi-tui": "17.1.1", - "@oh-my-pi/pi-utils": "17.1.1", - "@oh-my-pi/pi-wire": "17.1.1", - "@oh-my-pi/snapcompact": "17.1.1", + "@oh-my-pi/hashline": "17.1.2", + "@oh-my-pi/omp-stats": "17.1.2", + "@oh-my-pi/pi-agent-core": "17.1.2", + "@oh-my-pi/pi-ai": "17.1.2", + "@oh-my-pi/pi-catalog": "17.1.2", + "@oh-my-pi/pi-coding-agent": "17.1.2", + "@oh-my-pi/pi-mnemopi": "17.1.2", + "@oh-my-pi/pi-natives": "17.1.2", + "@oh-my-pi/pi-tui": "17.1.2", + "@oh-my-pi/pi-utils": "17.1.2", + "@oh-my-pi/pi-wire": "17.1.2", + "@oh-my-pi/snapcompact": "17.1.2", "@opentelemetry/api": "^1.9.1", "@opentelemetry/api-logs": "^0.220.0", "@opentelemetry/context-async-hooks": "^2.9.0", @@ -495,29 +495,29 @@ "@babel/types": ["@babel/types@7.29.7", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA=="], - "@biomejs/biome": ["@biomejs/biome@2.5.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.5.4", "@biomejs/cli-darwin-x64": "2.5.4", "@biomejs/cli-linux-arm64": "2.5.4", "@biomejs/cli-linux-arm64-musl": "2.5.4", "@biomejs/cli-linux-x64": "2.5.4", "@biomejs/cli-linux-x64-musl": "2.5.4", "@biomejs/cli-win32-arm64": "2.5.4", "@biomejs/cli-win32-x64": "2.5.4" }, "bin": { "biome": "bin/biome" } }, "sha512-xy5FNE5kQJKyK5MR1gJy6ztXYx4WBAbYGlK04lMEgmyPRWKybY9NFwiG9yo0XdzOU8Xvhj41u034J1ywfoWfMw=="], + "@biomejs/biome": ["@biomejs/biome@2.5.5", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.5.5", "@biomejs/cli-darwin-x64": "2.5.5", "@biomejs/cli-linux-arm64": "2.5.5", "@biomejs/cli-linux-arm64-musl": "2.5.5", "@biomejs/cli-linux-x64": "2.5.5", "@biomejs/cli-linux-x64-musl": "2.5.5", "@biomejs/cli-win32-arm64": "2.5.5", "@biomejs/cli-win32-x64": "2.5.5" }, "bin": { "biome": "bin/biome" } }, "sha512-r1S8nFsAG1MY+vJFZALzIvwXAJv6ejDQ0mxP21Tgr9YK3ZFtjrvbBwDdNhx1rUqvccEIeNg20cYCNzl6Cr69pQ=="], - "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.5.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-4o3NFRobXHynkgcFVrlZsoDAFtF2ldlEGN8sORSws5ZQqyY4PXnPUIylu4ksfyHuwkfvDREuWh3JK+niRwGq3w=="], + "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.5.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-kUrAhXVWUrwmAUnV2iXSK7umxKFysTwvqK+Ty6ptUcLY/7T3SnCAjUowE4uvwaEej6nXZ7hu/dTtbokKdsPeag=="], - "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.5.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-D32P5HkU2Y6PySuC/WsVDTOgsDwVFmujzhhhOQjajtATpVWFDXuVd3oRbsWNSEA+aaFzyzZm22szsyydBYlSyQ=="], + "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.5.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-DamiYc5bUYZ2uxlfc+RLEPtz1Abb6PO5eTbOkufLpSGwd/7AMQAdxhFYiXmwwkJL8IsT8S7GvdgwDHqaMFAvKw=="], - "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.5.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-pSEfW7B8kTsXUjUxC1xVVK+y85Ht3C5XxZ9gclmC7/3Ku9Vqz8jmI7k0p/BNIjQ6t4sFERI2sFeH73ybiZl6YQ=="], + "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.5.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-lRKF/pH/1RiYiBKExi3TCZVAtvzEm77aifrvcNiDFrR9WxeAnDUjDnseb6y2XV85mjitLs6SILGm2XG77cHtSQ=="], - "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.5.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-Rpm5/AT1m+DlJmUoYvS4/vXc+0tXJPJ2NQz25TGPyHVF5JrWy75PE0GH6kVxsKtQDuCH4OgzquZq0R4kj/wCVg=="], + "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.5.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-U4WMl/sy/E/Q73vf15VspakLRRs2LDFcCeBxJnQfXzssb88zpV6PJPaQ3ezhQ7H6Ht2/8bvuZeHgJWzmoxllZg=="], - "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.5.4", "", { "os": "linux", "cpu": "x64" }, "sha512-FNxojWJkL7EajAuzBgoLe0T2G0y112M4lBrDIFl/DomFTx8yqenYOIdsRLNXvOvBBofE8hJi85LjzLmBDpY7/Q=="], + "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.5.5", "", { "os": "linux", "cpu": "x64" }, "sha512-H/O39nJEw/2Zm/fm7hrmxxoF8kK/aU1uCoPp70ruXVbomaAdLpJJnCmL11Q2JotT8QVHH06So04Oq53lCSwSwQ=="], - "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.5.4", "", { "os": "linux", "cpu": "x64" }, "sha512-aby/PohmmgbShcHqFsZVzG8H6D98+P+A6xRWRrQcLW1pCjabcov5UUlke4UqNQBYTkDQav+jB4zyyDDeKB2GaA=="], + "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.5.5", "", { "os": "linux", "cpu": "x64" }, "sha512-m7wC7tjX5Lrmo69dc4md8FeKpPU1NTCY1v7xUoQQ2vadWwNnBS0KZOG8471otFPHrTHihQJAjQPgMObpLvDe6A=="], - "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.5.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-emoXexPZIPAZkz2RKmA95WJUqK3I5MJNYtwEbL5ESciRzhmFMMyekDhNG8hpeOaK+ZGRDxAU4wvGuA5IHQ0h0w=="], + "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.5.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-7BryINPuYypLUAH3o/o5ZdgomJ4zn3EDR0ChZJst7n32S6ZhKbgHXuYydLu+YAnx59ehGFR0z/MG6qnzQi3Yyw=="], - "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.5.4", "", { "os": "win32", "cpu": "x64" }, "sha512-U1jaluLw1qQc2Tx7/CeSoL9N5XcqIH+GWjpUAy1ouB5nVjSCMNO+NNHdY3RAs8zxNurLWAdj6pehQdCA2zyU+Q=="], + "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.5.5", "", { "os": "win32", "cpu": "x64" }, "sha512-bIBFo+n6MIxdNcVFy5CrurbKiZQiUciK3bt8+O9I4wjFZNTfXLpi+giq47522eXqW5NBc9ulx7dR1SlZKi2J5g=="], - "@bufbuild/protobuf": ["@bufbuild/protobuf@2.12.1", "", {}, "sha512-BvAMfS6LrgZiryOAZ4pBYucu4wG/Ei/9o9DZ9akbREnMLbPJiom2i8b9C8IsKErQoiKqVhrerzt3kOT/RrzLHg=="], + "@bufbuild/protobuf": ["@bufbuild/protobuf@2.13.0", "", {}, "sha512-acq7c49vxfm1ggJ95P70TX7ABDM0vxr1SYD3BB0o0jnBLB4OAqeHyKuN+cD3w80gXEDQ2zxHpR6CUeA+O/aU9g=="], - "@bufbuild/protoc-gen-es": ["@bufbuild/protoc-gen-es@2.12.1", "", { "dependencies": { "@bufbuild/protobuf": "2.12.1", "@bufbuild/protoplugin": "2.12.1" }, "bin": { "protoc-gen-es": "bin/protoc-gen-es" } }, "sha512-SWa7XvRYRouMo+vBQmpNFZ+ZEqQ8AC0LpL4QWAo1gvstLhFh/Y7Nf/a+MK7ZxDq5LZSThwfk974L1sFxO3OaGw=="], + "@bufbuild/protoc-gen-es": ["@bufbuild/protoc-gen-es@2.13.0", "", { "dependencies": { "@bufbuild/protobuf": "2.13.0", "@bufbuild/protoplugin": "2.13.0" }, "bin": { "protoc-gen-es": "bin/protoc-gen-es" } }, "sha512-ylI1vrLksdnXrVZRs9xGxmrQxKGhUm6pPszv26kqBvNiO3qPTktk+hgfwbLISBY4M/reShkT2dFLGT9fbydBXg=="], - "@bufbuild/protoplugin": ["@bufbuild/protoplugin@2.12.1", "", { "dependencies": { "@bufbuild/protobuf": "2.12.1", "@typescript/vfs": "^1.6.2", "typescript": "5.4.5" } }, "sha512-PY58KxQVAD1BnnKtStOctsMoegEVGfBnY5AOqVQOIu711nA13oYtTqJM8df5lUQg2J1DR3XxUXptE+fWX5oLdA=="], + "@bufbuild/protoplugin": ["@bufbuild/protoplugin@2.13.0", "", { "dependencies": { "@bufbuild/protobuf": "2.13.0", "@typescript/vfs": "^1.6.2", "typescript": "5.4.5" } }, "sha512-32eMChKaL/A8Hh5AfMmXSdnuyznN85uoEjoyWiWeRrvtQOtpqX/v1R9PDe0g9vMIgzznK9inMT3CUaal0kjLUQ=="], "@colors/colors": ["@colors/colors@1.6.0", "", {}, "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA=="], @@ -1045,7 +1045,7 @@ "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], - "baseline-browser-mapping": ["baseline-browser-mapping@2.10.44", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-T3ghW+sl/ZJ8w1v/yQx3qvJ9040DWoLBz8JT/CILbAKcFyG9b2MRe75v6W5uXjv6uH1lumK2Kv46y2zSkcej0Q=="], + "baseline-browser-mapping": ["baseline-browser-mapping@2.11.0", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-oCu2wfipvX3AePSgmOuKkIywOu+8n9psz7hXYmk56ghpu3+7KzNIBopaOs4c9BrtdnTtW30unG9GTfHo7EwERQ=="], "before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="], @@ -1405,7 +1405,7 @@ "platform": ["platform@1.3.6", "", {}, "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg=="], - "postcss": ["postcss@8.5.20", "", { "dependencies": { "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-lW616l85ucIQL+FocMmL7pQFPqBmwejrCMg+iPxyImlrANNJG9NHq/RkyCZopDhd8C3LA03PHRJDjkbGu8vvug=="], + "postcss": ["postcss@8.5.21", "", { "dependencies": { "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-v4sDNP3fdNiWMfabO7OwOQdOX8TiQSztKyT1Wj0w+j7LDallJThJRBBBmzVGyYj0crMh7jlV4zepPkiNu9UwDQ=="], "prettier": ["prettier@3.9.6", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g=="], @@ -1647,6 +1647,8 @@ "string_decoder/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], + "vite/lightningcss": ["lightningcss@1.33.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.33.0", "lightningcss-darwin-arm64": "1.33.0", "lightningcss-darwin-x64": "1.33.0", "lightningcss-freebsd-x64": "1.33.0", "lightningcss-linux-arm-gnueabihf": "1.33.0", "lightningcss-linux-arm64-gnu": "1.33.0", "lightningcss-linux-arm64-musl": "1.33.0", "lightningcss-linux-x64-gnu": "1.33.0", "lightningcss-linux-x64-musl": "1.33.0", "lightningcss-win32-arm64-msvc": "1.33.0", "lightningcss-win32-x64-msvc": "1.33.0" } }, "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA=="], + "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], "@huggingface/transformers/onnxruntime-node/global-agent": ["global-agent@3.0.0", "", { "dependencies": { "boolean": "^3.0.1", "es6-error": "^4.1.1", "matcher": "^3.0.0", "roarr": "^2.15.3", "semver": "^7.3.2", "serialize-error": "^7.0.1" } }, "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q=="], @@ -1667,6 +1669,28 @@ "jszip/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], + "vite/lightningcss/lightningcss-android-arm64": ["lightningcss-android-arm64@1.33.0", "", { "os": "android", "cpu": "arm64" }, "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg=="], + + "vite/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.33.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg=="], + + "vite/lightningcss/lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.33.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ=="], + + "vite/lightningcss/lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.33.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg=="], + + "vite/lightningcss/lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.33.0", "", { "os": "linux", "cpu": "arm" }, "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ=="], + + "vite/lightningcss/lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.33.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg=="], + + "vite/lightningcss/lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.33.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ=="], + + "vite/lightningcss/lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.33.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg=="], + + "vite/lightningcss/lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.33.0", "", { "os": "linux", "cpu": "x64" }, "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw=="], + + "vite/lightningcss/lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.33.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA=="], + + "vite/lightningcss/lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.33.0", "", { "os": "win32", "cpu": "x64" }, "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA=="], + "@huggingface/transformers/onnxruntime-node/global-agent/matcher": ["matcher@3.0.0", "", { "dependencies": { "escape-string-regexp": "^4.0.0" } }, "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng=="], "@huggingface/transformers/onnxruntime-node/global-agent/serialize-error": ["serialize-error@7.0.1", "", { "dependencies": { "type-fest": "^0.13.1" } }, "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw=="], diff --git a/crates/pi-natives/src/lib.rs b/crates/pi-natives/src/lib.rs index 87648b7ac..0e2bbd6ab 100644 --- a/crates/pi-natives/src/lib.rs +++ b/crates/pi-natives/src/lib.rs @@ -260,7 +260,7 @@ fn create_windows_napi_tokio_runtime() -> Option { /// MUST stay in sync with `VERSION_SENTINEL_EXPORT` in /// `packages/natives/native/index.js` (which derives the name from /// `package.json#version`). -#[napi(js_name = "__piNativesV17_1_1")] +#[napi(js_name = "__piNativesV17_1_2")] pub const fn pi_natives_version_sentinel() {} /// Native module entry point: install crash diagnostics before any tool can diff --git a/crates/pi-shell/Cargo.toml b/crates/pi-shell/Cargo.toml index e67032299..07ab77a05 100644 --- a/crates/pi-shell/Cargo.toml +++ b/crates/pi-shell/Cargo.toml @@ -80,6 +80,7 @@ uu_sed = { path = "../vendor/uu-sed" } uu_xargs = { path = "../vendor/uu-xargs" } jaq = { path = "../vendor/jaq" } jiff = { version = "0.2", features = ["tzdb-bundle-platform"] } +memchr = "2" [target.'cfg(unix)'.dependencies] libc.workspace = true diff --git a/crates/pi-shell/src/moreutils/combine.rs b/crates/pi-shell/src/moreutils/combine.rs index c0fca8295..ab241685e 100644 --- a/crates/pi-shell/src/moreutils/combine.rs +++ b/crates/pi-shell/src/moreutils/combine.rs @@ -5,7 +5,7 @@ //! byte strings; membership comparison strips a trailing `\n`, so a final line //! without a newline still matches, and is emitted as-is (no newline added). //! Usage errors (wrong arg count, unknown OP, both sides stdin) exit 1, unlike -//! moreutils' die() exit 255. +//! moreutils' `die()` exit 255. use std::{ collections::HashSet, @@ -36,7 +36,7 @@ enum Error { impl From for Error { fn from(msg: String) -> Self { - Error::Msg(msg) + Self::Msg(msg) } } @@ -56,9 +56,15 @@ pub fn run(argv: Vec) -> i32 { }, }; - let file1 = matches.get_one::(ARG_FILE1).expect("required").clone(); + let file1 = matches + .get_one::(ARG_FILE1) + .expect("required") + .clone(); let op = matches.get_one::(ARG_OP).expect("required"); - let file2 = matches.get_one::(ARG_FILE2).expect("required").clone(); + let file2 = matches + .get_one::(ARG_FILE2) + .expect("required") + .clone(); match execute(&file1, op, &file2) { Ok(()) => 0, @@ -158,8 +164,7 @@ fn open_input(name: &OsStr) -> Result, Error> { return Ok(Box::new(BufReader::new(pi_uutils_ctx::stdin()))); } let path = pi_uutils_ctx::resolve(name); - let file = - File::open(path).map_err(|err| Error::Msg(input_error(name, &err.to_string())))?; + let file = File::open(path).map_err(|err| Error::Msg(input_error(name, &err.to_string())))?; Ok(Box::new(BufReader::new(file))) } @@ -202,7 +207,8 @@ fn key(line: &[u8]) -> &[u8] { } fn write_line(out: &mut impl Write, line: &[u8]) -> Result<(), Error> { - out.write_all(line).map_err(|err| Error::Msg(err.to_string())) + out.write_all(line) + .map_err(|err| Error::Msg(err.to_string())) } fn input_error(name: &OsStr, err: &str) -> String { diff --git a/crates/pi-shell/src/moreutils/errno.rs b/crates/pi-shell/src/moreutils/errno.rs index eb848a613..c8e4755ba 100644 --- a/crates/pi-shell/src/moreutils/errno.rs +++ b/crates/pi-shell/src/moreutils/errno.rs @@ -9,8 +9,7 @@ //! then name; `--search` prints entries whose description contains all the //! given words case-insensitively. -use std::ffi::OsString; -use std::io::Write; +use std::{ffi::OsString, io::Write}; use clap::{Arg, ArgAction, Command}; use pi_uutils_ctx::format_usage; @@ -144,7 +143,7 @@ pub fn run(argv: Vec) -> i32 { failed = true; } } - if failed { 1 } else { 0 } + i32::from(failed) } fn command() -> Command { @@ -203,17 +202,15 @@ fn lookup(arg: &str) -> bool { }, None => false, } + } else if let Some((name, value)) = ERRNOS + .iter() + .find(|(name, _)| name.eq_ignore_ascii_case(arg)) + { + print_entry(name, *value); + true } else { - match ERRNOS.iter().find(|(name, _)| name.eq_ignore_ascii_case(arg)) { - Some((name, value)) => { - print_entry(name, *value); - true - }, - None => { - let _ = writeln!(pi_uutils_ctx::stderr(), "errno: unknown errno {arg}"); - false - }, - } + let _ = writeln!(pi_uutils_ctx::stderr(), "errno: unknown errno {arg}"); + false } } @@ -272,14 +269,14 @@ mod tests { let stdout = Arc::new(Mutex::new(Vec::new())); let stderr = Arc::new(Mutex::new(Vec::new())); let io = ScopeIo { - stdin: Box::new(Cursor::new(Vec::new())), - stdin_fd: None, + stdin: Box::new(Cursor::new(Vec::new())), + stdin_fd: None, stdin_is_search_input: false, - stdout: Box::new(SharedWriter(Arc::clone(&stdout))), - stderr: Box::new(SharedWriter(Arc::clone(&stderr))), - cwd: std::env::temp_dir(), - env: HashMap::new(), - cancel: Arc::new(AtomicBool::new(false)), + stdout: Box::new(SharedWriter(Arc::clone(&stdout))), + stderr: Box::new(SharedWriter(Arc::clone(&stderr))), + cwd: std::env::temp_dir(), + env: HashMap::new(), + cancel: Arc::new(AtomicBool::new(false)), }; let argv = std::iter::once("errno") .chain(args.iter().copied()) diff --git a/crates/pi-shell/src/moreutils/ifne.rs b/crates/pi-shell/src/moreutils/ifne.rs index 31286e1e9..b3aee2e39 100644 --- a/crates/pi-shell/src/moreutils/ifne.rs +++ b/crates/pi-shell/src/moreutils/ifne.rs @@ -19,7 +19,11 @@ const CHUNK: usize = 64 * 1024; pub fn run(argv: Vec) -> i32 { let mut args = argv.into_iter().skip(1).peekable(); let mut invert = false; - match args.peek().map(|a| a.to_string_lossy().into_owned()).as_deref() { + match args + .peek() + .map(|a| a.to_string_lossy().into_owned()) + .as_deref() + { Some("-n") => { invert = true; args.next(); @@ -90,11 +94,7 @@ fn spawn_and_pump(command: &[OsString], first: Option, stdin: &mut impl Read { Ok(child) => child, Err(err) => { - let _ = writeln!( - pi_uutils_ctx::stderr(), - "ifne: {}: {err}", - command[0].to_string_lossy() - ); + let _ = writeln!(pi_uutils_ctx::stderr(), "ifne: {}: {err}", command[0].to_string_lossy()); return 127; }, }; @@ -120,9 +120,7 @@ fn spawn_and_pump(command: &[OsString], first: Option, stdin: &mut impl Read // Ignore BrokenPipe: the child may exit before consuming its stdin // (e.g. `ifne head -1`). let pump = match copy_cancellable(stdin, &mut child_stdin, first) { - Err(CopyError::Io(err)) if err.kind() != ErrorKind::BrokenPipe => { - Err(CopyError::Io(err)) - }, + Err(CopyError::Io(err)) if err.kind() != ErrorKind::BrokenPipe => Err(CopyError::Io(err)), Err(CopyError::Cancelled) => Err(CopyError::Cancelled), _ => Ok(()), }; @@ -170,7 +168,7 @@ fn copy_cancellable( if let Some(byte) = first { dst.write_all(&[byte]).map_err(CopyError::Io)?; } - let mut buf = [0u8; CHUNK]; + let mut buf = vec![0u8; CHUNK].into_boxed_slice(); loop { if pi_uutils_ctx::is_cancelled() { return Err(CopyError::Cancelled); @@ -231,14 +229,14 @@ mod tests { let stdout = Arc::new(Mutex::new(Vec::new())); let stderr = Arc::new(Mutex::new(Vec::new())); let io = ScopeIo { - stdin: Box::new(Cursor::new(stdin.to_vec())), - stdin_fd: None, + stdin: Box::new(Cursor::new(stdin.to_vec())), + stdin_fd: None, stdin_is_search_input: false, - stdout: Box::new(SharedWriter(Arc::clone(&stdout))), - stderr: Box::new(SharedWriter(Arc::clone(&stderr))), - cwd: std::env::temp_dir(), - env: HashMap::from([("PATH".to_string(), "/usr/bin:/bin".to_string())]), - cancel: Arc::new(AtomicBool::new(false)), + stdout: Box::new(SharedWriter(Arc::clone(&stdout))), + stderr: Box::new(SharedWriter(Arc::clone(&stderr))), + cwd: std::env::temp_dir(), + env: HashMap::from([("PATH".to_string(), "/usr/bin:/bin".to_string())]), + cancel: Arc::new(AtomicBool::new(false)), }; let argv = std::iter::once("ifne") .chain(args.iter().copied()) diff --git a/crates/pi-shell/src/moreutils/isutf8.rs b/crates/pi-shell/src/moreutils/isutf8.rs index 2539c1d94..c992d783d 100644 --- a/crates/pi-shell/src/moreutils/isutf8.rs +++ b/crates/pi-shell/src/moreutils/isutf8.rs @@ -57,8 +57,7 @@ pub fn run(argv: Vec) -> i32 { let invert = matches.get_flag(OPT_INVERT); let files: Vec = matches .get_many::(ARG_FILES) - .map(|values| values.cloned().collect()) - .unwrap_or_else(|| vec![OsString::from("-")]); + .map_or_else(|| vec![OsString::from("-")], |values| values.cloned().collect()); let mut any_failed = false; let mut io_error = false; @@ -91,13 +90,7 @@ pub fn run(argv: Vec) -> i32 { } } - if io_error { - 2 - } else if any_failed { - 1 - } else { - 0 - } + if io_error { 2 } else { i32::from(any_failed) } } fn command() -> Command { @@ -202,9 +195,9 @@ fn validate(input: &mut impl Read) -> io::Result { /// Updates line/char counters over `text`, a slice already known to be valid /// UTF-8 (chars are counted as non-continuation bytes, so no re-decode). fn advance(text: &[u8], line: &mut u64, chars_in_line: &mut u64) { - match text.iter().rposition(|&b| b == b'\n') { + match memchr::memrchr(b'\n', text) { Some(last) => { - *line += text.iter().filter(|&&b| b == b'\n').count() as u64; + *line += memchr::memchr_iter(b'\n', text).count() as u64; *chars_in_line = count_chars(&text[last + 1..]); }, None => *chars_in_line += count_chars(text), @@ -212,7 +205,7 @@ fn advance(text: &[u8], line: &mut u64, chars_in_line: &mut u64) { } fn count_chars(bytes: &[u8]) -> u64 { - bytes.iter().filter(|&&b| (b & 0xC0) != 0x80).count() as u64 + bytes.iter().filter(|&&b| (b & 0xc0) != 0x80).count() as u64 } fn display_name(name: &OsStr) -> String { @@ -319,7 +312,7 @@ mod tests { fn truncated_sequence_at_chunk_boundary_is_invalid() { let (_dir, root) = tempdir(); let mut bytes = vec![b'a'; 65535]; - bytes.push(0xC3); // incomplete at the exact chunk boundary + bytes.push(0xc3); // incomplete at the exact chunk boundary bytes.extend_from_slice(b"zzz"); fs::write(root.join("cut"), &bytes).unwrap(); @@ -374,7 +367,10 @@ mod tests { fn stdin_is_validated_when_no_files_given() { let (_dir, root) = tempdir(); - assert_eq!(run_in(root.clone(), "héllo\n".as_bytes(), &[]), (0, String::new(), String::new())); + assert_eq!( + run_in(root.clone(), "héllo\n".as_bytes(), &[]), + (0, String::new(), String::new()) + ); let (code, stdout, _) = run_in(root, b"h\xFFi", &[]); assert_eq!(code, 1); diff --git a/crates/pi-shell/src/moreutils/sponge.rs b/crates/pi-shell/src/moreutils/sponge.rs index 467b5a9d6..7b91daaec 100644 --- a/crates/pi-shell/src/moreutils/sponge.rs +++ b/crates/pi-shell/src/moreutils/sponge.rs @@ -85,7 +85,11 @@ fn command() -> Command { .action(ArgAction::SetTrue), ) .arg(Arg::new("help").long("help").action(ArgAction::Help)) - .arg(Arg::new("version").long("version").action(ArgAction::Version)) + .arg( + Arg::new("version") + .long("version") + .action(ArgAction::Version), + ) .arg( Arg::new(ARG_FILE) .value_name("FILE") @@ -103,7 +107,7 @@ enum SoakError { fn soak_stdin() -> Result, SoakError> { let mut stdin = pi_uutils_ctx::stdin(); let mut buffer = Vec::new(); - let mut chunk = [0u8; CHUNK_SIZE]; + let mut chunk = vec![0u8; CHUNK_SIZE].into_boxed_slice(); loop { if pi_uutils_ctx::is_cancelled() { return Err(SoakError::Cancelled); @@ -135,7 +139,12 @@ fn replace_atomically(target: &Path, buffer: &[u8]) -> io::Result<()> { result } -fn write_and_swap(target: &Path, temp_path: &Path, temp: &mut File, buffer: &[u8]) -> io::Result<()> { +fn write_and_swap( + target: &Path, + temp_path: &Path, + temp: &mut File, + buffer: &[u8], +) -> io::Result<()> { temp.write_all(buffer)?; temp.flush()?; if let Ok(metadata) = fs::metadata(target) { @@ -148,8 +157,14 @@ fn write_and_swap(target: &Path, temp_path: &Path, temp: &mut File, buffer: &[u8 /// `target` with `create_new`, retrying on collision. fn create_sibling_temp(target: &Path) -> io::Result<(PathBuf, File)> { static COUNTER: AtomicU64 = AtomicU64::new(0); - let dir = target.parent().filter(|p| !p.as_os_str().is_empty()).unwrap_or(Path::new(".")); - let base = target.file_name().unwrap_or(OsStr::new("sponge")).to_string_lossy(); + let dir = target + .parent() + .filter(|p| !p.as_os_str().is_empty()) + .unwrap_or_else(|| Path::new(".")); + let base = target + .file_name() + .unwrap_or_else(|| OsStr::new("sponge")) + .to_string_lossy(); for _ in 0..32 { let nanos = SystemTime::now() .duration_since(UNIX_EPOCH) diff --git a/crates/pi-shell/src/moreutils/ts.rs b/crates/pi-shell/src/moreutils/ts.rs index c835d55fc..2222a3ee0 100644 --- a/crates/pi-shell/src/moreutils/ts.rs +++ b/crates/pi-shell/src/moreutils/ts.rs @@ -6,8 +6,8 @@ //! - `-i`: time elapsed since the previous line (default format `%H:%M:%S`) //! - `-s`: time elapsed since program start (default format `%H:%M:%S`) //! - `-m`: use the monotonic clock for `-i`/`-s` elapsed computation -//! - `-r`: rewrite an existing leading timestamp (RFC3339/ISO8601 or syslog -//! `%b %d %H:%M:%S`) into a human-relative form +//! - `-r`: rewrite an existing leading timestamp (RFC3339/ISO8601 or syslog `%b +//! %d %H:%M:%S`) into a human-relative form //! //! Elapsed durations are formatted as if they were seconds since the Unix //! epoch rendered in UTC (matching moreutils), so 90 elapsed seconds with @@ -100,8 +100,16 @@ fn command() -> Command { .action(ArgAction::SetTrue), ) .arg(Arg::new("help").long("help").action(ArgAction::Help)) - .arg(Arg::new("version").long("version").action(ArgAction::Version)) - .arg(Arg::new(ARG_FORMAT).value_name("FORMAT").help("strftime format string")) + .arg( + Arg::new("version") + .long("version") + .action(ArgAction::Version), + ) + .arg( + Arg::new(ARG_FORMAT) + .value_name("FORMAT") + .help("strftime format string"), + ) } /// Timestamping mode selected by the flags. @@ -149,7 +157,9 @@ fn timestamp_lines(matches: &ArgMatches) -> Result { return Ok(130); } buf.clear(); - let n = reader.read_until(b'\n', &mut buf).map_err(|err| err.to_string())?; + let n = reader + .read_until(b'\n', &mut buf) + .map_err(|err| err.to_string())?; if n == 0 { break; } @@ -162,8 +172,10 @@ fn timestamp_lines(matches: &ArgMatches) -> Result { let year = now.to_zoned(tz.clone()).year(); if let Some((consumed, then)) = parse_leading_timestamp(content, year, &tz) { let rel = render_relative(then, now); - out.write_all(rel.as_bytes()).map_err(|err| err.to_string())?; - out.write_all(&content[consumed..]).map_err(|err| err.to_string())?; + out.write_all(rel.as_bytes()) + .map_err(|err| err.to_string())?; + out.write_all(&content[consumed..]) + .map_err(|err| err.to_string())?; } else { out.write_all(content).map_err(|err| err.to_string())?; } @@ -171,24 +183,34 @@ fn timestamp_lines(matches: &ArgMatches) -> Result { Mode::Absolute => { let zoned = Timestamp::now().to_zoned(tz.clone()); let stamp = strtime::format(&format, &zoned).map_err(|err| err.to_string())?; - out.write_all(stamp.as_bytes()).map_err(|err| err.to_string())?; + out.write_all(stamp.as_bytes()) + .map_err(|err| err.to_string())?; out.write_all(b" ").map_err(|err| err.to_string())?; out.write_all(content).map_err(|err| err.to_string())?; }, Mode::SinceLast | Mode::SinceStart => { let nanos = if monotonic { let now = Instant::now(); - let anchor = if mode == Mode::SinceLast { last_mono } else { start_mono }; + let anchor = if mode == Mode::SinceLast { + last_mono + } else { + start_mono + }; last_mono = now; i128::try_from(now.duration_since(anchor).as_nanos()).unwrap_or(i128::MAX) } else { let now = Timestamp::now(); - let anchor = if mode == Mode::SinceLast { last_wall } else { start_wall }; + let anchor = if mode == Mode::SinceLast { + last_wall + } else { + start_wall + }; last_wall = now; now.duration_since(anchor).as_nanos().max(0) }; let stamp = format_elapsed(nanos, &format)?; - out.write_all(stamp.as_bytes()).map_err(|err| err.to_string())?; + out.write_all(stamp.as_bytes()) + .map_err(|err| err.to_string())?; out.write_all(b" ").map_err(|err| err.to_string())?; out.write_all(content).map_err(|err| err.to_string())?; }, @@ -262,11 +284,11 @@ fn expand_subseconds(format: &str) -> String { /// Length of the UTF-8 sequence introduced by `first` (1 for continuation or /// invalid bytes, which only arise from already-valid `&str` input here). -fn utf8_len(first: u8) -> usize { +const fn utf8_len(first: u8) -> usize { match first { - 0xC0..=0xDF => 2, - 0xE0..=0xEF => 3, - 0xF0..=0xF7 => 4, + 0xc0..=0xdf => 2, + 0xe0..=0xef => 3, + 0xf0..=0xf7 => 4, _ => 1, } } @@ -364,14 +386,14 @@ mod tests { let stdout = Arc::new(Mutex::new(Vec::new())); let stderr = Arc::new(Mutex::new(Vec::new())); let io = ScopeIo { - stdin: Box::new(Cursor::new(stdin.to_vec())), - stdin_fd: None, + stdin: Box::new(Cursor::new(stdin.to_vec())), + stdin_fd: None, stdin_is_search_input: false, - stdout: Box::new(SharedWriter(Arc::clone(&stdout))), - stderr: Box::new(SharedWriter(Arc::clone(&stderr))), - cwd: std::env::temp_dir(), - env: HashMap::from([("TZ".to_string(), "UTC".to_string())]), - cancel: Arc::new(AtomicBool::new(false)), + stdout: Box::new(SharedWriter(Arc::clone(&stdout))), + stderr: Box::new(SharedWriter(Arc::clone(&stderr))), + cwd: std::env::temp_dir(), + env: HashMap::from([("TZ".to_string(), "UTC".to_string())]), + cancel: Arc::new(AtomicBool::new(false)), }; let argv = std::iter::once("ts") .chain(args.iter().copied()) @@ -444,7 +466,7 @@ mod tests { #[test] fn relative_conflicts_with_elapsed_modes() { - let (code, _, _) = run_in(b"", &["-r", "-i"]); + let (code, ..) = run_in(b"", &["-r", "-i"]); assert_eq!(code, 2); } @@ -475,8 +497,7 @@ mod tests { assert_eq!(ts, "2024-01-01T17:00:00.5Z".parse::().unwrap()); // Civil datetime without offset resolves in the provided timezone. - let (consumed, ts) = - parse_leading_timestamp(b"2024-01-01T12:00:00 x", 2024, &tz).unwrap(); + let (consumed, ts) = parse_leading_timestamp(b"2024-01-01T12:00:00 x", 2024, &tz).unwrap(); assert_eq!(consumed, 19); assert_eq!(ts, "2024-01-01T12:00:00Z".parse::().unwrap()); diff --git a/crates/pi-shell/src/shell.rs b/crates/pi-shell/src/shell.rs index 000980f30..85e41fd12 100644 --- a/crates/pi-shell/src/shell.rs +++ b/crates/pi-shell/src/shell.rs @@ -2234,13 +2234,14 @@ mod tests { params.set_fd(OpenFiles::STDERR_FD, null_file().expect("null stderr")); let source_info = SourceInfo::from("pi-natives:test"); - let script = "PATH=/definitely-missing\n\ - echo x | ts -s '%H:%M:%S' | sponge out || exit 10\n\ - isutf8 out || exit 11\n\ - echo x | combine - and out || exit 12\n\ - ifne /definitely-missing/tool || exit 13"; - let result = - session.shell.run_string(script, &source_info, ¶ms).await.expect("moreutils script"); + let script = "PATH=/definitely-missing\necho x | ts -s '%H:%M:%S' | sponge out || exit \ + 10\nisutf8 out || exit 11\necho x | combine - and out || exit 12\nifne \ + /definitely-missing/tool || exit 13"; + let result = session + .shell + .run_string(script, &source_info, ¶ms) + .await + .expect("moreutils script"); assert_eq!(exit_code(&result), 0); // `ts -s` stamps the first line with zero elapsed time: `HH:MM:SS x`. diff --git a/package.json b/package.json index f65056e12..e3d02794e 100644 --- a/package.json +++ b/package.json @@ -26,18 +26,18 @@ "@huggingface/transformers": "^4.2.0", "@mozilla/readability": "^0.6.0", "@napi-rs/cli": "3.7.2", - "@oh-my-pi/hashline": "17.1.1", - "@oh-my-pi/omp-stats": "17.1.1", - "@oh-my-pi/pi-agent-core": "17.1.1", - "@oh-my-pi/pi-ai": "17.1.1", - "@oh-my-pi/pi-catalog": "17.1.1", - "@oh-my-pi/pi-coding-agent": "17.1.1", - "@oh-my-pi/pi-mnemopi": "17.1.1", - "@oh-my-pi/pi-natives": "17.1.1", - "@oh-my-pi/pi-tui": "17.1.1", - "@oh-my-pi/pi-utils": "17.1.1", - "@oh-my-pi/pi-wire": "17.1.1", - "@oh-my-pi/snapcompact": "17.1.1", + "@oh-my-pi/hashline": "17.1.2", + "@oh-my-pi/omp-stats": "17.1.2", + "@oh-my-pi/pi-agent-core": "17.1.2", + "@oh-my-pi/pi-ai": "17.1.2", + "@oh-my-pi/pi-catalog": "17.1.2", + "@oh-my-pi/pi-coding-agent": "17.1.2", + "@oh-my-pi/pi-mnemopi": "17.1.2", + "@oh-my-pi/pi-natives": "17.1.2", + "@oh-my-pi/pi-tui": "17.1.2", + "@oh-my-pi/pi-utils": "17.1.2", + "@oh-my-pi/pi-wire": "17.1.2", + "@oh-my-pi/snapcompact": "17.1.2", "@opentelemetry/api": "^1.9.1", "@opentelemetry/api-logs": "^0.220.0", "@opentelemetry/context-async-hooks": "^2.9.0", diff --git a/packages/agent/CHANGELOG.md b/packages/agent/CHANGELOG.md index f4b10a7d7..2cb3f71dc 100644 --- a/packages/agent/CHANGELOG.md +++ b/packages/agent/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +## [17.1.2] - 2026-07-24 + ### Added - Added `resolveFallbackTool` option to allow routing unadvertised tool calls to host-side transports (e.g., device mounts) diff --git a/packages/agent/package.json b/packages/agent/package.json index eb4e681f9..269c23de3 100644 --- a/packages/agent/package.json +++ b/packages/agent/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/pi-agent-core", - "version": "17.1.1", + "version": "17.1.2", "description": "General-purpose agent with transport abstraction, state management, and attachment support", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 5ef3ae614..e042190d2 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +## [17.1.2] - 2026-07-24 + ### Added - Added `GET /v1/usage/history` to the auth broker (recorded usage-limit snapshots with `sinceMs`/`provider` filters) and `AuthBrokerClient.fetchUsageHistory` — in broker deployments the broker host performs every upstream usage fetch, so its durable history is the only complete utilization record @@ -10,11 +12,10 @@ ### Changed - Renamed the Z.AI feature quota row to `ZAI Zread Quota` (tier/id slug `zread`), replacing the 74-char `ZAI Web Search / Reader / Zread Quota (web-search-reader-zread)` title that wrapped `omp usage` rows + ### Fixed - Fixed every Claude (`anthropic-messages`) model on the `opencode-zen` provider failing with `401 Missing API key`: the gateway requires `x-api-key`, so `opencode-zen` now uses X-Api-Key auth like `opencode-go`/`umans` instead of bearer-only, and no longer sends the `context_management` field its Anthropic proxy rejects on thinking requests ([#6510](https://github.com/can1357/oh-my-pi/issues/6510)). -### Fixed - - Fixed Anthropic native server-tool blocks being dropped from persisted assistant turns, preserving signed web-search continuations in their original response order ([#6495](https://github.com/can1357/oh-my-pi/issues/6495)) ## [17.1.1] - 2026-07-24 diff --git a/packages/ai/package.json b/packages/ai/package.json index 4e61b9455..fc0d6c6d4 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/pi-ai", - "version": "17.1.1", + "version": "17.1.2", "description": "Unified LLM API with automatic model discovery and provider configuration", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/catalog/package.json b/packages/catalog/package.json index 7a5c72e98..7a80df61b 100644 --- a/packages/catalog/package.json +++ b/packages/catalog/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/pi-catalog", - "version": "17.1.1", + "version": "17.1.2", "description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index d31096933..e150972d1 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +## [17.1.2] - 2026-07-24 + ### Added - Added in-process moreutils-style shell builtins to the bash tool's embedded shell: `ts` (timestamp lines; `-i`/`-s` elapsed modes, `-m` monotonic clock, `-r` relative rewriting of RFC3339/syslog timestamps, `%.S`/`%.s`/`%.T` subsecond extensions), `sponge` (soak stdin fully before atomically writing the target, so `foo file | ... | sponge file` works; `-a` appends), `ifne` (run a command only when stdin is non-empty; `-n` inverts and passes non-empty stdin through), `isutf8` (streaming UTF-8 validation with line/char/byte diagnostics; `-q`, `-l`, `-i`), `combine` (boolean `and`/`not`/`or`/`xor` on the lines of two files, `-` for stdin), and `errno` (errno name/number/description lookup with `-l` list and `-s` search; unix only). Like the uutils-backed builtins, they run in-process against the command's own stdio, resolve paths against the shell working directory, honor cancellation, and are disabled by `PI_DISABLE_UUTILS_BUILTINS`. @@ -24,16 +26,12 @@ - Fixed credential-free web search engines (SearXNG, DuckDuckGo, Google, Startpage, Ecosia, Mojeek, and the Public Web fan-out) returning zero results for queries with `site:` paths (e.g. `site:github.com/owner/repo`) or `inurl:` operators: scraper engines only match `site:` against a bare domain and DuckDuckGo ignores `inurl:` entirely, so such queries silently emptied the result set and fell through to the next provider in the chain. A shared `formatScraperQuery` formatter now structurally demotes path-carrying `site:` and all `inurl:` values to plain search terms (covering OR-grouped and quoted directives) while preserving bare-domain `site:` filters, negated operators, and each engine's supported syntax; the pipeline post-filter still enforces the demoted constraints on returned sources. - Fixed `ast_edit` previews reading like applied edits to the model: the `⟨proposed⟩` badge was TUI-only, so the model-visible result (hashline header + `-`/`+` rows, identical to applied edit output) carried no staged-proposal signal. The preview result now leads with a "Staged as a proposal — files NOT modified yet" notice naming `xd://resolve`/`xd://reject`, the injected resolve reminder names the source tool, and the `ast_edit` tool prompt documents the two-phase flow. - Fixed the `hub` launch `ps`/`list` response burying the active process behind every exited one and growing without bound in long-lived projects: the broker now lists non-terminal daemons first (oldest to newest) and caps exited/failed history at the 10 most recently exited, so the active launch is immediately visible and the response stays bounded. Broker recovery also preserves each already-terminal daemon's real exit time instead of overwriting it with the restart timestamp, so the history cap keeps the genuinely most-recently-exited processes after an idle-broker restart ([#6517](https://github.com/can1357/oh-my-pi/issues/6517)). +- Fixed a tool call rendering twice in the transcript. A mid-stream `rebuildChatFromMessages` (from `/shake`, auto-compaction, or a settings toggle) preserves the live `pendingTools` components across the clear+replay, but that preservation assumed every pending-tool component was still dangling. When a tool's result had already landed in the session entries while its component still lingered in `pendingTools`, the replay reconstructed the completed block *and* the preserved live component was re-appended, so the same block appeared twice; resolved components are now dropped from preservation and owned by the replay ([#6516](https://github.com/can1357/oh-my-pi/issues/6516)). +- Fixed `--model default` (and other bare role names) resolving to the bundled `cursor/default` catalog model instead of the configured `modelRoles.default` role. `resolveCliModel`'s exact-match phase ran its unauthenticated catalog fallback before role resolution, so a bundled id colliding with a reserved role name shadowed a configured, runnable role — failing with `No API key found for cursor` on machines without Cursor credentials. The catalog fallback is now deferred so an authenticated exact model still wins, a configured role beats an unauthenticated catalog-only id, and the catalog id is still recovered when no role matches ([#6508](https://github.com/can1357/oh-my-pi/issues/6508)). ### Removed - Removed the `model` parameter from `task` and `agent()`: explicit per-spawn model selectors and fallback chains are no longer supported; spawns always use the agent's configured model -### Fixed - -- Fixed a tool call rendering twice in the transcript. A mid-stream `rebuildChatFromMessages` (from `/shake`, auto-compaction, or a settings toggle) preserves the live `pendingTools` components across the clear+replay, but that preservation assumed every pending-tool component was still dangling. When a tool's result had already landed in the session entries while its component still lingered in `pendingTools`, the replay reconstructed the completed block *and* the preserved live component was re-appended, so the same block appeared twice; resolved components are now dropped from preservation and owned by the replay ([#6516](https://github.com/can1357/oh-my-pi/issues/6516)). -### Fixed - -- Fixed `--model default` (and other bare role names) resolving to the bundled `cursor/default` catalog model instead of the configured `modelRoles.default` role. `resolveCliModel`'s exact-match phase ran its unauthenticated catalog fallback before role resolution, so a bundled id colliding with a reserved role name shadowed a configured, runnable role — failing with `No API key found for cursor` on machines without Cursor credentials. The catalog fallback is now deferred so an authenticated exact model still wins, a configured role beats an unauthenticated catalog-only id, and the catalog id is still recovered when no role matches ([#6508](https://github.com/can1357/oh-my-pi/issues/6508)). ## [17.1.1] - 2026-07-24 diff --git a/packages/coding-agent/package.json b/packages/coding-agent/package.json index c012fcfbd..3d3c74c29 100644 --- a/packages/coding-agent/package.json +++ b/packages/coding-agent/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/pi-coding-agent", - "version": "17.1.1", + "version": "17.1.2", "description": "Coding agent CLI with read, bash, edit, write tools and session management", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/hashline/CHANGELOG.md b/packages/hashline/CHANGELOG.md index 0cea5bb02..df7d62a69 100644 --- a/packages/hashline/CHANGELOG.md +++ b/packages/hashline/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +## [17.1.2] - 2026-07-24 + ### Changed - Bare `- ` bullet body rows are now auto-accepted as literal content with a warning when the hunk is unambiguously a Markdown bullet list (every `-` row bullet-shaped and no plain `+new` diff counterpart); ambiguous `-` rows still fail with the teaching error. diff --git a/packages/hashline/package.json b/packages/hashline/package.json index 4333a3164..1a6d7ba73 100644 --- a/packages/hashline/package.json +++ b/packages/hashline/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/hashline", - "version": "17.1.1", + "version": "17.1.2", "description": "Hashline: a compact, line-anchored patch language and applier. Pluggable FS/IO so it works over disk, in-memory, or any custom backend.", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/mnemopi/package.json b/packages/mnemopi/package.json index 87cb64a82..aa43de5a0 100644 --- a/packages/mnemopi/package.json +++ b/packages/mnemopi/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/pi-mnemopi", - "version": "17.1.1", + "version": "17.1.2", "description": "Local SQLite memory engine for Oh My Pi agents", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/natives/CHANGELOG.md b/packages/natives/CHANGELOG.md index a06f9ac94..2695acca3 100644 --- a/packages/natives/CHANGELOG.md +++ b/packages/natives/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +## [17.1.2] - 2026-07-24 + ### Fixed - Fixed native addon builds with CMake 4.x (bundled opus policy floor) and stopped passing `-C target-cpu=native` on darwin arm64, which baked build-host CPU features into shipped addons and broke `ring` compilation. diff --git a/packages/natives/native/index.d.ts b/packages/natives/native/index.d.ts index bab481f9f..1e8bb32bc 100644 --- a/packages/natives/native/index.d.ts +++ b/packages/natives/native/index.d.ts @@ -246,7 +246,7 @@ export declare function __ompInstallTokioRuntime(): void * `packages/natives/native/index.js` (which derives the name from * `package.json#version`). */ -export declare function __piNativesV17_1_1(): void +export declare function __piNativesV17_1_2(): void /** * Apply ast-grep rewrite rules to matching files; honors `dryRun` and returns diff --git a/packages/natives/native/index.js b/packages/natives/native/index.js index 9572c6cf4..3c06615a1 100644 --- a/packages/natives/native/index.js +++ b/packages/natives/native/index.js @@ -28,7 +28,7 @@ export const Shell = nativeBindings.Shell; // functions export const __ompInstallTokioRuntime = nativeBindings.__ompInstallTokioRuntime; -export const __piNativesV17_1_1 = nativeBindings.__piNativesV17_1_1; +export const __piNativesV17_1_2 = nativeBindings.__piNativesV17_1_2; export const astEdit = nativeBindings.astEdit; export const astGrep = nativeBindings.astGrep; export const astMatch = nativeBindings.astMatch; diff --git a/packages/natives/package.json b/packages/natives/package.json index 3cb766058..8f0ad7903 100644 --- a/packages/natives/package.json +++ b/packages/natives/package.json @@ -1,6 +1,6 @@ { "name": "@oh-my-pi/pi-natives", - "version": "17.1.1", + "version": "17.1.2", "description": "Native Rust bindings for audio, WebRTC, grep, clipboard, image processing, syntax highlighting, PTY, and shell operations via N-API", "type": "module", "homepage": "https://omp.sh", diff --git a/packages/snapcompact/package.json b/packages/snapcompact/package.json index 250ab72a4..432eccc9c 100644 --- a/packages/snapcompact/package.json +++ b/packages/snapcompact/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/snapcompact", - "version": "17.1.1", + "version": "17.1.2", "description": "Bitmap-frame context compression for vision-capable LLMs", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/stats/CHANGELOG.md b/packages/stats/CHANGELOG.md index 05b5e5953..94034375f 100644 --- a/packages/stats/CHANGELOG.md +++ b/packages/stats/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +## [17.1.2] - 2026-07-24 + ### Added - Added a Providers dashboard section: per-provider totals, stacked token/cost burn over time, peak-burn-hours histogram, subscription-window insights (windows burned, estimated tokens per window, peak concurrent utilization, ideal account count, exhaustion events), and latest window utilization per account — window analytics read the auth broker's `/v1/usage/history` when a broker is configured (falling back to the local agent DB), since broker deployments record usage history on the broker host diff --git a/packages/stats/package.json b/packages/stats/package.json index c1f9d4fba..bd6d2efa9 100644 --- a/packages/stats/package.json +++ b/packages/stats/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/omp-stats", - "version": "17.1.1", + "version": "17.1.2", "description": "Local observability dashboard for pi AI usage statistics", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/swarm-extension/package.json b/packages/swarm-extension/package.json index 0924c70b5..a333edf55 100644 --- a/packages/swarm-extension/package.json +++ b/packages/swarm-extension/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/swarm-extension", - "version": "17.1.1", + "version": "17.1.2", "description": "Swarm orchestration extension for omp", "homepage": "https://omp.sh", "author": "Derek Rynd", diff --git a/packages/tui/CHANGELOG.md b/packages/tui/CHANGELOG.md index c1b5b1791..5be734696 100644 --- a/packages/tui/CHANGELOG.md +++ b/packages/tui/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +## [17.1.2] - 2026-07-24 + ### Fixed - Fixed the terminal flickering when leaving a fullscreen overlay (e.g. `/settings`, the models page) or resizing on terminals that re-report their size whenever the alternate screen buffer toggles: the alt-toggle size echo no longer arms a destructive full-screen (ED3) rebuild, and the in-place repaint path is now auto-detected for any such terminal instead of only Warp ([#6511](https://github.com/can1357/oh-my-pi/issues/6511)). diff --git a/packages/tui/package.json b/packages/tui/package.json index f57a3f3c0..a012a9280 100644 --- a/packages/tui/package.json +++ b/packages/tui/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/pi-tui", - "version": "17.1.1", + "version": "17.1.2", "description": "Terminal User Interface library with differential rendering for efficient text-based applications", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/utils/package.json b/packages/utils/package.json index 6737dfcca..d5c02e2e4 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/pi-utils", - "version": "17.1.1", + "version": "17.1.2", "description": "Shared utilities for pi packages", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/wire/package.json b/packages/wire/package.json index 481412c6f..b58c011f8 100644 --- a/packages/wire/package.json +++ b/packages/wire/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/pi-wire", - "version": "17.1.1", + "version": "17.1.2", "description": "Shared wire protocol types for Oh My Pi packages", "homepage": "https://omp.sh", "author": "Can Boluk",