## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies.
> - The heartbeat runtime, agent import path, and agent configuration
defaults determine whether work is dispatched safely and predictably.
> - Several accumulated fixes all touched agent execution recovery, wake
routing, import behavior, and runtime concurrency defaults.
> - Those changes need to land together so the heartbeat service and
agent creation defaults stay internally consistent.
> - This pull request groups the runtime/governance changes from the
split branch into one standalone branch.
> - The benefit is safer recovery for stranded runs, bounded high-volume
reads, imported-agent approval correctness, skill-template support, and
a clearer default concurrency policy.
## What Changed
- Fixed stranded continuation recovery so successful automatic retries
are requeued instead of incorrectly blocking the issue.
- Bounded high-volume issue/log reads across issue, heartbeat, agent,
project, and workspace paths.
- Fixed imported-agent approval and instruction-path permission
handling.
- Quarantined seeded worktree execution state during worktree
provisioning.
- Queued approval follow-up wakes and hardened SQL_ASCII heartbeat
output handling.
- Added reusable agent instruction templates for hiring flows.
- Set the default max concurrent agent runs to five and updated related
UI/tests/docs.
## Verification
- `pnpm install --frozen-lockfile`
- `pnpm exec vitest run server/src/__tests__/company-portability.test.ts
server/src/__tests__/heartbeat-process-recovery.test.ts
server/src/__tests__/heartbeat-comment-wake-batching.test.ts
server/src/__tests__/heartbeat-list.test.ts
server/src/__tests__/issues-service.test.ts
server/src/__tests__/agent-permissions-routes.test.ts
packages/adapter-utils/src/server-utils.test.ts
ui/src/lib/new-agent-runtime-config.test.ts`
- Split integration check: merged this branch first, followed by the
other [PAP-1614](/PAP/issues/PAP-1614) branches, with no merge
conflicts.
- Confirmed this branch does not include `pnpm-lock.yaml`.
## Risks
- Medium risk: touches heartbeat recovery, queueing, and issue list
bounds in central runtime paths.
- Imported-agent and concurrency default behavior changes may affect
existing automation that assumes one-at-a-time default runs.
- No database migrations are included.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
- OpenAI Codex, GPT-5.4 tool-enabled coding model, agentic
code-editing/runtime with local shell and GitHub CLI access; exact
context window and reasoning mode are not exposed by the Paperclip
harness.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] 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>
## Thinking Path
> - Paperclip operators spend much of their time in issues, inboxes,
selectors, and rich comment threads.
> - Small interaction problems in those surfaces slow down supervision
of AI-agent work.
> - The branch included related operator quality-of-life fixes for issue
layout, inbox actions, recent selectors, mobile inputs, and chat
rendering stability.
> - These changes are UI-focused and can land independently from
workspace navigation and access-profile work.
> - This pull request groups the operator QoL fixes into one standalone
branch.
> - The benefit is a more stable and efficient board workflow for issue
triage and task editing.
## What Changed
- Widened issue detail content and added a desktop inbox archive action.
- Fixed mobile text-field zoom by keeping touch input font sizes at
16px.
- Prioritized recent picker selections for assignees/projects in issue
and routine flows.
- Showed actionable approvals in the Mine inbox model.
- Fixed issue chat renderer state crashes and hardened tests.
## Verification
- `pnpm install --frozen-lockfile`
- `pnpm exec vitest run ui/src/components/IssueChatThread.test.tsx
ui/src/lib/inbox.test.ts ui/src/lib/recent-selections.test.ts`
- Split integration check: merged last after the other
[PAP-1614](/PAP/issues/PAP-1614) branches with no merge conflicts.
- Confirmed this branch does not include `pnpm-lock.yaml`.
## Risks
- Low to medium risk: mostly UI state, layout, and selection-priority
behavior.
- Visual layout and mobile zoom behavior may need browser/device QA
beyond component tests.
- No database migrations are included.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
- OpenAI Codex, GPT-5.4 tool-enabled coding model, agentic
code-editing/runtime with local shell and GitHub CLI access; exact
context window and reasoning mode are not exposed by the Paperclip
harness.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] 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: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip agents do real work in project and execution workspaces.
> - Operators need workspace state to be visible, navigable, and
copyable without digging through raw run logs.
> - The branch included related workspace cards, navigation, runtime
controls, stale-service handling, and issue-property visibility.
> - These changes share the workspace UI and runtime-control surfaces
and can stand alone from unrelated access/profile work.
> - This pull request groups the workspace experience changes into one
standalone branch.
> - The benefit is a clearer workspace overview, better metadata copy
flows, and more accurate runtime service controls.
## What Changed
- Polished project workspace summary cards and made workspace metadata
copyable.
- Added a workspace navigation overview and extracted reusable project
workspace content.
- Squared and polished the execution workspace configuration page.
- Fixed stale workspace command matching and hid stopped stale services
in runtime controls.
- Showed live workspace service context in issue properties.
## Verification
- `pnpm install --frozen-lockfile`
- `pnpm exec vitest run
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/lib/project-workspaces-tab.test.ts
ui/src/components/Sidebar.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/components/IssueProperties.test.tsx`
- `pnpm exec vitest run packages/shared/src/workspace-commands.test.ts
--config /dev/null` because the root Vitest project config does not
currently include `packages/shared` tests.
- Split integration check: merged after runtime/governance,
dev-infra/backups, and access/profiles with no merge conflicts.
- Confirmed this branch does not include `pnpm-lock.yaml`.
## Risks
- Medium risk: touches workspace navigation, runtime controls, and issue
property rendering.
- Visual layout changes may need browser QA, especially around smaller
screens and dense workspace metadata.
- No database migrations are included.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
- OpenAI Codex, GPT-5.4 tool-enabled coding model, agentic
code-editing/runtime with local shell and GitHub CLI access; exact
context window and reasoning mode are not exposed by the Paperclip
harness.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] 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>
## Thinking Path
> - Paperclip is moving from a solo local operator model toward teams
supervising AI-agent companies.
> - Human access management and human-visible profile surfaces are part
of that multiple-user path.
> - The branch included related access cleanup, archived-member removal,
permission protection, and a user profile page.
> - These changes share company membership, user attribution, and
access-service behavior.
> - This pull request groups those human access/profile changes into one
standalone branch.
> - The benefit is safer member removal behavior and a first profile
surface for user work, activity, and cost attribution.
## What Changed
- Added archived company member removal support across shared contracts,
server routes/services, and UI.
- Protected company member removal with stricter permission checks and
tests.
- Added company user profile API, shared types, route wiring, client
API, route, and UI page.
- Simplified the user profile page visual design to a neutral
typography-led layout.
## Verification
- `pnpm install --frozen-lockfile`
- `pnpm exec vitest run server/src/__tests__/access-service.test.ts
server/src/__tests__/user-profile-routes.test.ts
ui/src/pages/CompanyAccess.test.tsx --hookTimeout=30000`
- `pnpm exec vitest run server/src/__tests__/user-profile-routes.test.ts
--testTimeout=30000 --hookTimeout=30000` after an initial local
embedded-Postgres hook timeout in the combined run.
- Split integration check: merged after runtime/governance and
dev-infra/backups with no merge conflicts.
- Confirmed this branch does not include `pnpm-lock.yaml`.
## Risks
- Medium risk: changes member removal permissions and adds a new user
profile route with cross-table stats.
- The profile page is a new UI surface and may need visual follow-up in
browser QA.
- No database migrations are included.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
- OpenAI Codex, GPT-5.4 tool-enabled coding model, agentic
code-editing/runtime with local shell and GitHub CLI access; exact
context window and reasoning mode are not exposed by the Paperclip
harness.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] 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>
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies.
> - Heartbeat runs are the control-plane record of each agent execution
window.
> - Long-running local agents can exhaust context or stop while still
holding useful next-step state.
> - Operators need that stop reason, next action, and continuation path
to be durable and visible.
> - This pull request adds run liveness metadata, continuation
summaries, and UI surfaces for issue run ledgers.
> - The benefit is that interrupted or long-running work can resume with
clearer context instead of losing the agent's last useful handoff.
## What Changed
- Added heartbeat-run liveness fields, continuation attempt tracking,
and an idempotent `0058` migration.
- Added server services and tests for run liveness, continuation
summaries, stop metadata, and activity backfill.
- Wired local and HTTP adapters to surface continuation/liveness context
through shared adapter utilities.
- Added shared constants, validators, and heartbeat types for liveness
continuation state.
- Added issue-detail UI surfaces for continuation handoffs and the run
ledger, with component tests.
- Updated agent runtime docs, heartbeat protocol docs, prompt guidance,
onboarding assets, and skills instructions to explain continuation
behavior.
- Addressed Greptile feedback by scoping document evidence by run,
excluding system continuation-summary documents from liveness evidence,
importing shared liveness types, surfacing hidden ledger run counts,
documenting bounded retry behavior, and moving run-ledger liveness
backfill off the request path.
## Verification
- `pnpm exec vitest run packages/adapter-utils/src/server-utils.test.ts
server/src/__tests__/run-continuations.test.ts
server/src/__tests__/run-liveness.test.ts
server/src/__tests__/activity-service.test.ts
server/src/__tests__/documents-service.test.ts
server/src/__tests__/issue-continuation-summary.test.ts
server/src/services/heartbeat-stop-metadata.test.ts
ui/src/components/IssueRunLedger.test.tsx
ui/src/components/IssueContinuationHandoff.test.tsx
ui/src/components/IssueDocumentsSection.test.tsx`
- `pnpm --filter @paperclipai/db build`
- `pnpm exec vitest run server/src/__tests__/activity-service.test.ts
ui/src/components/IssueRunLedger.test.tsx`
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm --filter @paperclipai/server typecheck`
- `pnpm exec vitest run server/src/__tests__/activity-service.test.ts
server/src/__tests__/run-continuations.test.ts
ui/src/components/IssueRunLedger.test.tsx`
- `pnpm exec vitest run
server/src/__tests__/heartbeat-process-recovery.test.ts -t "treats a
plan document update"`
- `pnpm exec vitest run server/src/__tests__/activity-service.test.ts
server/src/__tests__/heartbeat-process-recovery.test.ts -t "activity
service|treats a plan document update"`
- Remote PR checks on head `e53b1a1d`: `verify`, `e2e`, `policy`, and
Snyk all passed.
- Confirmed `public-gh/master` is an ancestor of this branch after
fetching `public-gh master`.
- Confirmed `pnpm-lock.yaml` is not included in the branch diff.
- Confirmed migration `0058_wealthy_starbolt.sql` is ordered after
`0057` and uses `IF NOT EXISTS` guards for repeat application.
- Greptile inline review threads are resolved.
## Risks
- Medium risk: this touches heartbeat execution, liveness recovery,
activity rendering, issue routes, shared contracts, docs, and UI.
- Migration risk is mitigated by additive columns/indexes and idempotent
guards.
- Run-ledger liveness backfill is now asynchronous, so the first ledger
response can briefly show historical missing liveness until the
background backfill completes.
- UI screenshot coverage is not included in this packaging pass;
validation is currently through focused component tests.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
- OpenAI Codex, GPT-5.4, local tool-use coding agent with terminal, git,
GitHub connector, GitHub CLI, and Paperclip API access.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] 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
Screenshot note: no before/after screenshots were captured in this PR
packaging pass; the UI changes are covered by focused component tests
listed above.
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip is the control plane for autonomous AI companies.
> - V1 needs to stay local-first while also supporting shared,
authenticated deployments.
> - Human operators need real identities, company membership, invite
flows, profile surfaces, and company-scoped access controls.
> - Agents and operators also need the existing issue, inbox, workspace,
approval, and plugin flows to keep working under those authenticated
boundaries.
> - This branch accumulated the multi-user implementation, follow-up QA
fixes, workspace/runtime refinements, invite UX improvements,
release-branch conflict resolution, and review hardening.
> - This pull request consolidates that branch onto the current `master`
branch as a single reviewable PR.
> - The benefit is a complete multi-user implementation path with tests
and docs carried forward without dropping existing branch work.
## What Changed
- Added authenticated human-user access surfaces: auth/session routes,
company user directory, profile settings, company access/member
management, join requests, and invite management.
- Added invite creation, invite landing, onboarding, logo/branding,
invite grants, deduped join requests, and authenticated multi-user E2E
coverage.
- Tightened company-scoped and instance-admin authorization across
board, plugin, adapter, access, issue, and workspace routes.
- Added profile-image URL validation hardening, avatar preservation on
name-only profile updates, and join-request uniqueness migration cleanup
for pending human requests.
- Added an atomic member role/status/grants update path so Company
Access saves no longer leave partially updated permissions.
- Improved issue chat, inbox, assignee identity rendering,
sidebar/account/company navigation, workspace routing, and execution
workspace reuse behavior for multi-user operation.
- Added and updated server/UI tests covering auth, invites, membership,
issue workspace inheritance, plugin authz, inbox/chat behavior, and
multi-user flows.
- Merged current `public-gh/master` into this branch, resolved all
conflicts, and verified no `pnpm-lock.yaml` change is included in this
PR diff.
## Verification
- `pnpm exec vitest run server/src/__tests__/issues-service.test.ts
ui/src/components/IssueChatThread.test.tsx ui/src/pages/Inbox.test.tsx`
- `pnpm run preflight:workspace-links && pnpm exec vitest run
server/src/__tests__/plugin-routes-authz.test.ts`
- `pnpm exec vitest run server/src/__tests__/plugin-routes-authz.test.ts
server/src/__tests__/workspace-runtime-service-authz.test.ts
server/src/__tests__/access-validators.test.ts`
- `pnpm exec vitest run
server/src/__tests__/authz-company-access.test.ts
server/src/__tests__/routines-routes.test.ts
server/src/__tests__/sidebar-preferences-routes.test.ts
server/src/__tests__/approval-routes-idempotency.test.ts
server/src/__tests__/openclaw-invite-prompt-route.test.ts
server/src/__tests__/agent-cross-tenant-authz-routes.test.ts
server/src/__tests__/routines-e2e.test.ts`
- `pnpm exec vitest run server/src/__tests__/auth-routes.test.ts
ui/src/pages/CompanyAccess.test.tsx`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/db typecheck && pnpm --filter @paperclipai/server
typecheck`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/server typecheck`
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm db:generate`
- `npx playwright test --config tests/e2e/playwright.config.ts --list`
- Confirmed branch has no uncommitted changes and is `0` commits behind
`public-gh/master` before PR creation.
- Confirmed no `pnpm-lock.yaml` change is staged or present in the PR
diff.
## Risks
- High review surface area: this PR contains the accumulated multi-user
branch plus follow-up fixes, so reviewers should focus especially on
company-boundary enforcement and authenticated-vs-local deployment
behavior.
- UI behavior changed across invites, inbox, issue chat, access
settings, and sidebar navigation; no browser screenshots are included in
this branch-consolidation PR.
- Plugin install, upgrade, and lifecycle/config mutations now require
instance-admin access, which is intentional but may change expectations
for non-admin board users.
- A join-request dedupe migration rejects duplicate pending human
requests before creating unique indexes; deployments with unusual
historical duplicates should review the migration behavior.
- Company member role/status/grant saves now use a new combined
endpoint; older separate endpoints remain for compatibility.
- Full production build was not run locally in this heartbeat; CI should
cover the full matrix.
## Model Used
- OpenAI Codex coding agent, GPT-5-based model, CLI/tool-use
environment. Exact deployed model identifier and context window were not
exposed by the runtime.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] 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
Note on screenshots: this is a branch-consolidation PR for an
already-developed multi-user branch, and no browser screenshots were
captured during this heartbeat.
---------
Co-authored-by: dotta <dotta@example.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - The board depends on issue, inbox, cost, and company-skill surfaces
to stay accurate and fast while agents are actively working
> - The PAP-1497 follow-up branch exposed a few rough edges in those
surfaces: stale active-run state on completed issues, missing creator
filters, oversized issue payload scans, and placeholder issue-route
parsing
> - Those gaps make the control plane harder to trust because operators
can see misleading run state, miss the right subset of work, or pay
extra query/render cost on large issue records
> - This pull request tightens those follow-ups across server and UI
code, and adds regression coverage for the affected paths
> - The benefit is a more reliable issue workflow, safer high-volume
cost aggregation, and clearer board/operator navigation
## What Changed
- Added the `v2026.415.0` release changelog entry.
- Fixed stale issue-run presentation after completion and reused the
shared issue-path parser so literal route placeholders no longer become
issue links.
- Added creator filters to the Issues page and Inbox, including
persisted filter-state normalization and regression coverage.
- Bounded issue detail/list project-mention scans and trimmed large
issue-list payload fields to keep issue reads lighter.
- Hardened company-skill list projection and cost/finance aggregation so
large markdown blobs and large summed values do not leak into list
responses or overflow 32-bit casts.
- Added targeted server/UI regression tests for company skills,
costs/finance, issue mention scanning, creator filters, inbox
normalization, and issue reference parsing.
## Verification
- `pnpm exec vitest run
server/src/__tests__/company-skills-service.test.ts
server/src/__tests__/costs-service.test.ts
server/src/__tests__/issues-goal-context-routes.test.ts
server/src/__tests__/issues-service.test.ts ui/src/lib/inbox.test.ts
ui/src/lib/issue-filters.test.ts ui/src/lib/issue-reference.test.ts`
- `gh pr checks 3779`
Current pass set on the PR head: `policy`, `verify`, `e2e`,
`security/snyk (cryppadotta)`, `Greptile Review`
## Risks
- Creator filter options are derived from the currently loaded
issue/agent data, so very sparse result sets may not surface every
historical creator until they appear in the active dataset.
- Cost/finance aggregate casts now use `double precision`; that removes
the current overflow risk, but future schema changes should keep
large-value aggregation behavior under review.
- Issue detail mention scanning now skips comment-body scans on the
detail route, so any consumer that relied on comment-only project
mentions there would need to fetch them separately.
## Model Used
- OpenAI Codex, GPT-5-based coding agent with terminal tool use and
local code execution in the Paperclip workspace. Exact internal model
ID/context-window exposure is not surfaced in this session.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [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>
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - Operators rely on issue, inbox, and routine views to understand what
the company is doing in real time
> - Those views need to stay fast and readable even when issue lists,
markdown comments, and run metadata get large
> - The current branch had a coherent set of UI and live-update
improvements spread across issue search, issue detail rendering, routine
affordances, and workspace lookups
> - This pull request groups those board-facing changes into one
standalone branch that can merge independently of the heartbeat/runtime
work
> - The benefit is a faster, clearer issue and routine workflow without
changing the underlying task model
## What Changed
- Show routine execution issues by default and rename the filter to
`Hide routine runs` so the default state no longer looks like an active
filter.
- Show the routine name in the run dialog and tighten the issue
properties pane with a workspace link, copy-on-click behavior, and an
inline parent arrow.
- Reduce issue detail rerenders, keep queued issue chat mounted, improve
issues page search responsiveness, and speed up issues first paint.
- Add inbox "other search results", refresh visible issue runs after
status updates, and optimize workspace lookups through summary-mode
execution workspace queries.
- Improve markdown wrapping and scrolling behavior for long strings and
self-comment code blocks.
- Relax the markdown sanitizer assertion so the test still validates
safety after the new wrap-friendly inline styles.
## Verification
- `pnpm vitest run ui/src/components/IssuesList.test.tsx
ui/src/lib/inbox.test.ts ui/src/pages/Issues.test.tsx
ui/src/context/BreadcrumbContext.test.tsx
ui/src/context/LiveUpdatesProvider.test.ts
ui/src/components/MarkdownBody.test.tsx
ui/src/api/execution-workspaces.test.ts
server/src/__tests__/execution-workspaces-routes.test.ts`
## Risks
- This touches several issue-facing UI surfaces at once, so regressions
would most likely show up as stale rendering, search result mismatches,
or small markdown presentation differences.
- The workspace lookup optimization depends on the summary-mode route
shape staying aligned between server and UI.
## Model Used
- OpenAI Codex, GPT-5-based coding agent in the Codex CLI environment.
Exact backend model deployment ID was not exposed in-session.
Tool-assisted editing and shell execution were used.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [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>
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - Local development needs to work cleanly across linked git worktrees
because Paperclip itself leans on worktree-based engineering workflows
> - Dev-mode asset routing, Vite watch behavior, and workspace package
links are part of that day-to-day control-plane ergonomics
> - The current branch had a small but coherent set of
worktree/dev-tooling fixes that are independent from both the issue UI
changes and the heartbeat runtime changes
> - This pull request isolates those environment fixes into a standalone
branch that can merge without carrying unrelated product work
> - The benefit is a smoother multi-worktree developer loop with fewer
stale links and less noisy dev watching
## What Changed
- Serve dev public assets before the HTML shell and add a routing test
that locks that behavior in.
- Ignore UI test files in the Vite dev watch helper so the dev server
does less unnecessary work.
- Update `ensure-workspace-package-links.ts` to relink stale workspace
dependencies whenever a workspace `node_modules` directory exists,
instead of only inside linked-worktree detection paths.
## Verification
- `pnpm vitest run server/src/__tests__/app-vite-dev-routing.test.ts
ui/src/lib/vite-watch.test.ts`
- `node cli/node_modules/tsx/dist/cli.mjs
scripts/ensure-workspace-package-links.ts`
## Risks
- The asset routing change is low risk but sits near app shell behavior,
so a regression would show up as broken static assets in dev mode.
- The workspace-link repair now runs in more cases, so the main risk is
doing unexpected relinks when a checkout has intentionally unusual
workspace symlink state.
## Model Used
- OpenAI Codex, GPT-5-based coding agent in the Codex CLI environment.
Exact backend model deployment ID was not exposed in-session.
Tool-assisted editing and shell execution were used.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] 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
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - The web UI is a single-page app built with Vite and shipped as a
static bundle to every deployment
> - Production bundles carry `console.log` / `console.debug` calls from
dev code and `/*! … */` legal-comment banners from third-party packages
> - The console calls leak internals to anyone opening devtools and
waste bytes per call site; the legal banners accumulate throughout the
bundle
> - Both problems affect every self-hoster, since they all ship the same
UI bundle
> - This pull request configures esbuild (via `vite.config.ts`) to strip
`console` and `debugger` statements and drop inline legal comments from
production builds only
## What Changed
- `ui/vite.config.ts`:
- Switch to the functional `defineConfig(({ mode }) => …)` form.
- Add `build.minify: "esbuild"` (explicit — it's the existing default).
- Add `esbuild.drop: ["console", "debugger"]` and
`esbuild.legalComments: "none"`, gated on `mode === "production"` so
`vite dev` is unaffected.
## Verification
- `pnpm --filter @paperclipai/ui build` then grep the
`ui/dist/assets/*.js` bundle for `console.log` — no occurrences.
- `pnpm --filter @paperclipai/ui dev` — `console.log` calls in source
still reach the browser console.
- Bundle size: small reduction (varies with project but measurable on a
fresh build).
## Risks
Low. No API surface change. Production code should not depend on
`console.*` for side effects; any call that did is now a dead call,
which is the same behavior most minifiers apply.
## Model Used
Claude Opus 4.6 (1M context), extended thinking mode.
## Checklist
- [x] Thinking path traces from project context to this change
- [x] Model used specified
- [x] Tests run locally and pass
- [x] CI green
- [x] Greptile review addressed
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - Humans watch and oversee those agents through a web UI
> - Accessibility matters for anyone who cannot read small text
comfortably — they rely on browser zoom
> - The app shell's viewport meta tag includes `maximum-scale=1.0,
user-scalable=no`
> - Those tokens disable pinch-zoom and are a WCAG 2.1 SC 1.4.4 (Resize
Text) failure
> - The original motivation — suppressing iOS Safari's auto-zoom on
focused inputs — is actually a font-size issue, not a viewport issue,
and modern Safari only auto-zooms when input font-size is below 16px
> - This pull request drops the two tokens, restoring pinch-zoom while
leaving the real fix (inputs at ≥16px) to CSS
## What Changed
- `ui/index.html` — remove `maximum-scale=1.0, user-scalable=no` from
the viewport meta tag. Keep `width=device-width, initial-scale=1.0,
viewport-fit=cover`.
## Verification
- Manual on iOS and Chrome mobile: pinch-to-zoom now works across the
app.
- Manual on desktop: Ctrl+/- zoom already worked via
`initial-scale=1.0`; unchanged.
## Risks
Low. Users who were relying on auto-zoom-suppression for text inputs
will notice nothing (modern Safari only auto-zooms below 16px). No API
surface change.
## Model Used
Claude Opus 4.6 (1M context), extended thinking mode.
## Checklist
- [x] Thinking path traces from project context to this change
- [x] Model used specified
- [x] Tests run locally and pass
- [x] CI green
- [x] Greptile review addressed
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - The control plane depends on authenticated routes enforcing company
boundaries and role permissions correctly
> - This branch also touches the issue detail and markdown editing flows
operators use while handling advisory and triage work
> - Partial issue cache seeds and fragile rich-editor parsing could
leave important issue content missing or blank at the moment an operator
needed it
> - Blocked issues becoming actionable again should wake their assignee
automatically instead of silently staying idle
> - This pull request rebases the advisory follow-up branch onto current
`master`, hardens authenticated route authorization, and carries the
issue-detail/editor reliability fixes forward with regression tests
> - The benefit is tighter authz on sensitive routes plus more reliable
issue/advisory editing and wakeup behavior on top of the latest base
## What Changed
- Hardened authenticated route authorization across agent, activity,
approval, access, project, plugin, health, execution-workspace,
portability, and related server paths, with new cross-tenant and
runtime-authz regression coverage.
- Switched issue detail queries from `initialData` to placeholder-based
hydration so list/quicklook seeds still refetch full issue bodies.
- Normalized advisory-style HTML images before mounting the markdown
editor and strengthened fallback behavior when the rich editor silently
fails or rejects the content.
- Woke assigned agents when blocked issues move back to `todo`, with
route coverage for reopen and unblock transitions.
- Rebasing note: this branch now sits cleanly on top of the latest
`master` tip used for the PR base.
## Verification
- `pnpm exec vitest run ui/src/lib/issueDetailQuery.test.tsx
ui/src/components/MarkdownEditor.test.tsx
server/src/__tests__/issue-comment-reopen-routes.test.ts
server/src/__tests__/activity-routes.test.ts
server/src/__tests__/agent-cross-tenant-authz-routes.test.ts`
- Confirmed `pnpm-lock.yaml` is not part of the PR diff.
- Rebased the branch onto current `public-gh/master` before publishing.
## Risks
- Broad authz tightening may expose existing flows that were relying on
permissive board or agent access and now need explicit grants.
- Markdown editor fallback changes could affect focus or rendering in
edge-case content that mixes HTML-like advisory markup with normal
markdown.
- This verification was intentionally scoped to touched regressions and
did not run the full repository suite.
## Model Used
- OpenAI Codex, GPT-5-based coding agent in the Codex CLI environment
with tool use for terminal, git, and GitHub operations. The exact
runtime model identifier is not exposed inside this session.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, it is behavior-only and does not
need before/after screenshots
- [x] I have updated relevant documentation to reflect my changes, or no
documentation changes were needed for these internal fixes
- [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>
## Thinking Path
> - Paperclip orchestrates AI agents via adapters (`claude_local`,
`codex_local`, etc.)
> - Each adapter type has different capabilities — instructions bundles,
skill materialization, local JWT — but these were gated by 5 hardcoded
type lists scattered across server routes and UI components
> - External adapter plugins (e.g. a future `opencode_k8s`) cannot add
themselves to those hardcoded lists without patching Paperclip source
> - The existing `supportsLocalAgentJwt` field on `ServerAdapterModule`
proves the right pattern already exists; it just wasn't applied to the
other capability gates
> - This pull request replaces the 4 remaining hardcoded lists with
declarative capability flags on `ServerAdapterModule`, exposed through
the adapter listing API
> - The benefit is that external adapter plugins can now declare their
own capabilities without any changes to Paperclip source code
## What Changed
- **`packages/adapter-utils/src/types.ts`** — added optional capability
fields to `ServerAdapterModule`: `supportsInstructionsBundle`,
`instructionsPathKey`, `requiresMaterializedRuntimeSkills`
- **`server/src/routes/agents.ts`** — replaced
`DEFAULT_MANAGED_INSTRUCTIONS_ADAPTER_TYPES` and
`ADAPTERS_REQUIRING_MATERIALIZED_RUNTIME_SKILLS` hardcoded sets with
capability-aware helper functions that fall back to the legacy sets for
adapters that don't set flags
- **`server/src/routes/adapters.ts`** — `GET /api/adapters` now includes
a `capabilities` object per adapter (all four flags + derived
`supportsSkills`)
- **`server/src/adapters/registry.ts`** — all built-in adapters
(`claude_local`, `codex_local`, `process`, `cursor`) now declare flags
explicitly
- **`ui/src/adapters/use-adapter-capabilities.ts`** — new hook that
fetches adapter capabilities from the API
- **`ui/src/pages/AgentDetail.tsx`** — replaced hardcoded `isLocal`
allowlist with `capabilities.supportsInstructionsBundle` from the API
- **`ui/src/components/AgentConfigForm.tsx`** /
**`OnboardingWizard.tsx`** — replaced `NONLOCAL_TYPES` denylist with
capability-based checks
- **`server/src/__tests__/adapter-registry.test.ts`** /
**`adapter-routes.test.ts`** — tests covering flag exposure,
undefined-when-unset, and per-adapter values
- **`docs/adapters/creating-an-adapter.md`** — new "Capability Flags"
section documenting all flags and an example for external plugin authors
## Verification
- Run `pnpm test --filter=@paperclip/server -- adapter-registry
adapter-routes` — all new tests pass
- Run `pnpm test --filter=@paperclip/adapter-utils` — existing tests
still pass
- Spin up dev server, open an agent with `claude_local` type —
instructions bundle tab still visible
- Create/open an agent with a non-local type — instructions bundle tab
still hidden
- Call `GET /api/adapters` and verify each adapter includes a
`capabilities` object with the correct flags
## Risks
- **Low risk overall** — all new flags are optional with
backwards-compatible fallbacks to the existing hardcoded sets; no
adapter behaviour changes unless a flag is explicitly set
- Adapters that do not declare flags continue to use the legacy lists,
so there is no regression risk for built-in adapters
- The UI capability hook adds one API call to AgentDetail mount; this is
a pre-existing endpoint, so no new latency path is introduced
## Model Used
- Provider: Anthropic
- Model: Claude Sonnet 4.6 (`claude-sonnet-4-6`)
- Context: 200k token context window
- Mode: Agentic tool use (code editing, bash, grep, file reads)
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [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: Pawla Abdul (Bot) <pawla@groombook.dev>
Co-authored-by: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - Reliable execution depends on heartbeat routing, issue lifecycle
semantics, telemetry, and a fast enough local verification loop to keep
regressions visible
> - The remaining commits on this branch were mostly server/runtime
correctness fixes plus test and documentation follow-ups in that area
> - Those changes are logically separate from the UI-focused
issue-detail and workspace/navigation branches even when they touch
overlapping issue APIs
> - This pull request groups the execution reliability, heartbeat,
telemetry, and tooling changes into one standalone branch
> - The benefit is a focused review of the control-plane correctness
work, including the follow-up fix that restored the implicit
comment-reopen helpers after branch splitting
## What Changed
- Hardened issue/heartbeat execution behavior, including self-review
stage skipping, deferred mention wakes during active execution, stranded
execution recovery, active-run scoping, assignee resolution, and
blocked-to-todo wake resumption
- Reduced noisy polling/logging overhead by trimming issue run payloads,
compacting persisted run logs, silencing high-volume request logs, and
capping heartbeat-run queries in dashboard/inbox surfaces
- Expanded telemetry and status semantics with adapter/model fields on
task completion plus clearer status guidance in docs/onboarding material
- Updated test infrastructure and verification defaults with faster
route-test module isolation, cheaper default `pnpm test`, e2e isolation
from local state, and repo verification follow-ups
- Included docs/release housekeeping from the branch and added a small
follow-up commit restoring the implicit comment-reopen helpers that were
dropped during branch reconstruction
## Verification
- `pnpm vitest run
server/src/__tests__/issue-comment-reopen-routes.test.ts
server/src/__tests__/issue-telemetry-routes.test.ts`
- `pnpm vitest run server/src/__tests__/http-log-policy.test.ts
server/src/__tests__/heartbeat-run-log.test.ts
server/src/__tests__/health.test.ts`
- `server/src/__tests__/activity-service.test.ts`,
`server/src/__tests__/heartbeat-comment-wake-batching.test.ts`, and
`server/src/__tests__/heartbeat-process-recovery.test.ts` were attempted
on this host but the embedded Postgres harness reported
init-script/data-dir problems and skipped or failed to start, so they
are noted as environment-limited
## Risks
- Medium: this branch changes core issue/heartbeat routing and
reopen/wakeup behavior, so regressions would affect agent execution flow
rather than isolated UI polish
- Because it also updates verification infrastructure, reviewers should
pay attention to whether the new tests are asserting the right failure
modes and not just reshaping harness behavior
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] 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>
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] 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>
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - A core part of that is the operator experience around reading issue
state, agent chat, and sub-task structure
> - The current branch had a long run of issue-detail and issue-list UX
fixes that all improve how humans follow and steer active work
> - Those changes mostly live in the UI/chat surface and should be
reviewed together instead of mixed with workspace/runtime work
> - This pull request packages the issue-detail, chat, markdown, and
sub-issue list improvements into one standalone change
> - The benefit is a cleaner, less jumpy, more reliable issue workflow
on desktop and mobile without coupling it to unrelated server/runtime
refactors
## What Changed
- Stabilized issue chat runtime wiring, optimistic comment handling,
queued-comment cancellation, and composer anchoring during live updates
- Fixed several issue-detail rendering and navigation regressions
including placeholder bleed, local polling scope, mobile inbox-to-issue
transitions, and visible refresh resets
- Improved markdown and rich-content handling with advisory image
normalization, editor fallback behavior, touch mention recovery, and
`issue:` quicklook links
- Refined sub-issue behavior with parent-derived defaults, current-user
inheritance fixes, empty-state cleanup, and a reusable issue-list
presentation for sub-issues
- Added targeted UI tests for the new issue-detail, chat scroll/message,
placeholder-data, markdown, and issue-list behaviors
## Verification
- `pnpm vitest run ui/src/components/IssueChatThread.test.tsx
ui/src/components/MarkdownEditor.test.tsx
ui/src/components/IssuesList.test.tsx
ui/src/context/LiveUpdatesProvider.test.tsx
ui/src/lib/issue-chat-messages.test.ts
ui/src/lib/issue-chat-scroll.test.ts
ui/src/lib/issue-detail-subissues.test.ts
ui/src/lib/query-placeholder-data.test.tsx
ui/src/hooks/usePaperclipIssueRuntime.test.tsx`
## Risks
- Medium: this branch touches the highest-traffic issue-detail UI paths,
so regressions would show up as chat/thread or sub-issue UX glitches
- The changes are UI-heavy and would benefit from reviewer screenshots
or a quick manual browser pass before merge
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [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
- [ ] 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>
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies.
> - Board users and agents collaborate on issue-scoped documents such as
plans and revisions need to be trustworthy because they are the audit
trail for those artifacts.
> - The issue document UI now supports revision history and restore, so
the UI has to distinguish the current revision from historical revisions
correctly even while multiple queries are refreshing.
> - In `PAPA-72`, the newest content could appear under an older
revision label because the current document snapshot and the
revision-history query could temporarily disagree after an edit.
> - That made the UI treat the newest revision like a historical restore
target, which is the opposite of the intended behavior.
> - This pull request derives one authoritative revision view from both
sources, sorts revisions newest-first, and keeps the freshest revision
marked current.
> - The benefit is that revision history stays stable and trustworthy
immediately after edits instead of briefly presenting the newest content
as an older revision.
## What Changed
- Added a `document-revisions` helper that merges the current document
snapshot with fetched revision history into one normalized revision
state.
- Updated `IssueDocumentsSection` to render from that normalized state
instead of trusting either query in isolation.
- Added focused tests covering the current-revision selection and
ordering behavior.
## Verification
- `pnpm -r typecheck`
- `pnpm build`
- Targeted revision tests passed locally.
- Manual reviewer check:
- Open an issue document with revision history.
- Edit and save the document.
- Immediately open the revision selector.
- Confirm the newest revision remains marked current and older revisions
remain the restore targets.
## Risks
- Low risk. The change is isolated to issue document revision
presentation in the UI.
- Main risk is merging the current snapshot with fetched history
incorrectly for edge cases, which is why the helper has focused unit
coverage.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [ ] 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
Agent configuration edits already had an API path for replacing the full adapterConfig, but the edit form was still sending merge-style patches. That meant clearing the last environment variable serialized as undefined, the key disappeared from JSON, and the server merged the old env bindings back into the saved config.
Build adapter config save payloads as full replacement patches, strip undefined keys before send, and reuse the existing replaceAdapterConfig contract so explicit clears persist correctly. Add regression coverage for the cleared-env case and for adapter-type changes that still need to preserve adapter-agnostic fields.
Fixes#3179
Shows a beautiful categorized cheatsheet of all keyboard shortcuts
(inbox, issue detail, global) when the user presses ? with keyboard
shortcuts enabled. Respects text input focus detection — won't trigger
in text fields. Uses the existing Dialog component and Radix UI.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Use createHistoricalTranscriptMessage for failed/cancelled/timed_out
runs even before transcript data loads. This prevents the flash where
a plain "run X failed" status line transforms into a foldable "failed
after X minutes" header when transcripts arrive asynchronously.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Move child indentation from wrapper paddingLeft into desktopMetaLeading
so the unread dot stays in the leftmost column regardless of nesting
depth. When nesting is enabled, all issue rows get a fixed-width folding
column (chevron or empty spacer) for consistent alignment. Children
indent after the folding column. When nesting is disabled, no folding
column is rendered.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Builds a flat navigation list that includes expanded child issues alongside
top-level items, so j/k moves through every visible row including children.
Also adds the NavEntry type and updates archive/read/enter actions to work
with both top-level work items and nested child issues.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Adds a ListTree icon button in the inbox top bar to toggle nesting
on/off. Preference is persisted in localStorage. When disabled, all
issues display as a flat list without grouping.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Groups child issues under their parent in the inbox, matching the
nesting pattern used on the issues list page. Parent groups sort by
the most recent activity across all family members. Archived parents
don't hide their children — orphans show independently.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Eliminates two visual glitches when a new agent run starts:
1. The initial "Working..." was rendered as plain text without the shimmer
animation or agent icon — now matches the proper working state styling.
2. A brief blank flash occurred when transcript chunks arrived but hadn't
produced parseable parts yet — fixed by deriving waitingText from parts
availability instead of the hasOutput flag.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Replace useEffect with synchronous state derivation during render so
the browser never paints the unfolded intermediate state. This prevents
the visible "jump" when loading an issue page with already-completed
work sections like "worked for 4 minutes".
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The sweep now completes at 60% of the cycle and holds for the
remaining 40%, giving a ~1s pause before repeating. Total cycle
duration increased from 1.5s to 2.5s.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The shimmer keyframes animated from -100% to 200%, pushing the gradient
fully off-screen at both extremes. On loop restart the text flashed
invisible for a frame. Changed to 100%→0% so the gradient always
overlaps the visible area — both endpoints show solid base-color text
and the highlight sweeps smoothly through without discontinuity.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The handleChatImageClick useCallback (and its dependencies) was defined
after conditional early returns, violating React's rules of hooks and
causing "Rendered more hooks than during the previous render" crashes.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Clicking an image in a chat message now opens the same ImageGalleryModal
used by the attachments gallery. Matches by contentPath or assetId.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
--foreground is defined as oklch(), not HSL channels. Wrapping it in
hsl() produced an invalid color, making the shimmer text invisible.
Use var(--foreground) directly and color-mix() for the highlight band.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Rework the shimmer-text CSS to use a Cursor-style sweep: full-opacity base
with a narrow transparent highlight band that slides across, linear timing,
tighter background-size. Add a "Status tokens" section to the Issue Chat UX
Lab showing both the active shimmer "Working" state and the static "Worked"
state side-by-side for quick visual review.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
When there are no blocking issues or sub-issues, show nothing (or just the
"+ Add sub-issue" button) instead of displaying "None" text.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Clicking the worktree name in the banner now copies it to clipboard
and shows "Copied\!" feedback for 1.5 seconds.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Adds two new groupBy options on the issues page: "Workspace" groups
issues by their projectWorkspaceId, and "Parent Issue" groups by
parentId. Groups with items sort first; sentinel groups (No Workspace /
No Parent) appear last. Creating a new issue from a parent group
pre-fills parentId.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - The issue detail page displays comment threads with rich timeline
rendering
> - Long threads (100+ items) cause severe typing lag in the comment
composer because every keystroke re-renders the entire timeline
> - CDP tracing confirmed 110ms avg key→paint latency and 60 long tasks
blocking the main thread for 3.7s total
> - This pull request memoizes the timeline, stabilizes callback props,
debounces editor observers, and reduces idle polling frequency
> - The benefit is responsive typing (21ms avg, 5.3× faster) even on
threads with 100+ timeline items
## What Changed
- **CommentThread.tsx**: Memoize `TimelineList` with `useMemo` so typing
state changes don't re-render 143 timeline items; extract
`handleFeedbackVote` to `useCallback`; added missing deps
(`pendingApprovalAction`, `onApproveApproval`, `onRejectApproval`) to
useMemo array
- **IssueDetail.tsx**: Extract inline callbacks (`handleCommentAdd`,
`handleCommentVote`, `handleCommentImageUpload`,
`handleCommentAttachImage`, `handleInterruptQueued`) to `useCallback`
with `.mutateAsync` deps (not full mutation objects) for stable
references; add conditional polling intervals (3s active / 30s idle) for
`liveRuns`, `activeRun`, `linkedRuns`, and timeline queries
- **MarkdownEditor.tsx**: Debounce `MutationObserver` and
`selectionchange` handlers via `requestAnimationFrame` coalescing
- **LiveRunWidget.tsx**: Accept optional `liveRunsData` and
`activeRunData` props to reuse parent-fetched data instead of duplicate
polling
## Verification
- Navigated to [IP address]:3105/PAPA/issues/PAPA-32 (thread with 100+
items)
- Typed in comment composer — lag eliminated, characters appear
instantly
- CDP trace test script (`test-typing-lag.mjs`) confirmed: avg 21ms
key→paint (was 110ms), 5 long tasks (was 60), 0.5s blocking (was 3.7s)
- Ran `pnpm test:run` locally — all tests pass
## Risks
- Low risk. All changes are additive memoization and callback
stabilization — no behavioral changes. Polling intervals are only
reduced for idle state; active runs still poll at 3–5s.
## Model Used
- Claude Opus 4.6 (`claude-opus-4-6`) via Claude Code CLI, with tool use
and extended context
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] 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>
Replace single retentionDays with a three-tier BackupRetentionPolicy:
- Daily: keep all backups (presets: 3, 7, 14 days; default 7)
- Weekly: keep one per calendar week (presets: 1, 2, 4 weeks; default 4)
- Monthly: keep one per calendar month (presets: 1, 3, 6 months; default 1)
Pruning sorts backups newest-first and applies each tier's cutoff,
keeping only the newest entry per ISO week/month bucket. The Instance
Settings General page now shows three preset selectors (no icon, matches
existing page design). Remove Database icon import.
Compress database backups with gzip (.sql.gz), reducing file size ~83%.
Add backup retention configuration to Instance Settings UI with preset
options (7 days, 2 weeks, 1 month). The backup scheduler now reads
retention from the database on each tick so changes take effect without
restart. Default retention changed from 30 to 7 days.
Action bar for agent messages is now: [copy] [thumbs up] [thumbs down] [date] [three dots].
Date shows relative time (e.g. "2h ago") if < 1 week old, otherwise short date (e.g. "Apr 6").
Hovering the date shows full timestamp tooltip. Date links to the comment anchor.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Agent comment header now only shows name (+ running badge)
- Date, copy, thumbs up/down, and three-dots menu all in action bar
- Activity event STATUS/ASSIGNEE labels changed from text-[9px] to
text-xs to match value font size
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Replace absolute positioning (-right-8) with a flex row layout for the
"You" avatar. The avatar now sits naturally to the right of the bubble
via flex justify-end + gap-2.5, avoiding overflow clipping issues.
Max-width 85% is on the content column, not the bubble div, so the
bubble + avatar together fill the row naturally.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Use relative positioning with pr-8 reserved space and absolute
positioning for the avatar, so it sits outside the content column
boundary while the bubble's right edge aligns with the column edge.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Scale activity components (events, runs) to ~80% font size with
xs avatars for a quieter visual weight
- Hide succeeded runs from the timeline; only show failed/errored
- Always show three-dots menu on agent comments with "Copy message"
option, plus optional "View run" when available
- User avatar repositioned to top-right (items-start) of message
- Change "Me" → "You" in assignee labels for natural chat phrasing
("You updated this task")
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Agent messages: avatar outside left (matching feed items alignment),
always shown, consistently uses icon avatar instead of initials
- User messages: avatar outside right, action bar moved below the
gray bubble, gray darkened to bg-muted
- System events: right-aligned when actor is the current user
- Run messages: use agent icon avatar consistently
- Pass actorType/actorId in event metadata for current-user detection
Co-Authored-By: Paperclip <noreply@paperclip.ing>
User messages: right-aligned bubbles (85% max-width) with gray
background, no border. Hover reveals short date + copy icon.
Agent messages: borderless with avatar, name, date and three-dots
in header. Left-aligned action bar with icon-only copy, thumbs up,
and thumbs down. Thumbs down opens a floating popover for reason.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The IssueChatCtx.Provider was opened but never closed, causing the
context to not properly wrap the thread. This, combined with the
stable component references via context (already in place), ensures
OutputFeedbackButtons state is preserved across re-renders when
feedback votes update.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Strip the rounded border, padding, background gradient, and shadow
from ThreadPrimitive.Root so the chat thread flows naturally without
a bordered wrapper container.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Give the leading element of each row (the "For" text and the
Eye/ShieldCheck icons) a fixed w-6 width so all InlineEntitySelector
pills start at the same horizontal position.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Comment out non-functional Labels chip in new-issue bottom bar
- Remove reviewer/approver mini pills from bottom chip bar
- Add three-dot menu (⋯) next to Project selector in the "For/in" row
- Clicking Reviewer or Approver in that menu toggles a full-sized
participant selector row under Assignee, matching its styling
- Toggling off clears the selection
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The Upload button was missing the pill/chip styling (border, rounded-md,
padding) that all other buttons in the chip bar have. Apply the same
className pattern used by the Labels chip.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Per feedback: reviewer/approver pickers were incorrectly placed in the
issue header row. This moves them back to the Properties sidebar at
regular size and adds them as small chip-style selectors in the
new-issue dialog's bottom bar (next to Upload), matching the existing
chip styling.
- Restored Reviewers/Approvers PropertyPicker rows in IssueProperties
- Removed ExecutionParticipantPicker pills from IssueDetail header
- Added Eye/ShieldCheck-icon reviewer/approver InlineEntitySelectors
in NewIssueDialog chip bar after Upload button
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Extract execution participant pickers from sidebar PropertyPicker rows into
compact pill-style Popover triggers in the issue header row, next to labels.
Creates a reusable ExecutionParticipantPicker component with matching
text-[10px] sizing. Removes the old sidebar rows and unused code.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Adds a "parent" column option to the inbox column toggle dropdown.
When enabled, sub-issues display the parent's identifier (e.g. PAP-123)
with the parent title as a tooltip. Uses the existing issueById lookup
map to resolve parent info without additional API calls.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- When no sub-issues exist, show "Add sub-issue" button alongside
"Upload attachment" and "New document" in the action row
- When sub-issues exist, show them in a dedicated section above
Documents with "Sub-issues" header and "Add sub-issue" button
- Remove the sub-issues tab from the comments/activity tabs
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Image attachments now render in a 4-column grid with square aspect ratio
and center-cropped thumbnails. Clicking opens the existing gallery modal.
Hover reveals a trash icon; clicking it shows an inline confirmation
overlay before deleting. Non-image attachments retain the original list
layout.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
On desktop, the floating scroll-to-bottom button now shifts left
to stay clear of the properties panel when it's open (320px + margin).
Mobile positioning is unchanged.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The DialogContent base class applies sm:max-w-lg which was overriding
the wider max-w setting. Use \!important to ensure the modal takes up
90% of viewport width.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Long branch/folder paths now wrap with break-all instead of truncating
and overflowing. Copy icon is always visible instead of hover-only,
since the sidebar is narrow and hover-reveal was hiding it behind overflow.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Make modal much wider (90vw) to show full document content
- Use monospace font in diff area for better readability
- Enable word-wrap with pre-wrap so long lines wrap cleanly
without breaking line number gutters
- Move revision selectors into a single row with colored
Old/New badges instead of stacked Left:/Right: labels
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Add a "View diff" option to the document three-dot menu (visible when
revision > 1) that opens a modal showing side-by-side changes between
revisions using react-diff-viewer-continued. Defaults to comparing the
current revision with its predecessor, with dropdowns to select any two
revisions.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Adds a new workspace section to the IssueProperties sidebar that
displays branch name and folder path (cwd) from the execution
workspace. Both values have copy-to-clipboard buttons and truncated
display with full path on hover.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
On mobile, the search input, tab selector, and "Show / hide columns" button
were all crammed into one row causing horizontal overflow. Now:
- Search appears as a full-width row above the tabs on mobile
- "Show / hide columns" button is hidden on mobile (columns are desktop-only)
- Desktop layout is unchanged
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Add overflow-hidden to the outer container to prevent horizontal scroll
- Add min-w-0 to grid children so long monospace content in inputs
respects container width instead of expanding it
- Truncate the workspace name heading for long names
- Add min-w-0 to the header name container
Co-Authored-By: Paperclip <noreply@paperclip.ing>
When unchecking the "Inherit project workspace runtime config" checkbox,
if the runtime config field is empty, automatically populate it with the
inherited config value so the user has a starting point to edit from.
Existing values are preserved and never overwritten.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Reduce card padding on small screens (p-4 → p-4 sm:p-5)
- Reduce spacing between sections on mobile (space-y-4 sm:space-y-6)
- Scale heading text (text-xl sm:text-2xl)
- Truncate long description on mobile, show full on sm+
- Reduce textarea min-heights on mobile (sm: prefix for larger sizes)
- Stack linked issue cards vertically on mobile, horizontal scroll on sm+
- Remove min-width constraint on linked issue cards on mobile
Co-Authored-By: Paperclip <noreply@paperclip.ing>
When dragging files like .zip onto the issue description editor, non-image
files are now uploaded as attachments instead of being silently ignored.
Images continue to be handled inline by MDXEditor's image plugin.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The archive mutation was only using CSS opacity to hide items while the
network request was in flight. When the query refetch completed or the
archiving timer expired, the item could reappear. Now we optimistically
remove the item from React Query caches on mutate, snapshot previous
data for rollback on error, and sync with the server in onSettled.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
fixes https://github.com/paperclipai/paperclip/issues/2336
## Thinking Path
<!--
Required. Trace your reasoning from the top of the project down to this
specific change. Start with what Paperclip is, then narrow through the
subsystem, the problem, and why this PR exists. Use blockquote style.
Aim for 5–8 steps. See CONTRIBUTING.md for full examples.
-->
- Paperclip allows to manage projects
- During the project creation you can optionally enter a description
- In the project overview or configuration you can edit the description
- However, you cannot remove the description
- The user should be able to remove the project description because it's
an optional property
- This pull request fixes the frontend bug that prevented the user to
remove/clear the project description
## What Changed
<!-- Bullet list of concrete changes. One bullet per logical unit. -->
- project description can be cleared in "project configuration" and
"project overview"
## Verification
<!--
How can a reviewer confirm this works? Include test commands, manual
steps, or both. For UI changes, include before/after screenshots.
-->
In project configuration or project overview:
- In the description field remove/clear the text
## Risks
<!--
What could go wrong? Mention migration safety, breaking changes,
behavioral shifts, or "Low risk" if genuinely minor.
-->
- none
## 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
- [x] 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
Closes#2412
Related: #2681, #498, #128
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - The Claude Code adapter spawns the `claude` CLI to run agent tasks
> - The adapter detects auth mode by checking for `ANTHROPIC_API_KEY` —
recognizing only "api" and "subscription" modes
> - But users running Claude Code via **AWS Bedrock**
(`CLAUDE_CODE_USE_BEDROCK=1`) fall through to the "subscription" path
> - This causes a misleading "ANTHROPIC_API_KEY is not set;
subscription-based auth can be used" message in the environment check
> - Additionally, the hello probe passes `--model claude-opus-4-6` which
is **not a valid Bedrock model identifier**, causing `400 The provided
model identifier is invalid` and a probe failure
> - This pull request adds Bedrock auth detection, skips the
Anthropic-style `--model` flag for Bedrock, and returns the correct
billing type
> - The benefit is that Bedrock users get a working environment check
and correct cost tracking out of the box
---
## Pain Point
Many enterprise teams use **Claude Code through AWS Bedrock** rather
than Anthropic's direct API — for compliance, billing consolidation, or
VPC requirements. Currently, these users hit a **hard wall during
onboarding**:
| Problem | Impact |
|---|---|
| ❌ Adapter environment check **always fails** | Users cannot create
their first agent — blocked at step 1 |
| ❌ `--model claude-opus-4-6` is **invalid on Bedrock** (requires
`us.anthropic.*` format) | Hello probe exits with code 1: `400 The
provided model identifier is invalid` |
| ❌ Auth shown as _"subscription-based"_ | Misleading — Bedrock is
neither subscription nor API-key auth |
| ❌ Quota polling hits Anthropic OAuth endpoint | Fails silently for
Bedrock users who have no Anthropic subscription |
> **Bottom line**: Paperclip is completely unusable for Bedrock users
out of the box.
## Why Bedrock Matters
AWS Bedrock is a major deployment path for Claude in enterprise
environments:
- **Enterprise compliance** — data stays within the customer's AWS
account and VPC
- **Unified billing** — Claude usage appears on the existing AWS
invoice, no separate Anthropic billing
- **IAM integration** — access controlled through AWS IAM roles and
policies
- **Regional deployment** — models run in the customer's preferred AWS
region
Supporting Bedrock unlocks Paperclip for organizations that **cannot**
use Anthropic's direct API due to procurement, security, or regulatory
constraints.
---
## What Changed
- **`execute.ts`**: Added `isBedrockAuth()` helper that checks
`CLAUDE_CODE_USE_BEDROCK` and `ANTHROPIC_BEDROCK_BASE_URL` env vars.
`resolveClaudeBillingType()` now returns `"metered_api"` for Bedrock.
Biller set to `"aws_bedrock"`. Skips `--model` flag when Bedrock is
active (Anthropic-style model IDs are invalid on Bedrock; the CLI uses
its own configured model).
- **`test.ts`**: Environment check now detects Bedrock env vars (from
adapter config or server env) and shows `"AWS Bedrock auth detected.
Claude will use Bedrock for inference."` instead of the misleading
subscription message. Also skips `--model` in the hello probe for
Bedrock.
- **`quota.ts`**: Early return with `{ ok: true, windows: [] }` when
Bedrock is active — Bedrock usage is billed through AWS, not Anthropic's
subscription quota system.
- **`ui/src/lib/utils.ts`**: Added `"aws_bedrock"` → `"AWS Bedrock"` to
`providerDisplayName()` and `quotaSourceDisplayName()`.
## Verification
1. `pnpm -r typecheck` — all packages pass
2. Unit tests added and passing (6/6)
3. Environment check with Bedrock env vars:
| | Before | After |
|---|---|---|
| **Status** | 🔴 Failed | ✅ Passed |
| **Auth message** | `ANTHROPIC_API_KEY is not set; subscription-based
auth can be used if Claude is logged in.` | `AWS Bedrock auth detected.
Claude will use Bedrock for inference.` |
| **Hello probe** | `ERROR · Claude hello probe failed.` (exit code 1 —
`--model claude-opus-4-6` is invalid on Bedrock) | `INFO · Claude hello
probe succeeded.` |
| **Screenshot** | <img height="500" alt="Screenshot 2026-04-05 at 8 25
27 AM"
src="https://github.com/user-attachments/assets/476431f6-6139-425a-8abc-97875d653657"
/> | <img height="500" alt="Screenshot 2026-04-05 at 8 31 58 AM"
src="https://github.com/user-attachments/assets/d388ce87-c5e6-4574-b8d2-fd8b86135299"
/> |
4. Existing API key / subscription paths are completely untouched unless
Bedrock env vars are present
## Risks
- **Low risk.** All changes are additive — existing "api" and
"subscription" code paths are only entered when Bedrock env vars are
absent.
- When Bedrock is active, the `--model` flag is skipped, so the
Paperclip model dropdown selection is ignored in favor of the Claude
CLI's own model config. This is intentional since Bedrock requires
different model identifiers.
## Model Used
- Claude Opus 4.6 (`claude-opus-4-6`, 1M context window) via Claude Code
CLI
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] 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: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Adds two new webhook trigger signing modes for external provider
compatibility:
- github_hmac: accepts X-Hub-Signature-256 header with
HMAC-SHA256(secret, rawBody), no timestamp prefix. Compatible with
GitHub, Sentry, and services following the same standard.
- none: no authentication; the 24-char hex publicId in the URL acts
as the shared secret. For services that cannot add auth headers.
The replay window UI field is hidden when these modes are selected
since neither uses timestamp-based replay protection.
Closes#1892
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Export and Import buttons in CompanySettings used plain <a href>
anchors which bypass the router's company-prefix wrapper. The links
resolved to /company/export and /company/import instead of
/:prefix/company/export, showing a 'Company not found' error.
Replace both <a href> elements with <Link to> from @/lib/router, which
calls applyCompanyPrefix under the hood and correctly resolves to
/:prefix/company/{export,import} regardless of which company is active.
Fixes: #2910
The sidebar inbox badge was counting all "mine" issues (issues created
by or assigned to the user) instead of only unread ones. This caused
the badge to show a count (e.g. 14) even when the Unread tab was empty.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add childIssues to the useEffect dependency array so the Properties panel
is refreshed whenever the child issue list updates (e.g. an agent creates
or deletes a sub-task while the panel is open). Previously the panel kept
the snapshot from the initial render of the parent issue.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Address two Greptile review comments:
1. Collapsed parent badge now shows total descendant count at all depths
rather than direct-child count only. Add `countDescendants` utility to
issue-tree.ts (recursive, uses existing childMap) and replace
`children.length` with it in the titleSuffix badge.
2. Add a useEffect that prunes stale IDs from `collapsedParents` whenever
the issues prop changes. Deleted or reassigned issues previously left
orphan IDs in localStorage indefinitely; the effect filters to only IDs
that appear as a parentId in the current issue list and persists the
cleaned array via updateView.
Add four unit tests for countDescendants: leaf node, single-level,
multi-level, and unknown ID.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Extract the inline tree-building logic from IssuesList into a pure
`buildIssueTree` function in lib/issue-tree.ts so it can be unit tested.
Add six tests covering: flat lists, parent-child grouping, multi-level
nesting, orphaned sub-tasks promoted to root, empty input, and list
order preservation.
Add two tests to IssueRow.test.tsx covering the new titleSuffix prop:
renders inline after the title when provided, and renders cleanly when
omitted.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Move parent-task link out of the 2-column PropertyRow layout and into
a dedicated full-width section at the bottom of the panel, separated
by a Separator. Sub-tasks are listed in the same section when present.
Each item shows a StatusIcon aligned with the first line of wrapped
title text (items-start + mt-0.5 on the icon wrapper).
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Move collapsedParents from ephemeral useState into IssueViewState,
which is already serialised to localStorage under the scoped key.
Navigating away and back now restores the exact collapsed/expanded
state the user left the list in.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Replace the boolean isChild flag with a numeric depth counter.
Each depth level adds 16px left padding via inline style on the
wrapper div, so sub-tasks of sub-tasks (and deeper) are indented
proportionally rather than all aligning at the same level.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
When a parent issue is collapsed, its title is suffixed with
"(N sub-tasks)" so the count remains visible at a glance.
The suffix disappears when the parent is expanded.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The base IssueRow has sm:pl-1 which overrides pl-6 at sm+ breakpoints.
Adding sm:pl-7 ensures the indent is visible at all screen sizes.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Sub-tasks are now grouped under their parent issue in the list view.
Parent issues with children show a chevron to collapse/expand their subtasks.
Child issues are visually indented to indicate hierarchy.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Keep issue search local to the loaded list, defer heavy result updates, and memoize the rendered list body so typing stays responsive.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
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>
- 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>
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>
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>
- 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>
## 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>
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.
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
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.
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.
- 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)
- 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
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
- 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
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>
The openclaw_gateway adapter hardcodes the Paperclip API key path to
~/.openclaw/workspace/paperclip-claimed-api-key.json in buildWakeText().
In multi-agent OpenClaw deployments, each agent has its own workspace
with its own key file. The hardcoded path forces all agents to share
one key, breaking agent identity isolation.
Add a claimedApiKeyPath field to the adapter config (with UI input)
that allows operators to set a per-agent path. Falls back to the
current default when unset — zero behavior change for existing
deployments.
Fixes#930
On the Paused tab every visible agent is paused, so applying
opacity-50 to all of them is redundant and makes the whole view
dim. Skip the dimming when tab === "paused" in both list and org
chart views. Pass tab prop through to OrgTreeNode for consistency.
Long goal descriptions pushed the Create button below the viewport
with no way to scroll, making it impossible to submit the form. Add
overflow-y-auto and max-h-[50vh] to the description container so it
scrolls within the dialog while keeping the footer visible.
Closes#2631
Empty status columns took the same 260px width as populated ones,
wasting horizontal space and forcing unnecessary scrolling. Collapse
empty columns to 48px (showing only the status icon) and expand
them back when an issue is dragged over for drop targeting.
Closes#2279
Clearing the extra args field set the overlay value to undefined,
which gets dropped during object spread when building the PATCH
payload. The existing extraArgs from the agent config survived the
merge, making it impossible to clear the field. Use null so the
value explicitly overwrites the existing config entry.
Closes#2350
Paused agents were visually identical to active agents in both the
list view and org chart, making it hard to distinguish them at a
glance. Add opacity-50 to agent rows when pausedAt is set.
Closes#2199
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>
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>
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - The web UI includes an agent detail page with an Instructions tab
for editing agent prompts
> - The Instructions tab used `max-w-6xl` (1152px) to constrain its
two-panel layout (file tree + editor)
> - The floating Cancel/Save buttons used `float-right` at the full page
width, disconnecting them from the constrained content
> - This also left a large empty margin on the right side at wider
viewports
> - This pull request removes `max-w-6xl` so the flex layout fills
available width
> - The benefit is buttons now align with the content edge, and the
right margin is eliminated
## What Changed
- Removed `max-w-6xl` from the `PromptsTab` container in
`ui/src/pages/AgentDetail.tsx:1920`
- The file panel + editor flex layout now fills the available page width
naturally
## Verification
- Navigate to any agent's Instructions tab at a wide viewport (1920px+)
- Before: content stops at 1152px with a gap to the right; Cancel/Save
buttons float to the far edge
- After: content fills available width; Cancel/Save buttons sit flush
with the editor panel
## Risks
- Low risk — only removes a max-width constraint on a single tab's
container. Other tabs (Configuration, Skills, etc.) are unaffected.
## CI Note
The test failure in `feedback-service.test.ts:714` is **pre-existing**
and unrelated to this change. A PII redaction filter is incorrectly
treating a UUID segment (`5618-4783`) as a phone number, producing
`[REDACTED_PHONE]` in the expected UUID value.
## 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
- [x] 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>
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - The UI includes an inline markdown editor (MDXEditor) for editing
agent instruction files like AGENTS.md
> - The editor should render in monospace to match how markdown/code
files look in a text editor
> - The `AgentDetail.tsx` component already passes `font-mono` via
Tailwind's `contentClassName`, but it wasn't taking effect
> - Two CSS rules in `index.css` set `font-family: inherit`, which
overrode the Tailwind utility due to specificity/source order
> - This PR removes those overrides so `font-mono` applies correctly
> - The benefit is the markdown editor now renders in monospace
(Menlo/SF Mono), matching user expectations for code/config files
## What Changed
- Removed `font-family: inherit` from `.paperclip-mdxeditor
[class*="_placeholder_"]` in `ui/src/index.css`
- Removed `font-family: inherit` from `.paperclip-mdxeditor-content` in
`ui/src/index.css`
## Verification
- Navigate to any agent's Instructions tab in the Paperclip UI
- Confirm the markdown editor content renders in a monospace font
(Menlo/SF Mono)
- Visually verified by user on a live dev server
## Risks
- Low risk. Only removes two CSS declarations. Non-monospace editors are
unaffected since `font-mono` is only applied to agent instruction files
via `contentClassName` in `AgentDetail.tsx`.
## Screenshots
Before:
<img width="934" height="1228" alt="Screenshot 2026-04-02 at 10 46
06 PM"
src="https://github.com/user-attachments/assets/5d84f913-cbea-4206-9d41-3f283209c009"
/>
After:
<img width="1068" height="1324" alt="PNG image"
src="https://github.com/user-attachments/assets/2040e812-d9ca-4b37-b73b-ce05cf52168c"
/>
## 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
- [x] 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>