Compare commits

...
5 Commits
Author SHA1 Message Date
Mohamed Boudra 6fc491e622 chore(release): cut 0.2.5 2026-07-30 13:22:40 +02:00
Mohamed Boudra 95257a6353 docs(changelog): simplify 0.2.5 entry 2026-07-30 13:17:51 +02:00
Mohamed Boudra 4d7d6a7d1b docs(changelog): 0.2.5 2026-07-30 12:33:47 +02:00
Cafe Babeandtang b345e53a9b Fix Linux desktop package startup (#2654)
Restore the Linux startup behavior that shipped in 0.2.3 by reverting the generalized sandbox detection from #2439.

Co-authored-by: tang <tang@tang-zai>
2026-07-30 12:32:44 +02:00
paseo-ai[bot] d1ce2b77f7 fix: update lockfile signatures and Nix hash [skip ci] 2026-07-29 23:58:09 +00:00
17 changed files with 55 additions and 178 deletions
+6
View File
@@ -1,5 +1,11 @@
# Changelog
## 0.2.5 - 2026-07-30
### Fixed
- Fixed the Linux Debian package ([#2654](https://github.com/getpaseo/paseo/pull/2654) by [@Neumannzc](https://github.com/Neumannzc))
## 0.2.4 - 2026-07-30
### Added
+1 -1
View File
@@ -1 +1 @@
sha256-n7k3zQ1NOm7dGmpqKE6RaEkl50/M2eFek6XIQJbYCEc=
sha256-KKDRzewqiwmsvF/7qFEJ3DK9DXtpAPUPxt0k9wkr1SY=
+21 -21
View File
@@ -1,12 +1,12 @@
{
"name": "paseo",
"version": "0.2.4",
"version": "0.2.5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "paseo",
"version": "0.2.4",
"version": "0.2.5",
"hasInstallScript": true,
"license": "AGPL-3.0-or-later",
"workspaces": [
@@ -35211,7 +35211,7 @@
},
"packages/app": {
"name": "@getpaseo/app",
"version": "0.2.4",
"version": "0.2.5",
"dependencies": {
"@codemirror/commands": "6.10.4",
"@codemirror/language": "6.12.4",
@@ -36236,12 +36236,12 @@
},
"packages/cli": {
"name": "@getpaseo/cli",
"version": "0.2.4",
"version": "0.2.5",
"dependencies": {
"@clack/prompts": "^1.0.0",
"@getpaseo/client": "0.2.4",
"@getpaseo/protocol": "0.2.4",
"@getpaseo/server": "0.2.4",
"@getpaseo/client": "0.2.5",
"@getpaseo/protocol": "0.2.5",
"@getpaseo/server": "0.2.5",
"chalk": "^5.3.0",
"commander": "^12.0.0",
"mime-types": "^2.1.35",
@@ -36488,10 +36488,10 @@
},
"packages/client": {
"name": "@getpaseo/client",
"version": "0.2.4",
"version": "0.2.5",
"dependencies": {
"@getpaseo/protocol": "0.2.4",
"@getpaseo/relay": "0.2.4",
"@getpaseo/protocol": "0.2.5",
"@getpaseo/relay": "0.2.5",
"zod": "^4.4.3"
},
"devDependencies": {
@@ -36502,7 +36502,7 @@
},
"packages/desktop": {
"name": "@getpaseo/desktop",
"version": "0.2.4",
"version": "0.2.5",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@getpaseo/cli": "*",
@@ -36745,7 +36745,7 @@
},
"packages/expo-two-way-audio": {
"name": "@getpaseo/expo-two-way-audio",
"version": "0.2.4",
"version": "0.2.5",
"license": "MIT",
"devDependencies": {
"@types/jest": "^29.5.14",
@@ -37641,7 +37641,7 @@
},
"packages/highlight": {
"name": "@getpaseo/highlight",
"version": "0.2.4",
"version": "0.2.5",
"dependencies": {
"@codemirror/language": "6.12.4",
"@codemirror/legacy-modes": "^6.5.3",
@@ -37873,7 +37873,7 @@
},
"packages/protocol": {
"name": "@getpaseo/protocol",
"version": "0.2.4",
"version": "0.2.5",
"dependencies": {
"zod": "^4.4.3"
},
@@ -37886,7 +37886,7 @@
},
"packages/relay": {
"name": "@getpaseo/relay",
"version": "0.2.4",
"version": "0.2.5",
"dependencies": {
"base64-js": "^1.5.1",
"tweetnacl": "^1.0.3",
@@ -38104,15 +38104,15 @@
},
"packages/server": {
"name": "@getpaseo/server",
"version": "0.2.4",
"version": "0.2.5",
"dependencies": {
"@agentclientprotocol/sdk": "^0.17.1",
"@anthropic-ai/claude-agent-sdk": "^0.3.220",
"@anthropic-ai/sdk": "^0.104.2",
"@getpaseo/client": "0.2.4",
"@getpaseo/highlight": "0.2.4",
"@getpaseo/protocol": "0.2.4",
"@getpaseo/relay": "0.2.4",
"@getpaseo/client": "0.2.5",
"@getpaseo/highlight": "0.2.5",
"@getpaseo/protocol": "0.2.5",
"@getpaseo/relay": "0.2.5",
"@isaacs/ttlcache": "^2.1.4",
"@modelcontextprotocol/sdk": "^1.20.1",
"@opencode-ai/sdk": "1.14.46",
@@ -38649,7 +38649,7 @@
},
"packages/website": {
"name": "@getpaseo/website",
"version": "0.2.4",
"version": "0.2.5",
"dependencies": {
"@cloudflare/vite-plugin": "^1.29.1",
"@cloudflare/workers-types": "^4.20260317.1",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "paseo",
"version": "0.2.4",
"version": "0.2.5",
"private": true,
"description": "Paseo: voice-controlled development environment for local AI coding agents",
"keywords": [
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/app",
"version": "0.2.4",
"version": "0.2.5",
"private": true,
"main": "index.ts",
"scripts": {
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/cli",
"version": "0.2.4",
"version": "0.2.5",
"description": "Paseo CLI - control your AI coding agents from the command line",
"bin": {
"paseo": "bin/paseo"
@@ -28,9 +28,9 @@
},
"dependencies": {
"@clack/prompts": "^1.0.0",
"@getpaseo/client": "0.2.4",
"@getpaseo/protocol": "0.2.4",
"@getpaseo/server": "0.2.4",
"@getpaseo/client": "0.2.5",
"@getpaseo/protocol": "0.2.5",
"@getpaseo/server": "0.2.5",
"chalk": "^5.3.0",
"commander": "^12.0.0",
"mime-types": "^2.1.35",
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/client",
"version": "0.2.4",
"version": "0.2.5",
"description": "Paseo client SDK package",
"files": [
"dist",
@@ -35,8 +35,8 @@
"test": "vitest run"
},
"dependencies": {
"@getpaseo/protocol": "0.2.4",
"@getpaseo/relay": "0.2.4",
"@getpaseo/protocol": "0.2.5",
"@getpaseo/relay": "0.2.5",
"zod": "^4.4.3"
},
"devDependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/desktop",
"version": "0.2.4",
"version": "0.2.5",
"private": true,
"description": "Paseo desktop app (Electron wrapper)",
"homepage": "https://paseo.sh",
+7 -9
View File
@@ -8,7 +8,7 @@ import { inheritLoginShellEnv } from "./login-shell-env.js";
import path from "node:path";
import { pathToFileURL } from "node:url";
import { existsSync, statSync } from "node:fs";
import { existsSync } from "node:fs";
import { execFileSync } from "node:child_process";
import {
app,
@@ -40,7 +40,6 @@ import {
buildStandardContextMenuItems,
} from "./window/window-manager.js";
import { setupDarwinCompositorWatchdog } from "./window/compositor-watchdog/index.js";
import { configureLinuxSandbox } from "./system/linux-sandbox.js";
import { registerDialogHandlers } from "./features/dialogs.js";
import {
registerNotificationHandlers,
@@ -310,13 +309,12 @@ if (forcedUserDataDir) {
}
}
configureLinuxSandbox({
platform: process.platform,
resourcesPath: process.resourcesPath,
statSandbox: (sandboxPath) => statSync(sandboxPath),
disableSandbox: () => app.commandLine.appendSwitch("no-sandbox"),
reportInspectionError: (error) => log.error("[linux-sandbox] failed to inspect helper", error),
});
// AppImage runtimes mount the app from /tmp under the user's UID, so the SUID
// chrome-sandbox helper we ship in .deb/.rpm cannot work there. Disable the
// sandbox only in that case; .deb/.rpm keep the sandbox on, matching VS Code.
if (process.platform === "linux" && process.env.APPIMAGE) {
app.commandLine.appendSwitch("no-sandbox");
}
// Allow users to pass Chromium flags via PASEO_ELECTRON_FLAGS for debugging
// rendering issues (e.g. "--disable-gpu --ozone-platform=x11").
@@ -1,82 +0,0 @@
import { describe, expect, it } from "vitest";
import { configureLinuxSandbox } from "./linux-sandbox";
interface SandboxMetadata {
mode: number;
uid: number;
}
function configureWithSandbox(
sandbox: SandboxMetadata | Error,
platform: NodeJS.Platform = "linux",
) {
const disabledSwitches: string[] = [];
const inspectionErrors: unknown[] = [];
configureLinuxSandbox({
platform,
resourcesPath: "/opt/Paseo/resources",
statSandbox: () => {
if (sandbox instanceof Error) {
throw sandbox;
}
return sandbox;
},
disableSandbox: () => disabledSwitches.push("no-sandbox"),
reportInspectionError: (error) => inspectionErrors.push(error),
});
return { disabledSwitches, inspectionErrors };
}
function createFileSystemError(code: string): NodeJS.ErrnoException {
const error: NodeJS.ErrnoException = new Error(code);
error.code = code;
return error;
}
describe("configureLinuxSandbox", () => {
it("disables the sandbox when an AppImage mount strips SUID", () => {
expect(configureWithSandbox({ uid: 1000, mode: 0o755 })).toEqual({
disabledSwitches: ["no-sandbox"],
inspectionErrors: [],
});
});
it("keeps the sandbox for a root-owned 4755 helper", () => {
expect(configureWithSandbox({ uid: 0, mode: 0o4755 })).toEqual({
disabledSwitches: [],
inspectionErrors: [],
});
});
it("disables the sandbox when a SUID helper is not root-owned", () => {
expect(configureWithSandbox({ uid: 1000, mode: 0o4755 })).toEqual({
disabledSwitches: ["no-sandbox"],
inspectionErrors: [],
});
});
it("disables the sandbox when the helper is missing", () => {
expect(configureWithSandbox(createFileSystemError("ENOENT"))).toEqual({
disabledSwitches: ["no-sandbox"],
inspectionErrors: [],
});
});
it("keeps the sandbox and reports unexpected inspection failures", () => {
const permissionError = createFileSystemError("EACCES");
expect(configureWithSandbox(permissionError)).toEqual({
disabledSwitches: [],
inspectionErrors: [permissionError],
});
});
it("does not inspect or configure the sandbox outside Linux", () => {
expect(configureWithSandbox(createFileSystemError("EACCES"), "darwin")).toEqual({
disabledSwitches: [],
inspectionErrors: [],
});
});
});
@@ -1,45 +0,0 @@
import path from "node:path";
const REQUIRED_SANDBOX_MODE = 0o4755;
const PERMISSION_BITS = 0o7777;
interface SandboxMetadata {
mode: number;
uid: number;
}
interface LinuxSandboxConfiguration {
platform: NodeJS.Platform;
resourcesPath: string;
statSandbox: (sandboxPath: string) => SandboxMetadata;
disableSandbox: () => void;
reportInspectionError: (error: unknown) => void;
}
function isMissingSandbox(error: unknown): boolean {
return error instanceof Error && "code" in error && error.code === "ENOENT";
}
export function configureLinuxSandbox(input: LinuxSandboxConfiguration): void {
if (input.platform !== "linux") {
return;
}
try {
const sandboxPath = path.join(input.resourcesPath, "..", "chrome-sandbox");
const sandbox = input.statSandbox(sandboxPath);
const hasUsableSandbox =
sandbox.uid === 0 && (sandbox.mode & PERMISSION_BITS) === REQUIRED_SANDBOX_MODE;
if (!hasUsableSandbox) {
input.disableSandbox();
}
} catch (error) {
if (isMissingSandbox(error)) {
input.disableSandbox();
return;
}
input.reportInspectionError(error);
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/expo-two-way-audio",
"version": "0.2.4",
"version": "0.2.5",
"description": "Native module for two way audio streaming",
"keywords": [
"ExpoTwoWayAudio",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/highlight",
"version": "0.2.4",
"version": "0.2.5",
"files": [
"dist",
"!dist/**/*.map"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/protocol",
"version": "0.2.4",
"version": "0.2.5",
"description": "Paseo shared protocol schemas and wire types",
"files": [
"dist",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/relay",
"version": "0.2.4",
"version": "0.2.5",
"description": "Paseo relay for bridging daemon and client connections",
"files": [
"dist",
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/server",
"version": "0.2.4",
"version": "0.2.5",
"description": "Paseo backend server",
"files": [
"dist/server",
@@ -67,10 +67,10 @@
"@agentclientprotocol/sdk": "^0.17.1",
"@anthropic-ai/claude-agent-sdk": "^0.3.220",
"@anthropic-ai/sdk": "^0.104.2",
"@getpaseo/client": "0.2.4",
"@getpaseo/highlight": "0.2.4",
"@getpaseo/protocol": "0.2.4",
"@getpaseo/relay": "0.2.4",
"@getpaseo/client": "0.2.5",
"@getpaseo/highlight": "0.2.5",
"@getpaseo/protocol": "0.2.5",
"@getpaseo/relay": "0.2.5",
"@isaacs/ttlcache": "^2.1.4",
"@modelcontextprotocol/sdk": "^1.20.1",
"@opencode-ai/sdk": "1.14.46",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/website",
"version": "0.2.4",
"version": "0.2.5",
"private": true,
"type": "module",
"scripts": {