Compare commits

...

3 Commits

Author SHA1 Message Date
Mohamed Boudra
84478a2dba chore(release): cut 0.1.68 2026-05-05 16:46:10 +07:00
Mohamed Boudra
93065b20f7 Add changelog for 0.1.68 2026-05-05 16:45:16 +07:00
Mohamed Boudra
bb8762e122 Fix desktop settings first-launch race 2026-05-05 16:43:38 +07:00
13 changed files with 59 additions and 30 deletions

View File

@@ -1,5 +1,11 @@
# Changelog
## 0.1.68 - 2026-05-05
### Fixed
- The desktop app no longer fails on first launch after a fresh install.
## 0.1.67 - 2026-05-03
### Fixed

26
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "paseo",
"version": "0.1.67",
"version": "0.1.68",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "paseo",
"version": "0.1.67",
"version": "0.1.68",
"hasInstallScript": true,
"license": "AGPL-3.0-or-later",
"workspaces": [
@@ -38445,7 +38445,7 @@
},
"packages/app": {
"name": "@getpaseo/app",
"version": "0.1.67",
"version": "0.1.68",
"dependencies": {
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
@@ -38571,10 +38571,10 @@
},
"packages/cli": {
"name": "@getpaseo/cli",
"version": "0.1.67",
"version": "0.1.68",
"dependencies": {
"@clack/prompts": "^1.0.0",
"@getpaseo/server": "0.1.67",
"@getpaseo/server": "0.1.68",
"chalk": "^5.3.0",
"commander": "^12.0.0",
"mime-types": "^2.1.35",
@@ -38616,7 +38616,7 @@
},
"packages/desktop": {
"name": "@getpaseo/desktop",
"version": "0.1.67",
"version": "0.1.68",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@getpaseo/cli": "*",
@@ -38665,7 +38665,7 @@
},
"packages/expo-two-way-audio": {
"name": "@getpaseo/expo-two-way-audio",
"version": "0.1.67",
"version": "0.1.68",
"license": "MIT",
"devDependencies": {
"@types/react": "^18.0.25",
@@ -38701,7 +38701,7 @@
},
"packages/highlight": {
"name": "@getpaseo/highlight",
"version": "0.1.67",
"version": "0.1.68",
"dependencies": {
"@lezer/common": "^1.5.0",
"@lezer/cpp": "^1.1.5",
@@ -38727,7 +38727,7 @@
},
"packages/relay": {
"name": "@getpaseo/relay",
"version": "0.1.67",
"version": "0.1.68",
"dependencies": {
"base64-js": "^1.5.1",
"tweetnacl": "^1.0.3",
@@ -38742,12 +38742,12 @@
},
"packages/server": {
"name": "@getpaseo/server",
"version": "0.1.67",
"version": "0.1.68",
"dependencies": {
"@agentclientprotocol/sdk": "^0.17.1",
"@anthropic-ai/claude-agent-sdk": "^0.2.11",
"@getpaseo/highlight": "0.1.67",
"@getpaseo/relay": "0.1.67",
"@getpaseo/highlight": "0.1.68",
"@getpaseo/relay": "0.1.68",
"@isaacs/ttlcache": "^2.1.4",
"@mariozechner/pi-agent-core": "^0.70.2",
"@mariozechner/pi-ai": "^0.70.2",
@@ -39200,7 +39200,7 @@
},
"packages/website": {
"name": "@getpaseo/website",
"version": "0.1.67",
"version": "0.1.68",
"dependencies": {
"@cloudflare/vite-plugin": "^1.20.3",
"@cloudflare/workers-types": "^4.20260114.0",

View File

@@ -1,6 +1,6 @@
{
"name": "paseo",
"version": "0.1.67",
"version": "0.1.68",
"private": true,
"description": "Paseo: voice-controlled development environment with OpenAI Realtime API",
"keywords": [

View File

@@ -1,6 +1,6 @@
{
"name": "@getpaseo/app",
"version": "0.1.67",
"version": "0.1.68",
"private": true,
"main": "index.ts",
"scripts": {

View File

@@ -1,6 +1,6 @@
{
"name": "@getpaseo/cli",
"version": "0.1.67",
"version": "0.1.68",
"description": "Paseo CLI - control your AI coding agents from the command line",
"bin": {
"paseo": "bin/paseo"
@@ -24,7 +24,7 @@
},
"dependencies": {
"@clack/prompts": "^1.0.0",
"@getpaseo/server": "0.1.67",
"@getpaseo/server": "0.1.68",
"chalk": "^5.3.0",
"commander": "^12.0.0",
"mime-types": "^2.1.35",

View File

@@ -1,6 +1,6 @@
{
"name": "@getpaseo/desktop",
"version": "0.1.67",
"version": "0.1.68",
"private": true,
"description": "Paseo desktop app (Electron wrapper)",
"homepage": "https://paseo.sh",

View File

@@ -43,6 +43,22 @@ describe("desktop-settings", () => {
expect(persisted.settings).toEqual(DEFAULT_DESKTOP_SETTINGS);
});
it("handles concurrent first-launch reads without racing the settings write", async () => {
const userDataPath = await createTempUserDataDir();
directories.add(userDataPath);
const store = createDesktopSettingsStore({ userDataPath });
const settings = await Promise.all(Array.from({ length: 20 }, () => store.get()));
const persisted = JSON.parse(await readFile(settingsFilePath(userDataPath), "utf8")) as {
settings: DesktopSettings;
};
const files = await readdir(userDataPath);
expect(settings).toEqual(Array.from({ length: 20 }, () => DEFAULT_DESKTOP_SETTINGS));
expect(persisted.settings).toEqual(DEFAULT_DESKTOP_SETTINGS);
expect(files).toEqual(["desktop-settings.json"]);
});
it("coerces invalid persisted values back to safe defaults", async () => {
const userDataPath = await createTempUserDataDir();
directories.add(userDataPath);

View File

@@ -1,3 +1,4 @@
import { randomUUID } from "node:crypto";
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
import path from "node:path";
@@ -198,13 +199,19 @@ export function createDesktopSettingsStore({
}): DesktopSettingsStore {
const filePath = path.join(userDataPath, DESKTOP_SETTINGS_FILENAME);
let cachedDocument: PersistedDesktopSettingsDocument | null = null;
let persistQueue: Promise<void> = Promise.resolve();
async function persistDocument(document: PersistedDesktopSettingsDocument): Promise<void> {
await mkdir(userDataPath, { recursive: true });
const tempFilePath = `${filePath}.tmp`;
await writeFile(tempFilePath, `${JSON.stringify(document, null, 2)}\n`, "utf8");
await rename(tempFilePath, filePath);
cachedDocument = document;
const write = async () => {
await mkdir(userDataPath, { recursive: true });
const tempFilePath = `${filePath}.tmp.${process.pid}.${randomUUID()}`;
await writeFile(tempFilePath, `${JSON.stringify(document, null, 2)}\n`, "utf8");
await rename(tempFilePath, filePath);
cachedDocument = document;
};
const queued = persistQueue.then(write, write);
persistQueue = queued.catch(() => undefined);
await queued;
}
async function loadDocument(): Promise<PersistedDesktopSettingsDocument> {

View File

@@ -1,6 +1,6 @@
{
"name": "@getpaseo/expo-two-way-audio",
"version": "0.1.67",
"version": "0.1.68",
"description": "Native module for two way audio streaming",
"keywords": [
"ExpoTwoWayAudio",

View File

@@ -1,6 +1,6 @@
{
"name": "@getpaseo/highlight",
"version": "0.1.67",
"version": "0.1.68",
"files": [
"dist"
],

View File

@@ -1,6 +1,6 @@
{
"name": "@getpaseo/relay",
"version": "0.1.67",
"version": "0.1.68",
"description": "Paseo relay for bridging daemon and client connections",
"files": [
"dist"

View File

@@ -1,6 +1,6 @@
{
"name": "@getpaseo/server",
"version": "0.1.67",
"version": "0.1.68",
"description": "Paseo backend server",
"files": [
"dist/server",
@@ -58,8 +58,8 @@
"dependencies": {
"@agentclientprotocol/sdk": "^0.17.1",
"@anthropic-ai/claude-agent-sdk": "^0.2.11",
"@getpaseo/highlight": "0.1.67",
"@getpaseo/relay": "0.1.67",
"@getpaseo/highlight": "0.1.68",
"@getpaseo/relay": "0.1.68",
"@isaacs/ttlcache": "^2.1.4",
"@mariozechner/pi-agent-core": "^0.70.2",
"@mariozechner/pi-ai": "^0.70.2",

View File

@@ -1,6 +1,6 @@
{
"name": "@getpaseo/website",
"version": "0.1.67",
"version": "0.1.68",
"private": true,
"type": "module",
"scripts": {