mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-23 00:53:38 +02:00
aed4478c81925891a6d87ac0da5b0e1aba7c183d
1478
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4c55f0d8da |
fix(inbox): hide external object summaries (#10020)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The inbox helps operators scan and act on tasks that need attention > - Inbox task rows currently include external-object summary markers alongside the core task information > - Those markers add a column of visual noise that is not needed for inbox triage > - External-object data must remain available to the inbox filters even when the row marker is removed > - This pull request stops passing external-object summaries into inbox rows and adds regression coverage > - The benefit is a cleaner inbox while preserving external-object filtering behavior ## Linked Issues or Issue Description - Refs #4556 - **Problem:** Inbox task rows display external-object summary markers that operators do not need for triage. - **Expected behavior:** Inbox rows omit the external-object marker, while filters that depend on external-object summaries continue to work. ## What Changed - Removed the external-object summary prop from inbox task rows. - Added a regression test that provides external-object summary data and confirms the inbox row does not render its marker. - Kept external-object summary loading intact for inbox filtering. ## Verification - `pnpm exec vitest run ui/src/pages/Inbox.test.tsx` — 18 tests passed. - `pnpm check:token-gates` — reproduces five pre-existing `#9627` color-literal violations; this PR adds no token values or new gate violations. ## Risks - Low risk: the change removes one optional presentation prop from the inbox row call site and leaves filtering data flow unchanged. - Regression coverage verifies summary data no longer produces the removed inbox marker. > 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 agent with shell and code execution; reasoning enabled; context-window size 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 checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
30ff3d7c58 |
feat(routines): expose activity gate API (#9438)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Scheduled routines provide recurring control-plane work without manual intervention > - The new activity gate can suppress scheduled runs when no external work occurred > - The core scheduler and database support landed without a public create/update contract > - Agents, operators, and managed plugins need validated fields plus discoverable semantics to opt in safely > - This pull request exposes the activity gate through routine APIs, revisions, plugin contracts, tests, and skill documentation > - The benefit is backward-compatible control over idle scheduled work without losing activity-triggered follow-up ## Linked Issues or Issue Description - Refs #8534 ## What Changed - Added shared activity-gate policy and scope enums with create/PATCH validation. - Persisted activity-gate fields through routine creation, updates, revision snapshots, pipeline snapshots, and revision restores. - Defaulted legacy revision snapshots during restore and added regression coverage for pre-field snapshots. - Extended managed-plugin routine declarations, production reconciliation, and the SDK test harness to preserve non-default gate settings. - Added end-to-end API coverage for create/PATCH/list/detail round-trips, defaults, and invalid enum rejection. - Documented schedule-only semantics, activity windows, own-run/read-action exclusions, scopes, and an hourly quiet-night watcher example. ## Verification - `pnpm exec vitest run packages/shared/src/validators/routine.test.ts server/src/__tests__/routines-service.test.ts server/src/__tests__/routines-e2e.test.ts` - `pnpm exec vitest run packages/shared/src/validators/plugin.test.ts packages/plugins/sdk/tests/testing-actions.test.ts server/src/__tests__/plugin-managed-routines.test.ts server/src/__tests__/routines-service.test.ts -t 'activity gate|preserves declared activity gate settings|resolves routine agent and project refs'` - `pnpm exec vitest run ui/src/lib/workspace-routines.test.ts ui/src/pages/Routines.test.tsx` - `pnpm --filter @paperclipai/shared typecheck` - `pnpm --filter @paperclipai/plugin-sdk typecheck` - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/ui typecheck` - `pnpm check:token-gates` - GitHub CI: all final-head checks green; Storybook visual regression skipped by path rules. - Greptile: 5/5 with no unresolved review threads. ## Risks - Low risk: defaults remain `always` and `company`, preserving existing routine behavior and old revision snapshots. - Managed plugin manifests can now declare the same validated gate settings as the public routine API; omitted values retain core defaults. - Revision snapshots now include the new fields so policy changes are not lost or treated as no-ops during restore. > For core feature work, checked `ROADMAP.md`: this extends the existing Scheduled Routines roadmap item and does not duplicate a separate planned capability. ## Model Used - OpenAI GPT-5.5 via Codex CLI, with repository tool use and code execution; context-window size was 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 checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
8f08ec5ce6 |
feat(status-cards): join summary-mentioned issues to watched set (#10205)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Status cards summarize changing company work and watch issues so later changes can produce useful deltas > - A summary can explicitly reference issues that are important to the update even when those issues do not match the card's configured queries > - Previously, those referenced issues were not retained in the watched set, so their later status, assignee, or comment changes could be missed > - The watched snapshot must avoid artificial additions or removals caused only by a summary changing which issues it references > - This pull request resolves issue references when a summary is written, persists them, and joins them to the watched snapshot with stable delta semantics > - The benefit is that status cards continue tracking the exact issues their latest update called out while keeping follow-up updates relevant and non-duplicative ## Linked Issues or Issue Description ### Pre-submission checklist - [x] I have searched existing open and closed issues and this is not a duplicate. - [x] I am on the latest released version of Paperclip (or can reproduce on `master`). - [x] I have confirmed the error originates in Paperclip itself — not in my agent adapter, API provider, or local configuration. ### What happened? When a status-card summary explicitly referenced an issue by identifier or `/issues/<uuid>` URL, that issue was not automatically retained in the card's watched set unless it independently matched a configured query. Later status, assignee, or comment changes to an issue highlighted by the latest update could therefore be omitted. ### Expected behavior References in the latest summary should resolve only within the card's company, appear in dry runs and the watched-issues UI, count and fingerprint like query matches, and enter or leave the watched set without artificial added/removed deltas already represented by the summary change. ### Steps to reproduce 1. Create a status card whose query does not match a second issue in the same company. 2. Write a summary that references the second issue by identifier or issue URL. 3. Inspect the card's watched count or Watched issues tab. 4. Change the referenced issue's status, assignee, or comments and run the next update. 5. Before this change, the referenced issue is absent from the watched snapshot and its later change does not produce the expected delta. ### Paperclip version or commit - Reproduced on `master` before this PR (base commit `762ce5b4ef`). ### Deployment mode - Local dev (`pnpm dev`), built from source. ### Agent adapter(s) involved - Not adapter-specific (core bug). ### Database mode - Embedded Postgres test environment; the schema change uses standard PostgreSQL JSONB. ### Access context - Board (human operator). ## What Changed - Added migration `0191` and schema support for persisted `status_cards.mentioned_issue_ids`. - Resolved summary references by issue identifier or `/issues/<uuid>` URL within the status card's company when summaries are written. - Joined mentioned issues into watched counts and fingerprints so later status, assignee, and comment changes generate normal update deltas. - Suppressed artificial added/removed deltas when the latest summary starts or stops mentioning an issue. - Added `mentionedIssues` to dry-run responses and a “Mentioned in the latest update” group in the Watched issues tab. - Updated the summarizer prompt to explain that referenced issues automatically join the watched set. - Added focused server and UI coverage for reference resolution, snapshot behavior, deltas, API responses, and rendering. ## Verification - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/status-cards.test.ts src/__tests__/status-card-update-engine.test.ts` — 31 tests passed. - `pnpm --filter @paperclipai/ui exec vitest run src/pages/StatusCards/StatusCardTile.test.tsx` — 11 tests passed. - Earlier implementation verification also passed database/shared/server typechecks, UI `tsc -b`, the broader StatusCards UI test set, and embedded-Postgres migration application. ### Visual Verification - Greptile T-Rex ran Playwright browser checks successfully and captured the Status Card drawer Watched tab showing the new “Mentioned in the latest update” grouping: https://app.greptile.com/trex/runs/15796101/artifacts ## Risks - The migration adds a nullable JSONB column and is backward-compatible; existing cards have no mentioned issues until their next summary write. - Reference extraction is company-scoped to prevent cross-company issue association. - Watched counts and future fingerprints change for cards whose latest summaries reference issues; tests cover additions, removals, and suppression of spurious deltas. - This targeted status-card fix does not introduce a new roadmap subsystem or external integration. ## Model Used - Anthropic Claude Fable 5 (Paperclip model alias; exact underlying provider model ID and context window were not recorded in the implementation task metadata), with extended reasoning, tool use, and code execution. - OpenAI Codex coding agent (runtime model identifier and context window not exposed to this task) prepared the PR, rebased the branch, and ran focused verification with terminal tool use. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
c9881223e4 |
fix(routines): show routines grouped by folder name (#10201)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Routines page is part of the operator UI for scheduled routine management > - The grouped-by-folder view was not presenting folder sections inline in the main pane > - That made the folder grouping mode harder to scan and hid the separation between custom folders, Unfiled routines, and built-in routines > - This pull request updates the Routines page rendering so folder groups appear as inline sections and built-in routines still split into their own section afterward > - The benefit is that grouped routines stay readable and the page matches the intended folder organization ## Linked Issues or Issue Description No corresponding public GitHub issue exists, so the problem is described directly below following the bug template. ### What happened On the Routines page, selecting Group → Folder flattened the grouped list into a single "All routines" section with only the separate built-in routines section below it. ### Expected behavior Group → Folder should render one inline section per folder, keep routines with no folder in an Unfiled section, and preserve the separate built-in routines section after the custom folder groups. ### Steps to reproduce 1. Open the Routines page. 2. Change grouping to Folder. 3. Observe the main pane. 4. The routine list is flattened instead of grouped into folder-labeled inline sections. ### Paperclip version / commit Current PR head: `a8e384c838e362de3437c7a88bc7aa38b10fd9c0` on `fix/routine-folder-grouping`. ### Deployment mode Local development workspace for the Paperclip app UI. ## What Changed - Updated the Routines page rendering so grouped folders render as inline sections instead of flattening into a single list. - Kept routines without a folder grouped under Unfiled. - Preserved the built-in routines section after custom folder groups. - Added and updated tests for the folder-grouped rendering behavior. ## Verification - `pnpm --filter @paperclipai/ui exec vitest run src/pages/Routines.test.tsx` - `pnpm --filter @paperclipai/ui typecheck` - `pnpm check:token-gates` ## Risks - Low risk: the change is localized to the Routines page rendering and its test coverage. - The main behavioral risk is accidental grouping regressions if future routine-grouping logic changes without updating the tests. ## Model Used OpenAI Codex, GPT-5, tool-use enabled, 256k-context class model. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Harold Kim <harold@paperclip.ing> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
3a16b91217 |
feat(status-cards): single-message setup drives query and update prompt (#10202)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI-agent companies and their ongoing work. > - Status cards turn a standing question into recurring, agent-generated summaries on the board. > - The existing setup split intent across a watch prompt and separate update instructions, which made creation and later behavior harder to understand. > - A status card should have one durable source of truth for both deciding what to watch and telling the summarizer what each update must contain. > - This pull request makes the card prompt that source of truth, simplifies creation to one step, and lets operators choose the running agent immediately. > - The benefit is a smaller mental model, fewer configuration modes, and consistent update instructions throughout the card lifecycle. ## Linked Issues or Issue Description Status cards currently require operators to express the same intent in two places: the watch prompt and optional update instructions with append/replace/none modes. This feature simplifies the experimental status-card workflow so a single prompt defines both the watch query and every generated update. The create flow must also support selecting the responsible agent without a second setup step. Related prior status-card work: #10101. ## What Changed - Use the status card's single prompt to compile the watch query and directly instruct every summary update. - Add migration `0190_status_card_single_prompt` to remove `status_cards.instructions_mode` and `status_cards.instructions`. - Add `agentId` to `createStatusCardSchema`, validate company membership, and default new cards to the built-in Summarizer. - Replace the two-step create flow with one prompt-and-agent dialog and extract a shared `SummarizerAgentSelect` for create/settings surfaces. - Remove the extra-instructions settings section, reset incremental history when the prompt changes, and rename the board page to "Status". - Update the bundled `status-card-query` skill and board-operator documentation, then regenerate the skills catalog manifest. ## Verification - Server status-card suites: 29/29 passing. - UI `StatusCards` suites: 22/22 passing. - Skills catalog suite: 20/20 passing. - `tsc -b` passes for server, UI, shared, and database packages. - `pnpm check:migrations` passes. - Light and dark mode screenshots cover the new create dialog and settings tab. ## Risks - Migration `0190` intentionally drops existing separate instruction text. Existing card prompts remain and become the update instructions under the new model; status cards are experimental and feature-flagged. - Prompt edits now reset the incremental summary chain and trigger a full rebuild, which is intentional because the prompt is also the update contract. - Agent selection is company-scoped; invalid agent ids return a validation error rather than creating a misrouted card. > 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 - Implementation: Anthropic Claude via the `claude_local` adapter, agent label "Claude Fable 5"; extended reasoning, tool use, and code execution. The exact provider model id and context-window value were not retained in the task metadata. - PR preparation: OpenAI GPT-5.4 through Codex CLI, with reasoning, repository inspection, GitHub CLI, and Paperclip API tool use. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
7e40ed8c43 |
feat(status-cards): add experimental status card update view (#10101)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI-agent companies. > - Operators need a board-level way to monitor a changing slice of company work without repeatedly rebuilding filters or reading raw task threads. > - Existing summaries are useful snapshots, but they do not provide a dedicated query-backed card with refresh policy, change tracking, update history, and per-update cost visibility. > - The capability needs to be safe to evaluate before it becomes part of the default product surface. > - This pull request adds end-to-end experimental Status Cards, from schema and query compilation through update orchestration and operator UI. > - The entire feature is gated behind the `enableStatusCards` experimental toggle, including its route and sidebar entry. > - The benefit is a governed, inspectable way to keep focused operational rollups current while preserving explicit controls over refresh frequency and spend. ## Linked Issues or Issue Description ### Subsystem affected Cross-cutting (`packages/db`, `packages/shared`, `server/`, `ui/`, and bundled skills/docs). ### Problem or motivation Operators cannot currently define a reusable natural-language view of company work, compile it into an inspectable query, and keep its summary current as matching issues change. Rebuilding filters and rereading task threads makes board-level monitoring repetitive and hides the relationship between source changes, refresh cost, and the resulting summary. ### Proposed solution Add experimental Status Cards that compile operator intent into a query, summarize matched work, record each update, expose manual/interval/reactive refresh policies and costs, and preserve the last good result across stale, updating, paused, and error states. The capability is off by default and fully gated behind `enableStatusCards`, including its route and navigation entry. ### Alternatives considered - Extend existing one-off summaries: rejected because status cards require persistent query provenance, refresh policy, update history, and card-specific cost controls. - Add a dashboard-only filter widget: rejected because it would not provide governed background refresh, an update ledger, or an inspectable compile pipeline. - Ship the surface by default: rejected in favor of an experimental toggle while behavior and operator value are evaluated. ### Roadmap alignment This advances Paperclip’s board-level execution visibility and output-first product goals. `ROADMAP.md` was checked and no duplicate status-card initiative was found. ### Additional context No related open PR was found in the public GitHub search for status cards. The PR-only design wireframes were removed from the repository after review; the published prototype remains external to the production source tree. ## What Changed - Added company-scoped status-card schema, CRUD APIs, compile provenance, update ledger, shared contracts, validators, and OpenAPI coverage. - Added the text-to-query compile pipeline, bundled `status-card-query` agent skill, query versioning, and authorized write-back flow. - Added the experimental board, create flow, lifecycle tiles, detail/settings/debug drawers, archived view, routing, navigation, and instance setting. - Added a change-gated update engine with manual, interval, and reactive refresh policies, trigger selection, active hours, and daily token caps. - Added per-update token/cost recording, today and lifetime rollups, and policy-derived cost previews. - Added operator documentation and agent-authoring hardening for compile and update behavior. - Added PR-prep integration coverage for settings/startup wiring and replaced raw UI values with design-system tokens. - Removed the PR-only `design/pap-15023-status-cards` wireframe artifacts so the repository contains only production feature assets. ## Verification - `pnpm -r typecheck` — passes on the PR head; includes `ui` `tsc -b` passing. The UI compile gate was also independently recorded as passing at `6d7f3cf96b` on July 23, 2026. - `pnpm build` — passes. - `pnpm check:token-gates` — passes with all three gates clean. - `pnpm test:run` — 2,880 tests passed and 1 skipped; the sole failure was an unrelated 10-second `afterAll` database-cleanup timeout in `execution-workspaces-service.test.ts`. - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/execution-workspaces-service.test.ts` — passes on immediate focused rerun (25/25). - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/instance-settings-service.test.ts src/__tests__/server-startup-feedback-export.test.ts` — passes (31/31). - `pnpm --filter @paperclipai/ui exec vitest run src/pages/StatusCards/StatusCardSettingsForm.test.tsx src/pages/StatusCards/StatusCardTile.test.tsx src/pages/StatusCards/format.test.ts src/lib/status-card-state.test.ts` — passes (26/26). - Recorded pre-PR QA: compile-pipeline e2e PASS; full lifecycle and cost QA PASS; security re-review PASS after write-back hardening; UX approved. - `pnpm exec vitest run packages/db/src/status-card-migrations.test.ts` — passes; reapplies migrations `0185`–`0189` against an already-migrated embedded Postgres database. - `pnpm --filter /db check:migrations` — passes migration numbering and safety checks. - `pnpm --filter /db typecheck` — passes. - Merged current `origin/master` on July 24, 2026 with no conflicts; migrations `0185`–`0189` remain unclaimed on master. ## Risks - The feature introduces five database migrations and a new background update path; all new DDL is repeat-safe after partial application, migration numbering/safety checks pass, and update execution is company-scoped and change-gated. - Natural-language compilation can produce invalid or overly broad queries; compile provenance, query validation, debug visibility, and version history make failures inspectable and recoverable. - Reactive or interval refresh could increase spend; active hours, max refresh frequency, daily token caps, per-update cost records, and budget-paused states bound and expose that risk. - The branch name contains an internal execution identifier because it is a fixed handoff branch; it was intentionally not renamed or rebased per the release handoff instructions. - Overall rollout risk is limited because the route, navigation, services, and UI are disabled by default behind `enableStatusCards`. > 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 using GPT-5.5 with reasoning, repository tool use, shell execution, GitHub CLI, and test/build execution. The runtime did not expose a context-window size. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change; the fixed execution-workspace identifier is documented as an authorized handoff exception - [x] I have run tests locally and they pass, with the one cleanup timeout passing on focused rerun - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
2002c4fff3 | refactor: remove redundant archived project filters (#10177) | ||
|
|
564870020b | Exclude archived projects from the default project list route (#10146) | ||
|
|
62e367c1b2 |
fix(ui): rewrite recovery and blocked-notice copy in plain language (#10065)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The issue-detail UI shows recovery cards and blocked/parked notices when a task loses its next step — a run finished with no disposition, a task is stranded, work is blocked behind other tasks, or an assigned item sits in the backlog > - That copy was written in the scheduler's internal vocabulary — "Corrective wake queued", "Graph Liveness", "lost a live action path", "the responsible" — which describes Paperclip's internals rather than the user's situation > - Users seeing these cards report having no idea what the card means or what they are supposed to do > - This pull request rewrites the user-facing copy in plain language and adds explicit calls to action that match the options in the card's Resolve menu > - The benefit is that a non-expert operator can read a recovery or blocked notice and immediately understand what happened and which action to take next ## Linked Issues or Issue Description No public GitHub issue exists for this; describing the problem here (bug-report format): - **What happened:** Recovery action cards and blocked notices render internal jargon, e.g. the headline "Paperclip detected this task lost a live action path. A recovery owner needs to act.", the chip "Corrective wake queued", the kind label "Graph Liveness", and phrases like "Comments still wake the responsible". Status values also appear as raw code literals (`in_progress`, `todo`). - **Expected behavior:** These notices should tell a normal user, in plain language, what happened and what to do next (retry the task, mark it done, send it for review, or record a blocker). - **Impact:** Operators stall on tasks that only need a simple disposition because the UI doesn't tell them that's what is being asked. Related prior work: #9417 (merged) made the reopen-suppressed blocked message explicit; this PR extends the same plain-language treatment to the rest of the recovery and blocked-notice copy. ## What Changed - Recovery card headlines for `missing_disposition`, `stranded_assigned_issue`, and `issue_graph_liveness` now say what Paperclip found and name the concrete next steps ("try the task again, mark it done, or send it for review") matching the card's Resolve menu. - The `issue_graph_liveness` kind label "Graph Liveness" is now "Task Needs Next Step", and the "Wake" metadata row is now "Follow-up". - Wake-policy chips describe actual behavior: "An agent will be asked to choose the next step" (was "Corrective wake queued"), "Board will decide", "Manual follow-up needed", "Repair needed before retry", "Check scheduled". - Blocked/waiting/parked notices say "the assignee" instead of "the responsible" / "responsible agent", and "notify" instead of "wake". - The still-needs-a-next-step notice drops raw `in_progress` code literals and keeps a plain-language option list (mark done or cancelled, send for review, record what is blocking it, delegate follow-up). - Parked-backlog notice renders "To do / In progress" as plain labels instead of code literals. - Component tests updated to pin the new copy and the successful-run example options. ## Verification - `cd ui && npx vitest run src/components/IssueRecoveryActionCard.test.tsx src/components/IssueBlockedNotice.test.tsx src/components/IssueAssignedBacklogNotice.test.tsx src/components/IssueChatThread.test.tsx` — 4 files, 126 tests, all passing. - Copy-only review: the diff touches display strings, one label map entry, and test assertions; no control flow, props, or identifiers change. ## Risks - Low risk — user-facing strings and test updates only. No behavior, API, or schema changes. The only functional surface is that anything keying off the displayed text (e.g. screenshots, external docs) will show the new wording. ## Model Used - Claude (Anthropic) — Claude Fable 5, model ID `claude-fable-5`, extended thinking enabled, running in Claude Code with agentic tool use. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes (no docs reference this copy) - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
0f898f95af |
Render managed experimental settings as locked, with a 'Managed by Paperclip Cloud' badge (#10061)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The experimental settings page renders one interactive toggle per feature from the settings API > - On managed instances some values are enforced by the hosting control plane, and the API now reports those keys as managed > - Rendering enforced values as live toggles misleads users: the click appears to work, and the value silently snaps back > - This pull request renders managed keys as locked toggles with a "Managed by Paperclip Cloud" badge and guards the handlers so no PATCH can be emitted > - The benefit is UI honesty on managed instances, with self-hosted responses rendering exactly as before ## Linked Issues or Issue Description Builds on #10058 — renders the per-key `managedKeys` metadata #10058 adds to settings responses (typing shared from #10058 at rebase). No public issue exists; `feature_request` template fields: - **Problem or motivation:** on managed instances users see fully interactive toggles for settings the control plane enforces; changes appear to apply and never do, with no explanation. - **Proposed solution:** disabled toggle + badge + guarded handler driven by the settings response's managed-key metadata; the ~17 uniform setting cards are extracted into one shared component with copy, aria-labels, and patch payloads preserved verbatim. - **Alternatives considered:** hiding managed settings entirely (users lose sight of the effective value and why it is fixed); tooltip-only hints on still-active toggles (doomed PATCHes are still emitted and stripped server-side). - **Roadmap alignment:** supports the in-progress "Cloud deployments" milestone in `ROADMAP.md`. ## What Changed - When the settings API reports a feature key as managed (`managedKeys` from the managed-config overlay), the experimental settings page renders that toggle disabled with a badge and a guarded handler, so a click can never emit a PATCH. Previously, managed-instance users saw fully interactive toggles they could never actually change. Self-hosted responses (no `managedKeys`) render exactly as before. - The ~17 copy-pasted uniform setting cards are extracted into one `ExperimentalToggleCard` component with titles, descriptions, footnotes, aria-labels, and patch payloads preserved verbatim; the two bespoke cards get inline managed handling (the managed auto-recovery toggle also cannot open its preview dialog). - `ui/src/api/instanceSettings.ts` response typing now uses the shared `InstanceExperimentalSettingsWithManaged` / `ManagedSettingMetadata` types from #10058; `ui/src/pages/InstanceExperimentalSettings.tsx` locked rendering + card extraction; tests. ## Verification - 24 page tests (20 existing unmodified + 4 new: locked badge with no PATCH while unmanaged keys stay editable; managed auto-recovery opens no dialog; an open recovery preview closes with no PATCH when a refresh marks auto-recovery managed; self-hosted unaffected): `pnpm --filter @paperclipai/ui exec vitest run src/pages/InstanceExperimentalSettings.test.tsx` - `pnpm --filter @paperclipai/ui typecheck` clean ## Risks - Low risk. UI-only change; no server or API behavior changes. Self-hosted responses carry no `managedKeys`, so the page renders exactly as before there. The card extraction preserves copy, aria-labels, and patch payloads verbatim, covered by the 20 pre-existing page tests passing unmodified. ## Model Used Claude Fable 5 (`claude-fable-5`), extended thinking, agentic tool use; independently peer-reviewed by a second AI agent before push ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
b431d4eca1 |
fix(a11y): add ARIA progressbar to QuotaBar component (#1878)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Operators run those agents against paid model providers, so the web UI has a Costs surface that reports spend and quota utilisation > - Those figures are drawn as horizontal bars by the shared `QuotaBar` component (`ui/src/components/QuotaBar.tsx`), consumed by `BillerSpendCard` and `ProviderQuotaCard` > - `QuotaBar` renders its fill as a plain `<div>` whose CSS width is the only encoding of the percentage — no `role`, no value attributes, no accessible name > - A screen reader therefore announces nothing at all for these bars, so the spend and quota numbers they convey are unavailable to assistive-technology users (WCAG 2.1 SC 4.1.2, Name/Role/Value) > - The same gap is being closed for the other bars in this area by #1805 (BudgetPolicyCard) and #1869 (ProviderQuotaCard's inline bars); `QuotaBar` is the remaining shared component with no ARIA semantics > - This pull request adds the standard ARIA progressbar attributes to `QuotaBar`'s fill element, reusing the `label` prop the component already takes > - The benefit is that every progress bar on the Costs screen exposes its name and current value to assistive technology, with no visual or behavioural change for sighted users ## Linked Issues or Issue Description No existing GitHub issue — the problem is described in-PR below, following [`bug_report.yml`](.github/ISSUE_TEMPLATE/bug_report.yml). Related PRs from the same accessibility sweep (each covers a *different* component, so these are companions rather than duplicates — all three are currently open): - Refs #1805 — ARIA attributes for the BudgetPolicyCard progress bar - Refs #1869 — ARIA attributes for the ProviderQuotaCard inline bars **What happened?** On the Costs screen, the spend/quota bars rendered by `QuotaBar` (via `BillerSpendCard` and `ProviderQuotaCard`) are non-semantic `<div>` elements. Screen readers skip them entirely: no role, no value, no label is announced, so the percentage information is available only visually. **Expected behavior** Each bar should be exposed as a progress bar with an accessible name and its current value — e.g. announced as "Weekly spend: 45%, progress bar". **Steps to reproduce** 1. Run the app and open the Costs page. 2. Expand any provider or biller card so a quota/spend bar is visible. 3. Navigate to the bar with a screen reader (VoiceOver, NVDA, or Chrome DevTools → Accessibility pane). 4. Observe that the fill element has no role, no value, and no accessible name. **Paperclip version or commit** Reproduces on `master`; `ui/src/components/QuotaBar.tsx` has carried no ARIA attributes since the component was introduced. **Deployment mode** Not deployment-specific — the missing markup is in the shipped component. Verified in local dev (`pnpm dev`). **Agent adapter(s) involved** Not adapter-specific (core UI). ## What Changed - `ui/src/components/QuotaBar.tsx`: added `role="progressbar"` to the fill `<div>`. - Added `aria-valuenow={Math.round(clampedPct)}` with `aria-valuemin={0}` / `aria-valuemax={100}`, using the already-clamped percentage so the reported value can never fall outside 0–100. - Added an `aria-label` of the form `<label>: <pct>%`, reusing the existing `label` prop for the accessible name. - No changes to props, styling, layout, or rendering logic: 1 file, 5 added lines, 0 deleted. ## Verification - Manual: open Costs → expand a provider/biller card, inspect the bar in Chrome DevTools → Accessibility pane. The fill node now reports role `progressbar`, value `45`, min `0`, max `100`, and name "Weekly spend: 45%". - Manual: with VoiceOver/NVDA, the bar announces "Weekly spend: 45%, progress bar" instead of being skipped. - Visual regression check: the bar is unchanged for sighted users — only ARIA attributes were added, no class or style changes. - CI (lint, typecheck, build, tests) is green on this branch. - No unit test is added: the change is a set of static ARIA attributes on one element, and `QuotaBar` currently has no test file. Happy to add one if maintainers would like coverage here. ## Risks Low risk. Presentation-only accessibility metadata on a single element; no props, state, or styling change, and no other component is touched. The one debatable point is that the percentage appears in both `aria-label` and `aria-valuenow`, so some screen readers may announce it twice; both forms are valid, and the label is kept because it carries the bar's name alongside the value. Happy to drop the percentage from the label if reviewers prefer the terser announcement. ## Model Used <!-- @bluzername: please replace this line with the provider + exact model ID (and context window / reasoning mode if relevant), or "None — human-authored". Required by CONTRIBUTING.md. --> ## Checklist - [x] I have included a thinking path that traces from project context to this change - [ ] 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] I have run tests locally and they pass - [ ] I have added or updated tests where applicable - [ ] I have updated relevant documentation to reflect my changes (no docs cover this component's markup) - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
8f7509c28b |
fix(a11y): add aria-label to mobile tab selector in PageTabBar (#1871)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - People increasingly drive Paperclip from a phone, so the UI ships a mobile layout alongside the desktop one > - `PageTabBar` is the shared component behind the tab strip on nearly every detail page — AgentDetail, ProjectDetail, RoutineDetail, IssueDetail, Inbox, Costs > - On desktop it renders a Radix `TabsList`, whose `TabsTrigger`s carry their own accessible names; on mobile it swaps to a native `<select>` > - That `<select>` had no accessible name at all, so screen readers announced it only as "popup button" — a user could not tell what the control switches between > - Because the component is shared, the gap reproduced on every mobile page that uses tabs rather than on one screen > - This pull request adds `aria-label="Page section"` to the mobile `<select>` > - The benefit is that mobile screen-reader users get the same orientation desktop users already get from the tab triggers, from a one-line change with no visual or behavioral impact ## Linked Issues or Issue Description No existing public issue covers this, so the problem is described in-PR following `.github/ISSUE_TEMPLATE/bug_report.yml`: - **What happened** — On a mobile viewport, the `PageTabBar` `<select>` had no `aria-label`, no `<label>` association, and no visible text of its own. VoiceOver/TalkBack announce it as an unlabeled "popup button". - **Expected behavior** — The control announces what it switches between, matching the accessible naming the desktop `TabsTrigger`s already provide. - **Steps to reproduce** — 1. Open any detail page with tabs (agent, project, routine, issue). 2. Narrow the viewport to mobile width so the tab strip collapses to a `<select>`. 3. Focus the `<select>` with a screen reader. 4. Observe that no purpose is announced. - **Version / commit** — head `ef92d1c`, branch `fix/page-tab-bar-mobile-a11y`. - **Deployment mode** — Any. The change is UI-only and client-side. **Related prior PR:** #1532 (closed unmerged on 2026-03-23) made this same one-line change to `ui/src/components/PageTabBar.tsx` as part of a ~100-file batch. This PR is the focused standalone version of that fix. ## What Changed - Added `aria-label="Page section"` to the mobile `<select>` in `ui/src/components/PageTabBar.tsx`. One line added; no other files touched. ## Verification - **Automated:** `pnpm -C ui test` and the repo CI gates (lint, typecheck, build) — CI is currently green on `ef92d1c`. - **Manual:** Open any tabbed detail page, narrow the viewport until the tab strip becomes a `<select>`, and focus it with VoiceOver (macOS/iOS) or TalkBack (Android). It now announces "Page section, popup button" instead of an unlabeled "popup button". - **Inspector check:** In devtools, the `<select>` node's computed accessible name is "Page section" (previously empty). ## Risks Low risk. `aria-label` on a `<select>` is a presentation-free attribute: it changes nothing about layout, styling, DOM structure, event handling, or the desktop code path, which is untouched. No migration, no API change, no new dependency. The only debatable point is wording — "Page section" is a generic name shared by every call-site (see the note below). ## Model Used Not specified by the original author, and not recoverable from the commit metadata (no `Co-Authored-By` or model trailer on `ef92d1c`). @bluzername — please replace this line with the provider, model ID/version, and any relevant capability details, or "None — human-authored". ## Checklist - [x] I have included a thinking path that traces from project context to this change - [ ] I have specified the model used (with version and capability details) — see above; needs the author - [ ] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (`fix/page-tab-bar-mobile-a11y`) and contains no internal Paperclip ticket id or instance-derived details - [ ] I have run tests locally and they pass - [ ] I have added or updated tests where applicable — no test added; the change is a static attribute with no branching behavior - [ ] I have updated relevant documentation to reflect my changes — not applicable - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups — currently 4/5, see below - [ ] I will address all Greptile and reviewer comments before requesting merge --- ### Maintainer note on the open Greptile comment This description was restructured to the repository PR template by a maintainer; the code and the author's intent are unchanged. Unchecked boxes above are ones only @bluzername can attest to. Greptile's one remaining comment asks for a `selectAriaLabel` prop so call-sites could override the label. We think the hardcoded label is correct here and match existing practice: shared components whose meaning is fixed own their label internally (`ThemeToggle.tsx`), while components whose label depends on the data they render take it as a prop (`CopyText.tsx`'s `ariaLabel`). This `<select>` always means "which page section", at every call-site, so a prop no caller would set would be unused API surface. |
||
|
|
0b496c9c03 |
feat(secrets): add run-bound agent secret access (#9921)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI-agent companies. > - Agents already receive selected company secrets through `env.*` bindings at run launch, but environment injection is ambient, long-lived, and not suitable for every secret consumer. > - The existing binding and secret-access-event models already provide company-scoped authorization and per-resolution audit seams. > - Agents need an explicit way to discover only the secrets granted to them and fetch a value on demand without exposing the wider company catalog. > - That capability must remain run-bound, preserve low-trust token carve-outs, and make every value read visible in both security and operator audit trails. > - This pull request adds an `access.*` delivery namespace, two run-bound agent routes, dual audit logging, documentation, and an operator grants editor. > - The benefit is least-privilege, revocable, auditable secret access while preserving existing env injection behavior. ## Linked Issues or Issue Description No pre-existing public issue. Related work: - Refs #9797 — existing in-sheet agent access UI that this PR extends to distinguish env and API delivery. - Refs #9918 — complementary searchable-agent picker improvement for the same secrets sheet. - Refs #9530 — related company-wide metadata catalog proposal; this PR intentionally exposes only the authenticated run's granted aliases and values. **Problem / motivation:** Agents can currently consume secrets only through process environment injection. This keeps values resident for the run, does not support on-demand consumers, and cannot provide a discrete operator-visible activity event for each agent-initiated read. **Proposed solution:** Treat `company_secret_bindings` as the source of truth for agent secret grants. Keep `env.KEY` as env delivery and add `access.ALIAS` for API-only delivery; an env binding also implies read access because the value is already present in the agent process. Add run-bound list/fetch endpoints that derive scope from the authenticated heartbeat run and never accept caller-selected overlays. **Alternatives considered:** A company-wide agent-readable catalog was rejected for this value path because it increases reconnaissance and does not prove a per-secret grant. Reusing the ephemeral environment-probe resolver was rejected because it lacks binding enforcement. Approval-gated reads and user-scoped secrets remain deferred beyond v1. **Roadmap alignment:** This extends the completed **Secrets Manager with per-agent access** roadmap capability from launch-time env injection to explicit run-bound API delivery without duplicating a separate planned initiative. ## What Changed - Added `access.*` agent binding validation and a dedicated run-bound resolver that combines `secrets:read` authorization with binding-context enforcement. - Added `GET /api/agents/me/secrets` for minimal granted metadata and `POST /api/agents/me/secrets/:key/value` for on-demand value fetches with `Cache-Control: no-store`. - Preserved the existing denials for low-trust review agents, task-bridge credentials, and skill-test tokens; standard long-lived agent API keys cannot call the run-bound routes. - Added dual audit behavior: value attempts write `secret_access_events` and `activity_log` (`secret.value.read`), while metadata listing writes the lighter `secret.access.listed` activity event. - Kept env compatibility: `env.*` remains injected at launch and also implies API read for the same bound agent; `access.*` never becomes an environment variable. - Added the agent-settings **Secret access** editor plus delivery-mode/alias surfacing on the Secrets page, with focused UI tests and tokenized layout styles. - Updated OpenAPI, shared types, agent-facing skill documentation, and API reference documentation. ### UI Screenshots P3 produced and reviewed three screenshots using mock data; images are intentionally not committed to the repository: - `secret-access-editor.png` — agent settings grant editor. - `secret-access-light.png` — Secrets-page delivery surfacing in light mode. - `secret-access-dark.png` — Secrets-page delivery surfacing in dark mode. The source attachments are retained with the implementation task and linked in the internal handoff; the public page publisher was unavailable in the PR-prep runtime. ## Verification - `pnpm exec vitest run server/src/__tests__/agent-secrets-routes.test.ts server/src/__tests__/secrets-service.test.ts server/src/__tests__/secrets-routes.test.ts ui/src/lib/secret-delivery.test.ts ui/src/components/AgentSecretAccessEditor.test.tsx` — 5 files, 122 tests passed. - Security follow-up: `pnpm exec vitest run server/src/__tests__/agent-secrets-routes.test.ts server/src/__tests__/secrets-service.test.ts` — 2 files, 73 tests passed after active-run and version-consistency fixes. - Final-head CI: all feature, typecheck, build, e2e, security, and review gates pass; `General tests (server (1/3))` remains red after one rerun because unrelated `heartbeat-retry-scheduling.test.ts` cleanup deletes `heartbeat_runs` before referenced `activity_log` rows. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/shared typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - `pnpm check:token-gates` — feature-local arbitrary-value violations fixed; command still reports five unchanged `#9627` literals outside this PR. - End-to-end QA passed all eight acceptance criteria: grant/list, fetch, dual audit, env-implies-read, denial matrix, revocation, UI rendering, and env-injection regression. Evidence: https://github.com/paperclipai/paperclip/pull/9921#issuecomment-5027455492 - Security review returned PASS-with-required-changes; the implementation uses the required dedicated binding-enforcing resolver, run-bound JWT restriction, run-derived overlays, minimal metadata, and a resolver redaction-registration hook. Evidence: https://github.com/paperclipai/paperclip/pull/9921#issuecomment-5027455382 ## Risks - A compromised agent can exfiltrate any secret explicitly granted to it; explicit company-scoped/run-scoped grants, revocation, and audit reduce but cannot remove that inherent capability risk. - The resolver invokes a redaction-registration hook before returning values, but the current route has no persistent cross-request per-run redaction registry. Paperclip-owned later comments/events therefore cannot yet guarantee automatic scrubbing of a deliberately copied fetched value; QA classified this as non-blocking residual hardening. - Audit-event insertion currently fails open if the security-event insert itself fails; the operator activity event provides partial redundancy, but a future hardening change should define fail-closed behavior for value delivery. - This PR overlaps `ui/src/pages/Secrets.tsx` with #9918 and may require a straightforward rebase after that PR moves. > 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.3-codex`, with reasoning, repository tool use, terminal execution, Paperclip API access, and GitHub CLI capabilities. Context-window size is not exposed by the runtime. - Anthropic Claude Opus 4.8 with 1M context and tool use assisted with the UI implementation commit. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
d23fbf8ae4 |
feat(connections): add AppDefinition Wave 1 catalog (#9981)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Connections is the subsystem that defines which external apps and MCP-style integrations operators can browse, configure, and run > - The v3 schema core in #9958 added stable connection identities, auth metadata, and grant-aware contracts, but the app catalog still used the older gallery shape > - The product needs a richer, typed AppDefinition catalog so browsing and setup can render provider-specific auth and configuration requirements consistently > - This pull request moves the Wave 1 app catalog onto generated AppDefinition data and carries that shape through shared types, server lookup paths, and app connection UI > - The benefit is that follow-up runtime and wizard work can build against one catalog contract instead of local-only mock/gallery data ## Linked Issues or Issue Description Refs #9958. No public GitHub issue exists for this branch. This is the catalog layer for the Connections v3 stack after the schema-core foundation in #9958. ## What Changed - Adds generated AppDefinition data for the Wave 1 catalog and ingestion reporting. - Replaces the legacy tool app gallery exports with AppDefinition-centered shared contracts, validators, and tests. - Updates server tool-access lookup behavior to use the AppDefinition catalog. - Updates app connection UI surfaces and tests to consume AppDefinition-backed catalog data. - Documents the catalog ingestion workflow in the connector playbook. ## Verification - `pnpm run preflight:workspace-links` - `pnpm exec vitest run packages/shared/src/app-definitions.test.ts packages/shared/src/app-definitions-url.test.ts ui/src/pages/apps/AppsConnect.test.tsx server/src/__tests__/tool-access-service.test.ts` ## Risks - Medium: this changes the catalog contract used by shared, server, and UI app connection surfaces. - Catalog data quality matters because generated definitions now drive browse/setup display. - Follow-up runtime and wizard PRs must rebase on this branch or on master after this lands. > 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 GPT-5 Codex coding agent with repository tool use. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
7e00f67138 |
feat(connections): add v3 schema core (#9958)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI-agent companies and their governed access to external systems. > - Connected Apps build on the existing Apps and MCP gateway substrate so companies can configure reusable, auditable integrations. > - The current connection record does not yet have a stable public address, explicit ownership/auth method fields, or subject-specific credential grants. > - Without that schema core, later OAuth, per-user authorization, token brokering, triggers, and connector-service phases cannot enforce tenant and subject boundaries consistently. > - This pull request adds the forward-compatible Connections v3 schema core while preserving the existing connection lifecycle and directly migrating the remote MCP transport name. > - The benefit is a company-scoped, least-privilege foundation for one-click integrations without bypassing Paperclip secrets, profiles, rules, or audit controls. ## Linked Issues or Issue Description No matching public issue was found. **Problem** Paperclip's current app connections need a durable identity and authorization substrate before Connected Apps can safely support multiple setup methods, per-user credentials, provider tenants, and managed connector services. The existing schema only models a single connection-level credential set and uses legacy transport terminology. **Proposed solution** Add a stable company-scoped connection UID, explicit ownership/auth/transport fields, a subject-aware `connection_grants` table, and multi-key credential annotations. Backfill existing connections and workspace grants in a reversible migration, then update shared/server/UI contracts to the new `mcp_remote` transport name. **Related work** - Related foundation: #9534 - Roadmap: Connected Apps (one-click integrations) ## What Changed - Added company-scoped connection `uid`, `ownership`, `authKind`, and canonical transport fields across database, shared contracts, validators, services, and UI fixtures. - Added `connection_grants` with workspace/user subject rules, provider tenant metadata, credential secret refs, revocation state, company scoping, and uniqueness constraints. - Added migration `0182_connections_v3_schema_core` to backfill stable UIDs, rename `remote_http` to `mcp_remote`, infer auth kinds, create default workspace grants, and support rollback coverage. - Added multi-key credential annotations and updated gateway/access services without changing the existing lifecycle behavior. - Updated the connection glossary, connector playbook, and security threat model for the new identity, grant, and relay boundaries. - Added explicit test UIDs to direct database fixtures so the new non-null invariant is exercised across affected server suites. ## Verification - `pnpm --filter @paperclipai/shared typecheck` - `pnpm --filter @paperclipai/db typecheck` - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/ui typecheck` - `pnpm exec vitest run server/src/__tests__/tool-access-service.test.ts server/src/__tests__/tool-gateway-service.test.ts server/src/__tests__/tool-gateway.test.ts server/src/__tests__/heartbeat-runtime-skills.test.ts server/src/__tests__/tool-oauth-legacy-backfill.test.ts server/src/__tests__/tool-access-policy-service.test.ts server/src/__tests__/heartbeat-runtime-mcp-servers.test.ts packages/db/src/connections-v3-schema-core-migration.test.ts packages/shared/src/validators/tool-access.test.ts --config vitest.config.ts` — 9 files, 218 tests passed. - Latest-head GitHub Actions: build, typecheck, general/serialized suites, backup/worktree restore coverage, both e2e shards, canary, policy, and security scans pass. - Greptile: 5/5 with zero unresolved threads. - `pnpm check:token-gates` remains red only on five pre-existing `#9627` color literals outside this change. ## Risks - **Migration risk:** UID backfill and default-grant creation touch every existing connection. The migration uses company-scoped uniqueness, deterministic legacy UIDs with ID suffixes, and seeded up/rollback coverage. - **Authorization risk:** Grant rows carry credential references. Constraints enforce workspace-vs-user subject shape, company/connection lookup indexes, one default grant per connection, and one user grant per connection/subject. Security review is requested specifically for this design. - **Compatibility risk:** `remote_http` is renamed directly to `mcp_remote`; all repository call sites and fixtures are updated in the same change. - **Future-phase risk:** Subject-bound token issuance, triggers, and connector-service relay verification remain fail-closed requirements documented for later phases; this PR does not expose those capabilities. > 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 CLI coding agent. The runtime did not expose an exact underlying model ID or context-window size; capabilities used include repository inspection, code editing, shell execution, test execution, Git/GitHub CLI operations, and structured reasoning. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
0d2bfee972 |
build(deps): bump radix-ui from 1.6.0 to 1.6.4 (#9895)
Bumps [radix-ui](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/radix-ui) from 1.6.0 to 1.6.4. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/radix-ui/primitives/blob/main/packages/react/radix-ui/CHANGELOG.md">radix-ui's changelog</a>.</em></p> <blockquote> <h2>1.6.4</h2> <ul> <li>Fixed a regression where importing primitives from the root <code>radix-ui</code> entry point erased every primitive's types to <code>any</code>.</li> </ul> <h2>1.6.3</h2> <h3>Dialog</h3> <ul> <li>Fixed broken ARIA references in Dialogs where title or description elements are not rendered.</li> </ul> <h3>Slider</h3> <ul> <li>Fixed a bug where <code>onValueCommit</code> was not called when a slider thumb was dragged across another thumb.</li> </ul> <h3>Toast</h3> <ul> <li>Fixed <code>Toast</code> removing non-focused toasts when pressing <code>Escape</code>.</li> </ul> <h3>Tooltip</h3> <ul> <li>Fixed a bug where <code>Tooltip.Content</code> children were mounted to the DOM twice.</li> </ul> <h3>Other updates</h3> <ul> <li>Fixed overriding inline animation style in <code>Popper.Content</code>.</li> <li>Improved tree-shaking so bundlers can drop unused components. Component parts are now marked <code>/* @__PURE__ */</code> and use named render functions instead of <code>Component.displayName = ...</code> assignments, which previously prevented dead-code elimination with some bundlers.</li> <li>Widened <code>virtualRef</code> prop type to allow <code>RefObject<Measurable | null></code> in popover components.</li> <li>Fixed dev-only checks with conditional exports to drop dev-warnings from production builds.</li> <li>Added per-primitive subpath entry points so each primitive can be imported directly, eg. <code>import { Accordion } from 'radix-ui/accordion'</code> or <code>import * as Accordion from 'radix-ui/accordion'</code>. This mirrors the namespaced exports available from the root <code>radix-ui</code> entry point.</li> <li>Fixed a bug where updating a <code>Checkbox</code>, <code>Switch</code>, or <code>RadioGroup</code> value programmatically (eg. a "select all" control) while inside a <code><form></code> would dispatch a <code>click</code> event from the hidden bubble input that propagated to ancestor <code>onClick</code> handlers.</li> </ul> <h2>1.6.2</h2> <h3>Other updates</h3> <ul> <li>Added CSS custom properties for Navigation Menu item indicators' translate values.</li> <li>Fixed a bug in Dismissable Layer causing background nested popovers to close all layers on outside click</li> <li>Fixed runtime errors for <code>Form.Message</code>, <code>Form.Control</code>, <code>Form.Label</code> and <code>Form.ValidityState</code> that are correctly rendered outside of <code>Form.Field</code> components</li> <li>Fixed a bug in form control components to ensure their values are updated when their associated form's is reset. This affects <code>RadioGroup</code>, <code>Slider</code>, <code>Select</code>, and <code>Switch</code>.</li> <li>Fixed menu items, tab triggers, toolbar links, and select items intercepting <code>Space</code>/<code>Enter</code> keys that originate from focusable descendants.</li> <li>Fixed a bug where calling an event handler without an argument would throw, preventing successive event handlers from being called. This affected all components that accept event handlers with internal implementations.</li> <li>Fixed a bug in Context Menu to ensure that the menu properly re-anchors to the latest pointer position when re-triggered in its open state.</li> <li>Fixed stale <code>onEscapeKeyDown</code>/<code>onDismiss</code> handlers on React 19.2.</li> <li>Fixed items in a Roving Focus Group not being auto-focused on mount within a Focus Scope component.</li> <li>Fixed a regression in Dismissable Layer originating from a <a href="https://redirect.github.com/react/react/pull/34831">bug in React's <code>useEffectEvent</code></a>.</li> <li>Fixed <code>--radix-scroll-area-corner-width</code> and <code>--radix-scroll-area-corner-height</code> not resetting to <code>0</code> when a corner is removed. Previously these values would stick around and leave a permanent gap on the remaining scrollbar.</li> <li>Fixed a bug in Slider where stepping with the keyboard would skip a valid value when the current value is off the step grid. Stepping now snaps to the next step-aligned value in the direction of travel, matching native <code><input type="range"></code> behavior.</li> </ul> <h2>1.6.1</h2> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/radix-ui/primitives/commits/HEAD/packages/react/radix-ui">compare view</a></li> </ul> </details> <details> <summary>Attestation changes</summary> <p>This version has no provenance attestation, while the previous version (1.6.0) was attested. Review the <a href="https://www.npmjs.com/package/radix-ui?activeTab=versions">package versions</a> before updating.</p> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
6439572ecd |
fix(ui): sync cron validity + settle branch test for radix-ui 1.6.4 (#9966)
## Thinking Path > - Paperclip is the open-source app people use to manage AI agents for work > - The `ui` package contains React components that drive the agent scheduling and workspace configuration UX > - Dependabot PR #9895 bumped `@radix-ui/react-*` from 1.6.0 → 1.6.4, which changed the internal effect-scheduling order inside Dialog and Select primitives > - Two `workspaces-a` CI tests started failing: `RoutineRunVariablesDialog` and `editable-sections / TriggersSection` > - Root cause for both: radix 1.6.4's changed scheduling pushes a cascaded state update one render-tick later, and each test asserted before that tick landed > - This PR fixes the two affected surfaces at the source (one production fix, one test fix) so the radix bump can land cleanly > - The benefit is unblocking PR #9895 without compromising test fidelity or production correctness ## Linked Issues or Issue Description Refs #9895 — this PR fixes the two `workspaces-a` test failures that blocked the radix-ui 1.6.0 → 1.6.4 Dependabot bump. **Root cause:** radix-ui 1.6.4 changed the internal effect-scheduling order inside its Dialog and Select primitives, pushing certain cascaded state updates one render-tick later than before. Two tests each asserted against the intermediate state, before the deferred tick landed. **Affected tests (both now pass at radix 1.6.0 AND 1.6.4):** 1. `editable-sections / TriggersSection` — `ScheduleEditor` disabled-button assertion 2. `RoutineRunVariablesDialog` — workspace branch propagation assertion Production behavior is unchanged and correct in both cases (verified via tracing). ## What Changed - **`ui/src/components/ScheduleEditor.tsx`** — `onValidityChange` is now called synchronously inside the custom-cron `onChange` handler, not only via the passive `useEffect` below. Previously there was a one-render window where an invalid draft still read as valid to the parent (button enabled); this closes that window. The effect call is preserved as a safety net for other entry paths; only the `onChange` path is new. - **`ui/src/components/RoutineRunVariablesDialog.test.tsx`** — the post-mount settle loop now waits for the branch value to actually appear in an `<input>` (`value === "pap-1634-routine-branch"`) rather than exiting as soon as the workspace card mounts. The card reports its branch name through an effect callback that triggers a follow-up render; the old loop exited one tick too early. Iteration cap raised from 10 → 20 to give the extra tick room. This PR intentionally does **not** bump radix-ui — that stays in #9895. ## Verification ```sh # TypeScript — clean at radix 1.6.0 (master): tsc -p ui/tsconfig.json # Targeted vitest: npx vitest run ui/src/components/RoutineRunVariablesDialog.test.tsx npx vitest run ui/src/components/editable-sections npx vitest run ui/src/components/ScheduleEditor # Full ui suite — green with radix 1.6.4 installed locally (371 files / 3035 tests): npx vitest run --project ui # check-forbidden-tokens — clean ``` All of the above pass at **both** radix 1.6.0 (current master) and 1.6.4. ## Risks Low risk. The production change (`ScheduleEditor.tsx`) adds a synchronous call to an already-injected `onValidityChange` prop — same value, earlier in the same event cycle. No new state, no new effects, no API changes. The test change tightens an assertion (waits longer, checks a more specific condition) rather than relaxing one. ## Model Used Claude Sonnet (Anthropic) — Paperclip agent workflow; model family claude-sonnet-4-x with tool use and extended reasoning 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 checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Harold Kim <harold@paperclip.ing> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
c1f6698ec5 |
fix(ui/invite): make pending-approval admin guidance non-clickable (#6786)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies, and
humans onboard into companies via invite links.
> - Some invite types (`company_join` with
`requires_company_admin_approval`) require an admin to approve the join
request after the invitee submits it.
> - While the requester waits, the invitee sees the
`AwaitingJoinApprovalPanel` in `InviteLanding`, which describes where
the admin needs to go to approve the request.
> - That panel rendered the destination — "Company Settings → Access" —
as two clickable `<a href="/company/settings/access">` links, even
though the surrounding copy is plainly addressed to the admin ("Ask
**them** to visit ..."), not the requester.
> - First-time invitees naturally click the only underlined link on the
screen, are sent to `/company/settings/access`, hit the "No company
access" panel (they have no membership yet), and conclude the invite
flow is broken.
> - This PR removes the navigation by rendering both "Company Settings →
Access" references as plain styled text (`<p>` / `<span>`), so the
guidance stays visible but cannot be followed by the requester.
> - The benefit is that the post-submit invite experience matches the
copy's intent — guidance for the admin, not navigation for the
requester.
Fixes #6784.
## What Changed
- `ui/src/pages/InviteLanding.tsx` — In `AwaitingJoinApprovalPanel`,
replace the two `<a href={approvalUrl}>Company Settings → Access</a>`
elements with `<p>` and `<span>` containing the same text. Remove the
now-unused `approvalUrl` constant.
- `ui/src/pages/InviteLanding.test.tsx` — Update the existing "pending
approval page" test: it previously asserted two anchor tags pointing at
`/company/settings/access`; it now asserts **zero** anchors while the
text "Company Settings → Access" still appears twice (in the "Approval
page" box and inline in the "Ask them to visit ..." sentence). Renamed
the test description from "...linked access instructions" to
"...non-clickable access instructions" to reflect the contract.
## Verification
```
pnpm vitest run ui/src/pages/InviteLanding.test.tsx
```
Result: 8 / 8 pass, including the updated "shows the pending approval
page with the company icon and non-clickable access instructions" case.
Manual reproduction (master @ `242a2c2f`,
`deploymentMode=authenticated`, `bind=lan`, embedded Postgres):
1. As instance admin, generate a `company_join` invite that requires
admin approval.
2. In a fresh browser profile, open the invite link.
3. Fill **Create your account** and submit.
4. The "Request to join \<company\>" panel appears.
5. Hover the "Company Settings → Access" mentions — no underline, no
link cursor; clicking does nothing. The text is still readable and the
surrounding copy ("Ask them to visit ...") still conveys the instruction
to the requester.
Before / after screenshots: see issue #6784 — the "before" state lands
users on `/company/settings/access` which renders "No company access".
After this PR the guidance is informational only.
## Risks
Low. UI-only change confined to one function in `InviteLanding.tsx` plus
its matching test. No API contracts, routes, or data shapes are
modified. The removed `approvalUrl` constant was only referenced by the
two anchor elements.
## Model Used
- Anthropic Claude Opus 4.7 (`claude-opus-4-7`, 1M context, extended
thinking enabled).
- Tools: file editing, Bash, Playwright reproduction against a
self-hosted Paperclip instance running master @ `242a2c2f`, and the
Paperclip monorepo's own Vitest suite for verifying the test update.
## 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
- [ ] If this change affects the UI, I have included before/after
screenshots (will attach in PR thread)
- [x] I have updated relevant documentation to reflect my changes (no
docs files needed updating)
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
|
||
|
|
a3f583b5a9 |
build(deps-dev): bump @tailwindcss/vite from 4.3.0 to 4.3.3 (#9892)
Bumps [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite) from 4.3.0 to 4.3.3. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/tailwindlabs/tailwindcss/releases">@tailwindcss/vite's releases</a>.</em></p> <blockquote> <h2>v4.3.3</h2> <h3>Fixed</h3> <ul> <li>Support <code>--watch --poll[=ms]</code> in <code>@tailwindcss/cli</code> when filesystem events are unreliable or unavailable (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20297">#20297</a>)</li> <li>Canonicalization: match arbitrary hex colors against theme colors case-insensitively (e.g. <code>bg-[#fff]</code> and <code>bg-[#FFF]</code> → <code>bg-white</code>) (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20298">#20298</a>)</li> <li>Prevent Preflight from overriding Firefox's native <code>iframe:focus-visible</code> outline styles (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20292">#20292</a>)</li> <li>Ensure <code>theme('colors.foo')</code> in JS plugins resolves correctly when both <code>--color-foo</code> and <code>--color-foo-bar</code> exist (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20299">#20299</a>)</li> <li>Ensure fractional opacity modifiers work with named shadow sizes like <code>shadow-sm/12.5</code>, <code>text-shadow-sm/12.5</code>, <code>drop-shadow-sm/12.5</code>, and <code>inset-shadow-sm/12.5</code> (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20302">#20302</a>)</li> <li>Parse selectors like <code>[data-foo]div</code> as two selectors instead of one (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20303">#20303</a>)</li> <li>Ensure <code>@tailwindcss/postcss</code> rebuilds when a preprocessor like Sass changes the input CSS without changing the input file on disk (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20310">#20310</a>)</li> <li>Ensure CSS nesting is handled even when Lightning CSS isn't run, such as in <code>@tailwindcss/browser</code> and Tailwind Play (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20124">#20124</a>)</li> <li>Prevent achromatic theme colors from shifting hue when mixed in polar color spaces like <code>oklch</code> (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20314">#20314</a>)</li> <li>Ensure <code>--spacing(0)</code> is optimized to <code>0px</code> instead of <code>0</code> so it remains a <code><length></code> when used in <code>calc(…)</code> (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20319">#20319</a>)</li> <li>Load <code>@parcel/watcher</code> only when needed in <code>@tailwindcss/cli --watch</code> mode, so one-off builds and <code>--watch --poll</code> work when <code>@parcel/watcher</code> can't be loaded (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20325">#20325</a>)</li> <li>Use explicit platform fonts instead of <code>system-ui</code> and <code>ui-sans-serif</code> so CJK text respects the page's <code>lang</code> attribute on Windows (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20318">#20318</a>)</li> <li>Prevent <code>@tailwindcss/upgrade</code> from rewriting ignored files when run from a subdirectory (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20329">#20329</a>)</li> <li>Ensure earlier <code>@source</code> rules pointing to nested files are scanned when later <code>@source</code> rules point to files in parent folders (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20335">#20335</a>)</li> <li>Prevent <code>@tailwindcss/vite</code> from triggering full page reloads when scanned files are processed by Vite but haven't been loaded as modules yet (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20336">#20336</a>)</li> </ul> <h2>v4.3.2</h2> <h3>Fixed</h3> <ul> <li>Support bare spacing values for <code>auto-rows-*</code> and <code>auto-cols-*</code> utilities (e.g. <code>auto-rows-12</code> and <code>auto-cols-16</code>) (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20229">#20229</a>)</li> <li>Prevent <code>@tailwindcss/cli</code> in <code>--watch</code> mode from crashing on Windows when <code>@source</code> points to a directory that doesn't exist (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20242">#20242</a>)</li> <li>Prevent <code>@tailwindcss/vite</code> from crashing in Deno v2.8.x when <code>context.parentURL</code> is not a valid URL (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20245">#20245</a>)</li> <li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode rebuilds when the input CSS file changes in an ignored directory (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20246">#20246</a>)</li> <li>Allow <code>@variant</code> rules used in <code>addBase(…)</code> to use custom variants defined later (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20247">#20247</a>)</li> <li>Prevent <code>@tailwindcss/vite</code> from crashing during HMR when scanned files or directories are deleted (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20259">#20259</a>)</li> <li>Generate <code>font-size</code> instead of <code>color</code> declarations for <code>text-[--spacing(…)]</code> (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20260">#20260</a>)</li> <li>Prevent <code>@source</code> patterns from scanning unrelated sibling files and folders (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20263">#20263</a>)</li> <li>Extract class candidates adjacent to Template Toolkit delimiters like <code>%]…[%</code> in <code>.tt</code>, <code>.tt2</code>, and <code>.tx</code> files (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li> <li>Extract class candidates from conditional Maud syntax like <code>p.text-black[condition]</code> (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li> <li>Prevent <code>@position-try</code> rules from triggering unknown at-rule warnings when optimizing CSS (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20277">#20277</a>)</li> <li>Support class suggestions for named opacity modifiers from <code>--opacity</code> theme values (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20287">#20287</a>)</li> <li>Prevent type errors in <code>@tailwindcss/postcss</code> when used with newer PostCSS patch releases (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20289">#20289</a>)</li> </ul> <h2>v4.3.1</h2> <h3>Added</h3> <ul> <li>Add <code>--silent</code> option to suppress output in <code>@tailwindcss/cli</code> (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20100">#20100</a>)</li> </ul> <h3>Fixed</h3> <ul> <li>Remove deprecation warnings by using <code>Module#registerHooks</code> instead of <code>Module#register</code> on Node 26+ (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20028">#20028</a>)</li> <li>Canonicalization: don't crash when plugin utilities throw for unsupported values (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20052">#20052</a>)</li> <li>Allow <code>@apply</code> to be used with CSS mixins (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19427">#19427</a>)</li> <li>Ensure <code>not-*</code> correctly negates <code>@container</code> queries, including <code>style(…)</code> queries (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20059">#20059</a>)</li> <li>Ensure <code>drop-shadow-*</code> color utilities work with custom shadow values containing <code>calc(…)</code> (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20080">#20080</a>)</li> <li>Fix 'Sourcemap is likely to be incorrect' warnings when using <code>@tailwindcss/vite</code> (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20103">#20103</a>)</li> <li>Ensure <code>@tailwindcss/webpack</code> can be installed in Rspack projects without requiring <code>webpack</code> as a peer dependency (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20027">#20027</a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md">@tailwindcss/vite's changelog</a>.</em></p> <blockquote> <h2>[4.3.3] - 2026-07-16</h2> <h3>Fixed</h3> <ul> <li>Support <code>--watch --poll[=ms]</code> in <code>@tailwindcss/cli</code> when filesystem events are unreliable or unavailable (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20297">#20297</a>)</li> <li>Canonicalization: match arbitrary hex colors against theme colors case-insensitively (e.g. <code>bg-[#fff]</code> and <code>bg-[#FFF]</code> → <code>bg-white</code>) (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20298">#20298</a>)</li> <li>Prevent Preflight from overriding Firefox's native <code>iframe:focus-visible</code> outline styles (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20292">#20292</a>)</li> <li>Ensure <code>theme('colors.foo')</code> in JS plugins resolves correctly when both <code>--color-foo</code> and <code>--color-foo-bar</code> exist (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20299">#20299</a>)</li> <li>Ensure fractional opacity modifiers work with named shadow sizes like <code>shadow-sm/12.5</code>, <code>text-shadow-sm/12.5</code>, <code>drop-shadow-sm/12.5</code>, and <code>inset-shadow-sm/12.5</code> (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20302">#20302</a>)</li> <li>Parse selectors like <code>[data-foo]div</code> as two selectors instead of one (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20303">#20303</a>)</li> <li>Ensure <code>@tailwindcss/postcss</code> rebuilds when a preprocessor like Sass changes the input CSS without changing the input file on disk (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20310">#20310</a>)</li> <li>Ensure CSS nesting is handled even when Lightning CSS isn't run, such as in <code>@tailwindcss/browser</code> and Tailwind Play (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20124">#20124</a>)</li> <li>Prevent achromatic theme colors from shifting hue when mixed in polar color spaces like <code>oklch</code> (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20314">#20314</a>)</li> <li>Ensure <code>--spacing(0)</code> is optimized to <code>0px</code> instead of <code>0</code> so it remains a <code><length></code> when used in <code>calc(…)</code> (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20319">#20319</a>)</li> <li>Load <code>@parcel/watcher</code> only when needed in <code>@tailwindcss/cli --watch</code> mode, so one-off builds and <code>--watch --poll</code> work when <code>@parcel/watcher</code> can't be loaded (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20325">#20325</a>)</li> <li>Use explicit platform fonts instead of <code>system-ui</code> and <code>ui-sans-serif</code> so CJK text respects the page's <code>lang</code> attribute on Windows (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20318">#20318</a>)</li> <li>Prevent <code>@tailwindcss/upgrade</code> from rewriting ignored files when run from a subdirectory (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20329">#20329</a>)</li> <li>Ensure earlier <code>@source</code> rules pointing to nested files are scanned when later <code>@source</code> rules point to files in parent folders (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20335">#20335</a>)</li> <li>Prevent <code>@tailwindcss/vite</code> from triggering full page reloads when scanned files are processed by Vite but haven't been loaded as modules yet (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20336">#20336</a>)</li> </ul> <h2>[4.3.2] - 2026-06-26</h2> <h3>Fixed</h3> <ul> <li>Support bare spacing values for <code>auto-rows-*</code> and <code>auto-cols-*</code> utilities (e.g. <code>auto-rows-12</code> and <code>auto-cols-16</code>) (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20229">#20229</a>)</li> <li>Prevent <code>@tailwindcss/cli</code> in <code>--watch</code> mode from crashing on Windows when <code>@source</code> points to a directory that doesn't exist (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20242">#20242</a>)</li> <li>Prevent <code>@tailwindcss/vite</code> from crashing in Deno v2.8.x when <code>context.parentURL</code> is not a valid URL (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20245">#20245</a>)</li> <li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode rebuilds when the input CSS file changes in an ignored directory (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20246">#20246</a>)</li> <li>Allow <code>@variant</code> rules used in <code>addBase(…)</code> to use custom variants defined later (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20247">#20247</a>)</li> <li>Prevent <code>@tailwindcss/vite</code> from crashing during HMR when scanned files or directories are deleted (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20259">#20259</a>)</li> <li>Generate <code>font-size</code> instead of <code>color</code> declarations for <code>text-[--spacing(…)]</code> (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20260">#20260</a>)</li> <li>Prevent <code>@source</code> patterns from scanning unrelated sibling files and folders (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20263">#20263</a>)</li> <li>Extract class candidates adjacent to Template Toolkit delimiters like <code>%]…[%</code> in <code>.tt</code>, <code>.tt2</code>, and <code>.tx</code> files (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li> <li>Extract class candidates from conditional Maud syntax like <code>p.text-black[condition]</code> (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li> <li>Prevent <code>@position-try</code> rules from triggering unknown at-rule warnings when optimizing CSS (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20277">#20277</a>)</li> <li>Support class suggestions for named opacity modifiers from <code>--opacity</code> theme values (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20287">#20287</a>)</li> <li>Prevent type errors in <code>@tailwindcss/postcss</code> when used with newer PostCSS patch releases (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20289">#20289</a>)</li> </ul> <h2>[4.3.1] - 2026-06-12</h2> <h3>Added</h3> <ul> <li>Add <code>--silent</code> option to suppress output in <code>@tailwindcss/cli</code> (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20100">#20100</a>)</li> </ul> <h3>Fixed</h3> <ul> <li>Remove deprecation warnings by using <code>Module#registerHooks</code> instead of <code>Module#register</code> on Node 26+ (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20028">#20028</a>)</li> <li>Canonicalization: don't crash when plugin utilities throw for unsupported values (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20052">#20052</a>)</li> <li>Allow <code>@apply</code> to be used with CSS mixins (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19427">#19427</a>)</li> <li>Ensure <code>not-*</code> correctly negates <code>@container</code> queries, including <code>style(…)</code> queries (<a href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20059">#20059</a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/tailwindlabs/tailwindcss/commit/c2b24dd15fed1c59dd521bd86082f520c9f5ad0d"><code>c2b24dd</code></a> 4.3.3 (<a href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite/issues/20334">#20334</a>)</li> <li><a href="https://github.com/tailwindlabs/tailwindcss/commit/bdcd7087b332d263353d46ed366b7b08040ded7a"><code>bdcd708</code></a> Don't trigger a full page reload for scanned files that Vite processes as mod...</li> <li><a href="https://github.com/tailwindlabs/tailwindcss/commit/056a1550721d4bf79ff732d5ab9414fa83f7064f"><code>056a155</code></a> 4.3.2 (<a href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite/issues/20281">#20281</a>)</li> <li><a href="https://github.com/tailwindlabs/tailwindcss/commit/bb6a10937c7e1434db39919fbb4df4a8982dba7f"><code>bb6a109</code></a> use <code>.ts</code> instead of <code>.css</code></li> <li><a href="https://github.com/tailwindlabs/tailwindcss/commit/8a14a710102cae195f6811e8578bef9477bc6be9"><code>8a14a71</code></a> 4.3.1 (<a href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite/issues/20226">#20226</a>)</li> <li><a href="https://github.com/tailwindlabs/tailwindcss/commit/73983e1cf5bc0ae721f4568cc24a5b5067b6b90b"><code>73983e1</code></a> Fix 'Sourcemap is likely to be incorrect' warnings when using `@tailwindcss/v...</li> <li>See full diff in <a href="https://github.com/tailwindlabs/tailwindcss/commits/v4.3.3/packages/@tailwindcss-vite">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
34f5674cbe |
build(deps): bump react-i18next from 17.0.9 to 17.0.10 (#9889)
Bumps [react-i18next](https://github.com/i18next/react-i18next) from 17.0.9 to 17.0.10. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md">react-i18next's changelog</a>.</em></p> <blockquote> <h2>17.0.10</h2> <ul> <li>fix(warnings): the <code>useTranslation</code> and <code>Trans</code> "You will need to pass in an i18next instance" warnings now match the <code>useSSR</code> wording, mentioning the props/context alternatives and the most common unexplained cause at scale: duplicate react-i18next copies in monorepo setups. The <code>Trans</code> variant also referenced the internal <code>i18nextReactModule</code> name; it now points to the public <code>initReactI18next</code> API.</li> <li>feat(warnings): development-only warning (<code>SUSPENDED_WHILE_LOADING</code>, logged once) right before <code>useTranslation</code> suspends while translations are loading. With the default <code>useSuspense: true</code> and no <code><Suspense></code> boundary this previously surfaced as a blank screen or a cryptic React error; the warning now names both fixes (add a <code><Suspense></code> boundary or set <code>react.useSuspense: false</code>). No-op in production builds; the <code>process.env.NODE_ENV</code> check is wrapped so runtimes without a <code>process</code> global (raw ESM in the browser, some edge runtimes) stay silent instead of throwing.</li> <li>ci: weekly workflow typechecking the test suite against <code>@types/react@next</code> / <code>@types/react-dom@next</code>, so the next React major's type changes (like the React 18 <code>TFunctionResult</code>/children wave) surface before user reports.</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/i18next/react-i18next/commit/3b71c2766c2507781ccfb7b2b7a638b3ab339958"><code>3b71c27</code></a> 17.0.10</li> <li><a href="https://github.com/i18next/react-i18next/commit/57c3500e6a18764eb30ef433f0899ea781c99bad"><code>57c3500</code></a> build</li> <li><a href="https://github.com/i18next/react-i18next/commit/c62476f4d10d7a8d77d6eb5b70ece5c960c978a0"><code>c62476f</code></a> chore: sync package-lock with i18next ^26.2.0 devDependency bump</li> <li><a href="https://github.com/i18next/react-i18next/commit/0126bd1cada6bcf98aa764f32e9f17e5f690e431"><code>0126bd1</code></a> improve instance warnings (monorepo hint) + dev-only suspense warning + weekl...</li> <li>See full diff in <a href="https://github.com/i18next/react-i18next/compare/v17.0.9...v17.0.10">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
dc7f09be0d |
build(deps-dev): bump vitest from 4.1.8 to 4.1.10 (#9886)
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.1.8 to 4.1.10. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/vitest-dev/vitest/releases">vitest's releases</a>.</em></p> <blockquote> <h2>v4.1.10</h2> <h3> 🐞 Bug Fixes</h3> <ul> <li><strong>browser</strong>: Check fs access in builtin commands [backport to v4] - by <a href="https://github.com/hi-ogawa"><code>@hi-ogawa</code></a>, <strong>Hiroshi Ogawa</strong> and <strong>OpenCode (claude-opus-4-8)</strong> in <a href="https://redirect.github.com/vitest-dev/vitest/issues/10680">vitest-dev/vitest#10680</a> <a href="https://github.com/vitest-dev/vitest/commit/5c18dd267"><!-- raw HTML omitted -->(5c18d)<!-- raw HTML omitted --></a></li> <li><strong>vm</strong>: Fix external module resolve error with deps optimizer query for encoded URI [backport to v4] - by <a href="https://github.com/SveLil"><code>@SveLil</code></a> and <a href="https://github.com/hi-ogawa"><code>@hi-ogawa</code></a> in <a href="https://redirect.github.com/vitest-dev/vitest/issues/10661">vitest-dev/vitest#10661</a> <a href="https://github.com/vitest-dev/vitest/commit/bae52b511"><!-- raw HTML omitted -->(bae52)<!-- raw HTML omitted --></a></li> </ul> <h5> <a href="https://github.com/vitest-dev/vitest/compare/v4.1.9...v4.1.10">View changes on GitHub</a></h5> <h2>v4.1.9</h2> <h3>🐞 Bug Fixes</h3> <ul> <li>Fix <code>importOriginal</code> with optimizer and query import [backport to v4] - by <strong>Hiroshi Ogawa</strong>, <strong>David Harris</strong>, <strong>Codex</strong>and <strong>Vladimir</strong> in <a href="https://redirect.github.com/vitest-dev/vitest/issues/10546">vitest-dev/vitest#10546</a> <a href="https://github.com/vitest-dev/vitest/commit/a5180190c"><!-- raw HTML omitted -->(a5180)<!-- raw HTML omitted --></a></li> <li><strong>browser</strong>: <ul> <li>Wait for orchestrator readiness before resolving browser sessions [backport to v4] - by <strong>Vladimir</strong> and <strong>Séamus O'Connor</strong> in <a href="https://redirect.github.com/vitest-dev/vitest/issues/10555">vitest-dev/vitest#10555</a> <a href="https://github.com/vitest-dev/vitest/commit/7fb29651a"><!-- raw HTML omitted -->(7fb29)<!-- raw HTML omitted --></a></li> <li>Wait for iframe tester readiness before preparing [backport to v4] - by <strong>Vladimir</strong> and <strong>Séamus O'Connor</strong> in <a href="https://redirect.github.com/vitest-dev/vitest/issues/10497">vitest-dev/vitest#10497</a> and <a href="https://redirect.github.com/vitest-dev/vitest/issues/10556">vitest-dev/vitest#10556</a> <a href="https://github.com/vitest-dev/vitest/commit/fbc626c40"><!-- raw HTML omitted -->(fbc62)<!-- raw HTML omitted --></a></li> </ul> </li> <li><strong>mocker</strong>: <ul> <li>Hoist vi.mock() for vite-plus/test imports [backport to v4] - by <strong>Hiroshi Ogawa</strong>, <strong>LongYinan</strong>, <strong>Claude Opus 4.8</strong> and <strong>Vladimir</strong> in <a href="https://redirect.github.com/vitest-dev/vitest/issues/10548">vitest-dev/vitest#10548</a> <a href="https://github.com/vitest-dev/vitest/commit/2c9559c02"><!-- raw HTML omitted -->(2c955)<!-- raw HTML omitted --></a></li> </ul> </li> <li><strong>pool</strong>: <ul> <li>Prevent test run hang on worker crash [backport to v4] - by <strong>Ari Perkkiö</strong> and <strong>Jattioui Ismail</strong> in <a href="https://redirect.github.com/vitest-dev/vitest/issues/10543">vitest-dev/vitest#10543</a> and <a href="https://redirect.github.com/vitest-dev/vitest/issues/10564">vitest-dev/vitest#10564</a> <a href="https://github.com/vitest-dev/vitest/commit/934b0f587"><!-- raw HTML omitted -->(934b0)<!-- raw HTML omitted --></a></li> </ul> </li> </ul> <h5><a href="https://github.com/vitest-dev/vitest/compare/v4.1.8...v4.1.9">View changes on GitHub</a></h5> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/vitest-dev/vitest/commit/db616d227b6e0cb07a94f5d1bba262ee95db7e46"><code>db616d2</code></a> chore: release v4.1.10 (<a href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10718">#10718</a>)</li> <li><a href="https://github.com/vitest-dev/vitest/commit/bae52b5112a6fd8200101b88bf8af9685d077295"><code>bae52b5</code></a> fix(vm): fix external module resolve error with deps optimizer query for enco...</li> <li><a href="https://github.com/vitest-dev/vitest/commit/a7a61e78c7d0718f00173cff6800a91a344457d4"><code>a7a61e7</code></a> chore: release v4.1.9 (<a href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10598">#10598</a>)</li> <li><a href="https://github.com/vitest-dev/vitest/commit/934b0f587cb61d8338d83f525295322692a2db40"><code>934b0f5</code></a> fix(pool): prevent test run hang on worker crash (<a href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10543">#10543</a>) [backport to v4] (#...</li> <li><a href="https://github.com/vitest-dev/vitest/commit/7fb29651afbae2a9b0cefe6c031a9308f168ac60"><code>7fb2965</code></a> fix(browser): wait for orchestrator readiness before resolving browser sessio...</li> <li><a href="https://github.com/vitest-dev/vitest/commit/a5180190c1be7089e3705e3dd9e84fea118d09d3"><code>a518019</code></a> fix: fix <code>importOriginal</code> with optimizer and query import [backport to v4] (#...</li> <li>See full diff in <a href="https://github.com/vitest-dev/vitest/commits/v4.1.10/packages/vitest">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
e171e6f9e6 |
build(deps): bump react-router-dom from 7.16.0 to 7.18.1 (#9888)
Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 7.16.0 to 7.18.1. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/remix-run/react-router/blob/react-router-dom@7.18.1/packages/react-router-dom/CHANGELOG.md">react-router-dom's changelog</a>.</em></p> <blockquote> <h2>v7.18.1</h2> <h3>Patch Changes</h3> <ul> <li>Fix incorrect <code>package.json</code> <code>main</code> field for CommonJS builds (<a href="https://redirect.github.com/remix-run/react-router/pull/15238">#15238</a>)</li> <li>Updated dependencies: <ul> <li><a href="https://github.com/remix-run/react-router/releases/tag/react-router@7.18.1"><code>react-router@7.18.1</code></a></li> </ul> </li> </ul> <h2>v7.18.0</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies: <ul> <li><a href="https://github.com/remix-run/react-router/releases/tag/react-router@7.18.0"><code>react-router@7.18.0</code></a></li> </ul> </li> </ul> <h2>v7.17.0</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies: <ul> <li><a href="https://github.com/remix-run/react-router/releases/tag/react-router@7.17.0"><code>react-router@7.17.0</code></a></li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/remix-run/react-router/commit/afdf85d3c15448a41017514caca2aca038d3e9ca"><code>afdf85d</code></a> Release v7.18.1 (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom/issues/15253">#15253</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/2ecaa1ddbbcd583999dda46dd5413e907e8a46f3"><code>2ecaa1d</code></a> Fix react-router-dom main entry metadata (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom/issues/15238">#15238</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/6fb1e79f8304eddd8b78759edea83cb32389ebf5"><code>6fb1e79</code></a> Release v7.18.0 (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom/issues/15187">#15187</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/195a0d03c1417127ccee73853058c8521beb4fce"><code>195a0d0</code></a> Release v7.17.0 (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom/issues/15145">#15145</a>)</li> <li>See full diff in <a href="https://github.com/remix-run/react-router/commits/react-router-dom@7.18.1/packages/react-router-dom">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
8cdb3552b4 |
build(deps): bump @lexical/link from 0.46.0 to 0.48.0 (#9885)
Bumps [@lexical/link](https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link) from 0.46.0 to 0.48.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/facebook/lexical/releases">@lexical/link's releases</a>.</em></p> <blockquote> <p>v0.48.0 is a maintenance release focused on bug fixes across Markdown, tables, lists, links, and selection. It's headlined by a fix for a v0.46.0 regression that broke native text drag-and-drop (<a href="https://redirect.github.com/facebook/lexical/pull/8842">#8842</a>) and a couple of notable security hardening fixes. It also adds a handful of new features, including an <code>MdastHtmlExtension</code> with examples for authoring custom Markdown constructs (collapsibles, <code>kbd</code>, alerts, footnotes), a customizable Yjs shared-type root name for collaborative editing, and new table row manipulation helpers.</p> <h2>New APIs & Features</h2> <ul> <li><a href="https://lexical.dev/docs/api/modules/lexical_table"><code>@lexical/table</code></a> — Added <code>$moveTableRow</code> for reordering table rows, plus the previously missing <code>$unmergeCellNode</code> export (<a href="https://redirect.github.com/facebook/lexical/pull/8833">#8833</a>)</li> <li><a href="https://lexical.dev/docs/api/modules/lexical_yjs"><code>@lexical/yjs</code></a> / <a href="https://lexical.dev/docs/api/modules/lexical_react"><code>@lexical/react</code></a> — The Yjs shared-type root name is now customizable, so Lexical can share a Yjs document with other content that uses a different root key (<a href="https://redirect.github.com/facebook/lexical/pull/8841">#8841</a>)</li> <li><a href="https://lexical.dev/docs/api/modules/lexical_extension"><code>@lexical/extension</code></a> / <a href="https://lexical.dev/docs/api/modules/lexical_mdast"><code>@lexical/mdast</code></a> — Added <code>MdastHtmlExtension</code> and Markdown custom-construct examples (collapsible sections, <code>kbd</code>, alerts, footnotes) demonstrating how to extend the Markdown ↔ mdast pipeline. See the <a href="https://lexical.dev/docs/serialization/markdown-mdast">Markdown & mdast serialization guide</a> (<a href="https://redirect.github.com/facebook/lexical/pull/8826">#8826</a>)</li> </ul> <h2>Notable Fixes</h2> <p><strong>Drag & drop (fix for v0.46.0 regression)</strong></p> <ul> <li>Don't cancel <code>dragover</code> for text drags, so native drops work again (<a href="https://redirect.github.com/facebook/lexical/pull/8842">#8842</a>)</li> </ul> <p><strong>Security</strong></p> <ul> <li><code>LinkNode.sanitizeUrl()</code> now fails closed on unparseable URLs, preventing a potential XSS vector (<a href="https://redirect.github.com/facebook/lexical/pull/8846">#8846</a>)</li> <li>Fixed a <code>serialize-javascript</code> dependency vulnerability (<a href="https://redirect.github.com/facebook/lexical/pull/8803">#8803</a>)</li> </ul> <p><strong>Markdown & code</strong></p> <ul> <li>Roundtrip overlapping inline formats correctly through mdast/Markdown (<a href="https://redirect.github.com/facebook/lexical/pull/8825">#8825</a>)</li> <li>Force re-tokenization after an async language load so highlighting appears once the grammar is ready (<a href="https://redirect.github.com/facebook/lexical/pull/8830">#8830</a>)</li> </ul> <p><strong>Tables</strong></p> <ul> <li>Auto-scroll while drag-selecting cells past the visible edge (<a href="https://redirect.github.com/facebook/lexical/pull/8822">#8822</a>)</li> <li>Enable table copy in read-only mode (<a href="https://redirect.github.com/facebook/lexical/pull/8845">#8845</a>)</li> </ul> <p><strong>Lists & character limit</strong></p> <ul> <li>Backspace at the start of a list item now outdents or converts to a paragraph (<a href="https://redirect.github.com/facebook/lexical/pull/8829">#8829</a>)</li> <li>Merge adjacent <code>OverflowNode</code>s in <code>useCharacterLimit</code> (<a href="https://redirect.github.com/facebook/lexical/pull/8831">#8831</a>)</li> <li>Count block separators when wrapping character-limit overflow (<a href="https://redirect.github.com/facebook/lexical/pull/8840">#8840</a>)</li> </ul> <p><strong>Links & selection</strong></p> <ul> <li>Disable link opening for disabled autolinks (<a href="https://redirect.github.com/facebook/lexical/pull/8839">#8839</a>)</li> <li>Skip <code>scrollIntoViewIfNeeded</code> when the selection rect is above the editor, fixing a Safari RTL caret jump (<a href="https://redirect.github.com/facebook/lexical/pull/8848">#8848</a>)</li> </ul> <h2>What's Changed</h2> <ul> <li>[lexical-mdast][lexical-markdown] Bug Fix: Roundtrip overlapping inline formats by <a href="https://github.com/etrepum"><code>@etrepum</code></a> in <a href="https://redirect.github.com/facebook/lexical/pull/8825">facebook/lexical#8825</a></li> <li>[lexical-table][lexical-playground] Bug Fix: Auto-scroll while drag-selecting cells past the visible edge by <a href="https://github.com/JohnJunior"><code>@JohnJunior</code></a> in <a href="https://redirect.github.com/facebook/lexical/pull/8822">facebook/lexical#8822</a></li> <li>[lexical-code-shiki] Bug Fix: force re-tokenize after async language load by <a href="https://github.com/ochevallier"><code>@ochevallier</code></a> in <a href="https://redirect.github.com/facebook/lexical/pull/8830">facebook/lexical#8830</a></li> <li>[lexical-react] Bug Fix: Merge adjacent OverflowNodes in useCharacterLimit by <a href="https://github.com/mayrang"><code>@mayrang</code></a> in <a href="https://redirect.github.com/facebook/lexical/pull/8831">facebook/lexical#8831</a></li> <li>Open playground links in a new tab by <a href="https://github.com/potatowagon"><code>@potatowagon</code></a> in <a href="https://redirect.github.com/facebook/lexical/pull/8837">facebook/lexical#8837</a></li> <li>[lexical-rich-text][lexical-plain-text] Bug Fix: don't cancel dragover for text drags so native drops work again by <a href="https://github.com/etrepum"><code>@etrepum</code></a> in <a href="https://redirect.github.com/facebook/lexical/pull/8842">facebook/lexical#8842</a></li> <li>[lexical-link] Bug Fix: disable link opening for disabled autolink in… by <a href="https://github.com/ochevallier"><code>@ochevallier</code></a> in <a href="https://redirect.github.com/facebook/lexical/pull/8839">facebook/lexical#8839</a></li> <li>[lexical-table] Feature: Add $moveTableRow function & Add missing export for $unmergeCellNode by <a href="https://github.com/hamo-o"><code>@hamo-o</code></a> in <a href="https://redirect.github.com/facebook/lexical/pull/8833">facebook/lexical#8833</a></li> <li>[lexical-list] Bug Fix: Backspace at start of list item outdents or converts to paragraph by <a href="https://github.com/mayrang"><code>@mayrang</code></a> in <a href="https://redirect.github.com/facebook/lexical/pull/8829">facebook/lexical#8829</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/facebook/lexical/blob/main/CHANGELOG.md">@lexical/link's changelog</a>.</em></p> <blockquote> <h2>v0.48.0 (2026-07-16)</h2> <ul> <li>lexical-reactlexical-table Bug Fix Enable table copy in read-only mode (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8845">#8845</a>) mayrang</li> <li>lexical-extensionlexical-mdastdev-mdast-editor-example Feature Add MdastHtmlExtension and Markdown custom-construct examples (collapsible, kbd, alerts, footnotes) (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8826">#8826</a>) Bob Ippolito</li> <li>Fix fail closed in LinkNode.sanitizeUrl() on unparseable URLs (XSS) (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8846">#8846</a>) xiezhenjia-meta</li> <li>lexical Chore Fix serialize-javascript package dependency vulnerability (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8803">#8803</a>) vijay ojha</li> <li>lexical-react Bug Fix Count block separators in character limit overflow wrapping (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8840">#8840</a>) mayrang</li> <li>lexical-yjslexical-react Feature Customizable Yjs shared-type root name (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8841">#8841</a>) mayrang</li> <li>lexical-list Bug Fix Backspace at start of list item outdents or converts to paragraph (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8829">#8829</a>) mayrang</li> <li>lexical-table Feature Add moveTableRow function Add missing export for unmergeCellNode (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8833">#8833</a>)</li> <li>lexical-link Bug Fix disable link opening for disabled autolink in (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8839">#8839</a>) Olivier Chevallier</li> <li>lexical-rich-textlexical-plain-text Bug Fix dont cancel dragover for text drags so native drops work again (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8842">#8842</a>) Bob Ippolito</li> <li>Open playground links in a new tab (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8837">#8837</a>) Sherry</li> <li>lexical-react Bug Fix Merge adjacent OverflowNodes in useCharacterLimit (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8831">#8831</a>) mayrang</li> <li>lexical-code-shiki Bug Fix force re-tokenize after async language load (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8830">#8830</a>) Olivier Chevallier</li> <li>lexical-tablelexical-playground Bug Fix Auto-scroll while drag-selecting cells past the visible edge (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8822">#8822</a>) Oleksandr Trukhnii</li> <li>lexical-mdastlexical-markdown Bug Fix Roundtrip overlapping inline formats (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8825">#8825</a>) Bob Ippolito</li> <li>v0.47.0 (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8821">#8821</a>) Bob Ippolito</li> <li>v0.47.0 Lexical GitHub Actions Bot</li> </ul> <h2>v0.47.0 (2026-07-10)</h2> <ul> <li>lexicallexical-rich-text Bug Fix Fix formatText toggle direction and add SETTEXTFORMATCOMMAND (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8807">#8807</a>) mayrang</li> <li>scripts Bug Fix Let npm prompt for OTP when publishing bootstrap stubs (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8820">#8820</a>) Bob Ippolito</li> <li>lexical-playground Bug Fix Clear inline font-size when converting to heading (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8800">#8800</a>) mayrang</li> <li>lexical-tablelexical-playground Feature setTableRowIsHeader and setTableColumnIsHeader utilities (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8815">#8815</a>) mayrang</li> <li>lexical-website Documentation Update Rewrite testing guide (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8811">#8811</a>) mayrang</li> <li>lexical-mdastlexical-rich-text Feature lexicalmdast, a micromarkmdast-based alternative to lexicalmarkdown (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8794">#8794</a>) Bob Ippolito</li> <li>Make dependency-check resilient to transient registry errors (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8818">#8818</a>) Gerard Rovira</li> <li>lexical Refactor Move event module globals into per-editor InputState (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8809">#8809</a>) mayrang</li> <li>lexical Bug Fix getDocument() should fall back to the global document when there is no active editor (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8813">#8813</a>) Sherry</li> <li>lexical-playground Bug Fix Keep cell background color modal open on first click (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8806">#8806</a>) sahir</li> <li>lexical-playground Bug Fix Use consistent default maxWidth for markdown-imported images (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8810">#8810</a>) mayrang</li> <li>lexical-devtoolslexical-playground Chore Update flow, hermes, and babel packages to latest (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8795">#8795</a>) Bob Ippolito</li> <li>Add a 7-day pnpm minimumReleaseAge to match the Dependabot cooldown (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8808">#8808</a>) Gerard Rovira</li> <li>lexical Chore Fix tmp package dependency vulnerability (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8802">#8802</a>) vijay ojha</li> <li>lexical Chore Add missing Flow type declarations (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8799">#8799</a>) mayrang</li> <li>lexical-markdown Feature Add generateNodesFromMarkdownString (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8789">#8789</a>) mayrang</li> <li>lexicallexical-playground Chore Refactor IME composition test infrastructure and add browser-level coverage (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8793">#8793</a>) mayrang</li> <li>lexical-playground Bug Fix Use viewBox dimensions for unsized Excalidraw output (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8798">#8798</a>) mayrang</li> <li>lexical-table Bug Fix Export insertTableRowAtNode and insertTableColumnAtNode (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8791">#8791</a>)</li> <li>lexical-playgroundlexical-website Feature Add Vercel Analytics and Speed Insights (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8796">#8796</a>) Gerard Rovira</li> <li>lexicallexical-eslint-plugin Feature Add getDocument() API and Shadow DOM lint enforcement (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8788">#8788</a>) mayrang</li> <li>scripts Bug Fix strip misplaced pure annotations from prod builds (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8786">#8786</a>) Bob Ippolito</li> <li>lexical Bug Fix deleteCharacter overwrites X11 PRIMARY selection via Selection.modify (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8774">#8774</a>) Bob Ippolito</li> <li>lexical-playground Bug Fix Support Unicode URLs in autolink matcher (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8787">#8787</a>) mayrang</li> <li>lexical-table Feature Spread pasted TSV text across table cells (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8780">#8780</a>) mayrang</li> <li>Breaking Changelexical Bug Fix Preserve DOM element when composing on segmented TextNode middle (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8784">#8784</a>) mayrang</li> <li>Breaking Changelexical-reactlexical-devtools-core Chore Drop React 17 support, baseline is now React 18 (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8782">#8782</a>) Bob Ippolito</li> <li>lexical-playgroundlexical Feature Ruby annotation node with floating editor (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8741">#8741</a>) mayrang</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/facebook/lexical/commit/284b7491d014c412a11ecc8e4b8ea8e09e07f7e9"><code>284b749</code></a> v0.48.0</li> <li><a href="https://github.com/facebook/lexical/commit/365516c5fcdcc141561dcbb2eb43b707b48dd5b8"><code>365516c</code></a> Fix: fail closed in LinkNode.sanitizeUrl() on unparseable URLs (XSS) (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8846">#8846</a>)</li> <li><a href="https://github.com/facebook/lexical/commit/71562324c7d2154f64d79f6d20803f67b9bd9c11"><code>7156232</code></a> [lexical-link] Bug Fix: disable link opening for disabled autolink in… (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8839">#8839</a>)</li> <li><a href="https://github.com/facebook/lexical/commit/e4b7cc3f420226059c8aa30df6e89bd5fadbea90"><code>e4b7cc3</code></a> v0.47.0 (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8821">#8821</a>)</li> <li><a href="https://github.com/facebook/lexical/commit/a7666ab11f5e8c674a3f5ca8a83d2e92f1b171d0"><code>a7666ab</code></a> [*][lexical-devtools][lexical-playground] Chore: Update flow, hermes, and bab...</li> <li><a href="https://github.com/facebook/lexical/commit/e649ab28b7e2dd58c1b4798c446e611f54356518"><code>e649ab2</code></a> [lexical][lexical-eslint-plugin] Feature: Add $getDocument() API and Shadow D...</li> <li><a href="https://github.com/facebook/lexical/commit/7b76175cc96d99489c2f3c792db193cf2d9bc127"><code>7b76175</code></a> [lexical-playground] Bug Fix: Support Unicode URLs in autolink matcher (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8787">#8787</a>)</li> <li><a href="https://github.com/facebook/lexical/commit/62a4b30f382b4dc60cacd1a9d753a2d1f44d9f5e"><code>62a4b30</code></a> [lexical][*] Feature: registerEventListener / registerEventListeners DOM help...</li> <li><a href="https://github.com/facebook/lexical/commit/d04ea9e83609bcbdf729287010b6a297ee6a0ac5"><code>d04ea9e</code></a> [lexical-a11y][lexical-react][lexical-playground][lexical-website] Feature: @...</li> <li><a href="https://github.com/facebook/lexical/commit/51d47b77e852e646091ff5cb7675264fd9aa234e"><code>51d47b7</code></a> [lexical] Bug Fix: Clean up trailing shadow root after select-all delete (<a href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8751">#8751</a>)</li> <li>Additional commits viewable in <a href="https://github.com/facebook/lexical/commits/v0.48.0/packages/lexical-link">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
53d6297f75 |
fix(ui): simplify external object labels and star controls (#9929)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI agents and their work > - Operators rely on task detail properties and header actions to scan linked resources and make quick decisions > - External GitHub objects used a long pull-request label and repeated mention counts that added visual noise without adding state > - The task-detail star action also rendered as a labelled outline button, unlike the compact star controls used elsewhere > - These inconsistencies made dense task-detail surfaces slower to scan and broke Paperclip's content-first visual language > - This pull request shortens the GitHub pull-request label, removes duplicate mention-count decoration, and aligns the detail star action with the icon-only control pattern > - The benefit is a calmer, more consistent task-detail experience with accessible labels preserved for assistive technology ## Linked Issues or Issue Description No matching public GitHub issue or open pull request was found. **What happened?** On the task detail surface, linked GitHub pull requests were labelled `Github Pull Request` and could show a repeated `×N` mention count. The detail-header star control used a labelled outline button rather than the compact icon-only star pattern. **Expected behavior** Linked pull requests should use the concise `Github PR` label without duplicate mention-count decoration, and the detail star action should render as an accessible icon-only ghost button consistent with neighboring controls. **Steps to reproduce** 1. Open a task with a linked GitHub pull request mentioned more than once. 2. Inspect the external-object property label and value row. 3. Inspect the star action in the task detail header. **Paperclip version or commit:** `230126d80b` (`master` at preparation time) **Deployment / installation:** Local development, built from source. **Scope:** Core UI; not adapter-specific, database-related, or configuration-related. ## What Changed - Render GitHub pull-request property labels as `Github PR`. - Remove repeated external-object mention-count decoration from property values. - Render detail-header star controls as icon-only ghost buttons while preserving `aria-label`, pressed, busy, error, and tooltip states. - Expand component coverage for concise labels, duplicate-count suppression, visual variants, and accessible star actions. ## Verification - `pnpm --filter @paperclipai/ui exec vitest run src/components/IssueProperties.test.tsx src/components/StarToggle.test.tsx` — 54 tests passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Visual review (before/after plus normal, starred, pending, and error states): https://htmlpreview.github.io/?https://gist.githubusercontent.com/cryppadotta/9688862a8826c1134aa2b2e8c16509d8/raw/45cb4921851f8968b21e7490e0d705161a9e165d/star-toggle-review.html - `pnpm check:token-gates` — reports five existing `#9627` violations in files unchanged by this PR; the same values are present on `master`. ## Risks - Low risk: changes are limited to task-detail presentation and tests. - The star action remains fully accessible through its existing ARIA label and tooltip, but it no longer displays visible text. - External-object mention counts remain available in data; only the redundant property-row decoration is removed. > 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.3 Codex, tool-enabled coding agent with repository and shell 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
59eee4829c |
fix(inbox): stop archived items from resurfacing (#9931)
## Thinking Path > - Paperclip is the control plane operators use to coordinate AI-agent companies and review work needing attention. > - The Inbox is the operator-facing surface that aggregates tasks requiring attention across server state and shared client polling. > - Archiving a task optimistically removed it, but ordinary background activity and stale polling responses could make it reappear seconds later. > - The server therefore needs to distinguish genuine user-attention events from routine agent/system activity. > - The client also needs a bounded local archive guard across every Inbox query path while the server mutation and in-flight polls settle. > - This pull request fixes both resurrection paths and adds race-focused regression coverage. > - The benefit is stable archive behavior without hiding a genuine archive failure after reconciliation or reload. ## Linked Issues or Issue Description ### Pre-submission checklist - [x] Searched existing open and closed issues and pull requests; no duplicate implementation was found. - [x] Reproduced on `master` before this branch. - [x] Confirmed this is a Paperclip core bug, not adapter or provider behavior. ### What happened? Archiving an Inbox task hid it optimistically, then background refresh activity could insert it back into the list seconds later. ### Expected behavior A successfully archived task remains hidden during normal polling. A genuine failed archive may become visible again after reconciliation or reload. ### Steps to reproduce 1. Open Inbox with a visible task. 2. Archive the task. 3. Wait for shared polling or routine agent activity to refresh task data. 4. Observe the archived task reappear without a hard page refresh. ### Paperclip version or commit `master` before this branch. ### Deployment mode Built from source using the local development application. ### Installation method Built from source (`pnpm`). ### Agent adapter(s) involved Not adapter-specific; this is a core Inbox bug. ### Database mode Not database-mode-specific. ### Access context Board (human operator). ### Additional context The failure had independent server and client causes: routine activity could resurface archived rows server-side, while stale shared-poll responses could bypass optimistic client removal. ## What Changed - Restrict server-side Inbox resurfacing to explicit user-attention events rather than any issue activity write. - Add a bounded client-side archive guard with confirmation, failure restoration, and cache reconciliation behavior. - Apply the guard to Inbox rendering, badge counts, optimistic cache updates, and shared-poll result application. - Classify the generic compact Inbox query so stale shared-poll data cannot bypass the guard. - Add server visibility-matrix tests and UI race-condition regression tests. ## Verification - `pnpm --filter @paperclipai/ui exec vitest run src/hooks/useSharedPolling.test.ts src/lib/inboxArchiveCache.test.ts src/pages/Inbox.test.tsx` — 25 passed. - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/issues-service.test.ts` — 107 passed. - Branch rebased cleanly onto current `origin/master` before push. ## Risks - Low-to-moderate behavioral risk: resurfacing is intentionally narrower, so the server tests cover human comments, mentions, interactions, and status transitions that must still regain attention. - The client guard is bounded and cleared on mutation failure, limiting the risk of hiding a task whose archive did not persist. - No schema, migration, public API, workflow, dependency-lock, or visual-token changes. > 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 - Anthropic Claude via Claude Code (`claude_local`; prior implementation/review run, exact underlying model ID and context window were not retained in the handoff metadata), with repository tool use and test execution. - OpenAI `gpt-5.5` via Codex CLI for final review repair and PR preparation, with reasoning, repository editing, GitHub tooling, and code execution. ## 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 searched GitHub for duplicate or related PRs and linked/described the result above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change and contains no internal Paperclip task identifier - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation where needed; no documentation change is required for this bug fix - [x] I have considered and documented risks above - [x] All Paperclip-authored commits include the required co-author trailer --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
26890650b2 |
test(ui): cover secret creation within folders (#9927)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Secrets UI lets operators navigate slash-delimited secret names as folders > - PR #9913 shipped create-in-folder behavior for company and per-user secrets > - The production behavior is already on master, but several create-in-folder interaction paths lack retained regression coverage there > - Without that coverage, prefix composition, derived keys, prefix removal, and staged empty folders could regress unnoticed > - This pull request adds focused render tests without changing production behavior > - The benefit is safer maintenance of the folder-based secrets workflow with a small, reviewable patch ## Linked Issues or Issue Description - Refs #9913 ## What Changed - Added render coverage for creating a company secret from a folder and deriving its key from the full slash-delimited name. - Added coverage for per-user secret prefixes and exposing the full name when the prefix chip is removed. - Added coverage for inline folder-name validation and URL-backed staging of an empty folder. ## Verification - `env -u PAPERCLIP_IN_WORKTREE -u PAPERCLIP_WORKTREE_NAME -u PAPERCLIP_CONFIG -u PAPERCLIP_HOME -u PAPERCLIP_INSTANCE_ID -u PAPERCLIP_CONTEXT pnpm exec vitest run ui/src/pages/Secrets.render.test.tsx` — 29 tests passed. - `pnpm check:token-gates` — reports five existing `#9627` literals in unrelated files; this PR changes no token-gated component code and introduces no new violation. ## Risks - Low risk: test-only change with no production, API, schema, migration, dependency, or runtime behavior changes. - The tests exercise existing DOM interactions and may need updates if the Secrets creation UI copy or controls intentionally change. > 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 CLI managed coding agent with repository inspection, code execution, Git/GitHub, and Paperclip API tools. The managed harness does not expose the exact underlying model ID or context-window size. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details — the assigned execution branch name is fixed by the task - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes — no documentation change is needed for test-only coverage - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
b9f4073a13 |
fix(ui): use searchable agent picker for secret access (#9918)
## Thinking Path > - Paperclip is the control plane people use to manage AI-agent companies. > - Operators need to grant secrets to specific agents safely and efficiently. > - The secrets access sheet previously used a native select while similar agent-assignment surfaces use a searchable picker. > - That inconsistency makes finding an agent slow and error-prone as companies grow. > - This pull request reuses the shared agent picker behavior for single-agent secret access grants. > - The benefit is a consistent, searchable selection experience without changing secret-access semantics. ## Linked Issues or Issue Description Refs #9797 **Problem / motivation:** The in-sheet agent access form introduced in #9797 renders every grantable agent in a native select. In companies with many agents, operators cannot filter by name or title and the experience differs from other agent-selection surfaces. **Proposed solution:** Add a single-select variant beside the existing `AgentMultiSelect`, then use it in the secret access grant form. **Alternatives considered:** Keeping a native select would preserve less code but would not scale or align with existing searchable agent selection. **Roadmap alignment:** This is a focused usability fix for an existing core control-plane surface and does not overlap an unstarted roadmap initiative. ## What Changed - Added `AgentSelect`, a searchable single-agent popover that filters by agent name and title. - Replaced the secret access form's native select with the shared searchable picker. - Added focused coverage for filtering, selecting, callback behavior, and popover closure. ## Verification - `pnpm exec vitest run ui/src/components/AgentMultiSelect.test.tsx` — passes (3 tests). - `pnpm --filter @paperclipai/ui typecheck` — passes. - `pnpm check:token-gates` — branch adds no violations; the command currently fails on five unchanged `#9627` literals already present on `master`. - Manual: open Secrets, choose a secret, add agent access, filter by agent name or title, select the result, and grant access. ## Risks - Low risk: the change is limited to agent selection UI and preserves the existing grant request payload. - The new picker depends on the existing popover/input primitives and resets its filter when closed. > 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-series coding agent (exact runtime model ID and context-window size are not exposed), with reasoning, repository tool use, terminal execution, and GitHub CLI capabilities. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
b94907f8af |
feat(ui): navigate slash-named secrets as folders (#9913)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Operators store company and user secrets under human-readable names > - Slash-delimited names already express useful hierarchy, but the Secrets page previously rendered them as one flat list > - Large secret collections therefore became harder to scan, navigate, and create within consistently named groups > - A client-derived folder model preserves the existing server contract while making those names navigable > - This pull request adds folder browsing, URL-addressable paths, global search, and create-in-folder behavior without adding folder records > - The benefit is a more scalable secrets workflow with no migration or API compatibility risk ## Linked Issues or Issue Description Slash-delimited secret names such as `dev/github/oauth/clientid` currently appear as raw flat rows. This change treats name prefixes as client-side navigation folders on the main Secrets tab while leaving stored names, API contracts, validation, and the database unchanged. - Wireframes and interaction specification: https://pages.paperclip.ing/pap-14698-secrets-folders/ - Folder paths are derived only from secret names; there is no server-side folder entity or data-model change. ## What Changed - Added pure secret-path utilities for normalized segments, breadcrumbs, nested folder listings, counts, and leaf/path rendering. - Added a Folders/Flat view to the main Secrets tab with folder-first sorting, breadcrumbs, empty-folder states, filters, and global search results. - Added URL navigation through `?path=<normalized/path>` so deep links, reload, browser Back, and new-tab folder navigation work. - Persisted the preferred view in `localStorage` under `paperclip.secrets.viewMode`; an explicit `?path=` deep link takes precedence for that visit. - Added create-in-folder behavior with a removable prefix chip, staged New folder paths, inline segment validation, and full-name key derivation. - Kept My secrets flat while rendering slash-delimited names with muted paths and emphasized leaves. - Added unit/render coverage for path helpers, folder navigation, and create-in-folder behavior. ## Verification - `pnpm exec vitest run ui/src/pages/secrets/secret-path.test.ts ui/src/pages/Secrets.render.test.tsx` — 35 tests passed. - `pnpm -r typecheck` — passed. - `pnpm test:run` — server suite passed 2,707 tests and UI suite passed 3,022 tests; one unrelated CLI doctor test was environment-sensitive because this agent inherited AWS variables. - `env -u AWS_PROFILE -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY -u AWS_SESSION_TOKEN -u AWS_REGION -u AWS_DEFAULT_REGION pnpm exec vitest run cli/src/__tests__/secrets.test.ts` — 8 tests passed. - `pnpm build` — passed. - `pnpm check:token-gates` — feature files are clean; the command reports five existing `#9627` color literals outside this diff. ## Risks - Low data risk: folders are derived client-side from existing names, with no schema, migration, API, or stored-name changes. - URL behavior changes only the main Secrets tab and uses the additive `?path=` contract. - View preference is browser-local and scoped to the `paperclip.secrets.viewMode` key. - Renaming or deleting the last secret under an open prefix intentionally leaves the user on an empty-folder state instead of redirecting. - “Move to folder…” bulk prefix rename remains deferred because it is a multi-secret mutation with separate conflict and partial-failure semantics. > 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 `gpt-5.5` via Codex CLI for PR preparation, verification, GitHub/Paperclip tool use, and codebase analysis; the managed harness does not expose the active context-window size. - Anthropic Claude Opus 4.8 (1M context) and Claude Fable 5 assisted earlier implementation/design commits, as recorded in their commit trailers; both used repository and code-editing tools. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details — the assigned shared execution branch name is fixed for this work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
f12bb27bcd |
feat: make issue monitors visible across task surfaces (#9783)
## Thinking Path > - Paperclip is the open source control plane people use to supervise AI-agent companies. > - Operators need task execution state to be visible where they read, reply to, and manage an issue. > - Scheduled monitor state was easy to miss because it lived in a description-area card and used inconsistent, mostly static time copy. > - The task page, composer, retry card, and properties panel therefore needed one shared monitor-state and countdown language. > - This pull request adds shared live-ticking time utilities, moves monitor status into a top-of-page banner and composer strip, and redesigns the properties row with complete read-only details. > - The benefit is that operators can immediately understand when an agent resumes, why it is waiting, and how to act without hunting across the page. ## Linked Issues or Issue Description Issue monitors can schedule a future agent check, retry, or wake, but the UI did not present that state consistently or prominently. The existing description-area activity card competed with issue content, the composer did not explain that replying wakes the agent early, compact properties copy truncated important details, and relative times did not share a live two-unit formatter. This change makes scheduled monitor state visible and consistent across the issue header, reply composer, properties panel, and scheduled-retry card. Related prior server-side recovery visibility work: #9629 (distinct scope). ## What Changed - Added shared two-unit monitor ETA/offset formatters and a live-ticking countdown hook, including compact absolute-time rules for Today, weekday, and cross-year dates. - Replaced the description-area monitor activity card with a top-of-page status banner and added an inline composer strip that explains replies wake the agent before the scheduled check. - Redesigned the properties Monitor row as readable two-line copy with attempt state, due/overdue/cleared wording, click-to-edit behavior, and a hover/tap details tooltip. - Adopted the shared two-unit formatting in the scheduled-retry card and added focused coverage for monitor formatting, state transitions, visibility, and controls. - Added the approved wireframe package and published reference: https://pages.paperclip.ing/pap-14557-monitor-visibility/ ## Verification - `pnpm vitest run ui/src/lib/issue-monitor.test.tsx ui/src/components/IssueMonitorBanner.test.tsx ui/src/components/IssueProperties.test.tsx` — 3 files, 74 tests passed. - `pnpm -r typecheck` — passed. - `pnpm build` — passed with existing Vite optimization/chunk-size warnings. - UX review approved the rendered real components across desktop/mobile, light/dark, and the scheduled/retrying/due/overdue/cleared/none state matrix. - QA passed 6/6 criteria in Chromium, including a live countdown transition without refresh. Review evidence included the P2 banner state-matrix screenshot and the P3 properties-row and details-tooltip screenshots, plus a dark-mode capture. - `pnpm check:token-gates` currently reports five pre-existing `#9627` comment literals on `origin/master`; this branch introduces none of those literals or any new token violation. ## Risks - Low-to-moderate UI behavior risk: monitor copy and placement change across several issue surfaces, but all derive from one shared state builder and focused tests cover the state matrix. - Countdown rendering wakes once per minute while a visible monitor is scheduled; the hook is limited to active monitor surfaces and stops when hidden. - No database, API contract, migration, telemetry, or authorization behavior changes. > 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.6-sol`; context-window metadata was unavailable in this runtime; reasoning, repository tool use, command execution, and test execution enabled. Earlier implementation commits were assisted by Claude Fable 5 and Claude Opus 4.8 (1M context), as credited in their commit trailers. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
67616dd7ea |
Rework secrets dialog and add in-sheet agent access (#9797)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI agents and the credentials those agents need for work. > - The secrets UI is responsible for making credential creation understandable and for showing where credentials are used. > - The create flow previously exposed an editable generated key too early, used an unnatural field order, and rendered uneven provider tab rows. > - The detail sheet also lacked an in-context way to see and manage which agents reference a selected secret. > - This pull request makes the create dialog follow a predictable name-to-value flow and adds agent access management directly to the secret details sheet. > - The benefit is a clearer secrets workflow with fewer accidental key edits and less navigation when granting or revoking agent access. ## Linked Issues or Issue Description **Subsystem affected:** `ui/` — React + Vite board UI **Problem or motivation:** Creating a secret currently makes its generated key look immediately editable, places fields in an awkward keyboard order, and applies provider-tab overrides that produce uneven rows. After creation, operators cannot inspect or change agent access from the selected secret's detail sheet. **Proposed solution:** Generate the key from the path-style name and keep it read-only until an explicit Edit action; place Value directly after Name; use the standard tab sizing; and add an Agent access section that reads and updates `secret_ref` / `user_secret_ref` environment bindings through agent adapter configuration. **Alternatives considered:** Keeping access management only on agent configuration screens was rejected because it hides a secret-centric question—“which agents can use this?”—and requires repetitive navigation. Keeping the key always editable was rejected because the generated value should be the safe default. **Roadmap alignment:** No matching item was found in `ROADMAP.md`; this is a focused usability and access-management improvement to the existing secrets surface. **Additional context:** GitHub search found no duplicate PR for this dialog and in-sheet access change. PR #9321 also mentions user-secret resolution but addresses unrelated skills-route behavior. ## What Changed - Auto-generate the create-secret key from Name, keep it read-only by default, and expose an explicit Edit action. - Use a path-style Name placeholder (`/dev/foo/bar`) and place Value immediately after Name for natural keyboard navigation. - Remove tab sizing/whitespace overrides that caused uneven provider-tab row heights. - Add an Agent access section to the Details tab that lists referencing agents and grants or revokes `secret_ref` / `user_secret_ref` environment bindings in place. - Cover company secrets and each-user definitions with focused render tests. ## Verification - `pnpm exec vitest run ui/src/pages/Secrets.render.test.tsx` — 17/17 passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - `pnpm check:token-gates` — changed files are clean; the repository-wide command currently reports five pre-existing `#9627` violations in unrelated files (`Sidebar.tsx`, `Inbox.tsx`, `IssueDetail.tsx`, `Issues.tsx`, and `Routines.tsx`). - Additional secrets verification completed during implementation: 35/35 adjacent secrets tests passed, and the flow was checked in a real browser in light and dark themes. ## Risks - Agent access mutations update adapter environment configuration, so malformed legacy env entries could affect how a binding is displayed or revoked. - Each-user definitions use `user_secret_ref` rather than `secret_ref`; focused tests cover selecting the correct binding type. - No database or API contract changes 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 - Anthropic Claude Fable 5 assisted with the implementation using repository-aware code editing and test execution. - OpenAI GPT-5.5 via Codex CLI assisted with PR preparation, branch hygiene, focused verification, GitHub operations, and review/check loops. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
83765f08d1 |
fix(ui): reap React 19.2 performance-track measures (memory leak) (#9827)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Its web UI is a long-lived single-page app; users leave tabs open for hours/days > - We chased multi-GB tab memory growth through several fixes (#9569, #9624, #9627, #9701) that cut real churn — but the footprint kept climbing > - A heap-snapshot diff on a 12-hour tab finally showed the true cause: of 13.2M heap nodes, **12.1M were `PerformanceMeasure` objects** — React 19.2 emits a `performance.measure()` per component render for its DevTools "Performance Tracks" and never clears them > - These are native objects, so `performance.memory` never reported them (it read a flat ~74 MB while the real heap was ~308 MB), which is why our earlier heap/DOM sampling looked stable while the footprint ballooned > - This pull request periodically clears the User Timing measure buffer, since nothing in the app consumes it > - The benefit is that long-lived tabs stop accumulating millions of native `PerformanceMeasure` objects, eliminating the remaining unbounded growth ## Linked Issues or Issue Description No public GitHub issue exists; describing inline per CONTRIBUTING.md → "Link Issues or Describe Them In-PR", following the bug report template. This is the root-cause fix for the memory growth chased in #9569 / #9624 / #9627 / #9701. **What happened?** Long-lived browser tabs grew to multiple GB of memory footprint over hours/days. A heap snapshot of a 12h tab showed **13.2M nodes, of which 12.1M were `PerformanceMeasure`** (vs ~1.0M total nodes on a fresh tab). Live capture showed **~340 `performance.measure()` calls/sec**, named after React components with a `detail.devtools` payload — React 19.2's "Performance Tracks". Nothing ever clears them, so they accumulate without bound. **Expected behavior** A long-lived tab should not accumulate millions of `PerformanceMeasure` entries. Idle/long-running tabs should hold a bounded footprint. **Steps to reproduce** Open the app (React 19.2 production build), leave a tab open with normal activity, and run `performance.getEntriesByType('measure').length` periodically — it climbs unbounded (12.3M after ~12h). `performance.clearMeasures()` drops it to near-zero and frees the memory. **Paperclip version or commit** Branch `fix/react-perf-measure-leak`, off `master` (after #9701). **Deployment mode** Local dev (`pnpm dev` build served by the dev instance), web UI. React 19.2.7. Not adapter-specific. ## What Changed - **`ui/src/lib/perf-measure-reaper.ts` (new)** — `startPerfMeasureReaper(intervalMs = 10_000)` clears `performance.clearMeasures()` on a timer and returns a stop function. It never calls `getEntriesByType('measure')` (which would materialize the huge buffer). Honors a `window.__paperclipKeepPerfMeasures = true` opt-out so a developer recording a React Performance Track in DevTools can keep the entries. - **`ui/src/main.tsx`** — start the reaper at app boot. - Only *measures* are cleared — React's tracks pass explicit start/end times and leave no marks, and the app doesn't use the User Timing API at all (verified), so nothing else is affected. ## Verification - **Root cause proven** by heap-snapshot diff: fresh tab ~1.0M nodes vs 12h tab 13.2M nodes, 12.1M of them `PerformanceMeasure`; live capture showed ~340 measures/sec with `detail.devtools` and React component names. - **Fix proven live**: `performance.clearMeasures()` on the aged tab dropped the buffer from **12,418,266 → 1,500** and reclaimed the memory (heap `perf.memory` 308 → 269 MB, plus the ~12M native objects, which are the bulk of the footprint). - `vitest`: `perf-measure-reaper.test.ts` — interval clearing, `stop()`, opt-out flag, and no-API no-op. All pass. - `tsc -b` clean. ## Risks Very low, client-only. - Clearing the User Timing measure buffer only affects the DevTools Performance panel's React track *history*; normal users never consume it. Developers who want to record it can set `window.__paperclipKeepPerfMeasures = true`. - Only `performance.clearMeasures()` is called (not `clearMarks`), so any mark-based timing elsewhere is untouched; a grep confirmed the app makes no `performance.mark()/measure()` calls of its own. - Adds exactly one 10s interval (negligible), and `clearMeasures()` does not materialize the buffer. Note: this is a React 19.2 upstream behavior (its performance tracks are emitted in the production build and never cleared). If React later gates or clears them, this reaper can be removed. ## Model Used - **Provider:** Anthropic, via the Claude Code CLI. - **Model:** Claude Opus 4.8 (`claude-opus-4-8`). - **Reasoning mode:** Extended thinking enabled. - **Capabilities used:** tool use (shell, file editing), the Chrome DevTools MCP to reproduce and profile, and a streaming heap-snapshot parser to identify the `PerformanceMeasure` accumulation. ## 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 searched GitHub for duplicate or related PRs and linked them above (continues #9701; no duplicates) - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have considered and documented any risks above - [ ] I have updated relevant documentation to reflect my changes (N/A — no user-facing docs; rationale documented inline) - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
051ae4d102 |
feat: restore decision training library and inspector (#9779)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI-agent companies and supervise governed work. > - Decisions capture high-value operator judgment, and the decision-training foundation merged in #9702 freezes that evidence for later evaluation and learning. > - Operators still need the UI from the closed stacked PR #9718 to intentionally capture examples and inspect the resulting dataset. > - GitHub automatically closed #9718 when its stacked base branch was deleted after #9702 merged, leaving the server foundation on `master` without the corresponding UI. > - This pull request restores the final UI and its still-required supporting API fields directly on current `master`, while excluding the obsolete migration and duplicated server-foundation diffs. > - The benefit is a reviewable replacement PR that preserves the completed decision-training workflow without replaying stale stack history. ## Linked Issues or Issue Description - Refs #9718 - Refs #9702 ## What Changed - Restored the top-level `/training` library and record inspector with search, filters, JSONL export, notes editing, and evidence tabs. - Restored the Decisions-row training affordance and capture drawer, including preview, provenance, deletion, cache refresh, and approval consistency behavior. - Restored the shared types and focused server support needed by the UI without reintroducing decision-training migrations or the already-merged server foundation. - Restored focused UI and attention-service tests from the final #9718 state. - Credit to the authors and reviewers of #9718; this recovery transplants their final reviewed delta after the stacked base deletion. ## Verification - `pnpm exec vitest run ui/src/pages/Training.test.tsx ui/src/components/DecisionTrainingDrawer.test.tsx ui/src/components/AttentionQueueRow.test.tsx server/src/__tests__/attention-service.test.ts server/src/__tests__/decision-training.test.ts` — 5 files, 48 tests passed. - `pnpm --filter @paperclipai/shared typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - `pnpm exec vitest run server/src/__tests__/openapi-routes.test.ts` — 3 tests passed; confirms exact route/OpenAPI parity for the restored preview endpoint. - `pnpm check:token-gates` — the restored files are clean; the repository-wide command currently reports five pre-existing false positives where comments reference GitHub issue `#9627` as if it were a color literal. ## Risks - Low migration risk: this PR contains no database migrations and is based directly on current `master`. - The main behavioral risk is cache invalidation across Decisions and Training views; focused tests cover capture, update, deletion, row state, and approval refresh behavior. - The token-gate baseline remains red on unrelated `#9627` comment references; this PR does not modify those files. > 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.3-Codex, reasoning with repository/tool access and code execution. Context window 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 checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
a090c09ee5 |
feat: add decision training snapshot foundation (#9702)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI-agent companies and their work > - Human approvals, issue interactions, and execution decisions already capture high-value decision moments > - Those moments are currently transient and cannot be reused as stable evaluation or training examples > - Reusable examples need a server-owned, immutable snapshot so later comments or runs cannot leak into the recorded state > - Human notes need to remain editable and auditable without changing the captured state > - This pull request adds the database model, snapshot capture service, API, export format, and attention-feed enrichment for decision training > - The benefit is a durable, inspectable foundation for evaluating whether agents can reproduce good human decisions from only the context available at decision time ## Linked Issues or Issue Description ### Subsystem affected Cross-cutting (`server/`, `packages/db`, and `packages/shared`). ### Problem or motivation Paperclip has no durable dataset for converting human decisions into evaluation-ready examples. Teams need to capture pending or resolved decisions with the exact issue context, comments, runs, and repository evidence available at a cutoff, while preventing future context from leaking into the example. ### Proposed solution Store immutable, schema-versioned snapshots anchored to durable interaction, approval, or execution-decision records; keep notes separately editable with history; expose human-only CRUD, list, and JSONL export APIs. ### Alternatives considered Client-generated snapshots were rejected because they duplicate cutoff logic and cannot reliably enforce no-leakage boundaries. Automatic outcome backfill was deferred so captured examples remain faithful to what was known at capture time. ### Roadmap alignment Supports the roadmap direction of turning completed work and decision patterns into reusable organizational knowledge. ### Additional context The implementation records explicit commit-resolution confidence (`exact`, `nearest_run`, `workspace`, or `none`) so downstream evaluation can distinguish evidence quality. ## What Changed - Added the `decision_training_examples` schema and idempotent migration with company, issue, and source/author indexes. - Added shared types for decision-training records, notes history, and versioned snapshots. - Added a single server-side snapshot capture path with inclusive comment cutoffs, pre-cutoff run capture, durable decision payloads, and explicit commit-resolution confidence. - Added create, list, detail, notes-only update, delete, and JSONL export routes with human-only write authorization and activity logging that skips no-op note submissions. - Added per-user `trainingExampleId` enrichment to attention items. - Added focused embedded-Postgres tests for cutoff boundaries, post-cutoff leakage, immutable snapshots, human-only writes, duplicate prevention, notes history, attention enrichment, and export shape. - Updated UI test and Storybook attention-item factories for the new required `trainingExampleId` contract. ## Verification - `pnpm exec vitest run server/src/__tests__/decision-training.test.ts` — 10 tests passed. - `pnpm --filter @paperclipai/db typecheck` — passed, including migration numbering and safety checks. - `pnpm --filter @paperclipai/shared typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. ## Risks - The migration adds a new table and indexes only; it does not rewrite existing rows or install resolve-time hooks. - Snapshot JSON can grow with long comment threads and run histories; v1 intentionally favors complete, inspectable examples over aggressive truncation. - Commit SHA resolution is evidence-based and records `exact`, `nearest_run`, or `none` so downstream consumers can account for confidence. - The API is additive, but future UI work must continue to treat the snapshot as immutable and use notes-only updates. > 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 using `gpt-5.3-codex`, with repository tool use, terminal execution, and code-editing capabilities; context-window size is 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 checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
1f1f545238 |
feat: add built-in summarizer and summary slots (#9713)
## Thinking Path > - Paperclip is the open source control plane people use to organize, govern, and understand AI-agent work > - Operators need concise, current status views across projects and execution workspaces without manually reading every issue and run > - Paperclip already has auditable issues, documents, built-in agents, routines, and live run events, but no first-class summary-slot workflow connecting those systems > - A built-in Summarizer can generate status prose through ordinary governed tasks while summary slots provide stable, revisioned destinations for that output > - The UI needs to show current summaries, generation progress, failures, revisions, and streaming draft status in the places operators already work > - This pull request adds the end-to-end summary-slot data, API, agent, orchestration, and UI surfaces behind an experimental setting > - The benefit is decision-oriented status context that remains company-scoped, auditable, retryable, and inexpensive by default ## Linked Issues or Issue Description No public GitHub issue exists for this feature. **Problem** Operators currently have to reconstruct project and workspace status by reading many issues, runs, and comments. This makes it hard to identify decisions, review queues, recent work, and the next event worth watching. **Proposed capability** Add an experimental summary system with revisioned summary slots for projects and workspaces, a paused-by-default built-in Summarizer agent, governed generation tasks, live draft status, and reusable UI cards. **Expected behavior** - Summary data remains company-scoped and revisions remain auditable. - Generation runs through normal issue/agent orchestration and deduplicates active requests. - Only the linked built-in Summarizer generation task can author a slot revision. - Operators can generate, retry, inspect revisions, and follow draft progress from project and workspace views. - The feature remains opt-in and background generation remains paused by default. ## What Changed - Added summary-slot schema, idempotent migrations, shared contracts, validators, API paths, and service tests. - Added company-scoped summary-slot routes for reading revisions, requesting generation, and guarded Summarizer writes with activity logging. - Added terminal generation finalization, failure reasons, assignment wakeups, and orchestration integration. - Added the paused-by-default built-in Summarizer bundle, low-cost runtime defaults, status-summarization skill, and stale-summary routine. - Added summary cards, revision selection, retry/configuration states, live draft streaming, transcript chunk handling, and project/workspace integrations. - Updated Claude local parsing for streamed status output and expanded server, adapter, shared, database, catalog, and UI coverage. ## Verification - `pnpm -r typecheck` - `pnpm exec vitest run packages/db/src/summary-slots-schema.test.ts packages/shared/src/summary-slot.test.ts server/src/__tests__/summary-slot-routes.test.ts server/src/__tests__/summary-slots.test.ts server/src/__tests__/built-in-agents.test.ts ui/src/components/SummarySlotCard.test.tsx ui/src/components/SummarySlotCard.status.test.tsx ui/src/components/useSummaryDraftStream.test.tsx ui/src/lib/summary-draft-stream.test.ts ui/src/lib/run-log-chunks.test.ts ui/src/context/LiveUpdatesProvider.hook.test.tsx` — 113 tests passed - `pnpm test:run` — server and UI suites passed; one CLI AWS doctor test was affected by inherited `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY`, and passed when those host credentials were removed - `pnpm exec vitest run cli/src/__tests__/secrets.test.ts` with inherited AWS credential variables removed — 8 tests passed - `pnpm build` - `pnpm check:token-gates` currently reports nine `#9627` comment references introduced by current `master`; none are in this PR diff ## Risks - Database risk is limited by incrementally ordered, idempotent migrations and migration safety checks. - Summary generation creates normal issues/runs, so misconfiguration can produce failed slots; the UI exposes retryable failure reasons and agent configuration entry points. - Streaming draft parsing depends on the documented `STATUS:` protocol; final persisted revisions remain the source of truth. - The feature is experimental, opt-in, and its built-in routine is paused with no background token spend by default. > 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 GPT-5.3 Codex with reasoning, repository tool use, code execution, GitHub CLI, and Paperclip control-plane integration. Earlier branch commits also record Claude model co-authorship where applicable. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
009410164f |
Fix inbox unread badge alignment (#9685)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Inbox lets operators scan task state and distinguish unread activity at a glance > - Read and unread rows should keep the same status-and-title alignment so the list remains easy to scan > - The mark-read dot previously participated in flex layout, which added an extra leading column and visibly indented unread rows > - Parent rows also needed special handling because their collapse chevron occupies the normal leading gutter > - This pull request moves the unread dot out of desktop flex flow, preserves a consistent leading spacer, and positions parent-row dots after the chevron > - The benefit is consistent alignment for read, unread, leaf, nested, and collapsible parent rows without hiding tree controls ## Linked Issues or Issue Description ### What happened? In the Inbox, an unread row rendered its status icon and title farther right than an equivalent read row because the mark-read dot occupied its own flex column. On a collapsible parent row, the dot also competed with the leading chevron. ### Expected behavior Read and unread Inbox rows keep identical status/title alignment while preserving the unread affordance and any tree-expansion controls. ### Steps to reproduce 1. Run Paperclip from `master` and open the Inbox at desktop width. 2. Compare otherwise-equivalent read and unread leaf rows. 3. Expand a task tree containing an unread depth-zero parent. 4. Observe the unread row indentation and the dot competing with the parent chevron. ### Paperclip version or commit Reproduced against the pre-fix `master` parent of this PR. - **Deployment mode:** Local dev (`pnpm dev`). - **Installation method:** Built from source. - **Agent adapters involved:** Not adapter-specific; this is a core Inbox UI bug. - **Database mode:** Not database-related. - **Access context:** Board (human operator). - **Additional context:** No logs or configuration are involved; the regression is visual layout behavior covered by focused component/page tests. ## What Changed - Render the desktop unread dot as an absolute overlay so it does not consume row width; retain the existing in-flow behavior on mobile. - Add an `unreadDotPlacement` option so depth-zero collapsible parents place the dot after the leading chevron. - Reserve the same leading spacer for read and unread non-chevron Inbox rows. - Expand `IssueRow` and Inbox tests to cover leaf alignment, nested rows, parent chevrons, fading state, and mobile behavior. ## Verification - `pnpm exec vitest run ui/src/components/IssueRow.test.tsx ui/src/pages/Inbox.test.tsx` — 2 files, 30 tests passed. - `pnpm check:token-gates` — all three token gates clean across 630 scanned files. - Browser QA (desktop 1280px and mobile 375px) — PASS: read/unread desktop content measured at identical x positions; nested guides, parent chevron hit target, fading state, and mobile mark-read hit targets verified. ## Risks - Low risk: the change is isolated to Inbox row presentation and has focused regression coverage. - The main visual risk is breakpoint-specific placement of the mark-read dot; tests explicitly cover desktop absolute positioning and mobile in-flow positioning. > 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.6-sol`, high reasoning effort, with repository/tool execution. The runtime did not expose a context-window size. - Original implementation commit also records assistance from Claude Opus 4.8. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
5d42382df4 |
feat(ui): stabilize workspace service controls (#9705)
## Thinking Path > - Paperclip is the open source control plane people use to coordinate AI-agent work. > - Execution workspaces provide the local service loop where operators start, stop, restart, inspect, and open workspace services. > - The existing header exposed those actions through separate controls whose position and labeling changed across runtime states. > - That movement made the most common development actions harder to scan and easier to misclick, especially with multiple services or long URLs. > - The design therefore uses one fixed-geometry, state-aware control bar and keeps service-specific detail behind a compact disclosure. > - This pull request adds that control surface, maps existing runtime data and every pending mutation into it, and integrates it into the execution-workspace header without changing server contracts. > - The benefit is a calmer, predictable service-control loop across stopped, transitional, running, unhealthy, failed, multi-service, and narrow-width states. ## Linked Issues or Issue Description ### Subsystem affected `ui/ — React + Vite board UI` ### Problem or motivation Execution-workspace service actions move and change shape as runtime state changes, while URLs and multi-service status compete for header space. During bulk actions, operators also need every targeted service to show its transitional state immediately. ### Proposed solution Use one fixed-geometry, state-aware service control bar in the workspace header. Map existing runtime records into a stable status, URL, and actions model, and track each in-flight bulk request independently until it settles. ### Alternatives considered Keeping the separate quick-control buttons was rejected because their geometry changes by state. Showing every service inline was rejected because it makes the header too wide; per-service detail remains in a compact disclosure and the Services tab. ### Roadmap alignment Reviewed `ROADMAP.md`; this focused execution-workspace UI improvement does not duplicate a listed roadmap initiative. ### Additional context The published design and state viewer is available at https://pages.paperclip.ing/pap-14233-workspace-service-controls/. ## What Changed - Added `WorkspaceServiceControlBar`, a fixed-geometry responsive control for single- and multi-service runtime states. - Added 15 Storybook states covering running, stopped, transitions, unhealthy, failed, disabled, long-URL, mobile, and multi-service behavior. - Replaced `WorkspaceRuntimeQuickControls` in the execution-workspace header with adapters that map live services and all pending requests into the new control model. - Added focused unit coverage for service-entry construction, bulk pending overlays, request resolution, clipboard feedback, and header integration. ## Verification - `cd ui && NODE_ENV=development pnpm vitest run src/components/WorkspaceServiceControlBar.test.tsx src/components/WorkspaceRuntimeControls.test.tsx src/pages/ExecutionWorkspaceDetail.test.tsx` — 29 tests passed. - `NODE_ENV=development pnpm --dir ui typecheck` — passed. - `pnpm check:token-gates` — all token gates clean. - Reviewed the Storybook captures for all primary states. ## Risks - Low-to-moderate UI risk: service controls depend on adapter mapping from existing runtime records; focused tests cover single-service and bulk-action mapping and integration paths. - Multi-service bulk actions intentionally apply to all eligible services, while per-service actions remain in the disclosure. > 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, exact model ID `gpt-5.3-codex`; runtime-managed context window; coding/reasoning mode with repository, terminal, Git, GitHub CLI, and test execution tools. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
a015ac7a57 |
fix(ui): allow interrupting queued issue runs (#9725)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The issue detail chat lets operators send messages while an issue run is live > - Messages sent during a live run are shown as queued and can expose an interrupt action > - The UI only treated running runs as interruptible, even though queued runs can also own the pending message > - That mismatch hid the interrupt button after sending a message while the agent run was still queued > - This pull request treats queued and running issue runs as interruptible and preserves the exact target run on optimistic and persisted comments > - The benefit is that operators can immediately interrupt the queued run their message is waiting behind ## Linked Issues or Issue Description - **What happened:** Sending a message while an issue-owned agent run was in `queued` state showed the message as pending but did not make the interrupt action available. - **Expected behavior:** A message queued behind either a queued or running issue run should retain that run as its interrupt target and expose the interrupt control. - **Steps to reproduce:** Open an in-progress issue with an issue-owned run still queued, send a chat message, and inspect the queued message actions. - **Version/commit:** Reproduced against the pre-change `master` UI behavior. - **Deployment mode:** Paperclip board UI with a queued issue execution run. ## What Changed - Generalized issue-run resolution from running-only to queued-or-running interruptible runs. - Used the interruptible run consistently for optimistic queue metadata, persisted comment decoration, cancel controls, and targeted interruption. - Added a regression test that sends a message behind a queued run and verifies the exact run is cancelled. ## Verification - `pnpm exec vitest run ui/src/pages/IssueDetail.test.tsx` — 44 tests passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - `pnpm check:token-gates` — repository-wide gate currently reports nine pre-existing `#9627` comment literals; this patch adds no token literals or gate violations. ## Risks - Low risk: the behavior change is limited to selecting queued issue-owned runs as valid interrupt targets in the existing chat flow. - Cancellation remains targeted by run ID, and the regression test verifies the queued run ID is preserved through optimistic and persisted comment states. > 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 `gpt-5.4` via Codex CLI; context-window size is not exposed by this runtime; reasoning-enabled with repository, shell, GitHub CLI, and code-execution tools. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
59fb27ff79 |
feat(inbox): let agents safely tidy user inboxes (#9724)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI-agent companies and their work > - The inbox is a per-user attention view, so archiving an item must not alter the underlying issue, assignment, or status > - Agents can help responsible users tidy resolved work only when the action is company-scoped, reversible, policy-controlled, and fully attributable > - The database and authorization foundations landed in #9654 and #9658, but the end-to-end archive routes, audit details, agent workflow guidance, and operator UI still need to ship together > - Separate stacked PRs #9659 and #9661 made the complete behavior harder to review and land as one coherent capability > - This pull request consolidates the remaining server, shared-contract, documentation, skill, and UI work on top of current master > - The benefit is a single reviewable change that lets agents safely archive responsible-user inbox items and lets users control or undo that behavior ## Linked Issues or Issue Description ### Subsystem affected Cross-cutting inbox management across shared contracts, server authorization/routes/services, shipped agent skills, and the board UI. ### Problem or motivation Agents may complete work whose issue remains in the responsible user's Mine inbox. Existing board-user archive behavior does not provide the agent-facing policy endpoints, target resolution, heartbeat-run attribution, typed denials, conservative workflow guidance, or UI needed for safe agent-managed cleanup. ### Proposed solution Allow authorized agents to archive or unarchive responsible-user inbox items under the user's open, allowlist, or disabled policy; preserve actor/agent/run attribution in issue detail and activity records; expose policy controls and agent archive attribution in the UI; and document conservative cleanup rules for agents and PR gardening. ### Alternatives considered - Reuse generic issue mutation permissions: rejected because inbox state belongs to a target user and requires user-scoped authorization. - Automatically archive every completed or closed item: rejected because completion signals can still require human review or a decision. - Keep the backend and UI as separate stacked PRs: superseded by this consolidated PR so the complete user-visible behavior can be reviewed and verified together. ### Related work - Builds on merged foundations #9654 and #9658. - Supersedes the remaining stacked changes in #9659 and #9661. - `ROADMAP.md` has no overlapping inbox archive or inbox authorization initiative. ## What Changed - Added shared inbox-agent policy types and validators plus company-scoped self-service policy routes and OpenAPI coverage. - Enabled agent archive/unarchive mutations with responsible-user targeting, policy enforcement, typed failures, attribution, idempotency, and detailed activity auditing. - Returned agent archive attribution in issue detail and documented reversible inbox cleanup semantics in the implementation spec and Paperclip skill. - Added conservative PR-gardening inbox tidy guidance that keeps GitHub access read-only and avoids archiving work that still needs human action. - Added the Profile settings policy control and Issue Properties attribution/unarchive UI with focused component coverage and narrow-pane handling. ## Verification - `pnpm exec vitest run server/src/__tests__/inbox-archive-routes.test.ts server/src/__tests__/inbox-agent-policy-routes.test.ts server/src/__tests__/authorization-service.test.ts server/src/__tests__/openapi-routes.test.ts ui/src/components/InboxAgentPolicyControl.test.tsx ui/src/components/IssueProperties.test.tsx` — 110 passed. - `pnpm --filter @paperclipai/db exec vitest run src/inbox-archive-agent-policies-migration.test.ts` — 1 passed. - `node --test .agents/skills/pr-gardening/scripts/pr-gardening.test.mjs` — 9 passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - `pnpm check:token-gates` — changed files are clean; the repository-wide command currently reports nine unrelated pre-existing `#9627` literals outside this PR's diff. ## Risks - Agent inbox mutations broaden an existing endpoint path, so authorization and target resolution must remain fail-closed; focused route and authorization tests cover allowed and denied paths. - Archive state affects only the responsible user's inbox presentation and remains reversible; it does not mutate issue status, assignment, or visibility. - The UI policy defaults to the existing open behavior, while allowlist and disabled modes can reduce agent access. - This PR intentionally builds on #9654 and #9658 and contains no new migration number or modification to an already-applied migration. > 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 using GPT-5.4, medium reasoning, repository tool use, shell execution, code review, and test execution. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (`feat/inbox-agent-archive-complete`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
89af58b6dc |
Clarify task-level model overrides in issue properties (#9710)
## Thinking Path > - Paperclip is the control plane where operators configure and inspect AI-agent work. > - An issue can override the assigned agent's primary model for that task. > - The issue-properties UI labeled that per-task setting as `Custom · <model>`, which could be read as a property of the model rather than a replacement of the agent default. > - Operators need the UI to distinguish the agent's primary model from an issue-specific override at both the collapsed summary and selection point. > - This pull request renames the lane presentation to `Override` and adds concise provenance text without changing the stored lane value or adapter configuration behavior. > - The benefit is that operators can immediately understand which model will run and why it differs from the agent default. ## Linked Issues or Issue Description No matching public GitHub issue was found. Related implementation work: #9700 moved Codex ACPX model configuration to startup and is already on `master`; #9355 also addresses ACP session-config rejection behavior. Those PRs concern execution behavior, while this PR is limited to clarifying the issue-level override UI. Bug report details: - **What happened?** The issue-properties Model row displayed `Custom · <model>` for a task-level `assigneeAdapterOverrides.adapterConfig.model`. Operators could misread `Custom` as describing the model itself and could not see that the value replaced the agent's primary model for this issue. - **Expected behavior:** The UI should explicitly identify a task-level model as an override and explain that it replaces the agent's primary model for the issue. - **Steps to reproduce:** Configure an agent with a primary model, set a different model on an issue, and inspect the Model row and model picker in Issue Properties. - **Paperclip version or commit:** Reproduced on the pre-change branch derived from current `master`. - **Deployment mode:** Local development or any deployment using the board UI. - **Installation method:** Built from source. - **Agent adapters involved:** Adapter-agnostic; any adapter exposing model selection. - **Database mode:** Not database-related. - **Access context:** Board operator viewing issue properties. - **Relevant logs or output:** Not applicable; this is a presentation ambiguity. - **Relevant config:** An issue-level `assigneeAdapterOverrides.adapterConfig.model` differing from the assigned agent's primary model. - **Additional context:** The internal lane identifier remains `custom`; only user-facing copy and explanatory text change. - **Privacy checklist:** No private instance links, internal ticket IDs, secrets, usernames, or local paths are included. ## What Changed - Renamed the collapsed issue model label from `Custom · <model>` to `Override · <model>` and added a provenance tooltip. - Renamed the model-picker lane from `Custom` to `Override` and added explanatory subtext at the selection point. - Updated the Issue Properties component test to assert the new label. - Added an isolated Storybook fixture for the task model override state so visual review has a stable target. ## Verification - `pnpm exec vitest run ui/src/components/IssueProperties.test.tsx` — 43 tests passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - `git diff --check public-gh/master...HEAD` — passed. - `pnpm check:token-gates` — the changed files are clean, but the repo-wide command currently reports nine unrelated `#9627` comment references already present on `master` as color literals. ## Risks - Low risk: this changes display strings and explanatory copy only; override storage, lane identifiers, API contracts, and execution behavior are unchanged. - The global token-gate false positive may also appear in CI until the unrelated `#9627` references on `master` are allowlisted or the scanner ignores issue-number comments. > 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 coding agent assisted this PR preparation using medium reasoning, repository-aware shell execution, Git/GitHub tooling, and local test/typecheck execution. The hosted runtime did not expose an exact model ID or context-window size to 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 checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
52aea90263 |
feat: organize skills with nested folders and My Skills (#9633)
## Thinking Path > - Paperclip is the open source control plane people use to organize and govern AI-agent companies > - Company skills are durable resources that users browse, import, assign, and maintain over time > - A flat skill list plus tags does not provide a stable location or hierarchy for personal, company, project-imported, and bundled skills > - Folder paths need to be canonical, company-scoped, safe to move, and preserved across re-imports without changing skill IDs > - The `/skills` UI also needs traversal, breadcrumbs, move/create flows, and a dedicated My Skills namespace that work on desktop and mobile > - This pull request adds the folder data model and APIs, reserved-root lifecycle, project import behavior, and the folder-first skills experience > - The benefit is a predictable filesystem-like organization model while tags remain available for cross-cutting classification ## Linked Issues or Issue Description Refs #9619 — the reviewed folder foundation was intentionally closed and folded into this combined feature PR. Refs #9026 — earlier flat-folder attempt superseded by this integrated implementation. Refs #3281 — related skill organization proposal; this PR uses canonical persisted folders rather than deriving groups from skill keys, and does not add hidden-skill behavior. **Feature request** - **Problem:** Skills currently lack a canonical hierarchical location, making personal skills, project imports, bundled skills, and company-authored skills difficult to traverse and manage at scale. - **Proposed behavior:** Add nested company-scoped folders with stable paths, reserved My/Projects/Bundled roots, subtree queries, safe move/create operations, and a folder-first `/skills` library UI. - **Import behavior:** New project scans file skills under `projects/<project-slug>`; later imports update content without overriding a user-selected folder. - **Alternatives considered:** Tags alone remain useful for cross-cutting classification, but they do not provide canonical location, nesting, reserved namespaces, or stable import placement. - **Roadmap alignment:** Extends the completed Skills Manager and Scheduled Routines capabilities without duplicating an active roadmap item. ## What Changed - Adds `folders` persistence for routine and skill folders, nested canonical paths, parent/slug/system-key fields, migration backfills, and reapply-safe migrations `0174`–`0175` after current master migrations. - Adds company-scoped folder CRUD, cycle/depth/namespace validation, reserved My/Projects/Bundled lifecycle, item moves, subtree filtering, and folder paths on skill results. - Preserves project-import placement: first import files into the project folder, while re-import keeps user-owned placement and stable skill IDs. - Adds the `/skills` folder tree rail, tags facet, breadcrumbs, subfolder browser, move/new-folder dialog, canonical detail location, inline tag editing, and folder-aware Studio creation. - Keeps bundled skills read-only even when their source metadata is incomplete by detecting the reserved Bundled folder and hiding selection/move actions. - Extends routine folder UI and OpenAPI coverage, and adds regression tests across migrations, services, routes, tree helpers, pages, and Studio creation. ## Verification - `pnpm exec vitest run packages/db/src/nested-skill-folders-migration.test.ts server/src/__tests__/folders-routes.test.ts server/src/__tests__/folders-service.test.ts server/src/__tests__/company-skills-service.test.ts server/src/__tests__/routines-service.test.ts ui/src/components/folders/FolderControls.test.tsx ui/src/components/folders/SkillFolderTree.test.tsx ui/src/components/folders/skill-folder-tree.test.ts ui/src/pages/CompanySkills.test.tsx ui/src/pages/Routines.test.tsx ui/src/pages/SkillStudio.test.tsx ui/src/lib/company-skill-routes.test.ts ui/src/lib/skill-create.test.ts` — 13 files, 192 tests passed. - `pnpm exec vitest run ui/src/pages/CompanySkills.test.tsx ui/src/components/folders/SkillFolderTree.test.tsx` — 2 files, 20 tests passed after preserving the existing PR's bundled-skill fixes. - `pnpm -r typecheck` — passed for all workspace packages. - `pnpm test:run` — passed in an isolated CI-like environment with inherited Paperclip runtime identity and static AWS credential variables removed. - `pnpm build` — production build passed for all workspace packages. - Greptile iteration 2 — 5/5 confidence with zero unresolved threads on commit `ff2d67aa71`. - Latest-head GitHub checks — all success, neutral, or skipped; PR is mergeable with a clean merge state. - `pnpm check:token-gates` — reports nine existing `#9627` comment false positives already present on `master`; this PR introduces no new token violation. ## Risks - **Migration/backfill:** `0174` creates the foundation and `0175` adds nested/reserved semantics. Both are ordered after current master migration `0173`, are covered by numbering/safety checks, and are designed to be reapply-safe. - **Reserved namespaces:** My, Projects, and Bundled roots are service-managed. Regression coverage prevents namespace squatting, cross-company folder use, bundled writes, cycles, and excessive depth. - **Behavioral change:** Project scans choose a project folder only on initial creation; existing skills deliberately retain their current folder during refresh. - **UI scope:** The folder rail applies to the Installed library; Catalog retains the discovery-oriented category sidebar. > 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 `gpt-5.5` in Codex CLI, medium reasoning mode; runtime did not expose a context-window value. Used repository/file tools, terminal execution, Git/GitHub operations, test execution, and code editing. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
d62c5adb7a |
fix(ui): stop recreating markdown mention observers (#3809)
Fixes #3759 ## Thinking Path > - Paperclip orchestrates AI agents and issue workflows, so the comment composer has to stay stable under normal typing. > - The affected subsystem is the shared markdown comment editor used across issue and workflow surfaces. > - That editor decorates mention links after Lexical updates the editable DOM. > - The current mention decoration effect recreates its `MutationObserver` whenever `value` changes, which happens on every keystroke. > - That observer also reacts to the DOM mutations produced by mention decoration itself, creating unnecessary observer churn in Chrome. > - This pull request keeps one observer instance alive, batches decoration work into `requestAnimationFrame`, and disconnects the observer while decoration writes run. > - The benefit is lower observer churn while preserving the existing mention chip behavior. ## What Changed - Removed `value` from the mention-decoration observer effect dependency list so the observer is not recreated on every external value update. - Batched mention decoration with `requestAnimationFrame` and temporarily disconnected the observer while DOM decorations are applied to avoid self-triggered feedback loops. - Added a regression test that verifies external value changes do not recreate the mention decoration observer. ## Verification - `pnpm install --frozen-lockfile` - `pnpm --filter @paperclipai/ui exec tsc --noEmit` - `pnpm --filter @paperclipai/ui exec vitest run src/components/MarkdownEditor.test.tsx` currently fails before test collection on the existing repo baseline with `TypeError: undefined is not an object (evaluating 'z.string')` from `packages/shared/src/adapter-type.ts` ## Risks - Low risk. The change is scoped to the mention decoration observer lifecycle and keeps the existing decoration logic intact. - The main behavior change is deferring decoration to the next animation frame instead of running immediately on every observed mutation. ## Model Used - OpenAI Codex, GPT-5-based coding agent with local tool use in the Codex CLI environment. ## 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 - [ ] 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 |
||
|
|
8b04147ca4 |
perf(ui): stop polling the event-sourced company live-runs list (#9701)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Its web UI keeps live views fresh with a live-events websocket plus React Query, and #9627 began replacing polling with event-sourcing (pushing data into the cache) > - After the churn fixes (#9624) and #9627 shipped, a long-lived tab's memory footprint was still climbing, so I re-profiled with the Chrome DevTools MCP > - The dominant remaining churn is React Query re-arming a polled query's `refetchInterval` timer on **every** observer notification — and our live-event handlers `setQueryData(liveRuns(companyId))` on nearly every event, so each pushed update re-arms every `liveRuns` observer's timer (the sidebar is always mounted) > - #9627 event-sourced the live-runs data but left the now-redundant `refetchInterval` in place, so we did half the fix — the poll is pure waste and the thing re-arming timers > - This pull request removes `refetchInterval` from the event-sourced company live-runs queries so the frequent cache writes have no timer to re-arm > - The benefit is that the steady-state timer churn on the most-observed resource collapses, so the off-heap footprint stops climbing ## Linked Issues or Issue Description No public GitHub issue exists; describing inline per CONTRIBUTING.md → "Link Issues or Describe Them In-PR", following the bug report template. Continues #9569 / #9624 / #9627. **What happened?** With the earlier fixes deployed, a browser tab left open on the app kept growing its memory footprint. MCP profiling showed ~100+ `setInterval` create/clear cycles per 5s on an aged tab (vs ~16 fresh), all from React Query's refetch-interval timers being re-armed on every `setQueryData` to the frequently-written `liveRuns(companyId)` query. **Expected behavior** A resource whose data is pushed (event-sourced) should not also poll; cache writes should not repeatedly re-arm interval timers. Idle tabs should hold a bounded footprint. **Steps to reproduce** Open a tab with agents streaming, leave it open, and instrument `setInterval`/`clearInterval`: the churn rate climbs and traces to `QueryObserver.updateTimers` (`refetchInterval`) for `liveRuns`, re-armed by every live-event cache write. **Paperclip version or commit** Branch `perf/drop-live-runs-refetch-interval`, off `master` (after #9627). **Deployment mode** Local dev (`pnpm dev`), web UI. Core UI live-updates plumbing; not adapter-specific. ## What Changed - Set `refetchInterval: false` on every site that polls the **plain** `queryKeys.liveRuns(companyId)` query (event-sourced by #9627): `Sidebar`, `SidebarAgents`, `Issues`, `Inbox`, `IssueDetail` (companyLiveRuns), `ProjectDetail` (×2), `Routines`, `ExecutionWorkspaceDetail`, `bridge-init`. - Removed the now-unused `useVisibilityRefetchInterval` interval vars/imports in `Issues`, `Inbox`, `IssueDetail`. - **Left variant-key sites polling on purpose** — `Agents` page (`[...liveRuns, "agents-page"]`) and `ActiveAgentsPanel` (`[...liveRuns, scope, …]`) are NOT event-sourced by #9627 (different exact cache key), so dropping their poll would make them stale. Those are a later phase. - Freshness for the converted queries now comes from event-sourcing (#9627) + its reconnect reconcile; the initial mount fetch and cross-tab publish (`usePublishSharedQueryData`) still happen. ## Verification - MCP profiling identified the churn: the single churning callback is React Query's `refetchInterval` timer, re-armed by `setQueryData(liveRuns)` on live events. - `vitest`: all affected suites pass (`Sidebar`, `SidebarAgents`, `Issues`, `Inbox`, `IssueDetail`, `ProjectDetail`, `Routines`, `ExecutionWorkspaceDetail`, `LiveUpdatesProvider`) — 153 tests. - Updated two `SidebarAgents` linger-window tests: they advanced fake timers to the *exact* linger-expiry boundary and had relied on poll-induced re-renders to flush. The linger self-schedules its own `setTimeout`, so the tests now cross the boundary with a small margin + an explicit flush (no product change). - `tsc -b` clean. - End-to-end footprint reduction should be re-measured against a rebuilt bundle with the same instrumentation. ## Risks Low, client-only. - `liveRuns(companyId)` freshness now depends entirely on event-sourcing + reconnect reconcile (both from #9627). If an event path is missed, the reconnect handler refetches once; durable replay is a planned later phase. - Variant-key run lists (Agents page, ActiveAgentsPanel) are unchanged and still poll, so they don't regress. - Issue-scoped run queries (`issues.liveRuns/activeRun/runs`) are **not** touched here — they aren't event-sourced yet and are a separate phase. ## Model Used - **Provider:** Anthropic, via the Claude Code CLI. - **Model:** Claude Opus 4.8 (`claude-opus-4-8`). - **Reasoning mode:** Extended thinking enabled. - **Capabilities used:** tool use (shell, file editing), and the Chrome DevTools MCP to re-profile the live instance and pinpoint the `refetchInterval` timer churn. ## 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 (a perf/plumbing change) - [x] I have searched GitHub for duplicate or related PRs and linked them above (continues #9627; no duplicates) - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have considered and documented any risks above - [ ] I have updated relevant documentation to reflect my changes (N/A — no user-facing docs; rationale documented inline) - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
6ec059ab4e |
fix(server): suppress stale handoff alarms during live continuation (#9695)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The control plane records a successful-run handoff when productive work ends without a durable next-step disposition > - That handoff state was derived only from the latest activity event, without checking whether a corrective run or wake was currently alive > - As a result, actively progressing issues could still show a high-severity missing-disposition alarm and blocked-inbox row > - The same stale required event could also remain indefinitely when a later successful run correctly skipped recovery because another valid continuation path already existed > - This pull request makes the derived state liveness-aware, suppresses attention only while the live path exists, and resolves stale required events on valid-path skips > - The benefit is that productive work stays calm while genuine stalls still resurface automatically when liveness disappears ## Linked Issues or Issue Description - **Bug:** An issue whose latest successful-run handoff event is `required` continues to report a missing disposition even while a heartbeat run, scheduled retry, or queued/deferred/claimed wake is actively targeting that issue. - **Expected behavior:** The API should expose current continuation liveness, the blocked inbox should suppress the alarm only while that path remains live, and a later successful run that skips recovery because a valid path exists should durably resolve the stale event. - **Related but distinct:** #9370 changes disposition freshness at detection time; #8748 adds an explicit policy opt-out. This PR preserves detection/escalation policy and fixes read-time/current-liveness state. ## What Changed - Extended `SuccessfulRunHandoffState` with `hasLiveContinuation` and optional `liveRunId` evidence. - Added bounded liveness hydration for required handoff states using active heartbeat-run and wake-request signals. - Suppressed `missing_disposition` blocked-inbox rows only while a run, scheduled retry, or live wake targets the issue. - Added durable `issue.successful_run_handoff_resolved` logging when handoff detection skips because another valid continuation path owns the next action. - Added focused regressions for live/absent derived state, self-healing attention suppression, valid-path skip classification, and resolved-event logging. - Updated UI normalization and fixtures for the shared contract without changing rendering behavior. ## Verification - `pnpm --filter @paperclipai/shared typecheck` - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/ui typecheck` - `pnpm vitest run server/src/services/recovery/successful-run-handoff.test.ts server/src/__tests__/issue-list-assignee-filter-routes.test.ts server/src/__tests__/issue-blocker-attention.test.ts` — 56 passed - `pnpm vitest run server/src/__tests__/heartbeat-process-recovery.test.ts -t "queues one finish-handoff wake when a successful run leaves in-progress work without a next action"` — 1 passed - `git diff --check` ## Risks - Low risk: no schema or migration changes, and detection, bounded correction attempts, and escalation behavior are unchanged. - Liveness lookups are limited to issues whose latest handoff state is `required`; blocked-inbox suppression reuses rows already loaded by that query path. - Suppression is read-time and self-healing: when the run or wake stops, the alarm returns on the next fetch. > 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 using `gpt-5.4`, tool-enabled software-engineering workflow with repository, shell, test, Git, GitHub, and Paperclip control-plane access. Context-window size is not exposed by this 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 checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
054b076b58 |
fix(ui): keep inbox hover and j/k keyboard selection in sync across list reshapes (#9680)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Inbox is the primary triage surface; it supports both mouse hover and `j`/`k` keyboard navigation over a flat, expandable list of rows > - Hover and keyboard selection are meant to be a single shared "cursor": hovering a row and then pressing `j`/`k` should continue from the hovered row, not jump elsewhere > - A prior hover-perf rewrite moved the hovered row into a numeric `hoveredIndexRef` and nulled it whenever the list reshaped; because the inbox polls constantly, any refresh between hovering and pressing a key dropped the hovered index > - With the hovered index dropped, the next keypress fell back to selection index `0`, stranding the cursor at the top of the list instead of continuing from the hovered row > - This pull request tracks the hovered row's stable identity (a nav key) alongside the numeric index and re-anchors it by key across reshapes, mirroring the existing keyboard-selection reconciliation > - The benefit is that mouse hover and keyboard navigation stay in sync exactly as intended, even while the inbox is polling ## Linked Issues or Issue Description **Bug report** - **What happened:** In the Inbox, hovering a row with the mouse and then pressing `j`/`k` (or another keyboard shortcut) does not continue from the hovered row. If the list refreshes (which happens on the inbox's constant polling) in the moment between hovering and pressing a key, keyboard selection snaps back to the top row instead. - **Expected behavior:** The keyboard cursor should be in sync with the hovered row — pressing `j`/`k` after hovering should move relative to the row the mouse is over. - **Steps to reproduce:** 1. Open the Inbox with several rows. 2. Hover the mouse over a row partway down the list. 3. Wait for (or trigger) a background poll/refresh of the list. 4. Press `j` or `k`. 5. Observe selection jumps to the top of the list instead of continuing from the hovered row. - **Root cause:** The `[flatNavItems]` effect nulled `hoveredIndexRef` on every list reshape. Since hover also clears the keyboard selection band to `-1`, the fallback selection index resolved to `0`. ## What Changed - Hoisted `navEntryKey` to module scope so it can compute a stable, index-independent identity for a nav row from both the hover handler and the reshape effect. - Added `hoveredNavKeyRef` to track the hovered row's stable key alongside the existing numeric `hoveredIndexRef`, set whenever the pointer selects a row. - On list reshape, re-anchor the hovered index by key (find the row with the same key) instead of unconditionally dropping it; only drop the hover when the row is actually gone. This mirrors the existing `selectedIndex` key-based reconciliation. - Added a unit test that hovers a row, reshapes the list via a simulated poll, presses `j`, and asserts selection continues from the hovered row. ## Verification - `pnpm --filter ./ui exec vitest run src/pages/Inbox.test.tsx` → 15/15 passing, including the new hover→`j`/`k` sync test and the existing keyboard-nav tests. - The new test explicitly covers the reshape-during-hover path that the prior test suite had deferred to live/e2e verification. ## Risks - Low risk. The change is confined to the Inbox's in-memory hover/selection bookkeeping (two refs and one effect); it adds no new renders (hover still paints via CSS `:hover`) and touches no data fetching, routing, or persistence. Behavior is unchanged when the list does not reshape; when it does, the hover now follows the same row instead of being dropped. ## Model Used - Claude Opus 4.8 (Anthropic), model id `claude-opus-4-8`, used with extended thinking and tool use (file edits, running the UI test suite locally). ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [ ] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
cf7711ecc5 |
feat(ui): explain when a message won't reopen a blocked issue (Rule C, PAP-13554) (#9417)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - When an agent's task is `blocked`, humans often comment on the issue
thread expecting it to reopen and resume
> - If the issue stays `blocked` because an unresolved (not-done)
blocker still gates the reopen path, the UI said nothing — the human
"sent a message and nothing happened" (a real silent-failure report)
> - That silence makes the product feel broken even though the gate is
working as designed
> - This pull request adds Rule C copy to the existing
`IssueBlockedNotice` surface: when a comment won't reopen a blocked
issue, it explains why and names the deepest unresolved blocker leaf
with its status
> - The benefit is that the human immediately understands the task is
*paused, not stuck*, and knows exactly which task to act on to unblock
it
## Linked Issues or Issue Description
<!-- No public GitHub issue — describing the underlying problem inline
(path B), following the feature issue template. -->
**Problem or motivation**
A human comments on a `blocked` issue expecting it to move back to
`todo` and resume. When the reopen gate keeps it blocked because an
unresolved (not-`done`) blocker remains, nothing in the UI communicates
this, so the user perceives a dropped message ("I sent a message and
nothing happened").
**Proposed solution**
Reuse the existing amber `IssueBlockedNotice` surface (the designated
blocked/recovery surface — no new component). When a message won't
reopen a blocked issue, the notice states that it won't reopen yet,
names the unresolved blocker leaf with its status (e.g. "Still blocked
by PAP-XXXXX (in progress)"), and reassures that it reopens
automatically once the blocker is done. UI-only; no server change.
**Alternatives considered**
Adding a server signal (a reopen-suppressed reason on the comment/notice
payload) was considered but rejected as unnecessary — the
unresolved-blocker set is already available client-side, so the copy is
derived in the component. Done-but-pending-finalize blockers are `done`,
so they fall out of the unresolved set into the standard reopen (Rule B)
path and are correctly not shown as reopen-suppressed.
## What Changed
- `ui/src/components/IssueBlockedNotice.tsx`: added reopen-suppressed
messaging for `blocked` issues that still have unresolved blockers — a
lead sentence ("a message won't reopen it yet, then it reopens
automatically"), the named unresolved blocker leaf with its status, and
an "and N other task(s)" summarization when multiple blockers remain.
- `ui/src/components/IssueBlockedNotice.test.tsx`: added/updated tests
covering the single, nested-chain (deepest-leaf), multiple-blocker, and
empty-blocker states, plus the not-a-reopen-case (`in_progress`) path.
- `ui/storybook/stories/issue-blocked-notice.stories.tsx`: new Storybook
stories rendering each notice state for copy review.
## Verification
- `cd ui && tsc -b` — typecheck clean (previously failed TS2322 on the
story meta; fixed by a default `args`).
- Vitest: `IssueBlockedNotice.test.tsx` green (single / nested /
multiple / empty / in-progress states).
- Storybook stories rendered at 1440×900 for all four states;
screenshots posted on the tracking issue.
- UXDesigner reviewed the notice copy and signed off (no copy edits
required).
## Risks
Low risk. UI-only, additive copy on an already-shipped amber notice
surface; no server or schema changes. The reopen behavior itself is
unchanged — this only explains the existing gate. Worst case is copy
wording, which had a design review.
## Model Used
Claude — claude-opus-4-8 (Opus 4.8), extended thinking, with tool use /
code execution in the Paperclip harness.
---
- [x] I searched the GitHub PR list for similar/duplicate PRs before
opening this one.
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
f44a002b8d |
fix(ui): restore prefix-aware company export/import links (#6648)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Each company workspace in the web UI is mounted under a URL prefix (e.g. `/NEU/company/...`), and `Link` from `@/lib/router` applies that prefix automatically via `applyCompanyPrefix` > - Company Settings rendered its Org Chart, Export, Import, and Cloud Upstream buttons as raw `<a href>` anchors, which drop the prefix, so those pages 404 on prefixed instances (#2910); `CompanyExport.filePathFromLocation` also failed to locate `/company/export/files/` inside prefixed URLs, breaking export file previews > - #2951 fixed the Settings links with `<Link to>` plus tests, but the sandbox-settings work in #4415 reverted the links back to `<a href>`, silently reintroducing the bug (#6647) > - This pull request restores the prefix-aware `<Link>` for all four Settings links, normalizes the pathname with `toCompanyRelativePath()` before matching the export-files marker, and adds regression tests covering every route so the fix cannot be lost again > - The benefit is that export/import/org-chart/cloud-upstream navigation and export file previews work on every prefixed deployment ## Linked Issues or Issue Description Fixes: #6647 Refs #2910 (original report: `/company/export` → prefix `COMPANY` → not found) Refs #2951 (original fix with `<Link to>` + tests — merged, then lost) Refs #4415 (sandbox settings PR that reverted Settings back to `<a href>`) ## What Changed - **`ui/src/pages/CompanySettings.tsx`**: use `Link` from `@/lib/router` for the Org Chart, Export, Import, and Cloud Upstream buttons (replacing raw `<a href>`) - **`ui/src/pages/CompanyExport.tsx`**: resolve file paths from prefixed URLs by normalizing with `toCompanyRelativePath()` before matching `/company/export/files/` - **`ui/src/lib/company-routes.test.ts`**: regression tests for export/import/cloud-upstream/org prefix rewriting, double-prefix prevention, and export file URL normalization ## Verification ```bash pnpm vitest run ui/src/lib/company-routes.test.ts ``` Manual: 1. Open `http://localhost:3100/NEU/company/settings` (or your company prefix). 2. Click **Export** / **Import** — URL should stay under `/:prefix/company/...`. 3. On export, select a file — URL should be `/:prefix/company/export/files/...` and preview should load. The change is navigation-target-only (no visual/layout changes), so before/after is shown as the resolved URLs: | Link | Before (prefix dropped → not found) | After | |------|-------------------------------------|-------| | Export | `/company/export` | `/NEU/company/export` | | Import | `/company/import` | `/NEU/company/import` | | Org Chart | `/org` | `/NEU/org` | | Cloud Upstream | `/company/settings/cloud-upstream` | `/NEU/company/settings/cloud-upstream` | ## Risks Low — same approach as #2951; only navigation/parsing, no API changes. ## Model Used - Original implementation: authored by @qbamca in Cursor (agentic editor; the session's exact model ID was not recorded) - Follow-up commit (merge-conflict resolution) and this description update: Claude Fable 5 (Anthropic, `claude-fable-5`, extended thinking, agentic tool use), operated by the Commit Capital triage team ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes (no doc changes required — behavior matches documented routing) - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups (pending re-review of the conflict-resolution commit) - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Jakub Mikiciuk <jmikiciuk@igus.net> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Andrew Aymeloglu <aaymeloglu@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
8eff54bc47 |
[codex] Explain AWS secret creation failures in the UI (#9645)
## Thinking Path > - Paperclip is the open source control plane operators use to manage AI-agent companies. > - Operators can store runtime secrets in provider vaults such as AWS Secrets Manager. > - The server already preserves sanitized AWS failure details, including the failed operation, required IAM capability, region, and safe recovery options. > - The create-secret dialog reduced that structured response to a generic message, leaving operators unable to understand or fix failed AWS writes. > - This pull request keeps the safe structured error through the UI and presents concise, actionable diagnostics without exposing raw AWS principals or account details. > - The benefit is that operators can correct IAM access or link an existing AWS secret immediately instead of debugging an opaque failure. ## Linked Issues or Issue Description No public issue was found for this exact UI gap. Bug report: - What happened: creating a Paperclip-managed value in AWS Secrets Manager could fail with a generic dialog error even though the API returned safe, actionable provider details. - Expected behavior: the dialog should identify the AWS operation, required IAM capability, region, provider vault, and safe alternative while keeping raw cloud-provider details redacted. - Steps to reproduce: configure an AWS Secrets Manager provider vault without `secretsmanager:CreateSecret`, then create a Paperclip-managed secret using that vault. - Paperclip version/commit: current `master` before this PR. - Deployment mode: Paperclip server with an AWS Secrets Manager provider vault. Related prior server-side propagation work: - Refs #9161 ## What Changed - Preserve the structured `ApiError` returned by failed create-secret mutations instead of reducing it to a string. - Render AWS-specific, sanitized diagnostics with the required IAM capability, region, provider vault, operation, and external-reference recovery option. - Add a full dialog render regression test that verifies actionable details appear and raw AWS ARN/account information does not. ## Verification - `pnpm exec vitest run ui/src/pages/Secrets.render.test.tsx` — 1 file passed, 15 tests passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - `pnpm check:token-gates` — all gates clean. - `git diff --check public-gh/master...HEAD` — passed. ### Visual Verification QA verified both states in Chromium at head `357cd2271` using the real `Secrets` component and confirmed that raw AWS account, ARN, assumed-role, and provider exception details are absent from the rendered DOM. **AWS access-denied diagnostics**  **Generic non-AWS fallback**  ## Risks Low risk. The change only affects failed create-secret presentation in the UI; successful secret creation, API contracts, schema, and migrations are unchanged. The structured details are server-sanitized, and the regression test confirms raw AWS principal/account data is not rendered. > 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 `gpt-5.4` via Codex CLI, with tool-enabled repository editing, shell execution, Git, GitHub, and Paperclip API access. Reasoning mode and exact context-window size 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 checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
8368fb30b0 |
fix(routines): coalesce sub-hourly catch-up runs (#9649)
## Thinking Path > - Paperclip is the open source control plane people use to run AI-agent companies. > - Scheduled routines support catch-up policies when the server resumes after missed cron ticks. > - The existing capped replay policy dispatched once per missed tick, which can flood the board after downtime for frequent schedules. > - Sub-hourly routines usually need one prompt catch-up execution rather than historical per-tick replay, while hourly-or-slower schedules may rely on the existing behavior. > - This pull request coalesces missed sub-hourly ticks into one execution and keeps the slower-schedule behavior unchanged. > - The benefit is bounded recovery work without changing the semantics of lower-frequency scheduled routines. ## Linked Issues or Issue Description ### What happened? When a scheduled routine using `enqueue_missed_with_cap` resumes after several missed sub-hourly cron ticks, Paperclip dispatches one catch-up execution for every missed tick. Those executions arrive in a same-second burst and can flood the board with duplicate-looking work. ### Expected behavior Sub-hourly schedules should advance past all missed ticks but dispatch exactly one catch-up execution. Hourly-or-slower schedules should retain capped per-tick replay. ### Steps to reproduce 1. Build Paperclip from `master` and create a routine with a sub-hourly cron schedule and `catchUpPolicy: enqueue_missed_with_cap`. 2. Set its persisted `nextRunAt` far enough in the past to cover several scheduled occurrences. 3. Run routine catch-up processing. 4. Observe multiple catch-up dispatches instead of one coalesced execution. ### Paperclip version or commit Reproduced on `master` before this PR. ### Deployment mode Built from source in local development with embedded PGlite. ## What Changed - Classify sub-hourly cadence from timezone-aware scheduled occurrences, avoiding daily multi-minute false positives while supporting schedules restricted to active days. - Coalesce all missed sub-hourly ticks into one catch-up dispatch while advancing `nextRunAt` to the next future occurrence. - Preserve capped per-tick replay for hourly-or-slower schedules. - Clarify the catch-up policy labels in both routine editing surfaces. - Add regression coverage for both the coalesced and preserved behaviors. ## Verification - `pnpm exec vitest run server/src/__tests__/routines-service.test.ts --testNamePattern='coalesces multiple missed sub-hourly ticks|continues replaying each missed hourly tick|continues replaying missed ticks for daily schedules with multiple minute values|coalesces sub-hourly schedules restricted to weekdays'` — 4 passed. - `pnpm check:token-gates` — all gates clean. - `git diff --check origin/master...HEAD` — clean. ## Risks - Low-to-moderate behavioral risk: sub-hourly routines using `enqueue_missed_with_cap` now intentionally receive one recovery execution instead of one per missed tick. - Hourly-or-slower schedules retain their previous capped replay behavior, limiting the compatibility surface. - No schema, migration, workflow, or lockfile changes. > 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 CLI with GPT-5.5, medium reasoning, code execution and repository tool use; the runtime did not expose a context-window size. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
f1508a7929 |
feat(decisions): expand image rows into gallery (#9532)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI-agent companies and review work that needs human attention. > - The Decisions page condenses approvals, failed runs, reviews, and issue interactions into a scannable attention queue. > - Some decision rows already include screenshot evidence, but the collapsed thumbnail stack is too small for meaningful inspection. > - Image-only rows were not expandable because expansion was previously reserved for inline decision resolvers. > - Reviewers therefore had to leave the Decisions page before they could understand the visual evidence attached to a row. > - This pull request makes rows with images expandable and presents a readable, linked gallery while preserving the compact collapsed view. > - The benefit is faster evidence review without sacrificing queue density or existing inline-resolution behavior. ## Linked Issues or Issue Description No public GitHub issue currently tracks this feature. ### Subsystem affected `ui/` — React + Vite board UI ### Problem or motivation Screenshot evidence in Decisions rows is only visible as small overlapping thumbnails, and non-inline rows cannot expand to show it. This makes visual review unnecessarily slow and forces reviewers to navigate away from the queue. ### Proposed solution Treat active rows with images as expandable, render the first three images at a readable size in an expanded gallery, and link images plus any remaining-image affordance to the related issue. ### Alternatives considered Always rendering large images would make the queue difficult to scan; opening the issue immediately preserves density but prevents in-context review. An explicit expandable gallery keeps both behaviors available. ### Roadmap alignment `ROADMAP.md` does not list overlapping Decisions image-gallery work. This is a focused improvement to the existing review surface rather than a new product area. ### Additional context The Storybook variants document both the collapsed thumbnail treatment and deterministic expanded gallery state for reviewer inspection. ## What Changed - Allow active Decisions rows with screenshot evidence to expand even when they have no inline resolver. - Keep compact thumbnails in collapsed rows and render up to three larger, linked images when expanded. - Add an accessible remaining-image tile that links to the related issue when more screenshots exist. - Add component coverage for image-only expansion and the remaining-image issue link. - Add collapsed and expanded image-gallery Storybook variants, including deterministic initial expansion. ## Verification - `pnpm exec vitest run ui/src/components/AttentionQueueRow.test.tsx` - `pnpm check:token-gates` - `pnpm --dir ui typecheck` - `pnpm --dir ui build-storybook` - QA visual verification (light + dark, no defects): https://github.com/paperclipai/paperclip/pull/9532#issuecomment-4964769485 ## Risks - Low risk: the change is isolated to Decisions row rendering and Storybook fixtures. - Rows with images gain a new expansion interaction, but existing inline resolver behavior and deep links remain intact. - The gallery intentionally limits the in-row preview to three images to avoid unbounded row height. > 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 - Anthropic Claude Opus 4.8 assisted with the original implementation and tests. - OpenAI `gpt-5.4` via Codex CLI assisted with current-master rebase integration, verification, and PR preparation. The runtime context-window size is not exposed; capabilities used include reasoning, repository tool use, code execution, and test execution. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
d32ed88443 |
fix(recovery): route recovery by failure cause (#9634)
## Thinking Path > - Paperclip is the open source control plane people use to coordinate AI-agent companies and their work. > - Its recovery subsystem detects stranded issue execution and decides whether to retry, escalate, or request operator intervention. > - The existing recovery path used a mostly generic owner ladder and generic execution contract, so transient failures could wake a manager who then performed the deliverable instead of repairing and returning the task. > - Provider quota failures also entered the same takeover path even when the correct action was to wait for capacity and retry the original assignee. > - Recovery actions already retain the source owner and evidence needed to choose a cause-specific route, render a scoped contract, and measure whether work was handed back. > - This pull request adds a cause-keyed recovery playbook, propagates its contract through every built-in adapter, and makes resolved recovery actions return work to the original owner by default. > - The benefit is bounded self-recovery that preserves task ownership, avoids needless management takeover, and makes recovery outcomes observable. ## Linked Issues or Issue Description No matching public GitHub issue was found. Related recovery work was reviewed but is not duplicated here: #9630 restores bounded recovery continuations, #8807 changes one assignee-ranking case, and #9404 records runtime-failure transition evidence. This change instead introduces cause-specific routing and recovery contracts across the recovery lifecycle. ### What happened? When an issue became stranded, recovery generally selected an owner through the same fallback ladder and rendered the normal execution contract. That made the recovery wake look like ordinary deliverable work, even when the correct action was to retry the original agent, repair its runtime, or wait for a provider quota reset. ### Expected behavior Recovery should select a response by failure cause, tell the recipient to recover rather than complete the deliverable, suppress takeover wakes for provider quota waits, and return repaired work to its original assignee unless the recovery owner explicitly completes it. ### Actual behavior Recovery could escalate transient failures to management, omit the cause-specific next action from the wake, and leave the recovery owner assigned after the runtime problem was resolved. ### Impact The generic path creates avoidable management work, ownership churn, and budget consumption while obscuring whether recovery successfully returned work to the responsible agent. ## What Changed - Added cause-keyed routing for process loss, missing disposition, provider quota limits, Codex output inactivity, workspace validation failures, and fallback recovery causes. - Added recovery-scoped wake rendering that replaces the generic execution contract with the failure summary, original assignee, attempt count, next action, and cause-specific playbook instruction. - Propagated the structured recovery contract through all built-in adapter execution paths, including Hermes local and gateway adapters. - Added provider-quota wait monitoring so capacity failures schedule the original assignee instead of enqueueing a takeover wake. - Added hand-back behavior and `handed_back` / `owner_completed` outcome accounting when recovery actions are resolved. - Added focused routing, renderer, quota-monitor, and hand-back regression coverage plus implementation-spec documentation. ## Verification - `pnpm exec vitest run packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/heartbeat-process-recovery.test.ts server/src/__tests__/heartbeat-workspace-branch-containment.test.ts server/src/__tests__/issue-recovery-actions.test.ts` - 4 test files passed; 194 tests passed. - Targeted `pnpm --filter ... typecheck` across `@paperclipai/adapter-utils`, `@paperclipai/shared`, `@paperclipai/server`, `@paperclipai/ui`, and all nine changed adapter packages. - 13 affected workspace packages passed typecheck. - `pnpm check:token-gates` - All UI token gates passed. ## Risks - Recovery routing behavior changes for stranded work, so an incorrectly classified cause could select a different recipient than before; fallback causes retain the existing management ladder. - Provider quota detection depends on structured failure evidence and conservative text matching; unmatched failures continue through fallback recovery. - Adapter prompt plumbing changes across built-ins, covered by shared renderer tests and compile-time call signatures. > 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 with exact model ID `gpt-5.6-sol`, using reasoning, tool use, and code execution. The runtime does not expose its configured context-window size. ## 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 searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |