chore: bump version to 17.1.2

- fixed rustfmt drift and clippy errors in pi-shell moreutils builtins (combine, errno, ifne, isutf8, sponge, ts) that blocked the release check gate
This commit is contained in:
can1357
2026-07-24 16:53:52 +02:00
parent c55b28a26d
commit 7ebf141743
35 changed files with 245 additions and 176 deletions
Generated
+6 -5
View File
@@ -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",
+1 -1
View File
@@ -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"]
+63 -39
View File
@@ -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=="],
+1 -1
View File
@@ -260,7 +260,7 @@ fn create_windows_napi_tokio_runtime() -> Option<tokio::runtime::Runtime> {
/// 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
+1
View File
@@ -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
+13 -7
View File
@@ -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<String> for Error {
fn from(msg: String) -> Self {
Error::Msg(msg)
Self::Msg(msg)
}
}
@@ -56,9 +56,15 @@ pub fn run(argv: Vec<OsString>) -> i32 {
},
};
let file1 = matches.get_one::<OsString>(ARG_FILE1).expect("required").clone();
let file1 = matches
.get_one::<OsString>(ARG_FILE1)
.expect("required")
.clone();
let op = matches.get_one::<String>(ARG_OP).expect("required");
let file2 = matches.get_one::<OsString>(ARG_FILE2).expect("required").clone();
let file2 = matches
.get_one::<OsString>(ARG_FILE2)
.expect("required")
.clone();
match execute(&file1, op, &file2) {
Ok(()) => 0,
@@ -158,8 +164,7 @@ fn open_input(name: &OsStr) -> Result<Box<dyn BufRead>, 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 {
+17 -20
View File
@@ -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<OsString>) -> 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())
+15 -17
View File
@@ -19,7 +19,11 @@ const CHUNK: usize = 64 * 1024;
pub fn run(argv: Vec<OsString>) -> 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<u8>, 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<u8>, 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())
+10 -14
View File
@@ -57,8 +57,7 @@ pub fn run(argv: Vec<OsString>) -> i32 {
let invert = matches.get_flag(OPT_INVERT);
let files: Vec<OsString> = matches
.get_many::<OsString>(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<OsString>) -> 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<Verdict> {
/// 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);
+20 -5
View File
@@ -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<Vec<u8>, 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)
+46 -25
View File
@@ -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<i32, String> {
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<i32, String> {
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<i32, String> {
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::<Timestamp>().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::<Timestamp>().unwrap());
+8 -7
View File
@@ -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, &params).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, &params)
.await
.expect("moreutils script");
assert_eq!(exit_code(&result), 0);
// `ts -s` stamps the first line with zero elapsed time: `HH:MM:SS x`.
+12 -12
View File
@@ -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",
+2
View File
@@ -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)
+1 -1
View File
@@ -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",
+3 -2
View File
@@ -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
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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",
+4 -6
View File
@@ -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
+1 -1
View File
@@ -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",
+2
View File
@@ -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.
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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",
+2
View File
@@ -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.
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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",
+2
View File
@@ -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
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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",
+2
View File
@@ -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)).
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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",