Compare commits

...
3 Commits
Author SHA1 Message Date
Mohamed Boudra c4dc36272c chore(release): cut 0.15.1 2026-11-05 03:27:21 +01:00
Mohamed Boudra 896f8efb64 docs(changelog): prepare 0.15.1 2026-11-05 03:01:38 +01:00
Mohamed Boudra cc8cd7e3cc fix(terminal): start the daemon when the terminal worker cannot start (#8810)
On 0.15.0 the daemon launches the detached terminal worker while it is
being created, and the worker refuses to start unless it can read its own
birth time and command line (Windows PowerShell 5.1 `Get-CimInstance`,
`ps` elsewhere). Any failure of that query used to escape
startWorkerTerminalManager and take the whole daemon down with
"Daemon failed to start (exit 1)", as two Windows machines hit after the
update: one whose PowerShell 5.1 cannot load CimCmdlets, one where
powershell.exe cannot be spawned at all. 0.14.0 never ran that query at
startup.

The launch error is now logged and the daemon starts without a current
worker. The pool already launches one lazily on the first terminal
creation, so that request reports the same error while the machine still
cannot run the query, and terminals come back once it can. The identity
requirement itself is unchanged: a worker without a verified identity is
never written or adopted.

(cherry picked from commit 8dfdb479ab)
2026-11-05 02:59:14 +01:00
22 changed files with 126 additions and 58 deletions
+6
View File
@@ -1,5 +1,11 @@
# Changelog
## 0.15.1 - 2026-11-05
### Fixed
- Fixed the daemon failing to start when the terminal worker cannot read its own process identity, which left Paseo Desktop without a daemon on Windows machines where Windows PowerShell 5.1 cannot run `Get-CimInstance` ([#8810](https://github.com/getpaseo/paseo/pull/8810))
## 0.15.0 - 2026-11-03
Daemon restarts now keep terminal programs running. Interrupted agents can resume in their existing conversations when you turn on agent recovery.
+6
View File
@@ -1,5 +1,11 @@
# Changelog
## 0.15.1 - 2026-11-05
### 修复
- 修复终端工作进程无法读取自身进程标识时 daemon 无法启动的问题;此前在 Windows PowerShell 5.1 无法运行 `Get-CimInstance` 的 Windows 机器上,Paseo 桌面版因此没有可用的 daemon ([#8810](https://github.com/getpaseo/paseo/pull/8810))
## 0.15.0 - 2026-11-03
daemon 重启后,终端中的程序继续运行。开启 Agent 恢复后,被中断的 Agent 会在原有会话中恢复工作。
@@ -0,0 +1,4 @@
Fixed
- Fixed the daemon failing to start when the terminal worker cannot read its own process identity, which left Paseo Desktop without a daemon on Windows machines where Windows PowerShell 5.1 cannot run Get-CimInstance
Full notes: https://paseo.sh/changelog
@@ -0,0 +1,4 @@
Fixed
- Fixed the daemon failing to start when the terminal worker cannot read its own process identity, which left Paseo Desktop without a daemon on Windows machines where Windows PowerShell 5.1 cannot run Get-CimInstance
Full notes: https://paseo.sh/changelog
@@ -0,0 +1,4 @@
Fixed
- Fixed the daemon failing to start when the terminal worker cannot read its own process identity, which left Paseo Desktop without a daemon on Windows machines where Windows PowerShell 5.1 cannot run Get-CimInstance
Full notes: https://paseo.sh/changelog
@@ -0,0 +1,4 @@
Fixed
- Fixed the daemon failing to start when the terminal worker cannot read its own process identity, which left Paseo Desktop without a daemon on Windows machines where Windows PowerShell 5.1 cannot run Get-CimInstance
Full notes: https://paseo.sh/changelog
+28 -28
View File
@@ -1,12 +1,12 @@
{
"name": "paseo",
"version": "0.15.0",
"version": "0.15.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "paseo",
"version": "0.15.0",
"version": "0.15.1",
"hasInstallScript": true,
"license": "Apache-2.0",
"workspaces": [
@@ -37632,7 +37632,7 @@
},
"packages/app": {
"name": "@getpaseo/app",
"version": "0.15.0",
"version": "0.15.1",
"dependencies": {
"@codemirror/commands": "6.10.4",
"@codemirror/language": "6.12.4",
@@ -39800,12 +39800,12 @@
},
"packages/cli": {
"name": "@getpaseo/cli",
"version": "0.15.0",
"version": "0.15.1",
"dependencies": {
"@clack/prompts": "^1.0.0",
"@getpaseo/client": "0.15.0",
"@getpaseo/protocol": "0.15.0",
"@getpaseo/server": "0.15.0",
"@getpaseo/client": "0.15.1",
"@getpaseo/protocol": "0.15.1",
"@getpaseo/server": "0.15.1",
"chalk": "^5.3.0",
"commander": "^12.0.0",
"mime-types": "^2.1.35",
@@ -40052,10 +40052,10 @@
},
"packages/client": {
"name": "@getpaseo/client",
"version": "0.15.0",
"version": "0.15.1",
"dependencies": {
"@getpaseo/protocol": "0.15.0",
"@getpaseo/relay": "0.15.0",
"@getpaseo/protocol": "0.15.1",
"@getpaseo/relay": "0.15.1",
"ws": "^8.20.0",
"zod": "^4.4.3"
},
@@ -40067,7 +40067,7 @@
},
"packages/desktop": {
"name": "@getpaseo/desktop",
"version": "0.15.0",
"version": "0.15.1",
"license": "Apache-2.0",
"dependencies": {
"@getpaseo/cli": "*",
@@ -40311,7 +40311,7 @@
},
"packages/expo-two-way-audio": {
"name": "@getpaseo/expo-two-way-audio",
"version": "0.15.0",
"version": "0.15.1",
"license": "MIT",
"devDependencies": {
"@types/jest": "^29.5.14",
@@ -40357,7 +40357,7 @@
},
"packages/highlight": {
"name": "@getpaseo/highlight",
"version": "0.15.0",
"version": "0.15.1",
"dependencies": {
"@codemirror/language": "6.12.4",
"@codemirror/legacy-modes": "^6.5.3",
@@ -40386,15 +40386,15 @@
},
"packages/plugin": {
"name": "@getpaseo/plugin",
"version": "0.15.0",
"version": "0.15.1",
"dependencies": {
"@agentclientprotocol/sdk": "^1.4.0",
"i18next": "^26.3.0",
"use-sync-external-store": "^1.6.0"
},
"devDependencies": {
"@getpaseo/client": "0.15.0",
"@getpaseo/protocol": "0.15.0",
"@getpaseo/client": "0.15.1",
"@getpaseo/protocol": "0.15.1",
"@types/node": "^20.9.0",
"@types/react": "~19.2.0",
"react": "19.2.3",
@@ -40404,8 +40404,8 @@
"zod": "^4.4.3"
},
"peerDependencies": {
"@getpaseo/client": "0.15.0",
"@getpaseo/protocol": "0.15.0",
"@getpaseo/client": "0.15.1",
"@getpaseo/protocol": "0.15.1",
"react": ">=19.1.0 <20",
"react-native": ">=0.81.5",
"zod": "^4.4.3"
@@ -40427,7 +40427,7 @@
},
"packages/protocol": {
"name": "@getpaseo/protocol",
"version": "0.15.0",
"version": "0.15.1",
"dependencies": {
"semver": "^7.8.5",
"zod": "^4.4.3"
@@ -40454,7 +40454,7 @@
},
"packages/relay": {
"name": "@getpaseo/relay",
"version": "0.15.0",
"version": "0.15.1",
"dependencies": {
"@noble/ciphers": "^2.4.0",
"@noble/curves": "^2.4.0",
@@ -40675,16 +40675,16 @@
},
"packages/server": {
"name": "@getpaseo/server",
"version": "0.15.0",
"version": "0.15.1",
"dependencies": {
"@agentclientprotocol/sdk": "^0.17.1",
"@anthropic-ai/claude-agent-sdk": "0.3.246",
"@anthropic-ai/sdk": "^0.104.2",
"@getpaseo/client": "0.15.0",
"@getpaseo/highlight": "0.15.0",
"@getpaseo/plugin": "0.15.0",
"@getpaseo/protocol": "0.15.0",
"@getpaseo/relay": "0.15.0",
"@getpaseo/client": "0.15.1",
"@getpaseo/highlight": "0.15.1",
"@getpaseo/plugin": "0.15.1",
"@getpaseo/protocol": "0.15.1",
"@getpaseo/relay": "0.15.1",
"@isaacs/ttlcache": "^2.1.4",
"@modelcontextprotocol/sdk": "1.29.0",
"@opencode-ai/sdk": "1.14.46",
@@ -41631,7 +41631,7 @@
},
"packages/website": {
"name": "@getpaseo/website",
"version": "0.15.0",
"version": "0.15.1",
"dependencies": {
"@cloudflare/vite-plugin": "^1.29.1",
"@cloudflare/workers-types": "^4.20260317.1",
@@ -43241,7 +43241,7 @@
},
"plugins": {
"name": "@getpaseo/builtin-plugins",
"version": "0.15.0",
"version": "0.15.1",
"dependencies": {
"@getpaseo/plugin": "*",
"zod": "^4.4.3"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "paseo",
"version": "0.15.0",
"version": "0.15.1",
"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.15.0",
"version": "0.15.1",
"private": true,
"main": "index.ts",
"scripts": {
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/cli",
"version": "0.15.0",
"version": "0.15.1",
"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.15.0",
"@getpaseo/protocol": "0.15.0",
"@getpaseo/server": "0.15.0",
"@getpaseo/client": "0.15.1",
"@getpaseo/protocol": "0.15.1",
"@getpaseo/server": "0.15.1",
"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.15.0",
"version": "0.15.1",
"description": "Paseo client SDK package",
"files": [
"dist",
@@ -47,8 +47,8 @@
"test": "vitest run"
},
"dependencies": {
"@getpaseo/protocol": "0.15.0",
"@getpaseo/relay": "0.15.0",
"@getpaseo/protocol": "0.15.1",
"@getpaseo/relay": "0.15.1",
"ws": "^8.20.0",
"zod": "^4.4.3"
},
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/desktop",
"version": "0.15.0",
"version": "0.15.1",
"private": true,
"description": "Paseo desktop app (Electron wrapper)",
"homepage": "https://paseo.sh",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/expo-two-way-audio",
"version": "0.15.0",
"version": "0.15.1",
"description": "Native module for two way audio streaming",
"keywords": [
"ExpoTwoWayAudio",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/highlight",
"version": "0.15.0",
"version": "0.15.1",
"files": [
"dist",
"!dist/**/*.map",
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/plugin",
"version": "0.15.0",
"version": "0.15.1",
"description": "Paseo plugin SDK package",
"files": [
"dist",
@@ -77,8 +77,8 @@
"use-sync-external-store": "^1.6.0"
},
"devDependencies": {
"@getpaseo/client": "0.15.0",
"@getpaseo/protocol": "0.15.0",
"@getpaseo/client": "0.15.1",
"@getpaseo/protocol": "0.15.1",
"@types/node": "^20.9.0",
"@types/react": "~19.2.0",
"react": "19.2.3",
@@ -88,8 +88,8 @@
"zod": "^4.4.3"
},
"peerDependencies": {
"@getpaseo/client": "0.15.0",
"@getpaseo/protocol": "0.15.0",
"@getpaseo/client": "0.15.1",
"@getpaseo/protocol": "0.15.1",
"react": ">=19.1.0 <20",
"react-native": ">=0.81.5",
"zod": "^4.4.3"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/protocol",
"version": "0.15.0",
"version": "0.15.1",
"description": "Paseo shared protocol schemas and wire types",
"files": [
"dist",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/relay",
"version": "0.15.0",
"version": "0.15.1",
"description": "Paseo relay for bridging daemon and client connections",
"files": [
"dist",
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/server",
"version": "0.15.0",
"version": "0.15.1",
"description": "Paseo backend server",
"files": [
"dist/server",
@@ -107,11 +107,11 @@
"@agentclientprotocol/sdk": "^0.17.1",
"@anthropic-ai/claude-agent-sdk": "0.3.246",
"@anthropic-ai/sdk": "^0.104.2",
"@getpaseo/client": "0.15.0",
"@getpaseo/highlight": "0.15.0",
"@getpaseo/plugin": "0.15.0",
"@getpaseo/protocol": "0.15.0",
"@getpaseo/relay": "0.15.0",
"@getpaseo/client": "0.15.1",
"@getpaseo/highlight": "0.15.1",
"@getpaseo/plugin": "0.15.1",
"@getpaseo/protocol": "0.15.1",
"@getpaseo/relay": "0.15.1",
"@isaacs/ttlcache": "^2.1.4",
"@modelcontextprotocol/sdk": "1.29.0",
"@opencode-ai/sdk": "1.14.46",
@@ -70,7 +70,7 @@ import {
TerminalWorkerIncompatibleError,
} from "./terminal-worker-pool.js";
import { connectTerminalWorker } from "./terminal-worker-client.js";
import { launchTerminalWorker } from "./terminal-worker-launch.js";
import { launchTerminalWorker, TerminalWorkerLaunchError } from "./terminal-worker-launch.js";
type TerminalRow = TerminalState["grid"][number];
@@ -2658,3 +2658,34 @@ it.each([false, true])(
},
45000,
);
// Both Windows reports in #8766: the worker's process identity query (PowerShell there, `ps` here)
// fails, the worker exits before writing its record, and the daemon used to exit with it.
it.skipIf(isPlatform("win32"))(
"starts without a worker when the worker cannot read its own identity, and launches one once it can",
async () => {
const paseoHome = createTemporaryHome();
const binDir = mkdtempSync(join(tmpdir(), "worker-terminal-manager-no-ps-"));
temporaryDirs.push(binDir);
writeFileSync(join(binDir, "ps"), "#!/bin/sh\nexit 1\n", { mode: 0o755 });
const originalPath = process.env.PATH;
process.env.PATH = `${binDir}${delimiter}${originalPath ?? ""}`;
try {
manager = await startRealWorkerManager({ paseoHome });
expect(await workerRecords(paseoHome)).toEqual([]);
await expect(
manager.createTerminal({ workspaceId: "ws-no-identity", cwd: paseoHome }),
).rejects.toThrow(TerminalWorkerLaunchError);
expect(await workerRecords(paseoHome)).toEqual([]);
} finally {
process.env.PATH = originalPath;
}
const terminal = trackTerminal(
await manager.createTerminal({ workspaceId: "ws-no-identity", cwd: paseoHome }),
);
expect(terminal.id).toBeTruthy();
expect((await workerRecords(paseoHome)).map((record) => record.pid)).toHaveLength(1);
},
30000,
);
@@ -1269,8 +1269,17 @@ export async function startWorkerTerminalManager(
try {
current = await startCurrent();
} catch (error) {
if (!(error instanceof NoTerminalWorkerAvailableError)) throw error;
logger.warn(error.message);
if (error instanceof NoTerminalWorkerAvailableError) {
logger.warn(error.message);
} else {
// The daemon starts without terminals rather than not at all. A worker that cannot start
// here (its process identity query failed, say) is launched again by the first terminal
// creation, which reports the same error if it still cannot.
logger.error(
{ err: error },
"Terminal worker did not start; terminals are unavailable until one starts",
);
}
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/website",
"version": "0.15.0",
"version": "0.15.1",
"private": true,
"type": "module",
"scripts": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@getpaseo/builtin-plugins",
"version": "0.15.0",
"version": "0.15.1",
"private": true,
"type": "module",
"scripts": {