# Description of Changes
Adds the ability for the Edit agent to request the content of the
document before it decides which parameters it needs. This makes it able
to process requests like `Split the document after the page containing
the "My Section" section`, allowing for document context-based requests
for all[^1] tools.
I had to make a few changes elsewhere to make this work, including:
- Moving the requesting of content out of the Question Agent and into a
common location
- Added specific API docs for the Split param because the generic ones
were not specific enough for the AI to be able to reliably perform the
correct operation
- Fixed an issue in the tool models generator which caused the Redact
params to only be half-generated (causing Pydantic to crash when the AI
tried to run Redact)
- Added missing logging to a bunch of tools and hooked it up properly so
it'll print to stderr
- Made the limits for the max pages/chars to extract from PDFs
configurable via env var
[^1]: Many of the tools can't actually do anything useful with the
context at this stage, but will just need the tool API to be extended
with new features like page-specific operations to be automatically able
to do smart operations without needing to change the Edit agent itself.
# Description of Changes
We keep adding stuff to `engine/config/.env.example` and have to
manually update `.env` because of it, which is really clunky, especially
when working on multiple worktrees at once. This PR changes it so that
we just have a committed `.env` file and have an `.env.local` override
to put the actual private keys into, which should make it a bit easier
to manage.
> [!warning]
>
> After this goes in, be very careful for a little while not to
accidentally commit any keys that you've got inside your `.env` file!
# Description of Changes
Add an extra parameter to every agent to receive the conversation
history in addition to the current message. This will make it possible
to answer followup questions from the AI without needing to give full
context in your message.
# PR: feature/UIRedesign → UIRedesignStaging
## Overview
Major layout restructure: the old right-rail icon column and top
file-tab strip are replaced by a new horizontal `WorkbenchBar` and a new
persistent `FileSidebar` on the left. Alongside those headline changes,
a range of bugs are fixed around viewer state, file management, and
thumbnail caching.
---
## Changes
### 1. Page layout restructured
**Before:** `QuickAccessBar` above content, `ToolPanel` on the left,
`RightRail` vertical icon column on the right.
**After:** `FileSidebar` on the left, `WorkbenchBar` across the top,
`ToolPanel` on the right. The right rail is gone.
---
### 2. `FileSidebar` — new persistent left sidebar
**Why:** The only way to see saved files was opening the file manager
modal. The sidebar gives quick access to everything in IndexedDB without
a modal.
**Before:** No persistent sidebar. Files managed exclusively via the
modal.
**After:**
- Collapsible strip on the left (collapses to a narrow icon strip,
expands to a file list).
- Shows all saved files, sorted by last modified. Files not yet
persisted to IndexedDB also appear.
- Click a file to toggle it on/off the workbench. If the file is open in
the viewer with unsaved changes, the save prompt fires first.
- Search bar filters by filename.
- Add files from computer or Google Drive directly from the sidebar.
- Thumbnail appears on hover, loaded lazily and cached for future
visits.
- The currently-viewed file is pinned at the top of the list with a
green highlight.
- List updates automatically when files are added or deleted anywhere in
the app.
---
### 3. `WorkbenchBar` replaces `TopControls` + `RightRail`
**Why:** `TopControls` only showed when files existed and only displayed
file tabs. The right rail was a separate vertical column. Neither gave a
coherent home for view switching, tool actions, and file operations.
**Before:** File tabs in a strip at the top; download/close/view buttons
in a separate vertical column on the right.
**After:**
- Always visible bar across the top.
- Left: Viewer / Active Files view switcher (hidden when no files are
open).
- Centre: Tool-specific action buttons (the same buttons that previously
lived in the right rail), plus zoom controls when in viewer mode.
- Right: Print (viewer only), Close (closes the current file in viewer
mode, closes all files in file editor mode), Download, Save As.
- Adapts to narrow widths by wrapping into two rows.
---
### 4. Viewer — active file never loses track after tool operations
**Why:** After running a tool on a file, the viewer would sometimes jump
to showing a different file.
**Before:** The "active file index" and "active file ID" were tracked as
two separate pieces of state that could desync when files were reordered
after a tool ran.
**After:** The index is always derived from the ID, so they can never
disagree. The viewer stays on the correct file after any operation.
### 5. Auto-navigate after file upload
**Before:** After uploading files via the modal, the user was left on
whatever view was active — no automatic navigation.
**After:** Single file uploaded → navigates to viewer. Multiple files
uploaded → navigates to Active Files.
---
### 6. Run button shows loading progress while files are still loading
**Why:** Opening a tool immediately after uploading many files could
silently skip files that hadn't finished loading yet.
**Before:** Run button was enabled immediately; files still being loaded
from storage were silently skipped.
**After:** While files are loading, the run button is replaced with a
disabled progress indicator. For multiple pending files it shows "2 / 5
files loading…". Once all files are ready, the button becomes active.
---
### 7. Bulk delete in file manager
**Why:** Deleting many files at once was slow and caused visible flicker
as each file was removed one by one.
**Before:** Each selected file went through the full single-delete flow
sequentially.
**After:** Local files are deleted in a single batch operation — one UI
update, one IndexedDB transaction. Server-connected files still go
through the sequential flow since each may need a confirmation prompt.
---
### 8. Deselecting a dirty file in the modal no longer removes it from
the workbench
**Before:** Deselecting a file in the file manager and clicking "Open"
would remove it from the workbench even if it had unsaved changes.
**After:** Files with unsaved changes are skipped when removing
deselected files.
---
### 9. File manager — "Close all files" button
**Before:** With nothing selected in the file manager, the "Open File"
button was disabled.
**After:** When nothing is selected but files are open, the button
changes to "Close all files" and becomes enabled.
---
### 10. File picker — search and hover thumbnails
**Before:** No way to filter the file list in the picker dropdown. No
visual preview.
**After:** Search input filters files by name. Hovering a row shows a
thumbnail preview.
---
### 11. Pan and ruler modes are now mutually exclusive
**Before:** Enabling the pan tool while the ruler was active left the
ruler in a broken state, and vice versa.
**After:** Activating either tool automatically deactivates the other.
---
### 12. Tool icons switched to outline style
All tool icons in the picker are now the outline variant instead of the
filled/solid variant, for a lighter, more consistent look.
---
### 13. Settings — language and theme options added to General settings
Language and theme (light/dark) controls are now available in Settings →
General.
---
## Test Script
---
### Sidebar and file management
1. **Sidebar toggle:** Confirm the left sidebar strip is visible on
load. Click expand — confirm the file list appears. Click collapse —
confirm it shrinks back to the strip.
2. **Upload and see files:** Upload 3 PDFs. Confirm all three appear in
the sidebar list without needing to open any modal.
3. **Sidebar search:** Type part of a filename in the sidebar search
box. Confirm the list filters. Clear it — confirm all files return.
4. **Toggle files on workbench from sidebar:** Click a file in the
sidebar that isn't on the workbench — confirm it opens. Click it again —
confirm it closes.
5. **Save prompt via sidebar:** Open a file in the viewer and make a
change (e.g. annotate). Click that file in the sidebar to close it —
confirm the unsaved-changes save prompt appears.
6. **Thumbnail on hover:** Hover a file row in the sidebar — confirm a
thumbnail preview appears.
7. **Currently viewed file pinned:** With multiple files open, confirm
the one you're viewing is highlighted at the top of the sidebar list.
8. **Sidebar reflects deletions:** Delete a file via the file manager
modal. Confirm the sidebar updates automatically without a page reload.
---
### Workbench bar
9. **No files state:** With no files open, confirm the workbench bar is
visible but no view tabs are shown.
10. **View tabs appear:** Upload a file — confirm "Viewer" and "Active
Files" tabs appear. Switch between them.
11. **Close button behaviour:** In Active Files with multiple files,
click Close — confirm all files close. Open a single file in viewer
mode, click Close — confirm only that file closes.
12. **Download:** Open a file in the viewer, click Download — confirm
the file saves.
13. **Zoom controls in viewer:** Confirm zoom in/out and a slider appear
in the bar's centre when in viewer mode. Drag the slider — confirm the
PDF zooms live. Switch to Active Files — confirm the controls disappear.
---
### Tool panel
14. **Collapse/expand:** Collapse the tool panel. Confirm a narrow strip
remains (not blank space). Click the expand icon — panel opens. Collapse
again, click the search icon — confirm the panel opens with the search
field already focused.
15. **Back button in tool:** Open a tool (e.g. Compress). Confirm the
search bar icon changes to a back arrow. Click it — confirm you return
to the tool list.
16. **Viewer tool mini bar:** Open a PDF in the viewer. Confirm a mini
toolbar appears at the top of the panel with viewer-specific buttons
(annotate, redact, form fill, etc.). Switch to Active Files — confirm it
disappears.
---
### Running tools with files loading
17. **Loading indicator on run button:** Upload 5+ PDFs and immediately
open a tool (e.g. Compress or Merge). If files are still loading,
confirm the run button shows a loading progress indicator and is
disabled. Wait until loading finishes — confirm the button becomes
active.
---
### Viewer correctness
18. **Active file stays put after tool run:** Open 3 PDFs. Navigate to
file #2 in the viewer. Run a tool (e.g. rotate) on file #2. Confirm the
viewer stays on file #2 after the operation completes.
19. **Pan / ruler mutual exclusion:** Open a PDF. Enable pan. Enable the
ruler — confirm pan turns off. Re-enable pan — confirm the ruler turns
off.
---
### File manager
20. **Bulk delete:** Open the file manager, select 3+ local files, click
Delete Selected. Confirm all disappear in one go with no flicker, and
the sidebar updates.
21. **Dirty file not removed on deselect:** Open a PDF, make a change.
Open the file manager, deselect that file, click Open. Confirm the file
is still on the workbench.
22. **Close all from modal:** Have files open. Open the file manager,
deselect everything — confirm the button changes to "Close all files".
Click it — confirm all files close.
---
### File picker (inside tools)
23. **Search in picker:** Open a tool with a file picker (e.g. Merge,
Compare). Open the picker dropdown. Type a partial name — confirm the
list filters. Hover a row — confirm a thumbnail appears.
---
### Other flows
24. **Auto-navigate after upload:** Upload a single PDF via the modal —
confirm you land in the viewer. Upload multiple at once — confirm you
land in Active Files.
25. **Landscape PDF aspect ratio:** Upload a landscape PDF. In Active
Files view, confirm its thumbnail card is wider than tall.
26. **Compare tool clear label:** Open the Compare tool. Click to clear
the selection. Confirm the confirm button reads "Clear Selected".
27. **Settings — language and theme:** Open Settings → General. Confirm
Language and Theme controls exist. Toggle theme — confirm it switches.
28. **Tool icons:** Open the tool picker and confirm all tool icons use
the outline/unfilled style.
<img width="2056" height="1077" alt="Screenshot 2026-04-14 at 5 08
36 PM"
src="https://github.com/user-attachments/assets/b68243cb-70f6-4aac-b4e8-76ca6c617be2"
/>
<img width="2056" height="1080" alt="Screenshot 2026-04-14 at 5 08
51 PM"
src="https://github.com/user-attachments/assets/b3c1525b-6f30-4abc-b85a-ce2368e376c7"
/>
<img width="2056" height="1081" alt="Screenshot 2026-04-14 at 5 09
10 PM"
src="https://github.com/user-attachments/assets/894bb5a4-dd4b-49ae-a7da-2ee343c6c656"
/>
<img width="2056" height="1080" alt="Screenshot 2026-04-14 at 5 09
31 PM"
src="https://github.com/user-attachments/assets/9d4dd1e4-026d-4736-891d-0ae6647318d4"
/>
# Description of Changes
Redesign AI engine so that it autogenerates the `tool_models.py` file
from the OpenAPI spec so the Python has access to the Java API
parameters and the full list of Java tools that it can run. CI ensures
that whenever someone modifies a tool endpoint that the AI enigne tool
models get updated as well (the dev gets told to run `task
engine:tool-models`).
There's loads of advantages to having the Java be the one that actually
executes the tools, rather than the frontend as it was previously set up
to theoretically use:
- The AI gets much better descriptions of the params from the API docs
- It'll be usable headless in the future so a Java daemon could run to
execute ops on files in a folder without the need for the UI to run
- The Java already has all the logic it needs to execute the tools
- We don't need to parse the TypeScript to find the API (which is hard
because the TS wasn't designed to be computer-read to extract the API)
I've also hooked up the prototype frontend to ensure it's working
properly, and have built it in a way that all the tool names can be
translated properly, which was always an issue with previous prototypes
of this.
---------
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
Co-authored-by: EthanHealy01 <80844253+EthanHealy01@users.noreply.github.com>
# Description of Changes
Follow on from #5949, expanding any type usage ban to the `desktop/`
folder
Also gets rid of a bunch of really verbose desktop logging that I don't
think we really need anymore (or ever needed tbh, most of it doesn't
make sense) because it was using a bunch of `any` typing and wasn't
worth fixing.
# Description of Changes
When I added Prettier formatting in #6052, my aim was to use just the
default settings in Prettier. Turns out, Prettier looks _really hard_
for any config files if it's not explicitly given one, which means that
if a developer has some sort of Prettier config file lying around on
their system, Prettier might find it and use it. Also, Prettier changes
its defaults based on stuff in `.editorconfig` without any good way of
disabling that behaviour explicitly in its config file.
To solve both of these issues, I've introduced a `.prettierrc` file
which sets Prettier's defaults explicitly, and then reformatted all our
code _again_ in Prettier's actual default settings. This should achieve
the aim of #6052 and remove the possibility for it breaking on different
dev computers.
# Description of Changes
Adds a streaming endpoint to the Java AI orchestrator
(`/api/v1/ai/orchestrate/stream` in addition to the existing
`/api/v1/ai/orchestrate`). This allows the caller to get updates of what
stage of orchestration is being run at the time so UIs can give the user
feedback.
Also contains some dubious Gradle changes to suppress errors coming from
Spotless, when it crashes in Google stuff. I'm not sure if that's
appropriate to add, feel free to ask for changes in review.
## Add Taskfile for unified dev workflow
### Summary
- Introduces [Taskfile](https://taskfile.dev/) as the single CLI entry
point for all development workflows across backend, frontend, engine,
Docker, and desktop
- ~80 tasks organized into 6 namespaces: `backend:`, `frontend:`,
`engine:`, `docker:`, `desktop:`, plus root-level composites
- All CI workflows migrated to use Task
- Deletes `engine/Makefile` and `scripts/build-tauri-jlink.{sh,bat}` —
replaced by Task equivalents
- Removes redundant npm scripts (`dev`, `build`, `prep`, `lint`, `test`,
`typecheck:all`) from `package.json`
- Smart dependency caching: `sources`/`status`/`generates`
fingerprinting, CI-aware `npm ci` vs `npm install`, `run: once` for
parallel dep deduplication
### What this does NOT do
- Does not replace Gradle, npm, or Docker — Taskfile is a thin
orchestration wrapper
- Does not change application code or behavior
### Install
```
npm install -g @go-task/cli # or: brew install go-task, winget install Task.Task
```
### Quick start
```
task --list # discover all tasks
task install # install all deps
task dev # start backend + frontend
task dev:all # also start AI engine
task test # run all tests
task check # quick quality gate (local dev)
task check:all # full CI quality gate
```
### Test plan
- [ ] Install `task` CLI and run `task --list` — verify all tasks
display
- [ ] Run `task install` — verify frontend + engine deps install
- [ ] Run `task dev` — verify backend + frontend start, Ctrl+C exits
cleanly
- [ ] Run `task frontend:check` — verify typecheck + lint + test pass
- [ ] Run `task desktop:dev` — verify jlink builds are cached on second
run
- [ ] Verify CI passes on all workflows
---------
Co-authored-by: James Brunton <jbrunton96@gmail.com>
# Changes
1. Files are no longer selected/deselected, they're just on the
workbench or not.
2. Compare tool logic was changed to accommodate the changes in file
selection
3. Added a re-usable file selector component that allows you to select
files from the workbench / saved files / upload files and used it in the
compare tool.
<img width="2056" height="1081" alt="Screenshot 2026-04-10 at 5 28
07 PM"
src="https://github.com/user-attachments/assets/e04f1c0e-91fc-4564-a6f1-b9b992ca4f70"
/>
3. Files on active files are cleaner looking, on hover shows buttons,
tool runs, versions
<img width="325" height="378" alt="Screenshot 2026-04-10 at 4 56 52 PM"
src="https://github.com/user-attachments/assets/d29d88fe-2c72-4c5f-9650-1376085bcff6"
/>
<img width="286" height="363" alt="Screenshot 2026-04-10 at 4 57 05 PM"
src="https://github.com/user-attachments/assets/387c1709-de22-4cc8-b658-9f4c9f192af1"
/>
# How to test
## Compare tool
1. Open the Compare tool with no files on the workbench
3. Click the Original PDF picker → confirm the popover opens with Saved
Files and Workbench tabs
5. Switch to Saved Files, pick a file → confirm it appears as a card but
does not appear in the workbench file list
6. Pick a second file for Edited PDF → confirm the Compare button
becomes active
7. Hit Compare → confirm results appear in the workbench view
8. Hit Swap → confirm a re-run is triggered and results update correctly
9. Use the upload button → confirm a thumbnail appears on the card
immediately
10. Clear selected → confirm both slots reset and the workbench view
closes
## FileSelectorPicker
1. Open either slot picker and switch between Saved Files / Workbench
tabs — confirm the active tab is remembered when you open the other
slot's picker
3. Sort by A–Z then reopen — confirm sort preference persists
4. Upload a PDF via the Upload tab button — confirm thumbnail shows in
the card, file appears in Saved Files on next open
5. With a file in the other slot, confirm it is hidden from both tab
lists (excludeIds)
## File editor
1. Load 3+ files, run any tool (e.g. Compress) — confirm it runs on all
files without needing to select any
2. Confirm Close All removes all files from the workbench