Commit Graph

1428 Commits

Author SHA1 Message Date
accx
686a25fb65 Fix Windows import session path matching (#1012) 2026-05-17 20:32:28 +08:00
Mohamed Boudra
00e7ac9ec8 Fix OpenCode custom command hangs (#1063)
* Fix OpenCode slash command turns

* ci: install opencode in server-tests so real OpenCode e2e runs

Server tests previously only installed the Claude Code CLI, so every
opencode-*.real.e2e.test.ts self-skipped on CI. The custom-command and
turn-lifecycle real tests cover the OpenCode session SSE rewrite, so
add opencode-ai globally and let them run. Big Pickle is free so no
provider secrets needed.

* Fix OpenCode unit tests exposed by enabling opencode in CI

server-tests previously skipped every OpenCodeAgentClient test because
opencode-ai was not installed. Now that CI runs them, four real issues
surface:

- Drop unused mkdirSync import (was used on a code path 1812b1489
  refactored away on main; the rebase merged imports without rechecking
  usage). Fixes the lint job.
- Fix slash-command-timeout test passing four ctor args instead of three,
  which silently dropped the TestOpenCodeRuntime and ran against the real
  opencode runtime.
- Relax the listModels contextWindowMaxTokens assertion. Some providers
  routed through OpenCode (OpenAI in particular) don't expose a numeric
  context window; assert the type only when the field is present.
- Swallow late notifySubscribers calls once close() flips the closed
  flag and clear subscribers up front. The session-lifetime SSE stream
  introduced by the prior commit means a session.error arriving after
  the owning test has moved on can rejectCompletion on a deferred no
  one is awaiting, surfacing as an unhandled rejection in a downstream
  test file.
2026-05-17 19:51:20 +08:00
c4605
b3c272f720 Fix native diff row expansion (#940)
* Fix structured diff parsing for no-prefix paths

Git can emit diff --git path path when diff.noprefix is enabled. The structured diff parser only handled the default a/path b/path form, so checkout diff assembly could lose hunks for affected files and render expanded rows empty.

Normalize optional a/ and b/ prefixes in both app and server parsers, and cover the no-prefix header form with regression tests.

* Fix no-prefix diff path parsing

---------

Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
2026-05-17 18:58:10 +08:00
Samuel K
ec646db844 fix(mcp): add missing schedule tools (update, logs, run-once) (#1032)
* fix(mcp): add missing schedule tools (update, logs, run-once)

Add three schedule MCP tools to close the parity gap between
CLI (`paseo schedule update/logs/run-once`) and MCP surface.

The WebSocket RPC handlers and ScheduleService methods already
exist (added in PR #694), but the MCP tools were never registered.

Tools added:
- update_schedule: update interval, prompt, name, maxRuns, etc.
- schedule_logs: retrieve run history for a schedule
- run_once_schedule: trigger immediate one-time execution

Includes 8 unit tests covering all three tools.

Fixes #1031

* Fix schedule MCP update handling

---------

Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
2026-05-16 22:45:22 +08:00
Mohamed Boudra
1812b14898 Fix OpenCode session imports (#1055)
* Fix OpenCode session imports

* Update OpenCode session tests after import cleanup
2026-05-16 22:08:26 +08:00
Mohamed Boudra
39094078a9 chore(release): cut 0.1.76 2026-05-15 18:07:13 +07:00
Mohamed Boudra
160d861534 Fix agent turn timing persistence 2026-05-15 17:38:28 +07:00
Mohamed Boudra
dbe24b609d Fix OpenCode turn timing 2026-05-15 15:22:57 +07:00
Mohamed Boudra
9bf36cdb56 Handle unborn repos in changes diff 2026-05-15 15:08:41 +07:00
Mohamed Boudra
12e24f9620 Show built-in Claude slash command output
Claude CLI's built-in slash commands (/voice, /usage, "Unknown command:
...") run client-side with no model turn — they arrive as a result with
output_tokens: 0 and the user-visible text carried in result.result, but
no preceding assistant_message in the stream. Surface that text as an
assistant_message so the turn doesn't end silently.

Also unify Codex skill-command text blocks to always carry the
"$skill-name" prefix in the text payload, matching the no-args path
which already did.
2026-05-15 13:34:07 +07:00
Mohamed Boudra
29d46c5d92 test: allow checkout context logger 2026-05-15 10:28:41 +07:00
Mohamed Boudra
a72c7f6c4b Use daemon timestamps for turn timing (#1033) 2026-05-15 11:09:13 +08:00
Mohamed Boudra
2d3c9101f3 Trace git command spawn and close metadata
Thread an optional logger through runGitCommand and the CheckoutContext
helpers so workspace-git-service can emit trace-level traces around each
git invocation. Behavior is unchanged when no logger is supplied.
2026-05-15 09:50:05 +07:00
Mohamed Boudra
f27d39fb63 Normalize default thinking options (#1028) 2026-05-15 00:11:56 +08:00
Mohamed Boudra
fbeda4510e Fix duplicate project worktree registration (#1024)
* Fix duplicate project worktree registration

* Update archive redirect test for project-aware routes
2026-05-14 20:57:32 +08:00
Mohamed Boudra
7e255a5249 Fix assistant file link resolution (#1025) 2026-05-14 20:55:41 +08:00
Mohamed Boudra
a19b780eca Fix OpenCode retry timeout handling (#1026) 2026-05-14 20:55:19 +08:00
Mohamed Boudra
faa0d93cb8 Fix ahead count when upstream branch is gone (#1023) 2026-05-14 19:10:14 +08:00
Mohamed Boudra
2dd77aae04 Auto-archive worktrees after PR merge (#1004)
Add a daemon setting `autoArchiveAfterMerge` (default off). When on, the
daemon's existing GitHub poll triggers archive once the PR is merged,
but only if the worktree is clean (not dirty, not ahead of origin).
Skips silently otherwise.
2026-05-14 10:08:48 +00:00
Mohamed Boudra
8296c797ff Project rename: distinguishable names for duplicate projects (#1003)
* Add project rename so duplicates get distinguishable names

Two checkouts of the same remote collapse into a single project record
(same projectId), which left users unable to tell duplicates apart in
the UI. customName lives alongside the derived displayName as an
override that reconciliation never touches, so renames persist across
git-remote changes. The rename UI lives in project settings.

Closes #987 (rename half).

* Fix COMPAT(projectCustomName) version to v0.1.76

* Update useProjects shape test for new projectCustomName key

* Use sendCorrelatedSessionRequest for renameProject

Match the pattern used by checkoutPrMerge and other newer RPCs
instead of hand-rolling the select callback.

* Use project.rename.{request,response} dotted RPC names

Match the convention from docs/rpc-namespacing.md (added in 75a6f8277).
Schemas, type exports, daemon client, session handler, and tests all
move to the namespaced names. No back-compat shim needed since the RPC
hasn't shipped.
2026-05-14 17:49:24 +08:00
Mohamed Boudra
e1ab779fe0 Fix Shift+Enter in terminal input modes (#999)
* Fix Shift+Enter terminal input modes

* Advertise terminal input capabilities
2026-05-14 17:48:22 +08:00
Mohamed Boudra
eb7fa02ac8 Surface GitHub auto-merge actions (#1001)
* Surface GitHub auto-merge actions

* Namespace GitHub auto-merge RPC

* Update workspace git refresh test expectation

* Avoid redundant GitHub refresh queue
2026-05-14 17:48:05 +08:00
Mohamed Boudra
05c12a9c5c Fix branch-off worktree upstream tracking (#1002) 2026-05-13 17:06:51 +00:00
Mohamed Boudra
512702fe46 Avoid probing extra executable candidates (#996) 2026-05-13 15:14:47 +00:00
Mohamed Boudra
68fae16740 Recover Pi sessions after Copilot 413 (#995) 2026-05-13 15:00:22 +00:00
Mohamed Boudra
e96cd16a0f Deduplicate Codex skill commands (#992) 2026-05-13 13:58:31 +00:00
Mohamed Boudra
316eeee9ca Fix ACP diagnostic model counting (#991) 2026-05-13 13:54:34 +00:00
Mohamed Boudra
c3012ea520 Add Codex context compaction support (#990) 2026-05-13 13:52:21 +00:00
Mohamed Boudra
e2ecae0e72 Preserve Codex assistant message ids (#989) 2026-05-13 13:18:31 +00:00
Mohamed Boudra
49fa72d70d Make provider snapshot refresh explicit (#988) 2026-05-13 20:54:07 +08:00
Bolun Zhang
c6534b3a16 Add MCP provider feature discovery (#910)
Refs #835
2026-05-13 20:12:10 +08:00
Bolun Zhang
15631b815b Add MCP provider feature controls (#909)
Refs #835
2026-05-13 20:05:52 +08:00
Chuan
6ed7dfc42a fix(server): include OpenCode console subscription providers in model list (#917)
* fix(server): include OpenCode console subscription providers in model list

Providers with source "api" (e.g. Pi coding agent via OpenCode Go
subscription) appear in providers.all but not in providers.connected,
which only lists env/config providers. Paseo was filtering exclusively
by connected, so subscription-managed providers were silently dropped
and users saw an empty model list or a misleading "set env vars" error.

Fix: treat source === "api" as accessible in both listModels() and the
context-window lookup helper. Also update the error message to mention
the console login option.

chore: add portless as a devDependency so npm run dev works without
a global install.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: remove portless dependency

* test(server): add unit tests for OpenCode api-source provider inclusion

Covers the source="api" logic added in 08e3c6bf: providers managed by the
OpenCode console/subscription must appear in listModels and the context window
lookup even when absent from the connected list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: drop unrelated package-lock.json churn

The lockfile changes were peer metadata additions from a newer npm
version, not actual dependency changes. Restore to match main.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
2026-05-13 18:48:00 +08:00
Mohamed Boudra
2bd2e8bc46 feat(claude): discover models from settings
Fixes #649, #475, #455, #558
2026-05-13 18:47:50 +08:00
ezra
72293f7f4f fix(server): fall back PR status queries for fine-grained tokens
Fixes #926
2026-05-13 17:52:13 +08:00
Mohamed Boudra
65d14d4433 Show upstream ACP JSON-RPC errors instead of [object Object]
* Preserve ACP JSON-RPC error details

* Unslop ACP error summarization
2026-05-13 17:43:40 +08:00
Chris Banes
9eb1ddf29d fix(cursor): discover models via Cursor ACP client
Fixes #925
2026-05-13 17:12:53 +08:00
Mohamed Boudra
d18bfe9047 Add local settings to Claude configuration (#977) 2026-05-13 16:34:49 +08:00
Mohamed Boudra
ea0bb81100 fix(server): reconcile workspace kind alongside project kind (#975)
The reconciler updated project.kind when a directory became a git repo
but never updated the workspace.kind underneath, leaving the sidebar in
a split-brain state: an expandable git project containing a workspace
with no leading icon (workspaceKind stayed "directory" instead of
flipping to "local_checkout" or "worktree").
2026-05-13 15:58:48 +08:00
Mohamed Boudra
9d7d1e8500 Fix zsh integration runtime file modes (#976) 2026-05-13 15:58:20 +08:00
c4605
16c27d7404 Add Auto Review permission mode for Claude Code (#928)
* Add Auto Review permission mode

* Align Codex Auto Review with auto permissions

* Defer Codex Auto Review to dedicated PR

* fix(app): drop unconditional snapshot refresh on mode selector open

Opening the mode selector was reusing the model selector refresh path, which forced a provider snapshot refresh every time. That made the agent status bar briefly lose its selected provider data and flash empty while the picker opened.

Keep the stale model refresh on the model selector only, and let the mode selector open from the existing snapshot state.

* refactor(claude): rename Claude auto permission mode label to "Auto mode"

Claude Code itself calls this permission setting Auto mode in its CLI/TUI, so match that label in Paseo. The supporting test names and transport eligibility errors now use the same terminology.

---------

Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
2026-05-13 13:58:26 +08:00
Mohamed Boudra
b8a3eefd47 feat(codex): implement Auto-review permission mode (#963)
* feat(codex): plumb auto-review approvals reviewer

* feat(codex): add Auto-review mode visuals

* test(codex): cover Auto-review mode plumbing

* test(codex): prove Auto-review approval routing
2026-05-13 13:58:15 +08:00
Mohamed Boudra
d24087c10a Fix relay E2EE reconnect races (#973)
* Fix relay E2EE reconnect races

* fix(relay): use WebSocket protocol ping for daemon control keepalive

The daemon's control socket pinged the relay every 10s with a JSON
`{type:"ping"}` message. Every JSON message wakes a hibernated Cloudflare
Durable Object via `webSocketMessage`, so an idle daemon was billing
relay DO CPU 24/7 just to echo `pong`.

Switch to `socket.ping()` (RFC 6455 protocol ping frames). Cloudflare's
runtime auto-responds at the edge without waking hibernated DOs, so an
idle daemon-to-relay connection now costs zero DO CPU.

Liveness still works: the `ws` library emits a `pong` event on the
daemon when the edge replies, which refreshes `controlLastSeenAt`.
`markControlReady` stays tied to DO-originated messages (sync,
connected, disconnected), so we still detect a broken DO at connect.

The DO keeps its JSON ping handler tagged `COMPAT(relay-json-ping)` so
old daemons (< v0.1.76) continue to work.

* test(relay): assert protocol-ping pongs arrive in e2e idle test

Adds a `relay_control_pong_received` debug log to the daemon's pong
handler, then asserts in the existing idle-relay e2e test that:

  - at least one pong arrived during the 12s idle wait (proving the
    Cloudflare edge auto-responds to RFC 6455 protocol pings)
  - no stale terminations fired (proving the keepalive path is healthy)

If the daemon ever regresses to JSON-level keepalive pings (which wake
the hibernated relay Durable Object and incur CPU billing), this test
will catch it: the `pong` event would never fire because the DO's reply
would arrive via `message`, not as a protocol pong frame.

The test's capturing logger is bumped to `debug` level so the assertion
can read the new debug log; production daemons stay at `info`.

Confirmed locally against wrangler-hosted relay: 2 pongs / 0 stale per
12s window.

* test(relay): catch dual-ping regression via DO-side legacy ping log

The existing idle-test assertion catches "revert to JSON ping only" via
the missing pong event, but misses the dual-ping regression where
someone adds `socket.send(JSON.stringify({type:"ping"}))` alongside
`socket.ping()`. Both paths would work, the pong assertion still
passes, and DO CPU billing silently returns.

Add a console.log in the DO's handleControlKeepalive (which only runs
when a JSON ping reaches the DO), then assert in the idle e2e test
that no such log appeared during the 12s idle window.

Verified the assertion catches the regression: temporarily injected a
`socket.send(JSON.stringify({type:"ping"}))` next to socket.ping(),
test failed with `expected 1 to be 0` and the relay logged
`legacy_json_ping_received`. Removed the injection.

Log noise during the COMPAT window doubles as useful telemetry: it
counts how many old daemons are still pinging, which informs the
removal date for the COMPAT shim.
2026-05-13 13:44:11 +08:00
Bolun Zhang
15cab6014c Refresh MCP worktree cache after create/archive (#911)
* Fix MCP worktree list cache after create/archive

* Fix MCP worktree archive refresh from scoped cwd

---------

Co-authored-by: zbl <zbl@zbl-M4Pro.local>
Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
2026-05-12 22:17:17 +08:00
Mohamed Boudra
47d236a299 Add diagnostics for generic ACP providers (#955) 2026-05-12 21:24:03 +08:00
Mohamed Boudra
51d9563352 chore(release): cut 0.1.75 2026-05-12 17:35:22 +07:00
Mohamed Boudra
985ad52cce fix(copilot): preserve legacy autopilot mode alias 2026-05-12 17:34:09 +07:00
Mohamed Boudra
d198c68b9e Fail Codex resume requests explicitly (#947) 2026-05-12 17:50:31 +08:00
Mohamed Boudra
751a07124f Fix scheduled agent cleanup (#945) 2026-05-12 17:05:40 +08:00
ezra
db0d63dd90 Handle Windows shell wrappers in Codex command summaries (#931) 2026-05-12 15:07:37 +08:00