mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-30 21:23:04 +00:00
4a5f98b3a444adc452f3976e585e0a9cc1c3cde9
7
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
41582eb5fd |
Terminals survive daemon restarts, crashes and updates (#7644)
* M1: terminals survive daemon restarts: stop reasons, detached terminal worker, kill cleanup
restart_server_request.killTerminals / shutdown_server_request.keepTerminals and server_info.features.terminalsSurviveRestart; CLI daemon restart --kill-terminals and daemon stop --keep-terminals (capability-gated). The terminal worker runs detached over an owner-only, secret-authenticated socket and is adopted on daemon start. One kill cleanup contract (the reaper) by birth time, used by the daemon, the supervisor and stopDaemonInstance. Settings offers Restart and close terminals.
* M1: fix review findings: reaper session/table retry, short-command creation order, remote kill-restart cleanup report, stop test port
* M1: fix review findings: reaper-owned cleanup record, session member identity by terminal id, unreadable cleanup records, Settings restart error rendered in the card
* M2: worker protocol versions and draining, worker runs from its own copy, desktop upgrades keep terminals, out-of-date daemon notice, docs/terminal-worker.md
- Daemon classifies live workers by protocol: adopts current, drains one version old, shuts
down older, leaves a newer one running and answers list/create with
terminal_worker_incompatible (daemon status prints it). Never more than two workers.
- esbuild worker bundle (build:lib); a built daemon copies bundle, shell integration and
node-pty into $PASEO_HOME/terminal-worker/<version>-<hash>/ and launches from it; copies no
record names are pruned.
- Desktop app_update/version_mismatch stop with keep terminals on macOS/Linux; Windows and a
daemon without the capability close them.
- Out-of-date daemon sidebar notice with Update button, worded by terminalsSurviveRestart.
- PASEO-13: unreadable worker records fail status and kill-restart retry.
- PASEO-14: a session member without a terminal id is unknown, not unrelated.
- Smoke test 46 with A/B installation fixtures and per-fixture CLI shims (PASEO-9 fold).
* M2: track in-flight worker requests without leaving an unhandled rejection
detach({ afterPendingRequests }) tracked each request with request.finally(), which rejects
with the request; a fire-and-forget send that timed out surfaced as an unhandled rejection
(worker-terminal-manager.test.ts). Track settlement only.
* M2: CI round 1 fixes: worker terminal manager in the MCP key test, status cleanup field, shared socket dir
- mcp-server.test.ts (new upstream test) built the worker manager with the old fork API;
it now starts a real detached worker in a throwaway home.
- daemon-session.test.ts expected status without terminalCleanupUnconfirmed (added in M1).
- paseo-daemon.test.ts: a home under the scratch temp dir is too long for a unix socket, so
the worker listens in the per-user paseo-<uid> directory, which outlives workers by design;
the test now requires it to be empty instead of absent.
* M2: run Windows PowerShell by its install path for process identity
server-tests (windows-latest): bootstrap-provider-availability.test.ts starts a daemon with a
PATH that holds only git, and the terminal worker failed to start: 'cannot read its own process
identity: spawn powershell.exe ENOENT'. Process inspection (managed-processes.ts inspect and the
terminal worker's process table) now runs %SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe.
* M2: lifecycle e2e plain stop uses the shutdown RPC on Windows
CI round 2, server-integration (windows-latest): 'stop and stop --force never signal processes
a stale or earlier-boot record names' called stopDaemonInstance without a shutdown channel,
which Windows refuses ('has no graceful shutdown channel'). Plain stops in the file now pass
one, as the CLI does.
* M2: native notice outlet, Windows desktop-update wording, worker cap counts unconfirmed cleanups, create recovers after a drain
* M2: phone sidebar mounts the callout slot (iOS notice verified), worker record reads retry transient errors
* M2: native notice preconditions use explicit working directories, one block per terminal
* M1: compact sidebar shows only native callouts on every platform; PTY round trips in the MCP key test get a 5 s window
* ci: pin Playwright browser jobs to ubuntu-24.04
The pinned Playwright (1.58) has no ubuntu-26.04 build, and forks whose
ubuntu-latest already resolves to 26.04 fail at browser install. Job names
are unchanged, so required-check contexts still match.
* ci: use ubuntu-latest for Playwright jobs, same as upstream
Reverts the ubuntu-24.04 pin; upstream main's Playwright shards pass on ubuntu-latest.
* fix(server): keep terminal worker record IO off the daemon event loop
* fix(server): restore terminal creation after worker failure
A disconnected terminal worker remained the current manager indefinitely, leaving dead sessions listed and every later create bound to a closed socket. Confirm process death before retiring the member and use the existing single launch path for replacement. Reconnect live workers and replay their screens while preserving terminal identity.
* test(server): verify orphan cleanup during worker recovery
Recovery reaps orphaned programs before a later daemon stop. The previous fixed-delay assertion raced that cleanup and failed when it completed promptly. Verify orphan removal, same-daemon replacement creation and cleanup on normal or forced stop instead.
* test(server): isolate Windows dependency fixture setup
Build the local package registry in setup so its npm packing processes do not consume the installation journey deadline. Install the platform package used by Windows runtime fixtures directly, avoiding an unused wrapper postinstall probe without a timeout.
* test(server): wait for pending watchers before disposal
Observation admission starts before asynchronous path setup reaches watcher subscription. Disposing at the admission counter races setup and never exercises late watcher cleanup. Wait for the subscriptions to be pending before disposing.
---------
Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
|
||
|
|
404d08d24b |
Report failed terminal launches and remove early exits (#6792)
* fix(server): report a terminal whose command cannot start instead of leaving a dead tab Opening a terminal profile whose command is not installed left a tab that could never be closed. Two problems sat on the same path. A terminal that dies during creation was resurrected by its own create. The worker sends terminalCreated, the createTerminal response and terminalExit in the same tick, so the parent drains all three before the awaiting create continuation resumes; that continuation called registerRecord a second time and put back a terminal the exit had just removed. Removal is owned solely by the terminalExit event and that event never comes twice, so the record outlived every close attempt: getTerminals kept listing it, capture returned nothing, kill was a silent no-op that still reported success, and only a daemon restart cleared it. The parent now tracks the ids with a create in flight and keeps the finished record when an exit removes one of them, so the create continuation returns the exited session instead of registering a live one. Removal still happens exactly once, in the terminalExit path. With the stuck tab gone, a missing command produced nothing at all: no tab and no message. node-pty spawns directly through execve on POSIX, with no shell, so a command that does not exist fails inside the spawn helper and surfaces as exit code 1 with no output -- exactly what `false` produces, so the exit carries no usable signal. createTerminal now resolves the command before spawning and fails the create when it cannot be found, so the daemon answers create_terminal with a null terminal and "<command>: command not found", which the app already renders. A command that starts and then exits non-zero still opens its tab. That resolution has to match what execve will do in the child, or a working profile is refused: it uses the terminal's own environment, built first so the check sees the per-cwd registered PATH and the entries buildTerminalEnvironment prepends, and it resolves a command containing a separator against the terminal's cwd rather than through PATH. Windows keeps resolving inside resolveTerminalSpawnCommand, which has its own shim handling and fallback. * fix(terminal): check exact executable names and verify launch output --------- Co-authored-by: KiraPC <pasqualecarmine.carbone@gmail.com> Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com> |
||
|
|
9760292650 |
fix(providers): launch plugin CLIs on Windows and tolerate Muse startup (#6151)
* fix(providers): launch plugin CLIs on Windows and tolerate Muse startup Plugin providers bypassed the core Windows launcher and the plugin host exposed an empty server SDK module. Share the launcher through the SDK and bind it in the host. Give Muse initialization its own deadline because native startup traverses session history before answering MSP. * fix(providers): terminate Windows launcher process trees A command-script launcher leaves the CLI behind cmd.exe. Expose forced process-tree termination in the server SDK, use it for Muse and SDK ACP teardown, and bound Muse closing so inherited streams cannot leave callers waiting forever. * test(muse): keep platform setup outside the teardown assertion * refactor(plugin): expose process capabilities without quoting helpers * fix(providers): close process trees on uncorrelated protocol errors |
||
|
|
b0c9de0c90 |
feat(plugins): first-class plugin providers — status, launch resolution, config overrides (#5707)
* feat(plugins): support provider status, launch resolution, and config overrides * fix(plugins): defer override warnings until provider startup settles |
||
|
|
dd7671be20 |
Remember model selections across workspace creation (#4401)
* fix(providers): remember model selections across workspace creation Keep saved model intent independent of catalogue readiness and use the caller-owned host and directory from the first render. Share discovery through provider-owned keys while preserving execution context. Give each target one committed snapshot, publish actual transitions atomically, and share catalogue content across client directory associations. Regression coverage exercises successful repeated creation and provider lifecycle boundaries. * fix(providers): preserve shared cache bodies during eviction Admit directory references with their bodies, retain reference recency during eviction and recovery, and remove the unused persisted index. Refresh known workspace catalogues concurrently. Make repeated-creation picker states explicit and seed mode tests from the installed provider catalogue, preserving assertions across Codex versions. * fix(providers): bound discovery independently per provider Settings refresh repairs all remembered targets, which otherwise starts an unbounded number of discoveries. Admit work after catalogue-key deduplication and keep each provider’s budget independent so a stalled provider cannot block another. Preserve active accounting across configuration changes and settle obsolete queued requests during replacement and shutdown. |
||
|
|
2cf041c4d8 | Keep provider diagnostics useful when discovery is slow (#1724) | ||
|
|
f352072dac |
Fix coding-agent terminal shortcuts not working on Windows (#1509)
* Fix coding-agent terminal shortcuts not working on Windows On Windows, opening a Terminal profile (Claude Code / Codex / OpenCode) did nothing, and afterwards even a plain New Terminal stopped working until restart. Three Windows-specific problems combined: - A failed node-pty conpty spawn completes asynchronously on its conout worker thread; the uncaught exception escaped the per-request try/catch and crashed the whole terminal worker, severing every terminal. Add uncaughtException / unhandledRejection guards so a single bad spawn keeps the worker alive. - Profile commands were passed to conpty unresolved. conpty's CreateProcess ignores PATHEXT, so bare codex (npm codex.cmd) wasn't found and .cmd/.bat shims can't run directly. Add resolveTerminalSpawnCommand() to resolve the real path and route .cmd/.bat through cmd.exe /c on Windows. - winget-installed CLIs (e.g. Claude Code) live under the winget Packages dir and aren't on PATH. findExecutable() now falls back to those known install locations, so all providers and terminal profiles benefit. Also surface a failed terminal create to the user via a toast instead of silently dropping the error. * Address review: simplify winget scan, narrow worker exception guard - Drop the single-element WINGET_PACKAGE_BIN_SUBDIRS loop in executable.ts and map package dirs directly to the root <name>.exe candidate. - Remove the unhandledRejection handler in the terminal worker (only the uncaughtException path is exercised by conpty's async spawn failure) and expand the comment to explain the keep-alive trade-off and the absence of a worker restart path. * Refactor executable resolution out of utils * Serialize terminal create requests in worker --------- Co-authored-by: danniel <liminfhu@gmail.com> Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com> |