paperclip/server/src/services
Devin Foley 3264f9c1f6
Fix typing lag in long comment threads (PAPA-63) (#3163)
## 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>
2026-04-08 17:54:03 -07:00
..
access.ts Remove api trigger kind and mark webhook as coming soon 2026-03-20 06:54:03 -05:00
activity-log.ts Add username log censor setting 2026-03-20 08:50:00 -05:00
activity.ts refactor: rename packages to @paperclipai and CLI binary to paperclipai 2026-03-03 08:45:26 -06:00
adapter-plugin-store.ts feat(adapters): external adapter plugin system with dynamic UI parser 2026-04-03 21:11:20 +01:00
agent-instructions.ts chore: mark bootstrapPromptTemplate as deprecated 2026-03-26 11:12:25 -05:00
agent-permissions.ts Implement agent hiring, approval workflows, config revisions, LLM reflection, and sidebar badges 2026-02-19 13:02:41 -06:00
agents.ts Stabilize onboarding e2e cleanup paths 2026-04-07 18:20:35 -05:00
approvals.ts Add username log censor setting 2026-03-20 08:50:00 -05:00
assets.ts refactor: rename packages to @paperclipai and CLI binary to paperclipai 2026-03-03 08:45:26 -06:00
board-auth.ts Address Greptile review on board CLI auth 2026-03-23 08:46:05 -05:00
budgets.ts Fix budget incident resolution edge cases 2026-03-16 16:48:13 -05:00
companies.ts Stabilize onboarding e2e cleanup paths 2026-04-07 18:20:35 -05:00
company-export-readme.ts fix: link Agent Company to agentcompanies.io in export README 2026-03-20 08:06:04 -05:00
company-portability.ts fix(export): strip project env values from company packages 2026-04-07 06:32:52 -05:00
company-skills.ts Merge pull request #2441 from DanielSousa/skill-removal-ui 2026-04-07 21:51:51 -05:00
costs.ts Fix budget auth and monthly spend rollups 2026-03-16 15:41:48 -05:00
cron.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
dashboard.ts feat(costs): add billing, quota, and budget control plane 2026-03-16 15:11:01 -05:00
default-agent-instructions.ts Add default agent instructions bundle 2026-03-20 07:42:36 -05:00
documents.ts Add feedback voting and thumbs capture flow 2026-04-02 09:11:49 -05:00
execution-workspace-policy.ts fix: address latest Greptile runtime review 2026-03-23 19:43:50 -05:00
execution-workspaces.ts Fix workspace runtime state reconciliation 2026-04-04 17:48:54 -05:00
feedback-redaction.ts Add feedback voting and thumbs capture flow 2026-04-02 09:11:49 -05:00
feedback-share-client.ts Restore feedback trace export fixes 2026-04-03 15:59:42 -05:00
feedback.ts Restore feedback trace export fixes 2026-04-03 15:59:42 -05:00
finance.ts feat(costs): add billing, quota, and budget control plane 2026-03-16 15:11:01 -05:00
github-fetch.ts fix: harden GHE URL detection and extract shared GitHub helpers 2026-04-01 21:05:48 +00:00
goals.ts Improve onboarding defaults and issue goal fallback 2026-03-12 08:50:31 -05:00
heartbeat-run-summary.ts feat(adapters): external adapter plugin system with dynamic UI parser 2026-04-03 21:11:20 +01:00
heartbeat.ts Fix typing lag in long comment threads (PAPA-63) (#3163) 2026-04-08 17:54:03 -07:00
hire-hook.ts fix(adapters): honor paused overrides and isolate UI parser state 2026-04-04 14:04:33 -05:00
index.ts Add feedback voting and thumbs capture flow 2026-04-02 09:11:49 -05:00
instance-settings.ts feat(inbox): add operator search and keyboard controls 2026-04-02 11:45:15 -05:00
issue-approvals.ts refactor: rename packages to @paperclipai and CLI binary to paperclipai 2026-03-03 08:45:26 -06:00
issue-assignment-wakeup.ts fix: close remaining routine merge blockers 2026-03-20 16:40:27 -05:00
issue-execution-policy.ts fix execution policy decision persistence 2026-04-07 17:43:10 -05:00
issue-goal-fallback.ts Seed onboarding project and issue goal context 2026-03-24 11:48:59 -05:00
issues.ts Merge pull request #2643 from chrisschwer/fix/stale-execution-lock-lifecycle 2026-04-07 22:55:53 -05:00
live-events.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
local-service-supervisor.ts Fix workspace runtime state reconciliation 2026-04-04 17:48:54 -05:00
plugin-capability-validator.ts Add plugin telemetry bridge capability 2026-04-02 10:47:29 -05:00
plugin-config-validator.ts Refactor secret-ref format registration to use a UI hint for Paperclip secret UUIDs 2026-03-14 15:43:56 -07:00
plugin-dev-watcher.ts Tighten plugin dev file watching 2026-03-14 12:07:04 -05:00
plugin-event-bus.ts Simplify plugin runtime and cleanup lifecycle 2026-03-13 16:58:29 -05:00
plugin-host-service-cleanup.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-host-services.ts feat(adapters): external adapter plugin system with dynamic UI parser 2026-04-03 21:11:20 +01:00
plugin-job-coordinator.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-job-scheduler.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-job-store.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-lifecycle.ts Simplify plugin runtime and cleanup lifecycle 2026-03-13 16:58:29 -05:00
plugin-loader.ts Enhance plugin loading and toolbar integration 2026-03-14 15:27:45 -07:00
plugin-log-retention.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-manifest-validator.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-registry.ts Simplify plugin runtime and cleanup lifecycle 2026-03-13 16:58:29 -05:00
plugin-runtime-sandbox.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-secrets-handler.ts Simplify plugin runtime and cleanup lifecycle 2026-03-13 16:58:29 -05:00
plugin-state-store.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-stream-bus.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-tool-dispatcher.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-tool-registry.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-worker-manager.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
project-workspace-runtime-config.ts Add workspace runtime controls 2026-03-29 10:55:26 -05:00
projects.ts Fix workspace runtime state reconciliation 2026-04-04 17:48:54 -05:00
quota-windows.ts feat(costs): add billing, quota, and budget control plane 2026-03-16 15:11:01 -05:00
routines.ts fix(server): use Buffer.length for timing-safe HMAC comparison and document header fallback 2026-04-06 16:26:27 -03:00
run-log-store.ts fix(server): use home-based path for run logs instead of cwd 2026-03-07 16:18:14 -08:00
secrets.ts Add project-level environment variables 2026-04-06 21:23:30 -05:00
sidebar-badges.ts Add touched/unread inbox issue semantics 2026-03-06 08:21:03 -06:00
work-products.ts Address remaining Greptile workspace review 2026-03-17 10:12:44 -05:00
workspace-operation-log-store.ts Add workspace operation tracking and fix project properties JSX 2026-03-17 09:36:35 -05:00
workspace-operations.ts Add username log censor setting 2026-03-20 08:50:00 -05:00
workspace-runtime-read-model.ts Fix workspace runtime state reconciliation 2026-04-04 17:48:54 -05:00
workspace-runtime.ts Limit isolated workspace memory spikes 2026-04-06 21:23:21 -05:00