chore: bump version to 10.5.0
This commit is contained in:
Generated
+1
-1
@@ -1989,7 +1989,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pi-natives"
|
||||
version = "10.3.2"
|
||||
version = "10.5.0"
|
||||
dependencies = [
|
||||
"arboard",
|
||||
"brush-builtins",
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ exclude = ["crates/brush-core-vendored", "crates/brush-builtins-vendored"]
|
||||
resolver = "3"
|
||||
|
||||
[workspace.package]
|
||||
version = "10.3.2"
|
||||
version = "10.5.0"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = ["Can Boluk"]
|
||||
|
||||
@@ -56,8 +56,8 @@ impl crate::sys::fs::PathExt for std::path::Path {
|
||||
fn get_device_and_inode(&self) -> Result<(u64, u64), crate::error::Error> {
|
||||
let metadata = self.metadata()?;
|
||||
let volume_serial_number =
|
||||
std::os::windows::fs::MetadataExt::volume_serial_number(&metadata) as u64;
|
||||
let file_index = std::os::windows::fs::MetadataExt::file_index(&metadata);
|
||||
u64::from(std::os::windows::fs::MetadataExt::volume_serial_number(&metadata).unwrap_or(0));
|
||||
let file_index = std::os::windows::fs::MetadataExt::file_index(&metadata).unwrap_or(0);
|
||||
Ok((volume_serial_number, file_index))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [10.5.0] - 2026-02-04
|
||||
### Added
|
||||
|
||||
- Added `concurrency` option to `AgentTool` to control tool scheduling: "shared" (default, runs in parallel) or "exclusive" (runs alone)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oh-my-pi/pi-agent-core",
|
||||
"version": "10.3.2",
|
||||
"version": "10.5.0",
|
||||
"description": "General-purpose agent with transport abstraction, state management, and attachment support",
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [10.5.0] - 2026-02-04
|
||||
### Changed
|
||||
|
||||
- Updated @anthropic-ai/sdk to ^0.72.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oh-my-pi/pi-ai",
|
||||
"version": "10.3.2",
|
||||
"version": "10.5.0",
|
||||
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [10.5.0] - 2026-02-04
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- Changed `ask` tool to require `questions` array parameter; single-question mode with `question`, `options`, `multi`, and `recommended` parameters is no longer supported
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oh-my-pi/pi-coding-agent",
|
||||
"version": "10.3.2",
|
||||
"version": "10.5.0",
|
||||
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
||||
"type": "module",
|
||||
"ompConfig": {
|
||||
|
||||
-6
@@ -20,9 +20,3 @@ declare module "*.py" {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
|
||||
// JavaScript files imported as text
|
||||
declare module "*.js?raw" {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
|
||||
@@ -13,20 +13,20 @@ import type { ToolSession } from "../sdk";
|
||||
import { htmlToBasicMarkdown } from "../web/scrapers/types";
|
||||
import type { OutputMeta } from "./output-meta";
|
||||
import { resolveToCwd } from "./path-utils";
|
||||
import stealthTamperingScript from "./puppeteer/00_stealth_tampering.js?raw" with { type: "text" };
|
||||
import stealthActivityScript from "./puppeteer/01_stealth_activity.js?raw" with { type: "text" };
|
||||
import stealthHairlineScript from "./puppeteer/02_stealth_hairline.js?raw" with { type: "text" };
|
||||
import stealthBotdScript from "./puppeteer/03_stealth_botd.js?raw" with { type: "text" };
|
||||
import stealthIframeScript from "./puppeteer/04_stealth_iframe.js?raw" with { type: "text" };
|
||||
import stealthWebglScript from "./puppeteer/05_stealth_webgl.js?raw" with { type: "text" };
|
||||
import stealthScreenScript from "./puppeteer/06_stealth_screen.js?raw" with { type: "text" };
|
||||
import stealthFontsScript from "./puppeteer/07_stealth_fonts.js?raw" with { type: "text" };
|
||||
import stealthAudioScript from "./puppeteer/08_stealth_audio.js?raw" with { type: "text" };
|
||||
import stealthLocaleScript from "./puppeteer/09_stealth_locale.js?raw" with { type: "text" };
|
||||
import stealthPluginsScript from "./puppeteer/10_stealth_plugins.js?raw" with { type: "text" };
|
||||
import stealthHardwareScript from "./puppeteer/11_stealth_hardware.js?raw" with { type: "text" };
|
||||
import stealthCodecsScript from "./puppeteer/12_stealth_codecs.js?raw" with { type: "text" };
|
||||
import stealthWorkerScript from "./puppeteer/13_stealth_worker.js?raw" with { type: "text" };
|
||||
import stealthTamperingScript from "./puppeteer/00_stealth_tampering.txt" with { type: "text" };
|
||||
import stealthActivityScript from "./puppeteer/01_stealth_activity.txt" with { type: "text" };
|
||||
import stealthHairlineScript from "./puppeteer/02_stealth_hairline.txt" with { type: "text" };
|
||||
import stealthBotdScript from "./puppeteer/03_stealth_botd.txt" with { type: "text" };
|
||||
import stealthIframeScript from "./puppeteer/04_stealth_iframe.txt" with { type: "text" };
|
||||
import stealthWebglScript from "./puppeteer/05_stealth_webgl.txt" with { type: "text" };
|
||||
import stealthScreenScript from "./puppeteer/06_stealth_screen.txt" with { type: "text" };
|
||||
import stealthFontsScript from "./puppeteer/07_stealth_fonts.txt" with { type: "text" };
|
||||
import stealthAudioScript from "./puppeteer/08_stealth_audio.txt" with { type: "text" };
|
||||
import stealthLocaleScript from "./puppeteer/09_stealth_locale.txt" with { type: "text" };
|
||||
import stealthPluginsScript from "./puppeteer/10_stealth_plugins.txt" with { type: "text" };
|
||||
import stealthHardwareScript from "./puppeteer/11_stealth_hardware.txt" with { type: "text" };
|
||||
import stealthCodecsScript from "./puppeteer/12_stealth_codecs.txt" with { type: "text" };
|
||||
import stealthWorkerScript from "./puppeteer/13_stealth_worker.txt" with { type: "text" };
|
||||
import { ToolAbortError, ToolError, throwIfAborted } from "./tool-errors";
|
||||
import { toolResult } from "./tool-result";
|
||||
|
||||
|
||||
@@ -1,112 +1,56 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "bun:test";
|
||||
import { _resetSettingsForTest, Settings } from "@oh-my-pi/pi-coding-agent/config/settings";
|
||||
import { acquireSharedGateway } from "@oh-my-pi/pi-coding-agent/ipy/gateway-coordinator";
|
||||
import * as shellSnapshot from "@oh-my-pi/pi-coding-agent/utils/shell-snapshot";
|
||||
import { TempDir } from "@oh-my-pi/pi-utils";
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { filterEnv } from "@oh-my-pi/pi-coding-agent/ipy/runtime";
|
||||
|
||||
class FakeWebSocket {
|
||||
static OPEN = 1;
|
||||
static CLOSED = 3;
|
||||
readyState = FakeWebSocket.OPEN;
|
||||
binaryType = "arraybuffer";
|
||||
url: string;
|
||||
onopen?: () => void;
|
||||
onerror?: (event: unknown) => void;
|
||||
onclose?: () => void;
|
||||
onmessage?: (event: { data: ArrayBuffer }) => void;
|
||||
describe("Python gateway environment filtering", () => {
|
||||
it("filters sensitive and unknown variables from shell env", () => {
|
||||
const env: Record<string, string | undefined> = {
|
||||
PATH: "/bin",
|
||||
HOME: "/home/test",
|
||||
OPENAI_API_KEY: "secret",
|
||||
ANTHROPIC_API_KEY: "also-secret",
|
||||
UNSAFE_TOKEN: "nope",
|
||||
OMP_CUSTOM: "1",
|
||||
LC_ALL: "en_US.UTF-8",
|
||||
};
|
||||
|
||||
constructor(url: string) {
|
||||
this.url = url;
|
||||
queueMicrotask(() => {
|
||||
this.onopen?.();
|
||||
});
|
||||
}
|
||||
const filtered = filterEnv(env);
|
||||
|
||||
send(_data: ArrayBuffer) {}
|
||||
|
||||
close() {
|
||||
this.readyState = FakeWebSocket.CLOSED;
|
||||
this.onclose?.();
|
||||
}
|
||||
}
|
||||
|
||||
describe("Shared Python gateway environment", () => {
|
||||
const originalEnv = { ...process.env };
|
||||
const originalFetch = globalThis.fetch;
|
||||
const originalWebSocket = globalThis.WebSocket;
|
||||
|
||||
beforeEach(() => {
|
||||
_resetSettingsForTest();
|
||||
process.env.BUN_ENV = "test";
|
||||
delete process.env.OMP_PYTHON_GATEWAY_URL;
|
||||
delete process.env.OMP_PYTHON_GATEWAY_TOKEN;
|
||||
globalThis.WebSocket = FakeWebSocket as unknown as typeof WebSocket;
|
||||
expect(filtered.PATH).toBe("/bin");
|
||||
expect(filtered.HOME).toBe("/home/test");
|
||||
expect(filtered.OMP_CUSTOM).toBe("1");
|
||||
expect(filtered.LC_ALL).toBe("en_US.UTF-8");
|
||||
expect(filtered.OPENAI_API_KEY).toBeUndefined();
|
||||
expect(filtered.ANTHROPIC_API_KEY).toBeUndefined();
|
||||
expect(filtered.UNSAFE_TOKEN).toBeUndefined();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
for (const key of Object.keys(process.env)) {
|
||||
if (!(key in originalEnv)) {
|
||||
delete process.env[key];
|
||||
}
|
||||
}
|
||||
for (const [key, value] of Object.entries(originalEnv)) {
|
||||
process.env[key] = value;
|
||||
}
|
||||
globalThis.fetch = originalFetch;
|
||||
globalThis.WebSocket = originalWebSocket;
|
||||
vi.restoreAllMocks();
|
||||
it("preserves XDG and LC prefixed variables", () => {
|
||||
const env: Record<string, string | undefined> = {
|
||||
XDG_CONFIG_HOME: "/home/test/.config",
|
||||
XDG_RUNTIME_DIR: "/run/user/1000",
|
||||
LC_CTYPE: "UTF-8",
|
||||
LC_MESSAGES: "en_US.UTF-8",
|
||||
};
|
||||
|
||||
const filtered = filterEnv(env);
|
||||
|
||||
expect(filtered.XDG_CONFIG_HOME).toBe("/home/test/.config");
|
||||
expect(filtered.XDG_RUNTIME_DIR).toBe("/run/user/1000");
|
||||
expect(filtered.LC_CTYPE).toBe("UTF-8");
|
||||
expect(filtered.LC_MESSAGES).toBe("en_US.UTF-8");
|
||||
});
|
||||
|
||||
it("filters environment variables before spawning shared gateway", async () => {
|
||||
const fetchSpy = vi.fn(async (input: string | URL) => {
|
||||
const url = typeof input === "string" ? input : input.toString();
|
||||
if (url.endsWith("/api/kernelspecs")) {
|
||||
return new Response(JSON.stringify({}), { status: 200 });
|
||||
}
|
||||
return new Response("", { status: 200 });
|
||||
});
|
||||
globalThis.fetch = fetchSpy as unknown as typeof fetch;
|
||||
it("passes filtered env through to resolved runtime", () => {
|
||||
const env: Record<string, string | undefined> = {
|
||||
PATH: "/usr/bin",
|
||||
HOME: "/home/test",
|
||||
OPENAI_API_KEY: "secret",
|
||||
OMP_DEBUG: "1",
|
||||
};
|
||||
|
||||
vi.spyOn(Settings.prototype, "getShellConfig").mockReturnValue({
|
||||
shell: "/bin/bash",
|
||||
args: ["-lc"],
|
||||
env: {
|
||||
PATH: "/bin",
|
||||
HOME: "/home/test",
|
||||
OPENAI_API_KEY: "secret",
|
||||
UNSAFE_TOKEN: "nope",
|
||||
OMP_CUSTOM: "1",
|
||||
LC_ALL: "en_US.UTF-8",
|
||||
},
|
||||
prefix: undefined,
|
||||
});
|
||||
const snapshotSpy = vi.spyOn(shellSnapshot, "getOrCreateSnapshot").mockResolvedValue(null);
|
||||
const whichSpy = vi.spyOn(Bun, "which").mockReturnValue("/usr/bin/python");
|
||||
|
||||
let spawnEnv: Record<string, string | undefined> | undefined;
|
||||
let spawnArgs: string[] | undefined;
|
||||
const spawnSpy = vi.spyOn(Bun, "spawn").mockImplementation(((...args: unknown[]) => {
|
||||
const [cmd, options] = args as [string[] | { cmd: string[] }, { env?: Record<string, string | undefined> }?];
|
||||
spawnArgs = Array.isArray(cmd) ? cmd : cmd.cmd;
|
||||
spawnEnv = options?.env;
|
||||
return { pid: 1234, exited: Promise.resolve(0) } as unknown as Bun.Subprocess;
|
||||
}) as unknown as typeof Bun.spawn);
|
||||
|
||||
using tempDir = TempDir.createSync("@python-kernel-env-");
|
||||
process.env.OMP_CODING_AGENT_DIR = tempDir.path();
|
||||
await acquireSharedGateway(tempDir.path());
|
||||
|
||||
expect(spawnArgs).toContain("kernel_gateway");
|
||||
expect(spawnEnv?.PATH).toBe("/bin");
|
||||
expect(spawnEnv?.HOME).toBe("/home/test");
|
||||
expect(spawnEnv?.OMP_CUSTOM).toBe("1");
|
||||
expect(spawnEnv?.LC_ALL).toBe("en_US.UTF-8");
|
||||
expect(spawnEnv?.OPENAI_API_KEY).toBeUndefined();
|
||||
expect(spawnEnv?.UNSAFE_TOKEN).toBeUndefined();
|
||||
|
||||
vi.restoreAllMocks();
|
||||
snapshotSpy.mockRestore();
|
||||
whichSpy.mockRestore();
|
||||
spawnSpy.mockRestore();
|
||||
const filtered = filterEnv(env);
|
||||
expect(filtered.OPENAI_API_KEY).toBeUndefined();
|
||||
expect(filtered.PATH).toBe("/usr/bin");
|
||||
expect(filtered.OMP_DEBUG).toBe("1");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oh-my-pi/pi-natives",
|
||||
"version": "10.3.2",
|
||||
"version": "10.5.0",
|
||||
"description": "Native Rust functionality via N-API",
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oh-my-pi/omp-stats",
|
||||
"version": "10.3.2",
|
||||
"version": "10.5.0",
|
||||
"description": "Local observability dashboard for pi AI usage statistics",
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [10.5.0] - 2026-02-04
|
||||
|
||||
### Fixed
|
||||
|
||||
- Treated inline image lines with cursor-move prefixes as image sequences to prevent width overflow crashes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oh-my-pi/pi-tui",
|
||||
"version": "10.3.2",
|
||||
"version": "10.5.0",
|
||||
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@oh-my-pi/pi-utils",
|
||||
"version": "10.3.2",
|
||||
"version": "10.5.0",
|
||||
"description": "Shared utilities for pi packages",
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
|
||||
Reference in New Issue
Block a user