Commit Graph
5815 Commits
Author SHA1 Message Date
99e4b53aa0 fix(app): restore outline jumps to prompts rendered by plugins (#6690)
* fix(app): jump the chat outline to prompts a timeline plugin draws

A timeline transformer replaces a stream item with plugin rows whose ids
are "<pluginId>/<itemId>". The chat outline, chat find and history reveal
look a message up by the source item's id, so once a plugin drew the
prompts the outline found no row: the rail showed the prompts and
clicking one did nothing, for mounted, virtualized and unloaded prompts
alike.

Projected plugin rows now carry the id of the item they replaced, and
getStreamItemMessageId answers with it. Row wrappers, the virtualized
index lookup, the visible-message set and history reveal all read that
function, so they now find the plugin row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(app): verify outline jumps to virtualized plugin prompts

Replacing every prompt keeps all loaded rows mounted, so the original plugin regression never exercised a virtualized target. Retain newer native prompts and verify that a loaded unmounted plugin prompt lands without fetching.

Co-authored-by: luopeihuan <luopeihuan@roundreddot.com>

* test(app): retain outline navigation screenshots

---------

Co-authored-by: luopeihuan <luopeihuan@roundreddot.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-12 12:10:54 +02:00
Mohamed Boudra 750cb82fbb Keep long mobile drafts readable with fullscreen editing (#6531)
* feat(app): add fullscreen editing to the compact composer

* fix(app): preserve read-only terminal command previews

Static command previews must render their published source; the live editor buffer is updated after render and has no mounted input to repaint read-only content.

* fix(app): import React for composer editing scope rendering

Workspace pane unit tests use the classic JSX transform, so the editing-scope provider needs React in scope when mounted.

* fix(app): preserve fullscreen composer controls and editing

Keep the fullscreen frame inside the visual viewport, gate hidden autocomplete keys, apply replacement commands to local line measurement, and return to inline before starting voice so its controls stay accessible.

* test(app): cover draft replacement through the production composer

Replace the measurement-hook fixture with profile switching and typing through the real composer. Keep measurement state inside its production surface; Android manual red/green evidence covers the native replacement flow.
2026-10-12 16:26:01 +07:00
paseo-bot[bot] 9246813fd2 Preserve spaces in project folder names for Changes and worktrees (#6686)
* fix(workspaces): preserve spaces in project directory names

Git path output and app workspace descriptors each stripped significant path whitespace. Preserve directory names while retaining single-record Git output validation and workspace separator normalization.

* test(workspaces): capture Changes after files appear

* test(workspaces): release fixtures when setup fails

---------

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-12 10:25:18 +02:00
Elowen 06f0522258 fix(server): invalidate worktree listings after archive (#6545)
* fix(server): invalidate worktree listings after archive

* fix(server): clear archived worktrees across cached checkout roots
2026-10-12 08:58:54 +02:00
paseo-bot[bot]and见安 9b92b2e25c Preserve base worktree paths when merging (#6668)
* fix(git): preserve the base worktree path when merging

* test(git): cover merging into whitespace worktree paths

* test(git): follow the server object parameter convention

* test(git): keep merge fixture line endings deterministic

Disable automatic CRLF checkout in the fixture repository so the exact-content assertion works with Windows Git defaults.

Co-authored-by: 见安 <73627805+Mar-garet@users.noreply.github.com>

---------

Co-authored-by: 见安 <73627805+Mar-garet@users.noreply.github.com>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-12 06:00:59 +02:00
Elowen a310444c67 fix: save workspace files with long valid names (#6658)
* fix(file-explorer): keep atomic save temporary names short

* test(file-explorer): cover saving long names through daemon RPC
2026-10-12 04:58:00 +02:00
paseo-bot[bot]and见安 c364b16d40 Report canceled child tasks and wait for replacement tasks to finish (#6660)
* fix(server): report canceled child turns to their callers

* fix(server): wait for replacement child tasks before notifying callers

A displaced turn emits cancellation while its replacement is still running. Notify on terminal events only once the child becomes idle, so Stop and Reload report cancellation while replacement prompts produce one eventual outcome.

Co-authored-by: 见安 <73627805+Mar-garet@users.noreply.github.com>

* test(server): remove debug output from cancellation regressions

---------

Co-authored-by: 见安 <73627805+Mar-garet@users.noreply.github.com>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-12 04:00:12 +02:00
paseo-bot[bot] dc7bc8db12 fix(app): keep typechecking after Expo generates environment types (#6656)
Expo declares NODE_ENV readonly after web startup. Preserve the early test environment setup with Object.assign and exercise the real configuration with Expo types in a failing-first compiler regression.

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-12 02:49:09 +02:00
paseo-bot[bot] 40f0393064 Record shortcuts using the keyboard layout character (#6652)
* fix(app): record shortcuts using the keyboard layout character

Shortcut capture stored the QWERTY position while dispatch matched the logical character, so a Dvorak B became Cmd+N. Use the existing logical key mappings for capture and preserve code fallback for named and rewritten Option keys.

* fix(app): keep named shortcut keys on their supported codes

Character capture must not advertise unsupported named keys. Restrict the logical lookup to printable mappings so keypad Enter keeps its existing unsupported behavior.

---------

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-12 01:58:11 +02:00
paseo-bot[bot] 166aabd57b Keep subprocess regression tests independent of terminal colors (#6648)
* test(server): isolate subprocess regressions from terminal colors

Inherited NO_COLOR and FORCE_COLOR make Node emit an unrelated warning. It contaminates argv-fixture stderr and fails the closed-output supervisor fixture before its pipe handlers are installed. Clear both settings only in these fixture subprocesses, preserving their output and lifecycle assertions.

* test(server): exercise conflicting colors regardless of parent environment

Run the closed-output and spaced-executable regressions with explicit conflicting color inputs as well as the inherited environment, so removing fixture isolation fails on ordinary CI environments too.

---------

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-12 00:47:28 +02:00
b852ae920b fix(desktop): show the Paseo window icon on Linux (#6645)
Packaged windows read resources/icon.png, but Linux packages only
installed desktop-entry icons. Include the runtime PNG and verify its
bytes in the existing packaged artifact smoke test.

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
Co-authored-by: Ivan Pantic <panta@talentkit.io>
Co-authored-by: Max Höhl <43786929+whme@users.noreply.github.com>
2026-10-11 23:57:52 +02:00
paseo-bot[bot]andX b3693b79d1 Find hidden agent plan files in workspace suggestions (#6641)
* fix(server): find hidden agent plan files in workspace suggestions

Workspace autocomplete skipped the editor's plan directory while traversing
other known agent directories. Include it in the existing discovery policy
and cover basename and partial-path queries through the daemon client.

Co-authored-by: X <X@16x.org>

* test(server): give plan suggestion queries explicit expectations

---------

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
Co-authored-by: X <X@16x.org>
2026-10-11 21:54:46 +02:00
0458988825 Connect the self-hosted web app through standard-port proxies (#6638)
* fix(server): give the web UI connection hint an explicit port (#1)

injectConnectionHint built `listen` straight from the Host header, which
carries no port when the client used the scheme's default — exactly what a
browser sends to a proxy terminating TLS on 443. The app parses `listen` with
parseHostPort, which requires an explicit port, so connectionFromListen
returned null and bootstrapInitialConnectionHint bailed before probing,
silently. Boot then fell through to the localhost:6767 fallback, which is the
viewer's own machine rather than the daemon, and the app landed on the welcome
screen with no host at all.

Reaching the daemon directly never hit this: http://host:6767 puts the port in
the Host header. It only appears behind a reverse proxy on 443 or 80, such as a
Tailscale Ingress, and only in a browser profile with no host already stored.

Spell the scheme default out when the header omits it, leaving the IPv6 bracket
form intact.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

* fix(server): compute the web bootstrap port before its connection hint

Keep the default-port fix for reverse proxy bootstrap within the repository branching style.

Co-authored-by: Sian Lerk Lau <kiawin@gmail.com>

---------

Co-authored-by: Sian Lerk Lau <kiawin@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-11 20:51:51 +02:00
paseo-bot[bot] 4bd31e1a2e test(cli): accept Codex catalogs without branded model IDs (#6633)
The provider regression test rejected valid GPT catalogs solely because no ID contained codex. Keep the structural output checks without requiring that upstream branding substring.

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-11 19:47:10 +02:00
paseo-bot[bot]andOkan YILDIRIM 1939ee79ed Accept daemon settings in the published editor schema (#6621)
* fix(config): accept daemon settings in the published editor schema

The website schema omitted accepted configuration fields, so editors
rejected valid browser, profile, plugin and metadata settings. Regenerate
from the daemon schema and guard the published artifact against drift.

Co-authored-by: Okan YILDIRIM <63511519+ragokan@users.noreply.github.com>

* fix(config): preserve proxy help when regenerating the schema

Keep the existing editor descriptions in the source schema so regeneration retains them. The new regression fails when the proxy descriptions disappear.

* test(usage): create SQLite store fixtures in one transaction

The Windows plugin suite exceeded its five-second test deadline while creating and exercising the first OMP store fixture. Commit the fixture as a unit rather than flushing each inserted row separately; preserve the read-only discovery assertions.

* test(config): show structured schema validation errors

---------

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
Co-authored-by: Okan YILDIRIM <63511519+ragokan@users.noreply.github.com>
2026-10-11 18:50:03 +02:00
paseo-bot[bot]andBudi 8d9e7d3ad3 Confirm remote permission approvals before reporting success (#6607)
* fix(cli): await permission resolution before closing transport

* test(cli): verify permission confirmation over real connections

Exercise permission commands through a real WebSocket protocol peer, keeping responses pending until explicit resolution. This catches success before acknowledgement without replacing the client connector or process output. Retain the contributor permission fix and verify both commands, batches, and unconfirmed responses.

Co-authored-by: Budi <11062155+budivoogt@users.noreply.github.com>

* test(cli): catch permission batches completing after one reply

Hold the second acknowledgement until a WebSocket round trip proves the first reply reached the client. A first-reply-only mutation must fail both batch tests.

* test(cli): inject permission clients into command regression tests

* test(cli): use timer helper for permission continuations

* style(cli): format permission regression tests with oxfmt

---------

Co-authored-by: Budi <11062155+budivoogt@users.noreply.github.com>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-11 18:03:43 +02:00
paseo-bot[bot]and见安 114389383d Keep files starting with two dots usable (#6604)
* fix(file-explorer): distinguish parent traversal from dot-prefixed names

* test(file-explorer): cover dot-prefixed paths through daemon RPC

* test(plugins): allow slower session readiness in provider fixtures

The event helper exhausted 200 iterations before a valid delayed session
became ready. Use an elapsed-time deadline while preserving real timers
for watchdog tests, and retain a delayed-start regression with launch
flag assertions.

Co-authored-by: 见安 <73627805+Mar-garet@users.noreply.github.com>

---------

Co-authored-by: 见安 <73627805+Mar-garet@users.noreply.github.com>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-11 16:51:00 +02:00
Elowen 804335bc00 fix(files): rename untracked bracket paths without matching siblings (#6573)
* fix(files): use literal paths when checking rename tracking

* fix(files): preserve Git activity labels for rename lookups

* fix(files): clear inherited literal mode for rename lookups

* test(files): cover tracked renames with inherited literal mode
2026-10-11 13:53:25 +02:00
Jiawen Geng e2fd5a9c57 fix(app): keep markdown text that only looks like HTML verbatim (#6370)
The html-ish pass feeds markdown to htmlparser2 so it can render
<details>, <img> and friends. htmlparser2 reads any `<` followed by a
letter as a tag and collects attributes up to the next `>`. A cell such
as `1<ratio<2` in a table therefore swallowed the rows after it, and the
re-serialized "tag" dropped the newlines and pipes that made them rows.
The same path broke autolinks (`<https://x/y>` became `<https: x y>`)
and cut text after a trailing `a<b`.

Only hand htmlparser2 what CommonMark reads as raw HTML: open tags,
closing tags and comments. Every other `<` stays text.

Unknown tags are rendered back as text, but they were rebuilt from the
parser's lowercased name and attributes, so `As<Integer>()` showed as
`As<integer>()`. Echo the source slice instead.
2026-10-11 13:20:37 +02:00
paseo-bot[bot]andIvan Malison b412374f0c Run React tests when the shell uses NODE_ENV=production (#6572)
* fix(tests): run React tests from production shells

Vitest preserves an inherited NODE_ENV, selecting React without its test APIs. Pin the environment before dependency resolution and worker startup in both test entry points.

Co-authored-by: Ivan Malison <IvanMalison@gmail.com>

* test(app): expect zero edits for a pure staged rename

The rename patch correction on main preserves unchanged content. Keep the discard journey intact and update its obsolete added-line assertion.

---------

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
Co-authored-by: Ivan Malison <IvanMalison@gmail.com>
2026-10-11 11:52:50 +02:00
paseo-bot[bot]andYu Han a3f75aa9e4 Show removed SQL comments in Git diffs (#6569)
Hunk content resembling patch headers was discarded before line parsing. Metadata is already ignored before the first hunk, so preserve every added and removed line once a hunk starts.

Closes #6564

Co-authored-by: Yu Han <73627805+Mar-garet@users.noreply.github.com>
2026-10-11 11:03:15 +02:00
paseo-bot[bot]and见安 46b1284177 Release files when HTTP downloads are canceled (#6567)
* fix(server): close canceled HTTP download streams

* test(server): verify canceled downloads release real file descriptors

Exercise the reported HTTP cancellation path without replacing shared Node methods, and include download regressions in the standard integration suite.

Co-authored-by: 见安 <73627805+Mar-garet@users.noreply.github.com>

* test(server): detect canceled download leaks through symlinked paths

Compare descriptor targets with the resolved file path and exercise a symlinked download directory so the regression cannot pass by missing the open file.

---------

Co-authored-by: 见安 <73627805+Mar-garet@users.noreply.github.com>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-11 09:57:29 +02:00
paseo-bot[bot]and见安 a5dba3c992 Show checkout patch lines with external Git diff commands configured (#6562)
* fix(server): parse Git patches without external diff commands

* test(server): keep diff command checks aligned with parsed patches

The external diff regression fix intentionally disables helper commands.
Keep the existing large-file batching assertions aligned with that command
while preserving their patch, omission, and concurrency checks.

Co-authored-by: 见安 <73627805+Mar-garet@users.noreply.github.com>

---------

Co-authored-by: 见安 <73627805+Mar-garet@users.noreply.github.com>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-11 08:58:07 +02:00
paseo-bot[bot] dd0350bc2b Show actual edits when a file is renamed in Changes (#6559)
* fix(server): show actual edits when a file is renamed

Path-limited patch requests discarded the detected rename source, so Git reported the destination as a new file. Include both literal paths and select the destination patch to preserve the rename and avoid duplicating changed copy sources.

* fix(server): preserve small copy patches beside oversized sources

Filter rename and copy output before enforcing the bounded request budget, so a modified source cannot hide its small copy patch.

---------

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-11 07:55:09 +02:00
paseo-bot[bot] cfb18f16d4 fix(app): find starting refs by change request descriptions (#6558)
Preserve returned change request bodies as search-only option text so client filtering keeps description matches. Keep title and ID matches ranked ahead of secondary text.

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-11 06:53:37 +02:00
paseo-bot[bot] 7f9b65d464 test(server): keep commit fixture authors independent of Git config (#6552)
Command-scoped user.name overrides the fixture repository configuration and breaks its author assertion. Supply the fixture author when creating commits and exercise the override with real Git.

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-11 05:46:39 +02:00
paseo-bot[bot] 7e66657bf0 fix(agent): preserve reasoning order in activity transcripts (#6546)
Format projected text entries in sequence instead of grouping replies ahead of their preceding reasoning. Timeline projection already owns fragment merging.

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-11 05:00:02 +02:00
paseo-bot[bot] 446749102e test(server): make commit signing checks independent of global format (#6540)
The failing signer uses gpg.program, which Git bypasses when a global SSH signing format is inherited. Select OpenPGP in the commit and squash-merge test repositories so both checks exercise their configured failing signer.

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-11 03:46:59 +02:00
paseo-bot[bot] e61009d5fb fix(server): display diffs with custom Git presentation settings (#6536)
Request uncolored patches with explicit a/ and b/ prefixes before parsing. Mnemonic paths do not match checkout entries, and forced ANSI colors hide patch headers and hunks.

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-11 03:00:33 +02:00
ee0d901efb Run each scheduled slot once without skipping the next occurrence (#6532)
* fix(server): claim scheduled slots atomically

* fix(server): skip elapsed schedule slots

* test(server): isolate overlapping tick runner

* test(schedule): reproduce duplicate cron dispatch across overlapping ticks

* fix(schedule): preserve final slots and recovery after failed outcome writes

Historical running records are not proof of a live execution after an outcome write fails. Keep live-run exclusion in the existing in-memory guard while the persisted cursor prevents duplicate slot claims. Final allowed runs do not need a future cron occurrence; recover interrupted final runs and preserve cadence if their limit changes during execution.

---------

Co-authored-by: Keith Kowal (paseo-dev) <keithpk+paseo-dev@kowal.me>
Co-authored-by: keithpk <keith@kowal.me>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-11 02:19:11 +02:00
paseo-bot[bot]andLorenzo Fiore d5513472ed Keep words intact in followed agent logs (#6528)
* fix(cli): keep streamed message fragments together in logs --follow

`paseo logs` without `-f` fetches the timeline projected, so
`projectTimelineRows` merges consecutive assistant and reasoning fragments by
exact concatenation before the transcript is rendered. Follow mode never got
there: it called `formatAgentActivityTranscript([item])` per arriving event, so
every fragment was projected alone and printed on its own line. Words broke at
fragment boundaries, a reader could not tell an author newline from a transport
one, and `[Thought]` was reprinted for each reasoning chunk.

Follow mode now keeps a fragment chain open using the same merge rule the
projection uses (same kind, same `turnId`, matching `messageId` when the event
carries one) and writes the text as it arrives instead of one line per event.
Only trailing whitespace is held back, so a message still ends trimmed the way
the one-shot transcript ends it, and the chain closes when another kind of item
arrives or the follow stops.

* test(cli): place daemon follow regression in its owning suite

* fix(cli): preserve filtered log boundaries and run the follow regression in CI

* test(cli): wait for a completed log line before terminating follow

---------

Co-authored-by: Lorenzo Fiore <fiorelorenzo.fl@gmail.com>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-11 00:55:14 +02:00
paseo-bot[bot] 1228c01a10 Find GitLab merge requests and issues by number (#6525)
* fix(gitlab): find merge requests and issues by number

GitLab text search matches titles and descriptions but not item numbers. Use repository-scoped IID filtering for numeric queries, keeping open-only results and the existing text search behavior.

* fix(gitlab): retain text matches in number searches

Supplement title and description search with the open-item number lookup, rather than replacing it. Prioritize exact numbers, deduplicate results, and preserve each list limit.

* refactor(gitlab): name list helper arguments

---------

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-11 00:03:10 +02:00
563c014dc1 Open assistant links to non-ASCII filenames (#6520)
* fix(app): decode percent-encoded assistant file links

markdown-it percent-encodes non-ASCII and space characters in link
hrefs, so a link like [x](docs/reports/报告.md) arrives as
docs/reports/%E6%8A%A5%E5%91%8A.md. The file:// and bare absolute-path
branches already run safeDecodeURIComponent, but the workspace-relative,
path:line, Windows, and home-relative branches did not, so clicking the
link tried to open the still-encoded name and failed with ENOENT.

Decode the path portion before the relative-path heuristics and in the
inline absolute/Windows branches so all href forms behave the same.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(app): decode hrefs only, never raw inline-code paths

Raw inline-code and linkified tokens reach the same parser as markdown
hrefs. Decoding unconditionally would send a real file named
my%20file.md to my file.md. Gate every decode on AssistantHrefParseOptions.decodeHref — set by the resolver only when the token
came from source.href — and extract parseWindowsFileLink to keep the
entry point under the complexity limit. Adds parse-level and
resolver-level regression tests for literal %20 filenames.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(app): keep raw absolute paths out of URL parsing

new URL() percent-encodes non-ASCII, so a raw inline-code path like
/tmp/开户.md became /tmp/%E5%BC%80%E6%88%B7.md when decodeHref was
false. Hrefs still go through URL parsing (normalizes dot segments
before decode); raw paths split the # fragment manually instead.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(app): keep encoded and literal file links distinct

Preserve inline-code provenance for Windows paths and key cached file lookups by their resolved query, path, and line range. Reproduce the reported non-ASCII Markdown link through the renderer and filesystem, with browser coverage for clicking it.

Co-authored-by: Ouyang Xingyuan <galaxyroaming@qq.com>

Co-authored-by: dengjiawen <dengjiawen@hortorgames.com>

* test(app): assert file content after opening the markdown link

Co-authored-by: sunshinehomeyu-blip <267551119+sunshinehomeyu-blip@users.noreply.github.com>

* fix(app): preserve encoded line markers in filenames

---------

Co-authored-by: Ouyang Xingyuan <galaxyroaming@qq.com>
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
Co-authored-by: dengjiawen <dengjiawen@hortorgames.com>
Co-authored-by: sunshinehomeyu-blip <267551119+sunshinehomeyu-blip@users.noreply.github.com>
2026-10-10 22:00:00 +02:00
Mohamed Boudra 01f9bc8291 Modernize compact headers and sidebar affordances (#6431)
* feat(app): modernize compact headers and sidebar affordances

Use a shared island header with quick tab creation and keep sheet footers inside their visible layout. Opt sidebar rows into touch sizing without changing global appearance settings.

* test(app): match darker light-theme workspace selection

* test(app): align plugin journeys with compact header
2026-10-10 20:53:09 +01:00
paseo-bot[bot] d0728cd1ed fix(opencode): preserve tool validation errors in v2 (#6519)
Failed bridge requests discarded the daemon error body before OpenCode could show the validation explanation to the agent. Preserve that message and status while retaining the HTTP fallback.

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-10 21:01:07 +02:00
paseo-bot[bot]and见安 0ba4d2526e Honor timestamps when reading and following agent logs (#6514)
* fix(cli): honor --since in agent logs

* test(cli): verify logs cutoff in the daemon-owned suite

Keep the real CLI and WebSocket regression while placing daemon fixtures
in the server suite, as the CI ownership contract requires. Invoke the
source CLI so the test runs with the server suite's dependency build.

Co-authored-by: 见安 <73627805+Mar-garet@users.noreply.github.com>

* test(server): use a portable loader URL for the logs regression

---------

Co-authored-by: 见安 <73627805+Mar-garet@users.noreply.github.com>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-10 19:48:42 +02:00
paseo-bot[bot]andJason 7868f5caf6 Keep email addresses intact when sending with Enter (#6471)
* fix: prevent file mention autocomplete from triggering on emails

Skip @ when preceded by a word character or +, and reject angle
brackets in mention queries so email addresses no longer open the
file autocomplete or steal Enter.

Closes #1364

* test(app): verify emails send intact without file completion

The word-character and plus guard tests previously passed because their queries included trailing spaces. Exercise each guard with the cursor at the end of the email, and cover Enter in the browser alongside normal file completion.

Co-authored-by: Jason <mildreins@gmail.com>

---------

Co-authored-by: Jason <mildreins@gmail.com>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-10 17:00:08 +02:00
paseo-bot[bot]andJason 0147edaaac Restore repository selection for CLI worktree commands (#6467)
* fix(cli): pass cwd to worktree ls and archive

worktree ls/archive called getPaseoWorktreeList({}) which fails because
the daemon requires cwd or repoRoot. Default to process.cwd(), accept
optional --cwd, and cover both with unit and CLI help tests.

Closes #2010

* test(cli): reproduce worktree listing without repository scope

* fix(cli): resolve local worktree paths from the calling directory

Local instance paths belong to the CLI working directory. Explicit endpoint paths remain daemon-relative, matching the project command convention. Cover both through the real daemon.

* refactor(cli): make repository directory selection explicit

---------

Co-authored-by: Jason <mildreins@gmail.com>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-10 15:53:10 +02:00
paseo-bot[bot]and2takumax-chura bd78e5efa4 Show committed changes for existing-branch worktrees (#6462)
* fix: resolve real base branch for worktrees checked out from an existing branch

When a worktree is created by checking out an already-existing branch,
the stored baseRefName was set to the branch's own name instead of the
repository's default branch. The diff panel then diffs the branch
against itself, always showing no changes.

Fixes #1873

* fix: fall back to the current branch when no default branch is found

Addresses Greptile review feedback on #1874: resolveRepositoryDefaultBranch
returns null for local-only repos with no origin/HEAD and no local
main/master (e.g. a repo whose trunk is "develop"), which previously
fell back to storing the checked-out branch as its own base — the
exact self-diff bug this PR fixes. Fall back to whichever branch is
currently checked out in the main repo instead.

* fix(server): preserve existing-branch diffs through workspace restore

Carry the resolved comparison base from the worktree creator into the workspace record. Resolve it for occupied branches too, so a fresh suffixed checkout still displays the feature's committed changes.

Co-authored-by: 2takumax-chura <takuma.okayama@churadata.okinawa>

* fix(server): skip deleted default refs when creating worktrees

---------

Co-authored-by: 2takumax-chura <takuma.okayama@churadata.okinawa>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-10 15:18:05 +02:00
e81d5d02b1 Keep terminal CJK text unchanged after returning to a workspace (#6452)
* fix(app): restore terminal surface after tab hide so CJK cells redraw

Retained panels use display:none. Coming back remasured without treating
that as a surface restore, so Hangul kept 2-cell slots while glyphs painted
at ~1 cell (extra gap). Reload WebGL if the context was lost and force a
refresh when the host grows from zero.

Closes #3434

* fix(server): keep wide-char continuation cells out of terminal snapshots

Wide chars (CJK) occupy two xterm cells, and the second cell reports no
chars. The snapshot capture collapsed that empty continuation to " ", so
every restored Hangul syllable took three columns instead of two. The
injected space was real: selecting and copying the restored row carried
it into the clipboard.

Capture the continuation as "" and have renderTerminalSnapshotToAnsi
skip it. No schema change; snapshots from older daemons still replay
verbatim.

* fix(app): restore retained terminals on presentation

Co-authored-by: seob717 <dev.seob717@gmail.com>

* fix(terminal): limit restoration changes to confirmed CJK corruption

Keep the independently reproduced snapshot fix. Surface recovery behavior remains unverified and belongs with the broader viewport report. Dispose the replay terminal after the regression test.

---------

Co-authored-by: Jason <mildreins@gmail.com>
Co-authored-by: seob717 <dev.seob717@gmail.com>
Co-authored-by: liujin0506 <liujin0506@qq.com>
Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-10 13:27:04 +02:00
paseo-bot[bot] b63a325be3 Let Android devices without a camera install Paseo from Google Play (#6339)
* fix(android): declare the camera optional so camera-less devices can install

Requesting CAMERA makes Android treat android.hardware.camera as a required
feature, so Google Play marks devices without a camera as incompatible.
Pairing works without QR scanning, so declare the camera features optional.

Fixes #6303

* test(app): resolve the manifest with the Expo CLI's prebuild packages

Load @expo/prebuild-config and @expo/config-plugins from @expo/cli instead
of the older hoisted copies, and set the F-Droid flag explicitly for each
build profile case.

---------

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
2026-10-10 09:54:15 +02:00
Mohamed Boudra 6ec6633425 feat(cli): expose account usage reports (#6474) 2026-10-09 23:51:32 +01:00
Mohamed Boudra b26b9234c0 Improve diff review with mobile comment sheets and direct feedback (#6455)
* feat(review): edit compact diff comments in a sheet

* feat(review): send diff feedback to workspace agents

Send saved reviews from the diff while retaining file navigation and unrelated composer drafts. Clear acknowledged versions only so comments edited or added during submission remain available.

* fix(review): preserve drafts and coordinate feedback across surfaces

Share pending submission ownership by draft while keeping recipient menus local. Retain editable text across presentation changes and acknowledgement, and reserve safe-area clearance for floating actions.

* fix(review): center a small primary feedback button on desktop

* fix(review): restore focus to feedback button after closing menu
2026-10-09 21:31:06 +01:00
Mohamed Boudra aec01ea605 feat(claude): offer Mythos 5.1 when Claude Code advertises it (#6403)
* feat(claude): add Mythos 5.1 with its model capabilities

* feat(claude): gate Mythos on advertised model identity

* fix(claude): retain capabilities for explicitly configured Mythos

* test(usage): load SQLite before timed store tests

The first Windows OMP store case exceeded its five-second budget while subsequent equivalent cases completed under a second. Load the builtin during test collection so its cold initialization does not consume the first test deadline.

* test(workspaces): publish complete service environment fixtures

Waiting for file existence races with writeFileSync creating the file before writing its contents. Rename completed JSON snapshots into place so the existing readiness check cannot expose an empty file.
2026-10-09 21:05:40 +01:00
paseo-ai[bot] a1da1b8f23 fix: update lockfile signatures and Nix hash [skip ci] 2026-10-09 15:43:26 +00:00
Mohamed Boudra 73390346ca fix(ios): address clipped chat and Markdown text (#6445)
* Revert "fix(app): reflow iPad chat text after pane resize (#5716)"

This reverts commit 5715b5ba62.

* docs(changelog): describe iOS text clipping fix for 0.11.2

* chore(release): cut 0.11.2
2026-10-09 16:35:43 +01:00
Mohamed Boudra 718ed932b7 Clarify maintainer and community roles in sponsor copy 2026-10-09 12:27:52 +02:00
0009a7e717 feat(workspaces): add background visibility (#5039)
* feat(server): let clients create internal agents

The daemon's own branch-name and commit-message generators run as
internal agents: never persisted, listed, flagged, announced, or seen by
plugin lifecycle hooks. Nothing outside the daemon could ask for one,
because the wire config schema strips `internal` and the agent.create
transform re-pins it. A plugin that runs a one-turn helper per event
therefore left an archived session in History every time.

Add an optional `internal` flag to `create_agent_request` (inherited by
`agent.create.request`), copy it onto the config in the session's create
path, and skip provider session persistence for it like the generators
do. The client SDK forwards the flag on both creation paths and gates it
once on `server_info.features.internalAgents`.

Two daemon paths assumed every agent is public and had to follow:
`resolveAgentIdentifier` now accepts a live agent by exact id, since the
id set it matched against came from listings that exclude internal
agents and left `wait_for_finish` answering "Agent not found"; and
archiving an internal agent now closes it without writing the record
that `registry.applySnapshot` used to leave behind, so `autoArchive`
does not accumulate hidden files on disk.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(server): keep internal agents whole through failure, archive, and wait

Review follow-ups for internal agents:

- A create that fails after the runtime is registered now closes the
  internal agent before rethrowing, so a hidden runtime cannot outlive
  the failed request. Public agents keep today's behaviour.
- Archiving an internal agent cascades to attached children like any
  parent. cascadeArchiveChildren takes the parent record instead of
  reading it back from storage, where an internal agent never is.
- The archived snapshot and last message of an internal agent stay
  readable by exact id for ten minutes, so create-then-waitForFinish
  returns the finished turn whether the wait lands before or after an
  auto-archive. Storage plays that role for public agents.
- The internal-agent e2e scenarios live in the existing
  create_agent_request lifecycle suite rather than a new file.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(server): cascade to live internal children and keep a failed internal create's worktree until it closes

Internal children never reach storage, so the parent archive cascade scans
live agents for them as well. A failed internal create now clears the
created id only after the runtime is archived, so worktree cleanup cannot
delete the directory under a runtime that would not close. Stored agent
payloads carry lastError, so a retained failed helper reports its error
through wait_for_finish instead of the generic message.

* feat(cli,mcp): expose internal agents and document --no-wait

paseo run gains --internal and create_agent gains internal, both forwarded
to the create request. --no-wait becomes the documented spelling for
returning immediately, matching paseo send; --background and --detach stay
as hidden aliases under COMPAT tags.

* test: follow the --no-wait rename and stub getRetiredInternalAgent

* feat: list internal agents on request and add internal workspaces

Internal agents stay hidden by default, but a caller can now ask for
them: `fetch_agents_request` takes `filter.includeInternal`, snapshots
carry `internal: true`, and `paseo ls --internal` shows them in an
INTERNAL column. The app never passes the flag.

Workspaces get the same flag. `workspace.create.request` with
`internal: true` persists a hidden workspace: listings, update
subscriptions, sync reads, empty-project counting, open-by-path, MCP
`list_workspaces`, and plugin workspace hooks all skip it unless the
caller opts in with `filter.includeInternal`. Every agent created inside
an internal workspace is internal and unpersisted; AgentManager applies
that from the workspace id before the plugin hook so creators cannot
opt out. Archive and shutdown enumerate internal agents so nothing
inside an internal workspace outlives it.

Surfaces: `paseo workspace create --internal`, `paseo workspace ls
--internal`, `paseo run --internal --new-workspace`, MCP
`create_workspace({ internal })`, SDK `workspaces.create({ internal })`
and `list({ filter: { includeInternal } })`. Clients gate on
`features.internalWorkspaces`.

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

* feat(workspaces): add background visibility with inherited creation defaults

* fix(cli): resolve workspace callers on the selected daemon

* test(workspaces): keep caller integration coverage in server suite

* test(cli): exercise workspace callers through CLI integration harness

* test(mcp): remove obsolete execution flags from browser fixtures

---------

Co-authored-by: marvin-ambrozio <marvin@gustavo.eng.br>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
2026-10-09 09:31:50 +01:00
Mohamed Boudra 29db2b7980 Keep created agents after first-prompt failures and bound fork history (#6379)
* fix(agents): preserve creation when the first prompt fails

A rejected initial prompt must leave a created agent with a turn error instead of returning the user to a draft whose creation key is already committed. Preserve receipt replay without repeating the prompt, and bound fork history to 100,000 characters before it becomes an attachment.

* test(creation): isolate user agent counters from background naming

Workspace naming uses internal provider sessions. Counting and rejecting those sessions made creation assertions depend on installed provider discovery timing. Keep discovery within the test adapters and scope observations to user-created agents.

* test(creation): retry temporary directory cleanup on Windows

Windows CI completed the rejection assertions but failed teardown with EBUSY. Match the daemon test harness bounded removal retries so transient directory locks do not fail creation tests.

* fix(agents): record rejected prompts before their errors

Startup rejection recorded only the system error, leaving the client to append its local prompt after it. Record the rejected submission at the terminal failure boundary so stream and fetched history agree on prompt-before-error ordering.

* fix(agents): require acceptance for delivery notifications

Retain rejected human submissions before their errors without projecting rejected inter-agent prompts as completed deliveries. Reproduces and fixes the notification regression exposed by merge CI.

* test(agents): retain rejected submissions across retries

The existing browser retry test assumed terminally rejected prompts disappeared. Assert the intended prompt-before-error history and a separate accepted retry while preserving draft, attachment, and ambiguous-steering checks.

* test(creation): allow integration latency in raw RPC responses

The peer inherited a one-second polling timeout despite exercising Git and provider startup. Reproduce the timeout with delayed startup and wait within an explicit integration budget while retaining all response and identity assertions.
2026-10-08 22:25:57 +01:00
Mohamed Boudra 8c096b5e33 docs: remove Linux setup detour from getting started (#6415) 2026-10-08 22:16:16 +01:00