mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-08 00:54:38 +02:00
0a09e4d975e1e1cd7de65fbd1ca730b9cd9f97ea
1520
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0a09e4d975 |
feat(decisions): add desk workflow and retention (#10672)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Decisions desk shows work that needs a human decision > - The queue foundation can group and rank decision work > - Operators also need a focused daily view and a safe way to handle old work > - This pull request adds the desk controls, the aging shelf, and reversible retention > - It also binds bulk archive decisions to the exact reviewed item set > - The benefit is a smaller daily queue without lost or orphaned work ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting: server, UI, database, and shared contracts. **Problem or motivation** Decision work can grow into one large company list. Operators need quick queue and date controls. Old items also need a safe retention path that does not delete work. **Proposed solution** Add queue and date controls to the Decisions desk. Compute the aging shelf on the server. Archive idle items after 90 days unless an operator keeps them. Keep archived items searchable and revivable. Notify origin agents in one batch per sweep. Bind bulk archive proposals to a signed, exact item manifest. **Alternatives considered** Client-only aging can drift across browsers and source kinds. Deleting old rows removes audit and recovery paths. An unsigned dynamic bulk query can archive items that the reviewer did not inspect. **Roadmap alignment** This work supports the Work Queues and decision-memory directions in `ROADMAP.md`. It extends the Decisions and attention-feed foundation from #10651. Related earlier work includes #9380, #10010, and #10474. ## What Changed - Added the queue rail, date chips, decide split, triage strip, queue page, and aging shelf UI. - Added server-owned shelf state with per-queue retention overrides. - Added reversible retention state, archive history, and an idempotent notification outbox. - Added the 90-day archive sweeper, Keep exemption, archived feed query, and revive actions. - Added one origin-agent notification per agent and sweep. - Added signed bulk archive proposals with exact-set and version checks. - Persisted queue-exclusion reasons atomically and kept cross-domain source resolution per-item until it has an exact-set transaction contract. - Added API contracts, OpenAPI entries, migration coverage, focused tests, and Storybook screens. ## Verification - `pnpm -r typecheck` - `pnpm test:run` (server: 329 files and 3,453 tests passed; UI: 408 files and 3,362 tests passed) - `env -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY pnpm exec vitest run cli/src/__tests__/secrets.test.ts` - `pnpm build` - `pnpm check:token-gates` - Focused retention, attention, decisions, migration replay, startup, and UI API tests. - Complete queue snapshot regression with 51 items across the normal 50-item page boundary. The unmodified CLI test reports one warning assertion in this runtime because the harness injects static AWS credential variables. The isolated test passes when those two variables are removed. ## Risks - The migration adds retention and notification outbox tables. It uses idempotent table, index, and foreign-key creation. - Retention runs on the heartbeat scheduler interval. Compare-and-set version checks prevent stale archive writes. - Bulk archive acceptance fails closed when authority, activity, version, or the reviewed set changes. - Archive is reversible and does not delete source records. > 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 `gpt-5.6-sol`. The model used tool calls, code execution, database migration generation, and test execution. The context-window size is not exposed in 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: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
dcac49a4fd |
feat(workspaces): defer isolated setup until runtime start (#10653)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Isolated workspaces give each task a safe and reproducible checkout. > - The existing setup cloned the development database before an agent needed to run the app. > - This made worktree creation slower and heavier for tasks that never start a service. > - Runtime services already use one server start path for heartbeat, operator, and startup recovery flows. > - This pull request moves heavy setup to that start path and keeps worktree creation lean. > - The benefit is faster isolated workspace creation with the same reliable runtime setup when a service starts. ## Linked Issues or Issue Description Related pull request: #10652 covers the initial deferred database-seeding slice. This pull request supersedes it with end-to-end runtime provisioning and safe cleanup. **What existing behavior does this improve?** This improves isolated worktree creation, runtime service startup, and isolated instance cleanup. **Subsystem affected** Cross-cutting: CLI worktree setup, server runtime orchestration, shared workspace contracts, and development scripts. **Current behavior** Paperclip seeds an isolated development database during worktree creation. It can also leave an isolated instance directory after workspace teardown. This work happens even when no runtime service starts. **Proposed behavior** Paperclip creates the worktree with a lean eager setup. It runs an idempotent runtime provision command before the first managed service spawn. Concurrent starts share one provision attempt. Teardown removes the isolated instance safely. **Reason and benefit** Many agent tasks only edit and test code. They do not need a running Paperclip instance. Deferring the database seed reduces workspace startup cost while preserving automatic setup for tasks that start the app. **Breaking changes** None. The new runtime provision command is optional. Existing workspace behavior is unchanged when it is absent. ## What Changed - Split Paperclip worktree setup into a lean eager script and an idempotent runtime provision script. - Added `runtimeProvisionCommand` to project, issue, realized workspace, and persisted workspace contracts. - Added a per-workspace provision mutex before local service spawn for heartbeat, operator, and startup recovery flows. - Added a persisted `provisioning` service state and the `workspace_runtime_provision` operation phase. - Kept provision time outside the service readiness timeout and made failed attempts visible and retryable. - Reclaimed isolated instance data during safe workspace teardown. - Serialized deferred database seeding across processes and bound teardown to the instance root captured in persisted workspace metadata. - Added tests for config flow, concurrency, retry, no-op behavior, readiness timing, scripts, CLI commands, and cleanup. - Documented the eager and runtime provisioning contracts. ## Verification - `pnpm -r typecheck` - `pnpm build` - `pnpm test:run` (server: 3,201 passed; UI: 3,345 passed; the CLI phase exposed one environment-sensitive AWS doctor assertion because the agent runtime injects static AWS credentials) - `env -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY pnpm exec vitest run cli/src/__tests__/secrets.test.ts -t 'passes AWS doctor checks when non-secret provider config is present'` - Focused runtime tests cover serialized provisioning, retry after stderr failure, absent-command no-op behavior, operation logging, persisted state order, and readiness timeout exclusion. - Focused CLI and cleanup tests cover concurrent seed serialization, stale-lock fail-closed behavior, persisted instance ownership, and rewritten sibling pointers. ## Risks - A faulty runtime provision script blocks service startup. Paperclip records stderr, marks the service failed, and retries on the next start. - Concurrent service requests share an in-process provision attempt, while the seed command uses an atomic filesystem lock across processes. A stale lock fails closed and requires an operator to verify no seed is running before removing it. - Isolated instance cleanup is destructive. The cleanup service validates ownership and path containment before removal. > 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`, with agentic reasoning, tool use, and code execution. The service does not expose the 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> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
ec84eb7342 |
fix(ui): defer Inbox re-sort to attention boundaries (#10623)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The Inbox lists work items by recent activity. > - An archive changes activity data and can change the computed order. > - The list can then move rows under the pointer during a fast archive sequence. > - The Inbox must keep its shown order while the operator is engaged. > - This pull request adopts fresh order only at an idle, visibility, or view-change boundary. > - The benefit is a stable Inbox that still receives fresh data and new items. ## Linked Issues or Issue Description **What happened** The Inbox re-sorts while an operator archives items quickly. An archive can lower a parent group's activity time. Unrelated rows then move, and the row under the pointer can change. **Expected behavior** Keep the shown order stable while the operator works in the Inbox. Insert new items at their computed positions. Adopt a fresh order after an idle period, after a long hidden-tab interval, or when the view changes. **Steps to reproduce** 1. Open the Inbox on the Mine tab with several items, including nested items. 2. Archive several items quickly with the pointer or keyboard. 3. Observe rows move before the archive sequence is complete. **Deployment mode** Any deployment. This change affects only the web UI. **Additional context** This PR supersedes the closed subset PR #10621. It keeps the full change in one review. ## What Changed - Added an order-pin utility for sections, root rows, non-issue items, and nested children. - Kept archived rows in place for the existing five-second undo interval. - Added an attention-boundary hook for idle, visibility, and view-change commits. - Connected pointer, wheel, hover, keyboard, and archive interactions to the idle boundary. - Made idle commits repeat while the Inbox stays idle. - Made view changes adopt the fresh order in the same render. - Added unit and integration coverage for order pins and attention boundaries. ## Verification - `pnpm exec vitest run ui/src/hooks/useInboxSortAttention.test.tsx ui/src/lib/inboxOrderPin.test.ts ui/src/pages/Inbox.test.tsx` — 33 tests passed. - `pnpm check:token-gates` — passed. - `pnpm -r typecheck` — passed. - `pnpm build` — passed. - `pnpm test:run` — 3,429 tests passed, 2 skipped, and 1 unrelated server test failed. The isolated failure expects `issue_commented` but current master records `heartbeat.scheduling_suppressed` in `plugin-orchestration-apis.test.ts`. ## Risks - Low risk. The change is client-only and does not change the sort algorithm. - A bad pin can show an old order until the next boundary. The tests cover repeated idle commits and immediate view 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 Opus 4.8 (`claude-opus-4-8`), extended thinking, tool use, and code execution for the implementation. - OpenAI Codex (`gpt-5`), reasoning, tool use, and code execution for PR preparation and verification. The serving snapshot, context-window size, and hidden reasoning configuration were not exposed. ## 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> |
||
|
|
30c49c8327 |
feat(decisions): add queues and prioritized attention feed (#10651)
<!-- Write all pull request text in Simplified Technical English (ASD-STE100): short sentences, one instruction per sentence, simple approved vocabulary, and the active voice. --> ## Thinking Path > - Paperclip is the open source control plane for companies of AI agents. > - Operators use the attention feed to find decisions that need action. > - The feed has eleven source kinds, but it has no durable queue or triage state. > - The feed also returns every item and lacks decision deadlines, snooze state, and decision-focused ordering. > - This pull request adds secure queue sidecars and enriches the attention feed with triage data, filters, cursor pagination, and decide-now ranking. > - The benefit is a bounded feed that can show the most urgent decisions first without weakening source visibility rules. ## Linked Issues or Issue Description This pull request replaces the closed [#10634](https://github.com/paperclipai/paperclip/pull/10634). It combines that queue foundation with the dependent attention-feed change as one review unit. **Subsystem affected** Database schema, shared contracts, server authorization and REST APIs, and the UI attention client library. **Problem or motivation** The attention feed can contain hundreds of mixed decision items. Operators cannot group them into durable queues, set a decision deadline, snooze an item, or request a bounded page ordered by urgency. The current client must download the full feed on each refresh. **Proposed solution** Store queue membership and triage state by stable attention identity. Re-authorize each source during queue reads and writes. Enrich attention items with queue, deadline, snooze, expiry, rule, and origin data. Add activity and queue filters, opaque cursor pagination, decide-focused ordering, and a decide-now count. **Alternatives considered** Adding queue fields to every source would duplicate schema and authorization logic across eleven source kinds. Client-only filtering and sorting would still transfer the full feed and would make pagination unstable. **Roadmap alignment** This change improves the core decision-attention surface and operator oversight. It does not implement the separate general-purpose work queue milestone in `ROADMAP.md`. ## What Changed - Added company-scoped queue, membership, triage, and append-only event tables with actor and run provenance. - Added queue CRUD, item membership, starter-rule discovery, and decide-by and snooze endpoints. - Kept source authorization on each queue mutation, read, and count. - Added attention fields for expiry, rule, origin agent, queues, decide-by attribution, and snooze state. - Added activity date filters, queue filters, opaque cursor pagination, and configurable page limits. - Added decide-now ordering by deadline, expiry, severity, and activity. - Added `decideNowCount` and excluded actively snoozed items from the default feed. - Updated the shared and UI client contracts. - Added focused server, route, OpenAPI, and UI client tests. ## Verification - `pnpm exec vitest run server/src/__tests__/attention-service.test.ts server/src/__tests__/decision-queues-routes.test.ts server/src/__tests__/openapi-routes.test.ts ui/src/api/attention.test.ts ui/src/lib/attention.test.ts` (72 tests passed) - `pnpm --filter @paperclipai/db check:migrations` - `pnpm -r --filter @paperclipai/db --filter @paperclipai/shared --filter @paperclipai/server --filter @paperclipai/ui typecheck` - `git diff --check origin/master...HEAD` ## Risks - The migration adds four company-scoped tables and provenance foreign keys. Migration numbering and safety checks pass. - Attention reads can lazily create starter queues and memberships. Inserts are idempotent, audited, and transactional. - Cursor validity depends on the filtered feed. The API returns a clear validation error when the cursor item no longer exists in that feed. - Queue reads re-check source visibility. This favors correct authorization over fewer queries. > 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, model `gpt-5`. The runtime used agentic reasoning, repository tools, code execution, and test execution. The runtime did not expose the 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> |
||
|
|
3dec88ce90 |
feat(agents): warn when an agent's escalation path routes to a paused manager (#10657)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agents escalate work up the org chart (`reports_to`), and operators pause agents — notably, instance imports pause every agent by default > - A paused manager does not invalidate the chain (subordinates stay invokable), so nothing surfaces when an operator unpauses workers but leaves their manager paused > - Escalations then dead-letter silently: agent-created issues assigned to the paused manager sit in a queue nothing will ever run > - This pull request computes paused ancestors in the existing org-chain health model and surfaces a non-blocking warning on the agent read models and detail page > - The benefit is that the operator learns their escalation paths are dead before work vanishes into them ## Linked Issues or Issue Description Fixes #10647 (companion to #10648, which refuses agent-initiated assignment to paused agents at write time — this PR makes the standing hazard visible) ## What Changed - `AgentOrgChainHealth` gains two additive, optional fields: `pausedAncestors` (paused agents in the `reports_to` chain) and `escalationWarning` (human-readable, only set when the agent itself can work — a paused/terminated agent's escalation path is moot). Chain validity, invokability, and assignability are byte-identical. - No server route changes needed: the fields flow through every existing agent read model (list, detail, org chart) since they ride the same `getAgentWorkEligibility` computation. - Agent detail page shows an amber "Escalation path is paused" banner (same visual language as the invalid-chain banner, but non-blocking) with the warning text naming the paused manager and the two remedies. ## Verification - `pnpm vitest run packages/shared/src/agent-eligibility.test.ts` — 5 new cases: paused direct manager warns; paused grandparent through a healthy manager warns; the agent itself paused → no warning (but ancestors still reported); fully active chain → no warning, empty list; terminated ancestor keeps the invalid-chain classification without double-counting as paused. - Full `@paperclipai/shared` suite (392 tests) and `agent-eligibility-routes` (54) unchanged. - `tsc --noEmit` in shared, server, and ui. ## Risks - Low. Purely additive fields plus one UI banner; no behavior gates on the new data. ## Model Used Claude Fable 5 (`claude-fable-5`, Anthropic) via Claude Code — extended thinking, agentic tool use. No other models involved. ## 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 |
||
|
|
c185e64b77 |
feat(ui): chat-style task view behind an experimental flag (#10606)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Operators spend most of their time on the issue detail page. They talk to the assigned agent there through comments. > - The current page reads as a ticket form. The thread sits below properties, the composer sits mid-page, and live agent activity renders as dense transcript logs. > - Talking to an agent is a conversation. A chat-first layout matches that mental model better than a ticket form. > - A layout change this large must not disrupt current users. It needs a safe opt-in path and full parity with the existing thread features. > - This pull request adds a chat-style task view behind a new "Chat-Style Tasks" experiment toggle. The flag is off by default and the existing page is unchanged when it is off. > - The benefit is a focused, readable conversation with the agent: live tool activity folds into compact summaries, the composer stays at the bottom, and properties, plan, and artifacts move into header tabs. ## Linked Issues or Issue Description Refs #49 (chat with agents is a much-wanted feature). Related PRs found in the dedup search: - #4489 — an earlier, closed attempt to promote the conversation to the primary surface on issue detail. This PR is a fresh, flag-gated take on the same goal. - #8837 — an open PR that proposes a two-column task layout. It restructures the same page but keeps the ticket paradigm; this PR is orthogonal because it is opt-in and chat-first. **Subsystem affected** UI (issue detail page). **Problem or motivation** The issue detail page presents agent conversations as a ticket: properties first, thread below, composer in the middle of the page, and raw transcript noise during live runs. Users who mainly converse with their agents must scroll past chrome to follow the conversation, and live activity is hard to read. **Proposed solution** An opt-in chat-style view of the issue detail page, gated by a new "Chat-Style Tasks" experiment toggle in Settings → Experimental. With the flag on, the thread fills the center pane, the composer docks to the bottom of the viewport, Properties / Plan / Artifacts become header tabs, live turns show a status pill with the current tool action and elapsed time, and settled turns collapse to a "Worked · N tools" summary that expands into per-tool rows. With the flag off, nothing changes. **Alternatives considered** Restyling the existing layout in place (rejected: too disruptive without an opt-out), and a separate chat page beside the issue page (rejected: splits the task's single source of truth). A per-request lab page (`/task-chat-lab`, dev-only) was kept for design iteration instead. **Roadmap alignment** ROADMAP.md "CEO Chat" wants lighter conversations that still resolve to real work objects. This PR keeps the core task-and-comments model — it only changes presentation, opt-in — so it does not duplicate that planned work. ## What Changed - New `enableTaskChatRedesign` instance setting, exposed as a "Chat-Style Tasks" experiment card in Settings → Experimental (shared feature catalog, validators, server instance-settings service, and UI settings page). - New `ui/src/components/task-chat/` component family: chat thread with turn grouping, agent reply bubbles, live status pill, collapsible turn summaries with per-tool rows, plan tab with a sticky CTA action bar, inline interaction cards, per-request mode chips, and a bottom-docked composer. - A shared tool taxonomy (`tool-taxonomy.ts`) maps tool names to verbs and icons; the status pill, tool rows, and the classic transcript view all use it. - A transcript adapter converts stored run logs into chat turns; it dedupes tool-call updates by `toolUseId` so tool counts match the expanded rows, and it keeps a tool row's first real name when later generic updates arrive. - Composer: posts on Cmd/Ctrl+Enter, supports image paste with object-URL thumbnail previews (revoked on clear/unmount), and uploads through the issue attachments route. - `IssueDetail.tsx`: with the flag on, pane tabs move to the header bar, the header is not sticky, and the chat fills the center; with the flag off, the previous layout renders unchanged. - Motion tokens for the new animations live in `ui/src/index.css` with a `motion-tokens.ts` catalog and a test that keeps the two in sync (the catalog now also covers the shared enter/exit/swap tokens that the decision/quicklook block declares). - A dev-only `/task-chat-lab` page with fixtures and a tweak panel for motion tuning. ## Verification - `pnpm typecheck` — clean across the workspace. - `pnpm check:token-gates` — 3/3 CLEAN. - `cd ui && pnpm vitest run` — 3,344 of 3,345 tests pass locally. The one failure is `IssueProperties.test.tsx` monitor-row time formatting, which is timezone-sensitive: it also fails on unmodified `origin/master` in a non-UTC timezone and passes with `TZ=UTC`. It is not related to this change. - `cd server && pnpm vitest run src/__tests__/instance-settings-service.test.ts` — 21/21 pass (covers the new setting). - Manual: start the dev server, open Settings → Experimental, enable "Chat-Style Tasks", and open any issue. The thread fills the page, the composer docks to the bottom, and Properties / Plan / Artifacts appear as header tabs. Assign an agent and comment to watch a live run: the status pill shows the current tool action with elapsed time, and the finished turn folds into a "Worked · N tools" summary. Disable the toggle and confirm the classic page is unchanged. - Visual snapshot baselines are intentionally not updated: per `doc/design/DECISION-SHEET.md`, "Per-change snapshot verification demoted to dormant (Jul 13 2026)". ## Risks - The flag-off path goes through the same `IssueDetail.tsx` file, so a regression there would affect current users. Mitigation: the classic markup renders through the same components as before behind explicit flag conditionals, and the full UI suite passes. - The transcript adapter interprets stored run-log formats, including legacy entries without `toolUseId`. Malformed logs degrade to generic tool rows rather than crashing. - The new view changes no server behavior other than one additive instance setting; it is additive and default-off. Overall risk with the flag off is low. ## Model Used - Claude (Anthropic), model id `claude-fable-5` (Claude Fable 5), extended thinking enabled, agentic tool use (file editing, shell, test execution) via Claude Code / Claude Agent SDK. ## 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 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
9c1f8e7887 |
feat(decisions): add first-class propose mode (#10010)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agents can currently perform many mutations directly, while humans often need a durable review point before cross-issue or destructive actions occur > - Existing approvals and issue-thread interactions do not provide a standalone, reusable object for presenting options, collecting typed inputs, detecting stale targets, and auditing effect execution > - The control plane therefore needs a first-class propose mode that separates an agent's recommendation from the governed mutation it may cause > - This pull request adds Decisions v1 across the database, shared contracts, server execution and telemetry, agent skill guidance, and operator UI > - The benefit is that agents can propose multi-option actions safely while operators get explicit provenance, fail-closed execution, per-effect results, and a focused attention workflow ## Linked Issues or Issue Description ### Subsystem affected Cross-cutting: `packages/db`, `packages/shared`, `server`, and `ui`. ### Problem or motivation Agents need a governed way to propose consequential work without immediately mutating issues, especially when one choice can affect several issue trees. Existing approvals and issue-thread interactions do not provide a standalone object with typed options, target snapshots, effect-level authorization, expiration, execution outcomes, and reusable attention-feed presentation. ### Proposed solution Add first-class Decisions that store options and typed inputs, surface open proposals in the operator attention feed, validate target freshness and the origin-agent/operator authorization intersection at decision time, execute a bounded set of auditable effects, and retain terminal outcomes. Decisions v1 supports comments, status and assignee changes, follow-up issue creation, blocker resolution, and issue-tree cancellation, plus bundle grouping, expiration/dismissal, rule-key telemetry, and agent-facing API guidance. ### Alternatives considered - Extend approvals with arbitrary effects: rejected because approvals represent governed yes/no actions and would become an unsafe generic mutation envelope. - Model every proposal as an issue-thread interaction: rejected because decisions can span several targets and need independent lifecycle, telemetry, idempotency, and effect results. - Let agents perform the mutation and ask for retrospective review: rejected because it removes the pre-execution governance boundary this feature is meant to provide. ### Roadmap alignment Aligns with `ROADMAP.md` sections **Agent Reviews and Approvals**, **Enforced Outcomes**, **MCP Tool Gateway & Apps (governed tool access)**, and **Activity History** by making explicit decisions, authorization gates, auditable execution, and terminal outcomes first-class control-plane objects. ### Additional context This does not replace existing approvals or issue-thread interactions, and it does not add an unrestricted generic mutation effect. ## What Changed - Added company-scoped decision, option, target, and effect-execution schema plus migration and shared TypeScript/Zod contracts. - Added decision routes and services for propose, list/get, decide, dismiss, cancel, target freshness checks, authorization intersection, idempotency, activity logging, and execution auditing. - Added rule-key decision telemetry and attention-feed metadata so open decisions are visible and measurable. - Added agent skill documentation for proposing and resolving decisions through the Paperclip API. - Added the Decisions UI: API client, query keys, inline attention resolver, bundle grouping, target-issue strip, terminal history, destructive confirmation, and per-effect result rendering. - Added server service coverage, DecisionCard state tests, and Storybook stories for the supported visual states. ## Verification - `pnpm -r typecheck` — passed. - `pnpm test:run` — 2,876 passed, 1 skipped, with one unrelated cross-suite cleanup-order failure in `heartbeat-responsible-user-invariant.test.ts`; the failing file passes in isolation (`6/6`). - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/heartbeat-responsible-user-invariant.test.ts` — passed. - `pnpm --filter @paperclipai/ui exec vitest run src/components/DecisionCard.test.tsx` — passed (`9/9`). - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/authz-existence-oracle-guard.test.ts src/__tests__/openapi-routes.test.ts` — passed (`5/5`). - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/decisions-service.test.ts` — passed (`16/16`). - `pnpm --filter paperclipai exec vitest run src/__tests__/company-import-export-e2e.test.ts` — passed (`1/1`). - `pnpm --filter @paperclipai/server typecheck` and `pnpm --filter paperclipai typecheck` — passed. - `pnpm build` — passed. - Rebased-head focused suite — passed (`6` files, `88` tests): shared decision contracts, Decisions service, OpenAPI routes, startup feedback export, DecisionCard states, and attention helpers. The follow-up stale-secondary-target regression passes in the DecisionCard suite (`10/10`). - Rebased-head scoped typechecks — passed for `@paperclipai/shared`, `@paperclipai/db`, `@paperclipai/server`, and `@paperclipai/ui`. - Rebased-head migration numbering and safety checks — passed after renumbering the additive migration to `0193` and making it replay-safe for environments that applied the earlier feature-branch number. - `pnpm check:token-gates` — passed with all gates clean. - GitHub PR workflow and Greptile review for `1f9f7645882d05dfdd9c99377c03a1f53f20e8be` — running after the stale-secondary-target fix and PR metadata refresh on July 27, 2026. - `pnpm --filter @paperclipai/ui build-storybook` exposes an existing Storybook version mismatch (`storybook` 10.4.6 vs `@storybook/addon-docs` 10.5.0); Decisions stories were validated with the docs addon temporarily disabled and the tracked config remains unchanged. ## Risks - **Migration:** Adds replay-safe migration `0193`; migration numbering and safety checks pass. The new tables and indexes are additive. - **Authorization:** Effect execution intersects the proposing agent's permissions with the responsible user context and fails closed; mistakes could reject a valid proposal rather than silently over-authorize it. - **Concurrency:** Target snapshots and idempotency keys protect against stale or duplicate execution, but reviewers should focus on mixed-effect partial outcomes and retry behavior. - **UI:** Decisions are integrated into the existing attention feed rather than a separate navigation surface, reducing routing risk but increasing the importance of attention-item metadata compatibility. > 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 using `gpt-5.6-sol` for final PR preparation, review fixes, and verification; repository tools and code execution were enabled, and context-window size is not exposed in this runtime. - Anthropic Claude Opus 4.8 with 1M context assisted with the Decisions UI implementation, as recorded in the relevant commits. ## 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> |
||
|
|
71231dfa38 |
feat(audit): agent audit UI — company page + per-agent tab (#9744)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Operators need an audit record of agent actions across tasks, comments, documents, approvals, and runs > - The permission-gated audit read API provides that record, but operators cannot inspect it in the product > - A readable UI must preserve company boundaries, server-side permission decisions, and redaction > - Audit exports must also be safe to open in spreadsheet software and must record the export itself > - This pull request adds company and per-agent audit views plus a guarded CSV export > - The benefit is a searchable, filterable, and reviewable agent action history with direct links back to work ## Linked Issues or Issue Description **Feature.** This change adds the frontend and CSV export for the agent action audit log. Refs #9731 and #9735. - Problem: agent actions are recorded, but operators have no readable product surface to inspect or export them. - Solution: add a company audit page and a per-agent Audit tab that use the permission-gated audit API. - Alternative: build a separate plugin-only surface. This was rejected because the existing permission model already supports a unified, server-authoritative view. This pull request targets the audit epic branch, which contains the merged #9735 audit API. ## What Changed - Added a company Audit page and sidebar entry. - Added a per-agent Audit tab with a fixed agent filter. - Added filters for agent, responsible user, action domain, entity type, and date range. - Added task and run links, responsible-user context, cursor pagination, and readable action text. - Added a permission-denied Enterprise card for callers without `audit:view_agent_actions`. - Added a CSV export that is permission-gated, capped, self-audited, CSV-escaped, and protected against spreadsheet formula injection. - Preserved the merged audit API cursor validation, redaction, and sub-millisecond pagination behavior. ## Verification - `pnpm exec vitest run ui/src/pages/audit/AuditFeed.test.tsx` — 6 passed. - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/agent-action-audit-routes.test.ts` — 8 passed with embedded PostgreSQL. - `pnpm -r typecheck` — passed across all workspaces. - `pnpm build` — passed across all workspaces. - `pnpm test:run` — all completed shards passed except one environment-sensitive CLI assertion caused by injected static AWS credential variables; the exact test passes 8/8 with those variables unset. - Manual Chromium QA exercised the populated feed, active filters, permission-denied card, per-agent tab, and CSV export. ## Screenshots and Manual QA - [All audit states exercised in Chromium](https://github.com/paperclipai/paperclip/pull/9744#issuecomment-4998997001) - [Detailed browser report and per-agent tab root cause](https://github.com/paperclipai/paperclip/pull/9744#issuecomment-4998771061) The per-agent redirect defect found during QA is fixed in this branch. ## Risks Low to moderate risk. The UI and export route are additive and use the existing company-scoped permission gate. The main risks are large exports and spreadsheet interpretation. The export is capped at 10,000 rows, records truncation accurately, and prefixes formula-like cells as text. There are no schema changes or migrations. > 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, 1M context, extended thinking, tool use, and code execution produced the original implementation. - OpenAI Codex, GPT-5 (deployment ID and context window not exposed), reasoning, tool use, code execution, browser-test orchestration, and GitHub review tooling repaired and verified the pull request. ## 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> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
86b265bb85 |
test(ui): isolate Cases routing regression (#10591)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The UI test suite protects the board route table > - The Cases routing regression test needs only the route table and sentinel pages > - The test initialized the full cloud access query flow for each route > - That unrelated setup made the two assertions spend several seconds polling > - This pull request isolates the routing dependency and removes the long timeout > - The benefit is faster and more focused route regression coverage ## Linked Issues or Issue Description **What happened?** The Cases routing regression test initialized cloud health, session, and board access queries. Its two route assertions spent about 6.69 seconds in test execution. **Expected behavior** The route regression test must bypass unrelated cloud access checks and resolve the two route assertions synchronously. **Steps to reproduce** 1. Run `pnpm --dir ui exec vitest run src/App.cases-routing.test.tsx` on the base commit. 2. Inspect the Vitest test duration. 3. Observe that the test waits through unrelated query transitions. **Paperclip version or commit** `7301fae942c3d5826974335cb40d6f1e0d95d1e0` **Deployment mode** Built from source. The defect affects the UI unit test suite. Related pull request: #9198 introduced the Cases route regression coverage. ## What Changed - Mock `CloudAccessGate` at the routing boundary. - Import the app after hoisted CSS setup and module mocks. - Remove the query client and three unrelated API mocks. - Replace long polling with a bounded three-turn route wait. - Remove the custom 20-second test timeouts. ## Verification - `pnpm --dir ui exec vitest run src/App.cases-routing.test.tsx` - `pnpm --filter @paperclipai/ui typecheck` - `pnpm check:token-gates` The focused run passed both tests. Test execution changed from about 6.69 seconds on the base commit to 40 milliseconds on this branch. ## Risks Low risk. The production route table is unchanged. The test still renders the real `App` route table and the same sentinel pages. > 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 model ID `gpt-5`. The context-window size is not exposed to this run. The run used reasoning, repository tools, code execution, and GitHub 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> |
||
|
|
627728bdde |
feat: add authoritative issue PATCH receipts (#10478)
<!-- Write all pull request text in Simplified Technical English (ASD-STE100): short sentences, one instruction per sentence, simple approved vocabulary, and the active voice. --> ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents update tasks through the issue API. > - The update response did not state which values changed. > - Blocker updates also did not echo the scalar blocker IDs. > - Agents therefore used an extra GET request to confirm a successful write. > - This pull request adds an authoritative change receipt and an optional small response. > - The benefit is fewer API calls with a clear and compatible write contract. ## Linked Issues or Issue Description No public GitHub issue exists for this change. ### Subsystem affected Cross-cutting: `server/`, `packages/shared`, and the UI issue cache. ### Problem or motivation A successful issue PATCH returned the updated issue, but it did not identify the effective changes. Blocker writes returned relation summaries without the scalar IDs. Agents could not distinguish a confirmed clear operation from missing data. The response must confirm committed field and blocker changes while existing UI clients continue to receive the full issue by default. ### Proposed solution Add a `changes` receipt. Add a conditional `blockedByIssueIds` echo. Support `Prefer: return=minimal`. Keep the full response as the default. ### Alternatives considered Make the small response the default for agent tokens. This would create different response contracts by actor type, so this pull request does not use that design. ### Roadmap alignment This is a focused control-plane reliability improvement. It does not duplicate an open roadmap milestone. ## What Changed - Compute committed issue row and relation changes in the issue service. - Omit no-op fields and truncate changed long text values to 200 characters. - Echo blocker ID arrays for blocker set and clear requests. - Add the opt-in `Prefer: return=minimal` response and `Preference-Applied` header. - Keep receipt metadata out of React Query issue caches. - Add route and embedded Postgres tests for the new contract. ## Verification - `pnpm exec vitest run server/src/__tests__/issue-activity-events-routes.test.ts` - `pnpm exec vitest run server/src/__tests__/issues-service.test.ts -t "returns authoritative update receipts for row fields and blocker relations"` - `pnpm --filter @paperclipai/shared typecheck` - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/ui typecheck` - `pnpm check:token-gates` - `git diff --check` ## Risks - Low compatibility risk. The default response only adds receipt fields. - Minimal mode is opt-in. Existing clients do not receive a smaller body. - The receipt excludes `updatedAt` because the response already returns it as the freshness anchor. - Prose API and agent workflow guidance will follow after the server contract is available. > 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 based on GPT-5. The exact deployment ID, context window size, and reasoning mode are not exposed to the agent. The agent used repository tools, 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> |
||
|
|
b1ac92f305 |
fix(ui): recover blockquotes the markdown editor escaped as backslash-gt (#10466)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The web UI uses one shared markdown editor for comments, issue descriptions, and documents. > - Users type `>` at the start of a line to insert a blockquote. > - The live editor shortcut does not always run in every browser and input method. > - The markdown exporter then changes the leading `>` to `\>` and saves literal text. > - The saved text does not render as a blockquote. > - This pull request restores the blockquote marker when markdown enters or leaves the editor. > - The benefit is reliable blockquote insertion on every surface that uses the shared editor. ## Linked Issues or Issue Description No public GitHub issue exists. Related prior attempt: #10465. **What happened?** The shared markdown editor sometimes saved a blockquote as literal text. This happened when the live shortcut did not run. The exporter saved `\> text`, which rendered as literal `> text`. **Expected behavior** A line that starts with `>` must render as a blockquote in comments, issue descriptions, and documents. **Steps to reproduce** 1. Open a task comment composer, description editor, or document editor. 2. Add `> ` to an existing line, or use an input method that does not run the live shortcut. 3. Save the content. 4. Observe that the saved line renders as literal text instead of a blockquote. **Paperclip version or commit** `master` at `78f8c6c3d4`. **Deployment mode** Self-hosted server. ## What Changed - Add `unescapeBlockquoteMarkers()` to restore block-level `\>` markers. - Keep indented code, list content, nested content, and fenced code unchanged. - Apply the helper when markdown enters and leaves `MarkdownEditor`. - Add focused tests for line position, indentation, container prefixes, and CommonMark fence rules. ## Verification - `pnpm exec vitest run ui/src/lib/blockquote-markdown.test.ts` passes with 22 tests. - `pnpm exec vitest run ui/src/components/MarkdownEditor.test.tsx` passes with 37 tests. - `pnpm --filter @paperclipai/ui typecheck` passes. - `pnpm check:token-gates` passes. - `git diff --check origin/master...HEAD` passes. - A browser harness used the real `MarkdownEditor` and `IssueChatThread` composer. It confirmed that `> text` renders as a blockquote and exports as `> text`. - The [Cutter preview](https://github.com/paperclipai/paperclip/pull/10466#issuecomment-5140558263) supplies a task-page screenshot and an editor interaction video. ## Risks - Low risk. The helper returns the input unchanged when it contains no `\>`. - A paragraph that deliberately starts with literal `\>` now becomes a blockquote. The editor has no literal-marker control, so this matches the available input behavior. - There are no database, API, or migration 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 Opus 4.8 (`claude-opus-4-8`, 1M context), extended thinking, with tool use and code execution. - OpenAI Codex with GPT-5 (`gpt-5`; runtime build and context-window metadata were not exposed), with reasoning, tool use, code execution, and GitHub review 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 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 (none needed) - [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> |
||
|
|
492555aaf9 |
design(decisions): flatten decision cards to two task-borrowed types (#10474)
The Decisions queue ran five parallel colour/icon vocabularies chosen by source kind, plus a separate severity badge, so two rows needing the same response could look unrelated and none of it matched the task list. Every row now resolves to one of two kinds, each borrowing the task status it corresponds to: blocking renders as `blocked`, review as `in_review`, both through StatusGlyph and the existing --status-task-icon-* tokens. Source kinds keep their own wording; only colour and icon merge. Card anatomy follows the design mock: no left accent rail, rounded cards 16px apart, a "/"-separated meta breadcrumb, a named See more / See less control, and no separately tinted drawer when expanded. Verb order is fixed across both states. Severity moves from chrome to a toolbar filter. Four defects fixed along the way: - blocked rows reported themselves as their own blocker (server-side) - the task key was missing wherever the row's subject IS the task - the task quicklook stuck open, because closing handed focus back to a trigger that opens on focus - the card ring appeared on click, and only on cards with a toggle Also: the standard task preview is aligned to its trigger's text and scales out of it, the task eyebrow renders its project as a tile, and the first motion tokens land alongside the disclosure and crossfade. Supersedes #9574 and #9575. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
90ead239a8 |
feat(ui/server): name cross-company environment secret refs instead of calling them missing (#10577)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Environment configs (sandbox providers, SSH) can bind stored company secrets through `format: "secret-ref"` fields, picked in the environment editor's secret picker > - Environments are instance-scoped and shared by every company on an instance, but the picker lists only the current company's secrets, so a ref pointing at another company's secret renders as "Missing secret (…)" in destructive styling > - That state is indistinguishable from a genuinely deleted secret, so operators "fix" a healthy binding by creating a duplicate secret in their own company — the exact sequence that used to corrupt bindings before #10576 > - This pull request adds an instance-gated metadata endpoint for an environment's secret refs and teaches the picker to name a cross-company secret and its owner honestly > - The benefit is that operators can tell a healthy cross-company binding from a broken one, and stop creating duplicate secrets ## Linked Issues or Issue Description **Is your feature request related to a problem? Please describe.** In the environment editor, a secret-ref field that points at a secret owned by a different company shows "Missing secret (22095402…)" in red, with "The previously selected secret is no longer available. Pick another or remove the binding." The binding is actually healthy — the current company's picker just cannot list the other company's secrets. Operators react by creating a duplicate secret and re-pointing the field. **Describe the solution you'd like** The editor should know the referenced secret's name, status, and owning company (metadata only, never the value) and present a cross-company ref neutrally, a deleted secret as deleted, and only an unknown id as missing. Related: #10576 (fixes the binding corruption this UI state used to trigger). ## What Changed - New `GET /environments/:id/secret-refs` returns `{ refs: [{ configPath, secretId, name, status, companyId, companyName }] }` for the environment's config-derived secret refs. Values are never returned. The route sits behind `assertCanAccessInstanceEnvironments`, the same gate as environment editing. - New `secretService.describeSecretRefs` loads that metadata across companies; unknown ids are omitted. - `SecretBindingPicker` reads an optional `SecretRefHintsContext` (keyed by secret id). With a hint, a ref the company list cannot show renders as `NAME — Owning Company` with neutral styling and the note "Owned by the … company. The binding keeps working; selecting a secret from this list re-points it here." A hint with `status: "deleted"` reports the secret as deleted. Without hints, behavior is byte-identical to before — agent editors and other picker users are unaffected. - `CompanyEnvironments` fetches descriptors for the environment being edited and provides them through the context. ## Verification - `cd server && pnpm vitest run src/__tests__/environment-routes.test.ts src/__tests__/secrets-service.test.ts` — new endpoint happy path, agent 403 (descriptors never computed), and embedded-Postgres coverage proving cross-company names resolve and unknown ids drop out. - `cd ui && pnpm vitest run src/components/SecretBindingPicker.test.tsx src/components/JsonSchemaForm.test.tsx src/pages/CompanyEnvironments.test.tsx` — hinted cross-company rendering, hinted deleted secret, and unchanged no-hint fallback. - `pnpm run typecheck` in `server` and `ui`. - Manual: edit an environment whose secret-ref field references another company's secret; the field names the secret and its owning company instead of "Missing secret". ## Risks - The endpoint exposes secret names and company names across companies to instance-level environment editors. Those actors already manage instance-shared environments (and instance admins are implicit members of every company), so this reveals no secret material and no new reach; the service method documents that callers must sit behind an instance-level gate. - UI change is additive and context-gated; pickers without a provider render exactly as before. ## Model Used Claude Fable 5 (`claude-fable-5`, Anthropic) via Claude Code — extended thinking, agentic tool use (file edits, vitest/tsc runs). No other models involved. ## 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 |
||
|
|
54e2031e87 |
fix(ui): accessibility and cleanup for IssueWorkspaceCard copy button (#1832)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The board UI shows the workspace attached to an issue in `ui/src/components/IssueWorkspaceCard.tsx` > - That card renders values such as the branch name and the workspace path through a small `CopyableInline` component, each with an icon-only copy button > - The button has a `title` attribute only. Screen readers do not announce `title` reliably. A screen reader user hears no useful name for the button, because the button contains an icon and no text > - The button also starts a 1.5 second `setTimeout` to reset its "copied" state. Nothing clears that timer. If the card unmounts first, the callback sets state on an unmounted component > - This pull request adds a dynamic `aria-label` to the button and clears the timer in a `useEffect` cleanup > - The benefit is a copy control that assistive technology can announce, and no stray timer after the card unmounts ## Linked Issues or Issue Description No existing GitHub issue covers this. The problem is described below with the fields from [`bug_report.yml`](.github/ISSUE_TEMPLATE/bug_report.yml). **What happened?** Open an issue that has a workspace attached. Tab to the copy button next to the branch or the workspace path in the workspace card. The screen reader announces an unlabeled button, because the button holds only a lucide `Copy` icon and a `title` attribute. Separately, copy a value and navigate away within 1.5 seconds. The pending `setTimeout` then calls `setCopied(false)` on an unmounted component. **Expected behavior** The copy button has an accessible name that says what it copies, and the name changes to confirm the copy. The reset timer is cleared when the component unmounts. **Steps to reproduce** 1. Run the app locally with `pnpm dev`. 2. Open an issue that has a workspace attached, so `IssueWorkspaceCard` renders. 3. Turn on a screen reader (VoiceOver, NVDA). 4. Tab to the copy button next to the workspace path or the branch name. The button has no useful accessible name. 5. Click the copy button, then navigate away from the issue in under 1.5 seconds. The reset timer is still pending. **Paperclip version or commit** Reproducible on `master` at this pull request's base commit. **Deployment mode** Local dev (pnpm dev). Related pull request, not a duplicate: #3531 makes copy-to-clipboard buttons work in non-secure contexts. That pull request changes the clipboard write path. This one changes the button label and the timer cleanup, so the two do not overlap. ## What Changed - Added an `aria-label` to the `CopyableInline` copy button in `ui/src/components/IssueWorkspaceCard.tsx`. The label reads `Copy <label>` (for example "Copy branch"), falls back to `Copy value` when the component gets no `label` prop, and changes to `Copied to clipboard` after a copy. - Added a `useEffect` cleanup that calls `clearTimeout(timerRef.current)` on unmount, so the 1.5 second reset timer cannot fire after the component unmounts. ## Verification - CI is green on this pull request. - Static check: `pnpm -r typecheck`. - Test suite: `pnpm test`. - Manual, screen reader: open an issue with a workspace, tab to the copy button next to the path or the branch, and confirm the announcement is "Copy path" or "Copy branch". Activate the button and confirm the announcement changes to "Copied to clipboard". - Manual, timer: click the copy button and navigate away from the issue immediately. Confirm the console shows no unmounted-component state update. ## Risks Low risk. The change adds one ARIA attribute and one unmount cleanup in a single presentational component. No behavior changes for mouse users, no API or schema change. `clearTimeout(undefined)` is a no-op, so the cleanup is safe when the user never copied. ## Model Used - Anthropic Claude Opus, model ID `claude-opus-4-6`, 200K context window, extended thinking enabled, with tool use for file edits. - Recorded by a maintainer while bringing this description up to the current template. The original description predates the Model Used requirement, so the author did not state a model. Author: please correct this line if the model was different. ## 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 - [ ] 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 - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Notes on the checklist: no test or documentation change applies to a two-line ARIA and cleanup fix in one component. The Greptile box stays unchecked until the current review round closes. |
||
|
|
2137f85e1d |
fix(ui): correct Last checked timestamp in workspace close dialog (#2179)
## Problem
In the ExecutionWorkspaceCloseDialog, the "Last checked" timestamp was
using \`new Date()\` which show the current render time, not when the
readiness check API call actually completed.
\`\`\`tsx
Last checked {formatDateTime(new Date())} // always NOW
\`\`\`
This mean every time React re-render the component (which happen
frequently), the timestamp update to the current moment. User see "Last
checked 2:45:30 PM" and think the check just ran, but actually it might
have ran 30 seconds ago. The timestamp is lying.
## What I changed
Changed from \`new Date()\` to \`new
Date(readinessQuery.dataUpdatedAt)\` which is the actual timestamp from
React Query tracking when the API response was last received.
\`\`\`tsx
Last checked {formatDateTime(new Date(readinessQuery.dataUpdatedAt))} //
actual check time
\`\`\`
Now the timestamp accurately show when the close readiness check was
performed. It stay stable between re-renders until the query actually
refetch.
## How to test
1. Open an execution workspace > click Close button to open the dialog
2. The "Last checked" timestamp should show when the API call completed
3. Wait a few seconds - timestamp should NOT update (it's the query
time, not render time)
4. Click "Recheck" or trigger refetch - timestamp should update to new
fetch time
1 file, 1 line changed.
|
||
|
|
bec04da2c2 |
fix(ui): make task header status and priority controls interactive (#10526)
<!-- Write all pull request text in Simplified Technical English (ASD-STE100): short sentences, one instruction per sentence, simple approved vocabulary, and the active voice. --> ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Operators use the task page header to read and change task state > - The status and priority icons already had picker logic, but the compact triggers were not semantic controls > - This made pointer and keyboard interaction unreliable in the task header > - This pull request makes both compact icon triggers real buttons and keeps the existing picker behavior > - The benefit is that operators can change status and priority directly from the header with pointer or keyboard input ## Linked Issues or Issue Description ### Subsystem affected `ui/` — React + Vite board UI. ### Problem or motivation The compact status and priority icons can receive change handlers, but their popover triggers are plain icon elements. They do not provide a reliable click target, keyboard focus, or control label. Operators need to change both values directly from the task header. ### Proposed solution Use semantic button triggers in the shared status and priority components. Keep the existing API update wiring and picker options. Keep task-row navigation links separate from editable row controls. An operator can select either icon, open its picker, and choose a new task status or priority. ### Alternatives considered A task-page-only wrapper would duplicate control behavior. Moving the controls would also change the page layout. The shared components already own the picker behavior, so a shared trigger fix is smaller and more consistent. ### Roadmap alignment This is a focused board UI usability and accessibility fix. It does not duplicate a planned roadmap feature. ### Additional context The task page already passes change handlers to these shared components. This change makes that existing path interactive and accessible. ## What Changed - Added semantic button triggers for compact and labeled status controls. - Added semantic button triggers for compact and labeled priority controls. - Added accessible current-state labels and keyboard focus styles. - Separated issue-row navigation links from row controls to avoid nested interactive elements. - Added real popover interaction coverage and row semantics regressions. - Added task-page regression tests for update requests. ## Verification - Focused task-header and row suites passed with 131 tests. - The final row, inbox, and picker regression suites passed with 83 tests. - `pnpm --filter @paperclipai/ui exec tsc -b --force` passed. - `pnpm run typecheck:build-gaps` reproduced the CI typecheck before the fix. The forced UI build passed after the fix. - `pnpm check:token-gates` passed. - `pnpm -r typecheck` passed. - `pnpm build` passed. - `pnpm test:run` completed the server and UI partitions. One unrelated CLI AWS doctor assertion saw injected static AWS credentials and returned `warn` instead of `pass`. The exact test passed after those two environment variables were removed. - `git diff --check origin/master...HEAD` passed. - All latest-head GitHub checks passed, including both e2e shards. - Greptile passed at the required threshold with zero open review threads. ## Risks - The shared issue-row DOM now uses a full-area navigation link beside native action buttons. - Existing visual layout, pointer navigation, keyboard navigation, and action behavior remain covered by row, inbox, and list tests. - Read-only status and priority icon uses are unchanged. > 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 the `gpt-5` model. The runtime did not expose its context window size. The agent used reasoning, repository tools, code execution, and GitHub CLI integration. ## 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 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> |
||
|
|
b4a7a12985 |
feat: make recovery updates quieter (#10542)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The recovery subsystem restores work after an agent run stops or loses state > - Recovery notices currently use the same visual weight as normal work comments > - Recovery agents can also post long narratives that obscure the useful hand-off > - The server must identify recovery output because agents cannot set presentation controls > - This pull request adds compact recovery notices, structured action references, and brief recovery prompts > - The benefit is a quieter issue thread that still keeps recovery state inspectable ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting: `server/`, `packages/shared`, and `packages/adapter-utils`. **Problem or motivation** Recovery notices and recovery-run comments can dominate an issue thread. Operators must scan routine recovery narration before they find the work hand-off. **Proposed solution** Give routine recovery output a compact system-notice presentation. Derive the presentation on the server so agents cannot hide arbitrary comments. Keep the successful missing-state summary fully visible because that comment is the recovery deliverable. **Alternatives considered** The UI could detect recovery text. That approach is fragile and does not provide structured action references. Agents could also set presentation directly, but that would weaken the current board-only security boundary. **Roadmap alignment** This change refines the completed “Self-healing runs & automatic recovery” and “Enforced Outcomes” roadmap areas. It does not add a competing roadmap capability. **Additional context** The scope covers shared comment validation, server recovery notices, agent-comment derivation, and recovery prompt text. No database migration is needed because presentation data already uses JSON. ## What Changed - Add the `compact` issue-comment presentation density to shared constants, types, and validation. - Give recovery escalation, waiting, and in-place notices compact titles and structured recovery-action metadata. - Use recovery-action metadata for notice deduplication, with the legacy text marker as a compatibility fallback. - Derive compact presentation for comments from recovery-scoped runs while preserving the board-only presentation boundary. - Keep successful missing-state recovery summaries fully visible. - Ask recovery participants to record outcomes in `resolutionNote` and keep source-issue comments brief. - Add shared, route, service, and prompt tests for the new behavior and exceptions. ## Verification - `pnpm -r typecheck` - Focused Vitest coverage: 320 tests passed across shared validators, adapter prompts, issue comments, recovery actions, and heartbeat recovery. - Full server phase: 292 files passed, 3,094 tests passed, and 2 tests skipped. - Full UI phase: 386 files passed and 3,182 tests passed. - `pnpm build` - Known master baseline: `cli/src/__tests__/secrets.test.ts` expects `pass`, but the current implementation returns `warn` when strict secret mode is disabled for Postgres. This branch does not change CLI secrets code. ## Risks - Low migration risk. The presentation column is JSON and needs no database migration. - Recovery-run detection depends on the persisted run context snapshot. - Structured metadata becomes the primary deduplication key. The existing body marker remains as a fallback for older 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 with `gpt-5.6-sol`. The runtime did not expose the context-window size. The model used agentic reasoning, repository tools, 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> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
6a3cbe1c58 |
fix(ui): load the full selected timeline window (#9576)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The timeline page visualizes company activity across a selected date window > - The UI requested only the first paginated issue batch even when the selected zoom covered seven or thirty days > - A busy company could therefore render an incomplete timeline while the controls implied the full window was loaded > - The timeline query needs to exhaust the API pagination for the selected date range and combine each page without duplicating shared timeline records > - This pull request adds a paginated window loader, merges the returned timeline data, and covers the multi-page behavior with a regression test > - The benefit is that the visible timeline matches the selected zoom window instead of silently omitting later issues ## Linked Issues or Issue Description ### Pre-submission checklist - [x] I searched existing open and closed issues and pull requests; no matching report or implementation was found. - [x] I reproduced the behavior against the pre-change `master` implementation. - [x] I confirmed the error originates in Paperclip's core timeline UI, not an adapter, provider, or local configuration. ### What happened? Selecting the default seven-day timeline range loaded only the first API page (up to 500 issues). Companies with more activity therefore displayed incomplete data even though the controls showed the full selected window. ### Expected behavior The timeline should load all issue pages that fall within the selected date window. ### Steps to reproduce 1. Open the company timeline for a date range containing more than 500 issues. 2. Keep the default seven-day range or select another multi-day preset. 3. Observe that only the first page of issue-backed timeline data is shown. ### Paperclip version or commit Pre-change `master`. ### Deployment mode Local dev source build. The behavior is not adapter-specific and is independent of database mode and access context. ### Privacy checklist - [x] No logs, configuration, personally identifiable information, or user data are included. ## What Changed - Added pagination parameters to the timeline API client contract. - Added a timeline window loader that requests every issue page and deduplicates actors, spans, events, and edges while preserving pagination metadata. - Switched the timeline query to use the complete-window loader. - Added a regression test proving a 501-issue window loads both API pages and combines their records. - Preserved delegation events and edges when parent and child issues fall on different API pages, with a server regression test. ## Verification - `pnpm exec vitest run server/src/__tests__/work-timeline-service.test.ts ui/src/pages/Timeline.test.tsx` — 16 tests passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm check:token-gates` — all gates clean. - `git diff --check origin/master...HEAD` — passed. - Remote CI: build, typecheck, both e2e shards, canary, policy, security, every general/serialized test shard, and the aggregate `verify` gate passed on head `24784b28e9`. ## Risks - Low risk: the change is isolated to timeline data loading and has no schema or API endpoint changes. - Large date windows now make sequential requests for all issue pages, increasing request count for very active companies; the 500-item page size bounds each response. - Merged records rely on stable identifiers or composite event/edge keys; the regression test covers cross-page combination and deduplication behavior. > 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 with reasoning, repository tool use, shell execution, and test execution. The runtime does not expose the exact 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> |
||
|
|
075951f6bd |
Fix import completion UX: inbox flood, false-failure message, stale company list (#10538)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Company Import/Export (#10507, hardened in #10523 and #10531) now imports a large company end to end via an async job > - A real 1,418-issue import succeeded, but three rough edges showed up in that success > - Imported issues flooded the inbox, a completed import surfaced a false "failed" message after its in-memory result expired, and the new company didn't appear in the switcher until a manual refresh > - This pull request keeps imported issues out of the inbox, treats an expired-but-completed import as success, and refreshes the company list on completion > - The benefit is that a successful import looks and feels successful, and doesn't bury the user's inbox in historical tasks ## Linked Issues or Issue Description - Refs #10507 / #10523 / #10531 (Import/Export and its hardening). No open issue; three post-import bugs described above. ## What Changed - **Imported issues no longer flood the inbox.** The inbox "mine" tab is a query: an issue is "touched" if the user authored a comment on it, and import re-attributes bundled user comments to the importing user — so every imported issue appeared. Import now seeds a per-user `issue_inbox_archives` row for each imported issue (via a batched `issues.archiveImportedInbox`), the exact table the inbox visibility query excludes. Gated on an actor user id, so agent/system imports and normal issue creation are untouched; genuine new activity still resurfaces the issue. - **A completed import no longer shows a false failure.** The in-memory job's terminal retention was 5 minutes, so a poll after that 404'd and the UI showed "failed." Retention is extended to 60 minutes — the real mitigation for a user who steps away during a long import. `watchImportJob` additionally treats a *server-confirmed* success whose full result is no longer retained (a `succeeded` status carrying only the compact summary — a cloud tenant job, or a board job whose full in-memory result aged out) as a soft success ("import completed — open the company"), navigating by the summary's company id. A 404 while the job is still being watched is *not* treated as success: a running job is never dropped by the retention sweep, so its disappearance means a restart mid-import that may not have finished, and it surfaces the honest "may have restarted while the import ran" error. A first-poll 404 (the id never existed) is likewise a real error. - **The imported company appears without a refresh.** `onSuccess` now invalidates the companies/switcher query unconditionally (covering both the full-result and expired-but-completed paths) and navigates by the job's company id. ## Verification - shared/server/ui typechecks clean; 15 UI tests in the touched spec green, plus the embedded-Postgres import batching and portability-routes suites. - New tests: embedded-Postgres test that imported touched issues are archived for the actor and excluded from the inbox query while a normally-created issue still appears; job resolvable at the old window+1 and only 404s past 60 min; UI soft success on a server-confirmed `succeeded` job without a retained full result (no error, list invalidated, navigates by company id), a running-then-gone job → honest error (restart mid-import), and a first-poll 404 → error. ## Risks - Low and import-scoped: the inbox archive only affects imported issues for the importing user; normal issue creation and non-user (agent/system) imports are unchanged. Retention extension is a constant; the async job store remains in-memory by design. A restart mid-import still 404s and is surfaced honestly as a possible failure (never masked as success); only a server-confirmed success whose full result has expired is reported as a soft success. ## Model Used - Implementation: Claude Fable 5 (`claude-fable-5`, Anthropic). Review hardening (the confirmed-success narrowing): Claude Opus 4.8 (`claude-opus-4-8`, Anthropic). Both via the Claude Code CLI with extended thinking + tool use; root-caused against the live import. ## 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 - [x] My branch name describes the change and contains no internal ticket id - [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 |
||
|
|
5ec7ce76e5 |
Upload company import packages as compressed zip uploads (fix large-company imports through Cloud) (#10531)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Company Import (#10507, hardened in #10523) lets a user upload a company package on the Import page > - The page expanded the user's `.zip` into a files map and POSTed it as ONE inline JSON body — ~40MB for a real company because attachment blobs get base64-inflated > - On Paperclip Cloud that body travels browser → harness proxy → tenant, where it truncated in transit → body-parser 400 → the browser saw "Failed to fetch", and nothing imported > - Two compounding causes: the giant inline body itself, and the board async opt-in riding an `x-paperclip-cloud-*` header that the Cloud harness strips as anti-spoofing (so async never engaged and the import held one fragile synchronous connection) > - This pull request uploads the raw compressed `.zip` as a multipart request (about a third the size, already compressed) parsed server-side into the same bundle the importer consumes, and moves the async opt-in to a proxy-safe `?async=1` > - The benefit is that a large-company import actually completes through Cloud: a small compressed upload, a real async job that survives dropped connections ## Linked Issues or Issue Description - Refs #10507 / #10523 (Import/Export and its hardening). No open issue; problem described above (large-company browser import through a proxy: inline JSON body truncates → 400 → "Failed to fetch"; async opt-in header stripped by the front door → async never engages). ## What Changed - **Multipart zip transport.** The Import page uploads the raw `File` as `multipart/form-data` (field `package`, import options in a JSON `meta` field); the server unzips it into `{ rootPath, files }` and runs the exact existing preview/import logic. The `application/json` inline path is byte-identical for CLI/programmatic callers. Bare `application/zip` (meta via `?meta=`) is also accepted for programmatic use. - **Shared node zip reader.** `packages/shared/src/portability-zip.ts` (node-only subpath, not re-exported to the browser bundle — same pattern as `portability-hash.ts`); the CLI's `zip.ts` becomes a thin re-export. Identical codec (STORE + DEFLATE via `inflateRawSync`, rejects data descriptors/zip64). - **Proxy-safe async signal.** `wantsAsyncImport` = `?async=1` (board browsers, survives the harness) OR the existing `x-paperclip-cloud-async-import` header (cloud tenants, set server-side). The UI async client now uses `?async=1`. Backward compatible. - **Size + preflight.** New `PORTABLE_ZIP_UPLOAD_LIMIT_BYTES = 128MB`; the inline 56MB preflight no longer gates the zip path (it shows the compressed size instead). Async submit/poll/resume, the duplicate-guard fingerprint (now over the resolved bundle), pause-on-import, progress/error panels, and activation all apply to the multipart path. - OpenAPI documents json + multipart + zip bodies and the `async` query param. ## Verification - Full typecheck chain (shared, server, ui, cli) clean. - 152 tests across 8 files: new `portability-zip.test.ts` (STORE/DEFLATE/base64-blob byte-exact round-trip, truncation throws, data-descriptor rejection); `company-portability-routes.test.ts` +7 (multipart import+preview equals the inline bundle; async multipart 202→poll→success; board async via `?async=1` with no cloud header; cloud-tenant async via header; sync fallback with neither; truncated-zip 400, nothing imported); `CompanyImport.test.tsx` asserts the local zip sends the raw File and the inline preflight no longer blocks; `openapi-routes.test.ts` green. - NOT yet measured: the end-to-end browser upload through the live Cloud harness — verified on staging after deploy before closing out. ## Risks - Import semantics unchanged — only transport changed; the JSON inline path is byte-identical, the cloud-tenant header async path untouched. Multipart parsing is server-side (memory-bound: a ~13MB zip → ~30MB files map, fine on the server). - The bare `application/zip` path is programmatic-only and covered by content-type dispatch but not a dedicated route test (the multipart path is). ## Model Used - Claude Fable 5 (`claude-fable-5`, Anthropic), Claude Code CLI, extended thinking + tool use; root-caused against live logs/DB and the harness proxy source. ## 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 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 |
||
|
|
276ae3a75d |
Harden company import: durable UI, async jobs, integrity guard, batched inserts (#10523)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Company Import/Export (#10507) moves whole companies between instances as portability bundles > - Real-world use on a large company (1,418 issues, ~10.6k comments) surfaced a cluster of related failures: the import took hours and the browser connection died while the server kept running, a retry silently produced a second partial import, the progress/error UI gave no durable signal, and a cloud-tenant user couldn't even open the companies afterward > - Root cause of the slowness: importBundle inserted every issue, comment, and document as a separate round-trip to a network Postgres — an N+1-over-network pattern > - This pull request hardens the whole import path: durable progress/error UI, an async server-side job so imports survive dropped connections (with a duplicate-submit guard), a fail-closed guard against incomplete payloads, and batched inserts that cut a large import from hours to minutes > - The benefit is that migrating a real, large company actually completes, is legible while it runs, and can't half-import twice ## Linked Issues or Issue Description - Refs #10507 (the Import/Export feature this hardens). Supersedes #10513 (the progress/error-UI piece, folded in here). No open issue; problem described above (large-company import: slow, connection-fragile, silently duplicable, opaque UI). ## What Changed - **Batched inserts (perf):** importBundle pre-generates entity ids in JS and inserts in chunked multi-row statements, so children no longer wait on parents' generated ids. A 1,418-issue import drops from ~15,600 insert statements to **82** (190×); benchmark below. Import semantics — collision handling, pause-on-import, label/blocker/monitor/attachment/embedded-asset handling, blob sha verification — are unchanged (full portability suite green). - **Async import jobs for board sessions:** the existing cloud-tenant async job path opens to board sessions with per-actor job keys; the import page submits, polls, and resumes watching after a reload or dropped connection instead of holding one fragile request. A non-terminal job blocks a duplicate submit (409 returns the running job), preventing the double-import. - **Fail-closed completeness guard:** an optional `expectedFileCount` on inline imports; the server rejects (422 `import_payload_incomplete`) a body carrying fewer files than declared, so a re-framed/short payload fails loudly instead of half-importing. - **Durable progress/error UI (was #10513):** persistent progress panels with size-aware copy, persistent error panels with retry guidance, and inline explanation when the preview button is disabled; request-lifecycle guards so stale previews/imports can't publish or detach. ## Verification - `pnpm -r` typechecks (shared, server, ui) clean. - `company-portability.test.ts` (76) + `company-portability-routes.test.ts` (30) green — the import correctness net — plus new `CompanyImport.test.tsx` async/resume/409 coverage and a new batching regression test (a 50-issue import issues <50 issue-insert statements; rows land unchanged). - **Batching benchmark (embedded Postgres):** at 1,418 issues × 7 comments × 1 doc — 82 insert statements vs ~15,598 one-per-row (190×), ~1s wall-clock; a row-verifying run at that scale imports all 1,418 issues / 9,926 comments / 1,418 documents with unique identifiers and no warnings (no rows dropped by chunking). Over a network DB the round-trip reduction is the hours→minutes lever. - What is NOT directly measured here: wall-clock against a real network Postgres (that happens on a staging deploy); the local timing is network-free. ## Risks - Batching is the load-bearing change: it rewrites the import write path. Mitigated by the unchanged 106-test correctness suite, a new scale/row-integrity test, and per-writer transactions (a failure rolls back its table group; not a single outer transaction across writers — noted, correctness preserved). - Async jobs are in-memory (lost on server restart → pollers 404 and can resubmit); matches the pre-existing cloud-tenant job semantics. - `expectedFileCount` is optional (older callers unaffected); over-count is allowed, only under-count fails closed. ## Model Used - Claude Fable 5 (`claude-fable-5`, Anthropic), Claude Code CLI, extended thinking + tool use; implementation across Fable 5 subagents with live diagnosis against a running instance. ## 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 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 |
||
|
|
916c13501f |
Replace host-to-host Cloud Sync with full-fidelity company Import/Export (#10507)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - A company accumulates real state — issues, labels, blockers, documents, work products, monitors, attachments, agents, routines — and people need to move that state between instances: self-hosted to cloud, cloud back to self-hosted, or plain backups > - The experimental, flag-gated Cloud Sync transport (#6548) tried to solve this host-to-host: the source pushed into a receiver over HTTPS with a cross-instance consent/token handshake, which required the destination to be publicly reachable and broke for common self-hosted topologies (plain-HTTP LAN/VPN origins); the receiver half never landed upstream at all > - Meanwhile the portability bundle and the existing export/import pages already move companies offline with none of those networking constraints — but silently dropped labels, blockers, issue documents, work products, monitors, and every attachment > - This pull request removes the host-to-host transport and makes Import/Export the single data-movement path: the pages become first-class company-settings destinations, exports declare exactly what they do not carry, and bundle schemaVersion 6 now carries all of the above, with attachments as content-addressed sha256 blobs verified before a single row is written > - The benefit is a migration and backup flow that works between any two instances with no reachability requirements, no cross-instance auth, and no silent data loss ## Linked Issues or Issue Description - Refs #6548 — the original Cloud Sync sender this PR supersedes and removes. - Related, not duplicates: #1697 (goals in the portability manifest — orthogonal field addition), #954 (an earlier import/export + skill-visibility proposal predating the current portability bundle). - No open issue describes this directly, so in brief (feature-request shape): **Problem** — moving a company between instances silently lost labels (imports with label references actually hard-failed), blocker relations, issue documents, work products, monitor state, and all attachments, and the alternative Cloud Sync transport required the destination to be publicly reachable over HTTPS plus a consent handshake, which failed for typical self-hosted setups. **Desired behavior** — one Import/Export flow in company settings that produces a portable bundle carrying all of that data, tells the operator up front what it cannot carry, imports with automations paused, and offers real one-click activation afterwards. ## What Changed - New export fidelity report (`GET /api/companies/:companyId/export/fidelity`) + an "Export fidelity" panel on the Export page listing anything a bundle will not include (now only: approvals, cost history, activity history) - Imports accept `pauseAutomations`; imported agents and routines land paused, the import result reports created routines, and the Import page ends in an activation panel that actually resumes selected agents/activates routines - Export and Import pages promoted into the company-settings nav; the Cloud Upstream wizard, ux-lab page, and API client removed; the old settings route redirects to Export - Host-to-host transport removed: upstream-sync/receiver-client routes and services, CLI `cloud connect`/`cloud push` + keypair store, the shared upstream transfer contract, and the `enableCloudSync` flag; migration `0196` drops the two experimental `cloud_upstream_*` sender tables - Bundle schemaVersion 6: labels (definitions + per-task names, remapped by name on import), blocker relations (`blockedBy` slugs, cycle-tolerant), issue documents (`tasks/<slug>/documents/<key>.md`), work products (system refs nulled), monitors (notes/scheduledBy restored, imported un-armed) - Attachments travel as content-addressed `blobs/<sha256>` entries (deduped; comment-scoped attachments re-link via comment index); every blob is hash-verified **before any write**, so a corrupted bundle cannot leave a partially imported company; both zip codecs now round-trip extensionless/binary entries byte-exactly; the Import page preflights the inline body limit and offers continue-without-attachments - v5 (and older) bundles still import, with an informational warning; bundles newer than v6 are rejected cleanly - Docs: board-operator import/export guide, CLI README, README/ROADMAP updated ## Verification - `pnpm -r` typechecks (shared, db incl. migration numbering/safety checks, server, ui, cli) and `pnpm check:token-gates` — clean - Vitest: full server + shared sweep 4,888 passed / 1 skipped, with the only 3 failures being pre-existing on `master` (2× heartbeat-workspace-branch-containment, 1× workspace-runtime auto-port; reproduced identically with this change stashed); ui + cli suites green; the embedded-Postgres export-fidelity suite applies the full migration chain including the new `0196` against a fresh database - Live end-to-end on a scratch instance: seeded a company with labels, a blocker pair, an issue document, a work product, a monitor, an agent, a routine, and two binary attachments (one comment-scoped) → export → import into a fresh company → labels remapped to new ids, blocker edge and document restored, monitor un-armed with notes intact, attachments byte-identical (sha256-compared through the API), agents/routines paused → activation panel resumed them; a v5-shaped bundle imported with only the info warning; flipping one byte in a blob made the import 422 with **zero** rows created - Reviewer repro: create a company with a labeled issue + attachment → Settings → Export → download → Settings → Import on another company/instance → watch the preview, apply with "start paused", then activate ## Risks - Migration `0196` drops `cloud_upstream_connections`/`cloud_upstream_runs` — experimental tables behind a default-off flag; their connection/run history is intentionally discarded - Breaking removals are all of experimental, flag-gated surface: `/api/upstream-sync/*` + `/api/cloud-upstreams/*` routes, `paperclipai cloud connect|push`, and the `enableCloudSync` flag (stale keys in stored instance settings parse harmlessly) - Import remains non-atomic on mid-apply errors generally (pre-existing behavior); the new blob verification specifically moved ahead of all writes so tampered bundles cannot create partial state - GitHub-sourced imports do not fetch `blobs/*` and skip attachments with a warning ## Model Used - Claude Fable 5 (`claude-fable-5`, Anthropic), via Claude Code CLI with extended thinking, tool use, and subagent orchestration; implementation and review split across Fable 5 subagents, with live end-to-end verification against a running instance ## 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 |
||
|
|
a6436126ce |
feat(ui): add recency separators to task lists (#10454)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI agents and their work > - Project pages give operators a dense task list for understanding what has changed recently > - A purely chronological list makes the transition from fresh work to aging work difficult to scan > - The existing activity feed already uses a quiet labeled divider to communicate a recency boundary > - This pull request applies that familiar pattern to task lists at the one-day and one-week boundaries > - The benefit is faster age-based scanning without adding filters, badges, or repeated metadata to every row ## Linked Issues or Issue Description ### Subsystem affected `ui/` — React + Vite board UI. ### Problem or motivation Operators scanning a project task list cannot quickly see where recently created or updated work gives way to tasks that are more than a day or a week old. ### Proposed solution Insert subtle, accessible “Older than a day” and “Older than a week” separators when a task list is sorted newest-first by creation or update time. ### Alternatives considered Per-row age badges would repeat state and add noise; persistent age-based groups would interfere with the list's existing grouping controls. Lightweight boundary markers preserve the current ordering and interaction model. ### Roadmap alignment This is a tightly scoped board-UI polish change and does not duplicate a roadmap milestone. ### Additional context The visual treatment follows the existing activity-feed recency separator pattern. A public GitHub search found no duplicate or related open issue or pull request. ## What Changed - Added rolling one-day and one-week recency buckets for created/updated timestamps. - Rendered token-compliant, accessible separators only for newest-first date sorts and only when visible rows cross a boundary. - Traversed expanded nested rows in their exact visible order and emitted every crossed boundary when adjacent rows skip an age bucket. - Added component and helper coverage for sequential boundaries, skipped buckets, expanded nested rows, and the no-separator same-bucket case. ## Verification - `pnpm exec vitest run ui/src/components/IssuesList.test.tsx` — 42 tests passed. - `pnpm check:token-gates` — all token gates clean. - `pnpm --filter @paperclipai/ui typecheck` — passed. - `pnpm --filter @paperclipai/ui build` — passed (with existing build warnings only). ## Risks - Low risk: the change is presentation-only and limited to list mode when sorting `created` or `updated` descending. - Boundaries use rolling 24-hour and 7-day windows rather than calendar-day boundaries, matching the age-based labels. > 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 family (the runtime did not expose a more specific model build or context-window size), with reasoning, repository tool use, code execution, and GitHub CLI 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 - [ ] 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> |
||
|
|
24aa2f516d |
feat(ui): add animated paperclip page loaders (#10456)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI agents for work > - Operators regularly pass through full-page loading states while authentication and company context resolve > - Those states currently render as small bare text, which is easy to miss and does not reinforce Paperclip's visual identity > - A shared loading component gives these transitions one accessible, consistent representation > - This pull request introduces an animated paperclip loader and uses it at the existing full-page loading boundaries > - The benefit is a clearer, calmer loading experience with reduced-motion and screen-reader support ## Linked Issues or Issue Description ### Subsystem affected `ui/` — React + Vite board UI ### Problem or motivation Full-page authentication, access-gate, and company-context waits use small bare `Loading…` text that is visually weak and inconsistent. ### Proposed solution Use one large centered paperclip loader at those boundaries, drawing the SVG with `currentColor` so it follows the active theme. ### Alternatives considered Keeping text-only states or adding a generic spinner would preserve less of Paperclip's product identity and would continue duplicating loading markup. ### Roadmap alignment This is tightly scoped UI polish and does not duplicate a planned roadmap capability. ### Additional context Internal coordination task PAP-15760 requested this focused change. ## What Changed - Added `AnimatedPaperclipIcon`, a theme-aware SVG whose stroke draws in a loop. - Added `PaperclipLoading`, a large full-viewport centered loader with `role="status"` and an `sr-only` `Loading…` label. - Added a static fully drawn fallback under `prefers-reduced-motion: reduce`. - Replaced bare loading text in `CloudAccessGate`, the Auth session check, and three company-context redirects. - Used token-safe Tailwind utilities throughout the component. - Added focused coverage for the status semantics and the Auth layout height override. ## Verification - `pnpm check:token-gates` - `pnpm -C ui exec tsc -b` - `pnpm -C ui exec vitest run src/components/AnimatedPaperclipIcon.test.tsx` - `pnpm -C ui exec vitest run src/App.test.tsx src/App.cases-routing.test.tsx` — 8/8 tests passed - Visually checked light and dark loading states; the screenshot below shows both themes.  ## Risks - Low risk: this changes presentation only at existing loading branches. - Motion-sensitive users receive a static, fully drawn paperclip through the reduced-motion media query. - Screen readers retain a concise loading announcement through the status role and visually hidden label. > 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 (exact service build ID and context-window size are not exposed in this environment), with reasoning, repository inspection, shell tool use, code execution, and image inspection. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used with all deployment details available to this environment - [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 found none - [x] I have described the issue in-PR following the feature-request fields - [x] I included the task-mandated internal parent reference and no private instance URL - [x] I preserved the task-mandated existing branch name without renaming it - [x] I have run scoped tests locally and they pass - [x] I added focused component coverage for the new loading state - [x] No documentation update is required for this presentation-only change - [x] I have considered and documented the 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> |
||
|
|
4c8d92f086 |
fix(ui): leave agent detail after termination (#10451)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The agent detail page lets operators inspect one agent and run lifecycle actions from that context > - Terminated agents are removed from the normal active-agent surface, so the current detail route may no longer be fetchable after termination > - Before this change, terminating an agent from its detail page invalidated agent queries while leaving the browser on the now-stale detail route > - That refetch could surface an "Agent not found" error even though the terminate action itself succeeded > - The shared action button already owns the terminate mutation, so it can notify detail-page callers when termination succeeds > - This pull request redirects the detail page back to the agents list after a successful terminate action > - The benefit is that operators land on a valid route and the Back button does not return them to the stale terminated-agent detail route ## Linked Issues or Issue Description No direct public GitHub issue or PR was found for this detail-page termination flow. ### What happened? After terminating an agent from its detail page, the UI could remain on that agent's detail route and show an "Agent not found" error after query invalidation/refetch. ### Expected behavior Once termination succeeds, the operator should leave the now-stale detail page and land on a valid agents view. ### Steps to reproduce 1. Open a non-built-in agent detail page. 2. Use the overflow actions menu to terminate the agent. 3. Observe the post-termination route/error state. ### Paperclip version or commit Current `master` before this PR. ### Deployment mode Browser UI behavior, independent of a specific deployment mode. Duplicate search: searched public GitHub issues and PRs for `agent not found terminate`, `terminate agent detail`, and `Agent not found`; no direct duplicate or viable in-flight PR was found. ## What Changed - Added an optional `onTerminateSuccess` callback to `AgentActionButtons`, fired only after the shared terminate mutation succeeds. - Wired `AgentDetail` to replace-navigate to `/agents/all` after successful termination. - Extended `AgentActionButtons` coverage for the terminate success path, including API args, callback payload, and query invalidations. ## Verification - `corepack pnpm exec vitest run ui/src/components/AgentActionButtons.test.tsx` - `corepack pnpm check:token-gates` - `git diff --check origin/master..HEAD` - Local diff scan for obvious tokens, credential filenames, and email addresses found no matches. ## Risks Low risk. The new callback is optional, only fires for successful terminate actions, and preserves existing behavior for other `AgentActionButtons` callers. ## Model Used OpenAI Codex, GPT-5-based coding agent (`gpt-5`), tool use enabled for repository inspection, editing, local verification, and GitHub CLI operations. Context window details 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> |
||
|
|
1452d5f413 |
perf(ui): warm issue detail navigation (#10416)
## Thinking Path > - Paperclip is the open source control plane people use to coordinate AI-agent companies > - The board UI opens issue details from lists, quicklooks, and the inbox > - Those navigation paths already have enough issue data to paint the header immediately, but the comment feed still waits for its first request > - That delay makes repeat navigation feel cold and can briefly show an empty thread before comments arrive > - This pull request centralizes the comment page shape, prefetches issue detail plus the first comment page, and renders a reserved skeleton while an uncached page is loading > - The benefit is faster, stable warm navigation without coupling this change to the separate aggregate issue-detail API work ## Linked Issues or Issue Description - **Subsystem affected:** `ui/` — React + Vite board UI - **Problem or motivation:** Opening an issue from an already-loaded list still waits for the first comments request and may flash the empty-thread state, making warm navigation feel slower than necessary. - **Proposed solution:** Prefetch the issue-detail snapshot and first comments page from every issue navigation entry point, reuse one page-size constant for prefetch and render queries, and show the existing chat skeleton until the uncached initial page resolves. - **Alternatives considered:** Relying only on detail-query prefetch leaves comments cold; bundling this with the aggregate issue-detail endpoint would make the UI improvement harder to review and land independently. - **Roadmap alignment:** `ROADMAP.md` has no overlapping issue-navigation initiative. This is a focused board responsiveness improvement. - **Related pull requests:** #10409 establishes the issue-detail performance baseline; #10414 reduces server-side issue-detail request overhead. ## What Changed - Added one shared issue-comment page-size constant used by rendering and prefetching. - Added first-page comment prefetching and a combined navigation prefetch helper. - Wired quicklook, issue-list keyboard navigation, and inbox navigation to warm both caches. - Kept the existing chat skeleton visible while the first uncached comment page loads. - Added focused cache behavior tests for comment and combined navigation prefetching. ## Verification - `vitest run ui/src/lib/prefetchIssueComments.test.ts` — 3 tests passed. - `tsc -b ui` — passed. - `pnpm check:token-gates` — passed. ## Risks - Low risk: this adds background prefetch requests on intentional issue navigation/hover paths. React Query stale-time deduplication prevents repeat requests while the cache is fresh. - The change intentionally remains independent of the separate aggregate `getView` work and composes with it through the same query keys. > 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, exact model `gpt-5.6-sol`; context-window size was not exposed; reasoning mode with repository tool use 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 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> |
||
|
|
487e33b8b6 |
fix(codex-local): resolve GPT-5.6 model metadata at source (#9780)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI agents for work > - The `codex_local` adapter runs OpenAI's Codex CLI through direct CLI and ACP execution lanes > - The adapter defaulted to the bare `gpt-5.6` alias while the bundled ACP Codex version lacked GPT-5.6-family metadata > - Default and legacy-configured runs therefore emitted fallback-metadata warnings and could use generic context limits > - This pull request upgrades the bundled Codex ACP dependency, selects the concrete `gpt-5.6-sol` model, and normalizes the legacy alias in both execution lanes > - The benefit is correct model metadata without hiding genuine stderr or transcript warnings ## Linked Issues or Issue Description Related public PRs: Refs #9342, Refs #9352, and Refs #9382. This PR is narrower: it upgrades bundled Codex metadata and normalizes the legacy bare alias in both execution lanes. **Bug report** ### What happened Default `codex_local` runs, and agents still configured with the bare `gpt-5.6` model, print a model-metadata fallback warning and use generic context-window limits. Root cause: the ACP lane bundled a Codex release predating GPT-5.6-family metadata, while Paperclip's default and advertised model used the bare `gpt-5.6` alias for which Codex publishes no metadata. ### Expected behavior A default Codex run resolves to a concrete model slug with published metadata and does not emit a fallback-metadata warning. ### Deployment mode Self-hosted/local `codex_local` adapter. ## What Changed - Upgraded `@agentclientprotocol/codex-acp` from `^1.1.0` to `^1.1.4` - Changed `DEFAULT_CODEX_LOCAL_MODEL` from `gpt-5.6` to `gpt-5.6-sol` - Removed the bare alias from advertised models and listed concrete GPT-5.6 Fast-mode variants - Added `normalizeCodexModel()` and applied it in both CLI and ACP execution lanes - Updated adapter docs, Storybook fixtures, and regression tests - Preserved warning visibility; no stderr, transcript, or log filtering changed ## Verification - `pnpm --filter @paperclipai/adapter-codex-local typecheck` - `pnpm check:token-gates` - `cd packages/adapters/codex-local && pnpm exec vitest run` — 205 tests passed - `cd server && pnpm exec vitest run src/__tests__/adapter-models.test.ts` — 17 tests passed - Confirmed the PR diff excludes `pnpm-lock.yaml` and `.github/workflows/**` as required by repository policy - Confirmed `.github/workflows/pr.yml` regenerates and uploads the PR lockfile artifact before downstream `pnpm install --frozen-lockfile` steps ## Risks Low risk. The behavior change is scoped to `codex_local` model selection. Existing concrete model IDs pass through unchanged; only the legacy bare `gpt-5.6` alias is rewritten. Dependency resolution may select a newer compatible `codex-acp` release within the declared range, so CI remains the final compatibility gate. > 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 - Original implementation: Anthropic Claude Opus 4.8 (`claude-opus-4-8`, 1M context, tool use and code execution) - Conflict resolution and PR preparation: OpenAI GPT-5.5 (`gpt-5.5`, Codex CLI coding agent, high-reasoning tool use and code execution; host-managed context window) ## 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 — branch name is fixed by the assigned execution workspace and cannot be renamed in-place - [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> |
||
|
|
a90f816c89 |
build(deps): bump lexical from 0.46.0 to 0.48.0 (#10299)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The UI depends on `lexical` for rich text editing in user-facing flows > - Dependabot detected a newer `lexical` release with bug fixes and security hardening > - A dependency-only bump is the smallest safe way to pick up those upstream fixes > - This pull request updates `lexical` from 0.46.0 to 0.48.0 > - The benefit is lower maintenance risk and a smaller security/support gap without changing app logic ## Linked Issues or Issue Description - No public issue exists for this maintenance update. - Related public PR: Refs #9885. ## What Changed - Bumped `lexical` from 0.46.0 to 0.48.0. - Refreshed the lockfile entries for the dependency update. ## Verification - GitHub Actions checks on PR #10299 passed. - No local code changes were needed for this dependency-only update. ## Risks - Low risk overall because this is a dependency-only update. - Upstream editor behavior could still shift subtly; CI and the dependency bump itself are the primary safeguard. ## Model Used - OpenAI GPT-5 (Codex), tool-using agent. ## 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 Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
f9034ab3ca |
build(deps-dev): bump @types/node from 22.19.21 to 22.20.1 (#10304)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.19.21 to 22.20.1. <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">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> |
||
|
|
dac7e66724 |
build(deps-dev): bump storybook from 10.4.6 to 10.5.5 (#10303)
Bumps [storybook](https://github.com/storybookjs/storybook/tree/HEAD/code/core) from 10.4.6 to 10.5.5. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/storybookjs/storybook/releases">storybook's releases</a>.</em></p> <blockquote> <h2>v10.5.5</h2> <h2>10.5.5</h2> <ul> <li>CLI: Update AI setup instructions to msw-storybook-addon v3 - <a href="https://redirect.github.com/storybookjs/storybook/pull/35512">#35512</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> <li>Core: Upgrade `ws` to fix security advisories - <a href="https://redirect.github.com/storybookjs/storybook/pull/35584">#35584</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>ReactNative: Telemetry framework detection fix - <a href="https://redirect.github.com/storybookjs/storybook/pull/35560">#35560</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>SyntaxHighlighter: Fix PrismJS dark mode mismatch - <a href="https://redirect.github.com/storybookjs/storybook/pull/35541">#35541</a>, thanks <a href="https://github.com/hxy-asdw"><code>@hxy-asdw</code></a>!</li> <li>TanStack: Preserve explicit route ids on pathful clones - <a href="https://redirect.github.com/storybookjs/storybook/pull/35499">#35499</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> <li>TanStack: Resolve mock redirects through Vite's resolver - <a href="https://redirect.github.com/storybookjs/storybook/pull/35501">#35501</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> <li>TanStack: Respect routeOverrides component overrides in stories - <a href="https://redirect.github.com/storybookjs/storybook/pull/35497">#35497</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> </ul> <h2>v10.5.4</h2> <h2>10.5.4</h2> <ul> <li>ReactNative: Telemetry framework detection fix - <a href="https://redirect.github.com/storybookjs/storybook/pull/35560">#35560</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>SyntaxHighlighter: Fix PrismJS dark mode mismatch - <a href="https://redirect.github.com/storybookjs/storybook/pull/35541">#35541</a>, thanks <a href="https://github.com/hxy-asdw"><code>@hxy-asdw</code></a>!</li> </ul> <h2>v10.5.3</h2> <h2>10.5.3</h2> <ul> <li>Dependencies: Upgrade TypeScript to 6.0.3 - <a href="https://redirect.github.com/storybookjs/storybook/pull/34971">#34971</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> </ul> <h2>v10.5.2</h2> <h2>10.5.2</h2> <ul> <li>Angular-Vite: Drop <code>@angular/platform-browser-dynamic</code> peer dependency - <a href="https://redirect.github.com/storybookjs/storybook/pull/35457">#35457</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> <li>Angular-Vite: Widen TypeScript peer dependency range to support TypeScript 6 - <a href="https://redirect.github.com/storybookjs/storybook/pull/35455">#35455</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> <li>Core: Include chromatic packages in ecosystem identifier - <a href="https://redirect.github.com/storybookjs/storybook/pull/35170">#35170</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> <li>TanStack: Fix createServerFn validator mock - <a href="https://redirect.github.com/storybookjs/storybook/pull/35185">#35185</a>, thanks <a href="https://github.com/sjh9714"><code>@sjh9714</code></a>!</li> <li>TanStack: Support pathless layout routes (id-only) in story routing - <a href="https://redirect.github.com/storybookjs/storybook/pull/35465">#35465</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> <li>Tanstack-react: Add missing Hydrate export - <a href="https://redirect.github.com/storybookjs/storybook/pull/35111">#35111</a>, thanks <a href="https://github.com/arun-357"><code>@arun-357</code></a>!</li> <li>Tanstack-react: Keep JSX-only component references during dead-code elimination - <a href="https://redirect.github.com/storybookjs/storybook/pull/35206">#35206</a>, thanks <a href="https://github.com/yatishgoel"><code>@yatishgoel</code></a>!</li> <li>Vitest: Fix coverage toggle crash on Vite 6 by clearing closed Vitest instance on restart - <a href="https://redirect.github.com/storybookjs/storybook/pull/35461">#35461</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> </ul> <h2>v10.5.1</h2> <h2>10.5.1</h2> <ul> <li>Angular-Vite: Drop <code>@angular/platform-browser-dynamic</code> peer dependency - <a href="https://redirect.github.com/storybookjs/storybook/pull/35457">#35457</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> <li>Angular-Vite: Widen TypeScript peer dependency range to support TypeScript 6 - <a href="https://redirect.github.com/storybookjs/storybook/pull/35455">#35455</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> <li>Core: Include chromatic packages in ecosystem identifier - <a href="https://redirect.github.com/storybookjs/storybook/pull/35170">#35170</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> </ul> <h2>v10.5.0</h2> <h2>10.5.0</h2> <blockquote> <p><em>Foundational changes for new AI workflows</em></p> </blockquote> <p>Storybook 10.5 contains hundreds of fixes and improvements:</p> <ul> <li>⚡️ Angular-vite framework: Modern, fast dev, docs, and test (preview)</li> <li>🌈 Vitest initialGlobals: Test across themes, viewports, locales</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md">storybook's changelog</a>.</em></p> <blockquote> <h2>10.5.5</h2> <ul> <li>CLI: Update AI setup instructions to msw-storybook-addon v3 - <a href="https://redirect.github.com/storybookjs/storybook/pull/35512">#35512</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> <li>Core: Upgrade <code>ws</code> to fix security advisories - <a href="https://redirect.github.com/storybookjs/storybook/pull/35584">#35584</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>ReactNative: Telemetry framework detection fix - <a href="https://redirect.github.com/storybookjs/storybook/pull/35560">#35560</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>SyntaxHighlighter: Fix PrismJS dark mode mismatch - <a href="https://redirect.github.com/storybookjs/storybook/pull/35541">#35541</a>, thanks <a href="https://github.com/hxy-asdw"><code>@hxy-asdw</code></a>!</li> <li>TanStack: Preserve explicit route ids on pathful clones - <a href="https://redirect.github.com/storybookjs/storybook/pull/35499">#35499</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> <li>TanStack: Resolve mock redirects through Vite's resolver - <a href="https://redirect.github.com/storybookjs/storybook/pull/35501">#35501</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> <li>TanStack: Respect routeOverrides component overrides in stories - <a href="https://redirect.github.com/storybookjs/storybook/pull/35497">#35497</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> </ul> <h2>10.5.4</h2> <ul> <li>ReactNative: Telemetry framework detection fix - <a href="https://redirect.github.com/storybookjs/storybook/pull/35560">#35560</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>SyntaxHighlighter: Fix PrismJS dark mode mismatch - <a href="https://redirect.github.com/storybookjs/storybook/pull/35541">#35541</a>, thanks <a href="https://github.com/hxy-asdw"><code>@hxy-asdw</code></a>!</li> </ul> <h2>10.5.3</h2> <ul> <li>Dependencies: Upgrade TypeScript to 6.0.3 - <a href="https://redirect.github.com/storybookjs/storybook/pull/34971">#34971</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> </ul> <h2>10.5.2</h2> <ul> <li>TanStack: Fix createServerFn validator mock - <a href="https://redirect.github.com/storybookjs/storybook/pull/35185">#35185</a>, thanks <a href="https://github.com/sjh9714"><code>@sjh9714</code></a>!</li> <li>TanStack: Support pathless layout routes (id-only) in story routing - <a href="https://redirect.github.com/storybookjs/storybook/pull/35465">#35465</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> <li>Tanstack-react: Add missing Hydrate export - <a href="https://redirect.github.com/storybookjs/storybook/pull/35111">#35111</a>, thanks <a href="https://github.com/arun-357"><code>@arun-357</code></a>!</li> <li>Tanstack-react: Keep JSX-only component references during dead-code elimination - <a href="https://redirect.github.com/storybookjs/storybook/pull/35206">#35206</a>, thanks <a href="https://github.com/yatishgoel"><code>@yatishgoel</code></a>!</li> <li>Vitest: Fix coverage toggle crash on Vite 6 by clearing closed Vitest instance on restart - <a href="https://redirect.github.com/storybookjs/storybook/pull/35461">#35461</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> </ul> <h2>10.5.1</h2> <ul> <li>Angular-Vite: Drop <code>@angular/platform-browser-dynamic</code> peer dependency - <a href="https://redirect.github.com/storybookjs/storybook/pull/35457">#35457</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> <li>Angular-Vite: Widen TypeScript peer dependency range to support TypeScript 6 - <a href="https://redirect.github.com/storybookjs/storybook/pull/35455">#35455</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> <li>Core: Include chromatic packages in ecosystem identifier - <a href="https://redirect.github.com/storybookjs/storybook/pull/35170">#35170</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> </ul> <h2>10.5.0</h2> <blockquote> <p><em>Foundational changes for new AI workflows</em></p> </blockquote> <p>Storybook 10.5 contains hundreds of fixes and improvements:</p> <ul> <li>⚡️ Angular-vite framework: Modern, fast dev, docs, and test (preview)</li> <li>🌈 Vitest initialGlobals: Test across themes, viewports, locales</li> <li>🤖 Agentic review: AI-curated visual changesets and search results (experimental)</li> <li>⚛️ React docgen service: Unified metadata across MCP, Docs, and Controls (experimental)</li> <li>🧑💻 Claude / Codex plugins: One-click ADE integration (experimental)</li> </ul> <!-- raw HTML omitted --> <ul> <li>A11y: Fix MDX heading anchors not keyboard accessible - <a href="https://redirect.github.com/storybookjs/storybook/pull/34368">#34368</a>, thanks <a href="https://github.com/TheSeydiCharyyev"><code>@TheSeydiCharyyev</code></a>!</li> <li>A11y: Handle lang attribute throughout preview - <a href="https://redirect.github.com/storybookjs/storybook/pull/35321">#35321</a>, thanks <a href="https://github.com/Sidnioulz"><code>@Sidnioulz</code></a>!</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/storybookjs/storybook/commit/05a52b7a888c6b85c3f8aa6765ed9a0a69a79e4c"><code>05a52b7</code></a> Bump version from "10.5.4" to "10.5.5" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/201e77a25c58aea0e48a3510f91d5a5d4da85860"><code>201e77a</code></a> Merge pull request <a href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/35512">#35512</a> from storybookjs/yann/ai-setup-msw-v3</li> <li><a href="https://github.com/storybookjs/storybook/commit/cac1e6d595df4a8a814ea2aa5005a5dbed0e18a6"><code>cac1e6d</code></a> Merge pull request <a href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/35584">#35584</a> from storybookjs/norbert/upgrade-ws-8.21</li> <li><a href="https://github.com/storybookjs/storybook/commit/9166a91fc2dac3f3b8e58ef60a81711882ef5219"><code>9166a91</code></a> Merge pull request <a href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/35567">#35567</a> from ia319/bug/35566-npm-12-registry-flags</li> <li><a href="https://github.com/storybookjs/storybook/commit/3327dc44697304275e28ceaa2cd34d9bede4e333"><code>3327dc4</code></a> Bump version from "10.5.3" to "10.5.4" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/3f07eb74aec415d985efdb19eeda2e625bd2d339"><code>3f07eb7</code></a> Merge pull request <a href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/35560">#35560</a> from storybookjs/norbert/fix-rn-telemetry-metadata</li> <li><a href="https://github.com/storybookjs/storybook/commit/22e36662a2c91c51bdc1204b467155ea3c870304"><code>22e3666</code></a> Merge pull request <a href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/35541">#35541</a> from hxy-asdw/fix/prismjs-dark-mode-contrast-35540</li> <li><a href="https://github.com/storybookjs/storybook/commit/9ac273930a49ad33b6a331f1f36dc472f5c36054"><code>9ac2739</code></a> Bump version from "10.5.2" to "10.5.3" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/b4b00f27662caf7328330b5ab47e9b903218f43a"><code>b4b00f2</code></a> Merge pull request <a href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/34971">#34971</a> from storybookjs/valentin/upgrade-typescript-6</li> <li><a href="https://github.com/storybookjs/storybook/commit/518f711cb367d8df184be22f1fab9a218b2743df"><code>518f711</code></a> Bump version from "10.5.1" to "10.5.2" [skip ci]</li> <li>Additional commits viewable in <a href="https://github.com/storybookjs/storybook/commits/v10.5.5/code/core">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> |
||
|
|
91e1eb43af |
build(deps): bump i18next from 26.3.1 to 26.3.6 (#10300)
Bumps [i18next](https://github.com/i18next/i18next) from 26.3.1 to 26.3.6. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/i18next/i18next/releases">i18next's releases</a>.</em></p> <blockquote> <h2>v26.3.6</h2> <ul> <li>fix: allow TypeScript 7 in the optional <code>typescript</code> peer dependency range (<code>^5 || ^6 || ^7</code>). With <code>typescript@7.0.2</code> in a project, <code>npm install</code> failed with an <code>ERESOLVE</code> peer conflict. The published types are TS7-compatible as-is: every <code>test/typescript</code> suite produces identical results under 6.0 and 7.0.2. Reported in <a href="https://redirect.github.com/i18next/react-i18next/issues/1927">react-i18next#1927</a>, thanks <a href="https://github.com/andikapradanaarif"><code>@andikapradanaarif</code></a>.</li> </ul> <h2>v26.3.5</h2> <ul> <li>fix: <code>$t()</code> nesting options blocks that span multiple lines are now parsed. <code>nest()</code> decided where the nested key ends by testing <code>match[1]</code> with <code>/{.*}/</code>, whose dot does not cross line breaks — so a <code>$t(key, { ... })</code> options object containing a newline was treated as having no options, mis-split as formatters, and the nested lookup ran without its options (placeholders stayed unresolved). The nesting regexp itself already matches newlines inside <code>$t(...)</code>; adding the <code>s</code> (dotAll) flag makes multiline options behave like the single-line form. Thanks <a href="https://github.com/spokodev"><code>@spokodev</code></a> (<a href="https://redirect.github.com/i18next/i18next/pull/2440">#2440</a>).</li> <li>fix: <code>getUsedParamsDetails</code> (the <code>returnDetails: true</code> path) no longer mutates the passed <code>replace</code> object. It wrote <code>count</code> straight onto <code>options.replace</code> so the returned <code>usedParams</code> would include it — a caller reusing one <code>replace</code> object across <code>t()</code> calls then carried a stale <code>count</code> into later interpolations (e.g. a previous call's <code>count: 5</code> rendered instead of the current call's value). The details are now built from a copy; <code>usedParams</code> still includes <code>count</code>. Thanks <a href="https://github.com/spokodev"><code>@spokodev</code></a> (<a href="https://redirect.github.com/i18next/i18next/pull/2441">#2441</a>).</li> <li>fix: with the default <code>skipOnVariables: true</code> + <code>escapeValue: true</code>, a <code>{{placeholder}}</code> carried inside an interpolated value now stays literal even when the value contains escapable characters. The skip logic advanced the regex <code>lastIndex</code> by the raw value length, but the escaped text written into the string is longer, so <code>lastIndex</code> landed inside the inserted value and a trailing <code>{{placeholder}}</code> in it got interpolated — leaking another in-scope variable that should have stayed literal (values without escapable characters were already skipped correctly). The advance now uses the escaped length that is actually written, and the regex-safe <code>$</code>-doubling is applied only at the <code>String.replace</code> call so it can't distort the length arithmetic. Thanks <a href="https://github.com/spokodev"><code>@spokodev</code></a> (<a href="https://redirect.github.com/i18next/i18next/pull/2442">#2442</a>).</li> </ul> <h2>v26.3.4</h2> <ul> <li>fix(security): <code>deepExtend</code> (used by <code>addResourceBundle(..., deep, overwrite)</code>) no longer recurses into inherited properties. It checked key existence with the <code>in</code> operator, which walks the prototype chain, so a source key matching an inherited built-in (e.g. <code>hasOwnProperty</code>, <code>toString</code>) caused recursion into the shared <code>Object.prototype</code> function and, with <code>overwrite: true</code>, could overwrite e.g. <code>Object.prototype.hasOwnProperty.call</code> with a non-callable value — corrupting a shared built-in process-wide (DoS). Existence is now checked with <code>Object.prototype.hasOwnProperty.call</code>, so such keys are copied as plain own data instead. This complements the existing <code>__proto__</code>/<code>constructor</code> guard and is also strictly more correct for an own-property merge. Only affects applications that pass attacker-controlled data with <code>deep: true</code> and <code>overwrite: true</code>; no standard backend/integration does this. Distinct from CVE-2026-48713 / CVE-2026-48714 (different packages, <code>setPath</code> mechanism). Thanks to zx (Jace) for the responsible disclosure.</li> </ul> <h2>v26.3.3</h2> <ul> <li>fix(types): selector <code>t($ => $.arr, { returnObjects: true, context })</code> on a JSON array of <strong>heterogeneous</strong> objects now preserves each element's full shape (e.g. <code>{ transKey1: string; transKey2: string }[]</code>) instead of collapsing to a union of partial element types. Two type-level causes: (1) <code>FilterKeys</code> evaluated the whole array element type at once, so <code>keyof (A | B)</code> only saw the keys common to every element — it now distributes over the object union and filters each element independently; (2) when TypeScript merges mismatched array element types it injects phantom optional <code>undefined</code> keys (e.g. <code>transKey1_withContext?: undefined</code> on elements that don't define it), which the context-detection helpers mistook for real context variants — they now skip keys typed as <code>undefined</code>. Also adds a dedicated <code>context</code> + <code>returnObjects: true</code> selector overload using <code>const Fn</code> + <code>ReturnType<Fn></code>, so <code>Target</code> is no longer collapsed to <code>unknown</code> via <code>ApplyTarget</code>. Resolves Problem 1 of <a href="https://redirect.github.com/i18next/i18next/issues/2398">#2398</a> (Problem 2 was already fixed on master). Thanks <a href="https://github.com/sauravgupta-dotcom"><code>@sauravgupta-dotcom</code></a> (<a href="https://redirect.github.com/i18next/i18next/pull/2438">#2438</a>). Fixes <a href="https://redirect.github.com/i18next/i18next/issues/2398">#2398</a>.</li> </ul> <h2>v26.3.2</h2> <ul> <li>fix: chained formatters with a parenthesised option that contains the format separator (e.g. <code>join(separator: ', ')</code>) now work at <strong>any</strong> position in the chain, not just first. Previously the comma-in-parens reassembly only repaired <code>formats[0]</code>, so <code>{{v, uppercase, join(separator: ', ')}}</code> split the <code>join(...)</code> option on the inner comma and never rejoined it, producing corrupt output. Replaced the first-position-only repair with a position-independent pass that re-joins fragments until each open paren closes. Thanks <a href="https://github.com/spokodev"><code>@spokodev</code></a> (<a href="https://redirect.github.com/i18next/i18next/pull/2437">#2437</a>).</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/i18next/i18next/blob/master/CHANGELOG.md">i18next's changelog</a>.</em></p> <blockquote> <h2>26.3.6</h2> <ul> <li>fix: allow TypeScript 7 in the optional <code>typescript</code> peer dependency range (<code>^5 || ^6 || ^7</code>). With <code>typescript@7.0.2</code> in a project, <code>npm install</code> failed with an <code>ERESOLVE</code> peer conflict. The published types are TS7-compatible as-is: every <code>test/typescript</code> suite produces identical results under 6.0 and 7.0.2. Reported in <a href="https://redirect.github.com/i18next/react-i18next/issues/1927">react-i18next#1927</a>, thanks <a href="https://github.com/andikapradanaarif"><code>@andikapradanaarif</code></a>.</li> </ul> <h2>26.3.5</h2> <ul> <li>fix: <code>$t()</code> nesting options blocks that span multiple lines are now parsed. <code>nest()</code> decided where the nested key ends by testing <code>match[1]</code> with <code>/{.*}/</code>, whose dot does not cross line breaks — so a <code>$t(key, { ... })</code> options object containing a newline was treated as having no options, mis-split as formatters, and the nested lookup ran without its options (placeholders stayed unresolved). The nesting regexp itself already matches newlines inside <code>$t(...)</code>; adding the <code>s</code> (dotAll) flag makes multiline options behave like the single-line form. Thanks <a href="https://github.com/spokodev"><code>@spokodev</code></a> (<a href="https://redirect.github.com/i18next/i18next/pull/2440">#2440</a>).</li> <li>fix: <code>getUsedParamsDetails</code> (the <code>returnDetails: true</code> path) no longer mutates the passed <code>replace</code> object. It wrote <code>count</code> straight onto <code>options.replace</code> so the returned <code>usedParams</code> would include it — a caller reusing one <code>replace</code> object across <code>t()</code> calls then carried a stale <code>count</code> into later interpolations (e.g. a previous call's <code>count: 5</code> rendered instead of the current call's value). The details are now built from a copy; <code>usedParams</code> still includes <code>count</code>. Thanks <a href="https://github.com/spokodev"><code>@spokodev</code></a> (<a href="https://redirect.github.com/i18next/i18next/pull/2441">#2441</a>).</li> <li>fix: with the default <code>skipOnVariables: true</code> + <code>escapeValue: true</code>, a <code>{{placeholder}}</code> carried inside an interpolated value now stays literal even when the value contains escapable characters. The skip logic advanced the regex <code>lastIndex</code> by the raw value length, but the escaped text written into the string is longer, so <code>lastIndex</code> landed inside the inserted value and a trailing <code>{{placeholder}}</code> in it got interpolated — leaking another in-scope variable that should have stayed literal (values without escapable characters were already skipped correctly). The advance now uses the escaped length that is actually written, and the regex-safe <code>$</code>-doubling is applied only at the <code>String.replace</code> call so it can't distort the length arithmetic. Thanks <a href="https://github.com/spokodev"><code>@spokodev</code></a> (<a href="https://redirect.github.com/i18next/i18next/pull/2442">#2442</a>).</li> </ul> <h2>26.3.4</h2> <ul> <li>fix(security): <code>deepExtend</code> (used by <code>addResourceBundle(..., deep, overwrite)</code>) no longer recurses into inherited properties. It checked key existence with the <code>in</code> operator, which walks the prototype chain, so a source key matching an inherited built-in (e.g. <code>hasOwnProperty</code>, <code>toString</code>) caused recursion into the shared <code>Object.prototype</code> function and, with <code>overwrite: true</code>, could overwrite e.g. <code>Object.prototype.hasOwnProperty.call</code> with a non-callable value — corrupting a shared built-in process-wide (DoS). Existence is now checked with <code>Object.prototype.hasOwnProperty.call</code>, so such keys are copied as plain own data instead. This complements the existing <code>__proto__</code>/<code>constructor</code> guard and is also strictly more correct for an own-property merge. Only affects applications that pass attacker-controlled data with <code>deep: true</code> and <code>overwrite: true</code>; no standard backend/integration does this. Distinct from CVE-2026-48713 / CVE-2026-48714 (different packages, <code>setPath</code> mechanism). See advisory <a href="https://github.com/i18next/i18next/security/advisories/GHSA-6jcc-5g8w-32mx">GHSA-6jcc-5g8w-32mx</a>, CVSS 5.9 (<code>CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:H</code>). Thanks to zx (Jace) <a href="https://github.com/manus-use"><code>@manus-use</code></a> for the responsible disclosure.</li> </ul> <h2>26.3.3</h2> <ul> <li>fix(types): selector <code>t($ => $.arr, { returnObjects: true, context })</code> on a JSON array of <strong>heterogeneous</strong> objects now preserves each element's full shape (e.g. <code>{ transKey1: string; transKey2: string }[]</code>) instead of collapsing to a union of partial element types. Two type-level causes: (1) <code>FilterKeys</code> evaluated the whole array element type at once, so <code>keyof (A | B)</code> only saw the keys common to every element — it now distributes over the object union and filters each element independently; (2) when TypeScript merges mismatched array element types it injects phantom optional <code>undefined</code> keys (e.g. <code>transKey1_withContext?: undefined</code> on elements that don't define it), which the context-detection helpers mistook for real context variants — they now skip keys typed as <code>undefined</code>. Also adds a dedicated <code>context</code> + <code>returnObjects: true</code> selector overload using <code>const Fn</code> + <code>ReturnType<Fn></code>, so <code>Target</code> is no longer collapsed to <code>unknown</code> via <code>ApplyTarget</code>. Resolves Problem 1 of <a href="https://redirect.github.com/i18next/i18next/issues/2398">#2398</a> (Problem 2 was already fixed on master). Thanks <a href="https://github.com/sauravgupta-dotcom"><code>@sauravgupta-dotcom</code></a> (<a href="https://redirect.github.com/i18next/i18next/pull/2438">#2438</a>). Fixes <a href="https://redirect.github.com/i18next/i18next/issues/2398">#2398</a>.</li> </ul> <h2>26.3.2</h2> <ul> <li>fix: chained formatters with a parenthesised option that contains the format separator (e.g. <code>join(separator: ', ')</code>) now work at <strong>any</strong> position in the chain, not just first. Previously the comma-in-parens reassembly only repaired <code>formats[0]</code>, so <code>{{v, uppercase, join(separator: ', ')}}</code> split the <code>join(...)</code> option on the inner comma and never rejoined it, producing corrupt output. Replaced the first-position-only repair with a position-independent pass that re-joins fragments until each open paren closes. Thanks <a href="https://github.com/spokodev"><code>@spokodev</code></a> (<a href="https://redirect.github.com/i18next/i18next/pull/2437">#2437</a>).</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/i18next/i18next/commit/e1c60d4dd28a16f91be7f55b3685ffcf9760619b"><code>e1c60d4</code></a> 26.3.6</li> <li><a href="https://github.com/i18next/i18next/commit/04da43e08cb799f2e6f9a5578f3674fe2ef49595"><code>04da43e</code></a> fix: allow typescript 7 in optional peerDependencies range (react-i18next#1927)</li> <li><a href="https://github.com/i18next/i18next/commit/8eed4accc6c69398e9e25f79b617249fd3f7b1ec"><code>8eed4ac</code></a> build</li> <li><a href="https://github.com/i18next/i18next/commit/573ae735682a082ad5a581dea3f2d5f517c53772"><code>573ae73</code></a> 26.3.5</li> <li><a href="https://github.com/i18next/i18next/commit/cc54b05b5cab9bf76cf66557c222c978bbb3c082"><code>cc54b05</code></a> docs(changelog): 26.3.5 — multiline $t() options, replace mutation, escaped-l...</li> <li><a href="https://github.com/i18next/i18next/commit/3180d67291a8fff10950f79660420c106c047f94"><code>3180d67</code></a> fix: skip interpolation of placeholders inside escaped values (<a href="https://redirect.github.com/i18next/i18next/issues/2442">#2442</a>)</li> <li><a href="https://github.com/i18next/i18next/commit/d16f5a2da748082155007ba0677d32b877b1102e"><code>d16f5a2</code></a> fix: stop mutating the passed replace object when returning details (<a href="https://redirect.github.com/i18next/i18next/issues/2441">#2441</a>)</li> <li><a href="https://github.com/i18next/i18next/commit/bed56c115979de52bd85c46d9b7a7b13361bf736"><code>bed56c1</code></a> fix: parse $t() nesting options block that spans multiple lines (<a href="https://redirect.github.com/i18next/i18next/issues/2440">#2440</a>)</li> <li><a href="https://github.com/i18next/i18next/commit/c19e45864f3abbbe90e30be44cc131f2248394bf"><code>c19e458</code></a> docs(changelog): link GHSA advisory for deepExtend fix</li> <li><a href="https://github.com/i18next/i18next/commit/7bb87d09f907b4395ed0825638d7d2c4356f7a89"><code>7bb87d0</code></a> docs(changelog): reference security advisory for deepExtend fix</li> <li>Additional commits viewable in <a href="https://github.com/i18next/i18next/compare/v26.3.1...v26.3.6">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> |
||
|
|
fb680df728 |
build(deps-dev): bump @storybook/addon-a11y from 10.4.2 to 10.5.4 (#10305)
Bumps [@storybook/addon-a11y](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/a11y) from 10.4.2 to 10.5.4. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/storybookjs/storybook/releases">@storybook/addon-a11y's releases</a>.</em></p> <blockquote> <h2>v10.5.4</h2> <h2>10.5.4</h2> <ul> <li>ReactNative: Telemetry framework detection fix - <a href="https://redirect.github.com/storybookjs/storybook/pull/35560">#35560</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>SyntaxHighlighter: Fix PrismJS dark mode mismatch - <a href="https://redirect.github.com/storybookjs/storybook/pull/35541">#35541</a>, thanks <a href="https://github.com/hxy-asdw"><code>@hxy-asdw</code></a>!</li> </ul> <h2>v10.5.3</h2> <h2>10.5.3</h2> <ul> <li>Dependencies: Upgrade TypeScript to 6.0.3 - <a href="https://redirect.github.com/storybookjs/storybook/pull/34971">#34971</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> </ul> <h2>v10.5.2</h2> <h2>10.5.2</h2> <ul> <li>Angular-Vite: Drop <code>@angular/platform-browser-dynamic</code> peer dependency - <a href="https://redirect.github.com/storybookjs/storybook/pull/35457">#35457</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> <li>Angular-Vite: Widen TypeScript peer dependency range to support TypeScript 6 - <a href="https://redirect.github.com/storybookjs/storybook/pull/35455">#35455</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> <li>Core: Include chromatic packages in ecosystem identifier - <a href="https://redirect.github.com/storybookjs/storybook/pull/35170">#35170</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> <li>TanStack: Fix createServerFn validator mock - <a href="https://redirect.github.com/storybookjs/storybook/pull/35185">#35185</a>, thanks <a href="https://github.com/sjh9714"><code>@sjh9714</code></a>!</li> <li>TanStack: Support pathless layout routes (id-only) in story routing - <a href="https://redirect.github.com/storybookjs/storybook/pull/35465">#35465</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> <li>Tanstack-react: Add missing Hydrate export - <a href="https://redirect.github.com/storybookjs/storybook/pull/35111">#35111</a>, thanks <a href="https://github.com/arun-357"><code>@arun-357</code></a>!</li> <li>Tanstack-react: Keep JSX-only component references during dead-code elimination - <a href="https://redirect.github.com/storybookjs/storybook/pull/35206">#35206</a>, thanks <a href="https://github.com/yatishgoel"><code>@yatishgoel</code></a>!</li> <li>Vitest: Fix coverage toggle crash on Vite 6 by clearing closed Vitest instance on restart - <a href="https://redirect.github.com/storybookjs/storybook/pull/35461">#35461</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> </ul> <h2>v10.5.1</h2> <h2>10.5.1</h2> <ul> <li>Angular-Vite: Drop <code>@angular/platform-browser-dynamic</code> peer dependency - <a href="https://redirect.github.com/storybookjs/storybook/pull/35457">#35457</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> <li>Angular-Vite: Widen TypeScript peer dependency range to support TypeScript 6 - <a href="https://redirect.github.com/storybookjs/storybook/pull/35455">#35455</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> <li>Core: Include chromatic packages in ecosystem identifier - <a href="https://redirect.github.com/storybookjs/storybook/pull/35170">#35170</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> </ul> <h2>v10.5.0</h2> <h2>10.5.0</h2> <blockquote> <p><em>Foundational changes for new AI workflows</em></p> </blockquote> <p>Storybook 10.5 contains hundreds of fixes and improvements:</p> <ul> <li>⚡️ Angular-vite framework: Modern, fast dev, docs, and test (preview)</li> <li>🌈 Vitest initialGlobals: Test across themes, viewports, locales</li> <li>🤖 Agentic review: AI-curated visual changesets and search results (experimental)</li> <li>⚛️ React docgen service: Unified metadata across MCP, Docs, and Controls (experimental)</li> <li>🧑💻 Claude / Codex plugins: One-click ADE integration (experimental)</li> </ul> <!-- raw HTML omitted --> <ul> <li>A11y: Fix MDX heading anchors not keyboard accessible - <a href="https://redirect.github.com/storybookjs/storybook/pull/34368">#34368</a>, thanks <a href="https://github.com/TheSeydiCharyyev"><code>@TheSeydiCharyyev</code></a>!</li> <li>A11y: Handle lang attribute throughout preview - <a href="https://redirect.github.com/storybookjs/storybook/pull/35321">#35321</a>, thanks <a href="https://github.com/Sidnioulz"><code>@Sidnioulz</code></a>!</li> <li>A11y: Surface required args and keyboard-reachable Setup controls in ArgsTable - <a href="https://redirect.github.com/storybookjs/storybook/pull/35306">#35306</a>, thanks <a href="https://github.com/Sidnioulz"><code>@Sidnioulz</code></a>!</li> <li>Addon A11y: Preserve disabled a11y rules with runOnly - <a href="https://redirect.github.com/storybookjs/storybook/pull/34649">#34649</a>, thanks <a href="https://github.com/cyphercodes"><code>@cyphercodes</code></a>!</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md">@storybook/addon-a11y's changelog</a>.</em></p> <blockquote> <h2>10.5.4</h2> <ul> <li>ReactNative: Telemetry framework detection fix - <a href="https://redirect.github.com/storybookjs/storybook/pull/35560">#35560</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>SyntaxHighlighter: Fix PrismJS dark mode mismatch - <a href="https://redirect.github.com/storybookjs/storybook/pull/35541">#35541</a>, thanks <a href="https://github.com/hxy-asdw"><code>@hxy-asdw</code></a>!</li> </ul> <h2>10.5.3</h2> <ul> <li>Dependencies: Upgrade TypeScript to 6.0.3 - <a href="https://redirect.github.com/storybookjs/storybook/pull/34971">#34971</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> </ul> <h2>10.5.2</h2> <ul> <li>TanStack: Fix createServerFn validator mock - <a href="https://redirect.github.com/storybookjs/storybook/pull/35185">#35185</a>, thanks <a href="https://github.com/sjh9714"><code>@sjh9714</code></a>!</li> <li>TanStack: Support pathless layout routes (id-only) in story routing - <a href="https://redirect.github.com/storybookjs/storybook/pull/35465">#35465</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> <li>Tanstack-react: Add missing Hydrate export - <a href="https://redirect.github.com/storybookjs/storybook/pull/35111">#35111</a>, thanks <a href="https://github.com/arun-357"><code>@arun-357</code></a>!</li> <li>Tanstack-react: Keep JSX-only component references during dead-code elimination - <a href="https://redirect.github.com/storybookjs/storybook/pull/35206">#35206</a>, thanks <a href="https://github.com/yatishgoel"><code>@yatishgoel</code></a>!</li> <li>Vitest: Fix coverage toggle crash on Vite 6 by clearing closed Vitest instance on restart - <a href="https://redirect.github.com/storybookjs/storybook/pull/35461">#35461</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> </ul> <h2>10.5.1</h2> <ul> <li>Angular-Vite: Drop <code>@angular/platform-browser-dynamic</code> peer dependency - <a href="https://redirect.github.com/storybookjs/storybook/pull/35457">#35457</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> <li>Angular-Vite: Widen TypeScript peer dependency range to support TypeScript 6 - <a href="https://redirect.github.com/storybookjs/storybook/pull/35455">#35455</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> <li>Core: Include chromatic packages in ecosystem identifier - <a href="https://redirect.github.com/storybookjs/storybook/pull/35170">#35170</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> </ul> <h2>10.5.0</h2> <blockquote> <p><em>Foundational changes for new AI workflows</em></p> </blockquote> <p>Storybook 10.5 contains hundreds of fixes and improvements:</p> <ul> <li>⚡️ Angular-vite framework: Modern, fast dev, docs, and test (preview)</li> <li>🌈 Vitest initialGlobals: Test across themes, viewports, locales</li> <li>🤖 Agentic review: AI-curated visual changesets and search results (experimental)</li> <li>⚛️ React docgen service: Unified metadata across MCP, Docs, and Controls (experimental)</li> <li>🧑💻 Claude / Codex plugins: One-click ADE integration (experimental)</li> </ul> <!-- raw HTML omitted --> <ul> <li>A11y: Fix MDX heading anchors not keyboard accessible - <a href="https://redirect.github.com/storybookjs/storybook/pull/34368">#34368</a>, thanks <a href="https://github.com/TheSeydiCharyyev"><code>@TheSeydiCharyyev</code></a>!</li> <li>A11y: Handle lang attribute throughout preview - <a href="https://redirect.github.com/storybookjs/storybook/pull/35321">#35321</a>, thanks <a href="https://github.com/Sidnioulz"><code>@Sidnioulz</code></a>!</li> <li>A11y: Surface required args and keyboard-reachable Setup controls in ArgsTable - <a href="https://redirect.github.com/storybookjs/storybook/pull/35306">#35306</a>, thanks <a href="https://github.com/Sidnioulz"><code>@Sidnioulz</code></a>!</li> <li>Addon A11y: Preserve disabled a11y rules with runOnly - <a href="https://redirect.github.com/storybookjs/storybook/pull/34649">#34649</a>, thanks <a href="https://github.com/cyphercodes"><code>@cyphercodes</code></a>!</li> <li>Addon Docs: DocsContent not filling available width when TOC is enabled - <a href="https://redirect.github.com/storybookjs/storybook/pull/35043">#35043</a>, thanks <a href="https://github.com/k-utsumi"><code>@k-utsumi</code></a>!</li> <li>Addon Docs: Resolve CSF4 module exports without a default export - <a href="https://redirect.github.com/storybookjs/storybook/pull/34834">#34834</a>, thanks <a href="https://github.com/TheSeydiCharyyev"><code>@TheSeydiCharyyev</code></a>!</li> <li>Addon Docs: Resolve providerImportSource to a path instead of a file:// URL - <a href="https://redirect.github.com/storybookjs/storybook/pull/34841">#34841</a>, thanks <a href="https://github.com/TheSeydiCharyyev"><code>@TheSeydiCharyyev</code></a>!</li> <li>Addon Vitest: Add an initialGlobals option to pin a project's globals - <a href="https://redirect.github.com/storybookjs/storybook/pull/35226">#35226</a>, thanks <a href="https://github.com/lifeiscontent"><code>@lifeiscontent</code></a>!</li> <li>Addon Vitest: Avoid erroring out on benign Win process exits - <a href="https://redirect.github.com/storybookjs/storybook/pull/35287">#35287</a>, thanks <a href="https://github.com/Sidnioulz"><code>@Sidnioulz</code></a>!</li> <li>Addon Vitest: Fix dynamic import failure with Vitest 3 - <a href="https://redirect.github.com/storybookjs/storybook/pull/34927">#34927</a>, thanks <a href="https://github.com/Sidnioulz"><code>@Sidnioulz</code></a>!</li> <li>Addon Vitest: Subscribe for run completion before triggering it - <a href="https://redirect.github.com/storybookjs/storybook/pull/35291">#35291</a>, thanks <a href="https://github.com/tsushanth"><code>@tsushanth</code></a>!</li> <li>Angular: Add versioned <code>@types/node</code> to packages installed during <code>storybook init</code> - <a href="https://redirect.github.com/storybookjs/storybook/pull/34192">#34192</a>, thanks <a href="https://github.com/copilot-swe-agent"><code>@copilot-swe-agent</code></a>!</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/storybookjs/storybook/commit/3327dc44697304275e28ceaa2cd34d9bede4e333"><code>3327dc4</code></a> Bump version from "10.5.3" to "10.5.4" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/9ac273930a49ad33b6a331f1f36dc472f5c36054"><code>9ac2739</code></a> Bump version from "10.5.2" to "10.5.3" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/b4b00f27662caf7328330b5ab47e9b903218f43a"><code>b4b00f2</code></a> Merge pull request <a href="https://github.com/storybookjs/storybook/tree/HEAD/code/addons/a11y/issues/34971">#34971</a> from storybookjs/valentin/upgrade-typescript-6</li> <li><a href="https://github.com/storybookjs/storybook/commit/518f711cb367d8df184be22f1fab9a218b2743df"><code>518f711</code></a> Bump version from "10.5.1" to "10.5.2" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/c253a0667d39899a0f7a09fa90f262f69ad4ae90"><code>c253a06</code></a> Bump version from "10.5.0" to "10.5.1" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/9dafcd22ed55947bc4c2fa1d5066b552baa0ebf4"><code>9dafcd2</code></a> Bump version from "10.5.0-beta.2" to "10.5.0" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/ad709148eb8ea2113bd326a6bc66a5c9b9f8d97c"><code>ad70914</code></a> Addon A11y: Keep nested command output while closing stdin</li> <li><a href="https://github.com/storybookjs/storybook/commit/c557fc0fb6db50c058b69fb4465f977ae786264c"><code>c557fc0</code></a> CLI: Fix silent hang in deferred addon configuration during upgrade</li> <li><a href="https://github.com/storybookjs/storybook/commit/448db85e651a09ca55f978356c4f1593f261f82a"><code>448db85</code></a> Bump version from "10.5.0-beta.1" to "10.5.0-beta.2" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/a4ce9790a783d8e7720e9de980a08576de9555db"><code>a4ce979</code></a> Bump version from "10.5.0-beta.0" to "10.5.0-beta.1" [skip ci]</li> <li>Additional commits viewable in <a href="https://github.com/storybookjs/storybook/commits/v10.5.4/code/addons/a11y">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> |
||
|
|
00b43a7446 |
build(deps): bump @tanstack/react-query from 5.101.2 to 5.101.4 (#10307)
Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.101.2 to 5.101.4. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/TanStack/query/releases">@tanstack/react-query's releases</a>.</em></p> <blockquote> <h2><code>@tanstack/react-query-devtools</code><a href="https://github.com/5"><code>@5</code></a>.101.4</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/query-devtools</code><a href="https://github.com/5"><code>@5</code></a>.101.4</li> <li><code>@tanstack/react-query</code><a href="https://github.com/5"><code>@5</code></a>.101.4</li> </ul> </li> </ul> <h2><code>@tanstack/react-query-next-experimental</code><a href="https://github.com/5"><code>@5</code></a>.101.4</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/react-query</code><a href="https://github.com/5"><code>@5</code></a>.101.4</li> </ul> </li> </ul> <h2><code>@tanstack/react-query-persist-client</code><a href="https://github.com/5"><code>@5</code></a>.101.4</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/query-persist-client-core</code><a href="https://github.com/5"><code>@5</code></a>.101.4</li> <li><code>@tanstack/react-query</code><a href="https://github.com/5"><code>@5</code></a>.101.4</li> </ul> </li> </ul> <h2><code>@tanstack/react-query</code><a href="https://github.com/5"><code>@5</code></a>.101.4</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/query-core</code><a href="https://github.com/5"><code>@5</code></a>.101.4</li> </ul> </li> </ul> <h2><code>@tanstack/react-query-devtools</code><a href="https://github.com/5"><code>@5</code></a>.101.3</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/query-devtools</code><a href="https://github.com/5"><code>@5</code></a>.101.3</li> <li><code>@tanstack/react-query</code><a href="https://github.com/5"><code>@5</code></a>.101.3</li> </ul> </li> </ul> <h2><code>@tanstack/react-query-next-experimental</code><a href="https://github.com/5"><code>@5</code></a>.101.3</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/react-query</code><a href="https://github.com/5"><code>@5</code></a>.101.3</li> </ul> </li> </ul> <h2><code>@tanstack/react-query-persist-client</code><a href="https://github.com/5"><code>@5</code></a>.101.3</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/query-persist-client-core</code><a href="https://github.com/5"><code>@5</code></a>.101.3</li> <li><code>@tanstack/react-query</code><a href="https://github.com/5"><code>@5</code></a>.101.3</li> </ul> </li> </ul> <h2><code>@tanstack/react-query</code><a href="https://github.com/5"><code>@5</code></a>.101.3</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [<a href="https://github.com/TanStack/query/commit/7e3c822a10896f41a8f1031c16b85096277af677"><code>7e3c822</code></a>]:</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md">@tanstack/react-query's changelog</a>.</em></p> <blockquote> <h2>5.101.4</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/query-core</code><a href="https://github.com/5"><code>@5</code></a>.101.4</li> </ul> </li> </ul> <h2>5.101.3</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [<a href="https://github.com/TanStack/query/commit/7e3c822a10896f41a8f1031c16b85096277af677"><code>7e3c822</code></a>]: <ul> <li><code>@tanstack/query-core</code><a href="https://github.com/5"><code>@5</code></a>.101.3</li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/TanStack/query/commit/86bb8a6fb2c7f15c74ff50afba053d778e6edc23"><code>86bb8a6</code></a> ci: Version Packages (<a href="https://github.com/TanStack/query/tree/HEAD/packages/react-query/issues/11094">#11094</a>)</li> <li><a href="https://github.com/TanStack/query/commit/181ea826cb5b5f722a774525046d8f4e105dd6bb"><code>181ea82</code></a> ci: Version Packages (<a href="https://github.com/TanStack/query/tree/HEAD/packages/react-query/issues/11089">#11089</a>)</li> <li><a href="https://github.com/TanStack/query/commit/6d55b0759b4722b888fa516b1bb86c0a56ea47a2"><code>6d55b07</code></a> test({react,preact}-query): use the '.then()' convention consistently (<a href="https://github.com/TanStack/query/tree/HEAD/packages/react-query/issues/11085">#11085</a>)</li> <li><a href="https://github.com/TanStack/query/commit/44f38df5deaf72d8d74bc62b620dffed43fdbc05"><code>44f38df</code></a> test({react,preact,solid}-query/useInfiniteQuery): inline the shared 'fetchIt...</li> <li><a href="https://github.com/TanStack/query/commit/d1558c1491629b36661e0a166e1091bb4a256daa"><code>d1558c1</code></a> test({react,preact}-query/usePrefetchQuery): inline the 'generateQueryFn' fac...</li> <li><a href="https://github.com/TanStack/query/commit/99690d18b7937f217d3744b1c2ac78cc47caeaa7"><code>99690d1</code></a> test({react,preact}-query/usePrefetchInfiniteQuery): inline single-use helper...</li> <li><a href="https://github.com/TanStack/query/commit/10770f0720dacae3a26701a747e33abd6bafbf8a"><code>10770f0</code></a> test({react,preact}-query/usePrefetchInfiniteQuery): inline the shared 'Suspe...</li> <li><a href="https://github.com/TanStack/query/commit/dbd5a86e95284387bc3f172208bc52c0053a1bb2"><code>dbd5a86</code></a> test({react,preact}-query/usePrefetchQuery): inline the shared 'Suspended' co...</li> <li><a href="https://github.com/TanStack/query/commit/b955f60d7965cc521df6ee8b1ce91b3d0e8c046d"><code>b955f60</code></a> test({react,preact}-query/useSuspenseQuery): assert the 'loading' fallback is...</li> <li><a href="https://github.com/TanStack/query/commit/b9c657e20b1ac1078ab265de8fc691aec192e143"><code>b9c657e</code></a> test({react,preact}-query/usePrefetchQuery): assert the 'Loading...' fallback...</li> <li>Additional commits viewable in <a href="https://github.com/TanStack/query/commits/@tanstack/react-query@5.101.4/packages/react-query">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> |
||
|
|
0a6532175c |
build(deps): bump react-resizable-panels from 4.12.1 to 4.12.2 (#10301)
Bumps [react-resizable-panels](https://github.com/bvaughn/react-resizable-panels) from 4.12.1 to 4.12.2. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/bvaughn/react-resizable-panels/blob/main/CHANGELOG.md">react-resizable-panels's changelog</a>.</em></p> <blockquote> <h2>4.12.2</h2> <ul> <li><a href="https://redirect.github.com/bvaughn/react-resizable-panels/issues/726">726</a>: Updated inline documentation to clarify size units.</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/bvaughn/react-resizable-panels/commit/a1eeb7aefdb024bb5879a323218e0ac05f77f28e"><code>a1eeb7a</code></a> 4.12.1 -> 4.12.2</li> <li>See full diff in <a href="https://github.com/bvaughn/react-resizable-panels/compare/4.12.1...4.12.2">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> |
||
|
|
c274f10abc |
feat(server): computed owner instance-admin elevation for cloud-managed instances, behind platform floors (#10343)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Cloud-managed instances authenticate tenant users through a trusted-header path (`resolveCloudTenantActor`) that deliberately never grants `instance_admin`, so every tenant user is company-scoped > - On a dedicated (single-owner) managed instance that leaves the paying owner unable to administer their own instance: instance settings, the environments admin surface, and the custom sandbox image flow are all instance-admin gated (the environments UI can't even show the provider/image of the platform sandbox because the restricted read view blanks `config` entirely) > - Re-granting the old blanket `instance_user_roles` row would repeat the mistake the shared-pool hardening fixed: DB rows go stale, resurrect via restores, and elevate through every auth path > - This pull request elevates only the stack `owner`, computed per request at the trusted-header boundary behind a new managed-tier feature flag, and ships that elevation together with code floors on the platform-owned surfaces an instance admin must not control on a managed instance > - The benefit is that dedicated-stack owners can administer their own instance while platform credentials, execution policy, backups, and runtime code-install stay platform-owned, and self-hosted behavior is unchanged ## Linked Issues or Issue Description No public GitHub issue exists for this change; the underlying issue is described here following the feature-request template. ### Problem or motivation - On cloud-managed instances, tenant users resolved from trusted headers are always company-scoped. For dedicated instances with a single paying owner, the owner cannot reach any instance-admin surface of their own instance (instance settings, environments administration, custom image setup), and the restricted environment read view hides even structural fields like the sandbox provider and image. - The previous hardening intentionally removed blanket elevation (and purges stale `instance_user_roles` rows on every trusted-header authentication). That protection must not regress for shared multi-tenant pools. ### Proposed solution - Owner-only, computed, flag-gated elevation plus code floors on platform-owned surfaces, in one PR so the elevation can never ship without the floors. ### Alternatives considered - Re-inserting an `instance_user_roles` row for owners (the pre-hardening model): rejected — DB rows go stale, survive restores, and elevate through every auth path; #7525 removed exactly this. - Widening only the environments read view without any elevation: rejected — it fixes one screen but still leaves a dedicated-instance owner unable to administer instance settings or custom images. - Elevating additional stack roles (`member`/`admin`/`support`): rejected — only the owner has an ownership claim over the whole instance; other roles stay company-scoped. ### Roadmap alignment - Extends the shipped "Cloud deployments" roadmap work (multi-tenant isolation, company-scoped cloud tenants, managed-instance bootstrap) without overlapping planned core items, and leaves self-hosted behavior unchanged. ## What Changed - **New feature key** `enableOwnerInstanceAdmin` (`packages/shared`): boolean flag in `instanceExperimentalSettingsSchema`, catalog tier `managed`, `cloudDefault: true`, `selfHostedDefault: false`. Inert on self-hosted instances — the elevation path only exists behind the cloud tenant trust token. - **Computed elevation** (`server/src/middleware/auth.ts`): `resolveCloudTenantActor` now returns `isInstanceAdmin: true` only when the trusted-header stack role is `owner` **and** the flag is enabled. The flag is resolved through the instance-settings service so the managed-config overlay applies (the control plane can disable elevation fleet-wide without touching tenant databases; a DB row edit or restore cannot resurrect it). Resolution fails closed on settings read errors. The `instance_user_roles` never-insert and the per-request stale-row purge are byte-identical. `member`/`admin`/`support` stack roles stay company-scoped. - **Authorization guard split** (`server/src/services/authorization.ts`): the blanket-allow now trusts the actor's *computed* `isInstanceAdmin` flag (only the attested resolver can set it for `cloud_tenant` actors) while keeping the `instance_user_roles` DB lookup excluded for `cloud_tenant` — a stale or hand-inserted role row still elevates nothing. - **Floor F1 — platform environment credentials** (`server/src/routes/environments.ts`): on cloud-managed instances, platform-provisioned environment rows (`managedByPaperclip` marker, plus the legacy managed-Kubernetes marker) use a single floored view for every reader on all environment routes (list, get, create, update, delete responses): `envVars` are never echoed and credential-shaped `config` keys (reusing the managed-config `SECRET_LIKE_CONFIG_KEY_PATTERN`) are dropped — for **all** actors including instance admins — while structural config (provider, image, template, region, …) and the managed markers stay visible. This also fixes the environments UI for managed sandboxes, which previously lost the provider/image entirely in the restricted view. The floor also covers writes: `PATCH /environments/:id` and `DELETE /environments/:id` on a platform-provisioned row are rejected (403, `environment_platform_managed`) for every actor including instance admins, and the guard binds to the persisted row's markers so a patch cannot strip the managed marker to lift the floor. The one recovery path is a metadata-only PATCH that solely clears the marker keys (null/false), for rows stamped through the old unrestricted API before the markers became reserved — and it never applies to a row whose slot markers are live platform state: the single local row (`environments_local_driver_idx`), which `ensureLocalEnvironment` adopts and stamps on cloud-managed instances from every caller (company creation, the heartbeat, run orchestration), and the single marked sandbox row (`environments_managed_sandbox_idx`) while a managed-sandbox bootstrap path is configured (managed-config `environments` section or `PAPERCLIP_EXECUTION_MODE=kubernetes`) and the provisioner therefore adopts and refreshes it on every boot. Clearing a live slot row's markers would let the next write reclassify it as tenant-managed and bypass the floor; conversely, when no sandbox provisioning path is configured the platform holds no claim on any sandbox row, so a platform marker there is stale by definition and the recovery patch applies. Every marker outside a live slot is clearable, so no legacy row is ever locked permanently. Custom-image setup and probes on the platform sandbox stay available to instance admins — those are the owner-facing flows this elevation exists for. The marker keys themselves are reserved: client create/update payloads that set `managedByPaperclip` or `managedKubernetesSandbox` are rejected (422, `environment_platform_marker_reserved`) on cloud-managed instances, so a tenant row can never be stamped platform-provisioned through the API and self-locked behind the write floor (the provisioner writes markers at the service layer, not through these routes). Tenant-created environments are otherwise unaffected. - **Floor F2 — executionMode** (`server/src/routes/instance-settings.ts`): on cloud-managed instances, `PATCH /instance/settings/general` rejects writes that would change `executionMode` (403, `execution_mode_platform_managed`). Same-value echoes pass so settings forms that submit the full general-settings object keep working. The boot-time execution-policy bootstrap path is untouched (it calls the service directly). - **Floor F3 — manual database backups** (`server/src/routes/instance-database-backups.ts`): floored off on cloud-managed instances (403, `database_backups_platform_managed`); backups are platform-owned there, and the result would also echo a server-side filesystem path. - **Floor F4 — adapter code install** (`server/src/routes/adapters.ts`): `POST /adapters/install` and `POST /adapters/:type/reinstall` are floored off on cloud-managed instances (403, `adapter_install_platform_managed`). Adapter packages execute in the server process, so a runtime install would let an instance admin read the platform trust anchors out of the process environment. This mirrors the existing bundled-only plugin install floor; adapter code on managed instances comes bundled with the platform image. ## Instance-admin surface audit Before widening who can hold `isInstanceAdmin`, every instance-admin-gated surface in `server/src` was enumerated and reviewed for whether its response or side effects could echo process environment values or platform credentials (tenant trust token, JWT signing keys, database connection strings, provider API keys): 29 distinct gate definitions covering ~90+ call sites, in four groups — sole instance-admin gates (12), instance-admin-or-company-permission gates (10), response-shaping/scope-widening sites (6), and the central `allow_instance_admin` short-circuit in the authorization service (58 `decide()` call sites). Findings and dispositions: - **Environment read/write responses** exposed platform sandbox `envVars`/credential-shaped config to instance admins → closed by floor F1. - **Manual backup trigger** echoed a server filesystem path and triggers a platform-owned operation → closed by floor F3. - **Adapter install/reinstall** loads externally fetched code into the server process (indirect, complete env exposure) → closed by floor F4. The sibling plugin-install path already had a bundled-only floor on managed instances and needed no change. - **Token-minting surfaces** (gateway tokens, custom-image terminal/connection tokens) mint credentials scoped to the instance's own resources, not platform trust anchors → acceptable for an owner-admin of a dedicated instance; unchanged. - All remaining gated surfaces return ordinary instance-scoped business data; none echo `process.env` or platform secrets directly. OAuth client secrets are referenced by env-var *name* only; SSH private keys are stored as secret refs before persistence and are not echoed. Operational note for managed platforms: this model assumes the process environment of a managed instance holds only that instance's own credentials. Platform operators should keep provider credentials per-instance (never fleet-shared) since an instance admin ultimately controls in-process code on their own instance. ## Verification - `pnpm vitest run server/src/middleware/cloud-tenant-actor.test.ts` — resolver matrix: owner × flag on/off, flag via managed overlay (on-over-DB-off and off-over-DB-on), member/admin/support × flag on, no-token self-hosted, fail-closed settings read, purge still runs and no role row is ever inserted (14 tests). - `pnpm vitest run server/src/__tests__/authorization-service.test.ts` — computed flag elevates a `cloud_tenant` actor; a stale `instance_user_roles` row still never does; `session` actors unchanged (full suite, embedded Postgres). - `pnpm vitest run server/src/__tests__/environment-routes.test.ts` — F1: no secret echo to admins on get/list, structural config visible to restricted readers, platform-row PATCH/DELETE rejected for admins (including a marker-stripping patch), marker-clear recovery allowed for stale legacy rows and for a marked sandbox row when no provisioning path is configured, but refused on the managed local row and on the sandbox slot row under a managed-config `environments` entry or the forced kubernetes execution mode, client marker-stamping creates/patches rejected, tenant rows still readable and writable, self-hosted read+write regression (60 tests). - `pnpm vitest run server/src/__tests__/environment-service.test.ts` — `ensureLocalEnvironment` adopts a pre-existing local row on cloud-managed instances (marker stamped, other metadata preserved, idempotent — no rewrite on re-ensure) and leaves self-hosted rows untouched (22 tests, embedded Postgres). - `pnpm vitest run server/src/__tests__/instance-settings-routes.test.ts server/src/__tests__/instance-database-backups-routes.test.ts` — F2 change-vs-echo matrix incl. self-hosted regression; F3 floor for both admin shapes (32 tests). - `pnpm vitest run server/src/__tests__/adapter-routes-authz.test.ts` — F4 floor; self-hosted install/reinstall behavior unchanged (existing cases). - `pnpm vitest run server/src/__tests__/first-admin-claim.test.ts server/src/__tests__/bootstrap-claim-routes.test.ts server/src/__tests__/managed-config.test.ts server/src/__tests__/health.test.ts server/src/__tests__/instance-settings-managed-overlay.test.ts server/src/services/managed-environments.test.ts server/src/services/execution-policy-bootstrap.test.ts` — first-admin bootstrap gate and managed-config behavior unchanged (91 tests). - `pnpm vitest run packages/shared/src/feature-catalog.test.ts` — catalog/schema sync tests cover the new key (selfHostedDefault must equal the schema default). - `pnpm run typecheck` — all 31 workspace projects clean. ## Risks - Self-hosted behavior is unchanged: every floor binds to `isCloudManagedInstance()` (tenant trust token present), the new flag defaults off with no elevation path, and regression tests pin the self-hosted branches. - The elevation is fail-closed and stateless: turning the flag off (managed overlay or DB) de-elevates on the next request; there is no role row to clean up and restores cannot resurrect elevation. - On a cloud-managed instance a pre-existing unmarked local row is adopted (stamped `managedByPaperclip`) by the next ensure and becomes platform-owned — the intended managed-product semantic: the platform owns the single local slot. Self-hosted instances are untouched. - F1 widens restricted readers' view of platform-provisioned rows from fully blanked `config`/`metadata` to structural-only `config` plus markers. Platform-delivered config is guaranteed secret-free by the managed-config contract (secret-shaped keys fail startup), and the floor re-drops secret-shaped keys defensively. - One extra instance-settings read per trusted-header request for owner-role actors (the resolver already performs several queries per request). ## Model Used Claude Fable 5 (Anthropic) — model id `claude-fable-5`, extended thinking enabled, agentic tool use via Claude Code; read-only explore subagents on the same model were used for the surface audit sweep. ## 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 - [ ] 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> |
||
|
|
c3bd0c5d50 |
feat(skills): add beta releases for the core Paperclip skill (#10228)
## Thinking Path > - Paperclip is the open source control plane people use to organize and operate AI-agent companies. > - Agent behavior depends partly on the bundled Paperclip core skill synchronized into each runtime. > - The existing database and runtime plumbing already supports immutable skill-version snapshots and per-agent version selections, but no product workflow exposed that capability. > - Replacing the live bundled skill globally would make champion adoption risky and difficult to compare across agents. > - This pull request adds an experimental, instance-level beta-skills gate plus a repository release registry, immutable seeded releases, enforcement, and a per-agent release picker. > - The benefit is controlled per-agent evaluation of frozen core-skill releases while the default-off path remains behaviorally unchanged. ## Linked Issues or Issue Description ### Subsystem affected Cross-cutting: `server/`, `ui/`, `packages/db`, and `packages/shared`. ### Problem or motivation Paperclip needs a safe way to evaluate improved versions of its core operating skill without globally replacing the live default. Today the version-snapshot and per-agent pin plumbing exists, but operators cannot use it. A global replacement would make regressions difficult to contain and would prevent controlled comparisons across agents. ### Proposed solution Add a default-off instance experiment that exposes immutable, named core-skill releases. When enabled, operators can pin each agent to a seeded release; when disabled, every agent resolves the live default while saved pins remain intact. Validate pinned writes at the API boundary, gate reads at runtime, and expose the selection in the agent Skills tab. ### Alternatives considered - **Replace the bundled core skill globally:** rejected because it changes every agent at once and provides no rollback/isolation boundary. - **Ship releases as separate skills:** rejected because releases are versions of one core capability, not independently enabled skills. - **Store release snapshots only outside the repository:** rejected because repository provenance and hashes make builds reproducible and reviewable. ### Roadmap alignment This extends the Skills Manager / Skill Studio direction in `ROADMAP.md` by making core-skill versions operable per agent. It does not duplicate another open implementation PR; GitHub searches found no related `enableBetaSkills` change. ### Additional context The feature remains experimental and default off. The V7 champion was selected through a multi-model evaluation process, and the frozen release contents are verified by SHA-256 below. ## What Changed - Added the default-off instance-level `enableBetaSkills` experimental flag. - Added `skills-releases/paperclip/` with the ordered release registry and frozen `v0` plus `v7-roster` snapshots. - Added release metadata to `company_skill_versions` and idempotent release seeding. The migration was planned as `0191`, then renumbered to `0192` because current `master` claimed `0191` before final rebase. - Added read-time gating and write-time validation so disabled instances always resolve the live default and reject pinned-version writes. - Added the per-agent Release picker in the agent Skills tab, including responsive layout and beta-pin state. - Kept `EDITS.md` out of the release registry and PR diff. ### V7 Adoption Evidence - Paid roster: 6 models, 94-case suite. - Result: 553/564 pass-within-2, mean 92.17/94, versus the P2 baseline of 544/564. - Reference model improved 84→91; maximin improved 84→90. - Final report: https://pages.paperclip.ing/skills/optimization/paperclip/pap-14624-p3-final-20260721/ ### Provenance - `v7-roster` is the Phase 1 champion plus additions-only edits E107–E112. Per-edit rationale remains in the evals repository at `source/v7-roster/EDITS.md` and is deliberately excluded from this PR. - `v0` is the `skills/paperclip` tree from commit `ea66ea81`. - Champion selection was accepted on July 21, 2026 via board card `9c304fc2` (PAP-14624 G3). - This delivery mechanism was accepted on July 24, 2026 via plan revision `2367abd2` (PAP-14858). ### QA Evidence - P4 QA matrix comment `b7f40522-4e9b-4a3a-9821-28e86fe1a987`: all 6 acceptance criteria passed. - Automated QA matrix: 166 tests passed with 0 failures, including real filesystem materialization and full SHA-256 assertions. - UI QA exercised the real agent Skills tab at desktop and mobile widths with the experimental flag both on and off. ## Verification - `pnpm check:token-gates` - Focused beta-release matrix: 169 tests passed across shared validators, server services/routes/heartbeat behavior, instance settings UI, and release picker UI. - `pnpm -r typecheck` - `pnpm build` - `pnpm test:run`: server and UI partitions passed; one CLI doctor test inherited temporary AWS credentials from the agent heartbeat and expected no static credentials. The isolated rerun with `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN` unset passed 8/8. - V7 SHA-256: - `SKILL.md`: `53ab290489684cbf116fdd1406a95f6b6f53c9c36358b1bf8bfeae481e253575` - `references/cases.md`: `3b821f59064a7761091020a14819a8d787131f24029748563d6c0e1be7e6eaec` - `references/workflows.md`: `69747bd6e05f7e3673d1e67b07ff295df1869c05e1fd029804d5fa9177db92cd` - Confirmed 49 changed files, no `pnpm-lock.yaml`, no workflow changes, and no `EDITS.md`. ## Risks - **Migration:** low-to-moderate risk. Three nullable columns and one partial unique index are added idempotently; existing rows remain valid. - **Behavior:** low risk while the flag is off because read-time resolution forces the live default and saved pins are preserved but inactive. - **Frozen content:** release snapshots intentionally diverge from future live skill edits; provenance and hashes make that divergence explicit and reproducible. - **UI:** low risk. The picker only renders for the bundled core skill when the experimental flag is enabled and seeded releases exist. > This extends the existing Skills Manager / Skill Studio direction described in `ROADMAP.md`; it does not duplicate another open implementation PR. The GitHub PR search found no related `enableBetaSkills` change. ## Model Used - OpenAI Codex using `gpt-5.5` with reasoning and terminal/code-execution tools; context-window size is not exposed by this runtime. Earlier implementation commits also record Claude Opus 4.8 assistance 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 - [ ] I have not referenced internal/instance-local Paperclip issues or links (required governance identifiers are included above; no internal URL is included) - [ ] My branch name describes the change and contains no internal Paperclip ticket id (the approved delivery plan mandated this shared branch name) - [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> |
||
|
|
c111ee4cb3 |
feat(server): add per-user document stars (#9952)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI-agent companies and their work. > - Artifacts and documents are first-class outputs, but users need a personal way to keep important documents easy to find. > - Existing resource memberships already model per-user starred projects and agents with company scoping and activity logging. > - Documents lacked the equivalent membership model, route, and artifact filtering behavior. > - The shared membership contract also needs to remain safe for existing UI project/agent mutation helpers when documents become a recognized resource type. > - This pull request extends the existing resource-membership system with per-user document stars and a starred artifacts view. > - The benefit is a company-scoped, idempotent server foundation for a dedicated starred-documents experience without weakening authorization or artifact filtering semantics. ## Linked Issues or Issue Description ### Problem / Motivation Board users cannot star individual documents, and the company artifacts API cannot return only the current user's starred documents. ### Proposed Solution Add company/user-scoped document memberships, a board-only document star route, document membership data in the shared contract, and a `starred=true` artifacts filter. ### Alternatives Considered A document column was rejected because stars are per-user; a separate star API was rejected because projects and agents already use resource memberships. ### Roadmap Alignment This extends the existing Artifacts & Work Products roadmap area and does not duplicate another open pull request found in the repository search. ## What Changed - Added the `document_memberships` schema and migration with company/user/document uniqueness and starred ordering. - Extended shared resource-membership and artifact-query contracts for documents and `starred=true`. - Added company-scoped document star/unstar service and board-only route behavior with activity logging. - Added starred document artifact filtering, including user-authored documents, document kinds, cursor ordering, and incompatible-kind handling. - Preserved idempotency under concurrent star requests and synchronized UI membership defaults/helpers with the expanded contract. - Added focused shared, route, service, and UI regression coverage. ## Verification - `pnpm exec vitest run packages/shared/src/resource-memberships.test.ts server/src/__tests__/company-artifacts-service.test.ts server/src/__tests__/resource-memberships-routes.test.ts` - `pnpm exec vitest run ui/src/components/SidebarAgents.test.tsx ui/src/components/SidebarProjects.test.tsx ui/src/components/SidebarStarredProjects.test.tsx` - `pnpm --filter @paperclipai/db check:migrations` - `pnpm -r typecheck` - `pnpm test:run` - `pnpm build` ## Risks - The migration adds a new membership table and non-concurrent indexes; migration safety gates pass with the repository's established policy. - The starred artifacts query intentionally returns only documents and relaxes the normal agent-authored/system-kind predicates for documents the current user explicitly starred. - Document membership mutations remain board-user-only; agent callers receive no document-star capability. > 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; runtime model ID and context-window size were not exposed to this session. Reasoning, repository tool use, code execution, and test execution were 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: Paperclip <noreply@paperclip.ing> |
||
|
|
1426494ab8 |
fix(agents): disable cheap model profiles by default (#10019)
## Thinking Path
> - Paperclip is the control plane people use to create and govern
AI-agent companies
> - Agent creation persists runtime configuration that controls which
model profiles future runs may select
> - Adapters can expose a `cheap` profile, and existing creation paths
implicitly left that profile available when operators made no choice
> - That made a newly created agent eligible for a lower-cost model
without an explicit operator opt-in
> - The UI also dropped an explicit opt-in when the operator selected
the adapter's default cheap model rather than a custom model ID
> - Codex additionally hardcoded `gpt-5.3-codex-spark` into its cheap
profile and static fallback model list, making Paperclip choose an
auth-dependent model rather than requiring an operator choice
> - This pull request makes new-agent creation disable an available
cheap profile by default while preserving explicit opt-in from the UI or
API
> - The Codex cheap profile now remains available for explicit
configuration but supplies no model default, so an unconfigured cheap
request stays on the primary model
> - The benefit is predictable model quality for new agents and an
intentional, auditable choice before lower-cost routing is enabled
## Linked Issues or Issue Description
**Problem**
New agents created with an adapter that exposes a `cheap` model profile
can inherit that profile without the operator explicitly enabling it. In
the UI, enabling the adapter-default cheap model is also omitted because
runtime configuration is only written when a custom model ID is present.
**Expected behavior**
- New agents default an available `cheap` model profile to `{ enabled:
false }` when the caller does not specify it.
- Explicit API configuration remains authoritative.
- UI opt-in persists even when the adapter default model is used.
- Codex does not advertise or automatically select
`gpt-5.3-codex-spark`; operators must explicitly configure any
lower-cost Codex model.
**Related public work**
- Refs #4881, which introduced cheap model profiles for local adapters.
- Supersedes the default-selection portions of #8032 and #10004 by
removing the Codex model default instead of replacing it with another
hardcoded model.
## What Changed
- Detect whether the selected adapter exposes a `cheap` model profile
during agent creation and hiring.
- Persist `runtimeConfig.modelProfiles.cheap.enabled = false` only when
the caller did not explicitly configure the profile.
- Preserve UI cheap-profile opt-in when using the adapter's default
model by writing an empty adapter config.
- Remove `gpt-5.3-codex-spark` from the Codex static model list.
- Keep the Codex `cheap` profile explicitly configurable while giving it
an empty adapter config, so Paperclip never chooses a cheap Codex model
automatically.
- Verify that a Codex cheap request without an explicit model leaves the
primary model unchanged.
- Extend server route and UI runtime-config tests for default-disable
and explicit-opt-in behavior.
## 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
packages/adapters/codex-local/src/index.test.ts
packages/adapters/codex-local/src/server/codex-args.test.ts
server/src/__tests__/adapter-models.test.ts
server/src/__tests__/adapter-registry.test.ts
server/src/__tests__/heartbeat-model-profile.test.ts
server/src/__tests__/agent-permissions-routes.test.ts
ui/src/lib/new-agent-runtime-config.test.ts`
- Result: 7 test files passed, 105 tests passed.
- GitHub `Typecheck + Release Registry` check passed on the final head.
- `git diff --check public-gh/master...HEAD`
## Risks
- Low behavioral risk: only newly created or hired agents are
normalized; existing agents are unchanged.
- Explicit `cheap` profile settings remain untouched, including explicit
opt-in.
- Codex users who explicitly opt into the cheap lane must choose a
model; requests without a configured override intentionally continue on
the primary model.
- Adapter profile discovery is now awaited during creation, adding a
small amount of adapter metadata lookup work.
- The source branch name is automation-provided and retained as required
by the task, so it does not satisfy the preferred public branch naming
convention.
> 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 reasoning, repository editing,
terminal execution, and GitHub/Paperclip tool access. 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)
- [ ] 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>
|
||
|
|
8339bcc7e7 |
fix(ui): keep decision training under decisions (#10181)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Operators review decisions and turn useful outcomes into training examples > - The training library belongs to the Decisions surface, but its routes and entry point appeared as a separate top-level destination > - That mismatch made the training icon feel disconnected and left internal links pointing at legacy `/training` URLs > - This pull request nests the training library and inspector under `/decisions/training`, keeps legacy URLs working through redirects, and uses one route helper everywhere > - The benefit is a clearer Decisions workflow without breaking existing bookmarks or links ## Linked Issues or Issue Description Refs: #9718 Refs: #9779 **Problem:** The Decisions page exposed training as a labeled header action while the training library lived at the unrelated top-level `/training` route. Links across the UI duplicated that legacy path. **Expected behavior:** Training should be an icon action alongside the other Decisions controls, and training library/record URLs should live under `/decisions/training` while old URLs continue to redirect. **Steps to reproduce:** 1. Open the Decisions page. 2. Observe the separate labeled Training button in the page heading. 3. Open a training record and note the top-level `/training/...` URL. **Version/commit:** Current `master` before this PR. **Deployment mode:** All UI deployment modes. ## What Changed - Move the training library and inspector routes under `/decisions/training`. - Redirect legacy `/training` and `/training/:id` URLs to the new locations. - Add `decisionTrainingHref()` and use it for training links and navigation. - Place the Training icon action with the Decisions filter and sort controls. - Add focused tests for library and record URL generation. ## Verification - `pnpm exec vitest run ui/src/lib/decisionTraining.test.ts` - `pnpm --filter @paperclipai/ui typecheck` - `pnpm --filter @paperclipai/ui build` - `pnpm check:token-gates` ## Risks - Low risk: the change is limited to client-side routes and navigation. - Existing `/training` bookmarks remain supported through replacement redirects. - No API, database, migration, dependency, or workflow 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 using GPT-5.4 with reasoning, repository tool use, shell execution, and code/test verification. ## 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> |
||
|
|
0cf64d36a5 |
feat(secrets): write through external values and deep-link details (#10196)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI-agent companies. > - Its secrets subsystem can resolve external references such as AWS Secrets Manager values without copying those values into Paperclip custody. > - Operators also need to rotate a referenced secret's value while preserving the same provider reference for consumers inside and outside Paperclip. > - Previously, external-reference rotation could only retarget metadata, and secret detail sheets were driven by local component state rather than shareable navigation state. > - This pull request adds an optional provider write capability, implements AWS Secrets Manager write-through rotation, and exposes capability-aware rotate modes in the UI. > - It also makes secret and each-user definition detail sheets URL-driven and adds a copy-link action. > - The benefit is that operators can update the canonical external value safely while keeping AWS rotation tracking intact, and they can share or navigate directly to secret details. ## Linked Issues or Issue Description ### Subsystem affected Cross-cutting (`server/`, `ui/`, and `packages/shared`). ### Problem or motivation External-reference secrets can follow a provider-managed value, but Paperclip could not write a replacement value back to providers that support it. Operators had to leave Paperclip, update the value separately, and then return without an auditable Paperclip rotation record. Secret detail sheets also could not be shared or restored through browser history because their selection lived only in component state. ### Proposed solution Add an optional `updateExternalSecretValue` provider capability and surface it as `supportsExternalValueWrites`. Implement AWS writes with `PutSecretValue` while leaving the resolution `versionId` unset so future reads continue following `AWSCURRENT`. Add write-value and retarget modes to the rotate dialog for capable providers. Drive secret detail selection from `?secret=` / `?definition=` query parameters and provide a copy-link action. ### Alternatives considered Converting an external reference into a Paperclip-managed secret would break consumers that depend on the existing provider reference. Pinning reads to the newly written AWS version would prevent later out-of-band rotations from flowing through. Keeping sheet selection only in React state would not support browser Back or shareable links. ### Roadmap alignment This extends the completed “Secrets Manager with per-agent access” roadmap capability; it does not duplicate a separate planned roadmap item. Public GitHub searches found no duplicate or closely related issue or PR. ### Additional context The PR includes focused provider, service, and UI render coverage. Cutter also generated previews for the deep-linked detail sheet and capability-aware rotate modes. ## What Changed - Added optional external-value write support to the secret provider contract and provider descriptors. - Implemented AWS Secrets Manager write-through with `PutSecretValue`, audit material, and compensation when persistence fails after the provider write. - Allowed `secretService.rotate()` value updates for external references while rejecting ambiguous value-plus-retarget combinations and unsupported providers. - Added capability-aware “Write new value” and “Change reference” rotate modes with updated custody and action copy. - Made secret and each-user definition detail sheets source their selection from URL query parameters, compose with folder paths, close through browser history, and expose a copy-link action. - Added provider, service, and UI render coverage for write-through, rollback, capability messaging, dialog modes, and deep links. ## Verification - `pnpm vitest run server/src/__tests__/aws-secrets-manager-provider.test.ts` — 18 passed. - `pnpm vitest run server/src/__tests__/secrets-service.test.ts` — 75 passed. - `pnpm vitest run ui/src/pages/Secrets.render.test.tsx` — 31 passed. - `pnpm --filter @paperclipai/shared typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - `pnpm check:token-gates` — passed with all gates clean. ## Risks - External value writes affect the canonical provider secret and therefore all consumers of that AWS secret; the UI explicitly labels this custody behavior. - A provider write can succeed before Paperclip persistence fails. The service records the written version and AWS support includes compensation coverage to restore the prior value where possible; unrecoverable failures return explicit audit-safe error details. - URL-driven sheet state changes navigation behavior; render tests cover deep links, Back/close behavior, and composition with folder query state. - No database migration or breaking API requirement is introduced; providers without the optional capability retain reference-only behavior. > 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 exact model ID `gpt-5.6-sol`, high reasoning mode, Codex CLI `0.142.5`, with repository, shell, Git, GitHub CLI, and code-execution tools. The runtime did not expose a context-window size. - Earlier implementation commits were assisted by Anthropic `Claude Fable 5` as recorded in their commit trailers; the exact backend model ID and context-window size were not preserved in the workspace metadata. ## 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 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, or confirmed no documentation change is required - [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> |
||
|
|
ab2bdfeebb |
feat(routines): activity-gated advanced run policy (editor + run rows) (#10225)
## 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 activity gate (`activity_gate_policy` / `activity_gate_scope`) lets a scheduled routine skip a tick when nothing has happened since its last run, so watcher-style routines stay asleep while the system is settled instead of burning tokens every tick. > - The scheduler, database columns, and the create/update API for those fields already landed (see #9438), but there was no way for an operator to actually set the policy from the routine editor, and the runs list rendered gated skips as bare "skipped" rows with no "why". > - This pull request adds the editor control and the run-row labels: the Delivery section gets an "Advanced run policy" picker plus a scope selector, and skipped runs explain why they were skipped. > - The benefit is that the activity gate becomes discoverable and usable end-to-end from the UI, closing the loop on the feature the API already supports. ## Linked Issues or Issue Description - Refs #8534 — activity gate for scheduled routines. - Builds on #9438 (merged) which exposed the activity-gate create/update API and the `Routine` response fields this UI reads and writes. This PR is the editor/UI companion to that API work. ## What Changed - **Routine editor — Advanced run policy control** (`ui/src/components/routine-sections/editable-sections.tsx`): the Delivery section gains a `RadioCardGroup` to choose between *Run on every scheduled tick* (default) and *Skip when there's been no activity since the last run*. When gating is enabled, a second scope picker (*Company-wide* / *This project*) appears. The control is **disabled with an explanatory hint** — rather than hidden — when the routine has no schedule trigger, since the gate only affects scheduled ticks (webhook/manual/API fires are themselves activity and always run). This keeps the capability discoverable. - **Edit-draft plumbing** (`ui/src/components/routine-sections/context.tsx`, `ui/src/pages/RoutineDetail.tsx`): `activityGatePolicy` / `activityGateScope` flow through the edit draft, the delivery section's dirty-field detection, the save payload, and revision restore, matching how `concurrencyPolicy` / `catchUpPolicy` are handled. - **Run-history skip reasons** (`ui/src/lib/routine-run-display.ts`): skipped run rows now render a human-readable "why" — `no_external_activity` → "Skipped — no activity since last run", plus labels for `paused` and `worktree_execution_cutoff` — instead of a bare status. - Storybook fixture updates for the new routine fields, plus focused run-display coverage for the skipped-run labels. ## Verification - `pnpm exec vitest run ui/src/lib/routine-run-display.test.ts` — 11 tests passing. - `pnpm --filter @paperclipai/ui typecheck` — clean. - `pnpm check:token-gates` — all token gates clean. - `pnpm --filter @paperclipai/ui build` — production build succeeds. - Current-head GitHub CI for `9f9af8ecccfadcdc4a3afab313aafad81cbd1112` — all checks pass (Storybook visual check skipped by workflow policy). ## Risks - **Low risk.** UI-only change; no schema/migration and no server changes (the API and columns already shipped in #9438). Fields are optional and default to the pre-feature behavior (`always` / `company`), so existing routines are unaffected. The scope picker only renders when gating is turned on, and the whole control is inert without a schedule trigger. ## Model Used - Claude Opus 4.8 (`claude-opus-4-8`, 1M context), extended thinking, with tool use (repo edit + shell verification). ## 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> |
||
|
|
f6ab82d490 |
feat(interactions): add interaction withdrawal and terminal-issue expiry (#10251)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agents and boards coordinate through issue-thread interactions (request_confirmation, ask_user_questions, suggest_tasks, …) that wait as `pending` cards until someone resolves them > - Two lifecycle gaps existed: an interaction's creator could not take back a card it no longer stands behind, and interactions left `pending` on issues that reached a terminal status lingered forever as live-looking approval requests > - Stale pending cards mislead humans (they look actionable), distort attention/liveness signals, and in the worst case invite acting on a proposal whose issue is already closed or cancelled > - This pull request adds an explicit withdraw route for pending interactions and automatically expires pending interactions when their issue reaches a terminal status (including a catch-up sweep for issues closed before this change) > - The benefit is that interaction cards now faithfully reflect reality: only genuinely actionable requests stay pending, and creators can retract requests that events have overtaken ## Linked Issues or Issue Description Fixes #5787 Refs #7403 Related prior PRs found while searching for duplicates (all overlap partially; none combine both lifecycle paths or the route-level authorization used here): #6709 and #7312 (creator-withdraw attempts), #8169 (terminal expiry), #8081 and #5137 (generalized cancel/expire endpoints), #6094 (stale confirmation auto-resolve). Related merged context: #9568 (agent cancel for ask_user_questions), #10119 (tolerating legacy `withdrawn_by_creator` result outcomes — the reader side of the outcome this PR writes). ## What Changed - New route `POST /issues/:id/interactions/:interactionId/withdraw` that resolves a `pending` interaction to status `withdrawn` with a structured result (`outcome: "withdrawn"`, optional trimmed `reason`), stamps `resolvedBy*`/`resolvedAt`, touches the issue, logs activity, and emits resolved-interaction telemetry - Withdrawal authorization: board users, the interaction's creator agent, or the issue's current assignee agent (assignees additionally pass the standard issue-mutation gate); task-watchdog runs are explicitly rejected, and authorization-boundary plus low-trust control-plane checks apply - Withdrawing an already-resolved interaction returns `409`; unknown/cross-issue/cross-company interaction ids return `404` - New service method `expirePendingInteractionsForTerminalIssue`: when an issue transitions to a terminal status, all of its `pending` interactions are resolved to `expired` with `outcome: "issue_closed"`, guarded by a `status = 'pending'` predicate so concurrent resolutions are not overwritten - The same expiry runs as a catch-up when interactions are listed on an already-terminal issue, so cards stranded by issues closed before this change also get cleaned up; expired request_confirmations are logged with a distinguishing source - Shared package: new `withdrawIssueThreadInteractionSchema` validator, `WithdrawIssueThreadInteraction` type, and `withdrawn` / `issue_closed` result-outcome support for all interaction kinds (kind-aware result shapes for `ask_user_questions` and `request_item_verdicts`) - UI helper `ui/src/lib/issue-thread-interactions.ts` recognizes the new outcomes for card rendering - Docs: bundled skill API reference updated with the withdraw endpoint - Review follow-up: terminal expiry moved from the HTTP route hooks into `issueService.update`'s status-transition block, so direct service callers (tree control, recovery, pipelines, status cards) expire pending cards too; the list-endpoint catch-up remains for issues closed before this change - Review follow-up: withdrawing or issue-close-expiring a `request_confirmation` also settles its linked `tool_action_requests` row (withdraw -> `cancelled`, issue closed -> `expired`), so a parked tool call cannot stay approvable after its card is gone - Review follow-up: interaction cards render dedicated copy for the new outcomes ("Withdrawn" with the reason, "Expired when issue closed") instead of falling through to superseded-by-comment / stale-target variants; withdrawn plan reviews badge as "Withdrawn" rather than "Changes requested" ## Screenshots Card states rendered from a local ux-lab harness with mocked data ([full gallery](https://pages.paperclip.ing/pr-10251-interaction-withdrawal-cards/)): | Light | Dark | | --- | --- | |  |  | ## Verification - `pnpm --filter @paperclipai/shared build` — clean tsc - `cd server && npx vitest run src/__tests__/issue-thread-interaction-routes.test.ts` — 22 tests pass, including new coverage for: creator-agent withdraw success, non-creator/non-assignee agent 403, watchdog-run 403, double-withdraw 409, and board-user withdraw - `cd server && npx vitest run src/services/issue-thread-interactions.test.ts` — 4 tests pass, including terminal-issue expiry writing `issue_closed` results and leaving already-resolved interactions untouched - `cd ui && pnpm typecheck` — clean - `cd server && npx vitest run src/__tests__/issues-service.test.ts` — includes a new embedded-Postgres test proving a direct `issueService.update` terminal transition expires pending interactions and writes the activity-log entry - `cd ui && npx vitest run src/components/IssueThreadInteractionCard.test.tsx` — 32 tests, including new coverage for withdrawn / issue-closed confirmation and question cards - `cd server && npx tsc --noEmit` — matches the pre-existing repo error baseline exactly (no new errors) - Manual: `POST /issues/:id/interactions/:interactionId/withdraw` with `{"reason":"superseded"}` as the creator agent resolves the card to `withdrawn`; closing an issue with a pending confirmation flips it to `expired` with `outcome: "issue_closed"` ## Risks - Interactions on terminal issues now auto-expire (including retroactively via the list-time catch-up), so consumers that expected to resolve a pending interaction on a closed issue will get `409`; this is the intended semantics and matches how the attention feed already wants to treat dead cards - New result outcomes (`withdrawn`, `issue_closed`) are written to stored results; readers were already made tolerant of these outcome strings in #10119, so mixed-version reads are safe - No schema/migration changes; per-row conditional updates (`status = 'pending'`) avoid clobbering concurrent resolutions - Withdrawal is a new mutation surface, but it is strictly narrower than existing resolve paths (board, creator, or assignee only; watchdog runs blocked) ## Model Used Claude Fable 5 (`claude-fable-5`, Anthropic Mythos-class tier) with extended thinking and agentic tool use (Claude Code harness); commit authored in a Paperclip-managed engineering 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> |
||
|
|
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) |