Commit graph

1868 commits

Author SHA1 Message Date
dotta
fe61e650c2 Avoid blur-save during mention selection
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 17:48:54 -05:00
dotta
c89349687f feat(ui): improve routines list and recent runs
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 17:48:54 -05:00
dotta
f515f2aa12 Fix workspace runtime state reconciliation
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 17:48:54 -05:00
dotta
5a9a2a9112 Fix mobile mention menu placement
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 17:48:54 -05:00
dotta
65818c3447 Guard closed isolated workspaces on issues
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 17:48:54 -05:00
dotta
4993b5338c Fix horizontal scroll overflow in close workspace modal
Root cause: CSS Grid items default to min-width:auto, allowing content
to push the dialog wider than the viewport on mobile.

- Add [&>*]:min-w-0 on DialogContent to prevent grid children from
  expanding beyond the container width
- Keep overflow-x-hidden as safety net
- Remove negative-margin sticky footer that extended beyond bounds
- Revert to standard DialogFooter without negative margins

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 17:48:54 -05:00
dotta
d3401c0518 Fix horizontal scroll overflow in close workspace modal
- Add overflow-x-hidden on DialogContent to prevent horizontal scroll
- Truncate long monospace text (branch names, base refs) in git status grid
- Add min-w-0 on grid cells to allow truncation within CSS grid
- Add overflow-hidden on git status card and repo root section
- Add max-w-full + overflow-x-auto on pre blocks for long commands

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 17:48:54 -05:00
dotta
dbb5f0c4a9 Unify all toggle switches into a single responsive ToggleSwitch component
Replaces 12+ inline toggle button implementations across the app with a
shared ToggleSwitch component that scales up on mobile for better touch
targets. Default size is h-6/w-10 on mobile, h-5/w-9 on desktop; "lg"
variant is h-7/w-12 on mobile, h-6/w-11 on desktop.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 17:48:54 -05:00
dotta
3d685335eb Add sign out button to instance general settings
Adds a sign out section at the bottom of the general settings page.
Uses authApi.signOut() and invalidates the session query to redirect
to the login page.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 17:48:54 -05:00
dotta
2615450afc Make close workspace modal responsive for mobile
- Reduce padding and text sizes on small screens (p-4/text-xs -> sm:p-6/sm:text-sm)
- Tighter spacing between sections on mobile (space-y-3 -> sm:space-y-4)
- Sticky footer so action buttons stay visible while scrolling
- Grid layout stays 2-col on all sizes for git status
- Add shrink-0 to loading spinner

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 17:48:54 -05:00
Dotta
35f2fc7230
Merge pull request #2218 from HenkDz/feat/external-adapter-phase1
feat(adapters): external adapter plugin system with dynamic UI parser
2026-04-04 17:45:19 -05:00
dotta
d9476abecb fix(adapters): honor paused overrides and isolate UI parser state
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-04 14:04:33 -05:00
Devin Foley
d202631016
fix: autoformat pasted markdown in inline editor (#2673)
## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies
> - The inline markdown editor (MarkdownEditor / MDXEditor) is used to
edit agent instructions, issue descriptions, and other content
> - When users paste agent instructions copied from terminals or
consoles, extra leading whitespace is uniformly added to every line
> - PR #2572 fixed markdown structure preservation on paste but did not
address the leading whitespace (dedent) problem
> - This pull request adds a Lexical paste normalization plugin that
strips common leading whitespace and normalizes line endings before
MDXEditor processes pasted content
> - The benefit is that pasted content from terminals/consoles renders
correctly without manual cleanup

## What Changed

- **`ui/src/lib/normalize-markdown.ts`** — Pure utility that computes
minimum common indentation across non-empty lines and strips it
(dedent), plus CRLF → LF normalization
- **`ui/src/lib/paste-normalization.ts`** — Lexical `PASTE_COMMAND`
plugin at `CRITICAL` priority that intercepts plain-text pastes,
normalizes the markdown, and re-dispatches cleaned content for MDXEditor
to process. Skips HTML-rich pastes.
- **`ui/src/components/MarkdownEditor.tsx`** — Registers the new plugin;
updates PR #2572's `handlePasteCapture` to use `normalizeMarkdown()`
(dedent + CRLF) instead of `normalizePastedMarkdown()` (CRLF only) for
the markdown-routing path
- **`ui/src/lib/paste-normalization.test.ts`** — 9 unit tests covering
dedent, CRLF normalization, mixed indent, empty lines, single-line
passthrough, and edge cases

## Verification

- `pnpm --dir ui exec vitest run src/lib/paste-normalization.test.ts` —
9 tests pass
- Manual: paste indented agent instructions from a terminal into any
inline markdown editor and confirm leading whitespace is stripped

## Risks

- Low risk. The plugin only activates for plain-text pastes (no HTML
clipboard data). HTML/rich pastes pass through unchanged. Single-line
pastes are not modified. The dedent logic is conservative — it only
strips whitespace common to all non-empty lines.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-04 11:21:27 -07:00
HenkDz
c6d2dc8b56 fix(ui): narrow overridePaused to boolean in AdapterManager spread 2026-04-04 17:08:53 +01:00
HenkDz
80b81459a7 Merge remote-tracking branch 'upstream/master' into feat/external-adapter-phase1 2026-04-04 14:33:48 +01:00
Dotta
a07237779b
Merge pull request #2735 from paperclipai/chore/update-v2026-403-0-release-notes
Update v2026.403.0 release notes
2026-04-04 07:50:33 -05:00
dotta
21dd6acb81 updated release notes 2026-04-04 07:44:23 -05:00
HenkDz
b81d765d2e feat: server-side override pause/resume for builtin adapter types
Replace the client-side-only override store with a real server-side
toggle. When a developer pauses the external override, the server swaps
ALL adapter behavior back to the builtin — execute handler, model listing,
config schema, detection — not just the UI parser.

Server changes:
- registry.ts: builtinFallbacks map + pausedOverrides set + setOverridePaused()
- routes/adapters.ts: PATCH /api/adapters/:type/override endpoint + overridePaused in list

UI changes:
- adapters.ts: setOverridePaused API method + overridePaused on AdapterInfo
- AdapterManager: overrideMutation calls server, instant feedback via invalidate()
- use-disabled-adapters.ts: reads adapter.overridePaused from server response

Removed:
- disabled-overrides-store.ts: no longer needed (server is the source of truth)

Note: already-running agent sessions keep the adapter they started with.
Only new sessions use the swapped adapter.
2026-04-04 13:17:21 +01:00
HenkDz
4efe018a8f fix(ui): external adapter UI parser can now override builtin parsers
Builtin adapter types (hermes_local, openclaw_gateway, etc.) could not
be overridden by external adapters on the UI side. The registry always
returned the built-in parser, ignoring the external ui-parser.js shipped
by packages like hermes-paperclip-adapter.

Changes:
- registry.ts: full override lifecycle with generation guard for stale loads
- disabled-overrides-store.ts: client-side override pause state with
  useSyncExternalStore reactivity (persisted to localStorage)
- use-disabled-adapters.ts: subscribe to override store changes
- AdapterManager.tsx: separate controls for override pause (client-side)
  vs menu visibility (server-side), virtual builtin rows with badges
- adapters.ts: allow reload/reinstall of builtin types when overridden
2026-04-04 12:40:39 +01:00
HenkDz
0651f48f6c fix(ui): move reinstall button to end — power, reload, remove, reinstall 2026-04-03 23:09:30 +01:00
HenkDz
01c05b5f1b fix(ui): remove loaded badge, order badges — source, icon, version, override, disabled 2026-04-03 22:58:04 +01:00
HenkDz
c36ea1de6f fix(ui): reorder adapter badges — always-present first, conditional last 2026-04-03 22:51:49 +01:00
HenkDz
3c4b8711ec fix(ui): remove title prop from Lucide icons (not supported in this version) 2026-04-03 22:38:38 +01:00
HenkDz
ef2cbb838f chore: add trailing newline to server/package.json 2026-04-03 22:37:33 +01:00
HenkDz
fb3aabb743 feat(adapters): add overriddenBuiltin flag to API and Adapter Manager UI
When an external plugin overrides a built-in adapter type, the
GET /api/adapters response now includes overriddenBuiltin: true. The
Adapter Manager shows an 'Overrides built-in' badge on such adapters.
2026-04-03 22:25:58 +01:00
HenkDz
2a2fa31a03 feat(adapters): allow external plugins to override built-in adapters
Previously external adapters matching a built-in type were skipped with
a warning. Now they override the built-in, so plugin developers can ship
improved versions of existing adapters (e.g. hermes-paperclip-adapter)
without removing the built-in fallback for users who haven't installed
the plugin.
2026-04-03 22:17:34 +01:00
Dotta
8adae848e4
Merge pull request #2675 from paperclipai/pap-feedback-trace-export-fixes
[codex] Restore feedback trace export fixes
2026-04-03 16:06:43 -05:00
dotta
00898e8194 Restore feedback trace export fixes 2026-04-03 15:59:42 -05:00
HenkDz
199a2178cf feat(ui): collapsible system_group block in transcript view
Batch consecutive system events into a single collapsible group
instead of rendering each as a separate warn-toned block. Shows
count in header, expands on click.
2026-04-03 21:52:36 +01:00
Dotta
ed95fc1dda
Merge pull request #2674 from paperclipai/fix/feedback-test-uuid-redaction
fix: use deterministic UUID in feedback-service test to avoid phone redaction
2026-04-03 15:21:26 -05:00
HenkDz
c757a07708 fix(adapters): stable sort order, npm/local icons, reinstall dialog, HMR polling on WSL
- Sort GET /api/adapters alphabetically by type (reload no longer shuffles)
- Show red Package icon for npm adapters, amber FolderOpen for local path
- Add reinstall confirmation dialog with current vs latest npm version
- Enable Vite polling when running on /mnt/ (WSL inotify doesn't work on NTFS)
2026-04-03 21:11:24 +01:00
HenkDz
acfd7c260a feat: add hermes_local session management and show provider/model in run details 2026-04-03 21:11:23 +01:00
HenkDz
388650afc7 fix: update tests for SchemaConfigFields and comingSoon logic
- registry.test: fallback now uses SchemaConfigFields, not ProcessConfigFields
- metadata.test: isEnabledAdapterType checks comingSoon first so
  intentionally withheld built-in adapters (process/http) stay disabled
2026-04-03 21:11:23 +01:00
HenkDz
d7a7bda209 chore: restore pnpm-lock.yaml to upstream/master
CI blocks lockfile changes in PRs — restore to match base.
2026-04-03 21:11:23 +01:00
HenkDz
47f3cdc1bb fix(ui): external adapter selection, config field placement, and transcript parser freshness
- Fix external adapters (hermes, droid) not auto-selected when
  navigating with ?adapterType= param — was using a stale
  module-level Set built before async adapter registration
- Move SchemaConfigFields to render after thinking effort (same
  visual area as Claude's chrome toggle) instead of bottom of
  config section
- Extract SelectField into its own component to fix React hooks
  order violation when schema fields change between renders
- Add onAdapterChange() subscription in registry.ts so
  registerUIAdapter() notifies components when dynamic parsers
  load, fixing stale parser for old runs
- Add parserTick to both RunTranscriptView and
  useLiveRunTranscripts to force recomputation on parser change
2026-04-03 21:11:22 +01:00
HenkDz
69a1593ff8 feat(adapters): declarative config-schema API and UI for plugin adapters
Cherry-picked from feat/externalize-hermes-adapter.
Resolved conflicts: kept Hermes as built-in on phase1 branch.
2026-04-03 21:11:22 +01:00
HenkDz
f884cbab78 fix(adapters): restore built-in Hermes and sync lockfile with server
Re-align phase1 with upstream: hermes_local ships via hermes-paperclip-adapter on the server and UI (hermes-local module). Fixes ERR_PNPM_OUTDATED_LOCKFILE from server/package.json missing a dep still present in the lockfile.

Add shared BUILTIN_ADAPTER_TYPES and skip external plugin registration when it would override a built-in type. Docs list Hermes as built-in; Droid remains the primary external example.

Made-with: Cursor
2026-04-03 21:11:21 +01:00
HenkDz
14d59da316 feat(adapters): external adapter plugin system with dynamic UI parser
- Plugin loader: install/reload/remove/reinstall external adapters
  from npm packages or local directories
- Plugin store persisted at ~/.paperclip/adapter-plugins.json
- Self-healing UI parser resolution with version caching
- UI: Adapter Manager page, dynamic loader, display registry
  with humanized names for unknown adapter types
- Dev watch: exclude adapter-plugins dir from tsx watcher
  to prevent mid-request server restarts during reinstall
- All consumer fallbacks use getAdapterLabel() for consistent display
- AdapterTypeDropdown uses controlled open state for proper close behavior
- Remove hermes-local from built-in UI (externalized to plugin)
- Add docs for external adapters and UI parser contract
2026-04-03 21:11:20 +01:00
Devin Foley
e13c3f7c6c fix: use deterministic UUID in feedback-service test to avoid phone redaction
The PII sanitizer's phone regex matches digit pairs like "4880-8614"
that span UUID segment boundaries. Random UUIDs occasionally produce
these patterns, causing flaky test failures where sourceRun.id gets
partially redacted as [REDACTED_PHONE].

Use a fixed hex-letter-heavy UUID for runId so no cross-boundary
digit sequence triggers the phone pattern.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 13:04:56 -07:00
Dotta
f8452a4520
Merge pull request #2657 from paperclipai/fix/inbox-last-activity-ordering
Add versioned telemetry events
2026-04-03 14:19:05 -05:00
dotta
68b2fe20bb Address Greptile telemetry review comments
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 14:11:11 -05:00
Devin Foley
aa256fee03
feat: add authenticated screenshot utility (#2622)
## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies
> - Agents sometimes need to capture UI screenshots for visual
verification of fixes
> - The Paperclip UI requires authentication, so headless browser
screenshots fail without auth
> - The CLI already stores a board token in `~/.paperclip/auth.json`
> - This pull request adds a Playwright-based screenshot script that
reads the board token and injects it as a Bearer header
> - The benefit is agents can now take authenticated screenshots of any
Paperclip UI page without storing email/password credentials

## What Changed

- Added `scripts/screenshot.cjs` — a Node.js script that:
  - Reads the board token from `~/.paperclip/auth.json`
- Launches Chromium via Playwright with the token as an `Authorization`
header
  - Navigates to the specified URL and saves a screenshot
  - Supports `--width`, `--height`, and `--wait` flags
- Accepts both full URLs and path-only shortcuts (e.g.,
`/PAPA/agents/cto/instructions`)

## Verification

```bash
node scripts/screenshot.cjs /PAPA/agents/cto/instructions /tmp/test.png --width 1920
```

Should produce an authenticated screenshot of the agent instructions
page.

## Risks

- Low risk — standalone utility script with no impact on the main
application. Requires Playwright (already a dev dependency) and a valid
board token in `~/.paperclip/auth.json`.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [ ] I have run tests locally and they pass
- [ ] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [ ] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-03 10:51:26 -07:00
馨冉
728fbdd199
Fix markdown paste handling in document editor (#2572)
Supersedes #2499.

## Thinking Path

1. **Project context**: Paperclip uses a markdown editor
(`MarkdownEditor`) for document editing. Users expect to paste
markdown-formatted text from external sources (like code editors, other
documents) and have it render correctly.

2. **Problem identification**: When users paste plain text containing
markdown syntax (e.g., `# Heading`, `- list item`), the editor was
treating it as plain text, resulting in raw markdown syntax being
displayed rather than formatted content.

3. **Root cause**: The default browser paste behavior doesn't recognize
markdown syntax in plain text. The editor needed to intercept paste
events and detect when the clipboard content looks like markdown.

4. **Solution design**: 
- Create a utility (`markdownPaste.ts`) to detect markdown patterns in
plain text
- Add a paste capture handler in `MarkdownEditor` that intercepts paste
events
- When markdown is detected, prevent default paste and use
`insertMarkdown` instead
   - Handle edge cases (code blocks, file pastes, HTML content)

## What

- Added `ui/src/lib/markdownPaste.ts`: Utility to detect markdown
patterns and normalize line endings
- Added `ui/src/lib/markdownPaste.test.ts`: Test coverage for markdown
detection
- Modified `ui/src/components/MarkdownEditor.tsx`: Added paste capture
handler to intercept and handle markdown paste

## Why

Users frequently copy markdown content from various sources (GitHub,
documentation, notes) and expect it to render correctly when pasted into
the editor. Without this fix, users see raw markdown syntax (e.g., `#
Title` instead of a formatted heading), which degrades the editing
experience.

## How to Verify

1. Open any document in Paperclip
2. Copy markdown text from an external source (e.g., `# Heading\n\n-
Item 1\n- Item 2`)
3. Paste into the editor
4. **Expected**: The content should render as formatted markdown
(heading + bullet list), not as plain text with markdown syntax

### Test Coverage

```bash
cd ui
npm test -- markdownPaste.test.ts
```

All tests should pass, including:
- Windows line ending normalization (`\r\n` → `\n`)
- Old-Mac line ending normalization (`\r` → `\n`)
- Markdown block detection (headings, lists, code fences, etc.)
- Plain text rejection (non-markdown content)

## Risks

1. **False positives**: Plain text containing markdown-like characters
(e.g., a paragraph starting with `#` as a hashtag) may be incorrectly
treated as markdown. The detection uses a heuristic that requires
block-level markdown patterns, which reduces but doesn't eliminate this
risk.

2. **Removed focus guard**: The previous implementation used
`isFocusedRef` to prevent `onChange` from firing during programmatic
`setMarkdown` calls. This guard was removed as part of refactoring. The
assumption is that MDXEditor does not fire `onChange` during
`setMarkdown`, but this should be monitored for unexpected parent update
loops.

3. **Clipboard compatibility**: The paste handler specifically looks for
`text/plain` content and ignores `text/html` (to preserve existing HTML
paste behavior). This means pasting from rich text editors that provide
both HTML and plain text will continue to use the HTML path, which may
or may not be the desired behavior.

---------

Co-authored-by: 馨冉 <xinxincui239@gmail.com>
2026-04-03 08:50:48 -07:00
dotta
9b3ad6e616 Fix telemetry test mocking in agent skill routes
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 09:43:58 -05:00
dotta
37b6ad42ea Add versioned telemetry events
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 09:25:00 -05:00
Dotta
2ac40aba56
Merge pull request #2645 from paperclipai/fix/feedback-row-run-link
fix(ui): tidy feedback actions and add v2026.403.0 changelog
2026-04-03 08:12:31 -05:00
dotta
8db0c7fd2f docs: add v2026.403.0 release changelog
Covers 183 commits since v2026.325.0 including execution workspaces,
inbox overhaul, telemetry, feedback/evals, document revisions,
GitHub Enterprise support, and numerous fixes.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 08:01:23 -05:00
dotta
993a3262f6 fix(ui): place run link in same row as feedback buttons, right-aligned
When a comment has both helpful/needswork feedback buttons and a run link,
the run link now appears right-aligned in the same row instead of a separate
section below. Comments with only a run link (no feedback buttons) still
show the run link in its own bordered row.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 08:01:23 -05:00
dotta
a13a67de54 fix(ui): style Don't allow button as outline in feedback modal
The "Don't allow" button in the feedback sharing preference modal
should be visually distinct from "Always allow" by using an outline
variant instead of the default solid primary style.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 08:01:23 -05:00
Dotta
422dd51a87
Merge pull request #2638 from paperclipai/fix/inbox-last-activity-ordering
fix(inbox): prefer canonical last activity
2026-04-03 07:27:46 -05:00